summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog25
-rw-r--r--Makefile.am12
-rw-r--r--common.h2
-rw-r--r--configure.ac9
-rw-r--r--configure_h.awk39
-rw-r--r--configure_log.awk33
-rwxr-xr-xeasy-rsa/2.0/pkitool6
-rw-r--r--init.c4
-rw-r--r--misc.c7
-rw-r--r--misc.h10
-rw-r--r--multi.c6
-rw-r--r--openvpn.835
-rw-r--r--options.c44
-rw-r--r--options.h5
-rw-r--r--route.c8
-rw-r--r--socket.c2
-rw-r--r--socks.c138
-rw-r--r--socks.h2
-rw-r--r--ssl.c124
-rw-r--r--ssl.h8
-rw-r--r--tun.c147
-rw-r--r--version.m42
-rw-r--r--win32.c5
23 files changed, 584 insertions, 89 deletions
diff --git a/ChangeLog b/ChangeLog
index 5580409..8e41bf2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,7 +1,30 @@
OpenVPN Change Log
Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net>
-2010.08.09 -- Version 2.1.2
+2010.08.21 -- Version 2.2-beta3
+
+* Attempt to fix issue where domake-win build system was not properly
+ signing drivers and .exe files.
+
+ Added win/tap_span.py for building multiple versions of the TAP driver
+ and tapinstall binaries using different DDK versions to span from Win2K
+ to Win7 and beyond.
+
+* Community patches
+ David Sommerseth (2):
+ Test framework improvment - Do not FAIL if t_client.rc is missing
+ More t_client.sh updates - exit with SKIP when we want to skip
+
+ Gert Doering (4):
+ Fix compile problems on NetBSD and OpenBSD
+ Fix <net/if.h> compile time problems on OpenBSD for good
+ full "VPN client connect" test framework for OpenVPN
+ Build t_client.sh by configure at run-time.
+
+ chantra (1):
+ Fixes openssl-1.0.0 compilation warning
+
+2010.08.16 -- Version 2.2-beta2
* Windows security issue:
Fixed potential local privilege escalation vulnerability in
diff --git a/Makefile.am b/Makefile.am
index ad0f7e3..430d3ab 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -6,6 +6,7 @@
# packet compression.
#
# Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net>
+# Copyright (C) 2010 David Sommerseth <dazo@users.sourceforge.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
@@ -37,7 +38,7 @@ MAINTAINERCLEANFILES = \
$(srcdir)/depcomp $(srcdir)/aclocal.m4 \
$(srcdir)/config.guess $(srcdir)/config.sub \
$(srcdir)/openvpn.spec
-CLEANFILES = openvpn.8.html
+CLEANFILES = openvpn.8.html configure.h
EXTRA_DIST = \
easy-rsa \
@@ -65,7 +66,8 @@ dist_noinst_SCRIPTS = \
$(TESTS) \
doclean \
domake-win \
- t_cltsrv-down.sh
+ t_cltsrv-down.sh \
+ configure_h.awk configure_log.awk
dist_noinst_DATA = \
openvpn.spec \
@@ -141,6 +143,12 @@ openvpn_SOURCES = \
win32.h win32.c \
cryptoapi.h cryptoapi.c
+nodist_openvpn_SOURCES = configure.h
+options.$(OBJEXT): configure.h
+
+configure.h: Makefile
+ awk -f $(srcdir)/configure_h.awk config.h > $@
+ awk -f $(srcdir)/configure_log.awk config.log >> $@
dist-hook:
cd $(distdir) && for i in $(EXTRA_DIST) $(SUBDIRS) ; do find $$i -name .svn -type d -prune -exec rm -rf '{}' ';' ; rm -f `find $$i -type f | grep -E '(^|\/)\.?\#|\~$$|\.s?o$$'` ; done
diff --git a/common.h b/common.h
index 5548f7c..ff3a0d5 100644
--- a/common.h
+++ b/common.h
@@ -97,6 +97,6 @@ typedef unsigned long ptr_type;
/*
* Script security warning
*/
-#define SCRIPT_SECURITY_WARNING "openvpn_execve: external program may not be called unless '--script-security 2' or higher is enabled. Use '--script-security 3 system' for backward compatibility with 2.1_rc8 and earlier. See --help text or man page for detailed info."
+#define SCRIPT_SECURITY_WARNING "WARNING: External program may not be called unless '--script-security 2' or higher is enabled. Use '--script-security 3 system' for backward compatibility with 2.1_rc8 and earlier. See --help text or man page for detailed info."
#endif
diff --git a/configure.ac b/configure.ac
index 4777108..aca812f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -98,6 +98,12 @@ AC_ARG_ENABLE(plugins,
[PLUGINS="yes"]
)
+AC_ARG_ENABLE(eurephia,
+ [ --disable-eurephia Disable support for the eurephia plug-in],
+ [EUREPHIA="$enableval"],
+ [EUREPHIA="yes"]
+)
+
AC_ARG_ENABLE(management,
[ --disable-management Disable management server support],
[MANAGEMENT="$enableval"],
@@ -641,6 +647,9 @@ if test "${WIN32}" != "yes"; then
)],
[AC_MSG_RESULT([libdl headers not found.])]
)
+ if test "$EUREPHIA" = "yes"; then
+ AC_DEFINE(ENABLE_EUREPHIA, 1, [Enable support for the eurephia plug-in])
+ fi
fi
fi
diff --git a/configure_h.awk b/configure_h.awk
new file mode 100644
index 0000000..672e745
--- /dev/null
+++ b/configure_h.awk
@@ -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) 2010 David Sommerseth <dazo@users.sourceforge.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
+#
+#
+# This script will build up a line which can be included into a C program.
+# The line will contain all interesting #define statements from f.ex. ./config.h
+#
+
+BEGIN {
+ printf ("#define CONFIGURE_DEFINES \"")
+}
+
+/^#define (ENABLE|DISABLE|DEPRECATED|USE)_/ {
+ printf (" %s", $2)
+}
+
+END {
+ printf ("\"\n")
+}
diff --git a/configure_log.awk b/configure_log.awk
new file mode 100644
index 0000000..099e5c4
--- /dev/null
+++ b/configure_log.awk
@@ -0,0 +1,33 @@
+#
+# 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) 2010 David Sommerseth <dazo@users.sourceforge.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
+#
+#
+# This script will build up a line which can be included into a C program.
+# The line will only contain the first entry of the ./configure line from
+# ./config.log.
+#
+
+/\$ (.*)\/configure/ {
+ printf ("#define CONFIGURE_CALL \"%s\"\n", $0)
+ exit 0
+}
diff --git a/easy-rsa/2.0/pkitool b/easy-rsa/2.0/pkitool
index 7266988..49588f5 100755
--- a/easy-rsa/2.0/pkitool
+++ b/easy-rsa/2.0/pkitool
@@ -192,6 +192,12 @@ while [ $# -gt 0 ]; do
$PKCS11TOOL --module "$PKCS11_MODULE_PATH" --list-objects --login --slot "$PKCS11_SLOT"
exit 0;;
+ --help|--usage)
+ usage
+ exit ;;
+ --version)
+ echo "$PROGNAME $VERSION"
+ exit ;;
# errors
--* ) die "$PROGNAME: unknown option: $1" ;;
* ) break ;;
diff --git a/init.c b/init.c
index 2049daf..01bcfc0 100644
--- a/init.c
+++ b/init.c
@@ -417,6 +417,7 @@ init_proxy_dowork (struct context *c)
{
c->c1.socks_proxy = socks_proxy_new (c->options.ce.socks_proxy_server,
c->options.ce.socks_proxy_port,
+ c->options.ce.socks_proxy_authfile,
c->options.ce.socks_proxy_retry,
c->options.auto_proxy_info);
if (c->c1.socks_proxy)
@@ -1191,7 +1192,7 @@ do_route (const struct options *options,
struct argv argv = argv_new ();
setenv_str (es, "script_type", "route-up");
argv_printf (&argv, "%sc", options->route_script);
- openvpn_execve_check (&argv, es, S_SCRIPT, "Route script failed");
+ openvpn_run_script (&argv, es, 0, "--route-up");
argv_reset (&argv);
}
@@ -2024,6 +2025,7 @@ do_init_crypto_tls (struct context *c, const unsigned int flags)
#endif
to.verify_command = options->tls_verify;
+ to.verify_export_cert = options->tls_export_cert;
to.verify_x509name = options->tls_remote;
to.crl_file = options->crl_file;
to.ns_cert_type = options->ns_cert_type;
diff --git a/misc.c b/misc.c
index d3e67ef..94e9efe 100644
--- a/misc.c
+++ b/misc.c
@@ -230,7 +230,7 @@ run_up_down (const char *command,
ifconfig_local, ifconfig_remote,
context);
argv_msg (M_INFO, &argv);
- openvpn_execve_check (&argv, es, S_SCRIPT|S_FATAL, "script failed");
+ openvpn_run_script (&argv, es, S_FATAL, "--up/--down");
argv_reset (&argv);
}
@@ -493,6 +493,7 @@ openvpn_execve_allowed (const unsigned int flags)
return script_security >= SSEC_BUILT_IN;
}
+
#ifndef WIN32
/*
* Run execve() inside a fork(). Designed to replicate the semantics of system() but
@@ -504,6 +505,7 @@ openvpn_execve (const struct argv *a, const struct env_set *es, const unsigned i
{
struct gc_arena gc = gc_new ();
int ret = -1;
+ static bool warn_shown = false;
if (a && a->argv[0])
{
@@ -540,9 +542,10 @@ openvpn_execve (const struct argv *a, const struct env_set *es, const unsigned i
ASSERT (0);
}
}
- else
+ else if (!warn_shown && (script_security < SSEC_SCRIPTS))
{
msg (M_WARN, SCRIPT_SECURITY_WARNING);
+ warn_shown = true;
}
#else
msg (M_WARN, "openvpn_execve: execve function not available");
diff --git a/misc.h b/misc.h
index 37da521..3f22ca0 100644
--- a/misc.h
+++ b/misc.h
@@ -136,6 +136,15 @@ bool openvpn_execve_check (const struct argv *a, const struct env_set *es, const
bool openvpn_execve_allowed (const unsigned int flags);
int openvpn_system (const char *command, const struct env_set *es, unsigned int flags);
+static inline bool
+openvpn_run_script (const struct argv *a, const struct env_set *es, const unsigned int flags, const char *hook)
+{
+ char msg[256];
+
+ openvpn_snprintf(msg, sizeof(msg), "WARNING: Failed running command (%s)", hook);
+ return openvpn_execve_check(a, es, flags | S_SCRIPT, msg);
+};
+
#ifdef HAVE_STRERROR
/* a thread-safe version of strerror */
const char* strerror_ts (int errnum, struct gc_arena *gc);
@@ -338,6 +347,7 @@ void get_user_pass_auto_userid (struct user_pass *up, const char *tag);
extern const char *iproute_path;
#endif
+/* Script security */
#define SSEC_NONE 0 /* strictly no calling of external programs */
#define SSEC_BUILT_IN 1 /* only call built-in programs such as ifconfig, route, netsh, etc.*/
#define SSEC_SCRIPTS 2 /* allow calling of built-in programs and user-defined scripts */
diff --git a/multi.c b/multi.c
index dc26a02..57310f6 100644
--- a/multi.c
+++ b/multi.c
@@ -109,7 +109,7 @@ learn_address_script (const struct multi_context *m,
mroute_addr_print (addr, &gc));
if (mi)
argv_printf_cat (&argv, "%s", tls_common_name (mi->context.c2.tls_multi, false));
- if (!openvpn_execve_check (&argv, es, S_SCRIPT, "WARNING: learn-address command failed"))
+ if (!openvpn_run_script (&argv, es, 0, "--learn-address"))
ret = false;
argv_reset (&argv);
}
@@ -480,7 +480,7 @@ multi_client_disconnect_script (struct multi_context *m,
struct argv argv = argv_new ();
setenv_str (mi->context.c2.es, "script_type", "client-disconnect");
argv_printf (&argv, "%sc", mi->context.options.client_disconnect_script);
- openvpn_execve_check (&argv, mi->context.c2.es, S_SCRIPT, "client-disconnect command failed");
+ openvpn_run_script (&argv, mi->context.c2.es, 0, "--client-disconnect");
argv_reset (&argv);
}
#ifdef MANAGEMENT_DEF_AUTH
@@ -1594,7 +1594,7 @@ multi_connection_established (struct multi_context *m, struct multi_instance *mi
mi->context.options.client_connect_script,
dc_file);
- if (openvpn_execve_check (&argv, mi->context.c2.es, S_SCRIPT, "client-connect command failed"))
+ if (openvpn_run_script (&argv, mi->context.c2.es, 0, "--client-connect"))
{
multi_client_connect_post (m, mi, dc_file, option_permissions_mask, &option_types_found);
++cc_succeeded_count;
diff --git a/openvpn.8 b/openvpn.8
index 4eaf0db..298c79a 100644
--- a/openvpn.8
+++ b/openvpn.8
@@ -4261,11 +4261,23 @@ test).
.B cmd
should return 0 to allow the TLS handshake to proceed, or 1 to fail.
+
+Note that
+.B cmd
+is a command line and as such may (if enclosed in quotes) contain
+whitespace separated arguments. The first word of
.B cmd
-is executed as
+is the shell command to execute and the remaining words are its
+arguments.
+When
+.B cmd
+is executed two arguments are appended, as follows:
.B cmd certificate_depth X509_NAME_oneline
+These arguments are, respectively, the current certificate depth and
+the X509 common name (cn) of the peer.
+
This feature is useful if the peer you want to trust has a certificate
which was signed by a certificate authority who also signed many
other certificates, where you don't necessarily want to trust all of them,
@@ -4279,14 +4291,14 @@ in the OpenVPN distribution.
See the "Environmental Variables" section below for
additional parameters passed as environmental variables.
-
-Note that
-.B cmd
-can be a shell command with multiple arguments, in which
-case all OpenVPN-generated arguments will be appended
-to
-.B cmd
-to build a command line which will be passed to the script.
+.\"*********************************************************
+.TP
+.B \-\-tls-export-cert directory
+Store the certificates the clients uses upon connection to this
+directory. This will be done before --tls-verify is called. The
+certificates will use a temporary name and will be deleted when
+the tls-verify script returns. The file name used for the certificate
+is available via the peer_cert environment variable.
.\"*********************************************************
.TP
.B \-\-tls-remote name
@@ -5287,6 +5299,11 @@ than their names as denoted on the command line
or configuration file.
.\"*********************************************************
.TP
+.B peer_cert
+Temporary file name containing the client certificate upon
+connection. Useful in conjunction with --tls-verify
+.\"*********************************************************
+.TP
.B script_context
Set to "init" or "restart" prior to up/down script execution.
For more information, see
diff --git a/options.c b/options.c
index e4c3c2e..3aa6820 100644
--- a/options.c
+++ b/options.c
@@ -7,6 +7,9 @@
*
* Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net>
*
+ * Additions for eurephia plugin done by:
+ * David Sommerseth <dazo@users.sourceforge.net> Copyright (C) 2009
+ *
* 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.
@@ -46,6 +49,8 @@
#include "helper.h"
#include "manage.h"
#include "forward.h"
+#include "configure.h"
+#include <ctype.h>
#include "memdbg.h"
@@ -74,6 +79,9 @@ const char title_string[] =
#ifdef ENABLE_PKCS11
" [PKCS11]"
#endif
+#ifdef ENABLE_EUREPHIA
+ " [eurephia]"
+#endif
" built on " __DATE__
;
@@ -121,8 +129,11 @@ static const char usage_message[] =
" AGENT user-agent\n"
#endif
#ifdef ENABLE_SOCKS
- "--socks-proxy s [p]: Connect to remote host through a Socks5 proxy at address\n"
- " s and port p (default port = 1080).\n"
+ "--socks-proxy s [p] [up] : Connect to remote host through a Socks5 proxy at\n"
+ " address s and port p (default port = 1080).\n"
+ " If proxy authentication is required,\n"
+ " up is a file containing username/password on 2 lines, or\n"
+ " 'stdin' to prompt for console.\n"
"--socks-proxy-retry : Retry indefinitely on Socks proxy errors.\n"
#endif
"--resolv-retry n: If hostname resolve fails for --remote, retry\n"
@@ -505,6 +516,8 @@ static const char usage_message[] =
"--key file : Local private key in .pem format.\n"
"--pkcs12 file : PKCS#12 file containing local private key, local certificate\n"
" and optionally the root CA certificate.\n"
+ "--x509-username-field : Field used in x509 certificat to be username.\n"
+ " Default is CN.\n"
#ifdef WIN32
"--cryptoapicert select-string : Load the certificate and private key from the\n"
" Windows Certificate System Store.\n"
@@ -535,6 +548,9 @@ static const char usage_message[] =
" tests of certification. cmd should return 0 to allow\n"
" TLS handshake to proceed, or 1 to fail. (cmd is\n"
" executed as 'cmd certificate_depth X509_NAME_oneline')\n"
+ "--tls-export-cert [directory] : Get peer cert in PEM format and store it \n"
+ " in an openvpn temporary file in [directory]. Peer cert is \n"
+ " stored before tls-verify script execution and deleted after.\n"
"--tls-remote x509name: Accept connections only from a host with X509 name\n"
" x509name. The remote host must also pass all other tests\n"
" of verification.\n"
@@ -758,6 +774,7 @@ init_options (struct options *o, const bool init_gc)
o->renegotiate_seconds = 3600;
o->handshake_window = 60;
o->transition_window = 3600;
+ o->x509_username_field = X509_USERNAME_FIELD_DEFAULT;
#endif
#endif
#ifdef ENABLE_PKCS11
@@ -1336,6 +1353,7 @@ show_settings (const struct options *o)
#endif
SHOW_STR (cipher_list);
SHOW_STR (tls_verify);
+ SHOW_STR (tls_export_cert);
SHOW_STR (tls_remote);
SHOW_STR (crl_file);
SHOW_INT (ns_cert_type);
@@ -2064,6 +2082,7 @@ options_postprocess_verify_ce (const struct options *options, const struct conne
MUST_BE_UNDEF (pkcs12_file);
MUST_BE_UNDEF (cipher_list);
MUST_BE_UNDEF (tls_verify);
+ MUST_BE_UNDEF (tls_export_cert);
MUST_BE_UNDEF (tls_remote);
MUST_BE_UNDEF (tls_timeout);
MUST_BE_UNDEF (renegotiate_bytes);
@@ -2910,6 +2929,14 @@ usage_version (void)
msg (M_INFO|M_NOPREFIX, "%s", title_string);
msg (M_INFO|M_NOPREFIX, "Originally developed by James Yonan");
msg (M_INFO|M_NOPREFIX, "Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net>");
+#ifndef ENABLE_SMALL
+#ifdef CONFIGURE_CALL
+ msg (M_INFO|M_NOPREFIX, "\n%s\n", CONFIGURE_CALL);
+#endif
+#ifdef CONFIGURE_DEFINES
+ msg (M_INFO|M_NOPREFIX, "Compile time defines: %s", CONFIGURE_DEFINES);
+#endif
+#endif
openvpn_exit (OPENVPN_EXIT_STATUS_USAGE); /* exit point */
}
@@ -4484,6 +4511,7 @@ add_option (struct options *options,
options->ce.socks_proxy_port = 1080;
}
options->ce.socks_proxy_server = p[1];
+ options->ce.socks_proxy_authfile = p[3]; /* might be NULL */
}
else if (streq (p[0], "socks-proxy-retry"))
{
@@ -5774,6 +5802,11 @@ add_option (struct options *options,
warn_multiple_script (options->tls_verify, "tls-verify");
options->tls_verify = string_substitute (p[1], ',', ' ', &options->gc);
}
+ else if (streq (p[0], "tls-export-cert") && p[1])
+ {
+ VERIFY_PERMISSION (OPT_P_GENERAL);
+ options->tls_export_cert = p[1];
+ }
else if (streq (p[0], "tls-remote") && p[1])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
@@ -5899,6 +5932,13 @@ add_option (struct options *options,
}
options->key_method = key_method;
}
+ else if (streq (p[0], "x509-username-field") && p[1])
+ {
+ char *s = p[1];
+ VERIFY_PERMISSION (OPT_P_GENERAL);
+ while ((*s = toupper(*s)) != '\0') s++; /* Uppercase if necessary */
+ options->x509_username_field = p[1];
+ }
#endif /* USE_SSL */
#endif /* USE_CRYPTO */
#ifdef ENABLE_PKCS11
diff --git a/options.h b/options.h
index fc5db58..c51a10d 100644
--- a/options.h
+++ b/options.h
@@ -95,6 +95,7 @@ struct connection_entry
#ifdef ENABLE_SOCKS
const char *socks_proxy_server;
int socks_proxy_port;
+ const char *socks_proxy_authfile;
bool socks_proxy_retry;
#endif
@@ -467,6 +468,7 @@ struct options
const char *pkcs12_file;
const char *cipher_list;
const char *tls_verify;
+ const char *tls_export_cert;
const char *tls_remote;
const char *crl_file;
@@ -511,6 +513,9 @@ struct options
within n seconds of handshake initiation. */
int handshake_window;
+ /* Field used to be the username in X509 cert. */
+ char *x509_username_field;
+
/* Old key allowed to live n seconds after new key goes active */
int transition_window;
diff --git a/route.c b/route.c
index 20f62d5..c63eb41 100644
--- a/route.c
+++ b/route.c
@@ -952,16 +952,14 @@ add_route (struct route *r, const struct tuntap *tt, unsigned int flags, const s
argv_printf (&argv, "%s add",
ROUTE_PATH);
-#if 0
- if (r->metric_defined)
- argv_printf_cat (&argv, "-rtt %d", r->metric);
-#endif
-
argv_printf_cat (&argv, "%s -netmask %s %s",
network,
netmask,
gateway);
+ if (r->metric_defined)
+ argv_printf_cat (&argv, "%d", r->metric);
+
argv_msg (D_ROUTE, &argv);
status = openvpn_execve_check (&argv, es, 0, "ERROR: Solaris route add command failed");
diff --git a/socket.c b/socket.c
index 660e2ac..b02d3da 100644
--- a/socket.c
+++ b/socket.c
@@ -1695,7 +1695,7 @@ link_socket_connection_initiated (const struct buffer *buf,
struct argv argv = argv_new ();
setenv_str (es, "script_type", "ipchange");
ipchange_fmt (true, &argv, info, &gc);
- openvpn_execve_check (&argv, es, S_SCRIPT, "ip-change command failed");
+ openvpn_run_script (&argv, es, 0, "--ipchange");
argv_reset (&argv);
}
diff --git a/socks.c b/socks.c
index 0c1bb3e..7c9edd1 100644
--- a/socks.c
+++ b/socks.c
@@ -23,10 +23,11 @@
*/
/*
- * 2004-01-30: Added Socks5 proxy support
+ * 2004-01-30: Added Socks5 proxy support, see RFC 1928
* (Christof Meerwald, http://cmeerw.org)
*
- * see RFC 1928, only supports "no authentication"
+ * 2010-10-10: Added Socks5 plain text authentication support (RFC 1929)
+ * (Pierre Bourdon <delroth@gmail.com>)
*/
#include "syshead.h"
@@ -38,10 +39,12 @@
#include "win32.h"
#include "socket.h"
#include "fdmisc.h"
+#include "misc.h"
#include "proxy.h"
#include "memdbg.h"
+#define UP_TYPE_SOCKS "SOCKS Proxy"
void
socks_adjust_frame_parameters (struct frame *frame, int proto)
@@ -53,6 +56,7 @@ socks_adjust_frame_parameters (struct frame *frame, int proto)
struct socks_proxy_info *
socks_proxy_new (const char *server,
int port,
+ const char *authfile,
bool retry,
struct auto_proxy_info *auto_proxy_info)
{
@@ -77,6 +81,12 @@ socks_proxy_new (const char *server,
strncpynt (p->server, server, sizeof (p->server));
p->port = port;
+
+ if (authfile)
+ strncpynt (p->authfile, authfile, sizeof (p->authfile));
+ else
+ p->authfile[0] = 0;
+
p->retry = retry;
p->defined = true;
@@ -90,15 +100,99 @@ socks_proxy_close (struct socks_proxy_info *sp)
}
static bool
-socks_handshake (socket_descriptor_t sd, volatile int *signal_received)
+socks_username_password_auth (struct socks_proxy_info *p,
+ socket_descriptor_t sd,
+ volatile int *signal_received)
+{
+ char to_send[516];
+ char buf[2];
+ int len = 0;
+ const int timeout_sec = 5;
+ struct user_pass creds;
+ ssize_t size;
+
+ creds.defined = 0;
+
+ get_user_pass (&creds, p->authfile, UP_TYPE_SOCKS, GET_USER_PASS_MANAGEMENT);
+ snprintf (to_send, sizeof (to_send), "\x01%c%s%c%s", strlen(creds.username),
+ creds.username, strlen(creds.password), creds.password);
+ size = send (sd, to_send, strlen(to_send), MSG_NOSIGNAL);
+
+ if (size != strlen (to_send))
+ {
+ msg (D_LINK_ERRORS | M_ERRNO_SOCK, "socks_username_password_auth: TCP port write failed on send()");
+ return false;
+ }
+
+ while (len < 2)
+ {
+ int status;
+ ssize_t size;
+ fd_set reads;
+ struct timeval tv;
+ char c;
+
+ FD_ZERO (&reads);
+ FD_SET (sd, &reads);
+ tv.tv_sec = timeout_sec;
+ tv.tv_usec = 0;
+
+ status = select (sd + 1, &reads, NULL, NULL, &tv);
+
+ get_signal (signal_received);
+ if (*signal_received)
+ return false;
+
+ /* timeout? */
+ if (status == 0)
+ {
+ msg (D_LINK_ERRORS | M_ERRNO_SOCK, "socks_username_password_auth: TCP port read timeout expired");
+ return false;
+ }
+
+ /* error */
+ if (status < 0)
+ {
+ msg (D_LINK_ERRORS | M_ERRNO_SOCK, "socks_username_password_auth: TCP port read failed on select()");
+ return false;
+ }
+
+ /* read single char */
+ size = recv(sd, &c, 1, MSG_NOSIGNAL);
+
+ /* error? */
+ if (size != 1)
+ {
+ msg (D_LINK_ERRORS | M_ERRNO_SOCK, "socks_username_password_auth: TCP port read failed on recv()");
+ return false;
+ }
+
+ /* store char in buffer */
+ buf[len++] = c;
+ }
+
+ /* VER = 5, SUCCESS = 0 --> auth success */
+ if (buf[0] != 5 && buf[1] != 0)
+ {
+ msg (D_LINK_ERRORS, "socks_username_password_auth: server refused the authentication");
+ return false;
+ }
+
+ return true;
+}
+
+static bool
+socks_handshake (struct socks_proxy_info *p,
+ socket_descriptor_t sd,
+ volatile int *signal_received)
{
char buf[2];
int len = 0;
const int timeout_sec = 5;
- /* VER = 5, NMETHODS = 1, METHODS = [0] */
- const ssize_t size = send (sd, "\x05\x01\x00", 3, MSG_NOSIGNAL);
- if (size != 3)
+ /* VER = 5, NMETHODS = 2, METHODS = [0 (no auth), 2 (plain login)] */
+ const ssize_t size = send (sd, "\x05\x02\x00\x02", 4, MSG_NOSIGNAL);
+ if (size != 4)
{
msg (D_LINK_ERRORS | M_ERRNO_SOCK, "socks_handshake: TCP port write failed on send()");
return false;
@@ -151,13 +245,37 @@ socks_handshake (socket_descriptor_t sd, volatile int *signal_received)
buf[len++] = c;
}
- /* VER == 5 && METHOD == 0 */
- if (buf[0] != '\x05' || buf[1] != '\x00')
+ /* VER == 5 */
+ if (buf[0] != '\x05')
{
msg (D_LINK_ERRORS, "socks_handshake: Socks proxy returned bad status");
return false;
}
+ /* select the appropriate authentication method */
+ switch (buf[1])
+ {
+ case 0: /* no authentication */
+ break;
+
+ case 2: /* login/password */
+ if (!p->authfile[0])
+ {
+ msg(D_LINK_ERRORS, "socks_handshake: server asked for username/login auth but we were "
+ "not provided any credentials");
+ return false;
+ }
+
+ if (!socks_username_password_auth(p, sd, signal_received))
+ return false;
+
+ break;
+
+ default: /* unknown auth method */
+ msg(D_LINK_ERRORS, "socks_handshake: unknown SOCKS auth method");
+ return false;
+ }
+
return true;
}
@@ -281,7 +399,7 @@ establish_socks_proxy_passthru (struct socks_proxy_info *p,
char buf[128];
size_t len;
- if (!socks_handshake (sd, signal_received))
+ if (!socks_handshake (p, sd, signal_received))
goto error;
/* format Socks CONNECT message */
@@ -328,7 +446,7 @@ establish_socks_proxy_udpassoc (struct socks_proxy_info *p,
struct openvpn_sockaddr *relay_addr,
volatile int *signal_received)
{
- if (!socks_handshake (ctrl_sd, signal_received))
+ if (!socks_handshake (p, ctrl_sd, signal_received))
goto error;
{
diff --git a/socks.h b/socks.h
index 702aa06..b748bb3 100644
--- a/socks.h
+++ b/socks.h
@@ -43,12 +43,14 @@ struct socks_proxy_info {
char server[128];
int port;
+ char authfile[256];
};
void socks_adjust_frame_parameters (struct frame *frame, int proto);
struct socks_proxy_info *socks_proxy_new (const char *server,
int port,
+ const char *authfile,
bool retry,
struct auto_proxy_info *auto_proxy_info);
diff --git a/ssl.c b/ssl.c
index 7618c8f..e7fd071 100644
--- a/ssl.c
+++ b/ssl.c
@@ -7,6 +7,10 @@
*
* Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net>
*
+ * Additions for eurephia plugin done by:
+ * David Sommerseth <dazo@users.sourceforge.net> Copyright (C) 2008-2009
+ *
+ *
* 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.
@@ -714,6 +718,51 @@ string_mod_sslname (char *str, const unsigned int restrictive_flags, const unsig
string_mod (str, restrictive_flags, 0, '_');
}
+/* Get peer cert and store it in pem format in a temporary file
+ * in tmp_dir
+ */
+
+const char *
+get_peer_cert(X509_STORE_CTX *ctx, const char *tmp_dir, struct gc_arena *gc)
+{
+ X509 *peercert;
+ FILE *peercert_file;
+ const char *peercert_filename="";
+
+ if(!tmp_dir)
+ return NULL;
+
+ /* get peer cert */
+ peercert = X509_STORE_CTX_get_current_cert(ctx);
+ if(!peercert)
+ {
+ msg (M_ERR, "Unable to get peer certificate from current context");
+ return NULL;
+ }
+
+ /* create tmp file to store peer cert */
+ peercert_filename = create_temp_file (tmp_dir, "pcf", gc);
+
+ /* write peer-cert in tmp-file */
+ peercert_file = fopen(peercert_filename, "w+");
+ if(!peercert_file)
+ {
+ msg (M_ERR, "Failed to open temporary file : %s", peercert_filename);
+ return NULL;
+ }
+ if(PEM_write_X509(peercert_file,peercert)<0)
+ {
+ msg (M_ERR, "Failed to write peer certificate in PEM format");
+ fclose(peercert_file);
+ return NULL;
+ }
+
+ fclose(peercert_file);
+ return peercert_filename;
+}
+
+char * x509_username_field; /* GLOBAL */
+
/*
* Our verify callback function -- check
* that an incoming peer certificate is good.
@@ -724,7 +773,7 @@ verify_callback (int preverify_ok, X509_STORE_CTX * ctx)
{
char *subject = NULL;
char envname[64];
- char common_name[TLS_CN_LEN];
+ char common_name[TLS_USERNAME_LEN];
SSL *ssl;
struct tls_session *session;
const struct tls_options *opt;
@@ -756,18 +805,20 @@ verify_callback (int preverify_ok, X509_STORE_CTX * ctx)
string_mod_sslname (subject, X509_NAME_CHAR_CLASS, opt->ssl_flags);
string_replace_leading (subject, '-', '_');
- /* extract the common name */
- if (!extract_x509_field_ssl (X509_get_subject_name (ctx->current_cert), "CN", common_name, TLS_CN_LEN))
+ /* extract the username (default is CN) */
+ if (!extract_x509_field_ssl (X509_get_subject_name (ctx->current_cert), x509_username_field, common_name, sizeof(common_name)))
{
if (!ctx->error_depth)
- {
- msg (D_TLS_ERRORS, "VERIFY ERROR: could not extract Common Name from X509 subject string ('%s') -- note that the Common Name length is limited to %d characters",
- subject,
- TLS_CN_LEN);
- goto err;
- }
+ {
+ msg (D_TLS_ERRORS, "VERIFY ERROR: could not extract %s from X509 subject string ('%s') -- note that the username length is limited to %d characters",
+ x509_username_field,
+ subject,
+ TLS_USERNAME_LEN);
+ goto err;
+ }
}
+
string_mod_sslname (common_name, COMMON_NAME_CHAR_CLASS, opt->ssl_flags);
cert_hash_remember (session, ctx->error_depth, ctx->current_cert->sha1_hash);
@@ -807,6 +858,16 @@ verify_callback (int preverify_ok, X509_STORE_CTX * ctx)
openvpn_snprintf (envname, sizeof(envname), "tls_id_%d", ctx->error_depth);
setenv_str (opt->es, envname, subject);
+#ifdef ENABLE_EUREPHIA
+ /* export X509 cert SHA1 fingerprint */
+ {
+ struct gc_arena gc = gc_new ();
+ openvpn_snprintf (envname, sizeof(envname), "tls_digest_%d", ctx->error_depth);
+ setenv_str (opt->es, envname,
+ format_hex_ex(ctx->current_cert->sha1_hash, SHA_DIGEST_LENGTH, 0, 1, ":", &gc));
+ gc_free(&gc);
+ }
+#endif
#if 0
/* export common name string as environmental variable */
openvpn_snprintf (envname, sizeof(envname), "tls_common_name_%d", ctx->error_depth);
@@ -933,32 +994,48 @@ verify_callback (int preverify_ok, X509_STORE_CTX * ctx)
/* run --tls-verify script */
if (opt->verify_command)
{
+ const char *tmp_file = NULL;
+ struct gc_arena gc;
int ret;
setenv_str (opt->es, "script_type", "tls-verify");
+ if (opt->verify_export_cert)
+ {
+ gc = gc_new();
+ if ((tmp_file=get_peer_cert(ctx, opt->verify_export_cert,&gc)))
+ {
+ setenv_str(opt->es, "peer_cert", tmp_file);
+ }
+ }
+
argv_printf (&argv, "%sc %d %s",
opt->verify_command,
ctx->error_depth,
subject);
argv_msg_prefix (D_TLS_DEBUG, &argv, "TLS: executing verify command");
- ret = openvpn_execve (&argv, opt->es, S_SCRIPT);
+ ret = openvpn_run_script (&argv, opt->es, 0, "--tls-verify script");
+
+ if (opt->verify_export_cert)
+ {
+ if (tmp_file)
+ delete_file(tmp_file);
+ gc_free(&gc);
+ }
- if (system_ok (ret))
+ if (ret)
{
msg (D_HANDSHAKE, "VERIFY SCRIPT OK: depth=%d, %s",
ctx->error_depth, subject);
}
else
{
- if (!system_executed (ret))
- argv_msg_prefix (M_ERR, &argv, "Verify command failed to execute");
msg (D_HANDSHAKE, "VERIFY SCRIPT ERROR: depth=%d, %s",
ctx->error_depth, subject);
goto err; /* Reject connection */
}
}
-
+
/* check peer cert against CRL */
if (opt->crl_file)
{
@@ -1798,7 +1875,8 @@ init_ssl (const struct options *options)
}
else
#endif
- SSL_CTX_set_verify (ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
+ x509_username_field = (char *) options->x509_username_field;
+ SSL_CTX_set_verify (ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
verify_callback);
/* Connection information callback */
@@ -3251,7 +3329,6 @@ verify_user_pass_script (struct tls_session *session, const struct user_pass *up
struct gc_arena gc = gc_new ();
struct argv argv = argv_new ();
const char *tmp_file = "";
- int retval;
bool ret = false;
/* Is username defined? */
@@ -3294,16 +3371,11 @@ verify_user_pass_script (struct tls_session *session, const struct user_pass *up
/* format command line */
argv_printf (&argv, "%sc %s", session->opt->auth_user_pass_verify_script, tmp_file);
-
+
/* call command */
- retval = openvpn_execve (&argv, session->opt->es, S_SCRIPT);
+ ret = openvpn_run_script (&argv, session->opt->es, 0,
+ "--auth-user-pass-verify");
- /* test return status of command */
- if (system_ok (retval))
- ret = true;
- else if (!system_executed (retval))
- argv_msg_prefix (D_TLS_ERRORS, &argv, "TLS Auth Error: user-pass-verify script failed to execute");
-
if (!session->opt->auth_user_pass_verify_script_via_file)
setenv_del (session->opt->es, "password");
}
@@ -3749,9 +3821,9 @@ key_method_2_read (struct buffer *buf, struct tls_multi *multi, struct tls_sessi
s2 = verify_user_pass_script (session, up);
/* check sizing of username if it will become our common name */
- if ((session->opt->ssl_flags & SSLF_USERNAME_AS_COMMON_NAME) && strlen (up->username) >= TLS_CN_LEN)
+ if ((session->opt->ssl_flags & SSLF_USERNAME_AS_COMMON_NAME) && strlen (up->username) >= TLS_USERNAME_LEN)
{
- msg (D_TLS_ERRORS, "TLS Auth Error: --username-as-common name specified and username is longer than the maximum permitted Common Name length of %d characters", TLS_CN_LEN);
+ msg (D_TLS_ERRORS, "TLS Auth Error: --username-as-common name specified and username is longer than the maximum permitted Common Name length of %d characters", TLS_USERNAME_LEN);
s1 = OPENVPN_PLUGIN_FUNC_ERROR;
}
diff --git a/ssl.h b/ssl.h
index bc2e72c..f159fdd 100644
--- a/ssl.h
+++ b/ssl.h
@@ -278,8 +278,8 @@
* Buffer sizes (also see mtu.h).
*/
-/* Maximum length of common name */
-#define TLS_CN_LEN 64
+/* Maximum length of the username in cert */
+#define TLS_USERNAME_LEN 64
/* Legal characters in an X509 or common name */
#define X509_NAME_CHAR_CLASS (CC_ALNUM|CC_UNDERBAR|CC_DASH|CC_DOT|CC_AT|CC_COLON|CC_SLASH|CC_EQUAL)
@@ -288,6 +288,9 @@
/* Maximum length of OCC options string passed as part of auth handshake */
#define TLS_OPTIONS_LEN 512
+/* Default field in X509 to be username */
+#define X509_USERNAME_FIELD_DEFAULT "CN"
+
/*
* Range of key exchange methods
*/
@@ -446,6 +449,7 @@ struct tls_options
/* cert verification parms */
const char *verify_command;
+ const char *verify_export_cert;
const char *verify_x509name;
const char *crl_file;
int ns_cert_type;
diff --git a/tun.c b/tun.c
index 10dde6b..0e4476e 100644
--- a/tun.c
+++ b/tun.c
@@ -63,6 +63,7 @@ static const char *netsh_get_id (const char *dev_node, struct gc_arena *gc);
#ifdef TARGET_SOLARIS
static void solaris_error_close (struct tuntap *tt, const struct env_set *es, const char *actual);
+#include <stropts.h>
#endif
bool
@@ -701,12 +702,45 @@ do_ifconfig (struct tuntap *tt,
);
}
else
- no_tap_ifconfig ();
+ if (tt->topology == TOP_SUBNET)
+ {
+ argv_printf (&argv,
+ "%s %s %s %s netmask %s mtu %d up",
+ IFCONFIG_PATH,
+ actual,
+ ifconfig_local,
+ ifconfig_local,
+ ifconfig_remote_netmask,
+ tun_mtu
+ );
+ }
+ else
+ argv_printf (&argv,
+ " %s %s %s netmask %s broadcast + up",
+ IFCONFIG_PATH,
+ actual,
+ ifconfig_local,
+ ifconfig_remote_netmask
+ );
argv_msg (M_INFO, &argv);
if (!openvpn_execve_check (&argv, es, 0, "Solaris ifconfig phase-2 failed"))
solaris_error_close (tt, es, actual);
+ if (!tun && tt->topology == TOP_SUBNET)
+ {
+ /* Add a network route for the local tun interface */
+ struct route r;
+ CLEAR (r);
+ r.defined = true;
+ r.network = tt->local & tt->remote_netmask;
+ r.netmask = tt->remote_netmask;
+ r.gateway = tt->local;
+ r.metric_defined = true;
+ r.metric = 0;
+ add_route (&r, tt, 0, es);
+ }
+
tt->did_ifconfig = true;
#elif defined(TARGET_OPENBSD)
@@ -1372,15 +1406,17 @@ read_tun (struct tuntap* tt, uint8_t *buf, int len)
void
open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6, struct tuntap *tt)
{
- int if_fd, muxid, ppa = -1;
- struct ifreq ifr;
+ int if_fd, ip_muxid, arp_muxid, arp_fd, ppa = -1;
+ struct lifreq ifr;
const char *ptr;
- const char *ip_node;
+ const char *ip_node, *arp_node;
const char *dev_tuntap_type;
int link_type;
bool is_tun;
+ struct strioctl strioc_if, strioc_ppa;
- ipv6_support (ipv6, false, tt);
+ ipv6_support (ipv6, true, tt);
+ memset(&ifr, 0x0, sizeof(ifr));
if (tt->type == DEV_TYPE_NULL)
{
@@ -1399,9 +1435,10 @@ open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6
}
else if (tt->type == DEV_TYPE_TAP)
{
- ip_node = "/dev/ip";
+ ip_node = "/dev/udp";
if (!dev_node)
dev_node = "/dev/tap";
+ arp_node = dev_node;
dev_tuntap_type = "tap";
link_type = I_PLINK; /* was: I_LINK */
is_tun = false;
@@ -1428,7 +1465,11 @@ open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6
msg (M_ERR, "Can't open %s", dev_node);
/* Assign a new PPA and get its unit number. */
- if ((ppa = ioctl (tt->fd, TUNNEWPPA, ppa)) < 0)
+ strioc_ppa.ic_cmd = TUNNEWPPA;
+ strioc_ppa.ic_timout = 0;
+ strioc_ppa.ic_len = sizeof(ppa);
+ strioc_ppa.ic_dp = (char *)&ppa;
+ if ((ppa = ioctl (tt->fd, I_STR, &strioc_ppa)) < 0)
msg (M_ERR, "Can't assign new interface");
if ((if_fd = open (dev_node, O_RDWR, 0)) < 0)
@@ -1437,27 +1478,83 @@ open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6
if (ioctl (if_fd, I_PUSH, "ip") < 0)
msg (M_ERR, "Can't push IP module");
+ if (tt->type == DEV_TYPE_TUN)
+ {
/* Assign ppa according to the unit number returned by tun device */
if (ioctl (if_fd, IF_UNITSEL, (char *) &ppa) < 0)
msg (M_ERR, "Can't set PPA %d", ppa);
-
- if ((muxid = ioctl (tt->ip_fd, link_type, if_fd)) < 0)
- msg (M_ERR, "Can't link %s device to IP", dev_tuntap_type);
-
- close (if_fd);
+ }
tt->actual_name = (char *) malloc (32);
check_malloc_return (tt->actual_name);
openvpn_snprintf (tt->actual_name, 32, "%s%d", dev_tuntap_type, ppa);
+ if (tt->type == DEV_TYPE_TAP)
+ {
+ if (ioctl(if_fd, SIOCGLIFFLAGS, &ifr) < 0)
+ msg (M_ERR, "Can't get flags\n");
+ strncpynt (ifr.lifr_name, tt->actual_name, sizeof (ifr.lifr_name));
+ ifr.lifr_ppa = ppa;
+ /* Assign ppa according to the unit number returned by tun device */
+ if (ioctl (if_fd, SIOCSLIFNAME, &ifr) < 0)
+ msg (M_ERR, "Can't set PPA %d", ppa);
+ if (ioctl(if_fd, SIOCGLIFFLAGS, &ifr) <0)
+ msg (M_ERR, "Can't get flags\n");
+ /* Push arp module to if_fd */
+ if (ioctl (if_fd, I_PUSH, "arp") < 0)
+ msg (M_ERR, "Can't push ARP module");
+
+ /* Pop any modules on the stream */
+ while (true)
+ {
+ if (ioctl (tt->ip_fd, I_POP, NULL) < 0)
+ break;
+ }
+ /* Push arp module to ip_fd */
+ if (ioctl (tt->ip_fd, I_PUSH, "arp") < 0)
+ msg (M_ERR, "Can't push ARP module\n");
+
+ /* Open arp_fd */
+ if ((arp_fd = open (arp_node, O_RDWR, 0)) < 0)
+ msg (M_ERR, "Can't open %s\n", arp_node);
+ /* Push arp module to arp_fd */
+ if (ioctl (arp_fd, I_PUSH, "arp") < 0)
+ msg (M_ERR, "Can't push ARP module\n");
+
+ /* Set ifname to arp */
+ strioc_if.ic_cmd = SIOCSLIFNAME;
+ strioc_if.ic_timout = 0;
+ strioc_if.ic_len = sizeof(ifr);
+ strioc_if.ic_dp = (char *)&ifr;
+ if (ioctl(arp_fd, I_STR, &strioc_if) < 0){
+ msg (M_ERR, "Can't set ifname to arp\n");
+ }
+ }
+
+ if ((ip_muxid = ioctl (tt->ip_fd, link_type, if_fd)) < 0)
+ msg (M_ERR, "Can't link %s device to IP", dev_tuntap_type);
+
+ if (tt->type == DEV_TYPE_TAP) {
+ if ((arp_muxid = ioctl (tt->ip_fd, link_type, arp_fd)) < 0)
+ msg (M_ERR, "Can't link %s device to ARP", dev_tuntap_type);
+ close (arp_fd);
+ }
+
CLEAR (ifr);
- strncpynt (ifr.ifr_name, tt->actual_name, sizeof (ifr.ifr_name));
- ifr.ifr_ip_muxid = muxid;
+ strncpynt (ifr.lifr_name, tt->actual_name, sizeof (ifr.lifr_name));
+ ifr.lifr_ip_muxid = ip_muxid;
+ if (tt->type == DEV_TYPE_TAP) {
+ ifr.lifr_arp_muxid = arp_muxid;
+ }
- if (ioctl (tt->ip_fd, SIOCSIFMUXID, &ifr) < 0)
+ if (ioctl (tt->ip_fd, SIOCSLIFMUXID, &ifr) < 0)
{
- ioctl (tt->ip_fd, I_PUNLINK, muxid);
+ if (tt->type == DEV_TYPE_TAP)
+ {
+ ioctl (tt->ip_fd, I_PUNLINK , arp_muxid);
+ }
+ ioctl (tt->ip_fd, I_PUNLINK, ip_muxid);
msg (M_ERR, "Can't set multiplexor id");
}
@@ -1475,18 +1572,24 @@ solaris_close_tun (struct tuntap *tt)
{
if (tt->ip_fd >= 0)
{
- struct ifreq ifr;
+ struct lifreq ifr;
CLEAR (ifr);
- strncpynt (ifr.ifr_name, tt->actual_name, sizeof (ifr.ifr_name));
+ strncpynt (ifr.lifr_name, tt->actual_name, sizeof (ifr.lifr_name));
- if (ioctl (tt->ip_fd, SIOCGIFFLAGS, &ifr) < 0)
+ if (ioctl (tt->ip_fd, SIOCGLIFFLAGS, &ifr) < 0)
msg (M_WARN | M_ERRNO, "Can't get iface flags");
- if (ioctl (tt->ip_fd, SIOCGIFMUXID, &ifr) < 0)
+ if (ioctl (tt->ip_fd, SIOCGLIFMUXID, &ifr) < 0)
msg (M_WARN | M_ERRNO, "Can't get multiplexor id");
- if (ioctl (tt->ip_fd, I_PUNLINK, ifr.ifr_ip_muxid) < 0)
- msg (M_WARN | M_ERRNO, "Can't unlink interface");
+ if (tt->type == DEV_TYPE_TAP)
+ {
+ if (ioctl (tt->ip_fd, I_PUNLINK, ifr.lifr_arp_muxid) < 0)
+ msg (M_WARN | M_ERRNO, "Can't unlink interface(arp)");
+ }
+
+ if (ioctl (tt->ip_fd, I_PUNLINK, ifr.lifr_ip_muxid) < 0)
+ msg (M_WARN | M_ERRNO, "Can't unlink interface(ip)");
close (tt->ip_fd);
tt->ip_fd = -1;
diff --git a/version.m4 b/version.m4
index 9af265e..f390f4c 100644
--- a/version.m4
+++ b/version.m4
@@ -1,5 +1,5 @@
dnl define the OpenVPN version
-define(PRODUCT_VERSION,[2.1.3c])
+define(PRODUCT_VERSION,[2.2-beta])
dnl define the TAP version
define(PRODUCT_TAP_ID,[tap0901])
define(PRODUCT_TAP_WIN32_MIN_MAJOR,[9])
diff --git a/win32.c b/win32.c
index 2a3350d..7c9901e 100644
--- a/win32.c
+++ b/win32.c
@@ -952,6 +952,8 @@ int
openvpn_execve (const struct argv *a, const struct env_set *es, const unsigned int flags)
{
int ret = -1;
+ static bool exec_warn = false;
+
if (a && a->argv[0])
{
if (openvpn_execve_allowed (flags))
@@ -1002,9 +1004,10 @@ openvpn_execve (const struct argv *a, const struct env_set *es, const unsigned i
ASSERT (0);
}
}
- else
+ else if (!exec_warn && (script_security < SSEC_SCRIPTS))
{
msg (M_WARN, SCRIPT_SECURITY_WARNING);
+ exec_warn = true;
}
}
else