|
|
|
|
@ -81,6 +81,8 @@
|
|
|
|
|
#define SMTP_PARSER_STATE_FIRST_REPLY_SEEN 0x04
|
|
|
|
|
/* Used to indicate that the parser is parsing a multiline reply */
|
|
|
|
|
#define SMTP_PARSER_STATE_PARSING_MULTILINE_REPLY 0x08
|
|
|
|
|
/* Used to indicate that the server supports pipelining */
|
|
|
|
|
#define SMTP_PARSER_STATE_PIPELINING_SERVER 0x10
|
|
|
|
|
|
|
|
|
|
/* Various SMTP commands
|
|
|
|
|
* We currently have var-ified just STARTTLS and DATA, since we need to them
|
|
|
|
|
@ -1000,6 +1002,12 @@ static int SMTPProcessReply(SMTPState *state, Flow *f,
|
|
|
|
|
* line of the multiline reply, following which we increment the index */
|
|
|
|
|
if (!(state->parser_state & SMTP_PARSER_STATE_PARSING_MULTILINE_REPLY)) {
|
|
|
|
|
state->cmds_idx++;
|
|
|
|
|
} else if (state->parser_state & SMTP_PARSER_STATE_FIRST_REPLY_SEEN) {
|
|
|
|
|
/* we check if the server is indicating pipelining support */
|
|
|
|
|
if (reply_code == SMTP_REPLY_250 && state->current_line_len == 14 &&
|
|
|
|
|
SCMemcmpLowercase("pipelining", state->current_line+4, 10) == 0) {
|
|
|
|
|
state->parser_state |= SMTP_PARSER_STATE_PIPELINING_SERVER;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* if we have matched all the buffered commands, reset the cnt and index */
|
|
|
|
|
@ -1189,7 +1197,10 @@ static int SMTPProcessRequest(SMTPState *state, Flow *f,
|
|
|
|
|
tx->msg_tail = tx->mime_state->msg;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Enter immediately data mode without waiting for server reply */
|
|
|
|
|
if (state->parser_state & SMTP_PARSER_STATE_PIPELINING_SERVER) {
|
|
|
|
|
state->parser_state |= SMTP_PARSER_STATE_COMMAND_DATA_MODE;
|
|
|
|
|
}
|
|
|
|
|
} else if (state->current_line_len >= 4 &&
|
|
|
|
|
SCMemcmpLowercase("bdat", state->current_line, 4) == 0) {
|
|
|
|
|
r = SMTPParseCommandBDAT(state);
|
|
|
|
|
@ -2787,6 +2798,7 @@ static int SMTPParserTest03(void)
|
|
|
|
|
/* MAIL FROM:pbsf@asdfs.com<CR><LF>
|
|
|
|
|
* RCPT TO:pbsf@asdfs.com<CR><LF>
|
|
|
|
|
* DATA<CR><LF>
|
|
|
|
|
* Immediate data
|
|
|
|
|
*/
|
|
|
|
|
uint8_t request2[] = {
|
|
|
|
|
0x4d, 0x41, 0x49, 0x4c, 0x20, 0x46, 0x52, 0x4f,
|
|
|
|
|
@ -2795,7 +2807,9 @@ static int SMTPParserTest03(void)
|
|
|
|
|
0x0d, 0x0a, 0x52, 0x43, 0x50, 0x54, 0x20, 0x54,
|
|
|
|
|
0x4f, 0x3a, 0x70, 0x62, 0x73, 0x66, 0x40, 0x61,
|
|
|
|
|
0x73, 0x64, 0x66, 0x73, 0x2e, 0x63, 0x6f, 0x6d,
|
|
|
|
|
0x0d, 0x0a, 0x44, 0x41, 0x54, 0x41, 0x0d, 0x0a
|
|
|
|
|
0x0d, 0x0a, 0x44, 0x41, 0x54, 0x41, 0x0d, 0x0a,
|
|
|
|
|
0x49, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74,
|
|
|
|
|
0x65, 0x20, 0x64, 0x61, 0x74, 0x61, 0x0d, 0x0a,
|
|
|
|
|
};
|
|
|
|
|
uint32_t request2_len = sizeof(request2);
|
|
|
|
|
/* 250 2.1.0 Ok<CR><LF>
|
|
|
|
|
@ -2881,7 +2895,8 @@ static int SMTPParserTest03(void)
|
|
|
|
|
if (smtp_state->input_len != 0 ||
|
|
|
|
|
smtp_state->cmds_cnt != 0 ||
|
|
|
|
|
smtp_state->cmds_idx != 0 ||
|
|
|
|
|
smtp_state->parser_state != SMTP_PARSER_STATE_FIRST_REPLY_SEEN) {
|
|
|
|
|
smtp_state->parser_state != ( SMTP_PARSER_STATE_FIRST_REPLY_SEEN |
|
|
|
|
|
SMTP_PARSER_STATE_PIPELINING_SERVER)) {
|
|
|
|
|
printf("smtp parser in inconsistent state\n");
|
|
|
|
|
goto end;
|
|
|
|
|
}
|
|
|
|
|
@ -2901,7 +2916,9 @@ static int SMTPParserTest03(void)
|
|
|
|
|
smtp_state->cmds[0] != SMTP_COMMAND_OTHER_CMD ||
|
|
|
|
|
smtp_state->cmds[1] != SMTP_COMMAND_OTHER_CMD ||
|
|
|
|
|
smtp_state->cmds[2] != SMTP_COMMAND_DATA ||
|
|
|
|
|
smtp_state->parser_state != (SMTP_PARSER_STATE_FIRST_REPLY_SEEN)) {
|
|
|
|
|
smtp_state->parser_state != (SMTP_PARSER_STATE_FIRST_REPLY_SEEN |
|
|
|
|
|
SMTP_PARSER_STATE_COMMAND_DATA_MODE |
|
|
|
|
|
SMTP_PARSER_STATE_PIPELINING_SERVER)) {
|
|
|
|
|
printf("smtp parser in inconsistent state\n");
|
|
|
|
|
goto end;
|
|
|
|
|
}
|
|
|
|
|
@ -2919,7 +2936,8 @@ static int SMTPParserTest03(void)
|
|
|
|
|
smtp_state->cmds_cnt != 0 ||
|
|
|
|
|
smtp_state->cmds_idx != 0 ||
|
|
|
|
|
smtp_state->parser_state != (SMTP_PARSER_STATE_FIRST_REPLY_SEEN |
|
|
|
|
|
SMTP_PARSER_STATE_COMMAND_DATA_MODE)) {
|
|
|
|
|
SMTP_PARSER_STATE_COMMAND_DATA_MODE |
|
|
|
|
|
SMTP_PARSER_STATE_PIPELINING_SERVER)) {
|
|
|
|
|
printf("smtp parser in inconsistent state\n");
|
|
|
|
|
goto end;
|
|
|
|
|
}
|
|
|
|
|
|