-/* Copyright (C) 2007-2015 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 "output-json-smtp.h"
#include "output-json-email-common.h"
-#ifdef HAVE_LIBJANSSON
-
-static json_t *JsonSmtpDataLogger(const Flow *f, void *state, void *vtx, uint64_t tx_id)
+static void EveSmtpDataLogger(const Flow *f, void *state, void *vtx, uint64_t tx_id, JsonBuilder *js)
{
- json_t *sjs = json_object();
SMTPTransaction *tx = vtx;
SMTPString *rcptto_str;
- if (sjs == NULL) {
- return NULL;
- }
if (((SMTPState *)state)->helo) {
- json_object_set_new(sjs, "helo",
- json_string((const char *)((SMTPState *)state)->helo));
+ jb_set_string(js, "helo", (const char *)((SMTPState *)state)->helo);
}
if (tx->mail_from) {
- json_object_set_new(sjs, "mail_from",
- json_string((const char *)tx->mail_from));
+ jb_set_string(js, "mail_from", (const char *)tx->mail_from);
}
if (!TAILQ_EMPTY(&tx->rcpt_to_list)) {
- json_t *js_rcptto = json_array();
- if (likely(js_rcptto != NULL)) {
- TAILQ_FOREACH(rcptto_str, &tx->rcpt_to_list, next) {
- json_array_append_new(js_rcptto, json_string((char *)rcptto_str->str));
- }
- json_object_set_new(sjs, "rcpt_to", js_rcptto);
+ 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);
}
-
- return sjs;
}
static int JsonSmtpLogger(ThreadVars *tv, void *thread_data, const Packet *p, Flow *f, void *state, void *tx, uint64_t tx_id)
SCEnter();
JsonEmailLogThread *jhl = (JsonEmailLogThread *)thread_data;
- json_t *sjs;
- json_t *js = CreateJSONHeaderWithTxId((Packet *)p, 1, "smtp", tx_id);
- if (unlikely(js == NULL))
+ JsonBuilder *jb = CreateEveHeaderWithTxId(
+ p, LOG_DIR_FLOW, "smtp", NULL, tx_id, jhl->emaillog_ctx->eve_ctx);
+ if (unlikely(jb == NULL))
return TM_ECODE_OK;
- /* reset */
- MemBufferReset(jhl->buffer);
+ jb_open_object(jb, "smtp");
+ EveSmtpDataLogger(f, state, tx, tx_id, jb);
+ jb_close(jb);
- sjs = JsonSmtpDataLogger(f, state, tx, tx_id);
- if (sjs) {
- json_object_set_new(js, "smtp", sjs);
- }
-
- if (JsonEmailLogJson(jhl, js, p, f, state, tx, tx_id) == TM_ECODE_OK) {
- OutputJSONBuffer(js, jhl->emaillog_ctx->file_ctx, &jhl->buffer);
- }
- json_object_del(js, "email");
- if (sjs) {
- json_object_del(js, "smtp");
- }
+ EveEmailLogJson(jhl, jb, p, f, state, tx, tx_id);
+ OutputJsonBuilderBuffer(jb, jhl->ctx);
- json_object_clear(js);
- json_decref(js);
+ jb_free(jb);
SCReturnInt(TM_ECODE_OK);
}
-json_t *JsonSMTPAddMetadata(const Flow *f, uint64_t tx_id)
+bool EveSMTPAddMetadata(const Flow *f, uint64_t tx_id, JsonBuilder *js)
{
SMTPState *smtp_state = (SMTPState *)FlowGetAppState(f);
if (smtp_state) {
SMTPTransaction *tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_SMTP, smtp_state, tx_id);
-
if (tx) {
- return JsonSmtpDataLogger(f, smtp_state, tx, tx_id);
+ EveSmtpDataLogger(f, smtp_state, tx, tx_id, js);
+ return true;
}
}
- return NULL;
-}
-
-static void OutputSmtpLogDeInitCtx(OutputCtx *output_ctx)
-{
- OutputJsonEmailCtx *email_ctx = output_ctx->data;
- if (email_ctx != NULL) {
- LogFileFreeCtx(email_ctx->file_ctx);
- SCFree(email_ctx);
- }
- SCFree(output_ctx);
+ return false;
}
static void OutputSmtpLogDeInitCtxSub(OutputCtx *output_ctx)
SCFree(output_ctx);
}
-#define DEFAULT_LOG_FILENAME "smtp.json"
-static OutputCtx *OutputSmtpLogInit(ConfNode *conf)
-{
- LogFileCtx *file_ctx = LogFileNewCtx();
- if(file_ctx == NULL) {
- SCLogError(SC_ERR_SMTP_LOG_GENERIC, "couldn't create new file_ctx");
- return NULL;
- }
-
- if (SCConfLogOpenGeneric(conf, file_ctx, DEFAULT_LOG_FILENAME, 1) < 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)
{
+ 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 = ojc->file_ctx;
+ email_ctx->eve_ctx = ojc;
OutputEmailInitConf(conf, email_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, 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)
- {
+ if(initdata == NULL) {
SCLogDebug("Error getting context for EveLogSMTP. \"initdata\" argument NULL");
- SCFree(aft);
- return TM_ECODE_FAILED;
+ 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));
}
void JsonSmtpLogRegister (void) {
- /* register as separate module */
- OutputRegisterTxModule(LOGGER_JSON_SMTP, "JsonSmtpLog", "smtp-json-log",
- OutputSmtpLogInit, ALPROTO_SMTP, JsonSmtpLogger, JsonSmtpLogThreadInit,
- JsonSmtpLogThreadDeinit, NULL);
-
- /* also register as child of eve-log */
+ /* register as child of eve-log */
OutputRegisterTxSubModule(LOGGER_JSON_SMTP, "eve-log", "JsonSmtpLog",
"eve-log.smtp", OutputSmtpLogInitSub, ALPROTO_SMTP, JsonSmtpLogger,
JsonSmtpLogThreadInit, JsonSmtpLogThreadDeinit, NULL);
}
-
-#else
-
-void JsonSmtpLogRegister (void)
-{
-}
-
-#endif