]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Bug 2526: pt 2: default ALLOW when no list specified.
authorAmos Jeffries <squid3@treenet.co.nz>
Wed, 4 Feb 2009 09:52:20 +0000 (22:52 +1300)
committerAmos Jeffries <squid3@treenet.co.nz>
Wed, 4 Feb 2009 09:52:20 +0000 (22:52 +1300)
Fallout from audit of access control checks.
 - Some got sensible defaults added
 - many got slightly more optimized defaults
 - documented the ACLChecklist interface and some API cleanups

18 files changed:
src/ACL.h
src/ACLChecklist.cc
src/ACLChecklist.h
src/ACLMyPortName.cc
src/DelayId.cc
src/HttpHeaderTools.cc
src/HttpReply.cc
src/adaptation/AccessCheck.cc
src/client_side.cc
src/client_side_reply.cc
src/client_side_request.cc
src/enums.h
src/forward.cc
src/htcp.cc
src/icp_v2.cc
src/peer_select.cc
src/snmp_core.cc
src/tunnel.cc

index 918019521c20a78302c82e3d880e62b2d6067074..374bca50775a592f0769a173cc6a09518f919cde 100644 (file)
--- a/src/ACL.h
+++ b/src/ACL.h
@@ -140,6 +140,13 @@ public:
     };
 };
 
+/// \ingroup ACLAPI
+typedef enum {
+    ACCESS_DENIED,
+    ACCESS_ALLOWED,
+    ACCESS_REQ_PROXY_AUTH
+} allow_t;
+
 /// \ingroup ACLAPI
 class acl_access
 {
index 097a061ede93ba6c2dec41f334a08b79a7b1a524..33b317e31c4391b55fcd360983492bc75600c1d6 100644 (file)
@@ -419,7 +419,7 @@ ACLChecklist::~ACLChecklist()
 
 
 ConnStateData *
-ACLChecklist::conn()
+ACLChecklist::conn() const
 {
     return  conn_;
 }
@@ -480,6 +480,11 @@ ACLChecklist::asyncState() const
     return state_;
 }
 
+/**
+ * Kick off a non-blocking (slow) ACL access list test
+ *
+ * NP: this should probably be made Async now.
+ */
 void
 ACLChecklist::nonBlockingCheck(PF * callback_, void *callback_data_)
 {
index 1b92ad9442c3409a9147eaddd93903e183eec6b1..850d3a9d9a5c70463196b976408e3ebdb68a9e40 100644 (file)
 #ifndef SQUID_ACLCHECKLIST_H
 #define SQUID_ACLCHECKLIST_H
 
-#include "typedefs.h"
-#include "client_side.h"
-#include "structs.h"
+//#include "typedefs.h"
+//#include "client_side.h"
+//#include "structs.h"
 
-class ExternalACLEntry;
+#include "ACL.h"
 
+class AuthUserRequest;
+class ExternalACLEntry;
 class ConnStateData;
 
 /// \ingroup ACLAPI
@@ -86,40 +88,100 @@ public:
     };
 
 
+public: /* operators */
     void *operator new(size_t);
     void operator delete(void *);
 
     ACLChecklist();
     ~ACLChecklist();
-    /* To cause link failures if assignment attempted */
+    /** NP: To cause link failures if assignment attempted */
     ACLChecklist (ACLChecklist const &);
+    /** NP: To cause link failures if assignment attempted */
     ACLChecklist &operator=(ACLChecklist const &);
 
+public: /* API methods */
+
+    /**
+     * Trigger off a non-blocking access check for a set of *_access options..
+     * The callback specified will be called with true/false
+     * when the results of the ACL tests are known.
+     */
     void nonBlockingCheck(PF * callback, void *callback_data);
+
+    /**
+     * Trigger a blocking access check for a set of *_access options.
+     * 
+     * ACLs which cannot be satisfied directly from available data are ignored.
+     * This means any proxy_auth, external_acl, DNS lookups, Ident lookups etc
+     * which have not already been performed and cached will not be checked.
+     *
+     * If there is no access list to check the default is to return DENIED.
+     * However callers should perform their own check and default based on local
+     * knowledge of the ACL usage rather than depend on this default.
+     * That will also save on work setting up ACLChecklist fields for a no-op.
+     * 
+     * \retval  1/true    Access Allowed
+     * \retval 0/false    Access Denied
+     */
     int fastCheck();
