mirror of
https://github.com/clearlinux/uwsgi.git
synced 2026-09-06 13:41:28 +00:00
first implementation of ssl sessions store in the shared cache
This commit is contained in:
@@ -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()");
|
||||
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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},
|
||||
|
||||
Reference in New Issue
Block a user