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