From: robertc <> Date: Thu, 13 Feb 2003 15:07:46 +0000 (+0000) Subject: Summary: Merge further ACL refactoring (including bugfixes) X-Git-Tag: SQUID_3_0_PRE1~356 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=225b7b107261e7d01d087e1061533751c2a7a0e0;p=thirdparty%2Fsquid.git Summary: Merge further ACL refactoring (including bugfixes) 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. --- diff --git a/src/ACL.h b/src/ACL.h index 48a4bd36e6..ca82697c3f 100644 --- 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 index 0000000000..b800c4ad8c --- /dev/null +++ b/src/ACLChecklist.cc @@ -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 + */ + +#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(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(); +} + diff --git a/src/ACLChecklist.h b/src/ACLChecklist.h index f272b72455..3707f3ca86 100644 --- a/src/ACLChecklist.h +++ b/src/ACLChecklist.h @@ -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 index 0000000000..d595217a55 --- /dev/null +++ b/src/ACLData.h @@ -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 + */ + +#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 */ diff --git a/src/ACLIP.cc b/src/ACLIP.cc index 2e1a74085b..1cf8f451a7 100644 --- a/src/ACLIP.cc +++ b/src/ACLIP.cc @@ -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){} diff --git a/src/ACLProxyAuth.cc b/src/ACLProxyAuth.cc index 32af816303..0c2473fc02 100644 --- a/src/ACLProxyAuth.cc +++ b/src/ACLProxyAuth.cc @@ -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); +} + diff --git a/src/ACLProxyAuth.h b/src/ACLProxyAuth.h index 2fd75618e8..1ae5b37131 100644 --- a/src/ACLProxyAuth.h +++ b/src/ACLProxyAuth.h @@ -36,7 +36,25 @@ #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 index 0000000000..dcc26198ac --- /dev/null +++ b/src/ACLRegexData.cc @@ -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 + */ + +#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 index 0000000000..d03db535a7 --- /dev/null +++ b/src/ACLRegexData.h @@ -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 + */ + +#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 */ diff --git a/src/ACLUserData.cc b/src/ACLUserData.cc index 3e81946741..1aca2fec7e 100644 --- a/src/ACLUserData.cc +++ b/src/ACLUserData.cc @@ -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; +} diff --git a/src/ACLUserData.h b/src/ACLUserData.h index 19eac21979..92e4df62bb 100644 --- a/src/ACLUserData.h +++ b/src/ACLUserData.h @@ -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 *names; struct { diff --git a/src/ExternalACL.h b/src/ExternalACL.h new file mode 100644 index 0000000000..26a0186d90 --- /dev/null +++ b/src/ExternalACL.h @@ -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 + */ + +#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 */ diff --git a/src/Makefile.am b/src/Makefile.am index 3333844dfc..2a1732d158 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -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 \ diff --git a/src/Makefile.in b/src/Makefile.in index c019b57fb4..370eb2aa4b 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -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 \ diff --git a/src/acl.cc b/src/acl.cc index 503fdd2efc..08f5d45462 100644 --- a/src/acl.cc +++ b/src/acl.cc @@ -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 @@ -39,11 +39,11 @@ #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(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) diff --git a/src/cf.data.pre b/src/cf.data.pre index ec3f231d4c..122a7ddc21 100644 --- a/src/cf.data.pre +++ b/src/cf.data.pre @@ -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. diff --git a/src/client_side_reply.cc b/src/client_side_reply.cc index 78ac15829f..140fe43785 100644 --- a/src/client_side_reply.cc +++ b/src/client_side_reply.cc @@ -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 diff --git a/src/client_side_request.cc b/src/client_side_request.cc index 028eadcd50..2ccb244d07 100644 --- a/src/client_side_request.cc +++ b/src/client_side_request.cc @@ -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)); } diff --git a/src/enums.h b/src/enums.h index 7f45be8a46..ac227283da 100644 --- a/src/enums.h +++ b/src/enums.h @@ -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 diff --git a/src/external_acl.cc b/src/external_acl.cc index 8950629541..34919133b2 100644 --- a/src/external_acl.cc +++ b/src/external_acl.cc @@ -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(acl_data); + external_acl_data *acl = static_cast(me->data); external_acl *def = acl->def; const char *key = makeExternalAclKey(ch, acl); external_acl_entry *entry = static_cast(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(); +} diff --git a/src/peer_select.cc b/src/peer_select.cc index 30a43739fd..2d1388ce64 100644 --- a/src/peer_select.cc +++ b/src/peer_select.cc @@ -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) {