diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 6f49350e75c..3bdf2aa9f00 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -130,7 +130,7 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-18.04, ubuntu-20.04] + os: [ubuntu-18.04, ubuntu-20.04, ubuntu-22.04] sslpkg: [libmbedtls-dev] ssllib: [mbedtls] libname: [mbed TLS] @@ -148,6 +148,10 @@ jobs: sslpkg: "libssl-dev" libname: OpenSSL 1.1.1 ssllib: openssl + - os: ubuntu-22.04 + sslpkg: "libssl-dev" + libname: OpenSSL 3.0.2 + ssllib: openssl - os: ubuntu-20.04 sslpkg: "libssl-dev" libname: OpenSSL 1.1.1 @@ -220,15 +224,37 @@ jobs: macos: runs-on: macos-latest + strategy: + fail-fast: false + matrix: + ossl: [ 1.1, 3 ] + build: [ normal, asan ] + include: + - build: asan + cflags: "-fsanitize=address -fno-optimize-sibling-calls -fsanitize-address-use-after-scope -fno-omit-frame-pointer -g -O1" + ldflags: -fsanitize=address + # Our build system ignores LDFLAGS for plugins + configureflags: --disable-plugin-auth-pam --disable-plugin-down-root + - build: normal + cflags: "-O2 -g" + ldflags: "" + configureflags: "" + + name: "macOS - OpenSSL ${{matrix.ossl}} - ${{matrix.build}}" + env: + CFLAGS: ${{ matrix.cflags }} + LDFLAGS: ${{ matrix.ldflags }} + OPENSSL_CFLAGS: -I/usr/local/opt/openssl@${{matrix.ossl}}/include + OPENSSL_LIBS: "-L/usr/local/opt/openssl@${{matrix.ossl}}/lib -lcrypto -lssl" steps: + - name: Install dependencies + run: brew install openssl@1.1 openssl@3 lzo lz4 man2html cmocka libtool automake autoconf - name: Checkout OpenVPN uses: actions/checkout@v2 - - name: Install dependencies - run: brew install openssl lzo lz4 man2html cmocka libtool automake autoconf - name: autoconf run: autoreconf -fvi - name: configure - run: OPENSSL_CFLAGS=-I/usr/local/opt/openssl@1.1/include OPENSSL_LIBS="-L/usr/local/opt/openssl@1.1/lib -lcrypto -lssl" ./configure + run: ./configure ${{matrix.configureflags}} - name: make all run: make -j4 - name: make check @@ -268,19 +294,17 @@ jobs: - name: Install rst2html run: python -m pip install --upgrade pip rst2html - - name: Restore artifacts, or run vcpkg, build and cache artifacts - uses: lukka/run-vcpkg@v7.4 + - name: Restore artifacts, or setup vcpkg (do not install any package) + uses: lukka/run-vcpkg@v10 with: - vcpkgGitCommitId: 'a2fcb03749ff5897b5985092934dc6057680c789' - vcpkgArguments: 'openssl lz4 lzo pkcs11-helper tap-windows6' - vcpkgTriplet: '${{ matrix.triplet }}-windows-ovpn' - cleanAfterBuild: false + vcpkgGitCommitId: '4b766c1cd17205e1b768c4fadfd5f867c1d0510e' + appendedCacheKey: '${{matrix.triplet}}' - - name: Build + - name: Run MSBuild consuming vcpkg.json working-directory: ${{env.GITHUB_WORKSPACE}} run: | - vcpkg integrate install - msbuild /m /p:Configuration=${{env.BUILD_CONFIGURATION}} /p:Platform="${{ matrix.plat }}" . + vcpkg integrate install + msbuild /m /p:Configuration=${{env.BUILD_CONFIGURATION}} /p:Platform="${{ matrix.plat }}" . - name: Archive artifacts uses: actions/upload-artifact@v2 diff --git a/.gitignore b/.gitignore index 178076edec8..7335154ff40 100644 --- a/.gitignore +++ b/.gitignore @@ -44,6 +44,7 @@ m4/ltoptions.m4 m4/ltsugar.m4 m4/ltversion.m4 m4/lt~obsolete.m4 +vcpkg_installed version.sh msvc-env-local.bat diff --git a/COPYING b/COPYING index 62e1a9d3ffb..b05944de463 100644 --- a/COPYING +++ b/COPYING @@ -31,6 +31,53 @@ OpenVPN license: file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. +Apache2 linking exception: +--------------------------- +OpenVPN is currently undergoing a license change to add an exception for +Apache 2 linking. The following exception is only valid for new contributions +after 2023-05-03 and past contribution where the authors have already agreed +to the exception. + + In addition, as a special exception, OpenVPN Inc and the + contributors give permission to link the code of this program to + libraries (the "Libraries") licensed under the Apache License + version 2.0 (this work and any linked library the "Combined Work") + and copy and distribute the Combined Work without an obligation to + license the Libraries under the GNU General Public License v2 + (GPL-2.0) as required by Section 2 of the GPL-2.0, and without an + obligation to refrain from imposing any additional restrictions in + the Apache License version 2 that are not in the GPL-2.0, as + required by Section 6 of the GPL-2.0. You must comply with the + GPL-2.0 in all other respects for the Combined Work, including + the obligation to provide source code. If you modify this file, you + may extend this exception to your version of the file, but you are + not obligated to do so. If you do not wish to do so, delete this + exception statement from your version. + +For better understanding, in plain non-legalese English this basically says: + + * The intention for this license exception is to allow OpenVPN to be + linked against APL-2 licensed libraries, even where the GPL-2.0 and + APL-2 licenses conflict from a legal perspective. + + * OpenVPN itself will stay GPL-2.0 and the code belonging to the + OpenVPN project must comply to the GPL-2.0 license. This is NOT + dual-licensing of the OpenVPN code base. + + * This license exception DOES NOT require NOR expect a license change + of the APL-2 based library. This exception allows using the APL-2 + library as-is. However, when distributing a compiled OpenVPN binary + linking against APL-2 libraries ("Combined Work"), the REQUIREMENT is + that the APL-2 library MUST also be available on similar terms as in + GPL-2.0, like providing the source code of the library upon request, + except in the two specific ways mentioned. + + * If the APL-2 based library forbids such linking and distribution, + this license exception DOES NOT overrule the restriction of the APL-2 + based library. If the APL-2 library cannot satisfy the requirements + in this license exception, you CANNOT distribute an OpenVPN binary + linked with this library. + LZO license: ------------ diff --git a/ChangeLog b/ChangeLog index edc0da3c6de..3701823d5df 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,105 @@ OpenVPN Change Log Copyright (C) 2002-2022 OpenVPN Inc +2023.02.14 -- Version 2.5.9 + +Arne Schwabe (6): + Implement optional cipher in --data-ciphers prefixed with ? + Fix handling an optional invalid cipher at the end of data-ciphers + Ensure that argument to parse_line has always space for final sentinel + Improve documentation on user/password requirement and unicodize function + Remove unused gc_arena + Fix corner case that might lead to leaked file descriptor + +Frank Lichtenheld (1): + msvc: always call git-version.py + +Lev Stipakov (1): + git-version.py: proper support for tags + +Max Fillinger (1): + Check if pkcs11_cert is NULL before freeing it + +Selva Nair (3): + Do not add leading space to pushed options + pull-filter: ignore leading "spaces" in option names + Do not include auth-token in pulled option digest + + +2022.10.27 -- Version 2.5.8 + +Antonio Quartulli (1): + tls-crypt-v2: bail out if the client key is too small + +Arne Schwabe (4): + Remove useless empty line from CR_RESPONSE message + Allow running a default configuration with TLS libraries without BF-CBC + Change command help to match man page and implementation + Fix OpenVPN querying user/password if auth-token with user expires + +Frank Lichtenheld (2): + t_client: Allow to force FAIL on prerequisite fails + t_client.sh: do not require fping6 + +Gert Doering (1): + Preparing release 2.5.8 + +Lev Stipakov (1): + msvc: add branch name and commit hash to version output + +Martin Janů (1): + Update the replay-window backtrack log message + +Selva Nair (5): + Do not skip ERROR:/SUCCESS: response from management interface + Fix auth-token usage with management-def-auth + Allow a few levels of recursion in virtual_output_callback() + Ensure --auth-nocache is handled during renegotiation + Purge auth-token as well while purging passwords + Do not copy auth_token username to itself + + +2022.05.24 -- Version 2.5.7 + +Antonio Quartulli (4): + networking: use OPENVPN_ETH_ALEN instead of ETH_ALEN + networking_iproute2: don't pass M_WARN to openvpn_execve_check() + t_net.sh: delete dummy iface using iproute command + auth-pam.c: add missing include limits.h + +Arne Schwabe (11): + Add insecure tls-cert-profile options + Refactor early initialisation and uninitialisation into methods + Allow loading of non default providers + Add ubuntu 22.04 to Github Actions + Add macos OpenSSL 3.0 and ASAN builds + Add --with-openssl-engine autoconf option (auto|yes|no) + Fix allowing/showing unsupported ciphers and digests + Remove dependency on BF-CBC existance from test_ncp + Add message when decoding PKCS12 file fails. + Translate OpenSSL 3.0 digest names to OpenSSL 1.1 digest names + Fix client-pending-auth error message to say ERROR instead of SUCCESS + +Gert Doering (1): + Preparing release 2.5.7 + +Jan Mikkelsen (1): + cipher-negotiation.rst missing from doc/Makefile.am + +Lev Stipakov (5): + vcpkg-ports\pkcs11-helper: shorten patch filename + msvc: adjust build options to harden binaries + vcpkg-ports: remove openssl port + vcpkg: switch to manifest + Fix M_ERRNO behavior on Windows + +Marc Becker (1): + vcpkg-ports/pkcs11-helper: bump to release 1.29 + +Simon Rozman (1): + tapctl: Resolve MSVC C4996 warnings + + 2022.03.16 -- Version 2.5.6 Antonio Quartulli (4): diff --git a/Changes.rst b/Changes.rst index 45d2c3f39e4..3ba78c6c7a7 100644 --- a/Changes.rst +++ b/Changes.rst @@ -1,3 +1,138 @@ +Overview of changes in 2.5.9 +============================ + +New features +------------ +- Optional ciphers in ``--data-ciphers`` + Ciphers in ``--data-ciphers`` can now be prefixed with a ``?`` to mark + those as optional and only use them if the SSL library supports them. + +User-visible Changes +-------------------- +- when compiling from a git checkout, put proper branch names into + windows builds + +Bugfixes +-------- +- do not include auth-token in pulled-option digest (interferes with + persist-tun when auth-token is in use, GH #200). + +- fix corner case that might lead to leaked file descriptor + +- fix parser bug (parse_line()) that can lead to buffer overflows on + malformed command line or server ccd file handling. Not exploitable. + +- pull-filter: ignore leading spaces in option names (work around server side + bug with erroneous extra spaces) + +- push: do not add leading spaces to "out of renegotiations" pushed auth-token + +- fix NULL pointer crash on "openvpn --show-tls" with mbedtls + + +Overview of changes in 2.5.8 +============================ + +New features +------------ +- allow running a default configuration with TLS libraries without BF-CBC + (even if TLS cipher negotiation would not actually use BF-CBC, the + long-term compatibility "default cipher BF-CBC" would trigger an error + on such TLS libraries) + +User-visible Changes +-------------------- +- add git branch name + commit ID to OpenVPN version string on + MSVC builds (windows) + +Testing Enhancements +-------------------- +- t_client.sh: if fping is found and fping6 is not, assume we have + fping 4.0 and up, and call "fping -6" for IPv6 ping tests + +- t_client.sh: allow to force FAIL on prerequisite fails, so a CI + environment will no longer "silently skip" t_client runs if fping (etc) + can not be found, but will error out + +Bugfixes +-------- +- ``--auth-nocache'' was not always correctly clearing username+password + after a renegotiation + +- ensure that auth-token received from server is cleared if requested + by the management interface ("forget password" or automatically + via ``--management-forget-disconnect'') + +- in a setup without username+password, but with auth-token and + auth-token-username pushed by the server, OpenVPN would start asking + for username+password on token expiry. Fix. + +- using ``--auth-token`` together with ``--management-client-auth`` + (on the server) would lead to TLS keys getting out of sync and client + being disconnected. Fix. + +- management interface would sometimes get stuck if client and server + try to write something simultaneously. Fix by allowing a limited + level of recursion in virtual_output_callback() + +- fix management interface not returning ERROR:/SUCCESS: response + on "signal SIGxxx" commands when in HOLD state + +- tls-crypt-v2: abort connection if client-key is too short + +- make man page agree with actual code on replay-window backtrag log message + +- remove useless empty line from CR_RESPONSE message + + +Overview of changes in 2.5.7 +============================ + +New features +------------ +- Limited OpenSSL 3.0 support + OpenSSL 3.0 support has been added. OpenSSL 3.0 support in 2.5 relies + on the compatiblity layer and full OpenSSL 3.0 support is coming with + OpenVPN 2.6. Only features that impact usage directly have been + backported: + + ``--tls-cert-profile insecure`` has been added to allow selecting the + lowest OpenSSL security level (not recommended, use only if you must). + + OpenSSL 3.0 no longer supports the Blowfish (and other deprecated) + algorithm by default and the new option ``--providers`` allows loading + the legacy provider to renable these algorithms. Most notably, + reading of many PKCS#12 files encrypted with the RC2 algorithm fails + unless ``--providers legacy default`` is configured. + + The OpenSSL engine feature ``--engine`` is not enabled by default + anymore if OpenSSL 3.0 is detected. + +- print OpenSSL error stack if decoding PKCS12 file fails + +User-visible Changes +-------------------- +- windows vcpkg building includes pkcs11-helper 1.29 now + +- add MSVC build options to harden windows binaries (HW-enforced + stack protection, SHA256 object hashes, SDL). + +Bugfixes +-------- +- fix omission of cipher-negotiation.rst in tarballs + +- fix errno handling on Windows (Windows has different classes of + error codes, GetLastError() and C runtime errno, these should now + be handled correctly) + +- fix PATH_MAX build failure in auth-pam.c + +- fix t_net.sh self-test leaving around stale "ovpn-dummy0" interface + +- fix overlong path names, leading to missing pkcs11-helper patch + in tarball + + Overview of changes in 2.5.6 ============================ diff --git a/build/msvc/msvc-generate/Makefile.mak b/build/msvc/msvc-generate/Makefile.mak index 1cb431026db..1c1c4bab181 100644 --- a/build/msvc/msvc-generate/Makefile.mak +++ b/build/msvc/msvc-generate/Makefile.mak @@ -1,4 +1,27 @@ -# Copyright (C) 2008-2012 Alon Bar-Lev +# +# 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) 2002-2022 OpenVPN Inc +# Copyright (C) 2008-2012 Alon Bar-Lev +# Copyright (C) 2022-2022 Lev Stipakov +# +# 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. +# CONFIG=$(SOLUTIONDIR)/version.m4 @@ -14,7 +37,9 @@ OUTPUT_PLUGIN_CONFIG=version.m4 INPUT_MAN=$(SOLUTIONDIR)/doc/openvpn.8.rst OUTPUT_MAN=$(SOLUTIONDIR)/doc/openvpn.8.html -all: $(OUTPUT_MSVC_VER) $(OUTPUT_PLUGIN) $(OUTPUT_MAN) +OUTPUT_MSVC_GIT_CONFIG=$(SOLUTIONDIR)/config-version.h + +all: $(OUTPUT_MSVC_VER) $(OUTPUT_PLUGIN) $(OUTPUT_MAN) $(OUTPUT_MSVC_GIT_CONFIG) $(OUTPUT_MSVC_VER): $(INPUT_MSVC_VER) $(CONFIG) cscript //nologo msvc-generate.js --config="$(CONFIG)" --input="$(INPUT_MSVC_VER)" --output="$(OUTPUT_MSVC_VER)" @@ -26,10 +51,17 @@ $(OUTPUT_PLUGIN): $(INPUT_PLUGIN) $(OUTPUT_PLUGIN_CONFIG) cscript //nologo msvc-generate.js --config="$(OUTPUT_PLUGIN_CONFIG)" --input="$(INPUT_PLUGIN)" --output="$(OUTPUT_PLUGIN)" $(OUTPUT_MAN): $(INPUT_MAN) - -FOR /F %i IN ('where rst2html.py') DO python %i "$(INPUT_MAN)" "$(OUTPUT_MAN)" + -FOR /F %i IN ('where rst2html.py') DO python %i "$(INPUT_MAN)" "$(OUTPUT_MAN)" + +# Force regeneration because we can't detect whether it is outdated +$(OUTPUT_MSVC_GIT_CONFIG): FORCE + python git-version.py $(SOLUTIONDIR) + +FORCE: clean: -del "$(OUTPUT_MSVC_VER)" -del "$(OUTPUT_PLUGIN)" -del "$(OUTPUT_PLUGIN_CONFIG)" -del "$(OUTPUT_MAN)" + -del "$(OUTPUT_MSVC_GIT_CONFIG)" diff --git a/build/msvc/msvc-generate/git-version.py b/build/msvc/msvc-generate/git-version.py new file mode 100644 index 00000000000..00458955af9 --- /dev/null +++ b/build/msvc/msvc-generate/git-version.py @@ -0,0 +1,75 @@ +# +# 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) 2022-2022 OpenVPN Inc +# Copyright (C) 2022-2022 Lev Stipakov +# +# 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. +# + +import os +import sys +import subprocess + +def run_command(args): + sp = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL) + o, _ = sp.communicate() + return o.decode("utf-8")[:-1] + +def get_branch_commit_id(): + commit_id = run_command(["git", "rev-parse", "--short=16", "HEAD"]) + if not commit_id: + raise + branch = run_command(["git", "describe", "--exact-match"]) + if not branch: + # this returns an array like ["master"] or ["release", "2.6"] + branch = run_command(["git", "rev-parse", "--symbolic-full-name", "HEAD"]).split("/")[2:] + if not branch: + branch = ["none"] + branch = "/" .join(branch) # handle cases like release/2.6 + + return branch, commit_id + +def main(): + try: + branch, commit_id = get_branch_commit_id() + except: + branch, commit_id = "unknown", "unknown" + + prev_content = "" + + name = os.path.join("%s" % (sys.argv[1] if len(sys.argv) > 1 else "."), "config-version.h") + try: + with open(name, "r") as f: + prev_content = f.read() + except: + # file doesn't exist + pass + + content = "#define CONFIGURE_GIT_REVISION \"%s/%s\"\n" % (branch, commit_id) + content += "#define CONFIGURE_GIT_FLAGS \"\"\n" + + if prev_content != content: + print("Writing %s" % name) + with open(name, "w") as f: + f.write(content) + else: + print("Content of %s hasn't changed" % name) + +if __name__ == "__main__": + main() diff --git a/build/msvc/msvc-generate/msvc-generate.vcxproj b/build/msvc/msvc-generate/msvc-generate.vcxproj index dda8b051d9e..eae94709408 100644 --- a/build/msvc/msvc-generate/msvc-generate.vcxproj +++ b/build/msvc/msvc-generate/msvc-generate.vcxproj @@ -150,7 +150,7 @@ - + diff --git a/config-msvc.h b/config-msvc.h index e7479c86144..47c5ba07ef6 100644 --- a/config-msvc.h +++ b/config-msvc.h @@ -177,3 +177,5 @@ typedef uint16_t in_port_t; #define HAVE_INET_NTOP #define HAVE_INET_PTON #endif + +#define HAVE_CONFIG_VERSION_H 1 diff --git a/configure.ac b/configure.ac index 6242cc22eb3..2f5f6bc7c11 100644 --- a/configure.ac +++ b/configure.ac @@ -281,6 +281,18 @@ AC_ARG_WITH( [with_crypto_library="openssl"] ) +AC_ARG_WITH( + [openssl-engine], + [AS_HELP_STRING([--with-openssl-engine], [enable engine support with OpenSSL. Default enabled for OpenSSL < 3.0, auto,yes,no @<:@default=auto@:>@])], + [ + case "${withval}" in + auto|yes|no) ;; + *) AC_MSG_ERROR([bad value ${withval} for --with-engine]) ;; + esac + ], + [with_openssl_engine="auto"] +) + AC_ARG_VAR([PLUGINDIR], [Path of plug-in directory @<:@default=LIBDIR/openvpn/plugins@:>@]) if test -n "${PLUGINDIR}"; then plugindir="${PLUGINDIR}" @@ -880,22 +892,44 @@ if test "${with_crypto_library}" = "openssl"; then [AC_MSG_ERROR([openssl check failed])] ) - have_openssl_engine="yes" - AC_CHECK_FUNCS( - [ \ + if test "${with_openssl_engine}" = "auto"; then + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[ + #include + ]], + [[ + /* Version encoding: MNNFFPPS - see opensslv.h for details */ + #if OPENSSL_VERSION_NUMBER >= 0x30000000L + #error Engine supported disabled by default in OpenSSL 3.0+ + #endif + ]] + )], + [have_openssl_engine="yes"], + [have_openssl_engine="no"] + ) + if test "${have_openssl_engine}" = "yes"; then + AC_CHECK_FUNCS( + [ \ ENGINE_load_builtin_engines \ ENGINE_register_all_complete \ - ENGINE_cleanup \ - ], - , - [have_openssl_engine="no"; break] - ) - if test "${have_openssl_engine}" = "no"; then - AC_CHECK_DECL( [ENGINE_cleanup], [have_openssl_engine="yes"],, - [[ - #include - ]] + ], + , + [have_openssl_engine="no"; break] + ) + fi + else + have_openssl_engine="${with_openssl_engine}" + if test "${have_openssl_engine}" = "yes"; then + AC_CHECK_FUNCS( + [ \ + ENGINE_load_builtin_engines \ + ENGINE_register_all_complete \ + ], + , + [AC_MSG_ERROR([OpenSSL engine support not found])] ) + fi fi if test "${have_openssl_engine}" = "yes"; then AC_DEFINE([HAVE_OPENSSL_ENGINE], [1], [OpenSSL engine support available]) diff --git a/contrib/vcpkg-ports/openssl/install-pc-files.cmake b/contrib/vcpkg-ports/openssl/install-pc-files.cmake deleted file mode 100644 index eb8d2b8c288..00000000000 --- a/contrib/vcpkg-ports/openssl/install-pc-files.cmake +++ /dev/null @@ -1,32 +0,0 @@ -function(install_pc_file name pc_data) - if(NOT DEFINED VCPKG_BUILD_TYPE OR VCPKG_BUILD_TYPE STREQUAL "release") - configure_file("${CMAKE_CURRENT_LIST_DIR}/openssl.pc.in" "${CURRENT_PACKAGES_DIR}/lib/pkgconfig/${name}.pc" @ONLY) - endif() - if(NOT DEFINED VCPKG_BUILD_TYPE OR VCPKG_BUILD_TYPE STREQUAL "debug") - configure_file("${CMAKE_CURRENT_LIST_DIR}/openssl.pc.in" "${CURRENT_PACKAGES_DIR}/debug/lib/pkgconfig/${name}.pc" @ONLY) - endif() -endfunction() - -install_pc_file(openssl [[ -Name: OpenSSL -Description: Secure Sockets Layer and cryptography libraries and tools -Requires: libssl libcrypto -]]) - -install_pc_file(libssl [[ -Name: OpenSSL-libssl -Description: Secure Sockets Layer and cryptography libraries -Libs: -L"${libdir}" -llibssl -Requires: libcrypto -Cflags: -I"${includedir}" -]]) - -install_pc_file(libcrypto [[ -Name: OpenSSL-libcrypto -Description: OpenSSL cryptography library -Libs: -L"${libdir}" -llibcrypto -Libs.private: -lcrypt32 -lws2_32 -Cflags: -I"${includedir}" -]]) - -vcpkg_fixup_pkgconfig() diff --git a/contrib/vcpkg-ports/openssl/openssl.pc.in b/contrib/vcpkg-ports/openssl/openssl.pc.in deleted file mode 100644 index 3033e1804da..00000000000 --- a/contrib/vcpkg-ports/openssl/openssl.pc.in +++ /dev/null @@ -1,6 +0,0 @@ -prefix=${pcfiledir}/../.. -exec_prefix=${prefix} -libdir=${exec_prefix}/lib -includedir=${prefix}/include -Version: @OPENSSL_VERSION@ -@pc_data@ diff --git a/contrib/vcpkg-ports/openssl/portfile.cmake b/contrib/vcpkg-ports/openssl/portfile.cmake deleted file mode 100644 index e94e7a83f02..00000000000 --- a/contrib/vcpkg-ports/openssl/portfile.cmake +++ /dev/null @@ -1,28 +0,0 @@ -if(EXISTS "${CURRENT_INSTALLED_DIR}/include/openssl/ssl.h") - message(FATAL_ERROR "Can't build openssl if libressl/boringssl is installed. Please remove libressl/boringssl, and try install openssl again if you need it.") -endif() - -set(OPENSSL_VERSION 1.1.1n) -vcpkg_download_distfile( - ARCHIVE - URLS "https://www.openssl.org/source/openssl-${OPENSSL_VERSION}.tar.gz" "https://www.openssl.org/source/old/1.1.1/openssl-${OPENSSL_VERSION}.tar.gz" - FILENAME "openssl-${OPENSSL_VERSION}.tar.gz" - SHA512 1937796736613dcf4105a54e42ecb61f95a1cea74677156f9459aea0f2c95159359e766089632bf364ee6b0d28d661eb9957bce8fecc9d2436378d8d79e8d0a4 -) - -vcpkg_find_acquire_program(PERL) -get_filename_component(PERL_EXE_PATH ${PERL} DIRECTORY) -vcpkg_add_to_path("${PERL_EXE_PATH}") - -if(VCPKG_TARGET_IS_UWP) - include("${CMAKE_CURRENT_LIST_DIR}/uwp/portfile.cmake") - include("${CMAKE_CURRENT_LIST_DIR}/install-pc-files.cmake") -elseif(VCPKG_TARGET_IS_WINDOWS AND NOT VCPKG_TARGET_IS_MINGW) - include("${CMAKE_CURRENT_LIST_DIR}/windows/portfile.cmake") - include("${CMAKE_CURRENT_LIST_DIR}/install-pc-files.cmake") -else() - include("${CMAKE_CURRENT_LIST_DIR}/unix/portfile.cmake") -endif() - -configure_file("${CMAKE_CURRENT_LIST_DIR}/vcpkg-cmake-wrapper.cmake.in" "${CURRENT_PACKAGES_DIR}/share/${PORT}/vcpkg-cmake-wrapper.cmake" @ONLY) -file(INSTALL "${CMAKE_CURRENT_LIST_DIR}/usage" DESTINATION "${CURRENT_PACKAGES_DIR}/share/${PORT}") diff --git a/contrib/vcpkg-ports/openssl/usage b/contrib/vcpkg-ports/openssl/usage deleted file mode 100644 index cf83f33916b..00000000000 --- a/contrib/vcpkg-ports/openssl/usage +++ /dev/null @@ -1,4 +0,0 @@ -The package openssl is compatible with built-in CMake targets: - - find_package(OpenSSL REQUIRED) - target_link_libraries(main PRIVATE OpenSSL::SSL OpenSSL::Crypto) diff --git a/contrib/vcpkg-ports/openssl/vcpkg-cmake-wrapper.cmake.in b/contrib/vcpkg-ports/openssl/vcpkg-cmake-wrapper.cmake.in deleted file mode 100644 index 4a5ee893a2f..00000000000 --- a/contrib/vcpkg-ports/openssl/vcpkg-cmake-wrapper.cmake.in +++ /dev/null @@ -1,78 +0,0 @@ -cmake_policy(PUSH) -cmake_policy(SET CMP0012 NEW) -cmake_policy(SET CMP0054 NEW) -cmake_policy(SET CMP0057 NEW) - -if(OPENSSL_USE_STATIC_LIBS) - if("@VCPKG_LIBRARY_LINKAGE@" STREQUAL "dynamic") - message(WARNING "OPENSSL_USE_STATIC_LIBS is set, but vcpkg port openssl was built with dynamic linkage") - endif() - set(OPENSSL_USE_STATIC_LIBS_BAK "${OPENSSL_USE_STATIC_LIBS}") - set(OPENSSL_USE_STATIC_LIBS FALSE) -endif() - -if(DEFINED OPENSSL_ROOT_DIR) - set(OPENSSL_ROOT_DIR_BAK "${OPENSSL_ROOT_DIR}") -endif() -get_filename_component(OPENSSL_ROOT_DIR "${CMAKE_CURRENT_LIST_DIR}" DIRECTORY) -get_filename_component(OPENSSL_ROOT_DIR "${OPENSSL_ROOT_DIR}" DIRECTORY) -find_path(OPENSSL_INCLUDE_DIR NAMES openssl/ssl.h PATH "${OPENSSL_ROOT_DIR}/include" NO_DEFAULT_PATH) -if(MSVC) - find_library(LIB_EAY_DEBUG NAMES libcrypto PATHS "${OPENSSL_ROOT_DIR}/debug/lib" NO_DEFAULT_PATH) - find_library(LIB_EAY_RELEASE NAMES libcrypto PATHS "${OPENSSL_ROOT_DIR}/lib" NO_DEFAULT_PATH) - find_library(SSL_EAY_DEBUG NAMES libssl PATHS "${OPENSSL_ROOT_DIR}/debug/lib" NO_DEFAULT_PATH) - find_library(SSL_EAY_RELEASE NAMES libssl PATHS "${OPENSSL_ROOT_DIR}/lib" NO_DEFAULT_PATH) -elseif(WIN32) - find_library(LIB_EAY NAMES libcrypto crypto NAMES_PER_DIR) - find_library(SSL_EAY NAMES libssl ssl NAMES_PER_DIR) -else() - find_library(OPENSSL_CRYPTO_LIBRARY NAMES crypto) - find_library(OPENSSL_SSL_LIBRARY NAMES ssl) -endif() - -_find_package(${ARGS}) - -unset(OPENSSL_ROOT_DIR) -if(DEFINED OPENSSL_ROOT_DIR_BAK) - set(OPENSSL_ROOT_DIR "${OPENSSL_ROOT_DIR_BAK}") - unset(OPENSSL_ROOT_DIR_BAK) -endif() - -if(DEFINED OPENSSL_USE_STATIC_LIBS_BAK) - set(OPENSSL_USE_STATIC_LIBS "${OPENSSL_USE_STATIC_LIBS_BAK}") - unset(OPENSSL_USE_STATIC_LIBS_BAK) -endif() - -if(OPENSSL_FOUND AND "@VCPKG_LIBRARY_LINKAGE@" STREQUAL "static") - if(WIN32) - list(APPEND OPENSSL_LIBRARIES crypt32 ws2_32) - if(TARGET OpenSSL::Crypto) - set_property(TARGET OpenSSL::Crypto APPEND PROPERTY INTERFACE_LINK_LIBRARIES "crypt32;ws2_32") - endif() - if(TARGET OpenSSL::SSL) - set_property(TARGET OpenSSL::SSL APPEND PROPERTY INTERFACE_LINK_LIBRARIES "crypt32;ws2_32") - endif() - else() - find_library(OPENSSL_DL_LIBRARY NAMES dl) - if(OPENSSL_DL_LIBRARY) - list(APPEND OPENSSL_LIBRARIES "dl") - if(TARGET OpenSSL::Crypto) - set_property(TARGET OpenSSL::Crypto APPEND PROPERTY INTERFACE_LINK_LIBRARIES "dl") - endif() - endif() - - if("REQUIRED" IN_LIST ARGS) - find_package(Threads REQUIRED) - else() - find_package(Threads) - endif() - list(APPEND OPENSSL_LIBRARIES ${CMAKE_THREAD_LIBS_INIT}) - if(TARGET OpenSSL::Crypto) - set_property(TARGET OpenSSL::Crypto APPEND PROPERTY INTERFACE_LINK_LIBRARIES "Threads::Threads") - endif() - if(TARGET OpenSSL::SSL) - set_property(TARGET OpenSSL::SSL APPEND PROPERTY INTERFACE_LINK_LIBRARIES "Threads::Threads") - endif() - endif() -endif() -cmake_policy(POP) diff --git a/contrib/vcpkg-ports/openssl/vcpkg.json b/contrib/vcpkg-ports/openssl/vcpkg.json deleted file mode 100644 index 18e6dde6637..00000000000 --- a/contrib/vcpkg-ports/openssl/vcpkg.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "name": "openssl", - "version-string": "1.1.1n", - "port-version": 2, - "description": "OpenSSL is an open source project that provides a robust, commercial-grade, and full-featured toolkit for the Transport Layer Security (TLS) and Secure Sockets Layer (SSL) protocols. It is also a general-purpose cryptography library.", - "homepage": "https://www.openssl.org", - "license": "OpenSSL", - "dependencies": [ - { - "name": "vcpkg-cmake", - "host": true - }, - { - "name": "vcpkg-cmake-config", - "host": true - } - ] -} diff --git a/contrib/vcpkg-ports/openssl/windows/portfile.cmake b/contrib/vcpkg-ports/openssl/windows/portfile.cmake deleted file mode 100644 index e4469ef3269..00000000000 --- a/contrib/vcpkg-ports/openssl/windows/portfile.cmake +++ /dev/null @@ -1,172 +0,0 @@ -vcpkg_extract_source_archive_ex( - OUT_SOURCE_PATH SOURCE_PATH - ARCHIVE ${ARCHIVE} -) - -vcpkg_find_acquire_program(NASM) -get_filename_component(NASM_EXE_PATH "${NASM}" DIRECTORY) -vcpkg_add_to_path(PREPEND "${NASM_EXE_PATH}") - -vcpkg_find_acquire_program(JOM) - -set(OPENSSL_SHARED no-shared) -if(VCPKG_LIBRARY_LINKAGE STREQUAL dynamic) - set(OPENSSL_SHARED shared) -endif() - -set(CONFIGURE_OPTIONS - enable-static-engine - enable-capieng - no-ssl2 - no-tests - -utf-8 - ${OPENSSL_SHARED} -) - -if(DEFINED OPENSSL_USE_NOPINSHARED) - set(CONFIGURE_OPTIONS ${CONFIGURE_OPTIONS} no-pinshared) -endif() - -if(OPENSSL_NO_AUTOLOAD_CONFIG) - set(CONFIGURE_OPTIONS ${CONFIGURE_OPTIONS} no-autoload-config) -endif() - -set(CONFIGURE_COMMAND "${PERL}" Configure ${CONFIGURE_OPTIONS}) - -if(VCPKG_TARGET_ARCHITECTURE STREQUAL "x86") - set(OPENSSL_ARCH VC-WIN32) -elseif(VCPKG_TARGET_ARCHITECTURE STREQUAL "x64") - set(OPENSSL_ARCH VC-WIN64A) -elseif(VCPKG_TARGET_ARCHITECTURE STREQUAL "arm") - set(OPENSSL_ARCH VC-WIN32-ARM) -elseif(VCPKG_TARGET_ARCHITECTURE STREQUAL "arm64") - set(OPENSSL_ARCH VC-WIN64-ARM) -else() - message(FATAL_ERROR "Unsupported target architecture: ${VCPKG_TARGET_ARCHITECTURE}") -endif() - -set(OPENSSL_MAKEFILE "makefile") - -file(REMOVE_RECURSE "${CURRENT_BUILDTREES_DIR}/${TARGET_TRIPLET}-rel" - "${CURRENT_BUILDTREES_DIR}/${TARGET_TRIPLET}-dbg") - -if(NOT DEFINED VCPKG_BUILD_TYPE OR VCPKG_BUILD_TYPE STREQUAL "release") - - # Copy openssl sources. - message(STATUS "Copying openssl release source files...") - file(GLOB OPENSSL_SOURCE_FILES ${SOURCE_PATH}/*) - foreach(SOURCE_FILE ${OPENSSL_SOURCE_FILES}) - file(COPY ${SOURCE_FILE} DESTINATION "${CURRENT_BUILDTREES_DIR}/${TARGET_TRIPLET}-rel") - endforeach() - message(STATUS "Copying openssl release source files... done") - set(SOURCE_PATH_RELEASE "${CURRENT_BUILDTREES_DIR}/${TARGET_TRIPLET}-rel") - - set(OPENSSLDIR_RELEASE ${CURRENT_PACKAGES_DIR}) - - message(STATUS "Configure ${TARGET_TRIPLET}-rel") - vcpkg_execute_required_process( - COMMAND ${CONFIGURE_COMMAND} ${OPENSSL_ARCH} "--prefix=${OPENSSLDIR_RELEASE}" "--openssldir=${OPENSSLDIR_RELEASE}" -FS - WORKING_DIRECTORY ${SOURCE_PATH_RELEASE} - LOGNAME configure-perl-${TARGET_TRIPLET}-rel - ) - message(STATUS "Configure ${TARGET_TRIPLET}-rel done") - - message(STATUS "Build ${TARGET_TRIPLET}-rel") - # Openssl's buildsystem has a race condition which will cause JOM to fail at some point. - # This is ok; we just do as much work as we can in parallel first, then follow up with a single-threaded build. - make_directory(${SOURCE_PATH_RELEASE}/inc32/openssl) - execute_process( - COMMAND ${JOM} -k -j $ENV{NUMBER_OF_PROCESSORS} -f ${OPENSSL_MAKEFILE} - WORKING_DIRECTORY ${SOURCE_PATH_RELEASE} - OUTPUT_FILE ${CURRENT_BUILDTREES_DIR}/build-${TARGET_TRIPLET}-rel-0-out.log - ERROR_FILE ${CURRENT_BUILDTREES_DIR}/build-${TARGET_TRIPLET}-rel-0-err.log - ) - vcpkg_execute_required_process( - COMMAND nmake -f ${OPENSSL_MAKEFILE} install_sw install_ssldirs - WORKING_DIRECTORY ${SOURCE_PATH_RELEASE} - LOGNAME build-${TARGET_TRIPLET}-rel-1) - - message(STATUS "Build ${TARGET_TRIPLET}-rel done") -endif() - - -if(NOT DEFINED VCPKG_BUILD_TYPE OR VCPKG_BUILD_TYPE STREQUAL "debug") - # Copy openssl sources. - message(STATUS "Copying openssl debug source files...") - file(GLOB OPENSSL_SOURCE_FILES ${SOURCE_PATH}/*) - foreach(SOURCE_FILE ${OPENSSL_SOURCE_FILES}) - file(COPY ${SOURCE_FILE} DESTINATION "${CURRENT_BUILDTREES_DIR}/${TARGET_TRIPLET}-dbg") - endforeach() - message(STATUS "Copying openssl debug source files... done") - set(SOURCE_PATH_DEBUG "${CURRENT_BUILDTREES_DIR}/${TARGET_TRIPLET}-dbg") - - set(OPENSSLDIR_DEBUG ${CURRENT_PACKAGES_DIR}/debug) - - message(STATUS "Configure ${TARGET_TRIPLET}-dbg") - vcpkg_execute_required_process( - COMMAND ${CONFIGURE_COMMAND} debug-${OPENSSL_ARCH} "--prefix=${OPENSSLDIR_DEBUG}" "--openssldir=${OPENSSLDIR_DEBUG}" -FS - WORKING_DIRECTORY ${SOURCE_PATH_DEBUG} - LOGNAME configure-perl-${TARGET_TRIPLET}-dbg - ) - message(STATUS "Configure ${TARGET_TRIPLET}-dbg done") - - message(STATUS "Build ${TARGET_TRIPLET}-dbg") - make_directory(${SOURCE_PATH_DEBUG}/inc32/openssl) - execute_process( - COMMAND "${JOM}" -k -j ${VCPKG_CONCURRENCY} -f "${OPENSSL_MAKEFILE}" - WORKING_DIRECTORY ${SOURCE_PATH_DEBUG} - OUTPUT_FILE ${CURRENT_BUILDTREES_DIR}/build-${TARGET_TRIPLET}-dbg-0-out.log - ERROR_FILE ${CURRENT_BUILDTREES_DIR}/build-${TARGET_TRIPLET}-dbg-0-err.log - ) - vcpkg_execute_required_process( - COMMAND nmake -f "${OPENSSL_MAKEFILE}" install_sw install_ssldirs - WORKING_DIRECTORY ${SOURCE_PATH_DEBUG} - LOGNAME build-${TARGET_TRIPLET}-dbg-1) - - message(STATUS "Build ${TARGET_TRIPLET}-dbg done") -endif() - -file(REMOVE_RECURSE "${CURRENT_PACKAGES_DIR}/certs") -file(REMOVE_RECURSE "${CURRENT_PACKAGES_DIR}/private") -file(REMOVE_RECURSE "${CURRENT_PACKAGES_DIR}/lib/engines-1_1") -file(REMOVE_RECURSE "${CURRENT_PACKAGES_DIR}/debug/certs") -file(REMOVE_RECURSE "${CURRENT_PACKAGES_DIR}/debug/lib/engines-1_1") -file(REMOVE_RECURSE "${CURRENT_PACKAGES_DIR}/debug/private") -file(REMOVE_RECURSE "${CURRENT_PACKAGES_DIR}/debug/include") - -file(REMOVE - "${CURRENT_PACKAGES_DIR}/ct_log_list.cnf" - "${CURRENT_PACKAGES_DIR}/ct_log_list.cnf.dist" - "${CURRENT_PACKAGES_DIR}/openssl.cnf.dist" - "${CURRENT_PACKAGES_DIR}/debug/bin/openssl.exe" - "${CURRENT_PACKAGES_DIR}/debug/ct_log_list.cnf" - "${CURRENT_PACKAGES_DIR}/debug/ct_log_list.cnf.dist" - "${CURRENT_PACKAGES_DIR}/debug/openssl.cnf" - "${CURRENT_PACKAGES_DIR}/debug/openssl.cnf.dist" -) - -file(MAKE_DIRECTORY "${CURRENT_PACKAGES_DIR}/tools/openssl/") -file(RENAME "${CURRENT_PACKAGES_DIR}/bin/openssl.exe" "${CURRENT_PACKAGES_DIR}/tools/openssl/openssl.exe") -file(RENAME "${CURRENT_PACKAGES_DIR}/openssl.cnf" "${CURRENT_PACKAGES_DIR}/tools/openssl/openssl.cnf") - -vcpkg_copy_tool_dependencies("${CURRENT_PACKAGES_DIR}/tools/openssl") - -if(VCPKG_LIBRARY_LINKAGE STREQUAL static) - # They should be empty, only the exes deleted above were in these directories - file(REMOVE_RECURSE "${CURRENT_PACKAGES_DIR}/debug/bin/") - file(REMOVE_RECURSE "${CURRENT_PACKAGES_DIR}/bin/") -endif() - -vcpkg_replace_string("${CURRENT_PACKAGES_DIR}/include/openssl/dtls1.h" - "" - "" -) - -vcpkg_replace_string("${CURRENT_PACKAGES_DIR}/include/openssl/rand.h" - "# include " - "#ifndef _WINSOCKAPI_\n#define _WINSOCKAPI_\n#endif\n# include " -) - -vcpkg_copy_pdbs() - -file(INSTALL "${SOURCE_PATH}/LICENSE" DESTINATION "${CURRENT_PACKAGES_DIR}/share/${PORT}" RENAME copyright) diff --git a/contrib/vcpkg-ports/pkcs11-helper/0003-config-w32-vc.h.in-indicate-OpenSSL-EC-support.patch b/contrib/vcpkg-ports/pkcs11-helper/0002-config-w32-vc.h.in-indicate-OpenSSL.patch similarity index 100% rename from contrib/vcpkg-ports/pkcs11-helper/0003-config-w32-vc.h.in-indicate-OpenSSL-EC-support.patch rename to contrib/vcpkg-ports/pkcs11-helper/0002-config-w32-vc.h.in-indicate-OpenSSL.patch diff --git a/contrib/vcpkg-ports/pkcs11-helper/0002-pkcs11.h-rename-interface-parameter.patch b/contrib/vcpkg-ports/pkcs11-helper/0002-pkcs11.h-rename-interface-parameter.patch deleted file mode 100644 index 13c60d9d807..00000000000 --- a/contrib/vcpkg-ports/pkcs11-helper/0002-pkcs11.h-rename-interface-parameter.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 0c2f862fe23dc6d2c0ca8432d1f6027c922c5a04 Mon Sep 17 00:00:00 2001 -From: Lev Stipakov -Date: Tue, 11 Jan 2022 14:24:45 +0200 -Subject: [PATCH] pkcs11.h: rename "interface" parameter - -"interface" is defined in cobaseapi.h as - - #define interface __STRUCT__ - -so use different name. - -Signed-off-by: Lev Stipakov ---- - include/pkcs11-helper-1.0/pkcs11.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/include/pkcs11-helper-1.0/pkcs11.h b/include/pkcs11-helper-1.0/pkcs11.h -index 85aa98e..7a7b958 100644 ---- a/include/pkcs11-helper-1.0/pkcs11.h -+++ b/include/pkcs11-helper-1.0/pkcs11.h -@@ -1210,7 +1210,7 @@ _CK_DECLARE_FUNCTION (C_GetInterfaceList, - _CK_DECLARE_FUNCTION (C_GetInterface, - (unsigned char *interface_name, - struct ck_version *version, -- struct ck_interface **interface, -+ struct ck_interface **iface, - ck_flags_t flags)); - - _CK_DECLARE_FUNCTION (C_LoginUser, --- -2.23.0.windows.1 - diff --git a/contrib/vcpkg-ports/pkcs11-helper/CONTROL b/contrib/vcpkg-ports/pkcs11-helper/CONTROL index ff116364746..1ead697ed11 100644 --- a/contrib/vcpkg-ports/pkcs11-helper/CONTROL +++ b/contrib/vcpkg-ports/pkcs11-helper/CONTROL @@ -1,4 +1,4 @@ Source: pkcs11-helper -Version: 1.28-4 +Version: 1.29-1 Homepage: https://github.com/OpenSC/pkcs11-helper Description: pkcs11-helper is a library that simplifies the interaction with PKCS#11 providers for end-user applications. diff --git a/contrib/vcpkg-ports/pkcs11-helper/portfile.cmake b/contrib/vcpkg-ports/pkcs11-helper/portfile.cmake index 55c653356d6..4432b5502bc 100644 --- a/contrib/vcpkg-ports/pkcs11-helper/portfile.cmake +++ b/contrib/vcpkg-ports/pkcs11-helper/portfile.cmake @@ -1,9 +1,9 @@ -set(VERSION 1.28.0) +set(VERSION 1.29.0) vcpkg_download_distfile(ARCHIVE - URLS "https://github.com/OpenSC/pkcs11-helper/releases/download/pkcs11-helper-${VERSION}/pkcs11-helper-${VERSION}.tar.gz" - FILENAME "pkcs11-helper-${VERSION}.tar.gz" - SHA512 1c1cc7f83ed360fabdcfa68d0eafa7d25be03e68c6a202e7ad2907feb472663bb34e12b9e162344ec221a4298abc02acdc75f0f45d9a89657aa7ac55e59badd5 + URLS "https://github.com/OpenSC/pkcs11-helper/releases/download/pkcs11-helper-${VERSION}/pkcs11-helper-${VERSION}.tar.bz2" + FILENAME "pkcs11-helper-${VERSION}.tar.bz2" + SHA512 c530f5a4b5826a02bfe787a1293a7595d5a0d6348daa16675bd10c6d6734b1f24a3cc73b5b89433cf1edf8815f8b7298fdfd1ed686f096bb5edfb425e9430eb2 ) vcpkg_extract_source_archive_ex( @@ -12,8 +12,7 @@ vcpkg_extract_source_archive_ex( REF ${VERSION} PATCHES 0001-nmake-compatibility-with-vcpkg-nmake.patch - 0002-pkcs11.h-rename-interface-parameter.patch - 0003-config-w32-vc.h.in-indicate-OpenSSL-EC-support.patch + 0002-config-w32-vc.h.in-indicate-OpenSSL.patch pkcs11-helper-001-RFC7512.patch ) diff --git a/doc/Makefile.am b/doc/Makefile.am index cc9a661cdf0..adf85446ced 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -25,6 +25,7 @@ dist_doc_DATA = \ openvpn_sections = \ man-sections/advanced-options.rst \ + man-sections/cipher-negotiation.rst \ man-sections/client-options.rst \ man-sections/connection-profiles.rst \ man-sections/encryption-options.rst \ diff --git a/doc/man-sections/generic-options.rst b/doc/man-sections/generic-options.rst index d5f08839b10..18085f9bd6d 100644 --- a/doc/man-sections/generic-options.rst +++ b/doc/man-sections/generic-options.rst @@ -252,6 +252,18 @@ which mode OpenVPN is configured as. This option solves the problem by persisting keys across :code:`SIGUSR1` resets, so they don't need to be re-read. +--providers providers + Load the list of (OpenSSL) providers. This is mainly useful for using an + external provider for key management like tpm2-openssl or to load the + legacy provider with + + :: + + --providers legacy default + + Behaviour of changing this option between SIGHUP might not be well behaving. + If you need to change/add/remove this option, fully restart OpenVPN. + --remap-usr1 signal Control whether internally or externally generated :code:`SIGUSR1` signals are remapped to :code:`SIGHUP` (restart without persisting state) or diff --git a/doc/man-sections/link-options.rst b/doc/man-sections/link-options.rst index 182f1498888..71387805102 100644 --- a/doc/man-sections/link-options.rst +++ b/doc/man-sections/link-options.rst @@ -330,7 +330,7 @@ the local and the remote host. value for ``n``. Satellite links in particular often require this. If you run OpenVPN at ``--verb 4``, you will see the message - "Replay-window backtrack occurred [x]" every time the maximum sequence + "PID_ERR replay-window backtrack occurred [x]" every time the maximum sequence number backtrack seen thus far increases. This can be used to calibrate ``n``. diff --git a/doc/man-sections/protocol-options.rst b/doc/man-sections/protocol-options.rst index e9d5d63d43b..25f8db12d95 100644 --- a/doc/man-sections/protocol-options.rst +++ b/doc/man-sections/protocol-options.rst @@ -184,6 +184,13 @@ configured in a compatible way between both the local and remote side. supported by the client will be pushed to clients that support cipher negotiation. + Starting with OpenVPN 2.5.9 a cipher can be prefixed with a :code:`?` to mark + it as optional. This allows including ciphers in the list that may not be + available on all platforms. + E.g. :code:`AES-256-GCM:AES-128-GCM:?CHACHA20-POLY1305` would only enable + Chacha20-Poly1305 if the underlying SSL library (and its configuration) + supports it. + Cipher negotiation is enabled in client-server mode only. I.e. if ``--mode`` is set to 'server' (server-side, implied by setting ``--server`` ), or if ``--pull`` is specified (client-side, implied by diff --git a/doc/man-sections/tls-options.rst b/doc/man-sections/tls-options.rst index f0b6d3dc53d..b7f44739175 100644 --- a/doc/man-sections/tls-options.rst +++ b/doc/man-sections/tls-options.rst @@ -369,6 +369,9 @@ certificates and keys: https://github.com/OpenVPN/easy-rsa The following profiles are supported: + :code:`insecure` + Identical for mbed TLS to `legacy` + :code:`legacy` (default) SHA1 and newer, RSA 2048-bit+, any elliptic curve. @@ -381,6 +384,9 @@ certificates and keys: https://github.com/OpenVPN/easy-rsa This option is only fully supported for mbed TLS builds. OpenSSL builds use the following approximation: + :code:`insecure` + sets "security level 0" + :code:`legacy` (default) sets "security level 1" diff --git a/doc/man-sections/vpn-network-options.rst b/doc/man-sections/vpn-network-options.rst index 25a26b3452f..645fd1efb61 100644 --- a/doc/man-sections/vpn-network-options.rst +++ b/doc/man-sections/vpn-network-options.rst @@ -116,7 +116,7 @@ routing. Valid syntax: :: - dhcp-options type [parm] + dhcp-option type [parm] :code:`DOMAIN` ``name`` Set Connection-specific DNS Suffix to :code:`name`. diff --git a/src/openvpn/auth_token.c b/src/openvpn/auth_token.c index ca7e5a4dd2f..7c4d15d1adf 100644 --- a/src/openvpn/auth_token.c +++ b/src/openvpn/auth_token.c @@ -87,6 +87,7 @@ add_session_token_env(struct tls_session *session, struct tls_multi *multi, default: /* Silence compiler warning, all four possible combinations are covered */ + state = NULL; ASSERT(0); } } @@ -348,8 +349,8 @@ verify_auth_token(struct user_pass *up, struct tls_multi *multi, return 0; } - /* Accept session tokens that not expired are in the acceptable range - * for renogiations */ + /* Accept session tokens only if their timestamp is in the acceptable range + * for renegotiations */ bool in_renog_time = now >= timestamp && now < timestamp + 2 * session->opt->renegotiate_seconds; @@ -361,13 +362,15 @@ verify_auth_token(struct user_pass *up, struct tls_multi *multi, if (!in_renog_time && !initialtoken) { + msg(M_WARN, "Timestamp (%" PRIu64 ") of auth-token is out of the renegotiation window", + timestamp); ret |= AUTH_TOKEN_EXPIRED; } /* Sanity check the initial timestamp */ if (timestamp < timestamp_initial) { - msg(M_WARN, "Initial timestamp (%" PRIu64 " in token from client earlier than " + msg(M_WARN, "Initial timestamp (%" PRIu64 ") in token from client earlier than " "current timestamp %" PRIu64 ". Broken/unsynchronised clock?", timestamp_initial, timestamp); ret |= AUTH_TOKEN_EXPIRED; diff --git a/src/openvpn/crypto_backend.h b/src/openvpn/crypto_backend.h index b5a122eeeb3..aebda3d6515 100644 --- a/src/openvpn/crypto_backend.h +++ b/src/openvpn/crypto_backend.h @@ -78,6 +78,21 @@ void crypto_clear_error(void); */ void crypto_init_lib_engine(const char *engine_name); + +/** + * Load the given (OpenSSL) providers + * @param provider name of providers to load + * @return reference to the loaded provider + */ +provider_t *crypto_load_provider(const char *provider); + +/** + * Unloads the given (OpenSSL) provider + * @param provname name of the provider to unload + * @param provider pointer to the provider to unload + */ +void crypto_unload_provider(const char *provname, provider_t *provider); + #ifdef DMALLOC /* * OpenSSL memory debugging. If dmalloc debugging is enabled, tell @@ -241,6 +256,8 @@ const cipher_kt_t *cipher_kt_get(const char *ciphername); * The returned name is normalised to the OpenVPN config name in case the * name differs from the name used by the crypto library. * + * Returns [null-cipher] in case the cipher_kt is NULL. + * * @param cipher_kt Static cipher parameters * * @return a statically allocated string describing the cipher. diff --git a/src/openvpn/crypto_mbedtls.c b/src/openvpn/crypto_mbedtls.c index 1da99d14743..000815209c9 100644 --- a/src/openvpn/crypto_mbedtls.c +++ b/src/openvpn/crypto_mbedtls.c @@ -69,6 +69,19 @@ crypto_init_lib_engine(const char *engine_name) "available"); } +provider_t *crypto_load_provider(const char *provider) +{ + if (provider) + { + msg(M_WARN, "Note: mbed TLS provider functionality is not available"); + } + return NULL; +} + +void crypto_unload_provider(const char *provname, provider_t *provider) +{ +} + /* * * Functions related to the core crypto library diff --git a/src/openvpn/crypto_mbedtls.h b/src/openvpn/crypto_mbedtls.h index 816e1397a4a..14614a12dbb 100644 --- a/src/openvpn/crypto_mbedtls.h +++ b/src/openvpn/crypto_mbedtls.h @@ -48,6 +48,9 @@ typedef mbedtls_md_context_t md_ctx_t; /** Generic HMAC %context. */ typedef mbedtls_md_context_t hmac_ctx_t; +/* Use a dummy type for the provider */ +typedef void provider_t; + /** Maximum length of an IV */ #define OPENVPN_MAX_IV_LENGTH MBEDTLS_MAX_IV_LENGTH diff --git a/src/openvpn/crypto_openssl.c b/src/openvpn/crypto_openssl.c index 0908e9aa173..7a05a352ad0 100644 --- a/src/openvpn/crypto_openssl.c +++ b/src/openvpn/crypto_openssl.c @@ -51,6 +51,10 @@ #include #include +#if OPENSSL_VERSION_NUMBER >= 0x30000000L +#include +#endif + #if defined(_WIN32) && defined(OPENSSL_NO_EC) #error Windows build with OPENSSL_NO_EC: disabling EC key is not supported. #endif @@ -145,6 +149,34 @@ crypto_init_lib_engine(const char *engine_name) #endif } +provider_t * +crypto_load_provider(const char *provider) +{ +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + /* Load providers into the default (NULL) library context */ + OSSL_PROVIDER *prov = OSSL_PROVIDER_load(NULL, provider); + if (!prov) + { + crypto_msg(M_FATAL, "failed to load provider '%s'", provider); + } + return prov; +#else /* OPENSSL_VERSION_NUMBER >= 0x30000000L */ + msg(M_WARN, "Note: OpenSSL provider functionality is not available"); + return NULL; +#endif +} + +void +crypto_unload_provider(const char *provname, provider_t *provider) +{ +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + if (!OSSL_PROVIDER_unload(provider)) + { + crypto_msg(M_FATAL, "failed to unload provider '%s'", provname); + } +#endif +} + /* * * Functions related to the core crypto library @@ -308,7 +340,11 @@ show_available_ciphers(void) || cipher_kt_mode_aead(cipher) )) { - cipher_list[num_ciphers++] = cipher; + /* Check explicit availibility (for OpenSSL 3.0) */ + if (cipher_kt_get(cipher_kt_name(cipher))) + { + cipher_list[num_ciphers++] = cipher; + } } if (num_ciphers == (sizeof(cipher_list)/sizeof(*cipher_list))) { @@ -340,6 +376,13 @@ show_available_ciphers(void) printf("\n"); } +void +print_digest(EVP_MD *digest, void *unused) +{ + printf("%s %d bit digest size\n", md_kt_name(digest), + EVP_MD_size(digest) * 8); +} + void show_available_digests(void) { @@ -353,16 +396,21 @@ show_available_digests(void) "the --auth option.\n\n"); #endif +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + EVP_MD_do_all_provided(NULL, print_digest, NULL); +#else for (nid = 0; nid < 10000; ++nid) { const EVP_MD *digest = EVP_get_digestbynid(nid); if (digest) { - printf("%s %d bit digest size\n", - OBJ_nid2sn(nid), EVP_MD_size(digest) * 8); + /* We cast the const away so we can keep the function prototype + * compatible with EVP_MD_do_all_provided */ + print_digest((EVP_MD *)digest, NULL); } } printf("\n"); +#endif } void @@ -593,6 +641,19 @@ cipher_kt_get(const char *ciphername) ciphername = translate_cipher_name_from_openvpn(ciphername); cipher = EVP_get_cipherbyname(ciphername); + /* This is a workaround for OpenSSL 3.0 to infer if the cipher is valid + * without doing all the refactoring that OpenVPN 2.6 has. This will + * not support custom algorithm from providers but at least ignore + * algorithms that are not available without providers (legacy) */ +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + EVP_CIPHER *tmpcipher = EVP_CIPHER_fetch(NULL, ciphername, NULL); + if (!tmpcipher) + { + cipher = NULL; + } + EVP_CIPHER_free(tmpcipher); +#endif + if (NULL == cipher) { crypto_msg(D_LOW, "Cipher algorithm '%s' not found", ciphername); @@ -893,6 +954,20 @@ md_kt_get(const char *digest) const EVP_MD *md = NULL; ASSERT(digest); md = EVP_get_digestbyname(digest); + + /* This is a workaround for OpenSSL 3.0 to infer if the digest is valid + * without doing all the refactoring that OpenVPN 2.6 has. This will + * not support custom algorithm from providers but at least ignore + * algorithms that are not available without providers (legacy) */ +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + EVP_MD *tmpmd = EVP_MD_fetch(NULL, digest, NULL); + if (!tmpmd) + { + md = NULL; + } + EVP_MD_free(tmpmd); +#endif + if (!md) { crypto_msg(M_FATAL, "Message hash algorithm '%s' not found", digest); @@ -907,6 +982,28 @@ md_kt_get(const char *digest) return md; } +/* Since we used the OpenSSL <=1.1 names as part of our OCC message, they + * are now unfortunately part of our wire protocol. + * + * OpenSSL 3.0 will still accept the "old" names so we do not need to use + * this translation table for forward lookup, only for returning the name + * with md_kt_name() */ +const cipher_name_pair digest_name_translation_table[] = { + { "BLAKE2s256", "BLAKE2S-256"}, + { "BLAKE2b512", "BLAKE2B-512"}, + { "RIPEMD160", "RIPEMD-160" }, + { "SHA224", "SHA2-224"}, + { "SHA256", "SHA2-256"}, + { "SHA384", "SHA2-384"}, + { "SHA512", "SHA2-512"}, + { "SHA512-224", "SHA2-512/224"}, + { "SHA512-256", "SHA2-512/256"}, + { "SHAKE128", "SHAKE-128"}, + { "SHAKE256", "SHAKE-256"}, +}; +const size_t digest_name_translation_table_count = + sizeof(digest_name_translation_table) / sizeof(*digest_name_translation_table); + const char * md_kt_name(const EVP_MD *kt) { @@ -914,7 +1011,20 @@ md_kt_name(const EVP_MD *kt) { return "[null-digest]"; } - return EVP_MD_name(kt); + + const char *name = EVP_MD_name(kt); + + /* Search for a digest name translation */ + for (size_t i = 0; i < digest_name_translation_table_count; i++) + { + const cipher_name_pair *pair = &digest_name_translation_table[i]; + if (!strcmp(name, pair->lib_name)) + { + name = pair->openvpn_name; + } + } + + return name; } unsigned char diff --git a/src/openvpn/crypto_openssl.h b/src/openvpn/crypto_openssl.h index ecc66fbfdaf..9bb58adae40 100644 --- a/src/openvpn/crypto_openssl.h +++ b/src/openvpn/crypto_openssl.h @@ -33,6 +33,10 @@ #include #include #include +#if OPENSSL_VERSION_NUMBER >= 0x30000000L +#include +#endif + /** Generic cipher key type %context. */ typedef EVP_CIPHER cipher_kt_t; @@ -49,6 +53,13 @@ typedef EVP_MD_CTX md_ctx_t; /** Generic HMAC %context. */ typedef HMAC_CTX hmac_ctx_t; +#if OPENSSL_VERSION_NUMBER < 0x30000000L +/* Use a dummy type for the provider */ +typedef void provider_t; +#else +typedef OSSL_PROVIDER provider_t; +#endif + /** Maximum length of an IV */ #define OPENVPN_MAX_IV_LENGTH EVP_MAX_IV_LENGTH diff --git a/src/openvpn/error.c b/src/openvpn/error.c index 54796d0356e..7fbda8442f9 100644 --- a/src/openvpn/error.c +++ b/src/openvpn/error.c @@ -220,6 +220,18 @@ x_msg(const unsigned int flags, const char *format, ...) va_end(arglist); } +static const char* +openvpn_strerror(int err, bool crt_error, struct gc_arena *gc) +{ +#ifdef _WIN32 + if (!crt_error) + { + return strerror_win32(err, gc); + } +#endif + return strerror(err); +} + void x_msg_va(const unsigned int flags, const char *format, va_list arglist) { @@ -244,7 +256,8 @@ x_msg_va(const unsigned int flags, const char *format, va_list arglist) } #endif - e = openvpn_errno(); + bool crt_error = false; + e = openvpn_errno_maybe_crt(&crt_error); /* * Apply muting filter. @@ -268,7 +281,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(e), e); + m1, openvpn_strerror(e, crt_error, &gc), e); SWAP; } @@ -649,7 +662,6 @@ x_check_status(int status, struct link_socket *sock, struct tuntap *tt) { - const int my_errno = openvpn_errno(); const char *extended_msg = NULL; msg(x_cs_verbose_level, "%s %s returned %d", @@ -672,26 +684,32 @@ x_check_status(int status, sock->info.mtu_changed = true; } } -#elif defined(_WIN32) +#endif /* EXTENDED_SOCKET_ERROR_CAPABILITY */ + +#ifdef _WIN32 /* get possible driver error from TAP-Windows driver */ if (tuntap_defined(tt)) { extended_msg = tap_win_getinfo(tt, &gc); } #endif - if (!ignore_sys_error(my_errno)) + + bool crt_error = false; + int my_errno = openvpn_errno_maybe_crt(&crt_error); + + if (!ignore_sys_error(my_errno, crt_error)) { if (extended_msg) { msg(x_cs_info_level, "%s %s [%s]: %s (code=%d)", description, sock ? proto2ascii(sock->info.proto, sock->info.af, true) : "", - extended_msg, strerror(my_errno), my_errno); + extended_msg, openvpn_strerror(my_errno, crt_error, &gc), my_errno); } else { msg(x_cs_info_level, "%s %s: %s (code=%d)", description, sock ? proto2ascii(sock->info.proto, sock->info.af, true) : "", - strerror(my_errno), my_errno); + openvpn_strerror(my_errno, crt_error, &gc), my_errno); } if (x_cs_err_delay_ms) diff --git a/src/openvpn/error.h b/src/openvpn/error.h index d2d83c8ae33..fc878a56a8c 100644 --- a/src/openvpn/error.h +++ b/src/openvpn/error.h @@ -71,13 +71,10 @@ struct gc_arena; /* String and Error functions */ #ifdef _WIN32 -#define openvpn_errno() GetLastError() -#define openvpn_strerror(e, gc) strerror_win32(e, gc) +#define openvpn_errno() GetLastError() const char *strerror_win32(DWORD errnum, struct gc_arena *gc); - #else -#define openvpn_errno() errno -#define openvpn_strerror(x, gc) strerror(x) +#define openvpn_errno() errno #endif /* @@ -363,20 +360,22 @@ msg_get_virtual_output(void) * which can be safely ignored. */ static inline bool -ignore_sys_error(const int err) +ignore_sys_error(const int err, bool crt_error) { - /* I/O operation pending */ #ifdef _WIN32 - if (err == WSAEWOULDBLOCK || err == WSAEINVAL) + if (!crt_error && ((err == WSAEWOULDBLOCK || err == WSAEINVAL))) { return true; } #else - if (err == EAGAIN) + crt_error = true; +#endif + + /* I/O operation pending */ + if (crt_error && (err == EAGAIN)) { return true; } -#endif #if 0 /* if enabled, suppress ENOBUFS errors */ #ifdef ENOBUFS @@ -398,6 +397,26 @@ nonfatal(const unsigned int err) return err & M_FATAL ? (err ^ M_FATAL) | M_NONFATAL : err; } +static inline int +openvpn_errno_maybe_crt(bool *crt_error) +{ + int err = 0; + *crt_error = false; +#ifdef _WIN32 + err = GetLastError(); + if (err == ERROR_SUCCESS) + { + /* error is likely C runtime */ + *crt_error = true; + err = errno; + } +#else + *crt_error = true; + err = errno; +#endif + return err; +} + #include "errlevel.h" #endif /* ifndef ERROR_H */ diff --git a/src/openvpn/forward.c b/src/openvpn/forward.c index 392a5c9f20e..de7cafded4b 100644 --- a/src/openvpn/forward.c +++ b/src/openvpn/forward.c @@ -1676,7 +1676,14 @@ process_outgoing_link(struct context *c) } /* for unreachable network and "connecting" state switch to the next host */ - if (size < 0 && ENETUNREACH == error_code && c->c2.tls_multi + + bool unreachable = error_code == +#ifdef _WIN32 + WSAENETUNREACH; +#else + ENETUNREACH; +#endif + if (size < 0 && unreachable && c->c2.tls_multi && !tls_initial_packet_received(c->c2.tls_multi) && c->options.mode == MODE_POINT_TO_POINT) { msg(M_INFO, "Network unreachable, restarting"); @@ -1707,8 +1714,6 @@ process_outgoing_link(struct context *c) void process_outgoing_tun(struct context *c) { - struct gc_arena gc = gc_new(); - /* * Set up for write() call to TUN/TAP * device. @@ -1794,7 +1799,6 @@ process_outgoing_tun(struct context *c) buf_reset(&c->c2.to_tun); perf_pop(); - gc_free(&gc); } void diff --git a/src/openvpn/init.c b/src/openvpn/init.c index da4d60afa3b..be8ff80fd84 100644 --- a/src/openvpn/init.c +++ b/src/openvpn/init.c @@ -596,6 +596,7 @@ init_query_passwords(const struct context *c) /* Auth user/pass input */ if (c->options.auth_user_pass_file) { + enable_auth_user_pass(); #ifdef ENABLE_MANAGEMENT auth_user_pass_setup(c->options.auth_user_pass_file, &c->options.sc_info); #else @@ -1596,19 +1597,6 @@ initialization_sequence_completed(struct context *c, const unsigned int flags) /* If we delayed UID/GID downgrade or chroot, do it now */ do_uid_gid_chroot(c, true); - - /* - * In some cases (i.e. when receiving auth-token via - * push-reply) the auth-nocache option configured on the - * client is overridden; for this reason we have to wait - * for the push-reply message before attempting to wipe - * the user/pass entered by the user - */ - if (c->options.mode == MODE_POINT_TO_POINT) - { - ssl_clean_user_pass(); - } - /* Test if errors */ if (flags & ISC_ERRORS) { @@ -2764,14 +2752,35 @@ do_init_crypto_tls_c1(struct context *c) #endif /* if P2MP */ } - /* Do not warn if we only have BF-CBC in options->ciphername - * because it is still the default cipher */ - bool warn = !streq(options->ciphername, "BF-CBC") - || options->enable_ncp_fallback; - /* Get cipher & hash algorithms */ - init_key_type(&c->c1.ks.key_type, options->ciphername, options->authname, - options->keysize, true, warn); - + /* + * BF-CBC is allowed to be used only when explicitly configured + * as NCP-fallback or when NCP has been disabled or explicitly + * allowed in the in ncp_ciphers list. + * In all other cases do not attempt to initialize BF-CBC as it + * may not even be supported by the underlying SSL library. + * + * Therefore, the key structure has to be initialized when: + * - any non-BF-CBC cipher was selected; or + * - BF-CBC is selected and NCP is disabled (explicit request to + * use the BF-CBC cipher); or + * - BF-CBC is selected, NCP is enabled and fallback is enabled + * (BF-CBC will be the fallback). + * - BF-CBC is in data-ciphers and we negotiate to use BF-CBC: + * If the negotiated cipher and options->ciphername are the + * same we do not reinit the cipher + * + * Note that BF-CBC will still be part of the OCC string to retain + * backwards compatibility with older clients. + */ + if (!streq(options->ciphername, "BF-CBC") || !options->ncp_enabled + || (options->ncp_enabled && tls_item_in_cipher_list("BF-CBC", options->ncp_ciphers)) + || options->enable_ncp_fallback) + { + /* Do not warn if the if the cipher is used only in OCC */ + bool warn = !options->ncp_enabled || options->enable_ncp_fallback; + init_key_type(&c->c1.ks.key_type, options->ciphername, options->authname, + options->keysize, true, warn); + } /* Initialize PRNG with config-specified digest */ prng_init(options->prng_hash, options->prng_nonce_secret_len); diff --git a/src/openvpn/lladdr.c b/src/openvpn/lladdr.c index 3ddbebb3896..ee677187d82 100644 --- a/src/openvpn/lladdr.c +++ b/src/openvpn/lladdr.c @@ -13,6 +13,7 @@ #include "misc.h" #include "run_command.h" #include "lladdr.h" +#include "proto.h" int set_lladdr(openvpn_net_ctx_t *ctx, const char *ifname, const char *lladdr, @@ -26,7 +27,7 @@ set_lladdr(openvpn_net_ctx_t *ctx, const char *ifname, const char *lladdr, } #if defined(TARGET_LINUX) - uint8_t addr[ETH_ALEN]; + uint8_t addr[OPENVPN_ETH_ALEN]; sscanf(lladdr, MAC_FMT, MAC_SCAN_ARG(addr)); r = (net_addr_ll_set(ctx, ifname, addr) == 0); diff --git a/src/openvpn/manage.c b/src/openvpn/manage.c index b327170c1d8..0a0b67fbba6 100644 --- a/src/openvpn/manage.c +++ b/src/openvpn/manage.c @@ -314,8 +314,7 @@ virtual_output_callback_func(void *arg, const unsigned int flags, const char *st #define AF_DID_PUSH (1<<0) #define AF_DID_RESET (1<<1) - - if (!recursive_level) /* don't allow recursion */ + if (recursive_level < 5) /* limit recursion */ { struct gc_arena gc = gc_new(); struct log_entry e; @@ -382,6 +381,12 @@ virtual_output_callback_func(void *arg, const unsigned int flags, const char *st --recursive_level; } + else + { + /* cannot use msg here */ + printf("virtual_output: message to management interface " + "dropped due to recursion: <%s>\n", str); + } } /* @@ -428,14 +433,11 @@ man_signal(struct management *man, const char *name) } else { + msg(M_CLIENT, "ERROR: signal '%s' is currently ignored", name); if (man->persist.special_state_msg) { msg(M_CLIENT, "%s", man->persist.special_state_msg); } - else - { - msg(M_CLIENT, "ERROR: signal '%s' is currently ignored", name); - } } } else @@ -766,6 +768,7 @@ static void man_forget_passwords(struct management *man) { ssl_purge_auth(false); + (void)ssl_clean_auth_token(); msg(M_CLIENT, "SUCCESS: Passwords were forgotten"); } @@ -1029,8 +1032,8 @@ man_client_pending_auth(struct management *man, const char *cid_str, const char } else { - msg(M_CLIENT, "SUCCESS: client-pending-auth command failed." - " Extra paramter might be too long"); + msg(M_CLIENT, "ERROR: client-pending-auth command failed." + " Extra parameter might be too long"); } } else @@ -2008,6 +2011,7 @@ man_reset_client_socket(struct management *man, const bool exiting) if (man->settings.flags & MF_FORGET_DISCONNECT) { ssl_purge_auth(false); + (void)ssl_clean_auth_token(); } if (man->settings.flags & MF_SIGNAL) @@ -2085,9 +2089,10 @@ man_process_command(struct management *man, const char *line) static bool man_io_error(struct management *man, const char *prefix) { - const int err = openvpn_errno(); + bool crt_error = false; + int err = openvpn_errno_maybe_crt(&crt_error); - if (!ignore_sys_error(err)) + if (!ignore_sys_error(err, crt_error)) { struct gc_arena gc = gc_new(); msg(D_MANAGEMENT, "MANAGEMENT: TCP %s error: %s", prefix, @@ -2972,17 +2977,14 @@ management_notify_client_cr_response(unsigned mda_key_id, { gc = gc_new(); - struct buffer out = alloc_buf_gc(256, &gc); msg(M_CLIENT, ">CLIENT:CR_RESPONSE,%lu,%u,%s", mdac->cid, mda_key_id, response); man_output_extra_env(management, "CLIENT"); - if (management->connection.env_filter_level>0) + if (management->connection.env_filter_level > 0) { man_output_peer_info_env(management, mdac); } man_output_env(es, true, management->connection.env_filter_level, "CLIENT"); - management_notify_generic(management, BSTR(&out)); - gc_free(&gc); } } diff --git a/src/openvpn/misc.c b/src/openvpn/misc.c index dceccd22ac4..e4662a7bdb0 100644 --- a/src/openvpn/misc.c +++ b/src/openvpn/misc.c @@ -273,6 +273,7 @@ get_user_pass_cr(struct user_pass *up, msg(D_LOW, "No password found in %s authfile '%s'. Querying the management interface", prefix, auth_file); if (!auth_user_pass_mgmt(up, prefix, flags, auth_challenge)) { + fclose(fp); return false; } } @@ -519,19 +520,13 @@ set_auth_token(struct user_pass *up, struct user_pass *tk, const char *token) * --auth-token has no username, so it needs the username * either already set or copied from up, or later set by * --auth-token-user - * - * Do not overwrite the username if already set to avoid - * overwriting an username set by --auth-token-user + * If already set, tk is fully defined. */ - if (up->defined && !tk->defined) + if (strlen(tk->username)) { - strncpynt(tk->username, up->username, USER_PASS_LEN); tk->defined = true; } } - - /* Cleans user/pass for nocache */ - purge_user_pass(up, false); } void diff --git a/src/openvpn/misc.h b/src/openvpn/misc.h index 570e473b28a..1e5205671ad 100644 --- a/src/openvpn/misc.h +++ b/src/openvpn/misc.h @@ -74,6 +74,7 @@ struct user_pass #else #define USER_PASS_LEN 128 #endif + /* Note that username and password are expected to be null-terminated */ char username[USER_PASS_LEN]; char password[USER_PASS_LEN]; }; diff --git a/src/openvpn/networking_iproute2.c b/src/openvpn/networking_iproute2.c index 3ca2bb35c31..db0f5503b29 100644 --- a/src/openvpn/networking_iproute2.c +++ b/src/openvpn/networking_iproute2.c @@ -105,7 +105,7 @@ net_addr_ll_set(openvpn_net_ctx_t *ctx, const openvpn_net_iface_t *iface, iproute_path, MAC_PRINT_ARG(addr), iface); argv_msg(M_INFO, &argv); - if (!openvpn_execve_check(&argv, ctx->es, M_WARN, + if (!openvpn_execve_check(&argv, ctx->es, 0, "Linux ip link set addr failed")) { ret = -1; diff --git a/src/openvpn/networking_sitnl.c b/src/openvpn/networking_sitnl.c index 959c897f117..515a30d6f0c 100644 --- a/src/openvpn/networking_sitnl.c +++ b/src/openvpn/networking_sitnl.c @@ -32,6 +32,7 @@ #include "buffer.h" #include "misc.h" #include "networking.h" +#include "proto.h" #include #include @@ -748,7 +749,7 @@ net_addr_ll_set(openvpn_net_ctx_t *ctx, const openvpn_net_iface_t *iface, req.i.ifi_family = AF_PACKET; req.i.ifi_index = ifindex; - SITNL_ADDATTR(&req.n, sizeof(req), IFLA_ADDRESS, addr, ETH_ALEN); + SITNL_ADDATTR(&req.n, sizeof(req), IFLA_ADDRESS, addr, OPENVPN_ETH_ALEN); msg(M_INFO, "%s: lladdr " MAC_FMT " for %s", __func__, MAC_PRINT_ARG(addr), iface); diff --git a/src/openvpn/ntlm.c b/src/openvpn/ntlm.c index e3707484d59..9158cfd6729 100644 --- a/src/openvpn/ntlm.c +++ b/src/openvpn/ntlm.c @@ -143,6 +143,19 @@ my_strupr(char *str) } } +/** + * This function expects a null-terminated string in src and will + * copy it (including the terminating NUL byte), + * alternating it with 0 to dst. + * + * This basically will transform a ASCII string into valid UTF-16. + * Characters that are 8bit in src, will get the same treatment, resulting in + * invalid or wrong unicode code points. + * + * @note the function will blindly assume that dst has double + * the space of src. + * @return the length of the number of bytes written to dst + */ static int unicodize(char *dst, const char *src) { diff --git a/src/openvpn/openvpn.c b/src/openvpn/openvpn.c index a21b21e2351..1cd8f1b308a 100644 --- a/src/openvpn/openvpn.c +++ b/src/openvpn/openvpn.c @@ -105,6 +105,33 @@ tunnel_point_to_point(struct context *c) #undef PROCESS_SIGNAL_P2P +void init_early(struct context *c) +{ + net_ctx_init(c, &c->net_ctx); + + /* init verbosity and mute levels */ + init_verb_mute(c, IVM_LEVEL_1); + + /* Initialise OpenSSL provider, this needs to be initialised this + * early since option post-processing and also openssl info + * printing depends on it */ + for (int j=1; j < MAX_PARMS && c->options.providers.names[j]; j++) + { + c->options.providers.providers[j] = + crypto_load_provider(c->options.providers.names[j]); + } +} + +static void uninit_early(struct context *c) +{ + net_ctx_free(&c->net_ctx); + for (int j=1; j < MAX_PARMS && c->options.providers.providers[j]; j++) + { + crypto_unload_provider(c->options.providers.names[j], + c->options.providers.providers[j]); + } + net_ctx_free(&c->net_ctx); +} /**************************************************************************/ /** @@ -193,10 +220,9 @@ openvpn_main(int argc, char *argv[]) open_plugins(&c, true, OPENVPN_PLUGIN_INIT_PRE_CONFIG_PARSE); #endif - net_ctx_init(&c, &c.net_ctx); - - /* init verbosity and mute levels */ - init_verb_mute(&c, IVM_LEVEL_1); + /* Early initialisation that need to happen before option + * post processing and other early startup but after parsing */ + init_early(&c); /* set dev options */ init_options_dev(&c.options); @@ -308,7 +334,7 @@ openvpn_main(int argc, char *argv[]) env_set_destroy(c.es); uninit_options(&c.options); gc_reset(&c.gc); - net_ctx_free(&c.net_ctx); + uninit_early(&c); } while (c.sig->signal_received == SIGHUP); } diff --git a/src/openvpn/openvpn.vcxproj b/src/openvpn/openvpn.vcxproj index 055f8ff5a80..d2cbaa8c834 100644 --- a/src/openvpn/openvpn.vcxproj +++ b/src/openvpn/openvpn.vcxproj @@ -124,34 +124,45 @@ true arm64-windows-ovpn + --overlay-triplets=$(SolutionDir)contrib\vcpkg-triplets --overlay-ports=$(SolutionDir)contrib\vcpkg-ports true arm64-windows-ovpn + --overlay-triplets=$(SolutionDir)contrib\vcpkg-triplets --overlay-ports=$(SolutionDir)contrib\vcpkg-ports true x86-windows-ovpn + --overlay-triplets=$(SolutionDir)contrib\vcpkg-triplets --overlay-ports=$(SolutionDir)contrib\vcpkg-ports true x86-windows-ovpn + --overlay-triplets=$(SolutionDir)contrib\vcpkg-triplets --overlay-ports=$(SolutionDir)contrib\vcpkg-ports true x64-windows-ovpn + --overlay-triplets=$(SolutionDir)contrib\vcpkg-triplets --overlay-ports=$(SolutionDir)contrib\vcpkg-ports true x64-windows-ovpn + --overlay-triplets=$(SolutionDir)contrib\vcpkg-triplets --overlay-ports=$(SolutionDir)contrib\vcpkg-ports + + + true - _CONSOLE;%(PreprocessorDefinitions) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;_CONSOLE;%(PreprocessorDefinitions) %(UndefinePreprocessorDefinitions) - Level2 true ..\compat;%(AdditionalIncludeDirectories) + Level2 + /ZH:SHA_256 %(AdditionalOptions) + true @@ -162,11 +173,13 @@ - _CONSOLE;%(PreprocessorDefinitions) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;_CONSOLE;%(PreprocessorDefinitions) %(UndefinePreprocessorDefinitions) - Level2 true ..\compat;%(AdditionalIncludeDirectories) + Level2 + /ZH:SHA_256 %(AdditionalOptions) + true @@ -177,11 +190,13 @@ - _CONSOLE;%(PreprocessorDefinitions) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;_CONSOLE;%(PreprocessorDefinitions) %(UndefinePreprocessorDefinitions) - Level2 true ..\compat;%(AdditionalIncludeDirectories) + Level2 + /ZH:SHA_256 %(AdditionalOptions) + true @@ -192,45 +207,53 @@ - _CONSOLE;%(PreprocessorDefinitions) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;_CONSOLE;%(PreprocessorDefinitions) %(UndefinePreprocessorDefinitions) - Level2 true ..\compat;%(AdditionalIncludeDirectories) Guard MultiThreaded + Level2 + /ZH:SHA_256 %(AdditionalOptions) + true Ncrypt.lib;gdi32.lib;ws2_32.lib;wininet.lib;crypt32.lib;iphlpapi.lib;winmm.lib;Fwpuclnt.lib;Rpcrt4.lib;setupapi.lib;Advapi32.lib $(OPENSSL_HOME)/lib;$(LZO_HOME)/lib;$(PKCS11H_HOME)/lib;%(AdditionalLibraryDirectories) Console + true - _CONSOLE;%(PreprocessorDefinitions) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;_CONSOLE;%(PreprocessorDefinitions) %(UndefinePreprocessorDefinitions) - Level2 true ..\compat;%(AdditionalIncludeDirectories) Guard + true + Level2 + /ZH:SHA_256 %(AdditionalOptions) Ncrypt.lib;gdi32.lib;ws2_32.lib;wininet.lib;crypt32.lib;iphlpapi.lib;winmm.lib;Fwpuclnt.lib;Rpcrt4.lib;setupapi.lib;Advapi32.lib $(OPENSSL_HOME)/lib;$(LZO_HOME)/lib;$(PKCS11H_HOME)/lib;%(AdditionalLibraryDirectories) Console + true - _CONSOLE;%(PreprocessorDefinitions) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;_CONSOLE;%(PreprocessorDefinitions) %(UndefinePreprocessorDefinitions) - Level2 true ..\compat;%(AdditionalIncludeDirectories) Guard + Level2 + /ZH:SHA_256 %(AdditionalOptions) + true diff --git a/src/openvpn/options.c b/src/openvpn/options.c index e0b273bdd43..2ddf30d8ce3 100644 --- a/src/openvpn/options.c +++ b/src/openvpn/options.c @@ -198,7 +198,7 @@ static const char usage_message[] = " is established. Multiple routes can be specified.\n" " netmask default: 255.255.255.255\n" " gateway default: taken from --route-gateway or --ifconfig\n" - " Specify default by leaving blank or setting to \"nil\".\n" + " Specify default by leaving blank or setting to \"default\".\n" "--route-ipv6 network/bits [gateway] [metric] :\n" " Add IPv6 route to routing table after connection\n" " is established. Multiple routes can be specified.\n" @@ -602,6 +602,7 @@ static const char usage_message[] = " : Use --show-tls to see a list of supported TLS ciphers (suites).\n" "--tls-cert-profile p : Set the allowed certificate crypto algorithm profile\n" " (default=legacy).\n" + "--providers l : A list l of OpenSSL providers to load.\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" @@ -1134,7 +1135,7 @@ parse_hash_fingerprint(const char *str, int nbytes, int msglevel, struct gc_aren #ifndef ENABLE_SMALL static void -show_dhcp_option_list(const char *name, const char * const*array, int len) +show_dhcp_option_list(const char *name, const char *const *array, int len) { int i; for (i = 0; i < len; ++i) @@ -2287,7 +2288,7 @@ options_postprocess_verify_ce(const struct options *options, if (options->mode == MODE_SERVER) { #define USAGE_VALID_SERVER_PROTOS "--mode server currently only supports " \ - "--proto values of udp, tcp-server, tcp4-server, or tcp6-server" + "--proto values of udp, tcp-server, tcp4-server, or tcp6-server" #ifdef TARGET_ANDROID msg(M_FATAL, "--mode server not supported on Android"); #endif @@ -3102,7 +3103,7 @@ options_postprocess_cipher(struct options *o) if (!o->ncp_enabled) { msg(M_USAGE, "--ncp-disable needs an explicit --cipher or " - "--data-ciphers-fallback config option"); + "--data-ciphers-fallback config option"); } msg(M_WARN, "--cipher is not set. Previous OpenVPN version defaulted to " @@ -3680,9 +3681,30 @@ calc_options_string_link_mtu(const struct options *o, const struct frame *frame) { struct frame fake_frame = *frame; struct key_type fake_kt; - init_key_type(&fake_kt, o->ciphername, o->authname, o->keysize, true, - false); + frame_remove_from_extra_frame(&fake_frame, crypto_max_overhead()); + + + /* o->ciphername might be BF-CBC even though the underlying SSL library + * does not support it. For this reason we workaround this corner case + * by pretending to have no encryption enabled and by manually adding + * the required packet overhead to the MTU computation. + */ + const char *ciphername = o->ciphername; + + if (strcmp(o->ciphername, "BF-CBC") == 0) + { + /* none has no overhead, so use this to later add only --auth + * overhead */ + + /* overhead of BF-CBC: 64 bit block size, 64 bit IV size */ + frame_add_to_extra_frame(&fake_frame, 64/8 + 64/8); + ciphername = "none"; + } + + init_key_type(&fake_kt, ciphername, o->authname, o->keysize, true, + false); + crypto_adjust_frame_parameters(&fake_frame, &fake_kt, o->replay, cipher_kt_mode_ofb_cfb(fake_kt.cipher)); frame_finalize(&fake_frame, o->ce.link_mtu_defined, o->ce.link_mtu, @@ -3852,18 +3874,33 @@ options_string(const struct options *o, + (TLS_SERVER == true) <= 1); - init_key_type(&kt, o->ciphername, o->authname, o->keysize, true, - false); + /* Skip resolving BF-CBC to allow SSL libraries without BF-CBC + * to work here in the default configuration */ + const char *ciphername = o->ciphername; + int keysize; + + if (strcmp(o->ciphername, "BF-CBC") == 0) + { + init_key_type(&kt, "none", o->authname, o->keysize, true, + false); + keysize = 128; + } + else + { + init_key_type(&kt, o->ciphername, o->authname, o->keysize, true, + false); + ciphername = cipher_kt_name(kt.cipher); + keysize = kt.cipher_length * 8; + } /* Only announce the cipher to our peer if we are willing to * support it */ - const char *ciphername = cipher_kt_name(kt.cipher); if (p2p_nopull || !o->ncp_enabled || tls_item_in_cipher_list(ciphername, o->ncp_ciphers)) { buf_printf(&out, ",cipher %s", ciphername); } buf_printf(&out, ",auth %s", md_kt_name(kt.digest)); - buf_printf(&out, ",keysize %d", kt.cipher_length * 8); + buf_printf(&out, ",keysize %d", keysize); if (o->shared_secret_file) { buf_printf(&out, ",secret"); @@ -4889,8 +4926,6 @@ parse_argv(struct options *options, unsigned int *option_types_found, struct env_set *es) { - int i, j; - /* usage message */ if (argc <= 1) { @@ -4900,7 +4935,7 @@ parse_argv(struct options *options, /* config filename specified only? */ if (argc == 2 && strncmp(argv[1], "--", 2)) { - char *p[MAX_PARMS]; + char *p[MAX_PARMS+1]; CLEAR(p); p[0] = "config"; p[1] = argv[1]; @@ -4910,9 +4945,9 @@ parse_argv(struct options *options, else { /* parse command line */ - for (i = 1; i < argc; ++i) + for (int i = 1; i < argc; ++i) { - char *p[MAX_PARMS]; + char *p[MAX_PARMS+1]; CLEAR(p); p[0] = argv[i]; if (strncmp(p[0], "--", 2)) @@ -4924,6 +4959,7 @@ parse_argv(struct options *options, p[0] += 2; } + int j; for (j = 1; j < MAX_PARMS; ++j) { if (i + j < argc) @@ -4964,6 +5000,12 @@ apply_pull_filter(const struct options *o, char *line) return true; } + /* skip leading spaces matching the behaviour of parse_line */ + while (isspace(*line)) + { + line++; + } + for (f = o->pull_filter_list->head; f; f = f->next) { if (f->type == PUF_TYPE_ACCEPT && strncmp(line, f->pattern, f->size) == 0) @@ -6167,9 +6209,9 @@ add_option(struct options *options, } } #ifdef TARGET_LINUX - else if (streq (p[0], "bind-dev") && p[1]) + else if (streq(p[0], "bind-dev") && p[1]) { - VERIFY_PERMISSION (OPT_P_SOCKFLAGS); + VERIFY_PERMISSION(OPT_P_SOCKFLAGS); options->bind_dev = p[1]; } #endif @@ -6247,7 +6289,7 @@ add_option(struct options *options, { int64_t val = atoll(p[2]); options->inactivity_minimum_bytes = (val < 0) ? 0 : val; - if ( options->inactivity_minimum_bytes > INT_MAX ) + if (options->inactivity_minimum_bytes > INT_MAX) { msg(M_WARN, "WARNING: '--inactive' with a 'bytes' value" " >2 Gbyte was silently ignored in older versions. If " @@ -8129,6 +8171,13 @@ add_option(struct options *options, options->keysize = keysize; } #endif + else if (streq(p[0], "providers") && p[1]) + { + for (size_t j = 1; j < MAX_PARMS && p[j] != NULL; j++) + { + options->providers.names[j] = p[j]; + } + } #ifdef ENABLE_PREDICTION_RESISTANCE else if (streq(p[0], "use-prediction-resistance") && !p[1]) { diff --git a/src/openvpn/options.h b/src/openvpn/options.h index 251660fdc9c..37220904265 100644 --- a/src/openvpn/options.h +++ b/src/openvpn/options.h @@ -176,6 +176,14 @@ struct remote_list struct remote_entry *array[CONNECTION_LIST_SIZE]; }; +struct provider_list +{ + /* Names of the providers */ + const char *names[MAX_PARMS]; + /* Pointers to the loaded providers to unload them */ + provider_t *providers[MAX_PARMS]; +}; + enum vlan_acceptable_frames { VLAN_ONLY_TAGGED, @@ -519,6 +527,7 @@ struct options const char *prng_hash; int prng_nonce_secret_len; const char *engine; + struct provider_list providers; bool replay; bool mute_replay_warnings; int replay_window; diff --git a/src/openvpn/platform.c b/src/openvpn/platform.c index 2604c27bdfa..4921f035613 100644 --- a/src/openvpn/platform.c +++ b/src/openvpn/platform.c @@ -471,7 +471,7 @@ platform_test_file(const char *filename) } else { - if (openvpn_errno() == EACCES) + if (errno == EACCES) { msg( M_WARN | M_ERRNO, "Could not access file '%s'", filename); } diff --git a/src/openvpn/push.c b/src/openvpn/push.c index fab1d5f43be..43db19121b5 100644 --- a/src/openvpn/push.c +++ b/src/openvpn/push.c @@ -225,7 +225,6 @@ receive_cr_response(struct context *c, const struct buffer *buffer) struct env_set *es = session->opt->es; int key_id = session->key[KS_PRIMARY].key_id; - management_notify_client_cr_response(key_id, mda, es, m); #endif msg(D_PUSH, "CR response was sent by client ('%s')", m); @@ -537,7 +536,7 @@ send_push_reply_auth_token(struct tls_multi *multi) /* Construct a mimimal control channel push reply message */ struct buffer buf = alloc_buf_gc(PUSH_BUNDLE_SIZE, &gc); - buf_printf(&buf, "%s, %s", push_reply_cmd, e->option); + buf_printf(&buf, "%s,%s", push_reply_cmd, e->option); send_control_channel_string_dowork(multi, BSTR(&buf), D_PUSH); gc_free(&gc); } @@ -780,8 +779,10 @@ push_update_digest(md_ctx_t *ctx, struct buffer *buf, const struct options *opt) char line[OPTION_PARM_SIZE]; while (buf_parse(buf, ',', line, sizeof(line))) { - /* peer-id might change on restart and this should not trigger reopening tun */ - if (strprefix(line, "peer-id ")) + /* peer-id and auth-token might change on restart and this should not trigger reopening tun */ + if (strprefix(line, "peer-id ") + || strprefix(line, "auth-token ") + || strprefix(line, "auth-token-user ")) { continue; } @@ -892,13 +893,13 @@ remove_iroutes_from_push_route_list(struct options *o) /* cycle through the push list */ while (e) { - char *p[MAX_PARMS]; + char *p[MAX_PARMS+1]; bool enable = true; /* parse the push item */ CLEAR(p); if (e->enable - && parse_line(e->option, p, SIZE(p), "[PUSH_ROUTE_REMOVE]", 1, D_ROUTE_DEBUG, &gc)) + && parse_line(e->option, p, SIZE(p)-1, "[PUSH_ROUTE_REMOVE]", 1, D_ROUTE_DEBUG, &gc)) { /* is the push item a route directive? */ if (p[0] && !strcmp(p[0], "route") && !p[3]) diff --git a/src/openvpn/ssl.c b/src/openvpn/ssl.c index 841a649abd9..f95b0014a76 100644 --- a/src/openvpn/ssl.c +++ b/src/openvpn/ssl.c @@ -393,9 +393,14 @@ static char *auth_challenge; /* GLOBAL */ #endif void -auth_user_pass_setup(const char *auth_file, const struct static_challenge_info *sci) +enable_auth_user_pass() { auth_user_pass_enabled = true; +} + +void +auth_user_pass_setup(const char *auth_file, const struct static_challenge_info *sci) +{ if (!auth_user_pass.defined && !auth_token.defined) { #ifdef ENABLE_MANAGEMENT @@ -2386,20 +2391,13 @@ key_method_2_write(struct buffer *buf, struct tls_multi *multi, { goto error; } - /* if auth-nocache was specified, the auth_user_pass object reaches - * a "complete" state only after having received the push-reply - * message. The push message might contain an auth-token that needs - * the username of auth_user_pass. - * - * For this reason, skip the purge operation here if no push-reply - * message has been received yet. - * - * This normally happens upon first negotiation only. - */ - if (!session->opt->pull) + /* save username for auth-token which may get pushed later */ + if (session->opt->pull && up != &auth_token) { - purge_user_pass(&auth_user_pass, false); + strncpynt(auth_token.username, up->username, USER_PASS_LEN); } + /* respect auth-nocache */ + purge_user_pass(&auth_user_pass, false); } else { @@ -4138,9 +4136,3 @@ protocol_dump(struct buffer *buffer, unsigned int flags, struct gc_arena *gc) done: return BSTR(&out); } - -void -ssl_clean_user_pass(void) -{ - purge_user_pass(&auth_user_pass, false); -} diff --git a/src/openvpn/ssl.h b/src/openvpn/ssl.h index 4fe8004a03d..1dcfe253520 100644 --- a/src/openvpn/ssl.h +++ b/src/openvpn/ssl.h @@ -419,6 +419,9 @@ void tls_post_encrypt(struct tls_multi *multi, struct buffer *buf); */ void pem_password_setup(const char *auth_file); +/* Enables the use of user/password authentication */ +void enable_auth_user_pass(); + /* * Setup authentication username and password. If auth_file is given, use the * credentials stored in the file. @@ -433,6 +436,7 @@ void ssl_set_auth_nocache(void); /* * Purge any stored authentication information, both for key files and tunnel * authentication. If PCKS #11 is enabled, purge authentication for that too. + * Note that auth_token is not cleared. */ void ssl_purge_auth(const bool auth_user_pass_only); @@ -600,12 +604,6 @@ void extract_x509_field_test(void); */ bool is_hard_reset_method2(int op); -/** - * Cleans the saved user/password unless auth-nocache is in use. - */ -void ssl_clean_user_pass(void); - - /* * Show the TLS ciphers that are available for us to use in the SSL * library with headers hinting their usage and warnings about usage. diff --git a/src/openvpn/ssl_mbedtls.c b/src/openvpn/ssl_mbedtls.c index 4a64e6d3385..9958099ceaf 100644 --- a/src/openvpn/ssl_mbedtls.c +++ b/src/openvpn/ssl_mbedtls.c @@ -168,7 +168,13 @@ tls_ctx_free(struct tls_root_ctx *ctx) } #if defined(ENABLE_PKCS11) - pkcs11h_certificate_freeCertificate(ctx->pkcs11_cert); + /* ...freeCertificate() can handle NULL ptrs, but if pkcs11 helper + * has not been initialized, it will ASSERT() - so, do not pass NULL + */ + if (ctx->pkcs11_cert) + { + pkcs11h_certificate_freeCertificate(ctx->pkcs11_cert); + } #endif if (ctx->allowed_ciphers) @@ -330,7 +336,8 @@ 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")) + if (!profile || 0 == strcmp(profile, "legacy") + || 0 == strcmp(profile, "insecure")) { ctx->cert_profile = openvpn_x509_crt_profile_legacy; } diff --git a/src/openvpn/ssl_ncp.c b/src/openvpn/ssl_ncp.c index b94c786ee55..4ab39a53903 100644 --- a/src/openvpn/ssl_ncp.c +++ b/src/openvpn/ssl_ncp.c @@ -108,7 +108,18 @@ mutate_ncp_cipher_list(const char *list, struct gc_arena *gc) * (and translate_cipher_name_from_openvpn/ * translate_cipher_name_to_openvpn) also normalises the cipher name, * e.g. replacing AeS-128-gCm with AES-128-GCM + * + * ciphers that have ? in front of them are considered optional and + * OpenVPN will only warn if they are not found (and remove them from + * the list) */ + + bool optional = false; + if (token[0] == '?') + { + token++; + optional = true; + } const cipher_kt_t *ktc = cipher_kt_get(token); if (strcmp(token, "none") == 0) { @@ -120,8 +131,9 @@ mutate_ncp_cipher_list(const char *list, struct gc_arena *gc) } if (!ktc && strcmp(token, "none") != 0) { - msg(M_WARN, "Unsupported cipher in --data-ciphers: %s", token); - error_found = true; + const char* optstr = optional ? "optional ": ""; + msg(M_WARN, "Unsupported %scipher in --data-ciphers: %s", optstr, token); + error_found = error_found || !optional; } else { diff --git a/src/openvpn/ssl_openssl.c b/src/openvpn/ssl_openssl.c index 595057d63db..e0360f75b96 100644 --- a/src/openvpn/ssl_openssl.c +++ b/src/openvpn/ssl_openssl.c @@ -551,6 +551,10 @@ tls_ctx_set_cert_profile(struct tls_root_ctx *ctx, const char *profile) { SSL_CTX_set_security_level(ctx->ctx, 1); } + else if (0 == strcmp(profile, "insecure")) + { + SSL_CTX_set_security_level(ctx->ctx, 0); + } else if (0 == strcmp(profile, "preferred")) { SSL_CTX_set_security_level(ctx->ctx, 2); @@ -821,6 +825,8 @@ tls_ctx_load_pkcs12(struct tls_root_ctx *ctx, const char *pkcs12_file, ca = NULL; if (!PKCS12_parse(p12, password, &pkey, &cert, &ca)) { + crypto_msg(M_WARN, "Decoding PKCS12 failed. Probably wrong password " + "or unsupported/legacy encryption"); #ifdef ENABLE_MANAGEMENT if (management && (ERR_GET_REASON(ERR_peek_error()) == PKCS12_R_MAC_VERIFY_FAILURE)) { diff --git a/src/openvpn/ssl_verify.c b/src/openvpn/ssl_verify.c index 7f977c0d1a7..efa2f436ad9 100644 --- a/src/openvpn/ssl_verify.c +++ b/src/openvpn/ssl_verify.c @@ -1397,7 +1397,14 @@ verify_user_pass(struct user_pass *up, struct tls_multi *multi, #ifdef MANAGEMENT_DEF_AUTH if (man_def_auth != KMDA_UNDEF) { - ks->authenticated = KS_AUTH_DEFERRED; + if (skip_auth) + { + ks->mda_status = ACF_DISABLED; + } + else + { + ks->authenticated = KS_AUTH_DEFERRED; + } } #endif if ((session->opt->ssl_flags & SSLF_USERNAME_AS_COMMON_NAME)) diff --git a/src/openvpn/tls_crypt.c b/src/openvpn/tls_crypt.c index 663f5e169a5..f2a97462d55 100644 --- a/src/openvpn/tls_crypt.c +++ b/src/openvpn/tls_crypt.c @@ -585,7 +585,8 @@ tls_crypt_v2_extract_client_key(struct buffer *buf, if (BLEN(&wrapped_client_key) < sizeof(net_len)) { - msg(D_TLS_ERRORS, "failed to read length"); + msg(D_TLS_ERRORS, "Can not read tls-crypt-v2 client key length"); + return false; } memcpy(&net_len, BEND(&wrapped_client_key) - sizeof(net_len), sizeof(net_len)); diff --git a/src/openvpn/tun.h b/src/openvpn/tun.h index ea19620d5af..ae98966bf96 100644 --- a/src/openvpn/tun.h +++ b/src/openvpn/tun.h @@ -461,7 +461,7 @@ tuntap_stop(int status) */ if (status < 0) { - return openvpn_errno() == ERROR_FILE_NOT_FOUND; + return GetLastError() == ERROR_FILE_NOT_FOUND; } return false; } @@ -474,7 +474,7 @@ tuntap_abort(int status) */ if (status < 0) { - return openvpn_errno() == ERROR_OPERATION_ABORTED; + return GetLastError() == ERROR_OPERATION_ABORTED; } return false; } diff --git a/src/openvpn/vcpkg.json b/src/openvpn/vcpkg.json new file mode 100644 index 00000000000..6537fdd6cf4 --- /dev/null +++ b/src/openvpn/vcpkg.json @@ -0,0 +1,19 @@ +{ + "$schema": "https://raw.githubusercontent.com/microsoft/vcpkg/master/scripts/vcpkg.schema.json", + "name": "openvpn", + "version": "2.5", + "dependencies": [ + "openssl", + "tap-windows6", + "lzo", + "lz4", + "pkcs11-helper" + ], + "builtin-baseline": "4b766c1cd17205e1b768c4fadfd5f867c1d0510e", + "overrides": [ + { + "name": "openssl", + "version-string": "1.1.1n" + } + ] +} diff --git a/src/openvpnmsica/openvpnmsica.vcxproj b/src/openvpnmsica/openvpnmsica.vcxproj index 11aa78bb006..3a9f0c97003 100644 --- a/src/openvpnmsica/openvpnmsica.vcxproj +++ b/src/openvpnmsica/openvpnmsica.vcxproj @@ -135,6 +135,54 @@ true + + + true + + + /ZH:SHA_256 %(AdditionalOptions) + %(PreprocessorDefinitions) + true + + + + + true + + + /ZH:SHA_256 %(AdditionalOptions) + true + %(PreprocessorDefinitions) + + + + + /ZH:SHA_256 %(AdditionalOptions) + %(PreprocessorDefinitions) + true + + + + + /ZH:SHA_256 %(AdditionalOptions) + %(PreprocessorDefinitions) + true + + + + + /ZH:SHA_256 %(AdditionalOptions) + %(PreprocessorDefinitions) + true + + + + + /ZH:SHA_256 %(AdditionalOptions) + %(PreprocessorDefinitions) + true + + diff --git a/src/openvpnserv/openvpnserv.vcxproj b/src/openvpnserv/openvpnserv.vcxproj index c9e935d8791..f4576b67805 100644 --- a/src/openvpnserv/openvpnserv.vcxproj +++ b/src/openvpnserv/openvpnserv.vcxproj @@ -124,7 +124,9 @@ ..\openvpn;..\compat;%(AdditionalIncludeDirectories) - _CONSOLE;%(PreprocessorDefinitions) + _CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;_CONSOLE;%(PreprocessorDefinitions) + true + /ZH:SHA_256 %(AdditionalOptions) @@ -135,7 +137,9 @@ ..\openvpn;..\compat;%(AdditionalIncludeDirectories) - _CONSOLE;%(PreprocessorDefinitions) + _CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;_CONSOLE;%(PreprocessorDefinitions) + true + /ZH:SHA_256 %(AdditionalOptions) @@ -146,7 +150,9 @@ ..\openvpn;..\compat;%(AdditionalIncludeDirectories) - _CONSOLE;%(PreprocessorDefinitions) + _CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;_CONSOLE;%(PreprocessorDefinitions) + true + /ZH:SHA_256 %(AdditionalOptions) @@ -157,30 +163,38 @@ ..\openvpn;..\compat;%(AdditionalIncludeDirectories) - _CONSOLE;%(PreprocessorDefinitions) - MultiThreaded + _CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;_CONSOLE;%(PreprocessorDefinitions) + MultiThreaded + true + /ZH:SHA_256 %(AdditionalOptions) Userenv.lib;Iphlpapi.lib;ntdll.lib;Fwpuclnt.lib;Netapi32.lib;Shlwapi.lib;%(AdditionalDependencies) Console + true ..\openvpn;..\compat;%(AdditionalIncludeDirectories) - _CONSOLE;%(PreprocessorDefinitions) + _CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;_CONSOLE;%(PreprocessorDefinitions) + true + /ZH:SHA_256 %(AdditionalOptions) legacy_stdio_definitions.lib;Userenv.lib;Iphlpapi.lib;ntdll.lib;Fwpuclnt.lib;Netapi32.lib;Shlwapi.lib;%(AdditionalDependencies) Console + true ..\openvpn;..\compat;%(AdditionalIncludeDirectories) - _CONSOLE;%(PreprocessorDefinitions) + _CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;_CONSOLE;%(PreprocessorDefinitions) + true + /ZH:SHA_256 %(AdditionalOptions) diff --git a/src/plugins/auth-pam/auth-pam.c b/src/plugins/auth-pam/auth-pam.c index 3a3a24096c3..c5e55d8acd4 100644 --- a/src/plugins/auth-pam/auth-pam.c +++ b/src/plugins/auth-pam/auth-pam.c @@ -47,6 +47,7 @@ #include #include #include +#include #include "utils.h" #include diff --git a/src/tapctl/tap.c b/src/tapctl/tap.c index e399a38a3a4..c9795bce1d6 100644 --- a/src/tapctl/tap.c +++ b/src/tapctl/tap.c @@ -73,14 +73,15 @@ find_function(const WCHAR *libname, const char *funcname, HMODULE *m) return NULL; } - size_t len = _countof(libpath) - wcslen(libpath) - 1; - if (len < wcslen(libname) + 1) + /* +1 for the path seperator '\' */ + const size_t path_length = wcslen(libpath) + 1 + wcslen(libname); + if (path_length >= _countof(libpath)) { SetLastError(ERROR_INSUFFICIENT_BUFFER); return NULL; } - wcsncat(libpath, L"\\", len); - wcsncat(libpath, libname, len-1); + wcscat_s(libpath, _countof(libpath), L"\\"); + wcscat_s(libpath, _countof(libpath), libname); *m = LoadLibraryW(libpath); if (*m == NULL) diff --git a/src/tapctl/tapctl.vcxproj b/src/tapctl/tapctl.vcxproj index 533278fe0d3..684fb80ade4 100644 --- a/src/tapctl/tapctl.vcxproj +++ b/src/tapctl/tapctl.vcxproj @@ -135,6 +135,7 @@ true +<<<<<<< HEAD @@ -145,6 +146,57 @@ +======= + + + true + /ZH:SHA_256 %(AdditionalOptions) + %(PreprocessorDefinitions) + + + + + true + /ZH:SHA_256 %(AdditionalOptions) + %(PreprocessorDefinitions) + + + + + true + /ZH:SHA_256 %(AdditionalOptions) + %(PreprocessorDefinitions) + + + + + MultiThreaded + true + /ZH:SHA_256 %(AdditionalOptions) + %(PreprocessorDefinitions) + + + true + + + + + true + /ZH:SHA_256 %(AdditionalOptions) + %(PreprocessorDefinitions) + + + + + true + + + true + /ZH:SHA_256 %(AdditionalOptions) + %(PreprocessorDefinitions) + + +>>>>>>> 3d9b4ce394f9d1a66842a5391aa744f7310a48a6 diff --git a/tests/t_client.sh.in b/tests/t_client.sh.in index 294546be580..76ac9b2277e 100755 --- a/tests/t_client.sh.in +++ b/tests/t_client.sh.in @@ -9,9 +9,13 @@ # - writable current directory to create subdir for logs # - t_client.rc in current directory OR source dir that specifies tests # - for "ping4" checks: fping binary in $PATH -# - for "ping6" checks: fping6 binary in $PATH +# - for "ping6" checks: fping (4.0+) or fping6 binary in $PATH # +# by changing this to 1 we can force automated builds to fail +# that are expected to have all the prerequisites +TCLIENT_SKIP_RC="${TCLIENT_SKIP_RC:-77}" + srcdir="${srcdir:-.}" top_builddir="${top_builddir:-..}" if [ -r "${top_builddir}"/t_client.rc ] ; then @@ -21,25 +25,28 @@ elif [ -r "${srcdir}"/t_client.rc ] ; then else echo "$0: cannot find 't_client.rc' in build dir ('${top_builddir}')" >&2 echo "$0: or source directory ('${srcdir}'). SKIPPING TEST." >&2 - exit 77 + exit "${TCLIENT_SKIP_RC}" fi # Check for external dependencies +FPING="fping" +FPING6="fping6" which fping > /dev/null if [ $? -ne 0 ]; then echo "$0: fping is not available in \$PATH" >&2 - exit 77 + exit "${TCLIENT_SKIP_RC}" fi which fping6 > /dev/null if [ $? -ne 0 ]; then - echo "$0: fping6 is not available in \$PATH" >&2 - exit 77 + echo "$0: fping6 is not available in \$PATH, assuming fping 4.0 or later" >&2 + FPING="fping -4" + FPING6="fping -6" fi KILL_EXEC=`which kill` if [ $? -ne 0 ]; then echo "$0: kill not found in \$PATH" >&2 - exit 77 + exit "${TCLIENT_SKIP_RC}" fi if [ ! -x "${top_builddir}/src/openvpn/openvpn" ] @@ -56,12 +63,12 @@ fi if [ -z "$CA_CERT" ] ; then echo "CA_CERT not defined in 't_client.rc'. SKIP test." >&2 - exit 77 + exit "${TCLIENT_SKIP_RC}" fi if [ -z "$TEST_RUN_LIST" ] ; then echo "TEST_RUN_LIST empty, no tests defined. SKIP test." >&2 - exit 77 + exit "${TCLIENT_SKIP_RC}" fi # Ensure PREFER_KSU is in a known state @@ -91,7 +98,7 @@ else then echo "$0: this test must run be as root, or RUN_SUDO=... " >&2 echo " must be set correctly in 't_client.rc'. SKIP." >&2 - exit 77 + exit "${TCLIENT_SKIP_RC}" else # We have to use sudo. Make sure that we (hopefully) do not have # to ask the users password during the test. This is done to @@ -101,7 +108,7 @@ else echo "$0: $RUN_SUDO $KILL_EXEC -0 succeeded, good." else echo "$0: $RUN_SUDO $KILL_EXEC -0 failed, cannot go on. SKIP." >&2 - exit 77 + exit "${TCLIENT_SKIP_RC}" fi fi fi @@ -216,8 +223,8 @@ run_ping_tests() if [ -z "$targetlist" ] ; then return ; fi case $proto in - 4) cmd=fping ;; - 6) cmd=fping6 ;; + 4) cmd="$FPING" ;; + 6) cmd="$FPING6" ;; *) echo "internal error in run_ping_tests arg 1: '$proto'" >&2 exit 1 ;; esac diff --git a/tests/t_net.sh b/tests/t_net.sh index f9dba40404f..af78152c7cd 100755 --- a/tests/t_net.sh +++ b/tests/t_net.sh @@ -166,6 +166,6 @@ for i in $(seq 0 $MAX_TEST); do done # remove interface for good -$RUN_SUDO $openvpn --dev $IFACE --dev-type tun --rmtun >/dev/null +$RUN_SUDO ip link del $IFACE exit 0 diff --git a/tests/unit_tests/openvpn/test_ncp.c b/tests/unit_tests/openvpn/test_ncp.c index e38a5738ee7..6e1e50a47cb 100644 --- a/tests/unit_tests/openvpn/test_ncp.c +++ b/tests/unit_tests/openvpn/test_ncp.c @@ -42,6 +42,7 @@ /* Defines for use in the tests and the mock parse_line() */ const char *bf_chacha = "BF-CBC:CHACHA20-POLY1305"; +const char *aes_chacha = "AES-128-CBC:CHACHA20-POLY1305"; const char *aes_ciphers = "AES-256-GCM:AES-128-GCM"; static void @@ -57,6 +58,11 @@ test_check_ncp_ciphers_list(void **state) assert_string_equal(mutate_ncp_cipher_list(aes_ciphers, &gc), aes_ciphers); + if (have_chacha) + { + assert_string_equal(mutate_ncp_cipher_list(aes_chacha, &gc), aes_chacha); + } + if (have_chacha && have_blowfish) { assert_string_equal(mutate_ncp_cipher_list(bf_chacha, &gc), bf_chacha); @@ -68,13 +74,27 @@ test_check_ncp_ciphers_list(void **state) assert_ptr_equal(mutate_ncp_cipher_list(bf_chacha, &gc), NULL); } + /* Check that optional ciphers work */ + assert_string_equal(mutate_ncp_cipher_list("AES-256-GCM:?vollbit:AES-128-GCM", &gc), + aes_ciphers); + + /* Check that optional ciphers work */ + assert_string_equal(mutate_ncp_cipher_list("?AES-256-GCM:?AES-128-GCM", &gc), + aes_ciphers); + + /* All unsupported should still yield an empty list */ + assert_ptr_equal(mutate_ncp_cipher_list("?kugelfisch:?grasshopper", &gc), NULL); + + /* If the last is optional, previous invalid ciphers should be ignored */ + assert_ptr_equal(mutate_ncp_cipher_list("Vollbit:Littlebit:AES-256-CBC:BF-CBC:?nixbit", &gc), NULL); + /* For testing that with OpenSSL 1.1.0+ that also accepts ciphers in * a different spelling the normalised cipher output is the same */ bool have_chacha_mixed_case = cipher_kt_get("ChaCha20-Poly1305"); if (have_chacha_mixed_case) { - assert_string_equal(mutate_ncp_cipher_list("BF-CBC:ChaCha20-Poly1305", &gc), - bf_chacha); + assert_string_equal(mutate_ncp_cipher_list("AES-128-CBC:ChaCha20-Poly1305", &gc), + aes_chacha); } assert_ptr_equal(mutate_ncp_cipher_list("vollbit", &gc), NULL); diff --git a/version.m4 b/version.m4 index 124a50aa2e0..53d1edf57d7 100644 --- a/version.m4 +++ b/version.m4 @@ -3,12 +3,12 @@ define([PRODUCT_NAME], [OpenVPN]) define([PRODUCT_TARNAME], [openvpn]) define([PRODUCT_VERSION_MAJOR], [2]) define([PRODUCT_VERSION_MINOR], [5]) -define([PRODUCT_VERSION_PATCH], [.6]) +define([PRODUCT_VERSION_PATCH], [.9]) 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,5,6,0]) +define([PRODUCT_VERSION_RESOURCE], [2,5,9,0]) dnl define the TAP version define([PRODUCT_TAP_WIN_COMPONENT_ID], [tap0901]) define([PRODUCT_TAP_WIN_MIN_MAJOR], [9])