]>
git.ipfire.org Git - thirdparty/squid.git/blob - src/auth/User.cc
bbdcfd51d39d58029b20c534bb8ccf34e95a2cfd
2 * Copyright (C) 1996-2016 The Squid Software Foundation and contributors
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
9 /* DEBUG: section 29 Authenticator */
13 #include "acl/Gadgets.h"
14 #include "auth/Config.h"
15 #include "auth/CredentialsCache.h"
16 #include "auth/Gadgets.h"
17 #include "auth/User.h"
18 #include "auth/UserRequest.h"
21 #include "SquidTime.h"
24 Auth::User::User(Auth::SchemeConfig
*aConfig
, const char *aRequestRealm
) :
25 auth_type(Auth::AUTH_UNKNOWN
),
29 credentials_state(Auth::Unchecked
),
31 requestRealm_(aRequestRealm
)
33 proxy_match_cache
.head
= proxy_match_cache
.tail
= NULL
;
34 ip_list
.head
= ip_list
.tail
= NULL
;
35 debugs(29, 5, HERE
<< "Initialised auth_user '" << this << "'.");
39 Auth::User::credentials() const
41 return credentials_state
;
45 Auth::User::credentials(CredentialState newCreds
)
47 credentials_state
= newCreds
;
51 * Combine two user structs. ONLY to be called from within a scheme
52 * module. The scheme module is responsible for ensuring that the
53 * two users _can_ be merged without invalidating all the request
54 * scheme data. The scheme is also responsible for merging any user
55 * related scheme data itself.
56 * The caller is responsible for altering all refcount pointers to
57 * the 'from' object. They are invalid once this method is complete.
60 Auth::User::absorb(Auth::User::Pointer from
)
63 * XXX Incomplete: it should merge in hash references too and ask the module to merge in scheme data
64 * dlink_list proxy_match_cache;
67 debugs(29, 5, HERE
<< "auth_user '" << from
<< "' into auth_user '" << this << "'.");
69 // combine the helper response annotations. Ensuring no duplicates are copied.
70 notes
.appendNewOnly(&from
->notes
);
72 /* absorb the list of IP address sources (for max_user_ip controls) */
73 AuthUserIP
*new_ipdata
;
74 while (from
->ip_list
.head
!= NULL
) {
75 new_ipdata
= static_cast<AuthUserIP
*>(from
->ip_list
.head
->data
);
77 /* If this IP has expired - ignore the expensive merge actions. */
78 if (new_ipdata
->ip_expiretime
<= squid_curtime
) {
79 /* This IP has expired - remove from the source list */
80 dlinkDelete(&new_ipdata
->node
, &(from
->ip_list
));
82 /* catch incipient underflow */
85 /* add to our list. replace if already present. */
86 AuthUserIP
*ipdata
= static_cast<AuthUserIP
*>(ip_list
.head
->data
);
89 AuthUserIP
*tempnode
= static_cast<AuthUserIP
*>(ipdata
->node
.next
->data
);
91 if (ipdata
->ipaddr
== new_ipdata
->ipaddr
) {
92 /* This IP has already been seen. */
94 /* update IP ttl and stop searching. */
95 ipdata
->ip_expiretime
= max(ipdata
->ip_expiretime
, new_ipdata
->ip_expiretime
);
97 } else if (ipdata
->ip_expiretime
<= squid_curtime
) {
98 /* This IP has expired - cleanup the destination list */
99 dlinkDelete(&ipdata
->node
, &ip_list
);
101 /* catch incipient underflow */
110 /* This ip is not in the seen list. Add it. */
111 dlinkAddTail(&new_ipdata
->node
, &ipdata
->node
, &ip_list
);
113 /* remove from the source list */
114 dlinkDelete(&new_ipdata
->node
, &(from
->ip_list
));
123 debugs(29, 5, HERE
<< "Freeing auth_user '" << this << "'.");
124 assert(LockCount() == 0);
126 /* free cached acl results */
127 aclCacheMatchFlush(&proxy_match_cache
);
129 /* free seen ip address's */
133 xfree((char*)username_
);
135 /* prevent accidental reuse */
136 auth_type
= Auth::AUTH_UNKNOWN
;
140 Auth::User::clearIp()
142 AuthUserIP
*ipdata
, *tempnode
;
144 ipdata
= (AuthUserIP
*) ip_list
.head
;
147 tempnode
= (AuthUserIP
*) ipdata
->node
.next
;
148 /* walk the ip list */
149 dlinkDelete(&ipdata
->node
, &ip_list
);
151 /* catch incipient underflow */
157 /* integrity check */
158 assert(ipcount
== 0);
162 Auth::User::removeIp(Ip::Address ipaddr
)
164 AuthUserIP
*ipdata
= (AuthUserIP
*) ip_list
.head
;
167 /* walk the ip list */
169 if (ipdata
->ipaddr
== ipaddr
) {
170 /* remove the node */
171 dlinkDelete(&ipdata
->node
, &ip_list
);
173 /* catch incipient underflow */
179 ipdata
= (AuthUserIP
*) ipdata
->node
.next
;
185 Auth::User::addIp(Ip::Address ipaddr
)
187 AuthUserIP
*ipdata
= (AuthUserIP
*) ip_list
.head
;
191 * we walk the entire list to prevent the first item in the list
192 * preventing old entries being flushed and locking a user out after
193 * a timeout+reconfigure
196 AuthUserIP
*tempnode
= (AuthUserIP
*) ipdata
->node
.next
;
197 /* walk the ip list */
199 if (ipdata
->ipaddr
== ipaddr
) {
200 /* This ip has already been seen. */
203 ipdata
->ip_expiretime
= squid_curtime
+ Auth::TheConfig
.ipTtl
;
204 } else if (ipdata
->ip_expiretime
<= squid_curtime
) {
205 /* This IP has expired - remove from the seen list */
206 dlinkDelete(&ipdata
->node
, &ip_list
);
208 /* catch incipient underflow */
219 /* This ip is not in the seen list */
220 ipdata
= new AuthUserIP(ipaddr
, squid_curtime
+ Auth::TheConfig
.ipTtl
);
222 dlinkAddTail(ipdata
, &ipdata
->node
, &ip_list
);
226 debugs(29, 2, HERE
<< "user '" << username() << "' has been seen at a new IP address (" << ipaddr
<< ")");
230 Auth::User::BuildUserKey(const char *username
, const char *realm
)
234 key
.Printf("%s:%s", username
, realm
);
236 key
.append(username
, strlen(username
));
241 * Dump the username cache statictics for viewing...
244 Auth::User::CredentialsCacheStats(StoreEntry
*output
)
246 auto userlist
= authenticateCachedUsersList();
247 storeAppendPrintf(output
, "Cached Usernames: %d", static_cast<int32_t>(userlist
.size()));
248 storeAppendPrintf(output
, "\n%-15s %-9s %-9s %-9s %s\t%s\n",
254 storeAppendPrintf(output
, "--------------- --------- --------- --------- ------------------------------\n");
255 for ( auto auth_user
: userlist
) {
256 storeAppendPrintf(output
, "%-15s %-9s %-9d %-9d %s\t" SQUIDSBUFPH
"\n",
257 Auth::Type_str
[auth_user
->auth_type
],
258 CredentialState_str
[auth_user
->credentials()],
260 static_cast<int32_t>(auth_user
->expiretime
- squid_curtime
+ Auth::TheConfig
.credentialsTtl
),
261 auth_user
->username(),
262 SQUIDSBUFPRINT(auth_user
->userKey())
268 Auth::User::username(char const *aString
)
272 username_
= xstrdup(aString
);
273 // NP: param #2 is working around a c_str() data-copy performance regression
274 userKey_
= BuildUserKey(username_
, (!requestRealm_
.isEmpty() ? requestRealm_
.c_str() : NULL
));
276 safe_free(username_
);