]> git.ipfire.org Git - thirdparty/squid.git/blobdiff - src/acl/DestinationIp.cc
Docs: Copyright updates for 2018 (#114)
[thirdparty/squid.git] / src / acl / DestinationIp.cc
index 5aeb762f687170ed964c9f0d03060f7b44c1fb99..a5e6cc97abc7de5ad6671c204eee03c40a96244b 100644 (file)
@@ -1,43 +1,21 @@
 /*
- * DEBUG: section 28    Access Control
- * AUTHOR: Duane Wessels
+ * Copyright (C) 1996-2018 The Squid Software Foundation and contributors
  *
- * SQUID Web Proxy Cache          http://www.squid-cache.org/
- * ----------------------------------------------------------
- *
- *  Squid is the result of efforts by numerous individuals from
- *  the Internet community; see the CONTRIBUTORS file for full
- *  details.   Many organizations have provided support for Squid's
- *  development; see the SPONSORS file for full details.  Squid is
- *  Copyrighted (C) 2001 by the Regents of the University of
- *  California; see the COPYRIGHT file for full details.  Squid
- *  incorporates software developed and/or copyrighted by other
- *  sources; see the CREDITS file for full details.
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
- *
- * Copyright (c) 2003, Robert Collins <robertc@squid-cache.org>
+ * Squid software is distributed under GPLv2+ license and includes
+ * contributions from numerous individuals and organizations.
+ * Please see the COPYING and CONTRIBUTORS files for details.
  */
 
+/* DEBUG: section 28    Access Control */
+
 #include "squid.h"
 #include "acl/DestinationIp.h"
 #include "acl/FilledChecklist.h"
 #include "client_side.h"
 #include "comm/Connection.h"
+#include "http/Stream.h"
 #include "HttpRequest.h"
-#include "structs.h"
+#include "SquidConfig.h"
 
 char const *
 ACLDestinationIP::typeString() const
@@ -45,40 +23,65 @@ ACLDestinationIP::typeString() const
     return "dst";
 }
 
+const Acl::Options &
+ACLDestinationIP::options()
+{
+    static const Acl::BooleanOption LookupBan;
+    static const Acl::Options MyOptions = { { "-n", &LookupBan } };
+    LookupBan.linkWith(&lookupBanned);
+    return MyOptions;
+}
+
 int
 ACLDestinationIP::match(ACLChecklist *cl)
 {
     ACLFilledChecklist *checklist = Filled(cl);
 
+    // if there is no HTTP request details fallback to the dst_addr
+    if (!checklist->request)
+        return ACLIP::match(checklist->dst_addr);
+
     // Bug 3243: CVE 2009-0801
     // Bypass of browser same-origin access control in intercepted communication
     // To resolve this we will force DIRECT and only to the original client destination.
     // In which case, we also need this ACL to accurately match the destination
-    if (Config.onoff.client_dst_passthru && checklist->request &&
-            (checklist->request->flags.intercepted || checklist->request->flags.spoof_client_ip)) {
-        assert(checklist->conn() && checklist->conn()->clientConnection != NULL);
-        return ACLIP::match(checklist->conn()->clientConnection->local);
+    if (Config.onoff.client_dst_passthru && (checklist->request->flags.intercepted || checklist->request->flags.interceptTproxy)) {
+        const auto conn = checklist->conn();
+        return (conn && conn->clientConnection) ?
+               ACLIP::match(conn->clientConnection->local) : -1;
     }
 
-    const ipcache_addrs *ia = ipcache_gethostbyname(checklist->request->GetHost(), IP_LOOKUP_IF_MISS);
+    if (lookupBanned) {
+        if (!checklist->request->url.hostIsNumeric()) {
+            debugs(28, 3, "No-lookup DNS ACL '" << AclMatchedName << "' for " << checklist->request->url.host());
+            return 0;
+        }
+
+        if (ACLIP::match(checklist->request->url.hostIP()))
+            return 1;
+        return 0;
+    }
+
+    const ipcache_addrs *ia = ipcache_gethostbyname(checklist->request->url.host(), IP_LOOKUP_IF_MISS);
 
     if (ia) {
         /* Entry in cache found */
 
-        for (int k = 0; k < (int) ia->count; ++k) {
-            if (ACLIP::match(ia->in_addrs[k]))
+        for (const auto ip: ia->goodAndBad()) {
+            if (ACLIP::match(ip))
                 return 1;
         }
 
         return 0;
-    } else if (!checklist->request->flags.destinationIPLookedUp()) {
+    } else if (!checklist->request->flags.destinationIpLookedUp) {
         /* No entry in cache, lookup not attempted */
-        debugs(28, 3, "aclMatchAcl: Can't yet compare '" << name << "' ACL for '" << checklist->request->GetHost() << "'");
-        checklist->changeState (DestinationIPLookup::Instance());
-        return 0;
-    } else {
-        return 0;
+        debugs(28, 3, "can't yet compare '" << name << "' ACL for " << checklist->request->url.host());
+        if (checklist->goAsync(DestinationIPLookup::Instance()))
+            return -1;
+        // else fall through to mismatch, hiding the lookup failure (XXX)
     }
+
+    return 0;
 }
 
 DestinationIPLookup DestinationIPLookup::instance_;
@@ -93,20 +96,16 @@ void
 DestinationIPLookup::checkForAsync(ACLChecklist *cl)const
 {
     ACLFilledChecklist *checklist = Filled(cl);
-    checklist->asyncInProgress(true);
-    ipcache_nbgethostbyname(checklist->request->GetHost(), LookupDone, checklist);
+    ipcache_nbgethostbyname(checklist->request->url.host(), LookupDone, checklist);
 }
 
 void
-DestinationIPLookup::LookupDone(const ipcache_addrs *, const DnsLookupDetails &details, void *data)
+DestinationIPLookup::LookupDone(const ipcache_addrs *, const Dns::LookupDetails &details, void *data)
 {
     ACLFilledChecklist *checklist = Filled((ACLChecklist*)data);
-    assert (checklist->asyncState() == DestinationIPLookup::Instance());
-    checklist->request->flags.destinationIPLookupCompleted();
+    checklist->request->flags.destinationIpLookedUp = true;
     checklist->request->recordLookup(details);
-    checklist->asyncInProgress(false);
-    checklist->changeState (ACLChecklist::NullState::Instance());
-    checklist->matchNonBlocking();
+    checklist->resumeNonBlockingCheck(DestinationIPLookup::Instance());
 }
 
 ACL *
@@ -114,3 +113,4 @@ ACLDestinationIP::clone() const
 {
     return new ACLDestinationIP(*this);
 }
+