]> git.ipfire.org Git - people/ms/suricata.git/blobdiff - src/output-json-smtp.c
smtp: log transaction even if no email present
[people/ms/suricata.git] / src / output-json-smtp.c
index f541ff891f0a7d04ef30cab884c29857752a3b4c..5fe126f4184c5a2a53a0bdc6d612cac8773e1767 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2007-2013 Open Information Security Foundation
+/* Copyright (C) 2007-2021 Open Information Security Foundation
  *
  * You can copy, redistribute or modify this Program under the terms of
  * the GNU General Public License version 2 as published by the Free
 #include "util-time.h"
 
 #include "output-json.h"
+#include "output-json-smtp.h"
 #include "output-json-email-common.h"
 
-#ifdef HAVE_LIBJANSSON
-#include <jansson.h>
+static void EveSmtpDataLogger(const Flow *f, void *state, void *vtx, uint64_t tx_id, JsonBuilder *js)
+{
+    SMTPTransaction *tx = vtx;
+    SMTPString *rcptto_str;
+    if (((SMTPState *)state)->helo) {
+        jb_set_string(js, "helo", (const char *)((SMTPState *)state)->helo);
+    }
+    if (tx->mail_from) {
+        jb_set_string(js, "mail_from", (const char *)tx->mail_from);
+    }
+    if (!TAILQ_EMPTY(&tx->rcpt_to_list)) {
+        jb_open_array(js, "rcpt_to");
+        TAILQ_FOREACH(rcptto_str, &tx->rcpt_to_list, next) {
+            jb_append_string(js, (char *)rcptto_str->str);
+        }
+        jb_close(js);
+    }
+}
 
 static int JsonSmtpLogger(ThreadVars *tv, void *thread_data, const Packet *p, Flow *f, void *state, void *tx, uint64_t tx_id)
 {
     SCEnter();
-    int r = JsonEmailLogger(tv, thread_data, p, f, state, tx, tx_id);
-    SCReturnInt(r);
+    JsonEmailLogThread *jhl = (JsonEmailLogThread *)thread_data;
+
+    JsonBuilder *jb = CreateEveHeaderWithTxId(
+            p, LOG_DIR_FLOW, "smtp", NULL, tx_id, jhl->emaillog_ctx->eve_ctx);
+    if (unlikely(jb == NULL))
+        return TM_ECODE_OK;
+
+    jb_open_object(jb, "smtp");
+    EveSmtpDataLogger(f, state, tx, tx_id, jb);
+    jb_close(jb);
+
+    EveEmailLogJson(jhl, jb, p, f, state, tx, tx_id);
+    OutputJsonBuilderBuffer(jb, jhl->ctx);
+
+    jb_free(jb);
+
+    SCReturnInt(TM_ECODE_OK);
+
 }
 
-static void OutputSmtpLogDeInitCtx(OutputCtx *output_ctx)
+bool EveSMTPAddMetadata(const Flow *f, uint64_t tx_id, JsonBuilder *js)
 {
-    OutputJsonEmailCtx *email_ctx = output_ctx->data;
-    if (email_ctx != NULL) {
-        LogFileFreeCtx(email_ctx->file_ctx);
-        SCFree(email_ctx);
+    SMTPState *smtp_state = (SMTPState *)FlowGetAppState(f);
+    if (smtp_state) {
+        SMTPTransaction *tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_SMTP, smtp_state, tx_id);
+        if (tx) {
+            EveSmtpDataLogger(f, smtp_state, tx, tx_id, js);
+            return true;
+        }
     }
-    SCFree(output_ctx);
+
+    return false;
 }
 
 static void OutputSmtpLogDeInitCtxSub(OutputCtx *output_ctx)
@@ -81,59 +118,24 @@ static void OutputSmtpLogDeInitCtxSub(OutputCtx *output_ctx)
     SCFree(output_ctx);
 }
 
-#define DEFAULT_LOG_FILENAME "smtp.json"
-OutputCtx *OutputSmtpLogInit(ConfNode *conf)
-{
-    LogFileCtx *file_ctx = LogFileNewCtx();
-    if(file_ctx == NULL) {
-        SCLogError(SC_ERR_HTTP_LOG_GENERIC, "couldn't create new file_ctx");
-        return NULL;
-    }
-
-    if (SCConfLogOpenGeneric(conf, file_ctx, DEFAULT_LOG_FILENAME) < 0) {
-        LogFileFreeCtx(file_ctx);
-        return NULL;
-    }
-
-    OutputJsonEmailCtx *email_ctx = SCMalloc(sizeof(OutputJsonEmailCtx));
-    if (unlikely(email_ctx == NULL)) {
-        LogFileFreeCtx(file_ctx);
-        return NULL;
-    }
-
-    OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx));
-    if (unlikely(output_ctx == NULL)) {
-        LogFileFreeCtx(file_ctx);
-        SCFree(email_ctx);
-        return NULL;
-    }
-
-    email_ctx->file_ctx = file_ctx;
-
-    output_ctx->data = email_ctx;
-    output_ctx->DeInit = OutputSmtpLogDeInitCtx;
-
-    /* enable the logger for the app layer */
-    AppLayerParserRegisterLogger(IPPROTO_TCP, ALPROTO_SMTP);
-
-    return output_ctx;
-}
-
-static OutputCtx *OutputSmtpLogInitSub(ConfNode *conf, OutputCtx *parent_ctx)
+static OutputInitResult OutputSmtpLogInitSub(ConfNode *conf, OutputCtx *parent_ctx)
 {
-    AlertJsonThread *ajt = parent_ctx->data;
+    OutputInitResult result = { NULL, false };
+    OutputJsonCtx *ojc = parent_ctx->data;
 
     OutputJsonEmailCtx *email_ctx = SCMalloc(sizeof(OutputJsonEmailCtx));
     if (unlikely(email_ctx == NULL))
-        return NULL;
+        return result;
 
     OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx));
     if (unlikely(output_ctx == NULL)) {
         SCFree(email_ctx);
-        return NULL;
+        return result;
     }
 
