diff --git a/src/sec-mod-auth.c b/src/sec-mod-auth.c index 952d6d7d..2732ea31 100644 --- a/src/sec-mod-auth.c +++ b/src/sec-mod-auth.c @@ -322,13 +322,16 @@ int handle_sec_auth_session_cmd(int cfd, sec_mod_st * sec, const SecAuthSessionM e = find_client_entry(sec, req->sid.data); if (e == NULL) { - seclog(sec, LOG_INFO, "session open/close but with non-existing sid!"); + seclog(sec, LOG_INFO, "session open/close but with non-existing SID!"); return -1; } if (cmd == SM_CMD_AUTH_SESSION_OPEN) { SecAuthSessionReplyMsg rep = SEC_AUTH_SESSION_REPLY_MSG__INIT; + /* we don't check for expiration of session here. This is + * done at the main server. */ + if (module != NULL && module->open_session != NULL) { ret = module->open_session(e->auth_ctx, req->sid.data, req->sid.len); if (ret < 0) { @@ -342,6 +345,7 @@ int handle_sec_auth_session_cmd(int cfd, sec_mod_st * sec, const SecAuthSessionM } } else { rep.reply = AUTH__REP__OK; + e->in_use++; } lpool = talloc_new(e); @@ -365,7 +369,7 @@ int handle_sec_auth_session_cmd(int cfd, sec_mod_st * sec, const SecAuthSessionM seclog(sec, LOG_WARNING, "sec-mod error in sending session reply"); } talloc_free(lpool); - } else { + } else { /* CLOSE */ if (req->has_uptime && req->uptime > e->stats.uptime) { e->stats.uptime = req->uptime; } @@ -375,7 +379,8 @@ int handle_sec_auth_session_cmd(int cfd, sec_mod_st * sec, const SecAuthSessionM if (req->has_bytes_out && req->bytes_out > e->stats.bytes_out) { e->stats.bytes_out = req->bytes_out; } - del_client_entry(sec, e); + + expire_client_entry(sec, e); } return 0; @@ -573,5 +578,6 @@ void sec_auth_user_deinit(sec_mod_st * sec, client_entry_st * e) } module->auth_deinit(e->auth_ctx); e->auth_ctx = NULL; + e->have_session = 0; } } diff --git a/src/sec-mod-db.c b/src/sec-mod-db.c index 50caa776..61439cc5 100644 --- a/src/sec-mod-db.c +++ b/src/sec-mod-db.c @@ -141,11 +141,6 @@ static void clean_entry(sec_mod_st *sec, client_entry_st * e) talloc_free(e); } -/* Allow few seconds prior to cleaning up entries, to avoid any race - * conditions when session control is enabled. - */ -#define SLACK_TIME 10 - void cleanup_client_entries(sec_mod_st *sec) { struct htable *db = sec->client_db; @@ -155,7 +150,8 @@ void cleanup_client_entries(sec_mod_st *sec) t = htable_first(db, &iter); while (t != NULL) { - if (t->have_session == 0 && now - t->time > MAX_AUTH_SECS + SLACK_TIME) { + if ((now - t->time) > (sec->config->cookie_timeout + AUTH_SLACK_TIME) && + t->in_use == 0) { htable_delval(db, &iter); clean_entry(sec, t); } @@ -171,3 +167,10 @@ void del_client_entry(sec_mod_st *sec, client_entry_st * e) htable_del(db, rehash(e, NULL), e); clean_entry(sec, e); } + +void expire_client_entry(sec_mod_st *sec, client_entry_st * e) +{ + if (e->in_use > 0) + e->in_use--; + e->time = time(0); +} diff --git a/src/sec-mod.h b/src/sec-mod.h index f87e267b..6a4212b5 100644 --- a/src/sec-mod.h +++ b/src/sec-mod.h @@ -53,6 +53,7 @@ typedef struct client_entry_st { uint8_t sid[SID_SIZE]; void * auth_ctx; /* the context of authentication */ unsigned have_session; /* whether an auth session is initialized */ + unsigned in_use; /* counter of users of this structure */ unsigned tls_auth_ok; stats_st stats; @@ -68,6 +69,7 @@ typedef struct client_entry_st { uint8_t dtls_session_id[GNUTLS_MAX_SESSION_ID]; + /* The time this client entry was last modified (created or closed) */ time_t time; } client_entry_st; @@ -77,6 +79,7 @@ unsigned sec_mod_client_db_elems(sec_mod_st *sec); client_entry_st * new_client_entry(sec_mod_st *sec, const char *ip); client_entry_st * find_client_entry(sec_mod_st *sec, uint8_t sid[SID_SIZE]); void del_client_entry(sec_mod_st *sec, client_entry_st * e); +void expire_client_entry(sec_mod_st *sec, client_entry_st * e); void cleanup_client_entries(sec_mod_st *sec); #ifdef __GNUC__ diff --git a/src/vpn.h b/src/vpn.h index 4bb68060..dbe0a664 100644 --- a/src/vpn.h +++ b/src/vpn.h @@ -106,7 +106,12 @@ extern int syslog_open; #define LOG_HTTP_DEBUG 2048 #define LOG_TRANSFER_DEBUG 2049 -#define MAX_AUTH_SECS 40 +/* Allow few seconds prior to cleaning up entries, to avoid any race + * conditions when session control is enabled. + */ +#define AUTH_SLACK_TIME 10 + + #define MAX_CIPHERSUITE_NAME 64 #define MAX_MSG_SIZE 256 #define SID_SIZE 16 diff --git a/src/worker-auth.c b/src/worker-auth.c index 210580c4..02fbc5f0 100644 --- a/src/worker-auth.c +++ b/src/worker-auth.c @@ -168,7 +168,7 @@ int get_auth_handler2(worker_st * ws, unsigned http_ver, const char *pmsg) ret = cstp_printf(ws, "Set-Cookie: webvpncontext=%s; Max-Age=%u; Secure\r\n", - context, (unsigned)MAX_AUTH_SECS); + context, (unsigned)ws->config->cookie_timeout); if (ret < 0) return -1;