]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
Merge r1859371, r1859422 from trunk:
authorYann Ylavic <ylavic@apache.org>
Fri, 24 May 2019 07:59:42 +0000 (07:59 +0000)
committerYann Ylavic <ylavic@apache.org>
Fri, 24 May 2019 07:59:42 +0000 (07:59 +0000)
mod_proxy/ssl: Proxy SSL client certificate
configuration and other proxy SSL configurations
broken inside <Proxy> context.
PR 63430
Triggered by r1855646+r1855748.
Patch from rpluem (proxy) and ylavic (ssl).

Follow up to r1859371: extend to other ap_proxy_connection_create[_ex]() users.

This function now now handles SSL reuse as well as the "proxy-request-hostname"
note (SNI), so let's also call it unconditionnaly in all proxy modules.

On the mod_ssl side, since this note has the lifetime of the connection, don't
reset/unset it during handshake (ssl_io_filter_handshake).

Submitted by: rjung, ylavic
Reviewed by: rjung, rpluem, ylavic

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

CHANGES
modules/http2/mod_proxy_http2.c
modules/proxy/mod_proxy_ftp.c
modules/proxy/mod_proxy_hcheck.c
modules/proxy/mod_proxy_http.c
modules/proxy/mod_proxy_uwsgi.c
modules/proxy/mod_proxy_wstunnel.c
modules/proxy/proxy_util.c
modules/ssl/mod_ssl.c
modules/ssl/ssl_engine_io.c

diff --git a/CHANGES b/CHANGES
index 3a691729eda7778e0d3b37a2bf900c11d8dd6bf1..a4a296d5f69bf4fb53ec59a491c8e81d3cc79a1a 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,10 @@
                                                          -*- coding: utf-8 -*-
 Changes with Apache 2.4.40
 
+  *) mod_proxy/ssl: Proxy SSL client certificate configuration and other proxy
+     SSL configurations broken inside <Proxy> context.  PR 63430.
+     [Ruediger Pluem, Yann Ylavic]
+
   *) mod_proxy: allow SSLProxyCheckPeer* usage for all proxy modules.
      PR 61857.  [Markus Gausling <markusgausling googlemail.com>, Yann Ylavic]
 
index 6da47312071f21200e300d5b6d723700b9039717..9d072d47febf2237787d6aed556dd3e1beffb627 100644 (file)
@@ -387,24 +387,22 @@ run_connect:
     }
     
     /* Step Three: Create conn_rec for the socket we have open now. */
-    if (!ctx->p_conn->connection) {
-        status = ap_proxy_connection_create_ex(ctx->proxy_func, ctx->p_conn, ctx->r);
-        if (status != OK) {
-            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, status, ctx->owner, APLOGNO(03353)
-                          "setup new connection: is_ssl=%d %s %s %s", 
-                          ctx->p_conn->is_ssl, ctx->p_conn->ssl_hostname, 
-                          locurl, ctx->p_conn->hostname);
-            ctx->r_status = status;
-            goto cleanup;
-        }
-        
-        if (!ctx->p_conn->data && ctx->is_ssl) {
-            /* New SSL connection: set a note on the connection about what
-             * protocol we want.
-             */
-            apr_table_setn(ctx->p_conn->connection->notes,
-                           "proxy-request-alpn-protos", "h2");
-        }
+    status = ap_proxy_connection_create_ex(ctx->proxy_func, ctx->p_conn, ctx->r);
+    if (status != OK) {
+        ap_log_cerror(APLOG_MARK, APLOG_DEBUG, status, ctx->owner, APLOGNO(03353)
+                      "setup new connection: is_ssl=%d %s %s %s", 
+                      ctx->p_conn->is_ssl, ctx->p_conn->ssl_hostname, 
+                      locurl, ctx->p_conn->hostname);
+        ctx->r_status = status;
+        goto cleanup;
+    }
+    
+    if (!ctx->p_conn->data && ctx->is_ssl) {
+        /* New SSL connection: set a note on the connection about what
+         * protocol we want.
+         */
+        apr_table_setn(ctx->p_conn->connection->notes,
+                       "proxy-request-alpn-protos", "h2");
     }
 
     if (ctx->master->aborted) goto cleanup;
index 4a10987b4d01080ab77b5131bfb849bdc5eb47e8..a29e085abf19018cc8c12b64d137a58f6e7753d2 100644 (file)
@@ -1180,12 +1180,10 @@ static int proxy_ftp_handler(request_rec *r, proxy_worker *worker,
         return HTTP_SERVICE_UNAVAILABLE;
     }
 
-    if (!backend->connection) {
-        status = ap_proxy_connection_create_ex("FTP", backend, r);
-        if (status != OK) {
-            proxy_ftp_cleanup(r, backend);
-            return status;
-        }
+    status = ap_proxy_connection_create_ex("FTP", backend, r);
+    if (status != OK) {
+        proxy_ftp_cleanup(r, backend);
+        return status;
     }
 
     /* Use old naming */
index 2783a58e786d156e42c27e80edd22dca098264e6..dd8e407176417b078cc646c46bb1579051100608 100644 (file)
@@ -762,10 +762,8 @@ static apr_status_t hc_check_http(baton_t *baton)
     }
 
     r = create_request_rec(ptemp, ctx->s, baton->balancer, wctx->method);
