summaryrefslogtreecommitdiff
path: root/src/openvpn
diff options
context:
space:
mode:
Diffstat (limited to 'src/openvpn')
-rw-r--r--src/openvpn/Makefile.in3
-rw-r--r--src/openvpn/crypto.c1
-rw-r--r--src/openvpn/crypto_backend.h9
-rw-r--r--src/openvpn/crypto_mbedtls.c7
-rw-r--r--src/openvpn/crypto_openssl.c8
-rw-r--r--src/openvpn/cryptoapi.c379
-rw-r--r--src/openvpn/forward.c2
-rw-r--r--src/openvpn/init.c2
-rw-r--r--src/openvpn/init.h2
-rw-r--r--src/openvpn/misc.c93
-rw-r--r--src/openvpn/misc.h5
-rw-r--r--src/openvpn/mtcp.c2
-rw-r--r--src/openvpn/mudp.c2
-rw-r--r--src/openvpn/multi.c32
-rw-r--r--src/openvpn/multi.h9
-rw-r--r--src/openvpn/openssl_compat.h12
-rw-r--r--src/openvpn/openvpn.c2
-rw-r--r--src/openvpn/openvpn_win32_resources.rc2
-rw-r--r--src/openvpn/options.c20
-rw-r--r--src/openvpn/pkcs11.c2
-rw-r--r--src/openvpn/proxy.c2
-rw-r--r--src/openvpn/route.c4
-rw-r--r--src/openvpn/socket.c2
-rw-r--r--src/openvpn/socks.c4
-rw-r--r--src/openvpn/ssl_openssl.c22
-rw-r--r--src/openvpn/tun.c10
-rw-r--r--src/openvpn/tun.h2
-rw-r--r--src/openvpn/win32.c15
28 files changed, 484 insertions, 171 deletions
diff --git a/src/openvpn/Makefile.in b/src/openvpn/Makefile.in
index 6aab503..3db2849 100644
--- a/src/openvpn/Makefile.in
+++ b/src/openvpn/Makefile.in
@@ -417,9 +417,6 @@ TAP_WIN_MIN_MINOR = @TAP_WIN_MIN_MINOR@
TEST_CFLAGS = @TEST_CFLAGS@
TEST_LDFLAGS = @TEST_LDFLAGS@
TMPFILES_DIR = @TMPFILES_DIR@
-VENDOR_BUILD_ROOT = @VENDOR_BUILD_ROOT@
-VENDOR_DIST_ROOT = @VENDOR_DIST_ROOT@
-VENDOR_SRC_ROOT = @VENDOR_SRC_ROOT@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
diff --git a/src/openvpn/crypto.c b/src/openvpn/crypto.c
index 59e5ac5..7e7dead 100644
--- a/src/openvpn/crypto.c
+++ b/src/openvpn/crypto.c
@@ -919,7 +919,6 @@ free_key_ctx(struct key_ctx *ctx)
{
if (ctx->cipher)
{
- cipher_ctx_cleanup(ctx->cipher);
cipher_ctx_free(ctx->cipher);
ctx->cipher = NULL;
}
diff --git a/src/openvpn/crypto_backend.h b/src/openvpn/crypto_backend.h
index 1ee2980..b3db925 100644
--- a/src/openvpn/crypto_backend.h
+++ b/src/openvpn/crypto_backend.h
@@ -307,7 +307,7 @@ bool cipher_kt_mode_aead(const cipher_kt_t *cipher);
cipher_ctx_t *cipher_ctx_new(void);
/**
- * Free a cipher context
+ * Cleanup and free a cipher context
*
* @param ctx Cipher context.
*/
@@ -327,13 +327,6 @@ void cipher_ctx_init(cipher_ctx_t *ctx, const uint8_t *key, int key_len,
const cipher_kt_t *kt, int enc);
/**
- * Cleanup the specified context.
- *
- * @param ctx Cipher context to cleanup.
- */
-void cipher_ctx_cleanup(cipher_ctx_t *ctx);
-
-/**
* Returns the size of the IV used by the cipher, in bytes, or 0 if no IV is
* used.
*
diff --git a/src/openvpn/crypto_mbedtls.c b/src/openvpn/crypto_mbedtls.c
index 82a92af..748043e 100644
--- a/src/openvpn/crypto_mbedtls.c
+++ b/src/openvpn/crypto_mbedtls.c
@@ -519,6 +519,7 @@ cipher_ctx_new(void)
void
cipher_ctx_free(mbedtls_cipher_context_t *ctx)
{
+ mbedtls_cipher_free(ctx);
free(ctx);
}
@@ -544,12 +545,6 @@ cipher_ctx_init(mbedtls_cipher_context_t *ctx, const uint8_t *key, int key_len,
ASSERT(ctx->key_bitlen <= key_len*8);
}
-void
-cipher_ctx_cleanup(mbedtls_cipher_context_t *ctx)
-{
- mbedtls_cipher_free(ctx);
-}
-
int
cipher_ctx_iv_length(const mbedtls_cipher_context_t *ctx)
{
diff --git a/src/openvpn/crypto_openssl.c b/src/openvpn/crypto_openssl.c
index 71602f3..3abcc99 100644
--- a/src/openvpn/crypto_openssl.c
+++ b/src/openvpn/crypto_openssl.c
@@ -679,7 +679,7 @@ cipher_ctx_init(EVP_CIPHER_CTX *ctx, const uint8_t *key, int key_len,
{
ASSERT(NULL != kt && NULL != ctx);
- EVP_CIPHER_CTX_init(ctx);
+ EVP_CIPHER_CTX_reset(ctx);
if (!EVP_CipherInit(ctx, kt, NULL, NULL, enc))
{
crypto_msg(M_FATAL, "EVP cipher init #1");
@@ -699,12 +699,6 @@ cipher_ctx_init(EVP_CIPHER_CTX *ctx, const uint8_t *key, int key_len,
ASSERT(EVP_CIPHER_CTX_key_length(ctx) <= key_len);
}
-void
-cipher_ctx_cleanup(EVP_CIPHER_CTX *ctx)
-{
- EVP_CIPHER_CTX_cleanup(ctx);
-}
-
int
cipher_ctx_iv_length(const EVP_CIPHER_CTX *ctx)
{
diff --git a/src/openvpn/cryptoapi.c b/src/openvpn/cryptoapi.c
index 720fce0..7f2c3c0 100644
--- a/src/openvpn/cryptoapi.c
+++ b/src/openvpn/cryptoapi.c
@@ -39,6 +39,7 @@
#ifdef ENABLE_CRYPTOAPI
#include <openssl/ssl.h>
+#include <openssl/evp.h>
#include <openssl/err.h>
#include <windows.h>
#include <wincrypt.h>
@@ -101,6 +102,12 @@ static ERR_STRING_DATA CRYPTOAPI_str_functs[] = {
{ 0, NULL }
};
+/* Global EVP_PKEY_METHOD used to override the sign operation */
+static EVP_PKEY_METHOD *pmethod;
+static int (*default_pkey_sign_init) (EVP_PKEY_CTX *ctx);
+static int (*default_pkey_sign) (EVP_PKEY_CTX *ctx, unsigned char *sig,
+ size_t *siglen, const unsigned char *tbs, size_t tbslen);
+
typedef struct _CAPI_DATA {
const CERT_CONTEXT *cert_context;
HCRYPTPROV_OR_NCRYPT_KEY_HANDLE crypt_prov;
@@ -108,6 +115,80 @@ typedef struct _CAPI_DATA {
BOOL free_crypt_prov;
} CAPI_DATA;
+/**
+ * Translate OpenSSL padding type to CNG padding type
+ * Returns 0 for unknown/unsupported padding.
+ */
+static DWORD
+cng_padding_type(int padding)
+{
+ DWORD pad = 0;
+
+ switch (padding)
+ {
+ case RSA_NO_PADDING:
+ pad = BCRYPT_PAD_NONE;
+ break;
+
+ case RSA_PKCS1_PADDING:
+ pad = BCRYPT_PAD_PKCS1;
+ break;
+
+ case RSA_PKCS1_PSS_PADDING:
+ pad = BCRYPT_PAD_PSS;
+ break;
+
+ default:
+ msg(M_WARN|M_INFO, "cryptoapicert: unknown OpenSSL padding type %d.",
+ padding);
+ }
+
+ return pad;
+}
+
+/**
+ * Translate OpenSSL hash OID to CNG algorithm name. Returns
+ * "UNKNOWN" for unsupported algorithms and NULL for MD5+SHA1
+ * mixed hash used in TLS 1.1 and earlier.
+ */
+static const wchar_t *
+cng_hash_algo(int md_type)
+{
+ const wchar_t *alg = L"UNKNOWN";
+ switch (md_type)
+ {
+ case NID_md5:
+ alg = BCRYPT_MD5_ALGORITHM;
+ break;
+
+ case NID_sha1:
+ alg = BCRYPT_SHA1_ALGORITHM;
+ break;
+
+ case NID_sha256:
+ alg = BCRYPT_SHA256_ALGORITHM;
+ break;
+
+ case NID_sha384:
+ alg = BCRYPT_SHA384_ALGORITHM;
+ break;
+
+ case NID_sha512:
+ alg = BCRYPT_SHA512_ALGORITHM;
+ break;
+
+ case NID_md5_sha1:
+ case 0:
+ alg = NULL;
+ break;
+
+ default:
+ msg(M_WARN|M_INFO, "cryptoapicert: Unknown hash type NID=0x%x", md_type);
+ break;
+ }
+ return alg;
+}
+
static char *
ms_error_text(DWORD ms_err)
{
@@ -217,25 +298,44 @@ rsa_pub_dec(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, in
* Sign the hash in 'from' using NCryptSignHash(). This requires an NCRYPT
* key handle in cd->crypt_prov. On return the signature is in 'to'. Returns
* the length of the signature or 0 on error.
+ * Only RSA is supported and padding should be BCRYPT_PAD_PKCS1 or
+ * BCRYPT_PAD_PSS.
* If the hash_algo is not NULL, PKCS #1 DigestInfo header gets added
- * to 'from', else it is signed as is.
- * For now we support only RSA and the padding is assumed to be PKCS1 v1.5
+ * to |from|, else it is signed as is. Use NULL for MD5 + SHA1 hash used
+ * in TLS 1.1 and earlier.
+ * In case of PSS padding, |saltlen| should specify the size of salt to use.
+ * If |to| is NULL returns the required buffer size.
*/
static int
priv_enc_CNG(const CAPI_DATA *cd, const wchar_t *hash_algo, const unsigned char *from,
- int flen, unsigned char *to, int tlen, int padding)
+ int flen, unsigned char *to, int tlen, DWORD padding, DWORD saltlen)
{
NCRYPT_KEY_HANDLE hkey = cd->crypt_prov;
DWORD len = 0;
ASSERT(cd->key_spec == CERT_NCRYPT_KEY_SPEC);
- msg(D_LOW, "Signing hash using CNG: data size = %d", flen);
-
- BCRYPT_PKCS1_PADDING_INFO padinfo = {hash_algo};
DWORD status;
- status = NCryptSignHash(hkey, padding? &padinfo : NULL, (BYTE*) from, flen,
- to, tlen, &len, padding? BCRYPT_PAD_PKCS1 : 0);
+ msg(D_LOW, "Signing hash using CNG: data size = %d padding = %lu", flen, padding);
+
+ if (padding == BCRYPT_PAD_PKCS1)
+ {
+ BCRYPT_PKCS1_PADDING_INFO padinfo = {hash_algo};
+ status = NCryptSignHash(hkey, &padinfo, (BYTE *)from, flen,
+ to, tlen, &len, padding);
+ }
+ else if (padding == BCRYPT_PAD_PSS)
+ {
+ BCRYPT_PSS_PADDING_INFO padinfo = {hash_algo, saltlen};
+ status = NCryptSignHash(hkey, &padinfo, (BYTE *)from, flen,
+ to, tlen, &len, padding);
+ }
+ else
+ {
+ RSAerr(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, RSA_R_UNKNOWN_PADDING_TYPE);
+ return 0;
+ }
+
if (status != ERROR_SUCCESS)
{
SetLastError(status);
@@ -261,16 +361,19 @@ rsa_priv_enc(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, i
RSAerr(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
+
+ if (cd->key_spec == CERT_NCRYPT_KEY_SPEC)
+ {
+ return priv_enc_CNG(cd, NULL, from, flen, to, RSA_size(rsa),
+ cng_padding_type(padding), 0);
+ }
+
if (padding != RSA_PKCS1_PADDING)
{
/* AFAICS, CryptSignHash() *always* uses PKCS1 padding. */
RSAerr(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, RSA_R_UNKNOWN_PADDING_TYPE);
return 0;
}
- if (cd->key_spec == CERT_NCRYPT_KEY_SPEC)
- {
- return priv_enc_CNG(cd, NULL, from, flen, to, RSA_size(rsa), padding);
- }
/* Unfortunately, there is no "CryptSign()" function in CryptoAPI, that would
* be way to straightforward for M$, I guess... So we have to do it this
@@ -333,12 +436,13 @@ rsa_priv_enc(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, i
return len;
}
-/*
+/**
* Sign the hash in |m| and return the signature in |sig|.
* Returns 1 on success, 0 on error.
* NCryptSignHash() is used to sign and it is instructed to add the
* the PKCS #1 DigestInfo header to |m| unless the hash algorithm is
* the MD5/SHA1 combination used in TLS 1.1 and earlier versions.
+ * OpenSSL exercises this callback only when padding is PKCS1 v1.5.
*/
static int
rsa_sign_CNG(int type, const unsigned char *m, unsigned int m_len,
@@ -355,45 +459,17 @@ rsa_sign_CNG(int type, const unsigned char *m, unsigned int m_len,
return 0;
}
- switch (type)
+ alg = cng_hash_algo(type);
+ if (alg && wcscmp(alg, L"UNKNOWN") == 0)
{
- case NID_md5:
- alg = BCRYPT_MD5_ALGORITHM;
- break;
-
- case NID_sha1:
- alg = BCRYPT_SHA1_ALGORITHM;
- break;
-
- case NID_sha256:
- alg = BCRYPT_SHA256_ALGORITHM;
- break;
-
- case NID_sha384:
- alg = BCRYPT_SHA384_ALGORITHM;
- break;
-
- case NID_sha512:
- alg = BCRYPT_SHA512_ALGORITHM;
- break;
-
- case NID_md5_sha1:
- if (m_len != SSL_SIG_LENGTH)
- {
- RSAerr(RSA_F_RSA_SIGN, RSA_R_INVALID_MESSAGE_LENGTH);
- return 0;
- }
- /* No DigestInfo header is required -- set alg-name to NULL */
- alg = NULL;
- break;
- default:
- msg(M_WARN, "cryptoapicert: Unknown hash type NID=0x%x", type);
- RSAerr(RSA_F_RSA_SIGN, RSA_R_UNKNOWN_ALGORITHM_TYPE);
- return 0;
+ RSAerr(RSA_F_RSA_SIGN, RSA_R_UNKNOWN_ALGORITHM_TYPE);
+ return 0;
}
- *siglen = priv_enc_CNG(cd, alg, m, (int)m_len, sig, RSA_size(rsa), padding);
- return (siglen == 0) ? 0 : 1;
+ *siglen = priv_enc_CNG(cd, alg, m, (int)m_len, sig, RSA_size(rsa),
+ cng_padding_type(padding), 0);
+
+ return (*siglen == 0) ? 0 : 1;
}
/* decrypt */
@@ -518,6 +594,176 @@ find_certificate_in_store(const char *cert_prop, HCERTSTORE cert_store)
return rv;
}
+#if (OPENSSL_VERSION_NUMBER >= 0x10100000L)
+
+static const CAPI_DATA *
+retrieve_capi_data(EVP_PKEY *pkey)
+{
+ const CAPI_DATA *cd = NULL;
+
+ if (pkey && EVP_PKEY_id(pkey) == EVP_PKEY_RSA)
+ {
+ RSA *rsa = EVP_PKEY_get0_RSA(pkey);
+ if (rsa)
+ {
+ cd = (CAPI_DATA *)RSA_meth_get0_app_data(RSA_get_method(rsa));
+ }
+ }
+ return cd;
+}
+
+static int
+pkey_rsa_sign_init(EVP_PKEY_CTX *ctx)
+{
+ EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx);
+
+ if (pkey && retrieve_capi_data(pkey))
+ {
+ return 1; /* Return success */
+ }
+ else if (default_pkey_sign_init) /* Not our key. Call the default method */
+ {
+ return default_pkey_sign_init(ctx);
+ }
+ return 1;
+}
+
+/**
+ * Implementation of EVP_PKEY_sign() using CNG: sign the digest in |tbs|
+ * and save the the signature in |sig| and its size in |*siglen|.
+ * If |sig| is NULL the required buffer size is returned in |*siglen|.
+ * Returns 1 on success, 0 or a negative integer on error.
+ */
+static int
+pkey_rsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
+ const unsigned char *tbs, size_t tbslen)
+{
+ EVP_PKEY *pkey = NULL;
+ const CAPI_DATA *cd = NULL;
+ EVP_MD *md = NULL;
+ const wchar_t *alg = NULL;
+
+ int padding;
+ int hashlen;
+ int saltlen;
+
+ pkey = EVP_PKEY_CTX_get0_pkey(ctx);
+ if (pkey)
+ {
+ cd = retrieve_capi_data(pkey);
+ }
+
+ /*
+ * We intercept all sign requests, not just the one's for our key.
+ * Check the key and call the saved OpenSSL method for unknown keys.
+ */
+ if (!pkey || !cd)
+ {
+ if (default_pkey_sign)
+ {
+ return default_pkey_sign(ctx, sig, siglen, tbs, tbslen);
+ }
+ else /* This should not happen */
+ {
+ msg(M_FATAL, "cryptopaicert: Unknown key and no default sign operation to fallback on");
+ return -1;
+ }
+ }
+
+ if (!EVP_PKEY_CTX_get_rsa_padding(ctx, &padding))
+ {
+ padding = RSA_PKCS1_PADDING; /* Default padding for RSA */
+ }
+
+ if (EVP_PKEY_CTX_get_signature_md(ctx, &md))
+ {
+ hashlen = EVP_MD_size(md);
+ alg = cng_hash_algo(EVP_MD_type(md));
+
+ /*
+ * alg == NULL indicates legacy MD5+SHA1 hash, else alg should be a valid
+ * digest algorithm.
+ */
+ if (alg && wcscmp(alg, L"UNKNOWN") == 0)
+ {
+ RSAerr(RSA_F_PKEY_RSA_SIGN, RSA_R_UNKNOWN_ALGORITHM_TYPE);
+ return -1;
+ }
+ }
+ else
+ {
+ msg(M_NONFATAL, "cryptoapicert: could not determine the signature digest algorithm");
+ RSAerr(RSA_F_PKEY_RSA_SIGN, RSA_R_UNKNOWN_ALGORITHM_TYPE);
+ return -1;
+ }
+
+ if (tbslen != (size_t)hashlen)
+ {
+ RSAerr(RSA_F_PKEY_RSA_SIGN, RSA_R_INVALID_DIGEST_LENGTH);
+ return -1;
+ }
+
+ /* If padding is PSS, determine parameters to pass to CNG */
+ if (padding == RSA_PKCS1_PSS_PADDING)
+ {
+ /*
+ * Ensure the digest type for signature and mask generation match.
+ * In CNG there is no option to specify separate hash functions for
+ * the two, but OpenSSL supports it. However, I have not seen the
+ * two being different in practice. Also the recommended practice is
+ * to use the same for both (rfc 8017 sec 8.1).
+ */
+ EVP_MD *mgf1md;
+ if (!EVP_PKEY_CTX_get_rsa_mgf1_md(ctx, &mgf1md)
+ || EVP_MD_type(mgf1md) != EVP_MD_type(md))
+ {
+ msg(M_NONFATAL, "cryptoapicert: Unknown MGF1 digest type or does"
+ " not match the signature digest type.");
+ RSAerr(RSA_F_PKEY_RSA_SIGN, RSA_R_UNSUPPORTED_MASK_PARAMETER);
+ }
+
+ if (!EVP_PKEY_CTX_get_rsa_pss_saltlen(ctx, &saltlen))
+ {
+ msg(M_WARN|M_INFO, "cryptoapicert: unable to get the salt length from context."
+ " Using the default value.");
+ saltlen = -1;
+ }
+
+ /*
+ * In OpenSSL saltlen = -1 indicates to use the size of the digest as
+ * size of the salt. A value of -2 or -3 indicates maximum salt length
+ * that will fit. See RSA_padding_add_PKCS1_PSS_mgf1() of OpenSSL.
+ */
+ if (saltlen == -1)
+ {
+ saltlen = hashlen;
+ }
+ else if (saltlen < 0)
+ {
+ const RSA *rsa = EVP_PKEY_get0_RSA(pkey);
+ saltlen = RSA_size(rsa) - hashlen - 2; /* max salt length for RSASSA-PSS */
+ if (RSA_bits(rsa) &0x7) /* number of bits in the key not a multiple of 8 */
+ {
+ saltlen--;
+ }
+ }
+
+ if (saltlen < 0)
+ {
+ RSAerr(RSA_F_PKEY_RSA_SIGN, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
+ return -1;
+ }
+ msg(D_LOW, "cryptoapicert: PSS padding using saltlen = %d", saltlen);
+ }
+
+ *siglen = priv_enc_CNG(cd, alg, tbs, (int)tbslen, sig, *siglen,
+ cng_padding_type(padding), (DWORD)saltlen);
+
+ return (*siglen == 0) ? 0 : 1;
+}
+
+#endif /* OPENSSL_VERSION >= 1.1.0 */
+
int
SSL_CTX_use_CryptoAPI_certificate(SSL_CTX *ssl_ctx, const char *cert_prop)
{
@@ -620,10 +866,45 @@ SSL_CTX_use_CryptoAPI_certificate(SSL_CTX *ssl_ctx, const char *cert_prop)
/* For CNG, set the RSA_sign method which gets priority over priv_enc().
* This method is called with the raw hash without the digestinfo
* header and works better when using NCryptSignHash() with some tokens.
+ * However, if PSS padding is in use, openssl does not call this
+ * function but adds the padding and then calls rsa_priv_enc()
+ * with padding set to NONE which is not supported by CNG.
+ * So, when posisble (OpenSSL 1.1.0 and up), we hook on to the sign
+ * operation in EVP_PKEY_METHOD struct.
*/
if (cd->key_spec == CERT_NCRYPT_KEY_SPEC)
{
+#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
RSA_meth_set_sign(my_rsa_method, rsa_sign_CNG);
+#else
+ /* pmethod is global -- initialize only if NULL */
+ if (!pmethod)
+ {
+ pmethod = EVP_PKEY_meth_new(EVP_PKEY_RSA, 0);
+ if (!pmethod)
+ {
+ SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ const EVP_PKEY_METHOD *default_pmethod = EVP_PKEY_meth_find(EVP_PKEY_RSA);
+ EVP_PKEY_meth_copy(pmethod, default_pmethod);
+
+ /* We want to override only sign_init() and sign() */
+ EVP_PKEY_meth_set_sign(pmethod, pkey_rsa_sign_init, pkey_rsa_sign);
+ EVP_PKEY_meth_add0(pmethod);
+
+ /* Keep a copy of the default sign and sign_init methods */
+
+#if (OPENSSL_VERSION_NUMBER < 0x1010009fL) /* < version 1.1.0i */
+ /* The function signature is not const-correct in these versions */
+ EVP_PKEY_meth_get_sign((EVP_PKEY_METHOD *)default_pmethod, &default_pkey_sign_init,
+ &default_pkey_sign);
+#else
+ EVP_PKEY_meth_get_sign(default_pmethod, &default_pkey_sign_init,
+ &default_pkey_sign);
+#endif
+ }
+#endif /* (OPENSSL_VERSION_NUMBER < 0x10100000L) */
}
rsa = RSA_new();
diff --git a/src/openvpn/forward.c b/src/openvpn/forward.c
index 8f90418..65f790f 100644
--- a/src/openvpn/forward.c
+++ b/src/openvpn/forward.c
@@ -1037,7 +1037,7 @@ read_incoming_tun(struct context *c)
c->c2.buf = c->c2.buffers->read_tun_buf;
#ifdef TUN_PASS_BUFFER
- read_tun_buffered(c->c1.tuntap, &c->c2.buf, MAX_RW_SIZE_TUN(&c->c2.frame));
+ read_tun_buffered(c->c1.tuntap, &c->c2.buf);
#else
ASSERT(buf_init(&c->c2.buf, FRAME_HEADROOM(&c->c2.frame)));
ASSERT(buf_safe(&c->c2.buf, MAX_RW_SIZE_TUN(&c->c2.frame)));
diff --git a/src/openvpn/init.c b/src/openvpn/init.c
index 1cdef31..d3785ca 100644
--- a/src/openvpn/init.c
+++ b/src/openvpn/init.c
@@ -3883,7 +3883,7 @@ init_management_callback_p2p(struct context *c)
#ifdef ENABLE_MANAGEMENT
void
-init_management(struct context *c)
+init_management(void)
{
if (!management)
{
diff --git a/src/openvpn/init.h b/src/openvpn/init.h
index c8ebe76..2c846db 100644
--- a/src/openvpn/init.h
+++ b/src/openvpn/init.h
@@ -119,7 +119,7 @@ void initialization_sequence_completed(struct context *c, const unsigned int fla
#ifdef ENABLE_MANAGEMENT
-void init_management(struct context *c);
+void init_management(void);
bool open_management(struct context *c);
diff --git a/src/openvpn/misc.c b/src/openvpn/misc.c
index 581a890..f44c65f 100644
--- a/src/openvpn/misc.c
+++ b/src/openvpn/misc.c
@@ -99,44 +99,57 @@ save_inetd_socket_descriptor(void)
}
/*
- * Print an error message based on the status code returned by system().
+ * Generate an error message based on the status code returned by openvpn_execve().
*/
const char *
system_error_message(int stat, struct gc_arena *gc)
{
struct buffer out = alloc_buf_gc(256, gc);
-#ifdef _WIN32
- if (stat == -1)
+
+ switch (stat)
{
- buf_printf(&out, "external program did not execute -- ");
- }
- buf_printf(&out, "returned error code %d", stat);
+ case OPENVPN_EXECVE_NOT_ALLOWED:
+ buf_printf(&out, "disallowed by script-security setting");
+ break;
+
+#ifdef _WIN32
+ case OPENVPN_EXECVE_ERROR:
+ buf_printf(&out, "external program did not execute -- ");
+ /* fall through */
+
+ default:
+ buf_printf(&out, "returned error code %d", stat);
+ break;
#else /* ifdef _WIN32 */
- if (stat == -1)
- {
- buf_printf(&out, "external program fork failed");
- }
- else if (!WIFEXITED(stat))
- {
- buf_printf(&out, "external program did not exit normally");
- }
- else
- {
- const int cmd_ret = WEXITSTATUS(stat);
- if (!cmd_ret)
- {
- buf_printf(&out, "external program exited normally");
- }
- else if (cmd_ret == 127)
- {
- buf_printf(&out, "could not execute external program");
- }
- else
- {
- buf_printf(&out, "external program exited with error status: %d", cmd_ret);
- }
- }
+
+ case OPENVPN_EXECVE_ERROR:
+ buf_printf(&out, "external program fork failed");
+ break;
+
+ default:
+ if (!WIFEXITED(stat))
+ {
+ buf_printf(&out, "external program did not exit normally");
+ }
+ else
+ {
+ const int cmd_ret = WEXITSTATUS(stat);
+ if (!cmd_ret)
+ {
+ buf_printf(&out, "external program exited normally");
+ }
+ else if (cmd_ret == OPENVPN_EXECVE_FAILURE)
+ {
+ buf_printf(&out, "could not execute external program");
+ }
+ else
+ {
+ buf_printf(&out, "external program exited with error status: %d", cmd_ret);
+ }
+ }
+ break;
#endif /* ifdef _WIN32 */
+ }
return (const char *)out.data;
}
@@ -186,12 +199,14 @@ openvpn_execve_allowed(const unsigned int flags)
* Run execve() inside a fork(). Designed to replicate the semantics of system() but
* in a safer way that doesn't require the invocation of a shell or the risks
* assocated with formatting and parsing a command line.
+ * Returns the exit status of child, OPENVPN_EXECVE_NOT_ALLOWED if openvpn_execve_allowed()
+ * returns false, or OPENVPN_EXECVE_ERROR on other errors.
*/
int
openvpn_execve(const struct argv *a, const struct env_set *es, const unsigned int flags)
{
struct gc_arena gc = gc_new();
- int ret = -1;
+ int ret = OPENVPN_EXECVE_ERROR;
static bool warn_shown = false;
if (a && a->argv[0])
@@ -208,7 +223,7 @@ openvpn_execve(const struct argv *a, const struct env_set *es, const unsigned in
if (pid == (pid_t)0) /* child side */
{
execve(cmd, argv, envp);
- exit(127);
+ exit(OPENVPN_EXECVE_FAILURE);
}
else if (pid < (pid_t)0) /* fork failed */
{
@@ -218,14 +233,18 @@ openvpn_execve(const struct argv *a, const struct env_set *es, const unsigned in
{
if (waitpid(pid, &ret, 0) != pid)
{
- ret = -1;
+ ret = OPENVPN_EXECVE_ERROR;
}
}
}
- else if (!warn_shown && (script_security < SSEC_SCRIPTS))
+ else
{
- msg(M_WARN, SCRIPT_SECURITY_WARNING);
- warn_shown = true;
+ ret = OPENVPN_EXECVE_NOT_ALLOWED;
+ if (!warn_shown && (script_security < SSEC_SCRIPTS))
+ {
+ msg(M_WARN, SCRIPT_SECURITY_WARNING);
+ warn_shown = true;
+ }
}
#else /* if defined(ENABLE_FEATURE_EXECVE) */
msg(M_WARN, "openvpn_execve: execve function not available");
@@ -272,7 +291,7 @@ openvpn_popen(const struct argv *a, const struct env_set *es)
close(pipe_stdout[0]); /* Close read end */
dup2(pipe_stdout[1],1);
execve(cmd, argv, envp);
- exit(127);
+ exit(OPENVPN_EXECVE_FAILURE);
}
else if (pid > (pid_t)0) /* parent side */
{
diff --git a/src/openvpn/misc.h b/src/openvpn/misc.h
index a64ddcc..8a34f43 100644
--- a/src/openvpn/misc.h
+++ b/src/openvpn/misc.h
@@ -57,6 +57,11 @@ struct env_set {
const char *system_error_message(int, struct gc_arena *gc);
+/* openvpn_execve return codes */
+#define OPENVPN_EXECVE_ERROR -1 /* generic error while forking to run an external program */
+#define OPENVPN_EXECVE_NOT_ALLOWED -2 /* external program not run due to script security */
+#define OPENVPN_EXECVE_FAILURE 127 /* exit code passed back from child when execve fails */
+
/* wrapper around the execve() call */
int openvpn_popen(const struct argv *a, const struct env_set *es);
diff --git a/src/openvpn/mtcp.c b/src/openvpn/mtcp.c
index 3756c27..e8d2add 100644
--- a/src/openvpn/mtcp.c
+++ b/src/openvpn/mtcp.c
@@ -834,7 +834,7 @@ tunnel_server_tcp(struct context *top)
#endif
/* shut down management interface */
- uninit_management_callback_multi(&multi);
+ uninit_management_callback();
/* save ifconfig-pool */
multi_ifconfig_pool_persist(&multi, true);
diff --git a/src/openvpn/mudp.c b/src/openvpn/mudp.c
index b3690ab..4f63654 100644
--- a/src/openvpn/mudp.c
+++ b/src/openvpn/mudp.c
@@ -362,7 +362,7 @@ tunnel_server_udp_single_threaded(struct context *top)
#endif
/* shut down management interface */
- uninit_management_callback_multi(&multi);
+ uninit_management_callback();
/* save ifconfig-pool */
multi_ifconfig_pool_persist(&multi, true);
diff --git a/src/openvpn/multi.c b/src/openvpn/multi.c
index 28c3b88..baffd74 100644
--- a/src/openvpn/multi.c
+++ b/src/openvpn/multi.c
@@ -555,8 +555,7 @@ setenv_stats(struct context *c)
}
static void
-multi_client_disconnect_setenv(struct multi_context *m,
- struct multi_instance *mi)
+multi_client_disconnect_setenv(struct multi_instance *mi)
{
/* setenv client real IP address */
setenv_trusted(mi->context.c2.es, get_link_socket_info(&mi->context));
@@ -572,13 +571,12 @@ multi_client_disconnect_setenv(struct multi_context *m,
}
static void
-multi_client_disconnect_script(struct multi_context *m,
- struct multi_instance *mi)
+multi_client_disconnect_script(struct multi_instance *mi)
{
if ((mi->context.c2.context_auth == CAS_SUCCEEDED && mi->connection_established_flag)
|| mi->context.c2.context_auth == CAS_PARTIAL)
{
- multi_client_disconnect_setenv(m, mi);
+ multi_client_disconnect_setenv(mi);
if (plugin_defined(mi->context.plugins, OPENVPN_PLUGIN_CLIENT_DISCONNECT))
{
@@ -685,7 +683,7 @@ multi_close_instance(struct multi_context *m,
set_cc_config(mi, NULL);
#endif
- multi_client_disconnect_script(m, mi);
+ multi_client_disconnect_script(mi);
if (mi->did_open_context)
{
@@ -1112,7 +1110,7 @@ multi_learn_addr(struct multi_context *m,
if (oldroute) /* route already exists? */
{
- if (route_quota_test(m, mi) && learn_address_script(m, mi, "update", &newroute->addr))
+ if (route_quota_test(mi) && learn_address_script(m, mi, "update", &newroute->addr))
{
learn_succeeded = true;
owner = mi;
@@ -1129,7 +1127,7 @@ multi_learn_addr(struct multi_context *m,
}
else
{
- if (route_quota_test(m, mi) && learn_address_script(m, mi, "add", &newroute->addr))
+ if (route_quota_test(mi) && learn_address_script(m, mi, "add", &newroute->addr))
{
learn_succeeded = true;
owner = mi;
@@ -1579,7 +1577,7 @@ multi_select_virtual_addr(struct multi_context *m, struct multi_instance *mi)
* Set virtual address environmental variables.
*/
static void
-multi_set_virtual_addr_env(struct multi_context *m, struct multi_instance *mi)
+multi_set_virtual_addr_env(struct multi_instance *mi)
{
setenv_del(mi->context.c2.es, "ifconfig_pool_local_ip");
setenv_del(mi->context.c2.es, "ifconfig_pool_remote_ip");
@@ -1658,7 +1656,7 @@ multi_client_connect_post(struct multi_context *m,
* directory or any --ifconfig-pool dynamic address.
*/
multi_select_virtual_addr(m, mi);
- multi_set_virtual_addr_env(m, mi);
+ multi_set_virtual_addr_env(mi);
}
}
@@ -1702,7 +1700,7 @@ multi_client_connect_post_plugin(struct multi_context *m,
* directory or any --ifconfig-pool dynamic address.
*/
multi_select_virtual_addr(m, mi);
- multi_set_virtual_addr_env(m, mi);
+ multi_set_virtual_addr_env(mi);
}
}
@@ -1742,7 +1740,7 @@ multi_client_connect_mda(struct multi_context *m,
* directory or any --ifconfig-pool dynamic address.
*/
multi_select_virtual_addr(m, mi);
- multi_set_virtual_addr_env(m, mi);
+ multi_set_virtual_addr_env(mi);
}
}
@@ -1761,7 +1759,7 @@ multi_client_connect_setenv(struct multi_context *m,
setenv_trusted(mi->context.c2.es, get_link_socket_info(&mi->context));
/* setenv client virtual IP address */
- multi_set_virtual_addr_env(m, mi);
+ multi_set_virtual_addr_env(mi);
/* setenv connection time */
{
@@ -2919,7 +2917,7 @@ multi_process_drop_outgoing_tun(struct multi_context *m, const unsigned int mpp_
*/
void
-route_quota_exceeded(const struct multi_context *m, const struct multi_instance *mi)
+route_quota_exceeded(const struct multi_instance *mi)
{
struct gc_arena gc = gc_new();
msg(D_ROUTE_QUOTA, "MULTI ROUTE: route quota (%d) exceeded for %s (see --max-routes-per-client option)",
@@ -3355,12 +3353,6 @@ init_management_callback_multi(struct multi_context *m)
#endif /* ifdef ENABLE_MANAGEMENT */
}
-void
-uninit_management_callback_multi(struct multi_context *m)
-{
- uninit_management_callback();
-}
-
/*
* Top level event loop.
*/
diff --git a/src/openvpn/multi.h b/src/openvpn/multi.h
index d7e5c29..ebcc22d 100644
--- a/src/openvpn/multi.h
+++ b/src/openvpn/multi.h
@@ -346,9 +346,6 @@ void multi_close_instance_on_signal(struct multi_context *m, struct multi_instan
void init_management_callback_multi(struct multi_context *m);
-void uninit_management_callback_multi(struct multi_context *m);
-
-
#ifdef ENABLE_ASYNC_PUSH
/**
* Called when inotify event is fired, which happens when acf file is closed or deleted.
@@ -403,7 +400,7 @@ multi_process_outgoing_link_pre(struct multi_context *m)
* Per-client route quota management
*/
-void route_quota_exceeded(const struct multi_context *m, const struct multi_instance *mi);
+void route_quota_exceeded(const struct multi_instance *mi);
static inline void
route_quota_inc(struct multi_instance *mi)
@@ -419,11 +416,11 @@ route_quota_dec(struct multi_instance *mi)
/* can we add a new route? */
static inline bool
-route_quota_test(const struct multi_context *m, const struct multi_instance *mi)
+route_quota_test(const struct multi_instance *mi)
{
if (mi->route_count >= mi->context.options.max_routes_per_client)
{
- route_quota_exceeded(m, mi);
+ route_quota_exceeded(mi);
return false;
}
else
diff --git a/src/openvpn/openssl_compat.h b/src/openvpn/openssl_compat.h
index e680702..8acc7d1 100644
--- a/src/openvpn/openssl_compat.h
+++ b/src/openvpn/openssl_compat.h
@@ -88,6 +88,18 @@ EVP_MD_CTX_new(void)
}
#endif
+#if !defined(HAVE_EVP_CIPHER_CTX_RESET)
+#define EVP_CIPHER_CTX_reset EVP_CIPHER_CTX_init
+#endif
+
+#if !defined(HAVE_X509_GET0_NOTBEFORE)
+#define X509_get0_notBefore X509_get_notBefore
+#endif
+
+#if !defined(HAVE_X509_GET0_NOTAFTER)
+#define X509_get0_notAfter X509_get_notAfter
+#endif
+
#if !defined(HAVE_HMAC_CTX_RESET)
/**
* Reset a HMAC context
diff --git a/src/openvpn/openvpn.c b/src/openvpn/openvpn.c
index 3819889..3d244fc 100644
--- a/src/openvpn/openvpn.c
+++ b/src/openvpn/openvpn.c
@@ -201,7 +201,7 @@ openvpn_main(int argc, char *argv[])
#ifdef ENABLE_MANAGEMENT
/* initialize management subsystem */
- init_management(&c);
+ init_management();
#endif
/* initialize options to default state */
diff --git a/src/openvpn/openvpn_win32_resources.rc b/src/openvpn/openvpn_win32_resources.rc
index d092e21..e4f1ee9 100644
--- a/src/openvpn/openvpn_win32_resources.rc
+++ b/src/openvpn/openvpn_win32_resources.rc
@@ -19,7 +19,7 @@ VS_VERSION_INFO VERSIONINFO
FILEFLAGS 0x0L
#endif
FILEOS 0x40004L
- FILETYPE 0x2L
+ FILETYPE VFT_APP
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
diff --git a/src/openvpn/options.c b/src/openvpn/options.c
index f951814..de30fcb 100644
--- a/src/openvpn/options.c
+++ b/src/openvpn/options.c
@@ -2228,7 +2228,7 @@ options_postprocess_verify_ce(const struct options *options, const struct connec
}
if (options->pull_filter_list)
{
- msg(M_USAGE, "--pull-filter cannot be used with --mode server");
+ msg(M_WARN, "--pull-filter ignored for --mode server");
}
if (!(proto_is_udp(ce->proto) || ce->proto == PROTO_TCP_SERVER))
{
@@ -2832,6 +2832,24 @@ options_postprocess_mutate_ce(struct options *o, struct connection_entry *ce)
#endif
}
+ /* our socks code is not fully IPv6 enabled yet (TCP works, UDP not)
+ * so fall back to IPv4-only (trac #1221)
+ */
+ if (ce->socks_proxy_server && proto_is_udp(ce->proto) && ce->af != AF_INET)
+ {
+ if (ce->af == AF_INET6)
+ {
+ msg(M_INFO, "WARNING: '--proto udp6' is not compatible with "
+ "'--socks-proxy' today. Forcing IPv4 mode." );
+ }
+ else
+ {
+ msg(M_INFO, "NOTICE: dual-stack mode for '--proto udp' does not "
+ "work correctly with '--socks-proxy' today. Forcing IPv4." );
+ }
+ ce->af = AF_INET;
+ }
+
/*
* Set MTU defaults
*/
diff --git a/src/openvpn/pkcs11.c b/src/openvpn/pkcs11.c
index 93f8580..d40ca45 100644
--- a/src/openvpn/pkcs11.c
+++ b/src/openvpn/pkcs11.c
@@ -312,7 +312,7 @@ pkcs11_initialize(
pkcs11h_setLogLevel(_pkcs11_msg_openvpn2pkcs11(get_debug_level()));
- if ((rv = pkcs11h_setForkMode(TRUE)) != CKR_OK)
+ if ((rv = pkcs11h_setForkMode(FALSE)) != CKR_OK)
{
msg(M_FATAL, "PKCS#11: Cannot set fork mode %ld-'%s'", rv, pkcs11h_getMessage(rv));
goto cleanup;
diff --git a/src/openvpn/proxy.c b/src/openvpn/proxy.c
index 3fdec86..afcca86 100644
--- a/src/openvpn/proxy.c
+++ b/src/openvpn/proxy.c
@@ -355,7 +355,7 @@ get_proxy_authenticate(socket_descriptor_t sd,
#if NTLM
else if (!strncmp(buf+20, "NTLM", 4))
{
- msg(D_PROXY, "PROXY AUTH HTLM: '%s'", buf);
+ msg(D_PROXY, "PROXY AUTH NTLM: '%s'", buf);
*data = NULL;
ret = HTTP_AUTH_NTLM;
}
diff --git a/src/openvpn/route.c b/src/openvpn/route.c
index 2d6428b..4199da3 100644
--- a/src/openvpn/route.c
+++ b/src/openvpn/route.c
@@ -2038,8 +2038,8 @@ add_route_ipv6(struct route_ipv6 *r6, const struct tuntap *tt, unsigned int flag
r6->netbits,
gateway );
- /* on tun/tap, not "elsewhere"? -> metric 0 */
- if (!r6->iface)
+ /* on tun (not tap), not "elsewhere"? -> metric 0 */
+ if (tt->type == DEV_TYPE_TUN && !r6->iface)
{
argv_printf_cat(&argv, "0");
}
diff --git a/src/openvpn/socket.c b/src/openvpn/socket.c
index c76d206..9131ec2 100644
--- a/src/openvpn/socket.c
+++ b/src/openvpn/socket.c
@@ -1170,7 +1170,7 @@ socket_do_listen(socket_descriptor_t sd,
ASSERT(local);
msg(M_INFO, "Listening for incoming TCP connection on %s",
print_sockaddr(local->ai_addr, &gc));
- if (listen(sd, 1))
+ if (listen(sd, 32))
{
msg(M_ERR, "TCP: listen() failed");
}
diff --git a/src/openvpn/socks.c b/src/openvpn/socks.c
index c61ef55..ad3a70b 100644
--- a/src/openvpn/socks.c
+++ b/src/openvpn/socks.c
@@ -414,6 +414,10 @@ recv_socks_reply(socket_descriptor_t sd,
{
memcpy(&addr->addr.in4.sin_addr, buf + 4, sizeof(addr->addr.in4.sin_addr));
memcpy(&addr->addr.in4.sin_port, buf + 8, sizeof(addr->addr.in4.sin_port));
+ struct gc_arena gc = gc_new();
+ msg(M_INFO, "SOCKS proxy wants us to send UDP to %s",
+ print_sockaddr(addr, &gc));
+ gc_free(&gc);
}
diff --git a/src/openvpn/ssl_openssl.c b/src/openvpn/ssl_openssl.c
index a78dae9..6aa3ac3 100644
--- a/src/openvpn/ssl_openssl.c
+++ b/src/openvpn/ssl_openssl.c
@@ -71,12 +71,13 @@ int mydata_index; /* GLOBAL */
void
tls_init_lib(void)
{
+#if (OPENSSL_VERSION_NUMBER < 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER))
SSL_library_init();
#ifndef ENABLE_SMALL
SSL_load_error_strings();
#endif
OpenSSL_add_all_algorithms();
-
+#endif
mydata_index = SSL_get_ex_new_index(0, "struct session *", NULL, NULL, NULL);
ASSERT(mydata_index >= 0);
}
@@ -84,10 +85,12 @@ tls_init_lib(void)
void
tls_free_lib(void)
{
+#if (OPENSSL_VERSION_NUMBER < 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER))
EVP_cleanup();
#ifndef ENABLE_SMALL
ERR_free_strings();
#endif
+#endif
}
void
@@ -206,7 +209,7 @@ info_callback(INFO_CALLBACK_SSL_CONST SSL *s, int where, int ret)
int
tls_version_max(void)
{
-#if defined(TLS1_3_VERSION)
+#if defined(TLS1_3_VERSION) && !defined(OPENSSL_NO_TLS1_3)
return TLS_VER_1_3;
#elif defined(TLS1_2_VERSION) || defined(SSL_OP_NO_TLSv1_2)
return TLS_VER_1_2;
@@ -233,7 +236,7 @@ openssl_tls_version(int ver)
{
return TLS1_2_VERSION;
}
-#if defined(TLS1_3_VERSION)
+#if defined(TLS1_3_VERSION) && !defined(OPENSSL_NO_TLS1_3)
else if (ver == TLS_VER_1_3)
{
return TLS1_3_VERSION;
@@ -459,8 +462,8 @@ tls_ctx_restrict_ciphers_tls13(struct tls_root_ctx *ctx, const char *ciphers)
return;
}
-#if (OPENSSL_VERSION_NUMBER < 0x1010100fL)
- crypto_msg(M_WARN, "Not compiled with OpenSSL 1.1.1 or higher. "
+#if (OPENSSL_VERSION_NUMBER < 0x1010100fL) || !defined(TLS1_3_VERSION) || defined(OPENSSL_NO_TLS1_3)
+ crypto_msg(M_WARN, "Not compiled with OpenSSL 1.1.1 or higher, or without TLS 1.3 support. "
"Ignoring TLS 1.3 only tls-ciphersuites '%s' setting.",
ciphers);
#else
@@ -534,7 +537,7 @@ tls_ctx_check_cert_time(const struct tls_root_ctx *ctx)
goto cleanup; /* Nothing to check if there is no certificate */
}
- ret = X509_cmp_time(X509_get_notBefore(cert), NULL);
+ ret = X509_cmp_time(X509_get0_notBefore(cert), NULL);
if (ret == 0)
{
msg(D_TLS_DEBUG_MED, "Failed to read certificate notBefore field.");
@@ -544,7 +547,7 @@ tls_ctx_check_cert_time(const struct tls_root_ctx *ctx)
msg(M_WARN, "WARNING: Your certificate is not yet valid!");
}
- ret = X509_cmp_time(X509_get_notAfter(cert), NULL);
+ ret = X509_cmp_time(X509_get0_notAfter(cert), NULL);
if (ret == 0)
{
msg(D_TLS_DEBUG_MED, "Failed to read certificate notAfter field.");
@@ -626,10 +629,13 @@ tls_ctx_load_ecdh_params(struct tls_root_ctx *ctx, const char *curve_name
else
{
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
+#if (OPENSSL_VERSION_NUMBER < 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER))
+
/* OpenSSL 1.0.2 and newer can automatically handle ECDH parameter
* loading */
SSL_CTX_set_ecdh_auto(ctx->ctx, 1);
return;
+#endif
#else
/* For older OpenSSL we have to extract the curve from key on our own */
EC_KEY *eckey = NULL;
@@ -1846,7 +1852,7 @@ show_available_tls_ciphers_list(const char *cipher_list,
crypto_msg(M_FATAL, "Cannot create SSL_CTX object");
}
-#if (OPENSSL_VERSION_NUMBER >= 0x1010100fL)
+#if (OPENSSL_VERSION_NUMBER >= 0x1010100fL) && defined(TLS1_3_VERSION) && !defined(OPENSSL_NO_TLS1_3)
if (tls13)
{
SSL_CTX_set_min_proto_version(tls_ctx.ctx, TLS1_3_VERSION);
diff --git a/src/openvpn/tun.c b/src/openvpn/tun.c
index 63f9d1b..80eaa2c 100644
--- a/src/openvpn/tun.c
+++ b/src/openvpn/tun.c
@@ -5044,7 +5044,6 @@ void
ipconfig_register_dns(const struct env_set *es)
{
struct argv argv = argv_new();
- bool status;
const char err[] = "ERROR: Windows ipconfig command failed";
msg(D_TUNTAP_INFO, "Start ipconfig commands for register-dns...");
@@ -5054,14 +5053,14 @@ ipconfig_register_dns(const struct env_set *es)
get_win_sys_path(),
WIN_IPCONFIG_PATH_SUFFIX);
argv_msg(D_TUNTAP_INFO, &argv);
- status = openvpn_execve_check(&argv, es, 0, err);
+ openvpn_execve_check(&argv, es, 0, err);
argv_reset(&argv);
argv_printf(&argv, "%s%sc /registerdns",
get_win_sys_path(),
WIN_IPCONFIG_PATH_SUFFIX);
argv_msg(D_TUNTAP_INFO, &argv);
- status = openvpn_execve_check(&argv, es, 0, err);
+ openvpn_execve_check(&argv, es, 0, err);
argv_reset(&argv);
netcmd_semaphore_release();
@@ -5355,8 +5354,7 @@ netsh_ifconfig(const struct tuntap_options *to,
}
static void
-netsh_enable_dhcp(const struct tuntap_options *to,
- const char *actual_name)
+netsh_enable_dhcp(const char *actual_name)
{
struct argv argv = argv_new();
@@ -5902,7 +5900,7 @@ open_tun(const char *dev, const char *dev_type, const char *dev_node, struct tun
}
else
{
- netsh_enable_dhcp(&tt->options, tt->actual_name);
+ netsh_enable_dhcp(tt->actual_name);
}
}
dhcp_masq = true;
diff --git a/src/openvpn/tun.h b/src/openvpn/tun.h
index 6c57ad0..54e1dfa 100644
--- a/src/openvpn/tun.h
+++ b/src/openvpn/tun.h
@@ -452,7 +452,7 @@ tun_write_win32(struct tuntap *tt, struct buffer *buf)
}
static inline int
-read_tun_buffered(struct tuntap *tt, struct buffer *buf, int maxsize)
+read_tun_buffered(struct tuntap *tt, struct buffer *buf)
{
return tun_finalize(tt->hand, &tt->reads, buf);
}
diff --git a/src/openvpn/win32.c b/src/openvpn/win32.c
index 29bbb84..f13807f 100644
--- a/src/openvpn/win32.c
+++ b/src/openvpn/win32.c
@@ -685,11 +685,10 @@ win32_pause(struct win32_signal *ws)
{
if (ws->mode == WSO_MODE_CONSOLE && HANDLE_DEFINED(ws->in.read))
{
- int status;
msg(M_INFO|M_NOPREFIX, "Press any key to continue...");
do
{
- status = WaitForSingleObject(ws->in.read, INFINITE);
+ WaitForSingleObject(ws->in.read, INFINITE);
} while (!win32_keyboard_get(ws));
}
}
@@ -1088,7 +1087,7 @@ wide_cmd_line(const struct argv *a, struct gc_arena *gc)
int
openvpn_execve(const struct argv *a, const struct env_set *es, const unsigned int flags)
{
- int ret = -1;
+ int ret = OPENVPN_EXECVE_ERROR;
static bool exec_warn = false;
if (a && a->argv[0])
@@ -1137,10 +1136,14 @@ openvpn_execve(const struct argv *a, const struct env_set *es, const unsigned in
free(env);
gc_free(&gc);
}
- else if (!exec_warn && (script_security < SSEC_SCRIPTS))
+ else
{
- msg(M_WARN, SCRIPT_SECURITY_WARNING);
- exec_warn = true;
+ ret = OPENVPN_EXECVE_NOT_ALLOWED;
+ if (!exec_warn && (script_security < SSEC_SCRIPTS))
+ {
+ msg(M_WARN, SCRIPT_SECURITY_WARNING);
+ exec_warn = true;
+ }
}
}
else