diff options
Diffstat (limited to 'src/openvpn')
-rw-r--r-- | src/openvpn/buffer.c | 23 | ||||
-rw-r--r-- | src/openvpn/buffer.h | 16 | ||||
-rw-r--r-- | src/openvpn/crypto.c | 2 | ||||
-rw-r--r-- | src/openvpn/crypto_openssl.c | 6 | ||||
-rw-r--r-- | src/openvpn/cryptoapi.c | 4 | ||||
-rw-r--r-- | src/openvpn/helper.c | 4 | ||||
-rw-r--r-- | src/openvpn/openvpn.vcxproj | 10 | ||||
-rw-r--r-- | src/openvpn/openvpn.vcxproj.filters | 3 | ||||
-rw-r--r-- | src/openvpn/options.c | 2 | ||||
-rw-r--r-- | src/openvpn/ring_buffer.h | 2 | ||||
-rw-r--r-- | src/openvpn/ssl_openssl.c | 4 | ||||
-rw-r--r-- | src/openvpn/ssl_openssl.h | 2 | ||||
-rw-r--r-- | src/openvpn/ssl_verify.c | 2 | ||||
-rw-r--r-- | src/openvpn/tun.c | 9 | ||||
-rw-r--r-- | src/openvpn/win32.c | 88 | ||||
-rw-r--r-- | src/openvpn/win32.h | 8 |
16 files changed, 127 insertions, 58 deletions
diff --git a/src/openvpn/buffer.c b/src/openvpn/buffer.c index c82d3d4..54e758a 100644 --- a/src/openvpn/buffer.c +++ b/src/openvpn/buffer.c @@ -311,29 +311,6 @@ openvpn_snprintf(char *str, size_t size, const char *format, ...) } /* - * openvpn_swprintf() is currently only used by Windows code paths - * and when enabled for all platforms it will currently break older - * OpenBSD versions lacking vswprintf(3) support in their libc. - */ - -#ifdef _WIN32 -bool -openvpn_swprintf(wchar_t *const str, const size_t size, const wchar_t *const format, ...) -{ - va_list arglist; - int len = -1; - if (size > 0) - { - va_start(arglist, format); - len = vswprintf(str, size, format, arglist); - va_end(arglist); - str[size - 1] = L'\0'; - } - return (len >= 0 && len < size); -} -#endif - -/* * write a string to the end of a buffer that was * truncated by buf_printf */ diff --git a/src/openvpn/buffer.h b/src/openvpn/buffer.h index fc7909b..1a795d2 100644 --- a/src/openvpn/buffer.h +++ b/src/openvpn/buffer.h @@ -449,22 +449,6 @@ __attribute__ ((format(__printf__, 3, 4))) ; -#ifdef _WIN32 -/* - * Like swprintf but guarantees null termination for size > 0 - * - * This is under #ifdef because only Windows-specific code in tun.c - * uses this function and its implementation breaks OpenBSD <= 4.9 - */ -bool -openvpn_swprintf(wchar_t *const str, const size_t size, const wchar_t *const format, ...); - -/* - * Unlike in openvpn_snprintf, we cannot use format attributes since - * GCC doesn't support wprintf as archetype. - */ -#endif - /* * remove/add trailing characters */ diff --git a/src/openvpn/crypto.c b/src/openvpn/crypto.c index 619cd96..6945cc0 100644 --- a/src/openvpn/crypto.c +++ b/src/openvpn/crypto.c @@ -729,7 +729,7 @@ warn_insecure_key_type(const char *ciphername, const cipher_kt_t *cipher) " bit (%d bit). This allows attacks like SWEET32. Mitigate by " "using a --cipher with a larger block size (e.g. AES-256-CBC). " "Support for these insecure ciphers will be removed in " - "OpenVPN 2.6.", + "OpenVPN 2.7.", ciphername, cipher_kt_block_size(cipher)*8); } } diff --git a/src/openvpn/crypto_openssl.c b/src/openvpn/crypto_openssl.c index 79fbab4..ef52092 100644 --- a/src/openvpn/crypto_openssl.c +++ b/src/openvpn/crypto_openssl.c @@ -51,6 +51,10 @@ #include <openssl/rand.h> #include <openssl/ssl.h> +#if defined(_WIN32) && defined(OPENSSL_NO_EC) +#error Windows build with OPENSSL_NO_EC: disabling EC key is not supported. +#endif + /* * Check for key size creepage. */ @@ -150,13 +154,11 @@ crypto_init_lib_engine(const char *engine_name) void crypto_init_lib(void) { -#ifndef _WIN32 #if (OPENSSL_VERSION_NUMBER >= 0x10100000L) OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG, NULL); #else OPENSSL_config(NULL); #endif -#endif /* _WIN32 */ /* * If you build the OpenSSL library and OpenVPN with * CRYPTO_MDEBUG, you will get a listing of OpenSSL diff --git a/src/openvpn/cryptoapi.c b/src/openvpn/cryptoapi.c index 6c4df9e..4becef4 100644 --- a/src/openvpn/cryptoapi.c +++ b/src/openvpn/cryptoapi.c @@ -537,7 +537,7 @@ finish(RSA *rsa) return 1; } -#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && !defined(OPENSSL_NO_EC) +#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) static EC_KEY_METHOD *ec_method = NULL; @@ -1232,7 +1232,7 @@ SSL_CTX_use_CryptoAPI_certificate(SSL_CTX *ssl_ctx, const char *cert_prop) goto err; } } -#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && !defined(OPENSSL_NO_EC) +#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) else if (EVP_PKEY_id(pkey) == EVP_PKEY_EC) { if (!ssl_ctx_set_eckey(ssl_ctx, cd, pkey)) diff --git a/src/openvpn/helper.c b/src/openvpn/helper.c index 67131b5..ebb5142 100644 --- a/src/openvpn/helper.c +++ b/src/openvpn/helper.c @@ -239,7 +239,7 @@ helper_client_server(struct options *o) * if tap OR (tun AND topology == subnet): * ifconfig 10.8.0.1 255.255.255.0 * if !nopool: - * ifconfig-pool 10.8.0.2 10.8.0.253 255.255.255.0 + * ifconfig-pool 10.8.0.2 10.8.0.254 255.255.255.0 * push "route-gateway 10.8.0.1" * if route-gateway unset: * route-gateway 10.8.0.2 @@ -342,7 +342,7 @@ helper_client_server(struct options *o) { o->ifconfig_pool_defined = true; o->ifconfig_pool_start = o->server_network + 2; - o->ifconfig_pool_end = (o->server_network | ~o->server_netmask) - 2; + o->ifconfig_pool_end = (o->server_network | ~o->server_netmask) - 1; ifconfig_pool_verify_range(M_USAGE, o->ifconfig_pool_start, o->ifconfig_pool_end); } o->ifconfig_pool_netmask = o->server_netmask; diff --git a/src/openvpn/openvpn.vcxproj b/src/openvpn/openvpn.vcxproj index 2144775..33b8f19 100644 --- a/src/openvpn/openvpn.vcxproj +++ b/src/openvpn/openvpn.vcxproj @@ -38,33 +38,39 @@ <WholeProgramOptimization>true</WholeProgramOptimization> <CharacterSet>NotSet</CharacterSet> <PlatformToolset>v142</PlatformToolset> + <SpectreMitigation>Spectre</SpectreMitigation> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> <ConfigurationType>Application</ConfigurationType> <WholeProgramOptimization>true</WholeProgramOptimization> <CharacterSet>NotSet</CharacterSet> <PlatformToolset>v142</PlatformToolset> + <SpectreMitigation>Spectre</SpectreMitigation> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration"> <ConfigurationType>Application</ConfigurationType> <WholeProgramOptimization>true</WholeProgramOptimization> <CharacterSet>NotSet</CharacterSet> <PlatformToolset>v142</PlatformToolset> + <SpectreMitigation>Spectre</SpectreMitigation> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <ConfigurationType>Application</ConfigurationType> <CharacterSet>NotSet</CharacterSet> <PlatformToolset>v142</PlatformToolset> + <SpectreMitigation>Spectre</SpectreMitigation> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> <ConfigurationType>Application</ConfigurationType> <CharacterSet>NotSet</CharacterSet> <PlatformToolset>v142</PlatformToolset> + <SpectreMitigation>Spectre</SpectreMitigation> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration"> <ConfigurationType>Application</ConfigurationType> <CharacterSet>NotSet</CharacterSet> <PlatformToolset>v142</PlatformToolset> + <SpectreMitigation>Spectre</SpectreMitigation> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> @@ -191,6 +197,7 @@ <WarningLevel>Level2</WarningLevel> <TreatWarningAsError>true</TreatWarningAsError> <AdditionalIncludeDirectories>..\compat;$(SolutionDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <ControlFlowGuard>Guard</ControlFlowGuard> </ClCompile> <ResourceCompile /> <Link> @@ -206,6 +213,7 @@ <WarningLevel>Level2</WarningLevel> <TreatWarningAsError>true</TreatWarningAsError> <AdditionalIncludeDirectories>..\compat;$(SolutionDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <ControlFlowGuard>Guard</ControlFlowGuard> </ClCompile> <ResourceCompile /> <Link> @@ -221,6 +229,7 @@ <WarningLevel>Level2</WarningLevel> <TreatWarningAsError>true</TreatWarningAsError> <AdditionalIncludeDirectories>..\compat;$(SolutionDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <ControlFlowGuard>Guard</ControlFlowGuard> </ClCompile> <ResourceCompile /> <Link> @@ -355,6 +364,7 @@ <ClInclude Include="multi.h" /> <ClInclude Include="ntlm.h" /> <ClInclude Include="occ.h" /> + <ClInclude Include="openssl_compat.h" /> <ClInclude Include="openvpn.h" /> <ClInclude Include="options.h" /> <ClInclude Include="otime.h" /> diff --git a/src/openvpn/openvpn.vcxproj.filters b/src/openvpn/openvpn.vcxproj.filters index cf5748c..bbcbff3 100644 --- a/src/openvpn/openvpn.vcxproj.filters +++ b/src/openvpn/openvpn.vcxproj.filters @@ -509,6 +509,9 @@ <ClInclude Include="ssl_ncp.h"> <Filter>Header Files</Filter> </ClInclude> + <ClInclude Include="openssl_compat.h"> + <Filter>Header Files</Filter> + </ClInclude> </ItemGroup> <ItemGroup> <ResourceCompile Include="openvpn_win32_resources.rc"> diff --git a/src/openvpn/options.c b/src/openvpn/options.c index a536ebe..f88cf2e 100644 --- a/src/openvpn/options.c +++ b/src/openvpn/options.c @@ -418,6 +418,8 @@ static const char usage_message[] = " execution. Peer must specify --pull in its config file.\n" "--push-reset : Don't inherit global push list for specific\n" " client instance.\n" + "--push-remove opt : Remove options matching 'opt' from the push list for\n" + " a specific client instance.\n" "--ifconfig-pool start-IP end-IP [netmask] : Set aside a pool of subnets\n" " to be dynamically allocated to connecting clients.\n" "--ifconfig-pool-persist file [seconds] : Persist/unpersist ifconfig-pool\n" diff --git a/src/openvpn/ring_buffer.h b/src/openvpn/ring_buffer.h index 77579e3..9661ceb 100644 --- a/src/openvpn/ring_buffer.h +++ b/src/openvpn/ring_buffer.h @@ -94,7 +94,7 @@ struct TUN_PACKET * that data has been written to receive ring * @return true if registration is successful, false otherwise - use GetLastError() */ -static bool +static inline bool register_ring_buffers(HANDLE device, struct tun_ring *send_ring, struct tun_ring *receive_ring, diff --git a/src/openvpn/ssl_openssl.c b/src/openvpn/ssl_openssl.c index 31d94f2..27fb66a 100644 --- a/src/openvpn/ssl_openssl.c +++ b/src/openvpn/ssl_openssl.c @@ -65,6 +65,10 @@ #include <openssl/ec.h> #endif +#if defined(_MSC_VER) && !defined(_M_ARM64) +#include <openssl/applink.c> +#endif + /* * Allocate space in SSL objects in which to store a struct tls_session * pointer back to parent. diff --git a/src/openvpn/ssl_openssl.h b/src/openvpn/ssl_openssl.h index 2eeb716..46338c2 100644 --- a/src/openvpn/ssl_openssl.h +++ b/src/openvpn/ssl_openssl.h @@ -54,6 +54,4 @@ struct key_state_ssl { */ extern int mydata_index; /* GLOBAL */ -void openssl_set_mydata_index(void); - #endif /* SSL_OPENSSL_H_ */ diff --git a/src/openvpn/ssl_verify.c b/src/openvpn/ssl_verify.c index 4f3b61d..0ccd43d 100644 --- a/src/openvpn/ssl_verify.c +++ b/src/openvpn/ssl_verify.c @@ -116,6 +116,8 @@ set_common_name(struct tls_session *session, const char *common_name) } #endif } + /* update common name in env */ + setenv_str(session->opt->es, "common_name", common_name); } /* diff --git a/src/openvpn/tun.c b/src/openvpn/tun.c index 512ccba..db8fdec 100644 --- a/src/openvpn/tun.c +++ b/src/openvpn/tun.c @@ -6388,14 +6388,7 @@ tuntap_dhcp_mask(const struct tuntap *tt, const char *device_guid) { if (tt->topology == TOP_SUBNET) { - if (tt->options.dhcp_masq_custom_offset) - { - ep[2] = dhcp_masq_addr(tt->local, tt->remote_netmask, tt->options.dhcp_masq_offset); - } - else - { - ep[2] = dhcp_masq_addr(tt->local, tt->remote_netmask, -1); - } + ep[2] = dhcp_masq_addr(tt->local, tt->remote_netmask, tt->options.dhcp_masq_custom_offset ? tt->options.dhcp_masq_offset : 0); } else { diff --git a/src/openvpn/win32.c b/src/openvpn/win32.c index 6cff17b..920a3b3 100644 --- a/src/openvpn/win32.c +++ b/src/openvpn/win32.c @@ -101,6 +101,12 @@ struct semaphore netcmd_semaphore; /* GLOBAL */ */ static char *win_sys_path = NULL; /* GLOBAL */ +/** + * Set OpenSSL environment variables to a safe directory + */ +static void +set_openssl_env_vars(); + void init_win32(void) { @@ -110,6 +116,8 @@ init_win32(void) } window_title_clear(&window_title); win32_signal_clear(&win32_signal); + + set_openssl_env_vars(); } void @@ -1509,4 +1517,84 @@ send_msg_iservice(HANDLE pipe, const void *data, size_t size, return ret; } +bool +openvpn_swprintf(wchar_t *const str, const size_t size, const wchar_t *const format, ...) +{ + va_list arglist; + int len = -1; + if (size > 0) + { + va_start(arglist, format); + len = vswprintf(str, size, format, arglist); + va_end(arglist); + str[size - 1] = L'\0'; + } + return (len >= 0 && len < size); +} + +static BOOL +get_install_path(WCHAR *path, DWORD size) +{ + WCHAR reg_path[256]; + HKEY key; + BOOL res = FALSE; + openvpn_swprintf(reg_path, _countof(reg_path), L"SOFTWARE\\" PACKAGE_NAME); + + LONG status = RegOpenKeyExW(HKEY_LOCAL_MACHINE, reg_path, 0, KEY_READ, &key); + if (status != ERROR_SUCCESS) + { + return res; + } + + /* The default value of REG_KEY is the install path */ + status = RegGetValueW(key, NULL, NULL, RRF_RT_REG_SZ, NULL, (LPBYTE)path, &size); + res = status == ERROR_SUCCESS; + + RegCloseKey(key); + + return res; +} + +static void +set_openssl_env_vars() +{ + const WCHAR *ssl_fallback_dir = L"C:\\Windows\\System32"; + + WCHAR install_path[MAX_PATH] = { 0 }; + if (!get_install_path(install_path, _countof(install_path))) + { + /* if we cannot find installation path from the registry, + * use Windows directory as a fallback + */ + openvpn_swprintf(install_path, _countof(install_path), L"%ls", ssl_fallback_dir); + } + + if ((install_path[wcslen(install_path) - 1]) == L'\\') + { + install_path[wcslen(install_path) - 1] = L'\0'; + } + + static struct { + WCHAR *name; + WCHAR *value; + } ossl_env[] = { + {L"OPENSSL_CONF", L"openssl.cnf"}, + {L"OPENSSL_ENGINES", L"engines"}, + {L"OPENSSL_MODULES", L"modules"} + }; + + for (size_t i = 0; i < SIZE(ossl_env); ++i) + { + size_t size = 0; + + _wgetenv_s(&size, NULL, 0, ossl_env[i].name); + if (size == 0) + { + WCHAR val[MAX_PATH] = {0}; + openvpn_swprintf(val, _countof(val), L"%ls\\ssl\\%ls", install_path, ossl_env[i].value); + _wputenv_s(ossl_env[i].name, val); + } + } +} + #endif /* ifdef _WIN32 */ diff --git a/src/openvpn/win32.h b/src/openvpn/win32.h index 5d3371a..5c3bcc3 100644 --- a/src/openvpn/win32.h +++ b/src/openvpn/win32.h @@ -327,7 +327,13 @@ bool send_msg_iservice(HANDLE pipe, const void *data, size_t size, int openvpn_execve(const struct argv *a, const struct env_set *es, const unsigned int flags); -bool impersonate_as_system(); +/* + * openvpn_swprintf() is currently only used by Windows code paths + * and when enabled for all platforms it will currently break older + * OpenBSD versions lacking vswprintf(3) support in their libc. + */ +bool +openvpn_swprintf(wchar_t *const str, const size_t size, const wchar_t *const format, ...); #endif /* ifndef OPENVPN_WIN32_H */ #endif /* ifdef _WIN32 */ |