| 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 <set> | 9 #include <set> |
| 10 #include <string> | 10 #include <string> |
| (...skipping 482 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 493 // Moves entries from |forms| that represent either blacklisted or federated | 493 // Moves entries from |forms| that represent either blacklisted or federated |
| 494 // logins into |extracted|. These two types are stored only in the LoginDatabase | 494 // logins into |extracted|. These two types are stored only in the LoginDatabase |
| 495 // and do not have corresponding Keychain entries. | 495 // and do not have corresponding Keychain entries. |
| 496 void ExtractNonKeychainForms(ScopedVector<autofill::PasswordForm>* forms, | 496 void ExtractNonKeychainForms(ScopedVector<autofill::PasswordForm>* forms, |
| 497 ScopedVector<autofill::PasswordForm>* extracted) { | 497 ScopedVector<autofill::PasswordForm>* extracted) { |
| 498 extracted->reserve(extracted->size() + forms->size()); | 498 extracted->reserve(extracted->size() + forms->size()); |
| 499 ScopedVector<autofill::PasswordForm> remaining; | 499 ScopedVector<autofill::PasswordForm> remaining; |
| 500 MoveAllFormsOut( | 500 MoveAllFormsOut( |
| 501 forms, [&remaining, extracted](scoped_ptr<autofill::PasswordForm> form) { | 501 forms, [&remaining, extracted](scoped_ptr<autofill::PasswordForm> form) { |
| 502 if (IsLoginDatabaseOnlyForm(*form)) | 502 if (IsLoginDatabaseOnlyForm(*form)) |
| 503 extracted->push_back(form.Pass()); | 503 extracted->push_back(std::move(form)); |
| 504 else | 504 else |
| 505 remaining.push_back(form.Pass()); | 505 remaining.push_back(std::move(form)); |
| 506 }); | 506 }); |
| 507 forms->swap(remaining); | 507 forms->swap(remaining); |
| 508 } | 508 } |
| 509 | 509 |
| 510 // Takes |keychain_forms| and |database_forms| and moves the following 2 types | 510 // Takes |keychain_forms| and |database_forms| and moves the following 2 types |
| 511 // of forms to |merged_forms|: | 511 // of forms to |merged_forms|: |
| 512 // (1) |database_forms| that by principle never have a corresponding Keychain | 512 // (1) |database_forms| that by principle never have a corresponding Keychain |
| 513 // entry (viz., blacklisted and federated logins), | 513 // entry (viz., blacklisted and federated logins), |
| 514 // (2) |database_forms| which should have and do have a corresponding entry in | 514 // (2) |database_forms| which should have and do have a corresponding entry in |
| 515 // |keychain_forms|. | 515 // |keychain_forms|. |
| (...skipping 16 matching lines...) Expand all Loading... |
| 532 // forms or not. If there is a match, add its password to the DB form and | 532 // forms or not. If there is a match, add its password to the DB form and |
| 533 // mark the keychain form as used. | 533 // mark the keychain form as used. |
| 534 MoveAllFormsOut(database_forms, [keychain_forms, &used_keychain_forms, | 534 MoveAllFormsOut(database_forms, [keychain_forms, &used_keychain_forms, |
| 535 merged_forms, &unused_database_forms]( | 535 merged_forms, &unused_database_forms]( |
| 536 scoped_ptr<autofill::PasswordForm> form) { | 536 scoped_ptr<autofill::PasswordForm> form) { |
| 537 const PasswordForm* best_match = | 537 const PasswordForm* best_match = |
| 538 BestKeychainFormForForm(*form, keychain_forms->get()); | 538 BestKeychainFormForForm(*form, keychain_forms->get()); |
| 539 if (best_match) { | 539 if (best_match) { |
| 540 used_keychain_forms.insert(best_match); | 540 used_keychain_forms.insert(best_match); |
| 541 form->password_value = best_match->password_value; | 541 form->password_value = best_match->password_value; |
| 542 merged_forms->push_back(form.Pass()); | 542 merged_forms->push_back(std::move(form)); |
| 543 } else { | 543 } else { |
| 544 unused_database_forms.push_back(form.Pass()); | 544 unused_database_forms.push_back(std::move(form)); |
| 545 } | 545 } |
| 546 }); | 546 }); |
| 547 database_forms->swap(unused_database_forms); | 547 database_forms->swap(unused_database_forms); |
| 548 | 548 |
| 549 // Clear out all the Keychain entries we used. | 549 // Clear out all the Keychain entries we used. |
| 550 ScopedVector<autofill::PasswordForm> unused_keychain_forms; | 550 ScopedVector<autofill::PasswordForm> unused_keychain_forms; |
| 551 unused_keychain_forms.reserve(keychain_forms->size()); | 551 unused_keychain_forms.reserve(keychain_forms->size()); |
| 552 for (auto& keychain_form : *keychain_forms) { | 552 for (auto& keychain_form : *keychain_forms) { |
| 553 if (!ContainsKey(used_keychain_forms, keychain_form)) { | 553 if (!ContainsKey(used_keychain_forms, keychain_form)) { |
| 554 unused_keychain_forms.push_back(keychain_form); | 554 unused_keychain_forms.push_back(keychain_form); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 600 unused_db_forms.reserve(database_forms->size()); | 600 unused_db_forms.reserve(database_forms->size()); |
| 601 // Move database forms with a password stored in |keychain| to |passwords|, | 601 // Move database forms with a password stored in |keychain| to |passwords|, |
| 602 // including the password. The rest is moved to |unused_db_forms|. | 602 // including the password. The rest is moved to |unused_db_forms|. |
| 603 MoveAllFormsOut(database_forms, | 603 MoveAllFormsOut(database_forms, |
| 604 [&keychain, &item_form_pairs, passwords, &unused_db_forms]( | 604 [&keychain, &item_form_pairs, passwords, &unused_db_forms]( |
| 605 scoped_ptr<autofill::PasswordForm> form) { | 605 scoped_ptr<autofill::PasswordForm> form) { |
| 606 ScopedVector<autofill::PasswordForm> keychain_matches = | 606 ScopedVector<autofill::PasswordForm> keychain_matches = |
| 607 ExtractPasswordsMergeableWithForm(keychain, item_form_pairs, *form); | 607 ExtractPasswordsMergeableWithForm(keychain, item_form_pairs, *form); |
| 608 | 608 |
| 609 ScopedVector<autofill::PasswordForm> db_form_container; | 609 ScopedVector<autofill::PasswordForm> db_form_container; |
| 610 db_form_container.push_back(form.Pass()); | 610 db_form_container.push_back(std::move(form)); |
| 611 MergePasswordForms(&keychain_matches, &db_form_container, passwords); | 611 MergePasswordForms(&keychain_matches, &db_form_container, passwords); |
| 612 AppendSecondToFirst(&unused_db_forms, &db_form_container); | 612 AppendSecondToFirst(&unused_db_forms, &db_form_container); |
| 613 }); | 613 }); |
| 614 database_forms->swap(unused_db_forms); | 614 database_forms->swap(unused_db_forms); |
| 615 | 615 |
| 616 STLDeleteContainerPairSecondPointers(item_form_pairs.begin(), | 616 STLDeleteContainerPairSecondPointers(item_form_pairs.begin(), |
| 617 item_form_pairs.end()); | 617 item_form_pairs.end()); |
| 618 for (SecKeychainItemRef item : keychain_items) { | 618 for (SecKeychainItemRef item : keychain_items) { |
| 619 keychain.Free(item); | 619 keychain.Free(item); |
| 620 } | 620 } |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 684 i != item_form_pairs.end(); ++i) { | 684 i != item_form_pairs.end(); ++i) { |
| 685 if (FormIsValidAndMatchesOtherForm(query_form, *(i->second))) { | 685 if (FormIsValidAndMatchesOtherForm(query_form, *(i->second))) { |
| 686 // Create a new object, since the caller is responsible for deleting the | 686 // Create a new object, since the caller is responsible for deleting the |
| 687 // returned forms. | 687 // returned forms. |
| 688 scoped_ptr<PasswordForm> form_with_password(new PasswordForm()); | 688 scoped_ptr<PasswordForm> form_with_password(new PasswordForm()); |
| 689 FillPasswordFormFromKeychainItem( | 689 FillPasswordFormFromKeychainItem( |
| 690 keychain, *(i->first), form_with_password.get(), | 690 keychain, *(i->first), form_with_password.get(), |
| 691 true); // Load password attributes and data. | 691 true); // Load password attributes and data. |
| 692 // Do not include blacklisted items found in the keychain. | 692 // Do not include blacklisted items found in the keychain. |
| 693 if (!form_with_password->blacklisted_by_user) | 693 if (!form_with_password->blacklisted_by_user) |
| 694 matches.push_back(form_with_password.Pass()); | 694 matches.push_back(std::move(form_with_password)); |
| 695 } | 695 } |
| 696 } | 696 } |
| 697 return matches.Pass(); | 697 return matches; |
| 698 } | 698 } |
| 699 | 699 |
| 700 } // namespace internal_keychain_helpers | 700 } // namespace internal_keychain_helpers |
| 701 | 701 |
| 702 #pragma mark - | 702 #pragma mark - |
| 703 | 703 |
| 704 MacKeychainPasswordFormAdapter::MacKeychainPasswordFormAdapter( | 704 MacKeychainPasswordFormAdapter::MacKeychainPasswordFormAdapter( |
| 705 const AppleKeychain* keychain) | 705 const AppleKeychain* keychain) |
| 706 : keychain_(keychain), finds_only_owned_(false) { | 706 : keychain_(keychain), finds_only_owned_(false) { |
| 707 } | 707 } |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 834 } | 834 } |
| 835 | 835 |
| 836 ScopedVector<autofill::PasswordForm> | 836 ScopedVector<autofill::PasswordForm> |
| 837 MacKeychainPasswordFormAdapter::ConvertKeychainItemsToForms( | 837 MacKeychainPasswordFormAdapter::ConvertKeychainItemsToForms( |
| 838 std::vector<SecKeychainItemRef>* items) { | 838 std::vector<SecKeychainItemRef>* items) { |
| 839 ScopedVector<autofill::PasswordForm> forms; | 839 ScopedVector<autofill::PasswordForm> forms; |
| 840 for (SecKeychainItemRef item : *items) { | 840 for (SecKeychainItemRef item : *items) { |
| 841 scoped_ptr<PasswordForm> form(new PasswordForm()); | 841 scoped_ptr<PasswordForm> form(new PasswordForm()); |
| 842 if (internal_keychain_helpers::FillPasswordFormFromKeychainItem( | 842 if (internal_keychain_helpers::FillPasswordFormFromKeychainItem( |
| 843 *keychain_, item, form.get(), true)) { | 843 *keychain_, item, form.get(), true)) { |
| 844 forms.push_back(form.Pass()); | 844 forms.push_back(std::move(form)); |
| 845 } | 845 } |
| 846 keychain_->Free(item); | 846 keychain_->Free(item); |
| 847 } | 847 } |
| 848 items->clear(); | 848 items->clear(); |
| 849 return forms.Pass(); | 849 return forms; |
| 850 } | 850 } |
| 851 | 851 |
| 852 SecKeychainItemRef MacKeychainPasswordFormAdapter::KeychainItemForForm( | 852 SecKeychainItemRef MacKeychainPasswordFormAdapter::KeychainItemForForm( |
| 853 const PasswordForm& form) { | 853 const PasswordForm& form) { |
| 854 // We don't store blacklist entries in the keychain, so the answer to "what | 854 // We don't store blacklist entries in the keychain, so the answer to "what |
| 855 // Keychain item goes with this form" is always "nothing" for blacklists. | 855 // Keychain item goes with this form" is always "nothing" for blacklists. |
| 856 // Same goes for federated logins. | 856 // Same goes for federated logins. |
| 857 if (IsLoginDatabaseOnlyForm(form)) | 857 if (IsLoginDatabaseOnlyForm(form)) |
| 858 return NULL; | 858 return NULL; |
| 859 | 859 |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 951 return finds_only_owned_ ? base::mac::CreatorCodeForApplication() : 0; | 951 return finds_only_owned_ ? base::mac::CreatorCodeForApplication() : 0; |
| 952 } | 952 } |
| 953 | 953 |
| 954 #pragma mark - | 954 #pragma mark - |
| 955 | 955 |
| 956 PasswordStoreMac::PasswordStoreMac( | 956 PasswordStoreMac::PasswordStoreMac( |
| 957 scoped_refptr<base::SingleThreadTaskRunner> main_thread_runner, | 957 scoped_refptr<base::SingleThreadTaskRunner> main_thread_runner, |
| 958 scoped_refptr<base::SingleThreadTaskRunner> db_thread_runner, | 958 scoped_refptr<base::SingleThreadTaskRunner> db_thread_runner, |
| 959 scoped_ptr<AppleKeychain> keychain) | 959 scoped_ptr<AppleKeychain> keychain) |
| 960 : password_manager::PasswordStore(main_thread_runner, db_thread_runner), | 960 : password_manager::PasswordStore(main_thread_runner, db_thread_runner), |
| 961 keychain_(keychain.Pass()), | 961 keychain_(std::move(keychain)), |
| 962 login_metadata_db_(nullptr) { | 962 login_metadata_db_(nullptr) { |
| 963 DCHECK(keychain_); | 963 DCHECK(keychain_); |
| 964 } | 964 } |
| 965 | 965 |
| 966 PasswordStoreMac::~PasswordStoreMac() {} | 966 PasswordStoreMac::~PasswordStoreMac() {} |
| 967 | 967 |
| 968 void PasswordStoreMac::InitWithTaskRunner( | 968 void PasswordStoreMac::InitWithTaskRunner( |
| 969 scoped_refptr<base::SingleThreadTaskRunner> background_task_runner) { | 969 scoped_refptr<base::SingleThreadTaskRunner> background_task_runner) { |
| 970 db_thread_runner_ = background_task_runner; | 970 db_thread_runner_ = background_task_runner; |
| 971 DCHECK(GetBackgroundTaskRunner()->BelongsToCurrentThread()); | 971 DCHECK(GetBackgroundTaskRunner()->BelongsToCurrentThread()); |
| (...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1144 ScopedVector<PasswordForm> forms_to_remove; | 1144 ScopedVector<PasswordForm> forms_to_remove; |
| 1145 if (login_metadata_db_ && | 1145 if (login_metadata_db_ && |
| 1146 login_metadata_db_->GetLoginsCreatedBetween(delete_begin, delete_end, | 1146 login_metadata_db_->GetLoginsCreatedBetween(delete_begin, delete_end, |
| 1147 &forms_to_consider)) { | 1147 &forms_to_consider)) { |
| 1148 MoveAllFormsOut( | 1148 MoveAllFormsOut( |
| 1149 &forms_to_consider, | 1149 &forms_to_consider, |
| 1150 [this, &origin, &forms_to_remove]( | 1150 [this, &origin, &forms_to_remove]( |
| 1151 scoped_ptr<autofill::PasswordForm> form_to_consider) { | 1151 scoped_ptr<autofill::PasswordForm> form_to_consider) { |
| 1152 if (origin.IsSameOriginWith(url::Origin(form_to_consider->origin)) && | 1152 if (origin.IsSameOriginWith(url::Origin(form_to_consider->origin)) && |
| 1153 login_metadata_db_->RemoveLogin(*form_to_consider)) | 1153 login_metadata_db_->RemoveLogin(*form_to_consider)) |
| 1154 forms_to_remove.push_back(form_to_consider.Pass()); | 1154 forms_to_remove.push_back(std::move(form_to_consider)); |
| 1155 }); | 1155 }); |
| 1156 if (!forms_to_remove.empty()) { | 1156 if (!forms_to_remove.empty()) { |
| 1157 RemoveKeychainForms(forms_to_remove.get()); | 1157 RemoveKeychainForms(forms_to_remove.get()); |
| 1158 CleanOrphanedForms(&forms_to_remove); // Add the orphaned forms. | 1158 CleanOrphanedForms(&forms_to_remove); // Add the orphaned forms. |
| 1159 changes = FormsToRemoveChangeList(forms_to_remove.get()); | 1159 changes = FormsToRemoveChangeList(forms_to_remove.get()); |
| 1160 LogStatsForBulkDeletion(changes.size()); | 1160 LogStatsForBulkDeletion(changes.size()); |
| 1161 } | 1161 } |
| 1162 } | 1162 } |
| 1163 return changes; | 1163 return changes; |
| 1164 } | 1164 } |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1247 ScopedVector<PasswordForm> keychain_blacklist_forms; | 1247 ScopedVector<PasswordForm> keychain_blacklist_forms; |
| 1248 internal_keychain_helpers::ExtractNonKeychainForms(&keychain_forms, | 1248 internal_keychain_helpers::ExtractNonKeychainForms(&keychain_forms, |
| 1249 &keychain_blacklist_forms); | 1249 &keychain_blacklist_forms); |
| 1250 AppendSecondToFirst(&matched_forms, &keychain_forms); | 1250 AppendSecondToFirst(&matched_forms, &keychain_forms); |
| 1251 | 1251 |
| 1252 if (!database_forms.empty()) { | 1252 if (!database_forms.empty()) { |
| 1253 RemoveDatabaseForms(&database_forms); | 1253 RemoveDatabaseForms(&database_forms); |
| 1254 NotifyLoginsChanged(FormsToRemoveChangeList(database_forms.get())); | 1254 NotifyLoginsChanged(FormsToRemoveChangeList(database_forms.get())); |
| 1255 } | 1255 } |
| 1256 | 1256 |
| 1257 return matched_forms.Pass(); | 1257 return matched_forms; |
| 1258 } | 1258 } |
| 1259 | 1259 |
| 1260 bool PasswordStoreMac::FillAutofillableLogins( | 1260 bool PasswordStoreMac::FillAutofillableLogins( |
| 1261 ScopedVector<PasswordForm>* forms) { | 1261 ScopedVector<PasswordForm>* forms) { |
| 1262 DCHECK(GetBackgroundTaskRunner()->BelongsToCurrentThread()); | 1262 DCHECK(GetBackgroundTaskRunner()->BelongsToCurrentThread()); |
| 1263 forms->clear(); | 1263 forms->clear(); |
| 1264 | 1264 |
| 1265 ScopedVector<PasswordForm> database_forms; | 1265 ScopedVector<PasswordForm> database_forms; |
| 1266 if (!login_metadata_db_ || | 1266 if (!login_metadata_db_ || |
| 1267 !login_metadata_db_->GetAutofillableLogins(&database_forms)) | 1267 !login_metadata_db_->GetAutofillableLogins(&database_forms)) |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1332 return has_match; | 1332 return has_match; |
| 1333 } | 1333 } |
| 1334 | 1334 |
| 1335 void PasswordStoreMac::RemoveDatabaseForms( | 1335 void PasswordStoreMac::RemoveDatabaseForms( |
| 1336 ScopedVector<autofill::PasswordForm>* forms) { | 1336 ScopedVector<autofill::PasswordForm>* forms) { |
| 1337 DCHECK(login_metadata_db_); | 1337 DCHECK(login_metadata_db_); |
| 1338 ScopedVector<autofill::PasswordForm> removed_forms; | 1338 ScopedVector<autofill::PasswordForm> removed_forms; |
| 1339 MoveAllFormsOut(forms, [this, &removed_forms]( | 1339 MoveAllFormsOut(forms, [this, &removed_forms]( |
| 1340 scoped_ptr<autofill::PasswordForm> form) { | 1340 scoped_ptr<autofill::PasswordForm> form) { |
| 1341 if (login_metadata_db_->RemoveLogin(*form)) | 1341 if (login_metadata_db_->RemoveLogin(*form)) |
| 1342 removed_forms.push_back(form.Pass()); | 1342 removed_forms.push_back(std::move(form)); |
| 1343 }); | 1343 }); |
| 1344 removed_forms.swap(*forms); | 1344 removed_forms.swap(*forms); |
| 1345 } | 1345 } |
| 1346 | 1346 |
| 1347 void PasswordStoreMac::RemoveKeychainForms( | 1347 void PasswordStoreMac::RemoveKeychainForms( |
| 1348 const std::vector<PasswordForm*>& forms) { | 1348 const std::vector<PasswordForm*>& forms) { |
| 1349 MacKeychainPasswordFormAdapter owned_keychain_adapter(keychain_.get()); | 1349 MacKeychainPasswordFormAdapter owned_keychain_adapter(keychain_.get()); |
| 1350 owned_keychain_adapter.SetFindsOnlyOwnedItems(true); | 1350 owned_keychain_adapter.SetFindsOnlyOwnedItems(true); |
| 1351 for (std::vector<PasswordForm*>::const_iterator i = forms.begin(); | 1351 for (std::vector<PasswordForm*>::const_iterator i = forms.begin(); |
| 1352 i != forms.end(); ++i) { | 1352 i != forms.end(); ++i) { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1367 ScopedVector<PasswordForm> forms_with_keychain_entry; | 1367 ScopedVector<PasswordForm> forms_with_keychain_entry; |
| 1368 internal_keychain_helpers::GetPasswordsForForms(*keychain_, &database_forms, | 1368 internal_keychain_helpers::GetPasswordsForForms(*keychain_, &database_forms, |
| 1369 &forms_with_keychain_entry); | 1369 &forms_with_keychain_entry); |
| 1370 | 1370 |
| 1371 // Clean up any orphaned database entries. | 1371 // Clean up any orphaned database entries. |
| 1372 RemoveDatabaseForms(&database_forms); | 1372 RemoveDatabaseForms(&database_forms); |
| 1373 | 1373 |
| 1374 // Move the orphaned DB forms to the output parameter. | 1374 // Move the orphaned DB forms to the output parameter. |
| 1375 AppendSecondToFirst(orphaned_forms, &database_forms); | 1375 AppendSecondToFirst(orphaned_forms, &database_forms); |
| 1376 } | 1376 } |
| OLD | NEW |