From e76e04c3f05538de220b6f5669002edabc0e865b Mon Sep 17 00:00:00 2001 From: Arne Schwabe Date: Thu, 7 Mar 2013 22:28:38 +0100 Subject: Update openvpn src to git version 839a41ac3d4253ad048e93c84f2291fc684c44d4 (include x509-verify-name) (closes issue #144) --HG-- extra : rebase_source : d93dcf4130eccf3a136850495e382942eb675a8e --- openvpn/src/openvpn/init.c | 7 +-- openvpn/src/openvpn/options.c | 115 ++++++++++++++++++++++++++++++++++----- openvpn/src/openvpn/options.h | 3 +- openvpn/src/openvpn/proxy.c | 4 +- openvpn/src/openvpn/ssl_common.h | 3 +- openvpn/src/openvpn/ssl_verify.c | 15 +++-- openvpn/src/openvpn/ssl_verify.h | 6 ++ openvpn/src/openvpn/syshead.h | 4 ++ 8 files changed, 130 insertions(+), 27 deletions(-) (limited to 'openvpn/src') diff --git a/openvpn/src/openvpn/init.c b/openvpn/src/openvpn/init.c index 28121235..be2ca9df 100644 --- a/openvpn/src/openvpn/init.c +++ b/openvpn/src/openvpn/init.c @@ -2236,7 +2236,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; @@ -2498,12 +2499,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/openvpn/src/openvpn/options.c b/openvpn/src/openvpn/options.c index 64c81cf2..8f0112ad 100644 --- a/openvpn/src/openvpn/options.c +++ b/openvpn/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" @@ -1599,7 +1599,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); { @@ -2115,7 +2116,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"); } @@ -2287,7 +2287,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); @@ -3746,9 +3746,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); @@ -5474,13 +5478,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); @@ -6426,10 +6423,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/openvpn/src/openvpn/options.h b/openvpn/src/openvpn/options.h index 909cb38a..e5de2f10 100644 --- a/openvpn/src/openvpn/options.h +++ b/openvpn/src/openvpn/options.h @@ -510,8 +510,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/openvpn/src/openvpn/proxy.c b/openvpn/src/openvpn/proxy.c index 17748504..b4c917a8 100644 --- a/openvpn/src/openvpn/proxy.c +++ b/openvpn/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/openvpn/src/openvpn/ssl_common.h b/openvpn/src/openvpn/ssl_common.h index cb259a96..c62294f5 100644 --- a/openvpn/src/openvpn/ssl_common.h +++ b/openvpn/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/openvpn/src/openvpn/ssl_verify.c b/openvpn/src/openvpn/ssl_verify.c index cac46e98..e651a8e0 100644 --- a/openvpn/src/openvpn/ssl_verify.c +++ b/openvpn/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/openvpn/src/openvpn/ssl_verify.h b/openvpn/src/openvpn/ssl_verify.h index 1d201523..e0bcba42 100644 --- a/openvpn/src/openvpn/ssl_verify.h +++ b/openvpn/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/openvpn/src/openvpn/syshead.h b/openvpn/src/openvpn/syshead.h index 163d2bb2..db02c237 100644 --- a/openvpn/src/openvpn/syshead.h +++ b/openvpn/src/openvpn/syshead.h @@ -307,6 +307,10 @@ #include #endif +#ifdef HAVE_NETINET_TCP_H +#include +#endif + #ifdef HAVE_NET_IF_TUN_H #include #endif -- cgit v1.2.3