-    void checkCallback(allow_t answer);
-    void preCheck();
+
+    /**
+     * Trigger a blocking access check for a single ACL line (a AND b AND c).
+     * 
+     * ACLs which cannot be satisfied directly from available data are ignored.
+     * This means any proxy_auth, external_acl, DNS lookups, Ident lookups etc
+     * which have not already been performed and cached will not be checked.
+     * 
+     * \retval  1/true    Access Allowed
+     * \retval 0/false    Access Denied
+     */
     _SQUID_INLINE_ bool matchAclListFast(const ACLList * list);
-    ConnStateData * conn();
-    int fd() const; // uses conn() if available
 
-    // set either conn or FD
+    /**
+     * Attempt to check the current checklist against current data.
+     * This is the core routine behind all ACL test routines.
+     * As much as possible of current tests are performed immediately
+     * and the result is maybe delayed to wait for async lookups.
+     *
+     * When all tests are done callback is presented with one of:
+     * \item ACCESS_ALLOWED     Access explicitly Allowed
+     * \item ACCESS_DENIED      Access explicitly Denied
+     */
+    void check();
+
+    ConnStateData * conn() const;
+
+    /// uses conn() if available
+    int fd() const;
+
+    /// set either conn
     void conn(ConnStateData *);
+    /// set FD
     void fd(int aDescriptor);
 
+/* Accessors used by internal ACL stuff */
+
     int authenticated();
 
     bool asyncInProgress() const;
     void asyncInProgress(bool const);
+
     bool finished() const;
     void markFinished();
-    void check();
+
     allow_t const & currentAnswer() const;
     void currentAnswer(allow_t const);
+
+    void changeState(AsyncState *);
+    AsyncState *asyncState() const;
+
+private: /* NP: only used internally */
+
+    void checkCallback(allow_t answer);
     void checkAccessList();
     void checkForAsync();
-    void changeState (AsyncState *);
-    AsyncState *asyncState() const;
+
+public: /* checklist available data */
 
     const acl_access *accessList;
 
@@ -132,6 +194,7 @@ public:
     struct peer *dst_peer;
 
     HttpRequest *request;
+
     /* for acls that look at reply data */
     HttpReply *reply;
     char rfc931[USER_IDENT_SZ];
@@ -148,17 +211,20 @@ public:
     PF *callback;
     void *callback_data;
     ExternalACLEntry *extacl_entry;
+
     bool destinationDomainChecked() const;
     void markDestinationDomainChecked();
     bool sourceDomainChecked() const;
     void markSourceDomainChecked();
 
-private:
+private: /* internal methods */
+    void preCheck();
     void matchAclList(const ACLList * list, bool const fast);
     void matchAclListSlow(const ACLList * list);
     CBDATA_CLASS(ACLChecklist);
-    ConnStateData * conn_;     /* hack for ident and NTLM */
-    int fd_; // may be available when conn_ is not
+
+    ConnStateData * conn_;          /**< hack for ident and NTLM */
+    int fd_;                        /**< may be available when conn_ is not */
     bool async_;
     bool finished_;
     allow_t allow_;
index d48b051a55e8b3cfa398483a5fc02c98d1ba1377..fed20b69218ad993e08bc7a03960ba54079f5ccc 100644 (file)
@@ -39,6 +39,9 @@
 #include "ACLStringData.h"
 #include "ACLChecklist.h"
 
+/* for ConnStateData */
+#include "client_side.h"
+
 
 ACL::Prototype ACLMyPortName::RegistryProtoype(&ACLMyPortName::RegistryEntry_, "myportname");
 
