Patch applied to trunk as r14898.

I am attaching the squid-3.5 version of the patch.



On 10/27/2016 12:46 AM, Amos Jeffries wrote:
On 21/10/2016 5:18 a.m., Christos Tsantilas wrote:

The original server_name code mishandled all SNI checks and some rare
host checks:

* The SNI-derived value was pointing to an already freed memory storage.
* Missing host-derived values were not detected (host() is never nil).
* Mismatches were re-checked with an undocumented "none" value instead
of being treated as mismatches.

Same for ssl::server_name_regex.

Also set SNI for more server-first and client-first transactions.

This is a Measurement Factory project.


+1.

Amos


_______________________________________________
squid-dev mailing list
[email protected]
http://lists.squid-cache.org/listinfo/squid-dev


ssl::server_name ACL badly broken since inception (trunk r14008).

The original server_name code mishandled all SNI checks and some rare
host checks:

* The SNI-derived value was pointing to an already freed memory storage.
* Missing host-derived values were not detected (GetHost() is never nil).
* Mismatches were re-checked with an undocumented "none" value
  instead of being treated as mismatches.

Same for ssl::server_name_regex.

This is a Measurement Factory project.

=== modified file 'src/acl/ServerName.cc'
--- src/acl/ServerName.cc	2016-09-08 12:27:06 +0000
+++ src/acl/ServerName.cc	2016-10-28 08:24:45 +0000
@@ -73,51 +73,52 @@
 
     char *s = reinterpret_cast<char *>(cn_data->data);
     char *d = cn;
     for (int i = 0; i < cn_data->length; ++i, ++d, ++s) {
         if (*s == '\0')
             return 1; // always a domain mismatch. contains 0x00
         *d = *s;
     }
     cn[cn_data->length] = '\0';
     debugs(28, 4, "Verifying certificate name/subjectAltName " << cn);
     if (data->match(cn))
         return 0;
     return 1;
 }
 
 int
 ACLServerNameStrategy::match (ACLData<MatchType> * &data, ACLFilledChecklist *checklist, ACLFlags &flags)
 {
     assert(checklist != NULL && checklist->request != NULL);
 
-    if (checklist->conn() && checklist->conn()->serverBump()) {
-        if (X509 *peer_cert = checklist->conn()->serverBump()->serverCert.get()) {
-            if (Ssl::matchX509CommonNames(peer_cert, (void *)data, check_cert_domain<MatchType>))
-                return 1;
+    const char *serverName = NULL;
+    SBuf serverNameKeeper; // because c_str() is not constant
+    if (ConnStateData *conn = checklist->conn()) {
+        if (conn->serverBump()) {
+            if (X509 *peer_cert = conn->serverBump()->serverCert.get())
+                return Ssl::matchX509CommonNames(peer_cert, (void *)data, check_cert_domain<MatchType>);
         }
-    }
 
-    const char *serverName = NULL;
-    if (checklist->conn() && !checklist->conn()->sslCommonName().isEmpty()) {
-        SBuf scn = checklist->conn()->sslCommonName();
-        serverName = scn.c_str();
+        if (conn->sslCommonName().isEmpty()) {
+            const char *host = checklist->request->GetHost();
+            if (host && *host) // paranoid first condition: host() is never nil
+                serverName = host;
+        } else {
+            serverNameKeeper = conn->sslCommonName();
+            serverName = serverNameKeeper.c_str();
+        }
     }
 
-    if (serverName == NULL)
-        serverName = checklist->request->GetHost();
-
-    if (serverName && data->match(serverName)) {
-        return 1;
-    }
+    if (!serverName)
+        serverName = "none";
 
-    return data->match("none");
+    return data->match(serverName);
 }
 
 ACLServerNameStrategy *
 ACLServerNameStrategy::Instance()
 {
     return &Instance_;
 }
 
 ACLServerNameStrategy ACLServerNameStrategy::Instance_;
 

=== modified file 'src/cf.data.pre'
--- src/cf.data.pre	2016-10-25 08:23:49 +0000
+++ src/cf.data.pre	2016-10-28 08:25:46 +0000
@@ -1150,40 +1150,43 @@
 
 	acl aclname at_step step
 	  # match against the current step during ssl_bump evaluation [fast]
 	  # Never matches and should not be used outside the ssl_bump context.
 	  #
 	  # At each SslBump step, Squid evaluates ssl_bump directives to find
 	  # the next bumping action (e.g., peek or splice). Valid SslBump step
 	  # values and the corresponding ssl_bump evaluation moments are:
 	  #   SslBump1: After getting TCP-level and HTTP CONNECT info.
 	  #   SslBump2: After getting SSL Client Hello info.
 	  #   SslBump3: After getting SSL Server Hello info.
 
 	acl aclname ssl::server_name .foo.com ...
 	  # matches server name obtained from various sources [fast]
 	  #
 	  # The server name is obtained during Ssl-Bump steps from such sources
 	  # as CONNECT request URI, client SNI, and SSL server certificate CN.
 	  # During each Ssl-Bump step, Squid may improve its understanding of a
 	  # "true server name". Unlike dstdomain, this ACL does not perform
 	  # DNS lookups.
+	  # The "none" name can be used to match transactions where Squid
+	  # could not compute the server name using any information source
+	  # already available at the ACL evaluation time.
 
 	acl aclname ssl::server_name_regex [-i] \.foo\.com ...
 	  # regex matches server name obtained from various sources [fast]
 ENDIF
 	acl aclname any-of acl1 acl2 ...
 	  # match any one of the acls [fast or slow]
 	  # The first matching ACL stops further ACL evaluation.
 	  #
 	  # ACLs from multiple any-of lines with the same name are ORed.
 	  # For example, A = (a1 or a2) or (a3 or a4) can be written as
 	  #   acl A any-of a1 a2
 	  #   acl A any-of a3 a4
 	  #
 	  # This group ACL is fast if all evaluated ACLs in the group are fast
 	  # and slow otherwise.
 
 	acl aclname all-of acl1 acl2 ... 
 	  # match all of the acls [fast or slow]
 	  # The first mismatching ACL stops further ACL evaluation.
 	  #

_______________________________________________
squid-dev mailing list
[email protected]
http://lists.squid-cache.org/listinfo/squid-dev

Reply via email to