]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Summary: Merge further ACL refactoring (including bugfixes)
authorrobertc <>
Thu, 13 Feb 2003 15:07:46 +0000 (15:07 +0000)
committerrobertc <>
Thu, 13 Feb 2003 15:07:46 +0000 (15:07 +0000)
Keywords:

Patches applied:

  * robertc@squid-cache.org--squid/squid--acl--3.0--patch-13
     More conversion of ACL's

  * robertc@squid-cache.org--squid/squid--acl--3.0--patch-12
     Fix ACLChecklist async tests.

  * robertc@squid-cache.org--squid/squid--acl--3.0--patch-11
     More conversion to the new ACL approach.

21 files changed:
src/ACL.h
src/ACLChecklist.cc [new file with mode: 0644]
src/ACLChecklist.h
src/ACLData.h [new file with mode: 0644]
src/ACLIP.cc
src/ACLProxyAuth.cc
src/ACLProxyAuth.h
src/ACLRegexData.cc [new file with mode: 0644]
src/ACLRegexData.h [new file with mode: 0644]
src/ACLUserData.cc
src/ACLUserData.h
src/ExternalACL.h [new file with mode: 0644]
src/Makefile.am
src/Makefile.in
src/acl.cc
src/cf.data.pre
src/client_side_reply.cc
src/client_side_request.cc
src/enums.h
src/external_acl.cc
src/peer_select.cc

index 48a4bd36e64b8cec1d98845ae02f3c6cd9db0aee..ca82697c3f8e6e47b8f3024864699e124eb5781d 100644 (file)
--- a/src/ACL.h
+++ b/src/ACL.h
@@ -1,6 +1,6 @@
 
 /*
- * $Id: ACL.h,v 1.3 2003/02/12 06:10:58 robertc Exp $
+ * $Id: ACL.h,v 1.4 2003/02/13 08:07:46 robertc Exp $
  *
  *
  * SQUID Web Proxy Cache          http://www.squid-cache.org/
@@ -66,12 +66,18 @@ SQUIDCEXTERN void aclParseDenyInfoLine(struct _acl_deny_info_list **);
 SQUIDCEXTERN void aclDestroyDenyInfoList(struct _acl_deny_info_list **);
 SQUIDCEXTERN void aclDestroyRegexList(struct _relist *data);
 SQUIDCEXTERN int aclMatchRegex(relist * data, const char *word);
+wordlist *aclDumpRegexList(relist * data);
 SQUIDCEXTERN void aclParseRegexList(void *curlist);
 SQUIDCEXTERN wordlist *aclDumpGeneric(const acl *);
 SQUIDCEXTERN int aclPurgeMethodInUse(acl_access *);
 SQUIDCEXTERN void aclCacheMatchFlush(dlink_list * cache);
-SQUIDCEXTERN int aclAuthenticated(ACLChecklist * checklist);
-void dump_acl_access(StoreEntry * entry, const char *name, acl_access * head);
+extern void dump_acl_access(StoreEntry * entry, const char *name, acl_access * head);
+IPH aclLookupDstIPforASNDone;
+#if USE_IDENT
+IDCB aclLookupIdentDone;
+#endif
+FQDNH aclLookupSrcFQDNDone;
+FQDNH aclLookupDstFQDNDone;
 
 class ACL {
   public:
@@ -81,6 +87,10 @@ class ACL {
 
     static ACL *Factory (char const *);
     static void ParseAclLine(acl ** head);
+    static ACL* FindByName(const char *name);
+
+    /* temporary until we subclass external acl's */
+    static void ExternalAclLookup(ACLChecklist * ch, ACL *, EAH * callback, void *callback_data);
 
     ACL();
     ACL (squid_acl const);
