--------------------- PatchSet 860 Date: 2000/11/21 00:11:15 Author: rbcollins Branch: auth_rewrite Tag: (none) Log: nearly complete Members: configure.in:1.1.1.3.10.17.2.1->1.1.1.3.10.17.2.2 src/authenticate.c:1.1.1.3.12.17.2.4->1.1.1.3.12.17.2.5 src/client_side.c:1.1.1.3.4.1.2.30.2.1->1.1.1.3.4.1.2.30.2.2 src/errorpage.c:1.1.1.3.10.9->1.1.1.3.10.9.2.1 src/structs.h:1.1.1.3.4.1.2.26.2.3->1.1.1.3.4.1.2.26.2.4 src/typedefs.h:1.1.1.3.12.13.2.3->1.1.1.3.12.13.2.4 src/auth/basic/auth_basic.c:1.1.2.2->1.1.2.3 src/auth/ntlm/auth_ntlm.c:1.1.2.2->1.1.2.3 Index: squid/configure.in =================================================================== RCS file: /cvsroot/squid-sf//squid/configure.in,v retrieving revision 1.1.1.3.10.17.2.1 retrieving revision 1.1.1.3.10.17.2.2 diff -u -r1.1.1.3.10.17.2.1 -r1.1.1.3.10.17.2.2 --- squid/configure.in 20 Nov 2000 06:55:35 -0000 1.1.1.3.10.17.2.1 +++ squid/configure.in 21 Nov 2000 00:11:15 -0000 1.1.1.3.10.17.2.2 @@ -3,13 +3,13 @@ dnl dnl Duane Wessels, wessels@nlanr.net, February 1996 (autoconf v2.9) dnl -dnl $Id: configure.in,v 1.1.1.3.10.17.2.1 2000/11/20 06:55:35 rbcollins Exp $ +dnl $Id: configure.in,v 1.1.1.3.10.17.2.2 2000/11/21 00:11:15 rbcollins Exp $ dnl dnl dnl AC_INIT(src/main.c) AC_CONFIG_HEADER(include/autoconf.h) -AC_REVISION($Revision: 1.1.1.3.10.17.2.1 $)dnl +AC_REVISION($Revision: 1.1.1.3.10.17.2.2 $)dnl AC_PREFIX_DEFAULT(/usr/local/squid) AC_CONFIG_AUX_DIR(cfgaux) @@ -689,7 +689,7 @@ esac ], [ if test -z "$AUTH_MODULES"; then - AUTH_MODULES="basic ntlm" + AUTH_MODULES="ntlm basic" fi ]) echo "Auth scheme modules built: $AUTH_MODULES" Index: squid/src/authenticate.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/authenticate.c,v retrieving revision 1.1.1.3.12.17.2.4 retrieving revision 1.1.1.3.12.17.2.5 diff -u -r1.1.1.3.12.17.2.4 -r1.1.1.3.12.17.2.5 --- squid/src/authenticate.c 20 Nov 2000 22:40:33 -0000 1.1.1.3.12.17.2.4 +++ squid/src/authenticate.c 21 Nov 2000 00:11:16 -0000 1.1.1.3.12.17.2.5 @@ -1,6 +1,6 @@ /* - * $Id: authenticate.c,v 1.1.1.3.12.17.2.4 2000/11/20 22:40:33 rbcollins Exp $ + * $Id: authenticate.c,v 1.1.1.3.12.17.2.5 2000/11/21 00:11:16 rbcollins Exp $ * * DEBUG: section 29 Authenticator * AUTHOR: Duane Wessels @@ -114,34 +114,6 @@ ("authenticateDecodeAuth: Unsupported proxy-auth scheme, '%s'\n", proxy_auth); return; -#if 0 - if (strncasecmp(proxy_auth, "Basic ", 6) == 0) { - if (Config.Program.authenticate != NULL) { - proxy_auth += 6; - auth_user->auth_type = AUTH_BASIC; -// auth_user->proxy_auth = xstrdup(proxy_auth); -// authenticateDecodeBasicAuth(auth_user); - authenticateDecodeBasicAuth(auth_user, proxy_auth); - } else - auth_user->auth_type = AUTH_UNKNOWN; - } else - if (strncmp("NTLM ", proxy_auth, 5) == 0) { - if (Config.Program.ntlmauthenticate != NULL) { - proxy_auth += 5; - auth_user->auth_type = AUTH_NTLM; -// auth_user->proxy_auth = xstrdup(proxy_auth); -// authenticateDecodeNTLMAuth(auth_user); - authenticateDecodeNTLMAuth(auth_user, proxy_auth); - } else - auth_user->auth_type = AUTH_UNKNOWN; - } else - { - debug(29, 1) - ("authenticateDecodeAuth: Unsupported proxy-auth scheme, '%s'\n", - proxy_auth); auth_user->auth_type = AUTH_UNKNOWN; - return; - } -#endif } #if 0 static void @@ -149,410 +121,8 @@ { cbdataFree(r); } - -/* Basic Scheme */ - -/* log a basic user in - */ -static acl_proxy_auth_user * -authenticateBasicAuthenticateUser(acl_proxy_auth_user *data, const char * proxy_auth) { - acl_proxy_auth_hash_pointer *usernamehash, *proxy_auth_hash=NULL; - acl_proxy_auth_user *auth_user=data; - /* if the password is not ok, do an identity */ - if (auth_user->flags.credentials_ok!=1) - return auth_user; - - /* password was checked and did match */ - debug(29, 4) ("authenticateBasicAuthenticateuser: user '%s' validated OK\n", - auth_user->auth_data.basic_auth.username); - /* see if this is an existing user with a different proxy_auth string */ - if ((usernamehash = hash_lookup(proxy_auth_username_cache, - auth_user->auth_data.basic_auth.username))) { - while ((usernamehash->auth_user->auth_type != auth_user->auth_type) && - (usernamehash->next) && - !strcmp(usernamehash->auth_user->auth_data.basic_auth.username,auth_user->auth_data.basic_auth.username) ) - 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(proxy_auth, usernamehash->auth_user); - /* maybe the p/w changed. update in the old structure */ - xfree(usernamehash->auth_user->auth_data.basic_auth.passwd); - usernamehash->auth_user->auth_data.basic_auth.passwd = - auth_user->auth_data.basic_auth.passwd; - auth_user->auth_data.basic_auth.passwd = NULL; - /* and remove the temporary structure */ - authenticateAuthUserUnlock(auth_user); - authenticateFreeProxyAuthUser(auth_user); - auth_user = usernamehash->auth_user; - /* lock the structure for this request */ - authenticateAuthUserLock(auth_user); - } - } else { - /* store user in hash's */ - authenticateUserNameCacheAdd(auth_user); - authenticateProxyAuthCacheAddLink(proxy_auth, auth_user); - } - /* auth_user is now linked, we reset these values - * after external auth occurs anyway */ - auth_user->expiretime = current_time.tv_sec; - auth_user->ip_expiretime = squid_curtime; - return auth_user; -} - -int authenticateBasicDirection(acl_proxy_auth_user *auth_user) { -/* null auth_user is checked for by authenticateDirection */ - switch (auth_user->flags.credentials_ok) { - case 0: /* not checked */ - return -1; - case 1: /* checked & ok */ - return 0; - case 2: /* partway through checking. Invalid for basic */ - return -2; - case 3: /* authentication process failed. */ - return -2; - } - return -2; -} - -static void -authenticateBasicHandleReply(void *data, char *reply) -{ - authenticateStateData *r = data; - acl_proxy_auth_user *auth_user; - int valid; - char *t = NULL; - debug(29, 5) ("authenticateBasicHandleReply: {%s}\n", reply ? reply : ""); - if (reply) { - if ((t = strchr(reply, ' '))) - *t = '\0'; - if (*reply == '\0') - reply = NULL; - } - assert(r->auth_user != NULL); - assert(r->auth_user->auth_type == AUTH_BASIC); - auth_user=r->auth_user; - if (reply && (strncasecmp(reply, "OK", 2) == 0)) - auth_user->flags.credentials_ok = 1; - else - auth_user->flags.credentials_ok = 2; - valid = cbdataValid(r->data); - cbdataUnlock(r->data); - if (valid) - r->handler(r->data, NULL); -#if 0 - if (valid) - r->handler(r->data, reply); -#endif - authenticateStateFree(r); -} - -static void -authenticateBasicStats(StoreEntry * sentry) -{ - storeAppendPrintf(sentry, "Basic Authenticator Statistics:\n"); - helperStats(sentry, basicauthenticators); -} - -/* - * Decode a Basic [Proxy-]Auth string, placing the results in the passed - * Auth_user structure. - */ - -static void -authenticateDecodeBasicAuth(acl_proxy_auth_user *auth_user, const char * proxy_auth) { - char *sent_auth; - char *cleartext; - assert(auth_user->auth_type == AUTH_BASIC); - - /* Trim leading whitespace before decoding */ - while (xisspace(*proxy_auth)) - proxy_auth++; - /* username and password */ - sent_auth = xstrdup(proxy_auth); - /* Trim trailing \n before decoding */ - strtok(sent_auth, "\n"); - cleartext = uudecode(sent_auth); - xfree(sent_auth); - /* - * Don't allow NL or CR in the credentials. - * Oezguer Kesim - */ - strtok(cleartext, "\r\n"); - debug(29, 6) ("authenticateDecodeBasicAuth: cleartext = '%s'\n", cleartext); - /* have we been called twice? */ - assert(auth_user->auth_data.basic_auth.username == NULL); - auth_user->auth_data.basic_auth.username = - xstrndup(cleartext, USER_IDENT_SZ); - xfree(cleartext); - /* again, have we been called twice? */ - assert(auth_user->auth_data.basic_auth.passwd == NULL); - if ((cleartext = - strchr(auth_user->auth_data.basic_auth.username, ':')) != NULL) - *(cleartext)++ = '\0'; - if (cleartext == NULL) { - debug(29, 2) ("authenticateDecodeBasicAuth: no password in proxy authorization header '%s'\n", - proxy_auth); auth_user->auth_type = AUTH_BROKEN; - } - if (*cleartext == '\0') { - debug(29, 2) ("authenticateDecodeBasicAuth: Disallowing empty password," - "user is '%s'\n", auth_user->auth_data.basic_auth.username); - auth_user->auth_type = AUTH_BROKEN; - } - /* special case: we have to free the strings for user and password - * if we are not returning AUTH_BASIC else the UserFree function will - * be confused. - */ - if (auth_user->auth_type != AUTH_BASIC) { - if (auth_user->auth_data.basic_auth.username) - xfree(auth_user->auth_data.basic_auth.username); - } else { - auth_user->auth_data.basic_auth.passwd = xstrndup(cleartext, USER_IDENT_SZ); - } - /* we are finished with the proxy_auth */ -// xfree(auth_user->proxy_auth); -// auth_user->proxy_auth = NULL; - return; -} - -/* send the initial data to a basic authenticator module */ -static void -authenticateBasicStart(acl_proxy_auth_user * auth_user, RH * handler, void *data) -{ - authenticateStateData *r = NULL; - char buf[8192]; - assert(auth_user); - assert(handler); - assert(auth_user->auth_type==AUTH_BASIC); - debug(29, 5) ("authenticateStart: '%s:%s'\n", auth_user->auth_data.basic_auth.username, - auth_user->auth_data.basic_auth.passwd); - if (Config.Program.authenticate == NULL) { - handler(data, NULL); - return; - } - r = xcalloc(1, sizeof(authenticateStateData)); - cbdataAdd(r, cbdataXfree, 0); - r->handler = handler; - cbdataLock(data); - r->data = data; - r->auth_user = auth_user; - snprintf(buf, 8192, "%s %s\n", auth_user->auth_data.basic_auth.username, auth_user->auth_data.basic_auth.passwd); - helperSubmit(basicauthenticators, buf, authenticateBasicHandleReply, r); -} - -/* NTLM Scheme */ - -int authenticateNTLMDirection(acl_proxy_auth_user *auth_user) { -/* null auth_user is checked for by authenticateDirection */ - switch (auth_user->auth_data.ntlm_auth.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 */ - case AUTHENTICATE_STATE_RESPONSE: /*send to helper */ - return -1; - case AUTHENTICATE_STATE_CHALLENGE: /* send to client */ - return 1; - case AUTHENTICATE_STATE_DONE: /* do nothing.. */ - return 0; - } - return -2; -} - -static stateful_helper_callback_t -authenticateNTLMHandleReply(void *data, void * lastserver, char *reply) -{ -#if 0 - authenticateStatefulStateData *r = data; -#endif - authenticateStateData *r = data; - int valid; - stateful_helper_callback_t result = S_HELPER_UNKNOWN; -#if 0 - void *nextserver=NULL; -#endif - char *t = NULL; - acl_proxy_auth_user *auth_user; - debug(29, 5) ("authenticateNTLMHandleReply: Helper: '%d' {%s}\n", lastserver, reply ? reply : ""); - valid = cbdataValid(r->data); - cbdataUnlock(r->data); - if (valid) { - if (reply) { - /* seperate out the useful data */ - if (strncasecmp(reply, "CH ", 3) == 0) { - reply += 3; - /* we have been given a Challenge */ - /* we should check we weren't given an empty challenge */ -#if 0 - result=S_HELPER_RESERVE; -#endif - assert(r->auth_user != NULL); - assert(r->auth_user->auth_type == AUTH_NTLM); - auth_user=r->auth_user; - result=S_HELPER_DEFER; -#if 0 - nextserver=lastserver; -#endif - debug(29,5)("authenticateNTLMHandleReply: helper '%d'\n",lastserver); - assert(auth_user->auth_data.ntlm_auth.auth_state == AUTHENTICATE_STATE_NEGOTIATE); -// auth_user->auth_data.ntlm_auth.auth_state = AUTHENTICATE_STATE_CHALLENGE; - auth_user->auth_data.ntlm_auth.authhelper = lastserver; - auth_user->auth_data.ntlm_auth.authchallenge = - xstrndup(reply, NTLM_CHALLENGE_SZ+5); - } - else if (strncasecmp(reply, "OK ", 3) == 0) { - /* we're finished, release the helper*/ - reply+=3; - assert(r->auth_user != NULL); - assert(r->auth_user->auth_type == AUTH_NTLM); - auth_user=r->auth_user; - result=S_HELPER_RELEASE; - /* we only expect OK when finishing the handshake */ - assert(auth_user->auth_data.ntlm_auth.auth_state == AUTHENTICATE_STATE_RESPONSE); - auth_user->auth_data.ntlm_auth.username = xstrndup(reply, MAX_LOGIN_SZ); - auth_user->auth_data.ntlm_auth.authhelper = NULL; - auth_user->flags.credentials_ok = 1; /* login ok */ - } - else if (strncasecmp(reply, "RESET OK", 8) == 0) { - /* Helper successfully reset */ - /* note a reset request returning here MUST NOT reserve the helper */ - /* also auth_user does not need to be valid on a reset call */ - result=S_HELPER_RELEASE; - if (r->auth_user) r->auth_user->auth_data.ntlm_auth.authhelper=NULL; - } - else if (strncasecmp(reply, "ERR", 3) == 0) { - /* TODO: only work with auth_user here if it exists */ - assert(r->auth_user != NULL); - assert(r->auth_user->auth_type == AUTH_NTLM); - auth_user=r->auth_user; - /* todo: action of Negotiate state on error */ - result=S_HELPER_RELEASE; /*some error has occured. no more requests */ - auth_user->auth_data.ntlm_auth.authhelper = NULL; - auth_user->auth_data.ntlm_auth.auth_state = AUTHENTICATE_STATE_NONE; - if (auth_user->auth_data.ntlm_auth.auth_state == AUTHENTICATE_STATE_NEGOTIATE) { - /* The helper rejected the negotiate. It automatically - * resets */ - auth_user->flags.credentials_ok = 3; /* cannot process */ - debug(29, 1) ("authenticateNTLMHandleReply: Error obtaining challenge from helper: %d.\n", lastserver); - } else { - auth_user->flags.credentials_ok = 2; /* Login/Usercode failed */ - debug(29, 1) ("authenticateNTLMHandleReply: Error validating user via NTLM.\n"); - } - if ((t = strchr(reply, ' ')))/* strip after a space */ - *t = '\0'; - } else { - /* TODO: only work with auth_user here if it exists */ - assert(r->auth_user != NULL); - assert(r->auth_user->auth_type == AUTH_NTLM); - auth_user=r->auth_user; - debug(29, 1) ("authenticateNTLMHandleReply: Unsupported helper response, '%s'\n", reply); - /* restart the authentication process */ - auth_user->auth_data.ntlm_auth.auth_state = AUTHENTICATE_STATE_NONE; - auth_user->flags.credentials_ok = 3; /* cannot process */ - auth_user->auth_data.ntlm_auth.authhelper = NULL; - } -#if 0 - if (*reply == '\0') - reply = NULL; -#endif - } else { - fatal("authenticateNTLMHandleReply: called with no result string\n"); - } -// r->handler(r->data, nextserver, reply); - r->handler(r->data, NULL); - } else { - debug(29,1) ("AuthenticateNTLMHandleReply: invalid callback data. Releasing helper '%d'.\n",lastserver); - result=S_HELPER_RELEASE; - } -#if 0 - authenticateStatefulStateFree(r); -#endif - authenticateStateFree(r); - debug(29,5)("NTLM HandleReply, telling stateful helper : %d\n",result); - return result; -} - - -static void -authenticateNTLMStateFree(authenticateNTLMStateData * r) -{ - cbdataFree(r); -} - - -static void -authenticateNTLMStats(StoreEntry * sentry) -{ - storeAppendPrintf(sentry, "NTLM Authenticator Statistics:\n"); - helperStatefulStats(sentry, ntlmauthenticators); -} - -/* send the initial data to a stateful ntlm authenticator module */ -static void -authenticateNTLMStart(acl_proxy_auth_user * auth_user, RH * handler, void *data) -{ -#if 0 - authenticateStatefulStateData *r = NULL; -#endif - authenticateStateData *r = NULL; - char buf[8192]; - char *sent_string=NULL; - - assert(auth_user); - assert(handler); - assert(data); - assert(auth_user->auth_type=AUTH_NTLM); - switch(auth_user->auth_data.ntlm_auth.auth_state) { - case AUTHENTICATE_STATE_NEGOTIATE: - sent_string = xstrdup(auth_user->auth_data.ntlm_auth.ntlmnegotiate); - break; - case AUTHENTICATE_STATE_RESPONSE: - sent_string = xstrdup(auth_user->auth_data.ntlm_auth.ntlmauthenticate); - assert(auth_user->auth_data.ntlm_auth.authhelper); - debug(28, 6) ("authenticateNTLMStart: Asking NTLMauthenticator '%d'.\n", auth_user->auth_data.ntlm_auth.authhelper); - break; - default: - fatal("Invalid authenticate state for NTLMStart"); - } - - while (!xisspace(*sent_string)) /*trim NTLM */ - sent_string++; - - while (xisspace(*sent_string)) /*trim leading spaces */ - sent_string++; - debug(29, 5) ("authenticateNTLMStart: state '%d'\n", auth_user->auth_data.ntlm_auth.auth_state); - debug(29, 5) ("authenticateNTLMStart: '%s'\n", sent_string); - if (Config.Program.ntlmauthenticate == NULL) { - debug(29, 1) ("authenticateNTLMStart: no NTLM program specified:'%s'\n", sent_string); -// handler(data,0, NULL); - handler(data, NULL); - return; - } - r = xcalloc(1, sizeof(authenticateStateData)); -#if 0 - r = xcalloc(1, sizeof(authenticateStatefulStateData)); #endif - cbdataAdd(r, cbdataXfree, 0); - r->handler = handler; - cbdataLock(data); - r->data = data; - r->auth_user = auth_user; - snprintf(buf, 8192, "%s\n", sent_string); - helperStatefulSubmit(ntlmauthenticators, buf, authenticateNTLMHandleReply, r, auth_user->auth_data.ntlm_auth.authhelper); - debug(29,9)("authenticateNTLMstart: finished\n"); -} -/* clear the NTLM helper of being reserved for future requests */ -void -authenticateNTLMReleasehelper(acl_proxy_auth_user *auth_user){ - assert(auth_user->auth_type==AUTH_NTLM); - debug(29,5) ("authenticateNTLMReleasehelper: releasing helper '%d'\n",auth_user->auth_data.ntlm_auth.authhelper); - helperStatefulReleaseServer(auth_user->auth_data.ntlm_auth.authhelper); - auth_user->auth_data.ntlm_auth.authhelper=NULL; -} -#endif /* clear any connection related authentication details */ void authenticateOnCloseConnection(acl_proxy_auth_user *auth_user){ @@ -561,50 +131,6 @@ } } -#if OBSOLETE -/* send the initial data to a stateful ntlm authenticator module */ -void -authenticateNTLMStart(const char *proxy_auth, SRH * handler, void *data, helper_ -stateful_server * lastserver) -{ - authenticateStatefulStateData *r = NULL; - char buf[8192]; - assert(proxy_auth); - assert(handler); - assert(data); - debug(29, 5) ("authenticateNTLMStart: '%s'\n", proxy_auth); - if (Config.Program.ntlmauthenticate == NULL) { - debug(29, 1) ("authenticateNTLMStart: no NTLM program specified:'%s'\n", - proxy_auth); - handler(data,0, NULL); - return; - } - r = xcalloc(1, sizeof(authenticateStatefulStateData)); - cbdataAdd(r, cbdataXfree, 0); - r->handler = handler; - cbdataLock(data); - r->data = data; - snprintf(buf, 8192, "%s\n", proxy_auth); - helperStatefulSubmit(ntlmauthenticators, buf, authenticateNTLMHandleReply, r -, lastserver); - debug(29,9)("authenticateNTLMstart: finished\n"); -} -#endif -#if 0 -/* - * Decode an NTLM [Proxy-]Auth string, placing the results in the passed - * Auth_user structure. - */ - -void -authenticateDecodeNTLMAuth(acl_proxy_auth_user *auth_user, const char * proxy_auth) { - assert(auth_user->auth_type == AUTH_NTLM); - /* all we have to do is identify that it's NTLM - the helper does the rest */ - debug(29, 6) ("authenticateDecodeNTLMAuth: NTLM authentication\n"); - return; -} -#endif - /**** PUBLIC FUNCTIONS (ALL GENERIC!) ****/ /* send the initial data to an authenticator module */ @@ -613,29 +139,12 @@ { assert(auth_user); assert(handler); + debug(29,5)("authenticateStart: auth_user '%d'\n", auth_user); if (auth_user->auth_module>0) authscheme_list[auth_user->auth_module-1].authStart(auth_user, handler, data); else handler(data,NULL); } -#if 0 - assert((auth_user->auth_type==AUTH_BASIC) || - (auth_user->auth_type==AUTH_NTLM)); - switch(auth_user->auth_type) { - case AUTH_NTLM: - authenticateNTLMStart(auth_user, handler, data); - break; - case AUTH_BASIC: - debug(28, 4) - ("AuthenticateStart: going to ask authenticator on %s\n", - auth_user->auth_data.basic_auth.username); - /* we must still check this user's password */ - authenticateBasicStart(auth_user, handler, data); - break; - default: - } -} -#endif /* * Check a auth_user pointer for validity. Does not check passwords, just data @@ -701,181 +210,6 @@ debug (29, 7) ("Couldn't find user in cache: assuming not logged in.\n"); return 0; } -#if 0 -static acl_proxy_auth_user * -authenticateNTLMAuthenticateUser(void *data, const char * proxy_auth, ConnStateData *conn) { - acl_proxy_auth_user *auth_user=data; - acl_proxy_auth_hash_pointer *usernamehash, *proxy_auth_hash=NULL; - LOCAL_ARRAY(char, ntlmhash, NTLM_CHALLENGE_SZ * 2); -// char * proxy_auth=auth_user->proxy_auth; - assert(auth_user->auth_type==AUTH_NTLM); - switch (auth_user->auth_data.ntlm_auth.auth_state) { - case AUTHENTICATE_STATE_NONE: - /* we've recieved a negotiate request. pass to a helper */ - debug(29, 3) ("authenticateNTLMAuthenticateUser: auth state ntlm none. %s\n", - proxy_auth); - auth_user->auth_data.ntlm_auth.auth_state = AUTHENTICATE_STATE_NEGOTIATE; -// auth_user->auth_data.ntlm_auth.ntlmnegotiate = auth_user->proxy_auth; -// /* use it up. */ -// auth_user->proxy_auth=NULL; - - auth_user->auth_data.ntlm_auth.ntlmnegotiate=xstrndup(proxy_auth, NTLM_CHALLENGE_SZ+5); - conn->auth_type=AUTH_NTLM; - conn->auth_user=auth_user; - - return auth_user; - break; - case AUTHENTICATE_STATE_NEGOTIATE: - auth_user->auth_data.ntlm_auth.auth_state = AUTHENTICATE_STATE_CHALLENGE; -// xfree(auth_user->proxy_auth); -// auth_user->proxy_auth=NULL; - return auth_user; - break; - case AUTHENTICATE_STATE_CHALLENGE: - /* we should have recieved a NTLM challenge. pass it to the same - * helper process */ - debug(29,3) ("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) { -#if 0 - proxy_auth += 5; -#endif - auth_user->auth_data.ntlm_auth.ntlmauthenticate = xstrdup(proxy_auth); -// xfree(auth_user->proxy_auth); -// auth_user->proxy_auth = NULL; - } 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", - auth_user->auth_data.ntlm_auth.ntlmauthenticate, - auth_user->auth_data.ntlm_auth.authchallenge); - /* see if we already know this user's authenticate */ - debug(29,3)("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,3)("authenticateNTLMAuthenticateUser: proxy-auth cache miss.\n"); - auth_user->auth_data.ntlm_auth.auth_state = AUTHENTICATE_STATE_RESPONSE; -#if 0 - xstrndup(proxy_auth, NTLM_CHALLENGE_SZ+5); -#endif - /* verify with the ntlm helper */ - } else { - debug(29,3)("authenticateNTLMAuthenticateUser: ntlm proxy-auth cache hit\n"); - /* throw away the temporary entry */ - authenticateNTLMReleasehelper(auth_user); - authenticateAuthUserUnlock(auth_user); - authenticateFreeProxyAuthUser(auth_user); - - auth_user = proxy_auth_hash->auth_user; - authenticateAuthUserLock(auth_user); - conn->auth_user=auth_user; - /* we found one */ - debug(29, 3) ("found matching cache entry\n"); - assert(auth_user->auth_type == AUTH_NTLM); - debug(29, 3) ("Username to be used is %s\n", - auth_user->auth_data.ntlm_auth.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 auth_user; - break; - case AUTHENTICATE_STATE_RESPONSE: - /* auth-challenge pair cache miss. We've just got the response */ - /*add to cache and let them through */ - auth_user->auth_data.ntlm_auth.auth_state = AUTHENTICATE_STATE_DONE; - /* this connection is authenticated */ - debug(29, 3) ("validated\nch %s\nauth %s\nauthuser %s\n", - auth_user->auth_data.ntlm_auth.authchallenge, - auth_user->auth_data.ntlm_auth.ntlmauthenticate, - auth_user->auth_data.ntlm_auth.username); - /* cache entries have authenticateauthheaderchallengestring */ - snprintf(ntlmhash, sizeof(ntlmhash) - 1, "%s%s", auth_user->auth_data.ntlm_auth.ntlmauthenticate, - auth_user->auth_data.ntlm_auth.authchallenge); - /* see if this is an existing user with a different proxy_auth - * string */ - if ((usernamehash = hash_lookup(proxy_auth_username_cache, - auth_user->auth_data.ntlm_auth.username))) { - while ((usernamehash->auth_user->auth_type != - auth_user->auth_type) && (usernamehash->next) && - !strcmp(usernamehash->auth_user->auth_data.ntlm_auth.username, auth_user->auth_data.ntlm_auth.username) ) - 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 */ - authenticateAuthUserUnlock(auth_user); - authenticateFreeProxyAuthUser(auth_user); - auth_user = usernamehash->auth_user; - authenticateAuthUserLock(auth_user); - conn->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 auth_user; - break; -#if 0 -done in acl.c - case AUTHENTICATE_STATE_DONE: - debug(28, 5) ("aclMatchProxyAuth: connection in state Done. using connec -tion credentials for the request.\n"); - /* is it working right? */ - assert(checklist->auth_user == NULL); - assert(checklist->conn->auth_user != NULL); - /* we have a valid username. */ - auth_user = checklist->conn->auth_user; - /* store the username in the request for logging */ - xstrncpy(checklist->request->authuser, - auth_user->auth_data.ntlm_auth.username, - USER_IDENT_SZ); - if (auth_user->expiretime + Config.authenticateTTL > current_time.tv_sec -) - { - auth_user->expiretime = current_time.tv_sec; - } - else{ - //user passed externa; authentication in every case to get here. f. -Let it through - } - - /* we don't unlock the auth_user until the connection is dropped. Thank - * MS for this quirk. */ - if (authenticateCheckAuthUserIP(checklist->src_addr, auth_user)){ - /* Once the match is completed we have finished with the - * auth_user structure */ - /* check to see if we have matched the user-acl before */ - return aclCacheMatchAcl(&auth_user->proxy_match_cache, acltype, - data, auth_user->auth_data.ntlm_auth.username); - } else { - return 0; - } - break; -#endif - } - - return auth_user; -} -#endif /* * authenticateAuthenticateUser: log this user in returns a new auth_user. @@ -892,27 +226,8 @@ return authscheme_list[auth_user->auth_module-1].authAuthenticate(auth_user, request, conn, type); return auth_user; - #if 0 proxy_auth = httpHeaderGetStr(&request->header, type); - debug(29,6) ("authenticateAuthenticateUser: authentication header type %d, value '%s'\n.", type,proxy_auth); - /* switch used so we get warn-on-compile if new AUTH type added but not - * handled */ - switch (auth_user->auth_type){ - case AUTH_BASIC: - return authenticateBasicAuthenticateUser(auth_user, proxy_auth); - break; - case AUTH_NTLM: - return authenticateNTLMAuthenticateUser(auth_user, proxy_auth, conn); - break; - case AUTH_UNKNOWN: - case AUTH_BROKEN: - /* Identity operation */ - auth_user->flags.credentials_ok=3; - return auth_user; - } - /*identity function */ - return auth_user; #endif } @@ -923,21 +238,6 @@ if (auth_user->auth_module>0) return authscheme_list[auth_user->auth_module-1].authUserUsername(auth_user); return NULL; -#if 0 - switch (auth_user->auth_type) { - case AUTH_UNKNOWN: - case AUTH_BROKEN: - return NULL; - break; - case AUTH_BASIC: - return auth_user->auth_data.basic_auth.username; - break; - case AUTH_NTLM: - return auth_user->auth_data.ntlm_auth.username; - break; - } - return NULL; -#endif } /* returns @@ -952,76 +252,19 @@ if (authenticateUserAuthenticated(auth_user)) return 0; if (auth_user->auth_module>0) return authscheme_list[auth_user->auth_module-1].getdirection(auth_user); -#if 0 - switch (auth_user->auth_type) { - case AUTH_UNKNOWN: - case AUTH_BROKEN: - return -2; - case AUTH_BASIC: - return authenticateBasicDirection(auth_user); - case AUTH_NTLM: - return authenticateNTLMDirection(auth_user); - } -#endif return -2; } - - void authenticateInit(void) { authSchemeSetup(); -#if 0 - static int init = 0; - static int ntlminit = 0; - if (Config.Program.authenticate){ - if (basicauthenticators == NULL) - basicauthenticators = helperCreate("basicauthenticator"); - basicauthenticators->cmdline = Config.Program.authenticate; - basicauthenticators->n_to_start = Config.authenticateChildren; - basicauthenticators->ipc_type = IPC_TCP_SOCKET; - helperOpenServers(basicauthenticators); - if (!init) { - cachemgrRegister("basicauthenticator", - "User Authenticator Stats", - authenticateBasicStats, 0, 1); - init++; - } - } - if (Config.Program.ntlmauthenticate){ - if (ntlmauthenticators == NULL) - ntlmauthenticators = helperStatefulCreate("ntlmauthenticator"); - ntlmauthenticators->cmdline = Config.Program.ntlmauthenticate; - ntlmauthenticators->n_to_start = Config.ntlmauthenticateChildren; - ntlmauthenticators->ipc_type = IPC_TCP_SOCKET; - helperStatefulOpenServers(ntlmauthenticators); - if (!ntlminit) { - cachemgrRegister("ntlmauthenticator", - "User NTLM Authenticator Stats", - authenticateNTLMStats, 0, 1); - ntlminit++; - } - } -#endif } void authenticateShutdown(void) { int i; -#if 0 - if (basicauthenticators) - helperShutdown(basicauthenticators); - if (ntlmauthenticators) - helperStatefulShutdown(ntlmauthenticators); - if (!shutting_down) - return; - helperFree(basicauthenticators); - basicauthenticators = NULL; - helperStatefulFree(ntlmauthenticators); - ntlmauthenticators = NULL; -#endif /* find the currently known authscheme types */ for (i = 0; authscheme_list && authscheme_list[i].typestr; i++) { authscheme_list[i].donefunc(); @@ -1034,9 +277,10 @@ authenticateFixErrorHeader(HttpReply * rep, ErrorState * err) /* send the auth types we are configured to support (and have compiled in!) */ { - auth_type_t auth_type=err->auth_type; +/* auth_type_t auth_type=err->auth_type; auth_state_t auth_state=err->auth_state; char *authchallenge=err->authchallenge; +*/ acl_proxy_auth_user *auth_user=err->auth_user; int type; switch (err->http_status) { case HTTP_PROXY_AUTHENTICATION_REQUIRED: @@ -1053,8 +297,18 @@ return; break; } - debug(29,9)("authenticateFixErrorHeader: headertype:%d authtype:%d authstate:%d\n",type,auth_type,auth_state); + debug(29,9)("authenticateFixErrorHeader: 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); + else { + int i; + /* call each currently known authscheme */ + for (i = 0; authscheme_list && authscheme_list[i].typestr; i++) { + authscheme_list[i].authFixErrorHeader(auth_user,rep, type, err->request); + } + } +#if OBSOLETE switch (auth_type){ case AUTH_UNKNOWN: #if 0 @@ -1118,6 +372,7 @@ fatal("Unknown authentication type"); } return; +#endif } Index: squid/src/client_side.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/client_side.c,v retrieving revision 1.1.1.3.4.1.2.30.2.1 retrieving revision 1.1.1.3.4.1.2.30.2.2 diff -u -r1.1.1.3.4.1.2.30.2.1 -r1.1.1.3.4.1.2.30.2.2 --- squid/src/client_side.c 20 Nov 2000 13:18:04 -0000 1.1.1.3.4.1.2.30.2.1 +++ squid/src/client_side.c 21 Nov 2000 00:11:16 -0000 1.1.1.3.4.1.2.30.2.2 @@ -1,6 +1,6 @@ /* - * $Id: client_side.c,v 1.1.1.3.4.1.2.30.2.1 2000/11/20 13:18:04 rbcollins Exp $ + * $Id: client_side.c,v 1.1.1.3.4.1.2.30.2.2 2000/11/21 00:11:16 rbcollins Exp $ * * DEBUG: section 33 Client-side Routines * AUTHOR: Duane Wessels @@ -259,6 +259,9 @@ err = errorCon(page_id, status); err->request = requestLink(http->request); err->src_addr = http->conn->peer.sin_addr; + if (http->conn->auth_user) + err->auth_user=http->conn->auth_user; +#if OBSOLETE err->auth_type = http->conn->auth_type; if (http->conn->auth_user) { if (http->conn->auth_user->auth_type==AUTH_NTLM) @@ -267,6 +270,7 @@ err->auth_state = AUTHENTICATE_STATE_NONE; if ((http->conn->auth_user) && (http->conn->auth_user->auth_type==AUTH_NTLM)) err->authchallenge = http->conn->auth_user->auth_data.ntlm_auth.authchallenge; +#endif errorAppendEntry(http->entry, err); } } Index: squid/src/errorpage.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/errorpage.c,v retrieving revision 1.1.1.3.10.9 retrieving revision 1.1.1.3.10.9.2.1 diff -u -r1.1.1.3.10.9 -r1.1.1.3.10.9.2.1 --- squid/src/errorpage.c 16 Nov 2000 11:47:00 -0000 1.1.1.3.10.9 +++ squid/src/errorpage.c 21 Nov 2000 00:11:16 -0000 1.1.1.3.10.9.2.1 @@ -1,6 +1,6 @@ /* - * $Id: errorpage.c,v 1.1.1.3.10.9 2000/11/16 11:47:00 rbcollins Exp $ + * $Id: errorpage.c,v 1.1.1.3.10.9.2.1 2000/11/21 00:11:16 rbcollins Exp $ * * DEBUG: section 4 Error Generation * AUTHOR: Duane Wessels @@ -277,7 +277,7 @@ storeBuffer(entry); rep = errorBuildReply(err); /* Add authentication header */ - debug(28,6)("errorpage:state:type %d:%d.\n",err->auth_state,err->auth_type); +// debug(28,6)("errorpage:state:type %d:%d.\n",err->auth_state,err->auth_type); authenticateFixErrorHeader(rep, err); httpReplySwapOut(rep, entry); httpReplyAbsorb(mem->reply, rep); 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.3 retrieving revision 1.1.1.3.4.1.2.26.2.4 diff -u -r1.1.1.3.4.1.2.26.2.3 -r1.1.1.3.4.1.2.26.2.4 --- squid/src/structs.h 20 Nov 2000 22:40:33 -0000 1.1.1.3.4.1.2.26.2.3 +++ squid/src/structs.h 21 Nov 2000 00:11:16 -0000 1.1.1.3.4.1.2.26.2.4 @@ -1,6 +1,6 @@ /* - * $Id: structs.h,v 1.1.1.3.4.1.2.26.2.3 2000/11/20 22:40:33 rbcollins Exp $ + * $Id: structs.h,v 1.1.1.3.4.1.2.26.2.4 2000/11/21 00:11:16 rbcollins Exp $ * * * SQUID Internet Object Cache http://squid.nlanr.net/Squid/ @@ -135,6 +135,7 @@ // STFSPARSE *parsefunc; // STFSRECONFIGURE *reconfigurefunc; AUTHSAUTHUSER *authAuthenticate; + AUTHSFIXERR *authFixErrorHeader; AUTHSUSERNAME *authUserUsername; AUTHSONCLOSEC *oncloseconnection; AUTHSDECODE *decodeauth; @@ -1591,9 +1592,10 @@ err_type type; int page_id; http_status http_status; - auth_type_t auth_type; + acl_proxy_auth_user * auth_user; +/* auth_type_t auth_type; auth_state_t auth_state; - char *authchallenge; + char *authchallenge; */ request_t *request; char *url; int xerrno; Index: squid/src/typedefs.h =================================================================== RCS file: /cvsroot/squid-sf//squid/src/typedefs.h,v retrieving revision 1.1.1.3.12.13.2.3 retrieving revision 1.1.1.3.12.13.2.4 diff -u -r1.1.1.3.12.13.2.3 -r1.1.1.3.12.13.2.4 --- squid/src/typedefs.h 20 Nov 2000 22:40:33 -0000 1.1.1.3.12.13.2.3 +++ squid/src/typedefs.h 21 Nov 2000 00:11:16 -0000 1.1.1.3.12.13.2.4 @@ -1,6 +1,6 @@ /* - * $Id: typedefs.h,v 1.1.1.3.12.13.2.3 2000/11/20 22:40:33 rbcollins Exp $ + * $Id: typedefs.h,v 1.1.1.3.12.13.2.4 2000/11/21 00:11:16 rbcollins Exp $ * * * SQUID Internet Object Cache http://squid.nlanr.net/Squid/ @@ -293,6 +293,7 @@ typedef acl_proxy_auth_user * AUTHSAUTHUSER(acl_proxy_auth_user *, request_t *, ConnStateData *, http_hdr_type); typedef void AUTHSDECODE(acl_proxy_auth_user *, const char *); typedef int AUTHSDIRECTION(acl_proxy_auth_user *); +typedef void AUTHSFIXERR(acl_proxy_auth_user *, HttpReply *, http_hdr_type, request_t *); typedef char *AUTHSUSERNAME(acl_proxy_auth_user *); typedef void AUTHSONCLOSEC(acl_proxy_auth_user *); typedef void AUTHSSETUP(authscheme_entry_t *); 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.2 retrieving revision 1.1.2.3 diff -u -r1.1.2.2 -r1.1.2.3 --- squid/src/auth/basic/auth_basic.c 20 Nov 2000 22:40:33 -0000 1.1.2.2 +++ squid/src/auth/basic/auth_basic.c 21 Nov 2000 00:11:16 -0000 1.1.2.3 @@ -71,7 +71,8 @@ static HLPCB authenticateBasicHandleReply; static AUTHSAUTHUSER authenticateBasicAuthenticateUser; static AUTHSDIRECTION authenticateBasicDirection; -static AUTHSDECODE authenticateBasicDecodeAuth; +static AUTHSDECODE authenticateBasicDecodeAuth; +static AUTHSFIXERR authenticateBasicFixErrorHeader; static AUTHSSTART authenticateBasicStart; static AUTHSSTATS authenticateBasicStats; static AUTHSUSERNAME authenticateBasicUsername; @@ -104,6 +105,7 @@ // authscheme->parsefunc = storeUfsDirParse; // authscheme->reconfigurefunc = storeUfsDirReconfigure; authscheme->authAuthenticate = authenticateBasicAuthenticateUser; + authscheme->authFixErrorHeader=authenticateBasicFixErrorHeader; authscheme->authStart =authenticateBasicStart; authscheme->authStats =authenticateBasicStats; authscheme->authUserUsername = authenticateBasicUsername; @@ -201,6 +203,14 @@ return -2; } +void +authenticateBasicFixErrorHeader(acl_proxy_auth_user *auth_user, HttpReply *rep, http_hdr_type type, request_t * request){ + 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); + } +} + static void authenticateBasicHandleReply(void *data, char *reply) { 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.2 retrieving revision 1.1.2.3 diff -u -r1.1.2.2 -r1.1.2.3 --- squid/src/auth/ntlm/auth_ntlm.c 20 Nov 2000 22:40:34 -0000 1.1.2.2 +++ squid/src/auth/ntlm/auth_ntlm.c 21 Nov 2000 00:11:16 -0000 1.1.2.3 @@ -69,6 +69,7 @@ static void authenticateNTLMStart(acl_proxy_auth_user *, RH * handler, void *); static HLPSCB authenticateNTLMHandleReply; static AUTHSAUTHUSER authenticateNTLMAuthenticateUser; +static AUTHSFIXERR authenticateNTLMFixErrorHeader; static AUTHSDIRECTION authenticateNTLMDirection; static AUTHSDECODE authenticateDecodeNTLMAuth; static AUTHSONCLOSEC authenticateNTLMOnCloseConnection; @@ -107,6 +108,7 @@ // authscheme->parsefunc = storeUfsDirParse; // authscheme->reconfigurefunc = storeUfsDirReconfigure; authscheme->authAuthenticate = authenticateNTLMAuthenticateUser; + authscheme->authFixErrorHeader=authenticateNTLMFixErrorHeader; authscheme->authStart =authenticateNTLMStart; authscheme->authStats =authenticateNTLMStats; authscheme->authUserUsername = authenticateNTLMUsername; @@ -151,6 +153,48 @@ return -2; } +/* + * Send the authenticate error header(s). Note: IE has a bug and the NTLM header + * must be first. To ensure that, the configure use --enable-auth=ntlm, anything + * else. + */ +void +authenticateNTLMFixErrorHeader(acl_proxy_auth_user *auth_user, HttpReply *rep, http_hdr_type type, request_t * request){ + if (Config.Program.ntlmauthenticate){ + /* New request, no user details */ + if (auth_user == NULL) { + debug(29, 5) ("authenticateFixErrorHeader: 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 { + switch (auth_user->auth_data.ntlm_auth.auth_state){ + case AUTHENTICATE_STATE_NONE: + debug(29, 5) ("authenticateFixErrorHeader: 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, 5) ("authenticateFixErrorHeader: Sending type:%d header: 'NTLM %s'\n",type,auth_user->auth_data.ntlm_auth.authchallenge); + httpHeaderPutStrf(&rep->header, type, "NTLM %s", auth_user->auth_data.ntlm_auth.authchallenge); + break; + default: + debug(29,1)("authenticateFixErrorHeader: state %d.\n",auth_user->auth_data.ntlm_auth.auth_state); + fatal("unexpected state in AuthenticateFixErrorHeader.\n"); + } + } + } +} + static stateful_helper_callback_t authenticateNTLMHandleReply(void *data, void * lastserver, char *reply) {