Added automatic TLS session expiration.

This commit is contained in:
Nikos Mavrogiannopoulos
2013-02-04 19:05:17 +01:00
parent 6572f2a082
commit ceca403691
7 changed files with 62 additions and 10 deletions

View File

@@ -81,12 +81,12 @@ struct hlist_node *pos, *tmp;
hash_del(&cache->list);
free(cache);
s->tls_db->entries--;
return 0;
}
}
return 0;
}
static int ip_cmp(const struct sockaddr_storage *s1, const struct sockaddr_storage *s2, size_t n)
@@ -141,6 +141,12 @@ size_t key;
if (req->session_data_size > MAX_SESSION_DATA_SIZE)
return -1;
if ((s->config->max_clients != 0 &&
s->tls_db->entries >= MAX(s->config->max_clients, DEFAULT_MAX_CACHED_TLS_SESSIONS(s->tls_db))) ||
(s->config->max_clients == 0 &&
s->tls_db->entries >= DEFAULT_MAX_CACHED_TLS_SESSIONS(s->tls_db)))
return -1;
key = hash_pjw_bare(req->session_id, req->session_id_size);
cache = malloc(sizeof(*cache));
@@ -156,6 +162,41 @@ size_t key;
memcpy(&cache->remote_addr, &proc->remote_addr, proc->remote_addr_len);
hash_add(s->tls_db->entry, &cache->list, key);
s->tls_db->entries++;
return 0;
}
void expire_tls_sessions(main_server_st *s)
{
tls_cache_st* cache;
int bkt;
struct hlist_node *pos, *tmp;
time_t now, exp;
now = time(0);
hash_for_each_safe(s->tls_db->entry, bkt, pos, tmp, cache, list) {
#if GNUTLS_VERSION_NUMBER >= 0x030107
gnutls_datum_t d;
d.data = (void*)cache->session_data;
d.size = cache->session_data_size;
exp = gnutls_db_check_entry_time(&d);
#else
exp = 0;
#endif
if (now-exp > TLS_SESSION_EXPIRATION_TIME) {
cache->session_data_size = 0;
cache->session_id_size = 0;
fprintf(stderr, "session removed\n");
hash_del(&cache->list);
free(cache);
s->tls_db->entries--;
}
}
return;
}

View File

@@ -44,7 +44,7 @@
int syslog_open = 0;
static unsigned int terminate = 0;
static unsigned int need_to_expire_cookies = 0;
static unsigned int need_maintainance = 0;
struct listen_list_st {
struct list_head list;
@@ -177,7 +177,7 @@ int status;
static void handle_alarm(int signo)
{
need_to_expire_cookies = 1;
need_maintainance = 1;
}
@@ -448,7 +448,8 @@ int main(int argc, char** argv)
if (config.foreground == 0)
daemon(0, 0);
alarm(config.cookie_validity + 300);
#define MAINTAINANCE_TIME (config.cookie_validity + 300)
alarm(MAINTAINANCE_TIME);
openlog("ocserv", LOG_PID|LOG_NDELAY, LOG_LOCAL0);
syslog_open = 1;
@@ -509,7 +510,7 @@ int main(int argc, char** argv)
continue;
}
if (config.max_clients > 0 && active_clients > config.max_clients) {
if (config.max_clients > 0 && active_clients >= config.max_clients) {
close(fd);
syslog(LOG_INFO, "Reached maximum client limit (active: %u)", active_clients);
break;
@@ -584,16 +585,20 @@ fork_failed:
}
/* Check if we need to expire any cookies */
if (need_to_expire_cookies != 0) {
need_to_expire_cookies = 0;
if (need_maintainance != 0) {
need_maintainance = 0;
pid = fork();
if (pid == 0) { /* child */
syslog(LOG_INFO, "Performing maintainance");
clear_listen_list(&llist);
clear_proc_list(&clist);
expire_cookies(&config);
expire_tls_sessions(&s);
exit(0);
}
alarm(MAINTAINANCE_TIME);
}
}

View File

@@ -32,6 +32,7 @@ typedef struct main_server_st {
int handle_commands(main_server_st *s, struct proc_list_st* cur);
void expire_tls_sessions(main_server_st *s);
int send_resume_fetch_reply(main_server_st* s, struct proc_list_st* proc,
cmd_resume_reply_t r, struct cmd_resume_fetch_reply_st * reply);

View File

@@ -18,7 +18,7 @@ auth-timeout = 40
tcp-port = 3333
# Keepalive in seconds
keepalive = 5
keepalive = 10
# The key and the certificates of the server
server-cert = /home/nmav/cvs/ocserv/test.pem
@@ -46,7 +46,7 @@ tls-priorities = "PERFORMANCE:%SERVER_PRECEDENCE:%COMPAT"
# Once a client is authenticated he's provided a cookie with
# which he can reconnect. This option sets the maximum lifetime
# of that cookie.
cookie-validity = 14400
cookie-validity = 30
# Cookie database file. Where to store the cookies.
cookie-db = /var/tmp/ocserv-cookie.db

View File

@@ -125,6 +125,7 @@ tls_cache_db_st * db;
exit(1);
hash_init(db->entry);
db->entries = 0;
*_db = db;
}

View File

@@ -50,9 +50,12 @@ typedef struct
struct hlist_node list;
} tls_cache_st;
#define TLS_SESSION_EXPIRATION_TIME 600
#define DEFAULT_MAX_CACHED_TLS_SESSIONS(db) HASH_SIZE(db->entry)
typedef struct
{
DECLARE_HASHTABLE(entry, 7);
unsigned int entries;
} tls_cache_db_st;
void tls_cache_init(struct cfg_st* config, tls_cache_db_st** db);

View File

@@ -345,6 +345,7 @@ void vpn_server(struct worker_st* ws)
set_resume_db_funcs(session);
gnutls_session_set_ptr(session, ws);
gnutls_db_set_ptr (session, ws);
gnutls_db_set_cache_expiration(session, TLS_SESSION_EXPIRATION_TIME);
do {
ret = gnutls_handshake(session);