From bbbcc62c36cd9bc74ac57530aff1d4cf7316170a Mon Sep 17 00:00:00 2001 From: Jocelyn Liu Date: Wed, 3 Mar 2021 10:23:58 -0800 Subject: [PATCH 1/6] Merge pull request #7702 from brave/unstoppable_domains Support Unstoppable Domains via DNS over HTTPS behind a feature flag --- app/brave_generated_resources.grd | 3 + browser/BUILD.gn | 6 + browser/brave_content_browser_client.cc | 18 +- browser/brave_local_state_prefs.cc | 10 + browser/extensions/BUILD.gn | 6 + .../api/settings_private/brave_prefs_util.cc | 11 + browser/profiles/BUILD.gn | 2 +- browser/profiles/brave_profile_manager.cc | 8 + .../brave_default_extensions_browser_proxy.js | 4 + .../brave_default_extensions_page.html | 8 + .../brave_default_extensions_page.js | 17 +- browser/ui/BUILD.gn | 6 + .../brave_default_extensions_handler.cc | 23 + .../brave_default_extensions_handler.h | 1 + browser/unstoppable_domains/BUILD.gn | 28 + browser/unstoppable_domains/test/BUILD.gn | 47 + ...domains_navigation_throttle_browsertest.cc | 134 +++ ...unstoppable_domains_service_browsertest.cc | 128 +++ .../test/utils_unittest.cc | 73 ++ ...stoppable_domains_service_delegate_impl.cc | 19 + ...nstoppable_domains_service_delegate_impl.h | 29 + .../unstoppable_domains_service_factory.cc | 49 + .../unstoppable_domains_service_factory.h | 41 + build/config/brave_build.gni | 5 +- chromium_src/chrome/browser/about_flags.cc | 14 + .../chrome/browser/flag_descriptions.cc | 3 + .../chrome/browser/flag_descriptions.h | 2 + .../net/stub_resolver_config_reader.cc | 55 + .../settings_localized_strings_provider.cc | 2 + chromium_src/net/DEPS | 1 + .../net/base/lookup_string_in_fixed_set.cc | 10 + chromium_src/net/dns/dns_transaction.cc | 41 + components/resources/BUILD.gn | 3 + .../resources/brave_components_resources.grd | 1 + .../resources/brave_components_strings.grd | 1 + .../unstoppable_domains_resources.grdp | 8 + .../unstoppable_domains_strings.grdp | 20 + components/unstoppable_domains/BUILD.gn | 37 + components/unstoppable_domains/DEPS | 14 + .../unstoppable_domains/buildflags/BUILD.gn | 7 + .../buildflags/buildflags.gni | 3 + components/unstoppable_domains/constants.h | 19 + components/unstoppable_domains/features.h | 20 + components/unstoppable_domains/pref_names.h | 20 + .../unstoppable_domains_interstitial.css | 14 + .../unstoppable_domains_interstitial.html | 31 + .../unstoppable_domains_interstitial.js | 21 + ..._domains_interstitial_controller_client.cc | 59 + ...e_domains_interstitial_controller_client.h | 60 + ...unstoppable_domains_navigation_throttle.cc | 93 ++ .../unstoppable_domains_navigation_throttle.h | 58 + .../unstoppable_domains_opt_in_page.cc | 111 ++ .../unstoppable_domains_opt_in_page.h | 58 + .../unstoppable_domains_service.cc | 45 + .../unstoppable_domains_service.h | 48 + .../unstoppable_domains_service_delegate.h | 20 + components/unstoppable_domains/utils.cc | 45 + components/unstoppable_domains/utils.h | 21 + net/dns/dns_transaction_unittest.cc | 1023 +++++++++++++++++ net/dns/sources.gni | 6 + net/sources.gni | 3 + net/unstoppable_domains/constants.h | 17 + ...r-net-stub_resolver_config_reader.cc.patch | 12 + patches/net-dns-BUILD.gn.patch | 28 + patches/net-dns-dns_transaction.cc.patch | 12 + test/BUILD.gn | 9 + 66 files changed, 2746 insertions(+), 5 deletions(-) create mode 100644 browser/unstoppable_domains/BUILD.gn create mode 100644 browser/unstoppable_domains/test/BUILD.gn create mode 100644 browser/unstoppable_domains/test/unstoppable_domains_navigation_throttle_browsertest.cc create mode 100644 browser/unstoppable_domains/test/unstoppable_domains_service_browsertest.cc create mode 100644 browser/unstoppable_domains/test/utils_unittest.cc create mode 100644 browser/unstoppable_domains/unstoppable_domains_service_delegate_impl.cc create mode 100644 browser/unstoppable_domains/unstoppable_domains_service_delegate_impl.h create mode 100644 browser/unstoppable_domains/unstoppable_domains_service_factory.cc create mode 100644 browser/unstoppable_domains/unstoppable_domains_service_factory.h create mode 100644 chromium_src/chrome/browser/net/stub_resolver_config_reader.cc create mode 100644 chromium_src/net/dns/dns_transaction.cc create mode 100644 components/resources/unstoppable_domains_resources.grdp create mode 100644 components/resources/unstoppable_domains_strings.grdp create mode 100644 components/unstoppable_domains/BUILD.gn create mode 100644 components/unstoppable_domains/DEPS create mode 100644 components/unstoppable_domains/buildflags/BUILD.gn create mode 100644 components/unstoppable_domains/buildflags/buildflags.gni create mode 100644 components/unstoppable_domains/constants.h create mode 100644 components/unstoppable_domains/features.h create mode 100644 components/unstoppable_domains/pref_names.h create mode 100644 components/unstoppable_domains/resources/unstoppable_domains_interstitial.css create mode 100644 components/unstoppable_domains/resources/unstoppable_domains_interstitial.html create mode 100644 components/unstoppable_domains/resources/unstoppable_domains_interstitial.js create mode 100644 components/unstoppable_domains/unstoppable_domains_interstitial_controller_client.cc create mode 100644 components/unstoppable_domains/unstoppable_domains_interstitial_controller_client.h create mode 100644 components/unstoppable_domains/unstoppable_domains_navigation_throttle.cc create mode 100644 components/unstoppable_domains/unstoppable_domains_navigation_throttle.h create mode 100644 components/unstoppable_domains/unstoppable_domains_opt_in_page.cc create mode 100644 components/unstoppable_domains/unstoppable_domains_opt_in_page.h create mode 100644 components/unstoppable_domains/unstoppable_domains_service.cc create mode 100644 components/unstoppable_domains/unstoppable_domains_service.h create mode 100644 components/unstoppable_domains/unstoppable_domains_service_delegate.h create mode 100644 components/unstoppable_domains/utils.cc create mode 100644 components/unstoppable_domains/utils.h create mode 100644 net/dns/dns_transaction_unittest.cc create mode 100644 net/dns/sources.gni create mode 100644 net/unstoppable_domains/constants.h create mode 100644 patches/chrome-browser-net-stub_resolver_config_reader.cc.patch create mode 100644 patches/net-dns-BUILD.gn.patch create mode 100644 patches/net-dns-dns_transaction.cc.patch diff --git a/app/brave_generated_resources.grd b/app/brave_generated_resources.grd index b1fc3b0d7439..10d6f8da5a36 100644 --- a/app/brave_generated_resources.grd +++ b/app/brave_generated_resources.grd @@ -694,6 +694,9 @@ By installing this extension, you are agreeing to the Google Widevine Terms of U Allow Google login for extensions + + Method to resolve Unstoppable Domains + Method to resolve IPFS resources diff --git a/browser/BUILD.gn b/browser/BUILD.gn index 688213df4c44..edc79926ebe1 100644 --- a/browser/BUILD.gn +++ b/browser/BUILD.gn @@ -16,6 +16,7 @@ import("//brave/components/ipfs/buildflags/buildflags.gni") import("//brave/components/sidebar/buildflags/buildflags.gni") import("//brave/components/speedreader/buildflags.gni") import("//brave/components/tor/buildflags/buildflags.gni") +import("//brave/components/unstoppable_domains/buildflags/buildflags.gni") import("//build/buildflag_header.gni") import("//build/config/features.gni") import("//chrome/common/features.gni") @@ -154,6 +155,7 @@ source_set("browser_process") { "//brave/components/sidebar/buildflags", "//brave/components/speedreader:buildflags", "//brave/components/tor/buildflags", + "//brave/components/unstoppable_domains/buildflags", "//brave/components/weekly_storage", "//brave/services/network/public/cpp", "//brave/ui/brave_ads", @@ -289,6 +291,10 @@ source_set("browser_process") { ] } + if (unstoppable_domains_enabled) { + deps += [ "//brave/browser/unstoppable_domains" ] + } + if (ipfs_enabled) { sources += [ "ipfs/content_browser_client_helper.cc", diff --git a/browser/brave_content_browser_client.cc b/browser/brave_content_browser_client.cc index 123c3d79ad66..8fec950fb4f6 100644 --- a/browser/brave_content_browser_client.cc +++ b/browser/brave_content_browser_client.cc @@ -35,6 +35,7 @@ #include "brave/components/ipfs/buildflags/buildflags.h" #include "brave/components/speedreader/buildflags.h" #include "brave/components/tor/buildflags/buildflags.h" +#include "brave/components/unstoppable_domains/buildflags/buildflags.h" #include "brave/grit/brave_generated_resources.h" #include "chrome/browser/chrome_content_browser_client.h" #include "chrome/browser/content_settings/host_content_settings_map_factory.h" @@ -88,6 +89,10 @@ using extensions::ChromeContentBrowserClientExtensionsPart; #include "brave/components/ipfs/ipfs_navigation_throttle.h" #endif +#if BUILDFLAG(UNSTOPPABLE_DOMAINS_ENABLED) +#include "brave/components/unstoppable_domains/unstoppable_domains_navigation_throttle.h" +#endif + #if BUILDFLAG(BRAVE_REWARDS_ENABLED) #include "brave/components/brave_rewards/browser/rewards_protocol_handler.h" #endif @@ -585,7 +590,8 @@ BraveContentBrowserClient::CreateThrottlesForNavigation( std::make_unique(handle)); #endif -#if BUILDFLAG(ENABLE_TOR) ||BUILDFLAG(IPFS_ENABLED) +#if BUILDFLAG(ENABLE_TOR) || BUILDFLAG(IPFS_ENABLED) || \ + BUILDFLAG(UNSTOPPABLE_DOMAINS_ENABLED) content::BrowserContext* context = handle->GetWebContents()->GetBrowserContext(); #endif @@ -618,5 +624,15 @@ BraveContentBrowserClient::CreateThrottlesForNavigation( throttles.push_back(std::move(ipfs_navigation_throttle)); #endif +#if BUILDFLAG(UNSTOPPABLE_DOMAINS_ENABLED) + std::unique_ptr + unstoppable_domains_navigation_throttle = unstoppable_domains:: + UnstoppableDomainsNavigationThrottle::MaybeCreateThrottleFor( + handle, g_brave_browser_process->local_state(), + g_brave_browser_process->GetApplicationLocale()); + if (unstoppable_domains_navigation_throttle) + throttles.push_back(std::move(unstoppable_domains_navigation_throttle)); +#endif + return throttles; } diff --git a/browser/brave_local_state_prefs.cc b/browser/brave_local_state_prefs.cc index 42b92a71c263..667ee1120ca0 100644 --- a/browser/brave_local_state_prefs.cc +++ b/browser/brave_local_state_prefs.cc @@ -18,6 +18,7 @@ #include "brave/components/p3a/brave_p3a_service.h" #include "brave/components/p3a/buildflags.h" #include "brave/components/tor/buildflags/buildflags.h" +#include "brave/components/unstoppable_domains/buildflags/buildflags.h" #include "chrome/common/pref_names.h" #include "components/metrics/metrics_pref_names.h" #include "components/prefs/pref_registry_simple.h" @@ -42,6 +43,10 @@ #include "brave/browser/widevine/widevine_utils.h" #endif +#if BUILDFLAG(UNSTOPPABLE_DOMAINS_ENABLED) +#include "brave/components/unstoppable_domains/unstoppable_domains_service.h" +#endif + namespace brave { void RegisterLocalStatePrefsForMigration(PrefRegistrySimple* registry) { @@ -95,6 +100,11 @@ void RegisterLocalStatePrefs(PrefRegistrySimple* registry) { RegisterWidevineLocalstatePrefs(registry); #endif +#if BUILDFLAG(UNSTOPPABLE_DOMAINS_ENABLED) + unstoppable_domains::UnstoppableDomainsService::RegisterLocalStatePrefs( + registry); +#endif + RegisterLocalStatePrefsForMigration(registry); } diff --git a/browser/extensions/BUILD.gn b/browser/extensions/BUILD.gn index 0a95f5484c90..fe2f08ba4840 100644 --- a/browser/extensions/BUILD.gn +++ b/browser/extensions/BUILD.gn @@ -10,6 +10,7 @@ import("//brave/components/gemini/browser/buildflags/buildflags.gni") import("//brave/components/ipfs/buildflags/buildflags.gni") import("//brave/components/sidebar/buildflags/buildflags.gni") import("//brave/components/tor/buildflags/buildflags.gni") +import("//brave/components/unstoppable_domains/buildflags/buildflags.gni") import("//build/config/features.gni") import("//components/gcm_driver/config.gni") @@ -67,6 +68,7 @@ source_set("extensions") { "//brave/components/ipfs/buildflags", "//brave/components/sidebar/buildflags", "//brave/components/tor/buildflags", + "//brave/components/unstoppable_domains/buildflags", "//chrome/browser/extensions", "//chrome/common", "//components/gcm_driver:gcm_buildflags", @@ -111,6 +113,10 @@ source_set("extensions") { deps += [ "//brave/components/ipfs" ] } + if (unstoppable_domains_enabled) { + deps += [ "//brave/components/unstoppable_domains" ] + } + if (brave_rewards_enabled) { sources += [ "api/brave_rewards_api.cc", diff --git a/browser/extensions/api/settings_private/brave_prefs_util.cc b/browser/extensions/api/settings_private/brave_prefs_util.cc index a626ca1a3f68..682c4c2767be 100644 --- a/browser/extensions/api/settings_private/brave_prefs_util.cc +++ b/browser/extensions/api/settings_private/brave_prefs_util.cc @@ -14,6 +14,7 @@ #include "brave/components/ntp_background_images/common/pref_names.h" #include "brave/components/sidebar/buildflags/buildflags.h" #include "brave/components/tor/buildflags/buildflags.h" +#include "brave/components/unstoppable_domains/buildflags/buildflags.h" #include "chrome/browser/extensions/api/settings_private/prefs_util.h" #include "chrome/common/extensions/api/settings_private.h" #include "chrome/common/pref_names.h" @@ -45,6 +46,10 @@ #include "brave/components/tor/pref_names.h" #endif +#if BUILDFLAG(UNSTOPPABLE_DOMAINS_ENABLED) +#include "brave/components/unstoppable_domains/pref_names.h" +#endif + namespace extensions { using ntp_background_images::prefs::kNewTabPageShowBackgroundImage; @@ -207,6 +212,12 @@ const PrefsUtil::TypedPrefMap& BravePrefsUtil::GetAllowlistedKeys() { (*s_brave_allowlist)[prefs::kWebRTCIPHandlingPolicy] = settings_api::PrefType::PREF_TYPE_STRING; +#if BUILDFLAG(UNSTOPPABLE_DOMAINS_ENABLED) + // Unstoppable Domains pref + (*s_brave_allowlist)[unstoppable_domains::kResolveMethod] = + settings_api::PrefType::PREF_TYPE_NUMBER; +#endif + return *s_brave_allowlist; } diff --git a/browser/profiles/BUILD.gn b/browser/profiles/BUILD.gn index b714402d2469..43138a45ec71 100644 --- a/browser/profiles/BUILD.gn +++ b/browser/profiles/BUILD.gn @@ -33,11 +33,11 @@ source_set("profiles") { "//brave/components/brave_rewards/browser", "//brave/components/brave_sync:prefs", "//brave/components/brave_wallet/buildflags", - "//brave/components/brave_wallet/buildflags", "//brave/components/content_settings/core/browser", "//brave/components/ipfs/buildflags", "//brave/components/ntp_background_images/common", "//brave/components/tor", + "//brave/components/unstoppable_domains/buildflags", "//brave/content:browser", "//chrome/common", "//components/gcm_driver:gcm_buildflags", diff --git a/browser/profiles/brave_profile_manager.cc b/browser/profiles/brave_profile_manager.cc index 1c6d7a895242..64b7ddb880cd 100644 --- a/browser/profiles/brave_profile_manager.cc +++ b/browser/profiles/brave_profile_manager.cc @@ -19,6 +19,7 @@ #include "brave/components/content_settings/core/browser/brave_content_settings_pref_provider.h" #include "brave/components/ipfs/buildflags/buildflags.h" #include "brave/components/tor/tor_constants.h" +#include "brave/components/unstoppable_domains/buildflags/buildflags.h" #include "brave/content/browser/webui/brave_shared_resources_data_source.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/chrome_notification_types.h" @@ -50,6 +51,10 @@ #include "brave/browser/ipfs/ipfs_service_factory.h" #endif +#if BUILDFLAG(UNSTOPPABLE_DOMAINS_ENABLED) +#include "brave/browser/unstoppable_domains/unstoppable_domains_service_factory.h" +#endif + using content::BrowserThread; BraveProfileManager::BraveProfileManager(const base::FilePath& user_data_dir) @@ -108,6 +113,9 @@ void BraveProfileManager::DoFinalInitForServices(Profile* profile, #if BUILDFLAG(IPFS_ENABLED) ipfs::IpfsServiceFactory::GetForContext(profile); #endif +#if BUILDFLAG(UNSTOPPABLE_DOMAINS_ENABLED) + unstoppable_domains::UnstoppableDomainsServiceFactory::GetForContext(profile); +#endif #if !BUILDFLAG(USE_GCM_FROM_PLATFORM) gcm::BraveGCMChannelStatus* status = gcm::BraveGCMChannelStatus::GetForProfile(profile); diff --git a/browser/resources/settings/brave_default_extensions_page/brave_default_extensions_browser_proxy.js b/browser/resources/settings/brave_default_extensions_page/brave_default_extensions_browser_proxy.js index c897a37c0923..279ff0189f6b 100644 --- a/browser/resources/settings/brave_default_extensions_page/brave_default_extensions_browser_proxy.js +++ b/browser/resources/settings/brave_default_extensions_page/brave_default_extensions_browser_proxy.js @@ -67,6 +67,10 @@ cr.define('settings', function () { wasSignInEnabledAtStartup () { return loadTimeData.getBoolean('signInAllowedOnNextStartupInitialValue') } + + isUnstoppableDomainsEnabled () { + return cr.sendWithPromise('isUnstoppableDomainsEnabled') + } } cr.addSingletonGetter(BraveDefaultExtensionsBrowserProxyImpl) diff --git a/browser/resources/settings/brave_default_extensions_page/brave_default_extensions_page.html b/browser/resources/settings/brave_default_extensions_page/brave_default_extensions_page.html index c0d231e44e98..c9bb46c6e392 100644 --- a/browser/resources/settings/brave_default_extensions_page/brave_default_extensions_page.html +++ b/browser/resources/settings/brave_default_extensions_page/brave_default_extensions_page.html @@ -85,6 +85,14 @@ sub-label="$i18n{hangoutsEnabledDesc}" on-settings-boolean-control-change="onHangoutsEnabledChange_"> + { this.widevineEnabled_ = enabled }) + this.browserProxy_.isUnstoppableDomainsEnabled().then(enabled => { + this.unstoppableDomainsEnabled_ = enabled + }); }, onWebTorrentEnabledChange_: function() { diff --git a/browser/ui/BUILD.gn b/browser/ui/BUILD.gn index b227925f256e..bf502533568a 100644 --- a/browser/ui/BUILD.gn +++ b/browser/ui/BUILD.gn @@ -7,6 +7,7 @@ import("//brave/components/ipfs/buildflags/buildflags.gni") import("//brave/components/sidebar/buildflags/buildflags.gni") import("//brave/components/speedreader/buildflags.gni") import("//brave/components/tor/buildflags/buildflags.gni") +import("//brave/components/unstoppable_domains/buildflags/buildflags.gni") import("//build/config/features.gni") import("//chrome/common/features.gni") import("//components/gcm_driver/config.gni") @@ -237,6 +238,7 @@ source_set("ui") { "//brave/components/p3a:buildflags", "//brave/components/sidebar/buildflags", "//brave/components/tor:pref_names", + "//brave/components/unstoppable_domains/buildflags", "//brave/components/vector_icons", "//brave/components/webcompat_reporter/browser", "//brave/components/webcompat_reporter/ui:generated_resources", @@ -372,6 +374,10 @@ source_set("ui") { } } + if (unstoppable_domains_enabled) { + deps += [ "//brave/components/unstoppable_domains" ] + } + if (brave_rewards_enabled) { sources += [ "views/brave_actions/brave_rewards_action_stub_view.cc", diff --git a/browser/ui/webui/settings/brave_default_extensions_handler.cc b/browser/ui/webui/settings/brave_default_extensions_handler.cc index c13845f39352..2719c6686868 100644 --- a/browser/ui/webui/settings/brave_default_extensions_handler.cc +++ b/browser/ui/webui/settings/brave_default_extensions_handler.cc @@ -13,6 +13,7 @@ #include "brave/browser/extensions/brave_component_loader.h" #include "brave/common/pref_names.h" #include "brave/components/brave_webtorrent/grit/brave_webtorrent_resources.h" +#include "brave/components/unstoppable_domains/buildflags/buildflags.h" #include "chrome/browser/about_flags.h" #include "chrome/browser/extensions/component_loader.h" #include "chrome/browser/extensions/extension_service.h" @@ -47,6 +48,10 @@ #include "brave/browser/widevine/widevine_utils.h" #endif +#if BUILDFLAG(UNSTOPPABLE_DOMAINS_ENABLED) +#include "brave/components/unstoppable_domains/utils.h" +#endif + BraveDefaultExtensionsHandler::BraveDefaultExtensionsHandler() : weak_ptr_factory_(this) { #if BUILDFLAG(ENABLE_WIDEVINE) @@ -108,6 +113,11 @@ void BraveDefaultExtensionsHandler::RegisterMessages() { "isWidevineEnabled", base::BindRepeating(&BraveDefaultExtensionsHandler::IsWidevineEnabled, base::Unretained(this))); + web_ui()->RegisterMessageCallback( + "isUnstoppableDomainsEnabled", + base::BindRepeating( + &BraveDefaultExtensionsHandler::IsUnstoppableDomainsEnabled, + base::Unretained(this))); // Can't call this in ctor because it needs to access web_ui(). InitializePrefCallbacks(); @@ -394,3 +404,16 @@ void BraveDefaultExtensionsHandler::SetBraveWalletEnabled( } } #endif + +void BraveDefaultExtensionsHandler::IsUnstoppableDomainsEnabled( + const base::ListValue* args) { + CHECK_EQ(args->GetSize(), 1U); + AllowJavascript(); + ResolveJavascriptCallback( + args->GetList()[0], +#if BUILDFLAG(UNSTOPPABLE_DOMAINS_ENABLED) + base::Value(unstoppable_domains::IsUnstoppableDomainsEnabled())); +#else + base::Value(false)); +#endif +} diff --git a/browser/ui/webui/settings/brave_default_extensions_handler.h b/browser/ui/webui/settings/brave_default_extensions_handler.h index e2507d662028..9118497ea51d 100644 --- a/browser/ui/webui/settings/brave_default_extensions_handler.h +++ b/browser/ui/webui/settings/brave_default_extensions_handler.h @@ -44,6 +44,7 @@ class BraveDefaultExtensionsHandler : public settings::SettingsPageUIHandler { void SetWidevineEnabled(const base::ListValue* args); void IsWidevineEnabled(const base::ListValue* args); void OnWidevineEnabledChanged(); + void IsUnstoppableDomainsEnabled(const base::ListValue* args); void InitializePrefCallbacks(); diff --git a/browser/unstoppable_domains/BUILD.gn b/browser/unstoppable_domains/BUILD.gn new file mode 100644 index 000000000000..b9f021060bd4 --- /dev/null +++ b/browser/unstoppable_domains/BUILD.gn @@ -0,0 +1,28 @@ +# Copyright (c) 2021 The Brave Authors. All rights reserved. +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this file, +# You can obtain one at http://mozilla.org/MPL/2.0/. */ + +source_set("unstoppable_domains") { + # See https://github.com/brave/brave-browser/issues/14441 + check_includes = false + + sources = [ + "unstoppable_domains_service_delegate_impl.cc", + "unstoppable_domains_service_delegate_impl.h", + "unstoppable_domains_service_factory.cc", + "unstoppable_domains_service_factory.h", + ] + + deps = [ + "//brave/components/unstoppable_domains", + "//components/keyed_service/content", + ] + + # Below deps are not directly used by unstoppable_domains target. + # This is added due to our include of + # `chrome/browser/net/system_network_context_manager.h` without adding + # //chrome/browser into deps to avoid circulate dependency. Without this, + # we could encounter error due to some files included are not generated yet. + deps += [ "//services/network/public/mojom" ] +} diff --git a/browser/unstoppable_domains/test/BUILD.gn b/browser/unstoppable_domains/test/BUILD.gn new file mode 100644 index 000000000000..ff577f9c6097 --- /dev/null +++ b/browser/unstoppable_domains/test/BUILD.gn @@ -0,0 +1,47 @@ +# Copyright (c) 2021 The Brave Authors. All rights reserved. +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this file, +# You can obtain one at http://mozilla.org/MPL/2.0/. */ + +import("//brave/build/config.gni") +import("//testing/test.gni") + +source_set("browser_tests") { + testonly = true + defines = [ "HAS_OUT_OF_PROC_TEST_RUNNER" ] + sources = [ + "//brave/browser/unstoppable_domains/test/unstoppable_domains_navigation_throttle_browsertest.cc", + "//brave/browser/unstoppable_domains/test/unstoppable_domains_service_browsertest.cc", + ] + deps = [ + "//base/test:test_support", + "//brave/components/unstoppable_domains", + "//chrome/browser:browser_process", + "//chrome/test:test_support", + "//chrome/test:test_support_ui", + "//components/prefs", + "//components/security_interstitials/content:security_interstitial_page", + "//content/test:test_support", + "//testing/gtest", + ] +} # source_set("browser_tests") { + +source_set("unit_tests") { + testonly = true + sources = [ + "//brave/browser/unstoppable_domains/test/utils_unittest.cc", + "//brave/net/dns/dns_transaction_unittest.cc", + ] + + deps = [ + "//base", + "//base/test:test_support", + "//brave/components/unstoppable_domains", + "//chrome/test:test_support", + "//components/prefs", + "//net", + "//net:test_support", + "//testing/gmock", + "//testing/gtest", + ] +} # source_set("unit_tests") diff --git a/browser/unstoppable_domains/test/unstoppable_domains_navigation_throttle_browsertest.cc b/browser/unstoppable_domains/test/unstoppable_domains_navigation_throttle_browsertest.cc new file mode 100644 index 000000000000..e08a415aebee --- /dev/null +++ b/browser/unstoppable_domains/test/unstoppable_domains_navigation_throttle_browsertest.cc @@ -0,0 +1,134 @@ +/* Copyright (c) 2021 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "base/test/scoped_feature_list.h" +#include "brave/components/unstoppable_domains/constants.h" +#include "brave/components/unstoppable_domains/features.h" +#include "brave/components/unstoppable_domains/pref_names.h" +#include "brave/components/unstoppable_domains/unstoppable_domains_opt_in_page.h" +#include "chrome/browser/browser_process.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/tabs/tab_strip_model.h" +#include "chrome/test/base/in_process_browser_test.h" +#include "chrome/test/base/ui_test_utils.h" +#include "components/prefs/pref_service.h" +#include "components/security_interstitials/content/security_interstitial_page.h" +#include "components/security_interstitials/content/security_interstitial_tab_helper.h" +#include "content/public/test/browser_test.h" +#include "content/public/test/browser_test_utils.h" +#include "content/public/test/test_navigation_observer.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "url/gurl.h" + +namespace { + +security_interstitials::SecurityInterstitialPage* GetCurrentInterstitial( + content::WebContents* web_contents) { + security_interstitials::SecurityInterstitialTabHelper* helper = + security_interstitials::SecurityInterstitialTabHelper::FromWebContents( + web_contents); + if (!helper) { + return nullptr; + } + return helper->GetBlockingPageForCurrentlyCommittedNavigationForTesting(); +} + +security_interstitials::SecurityInterstitialPage::TypeID GetInterstitialType( + content::WebContents* web_contents) { + security_interstitials::SecurityInterstitialPage* page = + GetCurrentInterstitial(web_contents); + if (!page) { + return nullptr; + } + return page->GetTypeForTesting(); +} + +void SendInterstitialCommand( + content::WebContents* web_contents, + security_interstitials::SecurityInterstitialCommand command) { + GetCurrentInterstitial(web_contents) + ->CommandReceived(base::NumberToString(command)); +} + +void SendInterstitialCommandSync( + Browser* browser, + security_interstitials::SecurityInterstitialCommand command) { + content::WebContents* web_contents = + browser->tab_strip_model()->GetActiveWebContents(); + + EXPECT_EQ(unstoppable_domains::UnstoppableDomainsOptInPage::kTypeForTesting, + GetInterstitialType(web_contents)); + + content::TestNavigationObserver navigation_observer(web_contents, 1); + SendInterstitialCommand(web_contents, command); + navigation_observer.Wait(); + + EXPECT_EQ(nullptr, GetCurrentInterstitial(web_contents)); +} + +} // namespace + +namespace unstoppable_domains { + +class UnstoppableDomainsNavigationThrottleBrowserTest + : public InProcessBrowserTest { + public: + UnstoppableDomainsNavigationThrottleBrowserTest() { + feature_list_.InitAndEnableFeature(features::kUnstoppableDomains); + } + + ~UnstoppableDomainsNavigationThrottleBrowserTest() override = default; + + void SetUpOnMainThread() override { + InProcessBrowserTest::SetUpOnMainThread(); + } + + PrefService* local_state() { return g_browser_process->local_state(); } + + private: + base::test::ScopedFeatureList feature_list_; +}; + +IN_PROC_BROWSER_TEST_F(UnstoppableDomainsNavigationThrottleBrowserTest, + ShowInterstitialAndProceed) { + ui_test_utils::NavigateToURL(browser(), GURL("http://test.crypto")); + + content::WebContents* web_contents = + browser()->tab_strip_model()->GetActiveWebContents(); + + EXPECT_TRUE(WaitForRenderFrameReady(web_contents->GetMainFrame())); + EXPECT_EQ(UnstoppableDomainsOptInPage::kTypeForTesting, + GetInterstitialType(web_contents)); + + EXPECT_EQ(static_cast(ResolveMethodTypes::ASK), + local_state()->GetInteger(kResolveMethod)); + SendInterstitialCommandSync( + browser(), + security_interstitials::SecurityInterstitialCommand::CMD_PROCEED); + EXPECT_EQ(static_cast(ResolveMethodTypes::DNS_OVER_HTTPS), + local_state()->GetInteger(kResolveMethod)); +} + +IN_PROC_BROWSER_TEST_F(UnstoppableDomainsNavigationThrottleBrowserTest, + ShowInterstitialAndReject) { + ui_test_utils::NavigateToURL(browser(), GURL("http://test.crypto")); + + content::WebContents* web_contents = + browser()->tab_strip_model()->GetActiveWebContents(); + + EXPECT_TRUE(WaitForRenderFrameReady(web_contents->GetMainFrame())); + EXPECT_EQ(UnstoppableDomainsOptInPage::kTypeForTesting, + GetInterstitialType(web_contents)); + + EXPECT_EQ(static_cast(ResolveMethodTypes::ASK), + local_state()->GetInteger(kResolveMethod)); + SendInterstitialCommandSync( + browser(), + security_interstitials::SecurityInterstitialCommand::CMD_DONT_PROCEED); + EXPECT_EQ(static_cast(ResolveMethodTypes::DISABLED), + local_state()->GetInteger(kResolveMethod)); +} + +} // namespace unstoppable_domains diff --git a/browser/unstoppable_domains/test/unstoppable_domains_service_browsertest.cc b/browser/unstoppable_domains/test/unstoppable_domains_service_browsertest.cc new file mode 100644 index 000000000000..17fc6da016de --- /dev/null +++ b/browser/unstoppable_domains/test/unstoppable_domains_service_browsertest.cc @@ -0,0 +1,128 @@ +/* Copyright (c) 2021 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "base/test/scoped_feature_list.h" +#include "brave/components/unstoppable_domains/constants.h" +#include "brave/components/unstoppable_domains/features.h" +#include "brave/components/unstoppable_domains/pref_names.h" +#include "brave/net/unstoppable_domains/constants.h" +#include "chrome/browser/browser_process.h" +#include "chrome/browser/net/secure_dns_config.h" +#include "chrome/browser/net/stub_resolver_config_reader.h" +#include "chrome/browser/net/system_network_context_manager.h" +#include "chrome/common/pref_names.h" +#include "chrome/test/base/in_process_browser_test.h" +#include "components/prefs/pref_service.h" +#include "content/public/test/browser_test.h" +#include "net/dns/public/secure_dns_mode.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace unstoppable_domains { + +class UnstoppableDomainsServiceBrowserTest : public InProcessBrowserTest { + public: + UnstoppableDomainsServiceBrowserTest() { + feature_list_.InitAndEnableFeature(features::kUnstoppableDomains); + } + + void SetUpOnMainThread() override { + InProcessBrowserTest::SetUpOnMainThread(); + stub_config_reader_ = + SystemNetworkContextManager::GetStubResolverConfigReader(); + ASSERT_TRUE(stub_config_reader_); + } + + ~UnstoppableDomainsServiceBrowserTest() override = default; + + PrefService* local_state() { return g_browser_process->local_state(); } + + SecureDnsConfig GetSecureDnsConfiguration( + bool force_check_parental_controls_for_automatic_mode = false) { + return stub_config_reader_->GetSecureDnsConfiguration( + force_check_parental_controls_for_automatic_mode); + } + + private: + base::test::ScopedFeatureList feature_list_; + StubResolverConfigReader* stub_config_reader_; +}; + +IN_PROC_BROWSER_TEST_F(UnstoppableDomainsServiceBrowserTest, + UpdateConfigWhenPrefChanged) { + // Initial state. + EXPECT_EQ(local_state()->GetInteger(kResolveMethod), + static_cast(ResolveMethodTypes::ASK)); + SecureDnsConfig config = GetSecureDnsConfiguration(); + EXPECT_EQ(config.mode(), net::SecureDnsMode::kAutomatic); + EXPECT_EQ(config.servers().size(), 0u); + + // Set resolve method to DoH should update the config. + local_state()->SetInteger( + kResolveMethod, static_cast(ResolveMethodTypes::DNS_OVER_HTTPS)); + config = GetSecureDnsConfiguration(); + std::vector expected_doh_servers = { + {kDoHResolver, true}}; + EXPECT_EQ(config.servers(), expected_doh_servers); + + // Set custom DoH provider should still keep the resolver for UD. + local_state()->SetString(prefs::kDnsOverHttpsTemplates, "https://test.com"); + config = GetSecureDnsConfiguration(); + expected_doh_servers = {{kDoHResolver, true}, {"https://test.com", true}}; + EXPECT_EQ(config.servers(), expected_doh_servers); + + // Set secure mode to off should return empty DoH servers. + local_state()->SetString( + prefs::kDnsOverHttpsMode, + SecureDnsConfig::ModeToString(net::SecureDnsMode::kOff)); + config = GetSecureDnsConfiguration(); + EXPECT_EQ(config.servers().size(), 0u); + + // Turn on secure mode again should get the same result as before. + local_state()->SetString( + prefs::kDnsOverHttpsMode, + SecureDnsConfig::ModeToString(net::SecureDnsMode::kSecure)); + config = GetSecureDnsConfiguration(); + EXPECT_EQ(config.servers(), expected_doh_servers); + + // Set resolve method to disabled should keep user's DoH setting. + local_state()->SetInteger(kResolveMethod, + static_cast(ResolveMethodTypes::DISABLED)); + config = GetSecureDnsConfiguration(); + expected_doh_servers = {{"https://test.com", true}}; + EXPECT_EQ(config.servers(), expected_doh_servers); +} + +IN_PROC_BROWSER_TEST_F(UnstoppableDomainsServiceBrowserTest, + HideUnstoppableDomainsResolvers) { + // Initial state. + EXPECT_EQ(local_state()->GetInteger(kResolveMethod), + static_cast(ResolveMethodTypes::ASK)); + SecureDnsConfig config = GetSecureDnsConfiguration(); + EXPECT_EQ(config.mode(), net::SecureDnsMode::kAutomatic); + EXPECT_EQ(config.servers().size(), 0u); + + // Set resolve method to DoH should update the config. + local_state()->SetInteger( + kResolveMethod, static_cast(ResolveMethodTypes::DNS_OVER_HTTPS)); + config = GetSecureDnsConfiguration(); + std::vector expected_doh_servers = { + {kDoHResolver, true}}; + EXPECT_EQ(config.servers(), expected_doh_servers); + + // Set custom DoH provider should still keep the resolver for UD. + local_state()->SetString(prefs::kDnsOverHttpsTemplates, "https://test.com"); + config = GetSecureDnsConfiguration(); + expected_doh_servers = {{kDoHResolver, true}, {"https://test.com", true}}; + EXPECT_EQ(config.servers(), expected_doh_servers); + + // Should hide unstoppable domains resolver if + // force_check_parental_controls_for_automatic_mode is true, used for hiding + // the special resolver in settings. + config = GetSecureDnsConfiguration(true); + expected_doh_servers = {{"https://test.com", true}}; + EXPECT_EQ(config.servers(), expected_doh_servers); +} + +} // namespace unstoppable_domains diff --git a/browser/unstoppable_domains/test/utils_unittest.cc b/browser/unstoppable_domains/test/utils_unittest.cc new file mode 100644 index 000000000000..c8655df32054 --- /dev/null +++ b/browser/unstoppable_domains/test/utils_unittest.cc @@ -0,0 +1,73 @@ +/* Copyright (c) 2021 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "brave/components/unstoppable_domains/utils.h" + +#include "base/test/scoped_feature_list.h" +#include "base/test/task_environment.h" +#include "brave/components/unstoppable_domains/constants.h" +#include "brave/components/unstoppable_domains/features.h" +#include "brave/components/unstoppable_domains/pref_names.h" +#include "chrome/test/base/scoped_testing_local_state.h" +#include "chrome/test/base/testing_browser_process.h" +#include "components/prefs/testing_pref_service.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace unstoppable_domains { + +class UtilsUnitTest : public testing::TestWithParam { + public: + UtilsUnitTest() + : local_state_(TestingBrowserProcess::GetGlobal()), + feature_enabled_(GetParam()) {} + ~UtilsUnitTest() override = default; + + void SetUp() override { + if (feature_enabled_) { + feature_list_.InitAndEnableFeature(features::kUnstoppableDomains); + } else { + feature_list_.InitAndDisableFeature(features::kUnstoppableDomains); + } + } + + PrefService* local_state() { return local_state_.Get(); } + bool feature_enabled() { return feature_enabled_; } + + private: + base::test::TaskEnvironment task_environment_; + base::test::ScopedFeatureList feature_list_; + ScopedTestingLocalState local_state_; + bool feature_enabled_; +}; + +TEST_P(UtilsUnitTest, IsUnstoppableDomainsTLD) { + EXPECT_TRUE(IsUnstoppableDomainsTLD(GURL("http://test.crypto"))); + EXPECT_FALSE(IsUnstoppableDomainsTLD(GURL("http://test.com"))); + EXPECT_FALSE(IsUnstoppableDomainsTLD(GURL("http://crypto"))); +} + +TEST_P(UtilsUnitTest, IsUnstoppableDomainsEnabled) { + EXPECT_EQ(feature_enabled(), IsUnstoppableDomainsEnabled()); +} + +TEST_P(UtilsUnitTest, IsResolveMethodAsk) { + EXPECT_EQ(feature_enabled(), IsResolveMethodAsk(local_state())); + + local_state()->SetInteger( + kResolveMethod, static_cast(ResolveMethodTypes::DNS_OVER_HTTPS)); + EXPECT_FALSE(IsResolveMethodAsk(local_state())); +} + +TEST_P(UtilsUnitTest, IsResolveMethodDoH) { + EXPECT_FALSE(IsResolveMethodDoH(local_state())); + + local_state()->SetInteger( + kResolveMethod, static_cast(ResolveMethodTypes::DNS_OVER_HTTPS)); + EXPECT_EQ(feature_enabled(), IsResolveMethodDoH(local_state())); +} + +INSTANTIATE_TEST_SUITE_P(/* no prefix */, UtilsUnitTest, testing::Bool()); + +} // namespace unstoppable_domains diff --git a/browser/unstoppable_domains/unstoppable_domains_service_delegate_impl.cc b/browser/unstoppable_domains/unstoppable_domains_service_delegate_impl.cc new file mode 100644 index 000000000000..48081e701575 --- /dev/null +++ b/browser/unstoppable_domains/unstoppable_domains_service_delegate_impl.cc @@ -0,0 +1,19 @@ +/* Copyright (c) 2021 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "brave/browser/unstoppable_domains/unstoppable_domains_service_delegate_impl.h" + +#include "chrome/browser/net/stub_resolver_config_reader.h" +#include "chrome/browser/net/system_network_context_manager.h" + +namespace unstoppable_domains { + +void UnstoppableDomainsServiceDelegateImpl::UpdateNetworkService() { + // Trigger a DoH config update in network service. + SystemNetworkContextManager::GetStubResolverConfigReader() + ->UpdateNetworkService(false /* record_metrics */); +} + +} // namespace unstoppable_domains diff --git a/browser/unstoppable_domains/unstoppable_domains_service_delegate_impl.h b/browser/unstoppable_domains/unstoppable_domains_service_delegate_impl.h new file mode 100644 index 000000000000..aed7638b4534 --- /dev/null +++ b/browser/unstoppable_domains/unstoppable_domains_service_delegate_impl.h @@ -0,0 +1,29 @@ +/* Copyright (c) 2021 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef BRAVE_BROWSER_UNSTOPPABLE_DOMAINS_UNSTOPPABLE_DOMAINS_SERVICE_DELEGATE_IMPL_H_ +#define BRAVE_BROWSER_UNSTOPPABLE_DOMAINS_UNSTOPPABLE_DOMAINS_SERVICE_DELEGATE_IMPL_H_ + +#include "brave/components/unstoppable_domains/unstoppable_domains_service_delegate.h" + +namespace unstoppable_domains { + +class UnstoppableDomainsServiceDelegateImpl + : public UnstoppableDomainsServiceDelegate { + public: + UnstoppableDomainsServiceDelegateImpl() = default; + ~UnstoppableDomainsServiceDelegateImpl() override = default; + + UnstoppableDomainsServiceDelegateImpl( + const UnstoppableDomainsServiceDelegateImpl&) = delete; + UnstoppableDomainsServiceDelegateImpl& operator=( + UnstoppableDomainsServiceDelegateImpl&) = delete; + + void UpdateNetworkService() override; +}; + +} // namespace unstoppable_domains + +#endif // BRAVE_BROWSER_UNSTOPPABLE_DOMAINS_UNSTOPPABLE_DOMAINS_SERVICE_DELEGATE_IMPL_H_ diff --git a/browser/unstoppable_domains/unstoppable_domains_service_factory.cc b/browser/unstoppable_domains/unstoppable_domains_service_factory.cc new file mode 100644 index 000000000000..efe353478c97 --- /dev/null +++ b/browser/unstoppable_domains/unstoppable_domains_service_factory.cc @@ -0,0 +1,49 @@ +/* Copyright (c) 2021 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "brave/browser/unstoppable_domains/unstoppable_domains_service_factory.h" + +#include + +#include "brave/browser/brave_browser_process_impl.h" +#include "brave/browser/unstoppable_domains/unstoppable_domains_service_delegate_impl.h" +#include "brave/components/unstoppable_domains/unstoppable_domains_service.h" +#include "brave/components/unstoppable_domains/utils.h" +#include "components/keyed_service/content/browser_context_dependency_manager.h" + +namespace unstoppable_domains { + +UnstoppableDomainsServiceFactory::UnstoppableDomainsServiceFactory() + : BrowserContextKeyedServiceFactory( + "UnstoppableDomainsService", + BrowserContextDependencyManager::GetInstance()) {} + +UnstoppableDomainsServiceFactory::~UnstoppableDomainsServiceFactory() {} + +// static +UnstoppableDomainsServiceFactory* +UnstoppableDomainsServiceFactory::GetInstance() { + return base::Singleton::get(); +} + +// static +UnstoppableDomainsService* UnstoppableDomainsServiceFactory::GetForContext( + content::BrowserContext* context) { + if (!IsUnstoppableDomainsEnabled()) + return nullptr; + + return static_cast( + GetInstance()->GetServiceForBrowserContext(context, true)); +} + +KeyedService* UnstoppableDomainsServiceFactory::BuildServiceInstanceFor( + content::BrowserContext* context) const { + return new UnstoppableDomainsService( + std::make_unique(), context, + g_brave_browser_process ? g_brave_browser_process->local_state() + : nullptr); +} + +} // namespace unstoppable_domains diff --git a/browser/unstoppable_domains/unstoppable_domains_service_factory.h b/browser/unstoppable_domains/unstoppable_domains_service_factory.h new file mode 100644 index 000000000000..d64665f916e4 --- /dev/null +++ b/browser/unstoppable_domains/unstoppable_domains_service_factory.h @@ -0,0 +1,41 @@ +/* Copyright (c) 2021 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef BRAVE_BROWSER_UNSTOPPABLE_DOMAINS_UNSTOPPABLE_DOMAINS_SERVICE_FACTORY_H_ +#define BRAVE_BROWSER_UNSTOPPABLE_DOMAINS_UNSTOPPABLE_DOMAINS_SERVICE_FACTORY_H_ + +#include "base/memory/singleton.h" +#include "components/keyed_service/content/browser_context_keyed_service_factory.h" + +namespace unstoppable_domains { + +class UnstoppableDomainsService; + +class UnstoppableDomainsServiceFactory + : public BrowserContextKeyedServiceFactory { + public: + static UnstoppableDomainsService* GetForContext( + content::BrowserContext* context); + static UnstoppableDomainsServiceFactory* GetInstance(); + + private: + friend struct base::DefaultSingletonTraits; + + UnstoppableDomainsServiceFactory(); + ~UnstoppableDomainsServiceFactory() override; + + UnstoppableDomainsServiceFactory(const UnstoppableDomainsServiceFactory&) = + delete; + UnstoppableDomainsServiceFactory& operator=( + const UnstoppableDomainsServiceFactory&) = delete; + + // BrowserContextKeyedServiceFactory overrides: + KeyedService* BuildServiceInstanceFor( + content::BrowserContext* context) const override; +}; + +} // namespace unstoppable_domains + +#endif // BRAVE_BROWSER_UNSTOPPABLE_DOMAINS_UNSTOPPABLE_DOMAINS_SERVICE_FACTORY_H_ diff --git a/build/config/brave_build.gni b/build/config/brave_build.gni index c3afdcc4bbc5..b2814a0e27a9 100644 --- a/build/config/brave_build.gni +++ b/build/config/brave_build.gni @@ -3,6 +3,8 @@ # import("//build/config/chrome_build.gni") in compiler.gni import("//brave/brave_repack_locales.gni") import("//brave/browser/extensions/resources.gni") +import("//brave/browser/resources/extensions/sources.gni") +import("//brave/browser/resources/settings/sources.gni") import("//brave/browser/sources.gni") import("//brave/build/config/compiler.gni") import("//brave/build/features.gni") @@ -13,8 +15,7 @@ import("//brave/components/sync/driver/sources.gni") import("//brave/components/sync/sources.gni") import("//brave/components/sync_device_info/sources.gni") import("//brave/installer/linux/sources.gni") +import("//brave/net/dns/sources.gni") import("//brave/net/sources.gni") import("//brave/renderer/sources.gni") import("//brave/third_party/blink/renderer/includes.gni") -import("//brave/browser/resources/settings/sources.gni") -import("//brave/browser/resources/extensions/sources.gni") diff --git a/chromium_src/chrome/browser/about_flags.cc b/chromium_src/chrome/browser/about_flags.cc index edd2e008b4bd..3c87f4899038 100644 --- a/chromium_src/chrome/browser/about_flags.cc +++ b/chromium_src/chrome/browser/about_flags.cc @@ -16,6 +16,7 @@ #include "brave/components/ntp_background_images/browser/features.h" #include "brave/components/sidebar/buildflags/buildflags.h" #include "brave/components/speedreader/buildflags.h" +#include "brave/components/unstoppable_domains/buildflags/buildflags.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_manager.h" #include "components/prefs/pref_service.h" @@ -93,6 +94,18 @@ using ntp_background_images::features::kBraveNTPSuperReferralWallpaper; #define BRAVE_NATIVE_WALLET_FEATURE_ENTRIES #endif +#if BUILDFLAG(UNSTOPPABLE_DOMAINS_ENABLED) +#include "brave/components/unstoppable_domains/features.h" + +#define BRAVE_UNSTOPPABLE_DOMAINS_FEATURE_ENTRIES \ + {"brave-unstoppable-domains", \ + flag_descriptions::kBraveUnstoppableDomainsName, \ + flag_descriptions::kBraveUnstoppableDomainsDescription, kOsDesktop, \ + FEATURE_VALUE_TYPE(unstoppable_domains::features::kUnstoppableDomains)}, +#else +#define BRAVE_UNSTOPPABLE_DOMAINS_FEATURE_ENTRIES +#endif + #define BRAVE_FEATURE_ENTRIES \ {"use-dev-updater-url", \ flag_descriptions::kUseDevUpdaterUrlName, \ @@ -120,6 +133,7 @@ using ntp_background_images::features::kBraveNTPSuperReferralWallpaper; BRAVE_IPFS_FEATURE_ENTRIES \ BRAVE_NATIVE_WALLET_FEATURE_ENTRIES \ SIDEBAR_FEATURE_ENTRIES \ + BRAVE_UNSTOPPABLE_DOMAINS_FEATURE_ENTRIES \ {"brave-super-referral", \ flag_descriptions::kBraveSuperReferralName, \ flag_descriptions::kBraveSuperReferralDescription, \ diff --git a/chromium_src/chrome/browser/flag_descriptions.cc b/chromium_src/chrome/browser/flag_descriptions.cc index c8f059b11126..6ff87dc7b93e 100644 --- a/chromium_src/chrome/browser/flag_descriptions.cc +++ b/chromium_src/chrome/browser/flag_descriptions.cc @@ -45,6 +45,9 @@ const char kNativeBraveWalletName[] = "Enable experimental Brave native wallet"; const char kNativeBraveWalletDescription[] = "Experimental native cryptocurrency wallet support without the use of " "extensions"; +const char kBraveUnstoppableDomainsName[] = "Enable unstoppable domains"; +const char kBraveUnstoppableDomainsDescription[] = + "Enable resolution support of unstoppable domains."; const char kBraveSuperReferralName[] = "Enable Brave Super Referral"; const char kBraveSuperReferralDescription[] = "Use custom theme for Brave Super Referral"; diff --git a/chromium_src/chrome/browser/flag_descriptions.h b/chromium_src/chrome/browser/flag_descriptions.h index e3a6cb0e6b38..3921993f87ad 100644 --- a/chromium_src/chrome/browser/flag_descriptions.h +++ b/chromium_src/chrome/browser/flag_descriptions.h @@ -29,6 +29,8 @@ extern const char kBraveIpfsName[]; extern const char kBraveIpfsDescription[]; extern const char kNativeBraveWalletName[]; extern const char kNativeBraveWalletDescription[]; +extern const char kBraveUnstoppableDomainsName[]; +extern const char kBraveUnstoppableDomainsDescription[]; extern const char kBraveSuperReferralName[]; extern const char kBraveSuperReferralDescription[]; extern const char kBraveEphemeralStorageName[]; diff --git a/chromium_src/chrome/browser/net/stub_resolver_config_reader.cc b/chromium_src/chrome/browser/net/stub_resolver_config_reader.cc new file mode 100644 index 000000000000..120dd06e6ea4 --- /dev/null +++ b/chromium_src/chrome/browser/net/stub_resolver_config_reader.cc @@ -0,0 +1,55 @@ +/* Copyright (c) 2021 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "brave/components/unstoppable_domains/buildflags/buildflags.h" +#include "components/prefs/pref_service.h" + +#if BUILDFLAG(UNSTOPPABLE_DOMAINS_ENABLED) +#include "base/strings/strcat.h" +#include "brave/components/unstoppable_domains/utils.h" +#include "brave/net/unstoppable_domains/constants.h" +#endif + +namespace { + +#if BUILDFLAG(UNSTOPPABLE_DOMAINS_ENABLED) +void AddUnstoppableDomainsResolver(std::string* doh_templates, + PrefService* local_state) { + if (unstoppable_domains::IsResolveMethodDoH(local_state) && + doh_templates->find(unstoppable_domains::kDoHResolver) == + std::string::npos) { + *doh_templates = + base::StrCat({unstoppable_domains::kDoHResolver, " ", *doh_templates}); + } +} +#endif // BUILDFLAG(UNSTOPPABLE_DOMAINS_ENABLED) + +// Add DoH servers to support Unstoppable Domains (and ENS in the future PR). +// These servers are controlled using its own prefs and not +// kDnsOverHttpsTemplates pref as the servers we added here are special and +// only applies to certain TLD which is different from user's global DoH +// provider settings. +void AddDoHServers(std::string* doh_templates, + PrefService* local_state, + bool force_check_parental_controls_for_automatic_mode) { + // force_check_parental_controls_for_automatic_mode is only true for + // settings UI which we specifically do not want to display those special + // resolvers we added. + if (force_check_parental_controls_for_automatic_mode) + return; + +#if BUILDFLAG(UNSTOPPABLE_DOMAINS_ENABLED) + AddUnstoppableDomainsResolver(doh_templates, local_state); +#endif +} + +} // namespace + +#define BRAVE_GET_AND_UPDATE_CONFIGURATION \ + AddDoHServers(&doh_templates, local_state_, \ + force_check_parental_controls_for_automatic_mode); + +#include "../../../../../chrome/browser/net/stub_resolver_config_reader.cc" +#undef BRAVE_GET_AND_UPDATE_CONFIGURATION diff --git a/chromium_src/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc b/chromium_src/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc index 4d38033d27d5..4a0281ce541a 100644 --- a/chromium_src/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc +++ b/chromium_src/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc @@ -219,6 +219,8 @@ void BraveAddCommonStrings(content::WebUIDataSource* html_source, IDS_SETTINGS_LOAD_CRYPTO_WALLETS_ON_STARTUP}, {"googleLoginForExtensionsDesc", IDS_SETTINGS_GOOGLE_LOGIN_FOR_EXTENSIONS}, {"hangoutsEnabledDesc", IDS_SETTINGS_HANGOUTS_ENABLED_DESC}, + {"resolveUnstoppableDomainsDesc", + IDS_SETTINGS_RESOLVE_UNSTOPPABLE_DOMAINS_DESC}, {"resolveIPFSURLDesc", IDS_SETTINGS_RESOLVE_IPFS_URLS_DESC}, {"ipfsPublicGatewayDesc", IDS_SETTINGS_IPFS_PUBLIC_GATEWAY_DESC}, {"ipfsChangeGatewayButtonLabel", diff --git a/chromium_src/net/DEPS b/chromium_src/net/DEPS index 518b5f55c96a..ac9b5ec33aad 100644 --- a/chromium_src/net/DEPS +++ b/chromium_src/net/DEPS @@ -1,6 +1,7 @@ include_rules = [ "+../../../../net/base", "+../../../../net/cookies", + "+../../../../net/dns", "+../../../../net/log", "+../../../../net/proxy_resolution", "+../../../../net/socket", diff --git a/chromium_src/net/base/lookup_string_in_fixed_set.cc b/chromium_src/net/base/lookup_string_in_fixed_set.cc index 9327fb71d6e1..9f6c3e5a9d49 100644 --- a/chromium_src/net/base/lookup_string_in_fixed_set.cc +++ b/chromium_src/net/base/lookup_string_in_fixed_set.cc @@ -10,6 +10,7 @@ #undef LookupSuffixInReversedSet #include "base/strings/string_util.h" +#include "brave/net/unstoppable_domains/constants.h" namespace net { @@ -40,6 +41,15 @@ int LookupSuffixInReversedSet(const unsigned char* graph, return kDafsaFound; } + // Recognize .crypto as a known TLD for unstoppable domains support. With + // this, when users type *.crypto in omnibox, it will be parsed as + // OmniboxInputType::URL input type instead of OmniboxInputType::UNKNOWN, + // The first entry in the autocomplete list will be URL instead of search. + if (base::EndsWith(host, unstoppable_domains::kCryptoDomain)) { + *suffix_length = strlen(unstoppable_domains::kCryptoDomain) - 1; + return kDafsaFound; + } + return LookupSuffixInReversedSet_ChromiumImpl(graph, length, include_private, host, suffix_length); } diff --git a/chromium_src/net/dns/dns_transaction.cc b/chromium_src/net/dns/dns_transaction.cc new file mode 100644 index 000000000000..2bc5e20c487c --- /dev/null +++ b/chromium_src/net/dns/dns_transaction.cc @@ -0,0 +1,41 @@ +/* Copyright (c) 2021 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "base/strings/string_util.h" +#include "brave/net/unstoppable_domains/constants.h" +#include "net/dns/dns_config.h" +#include "net/dns/dns_server_iterator.h" + +namespace { + +bool GetNextIndex(const std::string& hostname, + const net::DnsConfig& config, + net::DnsServerIterator* dns_server_iterator, + size_t* doh_server_index) { + // Skip unstoppable domains resolver for non-crypto domains. + if (config.dns_over_https_servers[*doh_server_index].server_template == + unstoppable_domains::kDoHResolver && + !base::EndsWith(hostname, unstoppable_domains::kCryptoDomain)) { + // No next available index to attempt. + if (!dns_server_iterator->AttemptAvailable()) { + return false; + } + + *doh_server_index = dns_server_iterator->GetNextAttemptIndex(); + } + + return true; +} + +} // namespace + +#define BRAVE_MAKE_HTTP_ATTEMPT \ + if (!GetNextIndex(hostname_, session_.get()->config(), \ + dns_server_iterator_.get(), &doh_server_index)) { \ + return AttemptResult(ERR_BLOCKED_BY_CLIENT, nullptr); \ + } + +#include "../../../../net/dns/dns_transaction.cc" +#undef BRAVE_MAKE_HTTP_ATTEMPT diff --git a/components/resources/BUILD.gn b/components/resources/BUILD.gn index 810d3c6c7382..ae513bcb7e20 100644 --- a/components/resources/BUILD.gn +++ b/components/resources/BUILD.gn @@ -7,6 +7,7 @@ import("//brave/components/ipfs/buildflags/buildflags.gni") import("//brave/components/sidebar/buildflags/buildflags.gni") import("//brave/components/speedreader/buildflags.gni") import("//brave/components/tor/buildflags/buildflags.gni") +import("//brave/components/unstoppable_domains/buildflags/buildflags.gni") import("//build/config/locales.gni") import("//extensions/buildflags/buildflags.gni") import("//tools/grit/grit_rule.gni") @@ -42,6 +43,7 @@ grit("static_resources") { "enable_speedreader=$enable_speedreader", "ipfs_enabled=$ipfs_enabled", "crypto_dot_com_enabled=$crypto_dot_com_enabled", + "unstoppable_domains_enabled=$unstoppable_domains_enabled", ] grit_flags = [ @@ -95,6 +97,7 @@ grit("strings") { defines = [ "enable_speedreader=$enable_speedreader", "ipfs_enabled=$ipfs_enabled", + "unstoppable_domains_enabled=$unstoppable_domains_enabled", "crypto_dot_com_enabled=$crypto_dot_com_enabled", "enable_tor=$enable_tor", "enable_sidebar=$enable_sidebar", diff --git a/components/resources/brave_components_resources.grd b/components/resources/brave_components_resources.grd index 89f2c529fa05..2924602c0d67 100644 --- a/components/resources/brave_components_resources.grd +++ b/components/resources/brave_components_resources.grd @@ -63,6 +63,7 @@ + diff --git a/components/resources/brave_components_strings.grd b/components/resources/brave_components_strings.grd index 26ef4244c191..f8523490ef3b 100644 --- a/components/resources/brave_components_strings.grd +++ b/components/resources/brave_components_strings.grd @@ -1072,6 +1072,7 @@ I understand + diff --git a/components/resources/unstoppable_domains_resources.grdp b/components/resources/unstoppable_domains_resources.grdp new file mode 100644 index 000000000000..79d5a2b704f4 --- /dev/null +++ b/components/resources/unstoppable_domains_resources.grdp @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/components/resources/unstoppable_domains_strings.grdp b/components/resources/unstoppable_domains_strings.grdp new file mode 100644 index 000000000000..8d1a3b30d14f --- /dev/null +++ b/components/resources/unstoppable_domains_strings.grdp @@ -0,0 +1,20 @@ + + + + + Unstoppable Domains + + + Enable support of Unstoppable Domains in Brave? + + + Brave can enable you to visit .crypto domains by using Cloudflare to resolve .crypto domain name lookup requests using DNS over HTTPS. If you enable this, Cloudflare will see the .crypto domain that you're trying to visit but they will not be able to see other domains. See Cloudflare's $1terms of use$2 and $3privacy policy$4. + + + Proceed using Cloudflare server + + + Disable + + + diff --git a/components/unstoppable_domains/BUILD.gn b/components/unstoppable_domains/BUILD.gn new file mode 100644 index 000000000000..439f42687de9 --- /dev/null +++ b/components/unstoppable_domains/BUILD.gn @@ -0,0 +1,37 @@ +# Copyright (c) 2021 The Brave Authors. All rights reserved. +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this file, +# You can obtain one at http://mozilla.org/MPL/2.0/. */ + +source_set("unstoppable_domains") { + sources = [ + "constants.h", + "features.h", + "pref_names.h", + "unstoppable_domains_interstitial_controller_client.cc", + "unstoppable_domains_interstitial_controller_client.h", + "unstoppable_domains_navigation_throttle.cc", + "unstoppable_domains_navigation_throttle.h", + "unstoppable_domains_opt_in_page.cc", + "unstoppable_domains_opt_in_page.h", + "unstoppable_domains_service.cc", + "unstoppable_domains_service.h", + "unstoppable_domains_service_delegate.h", + "utils.cc", + "utils.h", + ] + + deps = [ + "//base", + "//brave/components/resources:static_resources", + "//brave/components/resources:strings", + "//components/keyed_service/core", + "//components/prefs", + "//components/security_interstitials/content:security_interstitial_page", + "//components/security_interstitials/core", + "//components/user_prefs", + "//content/public/browser", + "//net", + "//url", + ] +} diff --git a/components/unstoppable_domains/DEPS b/components/unstoppable_domains/DEPS new file mode 100644 index 000000000000..778791c5d956 --- /dev/null +++ b/components/unstoppable_domains/DEPS @@ -0,0 +1,14 @@ +include_rules = [ + "+base", + "+components/keyed_service/core", + "+components/grit", + "+components/prefs", + "+components/security_interstitials/content", + "+components/security_interstitials/core", + "+components/user_prefs", + "+content/public/browser", + "+content/public/common", + "+net", + "+ui/base", + "+url", +] diff --git a/components/unstoppable_domains/buildflags/BUILD.gn b/components/unstoppable_domains/buildflags/BUILD.gn new file mode 100644 index 000000000000..9df0a982d318 --- /dev/null +++ b/components/unstoppable_domains/buildflags/BUILD.gn @@ -0,0 +1,7 @@ +import("//brave/components/unstoppable_domains/buildflags/buildflags.gni") +import("//build/buildflag_header.gni") + +buildflag_header("buildflags") { + header = "buildflags.h" + flags = [ "UNSTOPPABLE_DOMAINS_ENABLED=$unstoppable_domains_enabled" ] +} diff --git a/components/unstoppable_domains/buildflags/buildflags.gni b/components/unstoppable_domains/buildflags/buildflags.gni new file mode 100644 index 000000000000..d86b13dcaa55 --- /dev/null +++ b/components/unstoppable_domains/buildflags/buildflags.gni @@ -0,0 +1,3 @@ +declare_args() { + unstoppable_domains_enabled = is_mac || is_linux || is_win +} diff --git a/components/unstoppable_domains/constants.h b/components/unstoppable_domains/constants.h new file mode 100644 index 000000000000..53b19b782b4d --- /dev/null +++ b/components/unstoppable_domains/constants.h @@ -0,0 +1,19 @@ +/* Copyright (c) 2021 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef BRAVE_COMPONENTS_UNSTOPPABLE_DOMAINS_CONSTANTS_H_ +#define BRAVE_COMPONENTS_UNSTOPPABLE_DOMAINS_CONSTANTS_H_ + +namespace unstoppable_domains { + +enum class ResolveMethodTypes { + ASK, + DISABLED, + DNS_OVER_HTTPS, +}; + +} // namespace unstoppable_domains + +#endif // BRAVE_COMPONENTS_UNSTOPPABLE_DOMAINS_CONSTANTS_H_ diff --git a/components/unstoppable_domains/features.h b/components/unstoppable_domains/features.h new file mode 100644 index 000000000000..61be4b023726 --- /dev/null +++ b/components/unstoppable_domains/features.h @@ -0,0 +1,20 @@ +/* Copyright (c) 2021 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef BRAVE_COMPONENTS_UNSTOPPABLE_DOMAINS_FEATURES_H_ +#define BRAVE_COMPONENTS_UNSTOPPABLE_DOMAINS_FEATURES_H_ + +#include "base/feature_list.h" + +namespace unstoppable_domains { +namespace features { + +constexpr base::Feature kUnstoppableDomains{"UnstoppableDomains", + base::FEATURE_DISABLED_BY_DEFAULT}; + +} // namespace features +} // namespace unstoppable_domains + +#endif // BRAVE_COMPONENTS_UNSTOPPABLE_DOMAINS_FEATURES_H_ diff --git a/components/unstoppable_domains/pref_names.h b/components/unstoppable_domains/pref_names.h new file mode 100644 index 000000000000..23416806e912 --- /dev/null +++ b/components/unstoppable_domains/pref_names.h @@ -0,0 +1,20 @@ +/* Copyright (c) 2021 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef BRAVE_COMPONENTS_UNSTOPPABLE_DOMAINS_PREF_NAMES_H_ +#define BRAVE_COMPONENTS_UNSTOPPABLE_DOMAINS_PREF_NAMES_H_ + +namespace unstoppable_domains { + +// Used to determine which method should be used to resolve unstoppable +// domains, between: +// Disabled: Disable all unstoppable domains resolution. +// Ask: Ask users if they want to enable support of unstoppable domains. +// DNS Over HTTPS: Resolve domain name using a public DNS over HTTPS server. +constexpr char kResolveMethod[] = "brave.unstoppable_domains.resolve_method"; + +} // namespace unstoppable_domains + +#endif // BRAVE_COMPONENTS_UNSTOPPABLE_DOMAINS_PREF_NAMES_H_ diff --git a/components/unstoppable_domains/resources/unstoppable_domains_interstitial.css b/components/unstoppable_domains/resources/unstoppable_domains_interstitial.css new file mode 100644 index 000000000000..0d0524870d70 --- /dev/null +++ b/components/unstoppable_domains/resources/unstoppable_domains_interstitial.css @@ -0,0 +1,14 @@ +.unstoppable_domains #main-content a { + color: var(--google-blue-700); + text-decoration: none; +} + +.unstoppable_domains button { + background: var(--primary-button-fill-color); +} + +.unstoppable_domains .icon { + background-image: -webkit-image-set( + url(../../../../components/security_interstitials/core/browser/resources/images/1x/info.png) 1x, + url(../../../../components/security_interstitials/core/browser/resources/images/2x/info.png) 2x); +} diff --git a/components/unstoppable_domains/resources/unstoppable_domains_interstitial.html b/components/unstoppable_domains/resources/unstoppable_domains_interstitial.html new file mode 100644 index 000000000000..7206962d899d --- /dev/null +++ b/components/unstoppable_domains/resources/unstoppable_domains_interstitial.html @@ -0,0 +1,31 @@ + + + + + $i18n{tabTitle} + + + + + + + + + +
+
+
+
+

