Files
electron/shell/browser/browser_process_impl.cc
Shelley Vohr e7dd342f71 chore!: remove synchronous safeStorage methods (#53662)
Chromium removed the synchronous OSCrypt backend in
https://chromium-review.googlesource.com/c/chromium/src/+/7765593. Remove
safeStorage.isEncryptionAvailable(), encryptString() and decryptString(),
which were deprecated in Electron 45 and were the last users of it, move
pref registration, the Windows key load and the Linux backend name onto
os_crypt_async, and drop the revert of that CL together with the
os_crypt/sync visibility patch.

Closes https://github.com/electron/electron/issues/51301
2026-09-15 23:28:05 +02:00

565 lines
18 KiB
C++

// Copyright (c) 2012 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 "shell/browser/browser_process_impl.h"
#include <memory>
#include <utility>
#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/functional/bind.h"
#include "base/notimplemented.h"
#include "base/path_service.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/hid/hid_system_tray_icon.h"
#include "chrome/browser/usb/usb_system_tray_icon.h"
#include "chrome/common/chrome_switches.h"
#include "components/os_crypt/async/browser/key_provider.h"
#include "components/os_crypt/async/browser/os_crypt_async.h"
#include "components/prefs/in_memory_pref_store.h"
#include "components/prefs/json_pref_store.h"
#include "components/prefs/pref_registry.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/pref_service.h"
#include "components/prefs/pref_service_factory.h"
#include "components/prefs/value_map_pref_store.h"
#include "components/proxy_config/pref_proxy_config_tracker_impl.h"
#include "components/proxy_config/proxy_config_dictionary.h"
#include "components/proxy_config/proxy_config_pref_names.h"
#include "components/supervised_user/core/browser/device_parental_controls_noop_impl.h" // nogncheck
#include "content/public/browser/child_process_security_policy.h"
#include "content/public/browser/network_quality_observer_factory.h"
#include "content/public/browser/network_service_instance.h"
#include "extensions/common/constants.h"
#include "net/proxy_resolution/proxy_config.h"
#include "net/proxy_resolution/proxy_config_service.h"
#include "net/proxy_resolution/proxy_config_with_annotation.h"
#include "services/device/public/cpp/geolocation/geolocation_system_permission_manager.h"
#include "services/network/public/cpp/network_switches.h"
#include "shell/browser/metrics/electron_metrics_service_client.h"
#include "shell/browser/net/resolve_proxy_helper.h"
#include "shell/common/electron_constants.h"
#include "shell/common/electron_paths.h"
#include "shell/common/thread_restrictions.h"
#if BUILDFLAG(ENABLE_PRINTING)
#include "chrome/browser/printing/print_job_manager.h"
#endif
#if BUILDFLAG(IS_LINUX)
#include "base/environment.h"
#include "base/nix/xdg_util.h"
#include "chrome/browser/browser_features.h"
#include "components/os_crypt/async/browser/freedesktop_secret_key_provider.h"
#include "components/os_crypt/async/browser/secret_portal_key_provider.h"
#include "components/password_manager/core/browser/password_manager_switches.h" // nogncheck
#include "shell/common/application_info.h"
#endif
#if BUILDFLAG(IS_WIN)
#include "components/os_crypt/async/browser/dpapi_key_provider.h"
#include "components/os_crypt/async/browser/os_crypt_win.h"
#endif
#if BUILDFLAG(IS_MAC)
#include "chrome/common/chrome_features.h"
#include "components/os_crypt/async/browser/keychain_key_provider.h"
#endif
#if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_MAC)
#include "components/os_crypt/async/browser/posix_key_provider.h"
#endif
#if BUILDFLAG(IS_LINUX)
namespace {
// The name safeStorage.getSelectedStorageBackend() reports for the
// --password-store switch and desktop environment.
const char* SelectLinuxStorageBackend(const std::string& password_store) {
if (password_store == "kwallet")
return "kwallet";
if (password_store == "kwallet5")
return "kwallet5";
if (password_store == "kwallet6")
return "kwallet6";
if (password_store == "gnome-libsecret")
return "gnome_libsecret";
if (password_store == "basic")
return "basic_text";
auto env = base::Environment::Create();
switch (base::nix::GetDesktopEnvironment(env.get())) {
case base::nix::DESKTOP_ENVIRONMENT_KDE4:
return "kwallet";
case base::nix::DESKTOP_ENVIRONMENT_KDE5:
return "kwallet5";
case base::nix::DESKTOP_ENVIRONMENT_KDE6:
return "kwallet6";
case base::nix::DESKTOP_ENVIRONMENT_CINNAMON:
case base::nix::DESKTOP_ENVIRONMENT_DEEPIN:
case base::nix::DESKTOP_ENVIRONMENT_GNOME:
case base::nix::DESKTOP_ENVIRONMENT_PANTHEON:
case base::nix::DESKTOP_ENVIRONMENT_UKUI:
case base::nix::DESKTOP_ENVIRONMENT_UNITY:
case base::nix::DESKTOP_ENVIRONMENT_XFCE:
case base::nix::DESKTOP_ENVIRONMENT_COSMIC:
return "gnome_libsecret";
case base::nix::DESKTOP_ENVIRONMENT_KDE3:
case base::nix::DESKTOP_ENVIRONMENT_LXQT:
case base::nix::DESKTOP_ENVIRONMENT_OTHER:
return "basic_text";
}
}
} // namespace
#endif // BUILDFLAG(IS_LINUX)
BrowserProcessImpl::BrowserProcessImpl() {
g_browser_process = this;
}
BrowserProcessImpl::~BrowserProcessImpl() {
g_browser_process = nullptr;
}
// static
void BrowserProcessImpl::ApplyProxyModeFromCommandLine(
ValueMapPrefStore* pref_store) {
if (!pref_store)
return;
auto* command_line = base::CommandLine::ForCurrentProcess();
if (command_line->HasSwitch(switches::kNoProxyServer)) {
pref_store->SetValue(proxy_config::prefs::kProxy,
base::Value(ProxyConfigDictionary::CreateDirect()),
WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
} else if (command_line->HasSwitch(switches::kProxyPacUrl)) {
std::string pac_script_url =
command_line->GetSwitchValueASCII(switches::kProxyPacUrl);
pref_store->SetValue(proxy_config::prefs::kProxy,
base::Value(ProxyConfigDictionary::CreatePacScript(
pac_script_url, false /* pac_mandatory */)),
WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
} else if (command_line->HasSwitch(switches::kProxyAutoDetect)) {
pref_store->SetValue(proxy_config::prefs::kProxy,
base::Value(ProxyConfigDictionary::CreateAutoDetect()),
WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
} else if (command_line->HasSwitch(switches::kProxyServer)) {
std::string proxy_server =
command_line->GetSwitchValueASCII(switches::kProxyServer);
std::string bypass_list =
command_line->GetSwitchValueASCII(switches::kProxyBypassList);
pref_store->SetValue(proxy_config::prefs::kProxy,
base::Value(ProxyConfigDictionary::CreateFixedServers(
proxy_server, bypass_list)),
WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
}
}
BuildState* BrowserProcessImpl::GetBuildState() {
NOTIMPLEMENTED();
return nullptr;
}
GlobalFeatures* BrowserProcessImpl::GetFeatures() {
NOTIMPLEMENTED();
return nullptr;
}
ui::UnownedUserDataHost& BrowserProcessImpl::GetUnownedUserDataHost() {
NOTIMPLEMENTED();
static base::NoDestructor<ui::UnownedUserDataHost> instance;
return *instance;
}
const ui::UnownedUserDataHost& BrowserProcessImpl::GetUnownedUserDataHost()
const {
NOTIMPLEMENTED();
static base::NoDestructor<ui::UnownedUserDataHost> instance;
return *instance;
}
void BrowserProcessImpl::PostEarlyInitialization() {
PrefServiceFactory prefs_factory;
auto pref_registry = base::MakeRefCounted<PrefRegistrySimple>();
PrefProxyConfigTrackerImpl::RegisterPrefs(pref_registry.get());
electron::ElectronMetricsServiceClient::RegisterMetricsPrefs(
pref_registry.get());
#if BUILDFLAG(IS_WIN)
os_crypt_async::RegisterLocalPrefs(pref_registry.get());
#endif
#if BUILDFLAG(IS_LINUX)
os_crypt_async::SecretPortalKeyProvider::RegisterLocalPrefs(
pref_registry.get());
#endif
pref_registry->RegisterDictionaryPref(electron::kWindowStates);
in_memory_pref_store_ = base::MakeRefCounted<ValueMapPrefStore>();
ApplyProxyModeFromCommandLine(in_memory_pref_store());
prefs_factory.set_command_line_prefs(in_memory_pref_store());
base::FilePath prefs_path;
CHECK(base::PathService::Get(electron::DIR_SESSION_DATA, &prefs_path));
if (!base::DirectoryExists(prefs_path))
base::CreateDirectory(prefs_path);
prefs_path = prefs_path.Append(FILE_PATH_LITERAL("Local State"));
electron::ScopedAllowBlockingForElectron allow_blocking;
scoped_refptr<JsonPrefStore> user_pref_store =
base::MakeRefCounted<JsonPrefStore>(prefs_path);
user_pref_store->ReadPrefs();
prefs_factory.set_user_prefs(user_pref_store);
DCHECK(user_pref_store->IsInitializationComplete());
local_state_ = prefs_factory.Create(std::move(pref_registry));
}
void BrowserProcessImpl::PreCreateThreads() {
// chrome-extension:// URLs are safe to request anywhere, but may only
// commit (including in iframes) in extension processes.
content::ChildProcessSecurityPolicy::GetInstance()
->RegisterWebSafeIsolatedScheme(extensions::kExtensionScheme);
// Must be created before the IOThread.
// Once IOThread class is no longer needed,
// this can be created on first use.
if (!SystemNetworkContextManager::GetInstance())
SystemNetworkContextManager::CreateInstance(local_state_.get());
// Needs to be called here as per
// https://source.chromium.org/chromium/chromium/src/+/main:chrome/browser/chrome_browser_main.cc;l=1385-1389;drc=c3bda003554dad21313fb24b7a4f3e1aae6102d9.
CreateMetricsServiceClient();
}
void BrowserProcessImpl::PreMainMessageLoopRun() {
CreateNetworkQualityObserver();
CreateOSCryptAsync();
}
void BrowserProcessImpl::PostMainMessageLoopRun() {
if (local_state_)
local_state_->CommitPendingWrite();
// This expects to be destroyed before the task scheduler is torn down.
SystemNetworkContextManager::DeleteInstance();
}
bool BrowserProcessImpl::IsShuttingDown() {
return false;
}
metrics_services_manager::MetricsServicesManager*
BrowserProcessImpl::GetMetricsServicesManager() {
return nullptr;
}
metrics::MetricsService* BrowserProcessImpl::metrics_service() {
return metrics_service_client_ ? metrics_service_client_->GetMetricsService()
: nullptr;
}
ProfileManager* BrowserProcessImpl::profile_manager() {
return nullptr;
}
PrefService* BrowserProcessImpl::local_state() {
DCHECK(local_state_.get());
return local_state_.get();
}
signin::ActivePrimaryAccountsMetricsRecorder*
BrowserProcessImpl::active_primary_accounts_metrics_recorder() {
return nullptr;
}
scoped_refptr<network::SharedURLLoaderFactory>
BrowserProcessImpl::shared_url_loader_factory() {
return system_network_context_manager()->GetSharedURLLoaderFactory();
}
variations::VariationsService* BrowserProcessImpl::variations_service() {
return nullptr;
}
BrowserProcessPlatformPart* BrowserProcessImpl::platform_part() {
return nullptr;
}
NotificationUIManager* BrowserProcessImpl::notification_ui_manager() {
return nullptr;
}
NotificationPlatformBridge* BrowserProcessImpl::notification_platform_bridge() {
return nullptr;
}
SystemNetworkContextManager*
BrowserProcessImpl::system_network_context_manager() {
DCHECK(SystemNetworkContextManager::GetInstance());
return SystemNetworkContextManager::GetInstance();
}
network::NetworkQualityTracker* BrowserProcessImpl::network_quality_tracker() {
return nullptr;
}
embedder_support::OriginTrialsSettingsStorage*
BrowserProcessImpl::GetOriginTrialsSettingsStorage() {
return &origin_trials_settings_storage_;
}
policy::ChromeBrowserPolicyConnector*
BrowserProcessImpl::browser_policy_connector() {
return nullptr;
}
policy::PolicyService* BrowserProcessImpl::policy_service() {
return nullptr;
}
IconManager* BrowserProcessImpl::icon_manager() {
return nullptr;
}
GpuModeManager* BrowserProcessImpl::gpu_mode_manager() {
return nullptr;
}
printing::PrintPreviewDialogController*
BrowserProcessImpl::print_preview_dialog_controller() {
return nullptr;
}
printing::BackgroundPrintingManager*
BrowserProcessImpl::background_printing_manager() {
return nullptr;
}
supervised_user::DeviceParentalControls&
BrowserProcessImpl::device_parental_controls() {
if (!device_parental_controls_)
device_parental_controls_ =
std::make_unique<supervised_user::DeviceParentalControlsNoOpImpl>();
return *device_parental_controls_;
}
activity_reporter::ActivityReporter* BrowserProcessImpl::activity_reporter() {
return nullptr;
}
IntranetRedirectDetector* BrowserProcessImpl::intranet_redirect_detector() {
return nullptr;
}
DownloadStatusUpdater* BrowserProcessImpl::download_status_updater() {
return nullptr;
}
DownloadRequestLimiter* BrowserProcessImpl::download_request_limiter() {
return nullptr;
}
BackgroundModeManager* BrowserProcessImpl::background_mode_manager() {
return nullptr;
}
StatusTray* BrowserProcessImpl::status_tray() {
return nullptr;
}
safe_browsing::SafeBrowsingService*
BrowserProcessImpl::safe_browsing_service() {
return nullptr;
}
subresource_filter::RulesetService*
BrowserProcessImpl::subresource_filter_ruleset_service() {
return nullptr;
}
component_updater::ComponentUpdateService*
BrowserProcessImpl::component_updater() {
return nullptr;
}
WebRtcLogUploader* BrowserProcessImpl::webrtc_log_uploader() {
return nullptr;
}
network_time::NetworkTimeTracker* BrowserProcessImpl::network_time_tracker() {
return nullptr;
}
gcm::GCMDriver* BrowserProcessImpl::gcm_driver() {
return nullptr;
}
resource_coordinator::ResourceCoordinatorParts*
BrowserProcessImpl::resource_coordinator_parts() {
return nullptr;
}
resource_coordinator::TabManager* BrowserProcessImpl::GetTabManager() {
return nullptr;
}
SerialPolicyAllowedPorts* BrowserProcessImpl::serial_policy_allowed_ports() {
return nullptr;
}
HidSystemTrayIcon* BrowserProcessImpl::hid_system_tray_icon() {
return nullptr;
}
void BrowserProcessImpl::set_hid_system_tray_icon_for_test(
std::unique_ptr<HidSystemTrayIcon> icon) {}
UsbSystemTrayIcon* BrowserProcessImpl::usb_system_tray_icon() {
return nullptr;
}
void BrowserProcessImpl::set_usb_system_tray_icon_for_test(
std::unique_ptr<UsbSystemTrayIcon> icon) {}
speech::SpeechRecognitionSmallExpertModelInstaller*
BrowserProcessImpl::speech_recognition_small_expert_model_installer() {
return nullptr;
}
os_crypt_async::OSCryptAsync* BrowserProcessImpl::os_crypt_async() {
return os_crypt_async_.get();
}
void BrowserProcessImpl::set_additional_os_crypt_async_provider_for_test(
size_t precedence,
std::unique_ptr<os_crypt_async::KeyProvider> provider) {}
void BrowserProcessImpl::SetSystemLocale(const std::string& locale) {
system_locale_ = locale;
}
const std::string& BrowserProcessImpl::GetSystemLocale() const {
return system_locale_;
}
electron::ResolveProxyHelper* BrowserProcessImpl::GetResolveProxyHelper() {
if (!resolve_proxy_helper_) {
resolve_proxy_helper_ = base::MakeRefCounted<electron::ResolveProxyHelper>(
nullptr /* browser_context */);
}
return resolve_proxy_helper_.get();
}
void BrowserProcessImpl::SetApplicationLocale(const std::string& locale) {
locale_ = locale;
}
const std::string& BrowserProcessImpl::GetApplicationLocale() {
return locale_;
}
printing::PrintJobManager* BrowserProcessImpl::print_job_manager() {
#if BUILDFLAG(ENABLE_PRINTING)
if (!print_job_manager_)
print_job_manager_ = std::make_unique<printing::PrintJobManager>();
return print_job_manager_.get();
#else
return nullptr;
#endif
}
StartupData* BrowserProcessImpl::startup_data() {
return nullptr;
}
network::NetworkQualityTracker* BrowserProcessImpl::GetNetworkQualityTracker() {
if (!network_quality_tracker_) {
network_quality_tracker_ = std::make_unique<network::NetworkQualityTracker>(
base::BindRepeating(&content::GetNetworkService));
}
return network_quality_tracker_.get();
}
void BrowserProcessImpl::CreateNetworkQualityObserver() {
DCHECK(!network_quality_observer_);
network_quality_observer_ =
content::CreateNetworkQualityObserver(GetNetworkQualityTracker());
DCHECK(network_quality_observer_);
}
void BrowserProcessImpl::CreateOSCryptAsync() {
std::vector<std::pair<size_t, std::unique_ptr<os_crypt_async::KeyProvider>>>
providers;
#if BUILDFLAG(IS_WIN)
// Requires os_crypt_async::Init to have loaded the key, which happens in
// ElectronBrowserMainParts::PreCreateMainMessageLoop.
providers.emplace_back(
/*precedence=*/10u,
std::make_unique<os_crypt_async::DPAPIKeyProvider>(local_state()));
#endif // BUILDFLAG(IS_WIN)
#if BUILDFLAG(IS_LINUX)
base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess();
const auto password_store =
cmd_line->GetSwitchValueASCII(password_manager::kPasswordStore);
selected_linux_storage_backend_ = SelectLinuxStorageBackend(password_store);
if (password_store != "basic" &&
base::FeatureList::IsEnabled(features::kDbusSecretPortal)) {
// Use a higher priority than the FreedesktopSecretKeyProvider.
providers.emplace_back(
/*precedence=*/15u,
std::make_unique<os_crypt_async::SecretPortalKeyProvider>(
local_state(),
base::FeatureList::IsEnabled(
features::kSecretPortalKeyProviderUseForEncryption)));
}
auto freedesktop_config =
os_crypt_async::FreedesktopSecretKeyProvider::GetDefaultConfig();
const std::string app_name = electron::GetApplicationName();
freedesktop_config.app_name = app_name;
freedesktop_config.kwallet_folder = app_name + " Keys";
freedesktop_config.key_name = app_name + " Safe Storage";
providers.emplace_back(
/*precedence=*/10u,
std::make_unique<os_crypt_async::FreedesktopSecretKeyProvider>(
password_store, electron::GetApplicationName(), freedesktop_config,
nullptr));
#endif // BUILDFLAG(IS_LINUX)
#if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_MAC)
// On other POSIX systems, this is the only key provider. On Linux, it is used
// as a fallback.
providers.emplace_back(
/*precedence=*/5u, std::make_unique<os_crypt_async::PosixKeyProvider>());
#endif // BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_MAC)
#if BUILDFLAG(IS_MAC)
if (base::FeatureList::IsEnabled(features::kUseKeychainKeyProvider)) {
providers.emplace_back(
/*precedence=*/10u,
std::make_unique<os_crypt_async::KeychainKeyProvider>());
}
#endif // BUILDFLAG(IS_MAC)
os_crypt_async_ =
std::make_unique<os_crypt_async::OSCryptAsync>(std::move(providers));
}
void BrowserProcessImpl::CreateMetricsServiceClient() {
metrics_service_client_ =
std::make_unique<electron::ElectronMetricsServiceClient>();
}