Skip to content

Commit f72040d

Browse files
committed
fixup! smtp: add firewall progress states
1 parent b1a0786 commit f72040d

2 files changed

Lines changed: 52 additions & 4 deletions

File tree

src/app-layer-smtp.c

Lines changed: 50 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
909941
static 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);

src/app-layer-smtp.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,8 @@ typedef struct SMTPState_ {
157157
* stored command in the buffer to match the reply(ies) with the command */
158158
/** the command buffer */
159159
uint8_t *cmds;
160+
/** tx id for each stored command */
161+
uint64_t *cmds_tx_ids;
160162
/** the buffer length */
161163
uint16_t cmds_buffer_len;
162164
/** no of commands stored in the above buffer */

0 commit comments

Comments
 (0)