Squashed 'Sources/OpenVPNAdapter/Libraries/Vendors/openvpn/' changes from 7db7a009b0..29e060ffb3

29e060ffb3 CryptoAlgs: Don't report any digests for ciphers not using them
87d40ed8da ovpncli.cpp: socket_protect implementation for agent-enabled builds
12763bbbb8 win/client/tunsetup.hpp: implement add_bypass_route() method
c445361969 vcxprox: add missing file
0d7143c4bf transport: enable socket_protect call for all platforms
a6cae41285 cliopt.hpp: disable remote list bypass for agent-enabled build
3166957e2e add error codes for better error management at profile parsing time

git-subtree-dir: Sources/OpenVPNAdapter/Libraries/Vendors/openvpn
git-subtree-split: 29e060ffb34b8a4067d8d01f6506bdb2d220df02
This commit is contained in:
Sergey Abramchuk 2019-10-25 20:14:12 +03:00
parent 8e87aecebf
commit 688ce11081
12 changed files with 90 additions and 34 deletions

View File

@ -262,7 +262,13 @@ namespace openvpn {
bool socket_protect(int socket, IP::Addr endpoint) override bool socket_protect(int socket, IP::Addr endpoint) override
{ {
if (parent) if (parent)
return parent->socket_protect(socket, endpoint.to_string(), endpoint.is_ipv6()); {
#if defined(OPENVPN_COMMAND_AGENT) && defined(OPENVPN_PLATFORM_WIN)
return WinCommandAgent::add_bypass_route(endpoint);
#else
return parent->socket_protect(socket, endpoint.to_string(), endpoint.is_ipv6());
#endif
}
else else
return true; return true;
} }
@ -659,7 +665,7 @@ namespace openvpn {
catch (const std::exception& e) catch (const std::exception& e)
{ {
eval.error = true; eval.error = true;
eval.message = Unicode::utf8_printable<std::string>(e.what(), 256); eval.message = Unicode::utf8_printable<std::string>(std::string("ERR_PROFILE_GENERIC: ") + e.what(), 256);
} }
} }
@ -807,6 +813,11 @@ namespace openvpn {
return ret; return ret;
} }
OPENVPN_CLIENT_EXPORT bool OpenVPNClient::socket_protect(int socket, std::string remote, bool ipv6)
{
return true;
}
OPENVPN_CLIENT_EXPORT bool OpenVPNClient::parse_dynamic_challenge(const std::string& cookie, DynamicChallenge& dc) OPENVPN_CLIENT_EXPORT bool OpenVPNClient::parse_dynamic_challenge(const std::string& cookie, DynamicChallenge& dc)
{ {
try { try {
@ -977,8 +988,8 @@ namespace openvpn {
#ifdef OPENVPN_GREMLIN #ifdef OPENVPN_GREMLIN
cc.gremlin_config = state->gremlin_config; cc.gremlin_config = state->gremlin_config;
#endif #endif
#if defined(USE_TUN_BUILDER)
cc.socket_protect = &state->socket_protect; cc.socket_protect = &state->socket_protect;
#if defined(USE_TUN_BUILDER)
cc.builder = this; cc.builder = this;
#endif #endif
#if defined(OPENVPN_EXTERNAL_TUN_FACTORY) #if defined(OPENVPN_EXTERNAL_TUN_FACTORY)

View File

@ -492,7 +492,7 @@ namespace openvpn {
// Callback to "protect" a socket from being routed through the tunnel. // Callback to "protect" a socket from being routed through the tunnel.
// Will be called from the thread executing connect(). // Will be called from the thread executing connect().
// The remote and ipv6 are the remote host this socket will connect to // 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; virtual bool socket_protect(int socket, std::string remote, bool ipv6);
// Primary VPN client connect method, doesn't return until disconnect. // Primary VPN client connect method, doesn't return until disconnect.
// Should be called by a worker thread. This method will make callbacks // Should be called by a worker thread. This method will make callbacks

View File

@ -436,12 +436,14 @@ namespace openvpn {
tunconf->stop = config.stop; tunconf->stop = config.stop;
tunconf->wintun = config.wintun; tunconf->wintun = config.wintun;
if (config.tun_persist) if (config.tun_persist)
{ {
tunconf->tun_persist.reset(new TunWin::TunPersist(true, false, nullptr)); tunconf->tun_persist.reset(new TunWin::TunPersist(true, false, nullptr));
tunconf->tun_prop.remote_bypass = true; #ifndef OPENVPN_COMMAND_AGENT
/* remote_list is required by remote_bypass to work */ /* remote_list is required by remote_bypass to work */
tunconf->tun_prop.remote_list = remote_list; tunconf->tun_prop.remote_bypass = true;
} tunconf->tun_prop.remote_list = remote_list;
#endif
}
#ifdef OPENVPN_COMMAND_AGENT #ifdef OPENVPN_COMMAND_AGENT
tunconf->tun_setup_factory = WinCommandAgent::new_agent(opt); tunconf->tun_setup_factory = WinCommandAgent::new_agent(opt);
#endif #endif

View File

@ -97,7 +97,7 @@ namespace openvpn {
if (arg1 == "GENERIC_CONFIG") if (arg1 == "GENERIC_CONFIG")
{ {
error_ = true; error_ = true;
message_ = "SERVER_LOCKED_UNSUPPORTED: server locked profiles are currently unsupported"; message_ = "ERR_PROFILE_SERVER_LOCKED_UNSUPPORTED: server locked profiles are currently unsupported";
return; return;
} }
else if (arg1 == "ALLOW_PASSWORD_SAVE") else if (arg1 == "ALLOW_PASSWORD_SAVE")
@ -307,7 +307,7 @@ namespace openvpn {
catch (const std::exception& e) catch (const std::exception& e)
{ {
error_ = true; error_ = true;
message_ = Unicode::utf8_printable<std::string>(e.what(), 256); message_ = Unicode::utf8_printable<std::string>(std::string("ERR_PROFILE_GENERIC: ") + e.what(), 256);
} }
} }
@ -374,7 +374,7 @@ namespace openvpn {
{ {
ParseClientConfig ret; ParseClientConfig ret;
ret.error_ = true; ret.error_ = true;
ret.message_ = Unicode::utf8_printable<std::string>(e.what(), 256); ret.message_ = Unicode::utf8_printable<std::string>(std::string("ERR_PROFILE_GENERIC: ") + e.what(), 256);
return ret; return ret;
} }
} }

View File

@ -80,6 +80,7 @@ namespace openvpn {
F_CIPHER=(1<<2), // alg is a cipher F_CIPHER=(1<<2), // alg is a cipher
F_DIGEST=(1<<3), // alg is a digest F_DIGEST=(1<<3), // alg is a digest
F_ALLOW_DC=(1<<4), // alg may be used in OpenVPN data channel F_ALLOW_DC=(1<<4), // alg may be used in OpenVPN data channel
F_NO_CIPHER_DIGEST=(1<<5), // cipher alg does not depend on any additional digest
}; };
// size in bytes of AEAD "nonce tail" normally taken from // size in bytes of AEAD "nonce tail" normally taken from
@ -130,9 +131,9 @@ namespace openvpn {
{ "DES-EDE3-CBC", F_CIPHER|F_ALLOW_DC|CBC_HMAC, 24, 8, 8 }, { "DES-EDE3-CBC", F_CIPHER|F_ALLOW_DC|CBC_HMAC, 24, 8, 8 },
{ "BF-CBC", F_CIPHER|F_ALLOW_DC|CBC_HMAC, 16, 8, 8 }, { "BF-CBC", F_CIPHER|F_ALLOW_DC|CBC_HMAC, 16, 8, 8 },
{ "AES-256-CTR", F_CIPHER, 32, 16, 16 }, { "AES-256-CTR", F_CIPHER, 32, 16, 16 },
{ "AES-128-GCM", F_CIPHER|F_ALLOW_DC|AEAD, 16, 12, 16 }, { "AES-128-GCM", F_CIPHER|F_ALLOW_DC|AEAD|F_NO_CIPHER_DIGEST, 16, 12, 16 },
{ "AES-192-GCM", F_CIPHER|F_ALLOW_DC|AEAD, 24, 12, 16 }, { "AES-192-GCM", F_CIPHER|F_ALLOW_DC|AEAD|F_NO_CIPHER_DIGEST, 24, 12, 16 },
{ "AES-256-GCM", F_CIPHER|F_ALLOW_DC|AEAD, 32, 12, 16 }, { "AES-256-GCM", F_CIPHER|F_ALLOW_DC|AEAD|F_NO_CIPHER_DIGEST, 32, 12, 16 },
{ "MD4", F_DIGEST, 16, 0, 0 }, { "MD4", F_DIGEST, 16, 0, 0 },
{ "MD5", F_DIGEST|F_ALLOW_DC, 16, 0, 0 }, { "MD5", F_DIGEST|F_ALLOW_DC, 16, 0, 0 },
{ "SHA1", F_DIGEST|F_ALLOW_DC, 20, 0, 0 }, { "SHA1", F_DIGEST|F_ALLOW_DC, 20, 0, 0 },
@ -240,6 +241,20 @@ namespace openvpn {
return type; return type;
} }
/**
* Check if a specific algorithm depends on an additional digest or not
*
* @param type CryptoAlgs::Type to check
*
* @return Returns true if the queried algorithm depends on a digest,
* otherwise false. The check is done strictly against the
* CryptoAlgs::AlgFlags F_NO_CIPHER_DIGEST flag.
*/
inline bool use_cipher_digest(const Type type)
{
const Alg& alg = get(type);
return !(alg.flags() & F_NO_CIPHER_DIGEST);
}
} }
} }

View File

@ -184,7 +184,19 @@ namespace openvpn {
} }
CryptoAlgs::Type cipher() const { return cipher_; } CryptoAlgs::Type cipher() const { return cipher_; }
CryptoAlgs::Type digest() const { return digest_; }
/**
* Retrieve the digest configured for the data channel.
* If the configured data channel cipher does not use any
* additional digest, CryptoAlgs::NONE is returned.
*
* @return Returns the cipher digest in use
*/
CryptoAlgs::Type digest() const
{
return (CryptoAlgs::use_cipher_digest(cipher_) ? digest_ : CryptoAlgs::NONE);
}
CryptoDCFactory::Ptr factory() const { return factory_; } CryptoDCFactory::Ptr factory() const { return factory_; }

