]> git.ipfire.org Git - thirdparty/squid.git/blobdiff - src/servers/FtpServer.cc
Minimize direct comparisons with ACCESS_ALLOWED and ACCESS_DENIED.
[thirdparty/squid.git] / src / servers / FtpServer.cc
index 2e6e32cba1d4a7511285eab84656de58c291435e..5968695c1caecadc125c0623c42a49081a496478 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1996-2016 The Squid Software Foundation and contributors
+ * Copyright (C) 1996-2017 The Squid Software Foundation and contributors
  *
  * Squid software is distributed under GPLv2+ license and includes
  * contributions from numerous individuals and organizations.
@@ -152,7 +152,7 @@ Ftp::Server::doProcessRequest()
 }
 
 void
-Ftp::Server::processParsedRequest(Http::Stream *)
+Ftp::Server::processParsedRequest(Http::StreamPointer &)
 {
     Must(pipeline.count() == 1);
 
@@ -728,7 +728,9 @@ Ftp::Server::parseOneRequest()
                        &params : NULL;
     calcUri(path);
     char *newUri = xstrdup(uri.c_str());
-    HttpRequest *const request = HttpRequest::CreateFromUrl(newUri, method);
+    MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initClient);
+    mx->tcpClient = clientConnection;
+    HttpRequest *const request = HttpRequest::FromUrl(newUri, mx, method);
     if (!request) {
         debugs(33, 5, "Invalid FTP URL: " << uri);
         uri.clear();
@@ -1153,12 +1155,13 @@ Ftp::Server::writeForwardedForeign(const HttpReply *reply)
     writeErrorReply(reply, 451);
 }
 
-void
+bool
 Ftp::Server::writeControlMsgAndCall(HttpReply *reply, AsyncCall::Pointer &call)
 {
     // the caller guarantees that we are dealing with the current context only
     // the caller should also make sure reply->header.has(Http::HdrType::FTP_STATUS)
     writeForwardedReplyAndCall(reply, call);
+    return true;
 }
 
 void
@@ -1452,9 +1455,33 @@ Ftp::Server::createDataConnection(Ip::Address cltAddr)
     Comm::ConnectionPointer conn = new Comm::Connection();
     conn->flags |= COMM_DOBIND;
 
-    // Use local IP address of the control connection as the source address
-    // of the active data connection, or some clients will refuse to accept.
-    conn->setAddrs(clientConnection->local, cltAddr);
+    if (clientConnection->flags & COMM_INTERCEPTION) {
+        // In the case of NAT interception conn->local value is not set
+        // because the TCP stack will automatically pick correct source
+        // address for the data connection. We must only ensure that IP
+        // version matches client's address.
+        conn->local.setAnyAddr();
+
+        if (cltAddr.isIPv4())
+            conn->local.setIPv4();
+
+        conn->remote = cltAddr;
+    } else {
+        // In the case of explicit-proxy the local IP of the control connection
+        // is the Squid IP the client is knowingly talking to.
+        //
+        // In the case of TPROXY the IP address of the control connection is
+        // server IP the client is connecting to, it can be spoofed by Squid.
+        //
+        // In both cases some clients may refuse to accept data connections if
+        // these control connectin local-IP's are not used.
+        conn->setAddrs(clientConnection->local, cltAddr);
+
+        // Using non-local addresses in TPROXY mode requires appropriate socket option.
+        if (clientConnection->flags & COMM_TRANSPARENT)
+            conn->flags |= COMM_TRANSPARENT;
+    }
+
     // RFC 959 requires active FTP connections to originate from port 20
     // but that would preclude us from supporting concurrent transfers! (XXX?)
     conn->local.port(0);
@@ -1520,7 +1547,7 @@ Ftp::Server::handleUploadRequest(String &, String &)
         ClientHttpRequest *http = pipeline.front()->http;
         HttpRequest *request = http->request;
         ACLFilledChecklist bodyContinuationCheck(Config.accessList.forceRequestBodyContinuation, request, NULL);
-        if (bodyContinuationCheck.fastCheck() == ACCESS_ALLOWED) {
+        if (bodyContinuationCheck.fastCheck().allowed()) {
             request->forcedBodyContinuation = true;
             if (checkDataConnPost()) {
                 // Write control Msg