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