View File

@ -140,14 +140,14 @@ namespace openvpn {
else else
{ {
status_ = MERGE_OVPN_EXT_FAIL; status_ = MERGE_OVPN_EXT_FAIL;
error_ = basename_; error_ = std::string("ERR_PROFILE_NO_OVPN_EXTENSION: ") + basename_;
return; return;
} }
} }
catch (const std::exception& e) catch (const std::exception& e)
{ {
status_ = MERGE_OVPN_FILE_FAIL; status_ = MERGE_OVPN_FILE_FAIL;
error_ = e.what(); error_ = std::string("ERR_PROFILE_GENERIC: ") + e.what();
return; return;
} }
@ -157,7 +157,7 @@ namespace openvpn {
catch (const std::exception& e) catch (const std::exception& e)
{ {
status_ = MERGE_EXCEPTION; status_ = MERGE_EXCEPTION;
error_ = e.what(); error_ = std::string("ERR_PROFILE_GENERIC: ") + e.what();
} }
} }
@ -189,7 +189,7 @@ namespace openvpn {
if (total_size > max_size) if (total_size > max_size)
{ {
status_ = MERGE_EXCEPTION; status_ = MERGE_EXCEPTION;
error_ = "file too large"; error_ = "ERR_PROFILE_FILE_TOO_LARGE: file too large";
return; return;
} }
@ -207,7 +207,7 @@ namespace openvpn {
if (in.line_overflow()) if (in.line_overflow())
{ {
status_ = MERGE_EXCEPTION; status_ = MERGE_EXCEPTION;
error_ = "line too long"; error_ = "ERR_PROFILE_LINE_TOO_LONG: line too long";
return; return;
} }
const std::string& line = in.line_ref(); const std::string& line = in.line_ref();
@ -276,12 +276,13 @@ namespace openvpn {
{ {
echo = false; echo = false;
status_ = MERGE_REF_FAIL; status_ = MERGE_REF_FAIL;
error_ = "ERR_PROFILE_NO_FILENAME: filename not provided";
} }
else if (follow_references != FOLLOW_FULL && !path::is_flat(fn)) else if (follow_references != FOLLOW_FULL && !path::is_flat(fn))
{ {
echo = false; echo = false;
status_ = MERGE_REF_FAIL; status_ = MERGE_REF_FAIL;
error_ = fn; error_ = std::string("ERR_PROFILE_CANT_FOLLOW_LINK: ") + fn;
if (ref_fail_list_.size() < MAX_FN_LIST_SIZE) if (ref_fail_list_.size() < MAX_FN_LIST_SIZE)
ref_fail_list_.push_back(fn); ref_fail_list_.push_back(fn);
} }
@ -294,7 +295,7 @@ namespace openvpn {
if (follow_references == FOLLOW_NONE) if (follow_references == FOLLOW_NONE)
{ {
status_ = MERGE_EXCEPTION; status_ = MERGE_EXCEPTION;
error_ = fn + ": cannot follow file reference"; error_ = std::string("ERR_PROFILE_CANT_FOLLOW_LINK: ") + fn + ": cannot follow file reference";
return; return;
} }
path = path::join(profile_dir, fn); path = path::join(profile_dir, fn);
@ -303,7 +304,7 @@ namespace openvpn {
if (total_size > max_size) if (total_size > max_size)
{ {
status_ = MERGE_EXCEPTION; status_ = MERGE_EXCEPTION;
error_ = fn + ": file too large"; error_ = std::string("ERR_PROFILE_FILE_TOO_LARGE: ") + fn + ": file too large";
return; return;
} }
OptionList::detect_multiline_breakout(file_content, opt.ref(0)); OptionList::detect_multiline_breakout(file_content, opt.ref(0));
@ -312,7 +313,7 @@ namespace openvpn {
{ {
error = true; error = true;
status_ = MERGE_REF_FAIL; status_ = MERGE_REF_FAIL;
error_ = fn + " : " + e.what(); error_ = std::string("ERR_PROFILE_GENERIC: ") + fn + " : " + e.what();
if (ref_fail_list_.size() < MAX_FN_LIST_SIZE) if (ref_fail_list_.size() < MAX_FN_LIST_SIZE)
ref_fail_list_.push_back(fn); ref_fail_list_.push_back(fn);
} }
@ -363,7 +364,7 @@ namespace openvpn {
if (ref_fail_list_.size() >= 2) if (ref_fail_list_.size() >= 2)
{ {
status_ = MERGE_MULTIPLE_REF_FAIL; status_ = MERGE_MULTIPLE_REF_FAIL;
error_ = ""; error_ = "ERR_PROFILE_GENERIC: ";
for (size_t i = 0; i < ref_fail_list_.size(); ++i) for (size_t i = 0; i < ref_fail_list_.size(); ++i)
{ {
if (i) if (i)
@ -459,7 +460,7 @@ namespace openvpn {
catch (const std::exception& e) catch (const std::exception& e)
{ {
status_ = MERGE_EXCEPTION; status_ = MERGE_EXCEPTION;
error_ = e.what(); error_ = std::string("ERR_PROFILE_GENERIC: ") + e.what();
} }
} }

View File

@ -909,7 +909,7 @@ namespace openvpn {
OPENVPN_LOG("Contacting " << server_endpoint << " via HTTP Proxy"); OPENVPN_LOG("Contacting " << server_endpoint << " via HTTP Proxy");
parent->transport_wait_proxy(); parent->transport_wait_proxy();
socket.open(server_endpoint.protocol()); socket.open(server_endpoint.protocol());
#ifdef OPENVPN_PLATFORM_TYPE_UNIX
if (config->socket_protect) if (config->socket_protect)
{ {
if (!config->socket_protect->socket_protect(socket.native_handle(), server_endpoint_addr())) if (!config->socket_protect->socket_protect(socket.native_handle(), server_endpoint_addr()))
@ -920,7 +920,7 @@ namespace openvpn {
return; return;
} }
} }
#endif
socket.set_option(openvpn_io::ip::tcp::no_delay(true)); socket.set_option(openvpn_io::ip::tcp::no_delay(true));
socket.async_connect(server_endpoint, [self=Ptr(this)](const openvpn_io::error_code& error) socket.async_connect(server_endpoint, [self=Ptr(this)](const openvpn_io::error_code& error)
{ {

View File

@ -282,7 +282,7 @@ namespace openvpn {
<< server_protocol.str()); << server_protocol.str());
parent->transport_wait(); parent->transport_wait();
socket.open(server_endpoint.protocol()); socket.open(server_endpoint.protocol());
#if defined(OPENVPN_PLATFORM_TYPE_UNIX) || defined(OPENVPN_PLATFORM_UWP)
if (config->socket_protect) if (config->socket_protect)
{ {
if (!config->socket_protect->socket_protect(socket.native_handle(), server_endpoint_addr())) if (!config->socket_protect->socket_protect(socket.native_handle(), server_endpoint_addr()))
@ -293,7 +293,7 @@ namespace openvpn {
return; return;
} }
} }
#endif
socket.set_option(openvpn_io::ip::tcp::no_delay(true)); socket.set_option(openvpn_io::ip::tcp::no_delay(true));
socket.async_connect(server_endpoint, [self=Ptr(this)](const openvpn_io::error_code& error) socket.async_connect(server_endpoint, [self=Ptr(this)](const openvpn_io::error_code& error)
{ {

View File

@ -266,7 +266,7 @@ namespace openvpn {
OPENVPN_LOG("Contacting " << server_endpoint << " via UDP"); OPENVPN_LOG("Contacting " << server_endpoint << " via UDP");
parent->transport_wait(); parent->transport_wait();
socket.open(server_endpoint.protocol()); socket.open(server_endpoint.protocol());
#if defined(OPENVPN_PLATFORM_TYPE_UNIX) || defined(OPENVPN_PLATFORM_UWP)
if (config->socket_protect) if (config->socket_protect)
{ {
if (!config->socket_protect->socket_protect(socket.native_handle(), server_endpoint_addr())) if (!config->socket_protect->socket_protect(socket.native_handle(), server_endpoint_addr()))
@ -277,7 +277,7 @@ namespace openvpn {
return; return;
} }
} }
#endif
socket.async_connect(server_endpoint, [self=Ptr(this)](const openvpn_io::error_code& error) socket.async_connect(server_endpoint, [self=Ptr(this)](const openvpn_io::error_code& error)
{ {
OPENVPN_ASYNC_HANDLER; OPENVPN_ASYNC_HANDLER;

View File

@ -204,6 +204,20 @@ namespace openvpn {
destroy(os); destroy(os);
} }
static void add_bypass_route(const std::string& route,
bool ipv6,
ActionList& add_cmds,
ActionList& remove_cmds_bypass_gw)
{
const Util::DefaultGateway gw;
if (!ipv6)
{
add_cmds.add(new WinCmd("netsh interface ip add route " + route + "/32 " + to_string(gw.interface_index()) + ' ' + gw.gateway_address() + " store=active"));
remove_cmds_bypass_gw.add(new WinCmd("netsh interface ip delete route " + route + "/32 " + to_string(gw.interface_index()) + ' ' + gw.gateway_address() + " store=active"));
}
}
private: private:
struct L2State struct L2State
{ {

View File

@ -431,6 +431,7 @@
<ClInclude Include="..\openvpn\tun\win\client\clientconfig.hpp" /> <ClInclude Include="..\openvpn\tun\win\client\clientconfig.hpp" />
<ClInclude Include="..\openvpn\tun\win\ringbuffer.hpp" /> <ClInclude Include="..\openvpn\tun\win\ringbuffer.hpp" />
<ClInclude Include="..\openvpn\common\event.hpp" /> <ClInclude Include="..\openvpn\common\event.hpp" />
<ClInclude Include="..\openvpn\win\event.hpp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="..\test\ovpncli\cli.cpp" /> <ClCompile Include="..\test\ovpncli\cli.cpp" />