Hello,

Here's a patch for Squid ICAP 2.5 from CVS to add the X-Authenticated-User
header described in :

  http://www.ietf.org/internet-drafts/draft-stecher-icap-subid-00.txt

This mimics the X-Client-IP header to provide more information regarding
the original request to the ICAP server. It works with both REQMOD and
RESPMOD (a small change was needed to REQMOD to keep the original
authentification when generating the new request so RESPMOD could use it
too when chained).

It adds two configurations options:
- "icap_send_auth_user" to enable or disable it;
- "icap_auth_scheme" to specify the auth_scheme to report to the ICAP
  server, since squid authentification mechanism doesn't know this.

I think this can be useful for others as well, and I'd be glad to know
what you think of it.

Gaël.

-- 
Gaël Roualland -+- [EMAIL PROTECTED]
Index: src/cf.data.pre
===================================================================
RCS file: /cvsroot/squid/squid/src/cf.data.pre,v
retrieving revision 1.49.2.33.2.12
diff -u -r1.49.2.33.2.12 cf.data.pre
--- src/cf.data.pre     15 Oct 2003 22:20:48 -0000      1.49.2.33.2.12
+++ src/cf.data.pre     7 Nov 2003 18:38:57 -0000
@@ -2587,6 +2587,39 @@
        This adds the header "X-Client-IP" to ICAP requests.
 DOC_END
 
+NAME: icap_send_auth_user
+TYPE: onoff
+IFDEF: HS_FEAT_ICAP
+COMMENT: on|off
+LOC: Config.icapcfg.send_auth_user
+DEFAULT: off
+DOC_START
+       This adds the header "X-Authenticated-User" to ICAP requests 
+       if proxy access is authentified.
+DOC_END
+
+NAME: icap_auth_scheme
+TYPE: string
+IFDEF: HS_FEAT_ICAP
+LOC: Config.icapcfg.auth_scheme
+DEFAULT: Local://%u
+DOC_START
+       Authentification scheme to pass to ICAP requests if
+       icap_send_auth_user is enabled. The first occurence of "%u"
+       is replaced by the authentified user name. If no "%u" is found,
+       the username is added at the end of the scheme.
+       
+       See http://www.ietf.org/internet-drafts/draft-stecher-icap-subid-00.txt,
+       section 3.4 for details on this.
+
+       Examples:
+
+       icap_auth_scheme Local://%u
+       icap_auth_scheme LDAP://ldap-server/cn=%u,dc=company,dc=com
+       icap_auth_scheme WinNT://nt-domain/%u
+       icap_auth_scheme Radius://radius-server/%u
+DOC_END
+
 NAME: icap_service
 TYPE: icap_service_type
 IFDEF: HS_FEAT_ICAP
Index: src/icap_common.c
===================================================================
RCS file: /cvsroot/squid/squid/src/Attic/icap_common.c,v
retrieving revision 1.1.2.22
diff -u -r1.1.2.22 icap_common.c
--- src/icap_common.c   4 Nov 2003 18:22:33 -0000       1.1.2.22
+++ src/icap_common.c   7 Nov 2003 18:38:57 -0000
@@ -622,3 +622,41 @@
     }
     return bw;
 }
+
+/*
+ *  icapAddAuthUserHeader
+ *
+ *  Builds and adds the X-Authenticated-User header to an ICAP request headers.
+ */
+void
+icapAddAuthUserHeader(MemBuf * mb, auth_user_request_t *auth_user_request)
+{
+    char *user = authenticateUserRequestUsername(auth_user_request);
+    char *authuser;
+    size_t len, userlen, schemelen, userofslen;
+    char *userofs;
+
+    if (user == NULL) {
+       debug(81, 5) ("icapAddAuthUserHeader: NULL username\n");
+       return;
+    }
+
+    userlen = strlen(user);
+    schemelen = strlen(Config.icapcfg.auth_scheme);
+    len = userlen + schemelen + 1;
+    authuser = xcalloc(len, 1);
+
+    if ((userofs = strstr(Config.icapcfg.auth_scheme, "%u")) == NULL) {
+        /* simply add user at end of string */
+       snprintf(authuser, len, "%s%s", Config.icapcfg.auth_scheme, user);
+    } else {
+       userofslen = userofs - Config.icapcfg.auth_scheme;
+       xmemcpy(authuser, Config.icapcfg.auth_scheme, userofslen);
+       xmemcpy(authuser + userofslen, user, userlen);
+       xmemcpy(authuser + userofslen + userlen, 
+               userofs + 2, schemelen - (userofslen + 2) + 1);
+    }
+
+    memBufPrintf(mb, "X-Authenticated-User: %s\r\n", base64_encode(authuser));
+    xfree(authuser);
+}
Index: src/icap_reqmod.c
===================================================================
RCS file: /cvsroot/squid/squid/src/Attic/icap_reqmod.c,v
retrieving revision 1.1.2.22
diff -u -r1.1.2.22 icap_reqmod.c
--- src/icap_reqmod.c   6 Nov 2003 22:26:28 -0000       1.1.2.22
+++ src/icap_reqmod.c   7 Nov 2003 18:38:57 -0000
@@ -288,6 +288,11 @@
     request->my_addr = icap->request->my_addr;
     request->my_port = icap->request->my_port;
     request->class = icap->request->class;
