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
-*- 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]
}
/* 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;
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 */
}
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);
}
/* 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
}
/* 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)
}
/* 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;
/* 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);
}
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.
((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) {
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. */