]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
SSL-Bump: tproxy does not spoof spliced connections
authorChristos Tsantilas <chtsanti@users.sourceforge.net>
Thu, 29 Jun 2017 10:46:49 +0000 (22:46 +1200)
committerAmos Jeffries <squid3@treenet.co.nz>
Thu, 29 Jun 2017 10:46:49 +0000 (22:46 +1200)
Squid does not spoof client IP addresses when splicing after peeking/staring.

This is a Measurement Factory project

src/HttpRequest.cc
src/HttpRequest.h
src/client_side.cc

index a437b21d40d535274f534172d97b6d7d1fc151a1..33746331624106d9f1e4d99d10c5ecb99f5de9c8 100644 (file)
@@ -13,6 +13,7 @@
 #include "acl/AclSizeLimit.h"
 #include "acl/FilledChecklist.h"
 #include "client_side.h"
+#include "client_side_request.h"
 #include "dns/LookupDetails.h"
 #include "Downloader.h"
 #include "err_detail_type.h"
@@ -671,3 +672,41 @@ HttpRequest::effectiveRequestUri() const
     return url.absolute();
 }
 
+void
+HttpRequest::manager(const CbcPointer<ConnStateData> &aMgr, const AccessLogEntryPointer &al)
+{
+    clientConnectionManager = aMgr;
+
+    if (!clientConnectionManager.valid())
+        return;
+
+    AnyP::PortCfgPointer port = clientConnectionManager->port;
+    if (port) {
+        myportname = port->name;
+        flags.ignoreCc = port->ignore_cc;
+    }
+
+    if (auto clientConnection = clientConnectionManager->clientConnection) {
+        client_addr = clientConnection->remote; // XXX: remove request->client_addr member.
+#if FOLLOW_X_FORWARDED_FOR
+        // indirect client gets stored here because it is an HTTP header result (from X-Forwarded-For:)
+        // not details about the TCP connection itself
+        indirect_client_addr = clientConnection->remote;
+#endif /* FOLLOW_X_FORWARDED_FOR */
+        my_addr = clientConnection->local;
+
+        flags.intercepted = ((clientConnection->flags & COMM_INTERCEPTION) != 0);
+        flags.interceptTproxy = ((clientConnection->flags & COMM_TRANSPARENT) != 0 ) ;
+        const bool proxyProtocolPort = port ? port->flags.proxySurrogate : false;
+        if (flags.interceptTproxy && !proxyProtocolPort) {
+            if (Config.accessList.spoof_client_ip) {
+                ACLFilledChecklist *checklist = new ACLFilledChecklist(Config.accessList.spoof_client_ip, this, clientConnection->rfc931);
+                checklist->al = al;
+                flags.spoofClientIp = (checklist->fastCheck() == ACCESS_ALLOWED);
+                delete checklist;
+            } else
+                flags.spoofClientIp = true;
+        } else
+            flags.spoofClientIp = false;
+    }
+}
index 5f445ab632f9b58896a6aa625fbdf1e899660bb8..562851063c96dd304bc788fbdd56ec697c948cad 100644 (file)
@@ -36,6 +36,8 @@
 
 class ConnStateData;
 class Downloader;
+class AccessLogEntry;
+typedef RefCount<AccessLogEntry> AccessLogEntryPointer;
 
 /*  Http Request */
 void httpRequestPack(void *obj, Packable *p);
@@ -88,6 +90,9 @@ public:
     /// clear error details, useful for retries/repeats
     void clearError();
 
+    /// associates the request with a from-client connection manager
+    void manager(const CbcPointer<ConnStateData> &aMgr, const AccessLogEntryPointer &al);
+
 protected:
     void clean();
 
