2 * Copyright (C) 1996-2018 The Squid Software Foundation and contributors
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
10 #include "acl/FilledChecklist.h"
11 #include "client_side.h"
12 #include "comm/Connection.h"
13 #include "comm/forward.h"
14 #include "ExternalACLEntry.h"
15 #include "http/Stream.h"
16 #include "HttpReply.h"
17 #include "HttpRequest.h"
18 #include "SquidConfig.h"
20 #include "auth/AclProxyAuth.h"
21 #include "auth/UserRequest.h"
24 CBDATA_CLASS_INIT(ACLFilledChecklist
);
26 ACLFilledChecklist::ACLFilledChecklist() :
31 auth_user_request (NULL
),
39 requestErrorType(ERR_MAX
),
42 destinationDomainChecked_(false),
43 sourceDomainChecked_(false)
51 ACLFilledChecklist::~ACLFilledChecklist()
53 assert (!asyncInProgress());
55 safe_free(dst_rdns
); // created by xstrdup().
57 HTTPMSGUNLOCK(request
);
61 cbdataReferenceDone(conn_
);
64 cbdataReferenceDone(sslErrors
);
67 debugs(28, 4, HERE
<< "ACLFilledChecklist destroyed " << this);
71 showDebugWarning(const char *msg
)
73 static uint16_t count
= 0;
78 debugs(28, DBG_IMPORTANT
, "ALE missing " << msg
);
82 ACLFilledChecklist::verifyAle() const
84 // make sure the ALE fields used by Format::assemble to
85 // fill the old external_acl_type codes are set if any
86 // data on them exists in the Checklist
88 if (!al
->cache
.port
&& conn()) {
89 showDebugWarning("listening port");
90 al
->cache
.port
= conn()->port
;
95 showDebugWarning("HttpRequest object");
96 // XXX: al->request should be original,
97 // but the request may be already adapted
98 al
->request
= request
;
99 HTTPMSGLOCK(al
->request
);
102 if (!al
->adapted_request
) {
103 showDebugWarning("adapted HttpRequest object");
104 al
->adapted_request
= request
;
105 HTTPMSGLOCK(al
->adapted_request
);
108 if (al
->url
.isEmpty()) {
109 showDebugWarning("URL");
110 // XXX: al->url should be the request URL from client,
111 // but request->url may be different (e.g.,redirected)
112 al
->url
= request
->url
.absolute();
116 if (reply
&& !al
->reply
) {
117 showDebugWarning("HttpReply object");
119 HTTPMSGLOCK(al
->reply
);
123 if (*rfc931
&& !al
->cache
.rfc931
) {
124 showDebugWarning("IDENT");
125 al
->cache
.rfc931
= xstrdup(rfc931
);
131 ACLFilledChecklist::syncAle(HttpRequest
*adaptedRequest
, const char *logUri
) const
135 if (!al
->adapted_request
) {
136 al
->adapted_request
= adaptedRequest
;
137 HTTPMSGLOCK(al
->adapted_request
);
139 if (al
->url
.isEmpty())
144 ACLFilledChecklist::conn() const
146 return cbdataReferenceValid(conn_
) ? conn_
: nullptr;
150 ACLFilledChecklist::conn(ConnStateData
*aConn
)
154 assert (conn() == NULL
);
155 conn_
= cbdataReference(aConn
);
159 ACLFilledChecklist::fd() const
161 const auto c
= conn();
162 return (c
&& c
->clientConnection
) ? c
->clientConnection
->fd
: fd_
;
166 ACLFilledChecklist::fd(int aDescriptor
)
168 const auto c
= conn();
169 assert(!c
|| !c
->clientConnection
|| c
->clientConnection
->fd
== aDescriptor
);
174 ACLFilledChecklist::destinationDomainChecked() const
176 return destinationDomainChecked_
;
180 ACLFilledChecklist::markDestinationDomainChecked()
182 assert (!finished() && !destinationDomainChecked());
183 destinationDomainChecked_
= true;
187 ACLFilledChecklist::sourceDomainChecked() const
189 return sourceDomainChecked_
;
193 ACLFilledChecklist::markSourceDomainChecked()
195 assert (!finished() && !sourceDomainChecked());
196 sourceDomainChecked_
= true;
200 * There are two common ACLFilledChecklist lifecycles paths:
202 * A) Using aclCheckFast(): The caller creates an ACLFilledChecklist object
203 * on stack and calls aclCheckFast().
205 * B) Using aclNBCheck() and callbacks: The caller allocates an
206 * ACLFilledChecklist object (via operator new) and passes it to
207 * aclNBCheck(). Control eventually passes to ACLChecklist::checkCallback(),
208 * which will invoke the callback function as requested by the
209 * original caller of aclNBCheck(). This callback function must
210 * *not* delete the list. After the callback function returns,
211 * checkCallback() will delete the list (i.e., self).
213 ACLFilledChecklist::ACLFilledChecklist(const acl_access
*A
, HttpRequest
*http_request
, const char *ident
):
218 auth_user_request(NULL
),
221 snmp_community(NULL
),
226 requestErrorType(ERR_MAX
),
229 destinationDomainChecked_(false),
230 sourceDomainChecked_(false)
238 setRequest(http_request
);
242 void ACLFilledChecklist::setRequest(HttpRequest
*httpRequest
)
246 request
= httpRequest
;
247 HTTPMSGLOCK(request
);
248 #if FOLLOW_X_FORWARDED_FOR
249 if (Config
.onoff
.acl_uses_indirect_client
)
250 src_addr
= request
->indirect_client_addr
;
252 #endif /* FOLLOW_X_FORWARDED_FOR */
253 src_addr
= request
->client_addr
;
254 my_addr
= request
->my_addr
;
256 if (request
->clientConnectionManager
.valid())
257 conn(request
->clientConnectionManager
.get());
262 ACLFilledChecklist::setIdent(const char *ident
)
267 xstrncpy(rfc931
, ident
, USER_IDENT_SZ
);