26 RCSID(
"$Id: 896d93d9d792dbbd32e888dacfa5c94d5a52b13c $")
30 #define LOG_PREFIX "tls"
32 #include <freeradius-devel/internal/internal.h>
33 #include <freeradius-devel/server/pair.h>
34 #include <freeradius-devel/server/module_rlm.h>
35 #include <freeradius-devel/unlang/function.h>
36 #include <freeradius-devel/unlang/subrequest.h>
37 #include <freeradius-devel/unlang/interpret.h>
38 #include <freeradius-devel/util/debug.h>
47 #include <openssl/ssl.h>
48 #include <openssl/kdf.h>
56 uint8_t *fr_tls_cache_id(TALLOC_CTX *ctx, SSL_SESSION *sess)
61 id = SSL_SESSION_get_id(sess, &len);
74 static inline CC_HINT(always_inline,
nonnull)
80 id = SSL_SESSION_get_id(sess, &len);
93 #define SESSION_ID(_box, _sess) \
94 fr_value_box_t _box; \
95 if (unlikely(fr_tls_cache_id_to_box_shallow(&_box, _sess) < 0)) fr_value_box_init_null(&_box)
110 static inline CC_HINT(always_inline,
nonnull(2))
111 void tls_cache_session_id_to_vp(
request_t *request,
uint8_t const *session_id)
118 static inline CC_HINT(always_inline,
nonnull(2))
119 void _tls_cache_load_state_reset(
request_t *request, fr_tls_cache_t *cache,
char const *func)
121 if (cache->load.sess) {
123 SESSION_ID(sess_id, cache->load.sess);
127 SSL_SESSION_free(cache->load.sess);
128 cache->load.sess = NULL;
130 cache->load.state = FR_TLS_CACHE_LOAD_INIT;
132 #define tls_cache_load_state_reset(_request, _cache) _tls_cache_load_state_reset(_request, _cache, __FUNCTION__)
134 static inline CC_HINT(always_inline,
nonnull(2))
135 void _tls_cache_store_state_reset(
request_t *request, fr_tls_cache_t *cache,
char const *func)
137 if (cache->store.sess) {
139 SESSION_ID(sess_id, cache->store.sess);
142 SSL_SESSION_free(cache->store.sess);
143 cache->store.sess = NULL;
145 cache->store.state = FR_TLS_CACHE_STORE_INIT;
147 #define tls_cache_store_state_reset(_request, _cache) _tls_cache_store_state_reset(_request, _cache, __FUNCTION__)
149 static inline CC_HINT(always_inline)
150 void _tls_cache_clear_state_reset(
request_t *request, fr_tls_cache_t *cache,
char const *func)
152 if (cache->clear.id) {
156 TALLOC_FREE(cache->clear.id);
159 cache->clear.state = FR_TLS_CACHE_CLEAR_INIT;
161 #define tls_cache_clear_state_reset(_request, _cache) _tls_cache_clear_state_reset(_request, _cache, __FUNCTION__)
166 static int tls_cache_app_data_set(
request_t *request, SSL_SESSION *sess)
169 fr_dbuff_uctx_talloc_t tctx;
176 SESSION_ID(sess_id, sess);
178 RDEBUG2(
"Session ID %pV - Adding &session-state[*] to data", &sess_id);
200 SESSION_ID(sess_id, sess);
202 RPERROR(
"Session ID %pV - Failed serialising session-state list", &sess_id);
217 SESSION_ID(sess_id, sess);
219 fr_tls_log(request,
"Session ID %pV - Failed setting application data", &sess_id);
226 static int tls_cache_app_data_get(
request_t *request, SSL_SESSION *sess)
236 if (SSL_SESSION_get0_ticket_appdata(sess, (
void **)&
data, &data_len) != 1) {
237 SESSION_ID(sess_id, sess);
239 fr_tls_log(request,
"Session ID %pV - Failed retrieving application data", &sess_id);
257 SESSION_ID(sess_id, sess);
260 RPEDEBUG(
"Session-ID %pV - Failed decoding session-state", &sess_id);
266 SESSION_ID(sess_id, sess);
268 RDEBUG2(
"Session-ID %pV - Restoring &session-state[*]", &sess_id);
283 static void tls_cache_delete_request(SSL_SESSION *sess)
285 fr_tls_session_t *tls_session;
286 fr_tls_cache_t *tls_cache;
289 tls_session = talloc_get_type_abort(SSL_SESSION_get_ex_data(sess, FR_TLS_EX_INDEX_TLS_SESSION), fr_tls_session_t);
291 if (!tls_session->cache)
return;
293 request = fr_tls_session_request(tls_session->ssl);
294 tls_cache = tls_session->cache;
301 fr_assert(tls_cache->clear.state == FR_TLS_CACHE_CLEAR_INIT);
306 tls_cache->clear.id = fr_tls_cache_id(tls_cache, sess);
307 if (!tls_cache->clear.id) {
308 RWDEBUG(
"Error retrieving Session ID");
314 tls_cache->clear.state = FR_TLS_CACHE_CLEAR_REQUESTED;
323 if (tls_session->session == sess) tls_session->session = NULL;
338 if (tls_session->can_pause) ASYNC_pause_job();
346 fr_tls_session_t *tls_session = talloc_get_type_abort(uctx, fr_tls_session_t);
347 fr_tls_cache_t *tls_cache = tls_session->cache;
354 RWDEBUG(
"Failed acquiring session data");
356 tls_cache->load.state = FR_TLS_CACHE_LOAD_FAILED;
362 RWDEBUG(
"No cached session found");
367 p = (
unsigned char const **)&q;
369 sess = d2i_SSL_SESSION(NULL, p,
vp->vp_length);
371 fr_tls_log(request,
"Failed loading persisted session");
376 SESSION_ID(sess_id, sess);
378 RDEBUG3(
"Session ID %pV - Read %zu bytes of data. "
379 "Session de-serialized successfully", &sess_id,
vp->vp_length);
380 SSL_SESSION_print(fr_tls_request_log_bio(request,
L_DBG,
L_DBG_LVL_3), sess);
392 SSL_SESSION_set_ex_data(sess, FR_TLS_EX_INDEX_TLS_SESSION, fr_tls_session(tls_session->ssl));
394 tls_cache->load.state = FR_TLS_CACHE_LOAD_RETRIEVED;
395 tls_cache->load.sess = sess;
411 fr_tls_cache_t *tls_cache = tls_session->cache;
412 fr_tls_conf_t *
conf = fr_tls_session_conf(tls_session->ssl);
435 tls_cache_session_id_to_vp(child, tls_cache->load.id);
441 ua = fr_tls_call_push(child, tls_cache_load_result,
conf, tls_session);
444 tls_cache_load_state_reset(request, tls_cache);
456 fr_tls_session_t *tls_session = talloc_get_type_abort(uctx, fr_tls_session_t);
457 fr_tls_cache_t *tls_cache = tls_session->cache;
460 tls_cache_store_state_reset(request, tls_cache);
464 tls_cache->store.state = FR_TLS_CACHE_STORE_PERSISTED;
466 RWDEBUG(
"Failed storing session data");
467 tls_cache->store.state = FR_TLS_CACHE_STORE_INIT;
483 static inline CC_HINT(always_inline)
486 fr_tls_cache_t *tls_cache = tls_session->cache;
493 SSL_SESSION *sess = tls_session->cache->store.sess;
499 fr_assert(tls_cache->store.state == FR_TLS_CACHE_STORE_REQUESTED);
503 fr_tls_cache_id_to_box_shallow(&
id, sess);
505 RWDEBUG(
"Session ID %pV - Session has already expired, not storing", &
id);
541 len = i2d_SSL_SESSION(sess, NULL);
544 fr_tls_cache_id_to_box_shallow(&
id, sess);
547 fr_tls_strerror_printf(NULL);
548 RPWDEBUG(
"Session ID %pV - Serialisation failed, couldn't determine "
549 "required buffer length", &
id);
551 tls_cache_store_state_reset(request, tls_cache);
561 ret = i2d_SSL_SESSION(sess, &p);
564 fr_tls_cache_id_to_box_shallow(&
id, sess);
566 fr_tls_strerror_printf(NULL);
567 RPWDEBUG(
"Session ID %pV - Serialisation failed", &
id);
577 ua = fr_tls_call_push(child, tls_cache_store_result,
conf, tls_session);
578 if (ua < 0)
goto error;
588 fr_tls_session_t *tls_session = talloc_get_type_abort(uctx, fr_tls_session_t);
589 fr_tls_cache_t *tls_cache = tls_session->cache;
592 tls_cache_clear_state_reset(request, tls_cache);
601 RWDEBUG(
"Failed deleting session data - security may be compromised");
615 static inline CC_HINT(always_inline)
620 fr_tls_cache_t *tls_cache = tls_session->cache;
623 fr_assert(tls_cache->clear.state == FR_TLS_CACHE_CLEAR_REQUESTED);
640 tls_cache_session_id_to_vp(child, tls_cache->clear.id);
646 ua = fr_tls_call_push(child, tls_cache_clear_result,
conf, tls_session);
649 tls_cache_clear_state_reset(request, tls_cache);
666 fr_tls_cache_t *tls_cache = tls_session->cache;
667 fr_tls_conf_t *
conf = fr_tls_session_conf(tls_session->ssl);
674 if (tls_cache->load.state == FR_TLS_CACHE_LOAD_REQUESTED) {
675 return tls_cache_load_push(request, tls_session);
682 if (tls_cache->clear.state == FR_TLS_CACHE_CLEAR_REQUESTED) {
688 if (tls_cache->store.state == FR_TLS_CACHE_STORE_REQUESTED) {
692 id = SSL_SESSION_get_id(tls_cache->store.sess, &len);
693 if ((len == talloc_array_length(tls_cache->clear.id)) &&
694 (memcmp(tls_cache->clear.id,
id, len) == 0)) {
695 tls_cache_store_state_reset(request, tls_cache);
699 return tls_cache_clear_push(request,
conf, tls_session);
702 if (tls_cache->store.state == FR_TLS_CACHE_STORE_REQUESTED) {
703 return tls_cache_store_push(request,
conf, tls_session);
722 static int tls_cache_store_cb(SSL *ssl, SSL_SESSION *sess)
725 fr_tls_session_t *tls_session;
726 fr_tls_cache_t *tls_cache;
735 tls_session = fr_tls_session(ssl);
736 request = fr_tls_session_request(tls_session->ssl);
737 tls_cache = tls_session->cache;
745 id = SSL_SESSION_get_id(sess, &id_len);
751 tls_cache->store.sess = sess;
752 tls_cache->store.state = FR_TLS_CACHE_STORE_REQUESTED;
769 static SSL_SESSION *tls_cache_load_cb(SSL *ssl,
770 unsigned char const *key,
771 int key_len,
int *copy)
773 fr_tls_session_t *tls_session;
774 fr_tls_cache_t *tls_cache;
777 tls_session = fr_tls_session(ssl);
778 request = fr_tls_session_request(tls_session->ssl);
779 tls_cache = tls_session->cache;
791 if (!tls_cache || !tls_session->allow_session_resumption)
return NULL;
806 switch (tls_cache->load.state) {
807 case FR_TLS_CACHE_LOAD_INIT:
810 tls_cache->load.state = FR_TLS_CACHE_LOAD_REQUESTED;
821 if (
unlikely(!tls_session->can_pause)) {
824 "tls_session_async_handshake_cont must be in call stack", __FUNCTION__);
843 tls_cache_load_state_reset(request, tls_cache);
849 case FR_TLS_CACHE_LOAD_REQUESTED:
851 tls_cache->load.state = FR_TLS_CACHE_LOAD_FAILED;
854 case FR_TLS_CACHE_LOAD_RETRIEVED:
858 TALLOC_FREE(tls_cache->load.id);
860 RDEBUG3(
"Setting session data");
872 if (tls_cache_app_data_get(request, tls_cache->load.sess) < 0) {
873 REDEBUG(
"Denying session resumption via session-id");
879 tls_cache_delete_request(tls_cache->load.sess);
880 tls_cache_load_state_reset(request, tls_session->cache);
892 fr_tls_verify_cert_request(tls_session,
true);
894 if (
unlikely(!tls_session->can_pause))
goto cant_pause;
911 tls_cache_load_state_reset(request, tls_cache);
912 fr_tls_verify_cert_reset(tls_session);
921 if (!fr_tls_verify_cert_result(tls_session)) {
922 RDEBUG2(
"Certificate re-validation failed, denying session resumption via session-id");
925 sess = tls_cache->load.sess;
934 SESSION_ID(sess_id, tls_cache->load.sess);
936 RDEBUG3(
"Session ID %pV - Session ownership transferred to libssl", &sess_id);
938 tls_cache->load.sess = NULL;
944 case FR_TLS_CACHE_LOAD_FAILED:
945 RDEBUG3(
"Session data load failed");
949 TALLOC_FREE(tls_cache->load.id);
960 static void tls_cache_delete_cb(
UNUSED SSL_CTX *ctx, SSL_SESSION *sess)
968 if (!SSL_SESSION_get_ex_data(sess, FR_TLS_EX_INDEX_TLS_SESSION))
return;
969 tls_cache_delete_request(sess);
983 int fr_tls_cache_disable_cb(SSL *ssl,
int is_forward_secure)
987 fr_tls_session_t *tls_session;
990 tls_session = fr_tls_session(ssl);
991 request = fr_tls_session_request(tls_session->ssl);
1000 fr_tls_conf_t *
conf;
1002 conf = talloc_get_type_abort(SSL_get_ex_data(ssl, FR_TLS_EX_INDEX_CONF), fr_tls_conf_t);
1003 if (
conf->cache.require_extms && (SSL_get_extms_support(tls_session->ssl) == 0)) {
1004 RDEBUG2(
"Client does not support the Extended Master Secret extension, "
1005 "denying session resumption");
1009 if (
conf->cache.require_pfs && !is_forward_secure) {
1010 RDEBUG2(
"Cipher suite is not forward secure, denying session resumption");
1024 if (!tls_session->allow_session_resumption) {
1025 RDEBUG2(
"Session resumption not enabled for this TLS session, denying session resumption");
1030 if (
vp && (
vp->vp_uint32 == 0)) {
1031 RDEBUG2(
"&control.Allow-Session-Resumption == no, denying session resumption");
1033 SSL_CTX_remove_session(tls_session->ctx, tls_session->session);
1034 tls_session->allow_session_resumption =
false;
1038 RDEBUG2(
"Allowing future session-resumption");
1061 void fr_tls_cache_deny(
request_t *request, fr_tls_session_t *tls_session)
1063 fr_tls_cache_t *tls_cache = tls_session->cache;
1064 bool tmp_bind = !fr_tls_session_request_bound(tls_session->ssl);
1072 fr_tls_session_request_bind(tls_session->ssl, request);
1078 fr_assert(fr_tls_session_request(tls_session->ssl) == request);
1098 if (tls_session->session) SSL_CTX_remove_session(tls_session->ctx, tls_session->session);
1099 tls_session->allow_session_resumption =
false;
1104 tls_cache_store_state_reset(fr_tls_session_request(tls_session->ssl), tls_cache);
1109 if (tmp_bind) fr_tls_session_request_unbind(tls_session->ssl);
1114 static int _tls_cache_free(fr_tls_cache_t *tls_cache)
1116 tls_cache_load_state_reset(NULL, tls_cache);
1117 tls_cache_store_state_reset(NULL, tls_cache);
1128 void fr_tls_cache_session_alloc(fr_tls_session_t *tls_session)
1132 MEM(tls_session->cache = talloc_zero(tls_session, fr_tls_cache_t));
1133 talloc_set_destructor(tls_session->cache, _tls_cache_free);
1140 static inline CC_HINT(always_inline)
1141 void tls_cache_disable_stateless_resumption(SSL_CTX *ctx)
1143 long ctx_options = SSL_CTX_get_options(ctx);
1148 ctx_options |= SSL_OP_NO_TICKET;
1149 SSL_CTX_set_options(ctx, ctx_options);
1151 #if OPENSSL_VERSION_NUMBER >= 0x10101000L
1158 SSL_CTX_set_num_tickets(ctx, 0);
1166 static inline CC_HINT(always_inline)
1167 void tls_cache_disable_statefull_resumption(SSL_CTX *ctx)
1180 SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF);
1189 static int tls_cache_session_ticket_app_data_set(SSL *ssl,
void *arg)
1191 fr_tls_session_t *tls_session = fr_tls_session(ssl);
1192 fr_tls_cache_conf_t *tls_cache_conf = arg;
1202 if (!fr_tls_session_request_bound(ssl))
return 1;
1210 request = fr_tls_session_request(ssl);
1222 if (!tls_session->allow_session_resumption ||
1223 (!(tls_cache_conf->mode & FR_TLS_CACHE_STATELESS))) {
1224 REDEBUG(
"Generating session-tickets is not allowed");
1228 sess = SSL_get_session(ssl);
1230 REDEBUG(
"Failed retrieving session in session generation callback");
1234 if (tls_cache_app_data_set(request, sess) < 0)
return 0;
1243 static SSL_TICKET_RETURN tls_cache_session_ticket_app_data_get(SSL *ssl, SSL_SESSION *sess,
1244 UNUSED unsigned char const *keyname,
1245 UNUSED size_t keyname_len,
1246 SSL_TICKET_STATUS status,
1249 fr_tls_session_t *tls_session = fr_tls_session(ssl);
1250 fr_tls_conf_t *
conf = fr_tls_session_conf(tls_session->ssl);
1251 fr_tls_cache_conf_t *tls_cache_conf = arg;
1254 if (fr_tls_session_request_bound(ssl)) {
1255 request = fr_tls_session_request(ssl);
1259 if (!tls_session->allow_session_resumption ||
1260 (!(tls_cache_conf->mode & FR_TLS_CACHE_STATELESS))) {
1262 "denying session resumption via session-ticket");
1263 return SSL_TICKET_RETURN_IGNORE;
1267 case SSL_TICKET_EMPTY:
1268 case SSL_TICKET_NO_DECRYPT:
1269 case SSL_TICKET_FATAL_ERR_MALLOC:
1270 case SSL_TICKET_FATAL_ERR_OTHER:
1271 case SSL_TICKET_NONE:
1272 #ifdef STATIC_ANALYZER
1275 return SSL_TICKET_RETURN_IGNORE_RENEW;
1277 case SSL_TICKET_SUCCESS:
1278 if (!request)
return SSL_TICKET_RETURN_USE;
1281 case SSL_TICKET_SUCCESS_RENEW:
1282 if (!request)
return SSL_TICKET_RETURN_USE_RENEW;
1296 if (tls_cache_app_data_get(request, sess) < 0) {
1297 REDEBUG(
"Denying session resumption via session-ticket");
1298 return SSL_TICKET_RETURN_IGNORE_RENEW;
1301 if (
conf->virtual_server && tls_session->verify_client_cert) {
1302 RDEBUG2(
"Requesting certificate re-validation for session-ticket");
1311 fr_tls_verify_cert_request(tls_session,
true);
1319 if (
unlikely(!tls_session->can_pause)) {
1321 "tls_session_async_handshake_cont must be in call stack", __FUNCTION__);
1322 return SSL_TICKET_RETURN_IGNORE_RENEW;
1339 fr_tls_verify_cert_reset(tls_session);
1340 return SSL_TICKET_RETURN_ABORT;
1348 if (!fr_tls_verify_cert_result(tls_session)) {
1349 RDEBUG2(
"Certificate re-validation failed, denying session resumption via session-ticket");
1350 return SSL_TICKET_RETURN_IGNORE_RENEW;
1354 return (status == SSL_TICKET_SUCCESS_RENEW) ? SSL_TICKET_RETURN_USE_RENEW : SSL_TICKET_RETURN_USE;
1365 int fr_tls_cache_ctx_init(SSL_CTX *ctx, fr_tls_cache_conf_t
const *cache_conf)
1367 switch (cache_conf->mode) {
1368 case FR_TLS_CACHE_DISABLED:
1369 tls_cache_disable_stateless_resumption(ctx);
1370 tls_cache_disable_statefull_resumption(ctx);
1373 case FR_TLS_CACHE_AUTO:
1374 case FR_TLS_CACHE_STATEFUL:
1379 SSL_CTX_sess_set_new_cb(ctx, tls_cache_store_cb);
1380 SSL_CTX_sess_set_get_cb(ctx, tls_cache_load_cb);
1381 SSL_CTX_sess_set_remove_cb(ctx, tls_cache_delete_cb);
1389 SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_SERVER | SSL_SESS_CACHE_NO_INTERNAL);
1399 if (!(cache_conf->mode & FR_TLS_CACHE_STATELESS)) {
1400 tls_cache_disable_stateless_resumption(ctx);
1405 case FR_TLS_CACHE_STATELESS:
1409 EVP_PKEY_CTX *pkey_ctx = NULL;
1411 if (!(cache_conf->mode & FR_TLS_CACHE_STATEFUL)) tls_cache_disable_statefull_resumption(ctx);
1422 key_len = SSL_CTX_set_tlsext_ticket_keys(ctx, NULL, 0);
1424 if (
unlikely((pkey_ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, NULL)) == NULL)) {
1425 fr_tls_strerror_printf(NULL);
1426 PERROR(
"Failed initialising KDF");
1428 if (pkey_ctx) EVP_PKEY_CTX_free(pkey_ctx);
1431 if (
unlikely(EVP_PKEY_derive_init(pkey_ctx) != 1)) {
1432 fr_tls_strerror_printf(NULL);
1433 PERROR(
"Failed initialising KDF derivation ctx");
1436 if (
unlikely(EVP_PKEY_CTX_set_hkdf_md(pkey_ctx,
UNCONST(
struct evp_md_st *, EVP_sha256())) != 1)) {
1437 fr_tls_strerror_printf(NULL);
1438 PERROR(
"Failed setting KDF MD");
1441 if (
unlikely(EVP_PKEY_CTX_set1_hkdf_key(pkey_ctx,
1442 UNCONST(
unsigned char *, cache_conf->session_ticket_key),
1443 talloc_array_length(cache_conf->session_ticket_key)) != 1)) {
1444 fr_tls_strerror_printf(NULL);
1445 PERROR(
"Failed setting KDF key");
1448 if (
unlikely(EVP_PKEY_CTX_add1_hkdf_info(pkey_ctx,
1449 UNCONST(
unsigned char *,
"freeradius-session-ticket"),
1450 sizeof(
"freeradius-session-ticket") - 1) != 1)) {
1451 fr_tls_strerror_printf(NULL);
1452 PERROR(
"Failed setting KDF label");
1460 MEM(key_buff = talloc_array(NULL,
uint8_t, key_len));
1461 if (EVP_PKEY_derive(pkey_ctx, key_buff, &key_len) != 1) {
1462 fr_tls_strerror_printf(NULL);
1463 PERROR(
"Failed deriving session ticket key");
1468 EVP_PKEY_CTX_free(pkey_ctx);
1470 fr_assert(talloc_array_length(key_buff) == key_len);
1474 if (SSL_CTX_set_tlsext_ticket_keys(ctx,
1475 key_buff, key_len) != 1) {
1476 fr_tls_strerror_printf(NULL);
1477 PERROR(
"Failed setting session ticket keys");
1481 DEBUG3(
"Derived session-ticket-key:");
1489 if (
unlikely(SSL_CTX_set_session_ticket_cb(ctx,
1490 tls_cache_session_ticket_app_data_set,
1491 tls_cache_session_ticket_app_data_get,
1492 UNCONST(fr_tls_cache_conf_t *, cache_conf)) != 1)) {
1493 fr_tls_strerror_printf(NULL);
1494 PERROR(
"Failed setting session ticket callbacks");
1504 #if OPENSSL_VERSION_NUMBER >= 0x10101000L
1505 SSL_CTX_set_num_tickets(ctx, 1);
1511 SSL_CTX_set_not_resumable_session_callback(ctx, fr_tls_cache_disable_cb);
1512 SSL_CTX_set_quiet_shutdown(ctx, 1);
unlang_action_t
Returned by unlang_op_t calls, determine the next action of the interpreter.
@ UNLANG_ACTION_FAIL
Encountered an unexpected error.
@ UNLANG_ACTION_CALCULATE_RESULT
Calculate a new section rlm_rcode_t value.
#define UNCONST(_type, _ptr)
Remove const qualification from a pointer.
#define USES_APPLE_DEPRECATED_API
#define FALL_THROUGH
clang 10 doesn't recognised the FALL-THROUGH comment anymore
#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_len(_dbuff_or_marker)
The length of the underlying buffer.
#define fr_dbuff_init(_out, _start, _len_or_end)
Initialise an dbuff for encoding or decoding.
#define fr_dbuff_start(_dbuff_or_marker)
Return the 'start' position of a dbuff or marker.
#define fr_dbuff_remaining(_dbuff_or_marker)
Return the number of bytes remaining between the dbuff or marker and the end of the buffer.
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.
static void * fr_dcursor_current(fr_dcursor_t *cursor)
Return the item the cursor current points to.
#define fr_assert_msg(_x, _msg,...)
Calls panic_action ifndef NDEBUG, else logs error and causes the server to exit immediately with code...
fr_dict_attr_t const * fr_dict_root(fr_dict_t const *dict)
Return the root attribute of a dictionary.
bool unlang_request_is_cancelled(request_t const *request)
Return whether a request has been cancelled.
void log_request_pair_list(fr_log_lvl_t lvl, request_t *request, fr_pair_t const *parent, fr_pair_list_t const *vps, char const *prefix)
Print a fr_pair_list_t.
#define REXDENT()
Exdent (unindent) R* messages by one level.
#define ROPTIONAL(_l_request, _l_global, _fmt,...)
Use different logging functions depending on whether request is NULL or not.
#define RDEBUG_ENABLED3
True if request debug level 1-3 messages are enabled.
#define RHEXDUMP4(_data, _len, _fmt,...)
#define ROPTIONAL_ENABLED(_e_request, _e_global)
Check if a debug level is set by the request (if !NULL) or by the global log.
#define RPEDEBUG(fmt,...)
#define HEXDUMP3(_data, _len, _fmt,...)
#define RPWDEBUG(fmt,...)
#define DEBUG_ENABLED3
True if global debug level 1-3 messages are enabled.
#define RINDENT()
Indent R* messages by one level.
fr_value_box_t const * enum_tls_packet_type_store_session
HIDDEN fr_dict_attr_t const * attr_tls_packet_type
HIDDEN fr_dict_t const * dict_tls
fr_value_box_t const * enum_tls_packet_type_success
HIDDEN fr_dict_attr_t const * attr_tls_session_ttl
HIDDEN fr_dict_attr_t const * attr_tls_session_data
fr_value_box_t const * enum_tls_packet_type_load_session
HIDDEN fr_dict_attr_t const * attr_tls_session_id
fr_value_box_t const * enum_tls_packet_type_clear_session
fr_value_box_t const * enum_tls_packet_type_notfound
HIDDEN fr_dict_attr_t const * attr_allow_session_resumption
@ L_DBG_LVL_3
3rd highest priority debug messages (-xxx | -Xx).
@ L_DBG_LVL_2
2nd highest priority debug messages (-xx | -X).
@ L_DBG
Only displayed when debugging is enabled.
fr_pair_t * fr_pair_find_by_da(fr_pair_list_t const *list, fr_pair_t const *prev, fr_dict_attr_t const *da)
Find the first pair with a matching da.
int fr_pair_value_memdup_buffer(fr_pair_t *vp, uint8_t const *src, bool tainted)
Copy data from a talloced buffer into an "octets" data type.
void fr_pair_list_init(fr_pair_list_t *list)
Initialise a pair list header.
int fr_pair_value_memdup_buffer_shallow(fr_pair_t *vp, uint8_t const *src, bool tainted)
Assign a talloced buffer to a "octets" type value pair.
ssize_t fr_internal_decode_pair_dbuff(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *parent, fr_dbuff_t *dbuff, void *decode_ctx)
ssize_t fr_internal_encode_pair(fr_dbuff_t *dbuff, fr_dcursor_t *cursor, void *encode_ctx)
Encode a data structure into an internal attribute.
#define pair_update_request(_attr, _da)
#define RDEBUG_ENABLED2()
rlm_rcode_t
Return codes indicating the result of the module call.
#define pair_prepend_request(_attr, _da)
Allocate and prepend a fr_pair_t to the request list.
MEM(pair_append_request(&vp, attr_eap_aka_sim_identity) >=0)
#define fr_time()
Allow us to arbitrarily manipulate time.
Stores an attribute, a value and various bits of other data.
request_t * unlang_subrequest_alloc(request_t *parent, fr_dict_t const *namespace)
Allocate a subrequest to run through a virtual server at some point in the future.
uint8_t * talloc_typed_memdup(TALLOC_CTX *ctx, uint8_t const *in, size_t inlen)
Call talloc_memdup, setting the type on the new chunk correctly.
#define fr_time_lteq(_a, _b)
static int64_t fr_time_delta_to_sec(fr_time_delta_t delta)
static fr_time_t fr_time_from_sec(time_t when)
Convert a time_t (wallclock time) to a fr_time_t (internal time)
#define fr_time_sub(_a, _b)
Subtract one time from another.
void fr_pair_list_free(fr_pair_list_t *list)
Free memory used by a valuepair list.
void fr_pair_list_append(fr_pair_list_t *dst, fr_pair_list_t *src)
Appends a list of fr_pair_t from a temporary list to a destination list.
#define fr_pair_dcursor_init(_cursor, _list)
Initialises a special dcursor with callbacks that will maintain the attr sublists correctly.
void fr_value_box_memdup_shallow(fr_value_box_t *dst, fr_dict_attr_t const *enumv, uint8_t const *src, size_t len, bool tainted)
Assign a buffer to a box, but don't copy it.
#define fr_box_octets_buffer(_val)
static size_t char ** out
#define fr_box_octets(_val, _len)