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
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:
* 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
* 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 {
* 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);
}
}
{
conn->sock = NULL;
conn->connection = NULL;
+ conn->ssl_hostname = NULL;
apr_pool_clear(conn->scpool);
}
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;