From b47e50890b9771f3dbc885aeebc4dfc8c869ddd1 Mon Sep 17 00:00:00 2001 From: "William A. Rowe Jr" Date: Thu, 2 Jun 2016 22:29:32 +0000 Subject: [PATCH] Correct the behavior and interaction between SSLProxyCheckPeer[CN|Name], such that disabling either disables both, and that enabling either will trigger the more comprehensive SSLProxyCheckPeerName behavior. Only a single configuration remains to enable the legacy behavior, which is to explicitly disable SSLProxyCheckPeerName and enable SSLProxyCheckPeerCN. Major refactoring leads us to an alternate implementation for 2.4.21; https://github.com/wrowe/patches/blob/master/fix_proxy_check_peer-2.4.x.patch git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1746645 13f79535-47bb-0310-9956-ffa450edef68 --- docs/manual/mod/mod_ssl.xml | 60 ++++++++++++++++++++++++++----------- modules/ssl/ssl_engine_io.c | 4 ++- 2 files changed, 45 insertions(+), 19 deletions(-) diff --git a/docs/manual/mod/mod_ssl.xml b/docs/manual/mod/mod_ssl.xml index 2927eea2d4f..08348df192e 100644 --- a/docs/manual/mod/mod_ssl.xml +++ b/docs/manual/mod/mod_ssl.xml @@ -1917,17 +1917,32 @@ SSLProxyCheckPeerExpire on

This directive sets whether the remote server certificate's CN field is compared against the hostname of the request URL. If both are not equal -a 502 status code (Bad Gateway) is sent. +a 502 status code (Bad Gateway) is sent. SSLProxyCheckPeerCN is +superseded by SSLProxyCheckPeerName +in release 2.4.5 and later.

-In 2.4.5 and later, SSLProxyCheckPeerCN has been superseded by -SSLProxyCheckPeerName, and its -setting is only taken into account when -SSLProxyCheckPeerName off is specified at the same time. +In all releases 2.4.5 through 2.4.20, setting +SSLProxyCheckPeerName off was sufficient to enable this behavior +(as the SSLProxyCheckPeerCN default was on.) In +these releases, both directives must be set to off to completely +avoid remote server certificate name validation. Many users reported this +to be very confusing. +

+

+As of release 2.4.21, all configurations which enable either one of the +SSLProxyCheckPeerName or SSLProxyCheckPeerCN options +will use the new SSLProxyCheckPeerName +behavior, and all configurations which disable either one of the +SSLProxyCheckPeerName or SSLProxyCheckPeerCN options +will supress all remote server certificate name validation. Only the following +configuration will trigger the legacy certificate CN comparison in 2.4.21 and +later releases;

Example SSLProxyCheckPeerCN on +SSLProxyCheckPeerName off @@ -1945,21 +1960,30 @@ SSLProxyCheckPeerCN on

-This directive configures host name checking for server certificates -when mod_ssl is acting as an SSL client. The check will -succeed if the host name from the request URI is found in -either the subjectAltName extension or (one of) the CN attribute(s) -in the certificate's subject. If the check fails, the SSL request -is aborted and a 502 status code (Bad Gateway) is returned. -The directive supersedes SSLProxyCheckPeerCN, -which only checks for the expected host name in the first CN attribute. +This directive configures host name checking for server certificates when +mod_ssl is acting as an SSL client. The check will succeed if the host name +from the request URI matches one of the CN attribute(s) of the certificate's +subject, or matches the subjectAltName extension. If the check fails, the SSL +request is aborted and a 502 status code (Bad Gateway) is returned. +

+

+Wildcard matching is supported for specific cases: an subjectAltName entry +of type dNSName, or CN attributes starting with *. will match +with any host name of the same number of name elements and the same suffix. +E.g. *.example.org will match foo.example.org, +but will not match foo.bar.example.org, because the number of +elements in the respective host names differs.

-Wildcard matching is supported in one specific flavor: subjectAltName entries -of type dNSName or CN attributes starting with *. will match -for any DNS name with the same number of labels and the same suffix -(i.e., *.example.org matches for foo.example.org, -but not for foo.bar.example.org). +This feature was introduced in 2.4.5 and superseded the behavior of the +SSLProxyCheckPeerCN directive, which +only tested the exact value in the first CN attribute against the host name. +However, many users were confused by the behavior of using these directives +individually, so the mutual behavior of SSLProxyCheckPeerName +and SSLProxyCheckPeerCN directives were improved in release +2.4.21. See the SSLProxyCheckPeerCN +directive description for the original behavior and details of these +improvements.

diff --git a/modules/ssl/ssl_engine_io.c b/modules/ssl/ssl_engine_io.c index 0737640ada7..ea2319328d9 100644 --- a/modules/ssl/ssl_engine_io.c +++ b/modules/ssl/ssl_engine_io.c @@ -1189,6 +1189,8 @@ static apr_status_t ssl_io_filter_handshake(ssl_filter_ctx_t *filter_ctx) } } if ((sc->proxy_ssl_check_peer_name != SSL_ENABLED_FALSE) && + ((sc->proxy_ssl_check_peer_cn != SSL_ENABLED_FALSE) || + (sc->proxy_ssl_check_peer_name == SSL_ENABLED_TRUE)) && hostname_note) { apr_table_unset(c->notes, "proxy-request-hostname"); if (!cert @@ -1200,7 +1202,7 @@ static apr_status_t ssl_io_filter_handshake(ssl_filter_ctx_t *filter_ctx) "for hostname %s", hostname_note); } } - else if ((sc->proxy_ssl_check_peer_cn != SSL_ENABLED_FALSE) && + else if ((sc->proxy_ssl_check_peer_cn == SSL_ENABLED_TRUE) && hostname_note) { const char *hostname; int match = 0; -- 2.47.2