summaryrefslogtreecommitdiff
path: root/openvpn
diff options
context:
space:
mode:
Diffstat (limited to 'openvpn')
-rw-r--r--openvpn/Makefile.am9
-rw-r--r--openvpn/config-version.h.in1
-rw-r--r--openvpn/doc/doxygen/openvpn.doxyfile2
-rw-r--r--openvpn/doc/openvpn.81
-rw-r--r--openvpn/src/openvpn/comp.c135
-rw-r--r--openvpn/src/openvpn/comp.h171
-rw-r--r--openvpn/src/openvpn/compstub.c118
-rw-r--r--openvpn/src/openvpn/crypto_openssl.c6
-rw-r--r--openvpn/src/openvpn/error.c1
-rw-r--r--openvpn/src/openvpn/init.c39
-rw-r--r--openvpn/src/openvpn/manage.c157
-rw-r--r--openvpn/src/openvpn/manage.h8
-rw-r--r--openvpn/src/openvpn/multi.c20
-rw-r--r--openvpn/src/openvpn/multi.h1
-rw-r--r--openvpn/src/openvpn/options.c8
-rw-r--r--openvpn/src/openvpn/pf.c2
-rw-r--r--openvpn/src/openvpn/route.c20
-rw-r--r--openvpn/src/openvpn/snappy.c189
-rw-r--r--openvpn/src/openvpn/snappy.h39
-rw-r--r--openvpn/src/openvpn/socket.c37
-rw-r--r--openvpn/src/openvpn/socket.h14
-rw-r--r--openvpn/src/openvpn/ssl.c84
-rw-r--r--openvpn/src/openvpn/ssl_openssl.c2
-rw-r--r--openvpn/src/openvpn/syshead.h7
-rw-r--r--openvpn/src/openvpn/tun.c104
-rw-r--r--openvpn/src/openvpn/win32.c5
-rw-r--r--openvpn/version.m42
27 files changed, 935 insertions, 247 deletions
diff --git a/openvpn/Makefile.am b/openvpn/Makefile.am
index c5805797..1a30aa5a 100644
--- a/openvpn/Makefile.am
+++ b/openvpn/Makefile.am
@@ -66,7 +66,6 @@ dist_doc_DATA = \
dist_noinst_DATA = \
.gitignore \
.gitattributes \
- config-version.h.in \
PORTS \
README.IPv6 TODO.IPv6 \
README.polarssl \
@@ -91,8 +90,12 @@ root_DATA = version.sh
endif
config-version.h:
- @CONFIGURE_GIT_REVISION="`GIT_DIR=\"$(top_srcdir)/.git\" $(GIT) rev-parse --symbolic-full-name HEAD`/`GIT_DIR=\"$(top_srcdir)/.git\" $(GIT) rev-parse --short=16 HEAD`"; \
- $(SED) "s#@CONFIGURE_GIT_REVISION[@]#$${CONFIGURE_GIT_REVISION}#g" "$(srcdir)/config-version.h.in" > config-version.h.tmp
+ @CONFIGURE_GIT_CHFILES="`GIT_DIR=\"$(top_srcdir)/.git\" $(GIT) diff-files --name-status -r --ignore-submodules --quiet -- || echo \"+\"`"; \
+ CONFIGURE_GIT_UNCOMMITTED="`GIT_DIR=\"$(top_srcdir)/.git\" $(GIT) diff-index --cached --quiet --ignore-submodules HEAD || echo \"*\"`"; \
+ CONFIGURE_GIT_REVISION="`GIT_DIR=\"$(top_srcdir)/.git\" $(GIT) rev-parse --symbolic-full-name HEAD | cut -d/ -f3-`/`GIT_DIR=\"$(top_srcdir)/.git\" $(GIT) rev-parse --short=16 HEAD`"; \
+ echo "#define CONFIGURE_GIT_REVISION \"$${CONFIGURE_GIT_REVISION}\"" > config-version.h.tmp; \
+ echo "#define CONFIGURE_GIT_FLAGS \"$${CONFIGURE_GIT_CHFILES}$${CONFIGURE_GIT_UNCOMMITTED}\"" >> config-version.h.tmp
+
@if ! [ -f config-version.h ] || ! cmp -s config-version.h.tmp config-version.h; then \
echo "replacing config-version.h"; \
mv config-version.h.tmp config-version.h; \
diff --git a/openvpn/config-version.h.in b/openvpn/config-version.h.in
deleted file mode 100644
index 27ee36af..00000000
--- a/openvpn/config-version.h.in
+++ /dev/null
@@ -1 +0,0 @@
-#define CONFIGURE_GIT_REVISION "@CONFIGURE_GIT_REVISION@"
diff --git a/openvpn/doc/doxygen/openvpn.doxyfile b/openvpn/doc/doxygen/openvpn.doxyfile
index 5d87172c..cf26c42a 100644
--- a/openvpn/doc/doxygen/openvpn.doxyfile
+++ b/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 USE_CRYPTO USE_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_SSL ENABLE_PLUGIN ENABLE_MANAGEMENT ENABLE_OCC HAVE_GETTIMEOFDAY
EXPAND_AS_DEFINED =
SKIP_FUNCTION_MACROS = YES
#---------------------------------------------------------------------------
diff --git a/openvpn/doc/openvpn.8 b/openvpn/doc/openvpn.8
index 4ae351a0..15dd3206 100644
--- a/openvpn/doc/openvpn.8
+++ b/openvpn/doc/openvpn.8
@@ -2506,6 +2506,7 @@ Allow management interface to override
.B \-\-remote
directives (client-only).
.\"*********************************************************
+.TP
.B \-\-management-external-key
Allows usage for external private key file instead of
.B \-\-key
diff --git a/openvpn/src/openvpn/comp.c b/openvpn/src/openvpn/comp.c
new file mode 100644
index 00000000..96922571
--- /dev/null
+++ b/openvpn/src/openvpn/comp.c
@@ -0,0 +1,135 @@
+/*
+ * OpenVPN -- An application to securely tunnel IP networks
+ * over a single UDP port, with support for SSL/TLS-based
+ * session authentication and key exchange,
+ * packet encryption, packet authentication, and
+ * packet compression.
+ *
+ * Copyright (C) 2002-2012 OpenVPN Technologies, Inc. <sales@openvpn.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program (see the file COPYING included with this
+ * distribution); if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#elif defined(_MSC_VER)
+#include "config-msvc.h"
+#endif
+
+#include "syshead.h"
+
+#ifdef USE_COMP
+
+#include "comp.h"
+#include "error.h"
+#include "otime.h"
+
+#include "memdbg.h"
+
+struct compress_context *
+comp_init(const struct compress_options *opt)
+{
+ struct compress_context *compctx = NULL;
+ switch (opt->alg)
+ {
+ case COMP_ALG_STUB:
+ ALLOC_OBJ_CLEAR (compctx, struct compress_context);
+ compctx->flags = opt->flags;
+ compctx->alg = comp_stub_alg;
+ (*compctx->alg.compress_init)(compctx);
+ break;
+#ifdef ENABLE_LZO
+ case COMP_ALG_LZO:
+ ALLOC_OBJ_CLEAR (compctx, struct compress_context);
+ compctx->flags = opt->flags;
+ compctx->alg = lzo_alg;
+ (*compctx->alg.compress_init)(compctx);
+ break;
+#endif
+#ifdef ENABLE_SNAPPY
+ case COMP_ALG_SNAPPY:
+ ALLOC_OBJ_CLEAR (compctx, struct compress_context);
+ compctx->flags = opt->flags;
+ compctx->alg = snappy_alg;
+ (*compctx->alg.compress_init)(compctx);
+ break;
+#endif
+ }
+ return compctx;
+}
+
+void
+comp_uninit(struct compress_context *compctx)
+{
+ if (compctx)
+ {
+ (*compctx->alg.compress_uninit)(compctx);
+ free(compctx);
+ }
+}
+
+void
+comp_add_to_extra_frame(struct frame *frame)
+{
+ /* Leave room for our one-byte compressed/didn't-compress prefix byte. */
+ frame_add_to_extra_frame (frame, COMP_PREFIX_LEN);
+}
+
+void
+comp_add_to_extra_buffer(struct frame *frame)
+{
+ /* Leave room for compression buffer to expand in worst case scenario
+ where data is totally uncompressible */
+ frame_add_to_extra_buffer (frame, COMP_EXTRA_BUFFER (EXPANDED_SIZE(frame)));
+}
+
+void
+comp_print_stats (const struct compress_context *compctx, struct status_output *so)
+{
+ if (compctx)
+ {
+ status_printf (so, "pre-compress bytes," counter_format, compctx->pre_compress);
+ status_printf (so, "post-compress bytes," counter_format, compctx->post_compress);
+ status_printf (so, "pre-decompress bytes," counter_format, compctx->pre_decompress);
+ status_printf (so, "post-decompress bytes," counter_format, compctx->post_decompress);
+ }
+}
+
+/*
+ * Tell our peer which compression algorithms we support.
+ */
+void
+comp_generate_peer_info_string(const struct compress_options *opt, struct buffer *out)
+{
+ if (opt)
+ {
+ bool lzo_avail = false;
+ if (!(opt->flags & COMP_F_ADVERTISE_STUBS_ONLY))
+ {
+#if defined(ENABLE_SNAPPY)
+ buf_printf (out, "IV_SNAPPY=1\n");
+#endif
+#if defined(ENABLE_LZO)
+ buf_printf (out, "IV_LZO=1\n");
+ lzo_avail = true;
+#endif
+ }
+ if (!lzo_avail)
+ buf_printf (out, "IV_LZO_STUB=1\n");
+ buf_printf (out, "IV_COMP_STUB=1\n");
+ }
+}
+
+#endif /* USE_COMP */
diff --git a/openvpn/src/openvpn/comp.h b/openvpn/src/openvpn/comp.h
new file mode 100644
index 00000000..0d2f1bc9
--- /dev/null
+++ b/openvpn/src/openvpn/comp.h
@@ -0,0 +1,171 @@
+/*
+ * OpenVPN -- An application to securely tunnel IP networks
+ * over a single UDP port, with support for SSL/TLS-based
+ * session authentication and key exchange,
+ * packet encryption, packet authentication, and
+ * packet compression.
+ *
+ * Copyright (C) 2002-2012 OpenVPN Technologies, Inc. <sales@openvpn.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program (see the file COPYING included with this
+ * distribution); if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * Generic compression support. Currently we support
+ * Snappy and LZO 2.
+ */
+#ifndef OPENVPN_COMP_H
+#define OPENVPN_COMP_H
+
+#ifdef USE_COMP
+
+#include "buffer.h"
+#include "mtu.h"
+#include "common.h"
+#include "status.h"
+
+/* algorithms */
+#define COMP_ALG_UNDEF 0
+#define COMP_ALG_STUB 1 /* support compression command byte and framing without actual compression */
+#define COMP_ALG_LZO 2 /* LZO algorithm */
+#define COMP_ALG_SNAPPY 3 /* Snappy algorithm */
+
+/* Compression flags */
+#define COMP_F_ADAPTIVE (1<<0) /* COMP_ALG_LZO only */
+#define COMP_F_ASYM (1<<1) /* only downlink is compressed, not uplink */
+#define COMP_F_SWAP (1<<2) /* initial command byte is swapped with last byte in buffer to preserve payload alignment */
+#define COMP_F_ADVERTISE_STUBS_ONLY (1<<3) /* tell server that we only support compression stubs */
+
+/*
+ * Length of prepended prefix on compressed packets
+ */
+#define COMP_PREFIX_LEN 1
+
+/*
+ * Prefix bytes
+ */
+#define NO_COMPRESS_BYTE 0xFA
+#define NO_COMPRESS_BYTE_SWAP 0xFB /* to maintain payload alignment, replace this byte with last byte of packet */
+
+/*
+ * Compress worst case size expansion (for any algorithm)
+ *
+ * LZO: len + len/8 + 128 + 3
+ * Snappy: len + len/6 + 32
+ */
+#define COMP_EXTRA_BUFFER(len) ((len)/6 + 128 + 3 + COMP_PREFIX_LEN)
+
+/*
+ * Don't try to compress any packet smaller than this.
+ */
+#define COMPRESS_THRESHOLD 100
+
+/* Forward declaration of compression context */
+struct compress_context;
+
+/*
+ * Virtual methods and other static info for each compression algorithm
+ */
+struct compress_alg
+{
+ const char *name;
+ void (*compress_init)(struct compress_context *compctx);
+ void (*compress_uninit)(struct compress_context *compctx);
+ void (*compress)(struct buffer *buf, struct buffer work,
+ struct compress_context *compctx,
+ const struct frame* frame);
+
+ void (*decompress)(struct buffer *buf, struct buffer work,
+ struct compress_context *compctx,
+ const struct frame* frame);
+};
+
+/*
+ * Headers for each compression implementation
+ */
+#ifdef ENABLE_LZO
+#include "lzo.h"
+#endif
+
+#ifdef ENABLE_SNAPPY
+#include "snappy.h"
+#endif
+
+/*
+ * Information that basically identifies a compression
+ * algorithm and related flags.
+ */
+struct compress_options
+{
+ int alg;
+ unsigned int flags;
+};
+
+/*
+ * Workspace union of all supported compression algorithms
+ */
+union compress_workspace_union
+{
+#ifdef ENABLE_LZO
+ struct lzo_compress_workspace lzo;
+#endif
+#ifdef ENABLE_SNAPPY
+ struct snappy_workspace snappy;
+#endif
+};
+
+/*
+ * Context for active compression session
+ */
+struct compress_context
+{
+ unsigned int flags;
+ struct compress_alg alg;
+ union compress_workspace_union wu;
+
+ /* statistics */
+ counter_type pre_decompress;
+ counter_type post_decompress;
+ counter_type pre_compress;
+ counter_type post_compress;
+};
+
+extern const struct compress_alg comp_stub_alg;
+
+struct compress_context *comp_init(const struct compress_options *opt);
+
+void comp_uninit(struct compress_context *compctx);
+
+void comp_add_to_extra_frame(struct frame *frame);
+void comp_add_to_extra_buffer(struct frame *frame);
+
+void comp_print_stats (const struct compress_context *compctx, struct status_output *so);
+
+void comp_generate_peer_info_string(const struct compress_options *opt, struct buffer *out);
+
+static inline bool
+comp_enabled(const struct compress_options *info)
+{
+ return info->alg != COMP_ALG_UNDEF;
+}
+
+static inline bool
+comp_unswapped_prefix(const struct compress_options *info)
+{
+ return !(info->flags & COMP_F_SWAP);
+}
+
+#endif /* USE_COMP */
+#endif
diff --git a/openvpn/src/openvpn/compstub.c b/openvpn/src/openvpn/compstub.c
new file mode 100644
index 00000000..2ab7163e
--- /dev/null
+++ b/openvpn/src/openvpn/compstub.c
@@ -0,0 +1,118 @@
+/*
+ * OpenVPN -- An application to securely tunnel IP networks
+ * over a single UDP port, with support for SSL/TLS-based
+ * session authentication and key exchange,
+ * packet encryption, packet authentication, and
+ * packet compression.
+ *
+ * Copyright (C) 2002-2012 OpenVPN Technologies, Inc. <sales@openvpn.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program (see the file COPYING included with this
+ * distribution); if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#elif defined(_MSC_VER)
+#include "config-msvc.h"
+#endif
+
+#include "syshead.h"
+
+#if defined(USE_COMP)
+
+#include "comp.h"
+#include "error.h"
+#include "otime.h"
+
+#include "memdbg.h"
+
+static void
+stub_compress_init (struct compress_context *compctx)
+{
+}
+
+static void
+stub_compress_uninit (struct compress_context *compctx)
+{
+}
+
+static void
+stub_compress (struct buffer *buf, struct buffer work,
+ struct compress_context *compctx,
+ const struct frame* frame)
+{
+ if (buf->len <= 0)
+ return;
+ if (compctx->flags & COMP_F_SWAP)
+ {
+ uint8_t *head = BPTR (buf);
+ uint8_t *tail = BEND (buf);
+ ASSERT (buf_safe (buf, 1));
+ ++buf->len;
+
+ /* move head byte of payload to tail */
+ *tail = *head;
+ *head = NO_COMPRESS_BYTE_SWAP;
+ }
+ else
+ {
+ uint8_t *header = buf_prepend (buf, 1);
+ *header = NO_COMPRESS_BYTE;
+ }
+}
+
+static void
+stub_decompress (struct buffer *buf, struct buffer work,
+ struct compress_context *compctx,
+ const struct frame* frame)
+{
+ uint8_t c;
+ if (buf->len <= 0)
+ return;
+ if (compctx->flags & COMP_F_SWAP)
+ {
+ uint8_t *head = BPTR (buf);
+ c = *head;
+ --buf->len;
+ *head = *BEND (buf);
+ if (c != NO_COMPRESS_BYTE_SWAP)
+ {
+ dmsg (D_COMP_ERRORS, "Bad compression stub (swap) decompression header byte: %d", c);
+ buf->len = 0;
+ }
+ }
+ else
+ {
+ c = *BPTR (buf);
+ ASSERT (buf_advance (buf, 1));
+ if (c != NO_COMPRESS_BYTE)
+ {
+ dmsg (D_COMP_ERRORS, "Bad compression stub decompression header byte: %d", c);
+ buf->len = 0;
+ }
+ }
+}
+
+const struct compress_alg comp_stub_alg = {
+ "stub",
+ stub_compress_init,
+ stub_compress_uninit,
+ stub_compress,
+ stub_decompress
+};
+
+#else
+static void dummy(void) {}
+#endif /* USE_STUB */
diff --git a/openvpn/src/openvpn/crypto_openssl.c b/openvpn/src/openvpn/crypto_openssl.c
index 21d1762d..1501bc86 100644
--- a/openvpn/src/openvpn/crypto_openssl.c
+++ b/openvpn/src/openvpn/crypto_openssl.c
@@ -194,7 +194,8 @@ crypto_init_lib_engine (const char *engine_name)
void
crypto_init_lib (void)
{
-#ifndef USE_SSL
+#ifndef ENABLE_SSL
+ /* If SSL is enabled init is taken care of in ssl_openssl.c */
#ifndef ENABLE_SMALL
ERR_load_crypto_strings ();
#endif
@@ -215,7 +216,8 @@ crypto_init_lib (void)
void
crypto_uninit_lib (void)
{
-#ifndef USE_SSL
+#ifndef ENABLE_SSL
+ /* If SSL is enabled cleanup is taken care of in ssl_openssl.c */
EVP_cleanup ();
#ifndef ENABLE_SMALL
ERR_free_strings ();
diff --git a/openvpn/src/openvpn/error.c b/openvpn/src/openvpn/error.c
index d9450a6c..98611a1b 100644
--- a/openvpn/src/openvpn/error.c
+++ b/openvpn/src/openvpn/error.c
@@ -404,7 +404,6 @@ void
assert_failed (const char *filename, int line)
{
#ifdef GOOGLE_BREAKPAD
- msg (M_NONFATAL, "Assertion failed at %s:%d", filename, line);
breakpad_dodump();
#endif
msg (M_FATAL, "Assertion failed at %s:%d", filename, line);
diff --git a/openvpn/src/openvpn/init.c b/openvpn/src/openvpn/init.c
index 4af79657..335ebab1 100644
--- a/openvpn/src/openvpn/init.c
+++ b/openvpn/src/openvpn/init.c
@@ -1156,13 +1156,14 @@ do_init_traffic_shaper (struct context *c)
}
/*
- * Allocate a route list structure if at least one
- * --route option was specified.
+ * Allocate route list structures for IPv4 and IPv6
+ * (we do this for IPv4 even if no --route option has been seen, as other
+ * parts of OpenVPN might want to fill the route-list with info, e.g. DHCP)
*/
static void
do_alloc_route_list (struct context *c)
{
- if (c->options.routes && !c->c1.route_list)
+ if (!c->c1.route_list)
c->c1.route_list = new_route_list (c->options.max_routes, &c->gc);
if (c->options.routes_ipv6 && !c->c1.route_ipv6_list)
c->c1.route_ipv6_list = new_route_ipv6_list (c->options.max_routes, &c->gc);
@@ -1420,15 +1421,15 @@ do_open_tun (struct context *c)
if (!c->c1.tuntap)
{
#endif
-
+
#ifdef TARGET_ANDROID
/* If we emulate persist-tun on android we still have to open a new tun and
then close the old */
int oldtunfd=-1;
- if(c->c1.tuntap)
+ if (c->c1.tuntap)
oldtunfd = c->c1.tuntap->fd;
#endif
-
+
/* initialize (but do not open) tun/tap object */
do_init_tun (c);
@@ -1455,17 +1456,17 @@ do_open_tun (struct context *c)
}
/* possibly add routes */
- if(ifconfig_order() == ROUTE_BEFORE_TUN) {
- /* Ignore route_delay, would cause ROUTE_BEFORE_TUN to be ignored */
- do_route (&c->options, c->c1.route_list, c->c1.route_ipv6_list,
- c->c1.tuntap, c->plugins, c->c2.es);
- }
+ if (route_order() == ROUTE_BEFORE_TUN) {
+ /* Ignore route_delay, would cause ROUTE_BEFORE_TUN to be ignored */
+ do_route (&c->options, c->c1.route_list, c->c1.route_ipv6_list,
+ c->c1.tuntap, c->plugins, c->c2.es);
+ }
/* open the tun device */
open_tun (c->options.dev, c->options.dev_type, c->options.dev_node,
c->c1.tuntap);
#ifdef TARGET_ANDROID
- if(oldtunfd>=0)
+ if (oldtunfd>=0)
close(oldtunfd);
#endif
/* set the hardware address */
@@ -1495,7 +1496,7 @@ do_open_tun (struct context *c)
c->c2.es);
/* possibly add routes */
- if ((ifconfig_order() == ROUTE_AFTER_TUN) && (!c->options.route_delay_defined))
+ if ((route_order() == ROUTE_AFTER_TUN) && (!c->options.route_delay_defined))
do_route (&c->options, c->c1.route_list, c->c1.route_ipv6_list,
c->c1.tuntap, c->plugins, c->c2.es);
@@ -1705,7 +1706,7 @@ do_up (struct context *c, bool pulled_options, unsigned int option_types_found)
#endif
/* if --route-delay was specified, start timer */
- if ((ifconfig_order() == ROUTE_AFTER_TUN) && c->options.route_delay_defined)
+ if ((route_order() == ROUTE_AFTER_TUN) && c->options.route_delay_defined)
{
event_timeout_init (&c->c2.route_wakeup, c->options.route_delay, now);
event_timeout_init (&c->c2.route_wakeup_expire, c->options.route_delay + c->options.route_delay_window, now);
@@ -2544,6 +2545,12 @@ do_option_warnings (struct context *c)
msg (M_WARN, "NOTE: --connect-timeout option is not supported on this OS");
#endif
+ if (script_security >= SSEC_SCRIPTS)
+ msg (M_WARN, "NOTE: the current --script-security setting may allow this configuration to call user-defined scripts");
+ else if (script_security >= SSEC_PW_ENV)
+ msg (M_WARN, "WARNING: the current --script-security setting may allow passwords to be passed to scripts via environmental variables");
+ else
+ msg (M_WARN, "NOTE: " PACKAGE_NAME " 2.1 requires '--script-security 2' or higher to call user-defined scripts or executables");
}
static void
@@ -3681,10 +3688,6 @@ inherit_context_child (struct context *dest,
dest->c2.link_socket_info->lsa = &dest->c1.link_socket_addr;
dest->c2.link_socket_info->connection_established = false;
}
-
-#ifdef USE_COMP
- dest->c2.comp_context = NULL;
-#endif
}
void
diff --git a/openvpn/src/openvpn/manage.c b/openvpn/src/openvpn/manage.c
index c4e834b2..4e96d07f 100644
--- a/openvpn/src/openvpn/manage.c
+++ b/openvpn/src/openvpn/manage.c
@@ -1781,77 +1781,90 @@ man_io_error (struct management *man, const char *prefix)
}
#ifdef TARGET_ANDROID
-static ssize_t write_fd (int fd, void *ptr, size_t nbytes, int flags, int sendfd)
-{
- struct msghdr msg;
- struct iovec iov[1];
-
- union {
- struct cmsghdr cm;
- char control[CMSG_SPACE(sizeof(int))];
- } control_un;
- struct cmsghdr *cmptr;
-
- msg.msg_control = control_un.control;
- msg.msg_controllen = sizeof(control_un.control);
-
- cmptr = CMSG_FIRSTHDR(&msg);
- cmptr->cmsg_len = CMSG_LEN(sizeof(int));
- cmptr->cmsg_level = SOL_SOCKET;
- cmptr->cmsg_type = SCM_RIGHTS;
- *((int *) CMSG_DATA(cmptr)) = sendfd;
-
- msg.msg_name = NULL;
- msg.msg_namelen = 0;
-
- iov[0].iov_base = ptr;
- iov[0].iov_len = nbytes;
- msg.msg_iov = iov;
- msg.msg_iovlen = 1;
-
- return (sendmsg(fd, &msg, flags));
-}
-
-static ssize_t read_fd(int fd, void *ptr, size_t nbytes, int flags, int *recvfd)
-{
- struct msghdr msghdr;
- struct iovec iov[1];
- ssize_t n;
-
- union {
- struct cmsghdr cm;
- char control[CMSG_SPACE(sizeof (int))];
- } control_un;
- struct cmsghdr *cmptr;
-
- msghdr.msg_control = control_un.control;
- msghdr.msg_controllen = sizeof(control_un.control);
-
- msghdr.msg_name = NULL;
- msghdr.msg_namelen = 0;
-
- iov[0].iov_base = ptr;
- iov[0].iov_len = nbytes;
- msghdr.msg_iov = iov;
- msghdr.msg_iovlen = 1;
-
- if ( (n = recvmsg(fd, &msghdr, flags)) <= 0)
- return (n);
-
- if ( (cmptr = CMSG_FIRSTHDR(&msghdr)) != NULL &&
- cmptr->cmsg_len == CMSG_LEN(sizeof(int))) {
- if (cmptr->cmsg_level != SOL_SOCKET)
- msg (M_ERR, "control level != SOL_SOCKET");
- if (cmptr->cmsg_type != SCM_RIGHTS)
- msg (M_ERR, "control type != SCM_RIGHTS");
- *recvfd = *((int *) CMSG_DATA(cmptr));
- } else
- *recvfd = -1; /* descriptor was not passed */
-
+static ssize_t man_send_with_fd (int fd, void *ptr, size_t nbytes, int flags, int sendfd)
+{
+ struct msghdr msg;
+ struct iovec iov[1];
+
+ union {
+ struct cmsghdr cm;
+ char control[CMSG_SPACE(sizeof(int))];
+ } control_un;
+ struct cmsghdr *cmptr;
+
+ msg.msg_control = control_un.control;
+ msg.msg_controllen = sizeof(control_un.control);
+
+ cmptr = CMSG_FIRSTHDR(&msg);
+ cmptr->cmsg_len = CMSG_LEN(sizeof(int));
+ cmptr->cmsg_level = SOL_SOCKET;
+ cmptr->cmsg_type = SCM_RIGHTS;
+ *((int *) CMSG_DATA(cmptr)) = sendfd;
+
+ msg.msg_name = NULL;
+ msg.msg_namelen = 0;
+
+ iov[0].iov_base = ptr;
+ iov[0].iov_len = nbytes;
+ msg.msg_iov = iov;
+ msg.msg_iovlen = 1;
+
+ return (sendmsg(fd, &msg, flags));
+}
+
+static ssize_t man_recv_with_fd (int fd, void *ptr, size_t nbytes, int flags, int *recvfd)
+{
+ struct msghdr msghdr;
+ struct iovec iov[1];
+ ssize_t n;
+
+ union {
+ struct cmsghdr cm;
+ char control[CMSG_SPACE(sizeof (int))];
+ } control_un;
+ struct cmsghdr *cmptr;
+
+ msghdr.msg_control = control_un.control;
+ msghdr.msg_controllen = sizeof(control_un.control);
+
+ msghdr.msg_name = NULL;
+ msghdr.msg_namelen = 0;
+
+ iov[0].iov_base = ptr;
+ iov[0].iov_len = nbytes;
+ msghdr.msg_iov = iov;
+ msghdr.msg_iovlen = 1;
+
+ if ( (n = recvmsg(fd, &msghdr, flags)) <= 0)
return (n);
+
+ if ( (cmptr = CMSG_FIRSTHDR(&msghdr)) != NULL &&
+ cmptr->cmsg_len == CMSG_LEN(sizeof(int))) {
+ if (cmptr->cmsg_level != SOL_SOCKET)
+ msg (M_ERR, "control level != SOL_SOCKET");
+ if (cmptr->cmsg_type != SCM_RIGHTS)
+ msg (M_ERR, "control type != SCM_RIGHTS");
+ *recvfd = *((int *) CMSG_DATA(cmptr));
+ } else
+ *recvfd = -1; /* descriptor was not passed */
+
+ return (n);
}
-#endif
+/*
+ * The android control method will instruct the GUI part of openvpn to do
+ * the route/ifconfig/open tun command. See doc/android.txt for details.
+ */
+bool management_android_control (struct management *man, const char *command, const char *msg)
+{
+ struct user_pass up;
+ CLEAR(up);
+ strncpy (up.username, msg, sizeof(up.username)-1);
+
+ management_query_user_pass(management, &up , command, GET_USER_PASS_NEED_OK,(void*) 0);
+ return strcmp ("ok", up.password)==0;
+}
+#endif
static int
man_read (struct management *man)
@@ -1864,8 +1877,8 @@ man_read (struct management *man)
#ifdef TARGET_ANDROID
int fd;
- len = read_fd (man->connection.sd_cli, buf, sizeof (buf), MSG_NOSIGNAL, &fd);
- if(fd >= 0)
+ len = man_recv_with_fd (man->connection.sd_cli, buf, sizeof (buf), MSG_NOSIGNAL, &fd);
+ if(fd >= 0)
man->connection.lastfdreceived = fd;
#else
len = recv (man->connection.sd_cli, buf, sizeof (buf), MSG_NOSIGNAL);
@@ -1948,9 +1961,9 @@ man_write (struct management *man)
{
const int len = min_int (size_hint, BLEN (buf));
#ifdef TARGET_ANDROID
- if (man->connection.fdtosend > 0)
+ if (man->connection.fdtosend > 0)
{
- sent = write_fd (man->connection.sd_cli, BPTR (buf), len, MSG_NOSIGNAL,man->connection.fdtosend);
+ sent = man_send_with_fd (man->connection.sd_cli, BPTR (buf), len, MSG_NOSIGNAL,man->connection.fdtosend);
man->connection.fdtosend = -1;
} else
#endif
diff --git a/openvpn/src/openvpn/manage.h b/openvpn/src/openvpn/manage.h
index d2790dd4..962b5bc4 100644
--- a/openvpn/src/openvpn/manage.h
+++ b/openvpn/src/openvpn/manage.h
@@ -300,8 +300,8 @@ struct man_connection {
struct buffer_list *rsa_sig;
#endif
#ifdef TARGET_ANDROID
- int fdtosend;
- int lastfdreceived;
+ int fdtosend;
+ int lastfdreceived;
#endif
};
@@ -376,6 +376,10 @@ bool management_query_user_pass (struct management *man,
const unsigned int flags,
const char *static_challenge);
+#ifdef TARGET_ANDROID
+bool management_android_control (struct management *man, const char *command, const char *msg);
+#endif
+
bool management_should_daemonize (struct management *man);
bool management_would_hold (struct management *man);
bool management_hold (struct management *man);
diff --git a/openvpn/src/openvpn/multi.c b/openvpn/src/openvpn/multi.c
index ab3f10cb..f016b149 100644
--- a/openvpn/src/openvpn/multi.c
+++ b/openvpn/src/openvpn/multi.c
@@ -807,8 +807,8 @@ multi_print_status (struct multi_context *m, struct status_output *so, const int
*/
status_printf (so, "TITLE%c%s", sep, title_string);
status_printf (so, "TIME%c%s%c%u", sep, time_string (now, 0, false, &gc_top), sep, (unsigned int)now);
- status_printf (so, "HEADER%cCLIENT_LIST%cCommon Name%cReal Address%cVirtual Address%cBytes Received%cBytes Sent%cConnected Since%cConnected Since (time_t)%cUsername",
- sep, sep, sep, sep, sep, sep, sep, sep, sep);
+ status_printf (so, "HEADER%cCLIENT_LIST%cCommon Name%cReal Address%cVirtual Address%cVirtual IPv6 Address%cBytes Received%cBytes Sent%cConnected Since%cConnected Since (time_t)%cUsername%cClient ID",
+ sep, sep, sep, sep, sep, sep, sep, sep, sep, sep, sep);
hash_iterator_init (m->hash, &hi);
while ((he = hash_iterator_next (&hi)))
{
@@ -817,15 +817,26 @@ multi_print_status (struct multi_context *m, struct status_output *so, const int
if (!mi->halt)
{
- status_printf (so, "CLIENT_LIST%c%s%c%s%c%s%c" counter_format "%c" counter_format "%c%s%c%u%c%s",
+ status_printf (so, "CLIENT_LIST%c%s%c%s%c%s%c%s%c" counter_format "%c" counter_format "%c%s%c%u%c%s%c"
+#ifdef MANAGEMENT_DEF_AUTH
+ "%lu",
+#else
+ "",
+#endif
sep, tls_common_name (mi->context.c2.tls_multi, false),
sep, mroute_addr_print (&mi->real, &gc),
sep, print_in_addr_t (mi->reporting_addr, IA_EMPTY_IF_UNDEF, &gc),
+ sep, print_in6_addr (mi->reporting_addr_ipv6, IA_EMPTY_IF_UNDEF, &gc),
sep, mi->context.c2.link_read_bytes,
sep, mi->context.c2.link_write_bytes,
sep, time_string (mi->created, 0, false, &gc),
sep, (unsigned int)mi->created,
- sep, tls_username (mi->context.c2.tls_multi, false));
+ sep, tls_username (mi->context.c2.tls_multi, false),
+#ifdef MANAGEMENT_DEF_AUTH
+ sep, mi->context.c2.mda_context.cid);
+#else
+ sep);
+#endif
}
gc_free (&gc);
}
@@ -1847,6 +1858,7 @@ multi_connection_established (struct multi_context *m, struct multi_instance *mi
/* set our client's VPN endpoint for status reporting purposes */
mi->reporting_addr = mi->context.c2.push_ifconfig_local;
+ mi->reporting_addr_ipv6 = mi->context.c2.push_ifconfig_ipv6_local;
/* set context-level authentication flag */
mi->context.c2.context_auth = CAS_SUCCEEDED;
diff --git a/openvpn/src/openvpn/multi.h b/openvpn/src/openvpn/multi.h
index 2bc0c8a1..fc2ffb24 100644
--- a/openvpn/src/openvpn/multi.h
+++ b/openvpn/src/openvpn/multi.h
@@ -88,6 +88,7 @@ struct multi_instance {
bool socket_set_called;
in_addr_t reporting_addr; /* IP address shown in status listing */
+ struct in6_addr reporting_addr_ipv6; /* IPv6 address in status listing */
bool did_open_context;
bool did_real_hash;
diff --git a/openvpn/src/openvpn/options.c b/openvpn/src/openvpn/options.c
index 7dba31a7..37909ca9 100644
--- a/openvpn/src/openvpn/options.c
+++ b/openvpn/src/openvpn/options.c
@@ -64,6 +64,9 @@
const char title_string[] =
PACKAGE_STRING
+#ifdef CONFIGURE_GIT_REVISION
+ " [git:" CONFIGURE_GIT_REVISION CONFIGURE_GIT_FLAGS "]"
+#endif
" " TARGET_ALIAS
#ifdef ENABLE_CRYPTO
#ifdef ENABLE_SSL
@@ -1132,7 +1135,7 @@ show_tuntap_options (const struct tuntap_options *o)
#endif
#endif
-#if defined(WIN32) || defined(TARGET_ANDROID)
+#if defined(WIN32) || defined(TARGET_ANDROID)
static void
dhcp_option_address_parse (const char *name, const char *parm, in_addr_t *array, int *len, int msglevel)
{
@@ -3410,9 +3413,6 @@ usage_version (void)
#ifdef CONFIGURE_SPECIAL_BUILD
msg (M_INFO|M_NOPREFIX, "special build: %s", CONFIGURE_SPECIAL_BUILD);
#endif
-#ifdef CONFIGURE_GIT_REVISION
- msg (M_INFO|M_NOPREFIX, "git revision: %s", CONFIGURE_GIT_REVISION);
-#endif
#endif
openvpn_exit (OPENVPN_EXIT_STATUS_USAGE); /* exit point */
}
diff --git a/openvpn/src/openvpn/pf.c b/openvpn/src/openvpn/pf.c
index aafe9ff0..461beed7 100644
--- a/openvpn/src/openvpn/pf.c
+++ b/openvpn/src/openvpn/pf.c
@@ -417,7 +417,7 @@ lookup_cn_rule (struct hash *h, const char *cn, const uint32_t cn_hash)
bool
pf_cn_test (struct pf_set *pfs, const struct tls_multi *tm, const int type, const char *prefix)
{
- if (!pfs->kill)
+ if (pfs && !pfs->kill)
{
const char *cn;
uint32_t cn_hash;
diff --git a/openvpn/src/openvpn/route.c b/openvpn/src/openvpn/route.c
index 03574b9e..c5a7ba6b 100644
--- a/openvpn/src/openvpn/route.c
+++ b/openvpn/src/openvpn/route.c
@@ -503,6 +503,7 @@ route_list_add_vpn_gateway (struct route_list *rl,
struct env_set *es,
const in_addr_t addr)
{
+ ASSERT(rl);
rl->spec.remote_endpoint = addr;
rl->spec.flags |= RTSA_REMOTE_ENDPOINT;
setenv_route_addr (es, "vpn_gateway", rl->spec.remote_endpoint, -1);
@@ -1343,15 +1344,10 @@ add_route (struct route *r,
status = openvpn_execve_check (&argv, es, 0, "ERROR: Linux route add command failed");
#elif defined (TARGET_ANDROID)
+ struct buffer out = alloc_buf_gc (64, &gc);
- struct user_pass up;
- struct buffer out = alloc_buf_gc (64, &gc);
-
- buf_printf (&out, "%s %s", network, netmask);
-
- strcpy(up.username, buf_bptr(&out));
- management_query_user_pass(management, &up , "ROUTE", GET_USER_PASS_NEED_OK,(void*) 0);
-
+ buf_printf (&out, "%s %s", network, netmask);
+ management_android_control (management, "ROUTE", buf_bptr(&out));
#elif defined (WIN32)
{
@@ -1628,13 +1624,11 @@ add_route_ipv6 (struct route_ipv6 *r6, const struct tuntap *tt, unsigned int fla
status = openvpn_execve_check (&argv, es, 0, "ERROR: Linux route -6/-A inet6 add command failed");
#elif defined (TARGET_ANDROID)
- struct user_pass up;
struct buffer out = alloc_buf_gc (64, &gc);
-
+
buf_printf (&out, "%s/%d", network, r6->netbits);
-
- strcpy(up.username, buf_bptr(&out));
- management_query_user_pass(management, &up , "ROUTE6", GET_USER_PASS_NEED_OK,(void*) 0);
+
+ management_android_control (management, "ROUTE6", buf_bptr(&out));
#elif defined (WIN32)
diff --git a/openvpn/src/openvpn/snappy.c b/openvpn/src/openvpn/snappy.c
new file mode 100644
index 00000000..24440bae
--- /dev/null
+++ b/openvpn/src/openvpn/snappy.c
@@ -0,0 +1,189 @@
+/*
+ * OpenVPN -- An application to securely tunnel IP networks
+ * over a single UDP port, with support for SSL/TLS-based
+ * session authentication and key exchange,
+ * packet encryption, packet authentication, and
+ * packet compression.
+ *
+ * Copyright (C) 2002-2012 OpenVPN Technologies, Inc. <sales@openvpn.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program (see the file COPYING included with this
+ * distribution); if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#elif defined(_MSC_VER)
+#include "config-msvc.h"
+#endif
+
+#include "syshead.h"
+
+#if defined(ENABLE_SNAPPY)
+
+#include "snappy-c.h"
+
+#include "comp.h"
+#include "error.h"
+#include "otime.h"
+
+#include "memdbg.h"
+
+/* Initial command byte to tell our peer if we compressed */
+#define SNAPPY_COMPRESS_BYTE 0x68
+
+static void
+snap_compress_init (struct compress_context *compctx)
+{
+ msg (D_INIT_MEDIUM, "Snappy compression initializing");
+ ASSERT(compctx->flags & COMP_F_SWAP);
+}
+
+static void
+snap_compress_uninit (struct compress_context *compctx)
+{
+}
+
+static void
+snap_compress (struct buffer *buf, struct buffer work,
+ struct compress_context *compctx,
+ const struct frame* frame)
+{
+ snappy_status status;
+ bool compressed = false;
+
+ if (buf->len <= 0)
+ return;
+
+ /*
+ * In order to attempt compression, length must be at least COMPRESS_THRESHOLD.
+ */
+ if (buf->len >= COMPRESS_THRESHOLD)
+ {
+ const size_t ps = PAYLOAD_SIZE (frame);
+ size_t zlen = ps + COMP_EXTRA_BUFFER (ps);
+
+ ASSERT (buf_init (&work, FRAME_HEADROOM (frame)));
+ ASSERT (buf_safe (&work, zlen));
+
+ if (buf->len > ps)
+ {
+ dmsg (D_COMP_ERRORS, "Snappy compression buffer overflow");
+ buf->len = 0;
+ return;
+ }
+
+ status = snappy_compress((const char *)BPTR(buf), (size_t)BLEN(buf), (char *)BPTR(&work), &zlen);
+ if (status != SNAPPY_OK)
+ {
+ dmsg (D_COMP_ERRORS, "Snappy compression error: %d", status);
+ buf->len = 0;
+ return;
+ }
+
+ ASSERT (buf_safe (&work, zlen));
+ work.len = zlen;
+ compressed = true;
+
+ dmsg (D_COMP, "Snappy compress %d -> %d", buf->len, work.len);
+ compctx->pre_compress += buf->len;
+ compctx->post_compress += work.len;
+ }
+
+ /* did compression save us anything? */
+ {
+ uint8_t comp_head_byte = NO_COMPRESS_BYTE_SWAP;
+ if (compressed && work.len < buf->len)
+ {
+ *buf = work;
+ comp_head_byte = SNAPPY_COMPRESS_BYTE;
+ }
+
+ {
+ uint8_t *head = BPTR (buf);
+ uint8_t *tail = BEND (buf);
+ ASSERT (buf_safe (buf, 1));
+ ++buf->len;
+
+ /* move head byte of payload to tail */
+ *tail = *head;
+ *head = comp_head_byte;
+ }
+ }
+}
+
+static void
+snap_decompress (struct buffer *buf, struct buffer work,
+ struct compress_context *compctx,
+ const struct frame* frame)
+{
+ size_t zlen = EXPANDED_SIZE (frame);
+ snappy_status status;
+ uint8_t c; /* flag indicating whether or not our peer compressed */
+
+ if (buf->len <= 0)
+ return;
+
+ ASSERT (buf_init (&work, FRAME_HEADROOM (frame)));
+
+ /* do unframing/swap (assumes buf->len > 0) */
+ {
+ uint8_t *head = BPTR (buf);
+ c = *head;
+ --buf->len;
+ *head = *BEND (buf);
+ }
+
+ if (c == SNAPPY_COMPRESS_BYTE) /* packet was compressed */
+ {
+ ASSERT (buf_safe (&work, zlen));
+ status = snappy_uncompress((const char *)BPTR(buf), (size_t)BLEN(buf), (char *)BPTR(&work), &zlen);
+ if (status != SNAPPY_OK)
+ {
+ dmsg (D_COMP_ERRORS, "Snappy decompression error: %d", status);
+ buf->len = 0;
+ return;
+ }
+
+ ASSERT (buf_safe (&work, zlen));
+ work.len = zlen;
+
+ dmsg (D_COMP, "Snappy decompress %d -> %d", buf->len, work.len);
+ compctx->pre_decompress += buf->len;
+ compctx->post_decompress += work.len;
+
+ *buf = work;
+ }
+ else if (c == NO_COMPRESS_BYTE_SWAP) /* packet was not compressed */
+ {
+ ;
+ }
+ else
+ {
+ dmsg (D_COMP_ERRORS, "Bad Snappy decompression header byte: %d", c);
+ buf->len = 0;
+ }
+}
+
+const struct compress_alg snappy_alg = {
+ "snappy",
+ snap_compress_init,
+ snap_compress_uninit,
+ snap_compress,
+ snap_decompress
+};
+
+#else
+static void dummy(void) {}
+#endif /* ENABLE_SNAPPY */
diff --git a/openvpn/src/openvpn/snappy.h b/openvpn/src/openvpn/snappy.h
new file mode 100644
index 00000000..361a6317
--- /dev/null
+++ b/openvpn/src/openvpn/snappy.h
@@ -0,0 +1,39 @@
+/*
+ * OpenVPN -- An application to securely tunnel IP networks
+ * over a single UDP port, with support for SSL/TLS-based
+ * session authentication and key exchange,
+ * packet encryption, packet authentication, and
+ * packet compression.
+ *
+ * Copyright (C) 2002-2012 OpenVPN Technologies, Inc. <sales@openvpn.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program (see the file COPYING included with this
+ * distribution); if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef OPENVPN_SNAPPY_H
+#define OPENVPN_SNAPPY_H
+
+#if defined(ENABLE_SNAPPY)
+
+#include "buffer.h"
+
+extern const struct compress_alg snappy_alg;
+
+struct snappy_workspace
+{
+};
+
+#endif /* ENABLE_SNAPPY */
+#endif
diff --git a/openvpn/src/openvpn/socket.c b/openvpn/src/openvpn/socket.c
index 83af046f..af790630 100644
--- a/openvpn/src/openvpn/socket.c
+++ b/openvpn/src/openvpn/socket.c
@@ -172,7 +172,7 @@ openvpn_getaddrinfo (unsigned int flags,
CLEAR(hints);
hints.ai_family = ai_family;
hints.ai_flags = AI_NUMERICHOST;
- hints.ai_socktype = SOCK_STREAM;
+
if(flags & GETADDR_PASSIVE)
hints.ai_flags |= AI_PASSIVE;
@@ -697,20 +697,19 @@ create_socket (struct link_socket *sock)
#ifdef TARGET_ANDROID
static void protect_fd_nonlocal (int fd, struct sockaddr* addr)
{
- if (addr_local (addr)) {
- msg(M_DEBUG, "Address is local, not protecting socket fd %d", fd);
- return;
- }
-
- struct user_pass up;
- strcpy(up.username ,__func__);
- management->connection.fdtosend = fd;
- msg(M_DEBUG, "Protecting socket fd %d", fd);
- management_query_user_pass(management, &up , "PROTECTFD", GET_USER_PASS_NEED_OK,(void*) 0);
+ /* pass socket FD to management interface to pass on to VPNService API
+ * as "protected socket" (exempt from being routed into tunnel)
+ */
+ if (addr_local (addr)) {
+ msg(M_DEBUG, "Address is local, not protecting socket fd %d", fd);
+ return;
+ }
+ msg(M_DEBUG, "Protecting socket fd %d", fd);
+ management->connection.fdtosend = fd;
+ management_android_control (management, "PROTECTFD", __func__);
}
#endif
-
/*
* Functions used for establishing a TCP stream connection.
@@ -933,10 +932,12 @@ openvpn_connect (socket_descriptor_t sd,
{
int status = 0;
+#ifdef TARGET_ANDROID
+ protect_fd_nonlocal(sd, remote);
+#endif
+
#ifdef CONNECT_NONBLOCK
set_nonblock (sd);
-
- protect_fd_nonlocal(sd, remote);
status = connect (sd, remote, af_addr_size(remote->sa_family));
if (status)
status = openvpn_errno ();
@@ -1786,7 +1787,9 @@ link_socket_init_phase2 (struct link_socket *sock,
phase2_socks_client (sock, sig_info);
#endif
}
+#ifdef TARGET_ANDROID
protect_fd_nonlocal (sock->sd, &sock->info.lsa->actual.dest.addr.sa);
+#endif
}
if (sig_info && sig_info->signal_received)
@@ -2772,7 +2775,7 @@ link_socket_read_udp_posix (struct link_socket *sock,
ASSERT (buf_safe (buf, maxsize));
#if ENABLE_IP_PKTINFO
/* Both PROTO_UDPv4 and PROTO_UDPv6 */
- if (proto_is_udp(sock->info.proto) && sock->sockflags & SF_USE_IP_PKTINFO)
+ if (sock->info.proto == PROTO_UDP && sock->sockflags & SF_USE_IP_PKTINFO)
fromlen = link_socket_read_udp_posix_recvmsg (sock, buf, maxsize, from);
else
#endif
@@ -2919,7 +2922,7 @@ socket_recv_queue (struct link_socket *sock, int maxsize)
if (proto_is_udp(sock->info.proto))
{
sock->reads.addr_defined = true;
- if (sock->info.proto == PROTO_UDPv6)
+ if (sock->info.af == AF_INET)
sock->reads.addrlen = sizeof (sock->reads.addr6);
else
sock->reads.addrlen = sizeof (sock->reads.addr);
@@ -3018,7 +3021,7 @@ socket_send_queue (struct link_socket *sock, struct buffer *buf, const struct li
{
/* set destination address for UDP writes */
sock->writes.addr_defined = true;
- if (sock->info.proto == PROTO_UDPv6)
+ if (sock->info.af == AF_INET)
{
sock->writes.addr6 = to->dest.addr.in6;
sock->writes.addrlen = sizeof (sock->writes.addr6);
diff --git a/openvpn/src/openvpn/socket.h b/openvpn/src/openvpn/socket.h
index 5b7a26a9..2b134486 100644
--- a/openvpn/src/openvpn/socket.h
+++ b/openvpn/src/openvpn/socket.h
@@ -673,6 +673,20 @@ addrlist_match (const struct openvpn_sockaddr *a1, const struct addrinfo *addrli
return false;
}
+static inline in_addr_t
+addr_host (const struct openvpn_sockaddr *addr)
+{
+ /*
+ * "public" addr returned is checked against ifconfig for
+ * possible clash: non sense for now given
+ * that we do ifconfig only IPv4
+ */
+ if(addr->addr.sa.sa_family != AF_INET)
+ return 0;
+ return ntohl (addr->addr.in4.sin_addr.s_addr);
+}
+
+
static inline bool
addrlist_port_match (const struct openvpn_sockaddr *a1, const struct addrinfo *a2)
{
diff --git a/openvpn/src/openvpn/ssl.c b/openvpn/src/openvpn/ssl.c
index 7e261e75..9ca409f1 100644
--- a/openvpn/src/openvpn/ssl.c
+++ b/openvpn/src/openvpn/ssl.c
@@ -1775,68 +1775,66 @@ push_peer_info(struct buffer *buf, struct tls_session *session)
bool ret = false;
#ifdef ENABLE_PUSH_PEER_INFO
- {
- struct env_set *es = session->opt->es;
- struct env_item *e;
- struct buffer out = alloc_buf_gc (512*3, &gc);
+ if (session->opt->push_peer_info) /* write peer info */
+ {
+ struct env_set *es = session->opt->es;
+ struct env_item *e;
+ struct buffer out = alloc_buf_gc (512*3, &gc);
- /* push version */
- buf_printf (&out, "IV_VER=%s\n", PACKAGE_VERSION);
+ /* push version */
+ buf_printf (&out, "IV_VER=%s\n", PACKAGE_VERSION);
- /* push platform */
+ /* push platform */
#if defined(TARGET_LINUX)
- buf_printf (&out, "IV_PLAT=linux\n");
+ buf_printf (&out, "IV_PLAT=linux\n");
#elif defined(TARGET_SOLARIS)
- buf_printf (&out, "IV_PLAT=solaris\n");
+ buf_printf (&out, "IV_PLAT=solaris\n");
#elif defined(TARGET_OPENBSD)
- buf_printf (&out, "IV_PLAT=openbsd\n");
+ buf_printf (&out, "IV_PLAT=openbsd\n");
#elif defined(TARGET_DARWIN)
- buf_printf (&out, "IV_PLAT=mac\n");
+ buf_printf (&out, "IV_PLAT=mac\n");
#elif defined(TARGET_NETBSD)
- buf_printf (&out, "IV_PLAT=netbsd\n");
+ buf_printf (&out, "IV_PLAT=netbsd\n");
#elif defined(TARGET_FREEBSD)
- buf_printf (&out, "IV_PLAT=freebsd\n");
+ buf_printf (&out, "IV_PLAT=freebsd\n");
#elif defined(TARGET_ANDROID)
- buf_printf (&out, "IV_PLAT=android\n");
+ buf_printf (&out, "IV_PLAT=android\n");
#elif defined(WIN32)
- buf_printf (&out, "IV_PLAT=win\n");
+ buf_printf (&out, "IV_PLAT=win\n");
#endif
- /* push compression status */
+ /* push mac addr */
+ {
+ struct route_gateway_info rgi;
+ get_default_gateway (&rgi);
+ if (rgi.flags & RGI_HWADDR_DEFINED)
+ buf_printf (&out, "IV_HWADDR=%s\n", format_hex_ex (rgi.hwaddr, 6, 0, 1, ":", &gc));
+ }
+
+ /* push compression status */
#ifdef USE_COMP
- comp_generate_peer_info_string(&session->opt->comp_options, &out);
+ comp_generate_peer_info_string(&session->opt->comp_options, &out);
#endif
- if (session->opt->push_peer_info)
- {
- /* push mac addr */
+ /* push env vars that begin with UV_ */
+ for (e=es->list; e != NULL; e=e->next)
{
- struct route_gateway_info rgi;
- get_default_gateway (&rgi);
- if (rgi.flags & RGI_HWADDR_DEFINED)
- buf_printf (&out, "IV_HWADDR=%s\n", format_hex_ex (rgi.hwaddr, 6, 0, 1, ":", &gc));
+ if (e->string)
+ {
+ if (!strncmp(e->string, "UV_", 3) && buf_safe(&out, strlen(e->string)+1))
+ buf_printf (&out, "%s\n", e->string);
+ }
}
- /* push env vars that begin with UV_ */
- for (e=es->list; e != NULL; e=e->next)
- {
- if (e->string)
- {
- if (!strncmp(e->string, "UV_", 3) && buf_safe(&out, strlen(e->string)+1))
- buf_printf (&out, "%s\n", e->string);
- }
- }
- }
-
- if (!write_string(buf, BSTR(&out), -1))
- goto error;
- }
-#else
- {
- if (!write_empty_string (buf)) /* no peer info */
- goto error;
- }
+ if (!write_string(buf, BSTR(&out), -1))
+ goto error;
+ }
+ else
#endif
+ {
+ if (!write_empty_string (buf)) /* no peer info */
+ goto error;
+ }
ret = true;
error:
diff --git a/openvpn/src/openvpn/ssl_openssl.c b/openvpn/src/openvpn/ssl_openssl.c
index 79cc056e..c1b19dc2 100644
--- a/openvpn/src/openvpn/ssl_openssl.c
+++ b/openvpn/src/openvpn/ssl_openssl.c
@@ -232,7 +232,7 @@ tls_ctx_restrict_ciphers(struct tls_root_ctx *ctx, const char *ciphers)
// %.*s format specifier expects length of type int, so guarantee
// that length is small enough and cast to int.
msg (M_WARN, "No valid translation found for TLS cipher '%.*s'",
- (int) MIN(current_cipher_len, 256), current_cipher);
+ constrain_int(current_cipher_len, 0, 256), current_cipher);
}
else
{
diff --git a/openvpn/src/openvpn/syshead.h b/openvpn/src/openvpn/syshead.h
index 2be11159..df6927de 100644
--- a/openvpn/src/openvpn/syshead.h
+++ b/openvpn/src/openvpn/syshead.h
@@ -399,13 +399,6 @@
#endif
/*
- * do we have the MIN() macro?
- */
-#ifndef MIN
-#define MIN(a,b) (((a)<(b))?(a):(b))
-#endif
-
-/*
* Do we have the capability to report extended socket errors?
*/
#if defined(HAVE_LINUX_TYPES_H) && defined(HAVE_LINUX_ERRQUEUE_H) && defined(HAVE_SOCK_EXTENDED_ERR) && defined(HAVE_MSGHDR) && defined(HAVE_CMSGHDR) && defined(CMSG_FIRSTHDR) && defined(CMSG_NXTHDR) && defined(IP_RECVERR) && defined(MSG_ERRQUEUE) && defined(SOL_IP) && defined(HAVE_IOVEC)
diff --git a/openvpn/src/openvpn/tun.c b/openvpn/src/openvpn/tun.c
index d7d53a78..98cb16f3 100644
--- a/openvpn/src/openvpn/tun.c
+++ b/openvpn/src/openvpn/tun.c
@@ -773,39 +773,33 @@ do_ifconfig (struct tuntap *tt,
#endif /*ENABLE_IPROUTE*/
#elif defined(TARGET_ANDROID)
-
-
- if (do_ipv6) {
- struct user_pass up6;
- struct buffer out6 = alloc_buf_gc (64, &gc);
- buf_printf (&out6, "%s/%d", ifconfig_ipv6_local,tt->netbits_ipv6);
- strcpy(up6.username, buf_bptr(&out6));
- management_query_user_pass(management, &up6 , "IFCONFIG6", GET_USER_PASS_NEED_OK,(void*) 0);
- }
- struct user_pass up;
- struct buffer out = alloc_buf_gc (64, &gc);
- char* top;
- switch(tt->topology) {
- case TOP_NET30:
- top = "net30";
- break;
- case TOP_P2P:
- top="p2p";
- break;
- case TOP_SUBNET:
- top="subnet";
- break;
- default:
- top="undef";
- }
-
- buf_printf (&out, "%s %s %d %s", ifconfig_local, ifconfig_remote_netmask, tun_mtu,top);
- strcpy(up.username, buf_bptr(&out));
- management_query_user_pass(management, &up , "IFCONFIG", GET_USER_PASS_NEED_OK,(void*) 0);
+ if (do_ipv6) {
+ struct buffer out6 = alloc_buf_gc (64, &gc);
+ buf_printf (&out6, "%s/%d", ifconfig_ipv6_local,tt->netbits_ipv6);
+ management_android_control(management, "IFCONFIG6",buf_bptr(&out6));
+ }
+ struct buffer out = alloc_buf_gc (64, &gc);
+
+ char* top;
+ switch(tt->topology) {
+ case TOP_NET30:
+ top="net30";
+ break;
+ case TOP_P2P:
+ top="p2p";
+ break;
+ case TOP_SUBNET:
+ top="subnet";
+ break;
+ default:
+ top="undef";
+ }
+
+ buf_printf (&out, "%s %s %d %s", ifconfig_local, ifconfig_remote_netmask, tun_mtu, top);
+ management_android_control (management, "IFCONFIG", buf_bptr(&out));
-
#elif defined(TARGET_SOLARIS)
/* Solaris 2.6 (and 7?) cannot set all parameters in one go...
@@ -1414,33 +1408,33 @@ close_tun_generic (struct tuntap *tt)
void
open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt)
{
- int i;
- struct user_pass up;
- struct gc_arena gc = gc_new ();
-
- for (i = 0; i < tt->options.dns_len; ++i) {
- strcpy(up.username, print_in_addr_t(tt->options.dns[i], 0, &gc));
- management_query_user_pass(management, &up , "DNSSERVER", GET_USER_PASS_NEED_OK,(void*) 0);
- }
+#define ANDROID_TUNNAME "vpnservice-tun"
+ int i;
+ struct user_pass up;
+ struct gc_arena gc = gc_new ();
+ bool opentun;
- if(tt->options.domain) {
- strcpy(up.username , tt->options.domain);
- management_query_user_pass(management, &up , "DNSDOMAIN", GET_USER_PASS_NEED_OK,(void*) 0);
- }
-
- strcpy(up.username , dev);
- management_query_user_pass(management, &up , "OPENTUN", GET_USER_PASS_NEED_OK,(void*) 0);
+ for (i = 0; i < tt->options.dns_len; ++i) {
+ management_android_control (management, "DNSSERVER",
+ print_in_addr_t(tt->options.dns[i], 0, &gc));
+ }
- tt->fd = management->connection.lastfdreceived;
- management->connection.lastfdreceived=-1;
-
- if( (tt->fd < 0) || ! (strcmp("ok",up.password)==0)) {
- msg (M_ERR, "ERROR: Cannot open TUN");
- }
- /* Set the actual name to a dummy name to enable scripts */
- tt->actual_name = (char *) malloc(32);
- strncpy(tt->actual_name, "vpnservice-tun",32);
- gc_free (&gc);
+ if(tt->options.domain)
+ management_android_control (management, "DNSDOMAIN", tt->options.domain);
+
+ opentun = management_android_control (management, "OPENTUN", dev);
+
+ /* Pick up the fd from management interface after calling the OPENTUN command */
+ tt->fd = management->connection.lastfdreceived;
+ management->connection.lastfdreceived=-1;
+
+ /* Set the actual name to a dummy name */
+ tt->actual_name = string_alloc (ANDROID_TUNNAME, NULL);
+
+ if ((tt->fd < 0) || !opentun)
+ msg (M_ERR, "ERROR: Cannot open TUN");
+
+ gc_free (&gc);
}
void
diff --git a/openvpn/src/openvpn/win32.c b/openvpn/src/openvpn/win32.c
index 2db96a8d..178e2c35 100644
--- a/openvpn/src/openvpn/win32.c
+++ b/openvpn/src/openvpn/win32.c
@@ -879,7 +879,10 @@ openvpn_execve (const struct argv *a, const struct env_set *es, const unsigned i
start_info.dwFlags = STARTF_USESHOWWINDOW;
start_info.wShowWindow = SW_HIDE;
- if (CreateProcessW (cmd, cl, NULL, NULL, FALSE, 0, env, NULL, &start_info, &proc_info))
+ /* 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;
CloseHandle (proc_info.hThread);
diff --git a/openvpn/version.m4 b/openvpn/version.m4
index 1ea1c32f..376661f7 100644
--- a/openvpn/version.m4
+++ b/openvpn/version.m4
@@ -1,7 +1,7 @@
dnl define the OpenVPN version
define([PRODUCT_NAME], [OpenVPN])
define([PRODUCT_TARNAME], [openvpn])
-define([PRODUCT_VERSION], [2.3_master])
+define([PRODUCT_VERSION], [2.3_git])
define([PRODUCT_BUGREPORT], [openvpn-users@lists.sourceforge.net])
define([PRODUCT_VERSION_RESOURCE], [2,3,0,0])
dnl define the TAP version