-    if (!backend->connection) {
-        if ((status = ap_proxy_connection_create_ex("HCOH", backend, r)) != OK) {
-            return backend_cleanup("HCOH", backend, ctx->s, status);
-        }
+    if ((status = ap_proxy_connection_create_ex("HCOH", backend, r)) != OK) {
+        return backend_cleanup("HCOH", backend, ctx->s, status);
     }
     set_request_connection(r, backend->connection);
 
index 2f2cef5600850a280ff965a37981da1638efa6ca..00cbb8f3893560ca0ea592d936d9ec5badd0e9a8 100644 (file)
@@ -1972,11 +1972,9 @@ static int proxy_http_handler(request_rec *r, proxy_worker *worker,
         }
 
         /* Step Three: Create conn_rec */
-        if (!backend->connection) {
-            if ((status = ap_proxy_connection_create_ex(proxy_function,
-                                                        backend, r)) != OK)
-                break;
-        }
+        if ((status = ap_proxy_connection_create_ex(proxy_function,
+                                                    backend, r)) != OK)
+            break;
 
         /* Step Four: Send the Request
          * On the off-chance that we forced a 100-Continue as a
index c5d4f8e9a6176b6fb4459e3a229c33ee7b21605f..2ac2a95d2ef28c788a4e9f86b81083ed80e818a3 100644 (file)
@@ -509,12 +509,10 @@ static int uwsgi_handler(request_rec *r, proxy_worker * worker,
     }
 
     /* Step Three: Create conn_rec */
-    if (!backend->connection) {
-        if ((status = ap_proxy_connection_create(UWSGI_SCHEME, backend,
-                                                 r->connection,
-                                                 r->server)) != OK)
-            goto cleanup;
-    }
+    if ((status = ap_proxy_connection_create(UWSGI_SCHEME, backend,
+                                             r->connection,
+                                             r->server)) != OK)
+        goto cleanup;
 
     /* Step Four: Process the Request */
     if (((status = ap_setup_client_block(r, REQUEST_CHUNKED_ERROR)) != OK)
index 1056d5cb726615fee6958bd32a4798f783259673..2502d188b2e327ab6bbc4d74cf34e3ce55724433 100644 (file)
@@ -356,17 +356,15 @@ static int proxy_wstunnel_handler(request_rec *r, proxy_worker *worker,
         }
 
         /* Step Three: Create conn_rec */
-        if (!backend->connection) {
-            status = ap_proxy_connection_create_ex(scheme, backend, r);
-            if (status  != OK) {
-                break;
-            }
+        status = ap_proxy_connection_create_ex(scheme, backend, r);
+        if (status != OK) {
+            break;
         }
 
         backend->close = 1; /* must be after ap_proxy_determine_connection */
 
 
-        /* Step Three: Process the Request */
+        /* Step Four: Process the Request */
         status = proxy_wstunnel_request(p, r, backend, worker, conf, uri, locurl,
                                       server_portstr);
         break;
index 77880de622ccb4eed375124d7023388a48001d55..a9eb9917a785193a7c615c1f33efa4623223feba 100644 (file)
@@ -3224,6 +3224,9 @@ static int proxy_connection_create(const char *proxy_function,
             /* Set a note on the connection about what CN is requested,
              * such that mod_ssl can check if it is requested to do so.
              */
+            ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, conn->connection, 
+                          "%s: set SNI to %s for (%s)", proxy_function,
+                          conn->ssl_hostname, conn->hostname);
             apr_table_setn(conn->connection->notes, "proxy-request-hostname",
                            conn->ssl_hostname);
         }
index e857f5064768a89bdbdb066ff32bc0335db6901c..41029e29a241a730ab9415fde1669fa8b095079d 100644 (file)
@@ -448,10 +448,20 @@ static SSLConnRec *ssl_init_connection_ctx(conn_rec *c,
     SSLConnRec *sslconn = myConnConfig(c);
     int need_setup = 0;
 
+    /* mod_proxy's (r->)per_dir_config has the lifetime of the request, thus
+     * it uses ssl_engine_set() to reset sslconn->dc when reusing SSL backend
+     * connections, so we must fall through here. But in the case where we are
+     * called from ssl_init_ssl_connection() with no per_dir_config (which also
+     * includes mod_proxy's later run_pre_connection call), sslconn->dc should
+     * be preserved if it's already set.
+     */
     if (!sslconn) {
         sslconn = apr_pcalloc(c->pool, sizeof(*sslconn));
         need_setup = 1;
     }
+    else if (!new_proxy) {
+        return sslconn;
+    }
 
     /* Reinit dc in any case because it may be r->per_dir_config scoped
      * and thus a caller like mod_proxy needs to update it per request.
index 9f9b6c840ff8de8486bdeabb710c3cea3fec5241..8335657e19fa189c90622ef23518abd45993fa57 100644 (file)
@@ -1267,7 +1267,6 @@ static apr_status_t ssl_io_filter_handshake(ssl_filter_ctx_t *filter_ctx)
             ((dc->proxy->ssl_check_peer_cn != FALSE) ||
              (dc->proxy->ssl_check_peer_name == TRUE)) &&
             hostname_note) {
-            apr_table_unset(c->notes, "proxy-request-hostname");
             if (!cert
                 || modssl_X509_match_name(c->pool, cert, hostname_note,
                                           TRUE, server) == FALSE) {
@@ -1284,7 +1283,6 @@ static apr_status_t ssl_io_filter_handshake(ssl_filter_ctx_t *filter_ctx)
 
             hostname = ssl_var_lookup(NULL, server, c, NULL,
                                       "SSL_CLIENT_S_DN_CN");
-            apr_table_unset(c->notes, "proxy-request-hostname");
 
             /* Do string match or simplest wildcard match if that
              * fails. */