| Index: components/os_crypt/key_storage_libsecret.cc
|
| diff --git a/components/os_crypt/key_storage_libsecret.cc b/components/os_crypt/key_storage_libsecret.cc
|
| index 1a330dcb2cb393fd1ce58a650c8138565111b1df..32c6d0905e17f1354b1c9e26ad2648ee9dd5b2ed 100644
|
| --- a/components/os_crypt/key_storage_libsecret.cc
|
| +++ b/components/os_crypt/key_storage_libsecret.cc
|
| @@ -33,6 +33,22 @@ const SecretSchema kKeystoreSchemaV2 = {
|
| {nullptr, SECRET_SCHEMA_ATTRIBUTE_STRING},
|
| }};
|
|
|
| +// From a search result, extracts a SecretValue, asserting that there was at
|
| +// most one result. Returns nullptr if there are no results.
|
| +SecretValue* ToSingleSecret(GList* secret_items) {
|
| + GList* first = g_list_first(secret_items);
|
| + if (first == nullptr)
|
| + return nullptr;
|
| + if (g_list_next(first) != nullptr) {
|
| + VLOG(1) << "OSCrypt found more than one encryption keys.";
|
| + }
|
| + SecretItem* secret_item = static_cast<SecretItem*>(first->data);
|
| + SecretValue* secret_value =
|
| + LibsecretLoader::secret_item_get_secret(secret_item);
|
| + g_list_free(secret_items);
|
| + return secret_value;
|
| +}
|
| +
|
| } // namespace
|
|
|
| std::string KeyStorageLibsecret::AddRandomPasswordInLibsecret() {
|
| @@ -42,8 +58,13 @@ std::string KeyStorageLibsecret::AddRandomPasswordInLibsecret() {
|
| bool success = LibsecretLoader::secret_password_store_sync(
|
| &kKeystoreSchemaV2, nullptr, KeyStorageLinux::kKey, password.c_str(),
|
| nullptr, &error, "application", kApplicationName, nullptr);
|
| - if (error || !success) {
|
| + if (error) {
|
| VLOG(1) << "Libsecret lookup failed: " << error->message;
|
| + g_error_free(error);
|
| + return std::string();
|
| + }
|
| + if (!success) {
|
| + VLOG(1) << "Libsecret lookup failed.";
|
| return std::string();
|
| }
|
|
|
| @@ -55,13 +76,17 @@ std::string KeyStorageLibsecret::GetKey() {
|
| GError* error = nullptr;
|
| LibsecretAttributesBuilder attrs;
|
| attrs.Append("application", kApplicationName);
|
| - SecretValue* password_libsecret = LibsecretLoader::secret_service_lookup_sync(
|
| - nullptr, &kKeystoreSchemaV2, attrs.Get(), nullptr, &error);
|
| + GList* search_results = LibsecretLoader::secret_service_search_sync(
|
| + nullptr /* default secret service */, &kKeystoreSchemaV2, attrs.Get(),
|
| + static_cast<SecretSearchFlags>(SECRET_SEARCH_UNLOCK |
|
| + SECRET_SEARCH_LOAD_SECRETS),
|
| + nullptr, &error);
|
| if (error) {
|
| VLOG(1) << "Libsecret lookup failed: " << error->message;
|
| g_error_free(error);
|
| return std::string();
|
| }
|
| + SecretValue* password_libsecret = ToSingleSecret(search_results);
|
| if (!password_libsecret) {
|
| std::string password = Migrate();
|
| if (!password.empty())
|
| @@ -83,26 +108,48 @@ std::string KeyStorageLibsecret::Migrate() {
|
| LibsecretAttributesBuilder attrs;
|
|
|
| // Detect old entry.
|
| - SecretValue* password_libsecret = LibsecretLoader::secret_service_lookup_sync(
|
| - nullptr, &kKeystoreSchemaV1, attrs.Get(), nullptr, &error);
|
| - if (error || !password_libsecret)
|
| + GList* search_results = LibsecretLoader::secret_service_search_sync(
|
| + nullptr /* default secret service */, &kKeystoreSchemaV1, attrs.Get(),
|
| + static_cast<SecretSearchFlags>(SECRET_SEARCH_UNLOCK |
|
| + SECRET_SEARCH_LOAD_SECRETS),
|
| + nullptr, &error);
|
| + if (error) {
|
| + g_error_free(error);
|
| + g_list_free(search_results);
|
| + return std::string();
|
| + }
|
| + SecretValue* password_libsecret = ToSingleSecret(search_results);
|
| + if (!password_libsecret)
|
| return std::string();
|
|
|
| VLOG(1) << "OSCrypt detected a deprecated password in Libsecret.";
|
| std::string password(
|
| LibsecretLoader::secret_value_get_text(password_libsecret));
|
| + LibsecretLoader::secret_value_unref(password_libsecret);
|
|
|
| // Create new entry.
|
| bool success = LibsecretLoader::secret_password_store_sync(
|
| &kKeystoreSchemaV2, nullptr, KeyStorageLinux::kKey, password.c_str(),
|
| nullptr, &error, "application", kApplicationName, nullptr);
|
| - if (error || !success)
|
| + if (error) {
|
| + VLOG(1) << "Failed to store migrated password. " << error->message;
|
| + g_error_free(error);
|
| return std::string();
|
| + }
|
| + if (!success) {
|
| + VLOG(1) << "Failed to store migrated password.";
|
| + return std::string();
|
| + }
|
|
|
| // Delete old entry.
|
| // Even if deletion failed, we have to use the password that we created.
|
| success = LibsecretLoader::secret_password_clear_sync(
|
| &kKeystoreSchemaV1, nullptr, &error, nullptr);
|
| + if (error) {
|
| + VLOG(1) << "OSCrypt failed to delete deprecated password. "
|
| + << error->message;
|
| + g_error_free(error);
|
| + }
|
|
|
| VLOG(1) << "OSCrypt migrated from deprecated password.";
|
|
|
|
|