]> granicus.if.org Git - apache/commitdiff
Merge r1572630, r1572611, r1572967, r1573229 from trunk:
authorJim Jagielski <jim@apache.org>
Mon, 14 Apr 2014 12:47:49 +0000 (12:47 +0000)
committerJim Jagielski <jim@apache.org>
Mon, 14 Apr 2014 12:47:49 +0000 (12:47 +0000)
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

STATUS
include/ap_mmn.h
modules/proxy/mod_proxy.h
modules/proxy/mod_proxy_http.c
modules/proxy/proxy_util.c

diff --git a/STATUS b/STATUS
index 227fb5cbc0055106e81a87c3adf1d437687c97f6..842cf10581ff2a6d61a7038450fd322fab8a8fbe 100644 (file)
--- 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:
index 79f26f4072e6b7847816b04cef6f40f845224d97..8918e1a5f32c38a5962f376ce9140869d9faa385 100644 (file)
  * 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" */
 #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
index eb0106d6bcf56ccb5ae2fe9a165cdd8bab0234c5..67a9015be99e5682b0660d27361410c3c82b172b 100644 (file)
@@ -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 {
index 3aec4cfea8abf3ad2b7262f0507133c7b0d7cdff..a35c0a9f71cc180ea6c30324ae498218694f4f7b 100644 (file)
@@ -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);
             }
         }
 
index d05f0cdcce148b9051236f4cea6da717ec6ef6c6..d3bc1d0457f394fc26ae3c442ee0d74903606a62 100644 (file)
@@ -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;