On Fri, Sep 18, 2015 at 12:56 PM, Stefan Eissing
<[email protected]> wrote:
> Ok, what is happening for Steffen is not a bug, but a missing feature. The 
> question is how we move forward.
>
> The certificate at apachelounge.com has a long list of subjectAltNames, 
> probably common for a lot of sites. Chrome opens a connection to server1, 
> established h2, keeps it open. You open a tab on server2, chrome sees the 
> altName on the server1 cert and *reuses* that connection to send the request 
> for server2.
>
> httpd sees that the request is not in the same vhost as the one belonging to 
> the SNI server1 and refuses to serve it with a 421. Which rfc7540 intended 
> for this, telling the client to use a new connection.

IMHO we should not base our check on SNI vs hostname (header Host) but
rather r->server vs sslconn->server (ie. handshakeserver), patch
attached.

What really matters is that the initial handshake was made with the
same SSL parameters.

Regards,
Yann.
Index: modules/ssl/ssl_engine_kernel.c
===================================================================
--- modules/ssl/ssl_engine_kernel.c	(revision 1703648)
+++ modules/ssl/ssl_engine_kernel.c	(working copy)
@@ -172,19 +172,18 @@ int ssl_hook_ReadReq(request_rec *r)
      * original problem.
      */
     if (r->proxyreq != PROXYREQ_PROXY && ap_is_initial_req(r)) {
+        server_rec *handshakeserver = sslconn->server;
+        SSLSrvConfigRec *hssc = mySrvConfig(handshakeserver);
+
         if ((servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name))) {
-            char *host, *scope_id;
-            apr_port_t port;
-            apr_status_t rv;
-
             /*
              * The SNI extension supplied a hostname. So don't accept requests
-             * with either no hostname or a different hostname as this could
-             * cause us to end up in a different virtual host as the one that
-             * was used for the handshake causing different SSL parameters to
-             * be applied as SSLProtocol, SSLCACertificateFile/Path and
-             * SSLCADNRequestFile/Path cannot be renegotiated (SSLCA* due
-             * to current limitations in OpenSSL, see
+             * with either no hostname or a hostname that selected a different
+             * virtual host than the one used for the handshake, causing
+             * different SSL parameters to be applied, such as SSLProtocol,
+             * SSLCACertificateFile/Path and SSLCADNRequestFile/Path which
+             * cannot be renegotiated (SSLCA* due to current limitations in
+             * OpenSSL, see:
              * http://mail-archives.apache.org/mod_mbox/httpd-dev/200806.mbox/%[email protected]%3E
              * and
              * http://mail-archives.apache.org/mod_mbox/httpd-dev/201312.mbox/%3CCAKQ1sVNpOrdiBm-UPw1hEdSN7YQXRRjeaT-MCWbW_7mN%3DuFiOw%40mail.gmail.com%3E
@@ -196,27 +195,21 @@ int ssl_hook_ReadReq(request_rec *r)
                             " provided in HTTP request", servername);
                 return HTTP_BAD_REQUEST;
             }
-            rv = apr_parse_addr_port(&host, &scope_id, &port, r->hostname, r->pool);
-            if (rv != APR_SUCCESS || scope_id) {
-                return HTTP_BAD_REQUEST;
-            }
-            if (strcasecmp(host, servername) 
-                || !sslconn->server 
-                || !ssl_util_vhost_matches(host, sslconn->server)) {
+            if (r->server != handshakeserver) {
                 /* 
                  * We are really not in Kansas anymore...
-                 * The request hostname does not match the SNI and does not
-                 * select the virtual host that was selected by the SNI.
+                 * The request does not select the virtual host that was
+                 * selected by the SNI.
                  */
                 ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, APLOGNO(02032)
                              "Hostname %s provided via SNI and hostname %s provided"
-                             " via HTTP are different", servername, host);
+                             " via HTTP select a different server",
+                             servername, r->hostname);
                 return HTTP_MISDIRECTED_REQUEST;
             }
         }
         else if (((sc->strict_sni_vhost_check == SSL_ENABLED_TRUE)
-                 || (mySrvConfig(sslconn->server))->strict_sni_vhost_check
-                    == SSL_ENABLED_TRUE)
+                  || hssc->strict_sni_vhost_check == SSL_ENABLED_TRUE)
                  && r->connection->vhost_lookup_data) {
             /*
              * We are using a name based configuration here, but no hostname was

Reply via email to