Skip to content

Commit afe0872

Browse files
committed
fixup! smtp: complete transactions by progress state
1 parent 3b90a13 commit afe0872

1 file changed

Lines changed: 60 additions & 2 deletions

File tree

src/app-layer-smtp.c

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1018,7 +1018,17 @@ static int SMTPProcessReply(
10181018
}
10191019
} else if (IsReplyToCommand(state, SMTP_COMMAND_DATA)) {
10201020
if (reply_code == SMTP_REPLY_354) {
1021-
SMTPSetProgressTC(state->curr_tx, SMTP_RESPONSE_DATA);
1021+
SMTPTransaction *tx;
1022+
TAILQ_FOREACH(tx, &state->tx_list, next) {
1023+
if (tx->progress_ts >= SMTP_REQUEST_DATA &&
1024+
tx->progress_tc < SMTP_RESPONSE_DATA) {
1025+
break;
1026+
}
1027+
}
1028+
if (tx != NULL) {
1029+
tx->tx_data.updated_tc = true;
1030+
SMTPSetProgressTC(tx, SMTP_RESPONSE_DATA);
1031+
}
10221032
/* Next comes the mail for the DATA command in toserver direction */
10231033
state->parser_state |= SMTP_PARSER_STATE_COMMAND_DATA_MODE;
10241034
} else {
@@ -2948,6 +2958,17 @@ static int SMTPParserTest03(void)
29482958
0x0a
29492959
};
29502960
uint32_t reply2_len = sizeof(reply2);
2961+
uint8_t request3[] =
2962+
".\r\n"
2963+
"MAIL FROM:pipeline2@asdfs.com\r\n"
2964+
"RCPT TO:pipeline2@asdfs.com\r\n"
2965+
"DATA\r\n";
2966+
uint32_t request3_len = sizeof(request3) - 1;
2967+
uint8_t reply3[] = {
2968+
0x32, 0x35, 0x30, 0x20, 0x32, 0x2e, 0x30, 0x2e,
2969+
0x30, 0x20, 0x4f, 0x6b, 0x0d, 0x0a
2970+
};
2971+
uint32_t reply3_len = sizeof(reply3);
29512972

29522973
TcpSession ssn;
29532974
AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
@@ -3022,20 +3043,57 @@ static int SMTPParserTest03(void)
30223043
printf("smtp parser in inconsistent state\n");
30233044
goto end;
30243045
}
3046+
SMTPTransaction *tx0 = smtp_state->curr_tx;
3047+
3048+
r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_SMTP,
3049+
STREAM_TOSERVER, request3, request3_len);
3050+
if (r != 0) {
3051+
printf("smtp check returned %" PRId32 ", expected 0: ", r);
3052+
goto end;
3053+
}
3054+
SMTPTransaction *tx1 = smtp_state->curr_tx;
3055+
if (smtp_state->cmds_cnt != 7 || smtp_state->cmds_idx != 0 ||
3056+
smtp_state->cmds[3] != SMTP_COMMAND_DATA_MODE ||
3057+
smtp_state->cmds[4] != SMTP_COMMAND_OTHER_CMD ||
3058+
smtp_state->cmds[5] != SMTP_COMMAND_OTHER_CMD ||
3059+
smtp_state->cmds[6] != SMTP_COMMAND_DATA || tx0 == tx1 ||
3060+
smtp_state->parser_state !=
3061+
(SMTP_PARSER_STATE_FIRST_REPLY_SEEN | SMTP_PARSER_STATE_COMMAND_DATA_MODE |
3062+
SMTP_PARSER_STATE_PIPELINING_SERVER)) {
3063+
printf("smtp parser in inconsistent state\n");
3064+
goto end;
3065+
}
30253066

30263067
r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_SMTP,
30273068
STREAM_TOCLIENT, reply2, reply2_len);
30283069
if (r != 0) {
30293070
printf("smtp check returned %" PRId32 ", expected 0: ", r);
30303071
goto end;
30313072
}
3032-
if (smtp_state->cmds_cnt != 0 || smtp_state->cmds_idx != 0 ||
3073+
if (smtp_state->cmds_cnt != 7 || smtp_state->cmds_idx != 3 ||
30333074
smtp_state->parser_state !=
30343075
(SMTP_PARSER_STATE_FIRST_REPLY_SEEN | SMTP_PARSER_STATE_COMMAND_DATA_MODE |
30353076
SMTP_PARSER_STATE_PIPELINING_SERVER)) {
30363077
printf("smtp parser in inconsistent state\n");
30373078
goto end;
30383079
}
3080+
if (SMTPStateGetAlstateProgress(tx0, STREAM_TOCLIENT) != SMTP_RESPONSE_DATA ||
3081+
SMTPStateGetAlstateProgress(tx1, STREAM_TOCLIENT) >= SMTP_RESPONSE_DATA) {
3082+
printf("smtp progress in inconsistent state\n");
3083+
goto end;
3084+
}
3085+
3086+
r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_SMTP,
3087+
STREAM_TOCLIENT, reply3, reply3_len);
3088+
if (r != 0) {
3089+
printf("smtp check returned %" PRId32 ", expected 0: ", r);
3090+
goto end;
3091+
}
3092+
if (smtp_state->cmds_cnt != 7 || smtp_state->cmds_idx != 4 ||
3093+
SMTPStateGetAlstateProgress(tx0, STREAM_TOCLIENT) != SMTP_RESPONSE_COMPLETE) {
3094+
printf("smtp progress in inconsistent state\n");
3095+
goto end;
3096+
}
30393097

30403098
result = 1;
30413099
end:

0 commit comments

Comments
 (0)