36
/* The functions in this file handle authentication.
37
* They DO NOT perform access control or auditing.
38
* See acl.c for access control and client_side.c for auditing */
40
acl_proxy_auth_user *auth_user;
42
} authenticateStateData;
44
static HLPCB authenticateHandleReply;
45
static void authenticateStateFree(authenticateStateData * r);
46
static helper *authenticators = NULL;
49
authenticateHandleReply(void *data, char *reply)
51
authenticateStateData *r = data;
54
debug(29, 5) ("authenticateHandleReply: {%s}\n", reply ? reply : "<NULL>");
56
if ((t = strchr(reply, ' ')))
61
valid = cbdataValid(r->data);
62
cbdataUnlock(r->data);
64
r->handler(r->data, reply);
65
authenticateStateFree(r);
69
authenticateStateFree(authenticateStateData * r)
75
authenticateStats(StoreEntry * sentry)
77
storeAppendPrintf(sentry, "Authenticator Statistics:\n");
78
helperStats(sentry, authenticators);
81
CBDATA_TYPE(authenticateStateData);
83
/**** PUBLIC FUNCTIONS ****/
87
authenticateStart(acl_proxy_auth_user * auth_user, RH * handler, void *data)
89
authenticateStateData *r = NULL;
44
authenticateDecodeAuth(const char *proxy_auth, auth_user_request_t * auth_user_request);
52
MemPool *auth_user_request_pool = NULL;
54
/* Generic Functions */
58
authenticateAuthSchemeConfigured(const char *proxy_auth)
62
for (i = 0; i < Config.authConfig.n_configured; i++) {
63
scheme = Config.authConfig.schemes + i;
64
if (strncasecmp(proxy_auth, scheme->typestr, strlen(scheme->typestr)) == 0)
71
authenticateAuthSchemeId(const char *typestr)
74
for (i = 0; authscheme_list && authscheme_list[i].typestr; i++) {
75
if (strncasecmp(typestr, authscheme_list[i].typestr, strlen(authscheme_list[i].typestr)) == 0) {
83
authenticateDecodeAuth(const char *proxy_auth, auth_user_request_t * auth_user_request)
86
assert(proxy_auth != NULL);
87
assert(auth_user_request != NULL); /* we need this created for us. */
88
debug(29, 9) ("authenticateDecodeAuth: header = '%s'\n", proxy_auth);
89
if (authenticateAuthSchemeConfigured(proxy_auth)) {
90
/* we're configured to use this scheme - but is it active ? */
91
if ((i = authenticateAuthSchemeId(proxy_auth)) != -1) {
92
authscheme_list[i].decodeauth(auth_user_request, proxy_auth);
93
auth_user_request->auth_user->auth_module = i + 1;
98
("authenticateDecodeAuth: Unsupported or unconfigured proxy-auth scheme, '%s'\n",
103
/* clear any connection related authentication details */
105
authenticateOnCloseConnection(ConnStateData * conn)
107
auth_user_request_t *auth_user_request;
108
assert(conn != NULL);
109
if (conn->auth_user_request != NULL) {
110
auth_user_request = conn->auth_user_request;
111
if (authscheme_list[auth_user_request->auth_user->auth_module - 1].oncloseconnection) {
112
authscheme_list[auth_user_request->auth_user->auth_module - 1].oncloseconnection(conn);
117
/**** PUBLIC FUNCTIONS (ALL GENERIC!) ****/
119
/* send the initial data to an authenticator module */
121
authenticateStart(auth_user_request_t * auth_user_request, RH * handler, void *data)
123
assert(auth_user_request);
93
debug(29, 5) ("authenticateStart: '%s:%s'\n", hashKeyStr(&auth_user->hash),
95
if (Config.Program.authenticate == NULL) {
125
debug(29, 9) ("authenticateStart: auth_user_request '%d'\n", auth_user_request);
126
if (auth_user_request->auth_user->auth_module > 0)
127
authscheme_list[auth_user_request->auth_user->auth_module - 1].authStart(auth_user_request, handler, data);
96
129
handler(data, NULL);
99
r = CBDATA_ALLOC(authenticateStateData, NULL);
100
r->handler = handler;
103
r->auth_user = auth_user;
104
snprintf(buf, 8192, "%s %s\n", hashKeyStr(&r->auth_user->hash),
105
r->auth_user->passwd);
106
helperSubmit(authenticators, buf, authenticateHandleReply, r);
110
authenticateInit(void)
113
if (!Config.Program.authenticate)
115
if (authenticators == NULL)
116
authenticators = helperCreate("authenticator");
117
authenticators->cmdline = Config.Program.authenticate;
118
authenticators->n_to_start = Config.authenticateChildren;
119
authenticators->ipc_type = IPC_TCP_SOCKET;
120
helperOpenServers(authenticators);
122
cachemgrRegister("authenticator",
123
"User Authenticator Stats",
124
authenticateStats, 0, 1);
127
CBDATA_INIT_TYPE(authenticateStateData);
133
* Check a auth_user pointer for validity. Does not check passwords, just data
134
* sensability. Broken or Unknown auth_types are not valid for use...
138
authenticateValidateUser(auth_user_request_t * auth_user_request)
140
debug(29, 9) ("authenticateValidateUser: Validating Auth_user request '%d'.\n", auth_user_request);
141
if (auth_user_request == NULL) {
142
debug(29, 4) ("authenticateValidateUser: Auth_user_request was NULL!\n");
145
if (auth_user_request->auth_user == NULL) {
146
debug(29, 4) ("authenticateValidateUser: No associated auth_user structure\n");
149
if (auth_user_request->auth_user->auth_type == AUTH_UNKNOWN) {
150
debug(29, 4) ("authenticateValidateUser: Auth_user '%d' uses unknown scheme.\n", auth_user_request->auth_user);
153
if (auth_user_request->auth_user->auth_type == AUTH_BROKEN) {
154
debug(29, 4) ("authenticateValidateUser: Auth_user '%d' is broken for it's scheme.\n", auth_user_request->auth_user);
157
/* any other sanity checks that we need in the future */
159
/* Thus should a module call to something like authValidate */
161
/* finally return ok */
162
debug(29, 4) ("authenticateValidateUser: Validated Auth_user request '%d'.\n", auth_user_request);
168
authenticateAuthUserNew(const char *scheme)
170
auth_user_t *temp_auth;
171
temp_auth = memAllocate(MEM_AUTH_USER_T);
172
assert(temp_auth != NULL);
173
temp_auth->auth_type = AUTH_UNKNOWN;
174
temp_auth->references = 0;
175
temp_auth->auth_module = authenticateAuthSchemeId(scheme) + 1;
179
auth_user_request_t *
180
authenticateAuthUserRequestNew()
182
auth_user_request_t *temp_request;
183
if (!auth_user_request_pool)
184
auth_user_request_pool = memPoolCreate("Authenticate Request Data", sizeof(auth_user_request_t));
185
temp_request = memPoolAlloc(auth_user_request_pool);
186
assert(temp_request != NULL);
187
temp_request->auth_user = NULL;
188
temp_request->message = NULL;
189
temp_request->scheme_data = NULL;
190
temp_request->references = 0;
195
authenticateAuthUserRequestFree(auth_user_request_t * auth_user_request)
198
debug(29, 5) ("authenticateAuthUserRequestFree: freeing request %d\n", auth_user_request);
199
if (!auth_user_request)
201
assert(auth_user_request->references == 0);
202
if (auth_user_request->auth_user) {
203
if (auth_user_request->scheme_data != NULL) {
204
/* we MUST know the module */
205
assert((auth_user_request->auth_user->auth_module > 0));
206
/* and the module MUST support requestFree if it has created scheme data */
207
assert(authscheme_list[auth_user_request->auth_user->auth_module - 1].requestFree != NULL);
208
authscheme_list[auth_user_request->auth_user->auth_module - 1].requestFree(auth_user_request);
210
/* unlink from the auth_user struct */
211
link = auth_user_request->auth_user->requests.head;
212
while (link && (link->data != auth_user_request))
214
assert(link != NULL);
215
dlinkDelete(link, &auth_user_request->auth_user->requests);
216
dlinkNodeDelete(link);
218
/* unlock the request structure's lock */
219
authenticateAuthUserUnlock(auth_user_request->auth_user);
220
auth_user_request->auth_user = NULL;
222
assert(auth_user_request->scheme_data == NULL);
223
if (auth_user_request->message)
224
xfree(auth_user_request->message);
228
authenticateAuthUserRequestMessage(auth_user_request_t * auth_user_request)
230
if (auth_user_request)
231
return auth_user_request->message;
236
authenticateAuthUserRequestSetIp(auth_user_request_t * auth_user_request, struct in_addr ipaddr)
238
if (auth_user_request->auth_user)
239
if (!auth_user_request->auth_user->ipaddr.s_addr)
240
auth_user_request->auth_user->ipaddr = ipaddr;
243
/* Get Auth User: Return a filled out auth_user structure for the given
244
* Proxy Auth (or Auth) header. It may be a cached Auth User or a new
245
* Unauthenticated structure. The structure is given an inital lock here.
247
auth_user_request_t *
248
authenticateGetAuthUser(const char *proxy_auth)
250
auth_user_request_t *auth_user_request = authenticateAuthUserRequestNew();
251
/* and lock for the callers instance */
252
authenticateAuthUserRequestLock(auth_user_request);
253
authenticateDecodeAuth(proxy_auth, auth_user_request);
254
return auth_user_request;
258
* authenticateUserAuthenticated: is this auth_user structure logged in ?
261
authenticateUserAuthenticated(auth_user_request_t * auth_user_request)
263
assert(authenticateValidateUser(auth_user_request));
264
if (auth_user_request->auth_user->auth_module > 0)
265
return authscheme_list[auth_user_request->auth_user->auth_module - 1].authenticated(auth_user_request);
271
* authenticateAuthenticateUser: log this user request in.
272
* Cache hits may change the auth_user pointer in the structure if needed.
273
* This is basically a handle approach.
276
authenticateAuthenticateUser(auth_user_request_t * auth_user_request, request_t * request, ConnStateData * conn, http_hdr_type type)
278
assert(auth_user_request != NULL);
279
if (auth_user_request->auth_user->auth_module > 0)
280
authscheme_list[auth_user_request->auth_user->auth_module - 1].authAuthenticate(auth_user_request, request, conn, type);
283
/* authenticateUserUsername: return a pointer to the username in the */
285
authenticateUserUsername(auth_user_t * auth_user)
289
if (auth_user->auth_module > 0)
290
return authscheme_list[auth_user->auth_module - 1].authUserUsername(auth_user);
294
/* authenticateUserRequestUsername: return a pointer to the username in the */
296
authenticateUserRequestUsername(auth_user_request_t * auth_user_request)
298
assert(auth_user_request != NULL);
299
return authenticateUserUsername(auth_user_request->auth_user);
303
* 0: no output needed
306
* -2: authenticate broken in some fashion
309
authenticateDirection(auth_user_request_t * auth_user_request)
311
if (!auth_user_request)
313
if (authenticateUserAuthenticated(auth_user_request))
315
if (auth_user_request->auth_user->auth_module > 0)
316
return authscheme_list[auth_user_request->auth_user->auth_module - 1].getdirection(auth_user_request);
321
authenticateActiveSchemeCount()
324
for (i = 0; authscheme_list && authscheme_list[i].typestr; i++)
325
if (authscheme_list[i].Active())
327
debug(29, 9) ("authenticateActiveSchemeCount: %d active.\n", rv);
332
authenticateSchemeCount()
335
for (i = 0; authscheme_list && authscheme_list[i].typestr; i++)
337
debug(29, 9) ("authenticateSchemeCount: %d active.\n", rv);
342
authenticateSchemeInit(void)
348
authenticateInit(authConfig * config)
352
for (i = 0; i < config->n_configured; i++) {
353
if (authscheme_list[i].init) {
354
scheme = config->schemes + i;
355
authscheme_list[i].init(scheme);
358
if (!proxy_auth_username_cache)
359
authenticateInitUserCache();
131
363
authenticateShutdown(void)
135
helperShutdown(authenticators);
138
helperFree(authenticators);
139
authenticators = NULL;
366
debug(29, 2) ("authenticateShutdown: shutting down auth schemes\n");
367
/* find the currently known authscheme types */
368
for (i = 0; authscheme_list && authscheme_list[i].typestr; i++) {
369
if (authscheme_list[i].donefunc != NULL)
370
authscheme_list[i].donefunc();
372
debug(29, 2) ("authenticateShutdown: scheme %s has not registered a shutdown function.\n", authscheme_list[i].typestr);
373
authscheme_list[i].typestr = NULL;
378
authenticateFixHeader(HttpReply * rep, auth_user_request_t * auth_user_request, request_t * request, int accelerated)
379
/* send the auth types we are configured to support (and have compiled in!) */
381
/* auth_type_t auth_type=err->auth_type;
382
* auth_state_t auth_state=err->auth_state;
383
* char *authchallenge=err->authchallenge;
384
* auth_user_request_t *auth_user_request=err->auth_user_request;
387
switch (rep->sline.status) {
388
case HTTP_PROXY_AUTHENTICATION_REQUIRED:
389
/* Proxy authorisation needed */
390
type = HDR_PROXY_AUTHENTICATE;
392
case HTTP_UNAUTHORIZED:
393
/* WWW Authorisation needed */
394
type = HDR_WWW_AUTHENTICATE;
398
/* some other HTTP status */
401
debug(29, 9) ("authenticateFixHeader: headertype:%d authuser:%d\n", type, auth_user_request);
402
if ((rep->sline.status == HTTP_PROXY_AUTHENTICATION_REQUIRED)
403
|| (rep->sline.status == HTTP_UNAUTHORIZED))
404
/* this is a authenticate-needed response */
406
if ((auth_user_request != NULL) && (auth_user_request->auth_user->auth_module > 0))
407
authscheme_list[auth_user_request->auth_user->auth_module - 1].authFixHeader(auth_user_request, rep, type, request);
411
/* call each configured authscheme */
412
for (i = 0; i < Config.authConfig.n_configured; i++) {
413
scheme = Config.authConfig.schemes + i;
414
if (authscheme_list[scheme->Id].Active())
415
authscheme_list[scheme->Id].authFixHeader(auth_user_request, rep, type,
418
debug(29, 4) ("authenticateFixHeader: Configured scheme %s not Active\n", scheme->typestr);
422
if ((auth_user_request != NULL) && (auth_user_request->auth_user->auth_module > 0)
423
&& (authscheme_list[auth_user_request->auth_user->auth_module - 1].AddHeader))
424
authscheme_list[auth_user_request->auth_user->auth_module - 1].AddHeader(auth_user_request, rep, accelerated);
427
/* call the active auth module and allow it to add a trailer to the request */
429
authenticateAddTrailer(HttpReply * rep, auth_user_request_t * auth_user_request, request_t * request, int accelerated)
431
if ((auth_user_request != NULL) && (auth_user_request->auth_user->auth_module > 0)
432
&& (authscheme_list[auth_user_request->auth_user->auth_module - 1].AddTrailer))
433
authscheme_list[auth_user_request->auth_user->auth_module - 1].AddTrailer(auth_user_request, rep, accelerated);
437
authenticateAuthUserLock(auth_user_t * auth_user)
439
debug(29, 9) ("authenticateAuthUserLock auth_user '%d'.\n", auth_user);
440
assert(auth_user != NULL);
441
auth_user->references++;
442
debug(29, 9) ("authenticateAuthUserLock auth_user '%d' now at '%d'.\n", auth_user, auth_user->references);
446
authenticateAuthUserUnlock(auth_user_t * auth_user)
448
debug(29, 9) ("authenticateAuthUserUnlock auth_user '%d'.\n", auth_user);
449
assert(auth_user != NULL);
450
if (auth_user->references > 0) {
451
auth_user->references--;
453
debug(29, 1) ("Attempt to lower Auth User %d refcount below 0!\n", auth_user);
455
debug(29, 9) ("authenticateAuthUserUnlock auth_user '%d' now at '%d'.\n", auth_user, auth_user->references);
456
if (auth_user->references == 0)
457
authenticateFreeProxyAuthUser(auth_user);
461
authenticateAuthUserRequestLock(auth_user_request_t * auth_user_request)
463
debug(29, 9) ("authenticateAuthUserRequestLock auth_user request '%d'.\n", auth_user_request);
464
assert(auth_user_request != NULL);
465
auth_user_request->references++;
466
debug(29, 9) ("authenticateAuthUserRequestLock auth_user request '%d' now at '%d'.\n", auth_user_request, auth_user_request->references);
470
authenticateAuthUserRequestUnlock(auth_user_request_t * auth_user_request)
472
debug(29, 9) ("authenticateAuthUserRequestUnlock auth_user request '%d'.\n", auth_user_request);
473
assert(auth_user_request != NULL);
474
if (auth_user_request->references > 0) {
475
auth_user_request->references--;
477
debug(29, 1) ("Attempt to lower Auth User request %d refcount below 0!\n", auth_user_request);
479
debug(29, 9) ("authenticateAuthUserRequestUnlock auth_user_request '%d' now at '%d'.\n", auth_user_request, auth_user_request->references);
480
if (auth_user_request->references == 0) {
481
/* not locked anymore */
482
authenticateAuthUserRequestFree(auth_user_request);
487
authenticateAuthUserInuse(auth_user_t * auth_user)
488
/* returns 0 for not in use */
490
assert(auth_user != NULL);
491
return auth_user->references;
494
/* Combine two user structs. ONLY to be called from within a scheme module.
495
* The scheme module is responsible for ensuring that the two users _can_ be merged
496
* without invalidating all the request scheme data.
497
* the scheme is also responsible for merging any user related scheme data itself. */
499
authenticateAuthUserMerge(auth_user_t * from, auth_user_t * to)
501
dlink_node *link, *tmplink;
502
auth_user_request_t *auth_user_request;
503
/* XXX combine two authuser structs. Incomplete: it should merge in hash references
504
* too and ask the module to merge in scheme data */
505
debug(29, 5) ("authenticateAuthUserMerge auth_user '%d' into auth_user '%d'.\n", from, to);
506
link = from->requests.head;
508
auth_user_request = link->data;
511
dlinkDelete(tmplink, &from->requests);
512
dlinkAddTail(auth_user_request, tmplink, &to->requests);
513
auth_user_request->auth_user = to;
515
to->references += from->references;
516
from->references = 0;
517
authenticateFreeProxyAuthUser(from);
521
authenticateFreeProxyAuthUser(void *data)
523
auth_user_t *u = data;
524
auth_user_request_t *auth_user_request;
526
auth_user_hash_pointer *proxy_auth_hash;
528
dlink_node *link, *tmplink;
529
assert(data != NULL);
530
debug(29, 5) ("authenticateFreeProxyAuthUser: Freeing auth_user '%d' with refcount '%d'.\n", u, u->references);
531
assert(u->references == 0);
532
/* were they linked in by username ? */
533
if (u->usernamehash) {
534
assert(u->usernamehash->auth_user == u);
535
debug(29, 5) ("authenticateFreeProxyAuthUser: removing usernamehash entry '%d'\n", u->usernamehash);
536
hash_remove_link(proxy_auth_username_cache,
537
(hash_link *) u->usernamehash);
538
/* don't free the key as we use the same user string as the auth_user
540
memFree(u->usernamehash, MEM_AUTH_USER_HASH);
542
/* remove any outstanding requests */
543
link = u->requests.head;
545
debug(29, 5) ("authenticateFreeProxyAuthUser: removing request entry '%d'\n", link->data);
546
auth_user_request = link->data;
549
dlinkDelete(tmplink, &u->requests);
550
dlinkNodeDelete(tmplink);
551
authenticateAuthUserRequestFree(auth_user_request);
553
/* free cached acl results */
554
aclCacheMatchFlush(&u->proxy_match_cache);
555
if (u->scheme_data && u->auth_module > 0)
556
authscheme_list[u->auth_module - 1].FreeUser(u);
557
/* prevent accidental reuse */
558
u->auth_type = AUTH_UNKNOWN;
559
memFree(u, MEM_AUTH_USER_T);
563
authenticateInitUserCache()
565
if (!proxy_auth_username_cache) {
566
/* First time around, 7921 should be big enough */
567
proxy_auth_username_cache =
568
hash_create((HASHCMP *) strcmp, 7921, hash_string);
569
assert(proxy_auth_username_cache);
570
eventAdd("User Cache Maintenance", authenticateProxyUserCacheCleanup, NULL, Config.authenticateGCInterval, 1);
575
authenticateProxyUserCacheCleanup(void *datanotused)
578
* We walk the hash by username as that is the unique key we use.
579
* For big hashs we could consider stepping through the cache, 100/200
580
* entries at a time. Lets see how it flys first.
582
auth_user_hash_pointer *usernamehash;
583
auth_user_t *auth_user;
584
char *username = NULL;
585
debug(29, 3) ("authenticateProxyUserCacheCleanup: Cleaning the user cache now\n");
586
debug(29, 3) ("authenticateProxyUserCacheCleanup: Current time: %d\n", current_time.tv_sec);
587
hash_first(proxy_auth_username_cache);
588
while ((usernamehash = ((auth_user_hash_pointer *) hash_next(proxy_auth_username_cache)))) {
589
auth_user = usernamehash->auth_user;
590
username = authenticateUserUsername(auth_user);
592
/* if we need to have inpedendent expiry clauses, insert a module call
594
debug(29, 4) ("authenticateProxyUserCacheCleanup: Cache entry:\n\tType: %d\n\tUsername: %s\n\texpires: %d\n\treferences: %d\n", auth_user->auth_type, username, auth_user->expiretime + Config.authenticateTTL, auth_user->references);
595
if (auth_user->expiretime + Config.authenticateTTL <= current_time.tv_sec) {
596
debug(29, 5) ("authenticateProxyUserCacheCleanup: Removing user %s from cache due to timeout.\n", username);
597
/* the minus 1 accounts for the cache lock */
598
if ((authenticateAuthUserInuse(auth_user) - 1))
599
debug(29, 4) ("authenticateProxyUserCacheCleanup: this cache entry has expired AND has a non-zero ref count.\n");
601
authenticateAuthUserUnlock(auth_user);
604
debug(29, 3) ("authenticateProxyUserCacheCleanup: Finished cleaning the user cache.\n");
605
eventAdd("User Cache Maintenance", authenticateProxyUserCacheCleanup, NULL, Config.authenticateGCInterval, 1);
609
* authenticateUserCacheRestart() cleans all config-dependent data from the
610
* auth_user cache. It DOES NOT Flush the user cache.
614
authenticateUserCacheRestart()
616
auth_user_hash_pointer *usernamehash;
617
auth_user_t *auth_user;
618
char *username = NULL;
619
debug(29, 3) ("authenticateUserCacheRestart: Clearing config dependent cache data.\n");
620
hash_first(proxy_auth_username_cache);
621
while ((usernamehash = ((auth_user_hash_pointer *) hash_next(proxy_auth_username_cache)))) {
622
auth_user = usernamehash->auth_user;
623
username = authenticateUserUsername(auth_user);
624
debug(29, 5) ("authenticateUserCacheRestat: Clearing cache ACL results for user: %s\n", username);
625
aclCacheMatchFlush(&auth_user->proxy_match_cache);
631
* called to add another auth scheme module
634
authSchemeAdd(char *type, AUTHSSETUP * setup)
637
/* find the number of currently known authscheme types */
638
for (i = 0; authscheme_list && authscheme_list[i].typestr; i++) {
639
assert(strcmp(authscheme_list[i].typestr, type) != 0);
641
/* add the new type */
642
authscheme_list = xrealloc(authscheme_list, (i + 2) * sizeof(authscheme_entry_t));
643
memset(&authscheme_list[i + 1], 0, sizeof(authscheme_entry_t));
644
authscheme_list[i].typestr = type;
645
/* Call the scheme module to set up capabilities and initialize any global data */
646
setup(&authscheme_list[i]);
651
/* UserNameCacheAdd: add a auth_user structure to the username cache */
653
authenticateUserNameCacheAdd(auth_user_t * auth_user)
655
auth_user_hash_pointer *usernamehash;
656
usernamehash = memAllocate(MEM_AUTH_USER_HASH);
657
usernamehash->key = authenticateUserUsername(auth_user);
658
usernamehash->auth_user = auth_user;
659
hash_join(proxy_auth_username_cache, (hash_link *) usernamehash);
660
auth_user->usernamehash = usernamehash;
661
/* lock for presence in the cache */
662
authenticateAuthUserLock(auth_user);
668
* check the user for ip changes timeouts
670
* 1 = ip requirements are ok.
673
* ip_expire data should be in a struct of it's own - for code reuse */
675
authenticateCheckAuthUserIP(struct in_addr request_src_addr, auth_user_request_t * auth_user_request)
677
char *username = authenticateUserRequestUsername(auth_user_request);
678
if (request_src_addr.s_addr == auth_user_request->auth_user->ipaddr.s_addr || auth_user_request->auth_user->ip_expiretime + Config.authenticateIpTTL <= squid_curtime) {
679
/* user has not moved ip or had the ip timeout expire */
680
if ((auth_user_request->auth_user->auth_type == AUTH_UNKNOWN) ||
681
(auth_user_request->auth_user->auth_type == AUTH_BROKEN)) {
682
debug(29, 1) ("authenticateCheckProxyAuthIP: broken or unknown auth type %d.\n", auth_user_request->auth_user->auth_type);
685
username = authenticateUserRequestUsername(auth_user_request);
687
auth_user_request->auth_user->ip_expiretime = squid_curtime;
688
auth_user_request->auth_user->ipaddr = request_src_addr;
691
char *ip1 = xstrdup(inet_ntoa(auth_user_request->auth_user->ipaddr));
692
char *ip2 = xstrdup(inet_ntoa(request_src_addr));
693
if (Config.onoff.authenticateIpTTLStrict) {
694
debug(29, 1) ("aclMatchProxyAuth: user '%s' tried to use multiple IP addresses! (%s, %s)\n ", username, ip1, ip2);
696
/* Non-strict mode. Reassign ownership to the new IP */
697
auth_user_request->auth_user->ipaddr.s_addr = request_src_addr.s_addr;
698
debug(29, 1) ("aclMatchProxyAuth: user '%s' has changed IP address (%s, %s)\n ", username, ip1, ip2);
702
/* and deny access */