Skip to content

Commit

Permalink
smtp: improve pipelining support
Browse files Browse the repository at this point in the history
Fixes OISF#1863
  • Loading branch information
catenacyber authored and victorjulien committed Dec 19, 2018
1 parent 8357ef3 commit 447c104
Showing 1 changed file with 23 additions and 5 deletions.
28 changes: 23 additions & 5 deletions src/app-layer-smtp.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 */
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -2787,6 +2798,7 @@ static int SMTPParserTest03(void)
/* MAIL FROM:[email protected]<CR><LF>
* RCPT TO:[email protected]<CR><LF>
* DATA<CR><LF>
* Immediate data
*/
uint8_t request2[] = {
0x4d, 0x41, 0x49, 0x4c, 0x20, 0x46, 0x52, 0x4f,
Expand All @@ -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>
Expand Down Expand Up @@ -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;
}
Expand All @@ -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;
}
Expand All @@ -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;
}
Expand Down

0 comments on commit 447c104

Please sign in to comment.