From: Matthew Newton Date: Sat, 3 Mar 2012 15:00:11 +0000 (+0000) Subject: Move rlm_eap_tls TLS-specific config into user-specified section (given by new tls... X-Git-Tag: release_3_0_0_beta0~273 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=430244191ef50278aadcab8a32530ee69c99ed64;p=thirdparty%2Ffreeradius-server.git Move rlm_eap_tls TLS-specific config into user-specified section (given by new tls= option) --- diff --git a/src/include/tls.h b/src/include/tls.h index 68bbf37176a..22f27fbaab3 100644 --- a/src/include/tls.h +++ b/src/include/tls.h @@ -366,8 +366,6 @@ struct fr_tls_server_conf_t { char *verify_client_cert_cmd; int require_client_cert; - char *virtual_server; /* for processing certificates */ - #ifdef HAVE_OPENSSL_OCSP_H /* * OCSP Configuration diff --git a/src/main/tls.c b/src/main/tls.c index 04163085314..0f397a2b979 100644 --- a/src/main/tls.c +++ b/src/main/tls.c @@ -835,8 +835,6 @@ static CONF_PARSER tls_server_config[] = { 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 diff --git a/src/modules/rlm_eap/eap.h b/src/modules/rlm_eap/eap.h index 6d845ad7745..28282f10bd6 100644 --- a/src/modules/rlm_eap/eap.h +++ b/src/modules/rlm_eap/eap.h @@ -33,6 +33,9 @@ RCSIDH(eap_h, "$Id$") #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 diff --git a/src/modules/rlm_eap/libeap/eap_tls.c b/src/modules/rlm_eap/libeap/eap_tls.c index 2ff2e13204d..0442f762518 100644 --- a/src/modules/rlm_eap/libeap/eap_tls.c +++ b/src/modules/rlm_eap/libeap/eap_tls.c @@ -877,3 +877,87 @@ int eaptls_compose(EAP_DS *eap_ds, EAPTLS_PACKET *reply) 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; +} + diff --git a/src/modules/rlm_eap/libeap/eap_tls.h b/src/modules/rlm_eap/libeap/eap_tls.h index 6b434f054ca..1cc3a4b0bc7 100644 --- a/src/modules/rlm_eap/libeap/eap_tls.h +++ b/src/modules/rlm_eap/libeap/eap_tls.h @@ -104,4 +104,6 @@ void eaptls_free(EAPTLS_PACKET **eaptls_packet_ptr); 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*/ diff --git a/src/modules/rlm_eap/rlm_eap.c b/src/modules/rlm_eap/rlm_eap.c index 92a55fdbda2..245cb0c7ecf 100644 --- a/src/modules/rlm_eap/rlm_eap.c +++ b/src/modules/rlm_eap/rlm_eap.c @@ -160,6 +160,8 @@ static int eap_instantiate(CONF_SECTION *cs, void **instance) 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", diff --git a/src/modules/rlm_eap/types/rlm_eap_tls/rlm_eap_tls.c b/src/modules/rlm_eap/types/rlm_eap_tls/rlm_eap_tls.c index cdb057290d9..c84e223c66e 100644 --- a/src/modules/rlm_eap/types/rlm_eap_tls/rlm_eap_tls.c +++ b/src/modules/rlm_eap/types/rlm_eap_tls/rlm_eap_tls.c @@ -48,6 +48,10 @@ RCSID("$Id$") */ static int eaptls_detach(void *arg) { + rlm_eap_tls_t *inst = (rlm_eap_tls_t *) arg; + + free(inst); + return 0; } @@ -57,44 +61,33 @@ static int eaptls_detach(void *arg) */ 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; @@ -125,13 +118,15 @@ static int eaptls_initiate(void *type_arg, EAP_HANDLER *handler) { 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; @@ -159,7 +154,7 @@ static int eaptls_initiate(void *type_arg, EAP_HANDLER *handler) * 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; } @@ -184,11 +179,11 @@ static int eaptls_initiate(void *type_arg, EAP_HANDLER *handler) * 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); @@ -253,12 +248,14 @@ static int eaptls_initiate(void *type_arg, EAP_HANDLER *handler) /* * 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"); @@ -273,8 +270,7 @@ static int eaptls_authenticate(UNUSED void *arg, EAP_HANDLER *handler) * 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; @@ -289,7 +285,7 @@ static int eaptls_authenticate(UNUSED void *arg, EAP_HANDLER *handler) 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:"); diff --git a/src/modules/rlm_eap/types/rlm_eap_tls/rlm_eap_tls.h b/src/modules/rlm_eap/types/rlm_eap_tls/rlm_eap_tls.h index a5af987a444..757983c8af9 100644 --- a/src/modules/rlm_eap/types/rlm_eap_tls/rlm_eap_tls.h +++ b/src/modules/rlm_eap/types/rlm_eap_tls/rlm_eap_tls.h @@ -32,4 +32,25 @@ RCSIDH(rlm_eap_tls_h, "$Id$") #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 */