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 +0000
+++ src/ssl/PeerConnector.cc 2015-02-08 08:35:55 +0000
@@ -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_cast<Ssl::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_cast<Ssl::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_cast<Ssl::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_cast<Ssl::ServerBio *>(b->ptr);
+ // Inherite client features, like SSL version, SNI and other
+ srvBio->setClientFeatures(features);
+ srvBio->recordInput(true);
+ srvBio->mode(csd->sslBumpMode);
+ }
+ }
+ } else {
+ // Use SNI TLS extension only when we connect directly
+ // to the origin server and we know the server host name.
+ const char *sniServer = hostName ? hostName :
+ (!request->GetHostIsNumeric() ? request->GetHost() : NULL);
+ if (sniServer)
+ Ssl::setClientSNI(ssl, sniServer);
}
- } else {
- // 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 char *hostname = request->GetHost();
- const bool hostnameIsIp = request->GetHostIsNumeric();
- const bool isConnectRequest = request->clientConnectionManager.valid() &&
- !request->clientConnectionManager->port->flags.isIntercepted();
- if (!request->flags.sslPeek || isConnectRequest)
- 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 (!hostnameIsIp)
- Ssl::setClientSNI(ssl, hostname);
}
// If CertValidation Helper used do not lookup checklist for errors,
// but keep a list of errors to send it to CertValidator
if (!Ssl::TheConfig.ssl_crt_validator) {
// Create the ACL check list now, while we have access to more info.
// The list is used in ssl_verify_cb() and is freed in ssl_free().
if (acl_access *acl = ::Config.ssl_client.cert_error) {
ACLFilledChecklist *check = new ACLFilledChecklist(acl, request.getRaw(), dash_str);
// check->fd(fd); XXX: need client FD here
SSL_set_ex_data(ssl, ssl_ex_index_cert_error_check, check);
}
}
// store peeked cert to check SQUID_X509_V_ERR_CERT_CHANGE
X509 *peeked_cert;
if (request->clientConnectionManager.valid() &&
request->clientConnectionManager->serverBump() &&
(peeked_cert = request->clientConnectionManager->serverBump()->serverCert.get())) {
CRYPTO_add(&(peeked_cert->references),1,CRYPTO_LOCK_X509);
_______________________________________________
squid-dev mailing list
[email protected]
http://lists.squid-cache.org/listinfo/squid-dev