]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Domain mismatch when CONNECT has domain
authorChristos Tsantilas <chtsanti@users.sourceforge.net>
Thu, 5 Apr 2012 17:10:41 +0000 (20:10 +0300)
committerChristos Tsantilas <chtsanti@users.sourceforge.net>
Thu, 5 Apr 2012 17:10:41 +0000 (20:10 +0300)
Customers want Squid to detect domain mismatch as early as possible so
that Squid uses a minimal valid fake certificate and serves a
[customized] Squid error. Currently, the browser always displays the
built-in error even if CONNECT has a domain name.

This patch tells Squid to use CONNECT host name if not peeking or if it is not
an IP while peeking. It also sends SNI information if host name is not an IP.

Also on error pages use the server certificate CN as hostname only if the
CONNECT host name is not an IP address.

src/forward.cc

index 68b673226eb7e0523f0fde264f0c923d521662ce..20367f33ae9410fef9fe2a21a566a71e24f856e1 100644 (file)
@@ -679,8 +679,9 @@ FwdState::negotiateSSL(int fd)
                 }
             }
 
-            if (request->flags.sslPeek) {
-                // If possible, set host name to server certificate CN.
+            if (request->flags.sslPeek && request->GetHostIsNumeric()) {
+                // If possible, set host name to server certificate CN unless
+                // we already got the right name (from the CONNECT request).
                 if (X509 *srvX509 = errDetails->peerCert()) {
                     if (const char *name = Ssl::CommonHostName(srvX509)) {
                         request->SetHost(name);
@@ -767,17 +768,19 @@ FwdState::initiateSSL()
             SSL_set_session(ssl, peer->sslSession);
 
     } else {
-        // While we are peeking at the certificate, we do not know the server
-        // name that the client will request (after interception or CONNECT).
-        if (!request->flags.sslPeek) {
-            const char *hostname = request->GetHost();
+        // While we are peeking at the certificate, we may not know the server
+        // name that the client will request (after interception or CONNECT)
+        // unless it was the CONNECT request which used a host name. Some
+        // browsers are using IP addresses in CONNECT requests.
+        const char *hostname = request->GetHost();
+        const bool hostnameIsIp = request->GetHostIsNumeric();
+        if (!request->flags.sslPeek || !hostnameIsIp)
             SSL_set_ex_data(ssl, ssl_ex_index_server, (void*)hostname);
 
-            // Use SNI TLS extension only when we connect directly
-            // to the origin server and we know the server host name
-            if (!request->GetHostIsNumeric())
-                Ssl::setClientSNI(ssl, hostname);
-        }
+        // Use SNI TLS extension only when we connect directly
+        // to the origin server and we know the server host name
+        if (!hostnameIsIp)
+            Ssl::setClientSNI(ssl, hostname);
     }
 
     // Create the ACL check list now, while we have access to more info.