]>
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" |
3841dd46 | 43 | |
3841dd46 | 44 | template<class T> |
45 | inline void | |
46 | xRefFree(T &thing) | |
47 | { | |
48 | xfree (thing); | |
49 | } | |
50 | ||
51 | ACLDomainData::~ACLDomainData() | |
52 | { | |
53 | if (domains) | |
62e76326 | 54 | domains->destroy(xRefFree); |
55 | } | |
3841dd46 | 56 | |
57 | template<class T> | |
58 | inline int | |
59 | splaystrcasecmp (T&l, T&r) | |
60 | { | |
61 | return strcasecmp ((char *)l,(char *)r); | |
62 | } | |
63 | ||
64 | template<class T> | |
65 | inline int | |
66 | splaystrcmp (T&l, T&r) | |
67 | { | |
68 | return strcmp ((char *)l,(char *)r); | |
69 | } | |
70 | ||
71 | /* general compare functions, these are used for tree search algorithms | |
72 | * so they return <0, 0 or >0 */ | |
73 | ||
7e6b941f | 74 | /* compare a host and a domain */ |
75 | ||
76 | static int | |
77 | aclHostDomainCompare( char *const &a, char * const &b) | |
78 | { | |
1dc746da AJ |
79 | const char *h = static_cast<const char *>(a); |
80 | const char *d = static_cast<const char *>(b); | |
7e6b941f | 81 | return matchDomainName(h, d); |
82 | } | |
83 | ||
3841dd46 | 84 | /* compare two domains */ |
85 | ||
86 | template<class T> | |
87 | int | |
88 | aclDomainCompare(T const &a, T const &b) | |
89 | { | |
1dc746da AJ |
90 | char * const d1 = static_cast<char *>(b); |
91 | char * const d2 = static_cast<char *>(a); | |
3841dd46 | 92 | int ret; |
93 | ret = aclHostDomainCompare(d1, d2); | |
62e76326 | 94 | |
3841dd46 | 95 | if (ret != 0) { |
62e76326 | 96 | char *const d3 = d2; |
97 | char *const d4 = d1; | |
98 | ret = aclHostDomainCompare(d3, d4); | |
14e563cb AJ |
99 | if (ret == 0) { |
100 | // When a.example.com comes after .example.com in an ACL | |
101 | // sub-domain is ignored. That is okay. Just important | |
102 | debugs(28, DBG_IMPORTANT, "WARNING: '" << d3 << "' is a subdomain of '" << d4 << "'"); | |
103 | debugs(28, DBG_IMPORTANT, "WARNING: because of this '" << d3 << "' is ignored to keep splay tree searching predictable"); | |
104 | debugs(28, DBG_IMPORTANT, "WARNING: You should remove '" << (*d3=='.'?d4:d3) << "' from the ACL named '" << AclMatchedName << "'"); | |
105 | } | |
106 | } else if (ret == 0) { | |
107 | // When a.example.com comes before .example.com in an ACL | |
108 | // discarding the wildcard is critically bad. | |
109 | debugs(28, DBG_CRITICAL, "ERROR: '" << d1 << "' is a subdomain of '" << d2 << "'"); | |
110 | debugs(28, DBG_CRITICAL, "ERROR: because of this '" << d2 << "' is ignored to keep splay tree searching predictable"); | |
111 | debugs(28, DBG_CRITICAL, "ERROR: You should remove '" << (*d1=='.'?d2:d1) << "' from the ACL named '" << AclMatchedName << "'"); | |
112 | self_destruct(); | |
3841dd46 | 113 | } |
62e76326 | 114 | |
3841dd46 | 115 | return ret; |
116 | } | |
117 | ||
3841dd46 | 118 | bool |
119 | ACLDomainData::match(char const *host) | |
120 | { | |
121 | if (host == NULL) | |
62e76326 | 122 | return 0; |
123 | ||
bf8fe701 | 124 | debugs(28, 3, "aclMatchDomainList: checking '" << host << "'"); |
62e76326 | 125 | |
3841dd46 | 126 | domains = domains->splay((char *)host, aclHostDomainCompare); |
62e76326 | 127 | |
bf8fe701 | 128 | debugs(28, 3, "aclMatchDomainList: '" << host << "' " << (splayLastResult ? "NOT found" : "found")); |
62e76326 | 129 | |
3841dd46 | 130 | return !splayLastResult; |
131 | } | |
132 | ||
133 | static void | |
134 | aclDumpDomainListWalkee(char * const & node_data, void *outlist) | |
135 | { | |
136 | /* outlist is really a wordlist ** */ | |
137 | wordlistAdd((wordlist **)outlist, (char const *)node_data); | |
138 | } | |
139 | ||
140 | wordlist * | |
141 | ACLDomainData::dump() | |
142 | { | |
143 | wordlist *wl = NULL; | |
144 | /* damn this is VERY inefficient for long ACL lists... filling | |
145 | * a wordlist this way costs Sum(1,N) iterations. For instance | |
146 | * a 1000-elements list will be filled in 499500 iterations. | |
147 | */ | |
148 | domains->walk(aclDumpDomainListWalkee, &wl); | |
149 | return wl; | |
150 | } | |
151 | ||
152 | void | |
153 | ACLDomainData::parse() | |
154 | { | |
155 | char *t = NULL; | |
62e76326 | 156 | |
3841dd46 | 157 | while ((t = strtokFile())) { |
62e76326 | 158 | Tolower(t); |
159 | domains = domains->insert(xstrdup(t), aclDomainCompare); | |
3841dd46 | 160 | } |
161 | } | |
162 | ||
65092baf | 163 | bool |
164 | ACLDomainData::empty() const | |
165 | { | |
290eb6b9 | 166 | return domains->empty(); |
65092baf | 167 | } |
168 | ||
5dee515e | 169 | ACLData<char const *> * |
3841dd46 | 170 | ACLDomainData::clone() const |
171 | { | |
172 | /* Splay trees don't clone yet. */ | |
173 | assert (!domains); | |
174 | return new ACLDomainData; | |
175 | } |