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 */