From: Jeff Lucovsky Date: Sat, 6 Jun 2020 18:05:39 +0000 (-0400) Subject: ftp/eve: Convert FTP logging to use JsonBuilder X-Git-Tag: suricata-6.0.0-beta1~319 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=03de315bc2c419165802a270eb244b846ef8c143;p=thirdparty%2Fsuricata.git ftp/eve: Convert FTP logging to use JsonBuilder This commit converts the FTP logging mechanisms to use JsonBuilder. --- diff --git a/src/app-layer-ftp.c b/src/app-layer-ftp.c index 367bbae66d..6a19e3a31c 100644 --- a/src/app-layer-ftp.c +++ b/src/app-layer-ftp.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2007-2017 Open Information Security Foundation +/* Copyright (C) 2007-2020 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 @@ -55,7 +55,6 @@ #include "util-debug.h" #include "util-memcmp.h" #include "util-memrchr.h" -#include "util-byte.h" #include "util-mem.h" #include "util-misc.h" @@ -1439,36 +1438,31 @@ uint16_t JsonGetNextLineFromBuffer(const char *buffer, const uint16_t len) return c == NULL ? len : c - buffer + 1; } -json_t *JsonFTPDataAddMetadata(const Flow *f) +void JsonFTPDataAddMetadata(const Flow *f, JsonBuilder *jb) { const FtpDataState *ftp_state = NULL; if (f->alstate == NULL) - return NULL; + return; + ftp_state = (FtpDataState *)f->alstate; - json_t *ftpd = json_object(); - if (ftpd == NULL) - return NULL; + if (ftp_state->file_name) { - size_t size = ftp_state->file_len * 2 + 1; - char string[size]; - BytesToStringBuffer(ftp_state->file_name, ftp_state->file_len, string, size); - json_object_set_new(ftpd, "filename", SCJsonString(string)); + jb_set_string_from_bytes(jb, "filename", ftp_state->file_name, ftp_state->file_len); } switch (ftp_state->command) { case FTP_COMMAND_STOR: - json_object_set_new(ftpd, "command", json_string("STOR")); + JB_SET_STRING(jb, "command", "STOR"); break; case FTP_COMMAND_RETR: - json_object_set_new(ftpd, "command", json_string("RETR")); + JB_SET_STRING(jb, "command", "RETR"); break; default: break; } - return ftpd; } /** - * \brief Free memory allocated for global SMTP parser state. + * \brief Free memory allocated for global FTP parser state. */ void FTPParserCleanup(void) { diff --git a/src/app-layer-ftp.h b/src/app-layer-ftp.h index 7c8bab2d0b..081b23f7d3 100644 --- a/src/app-layer-ftp.h +++ b/src/app-layer-ftp.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation +/* Copyright (C) 2007-2020 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 @@ -25,6 +25,8 @@ #ifndef __APP_LAYER_FTP_H__ #define __APP_LAYER_FTP_H__ +#include "rust.h" + enum { FTP_STATE_IN_PROGRESS, FTP_STATE_PORT_DONE, @@ -221,7 +223,7 @@ uint64_t FTPMemuseGlobalCounter(void); uint64_t FTPMemcapGlobalCounter(void); uint16_t JsonGetNextLineFromBuffer(const char *buffer, const uint16_t len); -json_t *JsonFTPDataAddMetadata(const Flow *f); +void JsonFTPDataAddMetadata(const Flow *f, JsonBuilder *jb); #endif /* __APP_LAYER_FTP_H__ */ diff --git a/src/output-json-alert.c b/src/output-json-alert.c index 7f93b99245..9765128216 100644 --- a/src/output-json-alert.c +++ b/src/output-json-alert.c @@ -413,7 +413,6 @@ static int AlertJson(ThreadVars *tv, JsonAlertLogThread *aft, const Packet *p) { MemBuffer *payload = aft->payload_buffer; AlertJsonOutputCtx *json_output_ctx = aft->json_output_ctx; - json_t *hjs = NULL; int i; @@ -550,11 +549,7 @@ static int AlertJson(ThreadVars *tv, JsonAlertLogThread *aft, const Packet *p) break; } case ALPROTO_FTPDATA: - hjs = JsonFTPDataAddMetadata(p->flow); - if (hjs) { - jb_set_jsont(jb, "ftp-data", hjs); - json_decref(hjs); - } + JsonFTPDataAddMetadata(p->flow, jb); break; case ALPROTO_DNP3: AlertJsonDnp3(p->flow, pa->tx_id, jb); diff --git a/src/output-json-ftp.c b/src/output-json-ftp.c index cd34ed61aa..3d5029da37 100644 --- a/src/output-json-ftp.c +++ b/src/output-json-ftp.c @@ -38,7 +38,6 @@ #include "util-buffer.h" #include "util-debug.h" #include "util-mem.h" -#include "util-byte.h" #include "output.h" #include "output-json.h" @@ -60,41 +59,31 @@ typedef struct LogFTPLogThread_ { MemBuffer *buffer; } LogFTPLogThread; -static json_t *JsonFTPLogCommand(Flow *f, FTPTransaction *tx) +static void JsonFTPLogCommand(Flow *f, FTPTransaction *tx, JsonBuilder *jb) { - json_t *cjs = json_object(); - if (!cjs) { - return cjs; - } - /* Preallocate array objects to simplify failure case */ - json_t *js_resplist = NULL; - json_t *js_respcode_list = NULL; + JsonBuilder *js_resplist = NULL; + JsonBuilder *js_respcode_list = NULL; if (!TAILQ_EMPTY(&tx->response_list)) { - js_resplist = json_array(); - js_respcode_list = json_array(); + js_resplist = jb_new_array(); + js_respcode_list = jb_new_array(); if (unlikely(js_resplist == NULL || js_respcode_list == NULL)) { - if (js_resplist) { - json_decref(js_resplist); - } else { - json_decref(js_respcode_list); - } - return cjs; + goto fail; } } - - json_object_set_new(cjs, "command", json_string(tx->command_descriptor->command_name)); + jb_set_string(jb, "command", tx->command_descriptor->command_name); uint32_t min_length = tx->command_descriptor->command_length + 1; /* command + space */ if (tx->request_length > min_length) { - json_object_set_new(cjs, "command_data", - JsonAddStringN((const char *)tx->request + min_length, - tx->request_length - min_length)); - } else { - json_object_set_new(cjs, "command_data", json_string(NULL)); + jb_set_string_from_bytes(jb, + "command_data", + (const uint8_t *)tx->request + min_length, + tx->request_length - min_length - 1); } if (!TAILQ_EMPTY(&tx->response_list)) { + int resp_code_cnt = 0; + int resp_cnt = 0; FTPString *response; TAILQ_FOREACH(response, &tx->response_list, next) { /* handle multiple lines within the response, \r\n delimited */ @@ -107,15 +96,15 @@ static json_t *JsonFTPLogCommand(Flow *f, FTPTransaction *tx) if (pos >= 3) { /* Gather the completion code if present */ if (isdigit(where[0]) && isdigit(where[1]) && isdigit(where[2])) { - json_array_append_new(js_respcode_list, - JsonAddStringN((const char *)where, 3)); + jb_append_string_from_bytes(js_respcode_list, (const uint8_t *)where, 3); + resp_code_cnt++; offset = 4; } } /* move past 3 character completion code */ if (pos >= offset) { - json_array_append_new(js_resplist, - JsonAddStringN((const char *)where + offset, pos - offset)); + jb_append_string_from_bytes(js_resplist, (const uint8_t *)where + offset, pos - offset); + resp_cnt++; } where += pos; @@ -123,24 +112,46 @@ static json_t *JsonFTPLogCommand(Flow *f, FTPTransaction *tx) } } - json_object_set_new(cjs, "reply", js_resplist); - json_object_set_new(cjs, "completion_code", js_respcode_list); + if (resp_cnt) { + jb_close(js_resplist); + jb_set_object(jb, "reply", js_resplist); + } + jb_free(js_resplist); + if (resp_code_cnt) { + jb_close(js_respcode_list); + jb_set_object(jb, "completion_code", js_respcode_list); + } + jb_free(js_respcode_list); } if (tx->dyn_port) { - json_object_set_new(cjs, "dynamic_port", json_integer(tx->dyn_port)); + jb_set_uint(jb, "dynamic_port", tx->dyn_port); } if (tx->command_descriptor->command == FTP_COMMAND_PORT || tx->command_descriptor->command == FTP_COMMAND_EPRT) { - json_object_set_new(cjs, "mode", - json_string((char *)(tx->active ? "active" : "passive"))); + if (tx->active) { + JB_SET_STRING(jb, "mode", "active"); + } else { + JB_SET_STRING(jb, "mode", "passive"); + } + } + + if (tx->done) { + JB_SET_STRING(jb, "reply_received", "yes"); + } else { + JB_SET_STRING(jb, "reply_received", "no"); } - json_object_set_new(cjs, "reply_received", - json_string((char *)(tx->done ? "yes" : "no"))); + return; - return cjs; +fail: + if (js_resplist) { + jb_free(js_resplist); + } + if (js_respcode_list) { + jb_free(js_respcode_list); + } } @@ -159,27 +170,30 @@ static int JsonFTPLogger(ThreadVars *tv, void *thread_data, LogFTPLogThread *thread = thread_data; LogFTPFileCtx *ftp_ctx = thread->ftplog_ctx; - json_t *js = CreateJSONHeaderWithTxId(p, LOG_DIR_FLOW, event_type, tx_id); - if (likely(js)) { - JsonAddCommonOptions(&ftp_ctx->cfg, p, f, js); - json_t *cjs = NULL; + JsonBuilder *jb = CreateEveHeaderWithTxId(p, LOG_DIR_FLOW, event_type, NULL, tx_id); + if (likely(jb)) { + EveAddCommonOptions(&ftp_ctx->cfg, p, f, jb); + jb_open_object(jb, event_type); if (f->alproto == ALPROTO_FTPDATA) { - cjs = JsonFTPDataAddMetadata(f); + JsonFTPDataAddMetadata(f, jb); } else { - cjs = JsonFTPLogCommand(f, tx); + JsonFTPLogCommand(f, tx, jb); } - if (cjs) { - json_object_set_new(js, event_type, cjs); + if (!jb_close(jb)) { + goto fail; } MemBufferReset(thread->buffer); - OutputJSONBuffer(js, thread->ftplog_ctx->file_ctx, &thread->buffer); + OutputJsonBuilderBuffer(jb, thread->ftplog_ctx->file_ctx, &thread->buffer); - json_object_clear(js); - json_decref(js); + jb_free(jb); } return TM_ECODE_OK; + +fail: + jb_free(jb); + return TM_ECODE_FAILED; } static void OutputFTPLogDeInitCtxSub(OutputCtx *output_ctx)