From: Amos Jeffries Date: Sat, 10 May 2008 08:34:03 +0000 (+1200) Subject: Bug 2223: Feature: flexible handling of x-forwarded-for X-Git-Tag: SQUID_3_1_0_1~49^2~240^2~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=67c06f0d42ffa2b3b71082e0694460efa22a37a0;p=thirdparty%2Fsquid.git Bug 2223: Feature: flexible handling of x-forwarded-for This patch adds three settings for the 'forwarded_for' option in squid.conf: If set to "transparent", Squid will not alter the X-Forwarded-For header in any way. If set to "delete", Squid will delete the entire X-Forwarded-For header. If set to "truncate", Squid will remove all existing X-Forwarded-For entries, and place itself as the sole entry. The old options 'on' and 'off' have been left unaltered. --- diff --git a/src/AuthUser.cci b/src/AuthUser.cci index 03135359d2..c1060cab1a 100644 --- a/src/AuthUser.cci +++ b/src/AuthUser.cci @@ -37,6 +37,8 @@ #include "assert.h" /* for xstrdup() */ #include "util.h" +/* for safe_free() */ +#include "defines.h" char const * AuthUser::username () const diff --git a/src/cf.data.pre b/src/cf.data.pre index 6c30ee100e..172ebe42fc 100644 --- a/src/cf.data.pre +++ b/src/cf.data.pre @@ -5453,20 +5453,28 @@ DOC_START DOC_END NAME: forwarded_for -COMMENT: on|off -TYPE: onoff +COMMENT: on|off|transparent|truncate|delete +TYPE: string DEFAULT: on LOC: opt_forwarded_for DOC_START - If set, Squid will include your system's IP address or name - in the HTTP requests it forwards. By default it looks like - this: + If set to "on", Squid will append your client's IP address + in the HTTP requests it forwards. By default it looks like: X-Forwarded-For: 192.1.2.3 - If you disable this, it will appear as + If set to "off", it will appear as X-Forwarded-For: unknown + + If set to "transparent", Squid will not alter the + X-Forwarded-For header in any way. + + If set to "delete", Squid will delete the entire + X-Forwarded-For header. + + If set to "truncate", Squid will remove all existing + X-Forwarded-For entries, and place itself as the sole entry. DOC_END NAME: cachemgr_passwd diff --git a/src/globals.h b/src/globals.h index 00519753db..1694bd8521 100644 --- a/src/globals.h +++ b/src/globals.h @@ -97,7 +97,7 @@ extern "C" extern int opt_debug_stderr; /* -1 */ extern int opt_dns_tests; /* 1 */ extern int opt_foreground_rebuild; /* 0 */ - extern int opt_forwarded_for; /* 1 */ + extern char *opt_forwarded_for; /* NULL */ extern int opt_reload_hit_only; /* 0 */ #if HAVE_SYSLOG diff --git a/src/http.cc b/src/http.cc index 88006da85e..b9a6950189 100644 --- a/src/http.cc +++ b/src/http.cc @@ -1371,8 +1371,9 @@ HttpStateData::httpBuildRequestHeader(HttpRequest * request, /* building buffer for complex strings */ #define BBUF_SZ (MAX_URL+32) LOCAL_ARRAY(char, bbuf, BBUF_SZ); + LOCAL_ARRAY(char, ntoabuf, MAX_IPSTRLEN); const HttpHeader *hdr_in = &orig_request->header; - const HttpHeaderEntry *e; + const HttpHeaderEntry *e = NULL; String strFwd; HttpHeaderPos pos = HttpHeaderInitPos; assert (hdr_out->owner == hoRequest); @@ -1423,9 +1424,39 @@ HttpStateData::httpBuildRequestHeader(HttpRequest * request, } #endif - /* append X-Forwarded-For */ +#if 1 /* new code */ strFwd = hdr_in->getList(HDR_X_FORWARDED_FOR); + /** \pre Handle X-Forwarded-For */ + if(strcmp(opt_forwarded_for, "delete") != 0) { + if(strcmp(opt_forwarded_for, "on") == 0) { + /** If set to ON - append client IP or 'unknown'. */ + strFwd = hdr_in->getList(HDR_X_FORWARDED_FOR); + if( orig_request->client_addr.IsNoAddr() ) + strListAdd(&strFwd, "unknown", ','); + else + strListAdd(&strFwd, orig_request->client_addr.NtoA(ntoabuf, MAX_IPSTRLEN), ','); + } else if(strcmp(opt_forwarded_for, "off") == 0) { + /** If set to OFF - append 'unknown'. */ + strFwd = hdr_in->getList(HDR_X_FORWARDED_FOR); + strListAdd(&strFwd, "unknown", ','); + } else if(strcmp(opt_forwarded_for, "transparent") == 0) { + /** If set to TRANSPARENT - pass through unchanged. */ + strFwd = hdr_in->getList(HDR_X_FORWARDED_FOR); + } else if(strcmp(opt_forwarded_for, "truncate") == 0) { + /** If set to TRUNCATE - drop existing list and replace with client IP or 'unknown'. */ + if( orig_request->client_addr.IsNoAddr() ) + strFwd = "unknown"; + else + strFwd = orig_request->client_addr.NtoA(ntoabuf, MAX_IPSTRLEN); + } + if(strFwd.size() > 0) + hdr_out->putStr(HDR_X_FORWARDED_FOR, strFwd.buf()); + } + /** If set to DELETE - do not copy through. */ + +#else + if (opt_forwarded_for && !orig_request->client_addr.IsNoAddr()) { orig_request->client_addr.NtoA(bbuf,MAX_IPSTRLEN); strListAdd(&strFwd, bbuf, ','); @@ -1435,6 +1466,7 @@ HttpStateData::httpBuildRequestHeader(HttpRequest * request, hdr_out->putStr(HDR_X_FORWARDED_FOR, strFwd.buf()); +#endif strFwd.clean(); /* append Host if not there already */