// 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_server_config.h"
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.
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);
// If `is_profile_managed` is true, then the secure DNS settings can only be
// configured by enterprise policy; otherwise the secure DNS settings can be
// configured by the user in the settings UI.
SecureDnsManager(PrefService* local_state, bool is_profile_managed);
SecureDnsManager(const SecureDnsManager&) = delete;
SecureDnsManager& operator=(const SecureDnsManager&) = delete;
~SecureDnsManager() override;
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;
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 secure DNS enterprise policy changes. The policy values are
// mapped by the policy service to the local state pref service.
void MonitorPolicyPrefs();
// Callback for the registrar. Evaluates the current settings and publishes
// the result to shill.
void OnPolicyPrefChanged();
void OnDoHIncludedDomainsPrefChanged();
void OnDoHExcludedDomainsPrefChanged();
// 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();
// 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.
void BroadcastUpdates(bool template_uris_changed, bool mode_changed) const;
base::ScopedObservation<NetworkStateHandler, NetworkStateHandlerObserver>
network_state_handler_observer_{this};
PrefChangeRegistrar local_state_registrar_;
raw_ptr<PrefService> local_state_;
// 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_;
std::string cached_template_uris_;
std::string cached_mode_;
bool cached_is_config_managed_ = false;
base::ObserverList<Observer> observers_;
};
} // namespace ash
#endif // CHROME_BROWSER_ASH_NET_SECURE_DNS_MANAGER_H_