---------------------
PatchSet 1026 
Date: 2001/01/01 09:51:18
Author: rbcollins
Branch: auth_rewrite
Tag: (none) 
Log:
modularised per scheme config file entries. Allows a single cf.data.pre to
cover all compiled auth_scheme - step towards late binding of schemes

Members: 
	src/acl.c:1.1.1.3.12.26.2.10->1.1.1.3.12.26.2.11 
	src/authenticate.c:1.1.1.3.12.17.2.14->1.1.1.3.12.17.2.15 
	src/cache_cf.c:1.1.1.3.4.1.2.9.2.4->1.1.1.3.4.1.2.9.2.5 
	src/cf.data.pre:1.1.1.3.4.1.2.18.2.7->1.1.1.3.4.1.2.18.2.8 
	src/main.c:1.1.1.3.4.1.2.12.2.1->1.1.1.3.4.1.2.12.2.2 
	src/protos.h:1.1.1.3.12.17.2.10->1.1.1.3.12.17.2.11 
	src/structs.h:1.1.1.3.4.1.2.26.2.14->1.1.1.3.4.1.2.26.2.15 
	src/typedefs.h:1.1.1.3.12.13.2.10->1.1.1.3.12.13.2.11 
	src/auth/basic/auth_basic.c:1.1.2.9->1.1.2.10 
	src/auth/basic/auth_basic.h:1.1.2.1->1.1.2.2 

Index: squid/src/acl.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/acl.c,v
retrieving revision 1.1.1.3.12.26.2.10
retrieving revision 1.1.1.3.12.26.2.11
diff -u -r1.1.1.3.12.26.2.10 -r1.1.1.3.12.26.2.11
--- squid/src/acl.c	31 Dec 2000 15:10:38 -0000	1.1.1.3.12.26.2.10
+++ squid/src/acl.c	1 Jan 2001 09:51:18 -0000	1.1.1.3.12.26.2.11
@@ -1,6 +1,6 @@
 
 /*
- * $Id: acl.c,v 1.1.1.3.12.26.2.10 2000/12/31 15:10:38 rbcollins Exp $
+ * $Id: acl.c,v 1.1.1.3.12.26.2.11 2001/01/01 09:51:18 rbcollins Exp $
  *
  * DEBUG: section 28    Access Control
  * AUTHOR: Duane Wessels
@@ -791,15 +791,14 @@
 	aclParseMethodList(&A->data);
 	break;
     case ACL_PROXY_AUTH:
-
+#if 0
         if ((Config.Program.authenticate==NULL) && 
                (Config.Program.ntlmauthenticate==NULL)){
-#if 0
+#endif
         if (authenticateSchemeCount()==0) {
             debug(28,0) ("aclParseAclLine: IGNORING: Proxy Auth ACL '%s' \
 because no authentication schemes were compiled.\n",A->cfgline);
         } else if (authenticateActiveSchemeCount()==0) {
-#endif
             debug(28,0) ("aclParseAclLine: IGNORING: Proxy Auth ACL '%s' \
 because no authentication helper(s) are defined.\n",A->cfgline);
         } else {
Index: squid/src/authenticate.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/authenticate.c,v
retrieving revision 1.1.1.3.12.17.2.14
retrieving revision 1.1.1.3.12.17.2.15
diff -u -r1.1.1.3.12.17.2.14 -r1.1.1.3.12.17.2.15
--- squid/src/authenticate.c	1 Jan 2001 01:55:41 -0000	1.1.1.3.12.17.2.14
+++ squid/src/authenticate.c	1 Jan 2001 09:51:21 -0000	1.1.1.3.12.17.2.15
@@ -1,6 +1,6 @@
 
 /*
- * $Id: authenticate.c,v 1.1.1.3.12.17.2.14 2001/01/01 01:55:41 rbcollins Exp $
+ * $Id: authenticate.c,v 1.1.1.3.12.17.2.15 2001/01/01 09:51:21 rbcollins Exp $
  *
  * DEBUG: section 29    Authenticator
  * AUTHOR: Duane Wessels
@@ -40,14 +40,6 @@
 
 #include "squid.h"
 
-/* private data types */
-struct _authscheme_order_entry {
-    char *typestr;
-    int Id;
-};
-typedef struct _authscheme_order_entry authscheme_order_entry;
-
-authscheme_order_entry *authscheme_order_list;
 
 static void
 authenticateDecodeAuth(const char *proxy_auth, auth_user_t * auth_user);
@@ -62,12 +54,15 @@
 
 
 int
