| Index: net/url_request/url_request_unittest.cc
|
| diff --git a/net/url_request/url_request_unittest.cc b/net/url_request/url_request_unittest.cc
|
| index 26185bd77e4c81bcbca145fb7ca9ab76056b5d7c..0673d08314284068456ed3b7ffc066a881581a1d 100644
|
| --- a/net/url_request/url_request_unittest.cc
|
| +++ b/net/url_request/url_request_unittest.cc
|
| @@ -9,6 +9,7 @@
|
| #include <windows.h>
|
| #elif defined(USE_NSS)
|
| #include "base/nss_util.h"
|
| +#include <sslproto.h>
|
| #endif
|
|
|
| #include <algorithm>
|
| @@ -33,6 +34,7 @@
|
| #include "net/base/net_module.h"
|
| #include "net/base/net_util.h"
|
| #include "net/base/ssl_connection_status_flags.h"
|
| +#include "net/base/cert_status_flags.h"
|
| #include "net/base/upload_data.h"
|
| #include "net/disk_cache/disk_cache.h"
|
| #include "net/ftp/ftp_network_layer.h"
|
| @@ -56,7 +58,9 @@ namespace {
|
|
|
| const string16 kChrome(ASCIIToUTF16("chrome"));
|
| const string16 kSecret(ASCIIToUTF16("secret"));
|
| +const string16 kWrongSecret(ASCIIToUTF16("wrongsecret"));
|
| const string16 kUser(ASCIIToUTF16("user"));
|
| +const string16 kWrongUser(ASCIIToUTF16("wronguser"));
|
|
|
| base::StringPiece TestNetResourceProvider(int key) {
|
| return "header";
|
| @@ -423,6 +427,30 @@ class SSLClientAuthTestDelegate : public TestDelegate {
|
| int on_certificate_requested_count_;
|
| };
|
|
|
| +class HTTPSVClientSRPLoginTestDelegate : public TestDelegate {
|
| + public:
|
| + HTTPSVClientSRPLoginTestDelegate() :
|
| + on_tls_login_required_count_(0),
|
| + last_login_request_info_(NULL) {
|
| + }
|
| + virtual void OnTLSLoginRequired(
|
| + net::URLRequest* request,
|
| + net::AuthChallengeInfo* login_request_info) {
|
| + on_tls_login_required_count_++;
|
| + last_login_request_info_ = login_request_info;
|
| + MessageLoop::current()->Quit();
|
| + }
|
| + int on_tls_login_required_count() {
|
| + return on_tls_login_required_count_;
|
| + };
|
| + net::AuthChallengeInfo* last_login_request_info() {
|
| + return last_login_request_info_;
|
| + }
|
| + private:
|
| + int on_tls_login_required_count_;
|
| + net::AuthChallengeInfo* last_login_request_info_;
|
| +};
|
| +
|
| } // namespace
|
|
|
| // TODO(davidben): Test the rest of the code. Specifically,
|
| @@ -463,6 +491,428 @@ TEST_F(HTTPSRequestTest, ClientAuthTest) {
|
| }
|
| }
|
|
|
| +TEST_F(HTTPSRequestTest, HTTPSSRPLoginTest) {
|
| + bool only_tls_srp = false;
|
| + for (int i = 0; i < 2; i++, only_tls_srp = !only_tls_srp) {
|
| + net::TestServer::HTTPSOptions https_options;
|
| + https_options.use_tls_srp = true;
|
| + https_options.only_tls_srp = only_tls_srp;
|
| + net::TestServer test_server(https_options, FilePath());
|
| + ASSERT_TRUE(test_server.Start());
|
| +
|
| + TestDelegate d;
|
| + {
|
| + TestURLRequest r(test_server.GetURL("tlslogininfo"), &d);
|
| + r.SetTLSLogin(kUser, kSecret);
|
| +
|
| + r.Start();
|
| + EXPECT_TRUE(r.is_pending());
|
| +
|
| + MessageLoop::current()->Run();
|
| +
|
| + EXPECT_NE(0, d.bytes_received());
|
| + EXPECT_TRUE(d.data_received().find(UTF16ToUTF8(kUser)) !=
|
| + std::string::npos);
|
| + EXPECT_FALSE(d.received_data_before_response());
|
| + }
|
| + }
|
| +}
|
| +
|
| +// Provide no TLS login credentials at first; wait to be prompted by the
|
| +// server, and then provide them.
|
| +TEST_F(HTTPSRequestTest, HTTPSSRPLoginContinueTest) {
|
| + bool only_tls_srp = false;
|
| + for (int i = 0; i < 2; i++, only_tls_srp = !only_tls_srp) {
|
| + net::TestServer::HTTPSOptions https_options;
|
| + https_options.use_tls_srp = true;
|
| + https_options.only_tls_srp = only_tls_srp;
|
| + net::TestServer test_server(https_options, FilePath());
|
| + ASSERT_TRUE(test_server.Start());
|
| +
|
| + HTTPSVClientSRPLoginTestDelegate d;
|
| + {
|
| + GURL https_url = test_server.GetURL("tlslogininfo");
|
| + TestURLRequest r(https_url, &d);
|
| +
|
| + r.Start();
|
| + EXPECT_TRUE(r.is_pending());
|
| + MessageLoop::current()->Run();
|
| + EXPECT_EQ(0, d.bytes_received());
|
| + EXPECT_FALSE(d.received_data_before_response());
|
| + EXPECT_EQ(1, d.on_tls_login_required_count());
|
| + EXPECT_EQ("TLS-SRP", WideToUTF8(d.last_login_request_info()->scheme));
|
| + std::string host_and_port =
|
| + WideToUTF8(d.last_login_request_info()->host_and_port);
|
| + EXPECT_TRUE(host_and_port.find(https_url.host()) != std::string::npos);
|
| + EXPECT_TRUE(host_and_port.find(https_url.port()) != std::string::npos);
|
| + EXPECT_EQ("", WideToUTF8(d.last_login_request_info()->realm));
|
| +
|
| + r.SetTLSLogin(kUser, kSecret);
|
| + r.ContinueWithTLSLogin();
|
| + MessageLoop::current()->Run();
|
| +
|
| + EXPECT_NE(0, d.bytes_received());
|
| + EXPECT_TRUE(d.data_received().find(UTF16ToUTF8(kUser)) !=
|
| + std::string::npos);
|
| + EXPECT_FALSE(d.received_data_before_response());
|
| + }
|
| + }
|
| +}
|
| +
|
| +// Open a connection to the same host using SSL certificate auth, and then open
|
| +// a connection to the same host requesting TLS-SRP auth.
|
| +// TODO(sqs): disabled - see todo below.
|
| +//
|
| +// TODO(sqs): This happens on, e.g., GnuTLS/mod_gnutls. If the Client Hello has
|
| +// no "srp" extension but has SRP cipher suites, GnuTLS will choose a non-SRP
|
| +// ciphersuite. Other implementations (OpenSSL, TLS Lite) will send
|
| +// "unknown_psk_identity".
|
| +TEST_F(HTTPSRequestTest, DISABLED_SSLCertThenWantUpgradeToSRP) {
|
| + net::TestServer::HTTPSOptions https_options;
|
| + https_options.use_tls_srp = true;
|
| + https_options.only_tls_srp = false;
|
| + net::TestServer test_server(https_options, FilePath());
|
| + ASSERT_TRUE(test_server.Start());
|
| +
|
| + GURL https_url = test_server.GetURL("tlslogininfo");
|
| + GURL::Replacements replacements;
|
| + replacements.SetSchemeStr("httpsv");
|
| + GURL httpsv_url = https_url.ReplaceComponents(replacements);
|
| +
|
| + {
|
| + TestDelegate d_https;
|
| + d_https.set_allow_certificate_errors(true);
|
| + TestURLRequest r_https(https_url, &d_https);
|
| + // TODO(sqs): need to force this connection to use certificate auth. Right
|
| + // now, TLS Lite sends unknown_psk_identity if the client lists SRP cipher
|
| + // suites even if no srp username is sent in the client hello. One way to
|
| + // force this is to set all of the SRP cipher suites as disabled in the
|
| + // URLRequest's ssl_config, but it's not accessible (ssl_config is actually
|
| + // much deeper than URLRequest).
|
| +
|
| + r_https.Start();
|
| + EXPECT_TRUE(r_https.is_pending());
|
| + MessageLoop::current()->Run();
|
| + EXPECT_EQ(1, d_https.response_started_count());
|
| + EXPECT_NE(0, d_https.bytes_received());
|
| + CheckSSLInfo(r_https.ssl_info());
|
| +
|
| + HTTPSVClientSRPLoginTestDelegate d;
|
| + TestURLRequest r(httpsv_url, &d);
|
| + r.Start();
|
| + EXPECT_TRUE(r.is_pending());
|
| +
|
| + MessageLoop::current()->Run();
|
| + EXPECT_EQ(0, d.bytes_received());
|
| + EXPECT_FALSE(d.received_data_before_response());
|
| + EXPECT_EQ(1, d.on_tls_login_required_count());
|
| + EXPECT_EQ("TLS-SRP", WideToUTF8(d.last_login_request_info()->scheme));
|
| + std::string host_and_port =
|
| + WideToUTF8(d.last_login_request_info()->host_and_port);
|
| + EXPECT_TRUE(host_and_port.find(httpsv_url.host()) != std::string::npos);
|
| + EXPECT_TRUE(host_and_port.find(httpsv_url.port()) != std::string::npos);
|
| + EXPECT_EQ("", WideToUTF8(d.last_login_request_info()->realm));
|
| +
|
| + r.SetTLSLogin(kUser, kSecret);
|
| + r.ContinueWithTLSLogin();
|
| +
|
| + MessageLoop::current()->Run();
|
| + EXPECT_NE(0, d.bytes_received());
|
| + EXPECT_TRUE(d.data_received().find(UTF16ToUTF8(kUser)) !=
|
| + std::string::npos);
|
| + EXPECT_FALSE(d.received_data_before_response());
|
| + }
|
| +}
|
| +
|
| +TEST_F(HTTPSRequestTest, TLSLoginCredentialsRemainCached) {
|
| + net::TestServer::HTTPSOptions https_options;
|
| + https_options.use_tls_srp = true;
|
| + net::TestServer test_server(https_options, FilePath());
|
| + ASSERT_TRUE(test_server.Start());
|
| +
|
| + GURL https_url = test_server.GetURL("");
|
| + GURL::Replacements replacements;
|
| + replacements.SetSchemeStr("httpsv");
|
| + GURL httpsv_url = https_url.ReplaceComponents(replacements);
|
| +
|
| + GURL::Replacements replacements2;
|
| + replacements2.SetPathStr("tlslogininfo");
|
| + GURL https_url2 = https_url.ReplaceComponents(replacements2);
|
| +
|
| + {
|
| + HTTPSVClientSRPLoginTestDelegate d;
|
| + TestURLRequest r(httpsv_url, &d);
|
| + r.Start();
|
| + EXPECT_TRUE(r.is_pending());
|
| +
|
| + MessageLoop::current()->Run();
|
| + EXPECT_EQ(0, d.bytes_received());
|
| + EXPECT_FALSE(d.received_data_before_response());
|
| + EXPECT_EQ(1, d.on_tls_login_required_count());
|
| + EXPECT_EQ("TLS-SRP", WideToUTF8(d.last_login_request_info()->scheme));
|
| +
|
| + r.SetTLSLogin(kUser, kSecret);
|
| + r.ContinueWithTLSLogin();
|
| +
|
| + MessageLoop::current()->Run();
|
| + EXPECT_NE(0, d.bytes_received());
|
| + EXPECT_FALSE(d.received_data_before_response());
|
| +
|
| + // Don't specify credentials for this request.
|
| + HTTPSVClientSRPLoginTestDelegate d2;
|
| + TestURLRequest r2(https_url2, &d2);
|
| + r2.Start();
|
| + EXPECT_TRUE(r2.is_pending());
|
| + MessageLoop::current()->Run();
|
| + EXPECT_NE(0, d2.bytes_received());
|
| + EXPECT_FALSE(d2.received_data_before_response());
|
| + LOG(INFO) << "GOT '" << d2.data_received() << "'";
|
| + EXPECT_TRUE(d2.data_received().find(UTF16ToUTF8(kUser)) !=
|
| + std::string::npos);
|
| + }
|
| +}
|
| +
|
| +TEST_F(HTTPSRequestTest, HTTPSVLoginTest) {
|
| + bool only_tls_srp = false;
|
| + for (int i = 0; i < 2; i++, only_tls_srp = !only_tls_srp) {
|
| + net::TestServer::HTTPSOptions https_options;
|
| + https_options.use_tls_srp = true;
|
| + https_options.only_tls_srp = only_tls_srp;
|
| + net::TestServer test_server(https_options, FilePath());
|
| + ASSERT_TRUE(test_server.Start());
|
| +
|
| + GURL https_url = test_server.GetURL("tlslogininfo");
|
| + GURL::Replacements replacements;
|
| + replacements.SetSchemeStr("httpsv");
|
| + GURL httpsv_url = https_url.ReplaceComponents(replacements);
|
| +
|
| + {
|
| + HTTPSVClientSRPLoginTestDelegate d;
|
| + TestURLRequest r(httpsv_url, &d);
|
| + r.Start();
|
| + EXPECT_TRUE(r.is_pending());
|
| +
|
| + MessageLoop::current()->Run();
|
| + EXPECT_EQ(0, d.bytes_received());
|
| + EXPECT_FALSE(d.received_data_before_response());
|
| + EXPECT_EQ(1, d.on_tls_login_required_count());
|
| + EXPECT_EQ("TLS-SRP", WideToUTF8(d.last_login_request_info()->scheme));
|
| + std::string host_and_port =
|
| + WideToUTF8(d.last_login_request_info()->host_and_port);
|
| + EXPECT_TRUE(host_and_port.find(httpsv_url.host()) != std::string::npos);
|
| + EXPECT_TRUE(host_and_port.find(httpsv_url.port()) != std::string::npos);
|
| + EXPECT_EQ("", WideToUTF8(d.last_login_request_info()->realm));
|
| +
|
| + r.SetTLSLogin(kUser, kSecret);
|
| + r.ContinueWithTLSLogin();
|
| +
|
| + MessageLoop::current()->Run();
|
| + EXPECT_NE(0, d.bytes_received());
|
| + EXPECT_TRUE(d.data_received().find(UTF16ToUTF8(kUser)) !=
|
| + std::string::npos);
|
| + EXPECT_FALSE(d.received_data_before_response());
|
| + }
|
| + }
|
| +}
|
| +
|
| +TEST_F(HTTPSRequestTest, HTTPSVSRPLoginWithCertTest) {
|
| + net::TestServer::HTTPSOptions https_options(
|
| + net::TestServer::HTTPSOptions::CERT_OK);
|
| + https_options.use_tls_srp = true;
|
| + net::TestServer test_server(https_options,
|
| + FilePath(FILE_PATH_LITERAL("net/data/ssl")));
|
| + ASSERT_TRUE(test_server.Start());
|
| +
|
| + GURL https_url = test_server.GetURL("tlslogininfo");
|
| + GURL::Replacements replacements;
|
| + replacements.SetSchemeStr("httpsv");
|
| + GURL httpsv_url = https_url.ReplaceComponents(replacements);
|
| +
|
| + TestDelegate d;
|
| + {
|
| + TestURLRequest r(httpsv_url, &d);
|
| + r.SetTLSLogin(kUser, kSecret);
|
| +
|
| + r.Start();
|
| + EXPECT_TRUE(r.is_pending());
|
| +
|
| + MessageLoop::current()->Run();
|
| +
|
| + EXPECT_EQ(1, d.response_started_count());
|
| + EXPECT_FALSE(d.received_data_before_response());
|
| + EXPECT_NE(0, d.bytes_received());
|
| + CheckSSLInfo(r.ssl_info());
|
| + EXPECT_FALSE(net::IsCertStatusError(r.ssl_info().cert_status));
|
| + EXPECT_TRUE(r.ssl_info().cert.get());
|
| + EXPECT_EQ(kUser, r.ssl_info().tls_username);
|
| + EXPECT_TRUE(d.data_received().find(UTF16ToUTF8(kUser)) !=
|
| + std::string::npos);
|
| + }
|
| +}
|
| +
|
| +// Check that we still validate certs on SRP cipher suites that use certs.
|
| +TEST_F(HTTPSRequestTest, HTTPSVSRPBadCertFailureTest) {
|
| + bool cert_err_allowed = false;
|
| + for (int i = 0; i < 2; i++, cert_err_allowed = !cert_err_allowed) {
|
| + net::TestServer::HTTPSOptions https_options(
|
| + net::TestServer::HTTPSOptions::CERT_EXPIRED);
|
| + https_options.use_tls_srp = true;
|
| + net::TestServer test_server(https_options,
|
| + FilePath(FILE_PATH_LITERAL("net/data/ssl")));
|
| + ASSERT_TRUE(test_server.Start());
|
| +
|
| + GURL https_url = test_server.GetURL("tlslogininfo");
|
| + GURL::Replacements replacements;
|
| + replacements.SetSchemeStr("httpsv");
|
| + GURL httpsv_url = https_url.ReplaceComponents(replacements);
|
| +
|
| + TestDelegate d;
|
| + {
|
| + d.set_allow_certificate_errors(cert_err_allowed);
|
| + TestURLRequest r(httpsv_url, &d);
|
| + r.SetTLSLogin(kUser, kSecret);
|
| +
|
| + r.Start();
|
| + EXPECT_TRUE(r.is_pending());
|
| + MessageLoop::current()->Run();
|
| +
|
| + EXPECT_EQ(1, d.response_started_count());
|
| + EXPECT_FALSE(d.received_data_before_response());
|
| + EXPECT_TRUE(d.have_certificate_errors());
|
| +
|
| + if (cert_err_allowed) {
|
| + EXPECT_NE(0, d.bytes_received());
|
| + CheckSSLInfo(r.ssl_info());
|
| + EXPECT_TRUE(d.data_received().find(UTF16ToUTF8(kUser)) !=
|
| + std::string::npos);
|
| + } else {
|
| + EXPECT_EQ(0, d.bytes_received());
|
| + }
|
| + }
|
| + }
|
| +}
|
| +
|
| +TEST_F(HTTPSRequestTest, HTTPSVBadSecretFailureTest) {
|
| + bool only_tls_srp = false;
|
| + for (int i = 0; i < 2; i++, only_tls_srp = !only_tls_srp) {
|
| + net::TestServer::HTTPSOptions https_options;
|
| + https_options.use_tls_srp = true;
|
| + https_options.only_tls_srp = only_tls_srp;
|
| + net::TestServer test_server(https_options, FilePath());
|
| + ASSERT_TRUE(test_server.Start());
|
| +
|
| + GURL https_url = test_server.GetURL("tlslogininfo");
|
| + GURL::Replacements replacements;
|
| + replacements.SetSchemeStr("httpsv");
|
| + GURL httpsv_url = https_url.ReplaceComponents(replacements);
|
| +
|
| + {
|
| + HTTPSVClientSRPLoginTestDelegate d;
|
| +
|
| + TestURLRequest r(httpsv_url, &d);
|
| + // Try wrong password. Since this is an httpsv URL, even when the server
|
| + // also offers certificate-based cipher suites, we will fail to connect.
|
| + r.SetTLSLogin(kUser, kWrongSecret);
|
| + r.Start();
|
| + EXPECT_TRUE(r.is_pending());
|
| + MessageLoop::current()->Run();
|
| + EXPECT_EQ(0, d.bytes_received());
|
| + EXPECT_EQ(1, d.on_tls_login_required_count());
|
| + EXPECT_FALSE(d.received_data_before_response());
|
| +
|
| + // Now continue with the correct password.
|
| + r.SetTLSLogin(kUser, kSecret);
|
| + r.ContinueWithTLSLogin();
|
| +
|
| + MessageLoop::current()->Run();
|
| + EXPECT_NE(0, d.bytes_received());
|
| + EXPECT_TRUE(d.data_received().find(UTF16ToUTF8(kUser)) !=
|
| + std::string::npos);
|
| + EXPECT_FALSE(d.received_data_before_response());
|
| + }
|
| + }
|
| +}
|
| +
|
| +TEST_F(HTTPSRequestTest, HTTPSVBadUsernameTest) {
|
| + bool only_tls_srp = false;
|
| + for (int i = 0; i < 2; i++, only_tls_srp = !only_tls_srp) {
|
| + net::TestServer::HTTPSOptions https_options;
|
| + https_options.use_tls_srp = true;
|
| + https_options.only_tls_srp = only_tls_srp;
|
| + net::TestServer test_server(https_options, FilePath());
|
| + ASSERT_TRUE(test_server.Start());
|
| +
|
| + GURL https_url = test_server.GetURL("tlslogininfo");
|
| + GURL::Replacements replacements;
|
| + replacements.SetSchemeStr("httpsv");
|
| + GURL httpsv_url = https_url.ReplaceComponents(replacements);
|
| +
|
| + {
|
| + HTTPSVClientSRPLoginTestDelegate d;
|
| +
|
| + TestURLRequest r(httpsv_url, &d);
|
| + // Try wrong password. Since this is an httpsv URL, even when the server
|
| + // also offers certificate-based cipher suites, we will fail to connect.
|
| + r.SetTLSLogin(kWrongUser, kSecret);
|
| + r.Start();
|
| + EXPECT_TRUE(r.is_pending());
|
| + MessageLoop::current()->Run();
|
| + EXPECT_EQ(0, d.bytes_received());
|
| + EXPECT_FALSE(d.received_data_before_response());
|
| + EXPECT_EQ(1, d.on_tls_login_required_count());
|
| + ASSERT_TRUE(d.last_login_request_info() != NULL);
|
| + EXPECT_EQ("TLS-SRP", WideToUTF8(d.last_login_request_info()->scheme));
|
| + std::string host_and_port =
|
| + WideToUTF8(d.last_login_request_info()->host_and_port);
|
| + EXPECT_TRUE(host_and_port.find(httpsv_url.host()) != std::string::npos);
|
| + EXPECT_TRUE(host_and_port.find(httpsv_url.port()) != std::string::npos);
|
| + EXPECT_EQ("", WideToUTF8(d.last_login_request_info()->realm));
|
| +
|
| + // Now continue with the correct password.
|
| + r.SetTLSLogin(kUser, kSecret);
|
| + r.ContinueWithTLSLogin();
|
| +
|
| + MessageLoop::current()->Run();
|
| + EXPECT_NE(0, d.bytes_received());
|
| + EXPECT_TRUE(d.data_received().find(UTF16ToUTF8(kUser)) !=
|
| + std::string::npos);
|
| + EXPECT_FALSE(d.received_data_before_response());
|
| + }
|
| + }
|
| +}
|
| +
|
| +TEST_F(HTTPSRequestTest, HTTPSVCancelLoginTest) {
|
| + net::TestServer::HTTPSOptions https_options;
|
| + https_options.use_tls_srp = true;
|
| + https_options.only_tls_srp = true;
|
| + net::TestServer test_server(https_options, FilePath());
|
| + ASSERT_TRUE(test_server.Start());
|
| +
|
| + GURL https_url = test_server.GetURL("");
|
| + GURL::Replacements replacements;
|
| + replacements.SetSchemeStr("httpsv");
|
| + GURL httpsv_url = https_url.ReplaceComponents(replacements);
|
| +
|
| + {
|
| + HTTPSVClientSRPLoginTestDelegate d;
|
| +
|
| + TestURLRequest r(httpsv_url, &d);
|
| + r.Start();
|
| + EXPECT_TRUE(r.is_pending());
|
| + MessageLoop::current()->Run();
|
| +
|
| + EXPECT_EQ(0, d.bytes_received());
|
| + EXPECT_EQ(1, d.on_tls_login_required_count());
|
| + EXPECT_FALSE(d.received_data_before_response());
|
| +
|
| + r.CancelTLSLogin();
|
| +
|
| + MessageLoop::current()->Run();
|
| + EXPECT_EQ(0, d.bytes_received());
|
| + EXPECT_FALSE(d.received_data_before_response());
|
| + }
|
| +}
|
| +
|
| TEST_F(URLRequestTestHTTP, CancelTest) {
|
| TestDelegate d;
|
| {
|
|
|