| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/password_manager/password_store_mac.h" | 5 #include "chrome/browser/password_manager/password_store_mac.h" |
| 6 | 6 |
| 7 #include <CoreServices/CoreServices.h> | 7 #include <CoreServices/CoreServices.h> |
| 8 #include <stddef.h> | 8 #include <stddef.h> |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 #include <set> | 10 #include <set> |
| (...skipping 965 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 976 } | 976 } |
| 977 | 977 |
| 978 PasswordStoreMac::~PasswordStoreMac() {} | 978 PasswordStoreMac::~PasswordStoreMac() {} |
| 979 | 979 |
| 980 void PasswordStoreMac::InitWithTaskRunner( | 980 void PasswordStoreMac::InitWithTaskRunner( |
| 981 scoped_refptr<base::SingleThreadTaskRunner> background_task_runner) { | 981 scoped_refptr<base::SingleThreadTaskRunner> background_task_runner) { |
| 982 db_thread_runner_ = background_task_runner; | 982 db_thread_runner_ = background_task_runner; |
| 983 DCHECK(GetBackgroundTaskRunner()->BelongsToCurrentThread()); | 983 DCHECK(GetBackgroundTaskRunner()->BelongsToCurrentThread()); |
| 984 } | 984 } |
| 985 | 985 |
| 986 PasswordStoreMac::MigrationResult PasswordStoreMac::ImportFromKeychain() { | 986 // static |
| 987 DCHECK(GetBackgroundTaskRunner()->BelongsToCurrentThread()); | 987 PasswordStoreMac::MigrationResult PasswordStoreMac::ImportFromKeychain( |
| 988 if (!login_metadata_db_) | 988 password_manager::LoginDatabase* login_db, |
| 989 return LOGIN_DB_UNAVAILABLE; | 989 crypto::AppleKeychain* keychain) { |
| 990 | |
| 991 std::vector<std::unique_ptr<PasswordForm>> database_forms_new_format; | 990 std::vector<std::unique_ptr<PasswordForm>> database_forms_new_format; |
| 992 if (!login_metadata_db_->GetAutofillableLogins(&database_forms_new_format)) | 991 if (!login_db->GetAutofillableLogins(&database_forms_new_format)) |
| 993 return LOGIN_DB_FAILURE; | 992 return LOGIN_DB_FAILURE; |
| 994 ScopedVector<PasswordForm> database_forms = | 993 ScopedVector<PasswordForm> database_forms = |
| 995 ConvertToScopedVector(std::move(database_forms_new_format)); | 994 ConvertToScopedVector(std::move(database_forms_new_format)); |
| 996 | 995 |
| 997 ScopedVector<PasswordForm> uninteresting_forms; | 996 ScopedVector<PasswordForm> uninteresting_forms; |
| 998 internal_keychain_helpers::ExtractNonKeychainForms(&database_forms, | 997 internal_keychain_helpers::ExtractNonKeychainForms(&database_forms, |
| 999 &uninteresting_forms); | 998 &uninteresting_forms); |
| 1000 // If there are no passwords to lookup in the Keychain then we're done. | 999 // If there are no passwords to lookup in the Keychain then we're done. |
| 1001 if (database_forms.empty()) | 1000 if (database_forms.empty()) |
| 1002 return MIGRATION_OK; | 1001 return MIGRATION_OK; |
| 1003 | 1002 |
| 1004 // Mute the Keychain. | |
| 1005 chrome::ScopedSecKeychainSetUserInteractionAllowed user_interaction_allowed( | |
| 1006 false); | |
| 1007 | |
| 1008 // Make sure that the encryption key is retrieved from the Keychain so the | 1003 // Make sure that the encryption key is retrieved from the Keychain so the |
| 1009 // encryption can be done. | 1004 // encryption can be done. |
| 1010 std::string ciphertext; | 1005 std::string ciphertext; |
| 1011 if (!OSCrypt::EncryptString("test", &ciphertext)) | 1006 if (!OSCrypt::EncryptString("test", &ciphertext)) |
| 1012 return ENCRYPTOR_FAILURE; | 1007 return ENCRYPTOR_FAILURE; |
| 1013 | 1008 |
| 1009 // Mute the Keychain. |
| 1010 chrome::ScopedSecKeychainSetUserInteractionAllowed user_interaction_allowed( |
| 1011 false); |
| 1012 |
| 1014 // Retrieve the passwords. | 1013 // Retrieve the passwords. |
| 1015 // Get all the password attributes first. | 1014 // Get all the password attributes first. |
| 1016 std::vector<SecKeychainItemRef> keychain_items; | 1015 std::vector<SecKeychainItemRef> keychain_items; |
| 1017 std::vector<internal_keychain_helpers::ItemFormPair> item_form_pairs = | 1016 std::vector<internal_keychain_helpers::ItemFormPair> item_form_pairs = |
| 1018 internal_keychain_helpers:: | 1017 internal_keychain_helpers:: |
| 1019 ExtractAllKeychainItemAttributesIntoPasswordForms(&keychain_items, | 1018 ExtractAllKeychainItemAttributesIntoPasswordForms(&keychain_items, |
| 1020 *keychain_); | 1019 *keychain); |
| 1021 | 1020 |
| 1022 // Next, compare the attributes of the PasswordForms in |database_forms| | 1021 // Next, compare the attributes of the PasswordForms in |database_forms| |
| 1023 // against those in |item_form_pairs|, and extract password data for each | 1022 // against those in |item_form_pairs|, and extract password data for each |
| 1024 // matching PasswordForm using its corresponding SecKeychainItemRef. | 1023 // matching PasswordForm using its corresponding SecKeychainItemRef. |
| 1025 size_t unmerged_forms_count = 0; | 1024 size_t unmerged_forms_count = 0; |
| 1026 size_t chrome_owned_locked_forms_count = 0; | 1025 login_db->set_clear_password_values(false); |
| 1027 for (PasswordForm* form : database_forms) { | 1026 for (PasswordForm* form : database_forms) { |
| 1028 ScopedVector<autofill::PasswordForm> keychain_matches = | 1027 ScopedVector<autofill::PasswordForm> keychain_matches = |
| 1029 internal_keychain_helpers::ExtractPasswordsMergeableWithForm( | 1028 internal_keychain_helpers::ExtractPasswordsMergeableWithForm( |
| 1030 *keychain_, item_form_pairs, *form); | 1029 *keychain, item_form_pairs, *form); |
| 1031 | 1030 |
| 1032 const PasswordForm* best_match = | 1031 const PasswordForm* best_match = |
| 1033 BestKeychainFormForForm(*form, keychain_matches.get()); | 1032 BestKeychainFormForForm(*form, keychain_matches.get()); |
| 1034 if (best_match) { | 1033 if (best_match) { |
| 1035 form->password_value = best_match->password_value; | 1034 form->password_value = best_match->password_value; |
| 1035 PasswordStoreChangeList change = login_db->UpdateLogin(*form); |
| 1036 DCHECK_EQ(1u, change.size()); |
| 1036 } else { | 1037 } else { |
| 1037 unmerged_forms_count++; | 1038 unmerged_forms_count++; |
| 1038 // Check if any corresponding keychain items are created by Chrome. | 1039 bool removed = login_db->RemoveLogin(*form); |
| 1039 for (const auto& item_form_pair : item_form_pairs) { | 1040 DCHECK(removed); |
| 1040 if (internal_keychain_helpers::FormIsValidAndMatchesOtherForm( | |
| 1041 *form, *item_form_pair.second) && | |
| 1042 internal_keychain_helpers::HasChromeCreatorCode( | |
| 1043 *keychain_, *item_form_pair.first)) | |
| 1044 chrome_owned_locked_forms_count++; | |
| 1045 } | |
| 1046 } | 1041 } |
| 1047 } | 1042 } |
| 1048 base::STLDeleteContainerPairSecondPointers(item_form_pairs.begin(), | 1043 base::STLDeleteContainerPairSecondPointers(item_form_pairs.begin(), |
| 1049 item_form_pairs.end()); | 1044 item_form_pairs.end()); |
| 1050 for (SecKeychainItemRef item : keychain_items) | 1045 for (SecKeychainItemRef item : keychain_items) |
| 1051 keychain_->Free(item); | 1046 keychain->Free(item); |
| 1052 | 1047 |
| 1053 if (unmerged_forms_count) { | 1048 if (unmerged_forms_count) { |
| 1054 UMA_HISTOGRAM_COUNTS( | 1049 UMA_HISTOGRAM_COUNTS( |
| 1055 "PasswordManager.KeychainMigration.NumPasswordsOnFailure", | 1050 "PasswordManager.KeychainMigration.NumPasswordsOnFailure", |
| 1056 database_forms.size()); | 1051 database_forms.size()); |
| 1057 UMA_HISTOGRAM_COUNTS("PasswordManager.KeychainMigration.NumFailedPasswords", | 1052 UMA_HISTOGRAM_COUNTS("PasswordManager.KeychainMigration.NumFailedPasswords", |
| 1058 unmerged_forms_count); | 1053 unmerged_forms_count); |
| 1059 UMA_HISTOGRAM_COUNTS( | 1054 return MIGRATION_PARTIAL; |
| 1060 "PasswordManager.KeychainMigration.NumChromeOwnedInaccessiblePasswords", | |
| 1061 chrome_owned_locked_forms_count); | |
| 1062 return KEYCHAIN_BLOCKED; | |
| 1063 } | 1055 } |
| 1064 // Now all the passwords are available. It's time to update LoginDatabase. | |
| 1065 login_metadata_db_->set_clear_password_values(false); | |
| 1066 for (PasswordForm* form : database_forms) | |
| 1067 login_metadata_db_->UpdateLogin(*form); | |
| 1068 return MIGRATION_OK; | 1056 return MIGRATION_OK; |
| 1069 } | 1057 } |
| 1070 | 1058 |
| 1059 // static |
| 1060 void PasswordStoreMac::CleanUpKeychain( |
| 1061 crypto::AppleKeychain* keychain, |
| 1062 const std::vector<std::unique_ptr<autofill::PasswordForm>>& forms) { |
| 1063 MacKeychainPasswordFormAdapter keychain_adapter(keychain); |
| 1064 keychain_adapter.SetFindsOnlyOwnedItems(true); |
| 1065 for (const auto& form : forms) |
| 1066 keychain_adapter.RemovePassword(*form); |
| 1067 } |
| 1068 |
| 1071 void PasswordStoreMac::set_login_metadata_db( | 1069 void PasswordStoreMac::set_login_metadata_db( |
| 1072 password_manager::LoginDatabase* login_db) { | 1070 password_manager::LoginDatabase* login_db) { |
| 1073 login_metadata_db_ = login_db; | 1071 login_metadata_db_ = login_db; |
| 1074 if (login_metadata_db_) | 1072 if (login_metadata_db_) |
| 1075 login_metadata_db_->set_clear_password_values(true); | 1073 login_metadata_db_->set_clear_password_values(true); |
| 1076 } | 1074 } |
| 1077 | 1075 |
| 1078 bool PasswordStoreMac::Init( | 1076 bool PasswordStoreMac::Init( |
| 1079 const syncer::SyncableService::StartSyncFlare& flare) { | 1077 const syncer::SyncableService::StartSyncFlare& flare) { |
| 1080 // The class should be used inside PasswordStoreProxyMac only. | 1078 // The class should be used inside PasswordStoreProxyMac only. |
| (...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1426 ScopedVector<PasswordForm> forms_with_keychain_entry; | 1424 ScopedVector<PasswordForm> forms_with_keychain_entry; |
| 1427 internal_keychain_helpers::GetPasswordsForForms(*keychain_, &database_forms, | 1425 internal_keychain_helpers::GetPasswordsForForms(*keychain_, &database_forms, |
| 1428 &forms_with_keychain_entry); | 1426 &forms_with_keychain_entry); |
| 1429 | 1427 |
| 1430 // Clean up any orphaned database entries. | 1428 // Clean up any orphaned database entries. |
| 1431 RemoveDatabaseForms(&database_forms); | 1429 RemoveDatabaseForms(&database_forms); |
| 1432 | 1430 |
| 1433 // Move the orphaned DB forms to the output parameter. | 1431 // Move the orphaned DB forms to the output parameter. |
| 1434 AppendSecondToFirst(orphaned_forms, &database_forms); | 1432 AppendSecondToFirst(orphaned_forms, &database_forms); |
| 1435 } | 1433 } |
| OLD | NEW |