first implementation of ssl sessions store in the shared cache

This commit is contained in:
Roberto De Ioris
2012-11-25 10:46:58 +01:00
parent 598250d469
commit 4eb174e9cb
5 changed files with 94 additions and 5 deletions
-3
View File
@@ -4,9 +4,6 @@ extern struct uwsgi_server uwsgi;
void uwsgi_init_cache() {
if (!uwsgi.cache_blocksize)
uwsgi.cache_blocksize = UMAX16;
uwsgi.cache_hashtable = (uint64_t *) mmap(NULL, sizeof(uint64_t) * UMAX16, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
if (!uwsgi.cache_hashtable) {
uwsgi_error("mmap()");
+2
View File
@@ -14,6 +14,7 @@ void uwsgi_init_default() {
uwsgi.signal_socket = -1;
uwsgi.my_signal_socket = -1;
uwsgi.cache_server_fd = -1;
uwsgi.cache_blocksize = UMAX16;
uwsgi.stats_fd = -1;
uwsgi.stats_pusher_default_freq = 3;
@@ -76,6 +77,7 @@ void uwsgi_init_default() {
#ifdef UWSGI_SSL
// 1 day of tolerance
uwsgi.subscriptions_sign_check_tolerance = 3600 * 24;
uwsgi.ssl_sessions_timeout = 300;
#endif
#ifdef UWSGI_ALARM
+86 -2
View File
@@ -4294,6 +4294,59 @@ int uwsgi_ssl_verify_callback(int ok, X509_STORE_CTX * x509_store) {
return 1;
}
int uwsgi_ssl_session_new_cb(SSL *ssl, SSL_SESSION *sess) {
char session_blob[4096];
int len = i2d_SSL_SESSION(sess, NULL);
if (len > 4096) {
if (uwsgi.ssl_verbose) {
uwsgi_log("[uwsgi-ssl] unable to store session of size %d\n", len);
}
return 0;
}
unsigned char *p = (unsigned char *) session_blob;
i2d_SSL_SESSION(sess, &p);
// ok let's write the value to the cache
uwsgi_wlock(uwsgi.cache_lock);
if (uwsgi_cache_set((char *) sess->session_id, sess->session_id_length, session_blob, len, uwsgi.ssl_sessions_timeout, 0)) {
if (uwsgi.ssl_verbose) {
uwsgi_log("[uwsgi-ssl] unable to store session of size %d in the cache\n", len);
}
}
uwsgi_rwunlock(uwsgi.cache_lock);
return 0;
}
SSL_SESSION *uwsgi_ssl_session_get_cb(SSL *ssl, unsigned char *key, int keylen, int *copy) {
uint64_t valsize = 0;
*copy = 0;
uwsgi_rlock(uwsgi.cache_lock);
char *value = uwsgi_cache_get((char *)key, keylen, &valsize);
if (!value) {
uwsgi_rwunlock(uwsgi.cache_lock);
if (uwsgi.ssl_verbose) {
uwsgi_log("[uwsgi-ssl] cache miss\n");
}
return NULL;
}
SSL_SESSION *sess = d2i_SSL_SESSION(NULL, (const unsigned char **)&value, valsize);
uwsgi_rwunlock(uwsgi.cache_lock);
return sess;
}
void uwsgi_ssl_session_remove_cb(SSL_CTX *ctx, SSL_SESSION *sess) {
uwsgi_wlock(uwsgi.cache_lock);
if (uwsgi_cache_del((char *) sess->session_id, sess->session_id_length, 0)) {
if (uwsgi.ssl_verbose) {
uwsgi_log("[uwsgi-ssl] error removing cache item\n");
}
}
uwsgi_rwunlock(uwsgi.cache_lock);
}
SSL_CTX *uwsgi_ssl_new_server_context(char *name, char *crt, char *key, char *ciphers, char *client_ca) {
SSL_CTX *ctx = SSL_CTX_new(SSLv23_server_method());
@@ -4310,7 +4363,6 @@ SSL_CTX *uwsgi_ssl_new_server_context(char *name, char *crt, char *key, char *ci
#ifdef SSL_OP_NO_COMPRESSION
ssloptions |= SSL_OP_NO_COMPRESSION;
#endif
SSL_CTX_set_options(ctx, ssloptions);
// release/reuse buffers as soon as possibile
#ifdef SSL_MODE_RELEASE_BUFFERS
@@ -4354,7 +4406,7 @@ SSL_CTX *uwsgi_ssl_new_server_context(char *name, char *crt, char *key, char *ci
exit(1);
}
SSL_CTX_set_options(ctx, SSL_OP_CIPHER_SERVER_PREFERENCE);
ssloptions |= SSL_OP_CIPHER_SERVER_PREFERENCE;
}
// set session context (if possibile), this is required for client certificate authentication
@@ -4391,6 +4443,35 @@ SSL_CTX *uwsgi_ssl_new_server_context(char *name, char *crt, char *key, char *ci
// disable session caching by default
SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF);
if (uwsgi.ssl_sessions_use_cache) {
if (!uwsgi.cache_max_items) {
uwsgi_log("you have to enable uWSGI cache to use it as SSL session store !!!\n");
exit(1);
}
if (uwsgi.cache_blocksize < 4096) {
uwsgi_log("cache blocksize for SSL session store must be at least 4096 bytes\n");
exit(1);
}
SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_SERVER|
SSL_SESS_CACHE_NO_INTERNAL|
SSL_SESS_CACHE_NO_AUTO_CLEAR);
ssloptions |= SSL_OP_NO_TICKET;
// just for fun
SSL_CTX_sess_set_cache_size(ctx, 0);
// set the callback for ssl sessions
SSL_CTX_sess_set_new_cb(ctx, uwsgi_ssl_session_new_cb);
SSL_CTX_sess_set_get_cb(ctx, uwsgi_ssl_session_get_cb);
SSL_CTX_sess_set_remove_cb(ctx, uwsgi_ssl_session_remove_cb);
}
SSL_CTX_set_timeout(ctx, uwsgi.ssl_sessions_timeout);
/*
SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_SERVER);
#ifdef UWSGI_DEBUG
@@ -4401,6 +4482,9 @@ SSL_CTX *uwsgi_ssl_new_server_context(char *name, char *crt, char *key, char *ci
}
*/
SSL_CTX_set_options(ctx, ssloptions);
return ctx;
}
+4
View File
@@ -343,6 +343,10 @@ static struct uwsgi_option uwsgi_base_options[] = {
#endif
#ifdef UWSGI_SSL
{"ssl-verbose", no_argument, 0, "be verbose about SSL errors", uwsgi_opt_true, &uwsgi.ssl_verbose, 0},
{"ssl-sessions-use-cache", no_argument, 0, "use uWSGI cache for ssl sessions storage", uwsgi_opt_true, &uwsgi.ssl_sessions_use_cache, 0},
{"ssl-session-use-cache", no_argument, 0, "use uWSGI cache for ssl sessions storage", uwsgi_opt_true, &uwsgi.ssl_sessions_use_cache, 0},
{"ssl-sessions-timeout", required_argument, 0, "set SSL sessions timeout (default: 300 seconds)", uwsgi_opt_set_int, &uwsgi.ssl_sessions_timeout, 0},
{"ssl-session-timeout", required_argument, 0, "set SSL sessions timeout (default: 300 seconds)", uwsgi_opt_set_int, &uwsgi.ssl_sessions_timeout, 0},
#endif
{"check-interval", required_argument, 0, "set the interval (in seconds) of master checks", uwsgi_opt_set_dyn, (void *) UWSGI_OPTION_MASTER_INTERVAL, 0},
{"forkbomb-delay", required_argument, 0, "sleep for the specified number of seconds when a forkbomb is detected", uwsgi_opt_set_int, &uwsgi.forkbomb_delay, UWSGI_OPT_MASTER},
+2
View File
@@ -1886,6 +1886,8 @@ struct uwsgi_server {
#ifdef UWSGI_SSL
int ssl_initialized;
int ssl_verbose;
int ssl_sessions_use_cache;
int ssl_sessions_timeout;
#endif
#ifdef __linux__