@@ -680,12 +680,26 @@ static int SMTPInsertCommandIntoCommandBuffer(uint8_t command, SMTPState *state)
680680 sizeof (uint8_t ) * (state -> cmds_buffer_len + increment ));
681681 if (ptmp == NULL ) {
682682 SCFree (state -> cmds );
683+ SCFree (state -> cmds_tx_ids );
683684 state -> cmds = NULL ;
685+ state -> cmds_tx_ids = NULL ;
684686 SCLogDebug ("SCRealloc failure" );
685687 return -1 ;
686688 }
687689 state -> cmds = ptmp ;
688690
691+ ptmp = SCRealloc (state -> cmds_tx_ids ,
692+ sizeof (uint64_t ) * (state -> cmds_buffer_len + increment ));
693+ if (ptmp == NULL ) {
694+ SCFree (state -> cmds );
695+ SCFree (state -> cmds_tx_ids );
696+ state -> cmds = NULL ;
697+ state -> cmds_tx_ids = NULL ;
698+ SCLogDebug ("SCRealloc failure" );
699+ return -1 ;
700+ }
701+ state -> cmds_tx_ids = ptmp ;
702+
689703 state -> cmds_buffer_len += increment ;
690704 }
691705 if (state -> cmds_cnt >= 1 &&
@@ -704,6 +718,8 @@ static int SMTPInsertCommandIntoCommandBuffer(uint8_t command, SMTPState *state)
704718 }
705719
706720 state -> cmds [state -> cmds_cnt ] = command ;
721+ state -> cmds_tx_ids [state -> cmds_cnt ] =
722+ state -> curr_tx != NULL ? state -> curr_tx -> tx_id : UINT64_MAX ;
707723 state -> cmds_cnt ++ ;
708724
709725 return 0 ;
@@ -906,6 +922,22 @@ static inline bool IsReplyToCommand(const SMTPState *state, const uint8_t cmd)
906922 state -> cmds [state -> cmds_idx ] == cmd );
907923}
908924
925+ static SMTPTransaction * SMTPGetReplyTx (const SMTPState * state )
926+ {
927+ if (state -> cmds_idx >= state -> cmds_cnt )
928+ return NULL ;
929+
930+ const uint64_t tx_id = state -> cmds_tx_ids [state -> cmds_idx ];
931+ SMTPTransaction * tx = NULL ;
932+ TAILQ_FOREACH (tx , & state -> tx_list , next ) {
933+ if (tx -> tx_id == tx_id )
934+ return tx ;
935+ if (tx -> tx_id > tx_id )
936+ break ;
937+ }
938+ return NULL ;
939+ }
940+
909941static int SMTPProcessReply (
910942 SMTPState * state , Flow * f , SMTPThreadCtx * td , SMTPInput * input , const SMTPLine * line )
911943{
@@ -916,8 +948,12 @@ static int SMTPProcessReply(
916948 return 0 ; // to continue processing further
917949 }
918950
919- if (state -> curr_tx ) {
920- state -> curr_tx -> tx_data .updated_tc = true;
951+ SMTPTransaction * reply_tx = SMTPGetReplyTx (state );
952+ if (reply_tx == NULL ) {
953+ reply_tx = state -> curr_tx ;
954+ }
955+ if (reply_tx != NULL ) {
956+ reply_tx -> tx_data .updated_tc = true;
921957 }
922958 /* the reply code has to contain at least 3 bytes, to hold the 3 digit
923959 * reply code */
@@ -997,7 +1033,7 @@ static int SMTPProcessReply(
9971033 }
9981034 } else if (IsReplyToCommand (state , SMTP_COMMAND_DATA )) {
9991035 if (reply_code == SMTP_REPLY_354 ) {
1000- SMTPSetProgressTC (state -> curr_tx , SMTP_RESPONSE_DATA );
1036+ SMTPSetProgressTC (reply_tx , SMTP_RESPONSE_DATA );
10011037 /* Next comes the mail for the DATA command in toserver direction */
10021038 state -> parser_state |= SMTP_PARSER_STATE_COMMAND_DATA_MODE ;
10031039 } else {
@@ -1009,7 +1045,7 @@ static int SMTPProcessReply(
10091045 SMTPSetEvent (state , SMTP_DECODER_EVENT_DATA_COMMAND_REJECTED );
10101046 }
10111047 } else if (IsReplyToCommand (state , SMTP_COMMAND_BDAT )) {
1012- SMTPSetProgressTC (state -> curr_tx , SMTP_RESPONSE_DATA );
1048+ SMTPSetProgressTC (reply_tx , SMTP_RESPONSE_DATA );
10131049 } else if (IsReplyToCommand (state , SMTP_COMMAND_RSET )) {
10141050 if (reply_code == SMTP_REPLY_250 && state -> curr_tx &&
10151051 !(state -> parser_state & SMTP_PARSER_STATE_PARSING_MULTILINE_REPLY )) {
@@ -1598,6 +1634,13 @@ void *SMTPStateAlloc(void *orig_state, AppProto proto_orig)
15981634 SCFree (smtp_state );
15991635 return NULL ;
16001636 }
1637+ smtp_state -> cmds_tx_ids = SCMalloc (sizeof (uint64_t ) *
1638+ SMTP_COMMAND_BUFFER_STEPS );
1639+ if (smtp_state -> cmds_tx_ids == NULL ) {
1640+ SCFree (smtp_state -> cmds );
1641+ SCFree (smtp_state );
1642+ return NULL ;
1643+ }
16011644 smtp_state -> cmds_buffer_len = SMTP_COMMAND_BUFFER_STEPS ;
16021645
16031646 TAILQ_INIT (& smtp_state -> tx_list );
@@ -1695,6 +1738,9 @@ static void SMTPStateFree(void *p)
16951738 if (smtp_state -> cmds != NULL ) {
16961739 SCFree (smtp_state -> cmds );
16971740 }
1741+ if (smtp_state -> cmds_tx_ids != NULL ) {
1742+ SCFree (smtp_state -> cmds_tx_ids );
1743+ }
16981744
16991745 if (smtp_state -> helo ) {
17001746 SCFree (smtp_state -> helo );
0 commit comments