@@ -95,7 +105,6 @@ class ACL {
     virtual wordlist *dumpGeneric() const;
     virtual wordlist *dump() const;
     virtual bool valid () const;
-    virtual void startExternal(ACLChecklist *);
     int checklistMatches(ACLChecklist *);
     
     /* only relevant to METHOD acl's */
@@ -104,6 +113,8 @@ class ACL {
     /* only relecant to ASN acl's */
     void startCache();
     
+    int cacheMatchAcl(dlink_list * cache, ACLChecklist *);
+    virtual int matchForCache(ACLChecklist *checklist);
 
     char name[ACL_NAME_SZ];
     char *cfgline;
diff --git a/src/ACLChecklist.cc b/src/ACLChecklist.cc
new file mode 100644 (file)
index 0000000..b800c4a
--- /dev/null
@@ -0,0 +1,407 @@
+/*
+ * $Id: ACLChecklist.cc,v 1.1 2003/02/13 08:07:46 robertc Exp $
+ *
+ * DEBUG: section 28    Access Control
+ * AUTHOR: Duane Wessels
+ *
+ * SQUID Web Proxy Cache          http://www.squid-cache.org/
+ * ----------------------------------------------------------
+ *
+ *  Squid is the result of efforts by numerous individuals from
+ *  the Internet community; see the CONTRIBUTORS file for full
+ *  details.   Many organizations have provided support for Squid's
+ *  development; see the SPONSORS file for full details.  Squid is
+ *  Copyrighted (C) 2001 by the Regents of the University of
+ *  California; see the COPYRIGHT file for full details.  Squid
+ *  incorporates software developed and/or copyrighted by other
+ *  sources; see the CREDITS file for full details.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *  
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *  
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ *
+ * Copyright (c) 2003, Robert Collins <robertc@squid-cache.org>
+ */
+
+#include "squid.h"
+#include "ACLChecklist.h"
+/* TODO: trim this ! */
+#include "splay.h"
+#include "HttpRequest.h"
+#include "authenticate.h"
+#include "fde.h"
+#include "ACLProxyAuth.h"
+#if USE_IDENT
+#include "ACLIdent.h"
+#endif
+#include "ACLUserData.h"
+
+int
+ACLChecklist::authenticated()
+{
+    http_hdr_type headertype;
+    if (NULL == request) {
+       fatal ("requiresRequest SHOULD have been true for this ACL!!");
+    } else if (!request->flags.accelerated) {
+       /* Proxy authorization on proxy requests */
+       headertype = HDR_PROXY_AUTHORIZATION;
+    } else if (request->flags.internal) {
+       /* WWW authorization on accelerated internal requests */
+       headertype = HDR_AUTHORIZATION;
+    } else {
+#if AUTH_ON_ACCELERATION
+       /* WWW authorization on accelerated requests */
+       headertype = HDR_AUTHORIZATION;
+#else
+       debug(28, 1) ("ACHChecklist::authenticated: authentication not applicable on accelerated requests.\n");
+       return -1;
+#endif
+    }
+    /* get authed here */
+    /* Note: this fills in auth_user_request when applicable */
+    switch (authenticateTryToAuthenticateAndSetAuthUser(&auth_user_request, headertype, request, conn(), src_addr)) {
+    case AUTH_ACL_CANNOT_AUTHENTICATE:
+       debug(28, 4) ("aclMatchAcl: returning  0 user authenticated but not authorised.\n");
+       return 0;
+    case AUTH_AUTHENTICATED:
+       return 1;
+       break;
+    case AUTH_ACL_HELPER:
+       debug(28, 4) ("aclMatchAcl: returning 0 sending credentials to helper.\n");
+       changeState (ProxyAuthLookup::Instance());
+       return 0;
+    case AUTH_ACL_CHALLENGE:
+       debug(28, 4) ("aclMatchAcl: returning 0 sending authentication challenge.\n");
+       changeState (ProxyAuthNeeded::Instance());
+       return 0;
+    default:
+       fatal("unexpected authenticateAuthenticate reply\n");
+       return 0;
+    }
+}
+
+allow_t const &
+ACLChecklist::currentAnswer() const
+{
+    return allow_;
+}
+
+void
+ACLChecklist::currentAnswer(allow_t const newAnswer)
+{
+    allow_ = newAnswer;
+}
+    
+void
+ACLChecklist::check()
+{
+    /* deny if no rules present */
+    currentAnswer(ACCESS_DENIED);
+    /* NOTE: This holds a cbdata reference to the current access_list
+     * entry, not the whole list.
+     */
+    while (accessList != NULL) {
+       /*
+        * If the _acl_access is no longer valid (i.e. its been
+        * freed because of a reconfigure), then bail on this
+        * access check.  For now, return ACCESS_DENIED.
+        */
+       if (!cbdataReferenceValid(accessList)) {
+           cbdataReferenceDone(accessList);
+           break;
+       }
+
+       checkAccessList();
+       if (asyncInProgress())
+           return;
+
+       if (finished()) {
+           /*
+            * We are done.  Either the request
+            * is allowed, denied, requires authentication.
+            */
+           debug(28, 3) ("ACLChecklist::check: match found, returning %d\n", currentAnswer());
+           cbdataReferenceDone(accessList); /* A */
+           checkCallback(currentAnswer());
+           /* From here on in, this may be invalid */
+           return;
+       }
+       /*
+        * Reference the next access entry
+        */
+       const acl_access *A = accessList;
+       accessList = cbdataReference(accessList->next);
+       cbdataReferenceDone(A);
+    }
+    /* dropped off the end of the list */
+    debug(28, 3) ("ACLChecklist::check: NO match found, returning %d\n", 
+                 currentAnswer() != ACCESS_DENIED ? ACCESS_DENIED : ACCESS_ALLOWED);
+    checkCallback(currentAnswer() != ACCESS_DENIED ? ACCESS_DENIED : ACCESS_ALLOWED);
+}
+
+bool
+ACLChecklist::asyncInProgress() const
+{
+    return async_;
+}
+
+void
+ACLChecklist::asyncInProgress(bool const newAsync)
+{
+    assert (!finished());
+    async_ = newAsync;
+    debug (28,3)("ACLChecklist::asyncInProgress: async set to %d\n",async_);
+}
+
+bool
+ACLChecklist::finished() const
+{
+    return finished_;
+}
+
+void
+ACLChecklist::markFinished()
+{
+    assert (!finished());
+    finished_ = true;
+    debug (28,3)("checklist processing finished\n");
+}
+
+void
+ACLChecklist::checkAccessList()
+{
+    debug(28, 3) ("ACLChecklist::checkAccessList: checking '%s'\n", accessList->cfgline);
+    /* what is our result on a match? */
+    currentAnswer(accessList->allow);
+    /* does the current AND clause match */
+    bool match = matchAclList(accessList->aclList);
+    if (match)
+       markFinished();
+    /* Should be else, but keep the exact same flow as before */
+    checkForAsync();
+}
+
+void
+ACLChecklist::checkForAsync()
+{
+    /* check for async lookups needed. */
+    if (asyncState() != NullState::Instance()) {
+       /* If a state object is here, use it.
+        * When all cases are converted, the if goes away and it
+        * becomes unconditional.
+        * RBC 02 2003
+        */
+       asyncState()->checkForAsync(this);
+    } else if (state[ACL_DST_ASN] == ACL_LOOKUP_NEEDED) {
+       state[ACL_DST_ASN] = ACL_LOOKUP_PENDING;
+       ipcache_nbgethostbyname(request->host,
+                               aclLookupDstIPforASNDone, this);
+    asyncInProgress(true);
+    } else if (state[ACL_SRC_DOMAIN] == ACL_LOOKUP_NEEDED) {
+       state[ACL_SRC_DOMAIN] = ACL_LOOKUP_PENDING;
+       fqdncache_nbgethostbyaddr(src_addr,
+                                 aclLookupSrcFQDNDone, this);
+    asyncInProgress(true);
+    } else if (state[ACL_DST_DOMAIN] == ACL_LOOKUP_NEEDED) {
+       ipcache_addrs *ia;
+       ia = ipcacheCheckNumeric(request->host);
+       if (ia == NULL) {
+           state[ACL_DST_DOMAIN] = ACL_LOOKUP_DONE;
+       } else {
+           dst_addr = ia->in_addrs[0];
+           state[ACL_DST_DOMAIN] = ACL_LOOKUP_PENDING;
+           fqdncache_nbgethostbyaddr(dst_addr,
+                                     aclLookupDstFQDNDone, this);
+       }
+    asyncInProgress(true);
+#if USE_IDENT
+    } else if (state[ACL_IDENT] == ACL_LOOKUP_NEEDED) {
+       debug(28, 3) ("ACLChecklist::checkForAsync: Doing ident lookup\n");
+       if (conn() && cbdataReferenceValid(conn())) {
+           identStart(&conn()->me, &conn()->peer,
+                      aclLookupIdentDone, this);
+           state[ACL_IDENT] = ACL_LOOKUP_PENDING;
+       } else {
+           debug(28, 1) ("ACLChecklist::checkForAsync: Can't start ident lookup. No client connection\n");
+           currentAnswer(ACCESS_DENIED);
+           markFinished();
+           return;
+       }
+    asyncInProgress(true);
+#endif
+    }
+}
+
+void
+ACLChecklist::checkCallback(allow_t answer)
+{
+    PF *callback_;
+    void *cbdata_;
+    debug(28, 3) ("ACLChecklist::checkCallback: answer=%d\n", answer);
+    /* During reconfigure, we can end up not finishing call
+     * sequences into the auth code */
+    if (auth_user_request) {
+       /* the checklist lock */
+       authenticateAuthUserRequestUnlock(auth_user_request);
+       /* it might have been connection based */
+       assert(conn());
+       conn()->auth_user_request = NULL;
+       conn()->auth_type = AUTH_BROKEN;
+       auth_user_request = NULL;
+    }
+    callback_ = callback;
+    callback = NULL;
+    if (cbdataReferenceValidDone(callback_data, &cbdata_))
+       callback_(answer, cbdata_);
+    delete this;
+}
+bool
+ACLChecklist::matchAclList(const acl_list * head)
+{
+    PROF_start(aclMatchAclList);
+    const acl_list *node = head;
+    while (node) {
+       if (!node->matches(this)) {
+           debug(28, 3) ("aclmatchAclList: returning false (AND list entry failed to match)\n");
+           PROF_stop(aclMatchAclList);
+           return false;
+       }
+       node = node->next;
+    }
+    debug(28, 3) ("aclmatchAclList: returning true (AND list satisfied)\n");
+    PROF_stop(aclMatchAclList);
+    return true;
+}
+
+CBDATA_CLASS_INIT(ACLChecklist);
+
+void *
+ACLChecklist::operator new (size_t size)
+{
+    assert (size == sizeof(ACLChecklist));
+    CBDATA_INIT_TYPE(ACLChecklist);
+    ACLChecklist *result = cbdataAlloc(ACLChecklist);
+    /* Mark result as being owned - we want the refcounter to do the delete
+     * call */
+    cbdataReference(result);
+    return result;
+}
+void
+ACLChecklist::operator delete (void *address)
+{
+    ACLChecklist *t = static_cast<ACLChecklist *>(address);
+    cbdataFree(address);
+    /* And allow the memory to be freed */
+    cbdataReferenceDone (t);
+}
+
+void
+ACLChecklist::deleteSelf() const
+{
+    delete this;
+}
+
+ACLChecklist::ACLChecklist() : accessList (NULL), my_port (0), request (NULL),
+  reply (NULL),
+  auth_user_request (NULL)
+#if SQUID_SNMP
+    ,snmp_community(NULL)
+#endif
+  , callback (NULL),
+  callback_data (NULL),
+  extacl_entry (NULL),
+  conn_(NULL),
+  async_(false),
+  finished_(false),
+  allow_(ACCESS_DENIED),
+  state_(NullState::Instance())
+{
+    memset (&src_addr, '\0', sizeof (struct in_addr));
+    memset (&dst_addr, '\0', sizeof (struct in_addr));
+    memset (&my_addr, '\0', sizeof (struct in_addr));
+    rfc931[0] = '\0';
+    memset (&state, '\0', sizeof (state));
+}
+
+ACLChecklist::~ACLChecklist()
+{
+    assert (!asyncInProgress());
+    if (extacl_entry)
+       cbdataReferenceDone(extacl_entry);
+    if (request)
+       requestUnlink(request);
+    request = NULL;
+    cbdataReferenceDone(conn_);
+    cbdataReferenceDone(accessList);
+}
+
+
+ConnStateData *
+ACLChecklist::conn()
+{
+    return  conn_;
+}
+
+void
+ACLChecklist::conn(ConnStateData *aConn)
+{
+    assert (conn() == NULL);
+    conn_ = aConn;
+}
+
+void
+ACLChecklist::AsyncState::changeState (ACLChecklist *checklist, AsyncState *newState) const
+{
+    checklist->changeState(newState);
+}
+
+ACLChecklist::NullState *
+ACLChecklist::NullState::Instance()
+{
+    return &_instance;
+}
+
+void
+ACLChecklist::NullState::checkForAsync(ACLChecklist *) const
+{
+}
+
+ACLChecklist::NullState ACLChecklist::NullState::_instance;
+
+void
+ACLChecklist::changeState (AsyncState *newState)
+{
+    /* only change from null to active and back again,
+     * not active to active.
+     * relax this once conversion to states is complete
+     * RBC 02 2003
+     */
+    assert (state_ == NullState::Instance() || newState == NullState::Instance());
+    state_ = newState;
+}
+
+ACLChecklist::AsyncState *
+ACLChecklist::asyncState() const
+{
+    return state_;
+}
+
+void
+ACLChecklist::nonBlockingCheck(PF * callback_, void *callback_data_)
+{
+    callback = callback_;
+    callback_data = cbdataReference(callback_data_);
+    check();
+}
+
index f272b72455d712f067996a2e0082d479b71a58f6..3707f3ca861866e48b68196d032d9605fa0a022f 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: ACLChecklist.h,v 1.2 2003/02/12 06:10:58 robertc Exp $
+ * $Id: ACLChecklist.h,v 1.3 2003/02/13 08:07:46 robertc Exp $
  *
  *
  * SQUID Web Proxy Cache          http://www.squid-cache.org/
@@ -78,10 +78,12 @@ class ACLChecklist {
     ACLChecklist (ACLChecklist const &);
     ACLChecklist &operator=(ACLChecklist const &);
 
+    void nonBlockingCheck(PF * callback, void *callback_data);
     void checkCallback(allow_t answer);
-    int matchAclList(const acl_list * list);
+    bool matchAclList(const acl_list * list);
     ConnStateData *conn();
     void conn(ConnStateData *);
+    int authenticated();
 
     bool asyncInProgress() const;
     void asyncInProgress(bool const);
@@ -124,7 +126,6 @@ private:
 SQUIDCEXTERN ACLChecklist *aclChecklistCreate(const acl_access *,
     request_t *,
     const char *ident);
-SQUIDCEXTERN void aclNBCheck(ACLChecklist *, PF *, void *);
 SQUIDCEXTERN int aclCheckFast(const acl_access *A, ACLChecklist *);
 
 #endif /* SQUID_ACLCHECKLIST_H */
diff --git a/src/ACLData.h b/src/ACLData.h
new file mode 100644 (file)
index 0000000..d595217
--- /dev/null
@@ -0,0 +1,50 @@
+
+/*
+ * $Id: ACLData.h,v 1.1 2003/02/13 08:07:47 robertc Exp $
+ *
+ *
+ * SQUID Web Proxy Cache          http://www.squid-cache.org/
+ * ----------------------------------------------------------
+ *
+ *  Squid is the result of efforts by numerous individuals from
+ *  the Internet community; see the CONTRIBUTORS file for full
+ *  details.   Many organizations have provided support for Squid's
+ *  development; see the SPONSORS file for full details.  Squid is
+ *  Copyrighted (C) 2001 by the Regents of the University of
+ *  California; see the COPYRIGHT file for full details.  Squid
+ *  incorporates software developed and/or copyrighted by other
+ *  sources; see the CREDITS file for full details.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *  
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *  
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ *
+ *
+ * Copyright (c) 2003, Robert Collins <robertc@squid-cache.org>
+ */
+
+#ifndef SQUID_ACLDATA_H
+#define SQUID_ACLDATA_H
+
+class ACLData {
+  public:
+    virtual void deleteSelf() const =0;
+
+    virtual ~ACLData() {}
+    virtual bool match(char const *user) =0;
+    virtual wordlist *dump() =0;
+    virtual void parse() =0;
+    virtual ACLData *clone() const =0;
+};
+
+#endif /* SQUID_ACLDATA_H */
index 2e1a74085b0e799077ef09b99a1cf89ef1b6eb40..1cf8f451a7a8a0e35571f7a97a62fe95ed0ff63e 100644 (file)
@@ -371,5 +371,5 @@ acl_ip_data::deleteSelf() const
     delete this;
 }
 
-acl_ip_data::acl_ip_data () :addr1(no_addr), addr2(no_addr), mask (no_addr), next (NULL) {}
+acl_ip_data::acl_ip_data () :addr1(any_addr), addr2(any_addr), mask (any_addr), next (NULL) {}
 acl_ip_data::acl_ip_data (struct in_addr const &anAddress1, struct in_addr const &anAddress2, struct in_addr const &aMask, acl_ip_data *aNext) : addr1(anAddress1), addr2(anAddress2), mask(aMask), next(aNext){}
index 32af8163030c24ed4fa7a17a486bd198aaf37edc..0c2473fc023698732b8514c3083d0649c126252f 100644 (file)
@@ -38,6 +38,8 @@
 #include "ACLProxyAuth.h"
 #include "authenticate.h"
 #include "ACLChecklist.h"
+#include "ACLUserData.h"
+#include "ACLRegexData.h"
 
 MemPool *ACLProxyAuth::Pool(NULL);
 void *
@@ -64,7 +66,18 @@ ACLProxyAuth::deleteSelf() const
 
 ACLProxyAuth::~ACLProxyAuth()
 {
-    delete data;
+    data->deleteSelf();
+}
+
+ACLProxyAuth::ACLProxyAuth(ACLData *newData) : data (newData) {}
+ACLProxyAuth::ACLProxyAuth (ACLProxyAuth const &old) : data (old.data->clone())
+{
+}
+ACLProxyAuth &
+ACLProxyAuth::operator= (ACLProxyAuth const &rhs)
+{
+    data = rhs.data->clone();
+    return *this;
 }
 
 char const *
@@ -79,28 +92,23 @@ ACLProxyAuth::parse()
     if (authenticateSchemeCount() == 0) {
        debug(28, 0) ("aclProxyAuth::parse: IGNORING: Proxy Auth ACL '%s' "
                      "because no authentication schemes were compiled.\n", cfgline);
-    } else if (authenticateActiveSchemeCount() == 0) {
+       return;
+    }
+    if (authenticateActiveSchemeCount() == 0) {
        debug(28, 0) ("aclProxyAuth::parse: IGNORING: Proxy Auth ACL '%s' "
                      "because no authentication schemes are fully configured.\n", cfgline);
-    } else {
-       debug(28, 3) ("aclParseUserList: current is null. Creating\n");
-       data = new ACLUserData;
-       data->parse();
+       return;
     }
+    data->parse();
 }
 
-extern int
-aclMatchProxyAuth(void *data, auth_user_request_t * auth_user_request,
-    ACLChecklist * checklist, squid_acl acltype);
 int
 ACLProxyAuth::match(ACLChecklist *checklist)
 {
     int ti;
-    if ((ti = aclAuthenticated(checklist)) != 1)
+    if ((ti = checklist->authenticated()) != 1)
        return ti;
-    ti = aclMatchProxyAuth(data, checklist->auth_user_request,
-                          checklist, aclType());
-    checklist->auth_user_request = NULL;
+    ti = matchProxyAuth(checklist);
     return ti;
 }
 
@@ -115,3 +123,115 @@ ACLProxyAuth::valid () const
 {
     return data != NULL;
 }
+
+ProxyAuthNeeded ProxyAuthNeeded::instance_;
+
+ProxyAuthNeeded *
+ProxyAuthNeeded::Instance()
+{
+    return &instance_;
+}
+
+ProxyAuthLookup ProxyAuthLookup::instance_;
+
+ProxyAuthLookup *
+ProxyAuthLookup::Instance()
+{
+    return &instance_;
+}
+
+void
+ProxyAuthLookup::checkForAsync(ACLChecklist *checklist)const
+{
+    checklist->asyncInProgress(true);
+    debug(28, 3)
+      ("ACLChecklist::checkForAsync: checking password via authenticator\n");
+
+    auth_user_request_t *auth_user_request;
+    /* make sure someone created auth_user_request for us */
+    assert(checklist->auth_user_request != NULL);
+    auth_user_request = checklist->auth_user_request;
+
+    assert(authenticateValidateUser(auth_user_request));
+    authenticateStart(auth_user_request, LookupDone, checklist);
+}
+
+void
+ProxyAuthLookup::LookupDone(void *data, char *result)
+{
+    ACLChecklist *checklist = (ACLChecklist *)data;
+    assert (checklist->asyncState() == ProxyAuthLookup::Instance());
+
+    if (result != NULL)
+       fatal("AclLookupProxyAuthDone: Old code floating around somewhere.\nMake clean and if that doesn't work, report a bug to the squid developers.\n");
+    if (!authenticateValidateUser(checklist->auth_user_request) || checklist->conn() == NULL) {
+       /* credentials could not be checked either way
+        * restart the whole process */
+       /* OR the connection was closed, there's no way to continue */
+       authenticateAuthUserRequestUnlock(checklist->auth_user_request);
+       if (checklist->conn()) {
+           checklist->conn()->auth_user_request = NULL;
+           checklist->conn()->auth_type = AUTH_BROKEN;
+       }
+       checklist->auth_user_request = NULL;
+    }
+    checklist->asyncInProgress(false);
+    checklist->changeState (ACLChecklist::NullState::Instance());
+    checklist->check();
+}
+
+void
+ProxyAuthNeeded::checkForAsync(ACLChecklist *checklist) const
+{
+    /* Client is required to resend the request with correct authentication
+     * credentials. (This may be part of a stateful auth protocol.)
+     * The request is denied.
+     */
+    debug(28, 6) ("ACLChecklist::checkForAsync: requiring Proxy Auth header.\n");
+    checklist->currentAnswer(ACCESS_REQ_PROXY_AUTH);
+    checklist->markFinished();
+}
+
+ACL::Prototype ACLProxyAuth::UserRegistryProtoype(&ACLProxyAuth::UserRegistryEntry_, "proxy_auth");
+ACLProxyAuth ACLProxyAuth::UserRegistryEntry_(new ACLUserData);
+ACL::Prototype ACLProxyAuth::RegexRegistryProtoype(&ACLProxyAuth::RegexRegistryEntry_, "proxy_auth_regex");
+ACLProxyAuth ACLProxyAuth::RegexRegistryEntry_(new ACLRegexData);
+
+ACL *
+ACLProxyAuth::clone() const
+{
+    return new ACLProxyAuth(*this);
+}
+
+int
+ACLProxyAuth::matchForCache(ACLChecklist *checklist)
+{
+    return data->match(authenticateUserRequestUsername(checklist->auth_user_request));
+}
+
+/* aclMatchProxyAuth can return two exit codes:
+ * 0 : Authorisation for this ACL failed. (Did not match)
+ * 1 : Authorisation OK. (Matched)
+ */
+int
+ACLProxyAuth::matchProxyAuth(ACLChecklist *checklist)
+{
+    checkAuthForCaching(checklist);
+    /* check to see if we have matched the user-acl before */
+    int result = cacheMatchAcl(&checklist->auth_user_request->auth_user->
+       proxy_match_cache, checklist);
+    checklist->auth_user_request = NULL;
+    return result;
+}
+
+void
+ACLProxyAuth::checkAuthForCaching(ACLChecklist *checklist)const
+{
+    /* for completeness */
+    authenticateAuthUserRequestLock(checklist->auth_user_request);
+    /* consistent parameters ? */
+    assert(authenticateUserAuthenticated(checklist->auth_user_request));
+    /* this check completed */
+    authenticateAuthUserRequestUnlock(checklist->auth_user_request);
+}
+
index 2fd75618e8ac6cea040335f2c5be3fb828a97d11..1ae5b3713161d527f5d840545aa47a967c32d39c 100644 (file)
 #ifndef SQUID_ACLPROXYAUTH_H
 #define SQUID_ACLPROXYAUTH_H
 #include "ACL.h"
-#include "ACLUserData.h"
+#include "ACLData.h"
+#include "ACLChecklist.h"
+
+class ProxyAuthLookup : public ACLChecklist::AsyncState {
+  public:
+    static ProxyAuthLookup *Instance();
+    virtual void checkForAsync(ACLChecklist *)const;
+  private:
+    static ProxyAuthLookup instance_;
+    static void LookupDone(void *data, char *result);
+};
+
+class ProxyAuthNeeded : public ACLChecklist::AsyncState {
+  public:
+    static ProxyAuthNeeded *Instance();
+    virtual void checkForAsync(ACLChecklist *)const;
+  private:
+    static ProxyAuthNeeded instance_;
+};
 
 class ACLProxyAuth : public ACL {
   public:
@@ -45,17 +63,29 @@ class ACLProxyAuth : public ACL {
     virtual void deleteSelf() const;
 
     ~ACLProxyAuth();
+    ACLProxyAuth(ACLData *);
+    ACLProxyAuth (ACLProxyAuth const &);
+    ACLProxyAuth &operator= (ACLProxyAuth const &);
     
     virtual char const *typeString() const;
-    virtual squid_acl aclType() const { return ACL_PROXY_AUTH;}
+    virtual squid_acl aclType() const { return ACL_DERIVED;}
     virtual void parse();
     virtual bool isProxyAuth() const {return true;}
     virtual int match(ACLChecklist *checklist);
     virtual wordlist *dump() const;
     virtual bool valid () const;
+    virtual bool requiresRequest() const {return true;}
+    virtual ACL *clone()const;
+    virtual int matchForCache(ACLChecklist *checklist);
   private:
     static MemPool *Pool;
-    ACLUserData *data;
+    static Prototype UserRegistryProtoype;
+    static ACLProxyAuth UserRegistryEntry_;
+    static Prototype RegexRegistryProtoype;
+    static ACLProxyAuth RegexRegistryEntry_;
+    int matchProxyAuth(ACLChecklist *);
+    void checkAuthForCaching(ACLChecklist *) const;
+    ACLData *data;
 };
 
 #endif /* SQUID_ACLPROXYAUTH_H */
diff --git a/src/ACLRegexData.cc b/src/ACLRegexData.cc
new file mode 100644 (file)
index 0000000..dcc2619
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * $Id: ACLRegexData.cc,v 1.1 2003/02/13 08:07:47 robertc Exp $
+ *
+ * DEBUG: section 28    Access Control
+ * AUTHOR: Duane Wessels
+ *
+ * SQUID Web Proxy Cache          http://www.squid-cache.org/
+ * ----------------------------------------------------------
+ *
+ *  Squid is the result of efforts by numerous individuals from
+ *  the Internet community; see the CONTRIBUTORS file for full
+ *  details.   Many organizations have provided support for Squid's
+ *  development; see the SPONSORS file for full details.  Squid is
+ *  Copyrighted (C) 2001 by the Regents of the University of
+ *  California; see the COPYRIGHT file for full details.  Squid
+ *  incorporates software developed and/or copyrighted by other
+ *  sources; see the CREDITS file for full details.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *  
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *  
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ *
+ *
+ * Copyright (c) 2003, Robert Collins <robertc@squid-cache.org>
+ */
+
+#include "squid.h"
+#include "ACLRegexData.h"
+#include "authenticate.h"
+#include "ACLChecklist.h"
+#include "ACL.h"
+
+MemPool *ACLRegexData::Pool(NULL);
+void *
+ACLRegexData::operator new (size_t byteCount)
+{
+    /* derived classes with different sizes must implement their own new */
+    assert (byteCount == sizeof (ACLRegexData));
+    if (!Pool)
+       Pool = memPoolCreate("ACLRegexData", sizeof (ACLRegexData));
+    return memPoolAlloc(Pool);
+}
+
+void
+ACLRegexData::operator delete (void *address)
+{
+    memPoolFree (Pool, address);
+}
+
+void
+ACLRegexData::deleteSelf() const
+{
+    delete this;
+}
+
+ACLRegexData::~ACLRegexData()
+{
+    aclDestroyRegexList(data);
+} 
+
+bool
+ACLRegexData::match(char const *user)
+{
+    return aclMatchRegex(data, user);
+}
+
+wordlist *
+ACLRegexData::dump()
+{
+    return aclDumpRegexList(data);
+}
+
+void
+ACLRegexData::parse()
+{
+    aclParseRegexList(&data);
+}
+
+
+ACLData *
+ACLRegexData::clone() const
+{
+    /* Regex's don't clone yet. */
+    assert (!data);
+    return new ACLRegexData;
+}
diff --git a/src/ACLRegexData.h b/src/ACLRegexData.h
new file mode 100644 (file)
index 0000000..d03db53
--- /dev/null
@@ -0,0 +1,56 @@
+
+/*
+ * $Id: ACLRegexData.h,v 1.1 2003/02/13 08:07:47 robertc Exp $
+ *
+ *
+ * SQUID Web Proxy Cache          http://www.squid-cache.org/
+ * ----------------------------------------------------------
+ *
+ *  Squid is the result of efforts by numerous individuals from
+ *  the Internet community; see the CONTRIBUTORS file for full
+ *  details.   Many organizations have provided support for Squid's
+ *  development; see the SPONSORS file for full details.  Squid is
+ *  Copyrighted (C) 2001 by the Regents of the University of
+ *  California; see the COPYRIGHT file for full details.  Squid
+ *  incorporates software developed and/or copyrighted by other
+ *  sources; see the CREDITS file for full details.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *  
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *  
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ *
+ *
+ * Copyright (c) 2003, Robert Collins <robertc@squid-cache.org>
+ */
+
+#ifndef SQUID_ACLREGEXDATA_H
+#define SQUID_ACLREGEXDATA_H
+#include "ACLData.h"
+
+class ACLRegexData : public ACLData {
+  public:
+    void *operator new(size_t);
+    void operator delete(void *);
+    virtual void deleteSelf() const;
+
+    virtual ~ACLRegexData();
+    virtual bool match(char const *user);
+    virtual wordlist *dump();
+    virtual void parse();
+    virtual ACLData *clone() const;
+  private:
+    static MemPool *Pool;
+    relist *data;
+};
+
+#endif /* SQUID_ACLREGEXDATA_H */
index 3e819467417f4e79bc1ce3d0dc884f9bbf7de196..1aca2fec7e27275196af91836ab3b5017a846446 100644 (file)
@@ -172,3 +172,12 @@ ACLUserData::parse()
        names = names->insert(xstrdup(t), splaystrcmp);
     }
 }
