Restore cached VPs prior to EAP-TLS inner-tunnel method
authorAlan T. DeKok <aland@freeradius.org>
Thu, 18 Jun 2015 15:53:34 +0000 (11:53 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Thu, 18 Jun 2015 15:53:34 +0000 (11:53 -0400)
src/include/tls-h
src/main/tls.c
src/modules/rlm_eap/libeap/eap_tls.c

index 6a539ab..9fdc775 100644 (file)
@@ -316,6 +316,7 @@ fr_tls_status_t tls_application_data(tls_session_t *ssn, REQUEST *request);
 #define FR_TLS_EX_INDEX_TALLOC  (16)
 
 extern int fr_tls_ex_index_certs;
+extern int fr_tls_ex_index_vps;
 
 /* configured values goes right here */
 struct fr_tls_server_conf_t {
index 0fcdae2..692651f 100644 (file)
@@ -103,7 +103,7 @@ FR_NAME_NUMBER const fr_tls_status_table[] = {
 /* index we use to store cached session VPs
  * needs to be dynamic so we can supply a "free" function
  */
-static int fr_tls_ex_index_vps = -1;
+int fr_tls_ex_index_vps = -1;
 int fr_tls_ex_index_certs = -1;
 
 /* Session */
@@ -2976,7 +2976,6 @@ int tls_success(tls_session_t *ssn, REQUEST *request)
         */
        } else {
                size_t size;
-               vp_cursor_t cursor;
                char buffer[2 * MAX_SESSION_SIZE + 1];
 
                size = ssn->ssl->session->session_id_length;
@@ -2984,40 +2983,10 @@ int tls_success(tls_session_t *ssn, REQUEST *request)
 
                fr_bin2hex(buffer, ssn->ssl->session->session_id, size);
 
-               vps = SSL_SESSION_get_ex_data(ssn->ssl->session, fr_tls_ex_index_vps);
-               if (!vps) {
-                       RWDEBUG("No information in cached session %s", buffer);
-                       return -1;
-               }
-
-               RDEBUG("Adding cached attributes from session %s", buffer);
-
                /*
-                *      The cbtls_get_session() function doesn't have
-                *      access to sock->certs or handler->certs, which
-                *      is where the certificates normally live.  So
-                *      the certs are all in the VPS list here, and
-                *      have to be manually extracted.
+                *      The "restore VPs from OpenSSL cache" code is
+                *      now in eaptls_process()
                 */
-               RINDENT();
-               for (vp = fr_cursor_init(&cursor, &vps);
-                    vp;
-                    vp = fr_cursor_next(&cursor)) {
-                       /*
-                        *      TLS-* attrs get added back to
-                        *      the request list.
-                        */
-                       if ((vp->da->vendor == 0) &&
-                           (vp->da->attr >= PW_TLS_CERT_SERIAL) &&
-                           (vp->da->attr <= PW_TLS_CLIENT_CERT_SUBJECT_ALT_NAME_UPN)) {
-                               rdebug_pair(L_DBG_LVL_2, request, vp, "request:");
-                               pairadd(&request->packet->vps, paircopyvp(request->packet, vp));
-                       } else {
-                               rdebug_pair(L_DBG_LVL_2, request, vp, "reply:");
-                               pairadd(&request->reply->vps, paircopyvp(request->reply, vp));
-                       }
-               }
-               REXDENT();
 
                if (conf->session_cache_path) {
                        /* "touch" the cached session/vp file */
index e7b2f77..4e82053 100644 (file)
@@ -899,6 +899,62 @@ fr_tls_status_t eaptls_process(eap_handler_t *handler)
         *      Continue the handshake.
         */
        status = eaptls_operation(status, handler);
+       if (status == FR_TLS_SUCCESS) {
+#define MAX_SESSION_SIZE (256)
+               size_t size;
+               VALUE_PAIR *vps;
+               char buffer[2 * MAX_SESSION_SIZE + 1];
+               /*
+                *      Restore the cached VPs before processing the
+                *      application data.
+                */
+               size = tls_session->ssl->session->session_id_length;
+               if (size > MAX_SESSION_SIZE) size = MAX_SESSION_SIZE;
+
+               fr_bin2hex(buffer, tls_session->ssl->session->session_id, size);
+
+               vps = SSL_SESSION_get_ex_data(tls_session->ssl->session, fr_tls_ex_index_vps);
+               if (!vps) {
+                       RWDEBUG("No information in cached session %s", buffer);
+               } else {
+                       vp_cursor_t cursor;
+                       VALUE_PAIR *vp;
+
+                       RDEBUG("Adding cached attributes from session %s", buffer);
+
+                       /*
+                        *      The cbtls_get_session() function doesn't have
+                        *      access to sock->certs or handler->certs, which
+                        *      is where the certificates normally live.  So
+                        *      the certs are all in the VPS list here, and
+                        *      have to be manually extracted.
+                        */
+                       RINDENT();
+                       for (vp = fr_cursor_init(&cursor, &vps);
+                            vp;
+                            vp = fr_cursor_next(&cursor)) {
+                               /*
+                                *      TLS-* attrs get added back to
+                                *      the request list.
+                                */
+                               if ((vp->da->vendor == 0) &&
+                                   (vp->da->attr >= PW_TLS_CERT_SERIAL) &&
+                                   (vp->da->attr <= PW_TLS_CLIENT_CERT_SUBJECT_ALT_NAME_UPN)) {
+                                       /*
+                                        *      Certs already exist.  Don't re-add them.
+                                        */
+                                       if (!handler->certs) {
+                                               rdebug_pair(L_DBG_LVL_2, request, vp, "request:");
+                                               pairadd(&request->packet->vps, paircopyvp(request->packet, vp));
+                                       }
+                               } else {
+                                       rdebug_pair(L_DBG_LVL_2, request, vp, "reply:");
+                                       pairadd(&request->reply->vps, paircopyvp(request->reply, vp));
+                               }
+                       }
+                       REXDENT();
+               }
+       }
 
  done:
        SSL_set_ex_data(tls_session->ssl, FR_TLS_EX_INDEX_REQUEST, NULL);