]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
Support for configuration of JSON http output module
authorTom DeCanio <decanio.tom@gmail.com>
Tue, 5 Nov 2013 22:48:39 +0000 (14:48 -0800)
committerVictor Julien <victor@inliniac.net>
Wed, 29 Jan 2014 10:07:51 +0000 (11:07 +0100)
src/alert-json.c
src/alert-json.h
src/output-httplog.c
src/output-httplog.h

index eb6de6be6c2acfcae75badc6936b0c694ce77e2d..22a6fc28903117a46d019820121903d3684dfa70 100644 (file)
@@ -516,7 +516,11 @@ TmEcode AlertJsonThreadInit(ThreadVars *t, void *initdata, void **data)
     }
 
     /** Use the Ouptut Context (file pointer and mutex) */
-    aft->file_ctx = ((OutputCtx *)initdata)->data;
+    OutputJsonCtx *json_ctx = ((OutputCtx *)initdata)->data;
+    if (json_ctx != NULL) {
+        aft->file_ctx = json_ctx->file_ctx;
+        aft->http_ctx = json_ctx->http_ctx;
+    }
 
     *data = (void *)aft;
     return TM_ECODE_OK;
@@ -550,17 +554,24 @@ void AlertJsonExitPrintStats(ThreadVars *tv, void *data) {
  */
 OutputCtx *AlertJsonInitCtx(ConfNode *conf)
 {
-    LogFileCtx *logfile_ctx = LogFileNewCtx();
-    if (logfile_ctx == NULL) {
+    OutputJsonCtx *json_ctx = SCCalloc(1, sizeof(OutputJsonCtx));;
+    if (unlikely(json_ctx == NULL)) {
         SCLogDebug("AlertJsonInitCtx: Could not create new LogFileCtx");
         return NULL;
     }
 
+    json_ctx->file_ctx = LogFileNewCtx();
+    if (unlikely(json_ctx->file_ctx == NULL)) {
+        SCLogDebug("AlertJsonInitCtx: Could not create new LogFileCtx");
+        SCFree(json_ctx);
+        return NULL;
+    }
 
     OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx));
     if (unlikely(output_ctx == NULL))
         return NULL;
-    output_ctx->data = logfile_ctx;
+
+    output_ctx->data = json_ctx;
     output_ctx->DeInit = AlertJsonDeInitCtx;
 
     if (conf) {
@@ -583,8 +594,8 @@ OutputCtx *AlertJsonInitCtx(ConfNode *conf)
 
         if (json_out == ALERT_FILE) {
 
-            if (SCConfLogOpenGeneric(conf, logfile_ctx, DEFAULT_LOG_FILENAME) < 0) {
-                LogFileFreeCtx(logfile_ctx);
+            if (SCConfLogOpenGeneric(conf, json_ctx->file_ctx, DEFAULT_LOG_FILENAME) < 0) {
+                LogFileFreeCtx(json_ctx->file_ctx);
                 return NULL;
             }
 
@@ -660,7 +671,15 @@ OutputCtx *AlertJsonInitCtx(ConfNode *conf)
                 }
                 if (strcmp(output->val, "http") == 0) {
                     SCLogDebug("Enabling HTTP output");
-                    outputFlags |= OUTPUT_HTTP;
+                    /* Yuck.  there has to be a better way */
+                    ConfNode *child = ConfNodeLookupChild(output, "http");
+                    if (child) {
+                        json_ctx->http_ctx = OutputHttpLogInit(child);
+                        if (json_ctx->http_ctx != NULL)
+                            outputFlags |= OUTPUT_HTTP;
+                    } else {
+                        outputFlags |= OUTPUT_HTTP;
+                    }
                     continue;
                 }
             }
@@ -672,7 +691,8 @@ OutputCtx *AlertJsonInitCtx(ConfNode *conf)
 
 static void AlertJsonDeInitCtx(OutputCtx *output_ctx)
 {
-    LogFileCtx *logfile_ctx = (LogFileCtx *)output_ctx->data;
+    OutputJsonCtx *json_ctx = (OutputJsonCtx *)output_ctx->data;
+    LogFileCtx *logfile_ctx = json_ctx->file_ctx;
     LogFileFreeCtx(logfile_ctx);
     SCFree(output_ctx);
 }
index ed104070567fe4a37d3d963bbfa4fafa8a1d1a43..34bf4a8edcae864eed30ea654a2804243086cd2f 100644 (file)
@@ -32,6 +32,15 @@ void TmModuleAlertJsonIPv4Register (void);
 void TmModuleAlertJsonPv6Register (void);
 OutputCtx *AlertJsonInitCtx(ConfNode *);
 
+/* TODO: I think the following structures can be made private again */
+/*
+ * Global configuration context data
+ */
+typedef struct OutputJsonCtx_ {
+    LogFileCtx *file_ctx;
+    OutputCtx *http_ctx;
+} OutputJsonCtx;
+
 typedef struct AlertJsonThread_ {
     /** LogFileCtx has the pointer to the file and a mutex to allow multithreading */
     LogFileCtx* file_ctx;
@@ -41,7 +50,8 @@ typedef struct AlertJsonThread_ {
     uint64_t alert_cnt;
     uint64_t dns_cnt;
     uint64_t http_cnt;
-    uint32_t http_flags;
+    //uint32_t http_flags;
+    OutputCtx *http_ctx;
 } AlertJsonThread;
 
 #endif /* __ALERT_JSON_H__ */
index 7b3d1a099838950e3efb0ffc5e28694b8b614575..fd86bd60ecbfd3f2d67d9005c78e8cabf48bfe49 100644 (file)
@@ -83,18 +83,24 @@ typedef struct LogHttpCustomFormatNode_ {
     char data[LOG_HTTP_NODE_STRLEN]; /** optional data. ie: http header name */
 } LogHttpCustomFormatNode;
 
+#if 1
+typedef struct OutputHttpCtx_ {
+    uint32_t flags; /** Store mode */
+} OutputHttpCtx;
+#else
 typedef struct LogHttpFileCtx_ {
     LogFileCtx *file_ctx;
     uint32_t flags; /** Store mode */
     uint32_t cf_n; /** Total number of custom string format nodes */
     LogHttpCustomFormatNode *cf_nodes[LOG_HTTP_MAXN_NODES]; /** Custom format string nodes */
 } LogHttpFileCtx;
+#endif
 
 #define LOG_HTTP_DEFAULT 0
 #define LOG_HTTP_EXTENDED 1
 #define LOG_HTTP_CUSTOM 2
-#define LOG_HTTP_JSON_SYSLOG 8 /* JSON output via syslog */
 
+#if 0
 typedef struct LogHttpLogThread_ {
     LogHttpFileCtx *httplog_ctx;
     /** LogFileCtx has the pointer to the file and a mutex to allow multithreading */
@@ -102,6 +108,7 @@ typedef struct LogHttpLogThread_ {
 
     MemBuffer *buffer;
 } LogHttpLogThread;
+#endif
 
 /* Retrieves the selected cookie value */
 static uint32_t GetCookieValue(uint8_t *rawcookies, uint32_t rawcookies_len, char *cookiename,
@@ -328,12 +335,13 @@ static void LogHttpLogJSONCustom(AlertJsonThread *aft, json_t *js, htp_tx_t *tx,
 #endif
 }
 
-#ifdef HAVE_LIBJANSSON
 /* JSON format logging */
 static void LogHttpLogJSON(AlertJsonThread *aft, json_t *js, htp_tx_t *tx /*, char * timebuf,
                            char *srcip, Port sp, char *dstip, Port dp,
                            char *proto*/)
 {
+    //OutputHttpCtx *http_ctx = aft->http_ctx;
+    OutputHttpCtx *http_ctx = aft->http_ctx->data;
     json_t *hjs = json_object();
     if (hjs == NULL) {
         free(js);
@@ -402,7 +410,7 @@ static void LogHttpLogJSON(AlertJsonThread *aft, json_t *js, htp_tx_t *tx /*, ch
         if (c) free(c);
     }
 
-    if (aft->http_flags & LOG_HTTP_EXTENDED) {
+    if (http_ctx->flags & LOG_HTTP_EXTENDED) {
         /* referer */
         htp_header_t *h_referer = NULL;
         if (tx->request_headers != NULL) {
@@ -453,8 +461,8 @@ static void LogHttpLogJSON(AlertJsonThread *aft, json_t *js, htp_tx_t *tx /*, ch
 
     json_object_set_new(js, "http", hjs);
 }
-#endif
 
+#if 0
 static void LogHttpLogExtended(LogHttpLogThread *aft, htp_tx_t *tx)
 {
     MemBufferWriteString(aft->buffer, " [**] ");
@@ -514,6 +522,7 @@ static void LogHttpLogExtended(LogHttpLogThread *aft, htp_tx_t *tx)
     /* length */
     MemBufferWriteString(aft->buffer, " [**] %"PRIuMAX" bytes", (uintmax_t)tx->response_message_len);
 }
+#endif
 
 static TmEcode HttpJsonIPWrapper(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq,
                             PacketQueue *postpq/*, int ipproto*/)
@@ -529,6 +538,7 @@ static TmEcode HttpJsonIPWrapper(ThreadVars *tv, Packet *p, void *data, PacketQu
     int tx_progress_done_value_tc = 0;
     AlertJsonThread *aft = (AlertJsonThread *)data;
     MemBuffer *buffer = (MemBuffer *)aft->buffer;
+    OutputHttpCtx *http_ctx = aft->http_ctx->data;
 
     /* no flow, no htp state */
     if (p->flow == NULL) {
@@ -579,7 +589,8 @@ static TmEcode HttpJsonIPWrapper(ThreadVars *tv, Packet *p, void *data, PacketQu
         /* reset */
         MemBufferReset(buffer);
 
-        if (aft->http_flags & LOG_HTTP_CUSTOM) {
+        //if (aft->http_flags & LOG_HTTP_CUSTOM) {
+        if (http_ctx->flags & LOG_HTTP_CUSTOM) {
             LogHttpLogJSONCustom(aft, js, tx, &p->ts/*, srcip, sp, dstip, dp*/);
         } else {
             LogHttpLogJSON(aft, js, tx /*, timebuf, srcip, sp, dstip, dp, proto_s*/);
@@ -605,4 +616,30 @@ TmEcode OutputHttpLog (ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, P
     HttpJsonIPWrapper(tv, p, data, pq, postpq);
     SCReturnInt(TM_ECODE_OK);
 }
+
+OutputCtx *OutputHttpLogInit(ConfNode *conf)
+{
+    OutputHttpCtx *http_ctx = SCMalloc(sizeof(OutputHttpCtx));
+    if (unlikely(http_ctx == NULL))
+        return NULL;
+
+    OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx));
+    if (unlikely(output_ctx == NULL))
+        return NULL;
+
+    const char *extended = ConfNodeLookupChildValue(conf, "extended");
+
+    http_ctx->flags = LOG_HTTP_DEFAULT;
+
+    if (extended != NULL) {
+        if (ConfValIsTrue(extended)) {
+            http_ctx->flags = LOG_HTTP_EXTENDED;
+        }
+    }
+    output_ctx->data = http_ctx;
+    output_ctx->DeInit = NULL;
+
+    return output_ctx;
+}
+
 #endif
index 16c912f91022fb7342bcab53471a16f70f063658..50528d7613c0d4f83e9b9bccc324ce44ae5e7d14 100644 (file)
 /**
  * \file
  *
- * \author Victor Julien <victor@inliniac.net>
+ * \author Tom DeCanio <td@npulsetech.com>
  */
 
 #ifndef __OUTPUT_HTTPLOG_H__
 #define __OUTPUT_HTTPLOG_H__
+
 TmEcode OutputHttpLog (ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq);
 
-void TmModuleHttpJsonRegister (void);
-void TmModuleHttpJsonIPv4Register (void);
-void TmModuleHttpJsonIPv6Register (void);
-OutputCtx *HttpJsonInitCtx(ConfNode *);
+//void TmModuleHttpJsonRegister (void);
+//void TmModuleHttpJsonIPv4Register (void);
+//void TmModuleHttpJsonIPv6Register (void);
+//OutputCtx *HttpJsonInitCtx(ConfNode *);
 
+OutputCtx *OutputHttpLogInit(ConfNode *);
 #endif /* __OUTPUT_HTTPLOG_H__ */
+