diff --git a/NEWS b/NEWS index 1adcaf28..8de3d50d 100644 --- a/NEWS +++ b/NEWS @@ -3,6 +3,8 @@ - Several updates to allow compilation in FreeBSD. - Allow prior to leasing an IP to ping it in order to check if it is in use. - ocpasswd accepts options to lock and unlock users. +- Several updates to allow CISCO's anyconnect clients to connect to this + server. * Version 0.1.1 (released 2013-04-03) diff --git a/configure.ac b/configure.ac index 515b5a10..467ea20e 100644 --- a/configure.ac +++ b/configure.ac @@ -105,8 +105,8 @@ fi fi AC_ARG_ENABLE(anyconnect-compat, - AS_HELP_STRING([--enable-anyconnect-compat], [enable Anyconnect client compatibility (experimental)]), - anyconnect_enabled=$enableval, anyconnect_enabled=no) + AS_HELP_STRING([--disable-anyconnect-compat], [disable Anyconnect client compatibility (experimental)]), + anyconnect_enabled=$enableval, anyconnect_enabled=yes) if [ test "$anyconnect_enabled" = "yes" ];then AC_DEFINE([ANYCONNECT_CLIENT_COMPAT], [], [Enable Anyconnect compatibility]) fi diff --git a/doc/profile.xml b/doc/profile.xml index 4570518e..af0bd36e 100644 --- a/doc/profile.xml +++ b/doc/profile.xml @@ -18,14 +18,14 @@ - 10.100.2.17 + localhost VPN Server - 10.100.2.17 + localhost diff --git a/doc/sample.config b/doc/sample.config index 0e3cbffc..785e1261 100644 --- a/doc/sample.config +++ b/doc/sample.config @@ -8,17 +8,6 @@ auth = "plain[./sample.passwd]" # 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 = /profile.xml - -# Unless set to false it is required for clients to present their -# certificate even if they are authenticating via a previously granted -# cookie. Legacy CISCO clients do not do that, and thus this option -# should be set for them. -#always-require-cert = false - # Use listen-host to limit to specific IPs or to the IPs of a provided hostname. #listen-host = [IP|HOSTNAME] @@ -154,8 +143,8 @@ route = 192.168.1.0/255.255.255.0 # 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 +# The profile is ignored by the openconnect client. +#user-profile = profile.xml # Unless set to false it is required for clients to present their # certificate even if they are authenticating via a previously granted diff --git a/gl/Makefile.am b/gl/Makefile.am index 355c45cc..9516364c 100644 --- a/gl/Makefile.am +++ b/gl/Makefile.am @@ -21,7 +21,7 @@ # the same distribution terms as the rest of that program. # # Generated by gnulib-tool. -# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=gl --m4-base=gl/m4 --doc-base=doc --tests-base=gl/tests --aux-dir=build-aux --no-conditional-dependencies --no-libtool --macro-prefix=gl cloexec getline getpass gettime memmem minmax +# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=gl --m4-base=gl/m4 --doc-base=doc --tests-base=gl/tests --aux-dir=build-aux --no-conditional-dependencies --no-libtool --macro-prefix=gl c-ctype cloexec getline getpass gettime memmem minmax AUTOMAKE_OPTIONS = 1.5 gnits @@ -49,6 +49,12 @@ libgnu_a_LIBADD = $(gl_LIBOBJS) libgnu_a_DEPENDENCIES = $(gl_LIBOBJS) EXTRA_libgnu_a_SOURCES = +## begin gnulib module c-ctype + +libgnu_a_SOURCES += c-ctype.h c-ctype.c + +## end gnulib module c-ctype + ## begin gnulib module cloexec libgnu_a_SOURCES += cloexec.c diff --git a/gl/m4/gnulib-cache.m4 b/gl/m4/gnulib-cache.m4 index 5fbc02b0..5bb6c03c 100644 --- a/gl/m4/gnulib-cache.m4 +++ b/gl/m4/gnulib-cache.m4 @@ -27,11 +27,12 @@ # Specification in the form of a command-line invocation: -# gnulib-tool --import --dir=. --lib=libgnu --source-base=gl --m4-base=gl/m4 --doc-base=doc --tests-base=gl/tests --aux-dir=build-aux --no-conditional-dependencies --no-libtool --macro-prefix=gl cloexec getline getpass gettime memmem minmax +# gnulib-tool --import --dir=. --lib=libgnu --source-base=gl --m4-base=gl/m4 --doc-base=doc --tests-base=gl/tests --aux-dir=build-aux --no-conditional-dependencies --no-libtool --macro-prefix=gl c-ctype cloexec getline getpass gettime memmem minmax # Specification in the form of a few gnulib-tool.m4 macro invocations: gl_LOCAL_DIR([]) gl_MODULES([ + c-ctype cloexec getline getpass diff --git a/gl/m4/gnulib-comp.m4 b/gl/m4/gnulib-comp.m4 index 74fc57c7..a20ea386 100644 --- a/gl/m4/gnulib-comp.m4 +++ b/gl/m4/gnulib-comp.m4 @@ -38,6 +38,7 @@ AC_DEFUN([gl_EARLY], m4_pattern_allow([^gl_LIBOBJS$])dnl a variable m4_pattern_allow([^gl_LTLIBOBJS$])dnl a variable AC_REQUIRE([gl_PROG_AR_RANLIB]) + # Code from module c-ctype: # Code from module clock-time: # Code from module cloexec: # Code from module close: @@ -383,6 +384,8 @@ AC_DEFUN([gl_FILE_LIST], [ build-aux/snippet/arg-nonnull.h build-aux/snippet/c++defs.h build-aux/snippet/warn-on-use.h + lib/c-ctype.c + lib/c-ctype.h lib/cloexec.c lib/cloexec.h lib/close.c diff --git a/gl/sys_time.in.h b/gl/sys_time.in.h index 656c3f13..3dbf6320 100644 --- a/gl/sys_time.in.h +++ b/gl/sys_time.in.h @@ -24,6 +24,14 @@ #endif @PRAGMA_COLUMNS@ +/* On Cygwin, includes itself recursively via . + Simply delegate to the system's header in this case; it is a no-op. + Without this extra ifdef, the C++ gettimeofday declaration below + would be a forward declaration in gnulib's nested . */ +#ifdef _CYGWIN_SYS_TIME_H +# @INCLUDE_NEXT@ @NEXT_SYS_TIME_H@ +#else + /* The include_next requires a split double-inclusion guard. */ #if @HAVE_SYS_TIME_H@ # @INCLUDE_NEXT@ @NEXT_SYS_TIME_H@ @@ -200,4 +208,5 @@ _GL_WARN_ON_USE (gettimeofday, "gettimeofday is unportable - " #endif #endif /* _@GUARD_PREFIX@_SYS_TIME_H */ +#endif /* _CYGWIN_SYS_TIME_H */ #endif /* _@GUARD_PREFIX@_SYS_TIME_H */ diff --git a/src/ocserv-args.c b/src/ocserv-args.c index 0e123793..67b8251c 100644 --- a/src/ocserv-args.c +++ b/src/ocserv-args.c @@ -2,7 +2,7 @@ * * DO NOT EDIT THIS FILE (ocserv-args.c) * - * It has been AutoGen-ed April 29, 2013 at 12:12:15 AM by AutoGen 5.17.3 + * It has been AutoGen-ed April 29, 2013 at 02:14:53 PM by AutoGen 5.17.3 * From the definitions ocserv-args.def * and the template file options * diff --git a/src/ocserv-args.def b/src/ocserv-args.def index 2e4cd6b7..e6fec468 100644 --- a/src/ocserv-args.def +++ b/src/ocserv-args.def @@ -367,6 +367,22 @@ doc-section = { ds-format = 'texi'; ds-text = <<-_EOT_ The server has been tested to be compatible with the openconnect VPN client. -It isn't compatible with CISCO's AnyConnect clients (there is experimental code). +To enable compatibility with CISCO's AnyConnect clients use a simple client +policy that disables the downloader. An example policy file is shown below. +@example + + +my_user_name +true + + +2804076F5A73955FE7D92B656983EBA5BD48A276 +my_server_name + + + + + +@end example _EOT_; }; diff --git a/src/ocserv-args.h b/src/ocserv-args.h index b90dcfae..01c3dbf6 100644 --- a/src/ocserv-args.h +++ b/src/ocserv-args.h @@ -2,7 +2,7 @@ * * DO NOT EDIT THIS FILE (ocserv-args.h) * - * It has been AutoGen-ed April 29, 2013 at 12:12:15 AM by AutoGen 5.17.3 + * It has been AutoGen-ed April 29, 2013 at 02:14:53 PM by AutoGen 5.17.3 * From the definitions ocserv-args.def * and the template file options * diff --git a/src/tlslib.c b/src/tlslib.c index 54def61d..b56be4d0 100644 --- a/src/tlslib.c +++ b/src/tlslib.c @@ -39,7 +39,7 @@ #include #include #include - +#include ssize_t tls_send(gnutls_session_t session, const void *data, size_t data_size) @@ -576,6 +576,7 @@ gnutls_datum_t data; uint8_t digest[20]; char * retval; gnutls_x509_crt_t crt; +unsigned i; ret = gnutls_load_file(file, &data); if (ret < 0) { @@ -622,5 +623,9 @@ gnutls_x509_crt_t crt; } retval[ret_size] = 0; + /* convert to all caps */ + for (i=0;isession, "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, "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, "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, "Set-Cookie: webvpnc=bu:/&p:t&iu:1/&sh:%s; path=/; secure\r\n", + ws->config->cert_hash); } + + if (ret < 0) + return -1; #endif ret = tls_printf(ws->session, "\r\n"SUCCESS_MSG_HEAD"%s"SUCCESS_MSG_FOOT, msg); diff --git a/src/worker-vpn.c b/src/worker-vpn.c index e96ea899..8c8bedbd 100644 --- a/src/worker-vpn.c +++ b/src/worker-vpn.c @@ -190,10 +190,11 @@ int ret; #endif #define LL(x,y,z) {x, sizeof(x)-1, y, z} -struct known_urls_st known_urls[] = { +const static struct known_urls_st known_urls[] = { LL("/", get_auth_handler, post_auth_handler), LL("/auth", get_auth_handler, post_auth_handler), #ifdef ANYCONNECT_CLIENT_COMPAT + LL("/1/index.html", get_auth_handler, post_auth_handler), LL("/profiles", get_config_handler, NULL), LL("/+CSCOT+/translation-table", get_cscot_handler, NULL), #endif @@ -202,7 +203,7 @@ struct known_urls_st known_urls[] = { static url_handler_fn get_url_handler(const char* url) { -struct known_urls_st *p; +const struct known_urls_st *p; unsigned len = strlen(url); p = known_urls; @@ -220,7 +221,7 @@ unsigned len = strlen(url); static url_handler_fn post_url_handler(const char* url) { -struct known_urls_st *p; +const struct known_urls_st *p; p = known_urls; do { @@ -553,6 +554,8 @@ restart: do { nrecvd = tls_recv(session, buf, sizeof(buf)); if (nrecvd <= 0) { + if (nrecvd == 0) + goto finish; oclog(ws, LOG_INFO, "error receiving client data"); exit_worker(ws); } @@ -568,11 +571,10 @@ restart: oclog(ws, LOG_DEBUG, "HTTP GET %s", ws->req.url); fn = get_url_handler(ws->req.url); if (fn == NULL) { - oclog(ws, LOG_INFO, "unexpected URL %s", ws->req.url); - tls_puts(session, "HTTP/1.1 404 Nah, go away\r\n\r\n"); + oclog(ws, LOG_INFO, "unexpected URL %s", ws->req.url); + tls_puts(session, "HTTP/1.1 404 Not found\r\n\r\n"); goto finish; - } - + } ret = fn(ws, parser.http_minor); if (ret == 0 && (parser.http_major != 1 || parser.http_minor != 0)) goto restart; @@ -594,7 +596,7 @@ restart: fn = post_url_handler(ws->req.url); if (fn == NULL) { oclog(ws, LOG_INFO, "unexpected POST URL %s", ws->req.url); - tls_printf(session, "HTTP/1.%u 404 Nah, go away\r\n\r\n", parser.http_minor); + tls_puts(session, "HTTP/1.1 404 Not found\r\n\r\n"); goto finish; }