chromium/services/network/network_service.cc

// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "services/network/network_service.h"

#include <algorithm>
#include <map>
#include <optional>
#include <utility>
#include <vector>

#include "base/check.h"
#include "base/check_op.h"
#include "base/debug/crash_logging.h"
#include "base/debug/dump_without_crashing.h"
#include "base/environment.h"
#include "base/feature_list.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/functional/callback_helpers.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "base/memory/raw_ptr.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/not_fatal_until.h"
#include "base/task/sequenced_task_runner.h"
#include "base/task/task_traits.h"
#include "base/task/thread_pool.h"
#include "base/timer/timer.h"
#include "base/types/pass_key.h"
#include "base/values.h"
#include "build/build_config.h"
#include "build/chromecast_buildflags.h"
#include "build/chromeos_buildflags.h"
#include "components/ip_protection/common/masked_domain_list_manager.h"
#include "components/network_session_configurator/common/network_features.h"
#include "components/os_crypt/sync/os_crypt.h"
#include "components/privacy_sandbox/masked_domain_list/masked_domain_list.pb.h"
#include "mojo/public/cpp/base/proto_wrapper.h"
#include "mojo/public/cpp/bindings/callback_helpers.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/scoped_message_error_crash_key.h"
#include "mojo/public/cpp/bindings/shared_remote.h"
#include "mojo/public/cpp/system/functions.h"
#include "net/base/address_list.h"
#include "net/base/features.h"
#include "net/base/logging_network_change_observer.h"
#include "net/base/network_change_notifier.h"
#include "net/base/network_change_notifier_passive.h"
#include "net/base/port_util.h"
#include "net/cert/cert_database.h"
#include "net/cert/ct_log_response_parser.h"
#include "net/cert/internal/system_trust_store.h"
#include "net/cert/signed_tree_head.h"
#include "net/cookies/cookie_util.h"
#include "net/dns/host_resolver.h"
#include "net/dns/host_resolver_manager.h"
#include "net/dns/host_resolver_proc.h"
#include "net/dns/public/dns_config_overrides.h"
#include "net/dns/public/dns_over_https_config.h"
#include "net/dns/public/doh_provider_entry.h"
#include "net/dns/system_dns_config_change_notifier.h"
#include "net/dns/test_dns_config_service.h"
#include "net/first_party_sets/global_first_party_sets.h"
#include "net/http/http_auth_handler_factory.h"
#include "net/log/file_net_log_observer.h"
#include "net/log/net_log.h"
#include "net/log/net_log_capture_mode.h"
#include "net/log/net_log_util.h"
#include "net/nqe/network_quality_estimator.h"
#include "net/socket/client_socket_pool_manager.h"
#include "net/ssl/ssl_key_logger_impl.h"
#include "net/url_request/url_request_context.h"
#include "services/network/dns_config_change_manager.h"
#include "services/network/first_party_sets/first_party_sets_manager.h"
#include "services/network/http_auth_cache_copier.h"
#include "services/network/net_log_exporter.h"
#include "services/network/net_log_proxy_sink.h"
#include "services/network/network_context.h"
#include "services/network/public/cpp/crash_keys.h"
#include "services/network/public/cpp/features.h"
#include "services/network/public/cpp/initiator_lock_compatibility.h"
#include "services/network/public/cpp/load_info_util.h"
#include "services/network/public/cpp/network_switches.h"
#include "services/network/public/cpp/parsed_headers.h"
#include "services/network/public/mojom/key_pinning.mojom.h"
#include "services/network/public/mojom/network_service_test.mojom.h"
#include "services/network/public/mojom/system_dns_resolution.mojom-forward.h"
#include "services/network/restricted_cookie_manager.h"
#include "services/network/tpcd/metadata/manager.h"
#include "services/network/url_loader.h"

#if BUILDFLAG(IS_ANDROID) && defined(ARCH_CPU_ARMEL)
#include "third_party/boringssl/src/include/openssl/cpu.h"
#endif

#if (BUILDFLAG(IS_LINUX) && !BUILDFLAG(IS_CASTOS)) || \
    BUILDFLAG(IS_CHROMEOS_LACROS)

#include "components/os_crypt/sync/key_storage_config_linux.h"
#endif

#if BUILDFLAG(IS_LINUX)
#include "services/network/network_change_notifier_passive_factory.h"
#endif

#if BUILDFLAG(IS_ANDROID)
#include "base/android/application_status_listener.h"
#include "net/android/http_auth_negotiate_android.h"
#endif

#if BUILDFLAG(IS_CT_SUPPORTED)
#include "services/network/sct_auditing/sct_auditing_cache.h"
#endif