index 3b8f6ebadf73d1f21532a7f5417093dd1522e360..986c1ec7a1739886f84d1d376ee7908b92d5417d 100644 (file)
@@ -106,6 +106,14 @@ DelayId::DelayClient(ClientHttpRequest * http)
     }
 
     for (pool = 0; pool < DelayPools::pools(); pool++) {
+
+        /* pools require explicit 'allow' to assign a client into them */
+        if (!DelayPools::delay_data[pool].access) {
+            debugs(77, DBG_IMPORTANT, "delay_pool " << pool <<
+                   " has no delay_access configured. This means that no clients will ever use it.");
+            continue;
+        }
+
         ACLChecklist ch;
 #if FOLLOW_X_FORWARDED_FOR
         if (Config.onoff.delay_pool_uses_indirect_client)
@@ -124,8 +132,8 @@ DelayId::DelayClient(ClientHttpRequest * http)
 
         /* cbdataReferenceDone() happens in either fastCheck() or ~ACLCheckList */
 
-        if (DelayPools::delay_data[pool].theComposite().getRaw() &&
-                ch.fastCheck()) {
+        if (DelayPools::delay_data[pool].theComposite().getRaw() && ch.fastCheck()) {
+
             DelayId result (pool + 1);
             CompositePoolNode::CompositeSelectionDetails details;
             details.src_addr = ch.src_addr;
index 289ccc8b89401a7ebd50dfd2035be583d9034634..ba1cfe7e78c12e297d3c77f62e10c763dab27e05 100644 (file)
@@ -86,7 +86,7 @@ httpHeaderMaskInit(HttpHeaderMask * mask, int value)
     memset(mask, value, sizeof(*mask));
 }
 
-/* calculates a bit mask of a given array; does not reset mask! */
+/** calculates a bit mask of a given array; does not reset mask! */
 void
 httpHeaderCalcMask(HttpHeaderMask * mask, http_hdr_type http_hdr_type_enums[], size_t count)
 {
@@ -182,7 +182,7 @@ httpHeaderHasConnDir(const HttpHeader * hdr, const char *directive)
     return res;
 }
 
-/* returns true iff "m" is a member of the list */
+/** returns true iff "m" is a member of the list */
 int
 strListIsMember(const String * list, const char *m, char del)
 {
@@ -201,14 +201,14 @@ strListIsMember(const String * list, const char *m, char del)
     return 0;
 }
 
-/* returns true iff "s" is a substring of a member of the list */
+/** returns true iff "s" is a substring of a member of the list */
 int
 strListIsSubstr(const String * list, const char *s, char del)
 {
     assert(list && del);
     return list->pos(s) != 0;
 
-    /*
+    /** \note
      * Note: the original code with a loop is broken because it uses strstr()
      * instead of strnstr(). If 's' contains a 'del', strListIsSubstr() may
      * return true when it should not. If 's' does not contain a 'del', the
@@ -217,7 +217,7 @@ strListIsSubstr(const String * list, const char *s, char del)
      */
 }
 
-/* appends an item to the list */
+/** appends an item to the list */
 void
 strListAdd(String * str, const char *item, char del)
 {
@@ -234,7 +234,7 @@ strListAdd(String * str, const char *item, char del)
     str->append(item, strlen(item));
 }
 
-/*
+/**
  * iterates through a 0-terminated string of items separated by 'del's.
  * white space around 'del' is considered to be a part of 'del'
  * like strtok, but preserves the source, and can iterate several strings at once
@@ -301,7 +301,7 @@ strListGetItem(const String * str, char del, const char **item, int *ilen, const
     return len > 0;
 }
 
-/* handy to printf prefixes of potentially very long buffers */
+/** handy to printf prefixes of potentially very long buffers */
 const char *
 getStringPrefix(const char *str, const char *end)
 {
@@ -312,7 +312,7 @@ getStringPrefix(const char *str, const char *end)
     return buf;
 }
 
-/*
+/**
  * parses an int field, complains if soemthing went wrong, returns true on
  * success
  */
@@ -342,7 +342,8 @@ httpHeaderParseOffset(const char *start, int64_t * value)
 }
 
 
-/* Parses a quoted-string field (RFC 2616 section 2.2), complains if
+/**
+ * Parses a quoted-string field (RFC 2616 section 2.2), complains if
  * something went wrong, returns non-zero on success.
  * start should point at the first ".
  * RC TODO: This is too looose. We should honour the BNF and exclude CTL's
@@ -373,9 +374,13 @@ httpHeaderParseQuotedString (const char *start, String *val)
     }
 }
 
-/*
- * httpHdrMangle checks the anonymizer (header_access) configuration.
- * Returns 1 if the header is allowed.
+/**
+ * Checks the anonymizer (header_access) configuration.
+ * 
+ * \retval 0    Header is explicitly blocked for removal
+ * \retval 1    Header is explicitly allowed
+ * \retval 1    Header has been replaced, the current version can be used.
+ * \retval 1    Header has no access controls to test
  */
 static int
 httpHdrMangle(HttpHeaderEntry * e, HttpRequest * request, int req_or_rep)
@@ -396,10 +401,15 @@ httpHdrMangle(HttpHeaderEntry * e, HttpRequest * request, int req_or_rep)
         hm = &Config.request_header_access[e->id];
     }
 
