--------------------- PatchSet 1544 Date: 2001/02/10 17:32:48 Author: hno Branch: auth_rewrite Tag: (none) Log: ran indent Members: include/rfc2617.h:1.1.20.1->1.1.20.2 lib/rfc2617.c:1.1.20.1->1.1.20.2 src/acl.c:1.1.1.3.12.26.2.40->1.1.1.3.12.26.2.41 src/protos.h:1.1.1.3.12.17.2.24->1.1.1.3.12.17.2.25 src/auth/basic/auth_basic.c:1.1.2.31->1.1.2.32 src/auth/digest/auth_digest.c:1.1.20.2->1.1.20.3 src/auth/digest/auth_digest.h:1.1.20.1->1.1.20.2 src/auth/digest/helpers/password/digest_pw_auth.c:1.1.8.1->1.1.8.2 src/auth/ntlm/auth_ntlm.c:1.1.2.35->1.1.2.36 src/auth/ntlm/helpers/NTLMSSP/libntlmssp.c:1.1.2.5->1.1.2.6 src/auth/ntlm/helpers/NTLMSSP/ntlm.h:1.1.2.4->1.1.2.5 src/auth/ntlm/helpers/NTLMSSP/ntlm_auth.c:1.1.2.11->1.1.2.12 src/auth/ntlm/helpers/NTLMSSP/smbval/smblib.c:1.1.2.3->1.1.2.4 Index: squid/include/rfc2617.h =================================================================== RCS file: /cvsroot/squid-sf//squid/include/rfc2617.h,v retrieving revision 1.1.20.1 retrieving revision 1.1.20.2 diff -u -r1.1.20.1 -r1.1.20.2 --- squid/include/rfc2617.h 23 Jan 2001 23:03:53 -0000 1.1.20.1 +++ squid/include/rfc2617.h 10 Feb 2001 17:32:48 -0000 1.1.20.2 @@ -54,32 +54,32 @@ #define HASHLEN 16 typedef char HASH[HASHLEN]; #define HASHHEXLEN 32 -typedef char HASHHEX[HASHHEXLEN+1]; +typedef char HASHHEX[HASHHEXLEN + 1]; /* calculate H(A1) as per HTTP Digest spec */ void DigestCalcHA1( - const char * pszAlg, - const char * pszUserName, - const char * pszRealm, - const char * pszPassword, - const char * pszNonce, - const char * pszCNonce, + const char *pszAlg, + const char *pszUserName, + const char *pszRealm, + const char *pszPassword, + const char *pszNonce, + const char *pszCNonce, HASH HA1, HASHHEX SessionKey - ); +); /* calculate request-digest/response-digest as per HTTP Digest spec */ void DigestCalcResponse( - const HASHHEX HA1, /* H(A1) */ - const char * pszNonce, /* nonce from server */ - const char * pszNonceCount, /* 8 hex digits */ - const char * pszCNonce, /* client nonce */ - const char * pszQop, /* qop-value: "", "auth", "auth-int" */ - const char * pszMethod, /* method from the request */ - const char * pszDigestUri, /* requested URL */ - const HASHHEX HEntity, /* H(entity body) if qop="auth-int" */ - HASHHEX Response /* request-digest or response-digest */ - ); + const HASHHEX HA1, /* H(A1) */ + const char *pszNonce, /* nonce from server */ + const char *pszNonceCount, /* 8 hex digits */ + const char *pszCNonce, /* client nonce */ + const char *pszQop, /* qop-value: "", "auth", "auth-int" */ + const char *pszMethod, /* method from the request */ + const char *pszDigestUri, /* requested URL */ + const HASHHEX HEntity, /* H(entity body) if qop="auth-int" */ + HASHHEX Response /* request-digest or response-digest */ +); void CvtHex(const HASH Bin, HASHHEX Hex); Index: squid/lib/rfc2617.c =================================================================== RCS file: /cvsroot/squid-sf//squid/lib/rfc2617.c,v retrieving revision 1.1.20.1 retrieving revision 1.1.20.2 diff -u -r1.1.20.1 -r1.1.20.2 --- squid/lib/rfc2617.c 23 Jan 2001 23:03:53 -0000 1.1.20.1 +++ squid/lib/rfc2617.c 10 Feb 2001 17:32:48 -0000 1.1.20.2 @@ -50,127 +50,128 @@ #include #include "rfc2617.h" -void CvtHex(const HASH Bin, HASHHEX Hex ) +void +CvtHex(const HASH Bin, HASHHEX Hex) { unsigned short i; unsigned char j; for (i = 0; i < HASHLEN; i++) { - j = (Bin[i] >> 4) & 0xf; - if (j <= 9) - Hex[i*2] = (j + '0'); - else - Hex[i*2] = (j + 'a' - 10); - j = Bin[i] & 0xf; - if (j <= 9) - Hex[i*2+1] = (j + '0'); - else - Hex[i*2+1] = (j + 'a' - 10); + j = (Bin[i] >> 4) & 0xf; + if (j <= 9) + Hex[i * 2] = (j + '0'); + else + Hex[i * 2] = (j + 'a' - 10); + j = Bin[i] & 0xf; + if (j <= 9) + Hex[i * 2 + 1] = (j + '0'); + else + Hex[i * 2 + 1] = (j + 'a' - 10); }; Hex[HASHHEXLEN] = '\0'; }; -void CvtBin(const HASHHEX Hex, HASH Bin) +void +CvtBin(const HASHHEX Hex, HASH Bin) { unsigned short i; unsigned char j; for (i = 0; i < HASHHEXLEN; i++) { - j = Hex[i]; - if (('0' <=j) && (j <= '9')) - Bin[i/2] |= ((j - '0') << ((i%2 ==0) ? 4:0)); - else - Bin[i/2] |= ((j - 'a'+10) << ((i%2==0)?4:0)); + j = Hex[i]; + if (('0' <= j) && (j <= '9')) + Bin[i / 2] |= ((j - '0') << ((i % 2 == 0) ? 4 : 0)); + else + Bin[i / 2] |= ((j - 'a' + 10) << ((i % 2 == 0) ? 4 : 0)); }; Bin[HASHLEN] = '\0'; }; /* calculate H(A1) as per spec */ -void DigestCalcHA1( - const char * pszAlg, - const char * pszUserName, - const char * pszRealm, - const char * pszPassword, - const char * pszNonce, - const char * pszCNonce, +void +DigestCalcHA1( + const char *pszAlg, + const char *pszUserName, + const char *pszRealm, + const char *pszPassword, + const char *pszNonce, + const char *pszCNonce, HASH HA1, HASHHEX SessionKey - ) +) { - MD5_CTX Md5Ctx; + MD5_CTX Md5Ctx; - if (pszUserName) - { - MD5Init(&Md5Ctx); - MD5Update(&Md5Ctx, pszUserName, strlen(pszUserName)); - MD5Update(&Md5Ctx, ":", 1); - MD5Update(&Md5Ctx, pszRealm, strlen(pszRealm)); - MD5Update(&Md5Ctx, ":", 1); - MD5Update(&Md5Ctx, pszPassword, strlen(pszPassword)); - MD5Final(HA1, &Md5Ctx); - } - if (stricmp(pszAlg, "md5-sess") == 0) { - MD5Init(&Md5Ctx); - MD5Update(&Md5Ctx, HA1, HASHLEN); - MD5Update(&Md5Ctx, ":", 1); - MD5Update(&Md5Ctx, pszNonce, strlen(pszNonce)); - MD5Update(&Md5Ctx, ":", 1); - MD5Update(&Md5Ctx, pszCNonce, strlen(pszCNonce)); - MD5Final(HA1, &Md5Ctx); - }; - CvtHex(HA1, SessionKey); + if (pszUserName) { + MD5Init(&Md5Ctx); + MD5Update(&Md5Ctx, pszUserName, strlen(pszUserName)); + MD5Update(&Md5Ctx, ":", 1); + MD5Update(&Md5Ctx, pszRealm, strlen(pszRealm)); + MD5Update(&Md5Ctx, ":", 1); + MD5Update(&Md5Ctx, pszPassword, strlen(pszPassword)); + MD5Final(HA1, &Md5Ctx); + } + if (stricmp(pszAlg, "md5-sess") == 0) { + MD5Init(&Md5Ctx); + MD5Update(&Md5Ctx, HA1, HASHLEN); + MD5Update(&Md5Ctx, ":", 1); + MD5Update(&Md5Ctx, pszNonce, strlen(pszNonce)); + MD5Update(&Md5Ctx, ":", 1); + MD5Update(&Md5Ctx, pszCNonce, strlen(pszCNonce)); + MD5Final(HA1, &Md5Ctx); + }; + CvtHex(HA1, SessionKey); }; /* calculate request-digest/response-digest as per HTTP Digest spec */ -void DigestCalcResponse( - const HASHHEX HA1, /* H(A1) */ - const char * pszNonce, /* nonce from server */ - const char * pszNonceCount, /* 8 hex digits */ - const char * pszCNonce, /* client nonce */ - const char * pszQop, /* qop-value: "", "auth", "auth-int" */ - const char * pszMethod, /* method from the request */ - const char * pszDigestUri, /* requested URL */ - const HASHHEX HEntity, /* H(entity body) if qop="auth-int" */ - HASHHEX Response /* request-digest or response-digest */ - ) +void +DigestCalcResponse( + const HASHHEX HA1, /* H(A1) */ + const char *pszNonce, /* nonce from server */ + const char *pszNonceCount, /* 8 hex digits */ + const char *pszCNonce, /* client nonce */ + const char *pszQop, /* qop-value: "", "auth", "auth-int" */ + const char *pszMethod, /* method from the request */ + const char *pszDigestUri, /* requested URL */ + const HASHHEX HEntity, /* H(entity body) if qop="auth-int" */ + HASHHEX Response /* request-digest or response-digest */ +) { - MD5_CTX Md5Ctx; - HASH HA2; - HASH RespHash; - HASHHEX HA2Hex; - - /* calculate H(A2) - */ - MD5Init(&Md5Ctx); - MD5Update(&Md5Ctx, pszMethod, strlen(pszMethod)); - MD5Update(&Md5Ctx, ":", 1); - MD5Update(&Md5Ctx, pszDigestUri, strlen(pszDigestUri)); - if (stricmp(pszQop, "auth-int") == 0) { - MD5Update(&Md5Ctx, ":", 1); - MD5Update(&Md5Ctx, HEntity, HASHHEXLEN); - }; - MD5Final(HA2, &Md5Ctx); - CvtHex(HA2, HA2Hex); - - /* calculate response - */ - MD5Init(&Md5Ctx); - MD5Update(&Md5Ctx, HA1, HASHHEXLEN); - MD5Update(&Md5Ctx, ":", 1); - MD5Update(&Md5Ctx, pszNonce, strlen(pszNonce)); - MD5Update(&Md5Ctx, ":", 1); - if (*pszQop) { - MD5Update(&Md5Ctx, pszNonceCount, strlen(pszNonceCount)); - MD5Update(&Md5Ctx, ":", 1); - MD5Update(&Md5Ctx, pszCNonce, strlen(pszCNonce)); - MD5Update(&Md5Ctx, ":", 1); - MD5Update(&Md5Ctx, pszQop, strlen(pszQop)); - MD5Update(&Md5Ctx, ":", 1); - }; - MD5Update(&Md5Ctx, HA2Hex, HASHHEXLEN); - MD5Final(RespHash, &Md5Ctx); - CvtHex(RespHash, Response); -}; - + MD5_CTX Md5Ctx; + HASH HA2; + HASH RespHash; + HASHHEX HA2Hex; + + /* calculate H(A2) + */ + MD5Init(&Md5Ctx); + MD5Update(&Md5Ctx, pszMethod, strlen(pszMethod)); + MD5Update(&Md5Ctx, ":", 1); + MD5Update(&Md5Ctx, pszDigestUri, strlen(pszDigestUri)); + if (stricmp(pszQop, "auth-int") == 0) { + MD5Update(&Md5Ctx, ":", 1); + MD5Update(&Md5Ctx, HEntity, HASHHEXLEN); + }; + MD5Final(HA2, &Md5Ctx); + CvtHex(HA2, HA2Hex); + /* calculate response + */ + MD5Init(&Md5Ctx); + MD5Update(&Md5Ctx, HA1, HASHHEXLEN); + MD5Update(&Md5Ctx, ":", 1); + MD5Update(&Md5Ctx, pszNonce, strlen(pszNonce)); + MD5Update(&Md5Ctx, ":", 1); + if (*pszQop) { + MD5Update(&Md5Ctx, pszNonceCount, strlen(pszNonceCount)); + MD5Update(&Md5Ctx, ":", 1); + MD5Update(&Md5Ctx, pszCNonce, strlen(pszCNonce)); + MD5Update(&Md5Ctx, ":", 1); + MD5Update(&Md5Ctx, pszQop, strlen(pszQop)); + MD5Update(&Md5Ctx, ":", 1); + }; + MD5Update(&Md5Ctx, HA2Hex, HASHHEXLEN); + MD5Final(RespHash, &Md5Ctx); + CvtHex(RespHash, Response); +}; Index: squid/src/acl.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/acl.c,v retrieving revision 1.1.1.3.12.26.2.40 retrieving revision 1.1.1.3.12.26.2.41 diff -u -r1.1.1.3.12.26.2.40 -r1.1.1.3.12.26.2.41 --- squid/src/acl.c 8 Feb 2001 08:18:54 -0000 1.1.1.3.12.26.2.40 +++ squid/src/acl.c 10 Feb 2001 17:32:48 -0000 1.1.1.3.12.26.2.41 @@ -1,6 +1,8 @@ + + /* - * $Id: acl.c,v 1.1.1.3.12.26.2.40 2001/02/08 08:18:54 rbcollins Exp $ + * $Id: acl.c,v 1.1.1.3.12.26.2.41 2001/02/10 17:32:48 hno Exp $ * * DEBUG: section 28 Access Control * AUTHOR: Duane Wessels Index: squid/src/protos.h =================================================================== RCS file: /cvsroot/squid-sf//squid/src/protos.h,v retrieving revision 1.1.1.3.12.17.2.24 retrieving revision 1.1.1.3.12.17.2.25 diff -u -r1.1.1.3.12.17.2.24 -r1.1.1.3.12.17.2.25 --- squid/src/protos.h 23 Jan 2001 10:14:21 -0000 1.1.1.3.12.17.2.24 +++ squid/src/protos.h 10 Feb 2001 17:32:49 -0000 1.1.1.3.12.17.2.25 @@ -1,6 +1,6 @@ /* - * $Id: protos.h,v 1.1.1.3.12.17.2.24 2001/01/23 10:14:21 rbcollins Exp $ + * $Id: protos.h,v 1.1.1.3.12.17.2.25 2001/02/10 17:32:49 hno Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -744,7 +744,7 @@ extern void authenticateFreeProxyAuthUserACLResults(void *data); extern void authenticateProxyUserCacheCleanup(void *); extern void authenticateInitUserCache(); -#if GLOBALPROXYCACHE +#if GLOBALPROXYCACHE extern void authenticateProxyAuthCacheAddLink(const char *key, auth_user_t *); #endif extern int authenticateActiveSchemeCount(); Index: squid/src/auth/basic/auth_basic.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/auth/basic/auth_basic.c,v retrieving revision 1.1.2.31 retrieving revision 1.1.2.32 diff -u -r1.1.2.31 -r1.1.2.32 --- squid/src/auth/basic/auth_basic.c 30 Jan 2001 12:04:44 -0000 1.1.2.31 +++ squid/src/auth/basic/auth_basic.c 10 Feb 2001 17:32:49 -0000 1.1.2.32 @@ -108,7 +108,7 @@ authscheme->init = authBasicInit; authscheme->authAuthenticate = authenticateBasicAuthenticateUser; authscheme->authenticated = authenticateBasicAuthenticated; - authscheme->configured = authBasicConfigured; + authscheme->configured = authBasicConfigured; authscheme->authFixHeader = authenticateBasicFixErrorHeader; authscheme->FreeUser = authenticateBasicFreeUser; authscheme->freeconfig = authBasicFreeConfig; @@ -124,19 +124,19 @@ int authenticateBasicActive() { - return (authbasic_initialised==1) ? 1:0; + return (authbasic_initialised == 1) ? 1 : 0; } int authBasicConfigured() { if ((basicConfig != NULL) && (basicConfig->authenticate != NULL) && - (basicConfig->authenticateChildren != 0) && + (basicConfig->authenticateChildren != 0) && (basicConfig->basicAuthRealm != NULL)) { - debug(29,9)("authBasicConfigured: returning configured\n"); - return 1; - } - debug(29,9)("authBasicConfigured: returning unconfigured\n"); + debug(29, 9) ("authBasicConfigured: returning configured\n"); + return 1; + } + debug(29, 9) ("authBasicConfigured: returning unconfigured\n"); return 0; } @@ -161,7 +161,7 @@ static void authenticateBasicAuthenticateUser(auth_user_request_t * auth_user_request, request_t * request, ConnStateData * conn, http_hdr_type type) { -#if GLOBALPROXY_CACHE +#if GLOBALPROXY_CACHE auth_user_hash_pointer *usernamehash, *proxy_auth_hash = NULL; #endif auth_user_t *auth_user; 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.20.2 retrieving revision 1.1.20.3 diff -u -r1.1.20.2 -r1.1.20.3 --- squid/src/auth/digest/auth_digest.c 30 Jan 2001 12:04:45 -0000 1.1.20.2 +++ squid/src/auth/digest/auth_digest.c 10 Feb 2001 17:32:49 -0000 1.1.20.3 @@ -34,8 +34,8 @@ */ /* The functions in this file handle authentication. - They DO NOT perform access control or auditing. - See acl.c for access control and client_side.c for auditing */ + * They DO NOT perform access control or auditing. + * See acl.c for access control and client_side.c for auditing */ #include "squid.h" @@ -51,25 +51,25 @@ /* Digest Scheme */ static HLPCB authenticateDigestHandleReply; -static AUTHSACTIVE authenticateDigestActive; +static AUTHSACTIVE authenticateDigestActive; static AUTHSADDHEADER authDigestAddHeader; #if WAITING_FOR_TE static AUTHSADDTRAILER authDigestAddTrailer; #endif -static AUTHSAUTHED authDigestAuthenticated; -static AUTHSAUTHUSER authenticateDigestAuthenticateUser; +static AUTHSAUTHED authDigestAuthenticated; +static AUTHSAUTHUSER authenticateDigestAuthenticateUser; static AUTHSCONFIGURED authDigestConfigured; static AUTHSDIRECTION authenticateDigestDirection; -static AUTHSDECODE authenticateDigestDecodeAuth; -static AUTHSDUMP authDigestCfgDump; -static AUTHSFIXERR authenticateDigestFixHeader; -static AUTHSFREE authenticateDigestUserFree; +static AUTHSDECODE authenticateDigestDecodeAuth; +static AUTHSDUMP authDigestCfgDump; +static AUTHSFIXERR authenticateDigestFixHeader; +static AUTHSFREE authenticateDigestUserFree; static AUTHSFREECONFIG authDigestFreeConfig; -static AUTHSINIT authDigestInit; -static AUTHSPARSE authDigestParse; -static AUTHSREQFREE authDigestAURequestFree; -static AUTHSSTART authenticateDigestStart; -static AUTHSSTATS authenticateDigestStats; +static AUTHSINIT authDigestInit; +static AUTHSPARSE authDigestParse; +static AUTHSREQFREE authDigestAURequestFree; +static AUTHSSTART authenticateDigestStart; +static AUTHSSTATS authenticateDigestStats; static AUTHSUSERNAME authenticateDigestUsername; static AUTHSSHUTDOWN authDigestDone; @@ -92,32 +92,32 @@ * */ -static void authenticateDigestNonceCacheCleanup (void *data); +static void authenticateDigestNonceCacheCleanup(void *data); static digest_nonce_h *authenticateDigestNonceFindNonce(const char *nonceb64); -digest_nonce_h * authenticateDigestNonceNew(); -void authenticateDigestNonceDelete(digest_nonce_h *nonce); +digest_nonce_h *authenticateDigestNonceNew(); +void authenticateDigestNonceDelete(digest_nonce_h * nonce); void authenticateDigestNonceSetup(); void authenticateDigestNonceShutdown(); void authenticateDigestNonceReconfigure(); -const char *authenticateDigestNonceNonceb64(digest_nonce_h *nonce); -int authDigestNonceIsValid(digest_nonce_h *nonce, char nc[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 authDigestNonceUserUnlink(digest_nonce_h *nonce); -void authDigestNoncePurge(digest_nonce_h *nonce); +const char *authenticateDigestNonceNonceb64(digest_nonce_h * nonce); +int authDigestNonceIsValid(digest_nonce_h * nonce, char nc[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 authDigestNonceUserUnlink(digest_nonce_h * nonce); +void authDigestNoncePurge(digest_nonce_h * nonce); void -authDigestNonceEncode(digest_nonce_h *nonce) +authDigestNonceEncode(digest_nonce_h * nonce) { if (!nonce) - return; + return; if (nonce->nonceb64) - xfree(nonce->nonceb64); - nonce->nonceb64=xstrdup(base64_encode_bin((char *)&(nonce->noncedata),sizeof(digest_nonce_data))); + xfree(nonce->nonceb64); + nonce->nonceb64 = xstrdup(base64_encode_bin((char *) &(nonce->noncedata), sizeof(digest_nonce_data))); } digest_nonce_h * @@ -127,118 +127,116 @@ digest_nonce_h *temp; /* 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. -*/ + * === 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(); + 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.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.randomdata = random(); + authDigestNonceEncode(newnonce); } hash_join(digest_nonce_cache, (hash_link *) newnonce); /* the cache's link */ authDigestNonceLink(newnonce); - newnonce->flags.incache=1; - debug(29,5)("authenticateDigestNonceNew: created nonce %0p at %d\n", newnonce, newnonce->noncedata.creationtime); + newnonce->flags.incache = 1; + debug(29, 5) ("authenticateDigestNonceNew: created nonce %0p at %d\n", newnonce, newnonce->noncedata.creationtime); return newnonce; } void -authenticateDigestNonceDelete(digest_nonce_h *nonce) +authenticateDigestNonceDelete(digest_nonce_h * nonce) { - if (nonce) - { - assert(nonce->references == 0); + if (nonce) { + assert(nonce->references == 0); #if UNREACHABLECODE - if (nonce->flags.incache) - hash_remove_link(digest_nonce_cache, (hash_link *)nonce); + if (nonce->flags.incache) + hash_remove_link(digest_nonce_cache, (hash_link *) nonce); #endif - assert (nonce->flags.incache==0); - safe_free(nonce->nonceb64); - memPoolFree(digest_nonce_pool, nonce); + assert(nonce->flags.incache == 0); + safe_free(nonce->nonceb64); + memPoolFree(digest_nonce_pool, nonce); } -} +} -void authenticateDigestNonceSetup() +void +authenticateDigestNonceSetup() { if (!digest_nonce_pool) - digest_nonce_pool = memPoolCreate("Digest Scheme nonce's", sizeof(digest_nonce_h)); - if (!digest_nonce_cache) - { - digest_nonce_cache = hash_create((HASHCMP *) strcmp, 7921, hash_string); - assert(digest_nonce_cache); - eventAdd("Digest none cache maintenance",authenticateDigestNonceCacheCleanup, NULL, digestConfig->nonceGCInterval,1); + digest_nonce_pool = memPoolCreate("Digest Scheme nonce's", sizeof(digest_nonce_h)); + if (!digest_nonce_cache) { + digest_nonce_cache = hash_create((HASHCMP *) strcmp, 7921, hash_string); + assert(digest_nonce_cache); + eventAdd("Digest none cache maintenance", authenticateDigestNonceCacheCleanup, NULL, digestConfig->nonceGCInterval, 1); } } -void authenticateDigestNonceShutdown() +void +authenticateDigestNonceShutdown() { /* * We empty the cache of any nonces left in there. */ digest_nonce_h *nonce; - if (digest_nonce_cache) - { - 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); - authDigestNoncePurge(nonce); - } - } - if (digest_nonce_pool) - { - assert(memPoolInUseCount(digest_nonce_pool)==0); - memPoolDestroy(digest_nonce_pool); - digest_nonce_pool=NULL; + if (digest_nonce_cache) { + 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); + authDigestNoncePurge(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"); + debug(29, 2) ("authenticateDigestNonceShutdown: Nonce cache shutdown\n"); } -void authenticateDigestNonceReconfigure() +void +authenticateDigestNonceReconfigure() { } @@ -251,130 +249,125 @@ * entries at a time. Lets see how it flys first. */ digest_nonce_h *nonce; - debug(29,3) ("authenticateDigestNonceCacheCleanup: Cleaning the nonce cache now\n"); - debug(29,3) ("authenticateDigestNonceCacheCleanup: Current time: %d\n", - current_time.tv_sec); + debug(29, 3) ("authenticateDigestNonceCacheCleanup: Cleaning the nonce cache now\n"); + debug(29, 3) ("authenticateDigestNonceCacheCleanup: Current time: %d\n", + current_time.tv_sec); hash_first(digest_nonce_cache); - while ((nonce=((digest_nonce_h *)hash_next(digest_nonce_cache)))) { - 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); - /* invalidate nonce so future requests fail */ - nonce->flags.valid=0; - /* if it is tied to a auth_user, remove the tie */ - authDigestNonceUserUnlink(nonce); - authDigestNoncePurge(nonce); - } + while ((nonce = ((digest_nonce_h *) hash_next(digest_nonce_cache)))) { + 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); + /* invalidate nonce so future requests fail */ + nonce->flags.valid = 0; + /* if it is tied to a auth_user, remove the tie */ + authDigestNonceUserUnlink(nonce); + authDigestNoncePurge(nonce); + } } - debug(29,3) ("authenticateDigestNonceCacheCleanup: Finished cleaning the nonce cache.\n"); + debug(29, 3) ("authenticateDigestNonceCacheCleanup: Finished cleaning the nonce cache.\n"); if (authenticateDigestActive()) - eventAdd("Digest none cache maintenance",authenticateDigestNonceCacheCleanup, NULL, digestConfig->nonceGCInterval,1); + eventAdd("Digest none cache maintenance", authenticateDigestNonceCacheCleanup, NULL, digestConfig->nonceGCInterval, 1); } void -authDigestNonceLink(digest_nonce_h *nonce) +authDigestNonceLink(digest_nonce_h * nonce) { assert(nonce != NULL); nonce->references++; - debug(29, 9) ("authDigestNonceLink: nonce '%d' now at '%d'.\n", nonce,nonce->references); + debug(29, 9) ("authDigestNonceLink: nonce '%d' now at '%d'.\n", nonce, nonce->references); } int -authDigestNonceLinks(digest_nonce_h *nonce) +authDigestNonceLinks(digest_nonce_h * nonce) { if (!nonce) - return -1; + return -1; return nonce->references; } void -authDigestNonceUnlink(digest_nonce_h *nonce) +authDigestNonceUnlink(digest_nonce_h * nonce) { assert(nonce != NULL); if (nonce->references > 0) { - nonce->references--; + nonce->references--; } else { - debug(29, 1) ("authDigestNonceUnlink; Attempt to lower nonce %d refcount below 0!\n", nonce); + 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) - authenticateDigestNonceDelete(nonce); + authenticateDigestNonceDelete(nonce); } const char * -authenticateDigestNonceNonceb64(digest_nonce_h *nonce) +authenticateDigestNonceNonceb64(digest_nonce_h * nonce) { if (!nonce) - return NULL; + return NULL; return nonce->nonceb64; } digest_nonce_h * authenticateDigestNonceFindNonce(const char *nonceb64) { - digest_nonce_h *nonce=NULL; - if (nonceb64==NULL) - return NULL; - debug(29,9)("authDigestNonceFindNonce:looking for nonceb64 '%s' in the nonce cache.\n",nonceb64); - if ((nonce = hash_lookup(digest_nonce_cache, nonceb64))) - while ((strcmp(nonce->nonceb64,nonceb64)) && (nonce->next)) - nonce=nonce->next; - if ((nonce == NULL) || (strcmp(nonce->nonceb64,nonceb64))) - return NULL; - debug(29,9)("authDigestNonceFindNonce: Found nonce '%d'\n",nonce); + digest_nonce_h *nonce = NULL; + if (nonceb64 == NULL) + return NULL; + debug(29, 9) ("authDigestNonceFindNonce:looking for nonceb64 '%s' in the nonce cache.\n", nonceb64); + if ((nonce = hash_lookup(digest_nonce_cache, nonceb64))) + while ((strcmp(nonce->nonceb64, nonceb64)) && (nonce->next)) + nonce = nonce->next; + if ((nonce == NULL) || (strcmp(nonce->nonceb64, nonceb64))) + return NULL; + debug(29, 9) ("authDigestNonceFindNonce: Found nonce '%d'\n", nonce); return nonce; } int -authDigestNonceIsValid(digest_nonce_h *nonce,char nc[9]) +authDigestNonceIsValid(digest_nonce_h * nonce, char nc[9]) { int intnc; /* do we have a nonce ? */ if (!nonce) - return 0; - intnc=atoi(nc); - if (intnc != nonce->nc+1) - { - debug (29,4)("authDigestNonceIsValid: Nonce count doesn't match\n"); - nonce->flags.valid=0; - return 0; + return 0; + intnc = atoi(nc); + if (intnc != nonce->nc + 1) { + debug(29, 4) ("authDigestNonceIsValid: Nonce count doesn't match\n"); + nonce->flags.valid = 0; + return 0; } /* has it already been invalidated ? */ - if (!nonce->flags.valid) - { - debug (29,4)("authDigestNonceIsValid: Nonce already invalidated\n"); - return 0; + if (!nonce->flags.valid) { + debug(29, 4) ("authDigestNonceIsValid: Nonce already invalidated\n"); + return 0; } /* seems ok */ return -1; } int -authDigestNonceIsStale(digest_nonce_h *nonce) +authDigestNonceIsStale(digest_nonce_h * nonce) { /* do we have a nonce ? */ if (!nonce) - return -1; + return -1; /* has it's max duration expired? */ - if (nonce->noncedata.creationtime + digestConfig->noncemaxduration < current_time.tv_sec) - { - debug (29,4)("authDigestNonceIsStale: Nonce is too old. %d %d %d\n", nonce->noncedata.creationtime,digestConfig->noncemaxduration , current_time.tv_sec); - nonce->flags.valid=0; - return -1; - } - if (nonce->nc>99999998) - { - debug (29,4)("authDigestNonceIsStale: Nonce count overflow\n"); - nonce->flags.valid=0; - return -1; - } - if (nonce->nc>digestConfig->noncemaxuses) - { - debug (29,4)("authDigestNoncelastRequest: Nonce count over user limit\n"); - nonce->flags.valid=0; - return -1; + if (nonce->noncedata.creationtime + digestConfig->noncemaxduration < current_time.tv_sec) { + debug(29, 4) ("authDigestNonceIsStale: Nonce is too old. %d %d %d\n", nonce->noncedata.creationtime, digestConfig->noncemaxduration, current_time.tv_sec); + nonce->flags.valid = 0; + return -1; + } + if (nonce->nc > 99999998) { + debug(29, 4) ("authDigestNonceIsStale: Nonce count overflow\n"); + nonce->flags.valid = 0; + return -1; + } + if (nonce->nc > digestConfig->noncemaxuses) { + debug(29, 4) ("authDigestNoncelastRequest: Nonce count over user limit\n"); + nonce->flags.valid = 0; + return -1; } /* seems ok */ return 0; @@ -382,63 +375,59 @@ /* return -1 if the digest will be stale on the next request */ int -authDigestNonceLastRequest(digest_nonce_h *nonce) +authDigestNonceLastRequest(digest_nonce_h * nonce) { if (!nonce) - return -1; - if (nonce->nc==99999997) - { - debug (29,4)("authDigestNoncelastRequest: Nonce count about to overflow\n"); - return -1; - } - if (nonce->nc==digestConfig->noncemaxuses-1) - { - debug (29,4)("authDigestNoncelastRequest: Nonce count about to hit user limit\n"); - return -1; + return -1; + if (nonce->nc == 99999997) { + debug(29, 4) ("authDigestNoncelastRequest: Nonce count about to overflow\n"); + return -1; + } + if (nonce->nc == digestConfig->noncemaxuses - 1) { + debug(29, 4) ("authDigestNoncelastRequest: Nonce count about to hit user limit\n"); + return -1; } /* and other tests are possible. */ return 0; } void -authDigestNoncePurge(digest_nonce_h *nonce) +authDigestNoncePurge(digest_nonce_h * nonce) { if (!nonce) - return; + return; if (!nonce->flags.incache) - return; - hash_remove_link(digest_nonce_cache, (hash_link *)nonce); - nonce->flags.incache=0; + return; + hash_remove_link(digest_nonce_cache, (hash_link *) nonce); + nonce->flags.incache = 0; /* the cache's link */ - authDigestNonceUnlink(nonce); + authDigestNonceUnlink(nonce); } /* USER related functions */ int -authDigestUsercmpname(digest_user_h * u1, digest_user_h *u2) +authDigestUsercmpname(digest_user_h * u1, digest_user_h * u2) { - return strcmp(u1->username,u2->username); + return strcmp(u1->username, u2->username); } auth_user_t * -authDigestUserFindUsername(const char * username) +authDigestUserFindUsername(const char *username) { auth_user_hash_pointer *usernamehash; auth_user_t *auth_user; - debug(29,9)("authDigestUserFindUsername: Looking for user '%s'\n",username); - if (username && (usernamehash = hash_lookup(proxy_auth_username_cache, username))) - { - while ((usernamehash->auth_user->auth_type != AUTH_DIGEST) && - (usernamehash->next)) - usernamehash=usernamehash->next; - auth_user=NULL; - if (usernamehash->auth_user->auth_type==AUTH_DIGEST) - { - auth_user=usernamehash->auth_user; - } - return auth_user; + debug(29, 9) ("authDigestUserFindUsername: Looking for user '%s'\n", username); + if (username && (usernamehash = hash_lookup(proxy_auth_username_cache, username))) { + while ((usernamehash->auth_user->auth_type != AUTH_DIGEST) && + (usernamehash->next)) + usernamehash = usernamehash->next; + auth_user = NULL; + if (usernamehash->auth_user->auth_type == AUTH_DIGEST) { + auth_user = usernamehash->auth_user; + } + return auth_user; } return NULL; } @@ -453,7 +442,7 @@ authDigestUserSetup() { if (!digest_user_pool) - digest_user_pool = memPoolCreate("Digest Scheme User Data", sizeof(digest_user_h)); + digest_user_pool = memPoolCreate("Digest Scheme User Data", sizeof(digest_user_h)); } void @@ -466,16 +455,15 @@ 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; + 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; } } @@ -484,44 +472,44 @@ /* delete the digest reuqest structure. Does NOT delete related structures */ void -authDigestRequestDelete(digest_request_h *digest_request) +authDigestRequestDelete(digest_request_h * digest_request) { if (digest_request->nonceb64) - xfree(digest_request->nonceb64); + xfree(digest_request->nonceb64); if (digest_request->cnonce) - xfree(digest_request->cnonce); + xfree(digest_request->cnonce); if (digest_request->realm) - xfree(digest_request->realm); + xfree(digest_request->realm); if (digest_request->pszPass) - xfree(digest_request->pszPass); + xfree(digest_request->pszPass); if (digest_request->algorithm) - xfree(digest_request->algorithm); + xfree(digest_request->algorithm); if (digest_request->pszMethod) - xfree(digest_request->pszMethod); + xfree(digest_request->pszMethod); if (digest_request->qop) - xfree(digest_request->qop); + xfree(digest_request->qop); if (digest_request->uri) - xfree(digest_request->uri); + xfree(digest_request->uri); if (digest_request->response) - xfree(digest_request->response); + xfree(digest_request->response); if (digest_request->nonce) - authDigestNonceUnlink(digest_request->nonce); - memPoolFree(digest_request_pool, digest_request); + authDigestNonceUnlink(digest_request->nonce); + memPoolFree(digest_request_pool, digest_request); } void -authDigestAURequestFree(auth_user_request_t *auth_user_request) +authDigestAURequestFree(auth_user_request_t * auth_user_request) { if (auth_user_request->scheme_data != NULL) - authDigestRequestDelete((digest_request_h *)auth_user_request->scheme_data); + authDigestRequestDelete((digest_request_h *) auth_user_request->scheme_data); } digest_request_h * authDigestRequestNew() { digest_request_h *tmp; - tmp=memPoolAlloc(digest_request_pool); - assert (tmp !=NULL); + tmp = memPoolAlloc(digest_request_pool); + assert(tmp != NULL); return tmp; } @@ -529,18 +517,17 @@ authDigestRequestSetup() { if (!digest_request_pool) - digest_request_pool = memPoolCreate("Digest Scheme Request Data", sizeof(digest_request_h)); + digest_request_pool = memPoolCreate("Digest Scheme Request Data", sizeof(digest_request_h)); } void authDigestRequestShutdown() { /* 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; + if (digest_request_pool) { + assert(memPoolInUseCount(digest_request_pool) == 0); + memPoolDestroy(digest_request_pool); + digest_request_pool = NULL; } } @@ -548,23 +535,21 @@ void authDigestDone(void) { - if (digestauthenticators) - helperShutdown(digestauthenticators); - authdigest_initialised = 0; - if (!shutting_down) - { - authenticateDigestNonceReconfigure(); - return; - } if (digestauthenticators) - { - helperFree(digestauthenticators); - digestauthenticators = NULL; + helperShutdown(digestauthenticators); + authdigest_initialised = 0; + if (!shutting_down) { + authenticateDigestNonceReconfigure(); + return; + } + if (digestauthenticators) { + helperFree(digestauthenticators); + digestauthenticators = NULL; } authDigestRequestShutdown(); authDigestUserShutdown(); authenticateDigestNonceShutdown(); - debug(29,2)("authenticateDigestDone: Digest authentication shut down.\n"); + debug(29, 2) ("authenticateDigestDone: Digest authentication shut down.\n"); } static void @@ -572,43 +557,44 @@ { auth_digest_config *config = scheme->scheme_data; wordlist *list = config->authenticate; - debug(29,9)("authDigestCfgDump: Dumping configuration\n"); + debug(29, 9) ("authDigestCfgDump: Dumping configuration\n"); storeAppendPrintf(entry, "%s %s", name, "digest"); while (list != NULL) { - storeAppendPrintf(entry, " %s", list->key); - list = list->next; + 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->authenticateChildren, + name, "digest", config->noncemaxuses, + name, "digest", config->noncemaxduration, name, "digest", config->nonceGCInterval); } -void -authSchemeSetup_digest(authscheme_entry_t *authscheme) { +void +authSchemeSetup_digest(authscheme_entry_t * authscheme) +{ assert(!authdigest_initialised); - authscheme->Active =authenticateDigestActive; - authscheme->configured =authDigestConfigured; - authscheme->parse =authDigestParse; - authscheme->freeconfig =authDigestFreeConfig; - authscheme->dump =authDigestCfgDump; - authscheme->init =authDigestInit; + authscheme->Active = authenticateDigestActive; + authscheme->configured = authDigestConfigured; + authscheme->parse = authDigestParse; + authscheme->freeconfig = authDigestFreeConfig; + authscheme->dump = authDigestCfgDump; + authscheme->init = authDigestInit; authscheme->authAuthenticate = authenticateDigestAuthenticateUser; - authscheme->authenticated= authDigestAuthenticated; - authscheme->authFixHeader=authenticateDigestFixHeader; - authscheme->FreeUser =authenticateDigestUserFree; - authscheme->AddHeader =authDigestAddHeader; + authscheme->authenticated = authDigestAuthenticated; + authscheme->authFixHeader = authenticateDigestFixHeader; + authscheme->FreeUser = authenticateDigestUserFree; + authscheme->AddHeader = authDigestAddHeader; #if WAITING_FOR_TE - authscheme->AddTrailer =authDigestAddTrailer; + authscheme->AddTrailer = authDigestAddTrailer; #endif - authscheme->authStart =authenticateDigestStart; - authscheme->authStats =authenticateDigestStats; + authscheme->authStart = authenticateDigestStart; + authscheme->authStats = authenticateDigestStats; authscheme->authUserUsername = authenticateDigestUsername; - authscheme->getdirection=authenticateDigestDirection; - authscheme->oncloseconnection=NULL; - authscheme->decodeauth =authenticateDigestDecodeAuth; + authscheme->getdirection = authenticateDigestDirection; + authscheme->oncloseconnection = NULL; + authscheme->decodeauth = authenticateDigestDecodeAuth; authscheme->donefunc = authDigestDone; authscheme->requestFree = authDigestAURequestFree; } @@ -616,213 +602,206 @@ int authenticateDigestActive() { - return (authdigest_initialised==1) ? 1:0; + return (authdigest_initialised == 1) ? 1 : 0; } int authDigestConfigured() { if ((digestConfig != NULL) && (digestConfig->authenticate != NULL) && - (digestConfig->authenticateChildren != 0) && - (digestConfig->digestAuthRealm != NULL) && (digestConfig->noncemaxduration > -1)) - return 1; + (digestConfig->authenticateChildren != 0) && + (digestConfig->digestAuthRealm != NULL) && (digestConfig->noncemaxduration > -1)) + return 1; return 0; } int authDigestAuthenticated(auth_user_request_t * auth_user_request) { - if (auth_user_request->auth_user->flags.credentials_ok==1) - return 1; + if (auth_user_request->auth_user->flags.credentials_ok == 1) + return 1; else - return 0; + return 0; } /* log a digest user in */ static void -authenticateDigestAuthenticateUser(auth_user_request_t *auth_user_request, request_t *request, ConnStateData *conn, http_hdr_type type) { +authenticateDigestAuthenticateUser(auth_user_request_t * auth_user_request, request_t * request, ConnStateData * conn, http_hdr_type type) +{ auth_user_t *auth_user; - digest_request_h * digest_request; - digest_user_h * digest_user; + digest_request_h *digest_request; + digest_user_h *digest_user; HASHHEX SESSIONKEY; HASHHEX HA2 = ""; HASHHEX Response; - assert (auth_user_request->auth_user != NULL); - auth_user=auth_user_request->auth_user; + 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; + if (auth_user_request->auth_user->flags.credentials_ok == 3) { + return; } - assert(auth_user->scheme_data != NULL); digest_user = auth_user->scheme_data; - + assert(auth_user_request->scheme_data != NULL); - digest_request=auth_user_request->scheme_data; + 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; - return; - } - if (digest_request->nonce==NULL) - { - /* this isn't a nonce we issued */ - /* 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. - */ - auth_user->flags.credentials_ok=3; - return; - } - DigestCalcHA1(digest_request->algorithm, NULL,NULL,NULL, - authenticateDigestNonceNonceb64(digest_request->nonce), - digest_request->cnonce, - digest_user->HA1,SESSIONKEY); + if (!digest_user->HA1created) { + auth_user_request->auth_user->flags.credentials_ok = 2; + return; + } + if (digest_request->nonce == NULL) { + /* this isn't a nonce we issued */ + /* 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. + */ + auth_user->flags.credentials_ok = 3; + return; + } + DigestCalcHA1(digest_request->algorithm, NULL, NULL, NULL, + authenticateDigestNonceNonceb64(digest_request->nonce), + digest_request->cnonce, + digest_user->HA1, SESSIONKEY); DigestCalcResponse(SESSIONKEY, authenticateDigestNonceNonceb64(digest_request->nonce), - digest_request->nc, digest_request->cnonce, digest_request->qop, - RequestMethodStr[request->method], digest_request->uri, HA2, Response); + digest_request->nc, digest_request->cnonce, digest_request->qop, + RequestMethodStr[request->method], digest_request->uri, HA2, Response); - debug(29,9)("\nResponse = '%s'\n" - "squid is = '%s'\n" , digest_request->response,Response); - - if (strcasecmp(digest_request->response,Response)) - { - auth_user->flags.credentials_ok=3; - return; - } + debug(29, 9) ("\nResponse = '%s'\n" + "squid is = '%s'\n", digest_request->response, Response); - auth_user->flags.credentials_ok=1; + if (strcasecmp(digest_request->response, Response)) { + auth_user->flags.credentials_ok = 3; + return; + } + auth_user->flags.credentials_ok = 1; /* password was checked and did match */ debug(29, 4) ("authenticateDigestAuthenticateuser: user '%s' validated OK\n", - digest_user->username); + digest_user->username); /* auth_user is now linked, we reset these values * after external auth occurs anyway */ - auth_user->expiretime = current_time.tv_sec; + auth_user->expiretime = current_time.tv_sec; auth_user->ip_expiretime = squid_curtime; return; } -int authenticateDigestDirection(auth_user_request_t *auth_user_request) { - digest_request_h * digest_request; +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) { - case 0: /* not checked */ - return -1; - case 1: /* checked & ok */ - digest_request=auth_user_request->scheme_data; - if (authDigestNonceIsStale(digest_request->nonce)) - /* send stale response to the client agent */ - return -2; - return 0; - case 2: /* partway through checking. */ - return -1; - case 3: /* authentication process failed. */ - return -2; + case 0: /* not checked */ + return -1; + case 1: /* checked & ok */ + digest_request = auth_user_request->scheme_data; + if (authDigestNonceIsStale(digest_request->nonce)) + /* send stale response to the client agent */ + return -2; + return 0; + case 2: /* partway through checking. */ + return -1; + case 3: /* authentication process failed. */ + return -2; } return -2; } /* add the [proxy]authorisation header */ void -authDigestAddHeader(auth_user_request_t *auth_user_request, HttpReply *rep, int accel) +authDigestAddHeader(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; + return; + digest_request = auth_user_request->scheme_data; /* don't add to authentication error pages */ - if ((!accel && rep->sline.status==HTTP_PROXY_AUTHENTICATION_REQUIRED) - || (accel && rep->sline.status==HTTP_UNAUTHORIZED)) - return; + 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 WAITING_FOR_TE /* test for http/1.1 transfer chunked encoding */ if (chunkedtest) - return; + return; #endif - if ((digestConfig->authenticate) && authDigestNonceLastRequest(digest_request->nonce)) - { - digest_request->flags.authinfo_sent=1; - debug(29, 9) ("authDigestAddHead: Sending type:%d header: 'nextnonce=\"%s\"",type,authenticateDigestNonceNonceb64(digest_request->nonce)); - httpHeaderPutStrf(&rep->header, type, "nextnonce=\"%s\"",authenticateDigestNonceNonceb64(digest_request->nonce)); + if ((digestConfig->authenticate) && authDigestNonceLastRequest(digest_request->nonce)) { + digest_request->flags.authinfo_sent = 1; + debug(29, 9) ("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) +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; + return; + digest_request = auth_user_request->scheme_data; /* has the header already been send? */ if (digest_request->flags.authinfo_sent) - return; + return; /* don't add to authentication error pages */ - if ((!accel && rep->sline.status==HTTP_PROXY_AUTHENTICATION_REQUIRED) - || (accel && rep->sline.status==HTTP_UNAUTHORIZED)) - return; + 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, 9) ("authDigestAddTrailer: Sending type:%d header: 'nextnonce=\"%s\"",type, authenticateDigestNonceNonceb64(digest_request->nonce)); - httpTrailerPutStrf(&rep->header, type, "nextnonce=\"%s\"",authenticateDigestNonceNonceb64(digest_request->nonce)); + if ((digestConfig->authenticate) && authDigestNonceLastRequest(digest_request->nonce)) { + debug(29, 9) ("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){ +authenticateDigestFixHeader(auth_user_request_t * auth_user_request, HttpReply * rep, http_hdr_type type, request_t * request) +{ digest_request_h *digest_request; - int stale=0; + int stale = 0; digest_nonce_h *nonce = authenticateDigestNonceNew(); - if (auth_user_request && authDigestAuthenticated(auth_user_request) && auth_user_request->scheme_data) - { - digest_request=auth_user_request->scheme_data; - stale=authDigestNonceIsStale(digest_request->nonce); + if (auth_user_request && authDigestAuthenticated(auth_user_request) && auth_user_request->scheme_data) { + digest_request = auth_user_request->scheme_data; + stale = authDigestNonceIsStale(digest_request->nonce); } - if (digestConfig->authenticate){ - debug(29, 9) ("authenticateFixHeader: Sending type:%d header: 'Digest realm=\"%s\", nonce=\"%s\", qop=\"%s\", stale=%s\n",type,digestConfig->digestAuthRealm,authenticateDigestNonceNonceb64(nonce),QOP_AUTH, stale ? "true" : "false"); - /* in the future, for WWW auth we may want to support the domain entry */ - httpHeaderPutStrf(&rep->header, type, "Digest realm=\"%s\", nonce=\"%s\", qop=\"%s\", stale=%s",digestConfig->digestAuthRealm,authenticateDigestNonceNonceb64(nonce),QOP_AUTH, stale ? "true" : "false"); + if (digestConfig->authenticate) { + debug(29, 9) ("authenticateFixHeader: Sending type:%d header: 'Digest realm=\"%s\", nonce=\"%s\", qop=\"%s\", stale=%s\n", type, digestConfig->digestAuthRealm, authenticateDigestNonceNonceb64(nonce), QOP_AUTH, stale ? "true" : "false"); + /* in the future, for WWW auth we may want to support the domain entry */ + httpHeaderPutStrf(&rep->header, type, "Digest realm=\"%s\", nonce=\"%s\", qop=\"%s\", stale=%s", digestConfig->digestAuthRealm, authenticateDigestNonceNonceb64(nonce), QOP_AUTH, stale ? "true" : "false"); } } void -authenticateDigestUserFree(auth_user_t *auth_user) { - digest_user_h * digest_user = auth_user->scheme_data; - dlink_node *link,*tmplink; - debug(29,9) ("authenticateDigestFreeUser: Clearing Digest scheme data\n"); +authenticateDigestUserFree(auth_user_t * auth_user) +{ + digest_user_h *digest_user = auth_user->scheme_data; + dlink_node *link, *tmplink; + debug(29, 9) ("authenticateDigestFreeUser: Clearing Digest scheme data\n"); if (!digest_user) - return; + return; safe_free(digest_user->username); - link=digest_user->nonces.head; - while (link) - { - tmplink=link; - link=link->next; - dlinkDelete(tmplink, &digest_user->nonces); - authDigestNoncePurge(tmplink->data); - authDigestNonceUnlink(tmplink->data); - dlinkNodeDelete(tmplink); + link = digest_user->nonces.head; + while (link) { + tmplink = link; + link = link->next; + dlinkDelete(tmplink, &digest_user->nonces); + authDigestNoncePurge(tmplink->data); + authDigestNonceUnlink(tmplink->data); + dlinkNodeDelete(tmplink); } memPoolFree(digest_user_pool, auth_user->scheme_data); @@ -846,16 +825,15 @@ reply = NULL; } assert(r->auth_user_request != NULL); - auth_user_request=r->auth_user_request; + auth_user_request = r->auth_user_request; assert(auth_user_request->scheme_data != NULL); - digest_request = auth_user_request->scheme_data; + 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; - else - { - CvtBin(reply,digest_user->HA1); - digest_user->HA1created=1; + auth_user_request->auth_user->flags.credentials_ok = 3; + else { + CvtBin(reply, digest_user->HA1); + digest_user->HA1created = 1; } valid = cbdataValid(r->data); if (valid) @@ -867,94 +845,80 @@ /* Initialize helpers and the like for this auth scheme. Called AFTER parsing the * config file */ static void -authDigestInit(authScheme *scheme) +authDigestInit(authScheme * scheme) { static int init = 0; - if (digestConfig->authenticate){ - authDigestUserSetup(); - authDigestRequestSetup(); - authenticateDigestNonceSetup(); - authdigest_initialised = 1; - if (digestauthenticators == NULL) - digestauthenticators = helperCreate("digestauthenticator"); - digestauthenticators->cmdline = digestConfig->authenticate; - digestauthenticators->n_to_start = digestConfig->authenticateChildren; - digestauthenticators->ipc_type = IPC_TCP_SOCKET; - helperOpenServers(digestauthenticators); - if (!init) - { - cachemgrRegister("digestauthenticator", "User Authenticator Stats", - authenticateDigestStats, 0, 1); - init++; - } - CBDATA_INIT_TYPE(authenticateStateData); + if (digestConfig->authenticate) { + authDigestUserSetup(); + authDigestRequestSetup(); + authenticateDigestNonceSetup(); + authdigest_initialised = 1; + if (digestauthenticators == NULL) + digestauthenticators = helperCreate("digestauthenticator"); + digestauthenticators->cmdline = digestConfig->authenticate; + digestauthenticators->n_to_start = digestConfig->authenticateChildren; + digestauthenticators->ipc_type = IPC_TCP_SOCKET; + helperOpenServers(digestauthenticators); + if (!init) { + cachemgrRegister("digestauthenticator", "User Authenticator Stats", + authenticateDigestStats, 0, 1); + init++; + } + CBDATA_INIT_TYPE(authenticateStateData); } } /* free any allocated configuration details */ void -authDigestFreeConfig(authScheme *scheme) +authDigestFreeConfig(authScheme * scheme) { - if (digestConfig==NULL) - return; - assert(digestConfig==scheme->scheme_data); + if (digestConfig == NULL) + return; + assert(digestConfig == scheme->scheme_data); if (digestConfig->authenticate) - wordlistDestroy(&digestConfig->authenticate); + wordlistDestroy(&digestConfig->authenticate); if (digestConfig->digestAuthRealm) - safe_free(digestConfig->digestAuthRealm); - xfree(digestConfig); - digestConfig=NULL; + safe_free(digestConfig->digestAuthRealm); + xfree(digestConfig); + digestConfig = NULL; } static void -authDigestParse(authScheme *scheme, int n_configured, char *param_str) +authDigestParse(authScheme * scheme, int n_configured, char *param_str) { - if (scheme->scheme_data==NULL) - { - assert (digestConfig==NULL); - /* this is the first param to be found */ - scheme->scheme_data=xmalloc(sizeof(auth_digest_config)); - memset(scheme->scheme_data, 0, sizeof(auth_digest_config)); - digestConfig=scheme->scheme_data; - digestConfig->authenticateChildren=5; - /* 5 minutes */ - 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) - { + if (scheme->scheme_data == NULL) { + assert(digestConfig == NULL); + /* this is the first param to be found */ + scheme->scheme_data = xmalloc(sizeof(auth_digest_config)); + memset(scheme->scheme_data, 0, sizeof(auth_digest_config)); + digestConfig = scheme->scheme_data; + digestConfig->authenticateChildren = 5; + /* 5 minutes */ + 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) { if (digestConfig->authenticate) wordlistDestroy(&digestConfig->authenticate); - parse_wordlist(&digestConfig->authenticate); - requirePathnameExists("authparam digest program",digestConfig->authenticate->key); - } - else if (strcasecmp(param_str,"children")==0) - { - parse_int(&digestConfig->authenticateChildren); - } - else if (strcasecmp(param_str,"realm")==0) - { - parse_eol(&digestConfig->digestAuthRealm); - } - else if (strcasecmp(param_str,"nonce_garbage_interval")==0) - { - parse_time_t(&digestConfig->nonceGCInterval); - } - else if (strcasecmp(param_str,"nonce_max_duration")==0) - { - parse_time_t(&digestConfig->noncemaxduration); - } - 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); + parse_wordlist(&digestConfig->authenticate); + requirePathnameExists("authparam digest program", digestConfig->authenticate->key); + } else if (strcasecmp(param_str, "children") == 0) { + parse_int(&digestConfig->authenticateChildren); + } else if (strcasecmp(param_str, "realm") == 0) { + parse_eol(&digestConfig->digestAuthRealm); + } else if (strcasecmp(param_str, "nonce_garbage_interval") == 0) { + parse_time_t(&digestConfig->nonceGCInterval); + } else if (strcasecmp(param_str, "nonce_max_duration") == 0) { + parse_time_t(&digestConfig->noncemaxduration); + } 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); } } @@ -966,102 +930,101 @@ helperStats(sentry, digestauthenticators); } -/* NonceUserUnlink: remove the reference to auth_user and unlink the node from the list*/ +/* NonceUserUnlink: remove the reference to auth_user and unlink the node from the list */ void -authDigestNonceUserUnlink(digest_nonce_h *nonce) +authDigestNonceUserUnlink(digest_nonce_h * nonce) { - digest_user_h * digest_user; - dlink_node *link,*tmplink; + digest_user_h *digest_user; + dlink_node *link, *tmplink; if (!nonce) - return; + return; if (!nonce->auth_user) - return; + return; digest_user = nonce->auth_user->scheme_data; /* unlink from the user list. Yes we're crossing structures but this is the only * time this code is needed */ - link=digest_user->nonces.head; - while (link) - { - tmplink=link; - link=link->next; - if (tmplink->data==nonce) - { - dlinkDelete(tmplink, &digest_user->nonces); - authDigestNonceUnlink(tmplink->data); - dlinkNodeDelete(tmplink); - link=NULL; - } + link = digest_user->nonces.head; + while (link) { + tmplink = link; + link = link->next; + if (tmplink->data == nonce) { + dlinkDelete(tmplink, &digest_user->nonces); + authDigestNonceUnlink(tmplink->data); + dlinkNodeDelete(tmplink); + link = NULL; + } } /* this reference to auth_user was not locked because freeeing the auth_user frees * the nonce too. */ - nonce->auth_user=NULL; + nonce->auth_user = NULL; } /* authDigestUserLinkNonce: add a nonce to a given user's struct */ void -authDigestUserLinkNonce(auth_user_t *auth_user, digest_nonce_h *nonce) +authDigestUserLinkNonce(auth_user_t * auth_user, digest_nonce_h * nonce) { dlink_node *node; - digest_user_h * digest_user; + digest_user_h *digest_user; if (!auth_user || !nonce) - return; + return; if (!auth_user->scheme_data) - return; - digest_user=auth_user->scheme_data; - node=digest_user->nonces.head; + return; + digest_user = auth_user->scheme_data; + node = digest_user->nonces.head; while (node && (node->data != nonce)) - node=node->next; + node = node->next; if (node) - return; - node=dlinkNodeNew(); - dlinkAddTail(nonce,node,&digest_user->nonces); + return; + node = dlinkNodeNew(); + dlinkAddTail(nonce, node, &digest_user->nonces); authDigestNonceLink(nonce); /* ping this nonce to this auth user */ - assert ((nonce->auth_user==NULL) || (nonce->auth_user=auth_user)); + assert((nonce->auth_user == NULL) || (nonce->auth_user = auth_user)); /* we don't lock this reference because removing the auth_user removes the * hash too. Of course if that changes we're stuffed so read the code huh? */ - nonce->auth_user=auth_user; + nonce->auth_user = auth_user; } /* authenticateDigestUsername: return a pointer to the username in the */ char * -authenticateDigestUsername(auth_user_t *auth_user) { - digest_user_h * digest_user = auth_user->scheme_data; +authenticateDigestUsername(auth_user_t * auth_user) +{ + digest_user_h *digest_user = auth_user->scheme_data; if (digest_user) - return digest_user->username; + return digest_user->username; return NULL; } /* setup the necessary info to log the username */ void -authDigestLogUsername(auth_user_request_t *auth_user_request, char * username) +authDigestLogUsername(auth_user_request_t * auth_user_request, char *username) { - auth_user_t * auth_user; + auth_user_t *auth_user; digest_user_h *digest_user; dlink_node *node; - + /* log the username */ - debug(29,9)("authBasicDecodeAuth: Creating new user for logging '%s'\n",username); + debug(29, 9) ("authBasicDecodeAuth: Creating new user for logging '%s'\n", username); /* new auth_user */ - auth_user=authenticateAuthUserNew("digest"); + auth_user = authenticateAuthUserNew("digest"); /* new scheme data */ - digest_user=authDigestUserNew(); + digest_user = authDigestUserNew(); /* save the credentials */ - digest_user->username=username; + digest_user->username = username; /* link the scheme data in */ - auth_user->scheme_data=digest_user; + auth_user->scheme_data = digest_user; /* set the auth_user type */ - auth_user->auth_type=AUTH_BROKEN; + auth_user->auth_type = AUTH_BROKEN; /* link the request to the user */ - auth_user_request->auth_user=auth_user; + auth_user_request->auth_user = auth_user; /* lock for the auth_user_request link */ authenticateAuthUserLock(auth_user); - node=dlinkNodeNew(); + node = dlinkNodeNew(); dlinkAdd(auth_user_request, node, &auth_user->requests); } @@ -1071,129 +1034,112 @@ */ static void -authenticateDigestDecodeAuth(auth_user_request_t *auth_user_request, const char * proxy_auth) { +authenticateDigestDecodeAuth(auth_user_request_t * auth_user_request, const char *proxy_auth) +{ String temp; const char *item; const char *p; const char *pos = NULL; - char * username=NULL; + char *username = NULL; digest_nonce_h *nonce; int ilen; - digest_request_h * digest_request; - digest_user_h * digest_user; - auth_user_t * auth_user; + digest_request_h *digest_request; + digest_user_h *digest_user; + auth_user_t *auth_user; dlink_node *node; - debug(29,9)("authenticateDigestDecodeAuth: beginning\n"); + debug(29, 9) ("authenticateDigestDecodeAuth: beginning\n"); assert(auth_user_request != NULL); digest_request = authDigestRequestNew(); /* trim DIGEST from string */ while (!xisspace(*proxy_auth)) - proxy_auth++; + proxy_auth++; /* Trim leading whitespace before decoding */ while (xisspace(*proxy_auth)) - proxy_auth++; + proxy_auth++; stringInit(&temp, proxy_auth); - while (strListGetItem(&temp, ',', &item,&ilen,&pos)) - { - if ((p = strchr(item,'=')) && (p-itemrealm=xstrndup(p,strchr(p,'"')+1-p); - debug(29,9)("authDigestDecodeAuth: Found realm '%s'\n",digest_request->realm); - } - else if (!strncmp(item, "qop", ilen)) - { - /* white space */ - while (xisspace(*p)) - p++; - /* quote mark */ - p++; - digest_request->qop=xstrndup(p,strchr(p,'"')+1-p); - debug(29,9)("authDigestDecodeAuth: Found qop '%s'\n",digest_request->qop); - } - else if (!strncmp(item, "algorithm", ilen)) - { - /* white space */ - while (xisspace(*p)) - p++; - /* quote mark */ - p++; - digest_request->algorithm=xstrndup(p,strchr(p,'"')+1-p); - debug(29,9)("authDigestDecodeAuth: Found algorithm '%s'\n",digest_request->algorithm); - } - else if (!strncmp(item, "uri", ilen)) - { - /* white space */ - while (xisspace(*p)) - p++; - /* quote mark */ - p++; - digest_request->uri=xstrndup(p,strchr(p,'"')+1-p); - debug(29,9)("authDigestDecodeAuth: Found uri '%s'\n",digest_request->uri); - } - else if (!strncmp(item, "nonce", ilen)) - { - /* white space */ - while (xisspace(*p)) - p++; - /* quote mark */ - p++; - digest_request->nonceb64=xstrndup(p,strchr(p,'"')+1-p); - debug(29,9)("authDigestDecodeAuth: Found nonce '%s'\n",digest_request->nonceb64); - } - else if (!strncmp(item, "nc", ilen)) - { - /* white space */ - while (xisspace(*p)) - p++; - xstrncpy(digest_request->nc,p,9); - debug(29,9)("authDigestDecodeAuth: Found noncecount '%s'\n",digest_request->nc); - } - else if (!strncmp(item, "cnonce", ilen)) - { - /* white space */ - while (xisspace(*p)) - p++; - /* quote mark */ - p++; - digest_request->cnonce=xstrndup(p,strchr(p,'"')+1-p); - debug(29,9)("authDigestDecodeAuth: Found cnonce '%s'\n",digest_request->cnonce); - } - else if (!strncmp(item, "response", ilen)) - { - /* white space */ - while (xisspace(*p)) - p++; - /* quote mark */ - p++; - digest_request->response=xstrndup(p,strchr(p,'"')+1-p); - debug(29,9)("authDigestDecodeAuth: Found response '%s'\n",digest_request->response); - } + while (strListGetItem(&temp, ',', &item, &ilen, &pos)) { + if ((p = strchr(item, '=')) && (p - item < ilen)) + ilen = p++ - item; + if (!strncmp(item, "username", ilen)) { + /* white space */ + while (xisspace(*p)) + p++; + /* quote mark */ + p++; + username = xstrndup(p, strchr(p, '"') + 1 - p); + debug(29, 9) ("authDigestDecodeAuth: Found Username '%s'\n", username); + } else if (!strncmp(item, "realm", ilen)) { + /* white space */ + while (xisspace(*p)) + p++; + /* quote mark */ + p++; + digest_request->realm = xstrndup(p, strchr(p, '"') + 1 - p); + debug(29, 9) ("authDigestDecodeAuth: Found realm '%s'\n", digest_request->realm); + } else if (!strncmp(item, "qop", ilen)) { + /* white space */ + while (xisspace(*p)) + p++; + /* quote mark */ + p++; + digest_request->qop = xstrndup(p, strchr(p, '"') + 1 - p); + debug(29, 9) ("authDigestDecodeAuth: Found qop '%s'\n", digest_request->qop); + } else if (!strncmp(item, "algorithm", ilen)) { + /* white space */ + while (xisspace(*p)) + p++; + /* quote mark */ + p++; + digest_request->algorithm = xstrndup(p, strchr(p, '"') + 1 - p); + debug(29, 9) ("authDigestDecodeAuth: Found algorithm '%s'\n", digest_request->algorithm); + } else if (!strncmp(item, "uri", ilen)) { + /* white space */ + while (xisspace(*p)) + p++; + /* quote mark */ + p++; + digest_request->uri = xstrndup(p, strchr(p, '"') + 1 - p); + debug(29, 9) ("authDigestDecodeAuth: Found uri '%s'\n", digest_request->uri); + } else if (!strncmp(item, "nonce", ilen)) { + /* white space */ + while (xisspace(*p)) + p++; + /* quote mark */ + p++; + digest_request->nonceb64 = xstrndup(p, strchr(p, '"') + 1 - p); + debug(29, 9) ("authDigestDecodeAuth: Found nonce '%s'\n", digest_request->nonceb64); + } else if (!strncmp(item, "nc", ilen)) { + /* white space */ + while (xisspace(*p)) + p++; + xstrncpy(digest_request->nc, p, 9); + debug(29, 9) ("authDigestDecodeAuth: Found noncecount '%s'\n", digest_request->nc); + } else if (!strncmp(item, "cnonce", ilen)) { + /* white space */ + while (xisspace(*p)) + p++; + /* quote mark */ + p++; + digest_request->cnonce = xstrndup(p, strchr(p, '"') + 1 - p); + debug(29, 9) ("authDigestDecodeAuth: Found cnonce '%s'\n", digest_request->cnonce); + } else if (!strncmp(item, "response", ilen)) { + /* white space */ + while (xisspace(*p)) + p++; + /* quote mark */ + p++; + digest_request->response = xstrndup(p, strchr(p, '"') + 1 - p); + debug(29, 9) ("authDigestDecodeAuth: Found response '%s'\n", digest_request->response); + } } stringClean(&temp); - - + + /* now we validate the data given to us */ /* TODO: on invalid parameters we should return 400, not 407. Find some clean way @@ -1201,166 +1147,147 @@ * combined with a change to the clientwards handling code (ie let the clientwards * call set the error type (but limited to known correct values - 400/401/407 */ - /* first the NONCE count */ - if (digest_request->cnonce && strlen(digest_request->nc)!=8) - { - debug (29,4)("authenticateDigestDecode: nonce count length invalid\n"); - authDigestLogUsername(auth_user_request, username); - - /* we don't need the scheme specific data anymore*/ - authDigestRequestDelete(digest_request); - auth_user_request->scheme_data=NULL; - return; - } - + /* first the NONCE count */ + if (digest_request->cnonce && strlen(digest_request->nc) != 8) { + debug(29, 4) ("authenticateDigestDecode: nonce count length invalid\n"); + authDigestLogUsername(auth_user_request, username); + + /* we don't need the scheme specific data anymore */ + authDigestRequestDelete(digest_request); + auth_user_request->scheme_data = NULL; + return; + } /* now the nonce */ - nonce=authenticateDigestNonceFindNonce(digest_request->nonceb64); - if ((nonce==NULL) || !(authDigestNonceIsValid(nonce, digest_request->nc))) - { - /* we couldn't find a matching nonce! */ - debug (29,4)("authenticateDigestDecode: Unexpected or invalid nonce recieved\n"); - authDigestLogUsername(auth_user_request, username); - - /* we don't need the scheme specific data anymore*/ - authDigestRequestDelete(digest_request); - auth_user_request->scheme_data=NULL; - return; + nonce = authenticateDigestNonceFindNonce(digest_request->nonceb64); + if ((nonce == NULL) || !(authDigestNonceIsValid(nonce, digest_request->nc))) { + /* we couldn't find a matching nonce! */ + debug(29, 4) ("authenticateDigestDecode: Unexpected or invalid nonce recieved\n"); + authDigestLogUsername(auth_user_request, username); + + /* we don't need the scheme specific data anymore */ + authDigestRequestDelete(digest_request); + auth_user_request->scheme_data = NULL; + return; } - digest_request->nonce=nonce; + 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)) - { - /* we recieved a qop option we didn't send */ - debug (29,4)("authenticateDigestDecode: Invalid qop option recieved\n"); - authDigestLogUsername(auth_user_request, username); - - /* we don't need the scheme specific data anymore*/ - authDigestRequestDelete(digest_request); - auth_user_request->scheme_data=NULL; - return; + if (digest_request->qop && strcmp(digest_request->qop, QOP_AUTH)) { + /* we recieved a qop option we didn't send */ + debug(29, 4) ("authenticateDigestDecode: Invalid qop option recieved\n"); + authDigestLogUsername(auth_user_request, username); + + /* we don't need the scheme specific data anymore */ + authDigestRequestDelete(digest_request); + auth_user_request->scheme_data = NULL; + return; } - /* we can't check the URI just yet. We'll check it in the authenticate phase */ /* is the response the correct length? */ - if (!digest_request->response || strlen(digest_request->response)!=32) - { - debug (29,4)("authenticateDigestDecode: Response length invalid\n"); - authDigestLogUsername(auth_user_request, username); - - /* we don't need the scheme specific data anymore*/ - authDigestRequestDelete(digest_request); - auth_user_request->scheme_data=NULL; - return; + if (!digest_request->response || strlen(digest_request->response) != 32) { + debug(29, 4) ("authenticateDigestDecode: Response length invalid\n"); + authDigestLogUsername(auth_user_request, username); + + /* we don't need the scheme specific data anymore */ + authDigestRequestDelete(digest_request); + auth_user_request->scheme_data = NULL; + return; } - /* do we have a username ? */ - if (!username || username[0]=='\0') - { - debug (29,4)("authenticateDigestDecode: Empty or not present username\n"); - authDigestLogUsername(auth_user_request, username); - - /* we don't need the scheme specific data anymore*/ - authDigestRequestDelete(digest_request); - auth_user_request->scheme_data=NULL; - return; + if (!username || username[0] == '\0') { + debug(29, 4) ("authenticateDigestDecode: Empty or not present username\n"); + authDigestLogUsername(auth_user_request, username); + + /* we don't need the scheme specific data anymore */ + authDigestRequestDelete(digest_request); + auth_user_request->scheme_data = NULL; + return; } - /* check that we're not being hacked / the username hasn't changed */ - if (nonce->auth_user && strcmp(username, authenticateUserUsername(nonce->auth_user))) - { - debug (29,4)("authenticateDigestDecode: Username for the nonce does not equal the username for the request\n"); - authDigestLogUsername(auth_user_request, username); - - /* we don't need the scheme specific data anymore*/ - authDigestRequestDelete(digest_request); - auth_user_request->scheme_data=NULL; - return; - } - - - /* if we got a qop, did we get a cnonce or did we get a cnonce wihtout a qop?*/ - if ((digest_request->qop && !digest_request->cnonce) - || (!digest_request->qop && digest_request->cnonce)) - { - debug (29,4)("authenticateDigestDecode: qop without cnonce, or vice versa!\n"); - authDigestLogUsername(auth_user_request, username); - - /* we don't need the scheme specific data anymore*/ - authDigestRequestDelete(digest_request); - auth_user_request->scheme_data=NULL; - return; - } - - /* check the algorithm is present and supported*/ - if (digest_request->algorithm - && strcmp(digest_request->algorithm,"MD5") - && strcmp(digest_request->algorithm,"MD5-sess")) - { - debug (29,4)("authenticateDigestDecode: invalid algorithm specified!\n"); - authDigestLogUsername(auth_user_request, username); - - /* we don't need the scheme specific data anymore*/ - authDigestRequestDelete(digest_request); - auth_user_request->scheme_data=NULL; - return; + if (nonce->auth_user && strcmp(username, authenticateUserUsername(nonce->auth_user))) { + debug(29, 4) ("authenticateDigestDecode: Username for the nonce does not equal the username for the request\n"); + authDigestLogUsername(auth_user_request, username); + + /* we don't need the scheme specific data anymore */ + authDigestRequestDelete(digest_request); + auth_user_request->scheme_data = NULL; + return; + } + /* if we got a qop, did we get a cnonce or did we get a cnonce wihtout a qop? */ + if ((digest_request->qop && !digest_request->cnonce) + || (!digest_request->qop && digest_request->cnonce)) { + debug(29, 4) ("authenticateDigestDecode: qop without cnonce, or vice versa!\n"); + authDigestLogUsername(auth_user_request, username); + + /* we don't need the scheme specific data anymore */ + authDigestRequestDelete(digest_request); + auth_user_request->scheme_data = NULL; + return; + } + /* check the algorithm is present and supported */ + if (digest_request->algorithm + && strcmp(digest_request->algorithm, "MD5") + && strcmp(digest_request->algorithm, "MD5-sess")) { + debug(29, 4) ("authenticateDigestDecode: invalid algorithm specified!\n"); + authDigestLogUsername(auth_user_request, username); + + /* we don't need the scheme specific data anymore */ + authDigestRequestDelete(digest_request); + auth_user_request->scheme_data = NULL; + return; } + /* the method we'll check at the authenticate step as well */ - /* the method we'll check at the authenticate step as well */ - - /* we don't send or parse opaques. Ok so we're flexable ... */ + /* we don't send or parse opaques. Ok so we're flexable ... */ /* find the user */ - if ((auth_user=authDigestUserFindUsername(username))== NULL) - { - /* the user doesn't exist in the username cache yet */ - debug(29,9)("authDigestDecodeAuth: Creating new digest user '%s'\n",username); - /* new auth_user */ - auth_user=authenticateAuthUserNew("digest"); - /* new scheme user data */ - digest_user=authDigestUserNew(); - /* save the username */ - digest_user->username=username; - /* link the primary struct in */ - auth_user->scheme_data=digest_user; - /* set the user type */ - auth_user->auth_type=AUTH_DIGEST; - /* this auth_user struct is the one to get added to the username cache */ - /* store user in hash's */ - 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 - { - debug(29,9)("authDigestDecodeAuth: Found user '%s' in the user cache as '%d'\n",username,auth_user); - digest_user=auth_user->scheme_data; - xfree(username); + if ((auth_user = authDigestUserFindUsername(username)) == NULL) { + /* the user doesn't exist in the username cache yet */ + debug(29, 9) ("authDigestDecodeAuth: Creating new digest user '%s'\n", username); + /* new auth_user */ + auth_user = authenticateAuthUserNew("digest"); + /* new scheme user data */ + digest_user = authDigestUserNew(); + /* save the username */ + digest_user->username = username; + /* link the primary struct in */ + auth_user->scheme_data = digest_user; + /* set the user type */ + auth_user->auth_type = AUTH_DIGEST; + /* this auth_user struct is the one to get added to the username cache */ + /* store user in hash's */ + 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 { + debug(29, 9) ("authDigestDecodeAuth: Found user '%s' in the user cache as '%d'\n", username, auth_user); + digest_user = auth_user->scheme_data; + xfree(username); } /*link the request and the user */ - auth_user_request->auth_user=auth_user; - auth_user_request->scheme_data=digest_request; + auth_user_request->auth_user = auth_user; + auth_user_request->scheme_data = digest_request; /* lock for the request link */ authenticateAuthUserLock(auth_user); - node=dlinkNodeNew(); + node = dlinkNodeNew(); dlinkAdd(auth_user_request, node, &auth_user->requests); - debug(29,9)("username = '%s'\nrealm = '%s'\nqop = '%s'\nalgorithm = '%s'\nuri = '%s'\nnonce = '%s'\nnc = '%s'\ncnonce = '%s'\nresponse = '%s'\ndigestnonce = '%d'\n", - digest_user->username, digest_request->realm, - digest_request->qop, digest_request->algorithm, - digest_request->uri, digest_request->nonceb64, - digest_request->nc, digest_request->cnonce, digest_request->response,nonce); + debug(29, 9) ("username = '%s'\nrealm = '%s'\nqop = '%s'\nalgorithm = '%s'\nuri = '%s'\nnonce = '%s'\nnc = '%s'\ncnonce = '%s'\nresponse = '%s'\ndigestnonce = '%d'\n", + digest_user->username, digest_request->realm, + digest_request->qop, digest_request->algorithm, + digest_request->uri, digest_request->nonceb64, + digest_request->nc, digest_request->cnonce, digest_request->response, nonce); return; } @@ -1371,20 +1298,20 @@ { authenticateStateData *r = NULL; char buf[8192]; - digest_request_h * digest_request; - digest_user_h * digest_user; + digest_request_h *digest_request; + digest_user_h *digest_user; assert(auth_user_request); assert(handler); - assert(auth_user_request->auth_user->auth_type==AUTH_DIGEST); + assert(auth_user_request->auth_user->auth_type == AUTH_DIGEST); assert(auth_user_request->auth_user->scheme_data != NULL); assert(auth_user_request->scheme_data != NULL); digest_request = auth_user_request->scheme_data; - digest_user = auth_user_request->auth_user->scheme_data; + digest_user = auth_user_request->auth_user->scheme_data; debug(29, 9) ("authenticateStart: '\"%s\":\"%s\"'\n", digest_user->username, - digest_request->realm); + digest_request->realm); if (digestConfig->authenticate == NULL) { - handler(data, NULL); - return; + handler(data, NULL); + return; } r = CBDATA_ALLOC(authenticateStateData, NULL); r->handler = handler; 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.20.1 retrieving revision 1.1.20.2 diff -u -r1.1.20.1 -r1.1.20.2 --- squid/src/auth/digest/auth_digest.h 23 Jan 2001 22:54:53 -0000 1.1.20.1 +++ squid/src/auth/digest/auth_digest.h 10 Feb 2001 17:32:49 -0000 1.1.20.2 @@ -24,24 +24,33 @@ char *username; HASH HA1; int HA1created; - /* what nonces have been allocated to this user*/ + /* what nonces have been allocated to this user */ dlink_list nonces; }; /* the digest_request structure is what follows the http_request around */ struct _digest_request_h { - char * nonceb64;// = "dcd98b7102dd2f0e8b11d0f600bfb0c093"; - char * cnonce;// = "0a4f113b"; - char * realm;// = "testrealm@host.com"; - char * pszPass;// = "Circle Of Life"; - char * algorithm;// = "md5"; - char nc[9];// = "00000001"; - char * pszMethod;// = "GET"; - char * qop;// = "auth"; - char *uri;// = "/dir/index.html"; + char *nonceb64; // = "dcd98b7102dd2f0e8b11d0f600bfb0c093"; + + char *cnonce; // = "0a4f113b"; + + char *realm; // = "testrealm@host.com"; + + char *pszPass; // = "Circle Of Life"; + + char *algorithm; // = "md5"; + + char nc[9]; // = "00000001"; + + char *pszMethod; // = "GET"; + + char *qop; // = "auth"; + + char *uri; // = "/dir/index.html"; + char *response; struct { - unsigned int authinfo_sent:1; + unsigned int authinfo_sent:1; } flags; digest_nonce_h *nonce; }; @@ -65,11 +74,11 @@ /* reference count */ short references; /* the auth_user this nonce has been tied to */ - auth_user_t * auth_user; + auth_user_t *auth_user; /* has this nonce been invalidated ? */ struct { - unsigned int valid:1; - unsigned int incache:1; + unsigned int valid:1; + unsigned int incache:1; } flags; }; Index: squid/src/auth/digest/helpers/password/digest_pw_auth.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/auth/digest/helpers/password/Attic/digest_pw_auth.c,v retrieving revision 1.1.8.1 retrieving revision 1.1.8.2 diff -u -r1.1.8.1 -r1.1.8.2 --- squid/src/auth/digest/helpers/password/digest_pw_auth.c 23 Jan 2001 22:54:54 -0000 1.1.8.1 +++ squid/src/auth/digest/helpers/password/digest_pw_auth.c 10 Feb 2001 17:32:49 -0000 1.1.8.2 @@ -135,23 +135,23 @@ } } if ((user = strtok(buf, "\"")) == NULL) { - printf("ERR\n"); - continue; + printf("ERR\n"); + continue; + } + if ((realm = strtok(NULL, "\"")) == NULL) { + printf("ERR\n"); + continue; + } + if ((realm = strtok(NULL, "\"")) == NULL) { + printf("ERR\n"); + continue; } - if ((realm = strtok(NULL, "\"")) == NULL) { - printf("ERR\n"); - continue; - } - if ((realm = strtok(NULL, "\"")) == NULL) { - printf("ERR\n"); - continue; - } u = hash_lookup(hash, user); if (u == NULL) { printf("ERR\n"); } else { - DigestCalcHA1("md5",user,realm,u->passwd, NULL, NULL, HA1, HHA1); - printf("%s\n",HHA1); + DigestCalcHA1("md5", user, realm, u->passwd, NULL, NULL, HA1, HHA1); + printf("%s\n", HHA1); } } exit(0); Index: squid/src/auth/ntlm/auth_ntlm.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/auth/ntlm/auth_ntlm.c,v retrieving revision 1.1.2.35 retrieving revision 1.1.2.36 diff -u -r1.1.2.35 -r1.1.2.36 --- squid/src/auth/ntlm/auth_ntlm.c 9 Feb 2001 17:40:56 -0000 1.1.2.35 +++ squid/src/auth/ntlm/auth_ntlm.c 10 Feb 2001 17:32:49 -0000 1.1.2.36 @@ -42,9 +42,9 @@ #include "auth_ntlm.h" static void -authenticateStateFree (authenticateStateData * r) +authenticateStateFree(authenticateStateData * r) { - cbdataFree (r); + cbdataFree(r); } /* NTLM Scheme */ @@ -75,7 +75,7 @@ static statefulhelper *ntlmauthenticators = NULL; -CBDATA_TYPE (authenticateStateData); +CBDATA_TYPE(authenticateStateData); static int authntlm_initialised = 0; @@ -93,209 +93,191 @@ */ void -authNTLMDone (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) - helperStatefulFree (ntlmauthenticators); - ntlmauthenticators = NULL; - if (ntlm_helper_state_pool) - { - assert (memPoolInUseCount (ntlm_helper_state_pool) == 0); - memPoolDestroy (ntlm_helper_state_pool); - ntlm_helper_state_pool = NULL; - } - if (ntlm_request_pool) - { - assert (memPoolInUseCount (ntlm_request_pool) == 0); - memPoolDestroy (ntlm_request_pool); - ntlm_request_pool = NULL; - } - if (ntlm_user_pool) - { - assert (memPoolInUseCount (ntlm_user_pool) == 0); - memPoolDestroy (ntlm_user_pool); - ntlm_user_pool = NULL; + debug(29, 2) ("authNTLMDone: shutting down NTLM authentication.\n"); + if (ntlmauthenticators) + helperStatefulShutdown(ntlmauthenticators); + authntlm_initialised = 0; + if (!shutting_down) + return; + if (ntlmauthenticators) + helperStatefulFree(ntlmauthenticators); + ntlmauthenticators = NULL; + if (ntlm_helper_state_pool) { + assert(memPoolInUseCount(ntlm_helper_state_pool) == 0); + memPoolDestroy(ntlm_helper_state_pool); + ntlm_helper_state_pool = NULL; + } + if (ntlm_request_pool) { + assert(memPoolInUseCount(ntlm_request_pool) == 0); + memPoolDestroy(ntlm_request_pool); + ntlm_request_pool = NULL; + } + if (ntlm_user_pool) { + assert(memPoolInUseCount(ntlm_user_pool) == 0); + memPoolDestroy(ntlm_user_pool); + ntlm_user_pool = NULL; } - debug (29, 2) ("authNTLMDone: NTLM authentication Shutdown.\n"); + debug(29, 2) ("authNTLMDone: NTLM authentication Shutdown.\n"); } /* free any allocated configuration details */ void -authNTLMFreeConfig (authScheme * scheme) +authNTLMFreeConfig(authScheme * scheme) { - if (ntlmConfig == NULL) - return; - assert (ntlmConfig == scheme->scheme_data); - if (ntlmConfig->authenticate) - wordlistDestroy (&ntlmConfig->authenticate); - xfree (ntlmConfig); - ntlmConfig = NULL; + if (ntlmConfig == NULL) + return; + assert(ntlmConfig == scheme->scheme_data); + if (ntlmConfig->authenticate) + wordlistDestroy(&ntlmConfig->authenticate); + xfree(ntlmConfig); + ntlmConfig = NULL; } static void -authNTLMCfgDump (StoreEntry * entry, const char *name, authScheme * scheme) +authNTLMCfgDump(StoreEntry * entry, const char *name, authScheme * scheme) { - auth_ntlm_config *config = scheme->scheme_data; - wordlist *list = config->authenticate; - storeAppendPrintf (entry, "%s %s", name, "ntlm"); - while (list != NULL) - { - storeAppendPrintf (entry, " %s", list->key); - list = list->next; + auth_ntlm_config *config = scheme->scheme_data; + wordlist *list = config->authenticate; + storeAppendPrintf(entry, "%s %s", name, "ntlm"); + while (list != NULL) { + storeAppendPrintf(entry, " %s", list->key); + list = list->next; } - storeAppendPrintf (entry, "\n%s %s children %d\n%s %s max_challenge_reuses %d\n%s %s max_challenge_lifetime %d seconds\n", name, "ntlm", config->authenticateChildren, name, "ntlm", config->challengeuses, name, "ntlm", config->challengelifetime); + storeAppendPrintf(entry, "\n%s %s children %d\n%s %s max_challenge_reuses %d\n%s %s max_challenge_lifetime %d seconds\n", name, "ntlm", config->authenticateChildren, name, "ntlm", config->challengeuses, name, "ntlm", config->challengelifetime); } static void -authNTLMParse (authScheme * scheme, int n_configured, char *param_str) +authNTLMParse(authScheme * scheme, int n_configured, char *param_str) { - if (scheme->scheme_data == NULL) - { - assert (ntlmConfig == NULL); - /* this is the first param to be found */ - scheme->scheme_data = xmalloc (sizeof (auth_ntlm_config)); - memset (scheme->scheme_data, 0, sizeof (auth_ntlm_config)); - ntlmConfig = scheme->scheme_data; - ntlmConfig->authenticateChildren = 5; - ntlmConfig->challengeuses = 0; - ntlmConfig->challengelifetime = 60; - } - ntlmConfig = scheme->scheme_data; - if (strcasecmp (param_str, "program") == 0) - { - if (ntlmConfig->authenticate) - wordlistDestroy (&ntlmConfig->authenticate); - parse_wordlist (&ntlmConfig->authenticate); - requirePathnameExists ("authparam ntlm program", ntlmConfig->authenticate->key); - } - else if (strcasecmp (param_str, "children") == 0) - { - parse_int (&ntlmConfig->authenticateChildren); - } - else if (strcasecmp (param_str, "max_challenge_reuses") == 0) - { - parse_int (&ntlmConfig->challengeuses); - } - else if (strcasecmp (param_str, "max_challenge_lifetime") == 0) - { - parse_time_t (&ntlmConfig->challengelifetime); - } - else - { - debug (28, 0) ("unrecognised ntlm auth scheme parameter '%s'\n", param_str); + if (scheme->scheme_data == NULL) { + assert(ntlmConfig == NULL); + /* this is the first param to be found */ + scheme->scheme_data = xmalloc(sizeof(auth_ntlm_config)); + memset(scheme->scheme_data, 0, sizeof(auth_ntlm_config)); + ntlmConfig = scheme->scheme_data; + ntlmConfig->authenticateChildren = 5; + ntlmConfig->challengeuses = 0; + ntlmConfig->challengelifetime = 60; + } + ntlmConfig = scheme->scheme_data; + if (strcasecmp(param_str, "program") == 0) { + if (ntlmConfig->authenticate) + wordlistDestroy(&ntlmConfig->authenticate); + parse_wordlist(&ntlmConfig->authenticate); + requirePathnameExists("authparam ntlm program", ntlmConfig->authenticate->key); + } else if (strcasecmp(param_str, "children") == 0) { + parse_int(&ntlmConfig->authenticateChildren); + } else if (strcasecmp(param_str, "max_challenge_reuses") == 0) { + parse_int(&ntlmConfig->challengeuses); + } else if (strcasecmp(param_str, "max_challenge_lifetime") == 0) { + parse_time_t(&ntlmConfig->challengelifetime); + } else { + debug(28, 0) ("unrecognised ntlm auth scheme parameter '%s'\n", param_str); } } void -authSchemeSetup_ntlm (authscheme_entry_t * authscheme) -{ - assert (!authntlm_initialised); - authscheme->Active = authenticateNTLMActive; - authscheme->configured = authNTLMConfigured; - authscheme->parse = authNTLMParse; - authscheme->dump = authNTLMCfgDump; - authscheme->requestFree = authNTLMAURequestFree; - authscheme->freeconfig = authNTLMFreeConfig; - authscheme->init = authNTLMInit; - authscheme->authAuthenticate = authenticateNTLMAuthenticateUser; - authscheme->authenticated = authNTLMAuthenticated; - authscheme->authFixHeader = authenticateNTLMFixErrorHeader; - authscheme->FreeUser = authenticateNTLMFreeUser; - authscheme->authStart = authenticateNTLMStart; - authscheme->authStats = authenticateNTLMStats; - authscheme->authUserUsername = authenticateNTLMUsername; - authscheme->getdirection = authenticateNTLMDirection; - authscheme->decodeauth = authenticateDecodeNTLMAuth; - authscheme->donefunc = authNTLMDone; - authscheme->oncloseconnection = authenticateNTLMOnCloseConnection; +authSchemeSetup_ntlm(authscheme_entry_t * authscheme) +{ + assert(!authntlm_initialised); + authscheme->Active = authenticateNTLMActive; + authscheme->configured = authNTLMConfigured; + authscheme->parse = authNTLMParse; + authscheme->dump = authNTLMCfgDump; + authscheme->requestFree = authNTLMAURequestFree; + authscheme->freeconfig = authNTLMFreeConfig; + authscheme->init = authNTLMInit; + authscheme->authAuthenticate = authenticateNTLMAuthenticateUser; + authscheme->authenticated = authNTLMAuthenticated; + authscheme->authFixHeader = authenticateNTLMFixErrorHeader; + authscheme->FreeUser = authenticateNTLMFreeUser; + authscheme->authStart = authenticateNTLMStart; + authscheme->authStats = authenticateNTLMStats; + authscheme->authUserUsername = authenticateNTLMUsername; + authscheme->getdirection = authenticateNTLMDirection; + authscheme->decodeauth = authenticateDecodeNTLMAuth; + authscheme->donefunc = authNTLMDone; + authscheme->oncloseconnection = authenticateNTLMOnCloseConnection; } /* Initialize helpers and the like for this auth scheme. Called AFTER parsing the * config file */ static void -authNTLMInit (authScheme * scheme) +authNTLMInit(authScheme * scheme) { - static int ntlminit = 0; - if (ntlmConfig->authenticate) - { - if (!ntlm_helper_state_pool) - ntlm_helper_state_pool = memPoolCreate ("NTLM Helper State data", sizeof (ntlm_helper_state_t)); - if (!ntlm_user_pool) - ntlm_user_pool = memPoolCreate ("NTLM Scheme User Data", sizeof (ntlm_user_t)); - if (!ntlm_request_pool) - ntlm_request_pool = memPoolCreate ("NTLM Scheme Request Data", sizeof (ntlm_request_t)); - authntlm_initialised = 1; - if (ntlmauthenticators == NULL) - ntlmauthenticators = helperStatefulCreate ("ntlmauthenticator"); - if (!proxy_auth_cache) - proxy_auth_cache = hash_create ((HASHCMP *) strcmp, 7921, hash_string); - assert (proxy_auth_cache); - ntlmauthenticators->cmdline = ntlmConfig->authenticate; - ntlmauthenticators->n_to_start = ntlmConfig->authenticateChildren; - ntlmauthenticators->ipc_type = IPC_TCP_SOCKET; - ntlmauthenticators->datapool = ntlm_helper_state_pool; - ntlmauthenticators->IsAvailable = authenticateNTLMHelperServerAvailable; - ntlmauthenticators->OnEmptyQueue = authenticateNTLMHelperServerOnEmpty; - 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) - { - cachemgrRegister ("ntlmauthenticator", "User NTLM Authenticator Stats", authenticateNTLMStats, 0, 1); - ntlminit++; + static int ntlminit = 0; + if (ntlmConfig->authenticate) { + if (!ntlm_helper_state_pool) + ntlm_helper_state_pool = memPoolCreate("NTLM Helper State data", sizeof(ntlm_helper_state_t)); + if (!ntlm_user_pool) + ntlm_user_pool = memPoolCreate("NTLM Scheme User Data", sizeof(ntlm_user_t)); + if (!ntlm_request_pool) + ntlm_request_pool = memPoolCreate("NTLM Scheme Request Data", sizeof(ntlm_request_t)); + authntlm_initialised = 1; + if (ntlmauthenticators == NULL) + ntlmauthenticators = helperStatefulCreate("ntlmauthenticator"); + if (!proxy_auth_cache) + proxy_auth_cache = hash_create((HASHCMP *) strcmp, 7921, hash_string); + assert(proxy_auth_cache); + ntlmauthenticators->cmdline = ntlmConfig->authenticate; + ntlmauthenticators->n_to_start = ntlmConfig->authenticateChildren; + ntlmauthenticators->ipc_type = IPC_TCP_SOCKET; + ntlmauthenticators->datapool = ntlm_helper_state_pool; + ntlmauthenticators->IsAvailable = authenticateNTLMHelperServerAvailable; + ntlmauthenticators->OnEmptyQueue = authenticateNTLMHelperServerOnEmpty; + 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) { + cachemgrRegister("ntlmauthenticator", "User NTLM Authenticator Stats", authenticateNTLMStats, 0, 1); + ntlminit++; } - CBDATA_INIT_TYPE (authenticateStateData); + CBDATA_INIT_TYPE(authenticateStateData); } } int -authenticateNTLMActive () +authenticateNTLMActive() { - return (authntlm_initialised == 1) ? 1 : 0; + return (authntlm_initialised == 1) ? 1 : 0; } int -authNTLMConfigured () +authNTLMConfigured() { - if ((ntlmConfig != NULL) && (ntlmConfig->authenticate != NULL) && (ntlmConfig->authenticateChildren != 0) && (ntlmConfig->challengeuses > -1) && (ntlmConfig->challengelifetime > -1)) - { - debug (29, 9) ("authNTLMConfigured: returning configured\n"); - return 1; + if ((ntlmConfig != NULL) && (ntlmConfig->authenticate != NULL) && (ntlmConfig->authenticateChildren != 0) && (ntlmConfig->challengeuses > -1) && (ntlmConfig->challengelifetime > -1)) { + debug(29, 9) ("authNTLMConfigured: returning configured\n"); + return 1; } - debug (29, 9) ("authNTLMConfigured: returning unconfigured\n"); - return 0; + debug(29, 9) ("authNTLMConfigured: returning unconfigured\n"); + return 0; } /* NTLM Scheme */ int -authenticateNTLMDirection (auth_user_request_t * auth_user_request) +authenticateNTLMDirection(auth_user_request_t * auth_user_request) { - ntlm_request_t *ntlm_request = auth_user_request->scheme_data; + ntlm_request_t *ntlm_request = auth_user_request->scheme_data; /* null auth_user is checked for by authenticateDirection */ - switch (ntlm_request->auth_state) - { + switch (ntlm_request->auth_state) { case AUTHENTICATE_STATE_NONE: /* no progress at all. */ - debug (28, 1) ("authenticateNTLMDirection: called before NTLM Authenticate!. Report a bug to squid-dev.\n"); - return -2; - case AUTHENTICATE_STATE_NEGOTIATE: /* send to helper */ + debug(28, 1) ("authenticateNTLMDirection: called before NTLM Authenticate!. Report a bug to squid-dev.\n"); + return -2; + case AUTHENTICATE_STATE_NEGOTIATE: /* send to helper */ case AUTHENTICATE_STATE_RESPONSE: /*send to helper */ - return -1; - case AUTHENTICATE_STATE_CHALLENGE: /* send to client */ - return 1; + return -1; + case AUTHENTICATE_STATE_CHALLENGE: /* send to client */ + return 1; case AUTHENTICATE_STATE_DONE: /* do nothing.. */ - return 0; + return 0; } - return -2; + return -2; } /* @@ -304,542 +286,499 @@ * else. */ void -authenticateNTLMFixErrorHeader (auth_user_request_t * auth_user_request, HttpReply * rep, http_hdr_type type, request_t * request) +authenticateNTLMFixErrorHeader(auth_user_request_t * auth_user_request, HttpReply * rep, http_hdr_type type, request_t * request) { - ntlm_request_t *ntlm_request; - if (ntlmConfig->authenticate) - { - /* New request, no user details */ - if (auth_user_request == NULL) - { - debug (29, 9) ("authenticateNTLMFixErrorHeader: Sending type:%d header: 'NTLM'\n", type); - httpHeaderPutStrf (&rep->header, type, "NTLM"); - /* drop the connection */ - httpHeaderDelByName (&rep->header, "keep-alive"); - /* NTLM has problems if the initial connection is not dropped - * I haven't checked the RFC compliance of this hack - RBCollins */ - request->flags.proxy_keepalive = 0; - } - else - { - ntlm_request = auth_user_request->scheme_data; - switch (ntlm_request->auth_state) - { + ntlm_request_t *ntlm_request; + if (ntlmConfig->authenticate) { + /* New request, no user details */ + if (auth_user_request == NULL) { + debug(29, 9) ("authenticateNTLMFixErrorHeader: Sending type:%d header: 'NTLM'\n", type); + httpHeaderPutStrf(&rep->header, type, "NTLM"); + /* drop the connection */ + httpHeaderDelByName(&rep->header, "keep-alive"); + /* NTLM has problems if the initial connection is not dropped + * I haven't checked the RFC compliance of this hack - RBCollins */ + request->flags.proxy_keepalive = 0; + } else { + ntlm_request = auth_user_request->scheme_data; + switch (ntlm_request->auth_state) { case AUTHENTICATE_STATE_NONE: - debug (29, 9) ("authenticateNTLMFixErrorHeader: Sending type:%d header: 'NTLM'\n", type); - httpHeaderPutStrf (&rep->header, type, "NTLM"); - /* drop the connection */ - httpHeaderDelByName (&rep->header, "keep-alive"); - /* NTLM has problems if the initial connection is not dropped - * I haven't checked the RFC compliance of this hack - RBCollins */ - request->flags.proxy_keepalive = 0; - break; + debug(29, 9) ("authenticateNTLMFixErrorHeader: Sending type:%d header: 'NTLM'\n", type); + httpHeaderPutStrf(&rep->header, type, "NTLM"); + /* drop the connection */ + httpHeaderDelByName(&rep->header, "keep-alive"); + /* NTLM has problems if the initial connection is not dropped + * I haven't checked the RFC compliance of this hack - RBCollins */ + request->flags.proxy_keepalive = 0; + break; case AUTHENTICATE_STATE_CHALLENGE: - /* we are 'waiting' for a response */ - /* pass the challenge to the client */ - debug (29, 9) ("authenticateNTLMFixErrorHeader: Sending type:%d header: 'NTLM %s'\n", type, ntlm_request->authchallenge); - httpHeaderPutStrf (&rep->header, type, "NTLM %s", ntlm_request->authchallenge); - break; + /* we are 'waiting' for a response */ + /* pass the challenge to the client */ + debug(29, 9) ("authenticateNTLMFixErrorHeader: Sending type:%d header: 'NTLM %s'\n", type, ntlm_request->authchallenge); + httpHeaderPutStrf(&rep->header, type, "NTLM %s", ntlm_request->authchallenge); + break; default: - debug (29, 0) ("authenticateNTLMFixErrorHeader: state %d.\n", ntlm_request->auth_state); - fatal ("unexpected state in AuthenticateNTLMFixErrorHeader.\n"); + debug(29, 0) ("authenticateNTLMFixErrorHeader: state %d.\n", ntlm_request->auth_state); + fatal("unexpected state in AuthenticateNTLMFixErrorHeader.\n"); } } } } void -authNTLMRequestFree (ntlm_request_t * ntlm_request) +authNTLMRequestFree(ntlm_request_t * ntlm_request) { - if (!ntlm_request) - return; - if (ntlm_request->ntlmnegotiate) - xfree (ntlm_request->ntlmnegotiate); - if (ntlm_request->authchallenge) - xfree (ntlm_request->authchallenge); - if (ntlm_request->ntlmauthenticate) - xfree (ntlm_request->ntlmauthenticate); - memPoolFree (ntlm_request_pool, ntlm_request); + if (!ntlm_request) + return; + if (ntlm_request->ntlmnegotiate) + xfree(ntlm_request->ntlmnegotiate); + if (ntlm_request->authchallenge) + xfree(ntlm_request->authchallenge); + if (ntlm_request->ntlmauthenticate) + xfree(ntlm_request->ntlmauthenticate); + memPoolFree(ntlm_request_pool, ntlm_request); } void -authNTLMAURequestFree (auth_user_request_t * auth_user_request) -{ - if (auth_user_request->scheme_data) - authNTLMRequestFree ((ntlm_request_t *) auth_user_request->scheme_data); - auth_user_request->scheme_data = NULL; +authNTLMAURequestFree(auth_user_request_t * auth_user_request) +{ + if (auth_user_request->scheme_data) + authNTLMRequestFree((ntlm_request_t *) auth_user_request->scheme_data); + auth_user_request->scheme_data = NULL; } void -authenticateNTLMFreeUser (auth_user_t * auth_user) -{ - dlink_node *link, *tmplink; - ntlm_user_t *ntlm_user = auth_user->scheme_data; - auth_user_hash_pointer *proxy_auth_hash; - - debug (29, 5) ("authenticateNTLMFreeUser: Clearing NTLM scheme data\n"); - if (ntlm_user->username) - xfree (ntlm_user->username); - /* were they linked in by one or more proxy-authenticate headers */ - link = ntlm_user->proxy_auth_list.head; - while (link) - { - debug (29, 9) ("authenticateFreeProxyAuthUser: removing proxy_auth hash entry '%d'\n", link->data); - proxy_auth_hash = link->data; - tmplink = link; - link = link->next; - dlinkDelete (tmplink, &ntlm_user->proxy_auth_list); - hash_remove_link (proxy_auth_cache, (hash_link *) proxy_auth_hash); - /* free the key (usually the proxy_auth header) */ - xfree (proxy_auth_hash->key); - memFree (proxy_auth_hash, MEM_AUTH_USER_HASH); +authenticateNTLMFreeUser(auth_user_t * auth_user) +{ + dlink_node *link, *tmplink; + ntlm_user_t *ntlm_user = auth_user->scheme_data; + auth_user_hash_pointer *proxy_auth_hash; + + debug(29, 5) ("authenticateNTLMFreeUser: Clearing NTLM scheme data\n"); + if (ntlm_user->username) + xfree(ntlm_user->username); + /* were they linked in by one or more proxy-authenticate headers */ + link = ntlm_user->proxy_auth_list.head; + while (link) { + debug(29, 9) ("authenticateFreeProxyAuthUser: removing proxy_auth hash entry '%d'\n", link->data); + proxy_auth_hash = link->data; + tmplink = link; + link = link->next; + dlinkDelete(tmplink, &ntlm_user->proxy_auth_list); + hash_remove_link(proxy_auth_cache, (hash_link *) proxy_auth_hash); + /* free the key (usually the proxy_auth header) */ + xfree(proxy_auth_hash->key); + memFree(proxy_auth_hash, MEM_AUTH_USER_HASH); } - memPoolFree (ntlm_user_pool, ntlm_user); - auth_user->scheme_data = NULL; + memPoolFree(ntlm_user_pool, ntlm_user); + auth_user->scheme_data = NULL; } static stateful_helper_callback_t -authenticateNTLMHandleplaceholder (void *data, void *lastserver, char *reply) +authenticateNTLMHandleplaceholder(void *data, void *lastserver, char *reply) { - authenticateStateData *r = data; - stateful_helper_callback_t result = S_HELPER_UNKNOWN; - int valid; - /* we should only be called for placeholder requests - which have no reply string */ - assert (reply == NULL); - assert (r->auth_user_request); - /* standard callback stuff */ - valid = cbdataValid (r->data); - /* call authenticateNTLMStart to retry this request */ - debug (29, 9) ("authenticateNTLMHandleplaceholder: calling authenticateNTLMStart\n"); - authenticateNTLMStart (r->auth_user_request, r->handler, r->data); - cbdataUnlock (r->data); - authenticateStateFree (r); - return result; + authenticateStateData *r = data; + stateful_helper_callback_t result = S_HELPER_UNKNOWN; + int valid; + /* we should only be called for placeholder requests - which have no reply string */ + assert(reply == NULL); + assert(r->auth_user_request); + /* standard callback stuff */ + valid = cbdataValid(r->data); + /* call authenticateNTLMStart to retry this request */ + debug(29, 9) ("authenticateNTLMHandleplaceholder: calling authenticateNTLMStart\n"); + authenticateNTLMStart(r->auth_user_request, r->handler, r->data); + cbdataUnlock(r->data); + authenticateStateFree(r); + return result; } static stateful_helper_callback_t -authenticateNTLMHandleReply (void *data, void *lastserver, char *reply) +authenticateNTLMHandleReply(void *data, void *lastserver, char *reply) { - authenticateStateData *r = data; - ntlm_helper_state_t *helperstate; - int valid; - stateful_helper_callback_t result = S_HELPER_UNKNOWN; - char *t = NULL; - auth_user_request_t *auth_user_request; - auth_user_t *auth_user; - ntlm_user_t *ntlm_user; - ntlm_request_t *ntlm_request; - debug (29, 9) ("authenticateNTLMHandleReply: Helper: '%d' {%s}\n", lastserver, reply ? reply : ""); - valid = cbdataValid (r->data); - if (valid) - { - if (reply) - { - /* seperate out the useful data */ - if (strncasecmp (reply, "TT ", 3) == 0) - { - reply += 3; - /* we have been given a Challenge */ - /* we should check we weren't given an empty challenge */ - /* copy the challenge to the state data */ - helperstate = helperStatefulServerGetData (lastserver); - if (helperstate == NULL) - fatal ("lost NTLm helper state! quitting\n"); - helperstate->challenge = xstrndup (reply, NTLM_CHALLENGE_SZ + 5); - helperstate->challengeuses = 0; - helperstate->renewed = squid_curtime; - /* and we satisfy the request that happended on the refresh boundary */ - /* note this code is now in two places FIXME */ - assert (r->auth_user_request != NULL); - assert (r->auth_user_request->auth_user->auth_type == AUTH_NTLM); - auth_user_request = r->auth_user_request; - ntlm_request = auth_user_request->scheme_data; - assert (ntlm_request != NULL); - result = S_HELPER_DEFER; - debug (29, 9) ("authenticateNTLMHandleReply: helper '%d'\n", lastserver); - assert (ntlm_request->auth_state == AUTHENTICATE_STATE_NEGOTIATE); - ntlm_request->authhelper = lastserver; - ntlm_request->authchallenge = xstrndup (reply, NTLM_CHALLENGE_SZ + 5); - } - else if (strncasecmp (reply, "AF ", 3) == 0) - { - /* we're finished, release the helper */ - reply += 3; - assert (r->auth_user_request != NULL); - assert (r->auth_user_request->auth_user->auth_type == AUTH_NTLM); - auth_user_request = r->auth_user_request; - assert (auth_user_request->scheme_data != NULL); - ntlm_request = auth_user_request->scheme_data; - auth_user = auth_user_request->auth_user; - ntlm_user = auth_user_request->auth_user->scheme_data; - assert (ntlm_user != NULL); - result = S_HELPER_RELEASE; - /* we only expect OK when finishing the handshake */ - assert (ntlm_request->auth_state == AUTHENTICATE_STATE_RESPONSE); - ntlm_user->username = xstrndup (reply, MAX_LOGIN_SZ); - ntlm_request->authhelper = NULL; - auth_user->flags.credentials_ok = 1; /* login ok */ - } - else if (strncasecmp (reply, "NA ", 3) == 0) - { - /* TODO: only work with auth_user here if it exists */ - assert (r->auth_user_request != NULL); - assert (r->auth_user_request->auth_user->auth_type == AUTH_NTLM); - auth_user_request = r->auth_user_request; - auth_user = auth_user_request->auth_user; - assert (auth_user != NULL); - ntlm_user = auth_user->scheme_data; - ntlm_request = auth_user_request->scheme_data; - assert ((ntlm_user != NULL) && (ntlm_request != NULL)); - /* todo: action of Negotiate state on error */ - result = S_HELPER_RELEASE; /*some error has occured. no more requests */ - ntlm_request->authhelper = NULL; - auth_user->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 */ - *t = '\0'; - } - else if (strncasecmp (reply, "BH ", 3) == 0) - { - /* TODO kick off a refresh process. This can occur after a YR or after - * a KK. If after a YR release the helper and resubmit the request via - * Authenticate NTLM start. - * If after a KK deny the user's request w/ 407 and mark the helper as - * Needing YR. */ - assert (r->auth_user_request != NULL); - assert (r->auth_user_request->auth_user->auth_type == AUTH_NTLM); - auth_user_request = r->auth_user_request; - auth_user = auth_user_request->auth_user; - assert (auth_user != NULL); - ntlm_user = auth_user->scheme_data; - ntlm_request = auth_user_request->scheme_data; - assert ((ntlm_user != NULL) && (ntlm_request != NULL)); - result = S_HELPER_RELEASE; /*some error has occured. no more requests for - * this helper */ - helperstate = helperStatefulServerGetData (ntlm_request->authhelper); - ntlm_request->authhelper = NULL; - if (ntlm_request->auth_state == AUTHENTICATE_STATE_NEGOTIATE) - { - /* The helper broke on YR. It automatically - * resets */ - auth_user->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; - /* resubmit the request. This helper is currently busy, so we will get - * a different one. */ - authenticateNTLMStart (auth_user_request, r->handler, r->data); - } - else - { - /* the helper broke on a KK */ - /* first the standard KK stuff */ - auth_user->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 */ + authenticateStateData *r = data; + ntlm_helper_state_t *helperstate; + int valid; + stateful_helper_callback_t result = S_HELPER_UNKNOWN; + char *t = NULL; + auth_user_request_t *auth_user_request; + auth_user_t *auth_user; + ntlm_user_t *ntlm_user; + ntlm_request_t *ntlm_request; + debug(29, 9) ("authenticateNTLMHandleReply: Helper: '%d' {%s}\n", lastserver, reply ? reply : ""); + valid = cbdataValid(r->data); + if (valid) { + if (reply) { + /* seperate out the useful data */ + if (strncasecmp(reply, "TT ", 3) == 0) { + reply += 3; + /* we have been given a Challenge */ + /* we should check we weren't given an empty challenge */ + /* copy the challenge to the state data */ + helperstate = helperStatefulServerGetData(lastserver); + if (helperstate == NULL) + fatal("lost NTLm helper state! quitting\n"); + helperstate->challenge = xstrndup(reply, NTLM_CHALLENGE_SZ + 5); + helperstate->challengeuses = 0; + helperstate->renewed = squid_curtime; + /* and we satisfy the request that happended on the refresh boundary */ + /* note this code is now in two places FIXME */ + assert(r->auth_user_request != NULL); + assert(r->auth_user_request->auth_user->auth_type == AUTH_NTLM); + auth_user_request = r->auth_user_request; + ntlm_request = auth_user_request->scheme_data; + assert(ntlm_request != NULL); + result = S_HELPER_DEFER; + debug(29, 9) ("authenticateNTLMHandleReply: helper '%d'\n", lastserver); + assert(ntlm_request->auth_state == AUTHENTICATE_STATE_NEGOTIATE); + ntlm_request->authhelper = lastserver; + ntlm_request->authchallenge = xstrndup(reply, NTLM_CHALLENGE_SZ + 5); + } else if (strncasecmp(reply, "AF ", 3) == 0) { + /* we're finished, release the helper */ + reply += 3; + assert(r->auth_user_request != NULL); + assert(r->auth_user_request->auth_user->auth_type == AUTH_NTLM); + auth_user_request = r->auth_user_request; + assert(auth_user_request->scheme_data != NULL); + ntlm_request = auth_user_request->scheme_data; + auth_user = auth_user_request->auth_user; + ntlm_user = auth_user_request->auth_user->scheme_data; + assert(ntlm_user != NULL); + result = S_HELPER_RELEASE; + /* we only expect OK when finishing the handshake */ + assert(ntlm_request->auth_state == AUTHENTICATE_STATE_RESPONSE); + ntlm_user->username = xstrndup(reply, MAX_LOGIN_SZ); + ntlm_request->authhelper = NULL; + auth_user->flags.credentials_ok = 1; /* login ok */ + } else if (strncasecmp(reply, "NA ", 3) == 0) { + /* TODO: only work with auth_user here if it exists */ + assert(r->auth_user_request != NULL); + assert(r->auth_user_request->auth_user->auth_type == AUTH_NTLM); + auth_user_request = r->auth_user_request; + auth_user = auth_user_request->auth_user; + assert(auth_user != NULL); + ntlm_user = auth_user->scheme_data; + ntlm_request = auth_user_request->scheme_data; + assert((ntlm_user != NULL) && (ntlm_request != NULL)); + /* todo: action of Negotiate state on error */ + result = S_HELPER_RELEASE; /*some error has occured. no more requests */ + ntlm_request->authhelper = NULL; + auth_user->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 */ *t = '\0'; - /* now we mark the helper for resetting. */ - helperstate->starve = 1; + } else if (strncasecmp(reply, "BH ", 3) == 0) { + /* TODO kick off a refresh process. This can occur after a YR or after + * a KK. If after a YR release the helper and resubmit the request via + * Authenticate NTLM start. + * If after a KK deny the user's request w/ 407 and mark the helper as + * Needing YR. */ + assert(r->auth_user_request != NULL); + assert(r->auth_user_request->auth_user->auth_type == AUTH_NTLM); + auth_user_request = r->auth_user_request; + auth_user = auth_user_request->auth_user; + assert(auth_user != NULL); + ntlm_user = auth_user->scheme_data; + ntlm_request = auth_user_request->scheme_data; + assert((ntlm_user != NULL) && (ntlm_request != NULL)); + result = S_HELPER_RELEASE; /*some error has occured. no more requests for + * this helper */ + helperstate = helperStatefulServerGetData(ntlm_request->authhelper); + ntlm_request->authhelper = NULL; + if (ntlm_request->auth_state == AUTHENTICATE_STATE_NEGOTIATE) { + /* The helper broke on YR. It automatically + * resets */ + auth_user->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; + /* resubmit the request. This helper is currently busy, so we will get + * a different one. */ + authenticateNTLMStart(auth_user_request, r->handler, r->data); + } else { + /* the helper broke on a KK */ + /* first the standard KK stuff */ + auth_user->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 */ + *t = '\0'; + /* now we mark the helper for resetting. */ + helperstate->starve = 1; } - ntlm_request->auth_state = AUTHENTICATE_STATE_NONE; - } - else - { - /* TODO: only work with auth_user here if it exists */ - assert (r->auth_user_request != NULL); - assert (r->auth_user_request->auth_user->auth_type == AUTH_NTLM); - auth_user_request = r->auth_user_request; - auth_user = auth_user_request->auth_user; - assert (auth_user != NULL); - ntlm_user = auth_user->scheme_data; - ntlm_request = auth_user_request->scheme_data; - assert ((ntlm_user != NULL) && (ntlm_request != NULL)); - 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->authhelper = NULL; + ntlm_request->auth_state = AUTHENTICATE_STATE_NONE; + } else { + /* TODO: only work with auth_user here if it exists */ + assert(r->auth_user_request != NULL); + assert(r->auth_user_request->auth_user->auth_type == AUTH_NTLM); + auth_user_request = r->auth_user_request; + auth_user = auth_user_request->auth_user; + assert(auth_user != NULL); + ntlm_user = auth_user->scheme_data; + ntlm_request = auth_user_request->scheme_data; + assert((ntlm_user != NULL) && (ntlm_request != NULL)); + 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->authhelper = NULL; } + } else { + fatal("authenticateNTLMHandleReply: called with no result string\n"); } - else - { - fatal ("authenticateNTLMHandleReply: called with no result string\n"); - } - r->handler (r->data, NULL); - } - else - { - debug (29, 1) ("AuthenticateNTLMHandleReply: invalid callback data. Releasing helper '%d'.\n", lastserver); - result = S_HELPER_RELEASE; - } - cbdataUnlock (r->data); - authenticateStateFree (r); - debug (29, 9) ("NTLM HandleReply, telling stateful helper : %d\n", result); - return result; + r->handler(r->data, NULL); + } else { + debug(29, 1) ("AuthenticateNTLMHandleReply: invalid callback data. Releasing helper '%d'.\n", lastserver); + result = S_HELPER_RELEASE; + } + cbdataUnlock(r->data); + authenticateStateFree(r); + debug(29, 9) ("NTLM HandleReply, telling stateful helper : %d\n", result); + return result; } static void -authenticateNTLMStats (StoreEntry * sentry) +authenticateNTLMStats(StoreEntry * sentry) { - storeAppendPrintf (sentry, "NTLM Authenticator Statistics:\n"); - helperStatefulStats (sentry, ntlmauthenticators); + storeAppendPrintf(sentry, "NTLM Authenticator Statistics:\n"); + helperStatefulStats(sentry, ntlmauthenticators); } /* is a particular challenge still valid ? */ int -authenticateNTLMValidChallenge (ntlm_helper_state_t * helperstate) +authenticateNTLMValidChallenge(ntlm_helper_state_t * helperstate) { - if (helperstate->challenge == NULL) - return 0; - return 1; + if (helperstate->challenge == NULL) + return 0; + return 1; } /* does our policy call for changing the challenge now? */ int -authenticateNTLMChangeChallenge (ntlm_helper_state_t * helperstate) +authenticateNTLMChangeChallenge(ntlm_helper_state_t * helperstate) { - /* don't check for invalid challenges just for expiry choices */ - /* this is needed because we have to starve the helper until all old - * requests have been satisfied */ - if (!helperstate->renewed) - { - /* first use, no challenge has been set. Without this check, it will - loop forever */ - debug (29, 5) ("authenticateNTLMChangeChallenge: first use\n"); - return 0; - } - if (helperstate->challengeuses > ntlmConfig->challengeuses) - { - debug (29, 4) ("authenticateNTLMChangeChallenge: Challenge uses (%d) exceeded max uses (%d)\n", helperstate->challengeuses, ntlmConfig->challengeuses); - return 1; - } - if (helperstate->renewed + ntlmConfig->challengelifetime < squid_curtime) - { - debug (29, 4) ("authenticateNTLMChangeChallenge: Challenge exceeded max lifetime by %d seconds\n", squid_curtime - (helperstate->renewed + ntlmConfig->challengelifetime)); - return 1; + /* don't check for invalid challenges just for expiry choices */ + /* this is needed because we have to starve the helper until all old + * requests have been satisfied */ + if (!helperstate->renewed) { + /* first use, no challenge has been set. Without this check, it will + * loop forever */ + debug(29, 5) ("authenticateNTLMChangeChallenge: first use\n"); + return 0; + } + if (helperstate->challengeuses > ntlmConfig->challengeuses) { + debug(29, 4) ("authenticateNTLMChangeChallenge: Challenge uses (%d) exceeded max uses (%d)\n", helperstate->challengeuses, ntlmConfig->challengeuses); + return 1; + } + if (helperstate->renewed + ntlmConfig->challengelifetime < squid_curtime) { + debug(29, 4) ("authenticateNTLMChangeChallenge: Challenge exceeded max lifetime by %d seconds\n", squid_curtime - (helperstate->renewed + ntlmConfig->challengelifetime)); + return 1; } - debug (29, 6) ("Challenge is to be reused\n"); - return 0; + debug(29, 6) ("Challenge is to be reused\n"); + return 0; } /* send the initial data to a stateful ntlm authenticator module */ static void -authenticateNTLMStart (auth_user_request_t * auth_user_request, RH * handler, void *data) +authenticateNTLMStart(auth_user_request_t * auth_user_request, RH * handler, void *data) { - authenticateStateData *r = NULL; - helper_stateful_server *server; - ntlm_helper_state_t *helperstate; - char buf[8192]; - char *sent_string = NULL; - ntlm_user_t *ntlm_user; - ntlm_request_t *ntlm_request; - auth_user_t *auth_user; - - assert (auth_user_request); - auth_user = auth_user_request->auth_user; - ntlm_user = auth_user->scheme_data; - ntlm_request = auth_user_request->scheme_data; - assert (ntlm_user); - assert (ntlm_request); - assert (handler); - assert (data); - assert (auth_user->auth_type = AUTH_NTLM); - debug (29, 9) ("authenticateNTLMStart: auth state '%d'\n", ntlm_request->auth_state); - switch (ntlm_request->auth_state) - { + authenticateStateData *r = NULL; + helper_stateful_server *server; + ntlm_helper_state_t *helperstate; + char buf[8192]; + char *sent_string = NULL; + ntlm_user_t *ntlm_user; + ntlm_request_t *ntlm_request; + auth_user_t *auth_user; + + assert(auth_user_request); + auth_user = auth_user_request->auth_user; + ntlm_user = auth_user->scheme_data; + ntlm_request = auth_user_request->scheme_data; + assert(ntlm_user); + assert(ntlm_request); + assert(handler); + assert(data); + assert(auth_user->auth_type = AUTH_NTLM); + debug(29, 9) ("authenticateNTLMStart: auth state '%d'\n", ntlm_request->auth_state); + switch (ntlm_request->auth_state) { case AUTHENTICATE_STATE_NEGOTIATE: - sent_string = xstrdup (ntlm_request->ntlmnegotiate); - break; + sent_string = xstrdup(ntlm_request->ntlmnegotiate); + break; case AUTHENTICATE_STATE_RESPONSE: - sent_string = xstrdup (ntlm_request->ntlmauthenticate); - assert (ntlm_request->authhelper); - debug (29, 9) ("authenticateNTLMStart: Asking NTLMauthenticator '%d'.\n", ntlm_request->authhelper); - break; + sent_string = xstrdup(ntlm_request->ntlmauthenticate); + assert(ntlm_request->authhelper); + debug(29, 9) ("authenticateNTLMStart: Asking NTLMauthenticator '%d'.\n", ntlm_request->authhelper); + break; default: - fatal ("Invalid authenticate state for NTLMStart"); + fatal("Invalid authenticate state for NTLMStart"); } - while (!xisspace (*sent_string)) /*trim NTLM */ - sent_string++; + while (!xisspace(*sent_string)) /*trim NTLM */ + sent_string++; - while (xisspace (*sent_string)) /*trim leading spaces */ - sent_string++; + while (xisspace(*sent_string)) /*trim leading spaces */ + sent_string++; - debug (29, 9) ("authenticateNTLMStart: state '%d'\n", ntlm_request->auth_state); - debug (29, 9) ("authenticateNTLMStart: '%s'\n", sent_string); - if (ntlmConfig->authenticate == NULL) - { - debug (29, 0) ("authenticateNTLMStart: no NTLM program specified:'%s'\n", sent_string); - handler (data, NULL); - return; + debug(29, 9) ("authenticateNTLMStart: state '%d'\n", ntlm_request->auth_state); + debug(29, 9) ("authenticateNTLMStart: '%s'\n", sent_string); + if (ntlmConfig->authenticate == NULL) { + debug(29, 0) ("authenticateNTLMStart: no NTLM program specified:'%s'\n", sent_string); + handler(data, NULL); + return; } #ifdef NTLMHELPPROTOCOLV2 - r = CBDATA_ALLOC (authenticateStateData, NULL); - r->handler = handler; - cbdataLock (data); - r->data = data; - r->auth_user_request = auth_user_request; - snprintf (buf, 8192, "%s\n", sent_string); - helperStatefulSubmit (ntlmauthenticators, buf, authenticateNTLMHandleReply, r, ntlm_request->authhelper); - debug (29, 9) ("authenticateNTLMstart: finished\n"); + r = CBDATA_ALLOC(authenticateStateData, NULL); + r->handler = handler; + cbdataLock(data); + r->data = data; + r->auth_user_request = auth_user_request; + snprintf(buf, 8192, "%s\n", sent_string); + helperStatefulSubmit(ntlmauthenticators, buf, authenticateNTLMHandleReply, r, ntlm_request->authhelper); + debug(29, 9) ("authenticateNTLMstart: finished\n"); #else - /* this is ugly TODO: move the challenge generation routines to their own function and - * tidy the logic up to make use of the efficiency we now have */ - switch (ntlm_request->auth_state) - { + /* this is ugly TODO: move the challenge generation routines to their own function and + * tidy the logic up to make use of the efficiency we now have */ + switch (ntlm_request->auth_state) { case AUTHENTICATE_STATE_NEGOTIATE: - /* - * 1: get a helper server - * 2: does it have a challenge? - * 3: tell it to get a challenge, or give ntlmauthdone the challenge - */ - server = helperStatefulDefer (ntlmauthenticators); - helperstate = server ? helperStatefulServerGetData (server) : NULL; - while ((server != NULL) && authenticateNTLMChangeChallenge (helperstate)) - { - /* flag this helper for challenge changing */ - helperstate->starve = 1; - /* and release the deferred request */ - helperStatefulReleaseServer (server); - server = helperStatefulDefer (ntlmauthenticators); - if (server != NULL) - helperstate = helperStatefulServerGetData (server); - } - if (server == NULL) - debug (29, 9) ("unable to get a deferred ntlm helper... all helpers are refreshing challenges. Queuing as a placeholder request.\n"); - - ntlm_request->authhelper = server; - /* tell the log what helper we have been given */ - debug (29, 9) ("authenticateNTLMStart: helper '%d' assigned\n", server); - /* valid challenge? */ - if ((server == NULL) || !authenticateNTLMValidChallenge (helperstate)) - { - r = CBDATA_ALLOC (authenticateStateData, NULL); - r->handler = handler; - cbdataLock (data); - r->data = data; - r->auth_user_request = auth_user_request; - if (server == NULL) - { - helperStatefulSubmit (ntlmauthenticators, NULL, authenticateNTLMHandleplaceholder, r, ntlm_request->authhelper); - } - else - { - snprintf (buf, 8192, "YR\n"); - helperStatefulSubmit (ntlmauthenticators, buf, authenticateNTLMHandleReply, r, ntlm_request->authhelper); + /* + * 1: get a helper server + * 2: does it have a challenge? + * 3: tell it to get a challenge, or give ntlmauthdone the challenge + */ + server = helperStatefulDefer(ntlmauthenticators); + helperstate = server ? helperStatefulServerGetData(server) : NULL; + while ((server != NULL) && authenticateNTLMChangeChallenge(helperstate)) { + /* flag this helper for challenge changing */ + helperstate->starve = 1; + /* and release the deferred request */ + helperStatefulReleaseServer(server); + server = helperStatefulDefer(ntlmauthenticators); + if (server != NULL) + helperstate = helperStatefulServerGetData(server); + } + if (server == NULL) + debug(29, 9) ("unable to get a deferred ntlm helper... all helpers are refreshing challenges. Queuing as a placeholder request.\n"); + + ntlm_request->authhelper = server; + /* tell the log what helper we have been given */ + debug(29, 9) ("authenticateNTLMStart: helper '%d' assigned\n", server); + /* valid challenge? */ + if ((server == NULL) || !authenticateNTLMValidChallenge(helperstate)) { + r = CBDATA_ALLOC(authenticateStateData, NULL); + r->handler = handler; + cbdataLock(data); + r->data = data; + r->auth_user_request = auth_user_request; + if (server == NULL) { + helperStatefulSubmit(ntlmauthenticators, NULL, authenticateNTLMHandleplaceholder, r, ntlm_request->authhelper); + } else { + snprintf(buf, 8192, "YR\n"); + helperStatefulSubmit(ntlmauthenticators, buf, authenticateNTLMHandleReply, r, ntlm_request->authhelper); } - } - else - { - /* we have a valid challenge */ - /* TODO: turn the below into a function and call from here and handlereply */ - /* increment the challenge uses */ - helperstate->challengeuses++; - /* assign the challenge */ - ntlm_request->authchallenge = xstrndup (helperstate->challenge, NTLM_CHALLENGE_SZ + 5); - handler (data, NULL); + } else { + /* we have a valid challenge */ + /* TODO: turn the below into a function and call from here and handlereply */ + /* increment the challenge uses */ + helperstate->challengeuses++; + /* assign the challenge */ + ntlm_request->authchallenge = xstrndup(helperstate->challenge, NTLM_CHALLENGE_SZ + 5); + handler(data, NULL); } - break; + break; case AUTHENTICATE_STATE_RESPONSE: - r = CBDATA_ALLOC (authenticateStateData, NULL); - r->handler = handler; - cbdataLock (data); - r->data = data; - r->auth_user_request = auth_user_request; - snprintf (buf, 8192, "KK %s\n", sent_string); - helperStatefulSubmit (ntlmauthenticators, buf, authenticateNTLMHandleReply, r, ntlm_request->authhelper); - debug (29, 9) ("authenticateNTLMstart: finished\n"); - break; + r = CBDATA_ALLOC(authenticateStateData, NULL); + r->handler = handler; + cbdataLock(data); + r->data = data; + r->auth_user_request = auth_user_request; + snprintf(buf, 8192, "KK %s\n", sent_string); + helperStatefulSubmit(ntlmauthenticators, buf, authenticateNTLMHandleReply, r, ntlm_request->authhelper); + debug(29, 9) ("authenticateNTLMstart: finished\n"); + break; default: - fatal ("Invalid authenticate state for NTLMStart"); + fatal("Invalid authenticate state for NTLMStart"); } #endif } /* callback used by stateful helper routines */ int -authenticateNTLMHelperServerAvailable (void *data) +authenticateNTLMHelperServerAvailable(void *data) { - ntlm_helper_state_t *statedata = data; - if (statedata != NULL) - { - if (statedata->starve) - { - debug (29, 4) ("authenticateNTLMHelperServerAvailable: starving - returning 0\n"); - return 0; - } - else - { - debug (29, 4) ("authenticateNTLMHelperServerAvailable: not starving - returning 1\n"); - return 1; + ntlm_helper_state_t *statedata = data; + if (statedata != NULL) { + if (statedata->starve) { + debug(29, 4) ("authenticateNTLMHelperServerAvailable: starving - returning 0\n"); + return 0; + } else { + debug(29, 4) ("authenticateNTLMHelperServerAvailable: not starving - returning 1\n"); + return 1; } } - debug (29, 4) ("authenticateNTLMHelperServerAvailable: no state data - returning 0\n"); - return 0; + debug(29, 4) ("authenticateNTLMHelperServerAvailable: no state data - returning 0\n"); + return 0; } void -authenticateNTLMHelperServerOnEmpty (void *data) +authenticateNTLMHelperServerOnEmpty(void *data) { - ntlm_helper_state_t *statedata = data; - if (statedata == NULL) - return; - if (statedata->starve) - { - /* we have been starving the helper */ - debug (29, 9) ("authenticateNTLMHelperServerOnEmpty: resetting challenge details\n"); - statedata->starve = 0; - statedata->challengeuses = 0; - statedata->renewed = 0; - xfree (statedata->challenge); - statedata->challenge = NULL; + ntlm_helper_state_t *statedata = data; + if (statedata == NULL) + return; + if (statedata->starve) { + /* we have been starving the helper */ + debug(29, 9) ("authenticateNTLMHelperServerOnEmpty: resetting challenge details\n"); + statedata->starve = 0; + statedata->challengeuses = 0; + statedata->renewed = 0; + xfree(statedata->challenge); + statedata->challenge = NULL; } } /* clear the NTLM helper of being reserved for future requests */ void -authenticateNTLMReleasehelper (auth_user_request_t * auth_user_request) +authenticateNTLMReleasehelper(auth_user_request_t * auth_user_request) { - ntlm_request_t *ntlm_request; - assert (auth_user_request->auth_user->auth_type == AUTH_NTLM); - assert (auth_user_request->scheme_data != NULL); - ntlm_request = auth_user_request->scheme_data; - debug (29, 9) ("authenticateNTLMReleasehelper: releasing helper '%d'\n", ntlm_request->authhelper); - helperStatefulReleaseServer (ntlm_request->authhelper); - ntlm_request->authhelper = NULL; + ntlm_request_t *ntlm_request; + assert(auth_user_request->auth_user->auth_type == AUTH_NTLM); + assert(auth_user_request->scheme_data != NULL); + ntlm_request = auth_user_request->scheme_data; + debug(29, 9) ("authenticateNTLMReleasehelper: releasing helper '%d'\n", ntlm_request->authhelper); + helperStatefulReleaseServer(ntlm_request->authhelper); + ntlm_request->authhelper = NULL; } /* clear any connection related authentication details */ void -authenticateNTLMOnCloseConnection (ConnStateData * conn) +authenticateNTLMOnCloseConnection(ConnStateData * conn) { - ntlm_request_t *ntlm_request; - assert (conn != NULL); - if (conn->auth_user_request != NULL) - { - assert (conn->auth_user_request->scheme_data != NULL); - ntlm_request = conn->auth_user_request->scheme_data; - if (ntlm_request->authhelper != NULL) - authenticateNTLMReleasehelper (conn->auth_user_request); - /* unlock the connection based lock */ - debug (29, 9) ("authenticateNTLMOnCloseConnection: Unlocking auth_user from the connection.\n"); - authenticateAuthUserRequestUnlock (conn->auth_user_request); - conn->auth_user_request = NULL; + ntlm_request_t *ntlm_request; + assert(conn != NULL); + if (conn->auth_user_request != NULL) { + assert(conn->auth_user_request->scheme_data != NULL); + ntlm_request = conn->auth_user_request->scheme_data; + if (ntlm_request->authhelper != NULL) + authenticateNTLMReleasehelper(conn->auth_user_request); + /* unlock the connection based lock */ + debug(29, 9) ("authenticateNTLMOnCloseConnection: Unlocking auth_user from the connection.\n"); + authenticateAuthUserRequestUnlock(conn->auth_user_request); + conn->auth_user_request = NULL; } } /* authenticateUserUsername: return a pointer to the username in the */ char * -authenticateNTLMUsername (auth_user_t * auth_user) +authenticateNTLMUsername(auth_user_t * auth_user) { - ntlm_user_t *ntlm_user = auth_user->scheme_data; - if (ntlm_user) - return ntlm_user->username; - return NULL; + ntlm_user_t *ntlm_user = auth_user->scheme_data; + if (ntlm_user) + return ntlm_user->username; + return NULL; } @@ -849,192 +788,180 @@ */ void -authenticateDecodeNTLMAuth (auth_user_request_t * auth_user_request, const char *proxy_auth) +authenticateDecodeNTLMAuth(auth_user_request_t * auth_user_request, const char *proxy_auth) { - dlink_node *node; - assert (auth_user_request->auth_user == NULL); - auth_user_request->auth_user = authenticateAuthUserNew ("ntlm"); - auth_user_request->auth_user->auth_type = AUTH_NTLM; - auth_user_request->auth_user->scheme_data = memPoolAlloc (ntlm_user_pool); - auth_user_request->scheme_data = memPoolAlloc (ntlm_request_pool); - /* lock for the auth_user_request link */ - authenticateAuthUserLock (auth_user_request->auth_user); - node = dlinkNodeNew (); - dlinkAdd (auth_user_request, node, &auth_user_request->auth_user->requests); - - /* all we have to do is identify that it's NTLM - the helper does the rest */ - debug (29, 9) ("authenticateDecodeNTLMAuth: NTLM authentication\n"); - return; + dlink_node *node; + assert(auth_user_request->auth_user == NULL); + auth_user_request->auth_user = authenticateAuthUserNew("ntlm"); + auth_user_request->auth_user->auth_type = AUTH_NTLM; + auth_user_request->auth_user->scheme_data = memPoolAlloc(ntlm_user_pool); + auth_user_request->scheme_data = memPoolAlloc(ntlm_request_pool); + /* lock for the auth_user_request link */ + authenticateAuthUserLock(auth_user_request->auth_user); + node = dlinkNodeNew(); + dlinkAdd(auth_user_request, node, &auth_user_request->auth_user->requests); + + /* all we have to do is identify that it's NTLM - the helper does the rest */ + debug(29, 9) ("authenticateDecodeNTLMAuth: NTLM authentication\n"); + return; } int -authenticateNTLMcmpUsername (ntlm_user_t * u1, ntlm_user_t * u2) +authenticateNTLMcmpUsername(ntlm_user_t * u1, ntlm_user_t * u2) { - return strcmp (u1->username, u2->username); + return strcmp(u1->username, u2->username); } void -authenticateProxyAuthCacheAddLink (const char *key, auth_user_t * auth_user) +authenticateProxyAuthCacheAddLink(const char *key, auth_user_t * auth_user) { - auth_user_hash_pointer *proxy_auth_hash; - ntlm_user_t *ntlm_user; - proxy_auth_hash = memAllocate (MEM_AUTH_USER_HASH); - proxy_auth_hash->key = xstrdup (key); - proxy_auth_hash->auth_user = auth_user; - ntlm_user = auth_user->scheme_data; - dlinkAddTail (proxy_auth_hash, &proxy_auth_hash->link, &ntlm_user->proxy_auth_list); - hash_join (proxy_auth_cache, (hash_link *) proxy_auth_hash); + auth_user_hash_pointer *proxy_auth_hash; + ntlm_user_t *ntlm_user; + proxy_auth_hash = memAllocate(MEM_AUTH_USER_HASH); + proxy_auth_hash->key = xstrdup(key); + proxy_auth_hash->auth_user = auth_user; + ntlm_user = auth_user->scheme_data; + dlinkAddTail(proxy_auth_hash, &proxy_auth_hash->link, &ntlm_user->proxy_auth_list); + hash_join(proxy_auth_cache, (hash_link *) proxy_auth_hash); } int -authNTLMAuthenticated (auth_user_request_t * auth_user_request) +authNTLMAuthenticated(auth_user_request_t * auth_user_request) { - ntlm_request_t *ntlm_request = auth_user_request->scheme_data; - if (ntlm_request->auth_state == AUTHENTICATE_STATE_DONE) - return 1; - debug (29, 9) ("User not fully authenticated.\n"); - return 0; + ntlm_request_t *ntlm_request = auth_user_request->scheme_data; + if (ntlm_request->auth_state == AUTHENTICATE_STATE_DONE) + return 1; + debug(29, 9) ("User not fully authenticated.\n"); + return 0; } static void -authenticateNTLMAuthenticateUser (auth_user_request_t * auth_user_request, request_t * request, ConnStateData * conn, http_hdr_type type) +authenticateNTLMAuthenticateUser(auth_user_request_t * auth_user_request, request_t * request, ConnStateData * conn, http_hdr_type type) { - const char *proxy_auth; - auth_user_hash_pointer *usernamehash, *proxy_auth_hash = NULL; - auth_user_t *auth_user; - ntlm_request_t *ntlm_request; - ntlm_user_t *ntlm_user; - LOCAL_ARRAY (char, ntlmhash, NTLM_CHALLENGE_SZ * 2); - /* get header */ - proxy_auth = httpHeaderGetStr (&request->header, type); - - auth_user = auth_user_request->auth_user; - assert (auth_user); - assert (auth_user->auth_type == AUTH_NTLM); - assert (auth_user->scheme_data != NULL); - assert (auth_user_request->scheme_data != NULL); - ntlm_user = auth_user->scheme_data; - ntlm_request = auth_user_request->scheme_data; - switch (ntlm_request->auth_state) - { + const char *proxy_auth; + auth_user_hash_pointer *usernamehash, *proxy_auth_hash = NULL; + auth_user_t *auth_user; + ntlm_request_t *ntlm_request; + ntlm_user_t *ntlm_user; + LOCAL_ARRAY(char, ntlmhash, NTLM_CHALLENGE_SZ * 2); + /* get header */ + proxy_auth = httpHeaderGetStr(&request->header, type); + + auth_user = auth_user_request->auth_user; + assert(auth_user); + assert(auth_user->auth_type == AUTH_NTLM); + assert(auth_user->scheme_data != NULL); + assert(auth_user_request->scheme_data != NULL); + ntlm_user = auth_user->scheme_data; + ntlm_request = auth_user_request->scheme_data; + switch (ntlm_request->auth_state) { 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) - { - /* the authentication fialed badly... */ - return; - } - ntlm_request->auth_state = AUTHENTICATE_STATE_NEGOTIATE; - ntlm_request->ntlmnegotiate = xstrndup (proxy_auth, NTLM_CHALLENGE_SZ + 5); - conn->auth_type = AUTH_NTLM; - conn->auth_user_request = auth_user_request; - /* and lock for the connection duration */ - debug (29, 9) ("authenticateNTLMAuthenticateUser: Locking auth_user from the connection.\n"); - authenticateAuthUserRequestLock (auth_user_request); - return; - break; + /* 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) { + /* the authentication fialed badly... */ + return; + } + ntlm_request->auth_state = AUTHENTICATE_STATE_NEGOTIATE; + ntlm_request->ntlmnegotiate = xstrndup(proxy_auth, NTLM_CHALLENGE_SZ + 5); + conn->auth_type = AUTH_NTLM; + conn->auth_user_request = auth_user_request; + /* and lock for the connection duration */ + debug(29, 9) ("authenticateNTLMAuthenticateUser: Locking auth_user from the connection.\n"); + authenticateAuthUserRequestLock(auth_user_request); + return; + break; case AUTHENTICATE_STATE_NEGOTIATE: - ntlm_request->auth_state = AUTHENTICATE_STATE_CHALLENGE; - return; - break; + ntlm_request->auth_state = AUTHENTICATE_STATE_CHALLENGE; + return; + break; case AUTHENTICATE_STATE_CHALLENGE: - /* we should have recieved a NTLM challenge. pass it to the same - * helper process */ - debug (29, 9) ("authenticateNTLMAuthenticateUser: auth state challenge with header %s.\n", proxy_auth); - /* do a cache lookup here. If it matches it's a successful ntlm - * challenge - release the helper and use the existing auth_user - * details. */ - if (strncmp ("NTLM ", proxy_auth, 5) == 0) - { - ntlm_request->ntlmauthenticate = xstrdup (proxy_auth); - } - else - { - fatal ("Incorrect scheme in auth header\n"); - /* TODO: more fault tolerance.. reset the auth scheme here */ - } - /* cache entries have authenticateauthheaderchallengestring */ - snprintf (ntlmhash, sizeof (ntlmhash) - 1, "%s%s", ntlm_request->ntlmauthenticate, ntlm_request->authchallenge); - /* see if we already know this user's authenticate */ - debug (29, 9) ("aclMatchProxyAuth: cache lookup with key '%s'\n", ntlmhash); - assert (proxy_auth_cache != NULL); - proxy_auth_hash = hash_lookup (proxy_auth_cache, ntlmhash); - if (!proxy_auth_hash) - { /* not in the hash table */ - debug (29, 4) ("authenticateNTLMAuthenticateUser: proxy-auth cache miss.\n"); - ntlm_request->auth_state = AUTHENTICATE_STATE_RESPONSE; - /* verify with the ntlm helper */ + /* we should have recieved a NTLM challenge. pass it to the same + * helper process */ + debug(29, 9) ("authenticateNTLMAuthenticateUser: auth state challenge with header %s.\n", proxy_auth); + /* do a cache lookup here. If it matches it's a successful ntlm + * challenge - release the helper and use the existing auth_user + * details. */ + if (strncmp("NTLM ", proxy_auth, 5) == 0) { + ntlm_request->ntlmauthenticate = xstrdup(proxy_auth); + } else { + fatal("Incorrect scheme in auth header\n"); + /* TODO: more fault tolerance.. reset the auth scheme here */ + } + /* cache entries have authenticateauthheaderchallengestring */ + snprintf(ntlmhash, sizeof(ntlmhash) - 1, "%s%s", ntlm_request->ntlmauthenticate, ntlm_request->authchallenge); + /* see if we already know this user's authenticate */ + debug(29, 9) ("aclMatchProxyAuth: cache lookup with key '%s'\n", ntlmhash); + assert(proxy_auth_cache != NULL); + proxy_auth_hash = hash_lookup(proxy_auth_cache, ntlmhash); + if (!proxy_auth_hash) { /* not in the hash table */ + debug(29, 4) ("authenticateNTLMAuthenticateUser: proxy-auth cache miss.\n"); + ntlm_request->auth_state = AUTHENTICATE_STATE_RESPONSE; + /* verify with the ntlm helper */ + } else { + debug(29, 4) ("authenticateNTLMAuthenticateUser: ntlm proxy-auth cache hit\n"); + /* throw away the temporary entry */ + authenticateNTLMReleasehelper(auth_user_request); + authenticateAuthUserMerge(auth_user, proxy_auth_hash->auth_user); + auth_user = proxy_auth_hash->auth_user; + auth_user_request->auth_user = auth_user; + ntlm_request->auth_state = AUTHENTICATE_STATE_DONE; + /* we found one */ + debug(29, 9) ("found matching cache entry\n"); + assert(auth_user->auth_type == AUTH_NTLM); + /* 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 */ + /* 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; + auth_user->ip_expiretime = squid_curtime; } - else - { - debug (29, 4) ("authenticateNTLMAuthenticateUser: ntlm proxy-auth cache hit\n"); - /* throw away the temporary entry */ - authenticateNTLMReleasehelper (auth_user_request); - authenticateAuthUserMerge (auth_user, proxy_auth_hash->auth_user); - auth_user = proxy_auth_hash->auth_user; - auth_user_request->auth_user = auth_user; - ntlm_request->auth_state = AUTHENTICATE_STATE_DONE; - /* we found one */ - debug (29, 9) ("found matching cache entry\n"); - assert (auth_user->auth_type == AUTH_NTLM); - /* 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 */ - /* 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; - auth_user->ip_expiretime = squid_curtime; - } - return; - break; + return; + break; case AUTHENTICATE_STATE_RESPONSE: - /* auth-challenge pair cache miss. We've just got the response */ - /*add to cache and let them through */ - ntlm_request->auth_state = AUTHENTICATE_STATE_DONE; - /* this connection is authenticated */ - debug (29, 4) ("authenticated\nch %s\nauth %s\nauthuser %s\n", ntlm_request->authchallenge, ntlm_request->ntlmauthenticate, ntlm_user->username); - /* cache entries have authenticateauthheaderchallengestring */ - snprintf (ntlmhash, sizeof (ntlmhash) - 1, "%s%s", ntlm_request->ntlmauthenticate, ntlm_request->authchallenge); - /* see if this is an existing user with a different proxy_auth - * string */ - if ((usernamehash = hash_lookup (proxy_auth_username_cache, ntlm_user->username))) - { - while ((usernamehash->auth_user->auth_type != auth_user->auth_type) && (usernamehash->next) && !authenticateNTLMcmpUsername (usernamehash->auth_user->scheme_data, ntlm_user)) - usernamehash = usernamehash->next; - if (usernamehash->auth_user->auth_type == auth_user->auth_type) - { - /* - * add another link from the new proxy_auth to the - * auth_user structure and update the information */ - assert (proxy_auth_hash == NULL); - authenticateProxyAuthCacheAddLink (ntlmhash, usernamehash->auth_user); - /* we can't seamlessly recheck the username due to the - * challenge nature of the protocol. Just free the - * temporary auth_user */ - authenticateAuthUserMerge (auth_user, usernamehash->auth_user); - auth_user = usernamehash->auth_user; - auth_user_request->auth_user = auth_user; + /* auth-challenge pair cache miss. We've just got the response */ + /*add to cache and let them through */ + ntlm_request->auth_state = AUTHENTICATE_STATE_DONE; + /* this connection is authenticated */ + debug(29, 4) ("authenticated\nch %s\nauth %s\nauthuser %s\n", ntlm_request->authchallenge, ntlm_request->ntlmauthenticate, ntlm_user->username); + /* cache entries have authenticateauthheaderchallengestring */ + snprintf(ntlmhash, sizeof(ntlmhash) - 1, "%s%s", ntlm_request->ntlmauthenticate, ntlm_request->authchallenge); + /* see if this is an existing user with a different proxy_auth + * string */ + if ((usernamehash = hash_lookup(proxy_auth_username_cache, ntlm_user->username))) { + while ((usernamehash->auth_user->auth_type != auth_user->auth_type) && (usernamehash->next) && !authenticateNTLMcmpUsername(usernamehash->auth_user->scheme_data, ntlm_user)) + usernamehash = usernamehash->next; + if (usernamehash->auth_user->auth_type == auth_user->auth_type) { + /* + * add another link from the new proxy_auth to the + * auth_user structure and update the information */ + assert(proxy_auth_hash == NULL); + authenticateProxyAuthCacheAddLink(ntlmhash, usernamehash->auth_user); + /* we can't seamlessly recheck the username due to the + * challenge nature of the protocol. Just free the + * temporary auth_user */ + authenticateAuthUserMerge(auth_user, usernamehash->auth_user); + auth_user = usernamehash->auth_user; + auth_user_request->auth_user = auth_user; } - } - else - { - /* store user in hash's */ - authenticateUserNameCacheAdd (auth_user); - authenticateProxyAuthCacheAddLink (ntlmhash, auth_user); - } - /* 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->ip_expiretime = squid_curtime; - auth_user->flags.credentials_ok = 1; /*authenticated ok */ - return; - break; + } else { + /* store user in hash's */ + authenticateUserNameCacheAdd(auth_user); + authenticateProxyAuthCacheAddLink(ntlmhash, auth_user); + } + /* 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->ip_expiretime = squid_curtime; + auth_user->flags.credentials_ok = 1; /*authenticated ok */ + return; + break; case AUTHENTICATE_STATE_DONE: - fatal ("authenticateNTLMAuthenticateUser: unexpect auth state DONE! Report a bug to the squid developers.\n"); + fatal("authenticateNTLMAuthenticateUser: unexpect auth state DONE! Report a bug to the squid developers.\n"); } - return; + return; } Index: squid/src/auth/ntlm/helpers/NTLMSSP/libntlmssp.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/auth/ntlm/helpers/NTLMSSP/Attic/libntlmssp.c,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/ntlm/helpers/NTLMSSP/libntlmssp.c 9 Feb 2001 14:36:06 -0000 1.1.2.5 +++ squid/src/auth/ntlm/helpers/NTLMSSP/libntlmssp.c 10 Feb 2001 17:32:49 -0000 1.1.2.6 @@ -29,36 +29,37 @@ #endif /* these are part of rfcnb-priv.h and smblib-priv.h */ -extern int SMB_Get_Error_Msg (int msg, char *msgbuf, int len); -extern int SMB_Get_Last_Error (); -extern int RFCNB_Get_Last_Errno (); +extern int SMB_Get_Error_Msg(int msg, char *msgbuf, int len); +extern int SMB_Get_Last_Error(); +extern int RFCNB_Get_Last_Errno(); #include "smblib-priv.h" /* for SMB_Handle_Type */ /* a few forward-declarations. Hackish, but I don't care right now */ -SMB_Handle_Type SMB_Connect_Server (SMB_Handle_Type Con_Handle, char *server, char *NTdomain); +SMB_Handle_Type SMB_Connect_Server(SMB_Handle_Type Con_Handle, char *server, char *NTdomain); /* this one is reallllly haackiish. We really should be using anything from smblib-priv.h */ -static char *SMB_Prots[] = { "PC NETWORK PROGRAM 1.0", - "MICROSOFT NETWORKS 1.03", - "MICROSOFT NETWORKS 3.0", - "DOS LANMAN1.0", - "LANMAN1.0", - "DOS LM1.2X002", - "LM1.2X002", - "DOS LANMAN2.1", - "LANMAN2.1", - "Samba", - "NT LM 0.12", - "NT LANMAN 1.0", - NULL +static char *SMB_Prots[] = +{"PC NETWORK PROGRAM 1.0", + "MICROSOFT NETWORKS 1.03", + "MICROSOFT NETWORKS 3.0", + "DOS LANMAN1.0", + "LANMAN1.0", + "DOS LM1.2X002", + "LM1.2X002", + "DOS LANMAN2.1", + "LANMAN2.1", + "Samba", + "NT LM 0.12", + "NT LANMAN 1.0", + NULL }; #if 0 -int SMB_Discon (SMB_Handle_Type Con_Handle, BOOL KeepHandle); -int SMB_Negotiate (void *Con_Handle, char *Prots[]); -int SMB_Logon_Server (SMB_Handle_Type Con_Handle, char *UserName, char *PassWord, char *Domain, int precrypted); +int SMB_Discon(SMB_Handle_Type Con_Handle, BOOL KeepHandle); +int SMB_Negotiate(void *Con_Handle, char *Prots[]); +int SMB_Logon_Server(SMB_Handle_Type Con_Handle, char *UserName, char *PassWord, char *Domain, int precrypted); #endif #ifdef DEBUG @@ -74,80 +75,75 @@ /* Disconnects from the DC. A reconnection will be done upon the next request */ void -dc_disconnect () +dc_disconnect() { - if (handle != NULL) - SMB_Discon (handle, 0); - handle = NULL; + if (handle != NULL) + SMB_Discon(handle, 0); + handle = NULL; } int -connectedp () +connectedp() { - return (handle != NULL); + return (handle != NULL); } /* Tries to connect to a DC. Returns 0 on failure, 1 on OK */ int -is_dc_ok (char *domain, char *domain_controller) +is_dc_ok(char *domain, char *domain_controller) { - SMB_Handle_Type h = SMB_Connect_Server (NULL, domain_controller, domain); - if (h == NULL) - return 0; - SMB_Discon (h, 0); - return 1; + SMB_Handle_Type h = SMB_Connect_Server(NULL, domain_controller, domain); + if (h == NULL) + return 0; + SMB_Discon(h, 0); + return 1; } /* returns 0 on success, > 0 on failure */ static int -init_challenge (char *domain, char *domain_controller) +init_challenge(char *domain, char *domain_controller) { - int smberr; - char errstr[100]; + int smberr; + char errstr[100]; + + if (handle != NULL) { + return 0; + } + debug("Connecting to server %s domain %s\n", domain_controller, domain); + handle = SMB_Connect_Server(NULL, domain_controller, domain); + smberr = SMB_Get_Last_Error(); + SMB_Get_Error_Msg(smberr, errstr, 100); - if (handle != NULL) - { - return 0; - } - debug ("Connecting to server %s domain %s\n", domain_controller, domain); - handle = SMB_Connect_Server (NULL, domain_controller, domain); - smberr = SMB_Get_Last_Error (); - SMB_Get_Error_Msg (smberr, errstr, 100); - - - if (handle == NULL) - { /* couldn't connect */ - debug ("Couldn't connect to SMB Server. Error:%s\n", errstr); - return 1; - } - if (SMB_Negotiate (handle, SMB_Prots) < 0) - { /* An error */ - debug ("Error negotiating protocol with SMB Server\n"); - SMB_Discon (handle, 0); - handle = NULL; - return 2; - } - if (handle->Security == 0) - { /* share-level security, unuseable */ - debug ("SMB Server uses share-level security .. we need user sercurity.\n"); - SMB_Discon (handle, 0); - handle = NULL; - return 3; + + if (handle == NULL) { /* couldn't connect */ + debug("Couldn't connect to SMB Server. Error:%s\n", errstr); + return 1; + } + if (SMB_Negotiate(handle, SMB_Prots) < 0) { /* An error */ + debug("Error negotiating protocol with SMB Server\n"); + SMB_Discon(handle, 0); + handle = NULL; + return 2; + } + if (handle->Security == 0) { /* share-level security, unuseable */ + debug("SMB Server uses share-level security .. we need user sercurity.\n"); + SMB_Discon(handle, 0); + handle = NULL; + return 3; } - memcpy (challenge, handle->Encrypt_Key, NONCE_LEN); - return 0; + memcpy(challenge, handle->Encrypt_Key, NONCE_LEN); + return 0; } const char * -make_challenge (char *domain, char *domain_controller) +make_challenge(char *domain, char *domain_controller) { - if (init_challenge (domain, domain_controller) > 0) - { - return NULL; + if (init_challenge(domain, domain_controller) > 0) { + return NULL; } - return ntlm_make_challenge (domain, domain_controller, challenge, NONCE_LEN); + return ntlm_make_challenge(domain, domain_controller, challenge, NONCE_LEN); } #define min(A,B) (Adomain); - if (tmp.str == NULL) - return NULL; - memcpy (p, tmp.str, tmp.l); - p += tmp.l; - *p++ = '\\'; - tmp = ntlm_fetch_string ((char *) auth, auth_length, &auth->user); - if (tmp.str == NULL) - return NULL; - *(p + tmp.l) = '\0'; - return credentials; + char *p = credentials; + lstring tmp; + tmp = ntlm_fetch_string((char *) auth, auth_length, &auth->domain); + if (tmp.str == NULL) + return NULL; + memcpy(p, tmp.str, tmp.l); + p += tmp.l; + *p++ = '\\'; + tmp = ntlm_fetch_string((char *) auth, auth_length, &auth->user); + if (tmp.str == NULL) + return NULL; + *(p + tmp.l) = '\0'; + return credentials; } /* returns NULL on failure, or a pointer to @@ -185,66 +181,61 @@ * codes defined in ntlm.h */ char * -ntlm_check_auth (ntlm_authenticate * auth, int auth_length) +ntlm_check_auth(ntlm_authenticate * auth, int auth_length) { - int rv, retries = 0; - char pass[25]; - char *domain = credentials; - char *user; - lstring tmp; - - if (handle == NULL) - { /*if null we aren't connected, but it shouldn't happen */ - debug ("Weird, we've been disconnected\n"); - ntlm_errno = NTLM_NOT_CONNECTED; - return NULL; - } - /* Authenticating against the NT response doesn't seem to work... */ - tmp = ntlm_fetch_string ((char *) auth, auth_length, &auth->lmresponse); - if (tmp.str == NULL) - { - fprintf (stderr, "No auth at all. Returning no-auth\n"); - ntlm_errno = NTLM_LOGON_ERROR; - return NULL; + int rv, retries = 0; + char pass[25]; + char *domain = credentials; + char *user; + lstring tmp; + + if (handle == NULL) { /*if null we aren't connected, but it shouldn't happen */ + debug("Weird, we've been disconnected\n"); + ntlm_errno = NTLM_NOT_CONNECTED; + return NULL; + } + /* Authenticating against the NT response doesn't seem to work... */ + tmp = ntlm_fetch_string((char *) auth, auth_length, &auth->lmresponse); + if (tmp.str == NULL) { + fprintf(stderr, "No auth at all. Returning no-auth\n"); + ntlm_errno = NTLM_LOGON_ERROR; + return NULL; } - memcpy (pass, tmp.str, tmp.l); - pass[25] = '\0'; + memcpy(pass, tmp.str, tmp.l); + pass[25] = '\0'; /* debug("fetching domain\n"); */ - tmp = ntlm_fetch_string ((char *) auth, auth_length, &auth->domain); - if (tmp.str == NULL) - { - debug ("No domain supplied. Returning no-auth\n"); - ntlm_errno = NTLM_LOGON_ERROR; - return NULL; - } - memcpy (domain, tmp.str, tmp.l); - user = domain + tmp.l; - *user++ = '\0'; + tmp = ntlm_fetch_string((char *) auth, auth_length, &auth->domain); + if (tmp.str == NULL) { + debug("No domain supplied. Returning no-auth\n"); + ntlm_errno = NTLM_LOGON_ERROR; + return NULL; + } + memcpy(domain, tmp.str, tmp.l); + user = domain + tmp.l; + *user++ = '\0'; /* debug("fetching user name\n"); */ - tmp = ntlm_fetch_string ((char *) auth, auth_length, &auth->user); - if (tmp.str == NULL) - { - debug ("No username supplied. Returning no-auth\n"); - ntlm_errno = NTLM_LOGON_ERROR; - return NULL; - } - memcpy (user, tmp.str, tmp.l); - *(user + tmp.l) = '\0'; - - debug ("checking domain: '%s', user: '%s', pass='%s'\n", domain, user, pass); - - rv = SMB_Logon_Server (handle, user, pass, domain, 1); - debug ("Login attempt had result %d\n", rv); - - if (rv != NTV_NO_ERROR) - { /* failed */ - ntlm_errno = rv; - return NULL; + tmp = ntlm_fetch_string((char *) auth, auth_length, &auth->user); + if (tmp.str == NULL) { + debug("No username supplied. Returning no-auth\n"); + ntlm_errno = NTLM_LOGON_ERROR; + return NULL; + } + memcpy(user, tmp.str, tmp.l); + *(user + tmp.l) = '\0'; + + debug("checking domain: '%s', user: '%s', pass='%s'\n", domain, user, pass); + + rv = SMB_Logon_Server(handle, user, pass, domain, 1); + debug("Login attempt had result %d\n", rv); + + if (rv != NTV_NO_ERROR) { /* failed */ + ntlm_errno = rv; + return NULL; } - *(user - 1) = '\\'; /* hack. Performing, but ugly. */ + *(user - 1) = '\\'; /* hack. Performing, but ugly. */ - debug ("credentials: %s\n", credentials); - return credentials; + debug("credentials: %s\n", credentials); + return credentials; } Index: squid/src/auth/ntlm/helpers/NTLMSSP/ntlm.h =================================================================== RCS file: /cvsroot/squid-sf//squid/src/auth/ntlm/helpers/NTLMSSP/Attic/ntlm.h,v retrieving revision 1.1.2.4 retrieving revision 1.1.2.5 diff -u -r1.1.2.4 -r1.1.2.5 --- squid/src/auth/ntlm/helpers/NTLMSSP/ntlm.h 31 Jan 2001 13:17:20 -0000 1.1.2.4 +++ squid/src/auth/ntlm/helpers/NTLMSSP/ntlm.h 10 Feb 2001 17:32:49 -0000 1.1.2.5 @@ -78,7 +78,7 @@ const char *make_challenge(char *domain, char *controller); extern char *ntlm_check_auth(ntlm_authenticate * auth, int auth_length); -extern char *fetch_credentials (ntlm_authenticate *auth, int auth_length); +extern char *fetch_credentials(ntlm_authenticate * auth, int auth_length); void dc_disconnect(void); int connectedp(void); int is_dc_ok(char *domain, char *domain_controller); Index: squid/src/auth/ntlm/helpers/NTLMSSP/ntlm_auth.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/auth/ntlm/helpers/NTLMSSP/Attic/ntlm_auth.c,v retrieving revision 1.1.2.11 retrieving revision 1.1.2.12 diff -u -r1.1.2.11 -r1.1.2.12 --- squid/src/auth/ntlm/helpers/NTLMSSP/ntlm_auth.c 9 Feb 2001 14:37:07 -0000 1.1.2.11 +++ squid/src/auth/ntlm/helpers/NTLMSSP/ntlm_auth.c 10 Feb 2001 17:32:49 -0000 1.1.2.12 @@ -23,10 +23,10 @@ #include "smbval/rfcnb-error.h" /* these are part of rfcnb-priv.h and smblib-priv.h */ -extern int SMB_Get_Error_Msg (int msg, char *msgbuf, int len); -extern int SMB_Get_Last_Error (); -extern int SMB_Get_Last_SMB_Err (); -extern int RFCNB_Get_Last_Error (); +extern int SMB_Get_Error_Msg(int msg, char *msgbuf, int len); +extern int SMB_Get_Last_Error(); +extern int SMB_Get_Last_SMB_Err(); +extern int RFCNB_Get_Last_Error(); #include @@ -60,62 +60,54 @@ /* housekeeping cycle and periodic operations */ static unsigned char need_dc_resurrection = 0; static void -resurrect_dead_dc () +resurrect_dead_dc() { - int j; - dc *c = controllers; + int j; + dc *c = controllers; - need_dc_resurrection = 0; - for (j = 0; j < numcontrollers; j++) - if (c->status != DC_OK && is_dc_ok (c->domain, c->controller)) - c->status = DC_OK; + need_dc_resurrection = 0; + for (j = 0; j < numcontrollers; j++) + if (c->status != DC_OK && is_dc_ok(c->domain, c->controller)) + c->status = DC_OK; } /* makes a null-terminated string upper-case. Changes CONTENTS! */ static void -uc (char *string) +uc(char *string) { - char *p = string, c; - while ((c = *p)) - { - *p = toupper (c); - p++; + char *p = string, c; + while ((c = *p)) { + *p = toupper(c); + p++; } } /* makes a null-terminated string lower-case. Changes CONTENTS! */ static void -lc (char *string) +lc(char *string) { - char *p = string, c; - while ((c = *p)) - { - *p = tolower (c); - p++; + char *p = string, c; + while ((c = *p)) { + *p = tolower(c); + p++; } } void -send_bh_or_ld (char *bhmessage, ntlm_authenticate * failedauth, int authlen) +send_bh_or_ld(char *bhmessage, ntlm_authenticate * failedauth, int authlen) { - char *creds = NULL; - if (last_ditch_enabled) - { - creds = fetch_credentials (failedauth, authlen); - if (creds) - { - lc (creds); - SEND2 ("LD %s", creds); - } - else - { - SEND ("NA last-ditch on, but no credentials"); - } - } - else - { - SEND (bhmessage); + char *creds = NULL; + if (last_ditch_enabled) { + creds = fetch_credentials(failedauth, authlen); + if (creds) { + lc(creds); + SEND2("LD %s", creds); + } else { + SEND("NA last-ditch on, but no credentials"); + } + } else { + SEND(bhmessage); } } @@ -129,418 +121,387 @@ char *my_program_name = NULL; void -usage () +usage() { - fprintf (stderr, - "%s usage:\n" - "%s [-b] [-f] domain\\controller [domain\\controller ...]\n" - "-b, if specified, enables load-balancing among controllers\n" - "-f, if specified, enables failover among controllers\n" - "-l, if specified, changes behavior on domain controller failyures to" "\tlast-ditch\n\n" "You MUST specify at least one Domain Controller.\n" "You can use either \\ or / as separator between the domain name \n" "\tand the controller name\n", my_program_name, my_program_name); + fprintf(stderr, + "%s usage:\n" + "%s [-b] [-f] domain\\controller [domain\\controller ...]\n" + "-b, if specified, enables load-balancing among controllers\n" + "-f, if specified, enables failover among controllers\n" + "-l, if specified, changes behavior on domain controller failyures to" "\tlast-ditch\n\n" "You MUST specify at least one Domain Controller.\n" "You can use either \\ or / as separator between the domain name \n" "\tand the controller name\n", my_program_name, my_program_name); } void -process_options (int argc, char *argv[]) +process_options(int argc, char *argv[]) { - int opt, j, had_error = 0; - dc *new_dc = NULL, *last_dc = NULL; - while (-1 != (opt = getopt (argc, argv, "bfl"))) - { - switch (opt) - { + int opt, j, had_error = 0; + dc *new_dc = NULL, *last_dc = NULL; + while (-1 != (opt = getopt(argc, argv, "bfl"))) { + switch (opt) { case 'b': - load_balance = 1; - break; + load_balance = 1; + break; case 'f': - failover_enabled = 1; - break; + failover_enabled = 1; + break; case 'l': - last_ditch_enabled = 1; - break; + last_ditch_enabled = 1; + break; default: - fprintf (stderr, "unknown option: -%c. Exiting\n", opt); - usage (); - had_error = 1; - } - } - if (had_error) - exit (1); - /* Okay, now begin filling controllers up */ - /* we can avoid memcpy-ing, and just reuse argv[] */ - for (j = optind; j < argc; j++) - { - char *d, *c; - /* d will not be freed in case of non-error. Since we don't reconfigure, - * it's going to live as long as the process anyways */ - d = malloc (strlen (argv[j]) + 1); - strcpy (d, argv[j]); - debug ("Adding domain-controller %s\n", d); - if (NULL == (c = strchr (d, '\\')) && NULL == (c = strchr (d, '/'))) - { - fprintf (stderr, "Couldn't grok domain-controller %s\n", d); - free (d); - continue; - } - /* more than one delimiter is not allowed */ - if (NULL != strchr (c + 1, '\\') || NULL != strchr (c + 1, '/')) - { - fprintf (stderr, "Broken domain-controller %s\n", d); - free (d); - continue; - } - *c++ = '\0'; - new_dc = (dc *) malloc (sizeof (dc)); - if (!new_dc) - { - fprintf (stderr, "Malloc error while parsing DC options\n"); - free (d); - continue; - } - /* capitalize */ - uc (c); - uc (d); - numcontrollers++; - new_dc->domain = d; - new_dc->controller = c; - new_dc->status = DC_OK; - if (controllers == NULL) - { /* first controller */ - controllers = new_dc; - last_dc = new_dc; - } - else - { - last_dc->next = new_dc; /* can't be null */ - last_dc = new_dc; - } - } - if (numcontrollers == 0) - { - fprintf (stderr, "You must specify at least one domain-controller!\n"); - usage (); - exit (1); + fprintf(stderr, "unknown option: -%c. Exiting\n", opt); + usage(); + had_error = 1; + } + } + if (had_error) + exit(1); + /* Okay, now begin filling controllers up */ + /* we can avoid memcpy-ing, and just reuse argv[] */ + for (j = optind; j < argc; j++) { + char *d, *c; + /* d will not be freed in case of non-error. Since we don't reconfigure, + * it's going to live as long as the process anyways */ + d = malloc(strlen(argv[j]) + 1); + strcpy(d, argv[j]); + debug("Adding domain-controller %s\n", d); + if (NULL == (c = strchr(d, '\\')) && NULL == (c = strchr(d, '/'))) { + fprintf(stderr, "Couldn't grok domain-controller %s\n", d); + free(d); + continue; + } + /* more than one delimiter is not allowed */ + if (NULL != strchr(c + 1, '\\') || NULL != strchr(c + 1, '/')) { + fprintf(stderr, "Broken domain-controller %s\n", d); + free(d); + continue; + } + *c++ = '\0'; + new_dc = (dc *) malloc(sizeof(dc)); + if (!new_dc) { + fprintf(stderr, "Malloc error while parsing DC options\n"); + free(d); + continue; + } + /* capitalize */ + uc(c); + uc(d); + numcontrollers++; + new_dc->domain = d; + new_dc->controller = c; + new_dc->status = DC_OK; + if (controllers == NULL) { /* first controller */ + controllers = new_dc; + last_dc = new_dc; + } else { + last_dc->next = new_dc; /* can't be null */ + last_dc = new_dc; + } + } + if (numcontrollers == 0) { + fprintf(stderr, "You must specify at least one domain-controller!\n"); + usage(); + exit(1); } - last_dc->next = controllers; /* close the queue, now it's circular */ + last_dc->next = controllers; /* close the queue, now it's circular */ } /* tries connecting to the domain controllers in the "controllers" ring, * with failover if the adequate option is specified. */ const char * -obtain_challenge () +obtain_challenge() { - int j = 0; - const char *ch; - debug ("obtain_challenge: getting new challenge\n"); - for (j = 0; j < numcontrollers; j++) - { - if (current_dc->status == DC_OK) - { - debug ("getting challenge from %s\%s\n", current_dc->domain, current_dc->controller); - ch = make_challenge (current_dc->domain, current_dc->controller); - if (ch) - return ch; /* All went OK, returning */ - /* Huston, we've got a problem. Take this DC out of the loop */ - debug ("Marking DC as DEAD\n"); - current_dc->status = DC_DEAD; - need_dc_resurrection = 1; - } - if (failover_enabled == 0) /* No failover. Just return */ - return NULL; - /* Try with the next */ - current_dc = current_dc->next; + int j = 0; + const char *ch; + debug("obtain_challenge: getting new challenge\n"); + for (j = 0; j < numcontrollers; j++) { + if (current_dc->status == DC_OK) { + debug("getting challenge from %s\%s\n", current_dc->domain, current_dc->controller); + ch = make_challenge(current_dc->domain, current_dc->controller); + if (ch) + return ch; /* All went OK, returning */ + /* Huston, we've got a problem. Take this DC out of the loop */ + debug("Marking DC as DEAD\n"); + current_dc->status = DC_DEAD; + need_dc_resurrection = 1; + } + if (failover_enabled == 0) /* No failover. Just return */ + return NULL; + /* Try with the next */ + current_dc = current_dc->next; } - /* DC (all DCs if failover is enabled) failed. */ - return NULL; + /* DC (all DCs if failover is enabled) failed. */ + return NULL; } void -manage_request () +manage_request() { - ntlmhdr *fast_header; - char buf[BUFFER_SIZE]; - const char *ch; - char *ch2, *decoded, *cred; - int plen; - - if (fgets (buf, BUFFER_SIZE, stdin) == NULL) - { - fprintf (stderr, "fgets() failed! dying..... errno=%d (%s)\n", errno, strerror (errno)); - abort (); - exit (1); /* BIIG buffer */ - } - debug ("managing request\n"); - ch2 = memchr (buf, '\n', BUFFER_SIZE); /* safer against overrun than strchr */ - if (ch2) - { - *ch2 = '\0'; /* terminate the string at newline. */ - ch = ch2; - } - debug ("ntlm authenticator. Got '%s' from Squid\n", buf); - - if (memcmp (buf, "KK ", 3) == 0) - { /* authenticate-request */ - /* figure out what we got */ - decoded = base64_decode (buf + 3); - /* Note: we don't need to manage memory at this point, since - * base64_decode returns a pointer to static storage. - */ - - if (!decoded) - { /* decoding failure, return error */ - SEND ("NA Packet format error, couldn't base64-decode"); - return; - } - /* fast-track-decode request type. */ - fast_header = (struct _ntlmhdr *) decoded; - - /* sanity-check: it IS a NTLMSSP packet, isn't it? */ - if (memcmp (fast_header->signature, "NTLMSSP", 8) != 0) - { - SEND ("NA Broken authentication packet"); - return; + ntlmhdr *fast_header; + char buf[BUFFER_SIZE]; + const char *ch; + char *ch2, *decoded, *cred; + int plen; + + if (fgets(buf, BUFFER_SIZE, stdin) == NULL) { + fprintf(stderr, "fgets() failed! dying..... errno=%d (%s)\n", errno, strerror(errno)); + abort(); + exit(1); /* BIIG buffer */ + } + debug("managing request\n"); + ch2 = memchr(buf, '\n', BUFFER_SIZE); /* safer against overrun than strchr */ + if (ch2) { + *ch2 = '\0'; /* terminate the string at newline. */ + ch = ch2; + } + debug("ntlm authenticator. Got '%s' from Squid\n", buf); + + if (memcmp(buf, "KK ", 3) == 0) { /* authenticate-request */ + /* figure out what we got */ + decoded = base64_decode(buf + 3); + /* Note: we don't need to manage memory at this point, since + * base64_decode returns a pointer to static storage. + */ + + if (!decoded) { /* decoding failure, return error */ + SEND("NA Packet format error, couldn't base64-decode"); + return; + } + /* fast-track-decode request type. */ + fast_header = (struct _ntlmhdr *) decoded; + + /* sanity-check: it IS a NTLMSSP packet, isn't it? */ + if (memcmp(fast_header->signature, "NTLMSSP", 8) != 0) { + SEND("NA Broken authentication packet"); + return; } - switch (fast_header->type) - { + switch (fast_header->type) { case NTLM_NEGOTIATE: - SEND ("NA Invalid negotiation request received"); - return; - /* notreached */ + SEND("NA Invalid negotiation request received"); + return; + /* notreached */ case NTLM_CHALLENGE: - SEND ("NA Got a challenge. We refuse to have our authority disputed"); - return; - /* notreached */ + SEND("NA Got a challenge. We refuse to have our authority disputed"); + return; + /* notreached */ case NTLM_AUTHENTICATE: - /* check against the DC */ - plen = strlen (buf) * 3 / 4; /* we only need it here. Optimization */ - cred = ntlm_check_auth ((ntlm_authenticate *) decoded, plen); + /* check against the DC */ + plen = strlen(buf) * 3 / 4; /* we only need it here. Optimization */ + cred = ntlm_check_auth((ntlm_authenticate *) decoded, plen); #ifdef OLDCRUFT - if (cred == NULL) - { - int errorclass, errorcode; + if (cred == NULL) { + int errorclass, errorcode; #ifdef DEBUG - SMB_Get_Error_Msg (SMB_Get_Last_SMB_Err (), error_messages_buffer, BUFFER_SIZE); - debug ("Authentication failure. SMB error: %d: %s\n. Class=%d, Code=%d\n", SMB_Get_Last_SMB_Err (), error_messages_buffer, SMB_Get_Last_SMB_Err () & 0xff, SMB_Get_Last_SMB_Err () >> 16); - RFCNB_Get_Error_Msg (RFCNB_Get_Last_Error (), error_messages_buffer, BUFFER_SIZE); - debug ("RFCNB error status: code=%d (%s)\n", RFCNB_Get_Last_Error (), error_messages_buffer); + SMB_Get_Error_Msg(SMB_Get_Last_SMB_Err(), error_messages_buffer, BUFFER_SIZE); + debug("Authentication failure. SMB error: %d: %s\n. Class=%d, Code=%d\n", SMB_Get_Last_SMB_Err(), error_messages_buffer, SMB_Get_Last_SMB_Err() & 0xff, SMB_Get_Last_SMB_Err() >> 16); + RFCNB_Get_Error_Msg(RFCNB_Get_Last_Error(), error_messages_buffer, BUFFER_SIZE); + debug("RFCNB error status: code=%d (%s)\n", RFCNB_Get_Last_Error(), error_messages_buffer); #endif - /* This is kind of a special case, which happens when the - client sends credentials in a domain which is not trusted - by the domain we're using when authenticating. Unfortunately, - it can't currently be accommodated in the current framework so - I'll leave it hanging here, waiting for the general framework - to be expanded to better accommodate the generale case. */ - errorclass = SMB_Get_Last_SMB_Err () & 0xff; - errorcode = SMB_Get_Last_SMB_Err () >> 16; - if (errorclass == 1 && errorcode == 5) - { - SEND ("NA Wrong password or untrusted domain"); - return; + /* This is kind of a special case, which happens when the + * client sends credentials in a domain which is not trusted + * by the domain we're using when authenticating. Unfortunately, + * it can't currently be accommodated in the current framework so + * I'll leave it hanging here, waiting for the general framework + * to be expanded to better accommodate the generale case. */ + errorclass = SMB_Get_Last_SMB_Err() & 0xff; + errorcode = SMB_Get_Last_SMB_Err() >> 16; + if (errorclass == 1 && errorcode == 5) { + SEND("NA Wrong password or untrusted domain"); + return; } - switch (ntlm_errno) - { + switch (ntlm_errno) { case NTLM_LOGON_ERROR: - SEND ("NA authentication failure"); - /* I must have been drugged when I wrote the following two lines */ - /* dc_disconnect(); - current_dc = current_dc->next; */ - return; + SEND("NA authentication failure"); + /* I must have been drugged when I wrote the following two lines */ + /* dc_disconnect(); + * current_dc = current_dc->next; */ + return; case NTLM_SERVER_ERROR: - send_bh_or_ld ("BH Domain Controller Error", (ntlm_authenticate *) decoded, plen); - /* SEND("BH Domain Controller Error"); */ - /* we don't really need to disconnect NOW. - Besides, we asked squid to force a reconnect. This way, if we - have authentications in flight, we might even succeed. - */ - /* dc_disconnect(); */ - - SMB_Get_Error_Msg (SMB_Get_Last_Error (), smb_error_buffer, 1000); - debug ("Last error was: %s, RFC errno=%d\n", smb_error_buffer, RFCNB_Get_Last_Errno ()); - if (failover_enabled) - current_dc = current_dc->next; - return; + send_bh_or_ld("BH Domain Controller Error", (ntlm_authenticate *) decoded, plen); + /* SEND("BH Domain Controller Error"); */ + /* we don't really need to disconnect NOW. + * Besides, we asked squid to force a reconnect. This way, if we + * have authentications in flight, we might even succeed. + */ + /* dc_disconnect(); */ + + SMB_Get_Error_Msg(SMB_Get_Last_Error(), smb_error_buffer, 1000); + debug("Last error was: %s, RFC errno=%d\n", smb_error_buffer, RFCNB_Get_Last_Errno()); + if (failover_enabled) + current_dc = current_dc->next; + return; case NTLM_PROTOCOL_ERROR: - send_bh_or_ld ("BH Domain Controller communication error", (ntlm_authenticate *) decoded, plen); - /* SEND("BH Domain Controller communication error"); */ - /* dc_disconnect(); */ - if (failover_enabled) - current_dc = current_dc->next; - return; + send_bh_or_ld("BH Domain Controller communication error", (ntlm_authenticate *) decoded, plen); + /* SEND("BH Domain Controller communication error"); */ + /* dc_disconnect(); */ + if (failover_enabled) + current_dc = current_dc->next; + return; case NTLM_NOT_CONNECTED: - send_bh_or_ld ("BH Domain Controller (or network) died on us", (ntlm_authenticate *) decoded, plen); - /* SEND("BH Domain Controller (or network) died on us"); */ - /* dc_disconnect(); */ - if (failover_enabled) - current_dc = current_dc->next; - return; + send_bh_or_ld("BH Domain Controller (or network) died on us", (ntlm_authenticate *) decoded, plen); + /* SEND("BH Domain Controller (or network) died on us"); */ + /* dc_disconnect(); */ + if (failover_enabled) + current_dc = current_dc->next; + return; case NTLM_BAD_PROTOCOL: - send_bh_or_ld ("BH Domain controller failure", (ntlm_authenticate *) decoded, plen); - /* SEND("BH Domain controller failure"); */ -/* dc_disconnect(); *//* maybe we're overreacting? */ - SMB_Get_Error_Msg (SMB_Get_Last_Error (), smb_error_buffer, 1000); - debug ("Last error was: %s. RFCNB errno=%d\n", smb_error_buffer, RFCNB_Get_Last_Errno ()); - if (failover_enabled) - current_dc = current_dc->next; - return; + send_bh_or_ld("BH Domain controller failure", (ntlm_authenticate *) decoded, plen); + /* SEND("BH Domain controller failure"); */ + /* dc_disconnect(); *//* maybe we're overreacting? */ + SMB_Get_Error_Msg(SMB_Get_Last_Error(), smb_error_buffer, 1000); + debug("Last error was: %s. RFCNB errno=%d\n", smb_error_buffer, RFCNB_Get_Last_Errno()); + if (failover_enabled) + current_dc = current_dc->next; + return; default: - send_bh_or_ld ("BH Unhandled error while talking to Domain Controller", (ntlm_authenticate *) decoded, plen); - /* SEND("BH Unhandled error while talking to Domain Controller"); */ -/* dc_disconnect(); *//* maybe we're overreacting? */ - if (failover_enabled) - current_dc = current_dc->next; - return; + send_bh_or_ld("BH Unhandled error while talking to Domain Controller", (ntlm_authenticate *) decoded, plen); + /* SEND("BH Unhandled error while talking to Domain Controller"); */ + /* dc_disconnect(); *//* maybe we're overreacting? */ + if (failover_enabled) + current_dc = current_dc->next; + return; } } #else /* OLDCRUFT */ - if (cred == NULL) - { - int smblib_err, smb_errorclass, smb_errorcode, nb_error; - /* there was an error. We have two errno's to look at. - * libntlmssp's erno is insufficient, we'll have to look at - * the actual SMB library error codes, to acually figure - * out what's happening. The thing has braindamaged interfacess..*/ - smblib_err = SMB_Get_Last_Error (); - smb_errorclass = SMBlib_Error_Class (SMB_Get_Last_SMB_Err ()); - smb_errorcode = SMBlib_Error_Code (SMB_Get_Last_SMB_Err ()); - nb_error = RFCNB_Get_Last_Error (); - debug ("No creds. SMBlib error %d, SMB error class %d, " "SMB error code %d, NB error %d\n", smblib_err, smb_errorclass, smb_errorcode, nb_error); - /* Should I use smblib_err? Actually it seems I can do as well - * without it.. */ - if (nb_error != 0) - { /* netbios-level error */ - send_bh_or_ld ("NetBios error!", (ntlm_authenticate *) decoded, plen); - fprintf (stderr, "NetBios error code %d (%s)\n", nb_error, RFCNB_Error_Strings[abs (nb_error)]); - return; + if (cred == NULL) { + int smblib_err, smb_errorclass, smb_errorcode, nb_error; + /* there was an error. We have two errno's to look at. + * libntlmssp's erno is insufficient, we'll have to look at + * the actual SMB library error codes, to acually figure + * out what's happening. The thing has braindamaged interfacess..*/ + smblib_err = SMB_Get_Last_Error(); + smb_errorclass = SMBlib_Error_Class(SMB_Get_Last_SMB_Err()); + smb_errorcode = SMBlib_Error_Code(SMB_Get_Last_SMB_Err()); + nb_error = RFCNB_Get_Last_Error(); + debug("No creds. SMBlib error %d, SMB error class %d, " "SMB error code %d, NB error %d\n", smblib_err, smb_errorclass, smb_errorcode, nb_error); + /* Should I use smblib_err? Actually it seems I can do as well + * without it.. */ + if (nb_error != 0) { /* netbios-level error */ + send_bh_or_ld("NetBios error!", (ntlm_authenticate *) decoded, plen); + fprintf(stderr, "NetBios error code %d (%s)\n", nb_error, RFCNB_Error_Strings[abs(nb_error)]); + return; } - switch (smb_errorclass) - { + switch (smb_errorclass) { case SMBC_SUCCESS: - debug ("Huh? Got a SMB success code but could check auth.."); - SEND ("NA Authentication failed"); - /* - send_bh_or_ld("SMB success, but no creds. Internal error?", - (ntlm_authenticate *) decoded, plen); - */ - return; + debug("Huh? Got a SMB success code but could check auth.."); + SEND("NA Authentication failed"); + /* + * send_bh_or_ld("SMB success, but no creds. Internal error?", + * (ntlm_authenticate *) decoded, plen); + */ + return; case SMBC_ERRDOS: - /*this is the most important one for errors */ - debug ("DOS error\n"); - switch (smb_errorcode) - { - /* two categories matter to us: those which could be - server errors, and those which are auth errors */ + /*this is the most important one for errors */ + debug("DOS error\n"); + switch (smb_errorcode) { + /* two categories matter to us: those which could be + * server errors, and those which are auth errors */ case SMBD_noaccess: /* 5 */ - SEND ("NA Access denied"); - return; + SEND("NA Access denied"); + return; case SMBD_badformat: - SEND ("NA bad format in authentication packet"); - return; + SEND("NA bad format in authentication packet"); + return; case SMBD_badaccess: - SEND ("NA Bad access request"); - return; + SEND("NA Bad access request"); + return; case SMBD_baddata: - SEND ("NA Bad Data"); - return; + SEND("NA Bad Data"); + return; default: - send_bh_or_ld ("DOS Error", (ntlm_authenticate *) decoded, plen); - return; + send_bh_or_ld("DOS Error", (ntlm_authenticate *) decoded, plen); + return; } case SMBC_ERRSRV: /* server errors */ - debug ("Server error"); - switch (smb_errorcode) - { - /* mostly same as above */ + debug("Server error"); + switch (smb_errorcode) { + /* mostly same as above */ case SMBV_badpw: - SEND ("NA Bad password"); - return; + SEND("NA Bad password"); + return; case SMBV_access: - SEND ("NA Server access error"); - return; + SEND("NA Server access error"); + return; default: - send_bh_or_ld ("Server Error", (ntlm_authenticate *) decoded, plen); - return; + send_bh_or_ld("Server Error", (ntlm_authenticate *) decoded, plen); + return; } case SMBC_ERRHRD: /* hardware errors don't really matter */ - send_bh_or_ld ("Domain Controller Hardware error", (ntlm_authenticate *) decoded, plen); - return; + send_bh_or_ld("Domain Controller Hardware error", (ntlm_authenticate *) decoded, plen); + return; case SMBC_ERRCMD: - send_bh_or_ld ("Domain Controller Command Error", (ntlm_authenticate *) decoded, plen); - return; + send_bh_or_ld("Domain Controller Command Error", (ntlm_authenticate *) decoded, plen); + return; } } #endif /* OLDCRUFT */ - lc (cred); /* let's lowercase them for our convenience */ - SEND2 ("AF %s", cred); - return; + lc(cred); /* let's lowercase them for our convenience */ + SEND2("AF %s", cred); + return; default: - SEND ("BH unknown authentication packet type"); - return; + SEND("BH unknown authentication packet type"); + return; } - return; + return; } - if (memcmp (buf, "YR", 2) == 0) - { /* refresh-request */ - dc_disconnect (); - ch = obtain_challenge (); - /* Robert says we can afford to wait forever. I'll trust him on this - one */ - while (ch == NULL) - { - sleep (30); - ch = obtain_challenge (); - } - SEND2 ("TT %s", ch); - if (need_dc_resurrection) /* looks like a good moment... */ - resurrect_dead_dc (); - return; + if (memcmp(buf, "YR", 2) == 0) { /* refresh-request */ + dc_disconnect(); + ch = obtain_challenge(); + /* Robert says we can afford to wait forever. I'll trust him on this + * one */ + while (ch == NULL) { + sleep(30); + ch = obtain_challenge(); + } + SEND2("TT %s", ch); + if (need_dc_resurrection) /* looks like a good moment... */ + resurrect_dead_dc(); + return; } - SEND ("BH Helper detected protocol error"); - return; + SEND("BH Helper detected protocol error"); + return; /********* END ********/ } int -main (int argc, char *argv[]) +main(int argc, char *argv[]) { - debug ("ntlm_auth build " __DATE__ ", " __TIME__ " starting up...\n"); + debug("ntlm_auth build " __DATE__ ", " __TIME__ " starting up...\n"); #ifdef DEBUG - debug ("changing dir to /tmp"); - chdir ("/tmp"); + debug("changing dir to /tmp"); + chdir("/tmp"); #endif - my_program_name = argv[0]; - process_options (argc, argv); + my_program_name = argv[0]; + process_options(argc, argv); - debug ("options processed OK\n"); + debug("options processed OK\n"); - /* initialize FDescs */ - setbuf (stdout, NULL); - setbuf (stderr, NULL); - - /* select the first domain controller we're going to use */ - current_dc = controllers; - if (load_balance != 0 && numcontrollers > 1) - { - int n; - pid_t pid = getpid (); - n = pid % numcontrollers; - debug ("load balancing. Selected controller #%d\n", n); - while (n > 0) - { - current_dc = current_dc->next; - n--; - } - } - while (1) - { - manage_request (); + /* initialize FDescs */ + setbuf(stdout, NULL); + setbuf(stderr, NULL); + + /* select the first domain controller we're going to use */ + current_dc = controllers; + if (load_balance != 0 && numcontrollers > 1) { + int n; + pid_t pid = getpid(); + n = pid % numcontrollers; + debug("load balancing. Selected controller #%d\n", n); + while (n > 0) { + current_dc = current_dc->next; + n--; + } + } + while (1) { + manage_request(); } - return 0; + return 0; } Index: squid/src/auth/ntlm/helpers/NTLMSSP/smbval/smblib.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/auth/ntlm/helpers/NTLMSSP/smbval/Attic/smblib.c,v retrieving revision 1.1.2.3 retrieving revision 1.1.2.4 diff -u -r1.1.2.3 -r1.1.2.4 --- squid/src/auth/ntlm/helpers/NTLMSSP/smbval/smblib.c 9 Feb 2001 14:04:02 -0000 1.1.2.3 +++ squid/src/auth/ntlm/helpers/NTLMSSP/smbval/smblib.c 10 Feb 2001 17:32:50 -0000 1.1.2.4 @@ -1,3 +1,4 @@ + /* UNIX SMBlib NetBIOS implementation * * Version 1.0