namespace net {
class FirstPartySetEntry;
}

namespace network {

namespace {

NetworkService* g_network_service =;

std::unique_ptr<net::NetworkChangeNotifier> CreateNetworkChangeNotifierIfNeeded(
    net::NetworkChangeNotifier::ConnectionType initial_connection_type,
    net::NetworkChangeNotifier::ConnectionSubtype initial_connection_subtype,
    bool mock_network_change_notifier) {}

void OnGetNetworkList(std::unique_ptr<net::NetworkInterfaceList> networks,
                      mojom::NetworkService::GetNetworkListCallback callback,
                      bool success) {}

#if BUILDFLAG(IS_ANDROID) && BUILDFLAG(USE_KERBEROS)
// Used for Negotiate authentication on Android, which needs to generate tokens
// in the browser process.
class NetworkServiceAuthNegotiateAndroid : public net::HttpAuthMechanism {
 public:
  NetworkServiceAuthNegotiateAndroid(NetworkContext* network_context,
                                     const net::HttpAuthPreferences* prefs)
      : network_context_(network_context), auth_negotiate_(prefs) {}
  ~NetworkServiceAuthNegotiateAndroid() override = default;

  // HttpAuthMechanism implementation:
  bool Init(const net::NetLogWithSource& net_log) override {
    return auth_negotiate_.Init(net_log);
  }

  bool NeedsIdentity() const override {
    return auth_negotiate_.NeedsIdentity();
  }

  bool AllowsExplicitCredentials() const override {
    return auth_negotiate_.AllowsExplicitCredentials();
  }

  net::HttpAuth::AuthorizationResult ParseChallenge(
      net::HttpAuthChallengeTokenizer* tok) override {
    return auth_negotiate_.ParseChallenge(tok);
  }

  int GenerateAuthToken(const net::AuthCredentials* credentials,
                        const std::string& spn,
                        const std::string& channel_bindings,
                        std::string* auth_token,
                        const net::NetLogWithSource& net_log,
                        net::CompletionOnceCallback callback) override {
    network_context_->client()->OnGenerateHttpNegotiateAuthToken(
        auth_negotiate_.server_auth_token(), auth_negotiate_.can_delegate(),
        auth_negotiate_.GetAuthAndroidNegotiateAccountType(), spn,
        base::BindOnce(&NetworkServiceAuthNegotiateAndroid::Finish,
                       weak_factory_.GetWeakPtr(), auth_token,
                       std::move(callback)));
    return net::ERR_IO_PENDING;
  }

  void SetDelegation(net::HttpAuth::DelegationType delegation_type) override {
    auth_negotiate_.SetDelegation(delegation_type);
  }

 private:
  void Finish(std::string* auth_token_out,
              net::CompletionOnceCallback callback,
              int result,
              const std::string& auth_token) {
    *auth_token_out = auth_token;
    std::move(callback).Run(result);
  }

