+++ /dev/null
-/*
- * $Id$
- *
- * DEBUG: section 28 Access Control
- * AUTHOR: Henrik Nordstrom
- *
- * 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.
- *
- */
-
-bool
-ACLChecklist::matchAclListFast(const ACLList * list)
-{
- matchAclList(list, true);
- return finished();
-}
-
*/
#include "squid.h"
-#include "ACLChecklist.h"
-#include "HttpRequest.h"
-#include "HttpReply.h"
-#include "authenticate.h"
-#include "ACLProxyAuth.h"
-#include "client_side.h"
-#include "auth/UserRequest.h"
-
-int
-ACLChecklist::authenticated()
-{
- http_hdr_type headertype;
-
- if (NULL == request) {
- fatal ("requiresRequest SHOULD have been true for this ACL!!");
- return 0;
- } else if (request->flags.accelerated) {
- /* WWW authorization on accelerated requests */
- headertype = HDR_AUTHORIZATION;
- } else if (request->flags.intercepted || request->flags.spoof_client_ip) {
- debugs(28, DBG_IMPORTANT, HERE << " authentication not applicable on intercepted requests.");
- return -1;
- } else {
- /* Proxy authorization on proxy requests */
- headertype = HDR_PROXY_AUTHORIZATION;
- }
-
- /* get authed here */
- /* Note: this fills in auth_user_request when applicable */
- /*
- * DPW 2007-05-08
- * tryToAuthenticateAndSetAuthUser used to try to lock and
- * unlock auth_user_request on our behalf, but it was too
- * ugly and hard to follow. Now we do our own locking here.
- *
- * I'm not sure what tryToAuthenticateAndSetAuthUser does when
- * auth_user_request is set before calling. I'm tempted to
- * unlock and set it to NULL, but it seems safer to save the
- * pointer before calling and unlock it afterwards. If the
- * pointer doesn't change then its a no-op.
- */
- AuthUserRequest *old_auth_user_request = auth_user_request;
- auth_acl_t result = AuthUserRequest::tryToAuthenticateAndSetAuthUser (&auth_user_request, headertype, request, conn(), src_addr);
- if (auth_user_request)
- AUTHUSERREQUESTLOCK(auth_user_request, "ACLChecklist");
- AUTHUSERREQUESTUNLOCK(old_auth_user_request, "old ACLChecklist");
- switch (result) {
-
- case AUTH_ACL_CANNOT_AUTHENTICATE:
- debugs(28, 4, "aclMatchAcl: returning 0 user authenticated but not authorised.");
- return 0;
-
- case AUTH_AUTHENTICATED:
-
- return 1;
- break;
-
- case AUTH_ACL_HELPER:
- debugs(28, 4, "aclMatchAcl: returning 0 sending credentials to helper.");
- changeState (ProxyAuthLookup::Instance());
- return 0;
-
- case AUTH_ACL_CHALLENGE:
- debugs(28, 4, "aclMatchAcl: returning 0 sending authentication challenge.");
- changeState (ProxyAuthNeeded::Instance());
- return 0;
-
- default:
- fatal("unexpected authenticateAuthenticate reply\n");
- return 0;
- }
-}
+#include "acl/Checklist.h"
allow_t const &
ACLChecklist::currentAnswer() const
asyncState()->checkForAsync(this);
}
+// ACLFilledChecklist overwrites this to unclock something before we
+// "delete this"
void
ACLChecklist::checkCallback(allow_t answer)
{
void *cbdata_;
debugs(28, 3, "ACLChecklist::checkCallback: " << this << " answer=" << answer);
- /* During reconfigure, we can end up not finishing call
- * sequences into the auth code */
-
- if (auth_user_request) {
- /* the checklist lock */
- AUTHUSERREQUESTUNLOCK(auth_user_request, "ACLChecklist");
- /* it might have been connection based */
- assert(conn() != NULL);
- /*
- * DPW 2007-05-08
- * yuck, this make me uncomfortable. why do this here?
- * ConnStateData will do its own unlocking.
- */
- AUTHUSERREQUESTUNLOCK(conn()->auth_user_request, "conn via ACLChecklist");
- conn()->auth_type = AUTH_BROKEN;
- }
-
callback_ = callback;
callback = NULL;
PROF_stop(aclMatchAclList);
}
-CBDATA_CLASS_INIT(ACLChecklist);
-
-void *
-ACLChecklist::operator new (size_t size)
-{
- assert (size == sizeof(ACLChecklist));
- CBDATA_INIT_TYPE(ACLChecklist);
- ACLChecklist *result = cbdataAlloc(ACLChecklist);
- return result;
-}
-
-void
-ACLChecklist::operator delete (void *address)
-{
- ACLChecklist *t = static_cast<ACLChecklist *>(address);
- cbdataFree(t);
-}
-
ACLChecklist::ACLChecklist() :
accessList (NULL),
- dst_peer(NULL),
- request (NULL),
- reply (NULL),
- auth_user_request (NULL),
-#if SQUID_SNMP
- snmp_community(NULL),
-#endif
-#if USE_SSL
- ssl_error(0),
-#endif
callback (NULL),
callback_data (NULL),
- extacl_entry (NULL),
- conn_(NULL),
- fd_(-1),
async_(false),
finished_(false),
allow_(ACCESS_DENIED),
state_(NullState::Instance()),
- destinationDomainChecked_(false),
- sourceDomainChecked_(false),
lastACLResult_(false)
{
- my_addr.SetEmpty();
- src_addr.SetEmpty();
- dst_addr.SetEmpty();
- rfc931[0] = '\0';
}
ACLChecklist::~ACLChecklist()
{
assert (!asyncInProgress());
- if (extacl_entry)
- cbdataReferenceDone(extacl_entry);
-
- HTTPMSGUNLOCK(request);
-
- HTTPMSGUNLOCK(reply);
-
- // no auth_user_request in builds without any Authentication configured
- if (auth_user_request)
- AUTHUSERREQUESTUNLOCK(auth_user_request, "ACLChecklist destructor");
-
- cbdataReferenceDone(conn_);
-
cbdataReferenceDone(accessList);
debugs(28, 4, "ACLChecklist::~ACLChecklist: destroyed " << this);
}
-ConnStateData *
-ACLChecklist::conn() const
-{
- return conn_;
-}
-
-void
-ACLChecklist::conn(ConnStateData *aConn)
-{
- assert (conn() == NULL);
- conn_ = cbdataReference(aConn);
-}
-
-int
-ACLChecklist::fd() const
-{
- return conn_ != NULL ? conn_->fd : fd_;
-}
-
-void
-ACLChecklist::fd(int aDescriptor)
-{
- assert(!conn() || conn()->fd == aDescriptor);
- fd_ = aDescriptor;
-}
-
void
ACLChecklist::AsyncState::changeState (ACLChecklist *checklist, AsyncState *newState) const
{
}
-bool
-ACLChecklist::destinationDomainChecked() const
-{
- return destinationDomainChecked_;
-}
-
-void
-ACLChecklist::markDestinationDomainChecked()
-{
- assert (!finished() && !destinationDomainChecked());
- destinationDomainChecked_ = true;
-}
-
-bool
-ACLChecklist::sourceDomainChecked() const
-{
- return sourceDomainChecked_;
-}
-
-void
-ACLChecklist::markSourceDomainChecked()
-{
- assert (!finished() && !sourceDomainChecked());
- sourceDomainChecked_ = true;
-}
-
bool
ACLChecklist::checking() const
{
checking_ = newValue;
}
-/*
- * Any ACLChecklist created by aclChecklistCreate() must eventually be
- * freed by ACLChecklist::operator delete(). There are two common cases:
- *
- * A) Using aclCheckFast(): The caller creates the ACLChecklist using
- * aclChecklistCreate(), checks it using aclCheckFast(), and frees it
- * using aclChecklistFree().
- *
- * B) Using aclNBCheck() and callbacks: The caller creates the
- * ACLChecklist using aclChecklistCreate(), and passes it to
- * aclNBCheck(). Control eventually passes to ACLChecklist::checkCallback(),
- * which will invoke the callback function as requested by the
- * original caller of aclNBCheck(). This callback function must
- * *not* invoke aclChecklistFree(). After the callback function
- * returns, ACLChecklist::checkCallback() will free the ACLChecklist using
- * aclChecklistFree().
- */
-ACLChecklist *
-aclChecklistCreate(const acl_access * A, HttpRequest * request, const char *ident)
+bool
+ACLChecklist::callerGone()
{
- // TODO: make this a constructor? On-stack creation uses the same code.
- ACLChecklist *checklist = new ACLChecklist;
-
- if (A)
- checklist->accessList = cbdataReference(A);
-
- if (request != NULL) {
- checklist->request = HTTPMSGLOCK(request);
-#if FOLLOW_X_FORWARDED_FOR
- if (Config.onoff.acl_uses_indirect_client)
- checklist->src_addr = request->indirect_client_addr;
- else
-#endif /* FOLLOW_X_FORWARDED_FOR */
- checklist->src_addr = request->client_addr;
- checklist->my_addr = request->my_addr;
- }
-
-#if USE_IDENT
- if (ident)
- xstrncpy(checklist->rfc931, ident, USER_IDENT_SZ);
-
-#endif
-
- return checklist;
+ return !cbdataReferenceValid(callback_data);
}
bool
-ACLChecklist::callerGone()
+ACLChecklist::matchAclListFast(const ACLList * list)
{
- return !cbdataReferenceValid(callback_data);
+ matchAclList(list, true);
+ return finished();
}
-#ifndef _USE_INLINE_
-#include "ACLChecklist.cci"
-#endif
+
#ifndef SQUID_ACLCHECKLIST_H
#define SQUID_ACLCHECKLIST_H
-//#include "typedefs.h"
-//#include "client_side.h"
-//#include "structs.h"
+#include "acl/Acl.h"
-#include "ACL.h"
-
-class AuthUserRequest;
-class ExternalACLEntry;
-class ConnStateData;
-
-/// \ingroup ACLAPI
+/** \ingroup ACLAPI
+ Base class for maintaining Squid and transaction state for access checks.
+ Provides basic ACL checking methods. Its only child, ACLFilledChecklist,
+ keeps the actual state data. The split is necessary to avoid exposing
+ all ACL-related code to virtually Squid data types. */
class ACLChecklist
{
};
-public: /* operators */
- void *operator new(size_t);
- void operator delete(void *);
-
+public:
ACLChecklist();
- ~ACLChecklist();
- /** NP: To cause link failures if assignment attempted */
- ACLChecklist (ACLChecklist const &);
- /** NP: To cause link failures if assignment attempted */
- ACLChecklist &operator=(ACLChecklist const &);
-
-public: /* API methods */
+ virtual ~ACLChecklist();
/**
* Trigger off a non-blocking access check for a set of *_access options..
* \retval 1/true Access Allowed
* \retval 0/false Access Denied
*/
- _SQUID_INLINE_ bool matchAclListFast(const ACLList * list);
+ bool matchAclListFast(const ACLList * list);
/**
* Attempt to check the current checklist against current data.
*/
void check();
- ConnStateData * conn() const;
-
- /// uses conn() if available
- int fd() const;
-
- /// set either conn
- void conn(ConnStateData *);
- /// set FD
- void fd(int aDescriptor);
-
-/* Accessors used by internal ACL stuff */
-
- int authenticated();
-
bool asyncInProgress() const;
void asyncInProgress(bool const);
void changeState(AsyncState *);
AsyncState *asyncState() const;
-private: /* NP: only used internally */
+ // XXX: ACLs that need request or reply have to use ACLFilledChecklist and
+ // should do their own checks so that we do not have to povide these two
+ // for ACL::checklistMatches to use
+ virtual bool hasRequest() const = 0;
+ virtual bool hasReply() const = 0;
- void checkCallback(allow_t answer);
+private:
+ virtual void checkCallback(allow_t answer);
void checkAccessList();
void checkForAsync();
-public: /* checklist available data */
-
+public:
const acl_access *accessList;
- IpAddress src_addr;
-
- IpAddress dst_addr;
-
- IpAddress my_addr;
-
- struct peer *dst_peer;
-
- HttpRequest *request;
-
- /* for acls that look at reply data */
- HttpReply *reply;
- char rfc931[USER_IDENT_SZ];
- AuthUserRequest *auth_user_request;
-#if SQUID_SNMP
-
- char *snmp_community;
-#endif
-
-#if USE_SSL
- int ssl_error;
-#endif
-
PF *callback;
void *callback_data;
- ExternalACLEntry *extacl_entry;
-
- bool destinationDomainChecked() const;
- void markDestinationDomainChecked();
- bool sourceDomainChecked() const;
- void markSourceDomainChecked();
private: /* internal methods */
void preCheck();
void matchAclList(const ACLList * list, bool const fast);
void matchAclListSlow(const ACLList * list);
- CBDATA_CLASS(ACLChecklist);
- ConnStateData * conn_; /**< hack for ident and NTLM */
- int fd_; /**< may be available when conn_ is not */
bool async_;
bool finished_;
allow_t allow_;
AsyncState *state_;
- bool destinationDomainChecked_;
- bool sourceDomainChecked_;
+
bool checking_;
bool checking() const;
void checking (bool const);
bool lastACLResult() const { return lastACLResult_; }
};
-/// \ingroup ACLAPI
-SQUIDCEXTERN ACLChecklist *aclChecklistCreate(const acl_access *,
- HttpRequest *,
- const char *ident);
-
-#ifdef _USE_INLINE_
-#include "ACLChecklist.cci"
-#endif
-
#endif /* SQUID_ACLCHECKLIST_H */
--- /dev/null
+#include "squid.h"
+#include "HttpRequest.h"
+#include "HttpReply.h"
+#include "client_side.h"
+#include "auth/UserRequest.h"
+#include "auth/AclProxyAuth.h"
+#include "acl/FilledChecklist.h"
+
+CBDATA_CLASS_INIT(ACLFilledChecklist);
+
+#if MOVED
+int
+ACLFilledChecklist::authenticated()
+{
+ http_hdr_type headertype;
+
+ if (NULL == request) {
+ fatal ("requiresRequest SHOULD have been true for this ACL!!");
+ return 0;
+ } else if (request->flags.accelerated) {
+ /* WWW authorization on accelerated requests */
+ headertype = HDR_AUTHORIZATION;
+ } else if (request->flags.intercepted || request->flags.spoof_client_ip) {
+ debugs(28, DBG_IMPORTANT, HERE << " authentication not applicable on intercepted requests.");
+ return -1;
+ } else {
+ /* Proxy authorization on proxy requests */
+ headertype = HDR_PROXY_AUTHORIZATION;
+ }
+
+ /* get authed here */
+ /* Note: this fills in auth_user_request when applicable */
+ /*
+ * DPW 2007-05-08
+ * tryToAuthenticateAndSetAuthUser used to try to lock and
+ * unlock auth_user_request on our behalf, but it was too
+ * ugly and hard to follow. Now we do our own locking here.
+ *
+ * I'm not sure what tryToAuthenticateAndSetAuthUser does when
+ * auth_user_request is set before calling. I'm tempted to
+ * unlock and set it to NULL, but it seems safer to save the
+ * pointer before calling and unlock it afterwards. If the
+ * pointer doesn't change then its a no-op.
+ */
+ AuthUserRequest *old_auth_user_request = auth_user_request;
+ auth_acl_t result = AuthUserRequest::tryToAuthenticateAndSetAuthUser (&auth_user_request, headertype, request, conn(), src_addr);
+ if (auth_user_request)
+ AUTHUSERREQUESTLOCK(auth_user_request, "ACLFilledChecklist");
+ AUTHUSERREQUESTUNLOCK(old_auth_user_request, "old ACLFilledChecklist");
+ switch (result) {
+
+ case AUTH_ACL_CANNOT_AUTHENTICATE:
+ debugs(28, 4, "aclMatchAcl: returning 0 user authenticated but not authorised.");
+ return 0;
+
+ case AUTH_AUTHENTICATED:
+
+ return 1;
+ break;
+
+ case AUTH_ACL_HELPER:
+ debugs(28, 4, "aclMatchAcl: returning 0 sending credentials to helper.");
+ changeState (ProxyAuthLookup::Instance());
+ return 0;
+
+ case AUTH_ACL_CHALLENGE:
+ debugs(28, 4, "aclMatchAcl: returning 0 sending authentication challenge.");
+ changeState (ProxyAuthNeeded::Instance());
+ return 0;
+
+ default:
+ fatal("unexpected authenticateAuthenticate reply\n");
+ return 0;
+ }
+}
+#endif
+
+void
+ACLFilledChecklist::checkCallback(allow_t answer)
+{
+ debugs(28, 5, "ACLFilledChecklist::checkCallback: " << this << " answer=" << answer);
+
+ /* During reconfigure, we can end up not finishing call
+ * sequences into the auth code */
+
+ if (auth_user_request) {
+ /* the filled_checklist lock */
+ AUTHUSERREQUESTUNLOCK(auth_user_request, "ACLFilledChecklist");
+ /* it might have been connection based */
+ assert(conn() != NULL);
+ /*
+ * DPW 2007-05-08
+ * yuck, this make me uncomfortable. why do this here?
+ * ConnStateData will do its own unlocking.
+ */
+ AUTHUSERREQUESTUNLOCK(conn()->auth_user_request, "conn via ACLFilledChecklist");
+ conn()->auth_type = AUTH_BROKEN;
+ }
+
+ ACLFilledChecklist::checkCallback(answer); // may delete us
+}
+
+
+void *
+ACLFilledChecklist::operator new (size_t size)
+{
+ assert (size == sizeof(ACLFilledChecklist));
+ CBDATA_INIT_TYPE(ACLFilledChecklist);
+ ACLFilledChecklist *result = cbdataAlloc(ACLFilledChecklist);
+ return result;
+}
+
+void
+ACLFilledChecklist::operator delete (void *address)
+{
+ ACLFilledChecklist *t = static_cast<ACLFilledChecklist *>(address);
+ cbdataFree(t);
+}
+
+
+ACLFilledChecklist::ACLFilledChecklist() :
+ dst_peer(NULL),
+ request (NULL),
+ reply (NULL),
+ auth_user_request (NULL),
+#if SQUID_SNMP
+ snmp_community(NULL),
+#endif
+#if USE_SSL
+ ssl_error(0),
+#endif
+ extacl_entry (NULL),
+ conn_(NULL),
+ fd_(-1),
+ destinationDomainChecked_(false),
+ sourceDomainChecked_(false)
+{
+ my_addr.SetEmpty();
+ src_addr.SetEmpty();
+ dst_addr.SetEmpty();
+ rfc931[0] = '\0';
+}
+
+
+ACLFilledChecklist::~ACLFilledChecklist()
+{
+ assert (!asyncInProgress());
+
+ if (extacl_entry)
+ cbdataReferenceDone(extacl_entry);
+
+ HTTPMSGUNLOCK(request);
+
+ HTTPMSGUNLOCK(reply);
+
+ // no auth_user_request in builds without any Authentication configured
+ if (auth_user_request)
+ AUTHUSERREQUESTUNLOCK(auth_user_request, "ACLFilledChecklist destructor");
+
+ cbdataReferenceDone(conn_);
+
+ debugs(28, 4, HERE << "ACLFilledChecklist destroyed " << this);
+}
+
+
+ConnStateData *
+ACLFilledChecklist::conn() const
+{
+ return conn_;
+}
+
+void
+ACLFilledChecklist::conn(ConnStateData *aConn)
+{
+ assert (conn() == NULL);
+ conn_ = cbdataReference(aConn);
+}
+
+int
+ACLFilledChecklist::fd() const
+{
+ return conn_ != NULL ? conn_->fd : fd_;
+}
+
+void
+ACLFilledChecklist::fd(int aDescriptor)
+{
+ assert(!conn() || conn()->fd == aDescriptor);
+ fd_ = aDescriptor;
+}
+
+bool
+ACLFilledChecklist::destinationDomainChecked() const
+{
+ return destinationDomainChecked_;
+}
+
+void
+ACLFilledChecklist::markDestinationDomainChecked()
+{
+ assert (!finished() && !destinationDomainChecked());
+ destinationDomainChecked_ = true;
+}
+
+bool
+ACLFilledChecklist::sourceDomainChecked() const
+{
+ return sourceDomainChecked_;
+}
+
+void
+ACLFilledChecklist::markSourceDomainChecked()
+{
+ assert (!finished() && !sourceDomainChecked());
+ sourceDomainChecked_ = true;
+}
+
+/*
+ * There are two common ACLFilledChecklist lifecycles paths:
+ *
+ * A) Using aclCheckFast(): The caller creates an ACLFilledChecklist object
+ * on stack and calls aclCheckFast().
+ *
+ * B) Using aclNBCheck() and callbacks: The caller allocates an
+ * ACLFilledChecklist object (via operator new) and passes it to
+ * aclNBCheck(). Control eventually passes to ACLChecklist::checkCallback(),
+ * which will invoke the callback function as requested by the
+ * original caller of aclNBCheck(). This callback function must
+ * *not* delete the list. After the callback function returns,
+ * checkCallback() will delete the list (i.e., self).
+ */
+ACLFilledChecklist::ACLFilledChecklist(const acl_access *A, HttpRequest *request, const char *ident):
+ dst_peer(NULL),
+ request(NULL),
+ reply(NULL),
+ auth_user_request(NULL),
+#if SQUID_SNMP
+ snmp_community(NULL),
+#endif
+#if USE_SSL
+ ssl_error(0),
+#endif
+ extacl_entry (NULL),
+ conn_(NULL),
+ fd_(-1),
+ destinationDomainChecked_(false),
+ sourceDomainChecked_(false)
+{
+ my_addr.SetEmpty();
+ src_addr.SetEmpty();
+ dst_addr.SetEmpty();
+ rfc931[0] = '\0';
+
+ // cbdataReferenceDone() is in either fastCheck() or the destructor
+ if (A)
+ accessList = cbdataReference(A);
+
+ if (request != NULL) {
+ request = HTTPMSGLOCK(request);
+#if FOLLOW_X_FORWARDED_FOR
+ if (Config.onoff.acl_uses_indirect_client)
+ src_addr = request->indirect_client_addr;
+ else
+#endif /* FOLLOW_X_FORWARDED_FOR */
+ src_addr = request->client_addr;
+ my_addr = request->my_addr;
+ }
+
+#if USE_IDENT
+ if (ident)
+ xstrncpy(rfc931, ident, USER_IDENT_SZ);
+#endif
+}
+
--- /dev/null
+#ifndef SQUID_ACLFILLED_CHECKLIST_H
+#define SQUID_ACLFILLED_CHECKLIST_H
+
+#include "acl/Checklist.h"
+
+class AuthUserRequest;
+class ExternalACLEntry;
+class ConnStateData;
+
+/** \ingroup ACLAPI
+ ACLChecklist filled with specific data, representing Squid and transaction
+ state for access checks along with some data-specific checking methods */
+class ACLFilledChecklist: public ACLChecklist
+{
+public:
+ void *operator new(size_t);
+ void operator delete(void *);
+
+ ACLFilledChecklist();
+ ACLFilledChecklist(const acl_access *, HttpRequest *, const char *ident);
+ ~ACLFilledChecklist();
+
+public:
+ ConnStateData * conn() const;
+
+ /// uses conn() if available
+ int fd() const;
+
+ /// set either conn
+ void conn(ConnStateData *);
+ /// set FD
+ void fd(int aDescriptor);
+
+ //int authenticated();
+
+ bool destinationDomainChecked() const;
+ void markDestinationDomainChecked();
+ bool sourceDomainChecked() const;
+ void markSourceDomainChecked();
+
+ // ACLChecklist API
+ virtual bool hasRequest() const { return request != NULL; }
+ virtual bool hasReply() const { return reply != NULL; }
+
+public:
+ IpAddress src_addr;
+ IpAddress dst_addr;
+ IpAddress my_addr;
+ struct peer *dst_peer;
+
+ HttpRequest *request;
+ HttpReply *reply;
+
+ char rfc931[USER_IDENT_SZ];
+ AuthUserRequest *auth_user_request;
+
+#if SQUID_SNMP
+ char *snmp_community;
+#endif
+
+#if USE_SSL
+ int ssl_error;
+#endif
+
+ ExternalACLEntry *extacl_entry;
+
+private:
+ virtual void checkCallback(allow_t answer);
+
+private:
+ CBDATA_CLASS(ACLFilledChecklist);
+
+ ConnStateData * conn_; /**< hack for ident and NTLM */
+ int fd_; /**< may be available when conn_ is not */
+ bool destinationDomainChecked_;
+ bool sourceDomainChecked_;
+
+private:
+ /// not implemented; will cause link failures if used
+ ACLFilledChecklist(const ACLFilledChecklist &);
+ /// not implemented; will cause link failures if used
+ ACLFilledChecklist &operator=(const ACLFilledChecklist &);
+};
+
+/// convenience and safety wrapper for dynamic_cast<ACLFilledChecklist*>
+inline
+ACLFilledChecklist *Filled(ACLChecklist *checklist)
+{
+ // this should always be safe because ACLChecklist is an abstract class
+ // and ACLFilledChecklist is its only [concrete] child
+ return dynamic_cast<ACLFilledChecklist*>(checklist);
+}
+
+#endif /* SQUID_ACLFILLED_CHECKLIST_H */