25 RCSID(
"$Id: cb3b6a5bcef930b0d59f712fe48354580f5b3df6 $")
29 #include <freeradius-devel/util/atexit.h>
37 struct fr_tls_bio_dbuff_s {
41 fr_dbuff_uctx_talloc_t tctx;
47 static BIO_METHOD *tls_bio_talloc_meth;
51 static _Thread_local fr_tls_bio_dbuff_t *tls_bio_talloc_agg;
59 static int _tls_bio_talloc_write_cb(BIO *bio,
char const *
in,
int len)
61 fr_tls_bio_dbuff_t *bd = talloc_get_type_abort(BIO_get_data(bio), fr_tls_bio_dbuff_t);
79 static int _tls_bio_talloc_puts_cb(BIO *bio,
char const *
in)
81 return _tls_bio_talloc_write_cb(bio,
in, strlen(
in));
91 static int _tls_bio_talloc_read_cb(BIO *bio,
char *buf,
int size)
93 fr_tls_bio_dbuff_t *bd = talloc_get_type_abort(BIO_get_data(bio), fr_tls_bio_dbuff_t);
100 if (to_copy > (
size_t)size) to_copy = (
size_t)size;
123 static int _tls_bio_talloc_gets_cb(BIO *bio,
char *buf,
int size)
125 fr_tls_bio_dbuff_t *bd = talloc_get_type_abort(BIO_get_data(bio), fr_tls_bio_dbuff_t);
152 if (to_copy >= (
size_t)size) to_copy = (
size_t)size - 1;
172 uint8_t *fr_tls_bio_dbuff_finalise(fr_tls_bio_dbuff_t *bd)
177 if (
unlikely(!bd->dbuff_in.buff))
return NULL;
181 buff = bd->dbuff_in.buff;
182 bd->dbuff_in.buff = NULL;
183 bd->dbuff_out.buff = NULL;
193 char *fr_tls_bio_dbuff_finalise_bstr(fr_tls_bio_dbuff_t *bd)
198 if (
unlikely(!bd->dbuff_in.buff))
return NULL;
203 buff = bd->dbuff_in.buff;
204 bd->dbuff_in.buff = NULL;
205 bd->dbuff_out.buff = NULL;
206 talloc_set_type(
buff,
char);
215 void fr_tls_bio_dbuff_reset(fr_tls_bio_dbuff_t *bd)
223 static int _fr_tls_bio_dbuff_free(fr_tls_bio_dbuff_t *bd)
234 fr_dbuff_t *fr_tls_bio_dbuff_out(fr_tls_bio_dbuff_t *bd)
236 return &bd->dbuff_out;
242 fr_dbuff_t *fr_tls_bio_dbuff_in(fr_tls_bio_dbuff_t *bd)
244 return &bd->dbuff_in;
262 BIO *fr_tls_bio_dbuff_alloc(fr_tls_bio_dbuff_t **
out, TALLOC_CTX *bio_ctx, TALLOC_CTX *buff_ctx,
263 size_t init,
size_t max,
bool free_buff)
265 fr_tls_bio_dbuff_t *bd;
267 MEM(bd = talloc_zero(bio_ctx, fr_tls_bio_dbuff_t));
268 MEM(bd->bio = BIO_new(tls_bio_talloc_meth));
269 BIO_set_data(bd->bio, bd);
276 bd->dbuff_out.is_const = 1;
277 bd->free_buff = free_buff;
279 talloc_set_destructor(bd, _fr_tls_bio_dbuff_free);
292 uint8_t *fr_tls_bio_dbuff_thread_local_finalise(
void)
294 return fr_tls_bio_dbuff_finalise(tls_bio_talloc_agg);
305 char *fr_tls_bio_dbuff_thread_local_finalise_bstr(
void)
307 return fr_tls_bio_dbuff_finalise_bstr(tls_bio_talloc_agg);
314 void fr_tls_bio_dbuff_thread_local_clear(
void)
316 fr_tls_bio_dbuff_t *bd = tls_bio_talloc_agg;
319 if (
unlikely(!bd->dbuff_in.buff))
return;
327 static int _fr_tls_bio_dbuff_thread_local_free(
void *bio_talloc_agg)
329 fr_tls_bio_dbuff_t *our_bio_talloc_agg = talloc_get_type_abort(bio_talloc_agg, fr_tls_bio_dbuff_t);
342 BIO *fr_tls_bio_dbuff_thread_local(TALLOC_CTX *ctx,
size_t init,
size_t max)
344 fr_tls_bio_dbuff_t *bd = tls_bio_talloc_agg;
347 fr_tls_bio_dbuff_alloc(&bd, NULL, ctx,
init, max,
true);
353 fr_assert_msg(!tls_bio_talloc_agg->dbuff_out.buff,
"BIO not finalised");
357 return tls_bio_talloc_agg->bio;
363 int fr_tls_bio_init(
void)
375 tls_bio_talloc_meth = BIO_meth_new(BIO_get_new_index() | BIO_TYPE_SOURCE_SINK,
"fr_tls_bio_dbuff_t");
376 if (
unlikely(!tls_bio_talloc_meth))
return -1;
383 BIO_meth_set_write(tls_bio_talloc_meth, _tls_bio_talloc_write_cb);
384 BIO_meth_set_puts(tls_bio_talloc_meth, _tls_bio_talloc_puts_cb);
385 BIO_meth_set_read(tls_bio_talloc_meth, _tls_bio_talloc_read_cb);
386 BIO_meth_set_gets(tls_bio_talloc_meth, _tls_bio_talloc_gets_cb);
394 void fr_tls_bio_free(
void)
396 if (tls_bio_talloc_meth) {
397 BIO_meth_free(tls_bio_talloc_meth);
398 tls_bio_talloc_meth = NULL;
#define fr_atexit_thread_local(_name, _free, _uctx)
#define USES_APPLE_DEPRECATED_API
int fr_dbuff_trim_talloc(fr_dbuff_t *dbuff, size_t len)
Trim a talloced dbuff to the minimum length required to represent the contained string.
size_t fr_dbuff_shift(fr_dbuff_t *dbuff, size_t shift)
Shift the contents of the dbuff, returning the number of bytes we managed to shift.
#define fr_dbuff_used(_dbuff_or_marker)
Return the number of bytes remaining between the start of the dbuff or marker and the current positio...
static void fr_dbuff_free_talloc(fr_dbuff_t *dbuff)
Free the talloc buffer associated with a dbuff.
#define fr_dbuff_current(_dbuff_or_marker)
Return the 'current' position of a dbuff or marker.
#define fr_dbuff_set_to_start(_dbuff_or_marker)
Reset the 'current' position of the dbuff or marker to the 'start' of the buffer.
#define fr_dbuff_out_memcpy(_out, _dbuff_or_marker, _outlen)
Copy exactly _outlen bytes from the dbuff.
#define fr_dbuff_remaining(_dbuff_or_marker)
Return the number of bytes remaining between the dbuff or marker and the end of the buffer.
#define fr_dbuff_in_bytes(_dbuff_or_marker,...)
Copy a byte sequence into a dbuff or marker.
static fr_dbuff_t * fr_dbuff_init_talloc(TALLOC_CTX *ctx, fr_dbuff_t *dbuff, fr_dbuff_uctx_talloc_t *tctx, size_t init, size_t max)
Initialise a special dbuff which automatically extends as additional data is written.
#define fr_dbuff_in_memcpy_partial(_out, _in, _inlen)
Copy at most _inlen bytes into the dbuff.
#define FR_DBUFF_BIND_END_ABS(_dbuff_or_marker)
Create a new dbuff pointing to the same underlying buffer.
#define fr_cond_assert(_x)
Calls panic_action ifndef NDEBUG, else logs error and evaluates to value of _x.
#define fr_assert_msg(_x, _msg,...)
Calls panic_action ifndef NDEBUG, else logs error and causes the server to exit immediately with code...
static char buff[sizeof("18446744073709551615")+3]
MEM(pair_append_request(&vp, attr_eap_aka_sim_identity) >=0)
init
Enter the EAP-IDENTITY state.
static size_t char ** out