]> git.ipfire.org Git - thirdparty/squid.git/blob - src/acl/Checklist.h
Merged from trunk
[thirdparty/squid.git] / src / acl / Checklist.h
1 /*
2 *
3 * SQUID Web Proxy Cache http://www.squid-cache.org/
4 * ----------------------------------------------------------
5 *
6 * Squid is the result of efforts by numerous individuals from
7 * the Internet community; see the CONTRIBUTORS file for full
8 * details. Many organizations have provided support for Squid's
9 * development; see the SPONSORS file for full details. Squid is
10 * Copyrighted (C) 2001 by the Regents of the University of
11 * California; see the COPYRIGHT file for full details. Squid
12 * incorporates software developed and/or copyrighted by other
13 * sources; see the CREDITS file for full details.
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
28 *
29 */
30
31 #ifndef SQUID_ACLCHECKLIST_H
32 #define SQUID_ACLCHECKLIST_H
33
34 #include "acl/Acl.h"
35
36 /// ACL checklist callback
37 typedef void ACLCB(allow_t, void *);
38
39 /** \ingroup ACLAPI
40 Base class for maintaining Squid and transaction state for access checks.
41 Provides basic ACL checking methods. Its only child, ACLFilledChecklist,
42 keeps the actual state data. The split is necessary to avoid exposing
43 all ACL-related code to virtually Squid data types. */
44 class ACLChecklist
45 {
46
47 public:
48
49 /**
50 * State class.
51 * This abstract class defines the behaviour of
52 * async lookups - which can vary for different ACL types.
53 * Today, every state object must be a singleton.
54 * See NULLState for an example.
55 *
56 \note *no* state should be stored in the state object,
57 * they are used to change the behaviour of the checklist, not
58 * to hold information. If you need to store information in the
59 * state object, consider subclassing ACLChecklist, converting it
60 * to a composite, or changing the state objects from singletons to
61 * refcounted objects.
62 */
63
64 class AsyncState
65 {
66
67 public:
68 virtual void checkForAsync(ACLChecklist *) const = 0;
69 virtual ~AsyncState() {}
70
71 protected:
72 void changeState (ACLChecklist *, AsyncState *) const;
73 };
74
75 class NullState : public AsyncState
76 {
77
78 public:
79 static NullState *Instance();
80 virtual void checkForAsync(ACLChecklist *) const;
81 virtual ~NullState() {}
82
83 private:
84 static NullState _instance;
85 };
86
87 public:
88 ACLChecklist();
89 virtual ~ACLChecklist();
90
91 /**
92 * Start a non-blocking (async) check for a list of allow/deny rules.
93 * Each rule comes with a list of ACLs.
94 *
95 * The callback specified will be called with the result of the check.
96 *
97 * The first rule where all ACLs match wins. If there is such a rule,
98 * the result becomes that rule keyword (ACCESS_ALLOWED or ACCESS_DENIED).
99 *
100 * If there are rules but all ACL lists mismatch, an implicit rule is used.
101 * Its result is the negation of the keyword of the last seen rule.
102 *
103 * Some ACLs may stop the check prematurely by setting an exceptional
104 * check result (e.g., ACCESS_AUTH_REQUIRED) instead of declaring a
105 * match or mismatch.
106 *
107 * If there are no rules to check at all, the result becomes ACCESS_DUNNO.
108 * Calling this method with no rules to check wastes a lot of CPU cycles
109 * and will result in a DBG_CRITICAL debugging message.
110 */
111 void nonBlockingCheck(ACLCB * callback, void *callback_data);
112
113 /**
114 * Perform a blocking (immediate) check for a list of allow/deny rules.
115 * Each rule comes with a list of ACLs.
116 *
117 * The first rule where all ACLs match wins. If there is such a rule,
118 * the result becomes that rule keyword (ACCESS_ALLOWED or ACCESS_DENIED).
119 *
120 * If there are rules but all ACL lists mismatch, an implicit rule is used
121 * Its result is the negation of the keyword of the last seen rule.
122 *
123 * Some ACLs may stop the check prematurely by setting an exceptional
124 * check result (e.g., ACCESS_AUTH_REQUIRED) instead of declaring a
125 * match or mismatch.
126 *
127 * Some ACLs may require an async lookup which is prohibited by this
128 * method. In this case, the exceptional check result of ACCESS_DUNNO is
129 * immediately returned.
130 *
131 * If there are no rules to check at all, the result becomes ACCESS_DUNNO.
132 */
133 allow_t const & fastCheck();
134
135 /**
136 * Perform a blocking (immediate) check whether a list of ACLs matches.
137 * This method is meant to be used with squid.conf ACL-driven options that
138 * lack allow/deny keywords and are tested one ACL list at a time. Whether
139 * the checks for other occurrences of the same option continue after this
140 * call is up to the caller and option semantics.
141 *
142 * If all ACLs match, the result becomes ACCESS_ALLOWED.
143 *
144 * If all ACLs mismatch, the result becomes ACCESS_DENIED.
145 *
146 * Some ACLs may stop the check prematurely by setting an exceptional
147 * check result (e.g., ACCESS_AUTH_REQUIRED) instead of declaring a
148 * match or mismatch.
149 *
150 * Some ACLs may require an async lookup which is prohibited by this
151 * method. In this case, the exceptional check result of ACCESS_DUNNO is
152 * immediately returned.
153 *
154 * If there are no ACLs to check at all, the result becomes ACCESS_ALLOWED.
155 */
156 allow_t const & fastCheck(const ACLList * list);
157
158 // whether the last checked ACL of the current rule needs
159 // an async operation to determine whether there was a match
160 bool asyncNeeded() const;
161 bool asyncInProgress() const;
162 void asyncInProgress(bool const);
163
164 /// whether markFinished() was called
165 bool finished() const;
166 /// called when no more ACLs should be checked; sets the final answer and
167 /// prints a debugging message explaining the reason for that answer
168 void markFinished(const allow_t &newAnswer, const char *reason);
169
170 const allow_t &currentAnswer() const { return allow_; }
171
172 void changeState(AsyncState *);
173 AsyncState *asyncState() const;
174
175 // XXX: ACLs that need request or reply have to use ACLFilledChecklist and
176 // should do their own checks so that we do not have to povide these two
177 // for ACL::checklistMatches to use
178 virtual bool hasRequest() const = 0;
179 virtual bool hasReply() const = 0;
180
181 private:
182 /// Calls non-blocking check callback with the answer and destroys self.
183 void checkCallback(allow_t answer);
184
185 void checkAccessList();
186 void checkForAsync();
187
188 public:
189 const acl_access *accessList;
190
191 ACLCB *callback;
192 void *callback_data;
193
194 /**
195 * Performs non-blocking check starting with the current rule.
196 * Used by nonBlockingCheck() to initiate the checks and by
197 * async operation callbacks to resume checks after the async
198 * operation updates the current Squid state. See nonBlockingCheck()
199 * for details on final result determination.
200 */
201 void matchNonBlocking();
202
203 private: /* internal methods */
204 /// possible outcomes when trying to match a single ACL node in a list
205 typedef enum { nmrMatch, nmrMismatch, nmrFinished, nmrNeedsAsync }
206 NodeMatchingResult;
207
208 /// prepare for checking ACLs; called once per check
209 void preCheck(const char *what);
210 bool matchAclList(const ACLList * list, bool const fast);
211 bool matchNodes(const ACLList * head, bool const fast);
212 NodeMatchingResult matchNode(const ACLList &node, bool const fast);
213 void calcImplicitAnswer(const allow_t &lastSeenAction);
214
215 bool async_;
216 bool finished_;
217 allow_t allow_;
218 AsyncState *state_;
219
220 bool checking_;
221 bool checking() const;
222 void checking (bool const);
223
224 bool callerGone();
225 };
226
227 #endif /* SQUID_ACLCHECKLIST_H */