summaryrefslogtreecommitdiff
path: root/decoders/mail/mail_email.h
diff options
context:
space:
mode:
Diffstat (limited to 'decoders/mail/mail_email.h')
-rw-r--r--decoders/mail/mail_email.h342
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