1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196
|
// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_ASH_NET_SECURE_DNS_MANAGER_H_
#define CHROME_BROWSER_ASH_NET_SECURE_DNS_MANAGER_H_
#include <string>
#include "base/containers/flat_map.h"
#include "base/gtest_prod_util.h"
#include "base/memory/raw_ptr.h"
#include "base/observer_list.h"
#include "base/observer_list_types.h"
#include "chrome/browser/ash/net/dns_over_https/templates_uri_resolver.h"
#include "chromeos/ash/components/network/network_state.h"
#include "chromeos/ash/components/network/network_state_handler.h"
#include "chromeos/ash/components/network/network_state_handler_observer.h"
#include "components/prefs/pref_change_registrar.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/pref_service.h"
#include "net/dns/public/dns_over_https_config.h"
#include "net/dns/public/dns_over_https_server_config.h"
#include "net/dns/public/secure_dns_mode.h"
namespace user_manager {
class User;
} // namespace user_manager
namespace ash {
// Responds to changes in the SecureDNS preferences from the local state and
// generates and updates the corresponding shill property which can then be used
// by downstream services.
// The enterprise policies which control secure DNS settings in the browser are
// cross-platform policies that map to local state. This is required because the
// DNS config is global in the Network Service. On ChromeOS, local state is
// shared between all user sessions (including guest). For this reason, the
// user-set preferences map to the pref service that belongs to the primary
// profile.
class SecureDnsManager : public NetworkStateHandlerObserver {
public:
// Observes changes in the DNS-over-HTTPS configuration.
class Observer : public base::CheckedObserver {
public:
// Called when the effective DNS-over-HTTPS template URIs change.
virtual void OnTemplateUrisChanged(const std::string& template_uris) = 0;
// Called when the DNS-over-HTTPS mode changes.
virtual void OnModeChanged(const std::string& mode) = 0;
// Called before the SecureDnsManager is destroyed.
virtual void OnSecureDnsManagerShutdown() = 0;
~Observer() override = default;
};
void AddObserver(Observer* observer);
void RemoveObserver(Observer* observer);
SecureDnsManager(PrefService* local_state,
user_manager::User& user,
bool is_profile_managed);
SecureDnsManager(const SecureDnsManager&) = delete;
SecureDnsManager& operator=(const SecureDnsManager&) = delete;
~SecureDnsManager() override;
static void RegisterProfilePrefs(PrefRegistrySimple* registry);
static void RegisterLocalStatePrefs(PrefRegistrySimple* registry);
void SetDoHTemplatesUriResolverForTesting(
std::unique_ptr<dns_over_https::TemplatesUriResolver>
doh_templates_uri_resolver);
// If the URI templates for the DNS-over-HTTPS resolver contain user or device
// identifiers (which are hashed before being used), this method returns the
// plain text version of the URI templates. Otherwise returns nullopt.
std::optional<std::string> GetDohWithIdentifiersDisplayServers() const;
// Returns the OS' secure DNS configuration.
net::DnsOverHttpsConfig GetOsDohConfig() const;
net::SecureDnsMode GetOsDohMode() const;
void SetPrimaryProfilePropertiesForTesting(PrefService* profile_prefs,
bool is_profile_managed);
// Whether or not DoHIncludedDomains or DoHExcludedDomains is set.
bool IsDohDomainConfigSet() const { return cached_domain_config_set_; }
private:
void DefaultNetworkChanged(const NetworkState* network) override;
// Retrieves the list of secure DNS providers, preprocesses and caches it for
// later use. This is safe since the list is embedded in code and will not
// change at runtime.
void LoadProviders();
// Computes a collection of secure DNS providers to use based on the |mode|
// and |templates| prefs applied to |local_doh_providers_|.
base::Value::Dict GetProviders(const std::string& mode,
const std::string& templates) const;
// Starts tracking user-configured secure DNS settings. This settings are
// mapped to the pref service that belongs to the profile associated with the
// primary user.
void MonitorUserPrefs();
void OnPrefChanged();
// Starts tracking secure DNS enterprise policy changes. The policy values are
// mapped by the policy service to the local state pref service.
void MonitorLocalStatePrefs();
void OnLocalStatePrefsChanged();
void OnDoHIncludedDomainsPrefChanged();
void OnDoHExcludedDomainsPrefChanged();
// When moving between profiles (and login screen), SecureDnsManager instance
// is destroyed. A new instance is created on the new user session. On login
// screen, the class is not instantiated. In order to have the correct Shill
// state on login screen, Shill's state needs to be reset whenever the class
// is destroyed. This is done by propagating all the default values of the
// states.
void ResetShillState();
// If the DoH template URIs contain network identifiers, this method will
// instantiate `network_state_handler_observer_` to start monitoring
// network changes. Otherwise, it will reset
// `network_state_handler_observer_`.
void ToggleNetworkMonitoring();
void UpdateTemplateUri();
// Update the internal cached DoH config. If either the template URIs or the
// mode have been modified, inform all registered observers in the
// 'observers_' list and also notify Lacros and the shill service about the
// new values.
// `new_template_uris` is a space separated DoH template URI. The value is
// expected to be fetched from Chrome's kDnsOverHttpsTemplates prefs.
// When `force_update` is true, always send the updates to the observer
// regardless of any value changes.
// The DoH config for Chrome and shill might differ in the case where
// DoHIncludedDomains or DoHExcludedDomains is set. On such cases, DoH in
// Chrome is always disabled in order for ChromeOS DNS proxy to be able to
// listen for Chrome DNS requests.
void UpdateDoHConfig(const std::string& new_mode,
const std::string& new_template_uris,
bool force_update = false);
void UpdateChromeDoHConfig(const std::string& new_mode,
const std::string& new_template_uris,
bool force_update = false);
void UpdateShillDoHConfig(const std::string& new_mode,
const std::string& new_template_uris);
// Updates `cached_domain_config_set_`. If DoH domain config changed, also
// trigger a DoH config update to the observers in order for the UI to be
// updated.
void UpdateCachedDomainConfigSet();
base::ScopedObservation<NetworkStateHandler, NetworkStateHandlerObserver>
network_state_handler_observer_{this};
PrefChangeRegistrar local_state_registrar_, profile_prefs_registrar_;
raw_ptr<PrefService> local_state_;
raw_ref<user_manager::User> user_;
// Maps secure DNS provider URL templates to their corresponding standard DNS
// name servers. Providers that are either disabled or not applicable for the
// country have been pre-filtered.
base::flat_map<net::DnsOverHttpsServerConfig, std::string>
local_doh_providers_;
std::unique_ptr<dns_over_https::TemplatesUriResolver>
doh_templates_uri_resolver_;
// Cached OS-wide DoH provider URIs and mode. The value is expected to match
// Chrome's secure DNS prefs.
std::string cached_template_uris_;
std::string cached_mode_;
// Cached DoH provider URIs and mode for Chrome.
// The values might differ with the actual values in the case where
// DoHIncludedDomains or DoHExcludedDomains is set.
std::string cached_chrome_template_uris_;
std::string cached_chrome_mode_;
// Whether or not DoHIncludedDomains or DoHExcludedDomains is set.
bool cached_domain_config_set_ = false;
bool cached_is_config_managed_ = false;
bool is_profile_managed_ = false;
base::ObserverList<Observer> observers_;
};
} // namespace ash
#endif // CHROME_BROWSER_ASH_NET_SECURE_DNS_MANAGER_H_
|