diff --git a/Configuration/Framework.xcconfig b/Configuration/Framework.xcconfig index b72131d..7343136 100755 --- a/Configuration/Framework.xcconfig +++ b/Configuration/Framework.xcconfig @@ -12,5 +12,5 @@ LIBRARY_SEARCH_PATHS[sdk=iphonesimulator*] = "$(VENDORS_DIR)/lz4/lib/sim" "$(VEN LIBRARY_SEARCH_PATHS[sdk=iphoneos*] = "$(VENDORS_DIR)/lz4/lib/ios" "$(VENDORS_DIR)/mbedtls/lib/ios" LIBRARY_SEARCH_PATHS[sdk=macosx*] = "$(VENDORS_DIR)/lz4/lib/macos" "$(VENDORS_DIR)/mbedtls/lib/macos" OTHER_LDFLAGS = -lmbedtls -lmbedx509 -lmbedcrypto -llz4 -OTHER_CPLUSPLUSFLAGS = $(OTHER_CFLAGS) -DUSE_ASIO -DUSE_ASIO_THREADLOCAL -DASIO_STANDALONE -DASIO_NO_DEPRECATED -DHAVE_LZ4 -DUSE_MBEDTLS -DOPENVPN_FORCE_TUN_NULL -DUSE_TUN_BUILDER +OTHER_CPLUSPLUSFLAGS = $(OTHER_CFLAGS) -DUSE_ASIO -DUSE_ASIO_THREADLOCAL -DASIO_STANDALONE -DASIO_NO_DEPRECATED -DASIO_HAS_STD_STRING_VIEW -DHAVE_LZ4 -DUSE_MBEDTLS -DOPENVPN_FORCE_TUN_NULL -DUSE_TUN_BUILDER GCC_WARN_64_TO_32_BIT_CONVERSION = NO diff --git a/Sources/OpenVPNAdapter/Libraries/Vendors/asio/asio/include/asio/basic_socket.hpp b/Sources/OpenVPNAdapter/Libraries/Vendors/asio/asio/include/asio/basic_socket.hpp index 4343016..0d1b0d2 100644 --- a/Sources/OpenVPNAdapter/Libraries/Vendors/asio/asio/include/asio/basic_socket.hpp +++ b/Sources/OpenVPNAdapter/Libraries/Vendors/asio/asio/include/asio/basic_socket.hpp @@ -865,6 +865,8 @@ public: asio::error_code ec; const protocol_type protocol = peer_endpoint.protocol(); this->get_service().open(this->get_implementation(), protocol, ec); + if (!ec) + async_connect_post_open(protocol, ec); if (ec) { async_completionai_family == AF_INET6) + { + sockaddr_in6* a6 = (sockaddr_in6*)(*result)->ai_addr; + if (a6->sin6_scope_id && !(IN6_IS_ADDR_LINKLOCAL(&a6->sin6_addr) || IN6_IS_ADDR_MC_NODELOCAL(&a6->sin6_addr) || IN6_IS_ADDR_MC_LINKLOCAL(&a6->sin6_addr))) + a6->sin6_scope_id = 0; + } + return ec = translate_addrinfo_error(error); #else int error = ::getaddrinfo(host, service, &hints, result); diff --git a/Sources/OpenVPNAdapter/Libraries/Vendors/asio/asio/include/asio/ip/basic_resolver_results.hpp b/Sources/OpenVPNAdapter/Libraries/Vendors/asio/asio/include/asio/ip/basic_resolver_results.hpp index 4146a46..f0ae258 100644 --- a/Sources/OpenVPNAdapter/Libraries/Vendors/asio/asio/include/asio/ip/basic_resolver_results.hpp +++ b/Sources/OpenVPNAdapter/Libraries/Vendors/asio/asio/include/asio/ip/basic_resolver_results.hpp @@ -18,6 +18,7 @@ #include "asio/detail/config.hpp" #include #include +#include #include "asio/detail/socket_ops.hpp" #include "asio/detail/socket_types.hpp" #include "asio/ip/basic_resolver_iterator.hpp" @@ -299,6 +300,12 @@ public: return !a.equal(b); } + template + void randomize(Random& r) + { + std::shuffle(this->values_->begin(), this->values_->end(), r); + } + private: typedef std::vector > values_type; }; diff --git a/Sources/OpenVPNAdapter/Libraries/Vendors/openvpn/openvpn/client/async_resolve.hpp b/Sources/OpenVPNAdapter/Libraries/Vendors/openvpn/openvpn/client/async_resolve.hpp new file mode 100644 index 0000000..1ce03e4 --- /dev/null +++ b/Sources/OpenVPNAdapter/Libraries/Vendors/openvpn/openvpn/client/async_resolve.hpp @@ -0,0 +1,37 @@ +// OpenVPN -- An application to securely tunnel IP networks +// over a single port, with support for SSL/TLS-based +// session authentication and key exchange, +// packet encryption, packet authentication, and +// packet compression. +// +// Copyright (C) 2012-2019 OpenVPN Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License Version 3 +// 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program in the COPYING file. +// If not, see . + +#ifndef OPENVPN_CLIENT_ASYNC_RESOLVE_H +#define OPENVPN_CLIENT_ASYNC_RESOLVE_H + +#ifdef USE_ASIO +#include +#else +#include +#endif + +// create shortcuts for common templated classes +namespace openvpn { + typedef AsyncResolvable AsyncResolvableUDP; + typedef AsyncResolvable AsyncResolvableTCP; +} + +#endif /* OPENVPN_CLIENT_ASYNC_RESOLVE_H */ diff --git a/Sources/OpenVPNAdapter/Libraries/Vendors/openvpn/openvpn/client/async_resolve/asio.hpp b/Sources/OpenVPNAdapter/Libraries/Vendors/openvpn/openvpn/client/async_resolve/asio.hpp new file mode 100644 index 0000000..967ffb3 --- /dev/null +++ b/Sources/OpenVPNAdapter/Libraries/Vendors/openvpn/openvpn/client/async_resolve/asio.hpp @@ -0,0 +1,121 @@ +// OpenVPN -- An application to securely tunnel IP networks +// over a single port, with support for SSL/TLS-based +// session authentication and key exchange, +// packet encryption, packet authentication, and +// packet compression. +// +// Copyright (C) 2012-2019 OpenVPN Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License Version 3 +// 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program in the COPYING file. +// If not, see . + +#ifndef OPENVPN_CLIENT_ASYNC_RESOLVE_ASIO_H +#define OPENVPN_CLIENT_ASYNC_RESOLVE_ASIO_H + +#include +#include + +#include +#include +#include + + +namespace openvpn { + template + class AsyncResolvable: public virtual RC + { + private: + typedef RCPtr Ptr; + + openvpn_io::io_context& io_context; + + class ResolveThread : public RC + { + friend class AsyncResolvable; + + private: + typedef RCPtr Ptr; + + std::unique_ptr asio_work; + openvpn_io::io_context& io_context; + AsyncResolvable *resolvable; + + ResolveThread(openvpn_io::io_context &io_context_arg, + AsyncResolvable *resolvable_arg, + const std::string& host, const std::string& port) + : asio_work(new AsioWork(io_context_arg)), + io_context(io_context_arg), + resolvable(resolvable_arg) + { + std::thread resolve_thread([self=Ptr(this), host, port]() { + openvpn_io::io_context io_context(1); + openvpn_io::error_code error; + RESOLVER_TYPE resolver(io_context); + typename RESOLVER_TYPE::results_type results; + results = resolver.resolve(host, port, error); + + openvpn_io::post(self->io_context, [self, results, error]() { + OPENVPN_ASYNC_HANDLER; + self->resolvable->resolve_callback(error, results); + }); + + // the AsioWork can be released now that we have posted + // something else to the main io_context queue + self->asio_work.reset(); + }); + // detach the thread so that the client won't need to wait for + // it to join. + resolve_thread.detach(); + } + }; + + public: + AsyncResolvable(openvpn_io::io_context& io_context_arg) + : io_context(io_context_arg) + { + } + + virtual void resolve_callback(const openvpn_io::error_code& error, + typename RESOLVER_TYPE::results_type results) = 0; + + // mimic the asynchronous DNS resolution by performing a + // synchronous one in a detached thread. + // + // This strategy has the advantage of allowing the core to + // stop/exit without waiting for the getaddrinfo() (used + // internally) to terminate. + // Note: getaddrinfo() is non-interruptible by design. + // + // In other words, we are re-creating exactly what ASIO would + // normally do in case of async_resolve(), with the difference + // that here we have control over the resolving thread and we + // can easily detach it. Deatching the internal thread created + // by ASIO would not be feasible as it is not exposed. + void async_resolve_name(const std::string& host, const std::string& port) + { + // there might be nothing else in the main io_context queue + // right now, therefore we use AsioWork to prevent the loop + // from exiting while we perform the DNS resolution in the + // detached thread. + typename ResolveThread::Ptr t(new ResolveThread(io_context, this, host, port)); + } + + // The core assumes the existence of this method because it is used on + // other platforms (i.e. iOS), therefore we must declare it, even if no-op + void async_resolve_cancel() + { + } + }; +} + +#endif /* OPENVPN_CLIENT_ASYNC_RESOLVE_ASIO_H */ diff --git a/Sources/OpenVPNAdapter/Libraries/Vendors/openvpn/openvpn/client/async_resolve/generic.hpp b/Sources/OpenVPNAdapter/Libraries/Vendors/openvpn/openvpn/client/async_resolve/generic.hpp new file mode 100644 index 0000000..77274ee --- /dev/null +++ b/Sources/OpenVPNAdapter/Libraries/Vendors/openvpn/openvpn/client/async_resolve/generic.hpp @@ -0,0 +1,74 @@ +// OpenVPN -- An application to securely tunnel IP networks +// over a single port, with support for SSL/TLS-based +// session authentication and key exchange, +// packet encryption, packet authentication, and +// packet compression. +// +// Copyright (C) 2012-2019 OpenVPN Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License Version 3 +// 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program in the COPYING file. +// If not, see . + +#ifndef OPENVPN_CLIENT_ASYNC_RESOLVE_GENERIC_H +#define OPENVPN_CLIENT_ASYNC_RESOLVE_GENERIC_H + +#include +#include +#include + + +namespace openvpn { + template + class AsyncResolvable: public virtual RC + { + private: + typedef RCPtr Ptr; + + openvpn_io::io_context& io_context; + RESOLVER_TYPE resolver; + + public: + AsyncResolvable(openvpn_io::io_context& io_context_arg) + : io_context(io_context_arg), + resolver(io_context_arg) + { + } + + virtual void resolve_callback(const openvpn_io::error_code& error, + typename RESOLVER_TYPE::results_type results) = 0; + + // This implementation assumes that the i/o reactor provides an asynchronous + // DNS resolution routine using its own primitives and that doesn't require + // us to take care of any non-interruptible opration (i.e. getaddrinfo() in + // case of ASIO). + // + // For example, iOS implements aync_resolve using GCD and CFHost. This + // implementation satisfies the constraints mentioned above + void async_resolve_name(const std::string& host, const std::string& port) + { + resolver.async_resolve(host, port, [self=Ptr(this)](const openvpn_io::error_code& error, + typename RESOLVER_TYPE::results_type results) + { + OPENVPN_ASYNC_HANDLER; + self->resolve_callback(error, results); + }); + } + + void async_resolve_cancel() + { + resolver.cancel(); + } + }; +} + +#endif /* OPENVPN_CLIENT_ASYNC_RESOLVE_GENERIC_H */ diff --git a/Sources/OpenVPNAdapter/Libraries/Vendors/openvpn/openvpn/client/remotelist.hpp b/Sources/OpenVPNAdapter/Libraries/Vendors/openvpn/openvpn/client/remotelist.hpp index b6de7b5..83d07f0 100644 --- a/Sources/OpenVPNAdapter/Libraries/Vendors/openvpn/openvpn/client/remotelist.hpp +++ b/Sources/OpenVPNAdapter/Libraries/Vendors/openvpn/openvpn/client/remotelist.hpp @@ -31,10 +31,12 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -46,6 +48,7 @@ #include #include #include +#include #if OPENVPN_DEBUG_REMOTELIST >= 1 #define OPENVPN_LOG_REMOTELIST(x) OPENVPN_LOG(x) @@ -54,80 +57,6 @@ #endif namespace openvpn { - template - class AsyncResolvable: public virtual RC - { - private: - typedef RCPtr Ptr; - - openvpn_io::io_context& io_context; - std::unique_ptr asio_work; - - public: - AsyncResolvable(openvpn_io::io_context& io_context_arg) - : io_context(io_context_arg) - { - } - - virtual void resolve_callback(const openvpn_io::error_code& error, - typename RESOLVER_TYPE::results_type results) = 0; - - // mimic the asynchronous DNS resolution by performing a - // synchronous one in a detached thread. - // - // This strategy has the advantage of allowing the core to - // stop/exit without waiting for the getaddrinfo() (used - // internally) to terminate. - // Note: getaddrinfo() is non-interruptible by design. - // - // In other words, we are re-creating exactly what ASIO would - // normally do in case of async_resolve(), with the difference - // that here we have control over the resolving thread and we - // can easily detach it. Deatching the internal thread created - // by ASIO would not be feasible as it is not exposed. - void async_resolve_name(const std::string& host, const std::string& port) - { - // there might be nothing else in the main io_context queue - // right now, therefore we use AsioWork to prevent the loop - // from exiting while we perform the DNS resolution in the - // detached thread. - asio_work.reset(new AsioWork(io_context)); - - std::thread resolve_thread([self=Ptr(this), host, port]() { - openvpn_io::io_context io_context(1); - openvpn_io::error_code error; - RESOLVER_TYPE resolver(io_context); - typename RESOLVER_TYPE::results_type results; - results = resolver.resolve(host, port, error); - - openvpn_io::post(self->io_context, [self, results, error]() { - OPENVPN_ASYNC_HANDLER; - self->resolve_callback(error, results); - }); - - // the AsioWork can be released now that we have posted - // something else to the main io_context queue - self->asio_work.reset(); - }); - - // detach the thread so that the client won't need to wait for - // it to join. - resolve_thread.detach(); - } - - // to be called by the child class when the core wants to stop - // and we don't need to wait for the detached thread any longer. - // It simulates a resolve abort - void async_resolve_cancel() - { - asio_work.reset(); - } - }; - - typedef AsyncResolvable AsyncResolvableUDP; - typedef AsyncResolvable AsyncResolvableTCP; - - class RemoteList : public RC { // A single IP address that is part of a list of IP addresses diff --git a/Sources/OpenVPNAdapter/Libraries/Vendors/openvpn/openvpn/mbedtls/ssl/sslctx.hpp b/Sources/OpenVPNAdapter/Libraries/Vendors/openvpn/openvpn/mbedtls/ssl/sslctx.hpp index 6b277c5..8640981 100644 --- a/Sources/OpenVPNAdapter/Libraries/Vendors/openvpn/openvpn/mbedtls/ssl/sslctx.hpp +++ b/Sources/OpenVPNAdapter/Libraries/Vendors/openvpn/openvpn/mbedtls/ssl/sslctx.hpp @@ -36,6 +36,7 @@ #include #include #include +#include #include #include @@ -1224,11 +1225,20 @@ namespace openvpn { { const int SHA_DIGEST_LEN = 20; static_assert(sizeof(AuthCert::issuer_fp) == SHA_DIGEST_LEN, "size inconsistency"); +#if MBEDTLS_VERSION_NUMBER < 0x02070000 + // mbed TLS 2.7.0 and newer deprecates mbedtls_sha1() + // in favour of mbedtls_sha1_ret(). + + // We support for older mbed TLS versions + // to be able to build on Debian 9 and Ubuntu 16. + mbedtls_sha1(cert->raw.p, cert->raw.len, ssl->authcert->issuer_fp); +#else if(mbedtls_sha1_ret(cert->raw.p, cert->raw.len, ssl->authcert->issuer_fp)) { OPENVPN_LOG_SSL("VERIFY FAIL -- SHA1 calculation failed."); fail = true; } +#endif } } else if (depth == 0) // leaf-cert