From: Phil Mayers
Date: Thu, 20 Oct 2011 20:52:54 +0000 (+0100)
Subject: use the OpenSSL ex_data functions to allocate an index w/ free function to hold the...
X-Git-Tag: release_3_0_0_beta0~552^2
X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d3203fcf31d494266ef2885ade1f0c69c9ba5f13;p=thirdparty%2Ffreeradius-server.git
use the OpenSSL ex_data functions to allocate an index w/ free function to hold the cached VPs
---
diff --git a/src/include/tls.h b/src/include/tls.h
index 519ae71487d..d68599a47dc 100644
--- a/src/include/tls.h
+++ b/src/include/tls.h
@@ -322,7 +322,6 @@ void session_init(tls_session_t *ssn);
#define FR_TLS_EX_INDEX_REQUEST (2)
#define FR_TLS_EX_INDEX_CERTS (3)
#define FR_TLS_EX_INDEX_IDENTITY (4)
-#define FR_TLS_EX_INDEX_VPS (5)
#define FR_TLS_EX_INDEX_STORE (6)
/* configured values goes right here */
diff --git a/src/main/tls.c b/src/main/tls.c
index b1d1cf3e8b4..75faa2a1e1d 100644
--- a/src/main/tls.c
+++ b/src/main/tls.c
@@ -919,7 +919,6 @@ static void cbtls_remove_session(UNUSED SSL_CTX *ctx, SSL_SESSION *sess)
int i;
size_t size;
- VALUE_PAIR *vp;
char buffer[2 * MAX_SESSION_SIZE + 1];
size = sess->session_id_length;
@@ -929,15 +928,6 @@ static void cbtls_remove_session(UNUSED SSL_CTX *ctx, SSL_SESSION *sess)
DEBUG2(" SSL: Removing session %s from the cache", buffer);
- vp = SSL_SESSION_get_ex_data(sess, FR_TLS_EX_INDEX_VPS);
- if (vp) pairfree(&vp);
-
- for (i = 0; i <= FR_TLS_EX_INDEX_STORE; i++) {
- SSL_SESSION_get_ex_data(sess, i, NULL);
- }
-
- SSL_SESSION_free(sess);
-
return;
}
@@ -953,12 +943,12 @@ static int cbtls_new_session(UNUSED SSL *s, SSL_SESSION *sess)
DEBUG2(" SSL: adding session %s to cache", buffer);
- return 1;
+ return 0;
}
static SSL_SESSION *cbtls_get_session(UNUSED SSL *s,
unsigned char *data, int len,
- UNUSED int *copy)
+ int *copy)
{
size_t size;
char buffer[2 * MAX_SESSION_SIZE + 1];
@@ -971,6 +961,7 @@ static SSL_SESSION *cbtls_get_session(UNUSED SSL *s,
DEBUG2(" SSL: Client requested nonexistent cached session %s",
buffer);
+ *copy = 0;
return NULL;
}
@@ -1525,6 +1516,32 @@ static int set_ecdh_curve(SSL_CTX *ctx, const char *ecdh_curve)
#endif
#endif
+/* 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;
+
+/*
+ * DIE OPENSSL DIE DIE DIE
+ *
+ * What a palaver, just to free some data attached the
+ * session. We need to do this because the "remove" callback
+ * is called when refcount > 0 sometimes, if another thread
+ * is using the session
+ */
+static void sess_free_vps(UNUSED void *parent, void *data_ptr,
+ UNUSED CRYPTO_EX_DATA *ad, UNUSED int idx,
+ UNUSED long argl, UNUSED void *argp)
+{
+ VALUE_PAIR *vp = data_ptr;
+ if (!vp) return;
+
+ DEBUG2(" Freeing cached session VPs %p", vp);
+
+ pairfree(&vp);
+}
+
+
/*
* Create Global context SSL and use it in every new session
*
@@ -1741,6 +1758,8 @@ load_ca:
SSL_CTX_sess_set_remove_cb(ctx, cbtls_remove_session);
SSL_CTX_set_quiet_shutdown(ctx, 1);
+ if (FR_TLS_EX_INDEX_VPS < 0)
+ FR_TLS_EX_INDEX_VPS = SSL_SESSION_get_ex_new_index(0, NULL, NULL, NULL, sess_free_vps);
}
/*
@@ -2024,7 +2043,14 @@ int tls_success(tls_session_t *ssn, REQUEST *request)
* user data in the cache.
*/
} else if (!SSL_session_reused(ssn->ssl)) {
- RDEBUG2("Saving response in the cache");
+ size_t size;
+ char buffer[2 * MAX_SESSION_SIZE + 1];
+
+ size = ssn->ssl->session->session_id_length;
+ if (size > MAX_SESSION_SIZE) size = MAX_SESSION_SIZE;
+
+ fr_bin2hex(ssn->ssl->session->session_id, buffer, size);
+
vp = paircopy2(request->reply->vps, PW_USER_NAME, 0);
if (vp) pairadd(&vps, vp);
@@ -2036,10 +2062,11 @@ int tls_success(tls_session_t *ssn, REQUEST *request)
if (vp) pairadd(&vps, vp);
if (vps) {
+ RDEBUG2("Saving session %s vps %p in the cache", buffer, vps);
SSL_SESSION_set_ex_data(ssn->ssl->session,
FR_TLS_EX_INDEX_VPS, vps);
} else {
- RDEBUG2("WARNING: No information to cache: session caching will be disabled for this session.");
+ RDEBUG2("WARNING: No information to cache: session caching will be disabled for session %s", buffer);
SSL_CTX_remove_session(ssn->ctx,
ssn->ssl->session);
}
@@ -2049,15 +2076,23 @@ int tls_success(tls_session_t *ssn, REQUEST *request)
* reply.
*/
} else {
+ size_t size;
+ char buffer[2 * MAX_SESSION_SIZE + 1];
+
+ size = ssn->ssl->session->session_id_length;
+ if (size > MAX_SESSION_SIZE) size = MAX_SESSION_SIZE;
+
+ fr_bin2hex(ssn->ssl->session->session_id, buffer, size);
+
vp = SSL_SESSION_get_ex_data(ssn->ssl->session,
FR_TLS_EX_INDEX_VPS);
if (!vp) {
- RDEBUG("WARNING: No information in cached session!");
+ RDEBUG("WARNING: No information in cached session %s", buffer);
return -1;
} else {
- RDEBUG("Adding cached attributes to the reply:");
+ RDEBUG("Adding cached attributes for session %s vps %p to the reply:", buffer, vp);
debug_pair_list(vp);
pairadd(&request->reply->vps, paircopy(vp));