Several updates to handle URLs requested by the cisco client.

This commit is contained in:
Nikos Mavrogiannopoulos
2013-03-01 19:52:10 +01:00
parent 27b3378d40
commit 41e8d020b5
14 changed files with 346 additions and 145 deletions
+1 -1
View File
@@ -4,5 +4,5 @@ dist_man_MANS = ocserv.1
ocserv.1: ../src/ocserv-args.def
-sed 's/@subheading \(.*\)/@*\n@var{\1}\n@*/' $< > "$<".tmp && \
-@AUTOGEN@ -DMAN_SECTION=1 -Tagman-cmd.tpl "$<".tmp && \
@AUTOGEN@ -DMAN_SECTION=1 -Tagman-cmd.tpl "$<".tmp && \
rm -f "$<".tmp
+31
View File
@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<AnyConnectProfile xmlns="http://schemas.xmlsoap.org/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://schemas.xmlsoap.org/encoding/ AnyConnectProfile.xsd">
<ClientInitialization>
<UseStartBeforeLogon UserControllable="false">false</UseStartBeforeLogon>
<StrictCertificateTrust>false</StrictCertificateTrust>
<RestrictPreferenceCaching>false</RestrictPreferenceCaching>
<RestrictTunnelProtocols>IPSec</RestrictTunnelProtocols>
<BypassDownloader>true</BypassDownloader>
<CertEnrollmentPin>pinAllowed</CertEnrollmentPin>
<CertificateMatch>
<KeyUsage>
<MatchKey>Digital_Signature</MatchKey>
</KeyUsage>
<ExtendedKeyUsage>
<ExtendedMatchKey>ClientAuth</ExtendedMatchKey>
</ExtendedKeyUsage>
</CertificateMatch>
<BackupServerList>
<HostAddress>10.100.2.17</HostAddress>
</BackupServerList>
</ClientInitialization>
<ServerList>
<HostEntry>
<HostName>VPN Server</HostName>
<HostAddress>10.100.2.17</HostAddress>
</HostEntry>
</ServerList>
</AnyConnectProfile>
+10 -2
View File
@@ -4,6 +4,14 @@
#auth = "certificate"
auth = "pam"
# A banner to be displayed on clients
#banner = "Welcome"
# Client config xml. The variable $GROUP will be replaced by
# the user's group name. This file must be accessible from inside
# the worker's chroot. It is not used by the openconnect client.
user-profile = ../doc/profile.xml
# Use listen-host to limit to specific IPs or to the IPs of a provided hostname.
#listen-host = [IP|HOSTNAME]
@@ -16,8 +24,8 @@ max-clients = 16
max-same-clients = 2
# TCP and UDP port number
tcp-port = 3333
udp-port = 3333
tcp-port = 443
udp-port = 443
# Keepalive in seconds
keepalive = 32400
+1 -1
View File
@@ -28,4 +28,4 @@ ocserv_LDADD += $(LIBGNUTLS_LIBS) $(GDBM_LIBS) $(PAM_LIBS) $(LIBUTIL) \
$(LIBSECCOMP) $(LIBWRAP)
ocserv-args.c ocserv-args.h: $(srcdir)/ocserv-args.def
-@AUTOGEN@ $<
@AUTOGEN@ $<
+14
View File
@@ -30,6 +30,7 @@
#include <autoopts/options.h>
#include <vpn.h>
#include <tlslib.h>
#define DEFAULT_CFG_FILE "/etc/ocserv.conf"
@@ -146,6 +147,7 @@ unsigned j;
READ_STRING("server-key", config->key, 1);
READ_STRING("pin-file", config->pin_file, 0);
READ_STRING("srk-pin-file", config->srk_pin_file, 0);
READ_STRING("user-profile", config->xml_config_file, 0);
READ_STRING("ca-cert", config->ca, 0);
READ_STRING("crl", config->crl, 0);
@@ -208,6 +210,7 @@ unsigned j;
READ_MULTI_LINE("route", config->network.routes, config->network.routes_size, 0);
}
/* sanity checks on config */
static void check_cfg( struct cfg_st *config)
{
@@ -231,6 +234,14 @@ static void check_cfg( struct cfg_st *config)
exit(1);
}
if (config->cert) {
config->cert_hash = calc_sha1_hash(config->cert, 1);
}
if (config->xml_config_file) {
config->xml_config_hash = calc_sha1_hash(config->xml_config_file, 0);
}
if (config->keepalive == 0)
config->keepalive = 3600;
@@ -280,6 +291,9 @@ void reload_cfg_file(struct cfg_st* config)
{
unsigned i;
DEL(config->xml_config_file);
DEL(config->xml_config_hash);
DEL(config->cert_hash);
DEL(config->banner);
DEL(config->name);
DEL(config->cert);
+6 -4
View File
@@ -485,7 +485,7 @@ static void check_other_work(main_server_st *s)
if (reload_conf != 0) {
mslog(s, NULL, LOG_INFO, "HUP signal was received; reloading configuration");
reload_cfg_file(s->config);
tls_global_reinit(s);
tls_global_init_certs(s);
reload_conf = 0;
}
@@ -559,6 +559,9 @@ int main(int argc, char** argv)
signal(SIGCHLD, handle_children);
signal(SIGALRM, handle_alarm);
/* Initialize GnuTLS */
tls_global_init(&s);
/* load configuration */
ret = cmd_parser(argc, argv, &config);
if (ret < 0) {
@@ -601,11 +604,10 @@ int main(int argc, char** argv)
allow_severity = LOG_DAEMON|LOG_INFO;
deny_severity = LOG_DAEMON|LOG_WARNING;
#endif
memset(&ws, 0, sizeof(ws));
/* Initialize GnuTLS */
tls_global_init(&s);
memset(&ws, 0, sizeof(ws));
tls_global_init_certs(&s);
if (config.foreground == 0) {
if (daemon(0, 0) == -1) {
+4 -4
View File
@@ -2,7 +2,7 @@
*
* DO NOT EDIT THIS FILE (ocserv-args.c)
*
* It has been AutoGen-ed February 27, 2013 at 07:03:11 PM by AutoGen 5.16
* It has been AutoGen-ed March 1, 2013 at 07:46:59 PM by AutoGen 5.16
* From the definitions ocserv-args.def
* and the template file options
*
@@ -66,7 +66,7 @@ extern FILE * option_usage_fp;
* ocserv option static const strings
*/
static char const ocserv_opt_strs[1840] =
/* 0 */ "ocserv 0.0.1\n"
/* 0 */ "ocserv 0.0.2\n"
"Copyright (C) 2013 Nikos Mavrogiannopoulos, all rights reserved.\n"
"This is free software. It is licensed for use, modification and\n"
"redistribution under the terms of the\n"
@@ -99,7 +99,7 @@ static char const ocserv_opt_strs[1840] =
/* 1129 */ "Output version information and exit\0"
/* 1165 */ "version\0"
/* 1173 */ "OCSERV\0"
/* 1180 */ "ocserv - OpenConnect server - Ver. 0.0.1\n"
/* 1180 */ "ocserv - OpenConnect server - Ver. 0.0.2\n"
"USAGE: %s [ -<flag> [<val>] | --<name>[{=| }<val>] ]...\n\0"
/* 1279 */ "openconnect-devel@lists.infradead.org\0"
/* 1317 */ "\n\n\0"
@@ -111,7 +111,7 @@ static char const ocserv_opt_strs[1840] =
"authentication. Authenticated users are assigned an unprivileged worker\n"
"process and obtain a networking (tun) device and IP from a configurable\n"
"pool of addresses.\n\0"
/* 1752 */ "ocserv 0.0.1\0"
/* 1752 */ "ocserv 0.0.2\0"
/* 1765 */ "Usage: ocserv [options] -c [config]\n"
"ocserv --help for usage instructions.\n";
+5
View File
@@ -82,6 +82,11 @@ auth = "pam"
# A banner to be displayed on clients
#banner = "Welcome"
# Client profile xml. A sample file exists in doc/profile.xml.
# This file must be accessible from inside the worker's chroot.
# It is not used by the openconnect client.
#user-profile = /path/to/file.xml
# Use listen-host to limit to specific IPs or to the IPs of a provided hostname.
#listen-host = [IP|HOSTNAME]
+3 -3
View File
@@ -2,7 +2,7 @@
*
* DO NOT EDIT THIS FILE (ocserv-args.h)
*
* It has been AutoGen-ed February 27, 2013 at 07:03:10 PM by AutoGen 5.16
* It has been AutoGen-ed March 1, 2013 at 07:46:59 PM by AutoGen 5.16
* From the definitions ocserv-args.def
* and the template file options
*
@@ -76,8 +76,8 @@ typedef enum {
} teOptIndex;
#define OPTION_CT 7
#define OCSERV_VERSION "0.0.1"
#define OCSERV_FULL_VERSION "ocserv 0.0.1"
#define OCSERV_VERSION "0.0.2"
#define OCSERV_FULL_VERSION "ocserv 0.0.2"
/*
* Interface defines for all options. Replace "n" with the UPPER_CASED
+64 -7
View File
@@ -19,6 +19,7 @@
#include <config.h>
#include <gnutls/gnutls.h>
#include <gnutls/crypto.h>
#include <gnutls/pkcs11.h>
#include <errno.h>
#include <stdlib.h>
@@ -333,25 +334,24 @@ void tls_global_init(main_server_st* s)
int ret;
gnutls_global_set_audit_log_function(tls_audit_log_func);
if (s->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);
tls_global_reinit(s);
return;
}
/* reload key files etc. */
void tls_global_reinit(main_server_st* s)
void tls_global_init_certs(main_server_st* s)
{
int ret;
const char* perr;
if (s->config->tls_debug) {
gnutls_global_set_log_function(tls_log_func);
gnutls_global_set_log_level(9);
}
if (s->creds.xcred != NULL)
gnutls_certificate_free_credentials(s->creds.xcred);
@@ -468,3 +468,60 @@ int tls_uncork(gnutls_session_t session)
return 0;
#endif
}
void *calc_sha1_hash(char* file, unsigned cert)
{
int ret;
gnutls_datum_t data;
uint8_t digest[20];
char * retval;
gnutls_x509_crt_t crt;
ret = gnutls_load_file(file, &data);
if (ret < 0) {
fprintf(stderr, "Cannot open file '%s': %s\n", file, gnutls_strerror(ret));
exit(1);
}
if (cert != 0) {
ret = gnutls_x509_crt_init(&crt);
GNUTLS_FATAL_ERR(ret);
ret = gnutls_x509_crt_import(crt, &data, GNUTLS_X509_FMT_PEM);
if (ret == GNUTLS_E_BASE64_DECODING_ERROR)
ret = gnutls_x509_crt_import(crt, &data, GNUTLS_X509_FMT_DER);
GNUTLS_FATAL_ERR(ret);
gnutls_free(data.data);
ret = gnutls_x509_crt_export2(crt, GNUTLS_X509_FMT_DER, &data);
GNUTLS_FATAL_ERR(ret);
gnutls_x509_crt_deinit(crt);
}
ret = gnutls_hash_fast(GNUTLS_DIG_SHA1, data.data, data.size, digest);
gnutls_free(data.data);
if (ret < 0) {
fprintf(stderr, "Error calculating hash of '%s': %s\n", file, gnutls_strerror(ret));
exit(1);
}
size_t ret_size = sizeof(digest)*2+1;
retval = malloc(ret_size);
if (retval == NULL) {
fprintf(stderr, "Memory error\n");
exit(1);
}
data.data = digest;
data.size = sizeof(digest);
ret = gnutls_hex_encode(&data, retval, &ret_size);
if (ret < 0) {
fprintf(stderr, "Error in hex encode: %s\n", gnutls_strerror(ret));
exit(1);
}
retval[ret_size] = 0;
return retval;
}
+16 -2
View File
@@ -20,19 +20,32 @@ int tls_uncork(gnutls_session_t session);
void tls_global_init(struct main_server_st* s);
int tls_global_init_client(struct worker_st* ws);
void tls_global_reinit(struct main_server_st* s);
void tls_global_init_certs(struct main_server_st* s);
ssize_t tls_send_file(gnutls_session_t session, const char *file);
#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)); \
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_S_FATAL_ERR(session, x) \
if (x < 0 && gnutls_error_is_fatal (x) != 0) { \
if (syslog_open) { \
if (ret == GNUTLS_E_FATAL_ALERT_RECEIVED) { \
syslog(LOG_ERR, "GnuTLS error (at %s:%d): %s: %s", __FILE__, __LINE__, gnutls_strerror(x), gnutls_alert_get_name(gnutls_alert_get(session))); \
} else { \
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); \
}
void tls_close(gnutls_session_t session);
void tls_fatal_close(gnutls_session_t session,
@@ -66,5 +79,6 @@ typedef struct
void tls_cache_init(hash_db_st** db);
void tls_cache_deinit(hash_db_st* db);
void *calc_sha1_hash(char* file, unsigned cert);
#endif
+5
View File
@@ -60,6 +60,8 @@ struct cfg_st {
char *pin_file;
char *srk_pin_file;
char *cert;
char *cert_hash;
char *key;
char *ca;
char *crl;
@@ -88,6 +90,9 @@ struct cfg_st {
char *connect_script;
char *disconnect_script;
char *xml_config_file;
char *xml_config_hash;
uid_t uid;
gid_t gid;
+72 -115
View File
@@ -341,19 +341,84 @@ struct cmd_auth_cookie_req_st areq;
return recv_auth_reply(ws);
}
int post_common_handler(worker_st *ws, unsigned http_ver)
{
int ret, size;
char str_cookie[2*COOKIE_SIZE+1];
char *p;
unsigned i;
char msg[MAX_BANNER_SIZE+32];
p = str_cookie;
for (i=0;i<sizeof(ws->cookie);i++) {
sprintf(p, "%.2x", (unsigned int)ws->cookie[i]);
p+=2;
}
/* reply */
tls_cork(ws->session);
ret = tls_printf(ws->session, "HTTP/1.%u 200 OK\r\n", http_ver);
if (ret < 0)
return -1;
ret = tls_puts(ws->session, "Connection: Keep-Alive\r\n");
if (ret < 0)
return -1;
ret = tls_puts(ws->session, "Content-Type: text/xml\r\n");
if (ret < 0)
return -1;
if (ws->config->banner) {
size = snprintf(msg, sizeof(msg), "<banner>%s</banner>", ws->config->banner);
if (size <= 0)
return -1;
} else {
msg[0] = 0;
size = 0;
}
size += (sizeof(SUCCESS_MSG_HEAD)-1) + (sizeof(SUCCESS_MSG_FOOT)-1);
ret = tls_printf(ws->session, "Content-Length: %u\r\n", (unsigned)size);
if (ret < 0)
return -1;
ret = tls_puts(ws->session, "X-Transcend-Version: 1\r\n");
if (ret < 0)
return -1;
ret = tls_printf(ws->session, "Set-Cookie: webvpn=%s;Max-Age=%u\r\n", str_cookie, (unsigned)ws->config->cookie_validity);
if (ret < 0)
return -1;
if (ws->config->xml_config_file) {
ret = tls_printf(ws->session, "Set-Cookie: webvpnc=bu:/&p:t&iu:1/&sh:%s&lu:/+CSCOT+/translation-table?textdomain%%3DAnyConnect%%26type%%3Dmanifest&fu:profiles%%2Fprofile.xml&fh:%s\r\n", ws->config->cert_hash,ws->config->xml_config_hash);
if (ret < 0)
return -1;
}
ret = tls_printf(ws->session, "\r\n"SUCCESS_MSG_HEAD"%s"SUCCESS_MSG_FOOT, msg);
if (ret < 0)
return -1;
ret = tls_uncork(ws->session);
if (ret < 0)
return -1;
return 0;
}
int post_old_auth_handler(worker_st *ws, unsigned http_ver)
{
int ret, size;
int ret;
struct http_req_st *req = &ws->req;
const char* reason = "Authentication failed";
char str_cookie[2*COOKIE_SIZE+1];
char * username = NULL;
char * password = NULL;
char *p;
unsigned int i;
struct cmd_auth_req_st areq;
char msg[MAX_BANNER_SIZE+32];
memset(&areq, 0, sizeof(areq));
@@ -412,59 +477,7 @@ char msg[MAX_BANNER_SIZE+32];
oclog(ws, LOG_INFO, "User '%s' logged in", ws->username);
p = str_cookie;
for (i=0;i<sizeof(ws->cookie);i++) {
sprintf(p, "%.2x", (unsigned int)ws->cookie[i]);
p+=2;
}
/* reply */
tls_cork(ws->session);
ret = tls_printf(ws->session, "HTTP/1.%u 200 OK\r\n", http_ver);
if (ret < 0)
return -1;
ret = tls_puts(ws->session, "Connection: Keep-Alive\r\n");
if (ret < 0)
return -1;
ret = tls_puts(ws->session, "Content-Type: text/xml\r\n");
if (ret < 0)
return -1;
if (ws->config->banner) {
size = snprintf(msg, sizeof(msg), "<banner>%s</banner>", ws->config->banner);
if (size <= 0)
return -1;
} else {
msg[0] = 0;
size = 0;
}
size += (sizeof(SUCCESS_MSG_HEAD)-1) + (sizeof(SUCCESS_MSG_FOOT)-1);
ret = tls_printf(ws->session, "Content-Length: %u\r\n", (unsigned)size);
if (ret < 0)
return -1;
ret = tls_puts(ws->session, "X-Transcend-Version: 1\r\n");
if (ret < 0)
return -1;
ret = tls_printf(ws->session, "Set-Cookie: webvpn=%s;Max-Age=%u\r\n", str_cookie, (unsigned)ws->config->cookie_validity);
if (ret < 0)
return -1;
ret = tls_printf(ws->session, "\r\n"SUCCESS_MSG_HEAD"%s"SUCCESS_MSG_FOOT, msg);
if (ret < 0)
return -1;
ret = tls_uncork(ws->session);
if (ret < 0)
return -1;
return 0;
return post_common_handler(ws, http_ver);;
auth_fail:
tls_printf(ws->session,
@@ -480,16 +493,13 @@ auth_fail:
int post_new_auth_handler(worker_st *ws, unsigned http_ver)
{
int ret, size;
int ret;
struct http_req_st *req = &ws->req;
const char* reason = "Authentication failed";
char str_cookie[2*COOKIE_SIZE+1];
char * username = NULL;
char * password = NULL;
char *p;
unsigned int i;
struct cmd_auth_req_st areq;
char msg[MAX_BANNER_SIZE+32];
memset(&areq, 0, sizeof(areq));
@@ -544,60 +554,7 @@ char msg[MAX_BANNER_SIZE+32];
oclog(ws, LOG_INFO, "User '%s' logged in", ws->username);
p = str_cookie;
for (i=0;i<sizeof(ws->cookie);i++) {
sprintf(p, "%.2x", (unsigned int)ws->cookie[i]);
p+=2;
}
/* reply */
tls_cork(ws->session);
ret = tls_printf(ws->session, "HTTP/1.%u 200 OK\r\n", http_ver);
if (ret < 0)
return -1;
ret = tls_puts(ws->session, "Connection: Keep-Alive\r\n");
if (ret < 0)
return -1;
ret = tls_puts(ws->session, "Content-Type: text/xml\r\n");
if (ret < 0)
return -1;
if (ws->config->banner) {
size = snprintf(msg, sizeof(msg), "<banner>%s</banner>", ws->config->banner);
if (size <= 0)
return -1;
} else {
msg[0] = 0;
size = 0;
}
size += (sizeof(SUCCESS_MSG_HEAD)-1) + (sizeof(SUCCESS_MSG_FOOT)-1);
ret = tls_printf(ws->session, "Content-Length: %u\r\n", (unsigned)size);
if (ret < 0)
return -1;
ret = tls_puts(ws->session, "X-Transcend-Version: 1\r\n");
if (ret < 0)
return -1;
ret = tls_printf(ws->session, "Set-Cookie: webvpn=%s;Max-Age=%u\r\n", str_cookie, (unsigned)ws->config->cookie_validity);
if (ret < 0)
return -1;
ret = tls_printf(ws->session, "\r\n"SUCCESS_MSG_HEAD"%s"SUCCESS_MSG_FOOT, msg);
if (ret < 0)
return -1;
ret = tls_uncork(ws->session);
if (ret < 0)
return -1;
return 0;
return post_common_handler(ws, http_ver);;
ask_auth:
return get_auth_handler(ws, http_ver);
+114 -6
View File
@@ -81,23 +81,128 @@ static int connect_handler(worker_st *ws);
typedef int (*url_handler_fn)(worker_st*, unsigned http_ver);
struct known_urls_st {
const char* url;
unsigned url_size;
url_handler_fn get_handler;
url_handler_fn post_handler;
};
int get_config_handler(worker_st *ws, unsigned http_ver)
{
int ret;
struct stat st;
oclog(ws, LOG_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);
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);
return -1;
}
tls_cork(ws->session);
ret = tls_printf(ws->session, "HTTP/1.%u 200 OK\r\n", http_ver);
if (ret < 0)
return -1;
ret = tls_puts(ws->session, "Connection: Keep-Alive\r\n");
if (ret < 0)
return -1;
ret = tls_puts(ws->session, "Content-Type: text/xml\r\n");
if (ret < 0)
return -1;
ret = tls_puts(ws->session, "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);
if (ret < 0)
return -1;
ret = tls_puts(ws->session, "\r\n");
if (ret < 0)
return -1;
ret = tls_uncork(ws->session);
if (ret < 0)
return -1;
ret = tls_send_file(ws->session, 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;
}
return 0;
}
int get_cscot_handler(worker_st *ws, unsigned http_ver)
{
int ret;
oclog(ws, LOG_DEBUG, "requested CSCOT: %s", ws->req.url);
tls_cork(ws->session);
ret = tls_printf(ws->session, "HTTP/1.%u 200 OK\r\n", http_ver);
if (ret < 0)
return -1;
ret = tls_puts(ws->session, "Connection: Keep-Alive\r\n");
if (ret < 0)
return -1;
ret = tls_puts(ws->session, "Content-Type: text/xml\r\n");
if (ret < 0)
return -1;
ret = tls_puts(ws->session, "X-Transcend-Version: 1\r\n");
if (ret < 0)
return -1;
#define MANIFEST "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<vpn rev=\"1.0\">\n" \
"</vpn>\n"
ret = tls_printf(ws->session, "Content-Length: %u\r\n\r\n", (unsigned)sizeof(MANIFEST)-1);
if (ret < 0)
return -1;
ret = tls_puts(ws->session, MANIFEST);
if (ret < 0)
return -1;
ret = tls_uncork(ws->session);
if (ret < 0)
return -1;
return 0;
}
#define LL(x,y,z) {x, sizeof(x)-1, y, z}
struct known_urls_st known_urls[] = {
{"/", get_auth_handler, post_new_auth_handler},
{"/auth", get_auth_handler, post_old_auth_handler},
{NULL, NULL}
LL("/", get_auth_handler, post_new_auth_handler),
LL("/auth", get_auth_handler, post_old_auth_handler),
LL("/profiles", get_config_handler, NULL),
LL("/+CSCOT+/translation-table", get_cscot_handler, NULL),
{NULL, 0, NULL, NULL}
};
static url_handler_fn get_url_handler(const char* url)
{
struct known_urls_st *p;
unsigned len = strlen(url);
p = known_urls;
do {
if (p->url != NULL && strcmp(p->url, url)==0)
if (p->url != NULL && (
(len == p->url_size && strcmp(p->url, url)==0) ||
(len >= p->url_size && strncmp(p->url, url, p->url_size)==0 &&
(url[p->url_size] == '/' || url[p->url_size] == '?'))))
return p->get_handler;
p++;
} while(p->url != NULL);
@@ -409,7 +514,7 @@ void vpn_server(struct worker_st* ws)
do {
ret = gnutls_handshake(session);
} while (ret < 0 && gnutls_error_is_fatal(ret) == 0);
GNUTLS_FATAL_ERR(ret);
GNUTLS_S_FATAL_ERR(session, ret);
oclog(ws, LOG_DEBUG, "TLS handshake completed");
@@ -988,7 +1093,10 @@ unsigned mtu_overhead, tls_mtu = 0;
hsk_restart:
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));
if (ret == GNUTLS_E_FATAL_ALERT_RECEIVED)
oclog(ws, LOG_ERR, "error in DTLS handshake: %s: %s\n", gnutls_strerror(ret), gnutls_alert_get_name(gnutls_alert_get(ws->dtls_session)));
else
oclog(ws, LOG_ERR, "error in DTLS handshake: %s\n", gnutls_strerror(ret));
ws->udp_state = UP_DISABLED;
break;
}