summaryrefslogtreecommitdiff
path: root/src/openvpn
diff options
context:
space:
mode:
authorAlberto Gonzalez Iniesta <agi@inittab.org>2014-10-29 17:43:51 +0100
committerAlberto Gonzalez Iniesta <agi@inittab.org>2014-10-29 17:43:51 +0100
commit4d0c77888c6b17b11390eaefe41e14229365c463 (patch)
tree76db22e48b28d96f16a7ce0111109b00b6f519c3 /src/openvpn
parent52a3e3b0ad96506d705d1759f5a41b40563167ec (diff)
parent63862ed15e1abb4b29c5a43b469321c928613c62 (diff)
Merge tag 'upstream/2.3.5'
Upstream version 2.3.5
Diffstat (limited to 'src/openvpn')
-rw-r--r--src/openvpn/Makefile.am1
-rw-r--r--src/openvpn/Makefile.in9
-rw-r--r--src/openvpn/base64.c2
-rw-r--r--src/openvpn/console.c16
-rw-r--r--src/openvpn/crypto.c42
-rw-r--r--src/openvpn/crypto.h4
-rw-r--r--src/openvpn/crypto_backend.h30
-rw-r--r--src/openvpn/crypto_openssl.c86
-rw-r--r--src/openvpn/crypto_polarssl.c21
-rw-r--r--src/openvpn/forward.c9
-rw-r--r--src/openvpn/helper.c6
-rw-r--r--src/openvpn/init.c12
-rw-r--r--src/openvpn/misc.c13
-rw-r--r--src/openvpn/multi.c27
-rw-r--r--src/openvpn/options.c41
-rw-r--r--src/openvpn/options.h2
-rw-r--r--src/openvpn/route.c11
-rw-r--r--src/openvpn/socket.c5
-rw-r--r--src/openvpn/socket.h2
-rw-r--r--src/openvpn/ssl_backend.h2
-rw-r--r--src/openvpn/ssl_openssl.c9
-rw-r--r--src/openvpn/ssl_polarssl.c54
-rw-r--r--src/openvpn/ssl_verify_openssl.c6
-rw-r--r--src/openvpn/ssl_verify_polarssl.c9
-rw-r--r--src/openvpn/syshead.h8
-rw-r--r--src/openvpn/tun.h19
-rw-r--r--src/openvpn/win32.c6
27 files changed, 307 insertions, 145 deletions
diff --git a/src/openvpn/Makefile.am b/src/openvpn/Makefile.am
index 5d38628..2e602f1 100644
--- a/src/openvpn/Makefile.am
+++ b/src/openvpn/Makefile.am
@@ -119,6 +119,7 @@ openvpn_LDADD = \
$(OPTIONAL_PKCS11_HELPER_LIBS) \
$(OPTIONAL_CRYPTO_LIBS) \
$(OPTIONAL_SELINUX_LIBS) \
+ $(OPTIONAL_SYSTEMD_LIBS) \
$(OPTIONAL_DL_LIBS)
if WIN32
openvpn_SOURCES += openvpn_win32_resources.rc
diff --git a/src/openvpn/Makefile.in b/src/openvpn/Makefile.in
index b5a6c69..686f79b 100644
--- a/src/openvpn/Makefile.in
+++ b/src/openvpn/Makefile.in
@@ -181,7 +181,7 @@ openvpn_DEPENDENCIES = $(top_builddir)/src/compat/libcompat.la \
$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
- $(am__DEPENDENCIES_1)
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
am__v_lt_0 = --silent
@@ -316,6 +316,7 @@ OPTIONAL_LZO_LIBS = @OPTIONAL_LZO_LIBS@
OPTIONAL_PKCS11_HELPER_CFLAGS = @OPTIONAL_PKCS11_HELPER_CFLAGS@
OPTIONAL_PKCS11_HELPER_LIBS = @OPTIONAL_PKCS11_HELPER_LIBS@
OPTIONAL_SELINUX_LIBS = @OPTIONAL_SELINUX_LIBS@
+OPTIONAL_SYSTEMD_LIBS = @OPTIONAL_SYSTEMD_LIBS@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
@@ -344,6 +345,7 @@ SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
SOCKETS_LIBS = @SOCKETS_LIBS@
STRIP = @STRIP@
+SYSTEMD_ASK_PASSWORD = @SYSTEMD_ASK_PASSWORD@
TAP_CFLAGS = @TAP_CFLAGS@
TAP_WIN_COMPONENT_ID = @TAP_WIN_COMPONENT_ID@
TAP_WIN_MIN_MAJOR = @TAP_WIN_MIN_MAJOR@
@@ -384,6 +386,8 @@ infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
+libsystemd_CFLAGS = @libsystemd_CFLAGS@
+libsystemd_LIBS = @libsystemd_LIBS@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
@@ -451,7 +455,8 @@ openvpn_SOURCES = base64.c base64.h basic.h buffer.c buffer.h \
openvpn_LDADD = $(top_builddir)/src/compat/libcompat.la \
$(SOCKETS_LIBS) $(OPTIONAL_LZO_LIBS) \
$(OPTIONAL_PKCS11_HELPER_LIBS) $(OPTIONAL_CRYPTO_LIBS) \
- $(OPTIONAL_SELINUX_LIBS) $(OPTIONAL_DL_LIBS) $(am__append_3)
+ $(OPTIONAL_SELINUX_LIBS) $(OPTIONAL_SYSTEMD_LIBS) \
+ $(OPTIONAL_DL_LIBS) $(am__append_3)
all: all-am
.SUFFIXES:
diff --git a/src/openvpn/base64.c b/src/openvpn/base64.c
index bb89aae..7dccec2 100644
--- a/src/openvpn/base64.c
+++ b/src/openvpn/base64.c
@@ -110,7 +110,7 @@ token_decode(const char *token)
int i;
unsigned int val = 0;
int marker = 0;
- if (strlen(token) < 4)
+ if (!token[0] || !token[1] || !token[2] || !token[3])
return DECODE_ERROR;
for (i = 0; i < 4; i++) {
val *= 64;
diff --git a/src/openvpn/console.c b/src/openvpn/console.c
index afda8ca..d66d408 100644
--- a/src/openvpn/console.c
+++ b/src/openvpn/console.c
@@ -34,6 +34,10 @@
#include "buffer.h"
#include "misc.h"
+#ifdef ENABLE_SYSTEMD
+#include <systemd/sd-daemon.h>
+#endif
+
#ifdef WIN32
#include "win32.h"
@@ -143,14 +147,14 @@ close_tty (FILE *fp)
static bool
check_systemd_running ()
{
- struct stat a, b;
+ struct stat c;
/* We simply test whether the systemd cgroup hierarchy is
- * mounted */
+ * mounted, as well as the systemd-ask-password executable
+ * being available */
- return (lstat("/sys/fs/cgroup", &a) == 0)
- && (lstat("/sys/fs/cgroup/systemd", &b) == 0)
- && (a.st_dev != b.st_dev);
+ return (sd_booted() > 0)
+ && (stat(SYSTEMD_ASK_PASSWORD_PATH, &c) == 0);
}
@@ -162,7 +166,7 @@ get_console_input_systemd (const char *prompt, const bool echo, char *input, con
struct argv argv;
argv_init (&argv);
- argv_printf (&argv, "/bin/systemd-ask-password");
+ argv_printf (&argv, SYSTEMD_ASK_PASSWORD_PATH);
argv_printf_cat (&argv, "%s", prompt);
if ((std_out = openvpn_popen (&argv, NULL)) < 0) {
diff --git a/src/openvpn/crypto.c b/src/openvpn/crypto.c
index d9adf5b..0a5e83f 100644
--- a/src/openvpn/crypto.c
+++ b/src/openvpn/crypto.c
@@ -100,10 +100,10 @@ openvpn_encrypt (struct buffer *buf, struct buffer work,
{
uint8_t iv_buf[OPENVPN_MAX_IV_LENGTH];
const int iv_size = cipher_ctx_iv_length (ctx->cipher);
- const unsigned int mode = cipher_ctx_mode (ctx->cipher);
+ const cipher_kt_t *cipher_kt = cipher_ctx_get_cipher_kt (ctx->cipher);
int outlen;
- if (mode == OPENVPN_MODE_CBC)
+ if (cipher_kt_mode_cbc(cipher_kt))
{
CLEAR (iv_buf);
@@ -119,7 +119,7 @@ openvpn_encrypt (struct buffer *buf, struct buffer work,
ASSERT (packet_id_write (&pin, buf, BOOL_CAST (opt->flags & CO_PACKET_ID_LONG_FORM), true));
}
}
- else if (mode == OPENVPN_MODE_CFB || mode == OPENVPN_MODE_OFB)
+ else if (cipher_kt_mode_ofb_cfb(cipher_kt))
{
struct packet_id_net pin;
struct buffer b;
@@ -171,7 +171,10 @@ openvpn_encrypt (struct buffer *buf, struct buffer work,
/* Flush the encryption buffer */
ASSERT(cipher_ctx_final(ctx->cipher, BPTR (&work) + outlen, &outlen));
work.len += outlen;
- ASSERT (outlen == iv_size);
+
+ /* For all CBC mode ciphers, check the last block is complete */
+ ASSERT (cipher_kt_mode (cipher_kt) != OPENVPN_MODE_CBC ||
+ outlen == iv_size);
/* prepend the IV to the ciphertext */
if (opt->flags & CO_USE_IV)
@@ -272,8 +275,8 @@ openvpn_decrypt (struct buffer *buf, struct buffer work,
if (ctx->cipher)
{
- const unsigned int mode = cipher_ctx_mode (ctx->cipher);
const int iv_size = cipher_ctx_iv_length (ctx->cipher);
+ const cipher_kt_t *cipher_kt = cipher_ctx_get_cipher_kt (ctx->cipher);
uint8_t iv_buf[OPENVPN_MAX_IV_LENGTH];
int outlen;
@@ -320,7 +323,7 @@ openvpn_decrypt (struct buffer *buf, struct buffer work,
/* Get packet ID from plaintext buffer or IV, depending on cipher mode */
{
- if (mode == OPENVPN_MODE_CBC)
+ if (cipher_kt_mode_cbc(cipher_kt))
{
if (opt->packet_id)
{
@@ -329,7 +332,7 @@ openvpn_decrypt (struct buffer *buf, struct buffer work,
have_pin = true;
}
}
- else if (mode == OPENVPN_MODE_CFB || mode == OPENVPN_MODE_OFB)
+ else if (cipher_kt_mode_ofb_cfb(cipher_kt))
{
struct buffer b;
@@ -426,17 +429,12 @@ init_key_type (struct key_type *kt, const char *ciphername,
/* check legal cipher mode */
{
- const unsigned int mode = cipher_kt_mode (kt->cipher);
- if (!(mode == OPENVPN_MODE_CBC
-#ifdef ALLOW_NON_CBC_CIPHERS
- || (cfb_ofb_allowed && (mode == OPENVPN_MODE_CFB || mode == OPENVPN_MODE_OFB))
+ if (!(cipher_kt_mode_cbc(kt->cipher)
+#ifdef ENABLE_OFB_CFB_MODE
+ || (cfb_ofb_allowed && cipher_kt_mode_ofb_cfb(kt->cipher))
#endif
))
-#ifdef ENABLE_SMALL
msg (M_FATAL, "Cipher '%s' mode not supported", ciphername);
-#else
- msg (M_FATAL, "Cipher '%s' uses a mode not supported by " PACKAGE_NAME " in your current configuration. CBC mode is always supported, while CFB and OFB modes are supported only when using SSL/TLS authentication and key exchange mode, and when " PACKAGE_NAME " has been built with ALLOW_NON_CBC_CIPHERS.", ciphername);
-#endif
}
}
else
@@ -606,18 +604,10 @@ fixup_key (struct key *key, const struct key_type *kt)
void
check_replay_iv_consistency (const struct key_type *kt, bool packet_id, bool use_iv)
{
- if (cfb_ofb_mode (kt) && !(packet_id && use_iv))
- msg (M_FATAL, "--no-replay or --no-iv cannot be used with a CFB or OFB mode cipher");
-}
+ ASSERT(kt);
-bool
-cfb_ofb_mode (const struct key_type* kt)
-{
- if (kt && kt->cipher) {
- const unsigned int mode = cipher_kt_mode (kt->cipher);
- return mode == OPENVPN_MODE_CFB || mode == OPENVPN_MODE_OFB;
- }
- return false;
+ if (cipher_kt_mode_ofb_cfb(kt->cipher) && !(packet_id && use_iv))
+ msg (M_FATAL, "--no-replay or --no-iv cannot be used with a CFB or OFB mode cipher");
}
/*
diff --git a/src/openvpn/crypto.h b/src/openvpn/crypto.h
index 3b4b88e..bf2f802 100644
--- a/src/openvpn/crypto.h
+++ b/src/openvpn/crypto.h
@@ -32,8 +32,6 @@
#ifdef ENABLE_CRYPTO
-#define ALLOW_NON_CBC_CIPHERS
-
#include "crypto_backend.h"
#include "basic.h"
#include "buffer.h"
@@ -189,8 +187,6 @@ bool write_key (const struct key *key, const struct key_type *kt,
int read_key (struct key *key, const struct key_type *kt, struct buffer *buf);
-bool cfb_ofb_mode (const struct key_type* kt);
-
void init_key_type (struct key_type *kt, const char *ciphername,
bool ciphername_defined, const char *authname, bool authname_defined,
int keysize, bool cfb_ofb_allowed, bool warn);
diff --git a/src/openvpn/crypto_backend.h b/src/openvpn/crypto_backend.h
index 5ae47e6..bc067a7 100644
--- a/src/openvpn/crypto_backend.h
+++ b/src/openvpn/crypto_backend.h
@@ -230,6 +230,26 @@ int cipher_kt_block_size (const cipher_kt_t *cipher_kt);
*/
int cipher_kt_mode (const cipher_kt_t *cipher_kt);
+/**
+ * Check if the supplied cipher is a supported CBC mode cipher.
+ *
+ * @param cipher Static cipher parameters. May not be NULL.
+ *
+ * @return true iff the cipher is a CBC mode cipher.
+ */
+bool cipher_kt_mode_cbc(const cipher_kt_t *cipher)
+ __attribute__((nonnull));
+
+/**
+ * Check if the supplied cipher is a supported OFB or CFB mode cipher.
+ *
+ * @param cipher Static cipher parameters. May not be NULL.
+ *
+ * @return true iff the cipher is a OFB or CFB mode cipher.
+ */
+bool cipher_kt_mode_ofb_cfb(const cipher_kt_t *cipher)
+ __attribute__((nonnull));
+
/**
*
@@ -288,6 +308,16 @@ int cipher_ctx_block_size (const cipher_ctx_t *ctx);
int cipher_ctx_mode (const cipher_ctx_t *ctx);
/**
+ * Returns the static cipher parameters for this context.
+ *
+ * @param ctx Cipher's context. May not be NULL.
+ *
+ * @return Static cipher parameters for the supplied context.
+ */
+const cipher_kt_t *cipher_ctx_get_cipher_kt (const cipher_ctx_t *ctx)
+ __attribute__((nonnull));
+
+/**
* Resets the given cipher context, setting the IV to the specified value.
* Preserves the associated key information.
*
diff --git a/src/openvpn/crypto_openssl.c b/src/openvpn/crypto_openssl.c
index 1501bc8..4067701 100644
--- a/src/openvpn/crypto_openssl.c
+++ b/src/openvpn/crypto_openssl.c
@@ -40,6 +40,7 @@
#include "basic.h"
#include "buffer.h"
#include "integer.h"
+#include "crypto.h"
#include "crypto_backend.h"
#include <openssl/objects.h>
#include <openssl/evp.h>
@@ -84,24 +85,6 @@
#endif
-static inline int
-EVP_CipherInit_ov (EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, uint8_t *key, uint8_t *iv, int enc)
-{
- return EVP_CipherInit (ctx, type, key, iv, enc);
-}
-
-static inline int
-EVP_CipherUpdate_ov (EVP_CIPHER_CTX *ctx, uint8_t *out, int *outl, uint8_t *in, int inl)
-{
- return EVP_CipherUpdate (ctx, out, outl, in, inl);
-}
-
-static inline bool
-cipher_ok (const char* name)
-{
- return true;
-}
-
#ifndef EVP_CIPHER_name
#define EVP_CIPHER_name(e) OBJ_nid2sn(EVP_CIPHER_nid(e))
#endif
@@ -306,25 +289,30 @@ show_available_ciphers ()
"used as a parameter to the --cipher option. The default\n"
"key size is shown as well as whether or not it can be\n"
"changed with the --keysize directive. Using a CBC mode\n"
- "is recommended.\n\n");
+ "is recommended. In static key mode only CBC mode is allowed.\n\n");
#endif
for (nid = 0; nid < 10000; ++nid) /* is there a better way to get the size of the nid list? */
{
const EVP_CIPHER *cipher = EVP_get_cipherbynid (nid);
- if (cipher && cipher_ok (OBJ_nid2sn (nid)))
+ if (cipher)
{
- const unsigned int mode = EVP_CIPHER_mode (cipher);
- if (mode == EVP_CIPH_CBC_MODE
-#ifdef ALLOW_NON_CBC_CIPHERS
- || mode == EVP_CIPH_CFB_MODE || mode == EVP_CIPH_OFB_MODE
+ if (cipher_kt_mode_cbc(cipher)
+#ifdef ENABLE_OFB_CFB_MODE
+ || cipher_kt_mode_ofb_cfb(cipher)
#endif
)
- printf ("%s %d bit default key (%s)\n",
- OBJ_nid2sn (nid),
- EVP_CIPHER_key_length (cipher) * 8,
- ((EVP_CIPHER_flags (cipher) & EVP_CIPH_VARIABLE_LENGTH) ?
- "variable" : "fixed"));
+ {
+ const char *var_key_size =
+ (EVP_CIPHER_flags (cipher) & EVP_CIPH_VARIABLE_LENGTH) ?
+ "variable" : "fixed";
+ const char *ssl_only = cipher_kt_mode_ofb_cfb(cipher) ?
+ " (TLS client/server mode)" : "";
+
+ printf ("%s %d bit default key (%s)%s\n", OBJ_nid2sn (nid),
+ EVP_CIPHER_key_length (cipher) * 8, var_key_size,
+ ssl_only);
+ }
}
}
printf ("\n");
@@ -491,7 +479,7 @@ cipher_kt_get (const char *ciphername)
cipher = EVP_get_cipherbyname (ciphername);
- if ((NULL == cipher) || !cipher_ok (OBJ_nid2sn (EVP_CIPHER_nid (cipher))))
+ if (NULL == cipher)
msg (M_SSLERR, "Cipher algorithm '%s' not found", ciphername);
if (EVP_CIPHER_key_length (cipher) > MAX_CIPHER_KEY_LENGTH)
@@ -536,6 +524,29 @@ cipher_kt_mode (const EVP_CIPHER *cipher_kt)
return EVP_CIPHER_mode (cipher_kt);
}
+bool
+cipher_kt_mode_cbc(const cipher_kt_t *cipher)
+{
+ return cipher_kt_mode(cipher) == OPENVPN_MODE_CBC
+#ifdef EVP_CIPH_FLAG_AEAD_CIPHER
+ /* Exclude AEAD cipher modes, they require a different API */
+ && !(EVP_CIPHER_flags(cipher) & EVP_CIPH_FLAG_AEAD_CIPHER)
+#endif
+ ;
+}
+
+bool
+cipher_kt_mode_ofb_cfb(const cipher_kt_t *cipher)
+{
+ return (cipher_kt_mode(cipher) == OPENVPN_MODE_OFB ||
+ cipher_kt_mode(cipher) == OPENVPN_MODE_CFB)
+#ifdef EVP_CIPH_FLAG_AEAD_CIPHER
+ /* Exclude AEAD cipher modes, they require a different API */
+ && !(EVP_CIPHER_flags(cipher) & EVP_CIPH_FLAG_AEAD_CIPHER)
+#endif
+ ;
+}
+
/*
*
* Generic cipher context functions
@@ -552,13 +563,13 @@ cipher_ctx_init (EVP_CIPHER_CTX *ctx, uint8_t *key, int key_len,
CLEAR (*ctx);
EVP_CIPHER_CTX_init (ctx);
- if (!EVP_CipherInit_ov (ctx, kt, NULL, NULL, enc))
+ if (!EVP_CipherInit (ctx, kt, NULL, NULL, enc))
msg (M_SSLERR, "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");
#endif
- if (!EVP_CipherInit_ov (ctx, NULL, key, NULL, enc))
+ if (!EVP_CipherInit (ctx, NULL, key, NULL, enc))
msg (M_SSLERR, "EVP cipher init #2");
/* make sure we used a big enough key */
@@ -589,17 +600,24 @@ cipher_ctx_mode (const EVP_CIPHER_CTX *ctx)
return EVP_CIPHER_CTX_mode (ctx);
}
+const cipher_kt_t *
+cipher_ctx_get_cipher_kt (const cipher_ctx_t *ctx)
+{
+ return EVP_CIPHER_CTX_cipher(ctx);
+}
+
+
int
cipher_ctx_reset (EVP_CIPHER_CTX *ctx, uint8_t *iv_buf)
{
- return EVP_CipherInit_ov (ctx, NULL, NULL, iv_buf, -1);
+ return EVP_CipherInit (ctx, NULL, NULL, iv_buf, -1);
}
int
cipher_ctx_update (EVP_CIPHER_CTX *ctx, uint8_t *dst, int *dst_len,
uint8_t *src, int src_len)
{
- return EVP_CipherUpdate_ov (ctx, dst, dst_len, src, src_len);
+ return EVP_CipherUpdate (ctx, dst, dst_len, src, src_len);
}
int
diff --git a/src/openvpn/crypto_polarssl.c b/src/openvpn/crypto_polarssl.c
index 1f27d6c..8bf8d8d 100644
--- a/src/openvpn/crypto_polarssl.c
+++ b/src/openvpn/crypto_polarssl.c
@@ -416,6 +416,19 @@ cipher_kt_mode (const cipher_info_t *cipher_kt)
return cipher_kt->mode;
}
+bool
+cipher_kt_mode_cbc(const cipher_kt_t *cipher)
+{
+ return cipher_kt_mode(cipher) == OPENVPN_MODE_CBC;
+}
+
+bool
+cipher_kt_mode_ofb_cfb(const cipher_kt_t *cipher)
+{
+ return (cipher_kt_mode(cipher) == OPENVPN_MODE_OFB ||
+ cipher_kt_mode(cipher) == OPENVPN_MODE_CFB);
+}
+
/*
*
@@ -464,6 +477,14 @@ int cipher_ctx_mode (const cipher_context_t *ctx)
return cipher_kt_mode(ctx->cipher_info);
}
+const cipher_kt_t *
+cipher_ctx_get_cipher_kt (const cipher_ctx_t *ctx)
+{
+ ASSERT(NULL != ctx);
+
+ return ctx->cipher_info;
+}
+
int cipher_ctx_reset (cipher_context_t *ctx, uint8_t *iv_buf)
{
return 0 == cipher_reset(ctx, iv_buf);
diff --git a/src/openvpn/forward.c b/src/openvpn/forward.c
index 024cd58..7f0d083 100644
--- a/src/openvpn/forward.c
+++ b/src/openvpn/forward.c
@@ -952,6 +952,15 @@ read_incoming_tun (struct context *c)
return;
}
+ /* Was TUN/TAP I/O operation aborted? */
+ if (tuntap_abort(c->c2.buf.len))
+ {
+ register_signal(c, SIGTERM, "tun-abort");
+ msg(M_FATAL, "TUN/TAP I/O operation aborted, exiting");
+ perf_pop();
+ return;
+ }
+
/* Check the status return from read() */
check_status (c->c2.buf.len, "read from TUN/TAP", NULL, c->c1.tuntap);
diff --git a/src/openvpn/helper.c b/src/openvpn/helper.c
index d9eef03..0ed0b2b 100644
--- a/src/openvpn/helper.c
+++ b/src/openvpn/helper.c
@@ -232,6 +232,8 @@ helper_client_server (struct options *o)
* if !nopool:
* ifconfig-pool 10.8.0.2 10.8.0.254 255.255.255.0
* push "route-gateway 10.8.0.1"
+ * if route-gateway unset:
+ * route-gateway 10.8.0.2
*/
if (o->server_defined)
@@ -311,8 +313,10 @@ helper_client_server (struct options *o)
ifconfig_pool_verify_range (M_USAGE, o->ifconfig_pool_start, o->ifconfig_pool_end);
}
o->ifconfig_pool_netmask = o->server_netmask;
-
+
push_option (o, print_opt_route_gateway (o->server_network + 1, &o->gc), M_USAGE);
+ if (!o->route_default_gateway)
+ o->route_default_gateway = print_in_addr_t (o->server_network + 2, 0, &o->gc);
}
else
ASSERT (0);
diff --git a/src/openvpn/init.c b/src/openvpn/init.c
index 52d370b..18f506c 100644
--- a/src/openvpn/init.c
+++ b/src/openvpn/init.c
@@ -183,10 +183,12 @@ ce_management_query_proxy (struct context *c)
if (management)
{
gc = gc_new ();
- struct buffer out = alloc_buf_gc (256, &gc);
- buf_printf (&out, ">PROXY:%u,%s,%s", (l ? l->current : 0) + 1,
- (proto_is_udp (ce->proto) ? "UDP" : "TCP"), np (ce->remote));
- management_notify_generic (management, BSTR (&out));
+ {
+ struct buffer out = alloc_buf_gc (256, &gc);
+ buf_printf (&out, ">PROXY:%u,%s,%s", (l ? l->current : 0) + 1,
+ (proto_is_udp (ce->proto) ? "UDP" : "TCP"), np (ce->remote));
+ management_notify_generic (management, BSTR (&out));
+ }
ce->flags |= CE_MAN_QUERY_PROXY;
while (ce->flags & CE_MAN_QUERY_PROXY)
{
@@ -2159,7 +2161,7 @@ do_init_crypto_tls (struct context *c, const unsigned int flags)
options->use_iv);
/* In short form, unique datagram identifier is 32 bits, in long form 64 bits */
- packet_id_long_form = cfb_ofb_mode (&c->c1.ks.key_type);
+ packet_id_long_form = cipher_kt_mode_ofb_cfb (c->c1.ks.key_type.cipher);
/* Compute MTU parameters */
crypto_adjust_frame_parameters (&c->c2.frame,
diff --git a/src/openvpn/misc.c b/src/openvpn/misc.c
index 56a01a6..8408438 100644
--- a/src/openvpn/misc.c
+++ b/src/openvpn/misc.c
@@ -376,8 +376,11 @@ openvpn_popen (const struct argv *a, const struct env_set *es)
}
else /* parent side */
{
- ret=pipe_stdout[0];
- close (pipe_stdout[1]);
+ int status = 0;
+
+ waitpid(pid, &status, 0);
+ ret = pipe_stdout[0];
+ close (pipe_stdout[1]);
}
}
else {
@@ -869,6 +872,12 @@ test_file (const char *filename)
fclose (fp);
ret = true;
}
+ else
+ {
+ if( openvpn_errno () == EACCES ) {
+ msg( M_WARN | M_ERRNO, "Could not access file '%s'", filename);
+ }
+ }
}
dmsg (D_TEST_FILE, "TEST FILE '%s' [%d]",
diff --git a/src/openvpn/multi.c b/src/openvpn/multi.c
index ab3f10c..374950e 100644
--- a/src/openvpn/multi.c
+++ b/src/openvpn/multi.c
@@ -1452,10 +1452,6 @@ multi_client_connect_post (struct multi_context *m,
option_types_found,
mi->context.c2.es);
- if (!platform_unlink (dc_file))
- msg (D_MULTI_ERRORS, "MULTI: problem deleting temporary file: %s",
- dc_file);
-
/*
* If the --client-connect script generates a config file
* with an --ifconfig-push directive, it will override any
@@ -1698,6 +1694,11 @@ multi_connection_established (struct multi_context *m, struct multi_instance *mi
multi_client_connect_post (m, mi, dc_file, option_permissions_mask, &option_types_found);
++cc_succeeded_count;
}
+
+ if (!platform_unlink (dc_file))
+ msg (D_MULTI_ERRORS, "MULTI: problem deleting temporary file: %s",
+ dc_file);
+
script_depr_failed:
argv_reset (&argv);
}
@@ -1751,6 +1752,11 @@ multi_connection_established (struct multi_context *m, struct multi_instance *mi
}
else
cc_succeeded = false;
+
+ if (!platform_unlink (dc_file))
+ msg (D_MULTI_ERRORS, "MULTI: problem deleting temporary file: %s",
+ dc_file);
+
script_failed:
argv_reset (&argv);
}
@@ -2153,8 +2159,17 @@ multi_process_incoming_link (struct multi_context *m, struct multi_instance *ins
/* make sure that source address is associated with this client */
else if (multi_get_instance_by_virtual_addr (m, &src, true) != m->pending)
{
- msg (D_MULTI_DROPPED, "MULTI: bad source address from client [%s], packet dropped",
- mroute_addr_print (&src, &gc));
+ /* IPv6 link-local address (fe80::xxx)? */
+ if ( (src.type & MR_ADDR_MASK) == MR_ADDR_IPV6 &&
+ src.addr[0] == 0xfe && src.addr[1] == 0x80 )
+ {
+ /* do nothing, for now. TODO: add address learning */
+ }
+ else
+ {
+ msg (D_MULTI_DROPPED, "MULTI: bad source address from client [%s], packet dropped",
+ mroute_addr_print (&src, &gc));
+ }
c->c2.to_tun.len = 0;
}
/* client-to-client communication enabled? */
diff --git a/src/openvpn/options.c b/src/openvpn/options.c
index 1c0edbc..fa53a17 100644
--- a/src/openvpn/options.c
+++ b/src/openvpn/options.c
@@ -577,8 +577,8 @@ static const char usage_message[] =
" and optionally the root CA certificate.\n"
#endif
#ifdef ENABLE_X509ALTUSERNAME
- "--x509-username-field : Field used in x509 certificate to be username.\n"
- " Default is CN.\n"
+ "--x509-username-field : Field in x509 certificate containing the username.\n"
+ " Default is CN in the Subject field.\n"
#endif
"--verify-hash : Specify SHA1 fingerprint for level-1 cert.\n"
#ifdef WIN32
@@ -3439,18 +3439,21 @@ usage_small (void)
void
show_library_versions(const unsigned int flags)
{
- msg (flags, "library versions: %s%s%s",
#ifdef ENABLE_SSL
- get_ssl_library_version(),
+#define SSL_LIB_VER_STR get_ssl_library_version()
#else
- "",
+#define SSL_LIB_VER_STR ""
#endif
#ifdef ENABLE_LZO
- ", LZO ", lzo_version_string()
+#define LZO_LIB_VER_STR ", LZO ", lzo_version_string()
#else
- "", ""
+#define LZO_LIB_VER_STR "", ""
#endif
- );
+
+ msg (flags, "library versions: %s%s%s", SSL_LIB_VER_STR, LZO_LIB_VER_STR);
+
+#undef SSL_LIB_VER_STR
+#undef LZO_LIB_VER_STR
}
static void
@@ -6872,10 +6875,28 @@ add_option (struct options *options,
#ifdef ENABLE_X509ALTUSERNAME
else if (streq (p[0], "x509-username-field") && p[1])
{
+ /* This option used to automatically upcase the fieldname passed as the
+ * option argument, e.g., "ou" became "OU". Now, this "helpfulness" is
+ * fine-tuned by only upcasing Subject field attribute names which consist
+ * of all lower-case characters. Mixed-case attributes such as
+ * "emailAddress" are left as-is. An option parameter having the "ext:"
+ * prefix for matching X.509v3 extended fields will also remain unchanged.
+ */
char *s = p[1];
+
VERIFY_PERMISSION (OPT_P_GENERAL);
- if( strncmp ("ext:",s,4) != 0 )
- while ((*s = toupper(*s)) != '\0') s++; /* Uppercase if necessary */
+ if (strncmp("ext:", s, 4) != 0)
+ {
+ size_t i = 0;
+ while (s[i] && !isupper(s[i])) i++;
+ if (strlen(s) == i)
+ {
+ while ((*s = toupper(*s)) != '\0') s++;
+ msg(M_WARN, "DEPRECATED FEATURE: automatically upcased the "
+ "--x509-username-field parameter to '%s'; please update your"
+ "configuration", p[1]);
+ }
+ }
options->x509_username_field = p[1];
}
#endif /* ENABLE_X509ALTUSERNAME */
diff --git a/src/openvpn/options.h b/src/openvpn/options.h
index 8cbb85a..2c18838 100644
--- a/src/openvpn/options.h
+++ b/src/openvpn/options.h
@@ -683,6 +683,8 @@ void notnull (const char *arg, const char *description);
void usage_small (void);
+void show_library_versions(const unsigned int flags);
+
void init_options (struct options *o, const bool init_gc);
void uninit_options (struct options *o);
diff --git a/src/openvpn/route.c b/src/openvpn/route.c
index 532edc6..cc85e4d 100644
--- a/src/openvpn/route.c
+++ b/src/openvpn/route.c
@@ -1318,15 +1318,18 @@ add_route (struct route_ipv4 *r,
#if defined(TARGET_LINUX)
#ifdef ENABLE_IPROUTE
- /* FIXME -- add on-link support for ENABLE_IPROUTE */
- argv_printf (&argv, "%s route add %s/%d via %s",
+ argv_printf (&argv, "%s route add %s/%d",
iproute_path,
network,
- count_netmask_bits(netmask),
- gateway);
+ count_netmask_bits(netmask));
+
if (r->flags & RT_METRIC_DEFINED)
argv_printf_cat (&argv, "metric %d", r->metric);
+ if (is_on_link (is_local_route, flags, rgi))
+ argv_printf_cat (&argv, "dev %s", rgi->iface);
+ else
+ argv_printf_cat (&argv, "via %s", gateway);
#else
argv_printf (&argv, "%s add -net %s netmask %s",
ROUTE_PATH,
diff --git a/src/openvpn/socket.c b/src/openvpn/socket.c
index 23566f1..6e68c18 100644
--- a/src/openvpn/socket.c
+++ b/src/openvpn/socket.c
@@ -1150,7 +1150,6 @@ resolve_bind_local (struct link_socket *sock)
case AF_INET6:
{
int status;
- int err;
CLEAR(sock->info.lsa->local.addr.in6);
if (sock->local_host)
{
@@ -1173,7 +1172,7 @@ resolve_bind_local (struct link_socket *sock)
{
msg (M_FATAL, "getaddr6() failed for local \"%s\": %s",
sock->local_host,
- gai_strerror(err));
+ gai_strerror(status));
}
sock->info.lsa->local.addr.in6.sin6_port = htons (sock->local_port);
}
@@ -1227,6 +1226,7 @@ resolve_remote (struct link_socket *sock,
unsigned int flags = sf2gaf(GETADDR_RESOLVE|GETADDR_UPDATE_MANAGEMENT_STATE, sock->sockflags);
int retry = 0;
int status = -1;
+ struct addrinfo* ai;
if (sock->connection_profiles_defined && sock->resolve_retry_seconds == RESOLV_RETRY_INFINITE)
{
@@ -1263,7 +1263,6 @@ resolve_remote (struct link_socket *sock,
ASSERT (0);
}
- struct addrinfo* ai;
/* Temporary fix, this need to be changed for dual stack */
status = openvpn_getaddrinfo(flags, sock->remote_host, retry,
signal_received, af, &ai);
diff --git a/src/openvpn/socket.h b/src/openvpn/socket.h
index 4e7e7f8..793cd9f 100644
--- a/src/openvpn/socket.h
+++ b/src/openvpn/socket.h
@@ -1023,7 +1023,7 @@ static inline void
link_socket_set_tos (struct link_socket *ls)
{
if (ls && ls->ptos_defined)
- setsockopt (ls->sd, IPPROTO_IP, IP_TOS, &ls->ptos, sizeof (ls->ptos));
+ setsockopt (ls->sd, IPPROTO_IP, IP_TOS, (const void *)&ls->ptos, sizeof (ls->ptos));
}
#endif
diff --git a/src/openvpn/ssl_backend.h b/src/openvpn/ssl_backend.h
index b37b1e5..fc23175 100644
--- a/src/openvpn/ssl_backend.h
+++ b/src/openvpn/ssl_backend.h
@@ -472,6 +472,6 @@ void get_highest_preference_tls_cipher (char *buf, int size);
* return a pointer to a static memory area containing the
* name and version number of the SSL library in use
*/
-char * get_ssl_library_version(void);
+const char * get_ssl_library_version(void);
#endif /* SSL_BACKEND_H_ */
diff --git a/src/openvpn/ssl_openssl.c b/src/openvpn/ssl_openssl.c
index 481600a..e77b736 100644
--- a/src/openvpn/ssl_openssl.c
+++ b/src/openvpn/ssl_openssl.c
@@ -261,8 +261,7 @@ tls_ctx_restrict_ciphers(struct tls_root_ctx *ctx, const char *ciphers)
const tls_cipher_name_pair *cipher_pair;
- const size_t openssl_ciphers_size = 4096;
- char openssl_ciphers[openssl_ciphers_size];
+ char openssl_ciphers[4096];
size_t openssl_ciphers_len = 0;
openssl_ciphers[0] = '\0';
@@ -301,8 +300,8 @@ tls_ctx_restrict_ciphers(struct tls_root_ctx *ctx, const char *ciphers)
}
// Make sure new cipher name fits in cipher string
- if (((openssl_ciphers_size-1) - openssl_ciphers_len) < current_cipher_len) {
- msg(M_SSLERR, "Failed to set restricted TLS cipher list, too long (>%zu).", openssl_ciphers_size-1);
+ 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);
}
// Concatenate cipher name to OpenSSL cipher string
@@ -1355,7 +1354,7 @@ get_highest_preference_tls_cipher (char *buf, int size)
SSL_CTX_free (ctx);
}
-char *
+const char *
get_ssl_library_version(void)
{
return SSLeay_version(SSLEAY_VERSION);
diff --git a/src/openvpn/ssl_polarssl.c b/src/openvpn/ssl_polarssl.c
index 0dfffd6..5718c8c 100644
--- a/src/openvpn/ssl_polarssl.c
+++ b/src/openvpn/ssl_polarssl.c
@@ -40,6 +40,7 @@
#include "errlevel.h"
#include "ssl_backend.h"
+#include "base64.h"
#include "buffer.h"
#include "misc.h"
#include "manage.h"
@@ -49,7 +50,9 @@
#include <polarssl/havege.h>
#include "ssl_verify_polarssl.h"
+#include <polarssl/error.h>
#include <polarssl/pem.h>
+#include <polarssl/version.h>
void
tls_init_lib()
@@ -204,12 +207,13 @@ tls_ctx_restrict_ciphers(struct tls_root_ctx *ctx, const char *ciphers)
void
tls_ctx_load_dh_params (struct tls_root_ctx *ctx, const char *dh_file,
- const char *dh_file_inline
+ const char *dh_inline
)
{
- if (!strcmp (dh_file, INLINE_FILE_TAG) && dh_file_inline)
+ if (!strcmp (dh_file, INLINE_FILE_TAG) && dh_inline)
{
- if (0 != x509parse_dhm(ctx->dhm_ctx, dh_file_inline, strlen(dh_file_inline)))
+ if (0 != x509parse_dhm(ctx->dhm_ctx, (const unsigned char *) dh_inline,
+ strlen(dh_inline)))
msg (M_FATAL, "Cannot read inline DH parameters");
}
else
@@ -242,15 +246,15 @@ tls_ctx_load_cryptoapi(struct tls_root_ctx *ctx, const char *cryptoapi_cert)
void
tls_ctx_load_cert_file (struct tls_root_ctx *ctx, const char *cert_file,
- const char *cert_file_inline
+ const char *cert_inline
)
{
ASSERT(NULL != ctx);
- if (!strcmp (cert_file, INLINE_FILE_TAG) && cert_file_inline)
+ if (!strcmp (cert_file, INLINE_FILE_TAG) && cert_inline)
{
- if (0 != x509parse_crt(ctx->crt_chain, cert_file_inline,
- strlen(cert_file_inline)))
+ if (0 != x509parse_crt(ctx->crt_chain,
+ (const unsigned char *) cert_inline, strlen(cert_inline)))
msg (M_FATAL, "Cannot load inline certificate file");
}
else
@@ -262,30 +266,30 @@ tls_ctx_load_cert_file (struct tls_root_ctx *ctx, const char *cert_file,
int
tls_ctx_load_priv_file (struct tls_root_ctx *ctx, const char *priv_key_file,
- const char *priv_key_file_inline
+ const char *priv_key_inline
)
{
int status;
ASSERT(NULL != ctx);
- if (!strcmp (priv_key_file, INLINE_FILE_TAG) && priv_key_file_inline)
+ if (!strcmp (priv_key_file, INLINE_FILE_TAG) && priv_key_inline)
{
status = x509parse_key(ctx->priv_key,
- priv_key_file_inline, strlen(priv_key_file_inline),
+ (const unsigned char *) priv_key_inline, strlen(priv_key_inline),
NULL, 0);
- if (POLARSSL_ERR_PEM_PASSWORD_REQUIRED == status)
+ if (POLARSSL_ERR_X509_PASSWORD_REQUIRED == status)
{
char passbuf[512] = {0};
pem_password_callback(passbuf, 512, 0, NULL);
status = x509parse_key(ctx->priv_key,
- priv_key_file_inline, strlen(priv_key_file_inline),
- passbuf, strlen(passbuf));
+ (const unsigned char *) priv_key_inline, strlen(priv_key_inline),
+ (const unsigned char *) passbuf, strlen(passbuf));
}
}
else
{
status = x509parse_keyfile(ctx->priv_key, priv_key_file, NULL);
- if (POLARSSL_ERR_PEM_PASSWORD_REQUIRED == status)
+ if (POLARSSL_ERR_X509_PASSWORD_REQUIRED == status)
{
char passbuf[512] = {0};
pem_password_callback(passbuf, 512, 0, NULL);
@@ -295,7 +299,7 @@ tls_ctx_load_priv_file (struct tls_root_ctx *ctx, const char *priv_key_file,
if (0 != status)
{
#ifdef ENABLE_MANAGEMENT
- if (management && (POLARSSL_ERR_PEM_PASSWORD_MISMATCH == status))
+ if (management && (POLARSSL_ERR_X509_PASSWORD_MISMATCH == status))
management_auth_failure (management, UP_TYPE_PRIVATE_KEY, NULL);
#endif
msg (M_WARN, "Cannot load private key file %s", priv_key_file);
@@ -467,16 +471,17 @@ static inline size_t external_key_len(void *vctx)
#endif
void tls_ctx_load_ca (struct tls_root_ctx *ctx, const char *ca_file,
- const char *ca_file_inline,
+ const char *ca_inline,
const char *ca_path, bool tls_server
)
{
if (ca_path)
msg(M_FATAL, "ERROR: PolarSSL cannot handle the capath directive");
- if (ca_file && !strcmp (ca_file, INLINE_FILE_TAG) && ca_file_inline)
+ if (ca_file && !strcmp (ca_file, INLINE_FILE_TAG) && ca_inline)
{
- if (0 != x509parse_crt(ctx->ca_chain, ca_file_inline, strlen(ca_file_inline)))
+ if (0 != x509parse_crt(ctx->ca_chain, (const unsigned char *) ca_inline,
+ strlen(ca_inline)))
msg (M_FATAL, "Cannot load inline CA certificates");
}
else
@@ -489,15 +494,16 @@ void tls_ctx_load_ca (struct tls_root_ctx *ctx, const char *ca_file,
void
tls_ctx_load_extra_certs (struct tls_root_ctx *ctx, const char *extra_certs_file,
- const char *extra_certs_file_inline
+ const char *extra_certs_inline
)
{
ASSERT(NULL != ctx);
- if (!strcmp (extra_certs_file, INLINE_FILE_TAG) && extra_certs_file_inline)
+ if (!strcmp (extra_certs_file, INLINE_FILE_TAG) && extra_certs_inline)
{
- if (0 != x509parse_crt(ctx->crt_chain, extra_certs_file_inline,
- strlen(extra_certs_file_inline)))
+ if (0 != x509parse_crt(ctx->crt_chain,
+ (const unsigned char *) extra_certs_inline,
+ strlen(extra_certs_inline)))
msg (M_FATAL, "Cannot load inline extra-certs file");
}
else
@@ -620,7 +626,7 @@ static void my_debug( void *ctx, int level, const char *str )
void tls_ctx_personalise_random(struct tls_root_ctx *ctx)
{
static char old_sha256_hash[32] = {0};
- char sha256_hash[32] = {0};
+ unsigned char sha256_hash[32] = {0};
ctr_drbg_context *cd_ctx = rand_ctx_get();
if (NULL != ctx->crt_chain)
@@ -1068,7 +1074,7 @@ get_highest_preference_tls_cipher (char *buf, int size)
strncpynt (buf, cipher_name, size);
}
-char *
+const char *
get_ssl_library_version(void)
{
static char polar_version[30];
diff --git a/src/openvpn/ssl_verify_openssl.c b/src/openvpn/ssl_verify_openssl.c
index 19982ae..e1118d6 100644
--- a/src/openvpn/ssl_verify_openssl.c
+++ b/src/openvpn/ssl_verify_openssl.c
@@ -97,9 +97,7 @@ static
bool extract_x509_extension(X509 *cert, char *fieldname, char *out, int size)
{
bool retval = false;
- X509_EXTENSION *pExt;
char *buf = 0;
- int length = 0;
GENERAL_NAMES *extensions;
int nid = OBJ_txt2nid(fieldname);
@@ -591,12 +589,12 @@ x509_verify_crl(const char *crl_file, X509 *peer_cert, const char *subject)
in = BIO_new_file (crl_file, "r");
if (in == NULL) {
- msg (M_ERR, "CRL: cannot read: %s", crl_file);
+ msg (M_WARN, "CRL: cannot read: %s", crl_file);
goto end;
}
crl=PEM_read_bio_X509_CRL(in,NULL,NULL,NULL);
if (crl == NULL) {
- msg (M_ERR, "CRL: cannot read CRL from file %s", crl_file);
+ msg (M_WARN, "CRL: cannot read CRL from file %s", crl_file);
goto end;
}
diff --git a/src/openvpn/ssl_verify_polarssl.c b/src/openvpn/ssl_verify_polarssl.c
index 3fd861c..f8f9ab5 100644
--- a/src/openvpn/ssl_verify_polarssl.c
+++ b/src/openvpn/ssl_verify_polarssl.c
@@ -380,7 +380,7 @@ x509_verify_cert_eku (x509_cert *cert, const char * const expected_oid)
}
}
- if (0 == x509_oid_get_numeric_string( oid_num_str,
+ if (0 < x509_oid_get_numeric_string( oid_num_str,
sizeof (oid_num_str), oid))
{
msg (D_HANDSHAKE, "++ Certificate has EKU (oid) %s, expects %s",
@@ -414,9 +414,12 @@ x509_verify_crl(const char *crl_file, x509_cert *cert, const char *subject)
result_t retval = FAILURE;
x509_crl crl = {0};
- if (x509parse_crlfile(&crl, crl_file) != 0)
+ int polar_retval = x509parse_crlfile(&crl, crl_file);
+ if (polar_retval != 0)
{
- msg (M_ERR, "CRL: cannot read CRL from file %s", crl_file);
+ char errstr[128];
+ error_strerror(polar_retval, errstr, sizeof(errstr));
+ msg (M_WARN, "CRL: cannot read CRL from file %s (%s)", crl_file, errstr);
goto end;
}
diff --git a/src/openvpn/syshead.h b/src/openvpn/syshead.h
index 7a7d53a..f957a10 100644
--- a/src/openvpn/syshead.h
+++ b/src/openvpn/syshead.h
@@ -349,6 +349,14 @@
#endif /* TARGET_DRAGONFLY */
+#ifdef TARGET_DARWIN
+
+#ifdef HAVE_NETINET_TCP_H
+#include <netinet/tcp.h>
+#endif
+
+#endif /* TARGET_DARWIN */
+
#ifdef WIN32
#include <iphlpapi.h>
#include <ntddndis.h>
diff --git a/src/openvpn/tun.h b/src/openvpn/tun.h
index 085d6a3..1931c52 100644
--- a/src/openvpn/tun.h
+++ b/src/openvpn/tun.h
@@ -374,6 +374,19 @@ tuntap_stop (int status)
return false;
}
+static inline bool
+tuntap_abort(int status)
+{
+ /*
+ * Typically generated when driver is halted.
+ */
+ if (status < 0)
+ {
+ return openvpn_errno() == ERROR_OPERATION_ABORTED;
+ }
+ return false;
+}
+
static inline int
tun_write_win32 (struct tuntap *tt, struct buffer *buf)
{
@@ -415,6 +428,12 @@ tuntap_stop (int status)
return false;
}
+static inline bool
+tuntap_abort(int status)
+{
+ return false;
+}
+
static inline void
tun_standby_init (struct tuntap *tt)
{
diff --git a/src/openvpn/win32.c b/src/openvpn/win32.c
index 13fd881..f35c96b 100644
--- a/src/openvpn/win32.c
+++ b/src/openvpn/win32.c
@@ -870,6 +870,9 @@ openvpn_execve (const struct argv *a, const struct env_set *es, const unsigned i
WCHAR *cl = wide_cmd_line (a, &gc);
WCHAR *cmd = wide_string (a->argv[0], &gc);
+ /* this allows console programs to run, and is ignored otherwise */
+ DWORD proc_flags = CREATE_NO_WINDOW;
+
CLEAR (start_info);
CLEAR (proc_info);
@@ -879,9 +882,6 @@ openvpn_execve (const struct argv *a, const struct env_set *es, const unsigned i
start_info.dwFlags = STARTF_USESHOWWINDOW;
start_info.wShowWindow = SW_HIDE;
- /* this allows console programs to run, and is ignored otherwise */
- DWORD proc_flags = CREATE_NO_WINDOW;
-
if (CreateProcessW (cmd, cl, NULL, NULL, FALSE, proc_flags, env, NULL, &start_info, &proc_info))
{
DWORD exit_status = 0;