summaryrefslogtreecommitdiff
path: root/src/openvpn
diff options
context:
space:
mode:
authorAlberto Gonzalez Iniesta <agi@inittab.org>2013-05-17 12:00:05 +0200
committerAlberto Gonzalez Iniesta <agi@inittab.org>2013-05-17 12:00:05 +0200
commit7da22c96dd646047e97732832331c84528bdc95e (patch)
tree182180f14a3e23d52308d40654e1cf06b554944c /src/openvpn
parent8a59dafbd02d0ee1faaf674f4420cdc412f13aea (diff)
parentfcc893c0d8d245525cfb023b6e2a8aae086304cf (diff)
Merge tag 'upstream/2.3.1'
Upstream version 2.3.1
Diffstat (limited to 'src/openvpn')
-rw-r--r--src/openvpn/Makefile.in51
-rw-r--r--src/openvpn/buffer.h18
-rw-r--r--src/openvpn/crypto.c22
-rw-r--r--src/openvpn/crypto_backend.h12
-rw-r--r--src/openvpn/crypto_openssl.c12
-rw-r--r--src/openvpn/crypto_polarssl.c55
-rw-r--r--src/openvpn/crypto_polarssl.h3
-rw-r--r--src/openvpn/event.c3
-rw-r--r--src/openvpn/init.c7
-rw-r--r--src/openvpn/mbuf.h2
-rw-r--r--src/openvpn/misc.c30
-rw-r--r--src/openvpn/options.c139
-rw-r--r--src/openvpn/options.h3
-rw-r--r--src/openvpn/platform.c28
-rw-r--r--src/openvpn/plugin.c2
-rw-r--r--src/openvpn/plugin.h2
-rw-r--r--src/openvpn/proxy.c4
-rw-r--r--src/openvpn/route.c17
-rw-r--r--src/openvpn/route.h2
-rw-r--r--src/openvpn/ssl.c147
-rw-r--r--src/openvpn/ssl_backend.h9
-rw-r--r--src/openvpn/ssl_common.h3
-rw-r--r--src/openvpn/ssl_openssl.c77
-rw-r--r--src/openvpn/ssl_polarssl.c63
-rw-r--r--src/openvpn/ssl_polarssl.h1
-rw-r--r--src/openvpn/ssl_verify.c15
-rw-r--r--src/openvpn/ssl_verify.h6
-rw-r--r--src/openvpn/ssl_verify_polarssl.c27
-rw-r--r--src/openvpn/ssl_verify_polarssl.h22
-rw-r--r--src/openvpn/status.c2
-rw-r--r--src/openvpn/syshead.h11
-rw-r--r--src/openvpn/tun.c12
-rw-r--r--src/openvpn/tun.h2
33 files changed, 612 insertions, 197 deletions
diff --git a/src/openvpn/Makefile.in b/src/openvpn/Makefile.in
index d5f21c4..fbc2c39 100644
--- a/src/openvpn/Makefile.in
+++ b/src/openvpn/Makefile.in
@@ -1,9 +1,9 @@
-# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# Makefile.in generated by automake 1.11.6 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
-# Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+# Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
@@ -38,6 +38,23 @@
# Required to build Windows resource file
VPATH = @srcdir@
+am__make_dryrun = \
+ { \
+ am__dry=no; \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \
+ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
+ *) \
+ for am__flg in $$MAKEFLAGS; do \
+ case $$am__flg in \
+ *=*|--*) ;; \
+ *n*) am__dry=yes; break;; \
+ esac; \
+ done;; \
+ esac; \
+ test $$am__dry = yes; \
+ }
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
@@ -153,6 +170,11 @@ LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
$(LDFLAGS) -o $@
SOURCES = $(openvpn_SOURCES)
DIST_SOURCES = $(am__openvpn_SOURCES_DIST)
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
@@ -205,6 +227,7 @@ LZO_CFLAGS = @LZO_CFLAGS@
LZO_LIBS = @LZO_LIBS@
MAKEINFO = @MAKEINFO@
MAN2HTML = @MAN2HTML@
+MANIFEST_TOOL = @MANIFEST_TOOL@
MKDIR_P = @MKDIR_P@
NETSTAT = @NETSTAT@
NM = @NM@
@@ -260,6 +283,7 @@ abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
@@ -383,6 +407,7 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
+$(top_srcdir)/build/ltrc.inc:
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
@@ -394,8 +419,11 @@ $(ACLOCAL_M4): $(am__aclocal_m4_deps)
$(am__aclocal_m4_deps):
install-sbinPROGRAMS: $(sbin_PROGRAMS)
@$(NORMAL_INSTALL)
- test -z "$(sbindir)" || $(MKDIR_P) "$(DESTDIR)$(sbindir)"
@list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(sbindir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(sbindir)" || exit 1; \
+ fi; \
for p in $$list; do echo "$$p $$p"; done | \
sed 's/$(EXEEXT)$$//' | \
while read p p1; do if test -f $$p || test -f $$p1; \
@@ -435,7 +463,7 @@ clean-sbinPROGRAMS:
list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
echo " rm -f" $$list; \
rm -f $$list
-openvpn$(EXEEXT): $(openvpn_OBJECTS) $(openvpn_DEPENDENCIES)
+openvpn$(EXEEXT): $(openvpn_OBJECTS) $(openvpn_DEPENDENCIES) $(EXTRA_openvpn_DEPENDENCIES)
@rm -f openvpn$(EXEEXT)
$(LINK) $(openvpn_OBJECTS) $(openvpn_LDADD) $(LIBS)
@@ -640,10 +668,15 @@ install-am: all-am
installcheck: installcheck-am
install-strip:
- $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
- install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
- `test -z '$(STRIP)' || \
- echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
mostlyclean-generic:
clean-generic:
diff --git a/src/openvpn/buffer.h b/src/openvpn/buffer.h
index 5e11de0..93efb09 100644
--- a/src/openvpn/buffer.h
+++ b/src/openvpn/buffer.h
@@ -668,6 +668,10 @@ buf_read_u32 (struct buffer *buf, bool *good)
}
}
+/**
+ * Compare src buffer contents with match.
+ * *NOT* constant time. Do not use when comparing HMACs.
+ */
static inline bool
buf_string_match (const struct buffer *src, const void *match, int size)
{
@@ -676,6 +680,10 @@ buf_string_match (const struct buffer *src, const void *match, int size)
return memcmp (BPTR (src), match, size) == 0;
}
+/**
+ * Compare first size bytes of src buffer contents with match.
+ * *NOT* constant time. Do not use when comparing HMACs.
+ */
static inline bool
buf_string_match_head (const struct buffer *src, const void *match, int size)
{
@@ -689,16 +697,6 @@ bool buf_string_compare_advance (struct buffer *src, const char *match);
int buf_substring_len (const struct buffer *buf, int delim);
/*
- * Bitwise operations
- */
-static inline void
-xor (uint8_t *dest, const uint8_t *src, int len)
-{
- while (len-- > 0)
- *dest++ ^= *src++;
-}
-
-/*
* Print a string which might be NULL
*/
const char *np (const char *str);
diff --git a/src/openvpn/crypto.c b/src/openvpn/crypto.c
index ac2eecd..d9adf5b 100644
--- a/src/openvpn/crypto.c
+++ b/src/openvpn/crypto.c
@@ -65,6 +65,24 @@
#define CRYPT_ERROR(format) \
do { msg (D_CRYPT_ERRORS, "%s: " format, error_prefix); goto error_exit; } while (false)
+/**
+ * As memcmp(), but constant-time.
+ * Returns 0 when data is equal, non-zero otherwise.
+ */
+static int
+memcmp_constant_time (const void *a, const void *b, size_t size) {
+ const uint8_t * a1 = a;
+ const uint8_t * b1 = b;
+ int ret = 0;
+ size_t i;
+
+ for (i = 0; i < size; i++) {
+ ret |= *a1++ ^ *b1++;
+ }
+
+ return ret;
+}
+
void
openvpn_encrypt (struct buffer *buf, struct buffer work,
const struct crypto_options *opt,
@@ -244,7 +262,7 @@ openvpn_decrypt (struct buffer *buf, struct buffer work,
hmac_ctx_final (ctx->hmac, local_hmac);
/* Compare locally computed HMAC with packet HMAC */
- if (memcmp (local_hmac, BPTR (buf), hmac_len))
+ if (memcmp_constant_time (local_hmac, BPTR (buf), hmac_len))
CRYPT_ERROR ("packet HMAC authentication failed");
ASSERT (buf_advance (buf, hmac_len));
@@ -401,7 +419,7 @@ init_key_type (struct key_type *kt, const char *ciphername,
CLEAR (*kt);
if (ciphername && ciphername_defined)
{
- kt->cipher = cipher_kt_get (ciphername);
+ kt->cipher = cipher_kt_get (translate_cipher_name_from_openvpn(ciphername));
kt->cipher_length = cipher_kt_key_size (kt->cipher);
if (keysize > 0 && keysize <= MAX_CIPHER_KEY_LENGTH)
kt->cipher_length = keysize;
diff --git a/src/openvpn/crypto_backend.h b/src/openvpn/crypto_backend.h
index 1eac611..5ae47e6 100644
--- a/src/openvpn/crypto_backend.h
+++ b/src/openvpn/crypto_backend.h
@@ -63,6 +63,18 @@ void crypto_init_lib_engine (const char *engine_name);
void crypto_init_dmalloc (void);
#endif /* DMALLOC */
+/**
+ * Translate a data channel cipher name from the OpenVPN config file
+ * 'language' to the crypto library specific name.
+ */
+const char * translate_cipher_name_from_openvpn (const char *cipher_name);
+
+/**
+ * Translate a data channel cipher name from the crypto library specific name
+ * to the OpenVPN config file 'language'.
+ */
+const char * translate_cipher_name_from_openvpn (const char *cipher_name);
+
void show_available_ciphers (void);
void show_available_digests (void);
diff --git a/src/openvpn/crypto_openssl.c b/src/openvpn/crypto_openssl.c
index 5342502..21d1762 100644
--- a/src/openvpn/crypto_openssl.c
+++ b/src/openvpn/crypto_openssl.c
@@ -281,6 +281,18 @@ crypto_init_dmalloc (void)
}
#endif /* DMALLOC */
+const char *
+translate_cipher_name_from_openvpn (const char *cipher_name) {
+ // OpenSSL doesn't require any translation
+ return cipher_name;
+}
+
+const char *
+translate_cipher_name_to_openvpn (const char *cipher_name) {
+ // OpenSSL doesn't require any translation
+ return cipher_name;
+}
+
void
show_available_ciphers ()
{
diff --git a/src/openvpn/crypto_polarssl.c b/src/openvpn/crypto_polarssl.c
index 3978a3c..1f27d6c 100644
--- a/src/openvpn/crypto_polarssl.c
+++ b/src/openvpn/crypto_polarssl.c
@@ -94,6 +94,53 @@ crypto_init_dmalloc (void)
}
#endif /* DMALLOC */
+typedef struct { const char * openvpn_name; const char * polarssl_name; } cipher_name_pair;
+cipher_name_pair cipher_name_translation_table[] = {
+ { "BF-CBC", "BLOWFISH-CBC" },
+ { "BF-CFB", "BLOWFISH-CFB64" },
+ { "CAMELLIA-128-CFB", "CAMELLIA-128-CFB128" },
+ { "CAMELLIA-192-CFB", "CAMELLIA-192-CFB128" },
+ { "CAMELLIA-256-CFB", "CAMELLIA-256-CFB128" }
+};
+
+const cipher_name_pair *
+get_cipher_name_pair(const char *cipher_name) {
+ cipher_name_pair *pair;
+ size_t i = 0;
+
+ /* Search for a cipher name translation */
+ for (; i < sizeof (cipher_name_translation_table) / sizeof (*cipher_name_translation_table); i++)
+ {
+ pair = &cipher_name_translation_table[i];
+ if (0 == strcmp (cipher_name, pair->openvpn_name) ||
+ 0 == strcmp (cipher_name, pair->polarssl_name))
+ return pair;
+ }
+
+ /* Nothing found, return null */
+ return NULL;
+}
+
+const char *
+translate_cipher_name_from_openvpn (const char *cipher_name) {
+ const cipher_name_pair *pair = get_cipher_name_pair(cipher_name);
+
+ if (NULL == pair)
+ return cipher_name;
+
+ return pair->polarssl_name;
+}
+
+const char *
+translate_cipher_name_to_openvpn (const char *cipher_name) {
+ const cipher_name_pair *pair = get_cipher_name_pair(cipher_name);
+
+ if (NULL == pair)
+ return cipher_name;
+
+ return pair->openvpn_name;
+}
+
void
show_available_ciphers ()
{
@@ -114,7 +161,7 @@ show_available_ciphers ()
if (info && info->mode == POLARSSL_MODE_CBC)
printf ("%s %d bit default key\n",
- info->name, info->key_length);
+ cipher_kt_name(info), cipher_kt_key_size(info) * 8);
ciphers++;
}
@@ -331,7 +378,8 @@ cipher_kt_name (const cipher_info_t *cipher_kt)
{
if (NULL == cipher_kt)
return "[null-cipher]";
- return cipher_kt->name;
+
+ return translate_cipher_name_to_openvpn(cipher_kt->name);
}
int
@@ -339,6 +387,9 @@ cipher_kt_key_size (const cipher_info_t *cipher_kt)
{
if (NULL == cipher_kt)
return 0;
+ if (POLARSSL_CIPHER_ID_BLOWFISH == cipher_kt->base->cipher)
+ return 128/8; /* Override PolarSSL 32 bit default key size with sane 128 bit default */
+
return cipher_kt->key_length/8;
}
diff --git a/src/openvpn/crypto_polarssl.h b/src/openvpn/crypto_polarssl.h
index bfabb91..b6da436 100644
--- a/src/openvpn/crypto_polarssl.h
+++ b/src/openvpn/crypto_polarssl.h
@@ -30,7 +30,6 @@
#ifndef CRYPTO_POLARSSL_H_
#define CRYPTO_POLARSSL_H_
-#include <polarssl/version.h>
#include <polarssl/cipher.h>
#include <polarssl/md.h>
#include <polarssl/ctr_drbg.h>
@@ -60,7 +59,7 @@ typedef md_context_t hmac_ctx_t;
#define OPENVPN_MODE_OFB POLARSSL_MODE_OFB
/** Cipher is in CFB mode */
-#define OPENVPN_MODE_CFB POLARSSL_MODE_CFB128
+#define OPENVPN_MODE_CFB POLARSSL_MODE_CFB
/** Cipher should encrypt */
#define OPENVPN_OP_ENCRYPT POLARSSL_ENCRYPT
diff --git a/src/openvpn/event.c b/src/openvpn/event.c
index 2a13e1c..34a3c45 100644
--- a/src/openvpn/event.c
+++ b/src/openvpn/event.c
@@ -34,6 +34,7 @@
#include "error.h"
#include "integer.h"
#include "event.h"
+#include "fdmisc.h"
#include "memdbg.h"
@@ -582,6 +583,8 @@ ep_init (int *maxevents, unsigned int flags)
if (fd < 0)
return NULL;
+ set_cloexec (fd);
+
ALLOC_OBJ_CLEAR (eps, struct ep_set);
/* set dispatch functions */
diff --git a/src/openvpn/init.c b/src/openvpn/init.c
index 25d8225..979ba23 100644
--- a/src/openvpn/init.c
+++ b/src/openvpn/init.c
@@ -2205,7 +2205,8 @@ do_init_crypto_tls (struct context *c, const unsigned int flags)
to.verify_command = options->tls_verify;
to.verify_export_cert = options->tls_export_cert;
- to.verify_x509name = options->tls_remote;
+ to.verify_x509_type = (options->verify_x509_type & 0xff);
+ to.verify_x509_name = options->verify_x509_name;
to.crl_file = options->crl_file;
to.ssl_flags = options->ssl_flags;
to.ns_cert_type = options->ns_cert_type;
@@ -2467,12 +2468,10 @@ do_option_warnings (struct context *c)
warn_on_use_of_common_subnets ();
if (o->tls_client
&& !o->tls_verify
- && !o->tls_remote
+ && o->verify_x509_type == VERIFY_X509_NONE
&& !(o->ns_cert_type & NS_CERT_CHECK_SERVER)
&& !o->remote_cert_eku)
msg (M_WARN, "WARNING: No server certificate verification method has been enabled. See http://openvpn.net/howto.html#mitm for more info.");
- if (o->tls_remote)
- msg (M_WARN, "WARNING: Make sure you understand the semantics of --tls-remote before using it (see the man page).");
#endif
#endif
diff --git a/src/openvpn/mbuf.h b/src/openvpn/mbuf.h
index a0de679..1085adc 100644
--- a/src/openvpn/mbuf.h
+++ b/src/openvpn/mbuf.h
@@ -83,7 +83,7 @@ mbuf_defined (const struct mbuf_set *ms)
return ms && ms->len;
}
-static inline bool
+static inline unsigned int
mbuf_len (const struct mbuf_set *ms)
{
return ms->len;
diff --git a/src/openvpn/misc.c b/src/openvpn/misc.c
index fcc8552..fa327f8 100644
--- a/src/openvpn/misc.c
+++ b/src/openvpn/misc.c
@@ -707,13 +707,6 @@ env_set_remove_from_environment (const struct env_set *es)
static struct env_item *global_env = NULL; /* GLOBAL */
-void
-manage_env (char *str)
-{
- remove_env_item (str, true, &global_env);
- add_env_item (str, false, &global_env, NULL);
-}
-
#endif
/* add/modify/delete environmental strings */
@@ -789,27 +782,18 @@ setenv_str_ex (struct env_set *es,
if (value)
val_tmp = string_mod_const (value, value_include, value_exclude, value_replace, &gc);
- if (es)
+ ASSERT (es);
+
+ if (val_tmp)
{
- if (val_tmp)
- {
- const char *str = construct_name_value (name_tmp, val_tmp, &gc);
- env_set_add (es, str);
+ const char *str = construct_name_value (name_tmp, val_tmp, &gc);
+ env_set_add (es, str);
#if DEBUG_VERBOSE_SETENV
- msg (M_INFO, "SETENV_ES '%s'", str);
+ msg (M_INFO, "SETENV_ES '%s'", str);
#endif
- }
- else
- env_set_del (es, name_tmp);
}
else
- {
- char *str = construct_name_value (name_tmp, val_tmp, NULL);
- if (platform_putenv(str))
- {
- msg (M_WARN | M_ERRNO, "putenv('%s') failed", str);
- }
- }
+ env_set_del (es, name_tmp);
gc_free (&gc);
}
diff --git a/src/openvpn/options.c b/src/openvpn/options.c
index 8ca41a3..ec39212 100644
--- a/src/openvpn/options.c
+++ b/src/openvpn/options.c
@@ -614,8 +614,8 @@ static const char usage_message[] =
"--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"
+ "--verify-x509-name name: Accept connections only from a host with X509 subject\n"
+ " DN name. The remote host must also pass all other tests\n"
" of verification.\n"
"--ns-cert-type t: Require that peer certificate was signed with an explicit\n"
" nsCertType designation t = 'client' | 'server'.\n"
@@ -881,7 +881,7 @@ uninit_options (struct options *o)
}
}
-#ifdef ENABLE_DEBUG
+#ifndef ENABLE_SMALL
#define SHOW_PARM(name, value, format) msg(D_SHOW_PARMS, " " #name " = " format, (value))
#define SHOW_STR(var) SHOW_PARM(var, (o->var ? o->var : "[UNDEF]"), "'%s'")
@@ -1081,7 +1081,7 @@ parse_hash_fingerprint(const char *str, int nbytes, int msglevel, struct gc_aren
#ifdef WIN32
-#ifdef ENABLE_DEBUG
+#ifndef ENABLE_SMALL
static void
show_dhcp_option_addrs (const char *name, const in_addr_t *array, int len)
@@ -1153,7 +1153,7 @@ dhcp_option_address_parse (const char *name, const char *parm, in_addr_t *array,
#if P2MP
-#ifdef ENABLE_DEBUG
+#ifndef ENABLE_SMALL
static void
show_p2mp_parms (const struct options *o)
@@ -1225,7 +1225,7 @@ show_p2mp_parms (const struct options *o)
gc_free (&gc);
}
-#endif /* ENABLE_DEBUG */
+#endif /* ! ENABLE_SMALL */
#if P2MP_SERVER
@@ -1279,7 +1279,7 @@ option_iroute_ipv6 (struct options *o,
#endif /* P2MP_SERVER */
#endif /* P2MP */
-#if defined(ENABLE_HTTP_PROXY) && defined(ENABLE_DEBUG)
+#if defined(ENABLE_HTTP_PROXY) && !defined(ENABLE_SMALL)
static void
show_http_proxy_options (const struct http_proxy_options *o)
{
@@ -1332,7 +1332,7 @@ cnol_check_alloc (struct options *options)
}
#endif
-#ifdef ENABLE_DEBUG
+#ifndef ENABLE_SMALL
static void
show_connection_entry (const struct connection_entry *o)
{
@@ -1400,7 +1400,7 @@ show_connection_entries (const struct options *o)
void
show_settings (const struct options *o)
{
-#ifdef ENABLE_DEBUG
+#ifndef ENABLE_SMALL
msg (D_SHOW_PARMS, "Current Parameter Settings:");
SHOW_STR (config);
@@ -1596,7 +1596,8 @@ show_settings (const struct options *o)
SHOW_STR (cipher_list);
SHOW_STR (tls_verify);
SHOW_STR (tls_export_cert);
- SHOW_STR (tls_remote);
+ SHOW_INT (verify_x509_type);
+ SHOW_STR (verify_x509_name);
SHOW_STR (crl_file);
SHOW_INT (ns_cert_type);
{
@@ -2130,7 +2131,6 @@ options_postprocess_verify_ce (const struct options *options, const struct conne
if (options->stale_routes_check_interval)
msg (M_USAGE, "--stale-routes-check requires --mode server");
-
if (compat_flag (COMPAT_FLAG_QUERY | COMPAT_NO_NAME_REMAPPING))
msg (M_USAGE, "--compat-x509-names no-remapping requires --mode server");
}
@@ -2302,7 +2302,7 @@ options_postprocess_verify_ce (const struct options *options, const struct conne
MUST_BE_UNDEF (cipher_list);
MUST_BE_UNDEF (tls_verify);
MUST_BE_UNDEF (tls_export_cert);
- MUST_BE_UNDEF (tls_remote);
+ MUST_BE_UNDEF (verify_x509_name);
MUST_BE_UNDEF (tls_timeout);
MUST_BE_UNDEF (renegotiate_bytes);
MUST_BE_UNDEF (renegotiate_packets);
@@ -3771,9 +3771,13 @@ read_config_file (struct options *options,
line_num = 0;
while (fgets(line, sizeof (line), fp))
{
+ int offset = 0;
CLEAR (p);
++line_num;
- if (parse_line (line, p, SIZE (p), file, line_num, msglevel, &options->gc))
+ /* Ignore UTF-8 BOM at start of stream */
+ if (line_num == 1 && strncmp (line, "\xEF\xBB\xBF", 3) == 0)
+ offset = 3;
+ if (parse_line (line + offset, p, SIZE (p), file, line_num, msglevel, &options->gc))
{
bypass_doubledash (&p[0]);
check_inline_file_via_fp (fp, p, &options->gc);
@@ -4668,6 +4672,12 @@ add_option (struct options *options,
{
VERIFY_PERMISSION (OPT_P_MESSAGES);
options->verbosity = positive_atoi (p[1]);
+#if !defined(ENABLE_DEBUG) && !defined(ENABLE_SMALL)
+ /* Warn when a debug verbosity is supplied when built without debug support */
+ if (options->verbosity >= 7)
+ msg (M_WARN, "NOTE: debug verbosity (--verb %d) is enabled but this build lacks debug support.",
+ options->verbosity);
+#endif
}
else if (streq (p[0], "mute") && p[1])
{
@@ -5484,9 +5494,9 @@ add_option (struct options *options,
msg (msglevel, "error parsing --ifconfig-ipv6-pool parameters");
goto err;
}
- if ( netbits != 64 )
+ if ( netbits < 64 || netbits > 112 )
{
- msg( msglevel, "--ifconfig-ipv6-pool settings: only /64 supported right now (not /%d)", netbits );
+ msg( msglevel, "--ifconfig-ipv6-pool settings: only /64../112 supported right now (not /%d)", netbits );
goto err;
}
@@ -5557,13 +5567,6 @@ add_option (struct options *options,
VERIFY_PERMISSION (OPT_P_GENERAL);
options->ssl_flags |= SSLF_AUTH_USER_PASS_OPTIONAL;
}
- else if (streq (p[0], "compat-names"))
- {
- VERIFY_PERMISSION (OPT_P_GENERAL);
- compat_flag (COMPAT_FLAG_SET | COMPAT_NAMES);
- if (p[1] && streq (p[1], "no-remapping"))
- compat_flag (COMPAT_FLAG_SET | COMPAT_NO_NAME_REMAPPING);
- }
else if (streq (p[0], "opt-verify"))
{
VERIFY_PERMISSION (OPT_P_GENERAL);
@@ -6514,10 +6517,100 @@ add_option (struct options *options,
options->tls_export_cert = p[1];
}
#endif
+ else if (streq (p[0], "compat-names"))
+ {
+ VERIFY_PERMISSION (OPT_P_GENERAL);
+ if (options->verify_x509_type != VERIFY_X509_NONE &&
+ options->verify_x509_type != TLS_REMOTE_SUBJECT_DN &&
+ options->verify_x509_type != TLS_REMOTE_SUBJECT_RDN_PREFIX)
+ {
+ msg (msglevel, "you cannot use --compat-names with --verify-x509-name");
+ goto err;
+ }
+ msg (M_WARN, "DEPRECATED OPTION: --compat-names, please update your configuration");
+ compat_flag (COMPAT_FLAG_SET | COMPAT_NAMES);
+#if P2MP_SERVER
+ if (p[1] && streq (p[1], "no-remapping"))
+ compat_flag (COMPAT_FLAG_SET | COMPAT_NO_NAME_REMAPPING);
+ }
+ else if (streq (p[0], "no-name-remapping"))
+ {
+ VERIFY_PERMISSION (OPT_P_GENERAL);
+ if (options->verify_x509_type != VERIFY_X509_NONE &&
+ options->verify_x509_type != TLS_REMOTE_SUBJECT_DN &&
+ options->verify_x509_type != TLS_REMOTE_SUBJECT_RDN_PREFIX)
+ {
+ msg (msglevel, "you cannot use --no-name-remapping with --verify-x509-name");
+ goto err;
+ }
+ msg (M_WARN, "DEPRECATED OPTION: --no-name-remapping, please update your configuration");
+ compat_flag (COMPAT_FLAG_SET | COMPAT_NAMES);
+ compat_flag (COMPAT_FLAG_SET | COMPAT_NO_NAME_REMAPPING);
+#endif
+ }
else if (streq (p[0], "tls-remote") && p[1])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
- options->tls_remote = p[1];
+
+ if (options->verify_x509_type != VERIFY_X509_NONE &&
+ options->verify_x509_type != TLS_REMOTE_SUBJECT_DN &&
+ options->verify_x509_type != TLS_REMOTE_SUBJECT_RDN_PREFIX)
+ {
+ msg (msglevel, "you cannot use --tls-remote with --verify-x509-name");
+ goto err;
+ }
+ msg (M_WARN, "DEPRECATED OPTION: --tls-remote, please update your configuration");
+
+ if (strlen (p[1]))
+ {
+ int is_username = (!strchr (p[1], '=') || !strstr (p[1], ", "));
+ int type = TLS_REMOTE_SUBJECT_DN;
+ if (p[1][0] != '/' && is_username)
+ type = TLS_REMOTE_SUBJECT_RDN_PREFIX;
+
+ /*
+ * Enable legacy openvpn format for DNs that have not been converted
+ * yet and --x509-username-field (not containing an '=' or ', ')
+ */
+ if (p[1][0] == '/' || is_username)
+ compat_flag (COMPAT_FLAG_SET | COMPAT_NAMES);
+
+ options->verify_x509_type = type;
+ options->verify_x509_name = p[1];
+ }
+ }
+ else if (streq (p[0], "verify-x509-name") && p[1] && strlen (p[1]))
+ {
+ int type = VERIFY_X509_SUBJECT_DN;
+ VERIFY_PERMISSION (OPT_P_GENERAL);
+ if (options->verify_x509_type == TLS_REMOTE_SUBJECT_DN ||
+ options->verify_x509_type == TLS_REMOTE_SUBJECT_RDN_PREFIX)
+ {
+ msg (msglevel, "you cannot use --verify-x509-name with --tls-remote");
+ goto err;
+ }
+ if (compat_flag (COMPAT_FLAG_QUERY | COMPAT_NAMES))
+ {
+ msg (msglevel, "you cannot use --verify-x509-name with "
+ "--compat-names or --no-name-remapping");
+ goto err;
+ }
+ if (p[2])
+ {
+ if (streq (p[2], "subject"))
+ type = VERIFY_X509_SUBJECT_DN;
+ else if (streq (p[2], "name"))
+ type = VERIFY_X509_SUBJECT_RDN;
+ else if (streq (p[2], "name-prefix"))
+ type = VERIFY_X509_SUBJECT_RDN_PREFIX;
+ else
+ {
+ msg (msglevel, "unknown X.509 name type: %s", p[2]);
+ goto err;
+ }
+ }
+ options->verify_x509_type = type;
+ options->verify_x509_name = p[1];
}
else if (streq (p[0], "ns-cert-type") && p[1])
{
diff --git a/src/openvpn/options.h b/src/openvpn/options.h
index 306520b..d2ad94c 100644
--- a/src/openvpn/options.h
+++ b/src/openvpn/options.h
@@ -506,8 +506,9 @@ struct options
const char *pkcs12_file;
const char *cipher_list;
const char *tls_verify;
+ int verify_x509_type;
+ const char *verify_x509_name;
const char *tls_export_cert;
- const char *tls_remote;
const char *crl_file;
const char *ca_file_inline;
diff --git a/src/openvpn/platform.c b/src/openvpn/platform.c
index e79de7a..16d4dac 100644
--- a/src/openvpn/platform.c
+++ b/src/openvpn/platform.c
@@ -275,34 +275,6 @@ platform_unlink (const char *filename)
#endif
}
-int platform_putenv(char *string)
-{
- int status;
-#if defined(WIN32)
- struct gc_arena gc = gc_new ();
- char *s = string_alloc(string, &gc);
- char *value = strchr(s, '=');
- if (value!=NULL)
- {
- *value = '\0';
- value++;
- if (*value == '\0')
- value = NULL;
- }
-
- status = SetEnvironmentVariableW (wide_string (s, &gc),
- wide_string (value, &gc)) ? 1: 0;
- gc_free (&gc);
-#elif defined(HAVE_PUTENV)
- void manage_env (char *str); /* TODO: Resolve properly */
- status = putenv (string);
- if (!status)
- manage_env (string);
-#endif
-
- return status;
-}
-
FILE *
platform_fopen (const char *path, const char *mode)
{
diff --git a/src/openvpn/plugin.c b/src/openvpn/plugin.c
index 83f79e4..c96c121 100644
--- a/src/openvpn/plugin.c
+++ b/src/openvpn/plugin.c
@@ -155,7 +155,7 @@ plugin_option_list_add (struct plugin_option_list *list, char **p, struct gc_are
return false;
}
-#ifdef ENABLE_DEBUG
+#ifndef ENABLE_SMALL
void
plugin_option_list_print (const struct plugin_option_list *list, int msglevel)
{
diff --git a/src/openvpn/plugin.h b/src/openvpn/plugin.h
index 4ba150d..2f8416b 100644
--- a/src/openvpn/plugin.h
+++ b/src/openvpn/plugin.h
@@ -108,7 +108,7 @@ struct plugin_return
struct plugin_option_list *plugin_option_list_new (struct gc_arena *gc);
bool plugin_option_list_add (struct plugin_option_list *list, char **p, struct gc_arena *gc);
-#ifdef ENABLE_DEBUG
+#ifndef ENABLE_SMALL
void plugin_option_list_print (const struct plugin_option_list *list, int msglevel);
#endif
diff --git a/src/openvpn/proxy.c b/src/openvpn/proxy.c
index 363d8a7..95d7153 100644
--- a/src/openvpn/proxy.c
+++ b/src/openvpn/proxy.c
@@ -499,7 +499,7 @@ establish_http_proxy_passthru (struct http_proxy_info *p,
{
struct gc_arena gc = gc_new ();
char buf[512];
- char buf2[128];
+ char buf2[129];
char get[80];
int status;
int nparms;
@@ -622,7 +622,7 @@ establish_http_proxy_passthru (struct http_proxy_info *p,
openvpn_snprintf (get, sizeof get, "%%*s NTLM %%%ds", (int) sizeof (buf2) - 1);
nparms = sscanf (buf, get, buf2);
- buf2[127] = 0; /* we only need the beginning - ensure it's null terminated. */
+ buf2[128] = 0; /* we only need the beginning - ensure it's null terminated. */
/* check for "Proxy-Authenticate: NTLM TlRM..." */
if (nparms == 1)
diff --git a/src/openvpn/route.c b/src/openvpn/route.c
index dd69d8e..4c1e14e 100644
--- a/src/openvpn/route.c
+++ b/src/openvpn/route.c
@@ -1089,7 +1089,7 @@ delete_routes (struct route_list *rl, struct route_ipv6_list *rl6,
}
}
-#ifdef ENABLE_DEBUG
+#ifndef ENABLE_SMALL
static const char *
show_opt (const char *option)
@@ -1397,17 +1397,20 @@ add_route (struct route *r,
argv_printf (&argv, "%s add",
ROUTE_PATH);
-#if 0
- if (r->flags & RT_METRIC_DEFINED)
- argv_printf_cat (&argv, "-rtt %d", r->metric);
-#endif
-
argv_printf_cat (&argv, "%s -netmask %s %s",
network,
netmask,
gateway);
- /* FIXME -- add on-link support for Solaris */
+ /* Solaris can only distinguish between "metric 0" == "on-link on the
+ * interface where the IP address given is configured" and "metric > 0"
+ * == "use gateway specified" (no finer-grained route metrics available)
+ *
+ * More recent versions of Solaris can also do "-interface", but that
+ * would break backwards compatibility with older versions for no gain.
+ */
+ if (r->flags & RT_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/src/openvpn/route.h b/src/openvpn/route.h
index e63db59..a40de32 100644
--- a/src/openvpn/route.h
+++ b/src/openvpn/route.h
@@ -290,7 +290,7 @@ void print_default_gateway(const int msglevel, const struct route_gateway_info *
#define TLA_LOCAL 2
int test_local_addr (const in_addr_t addr, const struct route_gateway_info *rgi);
-#ifdef ENABLE_DEBUG
+#ifndef ENABLE_SMALL
void print_route_options (const struct route_option_list *rol,
int level);
#endif
diff --git a/src/openvpn/ssl.c b/src/openvpn/ssl.c
index 19512c0..43b3980 100644
--- a/src/openvpn/ssl.c
+++ b/src/openvpn/ssl.c
@@ -113,6 +113,153 @@ show_tls_performance_stats(void)
#endif
+/**
+ * SSL/TLS Cipher suite name translation table
+ */
+static const tls_cipher_name_pair tls_cipher_name_translation_table[] = {
+ {"ADH-SEED-SHA", "TLS-DH-anon-WITH-SEED-CBC-SHA"},
+ {"AES128-GCM-SHA256", "TLS-RSA-WITH-AES-128-GCM-SHA256"},
+ {"AES128-SHA256", "TLS-RSA-WITH-AES-128-CBC-SHA256"},
+ {"AES128-SHA", "TLS-RSA-WITH-AES-128-CBC-SHA"},
+ {"AES256-GCM-SHA384", "TLS-RSA-WITH-AES-256-GCM-SHA384"},
+ {"AES256-SHA256", "TLS-RSA-WITH-AES-256-CBC-SHA256"},
+ {"AES256-SHA", "TLS-RSA-WITH-AES-256-CBC-SHA"},
+ {"CAMELLIA128-SHA256", "TLS-RSA-WITH-CAMELLIA-128-CBC-SHA256"},
+ {"CAMELLIA128-SHA", "TLS-RSA-WITH-CAMELLIA-128-CBC-SHA"},
+ {"CAMELLIA256-SHA256", "TLS-RSA-WITH-CAMELLIA-256-CBC-SHA256"},
+ {"CAMELLIA256-SHA", "TLS-RSA-WITH-CAMELLIA-256-CBC-SHA"},
+ {"DES-CBC3-SHA", "TLS-RSA-WITH-3DES-EDE-CBC-SHA"},
+ {"DES-CBC-SHA", "TLS-RSA-WITH-DES-CBC-SHA"},
+ {"DH-DSS-SEED-SHA", "TLS-DH-DSS-WITH-SEED-CBC-SHA"},
+ {"DHE-DSS-AES128-GCM-SHA256", "TLS-DHE-DSS-WITH-AES-128-GCM-SHA256"},
+ {"DHE-DSS-AES128-SHA256", "TLS-DHE-DSS-WITH-AES-128-CBC-SHA256"},
+ {"DHE-DSS-AES128-SHA", "TLS-DHE-DSS-WITH-AES-128-CBC-SHA"},
+ {"DHE-DSS-AES256-GCM-SHA384", "TLS-DHE-DSS-WITH-AES-256-GCM-SHA384"},
+ {"DHE-DSS-AES256-SHA256", "TLS-DHE-DSS-WITH-AES-256-CBC-SHA256"},
+ {"DHE-DSS-AES256-SHA", "TLS-DHE-DSS-WITH-AES-256-CBC-SHA"},
+ {"DHE-DSS-CAMELLIA128-SHA256", "TLS-DHE-DSS-WITH-CAMELLIA-128-CBC-SHA256"},
+ {"DHE-DSS-CAMELLIA128-SHA", "TLS-DHE-DSS-WITH-CAMELLIA-128-CBC-SHA"},
+ {"DHE-DSS-CAMELLIA256-SHA256", "TLS-DHE-DSS-WITH-CAMELLIA-256-CBC-SHA256"},
+ {"DHE-DSS-CAMELLIA256-SHA", "TLS-DHE-DSS-WITH-CAMELLIA-256-CBC-SHA"},
+ {"DHE-DSS-DES-CBC3-SHA", "TLS-DHE-DSS-WITH-3DES-EDE-CBC-SHA"},
+ {"DHE-DSS-DES-CBC-SHA", "TLS-DHE-DSS-WITH-DES-CBC-SHA"},
+ {"DHE-DSS-SEED-SHA", "TLS-DHE-DSS-WITH-SEED-CBC-SHA"},
+ {"DHE-RSA-AES128-GCM-SHA256", "TLS-DHE-RSA-WITH-AES-128-GCM-SHA256"},
+ {"DHE-RSA-AES128-SHA256", "TLS-DHE-RSA-WITH-AES-128-CBC-SHA256"},
+ {"DHE-RSA-AES128-SHA", "TLS-DHE-RSA-WITH-AES-128-CBC-SHA"},
+ {"DHE-RSA-AES256-GCM-SHA384", "TLS-DHE-RSA-WITH-AES-256-GCM-SHA384"},
+ {"DHE-RSA-AES256-SHA256", "TLS-DHE-RSA-WITH-AES-256-CBC-SHA256"},
+ {"DHE-RSA-AES256-SHA", "TLS-DHE-RSA-WITH-AES-256-CBC-SHA"},
+ {"DHE-RSA-CAMELLIA128-SHA256", "TLS-DHE-RSA-WITH-CAMELLIA-128-CBC-SHA256"},
+ {"DHE-RSA-CAMELLIA128-SHA", "TLS-DHE-RSA-WITH-CAMELLIA-128-CBC-SHA"},
+ {"DHE-RSA-CAMELLIA256-SHA256", "TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA256"},
+ {"DHE-RSA-CAMELLIA256-SHA", "TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA"},
+ {"DHE-RSA-DES-CBC3-SHA", "TLS-DHE-RSA-WITH-3DES-EDE-CBC-SHA"},
+ {"DHE-RSA-DES-CBC-SHA", "TLS-DHE-RSA-WITH-DES-CBC-SHA"},
+ {"DHE-RSA-SEED-SHA", "TLS-DHE-RSA-WITH-SEED-CBC-SHA"},
+ {"DH-RSA-SEED-SHA", "TLS-DH-RSA-WITH-SEED-CBC-SHA"},
+ {"ECDH-ECDSA-AES128-GCM-SHA256", "TLS-ECDH-ECDSA-WITH-AES-128-GCM-SHA256"},
+ {"ECDH-ECDSA-AES128-SHA256", "TLS-ECDH-ECDSA-WITH-AES-128-CBC-SHA256"},
+ {"ECDH-ECDSA-AES128-SHA", "TLS-ECDH-ECDSA-WITH-AES-128-CBC-SHA"},
+ {"ECDH-ECDSA-AES256-GCM-SHA384", "TLS-ECDH-ECDSA-WITH-AES-256-GCM-SHA384"},
+ {"ECDH-ECDSA-AES256-SHA256", "TLS-ECDH-ECDSA-WITH-AES-256-CBC-SHA256"},
+ {"ECDH-ECDSA-AES256-SHA384", "TLS-ECDH-ECDSA-WITH-AES-256-CBC-SHA384"},
+ {"ECDH-ECDSA-AES256-SHA", "TLS-ECDH-ECDSA-WITH-AES-256-CBC-SHA"},
+ {"ECDH-ECDSA-CAMELLIA128-SHA256", "TLS-ECDH-ECDSA-WITH-CAMELLIA-128-CBC-SHA256"},
+ {"ECDH-ECDSA-CAMELLIA128-SHA", "TLS-ECDH-ECDSA-WITH-CAMELLIA-128-CBC-SHA"},
+ {"ECDH-ECDSA-CAMELLIA256-SHA256", "TLS-ECDH-ECDSA-WITH-CAMELLIA-256-CBC-SHA256"},
+ {"ECDH-ECDSA-CAMELLIA256-SHA", "TLS-ECDH-ECDSA-WITH-CAMELLIA-256-CBC-SHA"},
+ {"ECDH-ECDSA-DES-CBC3-SHA", "TLS-ECDH-ECDSA-WITH-3DES-EDE-CBC-SHA"},
+ {"ECDH-ECDSA-DES-CBC-SHA", "TLS-ECDH-ECDSA-WITH-DES-CBC-SHA"},
+ {"ECDH-ECDSA-RC4-SHA", "TLS-ECDH-ECDSA-WITH-RC4-128-SHA"},
+ {"ECDHE-ECDSA-AES128-GCM-SHA256", "TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256"},
+ {"ECDHE-ECDSA-AES128-SHA256", "TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA256"},
+ {"ECDHE-ECDSA-AES128-SHA384", "TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA384"},
+ {"ECDHE-ECDSA-AES128-SHA", "TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA"},
+ {"ECDHE-ECDSA-AES256-GCM-SHA384", "TLS-ECDHE-ECDSA-WITH-AES-256-GCM-SHA384"},
+ {"ECDHE-ECDSA-AES256-SHA256", "TLS-ECDHE-ECDSA-WITH-AES-256-CBC-SHA256"},
+ {"ECDHE-ECDSA-AES256-SHA384", "TLS-ECDHE-ECDSA-WITH-AES-256-CBC-SHA384"},
+ {"ECDHE-ECDSA-AES256-SHA", "TLS-ECDHE-ECDSA-WITH-AES-256-CBC-SHA"},
+ {"ECDHE-ECDSA-CAMELLIA128-SHA256", "TLS-ECDHE-ECDSA-WITH-CAMELLIA-128-CBC-SHA256"},
+ {"ECDHE-ECDSA-CAMELLIA128-SHA", "TLS-ECDHE-ECDSA-WITH-CAMELLIA-128-CBC-SHA"},
+ {"ECDHE-ECDSA-CAMELLIA256-SHA256", "TLS-ECDHE-ECDSA-WITH-CAMELLIA-256-CBC-SHA256"},
+ {"ECDHE-ECDSA-CAMELLIA256-SHA", "TLS-ECDHE-ECDSA-WITH-CAMELLIA-256-CBC-SHA"},
+ {"ECDHE-ECDSA-DES-CBC3-SHA", "TLS-ECDHE-ECDSA-WITH-3DES-EDE-CBC-SHA"},
+ {"ECDHE-ECDSA-DES-CBC-SHA", "TLS-ECDHE-ECDSA-WITH-DES-CBC-SHA"},
+ {"ECDHE-ECDSA-RC4-SHA", "TLS-ECDHE-ECDSA-WITH-RC4-128-SHA"},
+ {"ECDHE-RSA-AES128-GCM-SHA256", "TLS-ECDHE-RSA-WITH-AES-128-GCM-SHA256"},
+ {"ECDHE-RSA-AES128-SHA256", "TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA256"},
+ {"ECDHE-RSA-AES128-SHA384", "TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA384"},
+ {"ECDHE-RSA-AES128-SHA", "TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA"},
+ {"ECDHE-RSA-AES256-GCM-SHA384", "TLS-ECDHE-RSA-WITH-AES-256-GCM-SHA384"},
+ {"ECDHE-RSA-AES256-SHA256", "TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA256"},
+ {"ECDHE-RSA-AES256-SHA384", "TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA384"},
+ {"ECDHE-RSA-AES256-SHA", "TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA"},
+ {"ECDHE-RSA-CAMELLIA128-SHA256", "TLS-ECDHE-RSA-WITH-CAMELLIA-128-CBC-SHA256"},
+ {"ECDHE-RSA-CAMELLIA128-SHA", "TLS-ECDHE-RSA-WITH-CAMELLIA-128-CBC-SHA"},
+ {"ECDHE-RSA-CAMELLIA256-SHA256", "TLS-ECDHE-RSA-WITH-CAMELLIA-256-CBC-SHA256"},
+ {"ECDHE-RSA-CAMELLIA256-SHA", "TLS-ECDHE-RSA-WITH-CAMELLIA-256-CBC-SHA"},
+ {"ECDHE-RSA-DES-CBC3-SHA", "TLS-ECDHE-RSA-WITH-3DES-EDE-CBC-SHA"},
+ {"ECDHE-RSA-DES-CBC-SHA", "TLS-ECDHE-RSA-WITH-DES-CBC-SHA"},
+ {"ECDHE-RSA-RC4-SHA", "TLS-ECDHE-RSA-WITH-RC4-128-SHA"},
+ {"ECDH-RSA-AES128-GCM-SHA256", "TLS-ECDH-RSA-WITH-AES-128-GCM-SHA256"},
+ {"ECDH-RSA-AES128-SHA256", "TLS-ECDH-RSA-WITH-AES-128-CBC-SHA256"},
+ {"ECDH-RSA-AES128-SHA384", "TLS-ECDH-RSA-WITH-AES-128-CBC-SHA384"},
+ {"ECDH-RSA-AES128-SHA", "TLS-ECDH-RSA-WITH-AES-128-CBC-SHA"},
+ {"ECDH-RSA-AES256-GCM-SHA384", "TLS-ECDH-RSA-WITH-AES-256-GCM-SHA384"},
+ {"ECDH-RSA-AES256-SHA256", "TLS-ECDH-RSA-WITH-AES-256-CBC-SHA256"},
+ {"ECDH-RSA-AES256-SHA384", "TLS-ECDH-RSA-WITH-AES-256-CBC-SHA384"},
+ {"ECDH-RSA-AES256-SHA", "TLS-ECDH-RSA-WITH-AES-256-CBC-SHA"},
+ {"ECDH-RSA-CAMELLIA128-SHA256", "TLS-ECDH-RSA-WITH-CAMELLIA-128-CBC-SHA256"},
+ {"ECDH-RSA-CAMELLIA128-SHA", "TLS-ECDH-RSA-WITH-CAMELLIA-128-CBC-SHA"},
+ {"ECDH-RSA-CAMELLIA256-SHA256", "TLS-ECDH-RSA-WITH-CAMELLIA-256-CBC-SHA256"},
+ {"ECDH-RSA-CAMELLIA256-SHA", "TLS-ECDH-RSA-WITH-CAMELLIA-256-CBC-SHA"},
+ {"ECDH-RSA-DES-CBC3-SHA", "TLS-ECDH-RSA-WITH-3DES-EDE-CBC-SHA"},
+ {"ECDH-RSA-DES-CBC-SHA", "TLS-ECDH-RSA-WITH-DES-CBC-SHA"},
+ {"ECDH-RSA-RC4-SHA", "TLS-ECDH-RSA-WITH-RC4-128-SHA"},
+ {"EDH-DSS-DES-CBC3-SHA", "TLS-DHE-DSS-WITH-3DES-EDE-CBC-SHA"},
+ {"EDH-DSS-DES-CBC-SHA", "TLS-DHE-DSS-WITH-DES-CBC-SHA"},
+ {"EDH-RSA-DES-CBC3-SHA", "TLS-DHE-RSA-WITH-3DES-EDE-CBC-SHA"},
+ {"EDH-RSA-DES-CBC-SHA", "TLS-DHE-RSA-WITH-DES-CBC-SHA"},
+ {"EXP-DES-CBC-SHA", "TLS-RSA-EXPORT-WITH-DES40-CBC-SHA"},
+ {"EXP-EDH-DSS-DES-CBC-SHA", "TLS-DH-DSS-EXPORT-WITH-DES40-CBC-SHA"},
+ {"EXP-EDH-RSA-DES-CBC-SHA", "TLS-DH-RSA-EXPORT-WITH-DES40-CBC-SHA"},
+ {"EXP-RC2-CBC-MD5", "TLS-RSA-EXPORT-WITH-RC2-CBC-40-MD5"},
+ {"EXP-RC4-MD5", "TLS-RSA-EXPORT-WITH-RC4-40-MD5"},
+ {"NULL-MD5", "TLS-RSA-WITH-NULL-MD5"},
+ {"NULL-SHA256", "TLS-RSA-WITH-NULL-SHA256"},
+ {"NULL-SHA", "TLS-RSA-WITH-NULL-SHA"},
+ {"PSK-3DES-EDE-CBC-SHA", "TLS-PSK-WITH-3DES-EDE-CBC-SHA"},
+ {"PSK-AES128-CBC-SHA", "TLS-PSK-WITH-AES-128-CBC-SHA"},
+ {"PSK-AES256-CBC-SHA", "TLS-PSK-WITH-AES-256-CBC-SHA"},
+ {"PSK-RC4-SHA", "TLS-PSK-WITH-RC4-128-SHA"},
+ {"RC4-MD5", "TLS-RSA-WITH-RC4-128-MD5"},
+ {"RC4-SHA", "TLS-RSA-WITH-RC4-128-SHA"},
+ {"SEED-SHA", "TLS-RSA-WITH-SEED-CBC-SHA"},
+ {"SRP-DSS-3DES-EDE-CBC-SHA", "TLS-SRP-SHA-DSS-WITH-3DES-EDE-CBC-SHA"},
+ {"SRP-DSS-AES-128-CBC-SHA", "TLS-SRP-SHA-DSS-WITH-AES-128-CBC-SHA"},
+ {"SRP-DSS-AES-256-CBC-SHA", "TLS-SRP-SHA-DSS-WITH-AES-256-CBC-SHA"},
+ {"SRP-RSA-3DES-EDE-CBC-SHA", "TLS-SRP-SHA-RSA-WITH-3DES-EDE-CBC-SHA"},
+ {"SRP-RSA-AES-128-CBC-SHA", "TLS-SRP-SHA-RSA-WITH-AES-128-CBC-SHA"},
+ {"SRP-RSA-AES-256-CBC-SHA", "TLS-SRP-SHA-RSA-WITH-AES-256-CBC-SHA"},
+ {NULL, NULL}
+};
+
+const tls_cipher_name_pair *
+tls_get_cipher_name_pair (const char * cipher_name, size_t len) {
+ const tls_cipher_name_pair * pair = tls_cipher_name_translation_table;
+
+ while (pair->openssl_name != NULL) {
+ if ((strlen(pair->openssl_name) == len && 0 == memcmp (cipher_name, pair->openssl_name, len)) ||
+ (strlen(pair->iana_name) == len && 0 == memcmp (cipher_name, pair->iana_name, len))) {
+ return pair;
+ }
+ pair++;
+ }
+
+ // No entry found, return NULL
+ return NULL;
+}
/*
* Max number of bytes we will add
diff --git a/src/openvpn/ssl_backend.h b/src/openvpn/ssl_backend.h
index 203a4d2..f61580c 100644
--- a/src/openvpn/ssl_backend.h
+++ b/src/openvpn/ssl_backend.h
@@ -43,6 +43,15 @@
#endif
+/**
+ * Get a tls_cipher_name_pair containing OpenSSL and IANA names for supplied TLS cipher name
+ *
+ * @param cipher_name Can be either OpenSSL or IANA cipher name
+ * @return tls_cipher_name_pair* if found, NULL otherwise
+ */
+typedef struct { const char *openssl_name; const char *iana_name; } tls_cipher_name_pair;
+const tls_cipher_name_pair *tls_get_cipher_name_pair (const char *cipher_name, size_t len);
+
/*
*
* Functions implemented in ssl.c for use by the backend SSL library
diff --git a/src/openvpn/ssl_common.h b/src/openvpn/ssl_common.h
index cb259a9..c62294f 100644
--- a/src/openvpn/ssl_common.h
+++ b/src/openvpn/ssl_common.h
@@ -245,7 +245,8 @@ struct tls_options
/* cert verification parms */
const char *verify_command;
const char *verify_export_cert;
- const char *verify_x509name;
+ int verify_x509_type;
+ const char *verify_x509_name;
const char *crl_file;
int ns_cert_type;
unsigned remote_cert_ku[MAX_PARMS];
diff --git a/src/openvpn/ssl_openssl.c b/src/openvpn/ssl_openssl.c
index a727b60..1006617 100644
--- a/src/openvpn/ssl_openssl.c
+++ b/src/openvpn/ssl_openssl.c
@@ -202,10 +202,69 @@ tls_ctx_set_options (struct tls_root_ctx *ctx, unsigned int ssl_flags)
void
tls_ctx_restrict_ciphers(struct tls_root_ctx *ctx, const char *ciphers)
{
+ size_t begin_of_cipher, end_of_cipher;
+
+ const char *current_cipher;
+ size_t current_cipher_len;
+
+ const tls_cipher_name_pair *cipher_pair;
+
+ const size_t openssl_ciphers_size = 4096;
+ char openssl_ciphers[openssl_ciphers_size];
+ size_t openssl_ciphers_len = 0;
+ openssl_ciphers[0] = '\0';
+
ASSERT(NULL != ctx);
- if(!SSL_CTX_set_cipher_list(ctx->ctx, ciphers))
- msg(M_SSLERR, "Failed to set restricted TLS cipher list: %s", ciphers);
+ // Translate IANA cipher suite names to OpenSSL names
+ for (begin_of_cipher = 0; begin_of_cipher < strlen(ciphers); begin_of_cipher = end_of_cipher+1) {
+ end_of_cipher = strcspn(&ciphers[begin_of_cipher], ":");
+ cipher_pair = tls_get_cipher_name_pair(&ciphers[begin_of_cipher], end_of_cipher - begin_of_cipher);
+
+ if (NULL == cipher_pair)
+ {
+ // No translation found, use original
+ current_cipher = &ciphers[begin_of_cipher];
+ current_cipher_len = end_of_cipher - begin_of_cipher;
+
+ // Issue warning on missing translation
+ // %.*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);
+ }
+ else
+ {
+ // Use OpenSSL name
+ current_cipher = cipher_pair->openssl_name;
+ current_cipher_len = strlen(current_cipher);
+
+ if (end_of_cipher - begin_of_cipher == current_cipher_len &&
+ 0 == memcmp (&ciphers[begin_of_cipher], cipher_pair->openssl_name, end_of_cipher - begin_of_cipher))
+ {
+ // Non-IANA name used, show warning
+ msg (M_WARN, "Deprecated TLS cipher name '%s', please use IANA name '%s'", cipher_pair->openssl_name, cipher_pair->iana_name);
+ }
+ }
+
+ // Make sure new cipher name fits in cipher string
+ if (((openssl_ciphers_size-1) - openssl_ciphers_len) < current_cipher_len) {
+ msg(M_SSLERR, "Failed to set restricted TLS cipher list, too long (>%zu).", openssl_ciphers_size-1);
+ }
+
+ // Concatenate cipher name to OpenSSL cipher string
+ memcpy(&openssl_ciphers[openssl_ciphers_len], current_cipher, current_cipher_len);
+ openssl_ciphers_len += current_cipher_len;
+ openssl_ciphers[openssl_ciphers_len] = ':';
+ openssl_ciphers_len++;
+ }
+
+ if (openssl_ciphers_len > 0)
+ openssl_ciphers[openssl_ciphers_len-1] = '\0';
+
+ // Set OpenSSL cipher list
+ if(!SSL_CTX_set_cipher_list(ctx->ctx, openssl_ciphers))
+ msg(M_SSLERR, "Failed to set restricted TLS cipher list: %s", openssl_ciphers);
}
void
@@ -1131,6 +1190,8 @@ show_available_tls_ciphers ()
SSL_CTX *ctx;
SSL *ssl;
const char *cipher_name;
+ const char *print_name;
+ const tls_cipher_name_pair *pair;
int priority = 0;
ctx = SSL_CTX_new (TLSv1_method ());
@@ -1144,7 +1205,17 @@ show_available_tls_ciphers ()
printf ("Available TLS Ciphers,\n");
printf ("listed in order of preference:\n\n");
while ((cipher_name = SSL_get_cipher_list (ssl, priority++)))
- printf ("%s\n", cipher_name);
+ {
+ pair = tls_get_cipher_name_pair(cipher_name, strlen(cipher_name));
+
+ if (NULL == pair) {
+ // No translation found, print warning
+ printf ("%s (No IANA name known to OpenVPN, use OpenSSL name.)\n", cipher_name);
+ } else {
+ printf ("%s\n", pair->iana_name);
+ }
+
+ }
printf ("\n");
SSL_free (ssl);
diff --git a/src/openvpn/ssl_polarssl.c b/src/openvpn/ssl_polarssl.c
index 12318b3..2b5b37b 100644
--- a/src/openvpn/ssl_polarssl.c
+++ b/src/openvpn/ssl_polarssl.c
@@ -65,23 +65,6 @@ tls_clear_error()
{
}
-static int default_ciphersuites[] =
-{
- SSL_EDH_RSA_AES_256_SHA,
- SSL_EDH_RSA_CAMELLIA_256_SHA,
- SSL_EDH_RSA_AES_128_SHA,
- SSL_EDH_RSA_CAMELLIA_128_SHA,
- SSL_EDH_RSA_DES_168_SHA,
- SSL_RSA_AES_256_SHA,
- SSL_RSA_CAMELLIA_256_SHA,
- SSL_RSA_AES_128_SHA,
- SSL_RSA_CAMELLIA_128_SHA,
- SSL_RSA_DES_168_SHA,
- SSL_RSA_RC4_128_SHA,
- SSL_RSA_RC4_128_MD5,
- 0
-};
-
void
tls_ctx_server_new(struct tls_root_ctx *ctx)
{
@@ -161,6 +144,25 @@ tls_ctx_set_options (struct tls_root_ctx *ctx, unsigned int ssl_flags)
{
}
+static const char *
+tls_translate_cipher_name (const char * cipher_name) {
+ const tls_cipher_name_pair * pair = tls_get_cipher_name_pair(cipher_name, strlen(cipher_name));
+
+ if (NULL == pair)
+ {
+ // No translation found, return original
+ return cipher_name;
+ }
+
+ if (0 != strcmp(cipher_name, pair->iana_name))
+ {
+ // Deprecated name found, notify user
+ msg(M_WARN, "Deprecated cipher suite name '%s', please use IANA name '%s'", pair->openssl_name, pair->iana_name);
+ }
+
+ return pair->iana_name;
+}
+
void
tls_ctx_restrict_ciphers(struct tls_root_ctx *ctx, const char *ciphers)
{
@@ -186,7 +188,8 @@ tls_ctx_restrict_ciphers(struct tls_root_ctx *ctx, const char *ciphers)
token = strtok (tmp_ciphers, ":");
while(token)
{
- ctx->allowed_ciphers[i] = ssl_get_ciphersuite_id (token);
+ ctx->allowed_ciphers[i] = ssl_get_ciphersuite_id (
+ tls_translate_cipher_name (token));
if (0 != ctx->allowed_ciphers[i])
i++;
token = strtok (NULL, ":");
@@ -514,20 +517,17 @@ void key_state_ssl_init(struct key_state_ssl *ks_ssl,
ssl_set_rng (ks_ssl->ctx, ctr_drbg_random, rand_ctx_get());
- ALLOC_OBJ_CLEAR (ks_ssl->ssn, ssl_session);
- ssl_set_session (ks_ssl->ctx, 0, 0, ks_ssl->ssn );
if (ssl_ctx->allowed_ciphers)
ssl_set_ciphersuites (ks_ssl->ctx, ssl_ctx->allowed_ciphers);
- else
- ssl_set_ciphersuites (ks_ssl->ctx, default_ciphersuites);
/* Initialise authentication information */
if (is_server)
ssl_set_dh_param_ctx (ks_ssl->ctx, ssl_ctx->dhm_ctx );
#if defined(ENABLE_PKCS11)
if (ssl_ctx->priv_key_pkcs11 != NULL)
- ssl_set_own_cert_pkcs11( ks_ssl->ctx, ssl_ctx->crt_chain,
- ssl_ctx->priv_key_pkcs11 );
+ ssl_set_own_cert_alt( ks_ssl->ctx, ssl_ctx->crt_chain,
+ ssl_ctx->priv_key_pkcs11, ssl_pkcs11_decrypt, ssl_pkcs11_sign,
+ ssl_pkcs11_key_len );
else
#endif
ssl_set_own_cert( ks_ssl->ctx, ssl_ctx->crt_chain, ssl_ctx->priv_key );
@@ -543,7 +543,6 @@ void key_state_ssl_init(struct key_state_ssl *ks_ssl,
ALLOC_OBJ_CLEAR (ks_ssl->ct_out, endless_buffer);
ssl_set_bio (ks_ssl->ctx, endless_buf_read, ks_ssl->ct_in,
endless_buf_write, ks_ssl->ct_out);
-
}
}
@@ -556,8 +555,6 @@ key_state_ssl_free(struct key_state_ssl *ks_ssl)
ssl_free(ks_ssl->ctx);
free(ks_ssl->ctx);
}
- if (ks_ssl->ssn)
- free(ks_ssl->ssn);
if (ks_ssl->ct_in) {
buf_free_entries(ks_ssl->ct_in);
free(ks_ssl->ct_in);
@@ -666,6 +663,7 @@ key_state_read_ciphertext (struct key_state_ssl *ks, struct buffer *buf,
{
int retval = 0;
int len = 0;
+ char error_message[1024];
perf_push (PERF_BIO_READ_CIPHERTEXT);
@@ -691,7 +689,8 @@ key_state_read_ciphertext (struct key_state_ssl *ks, struct buffer *buf,
perf_pop ();
if (POLARSSL_ERR_NET_WANT_WRITE == retval || POLARSSL_ERR_NET_WANT_READ == retval)
return 0;
- msg (D_TLS_ERRORS, "TLS_ERROR: read tls_read_plaintext error");
+ error_strerror(retval, error_message, sizeof(error_message));
+ msg (D_TLS_ERRORS, "TLS_ERROR: read tls_read_ciphertext error: %d %s", retval, error_message);
buf->len = 0;
return -1;
}
@@ -763,6 +762,7 @@ key_state_read_plaintext (struct key_state_ssl *ks, struct buffer *buf,
{
int retval = 0;
int len = 0;
+ char error_message[1024];
perf_push (PERF_BIO_READ_PLAINTEXT);
@@ -787,7 +787,8 @@ key_state_read_plaintext (struct key_state_ssl *ks, struct buffer *buf,
{
if (POLARSSL_ERR_NET_WANT_WRITE == retval || POLARSSL_ERR_NET_WANT_READ == retval)
return 0;
- msg (D_TLS_ERRORS, "TLS_ERROR: read tls_read_plaintext error");
+ error_strerror(retval, error_message, sizeof(error_message));
+ msg (D_TLS_ERRORS, "TLS_ERROR: read tls_read_plaintext error: %d %s", retval, error_message);
buf->len = 0;
perf_pop ();
return -1;
@@ -818,7 +819,7 @@ key_state_read_plaintext (struct key_state_ssl *ks, struct buffer *buf,
void
print_details (struct key_state_ssl * ks_ssl, const char *prefix)
{
- x509_cert *cert;
+ const x509_cert *cert;
char s1[256];
char s2[256];
@@ -828,7 +829,7 @@ print_details (struct key_state_ssl * ks_ssl, const char *prefix)
ssl_get_version (ks_ssl->ctx),
ssl_get_ciphersuite(ks_ssl->ctx));
- cert = ks_ssl->ctx->peer_cert;
+ cert = ssl_get_peer_cert(ks_ssl->ctx);
if (cert != NULL)
{
openvpn_snprintf (s2, sizeof (s2), ", " counter_format " bit RSA", (counter_type) cert->rsa.len * 8);
diff --git a/src/openvpn/ssl_polarssl.h b/src/openvpn/ssl_polarssl.h
index 456573f..da93699 100644
--- a/src/openvpn/ssl_polarssl.h
+++ b/src/openvpn/ssl_polarssl.h
@@ -73,7 +73,6 @@ struct tls_root_ctx {
struct key_state_ssl {
ssl_context *ctx;
- ssl_session *ssn;
endless_buffer *ct_in;
endless_buffer *ct_out;
};
diff --git a/src/openvpn/ssl_verify.c b/src/openvpn/ssl_verify.c
index cac46e9..e651a8e 100644
--- a/src/openvpn/ssl_verify.c
+++ b/src/openvpn/ssl_verify.c
@@ -369,16 +369,21 @@ verify_peer_cert(const struct tls_options *opt, openvpn_x509_cert_t *peer_cert,
#endif /* OPENSSL_VERSION_NUMBER */
- /* verify X509 name or common name against --tls-remote */
- if (opt->verify_x509name && strlen (opt->verify_x509name) > 0)
+ /* verify X509 name or username against --verify-x509-[user]name */
+ if (opt->verify_x509_type != VERIFY_X509_NONE)
{
- if (strcmp (opt->verify_x509name, subject) == 0
- || strncmp (opt->verify_x509name, common_name, strlen (opt->verify_x509name)) == 0)
+ if ( (opt->verify_x509_type == VERIFY_X509_SUBJECT_DN
+ && strcmp (opt->verify_x509_name, subject) == 0)
+ || (opt->verify_x509_type == VERIFY_X509_SUBJECT_RDN
+ && strcmp (opt->verify_x509_name, common_name) == 0)
+ || (opt->verify_x509_type == VERIFY_X509_SUBJECT_RDN_PREFIX
+ && strncmp (opt->verify_x509_name, common_name,
+ strlen (opt->verify_x509_name)) == 0) )
msg (D_HANDSHAKE, "VERIFY X509NAME OK: %s", subject);
else
{
msg (D_HANDSHAKE, "VERIFY X509NAME ERROR: %s, must be %s",
- subject, opt->verify_x509name);
+ subject, opt->verify_x509_name);
return FAILURE; /* Reject connection */
}
}
diff --git a/src/openvpn/ssl_verify.h b/src/openvpn/ssl_verify.h
index 1d20152..e0bcba4 100644
--- a/src/openvpn/ssl_verify.h
+++ b/src/openvpn/ssl_verify.h
@@ -62,6 +62,12 @@ struct cert_hash_set {
struct cert_hash *ch[MAX_CERT_DEPTH]; /**< Array of certificate hashes */
};
+#define VERIFY_X509_NONE 0
+#define VERIFY_X509_SUBJECT_DN 1
+#define VERIFY_X509_SUBJECT_RDN 2
+#define VERIFY_X509_SUBJECT_RDN_PREFIX 3
+#define TLS_REMOTE_SUBJECT_DN 1 + 0x100
+#define TLS_REMOTE_SUBJECT_RDN_PREFIX 3 + 0x100
#define TLS_AUTHENTICATION_SUCCEEDED 0
#define TLS_AUTHENTICATION_FAILED 1
diff --git a/src/openvpn/ssl_verify_polarssl.c b/src/openvpn/ssl_verify_polarssl.c
index a32db8d..5db4f02 100644
--- a/src/openvpn/ssl_verify_polarssl.c
+++ b/src/openvpn/ssl_verify_polarssl.c
@@ -44,11 +44,10 @@
int
verify_callback (void *session_obj, x509_cert *cert, int cert_depth,
- int preverify_ok)
+ int *flags)
{
struct tls_session *session = (struct tls_session *) session_obj;
struct gc_arena gc = gc_new();
- int ret = 1;
ASSERT (cert);
ASSERT (session);
@@ -59,31 +58,29 @@ verify_callback (void *session_obj, x509_cert *cert, int cert_depth,
cert_hash_remember (session, cert_depth, x509_get_sha1_hash(cert, &gc));
/* did peer present cert which was signed by our root cert? */
- if (!preverify_ok)
+ if (*flags != 0)
{
char *subject = x509_get_subject(cert, &gc);
if (subject)
- msg (D_TLS_ERRORS, "VERIFY ERROR: depth=%d, %s", cert_depth, subject);
+ msg (D_TLS_ERRORS, "VERIFY ERROR: depth=%d, flags=%x, %s", cert_depth, *flags, subject);
else
- msg (D_TLS_ERRORS, "VERIFY ERROR: depth=%d, could not extract X509 "
- "subject string from certificate", cert_depth);
+ msg (D_TLS_ERRORS, "VERIFY ERROR: depth=%d, flags=%x, could not extract X509 "
+ "subject string from certificate", *flags, cert_depth);
- goto cleanup;
+ /* Leave flags set to non-zero to indicate that the cert is not ok */
+ }
+ else if (SUCCESS != verify_cert(session, cert, cert_depth))
+ {
+ *flags |= BADCERT_OTHER;
}
- if (SUCCESS != verify_cert(session, cert, cert_depth))
- goto cleanup;
-
- ret = 0;
-
-cleanup:
gc_free(&gc);
/*
- * PolarSSL expects 1 on failure, 0 on success
+ * PolarSSL-1.2.0+ expects 0 on anything except fatal errors.
*/
- return ret;
+ return 0;
}
#ifdef ENABLE_X509ALTUSERNAME
diff --git a/src/openvpn/ssl_verify_polarssl.h b/src/openvpn/ssl_verify_polarssl.h
index fceee66..b259081 100644
--- a/src/openvpn/ssl_verify_polarssl.h
+++ b/src/openvpn/ssl_verify_polarssl.h
@@ -55,27 +55,25 @@ typedef x509_cert openvpn_x509_cert_t;
* calls the PolarSSL library's \c ssl_set_verify_callback() function with \c
* verify_callback() as its callback argument.
*
- * It checks preverify_ok, and registers the certificate hash. If these steps
- * succeed, it calls the \c verify_cert() function, which performs
- * OpenVPN-specific verification.
+ * It checks *flags and registers the certificate hash. If these steps succeed,
+ * it calls the \c verify_cert() function, which performs OpenVPN-specific
+ * verification.
*
* @param session_obj - The OpenVPN \c tls_session associated with this object,
* as set during SSL session setup.
* @param cert - The certificate used by PolarSSL.
* @param cert_depth - The depth of the current certificate in the chain, with
* 0 being the actual certificate.
- * @param preverify_ok - Whether the remote OpenVPN peer's certificate
- * past verification. A value of 1 means it
- * verified successfully, 0 means it failed.
+ * @param flags - Whether the remote OpenVPN peer's certificate
+ * passed verification. A value of 0 means it
+ * verified successfully, any other value means it
+ * failed. \c verify_callback() is considered to have
+ * ok'ed this certificate if flags is 0 when it returns.
*
- * @return The return value indicates whether the supplied certificate is
- * allowed to set up a VPN tunnel. The following values can be
- * returned:
- * - \c 0: failure, this certificate is not allowed to connect.
- * - \c 1: success, this certificate is allowed to connect.
+ * @return The return value is 0 unless a fatal error occurred.
*/
int verify_callback (void *session_obj, x509_cert *cert, int cert_depth,
- int preverify_ok);
+ int *flags);
/** @} name Function for authenticating a new connection from a remote OpenVPN peer */
diff --git a/src/openvpn/status.c b/src/openvpn/status.c
index 5f9ab9e..b7ff484 100644
--- a/src/openvpn/status.c
+++ b/src/openvpn/status.c
@@ -33,6 +33,7 @@
#include "status.h"
#include "perf.h"
#include "misc.h"
+#include "fdmisc.h"
#include "memdbg.h"
@@ -98,6 +99,7 @@ status_open (const char *filename,
if (so->fd >= 0)
{
so->filename = string_alloc (filename, NULL);
+ set_cloexec (so->fd);
/* allocate read buffer */
if (so->flags & STATUS_OUTPUT_READ)
diff --git a/src/openvpn/syshead.h b/src/openvpn/syshead.h
index c81f08a..4db29cc 100644
--- a/src/openvpn/syshead.h
+++ b/src/openvpn/syshead.h
@@ -307,6 +307,10 @@
#include <netinet/ip.h>
#endif
+#ifdef HAVE_NETINET_TCP_H
+#include <netinet/tcp.h>
+#endif
+
#ifdef HAVE_NET_IF_TUN_H
#include <net/if_tun.h>
#endif
@@ -395,6 +399,13 @@
#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/src/openvpn/tun.c b/src/openvpn/tun.c
index 4b0365d..a361233 100644
--- a/src/openvpn/tun.c
+++ b/src/openvpn/tun.c
@@ -73,6 +73,8 @@ static void solaris_error_close (struct tuntap *tt, const struct env_set *es, co
#include <stropts.h>
#endif
+static void clear_tuntap (struct tuntap *tuntap);
+
bool
is_dev_type (const char *dev, const char *dev_type, const char *match_type)
{
@@ -298,16 +300,6 @@ warn_on_use_of_common_subnets (void)
}
/*
- * Complain if --dev tap and --ifconfig is used on an OS for which
- * we don't have a custom tap ifconfig template below.
- */
-static void
-no_tap_ifconfig ()
-{
- msg (M_FATAL, "Sorry but you cannot use --dev tap and --ifconfig together on this OS because I have not yet been programmed to understand the appropriate ifconfig syntax to use for TAP-style devices on this OS. Your best alternative is to use an --up script and do the ifconfig command manually.");
-}
-
-/*
* Return a string to be used for options compatibility check
* between peers.
*/
diff --git a/src/openvpn/tun.h b/src/openvpn/tun.h
index 8622bf8..c3fc62e 100644
--- a/src/openvpn/tun.h
+++ b/src/openvpn/tun.h
@@ -203,8 +203,6 @@ tuntap_defined (const struct tuntap *tt)
* Function prototypes
*/
-static void clear_tuntap (struct tuntap *tuntap);
-
void open_tun (const char *dev, const char *dev_type, const char *dev_node,
struct tuntap *tt);