| // Copyright 2020 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/stub_resolver_config_reader.h" |
| |
| #include <memory> |
| #include <vector> |
| |
| #include "base/test/task_environment.h" |
| #include "base/values.h" |
| #include "chrome/browser/net/secure_dns_config.h" |
| #include "chrome/common/pref_names.h" |
| #include "chrome/test/base/scoped_testing_local_state.h" |
| #include "components/prefs/pref_service.h" |
| #include "components/prefs/testing_pref_service.h" |
| #include "content/public/test/browser_task_environment.h" |
| #include "net/dns/public/dns_over_https_server_config.h" |
| #include "net/dns/public/secure_dns_mode.h" |
| #include "testing/gmock/include/gmock/gmock.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| namespace { |
| |
| constexpr char kDohServerTemplate[] = |
| "https://doh1.test https://doh2.test/query{?dns}"; |
| |
| // Override the reader to mock out the ShouldDisableDohFor...() methods. |
| class MockedStubResolverConfigReader : public StubResolverConfigReader { |
| public: |
| explicit MockedStubResolverConfigReader(PrefService* local_state) |
| : StubResolverConfigReader(local_state, |
| false /* set_up_pref_defaults */) {} |
| |
| bool ShouldDisableDohForManaged() override { return disable_for_managed_; } |
| |
| bool ShouldDisableDohForParentalControls() override { |
| parental_controls_checked_ = true; |
| return disable_for_parental_controls_; |
| } |
| |
| void set_disable_for_managed() { disable_for_managed_ = true; } |
| |
| void set_disable_for_parental_controls() { |
| disable_for_parental_controls_ = true; |
| } |
| |
| bool parental_controls_checked() { return parental_controls_checked_; } |
| |
| private: |
| bool disable_for_managed_ = false; |
| bool disable_for_parental_controls_ = false; |
| |
| bool parental_controls_checked_ = false; |
| }; |
| |
| class StubResolverConfigReaderTest : public testing::Test { |
| public: |
| StubResolverConfigReaderTest() { |
| StubResolverConfigReader::RegisterPrefs(local_state_.registry()); |
| } |
| |
| protected: |
| content::BrowserTaskEnvironment task_environment_{ |
| base::test::TaskEnvironment::TimeSource::MOCK_TIME}; |
| TestingPrefServiceSimple local_state_; |
| std::unique_ptr<MockedStubResolverConfigReader> config_reader_ = |
| std::make_unique<MockedStubResolverConfigReader>(&local_state_); |
| }; |
| |
| TEST_F(StubResolverConfigReaderTest, GetSecureDnsConfiguration) { |
| // |force_check_parental_controls_for_automatic_mode = true| is not the main |
| // default case, but the specific behavior involved is tested separately. |
| SecureDnsConfig secure_dns_config = config_reader_->GetSecureDnsConfiguration( |
| true /* force_check_parental_controls_for_automatic_mode */); |
| |
| EXPECT_FALSE(config_reader_->GetInsecureStubResolverEnabled()); |
| EXPECT_EQ(net::SecureDnsMode::kOff, secure_dns_config.mode()); |
| EXPECT_TRUE(secure_dns_config.servers().empty()); |
| |
| // Parental controls should not be checked when DoH otherwise disabled. |
| EXPECT_FALSE(config_reader_->parental_controls_checked()); |
| } |
| |
| TEST_F(StubResolverConfigReaderTest, DohEnabled) { |
| local_state_.SetBoolean(prefs::kBuiltInDnsClientEnabled, true); |
| local_state_.SetString(prefs::kDnsOverHttpsMode, |
| SecureDnsConfig::kModeAutomatic); |
| local_state_.SetString(prefs::kDnsOverHttpsTemplates, kDohServerTemplate); |
| |
| // |force_check_parental_controls_for_automatic_mode = true| is not the main |
| // default case, but the specific behavior involved is tested separately. |
| SecureDnsConfig secure_dns_config = config_reader_->GetSecureDnsConfiguration( |
| true /* force_check_parental_controls_for_automatic_mode */); |
| |
| EXPECT_TRUE(config_reader_->GetInsecureStubResolverEnabled()); |
| EXPECT_EQ(net::SecureDnsMode::kAutomatic, secure_dns_config.mode()); |
| EXPECT_THAT(secure_dns_config.servers(), |
| testing::ElementsAre( |
| net::DnsOverHttpsServerConfig("https://doh1.test", |
| true /* use_post */), |
| net::DnsOverHttpsServerConfig("https://doh2.test/query{?dns}", |
| false /* use_post */))); |
| |
| EXPECT_TRUE(config_reader_->parental_controls_checked()); |
| } |
| |
| TEST_F(StubResolverConfigReaderTest, DohEnabled_Secure) { |
| local_state_.SetBoolean(prefs::kBuiltInDnsClientEnabled, true); |
| local_state_.SetString(prefs::kDnsOverHttpsMode, |
| SecureDnsConfig::kModeSecure); |
| local_state_.SetString(prefs::kDnsOverHttpsTemplates, kDohServerTemplate); |
| |
| // |force_check_parental_controls_for_automatic_mode| should have no effect on |
| // SECURE mode, so set to false to ensure check is not deferred. |
| SecureDnsConfig secure_dns_config = config_reader_->GetSecureDnsConfiguration( |
| false /* force_check_parental_controls_for_automatic_mode */); |
| |
| EXPECT_TRUE(config_reader_->GetInsecureStubResolverEnabled()); |
| EXPECT_EQ(net::SecureDnsMode::kSecure, secure_dns_config.mode()); |
| EXPECT_THAT(secure_dns_config.servers(), |
| testing::ElementsAre( |
| net::DnsOverHttpsServerConfig("https://doh1.test", |
| true /* use_post */), |
| net::DnsOverHttpsServerConfig("https://doh2.test/query{?dns}", |
| false /* use_post */))); |
| |
| EXPECT_TRUE(config_reader_->parental_controls_checked()); |
| } |
| |
| TEST_F(StubResolverConfigReaderTest, DisabledForManaged) { |
| config_reader_->set_disable_for_managed(); |
| |
| local_state_.SetBoolean(prefs::kBuiltInDnsClientEnabled, true); |
| local_state_.SetString(prefs::kDnsOverHttpsMode, |
| SecureDnsConfig::kModeAutomatic); |
| local_state_.SetString(prefs::kDnsOverHttpsTemplates, kDohServerTemplate); |
| |
| // |force_check_parental_controls_for_automatic_mode = true| is not the main |
| // default case, but the specific behavior involved is tested separately. |
| SecureDnsConfig secure_dns_config = config_reader_->GetSecureDnsConfiguration( |
| true /* force_check_parental_controls_for_automatic_mode */); |
| |
| EXPECT_TRUE(config_reader_->GetInsecureStubResolverEnabled()); |
| EXPECT_EQ(net::SecureDnsMode::kOff, secure_dns_config.mode()); |
| EXPECT_TRUE(secure_dns_config.servers().empty()); |
| |
| // Parental controls should not be checked when DoH otherwise disabled. |
| EXPECT_FALSE(config_reader_->parental_controls_checked()); |
| } |
| |
| TEST_F(StubResolverConfigReaderTest, DisabledForManaged_Secure) { |
| config_reader_->set_disable_for_managed(); |
| |
| local_state_.SetBoolean(prefs::kBuiltInDnsClientEnabled, true); |
| local_state_.SetString(prefs::kDnsOverHttpsMode, |
| SecureDnsConfig::kModeSecure); |
| local_state_.SetString(prefs::kDnsOverHttpsTemplates, kDohServerTemplate); |
| |
| SecureDnsConfig secure_dns_config = config_reader_->GetSecureDnsConfiguration( |
| false /* force_check_parental_controls_for_automatic_mode */); |
| |
| EXPECT_TRUE(config_reader_->GetInsecureStubResolverEnabled()); |
| EXPECT_EQ(net::SecureDnsMode::kOff, secure_dns_config.mode()); |
| EXPECT_TRUE(secure_dns_config.servers().empty()); |
| |
| // Parental controls should not be checked when DoH otherwise disabled. |
| EXPECT_FALSE(config_reader_->parental_controls_checked()); |
| } |
| |
| TEST_F(StubResolverConfigReaderTest, DisabledForParentalControls) { |
| config_reader_->set_disable_for_parental_controls(); |
| |
| local_state_.SetBoolean(prefs::kBuiltInDnsClientEnabled, true); |
| local_state_.SetString(prefs::kDnsOverHttpsMode, |
| SecureDnsConfig::kModeAutomatic); |
| local_state_.SetString(prefs::kDnsOverHttpsTemplates, kDohServerTemplate); |
| |
| // |force_check_parental_controls_for_automatic_mode = true| is not the main |
| // default case, but the specific behavior involved is tested separately. |
| SecureDnsConfig secure_dns_config = config_reader_->GetSecureDnsConfiguration( |
| true /* force_check_parental_controls_for_automatic_mode */); |
| |
| EXPECT_TRUE(config_reader_->GetInsecureStubResolverEnabled()); |
| EXPECT_EQ(net::SecureDnsMode::kOff, secure_dns_config.mode()); |
| EXPECT_TRUE(secure_dns_config.servers().empty()); |
| |
| EXPECT_TRUE(config_reader_->parental_controls_checked()); |
| } |
| |
| TEST_F(StubResolverConfigReaderTest, DisabledForParentalControls_Secure) { |
| config_reader_->set_disable_for_parental_controls(); |
| |
| local_state_.SetBoolean(prefs::kBuiltInDnsClientEnabled, true); |
| local_state_.SetString(prefs::kDnsOverHttpsMode, |
| SecureDnsConfig::kModeSecure); |
| local_state_.SetString(prefs::kDnsOverHttpsTemplates, kDohServerTemplate); |
| |
| // |force_check_parental_controls_for_automatic_mode| should have no effect on |
| // SECURE mode, so set to false to ensure check is not deferred. |
| SecureDnsConfig secure_dns_config = config_reader_->GetSecureDnsConfiguration( |
| false /* force_check_parental_controls_for_automatic_mode */); |
| |
| EXPECT_TRUE(config_reader_->GetInsecureStubResolverEnabled()); |
| EXPECT_EQ(net::SecureDnsMode::kOff, secure_dns_config.mode()); |
| EXPECT_TRUE(secure_dns_config.servers().empty()); |
| |
| EXPECT_TRUE(config_reader_->parental_controls_checked()); |
| } |
| |
| TEST_F(StubResolverConfigReaderTest, DeferredParentalControlsCheck) { |
| config_reader_->set_disable_for_parental_controls(); |
| |
| local_state_.SetBoolean(prefs::kBuiltInDnsClientEnabled, true); |
| local_state_.SetString(prefs::kDnsOverHttpsMode, |
| SecureDnsConfig::kModeAutomatic); |
| local_state_.SetString(prefs::kDnsOverHttpsTemplates, kDohServerTemplate); |
| |
| SecureDnsConfig secure_dns_config = config_reader_->GetSecureDnsConfiguration( |
| false /* force_check_parental_controls_for_automatic_mode */); |
| |
| // Parental controls check initially skipped. |
| EXPECT_TRUE(config_reader_->GetInsecureStubResolverEnabled()); |
| EXPECT_EQ(net::SecureDnsMode::kAutomatic, secure_dns_config.mode()); |
| EXPECT_THAT(secure_dns_config.servers(), |
| testing::ElementsAre( |
| net::DnsOverHttpsServerConfig("https://doh1.test", |
| true /* use_post */), |
| net::DnsOverHttpsServerConfig("https://doh2.test/query{?dns}", |
| false /* use_post */))); |
| EXPECT_FALSE(config_reader_->parental_controls_checked()); |
| |
| task_environment_.AdvanceClock( |
| StubResolverConfigReader::kParentalControlsCheckDelay); |
| task_environment_.RunUntilIdle(); |
| |
| EXPECT_TRUE(config_reader_->parental_controls_checked()); |
| |
| secure_dns_config = config_reader_->GetSecureDnsConfiguration( |
| false /* force_check_parental_controls_for_automatic_mode */); |
| |
| EXPECT_TRUE(config_reader_->GetInsecureStubResolverEnabled()); |
| EXPECT_EQ(net::SecureDnsMode::kOff, secure_dns_config.mode()); |
| EXPECT_TRUE(secure_dns_config.servers().empty()); |
| } |
| |
| TEST_F(StubResolverConfigReaderTest, DeferredParentalControlsCheck_Managed) { |
| config_reader_->set_disable_for_managed(); |
| config_reader_->set_disable_for_parental_controls(); |
| |
| local_state_.SetBoolean(prefs::kBuiltInDnsClientEnabled, true); |
| local_state_.SetManagedPref( |
| prefs::kDnsOverHttpsMode, |
| std::make_unique<base::Value>(SecureDnsConfig::kModeAutomatic)); |
| local_state_.SetManagedPref( |
| prefs::kDnsOverHttpsTemplates, |
| std::make_unique<base::Value>(kDohServerTemplate)); |
| |
| SecureDnsConfig secure_dns_config = config_reader_->GetSecureDnsConfiguration( |
| false /* force_check_parental_controls_for_automatic_mode */); |
| |
| // Parental controls check initially skipped, and managed prefs take |
| // precedence over disables. |
| EXPECT_TRUE(config_reader_->GetInsecureStubResolverEnabled()); |
| EXPECT_EQ(net::SecureDnsMode::kAutomatic, secure_dns_config.mode()); |
| EXPECT_THAT(secure_dns_config.servers(), |
| testing::ElementsAre( |
| net::DnsOverHttpsServerConfig("https://doh1.test", |
| true /* use_post */), |
| net::DnsOverHttpsServerConfig("https://doh2.test/query{?dns}", |
| false /* use_post */))); |
| EXPECT_FALSE(config_reader_->parental_controls_checked()); |
| |
| task_environment_.AdvanceClock( |
| StubResolverConfigReader::kParentalControlsCheckDelay); |
| task_environment_.RunUntilIdle(); |
| |
| EXPECT_TRUE(config_reader_->parental_controls_checked()); |
| |
| secure_dns_config = config_reader_->GetSecureDnsConfiguration( |
| false /* force_check_parental_controls_for_automatic_mode */); |
| |
| // Expect DoH still enabled after parental controls check because managed |
| // prefs have precedence. |
| EXPECT_TRUE(config_reader_->GetInsecureStubResolverEnabled()); |
| EXPECT_EQ(net::SecureDnsMode::kAutomatic, secure_dns_config.mode()); |
| EXPECT_THAT(secure_dns_config.servers(), |
| testing::ElementsAre( |
| net::DnsOverHttpsServerConfig("https://doh1.test", |
| true /* use_post */), |
| net::DnsOverHttpsServerConfig("https://doh2.test/query{?dns}", |
| false /* use_post */))); |
| } |
| |
| } // namespace |