The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
log.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or modify
3  * it under the terms of the GNU General Public License as published by
4  * the Free Software Foundation; either version 2 of the License, or
5  * (at your option) any later version.
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  * along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
15  */
16 
17 /**
18  * $Id: 96d9bb20303e73cb067d7cf525545f32f6b44183 $
19  *
20  * @file tls/log.c
21  * @brief Retrieve errors and log messages from OpenSSL's overly complex logging system.
22  *
23  * @copyright 2016,2021 Arran Cudbard-Bell (a.cudbardb@freeradius.org)
24  * @copyright 2016 The FreeRADIUS server project
25  */
26 RCSID("$Id: 96d9bb20303e73cb067d7cf525545f32f6b44183 $")
27 USES_APPLE_DEPRECATED_API /* OpenSSL API has been deprecated by Apple */
28 
29 #ifdef WITH_TLS
30 #define LOG_PREFIX "tls"
31 
32 #include <freeradius-devel/util/debug.h>
33 #include <freeradius-devel/util/atexit.h>
34 #include <freeradius-devel/tls/strerror.h>
35 #include <freeradius-devel/tls/utils.h>
36 #include <stdatomic.h>
37 
38 #include "log.h"
39 
40 /** Holds the state of a log BIO
41  *
42  * Most of these fields are expected to change between uses of the BIO.
43  *
44  * BIOs do not have indexed extension structures like other structures in OpenSSL,
45  * so we're forced to place all information in a structure, and populate it just
46  * prior to a BIO being used.
47  *
48  * These BIOs are thread local to avoid conflicts or locking issues.
49  */
50 typedef struct {
51  BIO *bio; //!< Logging bio to write to.
52  fr_sbuff_t sbuff; //!< Used to aggregate line data.
53  fr_sbuff_uctx_talloc_t tctx; //!< extra talloc information for the sbuff.
54  fr_sbuff_marker_t logged_m; //!< How much data has been written.
55 
56  request_t *request; //!< the current request. Only used for the
57  ///< request log BIOs.
58  fr_log_type_t type; //!< The type of log messages the bio will produce.
59  fr_log_lvl_t lvl; //!< Level to log message at.
60  char const *file; //!< File this log bio was bound on.
61  int line; //!< Line this log bio was bound on.
62 } fr_tls_log_bio_t;
63 
64 /** Template for the thread local request log BIOs
65  */
66 static BIO_METHOD *tls_request_log_meth;
67 
68 /** Template for the global log BIOs
69  */
70 static BIO_METHOD *tls_global_log_meth;
71 
72 /** Counter for users of the request log bio
73  *
74  */
75 static _Atomic(uint32_t) tls_request_log_ref;
76 
77 /** Counter for users of the global log bio
78  *
79  */
80 static _Atomic(uint32_t) tls_global_log_ref;
81 
82 /** Thread local request log BIO
83  */
84 static _Thread_local fr_tls_log_bio_t *request_log_bio;
85 
86 /** Thread local global log BIO
87  */
88 static _Thread_local fr_tls_log_bio_t *global_log_bio;
89 
90 /** Print out the current stack of certs
91  *
92  * @param[in] file File where this function is being called.
93  * @param[in] line Line where this function is being called.
94  * @param[in] request Current request, may be NULL.
95  * @param[in] log_type The type of log message to produce L_INFO, L_ERR, L_DBG etc...
96  * @param[in] chain The certificate chain.
97  * @param[in] cert The leaf certificate.
98  */
99 void _fr_tls_chain_log(char const *file, int line,
100  request_t *request, fr_log_type_t log_type,
101  STACK_OF(X509) *chain, X509 *cert)
102 {
103  /*
104  * Dump to the thread local buffer
105  */
107  _fr_tls_strerror_push_chain(file, line, chain, cert);
108  if (request) {
109  log_request_perror(log_type, L_DBG_LVL_OFF, request, file, line, NULL);
110  } else {
111  fr_perror(NULL);
112  }
113 }
114 
115 /** Print out the current stack of certs
116  *
117  * @param[in] file File where this function is being called.
118  * @param[in] line Line where this function is being called.
119  * @param[in] request Current request, may be NULL.
120  * @param[in] log_type The type of log message to produce L_INFO, L_ERR, L_DBG etc...
121  * @param[in] chain The certificate chain.
122  * @param[in] cert The leaf certificate.
123  * @param[in] marker The certificate we want to mark.
124  */
125 void _fr_tls_chain_marker_log(char const *file, int line,
126  request_t *request, fr_log_type_t log_type,
127  STACK_OF(X509) *chain, X509 *cert, X509 *marker)
128 {
129  /*
130  * Dump to the thread local buffer
131  */
133  _fr_tls_strerror_push_chain_marker(file, line, chain, cert, marker);
134  if (request) {
135  log_request_perror(log_type, L_DBG_LVL_OFF, request, file, line, NULL);
136  } else {
137  fr_perror(NULL);
138  }
139 }
140 
141 /** Print out the current stack of X509 objects (certificates only)
142  *
143  * @param[in] file File where this function is being called.
144  * @param[in] line Line where this function is being called.
145  * @param[in] request Current request, may be NULL.
146  * @param[in] log_type The type of log message to produce L_INFO, L_ERR, L_DBG etc...
147  * @param[in] objects A stack of X509 objects
148  */
149 void _fr_tls_x509_objects_log(char const *file, int line,
150  request_t *request, fr_log_type_t log_type,
151  STACK_OF(X509_OBJECT) *objects)
152 {
153 
155  _fr_tls_strerror_push_x509_objects(file, line, objects);
156  if (request) {
157  log_request_perror(log_type, L_DBG_LVL_OFF, request, file, line, NULL);
158  } else {
159  fr_perror(NULL);
160  }
161 }
162 
163 /** Print errors raised by OpenSSL I/O functions
164  *
165  * Drains the thread local OpenSSL error queue, and prints out errors
166  * based on the SSL handle and the return code of the I/O function.
167  *
168  * OpenSSL lists I/O functions to be:
169  * - SSL_connect
170  * - SSL_accept
171  * - SSL_do_handshake
172  * - SSL_read
173  * - SSL_peek
174  * - SSL_write
175  *
176  * @param request The current request (may be NULL).
177  * @param err returned from SSL_get_error().
178  * @param fmt Error message describing the operation being attempted.
179  * @param ... Arguments for msg.
180  * @return
181  * - 0 TLS session may still be viable.
182  * - -1 TLS session cannot continue.
183  */
184 int fr_tls_log_io_error(request_t *request, int err, char const *fmt, ...)
185 {
186  static fr_table_num_ordered_t const ssl_io_error_table[] = {
187  { L("SSL_ERROR_NONE"), SSL_ERROR_NONE },
188  { L("SSL_ERROR_ZERO_RETURN"), SSL_ERROR_ZERO_RETURN },
189  { L("SSL_ERROR_WANT_READ"), SSL_ERROR_WANT_READ },
190  { L("SSL_ERROR_WANT_WRITE"), SSL_ERROR_WANT_WRITE },
191  { L("SSL_ERROR_WANT_CONNECT"), SSL_ERROR_WANT_CONNECT },
192  { L("SSL_ERROR_WANT_ACCEPT"), SSL_ERROR_WANT_ACCEPT },
193  { L("SSL_ERROR_WANT_X509_LOOKUP"), SSL_ERROR_WANT_X509_LOOKUP },
194  { L("SSL_ERROR_WANT_ASYNC"), SSL_ERROR_WANT_ASYNC },
195  { L("SSL_ERROR_WANT_ASYNC_JOB"), SSL_ERROR_WANT_ASYNC_JOB },
196  { L("SSL_ERROR_WANT_CLIENT_HELLO_CB"), SSL_ERROR_WANT_CLIENT_HELLO_CB },
197  { L("SSL_ERROR_SYSCALL"), SSL_ERROR_SYSCALL },
198  { L("SSL_ERROR_SSL"), SSL_ERROR_SSL }
199  };
200  static size_t ssl_io_error_table_len = NUM_ELEMENTS(ssl_io_error_table);
201 
202  va_list ap;
203  char *msg = NULL;
204 
205  switch (err) {
206  /*
207  * These seem to be harmless and already "dealt
208  * with" by our non-blocking environment. NB:
209  * "ZERO_RETURN" is the clean "error"
210  * indicating a successfully closed SSL
211  * tunnel. We let this happen because our IO
212  * loop should not appear to have broken on
213  * this condition - and outside the IO loop, the
214  * "shutdown" state is checked.
215  *
216  * Don't print anything if we ignore the error.
217  */
218  case SSL_ERROR_NONE:
219  case SSL_ERROR_WANT_READ:
220  case SSL_ERROR_WANT_WRITE:
221  case SSL_ERROR_WANT_X509_LOOKUP:
222  case SSL_ERROR_ZERO_RETURN:
224  va_start(ap, fmt);
225  msg = fr_vasprintf(NULL, fmt, ap);
226  va_end(ap);
227 
228  ROPTIONAL(RDEBUG2, DEBUG2, "%s - %s (%i)",
229  msg, fr_table_str_by_value(ssl_io_error_table, err, "<UNKNOWN>"), err);
230  talloc_free(msg);
231  }
232  break;
233 
234  /*
235  * These seem to be indications of a genuine
236  * error that should result in the SSL tunnel
237  * being regarded as "dead".
238  */
239  case SSL_ERROR_SYSCALL:
240  va_start(ap, fmt);
241  msg = fr_vasprintf(NULL, fmt, ap);
242  va_end(ap);
243 
244  ROPTIONAL(REDEBUG, ERROR, "%s - System call (I/O) error - %s (%i)",
245  msg, fr_table_str_by_value(ssl_io_error_table, err, "<UNKNOWN>"), err);
246 
247  talloc_free(msg);
248  return -1;
249 
250  /*
251  * Docs say a more verbose error is available
252  * in the normal error stack.
253  */
254  case SSL_ERROR_SSL:
255  va_start(ap, fmt);
256  (void)fr_tls_strerror_vprintf(fmt, ap);
257  va_end(ap);
258 
259  ROPTIONAL(RPERROR, PERROR, "");
260  return -1;
261 
262  /*
263  * For any other errors that (a) exist, and (b)
264  * crop up - we need to interpret what to do with
265  * them - so "politely inform" the caller that
266  * the code needs updating here.
267  */
268  default:
269  va_start(ap, fmt);
270  msg = fr_vasprintf(NULL, fmt, ap);
271  va_end(ap);
272 
273  ROPTIONAL(REDEBUG, ERROR, "%s - TLS session error - %s (%i)",
274  msg, fr_table_str_by_value(ssl_io_error_table, err, "<UNKNOWN>"), err);
275 
276  talloc_free(msg);
277 
278  return -1;
279  }
280 
281  return 0;
282 }
283 
284 
285 /** Print errors in the TLS thread local error stack
286  *
287  * Drains the thread local OpenSSL error queue, and prints out errors.
288  *
289  * @param[in] request The current request (may be NULL).
290  * @param[in] msg Error message describing the operation being attempted.
291  * @param[in] ... Arguments for msg.
292  * @return the number of errors drained from the stack.
293  */
294 int fr_tls_log(request_t *request, char const *msg, ...)
295 {
296  va_list ap;
297  int ret;
298 
299  va_start(ap, msg);
300  ret = fr_tls_strerror_vprintf(msg, ap);
301  va_end(ap);
302 
303  ROPTIONAL(RPERROR, PERROR, "");
304 
305  return ret;
306 }
307 
308 /** Clear errors in the TLS thread local error stack
309  *
310  */
311 void fr_tls_log_clear(void)
312 {
313  while (ERR_get_error() != 0);
314 }
315 
316 /** Increment the bio meth reference counter
317  *
318  */
319 static int tls_log_request_bio_create_cb(BIO *bio)
320 {
321  atomic_fetch_add(&tls_request_log_ref, 1);
322  BIO_set_init(bio, 1);
323  return 1;
324 }
325 
326 /** Converts BIO_write() calls to request log calls
327  *
328  * This callback is used to glue the output of OpenSSL functions into request log calls.
329  *
330  * @param[in] bio that was written to.
331  * @param[in] in data being written to BIO.
332  * @param[in] len Length of data being written.
333  */
334 static int tls_log_request_bio_write_cb(BIO *bio, char const *in, int len)
335 {
336  fr_tls_log_bio_t *lb = talloc_get_type_abort(BIO_get_data(bio), fr_tls_log_bio_t);
337  request_t *request = talloc_get_type_abort(lb->request, request_t);
338  log_request_func_t func;
339  char *le;
340 
341  /*
342  * Pick the right logging function based on the type
343  */
344  if ((lb->type == L_ERR) || (lb->type == L_DBG_ERR) || (lb->type == L_DBG_ERR_REQ)) {
345  func = log_request_error;
346  } else {
347  func = log_request;
348  }
349 
350  /*
351  * OpenSSL feeds us data in fragments so we need
352  * to aggregate it, then look for new line chars
353  * as an indication we need to print the line.
354  */
355  if (fr_sbuff_in_bstrncpy(&lb->sbuff, in, len) < 0) return 0;
356 
357  /*
358  * Split incoming data on new lines
359  */
360  while (fr_sbuff_behind(&lb->logged_m)) {
361  le = memchr(fr_sbuff_current(&lb->logged_m), '\n',
362  fr_sbuff_current(&lb->sbuff) - fr_sbuff_current(&lb->logged_m));
363  /*
364  * Wait until we have a complete line
365  */
366  if (le == NULL) break;
367 
368  /*
369  * Skip empty lines
370  */
371  if ((le - fr_sbuff_current(&lb->logged_m)) > 0) {
372  func(lb->type, lb->lvl, request, __FILE__, __LINE__, "%pV",
373  fr_box_strvalue_len(fr_sbuff_current(&lb->logged_m),
374  le - fr_sbuff_current(&lb->logged_m)));
375  }
376 
377  fr_sbuff_set(&lb->logged_m, le + 1);
378  }
379 
380  /*
381  * Clear out printed data
382  */
383  fr_sbuff_shift(&lb->sbuff, fr_sbuff_used(&lb->logged_m));
384 
385  return len; /* Amount of data written */
386 }
387 
388 /** Converts BIO_puts() calls to request log calls
389  *
390  * This callback is used to glue the output of OpenSSL functions into request log calls.
391  *
392  * @param[in] bio that was written to.
393  * @param[in] in data being written to BIO.
394  */
395 static int tls_log_request_bio_puts_cb(BIO *bio, char const *in)
396 {
397  return tls_log_request_bio_write_cb(bio, in, strlen(in));
398 }
399 
400 /** Decrement the bio meth reference counter
401  *
402  */
403 static int tls_log_request_bio_free_cb(BIO *bio)
404 {
405  atomic_fetch_sub(&tls_request_log_ref, 1);
406  BIO_set_init(bio, 0);
407  return 1;
408 }
409 
410 /** Increment the bio meth reference counter
411  *
412  */
413 static int tls_log_global_bio_create_cb(BIO *bio)
414 {
415  atomic_fetch_add(&tls_global_log_ref, 1);
416  BIO_set_init(bio, 1);
417  return 1;
418 }
419 
420 /** Converts BIO_write() calls to global log calls
421  *
422  * This callback is used to glue the output of OpenSSL functions into global log calls.
423  *
424  * @param[in] bio that was written to.
425  * @param[in] in data being written to BIO.
426  * @param[in] len Length of data being written.
427  */
428 static int tls_log_global_bio_write_cb(BIO *bio, char const *in, int len)
429 {
430  fr_tls_log_bio_t *lb = talloc_get_type_abort(BIO_get_data(bio), fr_tls_log_bio_t);
431  char *le;
432 
433  /*
434  * OpenSSL feeds us data in fragments so we need
435  * to aggregate it, then look for new line chars
436  * as an indication we need to print the line.
437  */
438  if (fr_sbuff_in_bstrncpy(&lb->sbuff, in, len) < 0) return 0;
439 
440  /*
441  * Split incoming data on new lines
442  */
443  while (fr_sbuff_behind(&lb->logged_m)) {
444  le = memchr(fr_sbuff_current(&lb->logged_m), '\n',
445  fr_sbuff_current(&lb->sbuff) - fr_sbuff_current(&lb->logged_m));
446  /*
447  * Wait until we have a complete line
448  */
449  if (le == NULL) break;
450 
451  /*
452  * Skip empty lines
453  */
454  if ((le - fr_sbuff_current(&lb->logged_m)) > 0) {
455  if (fr_debug_lvl >= lb->lvl) fr_log(&default_log, lb->type, __FILE__, __LINE__,
456  "%pV",
457  fr_box_strvalue_len(fr_sbuff_current(&lb->logged_m),
458  le - fr_sbuff_current(&lb->logged_m)));
459  }
460 
461  fr_sbuff_set(&lb->logged_m, le + 1);
462  }
463 
464  /*
465  * Clear out printed data
466  */
467  fr_sbuff_shift(&lb->sbuff, fr_sbuff_used(&lb->logged_m));
468 
469  return len; /* Amount of data written */
470 }
471 
472 /** Converts BIO_puts() calls to global log calls
473  *
474  * This callback is used to glue the output of OpenSSL functions into global log calls.
475  *
476  * @param[in] bio that was written to.
477  * @param[in] in data being written to BIO.
478  */
479 static int tls_log_global_bio_puts_cb(BIO *bio, char const *in)
480 {
481  return tls_log_global_bio_write_cb(bio, in, strlen(in));
482 }
483 
484 /** Decrement the bio meth reference counter
485  *
486  */
487 static int tls_log_global_bio_free_cb(BIO *bio)
488 {
489  atomic_fetch_sub(&tls_global_log_ref, 1);
490  BIO_set_init(bio, 0);
491  return 1;
492 }
493 
494 /** Frees a logging bio and its underlying OpenSSL BIO *
495  *
496  */
497 static int _fr_tls_log_bio_free(void *log_bio)
498 {
499  fr_tls_log_bio_t *our_log_bio = talloc_get_type_abort(log_bio, fr_tls_log_bio_t);
500 
501  BIO_free(our_log_bio->bio);
502  our_log_bio->bio = NULL;
503  return talloc_free(our_log_bio);
504 }
505 
506 /** Return a request log BIO to use with OpenSSL logging functions
507  *
508  * @note The contents of the BIO will only be written to the logging system on finding
509  * a new line. If data remains in the BIO when it is re-initialised (this function
510  * is called again), that data will be discarded.
511  *
512  * @note The returned BIO should be assumed to be invalid if the request yields.
513  *
514  * @param[in] file of caller.
515  * @param[in] line of caller.
516  * @param[in] request to temporarily associate with logging BIO.
517  * @param[in] type to temporarily assign to logging bio.
518  * @param[in] lvl to temporarily assign to logging bio.
519  * @return A thread local BIO to pass to OpenSSL logging functions.
520  */
521 BIO *_fr_tls_request_log_bio(char const *file, int line, request_t *request, fr_log_type_t type, fr_log_lvl_t lvl)
522 {
523  if (unlikely(!request_log_bio)) {
524  fr_tls_log_bio_t *lb;
525 
526  MEM(lb = talloc(NULL, fr_tls_log_bio_t));
527  *lb = (fr_tls_log_bio_t) {
528  .bio = BIO_new(tls_request_log_meth),
529  .request = request,
530  .type = type,
531  .lvl = lvl,
532  .file = file,
533  .line = line
534  };
535  MEM(lb->bio);
536  BIO_set_data(lb->bio, lb); /* So we can retrieve the fr_tls_lb_t in the callbacks */
537  fr_sbuff_init_talloc(lb, &lb->sbuff, &lb->tctx, 1024, 10 * 1024); /* start 1k, max 10k */
538  fr_atexit_thread_local(request_log_bio, _fr_tls_log_bio_free, lb);
539  fr_sbuff_marker(&lb->logged_m, &lb->sbuff);
540  return lb->bio;
541  }
542  fr_sbuff_reset_talloc(&request_log_bio->sbuff); /* Reset to initial size */
543  fr_sbuff_marker(&request_log_bio->logged_m, &request_log_bio->sbuff);
544  request_log_bio->request = request;
545  request_log_bio->type = type;
546  request_log_bio->lvl = lvl;
547  request_log_bio->file = file;
548  request_log_bio->line = line;
549 
550  return request_log_bio->bio;
551 }
552 
553 /** Return a global log BIO to use with OpenSSL logging functions
554  *
555  * @note The contents of the BIO will only be written to the logging system on finding
556  * a new line. If data remains in the BIO when it is re-initialised (this function
557  * is called again), that data will be discarded.
558  *
559  * @note The returned BIO should be assumed to be invalid if the current request yields.
560  *
561  * @param[in] file of caller.
562  * @param[in] line of caller.
563  * @param[in] type to temporarily assign to logging bio.
564  * @param[in] lvl to temporarily assign to logging bio.
565  * @return A thread local BIO to pass to OpenSSL logging functions.
566  */
567 BIO *_fr_tls_global_log_bio(char const *file, int line, fr_log_type_t type, fr_log_lvl_t lvl)
568 {
569  if (unlikely(!global_log_bio)) {
570  fr_tls_log_bio_t *lb;
571 
572  MEM(lb = talloc(NULL, fr_tls_log_bio_t));
573  *lb = (fr_tls_log_bio_t) {
574  .bio = BIO_new(tls_global_log_meth),
575  .type = type,
576  .lvl = lvl,
577  .file = file,
578  .line = line
579  };
580  MEM(lb->bio);
581  BIO_set_data(lb->bio, lb); /* So we can retrieve the fr_tls_lb_t in the callbacks */
582  fr_sbuff_init_talloc(lb, &lb->sbuff, &lb->tctx, 1024, 10 * 1024); /* start 1k, max 10k */
583  fr_atexit_thread_local(global_log_bio, _fr_tls_log_bio_free, lb);
584  fr_sbuff_marker(&lb->logged_m, &lb->sbuff);
585  return lb->bio;
586  }
587  fr_sbuff_reset_talloc(&request_log_bio->sbuff); /* Reset to initial size */
588  fr_sbuff_marker(&request_log_bio->logged_m, &request_log_bio->sbuff);
589  global_log_bio->type = type;
590  global_log_bio->lvl = lvl;
591  global_log_bio->file = file;
592  global_log_bio->line = line;
593 
594  return global_log_bio->bio;
595 }
596 
597 /** Initialise the BIO logging meths which are used to create thread local logging BIOs
598  *
599  */
600 int fr_tls_log_init(void)
601 {
602  /*
603  * As per the boringSSL documentation
604  *
605  * BIO_TYPE_START is the first user-allocated |BIO| type.
606  * No pre-defined type, flag bits aside, may exceed this
607  * value.
608  *
609  * The low byte here defines the BIO ID, and the high byte
610  * defines its capabilities.
611  */
612  tls_request_log_meth = BIO_meth_new(BIO_get_new_index() | BIO_TYPE_SOURCE_SINK, "fr_tls_request_log");
613  if (unlikely(!tls_request_log_meth)) return -1;
614 
615  BIO_meth_set_create(tls_request_log_meth, tls_log_request_bio_create_cb);
616  BIO_meth_set_write(tls_request_log_meth, tls_log_request_bio_write_cb);
617  BIO_meth_set_puts(tls_request_log_meth, tls_log_request_bio_puts_cb);
618  BIO_meth_set_destroy(tls_request_log_meth, tls_log_request_bio_free_cb);
619 
620  tls_global_log_meth = BIO_meth_new(BIO_get_new_index() | BIO_TYPE_SOURCE_SINK, "fr_tls_global_log");
621  if (unlikely(!tls_global_log_meth)) {
622  BIO_meth_free(tls_request_log_meth);
623  tls_request_log_meth = NULL;
624  return -1;
625  }
626 
627  BIO_meth_set_create(tls_global_log_meth, tls_log_global_bio_create_cb);
628  BIO_meth_set_write(tls_global_log_meth, tls_log_global_bio_write_cb);
629  BIO_meth_set_puts(tls_global_log_meth, tls_log_global_bio_puts_cb);
630  BIO_meth_set_destroy(tls_global_log_meth, tls_log_global_bio_free_cb);
631 
632  return 0;
633 }
634 
635 /** Free the global log method templates
636  *
637  */
638 void fr_tls_log_free(void)
639 {
640  /*
641  * These must be freed first else
642  * we get crashes in the OpenSSL
643  * code when we try to free them.
644  */
645  fr_assert_msg(atomic_load(&tls_request_log_ref) == 0, "request log BIO refs remaining %u", atomic_load(&tls_request_log_ref));
646  fr_assert_msg(atomic_load(&tls_global_log_ref) == 0, "global log BIO refs remaining %u", atomic_load(&tls_global_log_ref));
647 
648  if (tls_request_log_meth) {
649  BIO_meth_free(tls_request_log_meth);
650  tls_request_log_meth = NULL;
651  }
652 
653  if (tls_global_log_meth) {
654  BIO_meth_free(tls_global_log_meth);
655  tls_global_log_meth = NULL;
656  }
657 }
658 #endif /* WITH_TLS */
int const char * file
Definition: acutest.h:702
va_end(args)
log_entry msg
Definition: acutest.h:794
static int const char * fmt
Definition: acutest.h:573
int const char int line
Definition: acutest.h:702
va_start(args, fmt)
#define fr_atexit_thread_local(_name, _free, _uctx)
Definition: atexit.h:221
#define USES_APPLE_DEPRECATED_API
Definition: build.h:468
#define RCSID(id)
Definition: build.h:481
#define L(_str)
Helper for initialising arrays of string literals.
Definition: build.h:207
#define unlikely(_x)
Definition: build.h:379
#define NUM_ELEMENTS(_t)
Definition: build.h:335
#define fr_assert_msg(_x, _msg,...)
Calls panic_action ifndef NDEBUG, else logs error and causes the server to exit immediately with code...
Definition: debug.h:210
#define ERROR(fmt,...)
Definition: dhcpclient.c:41
static fr_slen_t err
Definition: dict.h:821
static fr_slen_t in
Definition: dict.h:821
void log_request(fr_log_type_t type, fr_log_lvl_t lvl, request_t *request, char const *file, int line, char const *fmt,...)
Marshal variadic log arguments into a va_list and pass to normal logging functions.
Definition: log.c:612
void log_request_perror(fr_log_type_t type, fr_log_lvl_t lvl, request_t *request, char const *file, int line, char const *fmt,...)
Drain any outstanding messages from the fr_strerror buffers.
Definition: log.c:679
void log_request_error(fr_log_type_t type, fr_log_lvl_t lvl, request_t *request, char const *file, int line, char const *fmt,...)
Marshal variadic log arguments into a va_list and pass to error logging functions.
Definition: log.c:647
#define PERROR(_fmt,...)
Definition: log.h:228
#define DEBUG_ENABLED2
True if global debug level 1-2 messages are enabled.
Definition: log.h:258
#define ROPTIONAL(_l_request, _l_global, _fmt,...)
Use different logging functions depending on whether request is NULL or not.
Definition: log.h:528
void(* log_request_func_t)(fr_log_type_t type, fr_log_lvl_t lvl, request_t *request, char const *file, int line, char const *fmt,...)
Function signature for log_request functions.
Definition: log.h:93
#define RPERROR(fmt,...)
Definition: log.h:302
talloc_free(reap)
int fr_debug_lvl
Definition: log.c:43
fr_log_t default_log
Definition: log.c:291
void fr_log(fr_log_t const *log, fr_log_type_t type, char const *file, int line, char const *fmt,...)
Send a server log message to its destination.
Definition: log.c:583
fr_log_lvl_t
Definition: log.h:67
@ L_DBG_LVL_OFF
No debug messages.
Definition: log.h:69
fr_log_type_t
Definition: log.h:54
@ L_ERR
Error message.
Definition: log.h:56
@ L_DBG_ERR
Error only displayed when debugging is enabled.
Definition: log.h:62
@ L_DBG_ERR_REQ
Less severe error only displayed when debugging is enabled.
Definition: log.h:64
unsigned int uint32_t
Definition: merged_model.c:33
char * fr_vasprintf(TALLOC_CTX *ctx, char const *fmt, va_list ap)
Definition: print.c:851
#define REDEBUG(fmt,...)
Definition: radclient.h:52
#define RDEBUG_ENABLED2()
Definition: radclient.h:50
#define RDEBUG2(fmt,...)
Definition: radclient.h:54
#define DEBUG2(fmt,...)
Definition: radclient.h:43
size_t fr_sbuff_shift(fr_sbuff_t *sbuff, size_t shift)
Shift the contents of the sbuff, returning the number of bytes we managed to shift.
Definition: sbuff.c:195
int fr_sbuff_reset_talloc(fr_sbuff_t *sbuff)
Reset a talloced buffer to its initial length, clearing any data stored.
Definition: sbuff.c:442
ssize_t fr_sbuff_in_bstrncpy(fr_sbuff_t *sbuff, char const *str, size_t len)
Copy bytes into the sbuff up to the first \0.
Definition: sbuff.c:1458
#define fr_sbuff_set(_dst, _src)
#define fr_sbuff_current(_sbuff_or_marker)
#define fr_sbuff_used(_sbuff_or_marker)
#define fr_sbuff_behind(_sbuff_or_marker)
Talloc sbuff extension structure.
Definition: sbuff.h:114
MEM(pair_append_request(&vp, attr_eap_aka_sim_identity) >=0)
fr_aka_sim_id_type_t type
#define _Atomic(T)
Definition: stdatomic.h:77
#define atomic_fetch_sub(object, operand)
Definition: stdatomic.h:339
#define atomic_load(object)
Definition: stdatomic.h:343
#define atomic_fetch_add(object, operand)
Definition: stdatomic.h:333
#define fr_table_str_by_value(_table, _number, _def)
Convert an integer to a string.
Definition: table.h:772
An element in an arbitrarily ordered array of name to num mappings.
Definition: table.h:57
void fr_perror(char const *fmt,...)
Print the current error to stderr with a prefix.
Definition: strerror.c:733
void fr_strerror_clear(void)
Clears all pending messages from the talloc pools.
Definition: strerror.c:577
#define fr_box_strvalue_len(_val, _len)
Definition: value.h:286