+
+
+ACLUserData *
+ACLUserData::clone() const
+{
+    /* Splay trees don't clone yet. */
+    assert (!names);
+    return new ACLUserData;
+}
index 19eac2197920630609960be93f11c43ad519d52c..92e4df62bb92d1d5059801ad3cb1a0c619520fd5 100644 (file)
@@ -37,8 +37,9 @@
 #define SQUID_ACLUSERDATA_H
 #include "splay.h"
 #include "ACL.h"
+#include "ACLData.h"
 
-class ACLUserData {
+class ACLUserData : public ACLData {
   public:
     void *operator new(size_t);
     void operator delete(void *);
@@ -48,6 +49,7 @@ class ACLUserData {
     bool match(char const *user);
     wordlist *dump();
     void parse();
+    virtual ACLUserData *clone() const;
     
     SplayNode<char *> *names;
     struct {
diff --git a/src/ExternalACL.h b/src/ExternalACL.h
new file mode 100644 (file)
index 0000000..26a0186
--- /dev/null
@@ -0,0 +1,47 @@
+
+/*
+ * $Id: ExternalACL.h,v 1.1 2003/02/13 08:07:47 robertc Exp $
+ *
+ *
+ * SQUID Web Proxy Cache          http://www.squid-cache.org/
+ * ----------------------------------------------------------
+ *
+ *  Squid is the result of efforts by numerous individuals from
+ *  the Internet community; see the CONTRIBUTORS file for full
+ *  details.   Many organizations have provided support for Squid's
+ *  development; see the SPONSORS file for full details.  Squid is
+ *  Copyrighted (C) 2001 by the Regents of the University of
+ *  California; see the COPYRIGHT file for full details.  Squid
+ *  incorporates software developed and/or copyrighted by other
+ *  sources; see the CREDITS file for full details.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *  
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *  
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ *
+ *
+ * Copyright (c) 2003, Robert Collins <robertc@squid-cache.org>
+ */
+
+#ifndef SQUID_EXTERNALACL_H
+#define SQUID_EXTERNALACL_H
+#include "ACLChecklist.h"
+class ExternalACLLookup : public ACLChecklist::AsyncState {
+  public:
+    static ExternalACLLookup *Instance();
+    virtual void checkForAsync(ACLChecklist *)const;
+  private:
+    static ExternalACLLookup instance_;
+    static void LookupDone(void *data, void *result);
+};
+#endif /* SQUID_EXTERNALACL_H */
index 3333844dfc07b40a3c4872f63f6805dbeee29bb9..2a1732d1587d70c43c98e559b45f0a3391c5ed8e 100644 (file)
@@ -1,7 +1,7 @@
 #
 #  Makefile for the Squid Object Cache server
 #
-#  $Id: Makefile.am,v 1.57 2003/02/12 06:10:58 robertc Exp $
+#  $Id: Makefile.am,v 1.58 2003/02/13 08:07:47 robertc Exp $
 #
 #  Uncomment and customize the following to suit your needs:
 #
@@ -147,6 +147,7 @@ EXTRA_squid_SOURCES = \
        win32.cc
 
 squid_ACLSOURCES = \
+       ACLData.h \
        ACLDestinationIP.cc \
        ACLDestinationIP.h \
        ACLIP.cc \
@@ -155,6 +156,8 @@ squid_ACLSOURCES = \
        ACLMyIP.h \
        ACLProxyAuth.cc \
        ACLProxyAuth.h \
+       ACLRegexData.cc \
+       ACLRegexData.h \
        ACLSourceIP.cc \
        ACLSourceIP.h \
        ACLUserData.cc \
@@ -164,6 +167,7 @@ squid_SOURCES = \
        access_log.cc \
        acl.cc \
        ACL.h \
+       ACLChecklist.cc \
        ACLChecklist.h \
        $(squid_ACLSOURCES) \
        asn.cc \
@@ -198,6 +202,7 @@ squid_SOURCES = \
        ETag.cc \
        event.cc \
        external_acl.cc \
+       ExternalACL.h \
        fd.cc \
        fde.cc \
        fde.h \
index c019b57fb40524d271f1da1afacbba10811397a7..370eb2aa4ba816e3c49cef2435a5e7230ef77fa4 100644 (file)
@@ -16,7 +16,7 @@
 #
 #  Makefile for the Squid Object Cache server
 #
-#  $Id: Makefile.in,v 1.285 2003/02/12 06:23:39 robertc Exp $
+#  $Id: Makefile.in,v 1.286 2003/02/13 08:07:47 robertc Exp $
 #
 #  Uncomment and customize the following to suit your needs:
 #
@@ -237,6 +237,7 @@ EXTRA_squid_SOURCES = \
 
 
 squid_ACLSOURCES = \
+       ACLData.h \
        ACLDestinationIP.cc \
        ACLDestinationIP.h \
        ACLIP.cc \
@@ -245,6 +246,8 @@ squid_ACLSOURCES = \
        ACLMyIP.h \
        ACLProxyAuth.cc \
        ACLProxyAuth.h \
+       ACLRegexData.cc \
+       ACLRegexData.h \
        ACLSourceIP.cc \
        ACLSourceIP.h \
        ACLUserData.cc \
@@ -255,6 +258,7 @@ squid_SOURCES = \
        access_log.cc \
        acl.cc \
        ACL.h \
+       ACLChecklist.cc \
        ACLChecklist.h \
        $(squid_ACLSOURCES) \
        asn.cc \
@@ -289,6 +293,7 @@ squid_SOURCES = \
        ETag.cc \
        event.cc \
        external_acl.cc \
+       ExternalACL.h \
        fd.cc \
        fde.cc \
        fde.h \
index 503fdd2efcb1f73efeb3add88b872b1fcdaadfa0..08f5d4546221e450e3f1ad8e23fd36b3b0a07b6f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: acl.cc,v 1.301 2003/02/12 06:10:58 robertc Exp $
+ * $Id: acl.cc,v 1.302 2003/02/13 08:07:47 robertc Exp $
  *
  * DEBUG: section 28    Access Control
  * AUTHOR: Duane Wessels
 #include "HttpRequest.h"
 #include "authenticate.h"
 #include "fde.h"
-#include "ACLProxyAuth.h"
 #if USE_IDENT
 #include "ACLIdent.h"
 #endif
 #include "ACLUserData.h"
+#include "ExternalACL.h"
 
 static void aclParseDomainList(void *curlist);
 static void aclParseIntlist(void *curlist);
@@ -56,9 +56,6 @@ static void aclParseTimeSpec(void *curlist);
 static void aclParseIntRange(void *curlist);
 static void aclDestroyTimeList(acl_time_data * data);
 static void aclDestroyIntRange(intrange *);
-static void aclLookupProxyAuthStart(ACLChecklist * checklist);
-static void aclLookupProxyAuthDone(void *data, char *result);
-static acl*aclFindByName(const char *name);
 static int aclMatchTime(acl_time_data * data, time_t when);
 static int aclMatchDomainList(void *dataptr, const char *);
 static int aclMatchIntegerRange(intrange * data, int i);
@@ -70,16 +67,9 @@ static void aclDestroyUserMaxIP(void *data);
 static wordlist *aclDumpUserMaxIP(void *data);
 static int aclMatchUserMaxIP(void *, auth_user_request_t *, struct in_addr);
 static squid_acl aclStrToType(const char *s);
-#if USE_IDENT
-static IDCB aclLookupIdentDone;
-#endif
-static IPH aclLookupDstIPforASNDone;
-static FQDNH aclLookupSrcFQDNDone;
-static FQDNH aclLookupDstFQDNDone;
-static EAH aclLookupExternalDone;
+IPH aclLookupDstIPforASNDone;
 static wordlist *aclDumpDomainList(void *data);
 static wordlist *aclDumpTimeSpecList(acl_time_data *);
-static wordlist *aclDumpRegexList(relist * data);
 static wordlist *aclDumpIntlistList(intlist * data);
 static wordlist *aclDumpIntRangeList(intrange * data);
 static wordlist *aclDumpProtoList(intlist * data);
@@ -97,7 +87,6 @@ static wordlist *aclDumpArpList(void *);
 static splayNode::SPLAYCMP aclArpCompare;
 static splayNode::SPLAYWALKEE aclDumpArpListWalkee;
 #endif
-static int aclCacheMatchAcl(dlink_list * cache, squid_acl acltype, void *data, char const *MatchParam);
 #if USE_SSL
 static void aclParseCertList(void *curlist);
 static int aclMatchUserCert(void *data, ACLChecklist *);
@@ -185,10 +174,6 @@ aclStrToType(const char *s)
        return ACL_BROWSER;
     if (!strcmp(s, "referer_regex"))
        return ACL_REFERER_REGEX;
-    if (!strcmp(s, "proxy_auth"))
-       return ACL_PROXY_AUTH;
-    if (!strcmp(s, "proxy_auth_regex"))
-       return ACL_PROXY_AUTH_REGEX;
     if (!strcmp(s, "src_as"))
        return ACL_SRC_ASN;
     if (!strcmp(s, "dst_as"))
@@ -258,8 +243,6 @@ aclTypeToStr(squid_acl type)
        return "browser";
     if (type == ACL_REFERER_REGEX)
        return "referer_regex";
-    if (type == ACL_PROXY_AUTH_REGEX)
-       return "proxy_auth_regex";
     if (type == ACL_SRC_ASN)
        return "src_as";
     if (type == ACL_DST_ASN)
@@ -293,8 +276,8 @@ aclTypeToStr(squid_acl type)
     return "ERROR";
 }
 
-static acl *
-aclFindByName(const char *name)
+acl *
+ACL::FindByName(const char *name)
 {
     acl *a;
     for (a = Config.aclList; a; a = a->next)
@@ -604,9 +587,6 @@ ACL::Factory (char const *type)
         result = new ACLIdent;
        break;
 #endif
-      case ACL_PROXY_AUTH:
-        result = new ACLProxyAuth;
-       break;
       case ACL_DST_DOMAIN:
       case ACL_SRC_DOMAIN:
       case ACL_DST_DOM_REGEX:
@@ -624,7 +604,6 @@ ACL::Factory (char const *type)
       case ACL_METHOD:
       case ACL_BROWSER:
       case ACL_REFERER_REGEX:
-      case ACL_PROXY_AUTH_REGEX:
       case ACL_SRC_ASN:
       case ACL_DST_ASN:
 #if SQUID_SNMP
@@ -699,7 +678,7 @@ ACL::ParseAclLine(acl ** head)
        debug(28, 0) ("aclParseAclLine: Invalid ACL type '%s'\n", t);
        return;
     }
-    if ((A = aclFindByName(aclname)) == NULL) {
+    if ((A = FindByName(aclname)) == NULL) {
        debug(28, 3) ("aclParseAclLine: Creating ACL '%s'\n", aclname);
        A = ACL::Factory(t);
        xstrncpy(A->name, aclname, ACL_NAME_SZ);
@@ -800,19 +779,7 @@ ACL::parse()
     case ACL_IDENT: 
 #endif
     case ACL_DERIVED:
-    case ACL_PROXY_AUTH:
-       fatal ("unused");
-       break;
-    case ACL_PROXY_AUTH_REGEX:
-       if (authenticateSchemeCount() == 0) {
-           debug(28, 0) ("aclParseAclLine: IGNORING: Proxy Auth ACL '%s' \
-because no authentication schemes were compiled.\n", cfgline);
-       } else if (authenticateActiveSchemeCount() == 0) {
-           debug(28, 0) ("aclParseAclLine: IGNORING: Proxy Auth ACL '%s' \
-because no authentication schemes are fully configured.\n", cfgline);
-       } else {
-           aclParseRegexList(&data);
-       }
+       fatal ("overriden");
        break;
 #if SQUID_SNMP
     case ACL_SNMP_COMMUNITY:
@@ -871,7 +838,7 @@ aclIsProxyAuth(const char *name)
     if (NULL == name)
        return false;
     acl *a;
-    if ((a = aclFindByName(name)))
+    if ((a = ACL::FindByName(name)))
        return a->isProxyAuth();
     return false;
 }
@@ -879,7 +846,7 @@ aclIsProxyAuth(const char *name)
 bool
 ACL::isProxyAuth() const
 {
-    return aclType() == ACL_PROXY_AUTH_REGEX;
+    return false;
 }
 
 /* maex@space.net (05.09.96)
@@ -1003,7 +970,7 @@ aclParseAclList(acl_list ** head)
            t++;
        }
        debug(28, 3) ("aclParseAccessLine: looking for ACL name '%s'\n", t);
-       a = aclFindByName(t);
+       a = ACL::FindByName(t);
        if (a == NULL) {
            debug(28, 0) ("%s line %d: %s\n",
                cfg_filename, config_lineno, config_input_line);
@@ -1064,56 +1031,43 @@ aclMatchRegex(relist * data, const char *word)
 
 /* ACL result caching routines */
 
+int
+ACL::matchForCache(ACLChecklist *checklist)
+{
+    /* This is a fatal to ensure that cacheMatchAcl calls are _only_
+     * made for supported acl types */
+    fatal("aclCacheMatchAcl: unknown or unexpected ACL type");
+    return 0;          /* NOTREACHED */
+}
+
 /*
  * we lookup an acl's cached results, and if we cannot find the acl being 
- * checked we check it and cache the result. This function is deliberatly 
- * generic to support caching of multiple acl types (but it needs to be more
- * generic still....
- * The Match Param and the cache MUST be tied together by the calling routine.
- * You have been warned :-]
- * Also only Matchxxx that are of the form (void *, void *) can be used.
- * probably some ugly overloading _could_ be done but I'll leave that as an
- * exercise for the reader. Note that caching of time based acl's is not
- * wise due to no expiry occuring to the cache entries until the user expires
- * or a reconfigure takes place. 
+ * checked we check it and cache the result. This function is a template
+ * method to support caching of multiple acl types.
+ * Note that caching of time based acl's is not
+ * wise in long lived caches (i.e. the auth_user proxy match cache.
  * RBC
  */
-static int
-aclCacheMatchAcl(dlink_list * cache, squid_acl acltype, void *data,
-    char const *MatchParam)
+int
+ACL::cacheMatchAcl(dlink_list * cache, ACLChecklist *checklist)
 {
-    int matchrv;
     acl_proxy_auth_match_cache *auth_match;
     dlink_node *link;
     link = cache->head;
     while (link) {
        auth_match = (acl_proxy_auth_match_cache *)link->data;
-       if (auth_match->acl_data == data) {
-           debug(28, 4) ("aclCacheMatchAcl: cache hit on acl '%p'\n", data);
+       if (auth_match->acl_data == this) {
+           debug(28, 4) ("ACL::cacheMatchAcl: cache hit on acl '%p'\n", this);
            return auth_match->matchrv;
        }
        link = link->next;
     }
     auth_match = NULL;
-    /* match the user in the acl. They are not cached. */
-    switch (acltype) {
-    case ACL_PROXY_AUTH:
-       matchrv = ((ACLUserData *)data)->match(MatchParam);
-       break;
-    case ACL_PROXY_AUTH_REGEX:
-       matchrv = aclMatchRegex((relist *)data, MatchParam);
-       break;
-    default:
-       /* This is a fatal to ensure that aclCacheMatchAcl calls are _only_
-        * made for supported acl types */
-       fatal("aclCacheMatchAcl: unknown or unexpected ACL type");
-       return 0;               /* NOTREACHED */
-    }
     auth_match = (acl_proxy_auth_match_cache *)memAllocate(MEM_ACL_PROXY_AUTH_MATCH);
-    auth_match->matchrv = matchrv;
-    auth_match->acl_data = data;
+    auth_match->matchrv = matchForCache (checklist);
+    auth_match->acl_data = this;
     dlinkAddTail(auth_match, &auth_match->link, cache);
-    return matchrv;
+    return auth_match->matchrv;
 }
 
 void
@@ -1131,34 +1085,6 @@ aclCacheMatchFlush(dlink_list * cache)
     }
 }
 
-/* aclMatchProxyAuth can return two exit codes:
- * 0 : Authorisation for this ACL failed. (Did not match)
- * 1 : Authorisation OK. (Matched)
- */
-int
-aclMatchProxyAuth(void *data, auth_user_request_t * auth_user_request,
-    ACLChecklist * checklist, squid_acl acltype)
-{
-    /* checklist is used to register user name when identified, nothing else */
-    /* General program flow in proxy_auth acls
-     * 1. Consistency checks: are we getting sensible data
-     * 2. Call the authenticate* functions to establish a authenticated user
-     * 4. look up the username in acltype (and cache the result against the 
-     *     username
-     */
-
-    /* for completeness */
-    authenticateAuthUserRequestLock(auth_user_request);
-
-    /* consistent parameters ? */
-    assert(authenticateUserAuthenticated(auth_user_request));
-    /* this ACL check completed */
-    authenticateAuthUserRequestUnlock(auth_user_request);
-    /* check to see if we have matched the user-acl before */
-    return aclCacheMatchAcl(&auth_user_request->auth_user->
-       proxy_match_cache, acltype, data,
-       authenticateUserRequestUsername(auth_user_request));
-}
 
 CBDATA_TYPE(acl_user_ip_data);
 
@@ -1253,18 +1179,6 @@ aclMatchUserMaxIP(void *data, auth_user_request_t * auth_user_request,
     return 1;
 }
 
-static void
-aclLookupProxyAuthStart(ACLChecklist * checklist)
-{
-    auth_user_request_t *auth_user_request;
-    /* make sure someone created auth_user_request for us */
-    assert(checklist->auth_user_request != NULL);
-    auth_user_request = checklist->auth_user_request;
-
-    assert(authenticateValidateUser(auth_user_request));
-    authenticateStart(auth_user_request, aclLookupProxyAuthDone, checklist);
-}
-
 static int
 aclMatchInteger(intlist * data, int i)
 {
@@ -1354,50 +1268,6 @@ aclMatchWordList(wordlist * w, const char *word)
 }
 #endif
 
-int
-aclAuthenticated(ACLChecklist * checklist)
-{
-    request_t *r = checklist->request;
-    http_hdr_type headertype;
-    if (NULL == r) {
-       return -1;
-    } else if (!r->flags.accelerated) {
-       /* Proxy authorization on proxy requests */
-       headertype = HDR_PROXY_AUTHORIZATION;
-    } else if (r->flags.internal) {
-       /* WWW authorization on accelerated internal requests */
-       headertype = HDR_AUTHORIZATION;
-    } else {
-#if AUTH_ON_ACCELERATION
-       /* WWW authorization on accelerated requests */
-       headertype = HDR_AUTHORIZATION;
-#else
-       debug(28, 1) ("aclAuthenticated: authentication not applicable on accelerated requests.\n");
-       return -1;
-#endif
-    }
-    /* get authed here */
-    /* Note: this fills in checklist->auth_user_request when applicable */
-    switch (authenticateTryToAuthenticateAndSetAuthUser(&checklist->auth_user_request, headertype, checklist->request, checklist->conn(), checklist->src_addr)) {
-    case AUTH_ACL_CANNOT_AUTHENTICATE:
-       debug(28, 4) ("aclMatchAcl: returning  0 user authenticated but not authorised.\n");
-       return 0;
-    case AUTH_AUTHENTICATED:
-       return 1;
-       break;
-    case AUTH_ACL_HELPER:
-       debug(28, 4) ("aclMatchAcl: returning 0 sending credentials to helper.\n");
-       checklist->state[ACL_PROXY_AUTH] = ACL_LOOKUP_NEEDED;
-       return 0;
-    case AUTH_ACL_CHALLENGE:
-       debug(28, 4) ("aclMatchAcl: returning 0 sending authentication challenge.\n");
-       checklist->state[ACL_PROXY_AUTH] = ACL_PROXY_AUTH_NEEDED;
-       return 0;
-    default:
-       fatal("unexpected authenticateAuthenticate reply\n");
-       return -1;
-    }
-}
 
 bool
 ACL::requiresRequest() const
@@ -1411,8 +1281,6 @@ ACL::requiresRequest() const
     case ACL_MAX_USER_IP:
     case ACL_METHOD:
     case ACL_PROTO:
-    case ACL_PROXY_AUTH:
-    case ACL_PROXY_AUTH_REGEX:
     case ACL_REP_MIME_TYPE:
     case ACL_REQ_MIME_TYPE:
     case ACL_URLPATH_REGEX:
@@ -1557,16 +1425,8 @@ ACL::match(ACLChecklist * checklist)
            return 0;
        return aclMatchRegex((relist *)data, header);
        /* NOTREACHED */
-    case ACL_PROXY_AUTH_REGEX:
-       if ((ti = aclAuthenticated(checklist)) != 1)
-           return ti;
-       ti = aclMatchProxyAuth(data, checklist->auth_user_request,
-           checklist, aclType());
-       checklist->auth_user_request = NULL;
-       return ti;
-       /* NOTREACHED */
     case ACL_MAX_USER_IP:
-       if ((ti = aclAuthenticated(checklist)) != 1)
+       if ((ti = checklist->authenticated()) != 1)
            return ti;
        ti = aclMatchUserMaxIP(data, checklist->auth_user_request,
            checklist->src_addr);
@@ -1636,7 +1496,6 @@ ACL::match(ACLChecklist * checklist)
     case ACL_IDENT:
 #endif
     case ACL_DERIVED:
-    case ACL_PROXY_AUTH:
        fatal ("overridden");
     }
     debug(28, 0) ("aclMatchAcl: '%s' has bad type %d\n",
@@ -1657,24 +1516,6 @@ ACLList::matches (ACLChecklist *checklist) const
     return true;
 }
 
-int
-ACLChecklist::matchAclList(const acl_list * head)
-{
-    PROF_start(aclMatchAclList);
-    const acl_list *node = head;
-    while (node) {
-       if (!node->matches(this)) {
-           debug(28, 3) ("aclmatchAclList: returning 0 (AND list entry failed to match)\n");
-           PROF_stop(aclMatchAclList);
-           return 0;
-       }
-       node = node->next;
-    }
-    debug(28, 3) ("aclmatchAclList: returning 1 (AND list satisfied)\n");
-    PROF_stop(aclMatchAclList);
-    return 1;
-}
-
 /* Warning: do not cbdata lock checklist here - it 
  * may be static or on the stack
  */
@@ -1697,212 +1538,8 @@ aclCheckFast(const acl_access * A, ACLChecklist * checklist)
     return allow == ACCESS_DENIED;
 }
 
-allow_t const &
-ACLChecklist::currentAnswer() const
-{
-    return allow_;
-}
-
-void
-ACLChecklist::currentAnswer(allow_t const newAnswer)
-{
-    allow_ = newAnswer;
-}
-    
-void
-ACLChecklist::check()
-{
-    /* deny if no rules present */
-    currentAnswer(ACCESS_DENIED);
-    /* NOTE: This holds a cbdata reference to the current access_list
-     * entry, not the whole list.
-     */
-    while (accessList != NULL) {
-       /*
-        * If the _acl_access is no longer valid (i.e. its been
-        * freed because of a reconfigure), then bail on this
-        * access check.  For now, return ACCESS_DENIED.
-        */
-       if (!cbdataReferenceValid(accessList)) {
-           cbdataReferenceDone(accessList);
-           break;
-       }
-
-       checkAccessList();
-       if (asyncInProgress())
-           return;
-
-       if (finished()) {
-           /*
-            * We are done.  Either the request
-            * is allowed, denied, requires authentication.
-            */
-           debug(28, 3) ("ACLChecklist::check: match found, returning %d\n", currentAnswer());
-           cbdataReferenceDone(accessList); /* A */
-           checkCallback(currentAnswer());
-           /* From here on in, this may be invalid */
-           return;
-       }
-       /*
-        * Reference the next access entry
-        */
-       const acl_access *A = accessList;
-       accessList = cbdataReference(accessList->next);
-       cbdataReferenceDone(A);
-    }
-    /* dropped off the end of the list */
-    debug(28, 3) ("ACLChecklist::check: NO match found, returning %d\n", 
-                 currentAnswer() != ACCESS_DENIED ? ACCESS_DENIED : ACCESS_ALLOWED);
-    checkCallback(currentAnswer() != ACCESS_DENIED ? ACCESS_DENIED : ACCESS_ALLOWED);
-}
-
-bool
-ACLChecklist::asyncInProgress() const
-{
-    return async_;
-}
-
-void
-ACLChecklist::asyncInProgress(bool const newAsync)
-{
-    assert (!finished());
-    async_ = newAsync;
-    debug (28,3)("ACLChecklist::asyncInProgress: async set to %d\n",async_);
-}
-
-bool
-ACLChecklist::finished() const
-{
-    return finished_;
-}
-
-void
-ACLChecklist::markFinished()
-{
-    assert (!finished());
-    finished_ = true;
-    debug (28,3)("checklist processing finished\n");
-}
-
-void
-ACLChecklist::checkAccessList()
-{
-    debug(28, 3) ("ACLChecklist::checkAccessList: checking '%s'\n", accessList->cfgline);
-    /* what is our result on a match? */
-    currentAnswer(accessList->allow);
-    /* does the current AND clause match */
-    int match = matchAclList(accessList->aclList);
-    if (match)
-       markFinished();
-    /* Should be else, but keep the exact same flow as before */
-    checkForAsync();
-}
-
-void
-ACLChecklist::checkForAsync()
-{
-    /* TODO: introduce a state object, with states:
-     * synccheck -- null op
-     * asyncneeded -- async lookup needed
-     * finished -- answer set.
-     */
-    /* check for async lookups needed. */
-    if (asyncState() != NullState::Instance()) {
-       /* If a state object is here, use it.
-        * When all cases are converted, the if goes away and it
-        * becomes unconditional.
-        * RBC 02 2003
-        */
-       asyncState()->checkForAsync(this);
-    } else if (state[ACL_DST_ASN] == ACL_LOOKUP_NEEDED) {
-       state[ACL_DST_ASN] = ACL_LOOKUP_PENDING;
-       ipcache_nbgethostbyname(request->host,
-                               aclLookupDstIPforASNDone, this);
-    } else if (state[ACL_SRC_DOMAIN] == ACL_LOOKUP_NEEDED) {
-       state[ACL_SRC_DOMAIN] = ACL_LOOKUP_PENDING;
-       fqdncache_nbgethostbyaddr(src_addr,
-                                 aclLookupSrcFQDNDone, this);
-    } else if (state[ACL_DST_DOMAIN] == ACL_LOOKUP_NEEDED) {
-       ipcache_addrs *ia;
-       ia = ipcacheCheckNumeric(request->host);
-       if (ia == NULL) {
-           state[ACL_DST_DOMAIN] = ACL_LOOKUP_DONE;
-       } else {
-           dst_addr = ia->in_addrs[0];
-           state[ACL_DST_DOMAIN] = ACL_LOOKUP_PENDING;
-           fqdncache_nbgethostbyaddr(dst_addr,
-                                     aclLookupDstFQDNDone, this);
-       }
-    } else if (state[ACL_PROXY_AUTH] == ACL_LOOKUP_NEEDED) {
-       debug(28, 3)
-         ("ACLChecklist::checkForAsync: checking password via authenticator\n");
-       aclLookupProxyAuthStart(this);
-       state[ACL_PROXY_AUTH] = ACL_LOOKUP_PENDING;
-    } else if (state[ACL_PROXY_AUTH] == ACL_PROXY_AUTH_NEEDED) {
-       /* Client is required to resend the request with correct authentication
-        * credentials. (This may be part of a stateful auth protocol.
-        * The request is denied.
-        */
-       debug(28, 6) ("ACLChecklist::checkForAsync: requiring Proxy Auth header.\n");
-       currentAnswer(ACCESS_REQ_PROXY_AUTH);
-       markFinished();
-       return;
 #if USE_IDENT
-    } else if (state[ACL_IDENT] == ACL_LOOKUP_NEEDED) {
-       debug(28, 3) ("ACLChecklist::checkForAsync: Doing ident lookup\n");
-       if (conn() && cbdataReferenceValid(conn())) {
-           identStart(&conn()->me, &conn()->peer,
-                      aclLookupIdentDone, this);
-           state[ACL_IDENT] = ACL_LOOKUP_PENDING;
-       } else {
-           debug(28, 1) ("ACLChecklist::checkForAsync: Can't start ident lookup. No client connection\n");
-           currentAnswer(ACCESS_DENIED);
-           markFinished();
-           return;
-       }
-#endif
-    } else if (state[ACL_EXTERNAL] == ACL_LOOKUP_NEEDED) {
-       acl *acl = aclFindByName(AclMatchedName);
-       assert (acl->aclType() == ACL_EXTERNAL);
-       acl->startExternal(this);
-    } else {
-       return;
-    }
-    asyncInProgress(true);
-}
-
 void
-ACL::startExternal(ACLChecklist *checklist)
-{
-    externalAclLookup(checklist, data, aclLookupExternalDone, checklist);
-}
-
-void
-ACLChecklist::checkCallback(allow_t answer)
-{
-    PF *callback_;
-    void *cbdata_;
-    debug(28, 3) ("ACLChecklist::checkCallback: answer=%d\n", answer);
-    /* During reconfigure, we can end up not finishing call
-     * sequences into the auth code */
-    if (auth_user_request) {
-       /* the checklist lock */
-       authenticateAuthUserRequestUnlock(auth_user_request);
-       /* it might have been connection based */
-       assert(conn());
-       conn()->auth_user_request = NULL;
-       conn()->auth_type = AUTH_BROKEN;
-       auth_user_request = NULL;
-    }
-    callback_ = callback;
-    callback = NULL;
-    if (cbdataReferenceValidDone(callback_data, &cbdata_))
-       callback_(answer, cbdata_);
-    delete this;
-}
-
-#if USE_IDENT
-static void
 aclLookupIdentDone(const char *ident, void *data)
 {
     ACLChecklist *checklist = (ACLChecklist *)data;
@@ -1925,7 +1562,7 @@ aclLookupIdentDone(const char *ident, void *data)
 }
 #endif
 
-static void
+void
 aclLookupDstIPforASNDone(const ipcache_addrs * ia, void *data)
 {
     ACLChecklist *checklist = (ACLChecklist *)data;
@@ -1934,7 +1571,7 @@ aclLookupDstIPforASNDone(const ipcache_addrs * ia, void *data)
     checklist->check();
 }
 
-static void
+void
 aclLookupSrcFQDNDone(const char *fqdn, void *data)
 {
     ACLChecklist *checklist = (ACLChecklist *)data;
@@ -1943,7 +1580,7 @@ aclLookupSrcFQDNDone(const char *fqdn, void *data)
     checklist->check();
 }
 
-static void
+void
 aclLookupDstFQDNDone(const char *fqdn, void *data)
 {
     ACLChecklist *checklist = (ACLChecklist *)data;
@@ -1952,114 +1589,6 @@ aclLookupDstFQDNDone(const char *fqdn, void *data)
     checklist->check();
 }
 
-static void
-aclLookupProxyAuthDone(void *data, char *result)
-{
-    ACLChecklist *checklist = (ACLChecklist *)data;
-    checklist->state[ACL_PROXY_AUTH] = ACL_LOOKUP_DONE;
-    if (result != NULL)
-       fatal("AclLookupProxyAuthDone: Old code floating around somewhere.\nMake clean and if that doesn't work, report a bug to the squid developers.\n");
-    if (!authenticateValidateUser(checklist->auth_user_request) || checklist->conn() == NULL) {
-       /* credentials could not be checked either way
-        * restart the whole process */
-       /* OR the connection was closed, there's no way to continue */
-       authenticateAuthUserRequestUnlock(checklist->auth_user_request);
-       if (checklist->conn()) {
-           checklist->conn()->auth_user_request = NULL;
-           checklist->conn()->auth_type = AUTH_BROKEN;
-       }
-       checklist->auth_user_request = NULL;
-    }
-    checklist->asyncInProgress(false);
-    checklist->check();
-}
-
-static void
-aclLookupExternalDone(void *data, void *result)
-{
-    ACLChecklist *checklist = (ACLChecklist *)data;
-    checklist->state[ACL_EXTERNAL] = ACL_LOOKUP_DONE;
-    checklist->extacl_entry = cbdataReference((external_acl_entry *)result);
-    checklist->asyncInProgress(false);
-    checklist->check();
-}
-
-CBDATA_CLASS_INIT(ACLChecklist);
-
-void *
-ACLChecklist::operator new (size_t size)
-{
-    assert (size == sizeof(ACLChecklist));
-    CBDATA_INIT_TYPE(ACLChecklist);
-    ACLChecklist *result = cbdataAlloc(ACLChecklist);
-    /* Mark result as being owned - we want the refcounter to do the delete
-     * call */
-    cbdataReference(result);
-    return result;
-}
-void
-ACLChecklist::operator delete (void *address)
-{
-    ACLChecklist *t = static_cast<ACLChecklist *>(address);
-    cbdataFree(address);
-    /* And allow the memory to be freed */
-    cbdataReferenceDone (t);
-}
-
-void
-ACLChecklist::deleteSelf() const
-{
-    delete this;
-}
-
-ACLChecklist::ACLChecklist() : accessList (NULL), my_port (0), request (NULL),
-  reply (NULL),
-  auth_user_request (NULL)
-#if SQUID_SNMP
-    ,snmp_community(NULL)
-#endif
-  , callback (NULL),
-  callback_data (NULL),
-  extacl_entry (NULL),
-  conn_(NULL),
-  async_(false),
-  finished_(false),
-  allow_(ACCESS_DENIED),
-  state_(NullState::Instance())
-{
-    memset (&src_addr, '\0', sizeof (struct in_addr));
-    memset (&dst_addr, '\0', sizeof (struct in_addr));
-    memset (&my_addr, '\0', sizeof (struct in_addr));
-    rfc931[0] = '\0';
-    memset (&state, '\0', sizeof (state));
-}
-
-ACLChecklist::~ACLChecklist()
-{
-    assert (!asyncInProgress());
-    if (extacl_entry)
-       cbdataReferenceDone(extacl_entry);
-    if (request)
-       requestUnlink(request);
-    request = NULL;
-    cbdataReferenceDone(conn_);
-    cbdataReferenceDone(accessList);
-}
-
-ConnStateData *
-ACLChecklist::conn()
-{
-    return  conn_;
-}
-
-void
-ACLChecklist::conn(ConnStateData *aConn)
-{
-    assert (conn() == NULL);
-    conn_ = aConn;
-}
-
 /*
  * Any ACLChecklist created by aclChecklistCreate() must eventually be
  * freed by ACLChecklist::operator delete().  There are two common cases:
@@ -2101,14 +1630,6 @@ aclChecklistCreate(const acl_access * A, request_t * request, const char *ident)
     return checklist;
 }
 
-void
-aclNBCheck(ACLChecklist * checklist, PF * callback, void *callback_data)
-{
-    checklist->callback = callback;
-    checklist->callback_data = cbdataReference(callback_data);
-    checklist->check();
-}
-
 /*********************/
 /* Destroy functions */
 /*********************/
@@ -2167,7 +1688,6 @@ ACL::~ACL()
        case ACL_IDENT:
 #endif
        case ACL_DERIVED:
-       case ACL_PROXY_AUTH:
            break;
        case ACL_TIME:
            aclDestroyTimeList((acl_time_data *)data);
@@ -2175,7 +1695,6 @@ ACL::~ACL()
 #if USE_IDENT
        case ACL_IDENT_REGEX:
 #endif
-       case ACL_PROXY_AUTH_REGEX:
        case ACL_URL_REGEX:
        case ACL_URLPATH_REGEX:
        case ACL_BROWSER:
@@ -2352,7 +1871,7 @@ aclDumpTimeSpecList(acl_time_data * t)
     return W;
 }
 
