From f4466a363fd43c98bf87de0b979d16d545655e12 Mon Sep 17 00:00:00 2001 From: Matthew Newton Date: Sat, 3 Mar 2012 13:20:17 +0000 Subject: [PATCH] Give rlm_eap_peap an initiate function and remove dependency on rlm_eap_tls --- src/modules/rlm_eap/eap.c | 3 +- .../rlm_eap/types/rlm_eap_peap/rlm_eap_peap.c | 112 ++++++++++++++++++--- 2 files changed, 101 insertions(+), 14 deletions(-) diff --git a/src/modules/rlm_eap/eap.c b/src/modules/rlm_eap/eap.c index 255daf8..80e92df 100644 --- a/src/modules/rlm_eap/eap.c +++ b/src/modules/rlm_eap/eap.c @@ -274,8 +274,7 @@ int eaptype_select(rlm_eap_t *inst, EAP_HANDLER *handler) * * Handler->eap_type holds the TRUE type. */ - if ((default_eap_type == PW_EAP_TTLS) || - (default_eap_type == PW_EAP_PEAP)) { + if (default_eap_type == PW_EAP_TTLS) { default_eap_type = PW_EAP_TLS; } diff --git a/src/modules/rlm_eap/types/rlm_eap_peap/rlm_eap_peap.c b/src/modules/rlm_eap/types/rlm_eap_peap/rlm_eap_peap.c index 34ef79b..72ebcdc 100644 --- a/src/modules/rlm_eap/types/rlm_eap_peap/rlm_eap_peap.c +++ b/src/modules/rlm_eap/types/rlm_eap_peap/rlm_eap_peap.c @@ -29,6 +29,12 @@ RCSID("$Id$") typedef struct rlm_eap_peap_t { /* + * TLS configuration + */ + char *tls_conf_name; + fr_tls_server_conf_t *tls_conf; + + /* * Default tunneled EAP type */ char *default_eap_type_name; @@ -68,6 +74,9 @@ typedef struct rlm_eap_peap_t { static CONF_PARSER module_config[] = { + { "tls", PW_TYPE_STRING_PTR, + offsetof(rlm_eap_peap_t, tls_conf_name), NULL, NULL }, + { "default_eap_type", PW_TYPE_STRING_PTR, offsetof(rlm_eap_peap_t, default_eap_type_name), NULL, "mschapv2" }, @@ -101,7 +110,6 @@ static int eappeap_detach(void *arg) { rlm_eap_peap_t *inst = (rlm_eap_peap_t *) arg; - free(inst); return 0; @@ -112,7 +120,7 @@ static int eappeap_detach(void *arg) */ static int eappeap_attach(CONF_SECTION *cs, void **instance) { - rlm_eap_peap_t *inst; + rlm_eap_peap_t *inst; inst = malloc(sizeof(*inst)); if (!inst) { @@ -141,6 +149,18 @@ static int eappeap_attach(CONF_SECTION *cs, void **instance) return -1; } + /* + * Read tls configuration, either from group given by 'tls' + * option, or from the eap-tls configuration. + */ + inst->tls_conf = eaptls_conf_parse(cs, "tls"); + + if (!inst->tls_conf) { + radlog(L_ERR, "rlm_eap_peap: Failed initializing SSL context"); + eappeap_detach(inst); + return -1; + } + *instance = inst; return 0; @@ -189,6 +209,83 @@ static peap_tunnel_t *peap_alloc(rlm_eap_peap_t *inst) } /* + * Send an initial eap-tls request to the peer, using the libeap functions. + */ +static int eappeap_initiate(void *type_arg, EAP_HANDLER *handler) +{ + int status; + tls_session_t *ssn; + rlm_eap_peap_t *inst; + VALUE_PAIR *vp; + int client_cert = FALSE; + REQUEST *request = handler->request; + + inst = type_arg; + + handler->tls = TRUE; + handler->finished = FALSE; + + /* + * Check if we need a client certificate. + * + * FIXME: This should be more configurable. + */ + vp = pairfind(handler->request->config_items, + PW_EAP_TLS_REQUIRE_CLIENT_CERT, 0); + if (vp) { + client_cert = vp->vp_integer; + } + + ssn = eaptls_session(inst->tls_conf, handler, client_cert); + if (!ssn) { + return 0; + } + + handler->opaque = ((void *)ssn); + handler->free_opaque = session_free; + + /* + * Set up type-specific information. + */ + ssn->prf_label = "client EAP encryption"; + + /* + * As it is a poorly designed protocol, PEAP uses + * bits in the TLS header to indicate PEAP + * version numbers. For now, we only support + * PEAP version 0, so it doesn't matter too much. + * However, if we support later versions of PEAP, + * we will need this flag to indicate which + * version we're currently dealing with. + */ + ssn->peap_flag = 0x00; + + /* + * PEAP version 0 requires 'include_length = no', + * so rather than hoping the user figures it out, + * we force it here. + */ + ssn->length_flag = 0; + + /* + * TLS session initialization is over. Now handle TLS + * related handshaking or application data. + */ + status = eaptls_start(handler->eap_ds, ssn->peap_flag); + RDEBUG2("Start returned %d", status); + if (status == 0) { + return 0; + } + + /* + * The next stage to process the packet. + */ + handler->stage = AUTHENTICATE; + + return 1; +} + +/* * Do authentication, by letting EAP-TLS do most of the work. */ static int eappeap_authenticate(void *arg, EAP_HANDLER *handler) @@ -335,16 +432,7 @@ static int eappeap_authenticate(void *arg, EAP_HANDLER *handler) EAP_TYPE rlm_eap_peap = { "eap_peap", eappeap_attach, /* attach */ - /* - * Note! There is NO eappeap_initate() function, as the - * main EAP module takes care of calling - * eaptls_initiate(). - * - * This is because PEAP is a protocol on top of TLS, so - * before we need to do PEAP, we've got to initiate a TLS - * session. - */ - NULL, /* Start the initial request */ + eappeap_initiate, /* Start the initial request */ NULL, /* authorization */ eappeap_authenticate, /* authentication */ eappeap_detach /* detach */ -- 2.1.4