  raw_ptr<NetworkContext> network_context_ = nullptr;
  net::android::HttpAuthNegotiateAndroid auth_negotiate_;
  base::WeakPtrFactory<NetworkServiceAuthNegotiateAndroid> weak_factory_{this};
};

std::unique_ptr<net::HttpAuthMechanism> CreateAuthSystem(
    NetworkContext* network_context,
    const net::HttpAuthPreferences* prefs) {
  return std::make_unique<NetworkServiceAuthNegotiateAndroid>(network_context,
                                                              prefs);
}
#endif

// Called when NetworkService received a bad IPC message (but only when
// NetworkService is running in a separate process - otherwise the existing bad
// message handling inside the Browser process is sufficient).
void HandleBadMessage(const std::string& error) {}

// Runs `results_cb` on `sequenced_task_runner` with an empty result and
// net::ERR_ABORTED.
void AsyncResolveSystemDnsWithEmptyResult(
    scoped_refptr<base::SequencedTaskRunner> sequenced_task_runner,
    net::SystemDnsResultsCallback results_cb) {}

void ResolveSystemDnsWithMojo(
    const mojo::Remote<mojom::SystemDnsResolver>& system_dns_override,
    const std::optional<std::string>& hostname,
    net::AddressFamily addr_family,
    net::HostResolverFlags flags,
    net::SystemDnsResultsCallback results_cb,
    net::handles::NetworkHandle network) {}

// Creating an instance of this class starts exporting UMA data related to
// RestrictedCookieManager. There should only be one instance of this class at a
// time and it should be kept around for the duration of the program. This is
// accomplished by having NetworkService own the instance.
class RestrictedCookieManagerMetrics
    : public RestrictedCookieManager::UmaMetricsUpdater {};

}  // namespace

// static
const base::TimeDelta NetworkService::kInitialDohProbeTimeout =;

// Handler of delaying calls to NetworkContext::ActivateDohProbes() until after
// an initial service startup delay.
class NetworkService::DelayedDohProbeActivator {};

NetworkService::NetworkService(
    std::unique_ptr<service_manager::BinderRegistry> registry,
    mojo::PendingReceiver<mojom::NetworkService> receiver,
    bool delay_initialization_until_set_client)
    :{}

void NetworkService::Initialize(mojom::NetworkServiceParamsPtr params,
                                bool mock_network_change_notifier) {}

NetworkService::~NetworkService() {}

void NetworkService::ReplaceSystemDnsConfigForTesting(
    base::OnceClosure replace_cb) {}

void NetworkService::SetNetworkAnnotationMonitor(
    mojo::PendingRemote<network::mojom::NetworkAnnotationMonitor> remote) {}

void NetworkService::NotifyNetworkRequestWithAnnotation(
    net::NetworkTrafficAnnotationTag traffic_annotation) {}

void NetworkService::SetTestDohConfigForTesting(
    net::SecureDnsMode secure_dns_mode,
    const net::DnsOverHttpsConfig& doh_config) {}

std::unique_ptr<NetworkService> NetworkService::Create(
    mojo::PendingReceiver<mojom::NetworkService> receiver) {}

// static
std::unique_ptr<NetworkService> NetworkService::CreateForTesting() {}

void NetworkService::RegisterNetworkContext(NetworkContext* network_context) {}

void NetworkService::DeregisterNetworkContext(NetworkContext* network_context) {}

void NetworkService::CreateNetLogEntriesForActiveObjects(
    net::NetLog::ThreadSafeObserver* observer) {}

void NetworkService::SetParams(mojom::NetworkServiceParamsPtr params) {}

void NetworkService::SetSystemDnsResolver(
    mojo::PendingRemote<mojom::SystemDnsResolver> override_remote) {}

void NetworkService::StartNetLog(base::File file,
                                 uint64_t max_total_size,
                                 net::NetLogCaptureMode capture_mode,
                                 base::Value::Dict constants) {}

void NetworkService::AttachNetLogProxy(
    mojo::PendingRemote<mojom::NetLogProxySource> proxy_source,
    mojo::PendingReceiver<mojom::NetLogProxySink> proxy_sink) {}

void NetworkService::SetSSLKeyLogFile(base::File file) {}

void NetworkService::CreateNetworkContext(
    mojo::PendingReceiver<mojom::NetworkContext> receiver,
    mojom::NetworkContextParamsPtr params) {}

void NetworkService::ConfigureStubHostResolver(
    bool insecure_dns_client_enabled,
    net::SecureDnsMode secure_dns_mode,
    const net::DnsOverHttpsConfig& dns_over_https_config,
    bool additional_dns_types_enabled) {}

void NetworkService::DisableQuic() {}

void NetworkService::SetUpHttpAuth(
    mojom::HttpAuthStaticParamsPtr http_auth_static_params) {}

void NetworkService::ConfigureHttpAuthPrefs(
    mojom::HttpAuthDynamicParamsPtr http_auth_dynamic_params) {}

void NetworkService::SetRawHeadersAccess(
    int32_t process_id,
    const std::vector<url::Origin>& origins) {}

void NetworkService::SetMaxConnectionsPerProxyChain(int32_t max_connections) {}

bool NetworkService::HasRawHeadersAccess(int32_t process_id,
                                         const GURL& resource_url) const {}

net::NetLog* NetworkService::net_log() const {}

void NetworkService::GetNetworkChangeManager(
    mojo::PendingReceiver<mojom::NetworkChangeManager> receiver) {}

void NetworkService::GetNetworkQualityEstimatorManager(
    mojo::PendingReceiver<mojom::NetworkQualityEstimatorManager> receiver) {}

void NetworkService::GetDnsConfigChangeManager(
    mojo::PendingReceiver<mojom::DnsConfigChangeManager> receiver) {}

void NetworkService::GetNetworkList(
    uint32_t policy,
    mojom::NetworkService::GetNetworkListCallback callback) {}

void NetworkService::OnTrustStoreChanged() {}

void NetworkService::OnClientCertStoreChanged() {}

void NetworkService::SetEncryptionKey(const std::string& encryption_key) {}

void NetworkService::OnMemoryPressure(
    base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level) {}

void NetworkService::OnPeerToPeerConnectionsCountChange(uint32_t count) {}

#if BUILDFLAG(IS_ANDROID)
void NetworkService::OnApplicationStateChange(
    base::android::ApplicationState state) {
  for (NetworkContext* network_context : network_contexts_) {
    for (auto const& listener : network_context->app_status_listeners()) {
      listener->Notify(state);
    }
  }
}
#endif

void NetworkService::SetEnvironment(
    std::vector<mojom::EnvironmentVariablePtr> environment) {}

void NetworkService::SetTrustTokenKeyCommitments(
    const std::string& raw_commitments,
    base::OnceClosure done) {}

void NetworkService::ParseHeaders(
    const GURL& url,
    const scoped_refptr<net::HttpResponseHeaders>& headers,
    ParseHeadersCallback callback) {}

void NetworkService::EnableDataUseUpdates(bool enable) {}

void NetworkService::SetIPv6ReachabilityOverride(bool reachability_override) {}

#if BUILDFLAG(IS_CT_SUPPORTED)
void NetworkService::ClearSCTAuditingCache() {}

void NetworkService::ConfigureSCTAuditing(
    mojom::SCTAuditingConfigurationPtr configuration) {}

void NetworkService::UpdateCtLogList(std::vector<mojom::CTLogInfoPtr> log_list,
                                     UpdateCtLogListCallback callback) {}

void NetworkService::UpdateCtKnownPopularSCTs(
    const std::vector<std::vector<uint8_t>>& sct_hashes,
    UpdateCtLogListCallback callback) {}

void NetworkService::SetCtEnforcementEnabled(
    bool enabled,
    SetCtEnforcementEnabledCallback callback) {}

#endif  // BUILDFLAG(IS_CT_SUPPORTED)

void NetworkService::UpdateKeyPinsList(mojom::PinListPtr pin_list,
                                       base::Time update_time) {}

void NetworkService::UpdateMaskedDomainList(
    mojo_base::ProtoWrapper masked_domain_list,
    const std::vector<std::string>& exclusion_list) {}

#if BUILDFLAG(IS_ANDROID)
void NetworkService::DumpWithoutCrashing(base::Time dump_request_time) {
  static base::debug::CrashKeyString* time_key =
      base::debug::AllocateCrashKeyString("time_since_dump_request_ms",
                                          base::debug::CrashKeySize::Size32);
  base::debug::ScopedCrashKeyString scoped_time(
      time_key, base::NumberToString(
                    (base::Time::Now() - dump_request_time).InMilliseconds()));
  base::debug::DumpWithoutCrashing();
}
#endif

void NetworkService::BindTestInterfaceForTesting(
    mojo::PendingReceiver<mojom::NetworkServiceTest> receiver) {}

void NetworkService::SetFirstPartySets(net::GlobalFirstPartySets sets) {}

void NetworkService::SetExplicitlyAllowedPorts(
    const std::vector<uint16_t>& ports) {}

#if BUILDFLAG(IS_LINUX)
void NetworkService::SetGssapiLibraryLoadObserver(
    mojo::PendingRemote<mojom::GssapiLibraryLoadObserver>
        gssapi_library_load_observer) {}
#endif  // BUILDFLAG(IS_LINUX)

void NetworkService::StartNetLogBounded(base::File file,
                                        uint64_t max_total_size,
                                        net::NetLogCaptureMode capture_mode,
                                        base::Value::Dict client_constants) {}

void NetworkService::OnStartNetLogBoundedScratchDirectoryCreated(
    base::File file,
    uint64_t max_total_size,
    net::NetLogCaptureMode capture_mode,
    base::Value::Dict constants,
    const base::FilePath& in_progress_dir_path) {}

void NetworkService::StartNetLogUnbounded(base::File file,
                                          net::NetLogCaptureMode capture_mode,
                                          base::Value::Dict client_constants) {}

std::unique_ptr<net::HttpAuthHandlerFactory>
NetworkService::CreateHttpAuthHandlerFactory(NetworkContext* network_context) {}

#if BUILDFLAG(IS_LINUX)
void NetworkService::OnBeforeGssapiLibraryLoad() {}
#endif  // BUILDFLAG(IS_LINUX)

void NetworkService::InitMockNetworkChangeNotifierForTesting() {}

void NetworkService::DestroyNetworkContexts() {}

void NetworkService::OnNetworkContextConnectionClosed(
    NetworkContext* network_context) {}

void NetworkService::Bind(
    mojo::PendingReceiver<mojom::NetworkService> receiver) {}

mojom::URLLoaderNetworkServiceObserver*
NetworkService::GetDefaultURLLoaderNetworkServiceObserver() {}

// static
NetworkService* NetworkService::GetNetworkServiceForTesting() {}

void NetworkService::SetTpcdMetadataGrants(
    const std::vector<ContentSettingPatternSource>& settings) {}
}  // namespace network