On Sat, Sep 06, 2003 at 07:38:00AM +1000, Robert Collins wrote: > On Sat, 2003-09-06 at 01:18, Diego Woitasen wrote: > > This patch add 3 switch to acl proxy_auth to force a authentication > > scheme to bogus clients, like IE and Messenger (see squid.conf help). > > > > Please somebody can check this and send me your opinion. > > Please run > indent -br -ce -i4 -ci4 -l80 -nlp -npcs -npsl -d0 -sc -di0 -psl > > over your modified files to remove whitespace changes, and then > regenerate the patch. > > Thank you, > Rob > > -- > GPG key available at: <http://members.aardvark.net.au/lifeless/keys.txt>.
ups! sorry. This is the right patch (indent 1.9.1) and apply to squid-2.5 CVS. Changes: -support for bogus clients in authentication. -authenticateAuthSchemeConfigure() renamed to authenticateAuthSchemeActive(). -New authenticateAuthSchemeConfigure() function. Please check this and apply if it is OK or tell me how can I do this better... Thanks! Diego Woitasen LUGAR - Linux Users Group Argentina diff -Nru squid-2.5/src/acl.c squid-2.5-ws/src/acl.c --- squid-2.5/src/acl.c Mon May 12 04:24:37 2003 +++ squid-2.5-ws/src/acl.c Sun Sep 7 13:37:50 2003 @@ -628,11 +628,33 @@ } data = *current; Top = data->names; - if ((t = strtokFile())) { - debug(28, 5) ("aclParseUserList: First token is %s\n", t); + data->flags.schemeid = -1; + while ((t = strtokFile())) { + debug(28, 5) ("aclParseUserList: token is %s\n", t); if (strcmp("-i", t) == 0) { debug(28, 5) ("aclParseUserList: Going case-insensitive\n"); data->flags.case_insensitive = 1; + } else if (strcmp("-b", t) == 0) { + if (!authenticateAuthSchemeConfigured("basic")) { + debug(28, 5) ("aclParseUserList: -b switch ignored, basic auth not configured\n"); + continue; + } + debug(28, 5) ("aclParseUserList: using basic auth\n"); + data->flags.schemeid = authenticateAuthSchemeId("basic"); + } else if (strcmp("-n", t) == 0) { + if (!authenticateAuthSchemeConfigured("ntlm")) { + debug(28, 5) ("aclParseUserList: -n switch ignored, ntlm auth not configured\n"); + continue; + } + debug(28, 5) ("aclParseUserList: using ntlm auth\n"); + data->flags.schemeid = authenticateAuthSchemeId("ntlm"); + } else if (strcmp("-d", t) == 0) { + if (!authenticateAuthSchemeConfigured("digest")) { + debug(28, 5) ("aclParseUserList: -d switch ignored, digest auth not configured\n"); + continue; + } + debug(28, 5) ("aclParseUserList: using digest auth\n"); + data->flags.schemeid = authenticateAuthSchemeId("digest"); } else if (strcmp("REQUIRED", t) == 0) { debug(28, 5) ("aclParseUserList: REQUIRED-type enabled\n"); data->flags.required = 1; @@ -644,15 +666,9 @@ } debug(28, 3) ("aclParseUserList: Case-insensitive-switch is %d\n", data->flags.case_insensitive); - /* we might inherit from a previous declaration */ - - debug(28, 4) ("aclParseUserList: parsing user list\n"); - while ((t = strtokFile())) { - debug(28, 6) ("aclParseUserList: Got token: %s\n", t); - if (data->flags.case_insensitive) - Tolower(t); - Top = splay_insert(xstrdup(t), Top, (SPLAYCMP *) strcmp); - } + debug(28, 3) ("aclParseUserList: scheme ID is %d\n", data->flags.schemeid); + /* we might inherit from a previous declaration, (?, [EMAIL PROTECTED]) */ + debug(28, 4) ("aclParseUserList: user list parsed \n"); data->names = Top; } @@ -1695,6 +1711,7 @@ int answer; checklist->current_acl = list->acl; AclMatchedName = list->acl->name; + AclMatched = list->acl; debug(28, 3) ("aclMatchAclList: checking %s%s\n", list->op ? null_string : "!", list->acl->name); answer = aclMatchAcl(list->acl, checklist); diff -Nru squid-2.5/src/authenticate.c squid-2.5-ws/src/authenticate.c --- squid-2.5/src/authenticate.c Sun May 18 18:49:19 2003 +++ squid-2.5-ws/src/authenticate.c Sun Sep 7 18:53:25 2003 @@ -56,9 +56,8 @@ /* Generic Functions */ - static int -authenticateAuthSchemeConfigured(const char *proxy_auth) +authenticateAuthSchemeActive(const char *proxy_auth) { authScheme *scheme; int i; @@ -71,6 +70,7 @@ return 0; } + int authenticateAuthSchemeId(const char *typestr) { @@ -90,7 +90,7 @@ assert(proxy_auth != NULL); assert(auth_user_request != NULL); /* we need this created for us. */ debug(29, 9) ("authenticateDecodeAuth: header = '%s'\n", proxy_auth); - if (authenticateAuthSchemeConfigured(proxy_auth)) { + if (authenticateAuthSchemeActive(proxy_auth)) { /* we're configured to use this scheme - but is it active ? */ if ((i = authenticateAuthSchemeId(proxy_auth)) != -1) { authscheme_list[i].decodeauth(auth_user_request, proxy_auth); @@ -733,14 +733,26 @@ else { int i; authScheme *scheme; - /* call each configured & running authscheme */ - for (i = 0; i < Config.authConfig.n_configured; i++) { - scheme = Config.authConfig.schemes + i; - if (authscheme_list[scheme->Id].Active()) - authscheme_list[scheme->Id].authFixHeader(NULL, rep, type, - request); + acl_user_data *user_data; + + user_data = AclMatched->data; + if ((AclMatched->type == ACL_PROXY_AUTH || AclMatched->type == ACL_PROXY_AUTH) && + user_data->flags.schemeid >= 0) { + if (authscheme_list[user_data->flags.schemeid].Active()) + authscheme_list[user_data->flags.schemeid].authFixHeader(NULL, + rep, type, request); else - debug(29, 4) ("authenticateFixHeader: Configured scheme %s not Active\n", scheme->typestr); + debug(29, 4) ("authenticateFixHeader: Configured scheme %d not Active\n", user_data->flags.schemeid); + } else { + /* call each configured & running authscheme */ + for (i = 0; i < Config.authConfig.n_configured; i++) { + scheme = Config.authConfig.schemes + i; + if (authscheme_list[scheme->Id].Active()) + authscheme_list[scheme->Id].authFixHeader(NULL, rep, type, + request); + else + debug(29, 4) ("authenticateFixHeader: Configured scheme %s not Active\n", scheme->typestr); + } } } } @@ -754,7 +766,6 @@ if (auth_user_request != NULL) auth_user_request->lastReply = AUTH_ACL_CANNOT_AUTHENTICATE; } - /* call the active auth module and allow it to add a trailer to the request */ void authenticateAddTrailer(HttpReply * rep, auth_user_request_t * auth_user_request, request_t * request, int accelerated) @@ -763,7 +774,6 @@ && (authscheme_list[auth_user_request->auth_user->auth_module - 1].AddTrailer)) authscheme_list[auth_user_request->auth_user->auth_module - 1].AddTrailer(auth_user_request, rep, accelerated); } - void authenticateAuthUserLock(auth_user_t * auth_user) { @@ -771,9 +781,8 @@ assert(auth_user != NULL); auth_user->references++; debug(29, 9) ("authenticateAuthUserLock auth_user '%p' now at '%ld'.\n", auth_user, (long int) auth_user->references); -} +} void -void authenticateAuthUserUnlock(auth_user_t * auth_user) { debug(29, 9) ("authenticateAuthUserUnlock auth_user '%p'.\n", auth_user); @@ -795,9 +804,8 @@ assert(auth_user_request != NULL); auth_user_request->references++; debug(29, 9) ("authenticateAuthUserRequestLock auth_user request '%p' now at '%ld'.\n", auth_user_request, (long int) auth_user_request->references); -} +} void -void authenticateAuthUserRequestUnlock(auth_user_request_t * auth_user_request) { debug(29, 9) ("authenticateAuthUserRequestUnlock auth_user request '%p'.\n", auth_user_request); @@ -820,15 +828,13 @@ { assert(auth_user != NULL); return auth_user->references; -} - -/* - * Combine two user structs. ONLY to be called from within a scheme - * module. The scheme module is responsible for ensuring that the - * two users _can_ be merged without invalidating all the request - * scheme data. the scheme is also responsible for merging any user - * related scheme data itself. - */ +} /* + * Combine two user structs. ONLY to be called from within a scheme + * module. The scheme module is responsible for ensuring that the + * two users _can_ be merged without invalidating all the request + * scheme data. the scheme is also responsible for merging any user + * related scheme data itself. + */ void authenticateAuthUserMerge(auth_user_t * from, auth_user_t * to) { @@ -873,8 +879,7 @@ * structure */ memFree(u->usernamehash, MEM_AUTH_USER_HASH); } - /* remove any outstanding requests */ - link = u->requests.head; + /* remove any outstanding requests */ link = u->requests.head; while (link) { debug(29, 5) ("authenticateFreeProxyAuthUser: removing request entry '%p'\n", link->data); auth_user_request = link->data; @@ -906,7 +911,6 @@ eventAdd("User Cache Maintenance", authenticateProxyUserCacheCleanup, NULL, Config.authenticateGCInterval, 1); } } - void authenticateProxyUserCacheCleanup(void *datanotused) { @@ -960,12 +964,9 @@ debug(29, 5) ("authenticateUserCacheRestat: Clearing cache ACL results for user: %s\n", username); aclCacheMatchFlush(&auth_user->proxy_match_cache); } - -} - -/* - * called to add another auth scheme module - */ +} /* + * called to add another auth scheme module + */ void authSchemeAdd(const char *type, AUTHSSETUP * setup) { @@ -974,8 +975,7 @@ /* find the number of currently known authscheme types */ for (i = 0; authscheme_list && authscheme_list[i].typestr; i++) { assert(strcmp(authscheme_list[i].typestr, type) != 0); - } - /* add the new type */ + } /* add the new type */ authscheme_list = xrealloc(authscheme_list, (i + 2) * sizeof(authscheme_entry_t)); memset(&authscheme_list[i], 0, sizeof(authscheme_entry_t)); memset(&authscheme_list[i + 1], 0, sizeof(authscheme_entry_t)); @@ -998,4 +998,16 @@ auth_user->usernamehash = usernamehash; /* lock for presence in the cache */ authenticateAuthUserLock(auth_user); +} int +authenticateAuthSchemeConfigured(const char *proxy_auth) +{ + authScheme *scheme; + int i; + for (i = 0; i < Config.authConfig.n_configured; i++) { + scheme = Config.authConfig.schemes + i; + if ((strncasecmp(proxy_auth, scheme->typestr, strlen(scheme->typestr)) == 0) && + (authscheme_list[scheme->Id].configured())) + return 1; + } + return 0; } diff -Nru squid-2.5/src/cf.data.pre squid-2.5-ws/src/cf.data.pre --- squid-2.5/src/cf.data.pre Tue Sep 2 04:49:32 2003 +++ squid-2.5-ws/src/cf.data.pre Sat Sep 6 23:39:51 2003 @@ -1971,10 +1971,14 @@ # cache_peer_access mycache.mydomain.net allow asexample # cache_peer_access mycache_mydomain.net deny all - acl aclname proxy_auth username ... + acl aclname proxy_auth [-i] [-b | -n | -d ] username ... acl aclname proxy_auth_regex [-i] pattern ... # list of valid usernames # use REQUIRED to accept any valid username. + # -i: case-insensitive + # -b: use basic authentication + # -n: use NTLM authentication + # -d: use digest authentication # # NOTE: when a Proxy-Authentication header is sent but it is not # needed during ACL checking the username is NOT logged @@ -1983,6 +1987,9 @@ # NOTE: proxy_auth requires a EXTERNAL authentication program # to check username/password combinations (see # auth_param directive). + # + # NOTE: If -b, -n or -d is not especified, the three schemes are + # offered to the client. # # WARNING: proxy_auth can't be used in a transparent proxy. It # collides with any authentication done by origin servers. It may diff -Nru squid-2.5/src/globals.h squid-2.5-ws/src/globals.h --- squid-2.5/src/globals.h Mon Jan 13 20:01:13 2003 +++ squid-2.5-ws/src/globals.h Sat Sep 6 23:30:09 2003 @@ -47,6 +47,7 @@ extern char ThisCache2[SQUIDHOSTNAMELEN << 1]; extern char config_input_line[BUFSIZ]; extern const char *AclMatchedName; /* NULL */ +extern acl *AclMatched; /* NULL */ extern const char *DefaultConfigFile; /* DEFAULT_CONFIG_FILE */ extern const char *RequestMethodStr[]; extern const char *ProtocolStr[]; diff -Nru squid-2.5/src/protos.h squid-2.5-ws/src/protos.h --- squid-2.5/src/protos.h Sun Aug 10 18:04:47 2003 +++ squid-2.5-ws/src/protos.h Sun Sep 7 00:47:45 2003 @@ -739,6 +739,7 @@ extern void authSchemeSetup(void); /* authenticate.c */ +extern int authenticateAuthSchemeConfigured(const char *proxy_auth); extern void authenticateAuthUserMerge(auth_user_t *, auth_user_t *); extern auth_user_t *authenticateAuthUserNew(const char *); extern int authenticateAuthSchemeId(const char *typestr); diff -Nru squid-2.5/src/structs.h squid-2.5-ws/src/structs.h --- squid-2.5/src/structs.h Wed Aug 6 10:49:03 2003 +++ squid-2.5-ws/src/structs.h Sun Sep 7 18:52:55 2003 @@ -53,6 +53,7 @@ struct { unsigned int case_insensitive:1; unsigned int required:1; + short int schemeid; } flags; };