---------------------
PatchSet 1075 
Date: 2001/01/05 03:44:58
Author: rbcollins
Branch: auth_digest
Tag: (none) 
Log:
authentication info header support

Members: 
	src/authenticate.c:1.1.1.3.12.17.2.11.2.8->1.1.1.3.12.17.2.11.2.9 
	src/client_side.c:1.1.1.3.4.1.2.30.2.6.2.4->1.1.1.3.4.1.2.30.2.6.2.5 
	src/errorpage.c:1.1.1.3.10.9.2.2.2.3->1.1.1.3.10.9.2.2.2.4 
	src/protos.h:1.1.1.3.12.17.2.9.2.5->1.1.1.3.12.17.2.9.2.6 
	src/squid.h:1.1.1.3.12.5.4.1->1.1.1.3.12.5.4.2 
	src/structs.h:1.1.1.3.4.1.2.26.2.12.2.7->1.1.1.3.4.1.2.26.2.12.2.8 
	src/typedefs.h:1.1.1.3.12.13.2.9.2.3->1.1.1.3.12.13.2.9.2.4 
	src/auth/digest/auth_digest.c:1.1.2.9->1.1.2.10 

Index: squid/src/authenticate.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/authenticate.c,v
retrieving revision 1.1.1.3.12.17.2.11.2.8
retrieving revision 1.1.1.3.12.17.2.11.2.9
diff -u -r1.1.1.3.12.17.2.11.2.8 -r1.1.1.3.12.17.2.11.2.9
--- squid/src/authenticate.c	4 Jan 2001 12:17:08 -0000	1.1.1.3.12.17.2.11.2.8
+++ squid/src/authenticate.c	5 Jan 2001 03:44:58 -0000	1.1.1.3.12.17.2.11.2.9
@@ -1,6 +1,6 @@
 
 /*
- * $Id: authenticate.c,v 1.1.1.3.12.17.2.11.2.8 2001/01/04 12:17:08 rbcollins Exp $
+ * $Id: authenticate.c,v 1.1.1.3.12.17.2.11.2.9 2001/01/05 03:44:58 rbcollins Exp $
  *
  * DEBUG: section 29    Authenticator
  * AUTHOR: Duane Wessels
@@ -430,7 +430,7 @@
     } 
 }
 
-
+#if 0
 void
 authenticateFixHeader(HttpReply * rep, ErrorState * err)
 /* send the auth types we are configured to support (and have compiled in!) */
@@ -473,6 +473,58 @@
         }
     }
 }
