From: Yann Ylavic Date: Fri, 24 May 2019 07:59:42 +0000 (+0000) Subject: Merge r1859371, r1859422 from trunk: X-Git-Tag: 2.4.40~118 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=313d5ee40f390da1a6ee2c2752864ad3aad0a1c3;p=thirdparty%2Fapache%2Fhttpd.git Merge r1859371, r1859422 from trunk: mod_proxy/ssl: Proxy SSL client certificate configuration and other proxy SSL configurations broken inside 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 --- diff --git a/CHANGES b/CHANGES index 3a691729eda..a4a296d5f69 100644 --- 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 context. PR 63430. + [Ruediger Pluem, Yann Ylavic] + *) mod_proxy: allow SSLProxyCheckPeer* usage for all proxy modules. PR 61857. [Markus Gausling , Yann Ylavic] diff --git a/modules/http2/mod_proxy_http2.c b/modules/http2/mod_proxy_http2.c index 6da47312071..9d072d47feb 100644 --- a/modules/http2/mod_proxy_http2.c +++ b/modules/http2/mod_proxy_http2.c @@ -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; diff --git a/modules/proxy/mod_proxy_ftp.c b/modules/proxy/mod_proxy_ftp.c index 4a10987b4d0..a29e085abf1 100644 --- a/modules/proxy/mod_proxy_ftp.c +++ b/modules/proxy/mod_proxy_ftp.c @@ -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 */ diff --git a/modules/proxy/mod_proxy_hcheck.c b/modules/proxy/mod_proxy_hcheck.c index 2783a58e786..dd8e4071764 100644 --- a/modules/proxy/mod_proxy_hcheck.c +++ b/modules/proxy/mod_proxy_hcheck.c @@ -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); diff --git a/modules/proxy/mod_proxy_http.c b/modules/proxy/mod_proxy_http.c index 2f2cef56008..00cbb8f3893 100644 --- a/modules/proxy/mod_proxy_http.c +++ b/modules/proxy/mod_proxy_http.c @@ -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 diff --git a/modules/proxy/mod_proxy_uwsgi.c b/modules/proxy/mod_proxy_uwsgi.c index c5d4f8e9a61..2ac2a95d2ef 100644 --- a/modules/proxy/mod_proxy_uwsgi.c +++ b/modules/proxy/mod_proxy_uwsgi.c @@ -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) diff --git a/modules/proxy/mod_proxy_wstunnel.c b/modules/proxy/mod_proxy_wstunnel.c index 1056d5cb726..2502d188b2e 100644 --- a/modules/proxy/mod_proxy_wstunnel.c +++ b/modules/proxy/mod_proxy_wstunnel.c @@ -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; diff --git a/modules/proxy/proxy_util.c b/modules/proxy/proxy_util.c index 77880de622c..a9eb9917a78 100644 --- a/modules/proxy/proxy_util.c +++ b/modules/proxy/proxy_util.c @@ -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); } diff --git a/modules/ssl/mod_ssl.c b/modules/ssl/mod_ssl.c index e857f506476..41029e29a24 100644 --- a/modules/ssl/mod_ssl.c +++ b/modules/ssl/mod_ssl.c @@ -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. diff --git a/modules/ssl/ssl_engine_io.c b/modules/ssl/ssl_engine_io.c index 9f9b6c840ff..8335657e19f 100644 --- a/modules/ssl/ssl_engine_io.c +++ b/modules/ssl/ssl_engine_io.c @@ -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. */