From: Shivani Bhardwaj Date: Sat, 6 May 2023 11:46:30 +0000 (+0530) Subject: smtp: handle following cmd if LF was found in long line X-Git-Tag: suricata-6.0.13~10 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=79a1b2edb5f4063d270bfbd7e765ace275ba9267;p=thirdparty%2Fsuricata.git smtp: handle following cmd if LF was found in long line If a long line had LF post the limit, it should be considered complete and not wait for the next line to complete it. However, currently, any following lines were skipped which could sometimes also be important commands for the entire transaction. Fix this by setting a flag in case we're truncating a long line but after having found the LF character. Bug 5989 --- diff --git a/src/app-layer-smtp.c b/src/app-layer-smtp.c index 14d0f38eeb..5d702a17fa 100644 --- a/src/app-layer-smtp.c +++ b/src/app-layer-smtp.c @@ -574,6 +574,7 @@ static AppLayerResult SMTPGetLine(SMTPState *state) uint32_t o_consumed = state->consumed; state->consumed = lf_idx - state->input + 1; state->current_line_len = state->consumed - o_consumed; + state->current_line_lf_found = true; DEBUG_VALIDATE_BUG_ON(state->current_line_len < 0); if (state->current_line_len < 0) SCReturnStruct(APP_LAYER_ERROR); @@ -1338,7 +1339,10 @@ static AppLayerResult SMTPParse(int direction, Flow *f, SMTPState *state, state->consumed = 0; state->current_line_len = 0; state->current_line_delimiter_len = 0; + state->current_line_lf_found = false; state->direction = direction; + + /* toserver */ if (direction == 0) { if (((state->current_command == SMTP_COMMAND_DATA) || (state->current_command == SMTP_COMMAND_BDAT)) && @@ -1362,7 +1366,9 @@ static AppLayerResult SMTPParse(int direction, Flow *f, SMTPState *state, SCReturnStruct(APP_LAYER_ERROR); if (state->current_line_delimiter_len == 0 && state->current_line_len == SMTP_LINE_BUFFER_LIMIT) { - state->discard_till_lf = true; + if (!state->current_line_lf_found) { + state->discard_till_lf = true; + } state->consumed = state->input_len + 1; // For the newly found LF SMTPSetEvent(state, SMTP_DECODER_EVENT_TRUNCATED_LINE); break; @@ -1396,7 +1402,9 @@ static AppLayerResult SMTPParse(int direction, Flow *f, SMTPState *state, SCReturnStruct(APP_LAYER_ERROR); if (state->current_line_delimiter_len == 0 && state->current_line_len == SMTP_LINE_BUFFER_LIMIT) { - state->discard_till_lf = true; + if (!state->current_line_lf_found) { + state->discard_till_lf = true; + } state->consumed = state->input_len + 1; // For the newly found LF SMTPSetEvent(state, SMTP_DECODER_EVENT_TRUNCATED_LINE); break; diff --git a/src/app-layer-smtp.h b/src/app-layer-smtp.h index 310fbe430f..a58c968502 100644 --- a/src/app-layer-smtp.h +++ b/src/app-layer-smtp.h @@ -130,6 +130,7 @@ typedef struct SMTPState_ { /** length of the line in current_line. Doesn't include the delimiter */ int32_t current_line_len; uint8_t current_line_delimiter_len; + bool current_line_lf_found; /* Consumed bytes till current line */ int32_t consumed; /* If rest of the bytes should be discarded in case of long line w/o LF */