]>
git.ipfire.org Git - thirdparty/squid.git/blob - src/acl/Checklist.h
d6ba989fe4d5f88fb30fde447a274c7b3e61500a
2 * Copyright (C) 1996-2025 The Squid Software Foundation and contributors
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.
9 #ifndef SQUID_SRC_ACL_CHECKLIST_H
10 #define SQUID_SRC_ACL_CHECKLIST_H
13 #include "acl/InnerNode.h"
22 /// ACL checklist callback
23 typedef void ACLCB(Acl::Answer
, void *);
26 Base class for maintaining Squid and transaction state for access checks.
27 Provides basic ACL checking methods. Its only child, ACLFilledChecklist,
28 keeps the actual state data. The split is necessary to avoid exposing
29 all ACL-related code to virtually Squid data types. */
35 /// a function that initiates asynchronous ACL checks; see goAsync()
36 using AsyncStarter
= void (ACLFilledChecklist
&, const Acl::Node
&);
40 virtual ~ACLChecklist();
43 * Perform a blocking (immediate) check for a list of allow/deny rules.
44 * Each rule comes with a list of ACLs.
46 * The first rule where all ACLs match wins. If there is such a rule,
47 * the result becomes that rule keyword (ACCESS_ALLOWED or ACCESS_DENIED).
49 * If there are rules but all ACL lists mismatch, an implicit rule is used
50 * Its result is the negation of the keyword of the last seen rule.
52 * Some ACLs may stop the check prematurely by setting an exceptional
53 * check result (e.g., ACCESS_AUTH_REQUIRED) instead of declaring a
56 * Some ACLs may require an async lookup which is prohibited by this
57 * method. In this case, the exceptional check result of ACCESS_DUNNO is
58 * immediately returned.
60 * If there are no rules to check at all, the result becomes ACCESS_DUNNO.
62 Acl::Answer
const & fastCheck();
65 * Perform a blocking (immediate) check whether a list of ACLs matches.
66 * This method is meant to be used with squid.conf ACL-driven options that
67 * lack allow/deny keywords and are tested one ACL list at a time. Whether
68 * the checks for other occurrences of the same option continue after this
69 * call is up to the caller and option semantics.
71 * If all ACLs match, the result becomes ACCESS_ALLOWED.
73 * If all ACLs mismatch, the result becomes ACCESS_DENIED.
75 * Some ACLs may stop the check prematurely by setting an exceptional
76 * check result (e.g., ACCESS_AUTH_REQUIRED) instead of declaring a
79 * Some ACLs may require an async lookup which is prohibited by this
80 * method. In this case, the exceptional check result of ACCESS_DUNNO is
81 * immediately returned.
83 * If there are no ACLs to check at all, the result becomes ACCESS_ALLOWED.
85 const Acl::Answer
&fastCheck(const ACLList
*);
87 /// If slow lookups are allowed, switches into "async in progress" state.
88 /// Otherwise, returns false; the caller is expected to handle the failure.
89 bool goAsync(AsyncStarter
, const Acl::Node
&);
91 /// Matches (or resumes matching of) a child node at pos while maintaining
92 /// resumption breadcrumbs if a [grand]child node goes async.
93 bool matchChild(const Acl::InnerNode
*parent
, Acl::Nodes::const_iterator pos
);
95 /// Whether we should continue to match tree nodes or stop/pause.
96 bool keepMatching() const { return !finished() && !asyncInProgress(); }
98 /// whether markFinished() was called
99 bool finished() const { return finished_
; }
100 /// async call has been started and has not finished (or failed) yet
101 bool asyncInProgress() const { return asyncStage_
!= asyncNone
; }
102 /// called when no more ACLs should be checked; sets the final answer and
103 /// prints a debugging message explaining the reason for that answer
104 void markFinished(const Acl::Answer
&newAnswer
, const char *reason
);
106 const Acl::Answer
¤tAnswer() const { return answer_
; }
108 /// whether the action is banned or not
109 bool bannedAction(const Acl::Answer
&action
) const;
110 /// add action to the list of banned actions
111 void banAction(const Acl::Answer
&action
);
113 // XXX: ACLs that need request or reply have to use ACLFilledChecklist and
114 // should do their own checks so that we do not have to povide these two
115 // for ACL::checklistMatches to use
116 virtual bool hasRequest() const = 0;
117 virtual bool hasReply() const = 0;
118 virtual bool hasAle() const = 0;
119 /// assigns uninitialized adapted_request and url ALE components
120 virtual void syncAle(HttpRequest
*adaptedRequest
, const char *logUri
) const = 0;
121 /// warns if there are uninitialized ALE components and fills them
122 virtual void verifyAle() const = 0;
124 /// change the current ACL list
125 void changeAcl(const acl_access
*);
127 /// remember the name of the last ACL being evaluated
128 void setLastCheckedName(const SBuf
&name
) { lastCheckedName_
= name
; }
132 * Start a non-blocking (async) check for a list of allow/deny rules.
133 * Each rule comes with a list of ACLs.
135 * The callback specified will be called with the result of the check.
137 * The first rule where all ACLs match wins. If there is such a rule,
138 * the result becomes that rule keyword (ACCESS_ALLOWED or ACCESS_DENIED).
140 * If there are rules but all ACL lists mismatch, an implicit rule is used.
141 * Its result is the negation of the keyword of the last seen rule.
143 * Some ACLs may stop the check prematurely by setting an exceptional
144 * check result (e.g., ACCESS_AUTH_REQUIRED) instead of declaring a
147 * If there are no rules to check at all, the result becomes ACCESS_DUNNO.
148 * Calling this method with no rules to check wastes a lot of CPU cycles
149 * and will result in a DBG_CRITICAL debugging message.
151 void nonBlockingCheck(ACLCB
* callback
, void *callback_data
);
154 /// Calls non-blocking check callback with the answer and destroys self.
155 /// If abortReason is provided, sets the final answer to ACCESS_DUNNO.
156 void checkCallback(const char *abortReason
);
158 void matchAndFinish();
160 /// \copydoc changeAcl()
161 /// \returns old accessList pointer (that may be nil)
162 Acl::TreePointer
swapAcl(const acl_access
*);
164 Acl::TreePointer accessList
;
171 /// Resumes non-blocking check started by nonBlockingCheck() and
172 /// suspended until some async operation updated Squid state.
173 void resumeNonBlockingCheck();
175 private: /* internal methods */
176 /// Position of a child node within an Acl::Node tree.
180 Breadcrumb(): parent(nullptr) {}
181 Breadcrumb(const Acl::InnerNode
*aParent
, Acl::Nodes::const_iterator aPos
): parent(aParent
), position(aPos
) {}
182 bool operator ==(const Breadcrumb
&b
) const { return parent
== b
.parent
&& (!parent
|| position
== b
.position
); }
183 bool operator !=(const Breadcrumb
&b
) const { return !this->operator ==(b
); }
184 void clear() { parent
= nullptr; }
185 RefCount
<const Acl::InnerNode
> parent
; ///< intermediate node in the ACL tree
186 Acl::Nodes::const_iterator position
; ///< child position inside parent
189 /// possible outcomes when trying to match a single ACL node in a list
190 typedef enum { nmrMatch
, nmrMismatch
, nmrFinished
, nmrNeedsAsync
}
193 /// prepare for checking ACLs; called once per check
194 void preCheck(const char *what
);
195 bool prepNonBlocking();
196 void completeNonBlocking();
197 void calcImplicitAnswer();
199 bool asyncCaller_
; ///< whether the caller supports async/slow ACLs
200 bool occupied_
; ///< whether a check (fast or non-blocking) is in progress
204 enum AsyncStage
{ asyncNone
, asyncStarting
, asyncRunning
, asyncFailed
};
205 AsyncStage asyncStage_
;
206 Breadcrumb matchLoc_
; ///< location of the node running matches() now
207 Breadcrumb asyncLoc_
; ///< currentNode_ that called goAsync()
208 unsigned asyncLoopDepth_
; ///< how many times the current async state has resumed
212 /// suspended (due to an async lookup) matches() in the ACL tree
213 std::stack
<Breadcrumb
> matchPath
;
214 /// the list of actions which must ignored during acl checks
215 std::vector
<Acl::Answer
> bannedActions_
;
217 /// the name of the last evaluated ACL (if any ACLs were evaluated)
218 std::optional
<SBuf
> lastCheckedName_
;
221 #endif /* SQUID_SRC_ACL_CHECKLIST_H */