]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
app-layer-smtp: parse and extract RCPT TO fields
authorEric Leblond <eric@regit.org>
Wed, 22 Apr 2015 12:40:30 +0000 (14:40 +0200)
committerEric Leblond <eric@regit.org>
Fri, 2 Oct 2015 20:57:58 +0000 (22:57 +0200)
Add the RCPT TO fields to a linked list stored in the transaction.

src/app-layer-smtp.c
src/app-layer-smtp.h

index d0c6589eea8fd89908921a9dc8f6fb591263e310..db2dd651ca3660c1e0b3162d1e239188899e5782 100644 (file)
@@ -222,6 +222,8 @@ SCEnumCharMap smtp_reply_map[ ] = {
 /* Create SMTP config structure */
 SMTPConfig smtp_config = { 0, { 0, 0, 0, 0 }, 0, 0, 0};
 
+static SMTPString *SMTPStringAlloc(void);
+
 /**
  * \brief Configure SMTP Mime Decoder by parsing out mime section of YAML
  * config file
@@ -323,6 +325,7 @@ static SMTPTransaction *SMTPTransactionCreate(void)
         return NULL;
     }
 
+    TAILQ_INIT(&tx->rcpt_to_list);
     tx->mime_state = NULL;
     return tx;
 }
@@ -1001,6 +1004,27 @@ static int SMTPParseCommandMAILFROM(SMTPState *state)
                                      &state->curr_tx->mail_from_len);
 }
 
+static int SMTPParseCommandRCPTTO(SMTPState *state)
+{
+    uint8_t *rcptto;
+    uint16_t rcptto_len;
+
+    if (SMTPParseCommandWithParam(state, 7, &rcptto, &rcptto_len) == 0) {
+        SMTPString *rcptto_str = SMTPStringAlloc();
+        if (rcptto_str) {
+            rcptto_str->str = rcptto;
+            rcptto_str->len = rcptto_len;
+            TAILQ_INSERT_TAIL(&state->curr_tx->rcpt_to_list, rcptto_str, next);
+        } else {
+            SCFree(rcptto);
+            return -1;
+        }
+    } else {
+        return -1;
+    }
+    return 0;
+}
+
 /* consider 'rset' and 'quit' to be part of the existing state */
 static int NoNewTx(SMTPState *state)
 {
@@ -1088,6 +1112,13 @@ static int SMTPProcessRequest(SMTPState *state, Flow *f,
                 SCReturnInt(-1);
             }
             state->current_command = SMTP_COMMAND_OTHER_CMD;
+        } else if (state->current_line_len >= 7 &&
+                   SCMemcmpLowercase("rcpt to", state->current_line, 7) == 0) {
+            r = SMTPParseCommandRCPTTO(state);
+            if (r == -1) {
+                SCReturnInt(-1);
+            }
+            state->current_command = SMTP_COMMAND_OTHER_CMD;
         } else {
             state->current_command = SMTP_COMMAND_OTHER_CMD;
         }
@@ -1203,6 +1234,25 @@ void *SMTPStateAlloc(void)
     return smtp_state;
 }
 
+static SMTPString *SMTPStringAlloc(void)
+{
+    SMTPString *smtp_string = SCMalloc(sizeof(SMTPString));
+    if (unlikely(smtp_string == NULL))
+        return NULL;
+    memset(smtp_string, 0, sizeof(SMTPString));
+
+    return smtp_string;
+}
+
+
+static void SMTPStringFree(SMTPString *str)
+{
+    if (str->str) {
+        SCFree(str->str);
+    }
+    SCFree(str);
+}
+
 static void *SMTPLocalStorageAlloc(void)
 {
     /* needed by the mpm */
@@ -1243,6 +1293,11 @@ static void SMTPTransactionFree(SMTPTransaction *tx, SMTPState *state)
     if (tx->mail_from)
         SCFree(tx->mail_from);
 
+    SMTPString *str = NULL;
+    while ((str = TAILQ_FIRST(&tx->rcpt_to_list))) {
+        TAILQ_REMOVE(&tx->rcpt_to_list, str, next);
+        SMTPStringFree(str);
+    }
 #if 0
         if (tx->decoder_events->cnt <= smtp_state->events)
             smtp_state->events -= tx->decoder_events->cnt;
index a63061638ea692d19d051e3a5374d32bb270b8f1..c58684143ab0845c445b8f1c4ccb22cc71c2b5d5 100644 (file)
@@ -51,6 +51,13 @@ enum {
     SMTP_DECODER_EVENT_MIME_BOUNDARY_TOO_LONG,
 };
 
+typedef struct SMTPString_ {
+    uint8_t *str;
+    uint16_t len;
+
+    TAILQ_ENTRY(SMTPString_) next;
+} SMTPString;
+
 typedef struct SMTPTransaction_ {
     /** id of this tx, starting at 0 */
     uint64_t tx_id;
@@ -69,6 +76,8 @@ typedef struct SMTPTransaction_ {
     uint8_t *mail_from;
     uint16_t mail_from_len;
 
+    TAILQ_HEAD(, SMTPString_) rcpt_to_list;  /**< rcpt to string list */
+
     TAILQ_ENTRY(SMTPTransaction_) next;
 } SMTPTransaction;