]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Add initiate code to rlm_eap_ttls, remove dependency on rlm_eap_tls
authorMatthew Newton <mcn4@leicester.ac.uk>
Sat, 3 Mar 2012 13:29:27 +0000 (13:29 +0000)
committerAlan T. DeKok <aland@freeradius.org>
Sun, 4 Mar 2012 09:42:43 +0000 (10:42 +0100)
src/modules/rlm_eap/eap.c
src/modules/rlm_eap/types/rlm_eap_ttls/rlm_eap_ttls.c

index 80e92df1a9e8b5c0d22fc26db32dccf59885e2d8..01bccf392cce63bd1750ebbc4128932a723bb9b9 100644 (file)
@@ -266,18 +266,6 @@ int eaptype_select(rlm_eap_t *inst, EAP_HANDLER *handler)
                handler->stage = INITIATE;
                handler->eap_type = default_eap_type;
 
-               /*
-                *      Wild & crazy stuff!  For TTLS & PEAP, we
-                *      initiate a TLS session, and then pass that
-                *      session data to TTLS or PEAP for the
-                *      authenticate stage.
-                *
-                *      Handler->eap_type holds the TRUE type.
-                */
-               if (default_eap_type == PW_EAP_TTLS) {
-                       default_eap_type = PW_EAP_TLS;
-               }
-
                if ((default_eap_type == PW_EAP_TNC) &&
                    !handler->request->parent) {
                        RDEBUG2("ERROR: EAP-TNC must be run inside of a TLS method.");
index af02003b1f3df4ae3f7dc7a943deac2deca2264c..c8fff33b5b0aa45e11934602315fef14577d9711 100644 (file)
@@ -29,6 +29,12 @@ RCSID("$Id$")
 
 
 typedef struct rlm_eap_ttls_t {
+       /*
+        *      TLS configuration
+        */
+       char    *tls_conf_name;
+       fr_tls_server_conf_t *tls_conf;
+
        /*
         *      Default tunneled EAP type
         */
@@ -66,6 +72,9 @@ typedef struct rlm_eap_ttls_t {
 
 
 static CONF_PARSER module_config[] = {
+       { "tls", PW_TYPE_STRING_PTR,
+         offsetof(rlm_eap_ttls_t, tls_conf_name), NULL, NULL },
+
        { "default_eap_type", PW_TYPE_STRING_PTR,
          offsetof(rlm_eap_ttls_t, default_eap_type_name), NULL, "md5" },
 
@@ -91,7 +100,6 @@ static int eapttls_detach(void *arg)
 {
        rlm_eap_ttls_t *inst = (rlm_eap_ttls_t *) arg;
 
-
        free(inst);
 
        return 0;
@@ -102,7 +110,7 @@ static int eapttls_detach(void *arg)
  */
 static int eapttls_attach(CONF_SECTION *cs, void **instance)
 {
-       rlm_eap_ttls_t *inst;
+       rlm_eap_ttls_t          *inst;
 
        inst = malloc(sizeof(*inst));
        if (!inst) {
@@ -131,6 +139,18 @@ static int eapttls_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_ttls: Failed initializing SSL context");
+               eapttls_detach(inst);
+               return -1;
+       }
+
        *instance = inst;
        return 0;
 }
@@ -175,6 +195,66 @@ static ttls_tunnel_t *ttls_alloc(rlm_eap_ttls_t *inst)
 }
 
 
+/*
+ *     Send an initial eap-tls request to the peer, using the libeap functions.
+ */
+static int eapttls_initiate(void *type_arg, EAP_HANDLER *handler)
+{
+       int             status;
+       tls_session_t   *ssn;
+       rlm_eap_ttls_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 = "ttls keying material";
+
+       /*
+        *      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.
  */
@@ -316,16 +396,7 @@ static int eapttls_authenticate(void *arg, EAP_HANDLER *handler)
 EAP_TYPE rlm_eap_ttls = {
        "eap_ttls",
        eapttls_attach,                 /* attach */
-       /*
-        *      Note! There is NO eapttls_initate() function, as the
-        *      main EAP module takes care of calling
-        *      eaptls_initiate().
-        *
-        *      This is because TTLS is a protocol on top of TLS, so
-        *      before we need to do TTLS, we've got to initiate a TLS
-        *      session.
-        */
-       NULL,                           /* Start the initial request */
+       eapttls_initiate,               /* Start the initial request */
        NULL,                           /* authorization */
        eapttls_authenticate,           /* authentication */
        eapttls_detach                  /* detach */