summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/http/http_auth.h90
-rw-r--r--net/http/http_auth_handler.h12
-rw-r--r--net/http/http_auth_handler_negotiate.h2
-rw-r--r--net/http/http_auth_handler_negotiate_posix.cc2
-rw-r--r--net/http/http_auth_handler_negotiate_win.cc13
-rw-r--r--net/http/http_auth_handler_ntlm.h2
-rw-r--r--net/http/http_auth_handler_ntlm_portable.cc2
-rw-r--r--net/http/http_auth_handler_ntlm_win.cc23
-rw-r--r--net/http/http_network_session.cc11
-rw-r--r--net/http/http_network_session.h6
-rw-r--r--net/http/http_network_transaction.cc90
-rw-r--r--net/http/http_network_transaction.h9
-rw-r--r--net/http/url_security_manager.h34
-rw-r--r--net/http/url_security_manager_posix.cc25
-rw-r--r--net/http/url_security_manager_win.cc101
-rw-r--r--net/net.gyp3
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',