]>
Commit | Line | Data |
---|---|---|
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 | ||
112 | namespace 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). | |
119 | template <class Parent> | |
120 | class FinalizedParameterizedNode: public Parent | |
121 | { | |
922513e5 | 122 | MEMPROXY_CLASS(FinalizedParameterizedNode<Parent>); |
8319d478 AR |
123 | |
124 | public: | |
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 | ||
159 | private: | |
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/. |
191 | void | |
192 | Acl::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 |