]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
log-tls: convert to packet logger API
authorVictor Julien <victor@inliniac.net>
Mon, 13 Jan 2014 15:13:27 +0000 (16:13 +0100)
committerVictor Julien <victor@inliniac.net>
Mon, 27 Jan 2014 14:20:59 +0000 (15:20 +0100)
This patch converts log-tls to use the packet logger API. The packet
logger API was choosen as the TLS parser is not transaction aware.

To make sure the state is only logged once, the flag
SSL_AL_FLAG_STATE_LOGGED was added to the parser. This flag is checked
by the condition function, and set at the end of the Logger function.

src/app-layer-ssl.h
src/log-tlslog.c

index 55a85ae4d7693d78249b52804c194482ceb8c008..d138200d05351bc6c4919957fce6be986f13c21b 100644 (file)
@@ -66,6 +66,9 @@ enum {
 #define SSL_AL_FLAG_STATE_SERVER_KEYX           0x1000
 #define SSL_AL_FLAG_STATE_UNKNOWN               0x2000
 
+#define SSL_AL_FLAG_STATE_LOGGED                0x4000
+
+/* config flags */
 #define SSL_TLS_LOG_PEM                         (1 << 0)
 
 
index 67fd96a377f50d1d2f2257a72e38aab3d5bccc7d..fa90a14a9cafc83052b851f1ce63a278bac0b12c 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2007-2013 Open Information Security Foundation
+/* Copyright (C) 2007-2014 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
  *
  * \author Roliers Jean-Paul <popof.fpn@gmail.co>
  * \author Eric Leblond <eric@regit.org>
+ * \author Victor Julien <victor@inliniac.net>
  *
- * Implements tls logging portion of the engine.
+ * Implements TLS logging portion of the engine. The TLS logger is
+ * implemented as a packet logger, as the TLS parser is not transaction
+ * aware.
  */
 
 #include "suricata-common.h"
@@ -112,7 +115,7 @@ static void LogTlsLogExtended(LogTlsLogThread *aft, SSLState * state)
     MemBufferWriteString(aft->buffer, "\n");
 }
 
