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