@@ -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 ;
30413099end :
0 commit comments