$i18nRaw{heading}

+

$i18nRaw{primaryParagraph}

+
+
+ +
+ diff --git a/components/unstoppable_domains/resources/unstoppable_domains_interstitial.js b/components/unstoppable_domains/resources/unstoppable_domains_interstitial.js new file mode 100644 index 000000000000..08dc2bdd3dbf --- /dev/null +++ b/components/unstoppable_domains/resources/unstoppable_domains_interstitial.js @@ -0,0 +1,21 @@ +// Copyright 2021 The Brave Authors. All rights reserved. +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this file, +// you can obtain one at http://mozilla.org/MPL/2.0/. + +function setupEvents() { + $('body').classList.add('unstoppable_domains'); + $('icon').classList.add('icon'); + + $('primary-button').addEventListener('click', function() { + sendCommand(SecurityInterstitialCommandId.CMD_PROCEED); + }); + + $('main-content').classList.remove(HIDDEN_CLASS); + + $('dont-proceed-button').addEventListener('click', function(event) { + sendCommand(SecurityInterstitialCommandId.CMD_DONT_PROCEED); + }); +} + +document.addEventListener('DOMContentLoaded', setupEvents); diff --git a/components/unstoppable_domains/unstoppable_domains_interstitial_controller_client.cc b/components/unstoppable_domains/unstoppable_domains_interstitial_controller_client.cc new file mode 100644 index 000000000000..4ad97f42235a --- /dev/null +++ b/components/unstoppable_domains/unstoppable_domains_interstitial_controller_client.cc @@ -0,0 +1,59 @@ +/* Copyright (c) 2021 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "brave/components/unstoppable_domains/unstoppable_domains_interstitial_controller_client.h" + +#include "brave/components/unstoppable_domains/constants.h" +#include "brave/components/unstoppable_domains/pref_names.h" +#include "components/prefs/pref_service.h" +#include "components/security_interstitials/content/settings_page_helper.h" +#include "components/security_interstitials/core/metrics_helper.h" + +namespace unstoppable_domains { + +// static +std::unique_ptr +UnstoppableDomainsInterstitialControllerClient::GetMetricsHelper( + const GURL& url) { + security_interstitials::MetricsHelper::ReportDetails report_details; + report_details.metric_prefix = "UnstoppableDomains"; + + return std::make_unique( + url, report_details, nullptr); +} + +UnstoppableDomainsInterstitialControllerClient:: + UnstoppableDomainsInterstitialControllerClient( + content::WebContents* web_contents, + const GURL& request_url, + PrefService* user_prefs, + PrefService* local_state, + const std::string& locale) + : security_interstitials::SecurityInterstitialControllerClient( + web_contents, + GetMetricsHelper(request_url), + user_prefs, + locale, + GURL("about:blank") /* default_safe_page */, + nullptr /* settings_page_helper */), + request_url_(request_url), + local_state_(local_state) {} + +void UnstoppableDomainsInterstitialControllerClient::Proceed() { + SetResolveMethodAndReload(ResolveMethodTypes::DNS_OVER_HTTPS); +} + +void UnstoppableDomainsInterstitialControllerClient::DontProceed() { + SetResolveMethodAndReload(ResolveMethodTypes::DISABLED); +} + +void UnstoppableDomainsInterstitialControllerClient::SetResolveMethodAndReload( + ResolveMethodTypes type) { + DCHECK(local_state_); + local_state_->SetInteger(kResolveMethod, static_cast(type)); + Reload(); +} + +} // namespace unstoppable_domains diff --git a/components/unstoppable_domains/unstoppable_domains_interstitial_controller_client.h b/components/unstoppable_domains/unstoppable_domains_interstitial_controller_client.h new file mode 100644 index 000000000000..93947abbdb2b --- /dev/null +++ b/components/unstoppable_domains/unstoppable_domains_interstitial_controller_client.h @@ -0,0 +1,60 @@ +/* Copyright (c) 2021 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef BRAVE_COMPONENTS_UNSTOPPABLE_DOMAINS_UNSTOPPABLE_DOMAINS_INTERSTITIAL_CONTROLLER_CLIENT_H_ +#define BRAVE_COMPONENTS_UNSTOPPABLE_DOMAINS_UNSTOPPABLE_DOMAINS_INTERSTITIAL_CONTROLLER_CLIENT_H_ + +#include +#include + +#include "components/security_interstitials/content/security_interstitial_controller_client.h" +#include "url/gurl.h" + +namespace content { +class WebContents; +} // namespace content + +namespace security_interstitials { +class MetricsHelper; +} // namespace security_interstitials + +class PrefService; + +namespace unstoppable_domains { +enum class ResolveMethodTypes; + +class UnstoppableDomainsInterstitialControllerClient + : public security_interstitials::SecurityInterstitialControllerClient { + public: + static std::unique_ptr + GetMetricsHelper(const GURL& url); + + UnstoppableDomainsInterstitialControllerClient( + content::WebContents* web_contents, + const GURL& request_url, + PrefService* user_prefs, + PrefService* local_state, + const std::string& locale); + ~UnstoppableDomainsInterstitialControllerClient() override = default; + + UnstoppableDomainsInterstitialControllerClient( + const UnstoppableDomainsInterstitialControllerClient&) = delete; + UnstoppableDomainsInterstitialControllerClient& operator=( + const UnstoppableDomainsInterstitialControllerClient&) = delete; + + // security_interstitials::SecurityInterstitialControllerClient: + void Proceed() override; + void DontProceed(); + + private: + void SetResolveMethodAndReload(ResolveMethodTypes type); + + const GURL request_url_; + PrefService* local_state_; +}; + +} // namespace unstoppable_domains + +#endif // BRAVE_COMPONENTS_UNSTOPPABLE_DOMAINS_UNSTOPPABLE_DOMAINS_INTERSTITIAL_CONTROLLER_CLIENT_H_ diff --git a/components/unstoppable_domains/unstoppable_domains_navigation_throttle.cc b/components/unstoppable_domains/unstoppable_domains_navigation_throttle.cc new file mode 100644 index 000000000000..59a2ddb18c64 --- /dev/null +++ b/components/unstoppable_domains/unstoppable_domains_navigation_throttle.cc @@ -0,0 +1,93 @@ +/* Copyright (c) 2021 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "brave/components/unstoppable_domains/unstoppable_domains_navigation_throttle.h" + +#include + +#include "base/bind.h" +#include "base/threading/sequenced_task_runner_handle.h" +#include "brave/components/unstoppable_domains/unstoppable_domains_interstitial_controller_client.h" +#include "brave/components/unstoppable_domains/unstoppable_domains_opt_in_page.h" +#include "brave/components/unstoppable_domains/utils.h" +#include "components/prefs/pref_service.h" +#include "components/security_interstitials/content/security_interstitial_tab_helper.h" +#include "components/user_prefs/user_prefs.h" +#include "content/public/browser/browser_context.h" +#include "content/public/browser/navigation_handle.h" +#include "content/public/browser/web_contents.h" +#include "net/base/net_errors.h" + +namespace unstoppable_domains { + +// static +std::unique_ptr +UnstoppableDomainsNavigationThrottle::MaybeCreateThrottleFor( + content::NavigationHandle* navigation_handle, + PrefService* local_state, + const std::string& locale) { + if (!IsUnstoppableDomainsEnabled()) + return nullptr; + + return std::make_unique( + navigation_handle, local_state, locale); +} + +UnstoppableDomainsNavigationThrottle::UnstoppableDomainsNavigationThrottle( + content::NavigationHandle* navigation_handle, + PrefService* local_state, + const std::string& locale) + : content::NavigationThrottle(navigation_handle), + local_state_(local_state), + locale_(locale) { + content::BrowserContext* context = + navigation_handle->GetWebContents()->GetBrowserContext(); + user_prefs_ = user_prefs::UserPrefs::Get(context); +} + +UnstoppableDomainsNavigationThrottle::~UnstoppableDomainsNavigationThrottle() = + default; + +content::NavigationThrottle::ThrottleCheckResult +UnstoppableDomainsNavigationThrottle::WillStartRequest() { + GURL url = navigation_handle()->GetURL(); + if (!IsUnstoppableDomainsTLD(url) || !IsResolveMethodAsk(local_state_)) { + return content::NavigationThrottle::PROCEED; + } + + base::SequencedTaskRunnerHandle::Get()->PostTask( + FROM_HERE, + base::BindOnce(&UnstoppableDomainsNavigationThrottle::ShowInterstitial, + weak_ptr_factory_.GetWeakPtr())); + return content::NavigationThrottle::DEFER; +} + +void UnstoppableDomainsNavigationThrottle::ShowInterstitial() { + content::NavigationHandle* handle = navigation_handle(); + content::WebContents* web_contents = handle->GetWebContents(); + const GURL& request_url = handle->GetURL(); + + auto controller_client = + std::make_unique( + web_contents, request_url, user_prefs_, local_state_, locale_); + auto page = std::make_unique( + web_contents, handle->GetURL(), std::move(controller_client)); + + // Get the page content before giving up ownership of |page|. + std::string page_content = page->GetHTMLContents(); + + security_interstitials::SecurityInterstitialTabHelper::AssociateBlockingPage( + web_contents, handle->GetNavigationId(), std::move(page)); + + CancelDeferredNavigation(content::NavigationThrottle::ThrottleCheckResult( + content::NavigationThrottle::CANCEL, net::ERR_BLOCKED_BY_CLIENT, + page_content)); +} + +const char* UnstoppableDomainsNavigationThrottle::GetNameForLogging() { + return "UnstoppableDomainsNavigationThrottle"; +} + +} // namespace unstoppable_domains diff --git a/components/unstoppable_domains/unstoppable_domains_navigation_throttle.h b/components/unstoppable_domains/unstoppable_domains_navigation_throttle.h new file mode 100644 index 000000000000..42b6c7542778 --- /dev/null +++ b/components/unstoppable_domains/unstoppable_domains_navigation_throttle.h @@ -0,0 +1,58 @@ +/* Copyright (c) 2021 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef BRAVE_COMPONENTS_UNSTOPPABLE_DOMAINS_UNSTOPPABLE_DOMAINS_NAVIGATION_THROTTLE_H_ +#define BRAVE_COMPONENTS_UNSTOPPABLE_DOMAINS_UNSTOPPABLE_DOMAINS_NAVIGATION_THROTTLE_H_ + +#include +#include + +#include "base/memory/weak_ptr.h" +#include "content/public/browser/navigation_throttle.h" + +namespace content { +class NavigationHandle; +} // namespace content + +class PrefService; + +namespace unstoppable_domains { + +class UnstoppableDomainsNavigationThrottle + : public content::NavigationThrottle { + public: + explicit UnstoppableDomainsNavigationThrottle( + content::NavigationHandle* navigation_handle, + PrefService* local_state, + const std::string& locale); + ~UnstoppableDomainsNavigationThrottle() override; + + UnstoppableDomainsNavigationThrottle( + const UnstoppableDomainsNavigationThrottle&) = delete; + UnstoppableDomainsNavigationThrottle& operator=( + const UnstoppableDomainsNavigationThrottle&) = delete; + + static std::unique_ptr + MaybeCreateThrottleFor(content::NavigationHandle* navigation_handle, + PrefService* local_state, + const std::string& locale); + + // content::NavigationThrottle implementation: + ThrottleCheckResult WillStartRequest() override; + const char* GetNameForLogging() override; + + private: + void ShowInterstitial(); + + PrefService* user_prefs_ = nullptr; + PrefService* local_state_ = nullptr; + std::string locale_; + base::WeakPtrFactory weak_ptr_factory_{ + this}; +}; + +} // namespace unstoppable_domains + +#endif // BRAVE_COMPONENTS_UNSTOPPABLE_DOMAINS_UNSTOPPABLE_DOMAINS_NAVIGATION_THROTTLE_H_ diff --git a/components/unstoppable_domains/unstoppable_domains_opt_in_page.cc b/components/unstoppable_domains/unstoppable_domains_opt_in_page.cc new file mode 100644 index 000000000000..69940d54c568 --- /dev/null +++ b/components/unstoppable_domains/unstoppable_domains_opt_in_page.cc @@ -0,0 +1,111 @@ +/* Copyright (c) 2021 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "brave/components/unstoppable_domains/unstoppable_domains_opt_in_page.h" + +#include +#include + +#include "base/notreached.h" +#include "base/strings/string_number_conversions.h" +#include "base/strings/string_util.h" +#include "base/strings/utf_string_conversions.h" +#include "base/values.h" +#include "brave/components/unstoppable_domains/unstoppable_domains_interstitial_controller_client.h" +#include "components/grit/brave_components_resources.h" +#include "components/grit/brave_components_strings.h" +#include "components/security_interstitials/content/security_interstitial_controller_client.h" +#include "ui/base/l10n/l10n_util.h" + +namespace unstoppable_domains { + +// static +const security_interstitials::SecurityInterstitialPage::TypeID + UnstoppableDomainsOptInPage::kTypeForTesting = + &UnstoppableDomainsOptInPage::kTypeForTesting; + +UnstoppableDomainsOptInPage::UnstoppableDomainsOptInPage( + content::WebContents* web_contents, + const GURL& request_url, + std::unique_ptr< + security_interstitials::SecurityInterstitialControllerClient> + controller) + : security_interstitials::SecurityInterstitialPage(web_contents, + request_url, + std::move(controller)) {} + +UnstoppableDomainsOptInPage::~UnstoppableDomainsOptInPage() = default; + +void UnstoppableDomainsOptInPage::CommandReceived(const std::string& command) { + if (command == "\"pageLoadComplete\"") { + // content::WaitForRenderFrameReady sends this message when the page + // load completes. Ignore it. + return; + } + + int cmd = 0; + bool retval = base::StringToInt(command, &cmd); + DCHECK(retval); + + switch (cmd) { + case security_interstitials::CMD_DONT_PROCEED: + static_cast(controller()) + ->DontProceed(); + break; + case security_interstitials::CMD_PROCEED: + controller()->Proceed(); + break; + default: + NOTREACHED() << "Unsupported command: " << command; + } +} + +void UnstoppableDomainsOptInPage::PopulateInterstitialStrings( + base::DictionaryValue* load_time_data) { + load_time_data->SetString( + "tabTitle", + l10n_util::GetStringUTF16(IDS_UNSTOPPABLE_DOMAINS_OPT_IN_TITLE)); + load_time_data->SetString( + "heading", + l10n_util::GetStringUTF16(IDS_UNSTOPPABLE_DOMAINS_OPT_IN_HEADING)); + + const std::vector message_params = { + base::ASCIIToUTF16(""), + base::ASCIIToUTF16(""), + base::ASCIIToUTF16( + ""), + base::ASCIIToUTF16(""), + }; + load_time_data->SetString( + "primaryParagraph", + base::ReplaceStringPlaceholders( + l10n_util::GetStringUTF16( + IDS_UNSTOPPABLE_DOMAINS_OPT_IN_PRIMARY_PARAGRAPH), + message_params, nullptr)); + + load_time_data->SetString( + "primaryButtonText", + l10n_util::GetStringUTF16(IDS_UNSTOPPABLE_DOMAINS_OPT_IN_PRIMARY_BUTTON)); + load_time_data->SetString( + "dontProceedButtonText", + l10n_util::GetStringUTF16( + IDS_UNSTOPPABLE_DOMAINS_OPT_IN_DONT_PROCEED_BUTTON)); + load_time_data->SetString("finalParagraph", base::string16()); +} + +int UnstoppableDomainsOptInPage::GetHTMLTemplateId() { + return IDR_UNSTOPPABLE_DOMAINS_INTERSTITIAL_HTML; +} + +security_interstitials::SecurityInterstitialPage::TypeID +UnstoppableDomainsOptInPage::GetTypeForTesting() { + return UnstoppableDomainsOptInPage::kTypeForTesting; +} + +} // namespace unstoppable_domains diff --git a/components/unstoppable_domains/unstoppable_domains_opt_in_page.h b/components/unstoppable_domains/unstoppable_domains_opt_in_page.h new file mode 100644 index 000000000000..9f427b5a0886 --- /dev/null +++ b/components/unstoppable_domains/unstoppable_domains_opt_in_page.h @@ -0,0 +1,58 @@ +/* Copyright (c) 2021 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef BRAVE_COMPONENTS_UNSTOPPABLE_DOMAINS_UNSTOPPABLE_DOMAINS_OPT_IN_PAGE_H_ +#define BRAVE_COMPONENTS_UNSTOPPABLE_DOMAINS_UNSTOPPABLE_DOMAINS_OPT_IN_PAGE_H_ + +#include +#include + +#include "components/security_interstitials/content/security_interstitial_page.h" + +namespace content { +class WebContents; +} // namespace content + +namespace security_interstitials { +class SecurityInterstitialControllerClient; +} // namespace security_interstitials + +namespace unstoppable_domains { + +class UnstoppableDomainsOptInPage + : public security_interstitials::SecurityInterstitialPage { + public: + // Interstitial type, used in tests. + static const security_interstitials::SecurityInterstitialPage::TypeID + kTypeForTesting; + + UnstoppableDomainsOptInPage( + content::WebContents* web_contents, + const GURL& request_url, + std::unique_ptr< + security_interstitials::SecurityInterstitialControllerClient> + controller); + ~UnstoppableDomainsOptInPage() override; + + UnstoppableDomainsOptInPage(const UnstoppableDomainsOptInPage&) = delete; + UnstoppableDomainsOptInPage& operator=(const UnstoppableDomainsOptInPage&) = + delete; + + // SecurityInterstitialPage:: + void OnInterstitialClosing() override {} + void CommandReceived(const std::string& command) override; + security_interstitials::SecurityInterstitialPage::TypeID GetTypeForTesting() + override; + + protected: + // SecurityInterstitialPage:: + void PopulateInterstitialStrings( + base::DictionaryValue* load_time_data) override; + int GetHTMLTemplateId() override; +}; + +} // namespace unstoppable_domains + +#endif // BRAVE_COMPONENTS_UNSTOPPABLE_DOMAINS_UNSTOPPABLE_DOMAINS_OPT_IN_PAGE_H_ diff --git a/components/unstoppable_domains/unstoppable_domains_service.cc b/components/unstoppable_domains/unstoppable_domains_service.cc new file mode 100644 index 000000000000..71f3c93c5e37 --- /dev/null +++ b/components/unstoppable_domains/unstoppable_domains_service.cc @@ -0,0 +1,45 @@ +/* Copyright (c) 2021 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "brave/components/unstoppable_domains/unstoppable_domains_service.h" + +#include + +#include "brave/components/unstoppable_domains/constants.h" +#include "brave/components/unstoppable_domains/pref_names.h" +#include "brave/components/unstoppable_domains/unstoppable_domains_service_delegate.h" +#include "components/prefs/pref_change_registrar.h" +#include "components/prefs/pref_registry_simple.h" +#include "components/prefs/pref_service.h" + +namespace unstoppable_domains { + +UnstoppableDomainsService::UnstoppableDomainsService( + std::unique_ptr delegate, + content::BrowserContext* context, + PrefService* local_state) + : delegate_(std::move(delegate)) { + pref_change_registrar_ = std::make_unique(); + pref_change_registrar_->Init(local_state); + pref_change_registrar_->Add( + kResolveMethod, + base::Bind(&UnstoppableDomainsService::OnPreferenceChanged, + base::Unretained(this))); +} + +UnstoppableDomainsService::~UnstoppableDomainsService() = default; + +// static +void UnstoppableDomainsService::RegisterLocalStatePrefs( + PrefRegistrySimple* registry) { + registry->RegisterIntegerPref(kResolveMethod, + static_cast(ResolveMethodTypes::ASK)); +} + +void UnstoppableDomainsService::OnPreferenceChanged() { + delegate_->UpdateNetworkService(); +} + +} // namespace unstoppable_domains diff --git a/components/unstoppable_domains/unstoppable_domains_service.h b/components/unstoppable_domains/unstoppable_domains_service.h new file mode 100644 index 000000000000..7a6e29fca9b9 --- /dev/null +++ b/components/unstoppable_domains/unstoppable_domains_service.h @@ -0,0 +1,48 @@ +/* Copyright (c) 2021 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef BRAVE_COMPONENTS_UNSTOPPABLE_DOMAINS_UNSTOPPABLE_DOMAINS_SERVICE_H_ +#define BRAVE_COMPONENTS_UNSTOPPABLE_DOMAINS_UNSTOPPABLE_DOMAINS_SERVICE_H_ + +#include + +#include "components/keyed_service/core/keyed_service.h" + +namespace content { +class BrowserContext; +} // namespace content + +class PrefChangeRegistrar; +class PrefRegistrySimple; +class PrefService; + +namespace unstoppable_domains { + +class UnstoppableDomainsServiceDelegate; + +class UnstoppableDomainsService : public KeyedService { + public: + UnstoppableDomainsService( + std::unique_ptr delegate, + content::BrowserContext* context, + PrefService* local_state); + ~UnstoppableDomainsService() override; + + UnstoppableDomainsService(const UnstoppableDomainsService&) = delete; + UnstoppableDomainsService& operator=(const UnstoppableDomainsService&) = + delete; + + static void RegisterLocalStatePrefs(PrefRegistrySimple* registry); + + private: + void OnPreferenceChanged(); + + std::unique_ptr pref_change_registrar_; + std::unique_ptr delegate_; +}; + +} // namespace unstoppable_domains + +#endif // BRAVE_COMPONENTS_UNSTOPPABLE_DOMAINS_UNSTOPPABLE_DOMAINS_SERVICE_H_ diff --git a/components/unstoppable_domains/unstoppable_domains_service_delegate.h b/components/unstoppable_domains/unstoppable_domains_service_delegate.h new file mode 100644 index 000000000000..91f2726ffb91 --- /dev/null +++ b/components/unstoppable_domains/unstoppable_domains_service_delegate.h @@ -0,0 +1,20 @@ +/* Copyright (c) 2021 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef BRAVE_COMPONENTS_UNSTOPPABLE_DOMAINS_UNSTOPPABLE_DOMAINS_SERVICE_DELEGATE_H_ +#define BRAVE_COMPONENTS_UNSTOPPABLE_DOMAINS_UNSTOPPABLE_DOMAINS_SERVICE_DELEGATE_H_ + +namespace unstoppable_domains { + +class UnstoppableDomainsServiceDelegate { + public: + UnstoppableDomainsServiceDelegate() = default; + virtual ~UnstoppableDomainsServiceDelegate() = default; + virtual void UpdateNetworkService() = 0; +}; + +} // namespace unstoppable_domains + +#endif // BRAVE_COMPONENTS_UNSTOPPABLE_DOMAINS_UNSTOPPABLE_DOMAINS_SERVICE_DELEGATE_H_ diff --git a/components/unstoppable_domains/utils.cc b/components/unstoppable_domains/utils.cc new file mode 100644 index 000000000000..84e2cc4b1739 --- /dev/null +++ b/components/unstoppable_domains/utils.cc @@ -0,0 +1,45 @@ +/* Copyright (c) 2021 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "brave/components/unstoppable_domains/utils.h" + +#include "base/feature_list.h" +#include "base/strings/string_util.h" +#include "brave/components/unstoppable_domains/constants.h" +#include "brave/components/unstoppable_domains/features.h" +#include "brave/components/unstoppable_domains/pref_names.h" +#include "brave/net/unstoppable_domains/constants.h" +#include "components/prefs/pref_service.h" +#include "url/gurl.h" + +namespace unstoppable_domains { + +bool IsUnstoppableDomainsTLD(const GURL& url) { + return base::EndsWith(url.host_piece(), kCryptoDomain); +} + +bool IsUnstoppableDomainsEnabled() { + return base::FeatureList::IsEnabled(features::kUnstoppableDomains); +} + +bool IsResolveMethodAsk(PrefService* local_state) { + if (!local_state || !IsUnstoppableDomainsEnabled()) { + return false; // Treat it as disabled. + } + + return local_state->GetInteger(kResolveMethod) == + static_cast(ResolveMethodTypes::ASK); +} + +bool IsResolveMethodDoH(PrefService* local_state) { + if (!local_state || !IsUnstoppableDomainsEnabled()) { + return false; // Treat it as disabled. + } + + return local_state->GetInteger(kResolveMethod) == + static_cast(ResolveMethodTypes::DNS_OVER_HTTPS); +} + +} // namespace unstoppable_domains diff --git a/components/unstoppable_domains/utils.h b/components/unstoppable_domains/utils.h new file mode 100644 index 000000000000..724bc573e997 --- /dev/null +++ b/components/unstoppable_domains/utils.h @@ -0,0 +1,21 @@ +/* Copyright (c) 2021 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef BRAVE_COMPONENTS_UNSTOPPABLE_DOMAINS_UTILS_H_ +#define BRAVE_COMPONENTS_UNSTOPPABLE_DOMAINS_UTILS_H_ + +class GURL; +class PrefService; + +namespace unstoppable_domains { + +bool IsUnstoppableDomainsTLD(const GURL& url); +bool IsUnstoppableDomainsEnabled(); +bool IsResolveMethodAsk(PrefService* local_state); +bool IsResolveMethodDoH(PrefService* local_state); + +} // namespace unstoppable_domains + +#endif // BRAVE_COMPONENTS_UNSTOPPABLE_DOMAINS_UTILS_H_ diff --git a/net/dns/dns_transaction_unittest.cc b/net/dns/dns_transaction_unittest.cc new file mode 100644 index 000000000000..34697f2f5153 --- /dev/null +++ b/net/dns/dns_transaction_unittest.cc @@ -0,0 +1,1023 @@ +/* Copyright (c) 2021 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "net/dns/dns_transaction.h" + +#include + +#include +#include +#include + +#include "base/base64url.h" +#include "base/bind.h" +#include "base/containers/circular_deque.h" +#include "base/optional.h" +#include "base/rand_util.h" +#include "base/run_loop.h" +#include "base/stl_util.h" +#include "base/strings/string_util.h" +#include "base/strings/stringprintf.h" +#include "base/sys_byteorder.h" +#include "base/test/metrics/histogram_tester.h" +#include "base/threading/thread_task_runner_handle.h" +#include "base/time/time.h" +#include "base/values.h" +#include "brave/net/unstoppable_domains/constants.h" +#include "net/base/ip_address.h" +#include "net/base/port_util.h" +#include "net/base/upload_bytes_element_reader.h" +#include "net/base/url_util.h" +#include "net/cookies/cookie_access_result.h" +#include "net/cookies/cookie_util.h" +#include "net/dns/dns_config.h" +#include "net/dns/dns_query.h" +#include "net/dns/dns_response.h" +#include "net/dns/dns_server_iterator.h" +#include "net/dns/dns_session.h" +#include "net/dns/dns_socket_allocator.h" +#include "net/dns/dns_test_util.h" +#include "net/dns/dns_util.h" +#include "net/dns/public/dns_over_https_server_config.h" +#include "net/dns/public/dns_protocol.h" +#include "net/dns/resolve_context.h" +#include "net/log/net_log.h" +#include "net/log/net_log_capture_mode.h" +#include "net/log/net_log_with_source.h" +#include "net/log/test_net_log.h" +#include "net/proxy_resolution/proxy_config_service_fixed.h" +#include "net/socket/socket_test_util.h" +#include "net/test/gtest_util.h" +#include "net/test/test_with_task_environment.h" +#include "net/test/url_request/url_request_failed_job.h" +#include "net/third_party/uri_template/uri_template.h" +#include "net/url_request/url_request_filter.h" +#include "net/url_request/url_request_interceptor.h" +#include "net/url_request/url_request_test_util.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +using net::test::IsOk; + +namespace net { + +namespace { + +base::TimeDelta kFallbackPeriod = base::TimeDelta::FromSeconds(1); + +const char kMockHostname[] = "mock.http"; + +std::string DomainFromDot(const base::StringPiece& dotted) { + std::string out; + EXPECT_TRUE(DNSDomainFromDot(dotted, &out)); + return out; +} + +enum class Transport { UDP, TCP, HTTPS }; + +// A SocketDataProvider builder. +class DnsSocketData { + public: + // The ctor takes parameters for the DnsQuery. + DnsSocketData(uint16_t id, + const char* dotted_name, + uint16_t qtype, + IoMode mode, + Transport transport, + const OptRecordRdata* opt_rdata = nullptr, + DnsQuery::PaddingStrategy padding_strategy = + DnsQuery::PaddingStrategy::NONE) + : query_(new DnsQuery(id, + DomainFromDot(dotted_name), + qtype, + opt_rdata, + padding_strategy)), + transport_(transport) { + if (Transport::TCP == transport_) { + std::unique_ptr length(new uint16_t); + *length = base::HostToNet16(query_->io_buffer()->size()); + writes_.push_back(MockWrite(mode, + reinterpret_cast(length.get()), + sizeof(uint16_t), num_reads_and_writes())); + lengths_.push_back(std::move(length)); + } + writes_.push_back(MockWrite(mode, query_->io_buffer()->data(), + query_->io_buffer()->size(), + num_reads_and_writes())); + } + ~DnsSocketData() = default; + + // All responses must be added before GetProvider. + + // Adds pre-built DnsResponse. |tcp_length| will be used in TCP mode only. + void AddResponseWithLength(std::unique_ptr response, + IoMode mode, + uint16_t tcp_length) { + CHECK(!provider_.get()); + if (Transport::TCP == transport_) { + std::unique_ptr length(new uint16_t); + *length = base::HostToNet16(tcp_length); + reads_.push_back(MockRead(mode, + reinterpret_cast(length.get()), + sizeof(uint16_t), num_reads_and_writes())); + lengths_.push_back(std::move(length)); + } + reads_.push_back(MockRead(mode, response->io_buffer()->data(), + response->io_buffer_size(), + num_reads_and_writes())); + responses_.push_back(std::move(response)); + } + + // Adds pre-built DnsResponse. + void AddResponse(std::unique_ptr response, IoMode mode) { + uint16_t tcp_length = response->io_buffer_size(); + AddResponseWithLength(std::move(response), mode, tcp_length); + } + + // Adds pre-built response from |data| buffer. + void AddResponseData(const uint8_t* data, size_t length, IoMode mode) { + CHECK(!provider_.get()); + AddResponse(std::make_unique( + reinterpret_cast(data), length, 0), + mode); + } + + // Adds pre-built response from |data| buffer. + void AddResponseData(const uint8_t* data, + size_t length, + int offset, + IoMode mode) { + CHECK(!provider_.get()); + AddResponse( + std::make_unique(reinterpret_cast(data), + length - offset, offset), + mode); + } + + // Add no-answer (RCODE only) response matching the query. + void AddRcode(int rcode, IoMode mode) { + std::unique_ptr response(new DnsResponse( + query_->io_buffer()->data(), query_->io_buffer()->size(), 0)); + dns_protocol::Header* header = + reinterpret_cast(response->io_buffer()->data()); + header->flags |= base::HostToNet16(dns_protocol::kFlagResponse | rcode); + AddResponse(std::move(response), mode); + } + + // Add error response. + void AddReadError(int error, IoMode mode) { + reads_.push_back(MockRead(mode, error, num_reads_and_writes())); + } + + // Build, if needed, and return the SocketDataProvider. No new responses + // should be added afterwards. + SequencedSocketData* GetProvider() { + if (provider_.get()) + return provider_.get(); + // Terminate the reads with ERR_IO_PENDING to prevent overrun and default to + // timeout. + if (transport_ != Transport::HTTPS) { + reads_.push_back(MockRead(SYNCHRONOUS, ERR_IO_PENDING, + writes_.size() + reads_.size())); + } + provider_.reset(new SequencedSocketData(reads_, writes_)); + if (Transport::TCP == transport_ || Transport::HTTPS == transport_) { + provider_->set_connect_data(MockConnect(reads_[0].mode, OK)); + } + return provider_.get(); + } + + uint16_t query_id() const { return query_->id(); } + + IOBufferWithSize* query_buffer() { return query_->io_buffer(); } + + private: + size_t num_reads_and_writes() const { return reads_.size() + writes_.size(); } + + std::unique_ptr query_; + Transport transport_; + std::vector> lengths_; + std::vector> responses_; + std::vector writes_; + std::vector reads_; + std::unique_ptr provider_; + + DISALLOW_COPY_AND_ASSIGN(DnsSocketData); +}; + +class TestSocketFactory; + +// A variant of MockUDPClientSocket which always fails to Connect. +class FailingUDPClientSocket : public MockUDPClientSocket { + public: + FailingUDPClientSocket(SocketDataProvider* data, net::NetLog* net_log) + : MockUDPClientSocket(data, net_log) {} + ~FailingUDPClientSocket() override = default; + int Connect(const IPEndPoint& endpoint) override { + return ERR_CONNECTION_REFUSED; + } + + private: + DISALLOW_COPY_AND_ASSIGN(FailingUDPClientSocket); +}; + +// A variant of MockUDPClientSocket which notifies the factory OnConnect. +class TestUDPClientSocket : public MockUDPClientSocket { + public: + TestUDPClientSocket(TestSocketFactory* factory, + SocketDataProvider* data, + net::NetLog* net_log) + : MockUDPClientSocket(data, net_log), factory_(factory) {} + ~TestUDPClientSocket() override = default; + int Connect(const IPEndPoint& endpoint) override; + + private: + TestSocketFactory* factory_; + + DISALLOW_COPY_AND_ASSIGN(TestUDPClientSocket); +}; + +// Creates TestUDPClientSockets and keeps endpoints reported via OnConnect. +class TestSocketFactory : public MockClientSocketFactory { + public: + TestSocketFactory() = default; + ~TestSocketFactory() override = default; + + std::unique_ptr CreateDatagramClientSocket( + DatagramSocket::BindType bind_type, + NetLog* net_log, + const NetLogSource& source) override { + if (fail_next_socket_) { + fail_next_socket_ = false; + return std::unique_ptr( + new FailingUDPClientSocket(&empty_data_, net_log)); + } + + SocketDataProvider* data_provider = mock_data().GetNext(); + auto socket = + std::make_unique(this, data_provider, net_log); + + // Even using DEFAULT_BIND, actual sockets have been measured to very rarely + // repeat the same source port multiple times in a row. Need to mimic that + // functionality here, so DnsUdpTracker doesn't misdiagnose repeated port + // as low entropy. + if (diverse_source_ports_) + socket->set_source_port(next_source_port_++); + + return socket; + } + + void OnConnect(const IPEndPoint& endpoint) { + remote_endpoints_.emplace_back(endpoint); + } + + struct RemoteNameserver { + explicit RemoteNameserver(IPEndPoint insecure_nameserver) + : insecure_nameserver(insecure_nameserver) {} + explicit RemoteNameserver(DnsOverHttpsServerConfig secure_nameserver) + : secure_nameserver(secure_nameserver) {} + + base::Optional insecure_nameserver; + base::Optional secure_nameserver; + }; + + std::vector remote_endpoints_; + bool fail_next_socket_ = false; + bool diverse_source_ports_ = true; + + private: + StaticSocketDataProvider empty_data_; + uint16_t next_source_port_ = 123; +}; + +int TestUDPClientSocket::Connect(const IPEndPoint& endpoint) { + factory_->OnConnect(endpoint); + return MockUDPClientSocket::Connect(endpoint); +} + +// Helper class that holds a DnsTransaction and handles OnTransactionComplete. +class TransactionHelper { + public: + // If |expected_answer_count| < 0 then it is the expected net error. + explicit TransactionHelper(int expected_answer_count) + : expected_answer_count_(expected_answer_count) {} + + // Mark that the transaction shall be destroyed immediately upon callback. + void set_cancel_in_callback() { cancel_in_callback_ = true; } + + void StartTransaction(DnsTransactionFactory* factory, + const char* hostname, + uint16_t qtype, + bool secure, + ResolveContext* context) { + std::unique_ptr transaction = factory->CreateTransaction( + hostname, qtype, CompletionCallback(), + NetLogWithSource::Make(&net_log_, net::NetLogSourceType::NONE), secure, + factory->GetSecureDnsModeForTest(), context, true /* fast_timeout */); + transaction->SetRequestPriority(DEFAULT_PRIORITY); + EXPECT_EQ(qtype, transaction->GetType()); + StartTransaction(std::move(transaction)); + } + + void StartTransaction(std::unique_ptr transaction) { + EXPECT_FALSE(transaction_); + transaction_ = std::move(transaction); + qtype_ = transaction_->GetType(); + transaction_->Start(); + } + + void Cancel() { + ASSERT_TRUE(transaction_.get() != nullptr); + transaction_.reset(nullptr); + } + + DnsTransactionFactory::CallbackType CompletionCallback() { + return base::BindOnce(&TransactionHelper::OnTransactionComplete, + base::Unretained(this)); + } + + void OnTransactionComplete(DnsTransaction* t, + int rv, + const DnsResponse* response, + base::Optional doh_provider_id) { + EXPECT_FALSE(completed_); + EXPECT_EQ(transaction_.get(), t); + + completed_ = true; + response_ = response; + + transaction_complete_run_loop_.Quit(); + + if (cancel_in_callback_) { + Cancel(); + return; + } + + if (response) + EXPECT_TRUE(response->IsValid()); + + if (expected_answer_count_ >= 0) { + ASSERT_THAT(rv, IsOk()); + ASSERT_TRUE(response != nullptr); + EXPECT_EQ(static_cast(expected_answer_count_), + response->answer_count()); + EXPECT_EQ(qtype_, response->qtype()); + + DnsRecordParser parser = response->Parser(); + DnsResourceRecord record; + for (int i = 0; i < expected_answer_count_; ++i) { + EXPECT_TRUE(parser.ReadRecord(&record)); + } + } else { + EXPECT_EQ(expected_answer_count_, rv); + } + } + + bool has_completed() const { return completed_; } + const DnsResponse* response() const { return response_; } + NetLog* net_log() { return &net_log_; } + + // Runs until the completion callback is called. Transaction must have already + // been started or this will never complete. + void RunUntilComplete() { + DCHECK(transaction_); + DCHECK(!transaction_complete_run_loop_.running()); + transaction_complete_run_loop_.Run(); + DCHECK(has_completed()); + } + + private: + uint16_t qtype_ = 0; + std::unique_ptr transaction_; + const DnsResponse* response_ = nullptr; + int expected_answer_count_; + bool cancel_in_callback_ = false; + base::RunLoop transaction_complete_run_loop_; + bool completed_ = false; + TestNetLog net_log_; +}; + +// Callback that allows a test to modify HttpResponseinfo +// before the response is sent to the requester. This allows +// response headers to be changed. +typedef base::RepeatingCallback + ResponseModifierCallback; + +// Callback that allows the test to substitute its own implementation +// of URLRequestJob to handle the request. +typedef base::RepeatingCallback( + URLRequest* request, + SocketDataProvider* data_provider)> + DohJobMakerCallback; + +// Subclass of URLRequestJob which takes a SocketDataProvider with data +// representing both a DNS over HTTPS query and response. +class URLRequestMockDohJob : public URLRequestJob, public AsyncSocket { + public: + URLRequestMockDohJob( + URLRequest* request, + SocketDataProvider* data_provider, + ResponseModifierCallback response_modifier = ResponseModifierCallback()) + : URLRequestJob(request), + content_length_(0), + leftover_data_len_(0), + data_provider_(data_provider), + response_modifier_(response_modifier) { + data_provider_->Initialize(this); + MatchQueryData(request, data_provider); + } + + // Compare the query contained in either the POST body or the body + // parameter of the GET query to the write data of the SocketDataProvider. + static void MatchQueryData(URLRequest* request, + SocketDataProvider* data_provider) { + std::string decoded_query; + if (request->method() == "GET") { + std::string encoded_query; + EXPECT_TRUE(GetValueForKeyInQuery(request->url(), "dns", &encoded_query)); + EXPECT_GT(encoded_query.size(), 0ul); + + EXPECT_TRUE(base::Base64UrlDecode( + encoded_query, base::Base64UrlDecodePolicy::IGNORE_PADDING, + &decoded_query)); + } else if (request->method() == "POST") { + const UploadDataStream* stream = request->get_upload_for_testing(); + auto* readers = stream->GetElementReaders(); + EXPECT_TRUE(readers); + EXPECT_FALSE(readers->empty()); + for (auto& reader : *readers) { + const UploadBytesElementReader* byte_reader = reader->AsBytesReader(); + decoded_query += + std::string(byte_reader->bytes(), byte_reader->length()); + } + } + + std::string query(decoded_query); + MockWriteResult result(SYNCHRONOUS, 1); + while (result.result > 0 && query.length() > 0) { + result = data_provider->OnWrite(query); + if (result.result > 0) + query = query.substr(result.result); + } + } + + static std::string GetMockHttpsUrl(const std::string& path) { + return "https://" + (kMockHostname + ("/" + path)); + } + + // URLRequestJob implementation: + void Start() override { + // Start reading asynchronously so that all error reporting and data + // callbacks happen as they would for network requests. + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::BindOnce(&URLRequestMockDohJob::StartAsync, + weak_factory_.GetWeakPtr())); + } + + ~URLRequestMockDohJob() override { + if (data_provider_) + data_provider_->DetachSocket(); + } + + int ReadRawData(IOBuffer* buf, int buf_size) override { + if (!data_provider_) + return ERR_FAILED; + if (leftover_data_len_ > 0) { + int rv = DoBufferCopy(leftover_data_, leftover_data_len_, buf, buf_size); + return rv; + } + + if (data_provider_->AllReadDataConsumed()) + return 0; + + MockRead read = data_provider_->OnRead(); + + if (read.result < ERR_IO_PENDING) + return read.result; + + if (read.result == ERR_IO_PENDING) { + pending_buf_ = buf; + pending_buf_size_ = buf_size; + return ERR_IO_PENDING; + } + return DoBufferCopy(read.data, read.data_len, buf, buf_size); + } + + void GetResponseInfo(HttpResponseInfo* info) override { + // Send back mock headers. + std::string raw_headers; + raw_headers.append( + "HTTP/1.1 200 OK\n" + "Content-type: application/dns-message\n"); + if (content_length_ > 0) { + raw_headers.append(base::StringPrintf("Content-Length: %1d\n", + static_cast(content_length_))); + } + info->headers = base::MakeRefCounted( + HttpUtil::AssembleRawHeaders(raw_headers)); + if (response_modifier_) + response_modifier_.Run(request(), info); + } + + // AsyncSocket implementation: + void OnReadComplete(const MockRead& data) override { + EXPECT_NE(data.result, ERR_IO_PENDING); + if (data.result < 0) + return ReadRawDataComplete(data.result); + ReadRawDataComplete(DoBufferCopy(data.data, data.data_len, pending_buf_, + pending_buf_size_)); + } + void OnWriteComplete(int rv) override {} + void OnConnectComplete(const MockConnect& data) override {} + void OnDataProviderDestroyed() override { data_provider_ = nullptr; } + + private: + void StartAsync() { + if (!request_) + return; + if (content_length_) + set_expected_content_size(content_length_); + NotifyHeadersComplete(); + } + + int DoBufferCopy(const char* data, + int data_len, + IOBuffer* buf, + int buf_size) { + if (data_len > buf_size) { + memcpy(buf->data(), data, buf_size); + leftover_data_ = data + buf_size; + leftover_data_len_ = data_len - buf_size; + return buf_size; + } + memcpy(buf->data(), data, data_len); + return data_len; + } + + const int content_length_; + const char* leftover_data_; + int leftover_data_len_; + SocketDataProvider* data_provider_; + const ResponseModifierCallback response_modifier_; + IOBuffer* pending_buf_; + int pending_buf_size_; + + base::WeakPtrFactory weak_factory_{this}; + + DISALLOW_COPY_AND_ASSIGN(URLRequestMockDohJob); +}; + +class DnsTransactionTestBase : public testing::Test { + public: + DnsTransactionTestBase() = default; + + ~DnsTransactionTestBase() override { + // All queued transaction IDs should be used by a transaction calling + // GetNextId(). + CHECK(transaction_ids_.empty()); + } + + // Generates |nameservers| for DnsConfig. + void ConfigureNumServers(size_t num_servers) { + CHECK_LE(num_servers, 255u); + config_.nameservers.clear(); + for (size_t i = 0; i < num_servers; ++i) { + config_.nameservers.push_back( + IPEndPoint(IPAddress(192, 168, 1, i), dns_protocol::kDefaultPort)); + } + } + + // Configures the DnsConfig DNS-over-HTTPS server(s), which either + // accept GET or POST requests based on use_post. If a + // ResponseModifierCallback is provided it will be called to construct the + // HTTPResponse. + void ConfigureDohServers(bool use_post, + size_t num_doh_servers = 1, + bool make_available = true) { + GURL url(URLRequestMockDohJob::GetMockHttpsUrl("doh_test")); + URLRequestFilter* filter = URLRequestFilter::GetInstance(); + filter->AddHostnameInterceptor(url.scheme(), url.host(), + std::make_unique(this)); + CHECK_LE(num_doh_servers, 255u); + for (size_t i = 0; i < num_doh_servers; ++i) { + std::string server_template(URLRequestMockDohJob::GetMockHttpsUrl( + base::StringPrintf("doh_test_%zu", i)) + + "{?dns}"); + config_.dns_over_https_servers.push_back( + DnsOverHttpsServerConfig(server_template, use_post)); + } + ConfigureFactory(); + + if (make_available) { + for (size_t server_index = 0; server_index < num_doh_servers; + ++server_index) { + resolve_context_->RecordServerSuccess( + server_index, true /* is_doh_server */, session_.get()); + } + } + } + + // Called after fully configuring |config|. + void ConfigureFactory() { + socket_factory_.reset(new TestSocketFactory()); + session_ = new DnsSession( + config_, + std::make_unique( + socket_factory_.get(), config_.nameservers, nullptr /* net_log */), + base::BindRepeating(&DnsTransactionTestBase::GetNextId, + base::Unretained(this)), + nullptr /* NetLog */); + resolve_context_->InvalidateCachesAndPerSessionData( + session_.get(), false /* network_change */); + transaction_factory_ = DnsTransactionFactory::CreateFactory(session_.get()); + } + + void AddSocketData(std::unique_ptr data, + bool enqueue_transaction_id = true) { + CHECK(socket_factory_.get()); + if (enqueue_transaction_id) + transaction_ids_.push_back(data->query_id()); + socket_factory_->AddSocketDataProvider(data->GetProvider()); + socket_data_.push_back(std::move(data)); + } + + // Add expected query for |dotted_name| and |qtype| with |id| and response + // taken verbatim from |data| of |data_length| bytes. The transaction id in + // |data| should equal |id|, unless testing mismatched response. + void AddQueryAndResponse(uint16_t id, + const char* dotted_name, + uint16_t qtype, + const uint8_t* response_data, + size_t response_length, + IoMode mode, + Transport transport, + const OptRecordRdata* opt_rdata = nullptr, + DnsQuery::PaddingStrategy padding_strategy = + DnsQuery::PaddingStrategy::NONE, + bool enqueue_transaction_id = true) { + CHECK(socket_factory_.get()); + std::unique_ptr data(new DnsSocketData( + id, dotted_name, qtype, mode, transport, opt_rdata, padding_strategy)); + data->AddResponseData(response_data, response_length, mode); + AddSocketData(std::move(data), enqueue_transaction_id); + } + + void AddQueryAndErrorResponse(uint16_t id, + const char* dotted_name, + uint16_t qtype, + int error, + IoMode mode, + Transport transport, + const OptRecordRdata* opt_rdata = nullptr, + DnsQuery::PaddingStrategy padding_strategy = + DnsQuery::PaddingStrategy::NONE, + bool enqueue_transaction_id = true) { + CHECK(socket_factory_.get()); + std::unique_ptr data(new DnsSocketData( + id, dotted_name, qtype, mode, transport, opt_rdata, padding_strategy)); + data->AddReadError(error, mode); + AddSocketData(std::move(data), enqueue_transaction_id); + } + + void AddAsyncQueryAndResponse(uint16_t id, + const char* dotted_name, + uint16_t qtype, + const uint8_t* data, + size_t data_length, + const OptRecordRdata* opt_rdata = nullptr) { + AddQueryAndResponse(id, dotted_name, qtype, data, data_length, ASYNC, + Transport::UDP, opt_rdata); + } + + void AddSyncQueryAndResponse(uint16_t id, + const char* dotted_name, + uint16_t qtype, + const uint8_t* data, + size_t data_length, + const OptRecordRdata* opt_rdata = nullptr) { + AddQueryAndResponse(id, dotted_name, qtype, data, data_length, SYNCHRONOUS, + Transport::UDP, opt_rdata); + } + + // Add expected query of |dotted_name| and |qtype| and no response. + void AddHangingQuery( + const char* dotted_name, + uint16_t qtype, + DnsQuery::PaddingStrategy padding_strategy = + DnsQuery::PaddingStrategy::NONE, + uint16_t id = base::RandInt(0, std::numeric_limits::max()), + bool enqueue_transaction_id = true) { + std::unique_ptr data( + new DnsSocketData(id, dotted_name, qtype, ASYNC, Transport::UDP, + nullptr /* opt_rdata */, padding_strategy)); + AddSocketData(std::move(data), enqueue_transaction_id); + } + + // Add expected query of |dotted_name| and |qtype| and matching response with + // no answer and RCODE set to |rcode|. The id will be generated randomly. + void AddQueryAndRcode( + const char* dotted_name, + uint16_t qtype, + int rcode, + IoMode mode, + Transport trans, + DnsQuery::PaddingStrategy padding_strategy = + DnsQuery::PaddingStrategy::NONE, + uint16_t id = base::RandInt(0, std::numeric_limits::max()), + bool enqueue_transaction_id = true) { + CHECK_NE(dns_protocol::kRcodeNOERROR, rcode); + std::unique_ptr data( + new DnsSocketData(id, dotted_name, qtype, mode, trans, + nullptr /* opt_rdata */, padding_strategy)); + data->AddRcode(rcode, mode); + AddSocketData(std::move(data), enqueue_transaction_id); + } + + void AddAsyncQueryAndRcode(const char* dotted_name, + uint16_t qtype, + int rcode) { + AddQueryAndRcode(dotted_name, qtype, rcode, ASYNC, Transport::UDP); + } + + void AddSyncQueryAndRcode(const char* dotted_name, + uint16_t qtype, + int rcode) { + AddQueryAndRcode(dotted_name, qtype, rcode, SYNCHRONOUS, Transport::UDP); + } + + // Checks if the sockets were connected in the order matching the indices in + // |servers|. + void CheckServerOrder(const size_t* servers, size_t num_attempts) { + ASSERT_EQ(num_attempts, socket_factory_->remote_endpoints_.size()); + auto num_insecure_nameservers = session_->config().nameservers.size(); + for (size_t i = 0; i < num_attempts; ++i) { + if (servers[i] < num_insecure_nameservers) { + // Check insecure server match. + EXPECT_EQ( + socket_factory_->remote_endpoints_[i].insecure_nameserver.value(), + session_->config().nameservers[servers[i]]); + } else { + // Check secure server match. + EXPECT_EQ( + socket_factory_->remote_endpoints_[i].secure_nameserver.value(), + session_->config() + .dns_over_https_servers[servers[i] - num_insecure_nameservers]); + } + } + } + + std::unique_ptr MaybeInterceptRequest(URLRequest* request) { + // If the path indicates a redirect, skip checking the list of + // configured servers, because it won't be there and we still want + // to handle it. + bool server_found = request->url().path() == "/redirect-destination"; + for (auto server : config_.dns_over_https_servers) { + if (server_found) + break; + std::string url_base = + GetURLFromTemplateWithoutParameters(server.server_template); + if (server.use_post && request->method() == "POST") { + if (url_base == request->url().spec()) { + server_found = true; + socket_factory_->remote_endpoints_.emplace_back(server); + } + } else if (!server.use_post && request->method() == "GET") { + std::string prefix = url_base + "?dns="; + auto mispair = std::mismatch(prefix.begin(), prefix.end(), + request->url().spec().begin()); + if (mispair.first == prefix.end()) { + server_found = true; + socket_factory_->remote_endpoints_.emplace_back(server); + } + } + } + EXPECT_TRUE(server_found); + + EXPECT_TRUE( + request->isolation_info().network_isolation_key().IsTransient()); + + // All DoH requests for the same ResolveContext should use the same + // IsolationInfo, so network objects like sockets can be reused between + // requests. + if (!expect_multiple_isolation_infos_) { + if (!isolation_info_) { + isolation_info_ = + std::make_unique(request->isolation_info()); + } else { + EXPECT_TRUE( + isolation_info_->IsEqualForTesting(request->isolation_info())); + } + } + + EXPECT_FALSE(request->allow_credentials()); + EXPECT_TRUE(request->disable_secure_dns()); + + std::string accept; + EXPECT_TRUE(request->extra_request_headers().GetHeader("Accept", &accept)); + EXPECT_EQ(accept, "application/dns-message"); + + std::string language; + EXPECT_TRUE(request->extra_request_headers().GetHeader("Accept-Language", + &language)); + EXPECT_EQ(language, "*"); + + std::string user_agent; + EXPECT_TRUE( + request->extra_request_headers().GetHeader("User-Agent", &user_agent)); + EXPECT_EQ(user_agent, "Chrome"); + + SocketDataProvider* provider = socket_factory_->mock_data().GetNext(); + + if (doh_job_maker_) + return doh_job_maker_.Run(request, provider); + + return std::make_unique(request, provider, + response_modifier_); + } + + class DohJobInterceptor : public URLRequestInterceptor { + public: + explicit DohJobInterceptor(DnsTransactionTestBase* test) : test_(test) {} + ~DohJobInterceptor() override {} + + // URLRequestInterceptor implementation: + std::unique_ptr MaybeInterceptRequest( + URLRequest* request) const override { + return test_->MaybeInterceptRequest(request); + } + + private: + DnsTransactionTestBase* test_; + + DISALLOW_COPY_AND_ASSIGN(DohJobInterceptor); + }; + + void SetResponseModifierCallback(ResponseModifierCallback response_modifier) { + response_modifier_ = response_modifier; + } + + void SetDohJobMakerCallback(DohJobMakerCallback doh_job_maker) { + doh_job_maker_ = doh_job_maker; + } + + void SetUp() override { + // By default set one server, + ConfigureNumServers(1); + // and no retransmissions, + config_.attempts = 1; + // and an arbitrary fallback period. + config_.fallback_period = kFallbackPeriod; + + request_context_ = std::make_unique(); + resolve_context_ = std::make_unique( + request_context_.get(), false /* enable_caching */); + + ConfigureFactory(); + } + + void TearDown() override { + // Check that all socket data was at least written to. + for (size_t i = 0; i < socket_data_.size(); ++i) { + EXPECT_TRUE(socket_data_[i]->GetProvider()->AllWriteDataConsumed()) << i; + } + + URLRequestFilter* filter = URLRequestFilter::GetInstance(); + filter->ClearHandlers(); + } + + void set_expect_multiple_isolation_infos( + bool expect_multiple_isolation_infos) { + expect_multiple_isolation_infos_ = expect_multiple_isolation_infos; + } + + protected: + int GetNextId(int min, int max) { + EXPECT_FALSE(transaction_ids_.empty()); + int id = transaction_ids_.front(); + transaction_ids_.pop_front(); + EXPECT_GE(id, min); + EXPECT_LE(id, max); + return id; + } + + DnsConfig config_; + + std::vector> socket_data_; + + base::circular_deque transaction_ids_; + std::unique_ptr socket_factory_; + std::unique_ptr request_context_; + std::unique_ptr resolve_context_; + scoped_refptr session_; + std::unique_ptr transaction_factory_; + ResponseModifierCallback response_modifier_; + DohJobMakerCallback doh_job_maker_; + + // Whether multiple IsolationInfos should be expected (due to there being + // multiple RequestContexts in use). + bool expect_multiple_isolation_infos_ = false; + + // IsolationInfo used by DoH requests. Populated on first DoH request, and + // compared to IsolationInfo used by all subsequent requests, unless + // |expect_multiple_isolation_infos_| is true. + std::unique_ptr isolation_info_; +}; + +static const char kTestCryptoHostName[] = "test.crypto"; + +// Response contains IP address: 142.250.72.196 for test.crypto. +static const uint8_t kTestCryptoResponseDatagram[] = { + 0x00, 0x00, 0x81, 0x80, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x74, 0x65, 0x73, 0x74, 0x06, 0x63, 0x72, 0x79, 0x70, 0x74, 0x6f, + 0x00, 0x00, 0x01, 0x00, 0x01, 0xc0, 0x0c, 0x00, 0x01, 0x00, 0x01, 0x00, + 0x00, 0x00, 0xa2, 0x00, 0x04, 0x8e, 0xfa, 0x48, 0xc4}; + +class BraveDnsTransactionTest : public DnsTransactionTestBase, + public WithTaskEnvironment { + public: + BraveDnsTransactionTest() = default; + + ~BraveDnsTransactionTest() override = default; + + void BraveConfigureDohServers(bool multiple_server) { + GURL url(unstoppable_domains::kDoHResolver); + URLRequestFilter* filter = URLRequestFilter::GetInstance(); + filter->AddHostnameInterceptor(url.scheme(), url.host(), + std::make_unique(this)); + config_.dns_over_https_servers.push_back( + {unstoppable_domains::kDoHResolver, true}); + + if (multiple_server) { + GURL url2("https://test.com/dns-query"); + filter->AddHostnameInterceptor(url2.scheme(), url2.host(), + std::make_unique(this)); + config_.dns_over_https_servers.push_back({url2.spec(), true}); + } + + ConfigureFactory(); + for (size_t server_index = 0; + server_index < config_.dns_over_https_servers.size(); ++server_index) { + resolve_context_->RecordServerSuccess( + server_index, true /* is_doh_server */, session_.get()); + } + } +}; + +TEST_F(BraveDnsTransactionTest, SkipUDResolverForNonCryptoDomainsSingleServer) { + BraveConfigureDohServers(false); + EXPECT_TRUE(resolve_context_->GetDohServerAvailability( + 0u /* doh_server_index */, session_.get())); + TransactionHelper helper0(ERR_BLOCKED_BY_CLIENT); + helper0.StartTransaction(transaction_factory_.get(), kT0HostName, kT0Qtype, + true /* secure */, resolve_context_.get()); + helper0.RunUntilComplete(); +} + +TEST_F(BraveDnsTransactionTest, + SkipUDResolverForNonCryptoDomainsMultipleServers) { + BraveConfigureDohServers(true); + AddQueryAndResponse(0, kT0HostName, kT0Qtype, kT0ResponseDatagram, + base::size(kT0ResponseDatagram), SYNCHRONOUS, + Transport::HTTPS, nullptr /* opt_rdata */, + DnsQuery::PaddingStrategy::BLOCK_LENGTH_128, + false /* enqueue_transaction_id */); + TransactionHelper helper0(kT0RecordCount); + helper0.StartTransaction(transaction_factory_.get(), kT0HostName, kT0Qtype, + true /* secure */, resolve_context_.get()); + helper0.RunUntilComplete(); +} + +TEST_F(BraveDnsTransactionTest, UseUDResolverForCryptoDomainsSingleServer) { + BraveConfigureDohServers(false); + AddQueryAndResponse( + 0, kTestCryptoHostName, dns_protocol::kTypeA, kTestCryptoResponseDatagram, + base::size(kTestCryptoResponseDatagram), SYNCHRONOUS, Transport::HTTPS, + nullptr /* opt_rdata */, DnsQuery::PaddingStrategy::BLOCK_LENGTH_128, + false /* enqueue_transaction_id */); + TransactionHelper helper0(1); + helper0.StartTransaction(transaction_factory_.get(), kTestCryptoHostName, + dns_protocol::kTypeA, true /* secure */, + resolve_context_.get()); + helper0.RunUntilComplete(); +} + +TEST_F(BraveDnsTransactionTest, UseUDResolverForCryptoDomainsMultipleServer) { + BraveConfigureDohServers(true); + AddQueryAndResponse( + 0, kTestCryptoHostName, dns_protocol::kTypeA, kTestCryptoResponseDatagram, + base::size(kTestCryptoResponseDatagram), SYNCHRONOUS, Transport::HTTPS, + nullptr /* opt_rdata */, DnsQuery::PaddingStrategy::BLOCK_LENGTH_128, + false /* enqueue_transaction_id */); + TransactionHelper helper0(1); + helper0.StartTransaction(transaction_factory_.get(), kTestCryptoHostName, + dns_protocol::kTypeA, true /* secure */, + resolve_context_.get()); + helper0.RunUntilComplete(); +} + +} // namespace + +} // namespace net diff --git a/net/dns/sources.gni b/net/dns/sources.gni new file mode 100644 index 000000000000..8d6c6c53bbf1 --- /dev/null +++ b/net/dns/sources.gni @@ -0,0 +1,6 @@ +# Copyright (c) 2021 The Brave Authors. All rights reserved. +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this file, +# You can obtain one at http://mozilla.org/MPL/2.0/. + +brave_dns_friend = [ "//brave/browser/unstoppable_domains/test:unit_tests" ] diff --git a/net/sources.gni b/net/sources.gni index 784143f6efc1..13dd035d6a1e 100644 --- a/net/sources.gni +++ b/net/sources.gni @@ -3,7 +3,10 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this file, # You can obtain one at http://mozilla.org/MPL/2.0/. +import("//brave/components/unstoppable_domains/buildflags/buildflags.gni") + brave_net_sources = [ "//brave/net/proxy_resolution/proxy_config_service_tor.cc", "//brave/net/proxy_resolution/proxy_config_service_tor.h", + "//brave/net/unstoppable_domains/constants.h", ] diff --git a/net/unstoppable_domains/constants.h b/net/unstoppable_domains/constants.h new file mode 100644 index 000000000000..f4ab9c7d6e5b --- /dev/null +++ b/net/unstoppable_domains/constants.h @@ -0,0 +1,17 @@ +/* Copyright (c) 2021 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef BRAVE_NET_UNSTOPPABLE_DOMAINS_CONSTANTS_H_ +#define BRAVE_NET_UNSTOPPABLE_DOMAINS_CONSTANTS_H_ + +namespace unstoppable_domains { + +constexpr char kCryptoDomain[] = ".crypto"; +constexpr char kDoHResolver[] = + "https://resolver.unstoppable.io/dns-query{?brave_UD}"; + +} // namespace unstoppable_domains + +#endif // BRAVE_NET_UNSTOPPABLE_DOMAINS_CONSTANTS_H_ diff --git a/patches/chrome-browser-net-stub_resolver_config_reader.cc.patch b/patches/chrome-browser-net-stub_resolver_config_reader.cc.patch new file mode 100644 index 000000000000..5310997be15a --- /dev/null +++ b/patches/chrome-browser-net-stub_resolver_config_reader.cc.patch @@ -0,0 +1,12 @@ +diff --git a/chrome/browser/net/stub_resolver_config_reader.cc b/chrome/browser/net/stub_resolver_config_reader.cc +index 677f6c50fc602a1c5ba6ca52f4ea6496d7d60e7f..d736b6e06fcbee8fb17e3397cee86f3dbe09ad8e 100644 +--- a/chrome/browser/net/stub_resolver_config_reader.cc ++++ b/chrome/browser/net/stub_resolver_config_reader.cc +@@ -353,6 +353,7 @@ SecureDnsConfig StubResolverConfigReader::GetAndUpdateConfiguration( + + std::string doh_templates = + local_state_->GetString(prefs::kDnsOverHttpsTemplates); ++ BRAVE_GET_AND_UPDATE_CONFIGURATION + std::string server_method; + std::vector dns_over_https_servers; + base::Optional> diff --git a/patches/net-dns-BUILD.gn.patch b/patches/net-dns-BUILD.gn.patch new file mode 100644 index 000000000000..96ddf7568861 --- /dev/null +++ b/patches/net-dns-BUILD.gn.patch @@ -0,0 +1,28 @@ +diff --git a/net/dns/BUILD.gn b/net/dns/BUILD.gn +index ea7c29d285af754ee3c1ca0537645b05602d55f4..90a40ae96ca2de9048eab86fd2f45e3e3555b6b4 100644 +--- a/net/dns/BUILD.gn ++++ b/net/dns/BUILD.gn +@@ -23,6 +23,7 @@ source_set("dns") { + "//net/*", + "//services/network/*", + ] ++ friend += brave_dns_friend + + public = [] + sources = [ +@@ -205,6 +206,7 @@ source_set("host_resolver") { + # wrapper. + "//services/proxy_resolver/*", + ] ++ friend += brave_dns_friend + + sources = [] + public = [] +@@ -309,6 +311,7 @@ source_set("dns_client") { + "//net/*", + "//services/network/*", + ] ++ friend += brave_dns_friend + + sources = [] + public = [] diff --git a/patches/net-dns-dns_transaction.cc.patch b/patches/net-dns-dns_transaction.cc.patch new file mode 100644 index 000000000000..db1e6f6f25a2 --- /dev/null +++ b/patches/net-dns-dns_transaction.cc.patch @@ -0,0 +1,12 @@ +diff --git a/net/dns/dns_transaction.cc b/net/dns/dns_transaction.cc +index 9bfd4cace384ca502716efa191eaa6ccfd6a54a8..9123e8cb94b566ef1a25cbc498dfc859e4165e73 100644 +--- a/net/dns/dns_transaction.cc ++++ b/net/dns/dns_transaction.cc +@@ -1299,6 +1299,7 @@ class DnsTransactionImpl : public DnsTransaction, + DCHECK(secure_); + + size_t doh_server_index = dns_server_iterator_->GetNextAttemptIndex(); ++ BRAVE_MAKE_HTTP_ATTEMPT + + unsigned attempt_number = attempts_.size(); + ConstructDnsHTTPAttempt( diff --git a/test/BUILD.gn b/test/BUILD.gn index 7caa755ba07f..d2f87ca914a3 100644 --- a/test/BUILD.gn +++ b/test/BUILD.gn @@ -17,6 +17,7 @@ import("//brave/components/greaselion/browser/buildflags/buildflags.gni") import("//brave/components/ipfs/buildflags/buildflags.gni") import("//brave/components/speedreader/buildflags.gni") import("//brave/components/tor/buildflags/buildflags.gni") +import("//brave/components/unstoppable_domains/buildflags/buildflags.gni") import("//brave/test/testing.gni") import("//chrome/common/features.gni") import("//components/gcm_driver/config.gni") @@ -199,6 +200,10 @@ test("brave_unit_tests") { "//services/preferences/public/cpp", ] + if (unstoppable_domains_enabled) { + deps += [ "//brave/browser/unstoppable_domains/test:unit_tests" ] + } + if (toolkit_views) { deps += [ "//chrome/browser/ui/views" ] } @@ -628,6 +633,10 @@ if (!is_android) { "//testing/gmock", ] + if (unstoppable_domains_enabled) { + deps += [ "//brave/browser/unstoppable_domains/test:browser_tests" ] + } + if (enable_brave_perf_predictor) { sources += [ "//brave/components/brave_perf_predictor/browser/perf_predictor_tab_helper_browsertest.cc" ] From 433c702abf7815756cec6009944952b6d98142b2 Mon Sep 17 00:00:00 2001 From: "Brian R. Bondy" Date: Fri, 5 Mar 2021 22:34:33 -0500 Subject: [PATCH 2/6] Merge pull request #8125 from brave/ens_support_rebase Add ENS support --- app/brave_generated_resources.grd | 3 + browser/BUILD.gn | 8 +- browser/brave_content_browser_client.cc | 18 ++-- browser/brave_local_state_prefs.cc | 11 +- .../BUILD.gn | 14 +-- ...ecentralized_dns_service_delegate_impl.cc} | 8 +- .../decentralized_dns_service_delegate_impl.h | 29 +++++ .../decentralized_dns_service_factory.cc | 48 +++++++++ .../decentralized_dns_service_factory.h | 41 +++++++ .../test/BUILD.gn | 10 +- ...ed_dns_navigation_throttle_browsertest.cc} | 82 ++++++++++---- .../decentralized_dns_service_browsertest.cc} | 68 ++++++++---- .../decentralized_dns/test/utils_unittest.cc | 101 ++++++++++++++++++ browser/extensions/BUILD.gn | 8 +- .../api/settings_private/brave_prefs_util.cc | 13 +-- browser/profiles/BUILD.gn | 2 +- browser/profiles/brave_profile_manager.cc | 10 +- .../brave_default_extensions_browser_proxy.js | 4 +- .../brave_default_extensions_page.html | 8 +- .../brave_default_extensions_page.js | 17 ++- browser/ui/BUILD.gn | 8 +- .../brave_default_extensions_handler.cc | 16 +-- .../brave_default_extensions_handler.h | 2 +- .../test/utils_unittest.cc | 73 ------------- ...nstoppable_domains_service_delegate_impl.h | 29 ----- .../unstoppable_domains_service_factory.cc | 49 --------- .../unstoppable_domains_service_factory.h | 41 ------- chromium_src/chrome/browser/about_flags.cc | 20 ++-- .../chrome/browser/flag_descriptions.cc | 7 +- .../chrome/browser/flag_descriptions.h | 4 +- .../net/stub_resolver_config_reader.cc | 41 +++---- .../settings_localized_strings_provider.cc | 1 + .../net/base/lookup_string_in_fixed_set.cc | 16 +-- chromium_src/net/dns/dns_transaction.cc | 15 ++- .../BUILD.gn | 20 ++-- .../DEPS | 0 .../decentralized_dns/buildflags/BUILD.gn | 7 ++ .../buildflags/buildflags.gni | 3 + .../constants.h | 10 +- ...zed_dns_interstitial_controller_client.cc} | 30 +++--- ...ized_dns_interstitial_controller_client.h} | 24 ++--- .../decentralized_dns_navigation_throttle.cc} | 52 ++++----- .../decentralized_dns_navigation_throttle.h} | 29 +++-- .../decentralized_dns_opt_in_page.cc} | 77 +++++++------ .../decentralized_dns_opt_in_page.h} | 23 ++-- .../decentralized_dns_service.cc | 51 +++++++++ .../decentralized_dns_service.h | 47 ++++++++ .../decentralized_dns_service_delegate.h | 20 ++++ components/decentralized_dns/features.h | 20 ++++ components/decentralized_dns/pref_names.h | 28 +++++ .../decentralized_dns_interstitial.css} | 0 .../decentralized_dns_interstitial.html} | 4 +- .../decentralized_dns_interstitial.js} | 2 +- components/decentralized_dns/utils.cc | 67 ++++++++++++ components/decentralized_dns/utils.h | 26 +++++ components/resources/BUILD.gn | 6 +- .../resources/brave_components_resources.grd | 2 +- .../resources/brave_components_strings.grd | 2 +- .../decentralized_dns_resources.grdp | 8 ++ .../resources/decentralized_dns_strings.grdp | 29 +++++ .../unstoppable_domains_resources.grdp | 8 -- .../unstoppable_domains_strings.grdp | 20 ---- .../unstoppable_domains/buildflags/BUILD.gn | 7 -- .../buildflags/buildflags.gni | 3 - components/unstoppable_domains/features.h | 20 ---- components/unstoppable_domains/pref_names.h | 20 ---- .../unstoppable_domains_service.cc | 45 -------- .../unstoppable_domains_service.h | 48 --------- .../unstoppable_domains_service_delegate.h | 20 ---- components/unstoppable_domains/utils.cc | 45 -------- components/unstoppable_domains/utils.h | 21 ---- net/decentralized_dns/constants.h | 21 ++++ net/dns/dns_transaction_unittest.cc | 73 ++++++++++--- net/dns/sources.gni | 2 +- net/sources.gni | 4 +- net/unstoppable_domains/constants.h | 17 --- test/BUILD.gn | 10 +- 77 files changed, 1022 insertions(+), 774 deletions(-) rename browser/{unstoppable_domains => decentralized_dns}/BUILD.gn (68%) rename browser/{unstoppable_domains/unstoppable_domains_service_delegate_impl.cc => decentralized_dns/decentralized_dns_service_delegate_impl.cc} (71%) create mode 100644 browser/decentralized_dns/decentralized_dns_service_delegate_impl.h create mode 100644 browser/decentralized_dns/decentralized_dns_service_factory.cc create mode 100644 browser/decentralized_dns/decentralized_dns_service_factory.h rename browser/{unstoppable_domains => decentralized_dns}/test/BUILD.gn (76%) rename browser/{unstoppable_domains/test/unstoppable_domains_navigation_throttle_browsertest.cc => decentralized_dns/test/decentralized_dns_navigation_throttle_browsertest.cc} (55%) rename browser/{unstoppable_domains/test/unstoppable_domains_service_browsertest.cc => decentralized_dns/test/decentralized_dns_service_browsertest.cc} (62%) create mode 100644 browser/decentralized_dns/test/utils_unittest.cc delete mode 100644 browser/unstoppable_domains/test/utils_unittest.cc delete mode 100644 browser/unstoppable_domains/unstoppable_domains_service_delegate_impl.h delete mode 100644 browser/unstoppable_domains/unstoppable_domains_service_factory.cc delete mode 100644 browser/unstoppable_domains/unstoppable_domains_service_factory.h rename components/{unstoppable_domains => decentralized_dns}/BUILD.gn (62%) rename components/{unstoppable_domains => decentralized_dns}/DEPS (100%) create mode 100644 components/decentralized_dns/buildflags/BUILD.gn create mode 100644 components/decentralized_dns/buildflags/buildflags.gni rename components/{unstoppable_domains => decentralized_dns}/constants.h (58%) rename components/{unstoppable_domains/unstoppable_domains_interstitial_controller_client.cc => decentralized_dns/decentralized_dns_interstitial_controller_client.cc} (59%) rename components/{unstoppable_domains/unstoppable_domains_interstitial_controller_client.h => decentralized_dns/decentralized_dns_interstitial_controller_client.h} (60%) rename components/{unstoppable_domains/unstoppable_domains_navigation_throttle.cc => decentralized_dns/decentralized_dns_navigation_throttle.cc} (58%) rename components/{unstoppable_domains/unstoppable_domains_navigation_throttle.h => decentralized_dns/decentralized_dns_navigation_throttle.h} (55%) rename components/{unstoppable_domains/unstoppable_domains_opt_in_page.cc => decentralized_dns/decentralized_dns_opt_in_page.cc} (54%) rename components/{unstoppable_domains/unstoppable_domains_opt_in_page.h => decentralized_dns/decentralized_dns_opt_in_page.h} (70%) create mode 100644 components/decentralized_dns/decentralized_dns_service.cc create mode 100644 components/decentralized_dns/decentralized_dns_service.h create mode 100644 components/decentralized_dns/decentralized_dns_service_delegate.h create mode 100644 components/decentralized_dns/features.h create mode 100644 components/decentralized_dns/pref_names.h rename components/{unstoppable_domains/resources/unstoppable_domains_interstitial.css => decentralized_dns/resources/decentralized_dns_interstitial.css} (100%) rename components/{unstoppable_domains/resources/unstoppable_domains_interstitial.html => decentralized_dns/resources/decentralized_dns_interstitial.html} (90%) rename components/{unstoppable_domains/resources/unstoppable_domains_interstitial.js => decentralized_dns/resources/decentralized_dns_interstitial.js} (93%) create mode 100644 components/decentralized_dns/utils.cc create mode 100644 components/decentralized_dns/utils.h create mode 100644 components/resources/decentralized_dns_resources.grdp create mode 100644 components/resources/decentralized_dns_strings.grdp delete mode 100644 components/resources/unstoppable_domains_resources.grdp delete mode 100644 components/resources/unstoppable_domains_strings.grdp delete mode 100644 components/unstoppable_domains/buildflags/BUILD.gn delete mode 100644 components/unstoppable_domains/buildflags/buildflags.gni delete mode 100644 components/unstoppable_domains/features.h delete mode 100644 components/unstoppable_domains/pref_names.h delete mode 100644 components/unstoppable_domains/unstoppable_domains_service.cc delete mode 100644 components/unstoppable_domains/unstoppable_domains_service.h delete mode 100644 components/unstoppable_domains/unstoppable_domains_service_delegate.h delete mode 100644 components/unstoppable_domains/utils.cc delete mode 100644 components/unstoppable_domains/utils.h create mode 100644 net/decentralized_dns/constants.h delete mode 100644 net/unstoppable_domains/constants.h diff --git a/app/brave_generated_resources.grd b/app/brave_generated_resources.grd index 10d6f8da5a36..95ea5fbb94db 100644 --- a/app/brave_generated_resources.grd +++ b/app/brave_generated_resources.grd @@ -697,6 +697,9 @@ By installing this extension, you are agreeing to the Google Widevine Terms of U Method to resolve Unstoppable Domains + + Method to resolve Ethereum Name Service (ENS) + Method to resolve IPFS resources diff --git a/browser/BUILD.gn b/browser/BUILD.gn index edc79926ebe1..c94f107e8a45 100644 --- a/browser/BUILD.gn +++ b/browser/BUILD.gn @@ -10,13 +10,13 @@ import("//brave/components/brave_wallet/buildflags/buildflags.gni") import("//brave/components/brave_wayback_machine/buildflags/buildflags.gni") import("//brave/components/brave_webtorrent/browser/buildflags/buildflags.gni") import("//brave/components/crypto_dot_com/browser/buildflags/buildflags.gni") +import("//brave/components/decentralized_dns/buildflags/buildflags.gni") import("//brave/components/gemini/browser/buildflags/buildflags.gni") import("//brave/components/greaselion/browser/buildflags/buildflags.gni") import("//brave/components/ipfs/buildflags/buildflags.gni") import("//brave/components/sidebar/buildflags/buildflags.gni") import("//brave/components/speedreader/buildflags.gni") import("//brave/components/tor/buildflags/buildflags.gni") -import("//brave/components/unstoppable_domains/buildflags/buildflags.gni") import("//build/buildflag_header.gni") import("//build/config/features.gni") import("//chrome/common/features.gni") @@ -144,6 +144,7 @@ source_set("browser_process") { "//brave/components/cosmetic_filters/browser", "//brave/components/cosmetic_filters/common:mojom", "//brave/components/crypto_dot_com/browser/buildflags", + "//brave/components/decentralized_dns/buildflags", "//brave/components/gemini/browser/buildflags", "//brave/components/greaselion/browser/buildflags", "//brave/components/ipfs/buildflags", @@ -155,7 +156,6 @@ source_set("browser_process") { "//brave/components/sidebar/buildflags", "//brave/components/speedreader:buildflags", "//brave/components/tor/buildflags", - "//brave/components/unstoppable_domains/buildflags", "//brave/components/weekly_storage", "//brave/services/network/public/cpp", "//brave/ui/brave_ads", @@ -291,8 +291,8 @@ source_set("browser_process") { ] } - if (unstoppable_domains_enabled) { - deps += [ "//brave/browser/unstoppable_domains" ] + if (decentralized_dns_enabled) { + deps += [ "//brave/browser/decentralized_dns" ] } if (ipfs_enabled) { diff --git a/browser/brave_content_browser_client.cc b/browser/brave_content_browser_client.cc index 8fec950fb4f6..855418837964 100644 --- a/browser/brave_content_browser_client.cc +++ b/browser/brave_content_browser_client.cc @@ -31,11 +31,11 @@ #include "brave/components/brave_webtorrent/browser/buildflags/buildflags.h" #include "brave/components/cosmetic_filters/browser/cosmetic_filters_resources.h" #include "brave/components/cosmetic_filters/common/cosmetic_filters.mojom.h" +#include "brave/components/decentralized_dns/buildflags/buildflags.h" #include "brave/components/gemini/browser/buildflags/buildflags.h" #include "brave/components/ipfs/buildflags/buildflags.h" #include "brave/components/speedreader/buildflags.h" #include "brave/components/tor/buildflags/buildflags.h" -#include "brave/components/unstoppable_domains/buildflags/buildflags.h" #include "brave/grit/brave_generated_resources.h" #include "chrome/browser/chrome_content_browser_client.h" #include "chrome/browser/content_settings/host_content_settings_map_factory.h" @@ -89,8 +89,8 @@ using extensions::ChromeContentBrowserClientExtensionsPart; #include "brave/components/ipfs/ipfs_navigation_throttle.h" #endif -#if BUILDFLAG(UNSTOPPABLE_DOMAINS_ENABLED) -#include "brave/components/unstoppable_domains/unstoppable_domains_navigation_throttle.h" +#if BUILDFLAG(DECENTRALIZED_DNS_ENABLED) +#include "brave/components/decentralized_dns/decentralized_dns_navigation_throttle.h" #endif #if BUILDFLAG(BRAVE_REWARDS_ENABLED) @@ -591,7 +591,7 @@ BraveContentBrowserClient::CreateThrottlesForNavigation( #endif #if BUILDFLAG(ENABLE_TOR) || BUILDFLAG(IPFS_ENABLED) || \ - BUILDFLAG(UNSTOPPABLE_DOMAINS_ENABLED) + BUILDFLAG(DECENTRALIZED_DNS_ENABLED) content::BrowserContext* context = handle->GetWebContents()->GetBrowserContext(); #endif @@ -624,14 +624,14 @@ BraveContentBrowserClient::CreateThrottlesForNavigation( throttles.push_back(std::move(ipfs_navigation_throttle)); #endif -#if BUILDFLAG(UNSTOPPABLE_DOMAINS_ENABLED) +#if BUILDFLAG(DECENTRALIZED_DNS_ENABLED) std::unique_ptr - unstoppable_domains_navigation_throttle = unstoppable_domains:: - UnstoppableDomainsNavigationThrottle::MaybeCreateThrottleFor( + decentralized_dns_navigation_throttle = decentralized_dns:: + DecentralizedDnsNavigationThrottle::MaybeCreateThrottleFor( handle, g_brave_browser_process->local_state(), g_brave_browser_process->GetApplicationLocale()); - if (unstoppable_domains_navigation_throttle) - throttles.push_back(std::move(unstoppable_domains_navigation_throttle)); + if (decentralized_dns_navigation_throttle) + throttles.push_back(std::move(decentralized_dns_navigation_throttle)); #endif return throttles; diff --git a/browser/brave_local_state_prefs.cc b/browser/brave_local_state_prefs.cc index 667ee1120ca0..fc13fd2a091a 100644 --- a/browser/brave_local_state_prefs.cc +++ b/browser/brave_local_state_prefs.cc @@ -13,12 +13,12 @@ #include "brave/components/brave_referrals/buildflags/buildflags.h" #include "brave/components/brave_shields/browser/ad_block_service.h" #include "brave/components/brave_shields/browser/brave_shields_p3a.h" +#include "brave/components/decentralized_dns/buildflags/buildflags.h" #include "brave/components/ntp_background_images/browser/ntp_background_images_service.h" #include "brave/components/ntp_background_images/browser/view_counter_service.h" #include "brave/components/p3a/brave_p3a_service.h" #include "brave/components/p3a/buildflags.h" #include "brave/components/tor/buildflags/buildflags.h" -#include "brave/components/unstoppable_domains/buildflags/buildflags.h" #include "chrome/common/pref_names.h" #include "components/metrics/metrics_pref_names.h" #include "components/prefs/pref_registry_simple.h" @@ -43,8 +43,8 @@ #include "brave/browser/widevine/widevine_utils.h" #endif -#if BUILDFLAG(UNSTOPPABLE_DOMAINS_ENABLED) -#include "brave/components/unstoppable_domains/unstoppable_domains_service.h" +#if BUILDFLAG(DECENTRALIZED_DNS_ENABLED) +#include "brave/components/decentralized_dns/decentralized_dns_service.h" #endif namespace brave { @@ -100,9 +100,8 @@ void RegisterLocalStatePrefs(PrefRegistrySimple* registry) { RegisterWidevineLocalstatePrefs(registry); #endif -#if BUILDFLAG(UNSTOPPABLE_DOMAINS_ENABLED) - unstoppable_domains::UnstoppableDomainsService::RegisterLocalStatePrefs( - registry); +#if BUILDFLAG(DECENTRALIZED_DNS_ENABLED) + decentralized_dns::DecentralizedDnsService::RegisterLocalStatePrefs(registry); #endif RegisterLocalStatePrefsForMigration(registry); diff --git a/browser/unstoppable_domains/BUILD.gn b/browser/decentralized_dns/BUILD.gn similarity index 68% rename from browser/unstoppable_domains/BUILD.gn rename to browser/decentralized_dns/BUILD.gn index b9f021060bd4..7d10824d3657 100644 --- a/browser/unstoppable_domains/BUILD.gn +++ b/browser/decentralized_dns/BUILD.gn @@ -3,23 +3,23 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this file, # You can obtain one at http://mozilla.org/MPL/2.0/. */ -source_set("unstoppable_domains") { +source_set("decentralized_dns") { # See https://github.com/brave/brave-browser/issues/14441 check_includes = false sources = [ - "unstoppable_domains_service_delegate_impl.cc", - "unstoppable_domains_service_delegate_impl.h", - "unstoppable_domains_service_factory.cc", - "unstoppable_domains_service_factory.h", + "decentralized_dns_service_delegate_impl.cc", + "decentralized_dns_service_delegate_impl.h", + "decentralized_dns_service_factory.cc", + "decentralized_dns_service_factory.h", ] deps = [ - "//brave/components/unstoppable_domains", + "//brave/components/decentralized_dns", "//components/keyed_service/content", ] - # Below deps are not directly used by unstoppable_domains target. + # Below deps are not directly used by decentralized_dns target. # This is added due to our include of # `chrome/browser/net/system_network_context_manager.h` without adding # //chrome/browser into deps to avoid circulate dependency. Without this, diff --git a/browser/unstoppable_domains/unstoppable_domains_service_delegate_impl.cc b/browser/decentralized_dns/decentralized_dns_service_delegate_impl.cc similarity index 71% rename from browser/unstoppable_domains/unstoppable_domains_service_delegate_impl.cc rename to browser/decentralized_dns/decentralized_dns_service_delegate_impl.cc index 48081e701575..0cf08f331e8c 100644 --- a/browser/unstoppable_domains/unstoppable_domains_service_delegate_impl.cc +++ b/browser/decentralized_dns/decentralized_dns_service_delegate_impl.cc @@ -3,17 +3,17 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include "brave/browser/unstoppable_domains/unstoppable_domains_service_delegate_impl.h" +#include "brave/browser/decentralized_dns/decentralized_dns_service_delegate_impl.h" #include "chrome/browser/net/stub_resolver_config_reader.h" #include "chrome/browser/net/system_network_context_manager.h" -namespace unstoppable_domains { +namespace decentralized_dns { -void UnstoppableDomainsServiceDelegateImpl::UpdateNetworkService() { +void DecentralizedDnsServiceDelegateImpl::UpdateNetworkService() { // Trigger a DoH config update in network service. SystemNetworkContextManager::GetStubResolverConfigReader() ->UpdateNetworkService(false /* record_metrics */); } -} // namespace unstoppable_domains +} // namespace decentralized_dns diff --git a/browser/decentralized_dns/decentralized_dns_service_delegate_impl.h b/browser/decentralized_dns/decentralized_dns_service_delegate_impl.h new file mode 100644 index 000000000000..f1cddfb1c4e5 --- /dev/null +++ b/browser/decentralized_dns/decentralized_dns_service_delegate_impl.h @@ -0,0 +1,29 @@ +/* Copyright (c) 2021 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef BRAVE_BROWSER_DECENTRALIZED_DNS_DECENTRALIZED_DNS_SERVICE_DELEGATE_IMPL_H_ +#define BRAVE_BROWSER_DECENTRALIZED_DNS_DECENTRALIZED_DNS_SERVICE_DELEGATE_IMPL_H_ + +#include "brave/components/decentralized_dns/decentralized_dns_service_delegate.h" + +namespace decentralized_dns { + +class DecentralizedDnsServiceDelegateImpl + : public DecentralizedDnsServiceDelegate { + public: + DecentralizedDnsServiceDelegateImpl() = default; + ~DecentralizedDnsServiceDelegateImpl() override = default; + + DecentralizedDnsServiceDelegateImpl( + const DecentralizedDnsServiceDelegateImpl&) = delete; + DecentralizedDnsServiceDelegateImpl& operator=( + DecentralizedDnsServiceDelegateImpl&) = delete; + + void UpdateNetworkService() override; +}; + +} // namespace decentralized_dns + +#endif // BRAVE_BROWSER_DECENTRALIZED_DNS_DECENTRALIZED_DNS_SERVICE_DELEGATE_IMPL_H_ diff --git a/browser/decentralized_dns/decentralized_dns_service_factory.cc b/browser/decentralized_dns/decentralized_dns_service_factory.cc new file mode 100644 index 000000000000..d26b936352d8 --- /dev/null +++ b/browser/decentralized_dns/decentralized_dns_service_factory.cc @@ -0,0 +1,48 @@ +/* Copyright (c) 2021 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "brave/browser/decentralized_dns/decentralized_dns_service_factory.h" + +#include + +#include "brave/browser/brave_browser_process_impl.h" +#include "brave/browser/decentralized_dns/decentralized_dns_service_delegate_impl.h" +#include "brave/components/decentralized_dns/decentralized_dns_service.h" +#include "brave/components/decentralized_dns/utils.h" +#include "components/keyed_service/content/browser_context_dependency_manager.h" + +namespace decentralized_dns { + +DecentralizedDnsServiceFactory::DecentralizedDnsServiceFactory() + : BrowserContextKeyedServiceFactory( + "DecentralizedDnsService", + BrowserContextDependencyManager::GetInstance()) {} + +DecentralizedDnsServiceFactory::~DecentralizedDnsServiceFactory() {} + +// static +DecentralizedDnsServiceFactory* DecentralizedDnsServiceFactory::GetInstance() { + return base::Singleton::get(); +} + +// static +DecentralizedDnsService* DecentralizedDnsServiceFactory::GetForContext( + content::BrowserContext* context) { + if (!IsDecentralizedDnsEnabled()) + return nullptr; + + return static_cast( + GetInstance()->GetServiceForBrowserContext(context, true)); +} + +KeyedService* DecentralizedDnsServiceFactory::BuildServiceInstanceFor( + content::BrowserContext* context) const { + return new DecentralizedDnsService( + std::make_unique(), context, + g_brave_browser_process ? g_brave_browser_process->local_state() + : nullptr); +} + +} // namespace decentralized_dns diff --git a/browser/decentralized_dns/decentralized_dns_service_factory.h b/browser/decentralized_dns/decentralized_dns_service_factory.h new file mode 100644 index 000000000000..45f41dc36da3 --- /dev/null +++ b/browser/decentralized_dns/decentralized_dns_service_factory.h @@ -0,0 +1,41 @@ +/* Copyright (c) 2021 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef BRAVE_BROWSER_DECENTRALIZED_DNS_DECENTRALIZED_DNS_SERVICE_FACTORY_H_ +#define BRAVE_BROWSER_DECENTRALIZED_DNS_DECENTRALIZED_DNS_SERVICE_FACTORY_H_ + +#include "base/memory/singleton.h" +#include "components/keyed_service/content/browser_context_keyed_service_factory.h" + +namespace decentralized_dns { + +class DecentralizedDnsService; + +class DecentralizedDnsServiceFactory + : public BrowserContextKeyedServiceFactory { + public: + static DecentralizedDnsService* GetForContext( + content::BrowserContext* context); + static DecentralizedDnsServiceFactory* GetInstance(); + + private: + friend struct base::DefaultSingletonTraits; + + DecentralizedDnsServiceFactory(); + ~DecentralizedDnsServiceFactory() override; + + DecentralizedDnsServiceFactory(const DecentralizedDnsServiceFactory&) = + delete; + DecentralizedDnsServiceFactory& operator=( + const DecentralizedDnsServiceFactory&) = delete; + + // BrowserContextKeyedServiceFactory overrides: + KeyedService* BuildServiceInstanceFor( + content::BrowserContext* context) const override; +}; + +} // namespace decentralized_dns + +#endif // BRAVE_BROWSER_DECENTRALIZED_DNS_DECENTRALIZED_DNS_SERVICE_FACTORY_H_ diff --git a/browser/unstoppable_domains/test/BUILD.gn b/browser/decentralized_dns/test/BUILD.gn similarity index 76% rename from browser/unstoppable_domains/test/BUILD.gn rename to browser/decentralized_dns/test/BUILD.gn index ff577f9c6097..32f4550ec48a 100644 --- a/browser/unstoppable_domains/test/BUILD.gn +++ b/browser/decentralized_dns/test/BUILD.gn @@ -10,12 +10,12 @@ source_set("browser_tests") { testonly = true defines = [ "HAS_OUT_OF_PROC_TEST_RUNNER" ] sources = [ - "//brave/browser/unstoppable_domains/test/unstoppable_domains_navigation_throttle_browsertest.cc", - "//brave/browser/unstoppable_domains/test/unstoppable_domains_service_browsertest.cc", + "//brave/browser/decentralized_dns/test/decentralized_dns_navigation_throttle_browsertest.cc", + "//brave/browser/decentralized_dns/test/decentralized_dns_service_browsertest.cc", ] deps = [ "//base/test:test_support", - "//brave/components/unstoppable_domains", + "//brave/components/decentralized_dns", "//chrome/browser:browser_process", "//chrome/test:test_support", "//chrome/test:test_support_ui", @@ -29,14 +29,14 @@ source_set("browser_tests") { source_set("unit_tests") { testonly = true sources = [ - "//brave/browser/unstoppable_domains/test/utils_unittest.cc", + "//brave/browser/decentralized_dns/test/utils_unittest.cc", "//brave/net/dns/dns_transaction_unittest.cc", ] deps = [ "//base", "//base/test:test_support", - "//brave/components/unstoppable_domains", + "//brave/components/decentralized_dns", "//chrome/test:test_support", "//components/prefs", "//net", diff --git a/browser/unstoppable_domains/test/unstoppable_domains_navigation_throttle_browsertest.cc b/browser/decentralized_dns/test/decentralized_dns_navigation_throttle_browsertest.cc similarity index 55% rename from browser/unstoppable_domains/test/unstoppable_domains_navigation_throttle_browsertest.cc rename to browser/decentralized_dns/test/decentralized_dns_navigation_throttle_browsertest.cc index e08a415aebee..6187d19c7f23 100644 --- a/browser/unstoppable_domains/test/unstoppable_domains_navigation_throttle_browsertest.cc +++ b/browser/decentralized_dns/test/decentralized_dns_navigation_throttle_browsertest.cc @@ -4,10 +4,10 @@ * You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "base/test/scoped_feature_list.h" -#include "brave/components/unstoppable_domains/constants.h" -#include "brave/components/unstoppable_domains/features.h" -#include "brave/components/unstoppable_domains/pref_names.h" -#include "brave/components/unstoppable_domains/unstoppable_domains_opt_in_page.h" +#include "brave/components/decentralized_dns/constants.h" +#include "brave/components/decentralized_dns/decentralized_dns_opt_in_page.h" +#include "brave/components/decentralized_dns/features.h" +#include "brave/components/decentralized_dns/pref_names.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" @@ -58,7 +58,7 @@ void SendInterstitialCommandSync( content::WebContents* web_contents = browser->tab_strip_model()->GetActiveWebContents(); - EXPECT_EQ(unstoppable_domains::UnstoppableDomainsOptInPage::kTypeForTesting, + EXPECT_EQ(decentralized_dns::DecentralizedDnsOptInPage::kTypeForTesting, GetInterstitialType(web_contents)); content::TestNavigationObserver navigation_observer(web_contents, 1); @@ -70,16 +70,16 @@ void SendInterstitialCommandSync( } // namespace -namespace unstoppable_domains { +namespace decentralized_dns { -class UnstoppableDomainsNavigationThrottleBrowserTest +class DecentralizedDnsNavigationThrottleBrowserTest : public InProcessBrowserTest { public: - UnstoppableDomainsNavigationThrottleBrowserTest() { - feature_list_.InitAndEnableFeature(features::kUnstoppableDomains); + DecentralizedDnsNavigationThrottleBrowserTest() { + feature_list_.InitAndEnableFeature(features::kDecentralizedDns); } - ~UnstoppableDomainsNavigationThrottleBrowserTest() override = default; + ~DecentralizedDnsNavigationThrottleBrowserTest() override = default; void SetUpOnMainThread() override { InProcessBrowserTest::SetUpOnMainThread(); @@ -91,44 +91,84 @@ class UnstoppableDomainsNavigationThrottleBrowserTest base::test::ScopedFeatureList feature_list_; }; -IN_PROC_BROWSER_TEST_F(UnstoppableDomainsNavigationThrottleBrowserTest, - ShowInterstitialAndProceed) { +IN_PROC_BROWSER_TEST_F(DecentralizedDnsNavigationThrottleBrowserTest, + ShowUnstoppableDomainsInterstitialAndProceed) { ui_test_utils::NavigateToURL(browser(), GURL("http://test.crypto")); content::WebContents* web_contents = browser()->tab_strip_model()->GetActiveWebContents(); EXPECT_TRUE(WaitForRenderFrameReady(web_contents->GetMainFrame())); - EXPECT_EQ(UnstoppableDomainsOptInPage::kTypeForTesting, + EXPECT_EQ(DecentralizedDnsOptInPage::kTypeForTesting, GetInterstitialType(web_contents)); EXPECT_EQ(static_cast(ResolveMethodTypes::ASK), - local_state()->GetInteger(kResolveMethod)); + local_state()->GetInteger(kUnstoppableDomainsResolveMethod)); SendInterstitialCommandSync( browser(), security_interstitials::SecurityInterstitialCommand::CMD_PROCEED); EXPECT_EQ(static_cast(ResolveMethodTypes::DNS_OVER_HTTPS), - local_state()->GetInteger(kResolveMethod)); + local_state()->GetInteger(kUnstoppableDomainsResolveMethod)); } -IN_PROC_BROWSER_TEST_F(UnstoppableDomainsNavigationThrottleBrowserTest, - ShowInterstitialAndReject) { +IN_PROC_BROWSER_TEST_F(DecentralizedDnsNavigationThrottleBrowserTest, + ShowUnstoppableDomainsInterstitialAndReject) { ui_test_utils::NavigateToURL(browser(), GURL("http://test.crypto")); content::WebContents* web_contents = browser()->tab_strip_model()->GetActiveWebContents(); EXPECT_TRUE(WaitForRenderFrameReady(web_contents->GetMainFrame())); - EXPECT_EQ(UnstoppableDomainsOptInPage::kTypeForTesting, + EXPECT_EQ(DecentralizedDnsOptInPage::kTypeForTesting, GetInterstitialType(web_contents)); EXPECT_EQ(static_cast(ResolveMethodTypes::ASK), - local_state()->GetInteger(kResolveMethod)); + local_state()->GetInteger(kUnstoppableDomainsResolveMethod)); SendInterstitialCommandSync( browser(), security_interstitials::SecurityInterstitialCommand::CMD_DONT_PROCEED); EXPECT_EQ(static_cast(ResolveMethodTypes::DISABLED), - local_state()->GetInteger(kResolveMethod)); + local_state()->GetInteger(kUnstoppableDomainsResolveMethod)); } -} // namespace unstoppable_domains +IN_PROC_BROWSER_TEST_F(DecentralizedDnsNavigationThrottleBrowserTest, + ShowENSInterstitialAndProceed) { + ui_test_utils::NavigateToURL(browser(), GURL("http://test.eth")); + + content::WebContents* web_contents = + browser()->tab_strip_model()->GetActiveWebContents(); + + EXPECT_TRUE(WaitForRenderFrameReady(web_contents->GetMainFrame())); + EXPECT_EQ(DecentralizedDnsOptInPage::kTypeForTesting, + GetInterstitialType(web_contents)); + + EXPECT_EQ(static_cast(ResolveMethodTypes::ASK), + local_state()->GetInteger(kENSResolveMethod)); + SendInterstitialCommandSync( + browser(), + security_interstitials::SecurityInterstitialCommand::CMD_PROCEED); + EXPECT_EQ(static_cast(ResolveMethodTypes::DNS_OVER_HTTPS), + local_state()->GetInteger(kENSResolveMethod)); +} + +IN_PROC_BROWSER_TEST_F(DecentralizedDnsNavigationThrottleBrowserTest, + ShowENSInterstitialAndReject) { + ui_test_utils::NavigateToURL(browser(), GURL("http://test.eth")); + + content::WebContents* web_contents = + browser()->tab_strip_model()->GetActiveWebContents(); + + EXPECT_TRUE(WaitForRenderFrameReady(web_contents->GetMainFrame())); + EXPECT_EQ(DecentralizedDnsOptInPage::kTypeForTesting, + GetInterstitialType(web_contents)); + + EXPECT_EQ(static_cast(ResolveMethodTypes::ASK), + local_state()->GetInteger(kENSResolveMethod)); + SendInterstitialCommandSync( + browser(), + security_interstitials::SecurityInterstitialCommand::CMD_DONT_PROCEED); + EXPECT_EQ(static_cast(ResolveMethodTypes::DISABLED), + local_state()->GetInteger(kENSResolveMethod)); +} + +} // namespace decentralized_dns diff --git a/browser/unstoppable_domains/test/unstoppable_domains_service_browsertest.cc b/browser/decentralized_dns/test/decentralized_dns_service_browsertest.cc similarity index 62% rename from browser/unstoppable_domains/test/unstoppable_domains_service_browsertest.cc rename to browser/decentralized_dns/test/decentralized_dns_service_browsertest.cc index 17fc6da016de..fce12cf2e3f2 100644 --- a/browser/unstoppable_domains/test/unstoppable_domains_service_browsertest.cc +++ b/browser/decentralized_dns/test/decentralized_dns_service_browsertest.cc @@ -4,10 +4,10 @@ * You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "base/test/scoped_feature_list.h" -#include "brave/components/unstoppable_domains/constants.h" -#include "brave/components/unstoppable_domains/features.h" -#include "brave/components/unstoppable_domains/pref_names.h" -#include "brave/net/unstoppable_domains/constants.h" +#include "brave/components/decentralized_dns/constants.h" +#include "brave/components/decentralized_dns/features.h" +#include "brave/components/decentralized_dns/pref_names.h" +#include "brave/net/decentralized_dns/constants.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/net/secure_dns_config.h" #include "chrome/browser/net/stub_resolver_config_reader.h" @@ -19,12 +19,12 @@ #include "net/dns/public/secure_dns_mode.h" #include "testing/gtest/include/gtest/gtest.h" -namespace unstoppable_domains { +namespace decentralized_dns { -class UnstoppableDomainsServiceBrowserTest : public InProcessBrowserTest { +class DecentralizedDnsServiceBrowserTest : public InProcessBrowserTest { public: - UnstoppableDomainsServiceBrowserTest() { - feature_list_.InitAndEnableFeature(features::kUnstoppableDomains); + DecentralizedDnsServiceBrowserTest() { + feature_list_.InitAndEnableFeature(features::kDecentralizedDns); } void SetUpOnMainThread() override { @@ -34,7 +34,7 @@ class UnstoppableDomainsServiceBrowserTest : public InProcessBrowserTest { ASSERT_TRUE(stub_config_reader_); } - ~UnstoppableDomainsServiceBrowserTest() override = default; + ~DecentralizedDnsServiceBrowserTest() override = default; PrefService* local_state() { return g_browser_process->local_state(); } @@ -49,10 +49,10 @@ class UnstoppableDomainsServiceBrowserTest : public InProcessBrowserTest { StubResolverConfigReader* stub_config_reader_; }; -IN_PROC_BROWSER_TEST_F(UnstoppableDomainsServiceBrowserTest, +IN_PROC_BROWSER_TEST_F(DecentralizedDnsServiceBrowserTest, UpdateConfigWhenPrefChanged) { // Initial state. - EXPECT_EQ(local_state()->GetInteger(kResolveMethod), + EXPECT_EQ(local_state()->GetInteger(kUnstoppableDomainsResolveMethod), static_cast(ResolveMethodTypes::ASK)); SecureDnsConfig config = GetSecureDnsConfiguration(); EXPECT_EQ(config.mode(), net::SecureDnsMode::kAutomatic); @@ -60,16 +60,18 @@ IN_PROC_BROWSER_TEST_F(UnstoppableDomainsServiceBrowserTest, // Set resolve method to DoH should update the config. local_state()->SetInteger( - kResolveMethod, static_cast(ResolveMethodTypes::DNS_OVER_HTTPS)); + kUnstoppableDomainsResolveMethod, + static_cast(ResolveMethodTypes::DNS_OVER_HTTPS)); config = GetSecureDnsConfiguration(); std::vector expected_doh_servers = { - {kDoHResolver, true}}; + {kUnstoppableDomainsDoHResolver, true}}; EXPECT_EQ(config.servers(), expected_doh_servers); // Set custom DoH provider should still keep the resolver for UD. local_state()->SetString(prefs::kDnsOverHttpsTemplates, "https://test.com"); config = GetSecureDnsConfiguration(); - expected_doh_servers = {{kDoHResolver, true}, {"https://test.com", true}}; + expected_doh_servers = {{kUnstoppableDomainsDoHResolver, true}, + {"https://test.com", true}}; EXPECT_EQ(config.servers(), expected_doh_servers); // Set secure mode to off should return empty DoH servers. @@ -86,18 +88,29 @@ IN_PROC_BROWSER_TEST_F(UnstoppableDomainsServiceBrowserTest, config = GetSecureDnsConfiguration(); EXPECT_EQ(config.servers(), expected_doh_servers); + // Set resolve method of ENS to DoH should update the config. + local_state()->SetInteger( + kENSResolveMethod, static_cast(ResolveMethodTypes::DNS_OVER_HTTPS)); + config = GetSecureDnsConfiguration(); + expected_doh_servers = {{kENSDoHResolver, true}, + {kUnstoppableDomainsDoHResolver, true}, + {"https://test.com", true}}; + EXPECT_EQ(config.servers(), expected_doh_servers); + // Set resolve method to disabled should keep user's DoH setting. - local_state()->SetInteger(kResolveMethod, + local_state()->SetInteger(kUnstoppableDomainsResolveMethod, + static_cast(ResolveMethodTypes::DISABLED)); + local_state()->SetInteger(kENSResolveMethod, static_cast(ResolveMethodTypes::DISABLED)); config = GetSecureDnsConfiguration(); expected_doh_servers = {{"https://test.com", true}}; EXPECT_EQ(config.servers(), expected_doh_servers); } -IN_PROC_BROWSER_TEST_F(UnstoppableDomainsServiceBrowserTest, - HideUnstoppableDomainsResolvers) { +IN_PROC_BROWSER_TEST_F(DecentralizedDnsServiceBrowserTest, + HideDecentralizedDnsResolvers) { // Initial state. - EXPECT_EQ(local_state()->GetInteger(kResolveMethod), + EXPECT_EQ(local_state()->GetInteger(kUnstoppableDomainsResolveMethod), static_cast(ResolveMethodTypes::ASK)); SecureDnsConfig config = GetSecureDnsConfiguration(); EXPECT_EQ(config.mode(), net::SecureDnsMode::kAutomatic); @@ -105,16 +118,27 @@ IN_PROC_BROWSER_TEST_F(UnstoppableDomainsServiceBrowserTest, // Set resolve method to DoH should update the config. local_state()->SetInteger( - kResolveMethod, static_cast(ResolveMethodTypes::DNS_OVER_HTTPS)); + kUnstoppableDomainsResolveMethod, + static_cast(ResolveMethodTypes::DNS_OVER_HTTPS)); config = GetSecureDnsConfiguration(); std::vector expected_doh_servers = { - {kDoHResolver, true}}; + {kUnstoppableDomainsDoHResolver, true}}; EXPECT_EQ(config.servers(), expected_doh_servers); // Set custom DoH provider should still keep the resolver for UD. local_state()->SetString(prefs::kDnsOverHttpsTemplates, "https://test.com"); config = GetSecureDnsConfiguration(); - expected_doh_servers = {{kDoHResolver, true}, {"https://test.com", true}}; + expected_doh_servers = {{kUnstoppableDomainsDoHResolver, true}, + {"https://test.com", true}}; + EXPECT_EQ(config.servers(), expected_doh_servers); + + // Set resolve method of ENS to DoH should update the config. + local_state()->SetInteger( + kENSResolveMethod, static_cast(ResolveMethodTypes::DNS_OVER_HTTPS)); + config = GetSecureDnsConfiguration(); + expected_doh_servers = {{kENSDoHResolver, true}, + {kUnstoppableDomainsDoHResolver, true}, + {"https://test.com", true}}; EXPECT_EQ(config.servers(), expected_doh_servers); // Should hide unstoppable domains resolver if @@ -125,4 +149,4 @@ IN_PROC_BROWSER_TEST_F(UnstoppableDomainsServiceBrowserTest, EXPECT_EQ(config.servers(), expected_doh_servers); } -} // namespace unstoppable_domains +} // namespace decentralized_dns diff --git a/browser/decentralized_dns/test/utils_unittest.cc b/browser/decentralized_dns/test/utils_unittest.cc new file mode 100644 index 000000000000..6309647de9ca --- /dev/null +++ b/browser/decentralized_dns/test/utils_unittest.cc @@ -0,0 +1,101 @@ +/* Copyright (c) 2021 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "brave/components/decentralized_dns/utils.h" + +#include "base/test/scoped_feature_list.h" +#include "base/test/task_environment.h" +#include "brave/components/decentralized_dns/constants.h" +#include "brave/components/decentralized_dns/features.h" +#include "brave/components/decentralized_dns/pref_names.h" +#include "chrome/test/base/scoped_testing_local_state.h" +#include "chrome/test/base/testing_browser_process.h" +#include "components/prefs/testing_pref_service.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace decentralized_dns { + +class UtilsUnitTest : public testing::TestWithParam { + public: + UtilsUnitTest() + : local_state_(TestingBrowserProcess::GetGlobal()), + feature_enabled_(GetParam()) {} + ~UtilsUnitTest() override = default; + + void SetUp() override { + if (feature_enabled_) { + feature_list_.InitAndEnableFeature(features::kDecentralizedDns); + } else { + feature_list_.InitAndDisableFeature(features::kDecentralizedDns); + } + } + + PrefService* local_state() { return local_state_.Get(); } + bool feature_enabled() { return feature_enabled_; } + + private: + base::test::TaskEnvironment task_environment_; + base::test::ScopedFeatureList feature_list_; + ScopedTestingLocalState local_state_; + bool feature_enabled_; +}; + +TEST_P(UtilsUnitTest, IsDecentralizedDnsEnabled) { + EXPECT_EQ(feature_enabled(), IsDecentralizedDnsEnabled()); +} + +TEST_P(UtilsUnitTest, IsUnstoppableDomainsTLD) { + EXPECT_TRUE(IsUnstoppableDomainsTLD(GURL("http://test.crypto"))); + EXPECT_FALSE(IsUnstoppableDomainsTLD(GURL("http://test.com"))); + EXPECT_FALSE(IsUnstoppableDomainsTLD(GURL("http://test.eth"))); + EXPECT_FALSE(IsUnstoppableDomainsTLD(GURL("http://crypto"))); +} + +TEST_P(UtilsUnitTest, IsUnstoppableDomainsResolveMethodAsk) { + EXPECT_EQ(feature_enabled(), + IsUnstoppableDomainsResolveMethodAsk(local_state())); + + local_state()->SetInteger( + kUnstoppableDomainsResolveMethod, + static_cast(ResolveMethodTypes::DNS_OVER_HTTPS)); + EXPECT_FALSE(IsUnstoppableDomainsResolveMethodAsk(local_state())); +} + +TEST_P(UtilsUnitTest, IsUnstoppableDomainsResolveMethodDoH) { + EXPECT_FALSE(IsUnstoppableDomainsResolveMethodDoH(local_state())); + + local_state()->SetInteger( + kUnstoppableDomainsResolveMethod, + static_cast(ResolveMethodTypes::DNS_OVER_HTTPS)); + EXPECT_EQ(feature_enabled(), + IsUnstoppableDomainsResolveMethodDoH(local_state())); +} + +TEST_P(UtilsUnitTest, IsENSTLD) { + EXPECT_TRUE(IsENSTLD(GURL("http://test.eth"))); + EXPECT_FALSE(IsENSTLD(GURL("http://test.com"))); + EXPECT_FALSE(IsENSTLD(GURL("http://test.crypto"))); + EXPECT_FALSE(IsENSTLD(GURL("http://eth"))); +} + +TEST_P(UtilsUnitTest, IsENSResolveMethodAsk) { + EXPECT_EQ(feature_enabled(), IsENSResolveMethodAsk(local_state())); + + local_state()->SetInteger( + kENSResolveMethod, static_cast(ResolveMethodTypes::DNS_OVER_HTTPS)); + EXPECT_FALSE(IsENSResolveMethodAsk(local_state())); +} + +TEST_P(UtilsUnitTest, IsENSResolveMethodDoH) { + EXPECT_FALSE(IsENSResolveMethodDoH(local_state())); + + local_state()->SetInteger( + kENSResolveMethod, static_cast(ResolveMethodTypes::DNS_OVER_HTTPS)); + EXPECT_EQ(feature_enabled(), IsENSResolveMethodDoH(local_state())); +} + +INSTANTIATE_TEST_SUITE_P(/* no prefix */, UtilsUnitTest, testing::Bool()); + +} // namespace decentralized_dns diff --git a/browser/extensions/BUILD.gn b/browser/extensions/BUILD.gn index fe2f08ba4840..73475de24152 100644 --- a/browser/extensions/BUILD.gn +++ b/browser/extensions/BUILD.gn @@ -6,11 +6,11 @@ import("//brave/components/brave_wallet/config.gni") import("//brave/components/brave_wayback_machine/buildflags/buildflags.gni") import("//brave/components/brave_webtorrent/browser/buildflags/buildflags.gni") import("//brave/components/crypto_dot_com/browser/buildflags/buildflags.gni") +import("//brave/components/decentralized_dns/buildflags/buildflags.gni") import("//brave/components/gemini/browser/buildflags/buildflags.gni") import("//brave/components/ipfs/buildflags/buildflags.gni") import("//brave/components/sidebar/buildflags/buildflags.gni") import("//brave/components/tor/buildflags/buildflags.gni") -import("//brave/components/unstoppable_domains/buildflags/buildflags.gni") import("//build/config/features.gni") import("//components/gcm_driver/config.gni") @@ -65,10 +65,10 @@ source_set("extensions") { "//brave/components/brave_shields/common", "//brave/components/brave_today/browser", "//brave/components/brave_wayback_machine:buildflags", + "//brave/components/decentralized_dns/buildflags", "//brave/components/ipfs/buildflags", "//brave/components/sidebar/buildflags", "//brave/components/tor/buildflags", - "//brave/components/unstoppable_domains/buildflags", "//chrome/browser/extensions", "//chrome/common", "//components/gcm_driver:gcm_buildflags", @@ -113,8 +113,8 @@ source_set("extensions") { deps += [ "//brave/components/ipfs" ] } - if (unstoppable_domains_enabled) { - deps += [ "//brave/components/unstoppable_domains" ] + if (decentralized_dns_enabled) { + deps += [ "//brave/components/decentralized_dns" ] } if (brave_rewards_enabled) { diff --git a/browser/extensions/api/settings_private/brave_prefs_util.cc b/browser/extensions/api/settings_private/brave_prefs_util.cc index 682c4c2767be..2604ff65efb8 100644 --- a/browser/extensions/api/settings_private/brave_prefs_util.cc +++ b/browser/extensions/api/settings_private/brave_prefs_util.cc @@ -10,11 +10,11 @@ #include "brave/components/brave_wallet/buildflags/buildflags.h" #include "brave/components/brave_wayback_machine/buildflags.h" #include "brave/components/crypto_dot_com/browser/buildflags/buildflags.h" +#include "brave/components/decentralized_dns/buildflags/buildflags.h" #include "brave/components/ipfs/buildflags/buildflags.h" #include "brave/components/ntp_background_images/common/pref_names.h" #include "brave/components/sidebar/buildflags/buildflags.h" #include "brave/components/tor/buildflags/buildflags.h" -#include "brave/components/unstoppable_domains/buildflags/buildflags.h" #include "chrome/browser/extensions/api/settings_private/prefs_util.h" #include "chrome/common/extensions/api/settings_private.h" #include "chrome/common/pref_names.h" @@ -46,8 +46,8 @@ #include "brave/components/tor/pref_names.h" #endif -#if BUILDFLAG(UNSTOPPABLE_DOMAINS_ENABLED) -#include "brave/components/unstoppable_domains/pref_names.h" +#if BUILDFLAG(DECENTRALIZED_DNS_ENABLED) +#include "brave/components/decentralized_dns/pref_names.h" #endif namespace extensions { @@ -212,9 +212,10 @@ const PrefsUtil::TypedPrefMap& BravePrefsUtil::GetAllowlistedKeys() { (*s_brave_allowlist)[prefs::kWebRTCIPHandlingPolicy] = settings_api::PrefType::PREF_TYPE_STRING; -#if BUILDFLAG(UNSTOPPABLE_DOMAINS_ENABLED) - // Unstoppable Domains pref - (*s_brave_allowlist)[unstoppable_domains::kResolveMethod] = +#if BUILDFLAG(DECENTRALIZED_DNS_ENABLED) + (*s_brave_allowlist)[decentralized_dns::kUnstoppableDomainsResolveMethod] = + settings_api::PrefType::PREF_TYPE_NUMBER; + (*s_brave_allowlist)[decentralized_dns::kENSResolveMethod] = settings_api::PrefType::PREF_TYPE_NUMBER; #endif diff --git a/browser/profiles/BUILD.gn b/browser/profiles/BUILD.gn index 43138a45ec71..ed5b9dae5f52 100644 --- a/browser/profiles/BUILD.gn +++ b/browser/profiles/BUILD.gn @@ -34,10 +34,10 @@ source_set("profiles") { "//brave/components/brave_sync:prefs", "//brave/components/brave_wallet/buildflags", "//brave/components/content_settings/core/browser", + "//brave/components/decentralized_dns/buildflags", "//brave/components/ipfs/buildflags", "//brave/components/ntp_background_images/common", "//brave/components/tor", - "//brave/components/unstoppable_domains/buildflags", "//brave/content:browser", "//chrome/common", "//components/gcm_driver:gcm_buildflags", diff --git a/browser/profiles/brave_profile_manager.cc b/browser/profiles/brave_profile_manager.cc index 64b7ddb880cd..a104e0d8d39f 100644 --- a/browser/profiles/brave_profile_manager.cc +++ b/browser/profiles/brave_profile_manager.cc @@ -17,9 +17,9 @@ #include "brave/components/brave_ads/browser/ads_service_factory.h" #include "brave/components/brave_wallet/buildflags/buildflags.h" #include "brave/components/content_settings/core/browser/brave_content_settings_pref_provider.h" +#include "brave/components/decentralized_dns/buildflags/buildflags.h" #include "brave/components/ipfs/buildflags/buildflags.h" #include "brave/components/tor/tor_constants.h" -#include "brave/components/unstoppable_domains/buildflags/buildflags.h" #include "brave/content/browser/webui/brave_shared_resources_data_source.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/chrome_notification_types.h" @@ -51,8 +51,8 @@ #include "brave/browser/ipfs/ipfs_service_factory.h" #endif -#if BUILDFLAG(UNSTOPPABLE_DOMAINS_ENABLED) -#include "brave/browser/unstoppable_domains/unstoppable_domains_service_factory.h" +#if BUILDFLAG(DECENTRALIZED_DNS_ENABLED) +#include "brave/browser/decentralized_dns/decentralized_dns_service_factory.h" #endif using content::BrowserThread; @@ -113,8 +113,8 @@ void BraveProfileManager::DoFinalInitForServices(Profile* profile, #if BUILDFLAG(IPFS_ENABLED) ipfs::IpfsServiceFactory::GetForContext(profile); #endif -#if BUILDFLAG(UNSTOPPABLE_DOMAINS_ENABLED) - unstoppable_domains::UnstoppableDomainsServiceFactory::GetForContext(profile); +#if BUILDFLAG(DECENTRALIZED_DNS_ENABLED) + decentralized_dns::DecentralizedDnsServiceFactory::GetForContext(profile); #endif #if !BUILDFLAG(USE_GCM_FROM_PLATFORM) gcm::BraveGCMChannelStatus* status = diff --git a/browser/resources/settings/brave_default_extensions_page/brave_default_extensions_browser_proxy.js b/browser/resources/settings/brave_default_extensions_page/brave_default_extensions_browser_proxy.js index 279ff0189f6b..5e110c6c94b7 100644 --- a/browser/resources/settings/brave_default_extensions_page/brave_default_extensions_browser_proxy.js +++ b/browser/resources/settings/brave_default_extensions_page/brave_default_extensions_browser_proxy.js @@ -68,8 +68,8 @@ cr.define('settings', function () { return loadTimeData.getBoolean('signInAllowedOnNextStartupInitialValue') } - isUnstoppableDomainsEnabled () { - return cr.sendWithPromise('isUnstoppableDomainsEnabled') + isDecentralizedDnsEnabled () { + return cr.sendWithPromise('isDecentralizedDnsEnabled') } } diff --git a/browser/resources/settings/brave_default_extensions_page/brave_default_extensions_page.html b/browser/resources/settings/brave_default_extensions_page/brave_default_extensions_page.html index c9bb46c6e392..b3cdb3fc036a 100644 --- a/browser/resources/settings/brave_default_extensions_page/brave_default_extensions_page.html +++ b/browser/resources/settings/brave_default_extensions_page/brave_default_extensions_page.html @@ -85,13 +85,19 @@ sub-label="$i18n{hangoutsEnabledDesc}" on-settings-boolean-control-change="onHangoutsEnabledChange_">
-