OLD | NEW |
---|---|
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/http/http_auth_controller.h" | 5 #include "net/http/http_auth_controller.h" |
6 | 6 |
7 #include "base/metrics/histogram.h" | 7 #include "base/metrics/histogram.h" |
8 #include "base/string_util.h" | 8 #include "base/string_util.h" |
9 #include "base/threading/platform_thread.h" | 9 #include "base/threading/platform_thread.h" |
10 #include "base/utf_string_conversions.h" | 10 #include "base/utf_string_conversions.h" |
(...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
309 default: | 309 default: |
310 NOTREACHED(); | 310 NOTREACHED(); |
311 break; | 311 break; |
312 } | 312 } |
313 } | 313 } |
314 | 314 |
315 identity_.invalid = true; | 315 identity_.invalid = true; |
316 | 316 |
317 bool can_send_auth = (target_ != HttpAuth::AUTH_SERVER || | 317 bool can_send_auth = (target_ != HttpAuth::AUTH_SERVER || |
318 !do_not_send_server_auth); | 318 !do_not_send_server_auth); |
319 if (!handler_.get() && can_send_auth) { | |
320 // Find the best authentication challenge that we support. | |
321 HttpAuth::ChooseBestChallenge(http_auth_handler_factory_, | |
322 headers, target_, auth_origin_, | |
323 disabled_schemes_, net_log, | |
324 &handler_); | |
325 if (handler_.get()) | |
326 HistogramAuthEvent(handler_.get(), AUTH_EVENT_START); | |
327 } | |
328 | 319 |
329 if (!handler_.get()) { | 320 do { |
330 if (establishing_tunnel) { | 321 if (!handler_.get() && can_send_auth) { |
331 LOG(ERROR) << "Can't perform auth to the " | 322 // Find the best authentication challenge that we support. |
332 << HttpAuth::GetAuthTargetString(target_) << " " | 323 HttpAuth::ChooseBestChallenge(http_auth_handler_factory_, |
333 << auth_origin_ << " when establishing a tunnel" | 324 headers, target_, auth_origin_, |
334 << AuthChallengeLogMessage(headers.get()); | 325 disabled_schemes_, net_log, |
326 &handler_); | |
327 if (handler_.get()) | |
328 HistogramAuthEvent(handler_.get(), AUTH_EVENT_START); | |
329 } | |
335 | 330 |
336 // We are establishing a tunnel, we can't show the error page because an | 331 if (!handler_.get()) { |
337 // active network attacker could control its contents. Instead, we just | 332 if (establishing_tunnel) { |
338 // fail to establish the tunnel. | 333 LOG(ERROR) << "Can't perform auth to the " |
339 DCHECK(target_ == HttpAuth::AUTH_PROXY); | 334 << HttpAuth::GetAuthTargetString(target_) << " " |
340 return ERR_PROXY_AUTH_UNSUPPORTED; | 335 << auth_origin_ << " when establishing a tunnel" |
336 << AuthChallengeLogMessage(headers.get()); | |
337 | |
338 // We are establishing a tunnel, we can't show the error page because an | |
339 // active network attacker could control its contents. Instead, we just | |
340 // fail to establish the tunnel. | |
341 DCHECK(target_ == HttpAuth::AUTH_PROXY); | |
342 return ERR_PROXY_AUTH_UNSUPPORTED; | |
343 } | |
344 // We found no supported challenge -- let the transaction continue so we | |
345 // end up displaying the error page. | |
346 return OK; | |
341 } | 347 } |
342 // We found no supported challenge -- let the transaction continue | |
343 // so we end up displaying the error page. | |
344 return OK; | |
345 } | |
346 | 348 |
347 if (handler_->NeedsIdentity()) { | 349 if (handler_->NeedsIdentity()) { |
348 // Pick a new auth identity to try, by looking to the URL and auth cache. | 350 // Pick a new auth identity to try, by looking to the URL and auth cache. |
349 // If an identity to try is found, it is saved to identity_. | 351 // If an identity to try is found, it is saved to identity_. |
350 SelectNextAuthIdentityToTry(); | 352 SelectNextAuthIdentityToTry(); |
351 } else { | 353 } else { |
352 // Proceed with the existing identity or a null identity. | 354 // Proceed with the existing identity or a null identity. |
353 identity_.invalid = false; | 355 identity_.invalid = false; |
354 } | 356 } |
355 | 357 |
356 // From this point on, we are restartable. | 358 // From this point on, we are restartable. |
357 | 359 |
358 if (identity_.invalid) { | 360 if (identity_.invalid) { |
359 // We have exhausted all identity possibilities, all we can do now is | 361 // We have exhausted all identity possibilities. |
360 // pass the challenge information back to the client. | 362 if (!handler_->AllowsExplicitCredentials()) { |
361 PopulateAuthChallenge(); | 363 // If the handler doesn't accept explicit credentials, then we need to |
362 } else { | 364 // choose a different auth scheme. |
cbentzel
2011/08/30 14:19:39
May want to do HistogramAuthEvent(handler_.get(),
asanka
2011/08/30 18:55:44
Done.
| |
363 auth_info_ = NULL; | 365 InvalidateCurrentHandler(INVALIDATE_HANDLER_AND_DISABLE_SCHEME); |
364 } | 366 } else { |
367 // Pass the challenge information back to the client. | |
368 PopulateAuthChallenge(); | |
369 } | |
370 } else { | |
371 auth_info_ = NULL; | |
372 } | |
365 | 373 |
374 // If we get here and we don't have a handler_, that's because we | |
375 // invalidated it due to not having any viable identities to use with it. Go | |
376 // back and try again. | |
377 // TODO(asanka): Instead we should create a priority list of | |
378 // <handler,identity> and iterate through that. | |
379 } while(!handler_.get()); | |
366 return OK; | 380 return OK; |
367 } | 381 } |
368 | 382 |
369 void HttpAuthController::ResetAuth(const string16& username, | 383 void HttpAuthController::ResetAuth(const string16& username, |
370 const string16& password) { | 384 const string16& password) { |
371 DCHECK(CalledOnValidThread()); | 385 DCHECK(CalledOnValidThread()); |
372 DCHECK(identity_.invalid || (username.empty() && password.empty())); | 386 DCHECK(identity_.invalid || (username.empty() && password.empty())); |
373 | 387 |
374 if (identity_.invalid) { | 388 if (identity_.invalid) { |
375 // Update the username/password. | 389 // Update the username/password. |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
412 return handler_.get() != NULL; | 426 return handler_.get() != NULL; |
413 } | 427 } |
414 | 428 |
415 bool HttpAuthController::HaveAuth() const { | 429 bool HttpAuthController::HaveAuth() const { |
416 return handler_.get() && !identity_.invalid; | 430 return handler_.get() && !identity_.invalid; |
417 } | 431 } |
418 | 432 |
419 void HttpAuthController::InvalidateCurrentHandler( | 433 void HttpAuthController::InvalidateCurrentHandler( |
420 InvalidateHandlerAction action) { | 434 InvalidateHandlerAction action) { |
421 DCHECK(CalledOnValidThread()); | 435 DCHECK(CalledOnValidThread()); |
436 DCHECK(handler_.get()); | |
422 | 437 |
423 if (action == INVALIDATE_HANDLER_AND_CACHED_CREDENTIALS) | 438 if (action == INVALIDATE_HANDLER_AND_CACHED_CREDENTIALS) |
424 InvalidateRejectedAuthFromCache(); | 439 InvalidateRejectedAuthFromCache(); |
440 if (action == INVALIDATE_HANDLER_AND_DISABLE_SCHEME) | |
441 DisableAuthScheme(handler_->auth_scheme()); | |
425 handler_.reset(); | 442 handler_.reset(); |
426 identity_ = HttpAuth::Identity(); | 443 identity_ = HttpAuth::Identity(); |
427 } | 444 } |
428 | 445 |
429 void HttpAuthController::InvalidateRejectedAuthFromCache() { | 446 void HttpAuthController::InvalidateRejectedAuthFromCache() { |
430 DCHECK(CalledOnValidThread()); | 447 DCHECK(CalledOnValidThread()); |
431 DCHECK(HaveAuth()); | 448 DCHECK(HaveAuth()); |
432 | 449 |
433 // Clear the cache entry for the identity we just failed on. | 450 // Clear the cache entry for the identity we just failed on. |
434 // Note: we require the username/password to match before invalidating | 451 // Note: we require the username/password to match before invalidating |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
551 DCHECK(CalledOnValidThread()); | 568 DCHECK(CalledOnValidThread()); |
552 return disabled_schemes_.find(scheme) != disabled_schemes_.end(); | 569 return disabled_schemes_.find(scheme) != disabled_schemes_.end(); |
553 } | 570 } |
554 | 571 |
555 void HttpAuthController::DisableAuthScheme(HttpAuth::Scheme scheme) { | 572 void HttpAuthController::DisableAuthScheme(HttpAuth::Scheme scheme) { |
556 DCHECK(CalledOnValidThread()); | 573 DCHECK(CalledOnValidThread()); |
557 disabled_schemes_.insert(scheme); | 574 disabled_schemes_.insert(scheme); |
558 } | 575 } |
559 | 576 |
560 } // namespace net | 577 } // namespace net |
OLD | NEW |