]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
ftp/eve: Convert FTP logging to use JsonBuilder
authorJeff Lucovsky <jeff@lucovsky.org>
Sat, 6 Jun 2020 18:05:39 +0000 (14:05 -0400)
committerVictor Julien <victor@inliniac.net>
Sun, 28 Jun 2020 12:16:16 +0000 (14:16 +0200)
This commit converts the FTP logging mechanisms to use JsonBuilder.

src/app-layer-ftp.c
src/app-layer-ftp.h
src/output-json-alert.c
src/output-json-ftp.c

index 367bbae66da87987f80659e7092f6d6286fed7ed..6a19e3a31cb6e5b07ea8dcd922cf96d8031aaf88 100644 (file)
@@ -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)
 {
index 7c8bab2d0bba1edf543583519d86025c058cac86..081b23f7d370240591b51a10f93663df4c919521 100644 (file)
@@ -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__ */
 
index 7f93b99245fd3348b462e8f47a8ddcd7a086815c..9765128216e477e16cc3ae219906cd32dcf99462 100644 (file)
@@ -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);
index cd34ed61aa4bcd45c6a988d07a5e0d5ef6a50e5d..3d5029da376562ff90753f9277d515504b6df827 100644 (file)
@@ -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)