diff options
author | Parménides GV <parmegv@sdf.org> | 2015-01-31 01:21:46 +0100 |
---|---|---|
committer | Parménides GV <parmegv@sdf.org> | 2015-01-31 01:21:46 +0100 |
commit | e495feae1bde6c6d7db0db5bf4959f501b8c1375 (patch) | |
tree | 90c4af22d047b7297a66a9e623c86c5af63b12f6 /app | |
parent | 618792ca47208818b892257da7d55809ed8ae20f (diff) | |
parent | 29fd5bc150155505a9fe0ffa4f1d0ac81db78724 (diff) |
Merge branch 'develop' into release-0.9.2
Diffstat (limited to 'app')
51 files changed, 919 insertions, 905 deletions
diff --git a/app/build.gradle b/app/build.gradle index db928f0b..4d3c5b9c 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -110,6 +110,7 @@ task copyIcsOpenVPNImages( type: Copy ) { include '**/ic_share*.png' include '**/ic_close*.png' include '**/ic_edit*.png' + include '**/ic_check*.png' includeEmptyDirs = false } into '.' diff --git a/app/jni/jniglue.c b/app/jni/jniglue.c index c2dd9f1e..12e67543 100644 --- a/app/jni/jniglue.c +++ b/app/jni/jniglue.c @@ -16,9 +16,7 @@ jint JNI_OnLoad(JavaVM *vm, void *reserved) { void android_openvpn_log(int level,const char* prefix,const char* prefix_sep,const char* m1) { -#ifndef NDEBUG __android_log_print(ANDROID_LOG_DEBUG,"openvpn","%s%s%s",prefix,prefix_sep,m1); -#endif } void Java_de_blinkt_openvpn_core_NativeUtils_jniclose(JNIEnv *env,jclass jo, jint fd) { diff --git a/app/openvpn/config-msvc.h b/app/openvpn/config-msvc.h index fa993843..8294c2c7 100644 --- a/app/openvpn/config-msvc.h +++ b/app/openvpn/config-msvc.h @@ -18,7 +18,6 @@ #define ENABLE_PLUGIN 1 #define ENABLE_PORT_SHARE 1 #define ENABLE_SOCKS 1 -#define ENABLE_SSL 1 #define HAVE_ERRNO_H 1 #define HAVE_FCNTL_H 1 diff --git a/app/openvpn/config-version.h b/app/openvpn/config-version.h index f89c974f..4aa92283 100644 --- a/app/openvpn/config-version.h +++ b/app/openvpn/config-version.h @@ -1,2 +1,2 @@ -#define CONFIGURE_GIT_REVISION "icsopenvpn_625-af9eb9424047f9f5" +#define CONFIGURE_GIT_REVISION "icsopenvpn_627-cff5e3e9c3ac08df" #define CONFIGURE_GIT_FLAGS "" diff --git a/app/openvpn/configure.ac b/app/openvpn/configure.ac index ddaa2b2e..91324688 100644 --- a/app/openvpn/configure.ac +++ b/app/openvpn/configure.ac @@ -79,13 +79,6 @@ AC_ARG_ENABLE( ) AC_ARG_ENABLE( - [ssl], - [AS_HELP_STRING([--disable-ssl], [disable SSL support for TLS-based key exchange @<:@default=yes@:>@])], - , - [enable_ssl="yes"] -) - -AC_ARG_ENABLE( [x509-alt-username], [AS_HELP_STRING([--enable-x509-alt-username], [enable the --x509-username-field feature @<:@default=no@:>@])], , @@ -1080,19 +1073,11 @@ case "${with_crypto_library}" in ;; esac -if test "${enable_ssl}" = "yes"; then - test "${enable_crypto}" != "yes" && AC_MSG_ERROR([crypto must be enabled for ssl]) - test "${have_crypto_ssl}" != "yes" && AC_MSG_ERROR([${with_ssl_library} ssl is required but missing]) - OPTIONAL_CRYPTO_CFLAGS="${OPTIONAL_CRYPTO_CFLAGS} ${CRYPTO_SSL_CFLAGS}" - OPTIONAL_CRYPTO_LIBS="${OPTIONAL_CRYPTO_LIBS} ${CRYPTO_SSL_LIBS}" - AC_DEFINE([ENABLE_SSL], [1], [Enable ssl library]) -fi - if test "${enable_crypto}" = "yes"; then test "${have_crypto_crypto}" != "yes" && AC_MSG_ERROR([${with_crypto_library} crypto is required but missing]) test "${enable_crypto_ofb_cfb}" = "yes" && AC_DEFINE([ENABLE_OFB_CFB_MODE], [1], [Enable OFB and CFB cipher modes]) - OPTIONAL_CRYPTO_CFLAGS="${OPTIONAL_CRYPTO_CFLAGS} ${CRYPTO_CRYPTO_CFLAGS}" - OPTIONAL_CRYPTO_LIBS="${OPTIONAL_CRYPTO_LIBS} ${CRYPTO_CRYPTO_LIBS}" + OPTIONAL_CRYPTO_CFLAGS="${OPTIONAL_CRYPTO_CFLAGS} ${CRYPTO_CRYPTO_CFLAGS} ${CRYPTO_SSL_CFLAGS}" + OPTIONAL_CRYPTO_LIBS="${OPTIONAL_CRYPTO_LIBS} ${CRYPTO_CRYPTO_LIBS} ${CRYPTO_SSL_LIBS}" AC_DEFINE([ENABLE_CRYPTO], [1], [Enable crypto library]) fi @@ -1135,10 +1120,17 @@ fi if test "${enable_pkcs11}" = "yes"; then test "${have_pkcs11_helper}" != "yes" && AC_MSG_ERROR([PKCS11 enabled but libpkcs11-helper is missing]) - test "${enable_ssl}" != "yes" && AC_MSG_ERROR([PKCS11 can be enabled only if SSL is enabled]) + test "${enable_crypto}" != "yes" && AC_MSG_ERROR([PKCS11 can be enabled only if crypto is enabled]) OPTIONAL_PKCS11_HELPER_CFLAGS="${PKCS11_HELPER_CFLAGS}" OPTIONAL_PKCS11_HELPER_LIBS="${PKCS11_HELPER_LIBS}" AC_DEFINE([ENABLE_PKCS11], [1], [Enable PKCS11]) + PKG_CHECK_MODULES( + [P11KIT], + [p11-kit-1], + [proxy_module="`$PKG_CONFIG --variable=proxy_module p11-kit-1`" + AC_DEFINE_UNQUOTED([DEFAULT_PKCS11_MODULE], "${proxy_module}", [p11-kit proxy])], + [] + ) fi if test "${enable_pedantic}" = "yes"; then diff --git a/app/openvpn/doc/doxygen/doc_data_crypto.h b/app/openvpn/doc/doxygen/doc_data_crypto.h index 640203f4..11726724 100644 --- a/app/openvpn/doc/doxygen/doc_data_crypto.h +++ b/app/openvpn/doc/doxygen/doc_data_crypto.h @@ -60,12 +60,12 @@ * * @par Settings that control this module's activity * Whether or not the Data Channel Crypto module is active depends on the - * compile-time \c ENABLE_CRYPTO and \c ENABLE_SSL preprocessor macros. How it - * processes packets received from the \link data_control Data Channel - * Control module\endlink at runtime depends on the associated \c - * crypto_options structure. To perform cryptographic operations, the \c - * crypto_options.key_ctx_bi must contain the correct cipher and HMAC - * security parameters for the direction the packet is traveling in. + * compile-time \c ENABLE_CRYPTO preprocessor macro. How it processes packets + * received from the \link data_control Data Channel Control module\endlink at + * runtime depends on the associated \c crypto_options structure. To perform + * cryptographic operations, the \c crypto_options.key_ctx_bi must contain the + * correct cipher and HMAC security parameters for the direction the packet is + * traveling in. * * @par Crypto algorithms * This module uses the crypto algorithm implementations of the external diff --git a/app/openvpn/doc/doxygen/openvpn.doxyfile b/app/openvpn/doc/doxygen/openvpn.doxyfile index cf26c42a..7a02028a 100644 --- a/app/openvpn/doc/doxygen/openvpn.doxyfile +++ b/app/openvpn/doc/doxygen/openvpn.doxyfile @@ -235,7 +235,7 @@ EXPAND_ONLY_PREDEF = NO SEARCH_INCLUDES = YES INCLUDE_PATH = INCLUDE_FILE_PATTERNS = -PREDEFINED = WIN32 NTLM USE_LZO ENABLE_FRAGMENT P2MP P2MP_SERVER ENABLE_CRYPTO ENABLE_CRYPTO_OPENSSL ENABLE_SSL ENABLE_PLUGIN ENABLE_MANAGEMENT ENABLE_OCC HAVE_GETTIMEOFDAY +PREDEFINED = WIN32 NTLM USE_LZO ENABLE_FRAGMENT P2MP P2MP_SERVER ENABLE_CRYPTO ENABLE_CRYPTO_OPENSSL ENABLE_PLUGIN ENABLE_MANAGEMENT ENABLE_OCC HAVE_GETTIMEOFDAY EXPAND_AS_DEFINED = SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- diff --git a/app/openvpn/doc/openvpn.8 b/app/openvpn/doc/openvpn.8 index 532eda5c..a8c189c9 100644 --- a/app/openvpn/doc/openvpn.8 +++ b/app/openvpn/doc/openvpn.8 @@ -4239,13 +4239,18 @@ Not available with PolarSSL. File containing Diffie Hellman parameters in .pem format (required for .B \-\-tls-server -only). Use +only). -.B openssl dhparam -out dh1024.pem 1024 +Set +.B file=none +to disable Diffie Hellman key exchange (and use ECDH only). Note that this +requires peers to be using an SSL library that supports ECDH TLS cipher suites +(e.g. OpenSSL 1.0.1+, or PolarSSL 1.3+). -to generate your own, or use the existing dh1024.pem file -included with the OpenVPN distribution. Diffie Hellman parameters -may be considered public. +Use +.B openssl dhparam -out dh2048.pem 2048 +to generate 2048-bit DH parameters. Diffie Hellman parameters may be considered +public. .\"********************************************************* .TP .B \-\-ecdh-curve name @@ -4393,6 +4398,16 @@ This option can be used instead of .B \-\-cert, \-\-key, and .B \-\-pkcs12. + +If p11-kit is present on the system, its +.B p11-kit-proxy.so +module will be loaded by default if either the +.B \-\-pkcs11\-id +or +.B \-\-pkcs11\-id\-management +options are specified without +.B \-\-pkcs11\-provider +being given. .\"********************************************************* .TP .B \-\-pkcs11-private-mode mode... @@ -5480,11 +5495,17 @@ adapter list. .SS PKCS#11 Standalone Options: .\"********************************************************* .TP -.B \-\-show-pkcs11-ids provider [cert_private] +.B \-\-show-pkcs11-ids [provider] [cert_private] (Standalone) Show PKCS#11 token object list. Specify cert_private as 1 if certificates are stored as private objects. +If p11-kit is present on the system, the +.B provider +argument is optional; if omitted the default +.B p11-kit-proxy.so +module will be queried. + .B \-\-verb option can be used BEFORE this option to produce debugging information. .\"********************************************************* diff --git a/app/openvpn/include/openvpn-plugin.h b/app/openvpn/include/openvpn-plugin.h index 5f2d4079..080ffff2 100644 --- a/app/openvpn/include/openvpn-plugin.h +++ b/app/openvpn/include/openvpn-plugin.h @@ -27,7 +27,7 @@ #define OPENVPN_PLUGIN_VERSION 3 -#ifdef ENABLE_SSL +#ifdef ENABLE_CRYPTO #ifdef ENABLE_CRYPTO_POLARSSL #include <polarssl/x509_crt.h> #ifndef __OPENVPN_X509_CERT_T_DECLARED @@ -358,9 +358,9 @@ struct openvpn_plugin_args_open_return * *per_client_context : the per-client context pointer which was returned by * openvpn_plugin_client_constructor_v1, if defined. * - * current_cert_depth : Certificate depth of the certificate being passed over (only if compiled with ENABLE_SSL defined) + * current_cert_depth : Certificate depth of the certificate being passed over (only if compiled with ENABLE_CRYPTO defined) * - * *current_cert : X509 Certificate object received from the client (only if compiled with ENABLE_SSL defined) + * *current_cert : X509 Certificate object received from the client (only if compiled with ENABLE_CRYPTO defined) * */ struct openvpn_plugin_args_func_in @@ -370,7 +370,7 @@ struct openvpn_plugin_args_func_in const char ** const envp; openvpn_plugin_handle_t handle; void *per_client_context; -#ifdef ENABLE_SSL +#ifdef ENABLE_CRYPTO int current_cert_depth; openvpn_x509_cert_t *current_cert; #else diff --git a/app/openvpn/sample/sample-plugins/log/log_v3.c b/app/openvpn/sample/sample-plugins/log/log_v3.c index 4d3af91a..bf1a15c8 100644 --- a/app/openvpn/sample/sample-plugins/log/log_v3.c +++ b/app/openvpn/sample/sample-plugins/log/log_v3.c @@ -36,7 +36,7 @@ #include <string.h> #include <stdlib.h> -#define ENABLE_SSL +#define ENABLE_CRYPTO #include "openvpn-plugin.h" diff --git a/app/openvpn/src/openvpn/crypto.c b/app/openvpn/src/openvpn/crypto.c index eaef9643..5cf9b9cd 100644 --- a/app/openvpn/src/openvpn/crypto.c +++ b/app/openvpn/src/openvpn/crypto.c @@ -726,8 +726,6 @@ test_crypto (const struct crypto_options *co, struct frame* frame) gc_free (&gc); } -#ifdef ENABLE_SSL - void get_tls_handshake_key (const struct key_type *key_type, struct key_ctx_bi *ctx, @@ -799,7 +797,6 @@ get_tls_handshake_key (const struct key_type *key_type, CLEAR (*ctx); } } -#endif /* header and footer for static key file */ static const char static_key_head[] = "-----BEGIN OpenVPN Static key V1-----"; @@ -1322,23 +1319,6 @@ get_random() return l; } -#ifndef ENABLE_SSL - -void -init_ssl_lib (void) -{ - crypto_init_lib (); -} - -void -free_ssl_lib (void) -{ - crypto_uninit_lib (); - prng_uninit(); -} - -#endif /* ENABLE_SSL */ - /* * md5 functions */ diff --git a/app/openvpn/src/openvpn/crypto.h b/app/openvpn/src/openvpn/crypto.h index e4898278..82158f9c 100644 --- a/app/openvpn/src/openvpn/crypto.h +++ b/app/openvpn/src/openvpn/crypto.h @@ -413,8 +413,6 @@ void key2_print (const struct key2* k, const char* prefix0, const char* prefix1); -#ifdef ENABLE_SSL - #define GHK_INLINE (1<<0) void get_tls_handshake_key (const struct key_type *key_type, struct key_ctx_bi *ctx, @@ -422,13 +420,6 @@ void get_tls_handshake_key (const struct key_type *key_type, const int key_direction, const unsigned int flags); -#else - -void init_ssl_lib (void); -void free_ssl_lib (void); - -#endif /* ENABLE_SSL */ - /* * md5 functions */ diff --git a/app/openvpn/src/openvpn/crypto_openssl.c b/app/openvpn/src/openvpn/crypto_openssl.c index f7a491d6..2d81a6d8 100644 --- a/app/openvpn/src/openvpn/crypto_openssl.c +++ b/app/openvpn/src/openvpn/crypto_openssl.c @@ -42,9 +42,12 @@ #include "integer.h" #include "crypto.h" #include "crypto_backend.h" -#include <openssl/objects.h> -#include <openssl/evp.h> + #include <openssl/des.h> +#include <openssl/err.h> +#include <openssl/evp.h> +#include <openssl/objects.h> +#include <openssl/ssl.h> /* * Check for key size creepage. @@ -100,13 +103,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'", @@ -142,14 +147,6 @@ crypto_init_lib_engine (const char *engine_name) void crypto_init_lib (void) { -#ifndef ENABLE_SSL - /* If SSL is enabled init is taken care of in ssl_openssl.c */ -#ifndef ENABLE_SMALL - ERR_load_crypto_strings (); -#endif - OpenSSL_add_all_algorithms (); -#endif - /* * If you build the OpenSSL library and OpenVPN with * CRYPTO_MDEBUG, you will get a listing of OpenSSL @@ -164,14 +161,6 @@ crypto_init_lib (void) void crypto_uninit_lib (void) { -#ifndef ENABLE_SSL - /* If SSL is enabled cleanup is taken care of in ssl_openssl.c */ - EVP_cleanup (); -#ifndef ENABLE_SMALL - ERR_free_strings (); -#endif -#endif - #ifdef CRYPTO_MDEBUG FILE* fp = fopen ("sdlog", "w"); ASSERT (fp); @@ -195,6 +184,26 @@ 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 ())) + { + /* Be more clear about frequently occurring "no shared cipher" error */ + if (err == ERR_PACK(ERR_LIB_SSL,SSL_F_SSL3_GET_CLIENT_HELLO, + SSL_R_NO_SHARED_CIPHER)) + { + msg (D_CRYPT_ERRORS, "TLS error: The server has no TLS ciphersuites " + "in common with the client. Your --tls-cipher setting might be " + "too restrictive."); + } + + msg (flags, "OpenSSL: %s", ERR_error_string (err, NULL)); + } +} + + /* * * OpenSSL memory debugging. If dmalloc debugging is enabled, tell @@ -386,17 +395,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; } } @@ -445,7 +457,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)", @@ -529,13 +541,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); @@ -582,7 +594,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 @@ -617,12 +631,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/app/openvpn/src/openvpn/crypto_openssl.h b/app/openvpn/src/openvpn/crypto_openssl.h index f883c2a5..42c7e9a9 100644 --- a/app/openvpn/src/openvpn/crypto_openssl.h +++ b/app/openvpn/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/app/openvpn/src/openvpn/error.c b/app/openvpn/src/openvpn/error.c index af865f32..72ebfab6 100644 --- a/app/openvpn/src/openvpn/error.c +++ b/app/openvpn/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 @@ -269,28 +262,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; - size_t 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/app/openvpn/src/openvpn/error.h b/app/openvpn/src/openvpn/error.h index 1e1f2acf..d5204f3f 100644 --- a/app/openvpn/src/openvpn/error.h +++ b/app/openvpn/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) @@ -354,6 +349,12 @@ ignore_sys_error (const int err) return false; } +/** Convert fatal errors to nonfatal, don't touch other errors */ +static inline const unsigned int +nonfatal(const unsigned int err) { + return err & M_FATAL ? (err ^ M_FATAL) | M_NONFATAL : err; +} + #include "errlevel.h" #endif diff --git a/app/openvpn/src/openvpn/forward-inline.h b/app/openvpn/src/openvpn/forward-inline.h index 5853ce29..0ca66929 100644 --- a/app/openvpn/src/openvpn/forward-inline.h +++ b/app/openvpn/src/openvpn/forward-inline.h @@ -35,7 +35,7 @@ static inline void check_tls (struct context *c) { -#if defined(ENABLE_CRYPTO) && defined(ENABLE_SSL) +#if defined(ENABLE_CRYPTO) void check_tls_dowork (struct context *c); if (c->c2.tls_multi) check_tls_dowork (c); @@ -49,7 +49,7 @@ check_tls (struct context *c) static inline void check_tls_errors (struct context *c) { -#if defined(ENABLE_CRYPTO) && defined(ENABLE_SSL) +#if defined(ENABLE_CRYPTO) void check_tls_errors_co (struct context *c); void check_tls_errors_nco (struct context *c); if (c->c2.tls_multi && c->c2.tls_exit_signal) diff --git a/app/openvpn/src/openvpn/forward.c b/app/openvpn/src/openvpn/forward.c index 5709ee51..f4471405 100644 --- a/app/openvpn/src/openvpn/forward.c +++ b/app/openvpn/src/openvpn/forward.c @@ -88,7 +88,7 @@ show_wait_status (struct context *c) * traffic on the control-channel. * */ -#if defined(ENABLE_CRYPTO) && defined(ENABLE_SSL) +#ifdef ENABLE_CRYPTO void check_tls_dowork (struct context *c) { @@ -117,9 +117,6 @@ check_tls_dowork (struct context *c) if (wakeup) context_reschedule_sec (c, wakeup); } -#endif - -#if defined(ENABLE_CRYPTO) && defined(ENABLE_SSL) void check_tls_errors_co (struct context *c) @@ -133,8 +130,7 @@ check_tls_errors_nco (struct context *c) { register_signal (c, c->c2.tls_exit_signal, "tls-error"); /* SOFT-SIGUSR1 -- TLS error */ } - -#endif +#endif /* ENABLE_CRYPTO */ #if P2MP @@ -239,7 +235,7 @@ check_connection_established_dowork (struct context *c) bool send_control_channel_string (struct context *c, const char *str, int msglevel) { -#if defined(ENABLE_CRYPTO) && defined(ENABLE_SSL) +#ifdef ENABLE_CRYPTO if (c->c2.tls_multi) { struct gc_arena gc = gc_new (); bool stat; @@ -264,7 +260,7 @@ send_control_channel_string (struct context *c, const char *str, int msglevel) gc_free (&gc); return stat; } -#endif +#endif /* ENABLE_CRYPTO */ return true; } @@ -457,7 +453,6 @@ encrypt_sign (struct context *c, bool comp_frag) } #ifdef ENABLE_CRYPTO -#ifdef ENABLE_SSL /* * If TLS mode, get the key we will use to encrypt * the packet. @@ -466,7 +461,6 @@ encrypt_sign (struct context *c, bool comp_frag) { tls_pre_encrypt (c->c2.tls_multi, &c->c2.buf, &c->c2.crypto_options); } -#endif /* * Encrypt the packet and write an optional @@ -480,7 +474,6 @@ encrypt_sign (struct context *c, bool comp_frag) link_socket_get_outgoing_addr (&c->c2.buf, get_link_socket_info (c), &c->c2.to_link_addr); #ifdef ENABLE_CRYPTO -#ifdef ENABLE_SSL /* * In TLS mode, prepend the appropriate one-byte opcode * to the packet which identifies it as a data channel @@ -493,7 +486,6 @@ encrypt_sign (struct context *c, bool comp_frag) tls_post_encrypt (c->c2.tls_multi, &c->c2.buf); } #endif -#endif /* if null encryption, copy result to read_tun_buf */ buffer_turnover (orig_buf, &c->c2.to_link, &c->c2.buf, &b->read_tun_buf); @@ -783,7 +775,6 @@ process_incoming_link_part1 (struct context *c, struct link_socket_info *lsi, bo link_socket_bad_incoming_addr (&c->c2.buf, lsi, &c->c2.from); #ifdef ENABLE_CRYPTO -#ifdef ENABLE_SSL if (c->c2.tls_multi) { /* @@ -813,7 +804,6 @@ process_incoming_link_part1 (struct context *c, struct link_socket_info *lsi, bo if (c->c2.context_auth != CAS_SUCCEEDED) c->c2.buf.len = 0; #endif -#endif /* ENABLE_SSL */ /* authenticate and decrypt the incoming packet */ decrypt_status = openvpn_decrypt (&c->c2.buf, c->c2.buffers->decrypt_buf, &c->c2.crypto_options, &c->c2.frame); diff --git a/app/openvpn/src/openvpn/init.c b/app/openvpn/src/openvpn/init.c index b5c81f87..77827a57 100644 --- a/app/openvpn/src/openvpn/init.c +++ b/app/openvpn/src/openvpn/init.c @@ -410,7 +410,7 @@ next_connection_entry (struct context *c) static void init_query_passwords (struct context *c) { -#if defined(ENABLE_CRYPTO) && defined(ENABLE_SSL) +#ifdef ENABLE_CRYPTO /* Certificate password input */ if (c->options.key_pass_file) pem_password_setup (c->options.key_pass_file); @@ -792,7 +792,7 @@ uninit_static (void) close_port_share (); #endif -#if defined(MEASURE_TLS_HANDSHAKE_STATS) && defined(ENABLE_CRYPTO) && defined(ENABLE_SSL) +#if defined(MEASURE_TLS_HANDSHAKE_STATS) && defined(ENABLE_CRYPTO) show_tls_performance_stats (); #endif } @@ -835,10 +835,7 @@ print_openssl_info (const struct options *options) */ #ifdef ENABLE_CRYPTO if (options->show_ciphers || options->show_digests || options->show_engines -#ifdef ENABLE_SSL - || options->show_tls_ciphers || options->show_curves -#endif - ) + || options->show_tls_ciphers || options->show_curves) { if (options->show_ciphers) show_available_ciphers (); @@ -846,12 +843,10 @@ print_openssl_info (const struct options *options) show_available_digests (); if (options->show_engines) show_available_engines (); -#ifdef ENABLE_SSL if (options->show_tls_ciphers) show_available_tls_ciphers (options->cipher_list); if (options->show_curves) show_available_curves(); -#endif return true; } #endif @@ -901,10 +896,8 @@ do_persist_tuntap (const struct options *options) || options->ifconfig_remote_netmask #ifdef ENABLE_CRYPTO || options->shared_secret_file -#ifdef ENABLE_SSL || options->tls_server || options->tls_client #endif -#endif ) msg (M_FATAL|M_OPTERR, "options --mktun or --rmtun should only be used together with --dev"); @@ -1012,7 +1005,7 @@ const char * format_common_name (struct context *c, struct gc_arena *gc) { struct buffer out = alloc_buf_gc (256, gc); -#if defined(ENABLE_CRYPTO) && defined(ENABLE_SSL) +#ifdef ENABLE_CRYPTO if (c->c2.tls_multi) { buf_printf (&out, "[%s] ", tls_common_name (c->c2.tls_multi, false)); @@ -1102,9 +1095,7 @@ do_init_timers (struct context *c, bool deferred) #ifdef ENABLE_CRYPTO if (c->options.packet_id_file) event_timeout_init (&c->c2.packet_id_persist_interval, 60, now); -#endif -#if defined(ENABLE_CRYPTO) && defined(ENABLE_SSL) /* initialize tmp_int optimization that limits the number of times we call tls_multi_process in the main event loop */ interval_init (&c->c2.tmp_int, TLS_MULTI_HORIZON, TLS_MULTI_REFRESH); @@ -1797,7 +1788,7 @@ do_deferred_options (struct context *c, const unsigned int found) if (found & OPT_P_SETENV) msg (D_PUSH, "OPTIONS IMPORT: environment modified"); -#ifdef ENABLE_SSL +#ifdef ENABLE_CRYPTO if (found & OPT_P_PEER_ID) { msg (D_PUSH, "OPTIONS IMPORT: peer-id set"); @@ -1928,13 +1919,11 @@ key_schedule_free (struct key_schedule *ks, bool free_ssl_ctx) { #ifdef ENABLE_CRYPTO free_key_ctx_bi (&ks->static_key); -#ifdef ENABLE_SSL if (tls_ctx_initialised(&ks->ssl_ctx) && free_ssl_ctx) { tls_ctx_free (&ks->ssl_ctx); free_key_ctx_bi (&ks->tls_auth_key); } -#endif /* ENABLE_SSL */ #endif /* ENABLE_CRYPTO */ CLEAR (*ks); } @@ -2054,8 +2043,6 @@ do_init_crypto_static (struct context *c, const unsigned int flags) options->use_iv); } -#ifdef ENABLE_SSL - /* * Initialize the persistent component of OpenVPN's TLS mode, * which is preserved across SIGUSR1 resets. @@ -2303,10 +2290,6 @@ do_init_finalize_tls_frame (struct context *c) } } -#endif /* ENABLE_SSL */ -#endif /* ENABLE_CRYPTO */ - -#ifdef ENABLE_CRYPTO /* * No encryption or authentication. */ @@ -2325,16 +2308,14 @@ do_init_crypto (struct context *c, const unsigned int flags) #ifdef ENABLE_CRYPTO if (c->options.shared_secret_file) do_init_crypto_static (c, flags); -#ifdef ENABLE_SSL else if (c->options.tls_server || c->options.tls_client) do_init_crypto_tls (c, flags); -#endif else /* no encryption or authentication. */ do_init_crypto_none (c); #else /* ENABLE_CRYPTO */ msg (M_WARN, "******* WARNING *******: " PACKAGE_NAME - " built without OpenSSL -- encryption and authentication features disabled -- all data will be tunnelled as cleartext"); + " built without crypto library -- encryption and authentication features disabled -- all data will be tunnelled as cleartext"); #endif /* ENABLE_CRYPTO */ } @@ -2503,7 +2484,6 @@ do_option_warnings (struct context *c) if (!o->use_iv) msg (M_WARN, "WARNING: You have disabled Crypto IVs (--no-iv) which may make " PACKAGE_NAME " less secure"); -#ifdef ENABLE_SSL if (o->tls_server) warn_on_use_of_common_subnets (); if (o->tls_client @@ -2513,7 +2493,6 @@ do_option_warnings (struct context *c) && !o->remote_cert_eku) msg (M_WARN, "WARNING: No server certificate verification method has been enabled. See http://openvpn.net/howto.html#mitm for more info."); #endif -#endif #ifndef CONNECT_NONBLOCK if (o->ce.connect_timeout_defined) @@ -2535,7 +2514,7 @@ do_option_warnings (struct context *c) static void do_init_frame_tls (struct context *c) { -#if defined(ENABLE_CRYPTO) && defined(ENABLE_SSL) +#ifdef ENABLE_CRYPTO do_init_finalize_tls_frame (c); #endif } @@ -2733,9 +2712,7 @@ do_compute_occ_strings (struct context *c) options_string_version (c->c2.options_string_remote, &gc), md5sum ((uint8_t*)c->c2.options_string_remote, strlen (c->c2.options_string_remote), 9, &gc)); -#endif -#if defined(ENABLE_CRYPTO) && defined(ENABLE_SSL) if (c->c2.tls_multi) tls_multi_init_set_options (c->c2.tls_multi, c->c2.options_string_local, @@ -2821,7 +2798,7 @@ do_close_free_buf (struct context *c) static void do_close_tls (struct context *c) { -#if defined(ENABLE_CRYPTO) && defined(ENABLE_SSL) +#ifdef ENABLE_CRYPTO if (c->c2.tls_multi) { tls_multi_free (c->c2.tls_multi, true); @@ -3072,7 +3049,7 @@ do_setup_fast_io (struct context *c) static void do_signal_on_tls_errors (struct context *c) { -#if defined(ENABLE_CRYPTO) && defined(ENABLE_SSL) +#ifdef ENABLE_CRYPTO if (c->options.tls_exit) c->c2.tls_exit_signal = SIGTERM; else @@ -3652,12 +3629,10 @@ inherit_context_child (struct context *dest, #ifdef ENABLE_CRYPTO dest->c1.ks.key_type = src->c1.ks.key_type; -#ifdef ENABLE_SSL /* inherit SSL context */ dest->c1.ks.ssl_ctx = src->c1.ks.ssl_ctx; dest->c1.ks.tls_auth_key = src->c1.ks.tls_auth_key; #endif -#endif /* options */ dest->options = src->options; @@ -3729,7 +3704,7 @@ inherit_context_top (struct context *dest, /* detach plugins */ dest->plugins_owned = false; -#if defined(ENABLE_CRYPTO) && defined(ENABLE_SSL) +#ifdef ENABLE_CRYPTO dest->c2.tls_multi = NULL; #endif diff --git a/app/openvpn/src/openvpn/manage.c b/app/openvpn/src/openvpn/manage.c index 9913197b..27164f18 100644 --- a/app/openvpn/src/openvpn/manage.c +++ b/app/openvpn/src/openvpn/manage.c @@ -701,7 +701,7 @@ man_query_need_str (struct management *man, const char *type, const char *action static void man_forget_passwords (struct management *man) { -#if defined(ENABLE_CRYPTO) && defined(ENABLE_SSL) +#ifdef ENABLE_CRYPTO ssl_purge_auth (false); msg (M_CLIENT, "SUCCESS: Passwords were forgotten"); #endif @@ -1115,7 +1115,7 @@ man_network_change (struct management *man) man->connection.fdtosend = fd; msg (M_CLIENT, "PROTECTFD: fd '%d' sent to be protected", fd); if (fd == -2) - man_signal (man, "USR1"); + man_signal (man, "SIGUSR1"); } } #endif @@ -1716,7 +1716,7 @@ man_reset_client_socket (struct management *man, const bool exiting) } if (!exiting) { -#if defined(ENABLE_CRYPTO) && defined(ENABLE_SSL) +#ifdef ENABLE_CRYPTO if (man->settings.flags & MF_FORGET_DISCONNECT) ssl_purge_auth (false); #endif diff --git a/app/openvpn/src/openvpn/multi.c b/app/openvpn/src/openvpn/multi.c index 90b3d2dc..b3688594 100644 --- a/app/openvpn/src/openvpn/multi.c +++ b/app/openvpn/src/openvpn/multi.c @@ -2125,17 +2125,20 @@ void multi_process_float (struct multi_context* m, struct multi_instance* mi) const uint32_t hv = hash_value (hash, &real); struct hash_bucket *bucket = hash_bucket (hash, hv); + /* make sure that we don't float to an address taken by another client */ struct hash_element *he = hash_lookup_fast (hash, bucket, &real, hv); if (he) { struct multi_instance *ex_mi = (struct multi_instance *) he->value; - const char *cn = tls_common_name (mi->context.c2.tls_multi, true); - const char *ex_cn = tls_common_name (ex_mi->context.c2.tls_multi, true); - if (cn && ex_cn && strcmp (cn, ex_cn)) + struct tls_multi *m1 = mi->context.c2.tls_multi; + struct tls_multi *m2 = ex_mi->context.c2.tls_multi; + + /* do not float if target address is taken by client with another cert */ + if (!cert_hash_compare(m1->locked_cert_hash_set, m2->locked_cert_hash_set)) { - msg (D_MULTI_MEDIUM, "prevent float to %s", - multi_instance_string (ex_mi, false, &gc)); + msg (D_MULTI_MEDIUM, "Disallow float to an address taken by another client %s", + multi_instance_string (ex_mi, false, &gc)); mi->context.c2.buf.len = 0; diff --git a/app/openvpn/src/openvpn/openvpn.h b/app/openvpn/src/openvpn/openvpn.h index eab8cd5b..b4596ea4 100644 --- a/app/openvpn/src/openvpn/openvpn.h +++ b/app/openvpn/src/openvpn/openvpn.h @@ -62,14 +62,11 @@ struct key_schedule /* pre-shared static key, read from a file */ struct key_ctx_bi static_key; -#ifdef ENABLE_SSL /* our global SSL context */ struct tls_root_ctx ssl_ctx; /* optional authentication HMAC key for TLS control channel */ struct key_ctx_bi tls_auth_key; - -#endif /* ENABLE_SSL */ #else /* ENABLE_CRYPTO */ int dummy; #endif /* ENABLE_CRYPTO */ @@ -335,8 +332,6 @@ struct context_2 /* * TLS-mode crypto objects. */ -#ifdef ENABLE_SSL - struct tls_multi *tls_multi; /**< TLS state structure for this VPN * tunnel. */ @@ -357,8 +352,6 @@ struct context_2 /* throw this signal on TLS errors */ int tls_exit_signal; -#endif /* ENABLE_SSL */ - struct crypto_options crypto_options; /**< Security parameters and crypto state * used by the \link data_crypto Data @@ -564,7 +557,7 @@ struct context * have been compiled in. */ -#if defined(ENABLE_CRYPTO) && defined(ENABLE_SSL) +#ifdef ENABLE_CRYPTO #define TLS_MODE(c) ((c)->c2.tls_multi != NULL) #define PROTO_DUMP_FLAGS (check_debug_level (D_LINK_RW_VERBOSE) ? (PD_SHOW_DATA|PD_VERBOSE) : 0) #define PROTO_DUMP(buf, gc) protocol_dump((buf), \ diff --git a/app/openvpn/src/openvpn/options.c b/app/openvpn/src/openvpn/options.c index 763e2cbc..e2897984 100644 --- a/app/openvpn/src/openvpn/options.c +++ b/app/openvpn/src/openvpn/options.c @@ -68,7 +68,6 @@ const char title_string[] = #endif " " TARGET_ALIAS #ifdef ENABLE_CRYPTO -#ifdef ENABLE_SSL #if defined(ENABLE_CRYPTO_POLARSSL) " [SSL (PolarSSL)]" #elif defined(ENABLE_CRYPTO_OPENSSL) @@ -76,15 +75,6 @@ const char title_string[] = #else " [SSL]" #endif /* defined(ENABLE_CRYPTO_POLARSSL) */ -#else /* ! ENABLE_SSL */ -#if defined(ENABLE_CRYPTO_POLARSSL) - " [CRYPTO (PolarSSL)]" -#elif defined(ENABLE_CRYPTO_OPENSSL) - " [CRYPTO (OpenSSL)]" -#else - " [CRYPTO]" -#endif /* defined(ENABLE_CRYPTO_POLARSSL) */ -#endif /* ENABLE_SSL */ #endif /* ENABLE_CRYPTO */ #ifdef USE_COMP #ifdef ENABLE_LZO @@ -546,7 +536,6 @@ static const char usage_message[] = "--use-prediction-resistance: Enable prediction resistance on the random\n" " number generator.\n" #endif -#ifdef ENABLE_SSL "\n" "TLS Key Negotiation Options:\n" "(These options are meaningful only for TLS-mode)\n" @@ -631,7 +620,6 @@ static const char usage_message[] = "--remote-cert-tls t: Require that peer certificate was signed with explicit\n" " key usage and extended key usage based on RFC3280 TLS rules.\n" " t = 'client' | 'server'.\n" -#endif /* ENABLE_SSL */ #ifdef ENABLE_PKCS11 "\n" "PKCS#11 Options:\n" @@ -656,9 +644,7 @@ static const char usage_message[] = "--show-ciphers : Show cipher algorithms to use with --cipher option.\n" "--show-digests : Show message digest algorithms to use with --auth option.\n" "--show-engines : Show hardware crypto accelerator engines (if available).\n" -#ifdef ENABLE_SSL "--show-tls : Show all TLS ciphers (TLS used only as a control channel).\n" -#endif #ifdef WIN32 "\n" "Windows Specific:\n" @@ -736,7 +722,11 @@ static const char usage_message[] = #ifdef ENABLE_PKCS11 "\n" "PKCS#11 standalone options:\n" - "--show-pkcs11-ids provider [cert_private] : Show PKCS#11 available ids.\n" +#ifdef DEFAULT_PKCS11_MODULE + "--show-pkcs11-ids [provider] [cert_private] : Show PKCS#11 available ids.\n" +#else + "--show-pkcs11-ids provider [cert_private] : Show PKCS#11 available ids.\n" +#endif " --verb option can be added *BEFORE* this.\n" #endif /* ENABLE_PKCS11 */ "\n" @@ -840,7 +830,6 @@ init_options (struct options *o, const bool init_gc) #ifdef ENABLE_PREDICTION_RESISTANCE o->use_prediction_resistance = false; #endif -#ifdef ENABLE_SSL o->key_method = 2; o->tls_timeout = 2; o->renegotiate_seconds = 3600; @@ -850,7 +839,6 @@ init_options (struct options *o, const bool init_gc) #ifdef ENABLE_X509ALTUSERNAME o->x509_username_field = X509_USERNAME_FIELD_DEFAULT; #endif -#endif /* ENABLE_SSL */ #endif /* ENABLE_CRYPTO */ #ifdef ENABLE_PKCS11 o->pkcs11_pin_cache_period = -1; @@ -1041,7 +1029,7 @@ string_substitute (const char *src, int from, int to, struct gc_arena *gc) return ret; } -#ifdef ENABLE_SSL +#ifdef ENABLE_CRYPTO static uint8_t * parse_hash_fingerprint(const char *str, int nbytes, int msglevel, struct gc_arena *gc) { @@ -1420,11 +1408,9 @@ show_settings (const struct options *o) SHOW_BOOL (show_digests); SHOW_BOOL (show_engines); SHOW_BOOL (genkey); -#ifdef ENABLE_SSL SHOW_STR (key_pass_file); SHOW_BOOL (show_tls_ciphers); #endif -#endif SHOW_INT (connect_retry_max); show_connection_entries (o); @@ -1576,7 +1562,6 @@ show_settings (const struct options *o) SHOW_BOOL (use_prediction_resistance); #endif -#ifdef ENABLE_SSL SHOW_BOOL (tls_server); SHOW_BOOL (tls_client); SHOW_INT (key_method); @@ -1628,8 +1613,7 @@ show_settings (const struct options *o) SHOW_BOOL (tls_exit); SHOW_STR (tls_auth_file); -#endif -#endif +#endif /* ENABLE_CRYPTO */ #ifdef ENABLE_PKCS11 { @@ -1845,7 +1829,7 @@ options_postprocess_verify_ce (const struct options *options, const struct conne msg (M_USAGE, "--inetd nowait can only be used with --proto tcp-server"); if (options->inetd == INETD_NOWAIT -#if defined(ENABLE_CRYPTO) && defined(ENABLE_SSL) +#ifdef ENABLE_CRYPTO && !(options->tls_server || options->tls_client) #endif ) @@ -2138,16 +2122,10 @@ options_postprocess_verify_ce (const struct options *options, const struct conne /* * SSL/TLS mode sanity checks. */ - -#ifdef ENABLE_SSL if (options->tls_server + options->tls_client + (options->shared_secret_file != NULL) > 1) msg (M_USAGE, "specify only one of --tls-server, --tls-client, or --secret"); - if (options->tls_server) - { - notnull (options->dh_file, "DH file (--dh)"); - } if (options->tls_server || options->tls_client) { #ifdef ENABLE_PKCS11 @@ -2316,7 +2294,6 @@ options_postprocess_verify_ce (const struct options *options, const struct conne } #undef MUST_BE_UNDEF #endif /* ENABLE_CRYPTO */ -#endif /* ENABLE_SSL */ #if P2MP if (options->auth_user_pass_file && !options->pull) @@ -2439,6 +2416,15 @@ options_postprocess_mutate_invariant (struct options *options) #endif } #endif + +#ifdef DEFAULT_PKCS11_MODULE + /* If p11-kit is present on the system then load its p11-kit-proxy.so + by default if the user asks for PKCS#11 without otherwise specifying + the module to use. */ + if (!options->pkcs11_providers[0] && + (options->pkcs11_id || options->pkcs11_id_management)) + options->pkcs11_providers[0] = DEFAULT_PKCS11_MODULE; +#endif } static void @@ -2499,11 +2485,39 @@ options_postprocess_mutate (struct options *o) for (i = 0; i < o->connection_list->len; ++i) options_postprocess_mutate_ce (o, o->connection_list->array[i]); +#ifdef ENABLE_CRYPTO + if (o->tls_server) + { + /* Check that DH file is specified, or explicitly disabled */ + notnull (o->dh_file, "DH file (--dh)"); + if (streq (o->dh_file, "none")) + o->dh_file = NULL; + } +#endif + #if ENABLE_MANAGEMENT if (o->http_proxy_override) options_postprocess_http_proxy_override(o); #endif +#ifdef ENABLE_CRYPTOAPI + if (o->cryptoapi_cert) + { + const int tls_version_max = + (o->ssl_flags >> SSLF_TLS_VERSION_MAX_SHIFT) & + SSLF_TLS_VERSION_MAX_MASK; + + if (tls_version_max == TLS_VER_UNSPEC || tls_version_max > TLS_VER_1_1) + { + msg(M_WARN, "Warning: cryptapicert used, setting maximum TLS " + "version to 1.1."); + o->ssl_flags &= ~(SSLF_TLS_VERSION_MAX_MASK << + SSLF_TLS_VERSION_MAX_SHIFT); + o->ssl_flags |= (TLS_VER_1_1 << SSLF_TLS_VERSION_MAX_SHIFT); + } + } +#endif /* ENABLE_CRYPTOAPI */ + #if P2MP /* * Save certain parms before modifying options via --pull @@ -2668,8 +2682,8 @@ options_postprocess_filechecks (struct options *options) { bool errs = false; +#ifdef ENABLE_CRYPTO /* ** SSL/TLS/crypto related files ** */ -#ifdef ENABLE_SSL errs |= check_file_access (CHKACC_FILE|CHKACC_INLINE, options->dh_file, R_OK, "--dh"); errs |= check_file_access (CHKACC_FILE|CHKACC_INLINE, options->ca_file, R_OK, "--ca"); errs |= check_file_access_chroot (options->chroot_dir, CHKACC_FILE, options->ca_path, R_OK, "--capath"); @@ -2693,20 +2707,15 @@ options_postprocess_filechecks (struct options *options) errs |= check_file_access (CHKACC_FILE|CHKACC_INLINE, options->tls_auth_file, R_OK, "--tls-auth"); -#endif /* ENABLE_SSL */ -#ifdef ENABLE_CRYPTO errs |= check_file_access (CHKACC_FILE|CHKACC_INLINE, options->shared_secret_file, R_OK, "--secret"); errs |= check_file_access (CHKACC_DIRPATH|CHKACC_FILEXSTWR, options->packet_id_file, R_OK|W_OK, "--replay-persist"); -#endif /* ENABLE_CRYPTO */ - /* ** Password files ** */ -#ifdef ENABLE_SSL errs |= check_file_access (CHKACC_FILE, options->key_pass_file, R_OK, "--askpass"); -#endif /* ENABLE_SSL */ +#endif /* ENABLE_CRYPTO */ #ifdef ENABLE_MANAGEMENT errs |= check_file_access (CHKACC_FILE|CHKACC_ACPTSTDIN, options->management_user_pass, R_OK, @@ -2729,10 +2738,10 @@ options_postprocess_filechecks (struct options *options) R_OK|W_OK, "--status"); /* ** Config related ** */ -#ifdef ENABLE_SSL +#ifdef ENABLE_CRYPTO errs |= check_file_access_chroot (options->chroot_dir, CHKACC_FILE, options->tls_export_cert, R_OK|W_OK|X_OK, "--tls-export-cert"); -#endif /* ENABLE_SSL */ +#endif /* ENABLE_CRYPTO */ #if P2MP_SERVER errs |= check_file_access_chroot (options->chroot_dir, CHKACC_FILE, options->client_config_dir, R_OK|X_OK, "--client-config-dir"); @@ -2957,13 +2966,8 @@ options_string (const struct options *o, #ifdef ENABLE_CRYPTO -#ifdef ENABLE_SSL #define TLS_CLIENT (o->tls_client) #define TLS_SERVER (o->tls_server) -#else -#define TLS_CLIENT (false) -#define TLS_SERVER (false) -#endif /* * Key direction @@ -3006,7 +3010,6 @@ options_string (const struct options *o, #endif } -#ifdef ENABLE_SSL /* * SSL Options */ @@ -3035,7 +3038,6 @@ options_string (const struct options *o, buf_printf (&out, ",tls-server"); } } -#endif /* ENABLE_SSL */ #undef TLS_CLIENT #undef TLS_SERVER @@ -3358,7 +3360,7 @@ usage (void) struct options o; init_options (&o, true); -#if defined(ENABLE_CRYPTO) && defined(ENABLE_SSL) +#ifdef ENABLE_CRYPTO fprintf (fp, usage_message, title_string, o.ce.connect_retry_seconds, @@ -3369,15 +3371,6 @@ usage (void) o.replay_window, o.replay_time, o.tls_timeout, o.renegotiate_seconds, o.handshake_window, o.transition_window); -#elif defined(ENABLE_CRYPTO) - fprintf (fp, usage_message, - title_string, - o.ce.connect_retry_seconds, - o.ce.local_port, o.ce.remote_port, - TUN_MTU_DEFAULT, TAP_MTU_EXTRA_DEFAULT, - o.verbosity, - o.authname, o.ciphername, - o.replay_window, o.replay_time); #else fprintf (fp, usage_message, title_string, @@ -3403,7 +3396,7 @@ usage_small (void) void show_library_versions(const unsigned int flags) { -#ifdef ENABLE_SSL +#ifdef ENABLE_CRYPTO #define SSL_LIB_VER_STR get_ssl_library_version() #else #define SSL_LIB_VER_STR "" @@ -6470,7 +6463,6 @@ add_option (struct options *options, options->use_prediction_resistance = true; } #endif -#ifdef ENABLE_SSL else if (streq (p[0], "show-tls")) { VERIFY_PERMISSION (OPT_P_GENERAL); @@ -6907,14 +6899,36 @@ add_option (struct options *options, options->x509_username_field = p[1]; } #endif /* ENABLE_X509ALTUSERNAME */ -#endif /* ENABLE_SSL */ #endif /* ENABLE_CRYPTO */ #ifdef ENABLE_PKCS11 - else if (streq (p[0], "show-pkcs11-ids") && p[1]) + else if (streq (p[0], "show-pkcs11-ids")) { char *provider = p[1]; bool cert_private = (p[2] == NULL ? false : ( atoi (p[2]) != 0 )); +#ifdef DEFAULT_PKCS11_MODULE + if (!provider) + provider = DEFAULT_PKCS11_MODULE; + else if (!p[2]) + { + char *endp = NULL; + int i = strtol(provider, &endp, 10); + + if (*endp == 0) + { + /* There was one argument, and it was purely numeric. + Interpret it as the cert_private argument */ + provider = DEFAULT_PKCS11_MODULE; + cert_private = i; + } + } +#else + if (!provider) + { + msg (msglevel, "--show-pkcs11-ids requires a provider parameter"); + goto err; + } +#endif VERIFY_PERMISSION (OPT_P_GENERAL); set_debug_level (options->verbosity, SDL_CONSTRAIN); diff --git a/app/openvpn/src/openvpn/options.h b/app/openvpn/src/openvpn/options.h index a51b8ab5..4e49208b 100644 --- a/app/openvpn/src/openvpn/options.h +++ b/app/openvpn/src/openvpn/options.h @@ -193,10 +193,8 @@ struct options bool show_ciphers; bool show_digests; bool show_engines; -#ifdef ENABLE_SSL bool show_tls_ciphers; bool show_curves; -#endif bool genkey; #endif @@ -493,7 +491,6 @@ struct options bool use_prediction_resistance; #endif -#ifdef ENABLE_SSL /* TLS (control channel) parms */ bool tls_server; bool tls_client; @@ -575,7 +572,6 @@ struct options bool tls_exit; -#endif /* ENABLE_SSL */ #endif /* ENABLE_CRYPTO */ #ifdef ENABLE_X509_TRACK diff --git a/app/openvpn/src/openvpn/plugin.c b/app/openvpn/src/openvpn/plugin.c index 54c5b52d..60dd2ee7 100644 --- a/app/openvpn/src/openvpn/plugin.c +++ b/app/openvpn/src/openvpn/plugin.c @@ -420,7 +420,7 @@ plugin_call_item (const struct plugin *p, const struct argv *av, struct openvpn_plugin_string_list **retlist, const char **envp -#ifdef ENABLE_SSL +#ifdef ENABLE_CRYPTO , int certdepth, openvpn_x509_cert_t *current_cert #endif @@ -449,7 +449,7 @@ plugin_call_item (const struct plugin *p, (const char ** const) envp, p->plugin_handle, per_client_context, -#ifdef ENABLE_SSL +#ifdef ENABLE_CRYPTO (current_cert ? certdepth : -1), current_cert #else @@ -659,7 +659,7 @@ plugin_call_ssl (const struct plugin_list *pl, const struct argv *av, struct plugin_return *pr, struct env_set *es -#ifdef ENABLE_SSL +#ifdef ENABLE_CRYPTO , int certdepth, openvpn_x509_cert_t *current_cert #endif @@ -689,7 +689,7 @@ plugin_call_ssl (const struct plugin_list *pl, av, pr ? &pr->list[i] : NULL, envp -#ifdef ENABLE_SSL +#ifdef ENABLE_CRYPTO ,certdepth, current_cert #endif diff --git a/app/openvpn/src/openvpn/plugin.h b/app/openvpn/src/openvpn/plugin.h index 2f8416b1..77b6e818 100644 --- a/app/openvpn/src/openvpn/plugin.h +++ b/app/openvpn/src/openvpn/plugin.h @@ -127,7 +127,7 @@ int plugin_call_ssl (const struct plugin_list *pl, const struct argv *av, struct plugin_return *pr, struct env_set *es -#ifdef ENABLE_SSL +#ifdef ENABLE_CRYPTO , int current_cert_depth, openvpn_x509_cert_t *current_cert #endif @@ -183,7 +183,7 @@ plugin_call_ssl (const struct plugin_list *pl, const struct argv *av, struct plugin_return *pr, struct env_set *es -#ifdef ENABLE_SSL +#ifdef ENABLE_CRYPTO , int current_cert_depth, openvpn_x509_cert_t *current_cert #endif @@ -202,7 +202,7 @@ plugin_call(const struct plugin_list *pl, struct env_set *es) { return plugin_call_ssl(pl, type, av, pr, es -#ifdef ENABLE_SSL +#ifdef ENABLE_CRYPTO , -1, NULL #endif ); diff --git a/app/openvpn/src/openvpn/reliable.c b/app/openvpn/src/openvpn/reliable.c index 763169ed..22883a72 100644 --- a/app/openvpn/src/openvpn/reliable.c +++ b/app/openvpn/src/openvpn/reliable.c @@ -35,7 +35,7 @@ #include "syshead.h" -#if defined(ENABLE_CRYPTO) && defined(ENABLE_SSL) +#ifdef ENABLE_CRYPTO #include "buffer.h" #include "error.h" @@ -754,4 +754,4 @@ reliable_debug_print (const struct reliable *rel, char *desc) #else static void dummy(void) {} -#endif /* ENABLE_CRYPTO && ENABLE_SSL*/ +#endif /* ENABLE_CRYPTO */ diff --git a/app/openvpn/src/openvpn/reliable.h b/app/openvpn/src/openvpn/reliable.h index 594ab825..828dcd3c 100644 --- a/app/openvpn/src/openvpn/reliable.h +++ b/app/openvpn/src/openvpn/reliable.h @@ -29,7 +29,7 @@ */ -#if defined(ENABLE_CRYPTO) && defined(ENABLE_SSL) +#ifdef ENABLE_CRYPTO #ifndef RELIABLE_H #define RELIABLE_H @@ -477,4 +477,4 @@ void reliable_ack_debug_print (const struct reliable_ack *ack, char *desc); #endif /* RELIABLE_H */ -#endif /* ENABLE_CRYPTO && ENABLE_SSL */ +#endif /* ENABLE_CRYPTO */ diff --git a/app/openvpn/src/openvpn/route.c b/app/openvpn/src/openvpn/route.c index 1cb98c03..8137e343 100644 --- a/app/openvpn/src/openvpn/route.c +++ b/app/openvpn/src/openvpn/route.c @@ -2648,7 +2648,7 @@ get_default_gateway (struct route_gateway_info *rgi) gc_free (&gc); } -#elif defined(TARGET_DARWIN) || \ +#elif defined(TARGET_DARWIN) || defined(TARGET_SOLARIS) || \ defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY) || \ defined(TARGET_OPENBSD) || defined(TARGET_NETBSD) @@ -2683,12 +2683,21 @@ struct rtmsg { ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long)) #endif +#if defined(TARGET_SOLARIS) +#define NEXTADDR(w, u) \ + if (rtm_addrs & (w)) {\ + l = ROUNDUP(sizeof(struct sockaddr_in)); memmove(cp, &(u), l); cp += l;\ + } + +#define ADVANCE(x, n) (x += ROUNDUP(sizeof(struct sockaddr_in))) +#else #define NEXTADDR(w, u) \ if (rtm_addrs & (w)) {\ l = ROUNDUP(u.sa_len); memmove(cp, &(u), l); cp += l;\ } #define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len)) +#endif #define max(a,b) ((a) > (b) ? (a) : (b)) @@ -2725,9 +2734,12 @@ get_default_gateway (struct route_gateway_info *rgi) rtm.rtm_addrs = rtm_addrs; so_dst.sa_family = AF_INET; - so_dst.sa_len = sizeof(struct sockaddr_in); so_mask.sa_family = AF_INET; + +#ifndef TARGET_SOLARIS + so_dst.sa_len = sizeof(struct sockaddr_in); so_mask.sa_len = sizeof(struct sockaddr_in); +#endif NEXTADDR(RTA_DST, so_dst); NEXTADDR(RTA_NETMASK, so_mask); @@ -2851,7 +2863,12 @@ get_default_gateway (struct route_gateway_info *rgi) for (cp = buffer; cp <= buffer + ifc.ifc_len - sizeof(struct ifreq); ) { ifr = (struct ifreq *)cp; +#if defined(TARGET_SOLARIS) + const size_t len = sizeof(ifr->ifr_name) + sizeof(ifr->ifr_addr); +#else const size_t len = sizeof(ifr->ifr_name) + max(sizeof(ifr->ifr_addr), ifr->ifr_addr.sa_len); +#endif + if (!ifr->ifr_addr.sa_family) break; if (!strncmp(ifr->ifr_name, rgi->iface, IFNAMSIZ)) diff --git a/app/openvpn/src/openvpn/session_id.c b/app/openvpn/src/openvpn/session_id.c index 2e07b547..0ebff657 100644 --- a/app/openvpn/src/openvpn/session_id.c +++ b/app/openvpn/src/openvpn/session_id.c @@ -39,7 +39,7 @@ #include "syshead.h" -#if defined(ENABLE_CRYPTO) && defined(ENABLE_SSL) +#ifdef ENABLE_CRYPTO #include "error.h" #include "common.h" @@ -64,4 +64,4 @@ session_id_print (const struct session_id *sid, struct gc_arena *gc) #else static void dummy(void) {} -#endif /* ENABLE_CRYPTO && ENABLE_SSL*/ +#endif /* ENABLE_CRYPTO */ diff --git a/app/openvpn/src/openvpn/session_id.h b/app/openvpn/src/openvpn/session_id.h index 33909dd4..2a1f41fd 100644 --- a/app/openvpn/src/openvpn/session_id.h +++ b/app/openvpn/src/openvpn/session_id.h @@ -30,7 +30,7 @@ * negotiated). */ -#if defined(ENABLE_CRYPTO) && defined(ENABLE_SSL) +#ifdef ENABLE_CRYPTO #ifndef SESSION_ID_H #define SESSION_ID_H @@ -83,4 +83,4 @@ void session_id_random (struct session_id *sid); const char *session_id_print (const struct session_id *sid, struct gc_arena *gc); #endif /* SESSION_ID_H */ -#endif /* ENABLE_CRYPTO && ENABLE_SSL */ +#endif /* ENABLE_CRYPTO */ diff --git a/app/openvpn/src/openvpn/ssl.c b/app/openvpn/src/openvpn/ssl.c index cdc8eb19..80293efd 100644 --- a/app/openvpn/src/openvpn/ssl.c +++ b/app/openvpn/src/openvpn/ssl.c @@ -43,7 +43,7 @@ #include "syshead.h" -#if defined(ENABLE_CRYPTO) && defined(ENABLE_SSL) +#if defined(ENABLE_CRYPTO) #include "error.h" #include "common.h" @@ -242,6 +242,7 @@ static const tls_cipher_name_pair tls_cipher_name_translation_table[] = { {"EDH", "EDH"}, {"EXP", "EXP"}, {"RSA", "RSA"}, + {"kRSA", "kRSA"}, {"SRP", "SRP"}, #endif {NULL, NULL} @@ -263,16 +264,14 @@ tls_get_cipher_name_pair (const char * cipher_name, size_t len) { return NULL; } -/* - * Max number of bytes we will add - * for data structures common to both - * data and control channel packets. - * (opcode only). +/** + * Max number of bytes we will add for data structures common to both data and + * control channel packets (1 byte opcode + 3 bytes peer-id). */ void tls_adjust_frame_parameters(struct frame *frame) { - frame_add_to_extra_frame (frame, 1); /* space for opcode */ + frame_add_to_extra_frame (frame, 1 + 3); /* space for opcode + peer-id */ } /* @@ -483,7 +482,10 @@ init_ssl (const struct options *options, struct tls_root_ctx *new_ctx) if (options->tls_server) { tls_ctx_server_new(new_ctx); - tls_ctx_load_dh_params(new_ctx, options->dh_file, options->dh_file_inline); + + if (options->dh_file) + tls_ctx_load_dh_params(new_ctx, options->dh_file, + options->dh_file_inline); } else /* if client */ { @@ -3625,4 +3627,4 @@ done: #else static void dummy(void) {} -#endif /* ENABLE_CRYPTO && ENABLE_SSL*/ +#endif /* ENABLE_CRYPTO */ diff --git a/app/openvpn/src/openvpn/ssl.h b/app/openvpn/src/openvpn/ssl.h index 7e5a203e..797c3e5d 100644 --- a/app/openvpn/src/openvpn/ssl.h +++ b/app/openvpn/src/openvpn/ssl.h @@ -30,7 +30,7 @@ #ifndef OPENVPN_SSL_H #define OPENVPN_SSL_H -#if defined(ENABLE_CRYPTO) && defined(ENABLE_SSL) +#if defined(ENABLE_CRYPTO) #include "basic.h" #include "common.h" @@ -512,6 +512,6 @@ void show_tls_performance_stats(void); /*#define EXTRACT_X509_FIELD_TEST*/ void extract_x509_field_test (void); -#endif /* ENABLE_CRYPTO && ENABLE_SSL */ +#endif /* ENABLE_CRYPTO */ #endif diff --git a/app/openvpn/src/openvpn/ssl_openssl.c b/app/openvpn/src/openvpn/ssl_openssl.c index 6782a953..48c05715 100644 --- a/app/openvpn/src/openvpn/ssl_openssl.c +++ b/app/openvpn/src/openvpn/ssl_openssl.c @@ -35,7 +35,7 @@ #include "syshead.h" -#if defined(ENABLE_SSL) && defined(ENABLE_CRYPTO_OPENSSL) +#if defined(ENABLE_CRYPTO) && defined(ENABLE_CRYPTO_OPENSSL) #include "errlevel.h" #include "buffer.h" @@ -104,7 +104,7 @@ tls_ctx_server_new(struct tls_root_ctx *ctx) 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"); } void @@ -115,7 +115,7 @@ tls_ctx_client_new(struct tls_root_ctx *ctx) 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 @@ -234,8 +234,8 @@ tls_ctx_restrict_ciphers(struct tls_root_ctx *ctx, const char *ciphers) if (ciphers == NULL) { /* Use sane default (disable export, and unsupported cipher modes) */ - if(!SSL_CTX_set_cipher_list(ctx->ctx, "DEFAULT:!EXP:!PSK:!SRP")) - msg(M_SSLERR, "Failed to set default TLS cipher list."); + if(!SSL_CTX_set_cipher_list(ctx->ctx, "DEFAULT:!EXP:!PSK:!SRP:!kRSA")) + crypto_msg (M_FATAL, "Failed to set default TLS cipher list."); return; } @@ -287,9 +287,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); @@ -305,7 +308,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 @@ -321,22 +324,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)); @@ -405,7 +408,7 @@ tls_ctx_load_ecdh_params (struct tls_root_ctx *ctx, const char *curve_name } if (!SSL_CTX_set_tmp_ecdh(ctx->ctx, ecdh)) - msg (M_SSLERR, "SSL_CTX_set_tmp_ecdh: cannot add curve"); + crypto_msg (M_FATAL, "SSL_CTX_set_tmp_ecdh: cannot add curve"); msg (D_TLS_DEBUG_LOW, "ECDH curve %s added", sname); @@ -441,7 +444,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); } @@ -449,11 +452,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 */ @@ -476,16 +479,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) @@ -499,9 +502,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 { @@ -515,7 +518,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)"); } } } @@ -530,8 +533,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 */ @@ -545,9 +547,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"); } } @@ -595,9 +597,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) @@ -655,14 +657,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: @@ -813,7 +815,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; } @@ -843,7 +845,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) @@ -866,7 +868,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) @@ -901,9 +903,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; } @@ -915,12 +920,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) @@ -934,7 +947,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); X509_STORE_set_flags (store, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL); } } @@ -951,7 +964,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); @@ -1043,7 +1056,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; } @@ -1077,16 +1090,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 (); } @@ -1152,8 +1164,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 (); @@ -1183,7 +1194,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*/ @@ -1358,11 +1369,11 @@ 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"); tls_ctx_restrict_ciphers(&tls_ctx, cipher_list); @@ -1403,7 +1414,7 @@ show_available_curves() curves = OPENSSL_malloc((int)(sizeof(EC_builtin_curve) * crv_len)); if (curves == NULL) - msg (M_SSLERR, "Cannot create EC_builtin_curve object"); + crypto_msg (M_FATAL, "Cannot create EC_builtin_curve object"); else { if (EC_get_builtin_curves(curves, crv_len)) @@ -1420,7 +1431,7 @@ show_available_curves() } else { - msg (M_SSLERR, "Cannot get list of builtin curves"); + crypto_msg (M_FATAL, "Cannot get list of builtin curves"); } OPENSSL_free(curves); } @@ -1439,10 +1450,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); @@ -1457,4 +1468,4 @@ get_ssl_library_version(void) return SSLeay_version(SSLEAY_VERSION); } -#endif /* defined(ENABLE_SSL) && defined(ENABLE_CRYPTO_OPENSSL) */ +#endif /* defined(ENABLE_CRYPTO) && defined(ENABLE_CRYPTO_OPENSSL) */ diff --git a/app/openvpn/src/openvpn/ssl_polarssl.c b/app/openvpn/src/openvpn/ssl_polarssl.c index 20368857..8cb328e7 100644 --- a/app/openvpn/src/openvpn/ssl_polarssl.c +++ b/app/openvpn/src/openvpn/ssl_polarssl.c @@ -36,7 +36,7 @@ #include "syshead.h" -#if defined(ENABLE_SSL) && defined(ENABLE_CRYPTO_POLARSSL) +#if defined(ENABLE_CRYPTO) && defined(ENABLE_CRYPTO_POLARSSL) #include "errlevel.h" #include "ssl_backend.h" @@ -1171,4 +1171,4 @@ get_ssl_library_version(void) return polar_version; } -#endif /* defined(ENABLE_SSL) && defined(ENABLE_CRYPTO_POLARSSL) */ +#endif /* defined(ENABLE_CRYPTO) && defined(ENABLE_CRYPTO_POLARSSL) */ diff --git a/app/openvpn/src/openvpn/ssl_verify.c b/app/openvpn/src/openvpn/ssl_verify.c index 2d10d155..ad50458b 100644 --- a/app/openvpn/src/openvpn/ssl_verify.c +++ b/app/openvpn/src/openvpn/ssl_verify.c @@ -35,7 +35,7 @@ #include "syshead.h" -#if defined(ENABLE_CRYPTO) && defined(ENABLE_SSL) +#ifdef ENABLE_CRYPTO #include "misc.h" #include "manage.h" @@ -238,7 +238,7 @@ cert_hash_free (struct cert_hash_set *chs) } } -static bool +bool cert_hash_compare (const struct cert_hash_set *chs1, const struct cert_hash_set *chs2) { if (chs1 && chs2) @@ -1268,4 +1268,4 @@ verify_final_auth_checks(struct tls_multi *multi, struct tls_session *session) gc_free (&gc); } } -#endif /* defined(ENABLE_CRYPTO) && defined(ENABLE_SSL) */ +#endif /* ENABLE_CRYPTO */ diff --git a/app/openvpn/src/openvpn/ssl_verify.h b/app/openvpn/src/openvpn/ssl_verify.h index 84554f89..d5bf22e5 100644 --- a/app/openvpn/src/openvpn/ssl_verify.h +++ b/app/openvpn/src/openvpn/ssl_verify.h @@ -30,7 +30,7 @@ #ifndef SSL_VERIFY_H_ #define SSL_VERIFY_H_ -#if defined(ENABLE_CRYPTO) && defined(ENABLE_SSL) +#ifdef ENABLE_CRYPTO #include "syshead.h" #include "misc.h" @@ -137,6 +137,14 @@ const char *tls_common_name (const struct tls_multi* multi, const bool null); */ const char *tls_username (const struct tls_multi *multi, const bool null); +/** + * Compares certificates hashes, returns true if hashes are equal. + * + * @param chs1 cert 1 hash set + * @param chs2 cert 2 hash set + */ +bool cert_hash_compare (const struct cert_hash_set *chs1, const struct cert_hash_set *chs2); + #ifdef ENABLE_PF /** @@ -236,6 +244,6 @@ tls_client_reason (struct tls_multi *multi) #endif } -#endif /* defined(ENABLE_CRYPTO) && defined(ENABLE_SSL) */ +#endif /* ENABLE_CRYPTO */ #endif /* SSL_VERIFY_H_ */ diff --git a/app/openvpn/src/openvpn/ssl_verify_openssl.c b/app/openvpn/src/openvpn/ssl_verify_openssl.c index 33cd757d..0348e98a 100644 --- a/app/openvpn/src/openvpn/ssl_verify_openssl.c +++ b/app/openvpn/src/openvpn/ssl_verify_openssl.c @@ -35,7 +35,7 @@ #include "syshead.h" -#if defined(ENABLE_SSL) && defined(ENABLE_CRYPTO_OPENSSL) +#if defined(ENABLE_CRYPTO) && defined(ENABLE_CRYPTO_OPENSSL) #include "ssl_verify_openssl.h" @@ -625,4 +625,4 @@ end: return retval; } -#endif /* defined(ENABLE_SSL) && defined(ENABLE_CRYPTO_OPENSSL) */ +#endif /* defined(ENABLE_CRYPTO) && defined(ENABLE_CRYPTO_OPENSSL) */ diff --git a/app/openvpn/src/openvpn/ssl_verify_polarssl.c b/app/openvpn/src/openvpn/ssl_verify_polarssl.c index 2b7c214f..e21301d3 100644 --- a/app/openvpn/src/openvpn/ssl_verify_polarssl.c +++ b/app/openvpn/src/openvpn/ssl_verify_polarssl.c @@ -35,7 +35,7 @@ #include "syshead.h" -#if defined(ENABLE_SSL) && defined(ENABLE_CRYPTO_POLARSSL) +#if defined(ENABLE_CRYPTO) && defined(ENABLE_CRYPTO_POLARSSL) #include "ssl_verify.h" #include <polarssl/error.h> @@ -403,4 +403,4 @@ end: return retval; } -#endif /* #if defined(ENABLE_SSL) && defined(ENABLE_CRYPTO_POLARSSL) */ +#endif /* #if defined(ENABLE_CRYPTO) && defined(ENABLE_CRYPTO_POLARSSL) */ diff --git a/app/openvpn/src/openvpn/syshead.h b/app/openvpn/src/openvpn/syshead.h index dc511cbc..8c509405 100644 --- a/app/openvpn/src/openvpn/syshead.h +++ b/app/openvpn/src/openvpn/syshead.h @@ -517,7 +517,7 @@ socket_defined (const socket_descriptor_t sd) * Do we have point-to-multipoint capability? */ -#if defined(ENABLE_CLIENT_SERVER) && defined(ENABLE_CRYPTO) && defined(ENABLE_SSL) && defined(HAVE_GETTIMEOFDAY_NANOSECONDS) +#if defined(ENABLE_CLIENT_SERVER) && defined(ENABLE_CRYPTO) && defined(HAVE_GETTIMEOFDAY_NANOSECONDS) #define P2MP 1 #else #define P2MP 0 @@ -554,7 +554,7 @@ socket_defined (const socket_descriptor_t sd) /* * Enable external private key */ -#if defined(ENABLE_MANAGEMENT) && defined(ENABLE_SSL) +#if defined(ENABLE_MANAGEMENT) && defined(ENABLE_CRYPTO) #define MANAGMENT_EXTERNAL_KEY #endif @@ -621,14 +621,14 @@ socket_defined (const socket_descriptor_t sd) /* * Do we have CryptoAPI capability? */ -#if defined(WIN32) && defined(ENABLE_CRYPTO) && defined(ENABLE_SSL) && defined(ENABLE_CRYPTO_OPENSSL) +#if defined(WIN32) && defined(ENABLE_CRYPTO) && defined(ENABLE_CRYPTO_OPENSSL) #define ENABLE_CRYPTOAPI #endif /* * Enable x509-track feature? */ -#if defined(ENABLE_CRYPTO) && defined(ENABLE_SSL) && defined (ENABLE_CRYPTO_OPENSSL) +#if defined(ENABLE_CRYPTO) && defined (ENABLE_CRYPTO_OPENSSL) #define ENABLE_X509_TRACK #endif @@ -697,7 +697,7 @@ socket_defined (const socket_descriptor_t sd) /* * Do we support pushing peer info? */ -#if defined(ENABLE_CRYPTO) && defined(ENABLE_SSL) +#if defined(ENABLE_CRYPTO) #define ENABLE_PUSH_PEER_INFO #endif diff --git a/app/src/main/java/de/blinkt/openvpn/core/ConfigParser.java b/app/src/main/java/de/blinkt/openvpn/core/ConfigParser.java index 5dc96bbc..5f5d486c 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/ConfigParser.java +++ b/app/src/main/java/de/blinkt/openvpn/core/ConfigParser.java @@ -28,11 +28,11 @@ import de.blinkt.openvpn.VpnProfile; public class ConfigParser { - public static final String CONVERTED_PROFILE = "converted Profile"; - private HashMap<String, Vector<Vector<String>>> options = new HashMap<String, Vector<Vector<String>>>(); - private HashMap<String, Vector<String>> meta = new HashMap<String, Vector<String>>(); + public static final String CONVERTED_PROFILE = "converted Profile"; + private HashMap<String, Vector<Vector<String>>> options = new HashMap<String, Vector<Vector<String>>>(); + private HashMap<String, Vector<String>> meta = new HashMap<String, Vector<String>>(); - public void parseConfig(Reader reader) throws IOException, ConfigParseError { + public void parseConfig(Reader reader) throws IOException, ConfigParseError { BufferedReader br = new BufferedReader(reader); @@ -75,192 +75,176 @@ public class ConfigParser { } catch (java.lang.OutOfMemoryError memoryError) { throw new ConfigParseError("File too large to parse: " + memoryError.getLocalizedMessage()); } - } + } - private Vector<String> parsemeta(String line) { - String meta = line.split("#\\sOVPN_ACCESS_SERVER_", 2)[1]; - String[] parts = meta.split("=",2); - Vector<String> rval = new Vector<String>(); + private Vector<String> parsemeta(String line) { + String meta = line.split("#\\sOVPN_ACCESS_SERVER_", 2)[1]; + String[] parts = meta.split("=", 2); + Vector<String> rval = new Vector<String>(); Collections.addAll(rval, parts); - return rval; - - } - - private void checkinlinefile(Vector<String> args, BufferedReader br) throws IOException, ConfigParseError { - String arg0 = args.get(0).trim(); - // CHeck for <foo> - if(arg0.startsWith("<") && arg0.endsWith(">")) { - String argname = arg0.substring(1, arg0.length()-1); - String inlinefile = VpnProfile.INLINE_TAG; - - String endtag = String.format("</%s>",argname); - do { - String line = br.readLine(); - if(line==null){ - throw new ConfigParseError(String.format("No endtag </%s> for starttag <%s> found",argname,argname)); - } - if(line.trim().equals(endtag)) - break; - else { - inlinefile+=line; - inlinefile+= "\n"; - } - } while(true); - - args.clear(); - args.add(argname); - args.add(inlinefile); - } - - } - - enum linestate { - initial, - readin_single_quote - , reading_quoted, reading_unquoted, done} - - private boolean space(char c) { - // I really hope nobody is using zero bytes inside his/her config file - // to sperate parameter but here we go: - return Character.isWhitespace(c) || c == '\0'; - - } - - public class ConfigParseError extends Exception { - private static final long serialVersionUID = -60L; - - public ConfigParseError(String msg) { - super(msg); - } - } - - - // adapted openvpn's parse function to java - private Vector<String> parseline(String line) throws ConfigParseError { - Vector<String> parameters = new Vector<String>(); - - if (line.length()==0) - return parameters; - - - linestate state = linestate.initial; - boolean backslash = false; - char out=0; - - int pos=0; - String currentarg=""; - - do { - // Emulate the c parsing ... - char in; - if(pos < line.length()) - in = line.charAt(pos); - else - in = '\0'; - - if (!backslash && in == '\\' && state != linestate.readin_single_quote) - { - backslash = true; - } - else - { - if (state == linestate.initial) - { - if (!space (in)) - { - if (in == ';' || in == '#') /* comment */ - break; - if (!backslash && in == '\"') - state = linestate.reading_quoted; - else if (!backslash && in == '\'') - state = linestate.readin_single_quote; - else - { - out = in; - state = linestate.reading_unquoted; - } - } - } - else if (state == linestate.reading_unquoted) - { - if (!backslash && space (in)) - state = linestate.done; - else - out = in; - } - else if (state == linestate.reading_quoted) - { - if (!backslash && in == '\"') - state = linestate.done; - else - out = in; - } - else if (state == linestate.readin_single_quote) - { - if (in == '\'') - state = linestate.done; - else - out = in; - } - - if (state == linestate.done) - { - /* ASSERT (parm_len > 0); */ - state = linestate.initial; - parameters.add(currentarg); - currentarg = ""; - out =0; - } - - if (backslash && out!=0) - { - if (!(out == '\\' || out == '\"' || space (out))) - { - throw new ConfigParseError("Options warning: Bad backslash ('\\') usage"); - } - } - backslash = false; - } + return rval; + + } + + private void checkinlinefile(Vector<String> args, BufferedReader br) throws IOException, ConfigParseError { + String arg0 = args.get(0).trim(); + // CHeck for <foo> + if (arg0.startsWith("<") && arg0.endsWith(">")) { + String argname = arg0.substring(1, arg0.length() - 1); + String inlinefile = VpnProfile.INLINE_TAG; + + String endtag = String.format("</%s>", argname); + do { + String line = br.readLine(); + if (line == null) { + throw new ConfigParseError(String.format("No endtag </%s> for starttag <%s> found", argname, argname)); + } + if (line.trim().equals(endtag)) + break; + else { + inlinefile += line; + inlinefile += "\n"; + } + } while (true); + + args.clear(); + args.add(argname); + args.add(inlinefile); + } + + } + + enum linestate { + initial, + readin_single_quote, reading_quoted, reading_unquoted, done + } + + private boolean space(char c) { + // I really hope nobody is using zero bytes inside his/her config file + // to sperate parameter but here we go: + return Character.isWhitespace(c) || c == '\0'; + + } + + public class ConfigParseError extends Exception { + private static final long serialVersionUID = -60L; + + public ConfigParseError(String msg) { + super(msg); + } + } + + + // adapted openvpn's parse function to java + private Vector<String> parseline(String line) throws ConfigParseError { + Vector<String> parameters = new Vector<String>(); + + if (line.length() == 0) + return parameters; + + + linestate state = linestate.initial; + boolean backslash = false; + char out = 0; + + int pos = 0; + String currentarg = ""; + + do { + // Emulate the c parsing ... + char in; + if (pos < line.length()) + in = line.charAt(pos); + else + in = '\0'; + + if (!backslash && in == '\\' && state != linestate.readin_single_quote) { + backslash = true; + } else { + if (state == linestate.initial) { + if (!space(in)) { + if (in == ';' || in == '#') /* comment */ + break; + if (!backslash && in == '\"') + state = linestate.reading_quoted; + else if (!backslash && in == '\'') + state = linestate.readin_single_quote; + else { + out = in; + state = linestate.reading_unquoted; + } + } + } else if (state == linestate.reading_unquoted) { + if (!backslash && space(in)) + state = linestate.done; + else + out = in; + } else if (state == linestate.reading_quoted) { + if (!backslash && in == '\"') + state = linestate.done; + else + out = in; + } else if (state == linestate.readin_single_quote) { + if (in == '\'') + state = linestate.done; + else + out = in; + } + + if (state == linestate.done) { + /* ASSERT (parm_len > 0); */ + state = linestate.initial; + parameters.add(currentarg); + currentarg = ""; + out = 0; + } + + if (backslash && out != 0) { + if (!(out == '\\' || out == '\"' || space(out))) { + throw new ConfigParseError("Options warning: Bad backslash ('\\') usage"); + } + } + backslash = false; + } /* store parameter character */ - if (out!=0) - { - currentarg+=out; - } - } while (pos++ < line.length()); - - return parameters; - } - - - final String[] unsupportedOptions = { "config", - "tls-server" - - }; - - // Ignore all scripts - // in most cases these won't work and user who wish to execute scripts will - // figure out themselves - final String[] ignoreOptions = { "tls-client", - "askpass", - "auth-nocache", - "up", - "down", - "route-up", - "ipchange", - "route-up", - "route-pre-down", - "auth-user-pass-verify", - "dhcp-release", - "dhcp-renew", - "dh", + if (out != 0) { + currentarg += out; + } + } while (pos++ < line.length()); + + return parameters; + } + + + final String[] unsupportedOptions = {"config", + "tls-server" + + }; + + // Ignore all scripts + // in most cases these won't work and user who wish to execute scripts will + // figure out themselves + final String[] ignoreOptions = {"tls-client", + "askpass", + "auth-nocache", + "up", + "down", + "route-up", + "ipchange", + "route-up", + "route-pre-down", + "auth-user-pass-verify", + "dhcp-release", + "dhcp-renew", + "dh", "group", "ip-win32", "management-hold", "management", "management-client", "management-query-remote", - "management-query-passwords", + "management-query-passwords", "management-query-proxy", "management-external-key", "management-forget-disconnect", @@ -269,32 +253,32 @@ public class ConfigParser { "management-up-down", "management-client-user", "management-client-group", - "pause-exit", + "pause-exit", "plugin", "machine-readable-output", - "persist-key", - "register-dns", - "route-delay", - "route-gateway", - "route-metric", - "route-method", - "status", - "script-security", - "show-net-up", - "suppress-timestamps", - "tmp-dir", - "tun-ipv6", - "topology", + "persist-key", + "register-dns", + "route-delay", + "route-gateway", + "route-metric", + "route-method", + "status", + "script-security", + "show-net-up", + "suppress-timestamps", + "tmp-dir", + "tun-ipv6", + "topology", "user", "win-sys", - }; final String[][] ignoreOptionsWithArg = - { - {"setenv", "IV_GUI_VER"}, - {"setenv", "IV_OPENVPN_GUI_VERSION"} - }; + { + {"setenv", "IV_GUI_VER"}, + {"setenv", "IV_OPENVPN_GUI_VERSION"}, + {"engine", "dynamic"} + }; final String[] connectionOptions = { "local", @@ -326,70 +310,67 @@ public class ConfigParser { // This method is far too long - @SuppressWarnings("ConstantConditions") + @SuppressWarnings("ConstantConditions") public VpnProfile convertProfile() throws ConfigParseError, IOException { - boolean noauthtypeset=true; - VpnProfile np = new VpnProfile(CONVERTED_PROFILE); - // Pull, client, tls-client - np.clearDefaults(); - - if(options.containsKey("client") || options.containsKey("pull")) { - np.mUsePull=true; - options.remove("pull"); - options.remove("client"); - } - - Vector<String> secret = getOption("secret", 1, 2); - if(secret!=null) - { - np.mAuthenticationType=VpnProfile.TYPE_STATICKEYS; - noauthtypeset=false; - np.mUseTLSAuth=true; - np.mTLSAuthFilename=secret.get(1); - if(secret.size()==3) - np.mTLSAuthDirection=secret.get(2); - - } - - Vector<Vector<String>> routes = getAllOption("route", 1, 4); - if(routes!=null) { - String routeopt = ""; + boolean noauthtypeset = true; + VpnProfile np = new VpnProfile(CONVERTED_PROFILE); + // Pull, client, tls-client + np.clearDefaults(); + + if (options.containsKey("client") || options.containsKey("pull")) { + np.mUsePull = true; + options.remove("pull"); + options.remove("client"); + } + + Vector<String> secret = getOption("secret", 1, 2); + if (secret != null) { + np.mAuthenticationType = VpnProfile.TYPE_STATICKEYS; + noauthtypeset = false; + np.mUseTLSAuth = true; + np.mTLSAuthFilename = secret.get(1); + if (secret.size() == 3) + np.mTLSAuthDirection = secret.get(2); + + } + + Vector<Vector<String>> routes = getAllOption("route", 1, 4); + if (routes != null) { + String routeopt = ""; String routeExcluded = ""; - for(Vector<String> route:routes){ - String netmask = "255.255.255.255"; + for (Vector<String> route : routes) { + String netmask = "255.255.255.255"; String gateway = "vpn_gateway"; - if(route.size() >= 3) - netmask = route.get(2); + if (route.size() >= 3) + netmask = route.get(2); if (route.size() >= 4) gateway = route.get(3); - String net = route.get(1); - try { - CIDRIP cidr = new CIDRIP(net, netmask); + String net = route.get(1); + try { + CIDRIP cidr = new CIDRIP(net, netmask); if (gateway.equals("net_gateway")) routeExcluded += cidr.toString() + " "; else - routeopt+=cidr.toString() + " "; - } catch (ArrayIndexOutOfBoundsException aioob) { - throw new ConfigParseError("Could not parse netmask of route " + netmask); - } catch (NumberFormatException ne) { - - + routeopt += cidr.toString() + " "; + } catch (ArrayIndexOutOfBoundsException aioob) { + throw new ConfigParseError("Could not parse netmask of route " + netmask); + } catch (NumberFormatException ne) { - throw new ConfigParseError("Could not parse netmask of route " + netmask); - } + throw new ConfigParseError("Could not parse netmask of route " + netmask); + } - } - np.mCustomRoutes=routeopt; - np.mExcludedRoutes=routeExcluded; - } + } + np.mCustomRoutes = routeopt; + np.mExcludedRoutes = routeExcluded; + } Vector<Vector<String>> routesV6 = getAllOption("route-ipv6", 1, 4); - if (routesV6!=null) { + if (routesV6 != null) { String customIPv6Routes = ""; - for (Vector<String> route:routesV6){ + for (Vector<String> route : routesV6) { customIPv6Routes += route.get(1) + " "; } @@ -397,39 +378,36 @@ public class ConfigParser { } // Also recognize tls-auth [inline] direction ... - Vector<Vector<String>> tlsauthoptions = getAllOption("tls-auth", 1, 2); - if(tlsauthoptions!=null) { - for(Vector<String> tlsauth:tlsauthoptions) { - if(tlsauth!=null) - { - if(!tlsauth.get(1).equals("[inline]")) { - np.mTLSAuthFilename=tlsauth.get(1); - np.mUseTLSAuth=true; - } - if(tlsauth.size()==3) - np.mTLSAuthDirection=tlsauth.get(2); - } - } - } - - Vector<String> direction = getOption("key-direction", 1, 1); - if(direction!=null) - np.mTLSAuthDirection=direction.get(1); + Vector<Vector<String>> tlsauthoptions = getAllOption("tls-auth", 1, 2); + if (tlsauthoptions != null) { + for (Vector<String> tlsauth : tlsauthoptions) { + if (tlsauth != null) { + if (!tlsauth.get(1).equals("[inline]")) { + np.mTLSAuthFilename = tlsauth.get(1); + np.mUseTLSAuth = true; + } + if (tlsauth.size() == 3) + np.mTLSAuthDirection = tlsauth.get(2); + } + } + } + + Vector<String> direction = getOption("key-direction", 1, 1); + if (direction != null) + np.mTLSAuthDirection = direction.get(1); Vector<Vector<String>> defgw = getAllOption("redirect-gateway", 0, 5); - if(defgw != null) - { - np.mUseDefaultRoute=true; + if (defgw != null) { + np.mUseDefaultRoute = true; checkRedirectParameters(np, defgw); } - Vector<Vector<String>> redirectPrivate = getAllOption("redirect-private",0,5); - if (redirectPrivate != null) - { - checkRedirectParameters(np,redirectPrivate); + Vector<Vector<String>> redirectPrivate = getAllOption("redirect-private", 0, 5); + if (redirectPrivate != null) { + checkRedirectParameters(np, redirectPrivate); } - Vector<String> dev =getOption("dev",1,1); - Vector<String> devtype =getOption("dev-type",1,1); + Vector<String> dev = getOption("dev", 1, 1); + Vector<String> devtype = getOption("dev-type", 1, 1); if ((devtype != null && devtype.get(1).equals("tun")) || (dev != null && dev.get(1).startsWith("tun")) || @@ -437,15 +415,15 @@ public class ConfigParser { //everything okay } else { throw new ConfigParseError("Sorry. Only tun mode is supported. See the FAQ for more detail"); - } + } - Vector<String> mssfix = getOption("mssfix",0,1); + Vector<String> mssfix = getOption("mssfix", 0, 1); - if (mssfix!=null) { - if (mssfix.size()>=2) { + if (mssfix != null) { + if (mssfix.size() >= 2) { try { - np.mMssFix=Integer.parseInt(mssfix.get(1)); - } catch(NumberFormatException e) { + np.mMssFix = Integer.parseInt(mssfix.get(1)); + } catch (NumberFormatException e) { throw new ConfigParseError("Argument to --mssfix has to be an integer"); } } else { @@ -454,172 +432,171 @@ public class ConfigParser { } - Vector<String> mode =getOption("mode",1,1); - if (mode != null){ - if(!mode.get(1).equals("p2p")) - throw new ConfigParseError("Invalid mode for --mode specified, need p2p"); - } - - - - Vector<Vector<String>> dhcpoptions = getAllOption("dhcp-option", 2, 2); - if(dhcpoptions!=null) { - for(Vector<String> dhcpoption:dhcpoptions) { - String type=dhcpoption.get(1); - String arg = dhcpoption.get(2); - if(type.equals("DOMAIN")) { - np.mSearchDomain=dhcpoption.get(2); - } else if(type.equals("DNS")) { - np.mOverrideDNS=true; - if(np.mDNS1.equals(VpnProfile.DEFAULT_DNS1)) - np.mDNS1=arg; - else - np.mDNS2=arg; - } - } - } - - Vector<String> ifconfig = getOption("ifconfig", 2, 2); - if(ifconfig!=null) { - try { - CIDRIP cidr = new CIDRIP(ifconfig.get(1), ifconfig.get(2)); - np.mIPv4Address=cidr.toString(); - } catch (NumberFormatException nfe) { - throw new ConfigParseError("Could not pase ifconfig IP address: " + nfe.getLocalizedMessage()); - } - - } - - if(getOption("remote-random-hostname", 0, 0)!=null) - np.mUseRandomHostname=true; - - if(getOption("float", 0, 0)!=null) - np.mUseFloat=true; - - if(getOption("comp-lzo", 0, 1)!=null) - np.mUseLzo=true; - - Vector<String> cipher = getOption("cipher", 1, 1); - if(cipher!=null) - np.mCipher= cipher.get(1); - - Vector<String> auth = getOption("auth", 1, 1); - if(auth!=null) - np.mAuth = auth.get(1); - - - Vector<String> ca = getOption("ca",1,1); - if(ca!=null){ - np.mCaFilename = ca.get(1); - } - - Vector<String> cert = getOption("cert",1,1); - if(cert!=null){ - np.mClientCertFilename = cert.get(1); - np.mAuthenticationType = VpnProfile.TYPE_CERTIFICATES; - noauthtypeset=false; - } - Vector<String> key= getOption("key",1,1); - if(key!=null) - np.mClientKeyFilename=key.get(1); - - Vector<String> pkcs12 = getOption("pkcs12",1,1); - if(pkcs12!=null) { - np.mPKCS12Filename = pkcs12.get(1); - np.mAuthenticationType = VpnProfile.TYPE_KEYSTORE; - noauthtypeset=false; - } - - Vector<String> cryptoapicert = getOption("cryptoapicert",1,1); - if(cryptoapicert!=null) { + Vector<String> mode = getOption("mode", 1, 1); + if (mode != null) { + if (!mode.get(1).equals("p2p")) + throw new ConfigParseError("Invalid mode for --mode specified, need p2p"); + } + + + Vector<Vector<String>> dhcpoptions = getAllOption("dhcp-option", 2, 2); + if (dhcpoptions != null) { + for (Vector<String> dhcpoption : dhcpoptions) { + String type = dhcpoption.get(1); + String arg = dhcpoption.get(2); + if (type.equals("DOMAIN")) { + np.mSearchDomain = dhcpoption.get(2); + } else if (type.equals("DNS")) { + np.mOverrideDNS = true; + if (np.mDNS1.equals(VpnProfile.DEFAULT_DNS1)) + np.mDNS1 = arg; + else + np.mDNS2 = arg; + } + } + } + + Vector<String> ifconfig = getOption("ifconfig", 2, 2); + if (ifconfig != null) { + try { + CIDRIP cidr = new CIDRIP(ifconfig.get(1), ifconfig.get(2)); + np.mIPv4Address = cidr.toString(); + } catch (NumberFormatException nfe) { + throw new ConfigParseError("Could not pase ifconfig IP address: " + nfe.getLocalizedMessage()); + } + + } + + if (getOption("remote-random-hostname", 0, 0) != null) + np.mUseRandomHostname = true; + + if (getOption("float", 0, 0) != null) + np.mUseFloat = true; + + if (getOption("comp-lzo", 0, 1) != null) + np.mUseLzo = true; + + Vector<String> cipher = getOption("cipher", 1, 1); + if (cipher != null) + np.mCipher = cipher.get(1); + + Vector<String> auth = getOption("auth", 1, 1); + if (auth != null) + np.mAuth = auth.get(1); + + + Vector<String> ca = getOption("ca", 1, 1); + if (ca != null) { + np.mCaFilename = ca.get(1); + } + + Vector<String> cert = getOption("cert", 1, 1); + if (cert != null) { + np.mClientCertFilename = cert.get(1); + np.mAuthenticationType = VpnProfile.TYPE_CERTIFICATES; + noauthtypeset = false; + } + Vector<String> key = getOption("key", 1, 1); + if (key != null) + np.mClientKeyFilename = key.get(1); + + Vector<String> pkcs12 = getOption("pkcs12", 1, 1); + if (pkcs12 != null) { + np.mPKCS12Filename = pkcs12.get(1); np.mAuthenticationType = VpnProfile.TYPE_KEYSTORE; - noauthtypeset=false; + noauthtypeset = false; } - Vector<String> compatnames = getOption("compat-names",1,2); - Vector<String> nonameremapping = getOption("no-name-remapping",1,1); - Vector<String> tlsremote = getOption("tls-remote",1,1); - if(tlsremote!=null){ - np.mRemoteCN = tlsremote.get(1); - np.mCheckRemoteCN=true; - np.mX509AuthType = VpnProfile.X509_VERIFY_TLSREMOTE; + Vector<String> cryptoapicert = getOption("cryptoapicert", 1, 1); + if (cryptoapicert != null) { + np.mAuthenticationType = VpnProfile.TYPE_KEYSTORE; + noauthtypeset = false; + } - if((compatnames!=null && compatnames.size() > 2) || - (nonameremapping!=null)) - np.mX509AuthType = VpnProfile.X509_VERIFY_TLSREMOTE_COMPAT_NOREMAPPING; - } + Vector<String> compatnames = getOption("compat-names", 1, 2); + Vector<String> nonameremapping = getOption("no-name-remapping", 1, 1); + Vector<String> tlsremote = getOption("tls-remote", 1, 1); + if (tlsremote != null) { + np.mRemoteCN = tlsremote.get(1); + np.mCheckRemoteCN = true; + np.mX509AuthType = VpnProfile.X509_VERIFY_TLSREMOTE; + + if ((compatnames != null && compatnames.size() > 2) || + (nonameremapping != null)) + np.mX509AuthType = VpnProfile.X509_VERIFY_TLSREMOTE_COMPAT_NOREMAPPING; + } - Vector<String> verifyx509name = getOption("verify-x509-name",1,2); - if(verifyx509name!=null){ - np.mRemoteCN = verifyx509name.get(1); - np.mCheckRemoteCN=true; - if(verifyx509name.size()>2) { - if (verifyx509name.get(2).equals("name")) - np.mX509AuthType=VpnProfile.X509_VERIFY_TLSREMOTE_RDN; - else if (verifyx509name.get(2).equals("name-prefix")) - np.mX509AuthType=VpnProfile.X509_VERIFY_TLSREMOTE_RDN_PREFIX; - else - throw new ConfigParseError("Unknown parameter to x509-verify-name: " + verifyx509name.get(2) ); - } else { - np.mX509AuthType = VpnProfile.X509_VERIFY_TLSREMOTE_DN; - } + Vector<String> verifyx509name = getOption("verify-x509-name", 1, 2); + if (verifyx509name != null) { + np.mRemoteCN = verifyx509name.get(1); + np.mCheckRemoteCN = true; + if (verifyx509name.size() > 2) { + if (verifyx509name.get(2).equals("name")) + np.mX509AuthType = VpnProfile.X509_VERIFY_TLSREMOTE_RDN; + else if (verifyx509name.get(2).equals("name-prefix")) + np.mX509AuthType = VpnProfile.X509_VERIFY_TLSREMOTE_RDN_PREFIX; + else + throw new ConfigParseError("Unknown parameter to x509-verify-name: " + verifyx509name.get(2)); + } else { + np.mX509AuthType = VpnProfile.X509_VERIFY_TLSREMOTE_DN; + } - } + } - Vector<String> verb = getOption("verb",1,1); - if(verb!=null){ - np.mVerb=verb.get(1); - } + Vector<String> verb = getOption("verb", 1, 1); + if (verb != null) { + np.mVerb = verb.get(1); + } - if(getOption("nobind", 0, 0) != null) - np.mNobind=true; + if (getOption("nobind", 0, 0) != null) + np.mNobind = true; - if(getOption("persist-tun", 0,0) != null) - np.mPersistTun=true; + if (getOption("persist-tun", 0, 0) != null) + np.mPersistTun = true; - Vector<String> connectretry = getOption("connect-retry", 1, 1); - if(connectretry!=null) - np.mConnectRetry =connectretry.get(1); + Vector<String> connectretry = getOption("connect-retry", 1, 1); + if (connectretry != null) + np.mConnectRetry = connectretry.get(1); - Vector<String> connectretrymax = getOption("connect-retry-max", 1, 1); - if(connectretrymax!=null) - np.mConnectRetryMax =connectretrymax.get(1); + Vector<String> connectretrymax = getOption("connect-retry-max", 1, 1); + if (connectretrymax != null) + np.mConnectRetryMax = connectretrymax.get(1); Vector<Vector<String>> remotetls = getAllOption("remote-cert-tls", 1, 1); - if(remotetls!=null) - if(remotetls.get(0).get(1).equals("server")) - np.mExpectTLSCert=true; - else - options.put("remotetls",remotetls); - - Vector<String> authuser = getOption("auth-user-pass",0,1); - if(authuser !=null){ - if(noauthtypeset) { - np.mAuthenticationType=VpnProfile.TYPE_USERPASS; - } else if(np.mAuthenticationType==VpnProfile.TYPE_CERTIFICATES) { - np.mAuthenticationType=VpnProfile.TYPE_USERPASS_CERTIFICATES; - } else if(np.mAuthenticationType==VpnProfile.TYPE_KEYSTORE) { - np.mAuthenticationType=VpnProfile.TYPE_USERPASS_KEYSTORE; - } - if(authuser.size()>1) { - // Set option value to password get to embed later. - np.mUsername=null; - useEmbbedUserAuth(np, authuser.get(1)); - } - } + if (remotetls != null) + if (remotetls.get(0).get(1).equals("server")) + np.mExpectTLSCert = true; + else + options.put("remotetls", remotetls); + + Vector<String> authuser = getOption("auth-user-pass", 0, 1); + if (authuser != null) { + if (noauthtypeset) { + np.mAuthenticationType = VpnProfile.TYPE_USERPASS; + } else if (np.mAuthenticationType == VpnProfile.TYPE_CERTIFICATES) { + np.mAuthenticationType = VpnProfile.TYPE_USERPASS_CERTIFICATES; + } else if (np.mAuthenticationType == VpnProfile.TYPE_KEYSTORE) { + np.mAuthenticationType = VpnProfile.TYPE_USERPASS_KEYSTORE; + } + if (authuser.size() > 1) { + // Set option value to password get to embed later. + np.mUsername = null; + useEmbbedUserAuth(np, authuser.get(1)); + } + } Pair<Connection, Connection[]> conns = parseConnectionOptions(null); - np.mConnections =conns.second; + np.mConnections = conns.second; Vector<Vector<String>> connectionBlocks = getAllOption("connection", 1, 1); - if (np.mConnections.length > 0 && connectionBlocks !=null ) { - throw new ConfigParseError("Using a <connection> block and --remote is not allowed."); + if (np.mConnections.length > 0 && connectionBlocks != null) { + throw new ConfigParseError("Using a <connection> block and --remote is not allowed."); } - if (connectionBlocks!=null) { + if (connectionBlocks != null) { np.mConnections = new Connection[connectionBlocks.size()]; int connIndex = 0; @@ -633,43 +610,43 @@ public class ConfigParser { connIndex++; } } - if(getOption("remote-random", 0, 0) != null) - np.mRemoteRandom=true; + if (getOption("remote-random", 0, 0) != null) + np.mRemoteRandom = true; Vector<String> protoforce = getOption("proto-force", 1, 1); - if(protoforce!=null) { + if (protoforce != null) { boolean disableUDP; String protoToDisable = protoforce.get(1); if (protoToDisable.equals("udp")) - disableUDP=true; + disableUDP = true; else if (protoToDisable.equals("tcp")) - disableUDP=false; + disableUDP = false; else throw new ConfigParseError(String.format("Unknown protocol %s in proto-force", protoToDisable)); - for (Connection conn:np.mConnections) - if(conn.mUseUdp==disableUDP) - conn.mEnabled=false; + for (Connection conn : np.mConnections) + if (conn.mUseUdp == disableUDP) + conn.mEnabled = false; } // Parse OpenVPN Access Server extra - Vector<String> friendlyname = meta.get("FRIENDLY_NAME"); - if(friendlyname !=null && friendlyname.size() > 1) - np.mName=friendlyname.get(1); + Vector<String> friendlyname = meta.get("FRIENDLY_NAME"); + if (friendlyname != null && friendlyname.size() > 1) + np.mName = friendlyname.get(1); - Vector<String> ocusername = meta.get("USERNAME"); - if(ocusername !=null && ocusername.size() > 1) - np.mUsername=ocusername.get(1); + Vector<String> ocusername = meta.get("USERNAME"); + if (ocusername != null && ocusername.size() > 1) + np.mUsername = ocusername.get(1); checkIgnoreAndInvalidOptions(np); - fixup(np); + fixup(np); - return np; - } + return np; + } private Pair<Connection, Connection[]> parseConnection(String connection, Connection defaultValues) throws IOException, ConfigParseError { - // Parse a connection Block as a new configuration file + // Parse a connection Block as a new configuration file ConfigParser connectionParser = new ConfigParser(); @@ -683,7 +660,7 @@ public class ConfigParser { private Pair<Connection, Connection[]> parseConnectionOptions(Connection connDefault) throws ConfigParseError { Connection conn; - if (connDefault!=null) + if (connDefault != null) try { conn = connDefault.clone(); } catch (CloneNotSupportedException e) { @@ -693,28 +670,28 @@ public class ConfigParser { else conn = new Connection(); - Vector<String> port = getOption("port", 1,1); - if(port!=null){ + Vector<String> port = getOption("port", 1, 1); + if (port != null) { conn.mServerPort = port.get(1); } - Vector<String> rport = getOption("rport", 1,1); - if(rport!=null){ + Vector<String> rport = getOption("rport", 1, 1); + if (rport != null) { conn.mServerPort = rport.get(1); } - Vector<String> proto = getOption("proto", 1,1); - if(proto!=null){ - conn.mUseUdp=isUdpProto(proto.get(1)); + Vector<String> proto = getOption("proto", 1, 1); + if (proto != null) { + conn.mUseUdp = isUdpProto(proto.get(1)); } // Parse remote config - Vector<Vector<String>> remotes = getAllOption("remote",1,3); + Vector<Vector<String>> remotes = getAllOption("remote", 1, 3); // Assume that we need custom options if connectionDefault are set - if(connDefault!=null) { + if (connDefault != null) { for (Vector<Vector<String>> option : options.values()) { conn.mCustomConfiguration += getOptionStrings(option); @@ -724,14 +701,14 @@ public class ConfigParser { conn.mUseCustomConfig = true; } // Make remotes empty to simplify code - if (remotes==null) + if (remotes == null) remotes = new Vector<Vector<String>>(); Connection[] connections = new Connection[remotes.size()]; - int i=0; - for (Vector<String> remote: remotes) { + int i = 0; + for (Vector<String> remote : remotes) { try { connections[i] = conn.clone(); } catch (CloneNotSupportedException e) { @@ -739,7 +716,7 @@ public class ConfigParser { } switch (remote.size()) { case 4: - connections[i].mUseUdp=isUdpProto(remote.get(3)); + connections[i].mUseUdp = isUdpProto(remote.get(3)); case 3: connections[i].mServerPort = remote.get(2); case 2: @@ -752,63 +729,60 @@ public class ConfigParser { } private void checkRedirectParameters(VpnProfile np, Vector<Vector<String>> defgw) { - for (Vector<String> redirect: defgw) - for (int i=1;i<redirect.size();i++){ + for (Vector<String> redirect : defgw) + for (int i = 1; i < redirect.size(); i++) { if (redirect.get(i).equals("block-local")) - np.mAllowLocalLAN=false; + np.mAllowLocalLAN = false; else if (redirect.get(i).equals("unblock-local")) - np.mAllowLocalLAN=true; + np.mAllowLocalLAN = true; } } - private boolean isUdpProto(String proto) throws ConfigParseError { - boolean isudp; - if(proto.equals("udp") || proto.equals("udp6")) - isudp=true; - else if (proto.equals("tcp-client") || - proto.equals("tcp") || - proto.equals("tcp6") || - proto.endsWith("tcp6-client")) - isudp =false; - else - throw new ConfigParseError("Unsupported option to --proto " + proto); - return isudp; - } - - static public void useEmbbedUserAuth(VpnProfile np, String inlinedata) - { - String data = VpnProfile.getEmbeddedContent(inlinedata); - String[] parts = data.split("\n"); - if(parts.length >= 2) { - np.mUsername=parts[0]; - np.mPassword=parts[1]; - } - } - - private void checkIgnoreAndInvalidOptions(VpnProfile np) throws ConfigParseError { - for(String option:unsupportedOptions) - if(options.containsKey(option)) - throw new ConfigParseError(String.format("Unsupported Option %s encountered in config file. Aborting",option)); + private boolean isUdpProto(String proto) throws ConfigParseError { + boolean isudp; + if (proto.equals("udp") || proto.equals("udp6")) + isudp = true; + else if (proto.equals("tcp-client") || + proto.equals("tcp") || + proto.equals("tcp6") || + proto.endsWith("tcp6-client")) + isudp = false; + else + throw new ConfigParseError("Unsupported option to --proto " + proto); + return isudp; + } - for(String option:ignoreOptions) - // removing an item which is not in the map is no error - options.remove(option); + static public void useEmbbedUserAuth(VpnProfile np, String inlinedata) { + String data = VpnProfile.getEmbeddedContent(inlinedata); + String[] parts = data.split("\n"); + if (parts.length >= 2) { + np.mUsername = parts[0]; + np.mPassword = parts[1]; + } + } + private void checkIgnoreAndInvalidOptions(VpnProfile np) throws ConfigParseError { + for (String option : unsupportedOptions) + if (options.containsKey(option)) + throw new ConfigParseError(String.format("Unsupported Option %s encountered in config file. Aborting", option)); + for (String option : ignoreOptions) + // removing an item which is not in the map is no error + options.remove(option); - if(options.size()> 0) { - np.mCustomConfigOptions += "# These Options were found in the config file do not map to config settings:\n"; + if (options.size() > 0) { + np.mCustomConfigOptions += "# These Options were found in the config file do not map to config settings:\n"; - for(Vector<Vector<String>> option:options.values()) { + for (Vector<Vector<String>> option : options.values()) { - np.mCustomConfigOptions += getOptionStrings(option); + np.mCustomConfigOptions += getOptionStrings(option); - } - np.mUseCustomConfig=true; + } + np.mUseCustomConfig = true; - } - } + } + } boolean ignoreThisOption(Vector<String> option) { @@ -843,35 +817,35 @@ public class ConfigParser { private void fixup(VpnProfile np) { - if(np.mRemoteCN.equals(np.mServerName)) { - np.mRemoteCN=""; - } - } - - private Vector<String> getOption(String option, int minarg, int maxarg) throws ConfigParseError { - Vector<Vector<String>> alloptions = getAllOption(option, minarg, maxarg); - if(alloptions==null) - return null; - else - return alloptions.lastElement(); - } - - - private Vector<Vector<String>> getAllOption(String option, int minarg, int maxarg) throws ConfigParseError { - Vector<Vector<String>> args = options.get(option); - if(args==null) - return null; - - for(Vector<String> optionline:args) - - if(optionline.size()< (minarg+1) || optionline.size() > maxarg+1) { - String err = String.format(Locale.getDefault(),"Option %s has %d parameters, expected between %d and %d", - option,optionline.size()-1,minarg,maxarg ); - throw new ConfigParseError(err); - } - options.remove(option); - return args; - } + if (np.mRemoteCN.equals(np.mServerName)) { + np.mRemoteCN = ""; + } + } + + private Vector<String> getOption(String option, int minarg, int maxarg) throws ConfigParseError { + Vector<Vector<String>> alloptions = getAllOption(option, minarg, maxarg); + if (alloptions == null) + return null; + else + return alloptions.lastElement(); + } + + + private Vector<Vector<String>> getAllOption(String option, int minarg, int maxarg) throws ConfigParseError { + Vector<Vector<String>> args = options.get(option); + if (args == null) + return null; + + for (Vector<String> optionline : args) + + if (optionline.size() < (minarg + 1) || optionline.size() > maxarg + 1) { + String err = String.format(Locale.getDefault(), "Option %s has %d parameters, expected between %d and %d", + option, optionline.size() - 1, minarg, maxarg); + throw new ConfigParseError(err); + } + options.remove(option); + return args; + } } diff --git a/app/src/main/java/de/blinkt/openvpn/core/NetworkSpace.java b/app/src/main/java/de/blinkt/openvpn/core/NetworkSpace.java index 26354689..c86f9e44 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/NetworkSpace.java +++ b/app/src/main/java/de/blinkt/openvpn/core/NetworkSpace.java @@ -172,8 +172,16 @@ public class NetworkSpace { } public boolean containsNet(ipAddress network) { - return getFirstAddress().compareTo(network.getFirstAddress()) != 1 && - getLastAddress().compareTo(network.getLastAddress()) != -1; + // this.first >= net.first && this.last <= net.last + BigInteger ourFirst = getFirstAddress(); + BigInteger ourLast = getLastAddress(); + BigInteger netFirst = network.getFirstAddress(); + BigInteger netLast = network.getLastAddress(); + + boolean a = ourFirst.compareTo(netFirst) != 1; + boolean b = ourLast.compareTo(netLast) != -1; + return a && b; + } } @@ -320,6 +328,7 @@ public class NetworkSpace { boolean skipIp=false; // If there is any smaller net that is excluded we may not add the positive route back + for (ipAddress calculatedIp: ipsSorted) { if(!calculatedIp.included && origIp.containsNet(calculatedIp)) { skipIp=true; diff --git a/app/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java b/app/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java index 3cb5527b..3c1ec064 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java +++ b/app/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java @@ -51,6 +51,8 @@ import static de.blinkt.openvpn.core.NetworkSpace.ipAddress; import static de.blinkt.openvpn.core.VpnStatus.ConnectionStatus.LEVEL_CONNECTED; import static de.blinkt.openvpn.core.VpnStatus.ConnectionStatus.LEVEL_CONNECTING_NO_SERVER_REPLY_YET; import static de.blinkt.openvpn.core.VpnStatus.ConnectionStatus.LEVEL_WAITING_FOR_USER_INPUT; +import static de.blinkt.openvpn.core.VpnStatus.ConnectionStatus.LEVEL_NOTCONNECTED; +import static de.blinkt.openvpn.core.VpnStatus.ConnectionStatus.LEVEL_NONETWORK; import se.leap.bitmaskclient.Dashboard; @@ -174,7 +176,7 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac mNotificationManager.notify(OPENVPN_STATUS, notification); - startForeground(OPENVPN_STATUS, notification); + //startForeground(OPENVPN_STATUS, notification); } private int getIconByConnectionStatus(ConnectionStatus level) { @@ -552,9 +554,15 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac Collection<ipAddress> positiveIPv4Routes = mRoutes.getPositiveIPList(); Collection<ipAddress> positiveIPv6Routes = mRoutesv6.getPositiveIPList(); + ipAddress multicastRange = new ipAddress(new CIDRIP("224.0.0.0", 3), true); + for (NetworkSpace.ipAddress route : positiveIPv4Routes) { try { - builder.addRoute(route.getIPv4Address(), route.networkMask); + + if (multicastRange.containsNet(route)) + VpnStatus.logDebug(R.string.ignore_multicast_route, route.toString()); + else + builder.addRoute(route.getIPv4Address(), route.networkMask); } catch (IllegalArgumentException ia) { VpnStatus.logError(getString(R.string.route_rejected) + route + " " + ia.getLocalizedMessage()); } @@ -607,7 +615,10 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac try { //Debug.stopMethodTracing(); - return builder.establish(); + ParcelFileDescriptor tun = builder.establish(); + if (tun==null) + throw new NullPointerException("Android establish() method returned null (Really broken network configuration?)"); + return tun; } catch (Exception e) { VpnStatus.logError(R.string.tun_open_error); VpnStatus.logError(getString(R.string.error) + e.getLocalizedMessage()); @@ -843,6 +854,21 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac mDisplayBytecount = true; mConnecttime = System.currentTimeMillis(); lowpriority = true; + if(mProfile.mPersistTun) { + NotificationManager ns = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); + ns.cancel(OPENVPN_STATUS); + return; + } + } else if (level == LEVEL_NONETWORK || level == LEVEL_NOTCONNECTED) { + NotificationManager ns = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); + ns.cancel(OPENVPN_STATUS); + return; + } else if (level != LEVEL_NOTCONNECTED && mConnecttime > 0) { + mDisplayBytecount = false; + String msg = "Traffic is blocked until the VPN becomes active."; + String ticker = msg; + showNotification(msg, ticker, lowpriority , 0, level); + return; } else { mDisplayBytecount = false; } @@ -876,7 +902,7 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac humanReadableByteCount(diffOut / OpenVPNManagement.mBytecountInterval, true)); boolean lowpriority = !mNotificationAlwaysVisible; - showNotification(netstat, null, lowpriority, mConnecttime, LEVEL_CONNECTED); + //showNotification(netstat, null, lowpriority, mConnecttime, LEVEL_CONNECTED); } } diff --git a/app/src/main/res/drawable-hdpi/ic_check_white_24dp.png b/app/src/main/res/drawable-hdpi/ic_check_white_24dp.png Binary files differnew file mode 100644 index 00000000..f42a0e2d --- /dev/null +++ b/app/src/main/res/drawable-hdpi/ic_check_white_24dp.png diff --git a/app/src/main/res/drawable-mdpi/ic_check_white_24dp.png b/app/src/main/res/drawable-mdpi/ic_check_white_24dp.png Binary files differnew file mode 100644 index 00000000..e91f9048 --- /dev/null +++ b/app/src/main/res/drawable-mdpi/ic_check_white_24dp.png diff --git a/app/src/main/res/drawable-xhdpi/ic_check_white_24dp.png b/app/src/main/res/drawable-xhdpi/ic_check_white_24dp.png Binary files differnew file mode 100644 index 00000000..e5024472 --- /dev/null +++ b/app/src/main/res/drawable-xhdpi/ic_check_white_24dp.png diff --git a/app/src/main/res/drawable-xxhdpi/ic_check_white_24dp.png b/app/src/main/res/drawable-xxhdpi/ic_check_white_24dp.png Binary files differnew file mode 100644 index 00000000..6e03d54c --- /dev/null +++ b/app/src/main/res/drawable-xxhdpi/ic_check_white_24dp.png diff --git a/app/src/main/res/drawable-xxxhdpi/ic_check_white_24dp.png b/app/src/main/res/drawable-xxxhdpi/ic_check_white_24dp.png Binary files differnew file mode 100644 index 00000000..87892840 --- /dev/null +++ b/app/src/main/res/drawable-xxxhdpi/ic_check_white_24dp.png diff --git a/app/src/main/res/layout/log_fragment.xml b/app/src/main/res/layout/log_fragment.xml index 4fec942e..491882a9 100644 --- a/app/src/main/res/layout/log_fragment.xml +++ b/app/src/main/res/layout/log_fragment.xml @@ -13,6 +13,7 @@ <LinearLayout android:background="@drawable/white_rect" android:elevation="1dp" + android:orientation="vertical" android:layout_height="wrap_content" android:layout_width="match_parent"> diff --git a/app/src/main/res/values-v21/refs.xml b/app/src/main/res/values-v21/refs.xml index d29d04ed..a4a26bec 100644 --- a/app/src/main/res/values-v21/refs.xml +++ b/app/src/main/res/values-v21/refs.xml @@ -7,9 +7,8 @@ <resources> <drawable name="ic_menu_close_clear_cancel">@drawable/ic_close_white_24dp</drawable> <drawable name="ic_menu_share">@drawable/ic_share_white_24dp </drawable> + <drawable name="ic_menu_save">@drawable/ic_check_white_24dp</drawable> <drawable name="ic_menu_view">@drawable/ic_filter_list_white_24dp</drawable> <drawable name="ic_menu_delete">@drawable/ic_delete_white_24dp</drawable> <drawable name="ic_menu_delete_grey">@drawable/ic_delete_grey600_24dp</drawable> - - <drawable name="ic_menu_edit">@drawable/ic_edit_white_24dp</drawable> </resources> diff --git a/app/src/main/res/values/strings-icsopenvpn.xml b/app/src/main/res/values/strings-icsopenvpn.xml index 307d3a42..39ad1193 100755 --- a/app/src/main/res/values/strings-icsopenvpn.xml +++ b/app/src/main/res/values/strings-icsopenvpn.xml @@ -350,5 +350,6 @@ <string name="show_log">Show log</string> <string name="faq_android_clients">Multiple OpenVPN clients for Android exist. The most common ones are OpenVPN for Android (this client), OpenVPN Connect and OpenVPN Settings.<p>The clients can be grouped into two groups: OpenVPN for Android and OpenVPN Connect use the official VPNService API (Android 4.0+) and require no root and OpenVPN Settings which uses root.<p>OpenVPN for Android is an open source client and developed by Arne Schwabe. It is targeted at more advanced users and offers many settings and the ability to import profiles from files and to configure/change profiles inside the app. The client is based on the community version of OpenVPN. It is based on the OpenVPN 2.x source code. This client can be seen as the semi officially client of the community. <p>OpenVPN Connect is non open source client that is developed by OpenVPN Technologies, Inc. The client is indented to be general use client and moree targeted at the average user and allows the import of OpenVPN profiles. This client is based on the OpenVPN C++ reimplementation of the OpenVPN protocol (This was required to allow OpenVPN Technologies, Inc to publish an iOS OpenVPN app). This client is the official client of the OpenVPN technologies <p> OpenVPN Settings is the oldest of the clients and also a UI for the open source OpenVPN. In contrast to OpenVPN for Android it requires root and does not use the VPNService API. It does not depend on Android 4.0+</string> <string name="faq_androids_clients_title">Differences between the OpenVPN Android clients</string> + <string name="ignore_multicast_route">Ignoring multicast route: %s</string> </resources> |