summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/io_thread.cc36
-rw-r--r--chrome/browser/io_thread.h1
-rw-r--r--chrome/browser/net/spdyproxy/http_auth_handler_spdyproxy.cc168
-rw-r--r--chrome/browser/net/spdyproxy/http_auth_handler_spdyproxy.h80
-rw-r--r--chrome/browser/net/spdyproxy/http_auth_handler_spdyproxy_unittest.cc161
-rw-r--r--chrome/browser/password_manager/password_manager.cc8
-rw-r--r--chrome/chrome_browser.gypi2
-rw-r--r--chrome/chrome_tests.gypi1
-rw-r--r--chrome/common/chrome_switches.cc3
-rw-r--r--chrome/common/chrome_switches.h1
-rw-r--r--chrome/common/pref_names.cc8
-rw-r--r--chrome/common/pref_names.h1
-rw-r--r--net/http/http_auth.cc1
-rw-r--r--net/http/http_auth.h1
14 files changed, 464 insertions, 8 deletions
diff --git a/chrome/browser/io_thread.cc b/chrome/browser/io_thread.cc
index 14efe1e..b8b3c90 100644
--- a/chrome/browser/io_thread.cc
+++ b/chrome/browser/io_thread.cc
@@ -31,6 +31,7 @@
#include "chrome/browser/net/pref_proxy_config_tracker.h"
#include "chrome/browser/net/proxy_service_factory.h"
#include "chrome/browser/net/sdch_dictionary_fetcher.h"
+#include "chrome/browser/net/spdyproxy/http_auth_handler_spdyproxy.h"
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h"
@@ -450,6 +451,10 @@ void IOThread::Init() {
globals_->cert_verifier.reset(net::CertVerifier::CreateDefault());
globals_->transport_security_state.reset(new net::TransportSecurityState());
globals_->ssl_config_service = GetSSLConfigService();
+ if (command_line.HasSwitch(switches::kSpdyProxyOrigin)) {
+ spdyproxy_origin_ =
+ command_line.GetSwitchValueASCII(switches::kSpdyProxyOrigin);
+ }
globals_->http_auth_handler_factory.reset(CreateDefaultAuthHandlerFactory(
globals_->host_resolver.get()));
globals_->http_server_properties.reset(new net::HttpServerPropertiesImpl);
@@ -591,13 +596,15 @@ void IOThread::CleanUp() {
// static
void IOThread::RegisterPrefs(PrefService* local_state) {
local_state->RegisterStringPref(prefs::kAuthSchemes,
- "basic,digest,ntlm,negotiate");
+ "basic,digest,ntlm,negotiate,"
+ "spdyproxy");
local_state->RegisterBooleanPref(prefs::kDisableAuthNegotiateCnameLookup,
false);
local_state->RegisterBooleanPref(prefs::kEnableAuthNegotiatePort, false);
local_state->RegisterStringPref(prefs::kAuthServerWhitelist, "");
local_state->RegisterStringPref(prefs::kAuthNegotiateDelegateWhitelist, "");
local_state->RegisterStringPref(prefs::kGSSAPILibraryName, "");
+ local_state->RegisterStringPref(prefs::kSpdyProxyOrigin, "");
local_state->RegisterBooleanPref(prefs::kEnableReferrers, true);
}
@@ -619,13 +626,26 @@ net::HttpAuthHandlerFactory* IOThread::CreateDefaultAuthHandlerFactory(
std::vector<std::string> supported_schemes;
base::SplitString(auth_schemes_, ',', &supported_schemes);
- return net::HttpAuthHandlerRegistryFactory::Create(
- supported_schemes,
- globals_->url_security_manager.get(),
- resolver,
- gssapi_library_name_,
- negotiate_disable_cname_lookup_,
- negotiate_enable_port_);
+ scoped_ptr<net::HttpAuthHandlerRegistryFactory> registry_factory(
+ net::HttpAuthHandlerRegistryFactory::Create(
+ supported_schemes, globals_->url_security_manager.get(),
+ resolver, gssapi_library_name_, negotiate_disable_cname_lookup_,
+ negotiate_enable_port_));
+
+ if (!spdyproxy_origin_.empty()) {
+ GURL origin_url(spdyproxy_origin_);
+ if (origin_url.is_valid()) {
+ registry_factory->RegisterSchemeFactory(
+ "spdyproxy",
+ new spdyproxy::HttpAuthHandlerSpdyProxy::Factory(origin_url));
+ } else {
+ LOG(WARNING) << "Skipping creation of SpdyProxy auth handler since "
+ << "authorized origin is invalid: "
+ << spdyproxy_origin_;
+ }
+ }
+
+ return registry_factory.release();
}
void IOThread::ClearHostCache() {
diff --git a/chrome/browser/io_thread.h b/chrome/browser/io_thread.h
index 180ae24..6e0699c 100644
--- a/chrome/browser/io_thread.h
+++ b/chrome/browser/io_thread.h
@@ -206,6 +206,7 @@ class IOThread : public content::BrowserThreadDelegate {
std::string auth_server_whitelist_;
std::string auth_delegate_whitelist_;
std::string gssapi_library_name_;
+ std::string spdyproxy_origin_;
// This is an instance of the default SSLConfigServiceManager for the current
// platform and it gets SSL preferences from local_state object.
diff --git a/chrome/browser/net/spdyproxy/http_auth_handler_spdyproxy.cc b/chrome/browser/net/spdyproxy/http_auth_handler_spdyproxy.cc
new file mode 100644
index 0000000..0cd9df4
--- /dev/null
+++ b/chrome/browser/net/spdyproxy/http_auth_handler_spdyproxy.cc
@@ -0,0 +1,168 @@
+// 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 "chrome/browser/net/spdyproxy/http_auth_handler_spdyproxy.h"
+
+#include <string>
+
+#include "base/i18n/icu_string_conversions.h"
+#include "base/metrics/histogram.h"
+#include "base/string_util.h"
+#include "base/utf_string_conversions.h"
+#include "net/base/net_errors.h"
+#include "net/http/http_auth.h"
+#include "net/http/http_request_info.h"
+
+namespace spdyproxy {
+
+using net::AuthCredentials;
+using net::BoundNetLog;
+using net::CompletionCallback;
+using net::HttpAuth;
+using net::HttpAuthHandler;
+using net::HttpAuthHandlerFactory;
+using net::HttpRequestInfo;
+using net::HttpUtil;
+
+HttpAuthHandlerSpdyProxy::Factory::Factory(
+ const GURL& authorized_spdyproxy_origin)
+ : authorized_spdyproxy_origin_(authorized_spdyproxy_origin) {
+}
+
+HttpAuthHandlerSpdyProxy::Factory::~Factory() {
+}
+
+int HttpAuthHandlerSpdyProxy::Factory::CreateAuthHandler(
+ HttpAuth::ChallengeTokenizer* challenge,
+ HttpAuth::Target target,
+ const GURL& origin,
+ CreateReason reason,
+ int digest_nonce_count,
+ const BoundNetLog& net_log,
+ scoped_ptr<HttpAuthHandler>* handler) {
+ // If a spdyproxy auth proxy has not been set, refuse all requests to use this
+ // auth handler.
+ if (authorized_spdyproxy_origin_.possibly_invalid_spec().empty()) {
+ VLOG(1) << "SpdyProxy auth without configuring authorized origin.";
+ return net::ERR_UNSUPPORTED_AUTH_SCHEME;
+ }
+
+ // We ensure that this authentication handler is used only with an authorized
+ // SPDY proxy, since otherwise a user's authentication token can be
+ // sniffed by a malicious proxy that presents an appropriate challenge.
+ const GURL origin_origin = origin.GetOrigin();
+ if (!(target == HttpAuth::AUTH_PROXY &&
+ origin_origin == authorized_spdyproxy_origin_)) {
+ UMA_HISTOGRAM_COUNTS("Net.UnexpectedSpdyProxyAuth", 1);
+ VLOG(1) << "SpdyProxy auth request with an unexpected config."
+ << " origin: " << origin_origin.possibly_invalid_spec()
+ << " authorized_origin: "
+ << authorized_spdyproxy_origin_.possibly_invalid_spec();
+ return net::ERR_UNSUPPORTED_AUTH_SCHEME;
+ }
+
+ scoped_ptr<HttpAuthHandler> tmp_handler(
+ new HttpAuthHandlerSpdyProxy(authorized_spdyproxy_origin_));
+ if (!tmp_handler->InitFromChallenge(challenge, target, origin, net_log))
+ return net::ERR_INVALID_RESPONSE;
+ handler->swap(tmp_handler);
+ return net::OK;
+}
+
+HttpAuthHandlerSpdyProxy::HttpAuthHandlerSpdyProxy(
+ const GURL& authorized_spdyproxy_origin)
+ : HttpAuthHandler(),
+ authorized_spdyproxy_origin_(authorized_spdyproxy_origin) {
+}
+
+HttpAuth::AuthorizationResult
+HttpAuthHandlerSpdyProxy::HandleAnotherChallenge(
+ HttpAuth::ChallengeTokenizer* challenge) {
+ // SpdyProxy authentication is always a single round, so any responses
+ // should be treated as a rejection.
+ return HttpAuth::AUTHORIZATION_RESULT_REJECT;
+}
+
+bool HttpAuthHandlerSpdyProxy::NeedsIdentity() {
+ return true;
+}
+
+bool HttpAuthHandlerSpdyProxy::AllowsDefaultCredentials() {
+ return false;
+}
+
+bool HttpAuthHandlerSpdyProxy::AllowsExplicitCredentials() {
+ return true;
+}
+
+bool HttpAuthHandlerSpdyProxy::Init(
+ HttpAuth::ChallengeTokenizer* challenge) {
+ auth_scheme_ = HttpAuth::AUTH_SCHEME_SPDYPROXY;
+ score_ = 5;
+ properties_ = ENCRYPTS_IDENTITY;
+ return ParseChallenge(challenge);
+}
+
+int HttpAuthHandlerSpdyProxy::GenerateAuthTokenImpl(
+ const AuthCredentials* credentials, const HttpRequestInfo* request,
+ const CompletionCallback&, std::string* auth_token) {
+ DCHECK(credentials);
+ if (credentials->password().length() == 0) {
+ DVLOG(1) << "Received a SpdyProxy auth token request without an "
+ << "available token.";
+ return -1;
+ }
+ *auth_token = "SpdyProxy ps=\"" + ps_token_ + "\", sid=\"" +
+ UTF16ToUTF8(credentials->password()) + "\"";
+ return net::OK;
+}
+
+bool HttpAuthHandlerSpdyProxy::ParseChallenge(
+ HttpAuth::ChallengeTokenizer* challenge) {
+
+ // Verify the challenge's auth-scheme.
+ if (!LowerCaseEqualsASCII(challenge->scheme(), "spdyproxy")) {
+ VLOG(1) << "Parsed challenge without SpdyProxy type";
+ return false;
+ }
+
+ HttpUtil::NameValuePairsIterator parameters = challenge->param_pairs();
+
+ // Loop through all the properties.
+ while (parameters.GetNext()) {
+ // FAIL -- couldn't parse a property.
+ if (!ParseChallengeProperty(parameters.name(),
+ parameters.value()))
+ return false;
+ }
+ // Check if tokenizer failed.
+ if (!parameters.valid())
+ return false;
+
+ // Check that the required properties were provided.
+ if (realm_.empty())
+ return false;
+
+ if (ps_token_.empty())
+ return false;
+
+ return true;
+}
+
+bool HttpAuthHandlerSpdyProxy::ParseChallengeProperty(
+ const std::string& name, const std::string& value) {
+ if (LowerCaseEqualsASCII(name, "realm")) {
+ std::string realm;
+ if (!base::ConvertToUtf8AndNormalize(value, base::kCodepageLatin1, &realm))
+ return false;
+ realm_ = realm;
+ } else if (LowerCaseEqualsASCII(name, "ps")) {
+ ps_token_ = value;
+ } else {
+ VLOG(1) << "Skipping unrecognized SpdyProxy auth property, " << name;
+ }
+ return true;
+}
+
+} // namespace spdyproxy
diff --git a/chrome/browser/net/spdyproxy/http_auth_handler_spdyproxy.h b/chrome/browser/net/spdyproxy/http_auth_handler_spdyproxy.h
new file mode 100644
index 0000000..4816e94
--- /dev/null
+++ b/chrome/browser/net/spdyproxy/http_auth_handler_spdyproxy.h
@@ -0,0 +1,80 @@
+// 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.
+
+#ifndef CHROME_BROWSER_NET_SPDYPROXY_HTTP_AUTH_HANDLER_SPDYPROXY_H_
+#define CHROME_BROWSER_NET_SPDYPROXY_HTTP_AUTH_HANDLER_SPDYPROXY_H_
+
+#include <string>
+
+#include "base/gtest_prod_util.h"
+#include "net/http/http_auth_handler.h"
+#include "net/http/http_auth_handler_factory.h"
+
+namespace spdyproxy {
+
+// Code for handling http SpdyProxy authentication.
+class HttpAuthHandlerSpdyProxy : public net::HttpAuthHandler {
+ public:
+ class Factory : public net::HttpAuthHandlerFactory {
+ public:
+ // Constructs a new spdyproxy handler factory which mints handlers that
+ // respond to challenges only from the given |authorized_spdyproxy_origin|.
+ explicit Factory(const GURL& authorized_spdyproxy_origin);
+ virtual ~Factory();
+
+ virtual int CreateAuthHandler(
+ net::HttpAuth::ChallengeTokenizer* challenge,
+ net::HttpAuth::Target target,
+ const GURL& origin,
+ CreateReason reason,
+ int digest_nonce_count,
+ const net::BoundNetLog& net_log,
+ scoped_ptr<HttpAuthHandler>* handler) OVERRIDE;
+
+ private:
+ // The origin for which we will respond to SpdyProxy auth challenges.
+ GURL authorized_spdyproxy_origin_;
+ };
+
+ // Constructs a new spdyproxy handler which responds to challenges
+ // from the given |authorized_spdyproxy_origin|.
+ explicit HttpAuthHandlerSpdyProxy(
+ const GURL& authorized_spdyproxy_origin);
+
+ // Overrides from net::HttpAuthHandler.
+ virtual net::HttpAuth::AuthorizationResult HandleAnotherChallenge(
+ net::HttpAuth::ChallengeTokenizer* challenge) OVERRIDE;
+ virtual bool NeedsIdentity() OVERRIDE;
+ virtual bool AllowsDefaultCredentials() OVERRIDE;
+ virtual bool AllowsExplicitCredentials() OVERRIDE;
+
+ private:
+ FRIEND_TEST_ALL_PREFIXES(HttpAuthHandlerSpdyProxyTest, ParseChallenge);
+
+ virtual ~HttpAuthHandlerSpdyProxy() {}
+
+ virtual bool Init(net::HttpAuth::ChallengeTokenizer* challenge) OVERRIDE;
+
+ virtual int GenerateAuthTokenImpl(const net::AuthCredentials* credentials,
+ const net::HttpRequestInfo* request,
+ const net::CompletionCallback& callback,
+ std::string* auth_token) OVERRIDE;
+
+ bool ParseChallenge(net::HttpAuth::ChallengeTokenizer* challenge);
+
+ bool ParseChallengeProperty(const std::string& name,
+ const std::string& value);
+
+ // The origin for which we will respond to SpdyProxy auth challenges.
+ GURL authorized_spdyproxy_origin_;
+
+ // The ps token, encoded as UTF-8.
+ std::string ps_token_;
+
+ DISALLOW_COPY_AND_ASSIGN(HttpAuthHandlerSpdyProxy);
+};
+
+} // namespace spdyproxy
+
+#endif // CHROME_BROWSER_NET_SPDYPROXY_HTTP_AUTH_HANDLER_SPDYPROXY_H_
diff --git a/chrome/browser/net/spdyproxy/http_auth_handler_spdyproxy_unittest.cc b/chrome/browser/net/spdyproxy/http_auth_handler_spdyproxy_unittest.cc
new file mode 100644
index 0000000..4a59ba1
--- /dev/null
+++ b/chrome/browser/net/spdyproxy/http_auth_handler_spdyproxy_unittest.cc
@@ -0,0 +1,161 @@
+// 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 "chrome/browser/net/spdyproxy/http_auth_handler_spdyproxy.h"
+
+#include <string>
+
+#include "base/basictypes.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/string_util.h"
+#include "base/utf_string_conversions.h"
+#include "net/base/net_errors.h"
+#include "net/http/http_request_info.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace {
+
+const char kValidOrigin[] = "https://www.proxy.com/";
+const char kValidChallenge[] = "SpdyProxy realm=\"SpdyProxy\", "
+ "ps=\"1-2-3-4\"";
+
+} // namespace
+
+namespace spdyproxy {
+
+using net::ERR_INVALID_RESPONSE;
+using net::ERR_UNSUPPORTED_AUTH_SCHEME;
+using net::OK;
+using net::AuthCredentials;
+using net::BoundNetLog;
+using net::CompletionCallback;
+using net::Error;
+using net::HttpAuth;
+using net::HttpAuthHandler;
+using net::HttpRequestInfo;
+
+TEST(HttpAuthHandlerSpdyProxyTest, GenerateAuthToken) {
+ // Verifies that challenge parsing is expected as described in individual
+ // cases below.
+ static const struct {
+ Error err1, err2;
+ const char* origin;
+ const char* challenge;
+ const char* username;
+ const char* sid;
+ const char* expected_credentials;
+ } tests[] = {
+ // A well-formed challenge where a sid is provided produces a valid
+ // response header echoing the sid and ps token.
+ { OK, OK,
+ kValidOrigin,
+ kValidChallenge,
+ "",
+ "sid-string",
+ "SpdyProxy ps=\"1-2-3-4\", sid=\"sid-string\"",},
+
+ // A non-SSL origin returns ERR_UNSUPPORTED_AUTH_SCHEME.
+ { ERR_UNSUPPORTED_AUTH_SCHEME, OK,
+ "http://www.proxy.com/", "", "", "", "",},
+
+ // An SSL origin not matching the authorized origin returns
+ // ERR_UNSUPPORTED_AUTH_SCHEME.
+ { ERR_UNSUPPORTED_AUTH_SCHEME, OK,
+ "https://www.unconfigured.com/", "", "", "", "",},
+
+ // Absent ps token yields ERR_INVALID_RESPONSE.
+ { ERR_INVALID_RESPONSE, OK,
+ kValidOrigin, "SpdyProxy realm=\"SpdyProxy\"", "", "", "",},
+ };
+ for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
+ GURL origin(tests[i].origin);
+ GURL authorized_origin(kValidOrigin);
+ HttpAuthHandlerSpdyProxy::Factory factory(authorized_origin);
+ scoped_ptr<HttpAuthHandler> spdyproxy;
+ EXPECT_EQ(tests[i].err1, factory.CreateAuthHandlerFromString(
+ tests[i].challenge, HttpAuth::AUTH_PROXY, origin, BoundNetLog(),
+ &spdyproxy));
+ if (tests[i].err1 != OK) {
+ continue;
+ }
+ AuthCredentials credentials(ASCIIToUTF16(tests[i].username),
+ ASCIIToUTF16(tests[i].sid));
+ HttpRequestInfo request_info;
+ std::string auth_token;
+ int rv = spdyproxy->GenerateAuthToken(&credentials, &request_info,
+ CompletionCallback(), &auth_token);
+ EXPECT_EQ(tests[i].err2, rv);
+ if (tests[i].err2 != OK) {
+ continue;
+ }
+ EXPECT_STREQ(tests[i].expected_credentials, auth_token.c_str());
+ }
+}
+
+TEST(HttpAuthHandlerSpdyProxyTest, NonProxyAuthTypeFails) {
+ // Verifies that an authorization request fails if requested by an ordinary
+ // site. (i.e., HttpAuth::AUTH_SERVER)
+ GURL origin(kValidOrigin);
+ GURL accepted_origin(kValidOrigin);
+ HttpAuthHandlerSpdyProxy::Factory factory(accepted_origin);
+ scoped_ptr<HttpAuthHandler> spdyproxy;
+ EXPECT_EQ(ERR_UNSUPPORTED_AUTH_SCHEME, factory.CreateAuthHandlerFromString(
+ kValidChallenge, HttpAuth::AUTH_SERVER, origin,
+ BoundNetLog(), &spdyproxy));
+}
+
+TEST(HttpAuthHandlerSpdyProxyTest, HandleAnotherChallenge) {
+ // Verifies that any repeat challenge is treated as a failure.
+ GURL origin(kValidOrigin);
+ GURL accepted_origin(kValidOrigin);
+ HttpAuthHandlerSpdyProxy::Factory factory(accepted_origin);
+ scoped_ptr<HttpAuthHandler> spdyproxy;
+ EXPECT_EQ(OK, factory.CreateAuthHandlerFromString(
+ kValidChallenge, HttpAuth::AUTH_PROXY, origin,
+ BoundNetLog(), &spdyproxy));
+ std::string challenge(kValidChallenge);
+ HttpAuth::ChallengeTokenizer tok(challenge.begin(),
+ challenge.end());
+ EXPECT_EQ(HttpAuth::AUTHORIZATION_RESULT_REJECT,
+ spdyproxy->HandleAnotherChallenge(&tok));
+}
+
+TEST(HttpAuthHandlerSpdyProxyTest, ParseChallenge) {
+ // Verifies that various challenge strings are parsed appropriately as
+ // described below.
+ static const struct {
+ const char* challenge;
+ int expected_rv;
+ const char* expected_ps;
+ const char* expected_realm;
+ } tests[] = {
+ // Absent parameters fails.
+ { "SpdyProxy", ERR_INVALID_RESPONSE, "", "", },
+
+ // Empty parameters fails.
+ { "SpdyProxy ps=\"\"", ERR_INVALID_RESPONSE, "", "", },
+
+ // Valid challenge parses successfully.
+ { kValidChallenge, OK, "1-2-3-4", "SpdyProxy", },
+ };
+ GURL origin(kValidOrigin);
+ GURL accepted_origin(kValidOrigin);
+ HttpAuthHandlerSpdyProxy::Factory factory(accepted_origin);
+ for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
+ std::string challenge = tests[i].challenge;
+ scoped_ptr<HttpAuthHandler> spdyproxy;
+ int rv = factory.CreateAuthHandlerFromString(
+ challenge, HttpAuth::AUTH_PROXY, origin, BoundNetLog(), &spdyproxy);
+ EXPECT_EQ(tests[i].expected_rv, rv);
+ if (rv == OK) {
+ EXPECT_EQ(tests[i].expected_realm, spdyproxy->realm());
+ HttpAuthHandlerSpdyProxy* as_spdyproxy =
+ static_cast<HttpAuthHandlerSpdyProxy*>(spdyproxy.get());
+ EXPECT_EQ(tests[i].expected_ps,
+ as_spdyproxy->ps_token_);
+ }
+ }
+}
+
+} // namespace spdyproxy
diff --git a/chrome/browser/password_manager/password_manager.cc b/chrome/browser/password_manager/password_manager.cc
index b3a2a53..fdd0138 100644
--- a/chrome/browser/password_manager/password_manager.cc
+++ b/chrome/browser/password_manager/password_manager.cc
@@ -6,6 +6,7 @@
#include "base/metrics/histogram.h"
#include "base/threading/platform_thread.h"
+#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/password_manager/password_form_manager.h"
#include "chrome/browser/password_manager/password_manager_delegate.h"
@@ -25,6 +26,8 @@ using webkit::forms::PasswordFormMap;
namespace {
+const char kSpdyProxyRealm[] = "/SpdyProxy";
+
// This routine is called when PasswordManagers are constructed.
//
// Currently we report metrics only once at startup. We require
@@ -212,6 +215,11 @@ void PasswordManager::OnPasswordFormsParsed(
for (std::vector<PasswordForm>::const_iterator iter = forms.begin();
iter != forms.end(); ++iter) {
+ // Don't involve the password manager if this form corresponds to
+ // SpdyProxy authentication, as indicated by the realm.
+ if (EndsWith(iter->signon_realm, kSpdyProxyRealm, true))
+ continue;
+
bool ssl_valid = iter->origin.SchemeIsSecure() && !had_ssl_error;
PasswordFormManager* manager =
new PasswordFormManager(delegate_->GetProfile(),
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index bfab0bc..44ce739 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -1089,6 +1089,8 @@
'browser/net/sdch_dictionary_fetcher.h',
'browser/net/service_providers_win.cc',
'browser/net/service_providers_win.h',
+ 'browser/net/spdyproxy/http_auth_handler_spdyproxy.cc',
+ 'browser/net/spdyproxy/http_auth_handler_spdyproxy.h',
'browser/net/sqlite_persistent_cookie_store.cc',
'browser/net/sqlite_persistent_cookie_store.h',
'browser/net/sqlite_server_bound_cert_store.cc',
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi
index 231fd40..c7fc8625 100644
--- a/chrome/chrome_tests.gypi
+++ b/chrome/chrome_tests.gypi
@@ -1415,6 +1415,7 @@
'browser/net/predictor_unittest.cc',
'browser/net/pref_proxy_config_tracker_impl_unittest.cc',
'browser/net/quoted_printable_unittest.cc',
+ 'browser/net/spdyproxy/http_auth_handler_spdyproxy_unittest.cc',
'browser/net/sqlite_persistent_cookie_store_unittest.cc',
'browser/net/sqlite_server_bound_cert_store_unittest.cc',
'browser/net/ssl_config_service_manager_pref_unittest.cc',
diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc
index ea056f5..ec381cd 100644
--- a/chrome/common/chrome_switches.cc
+++ b/chrome/common/chrome_switches.cc
@@ -1205,6 +1205,9 @@ const char kSimulateUpgrade[] = "simulate-upgrade";
// ClientSocketReusePolicy.
const char kSocketReusePolicy[] = "socket-reuse-policy";
+// Origin for which SpdyProxy authentication is supported.
+const char kSpdyProxyOrigin[] = "spdy-proxy-origin";
+
// Speculative resource prefetching.
const char kSpeculativeResourcePrefetching[] =
"speculative-resource-prefetching";
diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h
index e5dd5b8..bb592ad 100644
--- a/chrome/common/chrome_switches.h
+++ b/chrome/common/chrome_switches.h
@@ -320,6 +320,7 @@ extern const char kSocketReusePolicy[];
extern const char kSpeculativeResourcePrefetching[];
extern const char kSpeculativeResourcePrefetchingDisabled[];
extern const char kSpeculativeResourcePrefetchingLearning[];
+extern const char kSpdyProxyOrigin[];
extern const char kSSLVersionMax[];
extern const char kSSLVersionMin[];
extern const char kStartMaximized[];
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc
index 5765fe0..22f74c2 100644
--- a/chrome/common/pref_names.cc
+++ b/chrome/common/pref_names.cc
@@ -1761,18 +1761,26 @@ const char kAuthSchemes[] = "auth.schemes";
// Kerberos SPN.
const char kDisableAuthNegotiateCnameLookup[] =
"auth.disable_negotiate_cname_lookup";
+
// Boolean that specifies whether to include the port in a generated Kerberos
// SPN.
const char kEnableAuthNegotiatePort[] = "auth.enable_negotiate_port";
+
// Whitelist containing servers for which Integrated Authentication is enabled.
const char kAuthServerWhitelist[] = "auth.server_whitelist";
+
// Whitelist containing servers Chrome is allowed to do Kerberos delegation
// with.
const char kAuthNegotiateDelegateWhitelist[] =
"auth.negotiate_delegate_whitelist";
+
// String that specifies the name of a custom GSSAPI library to load.
const char kGSSAPILibraryName[] = "auth.gssapi_library_name";
+// String that specifies the origin allowed to use SpdyProxy
+// authentication, if any.
+const char kSpdyProxyOrigin[] = "auth.spdyproxy.origin";
+
// Boolean that specifies whether to allow basic auth prompting on cross-
// domain sub-content requests.
const char kAllowCrossOriginAuthPrompt[] = "auth.allow_cross_origin_prompt";
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h
index 63993cc..ee75f58 100644
--- a/chrome/common/pref_names.h
+++ b/chrome/common/pref_names.h
@@ -703,6 +703,7 @@ extern const char kEnableAuthNegotiatePort[];
extern const char kAuthServerWhitelist[];
extern const char kAuthNegotiateDelegateWhitelist[];
extern const char kGSSAPILibraryName[];
+extern const char kSpdyProxyOrigin[];
extern const char kAllowCrossOriginAuthPrompt[];
extern const char kRegisteredProtocolHandlers[];
diff --git a/net/http/http_auth.cc b/net/http/http_auth.cc
index 47a13be2..08f70c0 100644
--- a/net/http/http_auth.cc
+++ b/net/http/http_auth.cc
@@ -182,6 +182,7 @@ const char* HttpAuth::SchemeToString(Scheme scheme) {
"digest",
"ntlm",
"negotiate",
+ "spdyproxy",
"mock",
};
COMPILE_ASSERT(arraysize(kSchemeNames) == AUTH_SCHEME_MAX,
diff --git a/net/http/http_auth.h b/net/http/http_auth.h
index 364f933..1a03bb1 100644
--- a/net/http/http_auth.h
+++ b/net/http/http_auth.h
@@ -92,6 +92,7 @@ class NET_EXPORT_PRIVATE HttpAuth {
AUTH_SCHEME_DIGEST,
AUTH_SCHEME_NTLM,
AUTH_SCHEME_NEGOTIATE,
+ AUTH_SCHEME_SPDYPROXY,
AUTH_SCHEME_MOCK,
AUTH_SCHEME_MAX,
};