From: Christos Tsantilas Date: Mon, 12 Jun 2017 14:48:28 +0000 (+0300) Subject: Support for --long-acl-options X-Git-Tag: M-staged-PR71~128 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=4eac3407573794dec7f40816dc1f1f3139c2e63e;p=thirdparty%2Fsquid.git Support for --long-acl-options The old single-letter ACL "flags" code was refactored to support long option names (with option-specific value types) without significant per-ACL-object performance/RAM overheads and without creating a global registry for all possible options. This refactoring (unexpectedly) resulted in removal of a lot of unreliable static initialization code. Refactoring fixed ACL flags parsing code that was dangerously misinterpreting -i and +i flags in several contexts. For example, each of the three cases below was misinterpreted as if three domains were configured (e.g., "+i", "-z", and "example.com") on each line instead of one domain ("example.com"): acl parsedAsThreeDomains dstdomain +i -i .example.com acl parsedAsThreeDomains dstdomain -i +i .example.com acl parsedAsThreeDomains dstdomain +i -z .example.com TODO: Finish ACL::clone() removal. Then consider removing any unused ACLData::clone() and associated ACL/ACLData copying methods. This is a Measurement Factory project. --- diff --git a/src/AclRegs.cc b/src/AclRegs.cc index bbf2995c2b..48dd65c451 100644 --- a/src/AclRegs.cc +++ b/src/AclRegs.cc @@ -8,11 +8,6 @@ #include "squid.h" -/** This file exists to provide satic registration code to executables - that need ACLs. We cannot place this code in acl/lib*.la because it - does not get linked in, because nobody is using these classes by name. -*/ - #if USE_ADAPTATION #include "acl/AdaptationService.h" #include "acl/AdaptationServiceData.h" @@ -31,7 +26,6 @@ #include "acl/AtStepData.h" #endif #include "acl/Asn.h" -#include "acl/Browser.h" #include "acl/Checklist.h" #include "acl/ConnectionsEncrypted.h" #include "acl/Data.h" @@ -43,6 +37,7 @@ #include "acl/ExtUser.h" #endif #include "acl/FilledChecklist.h" +#include "acl/forward.h" #include "acl/Gadgets.h" #include "acl/HasComponent.h" #include "acl/HasComponentData.h" @@ -66,7 +61,6 @@ #include "acl/Protocol.h" #include "acl/ProtocolData.h" #include "acl/Random.h" -#include "acl/Referer.h" #include "acl/RegexData.h" #include "acl/ReplyHeaderStrategy.h" #include "acl/ReplyMimeType.h" @@ -103,149 +97,99 @@ #include "auth/AclProxyAuth.h" #endif #include "base/RegexPattern.h" +#include "ExternalACL.h" #if USE_IDENT #include "ident/AclIdent.h" #endif - -ACL::Prototype ACLBrowser::RegistryProtoype(&ACLBrowser::RegistryEntry_, "browser"); -ACLStrategised ACLBrowser::RegistryEntry_(new ACLRegexData, ACLRequestHeaderStrategy::Instance(), "browser"); -ACLFlag DestinationDomainFlags[] = {ACL_F_NO_LOOKUP, ACL_F_END}; -ACL::Prototype ACLDestinationDomain::LiteralRegistryProtoype(&ACLDestinationDomain::LiteralRegistryEntry_, "dstdomain"); -ACLStrategised ACLDestinationDomain::LiteralRegistryEntry_(new ACLDomainData, ACLDestinationDomainStrategy::Instance(), "dstdomain", DestinationDomainFlags); -ACL::Prototype ACLDestinationDomain::RegexRegistryProtoype(&ACLDestinationDomain::RegexRegistryEntry_, "dstdom_regex"); -ACLFlag DestinationDomainRegexFlags[] = {ACL_F_NO_LOOKUP, ACL_F_REGEX_CASE, ACL_F_END}; -ACLStrategised ACLDestinationDomain::RegexRegistryEntry_(new ACLRegexData,ACLDestinationDomainStrategy::Instance() ,"dstdom_regex", DestinationDomainRegexFlags); -ACL::Prototype ACLDestinationIP::RegistryProtoype(&ACLDestinationIP::RegistryEntry_, "dst"); -ACLDestinationIP ACLDestinationIP::RegistryEntry_; -#if USE_AUTH -ACL::Prototype ACLExtUser::UserRegistryProtoype(&ACLExtUser::UserRegistryEntry_, "ext_user"); -ACLExtUser ACLExtUser::UserRegistryEntry_(new ACLUserData, "ext_user"); -ACL::Prototype ACLExtUser::RegexRegistryProtoype(&ACLExtUser::RegexRegistryEntry_, "ext_user_regex" ); -ACLExtUser ACLExtUser::RegexRegistryEntry_(new ACLRegexData, "ext_user_regex"); +#if SQUID_SNMP +#include "snmp_core.h" #endif -ACL::Prototype ACLHierCode::RegistryProtoype(&ACLHierCode::RegistryEntry_, "hier_code"); -ACLStrategised ACLHierCode::RegistryEntry_(new ACLHierCodeData, ACLHierCodeStrategy::Instance(), "hier_code"); -ACL::Prototype ACLHTTPRepHeader::RegistryProtoype(&ACLHTTPRepHeader::RegistryEntry_, "rep_header"); -ACLStrategised ACLHTTPRepHeader::RegistryEntry_(new ACLHTTPHeaderData, ACLHTTPRepHeaderStrategy::Instance(), "rep_header"); -ACL::Prototype ACLHTTPReqHeader::RegistryProtoype(&ACLHTTPReqHeader::RegistryEntry_, "req_header"); -ACLStrategised ACLHTTPReqHeader::RegistryEntry_(new ACLHTTPHeaderData, ACLHTTPReqHeaderStrategy::Instance(), "req_header"); -ACL::Prototype ACLHTTPStatus::RegistryProtoype(&ACLHTTPStatus::RegistryEntry_, "http_status"); -ACLHTTPStatus ACLHTTPStatus::RegistryEntry_("http_status"); -ACL::Prototype ACLMaxConnection::RegistryProtoype(&ACLMaxConnection::RegistryEntry_, "maxconn"); -ACLMaxConnection ACLMaxConnection::RegistryEntry_("maxconn"); -ACL::Prototype ACLMethod::RegistryProtoype(&ACLMethod::RegistryEntry_, "method"); -ACLStrategised ACLMethod::RegistryEntry_(new ACLMethodData, ACLMethodStrategy::Instance(), "method"); -ACL::Prototype ACLLocalIP::RegistryProtoype(&ACLLocalIP::RegistryEntry_, "localip"); -ACLLocalIP ACLLocalIP::RegistryEntry_; -ACL::Prototype ACLLocalPort::RegistryProtoype(&ACLLocalPort::RegistryEntry_, "localport"); -ACLStrategised ACLLocalPort::RegistryEntry_(new ACLIntRange, ACLLocalPortStrategy::Instance(), "localport"); -ACL::Prototype ACLMyPortName::RegistryProtoype(&ACLMyPortName::RegistryEntry_, "myportname"); -ACLStrategised ACLMyPortName::RegistryEntry_(new ACLStringData, ACLMyPortNameStrategy::Instance(), "myportname"); -ACL::Prototype ACLPeerName::RegistryProtoype(&ACLPeerName::RegistryEntry_, "peername"); -ACLStrategised ACLPeerName::RegistryEntry_(new ACLStringData, ACLPeerNameStrategy::Instance(), "peername"); -ACL::Prototype ACLPeerName::RegexRegistryProtoype(&ACLPeerName::RegexRegistryEntry_, "peername_regex"); -ACLStrategised ACLPeerName::RegexRegistryEntry_(new ACLRegexData, ACLPeerNameStrategy::Instance(), "peername_regex"); -ACL::Prototype ACLProtocol::RegistryProtoype(&ACLProtocol::RegistryEntry_, "proto"); -ACLStrategised ACLProtocol::RegistryEntry_(new ACLProtocolData, ACLProtocolStrategy::Instance(), "proto"); -ACL::Prototype ACLRandom::RegistryProtoype(&ACLRandom::RegistryEntry_, "random"); -ACLRandom ACLRandom::RegistryEntry_("random"); -ACL::Prototype ACLReferer::RegistryProtoype(&ACLReferer::RegistryEntry_, "referer_regex"); -ACLStrategised ACLReferer::RegistryEntry_(new ACLRegexData, ACLRequestHeaderStrategy::Instance(), "referer_regex"); -ACL::Prototype ACLReplyMIMEType::RegistryProtoype(&ACLReplyMIMEType::RegistryEntry_, "rep_mime_type"); -ACLStrategised ACLReplyMIMEType::RegistryEntry_(new ACLRegexData, ACLReplyHeaderStrategy::Instance(), "rep_mime_type"); -ACL::Prototype ACLRequestMIMEType::RegistryProtoype(&ACLRequestMIMEType::RegistryEntry_, "req_mime_type"); -ACLStrategised ACLRequestMIMEType::RegistryEntry_(new ACLRegexData, ACLRequestHeaderStrategy::Instance(), "req_mime_type"); -ACL::Prototype ACLSourceDomain::LiteralRegistryProtoype(&ACLSourceDomain::LiteralRegistryEntry_, "srcdomain"); -ACLStrategised ACLSourceDomain::LiteralRegistryEntry_(new ACLDomainData, ACLSourceDomainStrategy::Instance(), "srcdomain"); -ACL::Prototype ACLSourceDomain::RegexRegistryProtoype(&ACLSourceDomain::RegexRegistryEntry_, "srcdom_regex"); -ACLStrategised ACLSourceDomain::RegexRegistryEntry_(new ACLRegexData,ACLSourceDomainStrategy::Instance() ,"srcdom_regex"); -ACL::Prototype ACLSourceIP::RegistryProtoype(&ACLSourceIP::RegistryEntry_, "src"); -ACLSourceIP ACLSourceIP::RegistryEntry_; -ACL::Prototype ACLTime::RegistryProtoype(&ACLTime::RegistryEntry_, "time"); -ACLStrategised ACLTime::RegistryEntry_(new ACLTimeData, ACLTimeStrategy::Instance(), "time"); -ACL::Prototype ACLUrl::RegistryProtoype(&ACLUrl::RegistryEntry_, "url_regex"); -ACLStrategised ACLUrl::RegistryEntry_(new ACLRegexData, ACLUrlStrategy::Instance(), "url_regex"); -ACL::Prototype ACLUrlLogin::RegistryProtoype(&ACLUrlLogin::RegistryEntry_, "urllogin"); -ACLStrategised ACLUrlLogin::RegistryEntry_(new ACLRegexData, ACLUrlLoginStrategy::Instance(), "urllogin"); -ACL::Prototype ACLUrlPath::LegacyRegistryProtoype(&ACLUrlPath::RegistryEntry_, "pattern"); -ACL::Prototype ACLUrlPath::RegistryProtoype(&ACLUrlPath::RegistryEntry_, "urlpath_regex"); -ACLStrategised ACLUrlPath::RegistryEntry_(new ACLRegexData, ACLUrlPathStrategy::Instance(), "urlpath_regex"); -ACL::Prototype ACLUrlPort::RegistryProtoype(&ACLUrlPort::RegistryEntry_, "port"); -ACLStrategised ACLUrlPort::RegistryEntry_(new ACLIntRange, ACLUrlPortStrategy::Instance(), "port"); - -#if USE_OPENSSL -ACL::Prototype ACLSslError::RegistryProtoype(&ACLSslError::RegistryEntry_, "ssl_error"); -ACLStrategised ACLSslError::RegistryEntry_(new ACLSslErrorData, ACLSslErrorStrategy::Instance(), "ssl_error"); -ACL::Prototype ACLCertificate::UserRegistryProtoype(&ACLCertificate::UserRegistryEntry_, "user_cert"); -ACLStrategised ACLCertificate::UserRegistryEntry_(new ACLCertificateData (Ssl::GetX509UserAttribute, "*"), ACLCertificateStrategy::Instance(), "user_cert"); -ACL::Prototype ACLCertificate::CARegistryProtoype(&ACLCertificate::CARegistryEntry_, "ca_cert"); -ACLStrategised ACLCertificate::CARegistryEntry_(new ACLCertificateData (Ssl::GetX509CAAttribute, "*"), ACLCertificateStrategy::Instance(), "ca_cert"); -ACL::Prototype ACLServerCertificate::X509FingerprintRegistryProtoype(&ACLServerCertificate::X509FingerprintRegistryEntry_, "server_cert_fingerprint"); -ACLStrategised ACLServerCertificate::X509FingerprintRegistryEntry_(new ACLCertificateData(Ssl::GetX509Fingerprint, "-sha1", true), ACLServerCertificateStrategy::Instance(), "server_cert_fingerprint"); -ACL::Prototype ACLAtStep::RegistryProtoype(&ACLAtStep::RegistryEntry_, "at_step"); -ACLStrategised ACLAtStep::RegistryEntry_(new ACLAtStepData, ACLAtStepStrategy::Instance(), "at_step"); +// Not in src/acl/ because some of the ACLs it registers are not in src/acl/. +void +Acl::Init() +{ + /* the registration order does not matter */ + + // The explicit return type (ACL*) for lambdas is needed because the type + // of the return expression inside lambda is not ACL* but AclFoo* while + // Acl::Maker is defined to return ACL*. + + RegisterMaker("all-of", [](TypeName)->ACL* { return new Acl::AllOf; }); // XXX: Add name parameter to ctor + RegisterMaker("any-of", [](TypeName)->ACL* { return new Acl::AnyOf; }); // XXX: Add name parameter to ctor + RegisterMaker("random", [](TypeName name)->ACL* { return new ACLRandom(name); }); + RegisterMaker("time", [](TypeName name)->ACL* { return new ACLStrategised(new ACLTimeData, new ACLTimeStrategy, name); }); + RegisterMaker("src_as", [](TypeName name)->ACL* { return new ACLStrategised(new ACLASN, new ACLSourceASNStrategy, name); }); + RegisterMaker("dst_as", [](TypeName name)->ACL* { return new ACLStrategised(new ACLASN, new ACLDestinationASNStrategy, name); }); + RegisterMaker("browser", [](TypeName name)->ACL* { return new ACLStrategised(new ACLRegexData, new ACLRequestHeaderStrategy, name); }); + RegisterMaker("dstdomain", [](TypeName name)->ACL* { return new ACLStrategised(new ACLDomainData, new ACLDestinationDomainStrategy, name); }); + RegisterMaker("dstdom_regex", [](TypeName name)->ACL* { return new ACLStrategised(new ACLRegexData, new ACLDestinationDomainStrategy , name); }); + RegisterMaker("dst", [](TypeName)->ACL* { return new ACLDestinationIP; }); // XXX: Add name parameter to ctor + RegisterMaker("hier_code", [](TypeName name)->ACL* { return new ACLStrategised(new ACLHierCodeData, new ACLHierCodeStrategy, name); }); + RegisterMaker("rep_header", [](TypeName name)->ACL* { return new ACLStrategised(new ACLHTTPHeaderData, new ACLHTTPRepHeaderStrategy, name); }); + RegisterMaker("req_header", [](TypeName name)->ACL* { return new ACLStrategised(new ACLHTTPHeaderData, new ACLHTTPReqHeaderStrategy, name); }); + RegisterMaker("http_status", [](TypeName name)->ACL* { return new ACLHTTPStatus(name); }); + RegisterMaker("maxconn", [](TypeName name)->ACL* { return new ACLMaxConnection(name); }); + RegisterMaker("method", [](TypeName name)->ACL* { return new ACLStrategised(new ACLMethodData, new ACLMethodStrategy, name); }); + RegisterMaker("localip", [](TypeName)->ACL* { return new ACLLocalIP; }); // XXX: Add name parameter to ctor + RegisterMaker("localport", [](TypeName name)->ACL* { return new ACLStrategised(new ACLIntRange, new ACLLocalPortStrategy, name); }); + RegisterMaker("myportname", [](TypeName name)->ACL* { return new ACLStrategised(new ACLStringData, new ACLMyPortNameStrategy, name); }); + RegisterMaker("peername", [](TypeName name)->ACL* { return new ACLStrategised(new ACLStringData, new ACLPeerNameStrategy, name); }); + RegisterMaker("peername_regex", [](TypeName name)->ACL* { return new ACLStrategised(new ACLRegexData, new ACLPeerNameStrategy, name); }); + RegisterMaker("proto", [](TypeName name)->ACL* { return new ACLStrategised(new ACLProtocolData, new ACLProtocolStrategy, name); }); + RegisterMaker("referer_regex", [](TypeName name)->ACL* { return new ACLStrategised(new ACLRegexData, new ACLRequestHeaderStrategy, name); }); + RegisterMaker("rep_mime_type", [](TypeName name)->ACL* { return new ACLStrategised(new ACLRegexData, new ACLReplyHeaderStrategy, name); }); + RegisterMaker("req_mime_type", [](TypeName name)->ACL* { return new ACLStrategised(new ACLRegexData, new ACLRequestHeaderStrategy, name); }); + RegisterMaker("srcdomain", [](TypeName name)->ACL* { return new ACLStrategised(new ACLDomainData, new ACLSourceDomainStrategy, name); }); + RegisterMaker("srcdom_regex", [](TypeName name)->ACL* { return new ACLStrategised(new ACLRegexData, new ACLSourceDomainStrategy, name); }); + RegisterMaker("src", [](TypeName)->ACL* { return new ACLSourceIP; }); // XXX: Add name parameter to ctor + RegisterMaker("url_regex", [](TypeName name)->ACL* { return new ACLStrategised(new ACLRegexData, new ACLUrlStrategy, name); }); + RegisterMaker("urllogin", [](TypeName name)->ACL* { return new ACLStrategised(new ACLRegexData, new ACLUrlLoginStrategy, name); }); + RegisterMaker("urlpath_regex", [](TypeName name)->ACL* { return new ACLStrategised(new ACLRegexData, new ACLUrlPathStrategy, name); }); + RegisterMaker("port", [](TypeName name)->ACL* { return new ACLStrategised(new ACLIntRange, new ACLUrlPortStrategy, name); }); + RegisterMaker("external", [](TypeName name)->ACL* { return new ACLExternal(name); }); + RegisterMaker("squid_error", [](TypeName name)->ACL* { return new ACLStrategised(new ACLSquidErrorData, new ACLSquidErrorStrategy, name); }); + RegisterMaker("connections_encrypted", [](TypeName name)->ACL* { return new Acl::ConnectionsEncrypted(name); }); + RegisterMaker("tag", [](TypeName name)->ACL* { return new ACLStrategised(new ACLStringData, new ACLTagStrategy, name); }); + RegisterMaker("note", [](TypeName name)->ACL* { return new ACLStrategised(new ACLNoteData, new ACLNoteStrategy, name); }); + RegisterMaker("annotate_client", [](TypeName name)->ACL* { return new ACLStrategised(new ACLAnnotationData, new ACLAnnotateClientStrategy, name); }); + RegisterMaker("annotate_transaction", [](TypeName name)->ACL* { return new ACLStrategised(new ACLAnnotationData, new ACLAnnotateTransactionStrategy, name); }); + RegisterMaker("has", [](TypeName name)->ACL* {return new ACLStrategised(new ACLHasComponentData, new ACLHasComponentStrategy, name); }); -ACL::Prototype ACLServerName::LiteralRegistryProtoype(&ACLServerName::LiteralRegistryEntry_, "ssl::server_name"); -ACLStrategised ACLServerName::LiteralRegistryEntry_(new ACLServerNameData, ACLServerNameStrategy::Instance(), "ssl::server_name"); -ACL::Prototype ACLServerName::RegexRegistryProtoype(&ACLServerName::RegexRegistryEntry_, "ssl::server_name_regex"); -ACLFlag ServerNameRegexFlags[] = {ACL_F_REGEX_CASE, ACL_F_END}; -ACLStrategised ACLServerName::RegexRegistryEntry_(new ACLRegexData, ACLServerNameStrategy::Instance(), "ssl::server_name_regex", ServerNameRegexFlags); +#if USE_OPENSSL + RegisterMaker("ssl_error", [](TypeName name)->ACL* { return new ACLStrategised(new ACLSslErrorData, new ACLSslErrorStrategy, name); }); + RegisterMaker("user_cert", [](TypeName name)->ACL* { return new ACLStrategised(new ACLCertificateData(Ssl::GetX509UserAttribute, "*"), new ACLCertificateStrategy, name); }); + RegisterMaker("ca_cert", [](TypeName name)->ACL* { return new ACLStrategised(new ACLCertificateData(Ssl::GetX509CAAttribute, "*"), new ACLCertificateStrategy, name); }); + RegisterMaker("server_cert_fingerprint", [](TypeName name)->ACL* { return new ACLStrategised(new ACLCertificateData(Ssl::GetX509Fingerprint, "-sha1", true), new ACLServerCertificateStrategy, name); }); + RegisterMaker("at_step", [](TypeName name)->ACL* { return new ACLStrategised(new ACLAtStepData, new ACLAtStepStrategy, name); }); + RegisterMaker("ssl::server_name", [](TypeName name)->ACL* { return new ACLStrategised(new ACLServerNameData, new ACLServerNameStrategy, name); }); + RegisterMaker("ssl::server_name_regex", [](TypeName name)->ACL* { return new ACLStrategised(new ACLRegexData, new ACLServerNameStrategy, name); }); #endif #if USE_SQUID_EUI -ACL::Prototype ACLARP::RegistryProtoype(&ACLARP::RegistryEntry_, "arp"); -ACLARP ACLARP::RegistryEntry_("arp"); -ACL::Prototype ACLEui64::RegistryProtoype(&ACLEui64::RegistryEntry_, "eui64"); -ACLEui64 ACLEui64::RegistryEntry_("eui64"); + RegisterMaker("arp", [](TypeName name)->ACL* { return new ACLARP(name); }); + RegisterMaker("eui64", [](TypeName name)->ACL* { return new ACLEui64(name); }); #endif #if USE_IDENT -ACL::Prototype ACLIdent::UserRegistryProtoype(&ACLIdent::UserRegistryEntry_, "ident"); -ACLIdent ACLIdent::UserRegistryEntry_(new ACLUserData, "ident"); -ACL::Prototype ACLIdent::RegexRegistryProtoype(&ACLIdent::RegexRegistryEntry_, "ident_regex" ); -ACLIdent ACLIdent::RegexRegistryEntry_(new ACLRegexData, "ident_regex"); + RegisterMaker("ident", [](TypeName name)->ACL* { return new ACLIdent(new ACLUserData, name); }); + RegisterMaker("ident_regex", [](TypeName name)->ACL* { return new ACLIdent(new ACLRegexData, name); }); #endif #if USE_AUTH -ACL::Prototype ACLProxyAuth::UserRegistryProtoype(&ACLProxyAuth::UserRegistryEntry_, "proxy_auth"); -ACLProxyAuth ACLProxyAuth::UserRegistryEntry_(new ACLUserData, "proxy_auth"); -ACL::Prototype ACLProxyAuth::RegexRegistryProtoype(&ACLProxyAuth::RegexRegistryEntry_, "proxy_auth_regex" ); -ACLProxyAuth ACLProxyAuth::RegexRegistryEntry_(new ACLRegexData, "proxy_auth_regex"); - -ACL::Prototype ACLMaxUserIP::RegistryProtoype(&ACLMaxUserIP::RegistryEntry_, "max_user_ip"); -ACLMaxUserIP ACLMaxUserIP::RegistryEntry_("max_user_ip"); + RegisterMaker("ext_user", [](TypeName name)->ACL* { return new ACLExtUser(new ACLUserData, name); }); + RegisterMaker("ext_user_regex", [](TypeName name)->ACL* { return new ACLExtUser(new ACLRegexData, name); }); + RegisterMaker("proxy_auth", [](TypeName name)->ACL* { return new ACLProxyAuth(new ACLUserData, name); }); + RegisterMaker("proxy_auth_regex", [](TypeName name)->ACL* { return new ACLProxyAuth(new ACLRegexData, name); }); + RegisterMaker("max_user_ip", [](TypeName name)->ACL* { return new ACLMaxUserIP(name); }); #endif -ACL::Prototype ACLTag::RegistryProtoype(&ACLTag::RegistryEntry_, "tag"); -ACLStrategised ACLTag::RegistryEntry_(new ACLStringData, ACLTagStrategy::Instance(), "tag"); - -ACL::Prototype Acl::AnyOf::RegistryProtoype(&Acl::AnyOf::RegistryEntry_, "any-of"); -Acl::AnyOf Acl::AnyOf::RegistryEntry_; - -ACL::Prototype Acl::AllOf::RegistryProtoype(&Acl::AllOf::RegistryEntry_, "all-of"); -Acl::AllOf Acl::AllOf::RegistryEntry_; - -ACL::Prototype ACLNote::RegistryProtoype(&ACLNote::RegistryEntry_, "note"); -ACLStrategised ACLNote::RegistryEntry_(new ACLNoteData, ACLNoteStrategy::Instance(), "note"); - -ACL::Prototype ACLAnnotateClient::RegistryProtoype(&ACLAnnotateClient::RegistryEntry_, "annotate_client"); -ACLStrategised ACLAnnotateClient::RegistryEntry_(new ACLAnnotationData, ACLAnnotateClientStrategy::Instance(), "annotate_client"); - -ACL::Prototype ACLAnnotateTransaction::RegistryProtoype(&ACLAnnotateTransaction::RegistryEntry_, "annotate_transaction"); -ACLStrategised ACLAnnotateTransaction::RegistryEntry_(new ACLAnnotationData, ACLAnnotateTransactionStrategy::Instance(), "annotate_transaction"); - #if USE_ADAPTATION -ACL::Prototype ACLAdaptationService::RegistryProtoype(&ACLAdaptationService::RegistryEntry_, "adaptation_service"); -ACLStrategised ACLAdaptationService::RegistryEntry_(new ACLAdaptationServiceData, ACLAdaptationServiceStrategy::Instance(), "adaptation_service"); + RegisterMaker("adaptation_service", [](TypeName name)->ACL* { return new ACLStrategised(new ACLAdaptationServiceData, new ACLAdaptationServiceStrategy, name); }); #endif -ACL::Prototype ACLSquidError::RegistryProtoype(&ACLSquidError::RegistryEntry_, "squid_error"); -ACLStrategised ACLSquidError::RegistryEntry_(new ACLSquidErrorData, ACLSquidErrorStrategy::Instance(), "squid_error"); - -ACL::Prototype Acl::ConnectionsEncrypted::RegistryProtoype(&Acl::ConnectionsEncrypted::RegistryEntry_, "connections_encrypted"); -Acl::ConnectionsEncrypted Acl::ConnectionsEncrypted::RegistryEntry_("connections_encrypted"); - -ACL::Prototype ACLHasComponent::RegistryProtoype(&ACLHasComponent::RegistryEntry_, "has"); -ACLStrategised ACLHasComponent::RegistryEntry_(new ACLHasComponentData, ACLHasComponentStrategy::Instance(), "has"); +#if SQUID_SNMP + RegisterMaker("snmp_community", [](TypeName name)->ACL* { return new ACLStrategised(new ACLStringData, new ACLSNMPCommunityStrategy, name); }); +#endif +} diff --git a/src/ExternalACL.h b/src/ExternalACL.h index a22d8ac993..9e7e2f606a 100644 --- a/src/ExternalACL.h +++ b/src/ExternalACL.h @@ -62,8 +62,6 @@ public: virtual bool empty () const; protected: - static Prototype RegistryProtoype; - static ACLExternal RegistryEntry_; external_acl_data *data; char const *class_; }; diff --git a/src/MessageDelayPools.h b/src/MessageDelayPools.h index 73b499d023..bddd15e665 100644 --- a/src/MessageDelayPools.h +++ b/src/MessageDelayPools.h @@ -15,6 +15,7 @@ #include "base/RefCount.h" #include "DelayBucket.h" #include "DelayPools.h" +#include "sbuf/SBuf.h" class MessageBucket; typedef RefCount MessageBucketPointer; diff --git a/src/acl/Acl.cc b/src/acl/Acl.cc index 78111e352b..8db5020353 100644 --- a/src/acl/Acl.cc +++ b/src/acl/Acl.cc @@ -12,195 +12,68 @@ #include "acl/Acl.h" #include "acl/Checklist.h" #include "acl/Gadgets.h" +#include "acl/Options.h" #include "anyp/PortCfg.h" #include "cache_cf.h" #include "ConfigParser.h" #include "Debug.h" -#include "dlink.h" #include "fatal.h" #include "globals.h" #include "profiler/Profiler.h" +#include "sbuf/List.h" +#include "sbuf/Stream.h" #include "SquidConfig.h" -#include - -#define abortFlags(CONTENT) \ - do { \ - debugs(28, 0, CONTENT); \ - self_destruct(); \ - } while (0) - -const ACLFlag ACLFlags::NoFlags[1] = {ACL_F_END}; +#include +#include const char *AclMatchedName = NULL; -ACLFlags::FlagsTokenizer::FlagsTokenizer() - : tokPos(nullptr), Parameter(nullptr) {} +namespace Acl { -ACLFlag -ACLFlags::FlagsTokenizer::nextFlag() -{ - if (needNextToken()) { - if (!nextToken()) - return 0; - } else - ++tokPos; - return *tokPos; -} - -bool -ACLFlags::FlagsTokenizer::hasParameter() const -{ - return tokPos && tokPos[0] && !tokPos[1] && Parameter; -} +/// ACL type name comparison functor +class TypeNameCmp { +public: + bool operator()(TypeName a, TypeName b) const { return strcmp(a, b) < 0; } +}; -SBuf -ACLFlags::FlagsTokenizer::getParameter() const -{ - return hasParameter() ? SBuf(Parameter) : SBuf(); -} +/// ACL makers indexed by ACL type name +typedef std::map Makers; -bool -ACLFlags::FlagsTokenizer::needNextToken() const +/// registered ACL Makers +static Makers & +TheMakers() { - return !tokPos || !tokPos[0] || !tokPos[1]; + static Makers Registry; + return Registry; } -bool -ACLFlags::FlagsTokenizer::nextToken() +/// creates an ACL object of the named (and already registered) ACL child type +static +ACL * +Make(TypeName typeName) { - char *t = ConfigParser::PeekAtToken(); - if (t == NULL || t[0] != '-' || !t[1]) - return false; - if (strchr(t, '=')) { - if(!ConfigParser::NextKvPair(tokPos, Parameter)) - abortFlags("Invalid formatting for flag '" << t << "'"); - assert(tokPos[0] == '-'); - tokPos++; - } else { - (void)ConfigParser::NextToken(); - if (!strcmp(t, "--")) - return false; - tokPos = t + 1; + const auto pos = TheMakers().find(typeName); + if (pos == TheMakers().end()) { + debugs(28, DBG_CRITICAL, "FATAL: Invalid ACL type '" << typeName << "'"); + self_destruct(); + assert(false); // not reached } - return true; -} - -ACLFlags::~ACLFlags() -{ - delete delimiters_; -} - -ACLFlags::Status -ACLFlags::flagStatus(const ACLFlag f) const -{ - if (f == ACL_F_REGEX_CASE) - return noParameter; - if (f == ACL_F_SUBSTRING) - return parameterOptional; - if (supported_.find(f) != std::string::npos) - return noParameter; - return notSupported; -} - -bool -ACLFlags::parameterSupported(const ACLFlag f, const SBuf &val) const -{ - if (f == ACL_F_SUBSTRING) - return val.findFirstOf(CharacterSet::ALPHA + CharacterSet::DIGIT) == SBuf::npos; - return true; -} -void -ACLFlags::makeSet(const ACLFlag f, const SBuf ¶m) -{ - flags_ |= flagToInt(f); - if (!param.isEmpty()) - flagParameters_[f].append(param); + ACL *result = (pos->second)(pos->first); + debugs(28, 4, typeName << '=' << result); + assert(result); + return result; } -void -ACLFlags::makeUnSet(const ACLFlag f) -{ - flags_ &= ~flagToInt(f); - flagParameters_[f].clear(); -} +} // namespace Acl void -ACLFlags::parseFlags() -{ - FlagsTokenizer tokenizer; - ACLFlag flag('\0'); - while ((flag = tokenizer.nextFlag())) { - switch (flagStatus(flag)) - { - case notSupported: - abortFlags("Flag '" << flag << "' not supported"); - break; - case noParameter: - makeSet(flag); - break; - case parameterRequired: - if (!tokenizer.hasParameter()) { - abortFlags("Flag '" << flag << "' must have a parameter"); - break; - } - case parameterOptional: - SBuf param; - if (tokenizer.hasParameter()) { - param = tokenizer.getParameter(); - if (!parameterSupported(flag, param)) - abortFlags("Parameter '" << param << "' for flag '" << flag << "' not supported"); - } - makeSet(flag, param); - break; - } - } - - /*Regex code needs to parse -i file*/ - if ( isSet(ACL_F_REGEX_CASE)) { - ConfigParser::TokenPutBack("-i"); - makeUnSet('i'); - } -} - -SBuf -ACLFlags::parameter(const ACLFlag f) const +Acl::RegisterMaker(TypeName typeName, Maker maker) { - assert(static_cast(f - 'A') < FlagIndexMax); - auto p = flagParameters_.find(f); - return p == flagParameters_.end() ? SBuf() : p->second; -} - -const CharacterSet * -ACLFlags::delimiters() -{ - if (isSet(ACL_F_SUBSTRING) && !delimiters_) { - static const SBuf defaultParameter(","); - SBuf rawParameter = parameter(ACL_F_SUBSTRING); - if (rawParameter.isEmpty()) - rawParameter = defaultParameter; - delimiters_ = new CharacterSet("ACLFlags::delimiters", rawParameter.c_str()); - } - return delimiters_; -} - -const char * -ACLFlags::flagsStr() const -{ - static char buf[64]; - if (flags_ == 0) - return ""; - - char *s = buf; - *s++ = '-'; - for (ACLFlag f = 'A'; f <= 'z'; f++) { - // ACL_F_REGEX_CASE (-i) flag handled by ACLRegexData class, ignore - if (isSet(f) && f != ACL_F_REGEX_CASE) - *s++ = f; - } - *s = '\0'; - return buf; + assert(typeName); + assert(*typeName); + TheMakers().emplace(typeName, maker); } void * @@ -231,17 +104,6 @@ ACL::FindByName(const char *name) return NULL; } -ACL * -ACL::Factory (char const *type) -{ - ACL *result = Prototype::Factory (type); - - if (!result) - fatal ("Unknown acl type in ACL::Factory"); - - return result; -} - ACL::ACL() : cfgline(nullptr), next(nullptr), @@ -250,15 +112,6 @@ ACL::ACL() : *name = 0; } -ACL::ACL(const ACLFlag flgs[]) : - cfgline(NULL), - next(NULL), - flags(flgs), - registered(false) -{ - *name = 0; -} - bool ACL::valid () const { return true; @@ -373,16 +226,9 @@ ACL::ParseAclLine(ConfigParser &parser, ACL ** head) return; // ignore the line } - if (!Prototype::Registered(theType)) { - debugs(28, DBG_CRITICAL, "FATAL: Invalid ACL type '" << theType << "'"); - // XXX: make this an ERROR and skip the ACL creation. We *may* die later when its use is attempted. Or may not. - parser.destruct(); - return; - } - if ((A = FindByName(aclname)) == NULL) { debugs(28, 3, "aclParseAclLine: Creating ACL '" << aclname << "'"); - A = ACL::Factory(theType); + A = Acl::Make(theType); A->context(aclname, config_input_line); new_acl = 1; } else { @@ -402,7 +248,7 @@ ACL::ParseAclLine(ConfigParser &parser, ACL ** head) */ AclMatchedName = A->name; /* ugly */ - A->flags.parseFlags(); + A->parseFlags(); /*split the function here */ A->parse(); @@ -439,6 +285,30 @@ ACL::isProxyAuth() const return false; } +void +ACL::parseFlags() +{ + // ACL kids that carry ACLData which supports parameter flags override this + Acl::ParseFlags(options(), Acl::NoFlags()); +} + +SBufList +ACL::dumpOptions() +{ + SBufList result; + const auto &myOptions = options(); + // optimization: most ACLs do not have myOptions + // this check also works around dump_SBufList() adding ' ' after empty items + if (!myOptions.empty()) { + SBufStream stream; + stream << myOptions; + const SBuf optionsImage = stream.buf(); + if (!optionsImage.isEmpty()) + result.push_back(optionsImage); + } + return result; +} + /* ACL result caching routines */ int @@ -530,69 +400,6 @@ ACL::~ACL() AclMatchedName = NULL; // in case it was pointing to our name } -ACL::Prototype::Prototype() : prototype (NULL), typeString (NULL) {} - -ACL::Prototype::Prototype (ACL const *aPrototype, char const *aType) : prototype (aPrototype), typeString (aType) -{ - registerMe (); -} - -std::vector * ACL::Prototype::Registry; -void *ACL::Prototype::Initialized; - -bool -ACL::Prototype::Registered(char const *aType) -{ - debugs(28, 7, "ACL::Prototype::Registered: invoked for type " << aType); - - for (iterator i = Registry->begin(); i != Registry->end(); ++i) - if (!strcmp (aType, (*i)->typeString)) { - debugs(28, 7, "ACL::Prototype::Registered: yes"); - return true; - } - - debugs(28, 7, "ACL::Prototype::Registered: no"); - return false; -} - -void -ACL::Prototype::registerMe () -{ - if (!Registry || (Initialized != ((char *)Registry - 5)) ) { - /* TODO: extract this */ - /* Not initialised */ - Registry = new std::vector; - Initialized = (char *)Registry - 5; - } - - if (Registered (typeString)) - fatalf ("Attempt to register %s twice", typeString); - - Registry->push_back (this); -} - -ACL::Prototype::~Prototype() -{ - // TODO: unregister me -} - -ACL * -ACL::Prototype::Factory (char const *typeToClone) -{ - debugs(28, 4, "ACL::Prototype::Factory: cloning an object for type '" << typeToClone << "'"); - - for (iterator i = Registry->begin(); i != Registry->end(); ++i) - if (!strcmp (typeToClone, (*i)->typeString)) { - ACL *A = (*i)->prototype->clone(); - A->flags = (*i)->prototype->flags; - return A; - } - - debugs(28, 4, "ACL::Prototype::Factory: cloning failed, no type '" << typeToClone << "' available"); - - return NULL; -} - void ACL::Initialize() { diff --git a/src/acl/Acl.h b/src/acl/Acl.h index c837089ca4..9ed1b19c30 100644 --- a/src/acl/Acl.h +++ b/src/acl/Acl.h @@ -10,110 +10,26 @@ #define SQUID_ACL_H #include "acl/forward.h" -#include "base/CharacterSet.h" +#include "acl/Options.h" #include "cbdata.h" #include "defines.h" #include "dlink.h" -#include "sbuf/List.h" +#include "sbuf/forward.h" -#include #include -#include -#include class ConfigParser; -typedef char ACLFlag; -// ACLData Flags -#define ACL_F_REGEX_CASE 'i' -#define ACL_F_NO_LOOKUP 'n' -#define ACL_F_STRICT 's' -#define ACL_F_SUBSTRING 'm' -#define ACL_F_END '\0' - -/** - * \ingroup ACLAPI - * Used to hold a list of one-letter flags which can be passed as parameters - * to acls (eg '-i', '-n' etc) - */ -class ACLFlags -{ -public: - enum Status - { - notSupported, - noParameter, - parameterOptional, - parameterRequired - }; - - explicit ACLFlags(const ACLFlag flags[]) : supported_(flags), flags_(0), delimiters_(nullptr) {} - ACLFlags() : flags_(0), delimiters_(nullptr) {} - ~ACLFlags(); - /// \return a Status for the given ACLFlag. - Status flagStatus(const ACLFlag f) const; - /// \return true if the parameter for the given flag is acceptable. - bool parameterSupported(const ACLFlag f, const SBuf &val) const; - /// Set the given flag - void makeSet(const ACLFlag f, const SBuf ¶m = SBuf("")); - void makeUnSet(const ACLFlag f); ///< Unset the given flag - /// \return true if the given flag is set. - bool isSet(const ACLFlag f) const { return flags_ & flagToInt(f);} - /// \return the parameter value of the given flag if set. - SBuf parameter(const ACLFlag f) const; - /// \return ACL_F_SUBSTRING parameter value(if set) converted to CharacterSet. - const CharacterSet *delimiters(); - /// Parse optional flags given in the form -[A..Z|a..z] - void parseFlags(); - const char *flagsStr() const; ///< Convert the flags to a string representation - /** - * Lexical analyzer for ACL flags - * - * Support tokens in the form: - * flag := '-' [A-Z|a-z]+ ['=' parameter ] - * Each token consist by one or more single-letter flags, which may - * followed by a parameter string. - * The parameter can belongs only to the last flag in token. - */ - class FlagsTokenizer - { - public: - FlagsTokenizer(); - ACLFlag nextFlag(); ///< The next flag or '\0' if finished - /// \return true if a parameter follows the last parsed flag. - bool hasParameter() const; - /// \return the parameter of last parsed flag, if exist. - SBuf getParameter() const; - - private: - /// \return true if the current token parsing is finished. - bool needNextToken() const; - /// Peeks at the next token and return false if the next token - /// is not flag, or a '--' is read. - bool nextToken(); - - char *tokPos; - char *Parameter; - }; +namespace Acl { -private: - /// Convert a flag to a 64bit unsigned integer. - /// The characters from 'A' to 'z' represented by the values from 65 to 122. - /// They are 57 different characters which can be fit to the bits of an 64bit - /// integer. - uint64_t flagToInt(const ACLFlag f) const { - assert('A' <= f && f <= 'z'); - return ((uint64_t)1 << (f - 'A')); - } +/// the ACL type name known to admins +typedef const char *TypeName; +/// a "factory" function for making ACL objects (of some ACL child type) +typedef ACL *(*Maker)(TypeName typeName); +/// use the given ACL Maker for all ACLs of the named type +void RegisterMaker(TypeName typeName, Maker maker); - std::string supported_; ///< The supported character flags - uint64_t flags_; ///< The flags which are set - static const uint32_t FlagIndexMax = 'z' - 'A'; - std::map flagParameters_; - CharacterSet *delimiters_; -public: - static const ACLFlag NoFlags[1]; ///< An empty flags list -}; +} // namespace Acl /// A configurable condition. A node in the ACL expression tree. /// Can evaluate itself in FilledChecklist context. @@ -126,13 +42,11 @@ public: void *operator new(size_t); void operator delete(void *); - static ACL *Factory(char const *); static void ParseAclLine(ConfigParser &parser, ACL ** head); static void Initialize(); static ACL *FindByName(const char *name); ACL(); - explicit ACL(const ACLFlag flgs[]); virtual ~ACL(); /// sets user-specified ACL name and squid.conf context @@ -144,7 +58,11 @@ public: /// Updates the checklist state on match, async, and failure. bool matches(ACLChecklist *checklist) const; - virtual ACL *clone() const = 0; + /// \returns (linked) Options supported by this ACL + virtual const Acl::Options &options() { return Acl::NoOptions(); } + + /// configures ACL options, throwing on configuration errors + virtual void parseFlags(); /// parses node represenation in squid.conf; dies on failures virtual void parse() = 0; @@ -159,36 +77,13 @@ public: virtual void prepareForUse() {} + SBufList dumpOptions(); ///< \returns approximate options configuration + char name[ACL_NAME_SZ]; char *cfgline; ACL *next; // XXX: remove or at least use refcounting - ACLFlags flags; ///< The list of given ACL flags bool registered; ///< added to the global list of ACLs via aclRegister() -public: - - class Prototype - { - - public: - Prototype(); - Prototype(ACL const *, char const *); - ~Prototype(); - static bool Registered(char const *); - static ACL *Factory(char const *); - - private: - ACL const *prototype; - char const *typeString; - - private: - static std::vector * Registry; - static void *Initialized; - typedef std::vector::iterator iterator; - typedef std::vector::const_iterator const_iterator; - void registerMe(); - }; - private: /// Matches the actual data in checklist against this ACL. virtual int match(ACLChecklist *checklist) = 0; // XXX: missing const diff --git a/src/acl/AdaptationService.cc b/src/acl/AdaptationService.cc index 2957266201..37c4b31f49 100644 --- a/src/acl/AdaptationService.cc +++ b/src/acl/AdaptationService.cc @@ -8,14 +8,14 @@ #include "squid.h" #include "acl/AdaptationService.h" -#include "acl/Checklist.h" +#include "acl/FilledChecklist.h" #include "acl/IntRange.h" #include "adaptation/Config.h" #include "adaptation/History.h" #include "HttpRequest.h" int -ACLAdaptationServiceStrategy::match (ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &) +ACLAdaptationServiceStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) { HttpRequest::Pointer request = checklist->request; if (request == NULL) @@ -33,11 +33,3 @@ ACLAdaptationServiceStrategy::match (ACLData * &data, ACLFilledCheckl return 0; } -ACLAdaptationServiceStrategy * -ACLAdaptationServiceStrategy::Instance() -{ - return &Instance_; -} - -ACLAdaptationServiceStrategy ACLAdaptationServiceStrategy::Instance_; - diff --git a/src/acl/AdaptationService.h b/src/acl/AdaptationService.h index 1b2ca5cf06..160e403204 100644 --- a/src/acl/AdaptationService.h +++ b/src/acl/AdaptationService.h @@ -9,7 +9,6 @@ #ifndef SQUID_ACLADAPTATIONSERVICE_H #define SQUID_ACLADAPTATIONSERVICE_H -#include "acl/Strategised.h" #include "acl/Strategy.h" /// \ingroup ACLAPI @@ -17,27 +16,7 @@ class ACLAdaptationServiceStrategy : public ACLStrategy { public: - virtual int match (ACLData * &, ACLFilledChecklist *, ACLFlags &); - static ACLAdaptationServiceStrategy *Instance(); - /** - * Not implemented to prevent copies of the instance. - */ - ACLAdaptationServiceStrategy(ACLAdaptationServiceStrategy const &); - -private: - static ACLAdaptationServiceStrategy Instance_; - ACLAdaptationServiceStrategy() {} - - ACLAdaptationServiceStrategy &operator = (ACLAdaptationServiceStrategy const &); -}; - -/// \ingroup ACLAPI -class ACLAdaptationService -{ - -private: - static ACL::Prototype RegistryProtoype; - static ACLStrategised RegistryEntry_; + virtual int match (ACLData * &, ACLFilledChecklist *) override; }; #endif /* SQUID_ACLADAPTATIONSERVICE_H */ diff --git a/src/acl/AllOf.h b/src/acl/AllOf.h index 211b41e179..e038af22d1 100644 --- a/src/acl/AllOf.h +++ b/src/acl/AllOf.h @@ -31,9 +31,6 @@ public: private: /* Acl::InnerNode API */ virtual int doMatch(ACLChecklist *checklist, Nodes::const_iterator start) const; - - static Prototype RegistryProtoype; - static AllOf RegistryEntry_; }; } // namespace Acl diff --git a/src/acl/AnnotateClient.cc b/src/acl/AnnotateClient.cc index 3aa16ad033..235d671577 100644 --- a/src/acl/AnnotateClient.cc +++ b/src/acl/AnnotateClient.cc @@ -9,29 +9,22 @@ #include "squid.h" #include "acl/AnnotateClient.h" #include "acl/AnnotationData.h" +#include "acl/FilledChecklist.h" #include "client_side.h" #include "http/Stream.h" #include "Notes.h" int -ACLAnnotateClientStrategy::match(ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &flags) +ACLAnnotateClientStrategy::match(ACLData * &data, ACLFilledChecklist *checklist) { if (const auto conn = checklist->conn()) { ACLAnnotationData *tdata = dynamic_cast(data); assert(tdata); - tdata->annotate(conn->notes(), flags.delimiters(), checklist->al); + tdata->annotate(conn->notes(), &delimiters.value, checklist->al); if (const auto request = checklist->request) - tdata->annotate(request->notes(), flags.delimiters(), checklist->al); + tdata->annotate(request->notes(), &delimiters.value, checklist->al); return 1; } return 0; } -ACLAnnotateClientStrategy * -ACLAnnotateClientStrategy::Instance() -{ - return &Instance_; -} - -ACLAnnotateClientStrategy ACLAnnotateClientStrategy::Instance_; - diff --git a/src/acl/AnnotateClient.h b/src/acl/AnnotateClient.h index bb63ca3cb1..84c2487b1a 100644 --- a/src/acl/AnnotateClient.h +++ b/src/acl/AnnotateClient.h @@ -9,31 +9,15 @@ #ifndef SQUID_ACLANNOTATECLIENT #define SQUID_ACLANNOTATECLIENT -#include "acl/Strategised.h" -#include "acl/Strategy.h" +#include "acl/Note.h" +#include "Notes.h" /// \ingroup ACLAPI -class ACLAnnotateClientStrategy : public ACLStrategy +class ACLAnnotateClientStrategy : public Acl::AnnotationStrategy { public: - static ACLAnnotateClientStrategy *Instance(); - ACLAnnotateClientStrategy(ACLAnnotateClientStrategy const &) = delete; - ACLAnnotateClientStrategy& operator=(ACLAnnotateClientStrategy const &) = delete; - virtual bool requiresRequest() const { return true; } - virtual int match(ACLData * &, ACLFilledChecklist *, ACLFlags &); - -private: - static ACLAnnotateClientStrategy Instance_; - ACLAnnotateClientStrategy() { } -}; - -/// \ingroup ACLAPI -class ACLAnnotateClient -{ -private: - static ACL::Prototype RegistryProtoype; - static ACLStrategised RegistryEntry_; + virtual int match(ACLData * &, ACLFilledChecklist *); }; #endif /* SQUID_ACLANNOTATECLIENT */ diff --git a/src/acl/AnnotateTransaction.cc b/src/acl/AnnotateTransaction.cc index ff758c9918..a1d37488bc 100644 --- a/src/acl/AnnotateTransaction.cc +++ b/src/acl/AnnotateTransaction.cc @@ -9,27 +9,19 @@ #include "squid.h" #include "acl/AnnotateTransaction.h" #include "acl/AnnotationData.h" -#include "acl/Checklist.h" +#include "acl/FilledChecklist.h" #include "HttpRequest.h" #include "Notes.h" int -ACLAnnotateTransactionStrategy::match(ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &flags) +ACLAnnotateTransactionStrategy::match(ACLData * &data, ACLFilledChecklist *checklist) { if (const auto request = checklist->request) { ACLAnnotationData *tdata = dynamic_cast(data); assert(tdata); - tdata->annotate(request->notes(), flags.delimiters(), checklist->al); + tdata->annotate(request->notes(), &delimiters.value, checklist->al); return 1; } return 0; } -ACLAnnotateTransactionStrategy * -ACLAnnotateTransactionStrategy::Instance() -{ - return &Instance_; -} - -ACLAnnotateTransactionStrategy ACLAnnotateTransactionStrategy::Instance_; - diff --git a/src/acl/AnnotateTransaction.h b/src/acl/AnnotateTransaction.h index 441db54b42..c1da5fb556 100644 --- a/src/acl/AnnotateTransaction.h +++ b/src/acl/AnnotateTransaction.h @@ -9,31 +9,15 @@ #ifndef SQUID_ACLANNOTATETRANSACTION #define SQUID_ACLANNOTATETRANSACTION -#include "acl/Strategised.h" -#include "acl/Strategy.h" +#include "acl/Note.h" +#include "Notes.h" /// \ingroup ACLAPI -class ACLAnnotateTransactionStrategy : public ACLStrategy +class ACLAnnotateTransactionStrategy: public Acl::AnnotationStrategy { public: - virtual int match(ACLData * &, ACLFilledChecklist *, ACLFlags &); + virtual int match(ACLData * &, ACLFilledChecklist *); virtual bool requiresRequest() const { return true; } - - static ACLAnnotateTransactionStrategy *Instance(); - ACLAnnotateTransactionStrategy(ACLAnnotateTransactionStrategy const &) = delete; - ACLAnnotateTransactionStrategy& operator=(ACLAnnotateTransactionStrategy const &) = delete; - -private: - static ACLAnnotateTransactionStrategy Instance_; - ACLAnnotateTransactionStrategy() {} -}; - -/// \ingroup ACLAPI -class ACLAnnotateTransaction -{ -private: - static ACL::Prototype RegistryProtoype; - static ACLStrategised RegistryEntry_; }; #endif /* SQUID_ACLANNOTATETRANSACTION */ diff --git a/src/acl/AnyOf.h b/src/acl/AnyOf.h index f5fc86e7bd..e90b95da72 100644 --- a/src/acl/AnyOf.h +++ b/src/acl/AnyOf.h @@ -24,10 +24,6 @@ public: virtual char const *typeString() const; virtual ACL *clone() const; virtual void parse(); - -private: - static Prototype RegistryProtoype; - static AnyOf RegistryEntry_; }; } // namespace Acl diff --git a/src/acl/Arp.h b/src/acl/Arp.h index a7d7ace3a2..dd345d4276 100644 --- a/src/acl/Arp.h +++ b/src/acl/Arp.h @@ -10,7 +10,6 @@ #define SQUID_ACLARP_H #include "acl/Acl.h" -#include "acl/Checklist.h" #include @@ -38,8 +37,6 @@ public: virtual bool empty () const; protected: - static Prototype RegistryProtoype; - static ACLARP RegistryEntry_; char const *class_; typedef std::set AclArpData_t; AclArpData_t aclArpData; diff --git a/src/acl/Asn.cc b/src/acl/Asn.cc index 300107ff89..5707ea1ac8 100644 --- a/src/acl/Asn.cc +++ b/src/acl/Asn.cc @@ -15,6 +15,7 @@ #include "acl/DestinationAsn.h" #include "acl/DestinationIp.h" #include "acl/SourceAsn.h" +#include "acl/Strategised.h" #include "FwdState.h" #include "HttpReply.h" #include "HttpRequest.h" @@ -577,30 +578,14 @@ ACLASN::clone() const template class ACLStrategised; -ACL::Prototype ACLASN::SourceRegistryProtoype(&ACLASN::SourceRegistryEntry_, "src_as"); - -ACLStrategised ACLASN::SourceRegistryEntry_(new ACLASN, ACLSourceASNStrategy::Instance(), "src_as"); - -ACL::Prototype ACLASN::DestinationRegistryProtoype(&ACLASN::DestinationRegistryEntry_, "dst_as"); - -ACLStrategised ACLASN::DestinationRegistryEntry_(new ACLASN, ACLDestinationASNStrategy::Instance(), "dst_as"); - int -ACLSourceASNStrategy::match (ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &) +ACLSourceASNStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) { return data->match(checklist->src_addr); } -ACLSourceASNStrategy * -ACLSourceASNStrategy::Instance() -{ - return &Instance_; -} - -ACLSourceASNStrategy ACLSourceASNStrategy::Instance_; - int -ACLDestinationASNStrategy::match (ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &) +ACLDestinationASNStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) { const ipcache_addrs *ia = ipcache_gethostbyname(checklist->request->url.host(), IP_LOOKUP_IF_MISS); @@ -624,11 +609,3 @@ ACLDestinationASNStrategy::match (ACLData * &data, ACLFilledChecklist return data->match(noaddr); } -ACLDestinationASNStrategy * -ACLDestinationASNStrategy::Instance() -{ - return &Instance_; -} - -ACLDestinationASNStrategy ACLDestinationASNStrategy::Instance_; - diff --git a/src/acl/Asn.h b/src/acl/Asn.h index c2674c9846..1093de58c9 100644 --- a/src/acl/Asn.h +++ b/src/acl/Asn.h @@ -9,9 +9,7 @@ #ifndef SQUID_ACLASN_H #define SQUID_ACLASN_H -#include "acl/Checklist.h" #include "acl/Data.h" -#include "acl/Strategised.h" #include "base/CbDataList.h" #include "ip/Address.h" @@ -40,10 +38,6 @@ public: virtual void prepareForUse(); private: - static ACL::Prototype SourceRegistryProtoype; - static ACLStrategised SourceRegistryEntry_; - static ACL::Prototype DestinationRegistryProtoype; - static ACLStrategised DestinationRegistryEntry_; CbDataList *data; }; diff --git a/src/acl/AtStep.cc b/src/acl/AtStep.cc index 89ec6633ca..dad464e2d9 100644 --- a/src/acl/AtStep.cc +++ b/src/acl/AtStep.cc @@ -12,13 +12,13 @@ #include "acl/AtStep.h" #include "acl/AtStepData.h" -#include "acl/Checklist.h" +#include "acl/FilledChecklist.h" #include "client_side.h" #include "http/Stream.h" #include "ssl/ServerBump.h" int -ACLAtStepStrategy::match (ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &) +ACLAtStepStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) { Ssl::ServerBump *bump = NULL; if (checklist->conn() != NULL && (bump = checklist->conn()->serverBump())) @@ -28,13 +28,5 @@ ACLAtStepStrategy::match (ACLData * &data, ACLFilledChecklist *ch return 0; } -ACLAtStepStrategy * -ACLAtStepStrategy::Instance() -{ - return &Instance_; -} - -ACLAtStepStrategy ACLAtStepStrategy::Instance_; - #endif /* USE_OPENSSL */ diff --git a/src/acl/AtStep.h b/src/acl/AtStep.h index 6b077ba17d..25f5440f2e 100644 --- a/src/acl/AtStep.h +++ b/src/acl/AtStep.h @@ -11,7 +11,6 @@ #if USE_OPENSSL -#include "acl/Strategised.h" #include "acl/Strategy.h" #include "ssl/support.h" @@ -20,25 +19,7 @@ class ACLAtStepStrategy : public ACLStrategy { public: - virtual int match (ACLData * &, ACLFilledChecklist *, ACLFlags &); - static ACLAtStepStrategy *Instance(); - - // Not implemented to prevent copies of the instance. - ACLAtStepStrategy(ACLAtStepStrategy const &); - -private: - static ACLAtStepStrategy Instance_; - ACLAtStepStrategy() {} - - ACLAtStepStrategy&operator=(ACLAtStepStrategy const &); -}; - -class ACLAtStep -{ - -private: - static ACL::Prototype RegistryProtoype; - static ACLStrategised RegistryEntry_; + virtual int match (ACLData * &, ACLFilledChecklist *) override; }; #endif /* USE_OPENSSL */ diff --git a/src/acl/BoolOps.cc b/src/acl/BoolOps.cc index ff1dfb227c..661f9318b1 100644 --- a/src/acl/BoolOps.cc +++ b/src/acl/BoolOps.cc @@ -10,6 +10,7 @@ #include "acl/BoolOps.h" #include "acl/Checklist.h" #include "Debug.h" +#include "sbuf/SBuf.h" /* Acl::NotNode */ diff --git a/src/acl/Browser.cc b/src/acl/Browser.cc deleted file mode 100644 index e777acfeea..0000000000 --- a/src/acl/Browser.cc +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (C) 1996-2017 The Squid Software Foundation and contributors - * - * Squid software is distributed under GPLv2+ license and includes - * contributions from numerous individuals and organizations. - * Please see the COPYING and CONTRIBUTORS files for details. - */ - -/* DEBUG: section 28 Access Control */ - -#include "squid.h" -#include "acl/Browser.h" -#include "acl/Checklist.h" -#include "acl/RegexData.h" - -/* explicit template instantiation required for some systems */ - -template class ACLRequestHeaderStrategy; - diff --git a/src/acl/Browser.h b/src/acl/Browser.h deleted file mode 100644 index ac3c337bf0..0000000000 --- a/src/acl/Browser.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (C) 1996-2017 The Squid Software Foundation and contributors - * - * Squid software is distributed under GPLv2+ license and includes - * contributions from numerous individuals and organizations. - * Please see the COPYING and CONTRIBUTORS files for details. - */ - -#ifndef SQUID_ACLBROWSER_H -#define SQUID_ACLBROWSER_H - -#include "acl/Acl.h" -#include "acl/Data.h" -#include "acl/RequestHeaderStrategy.h" -#include "acl/Strategised.h" - -/// \ingroup ACLAPI -class ACLBrowser -{ - -private: - static ACL::Prototype RegistryProtoype; - static ACLStrategised RegistryEntry_; -}; - -#endif /* SQUID_ACLBROWSER_H */ - diff --git a/src/acl/Certificate.cc b/src/acl/Certificate.cc index 26ed5c3688..fd693e2c06 100644 --- a/src/acl/Certificate.cc +++ b/src/acl/Certificate.cc @@ -25,7 +25,7 @@ #include "HttpRequest.h" int -ACLCertificateStrategy::match (ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &) +ACLCertificateStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) { const int fd = checklist->fd(); const bool goodDescriptor = 0 <= fd && fd <= Biggest_FD; @@ -36,13 +36,5 @@ ACLCertificateStrategy::match (ACLData * &data, ACLFilledChecklist *c return res; } -ACLCertificateStrategy * -ACLCertificateStrategy::Instance() -{ - return &Instance_; -} - -ACLCertificateStrategy ACLCertificateStrategy::Instance_; - #endif /* USE_OPENSSL */ diff --git a/src/acl/Certificate.h b/src/acl/Certificate.h index 9d29f0b710..322d80f96f 100644 --- a/src/acl/Certificate.h +++ b/src/acl/Certificate.h @@ -20,29 +20,7 @@ class ACLCertificateStrategy : public ACLStrategy { public: - virtual int match (ACLData * &, ACLFilledChecklist *, ACLFlags &); - static ACLCertificateStrategy *Instance(); - /* Not implemented to prevent copies of the instance. */ - /* Not private to prevent brain dead g+++ warnings about - * private constructors with no friends */ - ACLCertificateStrategy(ACLCertificateStrategy const &); - -private: - static ACLCertificateStrategy Instance_; - ACLCertificateStrategy() {} - - ACLCertificateStrategy&operator=(ACLCertificateStrategy const &); -}; - -/// \ingroup ACLAPI -class ACLCertificate -{ - -private: - static ACL::Prototype UserRegistryProtoype; - static ACLStrategised UserRegistryEntry_; - static ACL::Prototype CARegistryProtoype; - static ACLStrategised CARegistryEntry_; + virtual int match (ACLData * &, ACLFilledChecklist *); }; #endif /* SQUID_ACLCERTIFICATE_H */ diff --git a/src/acl/CharacterSetOption.h b/src/acl/CharacterSetOption.h new file mode 100644 index 0000000000..cfeafa0dee --- /dev/null +++ b/src/acl/CharacterSetOption.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 1996-2017 The Squid Software Foundation and contributors + * + * Squid software is distributed under GPLv2+ license and includes + * contributions from numerous individuals and organizations. + * Please see the COPYING and CONTRIBUTORS files for details. + */ + +#ifndef SQUID_ACL_CHARACTER_SET_OPTION_H +#define SQUID_ACL_CHARACTER_SET_OPTION_H + +#include "acl/Options.h" +#include "base/CharacterSet.h" +#include "sbuf/SBuf.h" + +namespace Acl { + +typedef OptionValue CharacterSetOptionValue; + +/* TypedOption specializations */ + +template <> +inline +void +TypedOption::import(const SBuf &rawValue) const +{ + SBuf chars = rawValue; // because c_str() is not constant + recipient_->value = CharacterSet(__FILE__, chars.c_str()); +} + +template <> +inline +void +TypedOption::print(std::ostream &os) const +{ + recipient_->value.printChars(os); // TODO: Quote if needed. +} + +/// option value to configure one or more characters (e.g., -m=",;") +class CharacterSetOption: public TypedOption +{ +public: + typedef TypedOption Parent; + CharacterSetOption(): Parent(valueOptional) {} +}; + +} // namespace Acl + +#endif /* SQUID_ACL_CHARACTER_SET_OPTION_H */ + diff --git a/src/acl/ConnectionsEncrypted.h b/src/acl/ConnectionsEncrypted.h index 0df050839e..7684de471b 100644 --- a/src/acl/ConnectionsEncrypted.h +++ b/src/acl/ConnectionsEncrypted.h @@ -33,8 +33,6 @@ public: virtual bool empty () const; protected: - static Prototype RegistryProtoype; - static ConnectionsEncrypted RegistryEntry_; char const *class_; }; diff --git a/src/acl/Data.h b/src/acl/Data.h index 1276173355..88a8afa77f 100644 --- a/src/acl/Data.h +++ b/src/acl/Data.h @@ -9,9 +9,10 @@ #ifndef SQUID_ACLDATA_H #define SQUID_ACLDATA_H +#include "acl/Options.h" #include "sbuf/List.h" -/// \ingroup ACLAPI +/// Configured ACL parameter(s) (e.g., domain names in dstdomain ACL). template class ACLData { @@ -20,6 +21,9 @@ public: virtual ~ACLData() {} + /// \returns the flags supported by these ACL parameters (e.g., "-i") + virtual const Acl::ParameterFlags &supportedFlags() const { return Acl::NoFlags(); } + virtual bool match(M) =0; virtual SBufList dump() const =0; virtual void parse() =0; diff --git a/src/acl/DestinationAsn.h b/src/acl/DestinationAsn.h index e5a6207066..350ff8e959 100644 --- a/src/acl/DestinationAsn.h +++ b/src/acl/DestinationAsn.h @@ -18,24 +18,8 @@ class ACLDestinationASNStrategy : public ACLStrategy { public: - virtual int match (ACLData * &, ACLFilledChecklist *, ACLFlags &); + virtual int match (ACLData * &, ACLFilledChecklist *); virtual bool requiresRequest() const {return true;} - - static ACLDestinationASNStrategy *Instance(); - - /** - * Not implemented to prevent copies of the instance. - \par - * Not private to prevent brain dead g++ warnings about - * private constructors with no friends - */ - ACLDestinationASNStrategy(ACLDestinationASNStrategy const &); - -private: - static ACLDestinationASNStrategy Instance_; - ACLDestinationASNStrategy() {} - - ACLDestinationASNStrategy&operator=(ACLDestinationASNStrategy const &); }; #endif /* SQUID_ACLDESTINATIONASN_H */ diff --git a/src/acl/DestinationDomain.cc b/src/acl/DestinationDomain.cc index 2b6a06842c..cf95988fc8 100644 --- a/src/acl/DestinationDomain.cc +++ b/src/acl/DestinationDomain.cc @@ -41,8 +41,19 @@ DestinationDomainLookup::LookupDone(const char *, const Dns::LookupDetails &deta checklist->resumeNonBlockingCheck(DestinationDomainLookup::Instance()); } +/* ACLDestinationDomainStrategy */ + +const Acl::Options & +ACLDestinationDomainStrategy::options() +{ + static const Acl::BooleanOption LookupBanFlag; + static const Acl::Options MyOptions = { { "-n", &LookupBanFlag } }; + LookupBanFlag.linkWith(&lookupBanned); + return MyOptions; +} + int -ACLDestinationDomainStrategy::match (ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &flags) +ACLDestinationDomainStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) { assert(checklist != NULL && checklist->request != NULL); @@ -50,7 +61,7 @@ ACLDestinationDomainStrategy::match (ACLData * &data, ACLFilledCheckl return 1; } - if (flags.isSet(ACL_F_NO_LOOKUP)) { + if (lookupBanned) { debugs(28, 3, "No-lookup DNS ACL '" << AclMatchedName << "' for " << checklist->request->url.host()); return 0; } @@ -91,11 +102,3 @@ ACLDestinationDomainStrategy::match (ACLData * &data, ACLFilledCheckl return data->match("none"); } -ACLDestinationDomainStrategy * -ACLDestinationDomainStrategy::Instance() -{ - return &Instance_; -} - -ACLDestinationDomainStrategy ACLDestinationDomainStrategy::Instance_; - diff --git a/src/acl/DestinationDomain.h b/src/acl/DestinationDomain.h index 5e2485cb5d..2c12abdb2a 100644 --- a/src/acl/DestinationDomain.h +++ b/src/acl/DestinationDomain.h @@ -20,23 +20,13 @@ class ACLDestinationDomainStrategy : public ACLStrategy { public: - virtual int match (ACLData * &, ACLFilledChecklist *, ACLFlags &); - static ACLDestinationDomainStrategy *Instance(); + /* ACLStrategy API */ + virtual int match (ACLData * &, ACLFilledChecklist *); virtual bool requiresRequest() const {return true;} - - /** - * Not implemented to prevent copies of the instance. - \par - * Not private to prevent brain dead g+++ warnings about - * private constructors with no friends - */ - ACLDestinationDomainStrategy(ACLDestinationDomainStrategy const &); + virtual const Acl::Options &options(); private: - static ACLDestinationDomainStrategy Instance_; - ACLDestinationDomainStrategy() {} - - ACLDestinationDomainStrategy&operator=(ACLDestinationDomainStrategy const &); + Acl::BooleanOptionValue lookupBanned; ///< Are DNS lookups allowed? }; /// \ingroup ACLAPI @@ -52,16 +42,5 @@ private: static void LookupDone(const char *, const Dns::LookupDetails &, void *); }; -/// \ingroup ACLAPI -class ACLDestinationDomain -{ - -private: - static ACL::Prototype LiteralRegistryProtoype; - static ACLStrategised LiteralRegistryEntry_; - static ACL::Prototype RegexRegistryProtoype; - static ACLStrategised RegexRegistryEntry_; -}; - #endif /* SQUID_ACLDESTINATIONDOMAIN_H */ diff --git a/src/acl/DestinationIp.cc b/src/acl/DestinationIp.cc index 9cfbc14f03..13262eb6e3 100644 --- a/src/acl/DestinationIp.cc +++ b/src/acl/DestinationIp.cc @@ -17,14 +17,21 @@ #include "HttpRequest.h" #include "SquidConfig.h" -ACLFlag ACLDestinationIP::SupportedFlags[] = {ACL_F_NO_LOOKUP, ACL_F_END}; - char const * ACLDestinationIP::typeString() const { return "dst"; } +const Acl::Options & +ACLDestinationIP::options() +{ + static const Acl::BooleanOption LookupBan; + static const Acl::Options MyOptions = { { "-n", &LookupBan } }; + LookupBan.linkWith(&lookupBanned); + return MyOptions; +} + int ACLDestinationIP::match(ACLChecklist *cl) { @@ -44,7 +51,7 @@ ACLDestinationIP::match(ACLChecklist *cl) ACLIP::match(conn->clientConnection->local) : -1; } - if (flags.isSet(ACL_F_NO_LOOKUP)) { + if (lookupBanned) { if (!checklist->request->url.hostIsNumeric()) { debugs(28, 3, "No-lookup DNS ACL '" << AclMatchedName << "' for " << checklist->request->url.host()); return 0; diff --git a/src/acl/DestinationIp.h b/src/acl/DestinationIp.h index 9d0eaeaefb..a6747a6d70 100644 --- a/src/acl/DestinationIp.h +++ b/src/acl/DestinationIp.h @@ -30,16 +30,14 @@ class ACLDestinationIP : public ACLIP MEMPROXY_CLASS(ACLDestinationIP); public: - ACLDestinationIP(): ACLIP(ACLDestinationIP::SupportedFlags) {} virtual char const *typeString() const; + virtual const Acl::Options &options(); virtual int match(ACLChecklist *checklist); virtual ACL *clone()const; - static ACLFlag SupportedFlags[]; private: - static Prototype RegistryProtoype; - static ACLDestinationIP RegistryEntry_; + Acl::BooleanOptionValue lookupBanned; ///< are DNS lookups allowed? }; #endif /* SQUID_ACLDESTINATIONIP_H */ diff --git a/src/acl/Eui64.h b/src/acl/Eui64.h index 01dc10a17d..fd3e0bf736 100644 --- a/src/acl/Eui64.h +++ b/src/acl/Eui64.h @@ -10,7 +10,6 @@ #define SQUID_ACLEUI64_H #include "acl/Acl.h" -#include "acl/Checklist.h" #include @@ -37,8 +36,6 @@ public: virtual bool empty () const; protected: - static Prototype RegistryProtoype; - static ACLEui64 RegistryEntry_; typedef std::set Eui64Data_t; Eui64Data_t eui64Data; char const *class_; diff --git a/src/acl/ExtUser.cc b/src/acl/ExtUser.cc index 973d7f1233..f2a15f68bc 100644 --- a/src/acl/ExtUser.cc +++ b/src/acl/ExtUser.cc @@ -43,6 +43,12 @@ ACLExtUser::typeString() const return type_; } +void +ACLExtUser::parseFlags() +{ + ParseFlags(Acl::NoOptions(), data->supportedFlags()); +} + void ACLExtUser::parse() { diff --git a/src/acl/ExtUser.h b/src/acl/ExtUser.h index f6cdb84469..6d1e228292 100644 --- a/src/acl/ExtUser.h +++ b/src/acl/ExtUser.h @@ -25,19 +25,16 @@ public: ACLExtUser & operator= (ACLExtUser const &rhs); ~ACLExtUser(); + /* ACL API */ virtual char const *typeString() const; virtual void parse(); - + virtual void parseFlags(); virtual int match(ACLChecklist *checklist); virtual SBufList dump() const; virtual bool empty () const; virtual ACL *clone()const; private: - static Prototype UserRegistryProtoype; - static ACLExtUser UserRegistryEntry_; - static Prototype RegexRegistryProtoype; - static ACLExtUser RegexRegistryEntry_; ACLData *data; char const *type_; }; diff --git a/src/acl/HasComponent.cc b/src/acl/HasComponent.cc index 1b0d4dd1b4..221a093480 100644 --- a/src/acl/HasComponent.cc +++ b/src/acl/HasComponent.cc @@ -11,18 +11,9 @@ #include "acl/HasComponentData.h" int -ACLHasComponentStrategy::match(ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &flags) +ACLHasComponentStrategy::match(ACLData * &data, ACLFilledChecklist *checklist) { ACLHasComponentData *cdata = dynamic_cast(data); assert(cdata); return cdata->match(checklist); } - -ACLHasComponentStrategy * -ACLHasComponentStrategy::Instance() -{ - return &Instance_; -} - -ACLHasComponentStrategy ACLHasComponentStrategy::Instance_; - diff --git a/src/acl/HasComponent.h b/src/acl/HasComponent.h index 3aba6cdda8..8fddc47c95 100644 --- a/src/acl/HasComponent.h +++ b/src/acl/HasComponent.h @@ -16,22 +16,7 @@ class ACLHasComponentStrategy : public ACLStrategy { public: - static ACLHasComponentStrategy *Instance(); - ACLHasComponentStrategy(ACLHasComponentStrategy const &) = delete; - ACLHasComponentStrategy& operator=(ACLHasComponentStrategy const &) = delete; - virtual int match(ACLData * &, ACLFilledChecklist *, ACLFlags &); - -private: - static ACLHasComponentStrategy Instance_; - ACLHasComponentStrategy() { } -}; - -/// \ingroup ACLAPI -class ACLHasComponent -{ -private: - static ACL::Prototype RegistryProtoype; - static ACLStrategised RegistryEntry_; + virtual int match(ACLData * &, ACLFilledChecklist *); }; #endif diff --git a/src/acl/HierCode.cc b/src/acl/HierCode.cc index b56465362b..326a7b36f2 100644 --- a/src/acl/HierCode.cc +++ b/src/acl/HierCode.cc @@ -10,6 +10,7 @@ #include "acl/Checklist.h" #include "acl/HierCode.h" #include "acl/HierCodeData.h" +#include "acl/Strategised.h" #include "HttpRequest.h" /* explicit template instantiation required for some systems */ @@ -17,16 +18,8 @@ template class ACLStrategised; int -ACLHierCodeStrategy::match (ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &) +ACLHierCodeStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) { return data->match (checklist->request->hier.code); } -ACLHierCodeStrategy * -ACLHierCodeStrategy::Instance() -{ - return &Instance_; -} - -ACLHierCodeStrategy ACLHierCodeStrategy::Instance_; - diff --git a/src/acl/HierCode.h b/src/acl/HierCode.h index 0d513d07be..d501a76a36 100644 --- a/src/acl/HierCode.h +++ b/src/acl/HierCode.h @@ -9,7 +9,6 @@ #ifndef SQUID_ACLHIERCODE_H #define SQUID_ACLHIERCODE_H -#include "acl/Strategised.h" #include "acl/Strategy.h" #include "hier_code.h" @@ -18,33 +17,8 @@ class ACLHierCodeStrategy : public ACLStrategy { public: - virtual int match (ACLData * &, ACLFilledChecklist *, ACLFlags &); + virtual int match (ACLData * &, ACLFilledChecklist *); virtual bool requiresRequest() const {return true;} - - static ACLHierCodeStrategy *Instance(); - - /** - * Not implemented to prevent copies of the instance. - \par - * Not private to prevent brain dead g+++ warnings about - * private constructors with no friends - */ - ACLHierCodeStrategy(ACLHierCodeStrategy const &); - -private: - static ACLHierCodeStrategy Instance_; - ACLHierCodeStrategy() {} - - ACLHierCodeStrategy &operator=(ACLHierCodeStrategy const &); -}; - -/// \ingroup ACLAPI -class ACLHierCode -{ - -private: - static ACL::Prototype RegistryProtoype; - static ACLStrategised RegistryEntry_; }; #endif /* SQUID_ACLHIERCODE_H */ diff --git a/src/acl/HttpRepHeader.cc b/src/acl/HttpRepHeader.cc index bfad171e68..4d492c7c2e 100644 --- a/src/acl/HttpRepHeader.cc +++ b/src/acl/HttpRepHeader.cc @@ -7,22 +7,14 @@ */ #include "squid.h" -#include "acl/Checklist.h" +#include "acl/FilledChecklist.h" #include "acl/HttpHeaderData.h" #include "acl/HttpRepHeader.h" #include "HttpReply.h" int -ACLHTTPRepHeaderStrategy::match (ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &) +ACLHTTPRepHeaderStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) { return data->match (&checklist->reply->header); } -ACLHTTPRepHeaderStrategy * -ACLHTTPRepHeaderStrategy::Instance() -{ - return &Instance_; -} - -ACLHTTPRepHeaderStrategy ACLHTTPRepHeaderStrategy::Instance_; - diff --git a/src/acl/HttpRepHeader.h b/src/acl/HttpRepHeader.h index 71e2a7dafc..dc417c15b4 100644 --- a/src/acl/HttpRepHeader.h +++ b/src/acl/HttpRepHeader.h @@ -18,32 +18,8 @@ class ACLHTTPRepHeaderStrategy : public ACLStrategy { public: - virtual int match (ACLData * &, ACLFilledChecklist *, ACLFlags &); + virtual int match (ACLData * &, ACLFilledChecklist *); virtual bool requiresReply() const { return true; } - - static ACLHTTPRepHeaderStrategy *Instance(); - /** - * Not implemented to prevent copies of the instance. - \par - * Not private to prevent brain dead g+++ warnings about - * private constructors with no friends - */ - ACLHTTPRepHeaderStrategy(ACLHTTPRepHeaderStrategy const &); - -private: - static ACLHTTPRepHeaderStrategy Instance_; - ACLHTTPRepHeaderStrategy() { } - - ACLHTTPRepHeaderStrategy&operator = (ACLHTTPRepHeaderStrategy const &); -}; - -/// \ingroup ACLAPI -class ACLHTTPRepHeader -{ - -private: - static ACL::Prototype RegistryProtoype; - static ACLStrategised RegistryEntry_; }; #endif /* SQUID_ACLHTTPREPHEADER_H */ diff --git a/src/acl/HttpReqHeader.cc b/src/acl/HttpReqHeader.cc index e481f8fcc5..7a808e952e 100644 --- a/src/acl/HttpReqHeader.cc +++ b/src/acl/HttpReqHeader.cc @@ -7,22 +7,14 @@ */ #include "squid.h" -#include "acl/Checklist.h" +#include "acl/FilledChecklist.h" #include "acl/HttpHeaderData.h" #include "acl/HttpReqHeader.h" #include "HttpRequest.h" int -ACLHTTPReqHeaderStrategy::match (ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &) +ACLHTTPReqHeaderStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) { return data->match (&checklist->request->header); } -ACLHTTPReqHeaderStrategy * -ACLHTTPReqHeaderStrategy::Instance() -{ - return &Instance_; -} - -ACLHTTPReqHeaderStrategy ACLHTTPReqHeaderStrategy::Instance_; - diff --git a/src/acl/HttpReqHeader.h b/src/acl/HttpReqHeader.h index 5be681db68..def941227f 100644 --- a/src/acl/HttpReqHeader.h +++ b/src/acl/HttpReqHeader.h @@ -9,7 +9,6 @@ #ifndef SQUID_ACLHTTPREQHEADER_H #define SQUID_ACLHTTPREQHEADER_H -#include "acl/Strategised.h" #include "acl/Strategy.h" #include "HttpHeader.h" @@ -18,29 +17,8 @@ class ACLHTTPReqHeaderStrategy : public ACLStrategy { public: - virtual int match (ACLData * &, ACLFilledChecklist *, ACLFlags &); + virtual int match (ACLData * &, ACLFilledChecklist *); virtual bool requiresRequest() const { return true; } - - static ACLHTTPReqHeaderStrategy *Instance(); - /* Not implemented to prevent copies of the instance. */ - /* Not private to prevent brain dead g+++ warnings about - * private constructors with no friends */ - ACLHTTPReqHeaderStrategy(ACLHTTPReqHeaderStrategy const &); - -private: - static ACLHTTPReqHeaderStrategy Instance_; - ACLHTTPReqHeaderStrategy() { } - - ACLHTTPReqHeaderStrategy&operator = (ACLHTTPReqHeaderStrategy const &); -}; - -/// \ingroup ACLAPI -class ACLHTTPReqHeader -{ - -private: - static ACL::Prototype RegistryProtoype; - static ACLStrategised RegistryEntry_; }; #endif /* SQUID_ACLHTTPREQHEADER_H */ diff --git a/src/acl/HttpStatus.h b/src/acl/HttpStatus.h index b5d6b07b52..836bedec03 100644 --- a/src/acl/HttpStatus.h +++ b/src/acl/HttpStatus.h @@ -43,8 +43,6 @@ public: virtual bool requiresReply() const { return true; } protected: - static Prototype RegistryProtoype; - static ACLHTTPStatus RegistryEntry_; Splay *data; char const *class_; }; diff --git a/src/acl/Ip.cc b/src/acl/Ip.cc index 2f23d53a52..53194f9a31 100644 --- a/src/acl/Ip.cc +++ b/src/acl/Ip.cc @@ -477,8 +477,6 @@ ACLIP::parse() if (data == NULL) data = new IPSplay(); - flags.parseFlags(); - while (char *t = ConfigParser::strtokFile()) { acl_ip_data *q = acl_ip_data::FactoryParse(t); diff --git a/src/acl/Ip.h b/src/acl/Ip.h index 7a93bf1e81..6f48915f9b 100644 --- a/src/acl/Ip.h +++ b/src/acl/Ip.h @@ -48,8 +48,6 @@ public: void operator delete(void *); ACLIP() : data(NULL) {} - explicit ACLIP(const ACLFlag flgs[]) : ACL(flgs), data(NULL) {} - ~ACLIP(); typedef Splay IPSplay; diff --git a/src/acl/LocalIp.h b/src/acl/LocalIp.h index af71364dc7..bfccbd3cf5 100644 --- a/src/acl/LocalIp.h +++ b/src/acl/LocalIp.h @@ -17,15 +17,9 @@ class ACLLocalIP : public ACLIP MEMPROXY_CLASS(ACLLocalIP); public: - static ACLLocalIP const &RegistryEntry(); - virtual char const *typeString() const; virtual int match(ACLChecklist *checklist); virtual ACL *clone()const; - -private: - static Prototype RegistryProtoype; - static ACLLocalIP RegistryEntry_; }; #endif /* SQUID_ACLLOCALIP_H */ diff --git a/src/acl/LocalPort.cc b/src/acl/LocalPort.cc index 5c947619a8..dc0aa23a67 100644 --- a/src/acl/LocalPort.cc +++ b/src/acl/LocalPort.cc @@ -7,21 +7,12 @@ */ #include "squid.h" -#include "acl/Checklist.h" -#include "acl/IntRange.h" +#include "acl/FilledChecklist.h" #include "acl/LocalPort.h" int -ACLLocalPortStrategy::match (ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &) +ACLLocalPortStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) { return data->match (checklist->my_addr.port()); } -ACLLocalPortStrategy * -ACLLocalPortStrategy::Instance() -{ - return &Instance_; -} - -ACLLocalPortStrategy ACLLocalPortStrategy::Instance_; - diff --git a/src/acl/LocalPort.h b/src/acl/LocalPort.h index 2d9242de8f..cf07dafc65 100644 --- a/src/acl/LocalPort.h +++ b/src/acl/LocalPort.h @@ -9,7 +9,6 @@ #ifndef SQUID_ACLLOCALPORT_H #define SQUID_ACLLOCALPORT_H -#include "acl/Strategised.h" #include "acl/Strategy.h" /// \ingroup ACLAPI @@ -17,30 +16,7 @@ class ACLLocalPortStrategy : public ACLStrategy { public: - virtual int match (ACLData * &, ACLFilledChecklist *, ACLFlags &); - static ACLLocalPortStrategy *Instance(); - /** - * Not implemented to prevent copies of the instance. - \par - * Not private to prevent brain dead g+++ warnings about - * private constructors with no friends - */ - ACLLocalPortStrategy(ACLLocalPortStrategy const &); - -private: - static ACLLocalPortStrategy Instance_; - ACLLocalPortStrategy() {} - - ACLLocalPortStrategy&operator=(ACLLocalPortStrategy const &); -}; - -/// \ingroup ACLAPI -class ACLLocalPort -{ - -private: - static ACL::Prototype RegistryProtoype; - static ACLStrategised RegistryEntry_; + virtual int match (ACLData * &, ACLFilledChecklist *) override; }; #endif /* SQUID_ACLLOCALPORT_H */ diff --git a/src/acl/Makefile.am b/src/acl/Makefile.am index 133ba56cba..98804b9e44 100644 --- a/src/acl/Makefile.am +++ b/src/acl/Makefile.am @@ -23,12 +23,15 @@ libapi_la_SOURCES = \ forward.h \ InnerNode.cc \ InnerNode.h \ + Options.h \ + Options.cc \ Tree.cc \ Tree.h ## Data-dependent Squid/transaction state used by specific ACLs. ## Does not refer to specific ACLs to avoid circular dependencies. libstate_la_SOURCES = \ + CharacterSetOption.h \ Data.h \ Strategy.h \ Strategised.cc \ @@ -62,8 +65,6 @@ libacls_la_SOURCES = \ AnyOf.h \ Asn.cc \ Asn.h \ - Browser.cc \ - Browser.h \ ConnectionsEncrypted.cc \ ConnectionsEncrypted.h \ DestinationAsn.h \ @@ -117,13 +118,9 @@ libacls_la_SOURCES = \ Protocol.h \ Random.cc \ Random.h \ - Referer.cc \ - Referer.h \ ReplyHeaderStrategy.h \ - ReplyMimeType.cc \ ReplyMimeType.h \ RequestHeaderStrategy.h \ - RequestMimeType.cc \ RequestMimeType.h \ SourceAsn.h \ SourceDomain.cc \ diff --git a/src/acl/MaxConnection.h b/src/acl/MaxConnection.h index 78d267362e..8dbcdf0720 100644 --- a/src/acl/MaxConnection.h +++ b/src/acl/MaxConnection.h @@ -10,7 +10,6 @@ #define SQUID_ACLMAXCONNECTION_H #include "acl/Acl.h" -#include "acl/Checklist.h" /// \ingroup ACLAPI class ACLMaxConnection : public ACL @@ -33,8 +32,6 @@ public: virtual void prepareForUse(); protected: - static Prototype RegistryProtoype; - static ACLMaxConnection RegistryEntry_; char const *class_; int limit; }; diff --git a/src/acl/Method.cc b/src/acl/Method.cc index b8040e3796..dfb619f658 100644 --- a/src/acl/Method.cc +++ b/src/acl/Method.cc @@ -7,9 +7,10 @@ */ #include "squid.h" -#include "acl/Checklist.h" +#include "acl/FilledChecklist.h" #include "acl/Method.h" #include "acl/MethodData.h" +#include "acl/Strategised.h" #include "HttpRequest.h" /* explicit template instantiation required for some systems */ @@ -17,16 +18,8 @@ template class ACLStrategised; int -ACLMethodStrategy::match (ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &) +ACLMethodStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) { return data->match (checklist->request->method); } -ACLMethodStrategy * -ACLMethodStrategy::Instance() -{ - return &Instance_; -} - -ACLMethodStrategy ACLMethodStrategy::Instance_; - diff --git a/src/acl/Method.h b/src/acl/Method.h index 710019d221..37d13512ca 100644 --- a/src/acl/Method.h +++ b/src/acl/Method.h @@ -9,7 +9,6 @@ #ifndef SQUID_ACLMETHOD_H #define SQUID_ACLMETHOD_H -#include "acl/Strategised.h" #include "acl/Strategy.h" #include "http/RequestMethod.h" @@ -18,33 +17,8 @@ class ACLMethodStrategy : public ACLStrategy { public: - virtual int match (ACLData * &, ACLFilledChecklist *, ACLFlags &); + virtual int match (ACLData * &, ACLFilledChecklist *); virtual bool requiresRequest() const {return true;} - - static ACLMethodStrategy *Instance(); - - /** - * Not implemented to prevent copies of the instance. - \par - * Not private to prevent brain dead g+++ warnings about - * private constructors with no friends - */ - ACLMethodStrategy(ACLMethodStrategy const &); - -private: - static ACLMethodStrategy Instance_; - ACLMethodStrategy() {} - - ACLMethodStrategy&operator=(ACLMethodStrategy const &); -}; - -/// \ingroup ACLAPI -class ACLMethod -{ - -private: - static ACL::Prototype RegistryProtoype; - static ACLStrategised RegistryEntry_; }; #endif /* SQUID_ACLMETHOD_H */ diff --git a/src/acl/MyPortName.cc b/src/acl/MyPortName.cc index 9566d76bf5..2de70ca53c 100644 --- a/src/acl/MyPortName.cc +++ b/src/acl/MyPortName.cc @@ -7,7 +7,7 @@ */ #include "squid.h" -#include "acl/Checklist.h" +#include "acl/FilledChecklist.h" #include "acl/MyPortName.h" #include "acl/StringData.h" #include "anyp/PortCfg.h" @@ -16,7 +16,7 @@ #include "HttpRequest.h" int -ACLMyPortNameStrategy::match(ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &) +ACLMyPortNameStrategy::match(ACLData * &data, ACLFilledChecklist *checklist) { if (checklist->conn() != NULL && checklist->conn()->port != NULL) return data->match(checklist->conn()->port->name); @@ -25,11 +25,3 @@ ACLMyPortNameStrategy::match(ACLData * &data, ACLFilledChecklist *che return 0; } -ACLMyPortNameStrategy * -ACLMyPortNameStrategy::Instance() -{ - return &Instance_; -} - -ACLMyPortNameStrategy ACLMyPortNameStrategy::Instance_; - diff --git a/src/acl/MyPortName.h b/src/acl/MyPortName.h index 3c2429528f..e385055195 100644 --- a/src/acl/MyPortName.h +++ b/src/acl/MyPortName.h @@ -8,33 +8,13 @@ #ifndef SQUID_ACLMYPORTNAME_H #define SQUID_ACLMYPORTNAME_H -#include "acl/Strategised.h" #include "acl/Strategy.h" class ACLMyPortNameStrategy : public ACLStrategy { public: - virtual int match (ACLData * &, ACLFilledChecklist *, ACLFlags &); - static ACLMyPortNameStrategy *Instance(); - /* Not implemented to prevent copies of the instance. */ - /* Not private to prevent brain dead g+++ warnings about - * private constructors with no friends */ - ACLMyPortNameStrategy(ACLMyPortNameStrategy const &); - -private: - static ACLMyPortNameStrategy Instance_; - ACLMyPortNameStrategy() {} - - ACLMyPortNameStrategy&operator=(ACLMyPortNameStrategy const &); -}; - -class ACLMyPortName -{ - -private: - static ACL::Prototype RegistryProtoype; - static ACLStrategised RegistryEntry_; + virtual int match (ACLData * &, ACLFilledChecklist *) override; }; #endif /* SQUID_ACLMYPORTNAME_H */ diff --git a/src/acl/Note.cc b/src/acl/Note.cc index a58ed9504a..c27489e1cb 100644 --- a/src/acl/Note.cc +++ b/src/acl/Note.cc @@ -7,24 +7,36 @@ */ #include "squid.h" -#include "acl/Checklist.h" +#include "acl/FilledChecklist.h" #include "acl/HttpHeaderData.h" #include "acl/Note.h" #include "acl/NoteData.h" #include "HttpRequest.h" -#include "Notes.h" -#include "parser/Tokenizer.h" -#include "sbuf/StringConvert.h" + +/* Acl::AnnotationStrategy */ + +const Acl::Options & +Acl::AnnotationStrategy::options() +{ + static const Acl::CharacterSetOption Delimiters; + static const Acl::Options MyOptions = { + { "-m", &Delimiters } + }; + Delimiters.linkWith(&delimiters); + return MyOptions; +} + +/* ACLNoteStrategy */ int -ACLNoteStrategy::match(ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &flags) +ACLNoteStrategy::match(ACLData * &data, ACLFilledChecklist *checklist) { if (const auto request = checklist->request) { - if (request->hasNotes() && matchNotes(data, request->notes().getRaw(), flags.delimiters())) + if (request->hasNotes() && matchNotes(data, request->notes().getRaw())) return 1; #if USE_ADAPTATION const Adaptation::History::Pointer ah = request->adaptLogHistory(); - if (ah != NULL && ah->metaHeaders != NULL && matchNotes(data, ah->metaHeaders.getRaw(), flags.delimiters())) + if (ah != NULL && ah->metaHeaders != NULL && matchNotes(data, ah->metaHeaders.getRaw())) return 1; #endif } @@ -32,20 +44,12 @@ ACLNoteStrategy::match(ACLData * &data, ACLFilledChecklist *checklist } bool -ACLNoteStrategy::matchNotes(ACLData *noteData, const NotePairs *note, const CharacterSet *delimiters) const +ACLNoteStrategy::matchNotes(ACLData *noteData, const NotePairs *note) const { - const NotePairs::Entries &entries = note->expandListEntries(delimiters); + const NotePairs::Entries &entries = note->expandListEntries(&delimiters.value); for (auto e: entries) if (noteData->match(e.getRaw())) return true; return false; } -ACLNoteStrategy * -ACLNoteStrategy::Instance() -{ - return &Instance_; -} - -ACLNoteStrategy ACLNoteStrategy::Instance_; - diff --git a/src/acl/Note.h b/src/acl/Note.h index aa93ffe472..86fd1204cd 100644 --- a/src/acl/Note.h +++ b/src/acl/Note.h @@ -9,42 +9,36 @@ #ifndef SQUID_ACLNOTE_H #define SQUID_ACLNOTE_H -#include "acl/Strategised.h" +#include "acl/CharacterSetOption.h" +#include "acl/Data.h" #include "acl/Strategy.h" +#include "Notes.h" -class ACLNoteData; -class CharacterSet; -class HttpRequest; +namespace Acl { -/// \ingroup ACLAPI -class ACLNoteStrategy : public ACLStrategy +/// common parent of several ACLs dealing with transaction annotations +class AnnotationStrategy: public ACLStrategy { - public: - virtual int match (ACLData * &, ACLFilledChecklist *, ACLFlags &); - virtual bool requiresRequest() const { return true; } + AnnotationStrategy(): delimiters(CharacterSet(__FILE__, ",")) {} - static ACLNoteStrategy *Instance(); - /* Not implemented to prevent copies of the instance. */ - /* Not private to prevent brain dead g+++ warnings about - * private constructors with no friends */ - ACLNoteStrategy(ACLNoteStrategy const &); - -private: - static ACLNoteStrategy Instance_; - ACLNoteStrategy() { } + virtual const Acl::Options &options() override; - ACLNoteStrategy& operator = (ACLNoteStrategy const &); - bool matchNotes(ACLData *, const NotePairs *, const CharacterSet *) const; + Acl::CharacterSetOptionValue delimiters; ///< annotation separators }; +} // namespace Acl + /// \ingroup ACLAPI -class ACLNote +class ACLNoteStrategy: public Acl::AnnotationStrategy { +public: + virtual int match (ACLData * &, ACLFilledChecklist *); + virtual bool requiresRequest() const { return true; } + private: - static ACL::Prototype RegistryProtoype; - static ACLStrategised RegistryEntry_; + bool matchNotes(ACLData *, const NotePairs *) const; }; #endif /* SQUID_ACLNOTE_H */ diff --git a/src/acl/Options.cc b/src/acl/Options.cc new file mode 100644 index 0000000000..44d9e48467 --- /dev/null +++ b/src/acl/Options.cc @@ -0,0 +1,283 @@ +/* + * Copyright (C) 1996-2017 The Squid Software Foundation and contributors + * + * Squid software is distributed under GPLv2+ license and includes + * contributions from numerous individuals and organizations. + * Please see the COPYING and CONTRIBUTORS files for details. + */ + +#include "squid.h" +#include "acl/Options.h" +#include "ConfigParser.h" +#include "Debug.h" +#include "sbuf/Stream.h" + +#include +#include + +namespace Acl { + +/// low-level parser that extracts but does not interpret ACL options +class OptionExtractor +{ +public: + /// parses the next option and fills public members with its details + /// \returns whether option extraction was successful + bool extractOne(); + + /* extracted option details (after successful extraction */ + SBuf name; ///< extracted option name, including dash(es) + bool hasValue = false; ///< whether the option has a value (-x=value) + const SBuf &value() const; ///< extracted option value (requires hasValue) + +protected: + bool advance(); + void extractWhole(); + void extractShort(); + +private: + SBuf prefix_; ///< option name(s), including leading dash(es) + SBuf value_; ///< the last seen value of some option + SBuf::size_type letterPos_ = 0; ///< letter position inside an -xyz sequence + bool sawValue_ = false; ///< the current option sequence had a value +}; + +/// parses/validates/stores ACL options; skips/preserves parameter flags +class OptionsParser +{ +public: + OptionsParser(const Options &options, const ParameterFlags &flags); + + // fill previously supplied options container, throwing on errors + void parse(); + +private: + const Option *findOption(/* const */ SBuf &rawName); + + /// ACL parameter flags in parsing order + typedef std::vector Names; + /// parsed ACL parameter flags that must be preserved for ACLData::parse() + static Names flagsToSkip; + + const Options &options_; ///< caller-supported, linked options + const ParameterFlags ¶meterFlags_; ///< caller-supported parameter flags +}; + +} // namespace Acl + +/* Acl::OptionNameCmp */ + +bool +Acl::OptionNameCmp::operator()(const OptionName a, const OptionName b) const +{ + return strcmp(a, b) < 0; +} + +/* Acl::OptionExtractor */ + +const SBuf & +Acl::OptionExtractor::value() const +{ + Must(hasValue); + return value_; +} + +bool +Acl::OptionExtractor::extractOne() +{ + if (!prefix_.isEmpty()) { + extractShort(); // continue with the previously extracted flags + return true; + } + + if (!advance()) + return false; // end of options (and, possibly, the whole "acl" directive) + + if (prefix_.length() < 2) + throw TexcHere(ToSBuf("truncated(?) ACL flag: ", prefix_)); // single - or + + + if (prefix_[0] == '-' && prefix_[1] == '-') { + if (prefix_.length() == 2) + return false; // skipped "--", an explicit end-of-options marker + extractWhole(); + return true; + } + + if (prefix_.length() == 2) { // common trivial case: -x or +y + extractWhole(); + return true; + } + + // -xyz or +xyz + letterPos_ = 1; + extractShort(); + return true; +} + +/// extracts a token with the next option/flag(s) or returns false +bool +Acl::OptionExtractor::advance() +{ + const char *next = ConfigParser::PeekAtToken(); + if (!next) + return false; // end of the "acl" line + + const char nextChar = *next; + if (!(nextChar == '-' || nextChar == '+')) + return false; // start of ACL parameters + + sawValue_ = strchr(next, '='); // TODO: Make ConfigParser reject '^=.*' tokens + if (sawValue_) { + char *rawPrefix = nullptr; + char *rawValue = nullptr; + if (!ConfigParser::NextKvPair(rawPrefix, rawValue)) + throw TexcHere(ToSBuf("Malformed acl option=value: ", next)); + prefix_.assign(rawPrefix); + value_.assign(rawValue); + } else { + prefix_.assign(next); + ConfigParser::NextToken(); // consume what we have peeked at + } + return true; +} + +/// handles -x[=option] or --foo[=option] +void +Acl::OptionExtractor::extractWhole() +{ + debugs(28, 8, "from " << prefix_ << " value: " << sawValue_); + hasValue = sawValue_; + name = prefix_; + prefix_.clear(); +} + +/// handles one flag letter inside an -xyx[=option] or +xyz[=option] sequence +void +Acl::OptionExtractor::extractShort() +{ + debugs(28, 8, "from " << prefix_ << " at " << letterPos_ << " value: " << sawValue_); + name.assign(prefix_.rawContent(), 1); // leading - or + + name.append(prefix_.at(letterPos_++)); + if (letterPos_ >= prefix_.length()) { // got last flag in the sequence + hasValue = sawValue_; + prefix_.clear(); + } else { + hasValue = false; + } +} + +/* Acl::OptionsParser */ + +// being "static" is an optimization to avoid paying for vector creation/growth +Acl::OptionsParser::Names Acl::OptionsParser::flagsToSkip; + +Acl::OptionsParser::OptionsParser(const Options &options, const ParameterFlags &flags): + options_(options), + parameterFlags_(flags) +{ +} + +const Acl::Option * +Acl::OptionsParser::findOption(/* const */ SBuf &rawNameBuf) +{ + // TODO: new std::map::find() in C++14 does not require this conversion + const auto rawName = rawNameBuf.c_str(); + + const auto optionPos = options_.find(rawName); + if (optionPos != options_.end()) + return optionPos->second; + + const auto flagPos = parameterFlags_.find(rawName); + if (flagPos != parameterFlags_.end()) { + flagsToSkip.push_back(*flagPos); // *flagPos is permanent unlike rawName + return nullptr; + } + + throw TexcHere(ToSBuf("unsupported ACL option: ", rawNameBuf)); +} + +void +Acl::OptionsParser::parse() +{ + flagsToSkip.clear(); + + OptionExtractor oex; + while (oex.extractOne()) { + /* const */ auto rawName = oex.name; + if (const Option *optionPtr = findOption(rawName)) { + const Option &option = *optionPtr; + if (option.configured()) + debugs(28, 7, "acl uses multiple " << rawName << " options"); + switch (option.valueExpectation) + { + case Option::valueNone: + if (oex.hasValue) + throw TexcHere(ToSBuf("unexpected value for an ACL option: ", rawName, '=', oex.value())); + option.configureDefault(); + break; + case Option::valueRequired: + if (!oex.hasValue) + throw TexcHere(ToSBuf("missing required value for ACL option ", rawName)); + option.configureWith(oex.value()); + break; + case Option::valueOptional: + if (oex.hasValue) + option.configureWith(oex.value()); + else + option.configureDefault(); + break; + } + } + // else skip supported parameter flag + } + + /* hack: regex code wants to parse all -i and +i flags itself */ + for (const auto name: flagsToSkip) + ConfigParser::TokenPutBack(name); +} + +void +Acl::ParseFlags(const Options &options, const ParameterFlags &flags) +{ + OptionsParser parser(options, flags); + parser.parse(); +} + +const Acl::Options & +Acl::NoOptions() +{ + static const Options none; + return none; +} + +const Acl::ParameterFlags & +Acl::NoFlags() +{ + static const ParameterFlags none; + return none; +} + +std::ostream & +operator <<(std::ostream &os, const Acl::Option &option) +{ + if (option.valued()) { + os << '='; + option.print(os); + } + return os; +} + +std::ostream & +operator <<(std::ostream &os, const Acl::Options &options) +{ + for (const auto pos: options) { + assert(pos.second); + const auto &option = *pos.second; + if (option.configured()) + os << pos.first << option; + } + // TODO: Remember "--" presence and print that delimiter when present. + // Detecting its need is difficult because parameter flags start with "-". + return os; +} + diff --git a/src/acl/Options.h b/src/acl/Options.h new file mode 100644 index 0000000000..f36c451e7a --- /dev/null +++ b/src/acl/Options.h @@ -0,0 +1,179 @@ +/* + * Copyright (C) 1996-2017 The Squid Software Foundation and contributors + * + * Squid software is distributed under GPLv2+ license and includes + * contributions from numerous individuals and organizations. + * Please see the COPYING and CONTRIBUTORS files for details. + */ + +#ifndef SQUID_ACL_OPTIONS_H +#define SQUID_ACL_OPTIONS_H + +#include "acl/forward.h" +#include "sbuf/forward.h" + +#include +#include +#include + +// After all same-name acl configuration lines are merged into one ACL: +// configuration = acl name type [option...] [[flag...] parameter...] +// option = -x[=value] | --name[=value] +// flag = option +// +// Options and flags use the same syntax, but differ in scope and handling code: +// * ACL options appear before all parameters and apply to all parameters. +// They are handled by ACL kids (or equivalent). +// * Parameter flags may appear after some other parameters and apply only to +// the subsequent parameters (until they are overwritten by later flags). +// They are handled by ACLData kids. +// ACL options parsing code skips and leaves leading parameter flags (if any) +// for ACLData code to process. + +namespace Acl { + +typedef const char *OptionName; + +/// A single option supported by an ACL: -x[=value] or --name[=value] +/// Unlike a parameter flag, this option applies to all ACL parameters. +class Option +{ +public: + typedef enum { valueNone, valueOptional, valueRequired } ValueExpectation; + explicit Option(ValueExpectation vex = valueNone): valueExpectation(vex) {} + virtual ~Option() {} + + /// whether the admin explicitly specified this option + /// (i.e., whether configureWith() or configureDefault() has been called) + virtual bool configured() const = 0; + + /// called after parsing -x or --name + virtual void configureDefault() const = 0; + + /// called after parsing -x=value or --name=value + virtual void configureWith(const SBuf &rawValue) const = 0; + + virtual bool valued() const = 0; + + /// prints a configuration snippet (as an admin could have typed) + virtual void print(std::ostream &os) const = 0; + + ValueExpectation valueExpectation = valueNone; ///< expect "=value" part? +}; + +/// Stores configuration of a typical boolean flag or a single-value Option. +template +class OptionValue +{ +public: + typedef Value value_type; + + OptionValue(): value {} {} + explicit OptionValue(const Value &aValue): value(aValue) {} + + explicit operator bool() const { return configured; } + + Value value; ///< final value storage, possibly after conversions + bool configured = false; ///< whether the option was present in squid.conf + bool valued = false; ///< whether a configured option had a value +}; + +/// a type-specific Option (e.g., a boolean --toggle or -m=SBuf) +template +class TypedOption: public Option +{ +public: + //typedef typename Recipient::value_type value_type; + explicit TypedOption(ValueExpectation vex = valueNone): Option(vex) {} + + /// who to tell when this option is enabled + void linkWith(Recipient *recipient) const + { + assert(recipient); + recipient_ = recipient; + } + + /* Option API */ + + virtual bool configured() const override { return recipient_ && recipient_->configured; } + virtual bool valued() const override { return recipient_ && recipient_->valued; } + + /// sets the default value when option is used without a value + virtual void configureDefault() const override + { + assert(recipient_); + recipient_->configured = true; + recipient_->valued = false; + // sets recipient_->value to default + setDefault(); + } + + /// sets the option value from rawValue + virtual void configureWith(const SBuf &rawValue) const override + { + assert(recipient_); + recipient_->configured = true; + recipient_->valued = true; + import(rawValue); + } + + virtual void print(std::ostream &os) const override { if (valued()) os << recipient_->value; } + +private: + void import(const SBuf &rawValue) const { recipient_->value = rawValue; } + void setDefault() const { /*leave recipient_->value as is*/} + + // The "mutable" specifier demarcates set-once Option kind/behavior from the + // ever-changing recipient of the actual admin-configured option value. + mutable Recipient *recipient_ = nullptr; ///< parsing results storage +}; + +/* two typical option kinds: --foo and --bar=text */ +typedef OptionValue BooleanOptionValue; +typedef OptionValue TextOptionValue; +typedef TypedOption BooleanOption; +typedef TypedOption TextOption; + +// this specialization should never be called until we start supporting +// boolean option values like --name=enable or --name=false +template <> +inline void +BooleanOption::import(const SBuf &) const +{ + assert(!"boolean options do not have ...=values (for now)"); +} + +template <> +inline void +BooleanOption::setDefault() const +{ + recipient_->value = true; +} + +/// option name comparison functor +class OptionNameCmp { +public: + bool operator()(const OptionName a, const OptionName b) const; +}; +/// name:option map +typedef std::map Options; + +/// a set of parameter flag names +typedef std::set ParameterFlags; + +/// parses the flags part of the being-parsed ACL, filling Option values +/// \param options options supported by the ACL as a whole (e.g., -n) +/// \param flags options supported by ACL parameter(s) (e.g., -i) +void ParseFlags(const Options &options, const ParameterFlags &flags); + +/* handy for Class::options() and Class::supportedFlags() defaults */ +const Options &NoOptions(); ///< \returns an empty Options container +const ParameterFlags &NoFlags(); ///< \returns an empty ParameterFlags container + +} // namespace Acl + +std::ostream &operator <<(std::ostream &os, const Acl::Option &option); +std::ostream &operator <<(std::ostream &os, const Acl::Options &options); + +#endif /* SQUID_ACL_OPTIONS_H */ + diff --git a/src/acl/PeerName.cc b/src/acl/PeerName.cc index 702a90c31b..aa5aaf16cb 100644 --- a/src/acl/PeerName.cc +++ b/src/acl/PeerName.cc @@ -7,25 +7,16 @@ */ #include "squid.h" -#include "acl/Checklist.h" +#include "acl/FilledChecklist.h" #include "acl/PeerName.h" #include "acl/RegexData.h" #include "acl/StringData.h" -#include "CachePeer.h" int -ACLPeerNameStrategy::match (ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &) +ACLPeerNameStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) { if (!checklist->dst_peer_name.isEmpty()) return data->match(checklist->dst_peer_name.c_str()); return 0; } -ACLPeerNameStrategy * -ACLPeerNameStrategy::Instance() -{ - return &Instance_; -} - -ACLPeerNameStrategy ACLPeerNameStrategy::Instance_; - diff --git a/src/acl/PeerName.h b/src/acl/PeerName.h index 84145ed440..38e56f66f3 100644 --- a/src/acl/PeerName.h +++ b/src/acl/PeerName.h @@ -9,35 +9,13 @@ #ifndef SQUID_ACLPEERNAME_H #define SQUID_ACLPEERNAME_H -#include "acl/Strategised.h" #include "acl/Strategy.h" class ACLPeerNameStrategy : public ACLStrategy { public: - virtual int match (ACLData * &, ACLFilledChecklist *, ACLFlags &); - static ACLPeerNameStrategy *Instance(); - /* Not implemented to prevent copies of the instance. */ - /* Not private to prevent brain dead g+++ warnings about - * private constructors with no friends */ - ACLPeerNameStrategy(ACLPeerNameStrategy const &); - -private: - static ACLPeerNameStrategy Instance_; - ACLPeerNameStrategy() {} - - ACLPeerNameStrategy&operator=(ACLPeerNameStrategy const &); -}; - -class ACLPeerName -{ - -private: - static ACL::Prototype RegistryProtoype; - static ACLStrategised RegistryEntry_; - static ACL::Prototype RegexRegistryProtoype; - static ACLStrategised RegexRegistryEntry_; + virtual int match (ACLData * &, ACLFilledChecklist *) override; }; #endif /* SQUID_ACLPEERNAME_H */ diff --git a/src/acl/Protocol.cc b/src/acl/Protocol.cc index 551ac65b69..bf142bf6c8 100644 --- a/src/acl/Protocol.cc +++ b/src/acl/Protocol.cc @@ -7,9 +7,10 @@ */ #include "squid.h" -#include "acl/Checklist.h" +#include "acl/FilledChecklist.h" #include "acl/Protocol.h" #include "acl/ProtocolData.h" +#include "acl/Strategised.h" #include "HttpRequest.h" /* explicit template instantiation required for some systems */ @@ -17,16 +18,8 @@ template class ACLStrategised; int -ACLProtocolStrategy::match(ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &) +ACLProtocolStrategy::match(ACLData * &data, ACLFilledChecklist *checklist) { return data->match(checklist->request->url.getScheme()); } -ACLProtocolStrategy * -ACLProtocolStrategy::Instance() -{ - return &Instance_; -} - -ACLProtocolStrategy ACLProtocolStrategy::Instance_; - diff --git a/src/acl/Protocol.h b/src/acl/Protocol.h index 9e541d8d8c..d157324cb5 100644 --- a/src/acl/Protocol.h +++ b/src/acl/Protocol.h @@ -9,7 +9,6 @@ #ifndef SQUID_ACLPROTOCOL_H #define SQUID_ACLPROTOCOL_H -#include "acl/Strategised.h" #include "acl/Strategy.h" #include "anyp/ProtocolType.h" @@ -17,28 +16,8 @@ class ACLProtocolStrategy : public ACLStrategy { public: - virtual int match (ACLData * &, ACLFilledChecklist *, ACLFlags &); + virtual int match (ACLData * &, ACLFilledChecklist *); virtual bool requiresRequest() const {return true;} - - static ACLProtocolStrategy *Instance(); - /* Not implemented to prevent copies of the instance. */ - /* Not private to prevent brain dead g+++ warnings about - * private constructors with no friends */ - ACLProtocolStrategy(ACLProtocolStrategy const &); - -private: - static ACLProtocolStrategy Instance_; - ACLProtocolStrategy() {} - - ACLProtocolStrategy&operator=(ACLProtocolStrategy const &); -}; - -class ACLProtocol -{ - -private: - static ACL::Prototype RegistryProtoype; - static ACLStrategised RegistryEntry_; }; #endif /* SQUID_ACLPROTOCOL_H */ diff --git a/src/acl/Random.h b/src/acl/Random.h index f373facc14..002e7d46d7 100644 --- a/src/acl/Random.h +++ b/src/acl/Random.h @@ -10,7 +10,6 @@ #define SQUID_ACL_RANDOM_H #include "acl/Acl.h" -#include "acl/Checklist.h" class ACLRandom : public ACL { @@ -31,8 +30,6 @@ public: virtual bool valid() const; protected: - static Prototype RegistryProtoype; - static ACLRandom RegistryEntry_; double data; // value to be exceeded before this ACL will match char pattern[256]; // pattern from config file. Used to generate 'data' char const *class_; diff --git a/src/acl/Referer.cc b/src/acl/Referer.cc deleted file mode 100644 index 6f99c09dd1..0000000000 --- a/src/acl/Referer.cc +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (C) 1996-2017 The Squid Software Foundation and contributors - * - * Squid software is distributed under GPLv2+ license and includes - * contributions from numerous individuals and organizations. - * Please see the COPYING and CONTRIBUTORS files for details. - */ - -/* DEBUG: section 28 Access Control */ - -#include "squid.h" -#include "acl/Checklist.h" -#include "acl/Referer.h" -#include "acl/RegexData.h" - -/* explicit template instantiation required for some systems */ - -template class ACLRequestHeaderStrategy; - diff --git a/src/acl/Referer.h b/src/acl/Referer.h deleted file mode 100644 index 31c584a618..0000000000 --- a/src/acl/Referer.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (C) 1996-2017 The Squid Software Foundation and contributors - * - * Squid software is distributed under GPLv2+ license and includes - * contributions from numerous individuals and organizations. - * Please see the COPYING and CONTRIBUTORS files for details. - */ - -#ifndef SQUID_ACLREFERER_H -#define SQUID_ACLREFERER_H -#include "acl/Acl.h" -#include "acl/Data.h" -#include "acl/RequestHeaderStrategy.h" -#include "acl/Strategised.h" - -class ACLReferer -{ - -private: - static ACL::Prototype RegistryProtoype; - static ACLStrategised RegistryEntry_; -}; - -#endif /* SQUID_ACLREFERER_H */ - diff --git a/src/acl/RegexData.cc b/src/acl/RegexData.cc index a5ad88e09d..f6c33b5b38 100644 --- a/src/acl/RegexData.cc +++ b/src/acl/RegexData.cc @@ -28,6 +28,13 @@ ACLRegexData::~ACLRegexData() { } +const Acl::ParameterFlags & +ACLRegexData::supportedFlags() const +{ + static const Acl::ParameterFlags flags = { "-i", "+i" }; + return flags; +} + bool ACLRegexData::match(char const *word) { diff --git a/src/acl/RegexData.h b/src/acl/RegexData.h index 862170ce56..42c00cca6d 100644 --- a/src/acl/RegexData.h +++ b/src/acl/RegexData.h @@ -24,6 +24,7 @@ public: virtual bool match(char const *user); virtual SBufList dump() const; virtual void parse(); + virtual const Acl::ParameterFlags &supportedFlags() const; virtual bool empty() const; virtual ACLData *clone() const; diff --git a/src/acl/ReplyHeaderStrategy.h b/src/acl/ReplyHeaderStrategy.h index 69427772fa..a611f41cba 100644 --- a/src/acl/ReplyHeaderStrategy.h +++ b/src/acl/ReplyHeaderStrategy.h @@ -9,8 +9,6 @@ #ifndef SQUID_ACLREPLYHEADERSTRATEGY_H #define SQUID_ACLREPLYHEADERSTRATEGY_H -class ACLChecklist; - #include "acl/Acl.h" #include "acl/Data.h" #include "acl/FilledChecklist.h" @@ -22,25 +20,13 @@ class ACLReplyHeaderStrategy : public ACLStrategy { public: - virtual int match (ACLData * &, ACLFilledChecklist *, ACLFlags &); + virtual int match (ACLData * &, ACLFilledChecklist *); virtual bool requiresReply() const {return true;} - - static ACLReplyHeaderStrategy *Instance(); - /* Not implemented to prevent copies of the instance. */ - /* Not private to prevent brain dead g+++ warnings about - * private constructors with no friends */ - ACLReplyHeaderStrategy(ACLReplyHeaderStrategy const &); - -private: - static ACLReplyHeaderStrategy *Instance_; - ACLReplyHeaderStrategy() {} - - ACLReplyHeaderStrategy&operator=(ACLReplyHeaderStrategy const &); }; template int -ACLReplyHeaderStrategy
::match (ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &) +ACLReplyHeaderStrategy
::match (ACLData * &data, ACLFilledChecklist *checklist) { char const *theHeader = checklist->reply->header.getStr(header); @@ -50,18 +36,5 @@ ACLReplyHeaderStrategy
::match (ACLData * &data, ACLFilledC return data->match(theHeader); } -template -ACLReplyHeaderStrategy
* -ACLReplyHeaderStrategy
::Instance() -{ - if (!Instance_) - Instance_ = new ACLReplyHeaderStrategy
; - - return Instance_; -} - -template -ACLReplyHeaderStrategy
* ACLReplyHeaderStrategy
::Instance_ = NULL; - #endif /* SQUID_REPLYHEADERSTRATEGY_H */ diff --git a/src/acl/ReplyMimeType.cc b/src/acl/ReplyMimeType.cc deleted file mode 100644 index fbf97648a5..0000000000 --- a/src/acl/ReplyMimeType.cc +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (C) 1996-2017 The Squid Software Foundation and contributors - * - * Squid software is distributed under GPLv2+ license and includes - * contributions from numerous individuals and organizations. - * Please see the COPYING and CONTRIBUTORS files for details. - */ - -/* DEBUG: section 28 Access Control */ - -#include "squid.h" -#include "acl/Checklist.h" -#include "acl/RegexData.h" -#include "acl/ReplyMimeType.h" - -/* explicit template instantiation required for some systems */ - -template class ACLReplyHeaderStrategy; - diff --git a/src/acl/ReplyMimeType.h b/src/acl/ReplyMimeType.h index 93d77c44ba..9ba3765974 100644 --- a/src/acl/ReplyMimeType.h +++ b/src/acl/ReplyMimeType.h @@ -9,26 +9,15 @@ #ifndef SQUID_ACLREPLYMIMETYPE_H #define SQUID_ACLREPLYMIMETYPE_H -#include "acl/Acl.h" -#include "acl/Strategised.h" - -class ACLReplyMIMEType -{ - -private: - static ACL::Prototype RegistryProtoype; - static ACLStrategised RegistryEntry_; -}; - -/* partial specialisation */ - -#include "acl/Checklist.h" +#include "acl/FilledChecklist.h" #include "acl/Data.h" #include "acl/ReplyHeaderStrategy.h" +/* partial specialisation */ + template <> inline int -ACLReplyHeaderStrategy::match(ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &) +ACLReplyHeaderStrategy::match(ACLData * &data, ACLFilledChecklist *checklist) { char const *theHeader = checklist->reply->header.getStr(Http::HdrType::CONTENT_TYPE); diff --git a/src/acl/RequestHeaderStrategy.h b/src/acl/RequestHeaderStrategy.h index f4c783aa7f..135587c4c1 100644 --- a/src/acl/RequestHeaderStrategy.h +++ b/src/acl/RequestHeaderStrategy.h @@ -19,25 +19,13 @@ class ACLRequestHeaderStrategy : public ACLStrategy { public: - virtual int match (ACLData * &, ACLFilledChecklist *, ACLFlags &); + virtual int match (ACLData * &, ACLFilledChecklist *); virtual bool requiresRequest() const {return true;} - - static ACLRequestHeaderStrategy *Instance(); - /* Not implemented to prevent copies of the instance. */ - /* Not private to prevent brain dead g+++ warnings about - * private constructors with no friends */ - ACLRequestHeaderStrategy(ACLRequestHeaderStrategy const &); - -private: - static ACLRequestHeaderStrategy *Instance_; - ACLRequestHeaderStrategy() {} - - ACLRequestHeaderStrategy&operator=(ACLRequestHeaderStrategy const &); }; template int -ACLRequestHeaderStrategy
::match (ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &) +ACLRequestHeaderStrategy
::match (ACLData * &data, ACLFilledChecklist *checklist) { char const *theHeader = checklist->request->header.getStr(header); @@ -47,18 +35,5 @@ ACLRequestHeaderStrategy
::match (ACLData * &data, ACLFille return data->match(theHeader); } -template -ACLRequestHeaderStrategy
* -ACLRequestHeaderStrategy
::Instance() -{ - if (!Instance_) - Instance_ = new ACLRequestHeaderStrategy
; - - return Instance_; -} - -template -ACLRequestHeaderStrategy
* ACLRequestHeaderStrategy
::Instance_ = NULL; - #endif /* SQUID_REQUESTHEADERSTRATEGY_H */ diff --git a/src/acl/RequestMimeType.cc b/src/acl/RequestMimeType.cc deleted file mode 100644 index 508fdac76f..0000000000 --- a/src/acl/RequestMimeType.cc +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (C) 1996-2017 The Squid Software Foundation and contributors - * - * Squid software is distributed under GPLv2+ license and includes - * contributions from numerous individuals and organizations. - * Please see the COPYING and CONTRIBUTORS files for details. - */ - -/* DEBUG: section 28 Access Control */ - -#include "squid.h" -#include "acl/Checklist.h" -#include "acl/RegexData.h" -#include "acl/RequestMimeType.h" - -/* explicit template instantiation required for some systems */ - -template class ACLRequestHeaderStrategy; - diff --git a/src/acl/RequestMimeType.h b/src/acl/RequestMimeType.h index 4240d4acbd..6d269a4946 100644 --- a/src/acl/RequestMimeType.h +++ b/src/acl/RequestMimeType.h @@ -9,26 +9,15 @@ #ifndef SQUID_ACLREQUESTMIMETYPE_H #define SQUID_ACLREQUESTMIMETYPE_H -#include "acl/Acl.h" -#include "acl/Strategised.h" - -class ACLRequestMIMEType -{ - -private: - static ACL::Prototype RegistryProtoype; - static ACLStrategised RegistryEntry_; -}; - -/* partial specialisation */ - -#include "acl/Checklist.h" +#include "acl/FilledChecklist.h" #include "acl/Data.h" #include "acl/RequestHeaderStrategy.h" +/* partial specialisation */ + template <> inline int -ACLRequestHeaderStrategy::match (ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &) +ACLRequestHeaderStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) { char const *theHeader = checklist->request->header.getStr(Http::HdrType::CONTENT_TYPE); diff --git a/src/acl/ServerCertificate.cc b/src/acl/ServerCertificate.cc index 4c3a1a720c..e01d4d976f 100644 --- a/src/acl/ServerCertificate.cc +++ b/src/acl/ServerCertificate.cc @@ -19,7 +19,7 @@ #include "ssl/ServerBump.h" int -ACLServerCertificateStrategy::match(ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &) +ACLServerCertificateStrategy::match(ACLData * &data, ACLFilledChecklist *checklist) { Security::CertPointer cert; if (checklist->serverCert) @@ -33,13 +33,5 @@ ACLServerCertificateStrategy::match(ACLData * &data, ACLFilledCheckli return data->match(cert.get()); } -ACLServerCertificateStrategy * -ACLServerCertificateStrategy::Instance() -{ - return &Instance_; -} - -ACLServerCertificateStrategy ACLServerCertificateStrategy::Instance_; - #endif /* USE_OPENSSL */ diff --git a/src/acl/ServerCertificate.h b/src/acl/ServerCertificate.h index 3631ab5127..f26273aa29 100644 --- a/src/acl/ServerCertificate.h +++ b/src/acl/ServerCertificate.h @@ -19,26 +19,7 @@ class ACLServerCertificateStrategy : public ACLStrategy { public: - virtual int match (ACLData * &, ACLFilledChecklist *, ACLFlags &); - static ACLServerCertificateStrategy *Instance(); - /* Not implemented to prevent copies of the instance. */ - /* Not private to prevent brain dead g+++ warnings about - * private constructors with no friends */ - ACLServerCertificateStrategy(ACLServerCertificateStrategy const &); - -private: - static ACLServerCertificateStrategy Instance_; - ACLServerCertificateStrategy() {} - - ACLServerCertificateStrategy&operator=(ACLServerCertificateStrategy const &); -}; - -/// \ingroup ACLAPI -class ACLServerCertificate -{ -private: - static ACL::Prototype X509FingerprintRegistryProtoype; - static ACLStrategised X509FingerprintRegistryEntry_; + virtual int match (ACLData * &, ACLFilledChecklist *) override; }; #endif /* SQUID_ACLSERVERCERTIFICATE_H */ diff --git a/src/acl/ServerName.cc b/src/acl/ServerName.cc index 3738943faa..15d02e9c36 100644 --- a/src/acl/ServerName.cc +++ b/src/acl/ServerName.cc @@ -9,8 +9,8 @@ /* DEBUG: section 28 Access Control */ #include "squid.h" -#include "acl/Checklist.h" #include "acl/DomainData.h" +#include "acl/FilledChecklist.h" #include "acl/RegexData.h" #include "acl/ServerName.h" #include "client_side.h" @@ -87,7 +87,7 @@ check_cert_domain( void *check_data, ASN1_STRING *cn_data) } int -ACLServerNameStrategy::match (ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &flags) +ACLServerNameStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) { assert(checklist != NULL && checklist->request != NULL); @@ -116,11 +116,3 @@ ACLServerNameStrategy::match (ACLData * &data, ACLFilledChecklist *ch return data->match(serverName); } -ACLServerNameStrategy * -ACLServerNameStrategy::Instance() -{ - return &Instance_; -} - -ACLServerNameStrategy ACLServerNameStrategy::Instance_; - diff --git a/src/acl/ServerName.h b/src/acl/ServerName.h index e31befa449..32af2dbd8a 100644 --- a/src/acl/ServerName.h +++ b/src/acl/ServerName.h @@ -10,10 +10,8 @@ #define SQUID_ACLSERVERNAME_H #include "acl/Acl.h" -#include "acl/Checklist.h" -#include "acl/Data.h" #include "acl/DomainData.h" -#include "acl/Strategised.h" +#include "acl/Strategy.h" class ACLServerNameData : public ACLDomainData { MEMPROXY_CLASS(ACLServerNameData); @@ -27,33 +25,10 @@ class ACLServerNameStrategy : public ACLStrategy { public: - virtual int match (ACLData * &, ACLFilledChecklist *, ACLFlags &); - static ACLServerNameStrategy *Instance(); + /* ACLStrategy API */ + virtual int match (ACLData * &, ACLFilledChecklist *); virtual bool requiresRequest() const {return true;} - /** - * Not implemented to prevent copies of the instance. - \par - * Not private to prevent brain dead g+++ warnings about - * private constructors with no friends - */ - ACLServerNameStrategy(ACLServerNameStrategy const &); - -private: - static ACLServerNameStrategy Instance_; - ACLServerNameStrategy() {} - - ACLServerNameStrategy&operator=(ACLServerNameStrategy const &); -}; - -class ACLServerName -{ - -private: - static ACL::Prototype LiteralRegistryProtoype; - static ACLStrategised LiteralRegistryEntry_; - static ACL::Prototype RegexRegistryProtoype; - static ACLStrategised RegexRegistryEntry_; }; #endif /* SQUID_ACLSERVERNAME_H */ diff --git a/src/acl/SourceAsn.h b/src/acl/SourceAsn.h index 643f0feef9..3b19bd6b93 100644 --- a/src/acl/SourceAsn.h +++ b/src/acl/SourceAsn.h @@ -18,18 +18,7 @@ class ACLSourceASNStrategy : public ACLStrategy { public: - virtual int match (ACLData * &, ACLFilledChecklist *, ACLFlags &); - static ACLSourceASNStrategy *Instance(); - /* Not implemented to prevent copies of the instance. */ - /* Not private to prevent brain dead g+++ warnings about - * private constructors with no friends */ - ACLSourceASNStrategy(ACLSourceASNStrategy const &); - -private: - static ACLSourceASNStrategy Instance_; - ACLSourceASNStrategy() {} - - ACLSourceASNStrategy&operator=(ACLSourceASNStrategy const &); + virtual int match (ACLData * &, ACLFilledChecklist *) override; }; #endif /* SQUID_ACL_SOURCEASN_H */ diff --git a/src/acl/SourceDomain.cc b/src/acl/SourceDomain.cc index 4a5c5f7a78..a76cd5bb8c 100644 --- a/src/acl/SourceDomain.cc +++ b/src/acl/SourceDomain.cc @@ -11,6 +11,7 @@ #include "squid.h" #include "acl/Checklist.h" #include "acl/DomainData.h" +#include "acl/FilledChecklist.h" #include "acl/RegexData.h" #include "acl/SourceDomain.h" #include "fqdncache.h" @@ -40,7 +41,7 @@ SourceDomainLookup::LookupDone(const char *, const Dns::LookupDetails &details, } int -ACLSourceDomainStrategy::match (ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &) +ACLSourceDomainStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) { const char *fqdn = NULL; fqdn = fqdncache_gethostbyaddr(checklist->src_addr, FQDN_LOOKUP_IF_MISS); @@ -58,11 +59,3 @@ ACLSourceDomainStrategy::match (ACLData * &data, ACLFilledChecklist * return data->match("none"); } -ACLSourceDomainStrategy * -ACLSourceDomainStrategy::Instance() -{ - return &Instance_; -} - -ACLSourceDomainStrategy ACLSourceDomainStrategy::Instance_; - diff --git a/src/acl/SourceDomain.h b/src/acl/SourceDomain.h index cd189e4733..d6ac22ae4d 100644 --- a/src/acl/SourceDomain.h +++ b/src/acl/SourceDomain.h @@ -11,25 +11,14 @@ #include "acl/Acl.h" #include "acl/Checklist.h" #include "acl/Data.h" -#include "acl/Strategised.h" +#include "acl/Strategy.h" #include "dns/forward.h" class ACLSourceDomainStrategy : public ACLStrategy { public: - virtual int match (ACLData * &, ACLFilledChecklist *, ACLFlags &); - static ACLSourceDomainStrategy *Instance(); - /* Not implemented to prevent copies of the instance. */ - /* Not private to prevent brain dead g+++ warnings about - * private constructors with no friends */ - ACLSourceDomainStrategy(ACLSourceDomainStrategy const &); - -private: - static ACLSourceDomainStrategy Instance_; - ACLSourceDomainStrategy() {} - - ACLSourceDomainStrategy&operator=(ACLSourceDomainStrategy const &); + virtual int match (ACLData * &, ACLFilledChecklist *) override; }; class SourceDomainLookup : public ACLChecklist::AsyncState @@ -44,15 +33,5 @@ private: static void LookupDone(const char *, const Dns::LookupDetails &, void *); }; -class ACLSourceDomain -{ - -private: - static ACL::Prototype LiteralRegistryProtoype; - static ACLStrategised LiteralRegistryEntry_; - static ACL::Prototype RegexRegistryProtoype; - static ACLStrategised RegexRegistryEntry_; -}; - #endif /* SQUID_ACLSOURCEDOMAIN_H */ diff --git a/src/acl/SourceIp.h b/src/acl/SourceIp.h index 4cf0968e60..43633f5f7d 100644 --- a/src/acl/SourceIp.h +++ b/src/acl/SourceIp.h @@ -19,10 +19,6 @@ public: virtual char const *typeString() const; virtual int match(ACLChecklist *checklist); virtual ACL *clone()const; - -private: - static Prototype RegistryProtoype; - static ACLSourceIP RegistryEntry_; }; #endif /* SQUID_ACLSOURCEIP_H */ diff --git a/src/acl/SquidError.cc b/src/acl/SquidError.cc index b31c758fff..5e760b46e3 100644 --- a/src/acl/SquidError.cc +++ b/src/acl/SquidError.cc @@ -7,12 +7,12 @@ */ #include "squid.h" -#include "acl/Checklist.h" +#include "acl/FilledChecklist.h" #include "acl/SquidError.h" #include "HttpRequest.h" int -ACLSquidErrorStrategy::match (ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &) +ACLSquidErrorStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) { if (checklist->requestErrorType != ERR_MAX) return data->match(checklist->requestErrorType); @@ -21,11 +21,3 @@ ACLSquidErrorStrategy::match (ACLData * &data, ACLFilledChecklist *ch return 0; } -ACLSquidErrorStrategy * -ACLSquidErrorStrategy::Instance() -{ - return &Instance_; -} - -ACLSquidErrorStrategy ACLSquidErrorStrategy::Instance_; - diff --git a/src/acl/SquidError.h b/src/acl/SquidError.h index 7b119c2d3d..3bc2ff304b 100644 --- a/src/acl/SquidError.h +++ b/src/acl/SquidError.h @@ -9,7 +9,6 @@ #ifndef SQUID_ACLSQUIDERROR_H #define SQUID_ACLSQUIDERROR_H -#include "acl/Strategised.h" #include "acl/Strategy.h" #include "err_type.h" @@ -17,27 +16,7 @@ class ACLSquidErrorStrategy : public ACLStrategy { public: - virtual int match (ACLData * &, ACLFilledChecklist *, ACLFlags &); - - static ACLSquidErrorStrategy *Instance(); - /* Not implemented to prevent copies of the instance. */ - /* Not private to prevent brain dead g+++ warnings about - * private constructors with no friends */ - ACLSquidErrorStrategy(ACLSquidErrorStrategy const &); - -private: - static ACLSquidErrorStrategy Instance_; - ACLSquidErrorStrategy() {} - - ACLSquidErrorStrategy&operator=(ACLSquidErrorStrategy const &); -}; - -class ACLSquidError -{ - -private: - static ACL::Prototype RegistryProtoype; - static ACLStrategised RegistryEntry_; + virtual int match (ACLData * &, ACLFilledChecklist *) override; }; #endif /* SQUID_ACLSQUIDERROR_H */ diff --git a/src/acl/SslError.cc b/src/acl/SslError.cc index bf82936a0c..f21d808586 100644 --- a/src/acl/SslError.cc +++ b/src/acl/SslError.cc @@ -7,21 +7,13 @@ */ #include "squid.h" -#include "acl/Checklist.h" +#include "acl/FilledChecklist.h" #include "acl/SslError.h" #include "acl/SslErrorData.h" int -ACLSslErrorStrategy::match (ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &) +ACLSslErrorStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) { return data->match (checklist->sslErrors); } -ACLSslErrorStrategy * -ACLSslErrorStrategy::Instance() -{ - return &Instance_; -} - -ACLSslErrorStrategy ACLSslErrorStrategy::Instance_; - diff --git a/src/acl/SslError.h b/src/acl/SslError.h index 036a3994cb..c4225c0634 100644 --- a/src/acl/SslError.h +++ b/src/acl/SslError.h @@ -9,33 +9,14 @@ #ifndef SQUID_ACLSSL_ERROR_H #define SQUID_ACLSSL_ERROR_H -#include "acl/Strategised.h" #include "acl/Strategy.h" +#include "security/forward.h" class ACLSslErrorStrategy : public ACLStrategy { public: - virtual int match (ACLData * &, ACLFilledChecklist *, ACLFlags &); - static ACLSslErrorStrategy *Instance(); - /* Not implemented to prevent copies of the instance. */ - /* Not private to prevent brain dead g+++ warnings about - * private constructors with no friends */ - ACLSslErrorStrategy(ACLSslErrorStrategy const &); - -private: - static ACLSslErrorStrategy Instance_; - ACLSslErrorStrategy() {} - - ACLSslErrorStrategy&operator=(ACLSslErrorStrategy const &); -}; - -class ACLSslError -{ - -private: - static ACL::Prototype RegistryProtoype; - static ACLStrategised RegistryEntry_; + virtual int match (ACLData * &, ACLFilledChecklist *) override; }; #endif /* SQUID_ACLSSL_ERROR_H */ diff --git a/src/acl/Strategised.h b/src/acl/Strategised.h index 9a092e2f9f..9043188c65 100644 --- a/src/acl/Strategised.h +++ b/src/acl/Strategised.h @@ -14,6 +14,16 @@ #include "acl/FilledChecklist.h" #include "acl/Strategy.h" +// XXX: Replace with a much simpler abstract ACL child class without the +// ACLStrategy parameter (and associated call forwarding). Duplicating key +// portions of the ACL class API in ACLStrategy is not needed because +// ACLStrategy is unused outside the ACLStrategised context. Existing classes +// like ACLExtUser, ACLProxyAuth, and ACLIdent seem to confirm this assertion. +// It also requires forwarding ACL info to ACLStrategy as method parameters. + +/// Splits the ACL API into two individually configurable components: +/// * ACLStrategy that usually extracts information from the current transaction +/// * ACLData that usually matches information against admin-configured values template class ACLStrategised : public ACL { @@ -23,24 +33,24 @@ public: typedef M MatchType; ~ACLStrategised(); - ACLStrategised(ACLData *, ACLStrategy *, char const *, const ACLFlag flags[] = ACLFlags::NoFlags); - ACLStrategised (ACLStrategised const &); - ACLStrategised &operator= (ACLStrategised const &); + ACLStrategised(ACLData *, ACLStrategy *, char const *); + ACLStrategised(ACLStrategised const &&) = delete; virtual char const *typeString() const; + virtual void parseFlags(); + virtual bool requiresRequest() const {return matcher->requiresRequest();} virtual bool requiresReply() const {return matcher->requiresReply();} virtual void prepareForUse() { data->prepareForUse();} - + virtual const Acl::Options &options() { return matcher->options(); } virtual void parse(); virtual int match(ACLChecklist *checklist); virtual int match (M const &); virtual SBufList dump() const; virtual bool empty () const; virtual bool valid () const; - virtual ACL *clone()const; private: ACLData *data; @@ -57,27 +67,21 @@ ACLStrategised::~ACLStrategised() } template -ACLStrategised::ACLStrategised(ACLData *newData, ACLStrategy *theStrategy, char const *theType, const ACLFlag flgs[]) : ACL(flgs), data (newData), type_(theType), matcher(theStrategy) {} - -template -ACLStrategised::ACLStrategised (ACLStrategised const &old) : data (old.data->clone()), type_(old.type_), matcher (old.matcher) +ACLStrategised::ACLStrategised(ACLData *newData, ACLStrategy *theStrategy, char const *theType): data(newData), type_(theType), matcher(theStrategy) {} template -ACLStrategised & -ACLStrategised::operator= (ACLStrategised const &rhs) +char const * +ACLStrategised::typeString() const { - data = rhs.data->clone(); - type_ = rhs.type_; - matcher = rhs.matcher; - return *this; + return type_; } template -char const * -ACLStrategised::typeString() const +void +ACLStrategised::parseFlags() { - return type_; + ParseFlags(options(), data->supportedFlags()); } template @@ -100,7 +104,7 @@ ACLStrategised::match(ACLChecklist *cl) { ACLFilledChecklist *checklist = dynamic_cast(cl); assert(checklist); - return matcher->match(data, checklist, flags); + return matcher->match(data, checklist); } template @@ -124,12 +128,5 @@ ACLStrategised::valid () const return matcher->valid(); } -template -ACL * -ACLStrategised::clone() const -{ - return new ACLStrategised(*this); -} - #endif /* SQUID_ACLSTRATEGISED_H */ diff --git a/src/acl/Strategy.h b/src/acl/Strategy.h index 613d33f969..feaf5f8ce9 100644 --- a/src/acl/Strategy.h +++ b/src/acl/Strategy.h @@ -11,17 +11,22 @@ #include "acl/Acl.h" #include "acl/Data.h" +#include "acl/Options.h" class ACLFilledChecklist; template +/// A matching algorithm. class ACLStrategy { public: typedef M MatchType; - virtual int match (ACLData * &, ACLFilledChecklist *, ACLFlags &) = 0; + + /* Replicate ACL API parts relevant to the matching algorithm. */ + virtual const Acl::Options &options() { return Acl::NoOptions(); } + virtual int match (ACLData * &, ACLFilledChecklist *) = 0; virtual bool requiresRequest() const {return false;} virtual bool requiresReply() const {return false;} diff --git a/src/acl/Tag.cc b/src/acl/Tag.cc index e2143513d4..e884b53e70 100644 --- a/src/acl/Tag.cc +++ b/src/acl/Tag.cc @@ -7,24 +7,16 @@ */ #include "squid.h" -#include "acl/Checklist.h" +#include "acl/FilledChecklist.h" #include "acl/StringData.h" #include "acl/Tag.h" #include "HttpRequest.h" int -ACLTagStrategy::match (ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &) +ACLTagStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) { if (checklist->request != NULL) return data->match (checklist->request->tag.termedBuf()); return 0; } -ACLTagStrategy * -ACLTagStrategy::Instance() -{ - return &Instance_; -} - -ACLTagStrategy ACLTagStrategy::Instance_; - diff --git a/src/acl/Tag.h b/src/acl/Tag.h index 2c3d9b2fea..4e093bf513 100644 --- a/src/acl/Tag.h +++ b/src/acl/Tag.h @@ -9,33 +9,13 @@ #ifndef SQUID_ACLTAG_H #define SQUID_ACLTAG_H -#include "acl/Strategised.h" #include "acl/Strategy.h" class ACLTagStrategy : public ACLStrategy { public: - virtual int match (ACLData * &, ACLFilledChecklist *, ACLFlags &); - static ACLTagStrategy *Instance(); - /* Not implemented to prevent copies of the instance. */ - /* Not private to prevent brain dead g+++ warnings about - * private constructors with no friends */ - ACLTagStrategy(ACLTagStrategy const &); - -private: - static ACLTagStrategy Instance_; - ACLTagStrategy() {} - - ACLTagStrategy&operator=(ACLTagStrategy const &); -}; - -class ACLTag -{ - -private: - static ACL::Prototype RegistryProtoype; - static ACLStrategised RegistryEntry_; + virtual int match (ACLData * &, ACLFilledChecklist *) override; }; #endif /* SQUID_ACLMYPORTNAME_H */ diff --git a/src/acl/Time.cc b/src/acl/Time.cc index 03646df212..0267ba7089 100644 --- a/src/acl/Time.cc +++ b/src/acl/Time.cc @@ -14,16 +14,8 @@ #include "SquidTime.h" int -ACLTimeStrategy::match(ACLData * &data, ACLFilledChecklist *, ACLFlags &) +ACLTimeStrategy::match(ACLData * &data, ACLFilledChecklist *) { return data->match(squid_curtime); } -ACLTimeStrategy * -ACLTimeStrategy::Instance() -{ - return &Instance_; -} - -ACLTimeStrategy ACLTimeStrategy::Instance_; - diff --git a/src/acl/Time.h b/src/acl/Time.h index db749ffe1d..41cd06a82f 100644 --- a/src/acl/Time.h +++ b/src/acl/Time.h @@ -8,36 +8,14 @@ #ifndef SQUID_ACLTIME_H #define SQUID_ACLTIME_H -#include "acl/Acl.h" #include "acl/Data.h" #include "acl/Strategised.h" -class ACLChecklist; // XXX: we do not need it - class ACLTimeStrategy : public ACLStrategy { public: - virtual int match (ACLData * &, ACLFilledChecklist *, ACLFlags &); - static ACLTimeStrategy *Instance(); - /* Not implemented to prevent copies of the instance. */ - /* Not private to prevent brain dead g+++ warnings about - * private constructors with no friends */ - ACLTimeStrategy(ACLTimeStrategy const &); - -private: - static ACLTimeStrategy Instance_; - ACLTimeStrategy() {} - - ACLTimeStrategy&operator=(ACLTimeStrategy const &); -}; - -class ACLTime -{ - -public: - static ACL::Prototype RegistryProtoype; - static ACLStrategised RegistryEntry_; + virtual int match (ACLData * &, ACLFilledChecklist *) override; }; #endif /* SQUID_ACLTIME_H */ diff --git a/src/acl/Url.cc b/src/acl/Url.cc index b6b76d85a7..c744219c21 100644 --- a/src/acl/Url.cc +++ b/src/acl/Url.cc @@ -9,7 +9,7 @@ /* DEBUG: section 28 Access Control */ #include "squid.h" -#include "acl/Checklist.h" +#include "acl/FilledChecklist.h" #include "acl/RegexData.h" #include "acl/Url.h" #include "HttpRequest.h" @@ -17,7 +17,7 @@ #include "src/URL.h" int -ACLUrlStrategy::match (ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &) +ACLUrlStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) { char *esc_buf = SBufToCstring(checklist->request->effectiveRequestUri()); rfc1738_unescape(esc_buf); @@ -26,11 +26,3 @@ ACLUrlStrategy::match (ACLData * &data, ACLFilledChecklist *checkl return result; } -ACLUrlStrategy * -ACLUrlStrategy::Instance() -{ - return &Instance_; -} - -ACLUrlStrategy ACLUrlStrategy::Instance_; - diff --git a/src/acl/Url.h b/src/acl/Url.h index 95dc02aaa1..950ef4341a 100644 --- a/src/acl/Url.h +++ b/src/acl/Url.h @@ -8,7 +8,7 @@ #ifndef SQUID_ACLURL_H #define SQUID_ACLURL_H -#include "acl/Acl.h" + #include "acl/Data.h" #include "acl/Strategised.h" @@ -16,29 +16,8 @@ class ACLUrlStrategy : public ACLStrategy { public: - virtual int match (ACLData * &, ACLFilledChecklist *, ACLFlags &); + virtual int match (ACLData * &, ACLFilledChecklist *); virtual bool requiresRequest() const {return true;} - - static ACLUrlStrategy *Instance(); - /* Not implemented to prevent copies of the instance. */ - /* Not private to prevent brain dead g+++ warnings about - * private constructors with no friends */ - ACLUrlStrategy(ACLUrlStrategy const &); - -private: - static ACLUrlStrategy Instance_; - ACLUrlStrategy() {} - - ACLUrlStrategy&operator=(ACLUrlStrategy const &); -}; - -class ACLUrl -{ - -public: - static ACL::Prototype RegistryProtoype; - static ACL::Prototype LegacyRegistryProtoype; - static ACLStrategised RegistryEntry_; }; #endif /* SQUID_ACLURL_H */ diff --git a/src/acl/UrlLogin.cc b/src/acl/UrlLogin.cc index 734c597db4..52fae965d5 100644 --- a/src/acl/UrlLogin.cc +++ b/src/acl/UrlLogin.cc @@ -9,14 +9,14 @@ /* DEBUG: section 28 Access Control */ #include "squid.h" -#include "acl/Checklist.h" +#include "acl/FilledChecklist.h" #include "acl/RegexData.h" #include "acl/UrlLogin.h" #include "HttpRequest.h" #include "rfc1738.h" int -ACLUrlLoginStrategy::match(ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &) +ACLUrlLoginStrategy::match(ACLData * &data, ACLFilledChecklist *checklist) { if (checklist->request->url.userInfo().isEmpty()) { debugs(28, 5, "URL has no user-info details. cannot match"); @@ -31,11 +31,3 @@ ACLUrlLoginStrategy::match(ACLData * &data, ACLFilledChecklist *ch return data->match(str); } -ACLUrlLoginStrategy * -ACLUrlLoginStrategy::Instance() -{ - return &Instance_; -} - -ACLUrlLoginStrategy ACLUrlLoginStrategy::Instance_; - diff --git a/src/acl/UrlLogin.h b/src/acl/UrlLogin.h index 22fe41f5af..bc635836cf 100644 --- a/src/acl/UrlLogin.h +++ b/src/acl/UrlLogin.h @@ -11,36 +11,14 @@ #include "acl/Acl.h" #include "acl/Data.h" -#include "acl/Strategised.h" #include "acl/Strategy.h" class ACLUrlLoginStrategy : public ACLStrategy { public: - virtual int match (ACLData * &, ACLFilledChecklist *, ACLFlags &); + virtual int match (ACLData * &, ACLFilledChecklist *); virtual bool requiresRequest() const {return true;} - - static ACLUrlLoginStrategy *Instance(); - /* Not implemented to prevent copies of the instance. */ - /* Not private to prevent brain dead g+++ warnings about - * private constructors with no friends */ - ACLUrlLoginStrategy(ACLUrlLoginStrategy const &); - -private: - static ACLUrlLoginStrategy Instance_; - ACLUrlLoginStrategy() {} - - ACLUrlLoginStrategy&operator=(ACLUrlLoginStrategy const &); -}; - -class ACLUrlLogin -{ - -public: - static ACL::Prototype RegistryProtoype; - static ACL::Prototype LegacyRegistryProtoype; - static ACLStrategised RegistryEntry_; }; #endif /* SQUID_ACLURLLOGIN_H */ diff --git a/src/acl/UrlPath.cc b/src/acl/UrlPath.cc index 2ac2be006e..c9a4f0aed4 100644 --- a/src/acl/UrlPath.cc +++ b/src/acl/UrlPath.cc @@ -9,14 +9,14 @@ /* DEBUG: section 28 Access Control */ #include "squid.h" -#include "acl/Checklist.h" +#include "acl/FilledChecklist.h" #include "acl/RegexData.h" #include "acl/UrlPath.h" #include "HttpRequest.h" #include "rfc1738.h" int -ACLUrlPathStrategy::match (ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &) +ACLUrlPathStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) { if (checklist->request->url.path().isEmpty()) return -1; @@ -28,11 +28,3 @@ ACLUrlPathStrategy::match (ACLData * &data, ACLFilledChecklist *ch return result; } -ACLUrlPathStrategy * -ACLUrlPathStrategy::Instance() -{ - return &Instance_; -} - -ACLUrlPathStrategy ACLUrlPathStrategy::Instance_; - diff --git a/src/acl/UrlPath.h b/src/acl/UrlPath.h index f249394a68..571fafd353 100644 --- a/src/acl/UrlPath.h +++ b/src/acl/UrlPath.h @@ -8,38 +8,15 @@ #ifndef SQUID_ACLURLPATH_H #define SQUID_ACLURLPATH_H -#include "acl/Acl.h" -#include "acl/Data.h" -#include "acl/Strategised.h" + #include "acl/Strategy.h" class ACLUrlPathStrategy : public ACLStrategy { public: - virtual int match (ACLData * &, ACLFilledChecklist *, ACLFlags &); + virtual int match (ACLData * &, ACLFilledChecklist *); virtual bool requiresRequest() const {return true;} - - static ACLUrlPathStrategy *Instance(); - /* Not implemented to prevent copies of the instance. */ - /* Not private to prevent brain dead g+++ warnings about - * private constructors with no friends */ - ACLUrlPathStrategy(ACLUrlPathStrategy const &); - -private: - static ACLUrlPathStrategy Instance_; - ACLUrlPathStrategy() {} - - ACLUrlPathStrategy&operator=(ACLUrlPathStrategy const &); -}; - -class ACLUrlPath -{ - -public: - static ACL::Prototype RegistryProtoype; - static ACL::Prototype LegacyRegistryProtoype; - static ACLStrategised RegistryEntry_; }; #endif /* SQUID_ACLURLPATH_H */ diff --git a/src/acl/UrlPort.cc b/src/acl/UrlPort.cc index c2f0ad11d1..ae3797bbd6 100644 --- a/src/acl/UrlPort.cc +++ b/src/acl/UrlPort.cc @@ -7,22 +7,13 @@ */ #include "squid.h" -#include "acl/Checklist.h" -#include "acl/IntRange.h" +#include "acl/FilledChecklist.h" #include "acl/UrlPort.h" #include "HttpRequest.h" int -ACLUrlPortStrategy::match(ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &) +ACLUrlPortStrategy::match(ACLData * &data, ACLFilledChecklist *checklist) { return data->match(checklist->request->url.port()); } -ACLUrlPortStrategy * -ACLUrlPortStrategy::Instance() -{ - return &Instance_; -} - -ACLUrlPortStrategy ACLUrlPortStrategy::Instance_; - diff --git a/src/acl/UrlPort.h b/src/acl/UrlPort.h index 19cd8caba4..d0bb64c57f 100644 --- a/src/acl/UrlPort.h +++ b/src/acl/UrlPort.h @@ -8,35 +8,15 @@ #ifndef SQUID_ACLURLPORT_H #define SQUID_ACLURLPORT_H -#include "acl/Strategised.h" + #include "acl/Strategy.h" class ACLUrlPortStrategy : public ACLStrategy { public: - virtual int match (ACLData * &, ACLFilledChecklist *, ACLFlags &); + virtual int match (ACLData * &, ACLFilledChecklist *); virtual bool requiresRequest() const {return true;} - - static ACLUrlPortStrategy *Instance(); - /* Not implemented to prevent copies of the instance. */ - /* Not private to prevent brain dead g+++ warnings about - * private constructors with no friends */ - ACLUrlPortStrategy(ACLUrlPortStrategy const &); - -private: - static ACLUrlPortStrategy Instance_; - ACLUrlPortStrategy() {} - - ACLUrlPortStrategy&operator=(ACLUrlPortStrategy const &); -}; - -class ACLUrlPort -{ - -private: - static ACL::Prototype RegistryProtoype; - static ACLStrategised RegistryEntry_; }; #endif /* SQUID_ACLURLPORT_H */ diff --git a/src/acl/forward.h b/src/acl/forward.h index 755f340d8e..5d425b9725 100644 --- a/src/acl/forward.h +++ b/src/acl/forward.h @@ -29,6 +29,9 @@ class AndNode; class OrNode; class Tree; +/// prepares to parse ACLs configuration +void Init(void); + } // namespace Acl class allow_t; diff --git a/src/auth/AclMaxUserIp.cc b/src/auth/AclMaxUserIp.cc index 5ee8110e5c..71ff3e3ce5 100644 --- a/src/auth/AclMaxUserIp.cc +++ b/src/auth/AclMaxUserIp.cc @@ -18,24 +18,11 @@ #include "Parsing.h" #include "wordlist.h" -ACLFlag ACLMaxUserIP::SupportedFlags[] = {ACL_F_STRICT, ACL_F_END}; - ACLMaxUserIP::ACLMaxUserIP(char const *theClass) : - ACL(SupportedFlags), class_(theClass), maximum(0) {} -ACLMaxUserIP::ACLMaxUserIP(ACLMaxUserIP const &old) : - class_(old.class_), - maximum(old.maximum) -{ - flags = old.flags; -} - -ACLMaxUserIP::~ACLMaxUserIP() -{} - ACL * ACLMaxUserIP::clone() const { @@ -60,6 +47,15 @@ ACLMaxUserIP::valid() const return maximum > 0; } +const Acl::Options & +ACLMaxUserIP::options() +{ + static const Acl::BooleanOption BeStrict; + static const Acl::Options MyOptions = { { "-s", &BeStrict } }; + BeStrict.linkWith(&beStrict); + return MyOptions; +} + void ACLMaxUserIP::parse() { @@ -102,7 +98,7 @@ ACLMaxUserIP::match(Auth::UserRequest::Pointer auth_user_request, Ip::Address co debugs(28, DBG_IMPORTANT, "aclMatchUserMaxIP: user '" << auth_user_request->username() << "' tries to use too many IP addresses (max " << maximum << " allowed)!"); /* this is a match */ - if (flags.isSet(ACL_F_STRICT)) { + if (beStrict) { /* * simply deny access - the user name is already associated with * the request diff --git a/src/auth/AclMaxUserIp.h b/src/auth/AclMaxUserIp.h index 3487e23859..c485324743 100644 --- a/src/auth/AclMaxUserIp.h +++ b/src/auth/AclMaxUserIp.h @@ -12,7 +12,6 @@ #if USE_AUTH #include "acl/Acl.h" -#include "acl/Checklist.h" #include "auth/UserRequest.h" class ACLMaxUserIP : public ACL @@ -20,13 +19,11 @@ class ACLMaxUserIP : public ACL MEMPROXY_CLASS(ACLMaxUserIP); public: - ACLMaxUserIP(char const *theClass); - ACLMaxUserIP(ACLMaxUserIP const &old); - ~ACLMaxUserIP(); - ACLMaxUserIP &operator =(ACLMaxUserIP const &); + explicit ACLMaxUserIP(char const *theClass); virtual ACL *clone() const; virtual char const *typeString() const; + virtual const Acl::Options &options(); virtual void parse(); virtual int match(ACLChecklist *cl); virtual SBufList dump() const; @@ -36,14 +33,13 @@ public: int getMaximum() const {return maximum;} - bool getStrict() const {return flags.isSet(ACL_F_STRICT);} - private: - static Prototype RegistryProtoype; - static ACLMaxUserIP RegistryEntry_; - static ACLFlag SupportedFlags[]; - int match(Auth::UserRequest::Pointer auth_user_request, Ip::Address const &src_addr); + +public: + Acl::BooleanOptionValue beStrict; ///< Enforce "one user, one device" policy? + +private: char const *class_; int maximum; }; diff --git a/src/auth/AclProxyAuth.cc b/src/auth/AclProxyAuth.cc index 5763643da4..e81af5ae90 100644 --- a/src/auth/AclProxyAuth.cc +++ b/src/auth/AclProxyAuth.cc @@ -50,6 +50,12 @@ ACLProxyAuth::typeString() const return type_; } +void +ACLProxyAuth::parseFlags() +{ + ParseFlags(Acl::NoOptions(), data->supportedFlags()); +} + void ACLProxyAuth::parse() { diff --git a/src/auth/AclProxyAuth.h b/src/auth/AclProxyAuth.h index 59db9370b0..0901f1da3d 100644 --- a/src/auth/AclProxyAuth.h +++ b/src/auth/AclProxyAuth.h @@ -37,24 +37,20 @@ public: ACLProxyAuth(ACLProxyAuth const &); ACLProxyAuth &operator =(ACLProxyAuth const &); + /* ACL API */ virtual char const *typeString() const; virtual void parse(); virtual bool isProxyAuth() const {return true;} - + virtual void parseFlags(); virtual int match(ACLChecklist *checklist); virtual SBufList dump() const; virtual bool valid() const; virtual bool empty() const; virtual bool requiresRequest() const {return true;} - virtual ACL *clone() const; virtual int matchForCache(ACLChecklist *checklist); private: - static Prototype UserRegistryProtoype; - static ACLProxyAuth UserRegistryEntry_; - static Prototype RegexRegistryProtoype; - static ACLProxyAuth RegexRegistryEntry_; int matchProxyAuth(ACLChecklist *); ACLData *data; char const *type_; diff --git a/src/base/CharacterSet.cc b/src/base/CharacterSet.cc index 8bf088425c..14173b010c 100644 --- a/src/base/CharacterSet.cc +++ b/src/base/CharacterSet.cc @@ -97,6 +97,15 @@ CharacterSet::CharacterSet(const char *label, std::initializer_list(idx); + } +} + CharacterSet operator+ (CharacterSet lhs, const CharacterSet &rhs) { diff --git a/src/base/CharacterSet.h b/src/base/CharacterSet.h index 1c1cfc6ed8..2f9490de83 100644 --- a/src/base/CharacterSet.h +++ b/src/base/CharacterSet.h @@ -19,9 +19,8 @@ class CharacterSet public: typedef std::vector Storage; - /// define a character set with the given label ("anonymous" if nullptr) - /// with specified initial contents - CharacterSet(const char *label, const char * const initial); + /// a character set with a given label and contents + explicit CharacterSet(const char *label = "anonymous", const char * const chars = ""); /// define a character set with the given label ("anonymous" if nullptr) /// containing characters defined in the supplied ranges @@ -33,6 +32,9 @@ public: /// \see addRange CharacterSet(const char *label, std::initializer_list> ranges); + /// whether the set lacks any members + bool isEmpty() const { return chars_.empty(); } + /// whether a given character exists in the set bool operator[](unsigned char c) const {return chars_[static_cast(c)] != 0;} @@ -60,6 +62,9 @@ public: /// \note Ignores label bool operator != (const CharacterSet &cs) const { return !operator==(cs); } + /// prints all chars in arbitrary order, without any quoting/escaping + void printChars(std::ostream &os) const; + /// optional set label for debugging (default: "anonymous") const char * name; diff --git a/src/cache_cf.cc b/src/cache_cf.cc index 815199a4c7..1ff67e067a 100644 --- a/src/cache_cf.cc +++ b/src/cache_cf.cc @@ -567,8 +567,9 @@ parseOneConfigFile(const char *file_name, unsigned int depth) return err_count; } +static int -parseConfigFile(const char *file_name) +parseConfigFileOrThrow(const char *file_name) { int err_count = 0; @@ -609,6 +610,20 @@ parseConfigFile(const char *file_name) return err_count; } +// TODO: Refactor main.cc to centrally handle (and report) all exceptions. +int +parseConfigFile(const char *file_name) +{ + try { + return parseConfigFileOrThrow(file_name); + } + catch (const std::exception &ex) { + debugs(3, DBG_CRITICAL, "FATAL: bad configuration: " << ex.what()); + self_destruct(); + return 1; // not reached + } +} + static void configDoConfigure(void) { @@ -1342,12 +1357,14 @@ dump_acl(StoreEntry * entry, const char *name, ACL * ae) { while (ae != NULL) { debugs(3, 3, "dump_acl: " << name << " " << ae->name); - storeAppendPrintf(entry, "%s %s %s %s ", + storeAppendPrintf(entry, "%s %s %s ", name, ae->name, - ae->typeString(), - ae->flags.flagsStr()); - dump_SBufList(entry, ae->dump()); + ae->typeString()); + SBufList tail; + tail.splice(tail.end(), ae->dumpOptions()); + tail.splice(tail.end(), ae->dump()); // ACL parameters + dump_SBufList(entry, tail); ae = ae->next; } } diff --git a/src/external_acl.cc b/src/external_acl.cc index c8c08fee81..f560af5c74 100644 --- a/src/external_acl.cc +++ b/src/external_acl.cc @@ -1149,17 +1149,6 @@ ExternalACLLookup::LookupDone(void *data, const ExternalACLEntryPointer &result) checklist->resumeNonBlockingCheck(ExternalACLLookup::Instance()); } -/* This registers "external" in the registry. To do dynamic definitions - * of external ACL's, rather than a static prototype, have a Prototype instance - * prototype in the class that defines each external acl 'class'. - * Then, then the external acl instance is created, it self registers under - * it's name. - * Be sure that clone is fully functional for that acl class though! - */ -ACL::Prototype ACLExternal::RegistryProtoype(&ACLExternal::RegistryEntry_, "external"); - -ACLExternal ACLExternal::RegistryEntry_("external"); - ACL * ACLExternal::clone() const { diff --git a/src/ident/AclIdent.cc b/src/ident/AclIdent.cc index d838a4dc19..d4dedbac4b 100644 --- a/src/ident/AclIdent.cc +++ b/src/ident/AclIdent.cc @@ -46,6 +46,12 @@ ACLIdent::typeString() const return type_; } +void +ACLIdent::parseFlags() +{ + ParseFlags(Acl::NoOptions(), data->supportedFlags()); +} + void ACLIdent::parse() { diff --git a/src/ident/AclIdent.h b/src/ident/AclIdent.h index 37310b3d8d..287430aed2 100644 --- a/src/ident/AclIdent.h +++ b/src/ident/AclIdent.h @@ -40,20 +40,17 @@ public: ACLIdent & operator= (ACLIdent const &rhs); ~ACLIdent(); + /* ACL API */ virtual char const *typeString() const; virtual void parse(); virtual bool isProxyAuth() const {return true;} - + virtual void parseFlags(); virtual int match(ACLChecklist *checklist); virtual SBufList dump() const; virtual bool empty () const; virtual ACL *clone()const; private: - static Prototype UserRegistryProtoype; - static ACLIdent UserRegistryEntry_; - static Prototype RegexRegistryProtoype; - static ACLIdent RegexRegistryEntry_; ACLData *data; char const *type_; }; diff --git a/src/main.cc b/src/main.cc index 12f326caeb..31bc257542 100644 --- a/src/main.cc +++ b/src/main.cc @@ -10,8 +10,9 @@ #include "squid.h" #include "AccessLogEntry.h" -#include "acl/Acl.h" +//#include "acl/Acl.h" #include "acl/Asn.h" +#include "acl/forward.h" #include "anyp/UriScheme.h" #include "auth/Config.h" #include "auth/Gadgets.h" @@ -1556,6 +1557,7 @@ SquidMain(int argc, char **argv) /* we may want the parsing process to set this up in the future */ Store::Init(); + Acl::Init(); Auth::Init(); /* required for config parsing. NOP if !USE_AUTH */ Ip::ProbeTransport(); // determine IPv4 or IPv6 capabilities before parsing. diff --git a/src/snmp_core.cc b/src/snmp_core.cc index 69b3686353..4965278c72 100644 --- a/src/snmp_core.cc +++ b/src/snmp_core.cc @@ -1130,51 +1130,9 @@ oid2addr(oid * id, Ip::Address &addr, u_int size) addr = i6addr; } -/* SNMP checklists */ -#include "acl/Strategised.h" -#include "acl/Strategy.h" -#include "acl/StringData.h" - -class ACLSNMPCommunityStrategy : public ACLStrategy -{ - -public: - virtual int match (ACLData * &, ACLFilledChecklist *, ACLFlags &); - static ACLSNMPCommunityStrategy *Instance(); - /* Not implemented to prevent copies of the instance. */ - /* Not private to prevent brain dead g++ warnings about - * private constructors with no friends */ - ACLSNMPCommunityStrategy(ACLSNMPCommunityStrategy const &); - -private: - static ACLSNMPCommunityStrategy Instance_; - ACLSNMPCommunityStrategy() {} - - ACLSNMPCommunityStrategy&operator=(ACLSNMPCommunityStrategy const &); -}; - -class ACLSNMPCommunity -{ - -private: - static ACL::Prototype RegistryProtoype; - static ACLStrategised RegistryEntry_; -}; - -ACL::Prototype ACLSNMPCommunity::RegistryProtoype(&ACLSNMPCommunity::RegistryEntry_, "snmp_community"); -ACLStrategised ACLSNMPCommunity::RegistryEntry_(new ACLStringData, ACLSNMPCommunityStrategy::Instance(), "snmp_community"); - int -ACLSNMPCommunityStrategy::match (ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &) +ACLSNMPCommunityStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) { return data->match (checklist->snmp_community); } -ACLSNMPCommunityStrategy * -ACLSNMPCommunityStrategy::Instance() -{ - return &Instance_; -} - -ACLSNMPCommunityStrategy ACLSNMPCommunityStrategy::Instance_; - diff --git a/src/snmp_core.h b/src/snmp_core.h index 541aa281ab..ed89ef8a9d 100644 --- a/src/snmp_core.h +++ b/src/snmp_core.h @@ -11,6 +11,7 @@ #ifndef SQUID_SNMP_CORE_H #define SQUID_SNMP_CORE_H +#include "acl/Strategy.h" #include "cache_snmp.h" #include "comm/forward.h" #include "ip/forward.h" @@ -51,5 +52,11 @@ const char * snmpDebugOid(oid * Name, snint Len, MemBuf &outbuf); void addr2oid(Ip::Address &addr, oid *Dest); void oid2addr(oid *Dest, Ip::Address &addr, u_int code); +class ACLSNMPCommunityStrategy: public ACLStrategy +{ +public: + virtual int match (ACLData *&data, ACLFilledChecklist *checklist) override; +}; + #endif /* SQUID_SNMP_CORE_H */ diff --git a/src/tests/stub_libauth_acls.cc b/src/tests/stub_libauth_acls.cc index d978d51b7d..487ef979cf 100644 --- a/src/tests/stub_libauth_acls.cc +++ b/src/tests/stub_libauth_acls.cc @@ -20,8 +20,6 @@ allow_t AuthenticateAcl(ACLChecklist *) STUB_RETVAL(ACCESS_DENIED) #include "auth/AclMaxUserIp.h" ACL * ACLMaxUserIP::clone() const STUB_RETVAL(NULL) ACLMaxUserIP::ACLMaxUserIP (char const *) STUB -ACLMaxUserIP::ACLMaxUserIP (ACLMaxUserIP const &) STUB -ACLMaxUserIP::~ACLMaxUserIP() STUB char const * ACLMaxUserIP::typeString() const STUB_RETVAL(NULL) bool ACLMaxUserIP::empty () const STUB_RETVAL(false) bool ACLMaxUserIP::valid () const STUB_RETVAL(false) @@ -29,6 +27,7 @@ void ACLMaxUserIP::parse() STUB int ACLMaxUserIP::match(Auth::UserRequest::Pointer, Ip::Address const &) STUB_RETVAL(0) int ACLMaxUserIP::match(ACLChecklist *) STUB_RETVAL(0) SBufList ACLMaxUserIP::dump() const STUB_RETVAL(SBufList()) +const Acl::Options &ACLMaxUserIP::options() STUB_RETVAL(Acl::NoOptions()) #include "auth/AclProxyAuth.h" ACLProxyAuth::~ACLProxyAuth() STUB @@ -47,6 +46,7 @@ void ProxyAuthLookup::LookupDone(void *) STUB ACL * ACLProxyAuth::clone() const STUB_RETVAL(NULL) int ACLProxyAuth::matchForCache(ACLChecklist *) STUB_RETVAL(0) int ACLProxyAuth::matchProxyAuth(ACLChecklist *) STUB_RETVAL(0) +void ACLProxyAuth::parseFlags() STUB #endif /* USE_AUTH */ diff --git a/src/tests/testACLMaxUserIP.cc b/src/tests/testACLMaxUserIP.cc index 9185a4b8c2..e1245f7709 100644 --- a/src/tests/testACLMaxUserIP.cc +++ b/src/tests/testACLMaxUserIP.cc @@ -10,7 +10,9 @@ #if USE_AUTH +#include "acl/Acl.h" #include "auth/AclMaxUserIp.h" +#include "auth/UserRequest.h" #include "ConfigParser.h" #include "testACLMaxUserIP.h" #include "unitTestMain.h" @@ -26,13 +28,17 @@ testACLMaxUserIP::testDefaults() /* 0 is not a valid maximum, so we start at 0 */ CPPUNIT_ASSERT_EQUAL(0,anACL.getMaximum()); /* and we have no option to turn strict OFF, so start ON. */ - CPPUNIT_ASSERT_EQUAL(false,anACL.getStrict()); + CPPUNIT_ASSERT_EQUAL(false, static_cast(anACL.beStrict)); /* an unparsed acl must not be valid - there is no sane default */ CPPUNIT_ASSERT_EQUAL(false,anACL.valid()); } -ACL::Prototype ACLMaxUserIP::RegistryProtoype(&ACLMaxUserIP::RegistryEntry_, "max_user_ip"); -ACLMaxUserIP ACLMaxUserIP::RegistryEntry_("max_user_ip"); +void +testACLMaxUserIP::setUp() +{ + CPPUNIT_NS::TestFixture::setUp(); + Acl::RegisterMaker("max_user_ip", [](Acl::TypeName name)->ACL* { return new ACLMaxUserIP(name); }); +} void testACLMaxUserIP::testParseLine() @@ -49,7 +55,7 @@ testACLMaxUserIP::testParseLine() if (maxUserIpACL) { /* we want a maximum of one, and strict to be true */ CPPUNIT_ASSERT_EQUAL(1, maxUserIpACL->getMaximum()); - CPPUNIT_ASSERT_EQUAL(true, maxUserIpACL->getStrict()); + CPPUNIT_ASSERT_EQUAL(true, static_cast(maxUserIpACL->beStrict)); /* the acl must be vaid */ CPPUNIT_ASSERT_EQUAL(true, maxUserIpACL->valid()); } diff --git a/src/tests/testACLMaxUserIP.h b/src/tests/testACLMaxUserIP.h index d57d3d1bb3..936f81dd8f 100644 --- a/src/tests/testACLMaxUserIP.h +++ b/src/tests/testACLMaxUserIP.h @@ -27,6 +27,7 @@ class testACLMaxUserIP : public CPPUNIT_NS::TestFixture CPPUNIT_TEST_SUITE_END(); public: + virtual void setUp() override; protected: void testDefaults();