From: Alan T. DeKok Date: Thu, 18 Jun 2015 15:53:34 +0000 (-0400) Subject: Restore cached VPs prior to EAP-TLS inner-tunnel method X-Git-Tag: release_3_0_9~122 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=093a4ac;p=thirdparty%2Ffreeradius-server.git Restore cached VPs prior to EAP-TLS inner-tunnel method --- diff --git a/src/include/tls-h b/src/include/tls-h index 6a539aba85..9fdc775fa0 100644 --- a/src/include/tls-h +++ b/src/include/tls-h @@ -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 { diff --git a/src/main/tls.c b/src/main/tls.c index 0fcdae2616..692651fa59 100644 --- a/src/main/tls.c +++ b/src/main/tls.c @@ -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 */ diff --git a/src/modules/rlm_eap/libeap/eap_tls.c b/src/modules/rlm_eap/libeap/eap_tls.c index e7b2f770d8..4e820530b2 100644 --- a/src/modules/rlm_eap/libeap/eap_tls.c +++ b/src/modules/rlm_eap/libeap/eap_tls.c @@ -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);