mirror of
https://gitlab.com/openconnect/ocserv.git
synced 2026-02-10 00:37:00 +08:00
several updates in cookies, and tun handling.
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
14
src/main.c
14
src/main.c
@@ -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) {
|
||||
|
||||
|
||||
20
src/main.h
20
src/main.h
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user