-static int GetIPInformations(Packet *p, char* srcip, size_t srcip_len,
+static int GetIPInformations(const Packet *p, char* srcip, size_t srcip_len,
                              Port* sp, char* dstip, size_t dstip_len,
                              Port* dp, int ipproto)
 {
@@ -150,7 +153,7 @@ static int GetIPInformations(Packet *p, char* srcip, size_t srcip_len,
     return 1;
 }
 
-static int CreateFileName(LogTlsFileCtx *log, Packet *p, SSLState *state, char *filename)
+static int CreateFileName(LogTlsFileCtx *log, const Packet *p, SSLState *state, char *filename)
 {
 #define FILELEN 64  //filename len + extention + ending path / + some space
 
@@ -172,8 +175,7 @@ static int CreateFileName(LogTlsFileCtx *log, Packet *p, SSLState *state, char *
     return 1;
 }
 
-
-static void LogTlsLogPem(LogTlsLogThread *aft, Packet *p, SSLState *state, LogTlsFileCtx *log, int ipproto)
+static void LogTlsLogPem(LogTlsLogThread *aft, const Packet *p, SSLState *state, LogTlsFileCtx *log, int ipproto)
 {
 #define PEMHEADER "-----BEGIN CERTIFICATE-----\n"
 #define PEMFOOTER "-----END CERTIFICATE-----\n"
@@ -307,114 +309,6 @@ end_fp:
     fclose(fp);
 }
 
-
-static TmEcode LogTlsLogIPWrapper(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq, int ipproto)
-{
-
-    SCEnter();
-    LogTlsLogThread *aft = (LogTlsLogThread *) data;
-    LogTlsFileCtx *hlog = aft->tlslog_ctx;
-
-    char timebuf[64];
-
-    /* no flow, no tls state */
-    if (p->flow == NULL) {
-        SCReturnInt(TM_ECODE_OK);
-    }
-
-    /* check if we have TLS state or not */
-    FLOWLOCK_WRLOCK(p->flow);
-    uint16_t proto = FlowGetAppProtocol(p->flow);
-    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");
-        goto end;
-    }
-
-    if (ssl_state->server_connp.cert0_issuerdn == NULL || ssl_state->server_connp.cert0_subject == NULL)
-        goto end;
-
-    if (ssl_state->server_connp.cert_log_flag & SSL_TLS_LOG_PEM) {
-        LogTlsLogPem(aft, p, ssl_state, hlog, ipproto);
-    }
-
-    if (AppLayerParserGetTransactionLogId(p->flow->alparser) != 0) {
-        goto end;
-    }
-
-    CreateTimeString(&p->ts, timebuf, sizeof(timebuf));
-    #define PRINT_BUF_LEN 46
-    char srcip[PRINT_BUF_LEN], dstip[PRINT_BUF_LEN];
-    Port sp, dp;
-    if (!GetIPInformations(p, srcip, PRINT_BUF_LEN,
-                           &sp, dstip, PRINT_BUF_LEN, &dp, ipproto)) {
-        goto end;
-    }
-
-    /* reset */
-    MemBufferReset(aft->buffer);
-
-    MemBufferWriteString(aft->buffer,
-                         "%s %s:%d -> %s:%d  TLS: Subject='%s' Issuerdn='%s'",
-                         timebuf, srcip, sp, dstip, dp,
-                         ssl_state->server_connp.cert0_subject, ssl_state->server_connp.cert0_issuerdn);
-
-    AppLayerParserSetTransactionLogId(p->flow->alparser);
-
-    if (hlog->flags & LOG_TLS_EXTENDED) {
-        LogTlsLogExtended(aft, ssl_state);
-    } else {
-        MemBufferWriteString(aft->buffer, "\n");
-    }
-
-    aft->tls_cnt ++;
-
-    SCMutexLock(&hlog->file_ctx->fp_mutex);
-    MemBufferPrintToFPAsString(aft->buffer, hlog->file_ctx->fp);
-    fflush(hlog->file_ctx->fp);
-    SCMutexUnlock(&hlog->file_ctx->fp_mutex);
-
-end:
-    FLOWLOCK_UNLOCK(p->flow);
-    SCReturnInt(TM_ECODE_OK);
-
-}
-
-static TmEcode LogTlsLogIPv4(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq)
-{
-    return LogTlsLogIPWrapper(tv, p, data, pq, postpq, AF_INET);
-}
-
-static TmEcode LogTlsLogIPv6(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq)
-{
-    return LogTlsLogIPWrapper(tv, p, data, pq, postpq, AF_INET6);
-}
-
-static TmEcode LogTlsLog(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq)
-{
-    SCEnter();
-
-    /* no flow, no htp state */
-    if (p->flow == NULL) {
-        SCReturnInt(TM_ECODE_OK);
-    }
-
-    if (!(PKT_IS_TCP(p))) {
-        SCReturnInt(TM_ECODE_OK);
-    }
-
-    if (PKT_IS_IPV4(p)) {
-        SCReturnInt(LogTlsLogIPv4(tv, p, data, pq, postpq));
-    } else if (PKT_IS_IPV6(p)) {
-        SCReturnInt(LogTlsLogIPv6(tv, p, data, pq, postpq));
-    }
-
-    SCReturnInt(TM_ECODE_OK);
-}
-
 static TmEcode LogTlsLogThreadInit(ThreadVars *t, void *initdata, void **data)
 {
     LogTlsLogThread *aft = SCMalloc(sizeof(LogTlsLogThread));
@@ -571,17 +465,123 @@ filectx_error:
     return NULL;
 }
 
+/** \internal
+ *  \brief Condition function for TLS logger
+ *  \retval bool true or false -- log now?
+ */
+static int LogTlsCondition(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;
+}
+
+static int LogTlsLogger(ThreadVars *tv, void *thread_data, const Packet *p) {
+    LogTlsLogThread *aft = (LogTlsLogThread *)thread_data;
+    LogTlsFileCtx *hlog = aft->tlslog_ctx;
+    char timebuf[64];
+    int ipproto = (PKT_IS_IPV4(p)) ? AF_INET : AF_INET6;
+
+    if (unlikely(p->flow == NULL)) {
+        return 0;
+    }
+
+    /* check if we have TLS state or not */
+    FLOWLOCK_WRLOCK(p->flow);
+    uint16_t proto = FlowGetAppProtocol(p->flow);
+    if (proto != ALPROTO_TLS)
+        goto end;
+
+    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 (ssl_state->server_connp.cert_log_flag & SSL_TLS_LOG_PEM) {
+        LogTlsLogPem(aft, p, ssl_state, hlog, ipproto);
+    }
+
+    CreateTimeString(&p->ts, timebuf, sizeof(timebuf));
+#define PRINT_BUF_LEN 46
+    char srcip[PRINT_BUF_LEN], dstip[PRINT_BUF_LEN];
+    Port sp, dp;
+    if (!GetIPInformations(p, srcip, PRINT_BUF_LEN,
+                           &sp, dstip, PRINT_BUF_LEN, &dp, ipproto)) {
+        goto end;
+    }
+
+    MemBufferReset(aft->buffer);
+    MemBufferWriteString(aft->buffer,
+                         "%s %s:%d -> %s:%d  TLS: Subject='%s' Issuerdn='%s'",
+                         timebuf, srcip, sp, dstip, dp,
+                         ssl_state->server_connp.cert0_subject,
+                         ssl_state->server_connp.cert0_issuerdn);
+
+    if (hlog->flags & LOG_TLS_EXTENDED) {
+        LogTlsLogExtended(aft, ssl_state);
+    } else {
+        MemBufferWriteString(aft->buffer, "\n");
+    }
+
+    aft->tls_cnt++;
+
+    SCMutexLock(&hlog->file_ctx->fp_mutex);
+    MemBufferPrintToFPAsString(aft->buffer, hlog->file_ctx->fp);
+    fflush(hlog->file_ctx->fp);
+    SCMutexUnlock(&hlog->file_ctx->fp_mutex);
+
+    /* we only log the state once */
+    ssl_state->flags |= SSL_AL_FLAG_STATE_LOGGED;
+end:
+    FLOWLOCK_UNLOCK(p->flow);
+    return 0;
+}
+
 void TmModuleLogTlsLogRegister(void)
 {
     tmm_modules[TMM_LOGTLSLOG].name = MODULE_NAME;
     tmm_modules[TMM_LOGTLSLOG].ThreadInit = LogTlsLogThreadInit;
-    tmm_modules[TMM_LOGTLSLOG].Func = LogTlsLog;
+    tmm_modules[TMM_LOGTLSLOG].Func = NULL;
     tmm_modules[TMM_LOGTLSLOG].ThreadExitPrintStats = LogTlsLogExitPrintStats;
     tmm_modules[TMM_LOGTLSLOG].ThreadDeinit = LogTlsLogThreadDeinit;
     tmm_modules[TMM_LOGTLSLOG].RegisterTests = NULL;
     tmm_modules[TMM_LOGTLSLOG].cap_flags = 0;
 
-    OutputRegisterModule(MODULE_NAME, "tls-log", LogTlsLogInitCtx);
+    OutputRegisterPacketModule(MODULE_NAME, "tls-log", LogTlsLogInitCtx,
+            LogTlsLogger, LogTlsCondition);
 
     SC_ATOMIC_INIT(cert_id);
 }