]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Move rlm_eap_tls TLS-specific config into user-specified section (given by new tls...
authorMatthew Newton <mcn4@leicester.ac.uk>
Sat, 3 Mar 2012 15:00:11 +0000 (15:00 +0000)
committerAlan T. DeKok <aland@freeradius.org>
Sun, 4 Mar 2012 09:35:58 +0000 (10:35 +0100)
src/include/tls.h
src/main/tls.c
src/modules/rlm_eap/eap.h
src/modules/rlm_eap/libeap/eap_tls.c
src/modules/rlm_eap/libeap/eap_tls.h
src/modules/rlm_eap/rlm_eap.c
src/modules/rlm_eap/types/rlm_eap_tls/rlm_eap_tls.c
src/modules/rlm_eap/types/rlm_eap_tls/rlm_eap_tls.h

index 68bbf37176a2328376cb10829aee911af8f5af04..22f27fbaab323d69cb3a3116e57135528ad42632 100644 (file)
@@ -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
index 041630853140d349152998b37f5d7d342e0e9859..0f397a2b979517f471a360d258e4810f086dc35d 100644 (file)
@@ -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
index 6d845ad77456fb31afe0fb33434422df7cb52f88..28282f10bd6e40c2d4430be9b67cdcec8e94d034 100644 (file)
@@ -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
index 2ff2e13204ddeb831ab8bf41ee8d6bc3435a5b75..0442f76251879203897cf12c29140c4fb2251d42 100644 (file)
@@ -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;
+}
+
index 6b434f054caeee26f881e8396a60ad110c75a141..1cc3a4b0bc70dc79a9dfd3b39a1eeb3a239ce8a7 100644 (file)
@@ -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*/
index 92a55fdbda27f071f1ca744dc5b3fed26fb994df..245cb0c7ecf71148648a9444dbb874fb9c01b0c2 100644 (file)
@@ -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",
index cdb057290d96511398e8d3a8640c1b53703d77f7..c84e223c66e81c90509bc627cc709e94c4ee6db4 100644 (file)
@@ -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:");
index a5af987a44415a32d9ed44e9f9797fbe99050596..757983c8af9c88f8c249890bc04b22c8b2fd208a 100644 (file)
@@ -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 */