]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
tls json: turn into packet logger
authorVictor Julien <victor@inliniac.net>
Thu, 30 Jan 2014 10:45:30 +0000 (11:45 +0100)
committerVictor Julien <victor@inliniac.net>
Thu, 30 Jan 2014 10:45:30 +0000 (11:45 +0100)
Like log-tls, turn the json tls logger into a packet logger as the
protocol parser is not tx aware.

Make it a child of eve-log as well.

src/output-json.c
src/output-tlslog.c
src/output-tlslog.h
src/suricata.c
src/tm-threads-common.h

index 71ec1cb2d637871477b94c25b577ad8f4afbce26..5a88a7c92492c0121589edf2504bf4d0dda88950 100644 (file)
@@ -361,10 +361,6 @@ TmEcode OutputJson (ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, Pack
         OutputFileLog(tv, p, data);
     }
 
-    if (output_flags & OUTPUT_TLS) {
-        OutputTlsLog(tv, p, data);
-    }
-
     return TM_ECODE_OK;
 }
 
@@ -538,14 +534,6 @@ OutputCtx *OutputJsonInitCtx(ConfNode *conf)
                     output_flags |= OUTPUT_FILES;
                     continue;
                 }
-                if (strcmp(output->val, "tls") == 0) {
-                    SCLogDebug("Enabling TLS output");
-                    ConfNode *child = ConfNodeLookupChild(output, "tls");
-                    json_ctx->tls_ctx = OutputTlsLogInit(child);
-                    AppLayerParserRegisterLogger(IPPROTO_TCP,ALPROTO_TLS);
-                    output_flags |= OUTPUT_TLS;
-                    continue;
-                }
             }
         }
     }
index 4a67b674245d53ec3f4dc3710785a0d2776ad453..0fe95fb162118ebd8cd6725a0287b251c38746b1 100644 (file)
@@ -61,9 +61,16 @@ SC_ATOMIC_DECLARE(unsigned int, cert_id);
 #define LOG_TLS_EXTENDED    (1 << 0)
 
 typedef struct OutputTlsCtx_ {
+    LogFileCtx *file_ctx;
     uint32_t flags; /** Store mode */
 } OutputTlsCtx;
 
+
+typedef struct JsonTlsLogThread_ {
+    OutputTlsCtx *tlslog_ctx;
+    MemBuffer *buffer;
+} JsonTlsLogThread;
+
 #define SSL_VERSION_LENGTH 13
 
 static void LogTlsLogExtendedJSON(json_t *tjs, SSLState * state)
@@ -100,20 +107,15 @@ static void LogTlsLogExtendedJSON(json_t *tjs, SSLState * state)
             break;
     }
     json_object_set_new(tjs, "version", json_string(ssl_version));
-
 }
 
