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