-static wordlist *
+wordlist *
 aclDumpRegexList(relist * data)
 {
     wordlist *W = NULL;
@@ -2440,11 +1959,9 @@ ACL::dump() const
     case ACL_IDENT:
 #endif
     case ACL_DERIVED:
-    case ACL_PROXY_AUTH:
        fatal ("unused");
     case ACL_TIME:
        return aclDumpTimeSpecList((acl_time_data *)data);
-    case ACL_PROXY_AUTH_REGEX:
     case ACL_URL_REGEX:
     case ACL_URLPATH_REGEX:
     case ACL_BROWSER:
@@ -2946,43 +2463,6 @@ acl_access::deleteSelf () const
     delete this;
 }
 
-void
-ACLChecklist::AsyncState::changeState (ACLChecklist *checklist, AsyncState *newState) const
-{
-    checklist->changeState(newState);
-}
-
-ACLChecklist::NullState *
-ACLChecklist::NullState::Instance()
-{
-    return &_instance;
-}
-
-void
-ACLChecklist::NullState::checkForAsync(ACLChecklist *) const
-{
-}
-
-ACLChecklist::NullState ACLChecklist::NullState::_instance;
-
-void
-ACLChecklist::changeState (AsyncState *newState)
-{
-    /* only change from null to active and back again,
-     * not active to active.
-     * relax this once conversion to states is complete
-     * RBC 02 2003
-     */
-    assert (state_ == NullState::Instance() || newState == NullState::Instance());
-    state_ = newState;
-}
-
-ACLChecklist::AsyncState *
-ACLChecklist::asyncState() const
-{
-    return state_;
-}
-
 ACL::Prototype::Prototype() : prototype (NULL), typeString (NULL) {}
 
 ACL::Prototype::Prototype (ACL const *aPrototype, char const *aType) : prototype (aPrototype), typeString (aType) 
