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 2250775de6dd44b320501dddd349dd8a09d4b6ef..1a330dcb2cb393fd1ce58a650c8138565111b1df 100644 |
--- a/components/os_crypt/key_storage_libsecret.cc |
+++ b/components/os_crypt/key_storage_libsecret.cc |
@@ -11,42 +11,61 @@ |
namespace { |
-const SecretSchema kKeystoreSchema = { |
+#if defined(GOOGLE_CHROME_BUILD) |
+const char kApplicationName[] = "chrome"; |
+#else |
+const char kApplicationName[] = "chromium"; |
+#endif |
+ |
+// Deprecated in M55 (crbug.com/639298) |
+const SecretSchema kKeystoreSchemaV1 = { |
"chrome_libsecret_os_crypt_password", |
SECRET_SCHEMA_NONE, |
{ |
{nullptr, SECRET_SCHEMA_ATTRIBUTE_STRING}, |
}}; |
+const SecretSchema kKeystoreSchemaV2 = { |
+ "chrome_libsecret_os_crypt_password_v2", |
+ SECRET_SCHEMA_DONT_MATCH_NAME, |
+ { |
+ {"application", SECRET_SCHEMA_ATTRIBUTE_STRING}, |
+ {nullptr, SECRET_SCHEMA_ATTRIBUTE_STRING}, |
+ }}; |
+ |
} // namespace |
std::string KeyStorageLibsecret::AddRandomPasswordInLibsecret() { |
std::string password; |
base::Base64Encode(base::RandBytesAsString(16), &password); |
GError* error = nullptr; |
- LibsecretLoader::secret_password_store_sync( |
- &kKeystoreSchema, nullptr, KeyStorageLinux::kKey, password.c_str(), |
- nullptr, &error, nullptr); |
- |
- if (error) { |
+ bool success = LibsecretLoader::secret_password_store_sync( |
+ &kKeystoreSchemaV2, nullptr, KeyStorageLinux::kKey, password.c_str(), |
+ nullptr, &error, "application", kApplicationName, nullptr); |
+ if (error || !success) { |
VLOG(1) << "Libsecret lookup failed: " << error->message; |
return std::string(); |
} |
+ |
+ VLOG(1) << "OSCrypt generated a new password."; |
return password; |
} |
std::string KeyStorageLibsecret::GetKey() { |
GError* error = nullptr; |
LibsecretAttributesBuilder attrs; |
+ attrs.Append("application", kApplicationName); |
SecretValue* password_libsecret = LibsecretLoader::secret_service_lookup_sync( |
- nullptr, &kKeystoreSchema, attrs.Get(), nullptr, &error); |
- |
+ nullptr, &kKeystoreSchemaV2, attrs.Get(), nullptr, &error); |
if (error) { |
VLOG(1) << "Libsecret lookup failed: " << error->message; |
g_error_free(error); |
return std::string(); |
} |
if (!password_libsecret) { |
+ std::string password = Migrate(); |
+ if (!password.empty()) |
+ return password; |
return AddRandomPasswordInLibsecret(); |
} |
std::string password( |
@@ -58,3 +77,34 @@ std::string KeyStorageLibsecret::GetKey() { |
bool KeyStorageLibsecret::Init() { |
return LibsecretLoader::EnsureLibsecretLoaded(); |
} |
+ |
+std::string KeyStorageLibsecret::Migrate() { |
+ GError* error = nullptr; |
+ LibsecretAttributesBuilder attrs; |
+ |
+ // Detect old entry. |
+ SecretValue* password_libsecret = LibsecretLoader::secret_service_lookup_sync( |
+ nullptr, &kKeystoreSchemaV1, attrs.Get(), nullptr, &error); |
+ if (error || !password_libsecret) |
+ return std::string(); |
+ |
+ VLOG(1) << "OSCrypt detected a deprecated password in Libsecret."; |
+ std::string password( |
+ LibsecretLoader::secret_value_get_text(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) |
+ 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); |
+ |
+ VLOG(1) << "OSCrypt migrated from deprecated password."; |
+ |
+ return password; |
+} |