suricata
log-tlsstore.c
Go to the documentation of this file.
1 /* Copyright (C) 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  *
25  * Implements TLS store portion of the engine.
26  *
27  */
28 
29 #include "suricata-common.h"
30 #include "log-tlsstore.h"
31 
32 #include "decode.h"
33 
34 #include "app-layer-parser.h"
35 #include "app-layer-ssl.h"
36 
37 #include "output.h"
38 #include "log-tlslog.h"
39 
40 #include "util-conf.h"
41 #include "util-path.h"
42 #include "util-time.h"
43 
44 #define MODULE_NAME "LogTlsStoreLog"
45 
46 static char tls_logfile_base_dir[PATH_MAX] = "/tmp";
47 SC_ATOMIC_DECLARE(unsigned int, cert_id);
48 static char logging_dir_not_writable;
49 
50 #define LOGGING_WRITE_ISSUE_LIMIT 6
51 
52 typedef struct LogTlsStoreLogThread_ {
53  uint32_t tls_cnt;
54 
55  uint8_t* enc_buf;
56  size_t enc_buf_len;
58 
59 static int CreateFileName(
60  const Packet *p, SSLState *state, char *filename, size_t filename_size, const bool client)
61 {
62  char path[PATH_MAX];
63  int file_id = SC_ATOMIC_ADD(cert_id, 1);
64 
65  const char *dir = client ? "client-" : "";
66 
67  /* Use format : packet time + incremental ID
68  * When running on same pcap it will overwrite
69  * On a live device, we will not be able to overwrite */
70  if (snprintf(path, sizeof(path), "%s/%s%ld.%ld-%d.pem", tls_logfile_base_dir, dir,
71  (long int)SCTIME_SECS(p->ts), (long int)SCTIME_USECS(p->ts),
72  file_id) == sizeof(path))
73  return 0;
74 
75  strlcpy(filename, path, filename_size);
76  return 1;
77 }
78 
79 static void LogTlsLogPem(LogTlsStoreLogThread *aft, const Packet *p, SSLState *state,
80  SSLStateConnp *connp, int ipproto)
81 {
82 #define PEMHEADER "-----BEGIN CERTIFICATE-----\n"
83 #define PEMFOOTER "-----END CERTIFICATE-----\n"
84  //Logging pem certificate
85  char filename[PATH_MAX] = "";
86  FILE* fp = NULL;
87  FILE* fpmeta = NULL;
88  unsigned long pemlen;
89  unsigned char* pembase64ptr = NULL;
90  int ret;
91  uint8_t *ptmp;
92  SSLCertsChain *cert;
93 
94  if (TAILQ_EMPTY(&connp->certs)) {
95  SCReturn;
96  }
97 
98  const bool client = connp == &state->client_connp;
99  CreateFileName(p, state, filename, sizeof(filename), client);
100  if (strlen(filename) == 0) {
101  SCLogWarning("Can't create PEM filename");
102  SCReturn;
103  }
104 
105  fp = fopen(filename, "w");
106  if (fp == NULL) {
107  if (logging_dir_not_writable < LOGGING_WRITE_ISSUE_LIMIT) {
108  SCLogWarning(
109  "Can't create PEM file '%s' in '%s' directory", filename, tls_logfile_base_dir);
110  logging_dir_not_writable++;
111  }
112  SCReturn;
113  }
114 
115  TAILQ_FOREACH (cert, &connp->certs, next) {
116  pemlen = Base64EncodeBufferSize(cert->cert_len);
117  if (pemlen > aft->enc_buf_len) {
118  ptmp = (uint8_t*) SCRealloc(aft->enc_buf, sizeof(uint8_t) * pemlen);
119  if (ptmp == NULL) {
120  SCFree(aft->enc_buf);
121  aft->enc_buf = NULL;
122  aft->enc_buf_len = 0;
123  SCLogWarning("Can't allocate data for base64 encoding");
124  goto end_fp;
125  }
126  aft->enc_buf = ptmp;
127  aft->enc_buf_len = pemlen;
128  }
129 
130  memset(aft->enc_buf, 0, aft->enc_buf_len);
131 
132  ret = Base64Encode((unsigned char*) cert->cert_data, cert->cert_len, aft->enc_buf, &pemlen);
133  if (ret != SC_BASE64_OK) {
134  SCLogWarning("Invalid return of Base64Encode function");
135  goto end_fwrite_fp;
136  }
137 
138  if (fprintf(fp, PEMHEADER) < 0)
139  goto end_fwrite_fp;
140 
141  pembase64ptr = aft->enc_buf;
142  while (pemlen > 0) {
143  size_t loffset = pemlen >= 64 ? 64 : pemlen;
144  if (fwrite(pembase64ptr, 1, loffset, fp) != loffset)
145  goto end_fwrite_fp;
146  if (fwrite("\n", 1, 1, fp) != 1)
147  goto end_fwrite_fp;
148  pembase64ptr += 64;
149  if (pemlen < 64)
150  break;
151  pemlen -= 64;
152  }
153 
154  if (fprintf(fp, PEMFOOTER) < 0)
155  goto end_fwrite_fp;
156  }
157  fclose(fp);
158 
159  //Logging certificate informations
160  memcpy(filename + (strlen(filename) - 3), "meta", 4);
161  fpmeta = fopen(filename, "w");
162  if (fpmeta != NULL) {
163  #define PRINT_BUF_LEN 46
164  char srcip[PRINT_BUF_LEN], dstip[PRINT_BUF_LEN];
165  char timebuf[64];
166  Port sp, dp;
167  CreateTimeString(p->ts, timebuf, sizeof(timebuf));
168  if (!TLSGetIPInformations(p, srcip, PRINT_BUF_LEN, &sp, dstip, PRINT_BUF_LEN, &dp, ipproto))
169  goto end_fwrite_fpmeta;
170  if (fprintf(fpmeta, "TIME: %s\n", timebuf) < 0)
171  goto end_fwrite_fpmeta;
172  if (p->pcap_cnt > 0) {
173  if (fprintf(fpmeta, "PCAP PKT NUM: %"PRIu64"\n", p->pcap_cnt) < 0)
174  goto end_fwrite_fpmeta;
175  }
176  if (fprintf(fpmeta, "SRC IP: %s\n", srcip) < 0)
177  goto end_fwrite_fpmeta;
178  if (fprintf(fpmeta, "DST IP: %s\n", dstip) < 0)
179  goto end_fwrite_fpmeta;
180  if (fprintf(fpmeta, "PROTO: %" PRIu32 "\n", p->proto) < 0)
181  goto end_fwrite_fpmeta;
182  if (PacketIsTCP(p) || PacketIsUDP(p)) {
183  if (fprintf(fpmeta, "SRC PORT: %" PRIu16 "\n", sp) < 0)
184  goto end_fwrite_fpmeta;
185  if (fprintf(fpmeta, "DST PORT: %" PRIu16 "\n", dp) < 0)
186  goto end_fwrite_fpmeta;
187  }
188 
189  if (fprintf(fpmeta,
190  "TLS SUBJECT: %s\n"
191  "TLS ISSUERDN: %s\n"
192  "TLS FINGERPRINT: %s\n",
193  connp->cert0_subject, connp->cert0_issuerdn, connp->cert0_fingerprint) < 0)
194  goto end_fwrite_fpmeta;
195 
196  fclose(fpmeta);
197  } else {
198  if (logging_dir_not_writable < LOGGING_WRITE_ISSUE_LIMIT) {
199  SCLogWarning("Can't create meta file '%s' in '%s' directory", filename,
200  tls_logfile_base_dir);
201  logging_dir_not_writable++;
202  }
203  SCReturn;
204  }
205 
206  /* Reset the store flag */
207  connp->cert_log_flag &= ~SSL_TLS_LOG_PEM;
208  SCReturn;
209 
210 end_fwrite_fp:
211  fclose(fp);
212  if (logging_dir_not_writable < LOGGING_WRITE_ISSUE_LIMIT) {
213  SCLogWarning("Unable to write certificate");
214  logging_dir_not_writable++;
215  }
216 end_fwrite_fpmeta:
217  if (fpmeta) {
218  fclose(fpmeta);
219  if (logging_dir_not_writable < LOGGING_WRITE_ISSUE_LIMIT) {
220  SCLogWarning("Unable to write certificate metafile");
221  logging_dir_not_writable++;
222  }
223  }
224  SCReturn;
225 end_fp:
226  fclose(fp);
227  SCReturn;
228 }
229 
230 /** \internal
231  * \brief Condition function for TLS logger
232  * \retval bool true or false -- log now?
233  */
234 static bool LogTlsStoreCondition(
235  ThreadVars *tv, const Packet *p, void *state, void *tx, uint64_t tx_id)
236 {
237  if (p->flow == NULL) {
238  return false;
239  }
240 
241  if (!(PacketIsTCP(p))) {
242  return false;
243  }
244 
245  SSLState *ssl_state = (SSLState *)state;
246  if (ssl_state == NULL) {
247  SCLogDebug("no tls state, so no request logging");
248  goto dontlog;
249  }
250 
251  if ((ssl_state->server_connp.cert_log_flag & SSL_TLS_LOG_PEM) == 0) {
252  goto dontlog;
253  }
254 
255  if (ssl_state->server_connp.cert0_issuerdn == NULL ||
256  ssl_state->server_connp.cert0_subject == NULL) {
257  goto dontlog;
258  }
259 
260  return true;
261 dontlog:
262  return false;
263 }
264 
265 static bool LogTlsStoreConditionClient(
266  ThreadVars *tv, const Packet *p, void *state, void *tx, uint64_t tx_id)
267 {
268  if (p->flow == NULL) {
269  return false;
270  }
271 
272  if (!(PacketIsTCP(p))) {
273  return false;
274  }
275 
276  SSLState *ssl_state = (SSLState *)state;
277  if (ssl_state == NULL) {
278  SCLogDebug("no tls state, so no request logging");
279  goto dontlog;
280  }
281 
282  if ((ssl_state->client_connp.cert_log_flag & SSL_TLS_LOG_PEM) == 0) {
283  goto dontlog;
284  }
285 
286  if ((ssl_state->client_connp.cert0_issuerdn == NULL ||
287  ssl_state->client_connp.cert0_subject == NULL)) {
288  goto dontlog;
289  }
290 
291  return true;
292 dontlog:
293  return false;
294 }
295 
296 static int LogTlsStoreLoggerClient(ThreadVars *tv, void *thread_data, const Packet *p, Flow *f,
297  void *state, void *tx, uint64_t tx_id)
298 {
299  LogTlsStoreLogThread *aft = (LogTlsStoreLogThread *)thread_data;
300  int ipproto = (PacketIsIPv4(p)) ? AF_INET : AF_INET6;
301 
302  SSLState *ssl_state = (SSLState *)state;
303  if (unlikely(ssl_state == NULL)) {
304  return 0;
305  }
306  /* client cert */
307  SSLStateConnp *connp = &ssl_state->client_connp;
308  if (connp->cert_log_flag & SSL_TLS_LOG_PEM) {
309  LogTlsLogPem(aft, p, ssl_state, connp, ipproto);
310  }
311 
312  return 0;
313 }
314 
315 static int LogTlsStoreLogger(ThreadVars *tv, void *thread_data, const Packet *p, Flow *f,
316  void *state, void *tx, uint64_t tx_id)
317 {
318  LogTlsStoreLogThread *aft = (LogTlsStoreLogThread *)thread_data;
319  int ipproto = (PacketIsIPv4(p)) ? AF_INET : AF_INET6;
320 
321  SSLState *ssl_state = (SSLState *)state;
322  if (unlikely(ssl_state == NULL)) {
323  return 0;
324  }
325  /* server cert */
326  SSLStateConnp *connp = &ssl_state->server_connp;
327  if (connp->cert_log_flag & SSL_TLS_LOG_PEM) {
328  LogTlsLogPem(aft, p, ssl_state, connp, ipproto);
329  }
330 
331  return 0;
332 }
333 
334 static TmEcode LogTlsStoreLogThreadInit(ThreadVars *t, const void *initdata, void **data)
335 {
337  if (unlikely(aft == NULL))
338  return TM_ECODE_FAILED;
339 
340  if (initdata == NULL) {
341  SCLogDebug("Error getting context for LogTLSStore. \"initdata\" argument NULL");
342  SCFree(aft);
343  return TM_ECODE_FAILED;
344  }
345 
346  struct stat stat_buf;
347  /* coverity[toctou] */
348  if (stat(tls_logfile_base_dir, &stat_buf) != 0) {
349  int ret;
350  /* coverity[toctou] */
351  ret = SCMkDir(tls_logfile_base_dir, S_IRWXU|S_IXGRP|S_IRGRP);
352  if (ret != 0) {
353  int err = errno;
354  if (err != EEXIST) {
355  SCLogError("Cannot create certs drop directory %s: %s", tls_logfile_base_dir,
356  strerror(err));
357  exit(EXIT_FAILURE);
358  }
359  } else {
360  SCLogInfo("Created certs drop directory %s",
361  tls_logfile_base_dir);
362  }
363 
364  }
365 
366  *data = (void *)aft;
367  return TM_ECODE_OK;
368 }
369 
370 static TmEcode LogTlsStoreLogThreadDeinit(ThreadVars *t, void *data)
371 {
373  if (aft == NULL) {
374  return TM_ECODE_OK;
375  }
376 
377  if (aft->enc_buf != NULL)
378  SCFree(aft->enc_buf);
379 
380  /* clear memory */
381  memset(aft, 0, sizeof(LogTlsStoreLogThread));
382 
383  SCFree(aft);
384  return TM_ECODE_OK;
385 }
386 
387 static void LogTlsStoreLogExitPrintStats(ThreadVars *tv, void *data)
388 {
390  if (aft == NULL) {
391  return;
392  }
393 
394  SCLogInfo("(%s) certificates extracted %" PRIu32 "", tv->name, aft->tls_cnt);
395 }
396 
397 /**
398  * \internal
399  *
400  * \brief deinit the log ctx and write out the waldo
401  *
402  * \param output_ctx output context to deinit
403  */
404 static void LogTlsStoreLogDeInitCtx(OutputCtx *output_ctx)
405 {
406  SCFree(output_ctx);
407 }
408 
409 /** \brief Create a new http log LogFilestoreCtx.
410  * \param conf Pointer to ConfNode containing this loggers configuration.
411  * \return NULL if failure, LogFilestoreCtx* to the file_ctx if succesful
412  * */
413 static OutputInitResult LogTlsStoreLogInitCtx(ConfNode *conf)
414 {
415  OutputInitResult result = { NULL, false };
416  OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx));
417  if (unlikely(output_ctx == NULL))
418  return result;
419 
420  output_ctx->data = NULL;
421  output_ctx->DeInit = LogTlsStoreLogDeInitCtx;
422 
423  const char *s_default_log_dir = ConfigGetLogDirectory();
424  const char *s_base_dir = ConfNodeLookupChildValue(conf, "certs-log-dir");
425  if (s_base_dir == NULL || strlen(s_base_dir) == 0) {
426  strlcpy(tls_logfile_base_dir,
427  s_default_log_dir, sizeof(tls_logfile_base_dir));
428  } else {
429  if (PathIsAbsolute(s_base_dir)) {
430  strlcpy(tls_logfile_base_dir,
431  s_base_dir, sizeof(tls_logfile_base_dir));
432  } else {
433  snprintf(tls_logfile_base_dir, sizeof(tls_logfile_base_dir),
434  "%s/%s", s_default_log_dir, s_base_dir);
435  }
436  }
437 
438  SCLogInfo("storing certs in %s", tls_logfile_base_dir);
439 
440  /* enable the logger for the app layer */
442 
443  result.ctx = output_ctx;
444  result.ok = true;
445  SCReturnCT(result, "OutputInitResult");
446 }
447 
449 {
451  "tls-store", LogTlsStoreLogInitCtx, ALPROTO_TLS, LogTlsStoreLogger,
452  LogTlsStoreCondition, LogTlsStoreLogThreadInit,
453  LogTlsStoreLogThreadDeinit, LogTlsStoreLogExitPrintStats);
454 
456  LogTlsStoreLogInitCtx, ALPROTO_TLS, LogTlsStoreLoggerClient, LogTlsStoreConditionClient,
457  LogTlsStoreLogThreadInit, LogTlsStoreLogThreadDeinit, LogTlsStoreLogExitPrintStats);
458 
459  SC_ATOMIC_INIT(cert_id);
460  SC_ATOMIC_SET(cert_id, 1);
461 
462  SCLogDebug("registered");
463 }
LogTlsStoreRegister
void LogTlsStoreRegister(void)
Definition: log-tlsstore.c:448
SSLStateConnp_::cert0_subject
char * cert0_subject
Definition: app-layer-ssl.h:255
Packet_::proto
uint8_t proto
Definition: decode.h:501
SSLState_
SSLv[2.0|3.[0|1|2|3]] state structure.
Definition: app-layer-ssl.h:296
SSLCertsChain_::cert_len
uint32_t cert_len
Definition: app-layer-ssl.h:225
ThreadVars_::name
char name[16]
Definition: threadvars.h:64
SC_ATOMIC_INIT
#define SC_ATOMIC_INIT(name)
wrapper for initializing an atomic variable.
Definition: util-atomic.h:314
unlikely
#define unlikely(expr)
Definition: util-optimize.h:35
SC_ATOMIC_SET
#define SC_ATOMIC_SET(name, val)
Set the value for the atomic variable.
Definition: util-atomic.h:386
SSLState_::client_connp
SSLStateConnp client_connp
Definition: app-layer-ssl.h:314
ALPROTO_TLS
@ ALPROTO_TLS
Definition: app-layer-protos.h:33
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:269
Packet_::pcap_cnt
uint64_t pcap_cnt
Definition: decode.h:601
next
struct HtpBodyChunk_ * next
Definition: app-layer-htp.h:0
SSLState_::server_connp
SSLStateConnp server_connp
Definition: app-layer-ssl.h:315
SSLStateConnp_
Definition: app-layer-ssl.h:235
Flow_
Flow data structure.
Definition: flow.h:360
SC_ATOMIC_ADD
#define SC_ATOMIC_ADD(name, val)
add a value to our atomic variable
Definition: util-atomic.h:332
TAILQ_EMPTY
#define TAILQ_EMPTY(head)
Definition: queue.h:248
TAILQ_FOREACH
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:252
TM_ECODE_FAILED
@ TM_ECODE_FAILED
Definition: tm-threads-common.h:83
LogTlsStoreLogThread_
Definition: log-tlsstore.c:52
SSLStateConnp_::cert0_issuerdn
char * cert0_issuerdn
Definition: app-layer-ssl.h:256
OutputCtx_::data
void * data
Definition: tm-modules.h:88
TM_ECODE_OK
@ TM_ECODE_OK
Definition: tm-threads-common.h:82
OutputCtx_
Definition: tm-modules.h:85
strlcpy
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: util-strlcpyu.c:43
decode.h
OutputInitResult_::ctx
OutputCtx * ctx
Definition: output.h:47
Packet_::ts
SCTime_t ts
Definition: decode.h:527
AppLayerParserRegisterLogger
void AppLayerParserRegisterLogger(uint8_t ipproto, AppProto alproto)
Definition: app-layer-parser.c:458
SSLCertsChain_
Definition: app-layer-ssl.h:223
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:57
LogTlsStoreLogThread
struct LogTlsStoreLogThread_ LogTlsStoreLogThread
util-time.h
OutputInitResult_::ok
bool ok
Definition: output.h:48
log-tlslog.h
SCLogWarning
#define SCLogWarning(...)
Macro used to log WARNING messages.
Definition: util-debug.h:249
app-layer-parser.h
LogTlsStoreLogThread_::enc_buf_len
size_t enc_buf_len
Definition: log-tlsstore.c:56
SCReturn
#define SCReturn
Definition: util-debug.h:273
Packet_
Definition: decode.h:479
Port
uint16_t Port
Definition: decode.h:220
TmEcode
TmEcode
Definition: tm-threads-common.h:81
SSLCertsChain_::cert_data
uint8_t * cert_data
Definition: app-layer-ssl.h:224
SCLogInfo
#define SCLogInfo(...)
Macro used to log INFORMATIONAL messages.
Definition: util-debug.h:224
SCRealloc
#define SCRealloc(ptr, sz)
Definition: util-mem.h:50
OutputInitResult_
Definition: output.h:46
util-conf.h
Packet_::flow
struct Flow_ * flow
Definition: decode.h:518
suricata-common.h
OutputCtx_::DeInit
void(* DeInit)(struct OutputCtx_ *)
Definition: tm-modules.h:91
PEMFOOTER
#define PEMFOOTER
util-path.h
SCTIME_SECS
#define SCTIME_SECS(t)
Definition: util-time.h:57
PathIsAbsolute
int PathIsAbsolute(const char *path)
Check if a path is absolute.
Definition: util-path.c:44
PRINT_BUF_LEN
#define PRINT_BUF_LEN
SCMkDir
#define SCMkDir(a, b)
Definition: util-path.h:45
MODULE_NAME
#define MODULE_NAME
Definition: log-tlsstore.c:44
tv
ThreadVars * tv
Definition: fuzz_decodepcapfile.c:32
SSL_TLS_LOG_PEM
#define SSL_TLS_LOG_PEM
Definition: app-layer-ssl.h:138
ConfigGetLogDirectory
const char * ConfigGetLogDirectory(void)
Definition: util-conf.c:38
TLSGetIPInformations
int TLSGetIPInformations(const Packet *p, char *srcip, size_t srcip_len, Port *sp, char *dstip, size_t dstip_len, Port *dp, int ipproto)
Definition: log-tlslog.c:94
SCLogError
#define SCLogError(...)
Macro used to log ERROR messages.
Definition: util-debug.h:261
SCFree
#define SCFree(p)
Definition: util-mem.h:61
ConfNode_
Definition: conf.h:32
SSLStateConnp_::cert_log_flag
uint32_t cert_log_flag
Definition: app-layer-ssl.h:275
LOGGER_TLS_STORE_CLIENT
@ LOGGER_TLS_STORE_CLIENT
Definition: suricata-common.h:466
SCReturnCT
#define SCReturnCT(x, type)
Definition: util-debug.h:285
LOGGING_WRITE_ISSUE_LIMIT
#define LOGGING_WRITE_ISSUE_LIMIT
Definition: log-tlsstore.c:50
LogTlsStoreLogThread_::enc_buf
uint8_t * enc_buf
Definition: log-tlsstore.c:55
LOGGER_TLS_STORE
@ LOGGER_TLS_STORE
Definition: suricata-common.h:465
SSLStateConnp_::cert0_fingerprint
char * cert0_fingerprint
Definition: app-layer-ssl.h:260
SC_ATOMIC_DECLARE
SC_ATOMIC_DECLARE(unsigned int, cert_id)
log-tlsstore.h
SCCalloc
#define SCCalloc(nm, sz)
Definition: util-mem.h:53
OutputRegisterTxModuleWithCondition
void OutputRegisterTxModuleWithCondition(LoggerId id, const char *name, const char *conf_name, OutputInitFunc InitFunc, AppProto alproto, TxLogger TxLogFunc, TxLoggerCondition TxLogCondition, ThreadInitFunc ThreadInit, ThreadDeinitFunc ThreadDeinit, ThreadExitPrintStatsFunc ThreadExitPrintStats)
Register a tx output module with condition.
Definition: output.c:332
app-layer-ssl.h
PEMHEADER
#define PEMHEADER
CreateTimeString
void CreateTimeString(const SCTime_t ts, char *str, size_t size)
Definition: util-time.c:272
output.h
SCTIME_USECS
#define SCTIME_USECS(t)
Definition: util-time.h:56
LogTlsStoreLogThread_::tls_cnt
uint32_t tls_cnt
Definition: log-tlsstore.c:53
ConfNodeLookupChildValue
const char * ConfNodeLookupChildValue(const ConfNode *node, const char *name)
Lookup the value of a child configuration node by name.
Definition: conf.c:809