=== modified file 'src/AclRegs.cc' --- src/AclRegs.cc 2012-10-29 01:31:29 +0000 +++ src/AclRegs.cc 2012-11-21 11:50:52 +0000 @@ -1,59 +1,62 @@ #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. */ #include "acl/Acl.h" +#include "acl/AllOfData.h" #if USE_SQUID_EUI #include "acl/Arp.h" #include "acl/Eui64.h" #endif #include "acl/Asn.h" #include "acl/Browser.h" #include "acl/Checklist.h" #include "acl/Data.h" #include "acl/DestinationAsn.h" #include "acl/DestinationDomain.h" #include "acl/DestinationIp.h" #include "acl/DomainData.h" #if USE_AUTH #include "acl/ExtUser.h" #endif #include "acl/FilledChecklist.h" #include "acl/Gadgets.h" +#include "acl/Group.h" #include "acl/HierCodeData.h" #include "acl/HierCode.h" #include "acl/HttpHeaderData.h" #include "acl/HttpRepHeader.h" #include "acl/HttpReqHeader.h" #include "acl/HttpStatus.h" #include "acl/IntRange.h" #include "acl/Ip.h" #include "acl/LocalIp.h" #include "acl/LocalPort.h" #include "acl/MaxConnection.h" #include "acl/MethodData.h" #include "acl/Method.h" #include "acl/MyPortName.h" +#include "acl/OneOfData.h" #include "acl/PeerName.h" #include "acl/ProtocolData.h" #include "acl/Protocol.h" #include "acl/Random.h" #include "acl/Referer.h" #include "acl/RegexData.h" #include "acl/ReplyHeaderStrategy.h" #include "acl/ReplyMimeType.h" #include "acl/RequestHeaderStrategy.h" #include "acl/RequestMimeType.h" #include "acl/SourceAsn.h" #include "acl/SourceDomain.h" #include "acl/SourceIp.h" #if USE_SSL #include "acl/SslErrorData.h" #include "acl/SslError.h" #include "acl/CertificateData.h" #include "acl/Certificate.h" #endif #include "acl/Strategised.h" @@ -157,20 +160,26 @@ #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"); #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"); #endif ACL::Prototype ACLTag::RegistryProtoype(&ACLTag::RegistryEntry_, "tag"); ACLStrategised ACLTag::RegistryEntry_(new ACLStringData, ACLTagStrategy::Instance(), "tag"); + +ACL::Prototype ACLGroup::OrRegistryProtoype(&ACLGroup::OrRegistryEntry_, "one-of"); +ACLStrategised ACLGroup::OrRegistryEntry_(new ACLOneOfData, ACLGroupStrategy::Instance(), "one-of"); + +ACL::Prototype ACLGroup::AndRegistryProtoype(&ACLGroup::AndRegistryEntry_, "all-of"); +ACLStrategised ACLGroup::AndRegistryEntry_(new ACLAllOfData, ACLGroupStrategy::Instance(), "all-of"); === added file 'src/acl/AllOfData.cc' --- src/acl/AllOfData.cc 1970-01-01 00:00:00 +0000 +++ src/acl/AllOfData.cc 2012-11-21 11:48:03 +0000 @@ -0,0 +1,55 @@ +/* + */ + +#include "squid.h" +#include "acl/Checklist.h" +#include "acl/AllOfData.h" +#include "ConfigParser.h" +#include "cache_cf.h" +#include "Debug.h" +#include "Gadgets.h" +#include "wordlist.h" + +ACLAllOfData::~ACLAllOfData() +{ +} + +wordlist * +ACLAllOfData::dump() +{ + if (!accessList) + return NULL; + + wordlist *W = NULL; + for (ACLList *l = accessList->aclList; l != NULL; l = l->next) + wordlistAdd(&W, l->_acl->name); + + return W; +} + +void +ACLAllOfData::parse() +{ + ConfigParser parser; + assert(accessList == NULL); + acl_access **tail = &accessList; + + // The AND acl: + // acl AND acl1 acl2 acl3 ... + // Implemented as the following checklist + // checklist allow acl1 acl2 acl3 ... + // checklist deny all + + acl_access *A = new acl_access; + A->allow = ACCESS_ALLOWED; + aclParseAclList(parser, &A->aclList); + *tail = A; + tail = &A->next; +} + +ACLData * +ACLAllOfData::clone() const +{ + assert (!accessList); + return new ACLAllOfData; +} === added file 'src/acl/AllOfData.h' --- src/acl/AllOfData.h 1970-01-01 00:00:00 +0000 +++ src/acl/AllOfData.h 2012-11-22 14:23:48 +0000 @@ -0,0 +1,31 @@ +/* + */ + +#ifndef SQUID_ACLALLOFDATA_H +#define SQUID_ACLALLOFDATA_H + +#include "splay.h" +#include "acl/Acl.h" +#include "acl/Data.h" +#include "acl/FilledChecklist.h" +#include "acl/Group.h" + +/** + * \ingroup ACLAPI + * all-of ACL data + */ +class ACLAllOfData : public ACLGroupData +{ +public: + MEMPROXY_CLASS(ACLAllOfData); + virtual ~ACLAllOfData(); + + // ACLData API + virtual wordlist *dump(); + virtual void parse(); + virtual ACLData *clone() const; +}; + +MEMPROXY_CLASS_INLINE(ACLAllOfData); + +#endif /* SQUID_ACLALLOFDATA_H */ === modified file 'src/acl/Checklist.cc' --- src/acl/Checklist.cc 2012-09-01 14:38:36 +0000 +++ src/acl/Checklist.cc 2012-11-21 09:49:38 +0000 @@ -56,46 +56,50 @@ return; } allow_t lastSeenKeyword = ACCESS_DUNNO; /* NOTE: This holds a cbdata reference to the current access_list * entry, not the whole list. */ while (accessList != NULL) { /** \par * If the _acl_access is no longer valid (i.e. its been * freed because of a reconfigure), then bail with ACCESS_DUNNO. */ if (!cbdataReferenceValid(accessList)) { cbdataReferenceDone(accessList); debugs(28, 4, "ACLChecklist::check: " << this << " accessList is invalid"); checkCallback(ACCESS_DUNNO); return; } - checking (true); - checkAccessList(); - checking (false); - - if (asyncInProgress()) { - return; + // We may call matchNonBlocking to complete acl non-blocking checking + // and call the callbacks. In this case do not call checkAccessList. + if (!finished()) { + checking (true); + checkAccessList(); + checking (false); + + if (asyncInProgress()) { + return; + } } if (finished()) { /** \par * Either the request is allowed, denied, requires authentication. */ debugs(28, 3, "ACLChecklist::check: " << this << " match found, calling back with " << currentAnswer()); cbdataReferenceDone(accessList); /* A */ checkCallback(currentAnswer()); /* From here on in, this may be invalid */ return; } lastSeenKeyword = accessList->allow; /* * Reference the next access entry */ const acl_access *A = accessList; === modified file 'src/acl/FilledChecklist.cc' --- src/acl/FilledChecklist.cc 2012-09-09 19:41:47 +0000 +++ src/acl/FilledChecklist.cc 2012-12-05 17:23:47 +0000 @@ -177,20 +177,54 @@ if (http_request != NULL) { request = HTTPMSGLOCK(http_request); #if FOLLOW_X_FORWARDED_FOR if (Config.onoff.acl_uses_indirect_client) src_addr = request->indirect_client_addr; else #endif /* FOLLOW_X_FORWARDED_FOR */ src_addr = request->client_addr; my_addr = request->my_addr; if (request->clientConnectionManager.valid()) conn(request->clientConnectionManager.get()); } #if USE_IDENT if (ident) xstrncpy(rfc931, ident, USER_IDENT_SZ); #endif } +ACLFilledChecklist *ACLFilledChecklist::cloneFilled() +{ + ACLFilledChecklist *newFilled = new ACLFilledChecklist; + newFilled->src_addr = src_addr; + newFilled->dst_addr = dst_addr; + newFilled->my_addr = my_addr; + newFilled->dst_peer = dst_peer; + newFilled->dst_rdns = dst_rdns ? xstrdup(dst_rdns) : NULL; + + if (request) + newFilled->request = HTTPMSGLOCK(request); + else + newFilled->request = NULL; + if (reply) + newFilled->reply = HTTPMSGLOCK(reply); + else + newFilled->reply = NULL; + xstrncpy(newFilled->rfc931, rfc931, USER_IDENT_SZ); +#if USE_AUTH + newFilled->auth_user_request = auth_user_request; +#endif +#if SQUID_SNMP + newFilled->snmp_community = snmp_community; +#endif +#if USE_SSL + newFilled->sslErrors = cbdataReference(sslErrors); +#endif + newFilled->extacl_entry = cbdataReference(extacl_entry); + newFilled->conn_ = cbdataReference(conn_); + newFilled->fd_ = fd_; + newFilled->destinationDomainChecked_ = destinationDomainChecked_; + newFilled->sourceDomainChecked_ = sourceDomainChecked_; + return newFilled; +} === modified file 'src/acl/FilledChecklist.h' --- src/acl/FilledChecklist.h 2012-10-03 07:34:10 +0000 +++ src/acl/FilledChecklist.h 2012-12-05 17:20:45 +0000 @@ -34,40 +34,41 @@ ConnStateData * conn() const; /// The client side fd. It uses conn() if available int fd() const; /// set either conn void conn(ConnStateData *); /// set the client side FD void fd(int aDescriptor); //int authenticated(); bool destinationDomainChecked() const; void markDestinationDomainChecked(); bool sourceDomainChecked() const; void markSourceDomainChecked(); // ACLChecklist API virtual bool hasRequest() const { return request != NULL; } virtual bool hasReply() const { return reply != NULL; } + ACLFilledChecklist *cloneFilled(); public: Ip::Address src_addr; Ip::Address dst_addr; Ip::Address my_addr; CachePeer *dst_peer; char *dst_rdns; HttpRequest *request; HttpReply *reply; char rfc931[USER_IDENT_SZ]; #if USE_AUTH Auth::UserRequest::Pointer auth_user_request; #endif #if SQUID_SNMP char *snmp_community; #endif #if USE_SSL === added file 'src/acl/Group.cc' --- src/acl/Group.cc 1970-01-01 00:00:00 +0000 +++ src/acl/Group.cc 2012-12-05 19:26:53 +0000 @@ -0,0 +1,121 @@ +/* + */ + +#include "squid.h" +#include "acl/Checklist.h" +#include "acl/Gadgets.h" +#include "acl/Group.h" +#include "fqdncache.h" +#include "HttpRequest.h" +#include "HttpReply.h" +#include "ipcache.h" + +ACLGroupStrategy ACLGroupStrategy::Instance_; + +CBDATA_NAMESPACED_CLASS_INIT(ACLGroupStrategy,GroupStrategyCBData); + +class GroupLookup : public ACLChecklist::AsyncState +{ +public: + static GroupLookup *Instance(); + virtual void checkForAsync(ACLChecklist *)const; +private: + static GroupLookup instance_; +}; + +GroupLookup GroupLookup::instance_; + +GroupLookup * +GroupLookup::Instance() +{ + return &instance_; +} + +void +GroupLookup::checkForAsync(ACLChecklist *cl) const +{ + ACLFilledChecklist *checklist = Filled(cl); + checklist->asyncInProgress(true); +} + +ACLGroupData::~ACLGroupData() +{ + aclDestroyAccessList(&accessList); +} + +ACLGroupStrategy::GroupStrategyCBData::GroupStrategyCBData(ACLFilledChecklist *group, ACLFilledChecklist *current) +{ + groupCheck = cbdataReference(group); + currentCheck = cbdataReference(current); +} + +ACLGroupStrategy::GroupStrategyCBData::~GroupStrategyCBData() +{ + cbdataReferenceDone(groupCheck); + cbdataReferenceDone(currentCheck); +} + + +void +ACLGroupStrategy::GroupStrategyCB(allow_t answer, void *data) +{ + ACLGroupStrategy::GroupStrategyCBData *groupData = (ACLGroupStrategy::GroupStrategyCBData *)data; + ACLFilledChecklist *groupCheck = groupData->groupCheck; + ACLFilledChecklist *checklist = groupData->currentCheck; + + //Copy looked up values + if (!checklist->destinationDomainChecked() && groupCheck->destinationDomainChecked()) { + if (!checklist->dst_rdns && groupCheck->dst_rdns) + checklist->dst_rdns = xstrdup(groupCheck->dst_rdns); + checklist->dst_addr = groupCheck->dst_addr; + checklist->markDestinationDomainChecked(); + } + + if (!checklist->sourceDomainChecked() && groupCheck->sourceDomainChecked()) + checklist->markSourceDomainChecked(); + + if (checklist->extacl_entry != groupCheck->extacl_entry) { + cbdataReferenceDone(checklist->extacl_entry); + checklist->extacl_entry = cbdataReference(groupCheck->extacl_entry); + } + + debugs(28, 5, HERE << "Slow acl check finished. The answer is: " << answer); + checklist->asyncInProgress(false); + checklist->changeState (ACLChecklist::NullState::Instance()); + checklist->matchNonBlocking(); + delete groupData; +} + +int +ACLGroupStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) +{ + ACLGroupData *chData = dynamic_cast(data); + ACLFilledChecklist *groupCheck = checklist->cloneFilled(); + groupCheck->accessList = cbdataReference(chData->accessList); + + if (checklist->reply) + groupCheck->reply = HTTPMSGLOCK(checklist->reply); + + allow_t answer; + if ((answer = groupCheck->fastCheck()) == ACCESS_DUNNO) { + checklist->changeState(GroupLookup::Instance()); + ACLGroupStrategy::GroupStrategyCBData *groupCbData = new ACLGroupStrategy::GroupStrategyCBData(groupCheck, checklist); + assert(cbdataReferenceValid(groupCheck)); + groupCheck->nonBlockingCheck(GroupStrategyCB, groupCbData); + return 0; + } else + return answer == ACCESS_ALLOWED; +} + +ACLGroupStrategy * +ACLGroupStrategy::Instance() +{ + return &Instance_; +} + +bool +ACLGroupData::match(ACLFilledChecklist *checklist) +{ + assert(false); + return false; +} === added file 'src/acl/Group.h' --- src/acl/Group.h 1970-01-01 00:00:00 +0000 +++ src/acl/Group.h 2012-12-05 18:52:05 +0000 @@ -0,0 +1,87 @@ +/* + */ + +#ifndef SQUID_ACLSYNTHESIZED_H +#define SQUID_ACLSYNTHESIZED_H + +#include "acl/Acl.h" +#include "acl/Data.h" +#include "acl/Checklist.h" +#include "acl/Strategised.h" + +/** + * \ingroup ACLAPI + * Applies ACLData API to a group of ACLs + */ +class ACLGroupData : public ACLData +{ + +public: + virtual ~ACLGroupData(); + + // ACLData API + virtual bool match(ACLFilledChecklist *checklist); + virtual wordlist *dump() =0; + virtual void parse() =0; + virtual bool empty() const {return !accessList; } + virtual ACLData *clone() const =0; + + /// individual ACLs storage with the right AND/OR/NOT rules structure + acl_access *accessList; +}; + +/** + * \ingroup ACLAPI + * Applies ACLStrategy API to a group of ACLs + */ +class ACLGroupStrategy : public ACLStrategy +{ +public: + ///Cbdata class used to pass data to the GroupStrategyCB callback function + class GroupStrategyCBData { + public: + ACLFilledChecklist *groupCheck; + ACLFilledChecklist *currentCheck; + GroupStrategyCBData(ACLFilledChecklist *groupCheck, ACLFilledChecklist *currentCheck); + ~GroupStrategyCBData(); + CBDATA_CLASS2(GroupStrategyCBData); + }; + +public: + static ACLGroupStrategy *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 + */ + ACLGroupStrategy(ACLGroupStrategy const &); + +private: + /// ACLChecklist callback called for nonblocking ACLs group + static void GroupStrategyCB(allow_t answer, void *data); + + ACLGroupStrategy() {} + /// Not implemented + ACLGroupStrategy &operator=(ACLGroupStrategy const &); + + static ACLGroupStrategy Instance_; +}; + +/// \ingroup ACLAPI +class ACLGroup +{ + +private: + static ACL::Prototype OrRegistryProtoype; + static ACL::Prototype AndRegistryProtoype; + static ACLStrategised OrRegistryEntry_; + static ACLStrategised AndRegistryEntry_; +}; + +#endif /* SQUID_ACLSYNTHESIZED_H */ === modified file 'src/acl/Makefile.am' --- src/acl/Makefile.am 2012-10-29 01:31:29 +0000 +++ src/acl/Makefile.am 2012-11-21 11:50:52 +0000 @@ -19,98 +19,104 @@ Strategised.h \ FilledChecklist.cc \ FilledChecklist.h \ AclAddress.h \ AclAddress.cc ## data-specific ACLs libacls_la_SOURCES = \ IntRange.cc \ IntRange.h \ RegexData.cc \ RegexData.h \ StringData.cc \ StringData.h \ Time.cc \ Time.h \ TimeData.cc \ TimeData.h \ Asn.cc \ Asn.h \ + AllOfData.cc \ + AllOfData.h \ Browser.cc \ Browser.h \ DestinationAsn.h \ DestinationDomain.cc \ DestinationDomain.h \ DestinationIp.cc \ DestinationIp.h \ DomainData.cc \ DomainData.h \ ExtUser.cc \ ExtUser.h \ HierCodeData.cc \ HierCodeData.h \ HierCode.cc \ HierCode.h \ HttpHeaderData.cc \ HttpHeaderData.h \ HttpRepHeader.cc \ HttpRepHeader.h \ HttpReqHeader.cc \ HttpReqHeader.h \ HttpStatus.cc \ HttpStatus.h \ Ip.cc \ Ip.h \ LocalIp.cc \ LocalIp.h \ LocalPort.cc \ LocalPort.h \ MaxConnection.cc \ MaxConnection.h \ Method.cc \ MethodData.cc \ MethodData.h \ Method.h \ MyPortName.cc \ MyPortName.h \ + OneOfData.cc \ + OneOfData.h \ PeerName.cc \ PeerName.h \ Protocol.cc \ ProtocolData.cc \ ProtocolData.h \ 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 \ SourceDomain.h \ SourceIp.cc \ SourceIp.h \ + Group.cc \ + Group.h \ Tag.cc \ Tag.h \ Url.cc \ Url.h \ UrlLogin.cc \ UrlLogin.h \ UrlPath.cc \ UrlPath.h \ UrlPort.cc \ UrlPort.h \ UserData.cc \ UserData.h \ AclNameList.h \ AclDenyInfoList.h \ Gadgets.cc \ Gadgets.h \ AclSizeLimit.h ## Add conditional sources ## TODO: move these to their respectful dirs when those dirs are created === added file 'src/acl/OneOfData.cc' --- src/acl/OneOfData.cc 1970-01-01 00:00:00 +0000 +++ src/acl/OneOfData.cc 2012-11-21 11:48:19 +0000 @@ -0,0 +1,80 @@ +/* + */ + +#include "squid.h" +#include "acl/Checklist.h" +#include "acl/OneOfData.h" +#include "ConfigParser.h" +#include "cache_cf.h" +#include "Debug.h" +#include "Gadgets.h" +#include "wordlist.h" + +ACLOneOfData::~ACLOneOfData() +{ +} + +wordlist * +ACLOneOfData::dump() +{ + if (!accessList) + return NULL; + + wordlist *W = NULL; + for (acl_access *l = accessList; l->allow != ACCESS_DENIED; l = l->next) { + assert(l->aclList && l->aclList->_acl); + wordlistAdd(&W, l->aclList->_acl->name); + } + + return W; +} + +void +ACLOneOfData::parse() +{ + char *t = NULL; + + // The OR acl: + // acl OR acl1 acl2 acl3 ... + // Implemented as the following checklist + // checklist allow acl1 + // checklist allow acl2 + // checklist allow acl3 + // ...... + // checklist deny all + + assert(accessList == NULL); + acl_access **tail = &accessList; + ACL *a = NULL; + while ((t = strtokFile())) { + ACLList *L = new ACLList; + + if (*t == '!') { + L->negated (true); + ++t; + } + + a = ACL::FindByName(t); + + if (a == NULL) { + debugs(28, DBG_CRITICAL, HERE << " ACL name '" << t << "' not found."); + delete L; + self_destruct(); + return; + } + + L->_acl = a; + acl_access *A = new acl_access; + A->allow = ACCESS_ALLOWED; + A->aclList = L; + *tail = A; + tail = &A->next; + } +} + +ACLData * +ACLOneOfData::clone() const +{ + assert (!accessList); + return new ACLOneOfData; +} === added file 'src/acl/OneOfData.h' --- src/acl/OneOfData.h 1970-01-01 00:00:00 +0000 +++ src/acl/OneOfData.h 2012-11-22 14:23:22 +0000 @@ -0,0 +1,31 @@ +/* + */ + +#ifndef SQUID_ACLONEOFDATA_H +#define SQUID_ACLONEOFDATA_H + +#include "splay.h" +#include "acl/Acl.h" +#include "acl/Data.h" +#include "acl/FilledChecklist.h" +#include "acl/Group.h" + +/** + * \ingroup ACLAPI + * one-of ACL data + */ +class ACLOneOfData : public ACLGroupData +{ +public: + MEMPROXY_CLASS(ACLOneOfData); + virtual ~ACLOneOfData(); + + /* ACLData API */ + virtual wordlist *dump(); + virtual void parse(); + virtual ACLData *clone() const; +}; + +MEMPROXY_CLASS_INLINE(ACLOneOfData); + +#endif /* SQUID_ACLONEOFDATA_H */ === modified file 'src/cf.data.pre' --- src/cf.data.pre 2012-10-29 01:31:29 +0000 +++ src/cf.data.pre 2012-11-22 14:25:16 +0000 @@ -896,40 +896,49 @@ # match against SSL certificate validation error [fast] # # For valid error names see in @DEFAULT_ERROR_DIR@/templates/error-details.txt # template file. # # The following can be used as shortcuts for certificate properties: # [ssl::]certHasExpired: the "not after" field is in the past # [ssl::]certNotYetValid: the "not before" field is in the future # [ssl::]certUntrusted: The certificate issuer is not to be trusted. # [ssl::]certSelfSigned: The certificate is self signed. # [ssl::]certDomainMismatch: The certificate CN domain does not # match the name the name of the host we are connecting to. # # The ssl::certHasExpired, ssl::certNotYetValid, ssl::certDomainMismatch, # ssl::certUntrusted, and ssl::certSelfSigned can also be used as # predefined ACLs, just like the 'all' ACL. # # NOTE: The ssl_error ACL is only supported with sslproxy_cert_error, # sslproxy_cert_sign, and sslproxy_cert_adapt options. ENDIF + acl aclname one-of acl1 acl2 ... + # match any one of the acls [fast or slow] + # The first matching ACL stops further ACL evaluation. + # The one-of ACL is fast if all ACLs are fast and slow otherwise. + + acl aclname all-of acl1 acl2 ... + # match all of the acls [fast or slow] + # The first mismatching ACL stops further ACL evaluation. + # The all-of ACL is fast if all ACLs are fast and slow otherwise. Examples: acl macaddress arp 09:00:2b:23:45:67 acl myexample dst_as 1241 acl password proxy_auth REQUIRED acl fileupload req_mime_type -i ^multipart/form-data$ acl javascript rep_mime_type -i ^application/x-javascript$ NOCOMMENT_START # # Recommended minimum configuration: # # Example rule allowing access from your local networks. # Adapt to list your (internal) IP networks from where browsing # should be allowed acl localnet src 10.0.0.0/8 # RFC1918 possible internal network acl localnet src 172.16.0.0/12 # RFC1918 possible internal network acl localnet src 192.168.0.0/16 # RFC1918 possible internal network acl localnet src fc00::/7 # RFC 4193 local private network range