From: Amos Jeffries Date: Thu, 14 Mar 2013 11:32:19 +0000 (-0600) Subject: Fix SSL Bump bypass for intercepted traffic X-Git-Tag: SQUID_3_3_4~22 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7778eb1e7fd439f1a36bdcea28508ee6f3b36cbd;p=thirdparty%2Fsquid.git Fix SSL Bump bypass for intercepted traffic The SSL-bump bypass code on intercepted HTTPS traffic generates a fake CONNECT request from the original destination IP:port in an attempt to trigger a TCP tunnel being opened for the un-bumped data to be transferred over. The current implementation breaks in two situations: 1) when IPv6 traffic is intercepted The URL field generated does not account for the additional [] requirements involved when IPv6+port are combined. The resulting fake requests look like: CONNECT ::1:443 HTTP/1.1 Host: ::1 ... which are both invalid, and will fail to parse. Breaking IPv6 HTTPS interception bypass. Resolve this by using Ip::Address::ToURL() function which was created for the purpose of generating URL hostnames from raw-IP + port with the bracketing inserted when required. 2) when a non-443 port is being intercepted The Host: header generated is missing the port and Squid Host: header validity will reject the outbound CONNECT 127.0.0.1:8443 HTTP/1.1 Host: 127.0.0.1 ... this is an invalid request. Squid is currently ignoring the Host header. However Squid tunnel.cc does make use of peering and may relay the fake request Host: to upstream peers where we cannot be so sure what will happen. Resolve this issue by re-using the generated IP:port string for both URL and Host: fields, which preserves teh port in Host: regardless of value. This also means there is an unnecessary :443 tagged on for most HTTPS traffic, however the omission of port from the Host: header is only a MAY and this should not cause any issues. --- diff --git a/src/client_side.cc b/src/client_side.cc index f2ab2c567d..eb5f5e0b7c 100644 --- a/src/client_side.cc +++ b/src/client_side.cc @@ -3618,8 +3618,8 @@ httpsSslBumpAccessCheckDone(allow_t answer, void *data) // fake a CONNECT request to force connState to tunnel static char ip[MAX_IPSTRLEN]; static char reqStr[MAX_IPSTRLEN + 80]; - connState->clientConnection->local.NtoA(ip, sizeof(ip)); - snprintf(reqStr, sizeof(reqStr), "CONNECT %s:%d HTTP/1.1\r\nHost: %s\r\n\r\n", ip, connState->clientConnection->local.GetPort(), ip); + connState->clientConnection->local.ToURL(ip, sizeof(ip)); + snprintf(reqStr, sizeof(reqStr), "CONNECT %s HTTP/1.1\r\nHost: %s\r\n\r\n", ip, ip); bool ret = connState->handleReadData(reqStr, strlen(reqStr)); if (ret) ret = connState->clientParseRequests();