index 6ac4583b88f46f3fc8fb04ba1796be986cc54b12..108955eb66ef3159875faf1925d75a6b2c0e6309 100644 (file)
@@ -1633,11 +1633,10 @@ clientProcessRequest(ConnStateData *conn, const Http1::RequestParserPointer &hp,
     // this entire function to remove them from the FTP code path. Connection
     // setup and body_pipe preparation blobs are needed for FTP.
 
-    request->clientConnectionManager = conn;
+    request->manager(conn, http->al);
 
     request->flags.accelerated = http->flags.accel;
     request->flags.sslBumped=conn->switchedToHttps();
-    request->flags.ignoreCc = conn->port->ignore_cc;
     // TODO: decouple http->flags.accel from request->flags.sslBumped
     request->flags.noDirect = (request->flags.accelerated && !request->flags.sslBumped) ?
                               !conn->port->allow_direct : 0;
@@ -1650,25 +1649,6 @@ clientProcessRequest(ConnStateData *conn, const Http1::RequestParserPointer &hp,
     }
 #endif
 
-    /** \par
-     * If transparent or interception mode is working clone the transparent and interception flags
-     * from the port settings to the request.
-     */
-    if (http->clientConnection != NULL) {
-        request->flags.intercepted = ((http->clientConnection->flags & COMM_INTERCEPTION) != 0);
-        request->flags.interceptTproxy = ((http->clientConnection->flags & COMM_TRANSPARENT) != 0 ) ;
-        static const bool proxyProtocolPort = (conn->port != NULL) ? conn->port->flags.proxySurrogate : false;
-        if (request->flags.interceptTproxy && !proxyProtocolPort) {
-            if (Config.accessList.spoof_client_ip) {
-                ACLFilledChecklist *checklist = clientAclChecklistCreate(Config.accessList.spoof_client_ip, http);
-                request->flags.spoofClientIp = (checklist->fastCheck() == ACCESS_ALLOWED);
-                delete checklist;
-            } else
-                request->flags.spoofClientIp = true;
-        } else
-            request->flags.spoofClientIp = false;
-    }
-
     if (internalCheck(request->url.path())) {
         if (internalHostnameIs(request->url.host()) && request->url.port() == getMyPort()) {
             debugs(33, 2, "internal URL found: " << request->url.getScheme() << "://" << request->url.authority(true));
@@ -1685,14 +1665,6 @@ clientProcessRequest(ConnStateData *conn, const Http1::RequestParserPointer &hp,
 
     request->flags.internal = http->flags.internal;
     setLogUri (http, urlCanonicalClean(request.getRaw()));
-    request->client_addr = conn->clientConnection->remote; // XXX: remove request->client_addr member.
-#if FOLLOW_X_FORWARDED_FOR
-    // indirect client gets stored here because it is an HTTP header result (from X-Forwarded-For:)
-    // not details about the TCP connection itself
-    request->indirect_client_addr = conn->clientConnection->remote;
-#endif /* FOLLOW_X_FORWARDED_FOR */
-    request->my_addr = conn->clientConnection->local;
-    request->myportname = conn->port->name;
 
     if (!isFtp) {
         // XXX: for non-HTTP messages instantiate a different HttpMsg child type
@@ -1703,10 +1675,6 @@ clientProcessRequest(ConnStateData *conn, const Http1::RequestParserPointer &hp,
         request->http_ver.minor = http_ver.minor;
     }
 
-    // Link this HttpRequest to ConnStateData relatively early so the following complex handling can use it
-    // TODO: this effectively obsoletes a lot of conn->FOO copying. That needs cleaning up later.
-    request->clientConnectionManager = conn;
-
     if (request->header.chunked()) {
         chunked = true;
     } else if (request->header.has(Http::HdrType::TRANSFER_ENCODING)) {
@@ -3450,23 +3418,16 @@ ConnStateData::buildFakeRequest(Http::MethodType const method, SBuf &useHost, un
     http->request = request.getRaw();
     HTTPMSGLOCK(http->request);
 
-    request->clientConnectionManager = this;
+    request->manager(this, http->al);
 
     if (proto == AnyP::PROTO_HTTP)
         request->header.putStr(Http::HOST, useHost.c_str());
-    request->flags.intercepted = ((clientConnection->flags & COMM_INTERCEPTION) != 0);
-    request->flags.interceptTproxy = ((clientConnection->flags & COMM_TRANSPARENT) != 0 );
+
     request->sources |= ((switchedToHttps() || port->transport.protocol == AnyP::PROTO_HTTPS) ? HttpMsg::srcHttps : HttpMsg::srcHttp);
 #if USE_AUTH
     if (getAuth())
         request->auth_user_request = getAuth();
 #endif
-    request->client_addr = clientConnection->remote;
-#if FOLLOW_X_FORWARDED_FOR
-    request->indirect_client_addr = clientConnection->remote;
-#endif /* FOLLOW_X_FORWARDED_FOR */
-    request->my_addr = clientConnection->local;
-    request->myportname = port->name;
 
     inBuf = payload;
     flags.readMore = false;