index ec3f231d4c331b6cd912e758a297bf388d2a8cef..122a7ddc21dd96a64c33b08b1b8d6a5f3e70e777 100644 (file)
@@ -1,6 +1,6 @@
 
 #
-# $Id: cf.data.pre,v 1.298 2003/02/08 14:42:09 hno Exp $
+# $Id: cf.data.pre,v 1.299 2003/02/13 08:07:47 robertc Exp $
 #
 #
 # SQUID Web Proxy Cache          http://www.squid-cache.org/
@@ -2167,7 +2167,7 @@ DOC_START
          # cache_peer_access mycache.mydomain.net allow asexample
          # cache_peer_access mycache_mydomain.net deny all
 
-       acl aclname proxy_auth username ...
+       acl aclname proxy_auth [-i] username ...
        acl aclname proxy_auth_regex [-i] pattern ...
          # list of valid usernames
          # use REQUIRED to accept any valid username.
index 78ac15829ff0d2e13b42ad821559c2e526776aaf..140fe437855c10ca8a465fc173d75db95e24fe51 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: client_side_reply.cc,v 1.38 2003/02/08 17:37:36 hno Exp $
+ * $Id: client_side_reply.cc,v 1.39 2003/02/13 08:07:47 robertc Exp $
  *
  * DEBUG: section 88    Client-side Reply Routines
  * AUTHOR: Robert Collins (Originally Duane Wessels in client_side.c)
