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
(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;
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;
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
{ .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 },
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);
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;
}
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
*
*/
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;
}
CONF_SECTION *clear_session;
CONF_SECTION *verify_certificate;
CONF_SECTION *new_session;
+ CONF_SECTION *establish_session;
} process_tls_sections_t;
typedef struct {
.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)
.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
};