This is the patch (indent 1.9.1) and apply to squid-2.5 CVS. 

  Changes: 
          -support for bogus clients in authentication, forcing the use
          of some scheme for some clients with acls. 
          -authenticateAuthSchemeConfigure() renamed to 
             authenticateAuthSchemeActive(). 
          -New authenticateAuthSchemeConfigure() function. 

authentication example:
acl basic_auth proxy_auth -b REQUIRED
acl ntlm_auth proxy_auth -n REQUIRED
acl ip1 src 10.10.10.10
acl ip2 src 10.10.10.11
http_access allow ip1 basic_auth
http_access allow ip2 ntlm_auth
..then the basic auth is offered to ip1 and ntlm if offered to ip2
(in authenticateFixHeader()).

Please check this and apply if it is OK or tell me how can I do this better, i thinks 
that it is necessary. 

Thanks! 


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;
 };
 

Reply via email to