]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
tls-store: support client logging
authorVictor Julien <vjulien@oisf.net>
Sat, 25 May 2024 15:35:26 +0000 (17:35 +0200)
committerVictor Julien <victor@inliniac.net>
Wed, 29 May 2024 18:45:04 +0000 (20:45 +0200)
Adds a `client-` prefix to the logged certs and meta files.

Ticket: #7045.

src/log-tlsstore.c
src/suricata-common.h
src/util-profiling.c

index a11f20d2b93ab2434ae0e5b63dbdae6ebf6dce6c..e6c89559ed4d6351a095b46c3947b04ae93018df 100644 (file)
@@ -56,15 +56,18 @@ typedef struct LogTlsStoreLogThread_ {
     size_t     enc_buf_len;
 } LogTlsStoreLogThread;
 
-static int CreateFileName(const Packet *p, SSLState *state, char *filename, size_t filename_size)
+static int CreateFileName(
+        const Packet *p, SSLState *state, char *filename, size_t filename_size, const bool client)
 {
     char path[PATH_MAX];
     int file_id = SC_ATOMIC_ADD(cert_id, 1);
 
+    const char *dir = client ? "client-" : "";
+
     /* Use format : packet time + incremental ID
      * When running on same pcap it will overwrite
      * On a live device, we will not be able to overwrite */
-    if (snprintf(path, sizeof(path), "%s/%ld.%ld-%d.pem", tls_logfile_base_dir,
+    if (snprintf(path, sizeof(path), "%s/%s%ld.%ld-%d.pem", tls_logfile_base_dir, dir,
                 (long int)SCTIME_SECS(p->ts), (long int)SCTIME_USECS(p->ts),
                 file_id) == sizeof(path))
         return 0;
@@ -73,7 +76,8 @@ static int CreateFileName(const Packet *p, SSLState *state, char *filename, size
     return 1;
 }
 
-static void LogTlsLogPem(LogTlsStoreLogThread *aft, const Packet *p, SSLState *state, int ipproto)
+static void LogTlsLogPem(LogTlsStoreLogThread *aft, const Packet *p, SSLState *state,
+        SSLStateConnp *connp, int ipproto)
 {
 #define PEMHEADER "-----BEGIN CERTIFICATE-----\n"
 #define PEMFOOTER "-----END CERTIFICATE-----\n"
@@ -87,10 +91,12 @@ static void LogTlsLogPem(LogTlsStoreLogThread *aft, const Packet *p, SSLState *s
     uint8_t *ptmp;
     SSLCertsChain *cert;
 
-    if (TAILQ_EMPTY(&state->server_connp.certs))
+    if (TAILQ_EMPTY(&connp->certs)) {
         SCReturn;
+    }
 
-    CreateFileName(p, state, filename, sizeof(filename));
+    const bool client = connp == &state->client_connp;
+    CreateFileName(p, state, filename, sizeof(filename), client);
     if (strlen(filename) == 0) {
         SCLogWarning("Can't create PEM filename");
         SCReturn;
@@ -106,7 +112,7 @@ static void LogTlsLogPem(LogTlsStoreLogThread *aft, const Packet *p, SSLState *s
         SCReturn;
     }
 
-    TAILQ_FOREACH(cert, &state->server_connp.certs, next) {
+    TAILQ_FOREACH (cert, &connp->certs, next) {
         pemlen = Base64EncodeBufferSize(cert->cert_len);
         if (pemlen > aft->enc_buf_len) {
             ptmp = (uint8_t*) SCRealloc(aft->enc_buf, sizeof(uint8_t) * pemlen);
@@ -180,12 +186,11 @@ static void LogTlsLogPem(LogTlsStoreLogThread *aft, const Packet *p, SSLState *s
                 goto end_fwrite_fpmeta;
         }
 
-        if (fprintf(fpmeta, "TLS SUBJECT:       %s\n"
+        if (fprintf(fpmeta,
+                    "TLS SUBJECT:       %s\n"
                     "TLS ISSUERDN:      %s\n"
                     "TLS FINGERPRINT:   %s\n",
-                state->server_connp.cert0_subject,
-                state->server_connp.cert0_issuerdn,
-                state->server_connp.cert0_fingerprint) < 0)
+                    connp->cert0_subject, connp->cert0_issuerdn, connp->cert0_fingerprint) < 0)
             goto end_fwrite_fpmeta;
 
         fclose(fpmeta);
@@ -199,7 +204,7 @@ static void LogTlsLogPem(LogTlsStoreLogThread *aft, const Packet *p, SSLState *s
     }
 
     /* Reset the store flag */
-    state->server_connp.cert_log_flag &= ~SSL_TLS_LOG_PEM;
+    connp->cert_log_flag &= ~SSL_TLS_LOG_PEM;
     SCReturn;
 
 end_fwrite_fp:
@@ -243,20 +248,53 @@ static bool LogTlsStoreCondition(
         goto dontlog;
     }
 
-    if ((ssl_state->server_connp.cert_log_flag & SSL_TLS_LOG_PEM) == 0)
+    if ((ssl_state->server_connp.cert_log_flag & SSL_TLS_LOG_PEM) == 0) {
         goto dontlog;
+    }
 
     if (ssl_state->server_connp.cert0_issuerdn == NULL ||
-            ssl_state->server_connp.cert0_subject == NULL)
+            ssl_state->server_connp.cert0_subject == NULL) {
+        goto dontlog;
+    }
+
+    return true;
+dontlog:
+    return false;
+}
+
+static bool LogTlsStoreConditionClient(
+        ThreadVars *tv, const Packet *p, void *state, void *tx, uint64_t tx_id)
+{
+    if (p->flow == NULL) {
+        return false;
+    }
+
+    if (!(PacketIsTCP(p))) {
+        return false;
+    }
+
+    SSLState *ssl_state = (SSLState *)state;
+    if (ssl_state == NULL) {
+        SCLogDebug("no tls state, so no request logging");
+        goto dontlog;
+    }
+
+    if ((ssl_state->client_connp.cert_log_flag & SSL_TLS_LOG_PEM) == 0) {
         goto dontlog;
+    }
+
+    if ((ssl_state->client_connp.cert0_issuerdn == NULL ||
+                ssl_state->client_connp.cert0_subject == NULL)) {
+        goto dontlog;
+    }
 
     return true;
 dontlog:
     return false;
 }
 
-static int LogTlsStoreLogger(ThreadVars *tv, void *thread_data, const Packet *p,
-                             Flow *f, void *state, void *tx, uint64_t tx_id)
+static int LogTlsStoreLoggerClient(ThreadVars *tv, void *thread_data, const Packet *p, Flow *f,
+        void *state, void *tx, uint64_t tx_id)
 {
     LogTlsStoreLogThread *aft = (LogTlsStoreLogThread *)thread_data;
     int ipproto = (PacketIsIPv4(p)) ? AF_INET : AF_INET6;
@@ -265,9 +303,29 @@ static int LogTlsStoreLogger(ThreadVars *tv, void *thread_data, const Packet *p,
     if (unlikely(ssl_state == NULL)) {
         return 0;
     }
+    /* client cert */
+    SSLStateConnp *connp = &ssl_state->client_connp;
+    if (connp->cert_log_flag & SSL_TLS_LOG_PEM) {
+        LogTlsLogPem(aft, p, ssl_state, connp, ipproto);
+    }
+
+    return 0;
+}
+
+static int LogTlsStoreLogger(ThreadVars *tv, void *thread_data, const Packet *p, Flow *f,
+        void *state, void *tx, uint64_t tx_id)
+{
+    LogTlsStoreLogThread *aft = (LogTlsStoreLogThread *)thread_data;
+    int ipproto = (PacketIsIPv4(p)) ? AF_INET : AF_INET6;
 
-    if (ssl_state->server_connp.cert_log_flag & SSL_TLS_LOG_PEM) {
-        LogTlsLogPem(aft, p, ssl_state, ipproto);
+    SSLState *ssl_state = (SSLState *)state;
+    if (unlikely(ssl_state == NULL)) {
+        return 0;
+    }
+    /* server cert */
+    SSLStateConnp *connp = &ssl_state->server_connp;
+    if (connp->cert_log_flag & SSL_TLS_LOG_PEM) {
+        LogTlsLogPem(aft, p, ssl_state, connp, ipproto);
     }
 
     return 0;
@@ -394,6 +452,10 @@ void LogTlsStoreRegister (void)
         LogTlsStoreCondition, LogTlsStoreLogThreadInit,
         LogTlsStoreLogThreadDeinit, LogTlsStoreLogExitPrintStats);
 
+    OutputRegisterTxModuleWithCondition(LOGGER_TLS_STORE_CLIENT, MODULE_NAME, "tls-store",
+            LogTlsStoreLogInitCtx, ALPROTO_TLS, LogTlsStoreLoggerClient, LogTlsStoreConditionClient,
+            LogTlsStoreLogThreadInit, LogTlsStoreLogThreadDeinit, LogTlsStoreLogExitPrintStats);
+
     SC_ATOMIC_INIT(cert_id);
     SC_ATOMIC_SET(cert_id, 1);
 
index 1f3c6341e59dd51b437a02c9a8fa6acb104bde10..cb95d17e974fd55cfb01c5c665caf3aff1267712 100644 (file)
@@ -463,6 +463,7 @@ typedef enum {
     /* TX loggers first for low logger IDs */
     LOGGER_HTTP,
     LOGGER_TLS_STORE,
+    LOGGER_TLS_STORE_CLIENT,
     LOGGER_TLS,
     LOGGER_JSON_TX,
     LOGGER_FILE,
index 46c587d01142cdc51135d53b824af1d3dacc0026..70b187e97a8fe8f538f4d222c9e4cba54be07cbe 100644 (file)
@@ -1266,6 +1266,7 @@ const char *PacketProfileLoggerIdToString(LoggerId id)
         CASE_CODE(LOGGER_UNDEFINED);
         CASE_CODE(LOGGER_HTTP);
         CASE_CODE(LOGGER_TLS_STORE);
+        CASE_CODE(LOGGER_TLS_STORE_CLIENT);
         CASE_CODE(LOGGER_TLS);
         CASE_CODE(LOGGER_JSON_TX);
         CASE_CODE(LOGGER_FILE);