blob: 8c9945efaaeaa124cecd7b4b29e19ed8cf754cfe [file] [log] [blame]
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/net/profile_network_context_service.h"
#include <string>
#include "base/bind.h"
#include "base/check_op.h"
#include "base/command_line.h"
#include "base/feature_list.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/metrics/field_trial.h"
#include "base/metrics/field_trial_params.h"
#include "base/metrics/histogram_macros.h"
#include "base/notreached.h"
#include "base/strings/string_split.h"
#include "base/task/post_task.h"
#include "base/task/thread_pool.h"
#include "build/chromeos_buildflags.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/content_settings/cookie_settings_factory.h"
#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
#include "chrome/browser/data_reduction_proxy/data_reduction_proxy_chrome_settings.h"
#include "chrome/browser/data_reduction_proxy/data_reduction_proxy_chrome_settings_factory.h"
#include "chrome/browser/domain_reliability/service_factory.h"
#include "chrome/browser/net/system_network_context_manager.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_content_client.h"
#include "chrome/common/chrome_features.h"
#include "chrome/common/chrome_paths_internal.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h"
#include "components/certificate_transparency/pref_names.h"
#include "components/content_settings/core/browser/host_content_settings_map.h"
#include "components/embedder_support/pref_names.h"
#include "components/language/core/browser/language_prefs.h"
#include "components/language/core/browser/pref_names.h"
#include "components/metrics/metrics_pref_names.h"
#include "components/pref_registry/pref_registry_syncable.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/pref_service.h"
#include "components/safe_browsing/core/common/safe_browsing_prefs.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/network_service_instance.h"
#include "content/public/browser/shared_cors_origin_access_list.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/common/url_constants.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "net/base/features.h"
#include "net/http/http_auth_preferences.h"
#include "net/http/http_util.h"
#include "net/ssl/client_cert_store.h"
#include "services/network/public/cpp/cors/origin_access_list.h"
#include "services/network/public/cpp/features.h"
#include "services/network/public/mojom/network_context.mojom.h"
#include "services/network/public/mojom/network_service.mojom.h"
#include "third_party/blink/public/common/features.h"
#if BUILDFLAG(IS_CHROMEOS_ASH)
#include "chrome/browser/chromeos/certificate_provider/certificate_provider.h"
#include "chrome/browser/chromeos/certificate_provider/certificate_provider_service.h"
#include "chrome/browser/chromeos/certificate_provider/certificate_provider_service_factory.h"
#include "chrome/browser/chromeos/net/client_cert_store_chromeos.h"
#include "chrome/browser/chromeos/policy/policy_cert_service.h"
#include "chrome/browser/chromeos/policy/policy_cert_service_factory.h"
#include "chrome/browser/chromeos/profiles/profile_helper.h"
#include "chrome/browser/policy/profile_policy_connector.h"
#include "chromeos/constants/chromeos_features.h"
#include "chromeos/constants/chromeos_switches.h"
#include "components/user_manager/user.h"
#include "components/user_manager/user_manager.h"
#endif
#if defined(USE_NSS_CERTS)
#include "chrome/browser/ui/crypto_module_delegate_nss.h"
#include "net/ssl/client_cert_store_nss.h"
#endif // defined(USE_NSS_CERTS)
#if defined(OS_WIN)
#include "net/ssl/client_cert_store_win.h"
#endif // defined(OS_WIN)
#if defined(OS_MAC)
#include "net/ssl/client_cert_store_mac.h"
#endif // defined(OS_MAC)
#if BUILDFLAG(TRIAL_COMPARISON_CERT_VERIFIER_SUPPORTED)
#include "chrome/browser/net/trial_comparison_cert_verifier_controller.h"
#endif
#if BUILDFLAG(ENABLE_EXTENSIONS)
#include "extensions/common/constants.h"
#endif
#if BUILDFLAG(IS_LACROS)
#include "chrome/browser/lacros/cert_db_initializer_factory.h"
#include "chrome/browser/lacros/client_cert_store_lacros.h"
#endif
namespace {
bool* g_discard_domain_reliability_uploads_for_testing = nullptr;
const char kHttpCacheFinchExperimentGroups[] =
"profile_network_context_service.http_cache_finch_experiment_groups";
std::vector<std::string> TranslateStringArray(const base::ListValue* list) {
std::vector<std::string> strings;
for (const base::Value& value : *list) {
DCHECK(value.is_string());
strings.push_back(value.GetString());
}
return strings;
}
std::string ComputeAcceptLanguageFromPref(const std::string& language_pref) {
std::string accept_languages_str =
net::HttpUtil::ExpandLanguageList(language_pref);
return net::HttpUtil::GenerateAcceptLanguageHeader(accept_languages_str);
}
#if BUILDFLAG(IS_CHROMEOS_ASH)
network::mojom::AdditionalCertificatesPtr GetAdditionalCertificates(
const policy::PolicyCertService* policy_cert_service,
const base::FilePath& storage_partition_path) {
auto additional_certificates = network::mojom::AdditionalCertificates::New();
policy_cert_service->GetPolicyCertificatesForStoragePartition(
storage_partition_path, &(additional_certificates->all_certificates),
&(additional_certificates->trust_anchors));
return additional_certificates;
}
#endif // defined (OS_CHROMEOS)
// Tests allowing ambient authentication with default credentials based on the
// profile type.
bool IsAmbientAuthAllowedForProfile(Profile* profile) {
if (profile->IsRegularProfile() && !profile->IsEphemeralGuestProfile())
return true;
// Non-primary OTR profiles are not used to create browser windows and are
// only technical means for a task that does not need to leave state after
// it's completed.
if (profile->IsOffTheRecord() && !profile->IsPrimaryOTRProfile())
return true;
PrefService* local_state = g_browser_process->local_state();
DCHECK(local_state);
DCHECK(local_state->FindPreference(
prefs::kAmbientAuthenticationInPrivateModesEnabled));
net::AmbientAuthAllowedProfileTypes type =
static_cast<net::AmbientAuthAllowedProfileTypes>(local_state->GetInteger(
prefs::kAmbientAuthenticationInPrivateModesEnabled));
if (profile->IsGuestSession() || profile->IsEphemeralGuestProfile()) {
return type == net::AmbientAuthAllowedProfileTypes::GUEST_AND_REGULAR ||
type == net::AmbientAuthAllowedProfileTypes::ALL;
} else if (profile->IsIncognitoProfile()) {
return type == net::AmbientAuthAllowedProfileTypes::INCOGNITO_AND_REGULAR ||
type == net::AmbientAuthAllowedProfileTypes::ALL;
}
// System profile does not need ambient authentication.
if (profile->IsSystemProfile())
return false;
// Profile type not yet supported.
NOTREACHED();
return false;
}
void UpdateCookieSettings(Profile* profile) {
ContentSettingsForOneType settings;
HostContentSettingsMapFactory::GetForProfile(profile)->GetSettingsForOneType(
ContentSettingsType::COOKIES, &settings);
content::BrowserContext::ForEachStoragePartition(
profile, base::BindRepeating(
[](ContentSettingsForOneType settings,
content::StoragePartition* storage_partition) {
storage_partition->GetCookieManagerForBrowserProcess()
->SetContentSettings(settings);
},
settings));
}
void UpdateLegacyCookieSettings(Profile* profile) {
ContentSettingsForOneType settings;
HostContentSettingsMapFactory::GetForProfile(profile)->GetSettingsForOneType(
ContentSettingsType::LEGACY_COOKIE_ACCESS, &settings);
content::BrowserContext::ForEachStoragePartition(
profile, base::BindRepeating(
[](ContentSettingsForOneType settings,
content::StoragePartition* storage_partition) {
storage_partition->GetCookieManagerForBrowserProcess()
->SetContentSettingsForLegacyCookieAccess(settings);
},
settings));
}
void UpdateStorageAccessSettings(Profile* profile) {
if (base::FeatureList::IsEnabled(blink::features::kStorageAccessAPI)) {
ContentSettingsForOneType settings;
HostContentSettingsMapFactory::GetForProfile(profile)
->GetSettingsForOneType(ContentSettingsType::STORAGE_ACCESS, &settings);
content::BrowserContext::ForEachStoragePartition(
profile, base::BindRepeating(
[](ContentSettingsForOneType settings,
content::StoragePartition* storage_partition) {
storage_partition->GetCookieManagerForBrowserProcess()
->SetStorageAccessGrantSettings(settings,
base::DoNothing());
},
settings));
}
}
} // namespace
ProfileNetworkContextService::ProfileNetworkContextService(Profile* profile)
: profile_(profile), proxy_config_monitor_(profile) {
PrefService* profile_prefs = profile->GetPrefs();
quic_allowed_.Init(prefs::kQuicAllowed, profile_prefs,
base::BindRepeating(
&ProfileNetworkContextService::DisableQuicIfNotAllowed,
base::Unretained(this)));
pref_accept_language_.Init(
language::prefs::kAcceptLanguages, profile_prefs,
base::BindRepeating(&ProfileNetworkContextService::UpdateAcceptLanguage,
base::Unretained(this)));
enable_referrers_.Init(
prefs::kEnableReferrers, profile_prefs,
base::BindRepeating(&ProfileNetworkContextService::UpdateReferrersEnabled,
base::Unretained(this)));
cookie_settings_ = CookieSettingsFactory::GetForProfile(profile);
cookie_settings_observer_.Add(cookie_settings_.get());
DisableQuicIfNotAllowed();
// Observe content settings so they can be synced to the network service.
HostContentSettingsMapFactory::GetForProfile(profile_)->AddObserver(this);
pref_change_registrar_.Init(profile_prefs);
// When any of the following CT preferences change, we schedule an update
// to aggregate the actual update using a |ct_policy_update_timer_|.
pref_change_registrar_.Add(
certificate_transparency::prefs::kCTRequiredHosts,
base::BindRepeating(&ProfileNetworkContextService::ScheduleUpdateCTPolicy,
base::Unretained(this)));
pref_change_registrar_.Add(
certificate_transparency::prefs::kCTExcludedHosts,
base::BindRepeating(&ProfileNetworkContextService::ScheduleUpdateCTPolicy,
base::Unretained(this)));
pref_change_registrar_.Add(
certificate_transparency::prefs::kCTExcludedSPKIs,
base::BindRepeating(&ProfileNetworkContextService::ScheduleUpdateCTPolicy,
base::Unretained(this)));
pref_change_registrar_.Add(
certificate_transparency::prefs::kCTExcludedLegacySPKIs,
base::BindRepeating(&ProfileNetworkContextService::ScheduleUpdateCTPolicy,
base::Unretained(this)));
pref_change_registrar_.Add(
prefs::kGloballyScopeHTTPAuthCacheEnabled,
base::BindRepeating(&ProfileNetworkContextService::
UpdateSplitAuthCacheByNetworkIsolationKey,
base::Unretained(this)));
}
ProfileNetworkContextService::~ProfileNetworkContextService() = default;
void ProfileNetworkContextService::ConfigureNetworkContextParams(
bool in_memory,
const base::FilePath& relative_partition_path,
network::mojom::NetworkContextParams* network_context_params,
network::mojom::CertVerifierCreationParams* cert_verifier_creation_params) {
ConfigureNetworkContextParamsInternal(in_memory, relative_partition_path,
network_context_params,
cert_verifier_creation_params);
if ((!in_memory && !profile_->IsOffTheRecord())) {
// TODO(jam): delete this code 1 year after Network Service shipped to all
// stable users, which would be after M83 branches.
base::FilePath base_cache_path;
chrome::GetUserCacheDirectory(GetPartitionPath(relative_partition_path),
&base_cache_path);
base::FilePath media_cache_path =
base_cache_path.Append(chrome::kMediaCacheDirname);
base::ThreadPool::PostTask(
FROM_HERE,
{base::TaskPriority::BEST_EFFORT, base::MayBlock(),
base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
base::BindOnce(base::GetDeletePathRecursivelyCallback(),
media_cache_path));
}
}
#if BUILDFLAG(IS_CHROMEOS_ASH)
void ProfileNetworkContextService::UpdateAdditionalCertificates() {
const policy::PolicyCertService* policy_cert_service =
policy::PolicyCertServiceFactory::GetForProfile(profile_);
if (!policy_cert_service)
return;
content::BrowserContext::ForEachStoragePartition(
profile_, base::BindRepeating(
[](const policy::PolicyCertService* policy_cert_service,
content::StoragePartition* storage_partition) {
auto additional_certificates = GetAdditionalCertificates(
policy_cert_service, storage_partition->GetPath());
storage_partition->GetNetworkContext()
->UpdateAdditionalCertificates(
std::move(additional_certificates));
},
policy_cert_service));
}
#endif
void ProfileNetworkContextService::RegisterProfilePrefs(
user_prefs::PrefRegistrySyncable* registry) {
registry->RegisterBooleanPref(
embedder_support::kAlternateErrorPagesEnabled, true,
user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
registry->RegisterBooleanPref(prefs::kQuicAllowed, true);
registry->RegisterBooleanPref(prefs::kGloballyScopeHTTPAuthCacheEnabled,
false);
}
// static
void ProfileNetworkContextService::RegisterLocalStatePrefs(
PrefRegistrySimple* registry) {
registry->RegisterListPref(prefs::kHSTSPolicyBypassList);
registry->RegisterIntegerPref(
prefs::kAmbientAuthenticationInPrivateModesEnabled,
static_cast<int>(net::AmbientAuthAllowedProfileTypes::REGULAR_ONLY));
// For information about whether to reset the HTTP Cache or not, defaults
// to the empty string, which does not prompt a reset.
registry->RegisterStringPref(kHttpCacheFinchExperimentGroups, "");
}
void ProfileNetworkContextService::DisableQuicIfNotAllowed() {
if (!quic_allowed_.IsManaged())
return;
// If QUIC is allowed, do nothing (re-enabling QUIC is not supported).
if (quic_allowed_.GetValue())
return;
g_browser_process->system_network_context_manager()->DisableQuic();
}
void ProfileNetworkContextService::UpdateAcceptLanguage() {
content::BrowserContext::ForEachStoragePartition(
profile_, base::BindRepeating(
[](const std::string& accept_language,
content::StoragePartition* storage_partition) {
storage_partition->GetNetworkContext()->SetAcceptLanguage(
accept_language);
},
ComputeAcceptLanguage()));
}
void ProfileNetworkContextService::OnThirdPartyCookieBlockingChanged(
bool block_third_party_cookies) {
content::BrowserContext::ForEachStoragePartition(
profile_, base::BindRepeating(
[](bool block_third_party_cookies,
content::StoragePartition* storage_partition) {
storage_partition->GetCookieManagerForBrowserProcess()
->BlockThirdPartyCookies(block_third_party_cookies);
},
block_third_party_cookies));
}
std::string ProfileNetworkContextService::ComputeAcceptLanguage() const {
if (profile_->IsOffTheRecord()) {
// In incognito mode return only the first language.
return ComputeAcceptLanguageFromPref(
language::GetFirstLanguage(pref_accept_language_.GetValue()));
}
return ComputeAcceptLanguageFromPref(pref_accept_language_.GetValue());
}
void ProfileNetworkContextService::UpdateReferrersEnabled() {
content::BrowserContext::ForEachStoragePartition(
profile_,
base::BindRepeating(
[](bool enable_referrers,
content::StoragePartition* storage_partition) {
storage_partition->GetNetworkContext()->SetEnableReferrers(
enable_referrers);
},
enable_referrers_.GetValue()));
}
network::mojom::CTPolicyPtr ProfileNetworkContextService::GetCTPolicy() {
auto* prefs = profile_->GetPrefs();
const base::ListValue* ct_required =
prefs->GetList(certificate_transparency::prefs::kCTRequiredHosts);
const base::ListValue* ct_excluded =
prefs->GetList(certificate_transparency::prefs::kCTExcludedHosts);
const base::ListValue* ct_excluded_spkis =
prefs->GetList(certificate_transparency::prefs::kCTExcludedSPKIs);
const base::ListValue* ct_excluded_legacy_spkis =
prefs->GetList(certificate_transparency::prefs::kCTExcludedLegacySPKIs);
std::vector<std::string> required(TranslateStringArray(ct_required));
std::vector<std::string> excluded(TranslateStringArray(ct_excluded));
std::vector<std::string> excluded_spkis(
TranslateStringArray(ct_excluded_spkis));
std::vector<std::string> excluded_legacy_spkis(
TranslateStringArray(ct_excluded_legacy_spkis));
return network::mojom::CTPolicy::New(std::move(required), std::move(excluded),
std::move(excluded_spkis),
std::move(excluded_legacy_spkis));
}
void ProfileNetworkContextService::UpdateCTPolicyForContexts(
const std::vector<network::mojom::NetworkContext*>& contexts) {
for (auto* context : contexts) {
context->SetCTPolicy(GetCTPolicy());
}
}
void ProfileNetworkContextService::UpdateCTPolicy() {
std::vector<network::mojom::NetworkContext*> contexts;
content::BrowserContext::ForEachStoragePartition(
profile_,
base::BindRepeating(
[](std::vector<network::mojom::NetworkContext*>* contexts_ptr,
content::StoragePartition* storage_partition) {
contexts_ptr->push_back(storage_partition->GetNetworkContext());
},
&contexts));
UpdateCTPolicyForContexts(contexts);
}
void ProfileNetworkContextService::ScheduleUpdateCTPolicy() {
ct_policy_update_timer_.Start(FROM_HERE, base::TimeDelta::FromSeconds(0),
this,
&ProfileNetworkContextService::UpdateCTPolicy);
}
bool ProfileNetworkContextService::ShouldSplitAuthCacheByNetworkIsolationKey()
const {
if (profile_->GetPrefs()->GetBoolean(
prefs::kGloballyScopeHTTPAuthCacheEnabled))
return false;
return base::FeatureList::IsEnabled(
network::features::kSplitAuthCacheByNetworkIsolationKey);
}
void ProfileNetworkContextService::UpdateSplitAuthCacheByNetworkIsolationKey() {
bool split_auth_cache_by_network_isolation_key =
ShouldSplitAuthCacheByNetworkIsolationKey();
content::BrowserContext::ForEachStoragePartition(
profile_, base::BindRepeating(
[](bool split_auth_cache_by_network_isolation_key,
content::StoragePartition* storage_partition) {
storage_partition->GetNetworkContext()
->SetSplitAuthCacheByNetworkIsolationKey(
split_auth_cache_by_network_isolation_key);
},
split_auth_cache_by_network_isolation_key));
}
// static
network::mojom::CookieManagerParamsPtr
ProfileNetworkContextService::CreateCookieManagerParams(
Profile* profile,
const content_settings::CookieSettings& cookie_settings) {
auto out = network::mojom::CookieManagerParams::New();
out->block_third_party_cookies =
cookie_settings.ShouldBlockThirdPartyCookies();
// This allows cookies to be sent on https requests from chrome:// pages,
// ignoring SameSite attribute rules. For example, this is needed for browser
// UI to interact with SameSite cookies on accounts.google.com, which are used
// for logging into Cloud Print from chrome://print, for displaying a list
// of available accounts on the NTP (chrome://new-tab-page), etc.
out->secure_origin_cookies_allowed_schemes.push_back(
content::kChromeUIScheme);
#if BUILDFLAG(ENABLE_EXTENSIONS)
// TODO(chlily): To be consistent with the content_settings version of
// CookieSettings, we should probably also add kExtensionScheme to the list of
// matching_scheme_cookies_allowed_schemes.
out->third_party_cookies_allowed_schemes.push_back(
extensions::kExtensionScheme);
#endif
ContentSettingsForOneType settings;
HostContentSettingsMap* host_content_settings_map =
HostContentSettingsMapFactory::GetForProfile(profile);
host_content_settings_map->GetSettingsForOneType(ContentSettingsType::COOKIES,
&settings);
out->settings = std::move(settings);
ContentSettingsForOneType settings_for_legacy_cookie_access;
host_content_settings_map->GetSettingsForOneType(
ContentSettingsType::LEGACY_COOKIE_ACCESS,
&settings_for_legacy_cookie_access);
out->settings_for_legacy_cookie_access =
std::move(settings_for_legacy_cookie_access);
ContentSettingsForOneType settings_for_storage_access;
if (base::FeatureList::IsEnabled(blink::features::kStorageAccessAPI)) {
host_content_settings_map->GetSettingsForOneType(
ContentSettingsType::STORAGE_ACCESS, &settings_for_storage_access);
}
out->settings_for_storage_access = std::move(settings_for_storage_access);
out->cookie_access_delegate_type =
network::mojom::CookieAccessDelegateType::USE_CONTENT_SETTINGS;
return out;
}
void ProfileNetworkContextService::FlushProxyConfigMonitorForTesting() {
proxy_config_monitor_.FlushForTesting();
}
void ProfileNetworkContextService::SetDiscardDomainReliabilityUploadsForTesting(
bool value) {
g_discard_domain_reliability_uploads_for_testing = new bool(value);
}
std::unique_ptr<net::ClientCertStore>
ProfileNetworkContextService::CreateClientCertStore() {
if (!client_cert_store_factory_.is_null())
return client_cert_store_factory_.Run();
#if BUILDFLAG(IS_CHROMEOS_ASH)
bool use_system_key_slot = false;
// Enable client certificates for the Chrome OS sign-in frame, if this feature
// is not disabled by a flag.
// Note that while this applies to the whole sign-in profile, client
// certificates will only be selected for the StoragePartition currently used
// in the sign-in frame (see SigninPartitionManager).
if (chromeos::switches::IsSigninFrameClientCertsEnabled() &&
chromeos::ProfileHelper::IsSigninProfile(profile_)) {
use_system_key_slot = true;
}
std::string username_hash;
const user_manager::User* user =
chromeos::ProfileHelper::Get()->GetUserByProfile(profile_);
if (user && !user->username_hash().empty()) {
username_hash = user->username_hash();
// Use the device-wide system key slot only if the user is affiliated on
// the device.
if (user->IsAffiliated()) {
use_system_key_slot = true;
}
}
chromeos::CertificateProviderService* cert_provider_service =
chromeos::CertificateProviderServiceFactory::GetForBrowserContext(
profile_);
std::unique_ptr<chromeos::CertificateProvider> certificate_provider;
if (cert_provider_service) {
certificate_provider = cert_provider_service->CreateCertificateProvider();
}
// ClientCertStoreChromeOS internally depends on NSS initialization that
// happens when the ResourceContext is created. Call GetResourceContext() so
// the dependency is explicit. See https://crbug.com/1018972.
profile_->GetResourceContext();
return std::make_unique<chromeos::ClientCertStoreChromeOS>(
std::move(certificate_provider), use_system_key_slot, username_hash,
base::BindRepeating(&CreateCryptoModuleBlockingPasswordDelegate,
kCryptoModulePasswordClientAuth));
#elif defined(USE_NSS_CERTS)
std::unique_ptr<net::ClientCertStore> store =
std::make_unique<net::ClientCertStoreNSS>(
base::BindRepeating(&CreateCryptoModuleBlockingPasswordDelegate,
kCryptoModulePasswordClientAuth));
#if BUILDFLAG(IS_LACROS)
CertDbInitializer* cert_db_initializer =
CertDbInitializerFactory::GetForProfileIfExists(profile_);
if (!cert_db_initializer || !profile_->IsMainProfile()) {
// TODO(crbug.com/1148298): return some cert store for secondary profiles in
// Lacros-Chrome.
return nullptr;
}
store = std::make_unique<ClientCertStoreLacros>(cert_db_initializer,
std::move(store));
#endif // BUILDFLAG(IS_LACROS)
return store;
#elif defined(OS_WIN)
return std::make_unique<net::ClientCertStoreWin>();
#elif defined(OS_MAC)
return std::make_unique<net::ClientCertStoreMac>();
#elif defined(OS_ANDROID)
// Android does not use the ClientCertStore infrastructure. On Android client
// cert matching is done by the OS as part of the call to show the cert
// selection dialog.
return nullptr;
#else
#error Unknown platform.
#endif
}
bool GetHttpCacheBackendResetParam(PrefService* local_state) {
// Get the field trial groups. If the server cannot be reached, then
// this corresponds to "None" for each experiment.
base::FieldTrial* field_trial = base::FeatureList::GetFieldTrial(
net::features::kSplitCacheByNetworkIsolationKey);
std::string current_field_trial_status =
(field_trial ? field_trial->group_name() : "None") + " ";
field_trial = base::FeatureList::GetFieldTrial(
net::features::kAppendFrameOriginToNetworkIsolationKey);
current_field_trial_status +=
(field_trial ? field_trial->group_name() : "None");
// This used to be for keying on scheme + eTLD+1 vs origin, but the trial was
// removed, and now it's always keyed on eTLD+1. Still keeping a third "None"
// to avoid resetting the disk cache.
current_field_trial_status += " None";
std::string previous_field_trial_status =
local_state->GetString(kHttpCacheFinchExperimentGroups);
local_state->SetString(kHttpCacheFinchExperimentGroups,
current_field_trial_status);
return !previous_field_trial_status.empty() &&
current_field_trial_status != previous_field_trial_status;
}
void ProfileNetworkContextService::ConfigureNetworkContextParamsInternal(
bool in_memory,
const base::FilePath& relative_partition_path,
network::mojom::NetworkContextParams* network_context_params,
network::mojom::CertVerifierCreationParams* cert_verifier_creation_params) {
if (profile_->IsOffTheRecord())
in_memory = true;
base::FilePath path(GetPartitionPath(relative_partition_path));
g_browser_process->system_network_context_manager()
->ConfigureDefaultNetworkContextParams(network_context_params,
cert_verifier_creation_params);
network_context_params->context_name = std::string("main");
network_context_params->accept_language = ComputeAcceptLanguage();
network_context_params->enable_referrers = enable_referrers_.GetValue();
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
if (command_line->HasSwitch(switches::kShortReportingDelay)) {
network_context_params->reporting_delivery_interval =
base::TimeDelta::FromMilliseconds(100);
}
// Always enable the HTTP cache.
network_context_params->http_cache_enabled = true;
network_context_params->http_auth_static_network_context_params =
network::mojom::HttpAuthStaticNetworkContextParams::New();
if (IsAmbientAuthAllowedForProfile(profile_)) {
network_context_params->http_auth_static_network_context_params
->allow_default_credentials =
net::HttpAuthPreferences::ALLOW_DEFAULT_CREDENTIALS;
} else {
network_context_params->http_auth_static_network_context_params
->allow_default_credentials =
net::HttpAuthPreferences::DISALLOW_DEFAULT_CREDENTIALS;
}
network_context_params->cookie_manager_params =
CreateCookieManagerParams(profile_, *cookie_settings_);
// Configure on-disk storage for non-OTR profiles. OTR profiles just use
// default behavior (in memory storage, default sizes).
if (!in_memory) {
PrefService* local_state = g_browser_process->local_state();
// Configure the HTTP cache path and size.
base::FilePath base_cache_path;
chrome::GetUserCacheDirectory(path, &base_cache_path);
base::FilePath disk_cache_dir =
local_state->GetFilePath(prefs::kDiskCacheDir);
if (!disk_cache_dir.empty())
base_cache_path = disk_cache_dir.Append(base_cache_path.BaseName());
network_context_params->http_cache_path =
base_cache_path.Append(chrome::kCacheDirname);
network_context_params->http_cache_max_size =
local_state->GetInteger(prefs::kDiskCacheSize);
// Currently this just contains HttpServerProperties, but that will likely
// change.
network_context_params->http_server_properties_path =
path.Append(chrome::kNetworkPersistentStateFilename);
base::FilePath cookie_path = path;
cookie_path = cookie_path.Append(chrome::kCookieFilename);
network_context_params->cookie_path = cookie_path;
base::FilePath trust_token_path = path;
trust_token_path = trust_token_path.Append(chrome::kTrustTokenFilename);
network_context_params->trust_token_path = std::move(trust_token_path);
#if BUILDFLAG(ENABLE_REPORTING)
base::FilePath reporting_and_nel_store_path = path;
reporting_and_nel_store_path = reporting_and_nel_store_path.Append(
chrome::kReportingAndNelStoreFilename);
network_context_params->reporting_and_nel_store_path =
reporting_and_nel_store_path;
#endif // BUILDFLAG(ENABLE_REPORTING)
if (relative_partition_path.empty()) { // This is the main partition.
network_context_params->restore_old_session_cookies =
profile_->ShouldRestoreOldSessionCookies();
network_context_params->persist_session_cookies =
profile_->ShouldPersistSessionCookies();
} else {
// Copy behavior of ProfileImplIOData::InitializeAppRequestContext.
network_context_params->restore_old_session_cookies = false;
network_context_params->persist_session_cookies = false;
}
network_context_params->transport_security_persister_path = path;
}
const base::ListValue* hsts_policy_bypass_list =
g_browser_process->local_state()->GetList(prefs::kHSTSPolicyBypassList);
for (const auto& value : *hsts_policy_bypass_list) {
std::string string_value;
if (!value.GetAsString(&string_value)) {
continue;
}
network_context_params->hsts_policy_bypass_list.push_back(string_value);
}
// NOTE(mmenke): Keep these protocol handlers and
// ProfileIOData::SetUpJobFactoryDefaultsForBuilder in sync with
// ProfileIOData::IsHandledProtocol().
// TODO(mmenke): Find a better way of handling tracking supported schemes.
#if !BUILDFLAG(DISABLE_FTP_SUPPORT)
network_context_params->enable_ftp_url_support =
base::FeatureList::IsEnabled(blink::features::kFtpProtocol);
#endif // !BUILDFLAG(DISABLE_FTP_SUPPORT)
proxy_config_monitor_.AddToNetworkContextParams(network_context_params);
network_context_params->enable_certificate_reporting = true;
network_context_params->enable_expect_ct_reporting = true;
// Initialize the network context to do SCT auditing only if the current
// profile is opted in to Safe Browsing Extended Reporting.
if (!profile_->IsOffTheRecord() &&
safe_browsing::IsExtendedReportingEnabled(*profile_->GetPrefs())) {
network_context_params->enable_sct_auditing = true;
}
network_context_params->ct_policy = GetCTPolicy();
#if BUILDFLAG(TRIAL_COMPARISON_CERT_VERIFIER_SUPPORTED)
// Require the use_builtin_cert_verifier to be explicitly initialized, as
// using the TrialComparisonCertVerifier requires knowing whether Chrome is
// using the system verifier.
DCHECK(cert_verifier_creation_params);
DCHECK_NE(
cert_verifier_creation_params->use_builtin_cert_verifier,
network::mojom::CertVerifierCreationParams::CertVerifierImpl::kDefault);
if (!in_memory &&
cert_verifier_creation_params->use_builtin_cert_verifier ==
network::mojom::CertVerifierCreationParams::CertVerifierImpl::
kSystem &&
TrialComparisonCertVerifierController::MaybeAllowedForProfile(profile_)) {
mojo::PendingRemote<network::mojom::TrialComparisonCertVerifierConfigClient>
config_client;
auto config_client_receiver =
config_client.InitWithNewPipeAndPassReceiver();
cert_verifier_creation_params->trial_comparison_cert_verifier_params =
network::mojom::TrialComparisonCertVerifierParams::New();
if (!trial_comparison_cert_verifier_controller_) {
trial_comparison_cert_verifier_controller_ =
std::make_unique<TrialComparisonCertVerifierController>(profile_);
}
trial_comparison_cert_verifier_controller_->AddClient(
std::move(config_client),
cert_verifier_creation_params->trial_comparison_cert_verifier_params
->report_client.InitWithNewPipeAndPassReceiver());
cert_verifier_creation_params->trial_comparison_cert_verifier_params
->initial_allowed =
trial_comparison_cert_verifier_controller_->IsAllowed();
cert_verifier_creation_params->trial_comparison_cert_verifier_params
->config_client_receiver = std::move(config_client_receiver);
}
#endif
if (domain_reliability::DomainReliabilityServiceFactory::
ShouldCreateService()) {
network_context_params->enable_domain_reliability = true;
network_context_params->domain_reliability_upload_reporter =
domain_reliability::DomainReliabilityServiceFactory::
kUploadReporterString;
network_context_params->discard_domain_reliablity_uploads =
g_discard_domain_reliability_uploads_for_testing
? *g_discard_domain_reliability_uploads_for_testing
: !g_browser_process->local_state()->GetBoolean(
metrics::prefs::kMetricsReportingEnabled);
}
auto* drp_settings =
DataReductionProxyChromeSettingsFactory::GetForBrowserContext(profile_);
if (drp_settings) {
mojo::Remote<network::mojom::CustomProxyConfigClient> config_client;
network_context_params->custom_proxy_config_client_receiver =
config_client.BindNewPipeAndPassReceiver();
drp_settings->AddCustomProxyConfigClient(std::move(config_client));
}
#if BUILDFLAG(IS_CHROMEOS_ASH)
bool profile_supports_policy_certs = false;
if (chromeos::ProfileHelper::IsSigninProfile(profile_))
profile_supports_policy_certs = true;
user_manager::UserManager* user_manager = user_manager::UserManager::Get();
if (user_manager) {
const user_manager::User* user =
chromeos::ProfileHelper::Get()->GetUserByProfile(profile_);
// No need to initialize NSS for users with empty username hash:
// Getters for a user's NSS slots always return NULL slot if the user's
// username hash is empty, even when the NSS is not initialized for the
// user.
if (user && !user->username_hash().empty()) {
cert_verifier_creation_params->username_hash = user->username_hash();
cert_verifier_creation_params->nss_path = profile_->GetPath();
profile_supports_policy_certs = true;
}
}
if (profile_supports_policy_certs &&
policy::PolicyCertServiceFactory::CreateAndStartObservingForProfile(
profile_)) {
const policy::PolicyCertService* policy_cert_service =
policy::PolicyCertServiceFactory::GetForProfile(profile_);
network_context_params->initial_additional_certificates =
GetAdditionalCertificates(policy_cert_service,
GetPartitionPath(relative_partition_path));
}
// Disable idle sockets close on memory pressure if configured by finch or
// about://flags.
if (base::FeatureList::IsEnabled(
chromeos::features::kDisableIdleSocketsCloseOnMemoryPressure)) {
network_context_params->disable_idle_sockets_close_on_memory_pressure =
true;
}
#endif
// Should be initialized with existing per-profile CORS access lists.
network_context_params->cors_origin_access_list =
profile_->GetSharedCorsOriginAccessList()
->GetOriginAccessList()
.CreateCorsOriginAccessPatternsList();
network_context_params->reset_http_cache_backend =
GetHttpCacheBackendResetParam(g_browser_process->local_state());
network_context_params->split_auth_cache_by_network_isolation_key =
ShouldSplitAuthCacheByNetworkIsolationKey();
// All consumers of the main NetworkContext must provide NetworkIsolationKeys
// / IsolationInfos, so storage can be isolated on a per-site basis.
network_context_params->require_network_isolation_key = true;
}
base::FilePath ProfileNetworkContextService::GetPartitionPath(
const base::FilePath& relative_partition_path) {
base::FilePath path = profile_->GetPath();
if (!relative_partition_path.empty())
path = path.Append(relative_partition_path);
return path;
}
void ProfileNetworkContextService::OnContentSettingChanged(
const ContentSettingsPattern& primary_pattern,
const ContentSettingsPattern& secondary_pattern,
ContentSettingsType content_type) {
switch (content_type) {
case ContentSettingsType::COOKIES:
UpdateCookieSettings(profile_);
break;
case ContentSettingsType::LEGACY_COOKIE_ACCESS:
UpdateLegacyCookieSettings(profile_);
break;
case ContentSettingsType::STORAGE_ACCESS:
UpdateStorageAccessSettings(profile_);
break;
case ContentSettingsType::DEFAULT:
UpdateCookieSettings(profile_);
UpdateLegacyCookieSettings(profile_);
UpdateStorageAccessSettings(profile_);
break;
default:
return;
}
}