diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/http/http_auth.h | 90 | ||||
-rw-r--r-- | net/http/http_auth_handler.h | 12 | ||||
-rw-r--r-- | net/http/http_auth_handler_negotiate.h | 2 | ||||
-rw-r--r-- | net/http/http_auth_handler_negotiate_posix.cc | 2 | ||||
-rw-r--r-- | net/http/http_auth_handler_negotiate_win.cc | 13 | ||||
-rw-r--r-- | net/http/http_auth_handler_ntlm.h | 2 | ||||
-rw-r--r-- | net/http/http_auth_handler_ntlm_portable.cc | 2 | ||||
-rw-r--r-- | net/http/http_auth_handler_ntlm_win.cc | 23 | ||||
-rw-r--r-- | net/http/http_network_session.cc | 11 | ||||
-rw-r--r-- | net/http/http_network_session.h | 6 | ||||
-rw-r--r-- | net/http/http_network_transaction.cc | 90 | ||||
-rw-r--r-- | net/http/http_network_transaction.h | 9 | ||||
-rw-r--r-- | net/http/url_security_manager.h | 34 | ||||
-rw-r--r-- | net/http/url_security_manager_posix.cc | 25 | ||||
-rw-r--r-- | net/http/url_security_manager_win.cc | 101 | ||||
-rw-r--r-- | net/net.gyp | 3 |
16 files changed, 321 insertions, 104 deletions
diff --git a/net/http/http_auth.h b/net/http/http_auth.h index 76deca8..8d1ecc5 100644 --- a/net/http/http_auth.h +++ b/net/http/http_auth.h @@ -19,49 +19,53 @@ class HttpResponseHeaders; class HttpAuth { public: - // Http authentication can be done the the proxy server, origin server, - // or both. This enum tracks who the target is. - enum Target { - AUTH_NONE = -1, - // We depend on the valid targets (!= AUTH_NONE) being usable as indexes - // in an array, so start from 0. - AUTH_PROXY = 0, - AUTH_SERVER = 1, - }; - - // Describes where the identity used for authentication came from. - enum IdentitySource { - // Came from nowhere -- the identity is not initialized. - IDENT_SRC_NONE, - - // The identity came from the auth cache, by doing a path-based - // lookup (premptive authorization). - IDENT_SRC_PATH_LOOKUP, - - // The identity was extracted from a URL of the form: - // http://<username>:<password>@host:port - IDENT_SRC_URL, - - // The identity was retrieved from the auth cache, by doing a - // realm lookup. - IDENT_SRC_REALM_LOOKUP, - - // The identity was provided by RestartWithAuth -- it likely - // came from a prompt (or maybe the password manager). - IDENT_SRC_EXTERNAL, - }; - - // Helper structure used by HttpNetworkTransaction to track - // the current identity being used for authorization. - struct Identity { - Identity() : source(IDENT_SRC_NONE), invalid(true) { } - - IdentitySource source; - bool invalid; - // TODO(wtc): |username| and |password| should be string16. - std::wstring username; - std::wstring password; - }; + // Http authentication can be done the the proxy server, origin server, + // or both. This enum tracks who the target is. + enum Target { + AUTH_NONE = -1, + // We depend on the valid targets (!= AUTH_NONE) being usable as indexes + // in an array, so start from 0. + AUTH_PROXY = 0, + AUTH_SERVER = 1, + }; + + // Describes where the identity used for authentication came from. + enum IdentitySource { + // Came from nowhere -- the identity is not initialized. + IDENT_SRC_NONE, + + // The identity came from the auth cache, by doing a path-based + // lookup (premptive authorization). + IDENT_SRC_PATH_LOOKUP, + + // The identity was extracted from a URL of the form: + // http://<username>:<password>@host:port + IDENT_SRC_URL, + + // The identity was retrieved from the auth cache, by doing a + // realm lookup. + IDENT_SRC_REALM_LOOKUP, + + // The identity was provided by RestartWithAuth -- it likely + // came from a prompt (or maybe the password manager). + IDENT_SRC_EXTERNAL, + + // The identity used the default credentials for the computer, + // on schemes that support single sign-on. + IDENT_SRC_DEFAULT_CREDENTIALS, + }; + + // Helper structure used by HttpNetworkTransaction to track + // the current identity being used for authorization. + struct Identity { + Identity() : source(IDENT_SRC_NONE), invalid(true) { } + + IdentitySource source; + bool invalid; + // TODO(wtc): |username| and |password| should be string16. + std::wstring username; + std::wstring password; + }; // Get the name of the header containing the auth challenge // (either WWW-Authenticate or Proxy-Authenticate). diff --git a/net/http/http_auth_handler.h b/net/http/http_auth_handler.h index dc0543e..d2eae13 100644 --- a/net/http/http_auth_handler.h +++ b/net/http/http_auth_handler.h @@ -74,10 +74,12 @@ class HttpAuthHandler : public base::RefCounted<HttpAuthHandler> { // single-round schemes. virtual bool IsFinalRound() { return true; } - // Returns whether the default credentials may be used for the |origin| passed - // into |InitFromChallenge|. If true, the user does not need to be prompted - // for username and password to establish credentials. - virtual bool AllowDefaultCredentials() { return false; } + // Returns whether the authentication scheme supports the use of default + // credentials. If true, the user does not need to be prompted for + // username and password to establish credentials. + // NOTE: SSO is a potential security risk. + // TODO(cbentzel): Add a pointer to Firefox documentation about risk. + virtual bool SupportsDefaultCredentials() { return false; } // TODO(cbentzel): Separate providing credentials from generating the // authentication token in the API. @@ -96,7 +98,7 @@ class HttpAuthHandler : public base::RefCounted<HttpAuthHandler> { // The return value is an error code. If the code is not |OK|, the value of // |*auth_token| is unspecified. // |auth_token| is a return value and must be non-NULL. - // This should only be called after |AllowDefaultCredentials| returns true. + // This should only be called if |SupportsDefaultCredentials| returns true. virtual int GenerateDefaultAuthToken(const HttpRequestInfo* request, const ProxyInfo* proxy, std::string* auth_token) = 0; diff --git a/net/http/http_auth_handler_negotiate.h b/net/http/http_auth_handler_negotiate.h index 4577d9c..f34664c 100644 --- a/net/http/http_auth_handler_negotiate.h +++ b/net/http/http_auth_handler_negotiate.h @@ -65,7 +65,7 @@ class HttpAuthHandlerNegotiate : public HttpAuthHandler { virtual bool IsFinalRound(); - virtual bool AllowDefaultCredentials(); + virtual bool SupportsDefaultCredentials(); virtual int GenerateAuthToken(const std::wstring& username, const std::wstring& password, diff --git a/net/http/http_auth_handler_negotiate_posix.cc b/net/http/http_auth_handler_negotiate_posix.cc index ab69267..2b96597 100644 --- a/net/http/http_auth_handler_negotiate_posix.cc +++ b/net/http/http_auth_handler_negotiate_posix.cc @@ -31,7 +31,7 @@ bool HttpAuthHandlerNegotiate::IsFinalRound() { return false; } -bool HttpAuthHandlerNegotiate::AllowDefaultCredentials() { +bool HttpAuthHandlerNegotiate::SupportsDefaultCredentials() { NOTREACHED(); LOG(ERROR) << ErrorToString(ERR_NOT_IMPLEMENTED); return false; diff --git a/net/http/http_auth_handler_negotiate_win.cc b/net/http/http_auth_handler_negotiate_win.cc index c09beb0..d710c69 100644 --- a/net/http/http_auth_handler_negotiate_win.cc +++ b/net/http/http_auth_handler_negotiate_win.cc @@ -51,17 +51,8 @@ bool HttpAuthHandlerNegotiate::IsFinalRound() { return auth_sspi_.IsFinalRound(); } -bool HttpAuthHandlerNegotiate::AllowDefaultCredentials() { - // NOTE: Temporarily disabled. SSO is a potential security risk. - // TODO(cbentzel): Add a pointer to Firefox documentation about risk. - - // TODO(cbentzel): Add a blanket command line flag to enable/disable? - // TODO(cbentzel): Add a whitelist regexp command line flag? - // TODO(cbentzel): Resolve the origin_ (helpful if doing already) and see if - // it is in private IP space? - // TODO(cbentzel): Compare origin_ to this machine's hostname and allow if - // it matches at least two or three layers deep? - return false; +bool HttpAuthHandlerNegotiate::SupportsDefaultCredentials() { + return true; } int HttpAuthHandlerNegotiate::GenerateDefaultAuthToken( diff --git a/net/http/http_auth_handler_ntlm.h b/net/http/http_auth_handler_ntlm.h index aebb5c4..542bf92 100644 --- a/net/http/http_auth_handler_ntlm.h +++ b/net/http/http_auth_handler_ntlm.h @@ -103,7 +103,7 @@ class HttpAuthHandlerNTLM : public HttpAuthHandler { virtual bool IsFinalRound(); - virtual bool AllowDefaultCredentials(); + virtual bool SupportsDefaultCredentials(); virtual int GenerateAuthToken(const std::wstring& username, const std::wstring& password, diff --git a/net/http/http_auth_handler_ntlm_portable.cc b/net/http/http_auth_handler_ntlm_portable.cc index 6cbf16a..5872131 100644 --- a/net/http/http_auth_handler_ntlm_portable.cc +++ b/net/http/http_auth_handler_ntlm_portable.cc @@ -658,7 +658,7 @@ bool HttpAuthHandlerNTLM::IsFinalRound() { return !auth_data_.empty(); } -bool HttpAuthHandlerNTLM::AllowDefaultCredentials() { +bool HttpAuthHandlerNTLM::SupportsDefaultCredentials() { // Default credentials are not supported in the portable implementation of // NTLM, but are supported in the SSPI implementation. return false; diff --git a/net/http/http_auth_handler_ntlm_win.cc b/net/http/http_auth_handler_ntlm_win.cc index 2de3411..2aa9c0d 100644 --- a/net/http/http_auth_handler_ntlm_win.cc +++ b/net/http/http_auth_handler_ntlm_win.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 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. @@ -36,17 +36,8 @@ bool HttpAuthHandlerNTLM::IsFinalRound() { return auth_sspi_.IsFinalRound(); } -bool HttpAuthHandlerNTLM::AllowDefaultCredentials() { - // NOTE: Temporarily disabled. SSO is a potential security risk with NTLM. - // TODO(cbentzel): Add a pointer to Firefox documentation about risk. - - // TODO(cbentzel): Add a blanket command line flag to enable/disable? - // TODO(cbentzel): Add a whitelist regexp command line flag? - // TODO(cbentzel): Resolve the origin_ (helpful if doing already) and see if - // it is in private IP space? - // TODO(cbentzel): Compare origin_ to this machine's hostname and allow if - // it matches at least two or three layers deep? - return false; +bool HttpAuthHandlerNTLM::SupportsDefaultCredentials() { + return true; } int HttpAuthHandlerNTLM::GenerateDefaultAuthToken( @@ -54,16 +45,16 @@ int HttpAuthHandlerNTLM::GenerateDefaultAuthToken( const ProxyInfo* proxy, std::string* auth_token) { return auth_sspi_.GenerateAuthToken( - NULL, // username - NULL, // password + NULL, // username + NULL, // password origin_, request, proxy, auth_token); } -HttpAuthHandlerNTLM::Factory::Factory() : - max_token_length_(0), +HttpAuthHandlerNTLM::Factory::Factory() + : max_token_length_(0), first_creation_(true), is_unsupported_(false), sspi_library_(SSPILibrary::GetDefault()) { diff --git a/net/http/http_network_session.cc b/net/http/http_network_session.cc index d7dbe94..66b7854 100644 --- a/net/http/http_network_session.cc +++ b/net/http/http_network_session.cc @@ -6,6 +6,7 @@ #include "base/logging.h" #include "net/http/http_auth_handler_factory.h" +#include "net/http/url_security_manager.h" #include "net/spdy/spdy_session_pool.h" namespace net { @@ -54,6 +55,14 @@ HttpNetworkSession::HttpNetworkSession( HttpNetworkSession::~HttpNetworkSession() { } +URLSecurityManager* HttpNetworkSession::GetURLSecurityManager() { + // Create the URL security manager lazily in the first call. + // This is called on a single thread. + if (!url_security_manager_.get()) + url_security_manager_.reset(URLSecurityManager::Create()); + return url_security_manager_.get(); +} + // static void HttpNetworkSession::set_max_sockets_per_group(int socket_count) { DCHECK(0 < socket_count); @@ -73,4 +82,4 @@ void HttpNetworkSession::ReplaceTCPSocketPool() { network_change_notifier_); } -} // namespace net +} // namespace net diff --git a/net/http/http_network_session.h b/net/http/http_network_session.h index 5b2cb97..fcfaac4 100644 --- a/net/http/http_network_session.h +++ b/net/http/http_network_session.h @@ -6,6 +6,7 @@ #define NET_HTTP_HTTP_NETWORK_SESSION_H_ #include "base/ref_counted.h" +#include "base/scoped_ptr.h" #include "net/base/host_resolver.h" #include "net/base/ssl_client_auth_cache.h" #include "net/base/ssl_config_service.h" @@ -21,6 +22,7 @@ class ClientSocketFactory; class HttpAuthHandlerFactory; class SpdySessionPool; class NetworkChangeNotifier; +class URLSecurityManager; // This class holds session objects used by HttpNetworkTransaction objects. class HttpNetworkSession : public base::RefCounted<HttpNetworkSession> { @@ -65,6 +67,9 @@ class HttpNetworkSession : public base::RefCounted<HttpNetworkSession> { return http_auth_handler_factory_; } + // Returns a pointer to the URL security manager. + URLSecurityManager* GetURLSecurityManager(); + // Replace the current socket pool with a new one. This effectively // abandons the current pool. This is only used for debugging. void ReplaceTCPSocketPool(); @@ -106,6 +111,7 @@ class HttpNetworkSession : public base::RefCounted<HttpNetworkSession> { scoped_refptr<SSLConfigService> ssl_config_service_; scoped_refptr<SpdySessionPool> spdy_session_pool_; HttpAuthHandlerFactory* http_auth_handler_factory_; + scoped_ptr<URLSecurityManager> url_security_manager_; }; } // namespace net diff --git a/net/http/http_network_transaction.cc b/net/http/http_network_transaction.cc index 218f26d..57cf773 100644 --- a/net/http/http_network_transaction.cc +++ b/net/http/http_network_transaction.cc @@ -29,6 +29,7 @@ #include "net/http/http_response_headers.h" #include "net/http/http_response_info.h" #include "net/http/http_util.h" +#include "net/http/url_security_manager.h" #include "net/socket/client_socket_factory.h" #include "net/socket/socks_client_socket_pool.h" #include "net/socket/ssl_client_socket.h" @@ -219,6 +220,7 @@ HttpNetworkTransaction::HttpNetworkTransaction(HttpNetworkSession* session) using_spdy_(false), alternate_protocol_mode_(kUnspecified), embedded_identity_used_(false), + default_credentials_used_(false), read_buf_len_(0), next_state_(STATE_NONE) { session->ssl_config_service()->GetSSLConfig(&ssl_config_); @@ -335,20 +337,25 @@ void HttpNetworkTransaction::PrepareForAuthRestart(HttpAuth::Target target) { // to know about it. If an entry for (origin, handler->realm()) already // exists, we update it. // - // If auth_identity_[target].source is HttpAuth::IDENT_SRC_NONE, - // auth_identity_[target] contains no identity because identity is not - // required yet. + // If auth_identity_[target].source is HttpAuth::IDENT_SRC_NONE or + // HttpAuth::IDENT_SRC_DEFAULT_CREDENTIALS, auth_identity_[target] contains + // no identity because identity is not required yet or we're using default + // credentials. // // TODO(wtc): For NTLM_SSPI, we add the same auth entry to the cache in // round 1 and round 2, which is redundant but correct. It would be nice // to add an auth entry to the cache only once, preferrably in round 1. // See http://crbug.com/21015. - bool has_auth_identity = - auth_identity_[target].source != HttpAuth::IDENT_SRC_NONE; - if (has_auth_identity) { - session_->auth_cache()->Add(AuthOrigin(target), auth_handler_[target], - auth_identity_[target].username, auth_identity_[target].password, - AuthPath(target)); + switch (auth_identity_[target].source) { + case HttpAuth::IDENT_SRC_NONE: + case HttpAuth::IDENT_SRC_DEFAULT_CREDENTIALS: + break; + default: + session_->auth_cache()->Add( + AuthOrigin(target), auth_handler_[target], + auth_identity_[target].username, auth_identity_[target].password, + AuthPath(target)); + break; } bool keep_alive = false; @@ -1610,12 +1617,17 @@ std::string HttpNetworkTransaction::BuildAuthorizationHeader( // Add a Authorization/Proxy-Authorization header line. std::string auth_token; - int rv = auth_handler_[target]->GenerateAuthToken( - auth_identity_[target].username, - auth_identity_[target].password, - request_, - &proxy_info_, - &auth_token); + int rv; + if (auth_identity_[target].source == + HttpAuth::IDENT_SRC_DEFAULT_CREDENTIALS) { + rv = auth_handler_[target]->GenerateDefaultAuthToken( + request_, &proxy_info_, &auth_token); + } else { + rv = auth_handler_[target]->GenerateAuthToken( + auth_identity_[target].username, + auth_identity_[target].password, + request_, &proxy_info_, &auth_token); + } if (rv == OK) return HttpAuth::GetAuthorizationHeaderName(target) + ": " + auth_token + "\r\n"; @@ -1694,9 +1706,25 @@ bool HttpNetworkTransaction::SelectPreemptiveAuth(HttpAuth::Target target) { auth_handler_[target] = entry->handler(); return true; } + + // TODO(cbentzel): Preemptively use default credentials if they have worked + // for the origin/path in the past to save a round trip. + return false; } +bool HttpNetworkTransaction::CanUseDefaultCredentials( + HttpAuth::Target target, + const GURL& auth_origin) const { + if (target == HttpAuth::AUTH_PROXY) + return true; + + URLSecurityManager* security_manager = session_->GetURLSecurityManager(); + if (!security_manager) + return false; + return security_manager->CanUseDefaultCredentials(auth_origin); +} + bool HttpNetworkTransaction::SelectNextAuthIdentityToTry( HttpAuth::Target target, const GURL& auth_origin) { @@ -1733,19 +1761,33 @@ bool HttpNetworkTransaction::SelectNextAuthIdentityToTry( // is the same realm that we have a cached identity for. However if // we use that identity, it would get sent over the wire in // clear text (which isn't what the user agreed to when entering it). - if (entry->handler()->scheme() != auth_handler_[target]->scheme()) { - LOG(WARNING) << "The scheme of realm " << auth_handler_[target]->realm() - << " has changed from " << entry->handler()->scheme() - << " to " << auth_handler_[target]->scheme(); - return false; + if (entry->handler()->scheme() == auth_handler_[target]->scheme()) { + auth_identity_[target].source = HttpAuth::IDENT_SRC_REALM_LOOKUP; + auth_identity_[target].invalid = false; + auth_identity_[target].username = entry->username(); + auth_identity_[target].password = entry->password(); + return true; } - - auth_identity_[target].source = HttpAuth::IDENT_SRC_REALM_LOOKUP; + LOG(WARNING) << "The scheme of realm " << auth_handler_[target]->realm() + << " has changed from " << entry->handler()->scheme() + << " to " << auth_handler_[target]->scheme(); + // Fall through. + } + + // Use default credentials (single sign on) if this is the first attempt + // at identity. Do not allow multiple times as it will infinite loop. + // We use default credentials after checking the auth cache so that if + // single sign-on doesn't work, we won't try default credentials for future + // transactions. + if (auth_handler_[target]->SupportsDefaultCredentials() && + !default_credentials_used_ && + CanUseDefaultCredentials(target, auth_origin)) { + auth_identity_[target].source = HttpAuth::IDENT_SRC_DEFAULT_CREDENTIALS; auth_identity_[target].invalid = false; - auth_identity_[target].username = entry->username(); - auth_identity_[target].password = entry->password(); + default_credentials_used_ = true; return true; } + return false; } diff --git a/net/http/http_network_transaction.h b/net/http/http_network_transaction.h index ca4e882..159f75d 100644 --- a/net/http/http_network_transaction.h +++ b/net/http/http_network_transaction.h @@ -237,6 +237,11 @@ class HttpNetworkTransaction : public HttpTransaction { void InvalidateRejectedAuthFromCache(HttpAuth::Target target, const GURL& auth_origin); + // Returns true if we can use the default credentials for the + // authentication. + bool CanUseDefaultCredentials(HttpAuth::Target target, + const GURL& auth_origin) const; + // Sets auth_identity_[target] to the next identity that the transaction // should try. It chooses candidates by searching the auth cache // and the URL for a username:password. Returns true if an identity @@ -335,6 +340,10 @@ class HttpNetworkTransaction : public HttpTransaction { // preventing an infinite auth restart loop. bool embedded_identity_used_; + // True if default credentials have already been tried for this transaction + // in response to an HTTP authentication challenge. + bool default_credentials_used_; + SSLConfig ssl_config_; std::string request_headers_; diff --git a/net/http/url_security_manager.h b/net/http/url_security_manager.h new file mode 100644 index 0000000..7309fef --- /dev/null +++ b/net/http/url_security_manager.h @@ -0,0 +1,34 @@ +// Copyright (c) 2010 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. + +#ifndef NET_HTTP_URL_SECURITY_MANAGER_H_ +#define NET_HTTP_URL_SECURITY_MANAGER_H_ + +class GURL; + +namespace net { + +// The URL security manager controls the policies (allow, deny, prompt user) +// regarding URL actions (e.g., sending the default credentials to a server). +// +// On Windows, we honor the WinINet/IE settings and group policy related to +// URL Security Zones. See the Microsoft Knowledge Base article 182569 +// "Internet Explorer security zones registry entries for advanced users" +// (http://support.microsoft.com/kb/182569) for more info on these registry +// keys. +class URLSecurityManager { + public: + virtual ~URLSecurityManager() {} + + // Creates a platform-dependent instance of URLSecurityManager. + static URLSecurityManager* Create(); + + // Returns true if we can send the default credentials to the server at + // |auth_origin| for HTTP NTLM or Negotiate authentication. + virtual bool CanUseDefaultCredentials(const GURL& auth_origin) const = 0; +}; + +} // namespace net + +#endif // NET_HTTP_URL_SECURITY_MANAGER_H_ diff --git a/net/http/url_security_manager_posix.cc b/net/http/url_security_manager_posix.cc new file mode 100644 index 0000000..84bae9f --- /dev/null +++ b/net/http/url_security_manager_posix.cc @@ -0,0 +1,25 @@ +// Copyright (c) 2010 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/url_security_manager.h" + +#include "googleurl/src/gurl.h" + +namespace net { + +class URLSecurityManagerDefault : public URLSecurityManager { + public: + // URLSecurityManager methods: + virtual bool CanUseDefaultCredentials(const GURL& auth_origin) const { + // TODO(wtc): use command-line whitelist. + return false; + } +}; + +// static +URLSecurityManager* URLSecurityManager::Create() { + return new URLSecurityManagerDefault; +} + +} // namespace net diff --git a/net/http/url_security_manager_win.cc b/net/http/url_security_manager_win.cc new file mode 100644 index 0000000..b3abb05 --- /dev/null +++ b/net/http/url_security_manager_win.cc @@ -0,0 +1,101 @@ +// Copyright (c) 2010 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/url_security_manager.h" + +#include <urlmon.h> +#pragma comment(lib, "urlmon.lib") + +#include "base/scoped_comptr_win.h" +#include "base/string_util.h" +#include "googleurl/src/gurl.h" + +// The Windows implementation of URLSecurityManager uses WinINet/IE's +// URL security zone manager. See the MSDN page "URL Security Zones" at +// http://msdn.microsoft.com/en-us/library/ms537021(VS.85).aspx for more +// info on the Internet Security Manager and Internet Zone Manager objects. + +namespace net { + +class URLSecurityManagerWin : public URLSecurityManager { + public: + URLSecurityManagerWin(); + + // URLSecurityManager methods: + virtual bool CanUseDefaultCredentials(const GURL& auth_origin) const; + + private: + ScopedComPtr<IInternetSecurityManager> security_manager_; +}; + +URLSecurityManagerWin::URLSecurityManagerWin() { + HRESULT hr = CoInternetCreateSecurityManager(NULL, + security_manager_.Receive(), + NULL); + DCHECK(SUCCEEDED(hr)); +} + + +bool URLSecurityManagerWin::CanUseDefaultCredentials( + const GURL& auth_origin) const { + if (!security_manager_) { + NOTREACHED(); // The code in the constructor failed. + return false; + } + + std::wstring url_w = ASCIIToWide(auth_origin.spec()); + DWORD policy = 0; + HRESULT hr; + hr = security_manager_->ProcessUrlAction(url_w.c_str(), + URLACTION_CREDENTIALS_USE, + reinterpret_cast<BYTE*>(&policy), + sizeof(policy), NULL, 0, + PUAF_NOUI, 0); + if (FAILED(hr)) { + LOG(ERROR) << "IInternetSecurityManager::ProcessUrlAction failed: " << hr; + return false; + } + + // Four possible policies for URLACTION_CREDENTIALS_USE. See the MSDN page + // "About URL Security Zones" at + // http://msdn.microsoft.com/en-us/library/ms537183(VS.85).aspx + switch (policy) { + case URLPOLICY_CREDENTIALS_SILENT_LOGON_OK: + return true; + case URLPOLICY_CREDENTIALS_CONDITIONAL_PROMPT: { + // This policy means "prompt the user for permission if the resource is + // not located in the Intranet zone". TODO(wtc): Note that it's + // prompting for permission (to use the default credentials), as opposed + // to prompting the user to enter a user name and password. + + // URLZONE_LOCAL_MACHINE 0 + // URLZONE_INTRANET 1 + // URLZONE_TRUSTED 2 + // URLZONE_INTERNET 3 + // URLZONE_UNTRUSTED 4 + DWORD zone = 0; + hr = security_manager_->MapUrlToZone(url_w.c_str(), &zone, 0); + if (FAILED(hr)) { + LOG(ERROR) << "IInternetSecurityManager::MapUrlToZone failed: " << hr; + return false; + } + return zone <= URLZONE_INTRANET; + } + case URLPOLICY_CREDENTIALS_MUST_PROMPT_USER: + return false; + case URLPOLICY_CREDENTIALS_ANONYMOUS_ONLY: + // TODO(wtc): we should fail the authentication. + return false; + default: + NOTREACHED(); + return false; + } +} + +// static +URLSecurityManager* URLSecurityManager::Create() { + return new URLSecurityManagerWin; +} + +} // namespace net diff --git a/net/net.gyp b/net/net.gyp index 34e77fc..177f69f 100644 --- a/net/net.gyp +++ b/net/net.gyp @@ -365,6 +365,9 @@ 'http/http_stream_parser.h', 'http/http_transaction.h', 'http/http_transaction_factory.h', + 'http/url_security_manager.h', + 'http/url_security_manager_posix.cc', + 'http/url_security_manager_win.cc', 'http/http_util.cc', 'http/http_util_icu.cc', 'http/http_util.h', |