several updates in cookies, and tun handling.

This commit is contained in:
Nikos Mavrogiannopoulos
2013-02-08 18:22:18 +01:00
parent 1f5f288742
commit 4434fd70fe
7 changed files with 63 additions and 39 deletions

View File

@@ -39,7 +39,7 @@
#ifdef HAVE_GDBM
static
int store_cookie_gdbm(main_server_st *s, const struct stored_cookie_st* sc)
int store_cookie_gdbm(main_server_st *s, struct stored_cookie_st* sc)
{
GDBM_FILE dbf;
datum key;
@@ -66,6 +66,7 @@ int ret;
ret = 0;
finish:
free(sc);
gdbm_close(dbf);
return ret;
}

View File

@@ -41,7 +41,7 @@
/* receives allocated data and stores them.
*/
int store_cookie_hash(main_server_st *s, const struct stored_cookie_st* sc)
int store_cookie_hash(main_server_st *s, struct stored_cookie_st* sc)
{
size_t key;

View File

@@ -12,7 +12,7 @@ struct stored_cookie_st {
time_t expiration;
};
typedef int (*cookie_store_fn)(main_server_st *, const struct stored_cookie_st* sc);
typedef int (*cookie_store_fn)(main_server_st *, struct stored_cookie_st* sc);
typedef int (*cookie_retrieve_fn)(main_server_st *, const void* cookie, unsigned cookie_size,
struct stored_cookie_st* sc);

View File

@@ -46,42 +46,36 @@
static int send_auth_reply(main_server_st* s, struct proc_st* proc,
cmd_auth_reply_t r, struct lease_st* lease)
{
struct iovec iov[6];
struct iovec iov[2];
uint8_t cmd[2];
struct msghdr hdr;
union {
struct cmsghdr cm;
char control[CMSG_SPACE(sizeof(int))];
} control_un;
struct cmd_auth_reply_st resp;
struct cmsghdr *cmptr;
memset(&control_un, 0, sizeof(control_un));
memset(&hdr, 0, sizeof(hdr));
cmd[0] = AUTH_REP;
cmd[1] = r;
iov[0].iov_base = cmd;
iov[0].iov_len = 2;
hdr.msg_iovlen++;
hdr.msg_iov = iov;
if (r == REP_AUTH_OK && lease != NULL) {
iov[1].iov_base = proc->cookie;
iov[1].iov_len = sizeof(proc->cookie);
hdr.msg_iovlen++;
cmd[0] = AUTH_REP;
iov[2].iov_base = proc->session_id;
iov[2].iov_len = proc->session_id_size;
iov[0].iov_base = cmd;
iov[0].iov_len = 1;
hdr.msg_iovlen++;
resp.reply = r;
memcpy(resp.cookie, proc->cookie, COOKIE_SIZE);
memcpy(resp.session_id, proc->session_id, sizeof(resp.session_id));
memcpy(resp.vname, lease->name, sizeof(resp.vname));
memcpy(resp.user, proc->username, sizeof(resp.user));
iov[3].iov_base = lease->name;
iov[3].iov_len = sizeof(lease->name);
hdr.msg_iovlen++;
iov[4].iov_base = proc->username;
iov[4].iov_len = MAX_USERNAME_SIZE;
iov[1].iov_base = &resp;
iov[1].iov_len = sizeof(resp);
hdr.msg_iovlen++;
/* Send the tun fd */
@@ -93,6 +87,13 @@ static int send_auth_reply(main_server_st* s, struct proc_st* proc,
cmptr->cmsg_level = SOL_SOCKET;
cmptr->cmsg_type = SCM_RIGHTS;
memcpy(CMSG_DATA(cmptr), &lease->fd, sizeof(int));
} else {
cmd[0] = AUTH_REP;
cmd[1] = REP_AUTH_FAILED;
iov[0].iov_base = cmd;
iov[0].iov_len = 2;
hdr.msg_iovlen++;
}
return(sendmsg(proc->fd, &hdr, 0));
@@ -109,10 +110,9 @@ struct stored_cookie_st sc;
return -1;
}
ret = 0; /* cookie was found and valid */
memcpy(proc->cookie, req->cookie, sizeof(proc->cookie));
memcpy(proc->username, sc.username, sizeof(proc->username));
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);
@@ -322,10 +322,11 @@ int handle_commands(main_server_st *s, struct proc_st* proc)
ret = generate_and_store_vals(s, proc);
if (ret < 0)
return -2;
mslog(s, proc, LOG_INFO, "User '%s' authenticated", proc->username);
} else {
mslog(s, proc, LOG_INFO, "User '%s' re-authenticated (using cookie)", proc->username);
}
mslog(s, proc, LOG_INFO, "User '%s' authenticated", proc->username);
ret = send_auth_reply(s, proc, REP_AUTH_OK, lease);
if (ret < 0) {
mslog(s, proc, LOG_ERR, "Could not send reply cmd (pid: %d, peer: %s).", proc->pid, peer_ip);

View File

@@ -384,6 +384,7 @@ static void handle_term(int signo)
terminate = 1;
}
#define RECORD_PAYLOAD_POS 13
#define HANDSHAKE_SESSION_ID_POS 46
static int forward_udp_to_owner(main_server_st* s, struct listener_st *listener)
@@ -413,17 +414,24 @@ int connected = 0;
goto fail;
/* check version */
if (buffer[1] != 254 && (buffer[1] != 1 && buffer[0] != 0)) {
mslog(s, NULL, LOG_ERR, "Unknown DTLS version: %u.%u", (unsigned)buffer[1], (unsigned)buffer[2]);
if (buffer[1] != 254 && (buffer[1] != 1 && buffer[2] != 0)) {
mslog(s, NULL, LOG_INFO, "Unknown DTLS version: %u.%u", (unsigned)buffer[1], (unsigned)buffer[2]);
goto fail;
}
if (buffer[0] != 22) {
mslog(s, NULL, LOG_INFO, "Unexpected DTLS content type: %u", (unsigned int)buffer[0]);
goto fail;
}
mslog(s, NULL, LOG_DEBUG, "DTLS record version: %u.%u", (unsigned int)buffer[1], (unsigned int)buffer[2]);
mslog(s, NULL, LOG_DEBUG, "DTLS hello version: %u.%u", (unsigned int)buffer[RECORD_PAYLOAD_POS], (unsigned int)buffer[RECORD_PAYLOAD_POS+1]);
/* read session_id */
session_id_size = buffer[RECORD_PAYLOAD_POS+HANDSHAKE_SESSION_ID_POS];
session_id = &buffer[RECORD_PAYLOAD_POS+HANDSHAKE_SESSION_ID_POS+1];
/* search for the IP and the session ID in all procs */
list_for_each(&s->clist->head, ctmp, list) {
if (ctmp->udp_fd_received == 0 && session_id_size == ctmp->session_id_size &&
memcmp(session_id, ctmp->session_id, session_id_size) == 0) {

View File

@@ -31,18 +31,24 @@ struct proc_st {
struct list_node list;
int fd;
pid_t pid;
unsigned udp_fd_received; /* if the corresponding process has received a UDP fd */
/* the tun lease this process has */
struct lease_st* lease;
struct sockaddr_storage remote_addr; /* peer address */
socklen_t remote_addr_len;
/* The DTLS session ID associated with the TLS session
* it is either generated or restored from a cookie.
*/
uint8_t session_id[GNUTLS_MAX_SESSION_ID];
unsigned session_id_size; /* would act as a flag if session_id is set */
/* The following are set by the worker process (or by a stored cookie) */
char username[MAX_USERNAME_SIZE]; /* the owner */
char hostname[MAX_HOSTNAME_SIZE]; /* the requested hostname */
uint8_t cookie[COOKIE_SIZE]; /* the cookie associated with the session */
/* The DTLS session ID associated with the TLS session */
uint8_t session_id[GNUTLS_MAX_SESSION_ID];
unsigned session_id_size; /* would act as a flag if session_id is set */
unsigned udp_fd_received;
/* the tun lease this process has */
struct lease_st* lease;
};
struct proc_list_st {

View File

@@ -439,6 +439,7 @@ static int set_tun_mtu(struct worker_st* ws, unsigned mtu)
int fd, ret, e;
struct ifreq ifr;
oclog(ws, LOG_DEBUG, "setting tun MTU to %u", mtu);
fd = socket(AF_INET, SOCK_STREAM, 0);
if (fd == -1)
return -1;
@@ -450,7 +451,7 @@ struct ifreq ifr;
ret = ioctl(fd, SIOCSIFMTU, &ifr);
if (ret != 0) {
e = errno;
oclog(ws, LOG_DEBUG, "ioctl SIOCSIFMTU error: %s", strerror(e));
oclog(ws, LOG_INFO, "ioctl SIOCSIFMTU error: %s", strerror(e));
ret = -1;
goto fail;
}
@@ -630,6 +631,7 @@ static
int mtu_not_ok(worker_st* ws, unsigned *mtu)
{
ws->last_bad_mtu = *mtu;
ws->last_good_mtu = (*mtu)/2;
@@ -638,6 +640,9 @@ int mtu_not_ok(worker_st* ws, unsigned *mtu)
*mtu = ws->last_good_mtu;
gnutls_dtls_set_data_mtu (ws->dtls_session, *mtu);
oclog(ws, LOG_DEBUG, "MTU %u is too large, switching to %u", ws->last_bad_mtu, *mtu);
set_tun_mtu(ws, *mtu);
return 0;
@@ -790,8 +795,10 @@ unsigned mtu_overhead, dtls_mtu = 0, tls_mtu = 0;
SEND_ERR(ret);
tls_mtu = vinfo.mtu - 8;
if (req->cstp_mtu > 0)
if (req->cstp_mtu > 0) {
tls_mtu = MIN(tls_mtu, req->cstp_mtu);
oclog(ws, LOG_DEBUG, "peer CSTP MTU is %u", req->cstp_mtu);
}
tls_mtu = MIN(sizeof(buffer)-8, tls_mtu);
ret = tls_printf(ws->session, "X-CSTP-MTU: %u\r\n", tls_mtu);
@@ -827,9 +834,10 @@ unsigned mtu_overhead, dtls_mtu = 0, tls_mtu = 0;
if (req->dtls_mtu > 0) {
dtls_mtu = MIN(req->dtls_mtu, dtls_mtu);
oclog(ws, LOG_DEBUG, "peer DTLS MTU is %u", req->dtls_mtu);
}
dtls_mtu = MIN(sizeof(buffer)-1, dtls_mtu);
dtls_mtu = MIN(sizeof(buffer)-1, dtls_mtu);
tls_printf(ws->session, "X-DTLS-MTU: %u\r\n", dtls_mtu);
}