char *verify_client_cert_cmd;
int require_client_cert;
- char *virtual_server; /* for processing certificates */
-
#ifdef HAVE_OPENSSL_OCSP_H
/*
* OCSP Configuration
offsetof(fr_tls_server_conf_t, make_cert_command), NULL, NULL},
{ "require_client_cert", PW_TYPE_BOOLEAN,
offsetof(fr_tls_server_conf_t, require_client_cert), NULL, NULL },
- { "virtual_server", PW_TYPE_STRING_PTR,
- offsetof(fr_tls_server_conf_t, virtual_server), NULL, NULL},
#if OPENSSL_VERSION_NUMBER >= 0x0090800fL
#ifndef OPENSSL_NO_ECDH
#include "eap_types.h"
+/* TLS configuration name */
+#define TLS_CONFIG_SECTION "tls-config"
+
/*
* EAP_DS contains all the received/sending information
* response = Received EAP packet
return 1;
}
+
+/*
+ * Parse TLS configuration
+ *
+ * If the option given by 'attr' is set, we find the config section
+ * of that name and use that for the TLS configuration. If not, we
+ * fall back to compatibility mode and read the TLS options from
+ * the 'tls' section.
+ */
+fr_tls_server_conf_t *eaptls_conf_parse(CONF_SECTION *cs, const char *attr)
+{
+ const char *tls_conf_name;
+ CONF_PAIR *cp;
+ CONF_SECTION *parent;
+ CONF_SECTION *tls_cs;
+ fr_tls_server_conf_t *tls_conf;
+
+ if (!cs)
+ return NULL;
+
+ rad_assert(attr != NULL);
+
+ parent = cf_item_parent(cf_sectiontoitem(cs));
+
+ cp = cf_pair_find(cs, attr);
+ if (cp) {
+ tls_conf_name = cf_pair_value(cp);
+
+ tls_cs = cf_section_sub_find_name2(parent, TLS_CONFIG_SECTION, tls_conf_name);
+
+ if (!tls_cs) {
+ radlog(L_ERR, "error: cannot find tls config '%s'", tls_conf_name);
+ return NULL;
+ }
+ } else {
+ /*
+ * If we can't find the section given by the 'attr', we
+ * fall-back to looking for the "tls" section, as in
+ * previous versions.
+ *
+ * We don't fall back if the 'attr' is specified, but we can't
+ * find the section - that is just a config error.
+ */
+ radlog(L_INFO, "debug: '%s' option missing, trying to use legacy configuration", attr);
+ tls_cs = cf_section_sub_find(parent, "tls");
+ }
+
+ if (!tls_cs)
+ return NULL;
+
+ tls_conf = tls_server_conf_parse(tls_cs);
+
+ if (!tls_conf)
+ return NULL;
+
+ /*
+ * The EAP RFC's say 1020, but we're less picky.
+ */
+ if (tls_conf->fragment_size < 100) {
+ radlog(L_ERR, "error: Fragment size is too small.");
+ return NULL;
+ }
+
+ /*
+ * The maximum size for a RADIUS packet is 4096,
+ * minus the header (20), Message-Authenticator (18),
+ * and State (18), etc. results in about 4000 bytes of data
+ * that can be devoted *solely* to EAP.
+ */
+ if (tls_conf->fragment_size > 4000) {
+ radlog(L_ERR, "error: Fragment size is too large.");
+ return NULL;
+ }
+
+ /*
+ * Account for the EAP header (4), and the EAP-TLS header
+ * (6), as per Section 4.2 of RFC 2716. What's left is
+ * the maximum amount of data we read from a TLS buffer.
+ */
+ tls_conf->fragment_size -= 10;
+
+ return tls_conf;
+}
+
int eaptls_start(EAP_DS *eap_ds, int peap);
int eaptls_compose(EAP_DS *eap_ds, EAPTLS_PACKET *reply);
+fr_tls_server_conf_t *eaptls_conf_parse(CONF_SECTION *cs, const char *key);
+
#endif /*_EAP_TLS_H*/
if (!auth_type) continue;
+ if (!strcmp(auth_type, TLS_CONFIG_SECTION)) continue;
+
eap_type = eaptype_name2type(auth_type);
if (eap_type < 0) {
radlog(L_ERR, "rlm_eap: Unknown EAP type %s",
*/
static int eaptls_detach(void *arg)
{
+ rlm_eap_tls_t *inst = (rlm_eap_tls_t *) arg;
+
+ free(inst);
+
return 0;
}
*/
static int eaptls_attach(CONF_SECTION *cs, void **instance)
{
- fr_tls_server_conf_t *inst;
+ rlm_eap_tls_t *inst;
+ fr_tls_server_conf_t *tls_conf;
/*
* Parse the config file & get all the configured values
*/
- inst = tls_server_conf_parse(cs);
+ inst = rad_malloc(sizeof(*inst));
if (!inst) {
- radlog(L_ERR, "rlm_eap_tls: Failed initializing SSL context");
+ radlog(L_ERR, "rlm_eap_tls: out of memory");
return -1;
}
+ memset(inst, 0, sizeof(*inst));
- /*
- * The EAP RFC's say 1020, but we're less picky.
- */
- if (inst->fragment_size < 100) {
- radlog(L_ERR, "rlm_eap_tls: Fragment size is too small.");
+ if (cf_section_parse(cs, inst, module_config) < 0) {
eaptls_detach(inst);
return -1;
}
- /*
- * The maximum size for a RADIUS packet is 4096,
- * minus the header (20), Message-Authenticator (18),
- * and State (18), etc. results in about 4000 bytes of data
- * that can be devoted *solely* to EAP.
- */
- if (inst->fragment_size > 4000) {
- radlog(L_ERR, "rlm_eap_tls: Fragment size is too large.");
+ tls_conf = eaptls_conf_parse(cs, "tls");
+
+ if (!tls_conf) {
+ radlog(L_ERR, "rlm_eap_tls: Failed initializing SSL context");
eaptls_detach(inst);
return -1;
}
- /*
- * Account for the EAP header (4), and the EAP-TLS header
- * (6), as per Section 4.2 of RFC 2716. What's left is
- * the maximum amount of data we read from a TLS buffer.
- */
- inst->fragment_size -= 10;
+ inst->tls_conf = tls_conf;
*instance = inst;
{
int status;
tls_session_t *ssn;
- fr_tls_server_conf_t *inst;
+ rlm_eap_tls_t *inst;
+ fr_tls_server_conf_t *tls_conf;
VALUE_PAIR *vp;
int client_cert = TRUE;
int verify_mode = 0;
REQUEST *request = handler->request;
inst = type_arg;
+ tls_conf = inst->tls_conf;
handler->tls = TRUE;
handler->finished = FALSE;
* in Opaque. So that we can use these data structures
* when we get the response
*/
- ssn = tls_new_session(inst, request, client_cert);
+ ssn = tls_new_session(tls_conf, request, client_cert);
if (!ssn) {
return 0;
}
* this index should be global.
*/
SSL_set_ex_data(ssn->ssl, FR_TLS_EX_INDEX_HANDLER, (void *)handler);
- SSL_set_ex_data(ssn->ssl, FR_TLS_EX_INDEX_CONF, (void *)inst);
+ SSL_set_ex_data(ssn->ssl, FR_TLS_EX_INDEX_CONF, (void *)tls_conf);
SSL_set_ex_data(ssn->ssl, FR_TLS_EX_INDEX_CERTS, (void *)&(handler->certs));
SSL_set_ex_data(ssn->ssl, FR_TLS_EX_INDEX_IDENTITY, (void *)&(handler->identity));
#ifdef HAVE_OPENSSL_OCSP_H
- SSL_set_ex_data(ssn->ssl, FR_TLS_EX_INDEX_STORE, (void *)inst->ocsp_store);
+ SSL_set_ex_data(ssn->ssl, FR_TLS_EX_INDEX_STORE, (void *)tls_conf->ocsp_store);
#endif
handler->opaque = ((void *)ssn);
/*
* Do authentication, by letting EAP-TLS do most of the work.
*/
-static int eaptls_authenticate(UNUSED void *arg, EAP_HANDLER *handler)
+static int eaptls_authenticate(void *type_arg, EAP_HANDLER *handler)
{
fr_tls_status_t status;
tls_session_t *tls_session = (tls_session_t *) handler->opaque;
REQUEST *request = handler->request;
- fr_tls_server_conf_t *conf;
+ rlm_eap_tls_t *inst;
+
+ inst = type_arg;
RDEBUG2("Authenticate");
* it accepts the certificates, too.
*/
case FR_TLS_SUCCESS:
- conf = SSL_get_ex_data(tls_session->ssl, FR_TLS_EX_INDEX_CONF);
- if (conf && conf->virtual_server) {
+ if (inst->virtual_server) {
VALUE_PAIR *vp;
REQUEST *fake;
PW_VIRTUAL_SERVER, 0)) != NULL) {
fake->server = vp->vp_strvalue;
} else {
- fake->server = conf->virtual_server;
+ fake->server = inst->virtual_server;
}
RDEBUG("Processing EAP-TLS Certificate check:");
#include "eap_tls.h"
+typedef struct rlm_eap_tls_t {
+ /*
+ * TLS configuration
+ */
+ char *tls_conf_name;
+ fr_tls_server_conf_t *tls_conf;
+
+ /*
+ * Virtual server for checking certificates
+ */
+ char *virtual_server;
+} rlm_eap_tls_t;
+
+static CONF_PARSER module_config[] = {
+ { "tls", PW_TYPE_STRING_PTR,
+ offsetof(rlm_eap_tls_t, tls_conf_name), NULL, NULL },
+
+ { "virtual_server", PW_TYPE_STRING_PTR,
+ offsetof(rlm_eap_tls_t, virtual_server), NULL, NULL },
+};
+
#endif /* _RLM_EAP_TLS_H */