diff --git a/doc/userguide/configuration/suricata-yaml.rst b/doc/userguide/configuration/suricata-yaml.rst index ebae0bc479..c04573778b 100644 --- a/doc/userguide/configuration/suricata-yaml.rst +++ b/doc/userguide/configuration/suricata-yaml.rst @@ -1748,7 +1748,7 @@ incompatible with ``decode-mime``. If both are enabled, Maximum transactions ~~~~~~~~~~~~~~~~~~~~ -MQTT, FTP, PostgreSQL, SMB, DCERPC, HTTP1 and NFS have each a `max-tx` parameter that can be customized. +SMTP, MQTT, FTP, PostgreSQL, SMB, DCERPC, HTTP1 and NFS have each a `max-tx` parameter that can be customized. `max-tx` refers to the maximum number of live transactions for each flow. An app-layer event `protocol.too_many_transactions` is triggered when this value is reached. The point of this parameter is to find a balance between the completeness of analysis diff --git a/src/app-layer-smtp.c b/src/app-layer-smtp.c index a4d94a94de..20eb8f526a 100644 --- a/src/app-layer-smtp.c +++ b/src/app-layer-smtp.c @@ -112,6 +112,8 @@ #define SMTP_EHLO_EXTENSION_STARTTLS #define SMTP_EHLO_EXTENSION_8BITMIME +#define SMTP_DEFAULT_MAX_TX 256 + typedef struct SMTPInput_ { /* current input that is being parsed */ const uint8_t *buf; @@ -421,6 +423,18 @@ static void SMTPConfigure(void) { smtp_config.raw_extraction = 0; } + uint64_t value = SMTP_DEFAULT_MAX_TX; + smtp_config.max_tx = SMTP_DEFAULT_MAX_TX; + const char *str = NULL; + if (ConfGet("app-layer.protocols.smtp.max-tx", &str) == 1) { + if (ParseSizeStringU64(str, &value) < 0) { + SCLogWarning("max-tx value cannot be deduced: %s," + " keeping default", + str); + } + smtp_config.max_tx = value; + } + SCReturn; } @@ -436,8 +450,11 @@ static void SMTPSetEvent(SMTPState *s, uint8_t e) SCLogDebug("couldn't set event %u", e); } -static SMTPTransaction *SMTPTransactionCreate(void) +static SMTPTransaction *SMTPTransactionCreate(SMTPState *state) { + if (state->tx_cnt > smtp_config.max_tx) { + return NULL; + } SMTPTransaction *tx = SCCalloc(1, sizeof(*tx)); if (tx == NULL) { return NULL; @@ -1170,7 +1187,7 @@ static int SMTPProcessRequest(SMTPState *state, Flow *f, AppLayerParserState *ps return 0; } if (state->curr_tx == NULL || (state->curr_tx->done && !NoNewTx(state, line))) { - tx = SMTPTransactionCreate(); + tx = SMTPTransactionCreate(state); if (tx == NULL) return -1; state->curr_tx = tx; @@ -1203,7 +1220,7 @@ static int SMTPProcessRequest(SMTPState *state, Flow *f, AppLayerParserState *ps // we did not close the previous tx, set error SMTPSetEvent(state, SMTP_DECODER_EVENT_UNPARSABLE_CONTENT); FileCloseFile(&tx->files_ts, &smtp_config.sbcfg, NULL, 0, FILE_TRUNCATED); - tx = SMTPTransactionCreate(); + tx = SMTPTransactionCreate(state); if (tx == NULL) return -1; state->curr_tx = tx; @@ -1221,7 +1238,7 @@ static int SMTPProcessRequest(SMTPState *state, Flow *f, AppLayerParserState *ps * of first one. So we start a new transaction. */ tx->mime_state->state_flag = PARSE_ERROR; SMTPSetEvent(state, SMTP_DECODER_EVENT_UNPARSABLE_CONTENT); - tx = SMTPTransactionCreate(); + tx = SMTPTransactionCreate(state); if (tx == NULL) return -1; state->curr_tx = tx; @@ -1932,6 +1949,8 @@ static void SMTPTestInitConfig(void) smtp_config.content_inspect_window = FILEDATA_CONTENT_INSPECT_WINDOW; smtp_config.content_inspect_min_size = FILEDATA_CONTENT_INSPECT_MIN_SIZE; + smtp_config.max_tx = SMTP_DEFAULT_MAX_TX; + smtp_config.sbcfg.buf_size = FILEDATA_CONTENT_INSPECT_WINDOW; } diff --git a/src/app-layer-smtp.h b/src/app-layer-smtp.h index 9fc1d506bb..7977922eba 100644 --- a/src/app-layer-smtp.h +++ b/src/app-layer-smtp.h @@ -101,6 +101,7 @@ typedef struct SMTPConfig { uint32_t content_limit; uint32_t content_inspect_min_size; uint32_t content_inspect_window; + uint64_t max_tx; bool raw_extraction; diff --git a/suricata.yaml.in b/suricata.yaml.in index 1d3542f059..97a7e1318e 100644 --- a/suricata.yaml.in +++ b/suricata.yaml.in @@ -934,6 +934,8 @@ app-layer: smtp: enabled: yes raw-extraction: no + # Maximum number of live SMTP transactions per flow + # max-tx: 256 # Configure SMTP-MIME Decoder mime: # Decode MIME messages from SMTP transactions