From c0f47b6edfd655a11e53110c935a8764fd834a96 Mon Sep 17 00:00:00 2001 From: Arne Schwabe Date: Fri, 24 May 2013 13:28:08 +0200 Subject: Updaten OpenVPN version to 2.4master --- openvpn/src/openvpn/comp.c | 135 +++++++++++++++++++++++++ openvpn/src/openvpn/comp.h | 171 +++++++++++++++++++++++++++++++ openvpn/src/openvpn/compstub.c | 118 ++++++++++++++++++++++ openvpn/src/openvpn/crypto_openssl.c | 6 +- openvpn/src/openvpn/error.c | 1 - openvpn/src/openvpn/init.c | 39 ++++---- openvpn/src/openvpn/manage.c | 157 ++++++++++++++++------------- openvpn/src/openvpn/manage.h | 8 +- openvpn/src/openvpn/multi.c | 20 +++- openvpn/src/openvpn/multi.h | 1 + openvpn/src/openvpn/options.c | 8 +- openvpn/src/openvpn/pf.c | 2 +- openvpn/src/openvpn/route.c | 20 ++-- openvpn/src/openvpn/snappy.c | 189 +++++++++++++++++++++++++++++++++++ openvpn/src/openvpn/snappy.h | 39 ++++++++ openvpn/src/openvpn/socket.c | 37 +++---- openvpn/src/openvpn/socket.h | 14 +++ openvpn/src/openvpn/ssl.c | 84 ++++++++-------- openvpn/src/openvpn/ssl_openssl.c | 2 +- openvpn/src/openvpn/syshead.h | 7 -- openvpn/src/openvpn/tun.c | 104 +++++++++---------- openvpn/src/openvpn/win32.c | 5 +- 22 files changed, 926 insertions(+), 241 deletions(-) create mode 100644 openvpn/src/openvpn/comp.c create mode 100644 openvpn/src/openvpn/comp.h create mode 100644 openvpn/src/openvpn/compstub.c create mode 100644 openvpn/src/openvpn/snappy.c create mode 100644 openvpn/src/openvpn/snappy.h (limited to 'openvpn/src') 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. + * + * 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. + * + * 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. + * + * 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. + * + * 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. + * + * 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 @@ -398,13 +398,6 @@ #define HAVE_GETTIMEOFDAY_NANOSECONDS 1 #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? */ 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); -- cgit v1.2.3