--------------------- PatchSet 1215 Date: 2001/01/09 13:06:13 Author: rbcollins Branch: auth_digest Tag: (none) Log: TODO implementations Members: src/auth/digest/auth_digest.c:1.1.2.13->1.1.2.14 Index: squid/src/auth/digest/auth_digest.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/auth/digest/auth_digest.c,v retrieving revision 1.1.2.13 retrieving revision 1.1.2.14 diff -u -r1.1.2.13 -r1.1.2.14 --- squid/src/auth/digest/auth_digest.c 8 Jan 2001 23:26:07 -0000 1.1.2.13 +++ squid/src/auth/digest/auth_digest.c 9 Jan 2001 13:06:13 -0000 1.1.2.14 @@ -210,8 +210,26 @@ void authenticateDigestNonceShutdown() { - /* TODO: clean and empty the cache*/ - memPoolDestroy(digest_nonce_pool); + /* + * We empty the cache of any nonces left in there. + */ + digest_nonce_h *nonce; + debug(29,2)("authenticateDigestNonceShutdown: Shutting down nonce cache \n"); + hash_first(digest_nonce_cache); + while ((nonce=((digest_nonce_h *)hash_next(digest_nonce_cache)))) { + assert (nonce->flags.incache); + hash_remove_link(digest_nonce_cache, (hash_link *)nonce); + nonce->flags.incache=0; + /* the cache's link */ + authDigestNonceUnlink(nonce); + } + if (digest_nonce_pool) + { + assert(memPoolInUseCount(digest_nonce_pool)==0); + memPoolDestroy(digest_nonce_pool); + digest_nonce_pool=NULL; + } + debug(29,2)("authenticateDigestNonceShutdown: Nonce cache shutdown\n"); } void authenticateDigestNonceReconfigure() @@ -239,6 +257,7 @@ debug(29,4)("authenticateDigestNonceCacheCleanup: Removing nonce %s from cache due to timeout.\n",nonce->nonceb64); assert (nonce->flags.incache); hash_remove_link(digest_nonce_cache, (hash_link *)nonce); + nonce->flags.incache=0; /* the cache's link */ authDigestNonceUnlink(nonce); } @@ -268,13 +287,13 @@ { assert(nonce != NULL); if (nonce->references > 0) { - auth_user->references--; + nonce->references--; } else { debug(29, 1) ("authDigestNonceUnlink; Attempt to lower nonce %d refcount below 0!\n", nonce); } debug(29, 9) ("authDigestNonceUnlink: nonce '%d' now at '%d'.\n", nonce, nonce->references); if (nonce->references == 0) - authDigestNonceDelete(nonce); + authenticateDigestNonceDelete(nonce); } const char * @@ -420,7 +439,23 @@ void authDigestUserShutdown() { - memPoolDestroy(digest_user_pool); + auth_user_hash_pointer *usernamehash; + auth_user_t *auth_user; + hash_first(proxy_auth_username_cache); + while ((usernamehash = ((auth_user_hash_pointer *) hash_next(proxy_auth_username_cache)))) { + auth_user = usernamehash->auth_user; + if (strcmp(authscheme_list[auth_user->auth_module-1].typestr,"digest")==0) + /* it's digest */ + { + authenticateAuthUserUnlock(auth_user); + } + } + if (digest_user_pool) + { + assert(memPoolInUseCount(digest_user_pool)==0); + memPoolDestroy(digest_user_pool); + digest_user_pool = NULL; + } } @@ -479,7 +514,13 @@ void authDigestRequestShutdown() { - memPoolDestroy(digest_request_pool); + /* No requests should be in progress when we get here */ + if (digest_request_pool) + { + assert(memPoolInUseCount(digest_request_pool)==0); + memPoolDestroy(digest_request_pool); + digest_request_pool = NULL; + } } @@ -494,11 +535,15 @@ authenticateDigestNonceReconfigure(); return; } - helperFree(digestauthenticators); - digestauthenticators = NULL; + if (digestauthenticators) + { + helperFree(digestauthenticators); + digestauthenticators = NULL; + } authDigestUserShutdown(); authDigestRequestShutdown(); authenticateDigestNonceShutdown(); + debug(29,2)("authenticateDigestDone: Digest authentication shut down.\n"); } static void @@ -506,6 +551,7 @@ { auth_digest_config *config = scheme->scheme_data; wordlist *list = config->authenticate; + debug(29,9)("authDigestCfgDump: Dumping configuration\n"); storeAppendPrintf(entry, "%s %s", name, "digest"); while (list != NULL) { storeAppendPrintf(entry, " %s", list->key); @@ -517,7 +563,6 @@ name, "digest", config->noncemaxuses, name, "digest", config->noncemaxduration, name, "digest", config->nonceGCInterval); - } void @@ -526,6 +571,7 @@ authscheme->Active =authenticateDigestActive; authscheme->parse =authDigestParse; authscheme->freeconfig =authDigestFreeConfig; + authscheme->dump =authDigestCfgDump; authscheme->init =authDigestInit; authscheme->authAuthenticate = authenticateDigestAuthenticateUser; authscheme->authenticated= authDigestAuthenticated; @@ -599,7 +645,9 @@ if (digest_request->nonce==NULL) { /* this isn't a nonce we issued */ - /* TODO: record breaks in authentication at the request level */ + /* TODO: record breaks in authentication at the request level + * This is probably best done with support changes at the auth_rewrite level -RBC + */ auth_user->flags.credentials_ok=3; return; } @@ -675,7 +723,7 @@ if ((digestConfig->authenticate) && authDigestNonceLastRequest(digest_request->nonce)) { - digest_request->flags.authinfo_sent; + digest_request->flags.authinfo_sent=1; debug(29, 5) ("authDigestAddHead: Sending type:%d header: 'nextnonce=\"%s\"",type,authenticateDigestNonceNonceb64(digest_request->nonce)); httpHeaderPutStrf(&rep->header, type, "nextnonce=\"%s\"",authenticateDigestNonceNonceb64(digest_request->nonce)); } @@ -731,31 +779,22 @@ void authenticateDigestUserFree(auth_user_t *auth_user) { digest_user_h * digest_user = auth_user->scheme_data; -#if 0 dlink_node *link,*tmplink; -#endif debug(29,6) ("authenticateDigestFreeUser: Clearing Digest scheme data\n"); if (!digest_user) return; -/* TODO the whole shebang - * - * logic: free all the user specific details. auth_rewrite takes care of freeing - * each request if a nonce is referenced don't free the nonce - */ - - if (digest_user->username) - xfree(digest_user->username); + safe_free(digest_user->username); /* currently the nonces aren't linked in */ -#if 0 link=digest_user->nonces.head; while (link) { tmplink=link; link=link->next; - + dlinkDelete(tmplink, &digest_user->nonces); + authDigestNonceUnlink(tmplink->data); + dlinkNodeDelete(tmplink); } -#endif memPoolFree(digest_user_pool, auth_user->scheme_data); auth_user->scheme_data = NULL; @@ -896,6 +935,29 @@ helperStats(sentry, digestauthenticators); } +/* authDigestUserLinkNonce: add a nonce to a given user's struct */ + +void +authDigestUserLinkNonce(auth_user_t *auth_user, digest_nonce_h *nonce) +{ + dlink_node *node; + digest_user_h * digest_user; + if (!auth_user || !nonce) + return; + if (!auth_user->scheme_data) + return; + digest_user=auth_user->scheme_data; + node=digest_user->nonces.head; + while (node && (node->data != nonce)) + node=node->next; + if (node) + return; + node=dlinkNodeNew(); + dlinkAddTail(nonce,node,&digest_user->nonces); + authDigestNonceLink(nonce); +} + + /* authenticateDigestUsername: return a pointer to the username in the */ char * @@ -1198,6 +1260,12 @@ /* store user in hash's */ debug(29,4)("authenticateDigestAuthenticateuser: user '%s' is not in the user cache\n", digest_user->username); authenticateUserNameCacheAdd(auth_user); + /* + * Add the digest to the user so we can tell if a hacking or spoofing attack + * is taking place. We do this by assuming the user agent won't change user + * name without warning. + */ + authDigestUserLinkNonce(auth_user,nonce); } else {