From: Jim Jagielski Date: Mon, 14 Apr 2014 12:47:49 +0000 (+0000) Subject: Merge r1572630, r1572611, r1572967, r1573229 from trunk: X-Git-Tag: 2.4.10~355 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=be6dcf150dfd4963683cd849ddc6be6ff212d2f7;p=apache Merge r1572630, r1572611, r1572967, r1573229 from trunk: Redo what was reverted in r1572627. Don't reuse a SSL backend connection whose SNI differs. PR 55782. This may happen when ProxyPreserveHost is on and the proxy-worker handles connections to different Hosts. Follows up r1572606. MMN minor bump required by proxy_conn_rec change. mod_proxy: follows up r1572630. Don't reuse a SSL backend connection with no SNI for a request requiring SNI. mod_proxy: Add comment and avoid ternary operator as condition (no functional change). Submitted by: ylavic Reviewed/backported by: jim git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1587201 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/STATUS b/STATUS index 227fb5cbc0..842cf10581 100644 --- a/STATUS +++ b/STATUS @@ -100,16 +100,6 @@ RELEASE SHOWSTOPPERS: PATCHES ACCEPTED TO BACKPORT FROM TRUNK: [ start all new proposals below, under PATCHES PROPOSED. ] - * mod_proxy: Don't reuse a SSL backend connection whose SNI differs. PR 55782. - This may happen when ProxyPreserveHost is on and the proxy-worker - handles connections to different Hosts. - trunk patch: http://svn.apache.org/r1572630 - http://svn.apache.org/r1572611 (MMN minor bump) - http://svn.apache.org/r1572967 - http://svn.apache.org/r1573229 - 2.4.x patch: trunk works (modulo MMN) - +1: ylavic, rpluem, jim - PATCHES PROPOSED TO BACKPORT FROM TRUNK: diff --git a/include/ap_mmn.h b/include/ap_mmn.h index 79f26f4072..8918e1a5f3 100644 --- a/include/ap_mmn.h +++ b/include/ap_mmn.h @@ -426,6 +426,7 @@ * 20120211.29 (2.4.7-dev) Add uds_path to proxy_conn_rec * 20120211.30 (2.4.7-dev) REWRITE_REDIRECT_HANDLER_NAME in mod_rewrite.h * 20120211.31 (2.4.7-dev) Add ap_proxy_port_of_scheme() + * 20120211.32 (2.4.10-dev) Add SSL reusable SNI to mod_proxy.h's proxy_conn_rec */ #define MODULE_MAGIC_COOKIE 0x41503234UL /* "AP24" */ @@ -433,7 +434,7 @@ #ifndef MODULE_MAGIC_NUMBER_MAJOR #define MODULE_MAGIC_NUMBER_MAJOR 20120211 #endif -#define MODULE_MAGIC_NUMBER_MINOR 31 /* 0...n */ +#define MODULE_MAGIC_NUMBER_MINOR 32 /* 0...n */ /** * Determine if the server's current MODULE_MAGIC_NUMBER is at least a diff --git a/modules/proxy/mod_proxy.h b/modules/proxy/mod_proxy.h index eb0106d6bc..67a9015be9 100644 --- a/modules/proxy/mod_proxy.h +++ b/modules/proxy/mod_proxy.h @@ -254,6 +254,7 @@ typedef struct { * filter chain or not */ unsigned int inreslist:1; /* connection in apr_reslist? */ const char *uds_path; /* Unix domain socket path */ + const char *ssl_hostname;/* Hostname (SNI) in use by SSL connection */ } proxy_conn_rec; typedef struct { diff --git a/modules/proxy/mod_proxy_http.c b/modules/proxy/mod_proxy_http.c index 3aec4cfea8..a35c0a9f71 100644 --- a/modules/proxy/mod_proxy_http.c +++ b/modules/proxy/mod_proxy_http.c @@ -1977,25 +1977,10 @@ static int proxy_http_handler(request_rec *r, proxy_worker *worker, * requested, such that mod_ssl can check if it is requested to do * so. */ - if (is_ssl) { - proxy_dir_conf *dconf; - const char *ssl_hostname; - - /* - * In the case of ProxyPreserveHost on use the hostname of - * the request if present otherwise use the one from the - * backend request URI. - */ - dconf = ap_get_module_config(r->per_dir_config, &proxy_module); - if ((dconf->preserve_host != 0) && (r->hostname != NULL)) { - ssl_hostname = r->hostname; - } - else { - ssl_hostname = uri->hostname; - } - - apr_table_set(backend->connection->notes, "proxy-request-hostname", - ssl_hostname); + if (backend->ssl_hostname) { + apr_table_setn(backend->connection->notes, + "proxy-request-hostname", + backend->ssl_hostname); } } diff --git a/modules/proxy/proxy_util.c b/modules/proxy/proxy_util.c index d05f0cdcce..d3bc1d0457 100644 --- a/modules/proxy/proxy_util.c +++ b/modules/proxy/proxy_util.c @@ -1402,6 +1402,7 @@ static void socket_cleanup(proxy_conn_rec *conn) { conn->sock = NULL; conn->connection = NULL; + conn->ssl_hostname = NULL; apr_pool_clear(conn->scpool); } @@ -2300,6 +2301,40 @@ ap_proxy_determine_connection(apr_pool_t *p, request_rec *r, return ap_proxyerror(r, HTTP_FORBIDDEN, "Connect to remote machine blocked"); } + /* + * When SSL is configured, determine the hostname (SNI) for the request + * and save it in conn->ssl_hostname. Close any reused connection whose + * SNI differs. + */ + if (conn->is_ssl) { + proxy_dir_conf *dconf; + const char *ssl_hostname; + /* + * In the case of ProxyPreserveHost on use the hostname of + * the request if present otherwise use the one from the + * backend request URI. + */ + dconf = ap_get_module_config(r->per_dir_config, &proxy_module); + if (dconf->preserve_host) { + ssl_hostname = r->hostname; + } + else { + ssl_hostname = conn->hostname; + } + /* + * Close if a SNI is in use but this request requires no or + * a different one, or no SNI is in use but one is required. + */ + if ((conn->ssl_hostname && (!ssl_hostname || + strcasecmp(conn->ssl_hostname, + ssl_hostname) != 0)) || + (!conn->ssl_hostname && ssl_hostname && conn->sock)) { + socket_cleanup(conn); + } + if (conn->ssl_hostname == NULL) { + conn->ssl_hostname = apr_pstrdup(conn->scpool, ssl_hostname); + } + } ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00947) "connected %s to %s:%d", *url, conn->hostname, conn->port); return OK;