+    if (icap->request->auth_user_request != NULL) {
+       /* Copy authentification info in new request */
+       request->auth_user_request = icap->request->auth_user_request;
+       authenticateAuthUserRequestLock(request->auth_user_request);
+    }
     icapReqModInterpretHttpRequest(icap, request);
     xfree(inbuf);
 }
@@ -609,6 +614,8 @@
     memBufAppend(&mb, crlf, 2);
     if (Config.icapcfg.send_client_ip)
        memBufPrintf(&mb, "X-Client-IP: %s\r\n", client_addr);
+    if (Config.icapcfg.send_auth_user && icap->request->auth_user_request != NULL)
+        icapAddAuthUserHeader(&mb, icap->request->auth_user_request);
     icap->flags.keep_alive = 1;
     if (!icap->flags.keep_alive)
        memBufAppend(&mb, "Connection: close\r\n", 19);
Index: src/icap_respmod.c
===================================================================
RCS file: /cvsroot/squid/squid/src/Attic/icap_respmod.c,v
retrieving revision 1.1.2.19
diff -u -r1.1.2.19 icap_respmod.c
--- src/icap_respmod.c  7 Nov 2003 05:52:53 -0000       1.1.2.19
+++ src/icap_respmod.c  7 Nov 2003 18:38:57 -0000
@@ -45,7 +45,8 @@
 const char *crlf = "\r\n";
 
 void
-getICAPRespModString(MemBuf * mb, int o1, int o2, int o3, char *service, char 
*client_addr)
+getICAPRespModString(MemBuf * mb, int o1, int o2, int o3, char *service, char 
*client_addr,
+                    IcapStateData * icap)
 {
     memBufPrintf(mb, "RESPMOD %s ICAP/1.0\r\nEncapsulated:", service);
     if (o1 >= 0)
@@ -61,6 +62,9 @@
     if (Config.icapcfg.send_client_ip) {
        memBufPrintf(mb, "X-Client-IP: %s\r\n", client_addr);
     }
+    if (Config.icapcfg.send_auth_user && icap->request->auth_user_request != NULL) {
+       icapAddAuthUserHeader(mb, icap->request->auth_user_request);
+    }
 #if NOT_YET_FINISHED
     if (Config.icapcfg.trailers) {
        memBufPrintf(mb, "X-TE: trailers\r\n");
@@ -127,9 +131,9 @@
     icap->respmod.res_body_sz = httpReplyBodySize(icap->request->method, r);
     httpReplyDestroy(r);
     if (icap->respmod.res_body_sz)
-       getICAPRespModString(mb, 0, o2, o3, service->uri, client_addr);
+       getICAPRespModString(mb, 0, o2, o3, service->uri, client_addr, icap);
     else
-       getICAPRespModString(mb, 0, o2, -o3, service->uri, client_addr);
+       getICAPRespModString(mb, 0, o2, -o3, service->uri, client_addr, icap);
     if (Config.icapcfg.preview_enable)
        if (icap->preview_size >= 0)
            memBufPrintf(mb, "Preview: %d\r\n", icap->preview_size);
Index: src/protos.h
===================================================================
RCS file: /cvsroot/squid/squid/src/protos.h,v
retrieving revision 1.41.6.13.2.18
diff -u -r1.41.6.13.2.18 protos.h
--- src/protos.h        4 Nov 2003 18:22:33 -0000       1.41.6.13.2.18
+++ src/protos.h        7 Nov 2003 18:38:58 -0000
@@ -1368,6 +1368,7 @@
 int icapParseKeepAlive(const IcapStateData *, const char *, const char *);
 void icapSetKeepAlive(IcapStateData * icap, const char *hdrs);
 size_t icapParseChunkedBody(IcapStateData *, STRCB *, void *);
+void icapAddAuthUserHeader(MemBuf *, auth_user_request_t *);
 
 
 /*
Index: src/structs.h
===================================================================
RCS file: /cvsroot/squid/squid/src/structs.h,v
retrieving revision 1.48.2.9.2.20
diff -u -r1.48.2.9.2.20 structs.h
--- src/structs.h       7 Nov 2003 05:52:53 -0000       1.48.2.9.2.20
+++ src/structs.h       7 Nov 2003 18:38:58 -0000
@@ -383,6 +383,8 @@
     icap_access *access_head;
     int preview_size;
     int send_client_ip;
+    int send_auth_user;
+    char *auth_scheme;
 };
 
 #endif /* HS_FEAT_ICAP */

Reply via email to