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 |