一。解析函数ProcessMimeBody:解析data命令的body数据
SMTPParse-> SMTPProcessRequest-> SMTPProcessCommandDATA-> MimeDecParseLine-> ProcessMimeEntity-> ProcessMimeBody
这个函数比较简单,主要查询boundary分界线,然后根据查找结果调用bounddary处理函数ProcessMimeBoundary,或者调用body数据处理函数
static int ProcessMimeBody(const uint8_t *buf, uint32_t len,
MimeDecParseState *state)
{
int ret = MIME_DEC_OK;
uint8_t temp[BOUNDARY_BUF];
uint8_t *bstart;
int body_found = 0;
uint32_t tlen;
//这个nss不知道干啥的,没看这个代码
#ifdef HAVE_NSS
if (MimeDecGetConfig()->body_md5) {
if (state->body_begin == 1) {
if (state->md5_ctx == NULL) {
state->md5_ctx = HASH_Create(HASH_AlgMD5);
HASH_Begin(state->md5_ctx);
}
}
HASH_Update(state->md5_ctx, buf, len + state->current_line_delimiter_len);
}
#endif
/* Ignore empty lines */
if (len == 0) {
return ret;
}
/* First look for boundary */
MimeDecStackNode *node = state->stack->top;
if (node == NULL) {
SCLogDebug("Error: Invalid stack state");
return MIME_DEC_ERR_PARSE;
}
//上次的数据如果是结尾boundary字符串,则在解析时设置标志BODY_END_BOUND,
//此处判断如果解析标志为BODY_END_BOUND,说明一个完整的信件体解析结束,
//那么本次及后续的数据就属于上一级(当前信件体的父信件体),
//于是需要确定本次及后续数据使用的boundary字符串,这个boundary字符串从哪里找呢,
//那就时使用其父信件体定义的boundary,父信件体的content-type中包含了这个boundary,
//所以代码判断其父信件体(top->next)是否包含boundary,包含则使用这个boundary,
//如果不包含再查找父信件体的父信件体,直到找到boundary,
//如果最后没有找到boundary则说明当前信件体后续没有子信件体了,
//后续数据是普通的body数据,不需要根据boundary生成子信件体等操作,
//直接将body数据存储到当前信件体的结构体中即可
/* Traverse through stack to find a boundary definition */
if (state->state_flag == BODY_END_BOUND || node->bdef == NULL) {
/* If not found, then use parent's boundary */
node = node->next;
while (node != NULL && node->bdef == NULL) {
SCLogDebug("Traversing through stack for node with boundary");
node = node->next;
}
}
/* This means no boundary / parent w/boundary was found so we are in the body */
if (node == NULL) {
//没有找到boundary则说明当前信件体后续没有子信件体了
//直接将body数据存储到当前信件体的结构体中即可
body_found = 1;
} else {
//查找boundary字符串,比较前边两个横线即“--”
/* Now look for start of boundary */
if (len > 1 && buf[0] == '-' && buf[1] == '-') {
tlen = node->bdef_len + 2;
if (tlen > BOUNDAR