* Where unicode/ansi versions of a method exist, always
explicitly call one of unicode or ansi methods by
appending a 'W' or 'A' to the end of the method name.
Never omit the 'W' or 'A' because that will cause the
default method to be used which may vary according to
build flags.
* Prepend all Windows API method references with "::" to
indicate that the method names should be resolved from
the top-level namespace.
1. NamedPipeImpersonate : RAII class for scoping
ImpersonateNamedPipeClient/RevertToSelf.
2. send_handle() : duplicate a handle prior to sending
to a remote process.
Added #ifdefs to support both XP/Win2003 and Vista+.
* Where unicode/ansi versions of a method exist, always
explicitly call one of unicode or ansi methods by
appending a 'W' or 'A' to the end of the method name.
Never omit the 'W' or 'A' because that will cause the
default method to be used which may vary according to
build flags.
* Prepend all Windows API method references with "::" to
indicate that the method names should be resolved from
the top-level namespace.
Previously, all listener sockets were configured with both
reuseaddr and reuseport. reuseaddr is reasonable to use as
a default, but reuseport should only be used when different
threads are listening on the same local port/address for
load-balancing purposes.
This patch adds two new socket option flags DISABLE_REUSE_ADDR
and REUSE_PORT, to provide finer-grained control over
these options.
Signed-off-by: James Yonan <james@openvpn.net>
As noted in the Asio documentation, an AsioTimer handler can be
called with a non-error status after timer cancellation.
Unfortunately, this can lead to race conditions, so I'm moving over
all AsioTimer users to AsioTimerSafe when I don't see the handler
clearly checking for late cancellation.
Signed-off-by: James Yonan <james@openvpn.net>
To support asynchronous command response, the virtual
method omi_command_in() should now return a boolean.
When omi_command_in() returns false, synchronous mode
is chosen (the previous default). This means that
omi_command_in() must emit "SUCCESS: ..." or
"ERROR: ..." before it returns.
When omi_command_in() returns true, the new asynchronous
mode is chosen, and omi_command_in() may return before
emitting SUCCESS or ERROR. In this mode, OMICore will
pause the incoming command pipeline and not make any
further calls to omi_command_in() until
OMICore::async_done() is called.
Signed-off-by: James Yonan <james@openvpn.net>
A common AsioTimer usage pattern is:
expires_at(Time::now() + duration)
This is more succinctly and efficiently stated as:
expires_after(duration).
Signed-off-by: James Yonan <james@openvpn.net>
Created a lightweight abstraction layer so that another i/o
reactor can be dropped in place of asio.
This commit includes:
* Added ASIO=1 to many "go" scripts that require asio
* Renamed "asio::" to "openvpn_io::".
Signed-off-by: James Yonan <james@openvpn.net>
Could benefit from some minor modifications to
python client backend and tray app:
* Client backend and ovpn3 both implement connection timeout.
Client backend should defer to the ovpn3 implementation.
* Client backend and ovpn3 both implement DNS server config
and SystemConfiguration event sent to
'Setup:/Network/Global/IPv4' for 'VPN up'.
Client backend should defer to the ovpn3 implementation.
* Ensure that system state changes (sleep, wakeup, network
roam, fast user switching, etc.) don't cause conflicts
between client backend and ovpn3 core both trying to
implement similar functionality.
* Tray app should render error detail in >FATAL: messages.
Right now tray raises a Disconnected notification but
loses any error detail.
std::strerror() doesn't claim to be thread-safe, so
add openvpn::strerror_str() which is thread-safe by
virtue of the fact that it backs to strerror_r().
Signed-off-by: James Yonan <james@openvpn.net>
Also, break out json::fmt_name* methods into their own
source file.
NOTE: this code includes some SFINAE, so may need #ifdefs for
Visual Studio.
Signed-off-by: James Yonan <james@openvpn.net>
BijectiveSetMapping is a one-to-many bijective mapping.
If K is the key and V is the value, you can:
1. add to the forward map in the form [ K : set(V) ]
2. delete K from the forward map
The BijectiveSetMapping automatically maintains the
reverse mapping where each element is the form:
[ V: set(K) ]
Also enhanced StringTempl::to_string() with an SFINAE
variant that supports objects having a to_string() method.
Signed-off-by: James Yonan <james@openvpn.net>
Also, break out json::fmt_name* methods into their own
source file.
NOTE: this code includes some SFINAE, so may need #ifdefs for
Visual Studio.
Signed-off-by: James Yonan <james@openvpn.net>
Also, break out json::fmt_name* methods into their own
source file.
NOTE: this code includes some SFINAE, so may need #ifdefs for
Visual Studio.
Signed-off-by: James Yonan <james@openvpn.net>
* Added simple parse() method that only requires
JSON string to be parsed.
* Added get_string_from_array() method that doesn't
require title parameter.
* Added cast_array() method that doesn't require
title parameter.
Signed-off-by: James Yonan <james@openvpn.net>
Also:
* break up some long lines in source code
* added get_uint_optional_via_string() and
get_uint64_optional_via_string()
Signed-off-by: James Yonan <james@openvpn.net>
* use namespace json instead of class json so that other
source files can also add stuff to namespace json
* make fmt_name() method public
* added get_string_from_array() method
* added get_(int|uint|uint64)_optional() methods
* added get_(uint|uint64)_via_string() methods
* added some title-free method variants such as get_dict()
and cast_dict()
Signed-off-by: James Yonan <james@openvpn.net>
* Templatize name and title parameters.
* String construct the json_parse exceptions instead of
using OPENVPN_THROW.
* Refactor to_x() methods to derive from get_x() methods
instead of the other way around.
* Added get_uint64() method.
* Added cast_array() method.
* Added format() method.
This fixes build on Android NDK with clang/clang++
Neither the Android libc nor the libc++ used by Android by default
have the __bswap_constant_64 macro.
The more standard include of byteswap.h and bswap_64 exists only on
Linux and Android. Mac OS X defines no function in its includes that
does a byteswap. Therefore keep the compiler internal but choose
Clang's when compiling with Clang.
Add /add-bypass-route method, which is called
by socket_protect() call in client before opening
connection to remote.
This is needed to do reconnect to another remote
in case when force-tunneling is used and existing
VPN tunnel is broken.
OVPN3-427
Signed-off-by: Lev Stipakov <lev@openvpn.net>
This enables agent to use Wintun instead of tap-windows6
as a tun driver. We pass an optional boolean flag, based on
config setting, from client to agent. That flag is then passed
by agent to TunSetup, which selects tun driver.
Signed-off-by: Lev Stipakov <lev@openvpn.net>
Sometimes when machine wakes from sleep,
it takes too long for agent service to start. This causes
an error which core treats as fatal and stops connection.
Fix by detecting timeout and throw non-fatal error, which
makes core reconnect.
Signed-off-by: Lev Stipakov <lev@openvpn.net>
Created a lightweight abstraction layer so that another i/o
reactor can be dropped in place of asio.
This commit includes:
* Added ASIO=1 to many "go" scripts that require asio
* Renamed "asio::" to "openvpn_io::".
Signed-off-by: James Yonan <james@openvpn.net>
* When transmitting Windows event objects from client app to
agent/service, duplicate the event HANDLEs before
transmission in case the original HANDLEs are closed before
the agent receives them. This has a minor disadvantage in
that the duplicated HANDLEs will leak if the agent/service
never establishes ownership over them.
* When agent/service receives event HANDLEs, since they have
already been duplicated in the context of the remote
process, move (instead of copy) the HANDLEs into the local
process context by using the DUPLICATE_CLOSE_SOURCE flag
to DuplicateHandle.
* When agent/service receives event HANDLEs, do some basic
sanity checks on them before calling async_wait.
* Split agent/service impersonation block into two sections,
one that can be executed before parent()->establish_tun()
and one after. This is done so that any exceptions
thrown by the pre-establish_tun() block can prevent the
expensive establish_tun() method from starting.
* In agent/service, call parent()->destroy_tun(os) if any
exceptions are thrown from http_request_received().
* Avoid TAP HANDLE leakage on named pipe comm link errors
when the agent has duplicated the HANDLE but before the
app has received it by using a Windows Event object
("confirm_event") that the agent client can use to assert
ownership over the HANDLE. If confirm_event never
signals, the agent will take responsibility for closing
the duplicated HANDLE.
* Trigger tun destroy through a Windows Event
("destroy_event") instead of a separate API method
("/tun-destroy") for better robustness since the Event
can easily be signaled by the app-side tuncli instance
destructor without any potential for exceptions.
* Agent client will now detect unexpected agent/service
process termination and immediately disconnect any
active session via this error:
self->parent.tun_error(Error::TUN_IFACE_DISABLED,
"service failure");
* /tun-setup API method will now explicitly close any
pre-existing tun instance before establishing a new
instance.
* Increased agent client API timeout from 10 to 30 seconds.
* Increased verbosity of agent/service logging in
agent.log.
* TAP interface is now opened from the service and
the TAP HANDLE is communicated back to the client.
This allows us to configure the TAP driver to
reject open requests from non-privileged users.
* Old ActionList approach required us to validate and
execute command lines sent from client to service.
The new API approach is higher-level and communicates
at the TunBuilderCapture level instead of using
lists of command lines (ActionList objects) that must
be sanity-checked.
* ovpnagent service can now detect client crashes and
close out an active tun session, preventing network
lockout.
1. OpenVPN Agent service -- ovpnagent/win/ovpnagent.cpp
2. OpenVPN agent client -- openvpn/client/win/cmdagent.hpp
Common configuration in openvpn/client/win/agentconfig.hpp
The client and service communicate over a named pipe, and
Windows Vista+ platforms will verify that both client and
server .exe files are running from the same directory.
Build OpenVPN 3 Windows client with OPENVPN_COMMAND_AGENT
to enable the privilege separation layer.
We need to support customization of pipe name in case when few
clients based on ovpnagent running at the same time. Name of
pipe is defined by build-time variable “OVPNAGENT_NAME” (we
already use it as name of Windows service).
Signed-off-by: Yuriy Barnovych <yuriy@openvpn.net>
Jira: UCONNECT-1151
1. OpenVPN Agent service -- ovpnagent/win/ovpnagent.cpp
2. OpenVPN agent client -- openvpn/client/win/cmdagent.hpp
Common configuration in openvpn/client/win/agentconfig.hpp
The client and service communicate over a named pipe, and
Windows Vista+ platforms will verify that both client and
server .exe files are running from the same directory.
Build OpenVPN 3 Windows client with OPENVPN_COMMAND_AGENT
to enable the privilege separation layer.
Created a lightweight abstraction layer so that another i/o
reactor can be dropped in place of asio.
This commit includes:
* Added ASIO=1 to many "go" scripts that require asio
* Renamed "asio::" to "openvpn_io::".
Signed-off-by: James Yonan <james@openvpn.net>
Previously, all listener sockets were configured with both
reuseaddr and reuseport. reuseaddr is reasonable to use as
a default, but reuseport should only be used when different
threads are listening on the same local port/address for
load-balancing purposes.
This patch adds two new socket option flags DISABLE_REUSE_ADDR
and REUSE_PORT, to provide finer-grained control over
these options.
Signed-off-by: James Yonan <james@openvpn.net>
Created a lightweight abstraction layer so that another i/o
reactor can be dropped in place of asio.
This commit includes:
* Added ASIO=1 to many "go" scripts that require asio
* Renamed "asio::" to "openvpn_io::".
Signed-off-by: James Yonan <james@openvpn.net>
Created a lightweight abstraction layer so that another i/o
reactor can be dropped in place of asio.
This commit includes:
* Added ASIO=1 to many "go" scripts that require asio
* Renamed "asio::" to "openvpn_io::".
Signed-off-by: James Yonan <james@openvpn.net>
Alt Routing allows services on meshed PG nodes to communicate
with services on other nodes via the secure mesh, and without
requiring SSL.
Signed-off-by: James Yonan <james@openvpn.net>
Created a lightweight abstraction layer so that another i/o
reactor can be dropped in place of asio.
This commit includes:
* Added ASIO=1 to many "go" scripts that require asio
* Renamed "asio::" to "openvpn_io::".
Signed-off-by: James Yonan <james@openvpn.net>
Errors fixed from gcc:
openvpn/openssl/pki/extpki.hpp: In static member function ‘static ECDSA_SIG* openvpn::ExternalPKIECImpl::ecdsa_sign_sig(const unsigned char*, int, const BIGNUM*, const BIGNUM*, EC_KEY*)’:
openvpn/openssl/pki/extpki.hpp:366:11: warning: variable ‘out’ set but not used [-Wunused-but-set-variable]
From Converity scan:
>>> CID 351295: Null pointer dereferences (REVERSE_INULL)
>>> Null-checking "rsa_meth" suggests that it may be null, but it has already been dereferenced on all paths leading to the check.
117 if (rsa_meth)
118 RSA_meth_free(rsa_meth);
119 }
Remove also check from sigout.size() > siglen. The buffer will throw an
exception if the decoded bytes do not fit.
When configuring net30 topology (TAP_WIN_IOCTL_CONFIG_POINT_TO_POINT),
remote value is calculated based on assumption that local address is
network + 2 and remote is network + 1. This holds for openvpn 2.4:
ifconfig 10.8.0.6 10.8.0.5
local 10.8.0.6
network = local & 255.255.255.252 = 10.8.0.4
remote = network + 1 = 10.8.0.5
But this doesn't hold when using VPN server by vpngate:
ifconfig 10.211.1.73 10.211.1.74
local 10.211.1.73
network = local & 255.255.255.252 = 10.211.1.72
remote = network + 1 = 10.211.1.73
Remote is same as local.
To fix, use openvpn2's approach - don't do any assumptions
and use ipconfig's second option as remote value.
Fixes https://github.com/OpenVPN/openvpn3/issues/95 (broken connection to vpngate)
Reported-by: Serathin <https://github.com/Serathin>
Signed-off-by: Lev Stipakov <lev@openvpn.net>
- use explicit for non copy single argument constructor
- add override where applicable
Signed-off-by: Arne Schwabe <arne@openvpn.net>
Signed-off-by: David Sommerseth <davids@openvpn.net>
The name add_exclude_route is extremely confusing in this context as
it implies that the function only adds exclude routes and not include
routes.
Signed-off-by: Arne Schwabe <arne@openvpn.net>
This allows to include/use this file when the other dependencies of
kodev.hpp are not yet declared. (E.g. logging)
Signed-off-by: Arne Schwabe <arne@openvpn.net>
As documentation says:
> If lpOverlapped is NULL, lpBytesReturned cannot be NULL
While on Windows 10 passing NULL works by accident,
on Windows 7 it crashes.
Signed-off-by: Lev Stipakov <lev@openvpn.net>
(cherry picked from commit 11d705d2c7)
The ClientAPI::EvalConfig::privateKeyPasswordRequired bool flag was not
set correctly when the private key was an encrypted EC key.
This flag is set in EvalConfig by OpenVPNClient::parse_config()
when it calls ParseClientConfig::privateKeyPasswordRequired().
Signed-off-by: David Sommerseth <davids@openvpn.net>
This is used to enable connectivity to a different remote
when force-tunneling is used and current VPN connection is broken.
Signed-off-by: Lev Stipakov <lev@openvpn.net>
This method generates /sbin/route commands which
create and delete bypass route for given host.
It is needed to enable connectivity to a different remote
when force-tunneling is used and current VPN connection is broken.
Signed-off-by: Lev Stipakov <lev@openvpn.net>
As documentation says:
> If lpOverlapped is NULL, lpBytesReturned cannot be NULL
While on Windows 10 passing NULL works by accident,
on Windows 7 it crashes.
Signed-off-by: Lev Stipakov <lev@openvpn.net>
Before debug logging, HTTP headers should be passed through
HTTP::headers_redact() to prevent the creds from being logged.
Signed-off-by: James Yonan <james@openvpn.net>
d8d14e1991 implemented a new logic which
allows the DNS resolution to happen in a detachable thread. Since then,
we must execute async_resolve_lock() before performing the resolution so
that the main event queue is kept alive, while the core is busy
resolving the hostname.
Failing to do so will result in the main event queue terminating due to
"no events in the queue" and thus closing the core process.
Add lock (and related cancel) around resolution operation to guarantee
the core process stays alive during resolution.
Signed-off-by: Antonio Quartulli <antonio@openvpn.net>
This is the mbed TLS counter part to the OpenSSL change in
commit e0fd92f30756. These two methods are generic and not
tied to the MbedTLSContext in any particular way.
This is needed to be able to add a unit test for the x509_get_*()
functions.
Signed-off-by: David Sommerseth <davids@openvpn.net>
This moves generic OpenSSL related functions used to extract X.509
certificate information to an independent file which can be used more
freely. This code does not contain anything specific to the
OpenSSLContext class group and works nicely as a separate unit.
This is needed to be able to add unit test code for the x509_get_*()
functions.
Signed-off-by: David Sommerseth <davids@openvpn.net>
This implements the --verify-x509-name support for builds with OpenSSL.
This change requires the x509_get_subject() to be extended to provide
the subject field in a newer format, which requires using a different
OpenSSL API. Since we have code which might require the old format as
well, x509_get_subject() will default to use the old format.
The --verify-x509-name supports matching both against the full subject
line and the X.509 Certificate Common Name, which means we need to check
which mode is configured and extract the proper value before calling the
VerifyX509Name::verify() method.
Signed-off-by: David Sommerseth <davids@openvpn.net>
This new VerifyX509Name class handles both extracting and parsing the
appropriate --verify-x509-name option and is able to verify if a given
subject or hostname is matching the expectation.
Signed-off-by: David Sommerseth <davids@openvpn.net>
In some situations, the local6 variable is nullptr but a default IPv6
route has been configured. This causes a segfault later in the call
chain when add_del_route() is being called.
We already have avoid a similar situation with IPv4, so implement the
same kind of safe guard for IPv6: If no local IPv6 address has been
configured, don't attempt to add IPv6 routes.
Signed-off-by: David Sommerseth <davids@openvpn.net>
This avoids the mistake of using the insecure MTRand in anything but
a unit test and has the advantage that not all MTRand in a unit test
suite report being secure
Signed-off-by: Arne Schwabe <arne@openvpn.net>
The CryptoDCSettings::digest() method returns SHA1 digest when the
cipher is an AEAD cipher. This is incorrect, as AEAD ciphers does not
use digests for authentication at all; the authentication is an
integral part of the AEAD cipher itself.
To solve this, the CryptoAlgs::AlgFlags has been extended with a new
F_NO_CIPHER_DIGEST flag which is expected to be set on ciphers not
depending on any digests for authentication, like AES-GCM/AEAD
ciphers. A new method, use_cipher_digest(), will return True if
the cipher depends on a digest for authentication.
Signed-off-by: David Sommerseth <davids@openvpn.net>
This method, which is called by agent, generates netsh commands
to add/remove bypass route.
While we also do it in adapter_config() call, with force tunneling
and tun_persist this functionality is required before opening tun,
therefore need in a separate method.
Signed-off-by: Lev Stipakov <lev@openvpn.net>
This enables socket_protect call for all transports / platforms
with default implemenation being no-op.
This is needed for better round-robin DNS
fix for Connect clients (OVPN3-427).
Signed-off-by: Lev Stipakov <lev@openvpn.net>
When tun_persist is set, we do pre-resolve and install bypass routes
for all remotes to be able to reconnect in force-tunneling case and tunnel is broken.
This is sub-optimal, since DNS may change during VPN session and there is no need
to have bypass route for remote A when we are connected to remote B.
Following commits will add bypass route before opening tunnel.
Signed-off-by: Lev Stipakov <lev@openvpn.net>
Prefix error messages with a predefined string of the form:
ERR_PROFILE_xxxxx:
This way a user can parse the prefix and get a better understanding of
the error, without relying on the sole message.
Signed-off-by: Antonio Quartulli <antonio@openvpn.net>
When connecting to a server which pushes a stub compressor and the
client has compression disabled, it will complain about it in the log.
> Server has pushed compressor COMP_STUBv2, but client has disabled
compression, switching to asymmetric
This is confusing, since stub compressors does not compress. No need to
confuse the users, so we just remove the warning in this case.
Signed-off-by: David Sommerseth <davids@openvpn.net>
If the connection enables compression, ensure the UI can get a
notification about this and evaluate if the should be warned or not.
Signed-off-by: David Sommerseth <davids@openvpn.net>
This is useful for unit tests that must produce deterministic results.
You would never want to define this in production, because it turns off
the check that prevents non-crypto RNGs from being used for crypto
purposes.
Signed-off-by: James Yonan <james@openvpn.net>
Initializing MTRand with a constant seed is useful for unit tests
that need to produce deterministic output.
Signed-off-by: James Yonan <james@openvpn.net>
This unmaps ring buffers on tun destory
and prevents memory (working set) leak on reconnect.
I didn't fix it earlier because of Working Set is not visible in
Task Manager, had to use ProcessExplorer.
Signed-off-by: Lev Stipakov <lev@openvpn.net>
OpenSSLContext::SSL::ssl23_method_client_ and
OpenSSLContext::SSL::ssl23_method_server_ are only defined if the
OPENSSL_VERSION_NUMBER is below 0x10100000L. But this will still make
multiple compilation units fail, due to how the various #include lines
are ordered and used. This can eventually lead to multiple declarations
of ssl23_method_client_ and ssl23_method_server_ - which happens to
coreUnitTests on RHEL-7.
We add an additional defined(OPENVPN_NO_EXTERN) test to be sure this is
really not declared unless externs are expected to be declared.
Signed-off-by: David Sommerseth <davids@openvpn.net>
Two of the OpenSSL API compat function declarations in compat.hpp was
missing the 'inline' keyword. Without this keyword, builds using
multiple compilation units (such as the coreUnitTests) would fail due to
multiple declarations of these functions.
Signed-off-by: David Sommerseth <davids@openvpn.net>
1. Don't emit spaces if the input string is empty.
2. Don't emit spaces after the last newline in the input string.
Signed-off-by: James Yonan <james@openvpn.net>
Linux has a filename maximum of 255 chars, but we need to
be careful about the composition of the temporary filename
so that we don't exceed this limitation on the temporary,
even when the original is within the limit.
Signed-off-by: James Yonan <james@openvpn.net>
Since the auth-token-user directive (that is pushed from
server to client) is base64-encoded, increase the size
to support a pre-base64-encoded username length
of 256 characters.
Signed-off-by: James Yonan <james@openvpn.net>
Instead of reading single packet and calling
asio::post (which incurs overhead) to read next one,
continue reading packets until ringbuffer is empty (head == tail).
According to tests, this increases read performance
by 40% (from 1.25 to 1.70 Gbit/s).
Signed-off-by: Lev Stipakov <lev@openvpn.net>
Without specifying io_context, ASIO will use system
executor, which creates separate thread pool and runs
read() in a wrong, non openvpn core, thread.
Signed-off-by: Lev Stipakov <lev@openvpn.net>
Wintun documentation clearly states that we must use auto-reset events in ring buffers.
Auto-reset sets event back to non-signalled state after calling WaitForSingleObject.
Without auto-reset and explicit ResetEvent call we got a busy loop.
To avoid confusion move event.hpp from common/ to win/, since it is
Windows-specific code.
Signed-off-by: Lev Stipakov <lev@openvpn.net>
OpenSSL 1.1.0 introduces OpenSSL_version() function and the
OPENVPN_VERSION macro. Since they are not defined in older OpenSSL
versoins, building breaks.
The usage of OpenSSL_version() and OPENSSL_VERSION where introduced with
commit 23959fa705
Signed-off-by: David Sommerseth <davids@openvpn.net>