~clint-fewbar/ubuntu/precise/squid3/ignore-sighup-early

« back to all changes in this revision

Viewing changes to src/auth/basic/auth_basic.cc

  • Committer: Bazaar Package Importer
  • Author(s): Luigi Gangitano
  • Date: 2010-05-04 11:15:49 UTC
  • mfrom: (1.3.1 upstream)
  • mto: (20.3.1 squeeze) (21.2.1 sid)
  • mto: This revision was merged to the branch mainline in revision 21.
  • Revision ID: james.westby@ubuntu.com-20100504111549-1apjh2g5sndki4te
Tags: upstream-3.1.3
ImportĀ upstreamĀ versionĀ 3.1.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
 * $Id: auth_basic.cc,v 1.52 2007/08/03 02:11:17 amosjeffries Exp $
 
2
 * $Id$
3
3
 *
4
4
 * DEBUG: section 29    Authenticator
5
5
 * AUTHOR: Duane Wessels
20
20
 *  it under the terms of the GNU General Public License as published by
21
21
 *  the Free Software Foundation; either version 2 of the License, or
22
22
 *  (at your option) any later version.
23
 
 *  
 
23
 *
24
24
 *  This program is distributed in the hope that it will be useful,
25
25
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
26
26
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
27
27
 *  GNU General Public License for more details.
28
 
 *  
 
28
 *
29
29
 *  You should have received a copy of the GNU General Public License
30
30
 *  along with this program; if not, write to the Free Software
31
31
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
39
39
 
40
40
#include "squid.h"
41
41
#include "auth_basic.h"
42
 
#include "authenticate.h"
 
42
#include "auth/Gadgets.h"
43
43
#include "CacheManager.h"
44
44
#include "Store.h"
45
45
#include "HttpReply.h"
46
46
#include "basicScheme.h"
 
47
#include "rfc1738.h"
47
48
#include "wordlist.h"
48
49
#include "SquidTime.h"
49
50
 
93
94
    basicauthenticators = NULL;
94
95
 
95
96
    /* XXX Reinstate auth shutdown for dynamic schemes? */
96
 
    debugs(29, 2, "authBasicDone: Basic authentication Shutdown.");
 
97
    debugs(29, DBG_CRITICAL, HERE << "Basic authentication Shutdown.");
97
98
}
98
99
 
99
100
bool
107
108
{
108
109
    if ((authenticate != NULL) && (authenticateChildren != 0) &&
109
110
            (basicAuthRealm != NULL)) {
110
 
        debugs(29, 9, "authBasicConfigured: returning configured");
 
111
        debugs(29, 9, HERE << "returning configured");
111
112
        return true;
112
113
    }
113
114
 
114
 
    debugs(29, 9, "authBasicConfigured: returning unconfigured");
 
115
    debugs(29, 9, HERE << "returning unconfigured");
115
116
    return false;
116
117
}
117
118
 
153
154
/* log a basic user in
154
155
 */
155
156
void
156
 
AuthBasicUserRequest::authenticate(HttpRequest * request, ConnStateData::Pointer conn, http_hdr_type type)
 
157
AuthBasicUserRequest::authenticate(HttpRequest * request, ConnStateData * conn, http_hdr_type type)
157
158
{
158
159
    assert(user() != NULL);
159
160
 
210
211
}
211
212
 
212
213
void
213
 
AuthBasicConfig::fixHeader(AuthUserRequest *auth_user_request, HttpReply *rep, http_hdr_type type, HttpRequest * request)
 
214
AuthBasicConfig::fixHeader(AuthUserRequest *auth_user_request, HttpReply *rep, http_hdr_type hdrType, HttpRequest * request)
214
215
{
215
216
    if (authenticate) {
216
 
        debugs(29, 9, "authenticateFixErrorHeader: Sending type:" << type << " header: 'Basic realm=\"" << basicAuthRealm << "\"'");
217
 
        httpHeaderPutStrf(&rep->header, type, "Basic realm=\"%s\"", basicAuthRealm);
 
217
        debugs(29, 9, HERE << "Sending type:" << hdrType << " header: 'Basic realm=\"" << basicAuthRealm << "\"'");
 
218
        httpHeaderPutStrf(&rep->header, hdrType, "Basic realm=\"%s\"", basicAuthRealm);
218
219
    }
219
220
}
220
221
 
