summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArne Schwabe <arne@rfc2549.org>2014-07-23 01:51:47 +0200
committerArne Schwabe <arne@rfc2549.org>2014-07-23 01:51:47 +0200
commita42b3f2e54971e1325666720e235ce1e17ed8cae (patch)
treef850a73ad93c392b2b8561636b08e07f2262f78c
parentb5bf37d1e2ff5968f748d1d756e37e46eb572ffd (diff)
Updaten OpenVPN master
--HG-- extra : rebase_source : 7937a60e9172279fce1c3cf37371a7e74caf7f31
-rw-r--r--main/openvpn/config-version.h4
-rw-r--r--main/openvpn/configure.ac34
-rwxr-xr-xmain/openvpn/distro/rpm/openvpn.init.d.rhel2
-rw-r--r--main/openvpn/distro/rpm/openvpn.init.d.suse2
-rw-r--r--main/openvpn/doc/openvpn.849
-rw-r--r--main/openvpn/sample/sample-config-files/server.conf9
-rw-r--r--main/openvpn/src/openvpn/crypto.c42
-rw-r--r--main/openvpn/src/openvpn/crypto.h4
-rw-r--r--main/openvpn/src/openvpn/crypto_backend.h30
-rw-r--r--main/openvpn/src/openvpn/crypto_openssl.c56
-rw-r--r--main/openvpn/src/openvpn/crypto_polarssl.c21
-rw-r--r--main/openvpn/src/openvpn/helper.c6
-rw-r--r--main/openvpn/src/openvpn/init.c6
-rw-r--r--main/openvpn/src/openvpn/options.c26
-rw-r--r--main/openvpn/src/openvpn/route.c60
-rw-r--r--main/openvpn/src/openvpn/ssl.c16
-rw-r--r--main/openvpn/src/openvpn/ssl_openssl.c3
-rw-r--r--main/openvpn/src/openvpn/ssl_openssl.h11
-rw-r--r--main/openvpn/src/openvpn/ssl_verify_openssl.c4
-rw-r--r--main/openvpn/src/openvpn/ssl_verify_polarssl.c7
-rw-r--r--main/openvpn/src/openvpn/syshead.h8
-rw-r--r--main/openvpn/src/openvpn/tun.c170
-rwxr-xr-xmain/openvpn/tests/t_client.sh.in6
-rwxr-xr-xmain/openvpn/tests/t_lpback.sh33
24 files changed, 505 insertions, 104 deletions
diff --git a/main/openvpn/config-version.h b/main/openvpn/config-version.h
index b9bd0a00..762b9dc6 100644
--- a/main/openvpn/config-version.h
+++ b/main/openvpn/config-version.h
@@ -1,2 +1,2 @@
-#define CONFIGURE_GIT_REVISION "icsopenvpn_615-c430ab0e0cef9994"
-#define CONFIGURE_GIT_FLAGS "+"
+#define CONFIGURE_GIT_REVISION "icsopenvpn_618-e63b88d330782d14"
+#define CONFIGURE_GIT_FLAGS ""
diff --git a/main/openvpn/configure.ac b/main/openvpn/configure.ac
index cb7a5d33..ffba3749 100644
--- a/main/openvpn/configure.ac
+++ b/main/openvpn/configure.ac
@@ -72,6 +72,13 @@ AC_ARG_ENABLE(
)
AC_ARG_ENABLE(
+ [ofb-cfb],
+ [AS_HELP_STRING([--enable-ofb-cfb], [enable support for OFB and CFB cipher modes @<:@default=yes@:>@])],
+ ,
+ [enable_crypto_ofb_cfb="yes"]
+)
+
+AC_ARG_ENABLE(
[ssl],
[AS_HELP_STRING([--disable-ssl], [disable SSL support for TLS-based key exchange @<:@default=yes@:>@])],
,
@@ -335,6 +342,13 @@ case "$host" in
AC_DEFINE([TARGET_DRAGONFLY], [1], [Are we running on DragonFlyBSD?])
AC_DEFINE_UNQUOTED([TARGET_PREFIX], ["D"], [Target prefix])
;;
+ *-aix*)
+ AC_DEFINE([TARGET_AIX], [1], [Are we running AIX?])
+ AC_DEFINE_UNQUOTED([TARGET_PREFIX], ["A"], [Target prefix])
+ ROUTE="/usr/sbin/route"
+ have_tap_header="yes"
+ ac_cv_header_net_if_h="no" # exists, but breaks things
+ ;;
*)
AC_DEFINE_UNQUOTED([TARGET_PREFIX], ["X"], [Target prefix])
have_tap_header="yes"
@@ -786,25 +800,6 @@ if test "${have_openssl_crypto}" = "yes"; then
LIBS="${saved_LIBS}"
fi
-if test "${enable_ssl}" = "yes" && test "${with_crypto_library}" = "openssl";
-then
- saved_CPPFLAGS="${CPPFLAGS}"
- CPPFLAGS="${CPPFLAGS} ${OPENSSL_CRYPTO_CFLAGS}"
- AC_MSG_CHECKING([for SSL_OP_NO_TICKET flag in OpenSSL])
- AC_EGREP_CPP(have_ssl_op_no_ticket, [
- #include <openssl/ssl.h>
- #ifdef SSL_OP_NO_TICKET
- have_ssl_op_no_ticket
- #endif
- ], [
- AC_MSG_RESULT([yes])
- ], [
- AC_MSG_RESULT([no])
- AC_ERROR([OpenVPN 2.4+ requires SSL_OP_NO_TICKET in OpenSSL])
- ])
- CPPFLAGS="${saved_CPPFLAGS}"
-fi
-
AC_ARG_VAR([POLARSSL_CFLAGS], [C compiler flags for polarssl])
AC_ARG_VAR([POLARSSL_LIBS], [linker flags for polarssl])
have_polarssl_ssl="yes"
@@ -1071,6 +1066,7 @@ fi
if test "${enable_crypto}" = "yes"; then
test "${have_crypto_crypto}" != "yes" && AC_MSG_ERROR([${with_crypto_library} crypto is required but missing])
+ test "${enable_crypto_ofb_cfb}" = "yes" && AC_DEFINE([ENABLE_OFB_CFB_MODE], [1], [Enable OFB and CFB cipher modes])
OPTIONAL_CRYPTO_CFLAGS="${OPTIONAL_CRYPTO_CFLAGS} ${CRYPTO_CRYPTO_CFLAGS}"
OPTIONAL_CRYPTO_LIBS="${OPTIONAL_CRYPTO_LIBS} ${CRYPTO_CRYPTO_LIBS}"
AC_DEFINE([ENABLE_CRYPTO], [1], [Enable crypto library])
diff --git a/main/openvpn/distro/rpm/openvpn.init.d.rhel b/main/openvpn/distro/rpm/openvpn.init.d.rhel
index 821abd58..cdf3e9de 100755
--- a/main/openvpn/distro/rpm/openvpn.init.d.rhel
+++ b/main/openvpn/distro/rpm/openvpn.init.d.rhel
@@ -148,7 +148,7 @@ case "$1" in
for c in `/bin/ls *.conf 2>/dev/null`; do
bn=${c%%.conf}
if [ -f "$bn.sh" ]; then
- . $bn.sh
+ . ./$bn.sh
fi
rm -f $piddir/$bn.pid
$openvpn --daemon --writepid $piddir/$bn.pid --config $c --cd $work
diff --git a/main/openvpn/distro/rpm/openvpn.init.d.suse b/main/openvpn/distro/rpm/openvpn.init.d.suse
index 2bac7f32..270024e8 100644
--- a/main/openvpn/distro/rpm/openvpn.init.d.suse
+++ b/main/openvpn/distro/rpm/openvpn.init.d.suse
@@ -161,7 +161,7 @@ case "$1" in
for c in `/bin/ls *.conf 2>/dev/null`; do
bn=${c%%.conf}
if [ -f "$bn.sh" ]; then
- . $bn.sh
+ . ./$bn.sh
fi
rm -f $piddir/$bn.pid
$openvpn --daemon --writepid $piddir/$bn.pid --config $c --cd $work
diff --git a/main/openvpn/doc/openvpn.8 b/main/openvpn/doc/openvpn.8
index 76b7bfd4..aee0bc83 100644
--- a/main/openvpn/doc/openvpn.8
+++ b/main/openvpn/doc/openvpn.8
@@ -2704,7 +2704,7 @@ on sufficiently fast hardware. SSL/TLS authentication must
be used in this mode.
.\"*********************************************************
.TP
-.B \-\-server network netmask
+.B \-\-server network netmask ['nopool']
A helper directive designed to simplify the configuration
of OpenVPN's server mode. This directive will set up an
OpenVPN server which will allocate addresses to clients
@@ -2739,6 +2739,9 @@ expands as follows:
if !nopool:
ifconfig-pool 10.8.0.2 10.8.0.254 255.255.255.0
push "route-gateway 10.8.0.1"
+ if route-gateway unset:
+ route-gateway 10.8.0.2
+
.in -4
.ft
.fi
@@ -4790,12 +4793,44 @@ the tls-verify script returns. The file name used for the certificate
is available via the peer_cert environment variable.
.\"*********************************************************
.TP
-.B \-\-x509-username-field fieldname
-Field in x509 certificate subject to be used as username (default=CN).
-.B Fieldname
-will be uppercased before matching. When this option is used, the
-.B \-\-verify-x509-username
-option will match against the chosen fieldname instead of the CN.
+.B \-\-x509-username-field [ext:\]fieldname
+Field in the X.509 certificate subject to be used as the username (default=CN).
+Typically, this option is specified with
+.B fieldname
+as either of the following:
+
+.B \-\-x509-username-field
+emailAddress
+.br
+.B \-\-x509-username-field ext:\fRsubjectAltName
+
+The first example uses the value of the "emailAddress" attribute in the
+certificate's Subject field as the username. The second example uses
+the
+.B ext:
+prefix to signify that the X.509 extension
+.B fieldname
+"subjectAltName" be searched for an rfc822Name (email) field to be used
+as the username. In cases where there are multiple email addresses
+in
+.B ext:fieldname\fR,
+the last occurrence is chosen.
+
+When this option is used, the
+.B \-\-verify-x509-name
+option will match against the chosen
+.B fieldname
+instead of the Common Name.
+
+.B Please note:
+This option has a feature which will convert an all-lowercase
+.B fieldname
+to uppercase characters, e.g., ou -> OU. A mixed-case
+.B fieldname
+or one having the
+.B ext:
+prefix will be left as-is. This automatic upcasing feature
+is deprecated and will be removed in a future release.
.\"*********************************************************
.TP
.B \-\-tls-remote name (DEPRECATED)
diff --git a/main/openvpn/sample/sample-config-files/server.conf b/main/openvpn/sample/sample-config-files/server.conf
index f483b6bb..467d5b8a 100644
--- a/main/openvpn/sample/sample-config-files/server.conf
+++ b/main/openvpn/sample/sample-config-files/server.conf
@@ -83,9 +83,16 @@ key server.key # This file should be kept secret
# Generate your own with:
# openssl dhparam -out dh1024.pem 1024
# Substitute 2048 for 1024 if you are using
-# 2048 bit keys.
+# 2048 bit keys.
dh dh1024.pem
+# Network topology
+# Should be subnet (addressing via IP)
+# unless Windows clients v2.0.9 and lower have to
+# be supported (then net30, i.e. a /30 per client)
+# Defaults to net30 (not recommended)
+;topology subnet
+
# Configure server mode and supply a VPN subnet
# for OpenVPN to draw client addresses from.
# The server will take 10.8.0.1 for itself,
diff --git a/main/openvpn/src/openvpn/crypto.c b/main/openvpn/src/openvpn/crypto.c
index 8201708a..62c4ab28 100644
--- a/main/openvpn/src/openvpn/crypto.c
+++ b/main/openvpn/src/openvpn/crypto.c
@@ -100,10 +100,10 @@ openvpn_encrypt (struct buffer *buf, struct buffer work,
{
uint8_t iv_buf[OPENVPN_MAX_IV_LENGTH];
const int iv_size = cipher_ctx_iv_length (ctx->cipher);
- const unsigned int mode = cipher_ctx_mode (ctx->cipher);
+ const cipher_kt_t *cipher_kt = cipher_ctx_get_cipher_kt (ctx->cipher);
int outlen;
- if (mode == OPENVPN_MODE_CBC)
+ if (cipher_kt_mode_cbc(cipher_kt))
{
CLEAR (iv_buf);
@@ -119,7 +119,7 @@ openvpn_encrypt (struct buffer *buf, struct buffer work,
ASSERT (packet_id_write (&pin, buf, BOOL_CAST (opt->flags & CO_PACKET_ID_LONG_FORM), true));
}
}
- else if (mode == OPENVPN_MODE_CFB || mode == OPENVPN_MODE_OFB)
+ else if (cipher_kt_mode_ofb_cfb(cipher_kt))
{
struct packet_id_net pin;
struct buffer b;
@@ -171,7 +171,10 @@ openvpn_encrypt (struct buffer *buf, struct buffer work,
/* Flush the encryption buffer */
ASSERT(cipher_ctx_final(ctx->cipher, BPTR (&work) + outlen, &outlen));
work.len += outlen;
- ASSERT (mode != OPENVPN_MODE_CBC || outlen == iv_size);
+
+ /* For all CBC mode ciphers, check the last block is complete */
+ ASSERT (cipher_kt_mode (cipher_kt) != OPENVPN_MODE_CBC ||
+ outlen == iv_size);
/* prepend the IV to the ciphertext */
if (opt->flags & CO_USE_IV)
@@ -272,8 +275,8 @@ openvpn_decrypt (struct buffer *buf, struct buffer work,
if (ctx->cipher)
{
- const unsigned int mode = cipher_ctx_mode (ctx->cipher);
const int iv_size = cipher_ctx_iv_length (ctx->cipher);
+ const cipher_kt_t *cipher_kt = cipher_ctx_get_cipher_kt (ctx->cipher);
uint8_t iv_buf[OPENVPN_MAX_IV_LENGTH];
int outlen;
@@ -320,7 +323,7 @@ openvpn_decrypt (struct buffer *buf, struct buffer work,
/* Get packet ID from plaintext buffer or IV, depending on cipher mode */
{
- if (mode == OPENVPN_MODE_CBC)
+ if (cipher_kt_mode_cbc(cipher_kt))
{
if (opt->packet_id)
{
@@ -329,7 +332,7 @@ openvpn_decrypt (struct buffer *buf, struct buffer work,
have_pin = true;
}
}
- else if (mode == OPENVPN_MODE_CFB || mode == OPENVPN_MODE_OFB)
+ else if (cipher_kt_mode_ofb_cfb(cipher_kt))
{
struct buffer b;
@@ -480,17 +483,12 @@ init_key_type (struct key_type *kt, const char *ciphername,
/* check legal cipher mode */
{
- const unsigned int mode = cipher_kt_mode (kt->cipher);
- if (!(mode == OPENVPN_MODE_CBC
-#ifdef ALLOW_NON_CBC_CIPHERS
- || (cfb_ofb_allowed && (mode == OPENVPN_MODE_CFB || mode == OPENVPN_MODE_OFB))
+ if (!(cipher_kt_mode_cbc(kt->cipher)
+#ifdef ENABLE_OFB_CFB_MODE
+ || (cfb_ofb_allowed && cipher_kt_mode_ofb_cfb(kt->cipher))
#endif
))
-#ifdef ENABLE_SMALL
msg (M_FATAL, "Cipher '%s' mode not supported", ciphername);
-#else
- msg (M_FATAL, "Cipher '%s' uses a mode not supported by " PACKAGE_NAME " in your current configuration. CBC mode is always supported, while CFB and OFB modes are supported only when using SSL/TLS authentication and key exchange mode, and when " PACKAGE_NAME " has been built with ALLOW_NON_CBC_CIPHERS.", ciphername);
-#endif
}
}
else
@@ -660,18 +658,10 @@ fixup_key (struct key *key, const struct key_type *kt)
void
check_replay_iv_consistency (const struct key_type *kt, bool packet_id, bool use_iv)
{
- if (cfb_ofb_mode (kt) && !(packet_id && use_iv))
- msg (M_FATAL, "--no-replay or --no-iv cannot be used with a CFB or OFB mode cipher");
-}
+ ASSERT(kt);
-bool
-cfb_ofb_mode (const struct key_type* kt)
-{
- if (kt && kt->cipher) {
- const unsigned int mode = cipher_kt_mode (kt->cipher);
- return mode == OPENVPN_MODE_CFB || mode == OPENVPN_MODE_OFB;
- }
- return false;
+ if (cipher_kt_mode_ofb_cfb(kt->cipher) && !(packet_id && use_iv))
+ msg (M_FATAL, "--no-replay or --no-iv cannot be used with a CFB or OFB mode cipher");
}
/*
diff --git a/main/openvpn/src/openvpn/crypto.h b/main/openvpn/src/openvpn/crypto.h
index 68cdf162..3c4e59d7 100644
--- a/main/openvpn/src/openvpn/crypto.h
+++ b/main/openvpn/src/openvpn/crypto.h
@@ -32,8 +32,6 @@
#ifdef ENABLE_CRYPTO
-#define ALLOW_NON_CBC_CIPHERS
-
#include "crypto_backend.h"
#include "basic.h"
#include "buffer.h"
@@ -189,8 +187,6 @@ bool write_key (const struct key *key, const struct key_type *kt,
int read_key (struct key *key, const struct key_type *kt, struct buffer *buf);
-bool cfb_ofb_mode (const struct key_type* kt);
-
void init_key_type (struct key_type *kt, const char *ciphername,
bool ciphername_defined, const char *authname, bool authname_defined,
int keysize, bool cfb_ofb_allowed, bool warn);
diff --git a/main/openvpn/src/openvpn/crypto_backend.h b/main/openvpn/src/openvpn/crypto_backend.h
index 5ae47e6c..a48ad6c5 100644
--- a/main/openvpn/src/openvpn/crypto_backend.h
+++ b/main/openvpn/src/openvpn/crypto_backend.h
@@ -230,6 +230,26 @@ int cipher_kt_block_size (const cipher_kt_t *cipher_kt);
*/
int cipher_kt_mode (const cipher_kt_t *cipher_kt);
+/**
+ * Check of the supplied cipher is a supported CBC mode cipher.
+ *
+ * @param cipher Static cipher parameters. May not be NULL.
+ *
+ * @return true iff the cipher is a CBC mode cipher.
+ */
+bool cipher_kt_mode_cbc(const cipher_kt_t *cipher)
+ __attribute__((nonnull));
+
+/**
+ * Check of the supplied cipher is a supported OFB or CFB mode cipher.
+ *
+ * @param cipher Static cipher parameters. May not be NULL.
+ *
+ * @return true iff the cipher is a OFB or CFB mode cipher.
+ */
+bool cipher_kt_mode_ofb_cfb(const cipher_kt_t *cipher)
+ __attribute__((nonnull));
+
/**
*
@@ -288,6 +308,16 @@ int cipher_ctx_block_size (const cipher_ctx_t *ctx);
int cipher_ctx_mode (const cipher_ctx_t *ctx);
/**
+ * Returns the static cipher parameters for this context.
+ *
+ * @param ctx Cipher's context. May not be NULL.
+ *
+ * @return Static cipher parameters for the supplied context.
+ */
+const cipher_kt_t *cipher_ctx_get_cipher_kt (const cipher_ctx_t *ctx)
+ __attribute__((nonnull));
+
+/**
* Resets the given cipher context, setting the IV to the specified value.
* Preserves the associated key information.
*
diff --git a/main/openvpn/src/openvpn/crypto_openssl.c b/main/openvpn/src/openvpn/crypto_openssl.c
index c3480e02..0ac89a19 100644
--- a/main/openvpn/src/openvpn/crypto_openssl.c
+++ b/main/openvpn/src/openvpn/crypto_openssl.c
@@ -40,6 +40,7 @@
#include "basic.h"
#include "buffer.h"
#include "integer.h"
+#include "crypto.h"
#include "crypto_backend.h"
#include <openssl/objects.h>
#include <openssl/evp.h>
@@ -253,7 +254,7 @@ show_available_ciphers ()
"used as a parameter to the --cipher option. The default\n"
"key size is shown as well as whether or not it can be\n"
"changed with the --keysize directive. Using a CBC mode\n"
- "is recommended.\n\n");
+ "is recommended. In static key mode only CBC mode is allowed.\n\n");
#endif
for (nid = 0; nid < 10000; ++nid) /* is there a better way to get the size of the nid list? */
@@ -261,17 +262,22 @@ show_available_ciphers ()
const EVP_CIPHER *cipher = EVP_get_cipherbynid (nid);
if (cipher)
{
- const unsigned int mode = EVP_CIPHER_mode (cipher);
- if (mode == EVP_CIPH_CBC_MODE
-#ifdef ALLOW_NON_CBC_CIPHERS
- || mode == EVP_CIPH_CFB_MODE || mode == EVP_CIPH_OFB_MODE
+ if (cipher_kt_mode_cbc(cipher)
+#ifdef ENABLE_OFB_CFB_MODE
+ || cipher_kt_mode_ofb_cfb(cipher)
#endif
)
- printf ("%s %d bit default key (%s)\n",
- OBJ_nid2sn (nid),
- EVP_CIPHER_key_length (cipher) * 8,
- ((EVP_CIPHER_flags (cipher) & EVP_CIPH_VARIABLE_LENGTH) ?
- "variable" : "fixed"));
+ {
+ const char *var_key_size =
+ (EVP_CIPHER_flags (cipher) & EVP_CIPH_VARIABLE_LENGTH) ?
+ "variable" : "fixed";
+ const char *ssl_only = cipher_kt_mode_ofb_cfb(cipher) ?
+ " (TLS client/server mode)" : "";
+
+ printf ("%s %d bit default key (%s)%s\n", OBJ_nid2sn (nid),
+ EVP_CIPHER_key_length (cipher) * 8, var_key_size,
+ ssl_only);
+ }
}
}
printf ("\n");
@@ -483,6 +489,29 @@ cipher_kt_mode (const EVP_CIPHER *cipher_kt)
return EVP_CIPHER_mode (cipher_kt);
}
+bool
+cipher_kt_mode_cbc(const cipher_kt_t *cipher)
+{
+ return cipher_kt_mode(cipher) == OPENVPN_MODE_CBC
+#ifdef EVP_CIPH_FLAG_AEAD_CIPHER
+ /* Exclude AEAD cipher modes, they require a different API */
+ && !(EVP_CIPHER_flags(cipher) & EVP_CIPH_FLAG_AEAD_CIPHER)
+#endif
+ ;
+}
+
+bool
+cipher_kt_mode_ofb_cfb(const cipher_kt_t *cipher)
+{
+ return (cipher_kt_mode(cipher) == OPENVPN_MODE_OFB ||
+ cipher_kt_mode(cipher) == OPENVPN_MODE_CFB)
+#ifdef EVP_CIPH_FLAG_AEAD_CIPHER
+ /* Exclude AEAD cipher modes, they require a different API */
+ && !(EVP_CIPHER_flags(cipher) & EVP_CIPH_FLAG_AEAD_CIPHER)
+#endif
+ ;
+}
+
/*
*
* Generic cipher context functions
@@ -536,6 +565,13 @@ cipher_ctx_mode (const EVP_CIPHER_CTX *ctx)
return EVP_CIPHER_CTX_mode (ctx);
}
+const cipher_kt_t *
+cipher_ctx_get_cipher_kt (const cipher_ctx_t *ctx)
+{
+ return EVP_CIPHER_CTX_cipher(ctx);
+}
+
+
int
cipher_ctx_reset (EVP_CIPHER_CTX *ctx, uint8_t *iv_buf)
{
diff --git a/main/openvpn/src/openvpn/crypto_polarssl.c b/main/openvpn/src/openvpn/crypto_polarssl.c
index 7dc8aa5b..1a986dbd 100644
--- a/main/openvpn/src/openvpn/crypto_polarssl.c
+++ b/main/openvpn/src/openvpn/crypto_polarssl.c
@@ -416,6 +416,19 @@ cipher_kt_mode (const cipher_info_t *cipher_kt)
return cipher_kt->mode;
}
+bool
+cipher_kt_mode_cbc(const cipher_kt_t *cipher)
+{
+ return cipher_kt_mode(cipher) == OPENVPN_MODE_CBC;
+}
+
+bool
+cipher_kt_mode_ofb_cfb(const cipher_kt_t *cipher)
+{
+ return (cipher_kt_mode(cipher) == OPENVPN_MODE_OFB ||
+ cipher_kt_mode(cipher) == OPENVPN_MODE_CFB);
+}
+
/*
*
@@ -464,6 +477,14 @@ int cipher_ctx_mode (const cipher_context_t *ctx)
return cipher_kt_mode(ctx->cipher_info);
}
+const cipher_kt_t *
+cipher_ctx_get_cipher_kt (const cipher_ctx_t *ctx)
+{
+ ASSERT(NULL != ctx);
+
+ return ctx->cipher_info;
+}
+
int cipher_ctx_reset (cipher_context_t *ctx, uint8_t *iv_buf)
{
int retval = cipher_reset(ctx);
diff --git a/main/openvpn/src/openvpn/helper.c b/main/openvpn/src/openvpn/helper.c
index d9eef03b..0ed0b2ba 100644
--- a/main/openvpn/src/openvpn/helper.c
+++ b/main/openvpn/src/openvpn/helper.c
@@ -232,6 +232,8 @@ helper_client_server (struct options *o)
* if !nopool:
* ifconfig-pool 10.8.0.2 10.8.0.254 255.255.255.0
* push "route-gateway 10.8.0.1"
+ * if route-gateway unset:
+ * route-gateway 10.8.0.2
*/
if (o->server_defined)
@@ -311,8 +313,10 @@ helper_client_server (struct options *o)
ifconfig_pool_verify_range (M_USAGE, o->ifconfig_pool_start, o->ifconfig_pool_end);
}
o->ifconfig_pool_netmask = o->server_netmask;
-
+
push_option (o, print_opt_route_gateway (o->server_network + 1, &o->gc), M_USAGE);
+ if (!o->route_default_gateway)
+ o->route_default_gateway = print_in_addr_t (o->server_network + 2, 0, &o->gc);
}
else
ASSERT (0);
diff --git a/main/openvpn/src/openvpn/init.c b/main/openvpn/src/openvpn/init.c
index 7dd61a20..6137588d 100644
--- a/main/openvpn/src/openvpn/init.c
+++ b/main/openvpn/src/openvpn/init.c
@@ -2150,7 +2150,7 @@ do_init_crypto_tls (struct context *c, const unsigned int flags)
options->use_iv);
/* In short form, unique datagram identifier is 32 bits, in long form 64 bits */
- packet_id_long_form = cfb_ofb_mode (&c->c1.ks.key_type);
+ packet_id_long_form = cipher_kt_mode_ofb_cfb (c->c1.ks.key_type.cipher);
/* Compute MTU parameters */
crypto_adjust_frame_parameters (&c->c2.frame,
@@ -3172,10 +3172,10 @@ managmenet_callback_network_change (void *arg)
if (c->c2.link_socket->sd == SOCKET_UNDEFINED)
return -1;
- /* Check if the client should translate the network change to a SIGUSR1 to
+ /* Check if the client should translate the network change to a SIGUSR1 to
reestablish the connection or just reprotect the socket */
- /* At the moment just assume that, for all settings that use pull
+ /* At the moment just assume that, for all settings that use pull
reestablishing the connection is required */
socketfd = c->c2.link_socket->sd;
diff --git a/main/openvpn/src/openvpn/options.c b/main/openvpn/src/openvpn/options.c
index addca14a..9ff2db5a 100644
--- a/main/openvpn/src/openvpn/options.c
+++ b/main/openvpn/src/openvpn/options.c
@@ -575,8 +575,8 @@ static const char usage_message[] =
" and optionally the root CA certificate.\n"
#endif
#ifdef ENABLE_X509ALTUSERNAME
- "--x509-username-field : Field used in x509 certificate to be username.\n"
- " Default is CN.\n"
+ "--x509-username-field : Field in x509 certificate containing the username.\n"
+ " Default is CN in the Subject field.\n"
#endif
"--verify-hash : Specify SHA1 fingerprint for level-1 cert.\n"
#ifdef WIN32
@@ -6881,10 +6881,28 @@ add_option (struct options *options,
#ifdef ENABLE_X509ALTUSERNAME
else if (streq (p[0], "x509-username-field") && p[1])
{
+ /* This option used to automatically upcase the fieldname passed as the
+ * option argument, e.g., "ou" became "OU". Now, this "helpfulness" is
+ * fine-tuned by only upcasing Subject field attribute names which consist
+ * of all lower-case characters. Mixed-case attributes such as
+ * "emailAddress" are left as-is. An option parameter having the "ext:"
+ * prefix for matching X.509v3 extended fields will also remain unchanged.
+ */
char *s = p[1];
+
VERIFY_PERMISSION (OPT_P_GENERAL);
- if( strncmp ("ext:",s,4) != 0 )
- while ((*s = toupper(*s)) != '\0') s++; /* Uppercase if necessary */
+ if (strncmp("ext:", s, 4) != 0)
+ {
+ size_t i = 0;
+ while (s[i] && !isupper(s[i])) i++;
+ if (strlen(s) == i)
+ {
+ while ((*s = toupper(*s)) != '\0') s++;
+ msg(M_WARN, "DEPRECATED FEATURE: automatically upcased the "
+ "--x509-username-field parameter to '%s'; please update your"
+ "configuration", p[1]);
+ }
+ }
options->x509_username_field = p[1];
}
#endif /* ENABLE_X509ALTUSERNAME */
diff --git a/main/openvpn/src/openvpn/route.c b/main/openvpn/src/openvpn/route.c
index bcc6fcee..562af9fe 100644
--- a/main/openvpn/src/openvpn/route.c
+++ b/main/openvpn/src/openvpn/route.c
@@ -1535,6 +1535,17 @@ add_route (struct route_ipv4 *r,
argv_msg (D_ROUTE, &argv);
status = openvpn_execve_check (&argv, es, 0, "ERROR: OpenBSD/NetBSD route add command failed");
+#elif defined(TARGET_AIX)
+
+ {
+ int netbits = netmask_to_netbits2(r->netmask);
+ argv_printf (&argv, "%s add -net %s/%d %s",
+ ROUTE_PATH,
+ network, netbits, gateway);
+ argv_msg (D_ROUTE, &argv);
+ status = openvpn_execve_check (&argv, es, 0, "ERROR: AIX route add command failed");
+ }
+
#else
msg (M_FATAL, "Sorry, but I don't know how to do 'route' commands on this operating system. Try putting your routes in a --route-up script");
#endif
@@ -1754,6 +1765,14 @@ add_route_ipv6 (struct route_ipv6 *r6, const struct tuntap *tt, unsigned int fla
argv_msg (D_ROUTE, &argv);
status = openvpn_execve_check (&argv, es, 0, "ERROR: NetBSD route add -inet6 command failed");
+#elif defined(TARGET_AIX)
+
+ argv_printf (&argv, "%s add -inet6 %s/%d %s",
+ ROUTE_PATH,
+ network, r6->netbits, gateway);
+ argv_msg (D_ROUTE, &argv);
+ status = openvpn_execve_check (&argv, es, 0, "ERROR: AIX route add command failed");
+
#else
msg (M_FATAL, "Sorry, but I don't know how to do 'route ipv6' commands on this operating system. Try putting your routes in a --route-up script");
#endif
@@ -1912,8 +1931,21 @@ delete_route (struct route_ipv4 *r,
argv_msg (D_ROUTE, &argv);
openvpn_execve_check (&argv, es, 0, "ERROR: OpenBSD/NetBSD route delete command failed");
+
#elif defined(TARGET_ANDROID)
msg (M_NONFATAL, "Sorry, deleting routes on Android is not possible. The VpnService API allows routes to be set on connect only.");
+
+#elif defined(TARGET_AIX)
+
+ {
+ int netbits = netmask_to_netbits2(r->netmask);
+ argv_printf (&argv, "%s delete -net %s/%d %s",
+ ROUTE_PATH,
+ network, netbits, gateway);
+ argv_msg (D_ROUTE, &argv);
+ openvpn_execve_check (&argv, es, 0, "ERROR: AIX route delete command failed");
+ }
+
#else
msg (M_FATAL, "Sorry, but I don't know how to do 'route' commands on this operating system. Try putting your routes in a --route-up script");
#endif
@@ -2084,6 +2116,14 @@ delete_route_ipv6 (const struct route_ipv6 *r6, const struct tuntap *tt, unsigne
argv_msg (D_ROUTE, &argv);
openvpn_execve_check (&argv, es, 0, "ERROR: NetBSD route delete -inet6 command failed");
+#elif defined(TARGET_AIX)
+
+ argv_printf (&argv, "%s delete -inet6 %s/%d %s",
+ ROUTE_PATH,
+ network, r6->netbits, gateway);
+ argv_msg (D_ROUTE, &argv);
+ openvpn_execve_check (&argv, es, 0, "ERROR: AIX route add command failed");
+
#else
msg (M_FATAL, "Sorry, but I don't know how to do 'route ipv6' commands on this operating system. Try putting your routes in a --route-down script");
#endif
@@ -2921,6 +2961,26 @@ netmask_to_netbits (const in_addr_t network, const in_addr_t netmask, int *netbi
return false;
}
+/* similar to netmask_to_netbits(), but don't mess with base address
+ * etc., just convert to netbits - non-mappable masks are returned as "-1"
+ */
+int netmask_to_netbits2 (in_addr_t netmask)
+{
+ int i;
+ const int addrlen = sizeof (in_addr_t) * 8;
+
+ for (i = 0; i <= addrlen; ++i)
+ {
+ in_addr_t mask = netbits_to_netmask (i);
+ if (mask == netmask)
+ {
+ return i;
+ }
+ }
+ return -1;
+}
+
+
/*
* get_bypass_addresses() is used by the redirect-gateway bypass-x
* functions to build a route bypass to selected DHCP/DNS servers,
diff --git a/main/openvpn/src/openvpn/ssl.c b/main/openvpn/src/openvpn/ssl.c
index 44f50808..929f95fa 100644
--- a/main/openvpn/src/openvpn/ssl.c
+++ b/main/openvpn/src/openvpn/ssl.c
@@ -998,22 +998,6 @@ reset_session (struct tls_multi *multi, struct tls_session *session)
tls_session_init (multi, session);
}
-#if 0
-/*
- * Transmit a TLS reset on our untrusted channel.
- */
-static void
-initiate_untrusted_session (struct tls_multi *multi, struct sockaddr_in *to)
-{
- struct tls_session *session = &multi->session[TM_UNTRUSTED];
- struct key_state *ks = &session->key[KS_PRIMARY];
-
- reset_session (multi, session);
- ks->remote_addr = *to;
- msg (D_TLS_DEBUG_LOW, "TLS: initiate_untrusted_session: addr=%s", print_sockaddr (to));
-}
-#endif
-
/*
* Used to determine in how many seconds we should be
* called again.
diff --git a/main/openvpn/src/openvpn/ssl_openssl.c b/main/openvpn/src/openvpn/ssl_openssl.c
index c9d2d26d..adf3ae6f 100644
--- a/main/openvpn/src/openvpn/ssl_openssl.c
+++ b/main/openvpn/src/openvpn/ssl_openssl.c
@@ -270,7 +270,8 @@ tls_ctx_restrict_ciphers(struct tls_root_ctx *ctx, const char *ciphers)
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))
+ 0 != memcmp (&ciphers[begin_of_cipher], cipher_pair->iana_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);
diff --git a/main/openvpn/src/openvpn/ssl_openssl.h b/main/openvpn/src/openvpn/ssl_openssl.h
index fc2052cb..97dc7422 100644
--- a/main/openvpn/src/openvpn/ssl_openssl.h
+++ b/main/openvpn/src/openvpn/ssl_openssl.h
@@ -33,6 +33,17 @@
#include <openssl/ssl.h>
/**
+ * SSL_OP_NO_TICKET tells OpenSSL to disable "stateless session resumption",
+ * as this is something we do not want nor need, but could potentially be
+ * used for a future attack. For compatibility reasons we keep building if the
+ * OpenSSL version is too old (pre-0.9.8f) to support stateless session
+ * resumption (and the accompanying SSL_OP_NO_TICKET flag).
+ */
+#ifndef SSL_OP_NO_TICKET
+# define SSL_OP_NO_TICKET 0
+#endif
+
+/**
* Structure that wraps the TLS context. Contents differ depending on the
* SSL library used.
*/
diff --git a/main/openvpn/src/openvpn/ssl_verify_openssl.c b/main/openvpn/src/openvpn/ssl_verify_openssl.c
index 2482eaa4..cbcff022 100644
--- a/main/openvpn/src/openvpn/ssl_verify_openssl.c
+++ b/main/openvpn/src/openvpn/ssl_verify_openssl.c
@@ -591,12 +591,12 @@ x509_verify_crl(const char *crl_file, X509 *peer_cert, const char *subject)
in = BIO_new_file (crl_file, "r");
if (in == NULL) {
- msg (M_ERR, "CRL: cannot read: %s", crl_file);
+ msg (M_WARN, "CRL: cannot read: %s", crl_file);
goto end;
}
crl=PEM_read_bio_X509_CRL(in,NULL,NULL,NULL);
if (crl == NULL) {
- msg (M_ERR, "CRL: cannot read CRL from file %s", crl_file);
+ msg (M_WARN, "CRL: cannot read CRL from file %s", crl_file);
goto end;
}
diff --git a/main/openvpn/src/openvpn/ssl_verify_polarssl.c b/main/openvpn/src/openvpn/ssl_verify_polarssl.c
index 7e8b5179..2b7c214f 100644
--- a/main/openvpn/src/openvpn/ssl_verify_polarssl.c
+++ b/main/openvpn/src/openvpn/ssl_verify_polarssl.c
@@ -371,9 +371,12 @@ x509_verify_crl(const char *crl_file, x509_crt *cert, const char *subject)
result_t retval = FAILURE;
x509_crl crl = {0};
- if (x509_crl_parse_file(&crl, crl_file) != 0)
+ int polar_retval = x509_crl_parse_file(&crl, crl_file);
+ if (polar_retval != 0)
{
- msg (M_ERR, "CRL: cannot read CRL from file %s", crl_file);
+ char errstr[128];
+ polarssl_strerror(polar_retval, errstr, sizeof(errstr));
+ msg (M_WARN, "CRL: cannot read CRL from file %s (%s)", crl_file, errstr);
goto end;
}
diff --git a/main/openvpn/src/openvpn/syshead.h b/main/openvpn/src/openvpn/syshead.h
index 771c4fc1..dc511cbc 100644
--- a/main/openvpn/src/openvpn/syshead.h
+++ b/main/openvpn/src/openvpn/syshead.h
@@ -349,6 +349,14 @@
#endif /* TARGET_DRAGONFLY */
+#ifdef TARGET_DARWIN
+
+#ifdef HAVE_NETINET_TCP_H
+#include <netinet/tcp.h>
+#endif
+
+#endif /* TARGET_DARWIN */
+
#ifdef WIN32
#include <iphlpapi.h>
#include <ntddndis.h>
diff --git a/main/openvpn/src/openvpn/tun.c b/main/openvpn/src/openvpn/tun.c
index 482f6402..e92edc2f 100644
--- a/main/openvpn/src/openvpn/tun.c
+++ b/main/openvpn/src/openvpn/tun.c
@@ -1194,6 +1194,43 @@ do_ifconfig (struct tuntap *tt,
openvpn_execve_check (&argv, es, S_FATAL, "FreeBSD ifconfig inet6 failed");
}
+#elif defined(TARGET_AIX)
+ {
+ /* AIX ifconfig will complain if it can't find ODM path in env */
+ struct env_set *aix_es = env_set_create (NULL);
+ env_set_add( aix_es, "ODMDIR=/etc/objrepos" );
+
+ if (tun)
+ msg(M_FATAL, "no tun support on AIX (canthappen)");
+
+ /* example: ifconfig tap0 172.30.1.1 netmask 255.255.254.0 up */
+ argv_printf (&argv,
+ "%s %s %s netmask %s mtu %d up",
+ IFCONFIG_PATH,
+ actual,
+ ifconfig_local,
+ ifconfig_remote_netmask,
+ tun_mtu
+ );
+
+ argv_msg (M_INFO, &argv);
+ openvpn_execve_check (&argv, aix_es, S_FATAL, "AIX ifconfig failed");
+ tt->did_ifconfig = true;
+
+ if ( do_ipv6 )
+ {
+ argv_printf (&argv,
+ "%s %s inet6 %s/%d",
+ IFCONFIG_PATH,
+ actual,
+ ifconfig_ipv6_local,
+ tt->netbits_ipv6
+ );
+ argv_msg (M_INFO, &argv);
+ openvpn_execve_check (&argv, aix_es, S_FATAL, "AIX ifconfig inet6 failed");
+ }
+ env_set_destroy (aix_es);
+ }
#elif defined (WIN32)
{
/*
@@ -2825,6 +2862,139 @@ read_tun (struct tuntap* tt, uint8_t *buf, int len)
return read (tt->fd, buf, len);
}
+#elif defined(TARGET_AIX)
+
+void
+open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt)
+{
+ char tunname[256];
+ char dynamic_name[20];
+ const char *p;
+ struct argv argv;
+
+ if (tt->type == DEV_TYPE_NULL)
+ {
+ open_null (tt);
+ return;
+ }
+
+ if ( tt->type == DEV_TYPE_TUN)
+ {
+ msg(M_FATAL, "no support for 'tun' devices on AIX" );
+ }
+
+ if ( strncmp( dev, "tap", 3 ) != 0 || dev_node )
+ {
+ msg(M_FATAL, "'--dev %s' and/or '--dev-node' not supported on AIX, use '--dev tap0', 'tap1', etc.", dev );
+ }
+
+ if ( strcmp( dev, "tap" ) == 0 ) /* find first free tap dev */
+ { /* (= no /dev/tapN node) */
+ int i;
+ for (i=0; i<99; i++ )
+ {
+ openvpn_snprintf (tunname, sizeof (tunname), "/dev/tap%d", i);
+ if ( access( tunname, F_OK ) < 0 && errno == ENOENT )
+ { break; }
+ }
+ if ( i >= 99 )
+ msg( M_FATAL, "cannot find unused tap device" );
+
+ openvpn_snprintf( dynamic_name, sizeof(dynamic_name), "tap%d", i );
+ dev = dynamic_name;
+ }
+ else /* name given, sanity check */
+ {
+ /* ensure that dev name is "tap+<digits>" *only* */
+ p = &dev[3];
+ while( isdigit(*p) ) p++;
+ if ( *p != '\0' )
+ msg( M_FATAL, "TAP device name must be '--dev tapNNNN'" );
+
+ openvpn_snprintf (tunname, sizeof (tunname), "/dev/%s", dev);
+ }
+
+ /* pre-existing device?
+ */
+ if ( access( tunname, F_OK ) < 0 && errno == ENOENT )
+ {
+
+ /* tunnel device must be created with 'ifconfig tapN create'
+ */
+ struct env_set *es = env_set_create (NULL);
+ argv_init (&argv);
+ argv_printf (&argv, "%s %s create", IFCONFIG_PATH, dev);
+ argv_msg (M_INFO, &argv);
+ env_set_add( es, "ODMDIR=/etc/objrepos" );
+ openvpn_execve_check (&argv, es, S_FATAL, "AIX 'create tun interface' failed");
+ env_set_destroy (es);
+ }
+ else
+ {
+ /* we didn't make it, we're not going to break it */
+ tt->persistent_if = TRUE;
+ }
+
+ if ((tt->fd = open (tunname, O_RDWR)) < 0)
+ {
+ msg (M_ERR, "Cannot open TAP device '%s'", tunname);
+ }
+
+ set_nonblock (tt->fd);
+ set_cloexec (tt->fd); /* don't pass fd to scripts */
+ msg (M_INFO, "TUN/TAP device %s opened", tunname);
+
+ /* tt->actual_name is passed to up and down scripts and used as the ifconfig dev name */
+ tt->actual_name = string_alloc(dev, NULL);
+}
+
+/* tap devices need to be manually destroyed on AIX
+ */
+void
+close_tun (struct tuntap* tt)
+{
+ struct gc_arena gc = gc_new ();
+ struct argv argv;
+ struct env_set *es = env_set_create (NULL);
+
+ if (!tt) return;
+
+ /* persistent devices need IP address unconfig, others need destroyal
+ */
+ argv_init (&argv);
+
+ if (tt->persistent_if)
+ {
+ argv_printf (&argv, "%s %s 0.0.0.0 down",
+ IFCONFIG_PATH, tt->actual_name);
+ }
+ else
+ {
+ argv_printf (&argv, "%s %s destroy",
+ IFCONFIG_PATH, tt->actual_name);
+ }
+
+ close_tun_generic (tt);
+ argv_msg (M_INFO, &argv);
+ env_set_add( es, "ODMDIR=/etc/objrepos" );
+ openvpn_execve_check (&argv, es, 0, "AIX 'destroy tap interface' failed (non-critical)");
+
+ free(tt);
+ env_set_destroy (es);
+}
+
+int
+write_tun (struct tuntap* tt, uint8_t *buf, int len)
+{
+ return write (tt->fd, buf, len);
+}
+
+int
+read_tun (struct tuntap* tt, uint8_t *buf, int len)
+{
+ return read (tt->fd, buf, len);
+}
+
#elif defined(WIN32)
int
diff --git a/main/openvpn/tests/t_client.sh.in b/main/openvpn/tests/t_client.sh.in
index 52c5ed1a..d4f7c4ab 100755
--- a/main/openvpn/tests/t_client.sh.in
+++ b/main/openvpn/tests/t_client.sh.in
@@ -134,6 +134,12 @@ get_ifconfig_route()
@NETSTAT@ -rn | awk '$3 !~ /^UHL/ { print $1,$2,$3,$6 }'
return
;;
+ AIX)
+ echo "-- AIX --"
+ @IFCONFIG@ -a | egrep "(flags=|inet)"
+ @NETSTAT@ -rn | awk '$3 !~ /^UHL/ { print $1,$2,$3,$6 }'
+ return
+ ;;
esac
echo "get_ifconfig_route(): no idea how to get info on your OS. FAIL." >&2
diff --git a/main/openvpn/tests/t_lpback.sh b/main/openvpn/tests/t_lpback.sh
index 40767a1b..8f88ad92 100755
--- a/main/openvpn/tests/t_lpback.sh
+++ b/main/openvpn/tests/t_lpback.sh
@@ -2,6 +2,7 @@
#
# t_lpback.sh - script to test OpenVPN's crypto loopback
# Copyright (C) 2005 Matthias Andree
+# Copyright (C) 2014 Steffan Karger
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
@@ -18,15 +19,39 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA.
-set -e
+set -eu
top_builddir="${top_builddir:-..}"
trap "rm -f key.$$ log.$$ ; trap 0 ; exit 77" 1 2 15
trap "rm -f key.$$ log.$$ ; exit 1" 0 3
+
+# Get list of supported ciphers from openvpn --show-ciphers output
+CIPHERS=$(${top_builddir}/src/openvpn/openvpn --show-ciphers | \
+ sed -e '1,/^$/d' -e s'/ .*//' -e '/^\s*$/d' | sort)
+
+# SK, 2014-06-04: currently the DES-EDE3-CFB1 implementation of OpenSSL is
+# broken (see http://rt.openssl.org/Ticket/Display.html?id=2867), so exclude
+# that cipher from this test.
+# GD, 2014-07-06 so is DES-CFB1
+# GD, 2014-07-06 do not test RC5-* either (fails on NetBSD w/o libcrypto_rc5)
+CIPHERS=$(echo "$CIPHERS" | egrep -v '^(DES-EDE3-CFB1|DES-CFB1|RC5-)' )
+
"${top_builddir}/src/openvpn/openvpn" --genkey --secret key.$$
set +e
-( "${top_builddir}/src/openvpn/openvpn" --test-crypto --secret key.$$ ) >log.$$ 2>&1
-e=$?
-if [ $e != 0 ] ; then cat log.$$ ; fi
+
+e=0
+for cipher in ${CIPHERS}
+do
+ echo -n "Testing cipher ${cipher}... "
+ ( "${top_builddir}/src/openvpn/openvpn" --test-crypto --secret key.$$ --cipher ${cipher} ) >log.$$ 2>&1
+ if [ $? != 0 ] ; then
+ echo "FAILED"
+ cat log.$$
+ e=1
+ else
+ echo "OK"
+ fi
+done
+
rm key.$$ log.$$
trap 0
exit $e