--------------------- PatchSet 1208 Date: 2001/01/08 23:26:07 Author: rbcollins Branch: auth_digest Tag: (none) Log: code tidyup and consistency checking/cache cleaning Members: src/authenticate.c:1.1.1.3.12.17.2.11.2.14->1.1.1.3.12.17.2.11.2.15 src/cf.data.pre:1.1.1.3.4.1.2.18.2.4.2.13->1.1.1.3.4.1.2.18.2.4.2.14 src/auth/basic/helpers/MSNT/smblib.c.patch:1.3.2.1->1.3.2.2(DEAD) src/auth/digest/Makefile.in:1.1.2.2->1.1.2.3 src/auth/digest/auth_digest.c:1.1.2.12->1.1.2.13 src/auth/digest/auth_digest.h:1.1.2.5->1.1.2.6 Index: squid/src/authenticate.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/authenticate.c,v retrieving revision 1.1.1.3.12.17.2.11.2.14 retrieving revision 1.1.1.3.12.17.2.11.2.15 diff -u -r1.1.1.3.12.17.2.11.2.14 -r1.1.1.3.12.17.2.11.2.15 --- squid/src/authenticate.c 8 Jan 2001 14:31:18 -0000 1.1.1.3.12.17.2.11.2.14 +++ squid/src/authenticate.c 8 Jan 2001 23:26:07 -0000 1.1.1.3.12.17.2.11.2.15 @@ -1,6 +1,6 @@ /* - * $Id: authenticate.c,v 1.1.1.3.12.17.2.11.2.14 2001/01/08 14:31:18 rbcollins Exp $ + * $Id: authenticate.c,v 1.1.1.3.12.17.2.11.2.15 2001/01/08 23:26:07 rbcollins Exp $ * * DEBUG: section 29 Authenticator * AUTHOR: Duane Wessels @@ -405,50 +405,6 @@ } } -#if 0 -void -authenticateFixHeader(HttpReply * rep, ErrorState * err) -/* send the auth types we are configured to support (and have compiled in!) */ -{ -/* auth_type_t auth_type=err->auth_type; - * auth_state_t auth_state=err->auth_state; - * char *authchallenge=err->authchallenge; - */ auth_user_request_t *auth_user_request = err->auth_user_request; - int type; - switch (err->http_status) { - case HTTP_PROXY_AUTHENTICATION_REQUIRED: - /* Proxy authorisation needed */ - type = HDR_PROXY_AUTHENTICATE; - break; - case HTTP_UNAUTHORIZED: - /* WWW Authorisation needed */ - type = HDR_WWW_AUTHENTICATE; - break; - default: - /* Keep GCC happy */ - /* some other HTTP status */ - return; - break; - } - debug(29, 9) ("authenticateFixHeader: headertype:%d authuser:%d\n", type, auth_user_request); - if ((auth_user_request != NULL) && (auth_user_request->auth_user->auth_module > 0)) - authscheme_list[auth_user_request->auth_user->auth_module - 1].authFixHeader(auth_user_request, rep, type, err->request); - else { - int i; - authScheme *scheme; - /* call each configured authscheme */ - for (i = 0; i < Config.authConfig.n_configured; i++) { - scheme = Config.authConfig.schemes + i; - if (authscheme_list[scheme->Id].Active()) - authscheme_list[scheme->Id].authFixHeader(auth_user_request, rep, type, - err->request); - else - debug(29, 8) ("authenticateFixHeader: Configured scheme %s not Active\n", scheme->typestr); - } - } -} -#endif - void authenticateFixHeader(HttpReply * rep, auth_user_request_t * auth_user_request, request_t * request, int accelerated) /* send the auth types we are configured to support (and have compiled in!) */ Index: squid/src/cf.data.pre =================================================================== RCS file: /cvsroot/squid-sf//squid/src/cf.data.pre,v retrieving revision 1.1.1.3.4.1.2.18.2.4.2.13 retrieving revision 1.1.1.3.4.1.2.18.2.4.2.14 diff -u -r1.1.1.3.4.1.2.18.2.4.2.13 -r1.1.1.3.4.1.2.18.2.4.2.14 --- squid/src/cf.data.pre 8 Jan 2001 14:31:18 -0000 1.1.1.3.4.1.2.18.2.4.2.13 +++ squid/src/cf.data.pre 8 Jan 2001 23:26:07 -0000 1.1.1.3.4.1.2.18.2.4.2.14 @@ -1,6 +1,6 @@ # -# $Id: cf.data.pre,v 1.1.1.3.4.1.2.18.2.4.2.13 2001/01/08 14:31:18 rbcollins Exp $ +# $Id: cf.data.pre,v 1.1.1.3.4.1.2.18.2.4.2.14 2001/01/08 23:26:07 rbcollins Exp $ # # # SQUID Internet Object Cache http://squid.nlanr.net/Squid/ @@ -1216,39 +1216,8 @@ "nonce_max_duration" timeinterval Specifies the maximum length of time a given nonce will be valid for. - === NTLM scheme options follow === - - "program" cmdline - Specify the command for the external ntlm authenticator. Such a - program reads a line containing the uuencoded NEGOTIATE and replies - with the ntlm CHALLENGE, then waits for the response and answers with - "OK" or "ERR" in an endless loop. If you use an ntlm authenticator, - make sure you have 1 acl of type proxy_auth. By default, the - ntlm authenticator_program is not used. - - auth_param ntlm program @DEFAULT_PREFIX@/bin/ntlm_auth - - "children" numberofchildren - The number of authenticator processes to spawn (no default). If you - start too few Squid will have to wait for them to process a backlog - of credential verifications, slowing it down. When crendential - verifications are done via a (slow) network you are likely to need - lots of authenticator processes. - auth_param ntlm children 5 - - "max_challenge_reuses" number - The maximum number of times a challenge given by a ntlm authentication - helper can be reused. Increasing this number increases your exposure - to replay attacks on your network. 0 means use the challenge only once. - (disable challenge caching) - See max_ntlm_challenge_lifetime for more information. - auth_param ntlm max_challenge_reuses 0 - - "max_challenge_lifetime" timespan - The maximum time period that a ntlm challenge is reused over. - The actual period will be the minimum of this time AND the number of - reused challenges. - auth_param ntlm max_challenge_lifetime 2 minutes + "nonce_max_count" number + Specifies the maximum number of times a given nonce can be used. === NTLM scheme options follow === @@ -1291,6 +1260,7 @@ auth_paran digest realm Squid proxy-caching web server auth_param digest nonce_garbage_interval 5 minutes auth_param digest nonce_max_duration 30 minutes +auth_param digest nonce_max_count 50 #auth_param ntlm program auth_param ntlm children 5 auth_param ntlm max_challenge_reuses 0 --- squid/src/auth/basic/helpers/MSNT/smblib.c.patch Wed Feb 14 00:48:35 2007 +++ /dev/null Wed Feb 14 00:45:56 2007 @@ -1,25 +0,0 @@ -7a8,9 -> (2000/02/11) Added some tricks to SMB_Logon_Server to control logons of users with illegal name -> Vadim A. Popov -520c522 -< ---- -> -523a526,542 -> return(SMBlibE_BAD); -> -> } -> -> /* Check out the special case: illegal user reported as Action=0x01 ... */ -> -> if (SVAL(SMB_Hdr(pkt), SMB_ssetpr_act_offset)&&0x01 != 0) { /* Process error */ -> -> #ifdef DEBUG -> fprintf(stderr, "SMB_SessSetupAndX failed with errorclass = %i, Error Code = %i\n", -> CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset), -> SVAL(SMB_Hdr(pkt), SMB_hdr_err_offset)); -> #endif -> -> SMBlib_SMB_Error = IVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset); -> RFCNB_Free_Pkt(pkt); -> SMBlib_errno = SMBlibE_GuestOnly; Index: squid/src/auth/digest/Makefile.in =================================================================== RCS file: /cvsroot/squid-sf//squid/src/auth/digest/Attic/Makefile.in,v retrieving revision 1.1.2.2 retrieving revision 1.1.2.3 diff -u -r1.1.2.2 -r1.1.2.3 --- squid/src/auth/digest/Makefile.in 8 Jan 2001 14:03:22 -0000 1.1.2.2 +++ squid/src/auth/digest/Makefile.in 8 Jan 2001 23:26:07 -0000 1.1.2.3 @@ -1,5 +1,5 @@ # -# Makefile for the UFS storage driver for the Squid Object Cache server +# Makefile for the Digest authentication scheme modulefor the Squid Object Cache server # # $Id$ # 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.12 retrieving revision 1.1.2.13 diff -u -r1.1.2.12 -r1.1.2.13 --- squid/src/auth/digest/auth_digest.c 8 Jan 2001 14:03:22 -0000 1.1.2.12 +++ squid/src/auth/digest/auth_digest.c 8 Jan 2001 23:26:07 -0000 1.1.2.13 @@ -3,7 +3,7 @@ * $Id$ * * DEBUG: section 29 Authenticator - * AUTHOR: Duane Wessels + * AUTHOR: Robert Collins * * SQUID Internet Object Cache http://squid.nlanr.net/Squid/ * ---------------------------------------------------------- @@ -53,10 +53,14 @@ static HLPCB authenticateDigestHandleReply; static AUTHSACTIVE authenticateDigestActive; static AUTHSADDHEADER authDigestAddHeader; +#if WAITING_FOR_TE +static AUTHSADDTRAILER authDigestAddTrailer; +#endif static AUTHSAUTHED authDigestAuthenticated; static AUTHSAUTHUSER authenticateDigestAuthenticateUser; static AUTHSDIRECTION authenticateDigestDirection; static AUTHSDECODE authenticateDigestDecodeAuth; +static AUTHSDUMP authDigestCfgDump; static AUTHSFIXERR authenticateDigestFixHeader; static AUTHSFREE authenticateDigestUserFree; static AUTHSFREECONFIG authDigestFreeConfig; @@ -81,9 +85,6 @@ CBDATA_TYPE(authenticateStateData); -/* strings */ -#define QOP_AUTH "auth" - /* * * Nonce Functions @@ -102,6 +103,9 @@ int authDigestNonceIsStale(digest_nonce_h *nonce); void authDigestNonceEncode(digest_nonce_h *nonce); int authDigestNonceLastRequest(digest_nonce_h *nonce); +void authDigestNonceLink(digest_nonce_h *nonce); +void authDigestNonceUnlink(digest_nonce_h *nonce); +int authDigestNonceLinks(digest_nonce_h *nonce); void authDigestNonceEncode(digest_nonce_h *nonce) @@ -119,22 +123,62 @@ digest_nonce_h *newnonce = memPoolAlloc(digest_nonce_pool); digest_nonce_h *temp; - /* TODO: create from unique data - get rid of random()*10*/ +/* NONCE CREATION - NOTES AND REASONING. RBC 20010108 + === EXCERPT FROM RFC 2617 === + The contents of the nonce are implementation dependent. The quality + of the implementation depends on a good choice. A nonce might, for + example, be constructed as the base 64 encoding of + + time-stamp H(time-stamp ":" ETag ":" private-key) + + where time-stamp is a server-generated time or other non-repeating + value, ETag is the value of the HTTP ETag header associated with + the requested entity, and private-key is data known only to the + server. With a nonce of this form a server would recalculate the + hash portion after receiving the client authentication header and + reject the request if it did not match the nonce from that header + or if the time-stamp value is not recent enough. In this way the + server can limit the time of the nonce's validity. The inclusion of + the ETag prevents a replay request for an updated version of the + resource. (Note: including the IP address of the client in the + nonce would appear to offer the server the ability to limit the + reuse of the nonce to the same client that originally got it. + However, that would break proxy farms, where requests from a single + user often go through different proxies in the farm. Also, IP + address spoofing is not that hard.) + ==== + + Now for my reasoning: + We will not accept a unrecognised nonce->we have all recognisable nonces stored + If we send out unique base64 encodings we guarantee that a given nonce applies + to only one user (barring attacks or really bad timing with expiry and creation). + Using a random component in the nonce allows us to loop to find a unique nonce. + We use H(nonce_data) so the nonce is meaningless to the reciever. + So our nonce looks like base64(H(timestamp,pointertohash,randomdata)) + And even if our randomness is not very random (probably due to bad coding on my + part) we don't really care - the timestamp and memory pointer should provide + enough protection for the users authentication. +*/ + /* create a new nonce */ newnonce->nc=0; newnonce->flags.valid=1; newnonce->noncedata.self=newnonce; newnonce->noncedata.creationtime=current_time.tv_sec; + newnonce->noncedata.randomdata=random(); authDigestNonceEncode(newnonce); /* loop until we get a unique nonce. The nonce creation must have a random factor*/ while ((temp=authenticateDigestNonceFindNonce(newnonce->nonceb64))) { /* create a new nonce */ - newnonce->noncedata.creationtime=current_time.tv_sec; + newnonce->noncedata.randomdata=random(); authDigestNonceEncode(newnonce); } hash_join(digest_nonce_cache, (hash_link *) newnonce); + /* the cache's link */ + authDigestNonceLink(newnonce); + newnonce->flags.incache=1; debug(29,6)("authenticateDigestNonceNew: created nonce %0p at %d\n", newnonce, newnonce->noncedata.creationtime); return newnonce; } @@ -144,8 +188,10 @@ { if (nonce) { - hash_remove_link(digest_nonce_cache, (hash_link *)nonce); - xfree(nonce->nonceb64); + assert(nonce->references == 0); + if (nonce->flags.incache) + hash_remove_link(digest_nonce_cache, (hash_link *)nonce); + safe_free(nonce->nonceb64); memPoolFree(digest_nonce_pool, nonce); } } @@ -158,7 +204,6 @@ { digest_nonce_cache = hash_create((HASHCMP *) strcmp, 7921, hash_string); assert(digest_nonce_cache); - /* TODO: make the GCinvterval digest specific */ eventAdd("Digest none cache maintenance",authenticateDigestNonceCacheCleanup, NULL, digestConfig->nonceGCInterval,1); } } @@ -188,23 +233,49 @@ current_time.tv_sec); hash_first(digest_nonce_cache); while ((nonce=((digest_nonce_h *)hash_next(digest_nonce_cache)))) { - debug(29,6) ("authenticateDigestNonceCacheCleanup: nonce entry : '%s'\n", nonce->nonceb64); - debug(29,6) ("authenticateDigestNonceCacheCleanup: Creation time: %d\n", nonce->noncedata.creationtime); - /* TODO put nonce timeout code into place */ -#if 0 - if (auth_user->expiretime + Config.authenticateTTL <= current_time.tv_sec) { - debug(29,3)("authenticateProxyUserCacheCleanup: Removing user %s from cache due to timeout.\n",username); - if (authenticateAuthUserInuse(auth_user)) - debug(29,3)("authenticateProxyUserCacheCleanup: this cache entry has expired AND has a non-zero ref count.\n"); - else - authenticateFreeProxyAuthUser(auth_user); + debug(29,3) ("authenticateDigestNonceCacheCleanup: nonce entry : '%s'\n", nonce->nonceb64); + debug(29,4) ("authenticateDigestNonceCacheCleanup: Creation time: %d\n", nonce->noncedata.creationtime); + if (authDigestNonceIsStale(nonce)) { + 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); + /* the cache's link */ + authDigestNonceUnlink(nonce); } -#endif } debug(29,6) ("authenticateDigestNonceCacheCleanup: Finished cleaning the nonce cache.\n"); eventAdd("Digest none cache maintenance",authenticateDigestNonceCacheCleanup, NULL, digestConfig->nonceGCInterval,1); } +void +authDigestNonceLink(digest_nonce_h *nonce) +{ + assert(nonce != NULL); + nonce->references++; + debug(29, 9) ("authDigestNonceLink: nonce '%d' now at '%d'.\n", nonce,nonce->references); +} + +int +authDigestNonceLinks(digest_nonce_h *nonce) +{ + if (!nonce) + return -1; + return nonce->references; +} + +void +authDigestNonceUnlink(digest_nonce_h *nonce) +{ + assert(nonce != NULL); + if (nonce->references > 0) { + auth_user->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); +} const char * authenticateDigestNonceNonceb64(digest_nonce_h *nonce) @@ -267,11 +338,17 @@ nonce->flags.valid=0; return -1; } - if (nonce->nc>99999997) + if (nonce->nc>99999998) { - debug (29,6)("authDigestNonceIsStale: Nonce count about to overflow\n"); + debug (29,6)("authDigestNonceIsStale: Nonce count overflow\n"); nonce->flags.valid=0; - return 0; + return -1; + } + if (nonce->nc>digestConfig->noncemaxuses) + { + debug (29,6)("authDigestNoncelastRequest: Nonce count over user limit\n"); + nonce->flags.valid=0; + return -1; } /* seems ok */ return 0; @@ -286,7 +363,12 @@ if (nonce->nc==99999997) { debug (29,6)("authDigestNoncelastRequest: Nonce count about to overflow\n"); - return 0; + return -1; + } + if (nonce->nc==digestConfig->noncemaxuses-1) + { + debug (29,6)("authDigestNoncelastRequest: Nonce count about to hit user limit\n"); + return -1; } /* and other tests are possible. */ return 0; @@ -367,7 +449,7 @@ if (digest_request->response) xfree(digest_request->response); if (digest_request->nonce) - authenticateDigestNonceDelete(digest_request->nonce); + authDigestNonceUnlink(digest_request->nonce); memPoolFree(digest_request_pool, digest_request); } @@ -419,11 +501,27 @@ authenticateDigestNonceShutdown(); } +static void +authDigestCfgDump(StoreEntry * entry, const char *name, authScheme * scheme) +{ + auth_digest_config *config = scheme->scheme_data; + wordlist *list = config->authenticate; + storeAppendPrintf(entry, "%s %s", name, "digest"); + while (list != NULL) { + storeAppendPrintf(entry, " %s", list->key); + list = list->next; + } + storeAppendPrintf(entry, "\n%s %s realm %s\n%s %s children %d\n%s %s nonce_max_count %d\n%s %s nonce_max_duration %d seconds\n%s %s nonce_garbage_interval %d seconds\n", + name, "digest", config->digestAuthRealm, + name, "digest", config->authenticateChildren, + name, "digest", config->noncemaxuses, + name, "digest", config->noncemaxduration, + name, "digest", config->nonceGCInterval); + +} + void authSchemeSetup_digest(authscheme_entry_t *authscheme) { -#if 0 -static int init = 0; -#endif assert(!authdigest_initialised); authscheme->Active =authenticateDigestActive; authscheme->parse =authDigestParse; @@ -434,6 +532,9 @@ authscheme->authFixHeader=authenticateDigestFixHeader; authscheme->FreeUser =authenticateDigestUserFree; authscheme->AddHeader =authDigestAddHeader; +#if WAITING_FOR_TE + authscheme->AddTrailer =authDigestAddTrailer; +#endif authscheme->authStart =authenticateDigestStart; authscheme->authStats =authenticateDigestStats; authscheme->authUserUsername = authenticateDigestUsername; @@ -442,32 +543,15 @@ authscheme->decodeauth =authenticateDigestDecodeAuth; authscheme->donefunc = authDigestDone; authscheme->requestFree = authDigestAURequestFree; -#if 0 - authDigestUserSetup(); - authDigestRequestSetup(); - authenticateDigestNonceSetup(); - authdigest_initialised = 1; - if (digestauthenticators == NULL) - digestauthenticators = helperCreate("digestauthenticator"); - digestauthenticators->cmdline = Config.Program.digestauthenticate; - digestauthenticators->n_to_start = Config.digestauthenticateChildren; - digestauthenticators->ipc_type = IPC_TCP_SOCKET; - helperOpenServers(digestauthenticators); - if (!init) - { - cachemgrRegister("digestauthenticator", "User Authenticator Stats", - authenticateDigestStats, 0, 1); - init++; - } -#endif } int authenticateDigestActive(){ - if (authdigest_initialised) - return 1; - else - return 0; + if ((digestConfig != NULL) && (digestConfig->authenticate != NULL) && + (digestConfig->authenticateChildren != 0) && + (digestConfig->digestAuthRealm != NULL) && (digestConfig->noncemaxduration > -1)) + return 1; + return 0; } int @@ -512,9 +596,6 @@ auth_user_request->auth_user->flags.credentials_ok=2; return; } -#if 0 - debug(29,4)("authenticateDigestAuthenticateuser: user '%s' is in the user cache as auth_user '%d', for us '%d' \n", digest_user->username,auth_user,digest_user->auth_user); -#endif if (digest_request->nonce==NULL) { /* this isn't a nonce we issued */ @@ -539,32 +620,7 @@ return; } -#if 0 - /* this is unneeded now the auth_rewrite code manages the request * user difference */ - /* we have authenticated this request */ - if (auth_user != digest_user->auth_user) - { - /* remove the request auth_user structure */ - authenticateAuthUserUnlock(auth_user); - auth_user = digest_user->auth_user; - /* and reference the existing digest data structure */ - /* lock the old structure for this request */ - authenticateAuthUserLock(auth_user); - } -#endif - - auth_user->flags.credentials_ok=1; - /* TODO: cleanup the digest_request info that is no longer needed */ -#if 0 - /* we have a valid user. Are they in the hash table? */ - if (!auth_user->usernamehash) - { - /* store user in hash's */ - debug(29,4)("authenticateDigestAuthenticateuser: user '%s' is not in the user cache\n", digest_auth->username); - authenticateUserNameCacheAdd(auth_user); - } auth_user->flags.credentials_ok=1; -#endif /* password was checked and did match */ debug(29, 4) ("authenticateDigestAuthenticateuser: user '%s' validated OK\n", digest_user->username); @@ -611,14 +667,49 @@ return; type = accel ? HDR_AUTHENTICATION_INFO : HDR_PROXY_AUTHENTICATION_INFO; +#if WAITING_FOR_TE + /* test for http/1.1 transfer chunked encoding */ + if (chunkedtest) + return; +#endif + if ((digestConfig->authenticate) && authDigestNonceLastRequest(digest_request->nonce)) { + digest_request->flags.authinfo_sent; 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)); } } +#if WAITING_FOR_TE +/* add the [proxy]authorisation header */ +void +authDigestAddTrailer(auth_user_request_t *auth_user_request, HttpReply *rep, int accel) +{ + int type; + digest_request_h *digest_request; + if (!auth_user_request) + return; + digest_request=auth_user_request->scheme_data; + /* has the header already been send? */ + if (digest_request->flags.authinfo_sent) + return; + /* don't add to authentication error pages */ + if ((!accel && rep->sline.status==HTTP_PROXY_AUTHENTICATION_REQUIRED) + || (accel && rep->sline.status==HTTP_UNAUTHORIZED)) + return; + type = accel ? HDR_AUTHENTICATION_INFO : HDR_PROXY_AUTHENTICATION_INFO; + + if ((digestConfig->authenticate) && authDigestNonceLastRequest(digest_request->nonce)) + { + debug(29, 5) ("authDigestAddTrailer: Sending type:%d header: 'nextnonce=\"%s\"",type, authenticateDigestNonceNonceb64(digest_request->nonce)); + httpTrailerPutStrf(&rep->header, type, "nextnonce=\"%s\"",authenticateDigestNonceNonceb64(digest_request->nonce)); + } + +} +#endif + /* add the [www-|Proxy-]authenticate header on a 407 or 401 reply */ void authenticateDigestFixHeader(auth_user_request_t *auth_user_request, HttpReply *rep, http_hdr_type type, request_t * request){ @@ -647,10 +738,10 @@ 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 -*/ + * + * 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); @@ -702,10 +793,6 @@ cbdataUnlock(r->data); if (valid) r->handler(r->data, NULL); -#if 0 - if (valid) - r->handler(r->data, reply); -#endif authenticateStateFree(r); } @@ -767,6 +854,8 @@ digestConfig->nonceGCInterval=5*60; /* 30 minutes */ digestConfig->noncemaxduration=30*60; + /* 50 requests */ + digestConfig->noncemaxuses=50; } digestConfig=scheme->scheme_data; if (strcasecmp(param_str,"program")==0) @@ -790,7 +879,10 @@ { parse_time_t(&digestConfig->noncemaxduration); } - else + else if (strcasecmp(param_str,"nonce_max_count")==0) + { + parse_int(&digestConfig->noncemaxuses); + } else { debug(28,0)("unrecognised digest auth scheme parameter '%s'\n",param_str); } @@ -1012,6 +1104,7 @@ digest_request->nonce=nonce; /* increment the nonce count */ nonce->nc++; + authDigestNonceLink(nonce); /* check the qop is what we expected */ if (digest_request->qop && strcmp(digest_request->qop, QOP_AUTH)) @@ -1126,31 +1219,6 @@ digest_request->uri, digest_request->nonceb64, digest_request->nc, digest_request->cnonce, digest_request->response,nonce); - - -#if 0 - if (*cleartext == '\0') { - debug(29, 2) ("authenticateDigestDecodeAuth: Disallowing empty password," - "user is '%s'\n", digest_auth->username); - auth_user->auth_type = AUTH_BROKEN; - } - /* special case: we have to free the strings for user and password - * if we are not returning AUTH_DIGEST else the UserFree function will - * be confused. - */ - if (auth_user->auth_type != AUTH_DIGEST) - { - if (digest_auth->username) - xfree(digest_auth->username); - memPoolFree(digest_data_pool, digest_auth); - auth_user->scheme_data = NULL; - } else { -// digest_auth->passwd = xstrndup(cleartext, USER_IDENT_SZ); - } - /* we are finished with the proxy_auth */ -// xfree(auth_user->proxy_auth); -// auth_user->proxy_auth = NULL; -#endif return; } Index: squid/src/auth/digest/auth_digest.h =================================================================== RCS file: /cvsroot/squid-sf//squid/src/auth/digest/auth_digest.h,v retrieving revision 1.1.2.5 retrieving revision 1.1.2.6 diff -u -r1.1.2.5 -r1.1.2.6 --- squid/src/auth/digest/auth_digest.h 4 Jan 2001 15:17:48 -0000 1.1.2.5 +++ squid/src/auth/digest/auth_digest.h 8 Jan 2001 23:26:07 -0000 1.1.2.6 @@ -24,17 +24,8 @@ char *username; HASH HA1; int HA1created; -#if 0 - /* workaround for incorrect division in the auth_user types - * it points to the auth_user struct that has all the acl caching going on */ - auth_user_t *auth_user; -#endif /* what nonces have been allocated to this user*/ dlink_list nonces; -#if 0 - /* what digest requests are in progress for this user */ - dlink_list requests; -#endif }; /* the digest_request structure is what follows the http_request around */ @@ -49,9 +40,9 @@ char * qop;// = "auth"; char *uri;// = "/dir/index.html"; char *response; -#if 0 - digest_user_h *user; -#endif + struct { + unsigned int authinfo_sent:1; + } flags; digest_nonce_h *nonce; }; @@ -60,6 +51,7 @@ time_t creationtime; /* in memory address of the nonce struct (similar purpose to an ETag) */ digest_nonce_h *self; + long randomdata; }; /* the nonce structure we'll pass around */ @@ -70,9 +62,12 @@ digest_nonce_data noncedata; /* number of uses we've seen of this nonce */ long nc; + /* reference count */ + short references; /* has this nonce been invalidated ? */ struct { - unsigned int valid:1; + unsigned int valid:1; + unsigned int incache:1; } flags; }; @@ -83,8 +78,12 @@ wordlist *authenticate; time_t nonceGCInterval; time_t noncemaxduration; + int noncemaxuses; }; typedef struct _auth_digest_config auth_digest_config; +/* strings */ +#define QOP_AUTH "auth" + #endif