231
232
 
232
233
BasicUser::~BasicUser()
233
234
{
234
 
    if (passwd)
235
 
        xfree(passwd);
236
 
 
237
 
    safe_free (cleartext);
 
235
    safe_free(passwd);
 
236
    safe_free(cleartext);
238
237
}
239
238
 
240
239
static void
244
243
    BasicAuthQueueNode *tmpnode;
245
244
    char *t = NULL;
246
245
    void *cbdata;
247
 
    debugs(29, 9, "authenticateBasicHandleReply: {" << (reply ? reply : "<NULL>") << "}");
 
246
    debugs(29, 9, HERE << "{" << (reply ? reply : "<NULL>") << "}");
248
247
 
249
248
    if (reply) {
250
249
        if ((t = strchr(reply, ' ')))
308
307
    storeAppendPrintf(entry, "%s basic concurrency %d\n", name, authenticateConcurrency);
309
308
    storeAppendPrintf(entry, "%s basic credentialsttl %d seconds\n", name, (int) credentialsTTL);
310
309
    storeAppendPrintf(entry, "%s basic casesensitive %s\n", name, casesensitive ? "on" : "off");
311
 
 
312
310
}
313
311
 
314
312
AuthBasicConfig::AuthBasicConfig()
344
342
        parse_time_t(&credentialsTTL);
345
343
    } else if (strcasecmp(param_str, "casesensitive") == 0) {
346
344
        parse_onoff(&casesensitive);
 
345
    } else if (strcasecmp(param_str, "utf8") == 0) {
 
346
        parse_onoff(&utf8);
347
347
    } else {
348
 
        debugs(29, 0, "unrecognised basic auth scheme parameter '" << param_str << "'");
 
348
        debugs(29, DBG_CRITICAL, HERE << "unrecognised basic auth scheme parameter '" << param_str << "'");
349
349
    }
350
350
}
351
351
 
357
357
 
358
358
CBDATA_TYPE(AuthenticateStateData);
359
359
 
360
 
static auth_user_t *
 
