mirror of
https://gitlab.com/openconnect/ocserv.git
synced 2026-10-14 02:22:03 +08:00
Allow the CSTP layer to operate without TLS
That also introduces a unix domain socket under which connections to the server can occur.
This commit is contained in:
@@ -49,6 +49,10 @@ max-same-clients = 2
|
|||||||
tcp-port = 443
|
tcp-port = 443
|
||||||
udp-port = 443
|
udp-port = 443
|
||||||
|
|
||||||
|
# Accept connections using a socket file. The connections are
|
||||||
|
# forwarded without SSL/TLS.
|
||||||
|
unix-conn-file = /var/run/ocserv-conn.socket
|
||||||
|
|
||||||
# Keepalive in seconds
|
# Keepalive in seconds
|
||||||
keepalive = 32400
|
keepalive = 32400
|
||||||
|
|
||||||
|
|||||||
@@ -82,6 +82,7 @@ static struct cfg_options available_options[] = {
|
|||||||
{ .name = "disconnect-script", .type = OPTION_STRING, .mandatory = 0 },
|
{ .name = "disconnect-script", .type = OPTION_STRING, .mandatory = 0 },
|
||||||
{ .name = "pid-file", .type = OPTION_STRING, .mandatory = 0 },
|
{ .name = "pid-file", .type = OPTION_STRING, .mandatory = 0 },
|
||||||
{ .name = "socket-file", .type = OPTION_STRING, .mandatory = 1 },
|
{ .name = "socket-file", .type = OPTION_STRING, .mandatory = 1 },
|
||||||
|
{ .name = "unix-conn-file", .type = OPTION_STRING, .mandatory = 0 },
|
||||||
{ .name = "occtl-socket-file", .type = OPTION_STRING, .mandatory = 0 },
|
{ .name = "occtl-socket-file", .type = OPTION_STRING, .mandatory = 0 },
|
||||||
{ .name = "banner", .type = OPTION_STRING, .mandatory = 0 },
|
{ .name = "banner", .type = OPTION_STRING, .mandatory = 0 },
|
||||||
{ .name = "use-seccomp", .type = OPTION_BOOLEAN, .mandatory = 0 },
|
{ .name = "use-seccomp", .type = OPTION_BOOLEAN, .mandatory = 0 },
|
||||||
@@ -436,6 +437,7 @@ unsigned force_cert_auth;
|
|||||||
if (reload == 0 && pid_file[0] == 0)
|
if (reload == 0 && pid_file[0] == 0)
|
||||||
READ_STATIC_STRING("pid-file", pid_file);
|
READ_STATIC_STRING("pid-file", pid_file);
|
||||||
|
|
||||||
|
READ_STRING("unix-conn-file", config->unix_conn_file);
|
||||||
READ_STRING("socket-file", config->socket_file_prefix);
|
READ_STRING("socket-file", config->socket_file_prefix);
|
||||||
READ_STRING("occtl-socket-file", config->occtl_socket_file);
|
READ_STRING("occtl-socket-file", config->occtl_socket_file);
|
||||||
if (config->occtl_socket_file == NULL)
|
if (config->occtl_socket_file == NULL)
|
||||||
|
|||||||
+62
-12
@@ -31,6 +31,8 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <sys/resource.h>
|
#include <sys/resource.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
#include <cloexec.h>
|
#include <cloexec.h>
|
||||||
#ifdef HAVE_MALLOC_TRIM
|
#ifdef HAVE_MALLOC_TRIM
|
||||||
# include <malloc.h> /* for malloc_trim() */
|
# include <malloc.h> /* for malloc_trim() */
|
||||||
@@ -90,7 +92,7 @@ static void add_listener(void *pool, struct listen_list_st *list,
|
|||||||
tmp = talloc_zero(pool, struct listener_st);
|
tmp = talloc_zero(pool, struct listener_st);
|
||||||
tmp->fd = fd;
|
tmp->fd = fd;
|
||||||
tmp->family = family;
|
tmp->family = family;
|
||||||
tmp->socktype = socktype;
|
tmp->sock_type = socktype;
|
||||||
tmp->protocol = protocol;
|
tmp->protocol = protocol;
|
||||||
|
|
||||||
tmp->addr_len = addr_len;
|
tmp->addr_len = addr_len;
|
||||||
@@ -135,12 +137,13 @@ int val;
|
|||||||
|
|
||||||
static
|
static
|
||||||
int _listen_ports(void *pool, struct cfg_st* config,
|
int _listen_ports(void *pool, struct cfg_st* config,
|
||||||
struct addrinfo *res, struct listen_list_st *list)
|
struct addrinfo *res, struct listen_list_st *list, int udp)
|
||||||
{
|
{
|
||||||
struct addrinfo *ptr;
|
struct addrinfo *ptr;
|
||||||
int s, y;
|
int s, y, e, ret;
|
||||||
const char* type = NULL;
|
const char* type = NULL;
|
||||||
char buf[512];
|
char buf[512];
|
||||||
|
struct sockaddr_un sa;
|
||||||
|
|
||||||
for (ptr = res; ptr != NULL; ptr = ptr->ai_next) {
|
for (ptr = res; ptr != NULL; ptr = ptr->ai_next) {
|
||||||
if (ptr->ai_family != AF_INET && ptr->ai_family != AF_INET6)
|
if (ptr->ai_family != AF_INET && ptr->ai_family != AF_INET6)
|
||||||
@@ -193,7 +196,7 @@ int _listen_ports(void *pool, struct cfg_st* config,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ptr->ai_socktype == SOCK_STREAM) {
|
if (ptr->ai_socktype == SOCK_STREAM) {
|
||||||
if (listen(s, 10) < 0) {
|
if (listen(s, 1024) < 0) {
|
||||||
perror("listen() failed");
|
perror("listen() failed");
|
||||||
force_close(s);
|
force_close(s);
|
||||||
return -1;
|
return -1;
|
||||||
@@ -202,11 +205,55 @@ int _listen_ports(void *pool, struct cfg_st* config,
|
|||||||
|
|
||||||
set_common_socket_options(s);
|
set_common_socket_options(s);
|
||||||
|
|
||||||
add_listener(pool, list, s, ptr->ai_family, ptr->ai_socktype,
|
add_listener(pool, list, s, ptr->ai_family, ptr->ai_socktype==SOCK_STREAM?SOCK_TYPE_TCP:SOCK_TYPE_UDP,
|
||||||
ptr->ai_protocol, ptr->ai_addr, ptr->ai_addrlen);
|
ptr->ai_protocol, ptr->ai_addr, ptr->ai_addrlen);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* open the UNIX domain socket to accept connections */
|
||||||
|
if (udp == 0 && config->unix_conn_file) {
|
||||||
|
memset(&sa, 0, sizeof(sa));
|
||||||
|
sa.sun_family = AF_UNIX;
|
||||||
|
snprintf(sa.sun_path, sizeof(sa.sun_path), "%s", config->unix_conn_file);
|
||||||
|
remove(sa.sun_path);
|
||||||
|
|
||||||
|
if (config->foreground != 0)
|
||||||
|
fprintf(stderr, "listening (UNIX) on %s...\n",
|
||||||
|
sa.sun_path);
|
||||||
|
|
||||||
|
s = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||||
|
if (s == -1) {
|
||||||
|
e = errno;
|
||||||
|
fprintf(stderr, "could not create socket '%s': %s", sa.sun_path,
|
||||||
|
strerror(e));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
umask(066);
|
||||||
|
ret = bind(s, (struct sockaddr *)&sa, SUN_LEN(&sa));
|
||||||
|
if (ret == -1) {
|
||||||
|
e = errno;
|
||||||
|
fprintf(stderr, "could not bind socket '%s': %s", sa.sun_path,
|
||||||
|
strerror(e));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = chown(sa.sun_path, config->uid, config->gid);
|
||||||
|
if (ret == -1) {
|
||||||
|
e = errno;
|
||||||
|
fprintf(stderr, "could not chown socket '%s': %s", sa.sun_path,
|
||||||
|
strerror(e));
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = listen(s, 1024);
|
||||||
|
if (ret == -1) {
|
||||||
|
e = errno;
|
||||||
|
fprintf(stderr, "could not listen to socket '%s': %s",
|
||||||
|
sa.sun_path, strerror(e));
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
add_listener(pool, list, s, AF_UNIX, SOCK_TYPE_UNIX, 0, (struct sockaddr *)&sa, sizeof(sa));
|
||||||
|
}
|
||||||
fflush(stderr);
|
fflush(stderr);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -280,7 +327,7 @@ listen_ports(void *pool, struct cfg_st* config,
|
|||||||
config->udp_port = ntohs(((struct sockaddr_in6*)&tmp_sock)->sin6_port);
|
config->udp_port = ntohs(((struct sockaddr_in6*)&tmp_sock)->sin6_port);
|
||||||
}
|
}
|
||||||
|
|
||||||
add_listener(pool, list, fd, family, type, 0, (struct sockaddr*)&tmp_sock, tmp_sock_len);
|
add_listener(pool, list, fd, family, type==SOCK_STREAM?SOCK_TYPE_TCP:SOCK_TYPE_UDP, 0, (struct sockaddr*)&tmp_sock, tmp_sock_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (list->total == 0) {
|
if (list->total == 0) {
|
||||||
@@ -317,7 +364,7 @@ listen_ports(void *pool, struct cfg_st* config,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = _listen_ports(pool, config, res, list);
|
ret = _listen_ports(pool, config, res, list, 0);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -347,7 +394,7 @@ listen_ports(void *pool, struct cfg_st* config,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = _listen_ports(pool, config, res, list);
|
ret = _listen_ports(pool, config, res, list, 1);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -371,7 +418,7 @@ int s, y, e;
|
|||||||
force_close(l->fd);
|
force_close(l->fd);
|
||||||
l->fd = -1;
|
l->fd = -1;
|
||||||
|
|
||||||
s = socket(l->family, l->socktype, l->protocol);
|
s = socket(l->family, SOCK_DGRAM, l->protocol);
|
||||||
if (s < 0) {
|
if (s < 0) {
|
||||||
perror("socket() failed");
|
perror("socket() failed");
|
||||||
return -1;
|
return -1;
|
||||||
@@ -1039,8 +1086,10 @@ int main(int argc, char** argv)
|
|||||||
/* Check for new connections to accept */
|
/* Check for new connections to accept */
|
||||||
list_for_each(&s->listen_list.head, ltmp, list) {
|
list_for_each(&s->listen_list.head, ltmp, list) {
|
||||||
set = FD_ISSET(ltmp->fd, &rd_set);
|
set = FD_ISSET(ltmp->fd, &rd_set);
|
||||||
if (set && ltmp->socktype == SOCK_STREAM) {
|
if (set && (ltmp->sock_type == SOCK_TYPE_TCP || ltmp->sock_type == SOCK_TYPE_UNIX)) {
|
||||||
/* connection on TCP port */
|
/* connection on TCP port */
|
||||||
|
int stype = ltmp->sock_type;
|
||||||
|
|
||||||
ws->remote_addr_len = sizeof(ws->remote_addr);
|
ws->remote_addr_len = sizeof(ws->remote_addr);
|
||||||
fd = accept(ltmp->fd, (void*)&ws->remote_addr, &ws->remote_addr_len);
|
fd = accept(ltmp->fd, (void*)&ws->remote_addr, &ws->remote_addr_len);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
@@ -1095,6 +1144,7 @@ int main(int argc, char** argv)
|
|||||||
ws->tun_fd = -1;
|
ws->tun_fd = -1;
|
||||||
ws->udp_fd = -1;
|
ws->udp_fd = -1;
|
||||||
ws->conn_fd = fd;
|
ws->conn_fd = fd;
|
||||||
|
ws->conn_type = stype;
|
||||||
ws->creds = &creds;
|
ws->creds = &creds;
|
||||||
|
|
||||||
/* Drop privileges after this point */
|
/* Drop privileges after this point */
|
||||||
@@ -1132,7 +1182,7 @@ fork_failed:
|
|||||||
|
|
||||||
if (s->config->rate_limit_ms > 0)
|
if (s->config->rate_limit_ms > 0)
|
||||||
ms_sleep(s->config->rate_limit_ms);
|
ms_sleep(s->config->rate_limit_ms);
|
||||||
} else if (set && ltmp->socktype == SOCK_DGRAM) {
|
} else if (set && ltmp->sock_type == SOCK_TYPE_UDP) {
|
||||||
/* connection on UDP port */
|
/* connection on UDP port */
|
||||||
ret = forward_udp_to_owner(s, ltmp);
|
ret = forward_udp_to_owner(s, ltmp);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
|||||||
+1
-1
@@ -52,7 +52,7 @@ extern unsigned int need_maintenance;
|
|||||||
struct listener_st {
|
struct listener_st {
|
||||||
struct list_node list;
|
struct list_node list;
|
||||||
int fd;
|
int fd;
|
||||||
int socktype;
|
sock_type_t sock_type;
|
||||||
|
|
||||||
struct sockaddr_storage addr; /* local socket address */
|
struct sockaddr_storage addr; /* local socket address */
|
||||||
socklen_t addr_len;
|
socklen_t addr_len;
|
||||||
|
|||||||
@@ -124,6 +124,10 @@ max-same-clients = 2
|
|||||||
tcp-port = 3333
|
tcp-port = 3333
|
||||||
udp-port = 3333
|
udp-port = 3333
|
||||||
|
|
||||||
|
# Accept connections using a socket file. The connections are
|
||||||
|
# forwarded without SSL/TLS.
|
||||||
|
#unix-conn-file = /var/run/ocserv-conn.socket
|
||||||
|
|
||||||
# Keepalive in seconds
|
# Keepalive in seconds
|
||||||
keepalive = 32400
|
keepalive = 32400
|
||||||
|
|
||||||
|
|||||||
+115
-51
@@ -41,56 +41,64 @@
|
|||||||
#include <common.h>
|
#include <common.h>
|
||||||
#include <sys/un.h>
|
#include <sys/un.h>
|
||||||
#include <sys/uio.h>
|
#include <sys/uio.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <netinet/tcp.h>
|
||||||
#include <c-ctype.h>
|
#include <c-ctype.h>
|
||||||
|
|
||||||
ssize_t tls_send(gnutls_session_t session, const void *data,
|
void cstp_cork(worker_st *ws)
|
||||||
|
{
|
||||||
|
if (ws->session) {
|
||||||
|
gnutls_record_cork(ws->session);
|
||||||
|
} else {
|
||||||
|
#ifdef __linux__
|
||||||
|
int state = 1;
|
||||||
|
setsockopt(ws->conn_fd, IPPROTO_TCP, TCP_CORK, &state, sizeof(state));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int cstp_uncork(worker_st *ws)
|
||||||
|
{
|
||||||
|
if (ws->session) {
|
||||||
|
return gnutls_record_uncork(ws->session, GNUTLS_RECORD_WAIT);
|
||||||
|
} else {
|
||||||
|
#ifdef __linux__
|
||||||
|
int state = 0;
|
||||||
|
setsockopt(ws->conn_fd, IPPROTO_TCP, TCP_CORK, &state, sizeof(state));
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ssize_t cstp_send(worker_st *ws, const void *data,
|
||||||
size_t data_size)
|
size_t data_size)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
int left = data_size;
|
int left = data_size;
|
||||||
const uint8_t* p = data;
|
const uint8_t* p = data;
|
||||||
|
|
||||||
while(left > 0) {
|
if (ws->session != NULL) {
|
||||||
ret = gnutls_record_send(session, p, data_size);
|
while(left > 0) {
|
||||||
if (ret < 0 && (ret != GNUTLS_E_AGAIN && ret != GNUTLS_E_INTERRUPTED)) {
|
ret = gnutls_record_send(ws->session, p, data_size);
|
||||||
return ret;
|
if (ret < 0 && (ret != GNUTLS_E_AGAIN && ret != GNUTLS_E_INTERRUPTED)) {
|
||||||
}
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
if (ret > 0) {
|
if (ret > 0) {
|
||||||
left -= ret;
|
left -= ret;
|
||||||
p += ret;
|
p += ret;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return data_size;
|
||||||
|
} else {
|
||||||
|
return force_write(ws->conn_fd, data, data_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
return data_size;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Same as tls_send() but will not retry on EAGAIN errors */
|
ssize_t cstp_send_file(worker_st *ws, const char *file)
|
||||||
ssize_t tls_send_nb(gnutls_session_t session, const void *data,
|
|
||||||
size_t data_size)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
int left = data_size;
|
|
||||||
const uint8_t* p = data;
|
|
||||||
|
|
||||||
while(left > 0) {
|
|
||||||
ret = gnutls_record_send(session, p, data_size);
|
|
||||||
if (ret < 0 && ret != GNUTLS_E_INTERRUPTED) {
|
|
||||||
if (ret == GNUTLS_E_AGAIN)
|
|
||||||
return data_size;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ret > 0) {
|
|
||||||
left -= ret;
|
|
||||||
p += ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return data_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
ssize_t tls_send_file(gnutls_session_t session, const char *file)
|
|
||||||
{
|
{
|
||||||
FILE* fp;
|
FILE* fp;
|
||||||
char buf[512];
|
char buf[512];
|
||||||
@@ -102,8 +110,8 @@ int ret;
|
|||||||
return GNUTLS_E_FILE_ERROR;
|
return GNUTLS_E_FILE_ERROR;
|
||||||
|
|
||||||
while ( (len = fread( buf, 1, sizeof(buf), fp)) > 0) {
|
while ( (len = fread( buf, 1, sizeof(buf), fp)) > 0) {
|
||||||
ret = tls_send(session, buf, len);
|
ret = cstp_send(ws, buf, len);
|
||||||
GNUTLS_FATAL_ERR(ret);
|
FATAL_ERR(ws, ret);
|
||||||
|
|
||||||
total += ret;
|
total += ret;
|
||||||
}
|
}
|
||||||
@@ -113,13 +121,30 @@ int ret;
|
|||||||
return total;
|
return total;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t tls_recv(gnutls_session_t session, void *data, size_t data_size)
|
ssize_t cstp_recv(worker_st *ws, void *data, size_t data_size)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
do {
|
if (ws->session != NULL) {
|
||||||
ret = gnutls_record_recv(session, data, data_size);
|
do {
|
||||||
} while (ret < 0 && (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN));
|
ret = gnutls_record_recv(ws->session, data, data_size);
|
||||||
|
} while (ret < 0 && (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN));
|
||||||
|
} else {
|
||||||
|
ret = force_read_timeout(ws->conn_fd, data, data_size, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t cstp_recv_nb(worker_st *ws, void *data, size_t data_size)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (ws->session != NULL) {
|
||||||
|
ret = gnutls_record_recv(ws->session, data, data_size);
|
||||||
|
} else {
|
||||||
|
ret = recv(ws->conn_fd, data, data_size, 0);
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -132,6 +157,9 @@ unsigned tls_has_session_cert(struct worker_st * ws)
|
|||||||
unsigned int list_size = 0;
|
unsigned int list_size = 0;
|
||||||
const gnutls_datum_t * certs;
|
const gnutls_datum_t * certs;
|
||||||
|
|
||||||
|
if (ws->session == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (ws->cert_auth_ok)
|
if (ws->cert_auth_ok)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
@@ -147,7 +175,7 @@ unsigned tls_has_session_cert(struct worker_st * ws)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int __attribute__ ((format(printf, 2, 3)))
|
int __attribute__ ((format(printf, 2, 3)))
|
||||||
tls_printf(gnutls_session_t session, const char *fmt, ...)
|
cstp_printf(worker_st *ws, const char *fmt, ...)
|
||||||
{
|
{
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
va_list args;
|
va_list args;
|
||||||
@@ -158,21 +186,57 @@ int __attribute__ ((format(printf, 2, 3)))
|
|||||||
va_start(args, fmt);
|
va_start(args, fmt);
|
||||||
s = vsnprintf(buf, 1023, fmt, args);
|
s = vsnprintf(buf, 1023, fmt, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
return tls_send(session, buf, s);
|
return cstp_send(ws, buf, s);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void tls_close(gnutls_session_t session)
|
void cstp_close(worker_st *ws)
|
||||||
{
|
{
|
||||||
gnutls_bye(session, GNUTLS_SHUT_WR);
|
if (ws->session) {
|
||||||
gnutls_deinit(session);
|
gnutls_bye(ws->session, GNUTLS_SHUT_WR);
|
||||||
|
gnutls_deinit(ws->session);
|
||||||
|
} else {
|
||||||
|
force_close(ws->conn_fd);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void tls_fatal_close(gnutls_session_t session,
|
void cstp_fatal_close(worker_st *ws,
|
||||||
gnutls_alert_description_t a)
|
gnutls_alert_description_t a)
|
||||||
{
|
{
|
||||||
gnutls_alert_send(session, GNUTLS_AL_FATAL, a);
|
if (ws->session) {
|
||||||
gnutls_deinit(session);
|
gnutls_alert_send(ws->session, GNUTLS_AL_FATAL, a);
|
||||||
|
gnutls_deinit(ws->session);
|
||||||
|
} else {
|
||||||
|
force_close(ws->conn_fd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t dtls_send(worker_st *ws, const void *data,
|
||||||
|
size_t data_size)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
int left = data_size;
|
||||||
|
const uint8_t* p = data;
|
||||||
|
|
||||||
|
while(left > 0) {
|
||||||
|
ret = gnutls_record_send(ws->dtls_session, p, data_size);
|
||||||
|
if (ret < 0 && (ret != GNUTLS_E_AGAIN && ret != GNUTLS_E_INTERRUPTED)) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret > 0) {
|
||||||
|
left -= ret;
|
||||||
|
p += ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return data_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dtls_close(worker_st *ws)
|
||||||
|
{
|
||||||
|
gnutls_bye(ws->dtls_session, GNUTLS_SHUT_WR);
|
||||||
|
gnutls_deinit(ws->dtls_session);
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t rehash(const void *_e, void *unused)
|
static size_t rehash(const void *_e, void *unused)
|
||||||
|
|||||||
+48
-10
@@ -25,6 +25,7 @@
|
|||||||
#include <gnutls/pkcs11.h>
|
#include <gnutls/pkcs11.h>
|
||||||
#include <vpn.h>
|
#include <vpn.h>
|
||||||
#include <ccan/htable/htable.h>
|
#include <ccan/htable/htable.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
@@ -32,6 +33,7 @@ typedef struct
|
|||||||
unsigned int entries;
|
unsigned int entries;
|
||||||
} tls_sess_db_st;
|
} tls_sess_db_st;
|
||||||
|
|
||||||
|
#if 0
|
||||||
#define tls_puts(s, str) tls_send(s, str, sizeof(str)-1)
|
#define tls_puts(s, str) tls_send(s, str, sizeof(str)-1)
|
||||||
|
|
||||||
int __attribute__ ((format(printf, 2, 3)))
|
int __attribute__ ((format(printf, 2, 3)))
|
||||||
@@ -47,6 +49,9 @@ ssize_t tls_send_nb(gnutls_session_t session, const void *data,
|
|||||||
void tls_cork(gnutls_session_t session);
|
void tls_cork(gnutls_session_t session);
|
||||||
int tls_uncork(gnutls_session_t session);
|
int tls_uncork(gnutls_session_t session);
|
||||||
|
|
||||||
|
ssize_t tls_send_file(gnutls_session_t session, const char *file);
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef struct tls_st {
|
typedef struct tls_st {
|
||||||
gnutls_certificate_credentials_t xcred;
|
gnutls_certificate_credentials_t xcred;
|
||||||
gnutls_priority_t cprio;
|
gnutls_priority_t cprio;
|
||||||
@@ -58,18 +63,8 @@ void tls_global_init(struct tls_st *creds);
|
|||||||
void tls_global_deinit(struct tls_st *creds);
|
void tls_global_deinit(struct tls_st *creds);
|
||||||
void tls_load_certs(struct main_server_st* s, struct tls_st *creds);
|
void tls_load_certs(struct main_server_st* s, struct tls_st *creds);
|
||||||
|
|
||||||
ssize_t tls_send_file(gnutls_session_t session, const char *file);
|
|
||||||
size_t tls_get_overhead(gnutls_protocol_t, gnutls_cipher_algorithm_t, gnutls_mac_algorithm_t);
|
size_t tls_get_overhead(gnutls_protocol_t, gnutls_cipher_algorithm_t, gnutls_mac_algorithm_t);
|
||||||
|
|
||||||
#define GNUTLS_FATAL_ERR(x) \
|
|
||||||
if (x < 0 && gnutls_error_is_fatal (x) != 0) { \
|
|
||||||
if (syslog_open) \
|
|
||||||
syslog(LOG_ERR, "GnuTLS error (at %s:%d): %s", __FILE__, __LINE__, gnutls_strerror(x)); \
|
|
||||||
else \
|
|
||||||
fprintf(stderr, "GnuTLS error (at %s:%d): %s\n", __FILE__, __LINE__, gnutls_strerror(x)); \
|
|
||||||
exit(1); \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define GNUTLS_FATAL_ERR_CMD(x, CMD) \
|
#define GNUTLS_FATAL_ERR_CMD(x, CMD) \
|
||||||
if (x < 0 && gnutls_error_is_fatal (x) != 0) { \
|
if (x < 0 && gnutls_error_is_fatal (x) != 0) { \
|
||||||
if (syslog_open) \
|
if (syslog_open) \
|
||||||
@@ -79,6 +74,29 @@ size_t tls_get_overhead(gnutls_protocol_t, gnutls_cipher_algorithm_t, gnutls_mac
|
|||||||
CMD; \
|
CMD; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define GNUTLS_FATAL_ERR(x) GNUTLS_FATAL_ERR_CMD(x, exit(1))
|
||||||
|
|
||||||
|
#define FATAL_ERR_CMD(ws, x, CMD) \
|
||||||
|
if (ws->session != NULL) { \
|
||||||
|
if (x < 0 && gnutls_error_is_fatal (x) != 0) { \
|
||||||
|
if (syslog_open) \
|
||||||
|
syslog(LOG_ERR, "GnuTLS error (at %s:%d): %s", __FILE__, __LINE__, gnutls_strerror(x)); \
|
||||||
|
else \
|
||||||
|
fprintf(stderr, "GnuTLS error (at %s:%d): %s\n", __FILE__, __LINE__, gnutls_strerror(x)); \
|
||||||
|
CMD; \
|
||||||
|
} \
|
||||||
|
} else { \
|
||||||
|
if (x < 0 && errno != EINTR && errno != EAGAIN) { \
|
||||||
|
if (syslog_open) \
|
||||||
|
syslog(LOG_ERR, "socket error (at %s:%d): %s", __FILE__, __LINE__, strerror(errno)); \
|
||||||
|
else \
|
||||||
|
fprintf(stderr, "socket error (at %s:%d): %s\n", __FILE__, __LINE__, strerror(errno)); \
|
||||||
|
CMD; \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define FATAL_ERR(ws, x) FATAL_ERR_CMD(ws, x, exit(1))
|
||||||
|
|
||||||
#define GNUTLS_S_FATAL_ERR(session, x) \
|
#define GNUTLS_S_FATAL_ERR(session, x) \
|
||||||
if (x < 0 && gnutls_error_is_fatal (x) != 0) { \
|
if (x < 0 && gnutls_error_is_fatal (x) != 0) { \
|
||||||
if (syslog_open) { \
|
if (syslog_open) { \
|
||||||
@@ -120,4 +138,24 @@ void tls_cache_init(void *pool, tls_sess_db_st* db);
|
|||||||
void tls_cache_deinit(tls_sess_db_st* db);
|
void tls_cache_deinit(tls_sess_db_st* db);
|
||||||
void *calc_sha1_hash(void *pool, char* file, unsigned cert);
|
void *calc_sha1_hash(void *pool, char* file, unsigned cert);
|
||||||
|
|
||||||
|
/* TLS API */
|
||||||
|
int __attribute__ ((format(printf, 2, 3)))
|
||||||
|
cstp_printf(struct worker_st *ws, const char *fmt, ...);
|
||||||
|
void cstp_close(struct worker_st *ws);
|
||||||
|
void cstp_fatal_close(struct worker_st *ws,
|
||||||
|
gnutls_alert_description_t a);
|
||||||
|
ssize_t cstp_recv(struct worker_st *ws, void *data, size_t data_size);
|
||||||
|
ssize_t cstp_recv_nb(struct worker_st *ws, void *data, size_t data_size);
|
||||||
|
ssize_t cstp_send_file(struct worker_st *ws, const char *file);
|
||||||
|
ssize_t cstp_send(struct worker_st *ws, const void *data,
|
||||||
|
size_t data_size);
|
||||||
|
#define cstp_puts(s, str) cstp_send(s, str, sizeof(str)-1)
|
||||||
|
|
||||||
|
void cstp_cork(struct worker_st *ws);
|
||||||
|
int cstp_uncork(struct worker_st *ws);
|
||||||
|
|
||||||
|
/* DTLS API */
|
||||||
|
void dtls_close(struct worker_st *ws);
|
||||||
|
ssize_t dtls_send(struct worker_st *ws, const void *data, size_t data_size);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -44,6 +44,12 @@
|
|||||||
# define _ATTR_PACKED
|
# define _ATTR_PACKED
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
SOCK_TYPE_TCP,
|
||||||
|
SOCK_TYPE_UDP,
|
||||||
|
SOCK_TYPE_UNIX
|
||||||
|
} sock_type_t;
|
||||||
|
|
||||||
#define DEBUG_BASIC 1
|
#define DEBUG_BASIC 1
|
||||||
#define DEBUG_HTTP 2
|
#define DEBUG_HTTP 2
|
||||||
#define DEBUG_TRANSFERRED 5
|
#define DEBUG_TRANSFERRED 5
|
||||||
@@ -181,6 +187,8 @@ struct cfg_st {
|
|||||||
char *name; /* server name */
|
char *name; /* server name */
|
||||||
unsigned int port;
|
unsigned int port;
|
||||||
unsigned int udp_port;
|
unsigned int udp_port;
|
||||||
|
char* unix_conn_file;
|
||||||
|
|
||||||
char *pin_file;
|
char *pin_file;
|
||||||
char *srk_pin_file;
|
char *srk_pin_file;
|
||||||
char **cert;
|
char **cert;
|
||||||
|
|||||||
+24
-24
@@ -152,12 +152,12 @@ int get_auth_handler2(worker_st * ws, unsigned http_ver, const char *pmsg)
|
|||||||
|
|
||||||
str_init(&str, ws);
|
str_init(&str, ws);
|
||||||
|
|
||||||
tls_cork(ws->session);
|
cstp_cork(ws);
|
||||||
ret = tls_printf(ws->session, "HTTP/1.%u 200 OK\r\n", http_ver);
|
ret = cstp_printf(ws, "HTTP/1.%u 200 OK\r\n", http_ver);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
ret = tls_puts(ws->session, "Connection: Keep-Alive\r\n");
|
ret = cstp_puts(ws, "Connection: Keep-Alive\r\n");
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
@@ -166,7 +166,7 @@ int get_auth_handler2(worker_st * ws, unsigned http_ver, const char *pmsg)
|
|||||||
sizeof(context));
|
sizeof(context));
|
||||||
|
|
||||||
ret =
|
ret =
|
||||||
tls_printf(ws->session,
|
cstp_printf(ws,
|
||||||
"Set-Cookie: webvpncontext=%s; Max-Age=%u; Secure\r\n",
|
"Set-Cookie: webvpncontext=%s; Max-Age=%u; Secure\r\n",
|
||||||
context, (unsigned)MAX_AUTH_SECS);
|
context, (unsigned)MAX_AUTH_SECS);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
@@ -175,7 +175,7 @@ int get_auth_handler2(worker_st * ws, unsigned http_ver, const char *pmsg)
|
|||||||
oclog(ws, LOG_DEBUG, "sent sid: %s", context);
|
oclog(ws, LOG_DEBUG, "sent sid: %s", context);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = tls_puts(ws->session, "Content-Type: text/xml\r\n");
|
ret = cstp_puts(ws, "Content-Type: text/xml\r\n");
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
ret = -1;
|
ret = -1;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
@@ -315,33 +315,33 @@ int get_auth_handler2(worker_st * ws, unsigned http_ver, const char *pmsg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ret =
|
ret =
|
||||||
tls_printf(ws->session, "Content-Length: %u\r\n",
|
cstp_printf(ws, "Content-Length: %u\r\n",
|
||||||
(unsigned int)str.length);
|
(unsigned int)str.length);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
ret = -1;
|
ret = -1;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = tls_puts(ws->session, "X-Transcend-Version: 1\r\n");
|
ret = cstp_puts(ws, "X-Transcend-Version: 1\r\n");
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
ret = -1;
|
ret = -1;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = tls_puts(ws->session, "\r\n");
|
ret = cstp_puts(ws, "\r\n");
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
ret = -1;
|
ret = -1;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = tls_send(ws->session, str.data, str.length);
|
ret = cstp_send(ws, str.data, str.length);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
ret = -1;
|
ret = -1;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ret = tls_uncork(ws->session);
|
ret = cstp_uncork(ws);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
ret = -1;
|
ret = -1;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
@@ -869,17 +869,17 @@ int post_common_handler(worker_st * ws, unsigned http_ver)
|
|||||||
(char *)str_cookie, str_cookie_size);
|
(char *)str_cookie, str_cookie_size);
|
||||||
|
|
||||||
/* reply */
|
/* reply */
|
||||||
tls_cork(ws->session);
|
cstp_cork(ws);
|
||||||
|
|
||||||
ret = tls_printf(ws->session, "HTTP/1.%u 200 OK\r\n", http_ver);
|
ret = cstp_printf(ws, "HTTP/1.%u 200 OK\r\n", http_ver);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
ret = tls_puts(ws->session, "Connection: Keep-Alive\r\n");
|
ret = cstp_puts(ws, "Connection: Keep-Alive\r\n");
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
ret = tls_puts(ws->session, "Content-Type: text/xml\r\n");
|
ret = cstp_puts(ws, "Content-Type: text/xml\r\n");
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
@@ -898,16 +898,16 @@ int post_common_handler(worker_st * ws, unsigned http_ver)
|
|||||||
|
|
||||||
size += success_msg_head_size + success_msg_foot_size;
|
size += success_msg_head_size + success_msg_foot_size;
|
||||||
|
|
||||||
ret = tls_printf(ws->session, "Content-Length: %u\r\n", (unsigned)size);
|
ret = cstp_printf(ws, "Content-Length: %u\r\n", (unsigned)size);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
ret = tls_puts(ws->session, "X-Transcend-Version: 1\r\n");
|
ret = cstp_puts(ws, "X-Transcend-Version: 1\r\n");
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
ret =
|
ret =
|
||||||
tls_printf(ws->session,
|
cstp_printf(ws,
|
||||||
"Set-Cookie: webvpn=%s; Secure\r\n",
|
"Set-Cookie: webvpn=%s; Secure\r\n",
|
||||||
str_cookie);
|
str_cookie);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
@@ -915,21 +915,21 @@ int post_common_handler(worker_st * ws, unsigned http_ver)
|
|||||||
|
|
||||||
#ifdef ANYCONNECT_CLIENT_COMPAT
|
#ifdef ANYCONNECT_CLIENT_COMPAT
|
||||||
ret =
|
ret =
|
||||||
tls_puts(ws->session,
|
cstp_puts(ws,
|
||||||
"Set-Cookie: webvpnc=; expires=Thu, 01 Jan 1970 22:00:00 GMT; path=/; Secure\r\n");
|
"Set-Cookie: webvpnc=; expires=Thu, 01 Jan 1970 22:00:00 GMT; path=/; Secure\r\n");
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (ws->config->xml_config_file) {
|
if (ws->config->xml_config_file) {
|
||||||
ret =
|
ret =
|
||||||
tls_printf(ws->session,
|
cstp_printf(ws,
|
||||||
"Set-Cookie: webvpnc=bu:/&p:t&iu:1/&sh:%s&lu:/+CSCOT+/translation-table?textdomain%%3DAnyConnect%%26type%%3Dmanifest&fu:profiles%%2F%s&fh:%s; path=/; Secure\r\n",
|
"Set-Cookie: webvpnc=bu:/&p:t&iu:1/&sh:%s&lu:/+CSCOT+/translation-table?textdomain%%3DAnyConnect%%26type%%3Dmanifest&fu:profiles%%2F%s&fh:%s; path=/; Secure\r\n",
|
||||||
ws->config->cert_hash,
|
ws->config->cert_hash,
|
||||||
ws->config->xml_config_file,
|
ws->config->xml_config_file,
|
||||||
ws->config->xml_config_hash);
|
ws->config->xml_config_hash);
|
||||||
} else {
|
} else {
|
||||||
ret =
|
ret =
|
||||||
tls_printf(ws->session,
|
cstp_printf(ws,
|
||||||
"Set-Cookie: webvpnc=bu:/&p:t&iu:1/&sh:%s; path=/; Secure\r\n",
|
"Set-Cookie: webvpnc=bu:/&p:t&iu:1/&sh:%s; path=/; Secure\r\n",
|
||||||
ws->config->cert_hash);
|
ws->config->cert_hash);
|
||||||
}
|
}
|
||||||
@@ -939,12 +939,12 @@ int post_common_handler(worker_st * ws, unsigned http_ver)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
ret =
|
ret =
|
||||||
tls_printf(ws->session,
|
cstp_printf(ws,
|
||||||
"\r\n%s%s%s", success_msg_head, msg, success_msg_foot);
|
"\r\n%s%s%s", success_msg_head, msg, success_msg_foot);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
ret = tls_uncork(ws->session);
|
ret = cstp_uncork(ws);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
@@ -1262,9 +1262,9 @@ int post_auth_handler(worker_st * ws, unsigned http_ver)
|
|||||||
|
|
||||||
if (sd != -1)
|
if (sd != -1)
|
||||||
close(sd);
|
close(sd);
|
||||||
tls_printf(ws->session,
|
cstp_printf(ws,
|
||||||
"HTTP/1.1 401 Unauthorized\r\nX-Reason: %s\r\n\r\n",
|
"HTTP/1.1 401 Unauthorized\r\nX-Reason: %s\r\n\r\n",
|
||||||
reason);
|
reason);
|
||||||
tls_fatal_close(ws->session, GNUTLS_A_ACCESS_DENIED);
|
cstp_fatal_close(ws, GNUTLS_A_ACCESS_DENIED);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|||||||
+36
-36
@@ -49,47 +49,47 @@ struct stat st;
|
|||||||
oclog(ws, LOG_HTTP_DEBUG, "requested config: %s", ws->req.url);
|
oclog(ws, LOG_HTTP_DEBUG, "requested config: %s", ws->req.url);
|
||||||
if (ws->config->xml_config_file == NULL) {
|
if (ws->config->xml_config_file == NULL) {
|
||||||
oclog(ws, LOG_INFO, "requested config but no config file is set");
|
oclog(ws, LOG_INFO, "requested config but no config file is set");
|
||||||
tls_printf(ws->session, "HTTP/1.%u 404 Not found\r\n", http_ver);
|
cstp_printf(ws, "HTTP/1.%u 404 Not found\r\n", http_ver);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = stat( ws->config->xml_config_file, &st);
|
ret = stat( ws->config->xml_config_file, &st);
|
||||||
if (ret == -1) {
|
if (ret == -1) {
|
||||||
oclog(ws, LOG_INFO, "cannot load config file '%s'", ws->config->xml_config_file);
|
oclog(ws, LOG_INFO, "cannot load config file '%s'", ws->config->xml_config_file);
|
||||||
tls_printf(ws->session, "HTTP/1.%u 404 Not found\r\n", http_ver);
|
cstp_printf(ws, "HTTP/1.%u 404 Not found\r\n", http_ver);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
tls_cork(ws->session);
|
cstp_cork(ws);
|
||||||
ret = tls_printf(ws->session, "HTTP/1.%u 200 OK\r\n", http_ver);
|
ret = cstp_printf(ws, "HTTP/1.%u 200 OK\r\n", http_ver);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
ret = tls_puts(ws->session, "Connection: Keep-Alive\r\n");
|
ret = cstp_puts(ws, "Connection: Keep-Alive\r\n");
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
ret = tls_puts(ws->session, "Content-Type: text/xml\r\n");
|
ret = cstp_puts(ws, "Content-Type: text/xml\r\n");
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
ret = tls_puts(ws->session, "X-Transcend-Version: 1\r\n");
|
ret = cstp_puts(ws, "X-Transcend-Version: 1\r\n");
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
ret = tls_printf(ws->session, "Content-Length: %u\r\n", (unsigned)st.st_size);
|
ret = cstp_printf(ws, "Content-Length: %u\r\n", (unsigned)st.st_size);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
ret = tls_puts(ws->session, "\r\n");
|
ret = cstp_puts(ws, "\r\n");
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
ret = tls_uncork(ws->session);
|
ret = cstp_uncork(ws);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
ret = tls_send_file(ws->session, ws->config->xml_config_file);
|
ret = cstp_send_file(ws, ws->config->xml_config_file);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
oclog(ws, LOG_ERR, "error sending file '%s': %s", ws->config->xml_config_file, gnutls_strerror(ret));
|
oclog(ws, LOG_ERR, "error sending file '%s': %s", ws->config->xml_config_file, gnutls_strerror(ret));
|
||||||
return -1;
|
return -1;
|
||||||
@@ -116,32 +116,32 @@ int len;
|
|||||||
len = sizeof(XML_START)-1;
|
len = sizeof(XML_START)-1;
|
||||||
}
|
}
|
||||||
|
|
||||||
tls_cork(ws->session);
|
cstp_cork(ws);
|
||||||
ret = tls_printf(ws->session, "HTTP/1.%u 200 OK\r\n", http_ver);
|
ret = cstp_printf(ws, "HTTP/1.%u 200 OK\r\n", http_ver);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
ret = tls_puts(ws->session, "Connection: Keep-Alive\r\n");
|
ret = cstp_puts(ws, "Connection: Keep-Alive\r\n");
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
ret = tls_puts(ws->session, "Content-Type: text/xml\r\n");
|
ret = cstp_puts(ws, "Content-Type: text/xml\r\n");
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
ret = tls_puts(ws->session, "X-Transcend-Version: 1\r\n");
|
ret = cstp_puts(ws, "X-Transcend-Version: 1\r\n");
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
ret = tls_printf(ws->session, "Content-Length: %d\r\n\r\n", len);
|
ret = cstp_printf(ws, "Content-Length: %d\r\n\r\n", len);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
ret = tls_send(ws->session, data, len);
|
ret = cstp_send(ws, data, len);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
ret = tls_uncork(ws->session);
|
ret = cstp_uncork(ws);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
@@ -162,32 +162,32 @@ int len;
|
|||||||
data = SH_SCRIPT;
|
data = SH_SCRIPT;
|
||||||
len = sizeof(SH_SCRIPT)-1;
|
len = sizeof(SH_SCRIPT)-1;
|
||||||
|
|
||||||
tls_cork(ws->session);
|
cstp_cork(ws);
|
||||||
ret = tls_printf(ws->session, "HTTP/1.%u 200 OK\r\n", http_ver);
|
ret = cstp_printf(ws, "HTTP/1.%u 200 OK\r\n", http_ver);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
ret = tls_puts(ws->session, "Connection: Keep-Alive\r\n");
|
ret = cstp_puts(ws, "Connection: Keep-Alive\r\n");
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
ret = tls_puts(ws->session, "Content-Type: application/x-shellscript\r\n");
|
ret = cstp_puts(ws, "Content-Type: application/x-shellscript\r\n");
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
ret = tls_puts(ws->session, "X-Transcend-Version: 1\r\n");
|
ret = cstp_puts(ws, "X-Transcend-Version: 1\r\n");
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
ret = tls_printf(ws->session, "Content-Length: %d\r\n\r\n", len);
|
ret = cstp_printf(ws, "Content-Length: %d\r\n\r\n", len);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
ret = tls_send(ws->session, data, len);
|
ret = cstp_send(ws, data, len);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
ret = tls_uncork(ws->session);
|
ret = cstp_uncork(ws);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
@@ -198,36 +198,36 @@ int get_empty_handler(worker_st *ws, unsigned http_ver)
|
|||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
tls_cork(ws->session);
|
cstp_cork(ws);
|
||||||
ret = tls_printf(ws->session, "HTTP/1.%u 200 OK\r\n", http_ver);
|
ret = cstp_printf(ws, "HTTP/1.%u 200 OK\r\n", http_ver);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
ret = tls_puts(ws->session, "Connection: Keep-Alive\r\n");
|
ret = cstp_puts(ws, "Connection: Keep-Alive\r\n");
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
ret = tls_puts(ws->session, "Content-Type: text/html\r\n");
|
ret = cstp_puts(ws, "Content-Type: text/html\r\n");
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
ret = tls_printf(ws->session, "Content-Length: %u\r\n", (unsigned int)sizeof(empty_msg)-1);
|
ret = cstp_printf(ws, "Content-Length: %u\r\n", (unsigned int)sizeof(empty_msg)-1);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
ret = tls_puts(ws->session, "X-Transcend-Version: 1\r\n");
|
ret = cstp_puts(ws, "X-Transcend-Version: 1\r\n");
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
ret = tls_puts(ws->session, "\r\n");
|
ret = cstp_puts(ws, "\r\n");
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
ret = tls_send(ws->session, empty_msg, sizeof(empty_msg)-1);
|
ret = cstp_send(ws, empty_msg, sizeof(empty_msg)-1);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
ret = tls_uncork(ws->session);
|
ret = cstp_uncork(ws);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
|||||||
+130
-110
@@ -674,7 +674,7 @@ void vpn_server(struct worker_st *ws)
|
|||||||
unsigned char buf[2048];
|
unsigned char buf[2048];
|
||||||
int ret;
|
int ret;
|
||||||
ssize_t nparsed, nrecvd;
|
ssize_t nparsed, nrecvd;
|
||||||
gnutls_session_t session;
|
gnutls_session_t session = NULL;
|
||||||
http_parser parser;
|
http_parser parser;
|
||||||
http_parser_settings settings;
|
http_parser_settings settings;
|
||||||
url_handler_fn fn;
|
url_handler_fn fn;
|
||||||
@@ -705,33 +705,38 @@ void vpn_server(struct worker_st *ws)
|
|||||||
else
|
else
|
||||||
ws->proto = AF_INET6;
|
ws->proto = AF_INET6;
|
||||||
|
|
||||||
/* initialize the session */
|
if (ws->conn_type != SOCK_TYPE_UNIX) {
|
||||||
ret = gnutls_init(&session, GNUTLS_SERVER);
|
/* initialize the session */
|
||||||
GNUTLS_FATAL_ERR(ret);
|
ret = gnutls_init(&session, GNUTLS_SERVER);
|
||||||
|
GNUTLS_FATAL_ERR(ret);
|
||||||
|
|
||||||
ret = gnutls_priority_set(session, ws->creds->cprio);
|
ret = gnutls_priority_set(session, ws->creds->cprio);
|
||||||
GNUTLS_FATAL_ERR(ret);
|
GNUTLS_FATAL_ERR(ret);
|
||||||
|
|
||||||
ret =
|
ret =
|
||||||
gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE,
|
gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE,
|
||||||
ws->creds->xcred);
|
ws->creds->xcred);
|
||||||
GNUTLS_FATAL_ERR(ret);
|
GNUTLS_FATAL_ERR(ret);
|
||||||
|
|
||||||
gnutls_certificate_server_set_request(session, ws->config->cert_req);
|
gnutls_certificate_server_set_request(session, ws->config->cert_req);
|
||||||
gnutls_transport_set_ptr(session,
|
|
||||||
|
gnutls_transport_set_ptr(session,
|
||||||
(gnutls_transport_ptr_t) (long)ws->conn_fd);
|
(gnutls_transport_ptr_t) (long)ws->conn_fd);
|
||||||
set_resume_db_funcs(session);
|
set_resume_db_funcs(session);
|
||||||
gnutls_session_set_ptr(session, ws);
|
gnutls_session_set_ptr(session, ws);
|
||||||
gnutls_db_set_ptr(session, ws);
|
gnutls_db_set_ptr(session, ws);
|
||||||
gnutls_db_set_cache_expiration(session, TLS_SESSION_EXPIRATION_TIME(ws->config));
|
gnutls_db_set_cache_expiration(session, TLS_SESSION_EXPIRATION_TIME(ws->config));
|
||||||
|
|
||||||
gnutls_handshake_set_timeout(session, GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT);
|
gnutls_handshake_set_timeout(session, GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT);
|
||||||
do {
|
do {
|
||||||
ret = gnutls_handshake(session);
|
ret = gnutls_handshake(session);
|
||||||
} while (ret < 0 && gnutls_error_is_fatal(ret) == 0);
|
} while (ret < 0 && gnutls_error_is_fatal(ret) == 0);
|
||||||
GNUTLS_S_FATAL_ERR(session, ret);
|
GNUTLS_S_FATAL_ERR(session, ret);
|
||||||
|
|
||||||
oclog(ws, LOG_DEBUG, "TLS handshake completed");
|
oclog(ws, LOG_DEBUG, "TLS handshake completed");
|
||||||
|
} else {
|
||||||
|
oclog(ws, LOG_DEBUG, "Accepted unix connection");
|
||||||
|
}
|
||||||
|
|
||||||
memset(&settings, 0, sizeof(settings));
|
memset(&settings, 0, sizeof(settings));
|
||||||
|
|
||||||
@@ -757,7 +762,7 @@ void vpn_server(struct worker_st *ws)
|
|||||||
http_req_reset(ws);
|
http_req_reset(ws);
|
||||||
/* parse as we go */
|
/* parse as we go */
|
||||||
do {
|
do {
|
||||||
nrecvd = tls_recv(session, buf, sizeof(buf));
|
nrecvd = cstp_recv_nb(ws, buf, sizeof(buf));
|
||||||
if (nrecvd <= 0) {
|
if (nrecvd <= 0) {
|
||||||
if (nrecvd == 0)
|
if (nrecvd == 0)
|
||||||
goto finish;
|
goto finish;
|
||||||
@@ -781,7 +786,7 @@ void vpn_server(struct worker_st *ws)
|
|||||||
fn = get_url_handler(ws->req.url);
|
fn = get_url_handler(ws->req.url);
|
||||||
if (fn == NULL) {
|
if (fn == NULL) {
|
||||||
oclog(ws, LOG_HTTP_DEBUG, "unexpected URL %s", ws->req.url);
|
oclog(ws, LOG_HTTP_DEBUG, "unexpected URL %s", ws->req.url);
|
||||||
tls_puts(session, "HTTP/1.1 404 Not found\r\n\r\n");
|
cstp_puts(ws, "HTTP/1.1 404 Not found\r\n\r\n");
|
||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
ret = fn(ws, parser.http_minor);
|
ret = fn(ws, parser.http_minor);
|
||||||
@@ -793,8 +798,8 @@ void vpn_server(struct worker_st *ws)
|
|||||||
/* continue reading */
|
/* continue reading */
|
||||||
oclog(ws, LOG_HTTP_DEBUG, "HTTP POST %s", ws->req.url);
|
oclog(ws, LOG_HTTP_DEBUG, "HTTP POST %s", ws->req.url);
|
||||||
while (ws->req.message_complete == 0) {
|
while (ws->req.message_complete == 0) {
|
||||||
nrecvd = tls_recv(session, buf, sizeof(buf));
|
nrecvd = cstp_recv_nb(ws, buf, sizeof(buf));
|
||||||
GNUTLS_FATAL_ERR(nrecvd);
|
FATAL_ERR(ws, nrecvd);
|
||||||
|
|
||||||
nparsed =
|
nparsed =
|
||||||
http_parser_execute(&parser, &settings, (void *)buf,
|
http_parser_execute(&parser, &settings, (void *)buf,
|
||||||
@@ -810,7 +815,7 @@ void vpn_server(struct worker_st *ws)
|
|||||||
if (fn == NULL) {
|
if (fn == NULL) {
|
||||||
oclog(ws, LOG_HTTP_DEBUG, "unexpected POST URL %s",
|
oclog(ws, LOG_HTTP_DEBUG, "unexpected POST URL %s",
|
||||||
ws->req.url);
|
ws->req.url);
|
||||||
tls_puts(session, "HTTP/1.1 404 Not found\r\n\r\n");
|
cstp_puts(ws, "HTTP/1.1 404 Not found\r\n\r\n");
|
||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -829,12 +834,12 @@ void vpn_server(struct worker_st *ws)
|
|||||||
} else {
|
} else {
|
||||||
oclog(ws, LOG_HTTP_DEBUG, "unexpected HTTP method %s",
|
oclog(ws, LOG_HTTP_DEBUG, "unexpected HTTP method %s",
|
||||||
http_method_str(parser.method));
|
http_method_str(parser.method));
|
||||||
tls_printf(session, "HTTP/1.%u 404 Nah, go away\r\n\r\n",
|
cstp_printf(ws, "HTTP/1.%u 404 Nah, go away\r\n\r\n",
|
||||||
parser.http_minor);
|
parser.http_minor);
|
||||||
}
|
}
|
||||||
|
|
||||||
finish:
|
finish:
|
||||||
tls_close(session);
|
cstp_close(ws);
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
@@ -907,7 +912,7 @@ int mtu_not_ok(worker_st * ws)
|
|||||||
if (ws->last_good_mtu == min) {
|
if (ws->last_good_mtu == min) {
|
||||||
oclog(ws, LOG_INFO,
|
oclog(ws, LOG_INFO,
|
||||||
"could not calculate a sufficient MTU. Disabling DTLS.");
|
"could not calculate a sufficient MTU. Disabling DTLS.");
|
||||||
tls_close(ws->dtls_session);
|
dtls_close(ws);
|
||||||
ws->udp_state = UP_DISABLED;
|
ws->udp_state = UP_DISABLED;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -979,7 +984,7 @@ int periodic_check(worker_st * ws, unsigned mtu_overhead, time_t now,
|
|||||||
(int)(now - ws->last_msg_udp), dpd);
|
(int)(now - ws->last_msg_udp), dpd);
|
||||||
|
|
||||||
ws->buffer[0] = AC_PKT_DPD_OUT;
|
ws->buffer[0] = AC_PKT_DPD_OUT;
|
||||||
ret = tls_send(ws->dtls_session, ws->buffer, 1);
|
ret = dtls_send(ws, ws->buffer, 1);
|
||||||
GNUTLS_FATAL_ERR_CMD(ret, exit_worker(ws));
|
GNUTLS_FATAL_ERR_CMD(ret, exit_worker(ws));
|
||||||
|
|
||||||
if (now - ws->last_msg_udp > DPD_MAX_TRIES * dpd) {
|
if (now - ws->last_msg_udp > DPD_MAX_TRIES * dpd) {
|
||||||
@@ -1001,8 +1006,8 @@ int periodic_check(worker_st * ws, unsigned mtu_overhead, time_t now,
|
|||||||
ws->buffer[6] = AC_PKT_DPD_OUT;
|
ws->buffer[6] = AC_PKT_DPD_OUT;
|
||||||
ws->buffer[7] = 0;
|
ws->buffer[7] = 0;
|
||||||
|
|
||||||
ret = tls_send(ws->session, ws->buffer, 8);
|
ret = cstp_send(ws, ws->buffer, 8);
|
||||||
GNUTLS_FATAL_ERR_CMD(ret, exit_worker(ws));
|
FATAL_ERR_CMD(ws, ret, exit_worker(ws));
|
||||||
|
|
||||||
if (now - ws->last_msg_tcp > DPD_MAX_TRIES * dpd) {
|
if (now - ws->last_msg_tcp > DPD_MAX_TRIES * dpd) {
|
||||||
oclog(ws, LOG_ERR,
|
oclog(ws, LOG_ERR,
|
||||||
@@ -1085,7 +1090,7 @@ static int dtls_mainloop(worker_st * ws, struct timespec *tnow)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
ret =
|
ret =
|
||||||
tls_recv_nb(ws->dtls_session, ws->buffer, ws->buffer_size);
|
gnutls_record_recv(ws->dtls_session, ws->buffer, ws->buffer_size);
|
||||||
oclog(ws, LOG_TRANSFER_DEBUG,
|
oclog(ws, LOG_TRANSFER_DEBUG,
|
||||||
"received %d byte(s) (DTLS)", ret);
|
"received %d byte(s) (DTLS)", ret);
|
||||||
|
|
||||||
@@ -1202,8 +1207,8 @@ static int tls_mainloop(struct worker_st *ws, struct timespec *tnow)
|
|||||||
{
|
{
|
||||||
int ret, l;
|
int ret, l;
|
||||||
|
|
||||||
ret = tls_recv_nb(ws->session, ws->buffer, ws->buffer_size);
|
ret = cstp_recv_nb(ws, ws->buffer, ws->buffer_size);
|
||||||
GNUTLS_FATAL_ERR_CMD(ret, exit_worker(ws));
|
FATAL_ERR_CMD(ws, ret, exit_worker(ws));
|
||||||
|
|
||||||
if (ret == 0) { /* disconnect */
|
if (ret == 0) { /* disconnect */
|
||||||
oclog(ws, LOG_DEBUG, "client disconnected");
|
oclog(ws, LOG_DEBUG, "client disconnected");
|
||||||
@@ -1285,7 +1290,7 @@ static int tun_mainloop(struct worker_st *ws, struct timespec *tnow)
|
|||||||
|
|
||||||
ws->buffer[7] = AC_PKT_DATA;
|
ws->buffer[7] = AC_PKT_DATA;
|
||||||
|
|
||||||
ret = tls_send(ws->dtls_session, ws->buffer + 7, l + 1);
|
ret = dtls_send(ws, ws->buffer + 7, l + 1);
|
||||||
GNUTLS_FATAL_ERR_CMD(ret, exit_worker(ws));
|
GNUTLS_FATAL_ERR_CMD(ret, exit_worker(ws));
|
||||||
|
|
||||||
if (ret == GNUTLS_E_LARGE_PACKET) {
|
if (ret == GNUTLS_E_LARGE_PACKET) {
|
||||||
@@ -1310,8 +1315,8 @@ static int tun_mainloop(struct worker_st *ws, struct timespec *tnow)
|
|||||||
ws->buffer[6] = AC_PKT_DATA;
|
ws->buffer[6] = AC_PKT_DATA;
|
||||||
ws->buffer[7] = 0;
|
ws->buffer[7] = 0;
|
||||||
|
|
||||||
ret = tls_send(ws->session, ws->buffer, l + 8);
|
ret = cstp_send(ws, ws->buffer, l + 8);
|
||||||
GNUTLS_FATAL_ERR_CMD(ret, exit_worker(ws));
|
FATAL_ERR_CMD(ws, ret, exit_worker(ws));
|
||||||
}
|
}
|
||||||
ws->last_nc_msg = tnow->tv_sec;
|
ws->last_nc_msg = tnow->tv_sec;
|
||||||
}
|
}
|
||||||
@@ -1384,9 +1389,9 @@ static int connect_handler(worker_st * ws)
|
|||||||
/* we must be in S_AUTH_COOKIE state */
|
/* we must be in S_AUTH_COOKIE state */
|
||||||
if (ws->auth_state != S_AUTH_COOKIE || ws->cookie_set == 0) {
|
if (ws->auth_state != S_AUTH_COOKIE || ws->cookie_set == 0) {
|
||||||
oclog(ws, LOG_WARNING, "no cookie found");
|
oclog(ws, LOG_WARNING, "no cookie found");
|
||||||
tls_puts(ws->session,
|
cstp_puts(ws,
|
||||||
"HTTP/1.1 503 Service Unavailable\r\n\r\n");
|
"HTTP/1.1 503 Service Unavailable\r\n\r\n");
|
||||||
tls_fatal_close(ws->session, GNUTLS_A_ACCESS_DENIED);
|
cstp_fatal_close(ws, GNUTLS_A_ACCESS_DENIED);
|
||||||
exit_worker(ws);
|
exit_worker(ws);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1396,31 +1401,31 @@ static int connect_handler(worker_st * ws)
|
|||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
oclog(ws, LOG_WARNING, "failed cookie authentication attempt");
|
oclog(ws, LOG_WARNING, "failed cookie authentication attempt");
|
||||||
if (ret == ERR_AUTH_FAIL) {
|
if (ret == ERR_AUTH_FAIL) {
|
||||||
tls_puts(ws->session,
|
cstp_puts(ws,
|
||||||
"HTTP/1.1 401 Unauthorized\r\n\r\n");
|
"HTTP/1.1 401 Unauthorized\r\n\r\n");
|
||||||
tls_puts(ws->session,
|
cstp_puts(ws,
|
||||||
"X-Reason: Cookie is not acceptable\r\n\r\n");
|
"X-Reason: Cookie is not acceptable\r\n\r\n");
|
||||||
} else {
|
} else {
|
||||||
tls_puts(ws->session,
|
cstp_puts(ws,
|
||||||
"HTTP/1.1 503 Service Unavailable\r\n\r\n");
|
"HTTP/1.1 503 Service Unavailable\r\n\r\n");
|
||||||
}
|
}
|
||||||
tls_fatal_close(ws->session, GNUTLS_A_ACCESS_DENIED);
|
cstp_fatal_close(ws, GNUTLS_A_ACCESS_DENIED);
|
||||||
exit_worker(ws);
|
exit_worker(ws);
|
||||||
}
|
}
|
||||||
ws->auth_state = S_AUTH_COMPLETE;
|
ws->auth_state = S_AUTH_COMPLETE;
|
||||||
|
|
||||||
if (strcmp(req->url, "/CSCOSSLC/tunnel") != 0) {
|
if (strcmp(req->url, "/CSCOSSLC/tunnel") != 0) {
|
||||||
oclog(ws, LOG_INFO, "bad connect request: '%s'\n", req->url);
|
oclog(ws, LOG_INFO, "bad connect request: '%s'\n", req->url);
|
||||||
tls_puts(ws->session, "HTTP/1.1 404 Nah, go away\r\n\r\n");
|
cstp_puts(ws, "HTTP/1.1 404 Nah, go away\r\n\r\n");
|
||||||
tls_fatal_close(ws->session, GNUTLS_A_ACCESS_DENIED);
|
cstp_fatal_close(ws, GNUTLS_A_ACCESS_DENIED);
|
||||||
exit_worker(ws);
|
exit_worker(ws);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ws->config->network.name[0] == 0) {
|
if (ws->config->network.name[0] == 0) {
|
||||||
oclog(ws, LOG_ERR,
|
oclog(ws, LOG_ERR,
|
||||||
"no networks are configured; rejecting client");
|
"no networks are configured; rejecting client");
|
||||||
tls_puts(ws->session, "HTTP/1.1 503 Service Unavailable\r\n");
|
cstp_puts(ws, "HTTP/1.1 503 Service Unavailable\r\n");
|
||||||
tls_puts(ws->session,
|
cstp_puts(ws,
|
||||||
"X-Reason: Server configuration error\r\n\r\n");
|
"X-Reason: Server configuration error\r\n\r\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -1429,8 +1434,8 @@ static int connect_handler(worker_st * ws)
|
|||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
oclog(ws, LOG_ERR,
|
oclog(ws, LOG_ERR,
|
||||||
"no networks are configured; rejecting client");
|
"no networks are configured; rejecting client");
|
||||||
tls_puts(ws->session, "HTTP/1.1 503 Service Unavailable\r\n");
|
cstp_puts(ws, "HTTP/1.1 503 Service Unavailable\r\n");
|
||||||
tls_puts(ws->session,
|
cstp_puts(ws,
|
||||||
"X-Reason: Server configuration error\r\n\r\n");
|
"X-Reason: Server configuration error\r\n\r\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -1440,14 +1445,14 @@ static int connect_handler(worker_st * ws)
|
|||||||
alarm(0);
|
alarm(0);
|
||||||
http_req_deinit(ws);
|
http_req_deinit(ws);
|
||||||
|
|
||||||
tls_cork(ws->session);
|
cstp_cork(ws);
|
||||||
ret = tls_puts(ws->session, "HTTP/1.1 200 CONNECTED\r\n");
|
ret = cstp_puts(ws, "HTTP/1.1 200 CONNECTED\r\n");
|
||||||
SEND_ERR(ret);
|
SEND_ERR(ret);
|
||||||
|
|
||||||
ret = tls_puts(ws->session, "X-CSTP-Version: 1\r\n");
|
ret = cstp_puts(ws, "X-CSTP-Version: 1\r\n");
|
||||||
SEND_ERR(ret);
|
SEND_ERR(ret);
|
||||||
|
|
||||||
ret = tls_puts(ws->session, "X-Server-Version: "PACKAGE_STRING"\r\n");
|
ret = cstp_puts(ws, "X-Server-Version: "PACKAGE_STRING"\r\n");
|
||||||
SEND_ERR(ret);
|
SEND_ERR(ret);
|
||||||
|
|
||||||
if (req->is_mobile) {
|
if (req->is_mobile) {
|
||||||
@@ -1458,14 +1463,14 @@ static int connect_handler(worker_st * ws)
|
|||||||
oclog(ws, LOG_DEBUG, "suggesting DPD of %d secs", ws->config->dpd);
|
oclog(ws, LOG_DEBUG, "suggesting DPD of %d secs", ws->config->dpd);
|
||||||
if (ws->config->dpd > 0) {
|
if (ws->config->dpd > 0) {
|
||||||
ret =
|
ret =
|
||||||
tls_printf(ws->session, "X-CSTP-DPD: %u\r\n",
|
cstp_printf(ws, "X-CSTP-DPD: %u\r\n",
|
||||||
ws->config->dpd);
|
ws->config->dpd);
|
||||||
SEND_ERR(ret);
|
SEND_ERR(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ws->config->default_domain) {
|
if (ws->config->default_domain) {
|
||||||
ret =
|
ret =
|
||||||
tls_printf(ws->session, "X-CSTP-Default-Domain: %s\r\n",
|
cstp_printf(ws, "X-CSTP-Default-Domain: %s\r\n",
|
||||||
ws->config->default_domain);
|
ws->config->default_domain);
|
||||||
SEND_ERR(ret);
|
SEND_ERR(ret);
|
||||||
}
|
}
|
||||||
@@ -1481,13 +1486,13 @@ static int connect_handler(worker_st * ws)
|
|||||||
if (ws->vinfo.ipv4 && req->no_ipv4 == 0) {
|
if (ws->vinfo.ipv4 && req->no_ipv4 == 0) {
|
||||||
oclog(ws, LOG_DEBUG, "sending IPv4 %s", ws->vinfo.ipv4);
|
oclog(ws, LOG_DEBUG, "sending IPv4 %s", ws->vinfo.ipv4);
|
||||||
ret =
|
ret =
|
||||||
tls_printf(ws->session, "X-CSTP-Address: %s\r\n",
|
cstp_printf(ws, "X-CSTP-Address: %s\r\n",
|
||||||
ws->vinfo.ipv4);
|
ws->vinfo.ipv4);
|
||||||
SEND_ERR(ret);
|
SEND_ERR(ret);
|
||||||
|
|
||||||
if (ws->vinfo.ipv4_netmask) {
|
if (ws->vinfo.ipv4_netmask) {
|
||||||
ret =
|
ret =
|
||||||
tls_printf(ws->session, "X-CSTP-Netmask: %s\r\n",
|
cstp_printf(ws, "X-CSTP-Netmask: %s\r\n",
|
||||||
ws->vinfo.ipv4_netmask);
|
ws->vinfo.ipv4_netmask);
|
||||||
SEND_ERR(ret);
|
SEND_ERR(ret);
|
||||||
}
|
}
|
||||||
@@ -1505,20 +1510,20 @@ static int connect_handler(worker_st * ws)
|
|||||||
oclog(ws, LOG_DEBUG, "sending IPv6 %s", ws->vinfo.ipv6);
|
oclog(ws, LOG_DEBUG, "sending IPv6 %s", ws->vinfo.ipv6);
|
||||||
if (ws->full_ipv6 && ws->vinfo.ipv6_prefix) {
|
if (ws->full_ipv6 && ws->vinfo.ipv6_prefix) {
|
||||||
ret =
|
ret =
|
||||||
tls_printf(ws->session,
|
cstp_printf(ws,
|
||||||
"X-CSTP-Address-IP6: %s/%u\r\n",
|
"X-CSTP-Address-IP6: %s/%u\r\n",
|
||||||
ws->vinfo.ipv6, ws->vinfo.ipv6_prefix);
|
ws->vinfo.ipv6, ws->vinfo.ipv6_prefix);
|
||||||
SEND_ERR(ret);
|
SEND_ERR(ret);
|
||||||
} else {
|
} else {
|
||||||
ret =
|
ret =
|
||||||
tls_printf(ws->session, "X-CSTP-Address: %s\r\n",
|
cstp_printf(ws, "X-CSTP-Address: %s\r\n",
|
||||||
ws->vinfo.ipv6);
|
ws->vinfo.ipv6);
|
||||||
SEND_ERR(ret);
|
SEND_ERR(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ws->vinfo.ipv6_network && ws->vinfo.ipv6_prefix != 0) {
|
if (ws->vinfo.ipv6_network && ws->vinfo.ipv6_prefix != 0) {
|
||||||
ret =
|
ret =
|
||||||
tls_printf(ws->session,
|
cstp_printf(ws,
|
||||||
"X-CSTP-Netmask: %s/%u\r\n",
|
"X-CSTP-Netmask: %s/%u\r\n",
|
||||||
ws->vinfo.ipv6_network, ws->vinfo.ipv6_prefix);
|
ws->vinfo.ipv6_network, ws->vinfo.ipv6_prefix);
|
||||||
SEND_ERR(ret);
|
SEND_ERR(ret);
|
||||||
@@ -1532,7 +1537,7 @@ static int connect_handler(worker_st * ws)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
ret =
|
ret =
|
||||||
tls_printf(ws->session, "X-CSTP-DNS: %s\r\n",
|
cstp_printf(ws, "X-CSTP-DNS: %s\r\n",
|
||||||
ws->vinfo.dns[i]);
|
ws->vinfo.dns[i]);
|
||||||
SEND_ERR(ret);
|
SEND_ERR(ret);
|
||||||
}
|
}
|
||||||
@@ -1544,7 +1549,7 @@ static int connect_handler(worker_st * ws)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
ret =
|
ret =
|
||||||
tls_printf(ws->session, "X-CSTP-NBNS: %s\r\n",
|
cstp_printf(ws, "X-CSTP-NBNS: %s\r\n",
|
||||||
ws->vinfo.nbns[i]);
|
ws->vinfo.nbns[i]);
|
||||||
SEND_ERR(ret);
|
SEND_ERR(ret);
|
||||||
}
|
}
|
||||||
@@ -1553,7 +1558,7 @@ static int connect_handler(worker_st * ws)
|
|||||||
oclog(ws, LOG_DEBUG, "adding split DNS %s",
|
oclog(ws, LOG_DEBUG, "adding split DNS %s",
|
||||||
ws->config->split_dns[i]);
|
ws->config->split_dns[i]);
|
||||||
ret =
|
ret =
|
||||||
tls_printf(ws->session, "X-CSTP-Split-DNS: %s\r\n",
|
cstp_printf(ws, "X-CSTP-Split-DNS: %s\r\n",
|
||||||
ws->config->split_dns[i]);
|
ws->config->split_dns[i]);
|
||||||
SEND_ERR(ret);
|
SEND_ERR(ret);
|
||||||
}
|
}
|
||||||
@@ -1572,11 +1577,11 @@ static int connect_handler(worker_st * ws)
|
|||||||
oclog(ws, LOG_DEBUG, "adding route %s", ws->vinfo.routes[i]);
|
oclog(ws, LOG_DEBUG, "adding route %s", ws->vinfo.routes[i]);
|
||||||
|
|
||||||
if (ip6 != 0 && ws->full_ipv6) {
|
if (ip6 != 0 && ws->full_ipv6) {
|
||||||
ret = tls_printf(ws->session,
|
ret = cstp_printf(ws,
|
||||||
"X-CSTP-Split-Include-IP6: %s\r\n",
|
"X-CSTP-Split-Include-IP6: %s\r\n",
|
||||||
ws->vinfo.routes[i]);
|
ws->vinfo.routes[i]);
|
||||||
} else {
|
} else {
|
||||||
ret = tls_printf(ws->session,
|
ret = cstp_printf(ws,
|
||||||
"X-CSTP-Split-Include: %s\r\n",
|
"X-CSTP-Split-Include: %s\r\n",
|
||||||
ws->vinfo.routes[i]);
|
ws->vinfo.routes[i]);
|
||||||
}
|
}
|
||||||
@@ -1596,11 +1601,11 @@ static int connect_handler(worker_st * ws)
|
|||||||
oclog(ws, LOG_DEBUG, "adding private route %s", ws->routes[i]);
|
oclog(ws, LOG_DEBUG, "adding private route %s", ws->routes[i]);
|
||||||
|
|
||||||
if (ip6 != 0 && ws->full_ipv6) {
|
if (ip6 != 0 && ws->full_ipv6) {
|
||||||
ret = tls_printf(ws->session,
|
ret = cstp_printf(ws,
|
||||||
"X-CSTP-Split-Include-IP6: %s\r\n",
|
"X-CSTP-Split-Include-IP6: %s\r\n",
|
||||||
ws->routes[i]);
|
ws->routes[i]);
|
||||||
} else {
|
} else {
|
||||||
ret = tls_printf(ws->session,
|
ret = cstp_printf(ws,
|
||||||
"X-CSTP-Split-Include: %s\r\n",
|
"X-CSTP-Split-Include: %s\r\n",
|
||||||
ws->routes[i]);
|
ws->routes[i]);
|
||||||
}
|
}
|
||||||
@@ -1609,22 +1614,22 @@ static int connect_handler(worker_st * ws)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ret =
|
ret =
|
||||||
tls_printf(ws->session, "X-CSTP-Keepalive: %u\r\n",
|
cstp_printf(ws, "X-CSTP-Keepalive: %u\r\n",
|
||||||
ws->config->keepalive);
|
ws->config->keepalive);
|
||||||
SEND_ERR(ret);
|
SEND_ERR(ret);
|
||||||
|
|
||||||
if (ws->config->idle_timeout > 0) {
|
if (ws->config->idle_timeout > 0) {
|
||||||
ret =
|
ret =
|
||||||
tls_printf(ws->session,
|
cstp_printf(ws,
|
||||||
"X-CSTP-Idle-Timeout: %u\r\n",
|
"X-CSTP-Idle-Timeout: %u\r\n",
|
||||||
(unsigned)ws->config->idle_timeout);
|
(unsigned)ws->config->idle_timeout);
|
||||||
} else {
|
} else {
|
||||||
ret = tls_puts(ws->session, "X-CSTP-Idle-Timeout: none\r\n");
|
ret = cstp_puts(ws, "X-CSTP-Idle-Timeout: none\r\n");
|
||||||
}
|
}
|
||||||
SEND_ERR(ret);
|
SEND_ERR(ret);
|
||||||
|
|
||||||
ret =
|
ret =
|
||||||
tls_puts(ws->session,
|
cstp_puts(ws,
|
||||||
"X-CSTP-Smartcard-Removal-Disconnect: true\r\n");
|
"X-CSTP-Smartcard-Removal-Disconnect: true\r\n");
|
||||||
SEND_ERR(ret);
|
SEND_ERR(ret);
|
||||||
|
|
||||||
@@ -1632,23 +1637,23 @@ static int connect_handler(worker_st * ws)
|
|||||||
unsigned method;
|
unsigned method;
|
||||||
|
|
||||||
ret =
|
ret =
|
||||||
tls_printf(ws->session, "X-CSTP-Rekey-Time: %u\r\n",
|
cstp_printf(ws, "X-CSTP-Rekey-Time: %u\r\n",
|
||||||
(unsigned)(ws->config->rekey_time));
|
(unsigned)(ws->config->rekey_time));
|
||||||
SEND_ERR(ret);
|
SEND_ERR(ret);
|
||||||
|
|
||||||
/* if the peer isn't patched for safe renegotiation, always
|
/* if the peer isn't patched for safe renegotiation, always
|
||||||
* require him to open a new tunnel. */
|
* require him to open a new tunnel. */
|
||||||
if (gnutls_safe_renegotiation_status(ws->session) != 0)
|
if (ws->session != NULL && gnutls_safe_renegotiation_status(ws->session) != 0)
|
||||||
method = ws->config->rekey_method;
|
method = ws->config->rekey_method;
|
||||||
else
|
else
|
||||||
method = REKEY_METHOD_NEW_TUNNEL;
|
method = REKEY_METHOD_NEW_TUNNEL;
|
||||||
|
|
||||||
ret = tls_printf(ws->session, "X-CSTP-Rekey-Method: %s\r\n",
|
ret = cstp_printf(ws, "X-CSTP-Rekey-Method: %s\r\n",
|
||||||
(method ==
|
(method ==
|
||||||
REKEY_METHOD_SSL) ? "ssl" : "new-tunnel");
|
REKEY_METHOD_SSL) ? "ssl" : "new-tunnel");
|
||||||
SEND_ERR(ret);
|
SEND_ERR(ret);
|
||||||
} else {
|
} else {
|
||||||
ret = tls_puts(ws->session, "X-CSTP-Rekey-Method: none\r\n");
|
ret = cstp_puts(ws, "X-CSTP-Rekey-Method: none\r\n");
|
||||||
SEND_ERR(ret);
|
SEND_ERR(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1656,14 +1661,14 @@ static int connect_handler(worker_st * ws)
|
|||||||
char *url = replace_vals(ws, ws->config->proxy_url);
|
char *url = replace_vals(ws, ws->config->proxy_url);
|
||||||
if (url != NULL) {
|
if (url != NULL) {
|
||||||
ret =
|
ret =
|
||||||
tls_printf(ws->session, "X-CSTP-MSIE-Proxy-Pac-URL: %s\r\n",
|
cstp_printf(ws, "X-CSTP-MSIE-Proxy-Pac-URL: %s\r\n",
|
||||||
url);
|
url);
|
||||||
SEND_ERR(ret);
|
SEND_ERR(ret);
|
||||||
talloc_free(url);
|
talloc_free(url);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = tls_puts(ws->session, "X-CSTP-Session-Timeout: none\r\n"
|
ret = cstp_puts(ws, "X-CSTP-Session-Timeout: none\r\n"
|
||||||
"X-CSTP-Disconnected-Timeout: none\r\n"
|
"X-CSTP-Disconnected-Timeout: none\r\n"
|
||||||
"X-CSTP-Keep: true\r\n"
|
"X-CSTP-Keep: true\r\n"
|
||||||
"X-CSTP-TCP-Keepalive: true\r\n"
|
"X-CSTP-TCP-Keepalive: true\r\n"
|
||||||
@@ -1677,7 +1682,7 @@ static int connect_handler(worker_st * ws)
|
|||||||
if (h) {
|
if (h) {
|
||||||
oclog(ws, LOG_DEBUG, "adding custom header '%s'", h);
|
oclog(ws, LOG_DEBUG, "adding custom header '%s'", h);
|
||||||
ret =
|
ret =
|
||||||
tls_printf(ws->session, "%s\r\n", h);
|
cstp_printf(ws, "%s\r\n", h);
|
||||||
SEND_ERR(ret);
|
SEND_ERR(ret);
|
||||||
talloc_free(h);
|
talloc_free(h);
|
||||||
}
|
}
|
||||||
@@ -1709,15 +1714,21 @@ static int connect_handler(worker_st * ws)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = tls_printf(ws->session, "X-CSTP-Base-MTU: %u\r\n", ws->vinfo.mtu);
|
ret = cstp_printf(ws, "X-CSTP-Base-MTU: %u\r\n", ws->vinfo.mtu);
|
||||||
SEND_ERR(ret);
|
SEND_ERR(ret);
|
||||||
oclog(ws, LOG_DEBUG, "CSTP Base MTU is %u bytes", ws->vinfo.mtu);
|
oclog(ws, LOG_DEBUG, "CSTP Base MTU is %u bytes", ws->vinfo.mtu);
|
||||||
|
|
||||||
/* calculate TLS channel MTU */
|
/* calculate TLS channel MTU */
|
||||||
ws->crypto_overhead = CSTP_OVERHEAD +
|
if (ws->session == NULL) {
|
||||||
tls_get_overhead(gnutls_protocol_get_version(ws->session),
|
/* wild guess */
|
||||||
gnutls_cipher_get(ws->session),
|
ws->crypto_overhead = CSTP_OVERHEAD +
|
||||||
gnutls_mac_get(ws->session));
|
tls_get_overhead(GNUTLS_TLS1_0, GNUTLS_CIPHER_AES_128_CBC, GNUTLS_MAC_SHA1);
|
||||||
|
} else {
|
||||||
|
ws->crypto_overhead = CSTP_OVERHEAD +
|
||||||
|
tls_get_overhead(gnutls_protocol_get_version(ws->session),
|
||||||
|
gnutls_cipher_get(ws->session),
|
||||||
|
gnutls_mac_get(ws->session));
|
||||||
|
}
|
||||||
|
|
||||||
/* plaintext MTU is the device MTU minus the overhead
|
/* plaintext MTU is the device MTU minus the overhead
|
||||||
* of the CSTP protocol. */
|
* of the CSTP protocol. */
|
||||||
@@ -1744,46 +1755,46 @@ static int connect_handler(worker_st * ws)
|
|||||||
p += 2;
|
p += 2;
|
||||||
}
|
}
|
||||||
ret =
|
ret =
|
||||||
tls_printf(ws->session, "X-DTLS-Session-ID: %s\r\n",
|
cstp_printf(ws, "X-DTLS-Session-ID: %s\r\n",
|
||||||
ws->buffer);
|
ws->buffer);
|
||||||
SEND_ERR(ret);
|
SEND_ERR(ret);
|
||||||
|
|
||||||
if (ws->config->dpd > 0) {
|
if (ws->config->dpd > 0) {
|
||||||
ret =
|
ret =
|
||||||
tls_printf(ws->session, "X-DTLS-DPD: %u\r\n",
|
cstp_printf(ws, "X-DTLS-DPD: %u\r\n",
|
||||||
ws->config->dpd);
|
ws->config->dpd);
|
||||||
SEND_ERR(ret);
|
SEND_ERR(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret =
|
ret =
|
||||||
tls_printf(ws->session, "X-DTLS-Port: %u\r\n",
|
cstp_printf(ws, "X-DTLS-Port: %u\r\n",
|
||||||
ws->config->udp_port);
|
ws->config->udp_port);
|
||||||
SEND_ERR(ret);
|
SEND_ERR(ret);
|
||||||
|
|
||||||
if (ws->config->rekey_time > 0) {
|
if (ws->config->rekey_time > 0) {
|
||||||
ret =
|
ret =
|
||||||
tls_printf(ws->session, "X-DTLS-Rekey-Time: %u\r\n",
|
cstp_printf(ws, "X-DTLS-Rekey-Time: %u\r\n",
|
||||||
(unsigned)(ws->config->rekey_time + 10));
|
(unsigned)(ws->config->rekey_time + 10));
|
||||||
SEND_ERR(ret);
|
SEND_ERR(ret);
|
||||||
|
|
||||||
/* This is our private extension */
|
/* This is our private extension */
|
||||||
if (ws->config->rekey_method == REKEY_METHOD_SSL) {
|
if (ws->config->rekey_method == REKEY_METHOD_SSL) {
|
||||||
ret =
|
ret =
|
||||||
tls_puts(ws->session,
|
cstp_puts(ws,
|
||||||
"X-DTLS-Rekey-Method: ssl\r\n");
|
"X-DTLS-Rekey-Method: ssl\r\n");
|
||||||
SEND_ERR(ret);
|
SEND_ERR(ret);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret =
|
ret =
|
||||||
tls_printf(ws->session, "X-DTLS-Keepalive: %u\r\n",
|
cstp_printf(ws, "X-DTLS-Keepalive: %u\r\n",
|
||||||
ws->config->keepalive);
|
ws->config->keepalive);
|
||||||
SEND_ERR(ret);
|
SEND_ERR(ret);
|
||||||
|
|
||||||
oclog(ws, LOG_DEBUG, "DTLS ciphersuite: %s",
|
oclog(ws, LOG_DEBUG, "DTLS ciphersuite: %s",
|
||||||
ws->req.selected_ciphersuite->oc_name);
|
ws->req.selected_ciphersuite->oc_name);
|
||||||
ret =
|
ret =
|
||||||
tls_printf(ws->session, "X-DTLS-CipherSuite: %s\r\n",
|
cstp_printf(ws, "X-DTLS-CipherSuite: %s\r\n",
|
||||||
ws->req.selected_ciphersuite->oc_name);
|
ws->req.selected_ciphersuite->oc_name);
|
||||||
SEND_ERR(ret);
|
SEND_ERR(ret);
|
||||||
|
|
||||||
@@ -1815,7 +1826,7 @@ static int connect_handler(worker_st * ws)
|
|||||||
ws->vinfo.mtu - proto_overhead - ws->crypto_overhead);
|
ws->vinfo.mtu - proto_overhead - ws->crypto_overhead);
|
||||||
|
|
||||||
ret =
|
ret =
|
||||||
tls_printf(ws->session, "X-DTLS-MTU: %u\r\n", ws->conn_mtu);
|
cstp_printf(ws, "X-DTLS-MTU: %u\r\n", ws->conn_mtu);
|
||||||
SEND_ERR(ret);
|
SEND_ERR(ret);
|
||||||
oclog(ws, LOG_DEBUG, "suggesting DTLS MTU %u", ws->conn_mtu);
|
oclog(ws, LOG_DEBUG, "suggesting DTLS MTU %u", ws->conn_mtu);
|
||||||
|
|
||||||
@@ -1833,7 +1844,7 @@ static int connect_handler(worker_st * ws)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* hack for openconnect. It uses only a single MTU value */
|
/* hack for openconnect. It uses only a single MTU value */
|
||||||
ret = tls_printf(ws->session, "X-CSTP-MTU: %u\r\n", ws->conn_mtu);
|
ret = cstp_printf(ws, "X-CSTP-MTU: %u\r\n", ws->conn_mtu);
|
||||||
SEND_ERR(ret);
|
SEND_ERR(ret);
|
||||||
|
|
||||||
if (ws->buffer_size <= ws->conn_mtu + CSTP_OVERHEAD) {
|
if (ws->buffer_size <= ws->conn_mtu + CSTP_OVERHEAD) {
|
||||||
@@ -1847,15 +1858,15 @@ static int connect_handler(worker_st * ws)
|
|||||||
|
|
||||||
if (ws->config->banner) {
|
if (ws->config->banner) {
|
||||||
ret =
|
ret =
|
||||||
tls_printf(ws->session, "X-CSTP-Banner: %s\r\n",
|
cstp_printf(ws, "X-CSTP-Banner: %s\r\n",
|
||||||
ws->config->banner);
|
ws->config->banner);
|
||||||
SEND_ERR(ret);
|
SEND_ERR(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = tls_puts(ws->session, "\r\n");
|
ret = cstp_puts(ws, "\r\n");
|
||||||
SEND_ERR(ret);
|
SEND_ERR(ret);
|
||||||
|
|
||||||
ret = tls_uncork(ws->session);
|
ret = cstp_uncork(ws);
|
||||||
SEND_ERR(ret);
|
SEND_ERR(ret);
|
||||||
|
|
||||||
/* start dead peer detection */
|
/* start dead peer detection */
|
||||||
@@ -1896,12 +1907,15 @@ static int connect_handler(worker_st * ws)
|
|||||||
|
|
||||||
oclog(ws, LOG_TRANSFER_DEBUG,
|
oclog(ws, LOG_TRANSFER_DEBUG,
|
||||||
"sending disconnect message in TLS channel");
|
"sending disconnect message in TLS channel");
|
||||||
ret = tls_send(ws->session, ws->buffer, 8);
|
ret = cstp_send(ws, ws->buffer, 8);
|
||||||
GNUTLS_FATAL_ERR_CMD(ret, exit_worker(ws));
|
FATAL_ERR_CMD(ws, ret, exit_worker(ws));
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
tls_pending = gnutls_record_check_pending(ws->session);
|
if (ws->session != NULL)
|
||||||
|
tls_pending = gnutls_record_check_pending(ws->session);
|
||||||
|
else
|
||||||
|
tls_pending = 0;
|
||||||
|
|
||||||
if (ws->dtls_session != NULL && ws->udp_state > UP_WAIT_FD) {
|
if (ws->dtls_session != NULL && ws->udp_state > UP_WAIT_FD) {
|
||||||
dtls_pending =
|
dtls_pending =
|
||||||
@@ -1979,10 +1993,10 @@ static int connect_handler(worker_st * ws)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
tls_close(ws->session);
|
cstp_close(ws);
|
||||||
/*gnutls_deinit(ws->session); */
|
/*gnutls_deinit(ws->session); */
|
||||||
if (ws->udp_state == UP_ACTIVE && ws->dtls_session) {
|
if (ws->udp_state == UP_ACTIVE && ws->dtls_session) {
|
||||||
tls_close(ws->dtls_session);
|
dtls_close(ws);
|
||||||
/*gnutls_deinit(ws->dtls_session); */
|
/*gnutls_deinit(ws->dtls_session); */
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2009,31 +2023,37 @@ static int parse_data(struct worker_st *ws, gnutls_session_t ts, /* the interfac
|
|||||||
break;
|
break;
|
||||||
case AC_PKT_DPD_OUT:
|
case AC_PKT_DPD_OUT:
|
||||||
if (ws->session == ts) {
|
if (ws->session == ts) {
|
||||||
ret = tls_send(ts, "STF\x01\x00\x00\x04\x00", 8);
|
ret = cstp_send(ws, "STF\x01\x00\x00\x04\x00", 8);
|
||||||
|
|
||||||
oclog(ws, LOG_TRANSFER_DEBUG,
|
oclog(ws, LOG_TRANSFER_DEBUG,
|
||||||
"received TLS DPD; sent response (%d bytes)",
|
"received TLS DPD; sent response (%d bytes)",
|
||||||
ret);
|
ret);
|
||||||
|
|
||||||
|
if (ret < 0) {
|
||||||
|
oclog(ws, LOG_ERR, "could not send data: %d", ret);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Use DPD for MTU discovery in DTLS */
|
/* Use DPD for MTU discovery in DTLS */
|
||||||
ws->buffer[0] = AC_PKT_DPD_RESP;
|
ws->buffer[0] = AC_PKT_DPD_RESP;
|
||||||
|
|
||||||
ret = tls_send(ts, ws->buffer, 1);
|
ret = dtls_send(ws, ws->buffer, 1);
|
||||||
if (ret == GNUTLS_E_LARGE_PACKET) {
|
if (ret == GNUTLS_E_LARGE_PACKET) {
|
||||||
mtu_not_ok(ws);
|
mtu_not_ok(ws);
|
||||||
ret = tls_send(ts, ws->buffer, 1);
|
ret = dtls_send(ws, ws->buffer, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
oclog(ws, LOG_TRANSFER_DEBUG,
|
oclog(ws, LOG_TRANSFER_DEBUG,
|
||||||
"received DTLS DPD; sent response (%d bytes)",
|
"received DTLS DPD; sent response (%d bytes)",
|
||||||
ret);
|
ret);
|
||||||
|
|
||||||
|
if (ret < 0) {
|
||||||
|
oclog(ws, LOG_ERR, "could not send TLS data: %s",
|
||||||
|
gnutls_strerror(ret));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret < 0) {
|
|
||||||
oclog(ws, LOG_ERR, "could not send TLS data: %s",
|
|
||||||
gnutls_strerror(ret));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case AC_PKT_DISCONN:
|
case AC_PKT_DISCONN:
|
||||||
oclog(ws, LOG_DEBUG, "received BYE packet; exiting");
|
oclog(ws, LOG_DEBUG, "received BYE packet; exiting");
|
||||||
|
|||||||
@@ -142,6 +142,7 @@ typedef struct worker_st {
|
|||||||
|
|
||||||
int cmd_fd;
|
int cmd_fd;
|
||||||
int conn_fd;
|
int conn_fd;
|
||||||
|
sock_type_t conn_type; /* AF_UNIX or something else */
|
||||||
|
|
||||||
http_parser *parser;
|
http_parser *parser;
|
||||||
struct cfg_st *config;
|
struct cfg_st *config;
|
||||||
|
|||||||
Reference in New Issue
Block a user