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:
Nikos Mavrogiannopoulos
2014-09-23 16:08:29 +02:00
parent ddcb609c5d
commit 4ea5a56ace
12 changed files with 435 additions and 244 deletions
+4
View File
@@ -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
+2
View File
@@ -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
View File
@@ -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
View File
@@ -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;
+4
View File
@@ -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
View File
@@ -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
View File
@@ -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
+8
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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");
+1
View File
@@ -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;