--------------------- PatchSet 1133 Date: 2001/01/06 23:33:48 Author: rbcollins Branch: auth_rewrite Tag: (none) Log: general tidyup Members: src/acl.c:1.1.1.3.12.26.2.19->1.1.1.3.12.26.2.20 Index: squid/src/acl.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/acl.c,v retrieving revision 1.1.1.3.12.26.2.19 retrieving revision 1.1.1.3.12.26.2.20 diff -u -r1.1.1.3.12.26.2.19 -r1.1.1.3.12.26.2.20 --- squid/src/acl.c 6 Jan 2001 22:51:16 -0000 1.1.1.3.12.26.2.19 +++ squid/src/acl.c 6 Jan 2001 23:33:48 -0000 1.1.1.3.12.26.2.20 @@ -1,6 +1,6 @@ /* - * $Id: acl.c,v 1.1.1.3.12.26.2.19 2001/01/06 22:51:16 rbcollins Exp $ + * $Id: acl.c,v 1.1.1.3.12.26.2.20 2001/01/06 23:33:48 rbcollins Exp $ * * DEBUG: section 28 Access Control * AUTHOR: Duane Wessels @@ -38,6 +38,7 @@ static int aclFromFile = 0; static FILE *aclFile; + static void aclParseDomainList(void *curlist); #if 0 /* potential future work */ @@ -727,7 +728,7 @@ new_acl = 1; } else { if (acltype != A->type) { - debug(28, 0) ("aclParseAclLine: ACL '%s' already exists with different type, skipping.\n", A->name); + debug(28, 0) ("aclParseAclLine: ACL '%s' already exists with different type, skipping.\n", A->name); return; } debug(28, 3) ("aclParseAclLine: Appending to '%s'\n", aclname); @@ -1168,8 +1169,7 @@ proxy_auth = httpHeaderGetStr(&checklist->request->header, headertype); if (checklist->conn == NULL) { - debug(28, 1) - ("aclMatchProxyAuth: no connection data, denying access\n"); + 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. @@ -1179,8 +1179,7 @@ if (((proxy_auth == NULL) && (checklist->conn->auth_type==AUTH_UNKNOWN)) || (checklist->conn->auth_type == AUTH_BROKEN)) { /* no header or authentication failed/got corrupted - restart */ checklist->conn->auth_type = AUTH_UNKNOWN; - debug(28,5) - ("aclMatchProxyAuth: auth state none:broken auth or no proxy_auth header.\n"); + 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 */ checklist->auth_user_request = NULL; checklist->conn->auth_user_request = NULL; @@ -1192,12 +1191,12 @@ } /* 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,6) ("aclMatchProxyAuth: header %s.\n", proxy_auth); + debug(28,9) ("aclMatchProxyAuth: header %s.\n", proxy_auth); if (auth_user_request == NULL) { - debug(28,5) ("aclMatchProxyAuth: This is a new request on FD:%d\n", checklist->conn->fd); + debug(28,9) ("aclMatchProxyAuth: This is a new request on FD:%d\n", checklist->conn->fd); if ((!checklist->request->auth_user_request) && (checklist->conn->auth_type==AUTH_UNKNOWN )) { /* beginning of a new request check */ - debug(28,5)("aclMatchProxyAuth: no connection authentication type\n"); + 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 @@ -1224,7 +1223,7 @@ authenticateAuthUserRequestLock(auth_user_request); } else { /* failed connection based authentication */ - debug(28,1)("auth user %d connauth user %d conn type %d\n",auth_user_request, checklist->conn->auth_user_request,checklist->conn->auth_type); + debug(28,4)("aclMatchProxyAuth: Aauth user request %d conn-auth user request %d conn type %d authentication failed.\n",auth_user_request, checklist->conn->auth_user_request,checklist->conn->auth_type); return -2; } } @@ -1348,7 +1347,6 @@ auth_user_request = checklist->auth_user_request; assert(authenticateValidateUser(auth_user_request)); - authenticateStart(auth_user_request, aclLookupProxyAuthDone, checklist); } @@ -1417,6 +1415,7 @@ t = (time_t) (tm.tm_hour * 60 + tm.tm_min); debug(28, 3) ("aclMatchTime: checking %d in %d-%d, weekbits=%x\n", (int) t, (int) data->start, (int) data->stop, data->weekbits); + if (t < data->start || t > data->stop) return 0; return data->weekbits & (1 << tm.tm_wday) ? 1 : 0; @@ -1511,13 +1510,11 @@ return aclMatchDomainList(&ae->data, "none"); /* NOTREACHED */ case ACL_SRC_DOMAIN: - fqdn = - fqdncache_gethostbyaddr(checklist->src_addr, - FQDN_LOOKUP_IF_MISS); if (fqdn) { + fqdn = fqdncache_gethostbyaddr(checklist->src_addr, FQDN_LOOKUP_IF_MISS); + if (fqdn) { return aclMatchDomainList(&ae->data, fqdn); } else if (checklist->state[ACL_SRC_DOMAIN] == ACL_LOOKUP_NONE) { - debug(28, - 3) ("aclMatchAcl: Can't yet compare '%s' ACL for '%s'\n", + debug(28, 3) ("aclMatchAcl: Can't yet compare '%s' ACL for '%s'\n", ae->name, inet_ntoa(checklist->src_addr)); checklist->state[ACL_SRC_DOMAIN] = ACL_LOOKUP_NEEDED; return 0; @@ -1531,8 +1528,7 @@ if (fqdn) return aclMatchRegex(ae->data, fqdn); if (checklist->state[ACL_DST_DOMAIN] == ACL_LOOKUP_NONE) { - debug(28, 3) - ("aclMatchAcl: Can't yet compare '%s' ACL for '%s'\n", + debug(28, 3) ("aclMatchAcl: Can't yet compare '%s' ACL for '%s'\n", ae->name, inet_ntoa(ia->in_addrs[0])); checklist->state[ACL_DST_DOMAIN] = ACL_LOOKUP_NEEDED; return 0; @@ -1540,46 +1536,44 @@ return aclMatchRegex(ae->data, "none"); /* NOTREACHED */ case ACL_SRC_DOM_REGEX: - fqdn = - fqdncache_gethostbyaddr(checklist->src_addr, - FQDN_LOOKUP_IF_MISS); if (fqdn) { + fqdn = fqdncache_gethostbyaddr(checklist->src_addr, FQDN_LOOKUP_IF_MISS); + if (fqdn) { return aclMatchRegex(ae->data, fqdn); } else if (checklist->state[ACL_SRC_DOMAIN] == ACL_LOOKUP_NONE) { - debug(28, - 3) ("aclMatchAcl: Can't yet compare '%s' ACL for '%s'\n", + debug(28, 3) ("aclMatchAcl: Can't yet compare '%s' ACL for '%s'\n", ae->name, inet_ntoa(checklist->src_addr)); checklist->state[ACL_SRC_DOMAIN] = ACL_LOOKUP_NEEDED; return 0; } return aclMatchRegex(ae->data, "none"); -/* NOTREACHED */ + /* NOTREACHED */ case ACL_TIME: return aclMatchTime(ae->data, squid_curtime); -/* NOTREACHED */ + /* NOTREACHED */ case ACL_URLPATH_REGEX: esc_buf = xstrdup(strBuf(r->urlpath)); rfc1738_unescape(esc_buf); k = aclMatchRegex(ae->data, esc_buf); safe_free(esc_buf); return k; -/* NOTREACHED */ + /* NOTREACHED */ case ACL_URL_REGEX: esc_buf = xstrdup(urlCanonical(r)); rfc1738_unescape(esc_buf); k = aclMatchRegex(ae->data, esc_buf); safe_free(esc_buf); return k; -/* NOTREACHED */ + /* NOTREACHED */ case ACL_MAXCONN: k = clientdbEstablished(checklist->src_addr, 0); return ((k > ((intlist *) ae->data)->i) ? 1 : 0); -/* NOTREACHED */ + /* NOTREACHED */ case ACL_URL_PORT: return aclMatchIntegerRange(ae->data, (int) r->port); -/* NOTREACHED */ + /* NOTREACHED */ case ACL_MY_PORT: return aclMatchIntegerRange(ae->data, (int) checklist->my_port); -/* NOTREACHED */ + /* NOTREACHED */ #if USE_IDENT case ACL_IDENT: if (checklist->rfc931[0]) { @@ -1600,16 +1594,16 @@ #endif case ACL_PROTO: return aclMatchInteger(ae->data, r->protocol); -/* NOTREACHED */ + /* NOTREACHED */ case ACL_METHOD: return aclMatchInteger(ae->data, r->method); -/* NOTREACHED */ + /* NOTREACHED */ case ACL_BROWSER: browser = httpHeaderGetStr(&checklist->request->header, HDR_USER_AGENT); if (NULL == browser) return 0; return aclMatchRegex(ae->data, browser); -/* NOTREACHED */ + /* NOTREACHED */ case ACL_PROXY_AUTH: case ACL_PROXY_AUTH_REGEX: if (NULL == r) { @@ -1645,57 +1639,43 @@ /* WWW authorization on accelerated requests */ headertype = HDR_AUTHORIZATION; #else - debug(28, 1) ("aclMatchAcl: proxy_auth %s not applicable on accelera -ted requests.\n", - ae->name); return -1; + debug(28, 1) ("aclMatchAcl: proxy_auth %s not applicable on accelerated requests.\n", ae->name); + return -1; #endif } #if 0 - /* we no longer check this here. See http.c - it's now a peer based option */ + /* we no longer check this here. See http.c - it's now a peer based option */ /* * Register that we used the proxy authentication header so that * it is not forwarded to the next proxy */ r->flags.used_proxy_auth = 1; #endif - /* Check the password */ + /* Check the credentials */ switch (aclMatchProxyAuth(ae->data, headertype, checklist->auth_user_request, checklist, ae->type)) { case 0: - debug(28, 5) ("aclMatchAcl: returning 0 user authenticated but not authorised.\n"); + debug(28, 4) ("aclMatchAcl: returning 0 user authenticated but not authorised.\n"); /* Authenticated but not Authorised for this ACL */ return 0; case 1: - debug(28, 5) ("aclMatchAcl: returning 1 user authenticated and authorised.\n"); + debug(28, 4) ("aclMatchAcl: returning 1 user authenticated and authorised.\n"); /* Authenticated and Authorised for this ACL */ return 1; case -2: - debug(28, 5) ("aclMatchAcl: returning 0 sending authentication challenge.\n"); + debug(28, 4) ("aclMatchAcl: returning 0 sending authentication challenge.\n"); /* Authentication credentials invalid or missing. */ /* Or partway through NTLM handshake. A proxy_Authenticate header * gets sent to the client. */ checklist->state[ACL_PROXY_AUTH] = ACL_PROXY_AUTH_NEEDED; - debug(28, 6) ("aclmatchAcl: sending a proxyauth header to the browser.\n"); -/* - * XXX This is a bit oddly done.. should perhaps use different - * return codes here - */ return 0; case -1: - debug(28, 5) ("aclMatchAcl: returning 0 sending credentials to helper.\n"); + debug(28, 4) ("aclMatchAcl: returning 0 sending credentials to helper.\n"); /* * we need to validate the password */ checklist->state[ACL_PROXY_AUTH] = ACL_LOOKUP_NEEDED; return 0; -#if 0 - case -3: - /* - * we need a external program to generate data for the client - */ - checklist->state[ACL_PROXY_AUTH] = ACL_HELPER_START; - return 0; -#endif } /* NOTREACHED */ #if SQUID_SNMP @@ -1713,8 +1693,7 @@ } return 0; } else if (checklist->state[ACL_DST_ASN] == ACL_LOOKUP_NONE) { - debug(28, - 3) ("asnMatchAcl: Can't yet compare '%s' ACL for '%s'\n", + debug(28, 3) ("asnMatchAcl: Can't yet compare '%s' ACL for '%s'\n", ae->name, r->host); checklist->state[ACL_DST_ASN] = ACL_LOOKUP_NEEDED; } else { @@ -1731,11 +1710,11 @@ if (NULL == header) header = ""; return aclMatchRegex(ae->data, header); -/* NOTREACHED */ + /* NOTREACHED */ case ACL_NONE: default: - debug(28, 0) ("aclMatchAcl: '%s' has bad type %d\n", ae->name, - ae->type); return 0; + debug(28, 0) ("aclMatchAcl: '%s' has bad type %d\n", ae->name, ae->type); + return 0; } /* NOTREACHED */ } @@ -1795,17 +1774,21 @@ if (checklist->state[ACL_DST_IP] == ACL_LOOKUP_NEEDED) { checklist->state[ACL_DST_IP] = ACL_LOOKUP_PENDING; ipcache_nbgethostbyname(checklist->request->host, - aclLookupDstIPDone, checklist); + aclLookupDstIPDone, + checklist); return; } else if (checklist->state[ACL_DST_ASN] == ACL_LOOKUP_NEEDED) { checklist->state[ACL_DST_ASN] = ACL_LOOKUP_PENDING; ipcache_nbgethostbyname(checklist->request->host, - aclLookupDstIPforASNDone, checklist); + aclLookupDstIPforASNDone, + checklist); return; } else if (checklist->state[ACL_SRC_DOMAIN] == ACL_LOOKUP_NEEDED) { checklist->state[ACL_SRC_DOMAIN] = ACL_LOOKUP_PENDING; fqdncache_nbgethostbyaddr(checklist->src_addr, - aclLookupSrcFQDNDone, checklist); return; + aclLookupSrcFQDNDone, + checklist); + return; } else if (checklist->state[ACL_DST_DOMAIN] == ACL_LOOKUP_NEEDED) { ia = ipcacheCheckNumeric(checklist->request->host); if (ia == NULL) { @@ -1815,7 +1798,9 @@ checklist->dst_addr = ia->in_addrs[0]; checklist->state[ACL_DST_DOMAIN] = ACL_LOOKUP_PENDING; fqdncache_nbgethostbyaddr(checklist->dst_addr, - aclLookupDstFQDNDone, checklist); return; + aclLookupDstFQDNDone, + checklist); + return; } else if (checklist->state[ACL_PROXY_AUTH] == ACL_LOOKUP_NEEDED) { debug(28, 3) @@ -1825,25 +1810,14 @@ return; } else if (checklist->state[ACL_PROXY_AUTH] == ACL_PROXY_AUTH_NEEDED) { - /* Special case. Client is required to resend the request - * with authentication. The request is denied. + /* Client is required to resend the request with correct authentication + * credentials. (This may be part of a stateful auth protocol. + * The request is denied. */ debug(28, 6) ("aclCheck: requiring Proxy Auth header.\n"); allow = ACCESS_REQ_PROXY_AUTH; match = -1; } -#if 0 - else if (checklist->state[ACL_PROXY_AUTH] == ACL_HELPER_START) { - /* we are using an external helper to do __everything__ in a STATEFUL fashion */ - debug(28, 3) ("aclCheck: handing Proxy Auth header to stateful authenticator\n"); - aclLookupProxyAuthStart(checklist); -#if OBSOLETE - aclLookupProxyAuthStatefulStart(checklist); -#endif - checklist->state[ACL_PROXY_AUTH] = ACL_HELPER_PENDING; - return; - } -#endif #if USE_IDENT else if (checklist->state[ACL_IDENT] == ACL_LOOKUP_NEEDED) { debug(28, 3) ("aclCheck: Doing ident lookup\n"); @@ -1873,11 +1847,9 @@ return; } checklist->access_list = A->next; -/* - - * Lock the next _acl_access entry - - */ + /* + * Lock the next _acl_access entry + */ if (A->next) cbdataLock(A->next); } @@ -1909,6 +1881,8 @@ cbdataUnlock(checklist->callback_data); checklist->callback = NULL; checklist->callback_data = NULL; + /* XXX: this assert is here to check for misbehaved acl authentication code. + * It can probably go sometime soon. */ assert(checklist->auth_user_request == NULL); aclChecklistFree(checklist); } @@ -1975,15 +1949,9 @@ auth_user_request_t *auth_user_request; checklist->state[ACL_PROXY_AUTH] = ACL_LOOKUP_DONE; if (result != NULL) - fatal("AclLookupProxyAuthDone: Old code floating around somewhere.\nMake clean and if that doesn't work, report a bug\n"); + fatal("AclLookupProxyAuthDone: Old code floating around somewhere.\nMake clean and if that doesn't work, report a bug to the squid developers.\n"); /* state info check */ assert(checklist->conn != NULL); -#if 0 - assert ((checklist->auth_user->auth_type == AUTH_NTLM) || - (checklist->auth_user->auth_type == AUTH_BASIC)); - if (checklist->auth_user->auth_type == AUTH_NTLM) - assert (checklist->conn->auth_user == checklist->auth_user); -#endif auth_user_request = checklist->auth_user_request; if (!authenticateValidateUser(auth_user_request)) { @@ -1993,38 +1961,12 @@ checklist->conn->auth_type = AUTH_BROKEN; checklist->auth_user_request = NULL; authenticateAuthUserRequestUnlock(auth_user_request); -#if 0 -/* This is handled automagically */ - authenticateFreeProxyAuthUser(auth_user); -#endif aclCheck(checklist); return; } -#if 0 - if (auth_user->flags.credentials_ok == 2) { - /* credentials check failed - user/password/challenge ... bad. */ - /* terminate the login process - * But if it was a connection oriented auth request - we know the attempted auth type so keep that. This can save - dropping the connection for request based authentication.*/ -#if 0 - checklist->conn->auth_user = NULL; - checklist->auth_user = NULL; - - authenticateAuthUserUnlock(auth_user); - - authenticateFreeProxyAuthUser(auth_user); -#endif - aclCheck(checklist); - return; - } -#endif aclCheck(checklist); } - - - #if 0 static void aclLookupProxyAuthDone(void *data, char *result) @@ -2039,90 +1981,12 @@ checklist->auth_user->flags.credentials_ok = 2; aclCheck(checklist); } - - -static void -aclLookupProxyNTLMAuthDone(void *data, char *result) -{ - aclCheck_t *checklist = data; - acl_proxy_auth_user *auth_user; - checklist->state[ACL_PROXY_AUTH] = ACL_LOOKUP_DONE; -#if 0 - debug(28, 4) ("aclLookupProxyStatefulAuthDone: result = %s\n", - result ? result : "NULL"); -#endif - if (result != NULL) - fatal("AclLookupProxyNTLMAuthDone: Old code floating around somewhere.\nMake clean and if that doesn't work, report a bug\n"); -/* check format */ -/* state info check */ - assert(checklist->conn != NULL); - assert (checklist->conn->auth_user != NULL); - assert (checklist->conn->auth_user->auth_type == AUTH_NTLM); - auth_user = checklist->conn->auth_user; - assert(checklist->conn->auth_type == AUTH_NTLM); - if (auth_user->flags.credentials_ok == 3) { - /* credentials could not be checked */ - /* restart the whole process */ - checklist->conn->auth_user = NULL; - checklist->conn->auth_type = AUTH_UNKNOWN; - checklist->auth_user = NULL; - authenticateAuthUserUnlock(auth_user); - authenticateFreeProxyAuthUser(auth_user); - aclCheck(checklist); - return; - } - -#if 0 - switch (auth_user->auth_data.ntlm_auth.auth_state) { - case AUTHENTICATE_STATE_NONE: - case AUTHENTICATE_STATE_CHALLENGE: - fatal - ("aclLookupProxyNTLMAuthDone: unexpected NTLM authentication state\n"); - break; - case AUTHENTICATE_STATE_DONE: - fatal("Old code present somewhere: report a bug!"); - break; - case AUTHENTICATE_STATE_NEGOTIATE: -#if 0 - auth_user->auth_data.ntlm_auth.authchallenge = - xstrndup(result, NTLM_CHALLENGE_SZ+5); - - if (result && (strncasecmp(result, "ERR", 3) == 0)) { - /* - * The helper rejected the negotiate. It automatically resets - */ - /* ERRS get trapped by authenticate. so we don't need to free the helper for other requests */ - checklist->conn->auth_type = AUTH_BROKEN; - auth_user->auth_data.ntlm_auth.auth_state = AUTHENTICATE_STATE_NONE; - debug(28, 1) ("aclLookupProxyNTLMAuthDone: bad NTLM negotiate request recieved on FD:%d.\n", - checklist->conn->fd); - } -#endif - break; - case AUTHENTICATE_STATE_RESPONSE: -#if 0 - if (result && (strncasecmp(result, "OK ", 3) == 0)) { - /* save the username */ - result += 3; - checklist->auth_user->auth_data.ntlm_auth.username = - xstrndup(result, MAX_LOGIN_SZ); - } else { - /* something botched.. restart */ - auth_user->auth_data.ntlm_auth.auth_state = AUTHENTICATE_STATE_NONE; - checklist->conn->auth_type = AUTH_BROKEN; - debug(28, 6) ("aclLookupProxyNTLMAuthDone: failed NTLM authentication on FD:%d error '%s'\n", - checklist->conn->fd, result); - } -#endif - break; - } -#endif - aclCheck(checklist); -} #endif aclCheck_t * -aclChecklistCreate(const acl_access * A, request_t * request, const char *ident) +aclChecklistCreate(const acl_access * A, + request_t * request, + const char *ident) { int i; aclCheck_t *checklist; @@ -2145,6 +2009,7 @@ if (ident) xstrncpy(checklist->rfc931, ident, USER_IDENT_SZ); #endif + checklist->auth_user_request = NULL; return checklist; } @@ -2158,6 +2023,11 @@ } + + + + + /*********************/ /* Destroy functions */ /*********************/ @@ -2291,6 +2161,7 @@ acl_deny_info_list *a_next = NULL; acl_name_list *l = NULL; acl_name_list *l_next = NULL; + for (a = *list; a; a = a_next) { for (l = a->acl_list; l; l = l_next) { l_next = l->next; @@ -2335,37 +2206,8 @@ } if (ret == 0) { debug(28, 0) ("WARNING: '%s' is a subdomain of '%s'\n", d1, d2); - debug(28, 0) - - - - - - - - - - - - - - ("WARNING: because of this '%s' is ignored to keep splay tree searching predictable\n", - a); debug(28, 0) - - - - - - - - - - - - - - ("WARNING: You should probably remove '%s' from the ACL named '%s'\n", - d1, AclMatchedName); + debug(28, 0) ("WARNING: because of this '%s' is ignored to keep splay tree searching predictable\n", a); + debug(28, 0) ("WARNING: You should probably remove '%s' from the ACL named '%s'\n", d1, AclMatchedName); } return ret; }