]>
Commit | Line | Data |
---|---|---|
3841dd46 | 1 | /* |
262a0e14 | 2 | * $Id$ |
3841dd46 | 3 | * |
4 | * DEBUG: section 28 Access Control | |
5 | * AUTHOR: Duane Wessels | |
6 | * | |
7 | * SQUID Web Proxy Cache http://www.squid-cache.org/ | |
8 | * ---------------------------------------------------------- | |
9 | * | |
10 | * Squid is the result of efforts by numerous individuals from | |
11 | * the Internet community; see the CONTRIBUTORS file for full | |
12 | * details. Many organizations have provided support for Squid's | |
13 | * development; see the SPONSORS file for full details. Squid is | |
14 | * Copyrighted (C) 2001 by the Regents of the University of | |
15 | * California; see the COPYRIGHT file for full details. Squid | |
16 | * incorporates software developed and/or copyrighted by other | |
17 | * sources; see the CREDITS file for full details. | |
18 | * | |
19 | * This program is free software; you can redistribute it and/or modify | |
20 | * it under the terms of the GNU General Public License as published by | |
21 | * the Free Software Foundation; either version 2 of the License, or | |
22 | * (at your option) any later version. | |
26ac0430 | 23 | * |
3841dd46 | 24 | * This program is distributed in the hope that it will be useful, |
25 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
26 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
27 | * GNU General Public License for more details. | |
26ac0430 | 28 | * |
3841dd46 | 29 | * You should have received a copy of the GNU General Public License |
30 | * along with this program; if not, write to the Free Software | |
31 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. | |
32 | * | |
33 | * | |
34 | * Copyright (c) 2003, Robert Collins <robertc@squid-cache.org> | |
35 | */ | |
36 | ||
582c2af2 | 37 | #include "squid.h" |
3ad63615 AR |
38 | #include "acl/DomainData.h" |
39 | #include "acl/Checklist.h" | |
582c2af2 FC |
40 | #include "Debug.h" |
41 | #include "protos.h" | |
d295d770 | 42 | #include "wordlist.h" |
b1bd952a | 43 | #include "URL.h" |
3841dd46 | 44 | |
3841dd46 | 45 | template<class T> |
46 | inline void | |
47 | xRefFree(T &thing) | |
48 | { | |
49 | xfree (thing); | |
50 | } | |
51 | ||
52 | ACLDomainData::~ACLDomainData() | |
53 | { | |
54 | if (domains) | |
62e76326 | 55 | domains->destroy(xRefFree); |
56 | } | |
3841dd46 | 57 | |
58 | template<class T> | |
59 | inline int | |
60 | splaystrcasecmp (T&l, T&r) | |
61 | { | |
62 | return strcasecmp ((char *)l,(char *)r); | |
63 | } | |
64 | ||
65 | template<class T> | |
66 | inline int | |
67 | splaystrcmp (T&l, T&r) | |
68 | { | |
69 | return strcmp ((char *)l,(char *)r); | |
70 | } | |
71 | ||
72 | /* general compare functions, these are used for tree search algorithms | |
73 | * so they return <0, 0 or >0 */ | |
74 | ||
7e6b941f | 75 | /* compare a host and a domain */ |
76 | ||
77 | static int | |
78 | aclHostDomainCompare( char *const &a, char * const &b) | |
79 | { | |
1dc746da AJ |
80 | const char *h = static_cast<const char *>(a); |
81 | const char *d = static_cast<const char *>(b); | |
7e6b941f | 82 | return matchDomainName(h, d); |
83 | } | |
84 | ||
85 | ||
3841dd46 | 86 | /* compare two domains */ |
87 | ||
88 | template<class T> | |
89 | int | |
90 | aclDomainCompare(T const &a, T const &b) | |
91 | { | |
1dc746da AJ |
92 | char * const d1 = static_cast<char *>(b); |
93 | char * const d2 = static_cast<char *>(a); | |
3841dd46 | 94 | int ret; |
95 | ret = aclHostDomainCompare(d1, d2); | |
62e76326 | 96 | |
3841dd46 | 97 | if (ret != 0) { |
62e76326 | 98 | char *const d3 = d2; |
99 | char *const d4 = d1; | |
100 | ret = aclHostDomainCompare(d3, d4); | |
14e563cb AJ |
101 | if (ret == 0) { |
102 | // When a.example.com comes after .example.com in an ACL | |
103 | // sub-domain is ignored. That is okay. Just important | |
104 | debugs(28, DBG_IMPORTANT, "WARNING: '" << d3 << "' is a subdomain of '" << d4 << "'"); | |
105 | debugs(28, DBG_IMPORTANT, "WARNING: because of this '" << d3 << "' is ignored to keep splay tree searching predictable"); | |
106 | debugs(28, DBG_IMPORTANT, "WARNING: You should remove '" << (*d3=='.'?d4:d3) << "' from the ACL named '" << AclMatchedName << "'"); | |
107 | } | |
108 | } else if (ret == 0) { | |
109 | // When a.example.com comes before .example.com in an ACL | |
110 | // discarding the wildcard is critically bad. | |
111 | debugs(28, DBG_CRITICAL, "ERROR: '" << d1 << "' is a subdomain of '" << d2 << "'"); | |
112 | debugs(28, DBG_CRITICAL, "ERROR: because of this '" << d2 << "' is ignored to keep splay tree searching predictable"); | |
113 | debugs(28, DBG_CRITICAL, "ERROR: You should remove '" << (*d1=='.'?d2:d1) << "' from the ACL named '" << AclMatchedName << "'"); | |
114 | self_destruct(); | |
3841dd46 | 115 | } |
62e76326 | 116 | |
3841dd46 | 117 | return ret; |
118 | } | |
119 | ||
3841dd46 | 120 | bool |
121 | ACLDomainData::match(char const *host) | |
122 | { | |
123 | if (host == NULL) | |
62e76326 | 124 | return 0; |
125 | ||
bf8fe701 | 126 | debugs(28, 3, "aclMatchDomainList: checking '" << host << "'"); |
62e76326 | 127 | |
3841dd46 | 128 | domains = domains->splay((char *)host, aclHostDomainCompare); |
62e76326 | 129 | |
bf8fe701 | 130 | debugs(28, 3, "aclMatchDomainList: '" << host << "' " << (splayLastResult ? "NOT found" : "found")); |
62e76326 | 131 | |
3841dd46 | 132 | return !splayLastResult; |
133 | } | |
134 | ||
135 | static void | |
136 | aclDumpDomainListWalkee(char * const & node_data, void *outlist) | |
137 | { | |
138 | /* outlist is really a wordlist ** */ | |
139 | wordlistAdd((wordlist **)outlist, (char const *)node_data); | |
140 | } | |
141 | ||
142 | wordlist * | |
143 | ACLDomainData::dump() | |
144 | { | |
145 | wordlist *wl = NULL; | |
146 | /* damn this is VERY inefficient for long ACL lists... filling | |
147 | * a wordlist this way costs Sum(1,N) iterations. For instance | |
148 | * a 1000-elements list will be filled in 499500 iterations. | |
149 | */ | |
150 | domains->walk(aclDumpDomainListWalkee, &wl); | |
151 | return wl; | |
152 | } | |
153 | ||
154 | void | |
155 | ACLDomainData::parse() | |
156 | { | |
157 | char *t = NULL; | |
62e76326 | 158 | |
3841dd46 | 159 | while ((t = strtokFile())) { |
62e76326 | 160 | Tolower(t); |
161 | domains = domains->insert(xstrdup(t), aclDomainCompare); | |
3841dd46 | 162 | } |
163 | } | |
164 | ||
65092baf | 165 | bool |
166 | ACLDomainData::empty() const | |
167 | { | |
290eb6b9 | 168 | return domains->empty(); |
65092baf | 169 | } |
170 | ||
3841dd46 | 171 | |
5dee515e | 172 | ACLData<char const *> * |
3841dd46 | 173 | ACLDomainData::clone() const |
174 | { | |
175 | /* Splay trees don't clone yet. */ | |
176 | assert (!domains); | |
177 | return new ACLDomainData; | |
178 | } |