]> git.ipfire.org Git - thirdparty/squid.git/blame - src/AclRegs.cc
NoNewGlobals for MapLabel (#1746)
[thirdparty/squid.git] / src / AclRegs.cc
CommitLineData
bbc27441 1/*
b8ae064d 2 * Copyright (C) 1996-2023 The Squid Software Foundation and contributors
bbc27441
AJ
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
582c2af2 9#include "squid.h"
2d46f579 10
c302ddb5
CT
11#if USE_ADAPTATION
12#include "acl/AdaptationService.h"
13#include "acl/AdaptationServiceData.h"
14#endif
6f58d7d7 15#include "acl/AllOf.h"
75d47340
CT
16#include "acl/AnnotateClient.h"
17#include "acl/AnnotateTransaction.h"
18#include "acl/AnnotationData.h"
6f58d7d7 19#include "acl/AnyOf.h"
32d002cb 20#if USE_SQUID_EUI
2d46f579 21#include "acl/Arp.h"
a98c2da5 22#include "acl/Eui64.h"
2d46f579 23#endif
5d65362c 24#if USE_OPENSSL
8693472e
CT
25#include "acl/AtStep.h"
26#include "acl/AtStepData.h"
5d65362c 27#endif
2d46f579 28#include "acl/Asn.h"
2d46f579 29#include "acl/Checklist.h"
88df846b 30#include "acl/ConnectionsEncrypted.h"
2d46f579
AR
31#include "acl/Data.h"
32#include "acl/DestinationAsn.h"
33#include "acl/DestinationDomain.h"
34#include "acl/DestinationIp.h"
35#include "acl/DomainData.h"
653d9927
A
36#if USE_LIBNETFILTERCONNTRACK
37#include "acl/ConnMark.h"
38#endif
2f1431ea 39#if USE_AUTH
2d46f579 40#include "acl/ExtUser.h"
2f1431ea 41#endif
2d46f579 42#include "acl/FilledChecklist.h"
4eac3407 43#include "acl/forward.h"
2d46f579 44#include "acl/Gadgets.h"
5ec4cffe
EB
45#include "acl/HasComponent.h"
46#include "acl/HasComponentData.h"
bbaf2685 47#include "acl/HierCode.h"
602d9612 48#include "acl/HierCodeData.h"
2d46f579
AR
49#include "acl/HttpHeaderData.h"
50#include "acl/HttpRepHeader.h"
51#include "acl/HttpReqHeader.h"
52#include "acl/HttpStatus.h"
2d46f579
AR
53#include "acl/IntRange.h"
54#include "acl/Ip.h"
1e40905d
AJ
55#include "acl/LocalIp.h"
56#include "acl/LocalPort.h"
2d46f579 57#include "acl/MaxConnection.h"
2d46f579 58#include "acl/Method.h"
602d9612 59#include "acl/MethodData.h"
2d46f579 60#include "acl/MyPortName.h"
922513e5 61#include "acl/Node.h"
ff9d9458 62#include "acl/Note.h"
39baccc8 63#include "acl/NoteData.h"
2d46f579 64#include "acl/PeerName.h"
2d46f579 65#include "acl/Protocol.h"
602d9612 66#include "acl/ProtocolData.h"
cb1b906f 67#include "acl/Random.h"
2d46f579
AR
68#include "acl/RegexData.h"
69#include "acl/ReplyHeaderStrategy.h"
70#include "acl/ReplyMimeType.h"
71#include "acl/RequestHeaderStrategy.h"
72#include "acl/RequestMimeType.h"
73#include "acl/SourceAsn.h"
74#include "acl/SourceDomain.h"
75#include "acl/SourceIp.h"
3248e962
CT
76#include "acl/SquidError.h"
77#include "acl/SquidErrorData.h"
cb4f4424 78#if USE_OPENSSL
2d46f579 79#include "acl/Certificate.h"
602d9612 80#include "acl/CertificateData.h"
69f69080 81#include "acl/ServerName.h"
602d9612
A
82#include "acl/SslError.h"
83#include "acl/SslErrorData.h"
2d46f579 84#endif
2d46f579 85#include "acl/StringData.h"
cb4f4424 86#if USE_OPENSSL
00352183
AR
87#include "acl/ServerCertificate.h"
88#endif
bb5e7a79 89#include "acl/Tag.h"
2d46f579 90#include "acl/Time.h"
602d9612 91#include "acl/TimeData.h"
5ceaee75 92#include "acl/TransactionInitiator.h"
2d46f579 93#include "acl/Url.h"
9d35fe37 94#include "acl/UrlLogin.h"
2d46f579
AR
95#include "acl/UrlPath.h"
96#include "acl/UrlPort.h"
97#include "acl/UserData.h"
2f1431ea 98#if USE_AUTH
abca32cf 99#include "auth/AclMaxUserIp.h"
602d9612 100#include "auth/AclProxyAuth.h"
2f1431ea 101#endif
e2b74520 102#include "base/RegexPattern.h"
4eac3407 103#include "ExternalACL.h"
4daaf3cb
AJ
104#if USE_IDENT
105#include "ident/AclIdent.h"
106#endif
4eac3407
CT
107#if SQUID_SNMP
108#include "snmp_core.h"
2f1431ea 109#endif
8319d478
AR
110#include "sbuf/Stream.h"
111
112namespace Acl
113{
114
115/// Constructs a ParameterizedNode-derived ACL (specified as a Parent class).
116/// This template exists to avoid placing a variant of this ACL construction
117/// code in each ParameterizedNode-derived ACL class just to pass through
118/// TypeName and Parameters onto ParameterizedNode (and to add MEMPROXY_CLASS).
119template <class Parent>
120class FinalizedParameterizedNode: public Parent
121{
922513e5 122 MEMPROXY_CLASS(FinalizedParameterizedNode<Parent>);
8319d478
AR
123
124public:
125 using Parameters = typename Parent::Parameters;
126 using Parent::data;
127
128 /// Replaces generic memory allocator label X set by our MEMPROXY_CLASS(X)
129 /// with an admin-friendly label based on the given acltype-like name.
130 /// Normally, our class constructor sets the right allocator label using the
131 /// actlype name, but that algorithm results in unstable and misleading
132 /// labels when the same instantiation of this template class is used for
133 /// _multiple_ acltype names. Calling this method corrects that behavior.
134 /// \prec this method must be called at most once
135 /// \prec if called, this method must be called before the class constructor
136 static void PreferAllocatorLabelPrefix(const char * const suffix)
137 {
138 assert(!PreferredAllocatorLabelSuffix); // must be called at most once
139 assert(!FinalPoolLabel); // must be called before the class constructor
140 assert(suffix);
141 PreferredAllocatorLabelSuffix = suffix;
142 }
143
144 FinalizedParameterizedNode(TypeName typeName, Parameters * const params):
145 typeName_(typeName)
146 {
147 Assure(!data); // base classes never set this data member
148 data.reset(params);
149 Assure(data); // ... but we always do
150
151 FinalizePoolLabel(typeName);
152 }
153
154 ~FinalizedParameterizedNode() override = default;
155
156 /* ACL API */
157 const char *typeString() const override { return typeName_; }
158
159private:
160 /// A constructor helper function that replaces generic memory allocator
161 /// label X set by our MEMPROXY_CLASS(X) with an admin-friendly label based
162 /// on the acltype name from squid.conf. Meant to be called from the
163 /// constructor so that no mgr:mem report lists this C++ template class
164 /// statistics using label X. Repeated calls are allowed but have no effect.
165 /// \sa PreferAllocatorLabelPrefix()
166 static void FinalizePoolLabel(const TypeName typeName)
167 {
168 if (FinalPoolLabel)
169 return; // the label has been finalized already
170
171 assert(typeName);
172 const auto label = ToSBuf("acltype=", PreferredAllocatorLabelSuffix ? PreferredAllocatorLabelSuffix : typeName);
173 FinalPoolLabel = SBufToCstring(label);
174 Pool().relabel(FinalPoolLabel);
175 }
176
177 /// if set, overrules FinalizePoolLabel() argument
178 inline static const char *PreferredAllocatorLabelSuffix = nullptr;
179
180 /// custom allocator label set by FinalizePoolLabel()
181 inline static const char *FinalPoolLabel = nullptr;
182
183 // TODO: Consider storing the spelling used by the admin instead.
184 /// the "acltype" name in its canonical spelling
185 TypeName typeName_;
186};
187
188} // namespace Acl
5d65362c 189
4eac3407
CT
190// Not in src/acl/ because some of the ACLs it registers are not in src/acl/.
191void
192Acl::Init()
193{
194 /* the registration order does not matter */
195
922513e5
FC
196 // The explicit return type (Acl::Node*) for lambdas is needed because the type
197 // of the return expression inside lambda is not Node* but AclFoo* while
198 // Maker is defined to return Node*.
199
200 RegisterMaker("all-of", [](TypeName)->Node* { return new AllOf; }); // XXX: Add name parameter to ctor
201 RegisterMaker("any-of", [](TypeName)->Node* { return new AnyOf; }); // XXX: Add name parameter to ctor
202 RegisterMaker("random", [](TypeName name)->Node* { return new ACLRandom(name); });
203 RegisterMaker("time", [](TypeName name)->Node* { return new FinalizedParameterizedNode<CurrentTimeCheck>(name, new ACLTimeData); });
204 RegisterMaker("src_as", [](TypeName name)->Node* { return new FinalizedParameterizedNode<SourceAsnCheck>(name, new ACLASN); });
205 RegisterMaker("dst_as", [](TypeName name)->Node* { return new FinalizedParameterizedNode<DestinationAsnCheck>(name, new ACLASN); });
206 RegisterMaker("browser", [](TypeName name)->Node* { return new FinalizedParameterizedNode<RequestHeaderCheck<Http::HdrType::USER_AGENT> >(name, new ACLRegexData); });
207
208 RegisterMaker("dstdomain", [](TypeName name)->Node* { return new FinalizedParameterizedNode<DestinationDomainCheck>(name, new ACLDomainData); });
209 RegisterMaker("dstdom_regex", [](TypeName name)->Node* { return new FinalizedParameterizedNode<DestinationDomainCheck>(name, new ACLRegexData); });
210 FinalizedParameterizedNode<DestinationDomainCheck>::PreferAllocatorLabelPrefix("dstdomain+");
211
212 RegisterMaker("dst", [](TypeName)->Node* { return new ACLDestinationIP; }); // XXX: Add name parameter to ctor
213 RegisterMaker("hier_code", [](TypeName name)->Node* { return new FinalizedParameterizedNode<HierCodeCheck>(name, new ACLHierCodeData); });
214 RegisterMaker("rep_header", [](TypeName name)->Node* { return new FinalizedParameterizedNode<HttpRepHeaderCheck>(name, new ACLHTTPHeaderData); });
215 RegisterMaker("req_header", [](TypeName name)->Node* { return new FinalizedParameterizedNode<HttpReqHeaderCheck>(name, new ACLHTTPHeaderData); });
216 RegisterMaker("http_status", [](TypeName name)->Node* { return new ACLHTTPStatus(name); });
217 RegisterMaker("maxconn", [](TypeName name)->Node* { return new ACLMaxConnection(name); });
218 RegisterMaker("method", [](TypeName name)->Node* { return new FinalizedParameterizedNode<MethodCheck>(name, new ACLMethodData); });
219 RegisterMaker("localip", [](TypeName)->Node* { return new ACLLocalIP; }); // XXX: Add name parameter to ctor
220 RegisterMaker("localport", [](TypeName name)->Node* { return new FinalizedParameterizedNode<LocalPortCheck>(name, new ACLIntRange); });
221 RegisterMaker("myportname", [](TypeName name)->Node* { return new FinalizedParameterizedNode<MyPortNameCheck>(name, new ACLStringData); });
222
223 RegisterMaker("peername", [](TypeName name)->Node* { return new FinalizedParameterizedNode<PeerNameCheck>(name, new ACLStringData); });
224 RegisterMaker("peername_regex", [](TypeName name)->Node* { return new FinalizedParameterizedNode<PeerNameCheck>(name, new ACLRegexData); });
225 FinalizedParameterizedNode<PeerNameCheck>::PreferAllocatorLabelPrefix("peername+");
226
227 RegisterMaker("proto", [](TypeName name)->Node* { return new FinalizedParameterizedNode<ProtocolCheck>(name, new ACLProtocolData); });
228 RegisterMaker("referer_regex", [](TypeName name)->Node* { return new FinalizedParameterizedNode<RequestHeaderCheck<Http::HdrType::REFERER> >(name, new ACLRegexData); });
229 RegisterMaker("rep_mime_type", [](TypeName name)->Node* { return new FinalizedParameterizedNode<ReplyHeaderCheck<Http::HdrType::CONTENT_TYPE> >(name, new ACLRegexData); });
230 RegisterMaker("req_mime_type", [](TypeName name)->Node* { return new FinalizedParameterizedNode<RequestHeaderCheck<Http::HdrType::CONTENT_TYPE> >(name, new ACLRegexData); });
231
232 RegisterMaker("srcdomain", [](TypeName name)->Node* { return new FinalizedParameterizedNode<SourceDomainCheck>(name, new ACLDomainData); });
233 RegisterMaker("srcdom_regex", [](TypeName name)->Node* { return new FinalizedParameterizedNode<SourceDomainCheck>(name, new ACLRegexData); });
234 FinalizedParameterizedNode<SourceDomainCheck>::PreferAllocatorLabelPrefix("srcdomain+");
235
236 RegisterMaker("src", [](TypeName)->Node* { return new ACLSourceIP; }); // XXX: Add name parameter to ctor
237 RegisterMaker("url_regex", [](TypeName name)->Node* { return new FinalizedParameterizedNode<UrlCheck>(name, new ACLRegexData); });
238 RegisterMaker("urllogin", [](TypeName name)->Node* { return new FinalizedParameterizedNode<UrlLoginCheck>(name, new ACLRegexData); });
239 RegisterMaker("urlpath_regex", [](TypeName name)->Node* { return new FinalizedParameterizedNode<UrlPathCheck>(name, new ACLRegexData); });
240 RegisterMaker("port", [](TypeName name)->Node* { return new FinalizedParameterizedNode<UrlPortCheck>(name, new ACLIntRange); });
241 RegisterMaker("external", [](TypeName name)->Node* { return new ACLExternal(name); });
242 RegisterMaker("squid_error", [](TypeName name)->Node* { return new FinalizedParameterizedNode<SquidErrorCheck>(name, new ACLSquidErrorData); });
243 RegisterMaker("connections_encrypted", [](TypeName name)->Node* { return new ConnectionsEncrypted(name); });
244 RegisterMaker("tag", [](TypeName name)->Node* { return new FinalizedParameterizedNode<TagCheck>(name, new ACLStringData); });
245 RegisterMaker("note", [](TypeName name)->Node* { return new FinalizedParameterizedNode<NoteCheck>(name, new ACLNoteData); });
246 RegisterMaker("annotate_client", [](TypeName name)->Node* { return new FinalizedParameterizedNode<AnnotateClientCheck>(name, new ACLAnnotationData); });
247 RegisterMaker("annotate_transaction", [](TypeName name)->Node* { return new FinalizedParameterizedNode<AnnotateTransactionCheck>(name, new ACLAnnotationData); });
248 RegisterMaker("has", [](TypeName name)->Node* { return new FinalizedParameterizedNode<HasComponentCheck>(name, new ACLHasComponentData); });
249 RegisterMaker("transaction_initiator", [](TypeName name)->Node* {return new TransactionInitiator(name);});
69f69080 250
653d9927 251#if USE_LIBNETFILTERCONNTRACK
922513e5
FC
252 RegisterMaker("clientside_mark", [](TypeName)->Node* { return new ConnMark; }); // XXX: Add name parameter to ctor
253 RegisterMaker("client_connection_mark", [](TypeName)->Node* { return new ConnMark; }); // XXX: Add name parameter to ctor
653d9927
A
254#endif
255
4eac3407 256#if USE_OPENSSL
922513e5 257 RegisterMaker("ssl_error", [](TypeName name)->Node* { return new FinalizedParameterizedNode<CertificateErrorCheck>(name, new ACLSslErrorData); });
8319d478 258
922513e5
FC
259 RegisterMaker("user_cert", [](TypeName name)->Node* { return new FinalizedParameterizedNode<ClientCertificateCheck>(name, new ACLCertificateData(Ssl::GetX509UserAttribute, "*")); });
260 RegisterMaker("ca_cert", [](TypeName name)->Node* { return new FinalizedParameterizedNode<ClientCertificateCheck>(name, new ACLCertificateData(Ssl::GetX509CAAttribute, "*")); });
261 FinalizedParameterizedNode<ClientCertificateCheck>::PreferAllocatorLabelPrefix("user_cert+");
8319d478 262
922513e5
FC
263 RegisterMaker("server_cert_fingerprint", [](TypeName name)->Node* { return new FinalizedParameterizedNode<ServerCertificateCheck>(name, new ACLCertificateData(Ssl::GetX509Fingerprint, nullptr, true)); });
264 RegisterMaker("at_step", [](TypeName name)->Node* { return new FinalizedParameterizedNode<AtStepCheck>(name, new ACLAtStepData); });
8319d478 265
922513e5
FC
266 RegisterMaker("ssl::server_name", [](TypeName name)->Node* { return new FinalizedParameterizedNode<ServerNameCheck>(name, new ACLServerNameData); });
267 RegisterMaker("ssl::server_name_regex", [](TypeName name)->Node* { return new FinalizedParameterizedNode<ServerNameCheck>(name, new ACLRegexData); });
268 FinalizedParameterizedNode<ServerNameCheck>::PreferAllocatorLabelPrefix("ssl::server_name+");
2d46f579
AR
269#endif
270
32d002cb 271#if USE_SQUID_EUI
922513e5
FC
272 RegisterMaker("arp", [](TypeName name)->Node* { return new ACLARP(name); });
273 RegisterMaker("eui64", [](TypeName name)->Node* { return new ACLEui64(name); });
2d46f579
AR
274#endif
275
ee326f02 276#if USE_IDENT
922513e5
FC
277 RegisterMaker("ident", [](TypeName name)->Node* { return new ACLIdent(new ACLUserData, name); });
278 RegisterMaker("ident_regex", [](TypeName name)->Node* { return new ACLIdent(new ACLRegexData, name); });
2d46f579
AR
279#endif
280
2f1431ea 281#if USE_AUTH
922513e5
FC
282 RegisterMaker("ext_user", [](TypeName name)->Node* { return new ACLExtUser(new ACLUserData, name); });
283 RegisterMaker("ext_user_regex", [](TypeName name)->Node* { return new ACLExtUser(new ACLRegexData, name); });
284 RegisterMaker("proxy_auth", [](TypeName name)->Node* { return new ACLProxyAuth(new ACLUserData, name); });
285 RegisterMaker("proxy_auth_regex", [](TypeName name)->Node* { return new ACLProxyAuth(new ACLRegexData, name); });
286 RegisterMaker("max_user_ip", [](TypeName name)->Node* { return new ACLMaxUserIP(name); });
2f1431ea 287#endif
bb5e7a79 288
c302ddb5 289#if USE_ADAPTATION
922513e5 290 RegisterMaker("adaptation_service", [](TypeName name)->Node* { return new FinalizedParameterizedNode<AdaptationServiceCheck>(name, new ACLAdaptationServiceData); });
c302ddb5 291#endif
f53969cc 292
4eac3407 293#if SQUID_SNMP
922513e5 294 RegisterMaker("snmp_community", [](TypeName name)->Node* { return new FinalizedParameterizedNode<SnmpCommunityCheck>(name, new ACLStringData); });
4eac3407
CT
295#endif
296}
5ec4cffe 297