changes to enable VPN functionality.

This commit is contained in:
Nikos Mavrogiannopoulos
2013-02-05 21:03:40 +01:00
parent 75a394bec6
commit 03edf5b5bc
8 changed files with 143 additions and 68 deletions

View File

@@ -201,6 +201,9 @@ int cmd_parser (int argc, char **argv, struct cfg_st* config)
if (HAVE_OPT(FOREGROUND))
config->foreground = 1;
if (HAVE_OPT(TLS_DEBUG))
config->tls_debug = 1;
if (HAVE_OPT(CONFIG)) {
cfg_file = OPT_ARG(CONFIG);

View File

@@ -50,7 +50,7 @@ static unsigned int need_children_cleanup = 0;
static void tls_log_func(int level, const char *str)
{
syslog(LOG_DEBUG, "Debug[<%d>]: %s", level, str);
syslog(LOG_DEBUG, "TLS[<%d>]: %s", level, str);
}
/* Returns 0 on success or negative value on error.
@@ -395,9 +395,11 @@ int main(int argc, char** argv)
}
/* Initialize GnuTLS */
gnutls_global_set_log_function(tls_log_func);
gnutls_global_set_audit_log_function(tls_audit_log_func);
gnutls_global_set_log_level(0);
if (config.tls_debug) {
gnutls_global_set_log_function(tls_log_func);
gnutls_global_set_log_level(9);
}
ret = gnutls_global_init();
GNUTLS_FATAL_ERR(ret);

View File

@@ -2,7 +2,7 @@
*
* DO NOT EDIT THIS FILE (ocserv-args.c)
*
* It has been AutoGen-ed February 4, 2013 at 08:41:20 PM by AutoGen 5.16
* It has been AutoGen-ed February 5, 2013 at 09:03:24 PM by AutoGen 5.16
* From the definitions ocserv-args.def
* and the template file options
*
@@ -65,7 +65,7 @@ extern FILE * option_usage_fp;
/*
* ocserv option static const strings
*/
static char const ocserv_opt_strs[1220] =
static char const ocserv_opt_strs[1282] =
/* 0 */ "ocserv\n"
"Copyright (C) 2013 Nikos Mavrogiannopoulos, all rights reserved.\n"
"This is free software. It is licensed for use, modification and\n"
@@ -83,21 +83,24 @@ static char const ocserv_opt_strs[1220] =
/* 803 */ "Do not fork into background.\0"
/* 832 */ "FOREGROUND\0"
/* 843 */ "foreground\0"
/* 854 */ "Configuration file for the server.\0"
/* 889 */ "CONFIG\0"
/* 896 */ "config\0"
/* 903 */ "Display extended usage information and exit\0"
/* 947 */ "help\0"
/* 952 */ "Extended usage information passed thru pager\0"
/* 997 */ "more-help\0"
/* 1007 */ "OCSERV\0"
/* 1014 */ "ocserv - OpenConnect server\n"
/* 854 */ "Enable verbose TLS debugging information.\0"
/* 896 */ "TLS_DEBUG\0"
/* 906 */ "tls-debug\0"
/* 916 */ "Configuration file for the server.\0"
/* 951 */ "CONFIG\0"
/* 958 */ "config\0"
/* 965 */ "Display extended usage information and exit\0"
/* 1009 */ "help\0"
/* 1014 */ "Extended usage information passed thru pager\0"
/* 1059 */ "more-help\0"
/* 1069 */ "OCSERV\0"
/* 1076 */ "ocserv - OpenConnect server\n"
"USAGE: %s [ -<flag> [<val>] | --<name>[{=| }<val>] ]...\n\0"
/* 1100 */ "nmav@gnutls.org\0"
/* 1116 */ "\n\n\0"
/* 1119 */ "\n"
/* 1162 */ "nmav@gnutls.org\0"
/* 1178 */ "\n\n\0"
/* 1181 */ "\n"
"OpenConnect VPN server.\n\0"
/* 1145 */ "Usage: ocserv [options] -c [config]\n"
/* 1207 */ "Usage: ocserv [options] -c [config]\n"
"ocserv --help for usage instructions.\n";
/*
@@ -108,23 +111,31 @@ static char const ocserv_opt_strs[1220] =
#define FOREGROUND_name (ocserv_opt_strs+843)
#define FOREGROUND_FLAGS (OPTST_DISABLED)
/*
* tls-debug option description:
*/
#define TLS_DEBUG_DESC (ocserv_opt_strs+854)
#define TLS_DEBUG_NAME (ocserv_opt_strs+896)
#define TLS_DEBUG_name (ocserv_opt_strs+906)
#define TLS_DEBUG_FLAGS (OPTST_DISABLED)
/*
* config option description:
*/
#define CONFIG_DESC (ocserv_opt_strs+854)
#define CONFIG_NAME (ocserv_opt_strs+889)
#define CONFIG_name (ocserv_opt_strs+896)
#define CONFIG_DESC (ocserv_opt_strs+916)
#define CONFIG_NAME (ocserv_opt_strs+951)
#define CONFIG_name (ocserv_opt_strs+958)
#define CONFIG_FLAGS (OPTST_DISABLED \
| OPTST_SET_ARGTYPE(OPARG_TYPE_FILE))
/*
* Help/More_Help option descriptions:
*/
#define HELP_DESC (ocserv_opt_strs+903)
#define HELP_name (ocserv_opt_strs+947)
#define HELP_DESC (ocserv_opt_strs+965)
#define HELP_name (ocserv_opt_strs+1009)
#ifdef HAVE_WORKING_FORK
#define MORE_HELP_DESC (ocserv_opt_strs+952)
#define MORE_HELP_name (ocserv_opt_strs+997)
#define MORE_HELP_DESC (ocserv_opt_strs+1014)
#define MORE_HELP_name (ocserv_opt_strs+1059)
#define MORE_HELP_FLAGS (OPTST_IMM | OPTST_NO_INIT)
#else
#define MORE_HELP_DESC NULL
@@ -161,8 +172,20 @@ static tOptDesc optDesc[OPTION_CT] = {
/* desc, NAME, name */ FOREGROUND_DESC, FOREGROUND_NAME, FOREGROUND_name,
/* disablement strs */ NULL, NULL },
{ /* entry idx, value */ 1, VALUE_OPT_CONFIG,
/* equiv idx, value */ 1, VALUE_OPT_CONFIG,
{ /* entry idx, value */ 1, VALUE_OPT_TLS_DEBUG,
/* equiv idx, value */ 1, VALUE_OPT_TLS_DEBUG,
/* equivalenced to */ NO_EQUIVALENT,
/* min, max, act ct */ 0, 1, 0,
/* opt state flags */ TLS_DEBUG_FLAGS, 0,
/* last opt argumnt */ { NULL }, /* --tls-debug */
/* arg list/cookie */ NULL,
/* must/cannot opts */ NULL, NULL,
/* option proc */ NULL,
/* desc, NAME, name */ TLS_DEBUG_DESC, TLS_DEBUG_NAME, TLS_DEBUG_name,
/* disablement strs */ NULL, NULL },
{ /* entry idx, value */ 2, VALUE_OPT_CONFIG,
/* equiv idx, value */ 2, VALUE_OPT_CONFIG,
/* equivalenced to */ NO_EQUIVALENT,
/* min, max, act ct */ 0, 1, 0,
/* opt state flags */ CONFIG_FLAGS, 0,
@@ -203,13 +226,13 @@ static tOptDesc optDesc[OPTION_CT] = {
*
* Define the ocserv Option Environment
*/
#define zPROGNAME (ocserv_opt_strs+1007)
#define zUsageTitle (ocserv_opt_strs+1014)
#define zPROGNAME (ocserv_opt_strs+1069)
#define zUsageTitle (ocserv_opt_strs+1076)
#define zRcName NULL
#define apzHomeList NULL
#define zBugsAddr (ocserv_opt_strs+1100)
#define zExplain (ocserv_opt_strs+1116)
#define zDetail (ocserv_opt_strs+1119)
#define zBugsAddr (ocserv_opt_strs+1162)
#define zExplain (ocserv_opt_strs+1178)
#define zDetail (ocserv_opt_strs+1181)
#define zFullVersion (NULL)
/* extracted from optcode.tlib near line 350 */
@@ -224,7 +247,7 @@ static tOptDesc optDesc[OPTION_CT] = {
#define ocserv_full_usage (NULL)
#define ocserv_short_usage (ocserv_opt_strs+1145)
#define ocserv_short_usage (ocserv_opt_strs+1207)
#endif /* not defined __doxygen__ */
@@ -330,7 +353,7 @@ tOptions ocservOptions = {
NO_EQUIVALENT, /* '-#' option index */
NO_EQUIVALENT /* index of default opt */
},
4 /* full option count */, 2 /* user option count */,
5 /* full option count */, 3 /* user option count */,
ocserv_full_usage, ocserv_short_usage,
NULL, NULL,
PKGDATADIR, ocserv_packager_info

View File

@@ -27,6 +27,12 @@ flag = {
doc = "";
};
flag = {
name = tls-debug;
descrip = "Enable verbose TLS debugging information.";
doc = "";
};
flag = {
name = config;
value = c;

View File

@@ -2,7 +2,7 @@
*
* DO NOT EDIT THIS FILE (ocserv-args.h)
*
* It has been AutoGen-ed February 4, 2013 at 08:41:20 PM by AutoGen 5.16
* It has been AutoGen-ed February 5, 2013 at 09:03:24 PM by AutoGen 5.16
* From the definitions ocserv-args.def
* and the template file options
*
@@ -67,12 +67,13 @@
*/
typedef enum {
INDEX_OPT_FOREGROUND = 0,
INDEX_OPT_CONFIG = 1,
INDEX_OPT_HELP = 2,
INDEX_OPT_MORE_HELP = 3
INDEX_OPT_TLS_DEBUG = 1,
INDEX_OPT_CONFIG = 2,
INDEX_OPT_HELP = 3,
INDEX_OPT_MORE_HELP = 4
} teOptIndex;
#define OPTION_CT 4
#define OPTION_CT 5
/*
* Interface defines for all options. Replace "n" with the UPPER_CASED
@@ -109,6 +110,7 @@ typedef enum {
* Interface defines for specific options.
*/
#define VALUE_OPT_FOREGROUND 'f'
#define VALUE_OPT_TLS_DEBUG 1
#define VALUE_OPT_CONFIG 'c'
#define VALUE_OPT_HELP 'h'
#define VALUE_OPT_MORE_HELP '!'

View File

@@ -18,7 +18,7 @@ auth-timeout = 40
tcp-port = 3333
# Keepalive in seconds
keepalive = 10
keepalive = 90
# The key and the certificates of the server
server-cert = /home/nmav/cvs/ocserv/test.pem
@@ -80,5 +80,5 @@ ipv4-dns = local
# Leave empty to assign the default MTU of the device
# mtu =
route = 192.168.2.0/255.255.255.0
route = 192.168.5.0/255.255.255.0
route = 192.168.1.0/255.255.255.0
#route = 192.168.5.0/255.255.255.0

View File

@@ -59,6 +59,7 @@ struct cfg_st {
unsigned keepalive;
const char *cookie_db;
unsigned foreground;
unsigned tls_debug;
unsigned max_clients;
const char *connect_script;

View File

@@ -685,14 +685,14 @@ fail:
return -1;
}
static ssize_t sock_send(int sockfd, const void *buf, size_t len)
static ssize_t tun_write(int sockfd, const void *buf, size_t len)
{
int left = len;
int ret;
const uint8_t * p = buf;
while(left > 0) {
ret = send(sockfd, p, left, 0);
ret = write(sockfd, p, left);
if (ret == -1) {
if (errno != EAGAIN && errno != EINTR)
return ret;
@@ -814,6 +814,7 @@ gnutls_session_t ts;
"X-CSTP-Split-Include: %s\r\n", vinfo.routes[i]);
}
tls_printf(ws->session, "X-CSTP-Keepalive: %u\r\n", ws->config->keepalive);
tls_printf(ws->session, "X-CSTP-MTU: %u\r\n", vinfo.mtu);
if (ws->udp_state != UP_DISABLED) {
p = (char*)buffer;
@@ -823,21 +824,23 @@ gnutls_session_t ts;
}
tls_printf(ws->session, "X-DTLS-Session-ID: %s\r\n", buffer);
tls_printf(ws->session, "X-DTLS-MTU: %u\r\n", vinfo.mtu);
tls_printf(ws->session, "X-DTLS-Port: %u\r\n", ws->udp_port);
tls_puts(ws->session, "X-DTLS-ReKey-Time: 86400\r\n");
tls_printf(ws->session, "X-DTLS-Keepalive: %u\r\n", ws->config->keepalive);
tls_puts(ws->session, "X-DTLS-CipherSuite: "OPENSSL_CIPHERSUITE"\r\n");
if (ws->udp_port_proto == AF_INET)
mtu_overhead = 20+8;
else
mtu_overhead = 40+8;
effective_mtu = vinfo.mtu - mtu_overhead;
tls_printf(ws->session, "X-DTLS-MTU: %u\r\n", effective_mtu);
}
tls_puts(ws->session, "X-CSTP-Banner: Hello there\r\n");
tls_puts(ws->session, "X-CSTP-Banner: Welcome\r\n");
tls_puts(ws->session, "\r\n");
if (ws->udp_port_proto == AF_INET)
mtu_overhead = 20+8;
else
mtu_overhead = 40+8;
for(;;) {
FD_ZERO(&rfds);
@@ -863,6 +866,7 @@ gnutls_session_t ts;
}
if (FD_ISSET(ws->tun_fd, &rfds)) {
if (ws->udp_state == UP_ACTIVE) {
l = effective_mtu;
ts = ws->dtls_session;
@@ -871,7 +875,7 @@ gnutls_session_t ts;
ts = ws->session;
}
l = recv(ws->tun_fd, buffer + 8, l - 8, 0);
l = read(ws->tun_fd, buffer + 8, l - 8);
if (l < 0) {
e = errno;
@@ -883,7 +887,7 @@ gnutls_session_t ts;
}
if (l == 0) { /* disconnect */
oclog(ws, LOG_INFO, "Client disconnected");
oclog(ws, LOG_INFO, "TUN device returned zero");
exit(1);
}
@@ -898,11 +902,11 @@ gnutls_session_t ts;
ret = tls_send(ts, buffer, l + 8);
GNUTLS_FATAL_ERR(ret);
if (ret == GNUTLS_E_LARGE_PACKET) {
/* XXX: we have to do something better than that.
* adjust mtu */
if (effective_mtu > 100)
if (effective_mtu > 128)
effective_mtu -= 32;
ret = tls_send(ws->session, buffer, l + 8);
@@ -913,9 +917,17 @@ gnutls_session_t ts;
if (FD_ISSET(ws->conn_fd, &rfds) || tls_pending != 0) {
ret = tls_recv(ws->session, buffer, sizeof(buffer));
GNUTLS_FATAL_ERR(ret);
ret = parse_cstp_data(ws, buffer, ret);
if (ret == 0) { /* disconnect */
oclog(ws, LOG_INFO, "Client disconnected");
exit(1);
}
l = ret;
ret = parse_cstp_data(ws, buffer, l);
if (ret < 0) {
oclog(ws, LOG_INFO, "Error parsing CSTP data");
exit(1);
}
@@ -927,18 +939,27 @@ gnutls_session_t ts;
}
if (ws->udp_state != UP_DISABLED && (FD_ISSET(ws->udp_fd, &rfds) || dtls_pending != 0)) {
switch (ws->udp_state) {
case UP_ACTIVE:
case UP_INACTIVE:
ret = tls_recv(ws->dtls_session, buffer, sizeof(buffer));
GNUTLS_FATAL_ERR(ret);
if (ret == 0) { /* disconnect */
oclog(ws, LOG_INFO, "Client disconnected");
exit(1);
}
l = ret;
ws->udp_state = UP_ACTIVE;
ret = parse_cstp_data(ws, buffer, ret);
if (ret < 0)
ret = parse_cstp_data(ws, buffer, l);
if (ret < 0) {
oclog(ws, LOG_INFO, "Error parsing CSTP data");
exit(1);
}
udp_recv_time = time(0);
break;
@@ -947,20 +968,27 @@ gnutls_session_t ts;
if (ret < 0)
exit(1);
gnutls_dtls_set_mtu (ws->dtls_session, vinfo.mtu-mtu_overhead);
gnutls_dtls_set_mtu (ws->dtls_session, effective_mtu);
break;
case UP_HANDSHAKE:
ret = gnutls_handshake(ws->dtls_session);
if (ret < 0 && gnutls_error_is_fatal(ret) != 0) {
oclog(ws, LOG_ERR, "Error in DTLS handshake: %s\n", gnutls_strerror(ret));
ws->udp_state = UP_DISABLED;
break;
}
if (ret == GNUTLS_E_LARGE_PACKET) {
/* adjust mtu */
if (effective_mtu > 256)
effective_mtu -= 128;
}
if (ret == 0) {
ws->udp_state = UP_ACTIVE;
effective_mtu = gnutls_dtls_get_data_mtu(ws->dtls_session);
oclog(ws, LOG_DEBUG, "DTLS handshake complete (MTU: %u)\n", effective_mtu);
}
break;
@@ -1032,9 +1060,10 @@ int handle_worker_commands(struct worker_st *ws)
static int parse_cstp_data(struct worker_st* ws, uint8_t* buf, size_t buf_size)
{
int pktlen, ret, e;
gnutls_session_t ts;
if (buf_size < 8) {
oclog(ws, LOG_INFO, "Can't read CSTP header\n");
oclog(ws, LOG_INFO, "Can't read CSTP header (only %d bytes are available)\n", (int)buf_size);
return -1;
}
@@ -1056,15 +1085,24 @@ int pktlen, ret, e;
break;
case AC_PKT_DPD_OUT:
if (ws->udp_state == UP_ACTIVE) {
ts = ws->dtls_session;
} else {
ts = ws->session;
}
ret =
tls_send(ws->session, "STF\x1\x0\x0\x4\x0", 8);
GNUTLS_FATAL_ERR(ret);
tls_send(ts, "STF\x01\x00\x00\x04\x00", 8);
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_INFO, "Received BYE packet\n");
break;
case AC_PKT_DATA:
ret = sock_send(ws->tun_fd, buf + 8, pktlen);
ret = tun_write(ws->tun_fd, buf + 8, pktlen);
if (ret == -1) {
e = errno;
oclog(ws, LOG_ERR, "Could not write data to tun: %s", strerror(e));