/src/suricata7/src/log-tlslog.c
Line | Count | Source |
1 | | /* Copyright (C) 2007-2014 Open Information Security Foundation |
2 | | * |
3 | | * You can copy, redistribute or modify this Program under the terms of |
4 | | * the GNU General Public License version 2 as published by the Free |
5 | | * Software Foundation. |
6 | | * |
7 | | * This program is distributed in the hope that it will be useful, |
8 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
9 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
10 | | * GNU General Public License for more details. |
11 | | * |
12 | | * You should have received a copy of the GNU General Public License |
13 | | * version 2 along with this program; if not, write to the Free Software |
14 | | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
15 | | * 02110-1301, USA. |
16 | | */ |
17 | | |
18 | | /** |
19 | | * \file |
20 | | * |
21 | | * \author Roliers Jean-Paul <popof.fpn@gmail.co> |
22 | | * \author Eric Leblond <eric@regit.org> |
23 | | * \author Victor Julien <victor@inliniac.net> |
24 | | * \author Paulo Pacheco <fooinha@gmail.com> |
25 | | * |
26 | | * Implements TLS logging portion of the engine. |
27 | | */ |
28 | | |
29 | | #include "suricata-common.h" |
30 | | #include "detect.h" |
31 | | #include "pkt-var.h" |
32 | | #include "conf.h" |
33 | | |
34 | | #include "threads.h" |
35 | | #include "threadvars.h" |
36 | | #include "tm-threads.h" |
37 | | |
38 | | #include "util-print.h" |
39 | | #include "util-unittest.h" |
40 | | |
41 | | #include "util-debug.h" |
42 | | |
43 | | #include "output.h" |
44 | | #include "log-tlslog.h" |
45 | | #include "app-layer-ssl.h" |
46 | | #include "app-layer.h" |
47 | | #include "app-layer-parser.h" |
48 | | #include "util-privs.h" |
49 | | #include "util-buffer.h" |
50 | | |
51 | | #include "util-logopenfile.h" |
52 | | #include "util-time.h" |
53 | | #include "log-cf-common.h" |
54 | | |
55 | 2 | #define DEFAULT_LOG_FILENAME "tls.log" |
56 | | |
57 | 33 | #define MODULE_NAME "LogTlsLog" |
58 | | |
59 | 9.32k | #define PRINT_BUF_LEN 46 |
60 | | |
61 | 2 | #define OUTPUT_BUFFER_SIZE 65535 |
62 | | #define CERT_ENC_BUFFER_SIZE 2048 |
63 | | |
64 | 0 | #define LOG_TLS_DEFAULT 0 |
65 | 4.66k | #define LOG_TLS_EXTENDED 1 |
66 | 4.66k | #define LOG_TLS_CUSTOM 2 |
67 | | |
68 | 6.09k | #define LOG_TLS_SESSION_RESUMPTION 4 |
69 | | |
70 | 0 | #define LOG_TLS_CF_VERSION 'v' |
71 | 0 | #define LOG_TLS_CF_DATE_NOT_BEFORE 'd' |
72 | 0 | #define LOG_TLS_CF_DATE_NOT_AFTER 'D' |
73 | 0 | #define LOG_TLS_CF_SHA1 'f' |
74 | 0 | #define LOG_TLS_CF_SNI 'n' |
75 | 0 | #define LOG_TLS_CF_SUBJECT 's' |
76 | 0 | #define LOG_TLS_CF_ISSUER 'i' |
77 | 0 | #define LOG_TLS_CF_EXTENDED 'E' |
78 | | |
79 | | typedef struct LogTlsFileCtx_ { |
80 | | LogFileCtx *file_ctx; |
81 | | uint32_t flags; /** Store mode */ |
82 | | LogCustomFormat *cf; |
83 | | } LogTlsFileCtx; |
84 | | |
85 | | typedef struct LogTlsLogThread_ { |
86 | | LogTlsFileCtx *tlslog_ctx; |
87 | | |
88 | | /* LogTlsFileCtx has the pointer to the file and a mutex to allow |
89 | | multithreading. */ |
90 | | uint32_t tls_cnt; |
91 | | |
92 | | MemBuffer *buffer; |
93 | | } LogTlsLogThread; |
94 | | |
95 | | int TLSGetIPInformations(const Packet *p, char* srcip, size_t srcip_len, |
96 | | Port* sp, char* dstip, size_t dstip_len, Port* dp, |
97 | | int ipproto) |
98 | 4.66k | { |
99 | 4.66k | if ((PKT_IS_TOSERVER(p))) { |
100 | 2.71k | switch (ipproto) { |
101 | 2.70k | case AF_INET: |
102 | 2.70k | PrintInet(AF_INET, (const void *) GET_IPV4_SRC_ADDR_PTR(p), |
103 | 2.70k | srcip, srcip_len); |
104 | 2.70k | PrintInet(AF_INET, (const void *) GET_IPV4_DST_ADDR_PTR(p), |
105 | 2.70k | dstip, dstip_len); |
106 | 2.70k | break; |
107 | 9 | case AF_INET6: |
108 | 9 | PrintInet(AF_INET6, (const void *) GET_IPV6_SRC_ADDR(p), srcip, |
109 | 9 | srcip_len); |
110 | 9 | PrintInet(AF_INET6, (const void *) GET_IPV6_DST_ADDR(p), dstip, |
111 | 9 | dstip_len); |
112 | 9 | break; |
113 | 0 | default: |
114 | 0 | return 0; |
115 | 2.71k | } |
116 | 2.71k | *sp = p->sp; |
117 | 2.71k | *dp = p->dp; |
118 | 2.71k | } else { |
119 | 1.95k | switch (ipproto) { |
120 | 1.95k | case AF_INET: |
121 | 1.95k | PrintInet(AF_INET, (const void *) GET_IPV4_DST_ADDR_PTR(p), |
122 | 1.95k | srcip, srcip_len); |
123 | 1.95k | PrintInet(AF_INET, (const void *) GET_IPV4_SRC_ADDR_PTR(p), |
124 | 1.95k | dstip, dstip_len); |
125 | 1.95k | break; |
126 | 3 | case AF_INET6: |
127 | 3 | PrintInet(AF_INET6, (const void *) GET_IPV6_DST_ADDR(p), srcip, |
128 | 3 | srcip_len); |
129 | 3 | PrintInet(AF_INET6, (const void *) GET_IPV6_SRC_ADDR(p), dstip, |
130 | 3 | dstip_len); |
131 | 3 | break; |
132 | 0 | default: |
133 | 0 | return 0; |
134 | 1.95k | } |
135 | 1.95k | *sp = p->dp; |
136 | 1.95k | *dp = p->sp; |
137 | 1.95k | } |
138 | 4.66k | return 1; |
139 | 4.66k | } |
140 | | |
141 | | static TmEcode LogTlsLogThreadInit(ThreadVars *t, const void *initdata, |
142 | | void **data) |
143 | 2 | { |
144 | 2 | LogTlsLogThread *aft = SCMalloc(sizeof(LogTlsLogThread)); |
145 | 2 | if (unlikely(aft == NULL)) |
146 | 0 | return TM_ECODE_FAILED; |
147 | | |
148 | 2 | memset(aft, 0, sizeof(LogTlsLogThread)); |
149 | | |
150 | 2 | if (initdata == NULL) { |
151 | 0 | SCLogDebug("Error getting context for TLSLog. \"initdata\" argument NULL"); |
152 | 0 | SCFree(aft); |
153 | 0 | return TM_ECODE_FAILED; |
154 | 0 | } |
155 | | |
156 | 2 | aft->buffer = MemBufferCreateNew(OUTPUT_BUFFER_SIZE); |
157 | 2 | if (aft->buffer == NULL) { |
158 | 0 | SCFree(aft); |
159 | 0 | return TM_ECODE_FAILED; |
160 | 0 | } |
161 | | |
162 | | /* Use the Output Context (file pointer and mutex) */ |
163 | 2 | aft->tlslog_ctx = ((OutputCtx *) initdata)->data; |
164 | | |
165 | 2 | *data = (void *)aft; |
166 | 2 | return TM_ECODE_OK; |
167 | 2 | } |
168 | | |
169 | | static TmEcode LogTlsLogThreadDeinit(ThreadVars *t, void *data) |
170 | 0 | { |
171 | 0 | LogTlsLogThread *aft = (LogTlsLogThread *)data; |
172 | 0 | if (aft == NULL) { |
173 | 0 | return TM_ECODE_OK; |
174 | 0 | } |
175 | | |
176 | 0 | MemBufferFree(aft->buffer); |
177 | 0 | memset(aft, 0, sizeof(LogTlsLogThread)); |
178 | |
|
179 | 0 | SCFree(aft); |
180 | 0 | return TM_ECODE_OK; |
181 | 0 | } |
182 | | |
183 | | static void LogTlsLogDeInitCtx(OutputCtx *output_ctx) |
184 | 0 | { |
185 | 0 | LogTlsFileCtx *tlslog_ctx = (LogTlsFileCtx *) output_ctx->data; |
186 | 0 | LogFileFreeCtx(tlslog_ctx->file_ctx); |
187 | 0 | LogCustomFormatFree(tlslog_ctx->cf); |
188 | 0 | SCFree(tlslog_ctx); |
189 | 0 | SCFree(output_ctx); |
190 | 0 | } |
191 | | |
192 | | static void LogTlsLogExitPrintStats(ThreadVars *tv, void *data) |
193 | 0 | { |
194 | 0 | LogTlsLogThread *aft = (LogTlsLogThread *)data; |
195 | 0 | if (aft == NULL) { |
196 | 0 | return; |
197 | 0 | } |
198 | | |
199 | 0 | SCLogInfo("TLS logger logged %" PRIu32 " requests", aft->tls_cnt); |
200 | 0 | } |
201 | | |
202 | | /** \brief Create a new tls log LogFileCtx. |
203 | | * \param conf Pointer to ConfNode containing this loggers configuration. |
204 | | * \return NULL if failure, LogFileCtx* to the file_ctx if succesful |
205 | | * */ |
206 | | static OutputInitResult LogTlsLogInitCtx(ConfNode *conf) |
207 | 2 | { |
208 | 2 | OutputInitResult result = { NULL, false }; |
209 | 2 | LogFileCtx* file_ctx = LogFileNewCtx(); |
210 | | |
211 | 2 | if (file_ctx == NULL) { |
212 | 0 | SCLogError("LogTlsLogInitCtx: Couldn't " |
213 | 0 | "create new file_ctx"); |
214 | 0 | return result; |
215 | 0 | } |
216 | | |
217 | 2 | if (SCConfLogOpenGeneric(conf, file_ctx, DEFAULT_LOG_FILENAME, 1) < 0) { |
218 | 0 | goto filectx_error; |
219 | 0 | } |
220 | | |
221 | 2 | LogTlsFileCtx *tlslog_ctx = SCCalloc(1, sizeof(LogTlsFileCtx)); |
222 | 2 | if (unlikely(tlslog_ctx == NULL)) { |
223 | 0 | goto filectx_error; |
224 | 0 | } |
225 | 2 | tlslog_ctx->file_ctx = file_ctx; |
226 | | |
227 | 2 | const char *extended = ConfNodeLookupChildValue(conf, "extended"); |
228 | 2 | const char *custom = ConfNodeLookupChildValue(conf, "custom"); |
229 | 2 | const char *customformat = ConfNodeLookupChildValue(conf, "customformat"); |
230 | | |
231 | | /* If custom logging format is selected, lets parse it */ |
232 | 2 | if (custom != NULL && customformat != NULL && ConfValIsTrue(custom)) { |
233 | 0 | tlslog_ctx->cf = LogCustomFormatAlloc(); |
234 | 0 | if (!tlslog_ctx->cf) { |
235 | 0 | goto tlslog_error; |
236 | 0 | } |
237 | | |
238 | 0 | tlslog_ctx->flags |= LOG_TLS_CUSTOM; |
239 | |
|
240 | 0 | if (!LogCustomFormatParse(tlslog_ctx->cf, customformat)) { |
241 | 0 | goto parser_error; |
242 | 0 | } |
243 | 2 | } else { |
244 | 2 | if (extended == NULL) { |
245 | 0 | tlslog_ctx->flags |= LOG_TLS_DEFAULT; |
246 | 2 | } else { |
247 | 2 | if (ConfValIsTrue(extended)) { |
248 | 2 | tlslog_ctx->flags |= LOG_TLS_EXTENDED; |
249 | 2 | } |
250 | 2 | } |
251 | 2 | } |
252 | | |
253 | 2 | const char *resumption = ConfNodeLookupChildValue(conf, |
254 | 2 | "session-resumption"); |
255 | 2 | if (resumption == NULL || ConfValIsTrue(resumption)) { |
256 | 2 | tlslog_ctx->flags |= LOG_TLS_SESSION_RESUMPTION; |
257 | 2 | } |
258 | | |
259 | 2 | OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx)); |
260 | 2 | if (unlikely(output_ctx == NULL)) { |
261 | 0 | goto tlslog_error; |
262 | 0 | } |
263 | 2 | output_ctx->data = tlslog_ctx; |
264 | 2 | output_ctx->DeInit = LogTlsLogDeInitCtx; |
265 | | |
266 | 2 | SCLogDebug("TLS log output initialized"); |
267 | | |
268 | | /* Enable the logger for the app layer */ |
269 | 2 | AppLayerParserRegisterLogger(IPPROTO_TCP, ALPROTO_TLS); |
270 | | |
271 | 2 | result.ctx = output_ctx; |
272 | 2 | result.ok = true; |
273 | 2 | return result; |
274 | | |
275 | 0 | parser_error: |
276 | 0 | SCLogError("Syntax error in custom tls log " |
277 | 0 | "format string."); |
278 | 0 | tlslog_error: |
279 | 0 | LogCustomFormatFree(tlslog_ctx->cf); |
280 | 0 | SCFree(tlslog_ctx); |
281 | 0 | filectx_error: |
282 | 0 | LogFileFreeCtx(file_ctx); |
283 | 0 | return result; |
284 | 0 | } |
285 | | |
286 | | static void LogTlsLogVersion(MemBuffer *buffer, uint16_t version) |
287 | 4.66k | { |
288 | 4.66k | char ssl_version[SSL_VERSION_MAX_STRLEN]; |
289 | 4.66k | SSLVersionToString(version, ssl_version); |
290 | 4.66k | MemBufferWriteString(buffer, "VERSION='%s'", ssl_version); |
291 | 4.66k | } |
292 | | |
293 | | static void LogTlsLogDate(MemBuffer *buffer, const char *title, int64_t *date) |
294 | 3.72k | { |
295 | 3.72k | char timebuf[64] = {0}; |
296 | 3.72k | if (sc_x509_format_timestamp(*date, timebuf, sizeof(timebuf))) { |
297 | 3.72k | MemBufferWriteString(buffer, "%s='%s'", title, timebuf); |
298 | 3.72k | } |
299 | 3.72k | } |
300 | | |
301 | | static void LogTlsLogString(MemBuffer *buffer, const char *title, |
302 | | const char *value) |
303 | 8.28k | { |
304 | 8.28k | MemBufferWriteString(buffer, "%s='%s'", title, value); |
305 | 8.28k | } |
306 | | |
307 | | static void LogTlsLogBasic(LogTlsLogThread *aft, SSLState *ssl_state, const SCTime_t ts, |
308 | | char *srcip, Port sp, char *dstip, Port dp) |
309 | 4.66k | { |
310 | 4.66k | char timebuf[64]; |
311 | 4.66k | CreateTimeString(ts, timebuf, sizeof(timebuf)); |
312 | 4.66k | MemBufferWriteString(aft->buffer, |
313 | 4.66k | "%s %s:%d -> %s:%d TLS:", |
314 | 4.66k | timebuf, srcip, sp, dstip, dp); |
315 | | |
316 | 4.66k | if (ssl_state->server_connp.cert0_subject != NULL) { |
317 | 1.87k | MemBufferWriteString(aft->buffer, " Subject='%s'", |
318 | 1.87k | ssl_state->server_connp.cert0_subject); |
319 | 1.87k | } |
320 | | |
321 | 4.66k | if (ssl_state->server_connp.cert0_issuerdn != NULL) { |
322 | 1.86k | MemBufferWriteString(aft->buffer, " Issuerdn='%s'", |
323 | 1.86k | ssl_state->server_connp.cert0_issuerdn); |
324 | 1.86k | } |
325 | | |
326 | 4.66k | if (ssl_state->flags & SSL_AL_FLAG_SESSION_RESUMED) { |
327 | | /* Only log a session as 'resumed' if a certificate has not |
328 | | been seen. */ |
329 | 4.55k | if ((ssl_state->server_connp.cert0_issuerdn == NULL) && |
330 | 2.78k | (ssl_state->server_connp.cert0_subject == NULL) && |
331 | 2.78k | (ssl_state->flags & SSL_AL_FLAG_STATE_SERVER_HELLO) && |
332 | 1.13k | ((ssl_state->flags & SSL_AL_FLAG_LOG_WITHOUT_CERT) == 0)) { |
333 | 1.08k | MemBufferWriteString(aft->buffer, " Session='resumed'"); |
334 | 1.08k | } |
335 | 4.55k | } |
336 | 4.66k | } |
337 | | |
338 | | static void LogTlsLogExtended(LogTlsLogThread *aft, SSLState *ssl_state, const SCTime_t ts, |
339 | | char *srcip, Port sp, char *dstip, Port dp) |
340 | 4.66k | { |
341 | 4.66k | if (ssl_state->server_connp.cert0_fingerprint != NULL) { |
342 | 1.86k | LOG_CF_WRITE_SPACE_SEPARATOR(aft->buffer); |
343 | 1.86k | LogTlsLogString(aft->buffer, "SHA1", |
344 | 1.86k | ssl_state->server_connp.cert0_fingerprint); |
345 | 1.86k | } |
346 | 4.66k | if (ssl_state->client_connp.sni != NULL) { |
347 | 4.55k | LOG_CF_WRITE_SPACE_SEPARATOR(aft->buffer); |
348 | 4.55k | LogTlsLogString(aft->buffer, "SNI", ssl_state->client_connp.sni); |
349 | 4.55k | } |
350 | 4.66k | if (ssl_state->server_connp.cert0_serial != NULL) { |
351 | 1.86k | LOG_CF_WRITE_SPACE_SEPARATOR(aft->buffer); |
352 | 1.86k | LogTlsLogString(aft->buffer, "SERIAL", |
353 | 1.86k | ssl_state->server_connp.cert0_serial); |
354 | 1.86k | } |
355 | | |
356 | 4.66k | LOG_CF_WRITE_SPACE_SEPARATOR(aft->buffer); |
357 | 4.66k | LogTlsLogVersion(aft->buffer, ssl_state->server_connp.version); |
358 | | |
359 | 4.66k | if (ssl_state->server_connp.cert0_not_before != 0) { |
360 | 1.86k | LOG_CF_WRITE_SPACE_SEPARATOR(aft->buffer); |
361 | 1.86k | LogTlsLogDate(aft->buffer, "NOTBEFORE", |
362 | 1.86k | &ssl_state->server_connp.cert0_not_before); |
363 | 1.86k | } |
364 | 4.66k | if (ssl_state->server_connp.cert0_not_after != 0) { |
365 | 1.86k | LOG_CF_WRITE_SPACE_SEPARATOR(aft->buffer); |
366 | 1.86k | LogTlsLogDate(aft->buffer, "NOTAFTER", |
367 | 1.86k | &ssl_state->server_connp.cert0_not_after); |
368 | 1.86k | } |
369 | 4.66k | } |
370 | | |
371 | | /* Custom format logging */ |
372 | | static void LogTlsLogCustom(LogTlsLogThread *aft, SSLState *ssl_state, const SCTime_t ts, |
373 | | char *srcip, Port sp, char *dstip, Port dp) |
374 | 0 | { |
375 | 0 | LogTlsFileCtx *tlslog_ctx = aft->tlslog_ctx; |
376 | 0 | uint32_t i; |
377 | 0 | char buf[64]; |
378 | |
|
379 | 0 | for (i = 0; i < tlslog_ctx->cf->cf_n; i++) |
380 | 0 | { |
381 | 0 | LogCustomFormatNode *node = tlslog_ctx->cf->cf_nodes[i]; |
382 | 0 | if (!node) /* Should never happen */ |
383 | 0 | continue; |
384 | | |
385 | 0 | switch (node->type) { |
386 | 0 | case LOG_CF_LITERAL: |
387 | | /* LITERAL */ |
388 | 0 | MemBufferWriteString(aft->buffer, "%s", node->data); |
389 | 0 | break; |
390 | 0 | case LOG_CF_TIMESTAMP: |
391 | | /* TIMESTAMP */ |
392 | 0 | LogCustomFormatWriteTimestamp(aft->buffer, node->data, ts); |
393 | 0 | break; |
394 | 0 | case LOG_CF_TIMESTAMP_U: |
395 | | /* TIMESTAMP USECONDS */ |
396 | 0 | snprintf(buf, sizeof(buf), "%06u", (unsigned int)SCTIME_USECS(ts)); |
397 | 0 | PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size, |
398 | 0 | (uint8_t *)buf, MIN(strlen(buf), 6)); |
399 | 0 | break; |
400 | 0 | case LOG_CF_CLIENT_IP: |
401 | | /* CLIENT IP ADDRESS */ |
402 | 0 | PrintRawUriBuf((char *)aft->buffer->buffer, |
403 | 0 | &aft->buffer->offset, aft->buffer->size, |
404 | 0 | (uint8_t *)srcip,strlen(srcip)); |
405 | 0 | break; |
406 | 0 | case LOG_CF_SERVER_IP: |
407 | | /* SERVER IP ADDRESS */ |
408 | 0 | PrintRawUriBuf((char *)aft->buffer->buffer, |
409 | 0 | &aft->buffer->offset, aft->buffer->size, |
410 | 0 | (uint8_t *)dstip, strlen(dstip)); |
411 | 0 | break; |
412 | 0 | case LOG_CF_CLIENT_PORT: |
413 | | /* CLIENT PORT */ |
414 | 0 | MemBufferWriteString(aft->buffer, "%" PRIu16 "", sp); |
415 | 0 | break; |
416 | 0 | case LOG_CF_SERVER_PORT: |
417 | | /* SERVER PORT */ |
418 | 0 | MemBufferWriteString(aft->buffer, "%" PRIu16 "", dp); |
419 | 0 | break; |
420 | 0 | case LOG_TLS_CF_VERSION: |
421 | 0 | LogTlsLogVersion(aft->buffer, ssl_state->server_connp.version); |
422 | 0 | break; |
423 | 0 | case LOG_TLS_CF_DATE_NOT_BEFORE: |
424 | 0 | LogTlsLogDate(aft->buffer, "NOTBEFORE", |
425 | 0 | &ssl_state->server_connp.cert0_not_before); |
426 | 0 | break; |
427 | 0 | case LOG_TLS_CF_DATE_NOT_AFTER: |
428 | 0 | LogTlsLogDate(aft->buffer, "NOTAFTER", |
429 | 0 | &ssl_state->server_connp.cert0_not_after); |
430 | 0 | break; |
431 | 0 | case LOG_TLS_CF_SHA1: |
432 | 0 | if (ssl_state->server_connp.cert0_fingerprint != NULL) { |
433 | 0 | MemBufferWriteString(aft->buffer, "%s", |
434 | 0 | ssl_state->server_connp.cert0_fingerprint); |
435 | 0 | } else { |
436 | 0 | LOG_CF_WRITE_UNKNOWN_VALUE(aft->buffer); |
437 | 0 | } |
438 | 0 | break; |
439 | 0 | case LOG_TLS_CF_SNI: |
440 | 0 | if (ssl_state->client_connp.sni != NULL) { |
441 | 0 | MemBufferWriteString(aft->buffer, "%s", |
442 | 0 | ssl_state->client_connp.sni); |
443 | 0 | } else { |
444 | 0 | LOG_CF_WRITE_UNKNOWN_VALUE(aft->buffer); |
445 | 0 | } |
446 | 0 | break; |
447 | 0 | case LOG_TLS_CF_SUBJECT: |
448 | 0 | if (ssl_state->server_connp.cert0_subject != NULL) { |
449 | 0 | MemBufferWriteString(aft->buffer, "%s", |
450 | 0 | ssl_state->server_connp.cert0_subject); |
451 | 0 | } else { |
452 | 0 | LOG_CF_WRITE_UNKNOWN_VALUE(aft->buffer); |
453 | 0 | } |
454 | 0 | break; |
455 | 0 | case LOG_TLS_CF_ISSUER: |
456 | 0 | if (ssl_state->server_connp.cert0_issuerdn != NULL) { |
457 | 0 | MemBufferWriteString(aft->buffer, "%s", |
458 | 0 | ssl_state->server_connp.cert0_issuerdn); |
459 | 0 | } else { |
460 | 0 | LOG_CF_WRITE_UNKNOWN_VALUE(aft->buffer); |
461 | 0 | } |
462 | 0 | break; |
463 | 0 | case LOG_TLS_CF_EXTENDED: |
464 | | /* Extended format */ |
465 | 0 | LogTlsLogExtended(aft, ssl_state, ts, srcip, sp, dstip, dp); |
466 | 0 | break; |
467 | 0 | default: |
468 | | /* NO MATCH */ |
469 | 0 | MemBufferWriteString(aft->buffer, LOG_CF_NONE); |
470 | 0 | SCLogDebug("No matching parameter %%%c for custom tls log.", |
471 | 0 | node->type); |
472 | 0 | break; |
473 | 0 | } |
474 | 0 | } |
475 | 0 | } |
476 | | |
477 | | |
478 | | static int LogTlsLogger(ThreadVars *tv, void *thread_data, const Packet *p, |
479 | | Flow *f, void *state, void *tx, uint64_t tx_id) |
480 | 6.09k | { |
481 | 6.09k | LogTlsLogThread *aft = (LogTlsLogThread *)thread_data; |
482 | 6.09k | LogTlsFileCtx *hlog = aft->tlslog_ctx; |
483 | 6.09k | int ipproto = (PKT_IS_IPV4(p)) ? AF_INET : AF_INET6; |
484 | | |
485 | 6.09k | SSLState *ssl_state = (SSLState *)state; |
486 | 6.09k | if (unlikely(ssl_state == NULL)) { |
487 | 0 | return 0; |
488 | 0 | } |
489 | | |
490 | 6.09k | if (((hlog->flags & LOG_TLS_SESSION_RESUMPTION) == 0 || |
491 | 6.09k | (ssl_state->flags & SSL_AL_FLAG_SESSION_RESUMED) == 0) && |
492 | 1.54k | (ssl_state->server_connp.cert0_issuerdn == NULL || |
493 | 99 | ssl_state->server_connp.cert0_subject == NULL) && |
494 | 1.44k | ((ssl_state->flags & SSL_AL_FLAG_LOG_WITHOUT_CERT) == 0)) { |
495 | 1.42k | return 0; |
496 | 1.42k | } |
497 | | |
498 | 4.66k | char srcip[PRINT_BUF_LEN], dstip[PRINT_BUF_LEN]; |
499 | | |
500 | 4.66k | Port sp, dp; |
501 | 4.66k | if (!TLSGetIPInformations(p, srcip, PRINT_BUF_LEN, &sp, dstip, |
502 | 4.66k | PRINT_BUF_LEN, &dp, ipproto)) { |
503 | 0 | return 0; |
504 | 0 | } |
505 | | |
506 | 4.66k | MemBufferReset(aft->buffer); |
507 | | |
508 | 4.66k | if (hlog->flags & LOG_TLS_CUSTOM) { |
509 | 0 | LogTlsLogCustom(aft, ssl_state, p->ts, srcip, sp, dstip, dp); |
510 | 4.66k | } else if (hlog->flags & LOG_TLS_EXTENDED) { |
511 | 4.66k | LogTlsLogBasic(aft, ssl_state, p->ts, srcip, sp, dstip, dp); |
512 | 4.66k | LogTlsLogExtended(aft, ssl_state, p->ts, srcip, sp, dstip, dp); |
513 | 4.66k | } else { |
514 | 0 | LogTlsLogBasic(aft, ssl_state, p->ts, srcip, sp, dstip, dp); |
515 | 0 | } |
516 | | |
517 | 4.66k | MemBufferWriteString(aft->buffer, "\n"); |
518 | | |
519 | 4.66k | aft->tls_cnt++; |
520 | | |
521 | 4.66k | hlog->file_ctx->Write((const char *)MEMBUFFER_BUFFER(aft->buffer), |
522 | 4.66k | MEMBUFFER_OFFSET(aft->buffer), hlog->file_ctx); |
523 | | |
524 | 4.66k | return 0; |
525 | 4.66k | } |
526 | | |
527 | | void LogTlsLogRegister(void) |
528 | 33 | { |
529 | 33 | OutputRegisterTxModuleWithProgress(LOGGER_TLS, MODULE_NAME, "tls-log", |
530 | 33 | LogTlsLogInitCtx, ALPROTO_TLS, LogTlsLogger, TLS_HANDSHAKE_DONE, |
531 | 33 | TLS_HANDSHAKE_DONE, LogTlsLogThreadInit, LogTlsLogThreadDeinit, |
532 | 33 | LogTlsLogExitPrintStats); |
533 | 33 | } |