diff options
author | Alberto Gonzalez Iniesta <agi@inittab.org> | 2016-05-10 17:40:25 +0200 |
---|---|---|
committer | Alberto Gonzalez Iniesta <agi@inittab.org> | 2016-05-10 17:40:25 +0200 |
commit | ffca24bed7a03d95585ad02278667abe75d8b272 (patch) | |
tree | 336f336401e5166e1009e24a6c8d40b97a97af89 /src/openvpn | |
parent | 9653b1bffea4e96c1eb7c1814e8bed21fea62321 (diff) |
Imported Upstream version 2.3.11upstream/2.3.11
Diffstat (limited to 'src/openvpn')
-rw-r--r-- | src/openvpn/Makefile.in | 27 | ||||
-rw-r--r-- | src/openvpn/console.c | 5 | ||||
-rw-r--r-- | src/openvpn/crypto_openssl.c | 51 | ||||
-rw-r--r-- | src/openvpn/crypto_openssl.h | 25 | ||||
-rw-r--r-- | src/openvpn/crypto_polarssl.c | 60 | ||||
-rw-r--r-- | src/openvpn/crypto_polarssl.h | 49 | ||||
-rw-r--r-- | src/openvpn/error.c | 31 | ||||
-rw-r--r-- | src/openvpn/error.h | 28 | ||||
-rw-r--r-- | src/openvpn/event.c | 8 | ||||
-rw-r--r-- | src/openvpn/fdmisc.h | 16 | ||||
-rw-r--r-- | src/openvpn/misc.c | 37 | ||||
-rw-r--r-- | src/openvpn/plugin.c | 2 | ||||
-rw-r--r-- | src/openvpn/proxy.c | 2 | ||||
-rw-r--r-- | src/openvpn/push.c | 5 | ||||
-rw-r--r-- | src/openvpn/route.c | 9 | ||||
-rw-r--r-- | src/openvpn/socket.c | 16 | ||||
-rw-r--r-- | src/openvpn/socks.c | 15 | ||||
-rw-r--r-- | src/openvpn/ssl.c | 5 | ||||
-rw-r--r-- | src/openvpn/ssl_openssl.c | 132 | ||||
-rw-r--r-- | src/openvpn/ssl_polarssl.c | 72 | ||||
-rw-r--r-- | src/openvpn/ssl_verify_polarssl.c | 26 | ||||
-rw-r--r-- | src/openvpn/tun.c | 4 | ||||
-rw-r--r-- | src/openvpn/win32.c | 51 |
23 files changed, 439 insertions, 237 deletions
diff --git a/src/openvpn/Makefile.in b/src/openvpn/Makefile.in index 8519969..3691c96 100644 --- a/src/openvpn/Makefile.in +++ b/src/openvpn/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.14.1 from Makefile.am. +# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2013 Free Software Foundation, Inc. +# Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -37,7 +37,17 @@ # Required to build Windows resource file VPATH = @srcdir@ -am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ @@ -100,8 +110,6 @@ PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ -DIST_COMMON = $(top_srcdir)/build/ltrc.inc $(srcdir)/Makefile.in \ - $(srcdir)/Makefile.am $(top_srcdir)/depcomp # we want unicode entry point but not the macro @WIN32_TRUE@am__append_1 = -municode -UUNICODE sbin_PROGRAMS = openvpn$(EXEEXT) @@ -118,6 +126,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_emptyarray.m4 \ $(top_srcdir)/compat.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = @@ -246,6 +255,8 @@ am__define_uniq_tagged_files = \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/build/ltrc.inc \ + $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ @@ -293,6 +304,7 @@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LZO_CFLAGS = @LZO_CFLAGS@ LZO_LIBS = @LZO_LIBS@ MAKEINFO = @MAKEINFO@ @@ -475,7 +487,6 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(top_srcdir)/build/ltrc.inc $(am_ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/openvpn/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign src/openvpn/Makefile -.PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ @@ -484,7 +495,7 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; -$(top_srcdir)/build/ltrc.inc: +$(top_srcdir)/build/ltrc.inc $(am__empty): $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh @@ -857,6 +868,8 @@ uninstall-am: uninstall-sbinPROGRAMS mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am uninstall-sbinPROGRAMS +.PRECIOUS: Makefile + .rc.lo: $(LTRCCOMPILE) -i "$<" -o "$@" diff --git a/src/openvpn/console.c b/src/openvpn/console.c index e1d46c4..86331a1 100644 --- a/src/openvpn/console.c +++ b/src/openvpn/console.c @@ -172,8 +172,9 @@ get_console_input_systemd (const char *prompt, const bool echo, char *input, con if ((std_out = openvpn_popen (&argv, NULL)) < 0) { return false; } - CLEAR (*input); - if (read (std_out, input, capacity) != 0) + + memset (input, 0, capacity); + if (read (std_out, input, capacity-1) > 0) { chomp (input); ret = true; diff --git a/src/openvpn/crypto_openssl.c b/src/openvpn/crypto_openssl.c index 4e195ce..c147245 100644 --- a/src/openvpn/crypto_openssl.c +++ b/src/openvpn/crypto_openssl.c @@ -135,13 +135,15 @@ setup_engine (const char *engine) if ((e = ENGINE_by_id (engine)) == NULL && (e = try_load_engine (engine)) == NULL) { - msg (M_FATAL, "OpenSSL error: cannot load engine '%s'", engine); + crypto_msg (M_FATAL, "OpenSSL error: cannot load engine '%s'", + engine); } if (!ENGINE_set_default (e, ENGINE_METHOD_ALL)) { - msg (M_FATAL, "OpenSSL error: ENGINE_set_default failed on engine '%s'", - engine); + crypto_msg (M_FATAL, + "OpenSSL error: ENGINE_set_default failed on engine '%s'", + engine); } msg (M_INFO, "Initializing OpenSSL support for engine '%s'", @@ -230,6 +232,14 @@ crypto_clear_error (void) ERR_clear_error (); } +void +crypto_print_openssl_errors(const unsigned int flags) { + size_t err = 0; + + while ((err = ERR_get_error ())) + msg (flags, "OpenSSL: %s", ERR_error_string (err, NULL)); +} + /* * * OpenSSL memory debugging. If dmalloc debugging is enabled, tell @@ -380,7 +390,7 @@ int rand_bytes(uint8_t *output, int len) { if (unlikely(1 != RAND_bytes (output, len))) { - msg(D_CRYPT_ERRORS, "RAND_bytes() failed"); + crypto_msg(D_CRYPT_ERRORS, "RAND_bytes() failed"); return 0; } return 1; @@ -426,17 +436,20 @@ key_des_check (uint8_t *key, int key_len, int ndc) DES_cblock *dc = (DES_cblock*) buf_read_alloc (&b, sizeof (DES_cblock)); if (!dc) { - msg (D_CRYPT_ERRORS, "CRYPTO INFO: check_key_DES: insufficient key material"); + crypto_msg (D_CRYPT_ERRORS, + "CRYPTO INFO: check_key_DES: insufficient key material"); goto err; } if (DES_is_weak_key(dc)) { - msg (D_CRYPT_ERRORS, "CRYPTO INFO: check_key_DES: weak key detected"); + crypto_msg (D_CRYPT_ERRORS, + "CRYPTO INFO: check_key_DES: weak key detected"); goto err; } if (!DES_check_key_parity (dc)) { - msg (D_CRYPT_ERRORS, "CRYPTO INFO: check_key_DES: bad parity detected"); + crypto_msg (D_CRYPT_ERRORS, + "CRYPTO INFO: check_key_DES: bad parity detected"); goto err; } } @@ -485,7 +498,7 @@ cipher_kt_get (const char *ciphername) cipher = EVP_get_cipherbyname (ciphername); if (NULL == cipher) - msg (M_SSLERR, "Cipher algorithm '%s' not found", ciphername); + crypto_msg (M_FATAL, "Cipher algorithm '%s' not found", ciphername); if (EVP_CIPHER_key_length (cipher) > MAX_CIPHER_KEY_LENGTH) msg (M_FATAL, "Cipher algorithm '%s' uses a default key size (%d bytes) which is larger than " PACKAGE_NAME "'s current maximum key size (%d bytes)", @@ -569,13 +582,13 @@ cipher_ctx_init (EVP_CIPHER_CTX *ctx, uint8_t *key, int key_len, EVP_CIPHER_CTX_init (ctx); if (!EVP_CipherInit (ctx, kt, NULL, NULL, enc)) - msg (M_SSLERR, "EVP cipher init #1"); + crypto_msg (M_FATAL, "EVP cipher init #1"); #ifdef HAVE_EVP_CIPHER_CTX_SET_KEY_LENGTH if (!EVP_CIPHER_CTX_set_key_length (ctx, key_len)) - msg (M_SSLERR, "EVP set key size"); + crypto_msg (M_FATAL, "EVP set key size"); #endif if (!EVP_CipherInit (ctx, NULL, key, NULL, enc)) - msg (M_SSLERR, "EVP cipher init #2"); + crypto_msg (M_FATAL, "EVP cipher init #2"); /* make sure we used a big enough key */ ASSERT (EVP_CIPHER_CTX_key_length (ctx) <= key_len); @@ -622,7 +635,9 @@ int cipher_ctx_update (EVP_CIPHER_CTX *ctx, uint8_t *dst, int *dst_len, uint8_t *src, int src_len) { - return EVP_CipherUpdate (ctx, dst, dst_len, src, src_len); + if (!EVP_CipherUpdate (ctx, dst, dst_len, src, src_len)) + crypto_msg(M_FATAL, "%s: EVP_CipherUpdate() failed", __func__); + return 1; } int @@ -657,12 +672,14 @@ md_kt_get (const char *digest) ASSERT (digest); md = EVP_get_digestbyname (digest); if (!md) - msg (M_SSLERR, "Message hash algorithm '%s' not found", digest); + crypto_msg (M_FATAL, "Message hash algorithm '%s' not found", digest); if (EVP_MD_size (md) > MAX_HMAC_KEY_LENGTH) - msg (M_FATAL, "Message hash algorithm '%s' uses a default hash size (%d bytes) which is larger than " PACKAGE_NAME "'s current maximum hash size (%d bytes)", - digest, - EVP_MD_size (md), - MAX_HMAC_KEY_LENGTH); + { + crypto_msg (M_FATAL, "Message hash algorithm '%s' uses a default hash " + "size (%d bytes) which is larger than " PACKAGE_NAME "'s current " + "maximum hash size (%d bytes)", + digest, EVP_MD_size (md), MAX_HMAC_KEY_LENGTH); + } return md; } diff --git a/src/openvpn/crypto_openssl.h b/src/openvpn/crypto_openssl.h index f883c2a..42c7e9a 100644 --- a/src/openvpn/crypto_openssl.h +++ b/src/openvpn/crypto_openssl.h @@ -70,4 +70,29 @@ typedef HMAC_CTX hmac_ctx_t; #define DES_KEY_LENGTH 8 #define MD4_DIGEST_LENGTH 16 +/** + * Retrieve any occurred OpenSSL errors and print those errors. + * + * Note that this function uses the not thread-safe OpenSSL error API. + * + * @param flags Flags to indicate error type and priority. + */ +void crypto_print_openssl_errors(const unsigned int flags); + +/** + * Retrieve any OpenSSL errors, then print the supplied error message. + * + * This is just a convenience wrapper for often occurring situations. + * + * @param flags Flags to indicate error type and priority. + * @param format Format string to print. + * @param format args (optional) arguments for the format string. + */ +# define crypto_msg(flags, ...) \ +do { \ + crypto_print_openssl_errors(nonfatal(flags)); \ + msg((flags), __VA_ARGS__); \ +} while (false) + + #endif /* CRYPTO_OPENSSL_H_ */ diff --git a/src/openvpn/crypto_polarssl.c b/src/openvpn/crypto_polarssl.c index 24712ed..92fdb78 100644 --- a/src/openvpn/crypto_polarssl.c +++ b/src/openvpn/crypto_polarssl.c @@ -46,6 +46,7 @@ #include "misc.h" #include <polarssl/des.h> +#include <polarssl/error.h> #include <polarssl/md5.h> #include <polarssl/cipher.h> #include <polarssl/havege.h> @@ -86,6 +87,32 @@ crypto_clear_error (void) { } +bool polar_log_err(unsigned int flags, int errval, const char *prefix) +{ + if (0 != errval) + { + char errstr[256]; + polarssl_strerror(errval, errstr, sizeof(errstr)); + + if (NULL == prefix) prefix = "PolarSSL error"; + msg (flags, "%s: %s", prefix, errstr); + } + + return 0 == errval; +} + +bool polar_log_func_line(unsigned int flags, int errval, const char *func, + int line) +{ + char prefix[256]; + + if (!openvpn_snprintf(prefix, sizeof(prefix), "%s:%d", func, line)) + return polar_log_err(flags, errval, func); + + return polar_log_err(flags, errval, prefix); +} + + #ifdef DMALLOC void crypto_init_dmalloc (void) @@ -234,7 +261,8 @@ ctr_drbg_context * rand_ctx_get() /* Initialise PolarSSL RNG, and built-in entropy sources */ entropy_init(&ec); - if (0 != ctr_drbg_init(&cd_ctx, entropy_func, &ec, BPTR(&pers_string), BLEN(&pers_string))) + if (!polar_ok(ctr_drbg_init(&cd_ctx, entropy_func, &ec, + BPTR(&pers_string), BLEN(&pers_string)))) msg (M_FATAL, "Failed to initialize random generator"); gc_free(&gc); @@ -445,10 +473,10 @@ cipher_ctx_init (cipher_context_t *ctx, uint8_t *key, int key_len, CLEAR (*ctx); - if (0 != cipher_init_ctx(ctx, kt)) + if (!polar_ok(cipher_init_ctx(ctx, kt))) msg (M_FATAL, "PolarSSL cipher context init #1"); - if (0 != cipher_setkey(ctx, key, key_len*8, enc)) + if (!polar_ok(cipher_setkey(ctx, key, key_len*8, enc))) msg (M_FATAL, "PolarSSL cipher set key"); /* make sure we used a big enough key */ @@ -487,36 +515,38 @@ cipher_ctx_get_cipher_kt (const cipher_ctx_t *ctx) int cipher_ctx_reset (cipher_context_t *ctx, uint8_t *iv_buf) { - int retval = cipher_reset(ctx); + if (!polar_ok(cipher_reset(ctx))) + return 0; - if (0 == retval) - retval = cipher_set_iv(ctx, iv_buf, ctx->cipher_info->iv_size); + if (!polar_ok(cipher_set_iv(ctx, iv_buf, ctx->cipher_info->iv_size))) + return 0; - return 0 == retval; + return 1; } int cipher_ctx_update (cipher_context_t *ctx, uint8_t *dst, int *dst_len, uint8_t *src, int src_len) { - int retval = 0; size_t s_dst_len = *dst_len; - retval = cipher_update(ctx, src, (size_t)src_len, dst, &s_dst_len); + if (!polar_ok(cipher_update(ctx, src, (size_t)src_len, dst, &s_dst_len))) + return 0; *dst_len = s_dst_len; - return 0 == retval; + return 1; } int cipher_ctx_final (cipher_context_t *ctx, uint8_t *dst, int *dst_len) { - int retval = 0; size_t s_dst_len = *dst_len; - retval = cipher_finish(ctx, dst, &s_dst_len); + if (!polar_ok(cipher_finish(ctx, dst, &s_dst_len))) + return 0; + *dst_len = s_dst_len; - return 0 == retval; + return 1; } void @@ -526,8 +556,8 @@ cipher_des_encrypt_ecb (const unsigned char key[DES_KEY_LENGTH], { des_context ctx; - des_setkey_enc(&ctx, key); - des_crypt_ecb(&ctx, src, dst); + ASSERT (polar_ok(des_setkey_enc(&ctx, key))); + ASSERT (polar_ok(des_crypt_ecb(&ctx, src, dst))); } diff --git a/src/openvpn/crypto_polarssl.h b/src/openvpn/crypto_polarssl.h index b6da436..12b5146 100644 --- a/src/openvpn/crypto_polarssl.h +++ b/src/openvpn/crypto_polarssl.h @@ -91,4 +91,53 @@ ctr_drbg_context * rand_ctx_get(); void rand_ctx_enable_prediction_resistance(); #endif +/** + * Log the supplied PolarSSL error, prefixed by supplied prefix. + * + * @param flags Flags to indicate error type and priority. + * @param errval PolarSSL error code to convert to error message. + * @param prefix Prefix to PolarSSL error message. + * + * @returns true if no errors are detected, false otherwise. + */ +bool polar_log_err(unsigned int flags, int errval, const char *prefix); + +/** + * Log the supplied PolarSSL error, prefixed by function name and line number. + * + * @param flags Flags to indicate error type and priority. + * @param errval PolarSSL error code to convert to error message. + * @param func Function name where error was reported. + * @param line Line number where error was reported. + * + * @returns true if no errors are detected, false otherwise. + */ +bool polar_log_func_line(unsigned int flags, int errval, const char *func, + int line); + +/** Wraps polar_log_func_line() to prevent function calls for non-errors */ +static inline bool polar_log_func_line_lite(unsigned int flags, int errval, + const char *func, int line) { + if (errval) { + return polar_log_func_line (flags, errval, func, line); + } + return true; +} + +/** + * Check errval and log on error. + * + * Convenience wrapper to put around polarssl library calls, e.g. + * if (!polar_ok(polarssl_func())) return 0; + * or + * ASSERT (polar_ok(polarssl_func())); + * + * @param errval PolarSSL error code to convert to error message. + * + * @returns true if no errors are detected, false otherwise. + */ +#define polar_ok(errval) \ + polar_log_func_line_lite (D_CRYPT_ERRORS, errval, __func__, __LINE__) + + #endif /* CRYPTO_POLARSSL_H_ */ diff --git a/src/openvpn/error.c b/src/openvpn/error.c index f503cf4..6ccdeae 100644 --- a/src/openvpn/error.c +++ b/src/openvpn/error.c @@ -43,13 +43,6 @@ #include "ps.h" #include "mstats.h" -#ifdef ENABLE_CRYPTO -#ifdef ENABLE_CRYPTO_OPENSSL -#include <openssl/err.h> -#endif -#endif - -#include "memdbg.h" #if SYSLOG_CAPABILITY #ifndef LOG_OPENVPN @@ -224,7 +217,7 @@ void x_msg_va (const unsigned int flags, const char *format, va_list arglist) #ifndef HAVE_VARARG_MACROS /* the macro has checked this otherwise */ - if (!MSG_TEST (flags)) + if (!msg_test (flags)) return; #endif @@ -254,28 +247,6 @@ void x_msg_va (const unsigned int flags, const char *format, va_list arglist) SWAP; } -#ifdef ENABLE_CRYPTO -#ifdef ENABLE_CRYPTO_OPENSSL - if (flags & M_SSL) - { - int nerrs = 0; - int err; - while ((err = ERR_get_error ())) - { - openvpn_snprintf (m2, ERR_BUF_SIZE, "%s: %s", - m1, ERR_error_string (err, NULL)); - SWAP; - ++nerrs; - } - if (!nerrs) - { - openvpn_snprintf (m2, ERR_BUF_SIZE, "%s (OpenSSL)", m1); - SWAP; - } - } -#endif -#endif - if (flags & M_OPTERR) { openvpn_snprintf (m2, ERR_BUF_SIZE, "Options error: %s", m1); diff --git a/src/openvpn/error.h b/src/openvpn/error.h index 42308e8..4024e5e 100644 --- a/src/openvpn/error.h +++ b/src/openvpn/error.h @@ -93,10 +93,6 @@ extern int x_msg_line_num; #define M_ERRNO (1<<8) /* show errno description */ -#ifdef ENABLE_CRYPTO_OPENSSL -# define M_SSL (1<<10) /* show SSL error */ -#endif - #define M_NOMUTE (1<<11) /* don't do mute processing */ #define M_NOPREFIX (1<<12) /* don't show date/time prefix */ #define M_USAGE_SMALL (1<<13) /* fatal options error, call usage_small */ @@ -107,7 +103,6 @@ extern int x_msg_line_num; /* flag combinations which are frequently used */ #define M_ERR (M_FATAL | M_ERRNO) -#define M_SSLERR (M_FATAL | M_SSL) #define M_USAGE (M_USAGE_SMALL | M_NOPREFIX | M_OPTERR) #define M_CLIENT (M_MSG_VIRT_OUT | M_NOMUTE | M_NOIPREFIX) @@ -140,26 +135,31 @@ extern int x_msg_line_num; * msg() as a macro for optimization win. */ -bool dont_mute (unsigned int flags); /* check muting filter */ +/** Check muting filter */ +bool dont_mute (unsigned int flags); -#define MSG_TEST(flags) (unlikely((((unsigned int)flags) & M_DEBUG_LEVEL) <= x_debug_level) && dont_mute (flags)) +/** Return true if flags represent an enabled, not muted log level */ +static inline bool msg_test (unsigned int flags) +{ + return ((flags & M_DEBUG_LEVEL) <= x_debug_level) && dont_mute (flags); +} /* Macro to ensure (and teach static analysis tools) we exit on fatal errors */ #define EXIT_FATAL(flags) do { if ((flags) & M_FATAL) _exit(1); } while (false) #if defined(HAVE_CPP_VARARG_MACRO_ISO) && !defined(__LCLINT__) # define HAVE_VARARG_MACROS -# define msg(flags, ...) do { if (MSG_TEST(flags)) x_msg((flags), __VA_ARGS__); EXIT_FATAL(flags); } while (false) +# define msg(flags, ...) do { if (msg_test(flags)) x_msg((flags), __VA_ARGS__); EXIT_FATAL(flags); } while (false) # ifdef ENABLE_DEBUG -# define dmsg(flags, ...) do { if (MSG_TEST(flags)) x_msg((flags), __VA_ARGS__); EXIT_FATAL(flags); } while (false) +# define dmsg(flags, ...) do { if (msg_test(flags)) x_msg((flags), __VA_ARGS__); EXIT_FATAL(flags); } while (false) # else # define dmsg(flags, ...) # endif #elif defined(HAVE_CPP_VARARG_MACRO_GCC) && !defined(__LCLINT__) # define HAVE_VARARG_MACROS -# define msg(flags, args...) do { if (MSG_TEST(flags)) x_msg((flags), args); EXIT_FATAL(flags); } while (false) +# define msg(flags, args...) do { if (msg_test(flags)) x_msg((flags), args); EXIT_FATAL(flags); } while (false) # ifdef ENABLE_DEBUG -# define dmsg(flags, args...) do { if (MSG_TEST(flags)) x_msg((flags), args); EXIT_FATAL(flags); } while (false) +# define dmsg(flags, args...) do { if (msg_test(flags)) x_msg((flags), args); EXIT_FATAL(flags); } while (false) # else # define dmsg(flags, args...) # endif @@ -360,6 +360,12 @@ ignore_sys_error (const int err) return false; } +/** Convert fatal errors to nonfatal, don't touch other errors */ +static inline unsigned int +nonfatal(const unsigned int err) { + return err & M_FATAL ? (err ^ M_FATAL) | M_NONFATAL : err; +} + #include "errlevel.h" #endif diff --git a/src/openvpn/event.c b/src/openvpn/event.c index 34a3c45..c642691 100644 --- a/src/openvpn/event.c +++ b/src/openvpn/event.c @@ -873,18 +873,18 @@ se_ctl (struct event_set *es, event_t event, unsigned int rwflags, void *arg) if (ses->fast) { if (rwflags & EVENT_READ) - FD_SET (event, &ses->readfds); + openvpn_fd_set (event, &ses->readfds); if (rwflags & EVENT_WRITE) - FD_SET (event, &ses->writefds); + openvpn_fd_set (event, &ses->writefds); } else { if (rwflags & EVENT_READ) - FD_SET (event, &ses->readfds); + openvpn_fd_set (event, &ses->readfds); else FD_CLR (event, &ses->readfds); if (rwflags & EVENT_WRITE) - FD_SET (event, &ses->writefds); + openvpn_fd_set (event, &ses->writefds); else FD_CLR (event, &ses->writefds); } diff --git a/src/openvpn/fdmisc.h b/src/openvpn/fdmisc.h index 4b6b6d0..13d6552 100644 --- a/src/openvpn/fdmisc.h +++ b/src/openvpn/fdmisc.h @@ -22,10 +22,26 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#ifndef FD_MISC_H +#define FD_MISC_H + #include "basic.h" +#include "error.h" +#include "syshead.h" bool set_nonblock_action (int fd); bool set_cloexec_action (int fd); void set_nonblock (int fd); void set_cloexec (int fd); + +static inline void openvpn_fd_set(int fd, fd_set *setp) +{ +#ifndef WIN32 /* The Windows FD_SET() implementation does not overflow */ + ASSERT (fd >= 0 && fd < FD_SETSIZE); +#endif + FD_SET (fd, setp); +} +#undef FD_SET /* prevent direct use of FD_SET() */ + +#endif /* FD_MISC_H */ diff --git a/src/openvpn/misc.c b/src/openvpn/misc.c index 04a5b5f..48ca0d5 100644 --- a/src/openvpn/misc.c +++ b/src/openvpn/misc.c @@ -1044,6 +1044,7 @@ get_user_pass_cr (struct user_pass *up, bool from_authfile = (auth_file && !streq (auth_file, "stdin")); bool username_from_stdin = false; bool password_from_stdin = false; + bool response_from_stdin = true; if (flags & GET_USER_PASS_PREVIOUS_CREDS_FAILED) msg (M_WARN, "Note: previous '%s' credentials failed", prefix); @@ -1053,10 +1054,11 @@ get_user_pass_cr (struct user_pass *up, * Get username/password from management interface? */ if (management - && ((auth_file && streq (auth_file, "management")) || (!from_authfile && (flags & GET_USER_PASS_MANAGEMENT))) + && (!from_authfile && (flags & GET_USER_PASS_MANAGEMENT)) && management_query_user_pass_enabled (management)) { const char *sc = NULL; + response_from_stdin = false; if (flags & GET_USER_PASS_PREVIOUS_CREDS_FAILED) management_auth_failure (management, prefix, "previous auth credentials failed"); @@ -1090,7 +1092,10 @@ get_user_pass_cr (struct user_pass *up, if (!strlen (up->password)) strcpy (up->password, "ok"); } - else if (from_authfile) + /* + * Read from auth file unless this is a dynamic challenge request. + */ + else if (from_authfile && !(flags & GET_USER_PASS_DYNAMIC_CHALLENGE)) { /* * Try to get username/password from a file. @@ -1141,10 +1146,10 @@ get_user_pass_cr (struct user_pass *up, /* * Get username/password from standard input? */ - if (username_from_stdin || password_from_stdin) + if (username_from_stdin || password_from_stdin || response_from_stdin) { #ifdef ENABLE_CLIENT_CR - if (auth_challenge && (flags & GET_USER_PASS_DYNAMIC_CHALLENGE)) + if (auth_challenge && (flags & GET_USER_PASS_DYNAMIC_CHALLENGE) && response_from_stdin) { struct auth_challenge_info *ac = get_auth_challenge (auth_challenge, &gc); if (ac) @@ -1154,7 +1159,8 @@ get_user_pass_cr (struct user_pass *up, buf_set_write (&packed_resp, (uint8_t*)up->password, USER_PASS_LEN); msg (M_INFO|M_NOPREFIX, "CHALLENGE: %s", ac->challenge_text); - if (!get_console_input ("Response:", BOOL_CAST(ac->flags&CR_ECHO), response, USER_PASS_LEN)) + if (!get_console_input (ac->challenge_text, BOOL_CAST(ac->flags&CR_ECHO), + response, USER_PASS_LEN)) msg (M_FATAL, "ERROR: could not read challenge response from stdin"); strncpynt (up->username, ac->user, USER_PASS_LEN); buf_printf (&packed_resp, "CRV1::%s::%s", ac->state_id, response); @@ -1185,14 +1191,16 @@ get_user_pass_cr (struct user_pass *up, msg (M_FATAL, "ERROR: could not not read %s password from stdin", prefix); #ifdef ENABLE_CLIENT_CR - if (auth_challenge && (flags & GET_USER_PASS_STATIC_CHALLENGE)) + if (auth_challenge && (flags & GET_USER_PASS_STATIC_CHALLENGE) && response_from_stdin) { char *response = (char *) gc_malloc (USER_PASS_LEN, false, &gc); struct buffer packed_resp; char *pw64=NULL, *resp64=NULL; msg (M_INFO|M_NOPREFIX, "CHALLENGE: %s", auth_challenge); - if (!get_console_input ("Response:", BOOL_CAST(flags & GET_USER_PASS_STATIC_CHALLENGE_ECHO), response, USER_PASS_LEN)) + + if (!get_console_input (auth_challenge, BOOL_CAST(flags & GET_USER_PASS_STATIC_CHALLENGE_ECHO), + response, USER_PASS_LEN)) msg (M_FATAL, "ERROR: could not read static challenge response from stdin"); if (openvpn_base64_encode(up->password, strlen(up->password), &pw64) == -1 || openvpn_base64_encode(response, strlen(response), &resp64) == -1) @@ -1648,22 +1656,27 @@ argv_system_str_append (struct argv *a, const char *str, const bool enquote) static char * argv_extract_cmd_name (const char *path) { + char *ret = NULL; if (path) { char *path_cp = string_alloc(path, NULL); /* POSIX basename() implementaions may modify its arguments */ const char *bn = basename (path_cp); if (bn) { - char *ret = string_alloc (bn, NULL); - char *dot = strrchr (ret, '.'); + char *dot = NULL; + ret = string_alloc (bn, NULL); + dot = strrchr (ret, '.'); if (dot) *dot = '\0'; free(path_cp); - if (ret[0] != '\0') - return ret; + if (ret[0] == '\0') + { + free(ret); + ret = NULL; + } } } - return NULL; + return ret; } const char * diff --git a/src/openvpn/plugin.c b/src/openvpn/plugin.c index 54c5b52..4e5e6ce 100644 --- a/src/openvpn/plugin.c +++ b/src/openvpn/plugin.c @@ -316,7 +316,7 @@ plugin_vlog (openvpn_plugin_log_flags_t flags, const char *name, const char *for if (flags & PLOG_NOMUTE) msg_flags |= M_NOMUTE; - if (MSG_TEST (msg_flags)) + if (msg_test (msg_flags)) { struct gc_arena gc; char* msg_fmt; diff --git a/src/openvpn/proxy.c b/src/openvpn/proxy.c index 95d7153..89989d1 100644 --- a/src/openvpn/proxy.c +++ b/src/openvpn/proxy.c @@ -94,7 +94,7 @@ recv_line (socket_descriptor_t sd, } FD_ZERO (&reads); - FD_SET (sd, &reads); + openvpn_fd_set (sd, &reads); tv.tv_sec = timeout_sec; tv.tv_usec = 0; diff --git a/src/openvpn/push.c b/src/openvpn/push.c index e4f3984..71f39c1 100644 --- a/src/openvpn/push.c +++ b/src/openvpn/push.c @@ -74,8 +74,11 @@ receive_auth_failed (struct context *c, const struct buffer *buffer) if (buf_string_compare_advance (&buf, "AUTH_FAILED,") && BLEN (&buf)) reason = BSTR (&buf); management_auth_failure (management, UP_TYPE_AUTH, reason); - } else + } #endif + /* + * Save the dynamic-challenge text even when management is defined + */ { #ifdef ENABLE_CLIENT_CR struct buffer buf = *buffer; diff --git a/src/openvpn/route.c b/src/openvpn/route.c index f35bc85..827bd79 100644 --- a/src/openvpn/route.c +++ b/src/openvpn/route.c @@ -2639,7 +2639,8 @@ void get_default_gateway (struct route_gateway_info *rgi) { struct gc_arena gc = gc_new (); - int s, seq, l, pid, rtm_addrs, i; + int s, seq, l, pid, rtm_addrs; + unsigned int i; struct sockaddr so_dst, so_mask; char *cp = m_rtmsg.m_space; struct sockaddr *gate = NULL, *sa; @@ -2776,7 +2777,8 @@ get_default_gateway (struct route_gateway_info *rgi) struct gc_arena gc = gc_new (); struct rtmsg m_rtmsg; int sockfd = -1; - int seq, l, pid, rtm_addrs, i; + int seq, l, pid, rtm_addrs; + unsigned int i; struct sockaddr so_dst, so_mask; char *cp = m_rtmsg.m_space; struct sockaddr *gate = NULL, *ifp = NULL, *sa; @@ -2976,7 +2978,8 @@ void get_default_gateway (struct route_gateway_info *rgi) { struct gc_arena gc = gc_new (); - int s, seq, l, rtm_addrs, i; + int s, seq, l, rtm_addrs; + unsigned int i; pid_t pid; struct sockaddr so_dst, so_mask; char *cp = m_rtmsg.m_space; diff --git a/src/openvpn/socket.c b/src/openvpn/socket.c index 3e30c75..b7ac339 100644 --- a/src/openvpn/socket.c +++ b/src/openvpn/socket.c @@ -842,7 +842,7 @@ socket_listen_accept (socket_descriptor_t sd, struct timeval tv; FD_ZERO (&reads); - FD_SET (sd, &reads); + openvpn_fd_set (sd, &reads); tv.tv_sec = 0; tv.tv_usec = 0; @@ -934,16 +934,22 @@ openvpn_connect (socket_descriptor_t sd, { while (true) { +#if POLL + struct pollfd fds[1]; + fds[0].fd = sd; + fds[0].events = POLLOUT; + status = poll(fds, 1, 0); +#else fd_set writes; struct timeval tv; FD_ZERO (&writes); - FD_SET (sd, &writes); + openvpn_fd_set (sd, &writes); tv.tv_sec = 0; tv.tv_usec = 0; status = select (sd + 1, NULL, &writes, NULL, &tv); - +#endif if (signal_received) { get_signal (signal_received); @@ -962,7 +968,11 @@ openvpn_connect (socket_descriptor_t sd, { if (--connect_timeout < 0) { +#ifdef WIN32 + status = WSAETIMEDOUT; +#else status = ETIMEDOUT; +#endif break; } openvpn_sleep (1); diff --git a/src/openvpn/socks.c b/src/openvpn/socks.c index 2f051ec..57dc02a 100644 --- a/src/openvpn/socks.c +++ b/src/openvpn/socks.c @@ -105,10 +105,13 @@ socks_username_password_auth (struct socks_proxy_info *p, ssize_t size; creds.defined = 0; - get_user_pass (&creds, p->authfile, UP_TYPE_SOCKS, GET_USER_PASS_MANAGEMENT); + if (!get_user_pass (&creds, p->authfile, UP_TYPE_SOCKS, GET_USER_PASS_MANAGEMENT)) + { + msg (M_NONFATAL, "SOCKS failed to get username/password."); + return false; + } - if( !creds.username || (strlen(creds.username) > 255) - || !creds.password || (strlen(creds.password) > 255) ) { + if( (strlen(creds.username) > 255) || (strlen(creds.password) > 255) ) { msg (M_NONFATAL, "SOCKS username and/or password exceeds 255 characters. " "Authentication not possible."); @@ -133,7 +136,7 @@ socks_username_password_auth (struct socks_proxy_info *p, char c; FD_ZERO (&reads); - FD_SET (sd, &reads); + openvpn_fd_set (sd, &reads); tv.tv_sec = timeout_sec; tv.tv_usec = 0; @@ -212,7 +215,7 @@ socks_handshake (struct socks_proxy_info *p, char c; FD_ZERO (&reads); - FD_SET (sd, &reads); + openvpn_fd_set (sd, &reads); tv.tv_sec = timeout_sec; tv.tv_usec = 0; @@ -318,7 +321,7 @@ recv_socks_reply (socket_descriptor_t sd, char c; FD_ZERO (&reads); - FD_SET (sd, &reads); + openvpn_fd_set (sd, &reads); tv.tv_sec = timeout_sec; tv.tv_usec = 0; diff --git a/src/openvpn/ssl.c b/src/openvpn/ssl.c index 0679890..9e31c3c 100644 --- a/src/openvpn/ssl.c +++ b/src/openvpn/ssl.c @@ -561,10 +561,7 @@ init_ssl (const struct options *options, struct tls_root_ctx *new_ctx) tls_ctx_check_cert_time(new_ctx); /* Allowable ciphers */ - if (options->cipher_list) - { - tls_ctx_restrict_ciphers(new_ctx, options->cipher_list); - } + tls_ctx_restrict_ciphers(new_ctx, options->cipher_list); #ifdef ENABLE_CRYPTO_POLARSSL /* Personalise the random by mixing in the certificate */ diff --git a/src/openvpn/ssl_openssl.c b/src/openvpn/ssl_openssl.c index e595e1b..1dfbb23 100644 --- a/src/openvpn/ssl_openssl.c +++ b/src/openvpn/ssl_openssl.c @@ -111,7 +111,7 @@ tmp_rsa_cb (SSL * s, int is_export, int keylength) if(!bn || !BN_set_word(bn, RSA_F4) || !RSA_generate_key_ex(rsa_tmp, keylength, bn, NULL)) - msg(M_SSLERR, "Failed to generate temp RSA key"); + crypto_msg(M_FATAL, "Failed to generate temp RSA key"); if (bn) BN_free( bn ); } @@ -132,7 +132,7 @@ tls_ctx_server_new(struct tls_root_ctx *ctx, unsigned int ssl_flags) ctx->ctx = SSL_CTX_new (SSLv23_server_method ()); if (ctx->ctx == NULL) - msg (M_SSLERR, "SSL_CTX_new SSLv23_server_method"); + crypto_msg (M_FATAL, "SSL_CTX_new SSLv23_server_method"); SSL_CTX_set_tmp_rsa_callback (ctx->ctx, tmp_rsa_cb); } @@ -151,7 +151,7 @@ tls_ctx_client_new(struct tls_root_ctx *ctx, unsigned int ssl_flags) ctx->ctx = SSL_CTX_new (SSLv23_client_method ()); if (ctx->ctx == NULL) - msg (M_SSLERR, "SSL_CTX_new SSLv23_client_method"); + crypto_msg (M_FATAL, "SSL_CTX_new SSLv23_client_method"); } void @@ -267,6 +267,20 @@ tls_ctx_set_options (struct tls_root_ctx *ctx, unsigned int ssl_flags) void tls_ctx_restrict_ciphers(struct tls_root_ctx *ctx, const char *ciphers) { + if (ciphers == NULL) + { + /* Use sane default TLS cipher list */ + if(!SSL_CTX_set_cipher_list(ctx->ctx, + /* Use openssl's default list as a basis */ + "DEFAULT" + /* Disable export ciphers and openssl's 'low' and 'medium' ciphers */ + ":!EXP:!LOW:!MEDIUM" + /* Disable unsupported TLS modes */ + ":!PSK:!SRP:!kRSA")) + crypto_msg (M_FATAL, "Failed to set default TLS cipher list."); + return; + } + size_t begin_of_cipher, end_of_cipher; const char *current_cipher; @@ -313,9 +327,12 @@ tls_ctx_restrict_ciphers(struct tls_root_ctx *ctx, const char *ciphers) } // Make sure new cipher name fits in cipher string - if (((sizeof(openssl_ciphers)-1) - openssl_ciphers_len) < current_cipher_len) { - msg(M_SSLERR, "Failed to set restricted TLS cipher list, too long (>%d).", (int)sizeof(openssl_ciphers)-1); - } + if (((sizeof(openssl_ciphers)-1) - openssl_ciphers_len) < current_cipher_len) + { + msg (M_FATAL, + "Failed to set restricted TLS cipher list, too long (>%d).", + (int)sizeof(openssl_ciphers)-1); + } // Concatenate cipher name to OpenSSL cipher string memcpy(&openssl_ciphers[openssl_ciphers_len], current_cipher, current_cipher_len); @@ -331,7 +348,7 @@ tls_ctx_restrict_ciphers(struct tls_root_ctx *ctx, const char *ciphers) // Set OpenSSL cipher list if(!SSL_CTX_set_cipher_list(ctx->ctx, openssl_ciphers)) - msg(M_SSLERR, "Failed to set restricted TLS cipher list: %s", openssl_ciphers); + crypto_msg (M_FATAL, "Failed to set restricted TLS cipher list: %s", openssl_ciphers); } void @@ -342,7 +359,7 @@ tls_ctx_check_cert_time (const struct tls_root_ctx *ctx) ASSERT (ctx); -#if OPENSSL_VERSION_NUMBER >= 0x10002000L +#if OPENSSL_VERSION_NUMBER >= 0x10002000L && !defined(LIBRESSL_VERSION_NUMBER) /* OpenSSL 1.0.2 and up */ cert = SSL_CTX_get0_certificate (ctx->ctx); #else @@ -377,7 +394,7 @@ tls_ctx_check_cert_time (const struct tls_root_ctx *ctx) } cleanup: -#if OPENSSL_VERSION_NUMBER < 0x10002000L +#if OPENSSL_VERSION_NUMBER < 0x10002000L || defined(LIBRESSL_VERSION_NUMBER) SSL_free (ssl); #endif return; @@ -396,22 +413,22 @@ tls_ctx_load_dh_params (struct tls_root_ctx *ctx, const char *dh_file, if (!strcmp (dh_file, INLINE_FILE_TAG) && dh_file_inline) { if (!(bio = BIO_new_mem_buf ((char *)dh_file_inline, -1))) - msg (M_SSLERR, "Cannot open memory BIO for inline DH parameters"); + crypto_msg (M_FATAL, "Cannot open memory BIO for inline DH parameters"); } else { /* Get Diffie Hellman Parameters */ if (!(bio = BIO_new_file (dh_file, "r"))) - msg (M_SSLERR, "Cannot open %s for DH parameters", dh_file); + crypto_msg (M_FATAL, "Cannot open %s for DH parameters", dh_file); } dh = PEM_read_bio_DHparams (bio, NULL, NULL, NULL); BIO_free (bio); if (!dh) - msg (M_SSLERR, "Cannot load DH parameters from %s", dh_file); + crypto_msg (M_FATAL, "Cannot load DH parameters from %s", dh_file); if (!SSL_CTX_set_tmp_dh (ctx->ctx, dh)) - msg (M_SSLERR, "SSL_CTX_set_tmp_dh"); + crypto_msg (M_FATAL, "SSL_CTX_set_tmp_dh"); msg (D_TLS_DEBUG_LOW, "Diffie-Hellman initialized with %d bit key", 8 * DH_size (dh)); @@ -444,7 +461,7 @@ tls_ctx_load_pkcs12(struct tls_root_ctx *ctx, const char *pkcs12_file, BIO_push(b64, bio); p12 = d2i_PKCS12_bio(b64, NULL); if (!p12) - msg(M_SSLERR, "Error reading inline PKCS#12 file"); + crypto_msg (M_FATAL, "Error reading inline PKCS#12 file"); BIO_free(b64); BIO_free(bio); } @@ -452,11 +469,11 @@ tls_ctx_load_pkcs12(struct tls_root_ctx *ctx, const char *pkcs12_file, { /* Load the PKCS #12 file */ if (!(fp = platform_fopen(pkcs12_file, "rb"))) - msg(M_SSLERR, "Error opening file %s", pkcs12_file); + crypto_msg (M_FATAL, "Error opening file %s", pkcs12_file); p12 = d2i_PKCS12_fp(fp, NULL); fclose(fp); if (!p12) - msg(M_SSLERR, "Error reading PKCS#12 file %s", pkcs12_file); + crypto_msg (M_FATAL, "Error reading PKCS#12 file %s", pkcs12_file); } /* Parse the PKCS #12 file */ @@ -479,16 +496,16 @@ tls_ctx_load_pkcs12(struct tls_root_ctx *ctx, const char *pkcs12_file, /* Load Certificate */ if (!SSL_CTX_use_certificate (ctx->ctx, cert)) - msg (M_SSLERR, "Cannot use certificate"); + crypto_msg (M_FATAL, "Cannot use certificate"); /* Load Private Key */ if (!SSL_CTX_use_PrivateKey (ctx->ctx, pkey)) - msg (M_SSLERR, "Cannot use private key"); + crypto_msg (M_FATAL, "Cannot use private key"); warn_if_group_others_accessible (pkcs12_file); /* Check Private Key */ if (!SSL_CTX_check_private_key (ctx->ctx)) - msg (M_SSLERR, "Private key does not match the certificate"); + crypto_msg (M_FATAL, "Private key does not match the certificate"); /* Set Certificate Verification chain */ if (load_ca_file) @@ -502,9 +519,9 @@ tls_ctx_load_pkcs12(struct tls_root_ctx *ctx, const char *pkcs12_file, for (i = 0; i < sk_X509_num(ca); i++) { if (!X509_STORE_add_cert(ctx->ctx->cert_store,sk_X509_value(ca, i))) - msg (M_SSLERR, "Cannot add certificate to certificate chain (X509_STORE_add_cert)"); + crypto_msg (M_FATAL,"Cannot add certificate to certificate chain (X509_STORE_add_cert)"); if (!SSL_CTX_add_client_CA(ctx->ctx, sk_X509_value(ca, i))) - msg (M_SSLERR, "Cannot add certificate to client CA list (SSL_CTX_add_client_CA)"); + crypto_msg (M_FATAL,"Cannot add certificate to client CA list (SSL_CTX_add_client_CA)"); } } } else { @@ -518,7 +535,7 @@ tls_ctx_load_pkcs12(struct tls_root_ctx *ctx, const char *pkcs12_file, for (i = 0; i < sk_X509_num(ca); i++) { if (!SSL_CTX_add_extra_chain_cert(ctx->ctx,sk_X509_value(ca, i))) - msg (M_SSLERR, "Cannot add extra certificate to chain (SSL_CTX_add_extra_chain_cert)"); + crypto_msg (M_FATAL, "Cannot add extra certificate to chain (SSL_CTX_add_extra_chain_cert)"); } } } @@ -533,8 +550,7 @@ tls_ctx_load_cryptoapi(struct tls_root_ctx *ctx, const char *cryptoapi_cert) /* Load Certificate and Private Key */ if (!SSL_CTX_use_CryptoAPI_certificate (ctx->ctx, cryptoapi_cert)) - msg (M_SSLERR, "Cannot load certificate \"%s\" from Microsoft Certificate Store", - cryptoapi_cert); + crypto_msg (M_FATAL, "Cannot load certificate \"%s\" from Microsoft Certificate Store", cryptoapi_cert); } #endif /* WIN32 */ @@ -548,9 +564,9 @@ tls_ctx_add_extra_certs (struct tls_root_ctx *ctx, BIO *bio) if (!PEM_read_bio_X509 (bio, &cert, 0, NULL)) /* takes ownership of cert */ break; if (!cert) - msg (M_SSLERR, "Error reading extra certificate"); + crypto_msg (M_FATAL, "Error reading extra certificate"); if (SSL_CTX_add_extra_chain_cert(ctx->ctx, cert) != 1) - msg (M_SSLERR, "Error adding extra certificate"); + crypto_msg (M_FATAL, "Error adding extra certificate"); } } @@ -598,9 +614,9 @@ end: if (!ret) { if (inline_file) - msg (M_SSLERR, "Cannot load inline certificate file"); + crypto_msg (M_FATAL, "Cannot load inline certificate file"); else - msg (M_SSLERR, "Cannot load certificate file %s", cert_file); + crypto_msg (M_FATAL, "Cannot load certificate file %s", cert_file); } if (in != NULL) @@ -659,14 +675,14 @@ tls_ctx_load_priv_file (struct tls_root_ctx *ctx, const char *priv_key_file, if (management && (ERR_GET_REASON (ERR_peek_error()) == EVP_R_BAD_DECRYPT)) management_auth_failure (management, UP_TYPE_PRIVATE_KEY, NULL); #endif - msg (M_WARN|M_SSL, "Cannot load private key file %s", priv_key_file); + crypto_msg (M_WARN, "Cannot load private key file %s", priv_key_file); goto end; } warn_if_group_others_accessible (priv_key_file); /* Check Private Key */ if (!SSL_CTX_check_private_key (ssl_ctx)) - msg (M_SSLERR, "Private key does not match the certificate"); + crypto_msg (M_FATAL, "Private key does not match the certificate"); ret = 0; end: @@ -816,7 +832,7 @@ tls_ctx_use_external_private_key (struct tls_root_ctx *ctx, if (rsa_meth) free(rsa_meth); } - msg (M_SSLERR, "Cannot enable SSL external private key capability"); + crypto_msg (M_FATAL, "Cannot enable SSL external private key capability"); return 0; } @@ -846,7 +862,7 @@ tls_ctx_load_ca (struct tls_root_ctx *ctx, const char *ca_file, store = SSL_CTX_get_cert_store(ctx->ctx); if (!store) - msg(M_SSLERR, "Cannot get certificate store (SSL_CTX_get_cert_store)"); + crypto_msg (M_FATAL, "Cannot get certificate store"); /* Try to add certificates and CRLs from ca_file */ if (ca_file) @@ -869,7 +885,7 @@ tls_ctx_load_ca (struct tls_root_ctx *ctx, const char *ca_file, if (tls_server && !info->x509) { - msg (M_SSLERR, "X509 name was missing in TLS mode"); + crypto_msg (M_FATAL, "X509 name was missing in TLS mode"); } if (info->x509) @@ -904,9 +920,12 @@ tls_ctx_load_ca (struct tls_root_ctx *ctx, const char *ca_file, if (tls_server) { int cnum = sk_X509_NAME_num (cert_names); - if (cnum != (prev + 1)) { - msg (M_WARN, "Cannot load CA certificate file %s (entry %d did not validate)", np(ca_file), added); - } + if (cnum != (prev + 1)) + { + crypto_msg (M_WARN, + "Cannot load CA certificate file %s (entry %d did not validate)", + np(ca_file), added); + } prev = cnum; } @@ -918,12 +937,20 @@ tls_ctx_load_ca (struct tls_root_ctx *ctx, const char *ca_file, SSL_CTX_set_client_CA_list (ctx->ctx, cert_names); if (!added) - msg (M_SSLERR, "Cannot load CA certificate file %s (no entries were read)", np(ca_file)); + { + crypto_msg (M_FATAL, + "Cannot load CA certificate file %s (no entries were read)", + np(ca_file)); + } if (tls_server) { int cnum = sk_X509_NAME_num (cert_names); if (cnum != added) - msg (M_SSLERR, "Cannot load CA certificate file %s (only %d of %d entries were valid X509 names)", np(ca_file), cnum, added); + { + crypto_msg (M_FATAL, "Cannot load CA certificate file %s (only %d " + "of %d entries were valid X509 names)", + np(ca_file), cnum, added); + } } if (in) @@ -937,7 +964,7 @@ tls_ctx_load_ca (struct tls_root_ctx *ctx, const char *ca_file, if (lookup && X509_LOOKUP_add_dir (lookup, ca_path, X509_FILETYPE_PEM)) msg(M_WARN, "WARNING: experimental option --capath %s", ca_path); else - msg(M_SSLERR, "Cannot add lookup at --capath %s", ca_path); + crypto_msg (M_FATAL, "Cannot add lookup at --capath %s", ca_path); #if OPENSSL_VERSION_NUMBER >= 0x00907000L X509_STORE_set_flags (store, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL); #else @@ -958,7 +985,7 @@ tls_ctx_load_extra_certs (struct tls_root_ctx *ctx, const char *extra_certs_file in = BIO_new_file (extra_certs_file, "r"); if (in == NULL) - msg (M_SSLERR, "Cannot load extra-certs file: %s", extra_certs_file); + crypto_msg (M_FATAL, "Cannot load extra-certs file: %s", extra_certs_file); else tls_ctx_add_extra_certs (ctx, in); @@ -1050,7 +1077,7 @@ getbio (BIO_METHOD * type, const char *desc) BIO *ret; ret = BIO_new (type); if (!ret) - msg (M_SSLERR, "Error creating %s BIO", desc); + crypto_msg (M_FATAL, "Error creating %s BIO", desc); return ret; } @@ -1084,16 +1111,15 @@ bio_write (BIO *bio, const uint8_t *data, int size, const char *desc) } else { - msg (D_TLS_ERRORS | M_SSL, "TLS ERROR: BIO write %s error", - desc); + crypto_msg (D_TLS_ERRORS, "TLS ERROR: BIO write %s error", desc); ret = -1; ERR_clear_error (); } } else if (i != size) { - msg (D_TLS_ERRORS | M_SSL, - "TLS ERROR: BIO write %s incomplete %d/%d", desc, i, size); + crypto_msg (D_TLS_ERRORS, "TLS ERROR: BIO write %s incomplete %d/%d", + desc, i, size); ret = -1; ERR_clear_error (); } @@ -1159,8 +1185,7 @@ bio_read (BIO *bio, struct buffer *buf, int maxlen, const char *desc) } else { - msg (D_TLS_ERRORS | M_SSL, "TLS_ERROR: BIO read %s error", - desc); + crypto_msg (D_TLS_ERRORS, "TLS_ERROR: BIO read %s error", desc); buf->len = 0; ret = -1; ERR_clear_error (); @@ -1190,7 +1215,7 @@ key_state_ssl_init(struct key_state_ssl *ks_ssl, const struct tls_root_ctx *ssl_ ks_ssl->ssl = SSL_new (ssl_ctx->ctx); if (!ks_ssl->ssl) - msg (M_SSLERR, "SSL_new failed"); + crypto_msg (M_FATAL, "SSL_new failed"); /* put session * in ssl object so we can access it from verify callback*/ @@ -1366,14 +1391,13 @@ show_available_tls_ciphers (const char *cipher_list) tls_ctx.ctx = SSL_CTX_new (SSLv23_method ()); if (!tls_ctx.ctx) - msg (M_SSLERR, "Cannot create SSL_CTX object"); + crypto_msg (M_FATAL, "Cannot create SSL_CTX object"); ssl = SSL_new (tls_ctx.ctx); if (!ssl) - msg (M_SSLERR, "Cannot create SSL object"); + crypto_msg (M_FATAL, "Cannot create SSL object"); - if (cipher_list) - tls_ctx_restrict_ciphers(&tls_ctx, cipher_list); + tls_ctx_restrict_ciphers(&tls_ctx, cipher_list); printf ("Available TLS Ciphers,\n"); printf ("listed in order of preference:\n\n"); @@ -1404,10 +1428,10 @@ get_highest_preference_tls_cipher (char *buf, int size) ctx = SSL_CTX_new (SSLv23_method ()); if (!ctx) - msg (M_SSLERR, "Cannot create SSL_CTX object"); + crypto_msg (M_FATAL, "Cannot create SSL_CTX object"); ssl = SSL_new (ctx); if (!ssl) - msg (M_SSLERR, "Cannot create SSL object"); + crypto_msg (M_FATAL, "Cannot create SSL object"); cipher_name = SSL_get_cipher_list (ssl, 0); strncpynt (buf, cipher_name, size); diff --git a/src/openvpn/ssl_polarssl.c b/src/openvpn/ssl_polarssl.c index cd8ee1a..1f58369 100644 --- a/src/openvpn/ssl_polarssl.c +++ b/src/openvpn/ssl_polarssl.c @@ -49,6 +49,7 @@ #include <polarssl/havege.h> #include "ssl_verify_polarssl.h" +#include <polarssl/debug.h> #include <polarssl/error.h> #include <polarssl/oid.h> #include <polarssl/pem.h> @@ -231,13 +232,13 @@ tls_ctx_load_dh_params (struct tls_root_ctx *ctx, const char *dh_file, { if (!strcmp (dh_file, INLINE_FILE_TAG) && dh_inline) { - if (0 != dhm_parse_dhm(ctx->dhm_ctx, (const unsigned char *) dh_inline, - strlen(dh_inline))) + if (!polar_ok(dhm_parse_dhm(ctx->dhm_ctx, + (const unsigned char *) dh_inline, strlen(dh_inline)))) msg (M_FATAL, "Cannot read inline DH parameters"); } else { - if (0 != dhm_parse_dhmfile(ctx->dhm_ctx, dh_file)) + if (!polar_ok(dhm_parse_dhmfile(ctx->dhm_ctx, dh_file))) msg (M_FATAL, "Cannot read DH parameters from file %s", dh_file); } @@ -277,14 +278,16 @@ tls_ctx_load_cert_file (struct tls_root_ctx *ctx, const char *cert_file, if (!strcmp (cert_file, INLINE_FILE_TAG) && cert_inline) { - if (0 != x509_crt_parse(ctx->crt_chain, - (const unsigned char *) cert_inline, strlen(cert_inline))) + if (!polar_ok(x509_crt_parse(ctx->crt_chain, + (const unsigned char *) cert_inline, strlen(cert_inline)))) msg (M_FATAL, "Cannot load inline certificate file"); } else { - if (0 != x509_crt_parse_file(ctx->crt_chain, cert_file)) - msg (M_FATAL, "Cannot load certificate file %s", cert_file); + if (!polar_ok(x509_crt_parse_file(ctx->crt_chain, cert_file))) + { + msg (M_FATAL, "Cannot load certificate file %s", cert_file); + } } } @@ -326,7 +329,7 @@ tls_ctx_load_priv_file (struct tls_root_ctx *ctx, const char *priv_key_file, status = pk_parse_keyfile(ctx->priv_key, priv_key_file, passbuf); } } - if (0 != status) + if (!polar_ok(status)) { #ifdef ENABLE_MANAGEMENT if (management && (POLARSSL_ERR_PK_PASSWORD_MISMATCH == status)) @@ -403,7 +406,7 @@ static inline int external_pkcs1_sign( void *ctx_voidptr, if( md_info == NULL ) return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); - if( oid_get_oid_by_md( md_alg, &oid, &oid_size ) != 0 ) + if (!polar_ok(oid_get_oid_by_md( md_alg, &oid, &oid_size ))) return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); hashlen = md_get_size( md_info ); @@ -501,8 +504,8 @@ tls_ctx_use_external_private_key (struct tls_root_ctx *ctx, ctx->external_key->signature_length = pk_get_len(&ctx->crt_chain->pk); ALLOC_OBJ_CLEAR (ctx->priv_key, pk_context); - if (0 != pk_init_ctx_rsa_alt(ctx->priv_key, ctx->external_key, - NULL, external_pkcs1_sign, external_key_len)) + if (!polar_ok (pk_init_ctx_rsa_alt(ctx->priv_key, ctx->external_key, + NULL, external_pkcs1_sign, external_key_len))) return 0; return 1; @@ -510,23 +513,21 @@ tls_ctx_use_external_private_key (struct tls_root_ctx *ctx, #endif void tls_ctx_load_ca (struct tls_root_ctx *ctx, const char *ca_file, - const char *ca_inline, - const char *ca_path, bool tls_server - ) + const char *ca_inline, const char *ca_path, bool tls_server) { if (ca_path) msg(M_FATAL, "ERROR: PolarSSL cannot handle the capath directive"); if (ca_file && !strcmp (ca_file, INLINE_FILE_TAG) && ca_inline) { - if (0 != x509_crt_parse(ctx->ca_chain, (unsigned char *) ca_inline, - strlen(ca_inline))) + if (!polar_ok(x509_crt_parse(ctx->ca_chain, + (const unsigned char *) ca_inline, strlen(ca_inline)))) msg (M_FATAL, "Cannot load inline CA certificates"); } else { /* Load CA file for verifying peer supplied certificate */ - if (0 != x509_crt_parse_file(ctx->ca_chain, ca_file)) + if (!polar_ok(x509_crt_parse_file(ctx->ca_chain, ca_file))) msg (M_FATAL, "Cannot load CA certificate file %s", ca_file); } } @@ -545,14 +546,14 @@ tls_ctx_load_extra_certs (struct tls_root_ctx *ctx, const char *extra_certs_file if (!strcmp (extra_certs_file, INLINE_FILE_TAG) && extra_certs_inline) { - if (0 != x509_crt_parse(ctx->crt_chain, + if (!polar_ok(x509_crt_parse(ctx->crt_chain, (const unsigned char *) extra_certs_inline, - strlen(extra_certs_inline))) + strlen(extra_certs_inline)))) msg (M_FATAL, "Cannot load inline extra-certs file"); } else { - if (0 != x509_crt_parse_file(ctx->crt_chain, extra_certs_file)) + if (!polar_ok(x509_crt_parse_file(ctx->crt_chain, extra_certs_file))) msg (M_FATAL, "Cannot load extra-certs file: %s", extra_certs_file); } } @@ -658,10 +659,8 @@ static int endless_buf_write( void *ctx, const unsigned char *in, size_t len ) static void my_debug( void *ctx, int level, const char *str ) { - if (level == 1) - { - dmsg (D_HANDSHAKE_VERBOSE, "PolarSSL alert: %s", str); - } + int my_loglevel = (level < 3) ? D_TLS_DEBUG_MED : D_TLS_DEBUG; + msg (my_loglevel, "PolarSSL msg: %s", str); } /* @@ -740,9 +739,10 @@ void key_state_ssl_init(struct key_state_ssl *ks_ssl, CLEAR(*ks_ssl); ALLOC_OBJ_CLEAR(ks_ssl->ctx, ssl_context); - if (0 == ssl_init(ks_ssl->ctx)) + if (polar_ok(ssl_init(ks_ssl->ctx))) { /* Initialise SSL context */ + debug_set_threshold(3); ssl_set_dbg (ks_ssl->ctx, my_debug, NULL); ssl_set_endpoint (ks_ssl->ctx, ssl_ctx->endpoint); @@ -761,9 +761,10 @@ void key_state_ssl_init(struct key_state_ssl *ks_ssl, /* Initialise authentication information */ if (is_server) - ssl_set_dh_param_ctx (ks_ssl->ctx, ssl_ctx->dhm_ctx); + polar_ok (ssl_set_dh_param_ctx (ks_ssl->ctx, ssl_ctx->dhm_ctx)); - ssl_set_own_cert (ks_ssl->ctx, ssl_ctx->crt_chain, ssl_ctx->priv_key); + polar_ok (ssl_set_own_cert (ks_ssl->ctx, ssl_ctx->crt_chain, + ssl_ctx->priv_key)); /* Initialise SSL verification */ #if P2MP_SERVER @@ -912,7 +913,8 @@ key_state_write_plaintext_const (struct key_state_ssl *ks, const uint8_t *data, perf_pop (); if (POLARSSL_ERR_NET_WANT_WRITE == retval || POLARSSL_ERR_NET_WANT_READ == retval) return 0; - msg (D_TLS_ERRORS, "TLS ERROR: write tls_write_plaintext_const error"); + polar_log_err (D_TLS_ERRORS, retval, + "TLS ERROR: write tls_write_plaintext_const error"); return -1; } @@ -938,7 +940,6 @@ key_state_read_ciphertext (struct key_state_ssl *ks, struct buffer *buf, { int retval = 0; int len = 0; - char error_message[1024]; perf_push (PERF_BIO_READ_CIPHERTEXT); @@ -964,8 +965,7 @@ key_state_read_ciphertext (struct key_state_ssl *ks, struct buffer *buf, perf_pop (); if (POLARSSL_ERR_NET_WANT_WRITE == retval || POLARSSL_ERR_NET_WANT_READ == retval) return 0; - error_strerror(retval, error_message, sizeof(error_message)); - msg (D_TLS_ERRORS, "TLS_ERROR: read tls_read_ciphertext error: %d %s", retval, error_message); + polar_log_err (D_TLS_ERRORS, retval, "TLS_ERROR: read tls_read_ciphertext error"); buf->len = 0; return -1; } @@ -1008,14 +1008,14 @@ key_state_write_ciphertext (struct key_state_ssl *ks, struct buffer *buf) if (POLARSSL_ERR_NET_WANT_WRITE == retval || POLARSSL_ERR_NET_WANT_READ == retval) return 0; - msg (D_TLS_ERRORS, "TLS ERROR: write tls_write_ciphertext error"); + polar_log_err (D_TLS_ERRORS, retval, + "TLS ERROR: write tls_write_ciphertext error"); return -1; } if (retval != buf->len) { - msg (D_TLS_ERRORS, - "TLS ERROR: write tls_write_ciphertext incomplete %d/%d", + msg (D_TLS_ERRORS, "TLS ERROR: write tls_write_ciphertext incomplete %d/%d", retval, buf->len); perf_pop (); return -1; @@ -1037,7 +1037,6 @@ key_state_read_plaintext (struct key_state_ssl *ks, struct buffer *buf, { int retval = 0; int len = 0; - char error_message[1024]; perf_push (PERF_BIO_READ_PLAINTEXT); @@ -1062,8 +1061,7 @@ key_state_read_plaintext (struct key_state_ssl *ks, struct buffer *buf, { if (POLARSSL_ERR_NET_WANT_WRITE == retval || POLARSSL_ERR_NET_WANT_READ == retval) return 0; - error_strerror(retval, error_message, sizeof(error_message)); - msg (D_TLS_ERRORS, "TLS_ERROR: read tls_read_plaintext error: %d %s", retval, error_message); + polar_log_err (D_TLS_ERRORS, retval, "TLS_ERROR: read tls_read_plaintext error"); buf->len = 0; perf_pop (); return -1; diff --git a/src/openvpn/ssl_verify_polarssl.c b/src/openvpn/ssl_verify_polarssl.c index ac252a3..7ed87d6 100644 --- a/src/openvpn/ssl_verify_polarssl.c +++ b/src/openvpn/ssl_verify_polarssl.c @@ -131,17 +131,12 @@ backend_x509_get_serial (openvpn_x509_cert_t *cert, struct gc_arena *gc) char *buf = NULL; size_t buflen = 0; mpi serial_mpi = { 0 }; - int retval = 0; /* Transform asn1 integer serial into PolarSSL MPI */ mpi_init(&serial_mpi); - retval = mpi_read_binary(&serial_mpi, cert->serial.p, cert->serial.len); - if (retval < 0) + if (!polar_ok(mpi_read_binary(&serial_mpi, cert->serial.p, cert->serial.len))) { - char errbuf[128]; - error_strerror(retval, errbuf, sizeof(errbuf)); - - msg(M_WARN, "Failed to retrieve serial from certificate: %s.", errbuf); + msg(M_WARN, "Failed to retrieve serial from certificate."); return NULL; } @@ -150,13 +145,9 @@ backend_x509_get_serial (openvpn_x509_cert_t *cert, struct gc_arena *gc) buf = gc_malloc(buflen, true, gc); /* Write MPI serial as decimal string into buffer */ - retval = mpi_write_string(&serial_mpi, 10, buf, &buflen); - if (retval < 0) + if (!polar_ok(mpi_write_string(&serial_mpi, 10, buf, &buflen))) { - char errbuf[128]; - error_strerror(retval, errbuf, sizeof(errbuf)); - - msg(M_WARN, "Failed to write serial to string: %s.", errbuf); + msg(M_WARN, "Failed to write serial to string."); return NULL; } @@ -372,12 +363,9 @@ x509_verify_crl(const char *crl_file, x509_crt *cert, const char *subject) struct gc_arena gc = gc_new(); char *serial; - int polar_retval = x509_crl_parse_file(&crl, crl_file); - if (polar_retval != 0) + if (!polar_ok(x509_crl_parse_file(&crl, crl_file))) { - char errstr[128]; - polarssl_strerror(polar_retval, errstr, sizeof(errstr)); - msg (M_WARN, "CRL: cannot read CRL from file %s (%s)", crl_file, errstr); + msg (M_WARN, "CRL: cannot read CRL from file %s", crl_file); goto end; } @@ -390,7 +378,7 @@ x509_verify_crl(const char *crl_file, x509_crt *cert, const char *subject) goto end; } - if (0 != x509_crt_revoked(cert, &crl)) + if (!polar_ok(x509_crt_revoked(cert, &crl))) { serial = backend_x509_get_serial_hex(cert, &gc); msg (D_HANDSHAKE, "CRL CHECK FAILED: %s (serial %s) is REVOKED", subject, (serial ? serial : "NOT AVAILABLE")); diff --git a/src/openvpn/tun.c b/src/openvpn/tun.c index bb019c0..b70410d 100644 --- a/src/openvpn/tun.c +++ b/src/openvpn/tun.c @@ -2626,9 +2626,9 @@ open_darwin_utun (const char *dev, const char *dev_type, const char *dev_node, s /* dev_node is simply utun, do the normal dynamic utun * otherwise try to parse the utun number */ - if (dev_node && !strcmp ("utun", dev_node)==0) + if (dev_node && (strcmp("utun", dev_node) != 0 )) { - if (!sscanf (dev_node, "utun%d", &utunnum)==1) + if (sscanf(dev_node, "utun%d", &utunnum) != 1 ) msg (M_FATAL, "Cannot parse 'dev-node %s' please use 'dev-node utunX'" "to use a utun device number X", dev_node); } diff --git a/src/openvpn/win32.c b/src/openvpn/win32.c index 6c6ac4c..e17cca1 100644 --- a/src/openvpn/win32.c +++ b/src/openvpn/win32.c @@ -1223,13 +1223,14 @@ win_wfp_block_dns (const NET_IFINDEX index) /* Prepare filter. */ Filter.subLayerKey = SubLayer.subLayerKey; Filter.displayData.name = FIREWALL_NAME; - Filter.weight.type = FWP_EMPTY; + Filter.weight.type = FWP_UINT8; + Filter.weight.uint8 = 0xF; Filter.filterCondition = Condition; Filter.numFilterConditions = 2; - /* First filter. Block IPv4 DNS queries except from OpenVPN itself. */ + /* First filter. Permit IPv4 DNS queries from OpenVPN itself. */ Filter.layerKey = FWPM_LAYER_ALE_AUTH_CONNECT_V4; - Filter.action.type = FWP_ACTION_BLOCK; + Filter.action.type = FWP_ACTION_PERMIT; Condition[0].fieldKey = FWPM_CONDITION_IP_REMOTE_PORT; Condition[0].matchType = FWP_MATCH_EQUAL; @@ -1237,26 +1238,44 @@ win_wfp_block_dns (const NET_IFINDEX index) Condition[0].conditionValue.uint16 = 53; Condition[1].fieldKey = FWPM_CONDITION_ALE_APP_ID; - Condition[1].matchType = FWP_MATCH_NOT_EQUAL; + Condition[1].matchType = FWP_MATCH_EQUAL; Condition[1].conditionValue.type = FWP_BYTE_BLOB_TYPE; Condition[1].conditionValue.byteBlob = openvpnblob; /* Add filter condition to our interface. */ if (!win_wfp_add_filter(m_hEngineHandle, &Filter, NULL, &filterid)) goto err; - dmsg (D_LOW, "Filter (Block IPv4 DNS) added with ID=%I64d", filterid); + dmsg (D_LOW, "Filter (Permit OpenVPN IPv4 DNS) added with ID=%I64d", filterid); - /* Second filter. Block IPv6 DNS queries except from OpenVPN itself. */ + /* Second filter. Permit IPv6 DNS queries from OpenVPN itself. */ Filter.layerKey = FWPM_LAYER_ALE_AUTH_CONNECT_V6; /* Add filter condition to our interface. */ if (!win_wfp_add_filter(m_hEngineHandle, &Filter, NULL, &filterid)) goto err; + dmsg (D_LOW, "Filter (Permit OpenVPN IPv6 DNS) added with ID=%I64d", filterid); + + /* Third filter. Block all IPv4 DNS queries. */ + Filter.layerKey = FWPM_LAYER_ALE_AUTH_CONNECT_V4; + Filter.action.type = FWP_ACTION_BLOCK; + Filter.weight.type = FWP_EMPTY; + Filter.numFilterConditions = 1; + + if (!win_wfp_add_filter(m_hEngineHandle, &Filter, NULL, &filterid)) + goto err; + dmsg (D_LOW, "Filter (Block IPv4 DNS) added with ID=%I64d", filterid); + + /* Forth filter. Block all IPv6 DNS queries. */ + Filter.layerKey = FWPM_LAYER_ALE_AUTH_CONNECT_V6; + + if (!win_wfp_add_filter(m_hEngineHandle, &Filter, NULL, &filterid)) + goto err; dmsg (D_LOW, "Filter (Block IPv6 DNS) added with ID=%I64d", filterid); - /* Third filter. Permit IPv4 DNS queries from TAP. */ + /* Fifth filter. Permit IPv4 DNS queries from TAP. */ Filter.layerKey = FWPM_LAYER_ALE_AUTH_CONNECT_V4; Filter.action.type = FWP_ACTION_PERMIT; + Filter.numFilterConditions = 2; Condition[1].fieldKey = FWPM_CONDITION_IP_LOCAL_INTERFACE; Condition[1].matchType = FWP_MATCH_EQUAL; @@ -1268,7 +1287,7 @@ win_wfp_block_dns (const NET_IFINDEX index) goto err; dmsg (D_LOW, "Filter (Permit IPv4 DNS queries from TAP) added with ID=%I64d", filterid); - /* Forth filter. Permit IPv6 DNS queries from TAP. */ + /* Sixth filter. Permit IPv6 DNS queries from TAP. */ Filter.layerKey = FWPM_LAYER_ALE_AUTH_CONNECT_V6; /* Add filter condition to our interface. */ @@ -1323,6 +1342,20 @@ win32_version_info() } } +bool +win32_is_64bit() +{ +#if defined(_WIN64) + return true; // 64-bit programs run only on Win64 +#elif defined(_WIN32) + // 32-bit programs run on both 32-bit and 64-bit Windows + BOOL f64 = FALSE; + return IsWow64Process(GetCurrentProcess(), &f64) && f64; +#else + return false; // Win64 does not support Win16 +#endif +} + const char * win32_version_string(struct gc_arena *gc, bool add_name) { @@ -1349,6 +1382,8 @@ win32_version_string(struct gc_arena *gc, bool add_name) break; } + buf_printf (&out, win32_is_64bit() ? " 64bit" : " 32bit"); + return (const char *)out.data; } |