@@ -1790,7 +1790,7 @@ clientReplyContext::processReplyAccess ()
        replyChecklist = clientAclChecklistCreate(Config.accessList.reply, http);
        replyChecklist->reply = rep;
        holdingReply = rep;
-       aclNBCheck(replyChecklist, ProcessReply, this);
+       replyChecklist->nonBlockingCheck(ProcessReply, this);
 }
 
 void
index 028eadcd5005fda64c083e9fb8d753c1499ca71c..2ccb244d0709717f69926a41c2c2c15df29f2512 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: client_side_request.cc,v 1.15 2003/02/12 06:11:02 robertc Exp $
+ * $Id: client_side_request.cc,v 1.16 2003/02/13 08:07:47 robertc Exp $
  * 
  * DEBUG: section 85    Client-side Request Routines
  * AUTHOR: Robert Collins (Originally Duane Wessels in client_side.c)
@@ -346,7 +346,7 @@ clientAccessCheck(ClientHttpRequest *http)
     }
     context->acl_checklist =
        clientAclChecklistCreate(Config.accessList.http, http);
-    aclNBCheck(context->acl_checklist, clientAccessCheckDone, context);
+    context->acl_checklist->nonBlockingCheck(clientAccessCheckDone, context);
 }
 
 void
@@ -698,7 +698,7 @@ ClientRequestContext::checkNoCache()
     if (Config.accessList.noCache && http->request->flags.cachable) {
        acl_checklist =
            clientAclChecklistCreate(Config.accessList.noCache, http);
-       aclNBCheck(acl_checklist, CheckNoCacheDone, cbdataReference(this));
+       acl_checklist->nonBlockingCheck(CheckNoCacheDone, cbdataReference(this));
     } else {
        CheckNoCacheDone(http->request->flags.cachable, cbdataReference(this));
     }
