]>
Commit | Line | Data |
---|---|---|
94439e4e | 1 | /* |
262a0e14 | 2 | * $Id$ |
94439e4e | 3 | * |
4 | * DEBUG: section 29 Authenticator | |
5 | * AUTHOR: Duane Wessels | |
6 | * | |
2b6662ba | 7 | * SQUID Web Proxy Cache http://www.squid-cache.org/ |
94439e4e | 8 | * ---------------------------------------------------------- |
9 | * | |
2b6662ba | 10 | * Squid is the result of efforts by numerous individuals from |
11 | * the Internet community; see the CONTRIBUTORS file for full | |
12 | * details. Many organizations have provided support for Squid's | |
13 | * development; see the SPONSORS file for full details. Squid is | |
14 | * Copyrighted (C) 2001 by the Regents of the University of | |
15 | * California; see the COPYRIGHT file for full details. Squid | |
16 | * incorporates software developed and/or copyrighted by other | |
17 | * sources; see the CREDITS file for full details. | |
94439e4e | 18 | * |
19 | * This program is free software; you can redistribute it and/or modify | |
20 | * it under the terms of the GNU General Public License as published by | |
21 | * the Free Software Foundation; either version 2 of the License, or | |
22 | * (at your option) any later version. | |
26ac0430 | 23 | * |
94439e4e | 24 | * This program is distributed in the hope that it will be useful, |
25 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
26 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
27 | * GNU General Public License for more details. | |
26ac0430 | 28 | * |
94439e4e | 29 | * You should have received a copy of the GNU General Public License |
30 | * along with this program; if not, write to the Free Software | |
31 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. | |
32 | * | |
33 | */ | |
34 | ||
35 | /* The functions in this file handle authentication. | |
36 | * They DO NOT perform access control or auditing. | |
37 | * See acl.c for access control and client_side.c for auditing */ | |
38 | ||
39 | ||
40 | #include "squid.h" | |
5817ee13 | 41 | #include "auth/basic/auth_basic.h" |
a623c828 | 42 | #include "auth/basic/basicScheme.h" |
928f3421 | 43 | #include "auth/basic/basicUserRequest.h" |
3ad63615 | 44 | #include "auth/Gadgets.h" |
a623c828 | 45 | #include "auth/State.h" |
62ee09ca | 46 | #include "CacheManager.h" |
e6ccf245 | 47 | #include "Store.h" |
924f73bc | 48 | #include "HttpReply.h" |
1fa9b1a7 | 49 | #include "rfc1738.h" |
d295d770 | 50 | #include "wordlist.h" |
985c86bc | 51 | #include "SquidTime.h" |
94439e4e | 52 | |
94439e4e | 53 | /* Basic Scheme */ |
94439e4e | 54 | static HLPCB authenticateBasicHandleReply; |
94439e4e | 55 | static AUTHSSTATS authenticateBasicStats; |
94439e4e | 56 | |
57 | static helper *basicauthenticators = NULL; | |
58 | ||
94439e4e | 59 | static int authbasic_initialised = 0; |
94439e4e | 60 | |
2d72d4fd | 61 | |
94439e4e | 62 | /* |
63 | * | |
2d72d4fd | 64 | * Public Functions |
94439e4e | 65 | * |
66 | */ | |
67 | ||
2d72d4fd | 68 | /* internal functions */ |
69 | ||
f5691f9c | 70 | bool |
71 | AuthBasicConfig::active() const | |
2d70df72 | 72 | { |
f5691f9c | 73 | return authbasic_initialised == 1; |
2d70df72 | 74 | } |
75 | ||
f5691f9c | 76 | bool |
77 | AuthBasicConfig::configured() const | |
94439e4e | 78 | { |
48d54e4d | 79 | if ((authenticate != NULL) && (authenticateChildren.n_max != 0) && |
f5691f9c | 80 | (basicAuthRealm != NULL)) { |
4c73ba5f | 81 | debugs(29, 9, HERE << "returning configured"); |
f5691f9c | 82 | return true; |
2d70df72 | 83 | } |
62e76326 | 84 | |
4c73ba5f | 85 | debugs(29, 9, HERE << "returning unconfigured"); |
f5691f9c | 86 | return false; |
94439e4e | 87 | } |
88 | ||
f5691f9c | 89 | const char * |
90 | AuthBasicConfig::type() const | |
94439e4e | 91 | { |
5817ee13 | 92 | return basicScheme::GetInstance()->type(); |
f5691f9c | 93 | } |
62e76326 | 94 | |
f5691f9c | 95 | |
96 | bool | |
97 | BasicUser::authenticated() const | |
94439e4e | 98 | { |
5817ee13 | 99 | if ((flags.credentials_ok == 1) && (credentials_checkedtime + static_cast<AuthBasicConfig*>(config)->credentialsTTL > squid_curtime)) |
f5691f9c | 100 | return true; |
101 | ||
bf8fe701 | 102 | debugs(29, 4, "User not authenticated or credentials need rechecking."); |
f5691f9c | 103 | |
104 | return false; | |
94439e4e | 105 | } |
62e76326 | 106 | |
94439e4e | 107 | void |
a33a428a | 108 | AuthBasicConfig::fixHeader(AuthUserRequest::Pointer auth_user_request, HttpReply *rep, http_hdr_type hdrType, HttpRequest * request) |
94439e4e | 109 | { |
f5691f9c | 110 | if (authenticate) { |
18ec8500 FC |
111 | debugs(29, 9, HERE << "Sending type:" << hdrType << " header: 'Basic realm=\"" << basicAuthRealm << "\"'"); |
112 | httpHeaderPutStrf(&rep->header, hdrType, "Basic realm=\"%s\"", basicAuthRealm); | |
94439e4e | 113 | } |
114 | } | |
115 | ||
5817ee13 | 116 | /** shutdown the auth helpers and free any allocated configuration details */ |
94439e4e | 117 | void |
f5691f9c | 118 | AuthBasicConfig::done() |
94439e4e | 119 | { |
5817ee13 AJ |
120 | authbasic_initialised = 0; |
121 | ||
122 | if (basicauthenticators) { | |
123 | helperShutdown(basicauthenticators); | |
5817ee13 AJ |
124 | } |
125 | ||
ed3ef6a8 AJ |
126 | delete basicauthenticators; |
127 | basicauthenticators = NULL; | |
128 | ||
f5691f9c | 129 | if (authenticate) |
130 | wordlistDestroy(&authenticate); | |
62e76326 | 131 | |
f5691f9c | 132 | if (basicAuthRealm) |
133 | safe_free(basicAuthRealm); | |
94439e4e | 134 | } |
135 | ||
f5691f9c | 136 | BasicUser::~BasicUser() |
94439e4e | 137 | { |
4c73ba5f AJ |
138 | safe_free(passwd); |
139 | safe_free(cleartext); | |
94439e4e | 140 | } |
141 | ||
142 | static void | |
143 | authenticateBasicHandleReply(void *data, char *reply) | |
144 | { | |
a623c828 | 145 | authenticateStateData *r = static_cast<authenticateStateData *>(data); |
e6ccf245 | 146 | BasicAuthQueueNode *tmpnode; |
94439e4e | 147 | char *t = NULL; |
fa80a8ef | 148 | void *cbdata; |
4c73ba5f | 149 | debugs(29, 9, HERE << "{" << (reply ? reply : "<NULL>") << "}"); |
62e76326 | 150 | |
94439e4e | 151 | if (reply) { |
62e76326 | 152 | if ((t = strchr(reply, ' '))) |
0a0c70cd | 153 | *t++ = '\0'; |
62e76326 | 154 | |
155 | if (*reply == '\0') | |
156 | reply = NULL; | |
94439e4e | 157 | } |
62e76326 | 158 | |
94439e4e | 159 | assert(r->auth_user_request != NULL); |
f5691f9c | 160 | assert(r->auth_user_request->user()->auth_type == AUTH_BASIC); |
161 | basic_data *basic_auth = dynamic_cast<basic_data *>(r->auth_user_request->user()); | |
62e76326 | 162 | |
2948b229 | 163 | assert(basic_auth != NULL); |
164 | ||
94439e4e | 165 | if (reply && (strncasecmp(reply, "OK", 2) == 0)) |
62e76326 | 166 | basic_auth->flags.credentials_ok = 1; |
0a0c70cd | 167 | else { |
62e76326 | 168 | basic_auth->flags.credentials_ok = 3; |
169 | ||
0a0c70cd | 170 | if (t && *t) |
171 | r->auth_user_request->setDenyMessage(t); | |
172 | } | |
173 | ||
94439e4e | 174 | basic_auth->credentials_checkedtime = squid_curtime; |
62e76326 | 175 | |
fa80a8ef | 176 | if (cbdataReferenceValidDone(r->data, &cbdata)) |
62e76326 | 177 | r->handler(cbdata, NULL); |
178 | ||
fa80a8ef | 179 | cbdataReferenceDone(r->data); |
62e76326 | 180 | |
f2afa96a | 181 | while (basic_auth->auth_queue) { |
62e76326 | 182 | tmpnode = basic_auth->auth_queue->next; |
183 | ||
184 | if (cbdataReferenceValidDone(basic_auth->auth_queue->data, &cbdata)) | |
185 | basic_auth->auth_queue->handler(cbdata, NULL); | |
186 | ||
187 | xfree(basic_auth->auth_queue); | |
188 | ||
189 | basic_auth->auth_queue = tmpnode; | |
94439e4e | 190 | } |
62e76326 | 191 | |
94439e4e | 192 | authenticateStateFree(r); |
193 | } | |
194 | ||
f5691f9c | 195 | void |
196 | AuthBasicConfig::dump(StoreEntry * entry, const char *name, AuthConfig * scheme) | |
94439e4e | 197 | { |
f5691f9c | 198 | wordlist *list = authenticate; |
94439e4e | 199 | storeAppendPrintf(entry, "%s %s", name, "basic"); |
62e76326 | 200 | |
94439e4e | 201 | while (list != NULL) { |
62e76326 | 202 | storeAppendPrintf(entry, " %s", list->key); |
203 | list = list->next; | |
94439e4e | 204 | } |
62e76326 | 205 | |
07eca7e0 | 206 | storeAppendPrintf(entry, "\n"); |
207 | ||
f5691f9c | 208 | storeAppendPrintf(entry, "%s basic realm %s\n", name, basicAuthRealm); |
404cfda1 | 209 | storeAppendPrintf(entry, "%s basic children %d startup=%d idle=%d concurrency=%d\n", name, authenticateChildren.n_max, authenticateChildren.n_startup, authenticateChildren.n_idle, authenticateChildren.concurrency); |
f5691f9c | 210 | storeAppendPrintf(entry, "%s basic credentialsttl %d seconds\n", name, (int) credentialsTTL); |
64658378 | 211 | storeAppendPrintf(entry, "%s basic casesensitive %s\n", name, casesensitive ? "on" : "off"); |
94439e4e | 212 | } |
213 | ||
5817ee13 | 214 | AuthBasicConfig::AuthBasicConfig() : |
ed3ef6a8 | 215 | authenticateChildren(20,0,1,1), |
5817ee13 AJ |
216 | authenticate(NULL), |
217 | credentialsTTL( 2*60*60 ), | |
218 | casesensitive(0), | |
219 | utf8(0) | |
f5691f9c | 220 | { |
75126633 | 221 | basicAuthRealm = xstrdup("Squid proxy-caching web server"); |
f5691f9c | 222 | } |
62e76326 | 223 | |
3845e4c8 | 224 | AuthBasicConfig::~AuthBasicConfig() |
225 | { | |
acde4327 | 226 | safe_free(basicAuthRealm); |
3845e4c8 | 227 | } |
228 | ||
f5691f9c | 229 | void |
230 | AuthBasicConfig::parse(AuthConfig * scheme, int n_configured, char *param_str) | |
231 | { | |
94439e4e | 232 | if (strcasecmp(param_str, "program") == 0) { |
f5691f9c | 233 | if (authenticate) |
234 | wordlistDestroy(&authenticate); | |
62e76326 | 235 | |
f5691f9c | 236 | parse_wordlist(&authenticate); |
62e76326 | 237 | |
42900318 | 238 | requirePathnameExists("auth_param basic program", authenticate->key); |
94439e4e | 239 | } else if (strcasecmp(param_str, "children") == 0) { |
48d54e4d | 240 | authenticateChildren.parseConfig(); |
94439e4e | 241 | } else if (strcasecmp(param_str, "realm") == 0) { |
f5691f9c | 242 | parse_eol(&basicAuthRealm); |
94439e4e | 243 | } else if (strcasecmp(param_str, "credentialsttl") == 0) { |
f5691f9c | 244 | parse_time_t(&credentialsTTL); |
64658378 | 245 | } else if (strcasecmp(param_str, "casesensitive") == 0) { |
246 | parse_onoff(&casesensitive); | |
f741d2f6 HN |
247 | } else if (strcasecmp(param_str, "utf8") == 0) { |
248 | parse_onoff(&utf8); | |
94439e4e | 249 | } else { |
4c73ba5f | 250 | debugs(29, DBG_CRITICAL, HERE << "unrecognised basic auth scheme parameter '" << param_str << "'"); |
94439e4e | 251 | } |
252 | } | |
253 | ||
254 | static void | |
255 | authenticateBasicStats(StoreEntry * sentry) | |
256 | { | |
9522b380 | 257 | helperStats(sentry, basicauthenticators, "Basic Authenticator Statistics"); |
94439e4e | 258 | } |
259 | ||
e1f7507e | 260 | static AuthUser * |
94439e4e | 261 | authBasicAuthUserFindUsername(const char *username) |
262 | { | |
e6ccf245 | 263 | AuthUserHashPointer *usernamehash; |
e1f7507e | 264 | debugs(29, 9, HERE << "Looking for user '" << username << "'"); |
62e76326 | 265 | |
e6ccf245 | 266 | if (username && (usernamehash = static_cast<AuthUserHashPointer *>(hash_lookup(proxy_auth_username_cache, username)))) { |
62e76326 | 267 | while (usernamehash) { |
f5691f9c | 268 | if ((usernamehash->user()->auth_type == AUTH_BASIC) && |
62e76326 | 269 | !strcmp(username, (char const *)usernamehash->key)) |
f5691f9c | 270 | return usernamehash->user(); |
62e76326 | 271 | |
272 | usernamehash = static_cast<AuthUserHashPointer *>(usernamehash->next); | |
273 | } | |
94439e4e | 274 | } |
62e76326 | 275 | |
94439e4e | 276 | return NULL; |
277 | } | |
278 | ||
f5691f9c | 279 | void |
280 | BasicUser::deleteSelf() const | |
281 | { | |
282 | delete this; | |
283 | } | |
94439e4e | 284 | |
18ec8500 | 285 | BasicUser::BasicUser(AuthConfig *aConfig) : AuthUser (aConfig) , passwd (NULL), credentials_checkedtime(0), auth_queue(NULL), cleartext (NULL), currentRequest (NULL), httpAuthHeader (NULL) |
f5691f9c | 286 | { |
287 | flags.credentials_ok = 0; | |
288 | } | |
62e76326 | 289 | |
35b3bc89 | 290 | bool |
f5691f9c | 291 | BasicUser::decodeCleartext() |
292 | { | |
acde4327 AJ |
293 | char *sent_auth = NULL; |
294 | ||
94439e4e | 295 | /* username and password */ |
f5691f9c | 296 | sent_auth = xstrdup(httpAuthHeader); |
acde4327 | 297 | |
94439e4e | 298 | /* Trim trailing \n before decoding */ |
299 | strtok(sent_auth, "\n"); | |
62e76326 | 300 | |
94439e4e | 301 | cleartext = uudecode(sent_auth); |
62e76326 | 302 | |
acde4327 AJ |
303 | safe_free(sent_auth); |
304 | ||
305 | if (!cleartext) | |
306 | return false; | |
62e76326 | 307 | |
94439e4e | 308 | /* |
309 | * Don't allow NL or CR in the credentials. | |
310 | * Oezguer Kesim <oec@codeblau.de> | |
311 | */ | |
4c73ba5f | 312 | debugs(29, 9, HERE << "'" << cleartext << "'"); |
62e76326 | 313 | |
36a04c15 | 314 | if (strcspn(cleartext, "\r\n") != strlen(cleartext)) { |
4c73ba5f | 315 | debugs(29, 1, HERE << "bad characters in authorization header '" << httpAuthHeader << "'"); |
147c7544 | 316 | safe_free(cleartext); |
317 | return false; | |
36a04c15 | 318 | } |
35b3bc89 | 319 | return true; |
320 | } | |
36a04c15 | 321 | |
35b3bc89 | 322 | void |
323 | BasicUser::extractUsername() | |
324 | { | |
acde4327 | 325 | char * seperator = strchr(cleartext, ':'); |
62e76326 | 326 | |
acde4327 AJ |
327 | if (seperator == NULL) { |
328 | username(cleartext); | |
329 | } else { | |
330 | /* terminate the username */ | |
331 | *seperator = '\0'; | |
332 | ||
333 | username(cleartext); | |
64658378 | 334 | |
acde4327 AJ |
335 | /* replace the colon so we can find the password */ |
336 | *seperator = ':'; | |
337 | } | |
411c6ea3 | 338 | |
5817ee13 | 339 | if (!static_cast<AuthBasicConfig*>(config)->casesensitive) |
64658378 | 340 | Tolower((char *)username()); |
f5691f9c | 341 | } |
62e76326 | 342 | |
f5691f9c | 343 | void |
344 | BasicUser::extractPassword() | |
345 | { | |
acde4327 | 346 | passwd = strchr(cleartext, ':'); |
62e76326 | 347 | |
acde4327 | 348 | if (passwd == NULL) { |
4c73ba5f | 349 | debugs(29, 4, HERE << "no password in proxy authorization header '" << httpAuthHeader << "'"); |
f5691f9c | 350 | passwd = NULL; |
4c73ba5f | 351 | currentRequest->setDenyMessage("no password was present in the HTTP [proxy-]authorization header. This is most likely a browser bug"); |
acde4327 AJ |
352 | } else { |
353 | ++passwd; | |
354 | if (*passwd == '\0') { | |
4c73ba5f | 355 | debugs(29, 4, HERE << "Disallowing empty password,user is '" << username() << "'"); |
acde4327 | 356 | passwd = NULL; |
4c73ba5f | 357 | currentRequest->setDenyMessage("Request denied because you provided an empty password. Users MUST have a password."); |
acde4327 AJ |
358 | } else { |
359 | passwd = xstrndup(passwd, USER_IDENT_SZ); | |
360 | } | |
94439e4e | 361 | } |
f5691f9c | 362 | } |
94439e4e | 363 | |
f5691f9c | 364 | void |
a33a428a | 365 | BasicUser::decode(char const *proxy_auth, AuthUserRequest::Pointer auth_user_request) |
f5691f9c | 366 | { |
367 | currentRequest = auth_user_request; | |
368 | httpAuthHeader = proxy_auth; | |
a33a428a | 369 | if (decodeCleartext()) { |
26ac0430 AJ |
370 | extractUsername(); |
371 | extractPassword(); | |
35b3bc89 | 372 | } |
f5691f9c | 373 | currentRequest = NULL; |
374 | httpAuthHeader = NULL; | |
375 | } | |
376 | ||
377 | bool | |
378 | BasicUser::valid() const | |
379 | { | |
147c7544 | 380 | if (username() == NULL) |
26ac0430 | 381 | return false; |
147c7544 | 382 | if (passwd == NULL) |
26ac0430 | 383 | return false; |
147c7544 | 384 | return true; |
f5691f9c | 385 | } |
94439e4e | 386 | |
f5691f9c | 387 | void |
a33a428a | 388 | BasicUser::makeLoggingInstance(AuthUserRequest::Pointer auth_user_request) |
f5691f9c | 389 | { |
390 | if (username()) { | |
391 | /* log the username */ | |
4c73ba5f | 392 | debugs(29, 9, HERE << "Creating new user for logging '" << username() << "'"); |
62e76326 | 393 | /* new scheme data */ |
5817ee13 | 394 | BasicUser *basic_auth = new BasicUser(config); |
f5691f9c | 395 | auth_user_request->user(basic_auth); |
62e76326 | 396 | /* save the credentials */ |
f5691f9c | 397 | basic_auth->username(username()); |
398 | username(NULL); | |
62e76326 | 399 | /* set the auth_user type */ |
f5691f9c | 400 | basic_auth->auth_type = AUTH_BROKEN; |
401 | /* link the request to the user */ | |
402 | basic_auth->addRequest(auth_user_request); | |
403 | } | |
404 | } | |
405 | ||
406 | AuthUser * | |
407 | BasicUser::makeCachedFrom() | |
408 | { | |
409 | /* the user doesn't exist in the username cache yet */ | |
4c73ba5f | 410 | debugs(29, 9, HERE << "Creating new user '" << username() << "'"); |
5817ee13 | 411 | BasicUser *basic_user = new BasicUser(config); |
f5691f9c | 412 | /* save the credentials */ |
413 | basic_user->username(username()); | |
414 | username(NULL); | |
415 | basic_user->passwd = passwd; | |
416 | passwd = NULL; | |
417 | /* set the auth_user type */ | |
418 | basic_user->auth_type = AUTH_BASIC; | |
419 | /* current time for timeouts */ | |
420 | basic_user->expiretime = current_time.tv_sec; | |
421 | ||
422 | /* this basic_user struct is the 'lucky one' to get added to the username cache */ | |
423 | /* the requests after this link to the basic_user */ | |
424 | /* store user in hash */ | |
425 | basic_user->addToNameCache(); | |
426 | return basic_user; | |
427 | } | |
428 | ||
429 | void | |
430 | BasicUser::updateCached(BasicUser *from) | |
431 | { | |
4c73ba5f | 432 | debugs(29, 9, HERE << "Found user '" << from->username() << "' in the user cache as '" << this << "'"); |
f5691f9c | 433 | |
434 | if (strcmp(from->passwd, passwd)) { | |
4c73ba5f | 435 | debugs(29, 4, HERE << "new password found. Updating in user master record and resetting auth state to unchecked"); |
f5691f9c | 436 | flags.credentials_ok = 0; |
437 | xfree(passwd); | |
438 | passwd = from->passwd; | |
439 | from->passwd = NULL; | |
440 | } | |
441 | ||
442 | if (flags.credentials_ok == 3) { | |
4c73ba5f | 443 | debugs(29, 4, HERE << "last attempt to authenticate this user failed, resetting auth state to unchecked"); |
f5691f9c | 444 | flags.credentials_ok = 0; |
445 | } | |
446 | } | |
447 | ||
4c73ba5f | 448 | /** |
f5691f9c | 449 | * Decode a Basic [Proxy-]Auth string, linking the passed |
450 | * auth_user_request structure to any existing user structure or creating one | |
26ac0430 AJ |
451 | * if needed. Note that just returning will be treated as |
452 | * "cannot decode credentials". Use the message field to return a | |
f5691f9c | 453 | * descriptive message to the user. |
454 | */ | |
a33a428a | 455 | AuthUserRequest::Pointer |
f5691f9c | 456 | AuthBasicConfig::decode(char const *proxy_auth) |
457 | { | |
928f3421 | 458 | AuthUserRequest::Pointer auth_user_request = dynamic_cast<AuthUserRequest*>(new AuthBasicUserRequest); |
f5691f9c | 459 | /* decode the username */ |
460 | /* trim BASIC from string */ | |
461 | ||
ba53f4b8 | 462 | while (xisgraph(*proxy_auth)) |
f5691f9c | 463 | proxy_auth++; |
464 | ||
5817ee13 | 465 | BasicUser *basic_auth, local_basic(this); |
f5691f9c | 466 | |
467 | /* Trim leading whitespace before decoding */ | |
468 | while (xisspace(*proxy_auth)) | |
469 | proxy_auth++; | |
470 | ||
471 | local_basic.decode(proxy_auth, auth_user_request); | |
472 | ||
473 | if (!local_basic.valid()) { | |
474 | local_basic.makeLoggingInstance(auth_user_request); | |
475 | return auth_user_request; | |
94439e4e | 476 | } |
62e76326 | 477 | |
f5691f9c | 478 | /* now lookup and see if we have a matching auth_user structure in |
479 | * memory. */ | |
62e76326 | 480 | |
e1f7507e | 481 | AuthUser *auth_user; |
62e76326 | 482 | |
f5691f9c | 483 | if ((auth_user = authBasicAuthUserFindUsername(local_basic.username())) == NULL) { |
484 | auth_user = local_basic.makeCachedFrom(); | |
485 | basic_auth = dynamic_cast<BasicUser *>(auth_user); | |
486 | assert (basic_auth); | |
487 | } else { | |
488 | basic_auth = dynamic_cast<BasicUser *>(auth_user); | |
489 | assert (basic_auth); | |
490 | basic_auth->updateCached (&local_basic); | |
491 | } | |
62e76326 | 492 | |
f5691f9c | 493 | /* link the request to the in-cache user */ |
494 | auth_user_request->user(basic_auth); | |
62e76326 | 495 | |
f5691f9c | 496 | basic_auth->addRequest(auth_user_request); |
497 | ||
498 | return auth_user_request; | |
94439e4e | 499 | } |
500 | ||
4c73ba5f | 501 | /** Initialize helpers and the like for this auth scheme. Called AFTER parsing the |
94439e4e | 502 | * config file */ |
f5691f9c | 503 | void |
5817ee13 | 504 | AuthBasicConfig::init(AuthConfig * schemeCfg) |
94439e4e | 505 | { |
f5691f9c | 506 | if (authenticate) { |
62e76326 | 507 | authbasic_initialised = 1; |
508 | ||
509 | if (basicauthenticators == NULL) | |
48d54e4d | 510 | basicauthenticators = new helper("basicauthenticator"); |
62e76326 | 511 | |
f5691f9c | 512 | basicauthenticators->cmdline = authenticate; |
62e76326 | 513 | |
48d54e4d | 514 | basicauthenticators->childs = authenticateChildren; |
07eca7e0 | 515 | |
62e76326 | 516 | basicauthenticators->ipc_type = IPC_STREAM; |
517 | ||
518 | helperOpenServers(basicauthenticators); | |
519 | ||
a623c828 | 520 | CBDATA_INIT_TYPE(authenticateStateData); |
94439e4e | 521 | } |
522 | } | |
523 | ||
62ee09ca | 524 | void |
15fab853 | 525 | AuthBasicConfig::registerWithCacheManager(void) |
62ee09ca | 526 | { |
15fab853 | 527 | CacheManager::GetInstance()-> |
26ac0430 AJ |
528 | registerAction("basicauthenticator", |
529 | "Basic User Authenticator Stats", | |
530 | authenticateBasicStats, 0, 1); | |
62ee09ca | 531 | } |
532 | ||
f5691f9c | 533 | void |
a33a428a | 534 | BasicUser::queueRequest(AuthUserRequest::Pointer auth_user_request, RH * handler, void *data) |
f5691f9c | 535 | { |
536 | BasicAuthQueueNode *node; | |
537 | node = static_cast<BasicAuthQueueNode *>(xmalloc(sizeof(BasicAuthQueueNode))); | |
538 | assert(node); | |
539 | /* save the details */ | |
540 | node->next = auth_queue; | |
541 | auth_queue = node; | |
542 | node->auth_user_request = auth_user_request; | |
543 | node->handler = handler; | |
544 | node->data = cbdataReference(data); | |
545 | } | |
546 | ||
f5691f9c | 547 | void |
a33a428a | 548 | BasicUser::submitRequest(AuthUserRequest::Pointer auth_user_request, RH * handler, void *data) |
f5691f9c | 549 | { |
928f3421 | 550 | /* mark the user as having verification in progress */ |
f5691f9c | 551 | flags.credentials_ok = 2; |
a623c828 | 552 | authenticateStateData *r = NULL; |
f5691f9c | 553 | char buf[8192]; |
554 | char user[1024], pass[1024]; | |
a623c828 | 555 | r = cbdataAlloc(authenticateStateData); |
f5691f9c | 556 | r->handler = handler; |
557 | r->data = cbdataReference(data); | |
558 | r->auth_user_request = auth_user_request; | |
5817ee13 | 559 | if (static_cast<AuthBasicConfig*>(config)->utf8) { |
26ac0430 AJ |
560 | latin1_to_utf8(user, sizeof(user), username()); |
561 | latin1_to_utf8(pass, sizeof(pass), passwd); | |
562 | xstrncpy(user, rfc1738_escape(user), sizeof(user)); | |
563 | xstrncpy(pass, rfc1738_escape(pass), sizeof(pass)); | |
f741d2f6 | 564 | } else { |
26ac0430 AJ |
565 | xstrncpy(user, rfc1738_escape(username()), sizeof(user)); |
566 | xstrncpy(pass, rfc1738_escape(passwd), sizeof(pass)); | |
f741d2f6 | 567 | } |
f5691f9c | 568 | snprintf(buf, sizeof(buf), "%s %s\n", user, pass); |
569 | helperSubmit(basicauthenticators, buf, authenticateBasicHandleReply, r); | |
570 | } |