]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
smtp: config limit maximum number of live transactions
authorPhilippe Antoine <pantoine@oisf.net>
Thu, 9 Nov 2023 11:27:59 +0000 (12:27 +0100)
committerVictor Julien <vjulien@oisf.net>
Tue, 6 Feb 2024 14:16:43 +0000 (15:16 +0100)
Ticket: #6477

doc/userguide/configuration/suricata-yaml.rst
src/app-layer-smtp.c
src/app-layer-smtp.h
suricata.yaml.in

index ebae0bc479f9e029bc41ac3d12ebb78302527ca2..c04573778b03d1e1252def25fa4a1dc82082ea55 100644 (file)
@@ -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
index a4d94a94ded23fbe8f0e3e82e4e1911f43ddbe0b..20eb8f526af85d582f50ca290905ea4e3f70be0e 100644 (file)
 #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;
 }
 
index 9fc1d506bbbb05862f7fe066465f36d822e0fdcf..7977922ebac9e95239806eff1d4c0c1622f6141c 100644 (file)
@@ -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;
 
index 1d3542f059ee6466fbf54f1bab6e7eaf5b197c58..97a7e1318edd2cd05595c3b7a164989a518d4c69 100644 (file)
@@ -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