]>
Commit | Line | Data |
---|---|---|
8000a965 | 1 | /* |
4ac4a490 | 2 | * Copyright (C) 1996-2017 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" |
d3dddfb5 | 16 | #include "http/Stream.h" |
a2ac85d9 | 17 | #include "HttpRequest.h" |
4d5904f7 | 18 | #include "SquidConfig.h" |
8000a965 | 19 | |
33810b1d CT |
20 | ACLFlag ACLDestinationIP::SupportedFlags[] = {ACL_F_NO_LOOKUP, ACL_F_END}; |
21 | ||
8000a965 | 22 | char const * |
23 | ACLDestinationIP::typeString() const | |
24 | { | |
25 | return "dst"; | |
26 | } | |
27 | ||
28 | int | |
c0941a6a | 29 | ACLDestinationIP::match(ACLChecklist *cl) |
8000a965 | 30 | { |
af6a12ee | 31 | ACLFilledChecklist *checklist = Filled(cl); |
bfe4e2fe | 32 | |
a3c5c081 AJ |
33 | // if there is no HTTP request details fallback to the dst_addr |
34 | if (!checklist->request) | |
35 | return ACLIP::match(checklist->dst_addr); | |
36 | ||
bfe4e2fe AJ |
37 | // Bug 3243: CVE 2009-0801 |
38 | // Bypass of browser same-origin access control in intercepted communication | |
39 | // To resolve this we will force DIRECT and only to the original client destination. | |
40 | // In which case, we also need this ACL to accurately match the destination | |
0d901ef4 | 41 | if (Config.onoff.client_dst_passthru && (checklist->request->flags.intercepted || checklist->request->flags.interceptTproxy)) { |
6cf166fc EB |
42 | const auto conn = checklist->conn(); |
43 | return (conn && conn->clientConnection) ? | |
ff89bfa0 | 44 | ACLIP::match(conn->clientConnection->local) : -1; |
bfe4e2fe AJ |
45 | } |
46 | ||
33810b1d | 47 | if (flags.isSet(ACL_F_NO_LOOKUP)) { |
5c51bffb AJ |
48 | if (!checklist->request->url.hostIsNumeric()) { |
49 | debugs(28, 3, "No-lookup DNS ACL '" << AclMatchedName << "' for " << checklist->request->url.host()); | |
33810b1d CT |
50 | return 0; |
51 | } | |
52 | ||
5c51bffb | 53 | if (ACLIP::match(checklist->request->url.hostIP())) |
33810b1d CT |
54 | return 1; |
55 | return 0; | |
56 | } | |
57 | ||
5c51bffb | 58 | const ipcache_addrs *ia = ipcache_gethostbyname(checklist->request->url.host(), IP_LOOKUP_IF_MISS); |
62e76326 | 59 | |
8000a965 | 60 | if (ia) { |
62e76326 | 61 | /* Entry in cache found */ |
62 | ||
742a021b | 63 | for (int k = 0; k < (int) ia->count; ++k) { |
62e76326 | 64 | if (ACLIP::match(ia->in_addrs[k])) |
65 | return 1; | |
66 | } | |
67 | ||
68 | return 0; | |
450fe1cb | 69 | } else if (!checklist->request->flags.destinationIpLookedUp) { |
62e76326 | 70 | /* No entry in cache, lookup not attempted */ |
5c51bffb | 71 | debugs(28, 3, "can't yet compare '" << name << "' ACL for " << checklist->request->url.host()); |
6f58d7d7 AR |
72 | if (checklist->goAsync(DestinationIPLookup::Instance())) |
73 | return -1; | |
74 | // else fall through to mismatch, hiding the lookup failure (XXX) | |
8000a965 | 75 | } |
6f58d7d7 AR |
76 | |
77 | return 0; | |
8000a965 | 78 | } |
79 | ||
80 | DestinationIPLookup DestinationIPLookup::instance_; | |
81 | ||
82 | DestinationIPLookup * | |
83 | DestinationIPLookup::Instance() | |
84 | { | |
85 | return &instance_; | |
86 | } | |
87 | ||
88 | void | |
c0941a6a | 89 | DestinationIPLookup::checkForAsync(ACLChecklist *cl)const |
8000a965 | 90 | { |
af6a12ee | 91 | ACLFilledChecklist *checklist = Filled(cl); |
5c51bffb | 92 | ipcache_nbgethostbyname(checklist->request->url.host(), LookupDone, checklist); |
8000a965 | 93 | } |
94 | ||
95 | void | |
4a3b98d7 | 96 | DestinationIPLookup::LookupDone(const ipcache_addrs *, const Dns::LookupDetails &details, void *data) |
8000a965 | 97 | { |
3ff65596 | 98 | ACLFilledChecklist *checklist = Filled((ACLChecklist*)data); |
e857372a | 99 | checklist->request->flags.destinationIpLookedUp = true; |
3ff65596 | 100 | checklist->request->recordLookup(details); |
6f58d7d7 | 101 | checklist->resumeNonBlockingCheck(DestinationIPLookup::Instance()); |
8000a965 | 102 | } |
103 | ||
8000a965 | 104 | ACL * |
105 | ACLDestinationIP::clone() const | |
106 | { | |
107 | return new ACLDestinationIP(*this); | |
108 | } | |
f53969cc | 109 |