-    email_ctx->file_ctx = ajt->file_ctx;
+    email_ctx->eve_ctx = ojc;
+
+    OutputEmailInitConf(conf, email_ctx);
 
     output_ctx->data = email_ctx;
     output_ctx->DeInit = OutputSmtpLogDeInitCtxSub;
@@ -141,35 +143,36 @@ static OutputCtx *OutputSmtpLogInitSub(ConfNode *conf, OutputCtx *parent_ctx)
     /* enable the logger for the app layer */
     AppLayerParserRegisterLogger(IPPROTO_TCP, ALPROTO_SMTP);
 
-    return output_ctx;
+    result.ctx = output_ctx;
+    result.ok = true;
+    return result;
 }
 
-#define OUTPUT_BUFFER_SIZE 65535
-static TmEcode JsonSmtpLogThreadInit(ThreadVars *t, void *initdata, void **data)
+static TmEcode JsonSmtpLogThreadInit(ThreadVars *t, const void *initdata, void **data)
 {
-    JsonEmailLogThread *aft = SCMalloc(sizeof(JsonEmailLogThread));
+    JsonEmailLogThread *aft = SCCalloc(1, sizeof(JsonEmailLogThread));
     if (unlikely(aft == NULL))
         return TM_ECODE_FAILED;
-    memset(aft, 0, sizeof(JsonEmailLogThread));
 
-    if(initdata == NULL)
-    {
-        SCLogDebug("Error getting context for HTTPLog.  \"initdata\" argument NULL");
-        SCFree(aft);
-        return TM_ECODE_FAILED;
+    if(initdata == NULL) {
+        SCLogDebug("Error getting context for EveLogSMTP.  \"initdata\" argument NULL");
+        goto error_exit;
     }
 
-    /* Use the Ouptut Context (file pointer and mutex) */
+    /* Use the Output Context (file pointer and mutex) */
     aft->emaillog_ctx = ((OutputCtx *)initdata)->data;
 
-    aft->buffer = MemBufferCreateNew(OUTPUT_BUFFER_SIZE);
-    if (aft->buffer == NULL) {
-        SCFree(aft);
-        return TM_ECODE_FAILED;
+    aft->ctx = CreateEveThreadCtx(t, aft->emaillog_ctx->eve_ctx);
+    if (aft->ctx == NULL) {
+        goto error_exit;
     }
 
     *data = (void *)aft;
     return TM_ECODE_OK;
+
+error_exit:
+    SCFree(aft);
+    return TM_ECODE_FAILED;
 }
 
 static TmEcode JsonSmtpLogThreadDeinit(ThreadVars *t, void *data)
@@ -178,8 +181,8 @@ static TmEcode JsonSmtpLogThreadDeinit(ThreadVars *t, void *data)
     if (aft == NULL) {
         return TM_ECODE_OK;
     }
+    FreeEveThreadCtx(aft->ctx);
 
-    MemBufferFree(aft->buffer);
     /* clear memory */
     memset(aft, 0, sizeof(JsonEmailLogThread));
 
@@ -187,38 +190,9 @@ static TmEcode JsonSmtpLogThreadDeinit(ThreadVars *t, void *data)
     return TM_ECODE_OK;
 }
 
-void TmModuleJsonSmtpLogRegister (void) {
-    tmm_modules[TMM_JSONSMTPLOG].name = "JsonSmtpLog";
-    tmm_modules[TMM_JSONSMTPLOG].ThreadInit = JsonSmtpLogThreadInit;
-    tmm_modules[TMM_JSONSMTPLOG].ThreadDeinit = JsonSmtpLogThreadDeinit;
-    tmm_modules[TMM_JSONSMTPLOG].RegisterTests = NULL;
-    tmm_modules[TMM_JSONSMTPLOG].cap_flags = 0;
-    tmm_modules[TMM_JSONSMTPLOG].flags = TM_FLAG_LOGAPI_TM;
-
-    /* register as separate module */
-    OutputRegisterTxModule("JsonSmtpLog", "smtp-json-log",
-                               OutputSmtpLogInit, ALPROTO_SMTP,
-                               JsonSmtpLogger);
-
-    /* also register as child of eve-log */
-    OutputRegisterTxSubModule("eve-log", "JsonSmtpLog",
-                                  "eve-log.smtp",
-                                  OutputSmtpLogInitSub, ALPROTO_SMTP,
-                                  JsonSmtpLogger);
+void JsonSmtpLogRegister (void) {
+    /* register as child of eve-log */
+    OutputRegisterTxSubModule(LOGGER_JSON_SMTP, "eve-log", "JsonSmtpLog",
+        "eve-log.smtp", OutputSmtpLogInitSub, ALPROTO_SMTP, JsonSmtpLogger,
+        JsonSmtpLogThreadInit, JsonSmtpLogThreadDeinit, NULL);
 }
-
-#else
-
-static TmEcode OutputJsonThreadInit(ThreadVars *t, void *initdata, void **data)
-{
-    SCLogInfo("Can't init JSON output - JSON support was disabled during build.");
-    return TM_ECODE_FAILED;
-}
-
-void TmModuleJsonSmtpLogRegister (void)
-{
-    tmm_modules[TMM_JSONSMTPLOG].name = "JsonSmtpLog";
-    tmm_modules[TMM_JSONSMTPLOG].ThreadInit = OutputJsonThreadInit;
-}
-
-#endif