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
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 = 32400
+2
View File
@@ -82,6 +82,7 @@ static struct cfg_options available_options[] = {
{ .name = "disconnect-script", .type = OPTION_STRING, .mandatory = 0 },
{ .name = "pid-file", .type = OPTION_STRING, .mandatory = 0 },
{ .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 = "banner", .type = OPTION_STRING, .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)
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("occtl-socket-file", config->occtl_socket_file);
if (config->occtl_socket_file == NULL)
+61 -11
View File
@@ -31,6 +31,8 @@
#include <errno.h>
#include <sys/ioctl.h>
#include <sys/resource.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <cloexec.h>
#ifdef HAVE_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->fd = fd;
tmp->family = family;
tmp->socktype = socktype;
tmp->sock_type = socktype;
tmp->protocol = protocol;
tmp->addr_len = addr_len;
@@ -135,12 +137,13 @@ int val;
static
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;
int s, y;
int s, y, e, ret;
const char* type = NULL;
char buf[512];
struct sockaddr_un sa;
for (ptr = res; ptr != NULL; ptr = ptr->ai_next) {
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 (listen(s, 10) < 0) {
if (listen(s, 1024) < 0) {
perror("listen() failed");
force_close(s);
return -1;
@@ -202,11 +205,55 @@ int _listen_ports(void *pool, struct cfg_st* config,
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);
}
/* 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);
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);
}
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) {
@@ -317,7 +364,7 @@ listen_ports(void *pool, struct cfg_st* config,
return -1;
}
ret = _listen_ports(pool, config, res, list);
ret = _listen_ports(pool, config, res, list, 0);
if (ret < 0) {
return -1;
}
@@ -347,7 +394,7 @@ listen_ports(void *pool, struct cfg_st* config,
return -1;
}
ret = _listen_ports(pool, config, res, list);
ret = _listen_ports(pool, config, res, list, 1);
if (ret < 0) {
return -1;
}
@@ -371,7 +418,7 @@ int s, y, e;
force_close(l->fd);
l->fd = -1;
s = socket(l->family, l->socktype, l->protocol);
s = socket(l->family, SOCK_DGRAM, l->protocol);
if (s < 0) {
perror("socket() failed");
return -1;
@@ -1039,8 +1086,10 @@ int main(int argc, char** argv)
/* Check for new connections to accept */
list_for_each(&s->listen_list.head, ltmp, list) {
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 */
int stype = ltmp->sock_type;
ws->remote_addr_len = sizeof(ws->remote_addr);
fd = accept(ltmp->fd, (void*)&ws->remote_addr, &ws->remote_addr_len);
if (fd < 0) {
@@ -1095,6 +1144,7 @@ int main(int argc, char** argv)
ws->tun_fd = -1;
ws->udp_fd = -1;
ws->conn_fd = fd;
ws->conn_type = stype;
ws->creds = &creds;
/* Drop privileges after this point */
@@ -1132,7 +1182,7 @@ fork_failed:
if (s->config->rate_limit_ms > 0)
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 */
ret = forward_udp_to_owner(s, ltmp);
if (ret < 0) {
+1 -1
View File
@@ -52,7 +52,7 @@ extern unsigned int need_maintenance;
struct listener_st {
struct list_node list;
int fd;
int socktype;
sock_type_t sock_type;
struct sockaddr_storage addr; /* local socket address */
socklen_t addr_len;
+4
View File
@@ -124,6 +124,10 @@ max-same-clients = 2
tcp-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 = 32400
+115 -51
View File
@@ -41,56 +41,64 @@
#include <common.h>
#include <sys/un.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>
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)
{
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_AGAIN && ret != GNUTLS_E_INTERRUPTED)) {
return ret;
}
if (ws->session != NULL) {
while(left > 0) {
ret = gnutls_record_send(ws->session, p, data_size);
if (ret < 0 && (ret != GNUTLS_E_AGAIN && ret != GNUTLS_E_INTERRUPTED)) {
return ret;
}
if (ret > 0) {
left -= ret;
p += ret;
if (ret > 0) {
left -= 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 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)
ssize_t cstp_send_file(worker_st *ws, const char *file)
{
FILE* fp;
char buf[512];
@@ -102,8 +110,8 @@ int ret;
return GNUTLS_E_FILE_ERROR;
while ( (len = fread( buf, 1, sizeof(buf), fp)) > 0) {
ret = tls_send(session, buf, len);
GNUTLS_FATAL_ERR(ret);
ret = cstp_send(ws, buf, len);
FATAL_ERR(ws, ret);
total += ret;
}
@@ -113,13 +121,30 @@ int ret;
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;
do {
ret = gnutls_record_recv(session, data, data_size);
} while (ret < 0 && (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN));
if (ws->session != NULL) {
do {
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;
}
@@ -132,6 +157,9 @@ unsigned tls_has_session_cert(struct worker_st * ws)
unsigned int list_size = 0;
const gnutls_datum_t * certs;
if (ws->session == NULL)
return 0;
if (ws->cert_auth_ok)
return 1;
@@ -147,7 +175,7 @@ unsigned tls_has_session_cert(struct worker_st * ws)
}
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];
va_list args;
@@ -158,21 +186,57 @@ int __attribute__ ((format(printf, 2, 3)))
va_start(args, fmt);
s = vsnprintf(buf, 1023, fmt, 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);
gnutls_deinit(session);
if (ws->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_send(session, GNUTLS_AL_FATAL, a);
gnutls_deinit(session);
if (ws->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)
+48 -10
View File
@@ -25,6 +25,7 @@
#include <gnutls/pkcs11.h>
#include <vpn.h>
#include <ccan/htable/htable.h>
#include <errno.h>
typedef struct
{
@@ -32,6 +33,7 @@ typedef struct
unsigned int entries;
} tls_sess_db_st;
#if 0
#define tls_puts(s, str) tls_send(s, str, sizeof(str)-1)
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);
int tls_uncork(gnutls_session_t session);
ssize_t tls_send_file(gnutls_session_t session, const char *file);
#endif
typedef struct tls_st {
gnutls_certificate_credentials_t xcred;
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_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);
#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) \
if (x < 0 && gnutls_error_is_fatal (x) != 0) { \
if (syslog_open) \
@@ -79,6 +74,29 @@ size_t tls_get_overhead(gnutls_protocol_t, gnutls_cipher_algorithm_t, gnutls_mac
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) \
if (x < 0 && gnutls_error_is_fatal (x) != 0) { \
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 *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
+8
View File
@@ -44,6 +44,12 @@
# define _ATTR_PACKED
#endif
typedef enum {
SOCK_TYPE_TCP,
SOCK_TYPE_UDP,
SOCK_TYPE_UNIX
} sock_type_t;
#define DEBUG_BASIC 1
#define DEBUG_HTTP 2
#define DEBUG_TRANSFERRED 5
@@ -181,6 +187,8 @@ struct cfg_st {
char *name; /* server name */
unsigned int port;
unsigned int udp_port;
char* unix_conn_file;
char *pin_file;
char *srk_pin_file;
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);
tls_cork(ws->session);
ret = tls_printf(ws->session, "HTTP/1.%u 200 OK\r\n", http_ver);
cstp_cork(ws);
ret = cstp_printf(ws, "HTTP/1.%u 200 OK\r\n", http_ver);
if (ret < 0)
return -1;
ret = tls_puts(ws->session, "Connection: Keep-Alive\r\n");
ret = cstp_puts(ws, "Connection: Keep-Alive\r\n");
if (ret < 0)
return -1;
@@ -166,7 +166,7 @@ int get_auth_handler2(worker_st * ws, unsigned http_ver, const char *pmsg)
sizeof(context));
ret =
tls_printf(ws->session,
cstp_printf(ws,
"Set-Cookie: webvpncontext=%s; Max-Age=%u; Secure\r\n",
context, (unsigned)MAX_AUTH_SECS);
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);
}
ret = tls_puts(ws->session, "Content-Type: text/xml\r\n");
ret = cstp_puts(ws, "Content-Type: text/xml\r\n");
if (ret < 0) {
ret = -1;
goto cleanup;
@@ -315,33 +315,33 @@ int get_auth_handler2(worker_st * ws, unsigned http_ver, const char *pmsg)
}
ret =
tls_printf(ws->session, "Content-Length: %u\r\n",
cstp_printf(ws, "Content-Length: %u\r\n",
(unsigned int)str.length);
if (ret < 0) {
ret = -1;
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) {
ret = -1;
goto cleanup;
}
ret = tls_puts(ws->session, "\r\n");
ret = cstp_puts(ws, "\r\n");
if (ret < 0) {
ret = -1;
goto cleanup;
}
ret = tls_send(ws->session, str.data, str.length);
ret = cstp_send(ws, str.data, str.length);
if (ret < 0) {
ret = -1;
goto cleanup;
}
ret = tls_uncork(ws->session);
ret = cstp_uncork(ws);
if (ret < 0) {
ret = -1;
goto cleanup;
@@ -869,17 +869,17 @@ int post_common_handler(worker_st * ws, unsigned http_ver)
(char *)str_cookie, str_cookie_size);
/* 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)
return -1;
ret = tls_puts(ws->session, "Connection: Keep-Alive\r\n");
ret = cstp_puts(ws, "Connection: Keep-Alive\r\n");
if (ret < 0)
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)
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;
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)
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)
return -1;
ret =
tls_printf(ws->session,
cstp_printf(ws,
"Set-Cookie: webvpn=%s; Secure\r\n",
str_cookie);
if (ret < 0)
@@ -915,21 +915,21 @@ int post_common_handler(worker_st * ws, unsigned http_ver)
#ifdef ANYCONNECT_CLIENT_COMPAT
ret =
tls_puts(ws->session,
cstp_puts(ws,
"Set-Cookie: webvpnc=; expires=Thu, 01 Jan 1970 22:00:00 GMT; path=/; Secure\r\n");
if (ret < 0)
return -1;
if (ws->config->xml_config_file) {
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",
ws->config->cert_hash,
ws->config->xml_config_file,
ws->config->xml_config_hash);
} else {
ret =
tls_printf(ws->session,
cstp_printf(ws,
"Set-Cookie: webvpnc=bu:/&p:t&iu:1/&sh:%s; path=/; Secure\r\n",
ws->config->cert_hash);
}
@@ -939,12 +939,12 @@ int post_common_handler(worker_st * ws, unsigned http_ver)
#endif
ret =
tls_printf(ws->session,
cstp_printf(ws,
"\r\n%s%s%s", success_msg_head, msg, success_msg_foot);
if (ret < 0)
return -1;
ret = tls_uncork(ws->session);
ret = cstp_uncork(ws);
if (ret < 0)
return -1;
@@ -1262,9 +1262,9 @@ int post_auth_handler(worker_st * ws, unsigned http_ver)
if (sd != -1)
close(sd);
tls_printf(ws->session,
cstp_printf(ws,
"HTTP/1.1 401 Unauthorized\r\nX-Reason: %s\r\n\r\n",
reason);
tls_fatal_close(ws->session, GNUTLS_A_ACCESS_DENIED);
cstp_fatal_close(ws, GNUTLS_A_ACCESS_DENIED);
exit(1);
}
+36 -36
View File
@@ -49,47 +49,47 @@ struct stat st;
oclog(ws, LOG_HTTP_DEBUG, "requested config: %s", ws->req.url);
if (ws->config->xml_config_file == NULL) {
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;
}
ret = stat( ws->config->xml_config_file, &st);
if (ret == -1) {
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;
}
tls_cork(ws->session);
ret = tls_printf(ws->session, "HTTP/1.%u 200 OK\r\n", http_ver);
cstp_cork(ws);
ret = cstp_printf(ws, "HTTP/1.%u 200 OK\r\n", http_ver);
if (ret < 0)
return -1;
ret = tls_puts(ws->session, "Connection: Keep-Alive\r\n");
ret = cstp_puts(ws, "Connection: Keep-Alive\r\n");
if (ret < 0)
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)
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)
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)
return -1;
ret = tls_puts(ws->session, "\r\n");
ret = cstp_puts(ws, "\r\n");
if (ret < 0)
return -1;
ret = tls_uncork(ws->session);
ret = cstp_uncork(ws);
if (ret < 0)
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) {
oclog(ws, LOG_ERR, "error sending file '%s': %s", ws->config->xml_config_file, gnutls_strerror(ret));
return -1;
@@ -116,32 +116,32 @@ int len;
len = sizeof(XML_START)-1;
}
tls_cork(ws->session);
ret = tls_printf(ws->session, "HTTP/1.%u 200 OK\r\n", http_ver);
cstp_cork(ws);
ret = cstp_printf(ws, "HTTP/1.%u 200 OK\r\n", http_ver);
if (ret < 0)
return -1;
ret = tls_puts(ws->session, "Connection: Keep-Alive\r\n");
ret = cstp_puts(ws, "Connection: Keep-Alive\r\n");
if (ret < 0)
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)
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)
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)
return -1;
ret = tls_send(ws->session, data, len);
ret = cstp_send(ws, data, len);
if (ret < 0)
return -1;
ret = tls_uncork(ws->session);
ret = cstp_uncork(ws);
if (ret < 0)
return -1;
@@ -162,32 +162,32 @@ int len;
data = SH_SCRIPT;
len = sizeof(SH_SCRIPT)-1;
tls_cork(ws->session);
ret = tls_printf(ws->session, "HTTP/1.%u 200 OK\r\n", http_ver);
cstp_cork(ws);
ret = cstp_printf(ws, "HTTP/1.%u 200 OK\r\n", http_ver);
if (ret < 0)
return -1;
ret = tls_puts(ws->session, "Connection: Keep-Alive\r\n");
ret = cstp_puts(ws, "Connection: Keep-Alive\r\n");
if (ret < 0)
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)
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)
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)
return -1;
ret = tls_send(ws->session, data, len);
ret = cstp_send(ws, data, len);
if (ret < 0)
return -1;
ret = tls_uncork(ws->session);
ret = cstp_uncork(ws);
if (ret < 0)
return -1;
@@ -198,36 +198,36 @@ int get_empty_handler(worker_st *ws, unsigned http_ver)
{
int ret;
tls_cork(ws->session);
ret = tls_printf(ws->session, "HTTP/1.%u 200 OK\r\n", http_ver);
cstp_cork(ws);
ret = cstp_printf(ws, "HTTP/1.%u 200 OK\r\n", http_ver);
if (ret < 0)
return -1;
ret = tls_puts(ws->session, "Connection: Keep-Alive\r\n");
ret = cstp_puts(ws, "Connection: Keep-Alive\r\n");
if (ret < 0)
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)
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)
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)
return -1;
ret = tls_puts(ws->session, "\r\n");
ret = cstp_puts(ws, "\r\n");
if (ret < 0)
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)
return -1;
ret = tls_uncork(ws->session);
ret = cstp_uncork(ws);
if (ret < 0)
return -1;
+130 -110
View File
@@ -674,7 +674,7 @@ void vpn_server(struct worker_st *ws)
unsigned char buf[2048];
int ret;
ssize_t nparsed, nrecvd;
gnutls_session_t session;
gnutls_session_t session = NULL;
http_parser parser;
http_parser_settings settings;
url_handler_fn fn;
@@ -705,33 +705,38 @@ void vpn_server(struct worker_st *ws)
else
ws->proto = AF_INET6;
/* initialize the session */
ret = gnutls_init(&session, GNUTLS_SERVER);
GNUTLS_FATAL_ERR(ret);
if (ws->conn_type != SOCK_TYPE_UNIX) {
/* initialize the session */
ret = gnutls_init(&session, GNUTLS_SERVER);
GNUTLS_FATAL_ERR(ret);
ret = gnutls_priority_set(session, ws->creds->cprio);
GNUTLS_FATAL_ERR(ret);
ret = gnutls_priority_set(session, ws->creds->cprio);
GNUTLS_FATAL_ERR(ret);
ret =
gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE,
ws->creds->xcred);
GNUTLS_FATAL_ERR(ret);
ret =
gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE,
ws->creds->xcred);
GNUTLS_FATAL_ERR(ret);
gnutls_certificate_server_set_request(session, ws->config->cert_req);
gnutls_transport_set_ptr(session,
gnutls_certificate_server_set_request(session, ws->config->cert_req);
gnutls_transport_set_ptr(session,
(gnutls_transport_ptr_t) (long)ws->conn_fd);
set_resume_db_funcs(session);
gnutls_session_set_ptr(session, ws);
gnutls_db_set_ptr(session, ws);
gnutls_db_set_cache_expiration(session, TLS_SESSION_EXPIRATION_TIME(ws->config));
set_resume_db_funcs(session);
gnutls_session_set_ptr(session, ws);
gnutls_db_set_ptr(session, ws);
gnutls_db_set_cache_expiration(session, TLS_SESSION_EXPIRATION_TIME(ws->config));
gnutls_handshake_set_timeout(session, GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT);
do {
ret = gnutls_handshake(session);
} while (ret < 0 && gnutls_error_is_fatal(ret) == 0);
GNUTLS_S_FATAL_ERR(session, ret);
gnutls_handshake_set_timeout(session, GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT);
do {
ret = gnutls_handshake(session);
} while (ret < 0 && gnutls_error_is_fatal(ret) == 0);
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));
@@ -757,7 +762,7 @@ void vpn_server(struct worker_st *ws)
http_req_reset(ws);
/* parse as we go */
do {
nrecvd = tls_recv(session, buf, sizeof(buf));
nrecvd = cstp_recv_nb(ws, buf, sizeof(buf));
if (nrecvd <= 0) {
if (nrecvd == 0)
goto finish;
@@ -781,7 +786,7 @@ void vpn_server(struct worker_st *ws)
fn = get_url_handler(ws->req.url);
if (fn == NULL) {
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;
}
ret = fn(ws, parser.http_minor);
@@ -793,8 +798,8 @@ void vpn_server(struct worker_st *ws)
/* continue reading */
oclog(ws, LOG_HTTP_DEBUG, "HTTP POST %s", ws->req.url);
while (ws->req.message_complete == 0) {
nrecvd = tls_recv(session, buf, sizeof(buf));
GNUTLS_FATAL_ERR(nrecvd);
nrecvd = cstp_recv_nb(ws, buf, sizeof(buf));
FATAL_ERR(ws, nrecvd);
nparsed =
http_parser_execute(&parser, &settings, (void *)buf,
@@ -810,7 +815,7 @@ void vpn_server(struct worker_st *ws)
if (fn == NULL) {
oclog(ws, LOG_HTTP_DEBUG, "unexpected POST 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;
}
@@ -829,12 +834,12 @@ void vpn_server(struct worker_st *ws)
} else {
oclog(ws, LOG_HTTP_DEBUG, "unexpected HTTP method %s",
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);
}
finish:
tls_close(session);
cstp_close(ws);
}
static
@@ -907,7 +912,7 @@ int mtu_not_ok(worker_st * ws)
if (ws->last_good_mtu == min) {
oclog(ws, LOG_INFO,
"could not calculate a sufficient MTU. Disabling DTLS.");
tls_close(ws->dtls_session);
dtls_close(ws);
ws->udp_state = UP_DISABLED;
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);
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));
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[7] = 0;
ret = tls_send(ws->session, ws->buffer, 8);
GNUTLS_FATAL_ERR_CMD(ret, exit_worker(ws));
ret = cstp_send(ws, ws->buffer, 8);
FATAL_ERR_CMD(ws, ret, exit_worker(ws));
if (now - ws->last_msg_tcp > DPD_MAX_TRIES * dpd) {
oclog(ws, LOG_ERR,
@@ -1085,7 +1090,7 @@ static int dtls_mainloop(worker_st * ws, struct timespec *tnow)
}
#endif
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,
"received %d byte(s) (DTLS)", ret);
@@ -1202,8 +1207,8 @@ static int tls_mainloop(struct worker_st *ws, struct timespec *tnow)
{
int ret, l;
ret = tls_recv_nb(ws->session, ws->buffer, ws->buffer_size);
GNUTLS_FATAL_ERR_CMD(ret, exit_worker(ws));
ret = cstp_recv_nb(ws, ws->buffer, ws->buffer_size);
FATAL_ERR_CMD(ws, ret, exit_worker(ws));
if (ret == 0) { /* disconnect */
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;
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));
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[7] = 0;
ret = tls_send(ws->session, ws->buffer, l + 8);
GNUTLS_FATAL_ERR_CMD(ret, exit_worker(ws));
ret = cstp_send(ws, ws->buffer, l + 8);
FATAL_ERR_CMD(ws, ret, exit_worker(ws));
}
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 */
if (ws->auth_state != S_AUTH_COOKIE || ws->cookie_set == 0) {
oclog(ws, LOG_WARNING, "no cookie found");
tls_puts(ws->session,
cstp_puts(ws,
"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);
}
@@ -1396,31 +1401,31 @@ static int connect_handler(worker_st * ws)
if (ret < 0) {
oclog(ws, LOG_WARNING, "failed cookie authentication attempt");
if (ret == ERR_AUTH_FAIL) {
tls_puts(ws->session,
cstp_puts(ws,
"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");
} else {
tls_puts(ws->session,
cstp_puts(ws,
"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);
}
ws->auth_state = S_AUTH_COMPLETE;
if (strcmp(req->url, "/CSCOSSLC/tunnel") != 0) {
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");
tls_fatal_close(ws->session, GNUTLS_A_ACCESS_DENIED);
cstp_puts(ws, "HTTP/1.1 404 Nah, go away\r\n\r\n");
cstp_fatal_close(ws, GNUTLS_A_ACCESS_DENIED);
exit_worker(ws);
}
if (ws->config->network.name[0] == 0) {
oclog(ws, LOG_ERR,
"no networks are configured; rejecting client");
tls_puts(ws->session, "HTTP/1.1 503 Service Unavailable\r\n");
tls_puts(ws->session,
cstp_puts(ws, "HTTP/1.1 503 Service Unavailable\r\n");
cstp_puts(ws,
"X-Reason: Server configuration error\r\n\r\n");
return -1;
}
@@ -1429,8 +1434,8 @@ static int connect_handler(worker_st * ws)
if (ret < 0) {
oclog(ws, LOG_ERR,
"no networks are configured; rejecting client");
tls_puts(ws->session, "HTTP/1.1 503 Service Unavailable\r\n");
tls_puts(ws->session,
cstp_puts(ws, "HTTP/1.1 503 Service Unavailable\r\n");
cstp_puts(ws,
"X-Reason: Server configuration error\r\n\r\n");
return -1;
}
@@ -1440,14 +1445,14 @@ static int connect_handler(worker_st * ws)
alarm(0);
http_req_deinit(ws);
tls_cork(ws->session);
ret = tls_puts(ws->session, "HTTP/1.1 200 CONNECTED\r\n");
cstp_cork(ws);
ret = cstp_puts(ws, "HTTP/1.1 200 CONNECTED\r\n");
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);
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);
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);
if (ws->config->dpd > 0) {
ret =
tls_printf(ws->session, "X-CSTP-DPD: %u\r\n",
cstp_printf(ws, "X-CSTP-DPD: %u\r\n",
ws->config->dpd);
SEND_ERR(ret);
}
if (ws->config->default_domain) {
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);
SEND_ERR(ret);
}
@@ -1481,13 +1486,13 @@ static int connect_handler(worker_st * ws)
if (ws->vinfo.ipv4 && req->no_ipv4 == 0) {
oclog(ws, LOG_DEBUG, "sending IPv4 %s", ws->vinfo.ipv4);
ret =
tls_printf(ws->session, "X-CSTP-Address: %s\r\n",
cstp_printf(ws, "X-CSTP-Address: %s\r\n",
ws->vinfo.ipv4);
SEND_ERR(ret);
if (ws->vinfo.ipv4_netmask) {
ret =
tls_printf(ws->session, "X-CSTP-Netmask: %s\r\n",
cstp_printf(ws, "X-CSTP-Netmask: %s\r\n",
ws->vinfo.ipv4_netmask);
SEND_ERR(ret);
}
@@ -1505,20 +1510,20 @@ static int connect_handler(worker_st * ws)
oclog(ws, LOG_DEBUG, "sending IPv6 %s", ws->vinfo.ipv6);
if (ws->full_ipv6 && ws->vinfo.ipv6_prefix) {
ret =
tls_printf(ws->session,
cstp_printf(ws,
"X-CSTP-Address-IP6: %s/%u\r\n",
ws->vinfo.ipv6, ws->vinfo.ipv6_prefix);
SEND_ERR(ret);
} else {
ret =
tls_printf(ws->session, "X-CSTP-Address: %s\r\n",
cstp_printf(ws, "X-CSTP-Address: %s\r\n",
ws->vinfo.ipv6);
SEND_ERR(ret);
}
if (ws->vinfo.ipv6_network && ws->vinfo.ipv6_prefix != 0) {
ret =
tls_printf(ws->session,
cstp_printf(ws,
"X-CSTP-Netmask: %s/%u\r\n",
ws->vinfo.ipv6_network, ws->vinfo.ipv6_prefix);
SEND_ERR(ret);
@@ -1532,7 +1537,7 @@ static int connect_handler(worker_st * ws)
continue;
ret =
tls_printf(ws->session, "X-CSTP-DNS: %s\r\n",
cstp_printf(ws, "X-CSTP-DNS: %s\r\n",
ws->vinfo.dns[i]);
SEND_ERR(ret);
}
@@ -1544,7 +1549,7 @@ static int connect_handler(worker_st * ws)
continue;
ret =
tls_printf(ws->session, "X-CSTP-NBNS: %s\r\n",
cstp_printf(ws, "X-CSTP-NBNS: %s\r\n",
ws->vinfo.nbns[i]);
SEND_ERR(ret);
}
@@ -1553,7 +1558,7 @@ static int connect_handler(worker_st * ws)
oclog(ws, LOG_DEBUG, "adding split DNS %s",
ws->config->split_dns[i]);
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]);
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]);
if (ip6 != 0 && ws->full_ipv6) {
ret = tls_printf(ws->session,
ret = cstp_printf(ws,
"X-CSTP-Split-Include-IP6: %s\r\n",
ws->vinfo.routes[i]);
} else {
ret = tls_printf(ws->session,
ret = cstp_printf(ws,
"X-CSTP-Split-Include: %s\r\n",
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]);
if (ip6 != 0 && ws->full_ipv6) {
ret = tls_printf(ws->session,
ret = cstp_printf(ws,
"X-CSTP-Split-Include-IP6: %s\r\n",
ws->routes[i]);
} else {
ret = tls_printf(ws->session,
ret = cstp_printf(ws,
"X-CSTP-Split-Include: %s\r\n",
ws->routes[i]);
}
@@ -1609,22 +1614,22 @@ static int connect_handler(worker_st * ws)
}
ret =
tls_printf(ws->session, "X-CSTP-Keepalive: %u\r\n",
cstp_printf(ws, "X-CSTP-Keepalive: %u\r\n",
ws->config->keepalive);
SEND_ERR(ret);
if (ws->config->idle_timeout > 0) {
ret =
tls_printf(ws->session,
cstp_printf(ws,
"X-CSTP-Idle-Timeout: %u\r\n",
(unsigned)ws->config->idle_timeout);
} 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);
ret =
tls_puts(ws->session,
cstp_puts(ws,
"X-CSTP-Smartcard-Removal-Disconnect: true\r\n");
SEND_ERR(ret);
@@ -1632,23 +1637,23 @@ static int connect_handler(worker_st * ws)
unsigned method;
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));
SEND_ERR(ret);
/* if the peer isn't patched for safe renegotiation, always
* 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;
else
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 ==
REKEY_METHOD_SSL) ? "ssl" : "new-tunnel");
SEND_ERR(ret);
} 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);
}
@@ -1656,14 +1661,14 @@ static int connect_handler(worker_st * ws)
char *url = replace_vals(ws, ws->config->proxy_url);
if (url != NULL) {
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);
SEND_ERR(ret);
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-Keep: true\r\n"
"X-CSTP-TCP-Keepalive: true\r\n"
@@ -1677,7 +1682,7 @@ static int connect_handler(worker_st * ws)
if (h) {
oclog(ws, LOG_DEBUG, "adding custom header '%s'", h);
ret =
tls_printf(ws->session, "%s\r\n", h);
cstp_printf(ws, "%s\r\n", h);
SEND_ERR(ret);
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);
oclog(ws, LOG_DEBUG, "CSTP Base MTU is %u bytes", ws->vinfo.mtu);
/* calculate TLS channel MTU */
ws->crypto_overhead = CSTP_OVERHEAD +
tls_get_overhead(gnutls_protocol_get_version(ws->session),
gnutls_cipher_get(ws->session),
gnutls_mac_get(ws->session));
if (ws->session == NULL) {
/* wild guess */
ws->crypto_overhead = CSTP_OVERHEAD +
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
* of the CSTP protocol. */
@@ -1744,46 +1755,46 @@ static int connect_handler(worker_st * ws)
p += 2;
}
ret =
tls_printf(ws->session, "X-DTLS-Session-ID: %s\r\n",
cstp_printf(ws, "X-DTLS-Session-ID: %s\r\n",
ws->buffer);
SEND_ERR(ret);
if (ws->config->dpd > 0) {
ret =
tls_printf(ws->session, "X-DTLS-DPD: %u\r\n",
cstp_printf(ws, "X-DTLS-DPD: %u\r\n",
ws->config->dpd);
SEND_ERR(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);
SEND_ERR(ret);
if (ws->config->rekey_time > 0) {
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));
SEND_ERR(ret);
/* This is our private extension */
if (ws->config->rekey_method == REKEY_METHOD_SSL) {
ret =
tls_puts(ws->session,
cstp_puts(ws,
"X-DTLS-Rekey-Method: ssl\r\n");
SEND_ERR(ret);
}
}
ret =
tls_printf(ws->session, "X-DTLS-Keepalive: %u\r\n",
cstp_printf(ws, "X-DTLS-Keepalive: %u\r\n",
ws->config->keepalive);
SEND_ERR(ret);
oclog(ws, LOG_DEBUG, "DTLS ciphersuite: %s",
ws->req.selected_ciphersuite->oc_name);
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);
SEND_ERR(ret);
@@ -1815,7 +1826,7 @@ static int connect_handler(worker_st * ws)
ws->vinfo.mtu - proto_overhead - ws->crypto_overhead);
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);
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 */
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);
if (ws->buffer_size <= ws->conn_mtu + CSTP_OVERHEAD) {
@@ -1847,15 +1858,15 @@ static int connect_handler(worker_st * ws)
if (ws->config->banner) {
ret =
tls_printf(ws->session, "X-CSTP-Banner: %s\r\n",
cstp_printf(ws, "X-CSTP-Banner: %s\r\n",
ws->config->banner);
SEND_ERR(ret);
}
ret = tls_puts(ws->session, "\r\n");
ret = cstp_puts(ws, "\r\n");
SEND_ERR(ret);
ret = tls_uncork(ws->session);
ret = cstp_uncork(ws);
SEND_ERR(ret);
/* start dead peer detection */
@@ -1896,12 +1907,15 @@ static int connect_handler(worker_st * ws)
oclog(ws, LOG_TRANSFER_DEBUG,
"sending disconnect message in TLS channel");
ret = tls_send(ws->session, ws->buffer, 8);
GNUTLS_FATAL_ERR_CMD(ret, exit_worker(ws));
ret = cstp_send(ws, ws->buffer, 8);
FATAL_ERR_CMD(ws, ret, exit_worker(ws));
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) {
dtls_pending =
@@ -1979,10 +1993,10 @@ static int connect_handler(worker_st * ws)
return 0;
exit:
tls_close(ws->session);
cstp_close(ws);
/*gnutls_deinit(ws->session); */
if (ws->udp_state == UP_ACTIVE && ws->dtls_session) {
tls_close(ws->dtls_session);
dtls_close(ws);
/*gnutls_deinit(ws->dtls_session); */
}
@@ -2009,31 +2023,37 @@ static int parse_data(struct worker_st *ws, gnutls_session_t ts, /* the interfac
break;
case AC_PKT_DPD_OUT:
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,
"received TLS DPD; sent response (%d bytes)",
ret);
if (ret < 0) {
oclog(ws, LOG_ERR, "could not send data: %d", ret);
return -1;
}
} else {
/* Use DPD for MTU discovery in DTLS */
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) {
mtu_not_ok(ws);
ret = tls_send(ts, ws->buffer, 1);
ret = dtls_send(ws, ws->buffer, 1);
}
oclog(ws, LOG_TRANSFER_DEBUG,
"received DTLS DPD; sent response (%d bytes)",
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;
case AC_PKT_DISCONN:
oclog(ws, LOG_DEBUG, "received BYE packet; exiting");
+1
View File
@@ -142,6 +142,7 @@ typedef struct worker_st {
int cmd_fd;
int conn_fd;
sock_type_t conn_type; /* AF_UNIX or something else */
http_parser *parser;
struct cfg_st *config;