diff options
264 files changed, 4303 insertions, 4434 deletions
@@ -17,6 +17,7 @@ Release Debug Win32-Output +.vs .deps .libs Makefile @@ -55,6 +56,7 @@ distro/systemd/*.service sample/sample-keys/sample-ca/ vendor/.build vendor/dist +build/msvc/msvc-generate/version.m4 tests/t_client.sh tests/t_client-*-20??????-??????/ @@ -1,6 +1,6 @@ OpenVPN (TM) -- An Open Source VPN daemon -Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> +Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> This distribution contains multiple components, some of which fall under different licenses. By using OpenVPN @@ -11,7 +11,7 @@ each respective component. OpenVPN trademark ----------------- - "OpenVPN" is a trademark of OpenVPN Technologies, Inc. + "OpenVPN" is a trademark of OpenVPN Inc OpenVPN license: @@ -21,7 +21,7 @@ OpenVPN license: Special exception for linking OpenVPN with OpenSSL: - In addition, as a special exception, OpenVPN Technologies, Inc. gives + In addition, as a special exception, OpenVPN Inc gives permission to link the code of this program with the OpenSSL library (or with modified versions of OpenSSL that use the same license as OpenSSL), and distribute linked combinations including @@ -52,7 +52,7 @@ TAP-Win32/TAP-Win64 Driver license: Damion K. Wilson. The source and object code of the TAP-Win32/TAP-Win64 driver - is Copyright (C) 2002-2010 OpenVPN Technologies, Inc., and is released under + is Copyright (C) 2002-2018 OpenVPN Inc, and is released under the GPL version 2. Windows DDK Samples: @@ -1,5 +1,192 @@ OpenVPN Change Log -Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> +Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> + +2018.02.28 -- Version 2.4.4 +Antonio Quartulli (4): + reload HTTP proxy credentials when moving to the next connection profile + Allow learning iroutes with network made up of all 0s (only if netbits < 8) + mbedtls: fix typ0 in comment + manpage: fix simple typ0 + +Arne Schwabe (2): + Treat dhcp-option DNS6 and DNS identical + show the right string for key-direction + +Bertrand Bonnefoy-Claudet (1): + Fix typo in error message: "optione" -> "option" + +David Sommerseth (8): + lz4: Fix confused version check + lz4: Fix broken builds when pkg-config is not present but system library is + Remove references to keychain-mcd in Changes.rst + lz4: Rebase compat-lz4 against upstream v1.7.5 + systemd: Add and ship README.systemd + Update copyright to include 2018 plus company name change + man: Add .TQ groff support macro + man: Reword --management to prefer unix sockets over TCP + +Emmanuel Deloget (1): + OpenSSL: check EVP_PKEY key types before returning the pkey + +Gert Doering (2): + Remove warning on pushed tun-ipv6 option. + Fix removal of on-link prefix on windows with netsh + +Ilya Shipitsin (2): + travis-ci: add brew cache, remove ccache + travis-ci: modify openssl build script to support openssl-1.1.0 + +James Bottomley (1): + autoconf: Fix engine checks for openssl 1.1 + +Jeremie Courreges-Anglas (2): + Cast time_t to long long in order to print it. + Fix build with LibreSSL + +Selva Nair (14): + Check whether in pull_mode before warning about previous connection blocks + Avoid illegal memory access when malformed data is read from the pipe + Fix missing check for return value of malloc'd buffer + Return NULL if GetAdaptersInfo fails + Use RSA_meth_free instead of free + Bring cryptoapi.c upto speed with openssl 1.1 + Add SSL_CTX_get_max_proto_version() not in openssl 1.0 + TLS v1.2 support for cryptoapicert -- RSA only + Refactor get_interface_metric to return metric and auto flag separately + Ensure strings read from registry are null-terminated + Make most registry values optional + Use lowest metric interface when multiple interfaces match a route + Adapt to RegGetValue brokenness in Windows 7 + Fix format spec errors in Windows builds + +Simon Rozman (11): + Local functions are not supported in MSVC. Bummer. + Mixing wide and regular strings in concatenations is not allowed in MSVC. + RtlIpv6AddressToStringW() and RtlIpv4AddressToStringW() require mstcpip.h + Simplify iphlpapi.dll API calls + Fix local #include to use quoted form + Document ">PASSWORD:Auth-Token" real-time message + Fix typo in "verb" command examples + Uniform swprintf() across MinGW and MSVC compilers + MSVC meta files added to .gitignore list + openvpnserv: Add support for multi-instances + Document missing OpenVPN states + +Steffan Karger (21): + make struct key * argument of init_key_ctx const + buffer_list_aggregate_separator(): add unit tests + Add --tls-cert-profile option. + Use P_DATA_V2 for server->client packets too + Fix memory leak in buffer unit tests + buffer_list_aggregate_separator(): update list size after aggregating + buffer_list_aggregate_separator(): don't exceed max_len + buffer_list_aggregate_separator(): prevent 0-byte malloc + Fix types around buffer_list_push(_data) + ssl_openssl: fix compiler warning by removing getbio() wrapper + travis: use clang's -fsanitize=address to catch more bugs + Fix --tls-version-min and --tls-version-max for OpenSSL 1.1+ + Add support for TLS 1.3 in --tls-version-{min, max} + Plug memory leak if push is interrupted + Fix format errors when cross-compiling for Windows + Log pre-handshake packet drops using D_MULTI_DROPPED + Enable stricter compiler warnings by default + Get rid of ax_check_compile_flag.m4 + mbedtls: don't use API deprecated in mbed 2.7 + Warn if tls-version-max < tls-version-min + Don't throw fatal errors from create_temp_file() + +hashiz (1): + Fix '--bind ipv6only' + + +2017.09.25 -- Version 2.4.4 +Antonio Quartulli (23): + crypto: correct typ0 in error message + use M_ERRNO instead of explicitly printing errno + don't print errno twice + ntlm: avoid useless cast + ntlm: unwrap multiple function calls + route: improve error message + management: preserve wait_for_push field when asking for user/pass + tls-crypt: avoid warnings when --disable-crypto is used + ntlm: convert binary buffers to uint8_t * + ntlm: restyle compressed multiple function calls + ntlm: improve code style and readability + OpenSSL: remove unreachable call to SSL_CTX_get0_privatekey() + make function declarations C99 compliant + remove unused functions + use NULL instead of 0 when assigning pointers + add missing static attribute to functions + ntlm: avoid breaking anti-aliasing rules + remove the --disable-multi config switch + rename mroute_extract_addr_ipv4 to mroute_extract_addr_ip + route: avoid definition of unused variables in certain configurations + fix a couple of typ0s in comments and strings + fragment.c: simplify boolean expression + tcp-server: ensure AF family is propagated to child context + +Arne Schwabe (2): + Set tls-cipher restriction before loading certificates + Print ec bit details, refuse management-external-key if key is not RSA + +Conrad Hoffmann (2): + Use provided env vars in up/down script. + Document down-root plugin usage in client.down + +David Sommerseth (11): + doc: The CRL processing is not a deprecated feature + cleanup: Move write_pid() to where it is being used + contrib: Remove keychain-mcd code + cleanup: Move init_random_seed() to where it is being used + sample-plugins: fix ASN1_STRING_to_UTF8 return value checks + Highlight deprecated features + Use consistent version references + docs: Replace all PolarSSL references to mbed TLS + systemd: Ensure systemd shuts down OpenVPN in a proper way + systemd: Enable systemd's auto-restart feature for server profiles + lz4: Move towards a newer LZ4 API + +Emmanuel Deloget (3): + OpenSSL: remove pre-1.1 function from the OpenSSL compat interface + OpenSSL: remove EVP_CIPHER_CTX_new() from the compat layer + OpenSSL: remove EVP_CIPHER_CTX_free() from the compat layer + +Gert van Dijk (1): + Warn that DH config option is only meaningful in a tls-server context + +Ilya Shipitsin (3): + travis-ci: add 3 missing patches from master to release/2.4 + travis-ci: update openssl to 1.0.2l, update mbedtls to 2.5.1 + travis-ci: update pkcs11-helper to 1.22 + +Richard Bonhomme (1): + man: Corrections to doc/openvpn.8 + +Steffan Karger (17): + Fix typo in extract_x509_extension() debug message + Move adjust_power_of_2() to integer.h + Undo cipher push in client options state if cipher is rejected + Remove strerror_ts() + Move openvpn_sleep() to manage.c + fixup: also change missed openvpn_sleep() occurrences + Always use default keysize for NCP'd ciphers + Move create_temp_file() out of #ifdef ENABLE_CRYPTO + Deprecate --keysize + Deprecate --no-replay + Move run_up_down() to init.c + tls-crypt: introduce tls_crypt_kt() + crypto: create function to initialize encrypt and decrypt key + Add coverity static analysis to Travis CI config + tls-crypt: don't leak memory for incorrect tls-crypt messages + travis: reorder matrix to speed up build + Fix bounds check in read_key() + +Szilárd Pfeiffer (1): + OpenSSL: Always set SSL_OP_CIPHER_SERVER_PREFERENCE flag + +Thomas Veerman via Openvpn-devel (1): + Fix socks_proxy_port pointing to invalid data + 2017.06.21 -- Version 2.4.3 Antonio Quartulli (1): diff --git a/Changes.rst b/Changes.rst index 454dde4..4168d62 100644 --- a/Changes.rst +++ b/Changes.rst @@ -44,6 +44,13 @@ ECDH key exchange The TLS control channel now supports for elliptic curve diffie-hellmann key exchange (ECDH). +Improved Certificate Revocation List (CRL) processing + CRLs are now handled by the crypto library (OpenSSL or mbed TLS), instead + of inside OpenVPN itself. The crypto library implementations are more + strict than the OpenVPN implementation was. This might reject peer + certificates that would previously be accepted. If this occurs, OpenVPN + will log the crypto library's error description. + Dualstack round-robin DNS client connect Instead of only using the first address of each ``--remote`` OpenVPN will now try all addresses (IPv6 and IPv4) of a ``--remote`` entry. @@ -126,10 +133,6 @@ keying-material-exporter Keying Material Exporter [RFC-5705] allow additional keying material to be derived from existing TLS channel. -Mac OS X Keychain management client - Added contrib/keychain-mcd which allows to use Mac OS X keychain - certificates with OpenVPN. - Android platform support Support for running on Android using Android's VPNService API has been added. See doc/android.txt for more details. This support is primarily used in @@ -154,28 +157,41 @@ Asynchronous push reply Deprecated features ------------------- -- ``--key-method 1`` is deprecated in 2.4 and will be removed in 2.5. Migrate - away from ``--key-method 1`` as soon as possible. The recommended approach - is to remove the ``--key-method`` option from the configuration files, OpenVPN - will then use ``--key-method 2`` by default. Note that this requires changing - the option in both the client and server side configs. +For an up-to-date list of all deprecated options, see this wiki page: +https://community.openvpn.net/openvpn/wiki/DeprecatedOptions + +- ``--key-method 1`` is deprecated in OpenVPN 2.4 and will be removed in v2.5. + Migrate away from ``--key-method 1`` as soon as possible. The recommended + approach is to remove the ``--key-method`` option from the configuration + files, OpenVPN will then use ``--key-method 2`` by default. Note that this + requires changing the option in both the client and server side configs. + +- ``--tls-remote`` is removed in OpenVPN 2.4, as indicated in the v2.3 + man-pages. Similar functionality is provided via ``--verify-x509-name``, + which does the same job in a better way. + +- ``--compat-names`` and ``--no-name-remapping`` were deprecated in OpenVPN 2.3 + and will be removed in v2.5. All scripts and plug-ins depending on the old + non-standard X.509 subject formatting must be updated to the standardized + formatting. See the man page for more information. + +- ``--no-iv`` is deprecated in OpenVPN 2.4 and will be removed in v2.5. + +- ``--keysize`` is deprecated in OpenVPN 2.4 and will be removed in v2.6 + together with the support of ciphers with cipher block size less than + 128-bits. -- CRLs are now handled by the crypto library (OpenSSL or mbed TLS), instead of - inside OpenVPN itself. The crypto library implementations are more strict - than the OpenVPN implementation was. This might reject peer certificates - that would previously be accepted. If this occurs, OpenVPN will log the - crypto library's error description. +- ``--comp-lzo`` is deprecated in OpenVPN 2.4. Use ``--compress`` instead. -- ``--tls-remote`` is removed in 2.4, as indicated in the 2.3 man-pages. Similar - functionality is provided via ``--verify-x509-name``, which does the same job in - a better way. +- ``--ifconfig-pool-linear`` has been deprecated since OpenVPN 2.1 and will be + removed in v2.5. Use ``--topology p2p`` instead. -- ``--compat-names`` and ``--no-name-remapping`` were deprecated in 2.3 and will - be removed in 2.5. All scripts and plug-ins depending on the old non-standard - X.509 subject formatting must be updated to the standardized formatting. See - the man page for more information. +- ``--client-cert-not-required`` is deprecated in OpenVPN 2.4 and will be removed + in v2.5. Use ``--verify-client-cert none`` for a functional equivalent. -- ``--no-iv`` is deprecated in 2.4 and will be removed in 2.5. +- ``--ns-cert-type`` is deprecated in OpenVPN 2.3.18 and v2.4. It will be removed + in v2.5. Use the far better ``--remote-cert-tls`` option which replaces this + feature. User-visible Changes @@ -298,13 +314,120 @@ Maintainer-visible changes files instead of older ones, to provide a unified behaviour across systemd based Linux distributions. -- With OpenVPN v2.4, the project has moved over to depend on and actively use +- With OpenVPN 2.4, the project has moved over to depend on and actively use the official C99 standard (-std=c99). This may fail on some older compiler/libc header combinations. In most of these situations it is recommended to use -std=gnu99 in CFLAGS. This is known to be needed when doing i386/i686 builds on RHEL5. +Version 2.4.5 +============= +This is primarily a maintenance release, with further improved OpenSSL 1.1 +integration, several minor bug fixes and other minor improvements. + + +New features +------------ +- The new option ``--tls-cert-profile`` can be used to restrict the set of + allowed crypto algorithms in TLS certificates in mbed TLS builds. The + default profile is 'legacy' for now, which allows SHA1+, RSA-1024+ and any + elliptic curve certificates. The default will be changed to the 'preferred' + profile in the future, which requires SHA2+, RSA-2048+ and any curve. + +- make CryptoAPI support (Windows) compatible with OpenSSL 1.1 builds + +- TLS v1.2 support for cryptoapicert (on Windows) -- RSA only + +- openvpnserv: Add support for multi-instances (to support multiple + parallel OpenVPN installations, like EduVPN and regular OpenVPN) + +- Use P_DATA_V2 for server->client packets too (better packet alignment) + +- improve management interface documentation + +- rework registry key handling for OpenVPN service, notably making most + registry values optional, falling back to reasonable defaults + +- accept IPv6 address for pushed "dhcp-option DNS ..." + (make OpenVPN 2 option compatible with OpenVPN 3 iOS and Android clients) + + +Bug fixes +--------- +- Fix --tls-version-min and --tls-version-max for OpenSSL 1.1+ + +- Fix lots of compiler warnings (format string, type casts, ...) + +- Fix --redirect-gateway route installation on Windows systems that have + multiple interfaces into the same network (e.g. Wifi and wired LAN). + +- Fix IPv6 interface route cleanup on Windows + +- reload HTTP proxy credentials when moving to the next connection profile + +- Fix build with LibreSSL (multiple times) + +- Remove non-useful warning on pushed tun-ipv6 option. + +- fix building with MSVC due to incompatible C constructs + +- autoconf: Fix engine checks for openssl 1.1 + +- lz4: Rebase compat-lz4 against upstream v1.7.5 + +- lz4: Fix broken builds when pkg-config is not present but system library is + +- Fix '--bind ipv6only' + +- Allow learning iroutes with network made up of all 0s + + +Version 2.4.4 +============= +This is primarily a maintenance release, with further improved OpenSSL 1.1 +integration, several minor bug fixes and other minor improvements. + +Bug fixes +--------- +- Fix issues when a pushed cipher via the Negotiable Crypto Parameters (NCP) is + rejected by the remote side + +- Ignore ``--keysize`` when NCP have resulted in a changed cipher. + +- Configurations using ``--auth-nocache`` and the management interface to provide + user credentials (like NetworkManager on Linux) on client side with servers + implementing authentication tokens (for example, using ``--auth-gen-token``) + will now behave correctly and not query the user for an, to them, unknown + authentication token on renegotiations of the tunnel. + +- Fix bug causing invalid or corrupt SOCKS port number when changing the + proxy via the management interface. + +- The man page should now have proper escaping of hyphens/minus characters + and have seen some minor corrections. + +User-visible Changes +-------------------- +- Linux servers with systemd which uses the ``openvpn-server@.service`` unit + file for server configurations will now utilize the automatic restart feature + in systemd. If the OpenVPN server process dies unexpectedly, systemd will + ensure the OpenVPN configuration will be restarted without any user interaction. + +Deprecated features +------------------- +- ``--no-replay`` is deprecated and will be removed in OpenVPN 2.5. +- ``--keysize`` is deprecated in OpenVPN 2.4 and will be removed in v2.6 + +Security +-------- +- CVE-2017-12166: Fix bounds check for configurations using ``--key-method 1``. + Before this fix, it could allow an attacker to send a malformed packet to + trigger a stack overflow. This is considered to be a low risk issue, as + ``--key-method 2`` has been the default since OpenVPN 2.0 (released on + 2005-04-17). This option is already deprecated in v2.4 and will be + completely removed in v2.5. + Version 2.4.3 ============= @@ -321,7 +444,7 @@ New features Security -------- - CVE-2017-7522: Fix ``--x509-track`` post-authentication remote DoS - A client could crash a 2.4+ mbedtls server, if that server uses the + A client could crash a v2.4+ mbedtls server, if that server uses the ``--x509-track`` option and the client has a correct, signed and unrevoked certificate that contains an embedded NUL in the certificate subject. Discovered and reported to the OpenVPN security team by Guido Vranken. @@ -378,7 +501,7 @@ User-visible Changes Bugfixes -------- - Fix fingerprint calculation in mbed TLS builds. This means that mbed TLS users - of OpenVPN 2.4.0, 2.4.1 and 2.4.2 that rely on the values of the + of OpenVPN 2.4.0, v2.4.1 and v2.4.2 that rely on the values of the ``tls_digest_*`` env vars, or that use ``--verify-hash`` will have to change the fingerprint values they check against. The security impact of the incorrect calculation is very minimal; the last few bytes (max 4, typically @@ -407,16 +530,18 @@ Version 2.4.2 Bugfixes -------- -- Fix memory leak introduced in 2.4.1: if --remote-cert-tls is used, we leaked - some memory on each TLS (re)negotiation. +- Fix memory leak introduced in OpenVPN 2.4.1: if ``--remote-cert-tls`` is + used, we leaked some memory on each TLS (re)negotiation. + Security -------- -- Fix a pre-authentication denial-of-service attack on both clients and servers. - By sending a too-large control packet, OpenVPN 2.4.0 or 2.4.1 can be forced - to hit an ASSERT() and stop the process. If ``--tls-auth`` or ``--tls-crypt`` - is used, only attackers that have the ``--tls-auth`` or ``--tls-crypt`` key - can mount an attack. (OSTIF/Quarkslab audit finding 5.1, CVE-2017-7478) +- Fix a pre-authentication denial-of-service attack on both clients and + servers. By sending a too-large control packet, OpenVPN 2.4.0 or v2.4.1 can + be forced to hit an ASSERT() and stop the process. If ``--tls-auth`` or + ``--tls-crypt`` is used, only attackers that have the ``--tls-auth`` or + ``--tls-crypt`` key can mount an attack. + (OSTIF/Quarkslab audit finding 5.1, CVE-2017-7478) - Fix an authenticated remote DoS vulnerability that could be triggered by causing a packet id roll over. An attack is rather inefficient; a peer @@ -1,6 +1,6 @@ Installation instructions for OpenVPN, a Secure Tunneling Daemon -Copyright (C) 2002-2010 OpenVPN Technologies, Inc. This program is free software; +Copyright (C) 2002-2018 OpenVPN Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. @@ -75,8 +75,8 @@ REQUIRES: OPTIONAL (but recommended): (1) OpenSSL library, necessary for encryption, version 0.9.8 or higher required, available from http://www.openssl.org/ - (2) PolarSSL library, an alternative for encryption, version 1.1 or higher - required, available from https://polarssl.org/ + (2) mbed TLS library, an alternative for encryption, version 2.0 or higher + required, available from https://tls.mbed.org/ (3) LZO real-time compression library, required for link compression, available from http://www.oberhumer.com/opensource/lzo/ OpenBSD users can use ports or packages to install lzo, but remember diff --git a/Makefile.am b/Makefile.am index 87da182..f4ca50f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -5,7 +5,7 @@ # packet encryption, packet authentication, and # packet compression. # -# Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> +# Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> # Copyright (C) 2010 David Sommerseth <dazo@users.sourceforge.net> # Copyright (C) 2006-2012 Alon Bar-Lev <alon.barlev@gmail.com> # @@ -58,7 +58,7 @@ SUBDIRS = build distro include src sample doc vendor tests dist_doc_DATA = \ README \ README.IPv6 \ - README.polarssl \ + README.mbedtls \ Changes.rst \ COPYRIGHT.GPL \ COPYING @@ -68,7 +68,7 @@ dist_noinst_DATA = \ .gitattributes \ PORTS \ README.IPv6 TODO.IPv6 \ - README.polarssl \ + README.mbedtls \ openvpn.sln \ msvc-env.bat \ msvc-dev.bat \ diff --git a/Makefile.in b/Makefile.in index 4a09659..34a6439 100644 --- a/Makefile.in +++ b/Makefile.in @@ -21,7 +21,7 @@ # packet encryption, packet authentication, and # packet compression. # -# Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> +# Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> # Copyright (C) 2010 David Sommerseth <dazo@users.sourceforge.net> # Copyright (C) 2006-2012 Alon Bar-Lev <alon.barlev@gmail.com> # @@ -435,6 +435,7 @@ plugindir = @plugindir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ +runstatedir = @runstatedir@ sampledir = @sampledir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ @@ -476,7 +477,7 @@ SUBDIRS = build distro include src sample doc vendor tests dist_doc_DATA = \ README \ README.IPv6 \ - README.polarssl \ + README.mbedtls \ Changes.rst \ COPYRIGHT.GPL \ COPYING @@ -486,7 +487,7 @@ dist_noinst_DATA = \ .gitattributes \ PORTS \ README.IPv6 TODO.IPv6 \ - README.polarssl \ + README.mbedtls \ openvpn.sln \ msvc-env.bat \ msvc-dev.bat \ @@ -1,5 +1,5 @@ OpenVPN -Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> +Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> OpenVPN has been written to try to avoid features that are not standardized well across different @@ -1,6 +1,6 @@ OpenVPN -- A Secure tunneling daemon -Copyright (C) 2002-2010 OpenVPN Technologies, Inc. This program is free software; +Copyright (C) 2002-2018 OpenVPN Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. diff --git a/README.polarssl b/README.mbedtls index 6f1fa51..4875822 100644 --- a/README.polarssl +++ b/README.mbedtls @@ -1,18 +1,18 @@ -This version of OpenVPN has PolarSSL support. To enable follow the following +This version of OpenVPN has mbed TLS support. To enable follow the following instructions: To Build and Install, - ./configure --with-crypto-library=polarssl + ./configure --with-crypto-library=mbedtls make make install -This version depends on PolarSSL 1.3 (and requires at least 1.3.3). +This version depends on mbed TLS 2.0 (and requires at least 2.0.0). ************************************************************************* -Due to limitations in the PolarSSL library, the following features are missing -in the PolarSSL version of OpenVPN: +Due to limitations in the mbed TLS library, the following features are missing +in the mbed TLS version of OpenVPN: * PKCS#12 file support * --capath support - Loading certificate authorities from a directory diff --git a/build/Makefile.am b/build/Makefile.am index 4191a99..b011141 100644 --- a/build/Makefile.am +++ b/build/Makefile.am @@ -5,7 +5,7 @@ # packet encryption, packet authentication, and # packet compression. # -# Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> +# Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> # MAINTAINERCLEANFILES = \ diff --git a/build/Makefile.in b/build/Makefile.in index 94dd803..9b2edad 100644 --- a/build/Makefile.in +++ b/build/Makefile.in @@ -21,7 +21,7 @@ # packet encryption, packet authentication, and # packet compression. # -# Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> +# Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> # VPATH = @srcdir@ am__is_gnu_make = { \ @@ -364,6 +364,7 @@ plugindir = @plugindir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ +runstatedir = @runstatedir@ sampledir = @sampledir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ diff --git a/build/msvc/Makefile.am b/build/msvc/Makefile.am index 85a613b..3e9c3fe 100644 --- a/build/msvc/Makefile.am +++ b/build/msvc/Makefile.am @@ -5,7 +5,7 @@ # packet encryption, packet authentication, and # packet compression. # -# Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> +# Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> # Copyright (C) 2006-2012 Alon Bar-Lev <alon.barlev@gmail.com> # diff --git a/build/msvc/Makefile.in b/build/msvc/Makefile.in index 3e5a1aa..20270ab 100644 --- a/build/msvc/Makefile.in +++ b/build/msvc/Makefile.in @@ -21,7 +21,7 @@ # packet encryption, packet authentication, and # packet compression. # -# Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> +# Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> # Copyright (C) 2006-2012 Alon Bar-Lev <alon.barlev@gmail.com> # VPATH = @srcdir@ @@ -365,6 +365,7 @@ plugindir = @plugindir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ +runstatedir = @runstatedir@ sampledir = @sampledir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ diff --git a/build/msvc/msvc-generate/Makefile.am b/build/msvc/msvc-generate/Makefile.am index 2151b42..4ae850f 100644 --- a/build/msvc/msvc-generate/Makefile.am +++ b/build/msvc/msvc-generate/Makefile.am @@ -5,7 +5,7 @@ # packet encryption, packet authentication, and # packet compression. # -# Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> +# Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> # Copyright (C) 2006-2012 Alon Bar-Lev <alon.barlev@gmail.com> # diff --git a/build/msvc/msvc-generate/Makefile.in b/build/msvc/msvc-generate/Makefile.in index cb092fb..7b44532 100644 --- a/build/msvc/msvc-generate/Makefile.in +++ b/build/msvc/msvc-generate/Makefile.in @@ -21,7 +21,7 @@ # packet encryption, packet authentication, and # packet compression. # -# Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> +# Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> # Copyright (C) 2006-2012 Alon Bar-Lev <alon.barlev@gmail.com> # @@ -308,6 +308,7 @@ plugindir = @plugindir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ +runstatedir = @runstatedir@ sampledir = @sampledir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ diff --git a/config-msvc.h b/config-msvc.h index 9b97e71..0bb153d 100644 --- a/config-msvc.h +++ b/config-msvc.h @@ -4,7 +4,6 @@ #define ENABLE_DEF_AUTH 1 #define ENABLE_PF 1 -#define ENABLE_CLIENT_SERVER 1 #define ENABLE_CRYPTO 1 #define ENABLE_CRYPTO_OPENSSL 1 #define ENABLE_DEBUG 1 diff --git a/config.guess b/config.guess index 0bb53ae..2e9ad7f 100755 --- a/config.guess +++ b/config.guess @@ -1,8 +1,8 @@ #! /bin/sh # Attempt to guess a canonical system name. -# Copyright 1992-2015 Free Software Foundation, Inc. +# Copyright 1992-2016 Free Software Foundation, Inc. -timestamp='2015-03-04' +timestamp='2016-10-02' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -27,7 +27,7 @@ timestamp='2015-03-04' # Originally written by Per Bothner; maintained since 2000 by Ben Elliston. # # You can get the latest version of this script from: -# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess # # Please send patches to <config-patches@gnu.org>. @@ -50,7 +50,7 @@ version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. -Copyright 1992-2015 Free Software Foundation, Inc. +Copyright 1992-2016 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -186,9 +186,12 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in *) machine=${UNAME_MACHINE_ARCH}-unknown ;; esac # The Operating System including object format, if it has switched - # to ELF recently, or will in the future. + # to ELF recently (or will in the future) and ABI. case "${UNAME_MACHINE_ARCH}" in - arm*|earm*|i386|m68k|ns32k|sh3*|sparc|vax) + earm*) + os=netbsdelf + ;; + arm*|i386|m68k|ns32k|sh3*|sparc|vax) eval $set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ELF__ @@ -221,7 +224,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in release='-gnu' ;; *) - release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + release=`echo ${UNAME_RELEASE} | sed -e 's/[-_].*//' | cut -d. -f1,2` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: @@ -237,6 +240,10 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} exit ;; + *:LibertyBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-libertybsd${UNAME_RELEASE} + exit ;; *:ekkoBSD:*:*) echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} exit ;; @@ -249,6 +256,9 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in *:MirBSD:*:*) echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} exit ;; + *:Sortix:*:*) + echo ${UNAME_MACHINE}-unknown-sortix + exit ;; alpha:OSF1:*:*) case $UNAME_RELEASE in *4.0) @@ -265,42 +275,42 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` case "$ALPHA_CPU_TYPE" in "EV4 (21064)") - UNAME_MACHINE="alpha" ;; + UNAME_MACHINE=alpha ;; "EV4.5 (21064)") - UNAME_MACHINE="alpha" ;; + UNAME_MACHINE=alpha ;; "LCA4 (21066/21068)") - UNAME_MACHINE="alpha" ;; + UNAME_MACHINE=alpha ;; "EV5 (21164)") - UNAME_MACHINE="alphaev5" ;; + UNAME_MACHINE=alphaev5 ;; "EV5.6 (21164A)") - UNAME_MACHINE="alphaev56" ;; + UNAME_MACHINE=alphaev56 ;; "EV5.6 (21164PC)") - UNAME_MACHINE="alphapca56" ;; + UNAME_MACHINE=alphapca56 ;; "EV5.7 (21164PC)") - UNAME_MACHINE="alphapca57" ;; + UNAME_MACHINE=alphapca57 ;; "EV6 (21264)") - UNAME_MACHINE="alphaev6" ;; + UNAME_MACHINE=alphaev6 ;; "EV6.7 (21264A)") - UNAME_MACHINE="alphaev67" ;; + UNAME_MACHINE=alphaev67 ;; "EV6.8CB (21264C)") - UNAME_MACHINE="alphaev68" ;; + UNAME_MACHINE=alphaev68 ;; "EV6.8AL (21264B)") - UNAME_MACHINE="alphaev68" ;; + UNAME_MACHINE=alphaev68 ;; "EV6.8CX (21264D)") - UNAME_MACHINE="alphaev68" ;; + UNAME_MACHINE=alphaev68 ;; "EV6.9A (21264/EV69A)") - UNAME_MACHINE="alphaev69" ;; + UNAME_MACHINE=alphaev69 ;; "EV7 (21364)") - UNAME_MACHINE="alphaev7" ;; + UNAME_MACHINE=alphaev7 ;; "EV7.9 (21364A)") - UNAME_MACHINE="alphaev79" ;; + UNAME_MACHINE=alphaev79 ;; esac # A Pn.n version is a patched version. # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. - echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` # Reset EXIT trap before exiting to avoid spurious non-zero exit code. exitcode=$? trap '' 0 @@ -373,16 +383,16 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in exit ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) eval $set_cc_for_build - SUN_ARCH="i386" + SUN_ARCH=i386 # If there is a compiler, see if it is configured for 64-bit objects. # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. # This test works for both compilers. - if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if [ "$CC_FOR_BUILD" != no_compiler_found ]; then if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ - (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then - SUN_ARCH="x86_64" + SUN_ARCH=x86_64 fi fi echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` @@ -407,7 +417,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in exit ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` - test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + test "x${UNAME_RELEASE}" = x && UNAME_RELEASE=3 case "`/bin/arch`" in sun3) echo m68k-sun-sunos${UNAME_RELEASE} @@ -632,13 +642,13 @@ EOF sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` case "${sc_cpu_version}" in - 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 - 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0 + 528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 case "${sc_kernel_bits}" in - 32) HP_ARCH="hppa2.0n" ;; - 64) HP_ARCH="hppa2.0w" ;; - '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + 32) HP_ARCH=hppa2.0n ;; + 64) HP_ARCH=hppa2.0w ;; + '') HP_ARCH=hppa2.0 ;; # HP-UX 10.20 esac ;; esac fi @@ -677,11 +687,11 @@ EOF exit (0); } EOF - (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + (CCOPTS="" $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac - if [ ${HP_ARCH} = "hppa2.0w" ] + if [ ${HP_ARCH} = hppa2.0w ] then eval $set_cc_for_build @@ -694,12 +704,12 @@ EOF # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess # => hppa64-hp-hpux11.23 - if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | + if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | grep -q __LP64__ then - HP_ARCH="hppa2.0w" + HP_ARCH=hppa2.0w else - HP_ARCH="hppa64" + HP_ARCH=hppa64 fi fi echo ${HP_ARCH}-hp-hpux${HPUX_REV} @@ -804,14 +814,14 @@ EOF echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) - FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` + FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; 5000:UNIX_System_V:4.*:*) - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` + FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'` echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) @@ -825,7 +835,12 @@ EOF exit ;; *:FreeBSD:*:*) UNAME_PROCESSOR=`/usr/bin/uname -p` - echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + case ${UNAME_PROCESSOR} in + amd64) + echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + *) + echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + esac exit ;; i*:CYGWIN*:*) echo ${UNAME_MACHINE}-pc-cygwin @@ -888,7 +903,7 @@ EOF exit ;; *:GNU/*:*:*) # other systems with GNU libc and userland - echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC} + echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC} exit ;; i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix @@ -911,7 +926,7 @@ EOF EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep -q ld.so.1 - if test "$?" = 0 ; then LIBC="gnulibc1" ; fi + if test "$?" = 0 ; then LIBC=gnulibc1 ; fi echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; arc:Linux:*:* | arceb:Linux:*:*) @@ -957,6 +972,9 @@ EOF ia64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; + k1om:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; m32r*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; @@ -982,6 +1000,9 @@ EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; } ;; + mips64el:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; openrisc*:Linux:*:*) echo or1k-unknown-linux-${LIBC} exit ;; @@ -1014,6 +1035,9 @@ EOF ppcle:Linux:*:*) echo powerpcle-unknown-linux-${LIBC} exit ;; + riscv32:Linux:*:* | riscv64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; s390:Linux:*:* | s390x:Linux:*:*) echo ${UNAME_MACHINE}-ibm-linux-${LIBC} exit ;; @@ -1033,7 +1057,7 @@ EOF echo ${UNAME_MACHINE}-dec-linux-${LIBC} exit ;; x86_64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo ${UNAME_MACHINE}-pc-linux-${LIBC} exit ;; xtensa*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} @@ -1112,7 +1136,7 @@ EOF # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i586. # Note: whatever this is, it MUST be the same as what config.sub - # prints for the "djgpp" host, or else GDB configury will decide that + # prints for the "djgpp" host, or else GDB configure will decide that # this is a cross-build. echo i586-pc-msdosdjgpp exit ;; @@ -1261,6 +1285,9 @@ EOF SX-8R:SUPER-UX:*:*) echo sx8r-nec-superux${UNAME_RELEASE} exit ;; + SX-ACE:SUPER-UX:*:*) + echo sxace-nec-superux${UNAME_RELEASE} + exit ;; Power*:Rhapsody:*:*) echo powerpc-apple-rhapsody${UNAME_RELEASE} exit ;; @@ -1274,9 +1301,9 @@ EOF UNAME_PROCESSOR=powerpc fi if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then - if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if [ "$CC_FOR_BUILD" != no_compiler_found ]; then if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ - (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then case $UNAME_PROCESSOR in @@ -1298,7 +1325,7 @@ EOF exit ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` - if test "$UNAME_PROCESSOR" = "x86"; then + if test "$UNAME_PROCESSOR" = x86; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi @@ -1329,7 +1356,7 @@ EOF # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. - if test "$cputype" = "386"; then + if test "$cputype" = 386; then UNAME_MACHINE=i386 else UNAME_MACHINE="$cputype" @@ -1371,7 +1398,7 @@ EOF echo i386-pc-xenix exit ;; i*86:skyos:*:*) - echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' + echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE} | sed -e 's/ .*$//'` exit ;; i*86:rdos:*:*) echo ${UNAME_MACHINE}-pc-rdos @@ -1382,23 +1409,25 @@ EOF x86_64:VMkernel:*:*) echo ${UNAME_MACHINE}-unknown-esx exit ;; + amd64:Isilon\ OneFS:*:*) + echo x86_64-unknown-onefs + exit ;; esac cat >&2 <<EOF $0: unable to guess system type -This script, last modified $timestamp, has failed to recognize -the operating system you are using. It is advised that you -download the most up to date version of the config scripts from +This script (version $timestamp), has failed to recognize the +operating system you are using. If your script is old, overwrite +config.guess and config.sub with the latest versions from: - http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD + http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess and - http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD + http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub -If the version you run ($0) is already up to date, please -send the following data and any information you think might be -pertinent to <config-patches@gnu.org> in order to provide the needed -information to handle your system. +If $0 has already been updated, send the following data and any +information you think might be pertinent to config-patches@gnu.org to +provide the necessary information to handle your system. config.guess timestamp = $timestamp diff --git a/config.h.in b/config.h.in index 9e14a39..ade94a9 100644 --- a/config.h.in +++ b/config.h.in @@ -24,9 +24,6 @@ /* Enable client capability only */ #undef ENABLE_CLIENT_ONLY -/* Enable client/server capability */ -#undef ENABLE_CLIENT_SERVER - /* Enable compression stub capability */ #undef ENABLE_COMP_STUB @@ -202,6 +199,9 @@ /* Define to 1 if you have the `dup2' function. */ #undef HAVE_DUP2 +/* Define to 1 if you have the `EC_GROUP_order_bits' function. */ +#undef HAVE_EC_GROUP_ORDER_BITS + /* Define to 1 if you have the `ENGINE_cleanup' function. */ #undef HAVE_ENGINE_CLEANUP @@ -223,12 +223,6 @@ /* Define to 1 if you have the `EVP_aes_256_gcm' function. */ #undef HAVE_EVP_AES_256_GCM -/* Define to 1 if you have the `EVP_CIPHER_CTX_free' function. */ -#undef HAVE_EVP_CIPHER_CTX_FREE - -/* Define to 1 if you have the `EVP_CIPHER_CTX_new' function. */ -#undef HAVE_EVP_CIPHER_CTX_NEW - /* Define to 1 if you have the `EVP_CIPHER_CTX_set_key_length' function. */ #undef HAVE_EVP_CIPHER_CTX_SET_KEY_LENGTH @@ -244,6 +238,9 @@ /* Define to 1 if you have the `EVP_PKEY_get0_DSA' function. */ #undef HAVE_EVP_PKEY_GET0_DSA +/* Define to 1 if you have the `EVP_PKEY_get0_EC_KEY' function. */ +#undef HAVE_EVP_PKEY_GET0_EC_KEY + /* Define to 1 if you have the `EVP_PKEY_get0_RSA' function. */ #undef HAVE_EVP_PKEY_GET0_RSA @@ -301,9 +298,6 @@ /* Define to 1 if you have the `HMAC_CTX_free' function. */ #undef HAVE_HMAC_CTX_FREE -/* Define to 1 if you have the `HMAC_CTX_init' function. */ -#undef HAVE_HMAC_CTX_INIT - /* Define to 1 if you have the `HMAC_CTX_new' function. */ #undef HAVE_HMAC_CTX_NEW @@ -346,6 +340,9 @@ /* Define to 1 if you have the <libgen.h> header file. */ #undef HAVE_LIBGEN_H +/* Define to 1 if you have the `lz4' library (-llz4). */ +#undef HAVE_LIBLZ4 + /* Define to 1 if you have the <limits.h> header file. */ #undef HAVE_LIMITS_H @@ -463,6 +460,9 @@ /* Define to 1 if you have the `RSA_meth_free' function. */ #undef HAVE_RSA_METH_FREE +/* Define to 1 if you have the `RSA_meth_get0_app_data' function. */ +#undef HAVE_RSA_METH_GET0_APP_DATA + /* Define to 1 if you have the `RSA_meth_new' function. */ #undef HAVE_RSA_METH_NEW @@ -545,6 +545,9 @@ /* Define to 1 if you have the `SSL_CTX_new' function. */ #undef HAVE_SSL_CTX_NEW +/* Define to 1 if you have the `SSL_CTX_set_security_level' function. */ +#undef HAVE_SSL_CTX_SET_SECURITY_LEVEL + /* Define to 1 if you have the `stat' function. */ #undef HAVE_STAT @@ -563,9 +566,6 @@ /* Define to 1 if you have the `strdup' function. */ #undef HAVE_STRDUP -/* Define to 1 if you have the `strerror' function. */ -#undef HAVE_STRERROR - /* Define to 1 if you have the <strings.h> header file. */ #undef HAVE_STRINGS_H @@ -1,8 +1,8 @@ #! /bin/sh # Configuration validation subroutine script. -# Copyright 1992-2015 Free Software Foundation, Inc. +# Copyright 1992-2016 Free Software Foundation, Inc. -timestamp='2015-03-08' +timestamp='2016-11-04' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -33,7 +33,7 @@ timestamp='2015-03-08' # Otherwise, we print the canonical config type on stdout and succeed. # You can get the latest version of this script from: -# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases @@ -53,8 +53,7 @@ timestamp='2015-03-08' me=`echo "$0" | sed -e 's,.*/,,'` usage="\ -Usage: $0 [OPTION] CPU-MFR-OPSYS - $0 [OPTION] ALIAS +Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS Canonicalize a configuration name. @@ -68,7 +67,7 @@ Report bugs and patches to <config-patches@gnu.org>." version="\ GNU config.sub ($timestamp) -Copyright 1992-2015 Free Software Foundation, Inc. +Copyright 1992-2016 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -118,7 +117,7 @@ case $maybe_os in nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \ - kopensolaris*-gnu* | \ + kopensolaris*-gnu* | cloudabi*-eabi* | \ storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` @@ -255,6 +254,7 @@ case $basic_machine in | arc | arceb \ | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ | avr | avr32 \ + | ba \ | be32 | be64 \ | bfin \ | c4x | c8051 | clipper \ @@ -301,11 +301,12 @@ case $basic_machine in | open8 | or1k | or1knd | or32 \ | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle \ + | pru \ | pyramid \ | riscv32 | riscv64 \ | rl78 | rx \ | score \ - | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ + | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[234]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ | sh64 | sh64le \ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ @@ -373,9 +374,10 @@ case $basic_machine in | aarch64-* | aarch64_be-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ - | alphapca5[67]-* | alpha64pca5[67]-* | amd64-* | arc-* | arceb-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | avr-* | avr32-* \ + | ba-* \ | be32-* | be64-* \ | bfin-* | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* \ @@ -427,13 +429,15 @@ case $basic_machine in | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ + | pru-* \ | pyramid-* \ + | riscv32-* | riscv64-* \ | rl78-* | romp-* | rs6000-* | rx-* \ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ | sparclite-* \ - | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx*-* \ | tahoe-* \ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ | tile*-* \ @@ -485,6 +489,12 @@ case $basic_machine in basic_machine=a29k-none os=-bsd ;; + amd64) + basic_machine=x86_64-pc + ;; + amd64-*) + basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; amdahl) basic_machine=580-amdahl os=-sysv @@ -512,7 +522,7 @@ case $basic_machine in basic_machine=i386-pc os=-aros ;; - asmjs) + asmjs) basic_machine=asmjs-unknown ;; aux) @@ -635,6 +645,14 @@ case $basic_machine in basic_machine=m68k-bull os=-sysv3 ;; + e500v[12]) + basic_machine=powerpc-unknown + os=$os"spe" + ;; + e500v[12]-*) + basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + os=$os"spe" + ;; ebmon29k) basic_machine=a29k-amd os=-ebmon @@ -1014,7 +1032,7 @@ case $basic_machine in ppc-* | ppcbe-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` ;; - ppcle | powerpclittle | ppc-le | powerpc-little) + ppcle | powerpclittle) basic_machine=powerpcle-unknown ;; ppcle-* | powerpclittle-*) @@ -1024,7 +1042,7 @@ case $basic_machine in ;; ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; - ppc64le | powerpc64little | ppc64-le | powerpc64-little) + ppc64le | powerpc64little) basic_machine=powerpc64le-unknown ;; ppc64le-* | powerpc64little-*) @@ -1370,18 +1388,18 @@ case $os in | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ | -sym* | -kopensolaris* | -plan9* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ - | -aos* | -aros* | -cloudabi* \ + | -aos* | -aros* | -cloudabi* | -sortix* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ - | -bitrig* | -openbsd* | -solidbsd* \ + | -bitrig* | -openbsd* | -solidbsd* | -libertybsd* \ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -chorusos* | -chorusrdb* | -cegcc* \ | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ - | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ + | -midipix* | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ | -linux-newlib* | -linux-musl* | -linux-uclibc* \ | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ @@ -1390,7 +1408,8 @@ case $os in | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ - | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* | -tirtos*) + | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \ + | -onefs* | -tirtos* | -phoenix* | -fuchsia*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) @@ -1522,6 +1541,8 @@ case $os in ;; -nacl*) ;; + -ios) + ;; -none) ;; *) @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for OpenVPN 2.4.3. +# Generated by GNU Autoconf 2.69 for OpenVPN 2.4.5. # # Report bugs to <openvpn-users@lists.sourceforge.net>. # @@ -590,8 +590,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='OpenVPN' PACKAGE_TARNAME='openvpn' -PACKAGE_VERSION='2.4.3' -PACKAGE_STRING='OpenVPN 2.4.3' +PACKAGE_VERSION='2.4.5' +PACKAGE_STRING='OpenVPN 2.4.5' PACKAGE_BUGREPORT='openvpn-users@lists.sourceforge.net' PACKAGE_URL='' @@ -810,6 +810,7 @@ infodir docdir oldincludedir includedir +runstatedir localstatedir sharedstatedir sysconfdir @@ -840,7 +841,6 @@ enable_comp_stub enable_crypto enable_ofb_cfb enable_x509_alt_username -enable_multi enable_server enable_plugins enable_management @@ -953,6 +953,7 @@ datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' +runstatedir='${localstatedir}/run' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' @@ -1205,6 +1206,15 @@ do | -silent | --silent | --silen | --sile | --sil) silent=yes ;; + -runstatedir | --runstatedir | --runstatedi | --runstated \ + | --runstate | --runstat | --runsta | --runst | --runs \ + | --run | --ru | --r) + ac_prev=runstatedir ;; + -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ + | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ + | --run=* | --ru=* | --r=*) + runstatedir=$ac_optarg ;; + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ @@ -1342,7 +1352,7 @@ fi for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ - libdir localedir mandir + libdir localedir mandir runstatedir do eval ac_val=\$$ac_var # Remove trailing slashes. @@ -1455,7 +1465,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.4.3 to adapt to many kinds of systems. +\`configure' configures OpenVPN 2.4.5 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1495,6 +1505,7 @@ Fine tuning of the installation directories: --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] @@ -1525,7 +1536,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of OpenVPN 2.4.3:";; + short | recursive ) echo "Configuration of OpenVPN 2.4.5:";; esac cat <<\_ACEOF @@ -1548,8 +1559,6 @@ Optional Features: --enable-x509-alt-username enable the --x509-username-field feature [default=no] - --disable-multi disable client/server support (--mode server + - client mode) [default=yes] --disable-server disable server support only (but retain client support) [default=yes] --disable-plugins disable plug-in support [default=yes] @@ -1578,7 +1587,7 @@ Optional Features: --enable-pedantic enable pedantic compiler warnings, will not generate a working executable (debugging option) [default=no] --enable-werror promote compiler warnings to errors, will cause - builds to fail is the compiler issues warnings + builds to fail if the compiler issues warnings (debugging option) [default=no] --enable-strict-options enable strict options check between peers (debugging option) [default=no] @@ -1734,7 +1743,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -OpenVPN configure 2.4.3 +OpenVPN configure 2.4.5 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -2573,7 +2582,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.4.3, which was +It was created by OpenVPN $as_me 2.4.5, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -2937,13 +2946,13 @@ if test -z "${htmldir}"; then fi -$as_echo "#define OPENVPN_VERSION_RESOURCE 2,4,3,0" >>confdefs.h +$as_echo "#define OPENVPN_VERSION_RESOURCE 2,4,5,0" >>confdefs.h OPENVPN_VERSION_MAJOR=2 OPENVPN_VERSION_MINOR=4 -OPENVPN_VERSION_PATCH=.3 +OPENVPN_VERSION_PATCH=.5 $as_echo "#define OPENVPN_VERSION_MAJOR 2" >>confdefs.h @@ -2952,7 +2961,7 @@ $as_echo "#define OPENVPN_VERSION_MAJOR 2" >>confdefs.h $as_echo "#define OPENVPN_VERSION_MINOR 4" >>confdefs.h -$as_echo "#define OPENVPN_VERSION_PATCH \".3\"" >>confdefs.h +$as_echo "#define OPENVPN_VERSION_PATCH \".5\"" >>confdefs.h ac_aux_dir= @@ -3476,7 +3485,7 @@ fi # Define the identity of the package. PACKAGE='openvpn' - VERSION='2.4.3' + VERSION='2.4.5' cat >>confdefs.h <<_ACEOF @@ -5192,15 +5201,6 @@ else fi -# Check whether --enable-multi was given. -if test "${enable_multi+set}" = set; then : - enableval=$enable_multi; -else - enable_multi="yes" - -fi - - # Check whether --enable-server was given. if test "${enable_server+set}" = set; then : enableval=$enable_server; @@ -7391,7 +7391,7 @@ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) lt_cv_deplibs_check_method=pass_all ;; -netbsd*) +netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' else @@ -11111,6 +11111,9 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie openbsd* | bitrig*) with_gnu_ld=no ;; + linux* | k*bsd*-gnu | gnu*) + link_all_deplibs=no + ;; esac ld_shlibs=yes @@ -11365,7 +11368,7 @@ _LT_EOF fi ;; - netbsd*) + netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= @@ -12035,6 +12038,7 @@ $as_echo "$lt_cv_irix_exported_symbol" >&6; } if test yes = "$lt_cv_irix_exported_symbol"; then archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib' fi + link_all_deplibs=no else archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib' @@ -12056,7 +12060,7 @@ $as_echo "$lt_cv_irix_exported_symbol" >&6; } esac ;; - netbsd*) + netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else @@ -13171,6 +13175,18 @@ fi dynamic_linker='GNU/Linux ld.so' ;; +netbsdelf*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='NetBSD ld.elf_so' + ;; + netbsd*) version_type=sunos need_lib_prefix=no @@ -15600,7 +15616,7 @@ fi for ac_func in \ daemon chroot getpwnam setuid nice system getpid dup dup2 \ - getpass strerror syslog openlog mlockall getgrnam setgid \ + getpass syslog openlog mlockall getgrnam setgid \ setgroups stat flock readv writev time gettimeofday \ ctime memset vsnprintf strdup \ setsid chdir putenv getpeername unlink \ @@ -16598,6 +16614,17 @@ else fi done + if test "${have_openssl_engine}" = "no"; then + ac_fn_c_check_decl "$LINENO" "ENGINE_cleanup" "ac_cv_have_decl_ENGINE_cleanup" " + #include <openssl/engine.h> + + +" +if test "x$ac_cv_have_decl_ENGINE_cleanup" = xyes; then : + have_openssl_engine="yes" +fi + + fi if test "${have_openssl_engine}" = "yes"; then $as_echo "#define HAVE_OPENSSL_ENGINE 1" >>confdefs.h @@ -16621,17 +16648,15 @@ done for ac_func in \ - EVP_CIPHER_CTX_new \ - EVP_CIPHER_CTX_free \ HMAC_CTX_new \ HMAC_CTX_free \ HMAC_CTX_reset \ - HMAC_CTX_init \ EVP_MD_CTX_new \ EVP_MD_CTX_free \ EVP_MD_CTX_reset \ SSL_CTX_get_default_passwd_cb \ SSL_CTX_get_default_passwd_cb_userdata \ + SSL_CTX_set_security_level \ X509_get0_pubkey \ X509_STORE_get0_objects \ X509_OBJECT_free \ @@ -16639,6 +16664,7 @@ done EVP_PKEY_id \ EVP_PKEY_get0_RSA \ EVP_PKEY_get0_DSA \ + EVP_PKEY_get0_EC_KEY \ RSA_set_flags \ RSA_bits \ RSA_get0_key \ @@ -16654,6 +16680,8 @@ done RSA_meth_set_init \ RSA_meth_set_finish \ RSA_meth_set0_app_data \ + RSA_meth_get0_app_data \ + EC_GROUP_order_bits do : @@ -16996,15 +17024,150 @@ fi if test "$enable_lz4" = "yes" && test "$enable_comp_stub" = "no"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for LZ4 Library and Header files..." >&5 -$as_echo "$as_me: checking for LZ4 Library and Header files..." >&6;} - havelz4lib=1 - - # if LZ4_LIBS is set, we assume it will work, otherwise test - if test -z "${LZ4_LIBS}"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for LZ4_compress in -llz4" >&5 -$as_echo_n "checking for LZ4_compress in -llz4... " >&6; } -if ${ac_cv_lib_lz4_LZ4_compress+:} false; then : + if test -z "${LZ4_CFLAGS}" -a -z "${LZ4_LIBS}"; then + # if the user did not explicitly specify flags, try to autodetect + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for LZ4" >&5 +$as_echo_n "checking for LZ4... " >&6; } + +if test -n "$LZ4_CFLAGS"; then + pkg_cv_LZ4_CFLAGS="$LZ4_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4 >= 1.7.1 liblz4 < 100\""; } >&5 + ($PKG_CONFIG --exists --print-errors "liblz4 >= 1.7.1 liblz4 < 100") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LZ4_CFLAGS=`$PKG_CONFIG --cflags "liblz4 >= 1.7.1 liblz4 < 100" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$LZ4_LIBS"; then + pkg_cv_LZ4_LIBS="$LZ4_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4 >= 1.7.1 liblz4 < 100\""; } >&5 + ($PKG_CONFIG --exists --print-errors "liblz4 >= 1.7.1 liblz4 < 100") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LZ4_LIBS=`$PKG_CONFIG --libs "liblz4 >= 1.7.1 liblz4 < 100" 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 + LZ4_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "liblz4 >= 1.7.1 liblz4 < 100" 2>&1` + else + LZ4_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "liblz4 >= 1.7.1 liblz4 < 100" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$LZ4_PKG_ERRORS" >&5 + + LZ4_LIBS="-llz4" # If this fails, we will do another test next. + # We also add set LZ4_LIBS otherwise the + # linker will not know about the lz4 library + +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + LZ4_LIBS="-llz4" # If this fails, we will do another test next. + # We also add set LZ4_LIBS otherwise the + # linker will not know about the lz4 library + +else + LZ4_CFLAGS=$pkg_cv_LZ4_CFLAGS + LZ4_LIBS=$pkg_cv_LZ4_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + have_lz4="yes" +fi + fi + + saved_CFLAGS="${CFLAGS}" + saved_LIBS="${LIBS}" + CFLAGS="${CFLAGS} ${LZ4_CFLAGS}" + LIBS="${LIBS} ${LZ4_LIBS}" + + # If pkgconfig check failed or LZ4_CFLAGS/LZ4_LIBS env vars + # are used, check the version directly in the LZ4 include file + if test "${have_lz4}" != "yes"; then + for ac_header in lz4.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "lz4.h" "ac_cv_header_lz4_h" "$ac_includes_default" +if test "x$ac_cv_header_lz4_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LZ4_H 1 +_ACEOF + have_lz4h="yes" +fi + +done + + + if test "${have_lz4h}" = "yes" ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking additionally if system LZ4 version >= 1.7.1" >&5 +$as_echo_n "checking additionally if system LZ4 version >= 1.7.1... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include <lz4.h> + +int +main () +{ + +/* Version encoding: MMNNPP (Major miNor Patch) - see lz4.h for details */ +#if LZ4_VERSION_NUMBER < 10701L +#error LZ4 is too old +#endif + + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 +$as_echo "ok" >&6; } + have_lz4="yes" + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: system LZ4 library is too old" >&5 +$as_echo "system LZ4 library is too old" >&6; } + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi + fi + + # Double check we have a few needed functions + if test "${have_lz4}" = "yes" ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for LZ4_compress_default in -llz4" >&5 +$as_echo_n "checking for LZ4_compress_default in -llz4... " >&6; } +if ${ac_cv_lib_lz4_LZ4_compress_default+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -17018,62 +17181,89 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext #ifdef __cplusplus extern "C" #endif -char LZ4_compress (); +char LZ4_compress_default (); int main () { -return LZ4_compress (); +return LZ4_compress_default (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_lz4_LZ4_compress=yes + ac_cv_lib_lz4_LZ4_compress_default=yes else - ac_cv_lib_lz4_LZ4_compress=no + ac_cv_lib_lz4_LZ4_compress_default=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lz4_LZ4_compress" >&5 -$as_echo "$ac_cv_lib_lz4_LZ4_compress" >&6; } -if test "x$ac_cv_lib_lz4_LZ4_compress" = xyes; then : - LZ4_LIBS="-llz4" -else +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lz4_LZ4_compress_default" >&5 +$as_echo "$ac_cv_lib_lz4_LZ4_compress_default" >&6; } +if test "x$ac_cv_lib_lz4_LZ4_compress_default" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBLZ4 1 +_ACEOF - { $as_echo "$as_me:${as_lineno-$LINENO}: result: LZ4 library not found." >&5 -$as_echo "LZ4 library not found." >&6; } - havelz4lib=0 + LIBS="-llz4 $LIBS" +else + have_lz4="no" fi - fi + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for LZ4_decompress_safe in -llz4" >&5 +$as_echo_n "checking for LZ4_decompress_safe in -llz4... " >&6; } +if ${ac_cv_lib_lz4_LZ4_decompress_safe+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-llz4 $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ - saved_CFLAGS="${CFLAGS}" - CFLAGS="${CFLAGS} ${LZ4_CFLAGS}" - for ac_header in lz4.h -do : - ac_fn_c_check_header_mongrel "$LINENO" "lz4.h" "ac_cv_header_lz4_h" "$ac_includes_default" -if test "x$ac_cv_header_lz4_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LZ4_H 1 +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char LZ4_decompress_safe (); +int +main () +{ +return LZ4_decompress_safe (); + ; + return 0; +} _ACEOF - +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_lz4_LZ4_decompress_safe=yes else + ac_cv_lib_lz4_LZ4_decompress_safe=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lz4_LZ4_decompress_safe" >&5 +$as_echo "$ac_cv_lib_lz4_LZ4_decompress_safe" >&6; } +if test "x$ac_cv_lib_lz4_LZ4_decompress_safe" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBLZ4 1 +_ACEOF - { $as_echo "$as_me:${as_lineno-$LINENO}: result: LZ4 headers not found." >&5 -$as_echo "LZ4 headers not found." >&6; } - havelz4lib=0 + LIBS="-llz4 $LIBS" +else + have_lz4="no" fi -done - + fi - if test $havelz4lib = 0 ; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: LZ4 library or header not found, using version in src/compat/compat-lz4.*" >&5 -$as_echo "LZ4 library or header not found, using version in src/compat/compat-lz4.*" >&6; } + if test "${have_lz4}" != "yes" ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: usable LZ4 library or header not found, using version in src/compat/compat-lz4.*" >&5 +$as_echo " usable LZ4 library or header not found, using version in src/compat/compat-lz4.*" >&6; } $as_echo "#define NEED_COMPAT_LZ4 1" >>confdefs.h @@ -17085,6 +17275,7 @@ $as_echo "#define NEED_COMPAT_LZ4 1" >>confdefs.h $as_echo "#define ENABLE_LZ4 1" >>confdefs.h CFLAGS="${saved_CFLAGS}" + LIBS="${saved_LIBS}" fi @@ -17464,9 +17655,6 @@ fi test "${ac_cv_header_sys_uio_h}" = "yes" && $as_echo "#define HAVE_IOVEC 1" >>confdefs.h -test "${enable_multi}" = "yes" && -$as_echo "#define ENABLE_CLIENT_SERVER 1" >>confdefs.h - test "${enable_server}" = "no" && $as_echo "#define ENABLE_CLIENT_ONLY 1" >>confdefs.h @@ -17647,6 +17835,84 @@ _ACEOF fi fi + + + + old_cflags="$CFLAGS" + CFLAGS="-Wno-unused-function $CFLAGS" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler acceppts -Wno-unused-function" >&5 +$as_echo_n "checking whether the compiler acceppts -Wno-unused-function... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; }; CFLAGS="$old_cflags" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + + + old_cflags="$CFLAGS" + CFLAGS="-Wno-unused-parameter $CFLAGS" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler acceppts -Wno-unused-parameter" >&5 +$as_echo_n "checking whether the compiler acceppts -Wno-unused-parameter... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; }; CFLAGS="$old_cflags" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + + + old_cflags="$CFLAGS" + CFLAGS="-Wall $CFLAGS" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler acceppts -Wall" >&5 +$as_echo_n "checking whether the compiler acceppts -Wall... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; }; CFLAGS="$old_cflags" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + + if test "${enable_pedantic}" = "yes"; then enable_strict="yes" CFLAGS="${CFLAGS} -pedantic" @@ -17655,7 +17921,7 @@ $as_echo "#define PEDANTIC 1" >>confdefs.h fi if test "${enable_strict}" = "yes"; then - CFLAGS="${CFLAGS} -Wall -Wno-unused-parameter -Wno-unused-function" + CFLAGS="${CFLAGS} -Wsign-compare -Wuninitialized" fi if test "${enable_werror}" = "yes"; then CFLAGS="${CFLAGS} -Werror" @@ -18465,7 +18731,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.4.3, which was +This file was extended by OpenVPN $as_me 2.4.5, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -18531,7 +18797,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.4.3 +OpenVPN config.status 2.4.5 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" @@ -19753,7 +20019,6 @@ $as_echo X"$file" | cat <<_LT_EOF >> "$cfgfile" #! $SHELL # Generated automatically by $as_me ($PACKAGE) $VERSION -# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # NOTE: Changes made to this file will be lost: look at ltmain.sh. # Provide generalized library-building support services. diff --git a/configure.ac b/configure.ac index 2f954a3..88d1e09 100644 --- a/configure.ac +++ b/configure.ac @@ -4,7 +4,7 @@ dnl session authentication and key exchange, dnl packet encryption, packet authentication, and dnl packet compression. dnl -dnl Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> +dnl Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> dnl Copyright (C) 2006-2012 Alon Bar-Lev <alon.barlev@gmail.com> dnl dnl This program is free software; you can redistribute it and/or modify @@ -99,13 +99,6 @@ AC_ARG_ENABLE( ) AC_ARG_ENABLE( - [multi], - [AS_HELP_STRING([--disable-multi], [disable client/server support (--mode server + client mode) @<:@default=yes@:>@])], - , - [enable_multi="yes"] -) - -AC_ARG_ENABLE( [server], [AS_HELP_STRING([--disable-server], [disable server support only (but retain client support) @<:@default=yes@:>@])], , @@ -237,7 +230,7 @@ AC_ARG_ENABLE( AC_ARG_ENABLE( [werror], - [AS_HELP_STRING([--enable-werror], [promote compiler warnings to errors, will cause builds to fail is the compiler issues warnings (debugging option) @<:@default=no@:>@])], + [AS_HELP_STRING([--enable-werror], [promote compiler warnings to errors, will cause builds to fail if the compiler issues warnings (debugging option) @<:@default=no@:>@])], , [enable_werror="no"] ) @@ -662,7 +655,7 @@ AC_FUNC_FORK AC_CHECK_FUNCS([ \ daemon chroot getpwnam setuid nice system getpid dup dup2 \ - getpass strerror syslog openlog mlockall getgrnam setgid \ + getpass syslog openlog mlockall getgrnam setgid \ setgroups stat flock readv writev time gettimeofday \ ctime memset vsnprintf strdup \ setsid chdir putenv getpeername unlink \ @@ -886,6 +879,13 @@ if test "${enable_crypto}" = "yes" -a "${with_crypto_library}" = "openssl"; then , [have_openssl_engine="no"; break] ) + if test "${have_openssl_engine}" = "no"; then + AC_CHECK_DECL( [ENGINE_cleanup], [have_openssl_engine="yes"],, + [[ + #include <openssl/engine.h> + ]] + ) + fi if test "${have_openssl_engine}" = "yes"; then AC_DEFINE([HAVE_OPENSSL_ENGINE], [1], [OpenSSL engine support available]) fi @@ -899,17 +899,15 @@ if test "${enable_crypto}" = "yes" -a "${with_crypto_library}" = "openssl"; then AC_CHECK_FUNCS( [ \ - EVP_CIPHER_CTX_new \ - EVP_CIPHER_CTX_free \ HMAC_CTX_new \ HMAC_CTX_free \ HMAC_CTX_reset \ - HMAC_CTX_init \ EVP_MD_CTX_new \ EVP_MD_CTX_free \ EVP_MD_CTX_reset \ SSL_CTX_get_default_passwd_cb \ SSL_CTX_get_default_passwd_cb_userdata \ + SSL_CTX_set_security_level \ X509_get0_pubkey \ X509_STORE_get0_objects \ X509_OBJECT_free \ @@ -917,6 +915,7 @@ if test "${enable_crypto}" = "yes" -a "${with_crypto_library}" = "openssl"; then EVP_PKEY_id \ EVP_PKEY_get0_RSA \ EVP_PKEY_get0_DSA \ + EVP_PKEY_get0_EC_KEY \ RSA_set_flags \ RSA_bits \ RSA_get0_key \ @@ -932,6 +931,8 @@ if test "${enable_crypto}" = "yes" -a "${with_crypto_library}" = "openssl"; then RSA_meth_set_init \ RSA_meth_set_finish \ RSA_meth_set0_app_data \ + RSA_meth_get0_app_data \ + EC_GROUP_order_bits ] ) @@ -1076,37 +1077,73 @@ dnl AC_ARG_VAR([LZ4_CFLAGS], [C compiler flags for lz4]) AC_ARG_VAR([LZ4_LIBS], [linker flags for lz4]) if test "$enable_lz4" = "yes" && test "$enable_comp_stub" = "no"; then - AC_CHECKING([for LZ4 Library and Header files]) - havelz4lib=1 - - # if LZ4_LIBS is set, we assume it will work, otherwise test - if test -z "${LZ4_LIBS}"; then - AC_CHECK_LIB(lz4, LZ4_compress, - [ LZ4_LIBS="-llz4" ], - [ - AC_MSG_RESULT([LZ4 library not found.]) - havelz4lib=0 - ]) + if test -z "${LZ4_CFLAGS}" -a -z "${LZ4_LIBS}"; then + # if the user did not explicitly specify flags, try to autodetect + PKG_CHECK_MODULES([LZ4], + [liblz4 >= 1.7.1 liblz4 < 100], + [have_lz4="yes"], + [LZ4_LIBS="-llz4"] # If this fails, we will do another test next. + # We also add set LZ4_LIBS otherwise the + # linker will not know about the lz4 library + ) fi saved_CFLAGS="${CFLAGS}" + saved_LIBS="${LIBS}" CFLAGS="${CFLAGS} ${LZ4_CFLAGS}" - AC_CHECK_HEADERS(lz4.h, - , - [ - AC_MSG_RESULT([LZ4 headers not found.]) - havelz4lib=0 - ]) + LIBS="${LIBS} ${LZ4_LIBS}" + + # If pkgconfig check failed or LZ4_CFLAGS/LZ4_LIBS env vars + # are used, check the version directly in the LZ4 include file + if test "${have_lz4}" != "yes"; then + AC_CHECK_HEADERS([lz4.h], + [have_lz4h="yes"], + []) + + if test "${have_lz4h}" = "yes" ; then + AC_MSG_CHECKING([additionally if system LZ4 version >= 1.7.1]) + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([[ +#include <lz4.h> + ]], + [[ +/* Version encoding: MMNNPP (Major miNor Patch) - see lz4.h for details */ +#if LZ4_VERSION_NUMBER < 10701L +#error LZ4 is too old +#endif + ]] + )], + [ + AC_MSG_RESULT([ok]) + have_lz4="yes" + ], + [AC_MSG_RESULT([system LZ4 library is too old])] + ) + fi + fi - if test $havelz4lib = 0 ; then - AC_MSG_RESULT([LZ4 library or header not found, using version in src/compat/compat-lz4.*]) + # Double check we have a few needed functions + if test "${have_lz4}" = "yes" ; then + AC_CHECK_LIB([lz4], + [LZ4_compress_default], + [], + [have_lz4="no"]) + AC_CHECK_LIB([lz4], + [LZ4_decompress_safe], + [], + [have_lz4="no"]) + fi + + if test "${have_lz4}" != "yes" ; then + AC_MSG_RESULT([ usable LZ4 library or header not found, using version in src/compat/compat-lz4.*]) AC_DEFINE([NEED_COMPAT_LZ4], [1], [use copy of LZ4 source in compat/]) LZ4_LIBS="" fi OPTIONAL_LZ4_CFLAGS="${LZ4_CFLAGS}" OPTIONAL_LZ4_LIBS="${LZ4_LIBS}" - AC_DEFINE(ENABLE_LZ4, 1, [Enable LZ4 compression library]) + AC_DEFINE(ENABLE_LZ4, [1], [Enable LZ4 compression library]) CFLAGS="${saved_CFLAGS}" + LIBS="${saved_LIBS}" fi @@ -1178,7 +1215,6 @@ if test "${enable_x509_alt_username}" = "yes"; then fi test "${ac_cv_header_sys_uio_h}" = "yes" && AC_DEFINE([HAVE_IOVEC], [1], [struct iovec needed for IPv6 support]) -test "${enable_multi}" = "yes" && AC_DEFINE([ENABLE_CLIENT_SERVER], [1], [Enable client/server capability]) test "${enable_server}" = "no" && AC_DEFINE([ENABLE_CLIENT_ONLY], [1], [Enable client capability only]) test "${enable_management}" = "yes" && AC_DEFINE([ENABLE_MANAGEMENT], [1], [Enable management server capability]) test "${enable_multihome}" = "yes" && AC_DEFINE([ENABLE_MULTIHOME], [1], [Enable multi-homed UDP server capability]) @@ -1250,13 +1286,25 @@ if test "${enable_pkcs11}" = "yes"; then ) fi +AC_DEFUN([ACL_CHECK_ADD_COMPILE_FLAGS], [ + old_cflags="$CFLAGS" + CFLAGS="$1 $CFLAGS" + AC_MSG_CHECKING([whether the compiler acceppts $1]) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM()], [AC_MSG_RESULT([yes])], + [AC_MSG_RESULT([no]); CFLAGS="$old_cflags"])] +) + +ACL_CHECK_ADD_COMPILE_FLAGS([-Wno-unused-function]) +ACL_CHECK_ADD_COMPILE_FLAGS([-Wno-unused-parameter]) +ACL_CHECK_ADD_COMPILE_FLAGS([-Wall]) + if test "${enable_pedantic}" = "yes"; then enable_strict="yes" CFLAGS="${CFLAGS} -pedantic" AC_DEFINE([PEDANTIC], [1], [Enable pedantic mode]) fi if test "${enable_strict}" = "yes"; then - CFLAGS="${CFLAGS} -Wall -Wno-unused-parameter -Wno-unused-function" + CFLAGS="${CFLAGS} -Wsign-compare -Wuninitialized" fi if test "${enable_werror}" = "yes"; then CFLAGS="${CFLAGS} -Werror" diff --git a/contrib/keychain-mcd/Makefile b/contrib/keychain-mcd/Makefile deleted file mode 100644 index c6431df..0000000 --- a/contrib/keychain-mcd/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -CFILES = cert_data.c common_osx.c crypto_osx.c main.c -OFILES = $(CFILES:.c=.o) ../../src/openvpn/base64.o -prog = keychain-mcd - -CC = gcc -CFLAGS = -Wall -LDFLAGS = -framework CoreFoundation -framework Security -framework CoreServices - -$(prog): $(OFILES) - $(CC) $(LDFLAGS) $(OFILES) -o $(prog) - -%.o: %.c - $(CC) $(CFLAGS) -c $< -o $@ diff --git a/contrib/keychain-mcd/cert_data.c b/contrib/keychain-mcd/cert_data.c deleted file mode 100644 index c04f68e..0000000 --- a/contrib/keychain-mcd/cert_data.c +++ /dev/null @@ -1,866 +0,0 @@ -/* - * OpenVPN -- An application to securely tunnel IP networks - * over a single UDP port, with support for SSL/TLS-based - * session authentication and key exchange, - * packet encryption, packet authentication, and - * packet compression. - * - * Copyright (C) 2010 Brian Raderman <brian@irregularexpression.org> - * Copyright (C) 2013-2015 Vasily Kulikov <segoon@openwall.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include "cert_data.h" -#include <CommonCrypto/CommonDigest.h> -#include <openssl/ssl.h> - -#include "common_osx.h" -#include "crypto_osx.h" -#include <err.h> - -CFStringRef kCertDataSubjectName = CFSTR("subject"), - kCertDataIssuerName = CFSTR("issuer"), - kCertDataSha1Name = CFSTR("SHA1"), - kCertDataMd5Name = CFSTR("MD5"), - kCertDataSerialName = CFSTR("serial"), - kCertNameFwdSlash = CFSTR("/"), - kCertNameEquals = CFSTR("="); -CFStringRef kCertNameOrganization = CFSTR("o"), - kCertNameOrganizationalUnit = CFSTR("ou"), - kCertNameCountry = CFSTR("c"), - kCertNameLocality = CFSTR("l"), - kCertNameState = CFSTR("st"), - kCertNameCommonName = CFSTR("cn"), - kCertNameEmail = CFSTR("e"); -CFStringRef kStringSpace = CFSTR(" "), - kStringEmpty = CFSTR(""); - -typedef struct _CertName -{ - CFArrayRef countryName, organization, organizationalUnit, commonName, description, emailAddress, - stateName, localityName; -} CertName, *CertNameRef; - -typedef struct _DescData -{ - CFStringRef name, value; -} DescData, *DescDataRef; - -void destroyDescData(DescDataRef pData); - -CertNameRef -createCertName() -{ - CertNameRef pCertName = (CertNameRef)malloc(sizeof(CertName)); - pCertName->countryName = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); - pCertName->organization = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); - pCertName->organizationalUnit = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); - pCertName->commonName = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); - pCertName->description = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); - pCertName->emailAddress = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); - pCertName->stateName = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); - pCertName->localityName = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); - return pCertName; -} - -void -destroyCertName(CertNameRef pCertName) -{ - if (!pCertName) - { - return; - } - - CFRelease(pCertName->countryName); - CFRelease(pCertName->organization); - CFRelease(pCertName->organizationalUnit); - CFRelease(pCertName->commonName); - CFRelease(pCertName->description); - CFRelease(pCertName->emailAddress); - CFRelease(pCertName->stateName); - CFRelease(pCertName->localityName); - free(pCertName); -} - -bool -CFStringRefCmpCString(CFStringRef cfstr, const char *str) -{ - CFStringRef tmp = CFStringCreateWithCStringNoCopy(NULL, str, kCFStringEncodingUTF8, kCFAllocatorNull); - CFComparisonResult cresult = CFStringCompare(cfstr, tmp, 0); - bool result = cresult == kCFCompareEqualTo; - CFRelease(tmp); - return result; -} - -CFDateRef -GetDateFieldFromCertificate(SecCertificateRef certificate, CFTypeRef oid) -{ - const void *keys[] = { oid }; - CFDictionaryRef dict = NULL; - CFErrorRef error; - CFDateRef date = NULL; - - CFArrayRef keySelection = CFArrayCreate(NULL, keys, sizeof(keys)/sizeof(keys[0]), &kCFTypeArrayCallBacks); - dict = SecCertificateCopyValues(certificate, keySelection, &error); - if (dict == NULL) - { - printErrorMsg("GetDateFieldFromCertificate: SecCertificateCopyValues", error); - goto release_ks; - } - CFDictionaryRef vals = dict ? CFDictionaryGetValue(dict, oid) : NULL; - CFNumberRef vals2 = vals ? CFDictionaryGetValue(vals, kSecPropertyKeyValue) : NULL; - if (vals2 == NULL) - { - goto release_dict; - } - - CFAbsoluteTime validityNotBefore; - if (CFNumberGetValue(vals2, kCFNumberDoubleType, &validityNotBefore)) - { - date = CFDateCreate(kCFAllocatorDefault,validityNotBefore); - } - -release_dict: - CFRelease(dict); -release_ks: - CFRelease(keySelection); - return date; -} - -CFArrayRef -GetFieldsFromCertificate(SecCertificateRef certificate, CFTypeRef oid) -{ - CFMutableArrayRef fields = CFArrayCreateMutable(NULL, 0, NULL); - CertNameRef pCertName = createCertName(); - const void *keys[] = { oid, }; - CFDictionaryRef dict; - CFErrorRef error; - - CFArrayRef keySelection = CFArrayCreate(NULL, keys, 1, NULL); - - dict = SecCertificateCopyValues(certificate, keySelection, &error); - if (dict == NULL) - { - printErrorMsg("GetFieldsFromCertificate: SecCertificateCopyValues", error); - CFRelease(keySelection); - CFRelease(fields); - destroyCertName(pCertName); - return NULL; - } - CFDictionaryRef vals = CFDictionaryGetValue(dict, oid); - CFArrayRef vals2 = vals ? CFDictionaryGetValue(vals, kSecPropertyKeyValue) : NULL; - if (vals2) - { - for (int i = 0; i < CFArrayGetCount(vals2); i++) { - CFDictionaryRef subDict = CFArrayGetValueAtIndex(vals2, i); - CFStringRef label = CFDictionaryGetValue(subDict, kSecPropertyKeyLabel); - CFStringRef value = CFDictionaryGetValue(subDict, kSecPropertyKeyValue); - - if (CFStringCompare(label, kSecOIDEmailAddress, 0) == kCFCompareEqualTo) - { - CFArrayAppendValue((CFMutableArrayRef)pCertName->emailAddress, value); - } - else if (CFStringCompare(label, kSecOIDCountryName, 0) == kCFCompareEqualTo) - { - CFArrayAppendValue((CFMutableArrayRef)pCertName->countryName, value); - } - else if (CFStringCompare(label, kSecOIDOrganizationName, 0) == kCFCompareEqualTo) - { - CFArrayAppendValue((CFMutableArrayRef)pCertName->organization, value); - } - else if (CFStringCompare(label, kSecOIDOrganizationalUnitName, 0) == kCFCompareEqualTo) - { - CFArrayAppendValue((CFMutableArrayRef)pCertName->organizationalUnit, value); - } - else if (CFStringCompare(label, kSecOIDCommonName, 0) == kCFCompareEqualTo) - { - CFArrayAppendValue((CFMutableArrayRef)pCertName->commonName, value); - } - else if (CFStringCompare(label, kSecOIDDescription, 0) == kCFCompareEqualTo) - { - CFArrayAppendValue((CFMutableArrayRef)pCertName->description, value); - } - else if (CFStringCompare(label, kSecOIDStateProvinceName, 0) == kCFCompareEqualTo) - { - CFArrayAppendValue((CFMutableArrayRef)pCertName->stateName, value); - } - else if (CFStringCompare(label, kSecOIDLocalityName, 0) == kCFCompareEqualTo) - { - CFArrayAppendValue((CFMutableArrayRef)pCertName->localityName, value); - } - } - CFArrayAppendValue(fields, pCertName); - } - - CFRelease(dict); - CFRelease(keySelection); - return fields; -} - -CertDataRef -createCertDataFromCertificate(SecCertificateRef certificate) -{ - CertDataRef pCertData = (CertDataRef)malloc(sizeof(CertData)); - pCertData->subject = GetFieldsFromCertificate(certificate, kSecOIDX509V1SubjectName); - pCertData->issuer = GetFieldsFromCertificate(certificate, kSecOIDX509V1IssuerName); - - CFDataRef data = SecCertificateCopyData(certificate); - if (data == NULL) - { - warnx("SecCertificateCopyData() returned NULL"); - destroyCertData(pCertData); - return NULL; - } - - unsigned char sha1[CC_SHA1_DIGEST_LENGTH]; - CC_SHA1(CFDataGetBytePtr(data), CFDataGetLength(data), sha1); - pCertData->sha1 = createHexString(sha1, CC_SHA1_DIGEST_LENGTH); - - unsigned char md5[CC_MD5_DIGEST_LENGTH]; - CC_MD5(CFDataGetBytePtr(data), CFDataGetLength(data), md5); - pCertData->md5 = createHexString((unsigned char *)md5, CC_MD5_DIGEST_LENGTH); - - CFDataRef serial = SecCertificateCopySerialNumber(certificate, NULL); - pCertData->serial = createHexString((unsigned char *)CFDataGetBytePtr(serial), CFDataGetLength(serial)); - CFRelease(serial); - - return pCertData; -} - -CFStringRef -stringFromRange(const char *cstring, CFRange range) -{ - CFStringRef str = CFStringCreateWithBytes(NULL, (uint8 *)&cstring[range.location], range.length, kCFStringEncodingUTF8, false); - CFMutableStringRef mutableStr = CFStringCreateMutableCopy(NULL, 0, str); - CFStringTrimWhitespace(mutableStr); - CFRelease(str); - return mutableStr; -} - -DescDataRef -createDescData(const char *description, CFRange nameRange, CFRange valueRange) -{ - DescDataRef pRetVal = (DescDataRef)malloc(sizeof(DescData)); - - memset(pRetVal, 0, sizeof(DescData)); - - if (nameRange.length > 0) - { - pRetVal->name = stringFromRange(description, nameRange); - } - - if (valueRange.length > 0) - { - pRetVal->value = stringFromRange(description, valueRange); - } - -#if 0 - fprintf(stderr, "name = '%s', value = '%s'\n", - CFStringGetCStringPtr(pRetVal->name, kCFStringEncodingUTF8), - CFStringGetCStringPtr(pRetVal->value, kCFStringEncodingUTF8)); -#endif - return pRetVal; -} - -void -destroyDescData(DescDataRef pData) -{ - if (pData->name) - { - CFRelease(pData->name); - } - - if (pData->value) - { - CFRelease(pData->value); - } - - free(pData); -} - -CFArrayRef -createDescDataPairs(const char *description) -{ - int numChars = strlen(description); - CFRange nameRange, valueRange; - DescDataRef pData; - CFMutableArrayRef retVal = CFArrayCreateMutable(NULL, 0, NULL); - - int i = 0; - - nameRange = CFRangeMake(0, 0); - valueRange = CFRangeMake(0, 0); - bool bInValue = false; - - while (i < numChars) - { - if (!bInValue && (description[i] != ':')) - { - nameRange.length++; - } - else if (bInValue && (description[i] != ':')) - { - valueRange.length++; - } - else if (!bInValue) - { - bInValue = true; - valueRange.location = i + 1; - valueRange.length = 0; - } - else /*(bInValue) */ - { - bInValue = false; - while (description[i] != ' ') - { - valueRange.length--; - i--; - } - - pData = createDescData(description, nameRange, valueRange); - CFArrayAppendValue(retVal, pData); - - nameRange.location = i + 1; - nameRange.length = 0; - } - - i++; - } - - pData = createDescData(description, nameRange, valueRange); - CFArrayAppendValue(retVal, pData); - return retVal; -} - -void -arrayDestroyDescData(const void *val, void *context) -{ - DescDataRef pData = (DescDataRef) val; - destroyDescData(pData); -} - - -int -parseNameComponent(CFStringRef dn, CFStringRef *pName, CFStringRef *pValue) -{ - CFArrayRef nameStrings = CFStringCreateArrayBySeparatingStrings(NULL, dn, kCertNameEquals); - - *pName = *pValue = NULL; - - if (CFArrayGetCount(nameStrings) != 2) - { - return 0; - } - - CFMutableStringRef str; - - str = CFStringCreateMutableCopy(NULL, 0, CFArrayGetValueAtIndex(nameStrings, 0)); - CFStringTrimWhitespace(str); - *pName = str; - - str = CFStringCreateMutableCopy(NULL, 0, CFArrayGetValueAtIndex(nameStrings, 1)); - CFStringTrimWhitespace(str); - *pValue = str; - - CFRelease(nameStrings); - return 1; -} - -int -tryAppendSingleCertField(CertNameRef pCertName, CFArrayRef where, CFStringRef key, - CFStringRef name, CFStringRef value) -{ - if (CFStringCompareWithOptions(name, key, CFRangeMake(0, CFStringGetLength(name)), kCFCompareCaseInsensitive) - == kCFCompareEqualTo) - { - CFArrayAppendValue((CFMutableArrayRef)where, value); - return 1; - } - return 0; -} - -int -appendCertField(CertNameRef pCert, CFStringRef name, CFStringRef value) -{ - struct { - CFArrayRef field; - CFStringRef key; - } fields[] = { - { pCert->organization, kCertNameOrganization}, - { pCert->organizationalUnit, kCertNameOrganizationalUnit}, - { pCert->countryName, kCertNameCountry}, - { pCert->localityName, kCertNameLocality}, - { pCert->stateName, kCertNameState}, - { pCert->commonName, kCertNameCommonName}, - { pCert->emailAddress, kCertNameEmail}, - }; - int i; - int ret = 0; - - for (i = 0; i<sizeof(fields)/sizeof(fields[0]); i++) - ret += tryAppendSingleCertField(pCert, fields[i].field, fields[i].key, name, value); - return ret; -} - -int -parseCertName(CFStringRef nameDesc, CFMutableArrayRef names) -{ - CFArrayRef nameStrings = CFStringCreateArrayBySeparatingStrings(NULL, nameDesc, kCertNameFwdSlash); - int count = CFArrayGetCount(nameStrings); - int i; - int ret = 1; - - CertNameRef pCertName = createCertName(); - - for (i = 0; i < count; i++) - { - CFMutableStringRef dn = CFStringCreateMutableCopy(NULL, 0, CFArrayGetValueAtIndex(nameStrings, i)); - CFStringTrimWhitespace(dn); - - CFStringRef name, value; - - if (!parseNameComponent(dn, &name, &value)) - { - ret = 0; - } - - if (!name || !value) - { - if (name) - { - CFRelease(name); - } - - if (value) - { - CFRelease(value); - } - if (name && !value) - { - ret = 0; - } - - CFRelease(dn); - continue; - } - - if (!appendCertField(pCertName, name, value)) - { - ret = 0; - } - CFRelease(name); - CFRelease(value); - CFRelease(dn); - } - - CFArrayAppendValue(names, pCertName); - CFRelease(nameStrings); - return ret; -} - -int -arrayParseDescDataPair(const void *val, void *context) -{ - DescDataRef pDescData = (DescDataRef)val; - CertDataRef pCertData = (CertDataRef)context; - int ret = 1; - - if (!pDescData->name || !pDescData->value) - { - return 0; - } - - if (CFStringCompareWithOptions(pDescData->name, kCertDataSubjectName, CFRangeMake(0, CFStringGetLength(pDescData->name)), kCFCompareCaseInsensitive) == kCFCompareEqualTo) - { - ret = parseCertName(pDescData->value, (CFMutableArrayRef)pCertData->subject); - } - else if (CFStringCompareWithOptions(pDescData->name, kCertDataIssuerName, CFRangeMake(0, CFStringGetLength(pDescData->name)), kCFCompareCaseInsensitive) == kCFCompareEqualTo) - { - ret = parseCertName(pDescData->value, (CFMutableArrayRef)pCertData->issuer); - } - else if (CFStringCompareWithOptions(pDescData->name, kCertDataSha1Name, CFRangeMake(0, CFStringGetLength(pDescData->name)), kCFCompareCaseInsensitive) == kCFCompareEqualTo) - { - pCertData->sha1 = CFRetain(pDescData->value); - } - else if (CFStringCompareWithOptions(pDescData->name, kCertDataMd5Name, CFRangeMake(0, CFStringGetLength(pDescData->name)), kCFCompareCaseInsensitive) == kCFCompareEqualTo) - { - pCertData->md5 = CFRetain(pDescData->value); - } - else if (CFStringCompareWithOptions(pDescData->name, kCertDataSerialName, CFRangeMake(0, CFStringGetLength(pDescData->name)), kCFCompareCaseInsensitive) == kCFCompareEqualTo) - { - pCertData->serial = CFRetain(pDescData->value); - } - else - { - return 0; - } - - return ret; -} - -CertDataRef -createCertDataFromString(const char *description) -{ - CertDataRef pCertData = (CertDataRef)malloc(sizeof(CertData)); - pCertData->subject = CFArrayCreateMutable(NULL, 0, NULL); - pCertData->issuer = CFArrayCreateMutable(NULL, 0, NULL); - pCertData->sha1 = NULL; - pCertData->md5 = NULL; - pCertData->serial = NULL; - - CFArrayRef pairs = createDescDataPairs(description); - for (int i = 0; i<CFArrayGetCount(pairs); i++) - if (!arrayParseDescDataPair(CFArrayGetValueAtIndex(pairs, i), pCertData)) - { - arrayDestroyDescData(pCertData, NULL); - CFArrayApplyFunction(pairs, CFRangeMake(0, CFArrayGetCount(pairs)), arrayDestroyDescData, NULL); - CFRelease(pairs); - return 0; - } - - CFArrayApplyFunction(pairs, CFRangeMake(0, CFArrayGetCount(pairs)), arrayDestroyDescData, NULL); - CFRelease(pairs); - return pCertData; -} - -void -arrayDestroyCertName(const void *val, void *context) -{ - CertNameRef pCertName = (CertNameRef)val; - destroyCertName(pCertName); -} - -void -destroyCertData(CertDataRef pCertData) -{ - if (pCertData->subject) - { - CFArrayApplyFunction(pCertData->subject, CFRangeMake(0, CFArrayGetCount(pCertData->subject)), arrayDestroyCertName, NULL); - CFRelease(pCertData->subject); - } - - if (pCertData->issuer) - { - CFArrayApplyFunction(pCertData->issuer, CFRangeMake(0, CFArrayGetCount(pCertData->issuer)), arrayDestroyCertName, NULL); - CFRelease(pCertData->issuer); - } - - if (pCertData->sha1) - { - CFRelease(pCertData->sha1); - } - - if (pCertData->md5) - { - CFRelease(pCertData->md5); - } - - if (pCertData->serial) - { - CFRelease(pCertData->serial); - } - - free(pCertData); -} - -bool -stringArrayMatchesTemplate(CFArrayRef strings, CFArrayRef templateArray) -{ - int templateCount, stringCount, i; - - templateCount = CFArrayGetCount(templateArray); - - if (templateCount > 0) - { - stringCount = CFArrayGetCount(strings); - if (stringCount != templateCount) - { - return false; - } - - for (i = 0; i < stringCount; i++) - { - CFStringRef str, template; - - template = (CFStringRef)CFArrayGetValueAtIndex(templateArray, i); - str = (CFStringRef)CFArrayGetValueAtIndex(strings, i); - - if (CFStringCompareWithOptions(template, str, CFRangeMake(0, CFStringGetLength(template)), kCFCompareCaseInsensitive) != kCFCompareEqualTo) - { - return false; - } - } - } - - return true; - -} - -bool -certNameMatchesTemplate(CertNameRef pCertName, CertNameRef pTemplate) -{ - if (!stringArrayMatchesTemplate(pCertName->countryName, pTemplate->countryName)) - { - return false; - } - else if (!stringArrayMatchesTemplate(pCertName->organization, pTemplate->organization)) - { - return false; - } - else if (!stringArrayMatchesTemplate(pCertName->organizationalUnit, pTemplate->organizationalUnit)) - { - return false; - } - else if (!stringArrayMatchesTemplate(pCertName->commonName, pTemplate->commonName)) - { - return false; - } - else if (!stringArrayMatchesTemplate(pCertName->emailAddress, pTemplate->emailAddress)) - { - return false; - } - else if (!stringArrayMatchesTemplate(pCertName->stateName, pTemplate->stateName)) - { - return false; - } - else if (!stringArrayMatchesTemplate(pCertName->localityName, pTemplate->localityName)) - { - return false; - } - else - { - return true; - } -} - -bool -certNameArrayMatchesTemplate(CFArrayRef certNameArray, CFArrayRef templateArray) -{ - int templateCount, certCount, i; - - templateCount = CFArrayGetCount(templateArray); - - if (templateCount > 0) - { - certCount = CFArrayGetCount(certNameArray); - if (certCount != templateCount) - { - return false; - } - - for (i = 0; i < certCount; i++) - { - CertNameRef pName, pTemplateName; - - pTemplateName = (CertNameRef)CFArrayGetValueAtIndex(templateArray, i); - pName = (CertNameRef)CFArrayGetValueAtIndex(certNameArray, i); - - if (!certNameMatchesTemplate(pName, pTemplateName)) - { - return false; - } - } - } - - return true; -} - -bool -hexStringMatchesTemplate(CFStringRef str, CFStringRef template) -{ - if (template) - { - if (!str) - { - return false; - } - - CFMutableStringRef strMutable, templateMutable; - - strMutable = CFStringCreateMutableCopy(NULL, 0, str); - templateMutable = CFStringCreateMutableCopy(NULL, 0, template); - - CFStringFindAndReplace(strMutable, kStringSpace, kStringEmpty, CFRangeMake(0, CFStringGetLength(strMutable)), 0); - CFStringFindAndReplace(templateMutable, kStringSpace, kStringEmpty, CFRangeMake(0, CFStringGetLength(templateMutable)), 0); - - CFComparisonResult result = CFStringCompareWithOptions(templateMutable, strMutable, CFRangeMake(0, CFStringGetLength(templateMutable)), kCFCompareCaseInsensitive); - - CFRelease(strMutable); - CFRelease(templateMutable); - - if (result != kCFCompareEqualTo) - { - return false; - } - } - - return true; -} - -bool -certDataMatchesTemplate(CertDataRef pCertData, CertDataRef pTemplate) -{ - if (!certNameArrayMatchesTemplate(pCertData->subject, pTemplate->subject)) - { - return false; - } - - if (!certNameArrayMatchesTemplate(pCertData->issuer, pTemplate->issuer)) - { - return false; - } - - if (!hexStringMatchesTemplate(pCertData->sha1, pTemplate->sha1)) - { - return false; - } - - if (!hexStringMatchesTemplate(pCertData->md5, pTemplate->md5)) - { - return false; - } - - if (!hexStringMatchesTemplate(pCertData->serial, pTemplate->serial)) - { - return false; - } - - return true; -} - -bool -certExpired(SecCertificateRef certificate) -{ - bool result; - CFDateRef notAfter = GetDateFieldFromCertificate(certificate, kSecOIDX509V1ValidityNotAfter); - CFDateRef notBefore = GetDateFieldFromCertificate(certificate, kSecOIDX509V1ValidityNotBefore); - CFDateRef now = CFDateCreate(kCFAllocatorDefault, CFAbsoluteTimeGetCurrent()); - - if (!notAfter || !notBefore || !now) - { - warnx("GetDateFieldFromCertificate() returned NULL"); - result = true; - } - else - { - if (CFDateCompare(notBefore, now, NULL) != kCFCompareLessThan - || CFDateCompare(now, notAfter, NULL) != kCFCompareLessThan) - { - result = true; - } - else - { - result = false; - } - } - - CFRelease(notAfter); - CFRelease(notBefore); - CFRelease(now); - return result; -} - -SecIdentityRef -findIdentity(CertDataRef pCertDataTemplate) -{ - const void *keys[] = { - kSecClass, - kSecReturnRef, - kSecMatchLimit - }; - const void *values[] = { - kSecClassIdentity, - kCFBooleanTrue, - kSecMatchLimitAll - }; - CFArrayRef result = NULL; - - CFDictionaryRef query = CFDictionaryCreate(NULL, keys, values, - sizeof(keys) / sizeof(*keys), - &kCFTypeDictionaryKeyCallBacks, - &kCFTypeDictionaryValueCallBacks); - OSStatus status = SecItemCopyMatching(query, (CFTypeRef *)&result); - CFRelease(query); - if (status != noErr) - { - warnx("No identities in keychain found"); - return NULL; - } - - SecIdentityRef bestIdentity = NULL; - CFDateRef bestNotBeforeDate = NULL; - - for (int i = 0; i<CFArrayGetCount(result); i++) - { - SecIdentityRef identity = (SecIdentityRef)CFArrayGetValueAtIndex(result, i); - if (identity == NULL) - { - warnx("identity == NULL"); - continue; - } - - SecCertificateRef certificate = NULL; - SecIdentityCopyCertificate(identity, &certificate); - if (certificate == NULL) - { - warnx("SecIdentityCopyCertificate() returned NULL"); - continue; - } - - CertDataRef pCertData2 = createCertDataFromCertificate(certificate); - if (pCertData2 == NULL) - { - warnx("createCertDataFromCertificate() returned NULL"); - goto release_cert; - } - bool bMatches = certDataMatchesTemplate(pCertData2, pCertDataTemplate); - bool bExpired = certExpired(certificate); - destroyCertData(pCertData2); - - if (bMatches && !bExpired) - { - CFDateRef notBeforeDate = GetDateFieldFromCertificate(certificate, kSecOIDX509V1ValidityNotBefore); - if (!notBeforeDate) - { - warnx("GetDateFieldFromCertificate() returned NULL"); - goto release_cert; - } - if (bestIdentity == NULL) - { - CFRetain(identity); - bestIdentity = identity; - - bestNotBeforeDate = notBeforeDate; - CFRetain(notBeforeDate); - } - else if (CFDateCompare(bestNotBeforeDate, notBeforeDate, NULL) == kCFCompareLessThan) - { - CFRelease(bestIdentity); - CFRetain(identity); - bestIdentity = identity; - - bestNotBeforeDate = notBeforeDate; - CFRetain(notBeforeDate); - } - CFRelease(notBeforeDate); - } -release_cert: - CFRelease(certificate); - } - CFRelease(result); - - return bestIdentity; -} diff --git a/contrib/keychain-mcd/cert_data.h b/contrib/keychain-mcd/cert_data.h deleted file mode 100644 index c01251f..0000000 --- a/contrib/keychain-mcd/cert_data.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * OpenVPN -- An application to securely tunnel IP networks - * over a single UDP port, with support for SSL/TLS-based - * session authentication and key exchange, - * packet encryption, packet authentication, and - * packet compression. - * - * Copyright (C) 2010 Brian Raderman <brian@irregularexpression.org> - * Copyright (C) 2013-2015 Vasily Kulikov <segoon@openwall.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ -#ifndef __cert_data_h__ -#define __cert_data_h__ - -#include <CoreFoundation/CoreFoundation.h> -#include <Security/Security.h> - -typedef struct _CertData -{ - CFArrayRef subject; - CFArrayRef issuer; - CFStringRef serial; - CFStringRef md5, sha1; -} CertData, *CertDataRef; - -CertDataRef createCertDataFromCertificate(SecCertificateRef certificate); - -CertDataRef createCertDataFromString(const char *description); - -void destroyCertData(CertDataRef pCertData); - -bool certDataMatchesTemplate(CertDataRef pCertData, CertDataRef pTemplate); - -void printCertData(CertDataRef pCertData); - -SecIdentityRef findIdentity(CertDataRef pCertDataTemplate); - -#endif /* ifndef __cert_data_h__ */ diff --git a/contrib/keychain-mcd/common_osx.c b/contrib/keychain-mcd/common_osx.c deleted file mode 100644 index f817814..0000000 --- a/contrib/keychain-mcd/common_osx.c +++ /dev/null @@ -1,100 +0,0 @@ -/* - * OpenVPN -- An application to securely tunnel IP networks - * over a single UDP port, with support for SSL/TLS-based - * session authentication and key exchange, - * packet encryption, packet authentication, and - * packet compression. - * - * Copyright (C) 2010 Brian Raderman <brian@irregularexpression.org> - * Copyright (C) 2013-2015 Vasily Kulikov <segoon@openwall.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -/* - #include "config.h" - #include "syshead.h" - #include "common.h" - #include "buffer.h" - #include "error.h" - */ - -#include "common_osx.h" -#include <err.h> - -void -printCFString(CFStringRef str) -{ - CFIndex bufferLength = CFStringGetLength(str) + 1; - char *pBuffer = (char *)malloc(sizeof(char) * bufferLength); - CFStringGetCString(str, pBuffer, bufferLength, kCFStringEncodingUTF8); - warnx("%s\n", pBuffer); - free(pBuffer); -} - -char * -cfstringToCstr(CFStringRef str) -{ - CFIndex bufferLength = CFStringGetLength(str) + 1; - char *pBuffer = (char *)malloc(sizeof(char) * bufferLength); - CFStringGetCString(str, pBuffer, bufferLength, kCFStringEncodingUTF8); - return pBuffer; -} - -void -appendHexChar(CFMutableStringRef str, unsigned char halfByte) -{ - if (halfByte < 10) - { - CFStringAppendFormat(str, NULL, CFSTR("%d"), halfByte); - } - else - { - char tmp[2] = {'A'+halfByte-10, 0}; - CFStringAppendCString(str, tmp, kCFStringEncodingUTF8); - } -} - -CFStringRef -createHexString(unsigned char *pData, int length) -{ - unsigned char byte, low, high; - int i; - CFMutableStringRef str = CFStringCreateMutable(NULL, 0); - - for (i = 0; i < length; i++) - { - byte = pData[i]; - low = byte & 0x0F; - high = (byte >> 4); - - appendHexChar(str, high); - appendHexChar(str, low); - - if (i != (length - 1)) - { - CFStringAppendCString(str, " ", kCFStringEncodingUTF8); - } - } - - return str; -} - -void -printHex(unsigned char *pData, int length) -{ - CFStringRef hexStr = createHexString(pData, length); - printCFString(hexStr); - CFRelease(hexStr); -} diff --git a/contrib/keychain-mcd/common_osx.h b/contrib/keychain-mcd/common_osx.h deleted file mode 100644 index d37e059..0000000 --- a/contrib/keychain-mcd/common_osx.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * OpenVPN -- An application to securely tunnel IP networks - * over a single UDP port, with support for SSL/TLS-based - * session authentication and key exchange, - * packet encryption, packet authentication, and - * packet compression. - * - * Copyright (C) 2010 Brian Raderman <brian@irregularexpression.org> - * Copyright (C) 2013-2015 Vasily Kulikov <segoon@openwall.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifndef __common_osx_h__ -#define __common_osx_h__ - -#include <CoreFoundation/CoreFoundation.h> - -void printCFString(CFStringRef str); - -char *cfstringToCstr(CFStringRef str); - -CFStringRef createHexString(unsigned char *pData, int length); - -void printHex(unsigned char *pData, int length); - -#endif /*__Common_osx_h__ */ diff --git a/contrib/keychain-mcd/crypto_osx.c b/contrib/keychain-mcd/crypto_osx.c deleted file mode 100644 index 27ac4f5..0000000 --- a/contrib/keychain-mcd/crypto_osx.c +++ /dev/null @@ -1,79 +0,0 @@ -/* - * OpenVPN -- An application to securely tunnel IP networks - * over a single UDP port, with support for SSL/TLS-based - * session authentication and key exchange, - * packet encryption, packet authentication, and - * packet compression. - * - * Copyright (C) 2010 Brian Raderman <brian@irregularexpression.org> - * Copyright (C) 2013-2015 Vasily Kulikov <segoon@openwall.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include <CommonCrypto/CommonDigest.h> -#include <Security/SecKey.h> -#include <Security/Security.h> - -#include "crypto_osx.h" -#include <err.h> - -void -printErrorMsg(const char *func, CFErrorRef error) -{ - CFStringRef desc = CFErrorCopyDescription(error); - warnx("%s failed: %s", func, CFStringGetCStringPtr(desc, kCFStringEncodingUTF8)); - CFRelease(desc); -} - -void -printErrorStatusMsg(const char *func, OSStatus status) -{ - CFStringRef error; - error = SecCopyErrorMessageString(status, NULL); - if (error) - { - warnx("%s failed: %s", func, CFStringGetCStringPtr(error, kCFStringEncodingUTF8)); - CFRelease(error); - } - else - { - warnx("%s failed: %X", func, (int)status); - } -} - -void -signData(SecIdentityRef identity, const uint8_t *from, int flen, uint8_t *to, size_t *tlen) -{ - SecKeyRef privateKey = NULL; - OSStatus status; - - status = SecIdentityCopyPrivateKey(identity, &privateKey); - if (status != noErr) - { - printErrorStatusMsg("signData: SecIdentityCopyPrivateKey", status); - *tlen = 0; - return; - } - - status = SecKeyRawSign(privateKey, kSecPaddingPKCS1, from, flen, to, tlen); - CFRelease(privateKey); - if (status != noErr) - { - printErrorStatusMsg("signData: SecKeyRawSign", status); - *tlen = 0; - return; - } -} diff --git a/contrib/keychain-mcd/crypto_osx.h b/contrib/keychain-mcd/crypto_osx.h deleted file mode 100644 index 9f4b3f9..0000000 --- a/contrib/keychain-mcd/crypto_osx.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * OpenVPN -- An application to securely tunnel IP networks - * over a single UDP port, with support for SSL/TLS-based - * session authentication and key exchange, - * packet encryption, packet authentication, and - * packet compression. - * - * Copyright (C) 2010 Brian Raderman <brian@irregularexpression.org> - * Copyright (C) 2013-2015 Vasily Kulikov <segoon@openwall.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifndef __crypto_osx_h__ -#define __crypto_osx_h__ - -#include <CoreFoundation/CoreFoundation.h> -#include <Security/Security.h> - -extern OSStatus SecKeyRawSign( - SecKeyRef key, - SecPadding padding, - const uint8_t *dataToSign, - size_t dataToSignLen, - uint8_t *sig, - size_t *sigLen - ); - -void signData(SecIdentityRef identity, const uint8_t *from, int flen, uint8_t *to, size_t *tlen); - -void printErrorMsg(const char *func, CFErrorRef error); - -#endif /*__crypto_osx_h__ */ diff --git a/contrib/keychain-mcd/keychain-mcd.8 b/contrib/keychain-mcd/keychain-mcd.8 deleted file mode 100644 index 676b164..0000000 --- a/contrib/keychain-mcd/keychain-mcd.8 +++ /dev/null @@ -1,161 +0,0 @@ -.TH keychain-mcd 8 -.SH NAME - -keychain-mcd \- Mac OS X Keychain management daemon for OpenVPN - -.SH SYNOPSIS - -.B keychain-mcd -.I identity-template management-server-ip management-server-port -[ -.I password-file -] - -.SH DESCRIPTION - -.B keychain-mcd -is Mac OS X Keychain management daemon for OpenVPN. -It loads the certificate and private key from the Mac OSX Keychain (Mac OSX Only). -.B keychain-mcd -connects to OpenVPN via management interface and handles -certificate and private key commands (namely -.B NEED-CERTIFICATE -and -.B RSA-SIGN -commands). - -.B keychain-mcd -makes it possible to use any smart card supported by Mac OSX using the tokend interface, but also any -kind of certificate, residing in the Keychain, where you have access to -the private key. This option has been tested on the client side with an Aladdin eToken -on Mac OSX Leopard and with software certificates stored in the Keychain on Mac OS X. - -Note that Mac OS X might need to present the user with an authentication GUI when the Keychain -is accessed by keychain-mcd. - -Use -.B keychain-mcd -along with -.B --management-external-key -and/or -.B --management-external-cert -passed to -.B openvpn. - -.SH OPTIONS - -.TP -.BR identity-template - -A select string which is used to choose a keychain identity from -Mac OS X Keychain or -.I auto -if the identity template is passed from openvpn. - -\fBSubject\fR, \fBIssuer\fR, \fBSerial\fR, \fBSHA1\fR, \fBMD5\fR selectors can be used. - -To select a certificate based on a string search in the -certificate's subject and/or issuer: - -.nf - -"SUBJECT:c=US/o=Apple Inc./ou=me.com/cn=username ISSUER:c=US/o=Apple Computer, Inc./ou=Apple Computer Certificate Authority/cn=Apple .Mac Certificate Authority" - -.fi - -.I "Distinguished Name Component Abbreviations:" -.br -o = organization -.br -ou = organizational unit -.br -c = country -.br -l = locality -.br -st = state -.br -cn = common name -.br -e = email -.br - -All of the distinguished name components are optional, although you do need to specify at least one of them. You can -add spaces around the '/' and '=' characters, e.g. "SUBJECT: c = US / o = Apple Inc.". You do not need to specify -both the subject and the issuer, one or the other will work fine. -The identity searching algorithm will return the -certificate it finds that matches all of the criteria you have specified. -If there are several certificates matching all of the criteria then the youngest certificate is returned -(i.e. with the greater "not before" validity field). -You can also include the MD5 and/or SHA1 thumbprints and/or serial number -along with the subject and issuer. - -To select a certificate based on certificate's MD5 or SHA1 thumbprint: - -.nf -"SHA1: 30 F7 3A 7A B7 73 2A 98 54 33 4A A7 00 6F 6E AC EC D1 EF 02" - -"MD5: D5 F5 11 F1 38 EB 5F 4D CF 23 B6 94 E8 33 D8 B5" -.fi - -Again, you can include both the SHA1 and the MD5 thumbprints, but you can also use just one of them. -The thumbprint hex strings can easily be copy-and-pasted from the OSX Keychain Access GUI in the Applications/Utilities folder. -The hex string comparison is not case sensitive. - -To select a certificate based on certificate's serial number: - -"Serial: 3E 9B 6F 02 00 00 00 01 1F 20" - -If -.BR identity-template -equals to -.I auto -then the actual identity template is -obtained from argument of NEED-CERTIFICATE notification of openvpn. -In this case the argument of NEED-CERTIFICATE must begin with 'macosx-keychain:' prefix -and the rest of it must contain the actual identity template in the format described above. - - -.TP -.BR management-server-ip -OpenVPN management IP to connect to. -Both IPv4 and IPv6 addresses can be used. - -.TP -.BR management-server-port -OpenVPN management port to connect to. -Use -.B unix -for -.I management-server-port -and socket path for -.I management-server-ip -to connect to a local unix socket. - -.TP -.BR password-file - -Password file containing the management password on first line. -The password will be used to connect to -.B openvpn -management interface. - -Pass -.I password-file -to -.B keychain-mcd -if -.I pw-file -was specified in -.B --management -option to -.B openvpn. - - -.SH AUTHOR - -Vasily Kulikov <segoon@openwall.com> - -.SH "SEE ALSO" - -.BR openvpn (8) diff --git a/contrib/keychain-mcd/main.c b/contrib/keychain-mcd/main.c deleted file mode 100644 index c1d091e..0000000 --- a/contrib/keychain-mcd/main.c +++ /dev/null @@ -1,310 +0,0 @@ -/* - * OpenVPN -- An application to securely tunnel IP networks - * over a single UDP port, with support for SSL/TLS-based - * session authentication and key exchange, - * packet encryption, packet authentication, and - * packet compression. - * - * Copyright (C) 2015 Vasily Kulikov <segoon@openwall.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <sys/un.h> -#include <err.h> -#include <netdb.h> - -#include <Security/Security.h> -#include <CoreServices/CoreServices.h> - -#include "cert_data.h" -#include "crypto_osx.h" -#include "../../src/openvpn/base64.h" - - -SecIdentityRef -template_to_identity(const char *template) -{ - SecIdentityRef identity; - CertDataRef pCertDataTemplate = createCertDataFromString(template); - if (pCertDataTemplate == NULL) - { - errx(1, "Bad certificate template"); - } - identity = findIdentity(pCertDataTemplate); - if (identity == NULL) - { - errx(1, "No such identify"); - } - fprintf(stderr, "Identity found\n"); - destroyCertData(pCertDataTemplate); - return identity; -} - -int -connect_to_management_server(const char *ip, const char *port) -{ - int fd; - struct sockaddr_un addr_un; - struct sockaddr *addr; - size_t addr_len; - - if (strcmp(port, "unix") == 0) - { - addr = (struct sockaddr *)&addr_un; - addr_len = sizeof(addr_un); - - addr_un.sun_family = AF_UNIX; - strncpy(addr_un.sun_path, ip, sizeof(addr_un.sun_path)); - fd = socket(AF_UNIX, SOCK_STREAM, 0); - } - else - { - int rv; - struct addrinfo *result; - struct addrinfo hints; - - memset(&hints, 0, sizeof(hints)); - hints.ai_family = AF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; - - rv = getaddrinfo(ip, port, &hints, &result); - if (rv < 0) - { - errx(1, "getaddrinfo: %s", gai_strerror(rv)); - } - if (result == NULL) - { - errx(1, "getaddrinfo returned 0 addressed"); - } - - /* Use the first found address */ - fd = socket(result->ai_family, result->ai_socktype, result->ai_protocol); - addr = result->ai_addr; - addr_len = result->ai_addrlen; - } - if (fd < 0) - { - err(1, "socket"); - } - - if (connect(fd, addr, addr_len) < 0) - { - err(1, "connect"); - } - - return fd; -} - -int -is_prefix(const char *s, const char *prefix) -{ - return strncmp(s, prefix, strlen(prefix)) == 0; -} - -void -handle_rsasign(FILE *man_file, SecIdentityRef identity, const char *input) -{ - const char *input_b64 = strchr(input, ':') + 1; - char *input_binary; - int input_len; - char *output_binary; - size_t output_len; - char *output_b64; - - input_len = strlen(input_b64)*8/6 + 4; - input_binary = malloc(input_len); - input_len = openvpn_base64_decode(input_b64, input_binary, input_len); - if (input_len < 0) - { - errx(1, "openvpn_base64_decode: overflow"); - } - - output_len = 1024; - output_binary = malloc(output_len); - signData(identity, (const uint8_t *)input_binary, input_len, (uint8_t *)output_binary, &output_len); - if (output_len == 0) - { - errx(1, "handle_rsasign: failed to sign data"); - } - - openvpn_base64_encode(output_binary, output_len, &output_b64); - fprintf(man_file, "rsa-sig\n%s\nEND\n", output_b64); - free(output_b64); - free(input_binary); - free(output_binary); - - fprintf(stderr, "Handled RSA_SIGN command\n"); -} - -void -handle_needcertificate(FILE *man_file, SecIdentityRef identity) -{ - OSStatus status; - SecCertificateRef certificate = NULL; - CFDataRef data; - const unsigned char *cert; - size_t cert_len; - char *result_b64, *tmp_b64; - - status = SecIdentityCopyCertificate(identity, &certificate); - if (status != noErr) - { - const char *msg = GetMacOSStatusErrorString(status); - err(1, "SecIdentityCopyCertificate() failed: %s", msg); - } - - data = SecCertificateCopyData(certificate); - if (data == NULL) - { - err(1, "SecCertificateCopyData() returned NULL"); - } - - cert = CFDataGetBytePtr(data); - cert_len = CFDataGetLength(data); - - openvpn_base64_encode(cert, cert_len, &result_b64); -#if 0 - fprintf(stderr, "certificate %s\n", result_b64); -#endif - - fprintf(man_file, "certificate\n"); - fprintf(man_file, "-----BEGIN CERTIFICATE-----\n"); - tmp_b64 = result_b64; - while (strlen(tmp_b64) > 64) { - fprintf(man_file, "%.64s\n", tmp_b64); - tmp_b64 += 64; - } - if (*tmp_b64) - { - fprintf(man_file, "%s\n", tmp_b64); - } - fprintf(man_file, "-----END CERTIFICATE-----\n"); - fprintf(man_file, "END\n"); - - free(result_b64); - CFRelease(data); - CFRelease(certificate); - - fprintf(stderr, "Handled NEED 'cert' command\n"); -} - -void -management_loop(SecIdentityRef identity, int man_fd, const char *password) -{ - char *buffer = NULL; - size_t buffer_len = 0; - FILE *man = fdopen(man_fd, "w+"); - if (man == 0) - { - err(1, "fdopen"); - } - - if (password) - { - fprintf(man, "%s\n", password); - } - - while (1) { - if (getline(&buffer, &buffer_len, man) < 0) - { - err(1, "getline"); - } -#if 0 - fprintf(stderr, "M: %s", buffer); -#endif - - if (is_prefix(buffer, ">RSA_SIGN:")) - { - handle_rsasign(man, identity, buffer); - } - if (is_prefix(buffer, ">NEED-CERTIFICATE")) - { - if (!identity) - { - const char prefix[] = ">NEED-CERTIFICATE:macosx-keychain:"; - if (!is_prefix(buffer, prefix)) - { - errx(1, "No identity template is passed via command line and " \ - "NEED-CERTIFICATE management interface command " \ - "misses 'macosx-keychain' prefix."); - } - identity = template_to_identity(buffer+strlen(prefix)); - } - handle_needcertificate(man, identity); - } - if (is_prefix(buffer, ">FATAL")) - { - fprintf(stderr, "Fatal message from OpenVPN: %s\n", buffer+7); - } - if (is_prefix(buffer, ">INFO")) - { - fprintf(stderr, "INFO message from OpenVPN: %s\n", buffer+6); - } - } -} - -char * -read_password(const char *fname) -{ - char *password = NULL; - FILE *pwf = fopen(fname, "r"); - size_t n = 0; - - if (pwf == NULL) - { - errx(1, "fopen(%s) failed", fname); - } - if (getline(&password, &n, pwf) < 0) - { - err(1, "getline"); - } - fclose(pwf); - return password; -} - -int -main(int argc, char *argv[]) -{ - if (argc < 4) - { - err(1, "usage: %s <identity_template> <management_ip> <management_port> [<pw-file>]", argv[0]); - } - - char *identity_template = argv[1]; - char *s_ip = argv[2]; - char *s_port = argv[3]; - char *password = NULL; - int man_fd; - - if (argc > 4) - { - char *s_pw_file = argv[4]; - password = read_password(s_pw_file); - } - - SecIdentityRef identity = NULL; - if (strcmp(identity_template, "auto")) - { - identity = template_to_identity(identity_template); - } - man_fd = connect_to_management_server(s_ip, s_port); - fprintf(stderr, "Successfully connected to openvpn\n"); - - management_loop(identity, man_fd, password); -} diff --git a/contrib/pull-resolv-conf/client.down b/contrib/pull-resolv-conf/client.down index 05f2d4d..0cbb476 100644 --- a/contrib/pull-resolv-conf/client.down +++ b/contrib/pull-resolv-conf/client.down @@ -1,6 +1,6 @@ #!/bin/sh -# Copyright (c) 2005-2010 OpenVPN Technologies, Inc. +# Copyright (c) 2005-2018 OpenVPN Inc # Licensed under the GPL version 2 # First version by Jesse Adelman @@ -30,6 +30,10 @@ # the client "up" script will run fine, but the "down" script # will require the use of the OpenVPN "down-root" plugin # which is in the plugins/ directory of the OpenVPN source tree +# The config example above would have to be changed to: +# client +# up /etc/openvpn/client.up +# plugin openvpn-plugin-down-root.so "/etc/openvpn/client.down" # A horrid work around, from a security perspective, # is to run OpenVPN as root. THIS IS NOT RECOMMENDED. You have @@ -37,7 +41,7 @@ PATH=/bin:/usr/bin:/usr/local/bin:/sbin:/usr/sbin:/usr/local/sbin if type resolvconf >/dev/null 2>&1; then - resolvconf -d "${1}" -f + resolvconf -d "${dev}" -f elif [ -e /etc/resolv.conf.ovpnsave ] ; then # cp + rm rather than mv in case it's a symlink cp /etc/resolv.conf.ovpnsave /etc/resolv.conf diff --git a/contrib/pull-resolv-conf/client.up b/contrib/pull-resolv-conf/client.up index 8858b47..f076974 100644 --- a/contrib/pull-resolv-conf/client.up +++ b/contrib/pull-resolv-conf/client.up @@ -1,6 +1,6 @@ #!/bin/sh -# Copyright (c) 2005-2010 OpenVPN Technologies, Inc. +# Copyright (c) 2005-2018 OpenVPN Inc # Licensed under the GPL version 2 # First version by Jesse Adelman @@ -87,11 +87,11 @@ elif [ $ndoms -gt 1 ]; then fi # This is the complete file - "$domains" has a leading space already -out="# resolv.conf autogenerated by ${0} (${1})${nl}${dns}${ds}${domains}" +out="# resolv.conf autogenerated by ${0} (${dev})${nl}${dns}${ds}${domains}" # use resolvconf if it's available if type resolvconf >/dev/null 2>&1; then - printf "%s\n" "${out}" | resolvconf -p -a "${1}" + printf "%s\n" "${out}" | resolvconf -p -a "${dev}" else # Preserve the existing resolv.conf if [ -e /etc/resolv.conf ] ; then diff --git a/distro/Makefile.am b/distro/Makefile.am index eb0e554..e2098c8 100644 --- a/distro/Makefile.am +++ b/distro/Makefile.am @@ -5,7 +5,7 @@ # packet encryption, packet authentication, and # packet compression. # -# Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> +# Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> # Copyright (C) 2006-2012 Alon Bar-Lev <alon.barlev@gmail.com> # diff --git a/distro/Makefile.in b/distro/Makefile.in index 8e47181..9736f3b 100644 --- a/distro/Makefile.in +++ b/distro/Makefile.in @@ -21,7 +21,7 @@ # packet encryption, packet authentication, and # packet compression. # -# Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> +# Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> # Copyright (C) 2006-2012 Alon Bar-Lev <alon.barlev@gmail.com> # VPATH = @srcdir@ @@ -365,6 +365,7 @@ plugindir = @plugindir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ +runstatedir = @runstatedir@ sampledir = @sampledir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ diff --git a/distro/rpm/Makefile.am b/distro/rpm/Makefile.am index 37ee099..d16a5ac 100644 --- a/distro/rpm/Makefile.am +++ b/distro/rpm/Makefile.am @@ -5,7 +5,7 @@ # packet encryption, packet authentication, and # packet compression. # -# Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> +# Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> # Copyright (C) 2006-2012 Alon Bar-Lev <alon.barlev@gmail.com> # diff --git a/distro/rpm/Makefile.in b/distro/rpm/Makefile.in index c2d3b44..66b5f7f 100644 --- a/distro/rpm/Makefile.in +++ b/distro/rpm/Makefile.in @@ -21,7 +21,7 @@ # packet encryption, packet authentication, and # packet compression. # -# Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> +# Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> # Copyright (C) 2006-2012 Alon Bar-Lev <alon.barlev@gmail.com> # @@ -308,6 +308,7 @@ plugindir = @plugindir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ +runstatedir = @runstatedir@ sampledir = @sampledir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ diff --git a/distro/rpm/openvpn.spec b/distro/rpm/openvpn.spec index fc57c02..08188b3 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.4.3 +Version: 2.4.5 Release: 1 URL: http://openvpn.net/ Source0: http://prdownloads.sourceforge.net/openvpn/%{name}-%{version}.tar.gz diff --git a/distro/systemd/Makefile.am b/distro/systemd/Makefile.am index 1e3f3ea..69e1269 100644 --- a/distro/systemd/Makefile.am +++ b/distro/systemd/Makefile.am @@ -5,7 +5,7 @@ # packet encryption, packet authentication, and # packet compression. # -# Copyright (C) 2017 OpenVPN Technologies, Inc. <sales@openvpn.net> +# Copyright (C) 2017-2018 OpenVPN Inc <sales@openvpn.net> # %.service: %.service.in Makefile @@ -23,6 +23,8 @@ systemdunit_DATA = \ openvpn-server@.service tmpfiles_DATA = \ tmpfiles-openvpn.conf +dist_doc_DATA = \ + README.systemd install-data-hook: mv $(DESTDIR)$(tmpfilesdir)/tmpfiles-openvpn.conf $(DESTDIR)$(tmpfilesdir)/openvpn.conf diff --git a/distro/systemd/Makefile.in b/distro/systemd/Makefile.in index 27b390e..8e641aa 100644 --- a/distro/systemd/Makefile.in +++ b/distro/systemd/Makefile.in @@ -21,7 +21,7 @@ # packet encryption, packet authentication, and # packet compression. # -# Copyright (C) 2017 OpenVPN Technologies, Inc. <sales@openvpn.net> +# Copyright (C) 2017-2018 OpenVPN Inc <sales@openvpn.net> # VPATH = @srcdir@ @@ -109,7 +109,8 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_emptyarray.m4 \ $(top_srcdir)/compat.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) -DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +DIST_COMMON = $(srcdir)/Makefile.am $(am__dist_doc_DATA_DIST) \ + $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/include/openvpn-plugin.h @@ -134,6 +135,7 @@ am__can_run_installinfo = \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac +am__dist_doc_DATA_DIST = README.systemd am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ @@ -161,9 +163,9 @@ am__uninstall_files_from_dir = { \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } -am__installdirs = "$(DESTDIR)$(systemdunitdir)" \ +am__installdirs = "$(DESTDIR)$(docdir)" "$(DESTDIR)$(systemdunitdir)" \ "$(DESTDIR)$(tmpfilesdir)" -DATA = $(systemdunit_DATA) $(tmpfiles_DATA) +DATA = $(dist_doc_DATA) $(systemdunit_DATA) $(tmpfiles_DATA) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) @@ -335,6 +337,7 @@ plugindir = @plugindir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ +runstatedir = @runstatedir@ sampledir = @sampledir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ @@ -358,6 +361,9 @@ EXTRA_DIST = \ @ENABLE_SYSTEMD_TRUE@tmpfiles_DATA = \ @ENABLE_SYSTEMD_TRUE@ tmpfiles-openvpn.conf +@ENABLE_SYSTEMD_TRUE@dist_doc_DATA = \ +@ENABLE_SYSTEMD_TRUE@ README.systemd + MAINTAINERCLEANFILES = \ $(srcdir)/Makefile.in @@ -399,6 +405,27 @@ mostlyclean-libtool: clean-libtool: -rm -rf .libs _libs +install-dist_docDATA: $(dist_doc_DATA) + @$(NORMAL_INSTALL) + @list='$(dist_doc_DATA)'; test -n "$(docdir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(docdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(docdir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(docdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(docdir)" || exit $$?; \ + done + +uninstall-dist_docDATA: + @$(NORMAL_UNINSTALL) + @list='$(dist_doc_DATA)'; test -n "$(docdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(docdir)'; $(am__uninstall_files_from_dir) install-systemdunitDATA: $(systemdunit_DATA) @$(NORMAL_INSTALL) @list='$(systemdunit_DATA)'; test -n "$(systemdunitdir)" || list=; \ @@ -482,7 +509,7 @@ check-am: all-am check: check-am all-am: Makefile $(DATA) installdirs: - for dir in "$(DESTDIR)$(systemdunitdir)" "$(DESTDIR)$(tmpfilesdir)"; do \ + for dir in "$(DESTDIR)$(docdir)" "$(DESTDIR)$(systemdunitdir)" "$(DESTDIR)$(tmpfilesdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am @@ -537,7 +564,8 @@ info: info-am info-am: -install-data-am: install-systemdunitDATA install-tmpfilesDATA +install-data-am: install-dist_docDATA install-systemdunitDATA \ + install-tmpfilesDATA @$(NORMAL_INSTALL) $(MAKE) $(AM_MAKEFLAGS) install-data-hook install-dvi: install-dvi-am @@ -582,7 +610,8 @@ ps: ps-am ps-am: -uninstall-am: uninstall-systemdunitDATA uninstall-tmpfilesDATA +uninstall-am: uninstall-dist_docDATA uninstall-systemdunitDATA \ + uninstall-tmpfilesDATA .MAKE: install-am install-data-am install-strip @@ -590,14 +619,15 @@ uninstall-am: uninstall-systemdunitDATA uninstall-tmpfilesDATA cscopelist-am ctags-am distclean distclean-generic \ distclean-libtool distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am \ - install-data-hook install-dvi install-dvi-am install-exec \ - install-exec-am install-html install-html-am install-info \ - install-info-am install-man install-pdf install-pdf-am \ - install-ps install-ps-am install-strip install-systemdunitDATA \ - install-tmpfilesDATA installcheck installcheck-am installdirs \ - maintainer-clean maintainer-clean-generic mostlyclean \ - mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ - tags-am uninstall uninstall-am uninstall-systemdunitDATA \ + install-data-hook install-dist_docDATA install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip install-systemdunitDATA install-tmpfilesDATA \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags-am uninstall \ + uninstall-am uninstall-dist_docDATA uninstall-systemdunitDATA \ uninstall-tmpfilesDATA .PRECIOUS: Makefile diff --git a/distro/systemd/README.systemd b/distro/systemd/README.systemd new file mode 100644 index 0000000..a193a87 --- /dev/null +++ b/distro/systemd/README.systemd @@ -0,0 +1,70 @@ +OpenVPN and systemd +=================== + +As of OpenVPN v2.4, upstream is shipping systemd unit files to provide a +fine grained control of each OpenVPN configuration as well as trying to +restrict the capabilities the OpenVPN process have on a system. + + +Configuration profile types +--------------------------- +These new unit files separates between client and server profiles. The +configuration files are kept in separate directories, to provide clarity +of the profile they run under. + +Typically the client profile cannot bind to any ports below port 1024 +and the client configuration is always started with --nobind. + +The server profile is allowed to bind to any ports. In addition it enables +a client status file, usually found in the /run/openvpn-server directory. +The status format is set to version 2 by default. These settings may be +overridden by adding --status and/or --status-version in the OpenVPN +configuration file. + +Neither of these profiles makes use of PID files, but OpenVPN reports back to +systemd its PID once it has initialized. + +For configuration using a peer-to-peer mode (not using --mode server on one +of the sides) it is recommended to use the client profile. + + +Configuration files +------------------- +These new unit files expects client configuration files to be made available +in /etc/openvpn/client. Similar for the server configurations, it is expected +to be found in /etc/openvpn/server. The configuration files must have a .conf +file extension. + + +Managing VPN tunnels +-------------------- +Use the normal systemctl tool to start, stop VPN tunnels, as well as enable +and disable tunnels at boot time. The syntax is: + + - client configurations: + # systemctl $OPER openvpn-client@$CONFIGNAME + + - server configurations: + # systemctl $OPER openvpn-server@$CONFIGNAME + +Similarly, to view the OpenVPN journal log use a similar syntax: + + # journalctl -u openvpn-client@$CONFIGNAME + or + # journalctl -u openvpn-server@$CONFIGNAME + +* Examples + Say your server configuration is /etc/openvpn/server/tun0.conf, you + start this VPN service like this: + + # systemctl start openvpn-server@tun0 + + A client configuration file in /etc/openvpn/client/corpvpn.conf is + started like this: + + # systemctl start openvpn-client@corpvpn + + To view the server configuration's journal only listing entries from + yesterday and until today: + + # journalctl --since yesterday -u openvpn-server@tun0 diff --git a/distro/systemd/openvpn-client@.service.in b/distro/systemd/openvpn-client@.service.in index 49e3f51..cbcef65 100644 --- a/distro/systemd/openvpn-client@.service.in +++ b/distro/systemd/openvpn-client@.service.in @@ -17,6 +17,7 @@ DeviceAllow=/dev/null rw DeviceAllow=/dev/net/tun rw ProtectSystem=true ProtectHome=true +KillMode=process [Install] WantedBy=multi-user.target diff --git a/distro/systemd/openvpn-server@.service.in b/distro/systemd/openvpn-server@.service.in index 9a8a2c7..a8366a0 100644 --- a/distro/systemd/openvpn-server@.service.in +++ b/distro/systemd/openvpn-server@.service.in @@ -17,6 +17,9 @@ DeviceAllow=/dev/null rw DeviceAllow=/dev/net/tun rw ProtectSystem=true ProtectHome=true +KillMode=process +RestartSec=5s +Restart=on-failure [Install] WantedBy=multi-user.target diff --git a/doc/Makefile.am b/doc/Makefile.am index dedd1fa..f3a24a7 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -5,7 +5,7 @@ # packet encryption, packet authentication, and # packet compression. # -# Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> +# Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> # Copyright (C) 2006-2012 Alon Bar-Lev <alon.barlev@gmail.com> # diff --git a/doc/Makefile.in b/doc/Makefile.in index fad3a11..4ac438e 100644 --- a/doc/Makefile.in +++ b/doc/Makefile.in @@ -21,7 +21,7 @@ # packet encryption, packet authentication, and # packet compression. # -# Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> +# Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> # Copyright (C) 2006-2012 Alon Bar-Lev <alon.barlev@gmail.com> # @@ -342,6 +342,7 @@ plugindir = @plugindir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ +runstatedir = @runstatedir@ sampledir = @sampledir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ diff --git a/doc/management-notes.txt b/doc/management-notes.txt index 29c3aad..908b981 100644 --- a/doc/management-notes.txt +++ b/doc/management-notes.txt @@ -317,6 +317,11 @@ COMMAND -- password and username >PASSWORD:Verification Failed: 'custom server-generated string' + Example 6: If server pushes --auth-token to the client, the OpenVPN + will produce a real-time PASSWORD message: + + >PASSWORD:Auth-Token:foobar + COMMAND -- forget-passwords --------------------------- @@ -357,6 +362,8 @@ ADD_ROUTES -- Adding routes to system. CONNECTED -- Initialization Sequence Completed. RECONNECTING -- A restart has occurred. EXITING -- A graceful exit is in progress. +RESOLVE -- (Client only) DNS lookup +TCP_CONNECT -- (Client only) Connecting to TCP server Command examples: @@ -420,7 +427,7 @@ info on verbosity levels. Command examples: verb 4 -- change the verb parameter to 4 - mute -- show the current verb setting + verb -- show the current verb setting COMMAND -- version ------------------ diff --git a/doc/openvpn.8 b/doc/openvpn.8 index 56c0f7a..f8627ab 100644 --- a/doc/openvpn.8 +++ b/doc/openvpn.8 @@ -4,7 +4,7 @@ .\" packet encryption, packet authentication, and .\" packet compression. .\" -.\" Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> +.\" Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> .\" .\" This program is free software; you can redistribute it and/or modify .\" it under the terms of the GNU General Public License version 2 @@ -33,7 +33,15 @@ .\" .ft -- normal face .\" .in +|-{n} -- indent .\" -.TH openvpn 8 "25 August 2016" +.\" Support macros - this is not present on all platforms +.\" Continuation line for .TP header. +.de TQ +. br +. ns +. TP \\$1\" no doublequotes around argument! +.. +.\" End of TQ macro +.TH openvpn 8 "28 February 2018" .\"********************************************************* .SH NAME openvpn \- secure IP tunnel daemon. @@ -77,14 +85,14 @@ of its crypto capabilities from it. OpenVPN supports conventional encryption -using a pre-shared secret key +using a pre\-shared secret key .B (Static Key mode) or public key security .B (SSL/TLS mode) using client & server certificates. OpenVPN also -supports non-encrypted TCP/UDP tunnels. +supports non\-encrypted TCP/UDP tunnels. OpenVPN is designed to work with the .B TUN/TAP @@ -96,7 +104,7 @@ with a relatively lightweight footprint. .SH OPTIONS OpenVPN allows any option to be placed either on the command line or in a configuration file. Though all command line options are preceded -by a double-leading-dash ("\-\-"), this prefix can be removed when +by a double\-leading\-dash ("\-\-"), this prefix can be removed when an option is placed in a configuration file. .\"********************************************************* .TP @@ -126,7 +134,7 @@ can be used to enclose single parameters containing whitespace, and "#" or ";" characters in the first column can be used to denote comments. -Note that OpenVPN 2.0 and higher performs backslash-based shell +Note that OpenVPN 2.0 and higher performs backslash\-based shell escaping for characters not in single quotations, so the following mappings should be observed: @@ -164,7 +172,7 @@ Here is an example configuration file: .in +4 # # Sample OpenVPN configuration file for -# using a pre-shared static key. +# using a pre\-shared static key. # # '#' or ';' may be used to delimit comments. @@ -178,7 +186,7 @@ remote mypeer.mydomain # 10.1.0.2 is our remote VPN endpoint ifconfig 10.1.0.1 10.1.0.2 -# Our pre-shared static key +# Our pre\-shared static key secret static.key .in -4 .ft @@ -188,8 +196,8 @@ secret static.key .TP .B \-\-mode m Set OpenVPN major mode. By default, OpenVPN runs in -point-to-point mode ("p2p"). OpenVPN 2.0 introduces -a new mode ("server") which implements a multi-client +point\-to\-point mode ("p2p"). OpenVPN 2.0 introduces +a new mode ("server") which implements a multi\-client server capability. .\"********************************************************* .TP @@ -206,7 +214,7 @@ options may be specified for redundancy, each referring to a different OpenVPN server. Specifying multiple .B \-\-remote options for this purpose is a special case of the more -general connection-profile feature. See the +general connection\-profile feature. See the .B <connection> documentation below. @@ -243,7 +251,7 @@ the client with .B \-\-user and/or .B \-\-group, -AND the client is running a non-Windows OS, if the client needs +AND the client is running a non\-Windows OS, if the client needs to switch to a different server, and that server pushes back different TUN/TAP or route settings, the client may lack the necessary privileges to close and reopen the TUN/TAP interface. @@ -277,7 +285,7 @@ and IPv6 addresses, in the order getaddrinfo() returns them. .B \-\-remote\-random\-hostname Prepend a random string (6 bytes, 12 hex characters) to hostname to prevent DNS caching. For example, "foo.bar.gov" would be modified to -"<random-chars>.foo.bar.gov". +"<random\-chars>.foo.bar.gov". .\"********************************************************* .TP .B <connection> @@ -404,7 +412,7 @@ When multiple .B \-\-remote address/ports are specified, or if connection profiles are being used, initially randomize the order of the list -as a kind of basic load-balancing measure. +as a kind of basic load\-balancing measure. .\"********************************************************* .TP .B \-\-proto p @@ -453,12 +461,12 @@ networks. This article outlines some of problems with tunneling IP over TCP: -.I http://sites.inka.de/sites/bigred/devel/tcp-tcp.html +.I http://sites.inka.de/sites/bigred/devel/tcp\-tcp.html There are certain cases, however, where using TCP may be advantageous from -a security and robustness perspective, such as tunneling non-IP or -application-level UDP protocols, or tunneling protocols which don't -possess a built-in reliability layer. +a security and robustness perspective, such as tunneling non\-IP or +application\-level UDP protocols, or tunneling protocols which don't +possess a built\-in reliability layer. .\"********************************************************* .TP .B \-\-connect\-retry n [max] @@ -489,12 +497,12 @@ Show sensed HTTP or SOCKS proxy settings. Currently, only Windows clients support this option. .\"********************************************************* .TP -.B \-\-http\-proxy server port [authfile|'auto'|'auto\-nct'] [auth-method] +.B \-\-http\-proxy server port [authfile|'auto'|'auto\-nct'] [auth\-method] Connect to remote host through an HTTP proxy at address .B server and port .B port. -If HTTP Proxy-Authenticate is required, +If HTTP Proxy\-Authenticate is required, .B authfile is a file containing a username and password on 2 lines, or "stdin" to prompt from console. Its content can also be specified @@ -522,7 +530,7 @@ exists on OpenVPN 2.1 or higher. The .B auto\-nct -flag (no clear-text auth) instructs OpenVPN to automatically +flag (no clear\-text auth) instructs OpenVPN to automatically determine the authentication method, but to reject weak authentication protocols such as HTTP Basic Authentication. .\"********************************************************* @@ -531,16 +539,16 @@ authentication protocols such as HTTP Basic Authentication. Set extended HTTP proxy options. Repeat to set multiple options. -.B VERSION version -- +.B VERSION version \-\- Set HTTP version number to .B version (default=1.0). -.B AGENT user-agent -- -Set HTTP "User-Agent" string to -.B user-agent. +.B AGENT user\-agent \-\- +Set HTTP "User\-Agent" string to +.B user\-agent. -.B CUSTOM\-HEADER name content -- +.B CUSTOM\-HEADER name content \-\- Adds the custom Header with .B name as name and @@ -588,7 +596,7 @@ at a known address, however if packets arrive from a new address and pass all authentication tests, the new address will take control of the session. This is useful when you are connecting to a peer which holds a dynamic address -such as a dial-in user or DHCP client. +such as a dial\-in user or DHCP client. Essentially, .B \-\-float @@ -601,12 +609,12 @@ option. .B \-\-ipchange cmd Run command .B cmd -when our remote ip-address is initially authenticated or +when our remote ip\-address is initially authenticated or changes. .B cmd consists of a path to script (or executable program), optionally -followed by arguments. The path and arguments may be single- or double-quoted +followed by arguments. The path and arguments may be single\- or double\-quoted and/or escaped using a backslash, and should be separated by one or more spaces. When @@ -656,7 +664,7 @@ and .B \-\-rport options to given port). The current default of 1194 represents the official IANA port number -assignment for OpenVPN and has been used since version 2.0-beta17. +assignment for OpenVPN and has been used since version 2.0\-beta17. Previous versions used port 5000 as the default. .\"********************************************************* .TP @@ -717,9 +725,9 @@ devices encapsulate IPv4 or IPv6 (OSI Layer 3) while devices encapsulate Ethernet 802.3 (OSI Layer 2). .\"********************************************************* .TP -.B \-\-dev\-type device-type +.B \-\-dev\-type device\-type Which device type are we using? -.B device-type +.B device\-type should be .B tun (OSI Layer 3) @@ -756,23 +764,24 @@ directive, this directive must always be compatible between client and server. can be one of: .B net30 \-\- -Use a point-to-point topology, by allocating one /30 subnet per client. -This is designed to allow point-to-point semantics when some +Use a point\-to\-point topology, by allocating one /30 subnet per client. +This is designed to allow point\-to\-point semantics when some or all of the connecting clients might be Windows systems. This is the default on OpenVPN 2.0. .B p2p \-\- -Use a point-to-point topology where the remote endpoint of the client's +Use a point\-to\-point topology where the remote endpoint of the client's tun interface always points to the local endpoint of the server's tun interface. This mode allocates a single IP address per connecting client. Only use when none of the connecting clients are Windows systems. This mode is functionally equivalent to the .B \-\-ifconfig\-pool\-linear -directive which is available in OpenVPN 2.0 and is now deprecated. +directive which is available in OpenVPN 2.0, is deprecated and will be +removed in OpenVPN 2.5 .B subnet \-\- -Use a subnet rather than a point-to-point topology by +Use a subnet rather than a point\-to\-point topology by configuring the tun interface with a local IP address and subnet mask, similar to the topology used in .B \-\-dev tap @@ -782,7 +791,7 @@ Windows as well. Only available when server and clients are OpenVPN 2.1 or higher, or OpenVPN 2.0.x which has been manually patched with the .B \-\-topology directive code. When used on Windows, requires version 8.2 or higher -of the TAP-Win32 driver. When used on *nix, requires that the tun +of the TAP\-Win32 driver. When used on *nix, requires that the tun driver supports an .BR ifconfig (8) command which sets a subnet instead of a remote endpoint IP address. @@ -818,7 +827,7 @@ When not specifying a .B \-\-dev\-node option openvpn will first try to open utun, and fall back to tun.kext. -On Windows systems, select the TAP-Win32 adapter which +On Windows systems, select the TAP\-Win32 adapter which is named .B node in the Network Connections Control Panel or the @@ -826,10 +835,10 @@ raw GUID of the adapter enclosed by braces. The .B \-\-show\-adapters option under Windows can also be used -to enumerate all available TAP-Win32 +to enumerate all available TAP\-Win32 adapters and will show both the network connections control panel name and the GUID for -each TAP-Win32 adapter. +each TAP\-Win32 adapter. .TP .B \-\-lladdr address Specify the link layer address, more commonly known as the MAC address. @@ -845,7 +854,7 @@ May be used in order to execute OpenVPN in unprivileged environment. Set TUN/TAP adapter parameters. .B l is the IP address of the local VPN endpoint. -For TUN devices in point-to-point mode, +For TUN devices in point\-to\-point mode, .B rn is the IP address of the remote VPN endpoint. For TAP devices, or TUN devices used with @@ -855,7 +864,7 @@ is the subnet mask of the virtual network segment which is being created or connected to. For TUN devices, which facilitate virtual -point-to-point IP connections (when used in +point\-to\-point IP connections (when used in .B \-\-topology net30 or .B p2p @@ -875,7 +884,7 @@ you will be pinging across the VPN. For TAP devices, which provide the ability to create virtual ethernet segments, or TUN devices in -.B --topology subnet +.B \-\-topology subnet mode (which create virtual "multipoint networks"), .B \-\-ifconfig is used to set an IP address and @@ -955,10 +964,10 @@ while at the same time providing portable semantics across OpenVPN's platform space. .B netmask -default -- 255.255.255.255 +default \-\- 255.255.255.255 .B gateway -default -- taken from +default \-\- taken from .B \-\-route\-gateway or the second parameter to .B \-\-ifconfig @@ -967,7 +976,7 @@ when is specified. .B metric -default -- taken from +default \-\- taken from .B \-\-route\-metric otherwise 0. @@ -983,7 +992,7 @@ also be specified as a DNS or /etc/hosts file resolvable name, or as one of three special keywords: .B vpn_gateway --- The remote VPN endpoint address +\-\- The remote VPN endpoint address (derived either from .B \-\-route\-gateway or the second parameter to @@ -993,11 +1002,11 @@ when is specified). .B net_gateway --- The pre-existing IP default gateway, read from the routing +\-\- The pre\-existing IP default gateway, read from the routing table (not supported on all OSes). .B remote_host --- The +\-\- The .B \-\-remote address if OpenVPN is being run in client mode, and is undefined in server mode. .\"********************************************************* @@ -1012,7 +1021,7 @@ If .B dhcp is specified as the parameter, the gateway address will be extracted from a DHCP -negotiation with the OpenVPN server-side LAN. +negotiation with the OpenVPN server\-side LAN. .\"********************************************************* .TP .B \-\-route\-metric m @@ -1052,7 +1061,7 @@ On Windows, tries to be more intelligent by waiting .B w seconds (w=30 by default) -for the TAP-Win32 adapter to come up before adding routes. +for the TAP\-Win32 adapter to come up before adding routes. .\"********************************************************* .TP .B \-\-route\-up cmd @@ -1063,7 +1072,7 @@ after routes are added, subject to .B cmd consists of a path to script (or executable program), optionally -followed by arguments. The path and arguments may be single- or double-quoted +followed by arguments. The path and arguments may be single\- or double\-quoted and/or escaped using a backslash, and should be separated by one or more spaces. See the "Environmental Variables" section below for @@ -1077,7 +1086,7 @@ before routes are removed upon disconnection. .B cmd consists of a path to script (or executable program), optionally -followed by arguments. The path and arguments may be single- or double-quoted +followed by arguments. The path and arguments may be single\- or double\-quoted and/or escaped using a backslash, and should be separated by one or more spaces. See the "Environmental Variables" section below for @@ -1095,7 +1104,7 @@ When used with .B \-\-client or .B \-\-pull, -accept options pushed by server EXCEPT for routes, block-outside-dns and dhcp +accept options pushed by server EXCEPT for routes, block\-outside\-dns and dhcp options like DNS servers. When used on the client, this option effectively bars the @@ -1114,7 +1123,7 @@ and .\"********************************************************* .TP .B \-\-client\-nat snat|dnat network netmask alias -This pushable client option sets up a stateless one-to-one NAT +This pushable client option sets up a stateless one\-to\-one NAT rule on packet addresses (not ports), and is useful in cases where routes or ifconfig settings pushed to the client would create an IP numbering conflict. @@ -1140,14 +1149,14 @@ addresses in packets. .TP .B \-\-redirect\-gateway flags... Automatically execute routing commands to cause all outgoing IP traffic -to be redirected over the VPN. This is a client-side option. +to be redirected over the VPN. This is a client\-side option. This option performs three steps: .B (1) Create a static route for the .B \-\-remote -address which forwards to the pre-existing default gateway. +address which forwards to the pre\-existing default gateway. This is done so that .B (3) will not create a routing loop. @@ -1184,39 +1193,39 @@ Try to automatically determine whether to enable .B local flag above. -.B def1 -- +.B def1 \-\- Use this flag to override the default gateway by using 0.0.0.0/1 and 128.0.0.0/1 rather than 0.0.0.0/0. This has the benefit of overriding but not wiping out the original default gateway. -.B bypass-dhcp -- -Add a direct route to the DHCP server (if it is non-local) which +.B bypass\-dhcp \-\- +Add a direct route to the DHCP server (if it is non\-local) which bypasses the tunnel (Available on Windows clients, may not be available -on non-Windows clients). +on non\-Windows clients). -.B bypass-dns -- -Add a direct route to the DNS server(s) (if they are non-local) which +.B bypass\-dns \-\- +Add a direct route to the DNS server(s) (if they are non\-local) which bypasses the tunnel (Available on Windows clients, may not be available -on non-Windows clients). +on non\-Windows clients). -.B block-local -- +.B block\-local \-\- Block access to local LAN when the tunnel is active, except for the LAN gateway itself. This is accomplished by routing the local LAN (except for the LAN gateway address) into the tunnel. -.B ipv6 -- +.B ipv6 \-\- Redirect IPv6 routing into the tunnel. This works similar to the .B def1 flag, that is, more specific IPv6 routes are added (2000::/4, 3000::/4), covering the whole IPv6 unicast space. -.B !ipv4 -- -Do not redirect IPv4 traffic - typically used in the flag pair +.B !ipv4 \-\- +Do not redirect IPv4 traffic \- typically used in the flag pair .B "ipv6 !ipv4" -to redirect IPv6-only. +to redirect IPv6\-only. .\"********************************************************* .TP .B \-\-link\-mtu n @@ -1270,13 +1279,13 @@ Should we do Path MTU discovery on TCP/UDP channel? Only supported on OSes such as Linux that supports the necessary system call to set. .B 'no' --- Never send DF (Don't Fragment) frames +\-\- Never send DF (Don't Fragment) frames .br .B 'maybe' --- Use per-route hints +\-\- Use per\-route hints .br .B 'yes' --- Always DF (Don't Fragment) +\-\- Always DF (Don't Fragment) .br .\"********************************************************* .TP @@ -1356,7 +1365,7 @@ without IP level fragmentation. The .B \-\-mssfix option only makes sense when you are using the UDP protocol -for OpenVPN peer-to-peer communication, i.e. +for OpenVPN peer\-to\-peer communication, i.e. .B \-\-proto udp. .B \-\-mssfix @@ -1395,7 +1404,7 @@ parameter from the option. Therefore, one could lower the maximum UDP packet size -to 1300 (a good first try for solving MTU-related +to 1300 (a good first try for solving MTU\-related connection problems) with the following options: .B \-\-tun\-mtu 1500 \-\-fragment 1300 \-\-mssfix @@ -1458,11 +1467,11 @@ seconds before queuing the next write. It should be noted that OpenVPN supports multiple tunnels between the same two peers, allowing you -to construct full-speed and reduced bandwidth tunnels +to construct full\-speed and reduced bandwidth tunnels at the same time, -routing low-priority data such as off-site backups +routing low\-priority data such as off\-site backups over the reduced bandwidth tunnel, and other data -over the full-speed tunnel. +over the full\-speed tunnel. Also note that for low bandwidth tunnels (under 1000 bytes per second), you should probably @@ -1537,7 +1546,7 @@ This option can be combined with .B \-\-inactive, \-\-ping, and .B \-\-ping\-exit -to create a two-tiered inactivity disconnect. +to create a two\-tiered inactivity disconnect. For example, @@ -1560,7 +1569,7 @@ or other packet from remote. This option is useful in cases where the remote peer has a dynamic IP address and -a low-TTL DNS name is used to track the IP address using +a low\-TTL DNS name is used to track the IP address using a service such as .I http://dyndns.org/ + a dynamic DNS client such @@ -1570,7 +1579,7 @@ as If the peer cannot be reached, a restart will be triggered, causing the hostname used with .B \-\-remote -to be re-resolved (if +to be re\-resolved (if .B \-\-resolv\-retry is also specified). @@ -1620,7 +1629,7 @@ and .B \-\-ping\-restart. This option can be used on both client and server side, but it is -in enough to add this on the server side as it will push appropriate +enough to add this on the server side as it will push appropriate .B \-\-ping and .B \-\-ping\-restart @@ -1676,12 +1685,12 @@ restarts. .B SIGUSR1 is a restart signal similar to .B SIGHUP, -but which offers finer-grained control over +but which offers finer\-grained control over reset options. .\"********************************************************* .TP .B \-\-persist\-key -Don't re-read key files across +Don't re\-read key files across .B SIGUSR1 or .B \-\-ping\-restart. @@ -1692,12 +1701,12 @@ to allow restarts triggered by the .B SIGUSR1 signal. Normally if you drop root privileges in OpenVPN, -the daemon cannot be restarted since it will now be unable to re-read protected +the daemon cannot be restarted since it will now be unable to re\-read protected key files. This option solves the problem by persisting keys across .B SIGUSR1 -resets, so they don't need to be re-read. +resets, so they don't need to be re\-read. .\"********************************************************* .TP .B \-\-persist\-local\-ip @@ -1754,7 +1763,7 @@ UID change). .B cmd consists of a path to script (or executable program), optionally -followed by arguments. The path and arguments may be single- or double-quoted +followed by arguments. The path and arguments may be single\- or double\-quoted and/or escaped using a backslash, and should be separated by one or more spaces. The up command is useful for specifying route @@ -1779,7 +1788,7 @@ additional parameters passed as environmental variables. Note that if .B cmd -includes arguments, all OpenVPN-generated arguments will be appended +includes arguments, all OpenVPN\-generated arguments will be appended to them to build an argument list with which the executable will be called. @@ -1811,7 +1820,7 @@ as the last parameter. NOTE: on restart, OpenVPN will not pass the full set of environment variables to the script. Namely, everything related to routing and -gateways will not be passed, as nothing needs to be done anyway - all +gateways will not be passed, as nothing needs to be done anyway \- all the routing setup is already in place. Additionally, the up\-restart script will run with the downgraded UID/GID settings (if configured). @@ -1820,7 +1829,7 @@ The following standalone example shows how the script can be called in both an initialization and restart context. (NOTE: for security reasons, don't run the following example unless UDP port 9999 is blocked by your firewall. Also, the example will run indefinitely, -so you should abort with control-c). +so you should abort with control\-c). .B openvpn \-\-dev tun \-\-port 9999 \-\-verb 4 \-\-ping\-restart 10 \-\-up 'echo up' \-\-down 'echo down' \-\-persist\-tun \-\-up\-restart @@ -1857,7 +1866,7 @@ mode, this option normally requires the use of to allow connection initiation to be sensed in the absence of tunnel data, since UDP is a "connectionless" protocol. -On Windows, this option will delay the TAP-Win32 media state +On Windows, this option will delay the TAP\-Win32 media state transitioning to "connected" until connection establishment, i.e. the receipt of the first authenticated packet from the peer. .\"********************************************************* @@ -1873,7 +1882,7 @@ UID change and/or ). .B cmd consists of a path to script (or executable program), optionally -followed by arguments. The path and arguments may be single- or double-quoted +followed by arguments. The path and arguments may be single\- or double\-quoted and/or escaped using a backslash, and should be separated by one or more spaces. Called with the same parameters and environmental @@ -1969,7 +1978,7 @@ is available since OpenVPN 2.3.3. .\"********************************************************* .TP .B \-\-script\-security level -This directive offers policy-level control over OpenVPN's usage of external programs +This directive offers policy\-level control over OpenVPN's usage of external programs and scripts. Lower .B level values are more restrictive, higher values are more permissive. Settings for @@ -1979,10 +1988,10 @@ values are more restrictive, higher values are more permissive. Settings for Strictly no calling of external programs. .br .B 1 \-\- -(Default) Only call built-in executables such as ifconfig, ip, route, or netsh. +(Default) Only call built\-in executables such as ifconfig, ip, route, or netsh. .br .B 2 \-\- -Allow calling of built-in executables and user-defined scripts. +Allow calling of built\-in executables and user\-defined scripts. .br .B 3 \-\- Allow passwords to be passed to scripts via environmental variables (potentially unsafe). @@ -1994,7 +2003,7 @@ could be either .B execve or .B system. -As of OpenVPN v2.3, this flag is no longer accepted. In most *nix environments the execve() +As of OpenVPN 2.3, this flag is no longer accepted. In most *nix environments the execve() approach has been used without any issues. Some directives such as \-\-up allow options to be passed to the external @@ -2006,15 +2015,15 @@ To run scripts in Windows in earlier OpenVPN versions you needed to either add a full path to the script interpreter which can parse the script or use the .B system -flag to run these scripts. As of OpenVPN v2.3 it is now a strict requirement to have -full path to the script interpreter when running non-executables files. +flag to run these scripts. As of OpenVPN 2.3 it is now a strict requirement to have +full path to the script interpreter when running non\-executables files. This is not needed for executable files, such as .exe, .com, .bat or .cmd files. For example, if you have a Visual Basic script, you must use this syntax now: .nf .ft 3 .in +4 -\-\-up 'C:\\\\Windows\\\\System32\\\\wscript.exe C:\\\\Program\\ Files\\\\OpenVPN\\\\config\\\\my-up-script.vbs' +\-\-up 'C:\\\\Windows\\\\System32\\\\wscript.exe C:\\\\Program\\ Files\\\\OpenVPN\\\\config\\\\my\-up\-script.vbs' .in -4 .ft .fi @@ -2064,7 +2073,7 @@ signal to a DHCP reset), you should make use of one or more of the .B \-\-persist options to ensure that OpenVPN doesn't need to execute any privileged -operations in order to restart (such as re-reading key files +operations in order to restart (such as re\-reading key files or running .BR ifconfig on the TUN device). @@ -2110,7 +2119,7 @@ This can be desirable from a security standpoint. Since the chroot operation is delayed until after initialization, most OpenVPN options that reference -files will operate in a pre-chroot context. +files will operate in a pre\-chroot context. In many cases, the .B dir @@ -2145,7 +2154,7 @@ it inside the chroot directory (e.g. with mount \-\-bind). Since the setcon operation is delayed until after initialization, OpenVPN can be restricted to just -network-related system calls, whereas by applying the +network\-related system calls, whereas by applying the context before startup (such as the OpenVPN one provided in the SELinux Reference Policies) you will have to allow many things required only during initialization. @@ -2194,22 +2203,22 @@ that initialization scripts can test the return status of the openvpn command for a fairly reliable indication of whether the command has correctly initialized and entered the packet forwarding event loop. -In OpenVPN, the vast majority of errors which occur after initialization are non-fatal. +In OpenVPN, the vast majority of errors which occur after initialization are non\-fatal. Note: as soon as OpenVPN has daemonized, it can not ask for usernames, passwords, or key pass phrases anymore. This has certain consequences, -namely that using a password-protected private key will fail unless the +namely that using a password\-protected private key will fail unless the .B \-\-askpass option is used to tell OpenVPN to ask for the pass phrase (this -requirement is new in 2.3.7, and is a consequence of calling daemon() +requirement is new in v2.3.7, and is a consequence of calling daemon() before initializing the crypto layer). Further, using .B \-\-daemon together with -.B \-\-auth-user-pass +.B \-\-auth\-user\-pass (entered on console) and -.B \-\-auth-nocache +.B \-\-auth\-nocache will fail as soon as key renegotiation (and reauthentication) occurs. .\"********************************************************* .TP @@ -2346,7 +2355,7 @@ less than zero is higher priority). .\".B \-\-tls\-server .\"specified). .\" -.\"Using a TLS thread offloads the CPU-intensive process of SSL/TLS-based +.\"Using a TLS thread offloads the CPU\-intensive process of SSL/TLS\-based .\"key exchange to a background thread so that it does not become .\"a latency bottleneck in the tunnel packet forwarding process. .\" @@ -2368,7 +2377,7 @@ or TUN/TAP devices. In such cases, one can optimize the event loop by avoiding the poll/epoll/select call, improving CPU efficiency by 5% to 10%. -This option can only be used on non-Windows systems, when +This option can only be used on non\-Windows systems, when .B \-\-proto udp is specified, and when .B \-\-shaper @@ -2376,7 +2385,7 @@ is NOT specified. .\"********************************************************* .TP .B \-\-multihome -Configure a multi-homed UDP server. This option needs to be used when +Configure a multi\-homed UDP server. This option needs to be used when a server has more than one IP address (e.g. multiple interfaces, or secondary IP addresses), and is not using .B \-\-local @@ -2388,10 +2397,10 @@ processing, so it's not enabled by default. Note: this option is only relevant for UDP servers. -Note 2: if you do an IPv6+IPv4 dual-stack bind on a Linux machine with +Note 2: if you do an IPv6+IPv4 dual\-stack bind on a Linux machine with multiple IPv4 address, connections to IPv4 addresses will not work right on kernels before 3.15, due to missing kernel support for the -IPv4-mapped case (some distributions have ported this to earlier kernel +IPv4\-mapped case (some distributions have ported this to earlier kernel versions, though). .\"********************************************************* .TP @@ -2474,7 +2483,7 @@ The parameter may be "lzo", "lz4", or empty. LZO and LZ4 are different compression algorithms, with LZ4 generally offering the best performance with least CPU usage. -For backwards compatibility with OpenVPN versions before 2.4, use "lzo" +For backwards compatibility with OpenVPN versions before v2.4, use "lzo" (which is identical to the older option "\-\-comp\-lzo yes"). If the @@ -2485,19 +2494,21 @@ setting to be pushed later. .\"********************************************************* .TP .B \-\-comp\-lzo [mode] -Use LZO compression -- may add up to 1 byte per +.B DEPRECATED +This option will be removed in a future OpenVPN release. Use the +newer +.B \-\-compress +instead. + +Use LZO compression \-\- may add up to 1 byte per packet for incompressible data. .B mode may be "yes", "no", or "adaptive" (default). -This option is deprecated in favor of the newer -.B --compress -option. - In a server mode setup, it is possible to selectively turn compression on or off for individual clients. -First, make sure the client-side config file enables selective +First, make sure the client\-side config file enables selective compression by having at least one .B \-\-comp\-lzo directive, such as @@ -2536,62 +2547,60 @@ Normally, adaptive compression is enabled with Adaptive compression tries to optimize the case where you have compression enabled, but you are sending predominantly incompressible -(or pre-compressed) packets over the tunnel, such as an FTP or rsync transfer +(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 efficiency. If the data being sent over the tunnel is already compressed, the compression efficiency will be very low, triggering openvpn to disable -compression for a period of time until the next re-sample test. +compression for a period of time until the next re\-sample test. .\"********************************************************* .TP -.B \-\-management IP port [pw-file] -Enable a TCP server on -.B IP:port -to handle daemon management functions. -.B pw-file, -if specified, -is a password file (password on first line) -or "stdin" to prompt from standard input. The password -provided will set the password which TCP clients will need -to provide in order to access management functions. - -The management interface can also listen on a unix domain socket, -for those platforms that support it. To use a unix domain socket, specify -the unix socket pathname in place of -.B IP -and set -.B port -to 'unix'. While the default behavior is to create a unix domain socket -that may be connected to by any process, the +.B \-\-management socket\-name unix [pw\-file] \ \ \ \ \ (recommended) +.TQ +.B \-\-management IP port [pw\-file] +Enable a management server on a +.B socket\-name +Unix socket on those platforms supporting it, or on +a designated TCP port. + +.B pw\-file +, if specified, is a password file where the password must be on first line. +Instead of a filename it can use the keyword stdin which will prompt the user +for a password to use when OpenVPN is starting. + +For unix sockets, the default behaviour is to create a unix domain socket +that may be connected to by any process. Use the .B \-\-management\-client\-user and .B \-\-management\-client\-group -directives can be used to restrict access. - -The management interface provides a special mode where the TCP -management link can operate over the tunnel itself. To enable this mode, -set -.B IP -= "tunnel". Tunnel mode will cause the management interface -to listen for a TCP connection on the local VPN address of the -TUN/TAP interface. +directives to restrict access. + +The management interface provides a special mode where the TCP management link +can operate over the tunnel itself. To enable this mode, set IP to +.B tunnel. +Tunnel mode will cause the management interface to listen for a +TCP connection on the local VPN address of the TUN/TAP interface. + +.B BEWARE +of enabling the management interface over TCP. In these cases you should +.I ALWAYS +make use of +.B pw\-file +to password protect the management interface. Any user who can connect to this +TCP +.B IP:port +will be able to manage and control (and interfere with) the OpenVPN process. +It is also strongly recommended to set IP to 127.0.0.1 (localhost) to restrict +accessibility of the management server to local clients. -While the management port is designed for programmatic control -of OpenVPN by other applications, it is possible to telnet -to the port, using a telnet client in "raw" mode. Once connected, -type "help" for a list of commands. +While the management port is designed for programmatic control of OpenVPN by +other applications, it is possible to telnet to the port, using a telnet client +in "raw" mode. Once connected, type "help" for a list of commands. -For detailed documentation on the management interface, see -the management\-notes.txt file in the -.B management -folder of -the OpenVPN source distribution. +For detailed documentation on the management interface, see the +.I management\-notes.txt +file in the management folder of the OpenVPN source distribution. -It is strongly recommended that -.B IP -be set to 127.0.0.1 -(localhost) to restrict accessibility of the management -server to local clients. .TP .B \-\-management\-client Management interface will connect as a TCP/unix domain client to @@ -2615,28 +2624,28 @@ console. .B \-\-management\-query\-proxy Query management channel for proxy server information for a specific .B \-\-remote -(client-only). +(client\-only). .\"********************************************************* .TP .B \-\-management\-query\-remote Allow management interface to override .B \-\-remote -directives (client-only). +directives (client\-only). .\"********************************************************* .TP .B \-\-management\-external\-key Allows usage for external private key file instead of .B \-\-key -option (client-only). +option (client\-only). .\"********************************************************* .TP -.B \-\-management\-external\-cert certificate-hint +.B \-\-management\-external\-cert certificate\-hint Allows usage for external certificate instead of .B \-\-cert -option (client-only). -.B certificate-hint +option (client\-only). +.B certificate\-hint is an arbitrary string which is passed to a management -interface client as an argument of NEED-CERTIFICATE notification. +interface client as an argument of NEED\-CERTIFICATE notification. Requires \-\-management\-external\-key. .\"********************************************************* .TP @@ -2679,7 +2688,7 @@ Report tunnel up/down events to management interface. .B \-\-management\-client\-auth Gives management interface client the responsibility to authenticate clients after their client certificate -has been verified. See management-notes.txt in OpenVPN +has been verified. See management\-notes.txt in OpenVPN distribution for detailed notes. .\"********************************************************* .TP @@ -2701,21 +2710,21 @@ only allow connections from group .B g. .\"********************************************************* .TP -.B \-\-plugin module-pathname [init-string] -Load plug-in module from the file -.B module-pathname, +.B \-\-plugin module\-pathname [init\-string] +Load plug\-in module from the file +.B module\-pathname, passing -.B init-string +.B init\-string as an argument to the module initialization function. Multiple plugin modules may be loaded into one OpenVPN process. The -.B module-pathname +.B module\-pathname argument can be just a filename or a filename with a relative or absolute path. The format of the filename and path defines -if the plug-in will be loaded from a default plug-in directory +if the plug\-in will be loaded from a default plug\-in directory or outside this directory. .nf @@ -2730,7 +2739,7 @@ or outside this directory. .in -4 .fi -DEFAULT_DIR is replaced by the default plug-in directory, +DEFAULT_DIR is replaced by the default plug\-in directory, which is configured at the build time of OpenVPN. CWD is the current directory where OpenVPN was started or the directory OpenVPN have swithed into via the @@ -2740,7 +2749,7 @@ option before the option. For more information and examples on how to build OpenVPN -plug-in modules, see the README file in the +plug\-in modules, see the README file in the .B plugin folder of the OpenVPN source distribution. @@ -2763,7 +2772,7 @@ every module and script must return success (0) in order for the connection to be authenticated. .\"********************************************************* .TP -.B \-\-keying-material-exporter label len +.B \-\-keying\-material\-exporter label len Save Exported Keying Material [RFC5705] of len bytes (must be between 16 and 4095 bytes) using label in environment (exported_keying_material) for use by plugins in @@ -2775,7 +2784,7 @@ labels. In order to prevent this, labels MUST begin with "EXPORTER". This option requires OpenSSL 1.0.1 or newer. .\"********************************************************* .SS Server Mode -Starting with OpenVPN 2.0, a multi-client TCP/UDP server mode +Starting with OpenVPN 2.0, a multi\-client TCP/UDP server mode is supported, and can be enabled with the .B \-\-mode server option. In server mode, OpenVPN will listen on a single @@ -2793,7 +2802,7 @@ of OpenVPN's server mode. This directive will set up an OpenVPN server which will allocate addresses to clients out of the given network/netmask. The server itself will take the ".1" address of the given network -for use as the server-side endpoint of the local +for use as the server\-side endpoint of the local TUN/TAP interface. For example, @@ -2836,7 +2845,7 @@ if you are ethernet bridging. Use instead. .\"********************************************************* .TP -.B \-\-server\-bridge gateway netmask pool-start-IP pool-end-IP +.B \-\-server\-bridge gateway netmask pool\-start\-IP pool\-end\-IP .TP .B \-\-server\-bridge ['nogw'] @@ -2847,10 +2856,10 @@ of OpenVPN's server mode in ethernet bridging configurations. If .B \-\-server\-bridge -is used without any parameters, it will enable a DHCP-proxy +is used without any parameters, it will enable a DHCP\-proxy mode, where connecting OpenVPN clients will receive an IP address for their TAP adapter from the DHCP server running -on the OpenVPN server-side LAN. +on the OpenVPN server\-side LAN. Note that only clients that support the binding of a DHCP client with the TAP adapter (such as Windows) can support this mode. The optional @@ -2866,7 +2875,7 @@ with the .B brctl tool, and with Windows XP it is done in the Network Connections Panel by selecting the ethernet and -TAP adapters and right-clicking on "Bridge Connections". +TAP adapters and right\-clicking on "Bridge Connections". Next you you must manually set the IP/netmask on the bridge interface. The @@ -2883,9 +2892,9 @@ subnet. Finally, set aside a IP range in the bridged subnet, denoted by -.B pool-start-IP +.B pool\-start\-IP and -.B pool-end-IP, +.B pool\-end\-IP, for OpenVPN to allocate to connecting clients. @@ -2964,7 +2973,7 @@ This is a partial list of options which can currently be pushed: .TP .B \-\-push\-reset Don't inherit the global push list for a specific client instance. -Specify this option in a client-specific context such +Specify this option in a client\-specific context such as with a .B \-\-client\-config\-dir configuration file. This option will ignore @@ -2976,22 +2985,22 @@ options at the global config file level. selectively remove all .B \-\-push options matching "opt" from the option list for a client. "opt" is matched -as a substring against the whole option string to-be-pushed to the client, so +as a substring against the whole option string to\-be\-pushed to the client, so .B \-\-push\-remove route would remove all .B \-\-push route ... and -.B \-\-push route-ipv6 ... +.B \-\-push route\-ipv6 ... statements, while -.B \-\-push\-remove 'route-ipv6 2001:' +.B \-\-push\-remove 'route\-ipv6 2001:' would only remove IPv6 routes for 2001:... networks. .B \-\-push\-remove -can only be used in a client-specific context, like in a +can only be used in a client\-specific context, like in a .B \-\-client\-config\-dir file, or .B \-\-client\-connect -script or plugin -- similar to +script or plugin \-\- similar to .B \-\-push\-reset, just more selective. @@ -3008,22 +3017,22 @@ option with the new value. Push additional information about the client to server. The following data is always pushed to the server: -IV_VER=<version> -- the client OpenVPN version +IV_VER=<version> \-\- the client OpenVPN version -IV_PLAT=[linux|solaris|openbsd|mac|netbsd|freebsd|win] -- the client OS platform +IV_PLAT=[linux|solaris|openbsd|mac|netbsd|freebsd|win] \-\- the client OS platform -IV_LZO_STUB=1 -- if client was built with LZO stub capability +IV_LZO_STUB=1 \-\- if client was built with LZO stub capability -IV_LZ4=1 -- if the client supports LZ4 compressions. +IV_LZ4=1 \-\- if the client supports LZ4 compressions. -IV_PROTO=2 -- if the client supports peer-id floating mechansim +IV_PROTO=2 \-\- if the client supports peer\-id floating mechansim -IV_NCP=2 -- negotiable ciphers, client supports +IV_NCP=2 \-\- negotiable ciphers, client supports .B \-\-cipher pushed by the server, a value of 2 or greater indicates client -supports AES-GCM-128 and AES-GCM-256. +supports AES\-GCM\-128 and AES\-GCM\-256. -IV_UI_VER=<gui_id> <version> -- the UI version of a UI if one is +IV_UI_VER=<gui_id> <version> \-\- the UI version of a UI if one is running, for example "de.blinkt.openvpn 0.5.47" for the Android app. @@ -3031,13 +3040,13 @@ When .B \-\-push\-peer\-info is enabled the additional information consists of the following data: -IV_HWADDR=<mac address> -- the MAC address of clients default gateway +IV_HWADDR=<mac address> \-\- the MAC address of clients default gateway -IV_SSL=<version string> -- the ssl version used by the client, e.g. "OpenSSL 1.0.2f 28 Jan 2016". +IV_SSL=<version string> \-\- the ssl version used by the client, e.g. "OpenSSL 1.0.2f 28 Jan 2016". -IV_PLAT_VER=x.y - the version of the operating system, e.g. 6.1 for Windows 7. +IV_PLAT_VER=x.y \- the version of the operating system, e.g. 6.1 for Windows 7. -UV_<name>=<value> -- client environment variables whose names start with "UV_" +UV_<name>=<value> \-\- client environment variables whose names start with "UV_" .\"********************************************************* .TP .B \-\-disable @@ -3057,12 +3066,12 @@ or dynamically generated using a script. .\"********************************************************* .TP -.B \-\-ifconfig\-pool start-IP end-IP [netmask] +.B \-\-ifconfig\-pool start\-IP end\-IP [netmask] Set aside a pool of subnets to be dynamically allocated to connecting clients, similar -to a DHCP server. For tun-style +to a DHCP server. For tun\-style tunnels, each client will be given a /30 subnet (for -interoperability with Windows clients). For tap-style +interoperability with Windows clients). For tap\-style tunnels, individual addresses will be allocated, and the optional .B netmask @@ -3079,24 +3088,24 @@ at intervals (default=600), as well as on program startup and shutdown. -The goal of this option is to provide a long-term association +The goal of this option is to provide a long\-term association between clients (denoted by their common name) and the virtual -IP address assigned to them from the ifconfig-pool. -Maintaining a long-term +IP address assigned to them from the ifconfig\-pool. +Maintaining a long\-term association is good for clients because it allows them to effectively use the .B \-\-persist\-tun option. .B file -is a comma-delimited ASCII file, formatted as -<Common-Name>,<IP-address>. +is a comma\-delimited ASCII file, formatted as +<Common\-Name>,<IP\-address>. If .B seconds = 0, .B file -will be treated as read-only. This is useful if +will be treated as read\-only. This is useful if you would like to treat .B file as a configuration file. @@ -3107,9 +3116,13 @@ a common name and IP address. They do not guarantee that the given common name will always receive the given IP address. If you want guaranteed assignment, use .B \-\-ifconfig\-push + .\"********************************************************* .TP .B \-\-ifconfig\-pool\-linear +.B DEPRECATED +This option will be removed in OpenVPN 2.5 + Modifies the .B \-\-ifconfig\-pool directive to @@ -3169,17 +3182,17 @@ OpenVPN's internal client IP address selection algorithm works as follows: .B 1 --- Use +\-\- Use .B \-\-client\-connect script generated file for static IP (first choice). .br .B 2 --- Use +\-\- Use .B \-\-client\-config\-dir file for static IP (next choice). .br .B 3 --- Use +\-\- Use .B \-\-ifconfig\-pool allocation for dynamic IP (last choice). .br @@ -3239,15 +3252,15 @@ Because the OpenVPN server mode handles multiple clients through a single tun or tap interface, it is effectively a router. The .B \-\-client\-to\-client -flag tells OpenVPN to internally route client-to-client -traffic rather than pushing all client-originating traffic +flag tells OpenVPN to internally route client\-to\-client +traffic rather than pushing all client\-originating traffic to the TUN/TAP interface. When this option is used, each client will "see" the other clients which are currently connected. Otherwise, each client will only see the server. Don't use this option if you want to firewall tunnel traffic using -custom, per-client rules. +custom, per\-client rules. .\"********************************************************* .TP .B \-\-duplicate\-cn @@ -3263,11 +3276,11 @@ on client connection. .B cmd consists of a path to script (or executable program), optionally -followed by arguments. The path and arguments may be single- or double-quoted +followed by arguments. The path and arguments may be single\- or double\-quoted and/or escaped using a backslash, and should be separated by one or more spaces. The command is passed the common name -and IP address of the just-authenticated client +and IP address of the just\-authenticated client as environmental variables (see environmental variable section below). The command is also passed the pathname of a freshly created temporary file as the last argument @@ -3289,7 +3302,7 @@ Note that the return value of .B script is significant. If .B script -returns a non-zero error status, it will cause the client +returns a non\-zero error status, it will cause the client to be disconnected. .\"********************************************************* .TP @@ -3305,10 +3318,10 @@ successful (0) status returns. The exception to this rule is if the .B \-\-client\-disconnect -command or plugins are cascaded, and at least one client-connect -function succeeded, then ALL of the client-disconnect functions for +command or plugins are cascaded, and at least one client\-connect +function succeeded, then ALL of the client\-disconnect functions for scripts and plugins will be called on client instance object deletion, -even in cases where some of the related client-connect functions returned +even in cases where some of the related client\-connect functions returned an error status. The @@ -3328,7 +3341,7 @@ for custom client config files. After a connecting client has been authenticated, OpenVPN will look in this directory for a file having the same name as the client's X509 common name. If a matching file -exists, it will be opened and parsed for client-specific +exists, it will be opened and parsed for client\-specific configuration options. If no matching file is found, OpenVPN will instead try to open and parse a default file called "DEFAULT", which may be provided but is not required. Note that @@ -3347,7 +3360,7 @@ created, edited, or removed while the server is live, without needing to restart the server. The following -options are legal in a client-specific context: +options are legal in a client\-specific context: .B \-\-push, \-\-push\-reset, \-\-push\-remove, \-\-iroute, \-\-ifconfig\-push, and .B \-\-config. @@ -3373,7 +3386,7 @@ This directory will be used by in the following cases: * .B \-\-client\-connect -scripts to dynamically generate client-specific +scripts to dynamically generate client\-specific configuration files. * @@ -3452,7 +3465,7 @@ forcing the server to deplete virtual memory as its internal routing table expands. This directive can be used in a .B \-\-client\-config\-dir -file or auto-generated by a +file or auto\-generated by a .B \-\-client\-connect script to override the global value for a particular client. @@ -3508,7 +3521,7 @@ to validate client virtual addresses or routes. .B cmd consists of a path to script (or executable program), optionally -followed by arguments. The path and arguments may be single- or double-quoted +followed by arguments. The path and arguments may be single\- or double\-quoted and/or escaped using a backslash, and should be separated by one or more spaces. Three arguments will be appended to any arguments in @@ -3533,7 +3546,7 @@ client linked to this address. Only present for "add" or "update" operations, not "delete". On "add" or "update" methods, if the script returns -a failure code (non-zero), OpenVPN will reject the address +a failure code (non\-zero), OpenVPN will reject the address and will not modify its internal routing table. Normally, the @@ -3542,8 +3555,8 @@ script will use the information provided above to set appropriate firewall entries on the VPN TUN/TAP interface. Since OpenVPN provides the association between virtual IP or MAC address and the client's authenticated common name, -it allows a user-defined script to configure firewall access -policies with regard to the client's high-level common name, +it allows a user\-defined script to configure firewall access +policies with regard to the client's high\-level common name, rather than the low level client virtual addresses. .\"********************************************************* .TP @@ -3558,7 +3571,7 @@ provided by the client. .B cmd consists of a path to script (or executable program), optionally -followed by arguments. The path and arguments may be single- or double-quoted +followed by arguments. The path and arguments may be single\- or double\-quoted and/or escaped using a backslash, and should be separated by one or more spaces. If @@ -3597,18 +3610,18 @@ returning a success exit code (0) if the client's authentication request is to be accepted, or a failure code (1) to reject the client. -This directive is designed to enable a plugin-style interface +This directive is designed to enable a plugin\-style interface for extending OpenVPN's authentication capabilities. To protect against a client passing a maliciously formed username or password string, the username string must consist only of these characters: alphanumeric, underbar -('_'), dash ('-'), dot ('.'), or at ('@'). The password +('_'), dash ('\-'), dot ('.'), or at ('@'). The password string can consist of any printable characters except for CR or LF. Any illegal characters in either the username or password string will be converted to underbar ('_'). -Care must be taken by any user-defined scripts to avoid +Care must be taken by any user\-defined scripts to avoid creating a security vulnerability in the way that these strings are handled. Never use these strings in such a way that they might be escaped or evaluated by a shell interpreter. @@ -3637,7 +3650,7 @@ or it is set to 0, the token will never expire. This feature is useful for environments which is configured to use One Time Passwords (OTP) as part of the user/password authentications and that authentication mechanism does not -implement any auth-token support. +implement any auth\-token support. .\"********************************************************* .TP .B \-\-opt\-verify @@ -3663,24 +3676,25 @@ or is specified (or an authentication plugin module), the OpenVPN server daemon will require connecting clients to specify a username and password. This option makes the submission of a username/password -by clients optional, passing the responsibility to the user-defined authentication +by clients optional, passing the responsibility to the user\-defined authentication module/script to accept or deny the client based on other factors (such as the setting of X509 certificate fields). When this option is used, -and a connecting client does not submit a username/password, the user-defined +and a connecting client does not submit a username/password, the user\-defined authentication module/script will see the username and password as being set to empty strings (""). The authentication module/script MUST have logic to detect this condition and respond accordingly. .\"********************************************************* .TP -.B \-\-client\-cert\-not\-required (DEPRECATED) +.B \-\-client\-cert\-not\-required +.B DEPRECATED +This option will be removed in OpenVPN 2.5 + Don't require client certificate, client will authenticate using username/password only. Be aware that using this directive is less secure than requiring certificates from all clients. - .B Please note: -This option is now deprecated and will be removed in OpenVPN v2.5. -It is replaced by +This is replaced by .B \-\-verify\-client\-cert which allows for more flexibility. The option .B \-\-verify\-client\-cert none @@ -3745,7 +3759,10 @@ the authenticated username as the common name, rather than the common name from the client cert. .\"********************************************************* .TP -.B \-\-compat\-names [no\-remapping] (DEPRECATED) +.B \-\-compat\-names [no\-remapping] +.B DEPRECATED +This option will be removed in OpenVPN 2.5 + Until OpenVPN v2.3 the format of the X.509 Subject fields was formatted like this: .IP @@ -3753,24 +3770,24 @@ like this: /C=US/L=Somewhere/CN=John Doe/emailAddress=john@example.com .IP In addition the old behaviour was to remap any character other than -alphanumeric, underscore ('_'), dash ('-'), dot ('.'), and slash ('/') to +alphanumeric, underscore ('_'), dash ('\-'), dot ('.'), and slash ('/') to underscore ('_'). The X.509 Subject string as returned by the .B tls_id environmental variable, could additionally contain colon (':') or equal ('='). .IP When using the .B \-\-compat\-names -option, this old formatting and remapping will be re-enabled again. This is -purely implemented for compatibility reasons when using older plug-ins or -scripts which does not handle the new formatting or UTF-8 characters. +option, this old formatting and remapping will be re\-enabled again. This is +purely implemented for compatibility reasons when using older plug\-ins or +scripts which does not handle the new formatting or UTF\-8 characters. .IP -In OpenVPN v2.3 the formatting of these fields changed into a more +In OpenVPN 2.3 the formatting of these fields changed into a more standardised format. It now looks like: .IP .B C=US, L=Somewhere, CN=John Doe, emailAddress=john@example.com .IP -The new default format in OpenVPN v2.3 also does not do the character remapping +The new default format in OpenVPN 2.3 also does not do the character remapping which happened earlier. This new format enables proper support for UTF\-8 characters in the usernames, X.509 Subject fields and Common Name variables and it complies to the RFC 2253, UTF\-8 String Representation of Distinguished @@ -3785,15 +3802,18 @@ option to be compatible with the now deprecated \-\-no\-name\-remapping option. It is only available at the server. When this mode flag is used, the Common Name, Subject, and username strings are allowed to include any printable character including space, but excluding control characters such as tab, newline, and -carriage-return. no-remapping is only available on the server side. +carriage\-return. no\-remapping is only available on the server side. .B Please note: This option is immediately deprecated. It is only implemented to make the transition to the new formatting less intrusive. It will be -removed in OpenVPN v2.5. So please update your scripts/plug-ins where necessary. +removed in OpenVPN 2.5. So please update your scripts/plug\-ins where necessary. .\"********************************************************* .TP -.B \-\-no\-name\-remapping (DEPRECATED) +.B \-\-no\-name\-remapping +.B DEPRECATED +This option will be removed in OpenVPN 2.5 + The .B \-\-no\-name\-remapping option is an alias for @@ -3803,7 +3823,7 @@ It ensures compatibility with server configurations using the option. .B Please note: -This option is now deprecated. It will be removed in OpenVPN v2.5. +This option is now deprecated. It will be removed in OpenVPN 2.5. So please make sure you support the new X.509 name formatting described with the .B \-\-compat\-names @@ -3813,7 +3833,7 @@ option as soon as possible. .B \-\-port\-share host port [dir] When run in TCP server mode, share the OpenVPN port with another application, such as an HTTPS server. If OpenVPN -senses a connection to its port which is using a non-OpenVPN +senses a connection to its port which is using a non\-OpenVPN protocol, it will proxy the connection to the server at .B host:port. Currently only designed to work with HTTP/HTTPS, @@ -3857,7 +3877,7 @@ of OpenVPN's client mode. This directive is equivalent to: .TP .B \-\-pull This option must be used on a client which is connecting -to a multi-client server. It indicates to OpenVPN that it +to a multi\-client server. It indicates to OpenVPN that it should accept options pushed by the server, provided they are part of the legal set of pushable options (note that the .B \-\-pull @@ -3946,7 +3966,7 @@ the client. .TP .B \-\-auth\-retry type Controls how OpenVPN responds to username/password verification -errors such as the client-side response to an AUTH_FAILED message from the server +errors such as the client\-side response to an AUTH_FAILED message from the server or verification failure of the private key password. Normally used to prevent auth errors from being fatal @@ -3956,7 +3976,7 @@ of error. An AUTH_FAILED message is generated by the server if the client fails .B \-\-auth\-user\-pass -authentication, or if the server-side +authentication, or if the server\-side .B \-\-client\-connect script returns an error status when the client tries to connect. @@ -4005,7 +4025,7 @@ connect timeouts. .\"********************************************************* .TP .B \-\-explicit\-exit\-notify [n] -In UDP client mode or point-to-point mode, send server/peer an exit notification +In UDP client mode or point\-to\-point mode, send server/peer an exit notification if tunnel is restarted or OpenVPN process is exited. In client mode, on exit/restart, this option will tell the server to immediately close its client instance object @@ -4031,13 +4051,13 @@ When this option is set, OpenVPN will not drop incoming tun packets with same destination as host. .\"********************************************************* .SS Data Channel Encryption Options: -These options are meaningful for both Static & TLS-negotiated key modes +These options are meaningful for both Static & TLS\-negotiated key modes (must be compatible between peers). .\"********************************************************* .TP .B \-\-secret file [direction] -Enable Static Key encryption mode (non-TLS). -Use pre-shared secret +Enable Static Key encryption mode (non\-TLS). +Use pre\-shared secret .B file which was generated with .B \-\-genkey. @@ -4045,7 +4065,7 @@ which was generated with The optional .B direction parameter enables the use of 4 distinct keys -(HMAC-send, cipher-encrypt, HMAC-receive, cipher-decrypt), so that +(HMAC\-send, cipher\-encrypt, HMAC\-receive, cipher\-decrypt), so that each data flow direction has a different set of HMAC and cipher keys. This has a number of desirable security properties including eliminating certain kinds of DoS and message replay attacks. @@ -4065,7 +4085,7 @@ The .B direction parameter requires that .B file -contains a 2048 bit key. While pre-1.5 versions of OpenVPN +contains a 2048 bit key. While pre\-1.5 versions of OpenVPN generate 1024 bit key files, any version of OpenVPN which supports the .B direction @@ -4079,7 +4099,7 @@ the primary being ease of configuration. There are no certificates or certificate authorities or complicated negotiation handshakes and protocols. -The only requirement is that you have a pre-existing secure channel with +The only requirement is that you have a pre\-existing secure channel with your peer (such as .B ssh ) to initially copy the key. This requirement, along with the @@ -4092,13 +4112,13 @@ was able to steal your private key, he would gain no information to help him decrypt past sessions. Another advantageous aspect of Static Key encryption mode is that -it is a handshake-free protocol +it is a handshake\-free protocol without any distinguishing signature or feature (such as a header or protocol handshake sequence) that would mark the ciphertext packets as being generated by OpenVPN. Anyone eavesdropping on the wire would see nothing -but random-looking data. +but random\-looking data. .\"********************************************************* .TP .B \-\-key\-direction @@ -4111,7 +4131,7 @@ options. Useful when using inline files (See section on inline files). .TP .B \-\-auth alg Authenticate data channel packets and (if enabled) -.B tls-auth +.B tls\-auth control channel packets with HMAC using message digest algorithm .B alg. (The default is @@ -4121,7 +4141,7 @@ HMAC is a commonly used message authentication algorithm (MAC) that uses a data string, a secure hash algorithm, and a key, to produce a digital signature. -The OpenVPN data channel protocol uses encrypt-then-mac (i.e. first encrypt a +The OpenVPN data channel protocol uses encrypt\-then\-mac (i.e. first encrypt a packet, then HMAC the resulting ciphertext), which prevents padding oracle attacks. @@ -4131,9 +4151,9 @@ algorithm is ignored for the data channel, and the authentication method of the AEAD cipher is used instead. Note that .B alg still specifies the digest used for -.B tls-auth\fR. +.B tls\-auth\fR. -In static-key encryption mode, the HMAC key +In static\-key encryption mode, the HMAC key is included in the key file generated by .B \-\-genkey. In TLS mode, the HMAC key is dynamically generated and shared @@ -4151,13 +4171,29 @@ For more information on HMAC see .B \-\-cipher alg Encrypt data channel packets with cipher algorithm .B alg. + The default is -.B BF-CBC, -an abbreviation for Blowfish in Cipher Block Chaining mode. +.B BF\-CBC, +an abbreviation for Blowfish in Cipher Block Chaining mode. When cipher +negotiation (NCP) is allowed, OpenVPN 2.4 and newer on both client and server +side will automatically upgrade to +.B AES\-256\-GCM. +See +.B \-\-ncp\-ciphers +and +.B \-\-ncp\-disable +for more details on NCP. -Using BF-CBC is no longer recommended, because of it's 64-bit block size. This +Using +.B BF\-CBC +is no longer recommended, because of its 64\-bit block size. This small block size allows attacks based on collisions, as demonstrated by SWEET32. -See https://community.openvpn.net/openvpn/wiki/SWEET32 for details. +See https://community.openvpn.net/openvpn/wiki/SWEET32 for details. Due to +this, support for +.B BF\-CBC, DES, CAST5, IDEA +and +.B RC2 +ciphers will be removed in OpenVPN 2.6. To see other ciphers that are available with OpenVPN, use the .B \-\-show\-ciphers @@ -4167,34 +4203,26 @@ Set .B alg=none to disable encryption. -As of OpenVPN 2.4, cipher negotiation (NCP) can override the cipher specified by -.B \-\-cipher\fR. -See -.B \-\-ncp\-ciphers -and -.B \-\-ncp\-disable -for more on NCP. - .\"********************************************************* .TP .B \-\-ncp\-ciphers cipher_list Restrict the allowed ciphers to be negotiated to the ciphers in .B cipher_list\fR. .B cipher_list -is a colon-separated list of ciphers, and defaults to -"AES-256-GCM:AES-128-GCM". +is a colon\-separated list of ciphers, and defaults to +"AES\-256\-GCM:AES\-128\-GCM". For servers, the first cipher from .B cipher_list will be pushed to clients that support cipher negotiation. -Cipher negotiation is enabled in client-server mode only. I.e. if +Cipher negotiation is enabled in client\-server mode only. I.e. if .B \-\-mode -is set to 'server' (server-side, implied by setting +is set to 'server' (server\-side, implied by setting .B \-\-server ), or if .B \-\-pull -is specified (client-side, implied by setting \-\-client). +is specified (client\-side, implied by setting \-\-client). If both peers support and do not disable NCP, the negotiated cipher will override the cipher specified by @@ -4205,10 +4233,10 @@ will inherit the cipher of the peer if that cipher is different from the local .B \-\-cipher setting, but the peer cipher is one of the ciphers specified in .B \-\-ncp\-ciphers\fR. -E.g. a non-NCP client (<=2.3, or with \-\-ncp\-disabled set) connecting to a -NCP server (2.4+) with "\-\-cipher BF-CBC" and "\-\-ncp-ciphers -AES-256-GCM:AES-256-CBC" set can either specify "\-\-cipher BF-CBC" or -"\-\-cipher AES-256-CBC" and both will work. +E.g. a non\-NCP client (<=v2.3, or with \-\-ncp\-disabled set) connecting to a +NCP server (v2.4+) with "\-\-cipher BF\-CBC" and "\-\-ncp\-ciphers +AES\-256\-GCM:AES\-256\-CBC" set can either specify "\-\-cipher BF\-CBC" or +"\-\-cipher AES\-256\-CBC" and both will work. .\"********************************************************* .TP @@ -4218,20 +4246,23 @@ negotiation. .\"********************************************************* .TP .B \-\-keysize n +.B DEPRECATED +This option will be removed in OpenVPN 2.6. + Size of cipher key in bits (optional). -If unspecified, defaults to cipher-specific default. The +If unspecified, defaults to cipher\-specific default. The .B \-\-show\-ciphers option (see below) shows all available OpenSSL ciphers, their default key sizes, and whether the key size can be changed. Use care in changing a cipher's default key size. Many ciphers have not been extensively -cryptanalyzed with non-standard key lengths, and a +cryptanalyzed with non\-standard key lengths, and a larger key may offer no real guarantee of greater security, or may even reduce security. .\"********************************************************* .TP .B \-\-prng alg [nsl] -(Advanced) For PRNG (Pseudo-random number generator), +(Advanced) For PRNG (Pseudo\-random number generator), use digest algorithm .B alg (default=sha1), and set @@ -4242,14 +4273,14 @@ to the size in bytes of the nonce secret length (between 16 and 64). Set .B alg=none to disable the PRNG and use the OpenSSL RAND_bytes function -instead for all of OpenVPN's pseudo-random number needs. +instead for all of OpenVPN's pseudo\-random number needs. .\"********************************************************* .TP -.B \-\-engine [engine-name] -Enable OpenSSL hardware-based crypto engine functionality. +.B \-\-engine [engine\-name] +Enable OpenSSL hardware\-based crypto engine functionality. If -.B engine-name +.B engine\-name is specified, use a specific crypto engine. Use the .B \-\-show\-engines @@ -4258,6 +4289,9 @@ supported by OpenSSL. .\"********************************************************* .TP .B \-\-no\-replay +.B DEPRECATED +This option will be removed in OpenVPN 2.5. + (Advanced) Disable OpenVPN's protection against replay attacks. Don't use this option unless you are prepared to make a tradeoff of greater efficiency in exchange for less @@ -4302,7 +4336,7 @@ by IPSec. .\"********************************************************* .TP .B \-\-replay\-window n [t] -Use a replay protection sliding-window of size +Use a replay protection sliding\-window of size .B n and a time window of .B t @@ -4324,7 +4358,7 @@ option is specified. When OpenVPN tunnels IP packets over UDP, there is the possibility that packets might be dropped or delivered out of order. Because OpenVPN, like IPSec, is emulating the physical network layer, -it will accept an out-of-order packet sequence, and +it will accept an out\-of\-order packet sequence, and will deliver such packets in the same order they were received to the TCP/IP protocol stack, provided they satisfy several constraints. @@ -4353,7 +4387,7 @@ Satellite links in particular often require this. If you run OpenVPN at .B \-\-verb 4, -you will see the message "Replay-window backtrack occurred [x]" +you will see the message "Replay\-window backtrack occurred [x]" every time the maximum sequence number backtrack seen thus far increases. This can be used to calibrate .B n. @@ -4377,11 +4411,11 @@ reordering: Don't allow it. Since TCP guarantees reliability, any packet loss or reordering event can be assumed to be an attack. In this sense, it could be argued that TCP tunnel transport is preferred when -tunneling non-IP or UDP application protocols which might be vulnerable to a +tunneling non\-IP or UDP application protocols which might be vulnerable to a message deletion or reordering attack which falls within the normal operational parameters of IP networks. -So I would make the statement that one should never tunnel a non-IP protocol +So I would make the statement that one should never tunnel a non\-IP protocol or UDP application protocol over UDP, if the protocol might be vulnerable to a message deletion or reordering attack that falls within the normal operating parameters of what is to be expected from the physical IP layer. The problem @@ -4397,7 +4431,7 @@ packets. .\"********************************************************* .TP .B \-\-replay\-persist file -Persist replay-protection state across sessions using +Persist replay\-protection state across sessions using .B file to save and reload the state. @@ -4416,12 +4450,11 @@ which were already received by the prior session. This option only makes sense when replay protection is enabled (the default) and you are using either .B \-\-secret -(shared-secret key mode) or TLS mode with +(shared\-secret key mode) or TLS mode with .B \-\-tls\-auth. .\"********************************************************* .TP .B \-\-no\-iv - .B DEPRECATED This option will be removed in OpenVPN 2.5. @@ -4437,16 +4470,16 @@ messages are being encrypted/decrypted with the same key. IV is implemented differently depending on the cipher mode used. -In CBC mode, OpenVPN uses a pseudo-random IV for each packet. +In CBC mode, OpenVPN uses a pseudo\-random IV for each packet. In CFB/OFB mode, OpenVPN uses a unique sequence number and time stamp as the IV. In fact, in CFB/OFB mode, OpenVPN uses a datagram -space-saving optimization that uses the unique identifier for +space\-saving optimization that uses the unique identifier for datagram replay protection as the IV. .\"********************************************************* .TP .B \-\-use\-prediction\-resistance -Enable prediction resistance on PolarSSL's RNG. +Enable prediction resistance on mbed TLS's RNG. Enabling prediction resistance causes the RNG to reseed in each call for random. Reseeding this often can quickly deplete the kernel @@ -4455,12 +4488,10 @@ entropy pool. If you need this option, please consider running a daemon that adds entropy to the kernel pool. -Note that this option only works with PolarSSL versions greater -than 1.1. .\"********************************************************* .TP .B \-\-test\-crypto -Do a self-test of OpenVPN's crypto options by encrypting and +Do a self\-test of OpenVPN's crypto options by encrypting and decrypting test packets using the data channel encryption options specified above. This option does not require a peer to function, and therefore can be specified without @@ -4480,7 +4511,7 @@ or This option is very useful to test OpenVPN after it has been ported to a new platform, or to isolate problems in the compiler, OpenSSL -crypto library, or OpenVPN's crypto code. Since it is a self-test mode, +crypto library, or OpenVPN's crypto code. Since it is a self\-test mode, problems with encryption and authentication can be debugged independently of network and tunnel issues. .\"********************************************************* @@ -4496,7 +4527,7 @@ any mediation. The result is the best of both worlds: a fast data channel that forwards over UDP with only the overhead of encrypt, decrypt, and HMAC functions, and a control channel that provides all of the security features of TLS, -including certificate-based authentication and Diffie Hellman forward secrecy. +including certificate\-based authentication and Diffie Hellman forward secrecy. To use TLS mode, each peer that runs OpenVPN should have its own local certificate/key pair ( @@ -4519,12 +4550,12 @@ passing data. The OpenVPN project provides a set of scripts for managing RSA certificates & keys: -.I https://github.com/OpenVPN/easy-rsa +.I https://github.com/OpenVPN/easy\-rsa .\"********************************************************* .TP .B \-\-tls\-server Enable TLS and assume server role during TLS handshake. Note that -OpenVPN is designed as a peer-to-peer application. The designation +OpenVPN is designed as a peer\-to\-peer application. The designation of client or server is only for the purpose of negotiating the TLS control channel. .\"********************************************************* @@ -4557,18 +4588,18 @@ they are distributed with OpenVPN, they are totally insecure. .TP .B \-\-capath dir Directory containing trusted certificates (CAs and CRLs). -Not available with PolarSSL. +Not available with mbed TLS. When using the .B \-\-capath option, you are required to supply valid CRLs for the CAs too. CAs in the capath directory are expected to be named <hash>.<n>. CRLs are expected to be named <hash>.r<n>. See the -.B -CApath +.B \-CApath option of .B openssl verify , and the -.B -hash +.B \-hash option of .B openssl x509 and @@ -4586,11 +4617,11 @@ Set .B file=none to disable Diffie Hellman key exchange (and use ECDH only). Note that this requires peers to be using an SSL library that supports ECDH TLS cipher suites -(e.g. OpenSSL 1.0.1+, or PolarSSL 1.3+). +(e.g. OpenSSL 1.0.1+, or mbed TLS 2.0+). Use .B openssl dhparam \-out dh2048.pem 2048 -to generate 2048-bit DH parameters. Diffie Hellman parameters may be considered +to generate 2048\-bit DH parameters. Diffie Hellman parameters may be considered public. .\"********************************************************* .TP @@ -4598,13 +4629,13 @@ public. Specify the curve to use for elliptic curve Diffie Hellman. Available curves can be listed with .BR \-\-show\-curves . -The specified curve will only be used for ECDH TLS-ciphers. +The specified curve will only be used for ECDH TLS\-ciphers. This option is not supported in mbed TLS builds of OpenVPN. .\"********************************************************* .TP .B \-\-cert file -Local peer's signed certificate in .pem format -- must be signed +Local peer's signed certificate in .pem format \-\- must be signed by a certificate authority whose certificate is in .B \-\-ca file. Each peer in an OpenVPN link running in TLS mode should have its own @@ -4636,7 +4667,7 @@ Note that the command reads the location of the certificate authority key from its configuration file such as .B /usr/share/ssl/openssl.cnf --- note also +\-\- note also that for certificate authority functions, you must set up the files .B index.txt (may be empty) and @@ -4657,7 +4688,7 @@ local certificate chain. This option is useful for "split" CAs, where the CA for server certs is different than the CA for client certs. Putting certs in this file allows them to be used to complete the local -certificate chain without trusting them to verify the peer-submitted +certificate chain without trusting them to verify the peer\-submitted certificate, as would be the case if the certs were placed in the .B ca file. @@ -4674,7 +4705,7 @@ above). Sets the minimum TLS version we will accept from the peer (default is "1.0"). Examples for version -include "1.0", "1.1", or "1.2". If 'or-highest' is specified +include "1.0", "1.1", or "1.2". If 'or\-highest' is specified and version is not recognized, we will only accept the highest TLS version supported by the local SSL implementation. .\"********************************************************* @@ -4691,14 +4722,14 @@ This option can be used instead of .B \-\-ca, \-\-cert, and .B \-\-key. -Not available with PolarSSL. +Not available with mbed TLS. .\"********************************************************* .TP .B \-\-verify\-hash hash [algo] -Specify SHA1 or SHA256 fingerprint for level-1 cert. The level-1 cert is the +Specify SHA1 or SHA256 fingerprint for level\-1 cert. The level\-1 cert is the CA (or intermediate cert) that signs the leaf certificate, and is one removed from the leaf certificate in the direction of the root. -When accepting a connection from a peer, the level-1 cert +When accepting a connection from a peer, the level\-1 cert fingerprint must match .B hash or certificate verification will fail. Hash is specified @@ -4730,9 +4761,9 @@ option. .\"********************************************************* .TP .B \-\-pkcs11\-id\-management -Acquire PKCS#11 id from management interface. In this case a NEED-STR 'pkcs11-id-request' -real-time message will be triggered, application may use pkcs11-id-count command to -retrieve available number of certificates, and pkcs11-id-get command to retrieve certificate +Acquire PKCS#11 id from management interface. In this case a NEED\-STR 'pkcs11\-id\-request' +real\-time message will be triggered, application may use pkcs11\-id\-count command to +retrieve available number of certificates, and pkcs11\-id\-get command to retrieve certificate id and certificate body. .\"********************************************************* .TP @@ -4754,7 +4785,7 @@ This option can be used instead of and .B \-\-pkcs12. -If p11-kit is present on the system, its +If p11\-kit is present on the system, its .B p11\-kit\-proxy.so module will be loaded by default if either the .B \-\-pkcs11\-id @@ -4771,23 +4802,23 @@ 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 determine automatically. +(default) \-\- Try to determine automatically. .br .B 1 --- Use sign. +\-\- Use sign. .br .B 2 --- Use sign recover. +\-\- Use sign recover. .br .B 4 --- Use decrypt. +\-\- Use decrypt. .br .B 8 --- Use unwrap. +\-\- Use unwrap. .br .\"********************************************************* .TP -.B \-\-cryptoapicert select-string +.B \-\-cryptoapicert select\-string Load the certificate and private key from the Windows Certificate System Store (Windows/OpenSSL Only). @@ -4815,12 +4846,15 @@ To select a certificate, based on certificate's thumbprint: .B cryptoapicert "THUMB:f6 49 24 41 01 b4 ..." -The thumbprint hex string can easily be copy-and-pasted from the Windows +The thumbprint hex string can easily be copy\-and\-pasted from the Windows Certificate Store GUI. .\"********************************************************* .TP .B \-\-key\-method m +.B DEPRECATED +This option will be removed in OpenVPN 2.5 + Use data channel key negotiation method .B m. The key method must match on both sides of the connection. @@ -4830,7 +4864,7 @@ for protecting the tunnel data channel is generated and exchanged over the TLS session. In method 1 (the default for OpenVPN 1.x), both sides generate -random encrypt and HMAC-send keys which are forwarded to +random encrypt and HMAC\-send keys which are forwarded to the other host over the TLS channel. Method 1 is .B deprecated in OpenVPN 2.4 , and @@ -4871,7 +4905,7 @@ channel, over which the keys that are used to protect the actual VPN traffic are exchanged. The supplied list of ciphers is (after potential OpenSSL/IANA name translation) -simply supplied to the crypto library. Please see the OpenSSL and/or PolarSSL +simply supplied to the crypto library. Please see the OpenSSL and/or mbed TLS documentation for details on the cipher list interpretation. Use @@ -4880,16 +4914,47 @@ to see a list of TLS ciphers supported by your crypto library. Warning! .B \-\-tls\-cipher -is an expert feature, which - if used correcly - can improve the security of +is an expert feature, which \- if used correcly \- can improve the security of your VPN connection. But it is also easy to unwittingly use it to carefully align a gun with your foot, or just break your connection. Use with care! -The default for \-\-tls\-cipher is to use PolarSSL's default cipher list -when using PolarSSL or +The default for \-\-tls\-cipher is to use mbed TLS's default cipher list +when using mbed TLS or "DEFAULT:!EXP:!LOW:!MEDIUM:!kDH:!kECDH:!DSS:!PSK:!SRP:!kRSA" when using OpenSSL. .\"********************************************************* .TP +.B \-\-tls\-cert\-profile profile +Set the allowed cryptographic algorithms for certificates according to +.B profile\fN. + +The following profiles are supported: + +.B legacy +(default): SHA1 and newer, RSA 2048-bit+, any elliptic curve. + +.B preferred +: SHA2 and newer, RSA 2048-bit+, any elliptic curve. + +.B suiteb +: SHA256/SHA384, ECDSA with P-256 or P-384. + +This option is only fully supported for mbed TLS builds. OpenSSL builds use +the following approximation: + +.B legacy +(default): sets "security level 1" + +.B preferred +: sets "security level 2" + +.B suiteb +: sets "security level 3" and \-\-tls\-cipher "SUITEB128". + +OpenVPN will migrate to 'preferred' as default in the future. Please ensure +that your keys already comply. +.\"********************************************************* +.TP .B \-\-tls\-timeout n Packet retransmit timeout on TLS control channel if no acknowledgment from remote within @@ -4899,7 +4964,7 @@ packet to its peer, it will expect to receive an acknowledgement within .B n seconds or it will retransmit the packet, subject -to a TCP-like exponential backoff algorithm. This parameter +to a TCP\-like exponential backoff algorithm. This parameter only applies to control channel packets. Data channel packets (which carry encrypted tunnel data) are never acknowledged, sequenced, or retransmitted by OpenVPN because @@ -4916,7 +4981,7 @@ to be expressed as a number of bytes encrypted/decrypted, a number of packets, or a number of seconds. A key renegotiation will be forced if any of these three criteria are met by either peer. -If using ciphers with cipher block sizes less than 128-bits, \-\-reneg\-bytes is +If using ciphers with cipher block sizes less than 128\-bits, \-\-reneg\-bytes is set to 64MB by default, unless it is explicitly disabled by setting the value to 0, but this is .B HIGHLY DISCOURAGED @@ -4935,7 +5000,7 @@ Renegotiate data channel key after .B n seconds (default=3600). -When using dual-factor authentication, note that this default value may +When using dual\-factor authentication, note that this default value may cause the end user to be challenged to reauthorize once per hour. Also, keep in mind that this option can be used on both the client and server, @@ -4950,7 +5015,7 @@ your chosen value on the other side. .\"********************************************************* .TP .B \-\-hand\-window n -Handshake Window -- the TLS-based key exchange must finalize within +Handshake Window \-\- the TLS\-based key exchange must finalize within .B n seconds of handshake initiation by any peer (default = 60 seconds). @@ -4964,7 +5029,7 @@ data. .\"********************************************************* .TP .B \-\-tran\-window n -Transition window -- our old key can live this many seconds +Transition window \-\- our old key can live this many seconds after a new a key renegotiation begins (default = 3600 seconds). This feature allows for a graceful transition from old to new key, and removes the key renegotiation sequence from the critical @@ -5008,8 +5073,8 @@ response. (required) is a file in OpenVPN static key format which can be generated by .B \-\-genkey -Older versions (up to 2.3) supported a freeform passphrase file. -This is no longer supported in newer versions (2.4+). +Older versions (up to OpenVPN 2.3) supported a freeform passphrase file. +This is no longer supported in newer versions (v2.4+). See the .B \-\-secret @@ -5027,7 +5092,7 @@ is specified with .B \-\-float. The rationale for -this feature is as follows. TLS requires a multi-packet exchange +this feature is as follows. TLS requires a multi\-packet exchange before it is able to authenticate a peer. During this time before authentication, OpenVPN is allocating resources (memory and CPU) to this potential peer. The potential peer is also @@ -5036,7 +5101,7 @@ it is sending. Most successful network attacks today seek to either exploit bugs in programs (such as buffer overflow attacks) or force a program to consume so many resources that it becomes unusable. Of course the first line of defense is always to produce clean, -well-audited code. OpenVPN has been written with buffer overflow +well\-audited code. OpenVPN has been written with buffer overflow attack prevention as a top priority. But as history has shown, many of the most widely used network applications have, from time to time, @@ -5092,8 +5157,8 @@ provides more privacy by hiding the certificate used for the TLS connection, .IP \[bu] makes it harder to identify OpenVPN traffic as such, .IP \[bu] -provides "poor-man's" post-quantum security, against attackers who will never -know the pre-shared key (i.e. no forward secrecy). +provides "poor\-man's" post\-quantum security, against attackers who will never +know the pre\-shared key (i.e. no forward secrecy). .RE .IP @@ -5106,10 +5171,10 @@ does *not* require the user to set .B Security Considerations All peers use the same -.B \-\-tls-crypt -pre-shared group key to authenticate and encrypt control channel messages. To +.B \-\-tls\-crypt +pre\-shared group key to authenticate and encrypt control channel messages. To ensure that IV collisions remain unlikely, this key should not be used to -encrypt more than 2^48 client-to-server or 2^48 server-to-client control +encrypt more than 2^48 client\-to\-server or 2^48 server\-to\-client control channel messages. A typical initial negotiation is about 10 packets in each direction. Assuming both initial negotiation and renegotiations are at most 2^16 (65536) packets (to be conservative), and (re)negotiations happen each @@ -5123,8 +5188,8 @@ If IV collisions were to occur, this could result in the security of degrading to the same security as using .B \-\-tls\-auth\fR. That is, the control channel still benefits from the extra protection against -active man-in-the-middle-attacks and DoS attacks, but may no longer offer -extra privacy and post-quantum security on top of what TLS itself offers. +active man\-in\-the\-middle\-attacks and DoS attacks, but may no longer offer +extra privacy and post\-quantum security on top of what TLS itself offers. .\"********************************************************* .TP .B \-\-askpass [file] @@ -5242,7 +5307,7 @@ should return 0 to allow the TLS handshake to proceed, or 1 to fail. .B cmd consists of a path to script (or executable program), optionally -followed by arguments. The path and arguments may be single- or double-quoted +followed by arguments. The path and arguments may be single\- or double\-quoted and/or escaped using a backslash, and should be separated by one or more spaces. When @@ -5311,13 +5376,13 @@ instead of the Common Name. Only the subjectAltName and issuerAltName X.509 extensions are supported. .B Please note: -This option has a feature which will convert an all-lowercase +This option has a feature which will convert an all\-lowercase .B fieldname -to uppercase characters, e.g., ou -> OU. A mixed-case +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 +prefix will be left as\-is. This automatic upcasing feature is deprecated and will be removed in a future release. .\"********************************************************* .TP @@ -5331,18 +5396,18 @@ Which X.509 name is compared to depends on the setting of type. .B type can be "subject" to match the complete subject DN (default), -"name" to match a subject RDN or "name-prefix" to match a subject RDN prefix. +"name" to match a subject RDN or "name\-prefix" to match a subject RDN prefix. Which RDN is verified as name depends on the .B \-\-x509\-username\-field option. But it defaults to the common name (CN), e.g. a certificate with a -subject DN "C=KG, ST=NA, L=Bishkek, CN=Server-1" would be matched by: +subject DN "C=KG, ST=NA, L=Bishkek, CN=Server\-1" would be matched by: .B \-\-verify\-x509\-name 'C=KG, ST=NA, L=Bishkek, CN=Server\-1' and .B \-\-verify\-x509\-name Server\-1 name or you could use -.B \-\-verify\-x509\-name Server -name-prefix -if you want a client to only accept connections to "Server-1", "Server-2", etc. +.B \-\-verify\-x509\-name Server\- name\-prefix +if you want a client to only accept connections to "Server\-1", "Server\-2", etc. .B \-\-verify\-x509\-name is a useful replacement for the @@ -5361,7 +5426,7 @@ with designated servers. .B NOTE: Test against a name prefix only when you are using OpenVPN with a custom CA certificate that is under your control. -Never use this option with type "name-prefix" when your client certificates +Never use this option with type "name\-prefix" when your client certificates are signed by a third party, such as a commercial web CA. .\"********************************************************* .TP @@ -5377,8 +5442,9 @@ as X509_<depth>_<attribute>=<value>. Multiple options can be defined to track multiple attributes. .\"********************************************************* .TP -.B \-\-ns\-cert\-type client|server (DEPRECATED) -This option is deprecated. Use the more modern equivalent +.B \-\-ns\-cert\-type client|server +.B DEPRECATED +This option will be removed in OpenVPN 2.5. Use the more modern equivalent .B \-\-remote\-cert\-tls instead. This option will be removed in OpenVPN 2.5. @@ -5399,7 +5465,7 @@ to "server", then the clients can verify this with .B \-\-ns\-cert\-type server. This is an important security precaution to protect against -a man-in-the-middle attack where an authorized client +a man\-in\-the\-middle attack where an authorized client attempts to connect to another client by impersonating the server. The attack is easily prevented by having clients verify the server certificate using any one of @@ -5464,7 +5530,7 @@ option is equivalent to \-\-remote\-cert\-ku \-\-remote\-cert\-eku "TLS Web Server Authentication" This is an important security precaution to protect against -a man-in-the-middle attack where an authorized client +a man\-in\-the\-middle attack where an authorized client attempts to connect to another client by impersonating the server. The attack is easily prevented by having clients verify the server certificate using any one of @@ -5536,7 +5602,7 @@ an ECDSA cipher suite will not work if you are using an RSA certificate, etc.). .TP .B \-\-show\-engines (Standalone) -Show currently available hardware-based crypto acceleration +Show currently available hardware\-based crypto acceleration engines supported by the OpenSSL library. .\"********************************************************* .TP @@ -5547,7 +5613,7 @@ Show all available elliptic curves to use with the option. .\"********************************************************* .SS Generate a random key: -Used only for non-TLS static key encryption mode. +Used only for non\-TLS static key encryption mode. .\"********************************************************* .TP .B \-\-genkey @@ -5556,7 +5622,7 @@ Generate a random key to be used as a shared secret, for use with the .B \-\-secret option. This file must be shared with the -peer over a pre-existing secure channel such as +peer over a pre\-existing secure channel such as .BR scp (1) . .\"********************************************************* @@ -5566,7 +5632,7 @@ Write key to .B file. .\"********************************************************* .SS TUN/TAP persistent tunnel config mode: -Available with linux 2.4.7+. These options comprise a standalone mode +Available with Linux 2.4.7+. These options comprise a standalone mode of OpenVPN which can be used to create and delete persistent tunnels. .\"********************************************************* .TP @@ -5591,7 +5657,7 @@ and commands. These commands can be placed in the the same shell script which starts or terminates an OpenVPN session. -Another advantage is that open connections through the TUN/TAP-based tunnel +Another advantage is that open connections through the TUN/TAP\-based tunnel will not be reset if the OpenVPN peer restarts. This can be useful to provide uninterrupted connectivity through the tunnel in the event of a DHCP reset of the peer's public IP address (see the @@ -5605,7 +5671,7 @@ and .B \-\-tun\-mtu above). -On some platforms such as Windows, TAP-Win32 tunnels are persistent by +On some platforms such as Windows, TAP\-Win32 tunnels are persistent by default. .\"********************************************************* .TP @@ -5625,7 +5691,7 @@ Optional user to be owner of this tunnel. .B \-\-group group Optional group to be owner of this tunnel. .\"********************************************************* -.SS Windows-Specific Options: +.SS Windows\-Specific Options: .\"********************************************************* .TP .B \-\-win\-sys path @@ -5650,7 +5716,7 @@ is found in the configuration file. .B \-\-ip\-win32 method When using .B \-\-ifconfig -on Windows, set the TAP-Win32 adapter +on Windows, set the TAP\-Win32 adapter IP address and netmask using .B method. Don't use this option unless you are also using @@ -5663,13 +5729,13 @@ to the console telling the user to configure the adapter manually and indicating the IP/netmask which OpenVPN expects the adapter to be set to. -.B dynamic [offset] [lease-time] -- +.B dynamic [offset] [lease\-time] \-\- Automatically set the IP address and netmask by replying to DHCP query messages generated by the kernel. This mode is probably the "cleanest" solution -for setting the TCP/IP properties since it uses the well-known +for setting the TCP/IP properties since it uses the well\-known DHCP protocol. There are, however, two prerequisites for using -this mode: (1) The TCP/IP properties for the TAP-Win32 +this mode: (1) The TCP/IP properties for the TAP\-Win32 adapter must be set to "Obtain an IP address automatically," and (2) OpenVPN needs to claim an IP address in the subnet for use as the virtual DHCP server address. By default in @@ -5682,7 +5748,7 @@ virtual DHCP server address. In .B \-\-dev tun mode, OpenVPN will cause the DHCP server to masquerade as if it were coming from the remote endpoint. The optional offset parameter is -an integer which is > \-256 and < 256 and which defaults to -1. +an integer which is > \-256 and < 256 and which defaults to \-1. If offset is positive, the DHCP server will masquerade as the IP address at network address + offset. If offset is negative, the DHCP server will masquerade as the IP @@ -5693,17 +5759,17 @@ address is. OpenVPN will "claim" this address, so make sure to use a free address. Having said that, different OpenVPN instantiations, including different ends of the same connection, can share the same virtual DHCP server address. The -.B lease-time +.B lease\-time parameter controls the lease time of the DHCP assignment given to -the TAP-Win32 adapter, and is denoted in seconds. +the TAP\-Win32 adapter, and is denoted in seconds. Normally a very long lease time is preferred -because it prevents routes involving the TAP-Win32 adapter from +because it prevents routes involving the TAP\-Win32 adapter from being lost when the system goes to sleep. The default lease time is one year. .B netsh \-\- Automatically set the IP address and netmask using -the Windows command-line "netsh" +the Windows command\-line "netsh" command. This method appears to work correctly on Windows XP but not Windows 2000. @@ -5712,7 +5778,7 @@ Automatically set the IP address and netmask using the Windows IP Helper API. This approach does not have ideal semantics, though testing has indicated that it works okay in practice. If you use this option, -it is best to leave the TCP/IP properties for the TAP-Win32 +it is best to leave the TCP/IP properties for the TAP\-Win32 adapter in their default state, i.e. "Obtain an IP address automatically." @@ -5721,14 +5787,14 @@ automatically." .B dynamic method initially and fail over to .B netsh -if the DHCP negotiation with the TAP-Win32 adapter does +if the DHCP negotiation with the TAP\-Win32 adapter does not succeed in 20 seconds. Such failures have been known -to occur when certain third-party firewall packages installed +to occur when certain third\-party firewall packages installed on the client machine block the DHCP negotiation used by -the TAP-Win32 adapter. +the TAP\-Win32 adapter. Note that if the .B netsh -failover occurs, the TAP-Win32 adapter +failover occurs, the TAP\-Win32 adapter TCP/IP properties will be reset from DHCP to static, and this will cause future OpenVPN startups using the .B adaptive @@ -5742,7 +5808,7 @@ mode from using .B netsh, run OpenVPN at least once using the .B dynamic -mode to restore the TAP-Win32 adapter TCP/IP properties +mode to restore the TAP\-Win32 adapter TCP/IP properties to a DHCP configuration. .\"********************************************************* .TP @@ -5752,42 +5818,38 @@ Which method to use for adding routes on Windows? .B adaptive -(default) -- Try IP helper API first. If that fails, fall +(default) \-\- Try IP helper API first. If that fails, fall back to the route.exe shell command. .br .B ipapi --- Use IP helper API. +\-\- Use IP helper API. .br .B exe --- Call the route.exe shell command. +\-\- Call the route.exe shell command. .\"********************************************************* .TP .B \-\-dhcp\-option type [parm] -Set extended TAP-Win32 TCP/IP properties, must +Set extended TAP\-Win32 TCP/IP properties, must be used with .B \-\-ip\-win32 dynamic or .B \-\-ip\-win32 adaptive. This option can be used to set additional TCP/IP properties -on the TAP-Win32 adapter, and is particularly useful for +on the TAP\-Win32 adapter, and is particularly useful for configuring an OpenVPN client to access a Samba server across the VPN. .B DOMAIN name \-\- -Set Connection-specific DNS Suffix. +Set Connection\-specific DNS Suffix. .B DNS addr \-\- -Set primary domain name server IPv4 address. Repeat +Set primary domain name server IPv4 or IPv6 address. Repeat this option to set secondary DNS server addresses. -.B DNS6 addr \-\- -Set primary domain name server IPv6 address. Repeat -this option to set secondary DNS server IPv6 addresses. - -Note: currently this is handled using netsh (the -existing DHCP code can only do IPv4 DHCP, and that protocol only -permits IPv4 addresses anywhere). The option will be put into the -environment, so an +Note: DNS IPv6 servers are currently set using netsh (the existing +DHCP code can only do IPv4 DHCP, and that protocol only permits IPv4 +addresses anywhere). The option will be put into the environment, so +an .B \-\-up script could act upon it if needed. @@ -5808,17 +5870,17 @@ to set secondary NTP server addresses. .B NBT type \-\- Set NetBIOS over TCP/IP Node type. Possible options: .B 1 -= b-node (broadcasts), += b\-node (broadcasts), .B 2 -= p-node (point-to-point += p\-node (point\-to\-point name queries to a WINS server), .B 4 -= m-node (broadcast += m\-node (broadcast then query name server), and .B 8 -= h-node (query name server, then broadcast). += h\-node (query name server, then broadcast). -.B NBS scope-id -- +.B NBS scope\-id \-\- Set NetBIOS over TCP/IP Scope. A NetBIOS Scope ID provides an extended naming service for the NetBIOS over TCP/IP (Known as NBT) module. The primary purpose of a NetBIOS scope ID is to isolate NetBIOS traffic on @@ -5830,14 +5892,14 @@ computers to use the same computer name, as they have different scope IDs. The Scope ID becomes a part of the NetBIOS name, making the name unique. (This description of NetBIOS scopes courtesy of NeonSurge@abyss.com) -.B DISABLE-NBT -- -Disable Netbios-over-TCP/IP. +.B DISABLE\-NBT \-\- +Disable Netbios\-over\-TCP/IP. Note that if .B \-\-dhcp\-option is pushed via .B \-\-push -to a non-windows client, the option will be saved in the client's +to a non\-windows client, the option will be saved in the client's environment before the up script is called, under the name "foreign_option_{n}". .\"********************************************************* @@ -5845,7 +5907,7 @@ the name "foreign_option_{n}". .B \-\-tap\-sleep n Cause OpenVPN to sleep for .B n -seconds immediately after the TAP-Win32 adapter state +seconds immediately after the TAP\-Win32 adapter state is set to "connected". This option is intended to be used to troubleshoot problems @@ -5854,7 +5916,7 @@ with the and .B \-\-ip\-win32 options, and is used to give -the TAP-Win32 adapter time to come up before +the TAP\-Win32 adapter time to come up before Windows IP Helper API operations are applied to it. .\"********************************************************* .TP @@ -5871,7 +5933,7 @@ TCP or UDP port 53 except one inside the tunnel. It uses Windows Filtering Platform (WFP) and works on Windows Vista or later. -This option is considered unknown on non-Windows platforms +This option is considered unknown on non\-Windows platforms and unsupported on Windows XP, resulting in fatal error. You may want to use .B \-\-setenv opt @@ -5886,14 +5948,14 @@ fatal errors. Ask Windows to renew the TAP adapter lease on startup. This option is normally unnecessary, as Windows automatically triggers a DHCP renegotiation on the TAP adapter when it -comes up, however if you set the TAP-Win32 adapter +comes up, however if you set the TAP\-Win32 adapter Media Status property to "Always Connected", you may need this flag. .\"********************************************************* .TP .B \-\-dhcp\-release Ask Windows to release the TAP adapter lease on shutdown. -This option has no effect now, as it is enabled by default starting with version 2.4.1. +This option has no effect now, as it is enabled by default starting with OpenVPN 2.4.1. .\"********************************************************* .TP .B \-\-register\-dns @@ -5906,29 +5968,29 @@ recognizing pushed DNS servers. Put up a "press any key to continue" message on the console prior to OpenVPN program exit. This option is automatically used by the Windows explorer when OpenVPN is run on a configuration -file using the right-click explorer menu. +file using the right\-click explorer menu. .\"********************************************************* .TP -.B \-\-service exit-event [0|1] +.B \-\-service exit\-event [0|1] Should be used when OpenVPN is being automatically executed by another program in such a context that no interaction with the user via display or keyboard -is possible. In general, end-users should never need to explicitly +is possible. In general, end\-users should never need to explicitly use this option, as it is automatically added by the OpenVPN service wrapper when a given OpenVPN configuration is being run as a service. -.B exit-event +.B exit\-event is the name of a Windows global event object, and OpenVPN will continuously monitor the state of this event object and exit when it becomes signaled. The second parameter indicates the initial state of -.B exit-event +.B exit\-event and normally defaults to 0. Multiple OpenVPN processes can be simultaneously executed with the same -.B exit-event +.B exit\-event parameter. In any case, the controlling process can signal -.B exit-event, +.B exit\-event, causing all such OpenVPN processes to exit. When executing an OpenVPN process using the @@ -5944,9 +6006,9 @@ to write these messages to a file. .TP .B \-\-show\-adapters (Standalone) -Show available TAP-Win32 adapters which can be selected using the +Show available TAP\-Win32 adapters which can be selected using the .B \-\-dev\-node -option. On non-Windows systems, the +option. On non\-Windows systems, the .BR ifconfig (8) command provides similar functionality. .\"********************************************************* @@ -5954,14 +6016,14 @@ command provides similar functionality. .B \-\-allow\-nonadmin [TAP\-adapter] (Standalone) Set -.B TAP-adapter -to allow access from non-administrative accounts. If -.B TAP-adapter +.B TAP\-adapter +to allow access from non\-administrative accounts. If +.B TAP\-adapter is omitted, all TAP adapters on the system will be configured to allow -non-admin access. -The non-admin access setting will only persist for the length of time that -the TAP-Win32 device object and driver remain loaded, and will need -to be re-enabled after a reboot, or if the driver is unloaded +non\-admin access. +The non\-admin access setting will only persist for the length of time that +the TAP\-Win32 device object and driver remain loaded, and will need +to be re\-enabled after a reboot, or if the driver is unloaded and reloaded. This directive can only be used by an administrator. .\"********************************************************* @@ -5970,12 +6032,12 @@ This directive can only be used by an administrator. (Standalone) Show valid subnets for .B \-\-dev tun -emulation. Since the TAP-Win32 driver +emulation. Since the TAP\-Win32 driver exports an ethernet interface to Windows, and since TUN devices are -point-to-point in nature, it is necessary for the TAP-Win32 driver +point\-to\-point in nature, it is necessary for the TAP\-Win32 driver to impose certain constraints on TUN endpoint address selection. -Namely, the point-to-point endpoints used in TUN device emulation +Namely, the point\-to\-point endpoints used in TUN device emulation must be the middle two addresses of a /30 subnet (netmask 255.255.255.252). .\"********************************************************* .TP @@ -5992,7 +6054,7 @@ adapter list. Show PKCS#11 token object list. Specify cert_private as 1 if certificates are stored as private objects. -If p11-kit is present on the system, the +If p11\-kit is present on the system, the .B provider argument is optional; if omitted the default .B p11\-kit\-proxy.so @@ -6012,8 +6074,8 @@ is passed as argument, the IPv6 route for this host is reported. .\"********************************************************* .SS IPv6 Related Options .\"********************************************************* -The following options exist to support IPv6 tunneling in peer-to-peer -and client-server mode. All options are modeled after their IPv4 +The following options exist to support IPv6 tunneling in peer\-to\-peer +and client\-server mode. All options are modeled after their IPv4 counterparts, so more detailed explanations given there apply here as well (except for .B \-\-topology @@ -6035,7 +6097,7 @@ field from is used. .TP .B \-\-server\-ipv6 ipv6addr/bits -convenience-function to enable a number of IPv6 related options at +convenience\-function to enable a number of IPv6 related options at once, namely .B \-\-ifconfig\-ipv6, \-\-ifconfig\-ipv6\-pool and @@ -6052,14 +6114,14 @@ pool starts at and matches the offset determined from the start of the IPv4 pool. .TP .B \-\-ifconfig\-ipv6\-push ipv6addr/bits ipv6remote -for ccd/ per-client static IPv6 interface configuration, see +for ccd/ per\-client static IPv6 interface configuration, see .B \-\-client\-config\-dir and .B \-\-ifconfig\-push for more details. .TP .B \-\-iroute\-ipv6 ipv6addr/bits -for ccd/ per-client static IPv6 route configuration, see +for ccd/ per\-client static IPv6 route configuration, see .B \-\-iroute for more details how to setup and use this, and how .B \-\-iroute @@ -6070,7 +6132,7 @@ interact. .\"********************************************************* .SH SCRIPTING AND ENVIRONMENTAL VARIABLES OpenVPN exports a series -of environmental variables for use by user-defined scripts. +of environmental variables for use by user\-defined scripts. .\"********************************************************* .SS Script Order of Execution .\"********************************************************* @@ -6155,13 +6217,13 @@ Here is a brief rundown of OpenVPN's current string types and the permitted character class for each string: .B X509 Names: -Alphanumeric, underbar ('_'), dash ('-'), dot ('.'), at +Alphanumeric, underbar ('_'), dash ('\-'), dot ('.'), at ('@'), colon (':'), slash ('/'), and equal ('='). Alphanumeric is defined as a character which will cause the C library isalnum() function to return true. .B Common Names: -Alphanumeric, underbar ('_'), dash ('-'), dot ('.'), and at +Alphanumeric, underbar ('_'), dash ('\-'), dot ('.'), and at ('@'). .B \-\-auth\-user\-pass username: @@ -6175,8 +6237,8 @@ Printable is defined to be a character which will cause the C library isprint() function to return true. .B \-\-client\-config\-dir filename as derived from common name or username: -Alphanumeric, underbar ('_'), dash ('-'), and dot ('.') except for "." or -".." as standalone strings. As of 2.0.1-rc6, the at ('@') character has +Alphanumeric, underbar ('_'), dash ('\-'), and dot ('.') except for "." or +".." as standalone strings. As of v2.0.1\-rc6, the at ('@') character has been added as well for compatibility with the common name character class. .B Environmental variable names: @@ -6192,7 +6254,7 @@ character class for that string type will be remapped to underbar ('_'). Once set, a variable is persisted indefinitely until it is reset by a new value or a restart, -As of OpenVPN 2.0-beta12, in server mode, environmental +As of OpenVPN 2.0\-beta12, in server mode, environmental variables set by OpenVPN are scoped according to the client objects they are @@ -6274,7 +6336,7 @@ An option pushed via to a client which does not natively support it, such as .B \-\-dhcp\-option -on a non-Windows system, will be recorded to this +on a non\-Windows system, will be recorded to this environmental variable sequence prior to .B \-\-up script execution. @@ -6499,7 +6561,7 @@ Set on program initiation and reset on SIGHUP. .\"********************************************************* .TP .B route_net_gateway -The pre-existing default IP gateway in the system routing +The pre\-existing default IP gateway in the system routing table. Set prior to .B \-\-up @@ -6604,7 +6666,7 @@ or .\"********************************************************* .TP .B time_ascii -Client connection timestamp, formatted as a human-readable +Client connection timestamp, formatted as a human\-readable time string. Set prior to execution of the .B \-\-client\-connect @@ -6654,7 +6716,7 @@ is the verification level. Only set for TLS connections. Set prior to execution of .B \-\-tls\-verify script. This is in the form of a decimal string like "933971680", which is -suitable for doing serial-based OCSP queries (with OpenSSL, do not +suitable for doing serial\-based OCSP queries (with OpenSSL, do not prepend "0x" to the string) If something goes wrong while reading the value from the certificate it will be an empty string, so your code should check that. @@ -6755,12 +6817,12 @@ and 1 for the CA certificate. .ft 3 .in +4 X509_0_emailAddress=me@myhost.mydomain -X509_0_CN=Test-Client -X509_0_O=OpenVPN-TEST +X509_0_CN=Test\-Client +X509_0_O=OpenVPN\-TEST X509_0_ST=NA X509_0_C=KG X509_1_emailAddress=me@myhost.mydomain -X509_1_O=OpenVPN-TEST +X509_1_O=OpenVPN\-TEST X509_1_L=BISHKEK X509_1_ST=NA X509_1_C=KG @@ -6771,7 +6833,7 @@ X509_1_C=KG .SH INLINE FILE SUPPORT OpenVPN allows including files in the main configuration for the .B \-\-ca, \-\-cert, \-\-dh, \-\-extra\-certs, \-\-key, \-\-pkcs12, \-\-secret, -.B \-\-crl\-verify, \-\-http\-proxy\-user\-pass, \-\-tls-auth +.B \-\-crl\-verify, \-\-http\-proxy\-user\-pass, \-\-tls\-auth and .B \-\-tls\-crypt options. @@ -6787,9 +6849,9 @@ Here is an example of an inline file usage .ft 3 .in +4 <cert> ------BEGIN CERTIFICATE----- +\-\-\-\-\-BEGIN CERTIFICATE\-\-\-\-\- [...] ------END CERTIFICATE----- +\-\-\-\-\-END CERTIFICATE\-\-\-\-\- </cert> .in -4 .ft @@ -6805,15 +6867,15 @@ the inline file has to be base64 encoded. Encoding of a .p12 file into base64 ca .B SIGHUP Cause OpenVPN to close all TUN/TAP and network connections, -restart, re-read the configuration file (if any), +restart, re\-read the configuration file (if any), and reopen TUN/TAP and network connections. .\"********************************************************* .TP .B SIGUSR1 Like .B SIGHUP, -except don't re-read configuration file, and possibly don't close and reopen TUN/TAP -device, re-read key files, preserve local IP address/port, or preserve most recently authenticated +except don't re\-read configuration file, and possibly don't close and reopen TUN/TAP +device, re\-read key files, preserve local IP address/port, or preserve most recently authenticated remote IP address/port based on .B \-\-persist\-tun, \-\-persist\-key, \-\-persist\-local\-ip, and @@ -6893,7 +6955,7 @@ a UDP ping to its remote peer once every 15 seconds which will cause many stateful firewalls to forward packets in both directions without an explicit firewall rule). -If you are using a Linux iptables-based firewall, you may need to enter +If you are using a Linux iptables\-based firewall, you may need to enter the following command to allow incoming packets on the TUN device: .IP .B iptables \-A INPUT \-i tun+ \-j ACCEPT @@ -6933,7 +6995,7 @@ via .B ssh without using the VPN (since .B ssh -has its own built-in security) you would use the command +has its own built\-in security) you would use the command .B ssh alice.example.com. However in the same scenario, you could also use the command .B telnet 10.4.0.2 @@ -6978,7 +7040,7 @@ program. Omit the .B \-\-verb 9 option to have OpenVPN run quietly. .\"********************************************************* -.SS Example 2: A tunnel with static-key security (i.e. using a pre-shared secret) +.SS Example 2: A tunnel with static\-key security (i.e. using a pre\-shared secret) First build a static key on bob. .IP .B openvpn \-\-genkey \-\-secret key @@ -7011,13 +7073,13 @@ On alice: .IP .B ping 10.4.0.1 .\"********************************************************* -.SS Example 3: A tunnel with full TLS-based security +.SS Example 3: A tunnel with full TLS\-based security For this test, we will designate .B bob as the TLS client and .B alice as the TLS server. -.I Note that client or server designation only has meaning for the TLS subsystem. It has no bearing on OpenVPN's peer-to-peer, UDP-based communication model. +.I Note that client or server designation only has meaning for the TLS subsystem. It has no bearing on OpenVPN's peer\-to\-peer, UDP\-based communication model. First, build a separate certificate/key pair for both bob and alice (see above where @@ -7028,7 +7090,7 @@ Diffie Hellman parameters (see above where is discussed for more info). You can also use the included test files client.crt, client.key, server.crt, server.key and ca.crt. -The .crt files are certificates/public-keys, the .key +The .crt files are certificates/public\-keys, the .key files are private keys, and ca.crt is a certification authority who has signed both client.crt and server.crt. For Diffie Hellman @@ -7103,7 +7165,7 @@ in a script and execute with the option. .\"********************************************************* .SH FIREWALLS -OpenVPN's usage of a single UDP port makes it fairly firewall-friendly. +OpenVPN's usage of a single UDP port makes it fairly firewall\-friendly. You should add an entry to your firewall rules to allow incoming OpenVPN packets. On Linux 2.4+: .IP @@ -7112,7 +7174,7 @@ packets. On Linux 2.4+: This will allow incoming packets on UDP port 1194 (OpenVPN's default UDP port) from an OpenVPN peer at 1.2.3.4. -If you are using HMAC-based packet authentication (the default in any of +If you are using HMAC\-based packet authentication (the default in any of OpenVPN's secure modes), having the firewall filter on source address can be considered optional, since HMAC packet authentication is a much more secure method of verifying the authenticity of @@ -7205,11 +7267,11 @@ OpenSSL Project ( For more information on the TLS protocol, see .I http://www.ietf.org/rfc/rfc2246.txt -For more information on the LZO real-time compression library see +For more information on the LZO real\-time compression library see .I http://www.oberhumer.com/opensource/lzo/ .\"********************************************************* .SH COPYRIGHT -Copyright (C) 2002-2010 OpenVPN Technologies, Inc. This program is free software; +Copyright (C) 2002\-2018 OpenVPN Inc This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. diff --git a/include/Makefile.am b/include/Makefile.am index a52c427..484e4e1 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -5,7 +5,7 @@ # packet encryption, packet authentication, and # packet compression. # -# Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> +# Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> # Copyright (C) 2006-2012 Alon Bar-Lev <alon.barlev@gmail.com> # diff --git a/include/Makefile.in b/include/Makefile.in index c0d4bd2..34b7efd 100644 --- a/include/Makefile.in +++ b/include/Makefile.in @@ -21,7 +21,7 @@ # packet encryption, packet authentication, and # packet compression. # -# Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> +# Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> # Copyright (C) 2006-2012 Alon Bar-Lev <alon.barlev@gmail.com> # @@ -354,6 +354,7 @@ plugindir = @plugindir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ +runstatedir = @runstatedir@ sampledir = @sampledir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ diff --git a/include/openvpn-msg.h b/include/openvpn-msg.h index 91e0ccc..82ecfe8 100644 --- a/include/openvpn-msg.h +++ b/include/openvpn-msg.h @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2013-2017 Heiko Hund <heiko.hund@sophos.com> + * Copyright (C) 2013-2018 Heiko Hund <heiko.hund@sophos.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/include/openvpn-plugin.h b/include/openvpn-plugin.h index 5cc5d42..f9e11d3 100644 --- a/include/openvpn-plugin.h +++ b/include/openvpn-plugin.h @@ -6,7 +6,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -55,7 +55,7 @@ extern "C" { */ #define OPENVPN_VERSION_MAJOR 2 #define OPENVPN_VERSION_MINOR 4 -#define OPENVPN_VERSION_PATCH ".3" +#define OPENVPN_VERSION_PATCH ".5" /* * Plug-in types. These types correspond to the set of script callbacks diff --git a/include/openvpn-plugin.h.in b/include/openvpn-plugin.h.in index f29b3a0..8614b61 100644 --- a/include/openvpn-plugin.h.in +++ b/include/openvpn-plugin.h.in @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -1,7 +1,7 @@ #!/bin/sh # install - install a program, script, or datafile -scriptversion=2013-12-25.23; # UTC +scriptversion=2014-09-12.12; # UTC # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the @@ -324,34 +324,41 @@ do # is incompatible with FreeBSD 'install' when (umask & 300) != 0. ;; *) + # $RANDOM is not portable (e.g. dash); use it when possible to + # lower collision chance tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ - trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 + trap 'ret=$?; rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null; exit $ret' 0 + # As "mkdir -p" follows symlinks and we work in /tmp possibly; so + # create the $tmpdir first (and fail if unsuccessful) to make sure + # that nobody tries to guess the $tmpdir name. if (umask $mkdir_umask && - exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 + $mkdirprog $mkdir_mode "$tmpdir" && + exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 then if test -z "$dir_arg" || { # Check for POSIX incompatibilities with -m. # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or # other-writable bit of parent directory when it shouldn't. # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. - ls_ld_tmpdir=`ls -ld "$tmpdir"` + test_tmpdir="$tmpdir/a" + ls_ld_tmpdir=`ls -ld "$test_tmpdir"` case $ls_ld_tmpdir in d????-?r-*) different_mode=700;; d????-?--*) different_mode=755;; *) false;; esac && - $mkdirprog -m$different_mode -p -- "$tmpdir" && { - ls_ld_tmpdir_1=`ls -ld "$tmpdir"` + $mkdirprog -m$different_mode -p -- "$test_tmpdir" && { + ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" } } then posix_mkdir=: fi - rmdir "$tmpdir/d" "$tmpdir" + rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" else # Remove any dirs left behind by ancient mkdir implementations. - rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null + rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null fi trap '' 0;; esac;; @@ -31,7 +31,7 @@ PROGRAM=libtool PACKAGE=libtool -VERSION=2.4.6 +VERSION="2.4.6 Debian-2.4.6-2" package_revision=2.4.6 @@ -2068,12 +2068,12 @@ include the following information: compiler: $LTCC compiler flags: $LTCFLAGS linker: $LD (gnu? $with_gnu_ld) - version: $progname (GNU libtool) 2.4.6 + version: $progname $scriptversion Debian-2.4.6-2 automake: `($AUTOMAKE --version) 2>/dev/null |$SED 1q` autoconf: `($AUTOCONF --version) 2>/dev/null |$SED 1q` Report bugs to <bug-libtool@gnu.org>. -GNU libtool home page: <http://www.gnu.org/software/libtool/>. +GNU libtool home page: <http://www.gnu.org/s/libtool/>. General help using GNU software: <http://www.gnu.org/gethelp/>." exit 0 } @@ -7272,10 +7272,13 @@ func_mode_link () # -tp=* Portland pgcc target processor selection # --sysroot=* for sysroot support # -O*, -g*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization + # -specs=* GCC specs files # -stdlib=* select c++ std lib with clang + # -fsanitize=* Clang/GCC memory and address sanitizer -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \ - -O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-stdlib=*) + -O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-stdlib=*| \ + -specs=*|-fsanitize=*) func_quote_for_eval "$arg" arg=$func_quote_for_eval_result func_append compile_command " $arg" @@ -7568,7 +7571,10 @@ func_mode_link () case $pass in dlopen) libs=$dlfiles ;; dlpreopen) libs=$dlprefiles ;; - link) libs="$deplibs %DEPLIBS% $dependency_libs" ;; + link) + libs="$deplibs %DEPLIBS%" + test "X$link_all_deplibs" != Xno && libs="$libs $dependency_libs" + ;; esac fi if test lib,dlpreopen = "$linkmode,$pass"; then @@ -7887,19 +7893,19 @@ func_mode_link () # It is a libtool convenience library, so add in its objects. func_append convenience " $ladir/$objdir/$old_library" func_append old_convenience " $ladir/$objdir/$old_library" + tmp_libs= + for deplib in $dependency_libs; do + deplibs="$deplib $deplibs" + if $opt_preserve_dup_deps; then + case "$tmp_libs " in + *" $deplib "*) func_append specialdeplibs " $deplib" ;; + esac + fi + func_append tmp_libs " $deplib" + done elif test prog != "$linkmode" && test lib != "$linkmode"; then func_fatal_error "'$lib' is not a convenience library" fi - tmp_libs= - for deplib in $dependency_libs; do - deplibs="$deplib $deplibs" - if $opt_preserve_dup_deps; then - case "$tmp_libs " in - *" $deplib "*) func_append specialdeplibs " $deplib" ;; - esac - fi - func_append tmp_libs " $deplib" - done continue fi # $pass = conv @@ -8823,6 +8829,9 @@ func_mode_link () revision=$number_minor lt_irix_increment=no ;; + *) + func_fatal_configuration "$modename: unknown library version type '$version_type'" + ;; esac ;; no) diff --git a/m4/libtool.m4 b/m4/libtool.m4 index a3bc337..ee80844 100644 --- a/m4/libtool.m4 +++ b/m4/libtool.m4 @@ -728,7 +728,6 @@ _LT_CONFIG_SAVE_COMMANDS([ cat <<_LT_EOF >> "$cfgfile" #! $SHELL # Generated automatically by $as_me ($PACKAGE) $VERSION -# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # NOTE: Changes made to this file will be lost: look at ltmain.sh. # Provide generalized library-building support services. @@ -2887,6 +2886,18 @@ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) dynamic_linker='GNU/Linux ld.so' ;; +netbsdelf*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='NetBSD ld.elf_so' + ;; + netbsd*) version_type=sunos need_lib_prefix=no @@ -3546,7 +3557,7 @@ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) lt_cv_deplibs_check_method=pass_all ;; -netbsd*) +netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' else @@ -4424,7 +4435,7 @@ m4_if([$1], [CXX], [ ;; esac ;; - netbsd*) + netbsd* | netbsdelf*-gnu) ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise @@ -4936,6 +4947,9 @@ m4_if([$1], [CXX], [ ;; esac ;; + linux* | k*bsd*-gnu | gnu*) + _LT_TAGVAR(link_all_deplibs, $1)=no + ;; *) _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' ;; @@ -4998,6 +5012,9 @@ dnl Note also adjust exclude_expsyms for C++ above. openbsd* | bitrig*) with_gnu_ld=no ;; + linux* | k*bsd*-gnu | gnu*) + _LT_TAGVAR(link_all_deplibs, $1)=no + ;; esac _LT_TAGVAR(ld_shlibs, $1)=yes @@ -5252,7 +5269,7 @@ _LT_EOF fi ;; - netbsd*) + netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= @@ -5773,6 +5790,7 @@ _LT_EOF if test yes = "$lt_cv_irix_exported_symbol"; then _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib' fi + _LT_TAGVAR(link_all_deplibs, $1)=no else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib' @@ -5794,7 +5812,7 @@ _LT_EOF esac ;; - netbsd*) + netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else diff --git a/sample/Makefile.am b/sample/Makefile.am index 58ae965..3be698e 100644 --- a/sample/Makefile.am +++ b/sample/Makefile.am @@ -5,7 +5,7 @@ # packet encryption, packet authentication, and # packet compression. # -# Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> +# Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> # Copyright (C) 2006-2012 Alon Bar-Lev <alon.barlev@gmail.com> # diff --git a/sample/Makefile.in b/sample/Makefile.in index 421897e..a130be4 100644 --- a/sample/Makefile.in +++ b/sample/Makefile.in @@ -21,7 +21,7 @@ # packet encryption, packet authentication, and # packet compression. # -# Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> +# Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> # Copyright (C) 2006-2012 Alon Bar-Lev <alon.barlev@gmail.com> # @@ -335,6 +335,7 @@ plugindir = @plugindir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ +runstatedir = @runstatedir@ sampledir = @sampledir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ diff --git a/sample/sample-config-files/client.conf b/sample/sample-config-files/client.conf index f5c69e3..5fd4a94 100644 --- a/sample/sample-config-files/client.conf +++ b/sample/sample-config-files/client.conf @@ -110,7 +110,7 @@ tls-auth ta.key 1 # Select a cryptographic cipher. # If the cipher option is used on the server # then you must also specify it here. -# Note that 2.4 client/server will automatically +# Note that v2.4 client/server will automatically # negotiate AES-256-GCM in TLS mode. # See also the ncp-cipher option in the manpage cipher AES-256-CBC diff --git a/sample/sample-config-files/server.conf b/sample/sample-config-files/server.conf index aa7d5b3..1dd477b 100644 --- a/sample/sample-config-files/server.conf +++ b/sample/sample-config-files/server.conf @@ -246,13 +246,13 @@ tls-auth ta.key 0 # This file is secret # Select a cryptographic cipher. # This config item must be copied to # the client config file as well. -# Note that 2.4 client/server will automatically +# Note that v2.4 client/server will automatically # negotiate AES-256-GCM in TLS mode. # See also the ncp-cipher option in the manpage cipher AES-256-CBC # Enable compression on the VPN link and push the -# option to the client (2.4+ only, for earlier +# option to the client (v2.4+ only, for earlier # versions see below) ;compress lz4-v2 ;push "compress lz4-v2" diff --git a/sample/sample-plugins/defer/simple.c b/sample/sample-plugins/defer/simple.c index 4960497..d18695b 100644 --- a/sample/sample-plugins/defer/simple.c +++ b/sample/sample-plugins/defer/simple.c @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/sample/sample-plugins/keying-material-exporter-demo/keyingmaterialexporter.c b/sample/sample-plugins/keying-material-exporter-demo/keyingmaterialexporter.c index 226eea6..5d3ca14 100644 --- a/sample/sample-plugins/keying-material-exporter-demo/keyingmaterialexporter.c +++ b/sample/sample-plugins/keying-material-exporter-demo/keyingmaterialexporter.c @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -142,9 +142,8 @@ session_user_set(struct session *sess, X509 *x509) { continue; } - /* bug in OpenSSL 0.9.6b ASN1_STRING_to_UTF8 requires this workaround */ - unsigned char *buf = (unsigned char *)1; - if (ASN1_STRING_to_UTF8(&buf, val) <= 0) + unsigned char *buf = NULL; + if (ASN1_STRING_to_UTF8(&buf, val) < 0) { continue; } diff --git a/sample/sample-plugins/log/log.c b/sample/sample-plugins/log/log.c index c59027f..ecf62c0 100644 --- a/sample/sample-plugins/log/log.c +++ b/sample/sample-plugins/log/log.c @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/sample/sample-plugins/log/log_v3.c b/sample/sample-plugins/log/log_v3.c index 8b537dd..c972951 100644 --- a/sample/sample-plugins/log/log_v3.c +++ b/sample/sample-plugins/log/log_v3.c @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * Copyright (C) 2010 David Sommerseth <dazo@users.sourceforge.net> * * This program is free software; you can redistribute it and/or modify @@ -227,8 +227,7 @@ x509_print_info(X509 *x509crt) { continue; } - buf = (unsigned char *)1; /* bug in OpenSSL 0.9.6b ASN1_STRING_to_UTF8 requires this workaround */ - if (ASN1_STRING_to_UTF8(&buf, val) <= 0) + if (ASN1_STRING_to_UTF8(&buf, val) < 0) { continue; } diff --git a/sample/sample-plugins/simple/simple.c b/sample/sample-plugins/simple/simple.c index 0a05240..950c547 100644 --- a/sample/sample-plugins/simple/simple.c +++ b/sample/sample-plugins/simple/simple.c @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/Makefile.am b/src/Makefile.am index eb5b007..c7f6302 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -5,7 +5,7 @@ # packet encryption, packet authentication, and # packet compression. # -# Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> +# Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> # Copyright (C) 2006-2012 Alon Bar-Lev <alon.barlev@gmail.com> # diff --git a/src/Makefile.in b/src/Makefile.in index 526d549..4dd5397 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -21,7 +21,7 @@ # packet encryption, packet authentication, and # packet compression. # -# Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> +# Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> # Copyright (C) 2006-2012 Alon Bar-Lev <alon.barlev@gmail.com> # VPATH = @srcdir@ @@ -365,6 +365,7 @@ plugindir = @plugindir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ +runstatedir = @runstatedir@ sampledir = @sampledir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ diff --git a/src/compat/Makefile.am b/src/compat/Makefile.am index 444a8f8..b4c3a4a 100644 --- a/src/compat/Makefile.am +++ b/src/compat/Makefile.am @@ -5,7 +5,7 @@ # packet encryption, packet authentication, and # packet compression. # -# Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> +# Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> # Copyright (C) 2006-2012 Alon Bar-Lev <alon.barlev@gmail.com> # diff --git a/src/compat/Makefile.in b/src/compat/Makefile.in index b264f40..fd11e4b 100644 --- a/src/compat/Makefile.in +++ b/src/compat/Makefile.in @@ -21,7 +21,7 @@ # packet encryption, packet authentication, and # packet compression. # -# Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> +# Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> # Copyright (C) 2006-2012 Alon Bar-Lev <alon.barlev@gmail.com> # @@ -356,6 +356,7 @@ plugindir = @plugindir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ +runstatedir = @runstatedir@ sampledir = @sampledir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ diff --git a/src/compat/compat-gettimeofday.c b/src/compat/compat-gettimeofday.c index fb57f2d..7cae641 100644 --- a/src/compat/compat-gettimeofday.c +++ b/src/compat/compat-gettimeofday.c @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/compat/compat-lz4.c b/src/compat/compat-lz4.c index 5855ca1..723157d 100644 --- a/src/compat/compat-lz4.c +++ b/src/compat/compat-lz4.c @@ -1,6 +1,16 @@ +/* This file has been backported by dev-tools/lz4-rebaser.sh + * from upstream lz4 commit 7bb64ff2b69a9f8367de (v1.7.5) + */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#elif defined(_MSC_VER) +#include "config-msvc.h" +#endif + +#ifdef NEED_COMPAT_LZ4 /* LZ4 - Fast LZ compression algorithm - Copyright (C) 2011-2015, Yann Collet. + Copyright (C) 2011-2016, Yann Collet. BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) @@ -28,19 +38,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. You can contact the author at : - - LZ4 source repository : https://github.com/Cyan4973/lz4 - - LZ4 public forum : https://groups.google.com/forum/#!forum/lz4c + - LZ4 homepage : http://www.lz4.org + - LZ4 source repository : https://github.com/lz4/lz4 */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#elif defined(_MSC_VER) -#include "config-msvc.h" -#endif - -#ifdef NEED_COMPAT_LZ4 -/************************************** +/*-************************************ * Tuning parameters **************************************/ /* @@ -48,7 +51,9 @@ * Select how default compression functions will allocate memory for their hash table, * in memory stack (0:default, fastest), or in memory heap (1:requires malloc()). */ -#define HEAPMODE 0 +#ifndef HEAPMODE +# define HEAPMODE 0 +#endif /* * ACCELERATION_DEFAULT : @@ -57,9 +62,31 @@ #define ACCELERATION_DEFAULT 1 -/************************************** +/*-************************************ * CPU Feature Detection **************************************/ +/* LZ4_FORCE_MEMORY_ACCESS + * By default, access to unaligned memory is controlled by `memcpy()`, which is safe and portable. + * Unfortunately, on some target/compiler combinations, the generated assembly is sub-optimal. + * The below switch allow to select different access method for improved performance. + * Method 0 (default) : use `memcpy()`. Safe and portable. + * Method 1 : `__packed` statement. It depends on compiler extension (ie, not portable). + * This method is safe if your compiler supports it, and *generally* as fast or faster than `memcpy`. + * Method 2 : direct access. This method is portable but violate C standard. + * It can generate buggy code on targets which generate assembly depending on alignment. + * But in some circumstances, it's the only known way to get the most performance (ie GCC + ARMv6) + * See https://fastcompression.blogspot.fr/2015/08/accessing-unaligned-memory.html for details. + * Prefer these methods in priority order (0 > 1 > 2) + */ +#ifndef LZ4_FORCE_MEMORY_ACCESS /* can be defined externally, on command line for example */ +# if defined(__GNUC__) && ( defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) ) +# define LZ4_FORCE_MEMORY_ACCESS 2 +# elif defined(__INTEL_COMPILER) || \ + (defined(__GNUC__) && ( defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7S__) )) +# define LZ4_FORCE_MEMORY_ACCESS 1 +# endif +#endif + /* * LZ4_FORCE_SW_BITCOUNT * Define this parameter if your target system or compiler does not support hardware bit count @@ -69,13 +96,14 @@ #endif -/************************************** -* Includes +/*-************************************ +* Dependency **************************************/ #include "compat-lz4.h" +/* see also "memory routines" below */ -/************************************** +/*-************************************ * Compiler Options **************************************/ #ifdef _MSC_VER /* Visual Studio */ @@ -84,19 +112,16 @@ # pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */ # pragma warning(disable : 4293) /* disable: C4293: too large shift (32-bits) */ #else -# if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */ -# if defined(__GNUC__) || defined(__clang__) -# define FORCE_INLINE static inline __attribute__((always_inline)) -# else -# define FORCE_INLINE static inline -# endif +# if defined(__GNUC__) || defined(__clang__) +# define FORCE_INLINE static inline __attribute__((always_inline)) +# elif defined(__cplusplus) || (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) +# define FORCE_INLINE static inline # else # define FORCE_INLINE static -# endif /* __STDC_VERSION__ */ +# endif #endif /* _MSC_VER */ -/* LZ4_GCC_VERSION is defined into lz4.h */ -#if (LZ4_GCC_VERSION >= 302) || (__INTEL_COMPILER >= 800) || defined(__clang__) +#if (defined(__GNUC__) && (__GNUC__ >= 3)) || (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 800)) || defined(__clang__) # define expect(expr,value) (__builtin_expect ((expr),(value)) ) #else # define expect(expr,value) (expr) @@ -106,7 +131,7 @@ #define unlikely(expr) expect((expr) != 0, 0) -/************************************** +/*-************************************ * Memory routines **************************************/ #include <stdlib.h> /* malloc, calloc, free */ @@ -116,54 +141,100 @@ #define MEM_INIT memset -/************************************** +/*-************************************ * Basic Types **************************************/ -#if defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */ +#if defined(__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) # include <stdint.h> typedef uint8_t BYTE; typedef uint16_t U16; typedef uint32_t U32; typedef int32_t S32; typedef uint64_t U64; + typedef uintptr_t uptrval; #else typedef unsigned char BYTE; typedef unsigned short U16; typedef unsigned int U32; typedef signed int S32; typedef unsigned long long U64; + typedef size_t uptrval; /* generally true, except OpenVMS-64 */ #endif +#if defined(__x86_64__) + typedef U64 reg_t; /* 64-bits in x32 mode */ +#else + typedef size_t reg_t; /* 32-bits in x32 mode */ +#endif -/************************************** +/*-************************************ * Reading and writing into memory **************************************/ -#define STEPSIZE sizeof(size_t) - -static unsigned LZ4_64bits(void) { return sizeof(void*)==8; } - static unsigned LZ4_isLittleEndian(void) { - const union { U32 i; BYTE c[4]; } one = { 1 }; /* don't use static : performance detrimental */ + const union { U32 u; BYTE c[4]; } one = { 1 }; /* don't use static : performance detrimental */ return one.c[0]; } +#if defined(LZ4_FORCE_MEMORY_ACCESS) && (LZ4_FORCE_MEMORY_ACCESS==2) +/* lie to the compiler about data alignment; use with caution */ + +static U16 LZ4_read16(const void* memPtr) { return *(const U16*) memPtr; } +static U32 LZ4_read32(const void* memPtr) { return *(const U32*) memPtr; } +static reg_t LZ4_read_ARCH(const void* memPtr) { return *(const reg_t*) memPtr; } + +static void LZ4_write16(void* memPtr, U16 value) { *(U16*)memPtr = value; } +static void LZ4_write32(void* memPtr, U32 value) { *(U32*)memPtr = value; } + +#elif defined(LZ4_FORCE_MEMORY_ACCESS) && (LZ4_FORCE_MEMORY_ACCESS==1) + +/* __pack instructions are safer, but compiler specific, hence potentially problematic for some compilers */ +/* currently only defined for gcc and icc */ +typedef union { U16 u16; U32 u32; reg_t uArch; } __attribute__((packed)) unalign; + +static U16 LZ4_read16(const void* ptr) { return ((const unalign*)ptr)->u16; } +static U32 LZ4_read32(const void* ptr) { return ((const unalign*)ptr)->u32; } +static reg_t LZ4_read_ARCH(const void* ptr) { return ((const unalign*)ptr)->uArch; } + +static void LZ4_write16(void* memPtr, U16 value) { ((unalign*)memPtr)->u16 = value; } +static void LZ4_write32(void* memPtr, U32 value) { ((unalign*)memPtr)->u32 = value; } + +#else /* safe and portable access through memcpy() */ + static U16 LZ4_read16(const void* memPtr) { - U16 val16; - memcpy(&val16, memPtr, 2); - return val16; + U16 val; memcpy(&val, memPtr, sizeof(val)); return val; +} + +static U32 LZ4_read32(const void* memPtr) +{ + U32 val; memcpy(&val, memPtr, sizeof(val)); return val; +} + +static reg_t LZ4_read_ARCH(const void* memPtr) +{ + reg_t val; memcpy(&val, memPtr, sizeof(val)); return val; } +static void LZ4_write16(void* memPtr, U16 value) +{ + memcpy(memPtr, &value, sizeof(value)); +} + +static void LZ4_write32(void* memPtr, U32 value) +{ + memcpy(memPtr, &value, sizeof(value)); +} + +#endif /* LZ4_FORCE_MEMORY_ACCESS */ + + static U16 LZ4_readLE16(const void* memPtr) { - if (LZ4_isLittleEndian()) - { + if (LZ4_isLittleEndian()) { return LZ4_read16(memPtr); - } - else - { + } else { const BYTE* p = (const BYTE*)memPtr; return (U16)((U16)p[0] + (p[1]<<8)); } @@ -171,63 +242,39 @@ static U16 LZ4_readLE16(const void* memPtr) static void LZ4_writeLE16(void* memPtr, U16 value) { - if (LZ4_isLittleEndian()) - { - memcpy(memPtr, &value, 2); - } - else - { + if (LZ4_isLittleEndian()) { + LZ4_write16(memPtr, value); + } else { BYTE* p = (BYTE*)memPtr; p[0] = (BYTE) value; p[1] = (BYTE)(value>>8); } } -static U32 LZ4_read32(const void* memPtr) +static void LZ4_copy8(void* dst, const void* src) { - U32 val32; - memcpy(&val32, memPtr, 4); - return val32; + memcpy(dst,src,8); } -static U64 LZ4_read64(const void* memPtr) -{ - U64 val64; - memcpy(&val64, memPtr, 8); - return val64; -} - -static size_t LZ4_read_ARCH(const void* p) -{ - if (LZ4_64bits()) - return (size_t)LZ4_read64(p); - else - return (size_t)LZ4_read32(p); -} - - -static void LZ4_copy4(void* dstPtr, const void* srcPtr) { memcpy(dstPtr, srcPtr, 4); } - -static void LZ4_copy8(void* dstPtr, const void* srcPtr) { memcpy(dstPtr, srcPtr, 8); } - -/* customized version of memcpy, which may overwrite up to 7 bytes beyond dstEnd */ +/* customized variant of memcpy, which can overwrite up to 8 bytes beyond dstEnd */ static void LZ4_wildCopy(void* dstPtr, const void* srcPtr, void* dstEnd) { BYTE* d = (BYTE*)dstPtr; const BYTE* s = (const BYTE*)srcPtr; - BYTE* e = (BYTE*)dstEnd; + BYTE* const e = (BYTE*)dstEnd; + do { LZ4_copy8(d,s); d+=8; s+=8; } while (d<e); } -/************************************** +/*-************************************ * Common Constants **************************************/ #define MINMATCH 4 -#define COPYLENGTH 8 +#define WILDCOPYLENGTH 8 #define LASTLITERALS 5 -#define MFLIMIT (COPYLENGTH+MINMATCH) +#define MFLIMIT (WILDCOPYLENGTH+MINMATCH) static const int LZ4_minLength = (MFLIMIT+1); #define KB *(1 <<10) @@ -243,55 +290,48 @@ static const int LZ4_minLength = (MFLIMIT+1); #define RUN_MASK ((1U<<RUN_BITS)-1) -/************************************** +/*-************************************ * Common Utils **************************************/ #define LZ4_STATIC_ASSERT(c) { enum { LZ4_static_assert = 1/(int)(!!(c)) }; } /* use only *after* variable declarations */ -/************************************** +/*-************************************ * Common functions **************************************/ -static unsigned LZ4_NbCommonBytes (register size_t val) +static unsigned LZ4_NbCommonBytes (register reg_t val) { - if (LZ4_isLittleEndian()) - { - if (LZ4_64bits()) - { + if (LZ4_isLittleEndian()) { + if (sizeof(val)==8) { # if defined(_MSC_VER) && defined(_WIN64) && !defined(LZ4_FORCE_SW_BITCOUNT) unsigned long r = 0; _BitScanForward64( &r, (U64)val ); return (int)(r>>3); -# elif (defined(__clang__) || (LZ4_GCC_VERSION >= 304)) && !defined(LZ4_FORCE_SW_BITCOUNT) +# elif (defined(__clang__) || (defined(__GNUC__) && (__GNUC__>=3))) && !defined(LZ4_FORCE_SW_BITCOUNT) return (__builtin_ctzll((U64)val) >> 3); # else static const int DeBruijnBytePos[64] = { 0, 0, 0, 0, 0, 1, 1, 2, 0, 3, 1, 3, 1, 4, 2, 7, 0, 2, 3, 6, 1, 5, 3, 5, 1, 3, 4, 4, 2, 5, 6, 7, 7, 0, 1, 2, 3, 3, 4, 6, 2, 6, 5, 5, 3, 4, 5, 6, 7, 1, 2, 4, 6, 4, 4, 5, 7, 2, 6, 5, 7, 6, 7, 7 }; return DeBruijnBytePos[((U64)((val & -(long long)val) * 0x0218A392CDABBD3FULL)) >> 58]; # endif - } - else /* 32 bits */ - { + } else /* 32 bits */ { # if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT) unsigned long r; _BitScanForward( &r, (U32)val ); return (int)(r>>3); -# elif (defined(__clang__) || (LZ4_GCC_VERSION >= 304)) && !defined(LZ4_FORCE_SW_BITCOUNT) +# elif (defined(__clang__) || (defined(__GNUC__) && (__GNUC__>=3))) && !defined(LZ4_FORCE_SW_BITCOUNT) return (__builtin_ctz((U32)val) >> 3); # else static const int DeBruijnBytePos[32] = { 0, 0, 3, 0, 3, 1, 3, 0, 3, 2, 2, 1, 3, 2, 0, 1, 3, 3, 1, 2, 2, 2, 2, 0, 3, 1, 2, 0, 1, 0, 1, 1 }; return DeBruijnBytePos[((U32)((val & -(S32)val) * 0x077CB531U)) >> 27]; # endif } - } - else /* Big Endian CPU */ - { - if (LZ4_64bits()) - { + } else /* Big Endian CPU */ { + if (sizeof(val)==8) { # if defined(_MSC_VER) && defined(_WIN64) && !defined(LZ4_FORCE_SW_BITCOUNT) unsigned long r = 0; _BitScanReverse64( &r, val ); return (unsigned)(r>>3); -# elif (defined(__clang__) || (LZ4_GCC_VERSION >= 304)) && !defined(LZ4_FORCE_SW_BITCOUNT) +# elif (defined(__clang__) || (defined(__GNUC__) && (__GNUC__>=3))) && !defined(LZ4_FORCE_SW_BITCOUNT) return (__builtin_clzll((U64)val) >> 3); # else unsigned r; @@ -300,14 +340,12 @@ static unsigned LZ4_NbCommonBytes (register size_t val) r += (!val); return r; # endif - } - else /* 32 bits */ - { + } else /* 32 bits */ { # if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT) unsigned long r = 0; _BitScanReverse( &r, (unsigned long)val ); return (unsigned)(r>>3); -# elif (defined(__clang__) || (LZ4_GCC_VERSION >= 304)) && !defined(LZ4_FORCE_SW_BITCOUNT) +# elif (defined(__clang__) || (defined(__GNUC__) && (__GNUC__>=3))) && !defined(LZ4_FORCE_SW_BITCOUNT) return (__builtin_clz((U32)val) >> 3); # else unsigned r; @@ -319,19 +357,19 @@ static unsigned LZ4_NbCommonBytes (register size_t val) } } +#define STEPSIZE sizeof(reg_t) static unsigned LZ4_count(const BYTE* pIn, const BYTE* pMatch, const BYTE* pInLimit) { const BYTE* const pStart = pIn; - while (likely(pIn<pInLimit-(STEPSIZE-1))) - { - size_t diff = LZ4_read_ARCH(pMatch) ^ LZ4_read_ARCH(pIn); + while (likely(pIn<pInLimit-(STEPSIZE-1))) { + reg_t const diff = LZ4_read_ARCH(pMatch) ^ LZ4_read_ARCH(pIn); if (!diff) { pIn+=STEPSIZE; pMatch+=STEPSIZE; continue; } pIn += LZ4_NbCommonBytes(diff); return (unsigned)(pIn - pStart); } - if (LZ4_64bits()) if ((pIn<(pInLimit-3)) && (LZ4_read32(pMatch) == LZ4_read32(pIn))) { pIn+=4; pMatch+=4; } + if ((STEPSIZE==8) && (pIn<(pInLimit-3)) && (LZ4_read32(pMatch) == LZ4_read32(pIn))) { pIn+=4; pMatch+=4; } if ((pIn<(pInLimit-1)) && (LZ4_read16(pMatch) == LZ4_read16(pIn))) { pIn+=2; pMatch+=2; } if ((pIn<pInLimit) && (*pMatch == *pIn)) pIn++; return (unsigned)(pIn - pStart); @@ -339,29 +377,16 @@ static unsigned LZ4_count(const BYTE* pIn, const BYTE* pMatch, const BYTE* pInLi #ifndef LZ4_COMMONDEFS_ONLY -/************************************** +/*-************************************ * Local Constants **************************************/ -#define LZ4_HASHLOG (LZ4_MEMORY_USAGE-2) -#define HASHTABLESIZE (1 << LZ4_MEMORY_USAGE) -#define HASH_SIZE_U32 (1 << LZ4_HASHLOG) /* required as macro for static allocation */ - static const int LZ4_64Klimit = ((64 KB) + (MFLIMIT-1)); static const U32 LZ4_skipTrigger = 6; /* Increase this value ==> compression run slower on incompressible data */ -/************************************** +/*-************************************ * Local Structures and types **************************************/ -typedef struct { - U32 hashTable[HASH_SIZE_U32]; - U32 currentOffset; - U32 initCheck; - const BYTE* dictionary; - BYTE* bufferStart; /* obsolete, used for slideInputBuffer */ - U32 dictSize; -} LZ4_stream_t_internal; - typedef enum { notLimited = 0, limitedOutput = 1 } limitedOutput_directive; typedef enum { byPtr, byU32, byU16 } tableType_t; @@ -372,44 +397,43 @@ typedef enum { endOnOutputSize = 0, endOnInputSize = 1 } endCondition_directive; typedef enum { full = 0, partial = 1 } earlyEnd_directive; -/************************************** +/*-************************************ * Local Utils **************************************/ int LZ4_versionNumber (void) { return LZ4_VERSION_NUMBER; } +const char* LZ4_versionString(void) { return LZ4_VERSION_STRING; } int LZ4_compressBound(int isize) { return LZ4_COMPRESSBOUND(isize); } int LZ4_sizeofState() { return LZ4_STREAMSIZE; } - -/******************************** +/*-****************************** * Compression functions ********************************/ - -static U32 LZ4_hashSequence(U32 sequence, tableType_t const tableType) +static U32 LZ4_hash4(U32 sequence, tableType_t const tableType) { if (tableType == byU16) - return (((sequence) * 2654435761U) >> ((MINMATCH*8)-(LZ4_HASHLOG+1))); + return ((sequence * 2654435761U) >> ((MINMATCH*8)-(LZ4_HASHLOG+1))); else - return (((sequence) * 2654435761U) >> ((MINMATCH*8)-LZ4_HASHLOG)); + return ((sequence * 2654435761U) >> ((MINMATCH*8)-LZ4_HASHLOG)); } -static const U64 prime5bytes = 889523592379ULL; -static U32 LZ4_hashSequence64(size_t sequence, tableType_t const tableType) +static U32 LZ4_hash5(U64 sequence, tableType_t const tableType) { + static const U64 prime5bytes = 889523592379ULL; + static const U64 prime8bytes = 11400714785074694791ULL; const U32 hashLog = (tableType == byU16) ? LZ4_HASHLOG+1 : LZ4_HASHLOG; - const U32 hashMask = (1<<hashLog) - 1; - return ((sequence * prime5bytes) >> (40 - hashLog)) & hashMask; + if (LZ4_isLittleEndian()) + return (U32)(((sequence << 24) * prime5bytes) >> (64 - hashLog)); + else + return (U32)(((sequence >> 24) * prime8bytes) >> (64 - hashLog)); } -static U32 LZ4_hashSequenceT(size_t sequence, tableType_t const tableType) +FORCE_INLINE U32 LZ4_hashPosition(const void* const p, tableType_t const tableType) { - if (LZ4_64bits()) - return LZ4_hashSequence64(sequence, tableType); - return LZ4_hashSequence((U32)sequence, tableType); + if ((sizeof(reg_t)==8) && (tableType != byU16)) return LZ4_hash5(LZ4_read_ARCH(p), tableType); + return LZ4_hash4(LZ4_read32(p), tableType); } -static U32 LZ4_hashPosition(const void* p, tableType_t tableType) { return LZ4_hashSequenceT(LZ4_read_ARCH(p), tableType); } - static void LZ4_putPositionOnHash(const BYTE* p, U32 h, void* tableBase, tableType_t const tableType, const BYTE* srcBase) { switch (tableType) @@ -420,27 +444,30 @@ static void LZ4_putPositionOnHash(const BYTE* p, U32 h, void* tableBase, tableTy } } -static void LZ4_putPosition(const BYTE* p, void* tableBase, tableType_t tableType, const BYTE* srcBase) +FORCE_INLINE void LZ4_putPosition(const BYTE* p, void* tableBase, tableType_t tableType, const BYTE* srcBase) { - U32 h = LZ4_hashPosition(p, tableType); + U32 const h = LZ4_hashPosition(p, tableType); LZ4_putPositionOnHash(p, h, tableBase, tableType, srcBase); } static const BYTE* LZ4_getPositionOnHash(U32 h, void* tableBase, tableType_t tableType, const BYTE* srcBase) { if (tableType == byPtr) { const BYTE** hashTable = (const BYTE**) tableBase; return hashTable[h]; } - if (tableType == byU32) { U32* hashTable = (U32*) tableBase; return hashTable[h] + srcBase; } - { U16* hashTable = (U16*) tableBase; return hashTable[h] + srcBase; } /* default, to ensure a return */ + if (tableType == byU32) { const U32* const hashTable = (U32*) tableBase; return hashTable[h] + srcBase; } + { const U16* const hashTable = (U16*) tableBase; return hashTable[h] + srcBase; } /* default, to ensure a return */ } -static const BYTE* LZ4_getPosition(const BYTE* p, void* tableBase, tableType_t tableType, const BYTE* srcBase) +FORCE_INLINE const BYTE* LZ4_getPosition(const BYTE* p, void* tableBase, tableType_t tableType, const BYTE* srcBase) { - U32 h = LZ4_hashPosition(p, tableType); + U32 const h = LZ4_hashPosition(p, tableType); return LZ4_getPositionOnHash(h, tableBase, tableType, srcBase); } + +/** LZ4_compress_generic() : + inlined, to ensure branches are decided at compilation time */ FORCE_INLINE int LZ4_compress_generic( - void* const ctx, + LZ4_stream_t_internal* const cctx, const char* const source, char* const dest, const int inputSize, @@ -451,15 +478,13 @@ FORCE_INLINE int LZ4_compress_generic( const dictIssue_directive dictIssue, const U32 acceleration) { - LZ4_stream_t_internal* const dictPtr = (LZ4_stream_t_internal*)ctx; - const BYTE* ip = (const BYTE*) source; const BYTE* base; const BYTE* lowLimit; - const BYTE* const lowRefLimit = ip - dictPtr->dictSize; - const BYTE* const dictionary = dictPtr->dictionary; - const BYTE* const dictEnd = dictionary + dictPtr->dictSize; - const size_t dictDelta = dictEnd - (const BYTE*)source; + const BYTE* const lowRefLimit = ip - cctx->dictSize; + const BYTE* const dictionary = cctx->dictionary; + const BYTE* const dictEnd = dictionary + cctx->dictSize; + const ptrdiff_t dictDelta = dictEnd - (const BYTE*)source; const BYTE* anchor = (const BYTE*) source; const BYTE* const iend = ip + inputSize; const BYTE* const mflimit = iend - MFLIMIT; @@ -469,10 +494,9 @@ FORCE_INLINE int LZ4_compress_generic( BYTE* const olimit = op + maxOutputSize; U32 forwardH; - size_t refDelta=0; /* Init conditions */ - if ((U32)inputSize > (U32)LZ4_MAX_INPUT_SIZE) return 0; /* Unsupported input size, too large (or negative) */ + if ((U32)inputSize > (U32)LZ4_MAX_INPUT_SIZE) return 0; /* Unsupported inputSize, too large (or negative) */ switch(dict) { case noDict: @@ -481,11 +505,11 @@ FORCE_INLINE int LZ4_compress_generic( lowLimit = (const BYTE*)source; break; case withPrefix64k: - base = (const BYTE*)source - dictPtr->currentOffset; - lowLimit = (const BYTE*)source - dictPtr->dictSize; + base = (const BYTE*)source - cctx->currentOffset; + lowLimit = (const BYTE*)source - cctx->dictSize; break; case usingExtDict: - base = (const BYTE*)source - dictPtr->currentOffset; + base = (const BYTE*)source - cctx->currentOffset; lowLimit = (const BYTE*)source; break; } @@ -493,44 +517,38 @@ FORCE_INLINE int LZ4_compress_generic( if (inputSize<LZ4_minLength) goto _last_literals; /* Input too small, no compression (all literals) */ /* First Byte */ - LZ4_putPosition(ip, ctx, tableType, base); + LZ4_putPosition(ip, cctx->hashTable, tableType, base); ip++; forwardH = LZ4_hashPosition(ip, tableType); /* Main Loop */ - for ( ; ; ) - { + for ( ; ; ) { + ptrdiff_t refDelta = 0; const BYTE* match; BYTE* token; - { - const BYTE* forwardIp = ip; + + /* Find a match */ + { const BYTE* forwardIp = ip; unsigned step = 1; unsigned searchMatchNb = acceleration << LZ4_skipTrigger; - - /* Find a match */ do { - U32 h = forwardH; + U32 const h = forwardH; ip = forwardIp; forwardIp += step; step = (searchMatchNb++ >> LZ4_skipTrigger); if (unlikely(forwardIp > mflimit)) goto _last_literals; - match = LZ4_getPositionOnHash(h, ctx, tableType, base); - if (dict==usingExtDict) - { - if (match<(const BYTE*)source) - { + match = LZ4_getPositionOnHash(h, cctx->hashTable, tableType, base); + if (dict==usingExtDict) { + if (match < (const BYTE*)source) { refDelta = dictDelta; lowLimit = dictionary; - } - else - { + } else { refDelta = 0; lowLimit = (const BYTE*)source; - } - } + } } forwardH = LZ4_hashPosition(forwardIp, tableType); - LZ4_putPositionOnHash(ip, h, ctx, tableType, base); + LZ4_putPositionOnHash(ip, h, cctx->hashTable, tableType, base); } while ( ((dictIssue==dictSmall) ? (match < lowRefLimit) : 0) || ((tableType==byU16) ? 0 : (match + MAX_DISTANCE < ip)) @@ -538,18 +556,17 @@ FORCE_INLINE int LZ4_compress_generic( } /* Catch up */ - while ((ip>anchor) && (match+refDelta > lowLimit) && (unlikely(ip[-1]==match[refDelta-1]))) { ip--; match--; } + while (((ip>anchor) & (match+refDelta > lowLimit)) && (unlikely(ip[-1]==match[refDelta-1]))) { ip--; match--; } - { - /* Encode Literal length */ - unsigned litLength = (unsigned)(ip - anchor); + /* Encode Literals */ + { unsigned const litLength = (unsigned)(ip - anchor); token = op++; - if ((outputLimited) && (unlikely(op + litLength + (2 + 1 + LASTLITERALS) + (litLength/255) > olimit))) - return 0; /* Check output limit */ - if (litLength>=RUN_MASK) - { + if ((outputLimited) && /* Check output buffer overflow */ + (unlikely(op + litLength + (2 + 1 + LASTLITERALS) + (litLength/255) > olimit))) + return 0; + if (litLength >= RUN_MASK) { int len = (int)litLength-RUN_MASK; - *token=(RUN_MASK<<ML_BITS); + *token = (RUN_MASK<<ML_BITS); for(; len >= 255 ; len-=255) *op++ = 255; *op++ = (BYTE)len; } @@ -565,41 +582,37 @@ _next_match: LZ4_writeLE16(op, (U16)(ip-match)); op+=2; /* Encode MatchLength */ - { - unsigned matchLength; + { unsigned matchCode; - if ((dict==usingExtDict) && (lowLimit==dictionary)) - { + if ((dict==usingExtDict) && (lowLimit==dictionary)) { const BYTE* limit; match += refDelta; limit = ip + (dictEnd-match); if (limit > matchlimit) limit = matchlimit; - matchLength = LZ4_count(ip+MINMATCH, match+MINMATCH, limit); - ip += MINMATCH + matchLength; - if (ip==limit) - { - unsigned more = LZ4_count(ip, (const BYTE*)source, matchlimit); - matchLength += more; + matchCode = LZ4_count(ip+MINMATCH, match+MINMATCH, limit); + ip += MINMATCH + matchCode; + if (ip==limit) { + unsigned const more = LZ4_count(ip, (const BYTE*)source, matchlimit); + matchCode += more; ip += more; } - } - else - { - matchLength = LZ4_count(ip+MINMATCH, match+MINMATCH, matchlimit); - ip += MINMATCH + matchLength; + } else { + matchCode = LZ4_count(ip+MINMATCH, match+MINMATCH, matchlimit); + ip += MINMATCH + matchCode; } - if ((outputLimited) && (unlikely(op + (1 + LASTLITERALS) + (matchLength>>8) > olimit))) - return 0; /* Check output limit */ - if (matchLength>=ML_MASK) - { + if ( outputLimited && /* Check output buffer overflow */ + (unlikely(op + (1 + LASTLITERALS) + (matchCode>>8) > olimit)) ) + return 0; + if (matchCode >= ML_MASK) { *token += ML_MASK; - matchLength -= ML_MASK; - for (; matchLength >= 510 ; matchLength-=510) { *op++ = 255; *op++ = 255; } - if (matchLength >= 255) { matchLength-=255; *op++ = 255; } - *op++ = (BYTE)matchLength; - } - else *token += (BYTE)(matchLength); + matchCode -= ML_MASK; + LZ4_write32(op, 0xFFFFFFFF); + while (matchCode >= 4*255) op+=4, LZ4_write32(op, 0xFFFFFFFF), matchCode -= 4*255; + op += matchCode / 255; + *op++ = (BYTE)(matchCode % 255); + } else + *token += (BYTE)(matchCode); } anchor = ip; @@ -608,24 +621,19 @@ _next_match: if (ip > mflimit) break; /* Fill table */ - LZ4_putPosition(ip-2, ctx, tableType, base); + LZ4_putPosition(ip-2, cctx->hashTable, tableType, base); /* Test next position */ - match = LZ4_getPosition(ip, ctx, tableType, base); - if (dict==usingExtDict) - { - if (match<(const BYTE*)source) - { + match = LZ4_getPosition(ip, cctx->hashTable, tableType, base); + if (dict==usingExtDict) { + if (match < (const BYTE*)source) { refDelta = dictDelta; lowLimit = dictionary; - } - else - { + } else { refDelta = 0; lowLimit = (const BYTE*)source; - } - } - LZ4_putPosition(ip, ctx, tableType, base); + } } + LZ4_putPosition(ip, cctx->hashTable, tableType, base); if ( ((dictIssue==dictSmall) ? (match>=lowRefLimit) : 1) && (match+MAX_DISTANCE>=ip) && (LZ4_read32(match+refDelta)==LZ4_read32(ip)) ) @@ -637,19 +645,16 @@ _next_match: _last_literals: /* Encode Last Literals */ - { - const size_t lastRun = (size_t)(iend - anchor); - if ((outputLimited) && ((op - (BYTE*)dest) + lastRun + 1 + ((lastRun+255-RUN_MASK)/255) > (U32)maxOutputSize)) - return 0; /* Check output limit */ - if (lastRun >= RUN_MASK) - { + { size_t const lastRun = (size_t)(iend - anchor); + if ( (outputLimited) && /* Check output buffer overflow */ + ((op - (BYTE*)dest) + lastRun + 1 + ((lastRun+255-RUN_MASK)/255) > (U32)maxOutputSize) ) + return 0; + if (lastRun >= RUN_MASK) { size_t accumulator = lastRun - RUN_MASK; *op++ = RUN_MASK << ML_BITS; for(; accumulator >= 255 ; accumulator-=255) *op++ = 255; *op++ = (BYTE) accumulator; - } - else - { + } else { *op++ = (BYTE)(lastRun<<ML_BITS); } memcpy(op, anchor, lastRun); @@ -663,22 +668,20 @@ _last_literals: int LZ4_compress_fast_extState(void* state, const char* source, char* dest, int inputSize, int maxOutputSize, int acceleration) { + LZ4_stream_t_internal* ctx = &((LZ4_stream_t*)state)->internal_donotuse; LZ4_resetStream((LZ4_stream_t*)state); if (acceleration < 1) acceleration = ACCELERATION_DEFAULT; - if (maxOutputSize >= LZ4_compressBound(inputSize)) - { + if (maxOutputSize >= LZ4_compressBound(inputSize)) { if (inputSize < LZ4_64Klimit) - return LZ4_compress_generic(state, source, dest, inputSize, 0, notLimited, byU16, noDict, noDictIssue, acceleration); + return LZ4_compress_generic(ctx, source, dest, inputSize, 0, notLimited, byU16, noDict, noDictIssue, acceleration); else - return LZ4_compress_generic(state, source, dest, inputSize, 0, notLimited, LZ4_64bits() ? byU32 : byPtr, noDict, noDictIssue, acceleration); - } - else - { + return LZ4_compress_generic(ctx, source, dest, inputSize, 0, notLimited, (sizeof(void*)==8) ? byU32 : byPtr, noDict, noDictIssue, acceleration); + } else { if (inputSize < LZ4_64Klimit) - return LZ4_compress_generic(state, source, dest, inputSize, maxOutputSize, limitedOutput, byU16, noDict, noDictIssue, acceleration); + return LZ4_compress_generic(ctx, source, dest, inputSize, maxOutputSize, limitedOutput, byU16, noDict, noDictIssue, acceleration); else - return LZ4_compress_generic(state, source, dest, inputSize, maxOutputSize, limitedOutput, LZ4_64bits() ? byU32 : byPtr, noDict, noDictIssue, acceleration); + return LZ4_compress_generic(ctx, source, dest, inputSize, maxOutputSize, limitedOutput, (sizeof(void*)==8) ? byU32 : byPtr, noDict, noDictIssue, acceleration); } } @@ -689,10 +692,10 @@ int LZ4_compress_fast(const char* source, char* dest, int inputSize, int maxOutp void* ctxPtr = ALLOCATOR(1, sizeof(LZ4_stream_t)); /* malloc-calloc always properly aligned */ #else LZ4_stream_t ctx; - void* ctxPtr = &ctx; + void* const ctxPtr = &ctx; #endif - int result = LZ4_compress_fast_extState(ctxPtr, source, dest, inputSize, maxOutputSize, acceleration); + int const result = LZ4_compress_fast_extState(ctxPtr, source, dest, inputSize, maxOutputSize, acceleration); #if (HEAPMODE) FREEMEM(ctxPtr); @@ -712,22 +715,21 @@ int LZ4_compress_default(const char* source, char* dest, int inputSize, int maxO int LZ4_compress_fast_force(const char* source, char* dest, int inputSize, int maxOutputSize, int acceleration) { LZ4_stream_t ctx; - LZ4_resetStream(&ctx); if (inputSize < LZ4_64Klimit) - return LZ4_compress_generic(&ctx, source, dest, inputSize, maxOutputSize, limitedOutput, byU16, noDict, noDictIssue, acceleration); + return LZ4_compress_generic(&ctx.internal_donotuse, source, dest, inputSize, maxOutputSize, limitedOutput, byU16, noDict, noDictIssue, acceleration); else - return LZ4_compress_generic(&ctx, source, dest, inputSize, maxOutputSize, limitedOutput, LZ4_64bits() ? byU32 : byPtr, noDict, noDictIssue, acceleration); + return LZ4_compress_generic(&ctx.internal_donotuse, source, dest, inputSize, maxOutputSize, limitedOutput, sizeof(void*)==8 ? byU32 : byPtr, noDict, noDictIssue, acceleration); } -/******************************** -* destSize variant +/*-****************************** +* *_destSize() variant ********************************/ static int LZ4_compress_destSize_generic( - void* const ctx, + LZ4_stream_t_internal* const ctx, const char* const src, char* const dst, int* const srcSizePtr, @@ -759,32 +761,30 @@ static int LZ4_compress_destSize_generic( /* First Byte */ *srcSizePtr = 0; - LZ4_putPosition(ip, ctx, tableType, base); + LZ4_putPosition(ip, ctx->hashTable, tableType, base); ip++; forwardH = LZ4_hashPosition(ip, tableType); /* Main Loop */ - for ( ; ; ) - { + for ( ; ; ) { const BYTE* match; BYTE* token; - { - const BYTE* forwardIp = ip; + + /* Find a match */ + { const BYTE* forwardIp = ip; unsigned step = 1; unsigned searchMatchNb = 1 << LZ4_skipTrigger; - /* Find a match */ do { U32 h = forwardH; ip = forwardIp; forwardIp += step; step = (searchMatchNb++ >> LZ4_skipTrigger); - if (unlikely(forwardIp > mflimit)) - goto _last_literals; + if (unlikely(forwardIp > mflimit)) goto _last_literals; - match = LZ4_getPositionOnHash(h, ctx, tableType, base); + match = LZ4_getPositionOnHash(h, ctx->hashTable, tableType, base); forwardH = LZ4_hashPosition(forwardIp, tableType); - LZ4_putPositionOnHash(ip, h, ctx, tableType, base); + LZ4_putPositionOnHash(ip, h, ctx->hashTable, tableType, base); } while ( ((tableType==byU16) ? 0 : (match + MAX_DISTANCE < ip)) || (LZ4_read32(match) != LZ4_read32(ip)) ); @@ -793,18 +793,15 @@ static int LZ4_compress_destSize_generic( /* Catch up */ while ((ip>anchor) && (match > lowLimit) && (unlikely(ip[-1]==match[-1]))) { ip--; match--; } - { - /* Encode Literal length */ - unsigned litLength = (unsigned)(ip - anchor); + /* Encode Literal length */ + { unsigned litLength = (unsigned)(ip - anchor); token = op++; - if (op + ((litLength+240)/255) + litLength > oMaxLit) - { + if (op + ((litLength+240)/255) + litLength > oMaxLit) { /* Not enough space for a last match */ op--; goto _last_literals; } - if (litLength>=RUN_MASK) - { + if (litLength>=RUN_MASK) { unsigned len = litLength - RUN_MASK; *token=(RUN_MASK<<ML_BITS); for(; len >= 255 ; len-=255) *op++ = 255; @@ -822,21 +819,15 @@ _next_match: LZ4_writeLE16(op, (U16)(ip-match)); op+=2; /* Encode MatchLength */ - { - size_t matchLength; + { size_t matchLength = LZ4_count(ip+MINMATCH, match+MINMATCH, matchlimit); - matchLength = LZ4_count(ip+MINMATCH, match+MINMATCH, matchlimit); - - if (op + ((matchLength+240)/255) > oMaxMatch) - { + if (op + ((matchLength+240)/255) > oMaxMatch) { /* Match description too long : reduce it */ matchLength = (15-1) + (oMaxMatch-op) * 255; } - //printf("offset %5i, matchLength%5i \n", (int)(ip-match), matchLength + MINMATCH); ip += MINMATCH + matchLength; - if (matchLength>=ML_MASK) - { + if (matchLength>=ML_MASK) { *token += ML_MASK; matchLength -= ML_MASK; while (matchLength >= 255) { matchLength-=255; *op++ = 255; } @@ -852,11 +843,11 @@ _next_match: if (op > oMaxSeq) break; /* Fill table */ - LZ4_putPosition(ip-2, ctx, tableType, base); + LZ4_putPosition(ip-2, ctx->hashTable, tableType, base); /* Test next position */ - match = LZ4_getPosition(ip, ctx, tableType, base); - LZ4_putPosition(ip, ctx, tableType, base); + match = LZ4_getPosition(ip, ctx->hashTable, tableType, base); + LZ4_putPosition(ip, ctx->hashTable, tableType, base); if ( (match+MAX_DISTANCE>=ip) && (LZ4_read32(match)==LZ4_read32(ip)) ) { token=op++; *token=0; goto _next_match; } @@ -867,25 +858,20 @@ _next_match: _last_literals: /* Encode Last Literals */ - { - size_t lastRunSize = (size_t)(iend - anchor); - if (op + 1 /* token */ + ((lastRunSize+240)/255) /* litLength */ + lastRunSize /* literals */ > oend) - { + { size_t lastRunSize = (size_t)(iend - anchor); + if (op + 1 /* token */ + ((lastRunSize+240)/255) /* litLength */ + lastRunSize /* literals */ > oend) { /* adapt lastRunSize to fill 'dst' */ lastRunSize = (oend-op) - 1; lastRunSize -= (lastRunSize+240)/255; } ip = anchor + lastRunSize; - if (lastRunSize >= RUN_MASK) - { + if (lastRunSize >= RUN_MASK) { size_t accumulator = lastRunSize - RUN_MASK; *op++ = RUN_MASK << ML_BITS; for(; accumulator >= 255 ; accumulator-=255) *op++ = 255; *op++ = (BYTE) accumulator; - } - else - { + } else { *op++ = (BYTE)(lastRunSize<<ML_BITS); } memcpy(op, anchor, lastRunSize); @@ -898,20 +884,17 @@ _last_literals: } -static int LZ4_compress_destSize_extState (void* state, const char* src, char* dst, int* srcSizePtr, int targetDstSize) +static int LZ4_compress_destSize_extState (LZ4_stream_t* state, const char* src, char* dst, int* srcSizePtr, int targetDstSize) { - LZ4_resetStream((LZ4_stream_t*)state); + LZ4_resetStream(state); - if (targetDstSize >= LZ4_compressBound(*srcSizePtr)) /* compression success is guaranteed */ - { + if (targetDstSize >= LZ4_compressBound(*srcSizePtr)) { /* compression success is guaranteed */ return LZ4_compress_fast_extState(state, src, dst, *srcSizePtr, targetDstSize, 1); - } - else - { + } else { if (*srcSizePtr < LZ4_64Klimit) - return LZ4_compress_destSize_generic(state, src, dst, srcSizePtr, targetDstSize, byU16); + return LZ4_compress_destSize_generic(&state->internal_donotuse, src, dst, srcSizePtr, targetDstSize, byU16); else - return LZ4_compress_destSize_generic(state, src, dst, srcSizePtr, targetDstSize, LZ4_64bits() ? byU32 : byPtr); + return LZ4_compress_destSize_generic(&state->internal_donotuse, src, dst, srcSizePtr, targetDstSize, sizeof(void*)==8 ? byU32 : byPtr); } } @@ -919,10 +902,10 @@ static int LZ4_compress_destSize_extState (void* state, const char* src, char* d int LZ4_compress_destSize(const char* src, char* dst, int* srcSizePtr, int targetDstSize) { #if (HEAPMODE) - void* ctx = ALLOCATOR(1, sizeof(LZ4_stream_t)); /* malloc-calloc always properly aligned */ + LZ4_stream_t* ctx = (LZ4_stream_t*)ALLOCATOR(1, sizeof(LZ4_stream_t)); /* malloc-calloc always properly aligned */ #else LZ4_stream_t ctxBody; - void* ctx = &ctxBody; + LZ4_stream_t* ctx = &ctxBody; #endif int result = LZ4_compress_destSize_extState(ctx, src, dst, srcSizePtr, targetDstSize); @@ -935,7 +918,7 @@ int LZ4_compress_destSize(const char* src, char* dst, int* srcSizePtr, int targe -/******************************** +/*-****************************** * Streaming functions ********************************/ @@ -959,10 +942,10 @@ int LZ4_freeStream (LZ4_stream_t* LZ4_stream) } -#define HASH_UNIT sizeof(size_t) +#define HASH_UNIT sizeof(reg_t) int LZ4_loadDict (LZ4_stream_t* LZ4_dict, const char* dictionary, int dictSize) { - LZ4_stream_t_internal* dict = (LZ4_stream_t_internal*) LZ4_dict; + LZ4_stream_t_internal* dict = &LZ4_dict->internal_donotuse; const BYTE* p = (const BYTE*)dictionary; const BYTE* const dictEnd = p + dictSize; const BYTE* base; @@ -970,8 +953,7 @@ int LZ4_loadDict (LZ4_stream_t* LZ4_dict, const char* dictionary, int dictSize) if ((dict->initCheck) || (dict->currentOffset > 1 GB)) /* Uninitialized structure, or reuse overflow */ LZ4_resetStream(LZ4_dict); - if (dictSize < (int)HASH_UNIT) - { + if (dictSize < (int)HASH_UNIT) { dict->dictionary = NULL; dict->dictSize = 0; return 0; @@ -984,8 +966,7 @@ int LZ4_loadDict (LZ4_stream_t* LZ4_dict, const char* dictionary, int dictSize) dict->dictSize = (U32)(dictEnd - p); dict->currentOffset += dict->dictSize; - while (p <= dictEnd-HASH_UNIT) - { + while (p <= dictEnd-HASH_UNIT) { LZ4_putPosition(p, dict->hashTable, byU32, base); p+=3; } @@ -997,14 +978,12 @@ int LZ4_loadDict (LZ4_stream_t* LZ4_dict, const char* dictionary, int dictSize) static void LZ4_renormDictT(LZ4_stream_t_internal* LZ4_dict, const BYTE* src) { if ((LZ4_dict->currentOffset > 0x80000000) || - ((size_t)LZ4_dict->currentOffset > (size_t)src)) /* address space overflow */ - { + ((uptrval)LZ4_dict->currentOffset > (uptrval)src)) { /* address space overflow */ /* rescale hash table */ - U32 delta = LZ4_dict->currentOffset - 64 KB; + U32 const delta = LZ4_dict->currentOffset - 64 KB; const BYTE* dictEnd = LZ4_dict->dictionary + LZ4_dict->dictSize; int i; - for (i=0; i<HASH_SIZE_U32; i++) - { + for (i=0; i<LZ4_HASH_SIZE_U32; i++) { if (LZ4_dict->hashTable[i] < delta) LZ4_dict->hashTable[i]=0; else LZ4_dict->hashTable[i] -= delta; } @@ -1017,7 +996,7 @@ static void LZ4_renormDictT(LZ4_stream_t_internal* LZ4_dict, const BYTE* src) int LZ4_compress_fast_continue (LZ4_stream_t* LZ4_stream, const char* source, char* dest, int inputSize, int maxOutputSize, int acceleration) { - LZ4_stream_t_internal* streamPtr = (LZ4_stream_t_internal*)LZ4_stream; + LZ4_stream_t_internal* streamPtr = &LZ4_stream->internal_donotuse; const BYTE* const dictEnd = streamPtr->dictionary + streamPtr->dictSize; const BYTE* smallest = (const BYTE*) source; @@ -1027,10 +1006,8 @@ int LZ4_compress_fast_continue (LZ4_stream_t* LZ4_stream, const char* source, ch if (acceleration < 1) acceleration = ACCELERATION_DEFAULT; /* Check overlapping input/dictionary space */ - { - const BYTE* sourceEnd = (const BYTE*) source + inputSize; - if ((sourceEnd > streamPtr->dictionary) && (sourceEnd < dictEnd)) - { + { const BYTE* sourceEnd = (const BYTE*) source + inputSize; + if ((sourceEnd > streamPtr->dictionary) && (sourceEnd < dictEnd)) { streamPtr->dictSize = (U32)(dictEnd - sourceEnd); if (streamPtr->dictSize > 64 KB) streamPtr->dictSize = 64 KB; if (streamPtr->dictSize < 4) streamPtr->dictSize = 0; @@ -1039,25 +1016,23 @@ int LZ4_compress_fast_continue (LZ4_stream_t* LZ4_stream, const char* source, ch } /* prefix mode : source data follows dictionary */ - if (dictEnd == (const BYTE*)source) - { + if (dictEnd == (const BYTE*)source) { int result; if ((streamPtr->dictSize < 64 KB) && (streamPtr->dictSize < streamPtr->currentOffset)) - result = LZ4_compress_generic(LZ4_stream, source, dest, inputSize, maxOutputSize, limitedOutput, byU32, withPrefix64k, dictSmall, acceleration); + result = LZ4_compress_generic(streamPtr, source, dest, inputSize, maxOutputSize, limitedOutput, byU32, withPrefix64k, dictSmall, acceleration); else - result = LZ4_compress_generic(LZ4_stream, source, dest, inputSize, maxOutputSize, limitedOutput, byU32, withPrefix64k, noDictIssue, acceleration); + result = LZ4_compress_generic(streamPtr, source, dest, inputSize, maxOutputSize, limitedOutput, byU32, withPrefix64k, noDictIssue, acceleration); streamPtr->dictSize += (U32)inputSize; streamPtr->currentOffset += (U32)inputSize; return result; } /* external dictionary mode */ - { - int result; + { int result; if ((streamPtr->dictSize < 64 KB) && (streamPtr->dictSize < streamPtr->currentOffset)) - result = LZ4_compress_generic(LZ4_stream, source, dest, inputSize, maxOutputSize, limitedOutput, byU32, usingExtDict, dictSmall, acceleration); + result = LZ4_compress_generic(streamPtr, source, dest, inputSize, maxOutputSize, limitedOutput, byU32, usingExtDict, dictSmall, acceleration); else - result = LZ4_compress_generic(LZ4_stream, source, dest, inputSize, maxOutputSize, limitedOutput, byU32, usingExtDict, noDictIssue, acceleration); + result = LZ4_compress_generic(streamPtr, source, dest, inputSize, maxOutputSize, limitedOutput, byU32, usingExtDict, noDictIssue, acceleration); streamPtr->dictionary = (const BYTE*)source; streamPtr->dictSize = (U32)inputSize; streamPtr->currentOffset += (U32)inputSize; @@ -1069,15 +1044,15 @@ int LZ4_compress_fast_continue (LZ4_stream_t* LZ4_stream, const char* source, ch /* Hidden debug function, to force external dictionary mode */ int LZ4_compress_forceExtDict (LZ4_stream_t* LZ4_dict, const char* source, char* dest, int inputSize) { - LZ4_stream_t_internal* streamPtr = (LZ4_stream_t_internal*)LZ4_dict; + LZ4_stream_t_internal* streamPtr = &LZ4_dict->internal_donotuse; int result; const BYTE* const dictEnd = streamPtr->dictionary + streamPtr->dictSize; const BYTE* smallest = dictEnd; if (smallest > (const BYTE*) source) smallest = (const BYTE*) source; - LZ4_renormDictT((LZ4_stream_t_internal*)LZ4_dict, smallest); + LZ4_renormDictT(streamPtr, smallest); - result = LZ4_compress_generic(LZ4_dict, source, dest, inputSize, 0, notLimited, byU32, usingExtDict, noDictIssue, 1); + result = LZ4_compress_generic(streamPtr, source, dest, inputSize, 0, notLimited, byU32, usingExtDict, noDictIssue, 1); streamPtr->dictionary = (const BYTE*)source; streamPtr->dictSize = (U32)inputSize; @@ -1087,10 +1062,17 @@ int LZ4_compress_forceExtDict (LZ4_stream_t* LZ4_dict, const char* source, char* } +/*! LZ4_saveDict() : + * If previously compressed data block is not guaranteed to remain available at its memory location, + * save it into a safer place (char* safeBuffer). + * Note : you don't need to call LZ4_loadDict() afterwards, + * dictionary is immediately usable, you can therefore call LZ4_compress_fast_continue(). + * Return : saved dictionary size in bytes (necessarily <= dictSize), or 0 if error. + */ int LZ4_saveDict (LZ4_stream_t* LZ4_dict, char* safeBuffer, int dictSize) { - LZ4_stream_t_internal* dict = (LZ4_stream_t_internal*) LZ4_dict; - const BYTE* previousDictEnd = dict->dictionary + dict->dictSize; + LZ4_stream_t_internal* const dict = &LZ4_dict->internal_donotuse; + const BYTE* const previousDictEnd = dict->dictionary + dict->dictSize; if ((U32)dictSize > 64 KB) dictSize = 64 KB; /* useless to define a dictionary > 64 KB */ if ((U32)dictSize > dict->dictSize) dictSize = dict->dictSize; @@ -1105,14 +1087,14 @@ int LZ4_saveDict (LZ4_stream_t* LZ4_dict, char* safeBuffer, int dictSize) -/******************************* +/*-***************************** * Decompression functions *******************************/ -/* - * This generic decompression function cover all use cases. - * It shall be instantiated several times, using different sets of directives - * Note that it is essential this generic function is really inlined, - * in order to remove useless branches during compilation optimization. +/*! LZ4_decompress_generic() : + * This generic decompression function cover all use cases. + * It shall be instantiated several times, using different sets of directives + * Note that it is important this generic function is really inlined, + * in order to remove useless branches during compilation optimization. */ FORCE_INLINE int LZ4_decompress_generic( const char* const source, @@ -1124,7 +1106,7 @@ FORCE_INLINE int LZ4_decompress_generic( int partialDecoding, /* full, partial */ int targetOutputSize, /* only used if partialDecoding==partial */ int dict, /* noDict, withPrefix64k, usingExtDict */ - const BYTE* const lowPrefix, /* == dest if dict == noDict */ + const BYTE* const lowPrefix, /* == dest when no prefix */ const BYTE* const dictStart, /* only if dict==usingExtDict */ const size_t dictSize /* note : = 0 if noDict */ ) @@ -1140,53 +1122,45 @@ FORCE_INLINE int LZ4_decompress_generic( const BYTE* const lowLimit = lowPrefix - dictSize; const BYTE* const dictEnd = (const BYTE*)dictStart + dictSize; - const size_t dec32table[] = {4, 1, 2, 1, 4, 4, 4, 4}; - const size_t dec64table[] = {0, 0, 0, (size_t)-1, 0, 1, 2, 3}; + const unsigned dec32table[] = {0, 1, 2, 1, 4, 4, 4, 4}; + const int dec64table[] = {0, 0, 0, -1, 0, 1, 2, 3}; const int safeDecode = (endOnInput==endOnInputSize); const int checkOffset = ((safeDecode) && (dictSize < (int)(64 KB))); /* Special cases */ - if ((partialDecoding) && (oexit> oend-MFLIMIT)) oexit = oend-MFLIMIT; /* targetOutputSize too high => decode everything */ + if ((partialDecoding) && (oexit > oend-MFLIMIT)) oexit = oend-MFLIMIT; /* targetOutputSize too high => decode everything */ if ((endOnInput) && (unlikely(outputSize==0))) return ((inputSize==1) && (*ip==0)) ? 0 : -1; /* Empty output buffer */ if ((!endOnInput) && (unlikely(outputSize==0))) return (*ip==0?1:-1); - - /* Main Loop */ - while (1) - { - unsigned token; + /* Main Loop : decode sequences */ + while (1) { size_t length; const BYTE* match; + size_t offset; /* get literal length */ - token = *ip++; - if ((length=(token>>ML_BITS)) == RUN_MASK) - { + unsigned const token = *ip++; + if ((length=(token>>ML_BITS)) == RUN_MASK) { unsigned s; - do - { + do { s = *ip++; length += s; - } - while (likely((endOnInput)?ip<iend-RUN_MASK:1) && (s==255)); - if ((safeDecode) && unlikely((size_t)(op+length)<(size_t)(op))) goto _output_error; /* overflow detection */ - if ((safeDecode) && unlikely((size_t)(ip+length)<(size_t)(ip))) goto _output_error; /* overflow detection */ + } while ( likely(endOnInput ? ip<iend-RUN_MASK : 1) & (s==255) ); + if ((safeDecode) && unlikely((uptrval)(op)+length<(uptrval)(op))) goto _output_error; /* overflow detection */ + if ((safeDecode) && unlikely((uptrval)(ip)+length<(uptrval)(ip))) goto _output_error; /* overflow detection */ } /* copy literals */ cpy = op+length; - if (((endOnInput) && ((cpy>(partialDecoding?oexit:oend-MFLIMIT)) || (ip+length>iend-(2+1+LASTLITERALS))) ) - || ((!endOnInput) && (cpy>oend-COPYLENGTH))) + if ( ((endOnInput) && ((cpy>(partialDecoding?oexit:oend-MFLIMIT)) || (ip+length>iend-(2+1+LASTLITERALS))) ) + || ((!endOnInput) && (cpy>oend-WILDCOPYLENGTH)) ) { - if (partialDecoding) - { + if (partialDecoding) { if (cpy > oend) goto _output_error; /* Error : write attempt beyond end of output buffer */ if ((endOnInput) && (ip+length > iend)) goto _output_error; /* Error : read attempt beyond end of input buffer */ - } - else - { + } else { if ((!endOnInput) && (cpy != oend)) goto _output_error; /* Error : block decoding must stop exactly there */ if ((endOnInput) && ((ip+length != iend) || (cpy > oend))) goto _output_error; /* Error : input must be consumed */ } @@ -1199,84 +1173,76 @@ FORCE_INLINE int LZ4_decompress_generic( ip += length; op = cpy; /* get offset */ - match = cpy - LZ4_readLE16(ip); ip+=2; - if ((checkOffset) && (unlikely(match < lowLimit))) goto _output_error; /* Error : offset outside destination buffer */ + offset = LZ4_readLE16(ip); ip+=2; + match = op - offset; + if ((checkOffset) && (unlikely(match < lowLimit))) goto _output_error; /* Error : offset outside buffers */ + LZ4_write32(op, (U32)offset); /* costs ~1%; silence an msan warning when offset==0 */ /* get matchlength */ length = token & ML_MASK; - if (length == ML_MASK) - { + if (length == ML_MASK) { unsigned s; - do - { - if ((endOnInput) && (ip > iend-LASTLITERALS)) goto _output_error; + do { s = *ip++; + if ((endOnInput) && (ip > iend-LASTLITERALS)) goto _output_error; length += s; } while (s==255); - if ((safeDecode) && unlikely((size_t)(op+length)<(size_t)op)) goto _output_error; /* overflow detection */ + if ((safeDecode) && unlikely((uptrval)(op)+length<(uptrval)op)) goto _output_error; /* overflow detection */ } length += MINMATCH; /* check external dictionary */ - if ((dict==usingExtDict) && (match < lowPrefix)) - { + if ((dict==usingExtDict) && (match < lowPrefix)) { if (unlikely(op+length > oend-LASTLITERALS)) goto _output_error; /* doesn't respect parsing restriction */ - if (length <= (size_t)(lowPrefix-match)) - { + if (length <= (size_t)(lowPrefix-match)) { /* match can be copied as a single segment from external dictionary */ - match = dictEnd - (lowPrefix-match); - memmove(op, match, length); op += length; - } - else - { - /* match encompass external dictionary and current segment */ - size_t copySize = (size_t)(lowPrefix-match); + memmove(op, dictEnd - (lowPrefix-match), length); + op += length; + } else { + /* match encompass external dictionary and current block */ + size_t const copySize = (size_t)(lowPrefix-match); + size_t const restSize = length - copySize; memcpy(op, dictEnd - copySize, copySize); op += copySize; - copySize = length - copySize; - if (copySize > (size_t)(op-lowPrefix)) /* overlap within current segment */ - { - BYTE* const endOfMatch = op + copySize; + if (restSize > (size_t)(op-lowPrefix)) { /* overlap copy */ + BYTE* const endOfMatch = op + restSize; const BYTE* copyFrom = lowPrefix; while (op < endOfMatch) *op++ = *copyFrom++; - } - else - { - memcpy(op, lowPrefix, copySize); - op += copySize; - } - } + } else { + memcpy(op, lowPrefix, restSize); + op += restSize; + } } continue; } - /* copy repeated sequence */ + /* copy match within block */ cpy = op + length; - if (unlikely((op-match)<8)) - { - const size_t dec64 = dec64table[op-match]; + if (unlikely(offset<8)) { + const int dec64 = dec64table[offset]; op[0] = match[0]; op[1] = match[1]; op[2] = match[2]; op[3] = match[3]; - match += dec32table[op-match]; - LZ4_copy4(op+4, match); - op += 8; match -= dec64; - } else { LZ4_copy8(op, match); op+=8; match+=8; } - - if (unlikely(cpy>oend-12)) - { - if (cpy > oend-LASTLITERALS) goto _output_error; /* Error : last LASTLITERALS bytes must be literals */ - if (op < oend-8) - { - LZ4_wildCopy(op, match, oend-8); - match += (oend-8) - op; - op = oend-8; + match += dec32table[offset]; + memcpy(op+4, match, 4); + match -= dec64; + } else { LZ4_copy8(op, match); match+=8; } + op += 8; + + if (unlikely(cpy>oend-12)) { + BYTE* const oCopyLimit = oend-(WILDCOPYLENGTH-1); + if (cpy > oend-LASTLITERALS) goto _output_error; /* Error : last LASTLITERALS bytes must be literals (uncompressed) */ + if (op < oCopyLimit) { + LZ4_wildCopy(op, match, oCopyLimit); + match += oCopyLimit - op; + op = oCopyLimit; } while (op<cpy) *op++ = *match++; + } else { + LZ4_copy8(op, match); + if (length>16) LZ4_wildCopy(op+8, match+8, cpy); } - else - LZ4_wildCopy(op, match, cpy); op=cpy; /* correction */ } @@ -1308,15 +1274,7 @@ int LZ4_decompress_fast(const char* source, char* dest, int originalSize) } -/* streaming decompression functions */ - -typedef struct -{ - const BYTE* externalDict; - size_t extDictSize; - const BYTE* prefixEnd; - size_t prefixSize; -} LZ4_streamDecode_t_internal; +/*===== streaming decompression functions =====*/ /* * If you prefer dynamic allocation methods, @@ -1335,16 +1293,16 @@ int LZ4_freeStreamDecode (LZ4_streamDecode_t* LZ4_stream) return 0; } -/* - * LZ4_setStreamDecode - * Use this function to instruct where to find the dictionary +/*! + * LZ4_setStreamDecode() : + * Use this function to instruct where to find the dictionary. * This function is not necessary if previous data is still available where it was decoded. * Loading a size of 0 is allowed (same effect as no dictionary). * Return : 1 if OK, 0 if error */ int LZ4_setStreamDecode (LZ4_streamDecode_t* LZ4_streamDecode, const char* dictionary, int dictSize) { - LZ4_streamDecode_t_internal* lz4sd = (LZ4_streamDecode_t_internal*) LZ4_streamDecode; + LZ4_streamDecode_t_internal* lz4sd = &LZ4_streamDecode->internal_donotuse; lz4sd->prefixSize = (size_t) dictSize; lz4sd->prefixEnd = (const BYTE*) dictionary + dictSize; lz4sd->externalDict = NULL; @@ -1361,20 +1319,17 @@ int LZ4_setStreamDecode (LZ4_streamDecode_t* LZ4_streamDecode, const char* dicti */ int LZ4_decompress_safe_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* source, char* dest, int compressedSize, int maxOutputSize) { - LZ4_streamDecode_t_internal* lz4sd = (LZ4_streamDecode_t_internal*) LZ4_streamDecode; + LZ4_streamDecode_t_internal* lz4sd = &LZ4_streamDecode->internal_donotuse; int result; - if (lz4sd->prefixEnd == (BYTE*)dest) - { + if (lz4sd->prefixEnd == (BYTE*)dest) { result = LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, endOnInputSize, full, 0, usingExtDict, lz4sd->prefixEnd - lz4sd->prefixSize, lz4sd->externalDict, lz4sd->extDictSize); if (result <= 0) return result; lz4sd->prefixSize += result; lz4sd->prefixEnd += result; - } - else - { + } else { lz4sd->extDictSize = lz4sd->prefixSize; lz4sd->externalDict = lz4sd->prefixEnd - lz4sd->extDictSize; result = LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, @@ -1390,22 +1345,19 @@ int LZ4_decompress_safe_continue (LZ4_streamDecode_t* LZ4_streamDecode, const ch int LZ4_decompress_fast_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* source, char* dest, int originalSize) { - LZ4_streamDecode_t_internal* lz4sd = (LZ4_streamDecode_t_internal*) LZ4_streamDecode; + LZ4_streamDecode_t_internal* lz4sd = &LZ4_streamDecode->internal_donotuse; int result; - if (lz4sd->prefixEnd == (BYTE*)dest) - { + if (lz4sd->prefixEnd == (BYTE*)dest) { result = LZ4_decompress_generic(source, dest, 0, originalSize, endOnOutputSize, full, 0, usingExtDict, lz4sd->prefixEnd - lz4sd->prefixSize, lz4sd->externalDict, lz4sd->extDictSize); if (result <= 0) return result; lz4sd->prefixSize += originalSize; lz4sd->prefixEnd += originalSize; - } - else - { + } else { lz4sd->extDictSize = lz4sd->prefixSize; - lz4sd->externalDict = (BYTE*)dest - lz4sd->extDictSize; + lz4sd->externalDict = lz4sd->prefixEnd - lz4sd->extDictSize; result = LZ4_decompress_generic(source, dest, 0, originalSize, endOnOutputSize, full, 0, usingExtDict, (BYTE*)dest, lz4sd->externalDict, lz4sd->extDictSize); @@ -1429,8 +1381,7 @@ FORCE_INLINE int LZ4_decompress_usingDict_generic(const char* source, char* dest { if (dictSize==0) return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, safe, full, 0, noDict, (BYTE*)dest, NULL, 0); - if (dictStart+dictSize == dest) - { + if (dictStart+dictSize == dest) { if (dictSize >= (int)(64 KB - 1)) return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, safe, full, 0, withPrefix64k, (BYTE*)dest-64 KB, NULL, 0); return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, safe, full, 0, noDict, (BYTE*)dest-dictSize, NULL, 0); @@ -1455,7 +1406,7 @@ int LZ4_decompress_safe_forceExtDict(const char* source, char* dest, int compres } -/*************************************************** +/*=************************************************* * Obsolete Functions ***************************************************/ /* obsolete compression functions */ @@ -1480,29 +1431,29 @@ int LZ4_uncompress_unknownOutputSize (const char* source, char* dest, int isize, int LZ4_sizeofStreamState() { return LZ4_STREAMSIZE; } -static void LZ4_init(LZ4_stream_t_internal* lz4ds, BYTE* base) +static void LZ4_init(LZ4_stream_t* lz4ds, BYTE* base) { - MEM_INIT(lz4ds, 0, LZ4_STREAMSIZE); - lz4ds->bufferStart = base; + MEM_INIT(lz4ds, 0, sizeof(LZ4_stream_t)); + lz4ds->internal_donotuse.bufferStart = base; } int LZ4_resetStreamState(void* state, char* inputBuffer) { - if ((((size_t)state) & 3) != 0) return 1; /* Error : pointer is not aligned on 4-bytes boundary */ - LZ4_init((LZ4_stream_t_internal*)state, (BYTE*)inputBuffer); + if ((((uptrval)state) & 3) != 0) return 1; /* Error : pointer is not aligned on 4-bytes boundary */ + LZ4_init((LZ4_stream_t*)state, (BYTE*)inputBuffer); return 0; } void* LZ4_create (char* inputBuffer) { - void* lz4ds = ALLOCATOR(8, LZ4_STREAMSIZE_U64); - LZ4_init ((LZ4_stream_t_internal*)lz4ds, (BYTE*)inputBuffer); + LZ4_stream_t* lz4ds = (LZ4_stream_t*)ALLOCATOR(8, sizeof(LZ4_stream_t)); + LZ4_init (lz4ds, (BYTE*)inputBuffer); return lz4ds; } char* LZ4_slideInputBuffer (void* LZ4_Data) { - LZ4_stream_t_internal* ctx = (LZ4_stream_t_internal*)LZ4_Data; + LZ4_stream_t_internal* ctx = &((LZ4_stream_t*)LZ4_Data)->internal_donotuse; int dictSize = LZ4_saveDict((LZ4_stream_t*)LZ4_Data, (char*)ctx->bufferStart, 64 KB); return (char*)(ctx->bufferStart + dictSize); } @@ -1520,5 +1471,4 @@ int LZ4_decompress_fast_withPrefix64k(const char* source, char* dest, int origin } #endif /* LZ4_COMMONDEFS_ONLY */ - #endif /* NEED_COMPAT_LZ4 */ diff --git a/src/compat/compat-lz4.h b/src/compat/compat-lz4.h index 3e74002..0aae19c 100644 --- a/src/compat/compat-lz4.h +++ b/src/compat/compat-lz4.h @@ -1,7 +1,7 @@ /* - LZ4 - Fast LZ compression algorithm - Header File - Copyright (C) 2011-2015, Yann Collet. + * LZ4 - Fast LZ compression algorithm + * Header File + * Copyright (C) 2011-2016, Yann Collet. BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) @@ -29,34 +29,79 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. You can contact the author at : - - LZ4 source repository : https://github.com/Cyan4973/lz4 - - LZ4 public forum : https://groups.google.com/forum/#!forum/lz4c + - LZ4 homepage : http://www.lz4.org + - LZ4 source repository : https://github.com/lz4/lz4 */ -#pragma once +#ifndef LZ4_H_2983827168210 +#define LZ4_H_2983827168210 #if defined (__cplusplus) extern "C" { #endif +/* --- Dependency --- */ +#include <stddef.h> /* size_t */ + + +/** + Introduction + + LZ4 is lossless compression algorithm, providing compression speed at 400 MB/s per core, + scalable with multi-cores CPU. It features an extremely fast decoder, with speed in + multiple GB/s per core, typically reaching RAM speed limits on multi-core systems. + + The LZ4 compression library provides in-memory compression and decompression functions. + Compression can be done in: + - a single step (described as Simple Functions) + - a single step, reusing a context (described in Advanced Functions) + - unbounded multiple steps (described as Streaming compression) + + lz4.h provides block compression functions. It gives full buffer control to user. + Decompressing an lz4-compressed block also requires metadata (such as compressed size). + Each application is free to encode such metadata in whichever way it wants. + + An additional format, called LZ4 frame specification (doc/lz4_Frame_format.md), + take care of encoding standard metadata alongside LZ4-compressed blocks. + If your application requires interoperability, it's recommended to use it. + A library is provided to take care of it, see lz4frame.h. +*/ + +/*^*************************************************************** +* Export parameters +*****************************************************************/ /* - * lz4.h provides block compression functions, and gives full buffer control to programmer. - * If you need to generate inter-operable compressed data (respecting LZ4 frame specification), - * and can let the library handle its own memory, please use lz4frame.h instead. +* LZ4_DLL_EXPORT : +* Enable exporting of functions when building a Windows DLL */ +#if defined(LZ4_DLL_EXPORT) && (LZ4_DLL_EXPORT==1) +# define LZ4LIB_API __declspec(dllexport) +#elif defined(LZ4_DLL_IMPORT) && (LZ4_DLL_IMPORT==1) +# define LZ4LIB_API __declspec(dllimport) /* It isn't required but allows to generate better code, saving a function pointer load from the IAT and an indirect jump.*/ +#else +# define LZ4LIB_API +#endif -/************************************** -* Version -**************************************/ + +/*========== Version =========== */ #define LZ4_VERSION_MAJOR 1 /* for breaking interface changes */ #define LZ4_VERSION_MINOR 7 /* for new (non-breaking) interface capabilities */ -#define LZ4_VERSION_RELEASE 1 /* for tweaks, bug-fixes, or development */ +#define LZ4_VERSION_RELEASE 5 /* for tweaks, bug-fixes, or development */ + #define LZ4_VERSION_NUMBER (LZ4_VERSION_MAJOR *100*100 + LZ4_VERSION_MINOR *100 + LZ4_VERSION_RELEASE) -int LZ4_versionNumber (void); -/************************************** +#define LZ4_LIB_VERSION LZ4_VERSION_MAJOR.LZ4_VERSION_MINOR.LZ4_VERSION_RELEASE +#define LZ4_QUOTE(str) #str +#define LZ4_EXPAND_AND_QUOTE(str) LZ4_QUOTE(str) +#define LZ4_VERSION_STRING LZ4_EXPAND_AND_QUOTE(LZ4_LIB_VERSION) + +LZ4LIB_API int LZ4_versionNumber (void); +LZ4LIB_API const char* LZ4_versionString (void); + + +/*-************************************ * Tuning parameter **************************************/ -/* +/*! * LZ4_MEMORY_USAGE : * Memory usage formula : N->2^N Bytes (examples : 10 -> 1KB; 12 -> 4KB ; 16 -> 64KB; 20 -> 1MB; etc.) * Increasing memory usage improves compression ratio @@ -66,15 +111,10 @@ int LZ4_versionNumber (void); #define LZ4_MEMORY_USAGE 14 -/************************************** +/*-************************************ * Simple Functions **************************************/ - -int LZ4_compress_default(const char* source, char* dest, int sourceSize, int maxDestSize); -int LZ4_decompress_safe (const char* source, char* dest, int compressedSize, int maxDecompressedSize); - -/* -LZ4_compress_default() : +/*! LZ4_compress_default() : Compresses 'sourceSize' bytes from buffer 'source' into already allocated 'dest' buffer of size 'maxDestSize'. Compression is guaranteed to succeed if 'maxDestSize' >= LZ4_compressBound(sourceSize). @@ -86,9 +126,10 @@ LZ4_compress_default() : sourceSize : Max supported value is LZ4_MAX_INPUT_VALUE maxDestSize : full or partial size of buffer 'dest' (which must be already allocated) return : the number of bytes written into buffer 'dest' (necessarily <= maxOutputSize) - or 0 if compression fails + or 0 if compression fails */ +LZ4LIB_API int LZ4_compress_default(const char* source, char* dest, int sourceSize, int maxDestSize); -LZ4_decompress_safe() : +/*! LZ4_decompress_safe() : compressedSize : is the precise full size of the compressed block. maxDecompressedSize : is the size of destination buffer, which must be already allocated. return : the number of bytes decompressed into destination buffer (necessarily <= maxDecompressedSize) @@ -97,15 +138,16 @@ LZ4_decompress_safe() : This function is protected against buffer overflow exploits, including malicious data packets. It never writes outside output buffer, nor reads outside input buffer. */ +LZ4LIB_API int LZ4_decompress_safe (const char* source, char* dest, int compressedSize, int maxDecompressedSize); -/************************************** +/*-************************************ * Advanced Functions **************************************/ #define LZ4_MAX_INPUT_SIZE 0x7E000000 /* 2 113 929 216 bytes */ #define LZ4_COMPRESSBOUND(isize) ((unsigned)(isize) > (unsigned)LZ4_MAX_INPUT_SIZE ? 0 : (isize) + ((isize)/255) + 16) -/* +/*! LZ4_compressBound() : Provides the maximum size that LZ4 compression may output in a "worst case" scenario (input data not compressible) This function is primarily useful for memory allocation purposes (destination buffer size). @@ -115,9 +157,9 @@ LZ4_compressBound() : return : maximum output size in a "worst case" scenario or 0, if input size is too large ( > LZ4_MAX_INPUT_SIZE) */ -int LZ4_compressBound(int inputSize); +LZ4LIB_API int LZ4_compressBound(int inputSize); -/* +/*! LZ4_compress_fast() : Same as LZ4_compress_default(), but allows to select an "acceleration" factor. The larger the acceleration value, the faster the algorithm, but also the lesser the compression. @@ -125,21 +167,21 @@ LZ4_compress_fast() : An acceleration value of "1" is the same as regular LZ4_compress_default() Values <= 0 will be replaced by ACCELERATION_DEFAULT (see lz4.c), which is 1. */ -int LZ4_compress_fast (const char* source, char* dest, int sourceSize, int maxDestSize, int acceleration); +LZ4LIB_API int LZ4_compress_fast (const char* source, char* dest, int sourceSize, int maxDestSize, int acceleration); -/* +/*! LZ4_compress_fast_extState() : Same compression function, just using an externally allocated memory space to store compression state. Use LZ4_sizeofState() to know how much memory must be allocated, and allocate it on 8-bytes boundaries (using malloc() typically). Then, provide it as 'void* state' to compression function. */ -int LZ4_sizeofState(void); -int LZ4_compress_fast_extState (void* state, const char* source, char* dest, int inputSize, int maxDestSize, int acceleration); +LZ4LIB_API int LZ4_sizeofState(void); +LZ4LIB_API int LZ4_compress_fast_extState (void* state, const char* source, char* dest, int inputSize, int maxDestSize, int acceleration); -/* +/*! LZ4_compress_destSize() : Reverse the logic, by compressing as much data as possible from 'source' buffer into already allocated buffer 'dest' of size 'targetDestSize'. @@ -150,10 +192,10 @@ LZ4_compress_destSize() : return : Nb bytes written into 'dest' (necessarily <= targetDestSize) or 0 if compression fails */ -int LZ4_compress_destSize (const char* source, char* dest, int* sourceSizePtr, int targetDestSize); +LZ4LIB_API int LZ4_compress_destSize (const char* source, char* dest, int* sourceSizePtr, int targetDestSize); -/* +/*! LZ4_decompress_fast() : originalSize : is the original and therefore uncompressed size return : the number of bytes read from the source buffer (in other words, the compressed size) @@ -164,9 +206,9 @@ LZ4_decompress_fast() : However, it does not provide any protection against intentionally modified data stream (malicious input). Use this function in trusted environment only (data to decode comes from a trusted source). */ -int LZ4_decompress_fast (const char* source, char* dest, int originalSize); +LZ4LIB_API int LZ4_decompress_fast (const char* source, char* dest, int originalSize); -/* +/*! LZ4_decompress_safe_partial() : This function decompress a compressed block of size 'compressedSize' at position 'source' into destination buffer 'dest' of size 'maxDecompressedSize'. @@ -178,98 +220,73 @@ LZ4_decompress_safe_partial() : If the source stream is detected malformed, the function will stop decoding and return a negative result. This function never writes outside of output buffer, and never reads outside of input buffer. It is therefore protected against malicious data packets */ -int LZ4_decompress_safe_partial (const char* source, char* dest, int compressedSize, int targetOutputSize, int maxDecompressedSize); +LZ4LIB_API int LZ4_decompress_safe_partial (const char* source, char* dest, int compressedSize, int targetOutputSize, int maxDecompressedSize); -/*********************************************** +/*-********************************************* * Streaming Compression Functions ***********************************************/ -#define LZ4_STREAMSIZE_U64 ((1 << (LZ4_MEMORY_USAGE-3)) + 4) -#define LZ4_STREAMSIZE (LZ4_STREAMSIZE_U64 * sizeof(long long)) -/* - * LZ4_stream_t - * information structure to track an LZ4 stream. - * important : init this structure content before first use ! - * note : only allocated directly the structure if you are statically linking LZ4 - * If you are using liblz4 as a DLL, please use below construction methods instead. - */ -typedef struct { long long table[LZ4_STREAMSIZE_U64]; } LZ4_stream_t; +typedef union LZ4_stream_u LZ4_stream_t; /* incomplete type (defined later) */ -/* - * LZ4_resetStream - * Use this function to init an allocated LZ4_stream_t structure +/*! LZ4_createStream() and LZ4_freeStream() : + * LZ4_createStream() will allocate and initialize an `LZ4_stream_t` structure. + * LZ4_freeStream() releases its memory. */ -void LZ4_resetStream (LZ4_stream_t* streamPtr); +LZ4LIB_API LZ4_stream_t* LZ4_createStream(void); +LZ4LIB_API int LZ4_freeStream (LZ4_stream_t* streamPtr); -/* - * LZ4_createStream will allocate and initialize an LZ4_stream_t structure - * LZ4_freeStream releases its memory. - * In the context of a DLL (liblz4), please use these methods rather than the static struct. - * They are more future proof, in case of a change of LZ4_stream_t size. +/*! LZ4_resetStream() : + * An LZ4_stream_t structure can be allocated once and re-used multiple times. + * Use this function to init an allocated `LZ4_stream_t` structure and start a new compression. */ -LZ4_stream_t* LZ4_createStream(void); -int LZ4_freeStream (LZ4_stream_t* streamPtr); +LZ4LIB_API void LZ4_resetStream (LZ4_stream_t* streamPtr); -/* - * LZ4_loadDict - * Use this function to load a static dictionary into LZ4_stream. - * Any previous data will be forgotten, only 'dictionary' will remain in memory. - * Loading a size of 0 is allowed. - * Return : dictionary size, in bytes (necessarily <= 64 KB) +/*! LZ4_loadDict() : + * Use this function to load a static dictionary into LZ4_stream. + * Any previous data will be forgotten, only 'dictionary' will remain in memory. + * Loading a size of 0 is allowed. + * Return : dictionary size, in bytes (necessarily <= 64 KB) */ -int LZ4_loadDict (LZ4_stream_t* streamPtr, const char* dictionary, int dictSize); - -/* - * LZ4_compress_fast_continue - * Compress buffer content 'src', using data from previously compressed blocks as dictionary to improve compression ratio. - * Important : Previous data blocks are assumed to still be present and unmodified ! - * 'dst' buffer must be already allocated. - * If maxDstSize >= LZ4_compressBound(srcSize), compression is guaranteed to succeed, and runs faster. - * If not, and if compressed data cannot fit into 'dst' buffer size, compression stops, and function returns a zero. +LZ4LIB_API int LZ4_loadDict (LZ4_stream_t* streamPtr, const char* dictionary, int dictSize); + +/*! LZ4_compress_fast_continue() : + * Compress buffer content 'src', using data from previously compressed blocks as dictionary to improve compression ratio. + * Important : Previous data blocks are assumed to still be present and unmodified ! + * 'dst' buffer must be already allocated. + * If maxDstSize >= LZ4_compressBound(srcSize), compression is guaranteed to succeed, and runs faster. + * If not, and if compressed data cannot fit into 'dst' buffer size, compression stops, and function returns a zero. */ -int LZ4_compress_fast_continue (LZ4_stream_t* streamPtr, const char* src, char* dst, int srcSize, int maxDstSize, int acceleration); - -/* - * LZ4_saveDict - * If previously compressed data block is not guaranteed to remain available at its memory location - * save it into a safer place (char* safeBuffer) - * Note : you don't need to call LZ4_loadDict() afterwards, - * dictionary is immediately usable, you can therefore call LZ4_compress_fast_continue() - * Return : saved dictionary size in bytes (necessarily <= dictSize), or 0 if error +LZ4LIB_API int LZ4_compress_fast_continue (LZ4_stream_t* streamPtr, const char* src, char* dst, int srcSize, int maxDstSize, int acceleration); + +/*! LZ4_saveDict() : + * If previously compressed data block is not guaranteed to remain available at its memory location, + * save it into a safer place (char* safeBuffer). + * Note : you don't need to call LZ4_loadDict() afterwards, + * dictionary is immediately usable, you can therefore call LZ4_compress_fast_continue(). + * Return : saved dictionary size in bytes (necessarily <= dictSize), or 0 if error. */ -int LZ4_saveDict (LZ4_stream_t* streamPtr, char* safeBuffer, int dictSize); +LZ4LIB_API int LZ4_saveDict (LZ4_stream_t* streamPtr, char* safeBuffer, int dictSize); -/************************************************ +/*-********************************************** * Streaming Decompression Functions +* Bufferless synchronous API ************************************************/ +typedef union LZ4_streamDecode_u LZ4_streamDecode_t; /* incomplete type (defined later) */ -#define LZ4_STREAMDECODESIZE_U64 4 -#define LZ4_STREAMDECODESIZE (LZ4_STREAMDECODESIZE_U64 * sizeof(unsigned long long)) -typedef struct { unsigned long long table[LZ4_STREAMDECODESIZE_U64]; } LZ4_streamDecode_t; -/* - * LZ4_streamDecode_t - * information structure to track an LZ4 stream. - * init this structure content using LZ4_setStreamDecode or memset() before first use ! - * - * In the context of a DLL (liblz4) please prefer usage of construction methods below. - * They are more future proof, in case of a change of LZ4_streamDecode_t size in the future. - * LZ4_createStreamDecode will allocate and initialize an LZ4_streamDecode_t structure - * LZ4_freeStreamDecode releases its memory. - */ -LZ4_streamDecode_t* LZ4_createStreamDecode(void); -int LZ4_freeStreamDecode (LZ4_streamDecode_t* LZ4_stream); +/* creation / destruction of streaming decompression tracking structure */ +LZ4LIB_API LZ4_streamDecode_t* LZ4_createStreamDecode(void); +LZ4LIB_API int LZ4_freeStreamDecode (LZ4_streamDecode_t* LZ4_stream); -/* - * LZ4_setStreamDecode - * Use this function to instruct where to find the dictionary. - * Setting a size of 0 is allowed (same effect as reset). - * Return : 1 if OK, 0 if error +/*! LZ4_setStreamDecode() : + * Use this function to instruct where to find the dictionary. + * Setting a size of 0 is allowed (same effect as reset). + * @return : 1 if OK, 0 if error */ -int LZ4_setStreamDecode (LZ4_streamDecode_t* LZ4_streamDecode, const char* dictionary, int dictSize); +LZ4LIB_API int LZ4_setStreamDecode (LZ4_streamDecode_t* LZ4_streamDecode, const char* dictionary, int dictSize); -/* -*_continue() : +/*! +LZ4_decompress_*_continue() : These decoding functions allow decompression of multiple blocks in "streaming" mode. Previously decoded blocks *must* remain available at the memory position where they were decoded (up to 64 KB) In the case of a ring buffers, decoding buffer must be either : @@ -285,35 +302,120 @@ int LZ4_setStreamDecode (LZ4_streamDecode_t* LZ4_streamDecode, const char* dicti Whenever these conditions are not possible, save the last 64KB of decoded data into a safe buffer, and indicate where it is saved using LZ4_setStreamDecode() */ -int LZ4_decompress_safe_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* source, char* dest, int compressedSize, int maxDecompressedSize); -int LZ4_decompress_fast_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* source, char* dest, int originalSize); +LZ4LIB_API int LZ4_decompress_safe_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* source, char* dest, int compressedSize, int maxDecompressedSize); +LZ4LIB_API int LZ4_decompress_fast_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* source, char* dest, int originalSize); -/* -Advanced decoding functions : -*_usingDict() : - These decoding functions work the same as - a combination of LZ4_setStreamDecode() followed by LZ4_decompress_x_continue() - They are stand-alone. They don't need nor update an LZ4_streamDecode_t structure. -*/ -int LZ4_decompress_safe_usingDict (const char* source, char* dest, int compressedSize, int maxDecompressedSize, const char* dictStart, int dictSize); -int LZ4_decompress_fast_usingDict (const char* source, char* dest, int originalSize, const char* dictStart, int dictSize); +/*! LZ4_decompress_*_usingDict() : + * These decoding functions work the same as + * a combination of LZ4_setStreamDecode() followed by LZ4_decompress_*_continue() + * They are stand-alone, and don't need an LZ4_streamDecode_t structure. + */ +LZ4LIB_API int LZ4_decompress_safe_usingDict (const char* source, char* dest, int compressedSize, int maxDecompressedSize, const char* dictStart, int dictSize); +LZ4LIB_API int LZ4_decompress_fast_usingDict (const char* source, char* dest, int originalSize, const char* dictStart, int dictSize); + + +/*^********************************************** + * !!!!!! STATIC LINKING ONLY !!!!!! + ***********************************************/ +/*-************************************ + * Private definitions + ************************************** + * Do not use these definitions. + * They are exposed to allow static allocation of `LZ4_stream_t` and `LZ4_streamDecode_t`. + * Using these definitions will expose code to API and/or ABI break in future versions of the library. + **************************************/ +#define LZ4_HASHLOG (LZ4_MEMORY_USAGE-2) +#define LZ4_HASHTABLESIZE (1 << LZ4_MEMORY_USAGE) +#define LZ4_HASH_SIZE_U32 (1 << LZ4_HASHLOG) /* required as macro for static allocation */ + +#if defined(__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) +#include <stdint.h> + +typedef struct { + uint32_t hashTable[LZ4_HASH_SIZE_U32]; + uint32_t currentOffset; + uint32_t initCheck; + const uint8_t* dictionary; + uint8_t* bufferStart; /* obsolete, used for slideInputBuffer */ + uint32_t dictSize; +} LZ4_stream_t_internal; + +typedef struct { + const uint8_t* externalDict; + size_t extDictSize; + const uint8_t* prefixEnd; + size_t prefixSize; +} LZ4_streamDecode_t_internal; + +#else + +typedef struct { + unsigned int hashTable[LZ4_HASH_SIZE_U32]; + unsigned int currentOffset; + unsigned int initCheck; + const unsigned char* dictionary; + unsigned char* bufferStart; /* obsolete, used for slideInputBuffer */ + unsigned int dictSize; +} LZ4_stream_t_internal; + +typedef struct { + const unsigned char* externalDict; + size_t extDictSize; + const unsigned char* prefixEnd; + size_t prefixSize; +} LZ4_streamDecode_t_internal; + +#endif +/*! + * LZ4_stream_t : + * information structure to track an LZ4 stream. + * init this structure before first use. + * note : only use in association with static linking ! + * this definition is not API/ABI safe, + * and may change in a future version ! + */ +#define LZ4_STREAMSIZE_U64 ((1 << (LZ4_MEMORY_USAGE-3)) + 4) +#define LZ4_STREAMSIZE (LZ4_STREAMSIZE_U64 * sizeof(unsigned long long)) +union LZ4_stream_u { + unsigned long long table[LZ4_STREAMSIZE_U64]; + LZ4_stream_t_internal internal_donotuse; +} ; /* previously typedef'd to LZ4_stream_t */ + + +/*! + * LZ4_streamDecode_t : + * information structure to track an LZ4 stream during decompression. + * init this structure using LZ4_setStreamDecode (or memset()) before first use + * note : only use in association with static linking ! + * this definition is not API/ABI safe, + * and may change in a future version ! + */ +#define LZ4_STREAMDECODESIZE_U64 4 +#define LZ4_STREAMDECODESIZE (LZ4_STREAMDECODESIZE_U64 * sizeof(unsigned long long)) +union LZ4_streamDecode_u { + unsigned long long table[LZ4_STREAMDECODESIZE_U64]; + LZ4_streamDecode_t_internal internal_donotuse; +} ; /* previously typedef'd to LZ4_streamDecode_t */ -/************************************** +/*=************************************ * Obsolete Functions **************************************/ -/* Deprecate Warnings */ -/* Should these warnings messages be a problem, +/* Deprecation warnings */ +/* Should these warnings be a problem, it is generally possible to disable them, - with -Wno-deprecated-declarations for gcc - or _CRT_SECURE_NO_WARNINGS in Visual for example. - You can also define LZ4_DEPRECATE_WARNING_DEFBLOCK. */ -#ifndef LZ4_DEPRECATE_WARNING_DEFBLOCK -# define LZ4_DEPRECATE_WARNING_DEFBLOCK + typically with -Wno-deprecated-declarations for gcc + or _CRT_SECURE_NO_WARNINGS in Visual. + Otherwise, it's also possible to define LZ4_DISABLE_DEPRECATE_WARNINGS */ +#ifdef LZ4_DISABLE_DEPRECATE_WARNINGS +# define LZ4_DEPRECATED(message) /* disable deprecation warnings */ +#else # define LZ4_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) -# if (LZ4_GCC_VERSION >= 405) || defined(__clang__) +# if defined (__cplusplus) && (__cplusplus >= 201402) /* C++14 or greater */ +# define LZ4_DEPRECATED(message) [[deprecated(message)]] +# elif (LZ4_GCC_VERSION >= 405) || defined(__clang__) # define LZ4_DEPRECATED(message) __attribute__((deprecated(message))) # elif (LZ4_GCC_VERSION >= 301) # define LZ4_DEPRECATED(message) __attribute__((deprecated)) @@ -323,20 +425,19 @@ int LZ4_decompress_fast_usingDict (const char* source, char* dest, int originalS # pragma message("WARNING: You need to implement LZ4_DEPRECATED for this compiler") # define LZ4_DEPRECATED(message) # endif -#endif /* LZ4_DEPRECATE_WARNING_DEFBLOCK */ +#endif /* LZ4_DISABLE_DEPRECATE_WARNINGS */ /* Obsolete compression functions */ -/* These functions are planned to start generate warnings by r131 approximately */ -int LZ4_compress (const char* source, char* dest, int sourceSize); -int LZ4_compress_limitedOutput (const char* source, char* dest, int sourceSize, int maxOutputSize); -int LZ4_compress_withState (void* state, const char* source, char* dest, int inputSize); -int LZ4_compress_limitedOutput_withState (void* state, const char* source, char* dest, int inputSize, int maxOutputSize); -int LZ4_compress_continue (LZ4_stream_t* LZ4_streamPtr, const char* source, char* dest, int inputSize); -int LZ4_compress_limitedOutput_continue (LZ4_stream_t* LZ4_streamPtr, const char* source, char* dest, int inputSize, int maxOutputSize); +LZ4_DEPRECATED("use LZ4_compress_default() instead") int LZ4_compress (const char* source, char* dest, int sourceSize); +LZ4_DEPRECATED("use LZ4_compress_default() instead") int LZ4_compress_limitedOutput (const char* source, char* dest, int sourceSize, int maxOutputSize); +LZ4_DEPRECATED("use LZ4_compress_fast_extState() instead") int LZ4_compress_withState (void* state, const char* source, char* dest, int inputSize); +LZ4_DEPRECATED("use LZ4_compress_fast_extState() instead") int LZ4_compress_limitedOutput_withState (void* state, const char* source, char* dest, int inputSize, int maxOutputSize); +LZ4_DEPRECATED("use LZ4_compress_fast_continue() instead") int LZ4_compress_continue (LZ4_stream_t* LZ4_streamPtr, const char* source, char* dest, int inputSize); +LZ4_DEPRECATED("use LZ4_compress_fast_continue() instead") int LZ4_compress_limitedOutput_continue (LZ4_stream_t* LZ4_streamPtr, const char* source, char* dest, int inputSize, int maxOutputSize); /* Obsolete decompression functions */ /* These function names are completely deprecated and must no longer be used. - They are only provided here for compatibility with older programs. + They are only provided in lz4.c for compatibility with older programs. - LZ4_uncompress is the same as LZ4_decompress_fast - LZ4_uncompress_unknownOutputSize is the same as LZ4_decompress_safe These function prototypes are now disabled; uncomment them only if you really need them. @@ -358,3 +459,5 @@ LZ4_DEPRECATED("use LZ4_decompress_fast_usingDict() instead") int LZ4_decompress #if defined (__cplusplus) } #endif + +#endif /* LZ4_H_2983827168210 */ diff --git a/src/openvpn/Makefile.am b/src/openvpn/Makefile.am index fcc22d6..f3bf52f 100644 --- a/src/openvpn/Makefile.am +++ b/src/openvpn/Makefile.am @@ -5,7 +5,7 @@ # packet encryption, packet authentication, and # packet compression. # -# Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> +# Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> # Copyright (C) 2006-2012 Alon Bar-Lev <alon.barlev@gmail.com> # @@ -132,5 +132,5 @@ openvpn_LDADD = \ $(OPTIONAL_DL_LIBS) if WIN32 openvpn_SOURCES += openvpn_win32_resources.rc block_dns.c block_dns.h -openvpn_LDADD += -lgdi32 -lws2_32 -lwininet -lcrypt32 -liphlpapi -lwinmm -lfwpuclnt -lrpcrt4 +openvpn_LDADD += -lgdi32 -lws2_32 -lwininet -lcrypt32 -liphlpapi -lwinmm -lfwpuclnt -lrpcrt4 -lncrypt endif diff --git a/src/openvpn/Makefile.in b/src/openvpn/Makefile.in index ca4635b..69fa9c8 100644 --- a/src/openvpn/Makefile.in +++ b/src/openvpn/Makefile.in @@ -21,7 +21,7 @@ # packet encryption, packet authentication, and # packet compression. # -# Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> +# Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> # Copyright (C) 2006-2012 Alon Bar-Lev <alon.barlev@gmail.com> # @@ -115,7 +115,7 @@ host_triplet = @host@ @WIN32_TRUE@am__append_1 = -municode -UUNICODE sbin_PROGRAMS = openvpn$(EXEEXT) @WIN32_TRUE@am__append_2 = openvpn_win32_resources.rc block_dns.c block_dns.h -@WIN32_TRUE@am__append_3 = -lgdi32 -lws2_32 -lwininet -lcrypt32 -liphlpapi -lwinmm -lfwpuclnt -lrpcrt4 +@WIN32_TRUE@am__append_3 = -lgdi32 -lws2_32 -lwininet -lcrypt32 -liphlpapi -lwinmm -lfwpuclnt -lrpcrt4 -lncrypt subdir = src/openvpn ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_emptyarray.m4 \ @@ -434,6 +434,7 @@ plugindir = @plugindir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ +runstatedir = @runstatedir@ sampledir = @sampledir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ diff --git a/src/openvpn/argv.c b/src/openvpn/argv.c index a71d261..124e1c4 100644 --- a/src/openvpn/argv.c +++ b/src/openvpn/argv.c @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -36,6 +36,7 @@ #include "syshead.h" #include "argv.h" +#include "integer.h" #include "options.h" static void diff --git a/src/openvpn/argv.h b/src/openvpn/argv.h index 7d0754c..9d9f387 100644 --- a/src/openvpn/argv.h +++ b/src/openvpn/argv.h @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/basic.h b/src/openvpn/basic.h index 3aa69ca..eb9f211 100644 --- a/src/openvpn/basic.h +++ b/src/openvpn/basic.h @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/block_dns.c b/src/openvpn/block_dns.c index d43cbcf..889d6bb 100644 --- a/src/openvpn/block_dns.c +++ b/src/openvpn/block_dns.c @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * 2015-2016 <iam@valdikss.org.ru> * 2016 Selva Nair <selva.nair@gmail.com> * @@ -344,33 +344,43 @@ delete_block_dns_filters(HANDLE engine_handle) } /* - * Returns interface metric value for specified interface index. + * Return interface metric value for the specified interface index. * * Arguments: * index : The index of TAP adapter. * family : Address family (AF_INET for IPv4 and AF_INET6 for IPv6). - * Returns positive metric value or zero for automatic metric on success, - * a less then zero error code on failure. + * is_auto : On return set to true if automatic metric is in use. + * Unused if NULL. + * + * Returns positive metric value or -1 on error. */ - int -get_interface_metric(const NET_IFINDEX index, const ADDRESS_FAMILY family) +get_interface_metric(const NET_IFINDEX index, const ADDRESS_FAMILY family, int *is_auto) { DWORD err = 0; MIB_IPINTERFACE_ROW ipiface; InitializeIpInterfaceEntry(&ipiface); ipiface.Family = family; ipiface.InterfaceIndex = index; + + if (is_auto) + { + *is_auto = 0; + } err = GetIpInterfaceEntry(&ipiface); - if (err == NO_ERROR) + + /* On Windows metric is never > INT_MAX so return value of int is ok. + * But we check for overflow nevertheless. + */ + if (err == NO_ERROR && ipiface.Metric <= INT_MAX) { - if (ipiface.UseAutomaticMetric) + if (is_auto) { - return 0; + *is_auto = ipiface.UseAutomaticMetric; } - return ipiface.Metric; + return (int)ipiface.Metric; } - return -err; + return -1; } /* diff --git a/src/openvpn/block_dns.h b/src/openvpn/block_dns.h index c4b6693..50b383f 100644 --- a/src/openvpn/block_dns.h +++ b/src/openvpn/block_dns.h @@ -26,7 +26,7 @@ #ifndef OPENVPN_BLOCK_DNS_H #define OPENVPN_BLOCK_DNS_H -/* Any value less than 5 should work fine. 3 is choosen without any real reason. */ +/* Any value less than 5 should work fine. 3 is chosen without any real reason. */ #define BLOCK_DNS_IFACE_METRIC 3 typedef void (*block_dns_msg_handler_t) (DWORD err, const char *msg); @@ -39,17 +39,17 @@ add_block_dns_filters(HANDLE *engine, int iface_index, const WCHAR *exe_path, block_dns_msg_handler_t msg_handler_callback); /** - * Returns interface metric value for specified interface index. + * Return interface metric value for the specified interface index. * - * @param index The index of TAP adapter - * @param family Address family (AF_INET for IPv4 and AF_INET6 for IPv6) + * @param index The index of TAP adapter. + * @param family Address family (AF_INET for IPv4 and AF_INET6 for IPv6). + * @param is_auto On return set to true if automatic metric is in use. + * Unused if NULL. * - * @return positive metric value or zero for automatic metric on success, - * a less then zero error code on failure. + * @return positive interface metric on success or -1 on error */ - int -get_interface_metric(const NET_IFINDEX index, const ADDRESS_FAMILY family); +get_interface_metric(const NET_IFINDEX index, const ADDRESS_FAMILY family, int *is_auto); /** * Sets interface metric value for specified interface index. diff --git a/src/openvpn/buffer.c b/src/openvpn/buffer.c index 87e27ec..f2ab066 100644 --- a/src/openvpn/buffer.c +++ b/src/openvpn/buffer.c @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -180,7 +180,7 @@ buf_assign(struct buffer *dest, const struct buffer *src) } struct buffer -clear_buf() +clear_buf(void) { struct buffer buf; CLEAR(buf); @@ -1177,7 +1177,7 @@ buffer_list_reset(struct buffer_list *ol) } void -buffer_list_push(struct buffer_list *ol, const unsigned char *str) +buffer_list_push(struct buffer_list *ol, const char *str) { if (str) { @@ -1191,7 +1191,7 @@ buffer_list_push(struct buffer_list *ol, const unsigned char *str) } struct buffer_entry * -buffer_list_push_data(struct buffer_list *ol, const uint8_t *data, size_t size) +buffer_list_push_data(struct buffer_list *ol, const void *data, size_t size) { struct buffer_entry *e = NULL; if (data && (!ol->max_size || ol->size < ol->max_size)) @@ -1231,7 +1231,8 @@ buffer_list_peek(struct buffer_list *ol) } void -buffer_list_aggregate_separator(struct buffer_list *bl, const size_t max, const char *sep) +buffer_list_aggregate_separator(struct buffer_list *bl, const size_t max_len, + const char *sep) { int sep_len = strlen(sep); @@ -1240,9 +1241,15 @@ buffer_list_aggregate_separator(struct buffer_list *bl, const size_t max, const struct buffer_entry *more = bl->head; size_t size = 0; int count = 0; - for (count = 0; more && size <= max; ++count) + for (count = 0; more; ++count) { - size += BLEN(&more->buf) + sep_len; + size_t extra_len = BLEN(&more->buf) + sep_len; + if (size + extra_len > max_len) + { + break; + } + + size += extra_len; more = more->next; } @@ -1252,8 +1259,7 @@ buffer_list_aggregate_separator(struct buffer_list *bl, const size_t max, const struct buffer_entry *e = bl->head, *f; ALLOC_OBJ_CLEAR(f, struct buffer_entry); - f->buf.data = malloc(size); - check_malloc_return(f->buf.data); + f->buf = alloc_buf(size + 1); /* prevent 0-byte malloc */ f->buf.capacity = size; for (i = 0; e && i < count; ++i) { @@ -1265,6 +1271,7 @@ buffer_list_aggregate_separator(struct buffer_list *bl, const size_t max, const e = next; } bl->head = f; + bl->size -= count - 1; f->next = more; if (!more) { @@ -1325,7 +1332,7 @@ buffer_list_file(const char *fn, int max_line_len) bl = buffer_list_new(0); while (fgets(line, max_line_len, fp) != NULL) { - buffer_list_push(bl, (unsigned char *)line); + buffer_list_push(bl, line); } free(line); } diff --git a/src/openvpn/buffer.h b/src/openvpn/buffer.h index 8bc4428..e37254c 100644 --- a/src/openvpn/buffer.h +++ b/src/openvpn/buffer.h @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -91,7 +91,7 @@ struct gc_entry }; /** - * Gargabe collection entry for a specially allocated structure that needs + * Garbage collection entry for a specially allocated structure that needs * a custom free function to be freed like struct addrinfo * */ @@ -1090,9 +1090,9 @@ bool buffer_list_defined(const struct buffer_list *ol); void buffer_list_reset(struct buffer_list *ol); -void buffer_list_push(struct buffer_list *ol, const unsigned char *str); +void buffer_list_push(struct buffer_list *ol, const char *str); -struct buffer_entry *buffer_list_push_data(struct buffer_list *ol, const uint8_t *data, size_t size); +struct buffer_entry *buffer_list_push_data(struct buffer_list *ol, const void *data, size_t size); struct buffer *buffer_list_peek(struct buffer_list *ol); @@ -1102,7 +1102,8 @@ void buffer_list_pop(struct buffer_list *ol); void buffer_list_aggregate(struct buffer_list *bl, const size_t max); -void buffer_list_aggregate_separator(struct buffer_list *bl, const size_t max, const char *sep); +void buffer_list_aggregate_separator(struct buffer_list *bl, + const size_t max_len, const char *sep); struct buffer_list *buffer_list_file(const char *fn, int max_line_len); diff --git a/src/openvpn/circ_list.h b/src/openvpn/circ_list.h index 386e18d..23b42d2 100644 --- a/src/openvpn/circ_list.h +++ b/src/openvpn/circ_list.h @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/clinat.c b/src/openvpn/clinat.c index 633cec6..b08fd54 100644 --- a/src/openvpn/clinat.c +++ b/src/openvpn/clinat.c @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/clinat.h b/src/openvpn/clinat.h index e0cfad5..eec7a03 100644 --- a/src/openvpn/clinat.h +++ b/src/openvpn/clinat.h @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/common.h b/src/openvpn/common.h index bb08c01..0f73200 100644 --- a/src/openvpn/common.h +++ b/src/openvpn/common.h @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/comp-lz4.c b/src/openvpn/comp-lz4.c index 6e40c32..f2916bd 100644 --- a/src/openvpn/comp-lz4.c +++ b/src/openvpn/comp-lz4.c @@ -5,8 +5,8 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> - * Copyright (C) 2013-2017 Gert Doering <gert@greenie.muc.de> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> + * Copyright (C) 2013-2018 Gert Doering <gert@greenie.muc.de> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -43,6 +43,7 @@ #include "memdbg.h" + static void lz4_compress_init(struct compress_context *compctx) { @@ -86,7 +87,7 @@ do_lz4_compress(struct buffer *buf, return false; } - zlen = LZ4_compress_limitedOutput((const char *)BPTR(buf), (char *)BPTR(work), BLEN(buf), zlen_max ); + zlen = LZ4_compress_default((const char *)BPTR(buf), (char *)BPTR(work), BLEN(buf), zlen_max); if (zlen <= 0) { @@ -185,7 +186,7 @@ lz4v2_compress(struct buffer *buf, struct buffer work, } } -void +static void do_lz4_decompress(size_t zlen_max, struct buffer *work, struct buffer *buf, diff --git a/src/openvpn/comp-lz4.h b/src/openvpn/comp-lz4.h index c256ba5..8c1ca3a 100644 --- a/src/openvpn/comp-lz4.h +++ b/src/openvpn/comp-lz4.h @@ -5,8 +5,8 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> - * Copyright (C) 2013-2017 Gert Doering <gert@greenie.muc.de> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> + * Copyright (C) 2013-2018 Gert Doering <gert@greenie.muc.de> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/comp.c b/src/openvpn/comp.c index 4cda7e5..a945913 100644 --- a/src/openvpn/comp.c +++ b/src/openvpn/comp.c @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/comp.h b/src/openvpn/comp.h index e56fd2b..0dadd1e 100644 --- a/src/openvpn/comp.h +++ b/src/openvpn/comp.h @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/compstub.c b/src/openvpn/compstub.c index ca90924..9123541 100644 --- a/src/openvpn/compstub.c +++ b/src/openvpn/compstub.c @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/console.c b/src/openvpn/console.c index eb6944d..4d49722 100644 --- a/src/openvpn/console.c +++ b/src/openvpn/console.c @@ -5,9 +5,9 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * Copyright (C) 2014-2015 David Sommerseth <davids@redhat.com> - * Copyright (C) 2016-2017 David Sommerseth <davids@openvpn.net> + * Copyright (C) 2016-2018 David Sommerseth <davids@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -44,7 +44,7 @@ struct _query_user query_user[QUERY_USER_NUMSLOTS]; /* GLOBAL */ void -query_user_clear() +query_user_clear(void) { int i; diff --git a/src/openvpn/console.h b/src/openvpn/console.h index aa51e6f..5a70e5f 100644 --- a/src/openvpn/console.h +++ b/src/openvpn/console.h @@ -5,9 +5,9 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * Copyright (C) 2014-2015 David Sommerseth <davids@redhat.com> - * Copyright (C) 2016-2017 David Sommerseth <davids@openvpn.net> + * Copyright (C) 2016-2018 David Sommerseth <davids@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -46,7 +46,7 @@ extern struct _query_user query_user[]; /**< Global variable, declared in conso * Wipes all data put into all of the query_user structs * */ -void query_user_clear(); +void query_user_clear(void); /** @@ -72,7 +72,7 @@ void query_user_add(char *prompt, size_t prompt_len, * * @return True if executing all the defined steps completed successfully */ -bool query_user_exec_builtin(); +bool query_user_exec_builtin(void); #if defined(ENABLE_SYSTEMD) @@ -83,7 +83,7 @@ bool query_user_exec_builtin(); * * @return True if executing all the defined steps completed successfully */ -bool query_user_exec(); +bool query_user_exec(void); #else /* ENABLE_SYSTEMD not defined*/ /** @@ -92,7 +92,7 @@ bool query_user_exec(); * */ static bool -query_user_exec() +query_user_exec(void) { return query_user_exec_builtin(); } diff --git a/src/openvpn/console_builtin.c b/src/openvpn/console_builtin.c index 7b95da9..445928b 100644 --- a/src/openvpn/console_builtin.c +++ b/src/openvpn/console_builtin.c @@ -5,9 +5,9 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * Copyright (C) 2014-2015 David Sommerseth <davids@redhat.com> - * Copyright (C) 2016-2017 David Sommerseth <davids@openvpn.net> + * Copyright (C) 2016-2018 David Sommerseth <davids@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -267,7 +267,7 @@ get_console_input(const char *prompt, const bool echo, char *input, const int ca * */ bool -query_user_exec_builtin() +query_user_exec_builtin(void) { bool ret = true; /* Presume everything goes okay */ int i; diff --git a/src/openvpn/console_systemd.c b/src/openvpn/console_systemd.c index 8cee8c8..e7a72ae 100644 --- a/src/openvpn/console_systemd.c +++ b/src/openvpn/console_systemd.c @@ -41,7 +41,7 @@ */ static bool -check_systemd_running() +check_systemd_running(void) { struct stat c; @@ -95,7 +95,7 @@ get_console_input_systemd(const char *prompt, const bool echo, char *input, cons * */ bool -query_user_exec() +query_user_exec(void) { bool ret = true; /* Presume everything goes okay */ int i; diff --git a/src/openvpn/crypto.c b/src/openvpn/crypto.c index 5f482d0..dba3aa5 100644 --- a/src/openvpn/crypto.c +++ b/src/openvpn/crypto.c @@ -5,8 +5,8 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> - * Copyright (C) 2010-2017 Fox Crypto B.V. <openvpn@fox-it.com> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> + * Copyright (C) 2010-2018 Fox Crypto B.V. <openvpn@fox-it.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -842,7 +842,7 @@ init_key_type(struct key_type *kt, const char *ciphername, /* given a key and key_type, build a key_ctx */ void -init_key_ctx(struct key_ctx *ctx, struct key *key, +init_key_ctx(struct key_ctx *ctx, const struct key *key, const struct key_type *kt, int enc, const char *prefix) { @@ -895,6 +895,26 @@ init_key_ctx(struct key_ctx *ctx, struct key *key, } void +init_key_ctx_bi(struct key_ctx_bi *ctx, const struct key2 *key2, + int key_direction, const struct key_type *kt, const char *name) +{ + char log_prefix[128] = { 0 }; + struct key_direction_state kds; + + key_direction_state_init(&kds, key_direction); + + openvpn_snprintf(log_prefix, sizeof(log_prefix), "Outgoing %s", name); + init_key_ctx(&ctx->encrypt, &key2->keys[kds.out_key], kt, + OPENVPN_OP_ENCRYPT, log_prefix); + + openvpn_snprintf(log_prefix, sizeof(log_prefix), "Incoming %s", name); + init_key_ctx(&ctx->decrypt, &key2->keys[kds.in_key], kt, + OPENVPN_OP_DECRYPT, log_prefix); + + ctx->initialized = true; +} + +void free_key_ctx(struct key_ctx *ctx) { if (ctx->cipher) @@ -1184,7 +1204,6 @@ crypto_read_openvpn_key(const struct key_type *key_type, { struct key2 key2; struct key_direction_state kds; - char log_prefix[128] = { 0 }; if (key_inline) { @@ -1209,13 +1228,7 @@ crypto_read_openvpn_key(const struct key_type *key_type, must_have_n_keys(key_file, opt_name, &key2, kds.need_keys); /* initialize key in both directions */ - openvpn_snprintf(log_prefix, sizeof(log_prefix), "Outgoing %s", key_name); - init_key_ctx(&ctx->encrypt, &key2.keys[kds.out_key], key_type, - OPENVPN_OP_ENCRYPT, log_prefix); - openvpn_snprintf(log_prefix, sizeof(log_prefix), "Incoming %s", key_name); - init_key_ctx(&ctx->decrypt, &key2.keys[kds.in_key], key_type, - OPENVPN_OP_DECRYPT, log_prefix); - + init_key_ctx_bi(ctx, &key2, key_direction, key_type, key_name); secure_memzero(&key2, sizeof(key2)); } @@ -1284,7 +1297,7 @@ read_key_file(struct key2 *key2, const char *file, const unsigned int flags) fd = platform_open(file, O_RDONLY, 0); if (fd == -1) { - msg(M_ERR, "Cannot open file key file '%s'", file); + msg(M_ERR, "Cannot open key file '%s'", file); } size = read(fd, in.data, in.capacity); if (size < 0) @@ -1557,11 +1570,18 @@ ascii2keydirection(int msglevel, const char *str) } const char * -keydirection2ascii(int kd, bool remote) +keydirection2ascii(int kd, bool remote, bool humanreadable) { if (kd == KEY_DIRECTION_BIDIRECTIONAL) { - return NULL; + if (humanreadable) + { + return "not set"; + } + else + { + return NULL; + } } else if (kd == KEY_DIRECTION_NORMAL) { @@ -1676,6 +1696,11 @@ read_key(struct key *key, const struct key_type *kt, struct buffer *buf) goto read_err; } + if (cipher_length != kt->cipher_length || hmac_length != kt->hmac_length) + { + goto key_len_err; + } + if (!buf_read(buf, key->cipher, cipher_length)) { goto read_err; @@ -1685,11 +1710,6 @@ read_key(struct key *key, const struct key_type *kt, struct buffer *buf) goto read_err; } - if (cipher_length != kt->cipher_length || hmac_length != kt->hmac_length) - { - goto key_len_err; - } - return 1; read_err: @@ -1716,7 +1736,7 @@ static int nonce_secret_len = 0; /* GLOBAL */ /* Reset the nonce value, also done periodically to refresh entropy */ static void -prng_reset_nonce() +prng_reset_nonce(void) { const int size = md_kt_size(nonce_md) + nonce_secret_len; #if 1 /* Must be 1 for real usage */ @@ -1795,7 +1815,7 @@ prng_bytes(uint8_t *output, int len) /* an analogue to the random() function, but use prng_bytes */ long int -get_random() +get_random(void) { long int l; prng_bytes((unsigned char *)&l, sizeof(l)); diff --git a/src/openvpn/crypto.h b/src/openvpn/crypto.h index 8818c01..e42f697 100644 --- a/src/openvpn/crypto.h +++ b/src/openvpn/crypto.h @@ -5,8 +5,8 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> - * Copyright (C) 2010-2017 Fox Crypto B.V. <openvpn@fox-it.com> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> + * Copyright (C) 2010-2018 Fox Crypto B.V. <openvpn@fox-it.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -317,12 +317,16 @@ void init_key_type(struct key_type *kt, const char *ciphername, * Key context functions */ -void init_key_ctx(struct key_ctx *ctx, struct key *key, +void init_key_ctx(struct key_ctx *ctx, const struct key *key, const struct key_type *kt, int enc, const char *prefix); void free_key_ctx(struct key_ctx *ctx); +void init_key_ctx_bi(struct key_ctx_bi *ctx, const struct key2 *key2, + int key_direction, const struct key_type *kt, + const char *name); + void free_key_ctx_bi(struct key_ctx_bi *ctx); @@ -459,7 +463,7 @@ void prng_init(const char *md_name, const int nonce_secret_len_parm); */ void prng_bytes(uint8_t *output, int len); -void prng_uninit(); +void prng_uninit(void); void test_crypto(struct crypto_options *co, struct frame *f); @@ -474,7 +478,7 @@ void must_have_n_keys(const char *filename, const char *option, const struct key int ascii2keydirection(int msglevel, const char *str); -const char *keydirection2ascii(int kd, bool remote); +const char *keydirection2ascii(int kd, bool remote, bool humanreadable); /* print keys */ void key2_print(const struct key2 *k, diff --git a/src/openvpn/crypto_backend.h b/src/openvpn/crypto_backend.h index b7f519b..1ee2980 100644 --- a/src/openvpn/crypto_backend.h +++ b/src/openvpn/crypto_backend.h @@ -5,8 +5,8 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> - * Copyright (C) 2010-2017 Fox Crypto B.V. <openvpn@fox-it.com> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> + * Copyright (C) 2010-2018 Fox Crypto B.V. <openvpn@fox-it.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -323,7 +323,7 @@ void cipher_ctx_free(cipher_ctx_t *ctx); * @param enc Whether to encrypt or decrypt (either * \c MBEDTLS_OP_ENCRYPT or \c MBEDTLS_OP_DECRYPT). */ -void cipher_ctx_init(cipher_ctx_t *ctx, uint8_t *key, int key_len, +void cipher_ctx_init(cipher_ctx_t *ctx, const uint8_t *key, int key_len, const cipher_kt_t *kt, int enc); /** diff --git a/src/openvpn/crypto_mbedtls.c b/src/openvpn/crypto_mbedtls.c index 24bc315..82a92af 100644 --- a/src/openvpn/crypto_mbedtls.c +++ b/src/openvpn/crypto_mbedtls.c @@ -5,8 +5,8 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> - * Copyright (C) 2010-2017 Fox Crypto B.V. <openvpn@fox-it.com> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> + * Copyright (C) 2010-2018 Fox Crypto B.V. <openvpn@fox-it.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -159,7 +159,7 @@ print_cipher(const cipher_kt_t *info) } void -show_available_ciphers() +show_available_ciphers(void) { const int *ciphers = mbedtls_cipher_list(); @@ -196,7 +196,7 @@ show_available_ciphers() } void -show_available_digests() +show_available_digests(void) { const int *digests = mbedtls_md_list(); @@ -223,7 +223,7 @@ show_available_digests() } void -show_available_engines() +show_available_engines(void) { printf("Sorry, mbed TLS hardware crypto engine functionality is not " "available\n"); @@ -243,7 +243,7 @@ show_available_engines() * entropy gathering function. */ mbedtls_ctr_drbg_context * -rand_ctx_get() +rand_ctx_get(void) { static mbedtls_entropy_context ec = {0}; static mbedtls_ctr_drbg_context cd_ctx = {0}; @@ -280,7 +280,7 @@ rand_ctx_get() #ifdef ENABLE_PREDICTION_RESISTANCE void -rand_ctx_enable_prediction_resistance() +rand_ctx_enable_prediction_resistance(void) { mbedtls_ctr_drbg_context *cd_ctx = rand_ctx_get(); @@ -523,7 +523,7 @@ cipher_ctx_free(mbedtls_cipher_context_t *ctx) } void -cipher_ctx_init(mbedtls_cipher_context_t *ctx, uint8_t *key, int key_len, +cipher_ctx_init(mbedtls_cipher_context_t *ctx, const uint8_t *key, int key_len, const mbedtls_cipher_info_t *kt, const mbedtls_operation_t operation) { ASSERT(NULL != kt && NULL != ctx); @@ -804,6 +804,7 @@ md_ctx_init(mbedtls_md_context_t *ctx, const mbedtls_md_info_t *kt) void md_ctx_cleanup(mbedtls_md_context_t *ctx) { + mbedtls_md_free(ctx); } int diff --git a/src/openvpn/crypto_mbedtls.h b/src/openvpn/crypto_mbedtls.h index a434ce3..452b06e 100644 --- a/src/openvpn/crypto_mbedtls.h +++ b/src/openvpn/crypto_mbedtls.h @@ -5,8 +5,8 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> - * Copyright (C) 2010-2017 Fox Crypto B.V. <openvpn@fox-it.com> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> + * Copyright (C) 2010-2018 Fox Crypto B.V. <openvpn@fox-it.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -85,13 +85,13 @@ typedef mbedtls_md_context_t hmac_ctx_t; * added. During initialisation, a personalisation string will be added based * on the time, the PID, and a pointer to the random context. */ -mbedtls_ctr_drbg_context *rand_ctx_get(); +mbedtls_ctr_drbg_context *rand_ctx_get(void); #ifdef ENABLE_PREDICTION_RESISTANCE /** * Enable prediction resistance on the random number generator. */ -void rand_ctx_enable_prediction_resistance(); +void rand_ctx_enable_prediction_resistance(void); #endif diff --git a/src/openvpn/crypto_openssl.c b/src/openvpn/crypto_openssl.c index a55e65c..eae2b91 100644 --- a/src/openvpn/crypto_openssl.c +++ b/src/openvpn/crypto_openssl.c @@ -5,8 +5,8 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> - * Copyright (C) 2010-2017 Fox Crypto B.V. <openvpn@fox-it.com> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> + * Copyright (C) 2010-2018 Fox Crypto B.V. <openvpn@fox-it.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -280,7 +280,7 @@ print_cipher(const EVP_CIPHER *cipher) } void -show_available_ciphers() +show_available_ciphers(void) { int nid; size_t i; @@ -339,7 +339,7 @@ show_available_ciphers() } void -show_available_digests() +show_available_digests(void) { int nid; @@ -364,7 +364,7 @@ show_available_digests() } void -show_available_engines() +show_available_engines(void) { #if HAVE_OPENSSL_ENGINE /* Only defined for OpenSSL */ ENGINE *e; @@ -665,7 +665,7 @@ cipher_ctx_free(EVP_CIPHER_CTX *ctx) } void -cipher_ctx_init(EVP_CIPHER_CTX *ctx, uint8_t *key, int key_len, +cipher_ctx_init(EVP_CIPHER_CTX *ctx, const uint8_t *key, int key_len, const EVP_CIPHER *kt, int enc) { ASSERT(NULL != kt && NULL != ctx); @@ -930,7 +930,7 @@ hmac_ctx_init(HMAC_CTX *ctx, const uint8_t *key, int key_len, { ASSERT(NULL != kt && NULL != ctx); - HMAC_CTX_init(ctx); + HMAC_CTX_reset(ctx); HMAC_Init_ex(ctx, key, key_len, kt, NULL); /* make sure we used a big enough key */ diff --git a/src/openvpn/crypto_openssl.h b/src/openvpn/crypto_openssl.h index 60a2812..0a41370 100644 --- a/src/openvpn/crypto_openssl.h +++ b/src/openvpn/crypto_openssl.h @@ -5,8 +5,8 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> - * Copyright (C) 2010-2017 Fox Crypto B.V. <openvpn@fox-it.com> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> + * Copyright (C) 2010-2018 Fox Crypto B.V. <openvpn@fox-it.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/cryptoapi.c b/src/openvpn/cryptoapi.c index d90cc5d..89d253c 100644 --- a/src/openvpn/cryptoapi.c +++ b/src/openvpn/cryptoapi.c @@ -42,11 +42,13 @@ #include <openssl/err.h> #include <windows.h> #include <wincrypt.h> +#include <ncrypt.h> #include <stdio.h> #include <ctype.h> #include <assert.h> #include "buffer.h" +#include "openssl_compat.h" /* MinGW w32api 3.17 is still incomplete when it comes to CryptoAPI while * MinGW32-w64 defines all macros used. This is a hack around that problem. @@ -82,6 +84,7 @@ #define CRYPTOAPI_F_CRYPT_SIGN_HASH 106 #define CRYPTOAPI_F_LOAD_LIBRARY 107 #define CRYPTOAPI_F_GET_PROC_ADDRESS 108 +#define CRYPTOAPI_F_NCRYPT_SIGN_HASH 109 static ERR_STRING_DATA CRYPTOAPI_str_functs[] = { { ERR_PACK(ERR_LIB_CRYPTOAPI, 0, 0), "microsoft cryptoapi"}, @@ -94,12 +97,13 @@ static ERR_STRING_DATA CRYPTOAPI_str_functs[] = { { ERR_PACK(0, CRYPTOAPI_F_CRYPT_SIGN_HASH, 0), "CryptSignHash" }, { ERR_PACK(0, CRYPTOAPI_F_LOAD_LIBRARY, 0), "LoadLibrary" }, { ERR_PACK(0, CRYPTOAPI_F_GET_PROC_ADDRESS, 0), "GetProcAddress" }, + { ERR_PACK(0, CRYPTOAPI_F_NCRYPT_SIGN_HASH, 0), "NCryptSignHash" }, { 0, NULL } }; typedef struct _CAPI_DATA { const CERT_CONTEXT *cert_context; - HCRYPTPROV crypt_prov; + HCRYPTPROV_OR_NCRYPT_KEY_HANDLE crypt_prov; DWORD key_spec; BOOL free_crypt_prov; } CAPI_DATA; @@ -209,26 +213,66 @@ rsa_pub_dec(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, in return 0; } +/** + * Sign the hash in 'from' using NCryptSignHash(). This requires an NCRYPT + * key handle in cd->crypt_prov. On return the signature is in 'to'. Returns + * the length of the signature or 0 on error. + * For now we support only RSA and the padding is assumed to be PKCS1 v1.5 + */ +static int +priv_enc_CNG(const CAPI_DATA *cd, const unsigned char *from, int flen, + unsigned char *to, int tlen, int padding) +{ + NCRYPT_KEY_HANDLE hkey = cd->crypt_prov; + DWORD len; + ASSERT(cd->key_spec == CERT_NCRYPT_KEY_SPEC); + + msg(D_LOW, "Signing hash using CNG: data size = %d", flen); + + /* The hash OID is already in 'from'. So set the hash algorithm + * in the padding info struct to NULL. + */ + BCRYPT_PKCS1_PADDING_INFO padinfo = {NULL}; + DWORD status; + + status = NCryptSignHash(hkey, padding? &padinfo : NULL, (BYTE*) from, flen, + to, tlen, &len, padding? BCRYPT_PAD_PKCS1 : 0); + if (status != ERROR_SUCCESS) + { + SetLastError(status); + CRYPTOAPIerr(CRYPTOAPI_F_NCRYPT_SIGN_HASH); + len = 0; + } + + /* Unlike CAPI, CNG signature is in big endian order. No reversing needed. */ + return len; +} + /* sign arbitrary data */ static int rsa_priv_enc(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) { - CAPI_DATA *cd = (CAPI_DATA *) rsa->meth->app_data; + CAPI_DATA *cd = (CAPI_DATA *) RSA_meth_get0_app_data(RSA_get_method(rsa)); HCRYPTHASH hash; DWORD hash_size, len, i; unsigned char *buf; if (cd == NULL) { - RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, ERR_R_PASSED_NULL_PARAMETER); + RSAerr(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, ERR_R_PASSED_NULL_PARAMETER); return 0; } if (padding != RSA_PKCS1_PADDING) { /* AFAICS, CryptSignHash() *always* uses PKCS1 padding. */ - RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, RSA_R_UNKNOWN_PADDING_TYPE); + RSAerr(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, RSA_R_UNKNOWN_PADDING_TYPE); return 0; } + if (cd->key_spec == CERT_NCRYPT_KEY_SPEC) + { + return priv_enc_CNG(cd, from, flen, to, RSA_size(rsa), padding); + } + /* Unfortunately, there is no "CryptSign()" function in CryptoAPI, that would * be way to straightforward for M$, I guess... So we have to do it this * tricky way instead, by creating a "Hash", and load the already-made hash @@ -236,7 +280,7 @@ rsa_priv_enc(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, i /* For now, we only support NID_md5_sha1 */ if (flen != SSL_SIG_LENGTH) { - RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, RSA_R_INVALID_MESSAGE_LENGTH); + RSAerr(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, RSA_R_INVALID_MESSAGE_LENGTH); return 0; } if (!CryptCreateHash(cd->crypt_prov, CALG_SSL3_SHAMD5, 0, 0, &hash)) @@ -253,7 +297,7 @@ rsa_priv_enc(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, i } if ((int) hash_size != flen) { - RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, RSA_R_INVALID_MESSAGE_LENGTH); + RSAerr(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, RSA_R_INVALID_MESSAGE_LENGTH); CryptDestroyHash(hash); return 0; } @@ -268,7 +312,7 @@ rsa_priv_enc(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, i buf = malloc(len); if (buf == NULL) { - RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, ERR_R_MALLOC_FAILURE); + RSAerr(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, ERR_R_MALLOC_FAILURE); CryptDestroyHash(hash); return 0; } @@ -312,7 +356,8 @@ init(RSA *rsa) static int finish(RSA *rsa) { - CAPI_DATA *cd = (CAPI_DATA *) rsa->meth->app_data; + const RSA_METHOD *rsa_meth = RSA_get_method(rsa); + CAPI_DATA *cd = (CAPI_DATA *) RSA_meth_get0_app_data(rsa_meth); if (cd == NULL) { @@ -320,15 +365,21 @@ finish(RSA *rsa) } if (cd->crypt_prov && cd->free_crypt_prov) { - CryptReleaseContext(cd->crypt_prov, 0); + if (cd->key_spec == CERT_NCRYPT_KEY_SPEC) + { + NCryptFreeObject(cd->crypt_prov); + } + else + { + CryptReleaseContext(cd->crypt_prov, 0); + } } if (cd->cert_context) { CertFreeCertificateContext(cd->cert_context); } - free(rsa->meth->app_data); - free((char *) rsa->meth); - rsa->meth = NULL; + free(cd); + RSA_meth_free((RSA_METHOD*) rsa_meth); return 1; } @@ -412,9 +463,9 @@ SSL_CTX_use_CryptoAPI_certificate(SSL_CTX *ssl_ctx, const char *cert_prop) X509 *cert = NULL; RSA *rsa = NULL, *pub_rsa; CAPI_DATA *cd = calloc(1, sizeof(*cd)); - RSA_METHOD *my_rsa_method = calloc(1, sizeof(*my_rsa_method)); + RSA_METHOD *my_rsa_method = NULL; - if (cd == NULL || my_rsa_method == NULL) + if (cd == NULL) { SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, ERR_R_MALLOC_FAILURE); goto err; @@ -457,8 +508,11 @@ SSL_CTX_use_CryptoAPI_certificate(SSL_CTX *ssl_ctx, const char *cert_prop) } /* set up stuff to use the private key */ - if (!CryptAcquireCertificatePrivateKey(cd->cert_context, CRYPT_ACQUIRE_COMPARE_KEY_FLAG, - NULL, &cd->crypt_prov, &cd->key_spec, &cd->free_crypt_prov)) + /* We prefer to get an NCRYPT key handle so that TLS1.2 can be supported */ + DWORD flags = CRYPT_ACQUIRE_COMPARE_KEY_FLAG + | CRYPT_ACQUIRE_PREFER_NCRYPT_KEY_FLAG; + if (!CryptAcquireCertificatePrivateKey(cd->cert_context, flags, NULL, + &cd->crypt_prov, &cd->key_spec, &cd->free_crypt_prov)) { /* if we don't have a smart card reader here, and we try to access a * smart card certificate, we get: @@ -469,15 +523,37 @@ SSL_CTX_use_CryptoAPI_certificate(SSL_CTX *ssl_ctx, const char *cert_prop) /* here we don't need to do CryptGetUserKey() or anything; all necessary key * info is in cd->cert_context, and then, in cd->crypt_prov. */ - my_rsa_method->name = "Microsoft CryptoAPI RSA Method"; - my_rsa_method->rsa_pub_enc = rsa_pub_enc; - my_rsa_method->rsa_pub_dec = rsa_pub_dec; - my_rsa_method->rsa_priv_enc = rsa_priv_enc; - my_rsa_method->rsa_priv_dec = rsa_priv_dec; - /* my_rsa_method->init = init; */ - my_rsa_method->finish = finish; - my_rsa_method->flags = RSA_METHOD_FLAG_NO_CHECK; - my_rsa_method->app_data = (char *) cd; + /* if we do not have an NCRYPT key handle restrict TLS to v1.1 or lower */ + int max_version = SSL_CTX_get_max_proto_version(ssl_ctx); + if ((!max_version || max_version > TLS1_1_VERSION) + && cd->key_spec != CERT_NCRYPT_KEY_SPEC) + { + msg(M_WARN, "WARNING: cryptoapicert: private key is in a legacy store." + " Restricting TLS version to 1.1"); + if (SSL_CTX_get_min_proto_version(ssl_ctx) > TLS1_1_VERSION) + { + msg(M_NONFATAL, + "ERROR: cryptoapicert: min TLS version larger than 1.1." + " Try config option --tls-version-min 1.1"); + goto err; + } + if (!SSL_CTX_set_max_proto_version(ssl_ctx, TLS1_1_VERSION)) + { + msg(M_NONFATAL, "ERROR: cryptoapicert: set max TLS version failed"); + goto err; + } + } + + my_rsa_method = RSA_meth_new("Microsoft Cryptography API RSA Method", + RSA_METHOD_FLAG_NO_CHECK); + check_malloc_return(my_rsa_method); + RSA_meth_set_pub_enc(my_rsa_method, rsa_pub_enc); + RSA_meth_set_pub_dec(my_rsa_method, rsa_pub_dec); + RSA_meth_set_priv_enc(my_rsa_method, rsa_priv_enc); + RSA_meth_set_priv_dec(my_rsa_method, rsa_priv_dec); + RSA_meth_set_init(my_rsa_method, NULL); + RSA_meth_set_finish(my_rsa_method, finish); + RSA_meth_set0_app_data(my_rsa_method, cd); rsa = RSA_new(); if (rsa == NULL) @@ -486,23 +562,35 @@ SSL_CTX_use_CryptoAPI_certificate(SSL_CTX *ssl_ctx, const char *cert_prop) goto err; } - /* cert->cert_info->key->pkey is NULL until we call SSL_CTX_use_certificate(), + /* Public key in cert is NULL until we call SSL_CTX_use_certificate(), * so we do it here then... */ if (!SSL_CTX_use_certificate(ssl_ctx, cert)) { goto err; } /* the public key */ - pub_rsa = cert->cert_info->key->pkey->pkey.rsa; + EVP_PKEY *pkey = X509_get0_pubkey(cert); + /* SSL_CTX_use_certificate() increased the reference count in 'cert', so * we decrease it here with X509_free(), or it will never be cleaned up. */ X509_free(cert); cert = NULL; - /* I'm not sure about what we have to fill in in the RSA, trying out stuff... */ - /* rsa->n indicates the key size */ - rsa->n = BN_dup(pub_rsa->n); - rsa->flags |= RSA_FLAG_EXT_PKEY; + if (!(pub_rsa = EVP_PKEY_get0_RSA(pkey))) + { + msg(M_WARN, "cryptoapicert requires an RSA certificate"); + goto err; + } + + /* Our private key is external, so we fill in only n and e from the public key */ + const BIGNUM *n = NULL; + const BIGNUM *e = NULL; + RSA_get0_key(pub_rsa, &n, &e, NULL); + if (!RSA_set0_key(rsa, BN_dup(n), BN_dup(e), NULL)) + { + goto err; + } + RSA_set_flags(rsa, RSA_flags(rsa) | RSA_FLAG_EXT_PKEY); if (!RSA_set_method(rsa, my_rsa_method)) { goto err; @@ -536,7 +624,14 @@ err: { if (cd->free_crypt_prov && cd->crypt_prov) { - CryptReleaseContext(cd->crypt_prov, 0); + if (cd->key_spec == CERT_NCRYPT_KEY_SPEC) + { + NCryptFreeObject(cd->crypt_prov); + } + else + { + CryptReleaseContext(cd->crypt_prov, 0); + } } if (cd->cert_context) { diff --git a/src/openvpn/dhcp.c b/src/openvpn/dhcp.c index a2a5454..fb28b27 100644 --- a/src/openvpn/dhcp.c +++ b/src/openvpn/dhcp.c @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/dhcp.h b/src/openvpn/dhcp.h index dc41658..32aa15e 100644 --- a/src/openvpn/dhcp.h +++ b/src/openvpn/dhcp.h @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/errlevel.h b/src/openvpn/errlevel.h index 5bb043b..5ca4fa8 100644 --- a/src/openvpn/errlevel.h +++ b/src/openvpn/errlevel.h @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/error.c b/src/openvpn/error.c index ce50ff9..bc14e8c 100644 --- a/src/openvpn/error.c +++ b/src/openvpn/error.c @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -159,7 +159,7 @@ set_machine_readable_output(bool parsable) } void -error_reset() +error_reset(void) { use_syslog = std_redir = false; suppress_timestamps = false; @@ -267,7 +267,7 @@ x_msg_va(const unsigned int flags, const char *format, va_list arglist) if ((flags & M_ERRNO) && e) { openvpn_snprintf(m2, ERR_BUF_SIZE, "%s: %s (errno=%d)", - m1, strerror_ts(e, &gc), e); + m1, strerror(e), e); SWAP; } @@ -342,8 +342,8 @@ x_msg_va(const unsigned int flags, const char *format, va_list arglist) struct timeval tv; gettimeofday(&tv, NULL); - fprintf(fp, "%lu.%06lu %x %s%s%s%s", - tv.tv_sec, + fprintf(fp, "%"PRIi64".%06lu %x %s%s%s%s", + (int64_t)tv.tv_sec, (unsigned long)tv.tv_usec, flags, prefix, @@ -480,7 +480,7 @@ open_syslog(const char *pgmname, bool stdio_to_null) } void -close_syslog() +close_syslog(void) { #if SYSLOG_CAPABILITY if (use_syslog) @@ -635,7 +635,7 @@ unsigned int x_cs_verbose_level; /* GLOBAL */ unsigned int x_cs_err_delay_ms; /* GLOBAL */ void -reset_check_status() +reset_check_status(void) { x_cs_info_level = 0; x_cs_verbose_level = 0; @@ -693,20 +693,15 @@ x_check_status(int status, { if (extended_msg) { - msg(x_cs_info_level, "%s %s [%s]: %s (code=%d)", - description, + msg(x_cs_info_level, "%s %s [%s]: %s (code=%d)", description, sock ? proto2ascii(sock->info.proto, sock->info.af, true) : "", - extended_msg, - strerror_ts(my_errno, &gc), - my_errno); + extended_msg, strerror(my_errno), my_errno); } else { - msg(x_cs_info_level, "%s %s: %s (code=%d)", - description, + msg(x_cs_info_level, "%s %s: %s (code=%d)", description, sock ? proto2ascii(sock->info.proto, sock->info.af, true) : "", - strerror_ts(my_errno, &gc), - my_errno); + strerror(my_errno), my_errno); } if (x_cs_err_delay_ms) diff --git a/src/openvpn/error.h b/src/openvpn/error.h index 14ef7e6..eaedf17 100644 --- a/src/openvpn/error.h +++ b/src/openvpn/error.h @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -261,7 +261,7 @@ void msg_forked(void); void open_syslog(const char *pgmname, bool stdio_to_null); -void close_syslog(); +void close_syslog(void); /* log file output */ void redirect_stdout_stderr(const char *file, bool append); diff --git a/src/openvpn/event.c b/src/openvpn/event.c index d123070..b22741f 100644 --- a/src/openvpn/event.c +++ b/src/openvpn/event.c @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/event.h b/src/openvpn/event.h index ff795f4..4af6371 100644 --- a/src/openvpn/event.h +++ b/src/openvpn/event.h @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/fdmisc.c b/src/openvpn/fdmisc.c index 56e2250..1cea505 100644 --- a/src/openvpn/fdmisc.c +++ b/src/openvpn/fdmisc.c @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/fdmisc.h b/src/openvpn/fdmisc.h index b6d7101..0fb8b93 100644 --- a/src/openvpn/fdmisc.h +++ b/src/openvpn/fdmisc.h @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/forward-inline.h b/src/openvpn/forward-inline.h index ab83ea4..7d06b4e 100644 --- a/src/openvpn/forward-inline.h +++ b/src/openvpn/forward-inline.h @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/forward.c b/src/openvpn/forward.c index 371ddca..8f90418 100644 --- a/src/openvpn/forward.c +++ b/src/openvpn/forward.c @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -496,7 +496,7 @@ encrypt_sign(struct context *c, bool comp_frag) /* If using P_DATA_V2, prepend the 1-byte opcode and 3-byte peer-id to the * packet before openvpn_encrypt(), so we can authenticate the opcode too. */ - if (c->c2.buf.len > 0 && !c->c2.tls_multi->opt.server && c->c2.tls_multi->use_peer_id) + if (c->c2.buf.len > 0 && c->c2.tls_multi->use_peer_id) { tls_prepend_opcode_v2(c->c2.tls_multi, &b->encrypt_buf); } @@ -512,7 +512,7 @@ encrypt_sign(struct context *c, bool comp_frag) /* Do packet administration */ if (c->c2.tls_multi) { - if (c->c2.buf.len > 0 && (c->c2.tls_multi->opt.server || !c->c2.tls_multi->use_peer_id)) + if (c->c2.buf.len > 0 && !c->c2.tls_multi->use_peer_id) { tls_prepend_opcode_v1(c->c2.tls_multi, &c->c2.buf); } @@ -756,7 +756,7 @@ read_incoming_link(struct context *c) if (event_timeout_defined(&c->c2.explicit_exit_notification_interval)) { msg(D_STREAM_ERRORS, "Connection reset during exit notification period, ignoring [%d]", status); - openvpn_sleep(1); + management_sleep(1); } else #endif @@ -1007,7 +1007,7 @@ process_incoming_link_part2(struct context *c, struct link_socket_info *lsi, con } } -void +static void process_incoming_link(struct context *c) { perf_push(PERF_PROC_IN_LINK); diff --git a/src/openvpn/forward.h b/src/openvpn/forward.h index 9fde5a3..924cc5e 100644 --- a/src/openvpn/forward.h +++ b/src/openvpn/forward.h @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/fragment.c b/src/openvpn/fragment.c index 38de62f..4eb1dd2 100644 --- a/src/openvpn/fragment.c +++ b/src/openvpn/fragment.c @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -208,7 +208,7 @@ fragment_incoming(struct fragment_master *f, struct buffer *buf, } /* is this the first fragment for our sequence number? */ - if (!frag->defined || (frag->defined && frag->max_frag_size != size)) + if (!frag->defined || frag->max_frag_size != size) { frag->defined = true; frag->max_frag_size = size; diff --git a/src/openvpn/fragment.h b/src/openvpn/fragment.h index 90ba8f7..6fa9692 100644 --- a/src/openvpn/fragment.h +++ b/src/openvpn/fragment.h @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/gremlin.c b/src/openvpn/gremlin.c index e85ce9c..114cb19 100644 --- a/src/openvpn/gremlin.c +++ b/src/openvpn/gremlin.c @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/gremlin.h b/src/openvpn/gremlin.h index 8b23b34..22c90b9 100644 --- a/src/openvpn/gremlin.h +++ b/src/openvpn/gremlin.h @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/helper.c b/src/openvpn/helper.c index 17d1528..ff9df50 100644 --- a/src/openvpn/helper.c +++ b/src/openvpn/helper.c @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/helper.h b/src/openvpn/helper.h index c5b438b..866a398 100644 --- a/src/openvpn/helper.h +++ b/src/openvpn/helper.h @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/httpdigest.c b/src/openvpn/httpdigest.c index c553f93..7cf74fd 100644 --- a/src/openvpn/httpdigest.c +++ b/src/openvpn/httpdigest.c @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/httpdigest.h b/src/openvpn/httpdigest.h index aae7b8c..959220f 100644 --- a/src/openvpn/httpdigest.h +++ b/src/openvpn/httpdigest.h @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/init.c b/src/openvpn/init.c index 0652ef4..6968c77 100644 --- a/src/openvpn/init.c +++ b/src/openvpn/init.c @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -94,6 +94,94 @@ context_clear_all_except_first_time(struct context *c) } /* + * Pass tunnel endpoint and MTU parms to a user-supplied script. + * Used to execute the up/down script/plugins. + */ +static void +run_up_down(const char *command, + const struct plugin_list *plugins, + int plugin_type, + const char *arg, +#ifdef _WIN32 + DWORD adapter_index, +#endif + const char *dev_type, + int tun_mtu, + int link_mtu, + const char *ifconfig_local, + const char *ifconfig_remote, + const char *context, + const char *signal_text, + const char *script_type, + struct env_set *es) +{ + struct gc_arena gc = gc_new(); + + if (signal_text) + { + setenv_str(es, "signal", signal_text); + } + setenv_str(es, "script_context", context); + setenv_int(es, "tun_mtu", tun_mtu); + setenv_int(es, "link_mtu", link_mtu); + setenv_str(es, "dev", arg); + if (dev_type) + { + setenv_str(es, "dev_type", dev_type); + } +#ifdef _WIN32 + setenv_int(es, "dev_idx", adapter_index); +#endif + + if (!ifconfig_local) + { + ifconfig_local = ""; + } + if (!ifconfig_remote) + { + ifconfig_remote = ""; + } + if (!context) + { + context = ""; + } + + if (plugin_defined(plugins, plugin_type)) + { + struct argv argv = argv_new(); + ASSERT(arg); + argv_printf(&argv, + "%s %d %d %s %s %s", + arg, + tun_mtu, link_mtu, + ifconfig_local, ifconfig_remote, + context); + + if (plugin_call(plugins, plugin_type, &argv, NULL, es) != OPENVPN_PLUGIN_FUNC_SUCCESS) + { + msg(M_FATAL, "ERROR: up/down plugin call failed"); + } + + argv_reset(&argv); + } + + if (command) + { + struct argv argv = argv_new(); + ASSERT(arg); + setenv_str(es, "script_type", script_type); + argv_parse_cmd(&argv, command); + argv_printf_cat(&argv, "%s %d %d %s %s %s", arg, tun_mtu, link_mtu, + ifconfig_local, ifconfig_remote, context); + argv_msg(M_INFO, &argv); + openvpn_run_script(&argv, es, S_FATAL, "--up/--down"); + argv_reset(&argv); + } + + gc_free(&gc); +} + +/* * Should be called after options->ce is modified at the top * of a SIGUSR1 restart. */ @@ -150,7 +238,7 @@ management_callback_proxy_cmd(void *arg, const char **p) else if (streq(p[1], "SOCKS")) { ce->socks_proxy_server = string_alloc(p[2], gc); - ce->socks_proxy_port = p[3]; + ce->socks_proxy_port = string_alloc(p[3], gc); ret = true; } } @@ -610,6 +698,7 @@ init_port_share(struct context *c) #endif /* if PORT_SHARE */ + bool init_static(void) { @@ -619,8 +708,20 @@ init_static(void) crypto_init_dmalloc(); #endif - init_random_seed(); /* init random() function, only used as - * source for weak random numbers */ + + /* + * Initialize random number seed. random() is only used + * when "weak" random numbers are acceptable. + * SSL library routines are always used when cryptographically + * strong random numbers are required. + */ + struct timeval tv; + if (!gettimeofday(&tv, NULL)) + { + const unsigned int seed = (unsigned int) tv.tv_sec ^ tv.tv_usec; + srandom(seed); + } + error_reset(); /* initialize error.c */ reset_check_status(); /* initialize status check code in socket.c */ @@ -915,7 +1016,8 @@ print_openssl_info(const struct options *options) } if (options->show_tls_ciphers) { - show_available_tls_ciphers(options->cipher_list); + show_available_tls_ciphers(options->cipher_list, + options->tls_cert_profile); } if (options->show_curves) { @@ -1904,7 +2006,7 @@ do_close_tun(struct context *c, bool force) } void -tun_abort() +tun_abort(void) { struct context *c = static_context; if (c) @@ -1969,7 +2071,7 @@ do_up(struct context *c, bool pulled_options, unsigned int option_types_found) /* if so, close tun, delete routes, then reinitialize tun and add routes */ msg(M_INFO, "NOTE: Pulled options changed on restart, will need to close and reopen TUN/TAP device."); do_close_tun(c, true); - openvpn_sleep(1); + management_sleep(1); c->c2.did_open_tun = do_open_tun(c); update_time(); } @@ -2263,7 +2365,7 @@ socket_restart_pause(struct context *c) if (sec) { msg(D_RESTART, "Restart pause, %d second(s)", sec); - openvpn_sleep(sec); + management_sleep(sec); } } @@ -3332,6 +3434,12 @@ do_close_tls(struct context *c) } c->c2.options_string_local = c->c2.options_string_remote = NULL; #endif + + if (c->c2.pulled_options_state) + { + md_ctx_cleanup(c->c2.pulled_options_state); + md_ctx_free(c->c2.pulled_options_state); + } #endif } diff --git a/src/openvpn/init.h b/src/openvpn/init.h index 15feb67..c8ebe76 100644 --- a/src/openvpn/init.h +++ b/src/openvpn/init.h @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/integer.h b/src/openvpn/integer.h index 240781b..a7e19d3 100644 --- a/src/openvpn/integer.h +++ b/src/openvpn/integer.h @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -118,6 +118,24 @@ modulo_add(int x, int y, int mod) return sum; } +/* + * Return the next largest power of 2 + * or u if u is a power of 2. + */ +static inline size_t +adjust_power_of_2(size_t u) +{ + size_t ret = 1; + + while (ret < u) + { + ret <<= 1; + ASSERT(ret > 0); + } + + return ret; +} + static inline int index_verify(int index, int size, const char *file, int line) { diff --git a/src/openvpn/interval.c b/src/openvpn/interval.c index 1634386..00ee627 100644 --- a/src/openvpn/interval.c +++ b/src/openvpn/interval.c @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/interval.h b/src/openvpn/interval.h index 8095c0b..826a08b 100644 --- a/src/openvpn/interval.h +++ b/src/openvpn/interval.h @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -155,7 +155,7 @@ event_timeout_clear(struct event_timeout *et) } static inline struct event_timeout -event_timeout_clear_ret() +event_timeout_clear_ret(void) { struct event_timeout ret; event_timeout_clear(&ret); diff --git a/src/openvpn/list.c b/src/openvpn/list.c index edca6f7..09e393a 100644 --- a/src/openvpn/list.c +++ b/src/openvpn/list.c @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -31,6 +31,7 @@ #if P2MP_SERVER +#include "integer.h" #include "list.h" #include "misc.h" diff --git a/src/openvpn/list.h b/src/openvpn/list.h index c808efa..b67301c 100644 --- a/src/openvpn/list.h +++ b/src/openvpn/list.h @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/lzo.c b/src/openvpn/lzo.c index f754865..8d9efea 100644 --- a/src/openvpn/lzo.c +++ b/src/openvpn/lzo.c @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/lzo.h b/src/openvpn/lzo.h index deaeb8d..11e1c39 100644 --- a/src/openvpn/lzo.h +++ b/src/openvpn/lzo.h @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/manage.c b/src/openvpn/manage.c index c2e8dc7..61d61ef 100644 --- a/src/openvpn/manage.c +++ b/src/openvpn/manage.c @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -68,7 +68,7 @@ static void man_output_standalone(struct management *man, volatile int *signal_r static void man_reset_client_socket(struct management *man, const bool exiting); static void -man_help() +man_help(void) { msg(M_CLIENT, "Management Interface for %s", title_string); msg(M_CLIENT, "Commands:"); @@ -250,7 +250,7 @@ man_output_list_push_str(struct management *man, const char *str) { if (management_connected(man) && str) { - buffer_list_push(man->connection.out, (const unsigned char *) str); + buffer_list_push(man->connection.out, str); } } @@ -1878,17 +1878,15 @@ man_connect(struct management *man) #if UNIX_SOCK_SUPPORT if (man->settings.flags & MF_UNIX_SOCK) { - msg(D_LINK_ERRORS, - "MANAGEMENT: connect to unix socket %s failed: %s", - sockaddr_unix_name(&man->settings.local_unix, "NULL"), - strerror_ts(status, &gc)); + msg(D_LINK_ERRORS | M_ERRNO, + "MANAGEMENT: connect to unix socket %s failed", + sockaddr_unix_name(&man->settings.local_unix, "NULL")); } else #endif - msg(D_LINK_ERRORS, - "MANAGEMENT: connect to %s failed: %s", - print_sockaddr(man->settings.local->ai_addr, &gc), - strerror_ts(status, &gc)); + msg(D_LINK_ERRORS | M_ERRNO, + "MANAGEMENT: connect to %s failed", + print_sockaddr(man->settings.local->ai_addr, &gc)); throw_signal_soft(SIGTERM, "management-connect-failed"); goto done; } @@ -2008,9 +2006,8 @@ man_io_error(struct management *man, const char *prefix) if (!ignore_sys_error(err)) { struct gc_arena gc = gc_new(); - msg(D_MANAGEMENT, "MANAGEMENT: TCP %s error: %s", - prefix, - strerror_ts(err, &gc)); + msg(D_MANAGEMENT, "MANAGEMENT: TCP %s error: %s", prefix, + strerror(err)); gc_free(&gc); return true; } @@ -2196,13 +2193,13 @@ man_read(struct management *man) * process command line if complete */ { - const unsigned char *line; + const char *line; while ((line = command_line_get(man->connection.in))) { #ifdef MANAGEMENT_IN_EXTRA if (man->connection.in_extra) { - if (!strcmp((char *)line, "END")) + if (!strcmp(line, "END")) { in_extra_dispatch(man); } @@ -3504,7 +3501,9 @@ management_query_user_pass(struct management *man, */ if (ret) { - man->connection.up_query.nocache = up->nocache; /* preserve caller's nocache setting */ + /* preserve caller's settings */ + man->connection.up_query.nocache = up->nocache; + man->connection.up_query.wait_for_push = up->wait_for_push; *up = man->connection.up_query; } secure_memzero(&man->connection.up_query, sizeof(man->connection.up_query)); @@ -3516,7 +3515,7 @@ management_query_user_pass(struct management *man, #ifdef MANAGMENT_EXTERNAL_KEY -int +static int management_query_multiline(struct management *man, const char *b64_data, const char *prompt, const char *cmd, int *state, struct buffer_list **input) { @@ -3592,7 +3591,7 @@ done: return ret; } -char * +static char * /* returns allocated base64 signature */ management_query_multiline_flatten_newline(struct management *man, const char *b64_data, const char *prompt, const char *cmd, int *state, struct buffer_list **input) @@ -3621,7 +3620,7 @@ management_query_multiline_flatten_newline(struct management *man, return result; } -char * +static char * /* returns allocated base64 signature */ management_query_multiline_flatten(struct management *man, const char *b64_data, const char *prompt, const char *cmd, int *state, struct buffer_list **input) @@ -3795,18 +3794,18 @@ command_line_add(struct command_line *cl, const unsigned char *buf, const int le } } -const unsigned char * +const char * command_line_get(struct command_line *cl) { int i; - const unsigned char *ret = NULL; + const char *ret = NULL; i = buf_substring_len(&cl->buf, '\n'); if (i >= 0) { buf_copy_excess(&cl->residual, &cl->buf, i); buf_chomp(&cl->buf); - ret = (const unsigned char *) BSTR(&cl->buf); + ret = BSTR(&cl->buf); } return ret; } @@ -4000,9 +3999,25 @@ log_history_ref(const struct log_history *h, const int index) } } +void +management_sleep(const int n) +{ + if (management) + { + management_event_loop_n_seconds(management, n); + } + else + { + sleep(n); + } +} + #else /* ifdef ENABLE_MANAGEMENT */ -static void -dummy(void) + +void +management_sleep(const int n) { + sleep(n); } + #endif /* ENABLE_MANAGEMENT */ diff --git a/src/openvpn/manage.h b/src/openvpn/manage.h index 542cc07..f286754 100644 --- a/src/openvpn/manage.h +++ b/src/openvpn/manage.h @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -70,7 +70,7 @@ void command_line_free(struct command_line *cl); void command_line_add(struct command_line *cl, const unsigned char *buf, const int len); -const unsigned char *command_line_get(struct command_line *cl); +const char *command_line_get(struct command_line *cl); void command_line_reset(struct command_line *cl); @@ -605,4 +605,11 @@ management_bytes_server(struct management *man, #endif /* MANAGEMENT_DEF_AUTH */ #endif /* ifdef ENABLE_MANAGEMENT */ + +/** + * A sleep function that services the management layer for n seconds rather + * than doing nothing. + */ +void management_sleep(const int n); + #endif /* ifndef MANAGE_H */ diff --git a/src/openvpn/mbuf.c b/src/openvpn/mbuf.c index fafbce0..87faff0 100644 --- a/src/openvpn/mbuf.c +++ b/src/openvpn/mbuf.c @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -33,6 +33,7 @@ #include "buffer.h" #include "error.h" +#include "integer.h" #include "misc.h" #include "mbuf.h" diff --git a/src/openvpn/mbuf.h b/src/openvpn/mbuf.h index e0643de..4912c95 100644 --- a/src/openvpn/mbuf.h +++ b/src/openvpn/mbuf.h @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/memdbg.h b/src/openvpn/memdbg.h index 0ba695f..70c6365 100644 --- a/src/openvpn/memdbg.h +++ b/src/openvpn/memdbg.h @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/misc.c b/src/openvpn/misc.c index fbd9938..77bb671 100644 --- a/src/openvpn/misc.c +++ b/src/openvpn/misc.c @@ -5,9 +5,9 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * Copyright (C) 2014-2015 David Sommerseth <davids@redhat.com> - * Copyright (C) 2016-2017 David Sommerseth <davids@openvpn.net> + * Copyright (C) 2016-2018 David Sommerseth <davids@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -55,116 +55,6 @@ const char *iproute_path = IPROUTE_PATH; /* GLOBAL */ int script_security = SSEC_BUILT_IN; /* GLOBAL */ /* - * Pass tunnel endpoint and MTU parms to a user-supplied script. - * Used to execute the up/down script/plugins. - */ -void -run_up_down(const char *command, - const struct plugin_list *plugins, - int plugin_type, - const char *arg, -#ifdef _WIN32 - DWORD adapter_index, -#endif - const char *dev_type, - int tun_mtu, - int link_mtu, - const char *ifconfig_local, - const char *ifconfig_remote, - const char *context, - const char *signal_text, - const char *script_type, - struct env_set *es) -{ - struct gc_arena gc = gc_new(); - - if (signal_text) - { - setenv_str(es, "signal", signal_text); - } - setenv_str(es, "script_context", context); - setenv_int(es, "tun_mtu", tun_mtu); - setenv_int(es, "link_mtu", link_mtu); - setenv_str(es, "dev", arg); - if (dev_type) - { - setenv_str(es, "dev_type", dev_type); - } -#ifdef _WIN32 - setenv_int(es, "dev_idx", adapter_index); -#endif - - if (!ifconfig_local) - { - ifconfig_local = ""; - } - if (!ifconfig_remote) - { - ifconfig_remote = ""; - } - if (!context) - { - context = ""; - } - - if (plugin_defined(plugins, plugin_type)) - { - struct argv argv = argv_new(); - ASSERT(arg); - argv_printf(&argv, - "%s %d %d %s %s %s", - arg, - tun_mtu, link_mtu, - ifconfig_local, ifconfig_remote, - context); - - if (plugin_call(plugins, plugin_type, &argv, NULL, es) != OPENVPN_PLUGIN_FUNC_SUCCESS) - { - msg(M_FATAL, "ERROR: up/down plugin call failed"); - } - - argv_reset(&argv); - } - - if (command) - { - struct argv argv = argv_new(); - ASSERT(arg); - setenv_str(es, "script_type", script_type); - argv_parse_cmd(&argv, command); - argv_printf_cat(&argv, "%s %d %d %s %s %s", arg, tun_mtu, link_mtu, - ifconfig_local, ifconfig_remote, context); - argv_msg(M_INFO, &argv); - openvpn_run_script(&argv, es, S_FATAL, "--up/--down"); - argv_reset(&argv); - } - - gc_free(&gc); -} - -/* Write our PID to a file */ -void -write_pid(const char *filename) -{ - if (filename) - { - unsigned int pid = 0; - FILE *fp = platform_fopen(filename, "w"); - if (!fp) - { - msg(M_ERR, "Open error on pid file %s", filename); - } - - pid = platform_getpid(); - fprintf(fp, "%u\n", pid); - if (fclose(fp)) - { - msg(M_ERR, "Close error on pid file %s", filename); - } - } -} - -/* * Set standard file descriptors to /dev/null */ void @@ -426,40 +316,6 @@ openvpn_popen(const struct argv *a, const struct env_set *es) /* - * Initialize random number seed. random() is only used - * when "weak" random numbers are acceptable. - * OpenSSL routines are always used when cryptographically - * strong random numbers are required. - */ - -void -init_random_seed(void) -{ - struct timeval tv; - - if (!gettimeofday(&tv, NULL)) - { - const unsigned int seed = (unsigned int) tv.tv_sec ^ tv.tv_usec; - srandom(seed); - } -} - -/* thread-safe strerror */ - -const char * -strerror_ts(int errnum, struct gc_arena *gc) -{ -#ifdef HAVE_STRERROR - struct buffer out = alloc_buf_gc(256, gc); - - buf_printf(&out, "%s", openvpn_strerror(errnum, gc)); - return BSTR(&out); -#else - return "[error string unavailable]"; -#endif -} - -/* * Set environmental variable (int or string). * * On Posix, we use putenv for portability, @@ -484,29 +340,6 @@ construct_name_value(const char *name, const char *value, struct gc_arena *gc) return BSTR(&out); } -bool -deconstruct_name_value(const char *str, const char **name, const char **value, struct gc_arena *gc) -{ - char *cp; - - ASSERT(str); - ASSERT(name && value); - - *name = cp = string_alloc(str, gc); - *value = NULL; - - while ((*cp)) - { - if (*cp == '=' && !*value) - { - *cp = 0; - *value = cp + 1; - } - ++cp; - } - return *name && *value; -} - static bool env_string_equal(const char *s1, const char *s2) { @@ -886,8 +719,6 @@ test_file(const char *filename) return ret; } -#ifdef ENABLE_CRYPTO - /* create a temporary filename in directory */ const char * create_temp_file(const char *directory, const char *prefix, struct gc_arena *gc) @@ -900,20 +731,16 @@ create_temp_file(const char *directory, const char *prefix, struct gc_arena *gc) do { - uint8_t rndbytes[16]; - const char *rndstr; - ++attempts; ++counter; - prng_bytes(rndbytes, sizeof rndbytes); - rndstr = format_hex_ex(rndbytes, sizeof rndbytes, 40, 0, NULL, gc); - buf_printf(&fname, PACKAGE "_%s_%s.tmp", prefix, rndstr); + buf_printf(&fname, PACKAGE "_%s_%08lx%08lx.tmp", prefix, + (unsigned long) get_random(), (unsigned long) get_random()); retfname = gen_path(directory, BSTR(&fname), gc); if (!retfname) { - msg(M_FATAL, "Failed to create temporary filename and path"); + msg(M_WARN, "Failed to create temporary filename and path"); return NULL; } @@ -928,19 +755,19 @@ create_temp_file(const char *directory, const char *prefix, struct gc_arena *gc) else if (fd == -1 && errno != EEXIST) { /* Something else went wrong, no need to retry. */ - struct gc_arena gcerr = gc_new(); - msg(M_FATAL, "Could not create temporary file '%s': %s", - retfname, strerror_ts(errno, &gcerr)); - gc_free(&gcerr); + msg(M_WARN | M_ERRNO, "Could not create temporary file '%s'", + retfname); return NULL; } } while (attempts < 6); - msg(M_FATAL, "Failed to create temporary file after %i attempts", attempts); + msg(M_WARN, "Failed to create temporary file after %i attempts", attempts); return NULL; } +#ifdef ENABLE_CRYPTO + /* * Prepend a random string to hostname to prevent DNS caching. * For example, foo.bar.gov would be modified to <random-chars>.foo.bar.gov. @@ -1632,37 +1459,6 @@ make_extended_arg_array(char **p, struct gc_arena *gc) } } -void -openvpn_sleep(const int n) -{ -#ifdef ENABLE_MANAGEMENT - if (management) - { - management_event_loop_n_seconds(management, n); - return; - } -#endif - sleep(n); -} - -/* - * Return the next largest power of 2 - * or u if u is a power of 2. - */ -size_t -adjust_power_of_2(size_t u) -{ - size_t ret = 1; - - while (ret < u) - { - ret <<= 1; - ASSERT(ret > 0); - } - - return ret; -} - /* * Remove security-sensitive strings from control message * so that they will not be output to log file. diff --git a/src/openvpn/misc.h b/src/openvpn/misc.h index ce96549..9f358ae 100644 --- a/src/openvpn/misc.h +++ b/src/openvpn/misc.h @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -51,25 +51,6 @@ struct env_set { struct env_item *list; }; -void run_up_down(const char *command, - const struct plugin_list *plugins, - int plugin_type, - const char *arg, -#ifdef _WIN32 - DWORD adapter_index, -#endif - const char *dev_type, - int tun_mtu, - int link_mtu, - const char *ifconfig_local, - const char *ifconfig_remote, - const char *context, - const char *signal_text, - const char *script_type, - struct env_set *es); - -void write_pid(const char *filename); - /* system flags */ #define S_SCRIPT (1<<0) #define S_FATAL (1<<1) @@ -95,12 +76,6 @@ openvpn_run_script(const struct argv *a, const struct env_set *es, const unsigne } -#ifdef HAVE_STRERROR -/* a thread-safe version of strerror */ -const char *strerror_ts(int errnum, struct gc_arena *gc); - -#endif - /* Set standard file descriptors to /dev/null */ void set_std_files_to_null(bool stdin_only); @@ -108,9 +83,6 @@ void set_std_files_to_null(bool stdin_only); extern int inetd_socket_descriptor; void save_inetd_socket_descriptor(void); -/* init random() function, only used as source for weak random numbers, when !ENABLE_CRYPTO */ -void init_random_seed(void); - /* set/delete environmental variable */ void setenv_str_ex(struct env_set *es, const char *name, @@ -298,12 +270,6 @@ bool env_safe_to_print(const char *str); /* returns true if environmental variable may be passed to an external program */ bool env_allowed(const char *str); -/* - * A sleep function that services the management layer for n - * seconds rather than doing nothing. - */ -void openvpn_sleep(const int n); - void configure_path(void); const char *sanitize_control_message(const char *str, struct gc_arena *gc); @@ -327,8 +293,6 @@ extern const char *iproute_path; #define SSEC_PW_ENV 3 /* allow calling of built-in programs and user-defined scripts that may receive a password as an environmental variable */ extern int script_security; /* GLOBAL */ -/* return the next largest power of 2 */ -size_t adjust_power_of_2(size_t u); #define COMPAT_FLAG_QUERY 0 /** compat_flags operator: Query for a flag */ #define COMPAT_FLAG_SET (1<<0) /** compat_flags operator: Set a compat flag */ diff --git a/src/openvpn/mroute.c b/src/openvpn/mroute.c index 7b46a6a..28940a8 100644 --- a/src/openvpn/mroute.c +++ b/src/openvpn/mroute.c @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -65,25 +65,49 @@ is_mac_mcast_maddr(const struct mroute_addr *addr) * Don't learn certain addresses. */ bool -mroute_learnable_address(const struct mroute_addr *addr) +mroute_learnable_address(const struct mroute_addr *addr, struct gc_arena *gc) { int i; - bool not_all_zeros = false; - bool not_all_ones = false; + bool all_zeros = true; + bool all_ones = true; for (i = 0; i < addr->len; ++i) { int b = addr->raw_addr[i]; if (b != 0x00) { - not_all_zeros = true; + all_zeros = false; } if (b != 0xFF) { - not_all_ones = true; + all_ones = false; } } - return not_all_zeros && not_all_ones && !is_mac_mcast_maddr(addr); + + /* only networkss shorter than 8 bits are allowed to be all 0s. */ + if (all_zeros + && !((addr->type & MR_WITH_NETBITS) && (addr->netbits < 8))) + { + msg(D_MULTI_LOW, "Can't learn %s: network is all 0s, but netbits >= 8", + mroute_addr_print(addr, gc)); + return false; + } + + if (all_ones) + { + msg(D_MULTI_LOW, "Can't learn %s: network is all 1s", + mroute_addr_print(addr, gc)); + return false; + } + + if (is_mac_mcast_maddr(addr)) + { + msg(D_MULTI_LOW, "Can't learn %s: network is a multicast address", + mroute_addr_print(addr, gc)); + return false; + } + + return true; } static inline void @@ -159,9 +183,8 @@ mroute_extract_addr_arp(struct mroute_addr *src, #endif /* ifdef ENABLE_PF */ unsigned int -mroute_extract_addr_ipv4(struct mroute_addr *src, - struct mroute_addr *dest, - const struct buffer *buf) +mroute_extract_addr_ip(struct mroute_addr *src, struct mroute_addr *dest, + const struct buffer *buf) { unsigned int ret = 0; if (BLEN(buf) >= 1) @@ -267,7 +290,7 @@ mroute_extract_addr_ether(struct mroute_addr *src, switch (ntohs(eth->proto)) { case OPENVPN_ETH_P_IPV4: - ret |= (mroute_extract_addr_ipv4(esrc, edest, &b) << MROUTE_SEC_SHIFT); + ret |= (mroute_extract_addr_ip(esrc, edest, &b) << MROUTE_SEC_SHIFT); break; case OPENVPN_ETH_P_ARP: diff --git a/src/openvpn/mroute.h b/src/openvpn/mroute.h index e57a950..1063a18 100644 --- a/src/openvpn/mroute.h +++ b/src/openvpn/mroute.h @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -141,7 +141,8 @@ bool mroute_extract_openvpn_sockaddr(struct mroute_addr *addr, const struct openvpn_sockaddr *osaddr, bool use_port); -bool mroute_learnable_address(const struct mroute_addr *addr); +bool mroute_learnable_address(const struct mroute_addr *addr, + struct gc_arena *gc); uint32_t mroute_addr_hash_function(const void *key, uint32_t iv); @@ -181,9 +182,9 @@ mroute_extract_addr_from_packet(struct mroute_addr *src, const struct buffer *buf, int tunnel_type) { - unsigned int mroute_extract_addr_ipv4(struct mroute_addr *src, - struct mroute_addr *dest, - const struct buffer *buf); + unsigned int mroute_extract_addr_ip(struct mroute_addr *src, + struct mroute_addr *dest, + const struct buffer *buf); unsigned int mroute_extract_addr_ether(struct mroute_addr *src, struct mroute_addr *dest, @@ -195,7 +196,7 @@ mroute_extract_addr_from_packet(struct mroute_addr *src, verify_align_4(buf); if (tunnel_type == DEV_TYPE_TUN) { - ret = mroute_extract_addr_ipv4(src, dest, buf); + ret = mroute_extract_addr_ip(src, dest, buf); } else if (tunnel_type == DEV_TYPE_TAP) { diff --git a/src/openvpn/mss.c b/src/openvpn/mss.c index c36e004..facdf7b 100644 --- a/src/openvpn/mss.c +++ b/src/openvpn/mss.c @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/mss.h b/src/openvpn/mss.h index 0de2042..9350102 100644 --- a/src/openvpn/mss.h +++ b/src/openvpn/mss.h @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/mstats.c b/src/openvpn/mstats.c index 9b09188..281a835 100644 --- a/src/openvpn/mstats.c +++ b/src/openvpn/mstats.c @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/mstats.h b/src/openvpn/mstats.h index 486035f..0d58cbf 100644 --- a/src/openvpn/mstats.h +++ b/src/openvpn/mstats.h @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/mtcp.c b/src/openvpn/mtcp.c index cb940d8..3756c27 100644 --- a/src/openvpn/mtcp.c +++ b/src/openvpn/mtcp.c @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -521,7 +521,7 @@ multi_tcp_dispatch(struct multi_context *m, struct multi_instance *mi, const int return touched; } -int +static int multi_tcp_post(struct multi_context *m, struct multi_instance *mi, const int action) { struct context *c = multi_tcp_context(m, mi); @@ -797,7 +797,7 @@ tunnel_server_tcp(struct context *top) multi.top.c2.inotify_fd = inotify_init(); if (multi.top.c2.inotify_fd < 0) { - msg(D_MULTI_ERRORS, "MULTI: inotify_init error: %s", strerror(errno)); + msg(D_MULTI_ERRORS | M_ERRNO, "MULTI: inotify_init error"); } #endif diff --git a/src/openvpn/mtcp.h b/src/openvpn/mtcp.h index 79dcb13..bba455b 100644 --- a/src/openvpn/mtcp.h +++ b/src/openvpn/mtcp.h @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/mtu.c b/src/openvpn/mtu.c index 44bef68..04868cd 100644 --- a/src/openvpn/mtu.c +++ b/src/openvpn/mtu.c @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/mtu.h b/src/openvpn/mtu.h index d1e8c18..a82154a 100644 --- a/src/openvpn/mtu.h +++ b/src/openvpn/mtu.h @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/mudp.c b/src/openvpn/mudp.c index 793678d..b3690ab 100644 --- a/src/openvpn/mudp.c +++ b/src/openvpn/mudp.c @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -325,7 +325,7 @@ tunnel_server_udp_single_threaded(struct context *top) multi.top.c2.inotify_fd = inotify_init(); if (multi.top.c2.inotify_fd < 0) { - msg(D_MULTI_ERRORS, "MULTI: inotify_init error: %s", strerror(errno)); + msg(D_MULTI_ERRORS | M_ERRNO, "MULTI: inotify_init error"); } #endif diff --git a/src/openvpn/mudp.h b/src/openvpn/mudp.h index b9ceaf7..7e31151 100644 --- a/src/openvpn/mudp.h +++ b/src/openvpn/mudp.h @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/multi.c b/src/openvpn/multi.c index 8d3d67f..28c3b88 100644 --- a/src/openvpn/multi.c +++ b/src/openvpn/multi.c @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -485,7 +485,7 @@ multi_instance_string(const struct multi_instance *mi, bool null, struct gc_aren } } -void +static void generate_prefix(struct multi_instance *mi) { struct gc_arena gc = gc_new(); @@ -1077,6 +1077,7 @@ multi_learn_addr(struct multi_context *m, struct hash_bucket *bucket = hash_bucket(m->vhash, hv); struct multi_route *oldroute = NULL; struct multi_instance *owner = NULL; + struct gc_arena gc = gc_new(); /* if route currently exists, get the instance which owns it */ he = hash_lookup_fast(m->vhash, bucket, addr, hv); @@ -1090,11 +1091,9 @@ multi_learn_addr(struct multi_context *m, } /* do we need to add address to hash table? */ - if ((!owner || owner != mi) - && mroute_learnable_address(addr) + if ((!owner || owner != mi) && mroute_learnable_address(addr, &gc) && !mroute_addr_equal(addr, &m->local)) { - struct gc_arena gc = gc_new(); struct multi_route *newroute; bool learn_succeeded = false; @@ -1151,9 +1150,8 @@ multi_learn_addr(struct multi_context *m, { free(newroute); } - - gc_free(&gc); } + gc_free(&gc); return owner; } @@ -2355,7 +2353,7 @@ multi_process_post(struct multi_context *m, struct multi_instance *mi, const uns } else { - msg(M_NONFATAL, "MULTI: inotify_add_watch error: %s", strerror(errno)); + msg(M_NONFATAL | M_ERRNO, "MULTI: inotify_add_watch error"); } } #endif @@ -2967,7 +2965,7 @@ gremlin_flood_clients(struct multi_context *m) } #endif /* ifdef ENABLE_DEBUG */ -bool +static bool stale_route_check_trigger(struct multi_context *m) { struct timeval null; diff --git a/src/openvpn/multi.h b/src/openvpn/multi.h index 63afbaf..d7e5c29 100644 --- a/src/openvpn/multi.h +++ b/src/openvpn/multi.h @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/ntlm.c b/src/openvpn/ntlm.c index 0b1163e..077fa3e 100644 --- a/src/openvpn/ntlm.c +++ b/src/openvpn/ntlm.c @@ -60,45 +60,47 @@ static void create_des_keys(const unsigned char *hash, unsigned char *key) { key[0] = hash[0]; - key[1] = ((hash[0]&1)<<7)|(hash[1]>>1); - key[2] = ((hash[1]&3)<<6)|(hash[2]>>2); - key[3] = ((hash[2]&7)<<5)|(hash[3]>>3); - key[4] = ((hash[3]&15)<<4)|(hash[4]>>4); - key[5] = ((hash[4]&31)<<3)|(hash[5]>>5); - key[6] = ((hash[5]&63)<<2)|(hash[6]>>6); - key[7] = ((hash[6]&127)<<1); + key[1] = ((hash[0] & 1) << 7) | (hash[1] >> 1); + key[2] = ((hash[1] & 3) << 6) | (hash[2] >> 2); + key[3] = ((hash[2] & 7) << 5) | (hash[3] >> 3); + key[4] = ((hash[3] & 15) << 4) | (hash[4] >> 4); + key[5] = ((hash[4] & 31) << 3) | (hash[5] >> 5); + key[6] = ((hash[5] & 63) << 2) | (hash[6] >> 6); + key[7] = ((hash[6] & 127) << 1); key_des_fixup(key, 8, 1); } static void -gen_md4_hash(const char *data, int data_len, char *result) +gen_md4_hash(const uint8_t *data, int data_len, uint8_t *result) { /* result is 16 byte md4 hash */ const md_kt_t *md4_kt = md_kt_get("MD4"); - char md[MD4_DIGEST_LENGTH]; + uint8_t md[MD4_DIGEST_LENGTH]; md_full(md4_kt, data, data_len, md); memcpy(result, md, MD4_DIGEST_LENGTH); } static void -gen_hmac_md5(const char *data, int data_len, const char *key, int key_len,char *result) +gen_hmac_md5(const uint8_t *data, int data_len, const uint8_t *key, int key_len, + uint8_t *result) { const md_kt_t *md5_kt = md_kt_get("MD5"); hmac_ctx_t *hmac_ctx = hmac_ctx_new(); hmac_ctx_init(hmac_ctx, key, key_len, md5_kt); - hmac_ctx_update(hmac_ctx, (const unsigned char *)data, data_len); - hmac_ctx_final(hmac_ctx, (unsigned char *)result); + hmac_ctx_update(hmac_ctx, data, data_len); + hmac_ctx_final(hmac_ctx, result); hmac_ctx_cleanup(hmac_ctx); hmac_ctx_free(hmac_ctx); } static void -gen_timestamp(unsigned char *timestamp) +gen_timestamp(uint8_t *timestamp) { /* Copies 8 bytes long timestamp into "timestamp" buffer. - * Timestamp is Little-endian, 64-bit signed value representing the number of tenths of a microsecond since January 1, 1601. + * Timestamp is Little-endian, 64-bit signed value representing the + * number of tenths of a microsecond since January 1, 1601. */ UINTEGER64 timestamp_ull; @@ -129,8 +131,8 @@ gen_nonce(unsigned char *nonce) } } -void -my_strupr(unsigned char *str) +static void +my_strupr(char *str) { /* converts string to uppercase in place */ @@ -150,16 +152,17 @@ unicodize(char *dst, const char *src) { dst[i++] = *src; dst[i++] = 0; - } - while (*src++); + } while (*src++); return i; } static void -add_security_buffer(int sb_offset, void *data, int length, unsigned char *msg_buf, int *msg_bufpos) +add_security_buffer(int sb_offset, void *data, int length, + unsigned char *msg_buf, int *msg_bufpos) { - /* Adds security buffer data to a message and sets security buffer's offset and length */ + /* Adds security buffer data to a message and sets security buffer's + * offset and length */ msg_buf[sb_offset] = (unsigned char)length; msg_buf[sb_offset + 2] = msg_buf[sb_offset]; msg_buf[sb_offset + 4] = (unsigned char)(*msg_bufpos & 0xff); @@ -186,7 +189,8 @@ ntlm_phase_1(const struct http_proxy_info *p, struct gc_arena *gc) } const char * -ntlm_phase_3(const struct http_proxy_info *p, const char *phase_2, struct gc_arena *gc) +ntlm_phase_3(const struct http_proxy_info *p, const char *phase_2, + struct gc_arena *gc) { /* NTLM handshake * @@ -195,19 +199,19 @@ ntlm_phase_3(const struct http_proxy_info *p, const char *phase_2, struct gc_are */ char pwbuf[sizeof(p->up.password) * 2]; /* for unicode password */ - unsigned char buf2[128]; /* decoded reply from proxy */ - unsigned char phase3[464]; + uint8_t buf2[128]; /* decoded reply from proxy */ + uint8_t phase3[464]; - char md4_hash[MD4_DIGEST_LENGTH+5]; - char challenge[8], ntlm_response[24]; + uint8_t md4_hash[MD4_DIGEST_LENGTH + 5]; + uint8_t challenge[8], ntlm_response[24]; int i, ret_val; - char ntlmv2_response[144]; + uint8_t ntlmv2_response[144]; char userdomain_u[256]; /* for uppercase unicode username and domain */ char userdomain[128]; /* the same as previous but ascii */ - char ntlmv2_hash[MD5_DIGEST_LENGTH]; - char ntlmv2_hmacmd5[16]; - char *ntlmv2_blob = ntlmv2_response + 16; /* inside ntlmv2_response, length: 128 */ + uint8_t ntlmv2_hash[MD5_DIGEST_LENGTH]; + uint8_t ntlmv2_hmacmd5[16]; + uint8_t *ntlmv2_blob = ntlmv2_response + 16; /* inside ntlmv2_response, length: 128 */ int ntlmv2_blob_size = 0; int phase3_bufpos = 0x40; /* offset to next security buffer data to be added */ size_t len; @@ -246,12 +250,13 @@ ntlm_phase_3(const struct http_proxy_info *p, const char *phase_2, struct gc_are /* fill 1st 16 bytes with md4 hash, disregard terminating null */ - gen_md4_hash(pwbuf, unicodize(pwbuf, p->up.password) - 2, md4_hash); + int unicode_len = unicodize(pwbuf, p->up.password) - 2; + gen_md4_hash((uint8_t *)pwbuf, unicode_len, md4_hash); /* pad to 21 bytes */ memset(md4_hash + MD4_DIGEST_LENGTH, 0, 5); - ret_val = openvpn_base64_decode( phase_2, (void *)buf2, -1); + ret_val = openvpn_base64_decode(phase_2, buf2, -1); if (ret_val < 0) { return NULL; @@ -271,7 +276,8 @@ ntlm_phase_3(const struct http_proxy_info *p, const char *phase_2, struct gc_are int tib_len; /* NTLMv2 hash */ - my_strupr((unsigned char *)strcpy(userdomain, username)); + strcpy(userdomain, username); + my_strupr(userdomain); if (strlen(username) + strlen(domain) < sizeof(userdomain)) { strcat(userdomain, domain); @@ -281,34 +287,54 @@ ntlm_phase_3(const struct http_proxy_info *p, const char *phase_2, struct gc_are msg(M_INFO, "Warning: Username or domain too long"); } unicodize(userdomain_u, userdomain); - gen_hmac_md5(userdomain_u, 2 * strlen(userdomain), md4_hash, MD5_DIGEST_LENGTH, ntlmv2_hash); + gen_hmac_md5((uint8_t *)userdomain_u, 2 * strlen(userdomain), md4_hash, + MD5_DIGEST_LENGTH, ntlmv2_hash); /* NTLMv2 Blob */ memset(ntlmv2_blob, 0, 128); /* Clear blob buffer */ ntlmv2_blob[0x00] = 1; /* Signature */ ntlmv2_blob[0x01] = 1; /* Signature */ ntlmv2_blob[0x04] = 0; /* Reserved */ - gen_timestamp((unsigned char *)&ntlmv2_blob[0x08]); /* 64-bit Timestamp */ - gen_nonce((unsigned char *)&ntlmv2_blob[0x10]); /* 64-bit Client Nonce */ + gen_timestamp(&ntlmv2_blob[0x08]); /* 64-bit Timestamp */ + gen_nonce(&ntlmv2_blob[0x10]); /* 64-bit Client Nonce */ ntlmv2_blob[0x18] = 0; /* Unknown, zero should work */ /* Add target information block to the blob */ - if (( *((long *)&buf2[0x14]) & 0x00800000) == 0x00800000) /* Check for Target Information block */ + + /* Check for Target Information block */ + /* The NTLM spec instructs to interpret these 4 consecutive bytes as a + * 32bit long integer. However, no endianness is specified. + * The code here and that found in other NTLM implementations point + * towards the assumption that the byte order on the wire has to + * match the order on the sending and receiving hosts. Probably NTLM has + * been thought to be always running on x86_64/i386 machine thus + * implying Little-Endian everywhere. + * + * This said, in case of future changes, we should keep in mind that the + * byte order on the wire for the NTLM header is LE. + */ + const size_t hoff = 0x14; + unsigned long flags = buf2[hoff] | (buf2[hoff + 1] << 8) | + (buf2[hoff + 2] << 16) | (buf2[hoff + 3] << 24); + if ((flags & 0x00800000) == 0x00800000) { tib_len = buf2[0x28]; /* Get Target Information block size */ if (tib_len > 96) { tib_len = 96; } + { - char *tib_ptr; - int tib_pos = buf2[0x2c]; + uint8_t *tib_ptr; + uint8_t tib_pos = buf2[0x2c]; if (tib_pos + tib_len > sizeof(buf2)) { return NULL; } - tib_ptr = buf2 + tib_pos; /* Get Target Information block pointer */ - memcpy(&ntlmv2_blob[0x1c], tib_ptr, tib_len); /* Copy Target Information block into the blob */ + /* Get Target Information block pointer */ + tib_ptr = buf2 + tib_pos; + /* Copy Target Information block into the blob */ + memcpy(&ntlmv2_blob[0x1c], tib_ptr, tib_len); } } else @@ -316,7 +342,8 @@ ntlm_phase_3(const struct http_proxy_info *p, const char *phase_2, struct gc_are tib_len = 0; } - ntlmv2_blob[0x1c + tib_len] = 0; /* Unknown, zero works */ + /* Unknown, zero works */ + ntlmv2_blob[0x1c + tib_len] = 0; /* Get blob length */ ntlmv2_blob_size = 0x20 + tib_len; @@ -325,24 +352,28 @@ ntlm_phase_3(const struct http_proxy_info *p, const char *phase_2, struct gc_are memcpy(&ntlmv2_response[8], challenge, 8); /* hmac-md5 */ - gen_hmac_md5(&ntlmv2_response[8], ntlmv2_blob_size + 8, ntlmv2_hash, MD5_DIGEST_LENGTH, ntlmv2_hmacmd5); - - /* Add hmac-md5 result to the blob */ - memcpy(ntlmv2_response, ntlmv2_hmacmd5, MD5_DIGEST_LENGTH); /* Note: This overwrites challenge previously written at ntlmv2_response[8..15] */ + gen_hmac_md5(&ntlmv2_response[8], ntlmv2_blob_size + 8, ntlmv2_hash, + MD5_DIGEST_LENGTH, ntlmv2_hmacmd5); + /* Add hmac-md5 result to the blob. + * Note: This overwrites challenge previously written at + * ntlmv2_response[8..15] */ + memcpy(ntlmv2_response, ntlmv2_hmacmd5, MD5_DIGEST_LENGTH); } - else /* Generate NTLM response */ + else /* Generate NTLM response */ { - unsigned char key1[DES_KEY_LENGTH], key2[DES_KEY_LENGTH], key3[DES_KEY_LENGTH]; + unsigned char key1[DES_KEY_LENGTH], key2[DES_KEY_LENGTH]; + unsigned char key3[DES_KEY_LENGTH]; - create_des_keys((unsigned char *)md4_hash, key1); + create_des_keys(md4_hash, key1); cipher_des_encrypt_ecb(key1, challenge, ntlm_response); - create_des_keys((unsigned char *)&(md4_hash[DES_KEY_LENGTH-1]), key2); + create_des_keys(&md4_hash[DES_KEY_LENGTH - 1], key2); cipher_des_encrypt_ecb(key2, challenge, &ntlm_response[DES_KEY_LENGTH]); - create_des_keys((unsigned char *)&(md4_hash[2*(DES_KEY_LENGTH-1)]), key3); - cipher_des_encrypt_ecb(key3, challenge, &ntlm_response[DES_KEY_LENGTH*2]); + create_des_keys(&md4_hash[2 * (DES_KEY_LENGTH - 1)], key3); + cipher_des_encrypt_ecb(key3, challenge, + &ntlm_response[DES_KEY_LENGTH * 2]); } @@ -353,7 +384,8 @@ ntlm_phase_3(const struct http_proxy_info *p, const char *phase_2, struct gc_are if (ntlmv2_enabled) /* NTLMv2 response */ { - add_security_buffer(0x14, ntlmv2_response, ntlmv2_blob_size + 16, phase3, &phase3_bufpos); + add_security_buffer(0x14, ntlmv2_response, ntlmv2_blob_size + 16, + phase3, &phase3_bufpos); } else /* NTLM response */ { @@ -361,12 +393,13 @@ ntlm_phase_3(const struct http_proxy_info *p, const char *phase_2, struct gc_are } /* username in ascii */ - add_security_buffer(0x24, username, strlen(username), phase3, &phase3_bufpos); + add_security_buffer(0x24, username, strlen(username), phase3, + &phase3_bufpos); - /* Set domain. If <domain> is empty, default domain will be used (i.e. proxy's domain) */ + /* Set domain. If <domain> is empty, default domain will be used + * (i.e. proxy's domain) */ add_security_buffer(0x1c, domain, strlen(domain), phase3, &phase3_bufpos); - /* other security buffers will be empty */ phase3[0x10] = phase3_bufpos; /* lm not used */ phase3[0x30] = phase3_bufpos; /* no workstation name supplied */ @@ -376,7 +409,8 @@ ntlm_phase_3(const struct http_proxy_info *p, const char *phase_2, struct gc_are phase3[0x3c] = 0x02; /* negotiate oem */ phase3[0x3d] = 0x02; /* negotiate ntlm */ - return ((const char *)make_base64_string2((unsigned char *)phase3, phase3_bufpos, gc)); + return ((const char *)make_base64_string2((unsigned char *)phase3, + phase3_bufpos, gc)); } #else /* if NTLM */ diff --git a/src/openvpn/occ-inline.h b/src/openvpn/occ-inline.h index 68e9098..7f6f1b2 100644 --- a/src/openvpn/occ-inline.h +++ b/src/openvpn/occ-inline.h @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -31,7 +31,7 @@ */ static inline int -occ_reset_op() +occ_reset_op(void) { return -1; } diff --git a/src/openvpn/occ.c b/src/openvpn/occ.c index 40f7e76..80504af 100644 --- a/src/openvpn/occ.c +++ b/src/openvpn/occ.c @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/occ.h b/src/openvpn/occ.h index 12d7bc5..f6ff5f9 100644 --- a/src/openvpn/occ.h +++ b/src/openvpn/occ.h @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/openssl_compat.h b/src/openvpn/openssl_compat.h index c765f0b..c3152d0 100644 --- a/src/openvpn/openssl_compat.h +++ b/src/openvpn/openssl_compat.h @@ -5,8 +5,8 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> - * Copyright (C) 2010-2017 Fox Crypto B.V. <openvpn@fox-it.com> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> + * Copyright (C) 2010-2018 Fox Crypto B.V. <openvpn@fox-it.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -88,38 +88,19 @@ EVP_MD_CTX_new(void) } #endif -#if !defined(HAVE_EVP_CIPHER_CTX_FREE) -/** - * Free an existing cipher context - * - * @param ctx The cipher context - */ -static inline void -EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *c) -{ - free(c); -} -#endif - -#if !defined(HAVE_EVP_CIPHER_CTX_NEW) -/** - * Allocate a new cipher context object - * - * @return A zero'ed cipher context object - */ -static inline EVP_CIPHER_CTX * -EVP_CIPHER_CTX_new(void) -{ - EVP_CIPHER_CTX *ctx = NULL; - ALLOC_OBJ_CLEAR(ctx, EVP_CIPHER_CTX); - return ctx; -} -#endif - #if !defined(HAVE_HMAC_CTX_RESET) /** * Reset a HMAC context * + * OpenSSL 1.1+ removes APIs HMAC_CTX_init() and HMAC_CTX_cleanup() + * and replace them with a single call that does a cleanup followed + * by an init. A proper _reset() for OpenSSL < 1.1 should perform + * a similar set of operations. + * + * It means that before we kill a HMAC context, we'll have to cleanup + * again, as we probably have allocated a few resources when we forced + * an init. + * * @param ctx The HMAC context * @return 1 on success, 0 on error */ @@ -127,42 +108,22 @@ static inline int HMAC_CTX_reset(HMAC_CTX *ctx) { HMAC_CTX_cleanup(ctx); + HMAC_CTX_init(ctx); return 1; } #endif -#if !defined(HAVE_HMAC_CTX_INIT) -/** - * Init a HMAC context - * - * @param ctx The HMAC context - * - * Contrary to many functions in this file, HMAC_CTX_init() is not - * an OpenSSL 1.1 function: it comes from previous versions and was - * removed in v1.1. As a consequence, there is no distincting in - * v1.1 between a cleanup, and init and a reset. Yet, previous OpenSSL - * version need this distinction. - * - * In order to respect previous OpenSSL versions, we implement init - * as reset for OpenSSL 1.1+. - */ -static inline void -HMAC_CTX_init(HMAC_CTX *ctx) -{ - HMAC_CTX_reset(ctx); -} -#endif - #if !defined(HAVE_HMAC_CTX_FREE) /** - * Free an existing HMAC context + * Cleanup and free an existing HMAC context * * @param ctx The HMAC context */ static inline void -HMAC_CTX_free(HMAC_CTX *c) +HMAC_CTX_free(HMAC_CTX *ctx) { - free(c); + HMAC_CTX_cleanup(ctx); + free(ctx); } #endif @@ -279,7 +240,21 @@ X509_OBJECT_get_type(const X509_OBJECT *obj) static inline RSA * EVP_PKEY_get0_RSA(EVP_PKEY *pkey) { - return pkey ? pkey->pkey.rsa : NULL; + return (pkey && pkey->type == EVP_PKEY_RSA) ? pkey->pkey.rsa : NULL; +} +#endif + +#if !defined(HAVE_EVP_PKEY_GET0_EC_KEY) && !defined(OPENSSL_NO_EC) +/** + * Get the EC_KEY object of a public key + * + * @param pkey Public key object + * @return The underlying EC_KEY object + */ +static inline EC_KEY * +EVP_PKEY_get0_EC_KEY(EVP_PKEY *pkey) +{ + return (pkey && pkey->type == EVP_PKEY_EC) ? pkey->pkey.ec : NULL; } #endif @@ -307,7 +282,7 @@ EVP_PKEY_id(const EVP_PKEY *pkey) static inline DSA * EVP_PKEY_get0_DSA(EVP_PKEY *pkey) { - return pkey ? pkey->pkey.dsa : NULL; + return (pkey && pkey->type == EVP_PKEY_DSA) ? pkey->pkey.dsa : NULL; } #endif @@ -649,9 +624,149 @@ RSA_meth_set0_app_data(RSA_METHOD *meth, void *app_data) } #endif +#if !defined(HAVE_RSA_METH_GET0_APP_DATA) +/** + * Get the application data of an RSA_METHOD object + * + * @param meth The RSA_METHOD object + * @return pointer to application data, may be NULL + */ +static inline void * +RSA_meth_get0_app_data(const RSA_METHOD *meth) +{ + return meth ? meth->app_data : NULL; +} +#endif + +#if !defined(HAVE_EC_GROUP_ORDER_BITS) && !defined(OPENSSL_NO_EC) +/** + * Gets the number of bits of the order of an EC_GROUP + * + * @param group EC_GROUP object + * @return number of bits of group order. + */ +static inline int +EC_GROUP_order_bits(const EC_GROUP *group) +{ + BIGNUM* order = BN_new(); + EC_GROUP_get_order(group, order, NULL); + int bits = BN_num_bits(order); + BN_free(order); + return bits; +} +#endif + /* SSLeay symbols have been renamed in OpenSSL 1.1 */ #if !defined(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT) #define RSA_F_RSA_OSSL_PRIVATE_ENCRYPT RSA_F_RSA_EAY_PRIVATE_ENCRYPT #endif +#ifndef SSL_CTX_get_min_proto_version +/** Return the min SSL protocol version currently enabled in the context. + * If no valid version >= TLS1.0 is found, return 0. */ +static inline int +SSL_CTX_get_min_proto_version(SSL_CTX *ctx) +{ + long sslopt = SSL_CTX_get_options(ctx); + if (!(sslopt & SSL_OP_NO_TLSv1)) + { + return TLS1_VERSION; + } + if (!(sslopt & SSL_OP_NO_TLSv1_1)) + { + return TLS1_1_VERSION; + } + if (!(sslopt & SSL_OP_NO_TLSv1_2)) + { + return TLS1_2_VERSION; + } + return 0; +} +#endif /* SSL_CTX_get_min_proto_version */ + +#ifndef SSL_CTX_get_max_proto_version +/** Return the max SSL protocol version currently enabled in the context. + * If no valid version >= TLS1.0 is found, return 0. */ +static inline int +SSL_CTX_get_max_proto_version(SSL_CTX *ctx) +{ + long sslopt = SSL_CTX_get_options(ctx); +#ifdef SSL_OP_NO_TLSv1_2 + if (!(sslopt & SSL_OP_NO_TLSv1_2)) + { + return TLS1_2_VERSION; + } +#endif +#ifdef SSL_OP_NO_TLSv1_1 + if (!(sslopt & SSL_OP_NO_TLSv1_1)) + { + return TLS1_1_VERSION; + } +#endif + if (!(sslopt & SSL_OP_NO_TLSv1)) + { + return TLS1_VERSION; + } + return 0; +} +#endif /* SSL_CTX_get_max_proto_version */ + +#ifndef SSL_CTX_set_min_proto_version +/** Mimics SSL_CTX_set_min_proto_version for OpenSSL < 1.1 */ +static inline int +SSL_CTX_set_min_proto_version(SSL_CTX *ctx, long tls_ver_min) +{ + long sslopt = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3; /* Never do < TLS 1.0 */ + + if (tls_ver_min > TLS1_VERSION) + { + sslopt |= SSL_OP_NO_TLSv1; + } +#ifdef SSL_OP_NO_TLSv1_1 + if (tls_ver_min > TLS1_1_VERSION) + { + sslopt |= SSL_OP_NO_TLSv1_1; + } +#endif +#ifdef SSL_OP_NO_TLSv1_2 + if (tls_ver_min > TLS1_2_VERSION) + { + sslopt |= SSL_OP_NO_TLSv1_2; + } +#endif + SSL_CTX_set_options(ctx, sslopt); + + return 1; +} +#endif /* SSL_CTX_set_min_proto_version */ + +#ifndef SSL_CTX_set_max_proto_version +/** Mimics SSL_CTX_set_max_proto_version for OpenSSL < 1.1 */ +static inline int +SSL_CTX_set_max_proto_version(SSL_CTX *ctx, long tls_ver_max) +{ + long sslopt = 0; + + if (tls_ver_max < TLS1_VERSION) + { + sslopt |= SSL_OP_NO_TLSv1; + } +#ifdef SSL_OP_NO_TLSv1_1 + if (tls_ver_max < TLS1_1_VERSION) + { + sslopt |= SSL_OP_NO_TLSv1_1; + } +#endif +#ifdef SSL_OP_NO_TLSv1_2 + if (tls_ver_max < TLS1_2_VERSION) + { + sslopt |= SSL_OP_NO_TLSv1_2; + } +#endif + SSL_CTX_set_options(ctx, sslopt); + + return 1; +} +#endif /* SSL_CTX_set_max_proto_version */ + #endif /* OPENSSL_COMPAT_H_ */ diff --git a/src/openvpn/openvpn.c b/src/openvpn/openvpn.c index 08c09e6..b9e914a 100644 --- a/src/openvpn/openvpn.c +++ b/src/openvpn/openvpn.c @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -33,6 +33,7 @@ #include "forward.h" #include "multi.h" #include "win32.h" +#include "platform.h" #include "memdbg.h" @@ -47,6 +48,27 @@ process_signal_p2p(struct context *c) return process_signal(c); } +/* Write our PID to a file */ +static void +write_pid(const char *filename) +{ + if (filename) + { + unsigned int pid = 0; + FILE *fp = platform_fopen(filename, "w"); + if (!fp) + { + msg(M_ERR, "Open error on pid file %s", filename); + } + + pid = platform_getpid(); + fprintf(fp, "%u\n", pid); + if (fclose(fp)) + { + msg(M_ERR, "Close error on pid file %s", filename); + } + } +} /**************************************************************************/ diff --git a/src/openvpn/openvpn.h b/src/openvpn/openvpn.h index 9262e68..7736183 100644 --- a/src/openvpn/openvpn.h +++ b/src/openvpn/openvpn.h @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/options.c b/src/openvpn/options.c index fef5e90..3f9164c 100644 --- a/src/openvpn/options.c +++ b/src/openvpn/options.c @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * Copyright (C) 2008-2013 David Sommerseth <dazo@users.sourceforge.net> * * This program is free software; you can redistribute it and/or modify @@ -415,8 +415,9 @@ static const char usage_message[] = " client instance.\n" "--ifconfig-pool start-IP end-IP [netmask] : Set aside a pool of subnets\n" " to be dynamically allocated to connecting clients.\n" - "--ifconfig-pool-linear : Use individual addresses rather than /30 subnets\n" - " in tun mode. Not compatible with Windows clients.\n" + "--ifconfig-pool-linear : (DEPRECATED) Use individual addresses rather \n" + " than /30 subnets\n in tun mode. Not compatible with\n" + " Windows clients.\n" "--ifconfig-pool-persist file [seconds] : Persist/unpersist ifconfig-pool\n" " data to file, at seconds intervals (default=600).\n" " If seconds=0, file will be treated as read-only.\n" @@ -434,7 +435,7 @@ static const char usage_message[] = " Only valid in a client-specific config file.\n" "--disable : Client is disabled.\n" " Only valid in a client-specific config file.\n" - "--client-cert-not-required : Don't require client certificate, client\n" + "--client-cert-not-required : (DEPRECATED) Don't require client certificate, client\n" " will authenticate using username/password.\n" "--verify-client-cert [none|optional|require] : perform no, optional or\n" " mandatory client certificate verification.\n" @@ -455,7 +456,7 @@ static const char usage_message[] = " with those of the server will be disconnected.\n" "--auth-user-pass-optional : Allow connections by clients that don't\n" " specify a username/password.\n" - "--no-name-remapping : Allow Common Name and X509 Subject to include\n" + "--no-name-remapping : (DEPRECATED) Allow Common Name and X509 Subject to include\n" " any printable character.\n" "--client-to-client : Internally route client-to-client traffic.\n" "--duplicate-cn : Allow multiple clients with the same common name to\n" @@ -539,13 +540,13 @@ static const char usage_message[] = "--prng alg [nsl] : For PRNG, use digest algorithm alg, and\n" " nonce_secret_len=nsl. Set alg=none to disable PRNG.\n" #ifdef HAVE_EVP_CIPHER_CTX_SET_KEY_LENGTH - "--keysize n : Size of cipher key in bits (optional).\n" + "--keysize n : (DEPRECATED) Size of cipher key in bits (optional).\n" " If unspecified, defaults to cipher-specific default.\n" #endif #ifndef ENABLE_CRYPTO_MBEDTLS "--engine [name] : Enable OpenSSL hardware crypto engine functionality.\n" #endif - "--no-replay : Disable replay protection.\n" + "--no-replay : (DEPRECATED) Disable replay protection.\n" "--mute-replay-warnings : Silence the output of replay warnings to log file.\n" "--replay-window n [t] : Use a replay protection sliding window of size n\n" " and a time window of t seconds.\n" @@ -564,7 +565,7 @@ static const char usage_message[] = "(These options are meaningful only for TLS-mode)\n" "--tls-server : Enable TLS and assume server role during TLS handshake.\n" "--tls-client : Enable TLS and assume client role during TLS handshake.\n" - "--key-method m : Data channel key exchange method. m should be a method\n" + "--key-method m : (DEPRECATED) Data channel key exchange method. m should be a method\n" " number, such as 1 (default), 2, etc.\n" "--ca file : Certificate authority file in .pem format containing\n" " root certificate.\n" @@ -599,6 +600,8 @@ static const char usage_message[] = #endif "--tls-cipher l : A list l of allowable TLS ciphers separated by : (optional).\n" " : Use --show-tls to see a list of supported TLS ciphers.\n" + "--tls-cert-profile p : Set the allowed certificate crypto algorithm profile\n" + " (default=legacy).\n" "--tls-timeout n : Packet retransmit timeout on TLS control channel\n" " if no ACK from remote within n seconds (default=%d).\n" "--reneg-bytes n : Renegotiate data chan. key after n bytes sent and recvd.\n" @@ -704,8 +707,7 @@ static const char usage_message[] = " which allow multiple addresses,\n" " --dhcp-option must be repeated.\n" " DOMAIN name : Set DNS suffix\n" - " DNS addr : Set domain name server address(es) (IPv4)\n" - " DNS6 addr : Set domain name server address(es) (IPv6)\n" + " DNS addr : Set domain name server address(es) (IPv4 and IPv6)\n" " NTP : Set NTP server address(es)\n" " NBDD : Set NBDD server address(es)\n" " WINS addr : Set WINS server address(es)\n" @@ -873,6 +875,7 @@ init_options(struct options *o, const bool init_gc) o->renegotiate_seconds = 3600; o->handshake_window = 60; o->transition_window = 3600; + o->tls_cert_profile = NULL; o->ecdh_curve = NULL; #ifdef ENABLE_X509ALTUSERNAME o->x509_username_field = X509_USERNAME_FIELD_DEFAULT; @@ -961,7 +964,7 @@ pull_filter_type_name(int type) #endif -void +static void setenv_connection_entry(struct env_set *es, const struct connection_entry *e, const int i) @@ -1231,6 +1234,20 @@ show_tuntap_options(const struct tuntap_options *o) #if defined(_WIN32) || defined(TARGET_ANDROID) static void +dhcp_option_dns6_parse(const char *parm, struct in6_addr *dns6_list, int *len, int msglevel) +{ + struct in6_addr addr; + if (*len >= N_DHCP_ADDR) + { + msg(msglevel, "--dhcp-option DNS: maximum of %d IPv6 dns servers can be specified", + N_DHCP_ADDR); + } + else if (get_ipv6_addr(parm, &addr, NULL, msglevel)) + { + dns6_list[(*len)++] = addr; + } +} +static void dhcp_option_address_parse(const char *name, const char *parm, in_addr_t *array, int *len, int msglevel) { if (*len >= N_DHCP_ADDR) @@ -1441,7 +1458,7 @@ rol_check_alloc(struct options *options) } } -void +static void rol6_check_alloc(struct options *options) { if (!options->routes_ipv6) @@ -1699,7 +1716,7 @@ show_settings(const struct options *o) #ifdef ENABLE_CRYPTO SHOW_STR(shared_secret_file); - SHOW_INT(key_direction); + SHOW_PARM(key_direction, keydirection2ascii(o->key_direction, false, true), "%s"); SHOW_STR(ciphername); SHOW_BOOL(ncp_enabled); SHOW_STR(ncp_ciphers); @@ -1752,6 +1769,7 @@ show_settings(const struct options *o) SHOW_STR(cryptoapi_cert); #endif SHOW_STR(cipher_list); + SHOW_STR(tls_cert_profile); SHOW_STR(tls_verify); SHOW_STR(tls_export_cert); SHOW_INT(verify_x509_type); @@ -1872,7 +1890,7 @@ parse_http_proxy_override(const char *server, } } -void +static void options_postprocess_http_proxy_override(struct options *o) { const struct connection_list *l = o->connection_list; @@ -1989,7 +2007,7 @@ alloc_pull_filter(struct options *o, const int msglevel) return f; } -void +static void connection_entry_load_re(struct connection_entry *ce, const struct remote_entry *re) { if (re->remote) @@ -2495,6 +2513,16 @@ options_postprocess_verify_ce(const struct options *options, const struct connec msg(M_WARN, "WARNING: --no-iv is deprecated and will be removed in 2.5"); } + if (options->keysize) + { + msg(M_WARN, "WARNING: --keysize is DEPRECATED and will be removed in OpenVPN 2.6"); + } + + if (!options->replay) + { + msg(M_WARN, "WARNING: --no-replay is DEPRECATED and will be removed in OpenVPN 2.5"); + } + /* * Check consistency of replay options */ @@ -2528,6 +2556,18 @@ options_postprocess_verify_ce(const struct options *options, const struct connec "in the configuration file, which is the recommended approach."); } + const int tls_version_max = + (options->ssl_flags >> SSLF_TLS_VERSION_MAX_SHIFT) + & SSLF_TLS_VERSION_MAX_MASK; + const int tls_version_min = + (options->ssl_flags >> SSLF_TLS_VERSION_MIN_SHIFT) + & SSLF_TLS_VERSION_MIN_MASK; + + if (tls_version_max > 0 && tls_version_max < tls_version_min) + { + msg(M_USAGE, "--tls-version-min bigger than --tls-version-max"); + } + if (options->tls_server || options->tls_client) { #ifdef ENABLE_PKCS11 @@ -2734,6 +2774,7 @@ options_postprocess_verify_ce(const struct options *options, const struct connec MUST_BE_UNDEF(pkcs12_file); #endif MUST_BE_UNDEF(cipher_list); + MUST_BE_UNDEF(tls_cert_profile); MUST_BE_UNDEF(tls_verify); MUST_BE_UNDEF(tls_export_cert); MUST_BE_UNDEF(verify_x509_name); @@ -3016,6 +3057,13 @@ options_postprocess_mutate(struct options *o) o->dh_file = NULL; } } + else if (o->dh_file) + { + /* DH file is only meaningful in a tls-server context. */ + msg(M_WARN, "WARNING: Ignoring option 'dh' in tls-client mode, please only " + "include this in your server configuration"); + o->dh_file = NULL; + } /* cipher negotiation (NCP) currently assumes --pull or --mode server */ if (o->ncp_enabled @@ -3034,24 +3082,6 @@ options_postprocess_mutate(struct options *o) } #endif -#ifdef ENABLE_CRYPTOAPI - if (o->cryptoapi_cert) - { - const int tls_version_max = - (o->ssl_flags >> SSLF_TLS_VERSION_MAX_SHIFT) - &SSLF_TLS_VERSION_MAX_MASK; - - if (tls_version_max == TLS_VER_UNSPEC || tls_version_max > TLS_VER_1_1) - { - msg(M_WARN, "Warning: cryptapicert used, setting maximum TLS " - "version to 1.1."); - o->ssl_flags &= ~(SSLF_TLS_VERSION_MAX_MASK - <<SSLF_TLS_VERSION_MAX_SHIFT); - o->ssl_flags |= (TLS_VER_1_1 << SSLF_TLS_VERSION_MAX_SHIFT); - } - } -#endif /* ENABLE_CRYPTOAPI */ - #if P2MP /* * Save certain parms before modifying options via --pull @@ -3148,8 +3178,7 @@ check_file_access(const int type, const char *file, const int mode, const char * /* Scream if an error is found */ if (errcode > 0) { - msg(M_NOPREFIX|M_OPTERR, "%s fails with '%s': %s", - opt, file, strerror(errno)); + msg(M_NOPREFIX | M_OPTERR | M_ERRNO, "%s fails with '%s'", opt, file); } /* Return true if an error occured */ @@ -3607,7 +3636,7 @@ options_string(const struct options *o, * Key direction */ { - const char *kd = keydirection2ascii(o->key_direction, remote); + const char *kd = keydirection2ascii(o->key_direction, remote, false); if (kd) { buf_printf(&out, ",keydir %s", kd); @@ -4154,7 +4183,7 @@ usage_version(void) show_windows_version( M_INFO|M_NOPREFIX ); #endif msg(M_INFO|M_NOPREFIX, "Originally developed by James Yonan"); - msg(M_INFO|M_NOPREFIX, "Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net>"); + msg(M_INFO|M_NOPREFIX, "Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net>"); #ifndef ENABLE_SMALL #ifdef CONFIGURE_DEFINES msg(M_INFO|M_NOPREFIX, "Compile time defines: %s", CONFIGURE_DEFINES); @@ -4569,7 +4598,7 @@ read_config_file(struct options *options, ++line_num; if (strlen(line) == OPTION_LINE_SIZE) { - msg(msglevel, "In %s:%d: Maximum optione line length (%d) exceeded, line starts with %s", + msg(msglevel, "In %s:%d: Maximum option line length (%d) exceeded, line starts with %s", file, line_num, OPTION_LINE_SIZE, line); } @@ -4828,11 +4857,13 @@ verify_permission(const char *name, #ifndef ENABLE_SMALL /* Check if this options is allowed in connection block, * but we are currently not in a connection block + * unless this is a pushed option. * Parsing a connection block uses a temporary options struct without * connection_list */ - if ((type & OPT_P_CONNECTION) && options->connection_list) + if ((type & OPT_P_CONNECTION) && options->connection_list + && !(allowed & OPT_P_PULL_MODE)) { if (file) { @@ -5235,8 +5266,10 @@ add_option(struct options *options, } else if (streq(p[0], "tun-ipv6") && !p[1]) { - VERIFY_PERMISSION(OPT_P_UP); - msg(M_WARN, "Note: option tun-ipv6 is ignored because modern operating systems do not need special IPv6 tun handling anymore."); + if (!pull_mode) + { + msg(M_WARN, "Note: option tun-ipv6 is ignored because modern operating systems do not need special IPv6 tun handling anymore."); + } } #ifdef ENABLE_IPROUTE else if (streq(p[0], "iproute") && p[1] && !p[2]) @@ -5885,7 +5918,7 @@ add_option(struct options *options, VERIFY_PERMISSION(OPT_P_GENERAL|OPT_P_CONNECTION); options->ce.remote_port = p[1]; } - else if (streq(p[0], "bind") && !p[1]) + else if (streq(p[0], "bind") && !p[2]) { VERIFY_PERMISSION(OPT_P_GENERAL|OPT_P_CONNECTION); options->ce.bind_defined = true; @@ -6198,7 +6231,7 @@ add_option(struct options *options, else if (streq(p[0], "max-routes") && !p[2]) { msg(M_WARN, "DEPRECATED OPTION: --max-routes option ignored." - "The number of routes is unlimited as of version 2.4. " + "The number of routes is unlimited as of OpenVPN 2.4. " "This option will be removed in a future version, " "please remove it from your configuration."); } @@ -6582,6 +6615,7 @@ add_option(struct options *options, { VERIFY_PERMISSION(OPT_P_GENERAL); options->topology = TOP_P2P; + msg(M_WARN, "DEPRECATED OPTION: --ifconfig-pool-linear, use --topology p2p instead"); } else if (streq(p[0], "ifconfig-ipv6-pool") && p[1] && !p[2]) { @@ -7028,7 +7062,7 @@ add_option(struct options *options, VERIFY_PERMISSION(OPT_P_GENERAL); if (streq(p[1], "env")) { - msg(M_INFO, "NOTE: --win-sys env is default from OpenVPN v2.3. " + msg(M_INFO, "NOTE: --win-sys env is default from OpenVPN 2.3. " "This entry will now be ignored. " "Please remove this entry from your configuration file."); } @@ -7120,6 +7154,7 @@ add_option(struct options *options, { struct tuntap_options *o = &options->tuntap_options; VERIFY_PERMISSION(OPT_P_IPWIN32); + bool ipv6dns = false; if (streq(p[1], "DOMAIN") && p[2]) { @@ -7140,22 +7175,17 @@ add_option(struct options *options, } o->netbios_node_type = t; } - else if (streq(p[1], "DNS") && p[2]) + else if ((streq(p[1], "DNS") || streq(p[1], "DNS6")) && p[2] && (!strstr(p[2], ":") || ipv6_addr_safe(p[2]))) { - dhcp_option_address_parse("DNS", p[2], o->dns, &o->dns_len, msglevel); - } - else if (streq(p[1], "DNS6") && p[2] && ipv6_addr_safe(p[2])) - { - struct in6_addr addr; - foreign_option(options, p, 3, es); - if (o->dns6_len >= N_DHCP_ADDR) + if (strstr(p[2], ":")) { - msg(msglevel, "--dhcp-option DNS6: maximum of %d dns servers can be specified", - N_DHCP_ADDR); + ipv6dns=true; + foreign_option(options, p, 3, es); + dhcp_option_dns6_parse(p[2], o->dns6, &o->dns6_len, msglevel); } - else if (get_ipv6_addr(p[2], &addr, NULL, msglevel)) + else { - o->dns6[o->dns6_len++] = addr; + dhcp_option_address_parse("DNS", p[2], o->dns, &o->dns_len, msglevel); } } else if (streq(p[1], "WINS") && p[2]) @@ -7183,7 +7213,7 @@ add_option(struct options *options, /* flag that we have options to give to the TAP driver's DHCPv4 server * - skipped for "DNS6", as that's not a DHCPv4 option */ - if (!streq(p[1], "DNS6")) + if (!ipv6dns) { o->dhcp_options = true; } @@ -7830,6 +7860,11 @@ add_option(struct options *options, VERIFY_PERMISSION(OPT_P_GENERAL); options->cipher_list = p[1]; } + else if (streq(p[0], "tls-cert-profile") && p[1] && !p[2]) + { + VERIFY_PERMISSION(OPT_P_GENERAL); + options->tls_cert_profile = p[1]; + } else if (streq(p[0], "crl-verify") && p[1] && ((p[2] && streq(p[2], "dir")) || (p[2] && streq(p[1], INLINE_FILE_TAG) ) || !p[2]) && !p[3]) { @@ -7874,7 +7909,7 @@ add_option(struct options *options, msg(msglevel, "you cannot use --compat-names with --verify-x509-name"); goto err; } - msg(M_WARN, "DEPRECATED OPTION: --compat-names, please update your configuration. This will be removed in OpenVPN v2.5."); + msg(M_WARN, "DEPRECATED OPTION: --compat-names, please update your configuration. This will be removed in OpenVPN 2.5."); compat_flag(COMPAT_FLAG_SET | COMPAT_NAMES); #if P2MP_SERVER if (p[1] && streq(p[1], "no-remapping")) @@ -7890,7 +7925,7 @@ add_option(struct options *options, msg(msglevel, "you cannot use --no-name-remapping with --verify-x509-name"); goto err; } - msg(M_WARN, "DEPRECATED OPTION: --no-name-remapping, please update your configuration. This will be removed in OpenVPN v2.5."); + msg(M_WARN, "DEPRECATED OPTION: --no-name-remapping, please update your configuration. This will be removed in OpenVPN 2.5."); compat_flag(COMPAT_FLAG_SET | COMPAT_NAMES); compat_flag(COMPAT_FLAG_SET | COMPAT_NO_NAME_REMAPPING); #endif diff --git a/src/openvpn/options.h b/src/openvpn/options.h index 67b9b94..0421c93 100644 --- a/src/openvpn/options.h +++ b/src/openvpn/options.h @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -181,7 +181,7 @@ struct options /* enable forward compatibility for post-2.1 features */ bool forward_compatible; - /* list of options that should be ignored even if unkown */ + /* list of options that should be ignored even if unknown */ const char **ignore_unknown_option; /* persist parms */ @@ -503,6 +503,7 @@ struct options const char *priv_key_file; const char *pkcs12_file; const char *cipher_list; + const char *tls_cert_profile; const char *ecdh_curve; const char *tls_verify; int verify_x509_type; diff --git a/src/openvpn/otime.c b/src/openvpn/otime.c index 3e576cc..805aac9 100644 --- a/src/openvpn/otime.c +++ b/src/openvpn/otime.c @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/otime.h b/src/openvpn/otime.h index 8731472..a6f7ec2 100644 --- a/src/openvpn/otime.h +++ b/src/openvpn/otime.h @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/packet_id.c b/src/openvpn/packet_id.c index 30ae8fb..d58761b 100644 --- a/src/openvpn/packet_id.c +++ b/src/openvpn/packet_id.c @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -643,7 +643,7 @@ packet_id_debug_print(int msglevel, #ifdef PID_TEST void -packet_id_interactive_test() +packet_id_interactive_test(void) { struct packet_id pid; struct packet_id_net pin; diff --git a/src/openvpn/packet_id.h b/src/openvpn/packet_id.h index a370936..f984e7c 100644 --- a/src/openvpn/packet_id.h +++ b/src/openvpn/packet_id.h @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -299,7 +299,7 @@ packet_id_persist_save_obj(struct packet_id_persist *p, const struct packet_id * const char *packet_id_net_print(const struct packet_id_net *pin, bool print_timestamp, struct gc_arena *gc); #ifdef PID_TEST -void packet_id_interactive_test(); +void packet_id_interactive_test(void); #endif diff --git a/src/openvpn/perf.c b/src/openvpn/perf.c index 16cf749..d882358 100644 --- a/src/openvpn/perf.c +++ b/src/openvpn/perf.c @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/perf.h b/src/openvpn/perf.h index ae5ae08..9cf0343 100644 --- a/src/openvpn/perf.h +++ b/src/openvpn/perf.h @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/pf-inline.h b/src/openvpn/pf-inline.h index ac19ac4..90cc41c 100644 --- a/src/openvpn/pf-inline.h +++ b/src/openvpn/pf-inline.h @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/pf.c b/src/openvpn/pf.c index 5cb002b..7277ae6 100644 --- a/src/openvpn/pf.c +++ b/src/openvpn/pf.c @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/pf.h b/src/openvpn/pf.h index 414c85b..ff75a00 100644 --- a/src/openvpn/pf.h +++ b/src/openvpn/pf.h @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/ping-inline.h b/src/openvpn/ping-inline.h index 0642b85..1a5c8bc 100644 --- a/src/openvpn/ping-inline.h +++ b/src/openvpn/ping-inline.h @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/ping.c b/src/openvpn/ping.c index 728d6c2..208170d 100644 --- a/src/openvpn/ping.c +++ b/src/openvpn/ping.c @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/ping.h b/src/openvpn/ping.h index 5bd5c08..05793b4 100644 --- a/src/openvpn/ping.h +++ b/src/openvpn/ping.h @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/pkcs11.c b/src/openvpn/pkcs11.c index 6041828..93f8580 100644 --- a/src/openvpn/pkcs11.c +++ b/src/openvpn/pkcs11.c @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -356,7 +356,7 @@ cleanup: } void -pkcs11_terminate() +pkcs11_terminate(void) { dmsg( D_PKCS11_DEBUG, @@ -422,13 +422,13 @@ pkcs11_addProvider( } int -pkcs11_logout() +pkcs11_logout(void) { return pkcs11h_logout() == CKR_OK; } int -pkcs11_management_id_count() +pkcs11_management_id_count(void) { pkcs11h_certificate_id_list_t id_list = NULL; pkcs11h_certificate_id_list_t t = NULL; diff --git a/src/openvpn/pkcs11.h b/src/openvpn/pkcs11.h index f1722c0..66c6a7e 100644 --- a/src/openvpn/pkcs11.h +++ b/src/openvpn/pkcs11.h @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/pkcs11_backend.h b/src/openvpn/pkcs11_backend.h index b47b757..e8fb664 100644 --- a/src/openvpn/pkcs11_backend.h +++ b/src/openvpn/pkcs11_backend.h @@ -5,8 +5,8 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> - * Copyright (C) 2010-2017 Fox Crypto B.V. <openvpn@fox-it.com> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> + * Copyright (C) 2010-2018 Fox Crypto B.V. <openvpn@fox-it.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/pkcs11_mbedtls.c b/src/openvpn/pkcs11_mbedtls.c index 45372e4..7620624 100644 --- a/src/openvpn/pkcs11_mbedtls.c +++ b/src/openvpn/pkcs11_mbedtls.c @@ -5,8 +5,8 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> - * Copyright (C) 2010-2017 Fox Crypto B.V. <openvpn@fox-it.com> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> + * Copyright (C) 2010-2018 Fox Crypto B.V. <openvpn@fox-it.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/pkcs11_openssl.c b/src/openvpn/pkcs11_openssl.c index c37425b..642769c 100644 --- a/src/openvpn/pkcs11_openssl.c +++ b/src/openvpn/pkcs11_openssl.c @@ -5,8 +5,8 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> - * Copyright (C) 2010-2017 Fox Crypto B.V. <openvpn@fox-it.com> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> + * Copyright (C) 2010-2018 Fox Crypto B.V. <openvpn@fox-it.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/platform.c b/src/openvpn/platform.c index 2495523..fbffd0f 100644 --- a/src/openvpn/platform.c +++ b/src/openvpn/platform.c @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -159,7 +159,7 @@ platform_nice(int niceval) errno = 0; if (nice(niceval) < 0 && errno != 0) { - msg(M_WARN | M_ERRNO, "WARNING: nice %d failed: %s", niceval, strerror(errno)); + msg(M_WARN | M_ERRNO, "WARNING: nice %d failed", niceval); } else { @@ -173,7 +173,7 @@ platform_nice(int niceval) /* Get current PID */ unsigned int -platform_getpid() +platform_getpid(void) { #ifdef _WIN32 return (unsigned int) GetCurrentProcessId(); diff --git a/src/openvpn/platform.h b/src/openvpn/platform.h index cd2bbc9..288937d 100644 --- a/src/openvpn/platform.h +++ b/src/openvpn/platform.h @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/plugin.c b/src/openvpn/plugin.c index 557b6bc..ddd9e85 100644 --- a/src/openvpn/plugin.c +++ b/src/openvpn/plugin.c @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/plugin.h b/src/openvpn/plugin.h index 0cffee0..ec2d1fe 100644 --- a/src/openvpn/plugin.h +++ b/src/openvpn/plugin.h @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/pool.c b/src/openvpn/pool.c index a8f15b9..da28bc0 100644 --- a/src/openvpn/pool.c +++ b/src/openvpn/pool.c @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/pool.h b/src/openvpn/pool.h index ee91d82..6de28ac 100644 --- a/src/openvpn/pool.h +++ b/src/openvpn/pool.h @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/proto.c b/src/openvpn/proto.c index 2cbea3a..87c18e8 100644 --- a/src/openvpn/proto.c +++ b/src/openvpn/proto.c @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/proto.h b/src/openvpn/proto.h index 57f25c9..985aa99 100644 --- a/src/openvpn/proto.h +++ b/src/openvpn/proto.h @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/proxy.c b/src/openvpn/proxy.c index 7a737ea..3fdec86 100644 --- a/src/openvpn/proxy.c +++ b/src/openvpn/proxy.c @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -253,9 +253,24 @@ username_password_as_base64(const struct http_proxy_info *p, } static void +clear_user_pass_http(void) +{ + purge_user_pass(&static_proxy_user_pass, true); +} + +static void get_user_pass_http(struct http_proxy_info *p, const bool force) { - if (!static_proxy_user_pass.defined || force) + /* + * in case of forced (re)load, make sure the static storage is set as + * undefined, otherwise get_user_pass() won't try to load any credential + */ + if (force) + { + clear_user_pass_http(); + } + + if (!static_proxy_user_pass.defined) { unsigned int flags = GET_USER_PASS_MANAGEMENT; if (p->queried_creds) @@ -274,11 +289,6 @@ get_user_pass_http(struct http_proxy_info *p, const bool force) p->up = static_proxy_user_pass; } } -static void -clear_user_pass_http(void) -{ - purge_user_pass(&static_proxy_user_pass, true); -} #if 0 /* function only used in #if 0 debug statement */ @@ -550,7 +560,7 @@ http_proxy_close(struct http_proxy_info *hp) free(hp); } -bool +static bool add_proxy_headers(struct http_proxy_info *p, socket_descriptor_t sd, /* already open to proxy */ const char *host, /* openvpn server remote */ diff --git a/src/openvpn/proxy.h b/src/openvpn/proxy.h index 3ce79de..707f7fa 100644 --- a/src/openvpn/proxy.h +++ b/src/openvpn/proxy.h @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/ps.c b/src/openvpn/ps.c index c2b05cd..25ab374 100644 --- a/src/openvpn/ps.c +++ b/src/openvpn/ps.c @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -172,7 +172,7 @@ send_control(const socket_descriptor_t fd, int code) } static int -cmsg_size() +cmsg_size(void) { return CMSG_SPACE(sizeof(socket_descriptor_t)); } @@ -922,7 +922,7 @@ port_share_open(const char *host, openvpn_close_socket(fd[1]); exit(0); - return 0; /* NOTREACHED */ + return NULL; /* NOTREACHED */ } error: diff --git a/src/openvpn/ps.h b/src/openvpn/ps.h index b8c6853..b4490f5 100644 --- a/src/openvpn/ps.h +++ b/src/openvpn/ps.h @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/push.c b/src/openvpn/push.c index 5947a31..6a30e47 100644 --- a/src/openvpn/push.c +++ b/src/openvpn/push.c @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -365,6 +365,7 @@ prepare_push_reply(struct context *c, struct gc_arena *gc, { push_option_fmt(gc, push_list, M_USAGE, "peer-id %d", tls_multi->peer_id); + tls_multi->use_peer_id = true; } } diff --git a/src/openvpn/push.h b/src/openvpn/push.h index 4d42e81..5f6181e 100644 --- a/src/openvpn/push.h +++ b/src/openvpn/push.h @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/pushlist.h b/src/openvpn/pushlist.h index 57216b2..23b0ee5 100644 --- a/src/openvpn/pushlist.h +++ b/src/openvpn/pushlist.h @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/reliable.c b/src/openvpn/reliable.c index 93541a9..8f5e173 100644 --- a/src/openvpn/reliable.c +++ b/src/openvpn/reliable.c @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/reliable.h b/src/openvpn/reliable.h index aa34b02..bc32ad9 100644 --- a/src/openvpn/reliable.h +++ b/src/openvpn/reliable.h @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/route.c b/src/openvpn/route.c index a1811f4..2d6428b 100644 --- a/src/openvpn/route.c +++ b/src/openvpn/route.c @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -518,14 +518,14 @@ add_route_ipv6_to_option_list(struct route_ipv6_option_list *l, l->routes_ipv6 = ro; } -void +static void clear_route_list(struct route_list *rl) { gc_free(&rl->gc); CLEAR(*rl); } -void +static void clear_route_ipv6_list(struct route_ipv6_list *rl6) { gc_free(&rl6->gc); @@ -1530,7 +1530,9 @@ add_route(struct route_ipv4 *r, struct gc_arena gc; struct argv argv = argv_new(); const char *network; +#if !defined(ENABLE_IPROUTE) && !defined(TARGET_AIX) const char *netmask; +#endif const char *gateway; bool status = false; int is_local_route; @@ -1543,7 +1545,9 @@ add_route(struct route_ipv4 *r, gc_init(&gc); network = print_in_addr_t(r->network, 0, &gc); +#if !defined(ENABLE_IPROUTE) && !defined(TARGET_AIX) netmask = print_in_addr_t(r->netmask, 0, &gc); +#endif gateway = print_in_addr_t(r->gateway, 0, &gc); is_local_route = local_route(r->network, r->netmask, r->gateway, rgi); @@ -1816,7 +1820,7 @@ done: } -static void +void route_ipv6_clear_host_bits( struct route_ipv6 *r6 ) { /* clear host bit parts of route @@ -1965,12 +1969,12 @@ add_route_ipv6(struct route_ipv6 *r6, const struct tuntap *tt, unsigned int flag struct buffer out = alloc_buf_gc(64, &gc); if (r6->adapter_index) /* vpn server special route */ { - buf_printf(&out, "interface=%d", r6->adapter_index ); + buf_printf(&out, "interface=%lu", r6->adapter_index ); gateway_needed = true; } else { - buf_printf(&out, "interface=%d", tt->adapter_index ); + buf_printf(&out, "interface=%lu", tt->adapter_index ); } device = buf_bptr(&out); @@ -2132,8 +2136,12 @@ delete_route(struct route_ipv4 *r, struct gc_arena gc; struct argv argv = argv_new(); const char *network; +#if !defined(ENABLE_IPROUTE) && !defined(TARGET_AIX) const char *netmask; +#endif +#if !defined(TARGET_LINUX) && !defined(TARGET_ANDROID) const char *gateway; +#endif int is_local_route; if ((r->flags & (RT_DEFINED|RT_ADDED)) != (RT_DEFINED|RT_ADDED)) @@ -2144,8 +2152,12 @@ delete_route(struct route_ipv4 *r, gc_init(&gc); network = print_in_addr_t(r->network, 0, &gc); +#if !defined(ENABLE_IPROUTE) && !defined(TARGET_AIX) netmask = print_in_addr_t(r->netmask, 0, &gc); +#endif +#if !defined(TARGET_LINUX) && !defined(TARGET_ANDROID) gateway = print_in_addr_t(r->gateway, 0, &gc); +#endif is_local_route = local_route(r->network, r->netmask, r->gateway, rgi); if (is_local_route == LR_ERROR) @@ -2404,12 +2416,12 @@ delete_route_ipv6(const struct route_ipv6 *r6, const struct tuntap *tt, unsigned struct buffer out = alloc_buf_gc(64, &gc); if (r6->adapter_index) /* vpn server special route */ { - buf_printf(&out, "interface=%d", r6->adapter_index ); + buf_printf(&out, "interface=%lu", r6->adapter_index ); gateway_needed = true; } else { - buf_printf(&out, "interface=%d", tt->adapter_index ); + buf_printf(&out, "interface=%lu", tt->adapter_index ); } device = buf_bptr(&out); @@ -2768,7 +2780,6 @@ windows_route_find_if_index(const struct route_ipv4 *r, const struct tuntap *tt) msg(M_WARN, "Warning: route gateway is ambiguous: %s (%d matches)", print_in_addr_t(r->gateway, 0, &gc), count); - ret = TUN_ADAPTER_INDEX_INVALID; } dmsg(D_ROUTE_DEBUG, "DEBUG: route find if: on_tun=%d count=%d index=%d", @@ -2830,7 +2841,7 @@ get_default_gateway_ipv6(struct route_ipv6_gateway_info *rgi6, goto done; } - msg( D_ROUTE, "GDG6: II=%d DP=%s/%d NH=%s", + msg( D_ROUTE, "GDG6: II=%lu DP=%s/%d NH=%s", BestRoute.InterfaceIndex, print_in6_addr( BestRoute.DestinationPrefix.Prefix.Ipv6.sin6_addr, 0, &gc), BestRoute.DestinationPrefix.PrefixLength, @@ -2991,7 +3002,7 @@ do_route_service(const bool add, const route_message_t *rt, const size_t size, H if (ack.error_number != NO_ERROR) { - msg(M_WARN, "ROUTE: route %s failed using service: %s [status=%u if_index=%lu]", + msg(M_WARN, "ROUTE: route %s failed using service: %s [status=%u if_index=%d]", (add ? "addition" : "deletion"), strerror_win32(ack.error_number, &gc), ack.error_number, rt->iface.index); goto out; @@ -3441,7 +3452,14 @@ get_default_gateway_ipv6(struct route_ipv6_gateway_info *rgi6, if (nh->nlmsg_type == NLMSG_ERROR) { struct nlmsgerr *ne = (struct nlmsgerr *)NLMSG_DATA(nh); - msg(M_WARN, "GDG6: NLSMG_ERROR: error %d\n", ne->error); + + /* since linux-4.11 -ENETUNREACH is returned when no route can be + * found. Don't print any error message in this case */ + if (ne->error != -ENETUNREACH) + { + msg(M_WARN, "GDG6: NLMSG_ERROR: error %s\n", + strerror(-ne->error)); + } break; } diff --git a/src/openvpn/route.h b/src/openvpn/route.h index 6414d6c..6942022 100644 --- a/src/openvpn/route.h +++ b/src/openvpn/route.h @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -254,6 +254,8 @@ void copy_route_ipv6_option_list(struct route_ipv6_option_list *dest, const struct route_ipv6_option_list *src, struct gc_arena *a); +void route_ipv6_clear_host_bits( struct route_ipv6 *r6 ); + void add_route_ipv6(struct route_ipv6 *r, const struct tuntap *tt, unsigned int flags, const struct env_set *es); void delete_route_ipv6(const struct route_ipv6 *r, const struct tuntap *tt, unsigned int flags, const struct env_set *es); diff --git a/src/openvpn/schedule.c b/src/openvpn/schedule.c index b1ba5d4..76cf7c3 100644 --- a/src/openvpn/schedule.c +++ b/src/openvpn/schedule.c @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/schedule.h b/src/openvpn/schedule.h index e6c1b7e..74d37fb 100644 --- a/src/openvpn/schedule.h +++ b/src/openvpn/schedule.h @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/session_id.c b/src/openvpn/session_id.c index dce42e7..2b50feb 100644 --- a/src/openvpn/session_id.c +++ b/src/openvpn/session_id.c @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/session_id.h b/src/openvpn/session_id.h index 6611a3c..5e950a6 100644 --- a/src/openvpn/session_id.h +++ b/src/openvpn/session_id.h @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/shaper.c b/src/openvpn/shaper.c index 19dd54d..00eb2e9 100644 --- a/src/openvpn/shaper.c +++ b/src/openvpn/shaper.c @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/shaper.h b/src/openvpn/shaper.h index 6fac16d..0496c71 100644 --- a/src/openvpn/shaper.h +++ b/src/openvpn/shaper.h @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/sig.c b/src/openvpn/sig.c index 87cef71..d7f2abb 100644 --- a/src/openvpn/sig.c +++ b/src/openvpn/sig.c @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/sig.h b/src/openvpn/sig.h index 7c41070..887d833 100644 --- a/src/openvpn/sig.h +++ b/src/openvpn/sig.h @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/socket.c b/src/openvpn/socket.c index 4e7e3f9..211e744 100644 --- a/src/openvpn/socket.c +++ b/src/openvpn/socket.c @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -496,7 +496,7 @@ openvpn_getaddrinfo(unsigned int flags, goto done; } - openvpn_sleep(fail_wait_interval); + management_sleep(fail_wait_interval); } ASSERT(res); @@ -1122,7 +1122,7 @@ socket_do_accept(socket_descriptor_t sd, if (!socket_defined(new_sd)) { - msg(D_LINK_ERRORS | M_ERRNO, "TCP: accept(%d) failed", sd); + msg(D_LINK_ERRORS | M_ERRNO, "TCP: accept(%d) failed", (int)sd); } /* only valid if we have remote_len_af!=0 */ else if (remote_len_af && remote_len != remote_len_af) @@ -1193,7 +1193,7 @@ socket_listen_accept(socket_descriptor_t sd, if (status <= 0) { - openvpn_sleep(1); + management_sleep(1); continue; } @@ -1228,7 +1228,7 @@ socket_listen_accept(socket_descriptor_t sd, break; } } - openvpn_sleep(1); + management_sleep(1); } if (!nowait && openvpn_close_socket(sd)) @@ -1297,11 +1297,9 @@ socket_bind(socket_descriptor_t sd, } if (bind(sd, cur->ai_addr, cur->ai_addrlen)) { - const int errnum = openvpn_errno(); - msg(M_FATAL, "%s: Socket bind failed on local address %s: %s", + msg(M_FATAL | M_ERRNO, "%s: Socket bind failed on local address %s", prefix, - print_sockaddr_ex(local->ai_addr, ":", PS_SHOW_PORT, &gc), - strerror_ts(errnum, &gc)); + print_sockaddr_ex(local->ai_addr, ":", PS_SHOW_PORT, &gc)); } gc_free(&gc); } @@ -1376,7 +1374,7 @@ openvpn_connect(socket_descriptor_t sd, #endif break; } - openvpn_sleep(1); + management_sleep(1); continue; } @@ -1433,7 +1431,7 @@ set_actual_address(struct link_socket_actual *actual, struct addrinfo *ai) } -void +static void socket_connect(socket_descriptor_t *sd, const struct sockaddr *dest, const int connect_timeout, @@ -1475,10 +1473,8 @@ socket_connect(socket_descriptor_t *sd, if (status) { - msg(D_LINK_ERRORS, - "TCP: connect to %s failed: %s", - print_sockaddr(dest, &gc), - strerror_ts(status, &gc)); + msg(D_LINK_ERRORS, "TCP: connect to %s failed: %s", + print_sockaddr(dest, &gc), strerror(status)); openvpn_close_socket(*sd); *sd = SOCKET_UNDEFINED; @@ -1790,6 +1786,8 @@ link_socket_init_phase1(struct link_socket *sock, ASSERT(sock->info.proto == PROTO_TCP_SERVER); ASSERT(!sock->inetd); sock->sd = accept_from->sd; + /* inherit (possibly guessed) info AF from parent context */ + sock->info.af = accept_from->info.af; } /* are we running in HTTP proxy mode? */ @@ -1877,12 +1875,12 @@ phase2_inetd(struct link_socket *sock, const struct frame *frame, sock->info.lsa->actual.dest.addr.sa.sa_family = local_addr.addr.sa.sa_family; dmsg(D_SOCKET_DEBUG, "inetd(%s): using sa_family=%d from getsockname(%d)", proto2ascii(sock->info.proto, sock->info.af, false), - local_addr.addr.sa.sa_family, sock->sd); + local_addr.addr.sa.sa_family, (int)sock->sd); } else { msg(M_WARN, "inetd(%s): getsockname(%d) failed, using AF_INET", - proto2ascii(sock->info.proto, sock->info.af, false), sock->sd); + proto2ascii(sock->info.proto, sock->info.af, false), (int)sock->sd); } } #else /* ifdef HAVE_GETSOCKNAME */ @@ -3888,12 +3886,11 @@ socket_bind_unix(socket_descriptor_t sd, if (bind(sd, (struct sockaddr *) local, sizeof(struct sockaddr_un))) { - const int errnum = openvpn_errno(); - msg(M_FATAL, "%s: Socket bind[%d] failed on unix domain socket %s: %s", + msg(M_FATAL | M_ERRNO, + "%s: Socket bind[%d] failed on unix domain socket %s", prefix, (int)sd, - sockaddr_unix_name(local, "NULL"), - strerror_ts(errnum, &gc)); + sockaddr_unix_name(local, "NULL")); } #ifdef HAVE_UMASK diff --git a/src/openvpn/socket.h b/src/openvpn/socket.h index 2d7f218..479d115 100644 --- a/src/openvpn/socket.h +++ b/src/openvpn/socket.h @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/socks.c b/src/openvpn/socks.c index 92747ec..c61ef55 100644 --- a/src/openvpn/socks.c +++ b/src/openvpn/socks.c @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/socks.h b/src/openvpn/socks.h index 39b96c5..aef873c 100644 --- a/src/openvpn/socks.h +++ b/src/openvpn/socks.h @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/ssl.c b/src/openvpn/ssl.c index 15cd94a..effb8b2 100644 --- a/src/openvpn/ssl.c +++ b/src/openvpn/ssl.c @@ -5,8 +5,8 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> - * Copyright (C) 2010-2017 Fox Crypto B.V. <openvpn@fox-it.com> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> + * Copyright (C) 2010-2018 Fox Crypto B.V. <openvpn@fox-it.com> * Copyright (C) 2008-2013 David Sommerseth <dazo@users.sourceforge.net> * * This program is free software; you can redistribute it and/or modify @@ -347,7 +347,7 @@ tls_init_control_channel_frame_parameters(const struct frame *data_channel_frame } void -init_ssl_lib() +init_ssl_lib(void) { tls_init_lib(); @@ -355,7 +355,7 @@ init_ssl_lib() } void -free_ssl_lib() +free_ssl_lib(void) { crypto_uninit_lib(); prng_uninit(); @@ -530,6 +530,10 @@ tls_version_parse(const char *vstr, const char *extra) { return TLS_VER_1_2; } + else if (!strcmp(vstr, "1.3") && TLS_VER_1_3 <= max_version) + { + return TLS_VER_1_3; + } else if (extra && !strcmp(extra, "or-highest")) { return max_version; @@ -616,7 +620,18 @@ init_ssl(const struct options *options, struct tls_root_ctx *new_ctx) tls_ctx_client_new(new_ctx); } - tls_ctx_set_options(new_ctx, options->ssl_flags); + /* Restrict allowed certificate crypto algorithms */ + tls_ctx_set_cert_profile(new_ctx, options->tls_cert_profile); + + /* Allowable ciphers */ + /* Since @SECLEVEL also influces loading of certificates, set the + * cipher restrictions before loading certificates */ + tls_ctx_restrict_ciphers(new_ctx, options->cipher_list); + + if (!tls_ctx_set_options(new_ctx, options->ssl_flags)) + { + goto err; + } if (options->pkcs12_file) { @@ -708,9 +723,6 @@ init_ssl(const struct options *options, struct tls_root_ctx *new_ctx) tls_ctx_load_ecdh_params(new_ctx, options->ecdh_curve); } - /* Allowable ciphers */ - tls_ctx_restrict_ciphers(new_ctx, options->cipher_list); - #ifdef ENABLE_CRYPTO_MBEDTLS /* Personalise the random by mixing in the certificate */ tls_ctx_personalise_random(new_ctx); @@ -1532,7 +1544,7 @@ read_control_auth(struct buffer *buf, } else if (ctx->mode == TLS_WRAP_CRYPT) { - struct buffer tmp = alloc_buf(buf_forward_capacity_total(buf)); + struct buffer tmp = alloc_buf_gc(buf_forward_capacity_total(buf), &gc); if (!tls_crypt_unwrap(buf, &tmp, &ctx->opt)) { msg(D_TLS_ERRORS, "TLS Error: tls-crypt unwrapping failed from %s", @@ -1541,7 +1553,7 @@ read_control_auth(struct buffer *buf, } ASSERT(buf_init(buf, buf->offset)); ASSERT(buf_copy(buf, &tmp)); - free_buf(&tmp); + buf_clear(&tmp); } if (ctx->mode == TLS_WRAP_NONE || ctx->mode == TLS_WRAP_AUTH) @@ -1605,7 +1617,7 @@ key_source2_print(const struct key_source2 *k) * @param out Output buffer * @param olen Length of the output buffer */ -void +static void tls1_P_hash(const md_kt_t *md_kt, const uint8_t *sec, int sec_len, @@ -1838,20 +1850,8 @@ generate_key_expansion(struct key_ctx_bi *key, } /* Initialize OpenSSL key contexts */ - - ASSERT(server == true || server == false); - - init_key_ctx(&key->encrypt, - &key2.keys[(int)server], - key_type, - OPENVPN_OP_ENCRYPT, - "Data Channel Encrypt"); - - init_key_ctx(&key->decrypt, - &key2.keys[1-(int)server], - key_type, - OPENVPN_OP_DECRYPT, - "Data Channel Decrypt"); + int key_direction = server ? KEY_DIRECTION_INVERSE : KEY_DIRECTION_NORMAL; + init_key_ctx_bi(key, &key2, key_direction, key_type, "Data Channel"); /* Initialize implicit IVs */ key_ctx_update_implicit_iv(&key->encrypt, key2.keys[(int)server].hmac, @@ -1859,7 +1859,6 @@ generate_key_expansion(struct key_ctx_bi *key, key_ctx_update_implicit_iv(&key->decrypt, key2.keys[1-(int)server].hmac, MAX_HMAC_KEY_LENGTH); - key->initialized = true; ret = true; exit: @@ -1958,7 +1957,7 @@ cleanup: bool tls_session_update_crypto_params(struct tls_session *session, - const struct options *options, struct frame *frame) + struct options *options, struct frame *frame) { if (!session->opt->server && 0 != strcmp(options->ciphername, session->opt->config_ciphername) @@ -1967,6 +1966,8 @@ tls_session_update_crypto_params(struct tls_session *session, msg(D_TLS_ERRORS, "Error: pushed cipher not allowed - %s not in %s or %s", options->ciphername, session->opt->config_ciphername, options->ncp_ciphers); + /* undo cipher push, abort connection setup */ + options->ciphername = session->opt->config_ciphername; return false; } @@ -1974,6 +1975,11 @@ tls_session_update_crypto_params(struct tls_session *session, { msg(D_HANDSHAKE, "Data Channel: using negotiated cipher '%s'", options->ciphername); + if (options->keysize) + { + msg(D_HANDSHAKE, "NCP: overriding user-set keysize with default"); + options->keysize = 0; + } } init_key_type(&session->opt->key_type, options->ciphername, @@ -2186,16 +2192,6 @@ read_string_alloc(struct buffer *buf) return str; } -void -read_string_discard(struct buffer *buf) -{ - char *data = read_string_alloc(buf); - if (data) - { - free(data); - } -} - /* * Handle the reading and writing of key data to and from * the TLS control channel (cleartext). @@ -3369,7 +3365,7 @@ tls_pre_decrypt(struct tls_multi *multi, { if (!ks->crypto_options.key_ctx_bi.initialized) { - msg(D_TLS_DEBUG_LOW, + msg(D_MULTI_DROPPED, "Key %s [%d] not initialized (yet), dropping packet.", print_link_socket_actual(from, &gc), key_id); goto error_lite; diff --git a/src/openvpn/ssl.h b/src/openvpn/ssl.h index 56ea601..132424e 100644 --- a/src/openvpn/ssl.h +++ b/src/openvpn/ssl.h @@ -5,8 +5,8 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> - * Copyright (C) 2010-2017 Fox Crypto B.V. <openvpn@fox-it.com> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> + * Copyright (C) 2010-2018 Fox Crypto B.V. <openvpn@fox-it.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -481,7 +481,7 @@ void tls_update_remote_addr(struct tls_multi *multi, * @return true if updating succeeded, false otherwise. */ bool tls_session_update_crypto_params(struct tls_session *session, - const struct options *options, struct frame *frame); + struct options *options, struct frame *frame); /** * "Poor man's NCP": Use peer cipher if it is an allowed (NCP) cipher. diff --git a/src/openvpn/ssl_backend.h b/src/openvpn/ssl_backend.h index a738f0f..e704de8 100644 --- a/src/openvpn/ssl_backend.h +++ b/src/openvpn/ssl_backend.h @@ -5,8 +5,8 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> - * Copyright (C) 2010-2017 Fox Crypto B.V. <openvpn@fox-it.com> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> + * Copyright (C) 2010-2018 Fox Crypto B.V. <openvpn@fox-it.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -88,17 +88,17 @@ int pem_password_callback(char *buf, int size, int rwflag, void *u); * Perform any static initialisation necessary by the library. * Called on OpenVPN initialisation */ -void tls_init_lib(); +void tls_init_lib(void); /** * Free any global SSL library-specific data structures. */ -void tls_free_lib(); +void tls_free_lib(void); /** * Clear the underlying SSL library's error state. */ -void tls_clear_error(); +void tls_clear_error(void); /** * Parse a TLS version specifier @@ -114,6 +114,7 @@ void tls_clear_error(); #define TLS_VER_1_0 1 #define TLS_VER_1_1 2 #define TLS_VER_1_2 3 +#define TLS_VER_1_3 4 int tls_version_parse(const char *vstr, const char *extra); /** @@ -164,8 +165,10 @@ bool tls_ctx_initialised(struct tls_root_ctx *ctx); * * @param ctx TLS context to set options on * @param ssl_flags SSL flags to set + * + * @return true on success, false otherwise. */ -void tls_ctx_set_options(struct tls_root_ctx *ctx, unsigned int ssl_flags); +bool tls_ctx_set_options(struct tls_root_ctx *ctx, unsigned int ssl_flags); /** * Restrict the list of ciphers that can be used within the TLS context. @@ -177,6 +180,16 @@ void tls_ctx_set_options(struct tls_root_ctx *ctx, unsigned int ssl_flags); void tls_ctx_restrict_ciphers(struct tls_root_ctx *ctx, const char *ciphers); /** + * Set the TLS certificate profile. The profile defines which crypto + * algorithms may be used in the supplied certificate. + * + * @param ctx TLS context to restrict, must be valid. + * @param profile The profile name ('preferred', 'legacy' or 'suiteb'). + * Defaults to 'preferred' if NULL. + */ +void tls_ctx_set_cert_profile(struct tls_root_ctx *ctx, const char *profile); + +/** * Check our certificate notBefore and notAfter fields, and warn if the cert is * either not yet valid or has expired. Note that this is a non-fatal error, * since we compare against the system time, which might be incorrect. @@ -505,9 +518,12 @@ void print_details(struct key_state_ssl *ks_ssl, const char *prefix); * Show the TLS ciphers that are available for us to use in the OpenSSL * library. * - * @param - list of allowed TLS cipher, or NULL. + * @param cipher_list list of allowed TLS cipher, or NULL. + * @param tls_cert_profile TLS certificate crypto profile name. */ -void show_available_tls_ciphers(const char *tls_ciphers); +void +show_available_tls_ciphers(const char *cipher_list, + const char *tls_cert_profile); /* * Show the available elliptic curves in the crypto library diff --git a/src/openvpn/ssl_common.h b/src/openvpn/ssl_common.h index 25bffd5..c7565d8 100644 --- a/src/openvpn/ssl_common.h +++ b/src/openvpn/ssl_common.h @@ -5,8 +5,8 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> - * Copyright (C) 2010-2017 Fox Crypto B.V. <openvpn@fox-it.com> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> + * Copyright (C) 2010-2018 Fox Crypto B.V. <openvpn@fox-it.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/ssl_mbedtls.c b/src/openvpn/ssl_mbedtls.c index ef583e6..74b4726 100644 --- a/src/openvpn/ssl_mbedtls.c +++ b/src/openvpn/ssl_mbedtls.c @@ -5,8 +5,8 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> - * Copyright (C) 2010-2017 Fox Crypto B.V. <openvpn@fox-it.com> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> + * Copyright (C) 2010-2018 Fox Crypto B.V. <openvpn@fox-it.com> * Copyright (C) 2006-2010, Brainspark B.V. * * This program is free software; you can redistribute it and/or modify @@ -60,20 +60,47 @@ #include <mbedtls/oid.h> #include <mbedtls/pem.h> -#include <mbedtls/sha256.h> + +static const mbedtls_x509_crt_profile openvpn_x509_crt_profile_legacy = +{ + /* Hashes from SHA-1 and above */ + MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA1 ) | + MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_RIPEMD160 ) | + MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA224 ) | + MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA256 ) | + MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384 ) | + MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA512 ), + 0xFFFFFFF, /* Any PK alg */ + 0xFFFFFFF, /* Any curve */ + 1024, /* RSA-1024 and larger */ +}; + +static const mbedtls_x509_crt_profile openvpn_x509_crt_profile_preferred = +{ + /* SHA-2 and above */ + MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA224 ) | + MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA256 ) | + MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384 ) | + MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA512 ), + 0xFFFFFFF, /* Any PK alg */ + 0xFFFFFFF, /* Any curve */ + 2048, /* RSA-2048 and larger */ +}; + +#define openvpn_x509_crt_profile_suiteb mbedtls_x509_crt_profile_suiteb; void -tls_init_lib() +tls_init_lib(void) { } void -tls_free_lib() +tls_free_lib(void) { } void -tls_clear_error() +tls_clear_error(void) { } @@ -178,9 +205,10 @@ key_state_export_keying_material(struct key_state_ssl *ssl, { } -void +bool tls_ctx_set_options(struct tls_root_ctx *ctx, unsigned int ssl_flags) { + return true; } static const char * @@ -251,6 +279,27 @@ tls_ctx_restrict_ciphers(struct tls_root_ctx *ctx, const char *ciphers) } void +tls_ctx_set_cert_profile(struct tls_root_ctx *ctx, const char *profile) +{ + if (!profile || 0 == strcmp(profile, "legacy")) + { + ctx->cert_profile = openvpn_x509_crt_profile_legacy; + } + else if (0 == strcmp(profile, "preferred")) + { + ctx->cert_profile = openvpn_x509_crt_profile_preferred; + } + else if (0 == strcmp(profile, "suiteb")) + { + ctx->cert_profile = openvpn_x509_crt_profile_suiteb; + } + else + { + msg (M_FATAL, "ERROR: Invalid cert profile: %s", profile); + } +} + +void tls_ctx_check_cert_time(const struct tls_root_ctx *ctx) { ASSERT(ctx); @@ -801,9 +850,14 @@ tls_ctx_personalise_random(struct tls_root_ctx *ctx) if (NULL != ctx->crt_chain) { + const md_kt_t *sha256_kt = md_kt_get("SHA256"); mbedtls_x509_crt *cert = ctx->crt_chain; - mbedtls_sha256(cert->tbs.p, cert->tbs.len, sha256_hash, false); + if (0 != md_full(sha256_kt, cert->tbs.p, cert->tbs.len, sha256_hash)) + { + msg(M_WARN, "WARNING: failed to personalise random"); + } + if (0 != memcmp(old_sha256_hash, sha256_hash, sizeof(sha256_hash))) { mbedtls_ctr_drbg_update(cd_ctx, sha256_hash, 32); @@ -917,6 +971,8 @@ key_state_ssl_init(struct key_state_ssl *ks_ssl, mbedtls_ssl_conf_rng(&ks_ssl->ssl_config, mbedtls_ctr_drbg_random, rand_ctx_get()); + mbedtls_ssl_conf_cert_profile(&ks_ssl->ssl_config, &ssl_ctx->cert_profile); + if (ssl_ctx->allowed_ciphers) { mbedtls_ssl_conf_ciphersuites(&ks_ssl->ssl_config, ssl_ctx->allowed_ciphers); @@ -1271,12 +1327,14 @@ print_details(struct key_state_ssl *ks_ssl, const char *prefix) } void -show_available_tls_ciphers(const char *cipher_list) +show_available_tls_ciphers(const char *cipher_list, + const char *tls_cert_profile) { struct tls_root_ctx tls_ctx; const int *ciphers = mbedtls_ssl_list_ciphersuites(); tls_ctx_server_new(&tls_ctx); + tls_ctx_set_cert_profile(&tls_ctx, tls_cert_profile); tls_ctx_restrict_ciphers(&tls_ctx, cipher_list); if (tls_ctx.allowed_ciphers) diff --git a/src/openvpn/ssl_mbedtls.h b/src/openvpn/ssl_mbedtls.h index f69b610..dd8ca75 100644 --- a/src/openvpn/ssl_mbedtls.h +++ b/src/openvpn/ssl_mbedtls.h @@ -5,8 +5,8 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> - * Copyright (C) 2010-2017 Fox Crypto B.V. <openvpn@fox-it.com> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> + * Copyright (C) 2010-2018 Fox Crypto B.V. <openvpn@fox-it.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -82,6 +82,7 @@ struct tls_root_ctx { struct external_context *external_key; /**< Management external key */ #endif int *allowed_ciphers; /**< List of allowed ciphers for this connection */ + mbedtls_x509_crt_profile cert_profile; /**< Allowed certificate types */ }; struct key_state_ssl { diff --git a/src/openvpn/ssl_openssl.c b/src/openvpn/ssl_openssl.c index e589dcd..f23d246 100644 --- a/src/openvpn/ssl_openssl.c +++ b/src/openvpn/ssl_openssl.c @@ -5,8 +5,8 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> - * Copyright (C) 2010-2017 Fox Crypto B.V. <openvpn@fox-it.com> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> + * Copyright (C) 2010-2018 Fox Crypto B.V. <openvpn@fox-it.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -69,7 +69,7 @@ int mydata_index; /* GLOBAL */ void -tls_init_lib() +tls_init_lib(void) { SSL_library_init(); #ifndef ENABLE_SMALL @@ -82,7 +82,7 @@ tls_init_lib() } void -tls_free_lib() +tls_free_lib(void) { EVP_cleanup(); #ifndef ENABLE_SMALL @@ -91,7 +91,7 @@ tls_free_lib() } void -tls_clear_error() +tls_clear_error(void) { ERR_clear_error(); } @@ -206,16 +206,73 @@ info_callback(INFO_CALLBACK_SSL_CONST SSL *s, int where, int ret) int tls_version_max(void) { -#if defined(SSL_OP_NO_TLSv1_2) +#if defined(TLS1_3_VERSION) + return TLS_VER_1_3; +#elif defined(TLS1_2_VERSION) || defined(SSL_OP_NO_TLSv1_2) return TLS_VER_1_2; -#elif defined(SSL_OP_NO_TLSv1_1) +#elif defined(TLS1_1_VERSION) || defined(SSL_OP_NO_TLSv1_1) return TLS_VER_1_1; #else return TLS_VER_1_0; #endif } -void +/** Convert internal version number to openssl version number */ +static int +openssl_tls_version(int ver) +{ + if (ver == TLS_VER_1_0) + { + return TLS1_VERSION; + } + else if (ver == TLS_VER_1_1) + { + return TLS1_1_VERSION; + } + else if (ver == TLS_VER_1_2) + { + return TLS1_2_VERSION; + } +#if defined(TLS1_3_VERSION) + else if (ver == TLS_VER_1_3) + { + return TLS1_3_VERSION; + } +#endif + return 0; +} + +static bool +tls_ctx_set_tls_versions(struct tls_root_ctx *ctx, unsigned int ssl_flags) +{ + int tls_ver_min = openssl_tls_version( + (ssl_flags >> SSLF_TLS_VERSION_MIN_SHIFT) & SSLF_TLS_VERSION_MIN_MASK); + int tls_ver_max = openssl_tls_version( + (ssl_flags >> SSLF_TLS_VERSION_MAX_SHIFT) & SSLF_TLS_VERSION_MAX_MASK); + + if (!tls_ver_min) + { + /* Enforce at least TLS 1.0 */ + int cur_min = SSL_CTX_get_min_proto_version(ctx->ctx); + tls_ver_min = cur_min < TLS1_VERSION ? TLS1_VERSION : cur_min; + } + + if (!SSL_CTX_set_min_proto_version(ctx->ctx, tls_ver_min)) + { + msg(D_TLS_ERRORS, "%s: failed to set minimum TLS version", __func__); + return false; + } + + if (tls_ver_max && !SSL_CTX_set_max_proto_version(ctx->ctx, tls_ver_max)) + { + msg(D_TLS_ERRORS, "%s: failed to set maximum TLS version", __func__); + return false; + } + + return true; +} + +bool tls_ctx_set_options(struct tls_root_ctx *ctx, unsigned int ssl_flags) { ASSERT(NULL != ctx); @@ -223,41 +280,21 @@ tls_ctx_set_options(struct tls_root_ctx *ctx, unsigned int ssl_flags) /* default certificate verification flags */ int flags = SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT; - /* process SSL options including minimum TLS version we will accept from peer */ - { - long sslopt = SSL_OP_SINGLE_DH_USE | SSL_OP_NO_TICKET | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3; - int tls_ver_max = TLS_VER_UNSPEC; - const int tls_ver_min = - (ssl_flags >> SSLF_TLS_VERSION_MIN_SHIFT) & SSLF_TLS_VERSION_MIN_MASK; - - tls_ver_max = - (ssl_flags >> SSLF_TLS_VERSION_MAX_SHIFT) & SSLF_TLS_VERSION_MAX_MASK; - if (tls_ver_max <= TLS_VER_UNSPEC) - { - tls_ver_max = tls_version_max(); - } - - if (tls_ver_min > TLS_VER_1_0 || tls_ver_max < TLS_VER_1_0) - { - sslopt |= SSL_OP_NO_TLSv1; - } -#ifdef SSL_OP_NO_TLSv1_1 - if (tls_ver_min > TLS_VER_1_1 || tls_ver_max < TLS_VER_1_1) - { - sslopt |= SSL_OP_NO_TLSv1_1; - } -#endif -#ifdef SSL_OP_NO_TLSv1_2 - if (tls_ver_min > TLS_VER_1_2 || tls_ver_max < TLS_VER_1_2) - { - sslopt |= SSL_OP_NO_TLSv1_2; - } + /* process SSL options */ + long sslopt = SSL_OP_SINGLE_DH_USE | SSL_OP_NO_TICKET; +#ifdef SSL_OP_CIPHER_SERVER_PREFERENCE + sslopt |= SSL_OP_CIPHER_SERVER_PREFERENCE; #endif #ifdef SSL_OP_NO_COMPRESSION - /* Disable compression - flag not available in OpenSSL 0.9.8 */ - sslopt |= SSL_OP_NO_COMPRESSION; + /* Disable compression - flag not available in OpenSSL 0.9.8 */ + sslopt |= SSL_OP_NO_COMPRESSION; #endif - SSL_CTX_set_options(ctx->ctx, sslopt); + + SSL_CTX_set_options(ctx->ctx, sslopt); + + if (!tls_ctx_set_tls_versions(ctx, ssl_flags)) + { + return false; } #ifdef SSL_MODE_RELEASE_BUFFERS @@ -280,6 +317,8 @@ tls_ctx_set_options(struct tls_root_ctx *ctx, unsigned int ssl_flags) SSL_CTX_set_verify(ctx->ctx, flags, verify_callback); SSL_CTX_set_info_callback(ctx->ctx, info_callback); + + return true; } void @@ -384,6 +423,40 @@ tls_ctx_restrict_ciphers(struct tls_root_ctx *ctx, const char *ciphers) } void +tls_ctx_set_cert_profile(struct tls_root_ctx *ctx, const char *profile) +{ +#ifdef HAVE_SSL_CTX_SET_SECURITY_LEVEL + /* OpenSSL does not have certificate profiles, but a complex set of + * callbacks that we could try to implement to achieve something similar. + * For now, use OpenSSL's security levels to achieve similar (but not equal) + * behaviour. */ + if (!profile || 0 == strcmp(profile, "legacy")) + { + SSL_CTX_set_security_level(ctx->ctx, 1); + } + else if (0 == strcmp(profile, "preferred")) + { + SSL_CTX_set_security_level(ctx->ctx, 2); + } + else if (0 == strcmp(profile, "suiteb")) + { + SSL_CTX_set_security_level(ctx->ctx, 3); + SSL_CTX_set_cipher_list(ctx->ctx, "SUITEB128"); + } + else + { + msg(M_FATAL, "ERROR: Invalid cert profile: %s", profile); + } +#else + if (profile) + { + msg(M_WARN, "WARNING: OpenSSL 1.0.1 does not support --tls-cert-profile" + ", ignoring user-set profile: '%s'", profile); + } +#endif +} + +void tls_ctx_check_cert_time(const struct tls_root_ctx *ctx) { int ret; @@ -487,15 +560,7 @@ tls_ctx_load_ecdh_params(struct tls_root_ctx *ctx, const char *curve_name /* Generate a new ECDH key for each SSL session (for non-ephemeral ECDH) */ SSL_CTX_set_options(ctx->ctx, SSL_OP_SINGLE_ECDH_USE); -#if OPENSSL_VERSION_NUMBER >= 0x10002000L - /* OpenSSL 1.0.2 and newer can automatically handle ECDH parameter loading */ - if (NULL == curve_name) - { - SSL_CTX_set_ecdh_auto(ctx->ctx, 1); - return; - } -#endif - /* For older OpenSSL, we'll have to do the parameter loading on our own */ + if (curve_name != NULL) { /* Use user supplied curve if given */ @@ -504,14 +569,17 @@ tls_ctx_load_ecdh_params(struct tls_root_ctx *ctx, const char *curve_name } else { - /* Extract curve from key */ +#if OPENSSL_VERSION_NUMBER >= 0x10002000L + /* OpenSSL 1.0.2 and newer can automatically handle ECDH parameter + * loading */ + SSL_CTX_set_ecdh_auto(ctx->ctx, 1); + return; +#else + /* For older OpenSSL we have to extract the curve from key on our own */ EC_KEY *eckey = NULL; const EC_GROUP *ecgrp = NULL; EVP_PKEY *pkey = NULL; -#if OPENSSL_VERSION_NUMBER >= 0x10002000L && !defined(LIBRESSL_VERSION_NUMBER) - pkey = SSL_CTX_get0_privatekey(ctx->ctx); -#else /* Little hack to get private key ref from SSL_CTX, yay OpenSSL... */ SSL *ssl = SSL_new(ctx->ctx); if (!ssl) @@ -520,7 +588,6 @@ tls_ctx_load_ecdh_params(struct tls_root_ctx *ctx, const char *curve_name } pkey = SSL_get_privatekey(ssl); SSL_free(ssl); -#endif msg(D_TLS_DEBUG, "Extracting ECDH curve from private key"); @@ -529,6 +596,7 @@ tls_ctx_load_ecdh_params(struct tls_root_ctx *ctx, const char *curve_name { nid = EC_GROUP_get_curve_name(ecgrp); } +#endif } /* Translate NID back to name , just for kicks */ @@ -713,7 +781,7 @@ tls_ctx_add_extra_certs(struct tls_root_ctx *ctx, BIO *bio) for (;; ) { cert = NULL; - if (!PEM_read_bio_X509(bio, &cert, 0, NULL)) /* takes ownership of cert */ + if (!PEM_read_bio_X509(bio, &cert, NULL, NULL)) /* takes ownership of cert */ { break; } @@ -811,12 +879,6 @@ tls_ctx_load_cert_file(struct tls_root_ctx *ctx, const char *cert_file, tls_ctx_load_cert_file_and_copy(ctx, cert_file, cert_file_inline, NULL); } -void -tls_ctx_free_cert_file(X509 *x509) -{ - X509_free(x509); -} - int tls_ctx_load_priv_file(struct tls_root_ctx *ctx, const char *priv_key_file, const char *priv_key_file_inline @@ -1080,6 +1142,13 @@ tls_ctx_use_external_private_key(struct tls_root_ctx *ctx, ASSERT(pkey); /* NULL before SSL_CTX_use_certificate() is called */ pub_rsa = EVP_PKEY_get0_RSA(pkey); + /* Certificate might not be RSA but DSA or EC */ + if (!pub_rsa) + { + crypto_msg(M_WARN, "management-external-key requires a RSA certificate"); + goto err; + } + /* initialize RSA object */ const BIGNUM *n = NULL; const BIGNUM *e = NULL; @@ -1114,7 +1183,7 @@ err: { if (rsa_meth) { - free(rsa_meth); + RSA_meth_free(rsa_meth); } } crypto_msg(M_FATAL, "Cannot enable SSL external private key capability"); @@ -1330,7 +1399,7 @@ static time_t biofp_last_open; /* GLOBAL */ static const int biofp_reopen_interval = 600; /* GLOBAL */ static void -close_biofp() +close_biofp(void) { if (biofp) { @@ -1340,7 +1409,7 @@ close_biofp() } static void -open_biofp() +open_biofp(void) { const time_t current = time(NULL); const pid_t pid = getpid(); @@ -1386,23 +1455,6 @@ bio_debug_oc(const char *mode, BIO *bio) #endif /* ifdef BIO_DEBUG */ /* - * OpenVPN's interface to SSL/TLS authentication, - * encryption, and decryption is exclusively - * through "memory BIOs". - */ -static BIO * -getbio(BIO_METHOD *type, const char *desc) -{ - BIO *ret; - ret = BIO_new(type); - if (!ret) - { - crypto_msg(M_FATAL, "Error creating %s BIO", desc); - } - return ret; -} - -/* * Write to an OpenSSL BIO in non-blocking mode. */ static int @@ -1543,9 +1595,9 @@ key_state_ssl_init(struct key_state_ssl *ks_ssl, const struct tls_root_ctx *ssl_ * from verify callback*/ SSL_set_ex_data(ks_ssl->ssl, mydata_index, session); - ks_ssl->ssl_bio = getbio(BIO_f_ssl(), "ssl_bio"); - ks_ssl->ct_in = getbio(BIO_s_mem(), "ct_in"); - ks_ssl->ct_out = getbio(BIO_s_mem(), "ct_out"); + ASSERT((ks_ssl->ssl_bio = BIO_new(BIO_f_ssl()))); + ASSERT((ks_ssl->ct_in = BIO_new(BIO_s_mem()))); + ASSERT((ks_ssl->ct_out = BIO_new(BIO_s_mem()))); #ifdef BIO_DEBUG bio_debug_oc("open ssl_bio", ks_ssl->ssl_bio); @@ -1686,18 +1738,36 @@ print_details(struct key_state_ssl *ks_ssl, const char *prefix) EVP_PKEY *pkey = X509_get_pubkey(cert); if (pkey != NULL) { - if (EVP_PKEY_id(pkey) == EVP_PKEY_RSA && EVP_PKEY_get0_RSA(pkey) != NULL) + if ((EVP_PKEY_id(pkey) == EVP_PKEY_RSA) && (EVP_PKEY_get0_RSA(pkey) != NULL)) { RSA *rsa = EVP_PKEY_get0_RSA(pkey); openvpn_snprintf(s2, sizeof(s2), ", %d bit RSA", RSA_bits(rsa)); } - else if (EVP_PKEY_id(pkey) == EVP_PKEY_DSA && EVP_PKEY_get0_DSA(pkey) != NULL) + else if ((EVP_PKEY_id(pkey) == EVP_PKEY_DSA) && (EVP_PKEY_get0_DSA(pkey) != NULL)) { DSA *dsa = EVP_PKEY_get0_DSA(pkey); openvpn_snprintf(s2, sizeof(s2), ", %d bit DSA", DSA_bits(dsa)); } +#ifndef OPENSSL_NO_EC + else if ((EVP_PKEY_id(pkey) == EVP_PKEY_EC) && (EVP_PKEY_get0_EC_KEY(pkey) != NULL)) + { + EC_KEY *ec = EVP_PKEY_get0_EC_KEY(pkey); + const EC_GROUP *group = EC_KEY_get0_group(ec); + const char* curve; + + int nid = EC_GROUP_get_curve_name(group); + if (nid == 0 || (curve = OBJ_nid2sn(nid)) == NULL) + { + curve = "Error getting curve name"; + } + + openvpn_snprintf(s2, sizeof(s2), ", %d bit EC, curve: %s", + EC_GROUP_order_bits(group), curve); + + } +#endif EVP_PKEY_free(pkey); } X509_free(cert); @@ -1708,7 +1778,8 @@ print_details(struct key_state_ssl *ks_ssl, const char *prefix) } void -show_available_tls_ciphers(const char *cipher_list) +show_available_tls_ciphers(const char *cipher_list, + const char *tls_cert_profile) { struct tls_root_ctx tls_ctx; SSL *ssl; @@ -1728,6 +1799,7 @@ show_available_tls_ciphers(const char *cipher_list) crypto_msg(M_FATAL, "Cannot create SSL object"); } + tls_ctx_set_cert_profile(&tls_ctx, tls_cert_profile); tls_ctx_restrict_ciphers(&tls_ctx, cipher_list); printf("Available TLS Ciphers,\n"); @@ -1758,7 +1830,7 @@ show_available_tls_ciphers(const char *cipher_list) * in the OpenSSL library. */ void -show_available_curves() +show_available_curves(void) { #ifndef OPENSSL_NO_EC EC_builtin_curve *curves = NULL; diff --git a/src/openvpn/ssl_openssl.h b/src/openvpn/ssl_openssl.h index db4e1da..dabb941 100644 --- a/src/openvpn/ssl_openssl.h +++ b/src/openvpn/ssl_openssl.h @@ -5,8 +5,8 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> - * Copyright (C) 2010-2017 Fox Crypto B.V. <openvpn@fox-it.com> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> + * Copyright (C) 2010-2018 Fox Crypto B.V. <openvpn@fox-it.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/ssl_verify.c b/src/openvpn/ssl_verify.c index 9cd36d7..c7e595e 100644 --- a/src/openvpn/ssl_verify.c +++ b/src/openvpn/ssl_verify.c @@ -5,8 +5,8 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> - * Copyright (C) 2010-2017 Fox Crypto B.V. <openvpn@fox-it.com> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> + * Copyright (C) 2010-2018 Fox Crypto B.V. <openvpn@fox-it.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -547,14 +547,14 @@ verify_cert_export_cert(openvpn_x509_cert_t *peercert, const char *tmp_dir, stru FILE *peercert_file; const char *peercert_filename = ""; - if (!tmp_dir) + /* create tmp file to store peer cert */ + if (!tmp_dir + || !(peercert_filename = create_temp_file(tmp_dir, "pcf", gc))) { + msg (M_WARN, "Failed to create peer cert file"); return NULL; } - /* create tmp file to store peer cert */ - peercert_filename = create_temp_file(tmp_dir, "pcf", gc); - /* write peer-cert in tmp-file */ peercert_file = fopen(peercert_filename, "w+"); if (!peercert_file) @@ -589,10 +589,13 @@ verify_cert_call_command(const char *verify_command, struct env_set *es, if (verify_export_cert) { - if ((tmp_file = verify_cert_export_cert(cert, verify_export_cert, &gc))) + tmp_file = verify_cert_export_cert(cert, verify_export_cert, &gc); + if (!tmp_file) { - setenv_str(es, "peer_cert", tmp_file); + ret = false; + goto cleanup; } + setenv_str(es, "peer_cert", tmp_file); } argv_parse_cmd(&argv, verify_command); @@ -609,6 +612,7 @@ verify_cert_call_command(const char *verify_command, struct env_set *es, } } +cleanup: gc_free(&gc); argv_reset(&argv); @@ -879,21 +883,21 @@ key_state_rm_auth_control_file(struct key_state *ks) } } -static void +static bool key_state_gen_auth_control_file(struct key_state *ks, const struct tls_options *opt) { struct gc_arena gc = gc_new(); - const char *acf; key_state_rm_auth_control_file(ks); - acf = create_temp_file(opt->tmp_dir, "acf", &gc); + const char *acf = create_temp_file(opt->tmp_dir, "acf", &gc); if (acf) { ks->auth_control_file = string_alloc(acf, NULL); setenv_str(opt->es, "auth_control_file", ks->auth_control_file); - } /* FIXME: Should have better error handling? */ + } gc_free(&gc); + return acf; } static unsigned int @@ -1184,7 +1188,12 @@ verify_user_pass_plugin(struct tls_session *session, const struct user_pass *up, #ifdef PLUGIN_DEF_AUTH /* generate filename for deferred auth control file */ - key_state_gen_auth_control_file(ks, session->opt); + if (!key_state_gen_auth_control_file(ks, session->opt)) + { + msg (D_TLS_ERRORS, "TLS Auth Error (%s): " + "could not create deferred auth control file", __func__); + goto cleanup; + } #endif /* call command */ @@ -1209,6 +1218,7 @@ verify_user_pass_plugin(struct tls_session *session, const struct user_pass *up, msg(D_TLS_ERRORS, "TLS Auth Error (verify_user_pass_plugin): peer provided a blank username"); } +cleanup: return retval; } diff --git a/src/openvpn/ssl_verify.h b/src/openvpn/ssl_verify.h index f2d0d6c..3e2267a 100644 --- a/src/openvpn/ssl_verify.h +++ b/src/openvpn/ssl_verify.h @@ -5,8 +5,8 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> - * Copyright (C) 2010-2017 Fox Crypto B.V. <openvpn@fox-it.com> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> + * Copyright (C) 2010-2018 Fox Crypto B.V. <openvpn@fox-it.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/ssl_verify_backend.h b/src/openvpn/ssl_verify_backend.h index e8eaabe..2a9e8bb 100644 --- a/src/openvpn/ssl_verify_backend.h +++ b/src/openvpn/ssl_verify_backend.h @@ -5,8 +5,8 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> - * Copyright (C) 2010-2017 Fox Crypto B.V. <openvpn@fox-it.com> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> + * Copyright (C) 2010-2018 Fox Crypto B.V. <openvpn@fox-it.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/ssl_verify_mbedtls.c b/src/openvpn/ssl_verify_mbedtls.c index 838c217..2d019ab 100644 --- a/src/openvpn/ssl_verify_mbedtls.c +++ b/src/openvpn/ssl_verify_mbedtls.c @@ -5,8 +5,8 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> - * Copyright (C) 2010-2017 Fox Crypto B.V. <openvpn@fox-it.com> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> + * Copyright (C) 2010-2018 Fox Crypto B.V. <openvpn@fox-it.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/ssl_verify_mbedtls.h b/src/openvpn/ssl_verify_mbedtls.h index 8b0a5ae..00dc8a3 100644 --- a/src/openvpn/ssl_verify_mbedtls.h +++ b/src/openvpn/ssl_verify_mbedtls.h @@ -5,8 +5,8 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> - * Copyright (C) 2010-2017 Fox Crypto B.V. <openvpn@fox-it.com> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> + * Copyright (C) 2010-2018 Fox Crypto B.V. <openvpn@fox-it.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -48,9 +48,9 @@ typedef mbedtls_x509_crt openvpn_x509_cert_t; * This callback function is called when a new TLS session is being setup to * determine whether the remote OpenVPN peer's certificate is allowed to * connect. It is called for once for every certificate in the chain. The - * callback functionality is configured in the \c init_ssl() function, which - * calls the mbed TLS library's \c ssl_set_verify_callback() function with \c - * verify_callback() as its callback argument. + * callback functionality is configured in the \c key_state_ssl_init() function, + * which calls the mbed TLS library's \c mbedtls_ssl_conf_verify() function with + * \c verify_callback() as its callback argument. * * It checks *flags and registers the certificate hash. If these steps succeed, * it calls the \c verify_cert() function, which performs OpenVPN-specific diff --git a/src/openvpn/ssl_verify_openssl.c b/src/openvpn/ssl_verify_openssl.c index 468b495..b1ce06b 100644 --- a/src/openvpn/ssl_verify_openssl.c +++ b/src/openvpn/ssl_verify_openssl.c @@ -5,8 +5,8 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> - * Copyright (C) 2010-2017 Fox Crypto B.V. <openvpn@fox-it.com> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> + * Copyright (C) 2010-2018 Fox Crypto B.V. <openvpn@fox-it.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -129,8 +129,7 @@ extract_x509_extension(X509 *cert, char *fieldname, char *out, int size) if (!x509_username_field_ext_supported(fieldname)) { msg(D_TLS_ERRORS, - "ERROR: --x509-alt-username field 'ext:%s' not supported", - fieldname); + "ERROR: --x509-username-field 'ext:%s' not supported", fieldname); return false; } @@ -203,8 +202,8 @@ extract_x509_field_ssl(X509_NAME *x509, const char *field_name, char *out, { int lastpos = -1; int tmp = -1; - X509_NAME_ENTRY *x509ne = 0; - ASN1_STRING *asn1 = 0; + X509_NAME_ENTRY *x509ne = NULL; + ASN1_STRING *asn1 = NULL; unsigned char *buf = NULL; ASN1_OBJECT *field_name_obj = OBJ_txt2obj(field_name, 0); diff --git a/src/openvpn/ssl_verify_openssl.h b/src/openvpn/ssl_verify_openssl.h index 4c8dbeb..118e16f 100644 --- a/src/openvpn/ssl_verify_openssl.h +++ b/src/openvpn/ssl_verify_openssl.h @@ -5,8 +5,8 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> - * Copyright (C) 2010-2017 Fox Crypto B.V. <openvpn@fox-it.com> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> + * Copyright (C) 2010-2018 Fox Crypto B.V. <openvpn@fox-it.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/status.c b/src/openvpn/status.c index a163408..91391d1 100644 --- a/src/openvpn/status.c +++ b/src/openvpn/status.c @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -178,7 +178,7 @@ status_flush(struct status_output *so) const off_t off = lseek(so->fd, (off_t)0, SEEK_CUR); if (ftruncate(so->fd, off) != 0) { - msg(M_WARN, "Failed to truncate status file: %s", strerror(errno)); + msg(M_WARN | M_ERRNO, "Failed to truncate status file"); } } #elif defined(HAVE_CHSIZE) diff --git a/src/openvpn/status.h b/src/openvpn/status.h index 8199935..2a399d7 100644 --- a/src/openvpn/status.h +++ b/src/openvpn/status.h @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/syshead.h b/src/openvpn/syshead.h index 2973b5a..3ac9d70 100644 --- a/src/openvpn/syshead.h +++ b/src/openvpn/syshead.h @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -513,7 +513,7 @@ socket_defined(const socket_descriptor_t sd) * Do we have point-to-multipoint capability? */ -#if defined(ENABLE_CLIENT_SERVER) && defined(ENABLE_CRYPTO) && defined(HAVE_GETTIMEOFDAY_NANOSECONDS) +#if defined(ENABLE_CRYPTO) && defined(HAVE_GETTIMEOFDAY_NANOSECONDS) #define P2MP 1 #else #define P2MP 0 diff --git a/src/openvpn/tls_crypt.c b/src/openvpn/tls_crypt.c index e13bb4e..ecc654e 100644 --- a/src/openvpn/tls_crypt.c +++ b/src/openvpn/tls_crypt.c @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2016-2017 Fox Crypto B.V. <openvpn@fox-it.com> + * Copyright (C) 2016-2018 Fox Crypto B.V. <openvpn@fox-it.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -35,35 +35,47 @@ #include "tls_crypt.h" -int -tls_crypt_buf_overhead(void) -{ - return packet_id_size(true) + TLS_CRYPT_TAG_SIZE + TLS_CRYPT_BLOCK_SIZE; -} - -void -tls_crypt_init_key(struct key_ctx_bi *key, const char *key_file, - const char *key_inline, bool tls_server) +static struct key_type +tls_crypt_kt(void) { - const int key_direction = tls_server ? - KEY_DIRECTION_NORMAL : KEY_DIRECTION_INVERSE; - struct key_type kt; kt.cipher = cipher_kt_get("AES-256-CTR"); kt.digest = md_kt_get("SHA256"); if (!kt.cipher) { - msg(M_FATAL, "ERROR: --tls-crypt requires AES-256-CTR support."); + msg(M_WARN, "ERROR: --tls-crypt requires AES-256-CTR support."); + return (struct key_type) { 0 }; } if (!kt.digest) { - msg(M_FATAL, "ERROR: --tls-crypt requires HMAC-SHA-256 support."); + msg(M_WARN, "ERROR: --tls-crypt requires HMAC-SHA-256 support."); + return (struct key_type) { 0 }; } kt.cipher_length = cipher_kt_key_size(kt.cipher); kt.hmac_length = md_kt_size(kt.digest); + return kt; +} + +int +tls_crypt_buf_overhead(void) +{ + return packet_id_size(true) + TLS_CRYPT_TAG_SIZE + TLS_CRYPT_BLOCK_SIZE; +} + +void +tls_crypt_init_key(struct key_ctx_bi *key, const char *key_file, + const char *key_inline, bool tls_server) +{ + const int key_direction = tls_server ? + KEY_DIRECTION_NORMAL : KEY_DIRECTION_INVERSE; + struct key_type kt = tls_crypt_kt(); + if (!kt.cipher || !kt.digest) + { + msg (M_FATAL, "ERROR: --tls-crypt not supported"); + } crypto_read_openvpn_key(&kt, key, key_file, key_inline, key_direction, "Control Channel Encryption", "tls-crypt"); } diff --git a/src/openvpn/tls_crypt.h b/src/openvpn/tls_crypt.h index e8080df..05fcc4e 100644 --- a/src/openvpn/tls_crypt.h +++ b/src/openvpn/tls_crypt.h @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2016-2017 Fox Crypto B.V. <openvpn@fox-it.com> + * Copyright (C) 2016-2018 Fox Crypto B.V. <openvpn@fox-it.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -74,6 +74,8 @@ #ifndef TLSCRYPT_H #define TLSCRYPT_H +#ifdef ENABLE_CRYPTO + #include "buffer.h" #include "crypto.h" #include "session_id.h" @@ -140,4 +142,6 @@ bool tls_crypt_unwrap(const struct buffer *src, struct buffer *dst, /** @} */ +#endif /* ENABLE_CRYPTO */ + #endif /* TLSCRYPT_H */ diff --git a/src/openvpn/tun.c b/src/openvpn/tun.c index 75a156c..b071823 100644 --- a/src/openvpn/tun.c +++ b/src/openvpn/tun.c @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -45,6 +45,7 @@ #include "manage.h" #include "route.h" #include "win32.h" +#include "block_dns.h" #include "memdbg.h" @@ -124,7 +125,7 @@ do_address_service(const bool add, const short family, const struct tuntap *tt) if (ack.error_number != NO_ERROR) { - msg(M_WARN, "TUN: %s address failed using service: %s [status=%u if_index=%lu]", + msg(M_WARN, "TUN: %s address failed using service: %s [status=%u if_index=%d]", (add ? "adding" : "deleting"), strerror_win32(ack.error_number, &gc), ack.error_number, addr.iface.index); goto out; @@ -838,6 +839,7 @@ delete_route_connected_v6_net(struct tuntap *tt, r6.gateway = tt->local_ipv6; r6.metric = 0; /* connected route */ r6.flags = RT_DEFINED | RT_ADDED | RT_METRIC_DEFINED; + route_ipv6_clear_host_bits(&r6); delete_route_ipv6(&r6, tt, 0, es); } #endif /* if defined(_WIN32) || defined(TARGET_DARWIN) || defined(TARGET_NETBSD) || defined(TARGET_OPENBSD) */ @@ -1862,7 +1864,7 @@ open_tun(const char *dev, const char *dev_type, const char *dev_node, struct tun if (oldtunfd >=0 && android_method == ANDROID_OPEN_AFTER_CLOSE) { close(oldtunfd); - openvpn_sleep(2); + management_sleep(2); } if (oldtunfd >=0 && android_method == ANDROID_KEEP_OLD_TUN) @@ -2563,8 +2565,7 @@ open_tun(const char *dev, const char *dev_type, const char *dev_node, struct tun if (ioctl(tt->fd, TUNGIFINFO, &info) < 0) { - msg(M_WARN | M_ERRNO, "Can't get interface info: %s", - strerror(errno)); + msg(M_WARN | M_ERRNO, "Can't get interface info"); } #ifdef IFF_MULTICAST /* openbsd 4.x doesn't have this */ @@ -2573,8 +2574,7 @@ open_tun(const char *dev, const char *dev_type, const char *dev_node, struct tun if (ioctl(tt->fd, TUNSIFINFO, &info) < 0) { - msg(M_WARN | M_ERRNO, "Can't set interface info: %s", - strerror(errno)); + msg(M_WARN | M_ERRNO, "Can't set interface info"); } } } @@ -2663,7 +2663,7 @@ open_tun(const char *dev, const char *dev_type, const char *dev_node, struct tun i = 1; if (ioctl(tt->fd, TUNSIFHEAD, &i) < 0) /* multi-af mode on */ { - msg(M_WARN | M_ERRNO, "ioctl(TUNSIFHEAD): %s", strerror(errno)); + msg(M_WARN | M_ERRNO, "ioctl(TUNSIFHEAD)"); } } } @@ -2796,12 +2796,12 @@ open_tun(const char *dev, const char *dev_type, const char *dev_node, struct tun if (ioctl(tt->fd, TUNSIFMODE, &i) < 0) { - msg(M_WARN | M_ERRNO, "ioctl(TUNSIFMODE): %s", strerror(errno)); + msg(M_WARN | M_ERRNO, "ioctl(TUNSIFMODE)"); } i = 1; if (ioctl(tt->fd, TUNSIFHEAD, &i) < 0) { - msg(M_WARN | M_ERRNO, "ioctl(TUNSIFHEAD): %s", strerror(errno)); + msg(M_WARN | M_ERRNO, "ioctl(TUNSIFHEAD)"); } } } @@ -3022,16 +3022,14 @@ utun_open_helper(struct ctl_info ctlInfo, int utunnum) if (fd < 0) { - msg(M_INFO, "Opening utun (%s): %s", "socket(SYSPROTO_CONTROL)", - strerror(errno)); + msg(M_INFO | M_ERRNO, "Opening utun (socket(SYSPROTO_CONTROL))"); return -2; } if (ioctl(fd, CTLIOCGINFO, &ctlInfo) == -1) { close(fd); - msg(M_INFO, "Opening utun (%s): %s", "ioctl(CTLIOCGINFO)", - strerror(errno)); + msg(M_INFO | M_ERRNO, "Opening utun (ioctl(CTLIOCGINFO))"); return -2; } @@ -3049,8 +3047,7 @@ utun_open_helper(struct ctl_info ctlInfo, int utunnum) if (connect(fd, (struct sockaddr *)&sc, sizeof(sc)) < 0) { - msg(M_INFO, "Opening utun (%s): %s", "connect(AF_SYS_CONTROL)", - strerror(errno)); + msg(M_INFO | M_ERRNO, "Opening utun (connect(AF_SYS_CONTROL))"); close(fd); return -1; } @@ -3795,7 +3792,7 @@ get_panel_reg(struct gc_arena *gc) if (status != ERROR_SUCCESS || name_type != REG_SZ) { - dmsg(D_REGISTRY, "Error opening registry key: %s\\%s\\%s", + dmsg(D_REGISTRY, "Error opening registry key: %s\\%s\\%ls", NETWORK_CONNECTIONS_KEY, connection_string, name_string); } else @@ -4183,15 +4180,12 @@ get_adapter_info_list(struct gc_arena *gc) else { pi = (PIP_ADAPTER_INFO) gc_malloc(size, false, gc); - if ((status = GetAdaptersInfo(pi, &size)) == NO_ERROR) - { - return pi; - } - else + if ((status = GetAdaptersInfo(pi, &size)) != NO_ERROR) { msg(M_INFO, "GetAdaptersInfo #2 failed (status=%u) : %s", (unsigned int)status, strerror_win32(status, gc)); + pi = NULL; } } return pi; @@ -4488,6 +4482,7 @@ adapter_index_of_ip(const IP_ADAPTER_INFO *list, struct gc_arena gc = gc_new(); DWORD ret = TUN_ADAPTER_INDEX_INVALID; in_addr_t highest_netmask = 0; + int lowest_metric = INT_MAX; bool first = true; if (count) @@ -4501,9 +4496,14 @@ adapter_index_of_ip(const IP_ADAPTER_INFO *list, if (is_ip_in_adapter_subnet(list, ip, &hn)) { + int metric = get_interface_metric(list->Index, AF_INET, NULL); if (first || hn > highest_netmask) { highest_netmask = hn; + if (metric >= 0) + { + lowest_metric = metric; + } if (count) { *count = 1; @@ -4517,16 +4517,22 @@ adapter_index_of_ip(const IP_ADAPTER_INFO *list, { ++*count; } + if (metric >= 0 && metric < lowest_metric) + { + ret = list->Index; + lowest_metric = metric; + } } } list = list->Next; } - dmsg(D_ROUTE_DEBUG, "DEBUG: IP Locate: ip=%s nm=%s index=%d count=%d", + dmsg(D_ROUTE_DEBUG, "DEBUG: IP Locate: ip=%s nm=%s index=%d count=%d metric=%d", print_in_addr_t(ip, 0, &gc), print_in_addr_t(highest_netmask, 0, &gc), (int)ret, - count ? *count : -1); + count ? *count : -1, + lowest_metric); if (ret == TUN_ADAPTER_INDEX_INVALID && count) { @@ -4627,7 +4633,7 @@ get_adapter_index_method_1(const char *guid) DWORD index; ULONG aindex; wchar_t wbuf[256]; - _snwprintf(wbuf, SIZE(wbuf), L"\\DEVICE\\TCPIP_%S", guid); + swprintf(wbuf, SIZE(wbuf), L"\\DEVICE\\TCPIP_%S", guid); wbuf [SIZE(wbuf) - 1] = 0; if (GetAdapterIndex(wbuf, &aindex) != NO_ERROR) { @@ -5004,7 +5010,7 @@ netsh_command(const struct argv *a, int n, int msglevel) for (i = 0; i < n; ++i) { bool status; - openvpn_sleep(1); + management_sleep(1); netcmd_semaphore_lock(); argv_msg_prefix(M_INFO, a, "NETSH"); status = openvpn_execve_check(a, NULL, 0, "ERROR: netsh command failed"); @@ -5013,7 +5019,7 @@ netsh_command(const struct argv *a, int n, int msglevel) { return; } - openvpn_sleep(4); + management_sleep(4); } msg(msglevel, "NETSH: command failed"); } @@ -5996,7 +6002,7 @@ open_tun(const char *dev, const char *dev_type, const char *dev_node, struct tun if (s > 0) { msg(M_INFO, "Sleeping for %d seconds...", s); - openvpn_sleep(s); + management_sleep(s); } } diff --git a/src/openvpn/tun.h b/src/openvpn/tun.h index 8782d69..6c57ad0 100644 --- a/src/openvpn/tun.h +++ b/src/openvpn/tun.h @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/openvpn/win32.c b/src/openvpn/win32.c index d0b10ba..29bbb84 100644 --- a/src/openvpn/win32.c +++ b/src/openvpn/win32.c @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -1235,7 +1235,7 @@ set_win_sys_path_via_env(struct env_set *es) const char * -win_get_tempdir() +win_get_tempdir(void) { static char tmpdir[MAX_PATH]; WCHAR wtmpdir[MAX_PATH]; @@ -1344,17 +1344,16 @@ win_wfp_block_dns(const NET_IFINDEX index, const HANDLE msg_channel) block_dns_msg_handler); if (status == 0) { - tap_metric_v4 = get_interface_metric(index, AF_INET); - tap_metric_v6 = get_interface_metric(index, AF_INET6); - if (tap_metric_v4 < 0) + int is_auto = 0; + tap_metric_v4 = get_interface_metric(index, AF_INET, &is_auto); + if (is_auto) { - /* error, should not restore metric */ - tap_metric_v4 = -1; + tap_metric_v4 = 0; } - if (tap_metric_v6 < 0) + tap_metric_v6 = get_interface_metric(index, AF_INET6, &is_auto); + if (is_auto) { - /* error, should not restore metric */ - tap_metric_v6 = -1; + tap_metric_v6 = 0; } status = set_interface_metric(index, AF_INET, BLOCK_DNS_IFACE_METRIC); if (!status) @@ -1398,7 +1397,7 @@ win_wfp_uninit(const NET_IFINDEX index, const HANDLE msg_channel) } int -win32_version_info() +win32_version_info(void) { if (!IsWindowsXPOrGreater()) { @@ -1426,7 +1425,7 @@ win32_version_info() } bool -win32_is_64bit() +win32_is_64bit(void) { #if defined(_WIN64) return true; /* 64-bit programs run only on Win64 */ diff --git a/src/openvpn/win32.h b/src/openvpn/win32.h index 21a1021..4b99a5e 100644 --- a/src/openvpn/win32.h +++ b/src/openvpn/win32.h @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -285,7 +285,7 @@ char *get_win_sys_path(void); void fork_to_self(const char *cmdline); /* Find temporary directory */ -const char *win_get_tempdir(); +const char *win_get_tempdir(void); /* Convert a string from UTF-8 to UCS-2 */ WCHAR *wide_string(const char *utf8, struct gc_arena *gc); @@ -299,7 +299,7 @@ bool win_wfp_uninit(const NET_IFINDEX index, const HANDLE msg_channel); #define WIN_7 2 #define WIN_8 3 -int win32_version_info(); +int win32_version_info(void); /* * String representation of Windows version number and name, see diff --git a/src/openvpnserv/Makefile.am b/src/openvpnserv/Makefile.am index 21efc7c..bc65070 100644 --- a/src/openvpnserv/Makefile.am +++ b/src/openvpnserv/Makefile.am @@ -5,7 +5,7 @@ # packet encryption, packet authentication, and # packet compression. # -# Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> +# Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> # Copyright (C) 2006-2012 Alon Bar-Lev <alon.barlev@gmail.com> # diff --git a/src/openvpnserv/Makefile.in b/src/openvpnserv/Makefile.in index 234a927..0dd9792 100644 --- a/src/openvpnserv/Makefile.in +++ b/src/openvpnserv/Makefile.in @@ -21,7 +21,7 @@ # packet encryption, packet authentication, and # packet compression. # -# Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> +# Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> # Copyright (C) 2006-2012 Alon Bar-Lev <alon.barlev@gmail.com> # @@ -376,6 +376,7 @@ plugindir = @plugindir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ +runstatedir = @runstatedir@ sampledir = @sampledir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ diff --git a/src/openvpnserv/automatic.c b/src/openvpnserv/automatic.c index 4123d0f..5569ce9 100644 --- a/src/openvpnserv/automatic.c +++ b/src/openvpnserv/automatic.c @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -44,7 +44,7 @@ #define false 0 static SERVICE_STATUS_HANDLE service; -static SERVICE_STATUS status; +static SERVICE_STATUS status = { .dwServiceType = SERVICE_WIN32_SHARE_PROCESS }; openvpn_service_t automatic_service = { automatic, @@ -60,12 +60,6 @@ struct security_attributes SECURITY_DESCRIPTOR sd; }; -/* - * Which registry key in HKLM should - * we get config info from? - */ -#define REG_KEY "SOFTWARE\\" PACKAGE_NAME - static HANDLE exit_event = NULL; /* clear an object */ @@ -91,15 +85,6 @@ init_security_attributes_allow_all(struct security_attributes *obj) return true; } -/* - * This event is initially created in the non-signaled - * state. It will transition to the signaled state when - * we have received a terminate signal from the Service - * Control Manager which will cause an asynchronous call - * of ServiceStop below. - */ -#define EXIT_EVENT_NAME TEXT(PACKAGE "_exit_1") - HANDLE create_event(LPCTSTR name, bool allow_all, bool initial_state, bool manual_reset) { @@ -212,10 +197,19 @@ ServiceCtrlAutomatic(DWORD ctrl_code, DWORD event, LPVOID data, LPVOID ctx) VOID WINAPI +ServiceStartAutomaticOwn(DWORD dwArgc, LPTSTR *lpszArgv) +{ + status.dwServiceType = SERVICE_WIN32_OWN_PROCESS; + ServiceStartAutomatic(dwArgc, lpszArgv); +} + + +VOID WINAPI ServiceStartAutomatic(DWORD dwArgc, LPTSTR *lpszArgv) { DWORD error = NO_ERROR; settings_t settings; + TCHAR event_name[256]; service = RegisterServiceCtrlHandlerEx(automatic_service.name, ServiceCtrlAutomatic, &status); if (!service) @@ -223,7 +217,6 @@ ServiceStartAutomatic(DWORD dwArgc, LPTSTR *lpszArgv) return; } - status.dwServiceType = SERVICE_WIN32_SHARE_PROCESS; status.dwCurrentState = SERVICE_START_PENDING; status.dwServiceSpecificExitCode = NO_ERROR; status.dwWin32ExitCode = NO_ERROR; @@ -237,8 +230,15 @@ ServiceStartAutomatic(DWORD dwArgc, LPTSTR *lpszArgv) /* * Create our exit event + * This event is initially created in the non-signaled + * state. It will transition to the signaled state when + * we have received a terminate signal from the Service + * Control Manager which will cause an asynchronous call + * of ServiceStop below. */ - exit_event = create_event(EXIT_EVENT_NAME, false, false, true); + + openvpn_sntprintf(event_name, _countof(event_name), TEXT(PACKAGE "%s_exit_1"), service_instance); + exit_event = create_event(event_name, false, false, true); if (!exit_event) { MsgToEventLog(M_ERR, TEXT("CreateEvent failed")); @@ -327,8 +327,8 @@ ServiceStartAutomatic(DWORD dwArgc, LPTSTR *lpszArgv) TEXT("%s\\%s"), settings.log_dir, log_file); /* construct command line */ - openvpn_sntprintf(command_line, _countof(command_line), TEXT(PACKAGE " --service %s 1 --config \"%s\""), - EXIT_EVENT_NAME, + openvpn_sntprintf(command_line, _countof(command_line), TEXT("openvpn --service \"" PACKAGE "%s_exit_1\" 1 --config \"%s\""), + service_instance, find_obj.cFileName); /* Make security attributes struct for logfile handle so it can diff --git a/src/openvpnserv/common.c b/src/openvpnserv/common.c index 0c9098f..dc47666 100644 --- a/src/openvpnserv/common.c +++ b/src/openvpnserv/common.c @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2011-2017 Heiko Hund <heiko.hund@sophos.com> + * Copyright (C) 2011-2018 Heiko Hund <heiko.hund@sophos.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -21,8 +21,12 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include <service.h> -#include <validate.h> +#include "service.h" +#include "validate.h" + +LPCTSTR service_instance = TEXT(""); + + /* * These are necessary due to certain buggy implementations of (v)snprintf, * that don't guarantee null termination for size > 0. @@ -52,23 +56,25 @@ openvpn_sntprintf(LPTSTR str, size_t size, LPCTSTR format, ...) return len; } -#define REG_KEY TEXT("SOFTWARE\\" PACKAGE_NAME) - static DWORD -GetRegString(HKEY key, LPCTSTR value, LPTSTR data, DWORD size) +GetRegString(HKEY key, LPCTSTR value, LPTSTR data, DWORD size, LPCTSTR default_value) { - DWORD type; - LONG status = RegQueryValueEx(key, value, NULL, &type, (LPBYTE) data, &size); + LONG status = RegGetValue(key, NULL, value, RRF_RT_REG_SZ, + NULL, (LPBYTE) data, &size); - if (status == ERROR_SUCCESS && type != REG_SZ) + if (status == ERROR_FILE_NOT_FOUND && default_value) { - status = ERROR_DATATYPE_MISMATCH; + size_t len = size/sizeof(data[0]); + if (openvpn_sntprintf(data, len, default_value) > 0) + { + status = ERROR_SUCCESS; + } } if (status != ERROR_SUCCESS) { SetLastError(status); - return MsgToEventLog(M_SYSERR, TEXT("Error querying registry value: HKLM\\%s\\%s"), REG_KEY, value); + return MsgToEventLog(M_SYSERR, TEXT("Error querying registry value: HKLM\\SOFTWARE\\" PACKAGE_NAME "%s\\%s"), service_instance, value); } return ERROR_SUCCESS; @@ -78,60 +84,78 @@ GetRegString(HKEY key, LPCTSTR value, LPTSTR data, DWORD size) DWORD GetOpenvpnSettings(settings_t *s) { + TCHAR reg_path[256]; TCHAR priority[64]; TCHAR append[2]; DWORD error; HKEY key; + TCHAR install_path[MAX_PATH]; + TCHAR default_value[MAX_PATH]; + + openvpn_sntprintf(reg_path, _countof(reg_path), TEXT("SOFTWARE\\" PACKAGE_NAME "%s"), service_instance); - LONG status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, REG_KEY, 0, KEY_READ, &key); + LONG status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, reg_path, 0, KEY_READ, &key); if (status != ERROR_SUCCESS) { SetLastError(status); - return MsgToEventLog(M_SYSERR, TEXT("Could not open Registry key HKLM\\%s not found"), REG_KEY); + return MsgToEventLog(M_SYSERR, TEXT("Could not open Registry key HKLM\\%s not found"), reg_path); } - error = GetRegString(key, TEXT("exe_path"), s->exe_path, sizeof(s->exe_path)); + /* The default value of REG_KEY is the install path */ + if (GetRegString(key, NULL, install_path, sizeof(install_path), NULL) != ERROR_SUCCESS) + { + goto out; + } + + openvpn_sntprintf(default_value, _countof(default_value), TEXT("%s\\bin\\openvpn.exe"), + install_path); + error = GetRegString(key, TEXT("exe_path"), s->exe_path, sizeof(s->exe_path), default_value); if (error != ERROR_SUCCESS) { goto out; } - error = GetRegString(key, TEXT("config_dir"), s->config_dir, sizeof(s->config_dir)); + openvpn_sntprintf(default_value, _countof(default_value), TEXT("%s\\config"), install_path); + error = GetRegString(key, TEXT("config_dir"), s->config_dir, sizeof(s->config_dir), + default_value); if (error != ERROR_SUCCESS) { goto out; } - error = GetRegString(key, TEXT("config_ext"), s->ext_string, sizeof(s->ext_string)); + error = GetRegString(key, TEXT("config_ext"), s->ext_string, sizeof(s->ext_string), + TEXT(".ovpn")); if (error != ERROR_SUCCESS) { goto out; } - error = GetRegString(key, TEXT("log_dir"), s->log_dir, sizeof(s->log_dir)); + openvpn_sntprintf(default_value, _countof(default_value), TEXT("%s\\log"), install_path); + error = GetRegString(key, TEXT("log_dir"), s->log_dir, sizeof(s->log_dir), default_value); if (error != ERROR_SUCCESS) { goto out; } - error = GetRegString(key, TEXT("priority"), priority, sizeof(priority)); + error = GetRegString(key, TEXT("priority"), priority, sizeof(priority), + TEXT("NORMAL_PRIORITY_CLASS")); if (error != ERROR_SUCCESS) { goto out; } - error = GetRegString(key, TEXT("log_append"), append, sizeof(append)); + error = GetRegString(key, TEXT("log_append"), append, sizeof(append), TEXT("0")); if (error != ERROR_SUCCESS) { goto out; } /* read if present, else use default */ - error = GetRegString(key, TEXT("ovpn_admin_group"), s->ovpn_admin_group, sizeof(s->ovpn_admin_group)); + error = GetRegString(key, TEXT("ovpn_admin_group"), s->ovpn_admin_group, + sizeof(s->ovpn_admin_group), OVPN_ADMIN_GROUP); if (error != ERROR_SUCCESS) { - openvpn_sntprintf(s->ovpn_admin_group, _countof(s->ovpn_admin_group), OVPN_ADMIN_GROUP); - error = 0; /* this error is not fatal */ + goto out; } /* set process priority */ if (!_tcsicmp(priority, TEXT("IDLE_PRIORITY_CLASS"))) @@ -231,7 +255,7 @@ MsgToEventLog(DWORD flags, LPCTSTR format, ...) if (hEventSource != NULL) { openvpn_sntprintf(msg[0], _countof(msg[0]), - TEXT("%s%s: %s"), APPNAME, + TEXT("%s%s%s: %s"), APPNAME, service_instance, (flags & MSG_FLAGS_ERROR) ? TEXT(" error") : TEXT(""), err_msg); va_start(arglist, format); diff --git a/src/openvpnserv/interactive.c b/src/openvpnserv/interactive.c index 607c8a9..19be0db 100644 --- a/src/openvpnserv/interactive.c +++ b/src/openvpnserv/interactive.c @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2012-2017 Heiko Hund <heiko.hund@sophos.com> + * Copyright (C) 2012-2018 Heiko Hund <heiko.hund@sophos.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -33,6 +33,7 @@ #include <stdio.h> #include <sddl.h> #include <shellapi.h> +#include <mstcpip.h> #ifdef HAVE_VERSIONHELPERS_H #include <versionhelpers.h> @@ -52,7 +53,7 @@ #define ERROR_MESSAGE_TYPE 0x20000003 static SERVICE_STATUS_HANDLE service; -static SERVICE_STATUS status; +static SERVICE_STATUS status = { .dwServiceType = SERVICE_WIN32_SHARE_PROCESS }; static HANDLE exit_event = NULL; static settings_t settings; static HANDLE rdns_semaphore = NULL; @@ -276,7 +277,7 @@ ReturnProcessId(HANDLE pipe, DWORD pid, DWORD count, LPHANDLE events) * Same format as error messages (3 line string) with error = 0 in * 0x%08x format, PID on line 2 and a description "Process ID" on line 3 */ - _snwprintf(buf, _countof(buf), L"0x%08x\n0x%08x\n%s", 0, pid, msg); + swprintf(buf, _countof(buf), L"0x%08x\n0x%08x\n%s", 0, pid, msg); buf[_countof(buf) - 1] = '\0'; WritePipeAsync(pipe, buf, wcslen(buf) * 2, count, events); @@ -370,12 +371,12 @@ ValidateOptions(HANDLE pipe, const WCHAR *workdir, const WCHAR *options) BOOL ret = FALSE; int i; const WCHAR *msg1 = L"You have specified a config file location (%s relative to %s)" - " that requires admin approval. This error may be avoided" - " by adding your account to the \"%s\" group"; + L" that requires admin approval. This error may be avoided" + L" by adding your account to the \"%s\" group"; const WCHAR *msg2 = L"You have specified an option (%s) that may be used" - " only with admin approval. This error may be avoided" - " by adding your account to the \"%s\" group"; + L" only with admin approval. This error may be avoided" + L" by adding your account to the \"%s\" group"; argv = CommandLineToArgvW(options, &argc); @@ -402,8 +403,8 @@ ValidateOptions(HANDLE pipe, const WCHAR *workdir, const WCHAR *options) if (!CheckOption(workdir, 2, argv_tmp, &settings)) { - snwprintf(buf, _countof(buf), msg1, argv[0], workdir, - settings.ovpn_admin_group); + swprintf(buf, _countof(buf), msg1, argv[0], workdir, + settings.ovpn_admin_group); buf[_countof(buf) - 1] = L'\0'; ReturnError(pipe, ERROR_STARTUP_DATA, buf, 1, &exit_event); } @@ -421,15 +422,15 @@ ValidateOptions(HANDLE pipe, const WCHAR *workdir, const WCHAR *options) { if (wcscmp(L"--config", argv[i]) == 0 && argc-i > 1) { - snwprintf(buf, _countof(buf), msg1, argv[i+1], workdir, - settings.ovpn_admin_group); + swprintf(buf, _countof(buf), msg1, argv[i+1], workdir, + settings.ovpn_admin_group); buf[_countof(buf) - 1] = L'\0'; ReturnError(pipe, ERROR_STARTUP_DATA, buf, 1, &exit_event); } else { - snwprintf(buf, _countof(buf), msg2, argv[i], - settings.ovpn_admin_group); + swprintf(buf, _countof(buf), msg2, argv[i], + settings.ovpn_admin_group); buf[_countof(buf) - 1] = L'\0'; ReturnError(pipe, ERROR_STARTUP_DATA, buf, 1, &exit_event); } @@ -465,6 +466,13 @@ GetStartupData(HANDLE pipe, STARTUP_DATA *sud) } size = bytes / sizeof(*data); + if (size == 0) + { + MsgToEventLog(M_SYSERR, TEXT("malformed startup data: 1 byte received")); + ReturnError(pipe, ERROR_STARTUP_DATA, L"GetStartupData", 1, &exit_event); + goto out; + } + data = malloc(bytes); if (data == NULL) { @@ -546,32 +554,17 @@ static DWORD InterfaceLuid(const char *iface_name, PNET_LUID luid) { NETIO_STATUS status; - LPWSTR wide_name; - int n; + LPWSTR wide_name = utf8to16(iface_name); - typedef NETIO_STATUS WINAPI (*ConvertInterfaceAliasToLuidFn) (LPCWSTR, PNET_LUID); - static ConvertInterfaceAliasToLuidFn ConvertInterfaceAliasToLuid = NULL; - if (!ConvertInterfaceAliasToLuid) + if (wide_name) { - HMODULE iphlpapi = GetModuleHandle(TEXT("iphlpapi.dll")); - if (iphlpapi == NULL) - { - return GetLastError(); - } - - ConvertInterfaceAliasToLuid = (ConvertInterfaceAliasToLuidFn) GetProcAddress(iphlpapi, "ConvertInterfaceAliasToLuid"); - if (!ConvertInterfaceAliasToLuid) - { - return GetLastError(); - } + status = ConvertInterfaceAliasToLuid(wide_name, luid); + free(wide_name); + } + else + { + status = ERROR_OUTOFMEMORY; } - - n = MultiByteToWideChar(CP_UTF8, 0, iface_name, -1, NULL, 0); - wide_name = malloc(n * sizeof(WCHAR)); - MultiByteToWideChar(CP_UTF8, 0, iface_name, -1, wide_name, n); - status = ConvertInterfaceAliasToLuid(wide_name, luid); - free(wide_name); - return status; } @@ -584,24 +577,6 @@ CmpAddress(LPVOID item, LPVOID address) static DWORD DeleteAddress(PMIB_UNICASTIPADDRESS_ROW addr_row) { - typedef NETIOAPI_API (*DeleteUnicastIpAddressEntryFn) (const PMIB_UNICASTIPADDRESS_ROW); - static DeleteUnicastIpAddressEntryFn DeleteUnicastIpAddressEntry = NULL; - - if (!DeleteUnicastIpAddressEntry) - { - HMODULE iphlpapi = GetModuleHandle(TEXT("iphlpapi.dll")); - if (iphlpapi == NULL) - { - return GetLastError(); - } - - DeleteUnicastIpAddressEntry = (DeleteUnicastIpAddressEntryFn) GetProcAddress(iphlpapi, "DeleteUnicastIpAddressEntry"); - if (!DeleteUnicastIpAddressEntry) - { - return GetLastError(); - } - } - return DeleteUnicastIpAddressEntry(addr_row); } @@ -612,32 +587,6 @@ HandleAddressMessage(address_message_t *msg, undo_lists_t *lists) PMIB_UNICASTIPADDRESS_ROW addr_row; BOOL add = msg->header.type == msg_add_address; - typedef NETIOAPI_API (*CreateUnicastIpAddressEntryFn) (const PMIB_UNICASTIPADDRESS_ROW); - typedef NETIOAPI_API (*InitializeUnicastIpAddressEntryFn) (PMIB_UNICASTIPADDRESS_ROW); - static CreateUnicastIpAddressEntryFn CreateUnicastIpAddressEntry = NULL; - static InitializeUnicastIpAddressEntryFn InitializeUnicastIpAddressEntry = NULL; - - if (!CreateUnicastIpAddressEntry || !InitializeUnicastIpAddressEntry) - { - HMODULE iphlpapi = GetModuleHandle(TEXT("iphlpapi.dll")); - if (iphlpapi == NULL) - { - return GetLastError(); - } - - CreateUnicastIpAddressEntry = (CreateUnicastIpAddressEntryFn) GetProcAddress(iphlpapi, "CreateUnicastIpAddressEntry"); - if (!CreateUnicastIpAddressEntry) - { - return GetLastError(); - } - - InitializeUnicastIpAddressEntry = (InitializeUnicastIpAddressEntryFn) GetProcAddress(iphlpapi, "InitializeUnicastIpAddressEntry"); - if (!InitializeUnicastIpAddressEntry) - { - return GetLastError(); - } - } - addr_row = malloc(sizeof(*addr_row)); if (addr_row == NULL) { @@ -706,24 +655,6 @@ CmpRoute(LPVOID item, LPVOID route) static DWORD DeleteRoute(PMIB_IPFORWARD_ROW2 fwd_row) { - typedef NETIOAPI_API (*DeleteIpForwardEntry2Fn) (PMIB_IPFORWARD_ROW2); - static DeleteIpForwardEntry2Fn DeleteIpForwardEntry2 = NULL; - - if (!DeleteIpForwardEntry2) - { - HMODULE iphlpapi = GetModuleHandle(TEXT("iphlpapi.dll")); - if (iphlpapi == NULL) - { - return GetLastError(); - } - - DeleteIpForwardEntry2 = (DeleteIpForwardEntry2Fn) GetProcAddress(iphlpapi, "DeleteIpForwardEntry2"); - if (!DeleteIpForwardEntry2) - { - return GetLastError(); - } - } - return DeleteIpForwardEntry2(fwd_row); } @@ -734,24 +665,6 @@ HandleRouteMessage(route_message_t *msg, undo_lists_t *lists) PMIB_IPFORWARD_ROW2 fwd_row; BOOL add = msg->header.type == msg_add_route; - typedef NETIOAPI_API (*CreateIpForwardEntry2Fn) (PMIB_IPFORWARD_ROW2); - static CreateIpForwardEntry2Fn CreateIpForwardEntry2 = NULL; - - if (!CreateIpForwardEntry2) - { - HMODULE iphlpapi = GetModuleHandle(TEXT("iphlpapi.dll")); - if (iphlpapi == NULL) - { - return GetLastError(); - } - - CreateIpForwardEntry2 = (CreateIpForwardEntry2Fn) GetProcAddress(iphlpapi, "CreateIpForwardEntry2"); - if (!CreateIpForwardEntry2) - { - return GetLastError(); - } - } - fwd_row = malloc(sizeof(*fwd_row)); if (fwd_row == NULL) { @@ -820,36 +733,12 @@ out: static DWORD HandleFlushNeighborsMessage(flush_neighbors_message_t *msg) { - typedef NETIOAPI_API (*FlushIpNetTable2Fn) (ADDRESS_FAMILY, NET_IFINDEX); - static FlushIpNetTable2Fn flush_fn = NULL; - if (msg->family == AF_INET) { return FlushIpNetTable(msg->iface.index); } - if (!flush_fn) - { - HMODULE iphlpapi = GetModuleHandle(TEXT("iphlpapi.dll")); - if (iphlpapi == NULL) - { - return GetLastError(); - } - - flush_fn = (FlushIpNetTable2Fn) GetProcAddress(iphlpapi, "FlushIpNetTable2"); - if (!flush_fn) - { - if (GetLastError() == ERROR_PROC_NOT_FOUND) - { - return WSAEPFNOSUPPORT; - } - else - { - return GetLastError(); - } - } - } - return flush_fn(msg->family, msg->iface.index); + return FlushIpNetTable2(msg->family, msg->iface.index); } static void @@ -915,17 +804,18 @@ HandleBlockDNSMessage(const block_dns_message_t *msg, undo_lists_t *lists) } interface_data->engine = engine; interface_data->index = msg->iface.index; + int is_auto = 0; interface_data->metric_v4 = get_interface_metric(msg->iface.index, - AF_INET); - if (interface_data->metric_v4 < 0) + AF_INET, &is_auto); + if (is_auto) { - interface_data->metric_v4 = -1; + interface_data->metric_v4 = 0; } interface_data->metric_v6 = get_interface_metric(msg->iface.index, - AF_INET6); - if (interface_data->metric_v6 < 0) + AF_INET6, &is_auto); + if (is_auto) { - interface_data->metric_v6 = -1; + interface_data->metric_v6 = 0; } err = AddListItem(&(*lists)[block_dns], interface_data); if (!err) @@ -1066,7 +956,7 @@ RegisterDNS(LPVOID unused) if (GetSystemDirectory(sys_path, MAX_PATH)) { - _snwprintf(ipcfg, MAX_PATH, L"%s\\%s", sys_path, L"ipconfig.exe"); + swprintf(ipcfg, MAX_PATH, L"%s\\%s", sys_path, L"ipconfig.exe"); ipcfg[MAX_PATH-1] = L'\0'; } @@ -1436,7 +1326,7 @@ RunOpenvpn(LPVOID p) STARTUPINFOW startup_info; PROCESS_INFORMATION proc_info; LPVOID user_env = NULL; - TCHAR ovpn_pipe_name[36]; + TCHAR ovpn_pipe_name[256]; /* The entire pipe name string can be up to 256 characters long according to MSDN. */ LPCWSTR exe_path; WCHAR *cmdline = NULL; size_t cmdline_size; @@ -1598,7 +1488,7 @@ RunOpenvpn(LPVOID p) } openvpn_sntprintf(ovpn_pipe_name, _countof(ovpn_pipe_name), - TEXT("\\\\.\\pipe\\openvpn\\service_%lu"), GetCurrentThreadId()); + TEXT("\\\\.\\pipe\\" PACKAGE "%s\\service_%lu"), service_instance, GetCurrentThreadId()); ovpn_pipe = CreateNamedPipe(ovpn_pipe_name, PIPE_ACCESS_DUPLEX | FILE_FLAG_FIRST_PIPE_INSTANCE | FILE_FLAG_OVERLAPPED, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, 1, 128, 128, 0, NULL); @@ -1706,8 +1596,8 @@ RunOpenvpn(LPVOID p) else if (exit_code != 0) { WCHAR buf[256]; - int len = _snwprintf(buf, _countof(buf), - L"OpenVPN exited with error: exit code = %lu", exit_code); + swprintf(buf, _countof(buf), + L"OpenVPN exited with error: exit code = %lu", exit_code); buf[_countof(buf) - 1] = L'\0'; ReturnError(pipe, ERROR_OPENVPN_STARTUP, buf, 1, &exit_event); } @@ -1765,6 +1655,7 @@ ServiceCtrlInteractive(DWORD ctrl_code, DWORD event, LPVOID data, LPVOID ctx) static HANDLE CreateClientPipeInstance(VOID) { + TCHAR pipe_name[256]; /* The entire pipe name string can be up to 256 characters long according to MSDN. */ HANDLE pipe = NULL; PACL old_dacl, new_dacl; PSECURITY_DESCRIPTOR sd; @@ -1801,7 +1692,8 @@ CreateClientPipeInstance(VOID) initialized = TRUE; } - pipe = CreateNamedPipe(TEXT("\\\\.\\pipe\\openvpn\\service"), flags, + openvpn_sntprintf(pipe_name, _countof(pipe_name), TEXT("\\\\.\\pipe\\" PACKAGE "%s\\service"), service_instance); + pipe = CreateNamedPipe(pipe_name, flags, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE, PIPE_UNLIMITED_INSTANCES, 1024, 1024, 0, NULL); if (pipe == INVALID_HANDLE_VALUE) @@ -1890,6 +1782,20 @@ FreeWaitHandles(LPHANDLE h) free(h); } +static BOOL +CmpHandle(LPVOID item, LPVOID hnd) +{ + return item == hnd; +} + + +VOID WINAPI +ServiceStartInteractiveOwn(DWORD dwArgc, LPTSTR *lpszArgv) +{ + status.dwServiceType = SERVICE_WIN32_OWN_PROCESS; + ServiceStartInteractive(dwArgc, lpszArgv); +} + VOID WINAPI ServiceStartInteractive(DWORD dwArgc, LPTSTR *lpszArgv) @@ -1900,11 +1806,6 @@ ServiceStartInteractive(DWORD dwArgc, LPTSTR *lpszArgv) list_item_t *threads = NULL; PHANDLE handles = NULL; DWORD handle_count; - BOOL - CmpHandle(LPVOID item, LPVOID hnd) - { - return item == hnd; - } service = RegisterServiceCtrlHandlerEx(interactive_service.name, ServiceCtrlInteractive, &status); if (!service) @@ -1912,7 +1813,6 @@ ServiceStartInteractive(DWORD dwArgc, LPTSTR *lpszArgv) return; } - status.dwServiceType = SERVICE_WIN32_SHARE_PROCESS; status.dwCurrentState = SERVICE_START_PENDING; status.dwServiceSpecificExitCode = NO_ERROR; status.dwWin32ExitCode = NO_ERROR; diff --git a/src/openvpnserv/service.c b/src/openvpnserv/service.c index b79e999..7157bea 100644 --- a/src/openvpnserv/service.c +++ b/src/openvpnserv/service.c @@ -223,46 +223,81 @@ out: int _tmain(int argc, TCHAR *argv[]) { - SERVICE_TABLE_ENTRY dispatchTable[] = { + /* + * Automatic + Interactive service (as a SERVICE_WIN32_SHARE_PROCESS) + * This is the default. + */ + const SERVICE_TABLE_ENTRY dispatchTable_shared[] = { { automatic_service.name, ServiceStartAutomatic }, { interactive_service.name, ServiceStartInteractive }, { NULL, NULL } }; + /* Automatic service only (as a SERVICE_WIN32_OWN_PROCESS) */ + const SERVICE_TABLE_ENTRY dispatchTable_automatic[] = { + { TEXT(""), ServiceStartAutomaticOwn }, + { NULL, NULL } + }; + + /* Interactive service only (as a SERVICE_WIN32_OWN_PROCESS) */ + const SERVICE_TABLE_ENTRY dispatchTable_interactive[] = { + { TEXT(""), ServiceStartInteractiveOwn }, + { NULL, NULL } + }; + + const SERVICE_TABLE_ENTRY *dispatchTable = dispatchTable_shared; + openvpn_service[0] = automatic_service; openvpn_service[1] = interactive_service; - if (argc > 1 && (*argv[1] == TEXT('-') || *argv[1] == TEXT('/'))) + for (int i = 1; i < argc; i++) { - if (_tcsicmp(TEXT("install"), argv[1] + 1) == 0) - { - return CmdInstallServices(); - } - else if (_tcsicmp(TEXT("remove"), argv[1] + 1) == 0) - { - return CmdRemoveServices(); - } - else if (_tcsicmp(TEXT("start"), argv[1] + 1) == 0) - { - BOOL is_auto = argc < 3 || _tcsicmp(TEXT("interactive"), argv[2]) != 0; - return CmdStartService(is_auto ? automatic : interactive); - } - else + if (*argv[i] == TEXT('-') || *argv[i] == TEXT('/')) { - goto dispatch; - } + if (_tcsicmp(TEXT("install"), argv[i] + 1) == 0) + { + return CmdInstallServices(); + } + else if (_tcsicmp(TEXT("remove"), argv[i] + 1) == 0) + { + return CmdRemoveServices(); + } + else if (_tcsicmp(TEXT("start"), argv[i] + 1) == 0) + { + BOOL is_auto = argc < i + 2 || _tcsicmp(TEXT("interactive"), argv[i + 1]) != 0; + return CmdStartService(is_auto ? automatic : interactive); + } + else if (argc > i + 2 && _tcsicmp(TEXT("instance"), argv[i] + 1) == 0) + { + dispatchTable = _tcsicmp(TEXT("interactive"), argv[i + 1]) != 0 ? + dispatchTable_automatic : + dispatchTable_interactive; - return 0; + service_instance = argv[i + 2]; + i += 2; + } + else + { + _tprintf(TEXT("%s -install to install the services\n"), APPNAME); + _tprintf(TEXT("%s -start <name> to start a service (\"automatic\" or \"interactive\")\n"), APPNAME); + _tprintf(TEXT("%s -remove to remove the services\n"), APPNAME); + + _tprintf(TEXT("\nService run-time parameters:\n")); + _tprintf(TEXT("-instance <name> <id>\n") + TEXT(" Runs the service as an alternate instance. <name> can be \"automatic\" or\n") + TEXT(" \"interactive\". The service settings will be loaded from\n") + TEXT(" HKLM\\Software\\" PACKAGE_NAME "<id> registry key, and the interactive service will accept\n") + TEXT(" requests on \\\\.\\pipe\\" PACKAGE "<id>\\service named pipe.\n")); + + return 0; + } + } } /* If it doesn't match any of the above parameters * the service control manager may be starting the service * so we must call StartServiceCtrlDispatcher */ -dispatch: - _tprintf(TEXT("%s -install to install the services\n"), APPNAME); - _tprintf(TEXT("%s -start <name> to start a service (\"automatic\" or \"interactive\")\n"), APPNAME); - _tprintf(TEXT("%s -remove to remove the services\n"), APPNAME); _tprintf(TEXT("\nStartServiceCtrlDispatcher being called.\n")); _tprintf(TEXT("This may take several seconds. Please wait.\n")); diff --git a/src/openvpnserv/service.h b/src/openvpnserv/service.h index 9fe573e..af8f37f 100644 --- a/src/openvpnserv/service.h +++ b/src/openvpnserv/service.h @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2013-2017 Heiko Hund <heiko.hund@sophos.com> + * Copyright (C) 2013-2018 Heiko Hund <heiko.hund@sophos.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -73,10 +73,12 @@ typedef struct { extern openvpn_service_t automatic_service; extern openvpn_service_t interactive_service; +extern LPCTSTR service_instance; - +VOID WINAPI ServiceStartAutomaticOwn(DWORD argc, LPTSTR *argv); VOID WINAPI ServiceStartAutomatic(DWORD argc, LPTSTR *argv); +VOID WINAPI ServiceStartInteractiveOwn(DWORD argc, LPTSTR *argv); VOID WINAPI ServiceStartInteractive(DWORD argc, LPTSTR *argv); int openvpn_vsntprintf(LPTSTR str, size_t size, LPCTSTR format, va_list arglist); diff --git a/src/openvpnserv/validate.c b/src/openvpnserv/validate.c index f6a97e9..653bd12 100644 --- a/src/openvpnserv/validate.c +++ b/src/openvpnserv/validate.c @@ -65,7 +65,7 @@ CheckConfigPath(const WCHAR *workdir, const WCHAR *fname, const settings_t *s) /* convert fname to full path */ if (PathIsRelativeW(fname) ) { - snwprintf(tmp, _countof(tmp), L"%s\\%s", workdir, fname); + swprintf(tmp, _countof(tmp), L"%s\\%s", workdir, fname); tmp[_countof(tmp)-1] = L'\0'; config_file = tmp; } diff --git a/src/plugins/Makefile.am b/src/plugins/Makefile.am index ca90496..f346178 100644 --- a/src/plugins/Makefile.am +++ b/src/plugins/Makefile.am @@ -5,7 +5,7 @@ # packet encryption, packet authentication, and # packet compression. # -# Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> +# Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> # Copyright (C) 2006-2012 Alon Bar-Lev <alon.barlev@gmail.com> # diff --git a/src/plugins/Makefile.in b/src/plugins/Makefile.in index d63b407..ca48312 100644 --- a/src/plugins/Makefile.in +++ b/src/plugins/Makefile.in @@ -21,7 +21,7 @@ # packet encryption, packet authentication, and # packet compression. # -# Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> +# Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> # Copyright (C) 2006-2012 Alon Bar-Lev <alon.barlev@gmail.com> # VPATH = @srcdir@ @@ -365,6 +365,7 @@ plugindir = @plugindir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ +runstatedir = @runstatedir@ sampledir = @sampledir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ diff --git a/src/plugins/auth-pam/Makefile.in b/src/plugins/auth-pam/Makefile.in index 50b7523..20d7731 100644 --- a/src/plugins/auth-pam/Makefile.in +++ b/src/plugins/auth-pam/Makefile.in @@ -389,6 +389,7 @@ plugindir = @plugindir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ +runstatedir = @runstatedir@ sampledir = @sampledir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ diff --git a/src/plugins/auth-pam/auth-pam.c b/src/plugins/auth-pam/auth-pam.c index ae514d7..26b0eeb 100644 --- a/src/plugins/auth-pam/auth-pam.c +++ b/src/plugins/auth-pam/auth-pam.c @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/plugins/auth-pam/utils.c b/src/plugins/auth-pam/utils.c index 4b900c7..4e0c5bf 100644 --- a/src/plugins/auth-pam/utils.c +++ b/src/plugins/auth-pam/utils.c @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/plugins/auth-pam/utils.h b/src/plugins/auth-pam/utils.h index c0b4b10..90fff66 100644 --- a/src/plugins/auth-pam/utils.h +++ b/src/plugins/auth-pam/utils.h @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/src/plugins/down-root/Makefile.in b/src/plugins/down-root/Makefile.in index f1a840a..7069108 100644 --- a/src/plugins/down-root/Makefile.in +++ b/src/plugins/down-root/Makefile.in @@ -388,6 +388,7 @@ plugindir = @plugindir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ +runstatedir = @runstatedir@ sampledir = @sampledir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ diff --git a/src/plugins/down-root/down-root.c b/src/plugins/down-root/down-root.c index 4198184..c5e5023 100644 --- a/src/plugins/down-root/down-root.c +++ b/src/plugins/down-root/down-root.c @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> * Copyright (C) 2013 David Sommerseth <davids@redhat.com> * * This program is free software; you can redistribute it and/or modify diff --git a/tests/Makefile.am b/tests/Makefile.am index 0795680..2087dd0 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -5,7 +5,7 @@ # packet encryption, packet authentication, and # packet compression. # -# Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> +# Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> # Copyright (C) 2006-2012 Alon Bar-Lev <alon.barlev@gmail.com> # diff --git a/tests/Makefile.in b/tests/Makefile.in index 5c18809..db15cca 100644 --- a/tests/Makefile.in +++ b/tests/Makefile.in @@ -21,7 +21,7 @@ # packet encryption, packet authentication, and # packet compression. # -# Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> +# Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> # Copyright (C) 2006-2012 Alon Bar-Lev <alon.barlev@gmail.com> # @@ -395,6 +395,7 @@ plugindir = @plugindir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ +runstatedir = @runstatedir@ sampledir = @sampledir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ diff --git a/tests/t_client.sh b/tests/t_client.sh index c9ff038..09dd26f 100755 --- a/tests/t_client.sh +++ b/tests/t_client.sh @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash # # run OpenVPN client against ``test reference'' server # - check that ping, http, ... via tunnel works @@ -133,12 +133,12 @@ fail() get_ifconfig_route() { # linux / iproute2? (-> if configure got a path) - if [ -n "" ] + if [ -n "/bin/ip" ] then echo "-- linux iproute2 --" - addr show | grep -v valid_lft - route show - -o -6 route show | grep -v ' cache' | sed -E -e 's/ expires [0-9]*sec//' -e 's/ (mtu|hoplimit|cwnd|ssthresh) [0-9]+//g' -e 's/ (rtt|rttvar) [0-9]+ms//g' + /bin/ip addr show | grep -v valid_lft + /bin/ip route show + /bin/ip -o -6 route show | grep -v ' cache' | sed -E -e 's/ expires [0-9]*sec//' -e 's/ (mtu|hoplimit|cwnd|ssthresh) [0-9]+//g' -e 's/ (rtt|rttvar) [0-9]+ms//g' return fi diff --git a/tests/unit_tests/Makefile.in b/tests/unit_tests/Makefile.in index 8e281ff..29c161a 100644 --- a/tests/unit_tests/Makefile.in +++ b/tests/unit_tests/Makefile.in @@ -354,6 +354,7 @@ plugindir = @plugindir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ +runstatedir = @runstatedir@ sampledir = @sampledir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ diff --git a/tests/unit_tests/example_test/Makefile.in b/tests/unit_tests/example_test/Makefile.in index e5ae5f3..56511d5 100644 --- a/tests/unit_tests/example_test/Makefile.in +++ b/tests/unit_tests/example_test/Makefile.in @@ -377,6 +377,7 @@ plugindir = @plugindir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ +runstatedir = @runstatedir@ sampledir = @sampledir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ diff --git a/tests/unit_tests/openvpn/Makefile.am b/tests/unit_tests/openvpn/Makefile.am index 3bd382c..7b44f42 100644 --- a/tests/unit_tests/openvpn/Makefile.am +++ b/tests/unit_tests/openvpn/Makefile.am @@ -54,5 +54,4 @@ tls_crypt_testdriver_SOURCES = test_tls_crypt.c mock_msg.c \ $(openvpn_srcdir)/crypto_openssl.c \ $(openvpn_srcdir)/otime.c \ $(openvpn_srcdir)/packet_id.c \ - $(openvpn_srcdir)/platform.c \ - $(openvpn_srcdir)/tls_crypt.c + $(openvpn_srcdir)/platform.c diff --git a/tests/unit_tests/openvpn/Makefile.in b/tests/unit_tests/openvpn/Makefile.in index 3055aad..0114d5c 100644 --- a/tests/unit_tests/openvpn/Makefile.in +++ b/tests/unit_tests/openvpn/Makefile.in @@ -159,8 +159,7 @@ am_tls_crypt_testdriver_OBJECTS = \ tls_crypt_testdriver-crypto_openssl.$(OBJEXT) \ tls_crypt_testdriver-otime.$(OBJEXT) \ tls_crypt_testdriver-packet_id.$(OBJEXT) \ - tls_crypt_testdriver-platform.$(OBJEXT) \ - tls_crypt_testdriver-tls_crypt.$(OBJEXT) + tls_crypt_testdriver-platform.$(OBJEXT) tls_crypt_testdriver_OBJECTS = $(am_tls_crypt_testdriver_OBJECTS) tls_crypt_testdriver_LDADD = $(LDADD) tls_crypt_testdriver_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ @@ -423,6 +422,7 @@ plugindir = @plugindir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ +runstatedir = @runstatedir@ sampledir = @sampledir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ @@ -483,8 +483,7 @@ tls_crypt_testdriver_SOURCES = test_tls_crypt.c mock_msg.c \ $(openvpn_srcdir)/crypto_openssl.c \ $(openvpn_srcdir)/otime.c \ $(openvpn_srcdir)/packet_id.c \ - $(openvpn_srcdir)/platform.c \ - $(openvpn_srcdir)/tls_crypt.c + $(openvpn_srcdir)/platform.c all: all-am @@ -575,7 +574,6 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tls_crypt_testdriver-packet_id.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tls_crypt_testdriver-platform.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tls_crypt_testdriver-test_tls_crypt.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tls_crypt_testdriver-tls_crypt.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @@ -934,20 +932,6 @@ tls_crypt_testdriver-platform.obj: $(openvpn_srcdir)/platform.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tls_crypt_testdriver_CFLAGS) $(CFLAGS) -c -o tls_crypt_testdriver-platform.obj `if test -f '$(openvpn_srcdir)/platform.c'; then $(CYGPATH_W) '$(openvpn_srcdir)/platform.c'; else $(CYGPATH_W) '$(srcdir)/$(openvpn_srcdir)/platform.c'; fi` -tls_crypt_testdriver-tls_crypt.o: $(openvpn_srcdir)/tls_crypt.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tls_crypt_testdriver_CFLAGS) $(CFLAGS) -MT tls_crypt_testdriver-tls_crypt.o -MD -MP -MF $(DEPDIR)/tls_crypt_testdriver-tls_crypt.Tpo -c -o tls_crypt_testdriver-tls_crypt.o `test -f '$(openvpn_srcdir)/tls_crypt.c' || echo '$(srcdir)/'`$(openvpn_srcdir)/tls_crypt.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/tls_crypt_testdriver-tls_crypt.Tpo $(DEPDIR)/tls_crypt_testdriver-tls_crypt.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(openvpn_srcdir)/tls_crypt.c' object='tls_crypt_testdriver-tls_crypt.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tls_crypt_testdriver_CFLAGS) $(CFLAGS) -c -o tls_crypt_testdriver-tls_crypt.o `test -f '$(openvpn_srcdir)/tls_crypt.c' || echo '$(srcdir)/'`$(openvpn_srcdir)/tls_crypt.c - -tls_crypt_testdriver-tls_crypt.obj: $(openvpn_srcdir)/tls_crypt.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tls_crypt_testdriver_CFLAGS) $(CFLAGS) -MT tls_crypt_testdriver-tls_crypt.obj -MD -MP -MF $(DEPDIR)/tls_crypt_testdriver-tls_crypt.Tpo -c -o tls_crypt_testdriver-tls_crypt.obj `if test -f '$(openvpn_srcdir)/tls_crypt.c'; then $(CYGPATH_W) '$(openvpn_srcdir)/tls_crypt.c'; else $(CYGPATH_W) '$(srcdir)/$(openvpn_srcdir)/tls_crypt.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/tls_crypt_testdriver-tls_crypt.Tpo $(DEPDIR)/tls_crypt_testdriver-tls_crypt.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(openvpn_srcdir)/tls_crypt.c' object='tls_crypt_testdriver-tls_crypt.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tls_crypt_testdriver_CFLAGS) $(CFLAGS) -c -o tls_crypt_testdriver-tls_crypt.obj `if test -f '$(openvpn_srcdir)/tls_crypt.c'; then $(CYGPATH_W) '$(openvpn_srcdir)/tls_crypt.c'; else $(CYGPATH_W) '$(srcdir)/$(openvpn_srcdir)/tls_crypt.c'; fi` - mostlyclean-libtool: -rm -f *.lo diff --git a/tests/unit_tests/openvpn/mock_msg.c b/tests/unit_tests/openvpn/mock_msg.c index 4bd11ca..140e637 100644 --- a/tests/unit_tests/openvpn/mock_msg.c +++ b/tests/unit_tests/openvpn/mock_msg.c @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2016-2017 Fox Crypto B.V. <openvpn@fox-it.com> + * Copyright (C) 2016-2018 Fox Crypto B.V. <openvpn@fox-it.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/tests/unit_tests/openvpn/test_argv.c b/tests/unit_tests/openvpn/test_argv.c index 8c90eb9..4a3ba55 100644 --- a/tests/unit_tests/openvpn/test_argv.c +++ b/tests/unit_tests/openvpn/test_argv.c @@ -13,24 +13,6 @@ #include "argv.h" #include "buffer.h" -/* - * This is defined here to prevent #include'ing misc.h - * which makes things difficult beyond any recognition - */ -size_t -adjust_power_of_2(size_t u) -{ - size_t ret = 1; - - while (ret < u) - { - ret <<= 1; - assert(ret > 0); - } - - return ret; -} - /* Defines for use in the tests and the mock parse_line() */ #define PATH1 "/s p a c e" #define PATH2 "/foo bar/baz" diff --git a/tests/unit_tests/openvpn/test_buffer.c b/tests/unit_tests/openvpn/test_buffer.c index 69bb2e5..d083b78 100644 --- a/tests/unit_tests/openvpn/test_buffer.c +++ b/tests/unit_tests/openvpn/test_buffer.c @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2016-2017 Fox Crypto B.V. <openvpn@fox-it.com> + * Copyright (C) 2016-2018 Fox Crypto B.V. <openvpn@fox-it.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -35,7 +35,7 @@ #include "buffer.h" static void -buffer_strprefix(void **state) +test_buffer_strprefix(void **state) { assert_true(strprefix("123456", "123456")); assert_true(strprefix("123456", "123")); @@ -44,11 +44,188 @@ buffer_strprefix(void **state) assert_false(strprefix("12", "123")); } +#define testsep "," +#define testnosep "" +#define teststr1 "one" +#define teststr2 "two" +#define teststr3 "three" +#define teststr4 "four" + +#define assert_buf_equals_str(buf, str) \ + assert_int_equal(BLEN(buf), strlen(str)); \ + assert_memory_equal(BPTR(buf), str, BLEN(buf)); + +struct test_buffer_list_aggregate_ctx { + struct buffer_list *empty; + struct buffer_list *one_two_three; + struct buffer_list *zero_length_strings; + struct buffer_list *empty_buffers; +}; + +static int test_buffer_list_setup(void **state) +{ + struct test_buffer_list_aggregate_ctx *ctx = calloc(1, sizeof(*ctx)); + ctx->empty = buffer_list_new(0); + + ctx->one_two_three = buffer_list_new(3); + buffer_list_push(ctx->one_two_three, teststr1); + buffer_list_push(ctx->one_two_three, teststr2); + buffer_list_push(ctx->one_two_three, teststr3); + + ctx->zero_length_strings = buffer_list_new(2); + buffer_list_push(ctx->zero_length_strings, ""); + buffer_list_push(ctx->zero_length_strings, ""); + + ctx->empty_buffers = buffer_list_new(2); + uint8_t data = 0; + buffer_list_push_data(ctx->empty_buffers, &data, 0); + buffer_list_push_data(ctx->empty_buffers, &data, 0); + + *state = ctx; + return 0; +} + +static int test_buffer_list_teardown(void **state) +{ + struct test_buffer_list_aggregate_ctx *ctx = *state; + + buffer_list_free(ctx->empty); + buffer_list_free(ctx->one_two_three); + buffer_list_free(ctx->zero_length_strings); + buffer_list_free(ctx->empty_buffers); + free(ctx); + return 0; +} + +static void +test_buffer_list_full(void **state) +{ + struct test_buffer_list_aggregate_ctx *ctx = *state; + + /* list full */ + assert_int_equal(ctx->one_two_three->size, 3); + buffer_list_push(ctx->one_two_three, teststr4); + assert_int_equal(ctx->one_two_three->size, 3); +} + +static void +test_buffer_list_aggregate_separator_empty(void **state) +{ + struct test_buffer_list_aggregate_ctx *ctx = *state; + + /* aggregating an empty buffer list results in an empty buffer list */ + buffer_list_aggregate_separator(ctx->empty, 3, testsep); + assert_null(ctx->empty->head); +} + +static void +test_buffer_list_aggregate_separator_noop(void **state) +{ + struct test_buffer_list_aggregate_ctx *ctx = *state; + + /* With a max length of 2, no aggregation should take place */ + buffer_list_aggregate_separator(ctx->one_two_three, 2, testsep); + assert_int_equal(ctx->one_two_three->size, 3); + struct buffer *buf = buffer_list_peek(ctx->one_two_three); + assert_buf_equals_str(buf, teststr1); +} + +static void +test_buffer_list_aggregate_separator_two(void **state) +{ + struct test_buffer_list_aggregate_ctx *ctx = *state; + const char *expected = teststr1 testsep teststr2 testsep; + + /* Aggregate the first two elements + * (add 1 to max_len to test if "three" is not sneaked in too) + */ + buffer_list_aggregate_separator(ctx->one_two_three, strlen(expected) + 1, + testsep); + assert_int_equal(ctx->one_two_three->size, 2); + struct buffer *buf = buffer_list_peek(ctx->one_two_three); + assert_buf_equals_str(buf, expected); +} + +static void +test_buffer_list_aggregate_separator_all(void **state) +{ + struct test_buffer_list_aggregate_ctx *ctx = *state; + + /* Aggregate all */ + buffer_list_aggregate_separator(ctx->one_two_three, 1<<16, testsep); + assert_int_equal(ctx->one_two_three->size, 1); + struct buffer *buf = buffer_list_peek(ctx->one_two_three); + assert_buf_equals_str(buf, + teststr1 testsep teststr2 testsep teststr3 testsep); +} + +static void +test_buffer_list_aggregate_separator_nosep(void **state) +{ + struct test_buffer_list_aggregate_ctx *ctx = *state; + + /* Aggregate all */ + buffer_list_aggregate_separator(ctx->one_two_three, 1<<16, testnosep); + assert_int_equal(ctx->one_two_three->size, 1); + struct buffer *buf = buffer_list_peek(ctx->one_two_three); + assert_buf_equals_str(buf, teststr1 teststr2 teststr3); +} + +static void +test_buffer_list_aggregate_separator_zerolen(void **state) +{ + struct test_buffer_list_aggregate_ctx *ctx = *state; + struct buffer_list *bl_zerolen = ctx->zero_length_strings; + + /* Aggregate all */ + buffer_list_aggregate_separator(bl_zerolen, 1<<16, testnosep); + assert_int_equal(bl_zerolen->size, 1); + struct buffer *buf = buffer_list_peek(bl_zerolen); + assert_buf_equals_str(buf, ""); +} + +static void +test_buffer_list_aggregate_separator_emptybuffers(void **state) +{ + struct test_buffer_list_aggregate_ctx *ctx = *state; + struct buffer_list *bl_emptybuffers = ctx->empty_buffers; + + /* Aggregate all */ + buffer_list_aggregate_separator(bl_emptybuffers, 1<<16, testnosep); + assert_int_equal(bl_emptybuffers->size, 1); + struct buffer *buf = buffer_list_peek(bl_emptybuffers); + assert_int_equal(BLEN(buf), 0); +} + int main(void) { const struct CMUnitTest tests[] = { - cmocka_unit_test(buffer_strprefix), + cmocka_unit_test(test_buffer_strprefix), + cmocka_unit_test_setup_teardown(test_buffer_list_full, + test_buffer_list_setup, + test_buffer_list_teardown), + cmocka_unit_test_setup_teardown(test_buffer_list_aggregate_separator_empty, + test_buffer_list_setup, + test_buffer_list_teardown), + cmocka_unit_test_setup_teardown(test_buffer_list_aggregate_separator_noop, + test_buffer_list_setup, + test_buffer_list_teardown), + cmocka_unit_test_setup_teardown(test_buffer_list_aggregate_separator_two, + test_buffer_list_setup, + test_buffer_list_teardown), + cmocka_unit_test_setup_teardown(test_buffer_list_aggregate_separator_all, + test_buffer_list_setup, + test_buffer_list_teardown), + cmocka_unit_test_setup_teardown(test_buffer_list_aggregate_separator_nosep, + test_buffer_list_setup, + test_buffer_list_teardown), + cmocka_unit_test_setup_teardown(test_buffer_list_aggregate_separator_zerolen, + test_buffer_list_setup, + test_buffer_list_teardown), + cmocka_unit_test_setup_teardown(test_buffer_list_aggregate_separator_emptybuffers, + test_buffer_list_setup, + test_buffer_list_teardown), }; return cmocka_run_group_tests_name("buffer", tests, NULL, NULL); diff --git a/tests/unit_tests/openvpn/test_packet_id.c b/tests/unit_tests/openvpn/test_packet_id.c index 0a785ad..ba420c4 100644 --- a/tests/unit_tests/openvpn/test_packet_id.c +++ b/tests/unit_tests/openvpn/test_packet_id.c @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2016 Fox Crypto B.V. <openvpn@fox-it.com> + * Copyright (C) 2016-2018 Fox Crypto B.V. <openvpn@fox-it.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 diff --git a/tests/unit_tests/openvpn/test_tls_crypt.c b/tests/unit_tests/openvpn/test_tls_crypt.c index 9b82035..f5618f8 100644 --- a/tests/unit_tests/openvpn/test_tls_crypt.c +++ b/tests/unit_tests/openvpn/test_tls_crypt.c @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2016-2017 Fox Crypto B.V. <openvpn@fox-it.com> + * Copyright (C) 2016-2018 Fox Crypto B.V. <openvpn@fox-it.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -39,7 +39,7 @@ #include <setjmp.h> #include <cmocka.h> -#include "tls_crypt.h" +#include "tls_crypt.c" #include "mock_msg.h" @@ -60,23 +60,13 @@ setup(void **state) { struct test_context *ctx = calloc(1, sizeof(*ctx)); *state = ctx; - ctx->kt.cipher = cipher_kt_get("AES-256-CTR"); - ctx->kt.digest = md_kt_get("SHA256"); - if (!ctx->kt.cipher) - { - printf("No AES-256-CTR support, skipping test.\n"); - return 0; - } - if (!ctx->kt.digest) + struct key key = { 0 }; + + ctx->kt = tls_crypt_kt(); + if (!ctx->kt.cipher || !ctx->kt.digest) { - printf("No HMAC-SHA256 support, skipping test.\n"); return 0; } - ctx->kt.cipher_length = cipher_kt_key_size(ctx->kt.cipher); - ctx->kt.hmac_length = md_kt_size(ctx->kt.digest); - - struct key key = { 0 }; - init_key_ctx(&ctx->co.key_ctx_bi.encrypt, &key, &ctx->kt, true, "TEST"); init_key_ctx(&ctx->co.key_ctx_bi.decrypt, &key, &ctx->kt, false, "TEST"); diff --git a/tests/unit_tests/plugins/Makefile.in b/tests/unit_tests/plugins/Makefile.in index dd05026..8dfeb98 100644 --- a/tests/unit_tests/plugins/Makefile.in +++ b/tests/unit_tests/plugins/Makefile.in @@ -354,6 +354,7 @@ plugindir = @plugindir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ +runstatedir = @runstatedir@ sampledir = @sampledir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ diff --git a/tests/unit_tests/plugins/auth-pam/Makefile.in b/tests/unit_tests/plugins/auth-pam/Makefile.in index 1ec3d31..e63807c 100644 --- a/tests/unit_tests/plugins/auth-pam/Makefile.in +++ b/tests/unit_tests/plugins/auth-pam/Makefile.in @@ -371,6 +371,7 @@ plugindir = @plugindir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ +runstatedir = @runstatedir@ sampledir = @sampledir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ diff --git a/vendor/Makefile.in b/vendor/Makefile.in index fa48135..1bc5d05 100644 --- a/vendor/Makefile.in +++ b/vendor/Makefile.in @@ -294,6 +294,7 @@ plugindir = @plugindir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ +runstatedir = @runstatedir@ sampledir = @sampledir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ @@ -3,12 +3,12 @@ define([PRODUCT_NAME], [OpenVPN]) define([PRODUCT_TARNAME], [openvpn]) define([PRODUCT_VERSION_MAJOR], [2]) define([PRODUCT_VERSION_MINOR], [4]) -define([PRODUCT_VERSION_PATCH], [.3]) +define([PRODUCT_VERSION_PATCH], [.5]) m4_append([PRODUCT_VERSION], [PRODUCT_VERSION_MAJOR]) m4_append([PRODUCT_VERSION], [PRODUCT_VERSION_MINOR], [[.]]) m4_append([PRODUCT_VERSION], [PRODUCT_VERSION_PATCH], [[]]) define([PRODUCT_BUGREPORT], [openvpn-users@lists.sourceforge.net]) -define([PRODUCT_VERSION_RESOURCE], [2,4,3,0]) +define([PRODUCT_VERSION_RESOURCE], [2,4,5,0]) dnl define the TAP version define([PRODUCT_TAP_WIN_COMPONENT_ID], [tap0901]) define([PRODUCT_TAP_WIN_MIN_MAJOR], [9]) |