]> git.ipfire.org Git - thirdparty/squid.git/blame - src/auth/UserRequest.cc
Docs: Copyright updates for 2018 (#114)
[thirdparty/squid.git] / src / auth / UserRequest.cc
CommitLineData
f5691f9c 1/*
5b74111a 2 * Copyright (C) 1996-2018 The Squid Software Foundation and contributors
f5691f9c 3 *
bbc27441
AJ
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.
f5691f9c 7 */
8
bbc27441
AJ
9/* DEBUG: section 29 Authenticator */
10
f5691f9c 11/* The functions in this file handle authentication.
12 * They DO NOT perform access control or auditing.
13 * See acl.c for access control and client_side.c for auditing */
14
582c2af2 15#include "squid.h"
5bfc3dbd 16#include "acl/FilledChecklist.h"
5c112575 17#include "auth/Config.h"
582c2af2 18#include "client_side.h"
5c336a3b 19#include "comm/Connection.h"
ed6e9fb9 20#include "fatal.h"
86c63190 21#include "format/Format.h"
6f9a30f8
EB
22#include "helper.h"
23#include "helper/Reply.h"
d3dddfb5 24#include "http/Stream.h"
f5691f9c 25#include "HttpReply.h"
26#include "HttpRequest.h"
d4806c91 27#include "MemBuf.h"
f5691f9c 28
29/* Generic Functions */
30
f5691f9c 31char const *
c7baff40 32Auth::UserRequest::username() const
f5691f9c 33{
56a49fda 34 if (user() != NULL)
f5691f9c 35 return user()->username();
36 else
37 return NULL;
38}
39
f5691f9c 40/**** PUBLIC FUNCTIONS (ALL GENERIC!) ****/
41
42/* send the initial data to an authenticator module */
43void
d4806c91 44Auth::UserRequest::start(HttpRequest *request, AccessLogEntry::Pointer &al, AUTHCB * handler, void *data)
f5691f9c 45{
46 assert(handler);
a088a999 47 assert(data);
30c3f584
AJ
48 debugs(29, 9, this);
49 startHelperLookup(request, al, handler, data);
f5691f9c 50}
51
2e39494f 52bool
c7baff40 53Auth::UserRequest::valid() const
f5691f9c 54{
c7baff40 55 debugs(29, 9, HERE << "Validating Auth::UserRequest '" << this << "'.");
f5691f9c 56
2e39494f 57 if (user() == NULL) {
d87154ee 58 debugs(29, 4, HERE << "No associated Auth::User data");
0a608df9 59 return false;
f5691f9c 60 }
61
616cfc4c 62 if (user()->auth_type == Auth::AUTH_UNKNOWN) {
d87154ee 63 debugs(29, 4, HERE << "Auth::User '" << user() << "' uses unknown scheme.");
2e39494f 64 return false;
f5691f9c 65 }
66
616cfc4c 67 if (user()->auth_type == Auth::AUTH_BROKEN) {
d87154ee 68 debugs(29, 4, HERE << "Auth::User '" << user() << "' is broken for it's scheme.");
2e39494f 69 return false;
f5691f9c 70 }
71
72 /* any other sanity checks that we need in the future */
73
f5691f9c 74 /* finally return ok */
c7baff40 75 debugs(29, 5, HERE << "Validated. Auth::UserRequest '" << this << "'.");
2e39494f 76 return true;
f5691f9c 77}
78
79void *
ced8def3 80Auth::UserRequest::operator new (size_t)
f5691f9c 81{
c7baff40 82 fatal("Auth::UserRequest not directly allocatable\n");
f5691f9c 83 return (void *)1;
84}
85
86void
ced8def3 87Auth::UserRequest::operator delete (void *)
f5691f9c 88{
c7baff40 89 fatal("Auth::UserRequest child failed to override operator delete\n");
f5691f9c 90}
91
c7baff40 92Auth::UserRequest::UserRequest():
f53969cc
SM
93 _auth_user(NULL),
94 message(NULL),
95 lastReply(AUTH_ACL_CANNOT_AUTHENTICATE)
f5691f9c 96{
c7baff40 97 debugs(29, 5, HERE << "initialised request " << this);
f5691f9c 98}
99
c7baff40 100Auth::UserRequest::~UserRequest()
f5691f9c 101{
8bf217bd 102 assert(LockCount()==0);
c7baff40 103 debugs(29, 5, HERE << "freeing request " << this);
f5691f9c 104
56a49fda 105 if (user() != NULL) {
56a49fda 106 /* release our references to the user credentials */
f5691f9c 107 user(NULL);
108 }
109
56a49fda 110 safe_free(message);
f5691f9c 111}
112
113void
c7baff40 114Auth::UserRequest::setDenyMessage(char const *aString)
f5691f9c 115{
56a49fda
AJ
116 safe_free(message);
117 message = xstrdup(aString);
f5691f9c 118}
119
120char const *
6f9a30f8 121Auth::UserRequest::getDenyMessage() const
f5691f9c 122{
123 return message;
124}
125
126char const *
6f9a30f8 127Auth::UserRequest::denyMessage(char const * const default_message) const
f5691f9c 128{
328a07ab 129 if (getDenyMessage() == NULL)
f5691f9c 130 return default_message;
f5691f9c 131
132 return getDenyMessage();
133}
134
135static void
c7baff40 136authenticateAuthUserRequestSetIp(Auth::UserRequest::Pointer auth_user_request, Ip::Address &ipaddr)
f5691f9c 137{
d87154ee 138 Auth::User::Pointer auth_user = auth_user_request->user();
f5691f9c 139
4c19ba24 140 if (!auth_user)
f5691f9c 141 return;
142
4c19ba24 143 auth_user->addIp(ipaddr);
f5691f9c 144}
145
146void
c7baff40 147authenticateAuthUserRequestRemoveIp(Auth::UserRequest::Pointer auth_user_request, Ip::Address const &ipaddr)
f5691f9c 148{
d87154ee 149 Auth::User::Pointer auth_user = auth_user_request->user();
f5691f9c 150
4c19ba24 151 if (!auth_user)
f5691f9c 152 return;
153
4c19ba24 154 auth_user->removeIp(ipaddr);
f5691f9c 155}
156
157void
c7baff40 158authenticateAuthUserRequestClearIp(Auth::UserRequest::Pointer auth_user_request)
f5691f9c 159{
a33a428a 160 if (auth_user_request != NULL)
f5691f9c 161 auth_user_request->user()->clearIp();
162}
163
4b0f5de8 164int
c7baff40 165authenticateAuthUserRequestIPCount(Auth::UserRequest::Pointer auth_user_request)
f5691f9c 166{
a33a428a 167 assert(auth_user_request != NULL);
56a49fda 168 assert(auth_user_request->user() != NULL);
f5691f9c 169 return auth_user_request->user()->ipcount;
170}
171
f5691f9c 172/*
173 * authenticateUserAuthenticated: is this auth_user structure logged in ?
174 */
175int
c7baff40 176authenticateUserAuthenticated(Auth::UserRequest::Pointer auth_user_request)
f5691f9c 177{
0a608df9 178 if (auth_user_request == NULL || !auth_user_request->valid())
f5691f9c 179 return 0;
180
181 return auth_user_request->authenticated();
182}
183
51a3dd58 184Auth::Direction
c7baff40 185Auth::UserRequest::direction()
f5691f9c 186{
51a3dd58
AJ
187 if (user() == NULL)
188 return Auth::CRED_ERROR; // No credentials. Should this be a CHALLENGE instead?
189
f5691f9c 190 if (authenticateUserAuthenticated(this))
51a3dd58 191 return Auth::CRED_VALID;
f5691f9c 192
193 return module_direction();
f5691f9c 194}
195
196void
ced8def3 197Auth::UserRequest::addAuthenticationInfoHeader(HttpReply *, int)
f5691f9c 198{}
199
200void
ced8def3 201Auth::UserRequest::addAuthenticationInfoTrailer(HttpReply *, int)
f5691f9c 202{}
203
204void
cc1e110a 205Auth::UserRequest::releaseAuthServer()
f5691f9c 206{}
207
208const char *
c7baff40 209Auth::UserRequest::connLastHeader()
f5691f9c 210{
c7baff40 211 fatal("Auth::UserRequest::connLastHeader should always be overridden by conn based auth schemes");
f5691f9c 212 return NULL;
213}
214
215/*
26ac0430 216 * authenticateAuthenticateUser: call the module specific code to
f5691f9c 217 * log this user request in.
218 * Cache hits may change the auth_user pointer in the structure if needed.
219 * This is basically a handle approach.
220 */
221static void
789217a2 222authenticateAuthenticateUser(Auth::UserRequest::Pointer auth_user_request, HttpRequest * request, ConnStateData * conn, Http::HdrType type)
f5691f9c 223{
a33a428a 224 assert(auth_user_request.getRaw() != NULL);
f5691f9c 225
226 auth_user_request->authenticate(request, conn, type);
227}
228
c7baff40
AJ
229static Auth::UserRequest::Pointer
230authTryGetUser(Auth::UserRequest::Pointer auth_user_request, ConnStateData * conn, HttpRequest * request)
f5691f9c 231{
71e7400c
AJ
232 Auth::UserRequest::Pointer res;
233
a33a428a 234 if (auth_user_request != NULL)
71e7400c 235 res = auth_user_request;
a33a428a 236 else if (request != NULL && request->auth_user_request != NULL)
71e7400c 237 res = request->auth_user_request;
4d3a24ca 238 else if (conn != NULL)
71e7400c
AJ
239 res = conn->getAuth();
240
241 // attach the credential notes from helper to the transaction
389b88c3 242 if (request != NULL && res != NULL && res->user() != NULL) {
71e7400c
AJ
243 // XXX: we have no access to the transaction / AccessLogEntry so cant SyncNotes().
244 // workaround by using anything already set in HttpRequest
245 // OR use new and rely on a later Sync copying these to AccessLogEntry
71e7400c 246
457857fe 247 UpdateRequestNotes(conn, *request, res->user()->notes);
71e7400c
AJ
248 }
249
250 return res;
f5691f9c 251}
252
253/* returns one of
254 * AUTH_ACL_CHALLENGE,
255 * AUTH_ACL_HELPER,
256 * AUTH_ACL_CANNOT_AUTHENTICATE,
257 * AUTH_AUTHENTICATED
258 *
26ac0430 259 * How to use: In your proxy-auth dependent acl code, use the following
f5691f9c 260 * construct:
261 * int rv;
262 * if ((rv = AuthenticateAuthenticate()) != AUTH_AUTHENTICATED)
263 * return rv;
26ac0430 264 *
f5691f9c 265 * when this code is reached, the request/connection is authenticated.
266 *
26ac0430 267 * if you have non-acl code, but want to force authentication, you need a
f5691f9c 268 * callback mechanism like the acl testing routines that will send a 40[1|7] to
26ac0430 269 * the client when rv==AUTH_ACL_CHALLENGE, and will communicate with
f5691f9c 270 * the authenticateStart routine for rv==AUTH_ACL_HELPER
4f0ef8e8 271 *
272 * Caller is responsible for locking and unlocking their *auth_user_request!
f5691f9c 273 */
56a49fda 274AuthAclState
789217a2 275Auth::UserRequest::authenticate(Auth::UserRequest::Pointer * auth_user_request, Http::HdrType headertype, HttpRequest * request, ConnStateData * conn, Ip::Address &src_addr, AccessLogEntry::Pointer &al)
f5691f9c 276{
277 const char *proxy_auth;
278 assert(headertype != 0);
279
a9925b40 280 proxy_auth = request->header.getStr(headertype);
f5691f9c 281
282 /*
283 * a note on proxy_auth logix here:
284 * proxy_auth==NULL -> unauthenticated request || already
285 * authenticated connection so we test for an authenticated
286 * connection when we recieve no authentication header.
287 */
288
a1ce83aa
AJ
289 /* a) can we find other credentials to use? and b) are they logged in already? */
290 if (proxy_auth == NULL && !authenticateUserAuthenticated(authTryGetUser(*auth_user_request,conn,request))) {
f5691f9c 291 /* no header or authentication failed/got corrupted - restart */
a1ce83aa
AJ
292 debugs(29, 4, HERE << "No Proxy-Auth header and no working alternative. Requesting auth header.");
293
f5691f9c 294 /* something wrong with the AUTH credentials. Force a new attempt */
295
a1ce83aa 296 /* connection auth we must reset on auth errors */
4d3a24ca 297 if (conn != NULL) {
cc1e110a 298 conn->setAuth(NULL, "HTTP request missing credentials");
f5691f9c 299 }
300
26ac0430 301 *auth_user_request = NULL;
f5691f9c 302 return AUTH_ACL_CHALLENGE;
303 }
304
305 /*
306 * Is this an already authenticated connection with a new auth header?
26ac0430 307 * No check for function required in the if: its compulsory for conn based
f5691f9c 308 * auth modules
309 */
cc1e110a
AJ
310 if (proxy_auth && conn != NULL && conn->getAuth() != NULL &&
311 authenticateUserAuthenticated(conn->getAuth()) &&
312 conn->getAuth()->connLastHeader() != NULL &&
313 strcmp(proxy_auth, conn->getAuth()->connLastHeader())) {
a1ce83aa 314 debugs(29, 2, "WARNING: DUPLICATE AUTH - authentication header on already authenticated connection!. AU " <<
cc1e110a
AJ
315 conn->getAuth() << ", Current user '" <<
316 conn->getAuth()->username() << "' proxy_auth " <<
bf8fe701 317 proxy_auth);
318
a1ce83aa 319 /* remove this request struct - the link is already authed and it can't be to reauth. */
f5691f9c 320
321 /* This should _only_ ever occur on the first pass through
26ac0430 322 * authenticateAuthenticate
f5691f9c 323 */
324 assert(*auth_user_request == NULL);
cc1e110a 325 conn->setAuth(NULL, "changed credentials token");
f5691f9c 326 }
327
328 /* we have a proxy auth header and as far as we know this connection has
329 * not had bungled connection oriented authentication happen on it. */
a1ce83aa 330 debugs(29, 9, HERE << "header " << (proxy_auth ? proxy_auth : "-") << ".");
f5691f9c 331
26ac0430 332 if (*auth_user_request == NULL) {
5c336a3b 333 if (conn != NULL) {
73c36fd9 334 debugs(29, 9, HERE << "This is a new checklist test on:" << conn->clientConnection);
5c336a3b 335 }
f5691f9c 336
cc1e110a 337 if (proxy_auth && request->auth_user_request == NULL && conn != NULL && conn->getAuth() != NULL) {
dc79fed8 338 Auth::SchemeConfig * scheme = Auth::SchemeConfig::Find(proxy_auth);
638b2ce3 339
cc1e110a 340 if (conn->getAuth()->user() == NULL || conn->getAuth()->user()->config != scheme) {
c7baff40 341 debugs(29, DBG_IMPORTANT, "WARNING: Unexpected change of authentication scheme from '" <<
cc1e110a 342 (conn->getAuth()->user()!=NULL?conn->getAuth()->user()->config->type():"[no user]") <<
bf8fe701 343 "' to '" << proxy_auth << "' (client " <<
cc192b50 344 src_addr << ")");
bf8fe701 345
cc1e110a 346 conn->setAuth(NULL, "changed auth scheme");
638b2ce3 347 }
348 }
349
cc1e110a 350 if (request->auth_user_request == NULL && (conn == NULL || conn->getAuth() == NULL)) {
f5691f9c 351 /* beginning of a new request check */
a1ce83aa 352 debugs(29, 4, HERE << "No connection authentication type");
f5691f9c 353
dc79fed8 354 *auth_user_request = Auth::SchemeConfig::CreateAuthUser(proxy_auth, al);
0a608df9
AJ
355 if (*auth_user_request == NULL)
356 return AUTH_ACL_CHALLENGE;
357 else if (!(*auth_user_request)->valid()) {
f5691f9c 358 /* the decode might have left a username for logging, or a message to
359 * the user */
360
361 if ((*auth_user_request)->username()) {
f5691f9c 362 request->auth_user_request = *auth_user_request;
363 }
364
f5691f9c 365 *auth_user_request = NULL;
f5691f9c 366 return AUTH_ACL_CHALLENGE;
367 }
368
a33a428a 369 } else if (request->auth_user_request != NULL) {
f5691f9c 370 *auth_user_request = request->auth_user_request;
f5691f9c 371 } else {
4d3a24ca 372 assert (conn != NULL);
cc1e110a
AJ
373 if (conn->getAuth() != NULL) {
374 *auth_user_request = conn->getAuth();
f5691f9c 375 } else {
376 /* failed connection based authentication */
cc1e110a 377 debugs(29, 4, HERE << "Auth user request " << *auth_user_request << " conn-auth missing and failed to authenticate.");
f5691f9c 378 *auth_user_request = NULL;
379 return AUTH_ACL_CHALLENGE;
380 }
381 }
382 }
383
26ac0430 384 if (!authenticateUserAuthenticated(*auth_user_request)) {
51a3dd58 385 /* User not logged in. Try to log them in */
a33a428a 386 authenticateAuthenticateUser(*auth_user_request, request, conn, headertype);
f5691f9c 387
51a3dd58 388 switch ((*auth_user_request)->direction()) {
f5691f9c 389
51a3dd58 390 case Auth::CRED_CHALLENGE:
f5691f9c 391
a33a428a 392 if (request->auth_user_request == NULL) {
f5691f9c 393 request->auth_user_request = *auth_user_request;
394 }
395
f53969cc 396 /* fallthrough to ERROR case and do the challenge */
f5691f9c 397
51a3dd58 398 case Auth::CRED_ERROR:
4f0ef8e8 399 /* this ACL check is finished. */
f5691f9c 400 *auth_user_request = NULL;
f5691f9c 401 return AUTH_ACL_CHALLENGE;
402
51a3dd58 403 case Auth::CRED_LOOKUP:
f5691f9c 404 /* we are partway through authentication within squid,
405 * the *auth_user_request variables stores the auth_user_request
406 * for the callback to here - Do not Unlock */
407 return AUTH_ACL_HELPER;
f5691f9c 408
51a3dd58
AJ
409 case Auth::CRED_VALID:
410 /* authentication is finished */
411 /* See if user authentication failed for some reason */
412 if (!authenticateUserAuthenticated(*auth_user_request)) {
413 if ((*auth_user_request)->username()) {
414 if (!request->auth_user_request) {
415 request->auth_user_request = *auth_user_request;
416 }
f5691f9c 417 }
f5691f9c 418
51a3dd58
AJ
419 *auth_user_request = NULL;
420 return AUTH_ACL_CHALLENGE;
421 }
422 // otherwise fallthrough to acceptance.
f5691f9c 423 }
424 }
425
426 /* copy username to request for logging on client-side */
427 /* the credentials are correct at this point */
a33a428a 428 if (request->auth_user_request == NULL) {
f5691f9c 429 request->auth_user_request = *auth_user_request;
f5691f9c 430 authenticateAuthUserRequestSetIp(*auth_user_request, src_addr);
431 }
432
f5691f9c 433 return AUTH_AUTHENTICATED;
434}
435
56a49fda 436AuthAclState
789217a2 437Auth::UserRequest::tryToAuthenticateAndSetAuthUser(Auth::UserRequest::Pointer * aUR, Http::HdrType headertype, HttpRequest * request, ConnStateData * conn, Ip::Address &src_addr, AccessLogEntry::Pointer &al)
f5691f9c 438{
c7baff40
AJ
439 // If we have already been called, return the cached value
440 Auth::UserRequest::Pointer t = authTryGetUser(*aUR, conn, request);
f5691f9c 441
a33a428a 442 if (t != NULL && t->lastReply != AUTH_ACL_CANNOT_AUTHENTICATE && t->lastReply != AUTH_ACL_HELPER) {
c7baff40
AJ
443 if (*aUR == NULL)
444 *aUR = t;
f5691f9c 445
a33a428a 446 if (request->auth_user_request == NULL && t->lastReply == AUTH_AUTHENTICATED) {
26ac0430 447 request->auth_user_request = t;
26ac0430 448 }
f5691f9c 449 return t->lastReply;
450 }
451
c7baff40 452 // ok, call the actual authenticator routine.
d4806c91 453 AuthAclState result = authenticate(aUR, headertype, request, conn, src_addr, al);
f5691f9c 454
c7baff40
AJ
455 // auth process may have changed the UserRequest we are dealing with
456 t = authTryGetUser(*aUR, conn, request);
f5691f9c 457
a33a428a 458 if (t != NULL && result != AUTH_ACL_CANNOT_AUTHENTICATE && result != AUTH_ACL_HELPER)
f5691f9c 459 t->lastReply = result;
460
461 return result;
462}
463
5bfc3dbd
EB
464static Auth::ConfigVector &
465schemesConfig(HttpRequest *request, HttpReply *rep)
466{
d6e94bda 467 if (!Auth::TheConfig.schemeLists.empty() && Auth::TheConfig.schemeAccess) {
5bfc3dbd
EB
468 ACLFilledChecklist ch(NULL, request, NULL);
469 ch.reply = rep;
470 HTTPMSGLOCK(ch.reply);
d6e94bda 471 const allow_t answer = ch.fastCheck(Auth::TheConfig.schemeAccess);
06bf5384 472 if (answer.allowed())
d6e94bda 473 return Auth::TheConfig.schemeLists.at(answer.kind).authConfigs;
5bfc3dbd 474 }
5c112575 475 return Auth::TheConfig.schemes;
5bfc3dbd
EB
476}
477
f5691f9c 478void
923a8d89 479Auth::UserRequest::AddReplyAuthHeader(HttpReply * rep, Auth::UserRequest::Pointer auth_user_request, HttpRequest * request, int accelerated, int internal)
f5691f9c 480/* send the auth types we are configured to support (and have compiled in!) */
481{
789217a2 482 Http::HdrType type;
f5691f9c 483
9b769c67 484 switch (rep->sline.status()) {
f5691f9c 485
955394ce 486 case Http::scProxyAuthenticationRequired:
f5691f9c 487 /* Proxy authorisation needed */
789217a2 488 type = Http::HdrType::PROXY_AUTHENTICATE;
f5691f9c 489 break;
490
955394ce 491 case Http::scUnauthorized:
f5691f9c 492 /* WWW Authorisation needed */
789217a2 493 type = Http::HdrType::WWW_AUTHENTICATE;
f5691f9c 494 break;
495
496 default:
497 /* Keep GCC happy */
498 /* some other HTTP status */
81ab22b6 499 type = Http::HdrType::BAD_HDR;
f5691f9c 500 break;
501 }
502
81ab22b6 503 debugs(29, 9, "headertype:" << type << " authuser:" << auth_user_request);
f5691f9c 504
9b769c67
AJ
505 if (((rep->sline.status() == Http::scProxyAuthenticationRequired)
506 || (rep->sline.status() == Http::scUnauthorized)) && internal)
f5691f9c 507 /* this is a authenticate-needed response */
508 {
509
51a3dd58
AJ
510 if (auth_user_request != NULL && auth_user_request->direction() == Auth::CRED_CHALLENGE)
511 /* add the scheme specific challenge header to the response */
f5691f9c 512 auth_user_request->user()->config->fixHeader(auth_user_request, rep, type, request);
26ac0430 513 else {
dc79fed8 514 /* call each configured & running auth scheme */
5bfc3dbd 515 Auth::ConfigVector &configs = schemesConfig(request, rep);
dc79fed8 516 for (auto *scheme : configs) {
34401cfb
HN
517 if (scheme->active()) {
518 if (auth_user_request != NULL && auth_user_request->scheme()->type() == scheme->type())
519 scheme->fixHeader(auth_user_request, rep, type, request);
520 else
521 scheme->fixHeader(NULL, rep, type, request);
522 } else
c7baff40 523 debugs(29, 4, HERE << "Configured scheme " << scheme->type() << " not Active");
f5691f9c 524 }
525 }
526
527 }
7afc3bf2 528
f5691f9c 529 /*
530 * allow protocol specific headers to be _added_ to the existing
7afc3bf2 531 * response - currently Digest or Negotiate auth
f5691f9c 532 */
26ac0430 533 if (auth_user_request != NULL) {
7afc3bf2 534 auth_user_request->addAuthenticationInfoHeader(rep, accelerated);
26ac0430
AJ
535 if (auth_user_request->lastReply != AUTH_AUTHENTICATED)
536 auth_user_request->lastReply = AUTH_ACL_CANNOT_AUTHENTICATE;
f5691f9c 537 }
538}
539
c6cf8dee 540Auth::Scheme::Pointer
c7baff40 541Auth::UserRequest::scheme() const
f5691f9c 542{
c6cf8dee 543 return Auth::Scheme::Find(user()->config->type());
f5691f9c 544}
d4806c91
CT
545
546const char *
547Auth::UserRequest::helperRequestKeyExtras(HttpRequest *request, AccessLogEntry::Pointer &al)
548{
549 if (Format::Format *reqFmt = user()->config->keyExtras) {
550 static MemBuf mb;
551 mb.reset();
552 // We should pass AccessLogEntry as second argument ....
553 Auth::UserRequest::Pointer oldReq = request->auth_user_request;
554 request->auth_user_request = this;
555 reqFmt->assemble(mb, al, 0);
556 request->auth_user_request = oldReq;
557 debugs(29, 5, "Assembled line to send :" << mb.content());
558 return mb.content();
559 }
560 return NULL;
561}
f53969cc 562
6f9a30f8
EB
563void
564Auth::UserRequest::denyMessageFromHelper(const char *proto, const Helper::Reply &reply)
565{
566 static SBuf messageNote;
567 if (!reply.notes.find(messageNote, "message")) {
568 messageNote.append(proto);
569 messageNote.append(" Authentication denied with no reason given");
570 }
571 setDenyMessage(messageNote.c_str());
572}
573