26RCSID(
"$Id: bbab59eed62c0b6fef2babebb2c17edd43fe575e $")
 
   30#define LOG_PREFIX "tls" 
   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> 
   66static BIO_METHOD       *tls_request_log_meth;
 
   70static BIO_METHOD       *tls_global_log_meth;
 
   84static _Thread_local    fr_tls_log_bio_t        *request_log_bio;
 
   88static _Thread_local    fr_tls_log_bio_t        *global_log_bio;
 
   99void _fr_tls_chain_log(
char const *
file, 
int line,
 
  101                       STACK_OF(X509) *chain, X509 *cert)
 
  107        _fr_tls_strerror_push_chain(
file, 
line, chain, cert);
 
  125void _fr_tls_chain_marker_log(
char const *
file, 
int line,
 
  127                              STACK_OF(X509) *chain, X509 *cert, X509 *marker)
 
  133        _fr_tls_strerror_push_chain_marker(
file, 
line, chain, cert, marker);
 
  149void _fr_tls_x509_objects_log(
char const *
file, 
int line,
 
  151                              STACK_OF(X509_OBJECT) *objects)
 
  155        _fr_tls_strerror_push_x509_objects(
file, 
line, objects);
 
  184int fr_tls_log_io_error(
request_t *request, 
int err, 
char const *
fmt, ...)
 
  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                   }
 
  200        static size_t ssl_io_error_table_len = 
NUM_ELEMENTS(ssl_io_error_table);
 
  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:
 
  239        case SSL_ERROR_SYSCALL:
 
  256                (void)fr_tls_strerror_vprintf(
fmt, ap);
 
  300        ret = fr_tls_strerror_vprintf(
msg, ap);
 
  311void fr_tls_log_clear(
void)
 
  313        while (ERR_get_error() != 0);
 
  319static int tls_log_request_bio_create_cb(BIO *bio)
 
  322        BIO_set_init(bio, 1);
 
  334static int tls_log_request_bio_write_cb(BIO *bio, 
char const *
in, 
int len)
 
  336        fr_tls_log_bio_t        *lb = talloc_get_type_abort(BIO_get_data(bio), fr_tls_log_bio_t);
 
  362                REDEBUG2(
"Failed copying %u bytes into TLS log aggregation buffer, " 
  363                         "needed %zu more bytes", len, (
size_t)(-(slen)));
 
  376                if (le == NULL) 