index 7f45be8a4618a0aacd6932afa3fb094a31e78ed2..ac227283da1f4b4b8d20e056a64d0fa6ebe2fef4 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: enums.h,v 1.223 2003/02/12 06:11:03 robertc Exp $
+ * $Id: enums.h,v 1.224 2003/02/13 08:07:47 robertc Exp $
  *
  *
  * SQUID Web Proxy Cache          http://www.squid-cache.org/
@@ -115,8 +115,6 @@ typedef enum {
     ACL_METHOD,
     ACL_BROWSER,
     ACL_REFERER_REGEX,
-    ACL_PROXY_AUTH,
-    ACL_PROXY_AUTH_REGEX,
     ACL_SRC_ASN,
     ACL_DST_ASN,
 #if USE_ARP_ACL
index 89506295417f6b78429512fe700a71da763fbf93..34919133b2a27f56cafdfe41df9646e0ef336fb9 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: external_acl.cc,v 1.25 2003/02/12 06:11:03 robertc Exp $
+ * $Id: external_acl.cc,v 1.26 2003/02/13 08:07:48 robertc Exp $
  *
  * DEBUG: section 82    External ACL
  * AUTHOR: Henrik Nordstrom, MARA Systems AB
@@ -41,6 +41,7 @@
  */
 
 #include "squid.h"
+#include "ExternalACL.h"
 #include "authenticate.h"
 #include "Store.h"
 #include "fde.h"
@@ -449,7 +450,7 @@ aclMatchExternal(void *data, ACLChecklist * ch)
        if (acl->def->require_auth) {
            int ti;
            /* Make sure the user is authenticated */
-           if ((ti = aclAuthenticated(ch)) != 1) {
+           if ((ti = ch->authenticated()) != 1) {
                debug(82, 2) ("aclMatchExternal: %s user not authenticated (%d)\n", acl->def->name, ti);
                return ti;
            }
@@ -466,6 +467,7 @@ aclMatchExternal(void *data, ACLChecklist * ch)
     if (!entry) {
        debug(82, 2) ("aclMatchExternal: %s(\"%s\") = lookup needed\n", acl->def->name, key);
        ch->state[ACL_EXTERNAL] = ACL_LOOKUP_NEEDED;
+       ch->changeState (ExternalACLLookup::Instance());
        return 0;
     }
     external_acl_cache_touch(acl->def, entry);
@@ -782,10 +784,10 @@ externalAclHandleReply(void *data, char *reply)
 }
 
 void
-externalAclLookup(ACLChecklist * ch, void *acl_data, EAH * callback, void *callback_data)
+ACL::ExternalAclLookup(ACLChecklist * ch, ACL * me, EAH * callback, void *callback_data)
 {
     MemBuf buf;
-    external_acl_data *acl = static_cast<external_acl_data *>(acl_data);
+    external_acl_data *acl = static_cast<external_acl_data *>(me->data);
     external_acl *def = acl->def;
     const char *key = makeExternalAclKey(ch, acl);
     external_acl_entry *entry = static_cast<external_acl_entry *>(hash_lookup(def->cache, key));
@@ -887,3 +889,30 @@ externalAclShutdown(void)
        helperShutdown(p->theHelper);
     }
 }
+
+ExternalACLLookup ExternalACLLookup::instance_;
+ExternalACLLookup *
+ExternalACLLookup::Instance()
+{
+    return &instance_;
+}
+
+void
+ExternalACLLookup::checkForAsync(ACLChecklist *checklist)const
+{
+    assert (checklist->state[ACL_EXTERNAL] == ACL_LOOKUP_NEEDED);
+    acl *acl = ACL::FindByName(AclMatchedName);
+    assert (acl->aclType() == ACL_EXTERNAL);
+    checklist->asyncInProgress(true);
+    ACL::ExternalAclLookup(checklist, acl, LookupDone, checklist);
+}
+
+void
+ExternalACLLookup::LookupDone(void *data, void *result)
+{
+    ACLChecklist *checklist = (ACLChecklist *)data;
+    checklist->state[ACL_EXTERNAL] = ACL_LOOKUP_DONE;
+    checklist->extacl_entry = cbdataReference((external_acl_entry *)result);
+    checklist->asyncInProgress(false);
+    checklist->check();
+}
index 30a43739fd99c2fe348f23abe15659d33644576c..2d1388ce64ffda1a3705c0c00bc6739543ca3409 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: peer_select.cc,v 1.126 2003/02/12 06:11:04 robertc Exp $
+ * $Id: peer_select.cc,v 1.127 2003/02/13 08:07:48 robertc Exp $
  *
  * DEBUG: section 44    Peer Selection Algorithm
  * AUTHOR: Duane Wessels
@@ -251,8 +251,7 @@ peerSelectFoo(ps_state * ps)
                Config.accessList.AlwaysDirect,
                request,
                NULL);          /* ident */
-           aclNBCheck(ps->acl_checklist,
-               peerCheckAlwaysDirectDone,
+           ps->acl_checklist->nonBlockingCheck(peerCheckAlwaysDirectDone,
                ps);
            return;
        } else if (ps->always_direct > 0) {
@@ -262,8 +261,7 @@ peerSelectFoo(ps_state * ps)
                Config.accessList.NeverDirect,
                request,
                NULL);          /* ident */
-           aclNBCheck(ps->acl_checklist,
-               peerCheckNeverDirectDone,
+           ps->acl_checklist->nonBlockingCheck(peerCheckNeverDirectDone,
                ps);
            return;
        } else if (ps->never_direct > 0) {