diff options
Diffstat (limited to 'decoders/mail/mail_email.h')
| -rw-r--r-- | decoders/mail/mail_email.h | 342 |
1 files changed, 342 insertions, 0 deletions
diff --git a/decoders/mail/mail_email.h b/decoders/mail/mail_email.h new file mode 100644 index 0000000..77ca3c7 --- /dev/null +++ b/decoders/mail/mail_email.h @@ -0,0 +1,342 @@ +#pragma once + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include <sys/time.h> +#include "mail_internal.h" +#include "mail_mime.h" + +typedef enum +{ + MAIL_USERNAME_MASK=0, + MAIL_PASSWARD_MASK, + MAIL_FROM_MASK, + MAIL_TO_MASK, + MAIL_CC_MASK, + MAIL_BCC_MASK, + MAIL_DATE_MASK, + MAIL_SUBJECT_MASK, + MAIL_CONTENT_MASK, + MAIL_ATTACH_NAME_MASK, + MAIL_ATTACH_CONTENT_MASK, + MAIL_OTHER_MASK, + MAIL_FROM_CMD_MASK, + MAIL_TO_CMD_MASK, + MAIL_EHLO_CMD_MASK, + MAIL_REPLY_TO_MASK, + + /*ADD*/ + MAIL_REGION_NUM, + MAIL_STARTTLS_CMD_MASK, +}mail_interested_region_mask; + +//邮件各字段flag对应值;程序中定义的宏在字段前加"MAIL_",配置文件中注册的字段没有前面的"MAIL_" +//配置文件中支持"ALL" +//配置文件注册字段大小写敏感 +#define MAIL_USERNAME ((long long)1<<MAIL_USERNAME_MASK) +#define MAIL_PASSWARD ((long long)1<<MAIL_PASSWARD_MASK) +#define MAIL_FROM ((long long)1<<MAIL_FROM_MASK) +#define MAIL_TO ((long long)1<<MAIL_TO_MASK) +#define MAIL_CC ((long long)1<<MAIL_CC_MASK) +#define MAIL_BCC ((long long)1<<MAIL_BCC_MASK) +#define MAIL_DATE ((long long)1<<MAIL_DATE_MASK) +#define MAIL_SUBJECT ((long long)1<<MAIL_SUBJECT_MASK) +#define MAIL_CONTENT ((long long)1<<MAIL_CONTENT_MASK) +#define MAIL_ATTACH_NAME ((long long)1<<MAIL_ATTACH_NAME_MASK) +#define MAIL_ATTACH_CONTENT ((long long)1<<MAIL_ATTACH_CONTENT_MASK) +#define MAIL_OTHER ((long long)1<<MAIL_OTHER_MASK) +#define MAIL_FROM_CMD ((long long)1<<MAIL_FROM_CMD_MASK) +#define MAIL_TO_CMD ((long long)1<<MAIL_TO_CMD_MASK) +#define MAIL_EHLO_CMD ((long long)1<<MAIL_EHLO_CMD_MASK) +#define MAIL_REPLY_TO ((long long)1<<MAIL_REPLY_TO_MASK) +#define MAIL_STARTTLS_CMD ((long long)1<<MAIL_STARTTLS_CMD_MASK) + +#define SMTP_PROTOCOL 1 +#define POP3_PROTOCOL 2 +#define IMAP_PROTOCOL 3 + + +//传输编码 +#define MAIL_TRANS_ENC_UNKNOWN 0 +#define MAIL_TRANS_ENC_BASE64 1 +#define MAIL_TRANS_ENC_QP 2 + +typedef struct _mail_elem_info +{ + int buflen; + int max_len; + char* buf; +}stMailElem; + +typedef struct _mail_key_info +{ + stMailElem *username; //用户名 + stMailElem *password; //用户密码 + stMailElem *sendaddr; //发信地址 + stMailElem *recvaddr; //收信地址 + stMailElem *subject; //邮件主题 + stMailElem *date; //发信时间 +} stKeyInfo; + +typedef struct _field_element +{ + long long prot_flag; + char* current_charset; //当前字符集编码格式 ;可能为NULL; + void *buf; //当前字段对应原始数据内容, 经过传输编码解析 + int buflen; //当前字段对应原始数据长度 +}stFieldElem; + +typedef struct _mail_pme_info +{ + char protocol; //邮件协议SMTP_PROTOCOL/POP3_PROTOCOL/IMAP_PROTOCOL + char trans_enc; //传输编码,只有邮件正文、附件有;主题和附件名中是否有传输编码需要业务插件自行解析 + short session_seq; //当前会话是TCP链接中的第几个会话,从0开始; + int buflen; //邮件原始数据长度 + char* buf; //邮件原始数据内容,不经过传输编码解析 + char* current_charset; //当前字符集编码格式 ;可能为NULL; + stKeyInfo *pMailInfo; //保留邮件的关键信息 + + //NEXT: ADD BY ZCW + int cur_offset; //当前字段在原始数据buf中的的偏移 + stFieldElem *elem; + int elem_num; +} tdMailInfo; + + +#define MAIL_GLOBALMODULE "[MAIL_GLOBAL]" + +/****************************包获取相关宏******************************/ +/*协议编号*/ +#define MAIL_SERVICE_SMTP 6 +#define MAIL_SERVICE_POP3 7 +#define MAIL_SERVICE_IMAP4 5 + +/*数据流一行获取状态*/ +#define MAIL_GETLINE_ERR -1 +#define MAIL_INPUT_END 0 +#define MAIL_FOLD_LINE_END 1 +#define MAIL_FOLD_LINE_START 2 +#define MAIL_LINE_END 3 +#define MAIL_PACKET_END 4 + +/* 当丢包造成的状态错位时,通过检验新来包长度的办法区分正文和命令*/ +#define MAIL_FROM_LEN 120 //包含mail from 的包的应用层数据尺寸的上限。用于处理同一连接多封信时的丢包。 +#define RSETQUIT_CMD_LEN 20 //包含reset/quit命令 的包的应用层数据尺寸的上限。 +#define BDAT_CMD_LEN 50 //包含bdat命令 的包的应用层数据尺寸的上限。 +#define MAX_MAIL_USER_LEN 512 + +/*lqy 060331 最大保存关键字的长度,用于处理关键字跨包的情况*/ +#define MAX_ORDER_LINE_SIZE 2048 +#define MAIL_LINE_MAX_LEN (20*1024) +#define MAX_USER_PASS_LEN 50 //用户名密码的最大长度 + + +/************************邮件处理相关宏**********************************/ +/*邮件处理状态*/ +#define MAIL_STAT_INIT 0x10//邮件尚未状态 +#define MAIL_STAT_HEADER 0x11//邮件头部处理状态 +#define MAIL_STAT_BODY 0x12//邮件体处理状态 +#define MAIL_STAT_END 0x13//邮件结束状态 + +/*邮件主体各个部分定义*/ +enum EML_DATA_FIELD +{ + EML_DATA_HEAD_IN=1, + EML_DATA_BODY_IN, + EML_DATA_FROM, + EML_DATA_TO, + EML_DATA_CC, + EML_DATA_BCC, /*6*/ + EML_DATA_SUBJECT, + EML_DATA_CONTENTTYPE, + EML_DATA_CONTENTTRANSFERENCODING, + EML_DATA_HEAD_BODY_BORDER, + EML_DATA_END, /*11*/ + EML_DATA_RETURN_PATH, + EML_DATA_DELIVERED_TO, + EML_DATA_RECEIVED, + EML_DATA_DATE, /*15*/ + EML_DATA_REPLY_TO, + EML_UNKNOWN, +}; + +/*用户密码获取状态,比特位方式;对于AUTH PLAIN方式,用户密码会一起获得*/ +#define SMTP_NO_USER 0 +#define SMTP_HAVE_USER (1<<0) +#define SMTP_BEFORE_USER (1<<1) +#define SMTP_BEFORE_PASS (1<<2) +#define SMTP_AFTER_PASS (1<<3) +#define SMTP_AUTH_PLAIN (1<<4) + + +#define MAIL_GET_NONE -1 +#define MAIL_GET_FROM 9 +#define MAIL_GET_TO 10 +#define MAIL_GET_SUB 11 +#define MAIL_GET_DATE 12 +#define MAIL_GET_COUNT 13 +#define MAIL_GET_FILENAME 14 +#define MAIL_GET_FILECOUNT 15 +#define MAIL_GET_OTHER 16 +#define MAIL_GET_FILECOUNT_END 17 + +/*stBufCache缓冲区大小控制相关宏*/ +#define MAX_MALLOC_SIZE (64*1024) +#define REALLOC_BLOCK_SIZE 1024 +#define BUF_ELEM_BLOCK 128 + +#ifndef MAIL_MAX_CHARSET_LEN +#define MAIL_MAX_CHARSET_LEN 32 +#endif + +//批量回调时预先分配的单元个数 +#define MAIL_ELEM_NUM 16 + +//该结构体为避免初始化时分配很多次内存 +typedef struct _new_mail_key_info +{ + stMailElem username; //用户名 + stMailElem password; //用户密码 + stMailElem sendaddr; // 发信地址 + stMailElem recvaddr; // 收信地址 + stMailElem subject; //邮件主题 + stMailElem date; //发信时间 +}new_stKeyInfo; + +typedef struct _buf_cache +{ + void *buf; + int len; + int max_len; +}stBufCache; + +typedef struct _stMailPme +{ + stBufCache pDataLineBuf; //获取数据包缓存区 + stBufCache pOriginalData; //原始邮件信息 + stBufCache pMimeDecodeBuf; //MIME解码后的存储区 + stBufCache pBizRegion; //批量回调业务层的字段buf缓存区 + + tdMailInfo plug_mailinfo; //session_info->app_info + stKeyInfo pMailinfo; //plug_mailinfo.pMailinfo + new_stKeyInfo keyinfo; //plug_mailinfo.pMailinfo的成员 + stFieldElem elem; + + MimeParse_t *mimeinfo; // mime解码结构 + char subject_charset[MAIL_MAX_CHARSET_LEN]; //主题字符集编码格式 + + int iDataPointer; // 当前读取的数据偏移,用于按行读取中 + int max_elem_num; + + int EmlAnalyseState;// 标志邮件处理状态 + int MailInfoState; //zcw add, from stMailInfoOld + + int iProtoType; //邮件会话结构的协议类型 + + char pending_state; //1-为新的会话刚准备好上下文,0-新会话已到来 + char is_called; //当前会话回调过业务层 + char pre_dir; //上一个流的方向,用于双方向缓存数据的时候使用,对于SMTP只考虑单方向的忽略此变量 + + //NEXT ONLY IMAP4 + char is_continue; + char maybe_end; //')'不能确定结束与否的时候设置标记 + short obtain_line; //点名接下来获取一行,级别低于折叠行 + int pre_opsate; //')'不能确定结束与否的时候保留上一次的行类型 + long pre_uid; //IMAP协议按照字节数获取邮件内容的情况 + long uid; + + void* app_pme; +}stMailPme; + +int buf_elem_check_size(stMailElem *pdstBuf, int wantedlen); +int buf_cache_check_size(stBufCache *pbuf, int wantedlen); + +int save_original_data(stBufCache *pbuf, const char *data, int datalen); + +char mail_init_mailpme(stMailPme** mailpme_pointer,char ServiceType, int is_c2s); +void mail_clear_mailpme(stMailPme * mailpme); +char mail_reset_mailpme(stMailPme * mailpme); +char mail_reset_mailpme_noclose(stMailPme * mailpme); +void mail_close_business(stMailPme * mailpme); + +int mail_get_atcpline_c2s(const char *payload, size_t payload_len, stMailPme* mailpme, char ** output_buf,int *output_len); +int mail_get_tcpdata(const char *payload, size_t payload_len, stMailPme* smtpinfo, int need_folding, char ** output_buf,int *output_len); +int mail_get_mailaddr(stMailElem *pdstBuf,char *srcstr,int datalen); +int mail_save_mail_elem(char *srcdata, int datalen, stMailElem *pelem); + + + + + + +#include "stellar/mail.h" + +struct email_header { + struct iovec *from; + struct iovec *to; + struct iovec *cc; + struct iovec *bcc; + struct iovec *reply_to; + struct iovec *date; + struct iovec *subject; + + struct iovec *header_fields; + size_t n_header_fields; +}; + +struct email_body { + const char *body; + size_t body_len; + size_t body_offset; +}; + +struct email_attachment { + const char *attachment_name; + size_t attachment_name_len; + const char *attachment; + size_t attachment_len; + size_t attachment_offset; +}; + +struct email_eml { + const char *eml; + size_t eml_len; + size_t eml_offset; +}; + +enum email_state { + MAIL_HEADER, + MAIL_, + MAIL_CONTENT, + MAIL_ATTACHMENT, +}; + +struct email_parser { + enum email_state state; + struct email_header header; + struct email_body body; + struct email_attachment attachment; + struct email_eml eml; +}; + +struct mail_parser; + +enum MAIL_PROTOCOL email_parser_get_protocol(struct email_parser *parser); +size_t email_parser_get_seq(struct email_parser *parser); +int email_parser_get_command(struct email_parser *parser, enum MAIL_COMMAND *cmd, char **cmd_param, size_t *cmd_param_len, char **cmd_line, size_t *cmd_line_len); +struct email_header *mail_parser_get_header(struct email_parser *parser); +int email_parser_get_body(struct email_parser *parser, char **body, size_t *body_len, size_t *body_offset, int *is_body_finished); +int email_parser_get_attachment(struct email_parser *parser, char **attachment_name, size_t *attachment_name_len, char **attachment, size_t *attachment_len, size_t *attachment_offset, int *is_attachment_finished); +int email_parser_get_eml(struct email_parser *parser, char **eml, size_t *eml_len, size_t *eml_offset, int *is_eml_finished); + +int email_parser_process(struct email_parser *parser, const char *payload, size_t payload_len, int is_c2s); + +struct mail_parser *email_parser_init(); +void email_parser_exit(struct email_parser *parser); + +#ifdef __cplusplus +} +#endif |
