summaryrefslogtreecommitdiffstats
path: root/src/openvpn
diff options
context:
space:
mode:
authorHeiko Hund <heiko.hund@sophos.com>2013-03-07 16:36:41 +0100
committerGert Doering <gert@greenie.muc.de>2013-03-07 20:31:59 +0100
commitf6e12862cefd054eb1a44c18ea1dfb4cba7d007a (patch)
tree51e3ce54b2e8fcb3feac2a3252efc16ccecc633f /src/openvpn
parent0f92b3b4170dab29aaf5cb4e6a0d00d37bf418b4 (diff)
downloadopenvpn-f6e12862cefd054eb1a44c18ea1dfb4cba7d007a.tar.gz
openvpn-f6e12862cefd054eb1a44c18ea1dfb4cba7d007a.tar.xz
openvpn-f6e12862cefd054eb1a44c18ea1dfb4cba7d007a.zip
add new option for X.509 name verification
Add the option --verify-x509-name to provide the functionality of the now deprecated --tls-remote. The new option accepts RFC 2253 subject DNs only and compares RDN or RDN prefix only if configured explicitly. Signed-off-by: Heiko Hund <heiko.hund@sophos.com> Acked-by: Arne Schwabe <arne@rfc2549.org> Message-Id: 1362670601-18660-1-git-send-email-heiko.hund@sophos.com URL: http://article.gmane.org/gmane.network.openvpn.devel/7376 Signed-off-by: Gert Doering <gert@greenie.muc.de> (cherry picked from commit 9f0fc745664fd0fc6a1c6785e101bf912088db16)
Diffstat (limited to 'src/openvpn')
-rw-r--r--src/openvpn/init.c7
-rw-r--r--src/openvpn/options.c94
-rw-r--r--src/openvpn/options.h3
-rw-r--r--src/openvpn/ssl_common.h3
-rw-r--r--src/openvpn/ssl_verify.c15
-rw-r--r--src/openvpn/ssl_verify.h6
6 files changed, 105 insertions, 23 deletions
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/options.c b/src/openvpn/options.c
index 7fda76f..8592955 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"
@@ -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);
@@ -6514,27 +6514,97 @@ add_option (struct options *options,
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);
- /*
- * Enable legacy openvpn format for DNs that have not been converted
- * yet and X.509 common names (not containing an '=' or ', ')
- */
- if (p[1][0] == '/' || !strchr (p[1], '=') || !strstr (p[1], ", "))
- compat_flag (COMPAT_FLAG_SET | COMPAT_NAMES);
- 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/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_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