diff --git a/src/Makefile.am b/src/Makefile.am index 6ac06fb8..2fe29bdb 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -19,7 +19,7 @@ ocserv_SOURCES = main.c main-auth.c worker-vpn.c worker-auth.c tlslib.c \ vpn.h cookies.h tlslib.h http-parser/http_parser.h log.c tun.c tun.h \ config.c pam.c pam.h worker-resume.c worker.h main-resume.c main.h \ worker-extras.c main-auth.h \ - main-user.c cookies-gdbm.c cookies-hash.c worker-misc.c setproctitle.h \ + main-user.c worker-misc.c setproctitle.h \ setproctitle.c worker-privs.c plain.c plain.h common.h common.c \ sec-mod.c sec-mod.h script-list.h system.c system.h icmp-ping.c icmp-ping.h \ str.c str.h gettime.h $(CCAN_SOURCES) diff --git a/src/config.c b/src/config.c index cc4124c9..38f01c5c 100644 --- a/src/config.c +++ b/src/config.c @@ -191,8 +191,6 @@ unsigned j; READ_STRING("tls-priorities", config->priorities, 0); READ_STRING("chroot-dir", config->chroot_dir, 0); - READ_STRING("cookie-db", config->cookie_db_name, 0); - READ_NUMERIC("cookie-validity", config->cookie_validity, 1); READ_NUMERIC("auth-timeout", config->auth_timeout, 0); READ_NUMERIC("max-clients", config->max_clients, 0); @@ -376,7 +374,6 @@ unsigned i; DEL(config->cert_group_oid); DEL(config->priorities); DEL(config->chroot_dir); - DEL(config->cookie_db_name); DEL(config->connect_script); DEL(config->disconnect_script); diff --git a/src/cookies-gdbm.c b/src/cookies-gdbm.c deleted file mode 100644 index 8a85c656..00000000 --- a/src/cookies-gdbm.c +++ /dev/null @@ -1,190 +0,0 @@ -/* - * Copyright (C) 2013 Nikos Mavrogiannopoulos - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "setproctitle.h" -#include -#include - -#ifdef HAVE_GDBM - -# include - -/* Note that it receives allocated data and stores them. Do not - * free the sc. - */ -static -int cookie_gdbm_store(main_server_st *s, struct stored_cookie_st* sc) -{ -GDBM_FILE dbf; -datum key; -datum data; -int ret; - - dbf = gdbm_open((char*)s->config->cookie_db_name, 0, GDBM_WRCREAT, S_IRUSR|S_IWUSR, NULL); - if (dbf == NULL) { - syslog(LOG_ERR, "Cannot open cookie database: %s", s->config->cookie_db_name); - return -1; - } - - key.dptr = (void*)sc->cookie; - key.dsize = sizeof(sc->cookie); - data.dptr = (void*)sc; - data.dsize = sizeof(*sc); - - ret = gdbm_store( dbf, key, data, GDBM_INSERT); - if (ret != 0) { - ret = -1; - goto finish; - } - - ret = 0; - -finish: - free(sc); - gdbm_close(dbf); - return ret; -} - -/* retrieves and deletes the entry */ -static -int cookie_gdbm_retrieve(main_server_st *s, const void* cookie, unsigned cookie_size, - struct stored_cookie_st* sc) -{ -GDBM_FILE dbf; -datum key; -datum data; -int ret; - - dbf = gdbm_open((char*)s->config->cookie_db_name, 0, GDBM_READER, 0, NULL); - if (dbf == NULL) { - syslog(LOG_ERR, "Cannot open cookie database: %s", s->config->cookie_db_name); - return -1; - } - - key.dptr = (void*)cookie; - key.dsize = cookie_size; - - data = gdbm_fetch( dbf, key); - if (data.dsize != sizeof(*sc)) { - ret = -1; - goto finish; - } - memcpy(sc, data.dptr, data.dsize); - gdbm_delete(dbf, key); - - ret = 0; - -finish: - gdbm_close(dbf); - return ret; -} - -static -void cookie_gdbm_expire(main_server_st* s) -{ -GDBM_FILE dbf; -datum key; -datum data; -int deleted = 0; -struct stored_cookie_st sc; -time_t now = time(0); -pid_t pid; - - pid = fork(); - if (pid == 0) { /* child */ - clear_lists(s); - setproctitle(PACKAGE_NAME"-maint"); - - dbf = gdbm_open((char*)s->config->cookie_db_name, 0, GDBM_WRITER, 0, NULL); - if (dbf == NULL) - exit(1); - - key = gdbm_firstkey(dbf); - if (key.dptr == NULL) - goto finish; - - while(key.dptr != NULL) { - data = gdbm_fetch( dbf, key); - if (data.dsize != sizeof(sc)) { - gdbm_delete(dbf, key); - deleted++; - } else { - memcpy(&sc, data.dptr, data.dsize); - if (sc.expiration <= now) { - gdbm_delete(dbf, key); - deleted++; - } - } - - key = gdbm_nextkey(dbf, key); - } - - if (deleted > 0) - gdbm_reorganize(dbf); - -finish: - gdbm_close(dbf); - exit(0); - } - - return; -} - -static -int cookie_gdbm_init(main_server_st* s) -{ - return 0; -} - -static -void cookie_gdbm_erase(main_server_st* s) -{ - return; -} - -static -void cookie_gdbm_deinit(main_server_st* s) -{ - return; -} - -struct cookie_storage_st gdbm_cookie_funcs = { - .store = cookie_gdbm_store, - .retrieve = cookie_gdbm_retrieve, - .expire = cookie_gdbm_expire, - .init = cookie_gdbm_init, - .deinit = cookie_gdbm_deinit, - .erase = cookie_gdbm_erase, -}; - -#endif diff --git a/src/cookies-hash.c b/src/cookies-hash.c deleted file mode 100644 index 298947c7..00000000 --- a/src/cookies-hash.c +++ /dev/null @@ -1,199 +0,0 @@ -/* - * Copyright (C) 2013 Nikos Mavrogiannopoulos - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#define MAX_COOKIES(n) ((n>0&&n>64)?(2*n):128) - -/* Note that it receives allocated data and stores them. Do not - * free the sc. - */ -static -int store_cookie_hash(main_server_st *s, struct stored_cookie_st* sc) -{ -size_t key; - - if (s->cookie_db->entries >= MAX_COOKIES(s->config->max_clients)) { - mslog(s, NULL, LOG_INFO, "maximum number of cookies was reached (%u)", MAX_COOKIES(s->config->max_clients)); - need_maintainance = 1; - return -1; - } - - key = hash_stable_8(sc->cookie, COOKIE_SIZE, 0); - - htable_add(&s->cookie_db->ht, key, sc); - s->cookie_db->entries++; - - return 0; -} - -/* retrieves and deletes the entry */ -static -int retrieve_cookie_hash(main_server_st *s, const void* cookie, unsigned cookie_size, - struct stored_cookie_st* rsc) -{ -size_t key; -struct htable_iter iter; -struct stored_cookie_st * sc; - - key = hash_stable_8(cookie, cookie_size, 0); - - sc = htable_firstval(&s->cookie_db->ht, &iter, key); - while(sc != NULL) { - if (cookie_size == COOKIE_SIZE && - memcmp (cookie, sc->cookie, COOKIE_SIZE) == 0) { - - memcpy(rsc, sc, sizeof(*sc)); - htable_delval(&s->cookie_db->ht, &iter); - return 0; - } - - sc = htable_nextval(&s->cookie_db->ht, &iter, key); - } - - return -1; -} - -static void delete_entry(hash_db_st *cookie_db, struct htable_iter *iter, - struct stored_cookie_st *sc) -{ - htable_delval(&cookie_db->ht, iter); - free(sc); - cookie_db->entries--; -} - -static -void expire_cookies_hash(main_server_st* s) -{ -struct stored_cookie_st *sc; -struct htable_iter iter; -time_t now = time(0); -unsigned int todelete; - - sc = htable_first(&s->cookie_db->ht, &iter); - while(sc != NULL) { - if (sc->expiration <= now) { - delete_entry(s->cookie_db, &iter, sc); - } - sc = htable_next(&s->cookie_db->ht, &iter); - } - - /* if the hash is still full then delete the few first cookies */ - if (s->cookie_db->entries >= MAX_COOKIES(s->config->max_clients)) { - todelete = MAX_COOKIES(s->config->max_clients)/5; - mslog(s, NULL, LOG_INFO, "too many cookies present; expiring the first %u", todelete); - sc = htable_first(&s->cookie_db->ht, &iter); - while(sc != NULL) { - if (todelete >= 0) { - delete_entry(s->cookie_db, &iter, sc); - todelete--; - } else { - break; - } - sc = htable_next(&s->cookie_db->ht, &iter); - } - } -} - -static -void erase_cookies_hash(main_server_st* s) -{ -struct stored_cookie_st *sc; -struct htable_iter iter; -time_t now = time(0); - - sc = htable_first(&s->cookie_db->ht, &iter); - while(sc != NULL) { - if (sc->expiration <= now) { - htable_delval(&s->cookie_db->ht, &iter); - memset(sc->cookie, 0, sizeof(sc->cookie)); - free(sc); - s->cookie_db->entries--; - } - sc = htable_next(&s->cookie_db->ht, &iter); - } -} - -static size_t rehash(const void *_e, void *unused) -{ -const struct stored_cookie_st *e = _e; - - return hash_stable_8(e->cookie, COOKIE_SIZE, 0); -} - -static -int cookie_db_init_hash(main_server_st * s) -{ -hash_db_st * db; - - db = malloc(sizeof(*db)); - if (db == NULL) - return -1; - - htable_init(&db->ht, rehash, NULL); - db->entries = 0; - - s->cookie_db = db; - - return 0; -} - -static -void cookie_db_deinit_hash(main_server_st* s) -{ -struct stored_cookie_st* cache; -struct htable_iter iter; - - cache = htable_first(&s->cookie_db->ht, &iter); - while(cache != NULL) { - free(cache); - cache = htable_next(&s->cookie_db->ht, &iter); - } - htable_clear(&s->cookie_db->ht); - s->cookie_db->entries = 0; - - return; -} - -struct cookie_storage_st hash_cookie_funcs = { - .store = store_cookie_hash, - .retrieve = retrieve_cookie_hash, - .expire = expire_cookies_hash, - .erase = erase_cookies_hash, - .init = cookie_db_init_hash, - .deinit = cookie_db_deinit_hash, -}; diff --git a/src/cookies.c b/src/cookies.c index c2e2e332..e59fc7af 100644 --- a/src/cookies.c +++ b/src/cookies.c @@ -35,28 +35,91 @@ #include #include -cookie_store_fn store_cookie; -cookie_retrieve_fn retrieve_cookie; -cookie_db_deinit_fn cookie_db_deinit; -cookie_expire_fn expire_cookies; -cookie_expire_fn erase_cookies; - -int cookie_db_init(main_server_st* s) +int decrypt_cookie(main_server_st * s, const uint8_t* cookie, unsigned cookie_size, + struct stored_cookie_st* sc) { -struct cookie_storage_st* funcs; +gnutls_datum_t iv = { (void*)cookie, COOKIE_IV_SIZE }; +int ret; +uint8_t tag[COOKIE_MAC_SIZE]; +gnutls_cipher_hd_t h; +gnutls_datum_t key = { (void*)s->cookie_key, sizeof(s->cookie_key) }; -#ifdef HAVE_GDBM - if (s->config->cookie_db_name != NULL) - funcs = &gdbm_cookie_funcs; - else -#endif - funcs = &hash_cookie_funcs; + if (cookie_size != COOKIE_SIZE) + return -1; - cookie_db_deinit = funcs->deinit; - expire_cookies = funcs->expire; - erase_cookies = funcs->erase; - store_cookie = funcs->store; - retrieve_cookie = funcs->retrieve; + ret = gnutls_cipher_init(&h, GNUTLS_CIPHER_AES_128_GCM, &key, &iv); + if (ret < 0) + return -1; + + cookie += COOKIE_IV_SIZE; + + ret = gnutls_cipher_decrypt2(h, cookie, sizeof(*sc), sc, sizeof(*sc)); + if (ret < 0) { + ret = -1; + goto cleanup; + } + + ret = gnutls_cipher_tag(h, tag, sizeof(tag)); + if (ret < 0) { + ret = -1; + goto cleanup; + } + + cookie += sizeof(*sc); + if (memcmp(tag, cookie, COOKIE_MAC_SIZE) != 0) { + ret = -1; + goto cleanup; + } + + ret = 0; + +cleanup: + gnutls_cipher_deinit(h); + + return ret; +} + +int encrypt_cookie(main_server_st * s, uint8_t* cookie, unsigned cookie_size, + const struct stored_cookie_st* sc) +{ +uint8_t _iv[COOKIE_IV_SIZE]; +gnutls_cipher_hd_t h; +gnutls_datum_t iv = { _iv, sizeof(_iv) }; +gnutls_datum_t key = { (void*)s->cookie_key, sizeof(s->cookie_key) }; +int ret; + + if (cookie_size != COOKIE_SIZE) + return -1; + + ret = gnutls_rnd(GNUTLS_RND_NONCE, _iv, sizeof(_iv)); + if (ret < 0) + return -1; + + ret = gnutls_cipher_init(&h, GNUTLS_CIPHER_AES_128_GCM, &key, &iv); + if (ret < 0) + return -1; + + memcpy(cookie, _iv, COOKIE_IV_SIZE); + cookie += COOKIE_IV_SIZE; + + ret = gnutls_cipher_encrypt2(h, sc, sizeof(*sc), cookie, sizeof(*sc)); + if (ret < 0) { + ret = -1; + goto cleanup; + } + + cookie += sizeof(*sc); + + ret = gnutls_cipher_tag(h, cookie, COOKIE_MAC_SIZE); + if (ret < 0) { + ret = -1; + goto cleanup; + } + + ret = 0; + +cleanup: + gnutls_cipher_deinit(h); + return ret; - return funcs->init(s); } diff --git a/src/cookies.h b/src/cookies.h index 5776084c..8c80a6e5 100644 --- a/src/cookies.h +++ b/src/cookies.h @@ -2,44 +2,22 @@ #define COOKIES_H #include -#include -struct stored_cookie_st { - uint8_t cookie[COOKIE_SIZE]; +struct __attribute__ ((__packed__)) stored_cookie_st { char username[MAX_USERNAME_SIZE]; char groupname[MAX_GROUPNAME_SIZE]; char hostname[MAX_HOSTNAME_SIZE]; uint8_t session_id[GNUTLS_MAX_SESSION_ID]; - time_t expiration; + uint32_t expiration; }; -typedef int (*cookie_store_fn)(main_server_st *, struct stored_cookie_st* sc); +#define COOKIE_IV_SIZE 12 /* AES-GCM */ +#define COOKIE_MAC_SIZE 12 /* 96-bits of AES-GCM */ +#define COOKIE_SIZE (COOKIE_IV_SIZE + sizeof(struct stored_cookie_st) + COOKIE_MAC_SIZE) -typedef int (*cookie_retrieve_fn)(main_server_st *, const void* cookie, unsigned cookie_size, +int encrypt_cookie(struct main_server_st * s, uint8_t* cookie, unsigned cookie_size, + const struct stored_cookie_st* sc); +int decrypt_cookie(struct main_server_st * s, const uint8_t* cookie, unsigned cookie_size, struct stored_cookie_st* sc); -typedef void (*cookie_db_deinit_fn)(main_server_st*); -typedef void (*cookie_expire_fn)(main_server_st* s); - -extern cookie_store_fn store_cookie; -extern cookie_retrieve_fn retrieve_cookie; -extern cookie_db_deinit_fn cookie_db_deinit; -extern cookie_expire_fn expire_cookies; -extern cookie_expire_fn erase_cookies; - -int cookie_db_init(main_server_st*); - - -struct cookie_storage_st { - cookie_store_fn store; - cookie_retrieve_fn retrieve; - cookie_expire_fn expire; - cookie_expire_fn erase; /* erases cookies if stored in process */ - int (*init)(main_server_st *); - cookie_db_deinit_fn deinit; -}; - -extern struct cookie_storage_st gdbm_cookie_funcs; -extern struct cookie_storage_st hash_cookie_funcs; - #endif diff --git a/src/ipc.h b/src/ipc.h index 730a005a..153597a6 100644 --- a/src/ipc.h +++ b/src/ipc.h @@ -9,6 +9,7 @@ #include #include #include +#include #define MAX_MSG_SIZE 256 diff --git a/src/log.c b/src/log.c index af523fd8..94a916dc 100644 --- a/src/log.c +++ b/src/log.c @@ -27,6 +27,7 @@ #include #include +#include const char *human_addr(const struct sockaddr *sa, socklen_t salen, void *_buf, size_t buflen) diff --git a/src/main-auth.c b/src/main-auth.c index 8137624f..4d03f465 100644 --- a/src/main-auth.c +++ b/src/main-auth.c @@ -155,31 +155,27 @@ int handle_auth_cookie_req(main_server_st* s, struct proc_st* proc, const struct cmd_auth_cookie_req_st * req) { int ret; -struct stored_cookie_st *sc; +struct stored_cookie_st sc; time_t now = time(0); - sc = malloc(sizeof(*sc)); - if (sc == NULL) - return -1; - - ret = retrieve_cookie(s, req->cookie, sizeof(req->cookie), sc); + ret = decrypt_cookie(s, req->cookie, sizeof(req->cookie), &sc); if (ret < 0) { ret = -1; goto cleanup; } - if (sc->expiration < now) { + if (sc.expiration < now) { ret = -1; goto cleanup; } memcpy(proc->cookie, req->cookie, sizeof(proc->cookie)); - memcpy(proc->username, sc->username, sizeof(proc->username)); - memcpy(proc->groupname, sc->groupname, sizeof(proc->groupname)); - memcpy(proc->hostname, sc->hostname, sizeof(proc->hostname)); - memcpy(proc->session_id, sc->session_id, sizeof(proc->session_id)); + memcpy(proc->username, sc.username, sizeof(proc->username)); + memcpy(proc->groupname, sc.groupname, sizeof(proc->groupname)); + memcpy(proc->hostname, sc.hostname, sizeof(proc->hostname)); + memcpy(proc->session_id, sc.session_id, sizeof(proc->session_id)); proc->session_id_size = sizeof(proc->session_id); - + proc->username[sizeof(proc->username)-1] = 0; proc->groupname[sizeof(proc->groupname)-1] = 0; proc->hostname[sizeof(proc->hostname)-1] = 0; @@ -197,52 +193,33 @@ time_t now = time(0); } } - /* ok auth ok. Renew the cookie. */ - sc->expiration = time(0) + s->config->cookie_validity; - ret = store_cookie(s, sc); - if (ret < 0) - goto cleanup; - - /* sc is freed in store_cookie() */ - return 0; cleanup: - free(sc); return ret; } int generate_and_store_vals(main_server_st *s, struct proc_st* proc) { int ret; -struct stored_cookie_st *sc; +struct stored_cookie_st sc; - ret = gnutls_rnd(GNUTLS_RND_RANDOM, proc->cookie, sizeof(proc->cookie)); - if (ret < 0) - return -2; - ret = gnutls_rnd(GNUTLS_RND_NONCE, proc->session_id, sizeof(proc->session_id)); - if (ret < 0) - return -2; - proc->session_id_size = sizeof(proc->session_id); - - sc = calloc(1, sizeof(*sc)); - if (sc == NULL) - return -2; + ret = gnutls_rnd(GNUTLS_RND_NONCE, proc->session_id, sizeof(proc->session_id)); + if (ret < 0) + return -1; + + proc->session_id_size = sizeof(proc->session_id); - sc->expiration = time(0) + s->config->cookie_validity; + memcpy(sc.username, proc->username, sizeof(proc->username)); + memcpy(sc.groupname, proc->groupname, sizeof(proc->groupname)); + memcpy(sc.hostname, proc->hostname, sizeof(proc->hostname)); + memcpy(sc.session_id, proc->session_id, sizeof(proc->session_id)); - memcpy(sc->cookie, proc->cookie, sizeof(proc->cookie)); - memcpy(sc->username, proc->username, sizeof(sc->username)); - memcpy(sc->groupname, proc->groupname, sizeof(sc->groupname)); - memcpy(sc->hostname, proc->hostname, sizeof(sc->hostname)); - memcpy(sc->session_id, proc->session_id, sizeof(sc->session_id)); + sc.expiration = time(0) + s->config->cookie_validity; - /* the sc pointer stays there */ - ret = store_cookie(s, sc); - if (ret < 0) { - free(sc); + ret = encrypt_cookie(s, proc->cookie, sizeof(proc->cookie), &sc); + if (ret < 0) return -1; - } - + return 0; } diff --git a/src/main-misc.c b/src/main-misc.c index 88daa949..7aad94ab 100644 --- a/src/main-misc.c +++ b/src/main-misc.c @@ -147,7 +147,7 @@ fail: return ret; } -static int accept_user(main_server_st *s, struct proc_st* proc, unsigned cmd) +static int accept_user(main_server_st *s, struct proc_st* proc, unsigned cmd, const char* prev_user) { int ret; const char* group; @@ -155,7 +155,7 @@ const char* group; mslog(s, proc, LOG_DEBUG, "accepting user '%s'", proc->username); proc_auth_deinit(s, proc); - ret = open_tun(s, &proc->lease); + ret = open_tun(s, &proc->lease, prev_user); if (ret < 0) { return -1; } @@ -201,6 +201,7 @@ int handle_commands(main_server_st *s, struct proc_st* proc) struct iovec iov[2]; uint8_t cmd; struct msghdr hdr; + /* FIXME: do not write directly to the union */ union { struct cmd_auth_req_st auth; struct cmd_auth_cookie_req_st cauth; @@ -347,7 +348,7 @@ int handle_commands(main_server_st *s, struct proc_st* proc) return ret; } - ret = accept_user(s, proc, cmd); + ret = accept_user(s, proc, cmd, NULL); if (ret < 0) { goto cleanup; } @@ -355,6 +356,7 @@ int handle_commands(main_server_st *s, struct proc_st* proc) goto cleanup; case AUTH_COOKIE_REQ: + if (cmd_data_len != sizeof(cmd_data.cauth)) { mslog(s, proc, LOG_ERR, "error in received message (%u) length.", (unsigned)cmd); return ERR_BAD_COMMAND; @@ -366,7 +368,7 @@ int handle_commands(main_server_st *s, struct proc_st* proc) return ret; } - ret = accept_user(s, proc, cmd); + ret = accept_user(s, proc, cmd, (proc->username[0] != 0)?proc->username:NULL); if (ret < 0) { goto cleanup; } diff --git a/src/main.c b/src/main.c index 3ab0b64d..a2cc3c26 100644 --- a/src/main.c +++ b/src/main.c @@ -36,6 +36,7 @@ #include #include +#include #include #include "ipc.h" #include "setproctitle.h" @@ -599,7 +600,6 @@ static void check_other_work(main_server_st *s) need_maintainance = 0; mslog(s, NULL, LOG_INFO, "Performing maintainance"); expire_tls_sessions(s); - expire_cookies(s); expire_banned(s); alarm(MAINTAINANCE_TIME(s)); } @@ -655,6 +655,12 @@ int main(int argc, char** argv) /* Initialize GnuTLS */ tls_global_init(&s); + + ret = gnutls_rnd(GNUTLS_RND_RANDOM, s.cookie_key, sizeof(s.cookie_key)); + if (ret < 0) { + fprintf(stderr, "Error in cookie key generation\n"); + exit(1); + } /* load configuration */ ret = cmd_parser(argc, argv, &config); @@ -675,12 +681,6 @@ int main(int argc, char** argv) main_auth_init(&s); - ret = cookie_db_init(&s); - if (ret < 0) { - fprintf(stderr, "Could not initialize cookie database.\n"); - exit(1); - } - /* Listen to network ports */ ret = listen_ports(&config, &s.llist, config.name); if (ret < 0) { @@ -808,7 +808,6 @@ int main(int argc, char** argv) */ close(cmd_fd[0]); clear_lists(&s); - erase_cookies(&s); setproctitle(PACKAGE_NAME"-worker"); kill_on_parent_kill(SIGTERM); diff --git a/src/main.h b/src/main.h index 7f1f614f..7cc713c1 100644 --- a/src/main.h +++ b/src/main.h @@ -8,6 +8,7 @@ #include #include #include "ipc.h" +#include int cmd_parser (int argc, char **argv, struct cfg_st* config); void reload_cfg_file(struct cfg_st* config); @@ -70,7 +71,7 @@ struct proc_st { char groupname[MAX_GROUPNAME_SIZE]; /* the owner's group */ char hostname[MAX_HOSTNAME_SIZE]; /* the requested hostname */ uint8_t cookie[COOKIE_SIZE]; /* the cookie associated with the session */ - + void * auth_ctx; /* the context of authentication */ unsigned auth_status; /* PS_AUTH_ */ }; @@ -99,7 +100,8 @@ typedef struct main_server_st { struct cfg_st *config; struct tun_st *tun; hash_db_st *tls_db; - hash_db_st *cookie_db; + + uint8_t cookie_key[16]; /* tls credentials */ struct tls_st creds; @@ -148,7 +150,7 @@ __attribute__ ((format(printf, 4, 5))) void mslog_hex(const main_server_st * s, const struct proc_st* proc, int priority, const char *prefix, uint8_t* bin, unsigned bin_size); -int open_tun(main_server_st* s, struct lease_st** l); +int open_tun(main_server_st* s, struct lease_st** l, const char* prev_name); int set_tun_mtu(main_server_st* s, struct proc_st * proc, unsigned mtu); int send_auth_reply_msg(main_server_st* s, struct proc_st* proc); diff --git a/src/ocserv-args.c b/src/ocserv-args.c index 3956b1aa..d564f768 100644 --- a/src/ocserv-args.c +++ b/src/ocserv-args.c @@ -2,7 +2,7 @@ * * DO NOT EDIT THIS FILE (ocserv-args.c) * - * It has been AutoGen-ed June 27, 2013 at 05:58:30 PM by AutoGen 5.17.3 + * It has been AutoGen-ed July 1, 2013 at 12:18:22 PM by AutoGen 5.17.3 * From the definitions ocserv-args.def * and the template file options * diff --git a/src/ocserv-args.def b/src/ocserv-args.def index 8e2f7ec7..b4880b40 100644 --- a/src/ocserv-args.def +++ b/src/ocserv-args.def @@ -185,10 +185,6 @@ auth-timeout = 40 # of that cookie. cookie-validity = 172800 -# A cookie database. If not set cookies are stored in memory and -# server restarts won't preserve them. -#cookie-db = /var/tmp/cookies.db - # Script to call when a client connects and obtains an IP # Parameters are passed on the environment. # REASON, USERNAME, GROUPNAME, HOSTNAME (the hostname selected by client), diff --git a/src/ocserv-args.h b/src/ocserv-args.h index 0f6496f8..10f15051 100644 --- a/src/ocserv-args.h +++ b/src/ocserv-args.h @@ -2,7 +2,7 @@ * * DO NOT EDIT THIS FILE (ocserv-args.h) * - * It has been AutoGen-ed June 27, 2013 at 05:58:30 PM by AutoGen 5.17.3 + * It has been AutoGen-ed July 1, 2013 at 12:18:22 PM by AutoGen 5.17.3 * From the definitions ocserv-args.def * and the template file options * diff --git a/src/tun.c b/src/tun.c index e06bc190..1c97485d 100644 --- a/src/tun.c +++ b/src/tun.c @@ -289,7 +289,7 @@ static int set_network_info( main_server_st* s, const struct lease_st *lease) } -int open_tun(main_server_st* s, struct lease_st** l) +int open_tun(main_server_st* s, struct lease_st** l, const char* prev_name) { int tunfd, ret, e; struct ifreq ifr; @@ -298,6 +298,7 @@ int open_tun(main_server_st* s, struct lease_st** l) struct lease_st *last4, *tmp; struct lease_st *last6; unsigned current = s->tun->total; + time_t now = time(0); last4 = last6 = NULL; @@ -305,7 +306,7 @@ int open_tun(main_server_st* s, struct lease_st** l) list_for_each(&s->tun->head, tmp, list) { /* if the device isn't in use by the server and the IPs * are free. */ - if (tmp->in_use == 0) { + if (tmp->in_use == 0 && (tmp->available_at < now || (prev_name != NULL && strcmp(prev_name, tmp->name) == 0))) { if ((tmp->lip6_len != 0 && icmp_ping6(s, (void*)&tmp->lip6, (void*)&tmp->rip6) == 0) || (tmp->lip4_len != 0 && icmp_ping4(s, (void*)&tmp->lip4, (void*)&tmp->rip4) == 0)) { lease = tmp; @@ -434,6 +435,7 @@ int open_tun(main_server_st* s, struct lease_st** l) } lease->in_use = 1; + lease->available_at = now + s->config->cookie_validity; lease->fd = tunfd; *l = lease; diff --git a/src/tun.h b/src/tun.h index 5c225955..0e5288bd 100644 --- a/src/tun.h +++ b/src/tun.h @@ -11,6 +11,7 @@ struct lease_st { char name[IFNAMSIZ]; unsigned int tun_nr; unsigned int in_use; + time_t available_at; /* when it will be available */ struct sockaddr_storage rip4; socklen_t rip4_len; diff --git a/src/vpn.h b/src/vpn.h index 01980a3a..43bc63a8 100644 --- a/src/vpn.h +++ b/src/vpn.h @@ -113,9 +113,6 @@ struct cfg_st { unsigned rate_limit_ms; /* if non zero force a connection every rate_limit milliseconds */ unsigned ping_leases; /* non zero if we need to ping prior to leasing */ - /* if gdbm is there */ - char* cookie_db_name; - char *connect_script; char *disconnect_script; @@ -144,7 +141,6 @@ struct main_server_st; #define TLS_MASTER_SIZE 48 #define MAX_HOSTNAME_SIZE MAX_USERNAME_SIZE #define MAX_GROUPNAME_SIZE MAX_USERNAME_SIZE -#define COOKIE_SIZE 32 #define MAX_SESSION_DATA_SIZE (4*1024) const char *human_addr(const struct sockaddr *sa, socklen_t salen,