--------------------- PatchSet 8818 Date: 2006/12/19 02:03:19 Author: hno Branch: ntlm_ip_cache Tag: (none) Log: authenticate_ip_shortcircuit_ttl directive, caching authentication credentials on the client IP for a given period of time. Primary target is to do lazy NTLM authentication, but may also be used in other schemes to work around broken apps.. Note: The ttl really should be scheme specific.. Members: src/authenticate.c:1.34.8.2->1.34.8.3 src/cf.data.pre:1.161->1.161.8.1 src/structs.h:1.136->1.136.8.1 Index: squid/src/authenticate.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/authenticate.c,v retrieving revision 1.34.8.2 retrieving revision 1.34.8.3 diff -u -r1.34.8.2 -r1.34.8.3 --- squid/src/authenticate.c 19 Dec 2006 01:52:35 -0000 1.34.8.2 +++ squid/src/authenticate.c 19 Dec 2006 02:03:19 -0000 1.34.8.3 @@ -1,6 +1,6 @@ /* - * $Id: authenticate.c,v 1.34.8.2 2006/12/19 01:52:35 hno Exp $ + * $Id: authenticate.c,v 1.34.8.3 2006/12/19 02:03:19 hno Exp $ * * DEBUG: section 29 Authenticator * AUTHOR: Duane Wessels @@ -44,6 +44,7 @@ static void authenticateDecodeAuth(const char *proxy_auth, auth_user_request_t * auth_user_request); static auth_acl_t authenticateAuthenticate(auth_user_request_t ** auth_user_request, http_hdr_type headertype, request_t * request, ConnStateData * conn, struct in_addr src_addr); +static void authenticateAuthUserRequestUnlinkIp(const struct in_addr ipaddr); /* * @@ -259,6 +260,88 @@ auth_user->ipcount--; } +typedef struct { + hash_link hash; /* must be first */ + struct in_addr ipaddr; + auth_user_request_t *auth_user_request; + time_t last_seen; +} auth_user_request_ip_hash_t; +MemPool *auth_user_request_ip_pool = NULL; +hash_table *auth_user_request_ip_hash = NULL; + +static unsigned int +hash_in_addr(const void *a, unsigned int size) +{ + const struct in_addr *ipaddr = a; + const uint32_t ip = ntohl(ipaddr->s_addr); + return ip % size; +} + +static int +cmp_in_addr(const struct in_addr *a, const struct in_addr *b) +{ + const uint32_t ipa = ntohl(a->s_addr); + const uint32_t ipb = ntohl(b->s_addr); + + return memcmp(&ipa, &ipb, 4); +} + +static void +authenticateAuthUserRequestUnlinkIp(const struct in_addr ipaddr) +{ + auth_user_request_ip_hash_t *hash_entry = hash_lookup(auth_user_request_ip_hash, &ipaddr); + if (hash_entry) { + hash_remove_link(auth_user_request_ip_hash, &hash_entry->hash); + authenticateAuthUserRequestUnlock(hash_entry->auth_user_request); + memPoolFree(auth_user_request_ip_pool, hash_entry); + } +} + +static void +authenticateAuthUserRequestLinkIp(auth_user_request_t * auth_user_request, const struct in_addr ipaddr) +{ + auth_user_request_ip_hash_t *hash_entry; + + if (!Config.authenticateIpShortcircuitTTL) + return; + + if (!auth_user_request_ip_hash) { + auth_user_request_ip_hash = hash_create((HASHCMP *) cmp_in_addr, 7921, hash_in_addr); + auth_user_request_ip_pool = memPoolCreate("auth_user_request_ip_hash_t", sizeof(auth_user_request_ip_hash_t)); + } + authenticateAuthUserRequestUnlinkIp(ipaddr); + + hash_entry = memPoolAlloc(auth_user_request_ip_pool); + hash_entry->ipaddr = ipaddr; + hash_entry->hash.key = &hash_entry->ipaddr; + hash_entry->auth_user_request = auth_user_request; + authenticateAuthUserRequestLock(hash_entry->auth_user_request); + hash_entry->last_seen = squid_curtime; + hash_join(auth_user_request_ip_hash, &hash_entry->hash); +} + +static auth_user_request_t * +authenticateAuthUserRequestFindByIp(const struct in_addr ipaddr) +{ + time_t delta = Config.authenticateIpShortcircuitTTL; + auth_user_request_ip_hash_t *hash_entry; + auth_user_request_t *auth_user_request = NULL; + + if (!auth_user_request_ip_hash) + return NULL; + + hash_entry = hash_lookup(auth_user_request_ip_hash, &ipaddr); + if (!hash_entry) + return NULL; + + auth_user_request = hash_entry->auth_user_request; + if (hash_entry->last_seen + delta < squid_curtime) { + authenticateAuthUserRequestUnlinkIp(ipaddr); + return NULL; + } + return hash_entry->auth_user_request; +} + static void authenticateAuthUserRequestSetIp(auth_user_request_t * auth_user_request, struct in_addr ipaddr) { @@ -290,6 +373,8 @@ } } + authenticateAuthUserRequestLinkIp(auth_user_request, ipaddr); + if (found) return; @@ -411,8 +496,12 @@ return request->auth_user_request; else if (conn && conn->auth_user_request) return conn->auth_user_request; - else - return NULL; + else { + request->auth_user_request = authenticateAuthUserRequestFindByIp(request->client_addr); + if (request->auth_user_request) + authenticateAuthUserRequestLock(request->auth_user_request); + return request->auth_user_request; + } } /* returns one of Index: squid/src/cf.data.pre =================================================================== RCS file: /cvsroot/squid-sf//squid/src/cf.data.pre,v retrieving revision 1.161 retrieving revision 1.161.8.1 diff -u -r1.161 -r1.161.8.1 --- squid/src/cf.data.pre 29 Nov 2006 00:52:57 -0000 1.161 +++ squid/src/cf.data.pre 19 Dec 2006 02:03:25 -0000 1.161.8.1 @@ -1,6 +1,6 @@ # -# $Id: cf.data.pre,v 1.161 2006/11/29 00:52:57 squidadm Exp $ +# $Id: cf.data.pre,v 1.161.8.1 2006/12/19 02:03:25 hno Exp $ # # # SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -2105,6 +2105,15 @@ corporate LAN environment with relatively static address assignments. DOC_END +NAME: authenticate_ip_shortcircuit_ttl +TYPE: time_t +LOC: Config.authenticateIpShortcircuitTTL +DEFAULT: 0 seconds +DOC_START + Cache authentication credentials per client IP address for this + long. Default is 0 seconds (disabled). +DOC_END + NAME: external_acl_type TYPE: externalAclHelper LOC: Config.externalAclHelperList Index: squid/src/structs.h =================================================================== RCS file: /cvsroot/squid-sf//squid/src/structs.h,v retrieving revision 1.136 retrieving revision 1.136.8.1 diff -u -r1.136 -r1.136.8.1 --- squid/src/structs.h 29 Nov 2006 16:52:51 -0000 1.136 +++ squid/src/structs.h 19 Dec 2006 02:03:26 -0000 1.136.8.1 @@ -1,6 +1,6 @@ /* - * $Id: structs.h,v 1.136 2006/11/29 16:52:51 squidadm Exp $ + * $Id: structs.h,v 1.136.8.1 2006/12/19 02:03:26 hno Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -568,6 +568,7 @@ time_t authenticateGCInterval; time_t authenticateTTL; time_t authenticateIpTTL; + time_t authenticateIpShortcircuitTTL; char *appendDomain; int appendDomainLen; char *debugOptions;