From: robertc <> Date: Mon, 3 Sep 2001 16:33:02 +0000 (+0000) Subject: Merge from ntlm work. Fixes: reconfiguring when ntlm authentication in progress,... X-Git-Tag: SQUID_3_0_PRE1~1418 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=bd507204f961f2f7cafef8bd31eb8d5dcc38c323;p=thirdparty%2Fsquid.git Merge from ntlm work. Fixes: reconfiguring when ntlm authentication in progress, no longer resets all ntlm auth progress for user foo when user foo has an error on one connection --- diff --git a/src/acl.cc b/src/acl.cc index 887c87af31..5d5e7a479c 100644 --- a/src/acl.cc +++ b/src/acl.cc @@ -1,6 +1,6 @@ /* - * $Id: acl.cc,v 1.258 2001/08/21 05:54:13 wessels Exp $ + * $Id: acl.cc,v 1.259 2001/09/03 10:33:02 robertc Exp $ * * DEBUG: section 28 Access Control * AUTHOR: Duane Wessels @@ -1844,14 +1844,21 @@ static void aclCheckCallback(aclCheck_t * checklist, allow_t answer) { debug(28, 3) ("aclCheckCallback: answer=%d\n", answer); + /* During reconfigure, we can end up not finishing call sequences into the auth code */ + if (checklist->auth_user_request) { + /* the checklist lock */ + authenticateAuthUserRequestUnlock(checklist->auth_user_request); + /* it might have been connection based */ + assert(checklist->conn); + checklist->conn->auth_user_request = NULL; + checklist->conn->auth_type = AUTH_BROKEN; + checklist->auth_user_request = NULL; + } if (cbdataValid(checklist->callback_data)) checklist->callback(answer, checklist->callback_data); cbdataUnlock(checklist->callback_data); checklist->callback = NULL; checklist->callback_data = NULL; - /* XXX: this assert is here to check for misbehaved acl authentication code. - * It can probably go sometime soon. */ - assert(checklist->auth_user_request == NULL); aclChecklistFree(checklist); } @@ -1914,21 +1921,19 @@ static void aclLookupProxyAuthDone(void *data, char *result) { aclCheck_t *checklist = data; - auth_user_request_t *auth_user_request; checklist->state[ACL_PROXY_AUTH] = ACL_LOOKUP_DONE; if (result != NULL) fatal("AclLookupProxyAuthDone: Old code floating around somewhere.\nMake clean and if that doesn't work, report a bug to the squid developers.\n"); - auth_user_request = checklist->auth_user_request; - if (!authenticateValidateUser(auth_user_request) || checklist->conn == NULL) { + if (!authenticateValidateUser(checklist->auth_user_request) || checklist->conn == NULL) { /* credentials could not be checked either way * restart the whole process */ /* OR the connection was closed, there's no way to continue */ - checklist->conn->auth_user_request = NULL; - checklist->conn->auth_type = AUTH_BROKEN; + authenticateAuthUserRequestUnlock(checklist->auth_user_request); + if (checklist->conn) { + checklist->conn->auth_user_request = NULL; + checklist->conn->auth_type = AUTH_BROKEN; + } checklist->auth_user_request = NULL; - authenticateAuthUserRequestUnlock(auth_user_request); - aclCheck(checklist); - return; } aclCheck(checklist); } diff --git a/src/auth/basic/auth_basic.cc b/src/auth/basic/auth_basic.cc index 2bd3e9df42..4fcb83d2f2 100644 --- a/src/auth/basic/auth_basic.cc +++ b/src/auth/basic/auth_basic.cc @@ -1,5 +1,5 @@ /* - * $Id: auth_basic.cc,v 1.10 2001/08/30 23:00:36 robertc Exp $ + * $Id: auth_basic.cc,v 1.11 2001/09/03 10:33:03 robertc Exp $ * * DEBUG: section 29 Authenticator * AUTHOR: Duane Wessels @@ -149,7 +149,7 @@ static int authenticateBasicAuthenticated(auth_user_request_t * auth_user_request) { basic_data *basic_auth = auth_user_request->auth_user->scheme_data; - if ((auth_user_request->auth_user->flags.credentials_ok == 1) && (basic_auth->credentials_checkedtime + basicConfig->credentialsTTL > squid_curtime)) + if ((basic_auth->flags.credentials_ok == 1) && (basic_auth->credentials_checkedtime + basicConfig->credentialsTTL > squid_curtime)) return 1; debug(29, 4) ("User not authenticated or credentials need rechecking.\n"); return 0; @@ -174,12 +174,12 @@ authenticateBasicAuthenticateUser(auth_user_request_t * auth_user_request, reque assert(auth_user_request->auth_user != NULL); auth_user = auth_user_request->auth_user; - /* if the password is not ok, do an identity */ - if (auth_user->flags.credentials_ok != 1) - return; - assert(auth_user->scheme_data != NULL); basic_auth = auth_user->scheme_data; + + /* if the password is not ok, do an identity */ + if (basic_auth->flags.credentials_ok != 1) + return; /* are we about to recheck the credentials externally? */ if ((basic_auth->credentials_checkedtime + basicConfig->credentialsTTL) <= squid_curtime) { @@ -202,7 +202,7 @@ authenticateBasicDirection(auth_user_request_t * auth_user_request) /* null auth_user is checked for by authenticateDirection */ auth_user_t *auth_user = auth_user_request->auth_user; basic_data *basic_auth = auth_user->scheme_data; - switch (auth_user->flags.credentials_ok) { + switch (basic_auth->flags.credentials_ok) { case 0: /* not checked */ return -1; case 1: /* checked & ok */ @@ -275,9 +275,9 @@ authenticateBasicHandleReply(void *data, char *reply) auth_user = r->auth_user_request->auth_user; basic_auth = auth_user->scheme_data; if (reply && (strncasecmp(reply, "OK", 2) == 0)) - auth_user->flags.credentials_ok = 1; + basic_auth->flags.credentials_ok = 1; else - auth_user->flags.credentials_ok = 3; + basic_auth->flags.credentials_ok = 3; basic_auth->credentials_checkedtime = squid_curtime; valid = cbdataValid(r->data); if (valid) @@ -510,14 +510,14 @@ authenticateBasicDecodeAuth(auth_user_request_t * auth_user_request, const char basic_auth = auth_user->scheme_data; if (strcmp(local_basic.passwd, basic_auth->passwd)) { debug(29, 4) ("authBasicDecodeAuth: new password found. Updating in user master record and resetting auth state to unchecked\n"); - auth_user->flags.credentials_ok = 0; + basic_auth->flags.credentials_ok = 0; xfree(basic_auth->passwd); basic_auth->passwd = local_basic.passwd; } else xfree(local_basic.passwd); - if (auth_user->flags.credentials_ok == 3) { + if (basic_auth->flags.credentials_ok == 3) { debug(29, 4) ("authBasicDecodeAuth: last attempt to authenticate this user failed, resetting auth state to unchecked\n"); - auth_user->flags.credentials_ok = 0; + basic_auth->flags.credentials_ok = 0; } } /* link the request to the user */ @@ -574,7 +574,7 @@ authenticateBasicStart(auth_user_request_t * auth_user_request, RH * handler, vo return; } /* check to see if the auth_user already has a request outstanding */ - if (auth_user_request->auth_user->flags.credentials_ok == 2) { + if (basic_auth->flags.credentials_ok == 2) { /* there is a request with the same credentials already being verified */ auth_basic_queue_node *node; node = xmalloc(sizeof(auth_basic_queue_node)); @@ -594,7 +594,7 @@ authenticateBasicStart(auth_user_request_t * auth_user_request, RH * handler, vo r->data = data; r->auth_user_request = auth_user_request; /* mark the user as haveing verification in progress */ - auth_user_request->auth_user->flags.credentials_ok = 2; + basic_auth->flags.credentials_ok = 2; snprintf(buf, 8192, "%s %s\n", basic_auth->username, basic_auth->passwd); helperSubmit(basicauthenticators, buf, authenticateBasicHandleReply, r); } diff --git a/src/auth/basic/auth_basic.h b/src/auth/basic/auth_basic.h index 9c49b59436..a6f7ad135b 100644 --- a/src/auth/basic/auth_basic.h +++ b/src/auth/basic/auth_basic.h @@ -30,6 +30,9 @@ struct _basic_data { char *username; char *passwd; time_t credentials_checkedtime; + struct { + unsigned int credentials_ok:2; /*0=unchecked,1=ok,2=failed */ + } flags; auth_basic_queue_node *auth_queue; }; diff --git a/src/auth/digest/auth_digest.cc b/src/auth/digest/auth_digest.cc index 543e328e8a..febb66f634 100644 --- a/src/auth/digest/auth_digest.cc +++ b/src/auth/digest/auth_digest.cc @@ -1,6 +1,6 @@ /* - * $Id: auth_digest.cc,v 1.3 2001/08/03 15:13:10 adrian Exp $ + * $Id: auth_digest.cc,v 1.4 2001/09/03 10:33:03 robertc Exp $ * * DEBUG: section 29 Authenticator * AUTHOR: Robert Collins @@ -619,7 +619,8 @@ authDigestConfigured() int authDigestAuthenticated(auth_user_request_t * auth_user_request) { - if (auth_user_request->auth_user->flags.credentials_ok == 1) + digest_user_h *digest_user = auth_user_request->auth_user->scheme_data; + if (digest_user->flags.credentials_ok == 1) return 1; else return 0; @@ -641,19 +642,20 @@ authenticateDigestAuthenticateUser(auth_user_request_t * auth_user_request, requ assert(auth_user_request->auth_user != NULL); auth_user = auth_user_request->auth_user; - /* if the check has corrupted the user, just return */ - if (auth_user_request->auth_user->flags.credentials_ok == 3) { - return; - } assert(auth_user->scheme_data != NULL); digest_user = auth_user->scheme_data; + /* if the check has corrupted the user, just return */ + if (digest_user->flags.credentials_ok == 3) { + return; + } + assert(auth_user_request->scheme_data != NULL); digest_request = auth_user_request->scheme_data; /* do we have the HA1 */ if (!digest_user->HA1created) { - auth_user_request->auth_user->flags.credentials_ok = 2; + digest_user->flags.credentials_ok = 2; return; } if (digest_request->nonce == NULL) { @@ -661,8 +663,10 @@ authenticateDigestAuthenticateUser(auth_user_request_t * auth_user_request, requ /* TODO: record breaks in authentication at the request level * This is probably best done with support changes at the auth_rewrite level -RBC * and can wait for auth_rewrite V2. + * RBC 20010902 further note: flags.credentials ok is now a local scheme + * flag, so we can move this to the request level at any time. */ - auth_user->flags.credentials_ok = 3; + digest_user->flags.credentials_ok = 3; return; } DigestCalcHA1(digest_request->algorithm, NULL, NULL, NULL, @@ -677,10 +681,10 @@ authenticateDigestAuthenticateUser(auth_user_request_t * auth_user_request, requ "squid is = '%s'\n", digest_request->response, Response); if (strcasecmp(digest_request->response, Response)) { - auth_user->flags.credentials_ok = 3; + digest_user->flags.credentials_ok = 3; return; } - auth_user->flags.credentials_ok = 1; + digest_user->flags.credentials_ok = 1; /* password was checked and did match */ debug(29, 4) ("authenticateDigestAuthenticateuser: user '%s' validated OK\n", digest_user->username); @@ -695,8 +699,9 @@ int authenticateDigestDirection(auth_user_request_t * auth_user_request) { digest_request_h *digest_request; -/* null auth_user is checked for by authenticateDirection */ - switch (auth_user_request->auth_user->flags.credentials_ok) { + digest_user_h *digest_user = auth_user_request->auth_user->scheme_data; + /* null auth_user is checked for by authenticateDirection */ + switch (digest_user->flags.credentials_ok) { case 0: /* not checked */ return -1; case 1: /* checked & ok */ @@ -831,7 +836,7 @@ authenticateDigestHandleReply(void *data, char *reply) digest_request = auth_user_request->scheme_data; digest_user = auth_user_request->auth_user->scheme_data; if (reply && (strncasecmp(reply, "ERR", 3) == 0)) - auth_user_request->auth_user->flags.credentials_ok = 3; + digest_user->flags.credentials_ok = 3; else { CvtBin(reply, digest_user->HA1); digest_user->HA1created = 1; diff --git a/src/auth/digest/auth_digest.h b/src/auth/digest/auth_digest.h index 2f6e708c45..072e434d5e 100644 --- a/src/auth/digest/auth_digest.h +++ b/src/auth/digest/auth_digest.h @@ -24,6 +24,9 @@ struct _digest_user_h { char *username; HASH HA1; int HA1created; + struct { + unsigned int credentials_ok:2; /*0=unchecked,1=ok,2=failed */ + } flags; /* what nonces have been allocated to this user */ dlink_list nonces; }; diff --git a/src/auth/ntlm/auth_ntlm.cc b/src/auth/ntlm/auth_ntlm.cc index 264d7096e8..166a8cb47c 100644 --- a/src/auth/ntlm/auth_ntlm.cc +++ b/src/auth/ntlm/auth_ntlm.cc @@ -1,6 +1,6 @@ /* - * $Id: auth_ntlm.cc,v 1.11 2001/08/29 14:57:36 robertc Exp $ + * $Id: auth_ntlm.cc,v 1.12 2001/09/03 10:33:04 robertc Exp $ * * DEBUG: section 29 NTLM Authenticator * AUTHOR: Robert Collins @@ -75,7 +75,6 @@ static HLPSAVAIL authenticateNTLMHelperServerAvailable; static HLPSONEQ authenticateNTLMHelperServerOnEmpty; static statefulhelper *ntlmauthenticators = NULL; -static wordlist *ntlmprevauthline = NULL; CBDATA_TYPE(authenticateStateData); @@ -94,34 +93,17 @@ static hash_table *proxy_auth_cache = NULL; * */ -static int -wordliststrcmp(wordlist * a, wordlist * b) -{ - int i; - while (a && b) { - if ((i = strcmp(a->key, b->key))) - return i; - a = a->next; - b = b->next; - } - if (a && !b) - return -1; - if (b && !a) - return 1; - return 0; -} - void authNTLMDone(void) { debug(29, 2) ("authNTLMDone: shutting down NTLM authentication.\n"); + if (ntlmauthenticators) + helperStatefulShutdown(ntlmauthenticators); authntlm_initialised = 0; if (!shutting_down) return; - if (ntlmauthenticators) { - helperStatefulShutdown(ntlmauthenticators); + if (ntlmauthenticators) helperStatefulFree(ntlmauthenticators); - } ntlmauthenticators = NULL; if (ntlm_helper_state_pool) { assert(memPoolInUseCount(ntlm_helper_state_pool) == 0); @@ -262,13 +244,7 @@ authNTLMInit(authScheme * scheme) ntlmauthenticators->datapool = ntlm_helper_state_pool; ntlmauthenticators->IsAvailable = authenticateNTLMHelperServerAvailable; ntlmauthenticators->OnEmptyQueue = authenticateNTLMHelperServerOnEmpty; - if (wordliststrcmp(ntlmprevauthline, ntlmConfig->authenticate)) { - helperStatefulShutdown(ntlmauthenticators); - helperStatefulOpenServers(ntlmauthenticators); - if (ntlmprevauthline) - wordlistDestroy(&ntlmprevauthline); - ntlmprevauthline = wordlistDup(ntlmConfig->authenticate); - } + helperStatefulOpenServers(ntlmauthenticators); /* TODO: In here send the initial YR to preinitialise the challenge cache */ /* Think about this... currently we ask when the challenge is needed. Better? */ if (!ntlminit) { @@ -303,10 +279,10 @@ int authenticateNTLMDirection(auth_user_request_t * auth_user_request) { ntlm_request_t *ntlm_request = auth_user_request->scheme_data; -/* null auth_user is checked for by authenticateDirection */ + /* null auth_user is checked for by authenticateDirection */ switch (ntlm_request->auth_state) { case AUTHENTICATE_STATE_NONE: /* no progress at all. */ - if (auth_user_request->auth_user->flags.credentials_ok != 2) + if (ntlm_request->flags.credentials_ok != 2) debug(29, 1) ("authenticateNTLMDirection: called before NTLM Authenticate!. Report a bug to squid-dev. au %x\n", auth_user_request); return -2; case AUTHENTICATE_STATE_NEGOTIATE: /* send to helper */ @@ -510,7 +486,7 @@ authenticateNTLMHandleReply(void *data, void *lastserver, char *reply) assert(ntlm_request->auth_state == AUTHENTICATE_STATE_RESPONSE); ntlm_user->username = xstrndup(reply, MAX_LOGIN_SZ); ntlm_request->authserver = NULL; - auth_user->flags.credentials_ok = 1; /* login ok */ + ntlm_request->flags.credentials_ok = 1; /* login ok */ #ifdef NTLM_FAIL_OPEN } else if (strncasecmp(reply, "LD ", 3) == 0) { /* This is a variant of BH, which rather than deny access @@ -537,7 +513,7 @@ authenticateNTLMHandleReply(void *data, void *lastserver, char *reply) ntlm_user->username = xstrndup(reply, MAX_LOGIN_SZ); helperstate = helperStatefulServerGetData(ntlm_request->authserver); ntlm_request->authserver = NULL; - auth_user->flags.credentials_ok = 1; /* login ok */ + ntlm_request->flags.credentials_ok = 1; /* login ok */ /* BH code: mark helper as broken */ /* Not a valid helper response to a YR request. Assert so the helper * programmer will fix their bugs! */ @@ -558,7 +534,7 @@ authenticateNTLMHandleReply(void *data, void *lastserver, char *reply) /* todo: action of Negotiate state on error */ result = S_HELPER_RELEASE; /*some error has occured. no more requests */ ntlm_request->authserver = NULL; - auth_user->flags.credentials_ok = 2; /* Login/Usercode failed */ + ntlm_request->flags.credentials_ok = 2; /* Login/Usercode failed */ debug(29, 4) ("authenticateNTLMHandleReply: Error validating user via NTLM. Error returned '%s'\n", reply); ntlm_request->auth_state = AUTHENTICATE_STATE_NONE; if ((t = strchr(reply, ' '))) /* strip after a space */ @@ -588,7 +564,7 @@ authenticateNTLMHandleReply(void *data, void *lastserver, char *reply) if (ntlm_request->auth_state == AUTHENTICATE_STATE_NEGOTIATE) { /* The helper broke on YR. It automatically * resets */ - auth_user->flags.credentials_ok = 3; /* cannot process */ + ntlm_request->flags.credentials_ok = 3; /* cannot process */ debug(29, 1) ("authenticateNTLMHandleReply: Error obtaining challenge from helper: %d. Error returned '%s'\n", lastserver, reply); /* mark it for starving */ helperstate->starve = 1; @@ -603,7 +579,7 @@ authenticateNTLMHandleReply(void *data, void *lastserver, char *reply) } else { /* the helper broke on a KK */ /* first the standard KK stuff */ - auth_user->flags.credentials_ok = 2; /* Login/Usercode failed */ + ntlm_request->flags.credentials_ok = 2; /* Login/Usercode failed */ debug(29, 4) ("authenticateNTLMHandleReply: Error validating user via NTLM. Error returned '%s'\n", reply); if ((t = strchr(reply, ' '))) /* strip after a space */ *t = '\0'; @@ -624,7 +600,7 @@ authenticateNTLMHandleReply(void *data, void *lastserver, char *reply) debug(29, 1) ("authenticateNTLMHandleReply: *** Unsupported helper response ***, '%s'\n", reply); /* restart the authentication process */ ntlm_request->auth_state = AUTHENTICATE_STATE_NONE; - auth_user->flags.credentials_ok = 3; /* cannot process */ + ntlm_request->flags.credentials_ok = 3; /* cannot process */ assert (ntlm_request->authserver ? ntlm_request->authserver == lastserver : 1); ntlm_request->authserver = NULL; } @@ -987,7 +963,7 @@ authenticateNTLMAuthenticateUser(auth_user_request_t * auth_user_request, reques case AUTHENTICATE_STATE_NONE: /* we've recieved a negotiate request. pass to a helper */ debug(29, 9) ("authenticateNTLMAuthenticateUser: auth state ntlm none. %s\n", proxy_auth); - if (auth_user->flags.credentials_ok == 2) { + if (ntlm_request->flags.credentials_ok == 2) { /* the authentication fialed badly... */ return; } @@ -1047,7 +1023,7 @@ authenticateNTLMAuthenticateUser(auth_user_request_t * auth_user_request, reques /* get the existing entries details */ ntlm_user = auth_user->scheme_data; debug(29, 9) ("Username to be used is %s\n", ntlm_user->username); - auth_user->flags.credentials_ok = 1; /* authenticated ok */ + ntlm_request->flags.credentials_ok = 1; /* authenticated ok */ /* on ntlm auth we do not unlock the auth_user until the * connection is dropped. Thank MS for this quirk */ auth_user->expiretime = current_time.tv_sec; @@ -1093,7 +1069,7 @@ authenticateNTLMAuthenticateUser(auth_user_request_t * auth_user_request, reques /* set these to now because this is either a new login from an * existing user or a new user */ auth_user->expiretime = current_time.tv_sec; - auth_user->flags.credentials_ok = 1; /*authenticated ok */ + ntlm_request->flags.credentials_ok = 1; /*authenticated ok */ return; break; case AUTHENTICATE_STATE_DONE: diff --git a/src/auth/ntlm/auth_ntlm.h b/src/auth/ntlm/auth_ntlm.h index 4706c218a2..db5ab32df4 100644 --- a/src/auth/ntlm/auth_ntlm.h +++ b/src/auth/ntlm/auth_ntlm.h @@ -22,6 +22,9 @@ struct _ntlm_user { }; struct _ntlm_request { + struct { + unsigned int credentials_ok:2; /*0=unchecked,1=ok,2=failed */ + } flags; /* what negotiate string did the client use? */ char *ntlmnegotiate; /* what challenge did we give the client? */ diff --git a/src/authenticate.cc b/src/authenticate.cc index d34bed0aeb..a2ac2efa92 100644 --- a/src/authenticate.cc +++ b/src/authenticate.cc @@ -1,6 +1,6 @@ /* - * $Id: authenticate.cc,v 1.28 2001/08/29 14:57:34 robertc Exp $ + * $Id: authenticate.cc,v 1.29 2001/09/03 10:33:02 robertc Exp $ * * DEBUG: section 29 Authenticator * AUTHOR: Duane Wessels @@ -467,7 +467,7 @@ authenticateAuthenticate(auth_user_request_t ** auth_user_request, http_hdr_type if (proxy_auth && conn->auth_user_request && authenticateUserAuthenticated(conn->auth_user_request) && strcmp(proxy_auth, authscheme_list[conn->auth_user_request->auth_user->auth_module - 1].authConnLastHeader(conn->auth_user_request))) { - debug(28, 1) ("authenticateAuthenticate: DUPLICATE AUTH - authentication header on already authenticated connection!. AU %x, Current user '%s' proxy_auth %s\n", conn->auth_user_request, authenticateUserRequestUsername(conn->auth_user_request), proxy_auth); + debug(28, 2) ("authenticateAuthenticate: DUPLICATE AUTH - authentication header on already authenticated connection!. AU %x, Current user '%s' proxy_auth %s\n", conn->auth_user_request, authenticateUserRequestUsername(conn->auth_user_request), proxy_auth); /* remove this request struct - the link is already authed and it can't be to * reauth. */ diff --git a/src/structs.h b/src/structs.h index 14dcfbbfc8..560a24d30e 100644 --- a/src/structs.h +++ b/src/structs.h @@ -1,6 +1,6 @@ /* - * $Id: structs.h,v 1.397 2001/08/29 14:57:35 robertc Exp $ + * $Id: structs.h,v 1.398 2001/09/03 10:33:02 robertc Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -111,11 +111,9 @@ struct _auth_user_t { /* we may have many proxy-authenticate strings that decode to the same user */ dlink_list proxy_auth_list; dlink_list proxy_match_cache; + /* what ip addresses has this user been seen at?, plus a list length cache */ dlink_list ip_list; size_t ipcount; - struct { - unsigned int credentials_ok:2; /*0=unchecked,1=ok,2=failed */ - } flags; long expiretime; /* how many references are outstanding to this instance */ size_t references;