1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "services/network/network_service.h"
6 
7 #include <map>
8 #include <utility>
9 #include <vector>
10 
11 #include "base/bind.h"
12 #include "base/command_line.h"
13 #include "base/debug/crash_logging.h"
14 #include "base/debug/dump_without_crashing.h"
15 #include "base/environment.h"
16 #include "base/feature_list.h"
17 #include "base/logging.h"
18 #include "base/memory/ptr_util.h"
19 #include "base/metrics/histogram_macros.h"
20 #include "base/numerics/ranges.h"
21 #include "base/stl_util.h"
22 #include "base/task/post_task.h"
23 #include "base/task/thread_pool.h"
24 #include "base/timer/timer.h"
25 #include "base/values.h"
26 #include "build/chromecast_buildflags.h"
27 #include "components/network_session_configurator/common/network_features.h"
28 #include "components/os_crypt/os_crypt.h"
29 #include "mojo/core/embedder/embedder.h"
30 #include "mojo/public/cpp/bindings/scoped_message_error_crash_key.h"
31 #include "net/base/logging_network_change_observer.h"
32 #include "net/base/network_change_notifier.h"
33 #include "net/base/network_change_notifier_posix.h"
34 #include "net/base/port_util.h"
35 #include "net/cert/cert_database.h"
36 #include "net/cert/ct_log_response_parser.h"
37 #include "net/cert/signed_tree_head.h"
38 #include "net/dns/dns_config_overrides.h"
39 #include "net/dns/host_resolver.h"
40 #include "net/dns/host_resolver_manager.h"
41 #include "net/http/http_auth_handler_factory.h"
42 #include "net/log/file_net_log_observer.h"
43 #include "net/log/net_log.h"
44 #include "net/log/net_log_capture_mode.h"
45 #include "net/log/net_log_util.h"
46 #include "net/nqe/network_quality_estimator.h"
47 #include "net/socket/client_socket_pool_manager.h"
48 #include "net/ssl/ssl_key_logger_impl.h"
49 #include "net/url_request/url_request_context.h"
50 #include "services/network/crl_set_distributor.h"
51 #include "services/network/cross_origin_read_blocking.h"
52 #include "services/network/dns_config_change_manager.h"
53 #include "services/network/http_auth_cache_copier.h"
54 #include "services/network/legacy_tls_config_distributor.h"
55 #include "services/network/net_log_exporter.h"
56 #include "services/network/net_log_proxy_sink.h"
57 #include "services/network/network_context.h"
58 #include "services/network/network_usage_accumulator.h"
59 #include "services/network/public/cpp/features.h"
60 #include "services/network/public/cpp/initiator_lock_compatibility.h"
61 #include "services/network/public/cpp/load_info_util.h"
62 #include "services/network/public/cpp/network_switches.h"
63 #include "services/network/url_loader.h"
64 
65 #if defined(OS_ANDROID) && defined(ARCH_CPU_ARMEL)
66 #include "crypto/openssl_util.h"
67 #include "third_party/boringssl/src/include/openssl/cpu.h"
68 #endif
69 
70 #if (defined(OS_LINUX) || defined(OS_BSD)) && !defined(OS_CHROMEOS) && !BUILDFLAG(IS_CHROMECAST)
71 #include "components/os_crypt/key_storage_config_linux.h"
72 #endif
73 
74 #if defined(OS_ANDROID)
75 #include "base/android/application_status_listener.h"
76 #include "net/android/http_auth_negotiate_android.h"
77 #endif
78 
79 namespace network {
80 
81 namespace {
82 
83 NetworkService* g_network_service = nullptr;
84 
85 // The interval for calls to NetworkService::UpdateLoadStates
86 constexpr auto kUpdateLoadStatesInterval =
87     base::TimeDelta::FromMilliseconds(250);
88 
CreateNetworkChangeNotifierIfNeeded(net::NetworkChangeNotifier::ConnectionType initial_connection_type,net::NetworkChangeNotifier::ConnectionSubtype initial_connection_subtype,bool mock_network_change_notifier)89 std::unique_ptr<net::NetworkChangeNotifier> CreateNetworkChangeNotifierIfNeeded(
90     net::NetworkChangeNotifier::ConnectionType initial_connection_type,
91     net::NetworkChangeNotifier::ConnectionSubtype initial_connection_subtype,
92     bool mock_network_change_notifier) {
93   // There is a global singleton net::NetworkChangeNotifier if NetworkService
94   // is running inside of the browser process.
95   if (mock_network_change_notifier)
96     return net::NetworkChangeNotifier::CreateMockIfNeeded();
97   return net::NetworkChangeNotifier::CreateIfNeeded(initial_connection_type,
98                                                     initial_connection_subtype);
99 }
100 
OnGetNetworkList(std::unique_ptr<net::NetworkInterfaceList> networks,mojom::NetworkService::GetNetworkListCallback callback,bool success)101 void OnGetNetworkList(std::unique_ptr<net::NetworkInterfaceList> networks,
102                       mojom::NetworkService::GetNetworkListCallback callback,
103                       bool success) {
104   if (success) {
105     std::move(callback).Run(*networks);
106   } else {
107     std::move(callback).Run(base::nullopt);
108   }
109 }
110 
111 #if defined(OS_ANDROID) && BUILDFLAG(USE_KERBEROS)
112 // Used for Negotiate authentication on Android, which needs to generate tokens
113 // in the browser process.
114 class NetworkServiceAuthNegotiateAndroid : public net::HttpAuthMechanism {
115  public:
NetworkServiceAuthNegotiateAndroid(NetworkContext * network_context,const net::HttpAuthPreferences * prefs)116   NetworkServiceAuthNegotiateAndroid(NetworkContext* network_context,
117                                      const net::HttpAuthPreferences* prefs)
118       : network_context_(network_context), auth_negotiate_(prefs) {}
119   ~NetworkServiceAuthNegotiateAndroid() override = default;
120 
121   // HttpAuthMechanism implementation:
Init(const net::NetLogWithSource & net_log)122   bool Init(const net::NetLogWithSource& net_log) override {
123     return auth_negotiate_.Init(net_log);
124   }
125 
NeedsIdentity() const126   bool NeedsIdentity() const override {
127     return auth_negotiate_.NeedsIdentity();
128   }
129 
AllowsExplicitCredentials() const130   bool AllowsExplicitCredentials() const override {
131     return auth_negotiate_.AllowsExplicitCredentials();
132   }
133 
ParseChallenge(net::HttpAuthChallengeTokenizer * tok)134   net::HttpAuth::AuthorizationResult ParseChallenge(
135       net::HttpAuthChallengeTokenizer* tok) override {
136     return auth_negotiate_.ParseChallenge(tok);
137   }
138 
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)139   int GenerateAuthToken(const net::AuthCredentials* credentials,
140                         const std::string& spn,
141                         const std::string& channel_bindings,
142                         std::string* auth_token,
143                         const net::NetLogWithSource& net_log,
144                         net::CompletionOnceCallback callback) override {
145     network_context_->client()->OnGenerateHttpNegotiateAuthToken(
146         auth_negotiate_.server_auth_token(), auth_negotiate_.can_delegate(),
147         auth_negotiate_.GetAuthAndroidNegotiateAccountType(), spn,
148         base::BindOnce(&NetworkServiceAuthNegotiateAndroid::Finish,
149                        weak_factory_.GetWeakPtr(), auth_token,
150                        std::move(callback)));
151     return net::ERR_IO_PENDING;
152   }
153 
SetDelegation(net::HttpAuth::DelegationType delegation_type)154   void SetDelegation(net::HttpAuth::DelegationType delegation_type) override {
155     auth_negotiate_.SetDelegation(delegation_type);
156   }
157 
158  private:
Finish(std::string * auth_token_out,net::CompletionOnceCallback callback,int result,const std::string & auth_token)159   void Finish(std::string* auth_token_out,
160               net::CompletionOnceCallback callback,
161               int result,
162               const std::string& auth_token) {
163     *auth_token_out = auth_token;
164     std::move(callback).Run(result);
165   }
166 
167   NetworkContext* network_context_ = nullptr;
168   net::android::HttpAuthNegotiateAndroid auth_negotiate_;
169   base::WeakPtrFactory<NetworkServiceAuthNegotiateAndroid> weak_factory_{this};
170 };
171 
CreateAuthSystem(NetworkContext * network_context,const net::HttpAuthPreferences * prefs)172 std::unique_ptr<net::HttpAuthMechanism> CreateAuthSystem(
173     NetworkContext* network_context,
174     const net::HttpAuthPreferences* prefs) {
175   return std::make_unique<NetworkServiceAuthNegotiateAndroid>(network_context,
176                                                               prefs);
177 }
178 #endif
179 
180 // Called when NetworkService received a bad IPC message (but only when
181 // NetworkService is running in a separate process - otherwise the existing bad
182 // message handling inside the Browser process is sufficient).
HandleBadMessage(const std::string & error)183 void HandleBadMessage(const std::string& error) {
184   LOG(WARNING) << "Mojo error in NetworkService:" << error;
185   mojo::debug::ScopedMessageErrorCrashKey crash_key_value(error);
186   base::debug::DumpWithoutCrashing();
187 }
188 
189 }  // namespace
190 
191 // static
192 const base::TimeDelta NetworkService::kInitialDohProbeTimeout =
193     base::TimeDelta::FromSeconds(5);
194 
195 // Handler of delaying calls to NetworkContext::ActivateDohProbes() until after
196 // an initial service startup delay.
197 class NetworkService::DelayedDohProbeActivator {
198  public:
DelayedDohProbeActivator(NetworkService * network_service)199   explicit DelayedDohProbeActivator(NetworkService* network_service)
200       : network_service_(network_service) {
201     DCHECK(network_service_);
202 
203     // Delay initial DoH probes to prevent interference with startup tasks.
204     doh_probes_timer_.Start(
205         FROM_HERE, NetworkService::kInitialDohProbeTimeout,
206         base::BindOnce(&DelayedDohProbeActivator::ActivateAllDohProbes,
207                        base::Unretained(this)));
208   }
209 
210   DelayedDohProbeActivator(const DelayedDohProbeActivator&) = delete;
211   DelayedDohProbeActivator& operator=(const DelayedDohProbeActivator&) = delete;
212 
213   // Activates DoH probes for |network_context| iff the initial startup delay
214   // has expired. Intended to be called on registration of contexts to activate
215   // probes for contexts created and registered after the initial delay has
216   // expired.
MaybeActivateDohProbes(NetworkContext * network_context)217   void MaybeActivateDohProbes(NetworkContext* network_context) {
218     // If timer is still running, probes will be started on completion.
219     if (doh_probes_timer_.IsRunning())
220       return;
221 
222     network_context->ActivateDohProbes();
223   }
224 
225   // Attempts to activate DoH probes for all contexts registered with the
226   // service. Intended to be called on expiration of |doh_probes_timer_| to
227   // activate probes for contexts registered during the initial delay.
ActivateAllDohProbes()228   void ActivateAllDohProbes() {
229     for (auto* network_context : network_service_->network_contexts_) {
230       MaybeActivateDohProbes(network_context);
231     }
232   }
233 
234  private:
235   NetworkService* const network_service_;
236 
237   // If running, DoH probes will be started on completion. If not running, DoH
238   // probes may be started at any time.
239   base::OneShotTimer doh_probes_timer_;
240 };
241 
NetworkService(std::unique_ptr<service_manager::BinderRegistry> registry,mojo::PendingReceiver<mojom::NetworkService> receiver,bool delay_initialization_until_set_client)242 NetworkService::NetworkService(
243     std::unique_ptr<service_manager::BinderRegistry> registry,
244     mojo::PendingReceiver<mojom::NetworkService> receiver,
245     bool delay_initialization_until_set_client)
246     : net_log_(net::NetLog::Get()), registry_(std::move(registry)) {
247   DCHECK(!g_network_service);
248   g_network_service = this;
249 
250   // |registry_| is nullptr when an in-process NetworkService is
251   // created directly, like in most unit tests.
252   if (registry_) {
253     mojo::core::SetDefaultProcessErrorCallback(
254         base::BindRepeating(&HandleBadMessage));
255   }
256 
257   if (receiver.is_valid())
258     Bind(std::move(receiver));
259 
260   if (!delay_initialization_until_set_client)
261     Initialize(mojom::NetworkServiceParams::New());
262 }
263 
Initialize(mojom::NetworkServiceParamsPtr params,bool mock_network_change_notifier)264 void NetworkService::Initialize(mojom::NetworkServiceParamsPtr params,
265                                 bool mock_network_change_notifier) {
266   if (initialized_)
267     return;
268 
269   initialized_ = true;
270 
271 #if defined(OS_ANDROID) && defined(ARCH_CPU_ARMEL)
272   // Make sure OpenSSL is initialized before using it to histogram data.
273   crypto::EnsureOpenSSLInit();
274 
275   // Measure CPUs with broken NEON units. See https://crbug.com/341598.
276   UMA_HISTOGRAM_BOOLEAN("Net.HasBrokenNEON", CRYPTO_has_broken_NEON());
277   // Measure Android kernels with missing AT_HWCAP2 auxv fields. See
278   // https://crbug.com/boringssl/46.
279   UMA_HISTOGRAM_BOOLEAN("Net.NeedsHWCAP2Workaround",
280                         CRYPTO_needs_hwcap2_workaround());
281 #endif
282 
283   if (!params->environment.empty())
284     SetEnvironment(std::move(params->environment));
285 
286   base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
287 
288   // Set-up the global port overrides.
289   if (command_line->HasSwitch(switches::kExplicitlyAllowedPorts)) {
290     std::string allowed_ports =
291         command_line->GetSwitchValueASCII(switches::kExplicitlyAllowedPorts);
292     net::SetExplicitlyAllowedPorts(allowed_ports);
293   }
294 
295   // Record this once per session, though the switch is appled on a
296   // per-NetworkContext basis.
297   UMA_HISTOGRAM_BOOLEAN(
298       "Net.Certificate.IgnoreCertificateErrorsSPKIListPresent",
299       command_line->HasSwitch(switches::kIgnoreCertificateErrorsSPKIList));
300 
301   network_change_manager_ = std::make_unique<NetworkChangeManager>(
302       CreateNetworkChangeNotifierIfNeeded(
303           net::NetworkChangeNotifier::ConnectionType(
304               params->initial_connection_type),
305           net::NetworkChangeNotifier::ConnectionSubtype(
306               params->initial_connection_subtype),
307           mock_network_change_notifier));
308 
309   trace_net_log_observer_.WatchForTraceStart(net_log_);
310 
311   // Add an observer that will emit network change events to |net_log_|.
312   // Assuming NetworkChangeNotifier dispatches in FIFO order, we should be
313   // logging the network change before other IO thread consumers respond to it.
314   network_change_observer_ =
315       std::make_unique<net::LoggingNetworkChangeObserver>(net_log_);
316 
317   network_quality_estimator_manager_ =
318       std::make_unique<NetworkQualityEstimatorManager>(net_log_);
319 
320   dns_config_change_manager_ = std::make_unique<DnsConfigChangeManager>();
321 
322   host_resolver_manager_ = std::make_unique<net::HostResolverManager>(
323       net::HostResolver::ManagerOptions(),
324       net::NetworkChangeNotifier::GetSystemDnsConfigNotifier(), net_log_);
325   host_resolver_factory_ = std::make_unique<net::HostResolver::Factory>();
326 
327   network_usage_accumulator_ = std::make_unique<NetworkUsageAccumulator>();
328 
329   http_auth_cache_copier_ = std::make_unique<HttpAuthCacheCopier>();
330 
331   crl_set_distributor_ = std::make_unique<CRLSetDistributor>();
332 
333   legacy_tls_config_distributor_ =
334       std::make_unique<LegacyTLSConfigDistributor>();
335 
336   doh_probe_activator_ = std::make_unique<DelayedDohProbeActivator>(this);
337 
338   trust_token_key_commitments_ = std::make_unique<TrustTokenKeyCommitments>();
339 }
340 
~NetworkService()341 NetworkService::~NetworkService() {
342   DCHECK_EQ(this, g_network_service);
343 
344   doh_probe_activator_.reset();
345 
346   g_network_service = nullptr;
347   // Destroy owned network contexts.
348   DestroyNetworkContexts();
349 
350   // All NetworkContexts (Owned and unowned) must have been deleted by this
351   // point.
352   DCHECK(network_contexts_.empty());
353 
354   if (file_net_log_observer_) {
355     file_net_log_observer_->StopObserving(nullptr /*polled_data*/,
356                                           base::OnceClosure());
357   }
358 
359   if (initialized_)
360     trace_net_log_observer_.StopWatchForTraceStart();
361 }
362 
set_os_crypt_is_configured()363 void NetworkService::set_os_crypt_is_configured() {
364   os_crypt_config_set_ = true;
365 }
366 
Create(mojo::PendingReceiver<mojom::NetworkService> receiver)367 std::unique_ptr<NetworkService> NetworkService::Create(
368     mojo::PendingReceiver<mojom::NetworkService> receiver) {
369   return std::make_unique<NetworkService>(nullptr, std::move(receiver));
370 }
371 
CreateForTesting()372 std::unique_ptr<NetworkService> NetworkService::CreateForTesting() {
373   return std::make_unique<NetworkService>(
374       std::make_unique<service_manager::BinderRegistry>());
375 }
376 
RegisterNetworkContext(NetworkContext * network_context)377 void NetworkService::RegisterNetworkContext(NetworkContext* network_context) {
378 #ifndef TOOLKIT_QT
379   // If IsPrimaryNetworkContext() is true, there must be no other
380   // NetworkContexts created yet.
381   DCHECK(!network_context->IsPrimaryNetworkContext() ||
382          network_contexts_.empty());
383 #endif
384 
385   DCHECK_EQ(0u, network_contexts_.count(network_context));
386   network_contexts_.insert(network_context);
387   if (quic_disabled_)
388     network_context->DisableQuic();
389 
390   // The params may already be present, so we propagate it
391   // to this new network_context. When params gets changed
392   // via ConfigureHttpAuthPrefs method, we propagate the change
393   // to all NetworkContexts in |network_contexts_|
394   if (http_auth_dynamic_network_service_params_) {
395     network_context->OnHttpAuthDynamicParamsChanged(
396         http_auth_dynamic_network_service_params_.get());
397   }
398 
399   if (doh_probe_activator_)
400     doh_probe_activator_->MaybeActivateDohProbes(network_context);
401 }
402 
DeregisterNetworkContext(NetworkContext * network_context)403 void NetworkService::DeregisterNetworkContext(NetworkContext* network_context) {
404 #ifndef TOOLKIT_QT
405   // If the NetworkContext is the primary network context, all other
406   // NetworkContexts must already have been destroyed.
407   DCHECK(!network_context->IsPrimaryNetworkContext() ||
408          network_contexts_.size() == 1);
409 #endif
410 
411   DCHECK_EQ(1u, network_contexts_.count(network_context));
412   network_contexts_.erase(network_context);
413 }
414 
415 #if defined(OS_CHROMEOS)
ReinitializeLogging(mojom::LoggingSettingsPtr settings)416 void NetworkService::ReinitializeLogging(mojom::LoggingSettingsPtr settings) {
417   logging::LoggingSettings logging_settings;
418   logging_settings.logging_dest = settings->logging_dest;
419   base::ScopedFD log_file_descriptor = settings->log_file_descriptor.TakeFD();
420   logging_settings.log_file = fdopen(log_file_descriptor.release(), "a");
421   if (!logging_settings.log_file) {
422     LOG(ERROR) << "Failed to open new log file handle";
423     return;
424   }
425   if (!logging::InitLogging(logging_settings))
426     LOG(ERROR) << "Unable to reinitialize logging";
427 }
428 #endif
429 
CreateNetLogEntriesForActiveObjects(net::NetLog::ThreadSafeObserver * observer)430 void NetworkService::CreateNetLogEntriesForActiveObjects(
431     net::NetLog::ThreadSafeObserver* observer) {
432   std::set<net::URLRequestContext*> contexts;
433   for (NetworkContext* nc : network_contexts_)
434     contexts.insert(nc->url_request_context());
435   return net::CreateNetLogEntriesForActiveObjects(contexts, observer);
436 }
437 
SetClient(mojo::PendingRemote<mojom::NetworkServiceClient> client,mojom::NetworkServiceParamsPtr params)438 void NetworkService::SetClient(
439     mojo::PendingRemote<mojom::NetworkServiceClient> client,
440     mojom::NetworkServiceParamsPtr params) {
441   client_.Bind(std::move(client));
442   Initialize(std::move(params));
443 }
444 
StartNetLog(base::File file,net::NetLogCaptureMode capture_mode,base::Value client_constants)445 void NetworkService::StartNetLog(base::File file,
446                                  net::NetLogCaptureMode capture_mode,
447                                  base::Value client_constants) {
448   DCHECK(client_constants.is_dict());
449   std::unique_ptr<base::DictionaryValue> constants = net::GetNetConstants();
450   constants->MergeDictionary(&client_constants);
451 
452   file_net_log_observer_ = net::FileNetLogObserver::CreateUnboundedPreExisting(
453       std::move(file), std::move(constants));
454   file_net_log_observer_->StartObserving(net_log_, capture_mode);
455 }
456 
AttachNetLogProxy(mojo::PendingRemote<mojom::NetLogProxySource> proxy_source,mojo::PendingReceiver<mojom::NetLogProxySink> proxy_sink)457 void NetworkService::AttachNetLogProxy(
458     mojo::PendingRemote<mojom::NetLogProxySource> proxy_source,
459     mojo::PendingReceiver<mojom::NetLogProxySink> proxy_sink) {
460   if (!net_log_proxy_sink_)
461     net_log_proxy_sink_ = std::make_unique<NetLogProxySink>();
462   net_log_proxy_sink_->AttachSource(std::move(proxy_source),
463                                     std::move(proxy_sink));
464 }
465 
SetSSLKeyLogFile(base::File file)466 void NetworkService::SetSSLKeyLogFile(base::File file) {
467   net::SSLClientSocket::SetSSLKeyLogger(
468       std::make_unique<net::SSLKeyLoggerImpl>(std::move(file)));
469 }
470 
CreateNetworkContext(mojo::PendingReceiver<mojom::NetworkContext> receiver,mojom::NetworkContextParamsPtr params)471 void NetworkService::CreateNetworkContext(
472     mojo::PendingReceiver<mojom::NetworkContext> receiver,
473     mojom::NetworkContextParamsPtr params) {
474 #ifndef TOOLKIT_QT
475   // Only the first created NetworkContext can have |primary_next_context| set
476   // to true.
477   DCHECK(!params->primary_network_context || network_contexts_.empty());
478 #endif
479 
480   owned_network_contexts_.emplace(std::make_unique<NetworkContext>(
481       this, std::move(receiver), std::move(params),
482       base::BindOnce(&NetworkService::OnNetworkContextConnectionClosed,
483                      base::Unretained(this))));
484 }
485 
ConfigureStubHostResolver(bool insecure_dns_client_enabled,net::DnsConfig::SecureDnsMode secure_dns_mode,base::Optional<std::vector<mojom::DnsOverHttpsServerPtr>> dns_over_https_servers)486 void NetworkService::ConfigureStubHostResolver(
487     bool insecure_dns_client_enabled,
488     net::DnsConfig::SecureDnsMode secure_dns_mode,
489     base::Optional<std::vector<mojom::DnsOverHttpsServerPtr>>
490         dns_over_https_servers) {
491   DCHECK(!dns_over_https_servers || !dns_over_https_servers->empty());
492 
493   // Enable or disable the insecure part of DnsClient. "DnsClient" is the class
494   // that implements the stub resolver.
495   host_resolver_manager_->SetInsecureDnsClientEnabled(
496       insecure_dns_client_enabled);
497 
498   // Configure DNS over HTTPS.
499   net::DnsConfigOverrides overrides;
500   if (dns_over_https_servers && !dns_over_https_servers.value().empty()) {
501     overrides.dns_over_https_servers.emplace();
502     for (const auto& doh_server : *dns_over_https_servers) {
503       overrides.dns_over_https_servers.value().emplace_back(
504           doh_server->server_template, doh_server->use_post);
505     }
506   }
507   overrides.secure_dns_mode = secure_dns_mode;
508   overrides.allow_dns_over_https_upgrade =
509       base::FeatureList::IsEnabled(features::kDnsOverHttpsUpgrade);
510   overrides.disabled_upgrade_providers =
511       SplitString(features::kDnsOverHttpsUpgradeDisabledProvidersParam.Get(),
512                   ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
513   host_resolver_manager_->SetDnsConfigOverrides(overrides);
514 }
515 
DisableQuic()516 void NetworkService::DisableQuic() {
517   quic_disabled_ = true;
518 
519   for (auto* network_context : network_contexts_) {
520     network_context->DisableQuic();
521   }
522 }
523 
SetUpHttpAuth(mojom::HttpAuthStaticParamsPtr http_auth_static_params)524 void NetworkService::SetUpHttpAuth(
525     mojom::HttpAuthStaticParamsPtr http_auth_static_params) {
526   DCHECK(!http_auth_static_network_service_params_);
527   DCHECK(network_contexts_.empty());
528   http_auth_static_network_service_params_ = std::move(http_auth_static_params);
529 }
530 
ConfigureHttpAuthPrefs(mojom::HttpAuthDynamicParamsPtr http_auth_dynamic_params)531 void NetworkService::ConfigureHttpAuthPrefs(
532     mojom::HttpAuthDynamicParamsPtr http_auth_dynamic_params) {
533   // We need to store it as a member variable because the method
534   // NetworkService::RegisterNetworkContext(NetworkContext *network_context)
535   // uses it to populate the HttpAuthPreferences of the incoming network_context
536   // with the latest dynamic params of the NetworkService.
537   http_auth_dynamic_network_service_params_ =
538       std::move(http_auth_dynamic_params);
539 
540   for (NetworkContext* network_context : network_contexts_) {
541     network_context->OnHttpAuthDynamicParamsChanged(
542         http_auth_dynamic_network_service_params_.get());
543   }
544 }
545 
SetRawHeadersAccess(int32_t process_id,const std::vector<url::Origin> & origins)546 void NetworkService::SetRawHeadersAccess(
547     int32_t process_id,
548     const std::vector<url::Origin>& origins) {
549   DCHECK(process_id);
550   if (!origins.size()) {
551     raw_headers_access_origins_by_pid_.erase(process_id);
552   } else {
553     raw_headers_access_origins_by_pid_[process_id] =
554         base::flat_set<url::Origin>(origins.begin(), origins.end());
555   }
556 }
557 
SetMaxConnectionsPerProxy(int32_t max_connections)558 void NetworkService::SetMaxConnectionsPerProxy(int32_t max_connections) {
559   int new_limit = max_connections;
560   if (new_limit < 0)
561     new_limit = net::kDefaultMaxSocketsPerProxyServer;
562 
563   // Clamp the value between min_limit and max_limit.
564   int max_limit = 99;
565   int min_limit = net::ClientSocketPoolManager::max_sockets_per_group(
566       net::HttpNetworkSession::NORMAL_SOCKET_POOL);
567   new_limit = base::ClampToRange(new_limit, min_limit, max_limit);
568 
569   // Assign the global limit.
570   net::ClientSocketPoolManager::set_max_sockets_per_proxy_server(
571       net::HttpNetworkSession::NORMAL_SOCKET_POOL, new_limit);
572 }
573 
HasRawHeadersAccess(int32_t process_id,const GURL & resource_url) const574 bool NetworkService::HasRawHeadersAccess(int32_t process_id,
575                                          const GURL& resource_url) const {
576   // Allow raw headers for browser-initiated requests.
577   if (!process_id)
578     return true;
579   auto it = raw_headers_access_origins_by_pid_.find(process_id);
580   if (it == raw_headers_access_origins_by_pid_.end())
581     return false;
582   return it->second.find(url::Origin::Create(resource_url)) != it->second.end();
583 }
584 
net_log() const585 net::NetLog* NetworkService::net_log() const {
586   return net_log_;
587 }
588 
GetNetworkChangeManager(mojo::PendingReceiver<mojom::NetworkChangeManager> receiver)589 void NetworkService::GetNetworkChangeManager(
590     mojo::PendingReceiver<mojom::NetworkChangeManager> receiver) {
591   network_change_manager_->AddReceiver(std::move(receiver));
592 }
593 
GetNetworkQualityEstimatorManager(mojo::PendingReceiver<mojom::NetworkQualityEstimatorManager> receiver)594 void NetworkService::GetNetworkQualityEstimatorManager(
595     mojo::PendingReceiver<mojom::NetworkQualityEstimatorManager> receiver) {
596   network_quality_estimator_manager_->AddReceiver(std::move(receiver));
597 }
598 
GetDnsConfigChangeManager(mojo::PendingReceiver<mojom::DnsConfigChangeManager> receiver)599 void NetworkService::GetDnsConfigChangeManager(
600     mojo::PendingReceiver<mojom::DnsConfigChangeManager> receiver) {
601   dns_config_change_manager_->AddReceiver(std::move(receiver));
602 }
603 
GetTotalNetworkUsages(mojom::NetworkService::GetTotalNetworkUsagesCallback callback)604 void NetworkService::GetTotalNetworkUsages(
605     mojom::NetworkService::GetTotalNetworkUsagesCallback callback) {
606   std::move(callback).Run(network_usage_accumulator_->GetTotalNetworkUsages());
607 }
608 
GetNetworkList(uint32_t policy,mojom::NetworkService::GetNetworkListCallback callback)609 void NetworkService::GetNetworkList(
610     uint32_t policy,
611     mojom::NetworkService::GetNetworkListCallback callback) {
612   auto networks = std::make_unique<net::NetworkInterfaceList>();
613   auto* raw_networks = networks.get();
614   // net::GetNetworkList may block depending on platform.
615   base::ThreadPool::PostTaskAndReplyWithResult(
616       FROM_HERE, {base::MayBlock()},
617       base::BindOnce(&net::GetNetworkList, raw_networks, policy),
618       base::BindOnce(&OnGetNetworkList, std::move(networks),
619                      std::move(callback)));
620 }
621 
UpdateCRLSet(base::span<const uint8_t> crl_set,mojom::NetworkService::UpdateCRLSetCallback callback)622 void NetworkService::UpdateCRLSet(
623     base::span<const uint8_t> crl_set,
624     mojom::NetworkService::UpdateCRLSetCallback callback) {
625   crl_set_distributor_->OnNewCRLSet(crl_set, std::move(callback));
626 }
627 
UpdateLegacyTLSConfig(base::span<const uint8_t> config,mojom::NetworkService::UpdateLegacyTLSConfigCallback callback)628 void NetworkService::UpdateLegacyTLSConfig(
629     base::span<const uint8_t> config,
630     mojom::NetworkService::UpdateLegacyTLSConfigCallback callback) {
631   legacy_tls_config_distributor_->OnNewLegacyTLSConfig(config,
632                                                        std::move(callback));
633 }
634 
OnCertDBChanged()635 void NetworkService::OnCertDBChanged() {
636   net::CertDatabase::GetInstance()->NotifyObserversCertDBChanged();
637 }
638 
639 #if (defined(OS_LINUX) && !defined(OS_CHROMEOS)) || defined(OS_BSD)
SetCryptConfig(mojom::CryptConfigPtr crypt_config)640 void NetworkService::SetCryptConfig(mojom::CryptConfigPtr crypt_config) {
641 #if !BUILDFLAG(IS_CHROMECAST) && !defined(TOOLKIT_QT)
642   DCHECK(!os_crypt_config_set_);
643   auto config = std::make_unique<os_crypt::Config>();
644   config->store = crypt_config->store;
645   config->product_name = crypt_config->product_name;
646   config->main_thread_runner = base::ThreadTaskRunnerHandle::Get();
647   config->should_use_preference = crypt_config->should_use_preference;
648   config->user_data_path = crypt_config->user_data_path;
649   OSCrypt::SetConfig(std::move(config));
650   os_crypt_config_set_ = true;
651 #endif
652 }
653 #endif
654 
655 #if defined(OS_WIN) || (defined(OS_MACOSX) && !defined(OS_IOS))
SetEncryptionKey(const std::string & encryption_key)656 void NetworkService::SetEncryptionKey(const std::string& encryption_key) {
657   OSCrypt::SetRawEncryptionKey(encryption_key);
658 }
659 #endif
660 
AddCorbExceptionForPlugin(int32_t process_id)661 void NetworkService::AddCorbExceptionForPlugin(int32_t process_id) {
662   DCHECK_NE(mojom::kBrowserProcessId, process_id);
663   CrossOriginReadBlocking::AddExceptionForPlugin(process_id);
664 }
665 
AddAllowedRequestInitiatorForPlugin(int32_t process_id,const url::Origin & allowed_request_initiator)666 void NetworkService::AddAllowedRequestInitiatorForPlugin(
667     int32_t process_id,
668     const url::Origin& allowed_request_initiator) {
669   DCHECK_NE(mojom::kBrowserProcessId, process_id);
670   std::map<int, std::set<url::Origin>>& map = plugin_origins_;
671   map[process_id].insert(allowed_request_initiator);
672 }
673 
RemoveSecurityExceptionsForPlugin(int32_t process_id)674 void NetworkService::RemoveSecurityExceptionsForPlugin(int32_t process_id) {
675   DCHECK_NE(mojom::kBrowserProcessId, process_id);
676 
677   CrossOriginReadBlocking::RemoveExceptionForPlugin(process_id);
678 
679   std::map<int, std::set<url::Origin>>& map = plugin_origins_;
680   map.erase(process_id);
681 }
682 
IsInitiatorAllowedForPlugin(int process_id,const url::Origin & request_initiator)683 bool NetworkService::IsInitiatorAllowedForPlugin(
684     int process_id,
685     const url::Origin& request_initiator) {
686   const std::map<int, std::set<url::Origin>>& map = plugin_origins_;
687   const auto it = map.find(process_id);
688   if (it == map.end())
689     return false;
690 
691   const std::set<url::Origin>& allowed_origins = it->second;
692   return base::Contains(allowed_origins, request_initiator);
693 }
694 
OnMemoryPressure(base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level)695 void NetworkService::OnMemoryPressure(
696     base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level) {
697   base::MemoryPressureListener::NotifyMemoryPressure(memory_pressure_level);
698 }
699 
OnPeerToPeerConnectionsCountChange(uint32_t count)700 void NetworkService::OnPeerToPeerConnectionsCountChange(uint32_t count) {
701   network_quality_estimator_manager_->GetNetworkQualityEstimator()
702       ->OnPeerToPeerConnectionsCountChange(count);
703 }
704 
705 #if defined(OS_ANDROID)
OnApplicationStateChange(base::android::ApplicationState state)706 void NetworkService::OnApplicationStateChange(
707     base::android::ApplicationState state) {
708   for (auto* network_context : network_contexts_)
709     network_context->app_status_listener()->Notify(state);
710 }
711 #endif
712 
SetEnvironment(std::vector<mojom::EnvironmentVariablePtr> environment)713 void NetworkService::SetEnvironment(
714     std::vector<mojom::EnvironmentVariablePtr> environment) {
715   std::unique_ptr<base::Environment> env(base::Environment::Create());
716   for (const auto& variable : environment)
717     env->SetVar(variable->name, variable->value);
718 }
719 
SetTrustTokenKeyCommitments(base::flat_map<url::Origin,mojom::TrustTokenKeyCommitmentResultPtr> commitments)720 void NetworkService::SetTrustTokenKeyCommitments(
721     base::flat_map<url::Origin, mojom::TrustTokenKeyCommitmentResultPtr>
722         commitments) {
723   trust_token_key_commitments_->Set(std::move(commitments));
724 }
725 
726 #if defined(OS_ANDROID)
DumpWithoutCrashing(base::Time dump_request_time)727 void NetworkService::DumpWithoutCrashing(base::Time dump_request_time) {
728   static base::debug::CrashKeyString* time_key =
729       base::debug::AllocateCrashKeyString("time_since_dump_request_ms",
730                                           base::debug::CrashKeySize::Size32);
731   base::debug::ScopedCrashKeyString scoped_time(
732       time_key, base::NumberToString(
733                     (base::Time::Now() - dump_request_time).InMilliseconds()));
734   base::debug::DumpWithoutCrashing();
735 }
736 #endif
737 
BindTestInterface(mojo::PendingReceiver<mojom::NetworkServiceTest> receiver)738 void NetworkService::BindTestInterface(
739     mojo::PendingReceiver<mojom::NetworkServiceTest> receiver) {
740   if (registry_) {
741     auto pipe = receiver.PassPipe();
742     registry_->TryBindInterface(mojom::NetworkServiceTest::Name_, &pipe);
743   }
744 }
745 
746 std::unique_ptr<net::HttpAuthHandlerFactory>
CreateHttpAuthHandlerFactory(NetworkContext * network_context)747 NetworkService::CreateHttpAuthHandlerFactory(NetworkContext* network_context) {
748   if (!http_auth_static_network_service_params_) {
749     return net::HttpAuthHandlerFactory::CreateDefault(
750         network_context->GetHttpAuthPreferences()
751 #if defined(OS_ANDROID) && BUILDFLAG(USE_KERBEROS)
752             ,
753         base::BindRepeating(&CreateAuthSystem, network_context)
754 #endif
755     );
756   }
757 
758   return net::HttpAuthHandlerRegistryFactory::Create(
759       network_context->GetHttpAuthPreferences(),
760       http_auth_static_network_service_params_->supported_schemes
761 #if BUILDFLAG(USE_EXTERNAL_GSSAPI)
762       ,
763       http_auth_static_network_service_params_->gssapi_library_name
764 #endif
765 #if defined(OS_ANDROID) && BUILDFLAG(USE_KERBEROS)
766       ,
767       base::BindRepeating(&CreateAuthSystem, network_context)
768 #endif
769   );
770 }
771 
OnBeforeURLRequest()772 void NetworkService::OnBeforeURLRequest() {
773   MaybeStartUpdateLoadInfoTimer();
774 }
775 
DestroyNetworkContexts()776 void NetworkService::DestroyNetworkContexts() {
777   // Delete NetworkContexts. If there's a primary NetworkContext, it must be
778   // deleted after all other NetworkContexts, to avoid use-after-frees.
779   for (auto it = owned_network_contexts_.begin();
780        it != owned_network_contexts_.end();) {
781     const auto last = it;
782     ++it;
783     if (!(*last)->IsPrimaryNetworkContext())
784       owned_network_contexts_.erase(last);
785   }
786 
787   DCHECK_LE(owned_network_contexts_.size(), 1u);
788   owned_network_contexts_.clear();
789 }
790 
OnNetworkContextConnectionClosed(NetworkContext * network_context)791 void NetworkService::OnNetworkContextConnectionClosed(
792     NetworkContext* network_context) {
793   if (network_context->IsPrimaryNetworkContext()) {
794 #ifndef TOOLKIT_QT
795     DestroyNetworkContexts();
796     return;
797 #endif
798   }
799 
800   auto it = owned_network_contexts_.find(network_context);
801   DCHECK(it != owned_network_contexts_.end());
802   owned_network_contexts_.erase(it);
803 }
804 
MaybeStartUpdateLoadInfoTimer()805 void NetworkService::MaybeStartUpdateLoadInfoTimer() {
806   if (waiting_on_load_state_ack_ || update_load_info_timer_.IsRunning())
807     return;
808 
809   bool has_loader = false;
810   for (auto* network_context : network_contexts_) {
811     if (!network_context->url_request_context()->url_requests()->empty()) {
812       has_loader = true;
813       break;
814     }
815   }
816 
817   if (!has_loader)
818     return;
819 
820   update_load_info_timer_.Start(FROM_HERE, kUpdateLoadStatesInterval, this,
821                                 &NetworkService::UpdateLoadInfo);
822 }
823 
UpdateLoadInfo()824 void NetworkService::UpdateLoadInfo() {
825   // For requests from the same {process_id, routing_id} pair, pick the most
826   // important. For ones from the browser, return all of them.
827   std::vector<mojom::LoadInfoPtr> infos;
828   std::map<std::pair<int32_t, int32_t>, mojom::LoadInfoPtr> frame_infos;
829 
830   for (auto* network_context : network_contexts_) {
831     for (auto* loader :
832          *network_context->url_request_context()->url_requests()) {
833       auto* url_loader = URLLoader::ForRequest(*loader);
834       if (!url_loader)
835         continue;
836 
837       auto process_id = url_loader->GetProcessId();
838       auto routing_id = url_loader->GetRenderFrameId();
839       if (routing_id == MSG_ROUTING_NONE) {
840         // If there is no routing_id, then the browser can't associate this with
841         // a page so no need to send.
842         continue;
843       }
844 
845       auto load_info = mojom::LoadInfo::New();
846       load_info->process_id = process_id;
847       load_info->routing_id = routing_id;
848       load_info->host = loader->url().host();
849       auto load_state = loader->GetLoadState();
850       load_info->load_state = static_cast<uint32_t>(load_state.state);
851       load_info->state_param = std::move(load_state.param);
852       auto upload_progress = loader->GetUploadProgress();
853       load_info->upload_size = upload_progress.size();
854       load_info->upload_position = upload_progress.position();
855 
856       if (process_id == 0) {
857         // Requests from the browser can't be compared to ones from child
858         // processes, so send them all without looking for the most interesting.
859         infos.push_back(std::move(load_info));
860         continue;
861       }
862 
863       auto key = std::make_pair(process_id, routing_id);
864       auto existing = frame_infos.find(key);
865       if (existing == frame_infos.end() ||
866           LoadInfoIsMoreInteresting(*load_info, *existing->second)) {
867         frame_infos[key] = std::move(load_info);
868       }
869     }
870   }
871 
872   for (auto& it : frame_infos)
873     infos.push_back(std::move(it.second));
874 
875   if (infos.empty())
876     return;
877 
878   DCHECK(!waiting_on_load_state_ack_);
879   waiting_on_load_state_ack_ = true;
880   client_->OnLoadingStateUpdate(
881       std::move(infos), base::BindOnce(&NetworkService::AckUpdateLoadInfo,
882                                        base::Unretained(this)));
883 }
884 
AckUpdateLoadInfo()885 void NetworkService::AckUpdateLoadInfo() {
886   DCHECK(waiting_on_load_state_ack_);
887   waiting_on_load_state_ack_ = false;
888   MaybeStartUpdateLoadInfoTimer();
889 }
890 
Bind(mojo::PendingReceiver<mojom::NetworkService> receiver)891 void NetworkService::Bind(
892     mojo::PendingReceiver<mojom::NetworkService> receiver) {
893   DCHECK(!receiver_.is_bound());
894   receiver_.Bind(std::move(receiver));
895 }
896 
897 // static
GetNetworkServiceForTesting()898 NetworkService* NetworkService::GetNetworkServiceForTesting() {
899   return g_network_service;
900 }
901 
902 }  // namespace network
903