| Index: chrome/browser/password_manager/password_store_mac.cc
|
| diff --git a/chrome/browser/password_manager/password_store_mac.cc b/chrome/browser/password_manager/password_store_mac.cc
|
| index 391bb3508592de3aa79177b43bbb4cc96f072661..45e5666ad8eebdeefbc528700e9e4752584005eb 100644
|
| --- a/chrome/browser/password_manager/password_store_mac.cc
|
| +++ b/chrome/browser/password_manager/password_store_mac.cc
|
| @@ -983,13 +983,12 @@ void PasswordStoreMac::InitWithTaskRunner(
|
| DCHECK(GetBackgroundTaskRunner()->BelongsToCurrentThread());
|
| }
|
|
|
| -PasswordStoreMac::MigrationResult PasswordStoreMac::ImportFromKeychain() {
|
| - DCHECK(GetBackgroundTaskRunner()->BelongsToCurrentThread());
|
| - if (!login_metadata_db_)
|
| - return LOGIN_DB_UNAVAILABLE;
|
| -
|
| +// static
|
| +PasswordStoreMac::MigrationResult PasswordStoreMac::ImportFromKeychain(
|
| + password_manager::LoginDatabase* login_db,
|
| + crypto::AppleKeychain* keychain) {
|
| std::vector<std::unique_ptr<PasswordForm>> database_forms_new_format;
|
| - if (!login_metadata_db_->GetAutofillableLogins(&database_forms_new_format))
|
| + if (!login_db->GetAutofillableLogins(&database_forms_new_format))
|
| return LOGIN_DB_FAILURE;
|
| ScopedVector<PasswordForm> database_forms =
|
| ConvertToScopedVector(std::move(database_forms_new_format));
|
| @@ -1001,54 +1000,50 @@ PasswordStoreMac::MigrationResult PasswordStoreMac::ImportFromKeychain() {
|
| if (database_forms.empty())
|
| return MIGRATION_OK;
|
|
|
| - // Mute the Keychain.
|
| - chrome::ScopedSecKeychainSetUserInteractionAllowed user_interaction_allowed(
|
| - false);
|
| -
|
| // Make sure that the encryption key is retrieved from the Keychain so the
|
| // encryption can be done.
|
| std::string ciphertext;
|
| if (!OSCrypt::EncryptString("test", &ciphertext))
|
| return ENCRYPTOR_FAILURE;
|
|
|
| + // Mute the Keychain.
|
| + chrome::ScopedSecKeychainSetUserInteractionAllowed user_interaction_allowed(
|
| + false);
|
| +
|
| // Retrieve the passwords.
|
| // Get all the password attributes first.
|
| std::vector<SecKeychainItemRef> keychain_items;
|
| std::vector<internal_keychain_helpers::ItemFormPair> item_form_pairs =
|
| internal_keychain_helpers::
|
| ExtractAllKeychainItemAttributesIntoPasswordForms(&keychain_items,
|
| - *keychain_);
|
| + *keychain);
|
|
|
| // Next, compare the attributes of the PasswordForms in |database_forms|
|
| // against those in |item_form_pairs|, and extract password data for each
|
| // matching PasswordForm using its corresponding SecKeychainItemRef.
|
| size_t unmerged_forms_count = 0;
|
| - size_t chrome_owned_locked_forms_count = 0;
|
| + login_db->set_clear_password_values(false);
|
| for (PasswordForm* form : database_forms) {
|
| ScopedVector<autofill::PasswordForm> keychain_matches =
|
| internal_keychain_helpers::ExtractPasswordsMergeableWithForm(
|
| - *keychain_, item_form_pairs, *form);
|
| + *keychain, item_form_pairs, *form);
|
|
|
| const PasswordForm* best_match =
|
| BestKeychainFormForForm(*form, keychain_matches.get());
|
| if (best_match) {
|
| form->password_value = best_match->password_value;
|
| + PasswordStoreChangeList change = login_db->UpdateLogin(*form);
|
| + DCHECK_EQ(1u, change.size());
|
| } else {
|
| unmerged_forms_count++;
|
| - // Check if any corresponding keychain items are created by Chrome.
|
| - for (const auto& item_form_pair : item_form_pairs) {
|
| - if (internal_keychain_helpers::FormIsValidAndMatchesOtherForm(
|
| - *form, *item_form_pair.second) &&
|
| - internal_keychain_helpers::HasChromeCreatorCode(
|
| - *keychain_, *item_form_pair.first))
|
| - chrome_owned_locked_forms_count++;
|
| - }
|
| + bool removed = login_db->RemoveLogin(*form);
|
| + DCHECK(removed);
|
| }
|
| }
|
| base::STLDeleteContainerPairSecondPointers(item_form_pairs.begin(),
|
| item_form_pairs.end());
|
| for (SecKeychainItemRef item : keychain_items)
|
| - keychain_->Free(item);
|
| + keychain->Free(item);
|
|
|
| if (unmerged_forms_count) {
|
| UMA_HISTOGRAM_COUNTS(
|
| @@ -1056,18 +1051,21 @@ PasswordStoreMac::MigrationResult PasswordStoreMac::ImportFromKeychain() {
|
| database_forms.size());
|
| UMA_HISTOGRAM_COUNTS("PasswordManager.KeychainMigration.NumFailedPasswords",
|
| unmerged_forms_count);
|
| - UMA_HISTOGRAM_COUNTS(
|
| - "PasswordManager.KeychainMigration.NumChromeOwnedInaccessiblePasswords",
|
| - chrome_owned_locked_forms_count);
|
| - return KEYCHAIN_BLOCKED;
|
| + return MIGRATION_PARTIAL;
|
| }
|
| - // Now all the passwords are available. It's time to update LoginDatabase.
|
| - login_metadata_db_->set_clear_password_values(false);
|
| - for (PasswordForm* form : database_forms)
|
| - login_metadata_db_->UpdateLogin(*form);
|
| return MIGRATION_OK;
|
| }
|
|
|
| +// static
|
| +void PasswordStoreMac::CleanUpKeychain(
|
| + crypto::AppleKeychain* keychain,
|
| + const std::vector<std::unique_ptr<autofill::PasswordForm>>& forms) {
|
| + MacKeychainPasswordFormAdapter keychain_adapter(keychain);
|
| + keychain_adapter.SetFindsOnlyOwnedItems(true);
|
| + for (const auto& form : forms)
|
| + keychain_adapter.RemovePassword(*form);
|
| +}
|
| +
|
| void PasswordStoreMac::set_login_metadata_db(
|
| password_manager::LoginDatabase* login_db) {
|
| login_metadata_db_ = login_db;
|
|
|