#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
* 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 */
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);
/* 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,
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>
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;
}
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;
}
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;
}