-/* 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)
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;
/* 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)
if (aft == NULL) {
return TM_ECODE_OK;
}
+ FreeEveThreadCtx(aft->ctx);
- MemBufferFree(aft->buffer);
/* clear memory */
memset(aft, 0, sizeof(JsonEmailLogThread));
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