-authenticateAuthSchemeConfigured(wordlist *w, const char *proxy_auth){
-    while (w != NULL)
+authenticateAuthSchemeConfigured(const char *proxy_auth)
+{
+    authScheme *scheme;
+    int i;
+    for (i = 0; i < Config.authConfig.n_configured; i++)
     {
-        if (strncasecmp(proxy_auth, w->key, strlen(w->key))==0)
+        scheme=Config.authConfig.schemes+i;
+        if (strncasecmp(proxy_auth, scheme->typestr, strlen(scheme->typestr))==0)
             return 1;
-        w = w->next;
     }
     return 0;
 }
@@ -97,7 +92,7 @@
     assert(proxy_auth != NULL);
     assert(auth_user != NULL);  /* we need this created for us. */
     debug(29, 6) ("authenticateDecodeAuth: header = '%s'\n", proxy_auth);
-    if (authenticateAuthSchemeConfigured(Config.authenticate_scheme_order, proxy_auth))
+    if (authenticateAuthSchemeConfigured(proxy_auth))
     {
         /* we're configured to use this scheme - but is it active ? */
         if ((i=authenticateAuthSchemeId(proxy_auth))!=-1)
@@ -283,46 +278,25 @@
     return rv;
 }
 
-/*
- * Called after configuration and setup of auth schemes,
- * this routine creates the associative array of scheme type
- * to compiletime load order
- */
-void 
-authenticateCreateSchemeOrder(void)
+void
+authenticateSchemeInit(void)
 {
-    int i,j=0;
-    wordlist *w=Config.authenticate_scheme_order;
-    /* find the number of currently known authscheme types that are in the configure
-       order */
-    for (i = 0; authscheme_list && authscheme_list[i].typestr; i++) {
-        if (authenticateAuthSchemeConfigured(w, authscheme_list[i].typestr))
-            j++;
-    }
-    /* initialise the array */
-    authscheme_order_list = xrealloc(authscheme_order_list, (j+1) * sizeof(authscheme_order_entry));
-    /* zero the terminating entry */
-    authscheme_order_list[j].Id=-1;
-    authscheme_order_list[j].typestr=NULL;
-    /* walk the configure list, for each scheme add to the array */
-    i=0;
-    while (w != NULL)
-    {
-        if ((j=authenticateAuthSchemeId(w->key))!=-1)
-        {
-            authscheme_order_list[i].Id=j;
-            authscheme_order_list[i].typestr=authscheme_list[j].typestr;
-            i++;
-        }
-        w = w->next;
-    }
+    authSchemeSetup();
 }
 
 void
-authenticateInit(void)
+authenticateInit(authConfig *config)
 {
-    authSchemeSetup();
-    authenticateCreateSchemeOrder();
+    int i;
+    authScheme *scheme;
+    for (i = 0; i < config->n_configured; i++)
+    {
+        if (authscheme_list[i].init)
+        {
+            scheme=config->schemes+i;
+            authscheme_list[i].init(scheme);
+        }
+    } 
     if (!proxy_auth_username_cache)
         authenticateInitUserCache();
 }
@@ -372,12 +346,16 @@
         authscheme_list[auth_user->auth_module-1].authFixHeader(auth_user, rep, type, err->request);
     else {
         int i;
+        authScheme *scheme;
         /* call each configured authscheme */
-        for (i = 0; authscheme_order_list && authscheme_order_list[i].typestr; i++) {
-            if (authscheme_list[authscheme_order_list[i].Id].Active())
-                authscheme_list[authscheme_order_list[i].Id].authFixHeader(auth_user,rep, type, err->request);
+        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(auth_user,rep,type, 
+                    err->request);
             else
-                debug(29,8)("authenticateFixHeader: Compiled scheme %s not Active\n",authscheme_list[authscheme_order_list[i].Id].typestr);
+                debug(29,8)("authenticateFixHeader: Configured scheme %s not Active\n",scheme->typestr);
         }
     }
 }
