mirror of
https://gitlab.com/openconnect/ocserv.git
synced 2026-10-14 02:22:03 +08:00
Cookies are no longer persistent
This commit is contained in:
+1
-1
@@ -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 \
|
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 \
|
config.c pam.c pam.h worker-resume.c worker.h main-resume.c main.h \
|
||||||
worker-extras.c main-auth.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 \
|
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 \
|
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)
|
str.c str.h gettime.h $(CCAN_SOURCES)
|
||||||
|
|||||||
@@ -191,8 +191,6 @@ unsigned j;
|
|||||||
READ_STRING("tls-priorities", config->priorities, 0);
|
READ_STRING("tls-priorities", config->priorities, 0);
|
||||||
READ_STRING("chroot-dir", config->chroot_dir, 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("cookie-validity", config->cookie_validity, 1);
|
||||||
READ_NUMERIC("auth-timeout", config->auth_timeout, 0);
|
READ_NUMERIC("auth-timeout", config->auth_timeout, 0);
|
||||||
READ_NUMERIC("max-clients", config->max_clients, 0);
|
READ_NUMERIC("max-clients", config->max_clients, 0);
|
||||||
@@ -376,7 +374,6 @@ unsigned i;
|
|||||||
DEL(config->cert_group_oid);
|
DEL(config->cert_group_oid);
|
||||||
DEL(config->priorities);
|
DEL(config->priorities);
|
||||||
DEL(config->chroot_dir);
|
DEL(config->chroot_dir);
|
||||||
DEL(config->cookie_db_name);
|
|
||||||
DEL(config->connect_script);
|
DEL(config->connect_script);
|
||||||
DEL(config->disconnect_script);
|
DEL(config->disconnect_script);
|
||||||
|
|
||||||
|
|||||||
@@ -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 <config.h>
|
|
||||||
|
|
||||||
#include <gnutls/gnutls.h>
|
|
||||||
#include <gnutls/crypto.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <limits.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include "setproctitle.h"
|
|
||||||
#include <main.h>
|
|
||||||
#include <cookies.h>
|
|
||||||
|
|
||||||
#ifdef HAVE_GDBM
|
|
||||||
|
|
||||||
# include <gdbm.h>
|
|
||||||
|
|
||||||
/* 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
|
|
||||||
@@ -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 <config.h>
|
|
||||||
|
|
||||||
#include <gnutls/gnutls.h>
|
|
||||||
#include <gnutls/crypto.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <limits.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
|
|
||||||
#include <main.h>
|
|
||||||
#include <cookies.h>
|
|
||||||
#include <ccan/htable/htable.h>
|
|
||||||
#include <ccan/hash/hash.h>
|
|
||||||
|
|
||||||
#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,
|
|
||||||
};
|
|
||||||
+83
-20
@@ -35,28 +35,91 @@
|
|||||||
#include <main.h>
|
#include <main.h>
|
||||||
#include <cookies.h>
|
#include <cookies.h>
|
||||||
|
|
||||||
cookie_store_fn store_cookie;
|
int decrypt_cookie(main_server_st * s, const uint8_t* cookie, unsigned cookie_size,
|
||||||
cookie_retrieve_fn retrieve_cookie;
|
struct stored_cookie_st* sc)
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
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 (cookie_size != COOKIE_SIZE)
|
||||||
if (s->config->cookie_db_name != NULL)
|
return -1;
|
||||||
funcs = &gdbm_cookie_funcs;
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
funcs = &hash_cookie_funcs;
|
|
||||||
|
|
||||||
cookie_db_deinit = funcs->deinit;
|
ret = gnutls_cipher_init(&h, GNUTLS_CIPHER_AES_128_GCM, &key, &iv);
|
||||||
expire_cookies = funcs->expire;
|
if (ret < 0)
|
||||||
erase_cookies = funcs->erase;
|
return -1;
|
||||||
store_cookie = funcs->store;
|
|
||||||
retrieve_cookie = funcs->retrieve;
|
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);
|
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-30
@@ -2,44 +2,22 @@
|
|||||||
#define COOKIES_H
|
#define COOKIES_H
|
||||||
|
|
||||||
#include <vpn.h>
|
#include <vpn.h>
|
||||||
#include <main.h>
|
|
||||||
|
|
||||||
struct stored_cookie_st {
|
struct __attribute__ ((__packed__)) stored_cookie_st {
|
||||||
uint8_t cookie[COOKIE_SIZE];
|
|
||||||
char username[MAX_USERNAME_SIZE];
|
char username[MAX_USERNAME_SIZE];
|
||||||
char groupname[MAX_GROUPNAME_SIZE];
|
char groupname[MAX_GROUPNAME_SIZE];
|
||||||
char hostname[MAX_HOSTNAME_SIZE];
|
char hostname[MAX_HOSTNAME_SIZE];
|
||||||
uint8_t session_id[GNUTLS_MAX_SESSION_ID];
|
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);
|
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
|
#endif
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#include <net/if.h>
|
#include <net/if.h>
|
||||||
#include <vpn.h>
|
#include <vpn.h>
|
||||||
#include <tlslib.h>
|
#include <tlslib.h>
|
||||||
|
#include <cookies.h>
|
||||||
|
|
||||||
#define MAX_MSG_SIZE 256
|
#define MAX_MSG_SIZE 256
|
||||||
|
|
||||||
|
|||||||
@@ -27,6 +27,7 @@
|
|||||||
|
|
||||||
#include <vpn.h>
|
#include <vpn.h>
|
||||||
#include <worker.h>
|
#include <worker.h>
|
||||||
|
#include <main.h>
|
||||||
|
|
||||||
const char *human_addr(const struct sockaddr *sa, socklen_t salen,
|
const char *human_addr(const struct sockaddr *sa, socklen_t salen,
|
||||||
void *_buf, size_t buflen)
|
void *_buf, size_t buflen)
|
||||||
|
|||||||
+22
-45
@@ -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)
|
const struct cmd_auth_cookie_req_st * req)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
struct stored_cookie_st *sc;
|
struct stored_cookie_st sc;
|
||||||
time_t now = time(0);
|
time_t now = time(0);
|
||||||
|
|
||||||
sc = malloc(sizeof(*sc));
|
ret = decrypt_cookie(s, req->cookie, sizeof(req->cookie), &sc);
|
||||||
if (sc == NULL)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
ret = retrieve_cookie(s, req->cookie, sizeof(req->cookie), sc);
|
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
ret = -1;
|
ret = -1;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sc->expiration < now) {
|
if (sc.expiration < now) {
|
||||||
ret = -1;
|
ret = -1;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(proc->cookie, req->cookie, sizeof(proc->cookie));
|
memcpy(proc->cookie, req->cookie, sizeof(proc->cookie));
|
||||||
memcpy(proc->username, sc->username, sizeof(proc->username));
|
memcpy(proc->username, sc.username, sizeof(proc->username));
|
||||||
memcpy(proc->groupname, sc->groupname, sizeof(proc->groupname));
|
memcpy(proc->groupname, sc.groupname, sizeof(proc->groupname));
|
||||||
memcpy(proc->hostname, sc->hostname, sizeof(proc->hostname));
|
memcpy(proc->hostname, sc.hostname, sizeof(proc->hostname));
|
||||||
memcpy(proc->session_id, sc->session_id, sizeof(proc->session_id));
|
memcpy(proc->session_id, sc.session_id, sizeof(proc->session_id));
|
||||||
proc->session_id_size = sizeof(proc->session_id);
|
proc->session_id_size = sizeof(proc->session_id);
|
||||||
|
|
||||||
proc->username[sizeof(proc->username)-1] = 0;
|
proc->username[sizeof(proc->username)-1] = 0;
|
||||||
proc->groupname[sizeof(proc->groupname)-1] = 0;
|
proc->groupname[sizeof(proc->groupname)-1] = 0;
|
||||||
proc->hostname[sizeof(proc->hostname)-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;
|
return 0;
|
||||||
cleanup:
|
cleanup:
|
||||||
free(sc);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int generate_and_store_vals(main_server_st *s, struct proc_st* proc)
|
int generate_and_store_vals(main_server_st *s, struct proc_st* proc)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
struct stored_cookie_st *sc;
|
struct stored_cookie_st sc;
|
||||||
|
|
||||||
ret = gnutls_rnd(GNUTLS_RND_RANDOM, proc->cookie, sizeof(proc->cookie));
|
ret = gnutls_rnd(GNUTLS_RND_NONCE, proc->session_id, sizeof(proc->session_id));
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -2;
|
return -1;
|
||||||
ret = gnutls_rnd(GNUTLS_RND_NONCE, proc->session_id, sizeof(proc->session_id));
|
|
||||||
if (ret < 0)
|
proc->session_id_size = sizeof(proc->session_id);
|
||||||
return -2;
|
|
||||||
proc->session_id_size = sizeof(proc->session_id);
|
|
||||||
|
|
||||||
sc = calloc(1, sizeof(*sc));
|
|
||||||
if (sc == NULL)
|
|
||||||
return -2;
|
|
||||||
|
|
||||||
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));
|
sc.expiration = time(0) + s->config->cookie_validity;
|
||||||
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));
|
|
||||||
|
|
||||||
/* the sc pointer stays there */
|
ret = encrypt_cookie(s, proc->cookie, sizeof(proc->cookie), &sc);
|
||||||
ret = store_cookie(s, sc);
|
if (ret < 0)
|
||||||
if (ret < 0) {
|
|
||||||
free(sc);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+6
-4
@@ -147,7 +147,7 @@ fail:
|
|||||||
return ret;
|
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;
|
int ret;
|
||||||
const char* group;
|
const char* group;
|
||||||
@@ -155,7 +155,7 @@ const char* group;
|
|||||||
mslog(s, proc, LOG_DEBUG, "accepting user '%s'", proc->username);
|
mslog(s, proc, LOG_DEBUG, "accepting user '%s'", proc->username);
|
||||||
proc_auth_deinit(s, proc);
|
proc_auth_deinit(s, proc);
|
||||||
|
|
||||||
ret = open_tun(s, &proc->lease);
|
ret = open_tun(s, &proc->lease, prev_user);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -201,6 +201,7 @@ int handle_commands(main_server_st *s, struct proc_st* proc)
|
|||||||
struct iovec iov[2];
|
struct iovec iov[2];
|
||||||
uint8_t cmd;
|
uint8_t cmd;
|
||||||
struct msghdr hdr;
|
struct msghdr hdr;
|
||||||
|
/* FIXME: do not write directly to the union */
|
||||||
union {
|
union {
|
||||||
struct cmd_auth_req_st auth;
|
struct cmd_auth_req_st auth;
|
||||||
struct cmd_auth_cookie_req_st cauth;
|
struct cmd_auth_cookie_req_st cauth;
|
||||||
@@ -347,7 +348,7 @@ int handle_commands(main_server_st *s, struct proc_st* proc)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = accept_user(s, proc, cmd);
|
ret = accept_user(s, proc, cmd, NULL);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
@@ -355,6 +356,7 @@ int handle_commands(main_server_st *s, struct proc_st* proc)
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
case AUTH_COOKIE_REQ:
|
case AUTH_COOKIE_REQ:
|
||||||
|
|
||||||
if (cmd_data_len != sizeof(cmd_data.cauth)) {
|
if (cmd_data_len != sizeof(cmd_data.cauth)) {
|
||||||
mslog(s, proc, LOG_ERR, "error in received message (%u) length.", (unsigned)cmd);
|
mslog(s, proc, LOG_ERR, "error in received message (%u) length.", (unsigned)cmd);
|
||||||
return ERR_BAD_COMMAND;
|
return ERR_BAD_COMMAND;
|
||||||
@@ -366,7 +368,7 @@ int handle_commands(main_server_st *s, struct proc_st* proc)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = accept_user(s, proc, cmd);
|
ret = accept_user(s, proc, cmd, (proc->username[0] != 0)?proc->username:NULL);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-8
@@ -36,6 +36,7 @@
|
|||||||
#include <script-list.h>
|
#include <script-list.h>
|
||||||
|
|
||||||
#include <gnutls/x509.h>
|
#include <gnutls/x509.h>
|
||||||
|
#include <gnutls/crypto.h>
|
||||||
#include <tlslib.h>
|
#include <tlslib.h>
|
||||||
#include "ipc.h"
|
#include "ipc.h"
|
||||||
#include "setproctitle.h"
|
#include "setproctitle.h"
|
||||||
@@ -599,7 +600,6 @@ static void check_other_work(main_server_st *s)
|
|||||||
need_maintainance = 0;
|
need_maintainance = 0;
|
||||||
mslog(s, NULL, LOG_INFO, "Performing maintainance");
|
mslog(s, NULL, LOG_INFO, "Performing maintainance");
|
||||||
expire_tls_sessions(s);
|
expire_tls_sessions(s);
|
||||||
expire_cookies(s);
|
|
||||||
expire_banned(s);
|
expire_banned(s);
|
||||||
alarm(MAINTAINANCE_TIME(s));
|
alarm(MAINTAINANCE_TIME(s));
|
||||||
}
|
}
|
||||||
@@ -655,6 +655,12 @@ int main(int argc, char** argv)
|
|||||||
|
|
||||||
/* Initialize GnuTLS */
|
/* Initialize GnuTLS */
|
||||||
tls_global_init(&s);
|
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 */
|
/* load configuration */
|
||||||
ret = cmd_parser(argc, argv, &config);
|
ret = cmd_parser(argc, argv, &config);
|
||||||
@@ -675,12 +681,6 @@ int main(int argc, char** argv)
|
|||||||
|
|
||||||
main_auth_init(&s);
|
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 */
|
/* Listen to network ports */
|
||||||
ret = listen_ports(&config, &s.llist, config.name);
|
ret = listen_ports(&config, &s.llist, config.name);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
@@ -808,7 +808,6 @@ int main(int argc, char** argv)
|
|||||||
*/
|
*/
|
||||||
close(cmd_fd[0]);
|
close(cmd_fd[0]);
|
||||||
clear_lists(&s);
|
clear_lists(&s);
|
||||||
erase_cookies(&s);
|
|
||||||
|
|
||||||
setproctitle(PACKAGE_NAME"-worker");
|
setproctitle(PACKAGE_NAME"-worker");
|
||||||
kill_on_parent_kill(SIGTERM);
|
kill_on_parent_kill(SIGTERM);
|
||||||
|
|||||||
+5
-3
@@ -8,6 +8,7 @@
|
|||||||
#include <vpn.h>
|
#include <vpn.h>
|
||||||
#include <tlslib.h>
|
#include <tlslib.h>
|
||||||
#include "ipc.h"
|
#include "ipc.h"
|
||||||
|
#include <cookies.h>
|
||||||
|
|
||||||
int cmd_parser (int argc, char **argv, struct cfg_st* config);
|
int cmd_parser (int argc, char **argv, struct cfg_st* config);
|
||||||
void reload_cfg_file(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 groupname[MAX_GROUPNAME_SIZE]; /* the owner's group */
|
||||||
char hostname[MAX_HOSTNAME_SIZE]; /* the requested hostname */
|
char hostname[MAX_HOSTNAME_SIZE]; /* the requested hostname */
|
||||||
uint8_t cookie[COOKIE_SIZE]; /* the cookie associated with the session */
|
uint8_t cookie[COOKIE_SIZE]; /* the cookie associated with the session */
|
||||||
|
|
||||||
void * auth_ctx; /* the context of authentication */
|
void * auth_ctx; /* the context of authentication */
|
||||||
unsigned auth_status; /* PS_AUTH_ */
|
unsigned auth_status; /* PS_AUTH_ */
|
||||||
};
|
};
|
||||||
@@ -99,7 +100,8 @@ typedef struct main_server_st {
|
|||||||
struct cfg_st *config;
|
struct cfg_st *config;
|
||||||
struct tun_st *tun;
|
struct tun_st *tun;
|
||||||
hash_db_st *tls_db;
|
hash_db_st *tls_db;
|
||||||
hash_db_st *cookie_db;
|
|
||||||
|
uint8_t cookie_key[16];
|
||||||
|
|
||||||
/* tls credentials */
|
/* tls credentials */
|
||||||
struct tls_st creds;
|
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,
|
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 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 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);
|
int send_auth_reply_msg(main_server_st* s, struct proc_st* proc);
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
*
|
*
|
||||||
* DO NOT EDIT THIS FILE (ocserv-args.c)
|
* 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
|
* From the definitions ocserv-args.def
|
||||||
* and the template file options
|
* and the template file options
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -185,10 +185,6 @@ auth-timeout = 40
|
|||||||
# of that cookie.
|
# of that cookie.
|
||||||
cookie-validity = 172800
|
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
|
# Script to call when a client connects and obtains an IP
|
||||||
# Parameters are passed on the environment.
|
# Parameters are passed on the environment.
|
||||||
# REASON, USERNAME, GROUPNAME, HOSTNAME (the hostname selected by client),
|
# REASON, USERNAME, GROUPNAME, HOSTNAME (the hostname selected by client),
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
*
|
*
|
||||||
* DO NOT EDIT THIS FILE (ocserv-args.h)
|
* 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
|
* From the definitions ocserv-args.def
|
||||||
* and the template file options
|
* and the template file options
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -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;
|
int tunfd, ret, e;
|
||||||
struct ifreq ifr;
|
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 *last4, *tmp;
|
||||||
struct lease_st *last6;
|
struct lease_st *last6;
|
||||||
unsigned current = s->tun->total;
|
unsigned current = s->tun->total;
|
||||||
|
time_t now = time(0);
|
||||||
|
|
||||||
last4 = last6 = NULL;
|
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) {
|
list_for_each(&s->tun->head, tmp, list) {
|
||||||
/* if the device isn't in use by the server and the IPs
|
/* if the device isn't in use by the server and the IPs
|
||||||
* are free. */
|
* 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) ||
|
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)) {
|
(tmp->lip4_len != 0 && icmp_ping4(s, (void*)&tmp->lip4, (void*)&tmp->rip4) == 0)) {
|
||||||
lease = tmp;
|
lease = tmp;
|
||||||
@@ -434,6 +435,7 @@ int open_tun(main_server_st* s, struct lease_st** l)
|
|||||||
}
|
}
|
||||||
|
|
||||||
lease->in_use = 1;
|
lease->in_use = 1;
|
||||||
|
lease->available_at = now + s->config->cookie_validity;
|
||||||
lease->fd = tunfd;
|
lease->fd = tunfd;
|
||||||
*l = lease;
|
*l = lease;
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ struct lease_st {
|
|||||||
char name[IFNAMSIZ];
|
char name[IFNAMSIZ];
|
||||||
unsigned int tun_nr;
|
unsigned int tun_nr;
|
||||||
unsigned int in_use;
|
unsigned int in_use;
|
||||||
|
time_t available_at; /* when it will be available */
|
||||||
|
|
||||||
struct sockaddr_storage rip4;
|
struct sockaddr_storage rip4;
|
||||||
socklen_t rip4_len;
|
socklen_t rip4_len;
|
||||||
|
|||||||
@@ -113,9 +113,6 @@ struct cfg_st {
|
|||||||
unsigned rate_limit_ms; /* if non zero force a connection every rate_limit milliseconds */
|
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 */
|
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 *connect_script;
|
||||||
char *disconnect_script;
|
char *disconnect_script;
|
||||||
|
|
||||||
@@ -144,7 +141,6 @@ struct main_server_st;
|
|||||||
#define TLS_MASTER_SIZE 48
|
#define TLS_MASTER_SIZE 48
|
||||||
#define MAX_HOSTNAME_SIZE MAX_USERNAME_SIZE
|
#define MAX_HOSTNAME_SIZE MAX_USERNAME_SIZE
|
||||||
#define MAX_GROUPNAME_SIZE MAX_USERNAME_SIZE
|
#define MAX_GROUPNAME_SIZE MAX_USERNAME_SIZE
|
||||||
#define COOKIE_SIZE 32
|
|
||||||
#define MAX_SESSION_DATA_SIZE (4*1024)
|
#define MAX_SESSION_DATA_SIZE (4*1024)
|
||||||
|
|
||||||
const char *human_addr(const struct sockaddr *sa, socklen_t salen,
|
const char *human_addr(const struct sockaddr *sa, socklen_t salen,
|
||||||
|
|||||||
Reference in New Issue
Block a user