360
static AuthUser *
361
361
authBasicAuthUserFindUsername(const char *username)
362
362
{
363
363
    AuthUserHashPointer *usernamehash;
364
 
    debugs(29, 9, "authBasicAuthUserFindUsername: Looking for user '" << username << "'");
 
364
    debugs(29, 9, HERE << "Looking for user '" << username << "'");
365
365
 
366
366
    if (username && (usernamehash = static_cast<AuthUserHashPointer *>(hash_lookup(proxy_auth_username_cache, username)))) {
367
367
        while (usernamehash) {
382
382
    delete this;
383
383
}
384
384
 
385
 
BasicUser::BasicUser(AuthConfig *config) : AuthUser (config) , passwd (NULL), credentials_checkedtime(0), auth_queue(NULL), cleartext (NULL), currentRequest (NULL), httpAuthHeader (NULL)
 
385
BasicUser::BasicUser(AuthConfig *aConfig) : AuthUser (aConfig) , passwd (NULL), credentials_checkedtime(0), auth_queue(NULL), cleartext (NULL), currentRequest (NULL), httpAuthHeader (NULL)
386
386
{
387
387
    flags.credentials_ok = 0;
388
388
}
409
409
     * Don't allow NL or CR in the credentials.
410
410
     * Oezguer Kesim <oec@codeblau.de>
411
411
     */
412
 
    debugs(29, 9, "BasicUser::decodeCleartext: '" << cleartext << "'");
 
412
    debugs(29, 9, HERE << "'" << cleartext << "'");
413
413
 
414
414
    if (strcspn(cleartext, "\r\n") != strlen(cleartext)) {
415
 
        debugs(29, 1, "BasicUser::decodeCleartext: bad characters in authorization header '" << httpAuthHeader << "'");
 
415
        debugs(29, 1, HERE << "bad characters in authorization header '" << httpAuthHeader << "'");
416
416
        safe_free(cleartext);
417
417
        return false;
418
418
    }
446
446
    passwd = strchr(cleartext, ':');
447
447
 
448
448
    if (passwd == NULL) {
449
 
        debugs(29, 4, "authenticateBasicDecodeAuth: no password in proxy authorization header '" << httpAuthHeader << "'");
 
449
        debugs(29, 4, HERE << "no password in proxy authorization header '" << httpAuthHeader << "'");
450
450
        passwd = NULL;
451
 
        currentRequest->setDenyMessage ("no password was present in the HTTP [proxy-]authorization header. This is most likely a browser bug");
 
451
        currentRequest->setDenyMessage("no password was present in the HTTP [proxy-]authorization header. This is most likely a browser bug");
452
452
    } else {
453
453
        ++passwd;
454
454
        if (*passwd == '\0') {
455
 
            debugs(29, 4, "authenticateBasicDecodeAuth: Disallowing empty password,user is '" << username() << "'");
 
455
            debugs(29, 4, HERE << "Disallowing empty password,user is '" << username() << "'");
456
456
            passwd = NULL;
457
 
            currentRequest->setDenyMessage ("Request denied because you provided an empty password. Users MUST have a password.");
 
457
            currentRequest->setDenyMessage("Request denied because you provided an empty password. Users MUST have a password.");
458
458
        } else {
459
459
            passwd = xstrndup(passwd, USER_IDENT_SZ);
460
460
        }
467
467
    currentRequest = auth_user_request;
468
468
    httpAuthHeader = proxy_auth;
469
469
    if (decodeCleartext ()) {
470
 
        extractUsername();
471
 
        extractPassword();
 
470
        extractUsername();
 
471
        extractPassword();
472
472
    }
473
473
    currentRequest = NULL;
474
474
    httpAuthHeader = NULL;
478
478
BasicUser::valid() const
479
479
{
480
480
    if (username() == NULL)
481
 
        return false;
 
481
        return false;
482
482
    if (passwd == NULL)
483
 
        return false;
 
483
        return false;
484
484
    return true;
485
485
}
486
486
 
489
489
{
490
490
    if (username()) {
491
491
        /* log the username */
492
 
        debugs(29, 9, "authBasicDecodeAuth: Creating new user for logging '" << username() << "'");
 
492
        debugs(29, 9, HERE << "Creating new user for logging '" << username() << "'");
493
493
        /* new scheme data */
494
494
        BasicUser *basic_auth = new BasicUser(& basicConfig);
495
495
        auth_user_request->user(basic_auth);
507
507
BasicUser::makeCachedFrom()
508
508
{
509
509
    /* the user doesn't exist in the username cache yet */
510
 
    debugs(29, 9, "authBasicDecodeAuth: Creating new user '" << username() << "'");
 
510
    debugs(29, 9, HERE << "Creating new user '" << username() << "'");
511
511
    BasicUser *basic_user = new BasicUser(&basicConfig);
512
512
    /* save the credentials */
513
513
    basic_user->username(username());
529
529
void
530
530
BasicUser::updateCached(BasicUser *from)
531
531
{
532
 
    debugs(29, 9, "authBasicDecodeAuth: Found user '" << from->username() << "' in the user cache as '" << this << "'");
 
532
    debugs(29, 9, HERE << "Found user '" << from->username() << "' in the user cache as '" << this << "'");
533
533
 
534
534
    if (strcmp(from->passwd, passwd)) {
535
 
        debugs(29, 4, "authBasicDecodeAuth: new password found. Updating in user master record and resetting auth state to unchecked");
 
535
        debugs(29, 4, HERE << "new password found. Updating in user master record and resetting auth state to unchecked");
536
536
        flags.credentials_ok = 0;
537
537
        xfree(passwd);
538
538
        passwd = from->passwd;
540
540
    }
541
541
 
542
542
    if (flags.credentials_ok == 3) {
543
 
        debugs(29, 4, "authBasicDecodeAuth: last attempt to authenticate this user failed, resetting auth state to unchecked");
 
543
        debugs(29, 4, HERE << "last attempt to authenticate this user failed, resetting auth state to unchecked");
544
544
        flags.credentials_ok = 0;
545
545
    }
546
546
}
547
547
 
548
 
/*
 
548
/**
549
549
 * Decode a Basic [Proxy-]Auth string, linking the passed
550
550
 * auth_user_request structure to any existing user structure or creating one
551
 
 * if needed. Note that just returning will be treated as 
552
 
 * "cannot decode credentials". Use the message field to return a 
 
551
 * if needed. Note that just returning will be treated as
 
552
 * "cannot decode credentials". Use the message field to return a
553
553
 * descriptive message to the user.
554
554
 */
555
555
AuthUserRequest *
578
578
    /* now lookup and see if we have a matching auth_user structure in
579
579
     * memory. */
580
580
 
581
 
    auth_user_t *auth_user;
 
581
    AuthUser *auth_user;
582
582
 
583
583
    if ((auth_user = authBasicAuthUserFindUsername(local_basic.username())) == NULL) {
584
584
        auth_user = local_basic.makeCachedFrom();
598
598
    return auth_user_request;
599
599
}
600
600
 
601
 
/* Initialize helpers and the like for this auth scheme. Called AFTER parsing the
 
601
/** Initialize helpers and the like for this auth scheme. Called AFTER parsing the
602
602
 * config file */
603
603
void
604
604
AuthBasicConfig::init(AuthConfig * scheme)
624
624
}
625
625
 
626
626
void
627
 
AuthBasicConfig::registerWithCacheManager(CacheManager & manager)
 
627
AuthBasicConfig::registerWithCacheManager(void)
628
628
{
629
 
    manager.registerAction("basicauthenticator",
630
 
                           "Basic User Authenticator Stats",
631
 
                           authenticateBasicStats, 0, 1);
 
629
    CacheManager::GetInstance()->
 
630
    registerAction("basicauthenticator",
 
631
                   "Basic User Authenticator Stats",
 
632
                   authenticateBasicStats, 0, 1);
632
633
}
633
634
 
634
635
void
653
654
    assert(user()->auth_type == AUTH_BASIC);
654
655
    basic_auth = dynamic_cast<basic_data *>(user());
655
656
    assert(basic_auth != NULL);
656
 
    debugs(29, 9, "AuthBasicUserRequest::start: '" << basic_auth->username() << ":" << basic_auth->passwd << "'");
 
657
    debugs(29, 9, HERE << "'" << basic_auth->username() << ":" << basic_auth->passwd << "'");
657
658
 
658
659
    if (basicConfig.authenticate == NULL) {
659
660
        handler(data, NULL);
671
672
}
672
673
 
673
674
void
674
 
BasicUser::submitRequest (AuthUserRequest * auth_user_request, RH * handler, void *data)
 
675
BasicUser::submitRequest(AuthUserRequest * auth_user_request, RH * handler, void *data)
675
676
{
676
677
    /* mark the user as haveing verification in progress */
677
678
    flags.credentials_ok = 2;
682
683
    r->handler = handler;
683
684
    r->data = cbdataReference(data);
684
685
    r->auth_user_request = auth_user_request;
685
 
    xstrncpy(user, rfc1738_escape(username()), sizeof(user));
686
 
    xstrncpy(pass, rfc1738_escape(passwd), sizeof(pass));
 
686
    if (basicConfig.utf8) {
 
687
        latin1_to_utf8(user, sizeof(user), username());
 
688
        latin1_to_utf8(pass, sizeof(pass), passwd);
 
689
        xstrncpy(user, rfc1738_escape(user), sizeof(user));
 
690
        xstrncpy(pass, rfc1738_escape(pass), sizeof(pass));
 
691
    } else {
 
692
        xstrncpy(user, rfc1738_escape(username()), sizeof(user));
 
693
        xstrncpy(pass, rfc1738_escape(passwd), sizeof(pass));
 
694
    }
687
695
    snprintf(buf, sizeof(buf), "%s %s\n", user, pass);
688
696
    helperSubmit(basicauthenticators, buf, authenticateBasicHandleReply, r);
689
697
}
693
701
{
694
702
    return &basicConfig;
695
703
}
696