]> git.ipfire.org Git - thirdparty/squid.git/blob - src/acl/Acl.h
SourceFormat Enforcement
[thirdparty/squid.git] / src / acl / Acl.h
1 /*
2 * Copyright (C) 1996-2014 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 #ifndef SQUID_ACL_H
10 #define SQUID_ACL_H
11
12 #include "acl/forward.h"
13 #include "cbdata.h"
14 #include "defines.h"
15 #include "dlink.h"
16 #include "SBufList.h"
17
18 #include <ostream>
19 #include <string>
20 #include <vector>
21
22 class ConfigParser;
23
24 typedef char ACLFlag;
25 // ACLData Flags
26 #define ACL_F_REGEX_CASE 'i'
27 #define ACL_F_NO_LOOKUP 'n'
28 #define ACL_F_STRICT 's'
29 #define ACL_F_END '\0'
30
31 /**
32 * \ingroup ACLAPI
33 * Used to hold a list of one-letter flags which can be passed as parameters
34 * to acls (eg '-i', '-n' etc)
35 */
36 class ACLFlags
37 {
38 public:
39 explicit ACLFlags(const ACLFlag flags[]) : supported_(flags), flags_(0) {}
40 ACLFlags() : flags_(0) {}
41 bool supported(const ACLFlag f) const; ///< True if the given flag supported
42 void makeSet(const ACLFlag f) { flags_ |= flagToInt(f); } ///< Set the given flag
43 /// Return true if the given flag is set
44 bool isSet(const ACLFlag f) const { return flags_ & flagToInt(f);}
45 /// Parse optional flags given in the form -[A..Z|a..z]
46 void parseFlags();
47 const char *flagsStr() const; ///< Convert the flags to a string representation
48
49 private:
50 /// Convert a flag to a 64bit unsigned integer.
51 /// The characters from 'A' to 'z' represented by the values from 65 to 122.
52 /// They are 57 different characters which can be fit to the bits of an 64bit
53 /// integer.
54 uint64_t flagToInt(const ACLFlag f) const {
55 assert('A' <= f && f <= 'z');
56 return ((uint64_t)1 << (f - 'A'));
57 }
58
59 std::string supported_; ///< The supported character flags
60 uint64_t flags_; ///< The flags which is set
61 public:
62 static const ACLFlag NoFlags[1]; ///< An empty flags list
63 };
64
65 /// A configurable condition. A node in the ACL expression tree.
66 /// Can evaluate itself in FilledChecklist context.
67 /// Does not change during evaluation.
68 /// \ingroup ACLAPI
69 class ACL
70 {
71
72 public:
73 void *operator new(size_t);
74 void operator delete(void *);
75
76 static ACL *Factory(char const *);
77 static void ParseAclLine(ConfigParser &parser, ACL ** head);
78 static void Initialize();
79 static ACL *FindByName(const char *name);
80
81 ACL();
82 explicit ACL(const ACLFlag flgs[]) : cfgline(NULL), next(NULL), flags(flgs), registered(false) {
83 *name = 0;
84 }
85 virtual ~ACL();
86
87 /// sets user-specified ACL name and squid.conf context
88 void context(const char *name, const char *configuration);
89
90 /// Orchestrates matching checklist against the ACL using match(),
91 /// after checking preconditions and while providing debugging.
92 /// Returns true if and only if there was a successful match.
93 /// Updates the checklist state on match, async, and failure.
94 bool matches(ACLChecklist *checklist) const;
95
96 virtual ACL *clone() const = 0;
97
98 /// parses node represenation in squid.conf; dies on failures
99 virtual void parse() = 0;
100 virtual char const *typeString() const = 0;
101 virtual bool isProxyAuth() const;
102 virtual SBufList dump() const = 0;
103 virtual bool empty() const = 0;
104 virtual bool valid() const;
105
106 int cacheMatchAcl(dlink_list * cache, ACLChecklist *);
107 virtual int matchForCache(ACLChecklist *checklist);
108
109 virtual void prepareForUse() {}
110
111 char name[ACL_NAME_SZ];
112 char *cfgline;
113 ACL *next; // XXX: remove or at least use refcounting
114 ACLFlags flags; ///< The list of given ACL flags
115 bool registered; ///< added to the global list of ACLs via aclRegister()
116
117 public:
118
119 class Prototype
120 {
121
122 public:
123 Prototype();
124 Prototype(ACL const *, char const *);
125 ~Prototype();
126 static bool Registered(char const *);
127 static ACL *Factory(char const *);
128
129 private:
130 ACL const *prototype;
131 char const *typeString;
132
133 private:
134 static std::vector<Prototype const *> * Registry;
135 static void *Initialized;
136 typedef std::vector<Prototype const*>::iterator iterator;
137 typedef std::vector<Prototype const*>::const_iterator const_iterator;
138 void registerMe();
139 };
140
141 private:
142 /// Matches the actual data in checklist against this ACL.
143 virtual int match(ACLChecklist *checklist) = 0; // XXX: missing const
144
145 /// whether our (i.e. shallow) match() requires checklist to have a request
146 virtual bool requiresRequest() const;
147 /// whether our (i.e. shallow) match() requires checklist to have a reply
148 virtual bool requiresReply() const;
149 };
150
151 /// \ingroup ACLAPI
152 typedef enum {
153 // Authorization ACL result states
154 ACCESS_DENIED,
155 ACCESS_ALLOWED,
156 ACCESS_DUNNO,
157
158 // Authentication ACL result states
159 ACCESS_AUTH_REQUIRED, // Missing Credentials
160 } aclMatchCode;
161
162 /// \ingroup ACLAPI
163 /// ACL check answer; TODO: Rename to Acl::Answer
164 class allow_t
165 {
166 public:
167 // not explicit: allow "aclMatchCode to allow_t" conversions (for now)
168 allow_t(const aclMatchCode aCode): code(aCode), kind(0) {}
169
170 allow_t(): code(ACCESS_DUNNO), kind(0) {}
171
172 bool operator ==(const aclMatchCode aCode) const {
173 return code == aCode;
174 }
175
176 bool operator !=(const aclMatchCode aCode) const {
177 return !(*this == aCode);
178 }
179
180 operator aclMatchCode() const {
181 return code;
182 }
183
184 aclMatchCode code; ///< ACCESS_* code
185 int kind; ///< which custom access list verb matched
186 };
187
188 inline std::ostream &
189 operator <<(std::ostream &o, const allow_t a)
190 {
191 switch (a) {
192 case ACCESS_DENIED:
193 o << "DENIED";
194 break;
195 case ACCESS_ALLOWED:
196 o << "ALLOWED";
197 break;
198 case ACCESS_DUNNO:
199 o << "DUNNO";
200 break;
201 case ACCESS_AUTH_REQUIRED:
202 o << "AUTH_REQUIRED";
203 break;
204 }
205 return o;
206 }
207
208 /// \ingroup ACLAPI
209 class acl_proxy_auth_match_cache
210 {
211 MEMPROXY_CLASS(acl_proxy_auth_match_cache);
212
213 public:
214 dlink_node link;
215 int matchrv;
216 void *acl_data;
217 };
218
219 /// \ingroup ACLAPI
220 /// XXX: find a way to remove or at least use a refcounted ACL pointer
221 extern const char *AclMatchedName; /* NULL */
222
223 #endif /* SQUID_ACL_H */
224