]>
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" |
616cfc4c AJ |
42 | #include "auth/basic/Scheme.h" |
43 | #include "auth/basic/UserRequest.h" | |
3ad63615 | 44 | #include "auth/Gadgets.h" |
a623c828 | 45 | #include "auth/State.h" |
25f98340 | 46 | #include "charset.h" |
8822ebee | 47 | #include "mgr/Registration.h" |
e6ccf245 | 48 | #include "Store.h" |
924f73bc | 49 | #include "HttpReply.h" |
1fa9b1a7 | 50 | #include "rfc1738.h" |
25f98340 | 51 | #include "uudecode.h" |
d295d770 | 52 | #include "wordlist.h" |
985c86bc | 53 | #include "SquidTime.h" |
94439e4e | 54 | |
94439e4e | 55 | /* Basic Scheme */ |
94439e4e | 56 | static HLPCB authenticateBasicHandleReply; |
94439e4e | 57 | static AUTHSSTATS authenticateBasicStats; |
94439e4e | 58 | |
59 | static helper *basicauthenticators = NULL; | |
60 | ||
94439e4e | 61 | static int authbasic_initialised = 0; |
94439e4e | 62 | |
2d72d4fd | 63 | |
94439e4e | 64 | /* |
65 | * | |
2d72d4fd | 66 | * Public Functions |
94439e4e | 67 | * |
68 | */ | |
69 | ||
2d72d4fd | 70 | /* internal functions */ |
71 | ||
f5691f9c | 72 | bool |
73 | AuthBasicConfig::active() const | |
2d70df72 | 74 | { |
f5691f9c | 75 | return authbasic_initialised == 1; |
2d70df72 | 76 | } |
77 | ||
f5691f9c | 78 | bool |
79 | AuthBasicConfig::configured() const | |
94439e4e | 80 | { |
58ee2093 | 81 | if ((authenticateProgram != NULL) && (authenticateChildren.n_max != 0) && |
f5691f9c | 82 | (basicAuthRealm != NULL)) { |
4c73ba5f | 83 | debugs(29, 9, HERE << "returning configured"); |
f5691f9c | 84 | return true; |
2d70df72 | 85 | } |
62e76326 | 86 | |
4c73ba5f | 87 | debugs(29, 9, HERE << "returning unconfigured"); |
f5691f9c | 88 | return false; |
94439e4e | 89 | } |
90 | ||
f5691f9c | 91 | const char * |
92 | AuthBasicConfig::type() const | |
94439e4e | 93 | { |
5817ee13 | 94 | return basicScheme::GetInstance()->type(); |
f5691f9c | 95 | } |
62e76326 | 96 | |
56a49fda AJ |
97 | int32_t |
98 | BasicUser::ttl() const | |
99 | { | |
d232141d | 100 | if (credentials() != Ok && credentials() != Pending) |
56a49fda AJ |
101 | return -1; // TTL is obsolete NOW. |
102 | ||
92bec429 | 103 | int32_t basic_ttl = expiretime - squid_curtime + static_cast<AuthBasicConfig*>(config)->credentialsTTL; |
56a49fda AJ |
104 | int32_t global_ttl = static_cast<int32_t>(expiretime - squid_curtime + Config.authenticateTTL); |
105 | ||
106 | return min(basic_ttl, global_ttl); | |
107 | } | |
108 | ||
f5691f9c | 109 | bool |
110 | BasicUser::authenticated() const | |
94439e4e | 111 | { |
d232141d | 112 | if ((credentials() == Ok) && (expiretime + static_cast<AuthBasicConfig*>(config)->credentialsTTL > squid_curtime)) |
f5691f9c | 113 | return true; |
114 | ||
bf8fe701 | 115 | debugs(29, 4, "User not authenticated or credentials need rechecking."); |
f5691f9c | 116 | |
117 | return false; | |
94439e4e | 118 | } |
62e76326 | 119 | |
94439e4e | 120 | void |
a33a428a | 121 | AuthBasicConfig::fixHeader(AuthUserRequest::Pointer auth_user_request, HttpReply *rep, http_hdr_type hdrType, HttpRequest * request) |
94439e4e | 122 | { |
58ee2093 | 123 | if (authenticateProgram) { |
18ec8500 FC |
124 | debugs(29, 9, HERE << "Sending type:" << hdrType << " header: 'Basic realm=\"" << basicAuthRealm << "\"'"); |
125 | httpHeaderPutStrf(&rep->header, hdrType, "Basic realm=\"%s\"", basicAuthRealm); | |
94439e4e | 126 | } |
127 | } | |
128 | ||
0bcb6908 AJ |
129 | void |
130 | AuthBasicConfig::rotateHelpers() | |
131 | { | |
132 | /* schedule closure of existing helpers */ | |
133 | if (basicauthenticators) { | |
134 | helperShutdown(basicauthenticators); | |
135 | } | |
136 | ||
137 | /* NP: dynamic helper restart will ensure they start up again as needed. */ | |
138 | } | |
139 | ||
5817ee13 | 140 | /** shutdown the auth helpers and free any allocated configuration details */ |
94439e4e | 141 | void |
f5691f9c | 142 | AuthBasicConfig::done() |
94439e4e | 143 | { |
5817ee13 AJ |
144 | authbasic_initialised = 0; |
145 | ||
146 | if (basicauthenticators) { | |
147 | helperShutdown(basicauthenticators); | |
5817ee13 AJ |
148 | } |
149 | ||
ed3ef6a8 AJ |
150 | delete basicauthenticators; |
151 | basicauthenticators = NULL; | |
152 | ||
58ee2093 AJ |
153 | if (authenticateProgram) |
154 | wordlistDestroy(&authenticateProgram); | |
62e76326 | 155 | |
f5691f9c | 156 | if (basicAuthRealm) |
157 | safe_free(basicAuthRealm); | |
94439e4e | 158 | } |
159 | ||
f5691f9c | 160 | BasicUser::~BasicUser() |
94439e4e | 161 | { |
4c73ba5f | 162 | safe_free(passwd); |
94439e4e | 163 | } |
164 | ||
165 | static void | |
166 | authenticateBasicHandleReply(void *data, char *reply) | |
167 | { | |
a623c828 | 168 | authenticateStateData *r = static_cast<authenticateStateData *>(data); |
e6ccf245 | 169 | BasicAuthQueueNode *tmpnode; |
94439e4e | 170 | char *t = NULL; |
fa80a8ef | 171 | void *cbdata; |
4c73ba5f | 172 | debugs(29, 9, HERE << "{" << (reply ? reply : "<NULL>") << "}"); |
62e76326 | 173 | |
94439e4e | 174 | if (reply) { |
62e76326 | 175 | if ((t = strchr(reply, ' '))) |
0a0c70cd | 176 | *t++ = '\0'; |
62e76326 | 177 | |
178 | if (*reply == '\0') | |
179 | reply = NULL; | |
94439e4e | 180 | } |
62e76326 | 181 | |
94439e4e | 182 | assert(r->auth_user_request != NULL); |
616cfc4c | 183 | assert(r->auth_user_request->user()->auth_type == Auth::AUTH_BASIC); |
56a49fda AJ |
184 | |
185 | /* this is okay since we only play with the BasicUser child fields below | |
186 | * and dont pass the pointer itself anywhere */ | |
187 | BasicUser *basic_auth = dynamic_cast<BasicUser *>(r->auth_user_request->user().getRaw()); | |
62e76326 | 188 | |
2948b229 | 189 | assert(basic_auth != NULL); |
190 | ||
94439e4e | 191 | if (reply && (strncasecmp(reply, "OK", 2) == 0)) |
d232141d | 192 | basic_auth->credentials(AuthUser::Ok); |
0a0c70cd | 193 | else { |
d232141d | 194 | basic_auth->credentials(AuthUser::Failed); |
62e76326 | 195 | |
0a0c70cd | 196 | if (t && *t) |
197 | r->auth_user_request->setDenyMessage(t); | |
198 | } | |
199 | ||
92bec429 | 200 | basic_auth->expiretime = squid_curtime; |
62e76326 | 201 | |
fa80a8ef | 202 | if (cbdataReferenceValidDone(r->data, &cbdata)) |
62e76326 | 203 | r->handler(cbdata, NULL); |
204 | ||
fa80a8ef | 205 | cbdataReferenceDone(r->data); |
62e76326 | 206 | |
f2afa96a | 207 | while (basic_auth->auth_queue) { |
62e76326 | 208 | tmpnode = basic_auth->auth_queue->next; |
209 | ||
210 | if (cbdataReferenceValidDone(basic_auth->auth_queue->data, &cbdata)) | |
211 | basic_auth->auth_queue->handler(cbdata, NULL); | |
212 | ||
213 | xfree(basic_auth->auth_queue); | |
214 | ||
215 | basic_auth->auth_queue = tmpnode; | |
94439e4e | 216 | } |
62e76326 | 217 | |
94439e4e | 218 | authenticateStateFree(r); |
219 | } | |
220 | ||
f5691f9c | 221 | void |
222 | AuthBasicConfig::dump(StoreEntry * entry, const char *name, AuthConfig * scheme) | |
94439e4e | 223 | { |
58ee2093 | 224 | wordlist *list = authenticateProgram; |
94439e4e | 225 | storeAppendPrintf(entry, "%s %s", name, "basic"); |
62e76326 | 226 | |
94439e4e | 227 | while (list != NULL) { |
62e76326 | 228 | storeAppendPrintf(entry, " %s", list->key); |
229 | list = list->next; | |
94439e4e | 230 | } |
62e76326 | 231 | |
07eca7e0 | 232 | storeAppendPrintf(entry, "\n"); |
233 | ||
f5691f9c | 234 | storeAppendPrintf(entry, "%s basic realm %s\n", name, basicAuthRealm); |
404cfda1 | 235 | 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 | 236 | storeAppendPrintf(entry, "%s basic credentialsttl %d seconds\n", name, (int) credentialsTTL); |
64658378 | 237 | storeAppendPrintf(entry, "%s basic casesensitive %s\n", name, casesensitive ? "on" : "off"); |
94439e4e | 238 | } |
239 | ||
5817ee13 | 240 | AuthBasicConfig::AuthBasicConfig() : |
5817ee13 AJ |
241 | credentialsTTL( 2*60*60 ), |
242 | casesensitive(0), | |
243 | utf8(0) | |
f5691f9c | 244 | { |
75126633 | 245 | basicAuthRealm = xstrdup("Squid proxy-caching web server"); |
f5691f9c | 246 | } |
62e76326 | 247 | |
3845e4c8 | 248 | AuthBasicConfig::~AuthBasicConfig() |
249 | { | |
acde4327 | 250 | safe_free(basicAuthRealm); |
3845e4c8 | 251 | } |
252 | ||
f5691f9c | 253 | void |
254 | AuthBasicConfig::parse(AuthConfig * scheme, int n_configured, char *param_str) | |
255 | { | |
94439e4e | 256 | if (strcasecmp(param_str, "program") == 0) { |
58ee2093 AJ |
257 | if (authenticateProgram) |
258 | wordlistDestroy(&authenticateProgram); | |
62e76326 | 259 | |
58ee2093 | 260 | parse_wordlist(&authenticateProgram); |
62e76326 | 261 | |
58ee2093 | 262 | requirePathnameExists("auth_param basic program", authenticateProgram->key); |
94439e4e | 263 | } else if (strcasecmp(param_str, "children") == 0) { |
48d54e4d | 264 | authenticateChildren.parseConfig(); |
94439e4e | 265 | } else if (strcasecmp(param_str, "realm") == 0) { |
f5691f9c | 266 | parse_eol(&basicAuthRealm); |
94439e4e | 267 | } else if (strcasecmp(param_str, "credentialsttl") == 0) { |
f5691f9c | 268 | parse_time_t(&credentialsTTL); |
64658378 | 269 | } else if (strcasecmp(param_str, "casesensitive") == 0) { |
270 | parse_onoff(&casesensitive); | |
f741d2f6 HN |
271 | } else if (strcasecmp(param_str, "utf8") == 0) { |
272 | parse_onoff(&utf8); | |
94439e4e | 273 | } else { |
4c73ba5f | 274 | debugs(29, DBG_CRITICAL, HERE << "unrecognised basic auth scheme parameter '" << param_str << "'"); |
94439e4e | 275 | } |
276 | } | |
277 | ||
278 | static void | |
279 | authenticateBasicStats(StoreEntry * sentry) | |
280 | { | |
9522b380 | 281 | helperStats(sentry, basicauthenticators, "Basic Authenticator Statistics"); |
94439e4e | 282 | } |
283 | ||
56a49fda | 284 | static AuthUser::Pointer |
94439e4e | 285 | authBasicAuthUserFindUsername(const char *username) |
286 | { | |
e6ccf245 | 287 | AuthUserHashPointer *usernamehash; |
e1f7507e | 288 | debugs(29, 9, HERE << "Looking for user '" << username << "'"); |
62e76326 | 289 | |
e6ccf245 | 290 | if (username && (usernamehash = static_cast<AuthUserHashPointer *>(hash_lookup(proxy_auth_username_cache, username)))) { |
62e76326 | 291 | while (usernamehash) { |
616cfc4c | 292 | if ((usernamehash->user()->auth_type == Auth::AUTH_BASIC) && |
62e76326 | 293 | !strcmp(username, (char const *)usernamehash->key)) |
f5691f9c | 294 | return usernamehash->user(); |
62e76326 | 295 | |
296 | usernamehash = static_cast<AuthUserHashPointer *>(usernamehash->next); | |
297 | } | |
94439e4e | 298 | } |
62e76326 | 299 | |
94439e4e | 300 | return NULL; |
301 | } | |
302 | ||
d232141d AJ |
303 | BasicUser::BasicUser(AuthConfig *aConfig) : |
304 | AuthUser(aConfig), | |
305 | passwd(NULL), | |
306 | auth_queue(NULL), | |
431aae42 | 307 | currentRequest(NULL) |
d232141d | 308 | {} |
62e76326 | 309 | |
431aae42 AJ |
310 | char * |
311 | AuthBasicConfig::decodeCleartext(const char *httpAuthHeader) | |
f5691f9c | 312 | { |
431aae42 | 313 | const char *proxy_auth = httpAuthHeader; |
acde4327 | 314 | |
431aae42 AJ |
315 | /* trim BASIC from string */ |
316 | while (xisgraph(*proxy_auth)) | |
317 | proxy_auth++; | |
62e76326 | 318 | |
431aae42 AJ |
319 | /* Trim leading whitespace before decoding */ |
320 | while (xisspace(*proxy_auth)) | |
321 | proxy_auth++; | |
94439e4e | 322 | |
431aae42 AJ |
323 | /* Trim trailing \n before decoding */ |
324 | // XXX: really? is the \n actually still there? does the header parse not drop it? | |
325 | char *eek = xstrdup(proxy_auth); | |
326 | strtok(eek, "\n"); | |
327 | char *cleartext = uudecode(eek); | |
328 | safe_free(eek); | |
329 | ||
330 | if (cleartext) { | |
331 | /* | |
332 | * Don't allow NL or CR in the credentials. | |
333 | * Oezguer Kesim <oec@codeblau.de> | |
334 | */ | |
335 | debugs(29, 9, HERE << "'" << cleartext << "'"); | |
336 | ||
337 | if (strcspn(cleartext, "\r\n") != strlen(cleartext)) { | |
338 | debugs(29, DBG_IMPORTANT, "WARNING: Bad characters in authorization header '" << httpAuthHeader << "'"); | |
339 | safe_free(cleartext); | |
666f0b34 | 340 | } |
35b3bc89 | 341 | } |
431aae42 | 342 | return cleartext; |
f5691f9c | 343 | } |
344 | ||
345 | bool | |
346 | BasicUser::valid() const | |
347 | { | |
147c7544 | 348 | if (username() == NULL) |
26ac0430 | 349 | return false; |
147c7544 | 350 | if (passwd == NULL) |
26ac0430 | 351 | return false; |
147c7544 | 352 | return true; |
f5691f9c | 353 | } |
94439e4e | 354 | |
f5691f9c | 355 | void |
356 | BasicUser::updateCached(BasicUser *from) | |
357 | { | |
56a49fda AJ |
358 | debugs(29, 9, HERE << "Found user '" << from->username() << "' already in the user cache as '" << this << "'"); |
359 | ||
360 | assert(strcmp(from->username(), username()) == 0); | |
f5691f9c | 361 | |
362 | if (strcmp(from->passwd, passwd)) { | |
4c73ba5f | 363 | debugs(29, 4, HERE << "new password found. Updating in user master record and resetting auth state to unchecked"); |
d232141d | 364 | credentials(Unchecked); |
f5691f9c | 365 | xfree(passwd); |
366 | passwd = from->passwd; | |
367 | from->passwd = NULL; | |
368 | } | |
369 | ||
d232141d | 370 | if (credentials() == Failed) { |
4c73ba5f | 371 | debugs(29, 4, HERE << "last attempt to authenticate this user failed, resetting auth state to unchecked"); |
d232141d | 372 | credentials(Unchecked); |
f5691f9c | 373 | } |
374 | } | |
375 | ||
4c73ba5f | 376 | /** |
f5691f9c | 377 | * Decode a Basic [Proxy-]Auth string, linking the passed |
378 | * auth_user_request structure to any existing user structure or creating one | |
26ac0430 AJ |
379 | * if needed. Note that just returning will be treated as |
380 | * "cannot decode credentials". Use the message field to return a | |
f5691f9c | 381 | * descriptive message to the user. |
382 | */ | |
a33a428a | 383 | AuthUserRequest::Pointer |
f5691f9c | 384 | AuthBasicConfig::decode(char const *proxy_auth) |
385 | { | |
928f3421 | 386 | AuthUserRequest::Pointer auth_user_request = dynamic_cast<AuthUserRequest*>(new AuthBasicUserRequest); |
f5691f9c | 387 | /* decode the username */ |
f5691f9c | 388 | |
431aae42 AJ |
389 | // retrieve the cleartext (in a dynamically allocated char*) |
390 | char *cleartext = decodeCleartext(proxy_auth); | |
f5691f9c | 391 | |
431aae42 AJ |
392 | // empty header? no auth details produced... |
393 | if (!cleartext) | |
394 | return auth_user_request; | |
f5691f9c | 395 | |
431aae42 AJ |
396 | AuthUser::Pointer lb; |
397 | /* permitted because local_basic is purely local function scope. */ | |
398 | BasicUser *local_basic = NULL; | |
399 | ||
400 | char *seperator = strchr(cleartext, ':'); | |
401 | ||
402 | lb = local_basic = new BasicUser(this); | |
403 | if (seperator == NULL) { | |
404 | local_basic->username(cleartext); | |
405 | } else { | |
406 | /* terminate the username */ | |
407 | *seperator = '\0'; | |
408 | local_basic->username(cleartext); | |
409 | local_basic->passwd = xstrdup(seperator+1); | |
410 | } | |
411 | ||
412 | if (!casesensitive) | |
413 | Tolower((char *)local_basic->username()); | |
414 | ||
415 | if (local_basic->passwd == NULL) { | |
416 | debugs(29, 4, HERE << "no password in proxy authorization header '" << proxy_auth << "'"); | |
417 | auth_user_request->setDenyMessage("no password was present in the HTTP [proxy-]authorization header. This is most likely a browser bug"); | |
418 | } else { | |
419 | if (local_basic->passwd[0] == '\0') { | |
420 | debugs(29, 4, HERE << "Disallowing empty password. User is '" << local_basic->username() << "'"); | |
421 | safe_free(local_basic->passwd); | |
422 | auth_user_request->setDenyMessage("Request denied because you provided an empty password. Users MUST have a password."); | |
423 | } | |
424 | } | |
f5691f9c | 425 | |
431aae42 | 426 | xfree(cleartext); |
f5691f9c | 427 | |
56a49fda | 428 | if (!local_basic->valid()) { |
616cfc4c | 429 | lb->auth_type = Auth::AUTH_BROKEN; |
431aae42 | 430 | auth_user_request->user(lb); |
f5691f9c | 431 | return auth_user_request; |
94439e4e | 432 | } |
62e76326 | 433 | |
3265364b | 434 | /* now lookup and see if we have a matching auth_user structure in memory. */ |
56a49fda AJ |
435 | AuthUser::Pointer auth_user; |
436 | ||
431aae42 | 437 | if ((auth_user = authBasicAuthUserFindUsername(lb->username())) == NULL) { |
56a49fda AJ |
438 | /* the user doesn't exist in the username cache yet */ |
439 | /* save the credentials */ | |
431aae42 | 440 | debugs(29, 9, HERE << "Creating new user '" << lb->username() << "'"); |
56a49fda | 441 | /* set the auth_user type */ |
616cfc4c | 442 | lb->auth_type = Auth::AUTH_BASIC; |
56a49fda | 443 | /* current time for timeouts */ |
431aae42 | 444 | lb->expiretime = current_time.tv_sec; |
56a49fda AJ |
445 | |
446 | /* this basic_user struct is the 'lucky one' to get added to the username cache */ | |
447 | /* the requests after this link to the basic_user */ | |
448 | /* store user in hash */ | |
431aae42 | 449 | lb->addToNameCache(); |
62e76326 | 450 | |
431aae42 | 451 | auth_user = lb; |
56a49fda | 452 | assert(auth_user != NULL); |
f5691f9c | 453 | } else { |
56a49fda AJ |
454 | /* replace the current cached password with the new one */ |
455 | BasicUser *basic_auth = dynamic_cast<BasicUser *>(auth_user.getRaw()); | |
3265364b | 456 | assert(basic_auth); |
56a49fda AJ |
457 | basic_auth->updateCached(local_basic); |
458 | auth_user = basic_auth; | |
f5691f9c | 459 | } |
62e76326 | 460 | |
f5691f9c | 461 | /* link the request to the in-cache user */ |
56a49fda | 462 | auth_user_request->user(auth_user); |
f5691f9c | 463 | return auth_user_request; |
94439e4e | 464 | } |
465 | ||
4c73ba5f | 466 | /** Initialize helpers and the like for this auth scheme. Called AFTER parsing the |
94439e4e | 467 | * config file */ |
f5691f9c | 468 | void |
5817ee13 | 469 | AuthBasicConfig::init(AuthConfig * schemeCfg) |
94439e4e | 470 | { |
58ee2093 | 471 | if (authenticateProgram) { |
62e76326 | 472 | authbasic_initialised = 1; |
473 | ||
474 | if (basicauthenticators == NULL) | |
48d54e4d | 475 | basicauthenticators = new helper("basicauthenticator"); |
62e76326 | 476 | |
58ee2093 | 477 | basicauthenticators->cmdline = authenticateProgram; |
62e76326 | 478 | |
48d54e4d | 479 | basicauthenticators->childs = authenticateChildren; |
07eca7e0 | 480 | |
62e76326 | 481 | basicauthenticators->ipc_type = IPC_STREAM; |
482 | ||
483 | helperOpenServers(basicauthenticators); | |
484 | ||
a623c828 | 485 | CBDATA_INIT_TYPE(authenticateStateData); |
94439e4e | 486 | } |
487 | } | |
488 | ||
62ee09ca | 489 | void |
15fab853 | 490 | AuthBasicConfig::registerWithCacheManager(void) |
62ee09ca | 491 | { |
8822ebee | 492 | Mgr::RegisterAction("basicauthenticator", |
d9fc6862 A |
493 | "Basic User Authenticator Stats", |
494 | authenticateBasicStats, 0, 1); | |
62ee09ca | 495 | } |
496 | ||
f5691f9c | 497 | void |
a33a428a | 498 | BasicUser::queueRequest(AuthUserRequest::Pointer auth_user_request, RH * handler, void *data) |
f5691f9c | 499 | { |
500 | BasicAuthQueueNode *node; | |
bf9066b0 | 501 | node = static_cast<BasicAuthQueueNode *>(xcalloc(1, sizeof(BasicAuthQueueNode))); |
f5691f9c | 502 | assert(node); |
503 | /* save the details */ | |
504 | node->next = auth_queue; | |
505 | auth_queue = node; | |
506 | node->auth_user_request = auth_user_request; | |
507 | node->handler = handler; | |
508 | node->data = cbdataReference(data); | |
509 | } | |
510 | ||
f5691f9c | 511 | void |
a33a428a | 512 | BasicUser::submitRequest(AuthUserRequest::Pointer auth_user_request, RH * handler, void *data) |
f5691f9c | 513 | { |
928f3421 | 514 | /* mark the user as having verification in progress */ |
d232141d | 515 | credentials(Pending); |
a623c828 | 516 | authenticateStateData *r = NULL; |
f5691f9c | 517 | char buf[8192]; |
518 | char user[1024], pass[1024]; | |
a623c828 | 519 | r = cbdataAlloc(authenticateStateData); |
f5691f9c | 520 | r->handler = handler; |
521 | r->data = cbdataReference(data); | |
522 | r->auth_user_request = auth_user_request; | |
5817ee13 | 523 | if (static_cast<AuthBasicConfig*>(config)->utf8) { |
26ac0430 AJ |
524 | latin1_to_utf8(user, sizeof(user), username()); |
525 | latin1_to_utf8(pass, sizeof(pass), passwd); | |
526 | xstrncpy(user, rfc1738_escape(user), sizeof(user)); | |
527 | xstrncpy(pass, rfc1738_escape(pass), sizeof(pass)); | |
f741d2f6 | 528 | } else { |
26ac0430 AJ |
529 | xstrncpy(user, rfc1738_escape(username()), sizeof(user)); |
530 | xstrncpy(pass, rfc1738_escape(passwd), sizeof(pass)); | |
f741d2f6 | 531 | } |
f5691f9c | 532 | snprintf(buf, sizeof(buf), "%s %s\n", user, pass); |
533 | helperSubmit(basicauthenticators, buf, authenticateBasicHandleReply, r); | |
534 | } |