-
-static TmEcode LogTlsLogIPWrapperJSON(ThreadVars *tv, Packet *p, void *data)
-{
-    SCEnter();
-    AlertJsonThread *aft = (AlertJsonThread *)data;
+static int JsonTlsLogger(ThreadVars *tv, void *thread_data, const Packet *p) {
+    JsonTlsLogThread *aft = (JsonTlsLogThread *)thread_data;
     MemBuffer *buffer = (MemBuffer *)aft->buffer;
-    OutputTlsCtx *tls_ctx = aft->tls_ctx->data;
+    OutputTlsCtx *tls_ctx = aft->tlslog_ctx;
 
-    /* no flow, no tls state */
-    if (p->flow == NULL) {
-        SCReturnInt(TM_ECODE_OK);
+    if (unlikely(p->flow == NULL)) {
+        return 0;
     }
 
     /* check if we have TLS state or not */
@@ -122,19 +124,15 @@ static TmEcode LogTlsLogIPWrapperJSON(ThreadVars *tv, Packet *p, void *data)
     if (proto != ALPROTO_TLS)
         goto end;
 
-    SSLState *ssl_state = (SSLState *) FlowGetAppState(p->flow);
-    if (ssl_state == NULL) {
-        SCLogDebug("no tls state, so no request logging");
+    SSLState *ssl_state = (SSLState *)FlowGetAppState(p->flow);
+    if (unlikely(ssl_state == NULL)) {
         goto end;
     }
 
     if (ssl_state->server_connp.cert0_issuerdn == NULL || ssl_state->server_connp.cert0_subject == NULL)
         goto end;
 
-    if (AppLayerParserGetTransactionLogId(p->flow->alparser) != 0)
-        goto end;
-
-    json_t *js = CreateJSONHeader(p, 0);
+    json_t *js = CreateJSONHeader((Packet *)p, 0);//TODO
     if (unlikely(js == NULL))
         goto end;
 
@@ -161,36 +159,75 @@ static TmEcode LogTlsLogIPWrapperJSON(ThreadVars *tv, Packet *p, void *data)
 
     json_object_set_new(js, "tls", tjs);
 
-    OutputJSON(js, aft, &aft->tls_cnt);
+    OutputJSONBuffer(js, tls_ctx->file_ctx, buffer);
     json_object_clear(js);
     json_decref(js);
 
+    /* we only log the state once */
+    ssl_state->flags |= SSL_AL_FLAG_STATE_LOGGED;
 end:
     FLOWLOCK_UNLOCK(p->flow);
-    SCReturnInt(TM_ECODE_OK);
-
+    return 0;
 }
 
-TmEcode OutputTlsLog(ThreadVars *tv, Packet *p, void *data)
+#define OUTPUT_BUFFER_SIZE 65535
+static TmEcode JsonTlsLogThreadInit(ThreadVars *t, void *initdata, void **data)
 {
-    SCEnter();
+    JsonTlsLogThread *aft = SCMalloc(sizeof(JsonTlsLogThread));
+    if (unlikely(aft == NULL))
+        return TM_ECODE_FAILED;
+    memset(aft, 0, sizeof(JsonTlsLogThread));
+
+    if(initdata == NULL)
+    {
+        SCLogDebug("Error getting context for HTTPLog.  \"initdata\" argument NULL");
+        SCFree(aft);
+        return TM_ECODE_FAILED;
+    }
 
-    /* no flow, no htp state */
-    if (p->flow == NULL) {
-        SCReturnInt(TM_ECODE_OK);
+    /* Use the Ouptut Context (file pointer and mutex) */
+    aft->tlslog_ctx = ((OutputCtx *)initdata)->data;
+
+    aft->buffer = MemBufferCreateNew(OUTPUT_BUFFER_SIZE);
+    if (aft->buffer == NULL) {
+        SCFree(aft);
+        return TM_ECODE_FAILED;
     }
 
-    if (!(PKT_IS_TCP(p))) {
-        SCReturnInt(TM_ECODE_OK);
+    *data = (void *)aft;
+    return TM_ECODE_OK;
+}
+
+static TmEcode JsonTlsLogThreadDeinit(ThreadVars *t, void *data)
+{
+    JsonTlsLogThread *aft = (JsonTlsLogThread *)data;
+    if (aft == NULL) {
+        return TM_ECODE_OK;
     }
 
-    LogTlsLogIPWrapperJSON(tv, p, data);
+    MemBufferFree(aft->buffer);
+    /* clear memory */
+    memset(aft, 0, sizeof(JsonTlsLogThread));
 
-    SCReturnInt(TM_ECODE_OK);
+    SCFree(aft);
+    return TM_ECODE_OK;
 }
 
+
+#define DEFAULT_LOG_FILENAME "tls.json"
 OutputCtx *OutputTlsLogInit(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;
+    }
+
     OutputTlsCtx *tls_ctx = SCMalloc(sizeof(OutputTlsCtx));
     if (unlikely(tls_ctx == NULL))
         return NULL;
@@ -199,6 +236,7 @@ OutputCtx *OutputTlsLogInit(ConfNode *conf)
     if (unlikely(output_ctx == NULL))
         return NULL;
 
+    tls_ctx->file_ctx = file_ctx;
     tls_ctx->flags = LOG_TLS_DEFAULT;
 
     if (conf) {
@@ -215,4 +253,106 @@ OutputCtx *OutputTlsLogInit(ConfNode *conf)
 
     return output_ctx;
 }
+
+OutputCtx *OutputTlsLogInitSub(ConfNode *conf, OutputCtx *parent_ctx)
+{
+    AlertJsonThread *ajt = parent_ctx->data;
+
+    OutputTlsCtx *tls_ctx = SCMalloc(sizeof(OutputTlsCtx));
+    if (unlikely(tls_ctx == NULL))
+        return NULL;
+
+    OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx));
+    if (unlikely(output_ctx == NULL))
+        return NULL;
+
+    tls_ctx->file_ctx = ajt->file_ctx;
+    tls_ctx->flags = LOG_TLS_DEFAULT;
+
+    if (conf) {
+        const char *extended = ConfNodeLookupChildValue(conf, "extended");
+
+        if (extended != NULL) {
+            if (ConfValIsTrue(extended)) {
+                tls_ctx->flags = LOG_TLS_EXTENDED;
+            }
+        }
+    }
+    output_ctx->data = tls_ctx;
+    output_ctx->DeInit = NULL;
+
+    return output_ctx;
+}
+
+/** \internal
+ *  \brief Condition function for TLS logger
+ *  \retval bool true or false -- log now?
+ */
+static int JsonTlsCondition(ThreadVars *tv, const Packet *p) {
+    if (p->flow == NULL) {
+        return FALSE;
+    }
+
+    if (!(PKT_IS_TCP(p))) {
+        return FALSE;
+    }
+
+    FLOWLOCK_RDLOCK(p->flow);
+    uint16_t proto = FlowGetAppProtocol(p->flow);
+    if (proto != ALPROTO_TLS)
+        goto dontlog;
+
+    SSLState *ssl_state = (SSLState *)FlowGetAppState(p->flow);
+    if (ssl_state == NULL) {
+        SCLogDebug("no tls state, so no request logging");
+        goto dontlog;
+    }
+
+    /* we only log the state once */
+    if (ssl_state->flags & SSL_AL_FLAG_STATE_LOGGED)
+        goto dontlog;
+
+    if (ssl_state->server_connp.cert0_issuerdn == NULL ||
+            ssl_state->server_connp.cert0_subject == NULL)
+        goto dontlog;
+
+    /* todo: logic to log once */
+
+    FLOWLOCK_UNLOCK(p->flow);
+    return TRUE;
+dontlog:
+    FLOWLOCK_UNLOCK(p->flow);
+    return FALSE;
+}
+
+void TmModuleJsonTlsLogRegister (void) {
+    tmm_modules[TMM_JSONTLSLOG].name = "JsonTlsLog";
+    tmm_modules[TMM_JSONTLSLOG].ThreadInit = JsonTlsLogThreadInit;
+    tmm_modules[TMM_JSONTLSLOG].ThreadDeinit = JsonTlsLogThreadDeinit;
+    tmm_modules[TMM_JSONTLSLOG].RegisterTests = NULL;
+    tmm_modules[TMM_JSONTLSLOG].cap_flags = 0;
+
+    /* register as separate module */
+    OutputRegisterPacketModule("JsonTlsLog", "tls-json-log", OutputTlsLogInit,
+            JsonTlsLogger, JsonTlsCondition);
+
+    /* also register as child of eve-log */
+    OutputRegisterPacketSubModule("eve-log", "JsonTlsLog", "eve-log.tls", OutputTlsLogInitSub,
+            JsonTlsLogger, JsonTlsCondition);
+}
+
+#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 TmModuleJsonTlsLogRegister (void)
+{
+    tmm_modules[TMM_JSONTLSLOG].name = "JsonTlsLog";
+    tmm_modules[TMM_JSONTLSLOG].ThreadInit = OutputJsonThreadInit;
+}
+
 #endif
index 78007cefc5dd0e326e2c180ca24e1c46e5cabb5e..71835e78bd69f50d7e85692cde2d8203f3bdf562 100644 (file)
@@ -26,5 +26,6 @@
 
 TmEcode OutputTlsLog (ThreadVars *tv, Packet *p, void *data);
 OutputCtx *OutputTlsLogInit(ConfNode *);
+void TmModuleJsonTlsLogRegister (void);
 
 #endif /* __OUTPUT_TLSLOG_H__ */
index 3a3576fb03ce6233aaa895f5e8b36042c73368e9..1a20728dc23702971400c183a028d6403e008bca 100644 (file)
@@ -87,6 +87,7 @@
 #include "log-dnslog.h"
 #include "output-dnslog.h"
 #include "log-tlslog.h"
+#include "output-tlslog.h"
 #include "log-pcap.h"
 #include "log-file.h"
 #include "log-filestore.h"
@@ -803,7 +804,9 @@ void RegisterAllModules()
     /* http log */
     TmModuleLogHttpLogRegister();
     TmModuleJsonHttpLogRegister();
+    /* tls log */
     TmModuleLogTlsLogRegister();
+    TmModuleJsonTlsLogRegister();
     /* pcap log */
     TmModulePcapLogRegister();
     /* file log */
index e03d70f7ac94894a7b0cac1c839142db2b352283..09b8e6b25fbd9c8dede1bf1a417a5d63ed905f6c 100644 (file)
@@ -88,6 +88,7 @@ typedef enum {
     TMM_JSONDROPLOG,
     TMM_JSONHTTPLOG,
     TMM_JSONDNSLOG,
+    TMM_JSONTLSLOG,
     TMM_SIZE,
 } TmmId;