From: Christos Tsantilas Date: Tue, 14 Jul 2015 17:51:21 +0000 (-0700) Subject: Splice to origin cache_peer. X-Git-Tag: SQUID_3_5_7~20 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=737bf06f0601f1d8c8b7bf54fde22cb9463c1eec;p=thirdparty%2Fsquid.git Splice to origin cache_peer. Currently, Squid cannot redirect intercepted connections that are subject to SslBump rules to _originserver_ cache_peer. For example, consider Squid that enforces "safe search" by redirecting clients to forcesafesearch.example.com. Consider a TLS client that tries to connect to www.example.com. Squid needs to send that client to forcesafesearch.example.com (without changing the host header and SNI information; those would still point to www.example.com for safe search to work as intended!). The admin may configure Squid to send intercepted clients to an originserver cache_peer with the forcesafesearch.example.com address. Such a configuration does not currently work together with ssl_bump peek/splice rules. This patch: * Fixes src/neighbors.cc bug which prevented CONNECT requests from going to originserver cache peers. This bug affects both true CONNECT requests and intercepted SSL/TLS connections (with fake CONNECT requests). Squid use the CachePeer::in_addr.port which is not meant to be used for the HTTP port, apparently. HTTP checks should use CachePeer::http_port instead. * Changes Squid to not initiate SSL/TLS connection to cache_peer for true CONNECT requests. * Allows forwarding being-peeked (or stared) at connections to originserver cache_peers. The bug fix described in the first bullet makes the last two changes necessary. This is a Measurement Factory project. --- diff --git a/src/FwdState.cc b/src/FwdState.cc index 7fea9e259c..d0c1b090d3 100644 --- a/src/FwdState.cc +++ b/src/FwdState.cc @@ -683,10 +683,14 @@ FwdState::connectDone(const Comm::ConnectionPointer &conn, Comm::Flag status, in #if USE_OPENSSL if (!request->flags.pinned) { - if ((serverConnection()->getPeer() && serverConnection()->getPeer()->use_ssl) || - (!serverConnection()->getPeer() && request->url.getScheme() == AnyP::PROTO_HTTPS) || - request->flags.sslPeek) { - + const CachePeer *p = serverConnection()->getPeer(); + const bool peerWantsTls = p && p->use_ssl; + // userWillSslToPeerForUs assumes CONNECT == HTTPS + const bool userWillTlsToPeerForUs = p && p->options.originserver && + request->method == Http::METHOD_CONNECT; + const bool needTlsToPeer = peerWantsTls && !userWillTlsToPeerForUs; + const bool needTlsToOrigin = !p && request->url.getScheme() == AnyP::PROTO_HTTPS; + if (needTlsToPeer || needTlsToOrigin || request->flags.sslPeek) { HttpRequest::Pointer requestPointer = request; AsyncCall::Pointer callback = asyncCall(17,4, "FwdState::ConnectedToPeer", @@ -782,7 +786,9 @@ FwdState::connectStart() request->hier.startPeerClock(); - if (serverDestinations[0]->getPeer() && request->flags.sslBumped) { + // Do not fowrward bumped connections to parent proxy unless it is an + // origin server + if (serverDestinations[0]->getPeer() && !serverDestinations[0]->getPeer()->options.originserver && request->flags.sslBumped) { debugs(50, 4, "fwdConnectStart: Ssl bumped connections through parent proxy are not allowed"); ErrorState *anErr = new ErrorState(ERR_CANNOT_FORWARD, Http::scServiceUnavailable, request); fail(anErr); diff --git a/src/neighbors.cc b/src/neighbors.cc index a656193a99..49320f653c 100644 --- a/src/neighbors.cc +++ b/src/neighbors.cc @@ -161,7 +161,7 @@ peerAllowedToUse(const CachePeer * p, HttpRequest * request) // CONNECT requests are proxy requests. Not to be forwarded to origin servers. // Unless the destination port matches, in which case we MAY perform a 'DIRECT' to this CachePeer. - if (p->options.originserver && request->method == Http::METHOD_CONNECT && request->port != p->in_addr.port()) + if (p->options.originserver && request->method == Http::METHOD_CONNECT && request->port != p->http_port) return false; if (p->peer_domain == NULL && p->access == NULL)