--------------------- PatchSet 1023 Date: 2001/01/01 01:55:41 Author: rbcollins Branch: auth_rewrite Tag: (none) Log: runtime scheme order configuration Members: src/authenticate.c:1.1.1.3.12.17.2.13->1.1.1.3.12.17.2.14 src/cf.data.pre:1.1.1.3.4.1.2.18.2.6->1.1.1.3.4.1.2.18.2.7 src/errorpage.c:1.1.1.3.10.9.2.2->1.1.1.3.10.9.2.3 src/protos.h:1.1.1.3.12.17.2.9->1.1.1.3.12.17.2.10 src/structs.h:1.1.1.3.4.1.2.26.2.13->1.1.1.3.4.1.2.26.2.14 src/auth/basic/auth_basic.c:1.1.2.8->1.1.2.9 Index: squid/src/authenticate.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/authenticate.c,v retrieving revision 1.1.1.3.12.17.2.13 retrieving revision 1.1.1.3.12.17.2.14 diff -u -r1.1.1.3.12.17.2.13 -r1.1.1.3.12.17.2.14 --- squid/src/authenticate.c 31 Dec 2000 15:10:38 -0000 1.1.1.3.12.17.2.13 +++ squid/src/authenticate.c 1 Jan 2001 01:55:41 -0000 1.1.1.3.12.17.2.14 @@ -1,6 +1,6 @@ /* - * $Id: authenticate.c,v 1.1.1.3.12.17.2.13 2000/12/31 15:10:38 rbcollins Exp $ + * $Id: authenticate.c,v 1.1.1.3.12.17.2.14 2001/01/01 01:55:41 rbcollins Exp $ * * DEBUG: section 29 Authenticator * AUTHOR: Duane Wessels @@ -40,6 +40,15 @@ #include "squid.h" +/* private data types */ +struct _authscheme_order_entry { + char *typestr; + int Id; +}; +typedef struct _authscheme_order_entry authscheme_order_entry; + +authscheme_order_entry *authscheme_order_list; + static void authenticateDecodeAuth(const char *proxy_auth, auth_user_t * auth_user); @@ -51,6 +60,32 @@ /* Generic Functions */ + +int +authenticateAuthSchemeConfigured(wordlist *w, const char *proxy_auth){ + while (w != NULL) + { + if (strncasecmp(proxy_auth, w->key, strlen(w->key))==0) + return 1; + w = w->next; + } + return 0; +} + +int +authenticateAuthSchemeId(const char *typestr) +{ + int i=0; + for (i = 0; authscheme_list && authscheme_list[i].typestr; i++) + { + if (strncasecmp(typestr, authscheme_list[i].typestr, strlen(authscheme_list[i].typestr)) == 0) + { + return i; + } + } + return -1; +} + void authenticateDecodeAuth(const char *proxy_auth, auth_user_t * auth_user) { @@ -62,16 +97,28 @@ assert(proxy_auth != NULL); assert(auth_user != NULL); /* we need this created for us. */ debug(29, 6) ("authenticateDecodeAuth: header = '%s'\n", proxy_auth); - for (i = 0; authscheme_list && authscheme_list[i].typestr; i++) { - if ((authscheme_list[i].Active()) &&(strncasecmp(proxy_auth, authscheme_list[i].typestr, strlen(authscheme_list[i].typestr)) == 0)) { + if (authenticateAuthSchemeConfigured(Config.authenticate_scheme_order, proxy_auth)) + { + /* we're configured to use this scheme - but is it active ? */ + if ((i=authenticateAuthSchemeId(proxy_auth))!=-1) + { auth_user->auth_module = i+1; authscheme_list[i].decodeauth(auth_user, proxy_auth); return; } +#if 0 + for (i = 0; authscheme_list && authscheme_list[i].typestr; i++) { + if ((authscheme_list[i].Active()) &&(strncasecmp(proxy_auth, authscheme_list[i].typestr, strlen(authscheme_list[i].typestr)) == 0)) { + auth_user->auth_module = i+1; + authscheme_list[i].decodeauth(auth_user, proxy_auth); + return; + } + } +#endif } auth_user->auth_type = AUTH_UNKNOWN; debug(29, 1) - ("authenticateDecodeAuth: Unsupported proxy-auth scheme, '%s'\n", + ("authenticateDecodeAuth: Unsupported or unconfigured proxy-auth scheme, '%s'\n", proxy_auth); return; } @@ -236,10 +283,46 @@ return rv; } +/* + * Called after configuration and setup of auth schemes, + * this routine creates the associative array of scheme type + * to compiletime load order + */ +void +authenticateCreateSchemeOrder(void) +{ + int i,j=0; + wordlist *w=Config.authenticate_scheme_order; + /* find the number of currently known authscheme types that are in the configure + order */ + for (i = 0; authscheme_list && authscheme_list[i].typestr; i++) { + if (authenticateAuthSchemeConfigured(w, authscheme_list[i].typestr)) + j++; + } + /* initialise the array */ + authscheme_order_list = xrealloc(authscheme_order_list, (j+1) * sizeof(authscheme_order_entry)); + /* zero the terminating entry */ + authscheme_order_list[j].Id=-1; + authscheme_order_list[j].typestr=NULL; + /* walk the configure list, for each scheme add to the array */ + i=0; + while (w != NULL) + { + if ((j=authenticateAuthSchemeId(w->key))!=-1) + { + authscheme_order_list[i].Id=j; + authscheme_order_list[i].typestr=authscheme_list[j].typestr; + i++; + } + w = w->next; + } +} + void authenticateInit(void) { authSchemeSetup(); + authenticateCreateSchemeOrder(); if (!proxy_auth_username_cache) authenticateInitUserCache(); } @@ -261,7 +344,7 @@ void -authenticateFixErrorHeader(HttpReply * rep, ErrorState * err) +authenticateFixHeader(HttpReply * rep, ErrorState * err) /* send the auth types we are configured to support (and have compiled in!) */ { /* auth_type_t auth_type=err->auth_type; @@ -284,88 +367,21 @@ return; break; } - debug(29,9)("authenticateFixErrorHeader: headertype:%d authuser:%d\n",type,auth_user); + debug(29,9)("authenticateFixHeader: headertype:%d authuser:%d\n",type,auth_user); if ((auth_user !=NULL) && (auth_user->auth_module>0)) - authscheme_list[auth_user->auth_module-1].authFixErrorHeader(auth_user, rep, type, err->request); + authscheme_list[auth_user->auth_module-1].authFixHeader(auth_user, rep, type, err->request); else { int i; - /* call each currently known authscheme */ - for (i = 0; authscheme_list && authscheme_list[i].typestr; i++) { - if (authscheme_list[i].Active()) - authscheme_list[i].authFixErrorHeader(auth_user,rep, type, err->request); + /* call each configured authscheme */ + for (i = 0; authscheme_order_list && authscheme_order_list[i].typestr; i++) { + if (authscheme_list[authscheme_order_list[i].Id].Active()) + authscheme_list[authscheme_order_list[i].Id].authFixHeader(auth_user,rep, type, err->request); else - debug(29,8)("authenticateFixErrorHeader: Compiled scheme %s not Active\n",authscheme_list[i].typestr); - } - } - -#if 0 - switch (auth_type){ - case AUTH_UNKNOWN: -#if 0 - /* we don't know the auth type, so we cannot know the state */ - assert(auth_state==AUTHENTICATE_STATE_NONE); -#endif - /* the header order breaks RFC 2617, __but__ explorer doesn't use NTLM otherwise */ - #if !defined(RFC2616) - if (Config.Program.ntlmauthenticate){ - debug(29, 5) ("authenticateFixErrorHeader: Sending type:%d header: 'NTLM'\n",type); - httpHeaderPutStrf(&rep->header, type, "NTLM"); - } - #endif - if (Config.Program.authenticate){ - debug(29, 5) ("authenticateFixErrorHeader: Sending type:%d header: 'Basic realm=\"%s\"'\n",type,Config.proxyAuthRealm); - httpHeaderPutStrf(&rep->header, type, "Basic realm=\"%s\"", Config.proxyAuthRealm); - } - #if defined(RFC2616) - if (Config.Program.ntlmauthenticate){ - debug(29, 5) ("authenticateFixErrorHeader: Sending type:%d header: 'NTLM'\n",type); - httpHeaderPutStrf(&rep->header, type, "NTLM"); - } - #endif - if (Config.Program.ntlmauthenticate){ - httpHeaderDelByName(&rep->header, "keep-alive"); /* drop the connection */ - /* NTLM has problems if the initial connection is not dropped - I haven't checked the RFC compliance of this hack - RBCollins*/ - err->request->flags.proxy_keepalive = 0; - } - break; - case AUTH_BASIC: - assert(auth_state!=AUTHENTICATE_STATE_NONE); - if (Config.Program.authenticate){ - debug(29, 5) ("authenticateFixErrorHeader: Sending type:%d header: 'Basic realm=\"%s\"'\n",type,Config.proxyAuthRealm); - httpHeaderPutStrf(&rep->header, type, "Basic realm=\"%s\"", Config.proxyAuthRealm); + debug(29,8)("authenticateFixHeader: Compiled scheme %s not Active\n",authscheme_list[authscheme_order_list[i].Id].typestr); } - break; - case AUTH_NTLM: - if (Config.Program.ntlmauthenticate){ - /* if auth_state is none, the acl causing the denied was an NTLM _only_ - * not currently support in other routines..*/ - switch (auth_state){ - case AUTHENTICATE_STATE_NONE: - debug(29, 5) ("authenticateFixErrorHeader: Sending type:%d header: 'NTLM'\n",type); - httpHeaderPutStrf(&rep->header, type, "NTLM"); - break; - case AUTHENTICATE_STATE_CHALLENGE: /* we are 'waiting' for a response */ - /* pass the challenge from conn->authChallenge to the client */ - debug(29, 5) ("authenticateFixErrorHeader: Sending type:%d header: 'NTLM %s'\n",type,authchallenge); - httpHeaderPutStrf(&rep->header, type, "NTLM %s", authchallenge); - break; - default: - debug(29,1)("authenticateFixErrorHeader: state %d.\n",auth_state); - fatal("unexpected state in AuthenticateFixErrorHeader.\n"); - } - } - break; - case AUTH_BROKEN: - /* fall thru */ - default: - fatal("Unknown authentication type"); } - return; -#endif } - void authenticateAuthUserLock(auth_user_t *auth_user) { debug (29,6) ("authenticateAuthUserLock auth_user '%d'.\n",auth_user); @@ -400,7 +416,7 @@ void authenticateAuthUserMerge(auth_user_t *from, auth_user_t *to) { -/* combine two authuser structs. Incomplete: it should merge in hash references +/* XXX combine two authuser structs. Incomplete: it should merge in hash references too and ask the module to merge in scheme data*/ debug (29,6) ("authenticateAuthUserMerge auth_user '%d' into auth_user '%d'.\n",from,to); to->references+=from->references; @@ -444,25 +460,6 @@ aclCacheMatchFlush(&u->proxy_match_cache); if (u->scheme_data && u->auth_module>0) authscheme_list[u->auth_module-1].FreeUser(u); -#if 0 - switch (u->auth_type) { - case AUTH_BASIC: - debug(29,6) ("authenticateFreeProxyAuthUser: Clearing Basic scheme data\n"); - if (u->auth_data.basic_auth.username) - xfree(u->auth_data.basic_auth.username); - if (u->auth_data.basic_auth.passwd) - xfree(u->auth_data.basic_auth.passwd); - break; - case AUTH_NTLM: - debug(29,6) ("authenticateFreeProxyAuthUser: Clearing NTLM scheme data\n"); - if (u->auth_data.ntlm_auth.username) xfree(u->auth_data.ntlm_auth.username); - if (u->auth_data.ntlm_auth.ntlmnegotiate) xfree(u->auth_data.ntlm_auth.ntlmnegotiate); - if (u->auth_data.ntlm_auth.authchallenge) xfree(u->auth_data.ntlm_auth.authchallenge); - if (u->auth_data.ntlm_auth.ntlmauthenticate) xfree(u->auth_data.ntlm_auth.ntlmauthenticate); - case AUTH_BROKEN: - case AUTH_UNKNOWN: - } -#endif /* prevent accidental reuse */ u->auth_type=AUTH_UNKNOWN; memFree(u, MEM_AUTH_USER_T); @@ -503,20 +500,6 @@ /* if we need to have inpedendent expiry clauses, insert a module call * here */ -#if 0 - switch(auth_user->auth_type) { - case AUTH_UNKNOWN: - case AUTH_BROKEN: - fatal("Invalid user cache entry. This is a bug!\n"); - return; - case AUTH_NTLM: - username=auth_user->auth_data.ntlm_auth.username; - break; - case AUTH_BASIC: - username=auth_user->auth_data.basic_auth.username; - break; - } -#endif debug(29,6) ("authenticateProxyUserCacheCleanup: Cache entry:\n\tType: %d\n\tUsername: %s\n\texpires: %d\n\treferences: %d\n", auth_user->auth_type, username, auth_user->expiretime+ Config.authenticateTTL,auth_user->references); if (auth_user->expiretime + Config.authenticateTTL <= current_time.tv_sec) { debug(29,3)("authenticateProxyUserCacheCleanup: Removing user %s from cache due to timeout.\n",username); @@ -545,20 +528,6 @@ while ((usernamehash=((auth_user_hash_pointer *)hash_next(proxy_auth_username_cache)))) { auth_user=usernamehash->auth_user; username=authenticateUserUsername(auth_user); -#if 0 - switch(auth_user->auth_type) { - case AUTH_UNKNOWN: - case AUTH_BROKEN: - fatal("Invalid user cache entry. This is a bug!\n"); - return; - case AUTH_NTLM: - username=auth_user->auth_data.ntlm_auth.username; - break; - case AUTH_BASIC: - username=auth_user->auth_data.basic_auth.username; - break; - } -#endif debug(29,3) ("authenticateUserCacheRestat: Clearing cache ACL results for user: %s\n", username); aclCacheMatchFlush(&auth_user->proxy_match_cache); } Index: squid/src/cf.data.pre =================================================================== RCS file: /cvsroot/squid-sf//squid/src/cf.data.pre,v retrieving revision 1.1.1.3.4.1.2.18.2.6 retrieving revision 1.1.1.3.4.1.2.18.2.7 diff -u -r1.1.1.3.4.1.2.18.2.6 -r1.1.1.3.4.1.2.18.2.7 --- squid/src/cf.data.pre 31 Dec 2000 15:10:38 -0000 1.1.1.3.4.1.2.18.2.6 +++ squid/src/cf.data.pre 1 Jan 2001 01:55:41 -0000 1.1.1.3.4.1.2.18.2.7 @@ -1,6 +1,6 @@ # -# $Id: cf.data.pre,v 1.1.1.3.4.1.2.18.2.6 2000/12/31 15:10:38 rbcollins Exp $ +# $Id: cf.data.pre,v 1.1.1.3.4.1.2.18.2.7 2001/01/01 01:55:41 rbcollins Exp $ # # # SQUID Internet Object Cache http://squid.nlanr.net/Squid/ @@ -1089,6 +1089,18 @@ are sent. DOC_END +NAME: authenticate_scheme_order +TYPE: wordlist +DEFAULT: basic +LOC: Config.authenticate_scheme_order +DOC_START + Specify the order that authentication challenges are written to the + client agent in HTTP responses. Use none to prevent the use of + authentication under any circumstances. This is CASE SENSITIVE. + Defaults to use the 'basic' scheme only. +DOC_END + + NAME: authenticate_program_ntlm TYPE: wordlist LOC: Config.Program.ntlmauthenticate Index: squid/src/errorpage.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/errorpage.c,v retrieving revision 1.1.1.3.10.9.2.2 retrieving revision 1.1.1.3.10.9.2.3 diff -u -r1.1.1.3.10.9.2.2 -r1.1.1.3.10.9.2.3 --- squid/src/errorpage.c 13 Dec 2000 01:23:31 -0000 1.1.1.3.10.9.2.2 +++ squid/src/errorpage.c 1 Jan 2001 01:55:41 -0000 1.1.1.3.10.9.2.3 @@ -1,6 +1,6 @@ /* - * $Id: errorpage.c,v 1.1.1.3.10.9.2.2 2000/12/13 01:23:31 rbcollins Exp $ + * $Id: errorpage.c,v 1.1.1.3.10.9.2.3 2001/01/01 01:55:41 rbcollins Exp $ * * DEBUG: section 4 Error Generation * AUTHOR: Duane Wessels @@ -278,7 +278,7 @@ rep = errorBuildReply(err); /* Add authentication header */ // debug(28,6)("errorpage:state:type %d:%d.\n",err->auth_state,err->auth_type); - authenticateFixErrorHeader(rep, err); + authenticateFixHeader(rep, err); httpReplySwapOut(rep, entry); httpReplyAbsorb(mem->reply, rep); EBIT_CLR(entry->flags, ENTRY_FWD_HDR_WAIT); Index: squid/src/protos.h =================================================================== RCS file: /cvsroot/squid-sf//squid/src/protos.h,v retrieving revision 1.1.1.3.12.17.2.9 retrieving revision 1.1.1.3.12.17.2.10 diff -u -r1.1.1.3.12.17.2.9 -r1.1.1.3.12.17.2.10 --- squid/src/protos.h 13 Dec 2000 01:23:31 -0000 1.1.1.3.12.17.2.9 +++ squid/src/protos.h 1 Jan 2001 01:55:41 -0000 1.1.1.3.12.17.2.10 @@ -1,6 +1,6 @@ /* - * $Id: protos.h,v 1.1.1.3.12.17.2.9 2000/12/13 01:23:31 rbcollins Exp $ + * $Id: protos.h,v 1.1.1.3.12.17.2.10 2001/01/01 01:55:41 rbcollins Exp $ * * * SQUID Internet Object Cache http://squid.nlanr.net/Squid/ @@ -710,7 +710,7 @@ extern void authenticateStart(auth_user_t *, RH *, void *); extern void authenticateInit(void); extern void authenticateShutdown(void); -extern void authenticateFixErrorHeader(HttpReply * rep, ErrorState * err); +extern void authenticateFixHeader(HttpReply * rep, ErrorState * err); extern auth_user_t *authenticateGetAuthUser(const char *proxy_auth); extern auth_user_t *authenticateAuthenticateUser(auth_user_t *auth_user, request_t * request, ConnStateData *conn, http_hdr_type type); extern void authenticateAuthUserUnlock(auth_user_t *auth_user); Index: squid/src/structs.h =================================================================== RCS file: /cvsroot/squid-sf//squid/src/structs.h,v retrieving revision 1.1.1.3.4.1.2.26.2.13 retrieving revision 1.1.1.3.4.1.2.26.2.14 diff -u -r1.1.1.3.4.1.2.26.2.13 -r1.1.1.3.4.1.2.26.2.14 --- squid/src/structs.h 31 Dec 2000 15:10:38 -0000 1.1.1.3.4.1.2.26.2.13 +++ squid/src/structs.h 1 Jan 2001 01:55:41 -0000 1.1.1.3.4.1.2.26.2.14 @@ -1,6 +1,6 @@ /* - * $Id: structs.h,v 1.1.1.3.4.1.2.26.2.13 2000/12/31 15:10:38 rbcollins Exp $ + * $Id: structs.h,v 1.1.1.3.4.1.2.26.2.14 2001/01/01 01:55:41 rbcollins Exp $ * * * SQUID Internet Object Cache http://squid.nlanr.net/Squid/ @@ -115,7 +115,7 @@ AUTHSACTIVE *Active; AUTHSAUTHED *authenticated; AUTHSAUTHUSER *authAuthenticate; - AUTHSFIXERR *authFixErrorHeader; + AUTHSFIXERR *authFixHeader; AUTHSFREE *FreeUser; AUTHSUSERNAME *authUserUsername; AUTHSONCLOSEC *oncloseconnection; /*optional*/ @@ -383,6 +383,7 @@ int dnsChildren; #endif int redirectChildren; + wordlist *authenticate_scheme_order; int authenticateChildren; time_t authenticateGCInterval; time_t authenticateTTL; 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.8 retrieving revision 1.1.2.9 diff -u -r1.1.2.8 -r1.1.2.9 --- squid/src/auth/basic/auth_basic.c 31 Dec 2000 15:10:39 -0000 1.1.2.8 +++ squid/src/auth/basic/auth_basic.c 1 Jan 2001 01:55:42 -0000 1.1.2.9 @@ -97,7 +97,7 @@ if (Config.Program.authenticate){ authscheme->authAuthenticate = authenticateBasicAuthenticateUser; authscheme->authenticated= authenticateBasicAuthenticated; - authscheme->authFixErrorHeader=authenticateBasicFixErrorHeader; + authscheme->authFixHeader=authenticateBasicFixErrorHeader; authscheme->FreeUser =authenticateBasicFreeUser; authscheme->authStart =authenticateBasicStart; authscheme->authStats =authenticateBasicStats;