mirror of
https://github.com/electron/electron.git
synced 2026-04-10 03:01:51 -04:00
* feat: support Freedesktop Secret Service OSCrypt client Refs https://issues.chromium.org/issues/40086962 Refs https://issues.chromium.org/issues/447372315 * chore: rework to async interface * refactor: allow customizing freedesktop config * docs: add more async impl info * refactor: reject when temporarily unavailable * chore: feedback from review * chore: push_back => emplace_back
226 lines
9.0 KiB
Diff
226 lines
9.0 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Shelley Vohr <shelley.vohr@gmail.com>
|
|
Date: Tue, 20 Jan 2026 10:20:39 +0000
|
|
Subject: refactor: allow customizing config in FreedesktopSecretKeyProvider
|
|
|
|
This commit allows customizing components of the FreedesktopSecretKeyProvider
|
|
via config, specifically:
|
|
* App name
|
|
* KWallet folder name
|
|
* KWallet key name
|
|
|
|
This allows FreedesktopSecretKeyProvider to be used by multiple apps without
|
|
naming conflicts. This should be upstreamed to Chromium if possible.
|
|
|
|
diff --git a/components/os_crypt/async/browser/freedesktop_secret_key_provider.cc b/components/os_crypt/async/browser/freedesktop_secret_key_provider.cc
|
|
index c45f79eea18190a9216fd5ff1b3cf9d0d86ec059..356c6931017c83f7a89c5125f0bb90c8bc58569d 100644
|
|
--- a/components/os_crypt/async/browser/freedesktop_secret_key_provider.cc
|
|
+++ b/components/os_crypt/async/browser/freedesktop_secret_key_provider.cc
|
|
@@ -36,6 +36,30 @@ namespace os_crypt_async {
|
|
|
|
namespace {
|
|
|
|
+const char* GetDefaultAppName() {
|
|
+#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
|
|
+ return "chrome";
|
|
+#else
|
|
+ return "chromium";
|
|
+#endif
|
|
+}
|
|
+
|
|
+const char* GetDefaultKWalletFolder() {
|
|
+#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
|
|
+ return "Chrome Keys";
|
|
+#else
|
|
+ return "Chromium Keys";
|
|
+#endif
|
|
+}
|
|
+
|
|
+const char* GetDefaultKeyName() {
|
|
+#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
|
|
+ return "Chrome Safe Storage";
|
|
+#else
|
|
+ return "Chromium Safe Storage";
|
|
+#endif
|
|
+}
|
|
+
|
|
constexpr char kUmaInitStatus[] =
|
|
"OSCrypt.FreedesktopSecretKeyProvider.InitStatus";
|
|
constexpr char kUmaErrorDetail[] =
|
|
@@ -116,6 +140,24 @@ const char* InitStatusToString(
|
|
|
|
} // namespace
|
|
|
|
+FreedesktopSecretKeyProvider::Config::Config()
|
|
+ : app_name(GetDefaultAppName()),
|
|
+ kwallet_folder(GetDefaultKWalletFolder()),
|
|
+ key_name(GetDefaultKeyName()) {}
|
|
+
|
|
+FreedesktopSecretKeyProvider::Config::~Config() = default;
|
|
+
|
|
+FreedesktopSecretKeyProvider::Config::Config(const Config&) = default;
|
|
+
|
|
+FreedesktopSecretKeyProvider::Config&
|
|
+FreedesktopSecretKeyProvider::Config::operator=(const Config&) = default;
|
|
+
|
|
+// static
|
|
+FreedesktopSecretKeyProvider::Config
|
|
+FreedesktopSecretKeyProvider::GetDefaultConfig() {
|
|
+ return Config();
|
|
+}
|
|
+
|
|
// A helper class to handle a Secret Service prompt. It is templated on the
|
|
// return type expected from the prompt.
|
|
template <typename T>
|
|
@@ -246,8 +288,19 @@ FreedesktopSecretKeyProvider::FreedesktopSecretKeyProvider(
|
|
const std::string& password_store,
|
|
const std::string& product_name,
|
|
scoped_refptr<dbus::Bus> bus)
|
|
+ : FreedesktopSecretKeyProvider(password_store,
|
|
+ product_name,
|
|
+ GetDefaultConfig(),
|
|
+ std::move(bus)) {}
|
|
+
|
|
+FreedesktopSecretKeyProvider::FreedesktopSecretKeyProvider(
|
|
+ const std::string& password_store,
|
|
+ const std::string& product_name,
|
|
+ const Config& config,
|
|
+ scoped_refptr<dbus::Bus> bus)
|
|
: password_store_(password_store),
|
|
product_name_(product_name),
|
|
+ config_(config),
|
|
bus_(std::move(bus)) {
|
|
if (!bus_) {
|
|
bus_ = dbus_thread_linux::GetSharedSessionBus();
|
|
@@ -479,7 +532,7 @@ void FreedesktopSecretKeyProvider::OnOpenSession(
|
|
session_opened_ = true;
|
|
|
|
std::map<std::string, std::string> search_attrs{
|
|
- {kApplicationAttributeKey, kAppName}};
|
|
+ {kApplicationAttributeKey, config_.app_name}};
|
|
|
|
dbus_utils::CallMethod<"a{ss}", "ao">(
|
|
default_collection_proxy_, kSecretCollectionInterface, kMethodSearchItems,
|
|
@@ -668,7 +721,7 @@ void FreedesktopSecretKeyProvider::OnKWalletOpen(int32_t handle) {
|
|
kwallet_proxy_, kKWalletInterface, kKWalletMethodHasFolder,
|
|
base::BindOnce(&FreedesktopSecretKeyProvider::OnKWalletHasFolder,
|
|
weak_ptr_factory_.GetWeakPtr()),
|
|
- kwallet_handle_, kKWalletFolder, product_name_);
|
|
+ kwallet_handle_, config_.kwallet_folder, product_name_);
|
|
}
|
|
|
|
void FreedesktopSecretKeyProvider::OnKWalletHasFolder(
|
|
@@ -685,13 +738,13 @@ void FreedesktopSecretKeyProvider::OnKWalletHasFolder(
|
|
kwallet_proxy_, kKWalletInterface, kKWalletMethodHasEntry,
|
|
base::BindOnce(&FreedesktopSecretKeyProvider::OnKWalletHasEntry,
|
|
weak_ptr_factory_.GetWeakPtr()),
|
|
- kwallet_handle_, kKWalletFolder, kKeyName, product_name_);
|
|
+ kwallet_handle_, config_.kwallet_folder, config_.key_name, product_name_);
|
|
} else {
|
|
dbus_utils::CallMethod<"iss", "b">(
|
|
kwallet_proxy_, kKWalletInterface, kKWalletMethodCreateFolder,
|
|
base::BindOnce(&FreedesktopSecretKeyProvider::OnKWalletCreateFolder,
|
|
weak_ptr_factory_.GetWeakPtr()),
|
|
- kwallet_handle_, kKWalletFolder, product_name_);
|
|
+ kwallet_handle_, config_.kwallet_folder, product_name_);
|
|
}
|
|
}
|
|
|
|
@@ -725,7 +778,7 @@ void FreedesktopSecretKeyProvider::OnKWalletHasEntry(
|
|
kwallet_proxy_, kKWalletInterface, kKWalletMethodReadPassword,
|
|
base::BindOnce(&FreedesktopSecretKeyProvider::OnKWalletReadPassword,
|
|
weak_ptr_factory_.GetWeakPtr()),
|
|
- kwallet_handle_, kKWalletFolder, kKeyName, product_name_);
|
|
+ kwallet_handle_, config_.kwallet_folder, config_.key_name, product_name_);
|
|
} else {
|
|
GenerateAndWriteKWalletPassword();
|
|
}
|
|
@@ -761,7 +814,7 @@ void FreedesktopSecretKeyProvider::GenerateAndWriteKWalletPassword() {
|
|
kwallet_proxy_, kKWalletInterface, kKWalletMethodWritePassword,
|
|
base::BindOnce(&FreedesktopSecretKeyProvider::OnKWalletWritePassword,
|
|
weak_ptr_factory_.GetWeakPtr(), secret),
|
|
- kwallet_handle_, kKWalletFolder, kKeyName, secret->as_string(),
|
|
+ kwallet_handle_, config_.kwallet_folder, config_.key_name, secret->as_string(),
|
|
product_name_);
|
|
}
|
|
|
|
@@ -789,14 +842,14 @@ void FreedesktopSecretKeyProvider::OnKWalletWritePassword(
|
|
void FreedesktopSecretKeyProvider::CreateItem(
|
|
scoped_refptr<base::RefCountedMemory> secret) {
|
|
std::map<std::string, std::string> attributes{
|
|
- {kApplicationAttributeKey, kAppName},
|
|
+ {kApplicationAttributeKey, config_.app_name},
|
|
{kSchemaAttributeKey, kSchemaAttributeValue}};
|
|
|
|
std::map<std::string, dbus_utils::Variant> props;
|
|
props.emplace(kSecretItemAttributesProperty,
|
|
dbus_utils::Variant::Wrap<"a{ss}">(std::move(attributes)));
|
|
props.emplace(kSecretItemLabelProperty,
|
|
- dbus_utils::Variant::Wrap<"s">(kKeyName));
|
|
+ dbus_utils::Variant::Wrap<"s">(config_.key_name));
|
|
|
|
std::vector<uint8_t> secret_bytes(secret->begin(), secret->end());
|
|
auto secret_struct =
|
|
diff --git a/components/os_crypt/async/browser/freedesktop_secret_key_provider.h b/components/os_crypt/async/browser/freedesktop_secret_key_provider.h
|
|
index bc2c74090d3db088b97132c5cd83950510fe85b4..38f6384083537f60d12f016fbb67adc694e6f457 100644
|
|
--- a/components/os_crypt/async/browser/freedesktop_secret_key_provider.h
|
|
+++ b/components/os_crypt/async/browser/freedesktop_secret_key_provider.h
|
|
@@ -81,11 +81,32 @@ class FreedesktopSecretKeyProvider : public KeyProvider {
|
|
kMaxValue = kExtraDataInResponse,
|
|
};
|
|
|
|
+ struct Config {
|
|
+ Config();
|
|
+ ~Config();
|
|
+ Config(const Config&);
|
|
+ Config& operator=(const Config&);
|
|
+
|
|
+ // The application name used for D-Bus attributes.
|
|
+ std::string app_name;
|
|
+ // The folder name used in KWallet.
|
|
+ std::string kwallet_folder;
|
|
+ // The key name used for storing the encryption key.
|
|
+ std::string key_name;
|
|
+ };
|
|
+
|
|
FreedesktopSecretKeyProvider(const std::string& password_store,
|
|
const std::string& product_name,
|
|
scoped_refptr<dbus::Bus> bus);
|
|
+ FreedesktopSecretKeyProvider(const std::string& password_store,
|
|
+ const std::string& product_name,
|
|
+ const Config& config,
|
|
+ scoped_refptr<dbus::Bus> bus);
|
|
~FreedesktopSecretKeyProvider() override;
|
|
|
|
+ // Returns the default configuration with platform-specific defaults.
|
|
+ static Config GetDefaultConfig();
|
|
+
|
|
// KeyProvider:
|
|
void GetKey(KeyCallback callback) override;
|
|
bool UseForEncryption() override;
|
|
@@ -172,16 +193,6 @@ class FreedesktopSecretKeyProvider : public KeyProvider {
|
|
static constexpr int kKWalletInvalidHandle = -1;
|
|
static constexpr int kKWalletInvalidTransactionId = -1;
|
|
|
|
-#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
|
|
- static constexpr char kKWalletFolder[] = "Chrome Keys";
|
|
- static constexpr char kKeyName[] = "Chrome Safe Storage";
|
|
- static constexpr char kAppName[] = "chrome";
|
|
-#else
|
|
- static constexpr char kKWalletFolder[] = "Chromium Keys";
|
|
- static constexpr char kKeyName[] = "Chromium Safe Storage";
|
|
- static constexpr char kAppName[] = "chromium";
|
|
-#endif
|
|
-
|
|
void InitializeFreedesktopSecretService();
|
|
void OnServiceStarted(std::optional<bool> service_started);
|
|
void OnReadAliasDefault(dbus_utils::CallMethodResultSig<"o"> collection_path);
|
|
@@ -238,6 +249,7 @@ class FreedesktopSecretKeyProvider : public KeyProvider {
|
|
|
|
const std::string password_store_;
|
|
const std::string product_name_;
|
|
+ const Config config_;
|
|
scoped_refptr<dbus::Bus> bus_;
|
|
KeyCallback key_callback_;
|
|
|