From: Christos Tsantilas Date: Mon, 28 Jul 2014 18:48:30 +0000 (+0300) Subject: Peek and Splice: SNI to external_acl X-Git-Tag: SQUID_3_5_0_1~89^2~11 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=cedca6e77365670e565ba07bb785b43670732e28;p=thirdparty%2Fsquid.git Peek and Splice: SNI to external_acl Support the %ssl::>sni formating code with external_acl helpers and access logging. The new code prints the SNI name sent by the SSL client. If no SNI information is available, the code expands into a dash. It is currently supported only after the peek, stare, or splice SSL bumping actions. Note that older clients (e.g., IE on Windows XP) do not send SNI. This is a Measurement Factory project --- diff --git a/src/cf.data.pre b/src/cf.data.pre index c6bce1173f..1f0762f5c1 100644 --- a/src/cf.data.pre +++ b/src/cf.data.pre @@ -740,6 +740,7 @@ DOC_START %USER_CERTCHAIN SSL User certificate chain in PEM format %USER_CERT_xx SSL User certificate subject attribute xx %USER_CA_xx SSL User certificate issuer attribute xx + %ssl::>sni SSL client SNI sent to Squid %>{Header} HTTP request header "Header" %>{Hdr:member} @@ -3993,6 +3994,10 @@ DOC_START In all other cases, a single dash ("-") is logged. + ssl::>sni SSL client SNI sent to Squid. Available only + after the peek, stare, or splice SSL bumping + actions. + If ICAP is enabled, the following code becomes available (as well as ICAP log codes documented with the icap_log option): diff --git a/src/client_side.cc b/src/client_side.cc index a4f41a43bf..b49e921cd8 100644 --- a/src/client_side.cc +++ b/src/client_side.cc @@ -4003,6 +4003,12 @@ clientPeekAndSpliceSSL(int fd, void *data) assert(b); Ssl::ClientBio *bio = static_cast(b->ptr); if (bio->gotHello()) { + if (conn->serverBump()) { + Ssl::Bio::sslFeatures const &features = bio->getFeatures(); + if (!features.serverName.empty()) + conn->serverBump()->clientSni = features.serverName.c_str(); + } + debugs(83, 2, "I got hello. Start forwarding the request!!! "); Comm::SetSelect(fd, COMM_SELECT_READ, NULL, NULL, 0); Comm::SetSelect(fd, COMM_SELECT_WRITE, NULL, NULL, 0); diff --git a/src/external_acl.cc b/src/external_acl.cc index d4b81d1689..036a3c83f1 100644 --- a/src/external_acl.cc +++ b/src/external_acl.cc @@ -65,6 +65,7 @@ #include "URL.h" #include "wordlist.h" #if USE_OPENSSL +#include "ssl/ServerBump.h" #include "ssl/support.h" #endif #if USE_AUTH @@ -423,7 +424,8 @@ parse_externalAclHelper(external_acl ** list) debugs(82, DBG_PARSE_NOTE(DBG_IMPORTANT), "WARNING: external_acl_type %CA_CERT_* code is obsolete. Use %USER_CA_CERT_* instead"); format->type = Format::LFT_EXT_ACL_USER_CA_CERT; format->header = xstrdup(token + 11); - } + } else if (strcmp(token, "%ssl::>sni") == 0) + format->type = Format::LFT_SSL_CLIENT_SNI; #endif #if USE_AUTH else if (strcmp(token, "%EXT_USER") == 0 || strcmp(token, "%ue") == 0) @@ -559,6 +561,7 @@ dump_externalAclHelper(StoreEntry * sentry, const char *name, const external_acl DUMP_EXT_ACL_TYPE_FMT(EXT_ACL_USER_CERTCHAIN_RAW, " %%USER_CERTCHAIN_RAW"); DUMP_EXT_ACL_TYPE_FMT(EXT_ACL_USER_CERT, " %%USER_CERT_%s", format->header); DUMP_EXT_ACL_TYPE_FMT(EXT_ACL_USER_CA_CERT, " %%USER_CA_CERT_%s", format->header); + DUMP_EXT_ACL_TYPE_FMT(SSL_CLIENT_SNI, "ssl::>sni"); #endif #if USE_AUTH DUMP_EXT_ACL_TYPE_FMT(USER_EXTERNAL," %%ue"); @@ -1078,6 +1081,15 @@ makeExternalAclKey(ACLFilledChecklist * ch, external_acl_data * acl_data) } break; + + case Format::LFT_SSL_CLIENT_SNI: + if (ch->conn() != NULL) { + if (Ssl::ServerBump * srvBump = ch->conn()->serverBump()) { + if (!srvBump->clientSni.isEmpty()) + str = srvBump->clientSni.c_str(); + } + } + break; #endif #if USE_AUTH case Format::LFT_USER_EXTERNAL: diff --git a/src/format/ByteCode.h b/src/format/ByteCode.h index 9983a4a82f..958eb349d7 100644 --- a/src/format/ByteCode.h +++ b/src/format/ByteCode.h @@ -206,6 +206,7 @@ typedef enum { LFT_SSL_BUMP_MODE, LFT_SSL_USER_CERT_SUBJECT, LFT_SSL_USER_CERT_ISSUER, + LFT_SSL_CLIENT_SNI, #endif LFT_NOTE, diff --git a/src/format/Format.cc b/src/format/Format.cc index 7f61bc0b4a..1c72488ddc 100644 --- a/src/format/Format.cc +++ b/src/format/Format.cc @@ -17,6 +17,7 @@ #include "URL.h" #if USE_OPENSSL #include "ssl/ErrorDetail.h" +#include "ssl/ServerBump.h" #endif /// Convert a string to NULL pointer if it is "" @@ -1134,6 +1135,14 @@ Format::Format::assemble(MemBuf &mb, const AccessLogEntry::Pointer &al, int logS } } break; + case LFT_SSL_CLIENT_SNI: + if (al->request && al->request->clientConnectionManager.valid()) { + if (Ssl::ServerBump * srvBump = al->request->clientConnectionManager->serverBump()) { + if (!srvBump->clientSni.isEmpty()) + out = srvBump->clientSni.c_str(); + } + } + break; #endif case LFT_REQUEST_URLGROUP_OLD_2X: diff --git a/src/format/Token.cc b/src/format/Token.cc index 606633df00..6da8245582 100644 --- a/src/format/Token.cc +++ b/src/format/Token.cc @@ -181,6 +181,7 @@ static TokenTableEntry TokenTableSsl[] = { {"bump_mode", LFT_SSL_BUMP_MODE}, {">cert_subject", LFT_SSL_USER_CERT_SUBJECT}, {">cert_issuer", LFT_SSL_USER_CERT_ISSUER}, + {">sni", LFT_SSL_CLIENT_SNI}, {NULL, LFT_NONE} }; #endif diff --git a/src/ssl/ServerBump.h b/src/ssl/ServerBump.h index cdc94a722b..1057883e13 100644 --- a/src/ssl/ServerBump.h +++ b/src/ssl/ServerBump.h @@ -30,6 +30,7 @@ public: Ssl::CertErrors *sslErrors; ///< SSL [certificate validation] errors Ssl::BumpMode mode; ///< The SSL server bump mode Ssl::BumpStep step; ///< The SSL server bumping step + SBuf clientSni; ///< the SSL client SNI name private: store_client *sc; ///< dummy client to prevent entry trimming