mirror of
https://gitlab.com/openconnect/ocserv.git
synced 2026-02-10 00:37:00 +08:00
sec-mod: separated expiration from creation time fields
That allows to set explicit expiration of the cookie, and ensure that we can close a session in a way that we provide a limited time window for it to re-open. That handles anyconnect client compatibility; this client terminates and reconnects using the original cookie, multiple times. Signed-off-by: Nikos Mavrogiannopoulos <nmav@gnutls.org>
This commit is contained in:
committed by
Nikos Mavrogiannopoulos
parent
c4a8b21aad
commit
8253cc2920
@@ -143,7 +143,7 @@ int send_sec_auth_reply(int cfd, sec_mod_st * sec, client_entry_st * entry, AUTH
|
||||
}
|
||||
|
||||
/* calculate time in auth for this client */
|
||||
update_auth_time_stats(sec, time(0) - entry->time);
|
||||
update_auth_time_stats(sec, time(0) - entry->created);
|
||||
|
||||
msg.has_sid = 1;
|
||||
msg.sid.data = entry->sid;
|
||||
@@ -521,7 +521,8 @@ int handle_secm_session_open_cmd(sec_mod_st *sec, int fd, const SecmSessionOpenM
|
||||
talloc_free(lpool);
|
||||
|
||||
seclog(sec, LOG_INFO, "initiating session for user '%s' "SESSION_STR, e->acct_info.username, e->acct_info.safe_id);
|
||||
e->time = -1;
|
||||
/* refresh cookie validity */
|
||||
e->exptime = time(0) + sec->config->cookie_timeout + AUTH_SLACK_TIME;
|
||||
e->in_use++;
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -84,8 +84,8 @@ void handle_secm_list_cookies_reply(void *pool, int fd, sec_mod_st *sec)
|
||||
cookies[msg.n_cookies].session_is_open = t->session_is_open;
|
||||
cookies[msg.n_cookies].tls_auth_ok = t->tls_auth_ok;
|
||||
|
||||
if (t->time > 0)
|
||||
cookies[msg.n_cookies].last_modified = t->time;
|
||||
if (t->created > 0)
|
||||
cookies[msg.n_cookies].last_modified = t->created;
|
||||
else
|
||||
cookies[msg.n_cookies].last_modified = 0;
|
||||
cookies[msg.n_cookies].username = t->acct_info.username;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Red Hat
|
||||
* Copyright (C) 2017 Nikos Mavrogiannopoulos
|
||||
*
|
||||
* This file is part of ocserv.
|
||||
*
|
||||
@@ -90,6 +91,7 @@ client_entry_st *new_client_entry(sec_mod_st *sec, const char *ip, unsigned pid)
|
||||
client_entry_st *e, *te;
|
||||
int ret;
|
||||
int retries = 3;
|
||||
time_t now;
|
||||
|
||||
e = talloc_zero(db, client_entry_st);
|
||||
if (e == NULL) {
|
||||
@@ -117,7 +119,9 @@ client_entry_st *new_client_entry(sec_mod_st *sec, const char *ip, unsigned pid)
|
||||
}
|
||||
|
||||
calc_safe_id(e->sid, SID_SIZE, (char *)e->acct_info.safe_id, sizeof(e->acct_info.safe_id));
|
||||
e->time = time(0);
|
||||
now = time(0);
|
||||
e->exptime = now + sec->config->cookie_timeout + AUTH_SLACK_TIME;
|
||||
e->created = now;
|
||||
|
||||
if (htable_add(db, rehash(e, NULL), e) == 0) {
|
||||
seclog(sec, LOG_ERR,
|
||||
@@ -187,18 +191,29 @@ void del_client_entry(sec_mod_st *sec, client_entry_st * e)
|
||||
|
||||
void expire_client_entry(sec_mod_st *sec, client_entry_st * e)
|
||||
{
|
||||
time_t now;
|
||||
|
||||
if (e->in_use > 0)
|
||||
e->in_use--;
|
||||
if (e->in_use == 0) {
|
||||
e->time = time(0);
|
||||
|
||||
if (sec->config->persistent_cookies == 0 && (e->discon_reason == REASON_USER_DISCONNECT
|
||||
|| e->discon_reason == REASON_SERVER_DISCONNECT || e->discon_reason == REASON_SESSION_TIMEOUT)) {
|
||||
if (sec->config->persistent_cookies == 0 && (e->discon_reason == REASON_SERVER_DISCONNECT ||
|
||||
e->discon_reason == REASON_SESSION_TIMEOUT)) {
|
||||
seclog(sec, LOG_INFO, "invalidating session of user '%s' "SESSION_STR,
|
||||
e->acct_info.username, e->acct_info.safe_id);
|
||||
e->acct_info.username, e->acct_info.safe_id);
|
||||
/* immediately disconnect the user */
|
||||
del_client_entry(sec, e);
|
||||
} else {
|
||||
now = time(0);
|
||||
/* We intentionally don't close the session immediatelly on
|
||||
* REASON_USER_DISCONNECT, as some anyconect clients
|
||||
* explicitly disconnect with the intention to reconnect
|
||||
* seconds later. */
|
||||
if (e->discon_reason == REASON_USER_DISCONNECT) {
|
||||
if (!sec->config->persistent_cookies || (now+AUTH_SLACK_TIME >= e->exptime))
|
||||
e->exptime = now + AUTH_SLACK_TIME;
|
||||
} else {
|
||||
e->exptime = now + sec->config->cookie_timeout + AUTH_SLACK_TIME;
|
||||
}
|
||||
seclog(sec, LOG_INFO, "temporarily closing session for %s "SESSION_STR, e->acct_info.username, e->acct_info.safe_id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ typedef struct common_acct_info_st {
|
||||
unsigned id;
|
||||
} common_acct_info_st;
|
||||
|
||||
#define IS_CLIENT_ENTRY_EXPIRED_FULL(sec, e, now, clean) (e->time != -1 && (now - e->time) > (sec->config->cookie_timeout + (clean?AUTH_SLACK_TIME:0)) && e->in_use == 0)
|
||||
#define IS_CLIENT_ENTRY_EXPIRED_FULL(sec, e, now, clean) (e->exptime != -1 && now >= e->exptime && e->in_use == 0)
|
||||
#define IS_CLIENT_ENTRY_EXPIRED(sec, e, now) IS_CLIENT_ENTRY_EXPIRED_FULL(sec, e, now, 0)
|
||||
|
||||
typedef struct client_entry_st {
|
||||
@@ -101,8 +101,10 @@ 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;
|
||||
/* The time this client entry was created */
|
||||
time_t created;
|
||||
/* The time this client entry is supposed to expire */
|
||||
time_t exptime;
|
||||
|
||||
/* the auth type associated with the user */
|
||||
unsigned auth_type;
|
||||
|
||||
Reference in New Issue
Block a user