From 33810b1da0e66536755dd31ad95a0aabf2167858 Mon Sep 17 00:00:00 2001 From: Christos Tsantilas Date: Sun, 27 Jan 2013 19:35:07 +0200 Subject: [PATCH] No-lookup DNS ACLs Currently, dst, dstdom, dstdom_regex (and other?) DNS-related ACLs do DNS lookups if such a lookup is needed to convert an IP address into a domain name or vice versa. This creates two kinds of problems: - It is difficult to identify requests that use raw IP addresses in Request-URI or Host headers. One would have to use something like url_regex and possibly req_header to identify those before using dst ACLs to match the request destination against a known IP subnet. IPv6 would only make this harder. - It is difficult to use dst* ACLs in options that support fast ACLs only. If an async lookup is required, the answer will be unpredictable (now) or DUNNO (when the ACL bugs are fixed), possibly with warnings and other complications. This patch adds a -n option to dst, dstdom, dstdom_regex and other DNS-related ACLs. The option disable lookups and address type conversions. If lookup or conversion is required because the parameter type (IP or domain name) does not match the message address type (domain name or IP), then the ACL with a -n option would immediately declare a mismatch without any warnings or lookups. The "--" option can be used to stop processing all options, in the case the first acl value has '-' character as first character (for example the '-' is a valid domain name) For example: # Matches requests with full URI host set to localhost # but not requests with full URI host set to 127.0.0.1 acl toLocalRawName dstdom -n localhost http_access allow toLocalRawName # Use -- option to stop processing flags acl AnACL dst_domain -n -- -cream-and-sugar.tumblr.com # Matches requests with full URI host set to 127.0.0.1 # but not requests with full URI host set to localhost acl toLocalRawIp dst -n 127.0.0.1/32 cache_peer_access peer1 allow toLocalRawIp Please note that -n prohibits lookups in Squid's DNS caches as well. This is a Measurement Factory project --- src/AclRegs.cc | 6 ++- src/ConfigParser.cc | 30 ++++++++++++++- src/ConfigParser.h | 9 +++++ src/acl/Acl.cc | 66 ++++++++++++++++++++++++++++++++- src/acl/Acl.h | 45 ++++++++++++++++++++++ src/acl/Asn.cc | 4 +- src/acl/Certificate.cc | 2 +- src/acl/Certificate.h | 2 +- src/acl/DestinationAsn.h | 2 +- src/acl/DestinationDomain.cc | 7 +++- src/acl/DestinationDomain.h | 2 +- src/acl/DestinationIp.cc | 13 +++++++ src/acl/DestinationIp.h | 2 + src/acl/HierCode.cc | 2 +- src/acl/HierCode.h | 2 +- src/acl/HttpRepHeader.cc | 2 +- src/acl/HttpRepHeader.h | 2 +- src/acl/HttpReqHeader.cc | 2 +- src/acl/HttpReqHeader.h | 2 +- src/acl/Ip.cc | 9 ++++- src/acl/Ip.h | 2 + src/acl/LocalPort.cc | 2 +- src/acl/LocalPort.h | 2 +- src/acl/Method.cc | 2 +- src/acl/Method.h | 2 +- src/acl/MyPortName.cc | 2 +- src/acl/MyPortName.h | 2 +- src/acl/PeerName.cc | 2 +- src/acl/PeerName.h | 2 +- src/acl/Protocol.cc | 2 +- src/acl/Protocol.h | 2 +- src/acl/ReplyHeaderStrategy.h | 4 +- src/acl/ReplyMimeType.h | 2 +- src/acl/RequestHeaderStrategy.h | 4 +- src/acl/RequestMimeType.h | 2 +- src/acl/ServerCertificate.cc | 2 +- src/acl/ServerCertificate.h | 2 +- src/acl/SourceAsn.h | 2 +- src/acl/SourceDomain.cc | 2 +- src/acl/SourceDomain.h | 2 +- src/acl/SslError.cc | 2 +- src/acl/SslError.h | 2 +- src/acl/Strategised.h | 6 +-- src/acl/Strategy.h | 3 +- src/acl/Tag.cc | 2 +- src/acl/Tag.h | 2 +- src/acl/Time.cc | 2 +- src/acl/Time.h | 2 +- src/acl/Url.cc | 2 +- src/acl/Url.h | 2 +- src/acl/UrlLogin.cc | 2 +- src/acl/UrlLogin.h | 2 +- src/acl/UrlPath.cc | 2 +- src/acl/UrlPath.h | 2 +- src/acl/UrlPort.cc | 2 +- src/acl/UrlPort.h | 2 +- src/cache_cf.cc | 5 ++- src/external_acl.cc | 2 +- src/snmp_core.cc | 4 +- 59 files changed, 238 insertions(+), 65 deletions(-) diff --git a/src/AclRegs.cc b/src/AclRegs.cc index c84ff9bef2..fb112f18ba 100644 --- a/src/AclRegs.cc +++ b/src/AclRegs.cc @@ -80,10 +80,12 @@ 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"); +ACLStrategised ACLDestinationDomain::LiteralRegistryEntry_(new ACLDomainData, ACLDestinationDomainStrategy::Instance(), "dstdomain", DestinationDomainFlags); ACL::Prototype ACLDestinationDomain::RegexRegistryProtoype(&ACLDestinationDomain::RegexRegistryEntry_, "dstdom_regex"); -ACLStrategised ACLDestinationDomain::RegexRegistryEntry_(new ACLRegexData,ACLDestinationDomainStrategy::Instance() ,"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 diff --git a/src/ConfigParser.cc b/src/ConfigParser.cc index 7c81e44256..ceac61590a 100644 --- a/src/ConfigParser.cc +++ b/src/ConfigParser.cc @@ -38,6 +38,9 @@ #include "fatal.h" #include "globals.h" +char *ConfigParser::lastToken = NULL; +std::queue ConfigParser::undo; + void ConfigParser::destruct() { @@ -46,15 +49,38 @@ ConfigParser::destruct() cfg_filename, config_lineno, config_input_line); } +void +ConfigParser::strtokFileUndo() +{ + assert(lastToken); + undo.push(lastToken); +} + +void +ConfigParser::strtokFilePutBack(const char *tok) +{ + assert(tok); + undo.push(tok); +} + char * ConfigParser::strtokFile(void) { static int fromFile = 0; static FILE *wordFile = NULL; + LOCAL_ARRAY(char, undoToken, CONFIG_LINE_LIMIT); char *t, *fn; LOCAL_ARRAY(char, buf, CONFIG_LINE_LIMIT); + if (!undo.empty()) { + strncpy(undoToken, undo.front().c_str(), sizeof(undoToken)); + undoToken[sizeof(undoToken) - 1] = '\0'; + undo.pop(); + return undoToken; + } + + lastToken = NULL; do { if (!fromFile) { @@ -82,7 +108,7 @@ ConfigParser::strtokFile(void) fromFile = 1; } else { - return t; + return lastToken = t; } } @@ -113,7 +139,7 @@ ConfigParser::strtokFile(void) /* skip blank lines */ } while ( *t == '#' || !*t ); - return t; + return lastToken = t; } void diff --git a/src/ConfigParser.h b/src/ConfigParser.h index b3d778f3d2..c5807d8f5f 100644 --- a/src/ConfigParser.h +++ b/src/ConfigParser.h @@ -35,6 +35,10 @@ #define SQUID_CONFIGPARSER_H #include "SquidString.h" +#include +#if HAVE_STRING +#include +#endif class wordlist; /** @@ -76,6 +80,11 @@ public: static const char *QuoteString(String &var); static void ParseWordList(wordlist **list); static char * strtokFile(); + static void strtokFileUndo(); + static void strtokFilePutBack(const char *); +private: + static char *lastToken; + static std::queue undo; }; int parseConfigFile(const char *file_name); diff --git a/src/acl/Acl.cc b/src/acl/Acl.cc index 5043159ef8..68bd743b79 100644 --- a/src/acl/Acl.cc +++ b/src/acl/Acl.cc @@ -33,14 +33,70 @@ #include "acl/Acl.h" #include "acl/Checklist.h" #include "anyp/PortCfg.h" +#include "cache_cf.h" #include "ConfigParser.h" #include "Debug.h" #include "dlink.h" #include "globals.h" #include "SquidConfig.h" +const ACLFlag ACLFlags::NoFlags[1] = {ACL_F_END}; + const char *AclMatchedName = NULL; +bool ACLFlags::supported(const ACLFlag f) const +{ + if (f == ACL_F_REGEX_CASE) + return true; + return (supported_.find(f) != std::string::npos); +} + +void +ACLFlags::parseFlags(char * &nextToken) +{ + while((nextToken = ConfigParser::strtokFile()) != NULL && nextToken[0] == '-') { + + //if token is the "--" break flag + if (strcmp(nextToken, "--") == 0) + break; + + for (const char *flg = nextToken+1; *flg!='\0'; flg++ ) { + if (supported(*flg)) { + makeSet(*flg); + } + else { + debugs(28, 0, HERE << "Flag '" << *flg << "' not supported"); + self_destruct(); + } + } + } + + /*Regex code needs to parse -i file*/ + if ( isSet(ACL_F_REGEX_CASE)) + ConfigParser::strtokFilePutBack("-i"); + + if (nextToken != NULL && strcmp(nextToken, "--") != 0 ) + ConfigParser::strtokFileUndo(); +} + +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; +} + void * ACL::operator new (size_t byteCount) { @@ -180,6 +236,9 @@ ACL::ParseAclLine(ConfigParser &parser, ACL ** head) */ AclMatchedName = A->name; /* ugly */ + char *aTok; + A->flags.parseFlags(aTok); + /*split the function here */ A->parse(); @@ -425,8 +484,11 @@ 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)) - return (*i)->prototype->clone(); + 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"); diff --git a/src/acl/Acl.h b/src/acl/Acl.h index 8919e51d57..0727ef9c9e 100644 --- a/src/acl/Acl.h +++ b/src/acl/Acl.h @@ -42,11 +42,54 @@ #if HAVE_OSTREAM #include #endif +#if HAVE_STRING +#include +#endif class ConfigParser; class ACLChecklist; class ACLList; +typedef char ACLFlag; +// ACLData Flags +#define ACL_F_REGEX_CASE 'i' +#define ACL_F_NO_LOOKUP 'n' +#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: + explicit ACLFlags(const ACLFlag flags[]) : supported_(flags), flags_(0) {} + ACLFlags() : flags_(0) {} + bool supported(const ACLFlag f) const; ///< True if the given flag supported + void makeSet(const ACLFlag f) { flags_ |= flagToInt(f); } ///< Set the given flag + /// Return true if the given flag is set + bool isSet(const ACLFlag f) const { return flags_ & flagToInt(f);} + /// Parse a flags given in the form -[A..Z|a..z] + void parseFlags(char * &nextToken); + const char *flagsStr() const; ///< Convert the flags to a string representation + +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')); + } + + std::string supported_; ///< The supported character flags + uint64_t flags_; ///< The flags which is set +public: + static const ACLFlag NoFlags[1]; ///< An empty flags list +}; + /// \ingroup ACLAPI class ACL { @@ -61,6 +104,7 @@ public: static ACL* FindByName(const char *name); ACL(); + explicit ACL(const ACLFlag flgs[]) : cfgline(NULL), flags(flgs){} virtual ~ACL(); virtual ACL *clone()const = 0; virtual void parse() = 0; @@ -82,6 +126,7 @@ public: char name[ACL_NAME_SZ]; char *cfgline; ACL *next; + ACLFlags flags; ///< The list of given ACL flags public: diff --git a/src/acl/Asn.cc b/src/acl/Asn.cc index f2ba623650..b799c9ef24 100644 --- a/src/acl/Asn.cc +++ b/src/acl/Asn.cc @@ -609,7 +609,7 @@ ACL::Prototype ACLASN::DestinationRegistryProtoype(&ACLASN::DestinationRegistryE ACLStrategised ACLASN::DestinationRegistryEntry_(new ACLASN, ACLDestinationASNStrategy::Instance(), "dst_as"); int -ACLSourceASNStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) +ACLSourceASNStrategy::match (ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &) { return data->match(checklist->src_addr); } @@ -623,7 +623,7 @@ ACLSourceASNStrategy::Instance() ACLSourceASNStrategy ACLSourceASNStrategy::Instance_; int -ACLDestinationASNStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) +ACLDestinationASNStrategy::match (ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &) { const ipcache_addrs *ia = ipcache_gethostbyname(checklist->request->GetHost(), IP_LOOKUP_IF_MISS); diff --git a/src/acl/Certificate.cc b/src/acl/Certificate.cc index ad39cfc0b8..16b0ca997d 100644 --- a/src/acl/Certificate.cc +++ b/src/acl/Certificate.cc @@ -48,7 +48,7 @@ #include "globals.h" int -ACLCertificateStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) +ACLCertificateStrategy::match (ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &) { const int fd = checklist->fd(); const bool goodDescriptor = 0 <= fd && fd <= Biggest_FD; diff --git a/src/acl/Certificate.h b/src/acl/Certificate.h index 56db4fb800..b9d0d0da16 100644 --- a/src/acl/Certificate.h +++ b/src/acl/Certificate.h @@ -44,7 +44,7 @@ class ACLCertificateStrategy : public ACLStrategy { public: - virtual int match (ACLData * &, ACLFilledChecklist *); + 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 diff --git a/src/acl/DestinationAsn.h b/src/acl/DestinationAsn.h index 1df42699e2..078b82a9fd 100644 --- a/src/acl/DestinationAsn.h +++ b/src/acl/DestinationAsn.h @@ -41,7 +41,7 @@ class ACLDestinationASNStrategy : public ACLStrategy { public: - virtual int match (ACLData * &, ACLFilledChecklist *); + virtual int match (ACLData * &, ACLFilledChecklist *, ACLFlags &); virtual bool requiresRequest() const {return true;} static ACLDestinationASNStrategy *Instance(); diff --git a/src/acl/DestinationDomain.cc b/src/acl/DestinationDomain.cc index bcc4aef3d2..82c1e3dea1 100644 --- a/src/acl/DestinationDomain.cc +++ b/src/acl/DestinationDomain.cc @@ -71,7 +71,7 @@ DestinationDomainLookup::LookupDone(const char *fqdn, const DnsLookupDetails &de } int -ACLDestinationDomainStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) +ACLDestinationDomainStrategy::match (ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &flags) { assert(checklist != NULL && checklist->request != NULL); @@ -79,6 +79,11 @@ ACLDestinationDomainStrategy::match (ACLData * &data, ACLFilledCheckl return 1; } + if (flags.isSet(ACL_F_NO_LOOKUP)) { + debugs(28, 3, "aclMatchAcl: No-lookup DNS ACL '" << AclMatchedName << "' for '" << checklist->request->GetHost() << "'"); + return 0; + } + /* numeric IPA? no, trust the above result. */ if (checklist->request->GetHostIsNumeric() == 0) { return 0; diff --git a/src/acl/DestinationDomain.h b/src/acl/DestinationDomain.h index 05c09be335..d772521fd6 100644 --- a/src/acl/DestinationDomain.h +++ b/src/acl/DestinationDomain.h @@ -43,7 +43,7 @@ class ACLDestinationDomainStrategy : public ACLStrategy { public: - virtual int match (ACLData * &, ACLFilledChecklist *); + virtual int match (ACLData * &, ACLFilledChecklist *, ACLFlags &); static ACLDestinationDomainStrategy *Instance(); virtual bool requiresRequest() const {return true;} diff --git a/src/acl/DestinationIp.cc b/src/acl/DestinationIp.cc index 721fc0dd32..2dfc602ea3 100644 --- a/src/acl/DestinationIp.cc +++ b/src/acl/DestinationIp.cc @@ -39,6 +39,8 @@ #include "HttpRequest.h" #include "SquidConfig.h" +ACLFlag ACLDestinationIP::SupportedFlags[] = {ACL_F_NO_LOOKUP, ACL_F_END}; + char const * ACLDestinationIP::typeString() const { @@ -59,6 +61,17 @@ ACLDestinationIP::match(ACLChecklist *cl) return ACLIP::match(checklist->conn()->clientConnection->local); } + if (flags.isSet(ACL_F_NO_LOOKUP)) { + if (!checklist->request->GetHostIsNumeric()) { + debugs(28, 3, "aclMatchAcl: No-lookup DNS ACL '" << AclMatchedName << "' for '" << checklist->request->GetHost() << "'"); + return 0; + } + + if(ACLIP::match(checklist->request->host_addr)) + return 1; + return 0; + } + const ipcache_addrs *ia = ipcache_gethostbyname(checklist->request->GetHost(), IP_LOOKUP_IF_MISS); if (ia) { diff --git a/src/acl/DestinationIp.h b/src/acl/DestinationIp.h index 24521a44a3..f58cf3ffd5 100644 --- a/src/acl/DestinationIp.h +++ b/src/acl/DestinationIp.h @@ -55,12 +55,14 @@ class ACLDestinationIP : public ACLIP public: MEMPROXY_CLASS(ACLDestinationIP); + ACLDestinationIP(): ACLIP(ACLDestinationIP::SupportedFlags) {} virtual char const *typeString() const; virtual int match(ACLChecklist *checklist); virtual bool requiresRequest() const {return true;} virtual ACL *clone()const; + static ACLFlag SupportedFlags[]; private: static Prototype RegistryProtoype; static ACLDestinationIP RegistryEntry_; diff --git a/src/acl/HierCode.cc b/src/acl/HierCode.cc index 3072ca4e19..c691e78e51 100644 --- a/src/acl/HierCode.cc +++ b/src/acl/HierCode.cc @@ -9,7 +9,7 @@ template class ACLStrategised; int -ACLHierCodeStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) +ACLHierCodeStrategy::match (ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &) { return data->match (checklist->request->hier.code); } diff --git a/src/acl/HierCode.h b/src/acl/HierCode.h index 60661e7f76..ac9aac8d2a 100644 --- a/src/acl/HierCode.h +++ b/src/acl/HierCode.h @@ -10,7 +10,7 @@ class ACLHierCodeStrategy : public ACLStrategy { public: - virtual int match (ACLData * &, ACLFilledChecklist *); + virtual int match (ACLData * &, ACLFilledChecklist *, ACLFlags &); virtual bool requiresRequest() const {return true;} static ACLHierCodeStrategy *Instance(); diff --git a/src/acl/HttpRepHeader.cc b/src/acl/HttpRepHeader.cc index 58fe358377..d14daa2908 100644 --- a/src/acl/HttpRepHeader.cc +++ b/src/acl/HttpRepHeader.cc @@ -38,7 +38,7 @@ #include "HttpReply.h" int -ACLHTTPRepHeaderStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) +ACLHTTPRepHeaderStrategy::match (ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &) { return data->match (&checklist->reply->header); } diff --git a/src/acl/HttpRepHeader.h b/src/acl/HttpRepHeader.h index d40108dcd7..1f019058a5 100644 --- a/src/acl/HttpRepHeader.h +++ b/src/acl/HttpRepHeader.h @@ -42,7 +42,7 @@ class ACLHTTPRepHeaderStrategy : public ACLStrategy { public: - virtual int match (ACLData * &, ACLFilledChecklist *); + virtual int match (ACLData * &, ACLFilledChecklist *, ACLFlags &); virtual bool requiresReply() const { return true; } static ACLHTTPRepHeaderStrategy *Instance(); diff --git a/src/acl/HttpReqHeader.cc b/src/acl/HttpReqHeader.cc index 043464e4d9..49c701b04d 100644 --- a/src/acl/HttpReqHeader.cc +++ b/src/acl/HttpReqHeader.cc @@ -38,7 +38,7 @@ #include "HttpRequest.h" int -ACLHTTPReqHeaderStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) +ACLHTTPReqHeaderStrategy::match (ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &) { return data->match (&checklist->request->header); } diff --git a/src/acl/HttpReqHeader.h b/src/acl/HttpReqHeader.h index 584a2904dd..e805207ebe 100644 --- a/src/acl/HttpReqHeader.h +++ b/src/acl/HttpReqHeader.h @@ -42,7 +42,7 @@ class ACLHTTPReqHeaderStrategy : public ACLStrategy { public: - virtual int match (ACLData * &, ACLFilledChecklist *); + virtual int match (ACLData * &, ACLFilledChecklist *, ACLFlags &); virtual bool requiresRequest() const { return true; } static ACLHTTPReqHeaderStrategy *Instance(); diff --git a/src/acl/Ip.cc b/src/acl/Ip.cc index 578fca9628..9d599ea5ad 100644 --- a/src/acl/Ip.cc +++ b/src/acl/Ip.cc @@ -509,7 +509,12 @@ ACLIP::parse() { char *t = NULL; - while ((t = strtokFile())) { + flags.parseFlags(t); + + if (!t) + return; + + do { acl_ip_data *q = acl_ip_data::FactoryParse(t); while (q != NULL) { @@ -519,7 +524,7 @@ ACLIP::parse() data = data->insert(q, acl_ip_data::NetworkCompare); q = next_node; } - } + } while ((t = strtokFile())); } ACLIP::~ACLIP() diff --git a/src/acl/Ip.h b/src/acl/Ip.h index ce75d397b0..49f8f00318 100644 --- a/src/acl/Ip.h +++ b/src/acl/Ip.h @@ -33,6 +33,7 @@ #define SQUID_ACLIP_H #include "acl/Acl.h" +#include "acl/Data.h" #include "splay.h" #include "ip/Address.h" @@ -74,6 +75,7 @@ public: void operator delete(void *); ACLIP() : data(NULL) {} + explicit ACLIP(const ACLFlag flgs[]) : ACL(flgs), data(NULL) {} ~ACLIP(); diff --git a/src/acl/LocalPort.cc b/src/acl/LocalPort.cc index 269f01a0e7..7b22577e7e 100644 --- a/src/acl/LocalPort.cc +++ b/src/acl/LocalPort.cc @@ -37,7 +37,7 @@ #include "acl/Checklist.h" int -ACLLocalPortStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) +ACLLocalPortStrategy::match (ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &) { return data->match (checklist->my_addr.GetPort()); } diff --git a/src/acl/LocalPort.h b/src/acl/LocalPort.h index 2041d14d33..dd57aa03ea 100644 --- a/src/acl/LocalPort.h +++ b/src/acl/LocalPort.h @@ -41,7 +41,7 @@ class ACLLocalPortStrategy : public ACLStrategy { public: - virtual int match (ACLData * &, ACLFilledChecklist *); + virtual int match (ACLData * &, ACLFilledChecklist *, ACLFlags &); static ACLLocalPortStrategy *Instance(); /** * Not implemented to prevent copies of the instance. diff --git a/src/acl/Method.cc b/src/acl/Method.cc index 534080e406..08fd2eeb58 100644 --- a/src/acl/Method.cc +++ b/src/acl/Method.cc @@ -42,7 +42,7 @@ template class ACLStrategised; int -ACLMethodStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) +ACLMethodStrategy::match (ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &) { return data->match (checklist->request->method); } diff --git a/src/acl/Method.h b/src/acl/Method.h index 43c492747a..96ade28de3 100644 --- a/src/acl/Method.h +++ b/src/acl/Method.h @@ -42,7 +42,7 @@ class ACLMethodStrategy : public ACLStrategy { public: - virtual int match (ACLData * &, ACLFilledChecklist *); + virtual int match (ACLData * &, ACLFilledChecklist *, ACLFlags &); virtual bool requiresRequest() const {return true;} static ACLMethodStrategy *Instance(); diff --git a/src/acl/MyPortName.cc b/src/acl/MyPortName.cc index 860b4d2c2a..f2d5ebb92c 100644 --- a/src/acl/MyPortName.cc +++ b/src/acl/MyPortName.cc @@ -42,7 +42,7 @@ #include "client_side.h" int -ACLMyPortNameStrategy::match(ACLData * &data, ACLFilledChecklist *checklist) +ACLMyPortNameStrategy::match(ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &) { if (checklist->conn() != NULL) return data->match(checklist->conn()->port->name); diff --git a/src/acl/MyPortName.h b/src/acl/MyPortName.h index a7eed13c8c..9890d5a381 100644 --- a/src/acl/MyPortName.h +++ b/src/acl/MyPortName.h @@ -40,7 +40,7 @@ class ACLMyPortNameStrategy : public ACLStrategy { public: - virtual int match (ACLData * &, ACLFilledChecklist *); + 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 diff --git a/src/acl/PeerName.cc b/src/acl/PeerName.cc index 52eed51889..a3c36eb2d0 100644 --- a/src/acl/PeerName.cc +++ b/src/acl/PeerName.cc @@ -6,7 +6,7 @@ #include "CachePeer.h" int -ACLPeerNameStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) +ACLPeerNameStrategy::match (ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &) { if (checklist->dst_peer != NULL && checklist->dst_peer->name != NULL) return data->match(checklist->dst_peer->name); diff --git a/src/acl/PeerName.h b/src/acl/PeerName.h index 3e646c1955..84c23ee6fa 100644 --- a/src/acl/PeerName.h +++ b/src/acl/PeerName.h @@ -8,7 +8,7 @@ class ACLPeerNameStrategy : public ACLStrategy { public: - virtual int match (ACLData * &, ACLFilledChecklist *); + 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 diff --git a/src/acl/Protocol.cc b/src/acl/Protocol.cc index 9cd806585a..067977b9f8 100644 --- a/src/acl/Protocol.cc +++ b/src/acl/Protocol.cc @@ -42,7 +42,7 @@ template class ACLStrategised; int -ACLProtocolStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) +ACLProtocolStrategy::match (ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &) { return data->match (checklist->request->protocol); } diff --git a/src/acl/Protocol.h b/src/acl/Protocol.h index 74a02c62cd..d2aea168b4 100644 --- a/src/acl/Protocol.h +++ b/src/acl/Protocol.h @@ -42,7 +42,7 @@ class ACLProtocolStrategy : public ACLStrategy { public: - virtual int match (ACLData * &, ACLFilledChecklist *); + virtual int match (ACLData * &, ACLFilledChecklist *, ACLFlags &); virtual bool requiresRequest() const {return true;} static ACLProtocolStrategy *Instance(); diff --git a/src/acl/ReplyHeaderStrategy.h b/src/acl/ReplyHeaderStrategy.h index b8670a3931..857b7d9d3f 100644 --- a/src/acl/ReplyHeaderStrategy.h +++ b/src/acl/ReplyHeaderStrategy.h @@ -45,7 +45,7 @@ class ACLReplyHeaderStrategy : public ACLStrategy { public: - virtual int match (ACLData * &, ACLFilledChecklist *); + virtual int match (ACLData * &, ACLFilledChecklist *, ACLFlags &); virtual bool requiresReply() const {return true;} static ACLReplyHeaderStrategy *Instance(); @@ -63,7 +63,7 @@ private: template int -ACLReplyHeaderStrategy
::match (ACLData * &data, ACLFilledChecklist *checklist) +ACLReplyHeaderStrategy
::match (ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &) { char const *theHeader = checklist->reply->header.getStr(header); diff --git a/src/acl/ReplyMimeType.h b/src/acl/ReplyMimeType.h index 3a110d5509..cec43f7106 100644 --- a/src/acl/ReplyMimeType.h +++ b/src/acl/ReplyMimeType.h @@ -51,7 +51,7 @@ private: template <> inline int -ACLReplyHeaderStrategy::match(ACLData * &data, ACLFilledChecklist *checklist) +ACLReplyHeaderStrategy::match(ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &) { char const *theHeader = checklist->reply->header.getStr(HDR_CONTENT_TYPE); diff --git a/src/acl/RequestHeaderStrategy.h b/src/acl/RequestHeaderStrategy.h index 4304867dce..7d2c718909 100644 --- a/src/acl/RequestHeaderStrategy.h +++ b/src/acl/RequestHeaderStrategy.h @@ -45,7 +45,7 @@ class ACLRequestHeaderStrategy : public ACLStrategy { public: - virtual int match (ACLData * &, ACLFilledChecklist *); + virtual int match (ACLData * &, ACLFilledChecklist *, ACLFlags &); virtual bool requiresRequest() const {return true;} static ACLRequestHeaderStrategy *Instance(); @@ -63,7 +63,7 @@ private: template int -ACLRequestHeaderStrategy
::match (ACLData * &data, ACLFilledChecklist *checklist) +ACLRequestHeaderStrategy
::match (ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &) { char const *theHeader = checklist->request->header.getStr(header); diff --git a/src/acl/RequestMimeType.h b/src/acl/RequestMimeType.h index 87caf4a773..2859370839 100644 --- a/src/acl/RequestMimeType.h +++ b/src/acl/RequestMimeType.h @@ -51,7 +51,7 @@ private: template <> inline int -ACLRequestHeaderStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) +ACLRequestHeaderStrategy::match (ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &) { char const *theHeader = checklist->request->header.getStr(HDR_CONTENT_TYPE); diff --git a/src/acl/ServerCertificate.cc b/src/acl/ServerCertificate.cc index 29e43450e7..f87189a638 100644 --- a/src/acl/ServerCertificate.cc +++ b/src/acl/ServerCertificate.cc @@ -13,7 +13,7 @@ #include "ssl/ServerBump.h" int -ACLServerCertificateStrategy::match(ACLData * &data, ACLFilledChecklist *checklist) +ACLServerCertificateStrategy::match(ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &) { X509 *cert = NULL; if (checklist->serverCert.get()) diff --git a/src/acl/ServerCertificate.h b/src/acl/ServerCertificate.h index 84e245d3e1..e32cda3669 100644 --- a/src/acl/ServerCertificate.h +++ b/src/acl/ServerCertificate.h @@ -14,7 +14,7 @@ class ACLServerCertificateStrategy : public ACLStrategy { public: - virtual int match (ACLData * &, ACLFilledChecklist *); + 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 diff --git a/src/acl/SourceAsn.h b/src/acl/SourceAsn.h index 89c335e6fb..448709b263 100644 --- a/src/acl/SourceAsn.h +++ b/src/acl/SourceAsn.h @@ -44,7 +44,7 @@ class ACLSourceASNStrategy : public ACLStrategy { public: - virtual int match (ACLData * &, ACLFilledChecklist *); + 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 diff --git a/src/acl/SourceDomain.cc b/src/acl/SourceDomain.cc index d4bc7af22e..dced292ccf 100644 --- a/src/acl/SourceDomain.cc +++ b/src/acl/SourceDomain.cc @@ -69,7 +69,7 @@ SourceDomainLookup::LookupDone(const char *fqdn, const DnsLookupDetails &details } int -ACLSourceDomainStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) +ACLSourceDomainStrategy::match (ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &) { const char *fqdn = NULL; fqdn = fqdncache_gethostbyaddr(checklist->src_addr, FQDN_LOOKUP_IF_MISS); diff --git a/src/acl/SourceDomain.h b/src/acl/SourceDomain.h index f800b79fd7..8e82857419 100644 --- a/src/acl/SourceDomain.h +++ b/src/acl/SourceDomain.h @@ -42,7 +42,7 @@ class ACLSourceDomainStrategy : public ACLStrategy { public: - virtual int match (ACLData * &, ACLFilledChecklist *); + 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 diff --git a/src/acl/SslError.cc b/src/acl/SslError.cc index 95506d5a4c..6eae03e67b 100644 --- a/src/acl/SslError.cc +++ b/src/acl/SslError.cc @@ -4,7 +4,7 @@ #include "acl/Checklist.h" int -ACLSslErrorStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) +ACLSslErrorStrategy::match (ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &) { return data->match (checklist->sslErrors); } diff --git a/src/acl/SslError.h b/src/acl/SslError.h index e7ae0ba6bb..c6b5b25649 100644 --- a/src/acl/SslError.h +++ b/src/acl/SslError.h @@ -8,7 +8,7 @@ class ACLSslErrorStrategy : public ACLStrategy { public: - virtual int match (ACLData * &, ACLFilledChecklist *); + 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 diff --git a/src/acl/Strategised.h b/src/acl/Strategised.h index 76e2558bdd..971cc62a5c 100644 --- a/src/acl/Strategised.h +++ b/src/acl/Strategised.h @@ -49,7 +49,7 @@ public: void operator delete(void *); ~ACLStrategised(); - ACLStrategised(ACLData *, ACLStrategy *, char const *); + ACLStrategised(ACLData *, ACLStrategy *, char const *, const ACLFlag flags[] = ACLFlags::NoFlags); ACLStrategised (ACLStrategised const &); ACLStrategised &operator= (ACLStrategised const &); @@ -107,7 +107,7 @@ ACLStrategised::~ACLStrategised() } template -ACLStrategised::ACLStrategised(ACLData *newData, ACLStrategy *theStrategy, char const *theType) : data (newData), type_(theType), matcher(theStrategy) {} +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) @@ -150,7 +150,7 @@ ACLStrategised::match(ACLChecklist *cl) { ACLFilledChecklist *checklist = dynamic_cast(cl); assert(checklist); - return matcher->match(data, checklist); + return matcher->match(data, checklist, flags); } template diff --git a/src/acl/Strategy.h b/src/acl/Strategy.h index 10565ba269..b016e4d5ec 100644 --- a/src/acl/Strategy.h +++ b/src/acl/Strategy.h @@ -34,6 +34,7 @@ #ifndef SQUID_ACLSTRATEGY_H #define SQUID_ACLSTRATEGY_H +#include "acl/Acl.h" #include "acl/Data.h" class ACLFilledChecklist; @@ -45,7 +46,7 @@ class ACLStrategy public: typedef M MatchType; - virtual int match (ACLData * &, ACLFilledChecklist *) = 0; + virtual int match (ACLData * &, ACLFilledChecklist *, ACLFlags &) = 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 ef4ac00695..17ffdcdd28 100644 --- a/src/acl/Tag.cc +++ b/src/acl/Tag.cc @@ -41,7 +41,7 @@ #include "HttpRequest.h" int -ACLTagStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) +ACLTagStrategy::match (ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &) { if (checklist->request != NULL) return data->match (checklist->request->tag.termedBuf()); diff --git a/src/acl/Tag.h b/src/acl/Tag.h index 1d0d5e6a49..bdd2431830 100644 --- a/src/acl/Tag.h +++ b/src/acl/Tag.h @@ -41,7 +41,7 @@ class ACLTagStrategy : public ACLStrategy { public: - virtual int match (ACLData * &, ACLFilledChecklist *); + 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 diff --git a/src/acl/Time.cc b/src/acl/Time.cc index 4520f53fa0..208b087290 100644 --- a/src/acl/Time.cc +++ b/src/acl/Time.cc @@ -38,7 +38,7 @@ #include "SquidTime.h" int -ACLTimeStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) +ACLTimeStrategy::match (ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &) { return data->match (squid_curtime); } diff --git a/src/acl/Time.h b/src/acl/Time.h index fd3b7ee301..9e81c22e55 100644 --- a/src/acl/Time.h +++ b/src/acl/Time.h @@ -43,7 +43,7 @@ class ACLTimeStrategy : public ACLStrategy { public: - virtual int match (ACLData * &, ACLFilledChecklist *); + 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 diff --git a/src/acl/Url.cc b/src/acl/Url.cc index 1be778c3a8..e4d12d4cb0 100644 --- a/src/acl/Url.cc +++ b/src/acl/Url.cc @@ -40,7 +40,7 @@ #include "URL.h" int -ACLUrlStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) +ACLUrlStrategy::match (ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &) { char *esc_buf = xstrdup(urlCanonical(checklist->request)); rfc1738_unescape(esc_buf); diff --git a/src/acl/Url.h b/src/acl/Url.h index 96fb47fe3e..d82fbf0411 100644 --- a/src/acl/Url.h +++ b/src/acl/Url.h @@ -41,7 +41,7 @@ class ACLUrlStrategy : public ACLStrategy { public: - virtual int match (ACLData * &, ACLFilledChecklist *); + virtual int match (ACLData * &, ACLFilledChecklist *, ACLFlags &); virtual bool requiresRequest() const {return true;} static ACLUrlStrategy *Instance(); diff --git a/src/acl/UrlLogin.cc b/src/acl/UrlLogin.cc index b40a4b6baa..bdefaf0f9e 100644 --- a/src/acl/UrlLogin.cc +++ b/src/acl/UrlLogin.cc @@ -38,7 +38,7 @@ #include "rfc1738.h" int -ACLUrlLoginStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) +ACLUrlLoginStrategy::match (ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &) { char *esc_buf = xstrdup(checklist->request->login); rfc1738_unescape(esc_buf); diff --git a/src/acl/UrlLogin.h b/src/acl/UrlLogin.h index c29b745816..572b3ad354 100644 --- a/src/acl/UrlLogin.h +++ b/src/acl/UrlLogin.h @@ -45,7 +45,7 @@ class ACLUrlLoginStrategy : public ACLStrategy { public: - virtual int match (ACLData * &, ACLFilledChecklist *); + virtual int match (ACLData * &, ACLFilledChecklist *, ACLFlags &); virtual bool requiresRequest() const {return true;} static ACLUrlLoginStrategy *Instance(); diff --git a/src/acl/UrlPath.cc b/src/acl/UrlPath.cc index c29d32a8d3..018e20bbc5 100644 --- a/src/acl/UrlPath.cc +++ b/src/acl/UrlPath.cc @@ -40,7 +40,7 @@ #include "rfc1738.h" int -ACLUrlPathStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) +ACLUrlPathStrategy::match (ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &) { char *esc_buf = xstrdup(checklist->request->urlpath.termedBuf()); rfc1738_unescape(esc_buf); diff --git a/src/acl/UrlPath.h b/src/acl/UrlPath.h index a6fdce96e3..0ae533d25b 100644 --- a/src/acl/UrlPath.h +++ b/src/acl/UrlPath.h @@ -42,7 +42,7 @@ class ACLUrlPathStrategy : public ACLStrategy { public: - virtual int match (ACLData * &, ACLFilledChecklist *); + virtual int match (ACLData * &, ACLFilledChecklist *, ACLFlags &); virtual bool requiresRequest() const {return true;} static ACLUrlPathStrategy *Instance(); diff --git a/src/acl/UrlPort.cc b/src/acl/UrlPort.cc index c938ab4c69..81cbf47414 100644 --- a/src/acl/UrlPort.cc +++ b/src/acl/UrlPort.cc @@ -38,7 +38,7 @@ #include "HttpRequest.h" int -ACLUrlPortStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) +ACLUrlPortStrategy::match (ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &) { return data->match (checklist->request->port); } diff --git a/src/acl/UrlPort.h b/src/acl/UrlPort.h index 49a8849215..bdc07708ca 100644 --- a/src/acl/UrlPort.h +++ b/src/acl/UrlPort.h @@ -40,7 +40,7 @@ class ACLUrlPortStrategy : public ACLStrategy { public: - virtual int match (ACLData * &, ACLFilledChecklist *); + virtual int match (ACLData * &, ACLFilledChecklist *, ACLFlags &); virtual bool requiresRequest() const {return true;} static ACLUrlPortStrategy *Instance(); diff --git a/src/cache_cf.cc b/src/cache_cf.cc index a543b10ba3..cc45babfbd 100644 --- a/src/cache_cf.cc +++ b/src/cache_cf.cc @@ -1276,10 +1276,11 @@ 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 ", + storeAppendPrintf(entry, "%s %s %s %s ", name, ae->name, - ae->typeString()); + ae->typeString(), + ae->flags.flagsStr()); v = w = ae->dump(); while (v != NULL) { diff --git a/src/external_acl.cc b/src/external_acl.cc index c0c46bb973..0d41b8e700 100644 --- a/src/external_acl.cc +++ b/src/external_acl.cc @@ -705,7 +705,7 @@ ACLExternal::parse() data = cbdataAlloc(external_acl_data); - token = strtok(NULL, w_space); + token = strtokFile(); if (!token) self_destruct(); diff --git a/src/snmp_core.cc b/src/snmp_core.cc index 344651c0b8..1c4d8d1844 100644 --- a/src/snmp_core.cc +++ b/src/snmp_core.cc @@ -1160,7 +1160,7 @@ class ACLSNMPCommunityStrategy : public ACLStrategy { public: - virtual int match (ACLData * &, ACLFilledChecklist *); + 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 @@ -1186,7 +1186,7 @@ ACL::Prototype ACLSNMPCommunity::RegistryProtoype(&ACLSNMPCommunity::RegistryEnt ACLStrategised ACLSNMPCommunity::RegistryEntry_(new ACLStringData, ACLSNMPCommunityStrategy::Instance(), "snmp_community"); int -ACLSNMPCommunityStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) +ACLSNMPCommunityStrategy::match (ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &) { return data->match (checklist->snmp_community); } -- 2.39.5