--------------------- PatchSet 2689 Date: 2001/07/31 14:13:20 Author: rbcollins Branch: ntlm Tag: (none) Log: code shifting to tidy up authenticate API and some minor ntlm code notes Members: src/acl.c:1.1.1.3.12.62->1.1.1.3.12.63 src/authenticate.c:1.1.1.3.12.41->1.1.1.3.12.42 src/protos.h:1.1.1.3.12.37->1.1.1.3.12.38 src/auth/ntlm/auth_ntlm.c:1.1.10.14.2.25->1.1.10.14.2.26 Index: squid/src/acl.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/acl.c,v retrieving revision 1.1.1.3.12.62 retrieving revision 1.1.1.3.12.63 diff -u -r1.1.1.3.12.62 -r1.1.1.3.12.63 --- squid/src/acl.c 31 Jul 2001 09:09:24 -0000 1.1.1.3.12.62 +++ squid/src/acl.c 31 Jul 2001 14:13:20 -0000 1.1.1.3.12.63 @@ -1,6 +1,6 @@ /* - * $Id: acl.c,v 1.1.1.3.12.62 2001/07/31 09:09:24 rbcollins Exp $ + * $Id: acl.c,v 1.1.1.3.12.63 2001/07/31 14:13:20 rbcollins Exp $ * * DEBUG: section 28 Access Control * AUTHOR: Duane Wessels @@ -1182,189 +1182,6 @@ } } - - /* THIS IS FOR BUGFIXING BELOW... ***** - * Is this an already authenticated connection with a new auth header? - * FIXME: This breaks the abstraction model. Even if it is just for bug hunting - * It's really really ugly. - */ - #include "auth/ntlm/auth_ntlm.h" - -/* returns one of - * AUTH_ACL_CHALLENGE, - * AUTH_ACL_HELPER, - * AUTH_ACL_CANNOT_AUTHENTICATE, - * AUTH_AUTHENTICATED - * - * How to use: In your proxy-auth dependent acl code, use the following - * construct: - * int rv; - * if ((rv = AuthenticateAuthenticate()) != AUTH_AUTHENTICATED) - * return rv; - * - * when this code is reached, the request/connection is authenticated. - * - * if you have non-acl code, but want to force authentication, you need a - * callback mechanism like the acl testing routines that will send a 40[1|7] to - * the client when rv==AUTH_ACL_CHALLENGE, and will communicate with - * the authenticateStart routine for rv==AUTH_ACL_HELPER - */ -static auth_acl_t -AuthenticateAuthenticate(auth_user_request_t ** auth_user_request, http_hdr_type headertype, request_t *request, ConnStateData *conn, struct in_addr src_addr) -{ - const char * proxy_auth; - assert(headertype != 0); - proxy_auth = httpHeaderGetStr(&request->header, headertype); - - if (conn == NULL) { - debug(28, 1) ("aclMatchProxyAuth: no connection data, cannot process authentication\n"); - /* - * deny access: clientreadrequest requires conn data, and it is always - * compiled in so we should have it too. - */ - return AUTH_ACL_CANNOT_AUTHENTICATE; - } - - /* - * a note on proxy_auth logix here: - * proxy_auth==NULL -> unauthenticated request || already authenticated connection - * so we test for an authenticated connection when we recieve no authentication - * header. - */ - if (((proxy_auth == NULL) && (!authenticateUserAuthenticated(*auth_user_request ? *auth_user_request : conn->auth_user_request))) - || (conn->auth_type == AUTH_BROKEN)) { - /* no header or authentication failed/got corrupted - restart */ - conn->auth_type = AUTH_UNKNOWN; - debug(28, 4) ("aclMatchProxyAuth: broken auth or no proxy_auth header. Requesting auth header.\n"); - /* something wrong with the AUTH credentials. Force a new attempt */ - conn->auth_user_request = NULL; - if (*auth_user_request) { - /* unlock the ACL lock */ - authenticateAuthUserRequestUnlock(*auth_user_request); - auth_user_request = NULL; - } - return AUTH_ACL_CHALLENGE; - } - - /* - * Is this an already authenticated connection with a new auth header? - * FIXME: This breaks the abstraction model. Even if it is just for bug hunting - * It's really really ugly. - */ - if (proxy_auth && conn->auth_user_request && - authenticateUserAuthenticated(conn->auth_user_request) - && strcmp(proxy_auth, ((ntlm_request_t *)(conn->auth_user_request->scheme_data))->ntlmauthenticate)) { - debug(28,1) ("aclMatchProxyAuth: DUPLICATE AUTH - authentication header on already authenticated connection!. Current user '%s' proxy_auth %s, authenticate request %s\n", authenticateUserRequestUsername(conn->auth_user_request), proxy_auth, ((ntlm_request_t *)(conn->auth_user_request->scheme_data))->ntlmauthenticate); - /* remove this request struct - the link is already authed and it can't be to - * reauth. - */ - - /* This should _only_ ever occur on the first pass through aclMatchProxyAuth */ - assert(*auth_user_request == NULL); - /* unlock the conn lock on the auth_user_request */ - authenticateAuthUserRequestUnlock(conn->auth_user_request); - /* mark the conn as non-authed. */ - conn->auth_user_request=NULL; - /* Set the connection auth type */ - conn->auth_type = AUTH_UNKNOWN; - } - - /* we have a proxy auth header and as far as we know this connection has - * not had bungled connection oriented authentication happen on it. */ - debug(28, 9) ("aclMatchProxyAuth: header %s.\n", proxy_auth); - if (*auth_user_request == NULL) { - debug(28, 9) ("aclMatchProxyAuth: This is a new checklist test on FD:%d\n", - conn->fd); - if ((!request->auth_user_request) - && (conn->auth_type == AUTH_UNKNOWN)) { - /* beginning of a new request check */ - debug(28, 4) ("aclMatchProxyAuth: no connection authentication type\n"); - if (!authenticateValidateUser(*auth_user_request = - authenticateGetAuthUser(proxy_auth))) { - /* the decode might have left a username for logging, or a message to - * the user */ - if (authenticateUserRequestUsername(*auth_user_request)) { - /* lock the user for the request structure link */ - authenticateAuthUserRequestLock(*auth_user_request); - request->auth_user_request = *auth_user_request; - /* unlock the ACL reference. */ - authenticateAuthUserRequestUnlock(*auth_user_request); - } - return AUTH_ACL_CHALLENGE; - } - /* the user_request comes prelocked for the caller to GetAuthUser (us) */ - } else if (request->auth_user_request) { - *auth_user_request = request->auth_user_request; - /* lock the user request for this ACL processing */ - authenticateAuthUserRequestLock(*auth_user_request); - } else { - if (conn->auth_user_request != NULL) { - *auth_user_request = conn->auth_user_request; - /* lock the user request for this ACL processing */ - authenticateAuthUserRequestLock(*auth_user_request); - } else { - /* failed connection based authentication */ - debug(28, 4) ("aclMatchProxyAuth: Auth user request %d conn-auth user request %d conn type %d authentication failed.\n", - *auth_user_request, conn->auth_user_request, conn->auth_type); - authenticateAuthUserRequestUnlock(*auth_user_request); - *auth_user_request=NULL; - return AUTH_ACL_CHALLENGE; - } - } - } - - if (!authenticateUserAuthenticated(*auth_user_request)) { - /* User not logged in. Log them in */ - authenticateAuthenticateUser(*auth_user_request, request, - conn, headertype); - switch (authenticateDirection(*auth_user_request)) { - case 1: - /* this ACL check is finished. Unlock. */ - authenticateAuthUserRequestUnlock(*auth_user_request); - *auth_user_request=NULL; - return AUTH_ACL_CHALLENGE; - case -1: - /* we are partway through authentication within squid, - * the *auth_user_request variables stores the auth_user_request - * for the callback to here - Do not Unlock */ - return AUTH_ACL_HELPER; - case -2: - /* this ACL check is finished. Unlock. */ - authenticateAuthUserRequestUnlock(*auth_user_request); - *auth_user_request=NULL; - return AUTH_ACL_CHALLENGE; - } - /* on 0 the authentication is finished - fallthrough */ - /* See of user authentication failed for some reason */ - if (!authenticateUserAuthenticated(*auth_user_request)) { - if ((authenticateUserRequestUsername(*auth_user_request))) { - if (!request->auth_user_request) { - /* lock the user for the request structure link */ - authenticateAuthUserRequestLock(*auth_user_request); - request->auth_user_request = *auth_user_request; - } - } - /* this ACL check is finished. Unlock. */ - authenticateAuthUserRequestUnlock(*auth_user_request); - *auth_user_request=NULL; - return AUTH_ACL_CHALLENGE; - } - } - - /* copy username to request for logging on client-side */ - /* the credentials are correct at this point */ - if (!request->auth_user_request) { - /* lock the user for the request structure link */ - authenticateAuthUserRequestLock(*auth_user_request); - request->auth_user_request = *auth_user_request; - authenticateAuthUserRequestSetIp(*auth_user_request, src_addr); - } - - /* Unlock the request - we've authenticated it */ - authenticateAuthUserRequestUnlock(*auth_user_request); - return AUTH_AUTHENTICATED; -} - /* aclMatchProxyAuth can return four exit codes: * 0 : Authorisation for this ACL failed. (Did not match) * 1 : Authorisation OK. (Matched) @@ -1771,7 +1588,7 @@ #endif } /* get authed here */ - if ((ti = AuthenticateAuthenticate(&checklist->auth_user_request, headertype, checklist->request, checklist->conn, checklist->src_addr)) != AUTH_AUTHENTICATED) { + if ((ti = authenticateAuthenticate(&checklist->auth_user_request, headertype, checklist->request, checklist->conn, checklist->src_addr)) != AUTH_AUTHENTICATED) { switch (ti) { case 0: /* Authenticated but not Authorised for this ACL */ Index: squid/src/authenticate.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/authenticate.c,v retrieving revision 1.1.1.3.12.41 retrieving revision 1.1.1.3.12.42 diff -u -r1.1.1.3.12.41 -r1.1.1.3.12.42 --- squid/src/authenticate.c 27 Jul 2001 14:23:49 -0000 1.1.1.3.12.41 +++ squid/src/authenticate.c 31 Jul 2001 14:13:20 -0000 1.1.1.3.12.42 @@ -1,6 +1,6 @@ /* - * $Id: authenticate.c,v 1.1.1.3.12.41 2001/07/27 14:23:49 rbcollins Exp $ + * $Id: authenticate.c,v 1.1.1.3.12.42 2001/07/31 14:13:20 rbcollins Exp $ * * DEBUG: section 29 Authenticator * AUTHOR: Duane Wessels @@ -407,11 +407,12 @@ } /* - * authenticateAuthenticateUser: log this user request in. + * authenticateAuthenticateUser: call the module specific code to + * log this user request in. * Cache hits may change the auth_user pointer in the structure if needed. * This is basically a handle approach. */ -void +static void authenticateAuthenticateUser(auth_user_request_t * auth_user_request, request_t * request, ConnStateData * conn, http_hdr_type type) { assert(auth_user_request != NULL); @@ -419,6 +420,189 @@ authscheme_list[auth_user_request->auth_user->auth_module - 1].authAuthenticate(auth_user_request, request, conn, type); } + /* THIS IS FOR BUGFIXING BELOW... ***** + * Is this an already authenticated connection with a new auth header? + * FIXME: This breaks the abstraction model. Even if it is just for bug hunting + * It's really really ugly. + */ + #include "auth/ntlm/auth_ntlm.h" + +/* returns one of + * AUTH_ACL_CHALLENGE, + * AUTH_ACL_HELPER, + * AUTH_ACL_CANNOT_AUTHENTICATE, + * AUTH_AUTHENTICATED + * + * How to use: In your proxy-auth dependent acl code, use the following + * construct: + * int rv; + * if ((rv = AuthenticateAuthenticate()) != AUTH_AUTHENTICATED) + * return rv; + * + * when this code is reached, the request/connection is authenticated. + * + * if you have non-acl code, but want to force authentication, you need a + * callback mechanism like the acl testing routines that will send a 40[1|7] to + * the client when rv==AUTH_ACL_CHALLENGE, and will communicate with + * the authenticateStart routine for rv==AUTH_ACL_HELPER + */ +auth_acl_t +authenticateAuthenticate(auth_user_request_t ** auth_user_request, http_hdr_type headertype, request_t *request, ConnStateData *conn, struct in_addr src_addr) +{ + const char * proxy_auth; + assert(headertype != 0); + proxy_auth = httpHeaderGetStr(&request->header, headertype); + + if (conn == NULL) { + debug(28, 1) ("aclMatchProxyAuth: no connection data, cannot process authentication\n"); + /* + * deny access: clientreadrequest requires conn data, and it is always + * compiled in so we should have it too. + */ + return AUTH_ACL_CANNOT_AUTHENTICATE; + } + + /* + * a note on proxy_auth logix here: + * proxy_auth==NULL -> unauthenticated request || already authenticated connection + * so we test for an authenticated connection when we recieve no authentication + * header. + */ + if (((proxy_auth == NULL) && (!authenticateUserAuthenticated(*auth_user_request ? *auth_user_request : conn->auth_user_request))) + || (conn->auth_type == AUTH_BROKEN)) { + /* no header or authentication failed/got corrupted - restart */ + conn->auth_type = AUTH_UNKNOWN; + debug(28, 4) ("aclMatchProxyAuth: broken auth or no proxy_auth header. Requesting auth header.\n"); + /* something wrong with the AUTH credentials. Force a new attempt */ + conn->auth_user_request = NULL; + if (*auth_user_request) { + /* unlock the ACL lock */ + authenticateAuthUserRequestUnlock(*auth_user_request); + auth_user_request = NULL; + } + return AUTH_ACL_CHALLENGE; + } + + /* + * Is this an already authenticated connection with a new auth header? + * FIXME: This breaks the abstraction model. Even if it is just for bug hunting + * It's really really ugly. + */ + if (proxy_auth && conn->auth_user_request && + authenticateUserAuthenticated(conn->auth_user_request) + && strcmp(proxy_auth, ((ntlm_request_t *)(conn->auth_user_request->scheme_data))->ntlmauthenticate)) { + debug(28,1) ("aclMatchProxyAuth: DUPLICATE AUTH - authentication header on already authenticated connection!. Current user '%s' proxy_auth %s, authenticate request %s\n", authenticateUserRequestUsername(conn->auth_user_request), proxy_auth, ((ntlm_request_t *)(conn->auth_user_request->scheme_data))->ntlmauthenticate); + /* remove this request struct - the link is already authed and it can't be to + * reauth. + */ + + /* This should _only_ ever occur on the first pass through aclMatchProxyAuth */ + assert(*auth_user_request == NULL); + /* unlock the conn lock on the auth_user_request */ + authenticateAuthUserRequestUnlock(conn->auth_user_request); + /* mark the conn as non-authed. */ + conn->auth_user_request=NULL; + /* Set the connection auth type */ + conn->auth_type = AUTH_UNKNOWN; + } + + /* we have a proxy auth header and as far as we know this connection has + * not had bungled connection oriented authentication happen on it. */ + debug(28, 9) ("aclMatchProxyAuth: header %s.\n", proxy_auth); + if (*auth_user_request == NULL) { + debug(28, 9) ("aclMatchProxyAuth: This is a new checklist test on FD:%d\n", + conn->fd); + if ((!request->auth_user_request) + && (conn->auth_type == AUTH_UNKNOWN)) { + /* beginning of a new request check */ + debug(28, 4) ("aclMatchProxyAuth: no connection authentication type\n"); + if (!authenticateValidateUser(*auth_user_request = + authenticateGetAuthUser(proxy_auth))) { + /* the decode might have left a username for logging, or a message to + * the user */ + if (authenticateUserRequestUsername(*auth_user_request)) { + /* lock the user for the request structure link */ + authenticateAuthUserRequestLock(*auth_user_request); + request->auth_user_request = *auth_user_request; + /* unlock the ACL reference. */ + authenticateAuthUserRequestUnlock(*auth_user_request); + } + return AUTH_ACL_CHALLENGE; + } + /* the user_request comes prelocked for the caller to GetAuthUser (us) */ + } else if (request->auth_user_request) { + *auth_user_request = request->auth_user_request; + /* lock the user request for this ACL processing */ + authenticateAuthUserRequestLock(*auth_user_request); + } else { + if (conn->auth_user_request != NULL) { + *auth_user_request = conn->auth_user_request; + /* lock the user request for this ACL processing */ + authenticateAuthUserRequestLock(*auth_user_request); + } else { + /* failed connection based authentication */ + debug(28, 4) ("aclMatchProxyAuth: Auth user request %d conn-auth user request %d conn type %d authentication failed.\n", + *auth_user_request, conn->auth_user_request, conn->auth_type); + authenticateAuthUserRequestUnlock(*auth_user_request); + *auth_user_request=NULL; + return AUTH_ACL_CHALLENGE; + } + } + } + + if (!authenticateUserAuthenticated(*auth_user_request)) { + /* User not logged in. Log them in */ + authenticateAuthenticateUser(*auth_user_request, request, + conn, headertype); + switch (authenticateDirection(*auth_user_request)) { + case 1: + /* this ACL check is finished. Unlock. */ + authenticateAuthUserRequestUnlock(*auth_user_request); + *auth_user_request=NULL; + return AUTH_ACL_CHALLENGE; + case -1: + /* we are partway through authentication within squid, + * the *auth_user_request variables stores the auth_user_request + * for the callback to here - Do not Unlock */ + return AUTH_ACL_HELPER; + case -2: + /* this ACL check is finished. Unlock. */ + authenticateAuthUserRequestUnlock(*auth_user_request); + *auth_user_request=NULL; + return AUTH_ACL_CHALLENGE; + } + /* on 0 the authentication is finished - fallthrough */ + /* See of user authentication failed for some reason */ + if (!authenticateUserAuthenticated(*auth_user_request)) { + if ((authenticateUserRequestUsername(*auth_user_request))) { + if (!request->auth_user_request) { + /* lock the user for the request structure link */ + authenticateAuthUserRequestLock(*auth_user_request); + request->auth_user_request = *auth_user_request; + } + } + /* this ACL check is finished. Unlock. */ + authenticateAuthUserRequestUnlock(*auth_user_request); + *auth_user_request=NULL; + return AUTH_ACL_CHALLENGE; + } + } + + /* copy username to request for logging on client-side */ + /* the credentials are correct at this point */ + if (!request->auth_user_request) { + /* lock the user for the request structure link */ + authenticateAuthUserRequestLock(*auth_user_request); + request->auth_user_request = *auth_user_request; + authenticateAuthUserRequestSetIp(*auth_user_request, src_addr); + } + + /* Unlock the request - we've authenticated it */ + authenticateAuthUserRequestUnlock(*auth_user_request); + return AUTH_AUTHENTICATED; +} + + /* authenticateUserUsername: return a pointer to the username in the */ char * authenticateUserUsername(auth_user_t * auth_user) Index: squid/src/protos.h =================================================================== RCS file: /cvsroot/squid-sf//squid/src/protos.h,v retrieving revision 1.1.1.3.12.37 retrieving revision 1.1.1.3.12.38 diff -u -r1.1.1.3.12.37 -r1.1.1.3.12.38 --- squid/src/protos.h 29 Jul 2001 05:11:32 -0000 1.1.1.3.12.37 +++ squid/src/protos.h 31 Jul 2001 14:13:20 -0000 1.1.1.3.12.38 @@ -1,6 +1,6 @@ /* - * $Id: protos.h,v 1.1.1.3.12.37 2001/07/29 05:11:32 rbcollins Exp $ + * $Id: protos.h,v 1.1.1.3.12.38 2001/07/31 14:13:20 rbcollins Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -738,7 +738,7 @@ extern void authenticateFixHeader(HttpReply *, auth_user_request_t *, request_t *, int, int); extern void authenticateAddTrailer(HttpReply *, auth_user_request_t *, request_t *, int); extern auth_user_request_t *authenticateGetAuthUser(const char *proxy_auth); -extern void authenticateAuthenticateUser(auth_user_request_t *, request_t *, ConnStateData *, http_hdr_type); +extern auth_acl_t authenticateAuthenticate(auth_user_request_t **, http_hdr_type, request_t *, ConnStateData *, struct in_addr); extern void authenticateAuthUserUnlock(auth_user_t * auth_user); extern void authenticateAuthUserLock(auth_user_t * auth_user); extern void authenticateAuthUserRequestUnlock(auth_user_request_t *); 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.10.14.2.25 retrieving revision 1.1.10.14.2.26 diff -u -r1.1.10.14.2.25 -r1.1.10.14.2.26 --- squid/src/auth/ntlm/auth_ntlm.c 31 Jul 2001 09:09:24 -0000 1.1.10.14.2.25 +++ squid/src/auth/ntlm/auth_ntlm.c 31 Jul 2001 14:13:20 -0000 1.1.10.14.2.26 @@ -735,6 +735,7 @@ helperstate->starve = 1; /* and release the deferred request */ helperStatefulReleaseServer(server); + /* Get another deferrable server */ server = helperStatefulDefer(ntlmauthenticators); if (server != NULL) helperstate = helperStatefulServerGetData(server); @@ -747,14 +748,16 @@ debug(29, 9) ("authenticateNTLMStart: helper '%d' assigned\n", server); /* server and valid challenge? */ if ((server == NULL) || !authenticateNTLMValidChallenge(helperstate)) { + /* No server, or server with invalid challenge */ r = cbdataAlloc(authenticateStateData); 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->authserver); + helperStatefulSubmit(ntlmauthenticators, NULL, authenticateNTLMHandleplaceholder, r, NULL); } else { + /* Server with invalid challenge */ snprintf(buf, 8192, "YR\n"); #ifdef EXTRA_DEBUG @@ -764,7 +767,6 @@ assert (r->auth_user_request->auth_user->scheme_data); #endif - helperStatefulSubmit(ntlmauthenticators, buf, authenticateNTLMHandleReply, r, ntlm_request->authserver); } } else {