]> git.ipfire.org Git - thirdparty/squid.git/blob - src/acl/DestinationIp.cc
SourceFormat Enforcement
[thirdparty/squid.git] / src / acl / DestinationIp.cc
1 /*
2 * Copyright (C) 1996-2014 The Squid Software Foundation and contributors
3 *
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.
7 */
8
9 /* DEBUG: section 28 Access Control */
10
11 #include "squid.h"
12 #include "acl/DestinationIp.h"
13 #include "acl/FilledChecklist.h"
14 #include "client_side.h"
15 #include "comm/Connection.h"
16 #include "HttpRequest.h"
17 #include "SquidConfig.h"
18
19 ACLFlag ACLDestinationIP::SupportedFlags[] = {ACL_F_NO_LOOKUP, ACL_F_END};
20
21 char const *
22 ACLDestinationIP::typeString() const
23 {
24 return "dst";
25 }
26
27 int
28 ACLDestinationIP::match(ACLChecklist *cl)
29 {
30 ACLFilledChecklist *checklist = Filled(cl);
31
32 // Bug 3243: CVE 2009-0801
33 // Bypass of browser same-origin access control in intercepted communication
34 // To resolve this we will force DIRECT and only to the original client destination.
35 // In which case, we also need this ACL to accurately match the destination
36 if (Config.onoff.client_dst_passthru && (checklist->request->flags.intercepted || checklist->request->flags.interceptTproxy)) {
37 assert(checklist->conn() && checklist->conn()->clientConnection != NULL);
38 return ACLIP::match(checklist->conn()->clientConnection->local);
39 }
40
41 if (flags.isSet(ACL_F_NO_LOOKUP)) {
42 if (!checklist->request->GetHostIsNumeric()) {
43 debugs(28, 3, "aclMatchAcl: No-lookup DNS ACL '" << AclMatchedName << "' for '" << checklist->request->GetHost() << "'");
44 return 0;
45 }
46
47 if (ACLIP::match(checklist->request->host_addr))
48 return 1;
49 return 0;
50 }
51
52 const ipcache_addrs *ia = ipcache_gethostbyname(checklist->request->GetHost(), IP_LOOKUP_IF_MISS);
53
54 if (ia) {
55 /* Entry in cache found */
56
57 for (int k = 0; k < (int) ia->count; ++k) {
58 if (ACLIP::match(ia->in_addrs[k]))
59 return 1;
60 }
61
62 return 0;
63 } else if (!checklist->request->flags.destinationIpLookedUp) {
64 /* No entry in cache, lookup not attempted */
65 debugs(28, 3, "aclMatchAcl: Can't yet compare '" << name << "' ACL for '" << checklist->request->GetHost() << "'");
66 if (checklist->goAsync(DestinationIPLookup::Instance()))
67 return -1;
68 // else fall through to mismatch, hiding the lookup failure (XXX)
69 }
70
71 return 0;
72 }
73
74 DestinationIPLookup DestinationIPLookup::instance_;
75
76 DestinationIPLookup *
77 DestinationIPLookup::Instance()
78 {
79 return &instance_;
80 }
81
82 void
83 DestinationIPLookup::checkForAsync(ACLChecklist *cl)const
84 {
85 ACLFilledChecklist *checklist = Filled(cl);
86 ipcache_nbgethostbyname(checklist->request->GetHost(), LookupDone, checklist);
87 }
88
89 void
90 DestinationIPLookup::LookupDone(const ipcache_addrs *, const DnsLookupDetails &details, void *data)
91 {
92 ACLFilledChecklist *checklist = Filled((ACLChecklist*)data);
93 checklist->request->flags.destinationIpLookedUp = true;
94 checklist->request->recordLookup(details);
95 checklist->resumeNonBlockingCheck(DestinationIPLookup::Instance());
96 }
97
98 ACL *
99 ACLDestinationIP::clone() const
100 {
101 return new ACLDestinationIP(*this);
102 }
103