+    /* mangler or checklist went away. default allow */
+    if(!hm || !hm->access_list) {
+        return 1;
+    }
+
     checklist = aclChecklistCreate(hm->access_list, request, NULL);
 
-    if (1 == checklist->fastCheck()) {
-        /* aclCheckFast returns 1 for allow. */
+    if (checklist->fastCheck()) {
+        /* aclCheckFast returns true for allow. */
         retval = 1;
     } else if (NULL == hm->replacement) {
         /* It was denied, and we don't have any replacement */
@@ -417,7 +427,7 @@ httpHdrMangle(HttpHeaderEntry * e, HttpRequest * request, int req_or_rep)
     return retval;
 }
 
-/* Mangles headers for a list of headers. */
+/** Mangles headers for a list of headers. */
 void
 httpHdrMangleList(HttpHeader * l, HttpRequest * request, int req_or_rep)
 {
@@ -433,7 +443,7 @@ httpHdrMangleList(HttpHeader * l, HttpRequest * request, int req_or_rep)
         l->refreshMask();
 }
 
-/*
+/**
  * return 1 if manglers are configured.  Used to set a flag
  * for optimization during request forwarding.
  */
index f0fabc45f23fac5225be5a8b13c8e7c2b3fdbfd0..92547dfe4a89ae4924f1ff58d7803fa3b605eca3 100644 (file)
@@ -543,7 +543,8 @@ HttpReply::calcMaxBodySize(HttpRequest& request)
     ch.reply = HTTPMSGLOCK(this); // XXX: this lock makes method non-const
     ch.request = HTTPMSGLOCK(&request);
     for (acl_size_t *l = Config.ReplyBodySize; l; l = l -> next) {
-        if (ch.matchAclListFast(l->aclList)) {
+        /* if there is no ACL list or if the ACLs listed match use this size value */
+        if (!l->aclList || ch.matchAclListFast(l->aclList)) {
             debugs(58, 4, HERE << "bodySizeMax=" << bodySizeMax);
             bodySizeMax = l->size; // may be -1
             break;
index ba1f84a962c310cf1099c0bc9fc4cbf977ed2b6c..290e0b3b290a668a78a8862d6eaf8252b8e93b45 100644 (file)
@@ -104,6 +104,7 @@ Adaptation::AccessCheck::checkCandidates()
 
     while (!candidates.empty()) {
         if (AccessRule *r = FindRule(topCandidate())) {
+            /* BUG 2526: what to do when r->acl is empty?? */
             // XXX: we do not have access to conn->rfc931 here.
             acl_checklist = aclChecklistCreate(r->acl, req, dash_str);
             acl_checklist->reply = rep ? HTTPMSGLOCK(rep) : NULL;
index 2dd1a45e624170e718b28dd1e4e649b33d3e1916..e647a08137e4599daf995e4070fef20981a79cba 100644 (file)
@@ -2857,19 +2857,16 @@ httpAccept(int sock, int newfd, ConnectionDetail *details,
 
 #if USE_IDENT
 
-    ACLChecklist identChecklist;
-
-    identChecklist.src_addr = details->peer;
-
-    identChecklist.my_addr = details->me;
-
-    identChecklist.accessList = cbdataReference(Config.accessList.identLookup);
-
-    /* cbdataReferenceDone() happens in either fastCheck() or ~ACLCheckList */
-
-    if (identChecklist.fastCheck())
-        identStart(details->me, details->peer, clientIdentDone, connState);
+    if (Config.accessList.identLookup) {
+        ACLChecklist identChecklist;
+        identChecklist.src_addr = details->peer;
+        identChecklist.my_addr = details->me;
+        identChecklist.accessList = cbdataReference(Config.accessList.identLookup);
 
+        /* cbdataReferenceDone() happens in either fastCheck() or ~ACLCheckList */
+        if (identChecklist.fastCheck())
+            identStart(details->me, details->peer, clientIdentDone, connState);
+    }
 #endif
 
     if (s->tcp_keepalive.enabled) {
@@ -3075,18 +3072,16 @@ httpsAccept(int sock, int newfd, ConnectionDetail *details,
 
 #if USE_IDENT
 
-    ACLChecklist identChecklist;
+    if (Config.accessList.identLookup) {
+        ACLChecklist identChecklist;
+        identChecklist.src_addr = details->peer;
+        identChecklist.my_addr = details->me;
+        identChecklist.accessList = cbdataReference(Config.accessList.identLookup);
 
-    identChecklist.src_addr = details->peer;
-
-    identChecklist.my_addr = details->me;
-
-    identChecklist.accessList = cbdataReference(Config.accessList.identLookup);
-
-    /* cbdataReferenceDone() happens in either fastCheck() or ~ACLCheckList */
-
-    if (identChecklist.fastCheck())
-        identStart(details->me, details->peer, clientIdentDone, connState);
+        /* cbdataReferenceDone() happens in either fastCheck() or ~ACLCheckList */
+        if (identChecklist.fastCheck())
+            identStart(details->me, details->peer, clientIdentDone, connState);
+    }
 
 #endif
 
index f166aaa0c40d9d6a9041be3cfeb5de4ee2fe0eb3..7f200aacb2e77c617825348fb489ebab2bb231a4 100644 (file)
@@ -1758,8 +1758,10 @@ clientReplyContext::sendBodyTooLargeError()
 void
 clientReplyContext::processReplyAccess ()
 {
+    /* NP: this should probably soft-fail to a zero-sized-reply error ?? */
     assert(reply);
-    /* Dont't block our own responses or HTTP status messages */
+
+    /** Don't block our own responses or HTTP status messages */
     if (http->logType == LOG_TCP_DENIED ||
             http->logType == LOG_TCP_DENIED_REPLY ||
             alwaysAllowResponse(reply->sline.status)) {
@@ -1768,6 +1770,7 @@ clientReplyContext::processReplyAccess ()
         return;
     }
 
+    /** Check for reply to big error */
     if (reply->expectedBodyTooLarge(*http->request)) {
         sendBodyTooLargeError();
         return;
@@ -1775,11 +1778,13 @@ clientReplyContext::processReplyAccess ()
 
     headers_sz = reply->hdr_sz;
 
+    /** check for absent access controls (permit by default) */
     if (!Config.accessList.reply) {
         processReplyAccessResult(1);
         return;
     }
 
+    /** Process http_reply_access lists */
     ACLChecklist *replyChecklist;
     replyChecklist = clientAclChecklistCreate(Config.accessList.reply, http);
     replyChecklist->reply = HTTPMSGLOCK(reply);
index cf8d0a6847231a16ac1ec303e5133840c2c8eb10..e6a665ff0ef48f8173df0955ac1702e5c754c724 100644 (file)
@@ -509,8 +509,13 @@ ClientRequestContext::clientAccessCheck()
     }
 #endif /* FOLLOW_X_FORWARDED_FOR */
 
-    acl_checklist = clientAclChecklistCreate(Config.accessList.http, http);
-    acl_checklist->nonBlockingCheck(clientAccessCheckDoneWrapper, this);
+    if (Config.accessList.http) {
+        acl_checklist = clientAclChecklistCreate(Config.accessList.http, http);
+        acl_checklist->nonBlockingCheck(clientAccessCheckDoneWrapper, this);
+    } else {
+        debugs(0, DBG_CRITICAL, "No http_access configuration found. This will block ALL traffic");
+        clientAccessCheckDone(ACCESS_DENIED);
+    }
 }
 
 void
@@ -1022,11 +1027,19 @@ ClientRequestContext::clientRedirectDone(char *result)
     http->doCallouts();
 }
 
+/** Test cache allow/deny configuration
+ *  Sets flags.cachable=1 if caching is not denied.
+ */
 void
 ClientRequestContext::checkNoCache()
 {
-    acl_checklist = clientAclChecklistCreate(Config.accessList.noCache, http);
-    acl_checklist->nonBlockingCheck(checkNoCacheDoneWrapper, this);
+    if (Config.accessList.noCache) {
+        acl_checklist = clientAclChecklistCreate(Config.accessList.noCache, http);
+        acl_checklist->nonBlockingCheck(checkNoCacheDoneWrapper, this);
+    } else {
+        /* unless otherwise specified, we try to cache. */
+        checkNoCacheDone(1);
+    }
 }
 
 static void
index 8c7598924b15eaebe02ab7c10cd5949c0a67b8c1..ea308a55499dae1dc9f13fe0e4ae5152635bba3c 100644 (file)
@@ -349,12 +349,6 @@ typedef enum {
     STREAM_FAILED
 } clientStream_status_t;
 
-typedef enum {
-    ACCESS_DENIED,
-    ACCESS_ALLOWED,
-    ACCESS_REQ_PROXY_AUTH
-} allow_t;
-
 typedef enum {
     AUTH_ACL_CHALLENGE = -2,
     AUTH_ACL_HELPER = -1,
index a03a8fa014e9f0875ffba0f7070440f5c03ca24d..6cab0929fb263c4393a57c0c6fa2d5a33bdac39e 100644 (file)
@@ -194,14 +194,15 @@ FwdState::~FwdState()
 void
 FwdState::fwdStart(int client_fd, StoreEntry *entry, HttpRequest *request)
 {
-    /*
+    /** \note
      * client_addr == no_addr indicates this is an "internal" request
      * from peer_digest.c, asn.c, netdb.c, etc and should always
      * be allowed.  yuck, I know.
      */
 
-    if ( !request->client_addr.IsNoAddr() && request->protocol != PROTO_INTERNAL && request->protocol != PROTO_CACHEOBJ) {
-        /*
+    if ( Config.accessList.miss && !request->client_addr.IsNoAddr() &&
+         request->protocol != PROTO_INTERNAL && request->protocol != PROTO_CACHEOBJ) {
+        /**
          * Check if this host is allowed to fetch MISSES from us (miss_access)
          */
         ACLChecklist ch;
@@ -1312,7 +1313,7 @@ aclMapAddr(acl_address * head, ACLChecklist * ch)
     IpAddress addr;
 
     for (l = head; l; l = l->next) {
-        if (ch->matchAclListFast(l->aclList))
+        if (!l->aclList || ch->matchAclListFast(l->aclList))
             return l->addr;
     }
 
@@ -1330,7 +1331,7 @@ aclMapTOS(acl_tos * head, ACLChecklist * ch)
     acl_tos *l;
 
     for (l = head; l; l = l->next) {
-        if (ch->matchAclListFast(l->aclList))
+        if (!l->aclList || ch->matchAclListFast(l->aclList))
             return l->tos;
     }
 
@@ -1345,6 +1346,10 @@ getOutgoingAddr(HttpRequest * request, struct peer *dst_peer)
     if (request && request->flags.spoof_client_ip)
         return request->client_addr;
 
+    if (!Config.accessList.outgoing_address) {
+        return IpAddress(); // anything will do.
+    }
+
     ch.dst_peer = dst_peer;
 
     if (request) {
index 77e5645d56b32dc24ba93b7840ebff7c0473beec..fe3bbf7b166579685e7dd37947e6bbf974db9fc0 100644 (file)
@@ -844,9 +844,12 @@ htcpUnpackDetail(char *buf, int sz)
 }
 
 static int
-
 htcpAccessCheck(acl_access * acl, htcpSpecifier * s, IpAddress &from)
 {
+    /* default deny if no access list present */
+    if (!acl)
+        return 0;
+
     ACLChecklist checklist;
     checklist.src_addr = from;
     checklist.my_addr.SetNoAddr();
index 6b3f1a519ccb6168254245da65f86be309bdb9f8..ec7d8c7f94238d4732124d8cbede959b9d0261d2 100644 (file)
@@ -405,6 +405,10 @@ icpDenyAccess(IpAddress &from, char *url, int reqnum, int fd)
 int
 icpAccessAllowed(IpAddress &from, HttpRequest * icp_request)
 {
+    /* absent an explicit allow, we deny all */
+    if (!Config.accessList.icp)
+        return 0;
+
     ACLChecklist checklist;
     checklist.src_addr = from;
     checklist.my_addr.SetNoAddr();
index a5eb32c2613075830576882abcc7a85090054f09..e9f4a5c3b2b2d9579646188220505264dc8b6589 100644 (file)
@@ -290,18 +290,21 @@ peerSelectFoo(ps_state * ps)
     HttpRequest *request = ps->request;
     debugs(44, 3, "peerSelectFoo: '" << RequestMethodStr(request->method) << " " << request->GetHost() << "'");
 
+    /** If we don't known whether DIRECT is permitted ... */
     if (ps->direct == DIRECT_UNKNOWN) {
         if (ps->always_direct == 0 && Config.accessList.AlwaysDirect) {
+            /** check always_direct; */
             ps->acl_checklist = aclChecklistCreate(
                                     Config.accessList.AlwaysDirect,
                                     request,
                                     NULL);             /* ident */
-            ps->acl_checklist->nonBlockingCheck(peerCheckAlwaysDirectDone,
-                                                ps);
+            ps->acl_checklist->nonBlockingCheck(peerCheckAlwaysDirectDone, ps);
             return;
         } else if (ps->always_direct > 0) {
+            /** if always_direct says YES, do that. */
             ps->direct = DIRECT_YES;
         } else if (ps->never_direct == 0 && Config.accessList.NeverDirect) {
+            /** check never_direct; */
             ps->acl_checklist = aclChecklistCreate(
                                     Config.accessList.NeverDirect,
                                     request,
@@ -310,10 +313,13 @@ peerSelectFoo(ps_state * ps)
                                                 ps);
             return;
         } else if (ps->never_direct > 0) {
+            /** if always_direct says NO, do that. */
             ps->direct = DIRECT_NO;
         } else if (request->flags.accelerated) {
+            /** if we are accelerating, direct is not an option. */
             ps->direct = DIRECT_NO;
         } else if (request->flags.loopdetect) {
+            /** if we are in a forwarding-loop, direct is not an option. */
             ps->direct = DIRECT_YES;
         } else if (peerCheckNetdbDirect(ps)) {
             ps->direct = DIRECT_YES;
index 71cd059529b2fa3303e72f910256afa4b61a3459..5c4b9d9caef31afb111146bc4379c54ae183c758 100644 (file)
@@ -532,7 +532,9 @@ snmpDecodePacket(snmp_request_t * rq)
     rq->session.Version = SNMP_VERSION_1;
     Community = snmp_parse(&rq->session, PDU, buf, len);
 
-    if (Community) {
+    /* Check if we have explicit permission to access SNMP data.
+     * default (set above) is to deny all */
+    if (Community && Config.accessList.snmp) {
         ACLChecklist checklist;
         checklist.accessList = cbdataReference(Config.accessList.snmp);
         checklist.src_addr = rq->from;
index aad28a28af6f5afd7ac9b89c027c7703c5683a0b..7048133277da0a8fd75b60d9dcbcb7378380ba47 100644 (file)
@@ -613,9 +613,10 @@ tunnelStart(ClientHttpRequest * http, int64_t * size_ptr, int *status_ptr)
      * be allowed.  yuck, I know.
      */
 
-    if (!request->client_addr.IsNoAddr()) {
+    if (!request->client_addr.IsNoAddr() && Config.accessList.miss) {
         /*
          * Check if this host is allowed to fetch MISSES from us (miss_access)
+         * default is to allow.
          */
         ACLChecklist ch;
         ch.src_addr = request->client_addr;