Cookies are no longer persistent

This commit is contained in:
Nikos Mavrogiannopoulos
2013-07-01 12:18:51 +02:00
parent e7aa89dc96
commit 126c52ab5c
18 changed files with 141 additions and 515 deletions
+1 -1
View File
@@ -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)
-3
View File
@@ -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);
-190
View File
@@ -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
-199
View File
@@ -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
View File
@@ -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
View File
@@ -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
+1
View File
@@ -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
+1
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
* *
-4
View File
@@ -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
View File
@@ -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
* *
+4 -2
View File
@@ -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;
+1
View File
@@ -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;
-4
View File
@@ -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,