Index: squid/src/cache_cf.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/cache_cf.c,v
retrieving revision 1.1.1.3.4.1.2.9.2.4
retrieving revision 1.1.1.3.4.1.2.9.2.5
diff -u -r1.1.1.3.4.1.2.9.2.4 -r1.1.1.3.4.1.2.9.2.5
--- squid/src/cache_cf.c	13 Dec 2000 01:23:30 -0000	1.1.1.3.4.1.2.9.2.4
+++ squid/src/cache_cf.c	1 Jan 2001 09:51:21 -0000	1.1.1.3.4.1.2.9.2.5
@@ -1,6 +1,6 @@
 
 /*
- * $Id: cache_cf.c,v 1.1.1.3.4.1.2.9.2.4 2000/12/13 01:23:30 rbcollins Exp $
+ * $Id: cache_cf.c,v 1.1.1.3.4.1.2.9.2.5 2001/01/01 09:51:21 rbcollins Exp $
  *
  * DEBUG: section 3     Configuration File Parsing
  * AUTHOR: Harvest Derived
@@ -308,6 +308,7 @@
 	    Config.ntlmauthenticateChildren = DefaultAuthenticateChildrenMax;
 	}
     }
+#if 0
     if (Config.Program.authenticate) {
 	if (Config.authenticateChildren < 1) {
 	    Config.authenticateChildren = 0;
@@ -319,6 +320,7 @@
 	    Config.authenticateChildren = DefaultAuthenticateChildrenMax;
 	}
     }
+#endif
     if (Config.Accel.host) {
 	snprintf(buf, BUFSIZ, "http://%s:%d", Config.Accel.host, Config.Accel.port);
 	Config2.Accel.prefix = xstrdup(buf);
@@ -376,8 +378,10 @@
 	requirePathnameExists("redirect_program", Config.Program.redirect->key);
     if (Config.Program.ntlmauthenticate)
 	requirePathnameExists("authenticate_program_ntlm", Config.Program.ntlmauthenticate->key);
+#if 0
     if (Config.Program.authenticate)
 	requirePathnameExists("authenticate_program", Config.Program.authenticate->key);
+#endif
     requirePathnameExists("Icon Directory", Config.icons.directory);
     requirePathnameExists("Error Directory", Config.errorDirectory);
 #if HTTP_VIOLATIONS
@@ -898,6 +902,94 @@
     return (-1);
 }
 
+
+/* this will need to be moved later */
+
+void
+allocate_new_authScheme(authConfig * cfg)
+{
+    if (cfg->schemes == NULL) {
+        cfg->n_allocated = 4;
+        cfg->schemes = xcalloc(cfg->n_allocated, sizeof(authScheme));
+    }
+    if (cfg->n_allocated == cfg->n_configured) {
+        authScheme *tmp;
+        cfg->n_allocated <<= 1;
+        tmp = xcalloc(cfg->n_allocated, sizeof(authScheme));
+        xmemcpy(tmp, cfg->schemes, cfg->n_configured * sizeof(authScheme));
+        xfree(cfg->schemes);
+        cfg->schemes = tmp;
+    }
+}
+
+static void
+parse_authparam(authConfig * config)
+{
+    char *type_str;
+    char *param_str;
+    authScheme *scheme=NULL;
+    int type,i;
+ 
+    if ((type_str = strtok(NULL, w_space)) == NULL)
+        self_destruct();
+
+    if ((param_str = strtok(NULL, w_space)) == NULL)
+        self_destruct();
+
+    if ((type=authenticateAuthSchemeId(type_str))==-1)
+    {
+        debug(3,0) ("Parsing Config File: Unknown authentication scheme '%s'.\n",type_str);
+        return;
+    }
+
+    for (i = 0; i < config->n_configured; i++) {
+        if (config->schemes[i].Id==type) {
+            scheme=config->schemes + i;
+        }
+    }
+
+    if (scheme==NULL)
+    {
+        allocate_new_authScheme(config);
+        scheme=config->schemes + config->n_configured;
+        config->n_configured++;
+        scheme->Id=type;
+        scheme->typestr=authscheme_list[type].typestr;
+    }
+   
+    authscheme_list[type].parse(scheme, config->n_configured, param_str);
+}
+
+static void
+free_authparam(authConfig * cfg)
+{
+    authScheme *scheme;
+    int i;
+    /* DON'T FREE THESE FOR RECONFIGURE */
+    if (reconfiguring)
+        return;
+    for (i = 0; i < cfg->n_configured; i++) {
+        scheme = cfg->schemes + i;
+        authscheme_list[scheme->Id].freeconfig(scheme);
+    }
+    safe_free(cfg->schemes);
+    cfg->schemes = NULL;
+    cfg->n_allocated = 0;
+    cfg->n_configured = 0;
+}
+
+static void
+dump_authparam(StoreEntry * entry, const char *name, authConfig swap)
+{
+    fatalf("haha\n");
+//    SwapDir *s;
+//    int i;
+//    for (i = 0; i < swap.n_configured; i++) {
+//        s = swap.swapDirs + i;
+//        s->dump(entry, name, s);
+//    }
+}
+
 static void
 parse_cachedir(cacheSwap * swap)
 {
Index: squid/src/cf.data.pre
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/cf.data.pre,v
retrieving revision 1.1.1.3.4.1.2.18.2.7
retrieving revision 1.1.1.3.4.1.2.18.2.8
diff -u -r1.1.1.3.4.1.2.18.2.7 -r1.1.1.3.4.1.2.18.2.8
--- squid/src/cf.data.pre	1 Jan 2001 01:55:41 -0000	1.1.1.3.4.1.2.18.2.7
+++ squid/src/cf.data.pre	1 Jan 2001 09:51:21 -0000	1.1.1.3.4.1.2.18.2.8
@@ -1,6 +1,6 @@
 
 #
-# $Id: cf.data.pre,v 1.1.1.3.4.1.2.18.2.7 2001/01/01 01:55:41 rbcollins Exp $
+# $Id: cf.data.pre,v 1.1.1.3.4.1.2.18.2.8 2001/01/01 09:51:21 rbcollins Exp $
 #
 #
 # SQUID Internet Object Cache  http://squid.nlanr.net/Squid/
@@ -1089,15 +1089,67 @@
 	are sent.
 DOC_END
 
-NAME: authenticate_scheme_order
-TYPE: wordlist
-DEFAULT: basic
-LOC: Config.authenticate_scheme_order
+NAME: auth_param
+TYPE: authparam
+LOC: Config.authConfig
+DEFAULT: none
 DOC_START
-	Specify the order that authentication challenges are written to the
-	client agent in HTTP responses. Use none to prevent the use of
-	authentication under any circumstances. This is CASE SENSITIVE.
-	Defaults to use the 'basic' scheme only.
+	This is used to pass parameters to the various authentication
+	schemes.
+	format: auth_param scheme parameter [setting]
+	
+	auth_param basic program @DEFAULT_PREFIX@/bin/ncsa_auth @DEFAULT_PREFIX@/etc/passwd	
+	would tell the basic authentication scheme it's program parameter.
+
+	Parameters for the basic scheme follow.
+	
+	"program" cmdline
+	Specify the command for the external authenticator.  Such a
+	program reads a line containing "username password" and replies
+	"OK" or "ERR" in an endless loop.  If you use an authenticator,
+	make sure you have 1 acl of type proxy_auth.  By default, the
+	authenticate_program is not used.
+
+	If you want to use the traditional proxy authentication,
+	jump over to the ../auth_modules/NCSA directory and
+	type:
+		% make
+		% make install
+
+	Then, set this line to something like
+
+	auth_param basic program @DEFAULT_PREFIX@/bin/ncsa_auth @DEFAULT_PREFIX@/etc/passwd
+
+	"children" numberofchildren
+	The number of authenticator processes to spawn (no default). If you
+	start too few Squid will have to wait for them to process a backlog
+	of usercode/password verifications, slowing it down. When password
+	verifications are done via a (slow) network you are likely to need
+	lots of authenticator processes.
+	auth_param basic children 5
+
+	"realm" realmstring
+	Specifies the realm name which is to be reported to the client for
+	the basic proxy authentication scheme (part of the text the user will
+	see when prompted their username and password). Their is no default.
+	auth_param basic realm Squid proxy-caching web server
+
+	"credentialsttl" timetolive
+	Specifies how long squid assumes an externally validated username:password
+	pair is valid for - in other words how often the helper program is called 
+	for that user. Set this low to force revalidation with short lived passwords.
+	Note that setting this high does not impact your susceptability to replay
+	attacks unless you are using a one-time password system (such as SecureID).
+	If you are using such a system, you will be vulnerable to replay attacks
+	unless you also enable the IP ttl is strict option.
+
+NOCOMMENT_START
+#Recommended minimum configuration:
+#authparam basic program <uncomment and complete this line>
+authparam basic children 5
+authparam basic realm Squid proxy-caching web server
+#authparam basic credentialsttl 2 hours
+NOCOMMENT_END
 DOC_END
 
 
@@ -1148,40 +1200,6 @@
         will be the minimum of this time AND the number of reused challenges.
 DOC_END
 
-NAME: authenticate_program
-TYPE: wordlist
-LOC: Config.Program.authenticate
-DEFAULT: none
-DOC_START
-	Specify the command for the external authenticator.  Such a
-	program reads a line containing "username password" and replies
-	"OK" or "ERR" in an endless loop.  If you use an authenticator,
-	make sure you have 1 acl of type proxy_auth.  By default, the
-	authenticate_program is not used.
-
-	If you want to use the traditional proxy authentication,
-	jump over to the ../auth_modules/NCSA directory and
-	type:
-		% make
-		% make install
-
-	Then, set this line to something like
-
-	authenticate_program @DEFAULT_PREFIX@/bin/ncsa_auth @DEFAULT_PREFIX@/etc/passwd
-DOC_END
-
-NAME: authenticate_children
-TYPE: int
-DEFAULT: 5
-LOC: Config.authenticateChildren
-DOC_START
-	The number of authenticator processes to spawn (default 5). If you
-	start too few Squid will have to wait for them to process a backlog
-	of usercode/password verifications, slowing it down. When password
-	verifications are done via a (slow) network you are likely to need
-	lots of authenticator processes.
-DOC_END
-
 NAME: authenticate_cache_garbage_interval
 TYPE: time_t
 DEFAULT: 1 hour
@@ -1198,9 +1216,9 @@
 DEFAULT: 1 hour
 LOC: Config.authenticateTTL
 DOC_START
-	The time a checked username/password combination remains cached.
-	If a wrong password is given for a cached user, the user gets
-	removed from the username/password cache forcing a revalidation.
+	The time a user & their credentials stay in the logged in user cache
+	since their last request. When the garbage interval passes, all
+	user credentials that have passed their TTL are removed from memory.
 DOC_END
 
 NAME: authenticate_ip_ttl
@@ -1878,17 +1896,6 @@
 	the Squid FAQ (http://squid.nlanr.net/Squid/FAQ/FAQ-10.html).
 DOC_END
 
-NAME: proxy_auth_realm
-TYPE: eol
-DEFAULT: Squid proxy-caching web server
-LOC: Config.basicAuthRealm
-DOC_START
-	Specifies the realm name which is to be reported to the client for
-	the basic proxy authentication scheme (part of the text the user will 
-	see when prompted their username and password).
-DOC_END
-
-
 NAME: ident_lookup_access
 TYPE: acl_access
 IFDEF: USE_IDENT
Index: squid/src/main.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/main.c,v
retrieving revision 1.1.1.3.4.1.2.12.2.1
retrieving revision 1.1.1.3.4.1.2.12.2.2
diff -u -r1.1.1.3.4.1.2.12.2.1 -r1.1.1.3.4.1.2.12.2.2
--- squid/src/main.c	13 Dec 2000 01:23:31 -0000	1.1.1.3.4.1.2.12.2.1
+++ squid/src/main.c	1 Jan 2001 09:51:21 -0000	1.1.1.3.4.1.2.12.2.2
@@ -1,6 +1,6 @@
 
 /*
- * $Id: main.c,v 1.1.1.3.4.1.2.12.2.1 2000/12/13 01:23:31 rbcollins Exp $
+ * $Id: main.c,v 1.1.1.3.4.1.2.12.2.2 2001/01/01 09:51:21 rbcollins Exp $
  *
  * DEBUG: section 1     Startup and Main Loop
  * AUTHOR: Harvest Derived
@@ -359,7 +359,7 @@
     idnsInit();
 #endif
     redirectInit();
-    authenticateInit();
+    authenticateInit(&Config.authConfig);
 #if USE_WCCP
     wccpInit();
 #endif
@@ -400,7 +400,7 @@
     dnsInit();
 #endif
     redirectInit();
-    authenticateInit();
+    authenticateInit(&Config.authConfig);
 }
 
 static void
@@ -489,7 +489,7 @@
     idnsInit();
 #endif
     redirectInit();
-    authenticateInit();
+    authenticateInit(&Config.authConfig);
     useragentOpenLog();
     refererOpenLog();
     httpHeaderInitModule();	/* must go before any header processing (e.g. the one in errorInitialize) */
@@ -632,6 +632,7 @@
 #endif
 	eventInit();		/* eventInit() is required for config parsing */
 	storeFsInit();		/* required for config parsing */
+        authenticateSchemeInit(); /* required for config parsign */
 	parse_err = parseConfigFile(ConfigFile);
 
 	if (opt_parse_cfg_only)
Index: squid/src/protos.h
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/protos.h,v
retrieving revision 1.1.1.3.12.17.2.10
retrieving revision 1.1.1.3.12.17.2.11
diff -u -r1.1.1.3.12.17.2.10 -r1.1.1.3.12.17.2.11
--- squid/src/protos.h	1 Jan 2001 01:55:41 -0000	1.1.1.3.12.17.2.10
+++ squid/src/protos.h	1 Jan 2001 09:51:21 -0000	1.1.1.3.12.17.2.11
@@ -1,6 +1,6 @@
 
 /*
- * $Id: protos.h,v 1.1.1.3.12.17.2.10 2001/01/01 01:55:41 rbcollins Exp $
+ * $Id: protos.h,v 1.1.1.3.12.17.2.11 2001/01/01 09:51:21 rbcollins Exp $
  *
  *
  * SQUID Internet Object Cache  http://squid.nlanr.net/Squid/
@@ -707,8 +707,10 @@
 
 /* authenticate.c */
 extern void authenticateAuthUserMerge(auth_user_t *, auth_user_t *);
+extern int  authenticateAuthSchemeId(const char *typestr);
 extern void authenticateStart(auth_user_t *, RH *, void *);
-extern void authenticateInit(void);
+extern void authenticateSchemeInit(void);
+extern void authenticateInit(authConfig *);
 extern void authenticateShutdown(void);
 extern void authenticateFixHeader(HttpReply * rep, ErrorState * err);
 extern auth_user_t *authenticateGetAuthUser(const char *proxy_auth);
Index: squid/src/structs.h
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/structs.h,v
retrieving revision 1.1.1.3.4.1.2.26.2.14
retrieving revision 1.1.1.3.4.1.2.26.2.15
diff -u -r1.1.1.3.4.1.2.26.2.14 -r1.1.1.3.4.1.2.26.2.15
--- squid/src/structs.h	1 Jan 2001 01:55:41 -0000	1.1.1.3.4.1.2.26.2.14
+++ squid/src/structs.h	1 Jan 2001 09:51:21 -0000	1.1.1.3.4.1.2.26.2.15
@@ -1,6 +1,6 @@
 
 /*
- * $Id: structs.h,v 1.1.1.3.4.1.2.26.2.14 2001/01/01 01:55:41 rbcollins Exp $
+ * $Id: structs.h,v 1.1.1.3.4.1.2.26.2.15 2001/01/01 09:51:21 rbcollins Exp $
  *
  *
  * SQUID Internet Object Cache  http://squid.nlanr.net/Squid/
@@ -105,27 +105,42 @@
 };
 
 /*
- * This defines an auth scheme
+ * This defines an auth scheme module
  */
 
 struct _authscheme_entry {
     char *typestr;
-//    STFSPARSE *parsefunc;
-//    AUTHSRECONFIGURE *reconfigurefunc;
     AUTHSACTIVE   *Active;
     AUTHSAUTHED   *authenticated;
     AUTHSAUTHUSER *authAuthenticate;
     AUTHSFIXERR   *authFixHeader;
     AUTHSFREE     *FreeUser;
+    AUTHSFREECONFIG *freeconfig;
     AUTHSUSERNAME *authUserUsername;
     AUTHSONCLOSEC *oncloseconnection; /*optional*/
     AUTHSDECODE   *decodeauth;
     AUTHSDIRECTION *getdirection;
+    AUTHSPARSE    *parse;
+    AUTHSINIT     *init;
     AUTHSSHUTDOWN *donefunc;
     AUTHSSTART    *authStart;
     AUTHSSTATS    *authStats;
 };
 
+/*
+ * This is a configured auth scheme
+ */
+
+/* private data types */
+struct _authScheme {
+    /* pointer to the authscheme_list's string entry */
+    char *typestr;
+    /* the scheme id in the authscheme_list */
+    int Id;
+    /* the scheme's configuration details. */
+    void *scheme_data;
+};
+
 struct _acl_deny_info_list {
     int err_page_id;
     char *err_page_name;
@@ -370,7 +385,6 @@
 	char *dnsserver;
 #endif
 	wordlist *redirect;
-	wordlist *authenticate;
 	wordlist *ntlmauthenticate;
 #if USE_ICMP
 	char *pinger;
@@ -383,8 +397,6 @@
     int dnsChildren;
 #endif
     int redirectChildren;
-    wordlist *authenticate_scheme_order;
-    int authenticateChildren;
     time_t authenticateGCInterval;
     time_t authenticateTTL;
     time_t authenticateIpTTL;
@@ -513,7 +525,11 @@
 	acl_access *redirector;
     } accessList;
     acl_deny_info_list *denyInfoList;
-    char *basicAuthRealm;
+    struct _authConfig {
+         authScheme *schemes;
+         int n_allocated;
+         int n_configured;
+     } authConfig;
     struct {
 	size_t list_width;
 	int list_wrap;
Index: squid/src/typedefs.h
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/typedefs.h,v
retrieving revision 1.1.1.3.12.13.2.10
retrieving revision 1.1.1.3.12.13.2.11
diff -u -r1.1.1.3.12.13.2.10 -r1.1.1.3.12.13.2.11
--- squid/src/typedefs.h	31 Dec 2000 15:10:38 -0000	1.1.1.3.12.13.2.10
+++ squid/src/typedefs.h	1 Jan 2001 09:51:21 -0000	1.1.1.3.12.13.2.11
@@ -1,6 +1,6 @@
 
 /*
- * $Id: typedefs.h,v 1.1.1.3.12.13.2.10 2000/12/31 15:10:38 rbcollins Exp $
+ * $Id: typedefs.h,v 1.1.1.3.12.13.2.11 2001/01/01 09:51:21 rbcollins Exp $
  *
  *
  * SQUID Internet Object Cache  http://squid.nlanr.net/Squid/
@@ -67,6 +67,7 @@
 typedef struct _auth_user_hash_pointer auth_user_hash_pointer;
 typedef struct _acl_proxy_auth_match_cache acl_proxy_auth_match_cache;
 typedef struct _authscheme_entry authscheme_entry_t;
+typedef struct _authScheme authScheme;
 typedef struct _acl_arp_data acl_arp_data;
 typedef struct _acl acl;
 typedef struct _acl_snmp_comm acl_snmp_comm;
@@ -152,6 +153,7 @@
 typedef struct _StatCounters StatCounters;
 typedef struct _tlv tlv;
 typedef struct _storeSwapLogData storeSwapLogData;
+typedef struct _authConfig authConfig;
 typedef struct _cacheSwap cacheSwap;
 typedef struct _StatHist StatHist;
 typedef struct _String String;
@@ -297,8 +299,11 @@
 typedef int   AUTHSDIRECTION(auth_user_t *);
 typedef void  AUTHSFIXERR(auth_user_t *, HttpReply *, http_hdr_type, request_t *);
 typedef void  AUTHSFREE(auth_user_t *);
+typedef void  AUTHSFREECONFIG(authScheme *);
 typedef char *AUTHSUSERNAME(auth_user_t *);
 typedef void  AUTHSONCLOSEC(ConnStateData *);
+typedef void  AUTHSPARSE(authScheme *, int, char *);
+typedef void  AUTHSINIT(authScheme *);
 typedef void  AUTHSSETUP(authscheme_entry_t *);
 typedef void  AUTHSSHUTDOWN(void);
 typedef void  AUTHSSTART(auth_user_t * , RH * , void *);
Index: squid/src/auth/basic/auth_basic.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/auth/basic/auth_basic.c,v
retrieving revision 1.1.2.9
retrieving revision 1.1.2.10
diff -u -r1.1.2.9 -r1.1.2.10
--- squid/src/auth/basic/auth_basic.c	1 Jan 2001 01:55:42 -0000	1.1.2.9
+++ squid/src/auth/basic/auth_basic.c	1 Jan 2001 09:51:23 -0000	1.1.2.10
@@ -57,6 +57,9 @@
 static AUTHSDECODE    authenticateBasicDecodeAuth;
 static AUTHSFIXERR    authenticateBasicFixErrorHeader;
 static AUTHSFREE      authenticateBasicFreeUser;
+static AUTHSFREECONFIG authBasicFreeConfig;
+static AUTHSPARSE     authBasicParse;
+static AUTHSINIT      authBasicInit;
 static AUTHSSTART  authenticateBasicStart;
 static AUTHSSTATS  authenticateBasicStats;
 static AUTHSUSERNAME authenticateBasicUsername;
@@ -64,6 +67,8 @@
 
 static helper *basicauthenticators = NULL;
 
+static auth_basic_config *basicConfig = NULL;
+
 static int authbasic_initialised = 0;
 MemPool *basic_data_pool = NULL;
 
@@ -89,16 +94,15 @@
 
 void 
 authSchemeSetup_basic(authscheme_entry_t *authscheme) {
-static int init = 0;
     assert(!authbasic_initialised);
-//    authscheme->parsefunc = storeUfsDirParse;
-//    authscheme->reconfigurefunc = storeUfsDirReconfigure;
     authscheme->Active            =authenticateBasicActive;
-    if (Config.Program.authenticate){
+    authscheme->parse             =authBasicParse;
+    authscheme->init              =authBasicInit;
     authscheme->authAuthenticate = authenticateBasicAuthenticateUser;
     authscheme->authenticated= authenticateBasicAuthenticated;
     authscheme->authFixHeader=authenticateBasicFixErrorHeader;
     authscheme->FreeUser          =authenticateBasicFreeUser;
+    authscheme->freeconfig        =authBasicFreeConfig;
     authscheme->authStart   =authenticateBasicStart;
     authscheme->authStats   =authenticateBasicStats;
     authscheme->authUserUsername = authenticateBasicUsername;
@@ -106,31 +110,20 @@
     authscheme->oncloseconnection=NULL;
     authscheme->decodeauth  =authenticateBasicDecodeAuth;
     authscheme->donefunc = authBasicDone;
-    if (!basic_data_pool)
-        basic_data_pool = memPoolCreate("Basic Scheme User Data", sizeof(basic_data));
-//    ufs_state_pool = memPoolCreate("UFS IO State data", sizeof(ufsstate_t));
-    authbasic_initialised = 1;
-        if (basicauthenticators == NULL)
-                basicauthenticators = helperCreate("basicauthenticator");
-            basicauthenticators->cmdline = Config.Program.authenticate;
-            basicauthenticators->n_to_start = Config.authenticateChildren;
-            basicauthenticators->ipc_type = IPC_TCP_SOCKET;
-            helperOpenServers(basicauthenticators);
-            if (!init) {
-                cachemgrRegister("basicauthenticator",
-                    "User Authenticator Stats",
-                    authenticateBasicStats, 0, 1);
-                init++;
-            }
-        }
 }
 
 int
 authenticateBasicActive(){
+#if 0
     if (authbasic_initialised) 
         return 1; 
     else 
         return 0;
+#endif
+    if ((basicConfig!= NULL) && (basicConfig->authenticate!=NULL) && 
+        (basicConfig->authenticateChildren!=0) &&(basicConfig->basicAuthRealm != NULL))
+        return 1;
+    return 0;
 }
 
 int 
@@ -225,12 +218,27 @@
 
 void
 authenticateBasicFixErrorHeader(auth_user_t *auth_user, HttpReply *rep, http_hdr_type type, request_t * request){
-    if (Config.Program.authenticate){
-        debug(29, 5) ("authenticateFixErrorHeader: Sending type:%d header: 'Basic realm=\"%s\"'\n",type,Config.basicAuthRealm);
-    httpHeaderPutStrf(&rep->header, type, "Basic realm=\"%s\"", Config.basicAuthRealm);
+    if (basicConfig->authenticate){
+        debug(29, 5) ("authenticateFixErrorHeader: Sending type:%d header: 'Basic realm=\"%s\"'\n",type,basicConfig->basicAuthRealm);
+    httpHeaderPutStrf(&rep->header, type, "Basic realm=\"%s\"", basicConfig->basicAuthRealm);
     }
 }
 
+/* free any allocated configuration details */
+void
+authBasicFreeConfig(authScheme *scheme)
+{
+    if (basicConfig==NULL)
+        return;
+    assert(basicConfig==scheme);
+    if (basicConfig->authenticate)
+        wordlistDestroy(basicConfig->authenticate);
+    if (basicConfig->basicAuthRealm)
+        safe_free(basicConfig->basicAuthRealm);
+   xfree(basicConfig);
+   basicConfig=NULL; 
+}
+
 void
 authenticateBasicFreeUser(auth_user_t *auth_user) {
     basic_data * basic_auth = auth_user->scheme_data;
@@ -276,6 +284,71 @@
 }
 
 static void
+parse_int(int *var)
+{
+    int i;
+    i = GetInteger();
+    *var = i;
+}
+static void
+parse_eol(char *volatile *var)
+{
+    char *token = strtok(NULL, null_string);
+    safe_free(*var);
+    if (token == NULL)
+        self_destruct();
+    *var = xstrdup(token);
+}
+static void
+parse_wordlist(wordlist ** list)
+{
+    char *token;
+    while ((token = strtok(NULL, w_space)))
+        wordlistAdd(list, token);
+}
+
+static void
+requirePathnameExists(const char *name, const char *path)
+{
+    struct stat sb;
+    assert(path != NULL);
+    if (stat(path, &sb) < 0)
+        fatalf("%s: %s", path, xstrerror());
+}
+
+static void
+authBasicParse(authScheme *scheme, int n_configured, char *param_str)
+{
+    if (scheme->scheme_data==NULL)
+    {
+        assert (basicConfig==NULL);
+        /* this is the first param to be found */
+        scheme->scheme_data=xmalloc(sizeof(auth_basic_config));
+        memset(scheme->scheme_data, 0, sizeof(auth_basic_config));
+        basicConfig=scheme->scheme_data;
+        basicConfig->authenticateChildren=5;
+    }
+    basicConfig=scheme->scheme_data;
+    if (strcasecmp(param_str,"program")==0)
+    {
+        parse_wordlist(&basicConfig->authenticate);
+        requirePathnameExists("authparam basic program",basicConfig->authenticate->key);
+    }
+    else if (strcasecmp(param_str,"children")==0)
+    {
+        parse_int(&basicConfig->authenticateChildren);
+    }
+    else if (strcasecmp(param_str,"realm")==0)
+    {
+        parse_eol(&basicConfig->basicAuthRealm);
+    }
+    else
+    {
+        fatalf("unrecognised basic auth scheme parameter '%s'\n",param_str);
+    }
+}
+
+static void
 authenticateBasicStats(StoreEntry * sentry)
 {
     storeAppendPrintf(sentry, "Basic Authenticator Statistics:\n");
@@ -362,6 +435,32 @@
     return;
 }
 
+/* Initialize helpers and the like for this auth scheme. Called AFTER parsing the
+ * config file */
+static void
+authBasicInit(authScheme *scheme)
+{
+    static int init = 0;
+    if (basicConfig->authenticate){
+    if (!basic_data_pool)
+        basic_data_pool = memPoolCreate("Basic Scheme User Data", sizeof(basic_data));
+//    ufs_state_pool = memPoolCreate("UFS IO State data", sizeof(ufsstate_t));
+    authbasic_initialised = 1;
+        if (basicauthenticators == NULL)
+                basicauthenticators = helperCreate("basicauthenticator");
+            basicauthenticators->cmdline = basicConfig->authenticate;
+            basicauthenticators->n_to_start = basicConfig->authenticateChildren;
+            basicauthenticators->ipc_type = IPC_TCP_SOCKET;
+            helperOpenServers(basicauthenticators);
+            if (!init) {
+                cachemgrRegister("basicauthenticator",
+                    "User Authenticator Stats",
+                    authenticateBasicStats, 0, 1);
+                init++;
+            }
+        } 
+}
+
 /* send the initial data to a basic authenticator module */
 static void
 authenticateBasicStart(auth_user_t * auth_user, RH * handler, void *data)
@@ -376,7 +475,7 @@
     basic_auth = auth_user->scheme_data;
     debug(29, 5) ("authenticateStart: '%s:%s'\n", basic_auth->username,
         basic_auth->passwd);
-    if (Config.Program.authenticate == NULL) {
+    if (basicConfig->authenticate == NULL) {
         handler(data, NULL);
         return;
     }
Index: squid/src/auth/basic/auth_basic.h
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/auth/basic/auth_basic.h,v
retrieving revision 1.1.2.1
retrieving revision 1.1.2.2
diff -u -r1.1.2.1 -r1.1.2.2
--- squid/src/auth/basic/auth_basic.h	11 Dec 2000 23:32:15 -0000	1.1.2.1
+++ squid/src/auth/basic/auth_basic.h	1 Jan 2001 09:51:23 -0000	1.1.2.2
@@ -20,6 +20,15 @@
     char *passwd;
 };
 
+/* configuration runtime data */
+struct _auth_basic_config {
+    int authenticateChildren;
+    char *basicAuthRealm;
+    wordlist *authenticate;
+};
+
+typedef struct _auth_basic_config auth_basic_config;
+
 typedef struct _basic_data basic_data;
 
 #if 0
