mirror of
https://github.com/deneraraujo/OpenVPNAdapter.git
synced 2026-02-11 00:00:08 +08:00
Squashed 'Sources/OpenVPNAdapter/Libraries/Vendors/openvpn/' changes from cc90cde57..6608878d5
6608878d5 [OVPN3-341] implement mssfix support 1bf3fc0e4 win: update project files f8d209435 travis: update to default osx image: xcode9.4 31eb246a8 travis.yml: align deps version to lib-version 996f86635 RunContext: fixed rebase issue that added two "default: signal_rearm();" clauses aebea6456 build script: minor changes to Cityhash inclusion 1d754072c modstat: make update_file_mod_time_nanoseconds() a no-op on non-Linux 7974c9867 Fixed some breakage caused by recent endian/ffs commits a0dd7fe8b endian.hpp: break out endian compile-time tests to endian_platform.hpp c8bdf5a34 ffs.hpp: support additional numeric types dcb0c9452 BufferType: append() argument can now be a flexible buffer type 2009a8a25 Added AsioTimerSafe 39e71b7dd event_loop_wait_barrier: use a longer default timeout when running under valgrind 8b7e08e9b string::contains_non_space_ctrl: consider ASCII char 127 (DEL) to be a control char e43024d7c RunContext: rearm non-terminating signals 6ab379323 write_binary_atomic: remove temporary file on move failure 55dc653cd path: added is_contained() 02bf235c6 Reverted previous commit: "ReplyParser: added undefined status" 84dbc5b9b Allow test/cli.cpp to be used with NetCfg Tunbuilder client 80fed2c55 Allow updating auth-token during session ad7da751e don't print time in debug message and use OPENVPN_LOG_PROTO_VERBOSE 981407994 tls-crypt-v2: implement abstract metadata parser be38bbeb8 tls-crypt-v2: test/ssl/proto.cpp - extend protocol test 60fcf374f tls-crypt-v2: implement WKc appending/unwrapping logic 51f4a3a29 tls-crypt-v2: introduce CONTROL_HARD_RESET_V3 packet type 156a6e58b tls-crypt-v2: implement client key parser and renderer 54a97b381 ssl: add support for encoding/decoding PEM format f090fcda4 tls-crypt: make HMAC API more generic d87f5bbc0 OpenSSL: init library 2ea88a93b Add Remote endpoint information to protect_socket call 0a081ee17 [OVPN3-315] cli/go: add option to compile SITNL component 5bbfb57c0 [OVPN3-315] TunLinux::Client: allow user to select netlink at compile time e8458a68e [OVPN3-315] GW: add netlink support 4e77edb9e [OVPN3-315] TunLinux: add Netlink implementation for Tun setup methods 68508fe56 bigmutex: include missing extern.hpp header a7b923e1e Fix logic inversion from commit 2de9aebc 923e10d13 runcontext: arrange members to allow inheritance 2de9aebc7 Replace deprecated mbedtls_sha1 with mbedtls_sha1_ret e9c0bd00b Remove unused private field ee17c33c2 Add virtual deconstructor to TransportClientParent fab64ba0f Fix clang warning about unused attributes and missing overrides 2624d9ddf Also parse dhcp-option DNS6 as DNS server for compatibility with OpenVPN 2 6d12c9cc2 Refuse external pki with non RSA keys 4a25059f5 test/ovpncli: Don't override PROF env variable f241c4c5f scripts: Add tool to update copyright years 27beeb03d Update lz4 version to 1.8.3 17e356858 Define DASIO_HAS_STD_STRING_VIEW on Android build b107fd994 Remove unsupported platforms from Android build 6a200f72e Ensure all Android components are always installed fbcd374a4 [OVPN3-327] OpenSSL: ensure >TLS1.0 is negotiated by default d9b1f78b6 JSON: #define OPENVPN_JSON_INTERNAL when internal JSON library is used 39290f19d Fix build issues with #if macro on big-endian hardware d4f62d9ed Fix instantiating a new URL instead of parsing the URL git-subtree-dir: Sources/OpenVPNAdapter/Libraries/Vendors/openvpn git-subtree-split: 6608878d57eec1c64c16c5a13ee65b2cf0418ca1
This commit is contained in:
@@ -9,8 +9,8 @@ env:
|
||||
- secure: "dqiLqbzug/xs6F4Q9ei1pGpNf9Q6H3+iKN1W+P0TtODbCXPr/mLWdvHGVMIMqr7H7rBrIUPFPrfqd80nu3jQuQonjcHK/XyJJfmf5hUdhGAszSaixhWnGfVmn/VSV7/5+9DGAU3l9S6YZg4lvi12+cOrlblNgx8GeI5VdN/6HBSHkEqKNI56qn3Y+ugSdLeL1opmzlY58vRsCCmpBH8Ronn4tmSyi85/WZXfF43o9FGGJcygdh6QVWA1CDdNMeLTCt9ld+oToUIiFLiUrhfS1JpSvzysz2xsuEntxZaTMDYPyL4+O8Mj/scl6ejLLXzxTNa7AZOgySLBahf+F4b+yhL1deSVuu40MfxPW6XiM1jKy3KPH/GlYgM8CZQ3D1hQIq1CIUg8DgnTa06RUzevsR5DqDvz+EcPanFHE7dHGrPy9Rs/0y59dNHp3qWKjWMoSA06GerbF61XFOb4mcE29053kV8uxqIa5ZShZ/ndoLeVpQ4mZ+/XSkUybysVl0gWrKnnNNEPtqrdmKf+jlmKY0jyRPdwf425Ldn+wcbGw9ZEnkosYzqAhDBDX4OETAKLi8G0FEYECKKQcd1OX+HNvsOIyOAoLOj7H30F8UkPsjR3ysdIEmc6702ly06gDYjWmwQaCigL/1ktRKgf7ePB0HS+8fOa5SML7619kQrGrWA="
|
||||
- PREFIX="${HOME}/opt"
|
||||
- ASIO_VERSION="862aed305dcf91387535519c9549c17630339a12"
|
||||
- LZ4_VERSION="1.7.5"
|
||||
- MBEDTLS_VERSION="2.5.1"
|
||||
- LZ4_VERSION="1.8.3"
|
||||
- MBEDTLS_VERSION="2.7.5"
|
||||
- MBEDTLS_CFLAGS="-I${PREFIX}/include"
|
||||
- MBEDTLS_LIBS="-lmbedtls -lmbedx509 -lmbedcrypto"
|
||||
- OPENSSL_VERSION="1.0.2l"
|
||||
@@ -22,11 +22,9 @@ matrix:
|
||||
include:
|
||||
- env: SSLLIB="openssl"
|
||||
os: osx
|
||||
osx_image: xcode8.3
|
||||
compiler: clang
|
||||
- env: SSLLIB="mbedtls"
|
||||
os: osx
|
||||
osx_image: xcode8.3
|
||||
compiler: clang
|
||||
- env: SSLLIB="openssl" RUN_COVERITY_SCAN="1"
|
||||
os: linux
|
||||
|
||||
@@ -259,10 +259,10 @@ namespace openvpn {
|
||||
parent = parent_arg;
|
||||
}
|
||||
|
||||
virtual bool socket_protect(int socket)
|
||||
bool socket_protect(int socket, IP::Addr endpoint) override
|
||||
{
|
||||
if (parent)
|
||||
return parent->socket_protect(socket);
|
||||
return parent->socket_protect(socket, endpoint.to_string(), endpoint.is_ipv6());
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -466,7 +466,8 @@ namespace openvpn {
|
||||
|
||||
// Callback to "protect" a socket from being routed through the tunnel.
|
||||
// Will be called from the thread executing connect().
|
||||
virtual bool socket_protect(int socket) = 0;
|
||||
// The remote and ipv6 are the remote host this socket will connect to
|
||||
virtual bool socket_protect(int socket, std::string remote, bool ipv6) = 0;
|
||||
|
||||
// Primary VPN client connect method, doesn't return until disconnect.
|
||||
// Should be called by a worker thread. This method will make callbacks
|
||||
|
||||
4
deps/lib-versions
vendored
4
deps/lib-versions
vendored
@@ -1,8 +1,8 @@
|
||||
export ASIO_VERSION=asio-1-12-0
|
||||
export ASIO_CSUM=fa8c3a16dc2163f5b3451f2a14ce95277c971f46700497d4e94af6059c00dc06
|
||||
|
||||
export LZ4_VERSION=lz4-1.8.0
|
||||
export LZ4_CSUM=2ca482ea7a9bb103603108b5a7510b7592b90158c151ff50a28f1ca8389fccf6
|
||||
export LZ4_VERSION=lz4-1.8.3
|
||||
export LZ4_CSUM=33af5936ac06536805f9745e0b6d61da606a1f8b4cc5c04dd3cbaca3b9b4fc43
|
||||
|
||||
export MBEDTLS_VERSION=mbedtls-2.7.5
|
||||
export MBEDTLS_CSUM=a1302ad9094aabb9880d2755927b466a6bac8e02b68e04dee77321f3859e9b40
|
||||
|
||||
@@ -76,6 +76,7 @@ $GPP_CMD \
|
||||
-DASIO_NO_DEPRECATED \
|
||||
-DHAVE_LZ4 \
|
||||
-DOPENVPN_USE_TLS_MD5 \
|
||||
-DASIO_HAS_STD_STRING_VIEW \
|
||||
-I$O3/core/client \
|
||||
-I$O3/core \
|
||||
$common \
|
||||
|
||||
@@ -557,7 +557,8 @@ namespace openvpn {
|
||||
init_headroom(headroom);
|
||||
}
|
||||
|
||||
void append(const BufferType& other)
|
||||
template <typename B>
|
||||
void append(const B& other)
|
||||
{
|
||||
write(other.c_data(), other.size());
|
||||
}
|
||||
|
||||
@@ -693,6 +693,7 @@ namespace openvpn {
|
||||
cp->dc_deferred = true; // defer data channel setup until after options pull
|
||||
cp->tls_auth_factory.reset(new CryptoOvpnHMACFactory<SSLLib::CryptoAPI>());
|
||||
cp->tls_crypt_factory.reset(new CryptoTLSCryptFactory<SSLLib::CryptoAPI>());
|
||||
cp->tls_crypt_metadata_factory.reset(new CryptoTLSCryptMetadataFactory());
|
||||
cp->tlsprf_factory.reset(new CryptoTLSPRFFactory<SSLLib::CryptoAPI>());
|
||||
cp->ssl_factory = cc->new_factory();
|
||||
cp->load(opt, *proto_context_options, config.default_key_direction, false);
|
||||
|
||||
@@ -600,6 +600,13 @@ namespace openvpn {
|
||||
else
|
||||
OPENVPN_LOG("Options continuation...");
|
||||
}
|
||||
else if (received_options.complete() && string::starts_with(msg, "PUSH_REPLY,"))
|
||||
{
|
||||
// We got a PUSH REPLY in the middle of a session. Ignore it apart from
|
||||
// updating the auth-token if included in the push reply
|
||||
auto opts = OptionList::parse_from_csv_static(msg.substr(11), nullptr);
|
||||
extract_auth_token(opts);
|
||||
}
|
||||
else if (string::starts_with(msg, "AUTH_FAILED"))
|
||||
{
|
||||
std::string reason;
|
||||
|
||||
@@ -276,8 +276,7 @@ namespace openvpn {
|
||||
PreResolve(openvpn_io::io_context& io_context_arg,
|
||||
const RemoteList::Ptr& remote_list_arg,
|
||||
const SessionStats::Ptr& stats_arg)
|
||||
: io_context(io_context_arg),
|
||||
resolver(io_context_arg),
|
||||
: resolver(io_context_arg),
|
||||
notify_callback(nullptr),
|
||||
remote_list(remote_list_arg),
|
||||
stats(stats_arg),
|
||||
@@ -385,7 +384,6 @@ namespace openvpn {
|
||||
}
|
||||
}
|
||||
|
||||
openvpn_io::io_context& io_context;
|
||||
openvpn_io::ip::tcp::resolver resolver;
|
||||
NotifyCallback* notify_callback;
|
||||
RemoteList::Ptr remote_list;
|
||||
|
||||
@@ -34,11 +34,13 @@
|
||||
|
||||
#include <mutex>
|
||||
|
||||
#include <openvpn/common/extern.hpp>
|
||||
|
||||
namespace openvpn {
|
||||
namespace bigmutex {
|
||||
OPENVPN_EXTERN std::recursive_mutex the_recursive_mutex;
|
||||
}
|
||||
|
||||
|
||||
#ifdef OPENVPN_ENABLE_BIGMUTEX
|
||||
#define OPENVPN_ASYNC_HANDLER \
|
||||
std::lock_guard<std::recursive_mutex> lg(bigmutex::the_recursive_mutex);
|
||||
|
||||
@@ -19,25 +19,13 @@
|
||||
// along with this program in the COPYING file.
|
||||
// If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#ifndef OPENVPN_COMMON_ENDIAN_H
|
||||
#define OPENVPN_COMMON_ENDIAN_H
|
||||
#pragma once
|
||||
|
||||
#include <openvpn/common/size.hpp>
|
||||
|
||||
// test for machine endiannes
|
||||
#if defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && defined(__ORDER_LITTLE_ENDIAN__)
|
||||
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
||||
#define OPENVPN_BIG_ENDIAN
|
||||
#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
#define OPENVPN_LITTLE_ENDIAN
|
||||
#endif
|
||||
#elif defined(_WIN32)
|
||||
#define OPENVPN_LITTLE_ENDIAN // assume that Windows is always little-endian
|
||||
#endif
|
||||
#include <openvpn/common/endian_platform.hpp>
|
||||
|
||||
namespace openvpn {
|
||||
namespace Endian {
|
||||
# ifdef OPENVPN_LITTLE_ENDIAN
|
||||
# if defined(OPENVPN_LITTLE_ENDIAN)
|
||||
inline size_t e16(const size_t v)
|
||||
{
|
||||
return v;
|
||||
@@ -62,7 +50,7 @@ namespace openvpn {
|
||||
{
|
||||
return 1-v;
|
||||
}
|
||||
# elif OPENVPN_BIG_ENDIAN
|
||||
# elif defined(OPENVPN_BIG_ENDIAN)
|
||||
inline size_t e16rev(const size_t v)
|
||||
{
|
||||
return v;
|
||||
@@ -92,5 +80,3 @@ namespace openvpn {
|
||||
# endif
|
||||
}
|
||||
} // namespace openvpn
|
||||
|
||||
#endif // OPENVPN_COMMON_ENDIAN_H
|
||||
|
||||
35
openvpn/common/endian_platform.hpp
Normal file
35
openvpn/common/endian_platform.hpp
Normal file
@@ -0,0 +1,35 @@
|
||||
// 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-2018 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <openvpn/common/size.hpp>
|
||||
|
||||
// test for machine endiannes
|
||||
#if defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && defined(__ORDER_LITTLE_ENDIAN__)
|
||||
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
||||
#define OPENVPN_BIG_ENDIAN
|
||||
#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
#define OPENVPN_LITTLE_ENDIAN
|
||||
#endif
|
||||
#elif defined(_WIN32)
|
||||
#define OPENVPN_LITTLE_ENDIAN // assume that Windows is always little-endian
|
||||
#endif
|
||||
@@ -32,18 +32,88 @@ namespace openvpn {
|
||||
|
||||
#if defined(__GNUC__)
|
||||
|
||||
inline int find_first_set(unsigned int v)
|
||||
template <typename T>
|
||||
inline constexpr int n_bits_type()
|
||||
{
|
||||
return sizeof(T) * 8;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline constexpr int n_bits_type(const T& v)
|
||||
{
|
||||
return sizeof(v) * 8;
|
||||
}
|
||||
|
||||
inline int find_first_set(const unsigned int v)
|
||||
{
|
||||
if (!v)
|
||||
return 0;
|
||||
return __builtin_ffs(v);
|
||||
}
|
||||
|
||||
inline int find_last_set(unsigned int v)
|
||||
inline int find_first_set(const int v)
|
||||
{
|
||||
return find_first_set(static_cast<unsigned int>(v));
|
||||
}
|
||||
|
||||
inline int find_last_set(const unsigned int v)
|
||||
{
|
||||
if (!v)
|
||||
return 0;
|
||||
return 32 - __builtin_clz(v);
|
||||
return n_bits_type(v) - __builtin_clz(v);
|
||||
}
|
||||
|
||||
inline int find_last_set(const int v)
|
||||
{
|
||||
return find_last_set(static_cast<unsigned int>(v));
|
||||
}
|
||||
|
||||
inline int find_first_set(const unsigned long v)
|
||||
{
|
||||
if (!v)
|
||||
return 0;
|
||||
return __builtin_ffsl(v);
|
||||
}
|
||||
|
||||
inline int find_first_set(const long v)
|
||||
{
|
||||
return find_first_set(static_cast<unsigned long>(v));
|
||||
}
|
||||
|
||||
inline int find_last_set(const unsigned long v)
|
||||
{
|
||||
if (!v)
|
||||
return 0;
|
||||
return n_bits_type(v) - __builtin_clzl(v);
|
||||
}
|
||||
|
||||
inline int find_last_set(const long v)
|
||||
{
|
||||
return find_last_set(static_cast<unsigned long>(v));
|
||||
}
|
||||
|
||||
inline int find_first_set(const unsigned long long v)
|
||||
{
|
||||
if (!v)
|
||||
return 0;
|
||||
return __builtin_ffsll(v);
|
||||
}
|
||||
|
||||
inline int find_first_set(const long long v)
|
||||
{
|
||||
return find_first_set(static_cast<unsigned long long>(v));
|
||||
}
|
||||
|
||||
inline int find_last_set(const unsigned long long v)
|
||||
{
|
||||
if (!v)
|
||||
return 0;
|
||||
return n_bits_type(v) - __builtin_clzll(v);
|
||||
}
|
||||
|
||||
inline int find_last_set(const long long v)
|
||||
{
|
||||
return find_last_set(static_cast<unsigned long long>(v));
|
||||
}
|
||||
|
||||
#elif defined(_MSC_VER)
|
||||
|
||||
@@ -30,7 +30,8 @@
|
||||
#error atomic file methods not supported on Windows
|
||||
#endif
|
||||
|
||||
#include <stdio.h> // for rename()
|
||||
#include <stdio.h> // for rename()
|
||||
#include <unistd.h> // for unlink()
|
||||
#include <errno.h>
|
||||
#include <cstring>
|
||||
|
||||
@@ -63,6 +64,7 @@ namespace openvpn {
|
||||
if (::rename(tfn.c_str(), fn.c_str()) == -1)
|
||||
{
|
||||
const int eno = errno;
|
||||
::unlink(tfn.c_str()); // move failed, so delete the temporary file
|
||||
OPENVPN_THROW(file_unix_error, "error moving '" << tfn << "' -> '" << fn << "' : " << strerror_str(eno));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,5 +26,6 @@
|
||||
#include "json/json.h" // JsonCpp library
|
||||
#elif defined(HAVE_OPENVPN_COMMON)
|
||||
#define HAVE_JSON
|
||||
#define OPENVPN_JSON_INTERNAL
|
||||
#include <openvpn/common/json.hpp> // internal OpenVPN JSON implementation
|
||||
#endif
|
||||
|
||||
@@ -28,8 +28,12 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <openvpn/common/platform.hpp>
|
||||
|
||||
namespace openvpn {
|
||||
|
||||
#if defined(OPENVPN_PLATFORM_LINUX)
|
||||
|
||||
inline int update_file_mod_time_nanoseconds(const std::string& filename,
|
||||
const std::uint64_t nanoseconds_since_epooch)
|
||||
{
|
||||
@@ -54,4 +58,20 @@ namespace openvpn {
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
inline int update_file_mod_time_nanoseconds(const std::string& filename,
|
||||
const std::uint64_t nanoseconds_since_epooch)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline int update_file_mod_time_nanoseconds(const int fd,
|
||||
const std::uint64_t nanoseconds_since_epooch)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
@@ -113,6 +113,56 @@ namespace openvpn {
|
||||
return "";
|
||||
}
|
||||
|
||||
// return true if path is a regular file that doesn't try to traverse via ".." or "/..."
|
||||
inline bool is_contained(const std::string& path)
|
||||
{
|
||||
if (path.empty())
|
||||
return false;
|
||||
if (win_dev(path, false))
|
||||
return false;
|
||||
if (is_dirsep(path[0]))
|
||||
return false;
|
||||
|
||||
// look for ".." in path
|
||||
enum State {
|
||||
SEP, // immediately after separator
|
||||
MID, // middle of dir
|
||||
DOT_2, // looking for second '.'
|
||||
POST_DOT_2, // after ".."
|
||||
};
|
||||
State state = SEP;
|
||||
for (const auto c : path)
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case SEP:
|
||||
if (c == '.')
|
||||
state = DOT_2;
|
||||
else if (!is_dirsep(c))
|
||||
state = MID;
|
||||
break;
|
||||
case MID:
|
||||
if (is_dirsep(c))
|
||||
state = SEP;
|
||||
break;
|
||||
case DOT_2:
|
||||
if (c == '.')
|
||||
state = POST_DOT_2;
|
||||
else if (is_dirsep(c))
|
||||
state = SEP;
|
||||
else
|
||||
state = MID;
|
||||
break;
|
||||
case POST_DOT_2:
|
||||
if (is_dirsep(c))
|
||||
return false;
|
||||
state = MID;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return state != POST_DOT_2;
|
||||
}
|
||||
|
||||
inline std::string ext(const std::string& basename)
|
||||
{
|
||||
const size_t pos = basename.find_last_of('.');
|
||||
|
||||
@@ -325,7 +325,8 @@ namespace openvpn {
|
||||
cancel();
|
||||
}
|
||||
|
||||
void signal(const openvpn_io::error_code& error, int signum)
|
||||
protected:
|
||||
virtual void signal(const openvpn_io::error_code& error, int signum)
|
||||
{
|
||||
if (!error && !halt)
|
||||
{
|
||||
@@ -346,10 +347,14 @@ namespace openvpn {
|
||||
signal_rearm();
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
signal_rearm();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
void signal_rearm()
|
||||
{
|
||||
signals->register_signals_all([self=Ptr(this)](const openvpn_io::error_code& error, int signal_number)
|
||||
@@ -392,7 +397,6 @@ namespace openvpn {
|
||||
// servlist and related vars protected by mutex
|
||||
std::vector<ServerThread*> servlist;
|
||||
int thread_count = 0;
|
||||
volatile bool halt = false;
|
||||
|
||||
// stop
|
||||
Stop* async_stop_ = nullptr;
|
||||
@@ -404,6 +408,9 @@ namespace openvpn {
|
||||
// logging
|
||||
Log::Context log_context;
|
||||
Log::Context::Wrapper log_wrap; // must be constructed after log_context
|
||||
|
||||
protected:
|
||||
volatile bool halt = false;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -296,7 +296,7 @@ namespace openvpn {
|
||||
inline bool contains_non_space_ctrl(const std::string& str)
|
||||
{
|
||||
for (auto &c : str)
|
||||
if (!is_space(c) && is_ctrl(c))
|
||||
if ((!is_space(c) && is_ctrl(c)) || c == 127)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -26,9 +26,16 @@
|
||||
#include <openvpn/common/pthreadcond.hpp>
|
||||
|
||||
namespace openvpn {
|
||||
|
||||
#ifdef HAVE_VALGRIND
|
||||
static constexpr unsigned int WAIT_BARRIER_TIMEOUT = 300;
|
||||
#else
|
||||
static constexpr unsigned int WAIT_BARRIER_TIMEOUT = 30;
|
||||
#endif
|
||||
|
||||
template <typename THREAD_COMMON>
|
||||
inline void event_loop_wait_barrier(THREAD_COMMON& tc,
|
||||
const unsigned int seconds=30)
|
||||
const unsigned int seconds=WAIT_BARRIER_TIMEOUT)
|
||||
{
|
||||
// barrier prior to event-loop entry
|
||||
switch (tc.event_loop_bar.wait(seconds))
|
||||
|
||||
@@ -89,11 +89,8 @@ namespace openvpn {
|
||||
bool hmac_gen(unsigned char *header, const size_t header_len,
|
||||
const unsigned char *payload, const size_t payload_len)
|
||||
{
|
||||
if (header_len < head_size + output_hmac_size())
|
||||
return false;
|
||||
|
||||
hmac_pre(header, payload, payload_len);
|
||||
ctx_hmac.final(header + head_size);
|
||||
hmac_pre(header, header_len, payload, payload_len);
|
||||
ctx_hmac.final(header + header_len);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -103,13 +100,10 @@ namespace openvpn {
|
||||
{
|
||||
unsigned char local_hmac[CRYPTO_API::HMACContext::MAX_HMAC_SIZE];
|
||||
|
||||
if (header_len < head_size + output_hmac_size())
|
||||
return false;
|
||||
|
||||
hmac_pre(header, payload, payload_len);
|
||||
hmac_pre(header, header_len, payload, payload_len);
|
||||
ctx_hmac.final(local_hmac);
|
||||
|
||||
return !crypto::memneq(header + head_size, local_hmac, output_hmac_size());
|
||||
return !crypto::memneq(header + header_len, local_hmac, output_hmac_size());
|
||||
}
|
||||
|
||||
size_t encrypt(const unsigned char *iv, unsigned char *out, const size_t olen,
|
||||
@@ -132,11 +126,11 @@ namespace openvpn {
|
||||
|
||||
private:
|
||||
// assume length check on header has already been performed
|
||||
void hmac_pre(const unsigned char *header, const unsigned char *payload,
|
||||
const size_t payload_len)
|
||||
void hmac_pre(const unsigned char *header, const size_t header_len,
|
||||
const unsigned char *payload, const size_t payload_len)
|
||||
{
|
||||
ctx_hmac.reset();
|
||||
ctx_hmac.update(header, head_size);
|
||||
ctx_hmac.update(header, header_len);
|
||||
ctx_hmac.update(payload, payload_len);
|
||||
}
|
||||
|
||||
@@ -159,19 +153,8 @@ namespace openvpn {
|
||||
typename CRYPTO_API::HMACContext ctx_hmac;
|
||||
typename CRYPTO_API::CipherContext ctx_crypt;
|
||||
int mode;
|
||||
|
||||
static const size_t head_size;
|
||||
};
|
||||
|
||||
// initialize static member with non-constexpr.
|
||||
// This is the size of the header in a TLSCrypt-wrapped packets,
|
||||
// excluding the HMAC. Format:
|
||||
//
|
||||
// [OP] [PSID] [PID] [HMAC] [...]
|
||||
//
|
||||
template <typename CRYPTO_API>
|
||||
const size_t TLSCrypt<CRYPTO_API>::head_size = 1 + ProtoSessionID::SIZE + PacketID::size(PacketID::LONG_FORM);
|
||||
|
||||
// OvpnHMAC wrapper API using dynamic polymorphism
|
||||
|
||||
class TLSCryptInstance : public RC<thread_unsafe_refcount>
|
||||
@@ -208,8 +191,19 @@ namespace openvpn {
|
||||
virtual TLSCryptInstance::Ptr new_obj_send() = 0;
|
||||
|
||||
virtual TLSCryptInstance::Ptr new_obj_recv() = 0;
|
||||
|
||||
static const size_t hmac_offset;
|
||||
};
|
||||
|
||||
// initialize static member with non-constexpr.
|
||||
// This is the size of the header in a TLSCrypt-wrapped packets,
|
||||
// excluding the HMAC. Format:
|
||||
//
|
||||
// [OP] [PSID] [PID] [HMAC] [...]
|
||||
//
|
||||
const size_t TLSCryptContext::hmac_offset = 1 + ProtoSessionID::SIZE +
|
||||
PacketID::size(PacketID::LONG_FORM);
|
||||
|
||||
class TLSCryptFactory : public RC<thread_unsafe_refcount>
|
||||
{
|
||||
public:
|
||||
@@ -244,21 +238,6 @@ namespace openvpn {
|
||||
return tls_crypt.output_hmac_size();
|
||||
}
|
||||
|
||||
void ovpn_hmac_reset()
|
||||
{
|
||||
tls_crypt.ovpn_hmac_reset();
|
||||
}
|
||||
|
||||
void ovpn_hmac_update(const unsigned char *in, const size_t in_size)
|
||||
{
|
||||
tls_crypt.ovpn_hmac_update(in, in_size);
|
||||
}
|
||||
|
||||
void ovpn_hmac_write(unsigned char *out)
|
||||
{
|
||||
tls_crypt.ovpn_hmac_write(out);
|
||||
}
|
||||
|
||||
bool hmac_gen(unsigned char *header, const size_t header_len,
|
||||
const unsigned char *payload, const size_t payload_len)
|
||||
{
|
||||
|
||||
198
openvpn/crypto/tls_crypt_v2.hpp
Normal file
198
openvpn/crypto/tls_crypt_v2.hpp
Normal file
@@ -0,0 +1,198 @@
|
||||
// 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) 2017-2018 OpenVPN Technologies, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU 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 General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program in the COPYING file.
|
||||
// If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
// Classes for handling OpenVPN tls-crypt-v2 internals
|
||||
|
||||
#ifndef OPENVPN_CRYPTO_TLS_CRYPT_V2_H
|
||||
#define OPENVPN_CRYPTO_TLS_CRYPT_V2_H
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <openvpn/common/exception.hpp>
|
||||
#include <openvpn/buffer/buffer.hpp>
|
||||
#include <openvpn/crypto/static_key.hpp>
|
||||
#include <openvpn/crypto/tls_crypt.hpp>
|
||||
#include <openvpn/ssl/sslchoose.hpp>
|
||||
|
||||
namespace openvpn {
|
||||
class TLSCryptV2ServerKey
|
||||
{
|
||||
public:
|
||||
OPENVPN_SIMPLE_EXCEPTION(tls_crypt_v2_server_key_parse_error);
|
||||
OPENVPN_SIMPLE_EXCEPTION(tls_crypt_v2_server_key_encode_error);
|
||||
OPENVPN_SIMPLE_EXCEPTION(tls_crypt_v2_server_key_bad_size);
|
||||
|
||||
TLSCryptV2ServerKey()
|
||||
: key_size(128),
|
||||
key(key_size, BufferAllocated::DESTRUCT_ZERO)
|
||||
{}
|
||||
|
||||
bool defined() const
|
||||
{
|
||||
return key.defined();
|
||||
}
|
||||
|
||||
void parse(const std::string& key_text)
|
||||
{
|
||||
if (!SSLLib::PEMAPI::pem_decode(key, key_text.c_str(), key_text.length(),
|
||||
tls_crypt_v2_server_key_name))
|
||||
throw tls_crypt_v2_server_key_parse_error();
|
||||
|
||||
if (key.size() != key_size)
|
||||
throw tls_crypt_v2_server_key_bad_size();
|
||||
}
|
||||
|
||||
void extract_key(OpenVPNStaticKey& tls_key)
|
||||
{
|
||||
std::memcpy(tls_key.raw_alloc(), key.c_data(), key_size);
|
||||
}
|
||||
|
||||
std::string render() const
|
||||
{
|
||||
BufferAllocated data(32 + 2 * key.size(), 0);
|
||||
|
||||
if (!SSLLib::PEMAPI::pem_encode(data, key.c_data(), key.size(),
|
||||
tls_crypt_v2_server_key_name))
|
||||
throw tls_crypt_v2_server_key_encode_error();
|
||||
|
||||
return std::string((const char *)data.c_data());
|
||||
}
|
||||
|
||||
private:
|
||||
const size_t key_size;
|
||||
BufferAllocated key;
|
||||
static const std::string tls_crypt_v2_server_key_name;
|
||||
};
|
||||
|
||||
const std::string TLSCryptV2ServerKey::tls_crypt_v2_server_key_name = "OpenVPN tls-crypt-v2 server key";
|
||||
|
||||
class TLSCryptV2ClientKey
|
||||
{
|
||||
public:
|
||||
enum {
|
||||
WKC_MAX_SIZE = 1024, // bytes
|
||||
};
|
||||
|
||||
OPENVPN_SIMPLE_EXCEPTION(tls_crypt_v2_client_key_parse_error);
|
||||
OPENVPN_SIMPLE_EXCEPTION(tls_crypt_v2_client_key_encode_error);
|
||||
OPENVPN_SIMPLE_EXCEPTION(tls_crypt_v2_client_key_bad_size);
|
||||
|
||||
TLSCryptV2ClientKey() = delete;
|
||||
|
||||
TLSCryptV2ClientKey(TLSCryptContext::Ptr context)
|
||||
: key_size(OpenVPNStaticKey::KEY_SIZE),
|
||||
tag_size(context->digest_size())
|
||||
{}
|
||||
|
||||
bool defined() const
|
||||
{
|
||||
return key.defined() && wkc.defined();
|
||||
}
|
||||
|
||||
void parse(const std::string& key_text)
|
||||
{
|
||||
BufferAllocated data(key_size + WKC_MAX_SIZE, BufferAllocated::DESTRUCT_ZERO);
|
||||
|
||||
if (!SSLLib::PEMAPI::pem_decode(data, key_text.c_str(), key_text.length(),
|
||||
tls_crypt_v2_client_key_name))
|
||||
throw tls_crypt_v2_client_key_parse_error();
|
||||
|
||||
if (data.size() < (tag_size + key_size))
|
||||
throw tls_crypt_v2_client_key_bad_size();
|
||||
|
||||
key.init(data.data(), key_size, BufferAllocated::DESTRUCT_ZERO);
|
||||
wkc.init(data.data() + key_size, data.size() - key_size, BufferAllocated::DESTRUCT_ZERO);
|
||||
}
|
||||
|
||||
void extract_key(OpenVPNStaticKey& tls_key)
|
||||
{
|
||||
std::memcpy(tls_key.raw_alloc(), key.c_data(), key_size);
|
||||
}
|
||||
|
||||
std::string render() const
|
||||
{
|
||||
BufferAllocated data(32 + 2 * (key.size() + wkc.size()), 0);
|
||||
BufferAllocated in(key, BufferAllocated::GROW);
|
||||
in.append(wkc);
|
||||
|
||||
if (!SSLLib::PEMAPI::pem_encode(data, in.c_data(), in.size(), tls_crypt_v2_client_key_name))
|
||||
throw tls_crypt_v2_client_key_encode_error();
|
||||
|
||||
return std::string((const char *)data.c_data());
|
||||
}
|
||||
|
||||
void extract_wkc(BufferAllocated& wkc_out) const
|
||||
{
|
||||
wkc_out = wkc;
|
||||
}
|
||||
|
||||
private:
|
||||
BufferAllocated key;
|
||||
BufferAllocated wkc;
|
||||
|
||||
const size_t key_size;
|
||||
const size_t tag_size;
|
||||
|
||||
static const std::string tls_crypt_v2_client_key_name;
|
||||
};
|
||||
|
||||
const std::string TLSCryptV2ClientKey::tls_crypt_v2_client_key_name = "OpenVPN tls-crypt-v2 client key";
|
||||
|
||||
// the user can extend the TLSCryptMetadata and the TLSCryptMetadataFactory
|
||||
// classes to implement its own metadata verification method.
|
||||
//
|
||||
// default method is to *ignore* the metadata contained in the WKc sent by the client
|
||||
class TLSCryptMetadata : public RC<thread_unsafe_refcount>
|
||||
{
|
||||
public:
|
||||
typedef RCPtr<TLSCryptMetadata> Ptr;
|
||||
|
||||
// override this method with your own verification mechanism.
|
||||
//
|
||||
// If type is -1 it means that metadata is empty.
|
||||
//
|
||||
virtual bool verify(int type, Buffer& metadata) const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
// abstract class to be extended when creating other factories
|
||||
class TLSCryptMetadataFactory : public RC<thread_unsafe_refcount>
|
||||
{
|
||||
public:
|
||||
typedef RCPtr<TLSCryptMetadataFactory> Ptr;
|
||||
|
||||
virtual TLSCryptMetadata::Ptr new_obj() = 0;
|
||||
};
|
||||
|
||||
// factory implementation for the basic verification method
|
||||
class CryptoTLSCryptMetadataFactory : public TLSCryptMetadataFactory
|
||||
{
|
||||
public:
|
||||
TLSCryptMetadata::Ptr new_obj()
|
||||
{
|
||||
return new TLSCryptMetadata();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* OPENVPN_CRYPTO_TLS_CRYPT_V2_H */
|
||||
@@ -70,6 +70,7 @@ namespace openvpn {
|
||||
PRIMARY_EXPIRE, // primary key context expired
|
||||
TLS_VERSION_MIN, // peer cannot handshake at our minimum required TLS version
|
||||
TLS_AUTH_FAIL, // tls-auth HMAC verification failed
|
||||
TLS_CRYPT_META_FAIL, // tls-crypt-v2 metadata verification failed
|
||||
CERT_VERIFY_FAIL, // peer certificate verification failure
|
||||
PEM_PASSWORD_FAIL, // incorrect or missing PEM private key decryption password
|
||||
AUTH_FAILED, // general authentication failure
|
||||
@@ -145,6 +146,7 @@ namespace openvpn {
|
||||
"PRIMARY_EXPIRE",
|
||||
"TLS_VERSION_MIN",
|
||||
"TLS_AUTH_FAIL",
|
||||
"TLS_CRYPT_META_FAIL",
|
||||
"CERT_VERIFY_FAIL",
|
||||
"PEM_PASSWORD_FAIL",
|
||||
"AUTH_FAILED",
|
||||
|
||||
@@ -93,7 +93,6 @@ namespace openvpn {
|
||||
|
||||
public:
|
||||
enum status {
|
||||
undefined,
|
||||
pending,
|
||||
fail,
|
||||
success,
|
||||
|
||||
@@ -59,10 +59,6 @@ namespace openvpn {
|
||||
{
|
||||
base64_uninit_static();
|
||||
}
|
||||
|
||||
private:
|
||||
// initialize SSL library
|
||||
crypto_init crypto_init_;
|
||||
};
|
||||
|
||||
// process-wide singular instance
|
||||
|
||||
@@ -36,6 +36,11 @@ namespace openvpn {
|
||||
UDP = 17, /* UDP protocol */
|
||||
};
|
||||
|
||||
enum {
|
||||
IPv4 = 4,
|
||||
IPv6 = 6
|
||||
};
|
||||
|
||||
inline unsigned int version(const std::uint8_t version_len_prio)
|
||||
{
|
||||
return (version_len_prio >> 4) & 0x0F;
|
||||
|
||||
90
openvpn/ip/tcp.hpp
Normal file
90
openvpn/ip/tcp.hpp
Normal file
@@ -0,0 +1,90 @@
|
||||
// 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-2017 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <openvpn/common/endian.hpp>
|
||||
#include <openvpn/ip/ipcommon.hpp>
|
||||
|
||||
namespace openvpn {
|
||||
|
||||
#pragma pack(push)
|
||||
#pragma pack(1)
|
||||
|
||||
struct TCPHeader {
|
||||
static unsigned int length(const std::uint8_t doff_res)
|
||||
{
|
||||
return ((doff_res) & 0xF0) >> 2;
|
||||
}
|
||||
|
||||
std::uint16_t source;
|
||||
std::uint16_t dest;
|
||||
std::uint32_t seq;
|
||||
std::uint32_t ack_seq;
|
||||
std::uint8_t doff_res;
|
||||
std::uint8_t flags;
|
||||
std::uint16_t window;
|
||||
std::uint16_t check;
|
||||
std::uint16_t urgent_p;
|
||||
|
||||
// helper enum to parse options in TCP header
|
||||
enum {
|
||||
OPT_EOL = 0,
|
||||
OPT_NOP = 1,
|
||||
OPT_MAXSEG = 2,
|
||||
OPTLEN_MAXSEG = 4
|
||||
};
|
||||
|
||||
enum {
|
||||
FLAG_SYN = 1 << 1
|
||||
};
|
||||
};
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
/*
|
||||
* The following routine is used to update an
|
||||
* internet checksum. "acc" is a 32-bit
|
||||
* accumulation of all the changes to the
|
||||
* checksum (adding in old 16-bit words and
|
||||
* subtracting out new words), and "cksum"
|
||||
* is the checksum value to be updated.
|
||||
*/
|
||||
inline void tcp_adjust_checksum(int acc, std::uint16_t& cksum)
|
||||
{
|
||||
int _acc = acc;
|
||||
_acc += cksum;
|
||||
if (_acc < 0)
|
||||
{
|
||||
_acc = -_acc;
|
||||
_acc = (_acc >> 16) + (_acc & 0xffff);
|
||||
_acc += _acc >> 16;
|
||||
cksum = (uint16_t)~_acc;
|
||||
}
|
||||
else
|
||||
{
|
||||
_acc = (_acc >> 16) + (_acc & 0xffff);
|
||||
_acc += _acc >> 16;
|
||||
cksum = (uint16_t)_acc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -826,8 +826,15 @@ namespace openvpn {
|
||||
// set our own certificate, supporting chain (i.e. extra-certs), and external private key
|
||||
if (c.crt_chain)
|
||||
{
|
||||
epki_ctx.epki_enable(ctx, epki_decrypt, epki_sign, epki_key_len);
|
||||
mbedtls_ssl_conf_own_cert(sslconf, c.crt_chain->get(), epki_ctx.get());
|
||||
if (mbedtls_pk_get_type(&c.crt_chain.get()->get()->pk) == MBEDTLS_PK_RSA)
|
||||
{
|
||||
epki_ctx.epki_enable(ctx, epki_decrypt, epki_sign, epki_key_len);
|
||||
mbedtls_ssl_conf_own_cert(sslconf, c.crt_chain->get(), epki_ctx.get());
|
||||
}
|
||||
else
|
||||
{
|
||||
throw MbedTLSException("cert has unsupported type for external pki support");
|
||||
}
|
||||
}
|
||||
else
|
||||
throw MbedTLSException("cert is undefined");
|
||||
@@ -1217,7 +1224,11 @@ namespace openvpn {
|
||||
{
|
||||
const int SHA_DIGEST_LEN = 20;
|
||||
static_assert(sizeof(AuthCert::issuer_fp) == SHA_DIGEST_LEN, "size inconsistency");
|
||||
mbedtls_sha1(cert->raw.p, cert->raw.len, ssl->authcert->issuer_fp);
|
||||
if(mbedtls_sha1_ret(cert->raw.p, cert->raw.len, ssl->authcert->issuer_fp))
|
||||
{
|
||||
OPENVPN_LOG_SSL("VERIFY FAIL -- SHA1 calculation failed.");
|
||||
fail = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (depth == 0) // leaf-cert
|
||||
|
||||
77
openvpn/mbedtls/util/pem.hpp
Normal file
77
openvpn/mbedtls/util/pem.hpp
Normal file
@@ -0,0 +1,77 @@
|
||||
// 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) 2017-2018 OpenVPN Technologies, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU 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 General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program in the COPYING file.
|
||||
// If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
// Wrap the mbedTLS PEM API defined in <mbedtls/pem.h> so
|
||||
// that it can be used as part of the crypto layer of the OpenVPN core.
|
||||
|
||||
#ifndef OPENVPN_MBEDTLS_UTIL_PEM_H
|
||||
#define OPENVPN_MBEDTLS_UTIL_PEM_H
|
||||
|
||||
#include <mbedtls/pem.h>
|
||||
|
||||
namespace openvpn {
|
||||
class MbedTLSPEM
|
||||
{
|
||||
public:
|
||||
static bool pem_encode(BufferAllocated& dst, const unsigned char *src,
|
||||
size_t src_len, const std::string& key_name)
|
||||
{
|
||||
std::string header = "-----BEGIN " + key_name + "-----\n";
|
||||
std::string footer = "-----END " + key_name + "-----\n";
|
||||
size_t out_len = 0;
|
||||
|
||||
int ret = mbedtls_pem_write_buffer(header.c_str(), footer.c_str(),
|
||||
src, src_len, dst.data(),
|
||||
dst.max_size(), &out_len);
|
||||
if (ret == 0)
|
||||
dst.set_size(out_len);
|
||||
else
|
||||
{
|
||||
char buf[128];
|
||||
mbedtls_strerror(ret, buf, 128);
|
||||
OPENVPN_LOG("mbedtls_pem_write_buffer error: " << buf);
|
||||
}
|
||||
|
||||
return (ret == 0);
|
||||
}
|
||||
|
||||
static bool pem_decode(BufferAllocated& dst, const char *src,
|
||||
size_t src_len, const std::string& key_name)
|
||||
{
|
||||
std::string header = "-----BEGIN " + key_name + "-----";
|
||||
std::string footer = "-----END " + key_name + "-----";
|
||||
mbedtls_pem_context ctx = { 0 };
|
||||
size_t out_len = 0;
|
||||
|
||||
int ret = mbedtls_pem_read_buffer(&ctx, header.c_str(), footer.c_str(),
|
||||
(unsigned char *)src, nullptr, 0,
|
||||
&out_len);
|
||||
if (ret == 0)
|
||||
dst.init(ctx.buf, ctx.buflen, BufferAllocated::DESTRUCT_ZERO);
|
||||
|
||||
mbedtls_pem_free(&ctx);
|
||||
|
||||
return (ret == 0);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
#endif /* OPENVPN_MBEDTLS_UTIL_PEM_H */
|
||||
141
openvpn/netconf/linux/gwnetlink.hpp
Normal file
141
openvpn/netconf/linux/gwnetlink.hpp
Normal file
@@ -0,0 +1,141 @@
|
||||
// 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-2017 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
// Find default gateways on Linux using ip route command
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <openvpn/common/exception.hpp>
|
||||
#include <openvpn/addr/ip.hpp>
|
||||
#include <openvpn/addr/ipv4.hpp>
|
||||
#include <openvpn/addr/ipv6.hpp>
|
||||
#include <openvpn/tun/linux/client/sitnl.hpp>
|
||||
|
||||
namespace openvpn {
|
||||
class LinuxGWNetlink
|
||||
{
|
||||
public:
|
||||
OPENVPN_EXCEPTION(linux_gw_netlink_error);
|
||||
|
||||
LinuxGWNetlink(bool ipv6)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (ipv6)
|
||||
{
|
||||
IPv6::Addr addr6;
|
||||
|
||||
if (TunNetlink::SITNL::net_route_best_gw(IP::Route6(IPv6::Addr::from_zero(), 0),
|
||||
addr6, dev_) < 0)
|
||||
{
|
||||
OPENVPN_THROW(linux_gw_netlink_error,
|
||||
"error retrieving default IPv6 GW");
|
||||
}
|
||||
|
||||
addr_ = IP::Addr::from_ipv6(addr6);
|
||||
}
|
||||
else
|
||||
{
|
||||
IPv4::Addr addr4;
|
||||
|
||||
if (TunNetlink::SITNL::net_route_best_gw(IP::Route4(IPv4::Addr::from_zero(), 0),
|
||||
addr4, dev_) < 0)
|
||||
{
|
||||
OPENVPN_THROW(linux_gw_netlink_error,
|
||||
"error retrieving default IPv4 GW");
|
||||
}
|
||||
|
||||
addr_ = IP::Addr::from_ipv4(addr4);
|
||||
}
|
||||
} catch (...)
|
||||
{
|
||||
/* nothing to do. just leave default GW unassigned */
|
||||
}
|
||||
}
|
||||
|
||||
const std::string& dev() const
|
||||
{
|
||||
return dev_;
|
||||
}
|
||||
|
||||
const IP::Addr& addr() const
|
||||
{
|
||||
return addr_;
|
||||
}
|
||||
|
||||
bool defined() const
|
||||
{
|
||||
return !dev_.empty() && addr_.defined();
|
||||
}
|
||||
|
||||
std::string to_string() const
|
||||
{
|
||||
return dev_ + '/' + addr_.to_string();
|
||||
}
|
||||
|
||||
private:
|
||||
IP::Addr addr_;
|
||||
std::string dev_;
|
||||
};
|
||||
|
||||
struct LinuxGW46Netlink
|
||||
{
|
||||
LinuxGW46Netlink()
|
||||
: v4(false),
|
||||
v6(true)
|
||||
{
|
||||
}
|
||||
|
||||
std::string to_string() const
|
||||
{
|
||||
std::string ret = "[";
|
||||
if (v4.defined())
|
||||
{
|
||||
ret += "4:";
|
||||
ret += v4.to_string();
|
||||
}
|
||||
if (v6.defined())
|
||||
{
|
||||
if (v4.defined())
|
||||
ret += ' ';
|
||||
ret += "6:";
|
||||
ret += v6.to_string();
|
||||
}
|
||||
ret += "]";
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::string dev() const
|
||||
{
|
||||
if (v4.defined())
|
||||
return v4.dev();
|
||||
else if (v6.defined())
|
||||
return v6.dev();
|
||||
else
|
||||
throw LinuxGWNetlink::linux_gw_netlink_error("cannot determine gateway interface");
|
||||
}
|
||||
|
||||
LinuxGWNetlink v4;
|
||||
LinuxGWNetlink v6;
|
||||
};
|
||||
}
|
||||
@@ -520,6 +520,8 @@ namespace openvpn {
|
||||
|
||||
static void init_static()
|
||||
{
|
||||
SSL_library_init();
|
||||
|
||||
mydata_index = SSL_get_ex_new_index(0, (char *)"OpenSSLContext::SSL", nullptr, nullptr, nullptr);
|
||||
|
||||
// We actually override some of the OpenSSL SSLv23 methods here,
|
||||
@@ -867,7 +869,7 @@ namespace openvpn {
|
||||
try
|
||||
{
|
||||
// Create new SSL_CTX for server or client mode
|
||||
const bool ssl23 = (config->force_aes_cbc_ciphersuites || (config->tls_version_min > TLSVersion::UNDEF));
|
||||
const bool ssl23 = (!config->force_aes_cbc_ciphersuites || (config->tls_version_min > TLSVersion::UNDEF));
|
||||
if (config->mode.is_server())
|
||||
{
|
||||
ctx = SSL_CTX_new(ssl23 ? SSL::ssl23_method_server() : TLSv1_server_method());
|
||||
@@ -910,20 +912,17 @@ namespace openvpn {
|
||||
if (ssl23)
|
||||
{
|
||||
sslopt |= SSL_OP_NO_SSLv2;
|
||||
if (!config->force_aes_cbc_ciphersuites || config->tls_version_min > TLSVersion::UNDEF)
|
||||
{
|
||||
sslopt |= SSL_OP_NO_SSLv3;
|
||||
if (config->tls_version_min > TLSVersion::V1_0)
|
||||
sslopt |= SSL_OP_NO_TLSv1;
|
||||
# ifdef SSL_OP_NO_TLSv1_1
|
||||
if (config->tls_version_min > TLSVersion::V1_1)
|
||||
sslopt |= SSL_OP_NO_TLSv1_1;
|
||||
# endif
|
||||
# ifdef SSL_OP_NO_TLSv1_2
|
||||
if (config->tls_version_min > TLSVersion::V1_2)
|
||||
sslopt |= SSL_OP_NO_TLSv1_2;
|
||||
# endif
|
||||
}
|
||||
sslopt |= SSL_OP_NO_SSLv3;
|
||||
if (config->tls_version_min > TLSVersion::V1_0)
|
||||
sslopt |= SSL_OP_NO_TLSv1;
|
||||
# ifdef SSL_OP_NO_TLSv1_1
|
||||
if (config->tls_version_min > TLSVersion::V1_1)
|
||||
sslopt |= SSL_OP_NO_TLSv1_1;
|
||||
# endif
|
||||
# ifdef SSL_OP_NO_TLSv1_2
|
||||
if (config->tls_version_min > TLSVersion::V1_2)
|
||||
sslopt |= SSL_OP_NO_TLSv1_2;
|
||||
# endif
|
||||
}
|
||||
SSL_CTX_set_options(ctx, sslopt);
|
||||
|
||||
|
||||
103
openvpn/openssl/util/pem.hpp
Normal file
103
openvpn/openssl/util/pem.hpp
Normal file
@@ -0,0 +1,103 @@
|
||||
// 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) 2017-2018 OpenVPN Technologies, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU 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 General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program in the COPYING file.
|
||||
// If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
// Wrap the OpenSSL PEM API defined in <openssl/pem.h> so
|
||||
// that it can be used as part of the crypto layer of the OpenVPN core.
|
||||
|
||||
#ifndef OPENVPN_OPENSSL_UTIL_PEM_H
|
||||
#define OPENVPN_OPENSSL_UTIL_PEM_H
|
||||
|
||||
#include <openvpn/openssl/util/error.hpp>
|
||||
|
||||
#include <openssl/pem.h>
|
||||
|
||||
namespace openvpn {
|
||||
class OpenSSLPEM
|
||||
{
|
||||
public:
|
||||
static bool pem_encode(BufferAllocated& dst, const unsigned char *src,
|
||||
size_t src_len, const std::string& key_name)
|
||||
{
|
||||
bool ret = false;
|
||||
BIO *bio = BIO_new(BIO_s_mem());
|
||||
if (!bio)
|
||||
return false;
|
||||
|
||||
if (!PEM_write_bio(bio, key_name.c_str(), "", src, src_len))
|
||||
goto out;
|
||||
|
||||
BUF_MEM *bptr;
|
||||
BIO_get_mem_ptr(bio, &bptr);
|
||||
dst.write((unsigned char *)bptr->data, bptr->length);
|
||||
|
||||
ret = true;
|
||||
|
||||
out:
|
||||
if (!BIO_free(bio))
|
||||
ret = false;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool pem_decode(BufferAllocated& dst, const char *src,
|
||||
size_t src_len, const std::string& key_name)
|
||||
{
|
||||
bool ret = false;
|
||||
BIO *bio;
|
||||
|
||||
if (!(bio = BIO_new_mem_buf(src, src_len)))
|
||||
throw OpenSSLException("Cannot open memory BIO for PEM decode");
|
||||
|
||||
char *name_read = NULL;
|
||||
char *header_read = NULL;
|
||||
uint8_t *data_read = NULL;
|
||||
long data_read_len = 0;
|
||||
if (!PEM_read_bio(bio, &name_read, &header_read, &data_read,
|
||||
&data_read_len))
|
||||
{
|
||||
OPENVPN_LOG("PEM decode failed");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (key_name.compare(std::string(name_read)))
|
||||
{
|
||||
OPENVPN_LOG("unexpected PEM name (got '" << name_read <<
|
||||
"', expected '" << key_name << "')");
|
||||
goto out;
|
||||
}
|
||||
|
||||
dst.write(data_read, data_read_len);
|
||||
|
||||
ret = true;
|
||||
out:
|
||||
OPENSSL_free(name_read);
|
||||
OPENSSL_free(header_read);
|
||||
OPENSSL_free(data_read);
|
||||
|
||||
if (!BIO_free(bio))
|
||||
ret = false;
|
||||
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
#endif /* OPENVPN_OPENSSL_UTIL_PEM_H */
|
||||
@@ -422,6 +422,8 @@ namespace openvpn {
|
||||
}
|
||||
if (d == "tls-crypt")
|
||||
return true;
|
||||
if (d == "tls-crypt-v2")
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ namespace openvpn {
|
||||
inline bool is_openvpn_protocol(const unsigned char *p, const size_t len)
|
||||
{
|
||||
const int CONTROL_HARD_RESET_CLIENT_V2 = 7;
|
||||
const int CONTROL_HARD_RESET_CLIENT_V3 = 10;
|
||||
const int OPCODE_SHIFT = 3;
|
||||
const int MIN_INITIAL_PKT_SIZE = 14;
|
||||
|
||||
@@ -42,7 +43,8 @@ namespace openvpn {
|
||||
case 3:
|
||||
return p[0] == 0
|
||||
&& p[1] >= MIN_INITIAL_PKT_SIZE
|
||||
&& p[2] == (CONTROL_HARD_RESET_CLIENT_V2 << OPCODE_SHIFT);
|
||||
&& (p[2] == (CONTROL_HARD_RESET_CLIENT_V2 << OPCODE_SHIFT)
|
||||
|| p[2] == (CONTROL_HARD_RESET_CLIENT_V3 << OPCODE_SHIFT));
|
||||
case 2:
|
||||
return p[0] == 0 && p[1] >= MIN_INITIAL_PKT_SIZE;
|
||||
case 1:
|
||||
|
||||
@@ -48,6 +48,10 @@
|
||||
#include <openvpn/buffer/buffer.hpp>
|
||||
#include <openvpn/buffer/safestr.hpp>
|
||||
#include <openvpn/buffer/bufcomposed.hpp>
|
||||
#include <openvpn/ip/ip4.hpp>
|
||||
#include <openvpn/ip/ip6.hpp>
|
||||
#include <openvpn/ip/udp.hpp>
|
||||
#include <openvpn/ip/tcp.hpp>
|
||||
#include <openvpn/time/time.hpp>
|
||||
#include <openvpn/time/durhelper.hpp>
|
||||
#include <openvpn/frame/frame.hpp>
|
||||
@@ -57,6 +61,7 @@
|
||||
#include <openvpn/crypto/cipher.hpp>
|
||||
#include <openvpn/crypto/ovpnhmac.hpp>
|
||||
#include <openvpn/crypto/tls_crypt.hpp>
|
||||
#include <openvpn/crypto/tls_crypt_v2.hpp>
|
||||
#include <openvpn/crypto/packet_id.hpp>
|
||||
#include <openvpn/crypto/static_key.hpp>
|
||||
#include <openvpn/crypto/bs64_data_limit.hpp>
|
||||
@@ -65,6 +70,8 @@
|
||||
#include <openvpn/ssl/psid.hpp>
|
||||
#include <openvpn/ssl/tlsprf.hpp>
|
||||
#include <openvpn/ssl/datalimit.hpp>
|
||||
#include <openvpn/ssl/mssparms.hpp>
|
||||
#include <openvpn/transport/mssfix.hpp>
|
||||
#include <openvpn/transport/protocol.hpp>
|
||||
#include <openvpn/tun/layer.hpp>
|
||||
#include <openvpn/tun/tunmtu.hpp>
|
||||
@@ -171,6 +178,7 @@ namespace openvpn {
|
||||
|
||||
// indicates key_method >= 2
|
||||
CONTROL_HARD_RESET_CLIENT_V2 = 7, // initial key from client, forget previous state
|
||||
CONTROL_HARD_RESET_CLIENT_V3 = 10, // initial key from client, forget previous state
|
||||
CONTROL_HARD_RESET_SERVER_V2 = 8, // initial key from server, forget previous state
|
||||
|
||||
// define the range of legal opcodes
|
||||
@@ -291,8 +299,10 @@ namespace openvpn {
|
||||
// compressor
|
||||
CompressContext comp_ctx;
|
||||
|
||||
// tls_auth parms
|
||||
// tls_auth/crypt parms
|
||||
OpenVPNStaticKey tls_key; // leave this undefined to disable tls_auth/crypt
|
||||
bool tls_crypt_v2 = false; // needed to distinguish between tls-crypt and tls-crypt-v2 server mode
|
||||
BufferAllocated wkc; // leave this undefined to disable tls-crypt-v2 on client
|
||||
|
||||
OvpnHMACFactory::Ptr tls_auth_factory;
|
||||
OvpnHMACContext::Ptr tls_auth_context;
|
||||
@@ -301,6 +311,8 @@ namespace openvpn {
|
||||
TLSCryptFactory::Ptr tls_crypt_factory;
|
||||
TLSCryptContext::Ptr tls_crypt_context;
|
||||
|
||||
TLSCryptMetadataFactory::Ptr tls_crypt_metadata_factory;
|
||||
|
||||
// reliability layer parms
|
||||
reliable::id_t reliable_window = 0;
|
||||
size_t max_ack_list = 0;
|
||||
@@ -332,13 +344,15 @@ namespace openvpn {
|
||||
|
||||
// MTU
|
||||
unsigned int tun_mtu = 1500;
|
||||
MSSParms mss_parms;
|
||||
unsigned int mss_inter = 0;
|
||||
|
||||
// Debugging
|
||||
int debug_level = 1;
|
||||
|
||||
// Compatibility
|
||||
bool force_aes_cbc_ciphersuites = false;
|
||||
|
||||
|
||||
// For compatibility with openvpn2 we send initial options on rekeying,
|
||||
// instead of possible modifications caused by NCP
|
||||
std::string initial_options;
|
||||
@@ -433,6 +447,8 @@ namespace openvpn {
|
||||
{
|
||||
if (tls_auth_context)
|
||||
throw proto_option_error("tls-auth and tls-crypt are mutually exclusive");
|
||||
if (tls_crypt_context)
|
||||
throw proto_option_error("tls-crypt and tls-crypt-v2 are mutually exclusive");
|
||||
|
||||
tls_key.parse(o->get(1, 0));
|
||||
|
||||
@@ -445,6 +461,46 @@ namespace openvpn {
|
||||
set_tls_crypt_algs(digest, cipher);
|
||||
}
|
||||
}
|
||||
|
||||
// tls-crypt-v2
|
||||
{
|
||||
const Option *o = opt.get_ptr(relay_prefix("tls-crypt-v2"));
|
||||
if (o)
|
||||
{
|
||||
if (tls_auth_context)
|
||||
throw proto_option_error("tls-auth and tls-crypt-v2 are mutually exclusive");
|
||||
if (tls_crypt_context)
|
||||
throw proto_option_error("tls-crypt and tls-crypt-v2 are mutually exclusive");
|
||||
|
||||
digest = CryptoAlgs::lookup("SHA256");
|
||||
cipher = CryptoAlgs::lookup("AES-256-CTR");
|
||||
|
||||
if ((digest == CryptoAlgs::NONE) || (cipher == CryptoAlgs::NONE))
|
||||
throw proto_option_error("missing support for tls-crypt-v2 algorithms");
|
||||
|
||||
// initialize tls_crypt_context
|
||||
set_tls_crypt_algs(digest, cipher);
|
||||
|
||||
std::string keyfile = o->get(1, 0);
|
||||
|
||||
if (opt.exists("client"))
|
||||
{
|
||||
// in client mode expect the key to be a PEM encoded tls-crypt-v2 client key (key + WKc)
|
||||
TLSCryptV2ClientKey tls_crypt_v2_key(tls_crypt_context);
|
||||
tls_crypt_v2_key.parse(keyfile);
|
||||
tls_crypt_v2_key.extract_key(tls_key);
|
||||
tls_crypt_v2_key.extract_wkc(wkc);
|
||||
}
|
||||
else
|
||||
{
|
||||
// in server mode this is a PEM encoded tls-crypt-v2 server key
|
||||
TLSCryptV2ServerKey tls_crypt_v2_key;
|
||||
tls_crypt_v2_key.parse(keyfile);
|
||||
tls_crypt_v2_key.extract_key(tls_key);
|
||||
}
|
||||
tls_crypt_v2 = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// key-direction
|
||||
@@ -507,6 +563,9 @@ namespace openvpn {
|
||||
// tun-mtu
|
||||
tun_mtu = parse_tun_mtu(opt, tun_mtu);
|
||||
|
||||
// mssfix
|
||||
mss_parms.parse(opt);
|
||||
|
||||
// load parameters that can be present in both config file or pushed options
|
||||
load_common(opt, pco, server ? LOAD_COMMON_SERVER : LOAD_COMMON_CLIENT);
|
||||
}
|
||||
@@ -680,13 +739,18 @@ namespace openvpn {
|
||||
return tls_key.defined() && tls_crypt_context;
|
||||
}
|
||||
|
||||
bool tls_crypt_v2_enabled() const
|
||||
{
|
||||
return tls_crypt_enabled() && tls_crypt_v2;
|
||||
}
|
||||
|
||||
// generate a string summarizing options that will be
|
||||
// transmitted to peer for options consistency check
|
||||
std::string options_string()
|
||||
{
|
||||
if (!initial_options.empty())
|
||||
return initial_options;
|
||||
|
||||
|
||||
std::ostringstream out;
|
||||
|
||||
const bool server = ssl_factory->mode().is_server();
|
||||
@@ -726,7 +790,7 @@ namespace openvpn {
|
||||
out << ",tls-server";
|
||||
else
|
||||
out << ",tls-client";
|
||||
|
||||
|
||||
initial_options = out.str();
|
||||
|
||||
return initial_options;
|
||||
@@ -892,6 +956,7 @@ namespace openvpn {
|
||||
break;
|
||||
}
|
||||
case CONTROL_HARD_RESET_CLIENT_V2:
|
||||
case CONTROL_HARD_RESET_CLIENT_V3:
|
||||
{
|
||||
if (!proto.is_server())
|
||||
return;
|
||||
@@ -946,6 +1011,8 @@ namespace openvpn {
|
||||
return "DATA_V2";
|
||||
case CONTROL_HARD_RESET_CLIENT_V2:
|
||||
return "CONTROL_HARD_RESET_CLIENT_V2";
|
||||
case CONTROL_HARD_RESET_CLIENT_V3:
|
||||
return "CONTROL_HARD_RESET_CLIENT_V3";
|
||||
case CONTROL_HARD_RESET_SERVER_V2:
|
||||
return "CONTROL_HARD_RESET_SERVER_V2";
|
||||
}
|
||||
@@ -1217,6 +1284,8 @@ namespace openvpn {
|
||||
public:
|
||||
typedef RCPtr<KeyContext> Ptr;
|
||||
|
||||
OPENVPN_SIMPLE_EXCEPTION(tls_crypt_unwrap_wkc_error);
|
||||
|
||||
// KeyContext events occur on two basic key types:
|
||||
// Primary Key -- the key we transmit/encrypt on.
|
||||
// Secondary Key -- new keys and retiring keys.
|
||||
@@ -1351,7 +1420,7 @@ namespace openvpn {
|
||||
send_reset();
|
||||
set_state(state+1);
|
||||
dirty = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// control channel flush
|
||||
@@ -1466,6 +1535,10 @@ namespace openvpn {
|
||||
// decompress packet
|
||||
if (compress)
|
||||
compress->decompress(buf);
|
||||
|
||||
// set MSS for segments server can receive
|
||||
if (proto.config->mss_inter > 0)
|
||||
MSSFix::mssfix(buf, proto.config->mss_inter);
|
||||
}
|
||||
else
|
||||
buf.reset_size(); // no crypto context available
|
||||
@@ -1607,6 +1680,15 @@ namespace openvpn {
|
||||
{
|
||||
case TLS_AUTH:
|
||||
return validate_tls_auth(recv, proto, now);
|
||||
case TLS_CRYPT_V2:
|
||||
if (opcode_extract(recv[0]) == CONTROL_HARD_RESET_CLIENT_V3)
|
||||
{
|
||||
// skip validation of HARD_RESET_V3 because the tls-crypt
|
||||
// engine has not been initialized yet
|
||||
OPENVPN_LOG_PROTO_VERBOSE("SKIPPING VALIDATION OF HARD_RESET_V3");
|
||||
return true;
|
||||
}
|
||||
/* no break */
|
||||
case TLS_CRYPT:
|
||||
return validate_tls_crypt(recv, proto, now);
|
||||
case TLS_PLAIN:
|
||||
@@ -1675,6 +1757,35 @@ namespace openvpn {
|
||||
|
||||
// cache op32 for hot path in do_encrypt
|
||||
cache_op32();
|
||||
|
||||
int crypto_encap = (enable_op32 ? OP_SIZE_V2 : 1) +
|
||||
c.comp_ctx.extra_payload_bytes() +
|
||||
PacketID::size(PacketID::SHORT_FORM) +
|
||||
c.dc.context().encap_overhead();
|
||||
|
||||
int transport_encap = 0;
|
||||
if (c.mss_parms.mtu)
|
||||
{
|
||||
if (proto.is_tcp())
|
||||
transport_encap += sizeof(struct TCPHeader);
|
||||
else
|
||||
transport_encap += sizeof(struct UDPHeader);
|
||||
|
||||
if (c.protocol.is_ipv6())
|
||||
transport_encap += sizeof(struct IPv6Header);
|
||||
else
|
||||
transport_encap += sizeof(struct IPv4Header);
|
||||
|
||||
transport_encap += c.protocol.extra_transport_bytes();
|
||||
}
|
||||
|
||||
if (c.mss_parms.mssfix != 0)
|
||||
{
|
||||
OPENVPN_LOG_PROTO("MTU mssfix=" << c.mss_parms.mssfix <<
|
||||
" crypto_encap=" << crypto_encap <<
|
||||
" transport_encap=" << transport_encap);
|
||||
c.mss_inter = c.mss_parms.mssfix - (crypto_encap + transport_encap);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1765,7 +1876,9 @@ namespace openvpn {
|
||||
work.inc_size(decrypt_bytes);
|
||||
|
||||
// verify HMAC
|
||||
if (!proto.tls_crypt_recv->hmac_cmp(orig_data, orig_size, work.c_data(), work.size()))
|
||||
if (!proto.tls_crypt_recv->hmac_cmp(orig_data,
|
||||
TLSCryptContext::hmac_offset,
|
||||
work.c_data(), work.size()))
|
||||
return false;
|
||||
|
||||
// verify source PSID
|
||||
@@ -1819,6 +1932,10 @@ namespace openvpn {
|
||||
{
|
||||
bool pid_wrap;
|
||||
|
||||
// set MSS for segments client can receive
|
||||
if (proto.config->mss_inter > 0)
|
||||
MSSFix::mssfix(buf, proto.config->mss_inter);
|
||||
|
||||
// compress packet
|
||||
if (compress)
|
||||
compress->compress(buf, compress_hint);
|
||||
@@ -1990,25 +2107,36 @@ namespace openvpn {
|
||||
set_event(ev);
|
||||
}
|
||||
|
||||
unsigned int initial_op(const bool sender) const
|
||||
unsigned int initial_op(const bool sender, const bool tls_crypt_v2) const
|
||||
{
|
||||
if (key_id_)
|
||||
return CONTROL_SOFT_RESET_V1;
|
||||
{
|
||||
return CONTROL_SOFT_RESET_V1;
|
||||
}
|
||||
else
|
||||
return (proto.is_server() == sender) ? CONTROL_HARD_RESET_SERVER_V2 : CONTROL_HARD_RESET_CLIENT_V2;
|
||||
{
|
||||
if (proto.is_server() == sender)
|
||||
return CONTROL_HARD_RESET_SERVER_V2;
|
||||
|
||||
if (!tls_crypt_v2)
|
||||
return CONTROL_HARD_RESET_CLIENT_V2;
|
||||
else
|
||||
return CONTROL_HARD_RESET_CLIENT_V3;
|
||||
}
|
||||
}
|
||||
|
||||
void send_reset()
|
||||
{
|
||||
Packet pkt;
|
||||
pkt.opcode = initial_op(true);
|
||||
pkt.opcode = initial_op(true, proto.tls_wrap_mode == TLS_CRYPT_V2);
|
||||
pkt.frame_prepare(*proto.config->frame, Frame::WRITE_SSL_INIT);
|
||||
raw_send(std::move(pkt));
|
||||
}
|
||||
|
||||
void raw_recv(Packet&& raw_pkt) // called by ProtoStackBase
|
||||
{
|
||||
if (raw_pkt.buf->empty() && raw_pkt.opcode == initial_op(false))
|
||||
if (raw_pkt.buf->empty() &&
|
||||
raw_pkt.opcode == initial_op(false, proto.tls_wrap_mode == TLS_CRYPT_V2))
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
@@ -2265,14 +2393,15 @@ namespace openvpn {
|
||||
// write opcode
|
||||
work.push_front(op_compose(opcode, key_id_));
|
||||
|
||||
// compute HMAC using header fields (from 'work') and plaintext payload (from 'buf')
|
||||
proto.tls_crypt_send->hmac_gen(work.data(), work.size(), buf.c_data(), buf.size());
|
||||
// compute HMAC using header fields (from 'work') and plaintext
|
||||
// payload (from 'buf')
|
||||
proto.tls_crypt_send->hmac_gen(work.data(), TLSCryptContext::hmac_offset,
|
||||
buf.c_data(), buf.size());
|
||||
|
||||
const size_t head_size = 1 + ProtoSessionID::SIZE + PacketID::size(PacketID::LONG_FORM);
|
||||
const size_t data_offset = head_size + proto.hmac_size;
|
||||
const size_t data_offset = TLSCryptContext::hmac_offset + proto.hmac_size;
|
||||
|
||||
// encrypt the content of 'buf' (packet payload) into 'work'
|
||||
const size_t decrypt_bytes = proto.tls_crypt_send->encrypt(work.c_data() + head_size,
|
||||
const size_t decrypt_bytes = proto.tls_crypt_send->encrypt(work.c_data() + TLSCryptContext::hmac_offset,
|
||||
work.data() + data_offset,
|
||||
work.max_size() - data_offset,
|
||||
buf.c_data(), buf.size());
|
||||
@@ -2283,6 +2412,11 @@ namespace openvpn {
|
||||
}
|
||||
work.inc_size(decrypt_bytes);
|
||||
|
||||
// append WKc to wrapped packet for tls-crypt-v2
|
||||
if ((opcode == CONTROL_HARD_RESET_CLIENT_V3)
|
||||
&& (proto.tls_wrap_mode == TLS_CRYPT_V2))
|
||||
proto.tls_crypt_append_wkc(work);
|
||||
|
||||
// 'work' now contains the complete packet ready to go. swap it with 'buf'
|
||||
buf.swap(work);
|
||||
}
|
||||
@@ -2303,6 +2437,7 @@ namespace openvpn {
|
||||
gen_head_tls_auth(opcode, buf);
|
||||
break;
|
||||
case TLS_CRYPT:
|
||||
case TLS_CRYPT_V2:
|
||||
gen_head_tls_crypt(opcode, buf);
|
||||
break;
|
||||
case TLS_PLAIN:
|
||||
@@ -2448,15 +2583,14 @@ namespace openvpn {
|
||||
// skip the hmac
|
||||
recv.advance(proto.hmac_size);
|
||||
|
||||
const size_t head_size = 1 + ProtoSessionID::SIZE + PacketID::size(PacketID::LONG_FORM);
|
||||
const size_t data_offset = head_size + proto.hmac_size;
|
||||
const size_t data_offset = TLSCryptContext::hmac_offset + proto.hmac_size;
|
||||
if (orig_size < data_offset)
|
||||
return false;
|
||||
|
||||
// decrypt payload
|
||||
proto.config->frame->prepare(Frame::DECRYPT_WORK, work);
|
||||
|
||||
const size_t decrypt_bytes = proto.tls_crypt_recv->decrypt(orig_data + head_size,
|
||||
const size_t decrypt_bytes = proto.tls_crypt_recv->decrypt(orig_data + TLSCryptContext::hmac_offset,
|
||||
work.data(), work.max_size(),
|
||||
recv.c_data(), recv.size());
|
||||
if (!decrypt_bytes)
|
||||
@@ -2470,7 +2604,8 @@ namespace openvpn {
|
||||
work.inc_size(decrypt_bytes);
|
||||
|
||||
// verify HMAC
|
||||
if (!proto.tls_crypt_recv->hmac_cmp(orig_data, orig_size, work.c_data(), work.size()))
|
||||
if (!proto.tls_crypt_recv->hmac_cmp(orig_data, TLSCryptContext::hmac_offset,
|
||||
work.c_data(), work.size()))
|
||||
{
|
||||
proto.stats->error(Error::HMAC_ERROR);
|
||||
if (proto.is_tcp())
|
||||
@@ -2528,6 +2663,100 @@ namespace openvpn {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool unwrap_tls_crypt_wkc(Buffer &recv)
|
||||
{
|
||||
// the ``WKc`` is located at the end of the packet, after the tls-crypt
|
||||
// payload.
|
||||
// Format is as follows (as documented by Steffan Krager):
|
||||
//
|
||||
// ``len = len(WKc)`` (16 bit, network byte order)
|
||||
// ``T = HMAC-SHA256(Ka, len || Kc || metadata)``
|
||||
// ``IV = 128 most significant bits of T``
|
||||
// ``WKc = T || AES-256-CTR(Ke, IV, Kc || metadata) || len``
|
||||
|
||||
const unsigned char *orig_data = recv.data();
|
||||
const size_t orig_size = recv.size();
|
||||
const size_t hmac_size = proto.config->tls_crypt_context->digest_size();
|
||||
const size_t tls_frame_size = 1 + ProtoSessionID::SIZE +
|
||||
PacketID::size(PacketID::LONG_FORM) +
|
||||
hmac_size +
|
||||
// the following is the tls-crypt payload
|
||||
sizeof(char) + // length of ACK array
|
||||
sizeof(id_t); // reliable ID
|
||||
|
||||
// check that at least the authentication tag ``T`` is present
|
||||
if (orig_size < (tls_frame_size + hmac_size))
|
||||
return false;
|
||||
|
||||
// the ``WKc`` is just appended after the standard tls-crypt frame
|
||||
const unsigned char *wkc_raw = orig_data + tls_frame_size;
|
||||
const size_t wkc_raw_size = orig_size - tls_frame_size - sizeof(uint16_t);
|
||||
// retrieve the ``WKc`` len from the bottom of the packet and convert it to Host Order
|
||||
uint16_t wkc_len = ntohs(*(uint16_t *)(wkc_raw + wkc_raw_size));
|
||||
// length sanity check (the size of the ``len`` field is included in the value)
|
||||
if ((wkc_len - sizeof(uint16_t)) != wkc_raw_size)
|
||||
return false;
|
||||
|
||||
BufferAllocated plaintext(wkc_len, BufferAllocated::CONSTRUCT_ZERO);
|
||||
// plaintext will be used to compute the Auth Tag, therefore start by prepnding
|
||||
// the WKc length in network order
|
||||
wkc_len = htons(wkc_len);
|
||||
plaintext.write(&wkc_len, sizeof(wkc_len));
|
||||
const size_t decrypt_bytes = proto.tls_crypt_server->decrypt(wkc_raw,
|
||||
plaintext.data() + 2,
|
||||
plaintext.max_size() - 2,
|
||||
wkc_raw + hmac_size,
|
||||
wkc_raw_size - hmac_size);
|
||||
plaintext.inc_size(decrypt_bytes);
|
||||
// decrypted data must at least contain a full 2048bits client key
|
||||
// (metadata is optional)
|
||||
if (plaintext.size() < OpenVPNStaticKey::KEY_SIZE)
|
||||
{
|
||||
proto.stats->error(Error::DECRYPT_ERROR);
|
||||
if (proto.is_tcp())
|
||||
invalidate(Error::DECRYPT_ERROR);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!proto.tls_crypt_server->hmac_cmp(wkc_raw, 0,
|
||||
plaintext.c_data(),
|
||||
plaintext.size()))
|
||||
{
|
||||
proto.stats->error(Error::HMAC_ERROR);
|
||||
if (proto.is_tcp())
|
||||
invalidate(Error::HMAC_ERROR);
|
||||
return false;
|
||||
}
|
||||
|
||||
// we can now remove the WKc length from the plaintext, as it is not
|
||||
// really part of the key material
|
||||
plaintext.advance(sizeof(wkc_len));
|
||||
|
||||
// WKc has been authenticated: it contains the client key followed
|
||||
// by the optional metadata. Let's initialize the tls-crypt context
|
||||
// with the client key
|
||||
|
||||
OpenVPNStaticKey client_key;
|
||||
plaintext.read(client_key.raw_alloc(), OpenVPNStaticKey::KEY_SIZE);
|
||||
proto.reset_tls_crypt(*proto.config, client_key);
|
||||
|
||||
// verify metadata
|
||||
int metadata_type = -1;
|
||||
if (!plaintext.empty())
|
||||
metadata_type = plaintext.pop_front();
|
||||
|
||||
if (!proto.tls_crypt_metadata->verify(metadata_type, plaintext))
|
||||
{
|
||||
proto.stats->error(Error::TLS_CRYPT_META_FAIL);
|
||||
return false;
|
||||
}
|
||||
|
||||
// virtually remove the WKc from the packet
|
||||
recv.set_size(tls_frame_size);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool decapsulate(Packet& pkt) // called by ProtoStackBase
|
||||
{
|
||||
try {
|
||||
@@ -2535,6 +2764,20 @@ namespace openvpn {
|
||||
{
|
||||
case TLS_AUTH:
|
||||
return decapsulate_tls_auth(pkt);
|
||||
case TLS_CRYPT_V2:
|
||||
if (pkt.opcode == CONTROL_HARD_RESET_CLIENT_V3)
|
||||
{
|
||||
// unwrap WKc and extract Kc (client key) from packet.
|
||||
// This way we can initialize the tls-crypt per-client contexts
|
||||
// (this happens on the server side only)
|
||||
if (!unwrap_tls_crypt_wkc(*pkt.buf))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// now that the tls-crypt contexts have been initialized it is
|
||||
// possible to proceed with the standard tls-crypt decapsulation
|
||||
/* no break */
|
||||
case TLS_CRYPT:
|
||||
return decapsulate_tls_crypt(pkt);
|
||||
case TLS_PLAIN:
|
||||
@@ -2724,15 +2967,14 @@ namespace openvpn {
|
||||
if (opcode_extract(op) != reset_op || key_id_extract(op) != 0)
|
||||
return false;
|
||||
|
||||
const size_t head_size = 1 + ProtoSessionID::SIZE + PacketID::size(PacketID::LONG_FORM);
|
||||
const size_t data_offset = head_size + tls_crypt_recv->output_hmac_size();
|
||||
const size_t data_offset = TLSCryptContext::hmac_offset + tls_crypt_recv->output_hmac_size();
|
||||
if (net_buf.size() < data_offset)
|
||||
return false;
|
||||
|
||||
frame->prepare(Frame::DECRYPT_WORK, work);
|
||||
|
||||
// decrypt payload from 'net_buf' into 'work'
|
||||
const size_t decrypt_bytes = tls_crypt_recv->decrypt(net_buf.c_data() + head_size,
|
||||
const size_t decrypt_bytes = tls_crypt_recv->decrypt(net_buf.c_data() + TLSCryptContext::hmac_offset,
|
||||
work.data(), work.max_size(),
|
||||
net_buf.c_data() + data_offset,
|
||||
net_buf.size() - data_offset);
|
||||
@@ -2742,7 +2984,8 @@ namespace openvpn {
|
||||
work.inc_size(decrypt_bytes);
|
||||
|
||||
// verify HMAC
|
||||
return tls_crypt_recv->hmac_cmp(net_buf.c_data(), net_buf.size(),
|
||||
return tls_crypt_recv->hmac_cmp(net_buf.c_data(),
|
||||
TLSCryptContext::hmac_offset,
|
||||
work.data(), work.size());
|
||||
}
|
||||
catch (BufferException&)
|
||||
@@ -2751,11 +2994,30 @@ namespace openvpn {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected:
|
||||
unsigned int reset_op;
|
||||
|
||||
private:
|
||||
TLSCryptInstance::Ptr tls_crypt_recv;
|
||||
Frame::Ptr frame;
|
||||
BufferAllocated work;
|
||||
unsigned int reset_op;
|
||||
};
|
||||
|
||||
class TLSCryptV2PreValidate : public TLSCryptPreValidate
|
||||
{
|
||||
public:
|
||||
OPENVPN_SIMPLE_EXCEPTION(tls_crypt_v2_pre_validate);
|
||||
|
||||
TLSCryptV2PreValidate(const Config& c, const bool server)
|
||||
: TLSCryptPreValidate(c, server)
|
||||
{
|
||||
if (!c.tls_crypt_v2_enabled())
|
||||
throw tls_crypt_v2_pre_validate();
|
||||
|
||||
// in case of server peer, we expect the new v3 packet type
|
||||
if (server)
|
||||
reset_op = CONTROL_HARD_RESET_CLIENT_V3;
|
||||
}
|
||||
};
|
||||
|
||||
OPENVPN_SIMPLE_EXCEPTION(select_key_context_error);
|
||||
@@ -2771,20 +3033,27 @@ namespace openvpn {
|
||||
const Config& c = *config;
|
||||
|
||||
// tls-auth setup
|
||||
if (c.tls_auth_context)
|
||||
if (c.tls_crypt_v2_enabled())
|
||||
{
|
||||
tls_wrap_mode = TLS_AUTH;
|
||||
tls_wrap_mode = TLS_CRYPT_V2;
|
||||
|
||||
// get HMAC size from Digest object
|
||||
hmac_size = c.tls_auth_context->size();
|
||||
hmac_size = c.tls_crypt_context->digest_size();
|
||||
}
|
||||
else if (c.tls_crypt_context)
|
||||
else if (c.tls_crypt_enabled())
|
||||
{
|
||||
tls_wrap_mode = TLS_CRYPT;
|
||||
|
||||
// get HMAC size from Digest object
|
||||
hmac_size = c.tls_crypt_context->digest_size();
|
||||
}
|
||||
else if (c.tls_auth_enabled())
|
||||
{
|
||||
tls_wrap_mode = TLS_AUTH;
|
||||
|
||||
// get HMAC size from Digest object
|
||||
hmac_size = c.tls_auth_context->size();
|
||||
}
|
||||
else
|
||||
{
|
||||
tls_wrap_mode = TLS_PLAIN;
|
||||
@@ -2801,6 +3070,43 @@ namespace openvpn {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void reset_tls_crypt(const Config& c, const OpenVPNStaticKey& key)
|
||||
{
|
||||
tls_crypt_send = c.tls_crypt_context->new_obj_send();
|
||||
tls_crypt_recv = c.tls_crypt_context->new_obj_recv();
|
||||
|
||||
// static direction assignment - not user configurable
|
||||
unsigned int key_dir = is_server() ?
|
||||
OpenVPNStaticKey::NORMAL :
|
||||
OpenVPNStaticKey::INVERSE;
|
||||
|
||||
tls_crypt_send->init(key.slice(OpenVPNStaticKey::HMAC |
|
||||
OpenVPNStaticKey::ENCRYPT | key_dir),
|
||||
key.slice(OpenVPNStaticKey::CIPHER |
|
||||
OpenVPNStaticKey::ENCRYPT | key_dir));
|
||||
tls_crypt_recv->init(key.slice(OpenVPNStaticKey::HMAC |
|
||||
OpenVPNStaticKey::DECRYPT | key_dir),
|
||||
key.slice(OpenVPNStaticKey::CIPHER |
|
||||
OpenVPNStaticKey::DECRYPT | key_dir));
|
||||
}
|
||||
|
||||
void reset_tls_crypt_server(const Config& c)
|
||||
{
|
||||
//tls-crypt session key is derived later from WKc received from the client
|
||||
tls_crypt_send.reset();
|
||||
tls_crypt_recv.reset();
|
||||
|
||||
//server context is used only to process incoming WKc's
|
||||
tls_crypt_server = c.tls_crypt_context->new_obj_recv();
|
||||
|
||||
//the server key is composed by one key set only, therefore direction and
|
||||
//mode should not be specified when slicing
|
||||
tls_crypt_server->init(c.tls_key.slice(OpenVPNStaticKey::HMAC),
|
||||
c.tls_key.slice(OpenVPNStaticKey::CIPHER));
|
||||
|
||||
tls_crypt_metadata = c.tls_crypt_metadata_factory->new_obj();
|
||||
}
|
||||
|
||||
void reset()
|
||||
{
|
||||
const Config& c = *config;
|
||||
@@ -2820,16 +3126,19 @@ namespace openvpn {
|
||||
switch (tls_wrap_mode)
|
||||
{
|
||||
case TLS_CRYPT:
|
||||
tls_crypt_send = c.tls_crypt_context->new_obj_send();
|
||||
tls_crypt_recv = c.tls_crypt_context->new_obj_recv();
|
||||
|
||||
// static direction assignment - not user configurable
|
||||
key_dir = is_server() ? OpenVPNStaticKey::NORMAL : OpenVPNStaticKey::INVERSE;
|
||||
tls_crypt_send->init(c.tls_key.slice(OpenVPNStaticKey::HMAC | OpenVPNStaticKey::ENCRYPT | key_dir),
|
||||
c.tls_key.slice(OpenVPNStaticKey::CIPHER | OpenVPNStaticKey::ENCRYPT | key_dir));
|
||||
tls_crypt_recv->init(c.tls_key.slice(OpenVPNStaticKey::HMAC | OpenVPNStaticKey::DECRYPT | key_dir),
|
||||
c.tls_key.slice(OpenVPNStaticKey::CIPHER | OpenVPNStaticKey::DECRYPT | key_dir));
|
||||
|
||||
reset_tls_crypt(c, c.tls_key);
|
||||
// init tls_crypt packet ID
|
||||
ta_pid_send.init(PacketID::LONG_FORM);
|
||||
ta_pid_recv.init(c.pid_mode, PacketID::LONG_FORM, "SSL-CC", 0, stats);
|
||||
break;
|
||||
case TLS_CRYPT_V2:
|
||||
if (is_server())
|
||||
// setup key to be used to unwrap WKc upon client connection.
|
||||
// tls-crypt session key setup is postponed to reception of WKc
|
||||
// from client
|
||||
reset_tls_crypt_server(c);
|
||||
else
|
||||
reset_tls_crypt(c, c.tls_key);
|
||||
// init tls_crypt packet ID
|
||||
ta_pid_send.init(PacketID::LONG_FORM);
|
||||
ta_pid_recv.init(c.pid_mode, PacketID::LONG_FORM, "SSL-CC", 0, stats);
|
||||
@@ -2860,7 +3169,7 @@ namespace openvpn {
|
||||
break;
|
||||
case TLS_PLAIN:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// initialize proto session ID
|
||||
psid_self.randomize(*c.prng);
|
||||
@@ -3199,7 +3508,8 @@ namespace openvpn {
|
||||
enum TLSWrapMode {
|
||||
TLS_PLAIN,
|
||||
TLS_AUTH,
|
||||
TLS_CRYPT
|
||||
TLS_CRYPT,
|
||||
TLS_CRYPT_V2
|
||||
};
|
||||
|
||||
void reset_all()
|
||||
@@ -3483,6 +3793,13 @@ namespace openvpn {
|
||||
keepalive_xmit = kx;
|
||||
}
|
||||
|
||||
void tls_crypt_append_wkc(BufferAllocated& dst)
|
||||
{
|
||||
if (!config->wkc.defined())
|
||||
throw proto_error("Client Key Wrapper undefined");
|
||||
dst.append(config->wkc);
|
||||
}
|
||||
|
||||
// BEGIN ProtoContext data members
|
||||
|
||||
Config::Ptr config;
|
||||
@@ -3506,6 +3823,9 @@ namespace openvpn {
|
||||
TLSCryptInstance::Ptr tls_crypt_send;
|
||||
TLSCryptInstance::Ptr tls_crypt_recv;
|
||||
|
||||
TLSCryptInstance::Ptr tls_crypt_server;
|
||||
TLSCryptMetadata::Ptr tls_crypt_metadata;
|
||||
|
||||
PacketIDSend ta_pid_send;
|
||||
PacketIDReceive ta_pid_recv;
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <openvpn/openssl/crypto/api.hpp>
|
||||
#include <openvpn/openssl/ssl/sslctx.hpp>
|
||||
#include <openvpn/openssl/util/rand.hpp>
|
||||
#include <openvpn/openssl/util/pem.hpp>
|
||||
#endif
|
||||
|
||||
#ifdef USE_APPLE_SSL
|
||||
@@ -46,6 +47,7 @@
|
||||
#ifdef OPENVPN_PLATFORM_UWP
|
||||
#include <openvpn/mbedtls/util/uwprand.hpp>
|
||||
#endif
|
||||
#include <openvpn/mbedtls/util/pem.hpp>
|
||||
#endif
|
||||
|
||||
#ifdef USE_MBEDTLS_APPLE_HYBRID
|
||||
@@ -69,6 +71,7 @@ namespace openvpn {
|
||||
#else
|
||||
typedef MbedTLSRandom RandomAPI;
|
||||
#endif
|
||||
typedef MbedTLSPEM PEMAPI;
|
||||
#elif defined(USE_MBEDTLS_APPLE_HYBRID)
|
||||
// Uses Apple framework for CryptoAPI and MbedTLS for SSLAPI and RandomAPI
|
||||
#define SSL_LIB_NAME "MbedTLSAppleHybrid"
|
||||
@@ -85,6 +88,7 @@ namespace openvpn {
|
||||
typedef OpenSSLCryptoAPI CryptoAPI;
|
||||
typedef OpenSSLContext SSLAPI;
|
||||
typedef OpenSSLRandom RandomAPI;
|
||||
typedef OpenSSLPEM PEMAPI;
|
||||
#else
|
||||
#error no SSL library defined
|
||||
#endif
|
||||
|
||||
78
openvpn/time/asiotimersafe.hpp
Normal file
78
openvpn/time/asiotimersafe.hpp
Normal file
@@ -0,0 +1,78 @@
|
||||
// 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-2017 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <openvpn/time/asiotimer.hpp>
|
||||
|
||||
// AsioTimerSafe is like AsioTimer but with an epoch counter
|
||||
// that allows a handler to determine if it is the most recent
|
||||
// handler to be queued.
|
||||
|
||||
namespace openvpn {
|
||||
class AsioTimerSafe
|
||||
{
|
||||
public:
|
||||
typedef std::size_t epoch_t;
|
||||
|
||||
AsioTimerSafe(openvpn_io::io_context& io_context)
|
||||
: timer_(io_context)
|
||||
{
|
||||
}
|
||||
|
||||
std::size_t expires_at(const Time& t)
|
||||
{
|
||||
++epoch_;
|
||||
return timer_.expires_at(t);
|
||||
}
|
||||
|
||||
std::size_t expires_after(const Time::Duration& d)
|
||||
{
|
||||
++epoch_;
|
||||
return timer_.expires_after(d);
|
||||
}
|
||||
|
||||
std::size_t cancel()
|
||||
{
|
||||
++epoch_;
|
||||
return timer_.cancel();
|
||||
}
|
||||
|
||||
epoch_t epoch() const
|
||||
{
|
||||
return epoch_;
|
||||
}
|
||||
|
||||
template <typename F>
|
||||
void async_wait(F&& func)
|
||||
{
|
||||
++epoch_;
|
||||
timer_.async_wait([func=std::move(func), epoch=epoch_](const openvpn_io::error_code& error) mutable
|
||||
{
|
||||
func(error, epoch);
|
||||
});
|
||||
}
|
||||
|
||||
private:
|
||||
AsioTimer timer_;
|
||||
epoch_t epoch_ = 0;
|
||||
};
|
||||
}
|
||||
@@ -916,7 +916,7 @@ namespace openvpn {
|
||||
#ifdef OPENVPN_PLATFORM_TYPE_UNIX
|
||||
if (config->socket_protect)
|
||||
{
|
||||
if (!config->socket_protect->socket_protect(socket.native_handle()))
|
||||
if (!config->socket_protect->socket_protect(socket.native_handle(), server_endpoint_addr()))
|
||||
{
|
||||
config->stats->error(Error::SOCKET_PROTECT_ERROR);
|
||||
stop();
|
||||
|
||||
@@ -287,7 +287,7 @@ namespace openvpn {
|
||||
#if defined(OPENVPN_PLATFORM_TYPE_UNIX) || defined(OPENVPN_PLATFORM_UWP)
|
||||
if (config->socket_protect)
|
||||
{
|
||||
if (!config->socket_protect->socket_protect(socket.native_handle()))
|
||||
if (!config->socket_protect->socket_protect(socket.native_handle(), server_endpoint_addr()))
|
||||
{
|
||||
config->stats->error(Error::SOCKET_PROTECT_ERROR);
|
||||
stop();
|
||||
|
||||
@@ -91,6 +91,8 @@ namespace openvpn {
|
||||
// the keepalive parameters (in seconds).
|
||||
virtual void disable_keepalive(unsigned int& keepalive_ping,
|
||||
unsigned int& keepalive_timeout) = 0;
|
||||
|
||||
virtual ~TransportClientParent() {}
|
||||
};
|
||||
|
||||
// Factory for client transport object.
|
||||
|
||||
@@ -181,8 +181,7 @@ namespace openvpn {
|
||||
Client(openvpn_io::io_context& io_context_arg,
|
||||
ClientConfig* config_arg,
|
||||
TransportClientParent* parent_arg)
|
||||
: io_context(io_context_arg),
|
||||
socket(io_context_arg),
|
||||
: socket(io_context_arg),
|
||||
config(config_arg),
|
||||
parent(parent_arg),
|
||||
resolver(io_context_arg),
|
||||
@@ -274,7 +273,7 @@ namespace openvpn {
|
||||
#if defined(OPENVPN_PLATFORM_TYPE_UNIX) || defined(OPENVPN_PLATFORM_UWP)
|
||||
if (config->socket_protect)
|
||||
{
|
||||
if (!config->socket_protect->socket_protect(socket.native_handle()))
|
||||
if (!config->socket_protect->socket_protect(socket.native_handle(), server_endpoint_addr()))
|
||||
{
|
||||
config->stats->error(Error::SOCKET_PROTECT_ERROR);
|
||||
stop();
|
||||
@@ -321,7 +320,6 @@ namespace openvpn {
|
||||
std::string server_host;
|
||||
std::string server_port;
|
||||
|
||||
openvpn_io::io_context& io_context;
|
||||
openvpn_io::ip::udp::socket socket;
|
||||
ClientConfig::Ptr config;
|
||||
TransportClientParent* parent;
|
||||
|
||||
150
openvpn/transport/mssfix.hpp
Normal file
150
openvpn/transport/mssfix.hpp
Normal file
@@ -0,0 +1,150 @@
|
||||
// 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-2018 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <openvpn/buffer/buffer.hpp>
|
||||
#include <openvpn/ip/ipcommon.hpp>
|
||||
#include <openvpn/ip/ip4.hpp>
|
||||
#include <openvpn/ip/ip6.hpp>
|
||||
#include <openvpn/ip/tcp.hpp>
|
||||
|
||||
#if OPENVPN_DEBUG_PROTO >= 2
|
||||
#define OPENVPN_LOG_MSSFIX(x) OPENVPN_LOG(x)
|
||||
#else
|
||||
#define OPENVPN_LOG_MSSFIX(x)
|
||||
#endif
|
||||
|
||||
namespace openvpn {
|
||||
class MSSFix {
|
||||
public:
|
||||
static void mssfix(BufferAllocated& buf, int mss_inter)
|
||||
{
|
||||
if (buf.empty())
|
||||
return;
|
||||
|
||||
switch (IPCommon::version(buf[0]))
|
||||
{
|
||||
case IPCommon::IPv4:
|
||||
{
|
||||
if (buf.length() <= sizeof(struct IPv4Header))
|
||||
break;
|
||||
|
||||
const IPv4Header *iphdr = (const IPv4Header *)buf.c_data();
|
||||
|
||||
auto ipv4hlen = IPv4Header::length(iphdr->version_len);
|
||||
|
||||
if (iphdr->protocol == IPCommon::TCP &&
|
||||
ntohs(iphdr->tot_len) == buf.length() &&
|
||||
(ntohs(iphdr->frag_off) & IPv4Header::OFFMASK) == 0 &&
|
||||
ipv4hlen <= buf.length() &&
|
||||
buf.length() - ipv4hlen >= sizeof(struct TCPHeader))
|
||||
{
|
||||
TCPHeader* tcphdr = (TCPHeader*)(buf.data() + ipv4hlen);
|
||||
int ip_payload_len = buf.length() - ipv4hlen;
|
||||
|
||||
do_mssfix(tcphdr, mss_inter - (sizeof(struct IPv4Header) + sizeof(struct TCPHeader)), ip_payload_len);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case IPCommon::IPv6:
|
||||
{
|
||||
if (buf.length() <= sizeof(struct IPv6Header))
|
||||
break;
|
||||
|
||||
const IPv6Header *iphdr = (const IPv6Header *)buf.c_data();
|
||||
|
||||
if (buf.length() != ntohs(iphdr->payload_len) + sizeof(struct IPv6Header))
|
||||
break;
|
||||
|
||||
/* follow header chain until we reach final header, then check for TCP
|
||||
*
|
||||
* An IPv6 packet could, theoretically, have a chain of multiple headers
|
||||
* before the final header (TCP, UDP, ...), so we'd need to walk that
|
||||
* chain (see RFC 2460 and RFC 6564 for details).
|
||||
*
|
||||
* In practice, "most typically used" extention headers (AH, routing,
|
||||
* fragment, mobility) are very unlikely to be seen inside an OpenVPN
|
||||
* tun, so for now, we only handle the case of "single next header = TCP"
|
||||
*/
|
||||
if (iphdr->nexthdr != IPCommon::TCP)
|
||||
break;
|
||||
|
||||
/* skip IPv6 header (40 bytes),
|
||||
* verify remainder is large enough to contain a full TCP header
|
||||
*/
|
||||
int payload_len = buf.length() - sizeof(struct IPv6Header);
|
||||
if (payload_len >= (int) sizeof(struct TCPHeader))
|
||||
{
|
||||
TCPHeader *tcphdr = (TCPHeader *)(buf.data() + sizeof(struct IPv6Header));
|
||||
do_mssfix(tcphdr, mss_inter - (sizeof(struct IPv6Header) + sizeof(struct TCPHeader)),
|
||||
payload_len);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
static void do_mssfix(TCPHeader *tcphdr, int max_mss, int ip_payload_len)
|
||||
{
|
||||
if ((tcphdr->flags & TCPHeader::FLAG_SYN) == 0)
|
||||
return;
|
||||
|
||||
int tcphlen = TCPHeader::length(tcphdr->doff_res);
|
||||
if (tcphlen <= (int) sizeof(struct TCPHeader) || tcphlen > ip_payload_len)
|
||||
return;
|
||||
|
||||
int olen, optlen; // length of options field and Option-Length
|
||||
uint8_t *opt; // option type
|
||||
|
||||
for (olen = tcphlen - sizeof(struct TCPHeader), opt = (uint8_t *)(tcphdr + 1);
|
||||
olen > 1;
|
||||
olen -= optlen, opt += optlen)
|
||||
{
|
||||
if (*opt == TCPHeader::OPT_EOL)
|
||||
break;
|
||||
else if (*opt == TCPHeader::OPT_NOP)
|
||||
optlen = 1;
|
||||
else
|
||||
{
|
||||
optlen = *(opt + 1);
|
||||
if (optlen <= 0 || optlen > olen)
|
||||
break;
|
||||
if ((*opt == TCPHeader::OPT_MAXSEG) && (optlen == TCPHeader::OPTLEN_MAXSEG))
|
||||
{
|
||||
uint16_t mssval = (opt[2] << 8) + opt[3];
|
||||
if (mssval > max_mss)
|
||||
{
|
||||
OPENVPN_LOG_MSSFIX("MTU MSS " << mssval << " -> " << max_mss);
|
||||
int accumulate = htons(mssval);
|
||||
opt[2] = (max_mss >> 8) & 0xff;
|
||||
opt[3] = max_mss & 0xff;
|
||||
accumulate -= htons(max_mss);
|
||||
tcp_adjust_checksum(accumulate, tcphdr->check);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -22,6 +22,7 @@
|
||||
#ifndef OPENVPN_TRANSPORT_SOCKET_PROTECT_H
|
||||
#define OPENVPN_TRANSPORT_SOCKET_PROTECT_H
|
||||
|
||||
#include <openvpn/addr/ip.hpp>
|
||||
#ifdef OPENVPN_PLATFORM_UWP
|
||||
#include <openvpn/transport/uwp_socket_protect.hpp>
|
||||
#endif
|
||||
@@ -33,7 +34,7 @@ namespace openvpn {
|
||||
// the socket from being routed into the VPN tunnel.
|
||||
class BaseSocketProtect {
|
||||
public:
|
||||
virtual bool socket_protect(int socket) = 0;
|
||||
virtual bool socket_protect(int socket, IP::Addr endpoint) = 0;
|
||||
};
|
||||
|
||||
#ifdef OPENVPN_PLATFORM_UWP
|
||||
|
||||
@@ -342,7 +342,7 @@ namespace openvpn {
|
||||
{
|
||||
try {
|
||||
if (defined())
|
||||
URL::Parse(url);
|
||||
(URL::Parse(url));
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
|
||||
@@ -485,7 +485,7 @@ namespace openvpn {
|
||||
const Option& o = opt[*i];
|
||||
try {
|
||||
const std::string& type = o.get(1, 64);
|
||||
if (type == "DNS")
|
||||
if (type == "DNS" || type == "DNS6")
|
||||
{
|
||||
o.exact_args(3);
|
||||
const IP::Addr ip = IP::Addr::from_string(o.get(2, 256), "dns-server-ip");
|
||||
|
||||
917
openvpn/tun/linux/client/sitnl.hpp
Normal file
917
openvpn/tun/linux/client/sitnl.hpp
Normal file
@@ -0,0 +1,917 @@
|
||||
// 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-2018 OpenVPN Inc.
|
||||
// Copyright (C) 2018 Antonio Quartulli <antonio@openvpn.net>
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <linux/netlink.h>
|
||||
#include <linux/rtnetlink.h>
|
||||
|
||||
#include <openvpn/addr/ip.hpp>
|
||||
#include <openvpn/addr/ipv4.hpp>
|
||||
#include <openvpn/addr/ipv6.hpp>
|
||||
#include <openvpn/addr/route.hpp>
|
||||
|
||||
|
||||
#ifdef DEBUG_RTNL
|
||||
#define OPENVPN_LOG_RTNL(_x) OPENVPN_LOG(_x)
|
||||
#else
|
||||
#define OPENVPN_LOG_RTNL(_x)
|
||||
#endif
|
||||
|
||||
namespace openvpn {
|
||||
namespace TunNetlink {
|
||||
|
||||
#define SNDBUF_SIZE (1024 * 2)
|
||||
#define RCVBUF_SIZE (1024 * 4)
|
||||
|
||||
#define SITNL_ADDATTR(_msg, _max_size, _attr, _data, _size) \
|
||||
{ \
|
||||
if (sitnl_addattr(_msg, _max_size, _attr, _data, _size) < 0)\
|
||||
{ \
|
||||
goto err; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define NLMSG_TAIL(nmsg) \
|
||||
((struct rtattr *)(((uint8_t *)(nmsg)) + NLMSG_ALIGN((nmsg)->nlmsg_len)))
|
||||
|
||||
/* this class contains only static members */
|
||||
class SITNL
|
||||
{
|
||||
private:
|
||||
/**
|
||||
* Link state request message
|
||||
*/
|
||||
struct sitnl_link_req
|
||||
{
|
||||
struct nlmsghdr n;
|
||||
struct ifinfomsg i;
|
||||
char buf[256];
|
||||
};
|
||||
|
||||
/**
|
||||
* Address request message
|
||||
*/
|
||||
struct sitnl_addr_req
|
||||
{
|
||||
struct nlmsghdr n;
|
||||
struct ifaddrmsg i;
|
||||
char buf[256];
|
||||
};
|
||||
|
||||
/**
|
||||
* Route request message
|
||||
*/
|
||||
struct sitnl_route_req
|
||||
{
|
||||
struct nlmsghdr n;
|
||||
struct rtmsg r;
|
||||
char buf[256];
|
||||
};
|
||||
|
||||
typedef int (*sitnl_parse_reply_cb)(struct nlmsghdr *msg, void *arg);
|
||||
|
||||
/**
|
||||
* Helper function used to easily add attributes to a rtnl message
|
||||
*/
|
||||
static int
|
||||
sitnl_addattr(struct nlmsghdr *n, int maxlen, int type, const void *data,
|
||||
int alen)
|
||||
{
|
||||
int len = RTA_LENGTH(alen);
|
||||
struct rtattr *rta;
|
||||
|
||||
if ((int)(NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len)) > maxlen)
|
||||
{
|
||||
OPENVPN_LOG(__func__ << ": rtnl: message exceeded bound of " << maxlen);
|
||||
return -EMSGSIZE;
|
||||
}
|
||||
|
||||
rta = NLMSG_TAIL(n);
|
||||
rta->rta_type = type;
|
||||
rta->rta_len = len;
|
||||
|
||||
if (!data)
|
||||
{
|
||||
memset(RTA_DATA(rta), 0, alen);
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(RTA_DATA(rta), data, alen);
|
||||
}
|
||||
|
||||
n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Open RTNL socket
|
||||
*/
|
||||
static int
|
||||
sitnl_socket(void)
|
||||
{
|
||||
int sndbuf = SNDBUF_SIZE;
|
||||
int rcvbuf = RCVBUF_SIZE;
|
||||
int fd;
|
||||
|
||||
fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
|
||||
if (fd < 0)
|
||||
{
|
||||
OPENVPN_LOG(__func__ << ": cannot open netlink socket");
|
||||
return fd;
|
||||
}
|
||||
|
||||
if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(sndbuf)) < 0)
|
||||
{
|
||||
OPENVPN_LOG(__func__ << ": SO_SNDBUF");
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(rcvbuf)) < 0)
|
||||
{
|
||||
OPENVPN_LOG(__func__ << ": SO_RCVBUF");
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
/**
|
||||
* Bind socket to Netlink subsystem
|
||||
*/
|
||||
static int
|
||||
sitnl_bind(int fd, uint32_t groups)
|
||||
{
|
||||
socklen_t addr_len;
|
||||
struct sockaddr_nl local = { };
|
||||
|
||||
local.nl_family = AF_NETLINK;
|
||||
local.nl_groups = groups;
|
||||
|
||||
if (bind(fd, (struct sockaddr *)&local, sizeof(local)) < 0)
|
||||
{
|
||||
OPENVPN_LOG(__func__ << ": cannot bind netlink socket");
|
||||
return -errno;
|
||||
}
|
||||
|
||||
addr_len = sizeof(local);
|
||||
if (getsockname(fd, (struct sockaddr *)&local, &addr_len) < 0)
|
||||
{
|
||||
OPENVPN_LOG(__func__ << ": cannot getsockname");
|
||||
return -errno;
|
||||
}
|
||||
|
||||
if (addr_len != sizeof(local))
|
||||
{
|
||||
OPENVPN_LOG(__func__ << ": wrong address length " << addr_len);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (local.nl_family != AF_NETLINK)
|
||||
{
|
||||
OPENVPN_LOG(__func__ << ": wrong address family " << local.nl_family);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send Netlink message and run callback on reply (if specified)
|
||||
*/
|
||||
static int
|
||||
sitnl_send(struct nlmsghdr *payload, pid_t peer, unsigned int groups,
|
||||
sitnl_parse_reply_cb cb, void *arg_cb)
|
||||
{
|
||||
int len, rem_len, fd, ret, rcv_len;
|
||||
struct sockaddr_nl nladdr = { };
|
||||
struct nlmsgerr *err;
|
||||
struct nlmsghdr *h;
|
||||
unsigned int seq;
|
||||
char buf[1024 * 16];
|
||||
struct iovec iov =
|
||||
{
|
||||
.iov_base = payload,
|
||||
.iov_len = payload->nlmsg_len,
|
||||
};
|
||||
struct msghdr nlmsg =
|
||||
{
|
||||
.msg_name = &nladdr,
|
||||
.msg_namelen = sizeof(nladdr),
|
||||
.msg_iov = &iov,
|
||||
.msg_iovlen = 1,
|
||||
};
|
||||
|
||||
nladdr.nl_family = AF_NETLINK;
|
||||
nladdr.nl_pid = peer;
|
||||
nladdr.nl_groups = groups;
|
||||
|
||||
payload->nlmsg_seq = seq = time(NULL);
|
||||
|
||||
/* no need to send reply */
|
||||
if (!cb)
|
||||
{
|
||||
payload->nlmsg_flags |= NLM_F_ACK;
|
||||
}
|
||||
|
||||
fd = sitnl_socket();
|
||||
if (fd < 0)
|
||||
{
|
||||
OPENVPN_LOG(__func__ << ": can't open rtnl socket");
|
||||
return -errno;
|
||||
}
|
||||
|
||||
ret = sitnl_bind(fd, 0);
|
||||
if (ret < 0)
|
||||
{
|
||||
OPENVPN_LOG(__func__ << ": can't bind rtnl socket");
|
||||
ret = -errno;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = sendmsg(fd, &nlmsg, 0);
|
||||
if (ret < 0)
|
||||
{
|
||||
OPENVPN_LOG(__func__ << ": rtnl: error on sendmsg()");
|
||||
ret = -errno;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* prepare buffer to store RTNL replies */
|
||||
memset(buf, 0, sizeof(buf));
|
||||
iov.iov_base = buf;
|
||||
|
||||
while (1)
|
||||
{
|
||||
/*
|
||||
* iov_len is modified by recvmsg(), therefore has to be initialized before
|
||||
* using it again
|
||||
*/
|
||||
OPENVPN_LOG_RTNL(__func__ << ": checking for received messages");
|
||||
iov.iov_len = sizeof(buf);
|
||||
rcv_len = recvmsg(fd, &nlmsg, 0);
|
||||
OPENVPN_LOG_RTNL(__func__ << ": rtnl: received " << rcv_len << " bytes");
|
||||
if (rcv_len < 0)
|
||||
{
|
||||
if ((errno == EINTR) || (errno == EAGAIN))
|
||||
{
|
||||
OPENVPN_LOG(__func__ << ": interrupted call");
|
||||
continue;
|
||||
}
|
||||
OPENVPN_LOG(__func__ << ": rtnl: error on recvmsg()");
|
||||
ret = -errno;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (rcv_len == 0)
|
||||
{
|
||||
OPENVPN_LOG(__func__ << ": rtnl: socket reached unexpected EOF");
|
||||
ret = -EIO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (nlmsg.msg_namelen != sizeof(nladdr))
|
||||
{
|
||||
OPENVPN_LOG(__func__ << ": sender address length: "
|
||||
<< nlmsg.msg_namelen << " (expected " << sizeof(nladdr)
|
||||
<< ")");
|
||||
ret = -EIO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
h = (struct nlmsghdr *)buf;
|
||||
while (rcv_len >= (int)sizeof(*h))
|
||||
{
|
||||
len = h->nlmsg_len;
|
||||
rem_len = len - sizeof(*h);
|
||||
|
||||
if ((rem_len < 0) || (len > rcv_len))
|
||||
{
|
||||
if (nlmsg.msg_flags & MSG_TRUNC)
|
||||
{
|
||||
OPENVPN_LOG(__func__ << ": truncated message");
|
||||
ret = -EIO;
|
||||
goto out;
|
||||
}
|
||||
OPENVPN_LOG(__func__ << ": malformed message: len=" << len);
|
||||
ret = -EIO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (h->nlmsg_type == NLMSG_ERROR)
|
||||
{
|
||||
err = (struct nlmsgerr *)NLMSG_DATA(h);
|
||||
if (rem_len < (int)sizeof(struct nlmsgerr))
|
||||
{
|
||||
OPENVPN_LOG(__func__ << ": ERROR truncated");
|
||||
ret = -EIO;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!err->error)
|
||||
{
|
||||
ret = 0;
|
||||
if (cb)
|
||||
ret = cb(h, arg_cb);
|
||||
}
|
||||
else
|
||||
{
|
||||
OPENVPN_LOG(__func__ << ": rtnl: generic error: "
|
||||
<< strerror(-err->error)
|
||||
<< " (" << err->error << ")");
|
||||
ret = err->error;
|
||||
}
|
||||
}
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (cb)
|
||||
{
|
||||
ret = cb(h, arg_cb);
|
||||
goto out;
|
||||
}
|
||||
else
|
||||
{
|
||||
OPENVPN_LOG(__func__ << ": RTNL: unexpected reply");
|
||||
}
|
||||
|
||||
rcv_len -= NLMSG_ALIGN(len);
|
||||
h = (struct nlmsghdr *)((char *)h + NLMSG_ALIGN(len));
|
||||
}
|
||||
|
||||
if (nlmsg.msg_flags & MSG_TRUNC)
|
||||
{
|
||||
OPENVPN_LOG(__func__ << ": message truncated");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (rcv_len)
|
||||
{
|
||||
OPENVPN_LOG(__func__ << ": rtnl: " << rcv_len
|
||||
<< " not parsed bytes");
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
out:
|
||||
close(fd);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* store the route entry resulting from the query */
|
||||
typedef struct
|
||||
{
|
||||
sa_family_t family;
|
||||
IP::Addr gw;
|
||||
std::string iface;
|
||||
} route_res_t;
|
||||
|
||||
static int
|
||||
sitnl_route_save(struct nlmsghdr *n, void *arg)
|
||||
{
|
||||
route_res_t *res = (route_res_t *)arg;
|
||||
struct rtmsg *r = (struct rtmsg *)NLMSG_DATA(n);
|
||||
struct rtattr *rta = RTM_RTA(r);
|
||||
int len = n->nlmsg_len - NLMSG_LENGTH(sizeof(*r));
|
||||
int ifindex = 0;
|
||||
|
||||
while (RTA_OK(rta, len))
|
||||
{
|
||||
switch (rta->rta_type)
|
||||
{
|
||||
case RTA_OIF:
|
||||
/* route interface */
|
||||
ifindex = *(unsigned int *)RTA_DATA(rta);
|
||||
break;
|
||||
case RTA_DST:
|
||||
/* route prefix */
|
||||
RTA_DATA(rta);
|
||||
break;
|
||||
case RTA_GATEWAY:
|
||||
/* GW for the route */
|
||||
{
|
||||
const unsigned char *bytestr = (unsigned char *)RTA_DATA(rta);
|
||||
switch (res->family)
|
||||
{
|
||||
case AF_INET:
|
||||
res->gw = IP::Addr::from_ipv4(IPv4::Addr::from_bytes_net(bytestr));
|
||||
break;
|
||||
case AF_INET6:
|
||||
res->gw = IP::Addr::from_ipv6(IPv6::Addr::from_byte_string(bytestr));
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
rta = RTA_NEXT(rta, len);
|
||||
}
|
||||
|
||||
if (ifindex > 0)
|
||||
{
|
||||
char iface[IFNAMSIZ];
|
||||
if (!if_indextoname(ifindex, iface))
|
||||
{
|
||||
OPENVPN_LOG(__func__ << ": rtnl: can't get ifname for index "
|
||||
<< ifindex);
|
||||
return -1;
|
||||
}
|
||||
|
||||
res->iface = iface;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
sitnl_route_best_gw(const IP::Route& route, IP::Addr& best_gw,
|
||||
std::string& best_iface)
|
||||
{
|
||||
struct sitnl_route_req req = { };
|
||||
route_res_t res;
|
||||
int ret = -EINVAL;
|
||||
|
||||
req.n.nlmsg_len = NLMSG_LENGTH(sizeof(req.r));
|
||||
req.n.nlmsg_type = RTM_GETROUTE;
|
||||
req.n.nlmsg_flags = NLM_F_REQUEST;
|
||||
|
||||
res.family = req.r.rtm_family = route.addr.family();
|
||||
req.r.rtm_dst_len = route.prefix_len;
|
||||
|
||||
if (route.addr.family() == AF_INET)
|
||||
{
|
||||
req.n.nlmsg_flags |= NLM_F_DUMP;
|
||||
}
|
||||
|
||||
{
|
||||
unsigned char bytestr[IP::Addr::V6_SIZE / 8];
|
||||
route.addr.to_byte_string_variable(bytestr);
|
||||
|
||||
SITNL_ADDATTR(&req.n, sizeof(req), RTA_DST, bytestr,
|
||||
route.addr.size_bytes());
|
||||
}
|
||||
|
||||
ret = sitnl_send(&req.n, 0, 0, sitnl_route_save, &res);
|
||||
if (ret >= 0)
|
||||
{
|
||||
/* save result in output variables */
|
||||
best_gw = std::move(res.gw);
|
||||
best_iface = std::move(res.iface);
|
||||
|
||||
OPENVPN_LOG(__func__ << " result: via " << best_gw << " dev " << best_iface);
|
||||
}
|
||||
else
|
||||
{
|
||||
OPENVPN_LOG(__func__ << ": failed to retrieve route, err=" << ret);
|
||||
}
|
||||
|
||||
err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
sitnl_addr_set(const int cmd, const uint32_t flags, const std::string& iface,
|
||||
const IP::Addr& local, const IP::Addr& remote, int prefixlen,
|
||||
const IP::Addr& broadcast)
|
||||
{
|
||||
struct sitnl_addr_req req = { };
|
||||
int ret = -EINVAL;
|
||||
|
||||
if (iface.empty())
|
||||
{
|
||||
OPENVPN_LOG(__func__ << ": passed empty interface");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (local.unspecified())
|
||||
{
|
||||
OPENVPN_LOG(__func__ << ": passed zero IP address");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
req.n.nlmsg_len = NLMSG_LENGTH(sizeof(req.i));
|
||||
req.n.nlmsg_type = cmd;
|
||||
req.n.nlmsg_flags = NLM_F_REQUEST | flags;
|
||||
|
||||
req.i.ifa_family = local.family();
|
||||
req.i.ifa_index = if_nametoindex(iface.c_str());
|
||||
if (req.i.ifa_index == 0)
|
||||
{
|
||||
OPENVPN_LOG(__func__ << ": cannot get ifindex for " << iface << " "
|
||||
<< strerror(errno));
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
/* if no prefixlen has been specified, assume host address */
|
||||
if (prefixlen == 0)
|
||||
{
|
||||
prefixlen = local.size();
|
||||
}
|
||||
req.i.ifa_prefixlen = prefixlen;
|
||||
|
||||
{
|
||||
unsigned char bytestr[IP::Addr::V6_SIZE / 8];
|
||||
|
||||
local.to_byte_string_variable(bytestr);
|
||||
SITNL_ADDATTR(&req.n, sizeof(req), IFA_LOCAL, bytestr, local.size_bytes());
|
||||
|
||||
if (remote.specified())
|
||||
{
|
||||
remote.to_byte_string_variable(bytestr);
|
||||
SITNL_ADDATTR(&req.n, sizeof(req), IFA_ADDRESS, bytestr, remote.size_bytes());
|
||||
}
|
||||
|
||||
if (broadcast.specified())
|
||||
{
|
||||
broadcast.to_byte_string_variable(bytestr);
|
||||
SITNL_ADDATTR(&req.n, sizeof(req), IFA_BROADCAST, bytestr, broadcast.size_bytes());
|
||||
}
|
||||
}
|
||||
|
||||
ret = sitnl_send(&req.n, 0, 0, NULL, NULL);
|
||||
if ((ret < 0) && (errno == EEXIST))
|
||||
{
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
sitnl_addr_ptp_add(const std::string& iface, const IP::Addr& local,
|
||||
const IP::Addr& remote)
|
||||
{
|
||||
return sitnl_addr_set(RTM_NEWADDR, NLM_F_CREATE | NLM_F_REPLACE, iface,
|
||||
local, remote, 0,
|
||||
IP::Addr::from_zero(local.version()));
|
||||
}
|
||||
|
||||
static int
|
||||
sitnl_addr_ptp_del(const std::string& iface, const IP::Addr& local)
|
||||
{
|
||||
return sitnl_addr_set(RTM_DELADDR, 0, iface, local,
|
||||
IP::Addr::from_zero(local.version()),
|
||||
0, IP::Addr::from_zero(local.version()));
|
||||
}
|
||||
|
||||
static int
|
||||
sitnl_route_set(const int cmd, const uint32_t flags,
|
||||
const std::string& iface, const IP::Route& route,
|
||||
const IP::Addr& gw, const enum rt_class_t table,
|
||||
const int metric, const enum rt_scope_t scope,
|
||||
const int protocol, const int type)
|
||||
{
|
||||
struct sitnl_route_req req = { };
|
||||
int ret = -1;
|
||||
|
||||
req.n.nlmsg_len = NLMSG_LENGTH(sizeof(req.r));
|
||||
req.n.nlmsg_type = cmd;
|
||||
req.n.nlmsg_flags = NLM_F_REQUEST | flags;
|
||||
|
||||
req.r.rtm_family = route.addr.family();
|
||||
req.r.rtm_scope = scope;
|
||||
req.r.rtm_protocol = protocol;
|
||||
req.r.rtm_type = type;
|
||||
req.r.rtm_dst_len = route.prefix_len;
|
||||
|
||||
if (table < 256)
|
||||
{
|
||||
req.r.rtm_table = table;
|
||||
}
|
||||
else
|
||||
{
|
||||
req.r.rtm_table = RT_TABLE_UNSPEC;
|
||||
SITNL_ADDATTR(&req.n, sizeof(req), RTA_TABLE, &table, 4);
|
||||
}
|
||||
|
||||
{
|
||||
unsigned char bytestr[IP::Addr::V6_SIZE / 8];
|
||||
|
||||
route.addr.to_byte_string_variable(bytestr);
|
||||
SITNL_ADDATTR(&req.n, sizeof(req), RTA_DST, bytestr, route.addr.size_bytes());
|
||||
|
||||
if (gw.specified())
|
||||
{
|
||||
gw.to_byte_string_variable(bytestr);
|
||||
SITNL_ADDATTR(&req.n, sizeof(req), RTA_GATEWAY, bytestr, gw.size_bytes());
|
||||
}
|
||||
}
|
||||
|
||||
if (!iface.empty())
|
||||
{
|
||||
int ifindex = if_nametoindex(iface.c_str());
|
||||
if (ifindex == 0)
|
||||
{
|
||||
OPENVPN_LOG(__func__ << ": rtnl: cannot get ifindex for " << iface);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
SITNL_ADDATTR(&req.n, sizeof(req), RTA_OIF, &ifindex, 4);
|
||||
}
|
||||
|
||||
if (metric > 0)
|
||||
{
|
||||
SITNL_ADDATTR(&req.n, sizeof(req), RTA_PRIORITY, &metric, 4);
|
||||
}
|
||||
|
||||
ret = sitnl_send(&req.n, 0, 0, NULL, NULL);
|
||||
if ((ret < 0) && (errno == EEXIST))
|
||||
{
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
sitnl_addr_add(const std::string& iface, const IP::Addr& addr,
|
||||
int prefixlen, const IP::Addr& broadcast)
|
||||
{
|
||||
return sitnl_addr_set(RTM_NEWADDR, NLM_F_CREATE | NLM_F_REPLACE, iface,
|
||||
addr, IP::Addr::from_zero(addr.version()),
|
||||
prefixlen, broadcast);
|
||||
}
|
||||
|
||||
static int
|
||||
sitnl_addr_del(const std::string& iface, const IP::Addr& addr, int prefixlen)
|
||||
{
|
||||
return sitnl_addr_set(RTM_DELADDR, 0, iface, addr,
|
||||
IP::Addr::from_zero(addr.version()), prefixlen,
|
||||
IP::Addr::from_zero(addr.version()));
|
||||
}
|
||||
|
||||
static int
|
||||
sitnl_route_add(const IP::Route& route, const IP::Addr& gw,
|
||||
const std::string& iface, const uint32_t table,
|
||||
const int metric)
|
||||
{
|
||||
return sitnl_route_set(RTM_NEWROUTE, NLM_F_CREATE | NLM_F_REPLACE, iface,
|
||||
route, gw,
|
||||
(enum rt_class_t)(!table ? RT_TABLE_MAIN : table),
|
||||
metric, RT_SCOPE_UNIVERSE, RTPROT_BOOT, RTN_UNICAST);
|
||||
}
|
||||
|
||||
static int
|
||||
sitnl_route_del(const IP::Route& route, const IP::Addr& gw,
|
||||
const std::string& iface, const uint32_t table,
|
||||
const int metric)
|
||||
{
|
||||
return sitnl_route_set(RTM_DELROUTE, 0, iface, route, gw,
|
||||
(enum rt_class_t)(!table ? RT_TABLE_MAIN : table),
|
||||
metric, RT_SCOPE_NOWHERE,
|
||||
0, 0);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
static int
|
||||
net_route_best_gw(const IP::Route6& route, IPv6::Addr& best_gw6,
|
||||
std::string& best_iface)
|
||||
{
|
||||
IP::Addr best_gw;
|
||||
int ret;
|
||||
|
||||
OPENVPN_LOG(__func__ << " query IPv6: " << route);
|
||||
|
||||
ret = sitnl_route_best_gw(IP::Route(IP::Addr::from_ipv6(route.addr), route.prefix_len),
|
||||
best_gw, best_iface);
|
||||
if (ret >= 0)
|
||||
{
|
||||
best_gw6 = best_gw.to_ipv6();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
net_route_best_gw(const IP::Route4& route, IPv4::Addr &best_gw4,
|
||||
std::string& best_iface)
|
||||
{
|
||||
IP::Addr best_gw;
|
||||
int ret;
|
||||
|
||||
OPENVPN_LOG(__func__ << " query IPv4: " << route);
|
||||
|
||||
ret = sitnl_route_best_gw(IP::Route(IP::Addr::from_ipv4(route.addr), route.prefix_len),
|
||||
best_gw, best_iface);
|
||||
if (ret >= 0)
|
||||
{
|
||||
best_gw4 = best_gw.to_ipv4();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
net_iface_up(std::string& iface, bool up)
|
||||
{
|
||||
struct sitnl_link_req req = { };
|
||||
int ifindex;
|
||||
|
||||
if (iface.empty())
|
||||
{
|
||||
OPENVPN_LOG(__func__ << ": passed empty interface");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ifindex = if_nametoindex(iface.c_str());
|
||||
if (ifindex == 0)
|
||||
{
|
||||
OPENVPN_LOG(__func__ << ": rtnl: cannot get ifindex for " << iface
|
||||
<< ": " << strerror(errno));
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
req.n.nlmsg_len = NLMSG_LENGTH(sizeof(req.i));
|
||||
req.n.nlmsg_flags = NLM_F_REQUEST;
|
||||
req.n.nlmsg_type = RTM_NEWLINK;
|
||||
|
||||
req.i.ifi_family = AF_PACKET;
|
||||
req.i.ifi_index = ifindex;
|
||||
req.i.ifi_change |= IFF_UP;
|
||||
if (up)
|
||||
{
|
||||
req.i.ifi_flags |= IFF_UP;
|
||||
}
|
||||
else
|
||||
{
|
||||
req.i.ifi_flags &= ~IFF_UP;
|
||||
}
|
||||
|
||||
OPENVPN_LOG(__func__ << ": set " << iface << " " << (up ? "up" : "down"));
|
||||
|
||||
return sitnl_send(&req.n, 0, 0, NULL, NULL);
|
||||
}
|
||||
|
||||
static int
|
||||
net_iface_mtu_set(std::string& iface, uint32_t mtu)
|
||||
{
|
||||
struct sitnl_link_req req = { };
|
||||
int ifindex;
|
||||
|
||||
if (iface.empty())
|
||||
{
|
||||
OPENVPN_LOG(__func__ << ": passed empty interface");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ifindex = if_nametoindex(iface.c_str());
|
||||
if (ifindex == 0)
|
||||
{
|
||||
OPENVPN_LOG(__func__ << ": rtnl: cannot get ifindex for " << iface);
|
||||
return -1;
|
||||
}
|
||||
|
||||
req.n.nlmsg_len = NLMSG_LENGTH(sizeof(req.i));
|
||||
req.n.nlmsg_flags = NLM_F_REQUEST;
|
||||
req.n.nlmsg_type = RTM_NEWLINK;
|
||||
|
||||
req.i.ifi_family = AF_PACKET;
|
||||
req.i.ifi_index = ifindex;
|
||||
|
||||
SITNL_ADDATTR(&req.n, sizeof(req), IFLA_MTU, &mtu, 4);
|
||||
|
||||
OPENVPN_LOG(__func__ << ": mtu " << mtu << " for " << iface);
|
||||
|
||||
err:
|
||||
return sitnl_send(&req.n, 0, 0, NULL, NULL);
|
||||
}
|
||||
|
||||
static int
|
||||
net_addr_add(const std::string& iface, const IPv4::Addr& addr,
|
||||
const int prefixlen, const IPv4::Addr& broadcast)
|
||||
{
|
||||
OPENVPN_LOG(__func__ << ": " << addr << "/" << prefixlen << " brd "
|
||||
<< broadcast << " dev " << iface);
|
||||
|
||||
return sitnl_addr_add(iface, IP::Addr::from_ipv4(addr), prefixlen,
|
||||
IP::Addr::from_ipv4(broadcast));
|
||||
}
|
||||
|
||||
static int
|
||||
net_addr_add(const std::string& iface, const IPv6::Addr& addr,
|
||||
const int prefixlen)
|
||||
{
|
||||
OPENVPN_LOG(__func__ << ": " << addr << "/" << prefixlen << " dev " << iface);
|
||||
|
||||
return sitnl_addr_add(iface, IP::Addr::from_ipv6(addr), prefixlen,
|
||||
IP::Addr::from_zero(IP::Addr::V6));
|
||||
}
|
||||
|
||||
static int
|
||||
net_addr_del(const std::string& iface, const IPv4::Addr& addr,
|
||||
const int prefixlen)
|
||||
{
|
||||
OPENVPN_LOG(__func__ << ": " << addr << "/" << prefixlen << " dev " << iface);
|
||||
|
||||
return sitnl_addr_del(iface, IP::Addr::from_ipv4(addr), prefixlen);
|
||||
}
|
||||
|
||||
static int
|
||||
net_addr_del(const std::string& iface, const IPv6::Addr& addr,
|
||||
const int prefixlen)
|
||||
{
|
||||
OPENVPN_LOG(__func__ << ": " << addr << "/" << prefixlen << " dev " << iface);
|
||||
|
||||
return sitnl_addr_del(iface, IP::Addr::from_ipv6(addr), prefixlen);
|
||||
}
|
||||
|
||||
static int
|
||||
net_addr_ptp_add(const std::string& iface, const IPv4::Addr& local,
|
||||
const IPv4::Addr& remote)
|
||||
{
|
||||
OPENVPN_LOG(__func__ << ": " << local << " peer " << remote << " dev " << iface);
|
||||
|
||||
return sitnl_addr_ptp_add(iface, IP::Addr::from_ipv4(local),
|
||||
IP::Addr::from_ipv4(remote));
|
||||
}
|
||||
|
||||
static int
|
||||
net_addr_ptp_del(const std::string& iface, const IPv4::Addr& local,
|
||||
const IPv4::Addr& remote)
|
||||
{
|
||||
OPENVPN_LOG(__func__ << ": " << local << " dev " << iface);
|
||||
|
||||
return sitnl_addr_ptp_del(iface, IP::Addr::from_ipv4(local));
|
||||
}
|
||||
|
||||
static int
|
||||
net_route_add(const IP::Route4& route, const IPv4::Addr& gw,
|
||||
const std::string& iface, const uint32_t table,
|
||||
const int metric)
|
||||
{
|
||||
OPENVPN_LOG(__func__ << ": " << route << " via " << gw << " dev " << iface
|
||||
<< " table " << table << " metric " << metric);
|
||||
|
||||
return sitnl_route_add(IP::Route(IP::Addr::from_ipv4(route.addr), route.prefix_len),
|
||||
IP::Addr::from_ipv4(gw), iface, table, metric);
|
||||
}
|
||||
|
||||
static int
|
||||
net_route_add(const IP::Route6& route, const IPv6::Addr& gw,
|
||||
const std::string& iface, const uint32_t table,
|
||||
const int metric)
|
||||
{
|
||||
OPENVPN_LOG(__func__ << ": " << route << " via " << gw << " dev " << iface
|
||||
<< " table " << table << " metric " << metric);
|
||||
|
||||
return sitnl_route_add(IP::Route(IP::Addr::from_ipv6(route.addr), route.prefix_len),
|
||||
IP::Addr::from_ipv6(gw), iface, table, metric);
|
||||
}
|
||||
|
||||
static int
|
||||
net_route_del(const IP::Route4& route, const IPv4::Addr& gw,
|
||||
const std::string& iface, const uint32_t table,
|
||||
const int metric)
|
||||
{
|
||||
OPENVPN_LOG(__func__ << ": " << route << " via " << gw << " dev " << iface
|
||||
<< " table " << table << " metric " << metric);
|
||||
|
||||
return sitnl_route_del(IP::Route(IP::Addr::from_ipv4(route.addr), route.prefix_len),
|
||||
IP::Addr::from_ipv4(gw), iface, table, metric);
|
||||
}
|
||||
|
||||
static int
|
||||
net_route_del(const IP::Route6& route, const IPv6::Addr& gw,
|
||||
const std::string& iface, const uint32_t table,
|
||||
const int metric)
|
||||
{
|
||||
OPENVPN_LOG(__func__ << ": " << route << " via " << gw << " dev " << iface
|
||||
<< " table " << table << " metric " << metric);
|
||||
|
||||
return sitnl_route_del(IP::Route(IP::Addr::from_ipv6(route.addr), route.prefix_len),
|
||||
IP::Addr::from_ipv6(gw), iface, table, metric);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -30,7 +30,15 @@
|
||||
#include <openvpn/tun/builder/setup.hpp>
|
||||
#include <openvpn/tun/tunio.hpp>
|
||||
#include <openvpn/tun/persist/tunpersist.hpp>
|
||||
|
||||
// check if Netlink has been selected at compile time
|
||||
#ifdef OPENVPN_USE_SITNL
|
||||
#include <openvpn/tun/linux/client/tunnetlink.hpp>
|
||||
#define TUN_LINUX TunNetlink
|
||||
#else
|
||||
#include <openvpn/tun/linux/client/tunsetup.hpp>
|
||||
#define TUN_LINUX TunLinux
|
||||
#endif
|
||||
|
||||
namespace openvpn {
|
||||
namespace TunLinux {
|
||||
@@ -114,7 +122,7 @@ namespace openvpn {
|
||||
if (tun_setup_factory)
|
||||
return tun_setup_factory->new_setup_obj();
|
||||
else
|
||||
return new TunLinux::Setup();
|
||||
return new TUN_LINUX::Setup();
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -129,7 +137,7 @@ namespace openvpn {
|
||||
typedef Tun<Client*> TunImpl;
|
||||
|
||||
public:
|
||||
virtual void tun_start(const OptionList& opt, TransportClient& transcli, CryptoDCSettings&)
|
||||
virtual void tun_start(const OptionList& opt, TransportClient& transcli, CryptoDCSettings&) override
|
||||
{
|
||||
if (!impl)
|
||||
{
|
||||
@@ -184,7 +192,7 @@ namespace openvpn {
|
||||
tun_setup = config->new_setup_obj();
|
||||
|
||||
// create config object for tun setup layer
|
||||
Setup::Config tsconf;
|
||||
TUN_LINUX::Setup::Config tsconf;
|
||||
tsconf.layer = config->tun_prop.layer;
|
||||
tsconf.dev_name = config->dev_name;
|
||||
tsconf.txqueuelen = config->txqueuelen;
|
||||
@@ -228,12 +236,12 @@ namespace openvpn {
|
||||
}
|
||||
}
|
||||
|
||||
virtual bool tun_send(BufferAllocated& buf)
|
||||
virtual bool tun_send(BufferAllocated& buf) override
|
||||
{
|
||||
return send(buf);
|
||||
}
|
||||
|
||||
virtual std::string tun_name() const
|
||||
virtual std::string tun_name() const override
|
||||
{
|
||||
if (impl)
|
||||
return impl->name();
|
||||
@@ -241,7 +249,7 @@ namespace openvpn {
|
||||
return "UNDEF_TUN";
|
||||
}
|
||||
|
||||
virtual std::string vpn_ip4() const
|
||||
virtual std::string vpn_ip4() const override
|
||||
{
|
||||
if (state->vpn_ip4_addr.specified())
|
||||
return state->vpn_ip4_addr.to_string();
|
||||
@@ -249,7 +257,7 @@ namespace openvpn {
|
||||
return "";
|
||||
}
|
||||
|
||||
virtual std::string vpn_ip6() const
|
||||
virtual std::string vpn_ip6() const override
|
||||
{
|
||||
if (state->vpn_ip6_addr.specified())
|
||||
return state->vpn_ip6_addr.to_string();
|
||||
@@ -273,11 +281,11 @@ namespace openvpn {
|
||||
return "";
|
||||
}
|
||||
|
||||
virtual void set_disconnect()
|
||||
virtual void set_disconnect() override
|
||||
{
|
||||
}
|
||||
|
||||
virtual void stop() { stop_(); }
|
||||
virtual void stop() override { stop_(); }
|
||||
virtual ~Client() { stop_(); }
|
||||
|
||||
private:
|
||||
|
||||
821
openvpn/tun/linux/client/tunnetlink.hpp
Normal file
821
openvpn/tun/linux/client/tunnetlink.hpp
Normal file
@@ -0,0 +1,821 @@
|
||||
// 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-2018 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <net/if.h>
|
||||
#include <linux/if_tun.h>
|
||||
|
||||
#include <openvpn/netconf/linux/gwnetlink.hpp>
|
||||
#include <openvpn/common/action.hpp>
|
||||
#include <openvpn/tun/linux/client/sitnl.hpp>
|
||||
#include <openvpn/tun/client/tunbase.hpp>
|
||||
|
||||
namespace openvpn {
|
||||
namespace TunNetlink {
|
||||
|
||||
OPENVPN_EXCEPTION(tun_linux_error);
|
||||
OPENVPN_EXCEPTION(tun_open_error);
|
||||
OPENVPN_EXCEPTION(tun_layer_error);
|
||||
OPENVPN_EXCEPTION(tun_ioctl_error);
|
||||
OPENVPN_EXCEPTION(tun_fcntl_error);
|
||||
OPENVPN_EXCEPTION(tun_name_error);
|
||||
OPENVPN_EXCEPTION(tun_tx_queue_len_error);
|
||||
OPENVPN_EXCEPTION(tun_ifconfig_error);
|
||||
|
||||
struct NetlinkLinkSet : public Action
|
||||
{
|
||||
typedef RCPtr<NetlinkLinkSet> Ptr;
|
||||
|
||||
NetlinkLinkSet() {}
|
||||
|
||||
NetlinkLinkSet(std::string dev_arg, bool up_arg, int mtu_arg)
|
||||
: dev(dev_arg),
|
||||
up(up_arg),
|
||||
mtu(mtu_arg)
|
||||
{
|
||||
}
|
||||
|
||||
NetlinkLinkSet* copy() const
|
||||
{
|
||||
NetlinkLinkSet *ret = new NetlinkLinkSet;
|
||||
ret->dev = dev;
|
||||
ret->up = up;
|
||||
ret->mtu = mtu;
|
||||
return ret;
|
||||
}
|
||||
|
||||
virtual void execute(std::ostream& os) override
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (dev.empty())
|
||||
{
|
||||
os << "Error: can't call NetlinkLinkSet with no interface" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
ret = SITNL::net_iface_mtu_set(dev, mtu);
|
||||
if (ret)
|
||||
{
|
||||
os << "Error while executing NetlinkLinkSet " << dev << " mtu " << mtu
|
||||
<< ": " << ret << std::endl;
|
||||
}
|
||||
|
||||
ret = SITNL::net_iface_up(dev, up);
|
||||
if (ret)
|
||||
{
|
||||
os << "Error while executing NetlinkLinkSet " << dev << " up " << up
|
||||
<< ": " << ret << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
virtual std::string to_string() const override
|
||||
{
|
||||
std::ostringstream os;
|
||||
os << "netlink iface " << dev << " link set " << up << " mtu " << mtu;
|
||||
return os.str();
|
||||
}
|
||||
|
||||
std::string dev;
|
||||
bool up;
|
||||
int mtu;
|
||||
};
|
||||
|
||||
struct NetlinkAddr4 : public Action
|
||||
{
|
||||
typedef RCPtr<NetlinkAddr4> Ptr;
|
||||
|
||||
NetlinkAddr4() {}
|
||||
|
||||
NetlinkAddr4(std::string dev_arg, IPv4::Addr& addr_arg, int prefixlen_arg,
|
||||
IPv4::Addr& broadcast_arg, bool add_arg)
|
||||
: dev(dev_arg),
|
||||
addr(addr_arg),
|
||||
prefixlen(prefixlen_arg),
|
||||
broadcast(broadcast_arg),
|
||||
add(add_arg)
|
||||
{
|
||||
}
|
||||
|
||||
NetlinkAddr4* copy() const
|
||||
{
|
||||
NetlinkAddr4 *ret = new NetlinkAddr4;
|
||||
ret->dev = dev;
|
||||
ret->addr = addr;
|
||||
ret->prefixlen = prefixlen;
|
||||
ret->broadcast = broadcast;
|
||||
ret->add = add;
|
||||
return ret;
|
||||
}
|
||||
|
||||
virtual void execute(std::ostream& os) override
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (dev.empty())
|
||||
{
|
||||
os << "Error: can't call NetlinkAddr4 with no interface" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if (add)
|
||||
{
|
||||
ret = SITNL::net_addr_add(dev, addr, prefixlen, broadcast);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = SITNL::net_addr_del(dev, addr, prefixlen);
|
||||
}
|
||||
|
||||
if (ret)
|
||||
{
|
||||
os << "Error while executing NetlinkAddr4(add: " << add << ") "
|
||||
<< dev << ": " << ret << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
virtual std::string to_string() const override
|
||||
{
|
||||
std::ostringstream os;
|
||||
os << "netlink iface " << dev << " " << (add ? "add" : "del") << " "
|
||||
<< addr.to_string() << "/" << prefixlen << " broadcast "
|
||||
<< broadcast.to_string();
|
||||
return os.str();
|
||||
}
|
||||
|
||||
std::string dev;
|
||||
IPv4::Addr addr;
|
||||
int prefixlen;
|
||||
IPv4::Addr broadcast;
|
||||
bool add;
|
||||
};
|
||||
|
||||
struct NetlinkAddr6 : public Action
|
||||
{
|
||||
typedef RCPtr<NetlinkAddr6> Ptr;
|
||||
|
||||
NetlinkAddr6() {}
|
||||
|
||||
NetlinkAddr6(std::string dev_arg, IPv6::Addr& addr_arg, int prefixlen_arg,
|
||||
bool add_arg)
|
||||
: dev(dev_arg),
|
||||
addr(addr_arg),
|
||||
prefixlen(prefixlen_arg),
|
||||
add(add_arg)
|
||||
{
|
||||
}
|
||||
|
||||
NetlinkAddr6* copy() const
|
||||
{
|
||||
NetlinkAddr6 *ret = new NetlinkAddr6;
|
||||
ret->dev = dev;
|
||||
ret->addr = addr;
|
||||
ret->prefixlen = prefixlen;
|
||||
ret->add = add;
|
||||
return ret;
|
||||
}
|
||||
|
||||
virtual void execute(std::ostream& os) override
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (dev.empty())
|
||||
{
|
||||
os << "Error: can't call NetlinkAddr6 with no interface" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if (add)
|
||||
{
|
||||
ret = SITNL::net_addr_add(dev, addr, prefixlen);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = SITNL::net_addr_del(dev, addr, prefixlen);
|
||||
}
|
||||
|
||||
if (ret)
|
||||
{
|
||||
os << "Error while executing NetlinkAddr6(add: " << add << ") "
|
||||
<< dev << ": " << ret << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
virtual std::string to_string() const override
|
||||
{
|
||||
std::ostringstream os;
|
||||
os << "netlink iface " << dev << " " << (add ? "add" : "del") << " "
|
||||
<< addr.to_string() << "/" << prefixlen;
|
||||
return os.str();
|
||||
}
|
||||
|
||||
std::string dev;
|
||||
IPv6::Addr addr;
|
||||
int prefixlen;
|
||||
bool add;
|
||||
};
|
||||
|
||||
struct NetlinkAddr4PtP : public Action
|
||||
{
|
||||
typedef RCPtr<NetlinkAddr4PtP> Ptr;
|
||||
|
||||
NetlinkAddr4PtP() {}
|
||||
|
||||
NetlinkAddr4PtP(std::string dev_arg, IPv4::Addr local_arg,
|
||||
IPv4::Addr remote_arg, bool add_arg)
|
||||
: dev(dev_arg),
|
||||
local(local_arg),
|
||||
remote(remote_arg),
|
||||
add(add_arg)
|
||||
{
|
||||
}
|
||||
|
||||
NetlinkAddr4PtP* copy() const
|
||||
{
|
||||
NetlinkAddr4PtP *ret = new NetlinkAddr4PtP;
|
||||
ret->dev = dev;
|
||||
ret->local = local;
|
||||
ret->remote = remote;
|
||||
ret->add = add;
|
||||
return ret;
|
||||
}
|
||||
|
||||
virtual void execute(std::ostream& os) override
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (dev.empty())
|
||||
{
|
||||
os << "Error: can't call NetlinkAddr4PtP with no interface" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if (add)
|
||||
{
|
||||
ret = SITNL::net_addr_ptp_add(dev, local, remote);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = SITNL::net_addr_ptp_del(dev, local, remote);
|
||||
}
|
||||
|
||||
if (ret)
|
||||
{
|
||||
os << "Error while executing NetlinkAddr4PtP(add: " << add << ") "
|
||||
<< dev << ": " << ret << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
virtual std::string to_string() const override
|
||||
{
|
||||
return "netlink iface " + dev + " " + (add ? "add" : "del") + " ptp "
|
||||
+ local.to_string() + " remote " + remote.to_string();
|
||||
}
|
||||
|
||||
std::string dev;
|
||||
IPv4::Addr local;
|
||||
IPv4::Addr remote;
|
||||
bool add;
|
||||
};
|
||||
|
||||
struct NetlinkRoute4 : public Action
|
||||
{
|
||||
typedef RCPtr<NetlinkRoute4> Ptr;
|
||||
|
||||
NetlinkRoute4() {}
|
||||
|
||||
NetlinkRoute4(IPv4::Addr& dst_arg, int prefixlen_arg, IPv4::Addr& gw_arg,
|
||||
std::string dev_arg, bool add_arg)
|
||||
: route(dst_arg, prefixlen_arg),
|
||||
gw(gw_arg),
|
||||
dev(dev_arg),
|
||||
add(add_arg)
|
||||
{
|
||||
}
|
||||
|
||||
NetlinkRoute4* copy() const
|
||||
{
|
||||
NetlinkRoute4 *ret = new NetlinkRoute4;
|
||||
ret->route = route;
|
||||
ret->gw = gw;
|
||||
ret->dev = dev;
|
||||
return ret;
|
||||
}
|
||||
|
||||
virtual void execute(std::ostream& os) override
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (dev.empty())
|
||||
{
|
||||
os << "Error: can't call NetlinkRoute4 with no interface" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if (add)
|
||||
{
|
||||
ret = SITNL::net_route_add(route, gw, dev, 0, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = SITNL::net_route_del(route, gw, dev, 0, 0);
|
||||
}
|
||||
|
||||
if (ret)
|
||||
{
|
||||
os << "Error while executing NetlinkRoute4(add: " << add << ") "
|
||||
<< dev << ": " << ret << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
virtual std::string to_string() const override
|
||||
{
|
||||
std::ostringstream os;
|
||||
os << "netlink route " << (add ? "add" : "del") << " dev " << dev << " "
|
||||
<< route << " via " << gw.to_string();
|
||||
return os.str();
|
||||
}
|
||||
|
||||
IP::Route4 route;
|
||||
IPv4::Addr gw;
|
||||
std::string dev;
|
||||
bool add;
|
||||
};
|
||||
|
||||
struct NetlinkRoute6 : public Action
|
||||
{
|
||||
typedef RCPtr<NetlinkRoute6> Ptr;
|
||||
|
||||
NetlinkRoute6() {}
|
||||
|
||||
NetlinkRoute6(IPv6::Addr& dst_arg, int prefixlen_arg, IPv6::Addr& gw_arg,
|
||||
std::string dev_arg, bool add_arg)
|
||||
: route(dst_arg, prefixlen_arg),
|
||||
gw(gw_arg),
|
||||
dev(dev_arg),
|
||||
add(add_arg)
|
||||
{
|
||||
}
|
||||
|
||||
NetlinkRoute6* copy() const
|
||||
{
|
||||
NetlinkRoute6 *ret = new NetlinkRoute6;
|
||||
ret->route = route;
|
||||
ret->gw = gw;
|
||||
ret->dev = dev;
|
||||
return ret;
|
||||
}
|
||||
|
||||
virtual void execute(std::ostream& os) override
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (dev.empty())
|
||||
{
|
||||
os << "Error: can't call NetlinkRoute6 with no interface" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if (add)
|
||||
{
|
||||
ret = SITNL::net_route_add(route, gw, dev, 0, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = SITNL::net_route_del(route, gw, dev, 0, 0);
|
||||
}
|
||||
|
||||
if (ret)
|
||||
{
|
||||
os << "Error while executing NetlinkRoute6(add: " << add << ") "
|
||||
<< dev << ": " << ret << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
virtual std::string to_string() const override
|
||||
{
|
||||
std::ostringstream os;
|
||||
os << "netlink route " << (add ? "add" : "del") << " dev " << dev << " "
|
||||
<< route << " via " << gw.to_string();
|
||||
return os.str();
|
||||
}
|
||||
|
||||
IP::Route6 route;
|
||||
IPv6::Addr gw;
|
||||
std::string dev;
|
||||
bool add;
|
||||
};
|
||||
|
||||
enum { // add_del_route flags
|
||||
R_IPv6=(1<<0),
|
||||
R_ADD_SYS=(1<<1),
|
||||
R_ADD_DCO=(1<<2),
|
||||
R_ADD_ALL=R_ADD_SYS|R_ADD_DCO,
|
||||
};
|
||||
|
||||
/*inline IPv4::Addr cvt_pnr_ip_v4(const std::string& hexaddr)
|
||||
{
|
||||
BufferAllocated v(4, BufferAllocated::CONSTRUCT_ZERO);
|
||||
parse_hex(v, hexaddr);
|
||||
if (v.size() != 4)
|
||||
throw tun_linux_error("bad hex address");
|
||||
IPv4::Addr ret = IPv4::Addr::from_bytes(v.data());
|
||||
return IP::Addr::from_ipv4(ret);
|
||||
}*/
|
||||
|
||||
inline void add_del_route(const std::string& addr_str,
|
||||
const int prefix_len,
|
||||
const std::string& gateway_str,
|
||||
const std::string& dev,
|
||||
const unsigned int flags,
|
||||
std::vector<IP::Route>* rtvec,
|
||||
Action::Ptr& create,
|
||||
Action::Ptr& destroy)
|
||||
{
|
||||
if (flags & R_IPv6)
|
||||
{
|
||||
const IPv6::Addr addr = IPv6::Addr::from_string(addr_str);
|
||||
const IPv6::Addr netmask = IPv6::Addr::netmask_from_prefix_len(prefix_len);
|
||||
const IPv6::Addr net = addr & netmask;
|
||||
|
||||
if (flags & R_ADD_SYS)
|
||||
{
|
||||
// ip route add 2001:db8:1::/48 via 2001:db8:1::1
|
||||
NetlinkRoute6::Ptr add(new NetlinkRoute6);
|
||||
add->route.addr = net;
|
||||
add->route.prefix_len = prefix_len;
|
||||
add->gw = IPv6::Addr::from_string(gateway_str);
|
||||
add->dev = dev;
|
||||
add->add = true;
|
||||
|
||||
create = add;
|
||||
// for the destroy command, copy the add command but replace "add" with "delete"
|
||||
NetlinkRoute6::Ptr del(add->copy());
|
||||
del->add = false;
|
||||
destroy = del;
|
||||
}
|
||||
|
||||
if (rtvec && (flags & R_ADD_DCO))
|
||||
rtvec->emplace_back(IP::Addr::from_ipv6(net), prefix_len);
|
||||
}
|
||||
else
|
||||
{
|
||||
const IPv4::Addr addr = IPv4::Addr::from_string(addr_str);
|
||||
const IPv4::Addr netmask = IPv4::Addr::netmask_from_prefix_len(prefix_len);
|
||||
const IPv4::Addr net = addr & netmask;
|
||||
|
||||
if (flags & R_ADD_SYS)
|
||||
{
|
||||
// ip route add 192.0.2.128/25 via 192.0.2.1
|
||||
NetlinkRoute4::Ptr add(new NetlinkRoute4);
|
||||
add->route.addr = net;
|
||||
add->route.prefix_len = prefix_len;
|
||||
add->gw = IPv4::Addr::from_string(gateway_str);
|
||||
add->dev = dev;
|
||||
add->add = true;
|
||||
|
||||
create = add;
|
||||
// for the destroy command, copy the add command but replace "add" with "delete"
|
||||
NetlinkRoute4::Ptr del(add->copy());
|
||||
del->add = false;
|
||||
destroy = del;
|
||||
}
|
||||
|
||||
if (rtvec && (flags & R_ADD_DCO))
|
||||
rtvec->emplace_back(IP::Addr::from_ipv4(net), prefix_len);
|
||||
}
|
||||
}
|
||||
|
||||
inline void add_del_route(const std::string& addr_str,
|
||||
const int prefix_len,
|
||||
const std::string& gateway_str,
|
||||
const std::string& dev,
|
||||
const unsigned int flags,// add interface route to rtvec if defined
|
||||
std::vector<IP::Route>* rtvec,
|
||||
ActionList& create,
|
||||
ActionList& destroy)
|
||||
{
|
||||
Action::Ptr c, d;
|
||||
add_del_route(addr_str, prefix_len, gateway_str, dev, flags, rtvec, c, d);
|
||||
create.add(c);
|
||||
destroy.add(d);
|
||||
}
|
||||
|
||||
inline void iface_up(const std::string& iface_name,
|
||||
const int mtu,
|
||||
ActionList& create,
|
||||
ActionList& destroy)
|
||||
{
|
||||
{
|
||||
NetlinkLinkSet::Ptr add(new NetlinkLinkSet);
|
||||
add->dev = iface_name;
|
||||
add->up = true;
|
||||
add->mtu = mtu;
|
||||
|
||||
create.add(add);
|
||||
// for the destroy command, copy the add command but replace "up" with "down"
|
||||
NetlinkLinkSet::Ptr del(add->copy());
|
||||
del->up = false;
|
||||
destroy.add(del);
|
||||
}
|
||||
}
|
||||
|
||||
inline void iface_config(const std::string& iface_name,
|
||||
int unit,
|
||||
const TunBuilderCapture& pull,
|
||||
std::vector<IP::Route>* rtvec,
|
||||
ActionList& create,
|
||||
ActionList& destroy)
|
||||
{
|
||||
// set local4 and local6 to point to IPv4/6 route configurations
|
||||
const TunBuilderCapture::RouteAddress* local4 = pull.vpn_ipv4();
|
||||
const TunBuilderCapture::RouteAddress* local6 = pull.vpn_ipv6();
|
||||
|
||||
// Set IPv4 Interface
|
||||
if (local4)
|
||||
{
|
||||
NetlinkAddr4::Ptr add(new NetlinkAddr4);
|
||||
add->addr = IPv4::Addr::from_string(local4->address);
|
||||
add->prefixlen = local4->prefix_length;
|
||||
add->broadcast = IPv4::Addr::from_string(local4->address)
|
||||
| ~IPv4::Addr::netmask_from_prefix_len(local4->prefix_length);
|
||||
add->dev = iface_name;
|
||||
add->add = true;
|
||||
// if (unit >= 0)
|
||||
// {
|
||||
// add->argv.push_back("label");
|
||||
// add->argv.push_back(iface_name + ':' + openvpn::to_string(unit));
|
||||
// }
|
||||
create.add(add);
|
||||
|
||||
// for the destroy command, copy the add command but replace "add" with "delete"
|
||||
NetlinkAddr4::Ptr del(add->copy());
|
||||
del->add = false;
|
||||
destroy.add(del);
|
||||
|
||||
// add interface route to rtvec if defined
|
||||
add_del_route(local4->address, local4->prefix_length, local4->address, iface_name, R_ADD_DCO, rtvec, create, destroy);
|
||||
}
|
||||
|
||||
// Set IPv6 Interface
|
||||
if (local6 && !pull.block_ipv6)
|
||||
{
|
||||
NetlinkAddr6::Ptr add(new NetlinkAddr6);
|
||||
add->addr = IPv6::Addr::from_string(local6->address);
|
||||
add->prefixlen = local6->prefix_length;
|
||||
add->dev = iface_name;
|
||||
add->add = true;
|
||||
|
||||
create.add(add);
|
||||
|
||||
// for the destroy command, copy the add command but replace "add" with "delete"
|
||||
NetlinkAddr6::Ptr del(add->copy());
|
||||
del->add = false;
|
||||
destroy.add(del);
|
||||
|
||||
// add interface route to rtvec if defined
|
||||
add_del_route(local6->address, local6->prefix_length, local6->address, iface_name, R_ADD_DCO|R_IPv6, rtvec, create, destroy);
|
||||
}
|
||||
}
|
||||
|
||||
inline void tun_config(const std::string& iface_name,
|
||||
const TunBuilderCapture& pull,
|
||||
std::vector<IP::Route>* rtvec,
|
||||
ActionList& create,
|
||||
ActionList& destroy)
|
||||
{
|
||||
const LinuxGW46Netlink gw;
|
||||
|
||||
// set local4 and local6 to point to IPv4/6 route configurations
|
||||
const TunBuilderCapture::RouteAddress* local4 = pull.vpn_ipv4();
|
||||
const TunBuilderCapture::RouteAddress* local6 = pull.vpn_ipv6();
|
||||
|
||||
// configure interface
|
||||
iface_up(iface_name, pull.mtu, create, destroy);
|
||||
iface_config(iface_name, -1, pull, rtvec, create, destroy);
|
||||
|
||||
// Process Routes
|
||||
{
|
||||
for (const auto &route : pull.add_routes)
|
||||
{
|
||||
if (route.ipv6)
|
||||
{
|
||||
if (!pull.block_ipv6)
|
||||
add_del_route(route.address, route.prefix_length, local6->gateway, iface_name, R_ADD_ALL|R_IPv6, rtvec, create, destroy);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (local4 && !local4->gateway.empty())
|
||||
add_del_route(route.address, route.prefix_length, local4->gateway, iface_name, R_ADD_ALL, rtvec, create, destroy);
|
||||
else
|
||||
OPENVPN_LOG("ERROR: IPv4 route pushed without IPv4 ifconfig and/or route-gateway");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Process exclude routes
|
||||
{
|
||||
for (const auto &route : pull.exclude_routes)
|
||||
{
|
||||
if (route.ipv6)
|
||||
{
|
||||
OPENVPN_LOG("NOTE: exclude IPv6 routes not supported yet"); // fixme
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gw.v4.defined())
|
||||
add_del_route(route.address, route.prefix_length, gw.v4.addr().to_string(), gw.v4.dev(), R_ADD_SYS, rtvec, create, destroy);
|
||||
else
|
||||
OPENVPN_LOG("NOTE: cannot determine gateway for exclude IPv4 routes");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Process IPv4 redirect-gateway
|
||||
if (pull.reroute_gw.ipv4)
|
||||
{
|
||||
// add bypass route
|
||||
if (!pull.remote_address.ipv6 && !(pull.reroute_gw.flags & RedirectGatewayFlags::RG_LOCAL))
|
||||
add_del_route(pull.remote_address.address, 32, gw.v4.addr().to_string(), gw.v4.dev(), R_ADD_SYS, rtvec, create, destroy);
|
||||
|
||||
add_del_route("0.0.0.0", 1, local4->gateway, iface_name, R_ADD_ALL, rtvec, create, destroy);
|
||||
add_del_route("128.0.0.0", 1, local4->gateway, iface_name, R_ADD_ALL, rtvec, create, destroy);
|
||||
}
|
||||
|
||||
// Process IPv6 redirect-gateway
|
||||
if (pull.reroute_gw.ipv6 && !pull.block_ipv6)
|
||||
{
|
||||
// add bypass route
|
||||
if (pull.remote_address.ipv6 && !(pull.reroute_gw.flags & RedirectGatewayFlags::RG_LOCAL))
|
||||
add_del_route(pull.remote_address.address, 128, gw.v6.addr().to_string(), gw.v6.dev(), R_ADD_SYS|R_IPv6, rtvec, create, destroy);
|
||||
|
||||
add_del_route("0000::", 1, local6->gateway, iface_name, R_ADD_ALL|R_IPv6, rtvec, create, destroy);
|
||||
add_del_route("8000::", 1, local6->gateway, iface_name, R_ADD_ALL|R_IPv6, rtvec, create, destroy);
|
||||
}
|
||||
|
||||
// fixme -- Process block-ipv6
|
||||
|
||||
// fixme -- Handle pushed DNS servers
|
||||
}
|
||||
|
||||
class Setup : public TunBuilderSetup::Base
|
||||
{
|
||||
public:
|
||||
typedef RCPtr<Setup> Ptr;
|
||||
|
||||
struct Config : public TunBuilderSetup::Config
|
||||
{
|
||||
std::string iface_name;
|
||||
Layer layer; // OSI layer
|
||||
std::string dev_name;
|
||||
int txqueuelen;
|
||||
|
||||
#ifdef HAVE_JSON
|
||||
virtual Json::Value to_json() override
|
||||
{
|
||||
Json::Value root(Json::objectValue);
|
||||
root["iface_name"] = Json::Value(iface_name);
|
||||
root["layer"] = Json::Value(layer.str());
|
||||
root["dev_name"] = Json::Value(dev_name);
|
||||
root["txqueuelen"] = Json::Value(txqueuelen);
|
||||
return root;
|
||||
};
|
||||
|
||||
virtual void from_json(const Json::Value& root, const std::string& title) override
|
||||
{
|
||||
json::assert_dict(root, title);
|
||||
json::to_string(root, iface_name, "iface_name", title);
|
||||
layer = Layer::from_str(json::get_string(root, "layer", title));
|
||||
json::to_string(root, dev_name, "dev_name", title);
|
||||
json::to_int(root, txqueuelen, "txqueuelen", title);
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
virtual void destroy(std::ostream &os) override
|
||||
{
|
||||
// remove added routes
|
||||
if (remove_cmds)
|
||||
remove_cmds->execute(std::cout);
|
||||
}
|
||||
|
||||
virtual int establish(const TunBuilderCapture& pull, // defined by TunBuilderSetup::Base
|
||||
TunBuilderSetup::Config* config,
|
||||
Stop* stop,
|
||||
std::ostream& os) override
|
||||
{
|
||||
// get configuration
|
||||
Config *conf = dynamic_cast<Config *>(config);
|
||||
if (!conf)
|
||||
throw tun_linux_error("missing config");
|
||||
|
||||
static const char node[] = "/dev/net/tun";
|
||||
ScopedFD fd(open(node, O_RDWR));
|
||||
if (!fd.defined())
|
||||
OPENVPN_THROW(tun_open_error, "error opening tun device " << node << ": " << errinfo(errno));
|
||||
|
||||
struct ifreq ifr;
|
||||
std::memset(&ifr, 0, sizeof(ifr));
|
||||
ifr.ifr_flags = IFF_ONE_QUEUE;
|
||||
ifr.ifr_flags |= IFF_NO_PI;
|
||||
if (conf->layer() == Layer::OSI_LAYER_3)
|
||||
ifr.ifr_flags |= IFF_TUN;
|
||||
else if (conf->layer() == Layer::OSI_LAYER_2)
|
||||
ifr.ifr_flags |= IFF_TAP;
|
||||
else
|
||||
throw tun_layer_error("unknown OSI layer");
|
||||
|
||||
open_unit(conf->dev_name, ifr, fd);
|
||||
|
||||
if (fcntl (fd(), F_SETFL, O_NONBLOCK) < 0)
|
||||
throw tun_fcntl_error(errinfo(errno));
|
||||
|
||||
// Set the TX send queue size
|
||||
if (conf->txqueuelen)
|
||||
{
|
||||
struct ifreq netifr;
|
||||
ScopedFD ctl_fd(socket (AF_INET, SOCK_DGRAM, 0));
|
||||
|
||||
if (ctl_fd.defined())
|
||||
{
|
||||
std::memset(&netifr, 0, sizeof(netifr));
|
||||
strcpy (netifr.ifr_name, ifr.ifr_name);
|
||||
netifr.ifr_qlen = conf->txqueuelen;
|
||||
if (ioctl (ctl_fd(), SIOCSIFTXQLEN, (void *) &netifr) < 0)
|
||||
throw tun_tx_queue_len_error(errinfo(errno));
|
||||
}
|
||||
else
|
||||
throw tun_tx_queue_len_error(errinfo(errno));
|
||||
}
|
||||
|
||||
conf->iface_name = ifr.ifr_name;
|
||||
|
||||
ActionList::Ptr add_cmds = new ActionList();
|
||||
remove_cmds.reset(new ActionListReversed()); // remove commands executed in reversed order
|
||||
|
||||
// configure tun properties
|
||||
tun_config(ifr.ifr_name, pull, nullptr, *add_cmds, *remove_cmds);
|
||||
|
||||
// execute commands to bring up interface
|
||||
add_cmds->execute(std::cout);
|
||||
|
||||
return fd.release();
|
||||
}
|
||||
|
||||
private:
|
||||
void open_unit(const std::string& name, struct ifreq& ifr, ScopedFD& fd)
|
||||
{
|
||||
if (!name.empty())
|
||||
{
|
||||
const int max_units = 256;
|
||||
for (int unit = 0; unit < max_units; ++unit)
|
||||
{
|
||||
std::string n = name;
|
||||
if (unit)
|
||||
n += openvpn::to_string(unit);
|
||||
if (n.length() < IFNAMSIZ)
|
||||
::strcpy (ifr.ifr_name, n.c_str());
|
||||
else
|
||||
throw tun_name_error();
|
||||
if (ioctl (fd(), TUNSETIFF, (void *) &ifr) == 0)
|
||||
return;
|
||||
}
|
||||
const int eno = errno;
|
||||
OPENVPN_THROW(tun_ioctl_error, "failed to open tun device '" << name << "' after trying " << max_units << " units : " << errinfo(eno));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ioctl (fd(), TUNSETIFF, (void *) &ifr) < 0)
|
||||
{
|
||||
const int eno = errno;
|
||||
OPENVPN_THROW(tun_ioctl_error, "failed to open tun device '" << name << "' : " << errinfo(eno));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ActionListReversed::Ptr remove_cmds;
|
||||
};
|
||||
}
|
||||
} // namespace openvpn
|
||||
@@ -364,7 +364,7 @@ namespace openvpn {
|
||||
#endif
|
||||
};
|
||||
|
||||
virtual void destroy(std::ostream &os)
|
||||
virtual void destroy(std::ostream &os) override
|
||||
{
|
||||
// remove added routes
|
||||
if (remove_cmds)
|
||||
|
||||
@@ -17,7 +17,7 @@ cd $DEP_DIR
|
||||
rm -rf boost
|
||||
mkdir boost
|
||||
export LINK_MODE=static
|
||||
export TARGETS="android-a8a android-a8a-dbg android-a7a android-a7a-dbg android android-dbg"
|
||||
export TARGETS="android-a8a android-a8a-dbg android-a7a android-a7a-dbg"
|
||||
export SDK_PATH_SCRIPT=$O3/core/vars/android-sdk-path
|
||||
$O3/core/deps/boost/build-boost
|
||||
exit 0
|
||||
|
||||
@@ -15,7 +15,7 @@ cd $DEP_DIR
|
||||
rm -rf lzo
|
||||
mkdir lzo
|
||||
|
||||
for target in android-a8a android-a8a-dbg android-a7a android-a7a-dbg android android-dbg ; do
|
||||
for target in android-a8a android-a8a-dbg android-a7a android-a7a-dbg ; do
|
||||
echo '***************' TARGET $target
|
||||
TARGET=$target $O3/core/deps/lzo/build-lzo
|
||||
done
|
||||
|
||||
@@ -15,7 +15,7 @@ cd $DEP_DIR
|
||||
rm -rf minicrypto
|
||||
mkdir minicrypto
|
||||
|
||||
for target in android android-dbg android-a7a android-a7a-dbg ; do
|
||||
for target in android-a7a android-a7a-dbg ; do
|
||||
echo '***************' TARGET $target
|
||||
TARGET=$target $O3/core/deps/minicrypto/build-minicrypto
|
||||
done
|
||||
|
||||
@@ -18,7 +18,7 @@ mini=0
|
||||
rm -rf polarssl
|
||||
mkdir polarssl
|
||||
|
||||
for target in android-a8a android-a8a-dbg android-a7a android-a7a-dbg android android-dbg ; do
|
||||
for target in android-a8a android-a8a-dbg android-a7a android-a7a-dbg ; do
|
||||
echo '***************' TARGET $target
|
||||
VERBOSE=1 TARGET=$target CMAKE_TARGET=android USE_MINICRYPTO=$mini MINICRYPTO_DIR=$(pwd)/minicrypto/minicrypto-$target $O3/core/deps/polarssl/build-polarssl
|
||||
mv polarssl-$target polarssl/
|
||||
|
||||
@@ -15,31 +15,28 @@ fi
|
||||
|
||||
if [ -d "$SDK" ]; then
|
||||
echo "Android SDK already exists at $SDK. Doing only update"
|
||||
yes | $SDK/tools/bin/sdkmanager --licenses
|
||||
$SDK/tools/bin/sdkmanager --update
|
||||
exit 0
|
||||
else
|
||||
. $O3/core/deps/functions.sh
|
||||
|
||||
FNAME=sdk-tools-linux-3859397.zip
|
||||
URL=https://dl.google.com/android/repository/${FNAME}
|
||||
CSUM=444e22ce8ca0f67353bda4b85175ed3731cae3ffa695ca18119cbacef1c1bea0
|
||||
|
||||
download
|
||||
|
||||
cd $DEP_DIR
|
||||
rm -rf android-sdk
|
||||
mkdir android-sdk
|
||||
|
||||
. $O3/core/vars/android-sdk-path
|
||||
|
||||
cd $SDK
|
||||
unzip $DL/$FNAME
|
||||
fi
|
||||
|
||||
. $O3/core/deps/functions.sh
|
||||
|
||||
FNAME=sdk-tools-linux-3859397.zip
|
||||
URL=https://dl.google.com/android/repository/${FNAME}
|
||||
CSUM=444e22ce8ca0f67353bda4b85175ed3731cae3ffa695ca18119cbacef1c1bea0
|
||||
|
||||
download
|
||||
|
||||
cd $DEP_DIR
|
||||
rm -rf android-sdk
|
||||
mkdir android-sdk
|
||||
|
||||
. $O3/core/vars/android-sdk-path
|
||||
|
||||
cd $SDK
|
||||
unzip $DL/$FNAME
|
||||
|
||||
yes | $SDK/tools/bin/sdkmanager --licenses
|
||||
$SDK/tools/bin/sdkmanager --update
|
||||
$SDK/tools/bin/sdkmanager 'build-tools;26.0.2' \
|
||||
$SDK/tools/bin/sdkmanager --install 'build-tools;26.0.2' \
|
||||
'ndk-bundle' \
|
||||
'extras;android;m2repository' \
|
||||
'patcher;v4' \
|
||||
|
||||
@@ -15,7 +15,7 @@ cd $DEP_DIR
|
||||
rm -rf snappy
|
||||
mkdir snappy
|
||||
|
||||
for target in android-a8a android-a8a-dbg android-a7a android-a7a-dbg android android-dbg ; do
|
||||
for target in android-a8a android-a8a-dbg android-a7a android-a7a-dbg ; do
|
||||
echo '***************' TARGET $target
|
||||
TARGET=$target $O3/core/deps/snappy/build-snappy
|
||||
done
|
||||
|
||||
@@ -39,7 +39,7 @@ $NDK/build/tools/make-standalone-toolchain.sh \
|
||||
--toolchain=$ABI-$ABI_VER \
|
||||
--stl=gnustl \
|
||||
--arch=arm \
|
||||
--platform=android-14 \
|
||||
--platform=android-16 \
|
||||
--install-dir=$DEST
|
||||
cd $DEST/$ABI/bin
|
||||
ln -s ../../bin/$ABI-gcc cc
|
||||
@@ -58,7 +58,7 @@ $NDK/build/tools/make-standalone-toolchain.sh \
|
||||
--toolchain=$ABI-$ABI_VER \
|
||||
--stl=gnustl \
|
||||
--arch=x86 \
|
||||
--platform=android-14 \
|
||||
--platform=android-16 \
|
||||
--install-dir=$DEST
|
||||
cd $DEST/$SUB/bin
|
||||
ln -s ../../bin/$SUB-gcc cc
|
||||
|
||||
@@ -242,8 +242,12 @@ fi
|
||||
|
||||
# Cityhash
|
||||
if [ "$CITY" = "1" ]; then
|
||||
LIBDIRS="$LIBDIRS -L$DEP_DIR/cityhash/cityhash-$PLATFORM/lib"
|
||||
CPPFLAGS="$CPPFLAGS -I$DEP_DIR/cityhash/cityhash-$PLATFORM/include"
|
||||
if [ -d "$DEP_DIR/cityhash/cityhash-$PLATFORM/lib" ]; then
|
||||
LIBDIRS="$LIBDIRS -L$DEP_DIR/cityhash/cityhash-$PLATFORM/lib"
|
||||
fi
|
||||
if [ -d "$DEP_DIR/cityhash/cityhash-$PLATFORM/include" ]; then
|
||||
CPPFLAGS="$CPPFLAGS -I$DEP_DIR/cityhash/cityhash-$PLATFORM/include"
|
||||
fi
|
||||
LIBS="$LIBS -lcityhash"
|
||||
CPPFLAGS="$CPPFLAGS -DHAVE_CITYHASH"
|
||||
fi
|
||||
|
||||
51
scripts/update-copyright
Executable file
51
scripts/update-copyright
Executable file
@@ -0,0 +1,51 @@
|
||||
#!/bin/sh
|
||||
# update-copyright - Simple tool to update the Copyright lines
|
||||
# in all files checked into git
|
||||
#
|
||||
# Copyright (C) 2018 OpenVPN Inc
|
||||
# Copyright (C) 2018 David Sommerseth <davids@openvpn.net>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU 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 <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
# Basic shell sanity
|
||||
set -eu
|
||||
|
||||
# Simple argument control
|
||||
if [ $# -ne 1 ]; then
|
||||
echo "Usage: $0 <New Copyright Year>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Only update Copyright lines with these owners
|
||||
# The 'or' operator is GNU sed specific, and must be \|
|
||||
UPDATE_COPYRIGHT_LINES="OpenVPN Inc\|@openvpn\.net\\|unstable\.cc\|gmail\.com\|@fox-it\.com"
|
||||
COPY_YEAR="$1"
|
||||
|
||||
cd "$(git rev-parse --show-toplevel)"
|
||||
for file in $(git ls-files | grep -v deps/);
|
||||
do
|
||||
echo -n "Updating $file ..."
|
||||
# The first sed operation covers 20xx-20yy copyright lines,
|
||||
# The second sed operation changes 20xx -> 20xx-20yy
|
||||
sed -e "/$UPDATE_COPYRIGHT_LINES/s/\(Copyright (C) 20..-\)\(20..\)[[:blank:]]\+/\1$COPY_YEAR /" \
|
||||
-e "/$UPDATE_COPYRIGHT_LINES/s/\(Copyright (C) \)\(20..\)[[:blank:]]\+/\1\2-$COPY_YEAR /" \
|
||||
-e "/$UPDATE_COPYRIGHT_LINES/s/\(Copyright (C) $COPY_YEAR\)\(-$COPY_YEAR\)[[:blank:]]\+/\1 /" \
|
||||
-i $file
|
||||
echo " Done"
|
||||
done
|
||||
echo
|
||||
echo "** All files updated with $COPY_YEAR as the ending copyright year"
|
||||
echo
|
||||
exit 0
|
||||
@@ -80,6 +80,10 @@
|
||||
#include <openvpn/win/console.hpp>
|
||||
#endif
|
||||
|
||||
#ifdef USE_NETCFG
|
||||
#include "client/core-client-netcfg.hpp"
|
||||
#endif
|
||||
|
||||
using namespace openvpn;
|
||||
|
||||
namespace {
|
||||
@@ -141,9 +145,10 @@ public:
|
||||
#endif
|
||||
|
||||
private:
|
||||
virtual bool socket_protect(int socket) override
|
||||
bool socket_protect(int socket, std::string remote, bool ipv6) override
|
||||
{
|
||||
std::cout << "*** socket_protect " << socket << std::endl;
|
||||
std::cout << "*** socket_protect " << socket << " "
|
||||
<< remote << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -910,7 +915,13 @@ int openvpn_client(int argc, char *argv[], const std::string* profile_content)
|
||||
}
|
||||
else
|
||||
{
|
||||
#if defined(USE_NETCFG)
|
||||
DBus conn(G_BUS_TYPE_SYSTEM);
|
||||
conn.Connect();
|
||||
NetCfgTunBuilder<Client> client(conn.GetConnection());
|
||||
#else
|
||||
Client client;
|
||||
#endif
|
||||
const ClientAPI::EvalConfig eval = client.eval_config(config);
|
||||
if (eval.error)
|
||||
OPENVPN_THROW_EXCEPTION("eval config error: " << eval.message);
|
||||
|
||||
@@ -15,6 +15,7 @@ GCC_EXTRA="$GCC_EXTRA -DOPENVPN_SHOW_SESSION_TOKEN"
|
||||
[ "$BS64" = "1" ] && GCC_EXTRA="$GCC_EXTRA -DOPENVPN_BS64_DATA_LIMIT=2500000"
|
||||
[ "$ROVER" = "1" ] && GCC_EXTRA="$GCC_EXTRA -DOPENVPN_REMOTE_OVERRIDE"
|
||||
[ "$TLS" = "1" ] && GCC_EXTRA="$GCC_EXTRA -DOPENVPN_TLS_LINK"
|
||||
[ "$SITNL" = "1" ] && GCC_EXTRA="$GCC_EXTRA -DOPENVPN_USE_SITNL"
|
||||
if [ "$AGENT" = "1" ]; then
|
||||
GCC_EXTRA="$GCC_EXTRA -DOPENVPN_COMMAND_AGENT"
|
||||
fi
|
||||
@@ -23,9 +24,9 @@ export GCC_EXTRA
|
||||
|
||||
# determine platform
|
||||
if [ "$(uname)" == "Darwin" ]; then
|
||||
export PROF=osx64
|
||||
export PROF=${PROF:-osx64}
|
||||
elif [ "$(uname)" == "Linux" ]; then
|
||||
export PROF=linux
|
||||
export PROF=${PROF:-linux}
|
||||
else
|
||||
echo this script only knows how to build on Mac OS or Linux
|
||||
fi
|
||||
|
||||
@@ -41,7 +41,8 @@
|
||||
|
||||
#if !defined(USE_TLS_AUTH) && !defined(USE_TLS_CRYPT)
|
||||
//#define USE_TLS_AUTH
|
||||
#define USE_TLS_CRYPT
|
||||
//#define USE_TLS_CRYPT
|
||||
#define USE_TLS_CRYPT_V2
|
||||
#endif
|
||||
|
||||
#define OPENVPN_INSTRUMENTATION
|
||||
@@ -834,6 +835,8 @@ int test(const int thread_num)
|
||||
const std::string server_key = read_text("server.key");
|
||||
const std::string dh_pem = read_text("dh.pem");
|
||||
const std::string tls_auth_key = read_text("tls-auth.key");
|
||||
const std::string tls_crypt_v2_server_key = read_text("tls-crypt-v2-server.key");
|
||||
const std::string tls_crypt_v2_client_key = read_text("tls-crypt-v2-client.key");
|
||||
|
||||
// client config
|
||||
ClientSSLAPI::Config::Ptr cc(new ClientSSLAPI::Config());
|
||||
@@ -888,6 +891,17 @@ int test(const int thread_num)
|
||||
cp->tls_crypt_factory.reset(new CryptoTLSCryptFactory<ClientCryptoAPI>());
|
||||
cp->tls_key.parse(tls_auth_key);
|
||||
cp->set_tls_crypt_algs(CryptoAlgs::lookup("SHA256"), CryptoAlgs::lookup("AES-256-CTR"));
|
||||
#endif
|
||||
#ifdef USE_TLS_CRYPT_V2
|
||||
cp->tls_crypt_factory.reset(new CryptoTLSCryptFactory<ClientCryptoAPI>());
|
||||
cp->set_tls_crypt_algs(CryptoAlgs::lookup("SHA256"), CryptoAlgs::lookup("AES-256-CTR"));
|
||||
{
|
||||
TLSCryptV2ClientKey tls_crypt_v2_key(cp->tls_crypt_context);
|
||||
tls_crypt_v2_key.parse(tls_crypt_v2_client_key);
|
||||
tls_crypt_v2_key.extract_key(cp->tls_key);
|
||||
tls_crypt_v2_key.extract_wkc(cp->wkc);
|
||||
}
|
||||
cp->tls_crypt_v2 = true;
|
||||
#endif
|
||||
cp->reliable_window = 4;
|
||||
cp->max_ack_list = 4;
|
||||
@@ -959,10 +973,21 @@ int test(const int thread_num)
|
||||
sp->set_tls_auth_digest(CryptoAlgs::lookup(PROTO_DIGEST));
|
||||
sp->key_direction = 1;
|
||||
#endif
|
||||
#ifdef USE_TLS_CRYPT
|
||||
sp->tls_crypt_factory.reset(new CryptoTLSCryptFactory<ServerCryptoAPI>());
|
||||
#if defined(USE_TLS_CRYPT)
|
||||
sp->tls_crypt_factory.reset(new CryptoTLSCryptFactory<ClientCryptoAPI>());
|
||||
sp->tls_key.parse(tls_auth_key);
|
||||
sp->set_tls_crypt_algs(CryptoAlgs::lookup("SHA256"), CryptoAlgs::lookup("AES-256-CTR"));
|
||||
#endif
|
||||
#ifdef USE_TLS_CRYPT_V2
|
||||
sp->tls_crypt_factory.reset(new CryptoTLSCryptFactory<ClientCryptoAPI>());
|
||||
{
|
||||
TLSCryptV2ServerKey tls_crypt_v2_key;
|
||||
tls_crypt_v2_key.parse(tls_crypt_v2_server_key);
|
||||
tls_crypt_v2_key.extract_key(sp->tls_key);
|
||||
}
|
||||
sp->set_tls_crypt_algs(CryptoAlgs::lookup("SHA256"), CryptoAlgs::lookup("AES-256-CTR"));
|
||||
sp->tls_crypt_metadata_factory.reset(new CryptoTLSCryptMetadataFactory());
|
||||
sp->tls_crypt_v2 = true;
|
||||
#endif
|
||||
sp->reliable_window = 4;
|
||||
sp->max_ack_list = 4;
|
||||
|
||||
14
test/ssl/tls-crypt-v2-client.key
Normal file
14
test/ssl/tls-crypt-v2-client.key
Normal file
@@ -0,0 +1,14 @@
|
||||
-----BEGIN OpenVPN tls-crypt-v2 client key-----
|
||||
fxgWlYpYT1H8ZCW3/139Ip6WSAa2QQZUu64N/x3g7RzhYuaInPRpP9GLpeDpj/PP
|
||||
MOa0LuvbIr9Wm6V4+WUO+R8hOdfIMwtBlRleMDedFNRD5h1DCpoDdpgr5CxaPyqO
|
||||
H6eCvNP7POmqdGJyo9L6H9ndyetQp4r/8wXeYWSkcJKsIJsmyBqRzuODTENGYCqG
|
||||
FN3+XcUrEMYUyvb/c8NqDVQ6xpwc9+6N7840encSMZPYCq6o8J1QXZJ8sMoBEPa1
|
||||
gVtLCsPXp2oTs1h82NBpxO8BNPNFz1xIG+2Zy1NpU8PONnr0rtCRPNU7ejsG+p2I
|
||||
vRDt3VOf+3aD2eVFesR4NAWYTZlxg3eLG4zD/xSiGblBltbB/7qGPxgK6WOP2XD/
|
||||
V0Yh+TruX2vo4xjEXqV1umTx9K8u6nvaC8uv/72NsvPWkuAOEpY6qpDrqiya+zod
|
||||
zjrlKdLmftaTEMGURDIjooNygFOAania7UhLWOjhnzZFntLHoYmskF0C7om4CqPR
|
||||
dhf1OuyaD436yQVdt3t/8sjBGuY4hQZ3PuMKDEsHEzmq8bYwfmDf3U8IsK39NbXO
|
||||
Bh7Q3Gxxy0vTP2TRsGUbePh5ZveVtCJGe79tjtveLdEVdh+TsMB2xo/ZLFfjDPOx
|
||||
6xvj5xKQtyou5YawuniHn5nrDWbyARQDTmVl7a5w5HvK3SbuVDrJsuLiRohfKyah
|
||||
M17SAY5reFev6+piR+zT64zwTYdU20i28gEr
|
||||
-----END OpenVPN tls-crypt-v2 client key-----
|
||||
5
test/ssl/tls-crypt-v2-server.key
Normal file
5
test/ssl/tls-crypt-v2-server.key
Normal file
@@ -0,0 +1,5 @@
|
||||
-----BEGIN OpenVPN tls-crypt-v2 server key-----
|
||||
hn6VWraZG0o64iPI7faGYkwTMajjqhXqG2kC1X19jCl+aXhWPSgmDbRCT/pSfjLZ
|
||||
a2pKXP6DGdi3nuINKuPw4655AcuMaBe4b45+zJz5xk92NnNosLaTsanXtjfBNOK5
|
||||
S/M1f4cLZViVsJTDSMcINK/RCclWVK+IFi//CThZQM8=
|
||||
-----END OpenVPN tls-crypt-v2 server key-----
|
||||
@@ -1,143 +1,143 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{18446924-20CC-4EB7-B639-A76C1422E5C2}</ProjectGuid>
|
||||
<RootNamespace>unittests</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup />
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>TurnOffAllWarnings</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>false</SDLCheck>
|
||||
<AdditionalIncludeDirectories>$(OVPN3_BUILD)\amd64\mbedtls\include;$(OVPN3_BUILD)\amd64\lz4\lib;$(GTEST_ROOT)\googletest\include;$(OVPN3_CORE);$(OVPN3_BUILD)\amd64\asio\asio\include;$(OVPN3_TAP_WINDOWS)\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;NOMINMAX;_WIN32_WINNT=0x0600;USE_ASIO;ASIO_STANDALONE;USE_MBEDTLS;HAVE_LZ4;OPENVPN_FORCE_TUN_NULL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>lz4.lib;mbedtls.lib;Iphlpapi.lib;gtestd.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(OVPN3_BUILD)\amd64\mbedtls\library;$(GTEST_ROOT)\msvc\gtest\Debug\;%(AdditionalLibraryDirectories);$(OVPN3_BUILD)\amd64\lz4\lib</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>TurnOffAllWarnings</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>false</SDLCheck>
|
||||
<AdditionalIncludeDirectories>$(OVPN3_ROOT)\deps\amd64\mbedtls\include;$(OVPN3_ROOT)\deps\amd64\lz4\lib;$(GTEST_ROOT)\googletest\include;$(OVPN3_ROOT)\core;$(OVPN3_ROOT)\deps\amd64\asio\asio\include;$(OVPN3_ROOT)\deps\amd64\tap-windows\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;NOMINMAX;_WIN32_WINNT=0x0600;USE_ASIO;ASIO_STANDALONE;USE_MBEDTLS;HAVE_LZ4;OPENVPN_FORCE_TUN_NULL;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>lz4.lib;mbedtls.lib;Iphlpapi.lib;gtest.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(OVPN3_ROOT)\deps\amd64\mbedtls\library;$(GTEST_ROOT)\googlemock\gtest\Debug\;%(AdditionalLibraryDirectories);$(OVPN3_ROOT)\deps\amd64\lz4\lib</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>TurnOffAllWarnings</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>false</SDLCheck>
|
||||
<AdditionalIncludeDirectories>$(OVPN3_BUILD)\amd64\mbedtls\include;$(OVPN3_BUILD)\amd64\lz4\lib;$(GTEST_ROOT)\googletest\include;$(OVPN3_CORE);$(OVPN3_BUILD)\amd64\asio\asio\include;$(OVPN3_TAP_WINDOWS)\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;NOMINMAX;_WIN32_WINNT=0x0600;USE_ASIO;ASIO_STANDALONE;USE_MBEDTLS;HAVE_LZ4;OPENVPN_FORCE_TUN_NULL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalDependencies>lz4.lib;mbedtls.lib;Iphlpapi.lib;gtest.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(OVPN3_BUILD)\amd64\mbedtls\library;$(GTEST_ROOT)\msvc\gtest\Release\;%(AdditionalLibraryDirectories);$(OVPN3_BUILD)\amd64\lz4\lib</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>TurnOffAllWarnings</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>false</SDLCheck>
|
||||
<AdditionalIncludeDirectories>$(OVPN3_ROOT)\deps\amd64\mbedtls\include;$(OVPN3_ROOT)\deps\amd64\lz4\lib;$(GTEST_ROOT)\googletest\include;$(OVPN3_ROOT)\core;$(OVPN3_ROOT)\deps\amd64\asio\asio\include;$(OVPN3_ROOT)\deps\amd64\tap-windows\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;NOMINMAX;_WIN32_WINNT=0x0600;USE_ASIO;ASIO_STANDALONE;USE_MBEDTLS;HAVE_LZ4;OPENVPN_FORCE_TUN_NULL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalDependencies>lz4.lib;mbedtls.lib;Iphlpapi.lib;gtest.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(OVPN3_ROOT)\deps\amd64\mbedtls\library;$(GTEST_ROOT)\googlemock\gtest\Release\;%(AdditionalLibraryDirectories);$(OVPN3_ROOT)\deps\amd64\lz4\lib</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="test_log.cpp" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{18446924-20CC-4EB7-B639-A76C1422E5C2}</ProjectGuid>
|
||||
<RootNamespace>unittests</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0.17134.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup />
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>TurnOffAllWarnings</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>false</SDLCheck>
|
||||
<AdditionalIncludeDirectories>$(OVPN3_BUILD)\amd64\mbedtls\include;$(OVPN3_BUILD)\amd64\lz4\lib;$(GTEST_ROOT)\googletest\include;$(OVPN3_CORE);$(OVPN3_BUILD)\amd64\asio\asio\include;$(OVPN3_TAP_WINDOWS)\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;NOMINMAX;_WIN32_WINNT=0x0600;USE_ASIO;ASIO_STANDALONE;USE_MBEDTLS;HAVE_LZ4;OPENVPN_FORCE_TUN_NULL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>lz4.lib;mbedtls.lib;Iphlpapi.lib;gtestd.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(OVPN3_BUILD)\amd64\mbedtls\library;$(GTEST_ROOT)\msvc\gtest\Debug\;%(AdditionalLibraryDirectories);$(OVPN3_BUILD)\amd64\lz4\lib</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>TurnOffAllWarnings</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>false</SDLCheck>
|
||||
<AdditionalIncludeDirectories>$(OVPN3_ROOT)\deps\amd64\mbedtls\include;$(OVPN3_ROOT)\deps\amd64\lz4\lib;$(GTEST_ROOT)\googletest\include;$(OVPN3_ROOT)\core;$(OVPN3_ROOT)\deps\amd64\asio\asio\include;$(OVPN3_ROOT)\deps\amd64\tap-windows\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;NOMINMAX;_WIN32_WINNT=0x0600;USE_ASIO;ASIO_STANDALONE;USE_MBEDTLS;HAVE_LZ4;OPENVPN_FORCE_TUN_NULL;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>lz4.lib;mbedtls.lib;Iphlpapi.lib;gtest.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(OVPN3_ROOT)\deps\amd64\mbedtls\library;$(GTEST_ROOT)\googlemock\gtest\Debug\;%(AdditionalLibraryDirectories);$(OVPN3_ROOT)\deps\amd64\lz4\lib</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>TurnOffAllWarnings</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>false</SDLCheck>
|
||||
<AdditionalIncludeDirectories>$(OVPN3_BUILD)\amd64\mbedtls\include;$(OVPN3_BUILD)\amd64\lz4\lib;$(GTEST_ROOT)\googletest\include;$(OVPN3_CORE);$(OVPN3_BUILD)\amd64\asio\asio\include;$(OVPN3_TAP_WINDOWS)\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;NOMINMAX;_WIN32_WINNT=0x0600;USE_ASIO;ASIO_STANDALONE;USE_MBEDTLS;HAVE_LZ4;OPENVPN_FORCE_TUN_NULL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalDependencies>lz4.lib;mbedtls.lib;Iphlpapi.lib;gtest.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(OVPN3_BUILD)\amd64\mbedtls\library;$(GTEST_ROOT)\msvc\gtest\Release\;%(AdditionalLibraryDirectories);$(OVPN3_BUILD)\amd64\lz4\lib</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>TurnOffAllWarnings</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>false</SDLCheck>
|
||||
<AdditionalIncludeDirectories>$(OVPN3_ROOT)\deps\amd64\mbedtls\include;$(OVPN3_ROOT)\deps\amd64\lz4\lib;$(GTEST_ROOT)\googletest\include;$(OVPN3_ROOT)\core;$(OVPN3_ROOT)\deps\amd64\asio\asio\include;$(OVPN3_ROOT)\deps\amd64\tap-windows\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;NOMINMAX;_WIN32_WINNT=0x0600;USE_ASIO;ASIO_STANDALONE;USE_MBEDTLS;HAVE_LZ4;OPENVPN_FORCE_TUN_NULL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalDependencies>lz4.lib;mbedtls.lib;Iphlpapi.lib;gtest.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(OVPN3_ROOT)\deps\amd64\mbedtls\library;$(GTEST_ROOT)\googlemock\gtest\Release\;%(AdditionalLibraryDirectories);$(OVPN3_ROOT)\deps\amd64\lz4\lib</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="test_log.cpp" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
@@ -1,15 +0,0 @@
|
||||
[ -z "$DEP_DIR" ] && export DEP_DIR=$HOME/src/android
|
||||
export PLATFORM=android
|
||||
export ABI=armeabi
|
||||
export DEBUG_BUILD=0
|
||||
export OTHER_COMPILER_FLAGS=""
|
||||
export CXX_COMPILER_FLAGS="-std=c++1y"
|
||||
export LIB_OPT_LEVEL="-O3"
|
||||
export LIB_FPIC="-fPIC"
|
||||
export TC=$DEP_DIR/tc-arm
|
||||
export PLATFORM_FLAGS="-march=armv5te --sysroot=$TC/sysroot"
|
||||
export GPP_CMD="$TC/bin/arm-linux-androideabi-g++"
|
||||
export GCC_CMD="$TC/bin/arm-linux-androideabi-gcc"
|
||||
|
||||
[ -z "$VARS_SAVE_PATH" ] && VARS_SAVE_PATH="$PATH"
|
||||
export PATH="$TC/bin:$TC/arm-linux-androideabi/bin:$VARS_SAVE_PATH"
|
||||
@@ -7,7 +7,7 @@ export CXX_COMPILER_FLAGS="-std=c++1y"
|
||||
export LIB_OPT_LEVEL="-O3"
|
||||
export LIB_FPIC="-fPIC"
|
||||
export TC=$DEP_DIR/tc-arm
|
||||
export PLATFORM_FLAGS="-D__LP32__ -D__ANDROID_API__=14 -march=armv7-a -mthumb -fomit-frame-pointer --sysroot=$TC/sysroot"
|
||||
export PLATFORM_FLAGS="-D__LP32__ -march=armv7-a -mthumb -fomit-frame-pointer --sysroot=$TC/sysroot"
|
||||
export GPP_CMD="$TC/bin/arm-linux-androideabi-g++"
|
||||
export GCC_CMD="$TC/bin/arm-linux-androideabi-gcc"
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ export CXX_COMPILER_FLAGS="-std=c++1y"
|
||||
export LIB_OPT_LEVEL="-O3"
|
||||
export LIB_FPIC="-fPIC"
|
||||
export TC=$DEP_DIR/tc-arm64
|
||||
export PLATFORM_FLAGS="-D__ANDROID_API__=21 -march=armv8-a -fomit-frame-pointer --sysroot=$TC/sysroot"
|
||||
export PLATFORM_FLAGS="-march=armv8-a -fomit-frame-pointer --sysroot=$TC/sysroot"
|
||||
export GPP_CMD="$TC/bin/aarch64-linux-android-g++"
|
||||
export GCC_CMD="$TC/bin/aarch64-linux-android-gcc"
|
||||
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
[ -z "$DEP_DIR" ] && export DEP_DIR=$HOME/src/android
|
||||
export PLATFORM=android-dbg
|
||||
export ABI=armeabi
|
||||
export DEBUG_BUILD=1
|
||||
export OTHER_COMPILER_FLAGS="-g"
|
||||
export CXX_COMPILER_FLAGS="-std=c++1y"
|
||||
export LIB_OPT_LEVEL="-O0"
|
||||
export LIB_FPIC="-fPIC"
|
||||
export TC=$DEP_DIR/tc-arm
|
||||
export PLATFORM_FLAGS="-march=armv5te --sysroot=$TC/sysroot"
|
||||
export GPP_CMD="$TC/bin/arm-linux-androideabi-g++"
|
||||
export GCC_CMD="$TC/bin/arm-linux-androideabi-gcc"
|
||||
|
||||
[ -z "$VARS_SAVE_PATH" ] && VARS_SAVE_PATH="$PATH"
|
||||
export PATH="$TC/bin:$TC/arm-linux-androideabi/bin:$VARS_SAVE_PATH"
|
||||
@@ -7,7 +7,7 @@ export CXX_COMPILER_FLAGS="-std=c++1y"
|
||||
export LIB_OPT_LEVEL="-O3"
|
||||
export LIB_FPIC="-fPIC"
|
||||
export TC=$DEP_DIR/tc-x86
|
||||
export PLATFORM_FLAGS="-D__LP32__ -D__ANDROID_API__=14 -march=i686 -fomit-frame-pointer --sysroot=$TC/sysroot"
|
||||
export PLATFORM_FLAGS="-D__LP32__ -march=i686 -fomit-frame-pointer --sysroot=$TC/sysroot"
|
||||
export GPP_CMD="$TC/bin/i686-linux-android-g++"
|
||||
export GCC_CMD="$TC/bin/i686-linux-android-gcc"
|
||||
|
||||
|
||||
@@ -1,44 +1,45 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 14
|
||||
VisualStudioVersion = 14.0.25420.1
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cli", "ovpn3-core.vcxproj", "{1F891260-2039-494F-9777-EC5166AF31BC}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unittests", "..\test\unittests\unittests.vcxproj", "{18446924-20CC-4EB7-B639-A76C1422E5C2}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|ARM = Debug|ARM
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|ARM = Release|ARM
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{1F891260-2039-494F-9777-EC5166AF31BC}.Debug|ARM.ActiveCfg = Debug|Win32
|
||||
{1F891260-2039-494F-9777-EC5166AF31BC}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{1F891260-2039-494F-9777-EC5166AF31BC}.Debug|x64.Build.0 = Debug|x64
|
||||
{1F891260-2039-494F-9777-EC5166AF31BC}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{1F891260-2039-494F-9777-EC5166AF31BC}.Debug|x86.Build.0 = Debug|Win32
|
||||
{1F891260-2039-494F-9777-EC5166AF31BC}.Release|ARM.ActiveCfg = Release|Win32
|
||||
{1F891260-2039-494F-9777-EC5166AF31BC}.Release|x64.ActiveCfg = Release|x64
|
||||
{1F891260-2039-494F-9777-EC5166AF31BC}.Release|x64.Build.0 = Release|x64
|
||||
{1F891260-2039-494F-9777-EC5166AF31BC}.Release|x86.ActiveCfg = Release|Win32
|
||||
{1F891260-2039-494F-9777-EC5166AF31BC}.Release|x86.Build.0 = Release|Win32
|
||||
{18446924-20CC-4EB7-B639-A76C1422E5C2}.Debug|ARM.ActiveCfg = Debug|Win32
|
||||
{18446924-20CC-4EB7-B639-A76C1422E5C2}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{18446924-20CC-4EB7-B639-A76C1422E5C2}.Debug|x64.Build.0 = Debug|x64
|
||||
{18446924-20CC-4EB7-B639-A76C1422E5C2}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{18446924-20CC-4EB7-B639-A76C1422E5C2}.Debug|x86.Build.0 = Debug|Win32
|
||||
{18446924-20CC-4EB7-B639-A76C1422E5C2}.Release|ARM.ActiveCfg = Release|Win32
|
||||
{18446924-20CC-4EB7-B639-A76C1422E5C2}.Release|x64.ActiveCfg = Release|x64
|
||||
{18446924-20CC-4EB7-B639-A76C1422E5C2}.Release|x64.Build.0 = Release|x64
|
||||
{18446924-20CC-4EB7-B639-A76C1422E5C2}.Release|x86.ActiveCfg = Release|Win32
|
||||
{18446924-20CC-4EB7-B639-A76C1422E5C2}.Release|x86.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.28307.106
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cli", "ovpn3-core.vcxproj", "{1F891260-2039-494F-9777-EC5166AF31BC}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unittests", "..\test\unittests\unittests.vcxproj", "{18446924-20CC-4EB7-B639-A76C1422E5C2}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|ARM = Debug|ARM
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|ARM = Release|ARM
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{1F891260-2039-494F-9777-EC5166AF31BC}.Debug|ARM.ActiveCfg = Debug|x64
|
||||
{1F891260-2039-494F-9777-EC5166AF31BC}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{1F891260-2039-494F-9777-EC5166AF31BC}.Debug|x64.Build.0 = Debug|x64
|
||||
{1F891260-2039-494F-9777-EC5166AF31BC}.Debug|x86.ActiveCfg = Debug|x64
|
||||
{1F891260-2039-494F-9777-EC5166AF31BC}.Release|ARM.ActiveCfg = Release|x64
|
||||
{1F891260-2039-494F-9777-EC5166AF31BC}.Release|x64.ActiveCfg = Release|x64
|
||||
{1F891260-2039-494F-9777-EC5166AF31BC}.Release|x64.Build.0 = Release|x64
|
||||
{1F891260-2039-494F-9777-EC5166AF31BC}.Release|x86.ActiveCfg = Release|x64
|
||||
{18446924-20CC-4EB7-B639-A76C1422E5C2}.Debug|ARM.ActiveCfg = Debug|Win32
|
||||
{18446924-20CC-4EB7-B639-A76C1422E5C2}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{18446924-20CC-4EB7-B639-A76C1422E5C2}.Debug|x64.Build.0 = Debug|x64
|
||||
{18446924-20CC-4EB7-B639-A76C1422E5C2}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{18446924-20CC-4EB7-B639-A76C1422E5C2}.Debug|x86.Build.0 = Debug|Win32
|
||||
{18446924-20CC-4EB7-B639-A76C1422E5C2}.Release|ARM.ActiveCfg = Release|Win32
|
||||
{18446924-20CC-4EB7-B639-A76C1422E5C2}.Release|x64.ActiveCfg = Release|x64
|
||||
{18446924-20CC-4EB7-B639-A76C1422E5C2}.Release|x64.Build.0 = Release|x64
|
||||
{18446924-20CC-4EB7-B639-A76C1422E5C2}.Release|x86.ActiveCfg = Release|Win32
|
||||
{18446924-20CC-4EB7-B639-A76C1422E5C2}.Release|x86.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {2C22702B-DF56-4CEB-9CA4-C999BD01FD03}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
||||
@@ -1,14 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
@@ -18,9 +10,6 @@
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\test\ovpncli\cli.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\client\ovpncli.hpp" />
|
||||
<ClInclude Include="..\openvpn\addr\addrlist.hpp" />
|
||||
@@ -31,6 +20,8 @@
|
||||
<ClInclude Include="..\openvpn\addr\ipv6.hpp" />
|
||||
<ClInclude Include="..\openvpn\addr\macaddr.hpp" />
|
||||
<ClInclude Include="..\openvpn\addr\pool.hpp" />
|
||||
<ClInclude Include="..\openvpn\addr\quoteip.hpp" />
|
||||
<ClInclude Include="..\openvpn\addr\randaddr.hpp" />
|
||||
<ClInclude Include="..\openvpn\addr\range.hpp" />
|
||||
<ClInclude Include="..\openvpn\addr\regex.hpp" />
|
||||
<ClInclude Include="..\openvpn\addr\route.hpp" />
|
||||
@@ -62,6 +53,7 @@
|
||||
<ClInclude Include="..\openvpn\asio\asiocontext.hpp" />
|
||||
<ClInclude Include="..\openvpn\asio\asioerr.hpp" />
|
||||
<ClInclude Include="..\openvpn\asio\asiopolysock.hpp" />
|
||||
<ClInclude Include="..\openvpn\asio\asioresolverres.hpp" />
|
||||
<ClInclude Include="..\openvpn\asio\asiosignal.hpp" />
|
||||
<ClInclude Include="..\openvpn\asio\asiostop.hpp" />
|
||||
<ClInclude Include="..\openvpn\asio\asiowork.hpp" />
|
||||
@@ -81,6 +73,7 @@
|
||||
<ClInclude Include="..\openvpn\buffer\bufread.hpp" />
|
||||
<ClInclude Include="..\openvpn\buffer\bufstr.hpp" />
|
||||
<ClInclude Include="..\openvpn\buffer\bufstream.hpp" />
|
||||
<ClInclude Include="..\openvpn\buffer\lz4.hpp" />
|
||||
<ClInclude Include="..\openvpn\buffer\memq.hpp" />
|
||||
<ClInclude Include="..\openvpn\buffer\safestr.hpp" />
|
||||
<ClInclude Include="..\openvpn\buffer\zlib.hpp" />
|
||||
@@ -101,12 +94,14 @@
|
||||
<ClInclude Include="..\openvpn\common\abort.hpp" />
|
||||
<ClInclude Include="..\openvpn\common\action.hpp" />
|
||||
<ClInclude Include="..\openvpn\common\actionthread.hpp" />
|
||||
<ClInclude Include="..\openvpn\common\appversion.hpp" />
|
||||
<ClInclude Include="..\openvpn\common\arch.hpp" />
|
||||
<ClInclude Include="..\openvpn\common\argv.hpp" />
|
||||
<ClInclude Include="..\openvpn\common\arraysize.hpp" />
|
||||
<ClInclude Include="..\openvpn\common\asyncsleep.hpp" />
|
||||
<ClInclude Include="..\openvpn\common\autoreset.hpp" />
|
||||
<ClInclude Include="..\openvpn\common\base64.hpp" />
|
||||
<ClInclude Include="..\openvpn\common\bigmutex.hpp" />
|
||||
<ClInclude Include="..\openvpn\common\binprefix.hpp" />
|
||||
<ClInclude Include="..\openvpn\common\circ_list.hpp" />
|
||||
<ClInclude Include="..\openvpn\common\cleanup.hpp" />
|
||||
@@ -134,17 +129,19 @@
|
||||
<ClInclude Include="..\openvpn\common\hostlist.hpp" />
|
||||
<ClInclude Include="..\openvpn\common\hostname.hpp" />
|
||||
<ClInclude Include="..\openvpn\common\hostport.hpp" />
|
||||
<ClInclude Include="..\openvpn\common\inotify.hpp" />
|
||||
<ClInclude Include="..\openvpn\common\jsonlib.hpp" />
|
||||
<ClInclude Include="..\openvpn\common\lex.hpp" />
|
||||
<ClInclude Include="..\openvpn\common\likely.hpp" />
|
||||
<ClInclude Include="..\openvpn\common\link.hpp" />
|
||||
<ClInclude Include="..\openvpn\common\logrotate.hpp" />
|
||||
<ClInclude Include="..\openvpn\common\memneq.hpp" />
|
||||
<ClInclude Include="..\openvpn\common\mode.hpp" />
|
||||
<ClInclude Include="..\openvpn\common\modstat.hpp" />
|
||||
<ClInclude Include="..\openvpn\common\msgwin.hpp" />
|
||||
<ClInclude Include="..\openvpn\common\number.hpp" />
|
||||
<ClInclude Include="..\openvpn\common\olong.hpp" />
|
||||
<ClInclude Include="..\openvpn\common\options.hpp" />
|
||||
<ClInclude Include="..\openvpn\common\option_error.hpp" />
|
||||
<ClInclude Include="..\openvpn\common\ostream.hpp" />
|
||||
<ClInclude Include="..\openvpn\common\path.hpp" />
|
||||
<ClInclude Include="..\openvpn\common\peercred.hpp" />
|
||||
@@ -182,6 +179,7 @@
|
||||
<ClInclude Include="..\openvpn\common\usecount.hpp" />
|
||||
<ClInclude Include="..\openvpn\common\usergroup.hpp" />
|
||||
<ClInclude Include="..\openvpn\common\userpass.hpp" />
|
||||
<ClInclude Include="..\openvpn\common\valgrind.hpp" />
|
||||
<ClInclude Include="..\openvpn\common\version.hpp" />
|
||||
<ClInclude Include="..\openvpn\common\waitbarrier.hpp" />
|
||||
<ClInclude Include="..\openvpn\common\write.hpp" />
|
||||
@@ -210,6 +208,9 @@
|
||||
<ClInclude Include="..\openvpn\crypto\packet_id.hpp" />
|
||||
<ClInclude Include="..\openvpn\crypto\selftest.hpp" />
|
||||
<ClInclude Include="..\openvpn\crypto\static_key.hpp" />
|
||||
<ClInclude Include="..\openvpn\crypto\tls_crypt.hpp" />
|
||||
<ClInclude Include="..\openvpn\dco\dcocli.hpp" />
|
||||
<ClInclude Include="..\openvpn\dco\ipcollbase.hpp" />
|
||||
<ClInclude Include="..\openvpn\error\error.hpp" />
|
||||
<ClInclude Include="..\openvpn\error\excode.hpp" />
|
||||
<ClInclude Include="..\openvpn\frame\frame.hpp" />
|
||||
@@ -226,6 +227,7 @@
|
||||
<ClInclude Include="..\openvpn\http\urlencode.hpp" />
|
||||
<ClInclude Include="..\openvpn\http\urlparm.hpp" />
|
||||
<ClInclude Include="..\openvpn\http\urlparse.hpp" />
|
||||
<ClInclude Include="..\openvpn\http\validate_uri.hpp" />
|
||||
<ClInclude Include="..\openvpn\http\webexcept.hpp" />
|
||||
<ClInclude Include="..\openvpn\init\cryptoinit.hpp" />
|
||||
<ClInclude Include="..\openvpn\init\engineinit.hpp" />
|
||||
@@ -233,14 +235,27 @@
|
||||
<ClInclude Include="..\openvpn\io\io.hpp" />
|
||||
<ClInclude Include="..\openvpn\ip\dhcp.hpp" />
|
||||
<ClInclude Include="..\openvpn\ip\eth.hpp" />
|
||||
<ClInclude Include="..\openvpn\ip\icmp.hpp" />
|
||||
<ClInclude Include="..\openvpn\ip\ip.hpp" />
|
||||
<ClInclude Include="..\openvpn\ip\icmp4.hpp" />
|
||||
<ClInclude Include="..\openvpn\ip\icmp6.hpp" />
|
||||
<ClInclude Include="..\openvpn\ip\ip4.hpp" />
|
||||
<ClInclude Include="..\openvpn\ip\ip6.hpp" />
|
||||
<ClInclude Include="..\openvpn\ip\ipcommon.hpp" />
|
||||
<ClInclude Include="..\openvpn\ip\tcp.hpp" />
|
||||
<ClInclude Include="..\openvpn\ip\udp.hpp" />
|
||||
<ClInclude Include="..\openvpn\kovpn\kocrypto.hpp" />
|
||||
<ClInclude Include="..\openvpn\kovpn\kodev.hpp" />
|
||||
<ClInclude Include="..\openvpn\kovpn\korekey.hpp" />
|
||||
<ClInclude Include="..\openvpn\kovpn\koroute.hpp" />
|
||||
<ClInclude Include="..\openvpn\kovpn\kostats.hpp" />
|
||||
<ClInclude Include="..\openvpn\kovpn\kovpn.hpp" />
|
||||
<ClInclude Include="..\openvpn\legal\copyright.hpp" />
|
||||
<ClInclude Include="..\openvpn\linux\core.hpp" />
|
||||
<ClInclude Include="..\openvpn\linux\daemon_alive.hpp" />
|
||||
<ClInclude Include="..\openvpn\linux\procfs.hpp" />
|
||||
<ClInclude Include="..\openvpn\log\logbase.hpp" />
|
||||
<ClInclude Include="..\openvpn\log\logbasesimple.hpp" />
|
||||
<ClInclude Include="..\openvpn\log\logbasesimplemac.hpp" />
|
||||
<ClInclude Include="..\openvpn\log\logdatetime.hpp" />
|
||||
<ClInclude Include="..\openvpn\log\lognull.hpp" />
|
||||
<ClInclude Include="..\openvpn\log\logperiod.hpp" />
|
||||
<ClInclude Include="..\openvpn\log\logsimple.hpp" />
|
||||
@@ -298,6 +313,7 @@
|
||||
<ClInclude Include="..\openvpn\proxy\proxyauth.hpp" />
|
||||
<ClInclude Include="..\openvpn\random\devurand.hpp" />
|
||||
<ClInclude Include="..\openvpn\random\mtrandapi.hpp" />
|
||||
<ClInclude Include="..\openvpn\random\rand2.hpp" />
|
||||
<ClInclude Include="..\openvpn\random\randapi.hpp" />
|
||||
<ClInclude Include="..\openvpn\random\randbytestore.hpp" />
|
||||
<ClInclude Include="..\openvpn\reliable\relack.hpp" />
|
||||
@@ -325,6 +341,7 @@
|
||||
<ClInclude Include="..\openvpn\ssl\sslapi.hpp" />
|
||||
<ClInclude Include="..\openvpn\ssl\sslchoose.hpp" />
|
||||
<ClInclude Include="..\openvpn\ssl\sslconsts.hpp" />
|
||||
<ClInclude Include="..\openvpn\ssl\ssllog.hpp" />
|
||||
<ClInclude Include="..\openvpn\ssl\tlsprf.hpp" />
|
||||
<ClInclude Include="..\openvpn\ssl\tlsver.hpp" />
|
||||
<ClInclude Include="..\openvpn\ssl\tls_cert_profile.hpp" />
|
||||
@@ -332,9 +349,12 @@
|
||||
<ClInclude Include="..\openvpn\time\asiotimer.hpp" />
|
||||
<ClInclude Include="..\openvpn\time\coarsetime.hpp" />
|
||||
<ClInclude Include="..\openvpn\time\durhelper.hpp" />
|
||||
<ClInclude Include="..\openvpn\time\epoch.hpp" />
|
||||
<ClInclude Include="..\openvpn\time\time.hpp" />
|
||||
<ClInclude Include="..\openvpn\time\timestr.hpp" />
|
||||
<ClInclude Include="..\openvpn\transport\altproxy.hpp" />
|
||||
<ClInclude Include="..\openvpn\transport\client\extern\config.hpp" />
|
||||
<ClInclude Include="..\openvpn\transport\client\extern\fw.hpp" />
|
||||
<ClInclude Include="..\openvpn\transport\client\httpcli.hpp" />
|
||||
<ClInclude Include="..\openvpn\transport\client\relay.hpp" />
|
||||
<ClInclude Include="..\openvpn\transport\client\tcpcli.hpp" />
|
||||
@@ -342,6 +362,7 @@
|
||||
<ClInclude Include="..\openvpn\transport\client\udpcli.hpp" />
|
||||
<ClInclude Include="..\openvpn\transport\dco.hpp" />
|
||||
<ClInclude Include="..\openvpn\transport\gremlin.hpp" />
|
||||
<ClInclude Include="..\openvpn\transport\mssfix.hpp" />
|
||||
<ClInclude Include="..\openvpn\transport\mutate.hpp" />
|
||||
<ClInclude Include="..\openvpn\transport\pktstream.hpp" />
|
||||
<ClInclude Include="..\openvpn\transport\protocol.hpp" />
|
||||
@@ -349,6 +370,8 @@
|
||||
<ClInclude Include="..\openvpn\transport\server\transbase.hpp" />
|
||||
<ClInclude Include="..\openvpn\transport\socket_protect.hpp" />
|
||||
<ClInclude Include="..\openvpn\transport\tcplink.hpp" />
|
||||
<ClInclude Include="..\openvpn\transport\tcplinkbase.hpp" />
|
||||
<ClInclude Include="..\openvpn\transport\tcplinkcommon.hpp" />
|
||||
<ClInclude Include="..\openvpn\transport\udplink.hpp" />
|
||||
<ClInclude Include="..\openvpn\tun\builder\base.hpp" />
|
||||
<ClInclude Include="..\openvpn\tun\builder\capture.hpp" />
|
||||
@@ -365,13 +388,15 @@
|
||||
<ClInclude Include="..\openvpn\tun\ipv6_setting.hpp" />
|
||||
<ClInclude Include="..\openvpn\tun\layer.hpp" />
|
||||
<ClInclude Include="..\openvpn\tun\linux\client\tuncli.hpp" />
|
||||
<ClInclude Include="..\openvpn\tun\linux\tun.hpp" />
|
||||
<ClInclude Include="..\openvpn\tun\linux\client\tunsetup.hpp" />
|
||||
<ClInclude Include="..\openvpn\tun\mac\client\tuncli.hpp" />
|
||||
<ClInclude Include="..\openvpn\tun\mac\client\tunsetup.hpp" />
|
||||
<ClInclude Include="..\openvpn\tun\mac\dsdict.hpp" />
|
||||
<ClInclude Include="..\openvpn\tun\mac\gwv4.hpp" />
|
||||
<ClInclude Include="..\openvpn\tun\mac\macdns.hpp" />
|
||||
<ClInclude Include="..\openvpn\tun\mac\macdns_watchdog.hpp" />
|
||||
<ClInclude Include="..\openvpn\tun\mac\macgw.hpp" />
|
||||
<ClInclude Include="..\openvpn\tun\mac\macproxy.hpp" />
|
||||
<ClInclude Include="..\openvpn\tun\mac\tunutil.hpp" />
|
||||
<ClInclude Include="..\openvpn\tun\mac\utun.hpp" />
|
||||
<ClInclude Include="..\openvpn\tun\persist\tunpersist.hpp" />
|
||||
@@ -402,30 +427,20 @@
|
||||
<ClInclude Include="..\openvpn\win\unicode.hpp" />
|
||||
<ClInclude Include="..\openvpn\win\winerr.hpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\test\ovpncli\cli.cpp" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{1F891260-2039-494F-9777-EC5166AF31BC}</ProjectGuid>
|
||||
<RootNamespace>ovpn3core</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||
<WindowsTargetPlatformVersion>10.0.17134.0</WindowsTargetPlatformVersion>
|
||||
<ProjectName>cli</ProjectName>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
@@ -442,21 +457,6 @@
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup />
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>TurnOffAllWarnings</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>false</SDLCheck>
|
||||
<AdditionalIncludeDirectories>$(OVPN3_BUILD)\amd64\mbedtls\include;$(OVPN3_TAP_WINDOWS)\src;$(OVPN3_BUILD)\amd64\asio\asio\include;$(OVPN3_BUILD)\amd64\lz4\lib;$(OVPN3_CORE);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;NOMINMAX;_WIN32_WINNT=0x0600;USE_ASIO;ASIO_STANDALONE;USE_MBEDTLS;HAVE_LZ4;TAP_WIN_COMPONENT_ID=tap0901;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalOptions>%(AdditionalOptions)</AdditionalOptions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalLibraryDirectories>$(OVPN3_BUILD)\amd64\mbedtls\library;$(OVPN3_BUILD)\amd64\lz4\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>lz4.lib;mbedtls.lib;fwpuclnt.lib;ws2_32.lib;crypt32.lib;iphlpapi.lib;winmm.lib;advapi32.lib;wininet.lib;shell32.lib;ole32.lib;rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>TurnOffAllWarnings</WarningLevel>
|
||||
@@ -476,24 +476,6 @@
|
||||
<ShowProgress>NotSet</ShowProgress>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>TurnOffAllWarnings</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>false</SDLCheck>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;NOMINMAX;_WIN32_WINNT=0x0600;USE_ASIO;ASIO_STANDALONE;USE_MBEDTLS;HAVE_LZ4;TAP_WIN_COMPONENT_ID=tap0901;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(OVPN3_BUILD)\amd64\mbedtls\include;$(OVPN3_TAP_WINDOWS)\src;$(OVPN3_BUILD)\amd64\asio\asio\include;$(OVPN3_BUILD)\amd64\lz4\lib;$(OVPN3_CORE);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalLibraryDirectories>$(OVPN3_BUILD)\amd64\mbedtls\library;$(OVPN3_BUILD)\amd64\lz4\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>lz4.lib;mbedtls.lib;fwpuclnt.lib;ws2_32.lib;crypt32.lib;iphlpapi.lib;winmm.lib;advapi32.lib;wininet.lib;shell32.lib;ole32.lib;rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>TurnOffAllWarnings</WarningLevel>
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\test\ovpncli\cli.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\client\ovpncli.hpp" />
|
||||
<ClInclude Include="..\openvpn\addr\addrlist.hpp" />
|
||||
<ClInclude Include="..\openvpn\addr\addrpair.hpp" />
|
||||
<ClInclude Include="..\openvpn\addr\ip.hpp" />
|
||||
@@ -13,6 +9,8 @@
|
||||
<ClInclude Include="..\openvpn\addr\ipv6.hpp" />
|
||||
<ClInclude Include="..\openvpn\addr\macaddr.hpp" />
|
||||
<ClInclude Include="..\openvpn\addr\pool.hpp" />
|
||||
<ClInclude Include="..\openvpn\addr\quoteip.hpp" />
|
||||
<ClInclude Include="..\openvpn\addr\randaddr.hpp" />
|
||||
<ClInclude Include="..\openvpn\addr\range.hpp" />
|
||||
<ClInclude Include="..\openvpn\addr\regex.hpp" />
|
||||
<ClInclude Include="..\openvpn\addr\route.hpp" />
|
||||
@@ -44,6 +42,7 @@
|
||||
<ClInclude Include="..\openvpn\asio\asiocontext.hpp" />
|
||||
<ClInclude Include="..\openvpn\asio\asioerr.hpp" />
|
||||
<ClInclude Include="..\openvpn\asio\asiopolysock.hpp" />
|
||||
<ClInclude Include="..\openvpn\asio\asioresolverres.hpp" />
|
||||
<ClInclude Include="..\openvpn\asio\asiosignal.hpp" />
|
||||
<ClInclude Include="..\openvpn\asio\asiostop.hpp" />
|
||||
<ClInclude Include="..\openvpn\asio\asiowork.hpp" />
|
||||
@@ -63,6 +62,7 @@
|
||||
<ClInclude Include="..\openvpn\buffer\bufread.hpp" />
|
||||
<ClInclude Include="..\openvpn\buffer\bufstr.hpp" />
|
||||
<ClInclude Include="..\openvpn\buffer\bufstream.hpp" />
|
||||
<ClInclude Include="..\openvpn\buffer\lz4.hpp" />
|
||||
<ClInclude Include="..\openvpn\buffer\memq.hpp" />
|
||||
<ClInclude Include="..\openvpn\buffer\safestr.hpp" />
|
||||
<ClInclude Include="..\openvpn\buffer\zlib.hpp" />
|
||||
@@ -83,12 +83,14 @@
|
||||
<ClInclude Include="..\openvpn\common\abort.hpp" />
|
||||
<ClInclude Include="..\openvpn\common\action.hpp" />
|
||||
<ClInclude Include="..\openvpn\common\actionthread.hpp" />
|
||||
<ClInclude Include="..\openvpn\common\appversion.hpp" />
|
||||
<ClInclude Include="..\openvpn\common\arch.hpp" />
|
||||
<ClInclude Include="..\openvpn\common\argv.hpp" />
|
||||
<ClInclude Include="..\openvpn\common\arraysize.hpp" />
|
||||
<ClInclude Include="..\openvpn\common\asyncsleep.hpp" />
|
||||
<ClInclude Include="..\openvpn\common\autoreset.hpp" />
|
||||
<ClInclude Include="..\openvpn\common\base64.hpp" />
|
||||
<ClInclude Include="..\openvpn\common\bigmutex.hpp" />
|
||||
<ClInclude Include="..\openvpn\common\binprefix.hpp" />
|
||||
<ClInclude Include="..\openvpn\common\circ_list.hpp" />
|
||||
<ClInclude Include="..\openvpn\common\cleanup.hpp" />
|
||||
@@ -116,17 +118,19 @@
|
||||
<ClInclude Include="..\openvpn\common\hostlist.hpp" />
|
||||
<ClInclude Include="..\openvpn\common\hostname.hpp" />
|
||||
<ClInclude Include="..\openvpn\common\hostport.hpp" />
|
||||
<ClInclude Include="..\openvpn\common\inotify.hpp" />
|
||||
<ClInclude Include="..\openvpn\common\jsonlib.hpp" />
|
||||
<ClInclude Include="..\openvpn\common\lex.hpp" />
|
||||
<ClInclude Include="..\openvpn\common\likely.hpp" />
|
||||
<ClInclude Include="..\openvpn\common\link.hpp" />
|
||||
<ClInclude Include="..\openvpn\common\logrotate.hpp" />
|
||||
<ClInclude Include="..\openvpn\common\memneq.hpp" />
|
||||
<ClInclude Include="..\openvpn\common\mode.hpp" />
|
||||
<ClInclude Include="..\openvpn\common\modstat.hpp" />
|
||||
<ClInclude Include="..\openvpn\common\msgwin.hpp" />
|
||||
<ClInclude Include="..\openvpn\common\number.hpp" />
|
||||
<ClInclude Include="..\openvpn\common\olong.hpp" />
|
||||
<ClInclude Include="..\openvpn\common\options.hpp" />
|
||||
<ClInclude Include="..\openvpn\common\option_error.hpp" />
|
||||
<ClInclude Include="..\openvpn\common\ostream.hpp" />
|
||||
<ClInclude Include="..\openvpn\common\path.hpp" />
|
||||
<ClInclude Include="..\openvpn\common\peercred.hpp" />
|
||||
@@ -164,6 +168,7 @@
|
||||
<ClInclude Include="..\openvpn\common\usecount.hpp" />
|
||||
<ClInclude Include="..\openvpn\common\usergroup.hpp" />
|
||||
<ClInclude Include="..\openvpn\common\userpass.hpp" />
|
||||
<ClInclude Include="..\openvpn\common\valgrind.hpp" />
|
||||
<ClInclude Include="..\openvpn\common\version.hpp" />
|
||||
<ClInclude Include="..\openvpn\common\waitbarrier.hpp" />
|
||||
<ClInclude Include="..\openvpn\common\write.hpp" />
|
||||
@@ -192,6 +197,9 @@
|
||||
<ClInclude Include="..\openvpn\crypto\packet_id.hpp" />
|
||||
<ClInclude Include="..\openvpn\crypto\selftest.hpp" />
|
||||
<ClInclude Include="..\openvpn\crypto\static_key.hpp" />
|
||||
<ClInclude Include="..\openvpn\crypto\tls_crypt.hpp" />
|
||||
<ClInclude Include="..\openvpn\dco\dcocli.hpp" />
|
||||
<ClInclude Include="..\openvpn\dco\ipcollbase.hpp" />
|
||||
<ClInclude Include="..\openvpn\error\error.hpp" />
|
||||
<ClInclude Include="..\openvpn\error\excode.hpp" />
|
||||
<ClInclude Include="..\openvpn\frame\frame.hpp" />
|
||||
@@ -208,6 +216,7 @@
|
||||
<ClInclude Include="..\openvpn\http\urlencode.hpp" />
|
||||
<ClInclude Include="..\openvpn\http\urlparm.hpp" />
|
||||
<ClInclude Include="..\openvpn\http\urlparse.hpp" />
|
||||
<ClInclude Include="..\openvpn\http\validate_uri.hpp" />
|
||||
<ClInclude Include="..\openvpn\http\webexcept.hpp" />
|
||||
<ClInclude Include="..\openvpn\init\cryptoinit.hpp" />
|
||||
<ClInclude Include="..\openvpn\init\engineinit.hpp" />
|
||||
@@ -215,14 +224,26 @@
|
||||
<ClInclude Include="..\openvpn\io\io.hpp" />
|
||||
<ClInclude Include="..\openvpn\ip\dhcp.hpp" />
|
||||
<ClInclude Include="..\openvpn\ip\eth.hpp" />
|
||||
<ClInclude Include="..\openvpn\ip\icmp.hpp" />
|
||||
<ClInclude Include="..\openvpn\ip\ip.hpp" />
|
||||
<ClInclude Include="..\openvpn\ip\icmp4.hpp" />
|
||||
<ClInclude Include="..\openvpn\ip\icmp6.hpp" />
|
||||
<ClInclude Include="..\openvpn\ip\ip4.hpp" />
|
||||
<ClInclude Include="..\openvpn\ip\ip6.hpp" />
|
||||
<ClInclude Include="..\openvpn\ip\ipcommon.hpp" />
|
||||
<ClInclude Include="..\openvpn\ip\udp.hpp" />
|
||||
<ClInclude Include="..\openvpn\kovpn\kocrypto.hpp" />
|
||||
<ClInclude Include="..\openvpn\kovpn\kodev.hpp" />
|
||||
<ClInclude Include="..\openvpn\kovpn\korekey.hpp" />
|
||||
<ClInclude Include="..\openvpn\kovpn\koroute.hpp" />
|
||||
<ClInclude Include="..\openvpn\kovpn\kostats.hpp" />
|
||||
<ClInclude Include="..\openvpn\kovpn\kovpn.hpp" />
|
||||
<ClInclude Include="..\openvpn\legal\copyright.hpp" />
|
||||
<ClInclude Include="..\openvpn\linux\core.hpp" />
|
||||
<ClInclude Include="..\openvpn\linux\daemon_alive.hpp" />
|
||||
<ClInclude Include="..\openvpn\linux\procfs.hpp" />
|
||||
<ClInclude Include="..\openvpn\log\logbase.hpp" />
|
||||
<ClInclude Include="..\openvpn\log\logbasesimple.hpp" />
|
||||
<ClInclude Include="..\openvpn\log\logbasesimplemac.hpp" />
|
||||
<ClInclude Include="..\openvpn\log\logdatetime.hpp" />
|
||||
<ClInclude Include="..\openvpn\log\lognull.hpp" />
|
||||
<ClInclude Include="..\openvpn\log\logperiod.hpp" />
|
||||
<ClInclude Include="..\openvpn\log\logsimple.hpp" />
|
||||
@@ -280,6 +301,7 @@
|
||||
<ClInclude Include="..\openvpn\proxy\proxyauth.hpp" />
|
||||
<ClInclude Include="..\openvpn\random\devurand.hpp" />
|
||||
<ClInclude Include="..\openvpn\random\mtrandapi.hpp" />
|
||||
<ClInclude Include="..\openvpn\random\rand2.hpp" />
|
||||
<ClInclude Include="..\openvpn\random\randapi.hpp" />
|
||||
<ClInclude Include="..\openvpn\random\randbytestore.hpp" />
|
||||
<ClInclude Include="..\openvpn\reliable\relack.hpp" />
|
||||
@@ -307,6 +329,7 @@
|
||||
<ClInclude Include="..\openvpn\ssl\sslapi.hpp" />
|
||||
<ClInclude Include="..\openvpn\ssl\sslchoose.hpp" />
|
||||
<ClInclude Include="..\openvpn\ssl\sslconsts.hpp" />
|
||||
<ClInclude Include="..\openvpn\ssl\ssllog.hpp" />
|
||||
<ClInclude Include="..\openvpn\ssl\tlsprf.hpp" />
|
||||
<ClInclude Include="..\openvpn\ssl\tlsver.hpp" />
|
||||
<ClInclude Include="..\openvpn\ssl\tls_cert_profile.hpp" />
|
||||
@@ -314,9 +337,12 @@
|
||||
<ClInclude Include="..\openvpn\time\asiotimer.hpp" />
|
||||
<ClInclude Include="..\openvpn\time\coarsetime.hpp" />
|
||||
<ClInclude Include="..\openvpn\time\durhelper.hpp" />
|
||||
<ClInclude Include="..\openvpn\time\epoch.hpp" />
|
||||
<ClInclude Include="..\openvpn\time\time.hpp" />
|
||||
<ClInclude Include="..\openvpn\time\timestr.hpp" />
|
||||
<ClInclude Include="..\openvpn\transport\altproxy.hpp" />
|
||||
<ClInclude Include="..\openvpn\transport\client\extern\config.hpp" />
|
||||
<ClInclude Include="..\openvpn\transport\client\extern\fw.hpp" />
|
||||
<ClInclude Include="..\openvpn\transport\client\httpcli.hpp" />
|
||||
<ClInclude Include="..\openvpn\transport\client\relay.hpp" />
|
||||
<ClInclude Include="..\openvpn\transport\client\tcpcli.hpp" />
|
||||
@@ -331,6 +357,8 @@
|
||||
<ClInclude Include="..\openvpn\transport\server\transbase.hpp" />
|
||||
<ClInclude Include="..\openvpn\transport\socket_protect.hpp" />
|
||||
<ClInclude Include="..\openvpn\transport\tcplink.hpp" />
|
||||
<ClInclude Include="..\openvpn\transport\tcplinkbase.hpp" />
|
||||
<ClInclude Include="..\openvpn\transport\tcplinkcommon.hpp" />
|
||||
<ClInclude Include="..\openvpn\transport\udplink.hpp" />
|
||||
<ClInclude Include="..\openvpn\tun\builder\base.hpp" />
|
||||
<ClInclude Include="..\openvpn\tun\builder\capture.hpp" />
|
||||
@@ -347,18 +375,21 @@
|
||||
<ClInclude Include="..\openvpn\tun\ipv6_setting.hpp" />
|
||||
<ClInclude Include="..\openvpn\tun\layer.hpp" />
|
||||
<ClInclude Include="..\openvpn\tun\linux\client\tuncli.hpp" />
|
||||
<ClInclude Include="..\openvpn\tun\linux\tun.hpp" />
|
||||
<ClInclude Include="..\openvpn\tun\linux\client\tunsetup.hpp" />
|
||||
<ClInclude Include="..\openvpn\tun\mac\client\tuncli.hpp" />
|
||||
<ClInclude Include="..\openvpn\tun\mac\client\tunsetup.hpp" />
|
||||
<ClInclude Include="..\openvpn\tun\mac\dsdict.hpp" />
|
||||
<ClInclude Include="..\openvpn\tun\mac\gwv4.hpp" />
|
||||
<ClInclude Include="..\openvpn\tun\mac\macdns.hpp" />
|
||||
<ClInclude Include="..\openvpn\tun\mac\macdns_watchdog.hpp" />
|
||||
<ClInclude Include="..\openvpn\tun\mac\macgw.hpp" />
|
||||
<ClInclude Include="..\openvpn\tun\mac\macproxy.hpp" />
|
||||
<ClInclude Include="..\openvpn\tun\mac\tunutil.hpp" />
|
||||
<ClInclude Include="..\openvpn\tun\mac\utun.hpp" />
|
||||
<ClInclude Include="..\openvpn\tun\persist\tunpersist.hpp" />
|
||||
<ClInclude Include="..\openvpn\tun\persist\tunwrap.hpp" />
|
||||
<ClInclude Include="..\openvpn\tun\persist\tunwrapasio.hpp" />
|
||||
<ClInclude Include="..\openvpn\tun\proxy.hpp" />
|
||||
<ClInclude Include="..\openvpn\tun\server\tunbase.hpp" />
|
||||
<ClInclude Include="..\openvpn\tun\tunio.hpp" />
|
||||
<ClInclude Include="..\openvpn\tun\tunlog.hpp" />
|
||||
@@ -370,10 +401,12 @@
|
||||
<ClInclude Include="..\openvpn\tun\win\nrpt.hpp" />
|
||||
<ClInclude Include="..\openvpn\tun\win\tunutil.hpp" />
|
||||
<ClInclude Include="..\openvpn\tun\win\wfp.hpp" />
|
||||
<ClInclude Include="..\openvpn\tun\win\winproxy.hpp" />
|
||||
<ClInclude Include="..\openvpn\win\call.hpp" />
|
||||
<ClInclude Include="..\openvpn\win\cmd.hpp" />
|
||||
<ClInclude Include="..\openvpn\win\console.hpp" />
|
||||
<ClInclude Include="..\openvpn\win\handle.hpp" />
|
||||
<ClInclude Include="..\openvpn\win\impersonate.hpp" />
|
||||
<ClInclude Include="..\openvpn\win\modname.hpp" />
|
||||
<ClInclude Include="..\openvpn\win\reg.hpp" />
|
||||
<ClInclude Include="..\openvpn\win\scoped_handle.hpp" />
|
||||
@@ -383,5 +416,16 @@
|
||||
<ClInclude Include="..\openvpn\tun\win\winproxy.hpp" />
|
||||
<ClInclude Include="..\openvpn\tun\proxy.hpp" />
|
||||
<ClInclude Include="..\openvpn\win\impersonate.hpp" />
|
||||
<ClInclude Include="..\openvpn\ip\icmp4.hpp" />
|
||||
<ClInclude Include="..\openvpn\ip\icmp6.hpp" />
|
||||
<ClInclude Include="..\openvpn\ip\ip4.hpp" />
|
||||
<ClInclude Include="..\openvpn\ip\ip6.hpp" />
|
||||
<ClInclude Include="..\openvpn\ip\ipcommon.hpp" />
|
||||
<ClInclude Include="..\client\ovpncli.hpp" />
|
||||
<ClInclude Include="..\openvpn\transport\mssfix.hpp" />
|
||||
<ClInclude Include="..\openvpn\ip\tcp.hpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\test\ovpncli\cli.cpp" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
Reference in New Issue
Block a user