From de0fb97e71f0bc63f59ad8a6cfa19dc4914f2514 Mon Sep 17 00:00:00 2001 From: Arne Schwabe Date: Thu, 16 Oct 2014 12:40:17 +0200 Subject: Update OpenVPN --HG-- extra : rebase_source : eae76bb97139022b5592b2599b7e3870054bcaa9 --- main/openvpn/configure.ac | 27 ++++++++++++++++++++++++++- main/openvpn/contrib/OCSP_check/OCSP_check.sh | 13 ++++++++++--- main/openvpn/distro/systemd/openvpn@.service | 19 +++++++++++++++++++ main/openvpn/doc/android.txt | 24 +++++++++++++++--------- main/openvpn/src/openvpn/Makefile.am | 1 + main/openvpn/src/openvpn/base64.c | 2 +- main/openvpn/src/openvpn/console.c | 16 ++++++++++------ main/openvpn/src/openvpn/crypto_backend.h | 4 ++-- main/openvpn/src/openvpn/misc.c | 21 +++++++++++++-------- main/openvpn/src/openvpn/multi.c | 14 ++++++++++---- main/openvpn/src/openvpn/options.c | 4 ++-- main/openvpn/src/openvpn/plugin.c | 2 +- main/openvpn/src/openvpn/route.c | 11 +++++++---- main/openvpn/src/openvpn/sig.c | 2 +- main/openvpn/src/openvpn/socket.c | 4 ++-- main/openvpn/src/openvpn/ssl_polarssl.c | 26 +++++++++++++++----------- main/openvpn/src/openvpn/ssl_verify_openssl.c | 4 ++-- 17 files changed, 137 insertions(+), 57 deletions(-) create mode 100644 main/openvpn/distro/systemd/openvpn@.service (limited to 'main/openvpn') diff --git a/main/openvpn/configure.ac b/main/openvpn/configure.ac index ffba3749..608ab6d1 100644 --- a/main/openvpn/configure.ac +++ b/main/openvpn/configure.ac @@ -368,15 +368,18 @@ AC_ARG_VAR([IPROUTE], [full path to ip utility]) AC_ARG_VAR([NETSTAT], [path to netstat utility]) # tests AC_ARG_VAR([MAN2HTML], [path to man2html utility]) AC_ARG_VAR([GIT], [path to git utility]) +AC_ARG_VAR([SYSTEMD_ASK_PASSWORD], [path to systemd-ask-password utility]) AC_PATH_PROGS([IFCONFIG], [ifconfig],, [$PATH:/usr/local/sbin:/usr/sbin:/sbin]) AC_PATH_PROGS([ROUTE], [route],, [$PATH:/usr/local/sbin:/usr/sbin:/sbin]) AC_PATH_PROGS([IPROUTE], [ip],, [$PATH:/usr/local/sbin:/usr/sbin:/sbin]) +AC_PATH_PROGS([SYSTEMD_ASK_PASSWORD], [systemd-ask-password],, [$PATH:/usr/local/bin:/usr/bin:/bin]) AC_CHECK_PROGS([NETSTAT], [netstat], [netstat], [$PATH:/usr/local/sbin:/usr/sbin:/sbin:/etc]) # tests AC_CHECK_PROGS([MAN2HTML], [man2html]) AC_CHECK_PROGS([GIT], [git]) # optional AC_DEFINE_UNQUOTED([IFCONFIG_PATH], ["$IFCONFIG"], [Path to ifconfig tool]) AC_DEFINE_UNQUOTED([IPROUTE_PATH], ["$IPROUTE"], [Path to iproute tool]) AC_DEFINE_UNQUOTED([ROUTE_PATH], ["$ROUTE"], [Path to route tool]) +AC_DEFINE_UNQUOTED([SYSTEMD_ASK_PASSWORD_PATH], ["$SYSTEMD_ASK_PASSWORD"], [Path to systemd-ask-password tool]) # # Libtool @@ -994,6 +997,28 @@ if test "$enable_lz4" = "yes" && test "$enable_comp_stub" = "no"; then fi +dnl +dnl Check for systemd +dnl + +if test "$enable_systemd" = "yes" ; then + PKG_CHECK_MODULES([libsystemd], [systemd libsystemd], + [], + [PKG_CHECK_MODULES([libsystemd], [libsystemd-daemon])] + ) + AC_CHECK_HEADERS(systemd/sd-daemon.h, + , + [ + AC_MSG_ERROR([systemd development headers not found.]) + ]) + + saved_LIBS="${LIBS}" + LIBS="${LIBS} ${libsystemd_LIBS}" + AC_CHECK_FUNCS([sd_booted], [], [AC_MSG_ERROR([systemd library is missing sd_booted()])]) + OPTIONAL_SYSTEMD_LIBS="${libsystemd_LIBS}" + AC_DEFINE(ENABLE_SYSTEMD, 1, [Enable systemd integration]) + LIBS="${saved_LIBS}" +fi AC_MSG_CHECKING([git checkout]) @@ -1034,7 +1059,6 @@ test "${enable_def_auth}" = "yes" && AC_DEFINE([ENABLE_DEF_AUTH], [1], [Enable d test "${enable_pf}" = "yes" && AC_DEFINE([ENABLE_PF], [1], [Enable internal packet filter]) test "${enable_strict_options}" = "yes" && AC_DEFINE([ENABLE_STRICT_OPTIONS_CHECK], [1], [Enable strict options check between peers]) test "${enable_password_save}" = "yes" && AC_DEFINE([ENABLE_PASSWORD_SAVE], [1], [Allow --askpass and --auth-user-pass passwords to be read from a file]) -test "${enable_systemd}" = "yes" && AC_DEFINE([ENABLE_SYSTEMD], [1], [Enable systemd support]) case "${with_crypto_library}" in openssl) @@ -1167,6 +1191,7 @@ AC_SUBST([OPTIONAL_SNAPPY_CFLAGS]) AC_SUBST([OPTIONAL_SNAPPY_LIBS]) AC_SUBST([OPTIONAL_LZ4_CFLAGS]) AC_SUBST([OPTIONAL_LZ4_LIBS]) +AC_SUBST([OPTIONAL_SYSTEMD_LIBS]) AC_SUBST([OPTIONAL_PKCS11_HELPER_CFLAGS]) AC_SUBST([OPTIONAL_PKCS11_HELPER_LIBS]) diff --git a/main/openvpn/contrib/OCSP_check/OCSP_check.sh b/main/openvpn/contrib/OCSP_check/OCSP_check.sh index 553c3dce..6876c6d8 100644 --- a/main/openvpn/contrib/OCSP_check/OCSP_check.sh +++ b/main/openvpn/contrib/OCSP_check/OCSP_check.sh @@ -97,12 +97,19 @@ if [ $check_depth -eq -1 ] || [ $cur_depth -eq $check_depth ]; then "$nonce" \ -CAfile "$verify" \ -url "$ocsp_url" \ - -serial "${serial}" 2>/dev/null) + -serial "${serial}" 2>&1) if [ $? -eq 0 ]; then - # check that it's good + # check if ocsp didn't report any errors + if echo "$status" | grep -Eq "(error|fail)"; then + exit 1 + fi + # check that the reported status of certificate is ok if echo "$status" | grep -Fq "^${serial}: good"; then - exit 0 + # check if signature on the OCSP response verified correctly + if echo "$status" | grep -Fq "^Response verify OK"; then + exit 0 + fi fi fi fi diff --git a/main/openvpn/distro/systemd/openvpn@.service b/main/openvpn/distro/systemd/openvpn@.service new file mode 100644 index 00000000..7cd36c36 --- /dev/null +++ b/main/openvpn/distro/systemd/openvpn@.service @@ -0,0 +1,19 @@ +[Unit] +Description=OpenVPN tunnel for %I +After=syslog.target network.target +Documentation=man:openvpn(8) +Documentation=https://community.openvpn.net/openvpn/wiki/Openvpn23ManPage +Documentation=https://community.openvpn.net/openvpn/wiki/HOWTO + +[Service] +PrivateTmp=true +Type=forking +PIDFile=/var/run/openvpn/%i.pid +ExecStart=/usr/sbin/openvpn --daemon --writepid /var/run/openvpn/%i.pid --cd /etc/openvpn/ --config %i.conf +CapabilityBoundingSet=CAP_IPC_LOCK CAP_NET_ADMIN CAP_NET_BIND_SERVICE CAP_NET_RAW CAP_SETGID CAP_SETUID CAP_SYS_CHROOT CAP_DAC_READ_SEARCH +LimitNPROC=10 +DeviceAllow=/dev/null rw +DeviceAllow=/dev/net/tun rw + +[Install] +WantedBy=multi-user.target diff --git a/main/openvpn/doc/android.txt b/main/openvpn/doc/android.txt index cf8b3c79..137edfc5 100644 --- a/main/openvpn/doc/android.txt +++ b/main/openvpn/doc/android.txt @@ -55,6 +55,21 @@ To set the DNS server and search domain. The GUI will then respond with a "needok 'command' ok' or "needok 'command' cancel', e.g. "needok 'IFCONFIG' ok". +PERSIST_TUN_ACTION + +In Android 4.4-4.4.2 a bug exists that does not allow to open a new tun fd +while a tun fd is still open. When OpenVPN wants to open an fd it will do +this query. The UI should compare the last configuration of +the tun device with the current tun configuration and reply with either (or +always respond with OPEN_AFTER_BEFORE/OPEN_BEFORE_CLOSE) + +- NOACTION: Keep using the old fd +- OPEN_AFTER_CLOSE: First close the old fd and then open a new to workaround the bug +- OPEN_BEFORE_CLOSE: the normal behaviour when the VPN configuration changed + +For example the UI could respond with +needok 'PERSIST_TUN_ACTION' OPEN_AFTER_CLOSE + To protect a socket the OpenVPN will send a PROTECTFD to the UI. When sending the PROTECTFD command command to the UI it will send the fd of the socket as ancillary message over the UNIX socket. @@ -74,12 +89,3 @@ are not specific to Android but are rarely used on other platform. For example using SIGUSR1 and management-hold to restart, pause, continue the VPN on network changes or the external key management --management-external-key option and inline files. - -Due to a bug in Android 4.4-4.4.2 there the Android Control will also -query what action the daemon should take when opening the fd. The GUI -should compare the last configuration of the tun device with the current -tun configuration and reply with either - -- NOACTION: Keep using the old fd -- OPEN_AFTER_CLOSE: First close the old fd and then open a new to workaround the bug -- OPEN_BEFORE_CLOSE: the normal behaviour when the VPN configuration changed diff --git a/main/openvpn/src/openvpn/Makefile.am b/main/openvpn/src/openvpn/Makefile.am index fd593c57..d089f50f 100644 --- a/main/openvpn/src/openvpn/Makefile.am +++ b/main/openvpn/src/openvpn/Makefile.am @@ -126,6 +126,7 @@ openvpn_LDADD = \ $(OPTIONAL_PKCS11_HELPER_LIBS) \ $(OPTIONAL_CRYPTO_LIBS) \ $(OPTIONAL_SELINUX_LIBS) \ + $(OPTIONAL_SYSTEMD_LIBS) \ $(OPTIONAL_DL_LIBS) if WIN32 openvpn_SOURCES += openvpn_win32_resources.rc diff --git a/main/openvpn/src/openvpn/base64.c b/main/openvpn/src/openvpn/base64.c index 6dc8479f..258b258e 100644 --- a/main/openvpn/src/openvpn/base64.c +++ b/main/openvpn/src/openvpn/base64.c @@ -108,7 +108,7 @@ token_decode(const char *token) int i; unsigned int val = 0; int marker = 0; - if (strlen(token) < 4) + if (!token[0] || !token[1] || !token[2] || !token[3]) return DECODE_ERROR; for (i = 0; i < 4; i++) { val *= 64; diff --git a/main/openvpn/src/openvpn/console.c b/main/openvpn/src/openvpn/console.c index afda8ca3..d66d4087 100644 --- a/main/openvpn/src/openvpn/console.c +++ b/main/openvpn/src/openvpn/console.c @@ -34,6 +34,10 @@ #include "buffer.h" #include "misc.h" +#ifdef ENABLE_SYSTEMD +#include +#endif + #ifdef WIN32 #include "win32.h" @@ -143,14 +147,14 @@ close_tty (FILE *fp) static bool check_systemd_running () { - struct stat a, b; + struct stat c; /* We simply test whether the systemd cgroup hierarchy is - * mounted */ + * mounted, as well as the systemd-ask-password executable + * being available */ - return (lstat("/sys/fs/cgroup", &a) == 0) - && (lstat("/sys/fs/cgroup/systemd", &b) == 0) - && (a.st_dev != b.st_dev); + return (sd_booted() > 0) + && (stat(SYSTEMD_ASK_PASSWORD_PATH, &c) == 0); } @@ -162,7 +166,7 @@ get_console_input_systemd (const char *prompt, const bool echo, char *input, con struct argv argv; argv_init (&argv); - argv_printf (&argv, "/bin/systemd-ask-password"); + argv_printf (&argv, SYSTEMD_ASK_PASSWORD_PATH); argv_printf_cat (&argv, "%s", prompt); if ((std_out = openvpn_popen (&argv, NULL)) < 0) { diff --git a/main/openvpn/src/openvpn/crypto_backend.h b/main/openvpn/src/openvpn/crypto_backend.h index a48ad6c5..bc067a7d 100644 --- a/main/openvpn/src/openvpn/crypto_backend.h +++ b/main/openvpn/src/openvpn/crypto_backend.h @@ -231,7 +231,7 @@ int cipher_kt_block_size (const cipher_kt_t *cipher_kt); int cipher_kt_mode (const cipher_kt_t *cipher_kt); /** - * Check of the supplied cipher is a supported CBC mode cipher. + * Check if the supplied cipher is a supported CBC mode cipher. * * @param cipher Static cipher parameters. May not be NULL. * @@ -241,7 +241,7 @@ bool cipher_kt_mode_cbc(const cipher_kt_t *cipher) __attribute__((nonnull)); /** - * Check of the supplied cipher is a supported OFB or CFB mode cipher. + * Check if the supplied cipher is a supported OFB or CFB mode cipher. * * @param cipher Static cipher parameters. May not be NULL. * diff --git a/main/openvpn/src/openvpn/misc.c b/main/openvpn/src/openvpn/misc.c index 63b4c1cf..61bc523d 100644 --- a/main/openvpn/src/openvpn/misc.c +++ b/main/openvpn/src/openvpn/misc.c @@ -365,24 +365,29 @@ openvpn_popen (const struct argv *a, const struct env_set *es) pid = fork (); if (pid == (pid_t)0) /* child side */ { - close (pipe_stdout[0]); + close (pipe_stdout[0]); /* Close read end */ dup2 (pipe_stdout[1],1); execve (cmd, argv, envp); exit (127); } - else if (pid < (pid_t)0) /* fork failed */ + else if (pid > (pid_t)0) /* parent side */ { - msg (M_ERR, "openvpn_popen: unable to fork"); + int status = 0; + + close (pipe_stdout[1]); /* Close write end */ + waitpid(pid, &status, 0); + ret = pipe_stdout[0]; } - else /* parent side */ + else /* fork failed */ { - ret=pipe_stdout[0]; - close (pipe_stdout[1]); + close (pipe_stdout[0]); + close (pipe_stdout[1]); + msg (M_ERR, "openvpn_popen: unable to fork %s", cmd); } } else { - msg (M_WARN, "openvpn_popen: unable to create stdout pipe"); - ret = -1; + msg (M_WARN, "openvpn_popen: unable to create stdout pipe for %s", cmd); + ret = -1; } } else if (!warn_shown && (script_security < SSEC_SCRIPTS)) diff --git a/main/openvpn/src/openvpn/multi.c b/main/openvpn/src/openvpn/multi.c index a4289ac7..e55b9778 100644 --- a/main/openvpn/src/openvpn/multi.c +++ b/main/openvpn/src/openvpn/multi.c @@ -1467,10 +1467,6 @@ multi_client_connect_post (struct multi_context *m, option_types_found, mi->context.c2.es); - if (!platform_unlink (dc_file)) - msg (D_MULTI_ERRORS, "MULTI: problem deleting temporary file: %s", - dc_file); - /* * If the --client-connect script generates a config file * with an --ifconfig-push directive, it will override any @@ -1713,6 +1709,11 @@ multi_connection_established (struct multi_context *m, struct multi_instance *mi multi_client_connect_post (m, mi, dc_file, option_permissions_mask, &option_types_found); ++cc_succeeded_count; } + + if (!platform_unlink (dc_file)) + msg (D_MULTI_ERRORS, "MULTI: problem deleting temporary file: %s", + dc_file); + script_depr_failed: argv_reset (&argv); } @@ -1766,6 +1767,11 @@ multi_connection_established (struct multi_context *m, struct multi_instance *mi } else cc_succeeded = false; + + if (!platform_unlink (dc_file)) + msg (D_MULTI_ERRORS, "MULTI: problem deleting temporary file: %s", + dc_file); + script_failed: argv_reset (&argv); } diff --git a/main/openvpn/src/openvpn/options.c b/main/openvpn/src/openvpn/options.c index 9ff2db5a..6adccc6f 100644 --- a/main/openvpn/src/openvpn/options.c +++ b/main/openvpn/src/openvpn/options.c @@ -2926,8 +2926,8 @@ options_string (const struct options *o, o->ifconfig_ipv6_local, o->ifconfig_ipv6_netbits, o->ifconfig_ipv6_remote, - (in_addr_t)0, - (in_addr_t)0, + NULL, + NULL, false, NULL); if (tt) diff --git a/main/openvpn/src/openvpn/plugin.c b/main/openvpn/src/openvpn/plugin.c index 0948f238..54c5b52d 100644 --- a/main/openvpn/src/openvpn/plugin.c +++ b/main/openvpn/src/openvpn/plugin.c @@ -291,7 +291,7 @@ plugin_init_item (struct plugin *p, const struct plugin_option *o) static void plugin_vlog (openvpn_plugin_log_flags_t flags, const char *name, const char *format, va_list arglist) { - unsigned int msg_flags; + unsigned int msg_flags = 0; if (!format) return; diff --git a/main/openvpn/src/openvpn/route.c b/main/openvpn/src/openvpn/route.c index 562af9fe..e8bdcff7 100644 --- a/main/openvpn/src/openvpn/route.c +++ b/main/openvpn/src/openvpn/route.c @@ -1338,15 +1338,18 @@ add_route (struct route_ipv4 *r, #if defined(TARGET_LINUX) #ifdef ENABLE_IPROUTE - /* FIXME -- add on-link support for ENABLE_IPROUTE */ - argv_printf (&argv, "%s route add %s/%d via %s", + argv_printf (&argv, "%s route add %s/%d", iproute_path, network, - count_netmask_bits(netmask), - gateway); + count_netmask_bits(netmask)); + if (r->flags & RT_METRIC_DEFINED) argv_printf_cat (&argv, "metric %d", r->metric); + if (is_on_link (is_local_route, flags, rgi)) + argv_printf_cat (&argv, "dev %s", rgi->iface); + else + argv_printf_cat (&argv, "via %s", gateway); #else argv_printf (&argv, "%s add -net %s netmask %s", ROUTE_PATH, diff --git a/main/openvpn/src/openvpn/sig.c b/main/openvpn/src/openvpn/sig.c index 90e39a42..a3d29de0 100644 --- a/main/openvpn/src/openvpn/sig.c +++ b/main/openvpn/src/openvpn/sig.c @@ -126,7 +126,7 @@ print_signal (const struct signal_info *si, const char *title, int msglevel) { const char *type = (si->signal_text ? si->signal_text : ""); const char *t = (title ? title : "process"); - const char *hs; + const char *hs = NULL; switch (si->source) { case SIG_SOURCE_SOFT: diff --git a/main/openvpn/src/openvpn/socket.c b/main/openvpn/src/openvpn/socket.c index 9e6bd10c..c649d627 100644 --- a/main/openvpn/src/openvpn/socket.c +++ b/main/openvpn/src/openvpn/socket.c @@ -2354,12 +2354,12 @@ print_sockaddr_ex (const struct sockaddr *sa, struct gc_arena *gc) { struct buffer out = alloc_buf_gc (128, gc); - bool addr_is_defined; + bool addr_is_defined = false; char hostaddr[NI_MAXHOST] = ""; char servname[NI_MAXSERV] = ""; int status; - socklen_t salen; + socklen_t salen = 0; switch(sa->sa_family) { case AF_INET: diff --git a/main/openvpn/src/openvpn/ssl_polarssl.c b/main/openvpn/src/openvpn/ssl_polarssl.c index ddccf1d9..62c110b4 100644 --- a/main/openvpn/src/openvpn/ssl_polarssl.c +++ b/main/openvpn/src/openvpn/ssl_polarssl.c @@ -40,6 +40,7 @@ #include "errlevel.h" #include "ssl_backend.h" +#include "base64.h" #include "buffer.h" #include "misc.h" #include "manage.h" @@ -49,8 +50,10 @@ #include "ssl_verify_polarssl.h" #include +#include #include #include +#include void tls_init_lib() @@ -210,12 +213,13 @@ tls_ctx_restrict_ciphers(struct tls_root_ctx *ctx, const char *ciphers) void tls_ctx_load_dh_params (struct tls_root_ctx *ctx, const char *dh_file, - const char *dh_file_inline + const char *dh_inline ) { - if (!strcmp (dh_file, INLINE_FILE_TAG) && dh_file_inline) + if (!strcmp (dh_file, INLINE_FILE_TAG) && dh_inline) { - if (0 != dhm_parse_dhm(ctx->dhm_ctx, dh_file_inline, strlen(dh_file_inline))) + if (0 != dhm_parse_dhm(ctx->dhm_ctx, (const unsigned char *) dh_inline, + strlen(dh_inline))) msg (M_FATAL, "Cannot read inline DH parameters"); } else @@ -257,15 +261,15 @@ tls_ctx_load_cryptoapi(struct tls_root_ctx *ctx, const char *cryptoapi_cert) void tls_ctx_load_cert_file (struct tls_root_ctx *ctx, const char *cert_file, - const char *cert_file_inline + const char *cert_inline ) { ASSERT(NULL != ctx); - if (!strcmp (cert_file, INLINE_FILE_TAG) && cert_file_inline) + if (!strcmp (cert_file, INLINE_FILE_TAG) && cert_inline) { - if (0 != x509_crt_parse(ctx->crt_chain, cert_file_inline, - strlen(cert_file_inline))) + if (0 != x509_crt_parse(ctx->crt_chain, + (const unsigned char *) cert_inline, strlen(cert_inline))) msg (M_FATAL, "Cannot load inline certificate file"); } else @@ -282,16 +286,16 @@ tls_ctx_load_cert_file (struct tls_root_ctx *ctx, const char *cert_file, int tls_ctx_load_priv_file (struct tls_root_ctx *ctx, const char *priv_key_file, - const char *priv_key_file_inline + const char *priv_key_inline ) { int status; ASSERT(NULL != ctx); - if (!strcmp (priv_key_file, INLINE_FILE_TAG) && priv_key_file_inline) + if (!strcmp (priv_key_file, INLINE_FILE_TAG) && priv_key_inline) { status = pk_parse_key(ctx->priv_key, - priv_key_file_inline, strlen(priv_key_file_inline), + (const unsigned char *) priv_key_inline, strlen(priv_key_inline), NULL, 0); if (POLARSSL_ERR_PEM_PASSWORD_REQUIRED == status) @@ -299,7 +303,7 @@ tls_ctx_load_priv_file (struct tls_root_ctx *ctx, const char *priv_key_file, char passbuf[512] = {0}; pem_password_callback(passbuf, 512, 0, NULL); status = pk_parse_key(ctx->priv_key, - priv_key_file_inline, strlen(priv_key_file_inline), + (const unsigned char *) priv_key_inline, strlen(priv_key_inline), (unsigned char *) passbuf, strlen(passbuf)); } } diff --git a/main/openvpn/src/openvpn/ssl_verify_openssl.c b/main/openvpn/src/openvpn/ssl_verify_openssl.c index cbcff022..56e1c11a 100644 --- a/main/openvpn/src/openvpn/ssl_verify_openssl.c +++ b/main/openvpn/src/openvpn/ssl_verify_openssl.c @@ -140,8 +140,8 @@ bool extract_x509_extension(X509 *cert, char *fieldname, char *out, int size) } break; default: - msg (D_TLS_ERRORS, "ASN1 ERROR: can not handle field type %i", - name->type); + msg (D_TLS_DEBUG, "%s: ignoring general name field type %i", + __func__, name->type); break; } } -- cgit v1.2.3