+#endif
+
+void
+authenticateFixHeader(HttpReply * rep, auth_user_request_t * auth_user_request, request_t* request, int accelerated)
+/* send the auth types we are configured to support (and have compiled in!) */
+{
+/*    auth_type_t auth_type=err->auth_type;
+    auth_state_t auth_state=err->auth_state;
+    char *authchallenge=err->authchallenge;
+  auth_user_request_t *auth_user_request=err->auth_user_request;
+*/
+    int type;
+    switch (rep->sline.status) {
+    case HTTP_PROXY_AUTHENTICATION_REQUIRED:
+         /* Proxy authorisation needed */
+         type= HDR_PROXY_AUTHENTICATE;
+    break;
+    case HTTP_UNAUTHORIZED:
+         /* WWW Authorisation needed */
+         type=HDR_WWW_AUTHENTICATE;
+    break;
+    default:
+         /* Keep GCC happy */
+         /* some other HTTP status */
+    break;
+    }
+    debug(29,9)("authenticateFixHeader: headertype:%d authuser:%d\n",type,auth_user_request);
+    if ((rep->sline.status==HTTP_PROXY_AUTHENTICATION_REQUIRED) 
+        || (rep->sline.status==HTTP_UNAUTHORIZED))
+    /* this is a authenticate-needed response */
+    {
+        if ((auth_user_request !=NULL) && (auth_user_request->auth_user->auth_module>0))
+            authscheme_list[auth_user_request->auth_user->auth_module-1].authFixHeader(auth_user_request, rep, type, request);
+        else {
+            int i;
+            authScheme *scheme;
+            /* call each configured 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(auth_user_request,rep,type,
+                        request);
+                else
+                    debug(29,8)("authenticateFixHeader: Configured scheme %s not Active\n",scheme->typestr);
+            }
+        }
+    }
+    if ((auth_user_request != NULL) && (auth_user_request->auth_user->auth_module>0)
+        && (authscheme_list[auth_user_request->auth_user->auth_module-1].AddHeader))
+        authscheme_list[auth_user_request->auth_user->auth_module-1].AddHeader(auth_user_request, rep, accelerated);
+}
 
 void authenticateAuthUserLock(auth_user_t *auth_user)
 {
Index: squid/src/client_side.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/client_side.c,v
retrieving revision 1.1.1.3.4.1.2.30.2.6.2.4
retrieving revision 1.1.1.3.4.1.2.30.2.6.2.5
diff -u -r1.1.1.3.4.1.2.30.2.6.2.4 -r1.1.1.3.4.1.2.30.2.6.2.5
--- squid/src/client_side.c	4 Jan 2001 12:17:08 -0000	1.1.1.3.4.1.2.30.2.6.2.4
+++ squid/src/client_side.c	5 Jan 2001 03:44:58 -0000	1.1.1.3.4.1.2.30.2.6.2.5
@@ -1,6 +1,6 @@
 
 /*
- * $Id: client_side.c,v 1.1.1.3.4.1.2.30.2.6.2.4 2001/01/04 12:17:08 rbcollins Exp $
+ * $Id: client_side.c,v 1.1.1.3.4.1.2.30.2.6.2.5 2001/01/05 03:44:58 rbcollins Exp $
  *
  * DEBUG: section 33    Client-side Routines
  * AUTHOR: Duane Wessels
@@ -1302,6 +1302,9 @@
 		httpHeaderPutInt(hdr, HDR_AGE,
 		    squid_curtime - http->entry->timestamp);
     }
+    /* Handle authentication headers */
+    if (request->auth_user_request)
+        authenticateFixHeader(rep, request->auth_user_request, request,http->flags.accel);
     /* Append X-Cache */
     httpHeaderPutStrf(hdr, HDR_X_CACHE, "%s from %s",
 	is_hit ? "HIT" : "MISS", getMyHostname());
Index: squid/src/errorpage.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/errorpage.c,v
retrieving revision 1.1.1.3.10.9.2.2.2.3
retrieving revision 1.1.1.3.10.9.2.2.2.4
diff -u -r1.1.1.3.10.9.2.2.2.3 -r1.1.1.3.10.9.2.2.2.4
--- squid/src/errorpage.c	4 Jan 2001 12:17:09 -0000	1.1.1.3.10.9.2.2.2.3
+++ squid/src/errorpage.c	5 Jan 2001 03:44:58 -0000	1.1.1.3.10.9.2.2.2.4
@@ -1,6 +1,6 @@
 
 /*
- * $Id: errorpage.c,v 1.1.1.3.10.9.2.2.2.3 2001/01/04 12:17:09 rbcollins Exp $
+ * $Id: errorpage.c,v 1.1.1.3.10.9.2.2.2.4 2001/01/05 03:44:58 rbcollins Exp $
  *
  * DEBUG: section 4     Error Generation
  * AUTHOR: Duane Wessels
@@ -278,7 +278,11 @@
     rep = errorBuildReply(err);
     /* Add authentication header */
 //    debug(28,6)("errorpage:state:type %d:%d.\n",err->auth_state,err->auth_type);
-    authenticateFixHeader(rep, err);
+    /* TODO: alter errorstate to be accel on|off aware. The 0 on the next line
+     * depends on authenticate behaviour: all schemes to date send no extra data
+     * on 407/401 responses, and do not check the accel state on 401/407 responses 
+     */
+    authenticateFixHeader(rep, err->auth_user_request, err->request, 0);
     httpReplySwapOut(rep, entry);
     httpReplyAbsorb(mem->reply, rep);
     EBIT_CLR(entry->flags, ENTRY_FWD_HDR_WAIT);
Index: squid/src/protos.h
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/protos.h,v
retrieving revision 1.1.1.3.12.17.2.9.2.5
retrieving revision 1.1.1.3.12.17.2.9.2.6
diff -u -r1.1.1.3.12.17.2.9.2.5 -r1.1.1.3.12.17.2.9.2.6
--- squid/src/protos.h	4 Jan 2001 12:17:09 -0000	1.1.1.3.12.17.2.9.2.5
+++ squid/src/protos.h	5 Jan 2001 03:44:58 -0000	1.1.1.3.12.17.2.9.2.6
@@ -1,6 +1,6 @@
 
 /*
- * $Id: protos.h,v 1.1.1.3.12.17.2.9.2.5 2001/01/04 12:17:09 rbcollins Exp $
+ * $Id: protos.h,v 1.1.1.3.12.17.2.9.2.6 2001/01/05 03:44:58 rbcollins Exp $
  *
  *
  * SQUID Internet Object Cache  http://squid.nlanr.net/Squid/
@@ -721,7 +721,7 @@
 extern void authenticateSchemeInit(void);
 extern void authenticateInit(authConfig *);
 extern void authenticateShutdown(void);
-extern void authenticateFixHeader(HttpReply * rep, ErrorState * err);
+extern void authenticateFixHeader(HttpReply *, auth_user_request_t *, request_t *, int);
 extern auth_user_request_t *authenticateGetAuthUser(const char *proxy_auth);
 extern void authenticateAuthenticateUser(auth_user_request_t *, request_t *, ConnStateData *, http_hdr_type);
 extern void  authenticateAuthUserUnlock(auth_user_t *auth_user);
Index: squid/src/squid.h
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/squid.h,v
retrieving revision 1.1.1.3.12.5.4.1
retrieving revision 1.1.1.3.12.5.4.2
diff -u -r1.1.1.3.12.5.4.1 -r1.1.1.3.12.5.4.2
--- squid/src/squid.h	4 Jan 2001 12:17:09 -0000	1.1.1.3.12.5.4.1
+++ squid/src/squid.h	5 Jan 2001 03:44:58 -0000	1.1.1.3.12.5.4.2
@@ -1,6 +1,6 @@
 
 /*
- * $Id: squid.h,v 1.1.1.3.12.5.4.1 2001/01/04 12:17:09 rbcollins Exp $
+ * $Id: squid.h,v 1.1.1.3.12.5.4.2 2001/01/05 03:44:58 rbcollins Exp $
  *
  * AUTHOR: Duane Wessels
  *
@@ -158,6 +158,9 @@
 #if HAVE_SYS_STAT_H
 #include <sys/stat.h>
 #endif
+#if HAVE_SYS_VFS_H
+#include <sys/vfs.h>
+#endif
 #if HAVE_SYS_UN_H
 #include <sys/un.h>
 #endif
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.12.2.7
retrieving revision 1.1.1.3.4.1.2.26.2.12.2.8
diff -u -r1.1.1.3.4.1.2.26.2.12.2.7 -r1.1.1.3.4.1.2.26.2.12.2.8
--- squid/src/structs.h	4 Jan 2001 12:17:09 -0000	1.1.1.3.4.1.2.26.2.12.2.7
+++ squid/src/structs.h	5 Jan 2001 03:44:58 -0000	1.1.1.3.4.1.2.26.2.12.2.8
@@ -1,6 +1,6 @@
 
 /*
- * $Id: structs.h,v 1.1.1.3.4.1.2.26.2.12.2.7 2001/01/04 12:17:09 rbcollins Exp $
+ * $Id: structs.h,v 1.1.1.3.4.1.2.26.2.12.2.8 2001/01/05 03:44:58 rbcollins Exp $
  *
  *
  * SQUID Internet Object Cache  http://squid.nlanr.net/Squid/
@@ -125,6 +125,7 @@
 struct _authscheme_entry {
     char *typestr;
     AUTHSACTIVE   *Active;
+    AUTHSADDHEADER *AddHeader;
     AUTHSAUTHED   *authenticated;
     AUTHSAUTHUSER *authAuthenticate;
     AUTHSFIXERR   *authFixHeader;
Index: squid/src/typedefs.h
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/typedefs.h,v
retrieving revision 1.1.1.3.12.13.2.9.2.3
retrieving revision 1.1.1.3.12.13.2.9.2.4
diff -u -r1.1.1.3.12.13.2.9.2.3 -r1.1.1.3.12.13.2.9.2.4
--- squid/src/typedefs.h	2 Jan 2001 11:59:37 -0000	1.1.1.3.12.13.2.9.2.3
+++ squid/src/typedefs.h	5 Jan 2001 03:44:58 -0000	1.1.1.3.12.13.2.9.2.4
@@ -1,6 +1,6 @@
 
 /*
- * $Id: typedefs.h,v 1.1.1.3.12.13.2.9.2.3 2001/01/02 11:59:37 rbcollins Exp $
+ * $Id: typedefs.h,v 1.1.1.3.12.13.2.9.2.4 2001/01/05 03:44:58 rbcollins Exp $
  *
  *
  * SQUID Internet Object Cache  http://squid.nlanr.net/Squid/
@@ -299,6 +299,8 @@
 typedef void  AUTHSDECODE(auth_user_request_t *, const char *);
 typedef int   AUTHSDIRECTION(auth_user_request_t *);
 typedef void  AUTHSFIXERR(auth_user_request_t *, HttpReply *, http_hdr_type, request_t *);
+typedef void  AUTHSADDHEADER(auth_user_request_t *, HttpReply *, int);
+typedef void  AUTHSADDTRAILER(auth_user_request_t *, HttpReply *, int);
 typedef void  AUTHSFREE(auth_user_t *);
 typedef void  AUTHSFREECONFIG(authScheme *);
 typedef char *AUTHSUSERNAME(auth_user_t *);
Index: squid/src/auth/digest/auth_digest.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/auth/digest/auth_digest.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/digest/auth_digest.c	4 Jan 2001 15:17:47 -0000	1.1.2.9
+++ squid/src/auth/digest/auth_digest.c	5 Jan 2001 03:44:58 -0000	1.1.2.10
@@ -52,6 +52,7 @@
 
 static HLPCB authenticateDigestHandleReply;
 static AUTHSACTIVE    authenticateDigestActive;
+static AUTHSADDHEADER authDigestAddHeader;
 static AUTHSAUTHED    authDigestAuthenticated;
 static AUTHSAUTHUSER  authenticateDigestAuthenticateUser;
 static AUTHSDIRECTION authenticateDigestDirection;
@@ -96,7 +97,9 @@
 void authenticateDigestNonceReconfigure();
 const char *authenticateDigestNonceNonceb64(digest_nonce_h *nonce);
 int  authDigestNonceIsValid(digest_nonce_h *nonce, char nc[9]);
+int  authDigestNonceIsStale(digest_nonce_h *nonce);
 void authDigestNonceEncode(digest_nonce_h *nonce);
+int  authDigestNonceLastRequest(digest_nonce_h *nonce);
 
 void
 authDigestNonceEncode(digest_nonce_h *nonce)
@@ -232,13 +235,6 @@
     /* do we have a nonce ? */
     if (!nonce)
         return 0;
-    /* has it's max duration expired? */
-    if (nonce->noncedata.creationtime + digestConfig->noncemaxduration < current_time.tv_sec)
-    {
-        debug (29,6)("authDigestNonceIsValid: Nonce is too old. %d %d %d\n", nonce->noncedata.creationtime,digestConfig->noncemaxduration , current_time.tv_sec);
-        nonce->flags.valid=0;
-        return 0;
-    }
     intnc=atoi(nc);
     if (intnc != nonce->nc+1)
     {
@@ -246,12 +242,6 @@
         nonce->flags.valid=0;
         return 0;
     }
-    if (nonce->nc>99999997)
-    {
-        debug (29,6)("authDigestNonceIsValid: Nonce count about to overflow\n");
-        nonce->flags.valid=0;
-        return 0;
-    }
     /* has it already been invalidated ? */
     if (!nonce->flags.valid)
     {
@@ -262,6 +252,43 @@
     return -1;
 }
 
+int
+authDigestNonceIsStale(digest_nonce_h *nonce)
+{
+    /* do we have a nonce ? */
+    if (!nonce)
+        return -1;
+    /* has it's max duration expired? */
+    if (nonce->noncedata.creationtime + digestConfig->noncemaxduration < current_time.tv_sec)
+    {
+        debug (29,6)("authDigestNonceIsStale: Nonce is too old. %d %d %d\n", nonce->noncedata.creationtime,digestConfig->noncemaxduration , current_time.tv_sec);
+        nonce->flags.valid=0;
+        return -1;
+    }
+    if (nonce->nc>99999997)
+    {
+        debug (29,6)("authDigestNonceIsStale: Nonce count about to overflow\n");
+        nonce->flags.valid=0;
+        return 0;
+    }
+    /* seems ok */
+    return 0;
+}
+
+/* return -1 if the digest will be stale on the next request */
+int
+authDigestNonceLastRequest(digest_nonce_h *nonce)
+{
+    if (!nonce)
+        return -1;
+    if (nonce->nc=99999997)
+    {
+        debug (29,6)("authDigestNoncelastRequest: Nonce count about to overflow\n");
+        return 0;
+    }
+    /* and other tests are possible. */
+    return 0;
+}
 
 /* USER related functions */
 
@@ -404,6 +431,7 @@
     authscheme->authenticated= authDigestAuthenticated;
     authscheme->authFixHeader=authenticateDigestFixHeader;
     authscheme->FreeUser          =authenticateDigestUserFree;
+    authscheme->AddHeader         =authDigestAddHeader;
     authscheme->authStart   =authenticateDigestStart;
     authscheme->authStats   =authenticateDigestStats;
     authscheme->authUserUsername = authenticateDigestUsername;
@@ -547,11 +575,16 @@
 }
 
 int authenticateDigestDirection(auth_user_request_t *auth_user_request) {
+    digest_request_h * digest_request;
 /* null auth_user is checked for by authenticateDirection */
     switch (auth_user_request->auth_user->flags.credentials_ok) {
         case 0: /* not checked */
             return -1;
         case 1: /* checked & ok */
+            digest_request=auth_user_request->scheme_data;
+            if (authDigestNonceIsStale(digest_request->nonce))
+            /* send stale response to the client agent */
+                return -2;
             return 0;
         case 2: /* partway through checking. */
             return -1;
@@ -561,13 +594,44 @@
     return -2;
 }
 
+/* add the [proxy]authorisation header */
+void
+authDigestAddHeader(auth_user_request_t *auth_user_request, HttpReply *rep, int accel)
+{
+    int type;
+    digest_request_h *digest_request;
+    if (!auth_user_request)
+        return;
+    digest_request=auth_user_request->scheme_data;
+    /* don't add to authentication error pages */
+    if ((!accel && rep->sline.status==HTTP_PROXY_AUTHENTICATION_REQUIRED)
+    || (accel && rep->sline.status==HTTP_UNAUTHORIZED))
+         return;
+    type = accel ? HDR_AUTHENTICATION_INFO : HDR_PROXY_AUTHENTICATION_INFO;
+
+    if ((digestConfig->authenticate) && authDigestNonceLastRequest(digest_request->nonce))
+    {
+        debug(29, 5) ("authDigestAddHead: Sending type:%d header: 'nextnonce=\"%s\"",type,authenticateDigestNonceNonceb64(digest_request->nonce));
+        httpHeaderPutStrf(&rep->header, type, "nextnonce=\"%s\"",authenticateDigestNonceNonceb64(digest_request->nonce));
+    }
+    
+}
+
+/* add the [www-|Proxy-]authenticate header on a 407 or 401 reply */
 void
 authenticateDigestFixHeader(auth_user_request_t *auth_user_request, HttpReply *rep, http_hdr_type type, request_t * request){
+    digest_request_h *digest_request;
+    int stale=0;
     digest_nonce_h *nonce = authenticateDigestNonceNew();
+    if (auth_user_request && authDigestAuthenticated(auth_user_request) && auth_user_request->scheme_data)
+    {
+        digest_request=auth_user_request->scheme_data;
+        stale=authDigestNonceIsStale(digest_request->nonce);
+    }
     if (digestConfig->authenticate){
-        debug(29, 5) ("authenticateFixHeader: Sending type:%d header: 'Digest realm=\"%s\", nonce=\"%s\"\n",type,digestConfig->digestAuthRealm,authenticateDigestNonceNonceb64(nonce));
+        debug(29, 5) ("authenticateFixHeader: Sending type:%d header: 'Digest realm=\"%s\", nonce=\"%s\", qop=\"%s\", stale=%s\n",type,digestConfig->digestAuthRealm,authenticateDigestNonceNonceb64(nonce),QOP_AUTH, stale ? "true" : "false");
         /* in the future, for WWW auth we may want to support the domain entry */
-        httpHeaderPutStrf(&rep->header, type, "Digest realm=\"%s\", nonce=\"%s\", qop=\"%s\"",digestConfig->digestAuthRealm,authenticateDigestNonceNonceb64(nonce),QOP_AUTH);
+        httpHeaderPutStrf(&rep->header, type, "Digest realm=\"%s\", nonce=\"%s\", qop=\"%s\", stale=%s",digestConfig->digestAuthRealm,authenticateDigestNonceNonceb64(nonce),QOP_AUTH, stale ? "true" : "false");
     }
 }
 
