]> git.ipfire.org Git - thirdparty/squid.git/blame - src/acl/DestinationIp.cc
SourceFormat Enforcement
[thirdparty/squid.git] / src / acl / DestinationIp.cc
CommitLineData
8000a965 1/*
ef57eb7b 2 * Copyright (C) 1996-2016 The Squid Software Foundation and contributors
8000a965 3 *
bbc27441
AJ
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
8000a965 7 */
8
bbc27441
AJ
9/* DEBUG: section 28 Access Control */
10
582c2af2 11#include "squid.h"
c0941a6a
AR
12#include "acl/DestinationIp.h"
13#include "acl/FilledChecklist.h"
582c2af2 14#include "client_side.h"
bfe4e2fe 15#include "comm/Connection.h"
a2ac85d9 16#include "HttpRequest.h"
4d5904f7 17#include "SquidConfig.h"
8000a965 18
33810b1d
CT
19ACLFlag ACLDestinationIP::SupportedFlags[] = {ACL_F_NO_LOOKUP, ACL_F_END};
20
8000a965 21char const *
22ACLDestinationIP::typeString() const
23{
24 return "dst";
25}
26
27int
c0941a6a 28ACLDestinationIP::match(ACLChecklist *cl)
8000a965 29{
af6a12ee 30 ACLFilledChecklist *checklist = Filled(cl);
bfe4e2fe 31
a3c5c081
AJ
32 // if there is no HTTP request details fallback to the dst_addr
33 if (!checklist->request)
34 return ACLIP::match(checklist->dst_addr);
35
bfe4e2fe
AJ
36 // Bug 3243: CVE 2009-0801
37 // Bypass of browser same-origin access control in intercepted communication
38 // To resolve this we will force DIRECT and only to the original client destination.
39 // In which case, we also need this ACL to accurately match the destination
0d901ef4 40 if (Config.onoff.client_dst_passthru && (checklist->request->flags.intercepted || checklist->request->flags.interceptTproxy)) {
bfe4e2fe
AJ
41 assert(checklist->conn() && checklist->conn()->clientConnection != NULL);
42 return ACLIP::match(checklist->conn()->clientConnection->local);
43 }
44
33810b1d 45 if (flags.isSet(ACL_F_NO_LOOKUP)) {
5c51bffb
AJ
46 if (!checklist->request->url.hostIsNumeric()) {
47 debugs(28, 3, "No-lookup DNS ACL '" << AclMatchedName << "' for " << checklist->request->url.host());
33810b1d
CT
48 return 0;
49 }
50
5c51bffb 51 if (ACLIP::match(checklist->request->url.hostIP()))
33810b1d
CT
52 return 1;
53 return 0;
54 }
55
5c51bffb 56 const ipcache_addrs *ia = ipcache_gethostbyname(checklist->request->url.host(), IP_LOOKUP_IF_MISS);
62e76326 57
8000a965 58 if (ia) {
62e76326 59 /* Entry in cache found */
60
742a021b 61 for (int k = 0; k < (int) ia->count; ++k) {
62e76326 62 if (ACLIP::match(ia->in_addrs[k]))
63 return 1;
64 }
65
66 return 0;
450fe1cb 67 } else if (!checklist->request->flags.destinationIpLookedUp) {
62e76326 68 /* No entry in cache, lookup not attempted */
5c51bffb 69 debugs(28, 3, "can't yet compare '" << name << "' ACL for " << checklist->request->url.host());
6f58d7d7
AR
70 if (checklist->goAsync(DestinationIPLookup::Instance()))
71 return -1;
72 // else fall through to mismatch, hiding the lookup failure (XXX)
8000a965 73 }
6f58d7d7
AR
74
75 return 0;
8000a965 76}
77
78DestinationIPLookup DestinationIPLookup::instance_;
79
80DestinationIPLookup *
81DestinationIPLookup::Instance()
82{
83 return &instance_;
84}
85
86void
c0941a6a 87DestinationIPLookup::checkForAsync(ACLChecklist *cl)const
8000a965 88{
af6a12ee 89 ACLFilledChecklist *checklist = Filled(cl);
5c51bffb 90 ipcache_nbgethostbyname(checklist->request->url.host(), LookupDone, checklist);
8000a965 91}
92
93void
4a3b98d7 94DestinationIPLookup::LookupDone(const ipcache_addrs *, const Dns::LookupDetails &details, void *data)
8000a965 95{
3ff65596 96 ACLFilledChecklist *checklist = Filled((ACLChecklist*)data);
e857372a 97 checklist->request->flags.destinationIpLookedUp = true;
3ff65596 98 checklist->request->recordLookup(details);
6f58d7d7 99 checklist->resumeNonBlockingCheck(DestinationIPLookup::Instance());
8000a965 100}
101
8000a965 102ACL *
103ACLDestinationIP::clone() const
104{
105 return new ACLDestinationIP(*this);
106}
f53969cc 107