* we do NOT want the indirect client address to be tested here.
*/
ACLFilledChecklist ch(Config.accessList.miss, request, NULL);
+ ch.al = al;
ch.src_addr = request->client_addr;
+ ch.syncAle(request, nullptr);
if (ch.fastCheck().denied()) {
err_type page_id;
page_id = aclGetDenyInfoPage(&Config.denyInfoList, AclMatchedName, 1);
bool retriable = checkRetriable();
if (!retriable && Config.accessList.serverPconnForNonretriable) {
ACLFilledChecklist ch(Config.accessList.serverPconnForNonretriable, request, NULL);
+ ch.al = al;
+ ch.syncAle(request, nullptr);
retriable = ch.fastCheck().allowed();
}
// always call shared pool first because we need to close an idle
if (Config.accessList.spoof_client_ip) {
ACLFilledChecklist *checklist = new ACLFilledChecklist(Config.accessList.spoof_client_ip, this, clientConnection->rfc931);
checklist->al = al;
+ checklist->syncAle(this, nullptr);
flags.spoofClientIp = checklist->fastCheck().allowed();
delete checklist;
} else
typedef Values::iterator VLI;
ACLFilledChecklist ch(NULL, request, NULL);
+ ch.al = al;
ch.reply = reply;
+ ch.syncAle(request, nullptr);
if (reply)
HTTPMSGLOCK(ch.reply);
} else {
// make sure the ALE has as much data as possible
if (requiresAle())
- checklist->syncAle();
+ checklist->verifyAle();
// have to cast because old match() API is missing const
result = const_cast<ACL*>(this)->match(checklist);
#include <stack>
#include <vector>
+class HttpRequest;
+
/// ACL checklist callback
typedef void ACLCB(allow_t, void *);
virtual bool hasRequest() const = 0;
virtual bool hasReply() const = 0;
virtual bool hasAle() const = 0;
- virtual void syncAle() const = 0;
+ /// assigns uninitialized adapted_request and url ALE components
+ virtual void syncAle(HttpRequest *adaptedRequest, const char *logUri) const = 0;
+ /// warns if there are uninitialized ALE components and fills them
+ virtual void verifyAle() const = 0;
/// change the current ACL list
/// \return a pointer to the old list value (may be nullptr)
}
void
-ACLFilledChecklist::syncAle() const
+ACLFilledChecklist::verifyAle() const
{
// make sure the ALE fields used by Format::assemble to
// fill the old external_acl_type codes are set if any
if (request) {
if (!al->request) {
showDebugWarning("HttpRequest object");
+ // XXX: al->request should be original,
+ // but the request may be already adapted
al->request = request;
HTTPMSGLOCK(al->request);
}
if (al->url.isEmpty()) {
showDebugWarning("URL");
+ // XXX: al->url should be the request URL from client,
+ // but request->url may be different (e.g.,redirected)
al->url = request->url.absolute();
}
}
#endif
}
+void
+ACLFilledChecklist::syncAle(HttpRequest *adaptedRequest, const char *logUri) const
+{
+ if (!al)
+ return;
+ if (!al->adapted_request) {
+ al->adapted_request = adaptedRequest;
+ HTTPMSGLOCK(al->adapted_request);
+ }
+ if (al->url.isEmpty())
+ al->url = logUri;
+}
+
ConnStateData *
ACLFilledChecklist::conn() const
{
virtual bool hasRequest() const { return request != NULL; }
virtual bool hasReply() const { return reply != NULL; }
virtual bool hasAle() const { return al != NULL; }
- virtual void syncAle() const;
+ virtual void syncAle(HttpRequest *adaptedRequest, const char *logUri) const;
+ virtual void verifyAle() const;
public:
Ip::Address src_addr;
if ((acl_checklist->reply = filter.reply))
HTTPMSGLOCK(acl_checklist->reply);
acl_checklist->al = filter.al;
+ acl_checklist->syncAle(filter.request, nullptr);
acl_checklist->nonBlockingCheck(AccessCheckCallbackWrapper, this);
return;
}
al->adapted_request = request;
HTTPMSGLOCK(al->adapted_request);
}
+ // no need checklist.syncAle(): already synced
+ checklist.al = al;
accessLogLog(al, &checklist);
bool updatePerformanceCounters = true;
if (Config.accessList.stats_collection) {
ACLFilledChecklist statsCheck(Config.accessList.stats_collection, request, NULL);
+ statsCheck.al = al;
if (al->reply) {
statsCheck.reply = al->reply;
HTTPMSGLOCK(statsCheck.reply);
bool allowDomainMismatch = false;
if (Config.ssl_client.cert_error) {
ACLFilledChecklist check(Config.ssl_client.cert_error, request, dash_str);
+ check.al = http->al;
check.sslErrors = new Security::CertErrors(Security::CertError(SQUID_X509_V_ERR_DOMAIN_MISMATCH, srvCert));
+ check.syncAle(request, http->log_uri);
allowDomainMismatch = check.fastCheck().allowed();
delete check.sslErrors;
check.sslErrors = NULL;
{
if (conn->mayTunnelUnsupportedProto()) {
ACLFilledChecklist checklist(Config.accessList.on_unsupported_protocol, request.getRaw(), nullptr);
+ checklist.al = (context && context->http) ? context->http->al : nullptr;
checklist.requestErrorType = requestError;
checklist.src_addr = conn->clientConnection->remote;
checklist.my_addr = conn->clientConnection->local;
checklist.conn(conn);
+ ClientHttpRequest *http = context ? context->http : nullptr;
+ const char *log_uri = http ? http->log_uri : nullptr;
+ checklist.syncAle(request.getRaw(), log_uri);
allow_t answer = checklist.fastCheck();
if (answer.allowed() && answer.kind == 1) {
debugs(33, 3, "Request will be tunneled to server");
HTTPMSGUNLOCK(acl_checklist->al->request);
acl_checklist->al->request = request;
HTTPMSGLOCK(acl_checklist->al->request);
+ Http::StreamPointer context = pipeline.front();
+ ClientHttpRequest *http = context ? context->http : nullptr;
+ const char *log_uri = http ? http->log_uri : nullptr;
+ acl_checklist->syncAle(request, log_uri);
acl_checklist->nonBlockingCheck(httpsSslBumpAccessCheckDone, this);
#else
fatal("FATAL: SSL-Bump requires --with-openssl");
acl_checklist->banAction(allow_t(ACCESS_ALLOWED, Ssl::bumpNone));
acl_checklist->banAction(allow_t(ACCESS_ALLOWED, Ssl::bumpClientFirst));
acl_checklist->banAction(allow_t(ACCESS_ALLOWED, Ssl::bumpServerFirst));
+ const char *log_uri = http ? http->log_uri : nullptr;
+ acl_checklist->syncAle(sslServerBump->request.getRaw(), log_uri);
acl_checklist->nonBlockingCheck(httpsSslBumpStep2AccessCheckDone, this);
return;
}
ACLFilledChecklist *ch = new ACLFilledChecklist(acl, http->request,
cbdataReferenceValid(conn) && conn != NULL && conn->clientConnection != NULL ? conn->clientConnection->rfc931 : dash_str);
ch->al = http->al;
+ ch->syncAle(http->request, http->log_uri);
/*
* hack for ident ACL. It needs to get full addresses, and a place to store
* the ident result on persistent connections...
calloutContext->tosToClientDone = true;
if (getConn() != NULL && Comm::IsConnOpen(getConn()->clientConnection)) {
ACLFilledChecklist ch(NULL, request, NULL);
+ ch.al = calloutContext->http->al;
ch.src_addr = request->client_addr;
ch.my_addr = request->my_addr;
+ ch.syncAle(request, log_uri);
tos_t tos = aclMapTOS(Ip::Qos::TheConfig.tosToClient, &ch);
if (tos)
Ip::Qos::setSockTos(getConn()->clientConnection, tos);
calloutContext->nfmarkToClientDone = true;
if (getConn() != NULL && Comm::IsConnOpen(getConn()->clientConnection)) {
ACLFilledChecklist ch(NULL, request, NULL);
+ ch.al = calloutContext->http->al;
ch.src_addr = request->client_addr;
ch.my_addr = request->my_addr;
+ ch.syncAle(request, log_uri);
nfmark_t mark = aclMapNfmark(Ip::Qos::TheConfig.nfmarkToClient, &ch);
if (mark)
Ip::Qos::setSockNfmark(getConn()->clientConnection, mark);
ACLFilledChecklist ch(nullptr, nullptr, nullptr);
ch.src_addr = conn->remote;
ch.my_addr = conn->local;
+ ch.al = al;
accessLogLog(al, &ch);
}
// check whether the 1xx response forwarding is allowed by squid.conf
if (Config.accessList.reply) {
ACLFilledChecklist ch(Config.accessList.reply, originalRequest(), NULL);
+ ch.al = fwd->al;
ch.reply = reply;
+ ch.syncAle(originalRequest(), nullptr);
HTTPMSGLOCK(ch.reply);
if (!ch.fastCheck().allowed()) { // TODO: support slow lookups?
debugs(11, 3, HERE << "ignoring denied 1xx");
}
ACLFilledChecklist ch(Config.accessList.brokenPosts, originalRequest(), NULL);
+ ch.al = fwd->al;
+ ch.syncAle(originalRequest(), nullptr);
if (!ch.fastCheck().allowed()) {
debugs(11, 5, HERE << "didn't match brokenPosts");
return false;
bool
peerAllowedToUse(const CachePeer * p, HttpRequest * request)
{
-
assert(request != NULL);
if (neighborType(p, request->url) == PEER_SIBLING) {
return true;
ACLFilledChecklist checklist(p->access, request, NULL);
-
+// checklist.al = ps->al;
+ checklist.syncAle(request, nullptr);
return checklist.fastCheck().allowed();
}
if (acl_access *acl = ::Config.ssl_client.cert_error) {
ACLFilledChecklist *check = new ACLFilledChecklist(acl, request.getRaw(), dash_str);
check->al = al;
+ check->syncAle(request.getRaw(), nullptr);
// check->fd(fd); XXX: need client FD here
SSL_set_ex_data(serverSession.get(), ssl_ex_index_cert_error_check, check);
}
if (acl_access *acl = ::Config.ssl_client.cert_error) {
check = new ACLFilledChecklist(acl, request.getRaw(), dash_str);
check->al = al;
+ check->syncAle(request.getRaw(), nullptr);
}
Security::CertErrors *errs = nullptr;
acl_checklist->banAction(allow_t(ACCESS_ALLOWED, Ssl::bumpSplice));
if (!srvBio->canBump())
acl_checklist->banAction(allow_t(ACCESS_ALLOWED, Ssl::bumpBump));
+ acl_checklist->syncAle(request.getRaw(), nullptr);
acl_checklist->nonBlockingCheck(Ssl::PeekingPeerConnector::cbCheckForPeekAndSpliceDone, this);
}
* default is to allow.
*/
ACLFilledChecklist ch(Config.accessList.miss, request, NULL);
+ ch.al = http->al;
ch.src_addr = request->client_addr;
ch.my_addr = request->my_addr;
+ ch.syncAle(request, http->log_uri);
if (ch.fastCheck().denied()) {
debugs(26, 4, HERE << "MISS access forbidden.");
err = new ErrorState(ERR_FORWARDING_DENIED, Http::scForbidden, request);