]> git.ipfire.org Git - thirdparty/squid.git/blame - src/auth/basic/auth_basic.cc
Bug #1258: LDAP helpers fails to compile with SUN LDAP SDK
[thirdparty/squid.git] / src / auth / basic / auth_basic.cc
CommitLineData
94439e4e 1/*
411c6ea3 2 * $Id: auth_basic.cc,v 1.36 2005/01/06 13:16:39 serassio Exp $
94439e4e 3 *
4 * DEBUG: section 29 Authenticator
5 * AUTHOR: Duane Wessels
6 *
2b6662ba 7 * SQUID Web Proxy Cache http://www.squid-cache.org/
94439e4e 8 * ----------------------------------------------------------
9 *
2b6662ba 10 * Squid is the result of efforts by numerous individuals from
11 * the Internet community; see the CONTRIBUTORS file for full
12 * details. Many organizations have provided support for Squid's
13 * development; see the SPONSORS file for full details. Squid is
14 * Copyrighted (C) 2001 by the Regents of the University of
15 * California; see the COPYRIGHT file for full details. Squid
16 * incorporates software developed and/or copyrighted by other
17 * sources; see the CREDITS file for full details.
94439e4e 18 *
19 * This program is free software; you can redistribute it and/or modify
20 * it under the terms of the GNU General Public License as published by
21 * the Free Software Foundation; either version 2 of the License, or
22 * (at your option) any later version.
23 *
24 * This program is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU General Public License for more details.
28 *
29 * You should have received a copy of the GNU General Public License
30 * along with this program; if not, write to the Free Software
31 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
32 *
33 */
34
35/* The functions in this file handle authentication.
36 * They DO NOT perform access control or auditing.
37 * See acl.c for access control and client_side.c for auditing */
38
39
40#include "squid.h"
41#include "auth_basic.h"
e6ccf245 42#include "authenticate.h"
43#include "Store.h"
924f73bc 44#include "HttpReply.h"
f5691f9c 45#include "basicScheme.h"
94439e4e 46
47static void
e6ccf245 48authenticateStateFree(AuthenticateStateData * r)
94439e4e 49{
50 cbdataFree(r);
51}
52
53/* Basic Scheme */
54
55static HLPCB authenticateBasicHandleReply;
94439e4e 56static AUTHSSTATS authenticateBasicStats;
94439e4e 57
58static helper *basicauthenticators = NULL;
59
f5691f9c 60static AuthBasicConfig basicConfig;
94439e4e 61
62static int authbasic_initialised = 0;
94439e4e 63
2d72d4fd 64
94439e4e 65/*
66 *
2d72d4fd 67 * Public Functions
94439e4e 68 *
69 */
70
2d72d4fd 71/* internal functions */
72
f5691f9c 73/* TODO: move to basicScheme.cc - after all per request and user functions are moved out */
74void
75basicScheme::done()
2d72d4fd 76{
f5691f9c 77 /* TODO: this should be a Config call. */
78
2d72d4fd 79 if (basicauthenticators)
62e76326 80 helperShutdown(basicauthenticators);
81
2d72d4fd 82 authbasic_initialised = 0;
62e76326 83
2d72d4fd 84 if (!shutting_down)
62e76326 85 return;
86
2d72d4fd 87 if (basicauthenticators)
62e76326 88 helperFree(basicauthenticators);
89
2d72d4fd 90 basicauthenticators = NULL;
62e76326 91
f5691f9c 92 /* XXX Reinstate auth shutdown for dynamic schemes? */
2d72d4fd 93 debug(29, 2) ("authBasicDone: Basic authentication Shutdown.\n");
94}
95
f5691f9c 96bool
97AuthBasicConfig::active() const
2d70df72 98{
f5691f9c 99 return authbasic_initialised == 1;
2d70df72 100}
101
f5691f9c 102bool
103AuthBasicConfig::configured() const
94439e4e 104{
f5691f9c 105 if ((authenticate != NULL) && (authenticateChildren != 0) &&
106 (basicAuthRealm != NULL)) {
62e76326 107 debug(29, 9) ("authBasicConfigured: returning configured\n");
f5691f9c 108 return true;
2d70df72 109 }
62e76326 110
2d70df72 111 debug(29, 9) ("authBasicConfigured: returning unconfigured\n");
f5691f9c 112 return false;
94439e4e 113}
114
f5691f9c 115const char *
116AuthBasicConfig::type() const
94439e4e 117{
f5691f9c 118 return basicScheme::GetInstance().type();
119}
62e76326 120
f5691f9c 121AuthBasicUserRequest::AuthBasicUserRequest() : _theUser(NULL)
122{}
123
124AuthBasicUserRequest::~AuthBasicUserRequest()
125{}
126
127
128bool
129BasicUser::authenticated() const
94439e4e 130{
f5691f9c 131 if ((flags.credentials_ok == 1) && (credentials_checkedtime + basicConfig.credentialsTTL > squid_curtime))
132 return true;
133
134 debug(29, 4) ("User not authenticated or credentials need rechecking.\n");
135
136 return false;
94439e4e 137}
62e76326 138
f5691f9c 139int
140AuthBasicUserRequest::authenticated() const
141{
142 BasicUser const *basic_auth = dynamic_cast<BasicUser const *>(user());
143 assert (user());
144
145 if (basic_auth->authenticated())
146 return 1;
147
148 return 0;
149}
94439e4e 150
151/* log a basic user in
152 */
f5691f9c 153void
154AuthBasicUserRequest::authenticate(HttpRequest * request, ConnStateData::Pointer conn, http_hdr_type type)
94439e4e 155{
f5691f9c 156 assert(user() != NULL);
94439e4e 157
f5691f9c 158 basic_data *basic_auth = dynamic_cast<BasicUser *>(user());
9bea1d5b 159
bd507204 160 /* if the password is not ok, do an identity */
62e76326 161
bd507204 162 if (basic_auth->flags.credentials_ok != 1)
62e76326 163 return;
94439e4e 164
165 /* are we about to recheck the credentials externally? */
f5691f9c 166 if ((basic_auth->credentials_checkedtime + basicConfig.credentialsTTL) <= squid_curtime) {
62e76326 167 debug(29, 4) ("authBasicAuthenticate: credentials expired - rechecking\n");
168 return;
94439e4e 169 }
62e76326 170
94439e4e 171 /* we have been through the external helper, and the credentials haven't expired */
172 debug(29, 9) ("authenticateBasicAuthenticateuser: user '%s' authenticated\n",
f5691f9c 173 basic_auth->username());
94439e4e 174
f5691f9c 175 /* Decode now takes care of finding the AuthUser struct in the cache */
94439e4e 176 /* after external auth occurs anyway */
f5691f9c 177 basic_auth->expiretime = current_time.tv_sec;
62e76326 178
94439e4e 179 return;
180}
181
182int
f5691f9c 183AuthBasicUserRequest::module_direction()
94439e4e 184{
62e76326 185 /* null auth_user is checked for by authenticateDirection */
f5691f9c 186 basic_data *basic_auth = dynamic_cast<BasicUser *>(user());
187 assert (basic_auth);
62e76326 188
bd507204 189 switch (basic_auth->flags.credentials_ok) {
62e76326 190
94439e4e 191 case 0: /* not checked */
62e76326 192 return -1;
193
94439e4e 194 case 1: /* checked & ok */
62e76326 195
f5691f9c 196 if (basic_auth->credentials_checkedtime + basicConfig.credentialsTTL <= squid_curtime)
62e76326 197 return -1;
198
199 return 0;
200
94439e4e 201 case 2: /* paused while waiting for a username:password check on another request */
62e76326 202 return -1;
203
94439e4e 204 case 3: /* authentication process failed. */
88d3f890 205 return 0;
94439e4e 206 }
62e76326 207
94439e4e 208 return -2;
209}
210
211void
f5691f9c 212AuthBasicConfig::fixHeader(auth_user_request_t *auth_user_request, HttpReply *rep, http_hdr_type type, HttpRequest * request)
94439e4e 213{
f5691f9c 214 if (authenticate) {
215 debug(29, 9) ("authenticateFixErrorHeader: Sending type:%d header: 'Basic realm=\"%s\"'\n", type, basicAuthRealm);
216 httpHeaderPutStrf(&rep->header, type, "Basic realm=\"%s\"", basicAuthRealm);
94439e4e 217 }
218}
219
220/* free any allocated configuration details */
221void
f5691f9c 222AuthBasicConfig::done()
94439e4e 223{
f5691f9c 224 if (authenticate)
225 wordlistDestroy(&authenticate);
62e76326 226
f5691f9c 227 if (basicAuthRealm)
228 safe_free(basicAuthRealm);
94439e4e 229}
230
f5691f9c 231BasicUser::~BasicUser()
94439e4e 232{
f5691f9c 233 if (passwd)
234 xfree(passwd);
62e76326 235
f5691f9c 236 safe_free (cleartext);
94439e4e 237}
238
239static void
240authenticateBasicHandleReply(void *data, char *reply)
241{
e6ccf245 242 AuthenticateStateData *r = static_cast<AuthenticateStateData *>(data);
e6ccf245 243 BasicAuthQueueNode *tmpnode;
94439e4e 244 char *t = NULL;
fa80a8ef 245 void *cbdata;
94439e4e 246 debug(29, 9) ("authenticateBasicHandleReply: {%s}\n", reply ? reply : "<NULL>");
62e76326 247
94439e4e 248 if (reply) {
62e76326 249 if ((t = strchr(reply, ' ')))
250 *t = '\0';
251
252 if (*reply == '\0')
253 reply = NULL;
94439e4e 254 }
62e76326 255
94439e4e 256 assert(r->auth_user_request != NULL);
f5691f9c 257 assert(r->auth_user_request->user()->auth_type == AUTH_BASIC);
258 basic_data *basic_auth = dynamic_cast<basic_data *>(r->auth_user_request->user());
62e76326 259
94439e4e 260 if (reply && (strncasecmp(reply, "OK", 2) == 0))
62e76326 261 basic_auth->flags.credentials_ok = 1;
94439e4e 262 else
62e76326 263 basic_auth->flags.credentials_ok = 3;
264
94439e4e 265 basic_auth->credentials_checkedtime = squid_curtime;
62e76326 266
fa80a8ef 267 if (cbdataReferenceValidDone(r->data, &cbdata))
62e76326 268 r->handler(cbdata, NULL);
269
fa80a8ef 270 cbdataReferenceDone(r->data);
62e76326 271
f2afa96a 272 while (basic_auth->auth_queue) {
62e76326 273 tmpnode = basic_auth->auth_queue->next;
274
275 if (cbdataReferenceValidDone(basic_auth->auth_queue->data, &cbdata))
276 basic_auth->auth_queue->handler(cbdata, NULL);
277
278 xfree(basic_auth->auth_queue);
279
280 basic_auth->auth_queue = tmpnode;
94439e4e 281 }
62e76326 282
94439e4e 283 authenticateStateFree(r);
284}
285
f5691f9c 286void
287AuthBasicConfig::dump(StoreEntry * entry, const char *name, AuthConfig * scheme)
94439e4e 288{
f5691f9c 289 wordlist *list = authenticate;
94439e4e 290 storeAppendPrintf(entry, "%s %s", name, "basic");
62e76326 291
94439e4e 292 while (list != NULL) {
62e76326 293 storeAppendPrintf(entry, " %s", list->key);
294 list = list->next;
94439e4e 295 }
62e76326 296
07eca7e0 297 storeAppendPrintf(entry, "\n");
298
f5691f9c 299 storeAppendPrintf(entry, "%s basic realm %s\n", name, basicAuthRealm);
300 storeAppendPrintf(entry, "%s basic children %d\n", name, authenticateChildren);
301 storeAppendPrintf(entry, "%s basic concurrency %d\n", name, authenticateConcurrency);
302 storeAppendPrintf(entry, "%s basic credentialsttl %d seconds\n", name, (int) credentialsTTL);
64658378 303 storeAppendPrintf(entry, "%s basic casesensitive %s\n", name, casesensitive ? "on" : "off");
94439e4e 304
305}
306
f5691f9c 307AuthBasicConfig::AuthBasicConfig()
308{
309 /* TODO: move into initialisation list */
310 authenticateChildren = 5;
311 credentialsTTL = 2 * 60 * 60; /* two hours */
312}
62e76326 313
f5691f9c 314void
315AuthBasicConfig::parse(AuthConfig * scheme, int n_configured, char *param_str)
316{
94439e4e 317 if (strcasecmp(param_str, "program") == 0) {
f5691f9c 318 if (authenticate)
319 wordlistDestroy(&authenticate);
62e76326 320
f5691f9c 321 parse_wordlist(&authenticate);
62e76326 322
f5691f9c 323 requirePathnameExists("authparam basic program", authenticate->key);
94439e4e 324 } else if (strcasecmp(param_str, "children") == 0) {
f5691f9c 325 parse_int(&authenticateChildren);
07eca7e0 326 } else if (strcasecmp(param_str, "concurrency") == 0) {
f5691f9c 327 parse_int(&authenticateConcurrency);
94439e4e 328 } else if (strcasecmp(param_str, "realm") == 0) {
f5691f9c 329 parse_eol(&basicAuthRealm);
94439e4e 330 } else if (strcasecmp(param_str, "credentialsttl") == 0) {
f5691f9c 331 parse_time_t(&credentialsTTL);
64658378 332 } else if (strcasecmp(param_str, "casesensitive") == 0) {
333 parse_onoff(&casesensitive);
94439e4e 334 } else {
62e76326 335 debug(28, 0) ("unrecognised basic auth scheme parameter '%s'\n", param_str);
94439e4e 336 }
337}
338
339static void
340authenticateBasicStats(StoreEntry * sentry)
341{
342 storeAppendPrintf(sentry, "Basic Authenticator Statistics:\n");
343 helperStats(sentry, basicauthenticators);
344}
345
e6ccf245 346CBDATA_TYPE(AuthenticateStateData);
94439e4e 347
2d72d4fd 348static auth_user_t *
94439e4e 349authBasicAuthUserFindUsername(const char *username)
350{
e6ccf245 351 AuthUserHashPointer *usernamehash;
94439e4e 352 debug(29, 9) ("authBasicAuthUserFindUsername: Looking for user '%s'\n", username);
62e76326 353
e6ccf245 354 if (username && (usernamehash = static_cast<AuthUserHashPointer *>(hash_lookup(proxy_auth_username_cache, username)))) {
62e76326 355 while (usernamehash) {
f5691f9c 356 if ((usernamehash->user()->auth_type == AUTH_BASIC) &&
62e76326 357 !strcmp(username, (char const *)usernamehash->key))
f5691f9c 358 return usernamehash->user();
62e76326 359
360 usernamehash = static_cast<AuthUserHashPointer *>(usernamehash->next);
361 }
94439e4e 362 }
62e76326 363
94439e4e 364 return NULL;
365}
366
f5691f9c 367void
368BasicUser::deleteSelf() const
369{
370 delete this;
371}
94439e4e 372
f5691f9c 373BasicUser::BasicUser(AuthConfig *config) : AuthUser (config) , passwd (NULL), credentials_checkedtime(0), auth_queue(NULL), cleartext (NULL), currentRequest (NULL), httpAuthHeader (NULL)
374{
375 flags.credentials_ok = 0;
376}
62e76326 377
f5691f9c 378void
379BasicUser::decodeCleartext()
380{
381 char *sent_auth;
94439e4e 382 /* username and password */
f5691f9c 383 sent_auth = xstrdup(httpAuthHeader);
94439e4e 384 /* Trim trailing \n before decoding */
385 strtok(sent_auth, "\n");
62e76326 386
94439e4e 387 cleartext = uudecode(sent_auth);
62e76326 388
94439e4e 389 xfree(sent_auth);
f5691f9c 390}
62e76326 391
f5691f9c 392void
393BasicUser::extractUsername()
394{
94439e4e 395 /*
396 * Don't allow NL or CR in the credentials.
397 * Oezguer Kesim <oec@codeblau.de>
398 */
399 strtok(cleartext, "\r\n");
62e76326 400
94439e4e 401 debug(29, 9) ("authenticateBasicDecodeAuth: cleartext = '%s'\n", cleartext);
62e76326 402
411c6ea3 403 char * tempusername = xstrndup(cleartext, USER_IDENT_SZ);
94439e4e 404 xfree(cleartext);
f5691f9c 405 /* terminate the username string */
62e76326 406
411c6ea3 407 if ((cleartext = strchr(tempusername, ':')) != NULL)
62e76326 408 *(cleartext)++ = '\0';
64658378 409
411c6ea3 410 username (tempusername);
411
64658378 412 if (!basicConfig.casesensitive)
413 Tolower((char *)username());
f5691f9c 414}
62e76326 415
f5691f9c 416void
417BasicUser::extractPassword()
418{
419 passwd = cleartext;
62e76326 420
94439e4e 421 if (cleartext == NULL) {
62e76326 422 debug(29, 4) ("authenticateBasicDecodeAuth: no password in proxy authorization header '%s'\n",
f5691f9c 423 httpAuthHeader);
424 passwd = NULL;
425 currentRequest->setDenyMessage ("no password was present in the HTTP [proxy-]authorization header. This is most likely a browser bug");
94439e4e 426 } else if (*cleartext == '\0') {
62e76326 427 debug(29, 4) ("authenticateBasicDecodeAuth: Disallowing empty password,"
f5691f9c 428 "user is '%s'\n", username());
429 passwd = NULL;
430 currentRequest->setDenyMessage ("Request denied because you provided an empty password. Users MUST have a password.");
94439e4e 431 }
62e76326 432
f5691f9c 433 if (passwd)
434 passwd = xstrndup(cleartext, USER_IDENT_SZ);
62e76326 435
f5691f9c 436 cleartext = NULL;
437}
94439e4e 438
f5691f9c 439void
440BasicUser::decode(char const *proxy_auth, AuthUserRequest *auth_user_request)
441{
442 currentRequest = auth_user_request;
443 httpAuthHeader = proxy_auth;
444 decodeCleartext ();
445 extractUsername();
446 extractPassword();
447 currentRequest = NULL;
448 httpAuthHeader = NULL;
449}
450
451bool
452BasicUser::valid() const
453{
454 return passwd != NULL;
455}
94439e4e 456
f5691f9c 457void
458BasicUser::makeLoggingInstance(AuthBasicUserRequest *auth_user_request)
459{
460 if (username()) {
461 /* log the username */
462 debug(29, 9) ("authBasicDecodeAuth: Creating new user for logging '%s'\n", username());
62e76326 463 /* new scheme data */
f5691f9c 464 BasicUser *basic_auth = new BasicUser(& basicConfig);
465 auth_user_request->user(basic_auth);
62e76326 466 /* save the credentials */
f5691f9c 467 basic_auth->username(username());
468 username(NULL);
62e76326 469 /* set the auth_user type */
f5691f9c 470 basic_auth->auth_type = AUTH_BROKEN;
471 /* link the request to the user */
472 basic_auth->addRequest(auth_user_request);
473 }
474}
475
476AuthUser *
477BasicUser::makeCachedFrom()
478{
479 /* the user doesn't exist in the username cache yet */
480 debug(29, 9) ("authBasicDecodeAuth: Creating new user '%s'\n", username());
481 BasicUser *basic_user = new BasicUser(&basicConfig);
482 /* save the credentials */
483 basic_user->username(username());
484 username(NULL);
485 basic_user->passwd = passwd;
486 passwd = NULL;
487 /* set the auth_user type */
488 basic_user->auth_type = AUTH_BASIC;
489 /* current time for timeouts */
490 basic_user->expiretime = current_time.tv_sec;
491
492 /* this basic_user struct is the 'lucky one' to get added to the username cache */
493 /* the requests after this link to the basic_user */
494 /* store user in hash */
495 basic_user->addToNameCache();
496 return basic_user;
497}
498
499void
500BasicUser::updateCached(BasicUser *from)
501{
502 debug(29, 9) ("authBasicDecodeAuth: Found user '%s' in the user cache as '%p'\n", from->username(), this);
503
504 if (strcmp(from->passwd, passwd)) {
505 debug(29, 4) ("authBasicDecodeAuth: new password found. Updating in user master record and resetting auth state to unchecked\n");
506 flags.credentials_ok = 0;
507 xfree(passwd);
508 passwd = from->passwd;
509 from->passwd = NULL;
510 }
511
512 if (flags.credentials_ok == 3) {
513 debug(29, 4) ("authBasicDecodeAuth: last attempt to authenticate this user failed, resetting auth state to unchecked\n");
514 flags.credentials_ok = 0;
515 }
516}
517
518/*
519 * Decode a Basic [Proxy-]Auth string, linking the passed
520 * auth_user_request structure to any existing user structure or creating one
521 * if needed. Note that just returning will be treated as
522 * "cannot decode credentials". Use the message field to return a
523 * descriptive message to the user.
524 */
525AuthUserRequest *
526AuthBasicConfig::decode(char const *proxy_auth)
527{
528 AuthBasicUserRequest *auth_user_request = new AuthBasicUserRequest();
529 /* decode the username */
530 /* trim BASIC from string */
531
ba53f4b8 532 while (xisgraph(*proxy_auth))
f5691f9c 533 proxy_auth++;
534
535 BasicUser *basic_auth, local_basic(&basicConfig);
536
537 /* Trim leading whitespace before decoding */
538 while (xisspace(*proxy_auth))
539 proxy_auth++;
540
541 local_basic.decode(proxy_auth, auth_user_request);
542
543 if (!local_basic.valid()) {
544 local_basic.makeLoggingInstance(auth_user_request);
545 return auth_user_request;
94439e4e 546 }
62e76326 547
f5691f9c 548 /* now lookup and see if we have a matching auth_user structure in
549 * memory. */
62e76326 550
f5691f9c 551 auth_user_t *auth_user;
62e76326 552
f5691f9c 553 if ((auth_user = authBasicAuthUserFindUsername(local_basic.username())) == NULL) {
554 auth_user = local_basic.makeCachedFrom();
555 basic_auth = dynamic_cast<BasicUser *>(auth_user);
556 assert (basic_auth);
557 } else {
558 basic_auth = dynamic_cast<BasicUser *>(auth_user);
559 assert (basic_auth);
560 basic_auth->updateCached (&local_basic);
561 }
62e76326 562
f5691f9c 563 /* link the request to the in-cache user */
564 auth_user_request->user(basic_auth);
62e76326 565
f5691f9c 566 basic_auth->addRequest(auth_user_request);
567
568 return auth_user_request;
94439e4e 569}
570
571/* Initialize helpers and the like for this auth scheme. Called AFTER parsing the
572 * config file */
f5691f9c 573void
574AuthBasicConfig::init(AuthConfig * scheme)
94439e4e 575{
576 static int init = 0;
62e76326 577
f5691f9c 578 if (authenticate) {
62e76326 579 authbasic_initialised = 1;
580
581 if (basicauthenticators == NULL)
582 basicauthenticators = helperCreate("basicauthenticator");
583
f5691f9c 584 basicauthenticators->cmdline = authenticate;
62e76326 585
f5691f9c 586 basicauthenticators->n_to_start = authenticateChildren;
62e76326 587
f5691f9c 588 basicauthenticators->concurrency = authenticateConcurrency;
07eca7e0 589
62e76326 590 basicauthenticators->ipc_type = IPC_STREAM;
591
592 helperOpenServers(basicauthenticators);
593
594 if (!init) {
595 cachemgrRegister("basicauthenticator",
596 "Basic User Authenticator Stats",
597 authenticateBasicStats, 0, 1);
598 init++;
599 }
600
601 CBDATA_INIT_TYPE(AuthenticateStateData);
94439e4e 602 }
603}
604
f5691f9c 605void
606BasicUser::queueRequest(auth_user_request_t * auth_user_request, RH * handler, void *data)
607{
608 BasicAuthQueueNode *node;
609 node = static_cast<BasicAuthQueueNode *>(xmalloc(sizeof(BasicAuthQueueNode)));
610 assert(node);
611 /* save the details */
612 node->next = auth_queue;
613 auth_queue = node;
614 node->auth_user_request = auth_user_request;
615 node->handler = handler;
616 node->data = cbdataReference(data);
617}
618
94439e4e 619/* send the initial data to a basic authenticator module */
f5691f9c 620void
621AuthBasicUserRequest::module_start(RH * handler, void *data)
94439e4e 622{
94439e4e 623 basic_data *basic_auth;
f5691f9c 624 assert(user()->auth_type == AUTH_BASIC);
625 basic_auth = dynamic_cast<basic_data *>(user());
626 debug(29, 9) ("AuthBasicUserRequest::start: '%s:%s'\n", basic_auth->username(),
62e76326 627 basic_auth->passwd);
628
f5691f9c 629 if (basicConfig.authenticate == NULL) {
62e76326 630 handler(data, NULL);
631 return;
94439e4e 632 }
62e76326 633
94439e4e 634 /* check to see if the auth_user already has a request outstanding */
bd507204 635 if (basic_auth->flags.credentials_ok == 2) {
62e76326 636 /* there is a request with the same credentials already being verified */
f5691f9c 637 basic_auth->queueRequest(this, handler, data);
62e76326 638 return;
94439e4e 639 }
f5691f9c 640
641 basic_auth->submitRequest (this, handler, data);
94439e4e 642}
f5691f9c 643
644void
645BasicUser::submitRequest (auth_user_request_t * auth_user_request, RH * handler, void *data)
646{
647 /* mark the user as haveing verification in progress */
648 flags.credentials_ok = 2;
649 AuthenticateStateData *r = NULL;
650 char buf[8192];
651 char user[1024], pass[1024];
652 r = cbdataAlloc(AuthenticateStateData);
653 r->handler = handler;
654 r->data = cbdataReference(data);
655 r->auth_user_request = auth_user_request;
656 xstrncpy(user, rfc1738_escape(username()), sizeof(user));
657 xstrncpy(pass, rfc1738_escape(passwd), sizeof(pass));
658 snprintf(buf, sizeof(buf), "%s %s\n", user, pass);
659 helperSubmit(basicauthenticators, buf, authenticateBasicHandleReply, r);
660}
661
662AuthConfig *
663basicScheme::createConfig()
664{
665 return &basicConfig;
666}
667