]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
Merge r1572630, r1572611, r1572967, r1573229 from trunk:
authorYann Ylavic <ylavic@apache.org>
Fri, 18 Jul 2014 21:38:38 +0000 (21:38 +0000)
committerYann Ylavic <ylavic@apache.org>
Fri, 18 Jul 2014 21:38:38 +0000 (21:38 +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 by: ylavic, rpluem, wrowe

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.2.x@1611813 13f79535-47bb-0310-9956-ffa450edef68

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

index 3d2701e77bef918a4541098347419a29649f0a7b..bff6eff357a220217e11f4e44ad5482b1230ba70 100644 (file)
  * 20051115.32 (2.2.24) Add ap_get_exec_line
  * 20051115.33 (2.2.24) Add ap_pregsub_ex()
  * 20051115.34 (2.2.28) Add ap_copy_scoreboard_worker()
+ * 20051115.35 (2.2.27) Add SSL reusable SNI to mod_proxy.h's proxy_conn_rec
  */
 
 #define MODULE_MAGIC_COOKIE 0x41503232UL /* "AP22" */
 #ifndef MODULE_MAGIC_NUMBER_MAJOR
 #define MODULE_MAGIC_NUMBER_MAJOR 20051115
 #endif
-#define MODULE_MAGIC_NUMBER_MINOR 34                    /* 0...n */
+#define MODULE_MAGIC_NUMBER_MINOR 35                    /* 0...n */
 
 /**
  * Determine if the server's current MODULE_MAGIC_NUMBER is at least a
index 99048445f3faba09bd1265dae44f7bdae3012e6b..2d4998d94322b4dd75d8d7c88f78a6eeb4d3c669 100644 (file)
@@ -248,6 +248,7 @@ typedef struct {
     int          need_flush;/* Flag to decide whether we need to flush the
                              * filter chain or not */
     void         *forward;  /* opaque forward proxy data */
+    const char   *ssl_hostname;/* Hostname (SNI) in use by SSL connection */
 } proxy_conn_rec;
 
 typedef struct {
index ca3c5ee5fee87e4fc45e33165d3e462943f13e4f..330f80bd765ce8c5161e3643b456cad49ec5b8be 100644 (file)
@@ -2028,23 +2028,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) {
-            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.
-             */
-            if ((conf->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 85d31386e86503180cc7799f1f6146b8b6b26b8f..2a94aa6be91abecffa0c07261f1c3fcb4228d853 100644 (file)
@@ -1698,6 +1698,7 @@ static void socket_cleanup(proxy_conn_rec *conn)
 {
     conn->sock = NULL;
     conn->connection = NULL;
+    conn->ssl_hostname = NULL;
     apr_pool_clear(conn->scpool);
 }
 
@@ -2197,6 +2198,38 @@ 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) {
+        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.
+         */
+        if (conf->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_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
                  "proxy: connected %s to %s:%d", *url, conn->hostname,
                  conn->port);