SNI information is not set on transparent bumping mode
Forward SNI (obtained from an intercepted client connection) to servers
when SslBump peeks or stares at the server certificate.
SslBump was not forwarding SNI to servers when Squid obtained SNI from
an intercepted client while peeking (or staring) at client Hello.
This patch also fixes squid to consider hostname included in SNI
information more reliable than the hostname provided in CONNECT request
for certificates CN verify
This is a Measurement Factory project
SNI information is not set on transparent bumping mode
Forward SNI (obtained from an intercepted client connection) to servers
when SslBump peeks or stares at the server certificate.
SslBump was not forwarding SNI to servers when Squid obtained SNI from an
intercepted client while peeking (or staring) at client Hello.
This is a Measurement Factory project
=== modified file 'src/ssl/PeerConnector.cc'
--- src/ssl/PeerConnector.cc 2015-01-13 07:25:36 +
+++ src/ssl/PeerConnector.cc 2015-02-08 08:35:55 +
@@ -127,82 +127,91 @@
bail(anErr);
return;
}
if (peer) {
if (peer-ssldomain)
SSL_set_ex_data(ssl, ssl_ex_index_server, peer-ssldomain);
#if NOT_YET
else if (peer-name)
SSL_set_ex_data(ssl, ssl_ex_index_server, peer-name);
#endif
else
SSL_set_ex_data(ssl, ssl_ex_index_server, peer-host);
if (peer-sslSession)
SSL_set_session(ssl, peer-sslSession);
-
-} else if (request-clientConnectionManager-sslBumpMode == Ssl::bumpPeek || request-clientConnectionManager-sslBumpMode == Ssl::bumpStare) {
-// client connection is required for Peek or Stare mode in the case we need to splice
+} else if (const ConnStateData *csd = request-clientConnectionManager.valid()) {
+// client connection is required in the case we need to splice
// or terminate client and server connections
assert(clientConn != NULL);
-SSL *clientSsl = fd_table[request-clientConnectionManager-clientConnection-fd].ssl;
-BIO *b = SSL_get_rbio(clientSsl);
-Ssl::ClientBio *clnBio = static_castSsl::ClientBio *(b-ptr);
-const Ssl::Bio::sslFeatures features = clnBio-getFeatures();
-if (features.sslVersion != -1) {
-features.applyToSSL(ssl);
-// Should we allow it for all protocols?
-if (features.sslVersion = 3) {
-b = SSL_get_rbio(ssl);
-Ssl::ServerBio *srvBio = static_castSsl::ServerBio *(b-ptr);
-srvBio-setClientFeatures(features);
-srvBio-recordInput(true);
-srvBio-mode(request-clientConnectionManager-sslBumpMode);
-}
+const char *hostName = NULL;
+Ssl::ClientBio *cltBio = NULL;
+
+// In server-first bumping mode, clientSsl is NULL.
+if (SSL *clientSsl = fd_table[clientConn-fd].ssl) {
+BIO *b = SSL_get_rbio(clientSsl);
+cltBio = static_castSsl::ClientBio *(b-ptr);
+const Ssl::Bio::sslFeatures features = cltBio-getFeatures();
+if (!features.serverName.isEmpty())
+hostName = features.serverName.c_str();
+}
-const bool isConnectRequest = request-clientConnectionManager.valid()
- !request-clientConnectionManager-port-flags.isIntercepted();
-if (isConnectRequest)
-SSL_set_ex_data(ssl, ssl_ex_index_server, (void*)request-GetHost());
-else if (!features.serverName.isEmpty())
-SSL_set_ex_data(ssl, ssl_ex_index_server, (void*)features.serverName.c_str());
+if (!hostName) {
+// 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 with a user-typed address.
+const bool isConnectRequest = !csd-port-flags.isIntercepted();
+if (!request-flags.sslPeek || isConnectRequest)
+hostName = request-GetHost();
+}
+
+if (hostName)
+SSL_set_ex_data(ssl, ssl_ex_index_server, (void*)hostName);
+
+if (csd-sslBumpMode == Ssl::bumpPeek || csd-sslBumpMode == Ssl::bumpStare) {
+assert(cltBio);
+const Ssl::Bio::sslFeatures features = cltBio-getFeatures();
+if (features.sslVersion != -1) {
+features.applyToSSL(ssl);
+// Should we allow it for all protocols?
+if (features.sslVersion = 3) {
+BIO *b = SSL_get_rbio(ssl);
+Ssl::ServerBio *srvBio = static_castSsl::ServerBio *(b-ptr);
+// Inherite client features, like SSL version, SNI and other
+srvBio-setClientFeatures(features);
+