break;
 
  382                        func(lb->type, lb->lvl, request, __FILE__, __LINE__, 
"%pV",
 
  405static int tls_log_request_bio_puts_cb(BIO *bio, 
char const *
in)
 
  407        return tls_log_request_bio_write_cb(bio, 
in, strlen(
in));
 
  413static int tls_log_request_bio_free_cb(BIO *bio)
 
  416        BIO_set_init(bio, 0);
 
  423static int tls_log_global_bio_create_cb(BIO *bio)
 
  426        BIO_set_init(bio, 1);
 
  438static int tls_log_global_bio_write_cb(BIO *bio, 
char const *
in, 
int len)
 
  440        fr_tls_log_bio_t        *lb = talloc_get_type_abort(BIO_get_data(bio), fr_tls_log_bio_t);
 
  459                if (le == NULL) 
break;
 
  489static int tls_log_global_bio_puts_cb(BIO *bio, 
char const *
in)
 
  491        return tls_log_global_bio_write_cb(bio, 
in, strlen(
in));
 
  497static int tls_log_global_bio_free_cb(BIO *bio)
 
  500        BIO_set_init(bio, 0);
 
  507static int _fr_tls_log_bio_free(
void *log_bio)
 
  509        fr_tls_log_bio_t        *our_log_bio = talloc_get_type_abort(log_bio, fr_tls_log_bio_t);
 
  511        BIO_free(our_log_bio->bio);
 
  512        our_log_bio->bio = NULL;
 
  534                fr_tls_log_bio_t        *lb;
 
  536                MEM(lb = talloc(NULL, fr_tls_log_bio_t));
 
  537                *lb = (fr_tls_log_bio_t) {
 
  538                        .bio = BIO_new(tls_request_log_meth),
 
  546                BIO_set_data(lb->bio, lb);      
 
  547                fr_sbuff_init_talloc(lb, &lb->sbuff, &lb->tctx, 1024, 10 * 1024);       
 
  549                fr_sbuff_marker(&lb->logged_m, &lb->sbuff);
 
  553        fr_sbuff_marker(&request_log_bio->logged_m, &request_log_bio->sbuff);
 
  554        request_log_bio->request = request;
 
  555        request_log_bio->type = 
type;
 
  556        request_log_bio->lvl = lvl;
 
  557        request_log_bio->file = 
file;
 
  558        request_log_bio->line = 
line;
 
  560        return request_log_bio->bio;
 
  580                fr_tls_log_bio_t        *lb;
 
  582                MEM(lb = talloc(NULL, fr_tls_log_bio_t));
 
  583                *lb = (fr_tls_log_bio_t) {
 
  584                        .bio = BIO_new(tls_global_log_meth),
 
  591                BIO_set_data(lb->bio, lb);      
 
  592                fr_sbuff_init_talloc(lb, &lb->sbuff, &lb->tctx, 1024, 10 * 1024);       
 
  594                fr_sbuff_marker(&lb->logged_m, &lb->sbuff);
 
  598        fr_sbuff_marker(&request_log_bio->logged_m, &request_log_bio->sbuff);
 
  599        global_log_bio->type = 
type;
 
  600        global_log_bio->lvl = lvl;
 
  601        global_log_bio->file = 
file;
 
  602        global_log_bio->line = 
line;
 
  604        return global_log_bio->bio;
 
  610int fr_tls_log_init(
void)
 
  622        tls_request_log_meth = BIO_meth_new(BIO_get_new_index() | BIO_TYPE_SOURCE_SINK, 
"fr_tls_request_log");
 
  623        if (
unlikely(!tls_request_log_meth)) 
return -1;
 
  625        BIO_meth_set_create(tls_request_log_meth, tls_log_request_bio_create_cb);
 
  626        BIO_meth_set_write(tls_request_log_meth, tls_log_request_bio_write_cb);
 
  627        BIO_meth_set_puts(tls_request_log_meth, tls_log_request_bio_puts_cb);
 
  628        BIO_meth_set_destroy(tls_request_log_meth, tls_log_request_bio_free_cb);
 
  630        tls_global_log_meth = BIO_meth_new(BIO_get_new_index() | BIO_TYPE_SOURCE_SINK, 
"fr_tls_global_log");
 
  631        if (
unlikely(!tls_global_log_meth)) {
 
  632                BIO_meth_free(tls_request_log_meth);
 
  633                tls_request_log_meth = NULL;
 
  637        BIO_meth_set_create(tls_global_log_meth, tls_log_global_bio_create_cb);
 
  638        BIO_meth_set_write(tls_global_log_meth, tls_log_global_bio_write_cb);
 
  639        BIO_meth_set_puts(tls_global_log_meth, tls_log_global_bio_puts_cb);
 
  640        BIO_meth_set_destroy(tls_global_log_meth, tls_log_global_bio_free_cb);
 
  648void fr_tls_log_free(
void)
 
  658        if (tls_request_log_meth) {
 
  659                BIO_meth_free(tls_request_log_meth);
 
  660                tls_request_log_meth = NULL;
 
  663        if (tls_global_log_meth) {
 
  664                BIO_meth_free(tls_global_log_meth);
 
  665                tls_global_log_meth = NULL;
 
static int const char * fmt
#define fr_atexit_thread_local(_name, _free, _uctx)
#define USES_APPLE_DEPRECATED_API
#define L(_str)
Helper for initialising arrays of string literals.
#define fr_assert_msg(_x, _msg,...)
Calls panic_action ifndef NDEBUG, else logs error and causes the server to exit immediately with code...
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.
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.
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.
#define DEBUG_ENABLED2
True if global debug level 1-2 messages are enabled.
#define ROPTIONAL(_l_request, _l_global, _fmt,...)
Use different logging functions depending on whether request is NULL or not.
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.
#define REDEBUG2(fmt,...)
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.
@ L_DBG_LVL_OFF
No debug messages.
@ L_DBG_ERR
Error only displayed when debugging is enabled.
@ L_DBG_ERR_REQ
Less severe error only displayed when debugging is enabled.
char * fr_vasprintf(TALLOC_CTX *ctx, char const *fmt, va_list ap)
#define RDEBUG_ENABLED2()
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.
int fr_sbuff_reset_talloc(fr_sbuff_t *sbuff)
Reset a talloced buffer to its initial length, clearing any data stored.
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.
#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.
fr_aka_sim_id_type_t type
#define atomic_fetch_sub(object, operand)
#define atomic_load(object)
#define atomic_fetch_add(object, operand)
#define fr_table_str_by_value(_table, _number, _def)
Convert an integer to a string.
An element in an arbitrarily ordered array of name to num mappings.
void fr_perror(char const *fmt,...)
Print the current error to stderr with a prefix.
void fr_strerror_clear(void)
Clears all pending messages from the talloc pools.
#define fr_box_strvalue_len(_val, _len)