From 63862ed15e1abb4b29c5a43b469321c928613c62 Mon Sep 17 00:00:00 2001 From: Alberto Gonzalez Iniesta Date: Wed, 29 Oct 2014 17:43:51 +0100 Subject: Imported Upstream version 2.3.5 --- ChangeLog | 71 +++++- Makefile.in | 4 + README.polarssl | 4 +- build/Makefile.in | 4 + build/msvc/Makefile.in | 4 + build/msvc/msvc-generate/Makefile.in | 4 + config-msvc.h | 3 + config.h.in | 14 +- configure | 404 +++++++++++++++++++++++++++++++-- configure.ac | 38 +++- contrib/OCSP_check/OCSP_check.sh | 13 +- distro/Makefile.in | 4 + distro/rpm/Makefile.in | 4 + distro/rpm/openvpn.init.d.rhel | 2 +- distro/rpm/openvpn.init.d.suse | 2 +- distro/rpm/openvpn.spec | 2 +- doc/Makefile.in | 4 + doc/openvpn.8 | 57 ++++- include/Makefile.in | 4 + sample/Makefile.in | 4 + sample/sample-config-files/server.conf | 9 +- src/Makefile.in | 4 + src/compat/Makefile.in | 4 + src/openvpn/Makefile.am | 1 + src/openvpn/Makefile.in | 9 +- src/openvpn/base64.c | 2 +- src/openvpn/console.c | 16 +- src/openvpn/crypto.c | 42 ++-- src/openvpn/crypto.h | 4 - src/openvpn/crypto_backend.h | 30 +++ src/openvpn/crypto_openssl.c | 86 ++++--- src/openvpn/crypto_polarssl.c | 21 ++ src/openvpn/forward.c | 9 + src/openvpn/helper.c | 6 +- src/openvpn/init.c | 12 +- src/openvpn/misc.c | 13 +- src/openvpn/multi.c | 27 ++- src/openvpn/options.c | 41 +++- src/openvpn/options.h | 2 + src/openvpn/route.c | 11 +- src/openvpn/socket.c | 5 +- src/openvpn/socket.h | 2 +- src/openvpn/ssl_backend.h | 2 +- src/openvpn/ssl_openssl.c | 9 +- src/openvpn/ssl_polarssl.c | 54 +++-- src/openvpn/ssl_verify_openssl.c | 6 +- src/openvpn/ssl_verify_polarssl.c | 9 +- src/openvpn/syshead.h | 8 + src/openvpn/tun.h | 19 ++ src/openvpn/win32.c | 6 +- src/openvpnserv/Makefile.in | 4 + src/plugins/Makefile.in | 4 + src/plugins/auth-pam/Makefile.in | 4 + src/plugins/down-root/Makefile.in | 4 + tests/Makefile.in | 4 + tests/t_lpback.sh | 33 ++- version.m4 | 4 +- 57 files changed, 982 insertions(+), 190 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6018bd9..08c4cc0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,74 @@ OpenVPN Change Log -Copyright (C) 2002-2012 OpenVPN Technologies, Inc. +Copyright (C) 2002-2014 OpenVPN Technologies, Inc. + +2014.10.24 -- Version 2.3.5 +Andris Kalnozols (2): + Fix some typos in the man page. + Do not upcase x509-username-field for mixed-case arguments. + +Arne Schwabe (1): + Fix server routes not working in topology subnet with --server [v3] + +David Sommerseth (4): + Improve error reporting on file access to --client-config-dir and --ccd-exclusive + Don't let openvpn_popen() keep zombies around + Add systemd unit file for OpenVPN + systemd: Use systemd functions to consider systemd availability + +Gert Doering (3): + Drop incoming fe80:: packets silently now. + Fix t_lpback.sh platform-dependent failures + Call init script helpers with explicit path (./) + +Heiko Hund (1): + refine assertion to allow other modes than CBC + +Hubert Kario (2): + ocsp_check - signature verification and cert staus results are separate + ocsp_check - double check if ocsp didn't report any errors in execution + +James Bekkema (1): + Fix socket-flag/TCP_NODELAY on Mac OS X + +James Yonan (6): + Fixed several instances of declarations after statements. + In socket.c, fixed issue where uninitialized value (err) is being passed to to gai_strerror. + Explicitly cast the third parameter of setsockopt to const void * to avoid warning. + MSVC 2008 doesn't support dimensioning an array with a const var nor using %z as a printf format specifier. + Define PATH_SEPARATOR for MSVC builds. + Fixed some compile issues with show_library_versions() + +Jann Horn (1): + Remove quadratic complexity from openvpn_base64_decode() + +Mike Gilbert (1): + Add configure check for the path to systemd-ask-password + +Philipp Hagemeister (2): + Add topology in sample server configuration file + Implement on-link route adding for iproute2 + +Samuel Thibault (1): + Ensure that client-connect files are always deleted + +Steffan Karger (13): + Remove function without effect (cipher_ok() always returned true). + Remove unneeded wrapper functions in crypto_openssl.c + Fix bug that incorrectly refuses oid representation eku's in polar builds + Update README.polarssl + Rename ALLOW_NON_CBC_CIPHERS to ENABLE_OFB_CFB_MODE, and add to configure. + Add proper check for crypto modes (CBC or OFB/CFB) + Improve --show-ciphers to show if a cipher can be used in static key mode + Extend t_lpback tests to test all ciphers reported by --show-ciphers + Don't exit daemon if opening or parsing the CRL fails. + Fix typo in cipher_kt_mode_{cbc, ofb_cfb}() doxygen. + Fix regression with password protected private keys (polarssl) + ssl_polarssl.c: fix includes and make casts explicit + Remove unused variables from ssl_verify_openssl.c extract_x509_extension() + +TDivine (1): + Fix "code=995" bug with windows NDIS6 tap driver. + 2014.04.30 -- Version 2.3.4 Arne Schwabe (1): diff --git a/Makefile.in b/Makefile.in index 4f524e0..82a762e 100644 --- a/Makefile.in +++ b/Makefile.in @@ -335,6 +335,7 @@ OPTIONAL_LZO_LIBS = @OPTIONAL_LZO_LIBS@ OPTIONAL_PKCS11_HELPER_CFLAGS = @OPTIONAL_PKCS11_HELPER_CFLAGS@ OPTIONAL_PKCS11_HELPER_LIBS = @OPTIONAL_PKCS11_HELPER_LIBS@ OPTIONAL_SELINUX_LIBS = @OPTIONAL_SELINUX_LIBS@ +OPTIONAL_SYSTEMD_LIBS = @OPTIONAL_SYSTEMD_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ @@ -363,6 +364,7 @@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SOCKETS_LIBS = @SOCKETS_LIBS@ STRIP = @STRIP@ +SYSTEMD_ASK_PASSWORD = @SYSTEMD_ASK_PASSWORD@ TAP_CFLAGS = @TAP_CFLAGS@ TAP_WIN_COMPONENT_ID = @TAP_WIN_COMPONENT_ID@ TAP_WIN_MIN_MAJOR = @TAP_WIN_MIN_MAJOR@ @@ -403,6 +405,8 @@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ +libsystemd_CFLAGS = @libsystemd_CFLAGS@ +libsystemd_LIBS = @libsystemd_LIBS@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ diff --git a/README.polarssl b/README.polarssl index ab7c2d7..06f30bf 100644 --- a/README.polarssl +++ b/README.polarssl @@ -7,7 +7,7 @@ To Build and Install, make make install -This version depends on at least PolarSSL v1.1. +This version depends on PolarSSL 1.2 (and requires at least 1.2.10). ************************************************************************* @@ -17,12 +17,10 @@ in the PolarSSL version of OpenVPN: * PKCS#12 file support * --capath support - Loading certificate authorities from a directory * Windows CryptoAPI support - * Management external key support * X.509 alternative username fields (must be "CN") Plugin/Script features: - * X.509 Serial number is in hex, not decimal as with OpenSSL * X.509 subject line has a different format than the OpenSSL subject line * X.509 certificate export does not work * X.509 certificate tracking diff --git a/build/Makefile.in b/build/Makefile.in index 124d3f8..32f3dfa 100644 --- a/build/Makefile.in +++ b/build/Makefile.in @@ -253,6 +253,7 @@ OPTIONAL_LZO_LIBS = @OPTIONAL_LZO_LIBS@ OPTIONAL_PKCS11_HELPER_CFLAGS = @OPTIONAL_PKCS11_HELPER_CFLAGS@ OPTIONAL_PKCS11_HELPER_LIBS = @OPTIONAL_PKCS11_HELPER_LIBS@ OPTIONAL_SELINUX_LIBS = @OPTIONAL_SELINUX_LIBS@ +OPTIONAL_SYSTEMD_LIBS = @OPTIONAL_SYSTEMD_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ @@ -281,6 +282,7 @@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SOCKETS_LIBS = @SOCKETS_LIBS@ STRIP = @STRIP@ +SYSTEMD_ASK_PASSWORD = @SYSTEMD_ASK_PASSWORD@ TAP_CFLAGS = @TAP_CFLAGS@ TAP_WIN_COMPONENT_ID = @TAP_WIN_COMPONENT_ID@ TAP_WIN_MIN_MAJOR = @TAP_WIN_MIN_MAJOR@ @@ -321,6 +323,8 @@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ +libsystemd_CFLAGS = @libsystemd_CFLAGS@ +libsystemd_LIBS = @libsystemd_LIBS@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ diff --git a/build/msvc/Makefile.in b/build/msvc/Makefile.in index 6f0613d..f5cbb6b 100644 --- a/build/msvc/Makefile.in +++ b/build/msvc/Makefile.in @@ -254,6 +254,7 @@ OPTIONAL_LZO_LIBS = @OPTIONAL_LZO_LIBS@ OPTIONAL_PKCS11_HELPER_CFLAGS = @OPTIONAL_PKCS11_HELPER_CFLAGS@ OPTIONAL_PKCS11_HELPER_LIBS = @OPTIONAL_PKCS11_HELPER_LIBS@ OPTIONAL_SELINUX_LIBS = @OPTIONAL_SELINUX_LIBS@ +OPTIONAL_SYSTEMD_LIBS = @OPTIONAL_SYSTEMD_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ @@ -282,6 +283,7 @@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SOCKETS_LIBS = @SOCKETS_LIBS@ STRIP = @STRIP@ +SYSTEMD_ASK_PASSWORD = @SYSTEMD_ASK_PASSWORD@ TAP_CFLAGS = @TAP_CFLAGS@ TAP_WIN_COMPONENT_ID = @TAP_WIN_COMPONENT_ID@ TAP_WIN_MIN_MAJOR = @TAP_WIN_MIN_MAJOR@ @@ -322,6 +324,8 @@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ +libsystemd_CFLAGS = @libsystemd_CFLAGS@ +libsystemd_LIBS = @libsystemd_LIBS@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ diff --git a/build/msvc/msvc-generate/Makefile.in b/build/msvc/msvc-generate/Makefile.in index 2d28143..60b4e6a 100644 --- a/build/msvc/msvc-generate/Makefile.in +++ b/build/msvc/msvc-generate/Makefile.in @@ -197,6 +197,7 @@ OPTIONAL_LZO_LIBS = @OPTIONAL_LZO_LIBS@ OPTIONAL_PKCS11_HELPER_CFLAGS = @OPTIONAL_PKCS11_HELPER_CFLAGS@ OPTIONAL_PKCS11_HELPER_LIBS = @OPTIONAL_PKCS11_HELPER_LIBS@ OPTIONAL_SELINUX_LIBS = @OPTIONAL_SELINUX_LIBS@ +OPTIONAL_SYSTEMD_LIBS = @OPTIONAL_SYSTEMD_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ @@ -225,6 +226,7 @@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SOCKETS_LIBS = @SOCKETS_LIBS@ STRIP = @STRIP@ +SYSTEMD_ASK_PASSWORD = @SYSTEMD_ASK_PASSWORD@ TAP_CFLAGS = @TAP_CFLAGS@ TAP_WIN_COMPONENT_ID = @TAP_WIN_COMPONENT_ID@ TAP_WIN_MIN_MAJOR = @TAP_WIN_MIN_MAJOR@ @@ -265,6 +267,8 @@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ +libsystemd_CFLAGS = @libsystemd_CFLAGS@ +libsystemd_LIBS = @libsystemd_LIBS@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ diff --git a/config-msvc.h b/config-msvc.h index 9a95ae6..fa99384 100644 --- a/config-msvc.h +++ b/config-msvc.h @@ -76,6 +76,9 @@ #define HAVE_OPENSSL_ENGINE 1 +#define PATH_SEPARATOR '\\' +#define PATH_SEPARATOR_STR "\\" + #ifndef __cplusplus #define inline __inline #endif diff --git a/config.h.in b/config.h.in index 1817b2b..33a814d 100644 --- a/config.h.in +++ b/config.h.in @@ -60,6 +60,9 @@ /* Enable multi-homed UDP server capability */ #undef ENABLE_MULTIHOME +/* Enable OFB and CFB cipher modes */ +#undef ENABLE_OFB_CFB_MODE + /* Allow --askpass and --auth-user-pass passwords to be read from a file */ #undef ENABLE_PASSWORD_SAVE @@ -90,7 +93,7 @@ /* Enable strict options check between peers */ #undef ENABLE_STRICT_OPTIONS_CHECK -/* Enable systemd support */ +/* Enable systemd integration */ #undef ENABLE_SYSTEMD /* Enable --x509-username-field feature */ @@ -394,6 +397,9 @@ /* Define to 1 if you have the `res_init' function. */ #undef HAVE_RES_INIT +/* Define to 1 if you have the `sd_booted' function. */ +#undef HAVE_SD_BOOTED + /* Define to 1 if you have the `select' function. */ #undef HAVE_SELECT @@ -472,6 +478,9 @@ /* Define to 1 if you have the `system' function. */ #undef HAVE_SYSTEM +/* Define to 1 if you have the header file. */ +#undef HAVE_SYSTEMD_SD_DAEMON_H + /* Define to 1 if you have the header file. */ #undef HAVE_SYS_EPOLL_H @@ -629,6 +638,9 @@ /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS +/* Path to systemd-ask-password tool */ +#undef SYSTEMD_ASK_PASSWORD_PATH + /* The tap-windows id */ #undef TAP_WIN_COMPONENT_ID diff --git a/configure b/configure index 8638bf2..cc8e3d2 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for OpenVPN 2.3.4. +# Generated by GNU Autoconf 2.69 for OpenVPN 2.3.5. # # Report bugs to . # @@ -590,8 +590,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='OpenVPN' PACKAGE_TARNAME='openvpn' -PACKAGE_VERSION='2.3.4' -PACKAGE_STRING='OpenVPN 2.3.4' +PACKAGE_VERSION='2.3.5' +PACKAGE_STRING='OpenVPN 2.3.5' PACKAGE_BUGREPORT='openvpn-users@lists.sourceforge.net' PACKAGE_URL='' @@ -650,6 +650,7 @@ PLUGIN_AUTH_PAM_LIBS PLUGIN_AUTH_PAM_CFLAGS OPTIONAL_PKCS11_HELPER_LIBS OPTIONAL_PKCS11_HELPER_CFLAGS +OPTIONAL_SYSTEMD_LIBS OPTIONAL_LZO_LIBS OPTIONAL_LZO_CFLAGS OPTIONAL_CRYPTO_LIBS @@ -659,6 +660,8 @@ OPTIONAL_DL_LIBS TAP_WIN_MIN_MINOR TAP_WIN_MIN_MAJOR TAP_WIN_COMPONENT_ID +libsystemd_LIBS +libsystemd_CFLAGS LZO_LIBS LZO_CFLAGS POLARSSL_LIBS @@ -694,6 +697,7 @@ LIBTOOL OBJDUMP DLLTOOL AS +SYSTEMD_ASK_PASSWORD GIT MAN2HTML NETSTAT @@ -806,6 +810,7 @@ enable_dependency_tracking enable_lzo enable_lzo_stub enable_crypto +enable_ofb_cfb enable_ssl enable_x509_alt_username enable_multi @@ -862,6 +867,7 @@ IPROUTE NETSTAT MAN2HTML GIT +SYSTEMD_ASK_PASSWORD TAP_CFLAGS LIBPAM_CFLAGS LIBPAM_LIBS @@ -874,7 +880,9 @@ OPENSSL_SSL_LIBS POLARSSL_CFLAGS POLARSSL_LIBS LZO_CFLAGS -LZO_LIBS' +LZO_LIBS +libsystemd_CFLAGS +libsystemd_LIBS' # Initialize some variables set by options. @@ -1415,7 +1423,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures OpenVPN 2.3.4 to adapt to many kinds of systems. +\`configure' configures OpenVPN 2.3.5 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1485,7 +1493,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of OpenVPN 2.3.4:";; + short | recursive ) echo "Configuration of OpenVPN 2.3.5:";; esac cat <<\_ACEOF @@ -1504,6 +1512,8 @@ Optional Features: allow limited interoperability with LZO-enabled peers [default=no] --disable-crypto disable crypto support [default=yes] + --enable-ofb-cfb enable support for OFB and CFB cipher modes + [default=yes] --disable-ssl disable SSL support for TLS-based key exchange [default=yes] --enable-x509-alt-username @@ -1589,6 +1599,8 @@ Some influential environment variables: NETSTAT path to netstat utility MAN2HTML path to man2html utility GIT path to git utility + SYSTEMD_ASK_PASSWORD + path to systemd-ask-password utility TAP_CFLAGS C compiler flags for tap LIBPAM_CFLAGS C compiler flags for libpam @@ -1611,6 +1623,10 @@ Some influential environment variables: linker flags for polarssl LZO_CFLAGS C compiler flags for lzo LZO_LIBS linker flags for lzo + libsystemd_CFLAGS + C compiler flags for libsystemd, overriding pkg-config + libsystemd_LIBS + linker flags for libsystemd, overriding pkg-config Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. @@ -1678,7 +1694,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -OpenVPN configure 2.3.4 +OpenVPN configure 2.3.5 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -2460,7 +2476,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by OpenVPN $as_me 2.3.4, which was +It was created by OpenVPN $as_me 2.3.5, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -2824,7 +2840,7 @@ if test -z "${htmldir}"; then fi -$as_echo "#define OPENVPN_VERSION_RESOURCE 2,3,4,0" >>confdefs.h +$as_echo "#define OPENVPN_VERSION_RESOURCE 2,3,5,0" >>confdefs.h ac_aux_dir= @@ -3346,7 +3362,7 @@ fi # Define the identity of the package. PACKAGE='openvpn' - VERSION='2.3.4' + VERSION='2.3.5' cat >>confdefs.h <<_ACEOF @@ -5035,6 +5051,15 @@ else fi +# Check whether --enable-ofb-cfb was given. +if test "${enable_ofb_cfb+set}" = set; then : + enableval=$enable_ofb_cfb; +else + enable_crypto_ofb_cfb="yes" + +fi + + # Check whether --enable-ssl was given. if test "${enable_ssl+set}" = set; then : enableval=$enable_ssl; @@ -5810,6 +5835,7 @@ fi # tests + for ac_prog in ifconfig do # Extract the first word of "$ac_prog", so it can be a program name with args. @@ -5948,6 +5974,52 @@ fi test -n "$IPROUTE" && break done +for ac_prog in systemd-ask-password +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_SYSTEMD_ASK_PASSWORD+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $SYSTEMD_ASK_PASSWORD in + [\\/]* | ?:[\\/]*) + ac_cv_path_SYSTEMD_ASK_PASSWORD="$SYSTEMD_ASK_PASSWORD" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_dummy="$PATH:/usr/local/bin:/usr/bin:/bin" +for as_dir in $as_dummy +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_SYSTEMD_ASK_PASSWORD="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +SYSTEMD_ASK_PASSWORD=$ac_cv_path_SYSTEMD_ASK_PASSWORD +if test -n "$SYSTEMD_ASK_PASSWORD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $SYSTEMD_ASK_PASSWORD" >&5 +$as_echo "$SYSTEMD_ASK_PASSWORD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$SYSTEMD_ASK_PASSWORD" && break +done + for ac_prog in netstat do # Extract the first word of "$ac_prog", so it can be a program name with args. @@ -6092,6 +6164,11 @@ cat >>confdefs.h <<_ACEOF _ACEOF +cat >>confdefs.h <<_ACEOF +#define SYSTEMD_ASK_PASSWORD_PATH "$SYSTEMD_ASK_PASSWORD" +_ACEOF + + # # Libtool # @@ -16161,6 +16238,302 @@ done CFLAGS="${saved_CFLAGS}" fi + + +if test "$enable_systemd" = "yes" ; then + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for libsystemd" >&5 +$as_echo_n "checking for libsystemd... " >&6; } + +if test -n "$libsystemd_CFLAGS"; then + pkg_cv_libsystemd_CFLAGS="$libsystemd_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"systemd libsystemd\""; } >&5 + ($PKG_CONFIG --exists --print-errors "systemd libsystemd") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_libsystemd_CFLAGS=`$PKG_CONFIG --cflags "systemd libsystemd" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$libsystemd_LIBS"; then + pkg_cv_libsystemd_LIBS="$libsystemd_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"systemd libsystemd\""; } >&5 + ($PKG_CONFIG --exists --print-errors "systemd libsystemd") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_libsystemd_LIBS=`$PKG_CONFIG --libs "systemd libsystemd" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + libsystemd_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "systemd libsystemd" 2>&1` + else + libsystemd_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "systemd libsystemd" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$libsystemd_PKG_ERRORS" >&5 + + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for libsystemd" >&5 +$as_echo_n "checking for libsystemd... " >&6; } + +if test -n "$libsystemd_CFLAGS"; then + pkg_cv_libsystemd_CFLAGS="$libsystemd_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libsystemd-daemon\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libsystemd-daemon") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_libsystemd_CFLAGS=`$PKG_CONFIG --cflags "libsystemd-daemon" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$libsystemd_LIBS"; then + pkg_cv_libsystemd_LIBS="$libsystemd_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libsystemd-daemon\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libsystemd-daemon") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_libsystemd_LIBS=`$PKG_CONFIG --libs "libsystemd-daemon" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + libsystemd_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libsystemd-daemon" 2>&1` + else + libsystemd_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libsystemd-daemon" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$libsystemd_PKG_ERRORS" >&5 + + as_fn_error $? "Package requirements (libsystemd-daemon) were not met: + +$libsystemd_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +Alternatively, you may set the environment variables libsystemd_CFLAGS +and libsystemd_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details." "$LINENO" 5 +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +Alternatively, you may set the environment variables libsystemd_CFLAGS +and libsystemd_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details. + +To get pkg-config, see . +See \`config.log' for more details" "$LINENO" 5; } +else + libsystemd_CFLAGS=$pkg_cv_libsystemd_CFLAGS + libsystemd_LIBS=$pkg_cv_libsystemd_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +fi + +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for libsystemd" >&5 +$as_echo_n "checking for libsystemd... " >&6; } + +if test -n "$libsystemd_CFLAGS"; then + pkg_cv_libsystemd_CFLAGS="$libsystemd_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libsystemd-daemon\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libsystemd-daemon") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_libsystemd_CFLAGS=`$PKG_CONFIG --cflags "libsystemd-daemon" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$libsystemd_LIBS"; then + pkg_cv_libsystemd_LIBS="$libsystemd_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libsystemd-daemon\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libsystemd-daemon") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_libsystemd_LIBS=`$PKG_CONFIG --libs "libsystemd-daemon" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + libsystemd_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libsystemd-daemon" 2>&1` + else + libsystemd_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libsystemd-daemon" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$libsystemd_PKG_ERRORS" >&5 + + as_fn_error $? "Package requirements (libsystemd-daemon) were not met: + +$libsystemd_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +Alternatively, you may set the environment variables libsystemd_CFLAGS +and libsystemd_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details." "$LINENO" 5 +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +Alternatively, you may set the environment variables libsystemd_CFLAGS +and libsystemd_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details. + +To get pkg-config, see . +See \`config.log' for more details" "$LINENO" 5; } +else + libsystemd_CFLAGS=$pkg_cv_libsystemd_CFLAGS + libsystemd_LIBS=$pkg_cv_libsystemd_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +fi + +else + libsystemd_CFLAGS=$pkg_cv_libsystemd_CFLAGS + libsystemd_LIBS=$pkg_cv_libsystemd_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +fi + for ac_header in systemd/sd-daemon.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "systemd/sd-daemon.h" "ac_cv_header_systemd_sd_daemon_h" "$ac_includes_default" +if test "x$ac_cv_header_systemd_sd_daemon_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_SYSTEMD_SD_DAEMON_H 1 +_ACEOF + +else + + as_fn_error $? "systemd development headers not found." "$LINENO" 5 + +fi + +done + + + saved_LIBS="${LIBS}" + LIBS="${LIBS} ${libsystemd_LIBS}" + for ac_func in sd_booted +do : + ac_fn_c_check_func "$LINENO" "sd_booted" "ac_cv_func_sd_booted" +if test "x$ac_cv_func_sd_booted" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_SD_BOOTED 1 +_ACEOF + +else + as_fn_error $? "systemd library is missing sd_booted()" "$LINENO" 5 +fi +done + + OPTIONAL_SYSTEMD_LIBS="${libsystemd_LIBS}" + +$as_echo "#define ENABLE_SYSTEMD 1" >>confdefs.h + + LIBS="${saved_LIBS}" +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking git checkout" >&5 $as_echo_n "checking git checkout... " >&6; } GIT_CHECKOUT="no" @@ -16252,9 +16625,6 @@ $as_echo "#define ENABLE_STRICT_OPTIONS_CHECK 1" >>confdefs.h test "${enable_password_save}" = "yes" && $as_echo "#define ENABLE_PASSWORD_SAVE 1" >>confdefs.h -test "${enable_systemd}" = "yes" && -$as_echo "#define ENABLE_SYSTEMD 1" >>confdefs.h - case "${with_crypto_library}" in openssl) @@ -16294,6 +16664,9 @@ fi if test "${enable_crypto}" = "yes"; then test "${have_crypto_crypto}" != "yes" && as_fn_error $? "${with_crypto_library} crypto is required but missing" "$LINENO" 5 + test "${enable_crypto_ofb_cfb}" = "yes" && +$as_echo "#define ENABLE_OFB_CFB_MODE 1" >>confdefs.h + OPTIONAL_CRYPTO_CFLAGS="${OPTIONAL_CRYPTO_CFLAGS} ${CRYPTO_CRYPTO_CFLAGS}" OPTIONAL_CRYPTO_LIBS="${OPTIONAL_CRYPTO_LIBS} ${CRYPTO_CRYPTO_LIBS}" @@ -16426,6 +16799,7 @@ _ACEOF + if test "${WIN32}" = "yes"; then WIN32_TRUE= WIN32_FALSE='#' @@ -17014,7 +17388,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by OpenVPN $as_me 2.3.4, which was +This file was extended by OpenVPN $as_me 2.3.5, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -17080,7 +17454,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -OpenVPN config.status 2.3.4 +OpenVPN config.status 2.3.5 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/configure.ac b/configure.ac index 6ad8ff4..0e0fae5 100644 --- a/configure.ac +++ b/configure.ac @@ -60,6 +60,13 @@ AC_ARG_ENABLE( [enable_crypto="yes"] ) +AC_ARG_ENABLE( + [ofb-cfb], + [AS_HELP_STRING([--enable-ofb-cfb], [enable support for OFB and CFB cipher modes @<:@default=yes@:>@])], + , + [enable_crypto_ofb_cfb="yes"] +) + AC_ARG_ENABLE( [ssl], [AS_HELP_STRING([--disable-ssl], [disable SSL support for TLS-based key exchange @<:@default=yes@:>@])], @@ -350,15 +357,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 @@ -890,6 +900,31 @@ if test "${have_lzo}" = "yes"; then CFLAGS="${saved_CFLAGS}" 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]) GIT_CHECKOUT="no" if test -n "${GIT}" -a -d "${srcdir}/.git"; then @@ -930,7 +965,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) @@ -962,6 +996,7 @@ fi if test "${enable_crypto}" = "yes"; then test "${have_crypto_crypto}" != "yes" && AC_MSG_ERROR([${with_crypto_library} crypto is required but missing]) + test "${enable_crypto_ofb_cfb}" = "yes" && AC_DEFINE([ENABLE_OFB_CFB_MODE], [1], [Enable OFB and CFB cipher modes]) OPTIONAL_CRYPTO_CFLAGS="${OPTIONAL_CRYPTO_CFLAGS} ${CRYPTO_CRYPTO_CFLAGS}" OPTIONAL_CRYPTO_LIBS="${OPTIONAL_CRYPTO_LIBS} ${CRYPTO_CRYPTO_LIBS}" AC_DEFINE([ENABLE_CRYPTO], [1], [Enable crypto library]) @@ -1054,6 +1089,7 @@ AC_SUBST([OPTIONAL_CRYPTO_CFLAGS]) AC_SUBST([OPTIONAL_CRYPTO_LIBS]) AC_SUBST([OPTIONAL_LZO_CFLAGS]) AC_SUBST([OPTIONAL_LZO_LIBS]) +AC_SUBST([OPTIONAL_SYSTEMD_LIBS]) AC_SUBST([OPTIONAL_PKCS11_HELPER_CFLAGS]) AC_SUBST([OPTIONAL_PKCS11_HELPER_LIBS]) diff --git a/contrib/OCSP_check/OCSP_check.sh b/contrib/OCSP_check/OCSP_check.sh index 553c3dc..6876c6d 100644 --- a/contrib/OCSP_check/OCSP_check.sh +++ b/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/distro/Makefile.in b/distro/Makefile.in index 9460a9d..3f47a83 100644 --- a/distro/Makefile.in +++ b/distro/Makefile.in @@ -254,6 +254,7 @@ OPTIONAL_LZO_LIBS = @OPTIONAL_LZO_LIBS@ OPTIONAL_PKCS11_HELPER_CFLAGS = @OPTIONAL_PKCS11_HELPER_CFLAGS@ OPTIONAL_PKCS11_HELPER_LIBS = @OPTIONAL_PKCS11_HELPER_LIBS@ OPTIONAL_SELINUX_LIBS = @OPTIONAL_SELINUX_LIBS@ +OPTIONAL_SYSTEMD_LIBS = @OPTIONAL_SYSTEMD_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ @@ -282,6 +283,7 @@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SOCKETS_LIBS = @SOCKETS_LIBS@ STRIP = @STRIP@ +SYSTEMD_ASK_PASSWORD = @SYSTEMD_ASK_PASSWORD@ TAP_CFLAGS = @TAP_CFLAGS@ TAP_WIN_COMPONENT_ID = @TAP_WIN_COMPONENT_ID@ TAP_WIN_MIN_MAJOR = @TAP_WIN_MIN_MAJOR@ @@ -322,6 +324,8 @@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ +libsystemd_CFLAGS = @libsystemd_CFLAGS@ +libsystemd_LIBS = @libsystemd_LIBS@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ diff --git a/distro/rpm/Makefile.in b/distro/rpm/Makefile.in index fc2040b..d4253c6 100644 --- a/distro/rpm/Makefile.in +++ b/distro/rpm/Makefile.in @@ -197,6 +197,7 @@ OPTIONAL_LZO_LIBS = @OPTIONAL_LZO_LIBS@ OPTIONAL_PKCS11_HELPER_CFLAGS = @OPTIONAL_PKCS11_HELPER_CFLAGS@ OPTIONAL_PKCS11_HELPER_LIBS = @OPTIONAL_PKCS11_HELPER_LIBS@ OPTIONAL_SELINUX_LIBS = @OPTIONAL_SELINUX_LIBS@ +OPTIONAL_SYSTEMD_LIBS = @OPTIONAL_SYSTEMD_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ @@ -225,6 +226,7 @@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SOCKETS_LIBS = @SOCKETS_LIBS@ STRIP = @STRIP@ +SYSTEMD_ASK_PASSWORD = @SYSTEMD_ASK_PASSWORD@ TAP_CFLAGS = @TAP_CFLAGS@ TAP_WIN_COMPONENT_ID = @TAP_WIN_COMPONENT_ID@ TAP_WIN_MIN_MAJOR = @TAP_WIN_MIN_MAJOR@ @@ -265,6 +267,8 @@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ +libsystemd_CFLAGS = @libsystemd_CFLAGS@ +libsystemd_LIBS = @libsystemd_LIBS@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ diff --git a/distro/rpm/openvpn.init.d.rhel b/distro/rpm/openvpn.init.d.rhel index 821abd5..cdf3e9d 100755 --- a/distro/rpm/openvpn.init.d.rhel +++ b/distro/rpm/openvpn.init.d.rhel @@ -148,7 +148,7 @@ case "$1" in for c in `/bin/ls *.conf 2>/dev/null`; do bn=${c%%.conf} if [ -f "$bn.sh" ]; then - . $bn.sh + . ./$bn.sh fi rm -f $piddir/$bn.pid $openvpn --daemon --writepid $piddir/$bn.pid --config $c --cd $work diff --git a/distro/rpm/openvpn.init.d.suse b/distro/rpm/openvpn.init.d.suse index 2bac7f3..270024e 100644 --- a/distro/rpm/openvpn.init.d.suse +++ b/distro/rpm/openvpn.init.d.suse @@ -161,7 +161,7 @@ case "$1" in for c in `/bin/ls *.conf 2>/dev/null`; do bn=${c%%.conf} if [ -f "$bn.sh" ]; then - . $bn.sh + . ./$bn.sh fi rm -f $piddir/$bn.pid $openvpn --daemon --writepid $piddir/$bn.pid --config $c --cd $work diff --git a/distro/rpm/openvpn.spec b/distro/rpm/openvpn.spec index 1194c54..45637d7 100644 --- a/distro/rpm/openvpn.spec +++ b/distro/rpm/openvpn.spec @@ -13,7 +13,7 @@ Summary: OpenVPN is a robust and highly flexible VPN daemon by James Yonan. Name: openvpn -Version: 2.3.4 +Version: 2.3.5 Release: 1 URL: http://openvpn.net/ Source0: http://prdownloads.sourceforge.net/openvpn/%{name}-%{version}.tar.gz diff --git a/doc/Makefile.in b/doc/Makefile.in index b3783d5..ffb000f 100644 --- a/doc/Makefile.in +++ b/doc/Makefile.in @@ -231,6 +231,7 @@ OPTIONAL_LZO_LIBS = @OPTIONAL_LZO_LIBS@ OPTIONAL_PKCS11_HELPER_CFLAGS = @OPTIONAL_PKCS11_HELPER_CFLAGS@ OPTIONAL_PKCS11_HELPER_LIBS = @OPTIONAL_PKCS11_HELPER_LIBS@ OPTIONAL_SELINUX_LIBS = @OPTIONAL_SELINUX_LIBS@ +OPTIONAL_SYSTEMD_LIBS = @OPTIONAL_SYSTEMD_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ @@ -259,6 +260,7 @@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SOCKETS_LIBS = @SOCKETS_LIBS@ STRIP = @STRIP@ +SYSTEMD_ASK_PASSWORD = @SYSTEMD_ASK_PASSWORD@ TAP_CFLAGS = @TAP_CFLAGS@ TAP_WIN_COMPONENT_ID = @TAP_WIN_COMPONENT_ID@ TAP_WIN_MIN_MAJOR = @TAP_WIN_MIN_MAJOR@ @@ -299,6 +301,8 @@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ +libsystemd_CFLAGS = @libsystemd_CFLAGS@ +libsystemd_LIBS = @libsystemd_LIBS@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ diff --git a/doc/openvpn.8 b/doc/openvpn.8 index 786719d..39b128f 100644 --- a/doc/openvpn.8 +++ b/doc/openvpn.8 @@ -1606,7 +1606,7 @@ and in server mode configurations. The server timeout is set twice the value of the second argument. -This ensures that a timeout is dectected on client side +This ensures that a timeout is detected on client side before the server side drops the connection. For example, @@ -2459,7 +2459,7 @@ Normally, adaptive compression is enabled with .B \-\-comp-lzo. Adaptive compression tries to optimize the case where you have -compression enabled, but you are sending predominantly uncompressible +compression enabled, but you are sending predominantly incompressible (or pre-compressed) packets over the tunnel, such as an FTP or rsync transfer of a large, compressed file. With adaptive compression, OpenVPN will periodically sample the compression process to measure its @@ -2660,7 +2660,7 @@ on sufficiently fast hardware. SSL/TLS authentication must be used in this mode. .\"********************************************************* .TP -.B \-\-server network netmask +.B \-\-server network netmask ['nopool'] A helper directive designed to simplify the configuration of OpenVPN's server mode. This directive will set up an OpenVPN server which will allocate addresses to clients @@ -2695,6 +2695,9 @@ expands as follows: if !nopool: ifconfig-pool 10.8.0.2 10.8.0.254 255.255.255.0 push "route-gateway 10.8.0.1" + if route-gateway unset: + route-gateway 10.8.0.2 + .in -4 .ft .fi @@ -3498,7 +3501,7 @@ like this: .B /C=US/L=Somewhere/CN=John Doe/emailAddress=john@example.com .IP -In addition the old behavivour was to remap any character other than +In addition the old behaviour was to remap any character other than alphanumeric, underscore ('_'), dash ('-'), dot ('.'), and slash ('/') to underscore ('_'). The X.509 Subject string as returned by the .B tls_id @@ -4354,7 +4357,7 @@ A different mode can be specified for each provider. Mode is encoded as hex number, and can be a mask one of the following: .B 0 -(default) \-\- Try to determind automatically. +(default) \-\- Try to determine automatically. .br .B 1 \-\- Use sign. @@ -4745,12 +4748,44 @@ the tls-verify script returns. The file name used for the certificate is available via the peer_cert environment variable. .\"********************************************************* .TP -.B \-\-x509-username-field fieldname -Field in x509 certificate subject to be used as username (default=CN). -.B Fieldname -will be uppercased before matching. When this option is used, the -.B \-\-verify-x509-username -option will match against the chosen fieldname instead of the CN. +.B \-\-x509-username-field [ext:\]fieldname +Field in the X.509 certificate subject to be used as the username (default=CN). +Typically, this option is specified with +.B fieldname +as either of the following: + +.B \-\-x509-username-field +emailAddress +.br +.B \-\-x509-username-field ext:\fRsubjectAltName + +The first example uses the value of the "emailAddress" attribute in the +certificate's Subject field as the username. The second example uses +the +.B ext: +prefix to signify that the X.509 extension +.B fieldname +"subjectAltName" be searched for an rfc822Name (email) field to be used +as the username. In cases where there are multiple email addresses +in +.B ext:fieldname\fR, +the last occurrence is chosen. + +When this option is used, the +.B \-\-verify-x509-name +option will match against the chosen +.B fieldname +instead of the Common Name. + +.B Please note: +This option has a feature which will convert an all-lowercase +.B fieldname +to uppercase characters, e.g., ou -> OU. A mixed-case +.B fieldname +or one having the +.B ext: +prefix will be left as-is. This automatic upcasing feature +is deprecated and will be removed in a future release. .\"********************************************************* .TP .B \-\-tls-remote name (DEPRECATED) diff --git a/include/Makefile.in b/include/Makefile.in index 58f30dc..8bffd21 100644 --- a/include/Makefile.in +++ b/include/Makefile.in @@ -243,6 +243,7 @@ OPTIONAL_LZO_LIBS = @OPTIONAL_LZO_LIBS@ OPTIONAL_PKCS11_HELPER_CFLAGS = @OPTIONAL_PKCS11_HELPER_CFLAGS@ OPTIONAL_PKCS11_HELPER_LIBS = @OPTIONAL_PKCS11_HELPER_LIBS@ OPTIONAL_SELINUX_LIBS = @OPTIONAL_SELINUX_LIBS@ +OPTIONAL_SYSTEMD_LIBS = @OPTIONAL_SYSTEMD_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ @@ -271,6 +272,7 @@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SOCKETS_LIBS = @SOCKETS_LIBS@ STRIP = @STRIP@ +SYSTEMD_ASK_PASSWORD = @SYSTEMD_ASK_PASSWORD@ TAP_CFLAGS = @TAP_CFLAGS@ TAP_WIN_COMPONENT_ID = @TAP_WIN_COMPONENT_ID@ TAP_WIN_MIN_MAJOR = @TAP_WIN_MIN_MAJOR@ @@ -311,6 +313,8 @@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ +libsystemd_CFLAGS = @libsystemd_CFLAGS@ +libsystemd_LIBS = @libsystemd_LIBS@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ diff --git a/sample/Makefile.in b/sample/Makefile.in index 5826959..4e14709 100644 --- a/sample/Makefile.in +++ b/sample/Makefile.in @@ -224,6 +224,7 @@ OPTIONAL_LZO_LIBS = @OPTIONAL_LZO_LIBS@ OPTIONAL_PKCS11_HELPER_CFLAGS = @OPTIONAL_PKCS11_HELPER_CFLAGS@ OPTIONAL_PKCS11_HELPER_LIBS = @OPTIONAL_PKCS11_HELPER_LIBS@ OPTIONAL_SELINUX_LIBS = @OPTIONAL_SELINUX_LIBS@ +OPTIONAL_SYSTEMD_LIBS = @OPTIONAL_SYSTEMD_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ @@ -252,6 +253,7 @@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SOCKETS_LIBS = @SOCKETS_LIBS@ STRIP = @STRIP@ +SYSTEMD_ASK_PASSWORD = @SYSTEMD_ASK_PASSWORD@ TAP_CFLAGS = @TAP_CFLAGS@ TAP_WIN_COMPONENT_ID = @TAP_WIN_COMPONENT_ID@ TAP_WIN_MIN_MAJOR = @TAP_WIN_MIN_MAJOR@ @@ -292,6 +294,8 @@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ +libsystemd_CFLAGS = @libsystemd_CFLAGS@ +libsystemd_LIBS = @libsystemd_LIBS@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ diff --git a/sample/sample-config-files/server.conf b/sample/sample-config-files/server.conf index f483b6b..467d5b8 100644 --- a/sample/sample-config-files/server.conf +++ b/sample/sample-config-files/server.conf @@ -83,9 +83,16 @@ key server.key # This file should be kept secret # Generate your own with: # openssl dhparam -out dh1024.pem 1024 # Substitute 2048 for 1024 if you are using -# 2048 bit keys. +# 2048 bit keys. dh dh1024.pem +# Network topology +# Should be subnet (addressing via IP) +# unless Windows clients v2.0.9 and lower have to +# be supported (then net30, i.e. a /30 per client) +# Defaults to net30 (not recommended) +;topology subnet + # Configure server mode and supply a VPN subnet # for OpenVPN to draw client addresses from. # The server will take 10.8.0.1 for itself, diff --git a/src/Makefile.in b/src/Makefile.in index 0a33984..2cd864f 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -254,6 +254,7 @@ OPTIONAL_LZO_LIBS = @OPTIONAL_LZO_LIBS@ OPTIONAL_PKCS11_HELPER_CFLAGS = @OPTIONAL_PKCS11_HELPER_CFLAGS@ OPTIONAL_PKCS11_HELPER_LIBS = @OPTIONAL_PKCS11_HELPER_LIBS@ OPTIONAL_SELINUX_LIBS = @OPTIONAL_SELINUX_LIBS@ +OPTIONAL_SYSTEMD_LIBS = @OPTIONAL_SYSTEMD_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ @@ -282,6 +283,7 @@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SOCKETS_LIBS = @SOCKETS_LIBS@ STRIP = @STRIP@ +SYSTEMD_ASK_PASSWORD = @SYSTEMD_ASK_PASSWORD@ TAP_CFLAGS = @TAP_CFLAGS@ TAP_WIN_COMPONENT_ID = @TAP_WIN_COMPONENT_ID@ TAP_WIN_MIN_MAJOR = @TAP_WIN_MIN_MAJOR@ @@ -322,6 +324,8 @@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ +libsystemd_CFLAGS = @libsystemd_CFLAGS@ +libsystemd_LIBS = @libsystemd_LIBS@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ diff --git a/src/compat/Makefile.in b/src/compat/Makefile.in index acdca2c..4f2fcb3 100644 --- a/src/compat/Makefile.in +++ b/src/compat/Makefile.in @@ -246,6 +246,7 @@ OPTIONAL_LZO_LIBS = @OPTIONAL_LZO_LIBS@ OPTIONAL_PKCS11_HELPER_CFLAGS = @OPTIONAL_PKCS11_HELPER_CFLAGS@ OPTIONAL_PKCS11_HELPER_LIBS = @OPTIONAL_PKCS11_HELPER_LIBS@ OPTIONAL_SELINUX_LIBS = @OPTIONAL_SELINUX_LIBS@ +OPTIONAL_SYSTEMD_LIBS = @OPTIONAL_SYSTEMD_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ @@ -274,6 +275,7 @@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SOCKETS_LIBS = @SOCKETS_LIBS@ STRIP = @STRIP@ +SYSTEMD_ASK_PASSWORD = @SYSTEMD_ASK_PASSWORD@ TAP_CFLAGS = @TAP_CFLAGS@ TAP_WIN_COMPONENT_ID = @TAP_WIN_COMPONENT_ID@ TAP_WIN_MIN_MAJOR = @TAP_WIN_MIN_MAJOR@ @@ -314,6 +316,8 @@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ +libsystemd_CFLAGS = @libsystemd_CFLAGS@ +libsystemd_LIBS = @libsystemd_LIBS@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ diff --git a/src/openvpn/Makefile.am b/src/openvpn/Makefile.am index 5d38628..2e602f1 100644 --- a/src/openvpn/Makefile.am +++ b/src/openvpn/Makefile.am @@ -119,6 +119,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/src/openvpn/Makefile.in b/src/openvpn/Makefile.in index b5a6c69..686f79b 100644 --- a/src/openvpn/Makefile.in +++ b/src/openvpn/Makefile.in @@ -181,7 +181,7 @@ openvpn_DEPENDENCIES = $(top_builddir)/src/compat/libcompat.la \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ - $(am__DEPENDENCIES_1) + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent @@ -316,6 +316,7 @@ OPTIONAL_LZO_LIBS = @OPTIONAL_LZO_LIBS@ OPTIONAL_PKCS11_HELPER_CFLAGS = @OPTIONAL_PKCS11_HELPER_CFLAGS@ OPTIONAL_PKCS11_HELPER_LIBS = @OPTIONAL_PKCS11_HELPER_LIBS@ OPTIONAL_SELINUX_LIBS = @OPTIONAL_SELINUX_LIBS@ +OPTIONAL_SYSTEMD_LIBS = @OPTIONAL_SYSTEMD_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ @@ -344,6 +345,7 @@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SOCKETS_LIBS = @SOCKETS_LIBS@ STRIP = @STRIP@ +SYSTEMD_ASK_PASSWORD = @SYSTEMD_ASK_PASSWORD@ TAP_CFLAGS = @TAP_CFLAGS@ TAP_WIN_COMPONENT_ID = @TAP_WIN_COMPONENT_ID@ TAP_WIN_MIN_MAJOR = @TAP_WIN_MIN_MAJOR@ @@ -384,6 +386,8 @@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ +libsystemd_CFLAGS = @libsystemd_CFLAGS@ +libsystemd_LIBS = @libsystemd_LIBS@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ @@ -451,7 +455,8 @@ openvpn_SOURCES = base64.c base64.h basic.h buffer.c buffer.h \ openvpn_LDADD = $(top_builddir)/src/compat/libcompat.la \ $(SOCKETS_LIBS) $(OPTIONAL_LZO_LIBS) \ $(OPTIONAL_PKCS11_HELPER_LIBS) $(OPTIONAL_CRYPTO_LIBS) \ - $(OPTIONAL_SELINUX_LIBS) $(OPTIONAL_DL_LIBS) $(am__append_3) + $(OPTIONAL_SELINUX_LIBS) $(OPTIONAL_SYSTEMD_LIBS) \ + $(OPTIONAL_DL_LIBS) $(am__append_3) all: all-am .SUFFIXES: diff --git a/src/openvpn/base64.c b/src/openvpn/base64.c index bb89aae..7dccec2 100644 --- a/src/openvpn/base64.c +++ b/src/openvpn/base64.c @@ -110,7 +110,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/src/openvpn/console.c b/src/openvpn/console.c index afda8ca..d66d408 100644 --- a/src/openvpn/console.c +++ b/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/src/openvpn/crypto.c b/src/openvpn/crypto.c index d9adf5b..0a5e83f 100644 --- a/src/openvpn/crypto.c +++ b/src/openvpn/crypto.c @@ -100,10 +100,10 @@ openvpn_encrypt (struct buffer *buf, struct buffer work, { uint8_t iv_buf[OPENVPN_MAX_IV_LENGTH]; const int iv_size = cipher_ctx_iv_length (ctx->cipher); - const unsigned int mode = cipher_ctx_mode (ctx->cipher); + const cipher_kt_t *cipher_kt = cipher_ctx_get_cipher_kt (ctx->cipher); int outlen; - if (mode == OPENVPN_MODE_CBC) + if (cipher_kt_mode_cbc(cipher_kt)) { CLEAR (iv_buf); @@ -119,7 +119,7 @@ openvpn_encrypt (struct buffer *buf, struct buffer work, ASSERT (packet_id_write (&pin, buf, BOOL_CAST (opt->flags & CO_PACKET_ID_LONG_FORM), true)); } } - else if (mode == OPENVPN_MODE_CFB || mode == OPENVPN_MODE_OFB) + else if (cipher_kt_mode_ofb_cfb(cipher_kt)) { struct packet_id_net pin; struct buffer b; @@ -171,7 +171,10 @@ openvpn_encrypt (struct buffer *buf, struct buffer work, /* Flush the encryption buffer */ ASSERT(cipher_ctx_final(ctx->cipher, BPTR (&work) + outlen, &outlen)); work.len += outlen; - ASSERT (outlen == iv_size); + + /* For all CBC mode ciphers, check the last block is complete */ + ASSERT (cipher_kt_mode (cipher_kt) != OPENVPN_MODE_CBC || + outlen == iv_size); /* prepend the IV to the ciphertext */ if (opt->flags & CO_USE_IV) @@ -272,8 +275,8 @@ openvpn_decrypt (struct buffer *buf, struct buffer work, if (ctx->cipher) { - const unsigned int mode = cipher_ctx_mode (ctx->cipher); const int iv_size = cipher_ctx_iv_length (ctx->cipher); + const cipher_kt_t *cipher_kt = cipher_ctx_get_cipher_kt (ctx->cipher); uint8_t iv_buf[OPENVPN_MAX_IV_LENGTH]; int outlen; @@ -320,7 +323,7 @@ openvpn_decrypt (struct buffer *buf, struct buffer work, /* Get packet ID from plaintext buffer or IV, depending on cipher mode */ { - if (mode == OPENVPN_MODE_CBC) + if (cipher_kt_mode_cbc(cipher_kt)) { if (opt->packet_id) { @@ -329,7 +332,7 @@ openvpn_decrypt (struct buffer *buf, struct buffer work, have_pin = true; } } - else if (mode == OPENVPN_MODE_CFB || mode == OPENVPN_MODE_OFB) + else if (cipher_kt_mode_ofb_cfb(cipher_kt)) { struct buffer b; @@ -426,17 +429,12 @@ init_key_type (struct key_type *kt, const char *ciphername, /* check legal cipher mode */ { - const unsigned int mode = cipher_kt_mode (kt->cipher); - if (!(mode == OPENVPN_MODE_CBC -#ifdef ALLOW_NON_CBC_CIPHERS - || (cfb_ofb_allowed && (mode == OPENVPN_MODE_CFB || mode == OPENVPN_MODE_OFB)) + if (!(cipher_kt_mode_cbc(kt->cipher) +#ifdef ENABLE_OFB_CFB_MODE + || (cfb_ofb_allowed && cipher_kt_mode_ofb_cfb(kt->cipher)) #endif )) -#ifdef ENABLE_SMALL msg (M_FATAL, "Cipher '%s' mode not supported", ciphername); -#else - msg (M_FATAL, "Cipher '%s' uses a mode not supported by " PACKAGE_NAME " in your current configuration. CBC mode is always supported, while CFB and OFB modes are supported only when using SSL/TLS authentication and key exchange mode, and when " PACKAGE_NAME " has been built with ALLOW_NON_CBC_CIPHERS.", ciphername); -#endif } } else @@ -606,18 +604,10 @@ fixup_key (struct key *key, const struct key_type *kt) void check_replay_iv_consistency (const struct key_type *kt, bool packet_id, bool use_iv) { - if (cfb_ofb_mode (kt) && !(packet_id && use_iv)) - msg (M_FATAL, "--no-replay or --no-iv cannot be used with a CFB or OFB mode cipher"); -} + ASSERT(kt); -bool -cfb_ofb_mode (const struct key_type* kt) -{ - if (kt && kt->cipher) { - const unsigned int mode = cipher_kt_mode (kt->cipher); - return mode == OPENVPN_MODE_CFB || mode == OPENVPN_MODE_OFB; - } - return false; + if (cipher_kt_mode_ofb_cfb(kt->cipher) && !(packet_id && use_iv)) + msg (M_FATAL, "--no-replay or --no-iv cannot be used with a CFB or OFB mode cipher"); } /* diff --git a/src/openvpn/crypto.h b/src/openvpn/crypto.h index 3b4b88e..bf2f802 100644 --- a/src/openvpn/crypto.h +++ b/src/openvpn/crypto.h @@ -32,8 +32,6 @@ #ifdef ENABLE_CRYPTO -#define ALLOW_NON_CBC_CIPHERS - #include "crypto_backend.h" #include "basic.h" #include "buffer.h" @@ -189,8 +187,6 @@ bool write_key (const struct key *key, const struct key_type *kt, int read_key (struct key *key, const struct key_type *kt, struct buffer *buf); -bool cfb_ofb_mode (const struct key_type* kt); - void init_key_type (struct key_type *kt, const char *ciphername, bool ciphername_defined, const char *authname, bool authname_defined, int keysize, bool cfb_ofb_allowed, bool warn); diff --git a/src/openvpn/crypto_backend.h b/src/openvpn/crypto_backend.h index 5ae47e6..bc067a7 100644 --- a/src/openvpn/crypto_backend.h +++ b/src/openvpn/crypto_backend.h @@ -230,6 +230,26 @@ int cipher_kt_block_size (const cipher_kt_t *cipher_kt); */ int cipher_kt_mode (const cipher_kt_t *cipher_kt); +/** + * Check if the supplied cipher is a supported CBC mode cipher. + * + * @param cipher Static cipher parameters. May not be NULL. + * + * @return true iff the cipher is a CBC mode cipher. + */ +bool cipher_kt_mode_cbc(const cipher_kt_t *cipher) + __attribute__((nonnull)); + +/** + * Check if the supplied cipher is a supported OFB or CFB mode cipher. + * + * @param cipher Static cipher parameters. May not be NULL. + * + * @return true iff the cipher is a OFB or CFB mode cipher. + */ +bool cipher_kt_mode_ofb_cfb(const cipher_kt_t *cipher) + __attribute__((nonnull)); + /** * @@ -287,6 +307,16 @@ int cipher_ctx_block_size (const cipher_ctx_t *ctx); */ int cipher_ctx_mode (const cipher_ctx_t *ctx); +/** + * Returns the static cipher parameters for this context. + * + * @param ctx Cipher's context. May not be NULL. + * + * @return Static cipher parameters for the supplied context. + */ +const cipher_kt_t *cipher_ctx_get_cipher_kt (const cipher_ctx_t *ctx) + __attribute__((nonnull)); + /** * Resets the given cipher context, setting the IV to the specified value. * Preserves the associated key information. diff --git a/src/openvpn/crypto_openssl.c b/src/openvpn/crypto_openssl.c index 1501bc8..4067701 100644 --- a/src/openvpn/crypto_openssl.c +++ b/src/openvpn/crypto_openssl.c @@ -40,6 +40,7 @@ #include "basic.h" #include "buffer.h" #include "integer.h" +#include "crypto.h" #include "crypto_backend.h" #include #include @@ -84,24 +85,6 @@ #endif -static inline int -EVP_CipherInit_ov (EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, uint8_t *key, uint8_t *iv, int enc) -{ - return EVP_CipherInit (ctx, type, key, iv, enc); -} - -static inline int -EVP_CipherUpdate_ov (EVP_CIPHER_CTX *ctx, uint8_t *out, int *outl, uint8_t *in, int inl) -{ - return EVP_CipherUpdate (ctx, out, outl, in, inl); -} - -static inline bool -cipher_ok (const char* name) -{ - return true; -} - #ifndef EVP_CIPHER_name #define EVP_CIPHER_name(e) OBJ_nid2sn(EVP_CIPHER_nid(e)) #endif @@ -306,25 +289,30 @@ show_available_ciphers () "used as a parameter to the --cipher option. The default\n" "key size is shown as well as whether or not it can be\n" "changed with the --keysize directive. Using a CBC mode\n" - "is recommended.\n\n"); + "is recommended. In static key mode only CBC mode is allowed.\n\n"); #endif for (nid = 0; nid < 10000; ++nid) /* is there a better way to get the size of the nid list? */ { const EVP_CIPHER *cipher = EVP_get_cipherbynid (nid); - if (cipher && cipher_ok (OBJ_nid2sn (nid))) + if (cipher) { - const unsigned int mode = EVP_CIPHER_mode (cipher); - if (mode == EVP_CIPH_CBC_MODE -#ifdef ALLOW_NON_CBC_CIPHERS - || mode == EVP_CIPH_CFB_MODE || mode == EVP_CIPH_OFB_MODE + if (cipher_kt_mode_cbc(cipher) +#ifdef ENABLE_OFB_CFB_MODE + || cipher_kt_mode_ofb_cfb(cipher) #endif ) - printf ("%s %d bit default key (%s)\n", - OBJ_nid2sn (nid), - EVP_CIPHER_key_length (cipher) * 8, - ((EVP_CIPHER_flags (cipher) & EVP_CIPH_VARIABLE_LENGTH) ? - "variable" : "fixed")); + { + const char *var_key_size = + (EVP_CIPHER_flags (cipher) & EVP_CIPH_VARIABLE_LENGTH) ? + "variable" : "fixed"; + const char *ssl_only = cipher_kt_mode_ofb_cfb(cipher) ? + " (TLS client/server mode)" : ""; + + printf ("%s %d bit default key (%s)%s\n", OBJ_nid2sn (nid), + EVP_CIPHER_key_length (cipher) * 8, var_key_size, + ssl_only); + } } } printf ("\n"); @@ -491,7 +479,7 @@ cipher_kt_get (const char *ciphername) cipher = EVP_get_cipherbyname (ciphername); - if ((NULL == cipher) || !cipher_ok (OBJ_nid2sn (EVP_CIPHER_nid (cipher)))) + if (NULL == cipher) msg (M_SSLERR, "Cipher algorithm '%s' not found", ciphername); if (EVP_CIPHER_key_length (cipher) > MAX_CIPHER_KEY_LENGTH) @@ -536,6 +524,29 @@ cipher_kt_mode (const EVP_CIPHER *cipher_kt) return EVP_CIPHER_mode (cipher_kt); } +bool +cipher_kt_mode_cbc(const cipher_kt_t *cipher) +{ + return cipher_kt_mode(cipher) == OPENVPN_MODE_CBC +#ifdef EVP_CIPH_FLAG_AEAD_CIPHER + /* Exclude AEAD cipher modes, they require a different API */ + && !(EVP_CIPHER_flags(cipher) & EVP_CIPH_FLAG_AEAD_CIPHER) +#endif + ; +} + +bool +cipher_kt_mode_ofb_cfb(const cipher_kt_t *cipher) +{ + return (cipher_kt_mode(cipher) == OPENVPN_MODE_OFB || + cipher_kt_mode(cipher) == OPENVPN_MODE_CFB) +#ifdef EVP_CIPH_FLAG_AEAD_CIPHER + /* Exclude AEAD cipher modes, they require a different API */ + && !(EVP_CIPHER_flags(cipher) & EVP_CIPH_FLAG_AEAD_CIPHER) +#endif + ; +} + /* * * Generic cipher context functions @@ -552,13 +563,13 @@ cipher_ctx_init (EVP_CIPHER_CTX *ctx, uint8_t *key, int key_len, CLEAR (*ctx); EVP_CIPHER_CTX_init (ctx); - if (!EVP_CipherInit_ov (ctx, kt, NULL, NULL, enc)) + if (!EVP_CipherInit (ctx, kt, NULL, NULL, enc)) msg (M_SSLERR, "EVP cipher init #1"); #ifdef HAVE_EVP_CIPHER_CTX_SET_KEY_LENGTH if (!EVP_CIPHER_CTX_set_key_length (ctx, key_len)) msg (M_SSLERR, "EVP set key size"); #endif - if (!EVP_CipherInit_ov (ctx, NULL, key, NULL, enc)) + if (!EVP_CipherInit (ctx, NULL, key, NULL, enc)) msg (M_SSLERR, "EVP cipher init #2"); /* make sure we used a big enough key */ @@ -589,17 +600,24 @@ cipher_ctx_mode (const EVP_CIPHER_CTX *ctx) return EVP_CIPHER_CTX_mode (ctx); } +const cipher_kt_t * +cipher_ctx_get_cipher_kt (const cipher_ctx_t *ctx) +{ + return EVP_CIPHER_CTX_cipher(ctx); +} + + int cipher_ctx_reset (EVP_CIPHER_CTX *ctx, uint8_t *iv_buf) { - return EVP_CipherInit_ov (ctx, NULL, NULL, iv_buf, -1); + return EVP_CipherInit (ctx, NULL, NULL, iv_buf, -1); } int cipher_ctx_update (EVP_CIPHER_CTX *ctx, uint8_t *dst, int *dst_len, uint8_t *src, int src_len) { - return EVP_CipherUpdate_ov (ctx, dst, dst_len, src, src_len); + return EVP_CipherUpdate (ctx, dst, dst_len, src, src_len); } int diff --git a/src/openvpn/crypto_polarssl.c b/src/openvpn/crypto_polarssl.c index 1f27d6c..8bf8d8d 100644 --- a/src/openvpn/crypto_polarssl.c +++ b/src/openvpn/crypto_polarssl.c @@ -416,6 +416,19 @@ cipher_kt_mode (const cipher_info_t *cipher_kt) return cipher_kt->mode; } +bool +cipher_kt_mode_cbc(const cipher_kt_t *cipher) +{ + return cipher_kt_mode(cipher) == OPENVPN_MODE_CBC; +} + +bool +cipher_kt_mode_ofb_cfb(const cipher_kt_t *cipher) +{ + return (cipher_kt_mode(cipher) == OPENVPN_MODE_OFB || + cipher_kt_mode(cipher) == OPENVPN_MODE_CFB); +} + /* * @@ -464,6 +477,14 @@ int cipher_ctx_mode (const cipher_context_t *ctx) return cipher_kt_mode(ctx->cipher_info); } +const cipher_kt_t * +cipher_ctx_get_cipher_kt (const cipher_ctx_t *ctx) +{ + ASSERT(NULL != ctx); + + return ctx->cipher_info; +} + int cipher_ctx_reset (cipher_context_t *ctx, uint8_t *iv_buf) { return 0 == cipher_reset(ctx, iv_buf); diff --git a/src/openvpn/forward.c b/src/openvpn/forward.c index 024cd58..7f0d083 100644 --- a/src/openvpn/forward.c +++ b/src/openvpn/forward.c @@ -952,6 +952,15 @@ read_incoming_tun (struct context *c) return; } + /* Was TUN/TAP I/O operation aborted? */ + if (tuntap_abort(c->c2.buf.len)) + { + register_signal(c, SIGTERM, "tun-abort"); + msg(M_FATAL, "TUN/TAP I/O operation aborted, exiting"); + perf_pop(); + return; + } + /* Check the status return from read() */ check_status (c->c2.buf.len, "read from TUN/TAP", NULL, c->c1.tuntap); diff --git a/src/openvpn/helper.c b/src/openvpn/helper.c index d9eef03..0ed0b2b 100644 --- a/src/openvpn/helper.c +++ b/src/openvpn/helper.c @@ -232,6 +232,8 @@ helper_client_server (struct options *o) * if !nopool: * ifconfig-pool 10.8.0.2 10.8.0.254 255.255.255.0 * push "route-gateway 10.8.0.1" + * if route-gateway unset: + * route-gateway 10.8.0.2 */ if (o->server_defined) @@ -311,8 +313,10 @@ helper_client_server (struct options *o) ifconfig_pool_verify_range (M_USAGE, o->ifconfig_pool_start, o->ifconfig_pool_end); } o->ifconfig_pool_netmask = o->server_netmask; - + push_option (o, print_opt_route_gateway (o->server_network + 1, &o->gc), M_USAGE); + if (!o->route_default_gateway) + o->route_default_gateway = print_in_addr_t (o->server_network + 2, 0, &o->gc); } else ASSERT (0); diff --git a/src/openvpn/init.c b/src/openvpn/init.c index 52d370b..18f506c 100644 --- a/src/openvpn/init.c +++ b/src/openvpn/init.c @@ -183,10 +183,12 @@ ce_management_query_proxy (struct context *c) if (management) { gc = gc_new (); - struct buffer out = alloc_buf_gc (256, &gc); - buf_printf (&out, ">PROXY:%u,%s,%s", (l ? l->current : 0) + 1, - (proto_is_udp (ce->proto) ? "UDP" : "TCP"), np (ce->remote)); - management_notify_generic (management, BSTR (&out)); + { + struct buffer out = alloc_buf_gc (256, &gc); + buf_printf (&out, ">PROXY:%u,%s,%s", (l ? l->current : 0) + 1, + (proto_is_udp (ce->proto) ? "UDP" : "TCP"), np (ce->remote)); + management_notify_generic (management, BSTR (&out)); + } ce->flags |= CE_MAN_QUERY_PROXY; while (ce->flags & CE_MAN_QUERY_PROXY) { @@ -2159,7 +2161,7 @@ do_init_crypto_tls (struct context *c, const unsigned int flags) options->use_iv); /* In short form, unique datagram identifier is 32 bits, in long form 64 bits */ - packet_id_long_form = cfb_ofb_mode (&c->c1.ks.key_type); + packet_id_long_form = cipher_kt_mode_ofb_cfb (c->c1.ks.key_type.cipher); /* Compute MTU parameters */ crypto_adjust_frame_parameters (&c->c2.frame, diff --git a/src/openvpn/misc.c b/src/openvpn/misc.c index 56a01a6..8408438 100644 --- a/src/openvpn/misc.c +++ b/src/openvpn/misc.c @@ -376,8 +376,11 @@ openvpn_popen (const struct argv *a, const struct env_set *es) } else /* parent side */ { - ret=pipe_stdout[0]; - close (pipe_stdout[1]); + int status = 0; + + waitpid(pid, &status, 0); + ret = pipe_stdout[0]; + close (pipe_stdout[1]); } } else { @@ -869,6 +872,12 @@ test_file (const char *filename) fclose (fp); ret = true; } + else + { + if( openvpn_errno () == EACCES ) { + msg( M_WARN | M_ERRNO, "Could not access file '%s'", filename); + } + } } dmsg (D_TEST_FILE, "TEST FILE '%s' [%d]", diff --git a/src/openvpn/multi.c b/src/openvpn/multi.c index ab3f10c..374950e 100644 --- a/src/openvpn/multi.c +++ b/src/openvpn/multi.c @@ -1452,10 +1452,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 @@ -1698,6 +1694,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); } @@ -1751,6 +1752,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); } @@ -2153,8 +2159,17 @@ multi_process_incoming_link (struct multi_context *m, struct multi_instance *ins /* make sure that source address is associated with this client */ else if (multi_get_instance_by_virtual_addr (m, &src, true) != m->pending) { - msg (D_MULTI_DROPPED, "MULTI: bad source address from client [%s], packet dropped", - mroute_addr_print (&src, &gc)); + /* IPv6 link-local address (fe80::xxx)? */ + if ( (src.type & MR_ADDR_MASK) == MR_ADDR_IPV6 && + src.addr[0] == 0xfe && src.addr[1] == 0x80 ) + { + /* do nothing, for now. TODO: add address learning */ + } + else + { + msg (D_MULTI_DROPPED, "MULTI: bad source address from client [%s], packet dropped", + mroute_addr_print (&src, &gc)); + } c->c2.to_tun.len = 0; } /* client-to-client communication enabled? */ diff --git a/src/openvpn/options.c b/src/openvpn/options.c index 1c0edbc..fa53a17 100644 --- a/src/openvpn/options.c +++ b/src/openvpn/options.c @@ -577,8 +577,8 @@ static const char usage_message[] = " and optionally the root CA certificate.\n" #endif #ifdef ENABLE_X509ALTUSERNAME - "--x509-username-field : Field used in x509 certificate to be username.\n" - " Default is CN.\n" + "--x509-username-field : Field in x509 certificate containing the username.\n" + " Default is CN in the Subject field.\n" #endif "--verify-hash : Specify SHA1 fingerprint for level-1 cert.\n" #ifdef WIN32 @@ -3439,18 +3439,21 @@ usage_small (void) void show_library_versions(const unsigned int flags) { - msg (flags, "library versions: %s%s%s", #ifdef ENABLE_SSL - get_ssl_library_version(), +#define SSL_LIB_VER_STR get_ssl_library_version() #else - "", +#define SSL_LIB_VER_STR "" #endif #ifdef ENABLE_LZO - ", LZO ", lzo_version_string() +#define LZO_LIB_VER_STR ", LZO ", lzo_version_string() #else - "", "" +#define LZO_LIB_VER_STR "", "" #endif - ); + + msg (flags, "library versions: %s%s%s", SSL_LIB_VER_STR, LZO_LIB_VER_STR); + +#undef SSL_LIB_VER_STR +#undef LZO_LIB_VER_STR } static void @@ -6872,10 +6875,28 @@ add_option (struct options *options, #ifdef ENABLE_X509ALTUSERNAME else if (streq (p[0], "x509-username-field") && p[1]) { + /* This option used to automatically upcase the fieldname passed as the + * option argument, e.g., "ou" became "OU". Now, this "helpfulness" is + * fine-tuned by only upcasing Subject field attribute names which consist + * of all lower-case characters. Mixed-case attributes such as + * "emailAddress" are left as-is. An option parameter having the "ext:" + * prefix for matching X.509v3 extended fields will also remain unchanged. + */ char *s = p[1]; + VERIFY_PERMISSION (OPT_P_GENERAL); - if( strncmp ("ext:",s,4) != 0 ) - while ((*s = toupper(*s)) != '\0') s++; /* Uppercase if necessary */ + if (strncmp("ext:", s, 4) != 0) + { + size_t i = 0; + while (s[i] && !isupper(s[i])) i++; + if (strlen(s) == i) + { + while ((*s = toupper(*s)) != '\0') s++; + msg(M_WARN, "DEPRECATED FEATURE: automatically upcased the " + "--x509-username-field parameter to '%s'; please update your" + "configuration", p[1]); + } + } options->x509_username_field = p[1]; } #endif /* ENABLE_X509ALTUSERNAME */ diff --git a/src/openvpn/options.h b/src/openvpn/options.h index 8cbb85a..2c18838 100644 --- a/src/openvpn/options.h +++ b/src/openvpn/options.h @@ -683,6 +683,8 @@ void notnull (const char *arg, const char *description); void usage_small (void); +void show_library_versions(const unsigned int flags); + void init_options (struct options *o, const bool init_gc); void uninit_options (struct options *o); diff --git a/src/openvpn/route.c b/src/openvpn/route.c index 532edc6..cc85e4d 100644 --- a/src/openvpn/route.c +++ b/src/openvpn/route.c @@ -1318,15 +1318,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/src/openvpn/socket.c b/src/openvpn/socket.c index 23566f1..6e68c18 100644 --- a/src/openvpn/socket.c +++ b/src/openvpn/socket.c @@ -1150,7 +1150,6 @@ resolve_bind_local (struct link_socket *sock) case AF_INET6: { int status; - int err; CLEAR(sock->info.lsa->local.addr.in6); if (sock->local_host) { @@ -1173,7 +1172,7 @@ resolve_bind_local (struct link_socket *sock) { msg (M_FATAL, "getaddr6() failed for local \"%s\": %s", sock->local_host, - gai_strerror(err)); + gai_strerror(status)); } sock->info.lsa->local.addr.in6.sin6_port = htons (sock->local_port); } @@ -1227,6 +1226,7 @@ resolve_remote (struct link_socket *sock, unsigned int flags = sf2gaf(GETADDR_RESOLVE|GETADDR_UPDATE_MANAGEMENT_STATE, sock->sockflags); int retry = 0; int status = -1; + struct addrinfo* ai; if (sock->connection_profiles_defined && sock->resolve_retry_seconds == RESOLV_RETRY_INFINITE) { @@ -1263,7 +1263,6 @@ resolve_remote (struct link_socket *sock, ASSERT (0); } - struct addrinfo* ai; /* Temporary fix, this need to be changed for dual stack */ status = openvpn_getaddrinfo(flags, sock->remote_host, retry, signal_received, af, &ai); diff --git a/src/openvpn/socket.h b/src/openvpn/socket.h index 4e7e7f8..793cd9f 100644 --- a/src/openvpn/socket.h +++ b/src/openvpn/socket.h @@ -1023,7 +1023,7 @@ static inline void link_socket_set_tos (struct link_socket *ls) { if (ls && ls->ptos_defined) - setsockopt (ls->sd, IPPROTO_IP, IP_TOS, &ls->ptos, sizeof (ls->ptos)); + setsockopt (ls->sd, IPPROTO_IP, IP_TOS, (const void *)&ls->ptos, sizeof (ls->ptos)); } #endif diff --git a/src/openvpn/ssl_backend.h b/src/openvpn/ssl_backend.h index b37b1e5..fc23175 100644 --- a/src/openvpn/ssl_backend.h +++ b/src/openvpn/ssl_backend.h @@ -472,6 +472,6 @@ void get_highest_preference_tls_cipher (char *buf, int size); * return a pointer to a static memory area containing the * name and version number of the SSL library in use */ -char * get_ssl_library_version(void); +const char * get_ssl_library_version(void); #endif /* SSL_BACKEND_H_ */ diff --git a/src/openvpn/ssl_openssl.c b/src/openvpn/ssl_openssl.c index 481600a..e77b736 100644 --- a/src/openvpn/ssl_openssl.c +++ b/src/openvpn/ssl_openssl.c @@ -261,8 +261,7 @@ tls_ctx_restrict_ciphers(struct tls_root_ctx *ctx, const char *ciphers) const tls_cipher_name_pair *cipher_pair; - const size_t openssl_ciphers_size = 4096; - char openssl_ciphers[openssl_ciphers_size]; + char openssl_ciphers[4096]; size_t openssl_ciphers_len = 0; openssl_ciphers[0] = '\0'; @@ -301,8 +300,8 @@ tls_ctx_restrict_ciphers(struct tls_root_ctx *ctx, const char *ciphers) } // Make sure new cipher name fits in cipher string - if (((openssl_ciphers_size-1) - openssl_ciphers_len) < current_cipher_len) { - msg(M_SSLERR, "Failed to set restricted TLS cipher list, too long (>%zu).", openssl_ciphers_size-1); + if (((sizeof(openssl_ciphers)-1) - openssl_ciphers_len) < current_cipher_len) { + msg(M_SSLERR, "Failed to set restricted TLS cipher list, too long (>%d).", (int)sizeof(openssl_ciphers)-1); } // Concatenate cipher name to OpenSSL cipher string @@ -1355,7 +1354,7 @@ get_highest_preference_tls_cipher (char *buf, int size) SSL_CTX_free (ctx); } -char * +const char * get_ssl_library_version(void) { return SSLeay_version(SSLEAY_VERSION); diff --git a/src/openvpn/ssl_polarssl.c b/src/openvpn/ssl_polarssl.c index 0dfffd6..5718c8c 100644 --- a/src/openvpn/ssl_polarssl.c +++ b/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,7 +50,9 @@ #include #include "ssl_verify_polarssl.h" +#include #include +#include void tls_init_lib() @@ -204,12 +207,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 != x509parse_dhm(ctx->dhm_ctx, dh_file_inline, strlen(dh_file_inline))) + if (0 != x509parse_dhm(ctx->dhm_ctx, (const unsigned char *) dh_inline, + strlen(dh_inline))) msg (M_FATAL, "Cannot read inline DH parameters"); } else @@ -242,15 +246,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 != x509parse_crt(ctx->crt_chain, cert_file_inline, - strlen(cert_file_inline))) + if (0 != x509parse_crt(ctx->crt_chain, + (const unsigned char *) cert_inline, strlen(cert_inline))) msg (M_FATAL, "Cannot load inline certificate file"); } else @@ -262,30 +266,30 @@ 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 = x509parse_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) + if (POLARSSL_ERR_X509_PASSWORD_REQUIRED == status) { char passbuf[512] = {0}; pem_password_callback(passbuf, 512, 0, NULL); status = x509parse_key(ctx->priv_key, - priv_key_file_inline, strlen(priv_key_file_inline), - passbuf, strlen(passbuf)); + (const unsigned char *) priv_key_inline, strlen(priv_key_inline), + (const unsigned char *) passbuf, strlen(passbuf)); } } else { status = x509parse_keyfile(ctx->priv_key, priv_key_file, NULL); - if (POLARSSL_ERR_PEM_PASSWORD_REQUIRED == status) + if (POLARSSL_ERR_X509_PASSWORD_REQUIRED == status) { char passbuf[512] = {0}; pem_password_callback(passbuf, 512, 0, NULL); @@ -295,7 +299,7 @@ tls_ctx_load_priv_file (struct tls_root_ctx *ctx, const char *priv_key_file, if (0 != status) { #ifdef ENABLE_MANAGEMENT - if (management && (POLARSSL_ERR_PEM_PASSWORD_MISMATCH == status)) + if (management && (POLARSSL_ERR_X509_PASSWORD_MISMATCH == status)) management_auth_failure (management, UP_TYPE_PRIVATE_KEY, NULL); #endif msg (M_WARN, "Cannot load private key file %s", priv_key_file); @@ -467,16 +471,17 @@ static inline size_t external_key_len(void *vctx) #endif void tls_ctx_load_ca (struct tls_root_ctx *ctx, const char *ca_file, - const char *ca_file_inline, + const char *ca_inline, const char *ca_path, bool tls_server ) { if (ca_path) msg(M_FATAL, "ERROR: PolarSSL cannot handle the capath directive"); - if (ca_file && !strcmp (ca_file, INLINE_FILE_TAG) && ca_file_inline) + if (ca_file && !strcmp (ca_file, INLINE_FILE_TAG) && ca_inline) { - if (0 != x509parse_crt(ctx->ca_chain, ca_file_inline, strlen(ca_file_inline))) + if (0 != x509parse_crt(ctx->ca_chain, (const unsigned char *) ca_inline, + strlen(ca_inline))) msg (M_FATAL, "Cannot load inline CA certificates"); } else @@ -489,15 +494,16 @@ void tls_ctx_load_ca (struct tls_root_ctx *ctx, const char *ca_file, void tls_ctx_load_extra_certs (struct tls_root_ctx *ctx, const char *extra_certs_file, - const char *extra_certs_file_inline + const char *extra_certs_inline ) { ASSERT(NULL != ctx); - if (!strcmp (extra_certs_file, INLINE_FILE_TAG) && extra_certs_file_inline) + if (!strcmp (extra_certs_file, INLINE_FILE_TAG) && extra_certs_inline) { - if (0 != x509parse_crt(ctx->crt_chain, extra_certs_file_inline, - strlen(extra_certs_file_inline))) + if (0 != x509parse_crt(ctx->crt_chain, + (const unsigned char *) extra_certs_inline, + strlen(extra_certs_inline))) msg (M_FATAL, "Cannot load inline extra-certs file"); } else @@ -620,7 +626,7 @@ static void my_debug( void *ctx, int level, const char *str ) void tls_ctx_personalise_random(struct tls_root_ctx *ctx) { static char old_sha256_hash[32] = {0}; - char sha256_hash[32] = {0}; + unsigned char sha256_hash[32] = {0}; ctr_drbg_context *cd_ctx = rand_ctx_get(); if (NULL != ctx->crt_chain) @@ -1068,7 +1074,7 @@ get_highest_preference_tls_cipher (char *buf, int size) strncpynt (buf, cipher_name, size); } -char * +const char * get_ssl_library_version(void) { static char polar_version[30]; diff --git a/src/openvpn/ssl_verify_openssl.c b/src/openvpn/ssl_verify_openssl.c index 19982ae..e1118d6 100644 --- a/src/openvpn/ssl_verify_openssl.c +++ b/src/openvpn/ssl_verify_openssl.c @@ -97,9 +97,7 @@ static bool extract_x509_extension(X509 *cert, char *fieldname, char *out, int size) { bool retval = false; - X509_EXTENSION *pExt; char *buf = 0; - int length = 0; GENERAL_NAMES *extensions; int nid = OBJ_txt2nid(fieldname); @@ -591,12 +589,12 @@ x509_verify_crl(const char *crl_file, X509 *peer_cert, const char *subject) in = BIO_new_file (crl_file, "r"); if (in == NULL) { - msg (M_ERR, "CRL: cannot read: %s", crl_file); + msg (M_WARN, "CRL: cannot read: %s", crl_file); goto end; } crl=PEM_read_bio_X509_CRL(in,NULL,NULL,NULL); if (crl == NULL) { - msg (M_ERR, "CRL: cannot read CRL from file %s", crl_file); + msg (M_WARN, "CRL: cannot read CRL from file %s", crl_file); goto end; } diff --git a/src/openvpn/ssl_verify_polarssl.c b/src/openvpn/ssl_verify_polarssl.c index 3fd861c..f8f9ab5 100644 --- a/src/openvpn/ssl_verify_polarssl.c +++ b/src/openvpn/ssl_verify_polarssl.c @@ -380,7 +380,7 @@ x509_verify_cert_eku (x509_cert *cert, const char * const expected_oid) } } - if (0 == x509_oid_get_numeric_string( oid_num_str, + if (0 < x509_oid_get_numeric_string( oid_num_str, sizeof (oid_num_str), oid)) { msg (D_HANDSHAKE, "++ Certificate has EKU (oid) %s, expects %s", @@ -414,9 +414,12 @@ x509_verify_crl(const char *crl_file, x509_cert *cert, const char *subject) result_t retval = FAILURE; x509_crl crl = {0}; - if (x509parse_crlfile(&crl, crl_file) != 0) + int polar_retval = x509parse_crlfile(&crl, crl_file); + if (polar_retval != 0) { - msg (M_ERR, "CRL: cannot read CRL from file %s", crl_file); + char errstr[128]; + error_strerror(polar_retval, errstr, sizeof(errstr)); + msg (M_WARN, "CRL: cannot read CRL from file %s (%s)", crl_file, errstr); goto end; } diff --git a/src/openvpn/syshead.h b/src/openvpn/syshead.h index 7a7d53a..f957a10 100644 --- a/src/openvpn/syshead.h +++ b/src/openvpn/syshead.h @@ -349,6 +349,14 @@ #endif /* TARGET_DRAGONFLY */ +#ifdef TARGET_DARWIN + +#ifdef HAVE_NETINET_TCP_H +#include +#endif + +#endif /* TARGET_DARWIN */ + #ifdef WIN32 #include #include diff --git a/src/openvpn/tun.h b/src/openvpn/tun.h index 085d6a3..1931c52 100644 --- a/src/openvpn/tun.h +++ b/src/openvpn/tun.h @@ -374,6 +374,19 @@ tuntap_stop (int status) return false; } +static inline bool +tuntap_abort(int status) +{ + /* + * Typically generated when driver is halted. + */ + if (status < 0) + { + return openvpn_errno() == ERROR_OPERATION_ABORTED; + } + return false; +} + static inline int tun_write_win32 (struct tuntap *tt, struct buffer *buf) { @@ -415,6 +428,12 @@ tuntap_stop (int status) return false; } +static inline bool +tuntap_abort(int status) +{ + return false; +} + static inline void tun_standby_init (struct tuntap *tt) { diff --git a/src/openvpn/win32.c b/src/openvpn/win32.c index 13fd881..f35c96b 100644 --- a/src/openvpn/win32.c +++ b/src/openvpn/win32.c @@ -870,6 +870,9 @@ openvpn_execve (const struct argv *a, const struct env_set *es, const unsigned i WCHAR *cl = wide_cmd_line (a, &gc); WCHAR *cmd = wide_string (a->argv[0], &gc); + /* this allows console programs to run, and is ignored otherwise */ + DWORD proc_flags = CREATE_NO_WINDOW; + CLEAR (start_info); CLEAR (proc_info); @@ -879,9 +882,6 @@ openvpn_execve (const struct argv *a, const struct env_set *es, const unsigned i start_info.dwFlags = STARTF_USESHOWWINDOW; start_info.wShowWindow = SW_HIDE; - /* this allows console programs to run, and is ignored otherwise */ - DWORD proc_flags = CREATE_NO_WINDOW; - if (CreateProcessW (cmd, cl, NULL, NULL, FALSE, proc_flags, env, NULL, &start_info, &proc_info)) { DWORD exit_status = 0; diff --git a/src/openvpnserv/Makefile.in b/src/openvpnserv/Makefile.in index 1a9f752..272fd90 100644 --- a/src/openvpnserv/Makefile.in +++ b/src/openvpnserv/Makefile.in @@ -258,6 +258,7 @@ OPTIONAL_LZO_LIBS = @OPTIONAL_LZO_LIBS@ OPTIONAL_PKCS11_HELPER_CFLAGS = @OPTIONAL_PKCS11_HELPER_CFLAGS@ OPTIONAL_PKCS11_HELPER_LIBS = @OPTIONAL_PKCS11_HELPER_LIBS@ OPTIONAL_SELINUX_LIBS = @OPTIONAL_SELINUX_LIBS@ +OPTIONAL_SYSTEMD_LIBS = @OPTIONAL_SYSTEMD_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ @@ -286,6 +287,7 @@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SOCKETS_LIBS = @SOCKETS_LIBS@ STRIP = @STRIP@ +SYSTEMD_ASK_PASSWORD = @SYSTEMD_ASK_PASSWORD@ TAP_CFLAGS = @TAP_CFLAGS@ TAP_WIN_COMPONENT_ID = @TAP_WIN_COMPONENT_ID@ TAP_WIN_MIN_MAJOR = @TAP_WIN_MIN_MAJOR@ @@ -326,6 +328,8 @@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ +libsystemd_CFLAGS = @libsystemd_CFLAGS@ +libsystemd_LIBS = @libsystemd_LIBS@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ diff --git a/src/plugins/Makefile.in b/src/plugins/Makefile.in index 9a4da72..8b73edc 100644 --- a/src/plugins/Makefile.in +++ b/src/plugins/Makefile.in @@ -254,6 +254,7 @@ OPTIONAL_LZO_LIBS = @OPTIONAL_LZO_LIBS@ OPTIONAL_PKCS11_HELPER_CFLAGS = @OPTIONAL_PKCS11_HELPER_CFLAGS@ OPTIONAL_PKCS11_HELPER_LIBS = @OPTIONAL_PKCS11_HELPER_LIBS@ OPTIONAL_SELINUX_LIBS = @OPTIONAL_SELINUX_LIBS@ +OPTIONAL_SYSTEMD_LIBS = @OPTIONAL_SYSTEMD_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ @@ -282,6 +283,7 @@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SOCKETS_LIBS = @SOCKETS_LIBS@ STRIP = @STRIP@ +SYSTEMD_ASK_PASSWORD = @SYSTEMD_ASK_PASSWORD@ TAP_CFLAGS = @TAP_CFLAGS@ TAP_WIN_COMPONENT_ID = @TAP_WIN_COMPONENT_ID@ TAP_WIN_MIN_MAJOR = @TAP_WIN_MIN_MAJOR@ @@ -322,6 +324,8 @@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ +libsystemd_CFLAGS = @libsystemd_CFLAGS@ +libsystemd_LIBS = @libsystemd_LIBS@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ diff --git a/src/plugins/auth-pam/Makefile.in b/src/plugins/auth-pam/Makefile.in index 5e3af86..1e1547a 100644 --- a/src/plugins/auth-pam/Makefile.in +++ b/src/plugins/auth-pam/Makefile.in @@ -278,6 +278,7 @@ OPTIONAL_LZO_LIBS = @OPTIONAL_LZO_LIBS@ OPTIONAL_PKCS11_HELPER_CFLAGS = @OPTIONAL_PKCS11_HELPER_CFLAGS@ OPTIONAL_PKCS11_HELPER_LIBS = @OPTIONAL_PKCS11_HELPER_LIBS@ OPTIONAL_SELINUX_LIBS = @OPTIONAL_SELINUX_LIBS@ +OPTIONAL_SYSTEMD_LIBS = @OPTIONAL_SYSTEMD_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ @@ -306,6 +307,7 @@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SOCKETS_LIBS = @SOCKETS_LIBS@ STRIP = @STRIP@ +SYSTEMD_ASK_PASSWORD = @SYSTEMD_ASK_PASSWORD@ TAP_CFLAGS = @TAP_CFLAGS@ TAP_WIN_COMPONENT_ID = @TAP_WIN_COMPONENT_ID@ TAP_WIN_MIN_MAJOR = @TAP_WIN_MIN_MAJOR@ @@ -346,6 +348,8 @@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ +libsystemd_CFLAGS = @libsystemd_CFLAGS@ +libsystemd_LIBS = @libsystemd_LIBS@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ diff --git a/src/plugins/down-root/Makefile.in b/src/plugins/down-root/Makefile.in index 7bd7c88..26c4912 100644 --- a/src/plugins/down-root/Makefile.in +++ b/src/plugins/down-root/Makefile.in @@ -277,6 +277,7 @@ OPTIONAL_LZO_LIBS = @OPTIONAL_LZO_LIBS@ OPTIONAL_PKCS11_HELPER_CFLAGS = @OPTIONAL_PKCS11_HELPER_CFLAGS@ OPTIONAL_PKCS11_HELPER_LIBS = @OPTIONAL_PKCS11_HELPER_LIBS@ OPTIONAL_SELINUX_LIBS = @OPTIONAL_SELINUX_LIBS@ +OPTIONAL_SYSTEMD_LIBS = @OPTIONAL_SYSTEMD_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ @@ -305,6 +306,7 @@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SOCKETS_LIBS = @SOCKETS_LIBS@ STRIP = @STRIP@ +SYSTEMD_ASK_PASSWORD = @SYSTEMD_ASK_PASSWORD@ TAP_CFLAGS = @TAP_CFLAGS@ TAP_WIN_COMPONENT_ID = @TAP_WIN_COMPONENT_ID@ TAP_WIN_MIN_MAJOR = @TAP_WIN_MIN_MAJOR@ @@ -345,6 +347,8 @@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ +libsystemd_CFLAGS = @libsystemd_CFLAGS@ +libsystemd_LIBS = @libsystemd_LIBS@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ diff --git a/tests/Makefile.in b/tests/Makefile.in index f287a74..80d5d53 100644 --- a/tests/Makefile.in +++ b/tests/Makefile.in @@ -402,6 +402,7 @@ OPTIONAL_LZO_LIBS = @OPTIONAL_LZO_LIBS@ OPTIONAL_PKCS11_HELPER_CFLAGS = @OPTIONAL_PKCS11_HELPER_CFLAGS@ OPTIONAL_PKCS11_HELPER_LIBS = @OPTIONAL_PKCS11_HELPER_LIBS@ OPTIONAL_SELINUX_LIBS = @OPTIONAL_SELINUX_LIBS@ +OPTIONAL_SYSTEMD_LIBS = @OPTIONAL_SYSTEMD_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ @@ -430,6 +431,7 @@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SOCKETS_LIBS = @SOCKETS_LIBS@ STRIP = @STRIP@ +SYSTEMD_ASK_PASSWORD = @SYSTEMD_ASK_PASSWORD@ TAP_CFLAGS = @TAP_CFLAGS@ TAP_WIN_COMPONENT_ID = @TAP_WIN_COMPONENT_ID@ TAP_WIN_MIN_MAJOR = @TAP_WIN_MIN_MAJOR@ @@ -470,6 +472,8 @@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ +libsystemd_CFLAGS = @libsystemd_CFLAGS@ +libsystemd_LIBS = @libsystemd_LIBS@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ diff --git a/tests/t_lpback.sh b/tests/t_lpback.sh index 40767a1..8f88ad9 100755 --- a/tests/t_lpback.sh +++ b/tests/t_lpback.sh @@ -2,6 +2,7 @@ # # t_lpback.sh - script to test OpenVPN's crypto loopback # Copyright (C) 2005 Matthias Andree +# Copyright (C) 2014 Steffan Karger # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License @@ -18,15 +19,39 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, USA. -set -e +set -eu top_builddir="${top_builddir:-..}" trap "rm -f key.$$ log.$$ ; trap 0 ; exit 77" 1 2 15 trap "rm -f key.$$ log.$$ ; exit 1" 0 3 + +# Get list of supported ciphers from openvpn --show-ciphers output +CIPHERS=$(${top_builddir}/src/openvpn/openvpn --show-ciphers | \ + sed -e '1,/^$/d' -e s'/ .*//' -e '/^\s*$/d' | sort) + +# SK, 2014-06-04: currently the DES-EDE3-CFB1 implementation of OpenSSL is +# broken (see http://rt.openssl.org/Ticket/Display.html?id=2867), so exclude +# that cipher from this test. +# GD, 2014-07-06 so is DES-CFB1 +# GD, 2014-07-06 do not test RC5-* either (fails on NetBSD w/o libcrypto_rc5) +CIPHERS=$(echo "$CIPHERS" | egrep -v '^(DES-EDE3-CFB1|DES-CFB1|RC5-)' ) + "${top_builddir}/src/openvpn/openvpn" --genkey --secret key.$$ set +e -( "${top_builddir}/src/openvpn/openvpn" --test-crypto --secret key.$$ ) >log.$$ 2>&1 -e=$? -if [ $e != 0 ] ; then cat log.$$ ; fi + +e=0 +for cipher in ${CIPHERS} +do + echo -n "Testing cipher ${cipher}... " + ( "${top_builddir}/src/openvpn/openvpn" --test-crypto --secret key.$$ --cipher ${cipher} ) >log.$$ 2>&1 + if [ $? != 0 ] ; then + echo "FAILED" + cat log.$$ + e=1 + else + echo "OK" + fi +done + rm key.$$ log.$$ trap 0 exit $e diff --git a/version.m4 b/version.m4 index 2e4b5e4..0bd830f 100644 --- a/version.m4 +++ b/version.m4 @@ -1,9 +1,9 @@ dnl define the OpenVPN version define([PRODUCT_NAME], [OpenVPN]) define([PRODUCT_TARNAME], [openvpn]) -define([PRODUCT_VERSION], [2.3.4]) +define([PRODUCT_VERSION], [2.3.5]) define([PRODUCT_BUGREPORT], [openvpn-users@lists.sourceforge.net]) -define([PRODUCT_VERSION_RESOURCE], [2,3,4,0]) +define([PRODUCT_VERSION_RESOURCE], [2,3,5,0]) dnl define the TAP version define([PRODUCT_TAP_WIN_COMPONENT_ID], [tap0901]) define([PRODUCT_TAP_WIN_MIN_MAJOR], [9]) -- cgit v1.2.3