From: Nick Porter Date: Tue, 10 Dec 2024 11:55:52 +0000 (+0000) Subject: Add an optional "establish session" session X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e455495a9a5d686a32376ef387fbb278e7e10970;p=thirdparty%2Ffreeradius-server.git Add an optional "establish session" session Called after a TLS session is established, primarily intended for logging. --- diff --git a/share/dictionary/tls/dictionary.freeradius b/share/dictionary/tls/dictionary.freeradius index f38e6744f81..d4159385145 100644 --- a/share/dictionary/tls/dictionary.freeradius +++ b/share/dictionary/tls/dictionary.freeradius @@ -15,6 +15,7 @@ VALUE Packet-Type Store-Session 2 VALUE Packet-Type Clear-Session 3 VALUE Packet-Type Verify-Certificate 4 VALUE Packet-Type New-Session 5 +VALUE Packet-Type Establish-Session 6 # # We use response packet types instead of rcodes so that diff --git a/src/lib/server/cf_file.c b/src/lib/server/cf_file.c index 83d5d694257..10b5483361f 100644 --- a/src/lib/server/cf_file.c +++ b/src/lib/server/cf_file.c @@ -2694,6 +2694,7 @@ alloc_section: (strcmp(css->name1, "recv") == 0) || (strcmp(css->name1, "send") == 0) || (strcmp(css->name1, "store") == 0) || + (strcmp(css->name1, "establish") == 0) || (strcmp(css->name1, "verify") == 0)) { css->unlang = CF_UNLANG_ALLOW; css->allow_locals = true; diff --git a/src/lib/tls/attrs.h b/src/lib/tls/attrs.h index 325c818bded..46e8be1e445 100644 --- a/src/lib/tls/attrs.h +++ b/src/lib/tls/attrs.h @@ -72,6 +72,7 @@ extern fr_value_box_t const *enum_tls_packet_type_store_session; extern fr_value_box_t const *enum_tls_packet_type_clear_session; extern fr_value_box_t const *enum_tls_packet_type_verify_certificate; extern fr_value_box_t const *enum_tls_packet_type_new_session; +extern fr_value_box_t const *enum_tls_packet_type_establish_session; extern fr_value_box_t const *enum_tls_packet_type_success; extern fr_value_box_t const *enum_tls_packet_type_failure; diff --git a/src/lib/tls/base.c b/src/lib/tls/base.c index 48292f5faa6..ec77743a029 100644 --- a/src/lib/tls/base.c +++ b/src/lib/tls/base.c @@ -167,6 +167,7 @@ fr_value_box_t const *enum_tls_packet_type_store_session; fr_value_box_t const *enum_tls_packet_type_clear_session; fr_value_box_t const *enum_tls_packet_type_verify_certificate; fr_value_box_t const *enum_tls_packet_type_new_session; +fr_value_box_t const *enum_tls_packet_type_establish_session; /* * response types @@ -182,6 +183,7 @@ fr_dict_enum_autoload_t tls_dict_enum[] = { { .out = &enum_tls_packet_type_clear_session, .name = "Clear-Session", .attr = &attr_tls_packet_type }, { .out = &enum_tls_packet_type_verify_certificate, .name = "Verify-Certificate", .attr = &attr_tls_packet_type }, { .out = &enum_tls_packet_type_new_session, .name = "New-Session", .attr = &attr_tls_packet_type }, + { .out = &enum_tls_packet_type_establish_session, .name = "Establish-Session", .attr = &attr_tls_packet_type }, { .out = &enum_tls_packet_type_success, .name = "Success", .attr = &attr_tls_packet_type }, { .out = &enum_tls_packet_type_failure, .name = "Failure", .attr = &attr_tls_packet_type }, diff --git a/src/lib/tls/conf-h b/src/lib/tls/conf-h index 886329562a6..e54b47cea78 100644 --- a/src/lib/tls/conf-h +++ b/src/lib/tls/conf-h @@ -180,6 +180,7 @@ struct fr_tls_conf_s { bool verify_certificate; //!< Does the "verify certificate" section exist. bool new_session; //!< Does the "new session" section exist. + bool establish_session; //!< Does the "establish session" section exist. }; fr_tls_conf_t *fr_tls_conf_alloc(TALLOC_CTX *ctx); diff --git a/src/lib/tls/conf.c b/src/lib/tls/conf.c index a14411158ab..76c45b1808c 100644 --- a/src/lib/tls/conf.c +++ b/src/lib/tls/conf.c @@ -253,6 +253,7 @@ static int tls_virtual_server_cf_parse(TALLOC_CTX *ctx, void *out, void *parent, conf->verify_certificate = cf_section_find(conf->virtual_server, "verify", "certificate") ? true : false; conf->new_session = cf_section_find(conf->virtual_server, "new", "session") ? true : false; + conf->establish_session = cf_section_find(conf->virtual_server, "establish", "session") ? true : false; return 0; } diff --git a/src/lib/tls/session.c b/src/lib/tls/session.c index 1dc2b98def7..c4e8d02b139 100644 --- a/src/lib/tls/session.c +++ b/src/lib/tls/session.c @@ -1131,6 +1131,54 @@ static void fr_tls_session_alert_send(request_t *request, fr_tls_session_t *sess session_msg_log(request, session, session->dirty_out.data, session->dirty_out.used); } +/** Process the result of `establish session { ... }` + * + * As this is just a logging session, it's result doesn't affect the parent. + */ +static unlang_action_t tls_establish_session_result(UNUSED rlm_rcode_t *p_result, UNUSED int *priority, + UNUSED request_t *request, UNUSED void *uctx) +{ + return UNLANG_ACTION_CALCULATE_RESULT; +} + +/** Push an `establish session { ... }` call into the current request, using a subrequest + * + * @param[in] request The current request. + * @param[in] conf TLS configuration. + * @param[in] tls_session The current TLS session. + * @return + * - UNLANG_ACTION_PUSHED_CHILD on success. + * - UNLANG_ACTION_FAIL on failure. + */ +static inline CC_HINT(always_inline) +unlang_action_t tls_establish_session_push(request_t *request, fr_tls_conf_t *conf, fr_tls_session_t *tls_session) +{ + request_t *child; + fr_pair_t *vp; + unlang_action_t ua; + + MEM(child = unlang_subrequest_alloc(request, dict_tls)); + request = child; + + /* + * Setup the child request for reporting session + */ + MEM(pair_prepend_request(&vp, attr_tls_packet_type) >= 0); + vp->vp_uint32 = enum_tls_packet_type_establish_session->vb_uint32; + + /* + * Allocate a child, and set it up to call + * the TLS virtual server. + */ + ua = fr_tls_call_push(child, tls_establish_session_result, conf, tls_session); + if (ua < 0) { + talloc_free(child); + return UNLANG_ACTION_FAIL; + } + + return ua; +} + /** Finish off a handshake round, possibly adding attributes to the request * */ @@ -1270,6 +1318,10 @@ static unlang_action_t tls_session_async_handshake_done_round(UNUSED rlm_rcode_t tls_session->result = FR_TLS_RESULT_SUCCESS; fr_tls_session_request_unbind(tls_session->ssl); + if (SSL_is_init_finished(tls_session->ssl)) { + fr_tls_conf_t *conf = fr_tls_session_conf(tls_session->ssl); + if (conf->establish_session) return tls_establish_session_push(request, conf, tls_session); + } return UNLANG_ACTION_CALCULATE_RESULT; } diff --git a/src/process/tls/base.c b/src/process/tls/base.c index 599be6be729..ca2a30ac23c 100644 --- a/src/process/tls/base.c +++ b/src/process/tls/base.c @@ -47,6 +47,7 @@ typedef struct { CONF_SECTION *clear_session; CONF_SECTION *verify_certificate; CONF_SECTION *new_session; + CONF_SECTION *establish_session; } process_tls_sections_t; typedef struct { @@ -147,6 +148,23 @@ static fr_process_state_t const process_state[] = { .resume = resume_recv_no_send, .section_offset = PROCESS_CONF_OFFSET(new_session), }, + [FR_PACKET_TYPE_VALUE_ESTABLISH_SESSION] = { + .packet_type = { + [RLM_MODULE_OK] = FR_PACKET_TYPE_VALUE_SUCCESS, + [RLM_MODULE_UPDATED] = FR_PACKET_TYPE_VALUE_SUCCESS, + [RLM_MODULE_NOOP] = FR_PACKET_TYPE_VALUE_SUCCESS, + + [RLM_MODULE_REJECT] = FR_PACKET_TYPE_VALUE_FAILURE, + [RLM_MODULE_FAIL] = FR_PACKET_TYPE_VALUE_FAILURE, + [RLM_MODULE_INVALID] = FR_PACKET_TYPE_VALUE_FAILURE, + [RLM_MODULE_DISALLOW] = FR_PACKET_TYPE_VALUE_FAILURE, + [RLM_MODULE_NOTFOUND] = FR_PACKET_TYPE_VALUE_NOTFOUND, + }, + .rcode = RLM_MODULE_NOOP, + .recv = recv_generic, + .resume = resume_recv_no_send, + .section_offset = PROCESS_CONF_OFFSET(establish_session), + }, }; static unlang_action_t mod_process(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request) @@ -194,6 +212,11 @@ static const virtual_server_compile_t compile_list[] = { .actions = &mod_actions_authorize, .offset = PROCESS_CONF_OFFSET(new_session) }, + { + .section = SECTION_NAME("establish", "session"), + .actions = &mod_actions_authorize, + .offset = PROCESS_CONF_OFFSET(establish_session) + }, COMPILE_TERMINATOR };