Index: net/http/http_auth_handler_negotiate.cc |
diff --git a/net/http/http_auth_handler_negotiate.cc b/net/http/http_auth_handler_negotiate.cc |
deleted file mode 100644 |
index 557051cad6d551a2fa5a0c6afd38b553247c2cd4..0000000000000000000000000000000000000000 |
--- a/net/http/http_auth_handler_negotiate.cc |
+++ /dev/null |
@@ -1,343 +0,0 @@ |
-// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-#include "net/http/http_auth_handler_negotiate.h" |
- |
-#include "base/bind.h" |
-#include "base/bind_helpers.h" |
-#include "base/logging.h" |
-#include "base/profiler/scoped_tracker.h" |
-#include "base/strings/stringprintf.h" |
-#include "net/base/address_family.h" |
-#include "net/base/net_errors.h" |
-#include "net/dns/host_resolver.h" |
-#include "net/dns/single_request_host_resolver.h" |
-#include "net/http/http_auth_filter.h" |
-#include "net/http/url_security_manager.h" |
- |
-namespace net { |
- |
-HttpAuthHandlerNegotiate::Factory::Factory() |
- : disable_cname_lookup_(false), |
- use_port_(false), |
- resolver_(NULL), |
-#if defined(OS_WIN) |
- max_token_length_(0), |
- first_creation_(true), |
-#endif |
- is_unsupported_(false) { |
-} |
- |
-HttpAuthHandlerNegotiate::Factory::~Factory() { |
-} |
- |
-void HttpAuthHandlerNegotiate::Factory::set_host_resolver( |
- HostResolver* resolver) { |
- resolver_ = resolver; |
-} |
- |
-int HttpAuthHandlerNegotiate::Factory::CreateAuthHandler( |
- HttpAuthChallengeTokenizer* challenge, |
- HttpAuth::Target target, |
- const GURL& origin, |
- CreateReason reason, |
- int digest_nonce_count, |
- const BoundNetLog& net_log, |
- scoped_ptr<HttpAuthHandler>* handler) { |
-#if defined(OS_WIN) |
- if (is_unsupported_ || reason == CREATE_PREEMPTIVE) |
- return ERR_UNSUPPORTED_AUTH_SCHEME; |
- if (max_token_length_ == 0) { |
- int rv = DetermineMaxTokenLength(auth_library_.get(), NEGOSSP_NAME, |
- &max_token_length_); |
- if (rv == ERR_UNSUPPORTED_AUTH_SCHEME) |
- is_unsupported_ = true; |
- if (rv != OK) |
- return rv; |
- } |
- // TODO(cbentzel): Move towards model of parsing in the factory |
- // method and only constructing when valid. |
- scoped_ptr<HttpAuthHandler> tmp_handler( |
- new HttpAuthHandlerNegotiate(auth_library_.get(), max_token_length_, |
- url_security_manager(), resolver_, |
- disable_cname_lookup_, use_port_)); |
- if (!tmp_handler->InitFromChallenge(challenge, target, origin, net_log)) |
- return ERR_INVALID_RESPONSE; |
- handler->swap(tmp_handler); |
- return OK; |
-#elif defined(OS_POSIX) |
- if (is_unsupported_) |
- return ERR_UNSUPPORTED_AUTH_SCHEME; |
- if (!auth_library_->Init()) { |
- is_unsupported_ = true; |
- return ERR_UNSUPPORTED_AUTH_SCHEME; |
- } |
- // TODO(ahendrickson): Move towards model of parsing in the factory |
- // method and only constructing when valid. |
- scoped_ptr<HttpAuthHandler> tmp_handler( |
- new HttpAuthHandlerNegotiate(auth_library_.get(), url_security_manager(), |
- resolver_, disable_cname_lookup_, |
- use_port_)); |
- if (!tmp_handler->InitFromChallenge(challenge, target, origin, net_log)) |
- return ERR_INVALID_RESPONSE; |
- handler->swap(tmp_handler); |
- return OK; |
-#endif |
-} |
- |
-HttpAuthHandlerNegotiate::HttpAuthHandlerNegotiate( |
- AuthLibrary* auth_library, |
-#if defined(OS_WIN) |
- ULONG max_token_length, |
-#endif |
- URLSecurityManager* url_security_manager, |
- HostResolver* resolver, |
- bool disable_cname_lookup, |
- bool use_port) |
-#if defined(OS_WIN) |
- : auth_system_(auth_library, "Negotiate", NEGOSSP_NAME, max_token_length), |
-#elif defined(OS_POSIX) |
- : auth_system_(auth_library, "Negotiate", CHROME_GSS_SPNEGO_MECH_OID_DESC), |
-#endif |
- disable_cname_lookup_(disable_cname_lookup), |
- use_port_(use_port), |
- resolver_(resolver), |
- already_called_(false), |
- has_credentials_(false), |
- auth_token_(NULL), |
- next_state_(STATE_NONE), |
- url_security_manager_(url_security_manager) { |
-} |
- |
-HttpAuthHandlerNegotiate::~HttpAuthHandlerNegotiate() { |
-} |
- |
-std::string HttpAuthHandlerNegotiate::CreateSPN( |
- const AddressList& address_list, const GURL& origin) { |
- // Kerberos Web Server SPNs are in the form HTTP/<host>:<port> through SSPI, |
- // and in the form HTTP@<host>:<port> through GSSAPI |
- // http://msdn.microsoft.com/en-us/library/ms677601%28VS.85%29.aspx |
- // |
- // However, reality differs from the specification. A good description of |
- // the problems can be found here: |
- // http://blog.michelbarneveld.nl/michel/archive/2009/11/14/the-reason-why-kb911149-and-kb908209-are-not-the-soluton.aspx |
- // |
- // Typically the <host> portion should be the canonical FQDN for the service. |
- // If this could not be resolved, the original hostname in the URL will be |
- // attempted instead. However, some intranets register SPNs using aliases |
- // for the same canonical DNS name to allow multiple web services to reside |
- // on the same host machine without requiring different ports. IE6 and IE7 |
- // have hotpatches that allow the default behavior to be overridden. |
- // http://support.microsoft.com/kb/911149 |
- // http://support.microsoft.com/kb/938305 |
- // |
- // According to the spec, the <port> option should be included if it is a |
- // non-standard port (i.e. not 80 or 443 in the HTTP case). However, |
- // historically browsers have not included the port, even on non-standard |
- // ports. IE6 required a hotpatch and a registry setting to enable |
- // including non-standard ports, and IE7 and IE8 also require the same |
- // registry setting, but no hotpatch. Firefox does not appear to have an |
- // option to include non-standard ports as of 3.6. |
- // http://support.microsoft.com/kb/908209 |
- // |
- // Without any command-line flags, Chrome matches the behavior of Firefox |
- // and IE. Users can override the behavior so aliases are allowed and |
- // non-standard ports are included. |
- int port = origin.EffectiveIntPort(); |
- std::string server = address_list.canonical_name(); |
- if (server.empty()) |
- server = origin.host(); |
-#if defined(OS_WIN) |
- static const char kSpnSeparator = '/'; |
-#elif defined(OS_POSIX) |
- static const char kSpnSeparator = '@'; |
-#endif |
- if (port != 80 && port != 443 && use_port_) { |
- return base::StringPrintf("HTTP%c%s:%d", kSpnSeparator, server.c_str(), |
- port); |
- } else { |
- return base::StringPrintf("HTTP%c%s", kSpnSeparator, server.c_str()); |
- } |
-} |
- |
-HttpAuth::AuthorizationResult HttpAuthHandlerNegotiate::HandleAnotherChallenge( |
- HttpAuthChallengeTokenizer* challenge) { |
- return auth_system_.ParseChallenge(challenge); |
-} |
- |
-// Require identity on first pass instead of second. |
-bool HttpAuthHandlerNegotiate::NeedsIdentity() { |
- return auth_system_.NeedsIdentity(); |
-} |
- |
-bool HttpAuthHandlerNegotiate::AllowsDefaultCredentials() { |
- if (target_ == HttpAuth::AUTH_PROXY) |
- return true; |
- if (!url_security_manager_) |
- return false; |
- return url_security_manager_->CanUseDefaultCredentials(origin_); |
-} |
- |
-bool HttpAuthHandlerNegotiate::AllowsExplicitCredentials() { |
- return auth_system_.AllowsExplicitCredentials(); |
-} |
- |
-// The Negotiate challenge header looks like: |
-// WWW-Authenticate: NEGOTIATE auth-data |
-bool HttpAuthHandlerNegotiate::Init(HttpAuthChallengeTokenizer* challenge) { |
-#if defined(OS_POSIX) |
- if (!auth_system_.Init()) { |
- VLOG(1) << "can't initialize GSSAPI library"; |
- return false; |
- } |
- // GSSAPI does not provide a way to enter username/password to |
- // obtain a TGT. If the default credentials are not allowed for |
- // a particular site (based on whitelist), fall back to a |
- // different scheme. |
- if (!AllowsDefaultCredentials()) |
- return false; |
-#endif |
- if (CanDelegate()) |
- auth_system_.Delegate(); |
- auth_scheme_ = HttpAuth::AUTH_SCHEME_NEGOTIATE; |
- score_ = 4; |
- properties_ = ENCRYPTS_IDENTITY | IS_CONNECTION_BASED; |
- HttpAuth::AuthorizationResult auth_result = |
- auth_system_.ParseChallenge(challenge); |
- return (auth_result == HttpAuth::AUTHORIZATION_RESULT_ACCEPT); |
-} |
- |
-int HttpAuthHandlerNegotiate::GenerateAuthTokenImpl( |
- const AuthCredentials* credentials, const HttpRequestInfo* request, |
- const CompletionCallback& callback, std::string* auth_token) { |
- DCHECK(callback_.is_null()); |
- DCHECK(auth_token_ == NULL); |
- auth_token_ = auth_token; |
- if (already_called_) { |
- DCHECK((!has_credentials_ && credentials == NULL) || |
- (has_credentials_ && credentials->Equals(credentials_))); |
- next_state_ = STATE_GENERATE_AUTH_TOKEN; |
- } else { |
- already_called_ = true; |
- if (credentials) { |
- has_credentials_ = true; |
- credentials_ = *credentials; |
- } |
- next_state_ = STATE_RESOLVE_CANONICAL_NAME; |
- } |
- int rv = DoLoop(OK); |
- if (rv == ERR_IO_PENDING) |
- callback_ = callback; |
- return rv; |
-} |
- |
-void HttpAuthHandlerNegotiate::OnIOComplete(int result) { |
- // TODO(vadimt): Remove ScopedTracker below once crbug.com/436634 is fixed. |
- tracked_objects::ScopedTracker tracking_profile( |
- FROM_HERE_WITH_EXPLICIT_FUNCTION( |
- "436634 HttpAuthHandlerNegotiate::OnIOComplete")); |
- |
- int rv = DoLoop(result); |
- if (rv != ERR_IO_PENDING) |
- DoCallback(rv); |
-} |
- |
-void HttpAuthHandlerNegotiate::DoCallback(int rv) { |
- DCHECK(rv != ERR_IO_PENDING); |
- DCHECK(!callback_.is_null()); |
- CompletionCallback callback = callback_; |
- callback_.Reset(); |
- callback.Run(rv); |
-} |
- |
-int HttpAuthHandlerNegotiate::DoLoop(int result) { |
- DCHECK(next_state_ != STATE_NONE); |
- |
- int rv = result; |
- do { |
- State state = next_state_; |
- next_state_ = STATE_NONE; |
- switch (state) { |
- case STATE_RESOLVE_CANONICAL_NAME: |
- DCHECK_EQ(OK, rv); |
- rv = DoResolveCanonicalName(); |
- break; |
- case STATE_RESOLVE_CANONICAL_NAME_COMPLETE: |
- rv = DoResolveCanonicalNameComplete(rv); |
- break; |
- case STATE_GENERATE_AUTH_TOKEN: |
- DCHECK_EQ(OK, rv); |
- rv = DoGenerateAuthToken(); |
- break; |
- case STATE_GENERATE_AUTH_TOKEN_COMPLETE: |
- rv = DoGenerateAuthTokenComplete(rv); |
- break; |
- default: |
- NOTREACHED() << "bad state"; |
- rv = ERR_FAILED; |
- break; |
- } |
- } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE); |
- |
- return rv; |
-} |
- |
-int HttpAuthHandlerNegotiate::DoResolveCanonicalName() { |
- next_state_ = STATE_RESOLVE_CANONICAL_NAME_COMPLETE; |
- if (disable_cname_lookup_ || !resolver_) |
- return OK; |
- |
- // TODO(cbentzel): Add reverse DNS lookup for numeric addresses. |
- DCHECK(!single_resolve_.get()); |
- HostResolver::RequestInfo info(HostPortPair(origin_.host(), 0)); |
- info.set_host_resolver_flags(HOST_RESOLVER_CANONNAME); |
- single_resolve_.reset(new SingleRequestHostResolver(resolver_)); |
- return single_resolve_->Resolve( |
- info, |
- DEFAULT_PRIORITY, |
- &address_list_, |
- base::Bind(&HttpAuthHandlerNegotiate::OnIOComplete, |
- base::Unretained(this)), |
- net_log_); |
-} |
- |
-int HttpAuthHandlerNegotiate::DoResolveCanonicalNameComplete(int rv) { |
- DCHECK_NE(ERR_IO_PENDING, rv); |
- if (rv != OK) { |
- // Even in the error case, try to use origin_.host instead of |
- // passing the failure on to the caller. |
- VLOG(1) << "Problem finding canonical name for SPN for host " |
- << origin_.host() << ": " << ErrorToString(rv); |
- rv = OK; |
- } |
- |
- next_state_ = STATE_GENERATE_AUTH_TOKEN; |
- spn_ = CreateSPN(address_list_, origin_); |
- address_list_ = AddressList(); |
- return rv; |
-} |
- |
-int HttpAuthHandlerNegotiate::DoGenerateAuthToken() { |
- next_state_ = STATE_GENERATE_AUTH_TOKEN_COMPLETE; |
- AuthCredentials* credentials = has_credentials_ ? &credentials_ : NULL; |
- // TODO(cbentzel): This should possibly be done async. |
- return auth_system_.GenerateAuthToken(credentials, spn_, auth_token_); |
-} |
- |
-int HttpAuthHandlerNegotiate::DoGenerateAuthTokenComplete(int rv) { |
- DCHECK_NE(ERR_IO_PENDING, rv); |
- auth_token_ = NULL; |
- return rv; |
-} |
- |
-bool HttpAuthHandlerNegotiate::CanDelegate() const { |
- // TODO(cbentzel): Should delegation be allowed on proxies? |
- if (target_ == HttpAuth::AUTH_PROXY) |
- return false; |
- if (!url_security_manager_) |
- return false; |
- return url_security_manager_->CanDelegate(origin_); |
-} |
- |
-} // namespace net |