]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Split eap_tls initiate function, move session handling code into libeap/eaptls.c
authorMatthew Newton <mcn4@leicester.ac.uk>
Fri, 2 Mar 2012 21:30:07 +0000 (21:30 +0000)
committerAlan T. DeKok <aland@freeradius.org>
Sun, 4 Mar 2012 09:37:15 +0000 (10:37 +0100)
src/modules/rlm_eap/libeap/eap_tls.c
src/modules/rlm_eap/libeap/eap_tls.h
src/modules/rlm_eap/types/rlm_eap_tls/rlm_eap_tls.c

index 0442f76251879203897cf12c29140c4fb2251d42..255335ddad0bc88fbe7b37de899e45f0c3cbf05f 100644 (file)
@@ -80,6 +80,74 @@ void eaptls_free(EAPTLS_PACKET **eaptls_packet_ptr)
        *eaptls_packet_ptr = NULL;
 }
 
+/*
+ *     Send an initial eap-tls request to the peer.
+ *
+ *     Frame eap reply packet.
+ *     len = header + type + tls_typedata
+ *     tls_typedata = flags(Start (S) bit set, and no data)
+ *
+ *     Once having received the peer's Identity, the EAP server MUST
+ *     respond with an EAP-TLS/Start packet, which is an
+ *     EAP-Request packet with EAP-Type=EAP-TLS, the Start (S) bit
+ *     set, and no data.  The EAP-TLS conversation will then begin,
+ *     with the peer sending an EAP-Response packet with
+ *     EAP-Type = EAP-TLS.  The data field of that packet will
+ *     be the TLS data.
+ *
+ *     Fragment length is Framed-MTU - 4.
+ */
+tls_session_t *eaptls_session(fr_tls_server_conf_t *tls_conf, EAP_HANDLER *handler, int client_cert)
+{
+       tls_session_t   *ssn;
+       int             verify_mode = 0;
+       REQUEST         *request = handler->request;
+
+       handler->tls = TRUE;
+       handler->finished = FALSE;
+
+       /*
+        *      Every new session is started only from EAP-TLS-START.
+        *      Before Sending EAP-TLS-START, open a new SSL session.
+        *      Create all the required data structures & store them
+        *      in Opaque.  So that we can use these data structures
+        *      when we get the response
+        */
+       ssn = tls_new_session(tls_conf, request, client_cert);
+       if (!ssn) {
+               return NULL;
+       }
+
+       /*
+        *      Verify the peer certificate, if asked.
+        */
+       if (client_cert) {
+               RDEBUG2("Requiring client certificate");
+               verify_mode = SSL_VERIFY_PEER;
+               verify_mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
+               verify_mode |= SSL_VERIFY_CLIENT_ONCE;
+       }
+       SSL_set_verify(ssn->ssl, verify_mode, cbtls_verify);
+
+       /*
+        *      Create a structure for all the items required to be
+        *      verified for each client and set that as opaque data
+        *      structure.
+        *
+        *      NOTE: If we want to set each item sepearately then
+        *      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 *)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 *)tls_conf->ocsp_store);
+#endif
+
+       return ssn;
+}
+
 /*
    The S flag is set only within the EAP-TLS start message
    sent from the EAP server to the peer.
index 1cc3a4b0bc70dc79a9dfd3b39a1eeb3a239ce8a7..e46e8f0416e3f37baf8d6405356b9b4d6ebb3c90 100644 (file)
@@ -101,6 +101,7 @@ typedef struct tls_packet {
 /* EAP-TLS framework */
 EAPTLS_PACKET  *eaptls_alloc(void);
 void           eaptls_free(EAPTLS_PACKET **eaptls_packet_ptr);
+tls_session_t  *eaptls_session(fr_tls_server_conf_t *tls_conf, EAP_HANDLER *handler, int client_cert);
 int            eaptls_start(EAP_DS *eap_ds, int peap);
 int            eaptls_compose(EAP_DS *eap_ds, EAPTLS_PACKET *reply);
 
index c84e223c66e81c90509bc627cc709e94c4ee6db4..f7806dbe8a3a0a862e8905e219d1aa25993c5b2a 100644 (file)
@@ -96,137 +96,35 @@ static int eaptls_attach(CONF_SECTION *cs, void **instance)
 
 
 /*
- *     Send an initial eap-tls request to the peer.
- *
- *     Frame eap reply packet.
- *     len = header + type + tls_typedata
- *     tls_typedata = flags(Start (S) bit set, and no data)
- *
- *     Once having received the peer's Identity, the EAP server MUST
- *     respond with an EAP-TLS/Start packet, which is an
- *     EAP-Request packet with EAP-Type=EAP-TLS, the Start (S) bit
- *     set, and no data.  The EAP-TLS conversation will then begin,
- *     with the peer sending an EAP-Response packet with
- *     EAP-Type = EAP-TLS.  The data field of that packet will
- *     be the TLS data.
- *
- *     Fragment length is Framed-MTU - 4.
- *
- *     http://mail.frascone.com/pipermail/public/eap/2003-July/001426.html
+ *     Send an initial eap-tls request to the peer, using the libeap functions.
  */
 static int eaptls_initiate(void *type_arg, EAP_HANDLER *handler)
 {
        int             status;
        tls_session_t   *ssn;
        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;
 
        /*
-        *      If we're TTLS or PEAP, then do NOT require a client
-        *      certificate.
-        *
-        *      FIXME: This should be more configurable.
+        *      EAP-TLS always requires a client certificate.
         */
-       if (handler->eap_type != PW_EAP_TLS) {
-               vp = pairfind(handler->request->config_items,
-                             PW_EAP_TLS_REQUIRE_CLIENT_CERT, 0);
-               if (!vp) {
-                       client_cert = FALSE;
-               } else {
-                       client_cert = vp->vp_integer;
-               }
-       }
-
-       /*
-        *      Every new session is started only from EAP-TLS-START.
-        *      Before Sending EAP-TLS-START, open a new SSL session.
-        *      Create all the required data structures & store them
-        *      in Opaque.  So that we can use these data structures
-        *      when we get the response
-        */
-       ssn = tls_new_session(tls_conf, request, client_cert);
+       ssn = eaptls_session(inst->tls_conf, handler, TRUE);
        if (!ssn) {
                return 0;
        }
 
-       /*
-        *      Verify the peer certificate, if asked.
-        */
-       if (client_cert) {
-               RDEBUG2("Requiring client certificate");
-               verify_mode = SSL_VERIFY_PEER;
-               verify_mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
-               verify_mode |= SSL_VERIFY_CLIENT_ONCE;
-       }
-       SSL_set_verify(ssn->ssl, verify_mode, cbtls_verify);
-
-       /*
-        *      Create a structure for all the items required to be
-        *      verified for each client and set that as opaque data
-        *      structure.
-        *
-        *      NOTE: If we want to set each item sepearately then
-        *      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 *)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 *)tls_conf->ocsp_store);
-#endif
-
        handler->opaque = ((void *)ssn);
        handler->free_opaque = session_free;
 
        /*
         *      Set up type-specific information.
         */
-       switch (handler->eap_type) {
-       case PW_EAP_TLS:
-       default:
-               ssn->prf_label = "client EAP encryption";
-               break;
-
-       case PW_EAP_TTLS:
-               ssn->prf_label = "ttls keying material";
-               break;
-
-               /*
-                *      PEAP-specific breakage.
-                */
-       case PW_EAP_PEAP:
-               /*
-                *      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;
-
-               ssn->prf_label = "client EAP encryption";
-               break;
-       }
+       ssn->prf_label = "client EAP encryption";
 
        /*
         *      TLS session initialization is over.  Now handle TLS
@@ -234,8 +132,9 @@ static int eaptls_initiate(void *type_arg, EAP_HANDLER *handler)
         */
        status = eaptls_start(handler->eap_ds, ssn->peap_flag);
        RDEBUG2("Start returned %d", status);
-       if (status == 0)
+       if (status == 0) {
                return 0;
+       }
 
        /*
         *      The next stage to process the packet.