Index: include/splay.h =================================================================== RCS file: /cvsroot/squid/squid/include/splay.h,v retrieving revision 1.1.1.5 diff -u -r1.1.1.5 splay.h --- include/splay.h 2000/04/20 21:57:34 1.1.1.5 +++ include/splay.h 2000/10/17 09:15:33 @@ -2,6 +2,8 @@ * $Id: splay.h,v 1.1.1.5 2000/04/20 21:57:34 hno Exp $ */ +#ifndef _SPLAY_H +#define _SPLAY_H typedef struct _splay_node { void *data; @@ -19,3 +21,5 @@ extern splayNode *splay_splay(const void *, splayNode *, SPLAYCMP *); extern void splay_destroy(splayNode *, SPLAYFREE *); extern void splay_walk(splayNode *, SPLAYWALKEE *, void *); + +#endif /* _SPLAY_H */ Index: src/acl.c =================================================================== RCS file: /cvsroot/squid/squid/src/acl.c,v retrieving revision 1.1.1.6 diff -u -r1.1.1.6 acl.c --- src/acl.c 2000/04/20 21:57:34 1.1.1.6 +++ src/acl.c 2000/10/17 09:15:34 @@ -41,6 +41,7 @@ static hash_table *proxy_auth_cache = NULL; static void aclParseDomainList(void *curlist); +static void aclParseProxyAuthList(void **current); static void aclParseIpList(void *curlist); static void aclParseIntlist(void *curlist); static void aclParseWordList(void *curlist); @@ -57,7 +58,7 @@ static int aclMatchAcl(struct _acl *, aclCheck_t *); static int aclMatchIntegerRange(intrange * data, int i); static int aclMatchTime(acl_time_data * data, time_t when); -static int aclMatchUser(wordlist * data, const char *ident); +static int aclMatchUser(void *proxyauth_acl, char *user); static int aclMatchIp(void *dataptr, struct in_addr c); static int aclMatchDomainList(void *dataptr, const char *); static int aclMatchIntegerRange(intrange * data, int i); @@ -618,6 +619,45 @@ wordlistAdd(curlist, t); } +static void +aclParseProxyAuthList(void ** current) +{ + char *t=NULL; + acl_proxy_auth_data **data=(acl_proxy_auth_data **)current; + splayNode *Top=NULL; + int case_insensitive; + + debug(28,2) ("aclParseProxyAuthList: parsing authlist\n"); + if (*data==NULL) { + debug(28,3)("aclParseProxyAuthList: current is null. Creating\n"); + *data=memAllocate(MEM_ACL_PROXY_AUTH_DATA); /*we rely on mA. zeroing*/ + } + + if ((t = strtokFile())) { + debug(28,5)("aclParseProxyAuthList: First token is %s\n",t); + if (!strcmp("-i",t)) { + debug(28,5)("aclParseProxyAuthList: Going case-insensitive\n"); + (*data)->flags|=PROXY_AUTH_IS_CASE_INSENSITIVE; + } + else + Top=splay_insert(xstrdup(t), Top, (SPLAYCMP *)strcmp); + } + + case_insensitive=(*data)->flags & PROXY_AUTH_IS_CASE_INSENSITIVE; + debug(28,3)("aclParseProxyAuthList: Case-insensitive-switch is %d\n", + case_insensitive); + /* we might inherit from a previous declaration */ + + debug(28,4) ("aclParseProxyAuthList: parsing proxy-auth list\n"); + while ((t = strtokFile())) { + debug(28,6)("aclParseProxyAuthList: Got token: %s\n",t); + if (case_insensitive) Tolower(t); + Top=splay_insert(xstrdup(t), Top, (SPLAYCMP *)strcmp); + } + (*data)->names=Top; +} + + /**********************/ /* aclParseDomainList */ /**********************/ @@ -726,7 +766,7 @@ aclParseMethodList(&A->data); break; case ACL_PROXY_AUTH: - aclParseWordList(&A->data); + aclParseProxyAuthList(&A->data); if (!proxy_auth_cache) { /* First time around, 7921 should be big enough */ proxy_auth_cache = hash_create((HASHCMP *) strcmp, 7921, hash_string); @@ -980,20 +1020,29 @@ } static int -aclMatchUser(wordlist * data, const char *user) +aclMatchUser(void * proxyauth_acl, char *user) { - if (user == NULL) - return 0; - debug(28, 3) ("aclMatchUser: checking '%s'\n", user); - while (data) { - debug(28, 3) ("aclMatchUser: looking for '%s'\n", data->key); - if (strcmp(data->key, "REQUIRED") == 0 && *user != '\0' && strcmp(user, "-") != 0) - return 1; - if (strcmp(data->key, user) == 0) - return 1; - data = data->next; - } - return 0; + acl_proxy_auth_data *data=(acl_proxy_auth_data *)proxyauth_acl; + splayNode *Top=data->names; + int case_insensitive=((data->flags&PROXY_AUTH_IS_CASE_INSENSITIVE) != 0); + + debug(28,7)("aclMatchUser: user is %s, case_insensitive is %d\n", + user,case_insensitive); + debug(28,8)("Top is %p, Top->data is %s\n",Top, + (Top!=NULL?(Top)->data:"Unavailable")); + + if (user==NULL) + return 0; + if (case_insensitive) + Tolower(user); + + Top=splay_splay(user,Top,(SPLAYCMP *)strcmp); + /* Top=splay_splay(user,Top,(SPLAYCMP *)dumping_strcmp); */ + debug(28,7)("aclMatchUser: returning %d,Top is %p, Top->data is %s\n", + !splayLastResult, + Top, (Top?Top->data:"Unavailable")); + data->names=Top; + return !splayLastResult; } static int @@ -1809,6 +1858,13 @@ memFree(p, MEM_ACL_IP_DATA); } +static void aclFreeProxyAuthData(void *data) { + acl_proxy_auth_data *d=data; + splay_destroy(d->names,xfree); + memFree(d,MEM_ACL_PROXY_AUTH_DATA); +} + + void aclDestroyAcls(acl ** head) { @@ -1830,12 +1886,16 @@ break; #if SQUID_SNMP case ACL_SNMP_COMMUNITY: + wordlistDestroy((wordlist **) & a->data); + break; #endif #if USE_IDENT case ACL_IDENT: + wordlistDestroy((wordlist **) & a->data); + break; #endif case ACL_PROXY_AUTH: - wordlistDestroy((wordlist **) & a->data); + aclFreeProxyAuthData(a->data); break; case ACL_TIME: aclDestroyTimeList(a->data); @@ -2022,6 +2082,25 @@ } static void +aclDumpProxyAuthListWalkee(void *node_data, void * outlist) { + /* outlist is really a wordlist ** */ + wordlistAdd(outlist,node_data); +} + +wordlist * +aclDumpProxyAuthList (acl_proxy_auth_data * data) { + wordlist *wl = NULL; + if ((data->flags&PROXY_AUTH_IS_CASE_INSENSITIVE) != 0) + wordlistAdd(&wl,"-i"); + /* damn this is VERY inefficient for long ACL lists... filling + a wordlist this way costs Sum(1,N) iterations. For instance + a 1000-elements list woll be filled in 499500 iterations. + */ + splay_walk(data->names,aclDumpProxyAuthListWalkee,&wl); + return wl; +} + +static void aclDumpIpListWalkee(void *node, void *state) { acl_ip_data *ip = node; @@ -2162,13 +2241,17 @@ break; #if SQUID_SNMP case ACL_SNMP_COMMUNITY: + return wordlistDup(a->data); + break; #endif #if USE_IDENT case ACL_IDENT: + return wordlistDup(a->data); + break; #endif case ACL_PROXY_AUTH: - return wordlistDup(a->data); - break; + return aclDumpProxyAuthList(a->data); + break; case ACL_TIME: return aclDumpTimeSpecList(a->data); break; Index: src/enums.h =================================================================== RCS file: /cvsroot/squid/squid/src/enums.h,v retrieving revision 1.1.1.6 diff -u -r1.1.1.6 enums.h --- src/enums.h 2000/04/20 21:57:34 1.1.1.6 +++ src/enums.h 2000/10/17 09:15:34 @@ -498,6 +498,7 @@ MEM_ACL_IP_DATA, MEM_ACL_LIST, MEM_ACL_NAME_LIST, + MEM_ACL_PROXY_AUTH_DATA, MEM_ACL_PROXY_AUTH_USER, MEM_ACL_TIME_DATA, MEM_AIO_RESULT_T, Index: src/mem.c =================================================================== RCS file: /cvsroot/squid/squid/src/mem.c,v retrieving revision 1.1.1.5 diff -u -r1.1.1.5 mem.c --- src/mem.c 2000/04/20 21:57:34 1.1.1.5 +++ src/mem.c 2000/10/17 09:15:34 @@ -201,6 +201,8 @@ memDataInit(MEM_ACL_LIST, "acl_list", sizeof(acl_list), 0); memDataInit(MEM_ACL_NAME_LIST, "acl_name_list", sizeof(acl_name_list), 0); memDataInit(MEM_ACL_TIME_DATA, "acl_time_data", sizeof(acl_time_data), 0); + memDataInit(MEM_ACL_PROXY_AUTH_DATA, "acl_proxy_auth_data", + sizeof(acl_proxy_auth_data), 0); memDataInit(MEM_ACL_PROXY_AUTH_USER, "acl_proxy_auth_user", sizeof(acl_proxy_auth_user), 0); memDataInit(MEM_AIO_RESULT_T, "aio_result_t", sizeof(aio_result_t), 0); Index: src/structs.h =================================================================== RCS file: /cvsroot/squid/squid/src/structs.h,v retrieving revision 1.1.1.6 diff -u -r1.1.1.6 structs.h --- src/structs.h 2000/04/20 21:57:35 1.1.1.6 +++ src/structs.h 2000/10/17 09:15:34 @@ -31,6 +31,9 @@ * */ +#include "config.h" +#include "splay.h" + struct _dlink_node { void *data; dlink_node *prev; @@ -41,6 +44,15 @@ dlink_node *head; dlink_node *tail; }; + +#define PROXY_AUTH_IS_CASE_INSENSITIVE 0x1 +/* FIXME: not yet imlemented */ +#define PROXY_AUTH_IS_REQUIRED 0x2 +struct _acl_proxy_auth_data { + u_num32 flags; + splayNode *names; +}; + struct _acl_ip_data { struct in_addr addr1; /* if addr2 non-zero then its a range */ Index: src/typedefs.h =================================================================== RCS file: /cvsroot/squid/squid/src/typedefs.h,v retrieving revision 1.1.1.6 diff -u -r1.1.1.6 typedefs.h --- src/typedefs.h 2000/04/20 21:57:35 1.1.1.6 +++ src/typedefs.h 2000/10/17 09:15:35 @@ -61,6 +61,7 @@ typedef struct _acl_name_list acl_name_list; typedef struct _acl_deny_info_list acl_deny_info_list; typedef struct _acl_proxy_auth acl_proxy_auth; +typedef struct _acl_proxy_auth_data acl_proxy_auth_data; typedef struct _acl_proxy_auth_user acl_proxy_auth_user; typedef struct _acl_arp_data acl_arp_data; typedef struct _acl acl;