Commit 36d9cd71 authored by Matt Menke's avatar Matt Menke Committed by Commit Bot

Hook up TransportSecurityStatePersister to the network service.

Bug: 837776
Cq-Include-Trybots: master.tryserver.chromium.linux:linux_mojo
Change-Id: I5adf6cbed89f755e7e25c3efdf326aab1c472d67
Reviewed-on: https://chromium-review.googlesource.com/1045365Reviewed-by: default avatarTom Sepez <tsepez@chromium.org>
Reviewed-by: default avatarEmily Stark <estark@chromium.org>
Commit-Queue: Matt Menke <mmenke@chromium.org>
Cr-Commit-Position: refs/heads/master@{#557629}
parent 302b67a5
......@@ -606,6 +606,124 @@ IN_PROC_BROWSER_TEST_P(NetworkContextConfigurationBrowserTest, DiskCache) {
}
}
// Test certs cannot currently be installed on OSX with the network service
// enabled.
// TODO(mmenke): Once that is fixed, enable this test on OSX.
// See https://crbug.com/757088
#if !defined(OS_MACOSX)
// Visits a URL with an HSTS header, and makes sure it is respected.
IN_PROC_BROWSER_TEST_P(NetworkContextConfigurationBrowserTest, PRE_Hsts) {
net::test_server::EmbeddedTestServer ssl_server(
net::test_server::EmbeddedTestServer::TYPE_HTTPS);
ssl_server.SetSSLConfig(
net::test_server::EmbeddedTestServer::CERT_COMMON_NAME_IS_DOMAIN);
ssl_server.AddDefaultHandlers(
base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
ASSERT_TRUE(ssl_server.Start());
// Make a request whose response has an STS header.
std::unique_ptr<network::ResourceRequest> request =
std::make_unique<network::ResourceRequest>();
request->url = ssl_server.GetURL(
"/set-header?Strict-Transport-Security: max-age%3D600000");
content::SimpleURLLoaderTestHelper simple_loader_helper;
std::unique_ptr<network::SimpleURLLoader> simple_loader =
network::SimpleURLLoader::Create(std::move(request),
TRAFFIC_ANNOTATION_FOR_TESTS);
simple_loader->DownloadToStringOfUnboundedSizeUntilCrashAndDie(
loader_factory(), simple_loader_helper.GetCallback());
simple_loader_helper.WaitForCallback();
EXPECT_EQ(net::OK, simple_loader->NetError());
ASSERT_TRUE(simple_loader->ResponseInfo()->headers);
EXPECT_TRUE(simple_loader->ResponseInfo()->headers->HasHeaderValue(
"Strict-Transport-Security", "max-age=600000"));
// Make a cache-only request to make sure the HSTS entry is respected. Using a
// cache-only request both prevents the result from being cached, and makes
// the check identical to the one in the next test, which is run after the
// test server has been shut down.
GURL exected_ssl_url = ssl_server.base_url();
GURL::Replacements replacements;
replacements.SetSchemeStr("http");
GURL start_url = exected_ssl_url.ReplaceComponents(replacements);
request = std::make_unique<network::ResourceRequest>();
request->url = start_url;
request->load_flags = net::LOAD_ONLY_FROM_CACHE;
content::SimpleURLLoaderTestHelper simple_loader_helper2;
simple_loader = network::SimpleURLLoader::Create(
std::move(request), TRAFFIC_ANNOTATION_FOR_TESTS);
simple_loader->DownloadToStringOfUnboundedSizeUntilCrashAndDie(
loader_factory(), simple_loader_helper2.GetCallback());
simple_loader_helper2.WaitForCallback();
EXPECT_FALSE(simple_loader_helper2.response_body());
EXPECT_EQ(exected_ssl_url, simple_loader->GetFinalURL());
// Write the URL with HSTS information to a file, so it can be loaded in the
// next test. Have to use a file for this, since the server's port is random.
base::ScopedAllowBlockingForTesting allow_blocking;
base::FilePath save_url_file_path = browser()->profile()->GetPath().Append(
FILE_PATH_LITERAL("url_for_test.txt"));
std::string file_data = start_url.spec();
ASSERT_EQ(
static_cast<int>(file_data.length()),
base::WriteFile(save_url_file_path, file_data.data(), file_data.size()));
}
// Checks if the HSTS information from the last test is still available after a
// restart.
IN_PROC_BROWSER_TEST_P(NetworkContextConfigurationBrowserTest, Hsts) {
base::ScopedAllowBlockingForTesting allow_blocking;
base::FilePath save_url_file_path = browser()->profile()->GetPath().Append(
FILE_PATH_LITERAL("url_for_test.txt"));
std::string file_data;
ASSERT_TRUE(ReadFileToString(save_url_file_path, &file_data));
GURL start_url = GURL(file_data);
// Unfortunately, loading HSTS information is loaded asynchronously from
// disk, so there's no way to guarantee it has loaded by the time a
// request is made. As a result, may have to try multiple times to verify that
// cached HSTS information has been loaded, when it's stored on disk.
while (true) {
std::unique_ptr<network::ResourceRequest> request =
std::make_unique<network::ResourceRequest>();
request->url = start_url;
request->load_flags = net::LOAD_ONLY_FROM_CACHE;
content::SimpleURLLoaderTestHelper simple_loader_helper;
std::unique_ptr<network::SimpleURLLoader> simple_loader =
network::SimpleURLLoader::Create(std::move(request),
TRAFFIC_ANNOTATION_FOR_TESTS);
simple_loader->DownloadToStringOfUnboundedSizeUntilCrashAndDie(
loader_factory(), simple_loader_helper.GetCallback());
simple_loader_helper.WaitForCallback();
EXPECT_FALSE(simple_loader_helper.response_body());
// HSTS information is currently stored on disk if-and-only-if there's an
// on-disk HTTP cache.
if (GetHttpCacheType() == StorageType::kDisk) {
GURL::Replacements replacements;
replacements.SetSchemeStr("https");
GURL expected_https_url = start_url.ReplaceComponents(replacements);
// The file may not have been loaded yet, so if the cached HSTS
// information was not respected, try again.
if (expected_https_url != simple_loader->GetFinalURL())
continue;
EXPECT_EQ(expected_https_url, simple_loader->GetFinalURL());
break;
} else {
EXPECT_EQ(start_url, simple_loader->GetFinalURL());
break;
}
}
}
#endif // !defined(OS_MACOSX)
IN_PROC_BROWSER_TEST_P(NetworkContextConfigurationBrowserTest, ProxyConfig) {
SetProxyPref(embedded_test_server()->host_port_pair());
TestProxyConfigured();
......@@ -968,6 +1086,7 @@ IN_PROC_BROWSER_TEST_P(NetworkContextConfigurationHttpsStrippingPacBrowserTest,
}
// |NetworkServiceTestHelper| doesn't work on browser_tests on OSX.
// See https://crbug.com/757088
#if defined(OS_MACOSX)
// Instiates tests with a prefix indicating which NetworkContext is being
// tested, and a suffix of "/0" if the network service is disabled and "/1" if
......
......@@ -209,6 +209,8 @@ ProfileNetworkContextService::CreateNetworkContextParams(
network_context_params->restore_old_session_cookies = false;
network_context_params->persist_session_cookies = false;
}
network_context_params->transport_security_persister_path = path;
}
// NOTE(mmenke): Keep these protocol handlers and
......
......@@ -1101,9 +1101,6 @@ void ProfileIOData::Init(
io_thread->SetUpProxyService(builder.get());
if (!IsOffTheRecord())
builder->set_transport_security_persister_path(profile_params_->path);
// Take ownership over these parameters.
cookie_settings_ = profile_params_->cookie_settings;
host_content_settings_map_ = profile_params_->host_content_settings_map;
......
......@@ -554,6 +554,11 @@ URLRequestContextOwner NetworkContext::ApplyContextParamsToBuilder(
net_log));
}
if (network_context_params->transport_security_persister_path) {
builder->set_transport_security_persister_path(
*network_context_params->transport_security_persister_path);
}
builder->set_data_enabled(network_context_params->enable_data_url_support);
#if !BUILDFLAG(DISABLE_FILE_SUPPORT)
builder->set_file_enabled(network_context_params->enable_file_url_support);
......
......@@ -646,6 +646,61 @@ TEST_F(NetworkContextTest, ClearHttpServerPropertiesInMemory) {
->GetSupportsSpdy(kSchemeHostPort));
}
// Test that TransportSecurity state is persisted (or not) as expected.
TEST_F(NetworkContextTest, TransportSecurityStatePersisted) {
const char kDomain[] = "foo.test";
base::ScopedTempDir temp_dir;
ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
base::FilePath transport_security_persister_path = temp_dir.GetPath();
base::FilePath transport_security_persister_file_path =
transport_security_persister_path.AppendASCII("TransportSecurity");
EXPECT_FALSE(base::PathExists(transport_security_persister_file_path));
for (bool on_disk : {false, true}) {
// Create a NetworkContext.
mojom::NetworkContextParamsPtr context_params = CreateContextParams();
if (on_disk) {
context_params->transport_security_persister_path =
transport_security_persister_path;
}
std::unique_ptr<NetworkContext> network_context =
CreateContextWithParams(std::move(context_params));
// Add an STS entry.
net::TransportSecurityState::STSState sts_state;
net::TransportSecurityState* state =
network_context->url_request_context()->transport_security_state();
EXPECT_FALSE(state->GetDynamicSTSState(kDomain, &sts_state));
state->AddHSTS(kDomain,
base::Time::Now() + base::TimeDelta::FromSecondsD(1000),
false /* include subdomains */);
EXPECT_TRUE(state->GetDynamicSTSState(kDomain, &sts_state));
ASSERT_EQ(kDomain, sts_state.domain);
// Destroy the network context, and wait for all tasks to write state to
// disk to finish running.
network_context.reset();
scoped_task_environment_.RunUntilIdle();
EXPECT_EQ(on_disk,
base::PathExists(transport_security_persister_file_path));
// Create a new NetworkContext,with the same parameters, and check if the
// added STS entry still exists.
context_params = CreateContextParams();
if (on_disk) {
context_params->transport_security_persister_path =
transport_security_persister_path;
}
network_context = CreateContextWithParams(std::move(context_params));
// Wait for the entry to load.
scoped_task_environment_.RunUntilIdle();
state = network_context->url_request_context()->transport_security_state();
ASSERT_EQ(on_disk, state->GetDynamicSTSState(kDomain, &sts_state));
if (on_disk)
EXPECT_EQ(kDomain, sts_state.domain);
}
}
// Validates that clearing the HTTP cache when no cache exists does complete.
TEST_F(NetworkContextTest, ClearHttpCacheWithNoCache) {
mojom::NetworkContextParamsPtr context_params = CreateContextParams();
......
......@@ -80,6 +80,11 @@ struct NetworkContextParams {
// logic. If null, an in-memory cache will be used instead.
mojo_base.mojom.FilePath? http_server_properties_path;
// The directory in which to store cached transport security properties (like
// HSTS). The file itself will be called "TransportSecurity". If null, or the
// file can't be opened, an in-memory store will be used instead.
mojo_base.mojom.FilePath? transport_security_persister_path;
// Enabled protocols. Note that these apply to all fetches, including those
// used to fetch PAC scripts.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment