| Index: net/http/http_auth_controller.cc
|
| diff --git a/net/http/http_auth_controller.cc b/net/http/http_auth_controller.cc
|
| index f337c30b07738810297ebd4090bbe33af1eecda8..477478a49a9f30154916e0bee4db5a3e045cedf7 100644
|
| --- a/net/http/http_auth_controller.cc
|
| +++ b/net/http/http_auth_controller.cc
|
| @@ -316,53 +316,68 @@ int HttpAuthController::HandleAuthChallenge(
|
|
|
| bool can_send_auth = (target_ != HttpAuth::AUTH_SERVER ||
|
| !do_not_send_server_auth);
|
| - if (!handler_.get() && can_send_auth) {
|
| - // Find the best authentication challenge that we support.
|
| - HttpAuth::ChooseBestChallenge(http_auth_handler_factory_,
|
| - headers, target_, auth_origin_,
|
| - disabled_schemes_, net_log,
|
| - &handler_);
|
| - if (handler_.get())
|
| - HistogramAuthEvent(handler_.get(), AUTH_EVENT_START);
|
| - }
|
|
|
| - if (!handler_.get()) {
|
| - if (establishing_tunnel) {
|
| - LOG(ERROR) << "Can't perform auth to the "
|
| - << HttpAuth::GetAuthTargetString(target_) << " "
|
| - << auth_origin_ << " when establishing a tunnel"
|
| - << AuthChallengeLogMessage(headers.get());
|
| -
|
| - // We are establishing a tunnel, we can't show the error page because an
|
| - // active network attacker could control its contents. Instead, we just
|
| - // fail to establish the tunnel.
|
| - DCHECK(target_ == HttpAuth::AUTH_PROXY);
|
| - return ERR_PROXY_AUTH_UNSUPPORTED;
|
| + do {
|
| + if (!handler_.get() && can_send_auth) {
|
| + // Find the best authentication challenge that we support.
|
| + HttpAuth::ChooseBestChallenge(http_auth_handler_factory_,
|
| + headers, target_, auth_origin_,
|
| + disabled_schemes_, net_log,
|
| + &handler_);
|
| + if (handler_.get())
|
| + HistogramAuthEvent(handler_.get(), AUTH_EVENT_START);
|
| }
|
| - // We found no supported challenge -- let the transaction continue
|
| - // so we end up displaying the error page.
|
| - return OK;
|
| - }
|
|
|
| - if (handler_->NeedsIdentity()) {
|
| - // Pick a new auth identity to try, by looking to the URL and auth cache.
|
| - // If an identity to try is found, it is saved to identity_.
|
| - SelectNextAuthIdentityToTry();
|
| - } else {
|
| - // Proceed with the existing identity or a null identity.
|
| - identity_.invalid = false;
|
| - }
|
| + if (!handler_.get()) {
|
| + if (establishing_tunnel) {
|
| + LOG(ERROR) << "Can't perform auth to the "
|
| + << HttpAuth::GetAuthTargetString(target_) << " "
|
| + << auth_origin_ << " when establishing a tunnel"
|
| + << AuthChallengeLogMessage(headers.get());
|
| +
|
| + // We are establishing a tunnel, we can't show the error page because an
|
| + // active network attacker could control its contents. Instead, we just
|
| + // fail to establish the tunnel.
|
| + DCHECK(target_ == HttpAuth::AUTH_PROXY);
|
| + return ERR_PROXY_AUTH_UNSUPPORTED;
|
| + }
|
| + // We found no supported challenge -- let the transaction continue so we
|
| + // end up displaying the error page.
|
| + return OK;
|
| + }
|
|
|
| - // From this point on, we are restartable.
|
| + if (handler_->NeedsIdentity()) {
|
| + // Pick a new auth identity to try, by looking to the URL and auth cache.
|
| + // If an identity to try is found, it is saved to identity_.
|
| + SelectNextAuthIdentityToTry();
|
| + } else {
|
| + // Proceed with the existing identity or a null identity.
|
| + identity_.invalid = false;
|
| + }
|
|
|
| - if (identity_.invalid) {
|
| - // We have exhausted all identity possibilities, all we can do now is
|
| - // pass the challenge information back to the client.
|
| - PopulateAuthChallenge();
|
| - } else {
|
| - auth_info_ = NULL;
|
| - }
|
| + // From this point on, we are restartable.
|
| +
|
| + if (identity_.invalid) {
|
| + // We have exhausted all identity possibilities.
|
| + if (!handler_->AllowsExplicitCredentials()) {
|
| + // If the handler doesn't accept explicit credentials, then we need to
|
| + // choose a different auth scheme.
|
| + HistogramAuthEvent(handler_.get(), AUTH_EVENT_REJECT);
|
| + InvalidateCurrentHandler(INVALIDATE_HANDLER_AND_DISABLE_SCHEME);
|
| + } else {
|
| + // Pass the challenge information back to the client.
|
| + PopulateAuthChallenge();
|
| + }
|
| + } else {
|
| + auth_info_ = NULL;
|
| + }
|
|
|
| + // If we get here and we don't have a handler_, that's because we
|
| + // invalidated it due to not having any viable identities to use with it. Go
|
| + // back and try again.
|
| + // TODO(asanka): Instead we should create a priority list of
|
| + // <handler,identity> and iterate through that.
|
| + } while(!handler_.get());
|
| return OK;
|
| }
|
|
|
| @@ -419,9 +434,12 @@ bool HttpAuthController::HaveAuth() const {
|
| void HttpAuthController::InvalidateCurrentHandler(
|
| InvalidateHandlerAction action) {
|
| DCHECK(CalledOnValidThread());
|
| + DCHECK(handler_.get());
|
|
|
| if (action == INVALIDATE_HANDLER_AND_CACHED_CREDENTIALS)
|
| InvalidateRejectedAuthFromCache();
|
| + if (action == INVALIDATE_HANDLER_AND_DISABLE_SCHEME)
|
| + DisableAuthScheme(handler_->auth_scheme());
|
| handler_.reset();
|
| identity_ = HttpAuth::Identity();
|
| }
|
|
|