]> git.ipfire.org Git - thirdparty/squid.git/blame - src/acl/DomainData.cc
Merged from trunk
[thirdparty/squid.git] / src / acl / DomainData.cc
CommitLineData
3841dd46 1/*
bbc27441 2 * Copyright (C) 1996-2014 The Squid Software Foundation and contributors
3841dd46 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.
3841dd46 7 */
8
bbc27441
AJ
9/* DEBUG: section 28 Access Control */
10
582c2af2 11#include "squid.h"
3ad63615 12#include "acl/Checklist.h"
602d9612 13#include "acl/DomainData.h"
8a01b99e 14#include "cache_cf.h"
582c2af2 15#include "Debug.h"
c9c46c8b 16#include "src/URL.h"
ed6e9fb9 17#include "util.h"
3841dd46 18
3841dd46 19template<class T>
20inline void
21xRefFree(T &thing)
22{
23 xfree (thing);
24}
25
26ACLDomainData::~ACLDomainData()
27{
28 if (domains)
62e76326 29 domains->destroy(xRefFree);
30}
3841dd46 31
32template<class T>
33inline int
34splaystrcasecmp (T&l, T&r)
35{
36 return strcasecmp ((char *)l,(char *)r);
37}
38
39template<class T>
40inline int
41splaystrcmp (T&l, T&r)
42{
43 return strcmp ((char *)l,(char *)r);
44}
45
46/* general compare functions, these are used for tree search algorithms
47 * so they return <0, 0 or >0 */
48
7e6b941f 49/* compare a host and a domain */
50
51static int
52aclHostDomainCompare( char *const &a, char * const &b)
53{
1dc746da
AJ
54 const char *h = static_cast<const char *>(a);
55 const char *d = static_cast<const char *>(b);
7e6b941f 56 return matchDomainName(h, d);
57}
58
3841dd46 59/* compare two domains */
60
61template<class T>
62int
63aclDomainCompare(T const &a, T const &b)
64{
1dc746da
AJ
65 char * const d1 = static_cast<char *>(b);
66 char * const d2 = static_cast<char *>(a);
3841dd46 67 int ret;
68 ret = aclHostDomainCompare(d1, d2);
62e76326 69
3841dd46 70 if (ret != 0) {
62e76326 71 char *const d3 = d2;
72 char *const d4 = d1;
73 ret = aclHostDomainCompare(d3, d4);
14e563cb
AJ
74 if (ret == 0) {
75 // When a.example.com comes after .example.com in an ACL
76 // sub-domain is ignored. That is okay. Just important
3a835d3f
AJ
77 bool d3big = (strlen(d3) > strlen(d4)); // Always suggest removing the longer one.
78 debugs(28, DBG_IMPORTANT, "WARNING: '" << (d3big?d3:d4) << "' is a subdomain of '" << (d3big?d4:d3) << "'");
79 debugs(28, DBG_IMPORTANT, "WARNING: You should remove '" << (d3big?d3:d4) << "' from the ACL named '" << AclMatchedName << "'");
80 debugs(28, 2, HERE << "Ignore '" << d3 << "' to keep splay tree searching predictable");
14e563cb
AJ
81 }
82 } else if (ret == 0) {
3a835d3f
AJ
83 // It may be an exact duplicate. No problem. Just drop.
84 if (strcmp(d1,d2)==0) {
85 debugs(28, 2, "WARNING: '" << d2 << "' is duplicated in the list.");
86 debugs(28, 2, "WARNING: You should remove one '" << d2 << "' from the ACL named '" << AclMatchedName << "'");
87 return ret;
88 }
14e563cb
AJ
89 // When a.example.com comes before .example.com in an ACL
90 // discarding the wildcard is critically bad.
3a835d3f
AJ
91 // or Maybe even both are wildcards. Things are very weird in those cases.
92 bool d1big = (strlen(d1) > strlen(d2)); // Always suggest removing the longer one.
93 debugs(28, DBG_CRITICAL, "ERROR: '" << (d1big?d1:d2) << "' is a subdomain of '" << (d1big?d2:d1) << "'");
94 debugs(28, DBG_CRITICAL, "ERROR: You need to remove '" << (d1big?d1:d2) << "' from the ACL named '" << AclMatchedName << "'");
14e563cb 95 self_destruct();
3841dd46 96 }
62e76326 97
3841dd46 98 return ret;
99}
100
3841dd46 101bool
102ACLDomainData::match(char const *host)
103{
104 if (host == NULL)
62e76326 105 return 0;
106
bf8fe701 107 debugs(28, 3, "aclMatchDomainList: checking '" << host << "'");
62e76326 108
3841dd46 109 domains = domains->splay((char *)host, aclHostDomainCompare);
62e76326 110
bf8fe701 111 debugs(28, 3, "aclMatchDomainList: '" << host << "' " << (splayLastResult ? "NOT found" : "found"));
62e76326 112
3841dd46 113 return !splayLastResult;
114}
115
116static void
117aclDumpDomainListWalkee(char * const & node_data, void *outlist)
118{
8966008b
FC
119 /* outlist is really a SBufList ** */
120 static_cast<SBufList *>(outlist)->push_back(SBuf(node_data));
3841dd46 121}
122
8966008b 123SBufList
4f8ca96e 124ACLDomainData::dump() const
3841dd46 125{
8966008b 126 SBufList sl;
3841dd46 127 /* damn this is VERY inefficient for long ACL lists... filling
128 * a wordlist this way costs Sum(1,N) iterations. For instance
129 * a 1000-elements list will be filled in 499500 iterations.
130 */
8966008b
FC
131 domains->walk(aclDumpDomainListWalkee, &sl);
132 return sl;
3841dd46 133}
134
135void
136ACLDomainData::parse()
137{
138 char *t = NULL;
62e76326 139
3841dd46 140 while ((t = strtokFile())) {
62e76326 141 Tolower(t);
142 domains = domains->insert(xstrdup(t), aclDomainCompare);
3841dd46 143 }
144}
145
65092baf 146bool
147ACLDomainData::empty() const
148{
290eb6b9 149 return domains->empty();
65092baf 150}
151
5dee515e 152ACLData<char const *> *
3841dd46 153ACLDomainData::clone() const
154{
155 /* Splay trees don't clone yet. */
156 assert (!domains);
157 return new ACLDomainData;
158}
f53969cc 159