DomainData.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1996-2023 The Squid Software Foundation and contributors
3  *
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.
7  */
8 
9 /* DEBUG: section 28 Access Control */
10 
11 #include "squid.h"
12 #include "acl/Checklist.h"
13 #include "acl/DomainData.h"
14 #include "acl/SplayInserter.h"
15 #include "anyp/Uri.h"
16 #include "cache_cf.h"
17 #include "ConfigParser.h"
18 #include "debug/Stream.h"
19 #include "util.h"
20 
21 template<class T>
22 inline void
23 xRefFree(T &thing)
24 {
25  xfree (thing);
26 }
27 
29 {
30  if (domains) {
32  delete domains;
33  }
34 }
35 
36 template<class T>
37 inline int
38 splaystrcasecmp (T&l, T&r)
39 {
40  return strcasecmp ((char *)l,(char *)r);
41 }
42 
43 template<class T>
44 inline int
45 splaystrcmp (T&l, T&r)
46 {
47  return strcmp ((char *)l,(char *)r);
48 }
49 
50 /* general compare functions, these are used for tree search algorithms
51  * so they return <0, 0 or >0 */
52 
53 /* compare a host and a domain */
54 
55 static int
56 aclHostDomainCompare( char *const &a, char * const &b)
57 {
58  const char *h = static_cast<const char *>(a);
59  const char *d = static_cast<const char *>(b);
60  return matchDomainName(h, d);
61 }
62 
63 bool
64 ACLDomainData::match(char const *host)
65 {
66  if (host == nullptr)
67  return 0;
68 
69  debugs(28, 3, "aclMatchDomainList: checking '" << host << "'");
70 
71  char *h = const_cast<char *>(host);
72  char const * const * result = domains->find(h, aclHostDomainCompare);
73 
74  debugs(28, 3, "aclMatchDomainList: '" << host << "' " << (result ? "found" : "NOT found"));
75 
76  return (result != nullptr);
77 }
78 
81  void operator() (char * const & node_data) {
82  contents.push_back(SBuf(node_data));
83  }
84 };
85 
88 {
90  domains->visit(visitor);
91  return visitor.contents;
92 }
93 
94 template <>
95 int
97 {
98  // If X represents a set of matching domain names (e.g., .example.com), then
99  // matchDomainName(X, Y) uses a single domain name from X by removing the
100  // leading dot (e.g., example.com). We call that name "the root of X". If X
101  // is a single domain name, then its root is X itself. Since domain sets
102  // cannot have _partial_ overlaps (unlike IP or integer ranges), testing
103  // roots is enough to detect duplicates and establish correct set order.
104 
105  if (matchDomainName(b, a)) {
106  // Set A does not contain B's root. If set B contains A's root, then the
107  // call below will return 0, signaling duplicates. Otherwise, A and B
108  // have no common values, and the call below will correctly order the
109  // two sets, mimicking the order used by the Splay comparison function
110  // in match().
111  return matchDomainName(a, b);
112  } else {
113  // Signal duplicates because set A contains B's root (at least).
114  return 0;
115  }
116 }
117 
118 template <>
119 bool
121 {
122  // A value that starts with a dot matches a set of the corresponding domain
123  // names. Other values are individual domain names that match themselves.
124  // \sa matchDomainName()
125 
126  if (*a == '.' && *b == '.') {
127  // A and B are overlapping sets. More characters imply a smaller set.
128  return strlen(a) >= strlen(b);
129  }
130 
131  if (*a != '.' && *b != '.') {
132  // A and B are identical individual domain names
133  return true;
134  }
135 
136  // Either A or B is a set. The other one is a domain name inside that set.
137  // That domain name may use fewer or more characters (e.g., both example.com
138  // and x.example.com domains belong to the same .example.com set), so we
139  // cannot use a strlen()-based test here.
140  return *b == '.';
141 }
142 
143 template <>
146 {
147  Assure(!"domain name sets cannot partially overlap");
148  return nullptr; // unreachable code
149 }
150 
151 template <>
152 void
154 {
155  xfree(v);
156 }
157 
158 void
160 {
161  if (!domains)
162  domains = new Splay<char *>();
163 
164  while (char *t = ConfigParser::strtokFile()) {
165  Tolower(t);
167  }
168 }
169 
170 bool
172 {
173  return domains->empty();
174 }
175 
void operator()(char *const &node_data)
Definition: DomainData.cc:81
static int Compare(const Value &a, const Value &b)
const Value * find(FindValue const &, int(*compare)(FindValue const &a, Value const &b)) const
Definition: splay.h:305
void visit(ValueVisitor &) const
left-to-right visit of all stored Values
void xRefFree(T &thing)
Definition: DomainData.cc:23
SBufList dump() const override
Definition: DomainData.cc:87
int splaystrcmp(T &l, T &r)
Definition: DomainData.cc:45
static char * strtokFile()
Definition: ConfigParser.cc:65
bool empty() const
Definition: splay.h:78
static int aclHostDomainCompare(char *const &a, char *const &b)
Definition: DomainData.cc:56
void parse() override
Definition: DomainData.cc:159
std::list< SBuf > SBufList
Definition: forward.h:22
Definition: SBuf.h:93
#define xstrdup
int matchDomainName(const char *h, const char *d, MatchDomainNameFlags flags)
Definition: Uri.cc:860
bool match(char const *) override
Definition: DomainData.cc:64
static Value MakeCombinedValue(const Value &a, const Value &b)
static void Merge(Splay< Value > &, Value &&)
Definition: SplayInserter.h:68
void Tolower(char *)
Definition: util.cc:28
bool empty() const override
Definition: DomainData.cc:171
Splay< char * > * domains
Definition: DomainData.h:28
#define Assure(condition)
Definition: Assure.h:35
#define xfree
void destroy(SPLAYFREE *=DefaultFree)
Definition: splay.h:369
int splaystrcasecmp(T &l, T &r)
Definition: DomainData.cc:38
~ACLDomainData() override
Definition: DomainData.cc:28
static void DestroyValue(Value v)
A Splay::SPLAYFREE-like function that destroys parsed ACL parameter values.
Definition: SplayInserter.h:61
static bool IsSubset(const Value &a, const Value &b)
#define debugs(SECTION, LEVEL, CONTENT)
Definition: Stream.h:192

 

Introduction

Documentation

Support

Miscellaneous