Chromium Code Reviews| 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 <iterator> | |
| 10 #include <set> | 11 #include <set> |
| 11 #include <string> | 12 #include <string> |
| 12 #include <utility> | 13 #include <utility> |
| 13 #include <vector> | 14 #include <vector> |
| 14 | 15 |
| 15 #include "base/callback.h" | 16 #include "base/callback.h" |
| 16 #include "base/logging.h" | 17 #include "base/logging.h" |
| 17 #include "base/mac/foundation_util.h" | 18 #include "base/mac/foundation_util.h" |
| 18 #include "base/mac/mac_logging.h" | 19 #include "base/mac/mac_logging.h" |
| 19 #include "base/macros.h" | 20 #include "base/macros.h" |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 180 while (keychain_->SearchCopyNext(search_ref_, &keychain_item) == noErr) { | 181 while (keychain_->SearchCopyNext(search_ref_, &keychain_item) == noErr) { |
| 181 // Consumer is responsible for freeing the items. | 182 // Consumer is responsible for freeing the items. |
| 182 items->push_back(keychain_item); | 183 items->push_back(keychain_item); |
| 183 } | 184 } |
| 184 | 185 |
| 185 keychain_->Free(search_ref_); | 186 keychain_->Free(search_ref_); |
| 186 search_ref_ = NULL; | 187 search_ref_ = NULL; |
| 187 } | 188 } |
| 188 | 189 |
| 189 PasswordStoreChangeList FormsToRemoveChangeList( | 190 PasswordStoreChangeList FormsToRemoveChangeList( |
| 190 const std::vector<PasswordForm*>& forms) { | 191 const std::vector<std::unique_ptr<PasswordForm>>& forms) { |
| 191 PasswordStoreChangeList changes; | 192 PasswordStoreChangeList changes; |
| 192 for (std::vector<PasswordForm*>::const_iterator i = forms.begin(); | 193 for (const auto& form : forms) { |
| 193 i != forms.end(); ++i) { | 194 changes.push_back(PasswordStoreChange(PasswordStoreChange::REMOVE, *form)); |
| 194 changes.push_back(PasswordStoreChange(PasswordStoreChange::REMOVE, **i)); | |
| 195 } | 195 } |
| 196 return changes; | 196 return changes; |
| 197 } | 197 } |
| 198 | 198 |
| 199 // Moves the content of |second| to the end of |first|. | 199 // Moves the content of |second| to the end of |first|. |
| 200 void AppendSecondToFirst(ScopedVector<autofill::PasswordForm>* first, | 200 void AppendSecondToFirst(std::vector<std::unique_ptr<PasswordForm>>* first, |
| 201 ScopedVector<autofill::PasswordForm>* second) { | 201 std::vector<std::unique_ptr<PasswordForm>>* second) { |
| 202 first->insert(first->end(), second->begin(), second->end()); | 202 first->reserve(first->size() + second->size()); |
| 203 second->weak_clear(); | 203 std::move(second->begin(), second->end(), |
| 204 std::inserter(*first, first->end())); | |
|
vasilii
2016/12/12 10:09:21
std::back_inserter?
vabr (Chromium)
2016/12/12 11:18:17
Done.
| |
| 205 second->clear(); | |
| 204 } | 206 } |
| 205 | 207 |
| 206 // Returns the best match for |base_form| from |keychain_forms|, or nullptr if | 208 // Returns the best match for |base_form| from |keychain_forms|, or nullptr if |
| 207 // there is no suitable match. | 209 // there is no suitable match. |
| 208 const PasswordForm* BestKeychainFormForForm( | 210 const PasswordForm* BestKeychainFormForForm( |
| 209 const PasswordForm& base_form, | 211 const PasswordForm& base_form, |
| 210 const std::vector<PasswordForm*>& keychain_forms) { | 212 const std::vector<std::unique_ptr<PasswordForm>>& keychain_forms) { |
| 211 const PasswordForm* partial_match = nullptr; | 213 const PasswordForm* partial_match = nullptr; |
| 212 for (const auto* keychain_form : keychain_forms) { | 214 for (const auto& keychain_form : keychain_forms) { |
| 213 // TODO(stuartmorgan): We should really be scoring path matches and picking | 215 // TODO(stuartmorgan): We should really be scoring path matches and picking |
| 214 // the best, rather than just checking exact-or-not (although in practice | 216 // the best, rather than just checking exact-or-not (although in practice |
| 215 // keychain items with paths probably came from us). | 217 // keychain items with paths probably came from us). |
| 216 if (internal_keychain_helpers::FormsMatchForMerge( | 218 if (internal_keychain_helpers::FormsMatchForMerge( |
| 217 base_form, *keychain_form, | 219 base_form, *keychain_form, |
| 218 internal_keychain_helpers::FUZZY_FORM_MATCH)) { | 220 internal_keychain_helpers::FUZZY_FORM_MATCH)) { |
| 219 if (base_form.origin == keychain_form->origin) { | 221 if (base_form.origin == keychain_form->origin) { |
| 220 return keychain_form; | 222 return keychain_form.get(); |
| 221 } else if (!partial_match) { | 223 } else if (!partial_match) { |
| 222 partial_match = keychain_form; | 224 partial_match = keychain_form.get(); |
| 223 } | 225 } |
| 224 } | 226 } |
| 225 } | 227 } |
| 226 return partial_match; | 228 return partial_match; |
| 227 } | 229 } |
| 228 | 230 |
| 229 // Iterates over all elements in |forms|, passes the pointed to objects to | |
| 230 // |mover|, and clears |forms| efficiently. FormMover needs to be a callable | |
| 231 // entity, accepting std::unique_ptr<autofill::PasswordForm> as its sole | |
| 232 // argument. | |
| 233 template <typename FormMover> | |
| 234 inline void MoveAllFormsOut(ScopedVector<autofill::PasswordForm>* forms, | |
| 235 FormMover mover) { | |
| 236 for (autofill::PasswordForm* form_ptr : *forms) { | |
| 237 mover(std::unique_ptr<autofill::PasswordForm>(form_ptr)); | |
| 238 } | |
| 239 // We moved the ownership of every form out of |forms|. For performance | |
| 240 // reasons, we can just weak_clear it, instead of nullptr-ing the respective | |
| 241 // elements and letting the vector's destructor to go through the list once | |
| 242 // more. This was tested on a benchmark, and seemed to make a difference on | |
| 243 // Mac. | |
| 244 forms->weak_clear(); | |
| 245 } | |
| 246 | |
| 247 // True if the form has no password to be stored in Keychain. | 231 // True if the form has no password to be stored in Keychain. |
| 248 bool IsLoginDatabaseOnlyForm(const autofill::PasswordForm& form) { | 232 bool IsLoginDatabaseOnlyForm(const PasswordForm& form) { |
| 249 return form.blacklisted_by_user || !form.federation_origin.unique() || | 233 return form.blacklisted_by_user || !form.federation_origin.unique() || |
| 250 form.scheme == autofill::PasswordForm::SCHEME_USERNAME_ONLY; | 234 form.scheme == PasswordForm::SCHEME_USERNAME_ONLY; |
| 251 } | |
| 252 | |
| 253 // TODO(crbug.com/555132): Temporary utility to convert from std::vector to | |
| 254 // ScopedVector. | |
| 255 ScopedVector<PasswordForm> ConvertToScopedVector( | |
| 256 std::vector<std::unique_ptr<PasswordForm>> forms) { | |
| 257 ScopedVector<PasswordForm> result; | |
| 258 result.resize(forms.size()); | |
| 259 std::transform( | |
| 260 forms.begin(), forms.end(), result.begin(), | |
| 261 [](std::unique_ptr<PasswordForm>& form) { return form.release(); }); | |
| 262 return result; | |
| 263 } | 235 } |
| 264 | 236 |
| 265 } // namespace | 237 } // namespace |
| 266 | 238 |
| 267 #pragma mark - | 239 #pragma mark - |
| 268 | 240 |
| 269 // TODO(stuartmorgan): Convert most of this to private helpers in | 241 // TODO(stuartmorgan): Convert most of this to private helpers in |
| 270 // MacKeychainPasswordFormAdapter once it has sufficient higher-level public | 242 // MacKeychainPasswordFormAdapter once it has sufficient higher-level public |
| 271 // methods to provide test coverage. | 243 // methods to provide test coverage. |
| 272 namespace internal_keychain_helpers { | 244 namespace internal_keychain_helpers { |
| (...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 496 if (strictness == FUZZY_FORM_MATCH) { | 468 if (strictness == FUZZY_FORM_MATCH) { |
| 497 equal_realm |= form_a.is_public_suffix_match; | 469 equal_realm |= form_a.is_public_suffix_match; |
| 498 } | 470 } |
| 499 return form_a.scheme == form_b.scheme && equal_realm && | 471 return form_a.scheme == form_b.scheme && equal_realm && |
| 500 form_a.username_value == form_b.username_value; | 472 form_a.username_value == form_b.username_value; |
| 501 } | 473 } |
| 502 | 474 |
| 503 // Moves entries from |forms| that represent either blacklisted or federated | 475 // Moves entries from |forms| that represent either blacklisted or federated |
| 504 // logins into |extracted|. These two types are stored only in the LoginDatabase | 476 // logins into |extracted|. These two types are stored only in the LoginDatabase |
| 505 // and do not have corresponding Keychain entries. | 477 // and do not have corresponding Keychain entries. |
| 506 void ExtractNonKeychainForms(ScopedVector<autofill::PasswordForm>* forms, | 478 void ExtractNonKeychainForms( |
| 507 ScopedVector<autofill::PasswordForm>* extracted) { | 479 std::vector<std::unique_ptr<PasswordForm>>* forms, |
| 480 std::vector<std::unique_ptr<PasswordForm>>* extracted) { | |
| 508 extracted->reserve(extracted->size() + forms->size()); | 481 extracted->reserve(extracted->size() + forms->size()); |
| 509 ScopedVector<autofill::PasswordForm> remaining; | 482 |
| 510 MoveAllFormsOut(forms, [&remaining, extracted]( | 483 std::vector<std::unique_ptr<PasswordForm>> remaining; |
| 511 std::unique_ptr<autofill::PasswordForm> form) { | 484 remaining.reserve(forms->size()); |
| 485 | |
| 486 for (std::unique_ptr<PasswordForm>& form : *forms) { | |
| 512 if (IsLoginDatabaseOnlyForm(*form)) | 487 if (IsLoginDatabaseOnlyForm(*form)) |
| 513 extracted->push_back(std::move(form)); | 488 extracted->push_back(std::move(form)); |
| 514 else | 489 else |
| 515 remaining.push_back(std::move(form)); | 490 remaining.push_back(std::move(form)); |
| 516 }); | 491 } |
| 517 forms->swap(remaining); | 492 forms->swap(remaining); |
| 518 } | 493 } |
| 519 | 494 |
| 520 // Takes |keychain_forms| and |database_forms| and moves the following 2 types | 495 // Takes |keychain_forms| and |database_forms| and moves the following 2 types |
| 521 // of forms to |merged_forms|: | 496 // of forms to |merged_forms|: |
| 522 // (1) |database_forms| that by principle never have a corresponding Keychain | 497 // (1) |database_forms| that by principle never have a corresponding Keychain |
| 523 // entry (viz., blacklisted and federated logins), | 498 // entry (viz., blacklisted and federated logins), |
| 524 // (2) |database_forms| which should have and do have a corresponding entry in | 499 // (2) |database_forms| which should have and do have a corresponding entry in |
| 525 // |keychain_forms|. | 500 // |keychain_forms|. |
| 526 // The database forms of type (2) have their password value updated from the | 501 // The database forms of type (2) have their password value updated from the |
| 527 // corresponding keychain form, and all the keychain forms corresponding to some | 502 // corresponding keychain form, and all the keychain forms corresponding to some |
| 528 // database form are removed from |keychain_forms| and deleted. | 503 // database form are removed from |keychain_forms| and deleted. |
| 529 void MergePasswordForms(ScopedVector<autofill::PasswordForm>* keychain_forms, | 504 void MergePasswordForms( |
| 530 ScopedVector<autofill::PasswordForm>* database_forms, | 505 std::vector<std::unique_ptr<PasswordForm>>* keychain_forms, |
| 531 ScopedVector<autofill::PasswordForm>* merged_forms) { | 506 std::vector<std::unique_ptr<PasswordForm>>* database_forms, |
| 507 std::vector<std::unique_ptr<PasswordForm>>* merged_forms) { | |
| 532 // Pull out the database blacklist items and federated logins, since they are | 508 // Pull out the database blacklist items and federated logins, since they are |
| 533 // used as-is rather than being merged with keychain forms. | 509 // used as-is rather than being merged with keychain forms. |
| 534 ExtractNonKeychainForms(database_forms, merged_forms); | 510 ExtractNonKeychainForms(database_forms, merged_forms); |
| 535 | 511 |
| 536 // Merge the normal entries. | 512 // Merge the normal entries. |
| 537 ScopedVector<autofill::PasswordForm> unused_database_forms; | 513 std::vector<std::unique_ptr<PasswordForm>> unused_database_forms; |
| 538 unused_database_forms.reserve(database_forms->size()); | 514 unused_database_forms.reserve(database_forms->size()); |
| 539 std::set<const autofill::PasswordForm*> used_keychain_forms; | 515 std::set<const PasswordForm*> used_keychain_forms; |
| 540 // Move all database forms to either |merged_forms| or | 516 // Move all database forms to either |merged_forms| or |
| 541 // |unused_database_forms|, based on whether they have a match in the keychain | 517 // |unused_database_forms|, based on whether they have a match in the keychain |
| 542 // forms or not. If there is a match, add its password to the DB form and | 518 // forms or not. If there is a match, add its password to the DB form and |
| 543 // mark the keychain form as used. | 519 // mark the keychain form as used. |
| 544 MoveAllFormsOut( | 520 for (std::unique_ptr<PasswordForm>& db_form : *database_forms) { |
| 545 database_forms, | 521 const PasswordForm* best_match = |
| 546 [keychain_forms, &used_keychain_forms, merged_forms, | 522 BestKeychainFormForForm(*db_form, *keychain_forms); |
| 547 &unused_database_forms](std::unique_ptr<autofill::PasswordForm> form) { | 523 if (best_match) { |
| 548 const PasswordForm* best_match = | 524 used_keychain_forms.insert(best_match); |
| 549 BestKeychainFormForForm(*form, keychain_forms->get()); | 525 db_form->password_value = best_match->password_value; |
| 550 if (best_match) { | 526 merged_forms->push_back(std::move(db_form)); |
| 551 used_keychain_forms.insert(best_match); | 527 } else { |
| 552 form->password_value = best_match->password_value; | 528 unused_database_forms.push_back(std::move(db_form)); |
| 553 merged_forms->push_back(std::move(form)); | 529 } |
| 554 } else { | 530 } |
| 555 unused_database_forms.push_back(std::move(form)); | |
| 556 } | |
| 557 }); | |
| 558 database_forms->swap(unused_database_forms); | 531 database_forms->swap(unused_database_forms); |
| 559 | 532 |
| 560 // Clear out all the Keychain entries we used. | 533 // Clear out all the Keychain entries we used. |
| 561 ScopedVector<autofill::PasswordForm> unused_keychain_forms; | 534 std::vector<std::unique_ptr<PasswordForm>> unused_keychain_forms; |
| 562 unused_keychain_forms.reserve(keychain_forms->size()); | 535 unused_keychain_forms.reserve(keychain_forms->size()); |
| 563 for (auto*& keychain_form : *keychain_forms) { | 536 for (std::unique_ptr<PasswordForm>& keychain_form : *keychain_forms) { |
| 564 if (!base::ContainsKey(used_keychain_forms, keychain_form)) { | 537 if (!base::ContainsKey(used_keychain_forms, keychain_form.get())) { |
| 565 unused_keychain_forms.push_back(keychain_form); | 538 unused_keychain_forms.push_back(std::move(keychain_form)); |
| 566 keychain_form = nullptr; | |
| 567 } | 539 } |
| 568 } | 540 } |
| 569 keychain_forms->swap(unused_keychain_forms); | 541 keychain_forms->swap(unused_keychain_forms); |
| 570 } | 542 } |
| 571 | 543 |
| 572 std::vector<ItemFormPair> ExtractAllKeychainItemAttributesIntoPasswordForms( | 544 std::vector<ItemFormPair> ExtractAllKeychainItemAttributesIntoPasswordForms( |
| 573 std::vector<SecKeychainItemRef>* keychain_items, | 545 std::vector<SecKeychainItemRef>* keychain_items, |
| 574 const AppleKeychain& keychain) { | 546 const AppleKeychain& keychain) { |
| 575 DCHECK(keychain_items); | 547 DCHECK(keychain_items); |
| 576 MacKeychainPasswordFormAdapter keychain_adapter(&keychain); | 548 MacKeychainPasswordFormAdapter keychain_adapter(&keychain); |
| 577 *keychain_items = keychain_adapter.GetAllPasswordFormKeychainItems(); | 549 *keychain_items = keychain_adapter.GetAllPasswordFormKeychainItems(); |
| 578 std::vector<ItemFormPair> item_form_pairs; | 550 std::vector<ItemFormPair> item_form_pairs; |
| 579 for (const auto& keychain_item : *keychain_items) { | 551 for (const auto& keychain_item : *keychain_items) { |
| 580 std::unique_ptr<PasswordForm> form_without_password = | 552 std::unique_ptr<PasswordForm> form_without_password = |
| 581 base::MakeUnique<PasswordForm>(); | 553 base::MakeUnique<PasswordForm>(); |
| 582 internal_keychain_helpers::FillPasswordFormFromKeychainItem( | 554 internal_keychain_helpers::FillPasswordFormFromKeychainItem( |
| 583 keychain, keychain_item, form_without_password.get(), | 555 keychain, keychain_item, form_without_password.get(), |
| 584 false); // Load password attributes, but not password data. | 556 false); // Load password attributes, but not password data. |
| 585 item_form_pairs.push_back( | 557 item_form_pairs.push_back( |
| 586 std::make_pair(keychain_item, std::move(form_without_password))); | 558 std::make_pair(keychain_item, std::move(form_without_password))); |
| 587 } | 559 } |
| 588 return item_form_pairs; | 560 return item_form_pairs; |
| 589 } | 561 } |
| 590 | 562 |
| 591 void GetPasswordsForForms(const AppleKeychain& keychain, | 563 void GetPasswordsForForms( |
| 592 ScopedVector<autofill::PasswordForm>* database_forms, | 564 const AppleKeychain& keychain, |
| 593 ScopedVector<autofill::PasswordForm>* passwords) { | 565 std::vector<std::unique_ptr<PasswordForm>>* database_forms, |
| 566 std::vector<std::unique_ptr<PasswordForm>>* passwords) { | |
| 594 // First load the attributes of all items in the keychain without loading | 567 // First load the attributes of all items in the keychain without loading |
| 595 // their password data, and then match items in |database_forms| against them. | 568 // their password data, and then match items in |database_forms| against them. |
| 596 // This avoids individually searching through the keychain for passwords | 569 // This avoids individually searching through the keychain for passwords |
| 597 // matching each form in |database_forms|, and results in a significant | 570 // matching each form in |database_forms|, and results in a significant |
| 598 // performance gain, replacing O(N) keychain search operations with a single | 571 // performance gain, replacing O(N) keychain search operations with a single |
| 599 // operation that loads all keychain items, and then selective reads of only | 572 // operation that loads all keychain items, and then selective reads of only |
| 600 // the relevant passwords. See crbug.com/263685. | 573 // the relevant passwords. See crbug.com/263685. |
| 601 std::vector<SecKeychainItemRef> keychain_items; | 574 std::vector<SecKeychainItemRef> keychain_items; |
| 602 std::vector<ItemFormPair> item_form_pairs = | 575 std::vector<ItemFormPair> item_form_pairs = |
| 603 ExtractAllKeychainItemAttributesIntoPasswordForms(&keychain_items, | 576 ExtractAllKeychainItemAttributesIntoPasswordForms(&keychain_items, |
| 604 keychain); | 577 keychain); |
| 605 | 578 |
| 606 // Next, compare the attributes of the PasswordForms in |database_forms| | 579 // Next, compare the attributes of the PasswordForms in |database_forms| |
| 607 // against those in |item_form_pairs|, and extract password data for each | 580 // against those in |item_form_pairs|, and extract password data for each |
| 608 // matching PasswordForm using its corresponding SecKeychainItemRef. | 581 // matching PasswordForm using its corresponding SecKeychainItemRef. |
| 609 ScopedVector<autofill::PasswordForm> unused_db_forms; | 582 std::vector<std::unique_ptr<PasswordForm>> unused_db_forms; |
| 610 unused_db_forms.reserve(database_forms->size()); | 583 unused_db_forms.reserve(database_forms->size()); |
| 611 // Move database forms with a password stored in |keychain| to |passwords|, | 584 // Move database forms with a password stored in |keychain| to |passwords|, |
| 612 // including the password. The rest is moved to |unused_db_forms|. | 585 // including the password. The rest is moved to |unused_db_forms|. |
| 613 MoveAllFormsOut( | 586 for (std::unique_ptr<PasswordForm>& db_form : *database_forms) { |
| 614 database_forms, | 587 std::vector<std::unique_ptr<PasswordForm>> keychain_matches = |
| 615 [&keychain, &item_form_pairs, passwords, | 588 ExtractPasswordsMergeableWithForm(keychain, item_form_pairs, *db_form); |
| 616 &unused_db_forms](std::unique_ptr<autofill::PasswordForm> form) { | |
| 617 ScopedVector<autofill::PasswordForm> keychain_matches = | |
| 618 ExtractPasswordsMergeableWithForm(keychain, item_form_pairs, *form); | |
| 619 | 589 |
| 620 ScopedVector<autofill::PasswordForm> db_form_container; | 590 std::vector<std::unique_ptr<PasswordForm>> db_form_container; |
| 621 db_form_container.push_back(std::move(form)); | 591 db_form_container.push_back(std::move(db_form)); |
| 622 MergePasswordForms(&keychain_matches, &db_form_container, passwords); | 592 MergePasswordForms(&keychain_matches, &db_form_container, passwords); |
| 623 AppendSecondToFirst(&unused_db_forms, &db_form_container); | 593 AppendSecondToFirst(&unused_db_forms, &db_form_container); |
| 624 }); | 594 } |
| 625 database_forms->swap(unused_db_forms); | 595 database_forms->swap(unused_db_forms); |
| 626 | 596 |
| 627 for (SecKeychainItemRef item : keychain_items) { | 597 for (SecKeychainItemRef item : keychain_items) { |
| 628 keychain.Free(item); | 598 keychain.Free(item); |
| 629 } | 599 } |
| 630 } | 600 } |
| 631 | 601 |
| 632 // TODO(stuartmorgan): signon_realm for proxies is not yet supported. | 602 // TODO(stuartmorgan): signon_realm for proxies is not yet supported. |
| 633 bool ExtractSignonRealmComponents(const std::string& signon_realm, | 603 bool ExtractSignonRealmComponents(const std::string& signon_realm, |
| 634 std::string* server, | 604 std::string* server, |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 677 std::string security_domain; | 647 std::string security_domain; |
| 678 UInt32 port; | 648 UInt32 port; |
| 679 bool is_secure; | 649 bool is_secure; |
| 680 if (!ExtractSignonRealmComponents(query_form.signon_realm, &server, &port, | 650 if (!ExtractSignonRealmComponents(query_form.signon_realm, &server, &port, |
| 681 &is_secure, &security_domain)) { | 651 &is_secure, &security_domain)) { |
| 682 return false; | 652 return false; |
| 683 } | 653 } |
| 684 return FormsMatchForMerge(query_form, other_form, STRICT_FORM_MATCH); | 654 return FormsMatchForMerge(query_form, other_form, STRICT_FORM_MATCH); |
| 685 } | 655 } |
| 686 | 656 |
| 687 ScopedVector<autofill::PasswordForm> ExtractPasswordsMergeableWithForm( | 657 std::vector<std::unique_ptr<PasswordForm>> ExtractPasswordsMergeableWithForm( |
| 688 const AppleKeychain& keychain, | 658 const AppleKeychain& keychain, |
| 689 const std::vector<ItemFormPair>& item_form_pairs, | 659 const std::vector<ItemFormPair>& item_form_pairs, |
| 690 const PasswordForm& query_form) { | 660 const PasswordForm& query_form) { |
| 691 ScopedVector<autofill::PasswordForm> matches; | 661 std::vector<std::unique_ptr<PasswordForm>> matches; |
| 692 for (std::vector<ItemFormPair>::const_iterator i = item_form_pairs.begin(); | 662 for (std::vector<ItemFormPair>::const_iterator i = item_form_pairs.begin(); |
| 693 i != item_form_pairs.end(); ++i) { | 663 i != item_form_pairs.end(); ++i) { |
| 694 if (FormIsValidAndMatchesOtherForm(query_form, *(i->second))) { | 664 if (FormIsValidAndMatchesOtherForm(query_form, *(i->second))) { |
| 695 // Create a new object, since the caller is responsible for deleting the | 665 // Create a new object, since the caller is responsible for deleting the |
| 696 // returned forms. | 666 // returned forms. |
| 697 std::unique_ptr<PasswordForm> form_with_password(new PasswordForm()); | 667 auto form_with_password = base::MakeUnique<PasswordForm>(); |
| 698 FillPasswordFormFromKeychainItem( | 668 FillPasswordFormFromKeychainItem( |
| 699 keychain, i->first, form_with_password.get(), | 669 keychain, i->first, form_with_password.get(), |
| 700 true); // Load password attributes and data. | 670 true); // Load password attributes and data. |
| 701 // Do not include blacklisted items found in the keychain. | 671 // Do not include blacklisted items found in the keychain. |
| 702 if (!form_with_password->blacklisted_by_user) | 672 if (!form_with_password->blacklisted_by_user) |
| 703 matches.push_back(std::move(form_with_password)); | 673 matches.push_back(std::move(form_with_password)); |
| 704 } | 674 } |
| 705 } | 675 } |
| 706 return matches; | 676 return matches; |
| 707 } | 677 } |
| 708 | 678 |
| 709 } // namespace internal_keychain_helpers | 679 } // namespace internal_keychain_helpers |
| 710 | 680 |
| 711 #pragma mark - | 681 #pragma mark - |
| 712 | 682 |
| 713 MacKeychainPasswordFormAdapter::MacKeychainPasswordFormAdapter( | 683 MacKeychainPasswordFormAdapter::MacKeychainPasswordFormAdapter( |
| 714 const AppleKeychain* keychain) | 684 const AppleKeychain* keychain) |
| 715 : keychain_(keychain), finds_only_owned_(false) { | 685 : keychain_(keychain), finds_only_owned_(false) { |
| 716 } | 686 } |
| 717 | 687 |
| 718 ScopedVector<autofill::PasswordForm> | 688 std::vector<std::unique_ptr<PasswordForm>> |
| 719 MacKeychainPasswordFormAdapter::PasswordsFillingForm( | 689 MacKeychainPasswordFormAdapter::PasswordsFillingForm( |
| 720 const std::string& signon_realm, | 690 const std::string& signon_realm, |
| 721 PasswordForm::Scheme scheme) { | 691 PasswordForm::Scheme scheme) { |
| 722 std::vector<SecKeychainItemRef> keychain_items = | 692 std::vector<SecKeychainItemRef> keychain_items = |
| 723 MatchingKeychainItems(signon_realm, scheme, NULL, NULL); | 693 MatchingKeychainItems(signon_realm, scheme, NULL, NULL); |
| 724 return ConvertKeychainItemsToForms(&keychain_items); | 694 return ConvertKeychainItemsToForms(&keychain_items); |
| 725 } | 695 } |
| 726 | 696 |
| 727 bool MacKeychainPasswordFormAdapter::HasPasswordExactlyMatchingForm( | 697 bool MacKeychainPasswordFormAdapter::HasPasswordExactlyMatchingForm( |
| 728 const PasswordForm& query_form) { | 698 const PasswordForm& query_form) { |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 766 &supported_auth_types[i], | 736 &supported_auth_types[i], |
| 767 NULL, | 737 NULL, |
| 768 NULL, | 738 NULL, |
| 769 NULL, | 739 NULL, |
| 770 creator ? &creator : NULL); | 740 creator ? &creator : NULL); |
| 771 keychain_search.FindMatchingItems(&matches); | 741 keychain_search.FindMatchingItems(&matches); |
| 772 } | 742 } |
| 773 return matches; | 743 return matches; |
| 774 } | 744 } |
| 775 | 745 |
| 776 ScopedVector<autofill::PasswordForm> | 746 std::vector<std::unique_ptr<PasswordForm>> |
| 777 MacKeychainPasswordFormAdapter::GetAllPasswordFormPasswords() { | 747 MacKeychainPasswordFormAdapter::GetAllPasswordFormPasswords() { |
| 778 std::vector<SecKeychainItemRef> items = GetAllPasswordFormKeychainItems(); | 748 std::vector<SecKeychainItemRef> items = GetAllPasswordFormKeychainItems(); |
| 779 return ConvertKeychainItemsToForms(&items); | 749 return ConvertKeychainItemsToForms(&items); |
| 780 } | 750 } |
| 781 | 751 |
| 782 bool MacKeychainPasswordFormAdapter::AddPassword(const PasswordForm& form) { | 752 bool MacKeychainPasswordFormAdapter::AddPassword(const PasswordForm& form) { |
| 783 // We should never be trying to store a blacklist in the keychain. | 753 // We should never be trying to store a blacklist in the keychain. |
| 784 DCHECK(!IsLoginDatabaseOnlyForm(form)); | 754 DCHECK(!IsLoginDatabaseOnlyForm(form)); |
| 785 | 755 |
| 786 std::string server; | 756 std::string server; |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 833 OSStatus result = keychain_->ItemDelete(keychain_item); | 803 OSStatus result = keychain_->ItemDelete(keychain_item); |
| 834 keychain_->Free(keychain_item); | 804 keychain_->Free(keychain_item); |
| 835 return result == noErr; | 805 return result == noErr; |
| 836 } | 806 } |
| 837 | 807 |
| 838 void MacKeychainPasswordFormAdapter::SetFindsOnlyOwnedItems( | 808 void MacKeychainPasswordFormAdapter::SetFindsOnlyOwnedItems( |
| 839 bool finds_only_owned) { | 809 bool finds_only_owned) { |
| 840 finds_only_owned_ = finds_only_owned; | 810 finds_only_owned_ = finds_only_owned; |
| 841 } | 811 } |
| 842 | 812 |
| 843 ScopedVector<autofill::PasswordForm> | 813 std::vector<std::unique_ptr<PasswordForm>> |
| 844 MacKeychainPasswordFormAdapter::ConvertKeychainItemsToForms( | 814 MacKeychainPasswordFormAdapter::ConvertKeychainItemsToForms( |
| 845 std::vector<SecKeychainItemRef>* items) { | 815 std::vector<SecKeychainItemRef>* items) { |
| 846 ScopedVector<autofill::PasswordForm> forms; | 816 std::vector<std::unique_ptr<PasswordForm>> forms; |
| 847 for (SecKeychainItemRef item : *items) { | 817 for (SecKeychainItemRef item : *items) { |
| 848 std::unique_ptr<PasswordForm> form(new PasswordForm()); | 818 auto form = base::MakeUnique<PasswordForm>(); |
| 849 if (internal_keychain_helpers::FillPasswordFormFromKeychainItem( | 819 if (internal_keychain_helpers::FillPasswordFormFromKeychainItem( |
| 850 *keychain_, item, form.get(), true)) { | 820 *keychain_, item, form.get(), true)) { |
| 851 forms.push_back(std::move(form)); | 821 forms.push_back(std::move(form)); |
| 852 } | 822 } |
| 853 keychain_->Free(item); | 823 keychain_->Free(item); |
| 854 } | 824 } |
| 855 items->clear(); | 825 items->clear(); |
| 856 return forms; | 826 return forms; |
| 857 } | 827 } |
| 858 | 828 |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 877 } | 847 } |
| 878 | 848 |
| 879 // Free all items after the first, since we won't be returning them. | 849 // Free all items after the first, since we won't be returning them. |
| 880 for (auto i = matches.begin() + 1; i != matches.end(); ++i) | 850 for (auto i = matches.begin() + 1; i != matches.end(); ++i) |
| 881 keychain_->Free(*i); | 851 keychain_->Free(*i); |
| 882 | 852 |
| 883 return matches[0]; | 853 return matches[0]; |
| 884 } | 854 } |
| 885 | 855 |
| 886 std::vector<SecKeychainItemRef> | 856 std::vector<SecKeychainItemRef> |
| 887 MacKeychainPasswordFormAdapter::MatchingKeychainItems( | 857 MacKeychainPasswordFormAdapter::MatchingKeychainItems( |
| 888 const std::string& signon_realm, | 858 const std::string& signon_realm, |
| 889 autofill::PasswordForm::Scheme scheme, | 859 PasswordForm::Scheme scheme, |
| 890 const char* path, const char* username) { | 860 const char* path, |
| 861 const char* username) { | |
| 891 std::vector<SecKeychainItemRef> matches; | 862 std::vector<SecKeychainItemRef> matches; |
| 892 | 863 |
| 893 std::string server; | 864 std::string server; |
| 894 std::string security_domain; | 865 std::string security_domain; |
| 895 UInt32 port; | 866 UInt32 port; |
| 896 bool is_secure; | 867 bool is_secure; |
| 897 if (!internal_keychain_helpers::ExtractSignonRealmComponents( | 868 if (!internal_keychain_helpers::ExtractSignonRealmComponents( |
| 898 signon_realm, &server, &port, &is_secure, &security_domain)) { | 869 signon_realm, &server, &port, &is_secure, &security_domain)) { |
| 899 // TODO(stuartmorgan): Proxies will currently fail here, since their | 870 // TODO(stuartmorgan): Proxies will currently fail here, since their |
| 900 // signon_realm is not a URL. We need to detect the proxy case and handle | 871 // signon_realm is not a URL. We need to detect the proxy case and handle |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 977 void PasswordStoreMac::InitWithTaskRunner( | 948 void PasswordStoreMac::InitWithTaskRunner( |
| 978 scoped_refptr<base::SingleThreadTaskRunner> background_task_runner) { | 949 scoped_refptr<base::SingleThreadTaskRunner> background_task_runner) { |
| 979 db_thread_runner_ = background_task_runner; | 950 db_thread_runner_ = background_task_runner; |
| 980 DCHECK(GetBackgroundTaskRunner()->BelongsToCurrentThread()); | 951 DCHECK(GetBackgroundTaskRunner()->BelongsToCurrentThread()); |
| 981 } | 952 } |
| 982 | 953 |
| 983 // static | 954 // static |
| 984 PasswordStoreMac::MigrationResult PasswordStoreMac::ImportFromKeychain( | 955 PasswordStoreMac::MigrationResult PasswordStoreMac::ImportFromKeychain( |
| 985 password_manager::LoginDatabase* login_db, | 956 password_manager::LoginDatabase* login_db, |
| 986 crypto::AppleKeychain* keychain) { | 957 crypto::AppleKeychain* keychain) { |
| 987 std::vector<std::unique_ptr<PasswordForm>> database_forms_new_format; | 958 std::vector<std::unique_ptr<PasswordForm>> database_forms; |
| 988 if (!login_db->GetAutofillableLogins(&database_forms_new_format)) | 959 if (!login_db->GetAutofillableLogins(&database_forms)) |
| 989 return LOGIN_DB_FAILURE; | 960 return LOGIN_DB_FAILURE; |
| 990 ScopedVector<PasswordForm> database_forms = | |
| 991 ConvertToScopedVector(std::move(database_forms_new_format)); | |
| 992 | 961 |
| 993 ScopedVector<PasswordForm> uninteresting_forms; | 962 std::vector<std::unique_ptr<PasswordForm>> uninteresting_forms; |
| 994 internal_keychain_helpers::ExtractNonKeychainForms(&database_forms, | 963 internal_keychain_helpers::ExtractNonKeychainForms(&database_forms, |
| 995 &uninteresting_forms); | 964 &uninteresting_forms); |
| 996 // If there are no passwords to lookup in the Keychain then we're done. | 965 // If there are no passwords to lookup in the Keychain then we're done. |
| 997 if (database_forms.empty()) | 966 if (database_forms.empty()) |
| 998 return MIGRATION_OK; | 967 return MIGRATION_OK; |
| 999 | 968 |
| 1000 // Make sure that the encryption key is retrieved from the Keychain so the | 969 // Make sure that the encryption key is retrieved from the Keychain so the |
| 1001 // encryption can be done. | 970 // encryption can be done. |
| 1002 std::string ciphertext; | 971 std::string ciphertext; |
| 1003 if (!OSCrypt::EncryptString("test", &ciphertext)) | 972 if (!OSCrypt::EncryptString("test", &ciphertext)) |
| 1004 return ENCRYPTOR_FAILURE; | 973 return ENCRYPTOR_FAILURE; |
| 1005 | 974 |
| 1006 // Mute the Keychain. | 975 // Mute the Keychain. |
| 1007 chrome::ScopedSecKeychainSetUserInteractionAllowed user_interaction_allowed( | 976 chrome::ScopedSecKeychainSetUserInteractionAllowed user_interaction_allowed( |
| 1008 false); | 977 false); |
| 1009 | 978 |
| 1010 // Retrieve the passwords. | 979 // Retrieve the passwords. |
| 1011 // Get all the password attributes first. | 980 // Get all the password attributes first. |
| 1012 std::vector<SecKeychainItemRef> keychain_items; | 981 std::vector<SecKeychainItemRef> keychain_items; |
| 1013 std::vector<internal_keychain_helpers::ItemFormPair> item_form_pairs = | 982 std::vector<internal_keychain_helpers::ItemFormPair> item_form_pairs = |
| 1014 internal_keychain_helpers:: | 983 internal_keychain_helpers:: |
| 1015 ExtractAllKeychainItemAttributesIntoPasswordForms(&keychain_items, | 984 ExtractAllKeychainItemAttributesIntoPasswordForms(&keychain_items, |
| 1016 *keychain); | 985 *keychain); |
| 1017 | 986 |
| 1018 // Next, compare the attributes of the PasswordForms in |database_forms| | 987 // Next, compare the attributes of the PasswordForms in |database_forms| |
| 1019 // against those in |item_form_pairs|, and extract password data for each | 988 // against those in |item_form_pairs|, and extract password data for each |
| 1020 // matching PasswordForm using its corresponding SecKeychainItemRef. | 989 // matching PasswordForm using its corresponding SecKeychainItemRef. |
| 1021 size_t unmerged_forms_count = 0; | 990 size_t unmerged_forms_count = 0; |
| 1022 login_db->set_clear_password_values(false); | 991 login_db->set_clear_password_values(false); |
| 1023 for (PasswordForm* form : database_forms) { | 992 for (const auto& form : database_forms) { |
| 1024 ScopedVector<autofill::PasswordForm> keychain_matches = | 993 std::vector<std::unique_ptr<PasswordForm>> keychain_matches = |
| 1025 internal_keychain_helpers::ExtractPasswordsMergeableWithForm( | 994 internal_keychain_helpers::ExtractPasswordsMergeableWithForm( |
| 1026 *keychain, item_form_pairs, *form); | 995 *keychain, item_form_pairs, *form); |
| 1027 | 996 |
| 1028 const PasswordForm* best_match = | 997 const PasswordForm* best_match = |
| 1029 BestKeychainFormForForm(*form, keychain_matches.get()); | 998 BestKeychainFormForForm(*form, keychain_matches); |
| 1030 if (best_match) { | 999 if (best_match) { |
| 1031 form->password_value = best_match->password_value; | 1000 form->password_value = best_match->password_value; |
| 1032 PasswordStoreChangeList change = login_db->UpdateLogin(*form); | 1001 PasswordStoreChangeList change = login_db->UpdateLogin(*form); |
| 1033 DCHECK_EQ(1u, change.size()); | 1002 DCHECK_EQ(1u, change.size()); |
| 1034 } else { | 1003 } else { |
| 1035 unmerged_forms_count++; | 1004 unmerged_forms_count++; |
| 1036 bool removed = login_db->RemoveLogin(*form); | 1005 bool removed = login_db->RemoveLogin(*form); |
| 1037 DCHECK(removed); | 1006 DCHECK(removed); |
| 1038 } | 1007 } |
| 1039 } | 1008 } |
| 1040 for (SecKeychainItemRef item : keychain_items) | 1009 for (SecKeychainItemRef item : keychain_items) |
| 1041 keychain->Free(item); | 1010 keychain->Free(item); |
| 1042 | 1011 |
| 1043 if (unmerged_forms_count) { | 1012 if (unmerged_forms_count) { |
| 1044 UMA_HISTOGRAM_COUNTS( | 1013 UMA_HISTOGRAM_COUNTS( |
| 1045 "PasswordManager.KeychainMigration.NumPasswordsOnFailure", | 1014 "PasswordManager.KeychainMigration.NumPasswordsOnFailure", |
| 1046 database_forms.size()); | 1015 database_forms.size()); |
| 1047 UMA_HISTOGRAM_COUNTS("PasswordManager.KeychainMigration.NumFailedPasswords", | 1016 UMA_HISTOGRAM_COUNTS("PasswordManager.KeychainMigration.NumFailedPasswords", |
| 1048 unmerged_forms_count); | 1017 unmerged_forms_count); |
| 1049 return MIGRATION_PARTIAL; | 1018 return MIGRATION_PARTIAL; |
| 1050 } | 1019 } |
| 1051 return MIGRATION_OK; | 1020 return MIGRATION_OK; |
| 1052 } | 1021 } |
| 1053 | 1022 |
| 1054 // static | 1023 // static |
| 1055 void PasswordStoreMac::CleanUpKeychain( | 1024 void PasswordStoreMac::CleanUpKeychain( |
| 1056 crypto::AppleKeychain* keychain, | 1025 crypto::AppleKeychain* keychain, |
| 1057 const std::vector<std::unique_ptr<autofill::PasswordForm>>& forms) { | 1026 const std::vector<std::unique_ptr<PasswordForm>>& forms) { |
| 1058 MacKeychainPasswordFormAdapter keychain_adapter(keychain); | 1027 MacKeychainPasswordFormAdapter keychain_adapter(keychain); |
| 1059 keychain_adapter.SetFindsOnlyOwnedItems(true); | 1028 keychain_adapter.SetFindsOnlyOwnedItems(true); |
| 1060 for (const auto& form : forms) | 1029 for (const auto& form : forms) |
| 1061 keychain_adapter.RemovePassword(*form); | 1030 keychain_adapter.RemovePassword(*form); |
| 1062 } | 1031 } |
| 1063 | 1032 |
| 1064 void PasswordStoreMac::set_login_metadata_db( | 1033 void PasswordStoreMac::set_login_metadata_db( |
| 1065 password_manager::LoginDatabase* login_db) { | 1034 password_manager::LoginDatabase* login_db) { |
| 1066 login_metadata_db_ = login_db; | 1035 login_metadata_db_ = login_db; |
| 1067 if (login_metadata_db_) | 1036 if (login_metadata_db_) |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1140 changes.push_back(PasswordStoreChange(PasswordStoreChange::REMOVE, form)); | 1109 changes.push_back(PasswordStoreChange(PasswordStoreChange::REMOVE, form)); |
| 1141 } | 1110 } |
| 1142 return changes; | 1111 return changes; |
| 1143 } | 1112 } |
| 1144 | 1113 |
| 1145 PasswordStoreChangeList PasswordStoreMac::RemoveLoginsByURLAndTimeImpl( | 1114 PasswordStoreChangeList PasswordStoreMac::RemoveLoginsByURLAndTimeImpl( |
| 1146 const base::Callback<bool(const GURL&)>& url_filter, | 1115 const base::Callback<bool(const GURL&)>& url_filter, |
| 1147 base::Time delete_begin, | 1116 base::Time delete_begin, |
| 1148 base::Time delete_end) { | 1117 base::Time delete_end) { |
| 1149 PasswordStoreChangeList changes; | 1118 PasswordStoreChangeList changes; |
| 1150 ScopedVector<PasswordForm> forms_to_consider; | 1119 std::vector<std::unique_ptr<PasswordForm>> forms_to_consider; |
| 1151 ScopedVector<PasswordForm> forms_to_remove; | 1120 std::vector<std::unique_ptr<PasswordForm>> forms_to_remove; |
| 1152 if (login_metadata_db_ && | 1121 if (login_metadata_db_ && |
| 1153 login_metadata_db_->GetLoginsCreatedBetween(delete_begin, delete_end, | 1122 login_metadata_db_->GetLoginsCreatedBetween(delete_begin, delete_end, |
| 1154 &forms_to_consider)) { | 1123 &forms_to_consider)) { |
| 1155 MoveAllFormsOut( | 1124 for (std::unique_ptr<PasswordForm>& form_to_consider : forms_to_consider) { |
| 1156 &forms_to_consider, | 1125 if (url_filter.Run(form_to_consider->origin) && |
| 1157 [this, &url_filter, &forms_to_remove]( | 1126 login_metadata_db_->RemoveLogin(*form_to_consider)) |
| 1158 std::unique_ptr<autofill::PasswordForm> form_to_consider) { | 1127 forms_to_remove.push_back(std::move(form_to_consider)); |
| 1159 if (url_filter.Run(form_to_consider->origin) && | 1128 } |
| 1160 login_metadata_db_->RemoveLogin(*form_to_consider)) | |
| 1161 forms_to_remove.push_back(std::move(form_to_consider)); | |
| 1162 }); | |
| 1163 if (!forms_to_remove.empty()) { | 1129 if (!forms_to_remove.empty()) { |
| 1164 RemoveKeychainForms(forms_to_remove.get()); | 1130 RemoveKeychainForms(forms_to_remove); |
| 1165 CleanOrphanedForms(&forms_to_remove); // Add the orphaned forms. | 1131 CleanOrphanedForms(&forms_to_remove); // Add the orphaned forms. |
| 1166 changes = FormsToRemoveChangeList(forms_to_remove.get()); | 1132 changes = FormsToRemoveChangeList(forms_to_remove); |
| 1167 LogStatsForBulkDeletion(changes.size()); | 1133 LogStatsForBulkDeletion(changes.size()); |
| 1168 } | 1134 } |
| 1169 } | 1135 } |
| 1170 return changes; | 1136 return changes; |
| 1171 } | 1137 } |
| 1172 | 1138 |
| 1173 PasswordStoreChangeList PasswordStoreMac::RemoveLoginsCreatedBetweenImpl( | 1139 PasswordStoreChangeList PasswordStoreMac::RemoveLoginsCreatedBetweenImpl( |
| 1174 base::Time delete_begin, | 1140 base::Time delete_begin, |
| 1175 base::Time delete_end) { | 1141 base::Time delete_end) { |
| 1176 PasswordStoreChangeList changes; | 1142 PasswordStoreChangeList changes; |
| 1177 ScopedVector<PasswordForm> forms_to_remove; | 1143 std::vector<std::unique_ptr<PasswordForm>> forms_to_remove; |
| 1178 if (login_metadata_db_ && | 1144 if (login_metadata_db_ && |
| 1179 login_metadata_db_->GetLoginsCreatedBetween(delete_begin, delete_end, | 1145 login_metadata_db_->GetLoginsCreatedBetween(delete_begin, delete_end, |
| 1180 &forms_to_remove) && | 1146 &forms_to_remove) && |
| 1181 login_metadata_db_->RemoveLoginsCreatedBetween(delete_begin, | 1147 login_metadata_db_->RemoveLoginsCreatedBetween(delete_begin, |
| 1182 delete_end)) { | 1148 delete_end)) { |
| 1183 RemoveKeychainForms(forms_to_remove.get()); | 1149 RemoveKeychainForms(forms_to_remove); |
| 1184 CleanOrphanedForms(&forms_to_remove); // Add the orphaned forms. | 1150 CleanOrphanedForms(&forms_to_remove); // Add the orphaned forms. |
| 1185 changes = FormsToRemoveChangeList(forms_to_remove.get()); | 1151 changes = FormsToRemoveChangeList(forms_to_remove); |
| 1186 LogStatsForBulkDeletion(changes.size()); | 1152 LogStatsForBulkDeletion(changes.size()); |
| 1187 } | 1153 } |
| 1188 return changes; | 1154 return changes; |
| 1189 } | 1155 } |
| 1190 | 1156 |
| 1191 PasswordStoreChangeList PasswordStoreMac::RemoveLoginsSyncedBetweenImpl( | 1157 PasswordStoreChangeList PasswordStoreMac::RemoveLoginsSyncedBetweenImpl( |
| 1192 base::Time delete_begin, | 1158 base::Time delete_begin, |
| 1193 base::Time delete_end) { | 1159 base::Time delete_end) { |
| 1194 PasswordStoreChangeList changes; | 1160 PasswordStoreChangeList changes; |
| 1195 ScopedVector<PasswordForm> forms_to_remove; | 1161 std::vector<std::unique_ptr<PasswordForm>> forms_to_remove; |
| 1196 if (login_metadata_db_ && | 1162 if (login_metadata_db_ && |
| 1197 login_metadata_db_->GetLoginsSyncedBetween(delete_begin, delete_end, | 1163 login_metadata_db_->GetLoginsSyncedBetween(delete_begin, delete_end, |
| 1198 &forms_to_remove) && | 1164 &forms_to_remove) && |
| 1199 login_metadata_db_->RemoveLoginsSyncedBetween(delete_begin, delete_end)) { | 1165 login_metadata_db_->RemoveLoginsSyncedBetween(delete_begin, delete_end)) { |
| 1200 RemoveKeychainForms(forms_to_remove.get()); | 1166 RemoveKeychainForms(forms_to_remove); |
| 1201 CleanOrphanedForms(&forms_to_remove); // Add the orphaned forms_to_remove. | 1167 CleanOrphanedForms(&forms_to_remove); // Add the orphaned forms_to_remove. |
| 1202 changes = FormsToRemoveChangeList(forms_to_remove.get()); | 1168 changes = FormsToRemoveChangeList(forms_to_remove); |
| 1203 LogStatsForBulkDeletionDuringRollback(changes.size()); | 1169 LogStatsForBulkDeletionDuringRollback(changes.size()); |
| 1204 } | 1170 } |
| 1205 return changes; | 1171 return changes; |
| 1206 } | 1172 } |
| 1207 | 1173 |
| 1208 PasswordStoreChangeList PasswordStoreMac::DisableAutoSignInForOriginsImpl( | 1174 PasswordStoreChangeList PasswordStoreMac::DisableAutoSignInForOriginsImpl( |
| 1209 const base::Callback<bool(const GURL&)>& origin_filter) { | 1175 const base::Callback<bool(const GURL&)>& origin_filter) { |
| 1210 ScopedVector<autofill::PasswordForm> forms; | 1176 std::vector<std::unique_ptr<PasswordForm>> forms; |
| 1211 PasswordStoreChangeList changes; | 1177 PasswordStoreChangeList changes; |
| 1212 if (!login_metadata_db_ || | 1178 if (!login_metadata_db_ || |
| 1213 !login_metadata_db_->GetAutoSignInLogins(&forms)) { | 1179 !login_metadata_db_->GetAutoSignInLogins(&forms)) { |
| 1214 return changes; | 1180 return changes; |
| 1215 } | 1181 } |
| 1216 | 1182 |
| 1217 std::set<GURL> origins_to_update; | 1183 std::set<GURL> origins_to_update; |
| 1218 for (const auto* form : forms) { | 1184 for (const auto& form : forms) { |
| 1219 if (origin_filter.Run(form->origin)) | 1185 if (origin_filter.Run(form->origin)) |
| 1220 origins_to_update.insert(form->origin); | 1186 origins_to_update.insert(form->origin); |
| 1221 } | 1187 } |
| 1222 | 1188 |
| 1223 std::set<GURL> origins_updated; | 1189 std::set<GURL> origins_updated; |
| 1224 for (const GURL& origin : origins_to_update) { | 1190 for (const GURL& origin : origins_to_update) { |
| 1225 if (login_metadata_db_->DisableAutoSignInForOrigin(origin)) | 1191 if (login_metadata_db_->DisableAutoSignInForOrigin(origin)) |
| 1226 origins_updated.insert(origin); | 1192 origins_updated.insert(origin); |
| 1227 } | 1193 } |
| 1228 | 1194 |
| 1229 for (const auto* form : forms) { | 1195 for (const auto& form : forms) { |
| 1230 if (origins_updated.count(form->origin)) { | 1196 if (origins_updated.count(form->origin)) { |
| 1231 changes.push_back( | 1197 changes.push_back( |
| 1232 PasswordStoreChange(PasswordStoreChange::UPDATE, *form)); | 1198 PasswordStoreChange(PasswordStoreChange::UPDATE, *form)); |
| 1233 } | 1199 } |
| 1234 } | 1200 } |
| 1235 | 1201 |
| 1236 return changes; | 1202 return changes; |
| 1237 } | 1203 } |
| 1238 | 1204 |
| 1239 bool PasswordStoreMac::RemoveStatisticsByOriginAndTimeImpl( | 1205 bool PasswordStoreMac::RemoveStatisticsByOriginAndTimeImpl( |
| 1240 const base::Callback<bool(const GURL&)>& origin_filter, | 1206 const base::Callback<bool(const GURL&)>& origin_filter, |
| 1241 base::Time delete_begin, | 1207 base::Time delete_begin, |
| 1242 base::Time delete_end) { | 1208 base::Time delete_end) { |
| 1243 return login_metadata_db_ && | 1209 return login_metadata_db_ && |
| 1244 login_metadata_db_->stats_table().RemoveStatsByOriginAndTime( | 1210 login_metadata_db_->stats_table().RemoveStatsByOriginAndTime( |
| 1245 origin_filter, delete_begin, delete_end); | 1211 origin_filter, delete_begin, delete_end); |
| 1246 } | 1212 } |
| 1247 | 1213 |
| 1248 std::vector<std::unique_ptr<PasswordForm>> PasswordStoreMac::FillMatchingLogins( | 1214 std::vector<std::unique_ptr<PasswordForm>> PasswordStoreMac::FillMatchingLogins( |
| 1249 const FormDigest& form) { | 1215 const FormDigest& form) { |
| 1250 chrome::ScopedSecKeychainSetUserInteractionAllowed user_interaction_allowed( | 1216 chrome::ScopedSecKeychainSetUserInteractionAllowed user_interaction_allowed( |
| 1251 false); | 1217 false); |
| 1252 | 1218 |
| 1253 // TODO(crbug.com/555132): "new_format" means std::vector instead of | 1219 std::vector<std::unique_ptr<PasswordForm>> database_forms; |
| 1254 // ScopedVector. Remove |database_forms_new_format| in favour of | |
| 1255 // |database_forms| as soon as the latter is migrated to std::vector. | |
| 1256 std::vector<std::unique_ptr<PasswordForm>> database_forms_new_format; | |
| 1257 if (!login_metadata_db_ || | 1220 if (!login_metadata_db_ || |
| 1258 !login_metadata_db_->GetLogins(form, &database_forms_new_format)) { | 1221 !login_metadata_db_->GetLogins(form, &database_forms)) { |
| 1259 return std::vector<std::unique_ptr<PasswordForm>>(); | 1222 return std::vector<std::unique_ptr<PasswordForm>>(); |
| 1260 } | 1223 } |
| 1261 ScopedVector<PasswordForm> database_forms = | |
| 1262 ConvertToScopedVector(std::move(database_forms_new_format)); | |
| 1263 | 1224 |
| 1264 // Let's gather all signon realms we want to match with keychain entries. | 1225 // Let's gather all signon realms we want to match with keychain entries. |
| 1265 std::set<std::string> realm_set; | 1226 std::set<std::string> realm_set; |
| 1266 realm_set.insert(form.signon_realm); | 1227 realm_set.insert(form.signon_realm); |
| 1267 for (const autofill::PasswordForm* db_form : database_forms) { | 1228 for (const std::unique_ptr<PasswordForm>& db_form : database_forms) { |
| 1268 // TODO(vabr): We should not be getting different schemes here. | 1229 // TODO(vabr): We should not be getting different schemes here. |
| 1269 // http://crbug.com/340112 | 1230 // http://crbug.com/340112 |
| 1270 if (form.scheme != db_form->scheme) | 1231 if (form.scheme != db_form->scheme) |
| 1271 continue; // Forms with different schemes never match. | 1232 continue; // Forms with different schemes never match. |
| 1272 if (db_form->is_public_suffix_match || db_form->is_affiliation_based_match) | 1233 if (db_form->is_public_suffix_match || db_form->is_affiliation_based_match) |
| 1273 realm_set.insert(db_form->signon_realm); | 1234 realm_set.insert(db_form->signon_realm); |
| 1274 } | 1235 } |
| 1275 ScopedVector<autofill::PasswordForm> keychain_forms; | 1236 std::vector<std::unique_ptr<PasswordForm>> keychain_forms; |
| 1276 for (std::set<std::string>::const_iterator realm = realm_set.begin(); | 1237 for (std::set<std::string>::const_iterator realm = realm_set.begin(); |
| 1277 realm != realm_set.end(); ++realm) { | 1238 realm != realm_set.end(); ++realm) { |
| 1278 MacKeychainPasswordFormAdapter keychain_adapter(keychain_.get()); | 1239 MacKeychainPasswordFormAdapter keychain_adapter(keychain_.get()); |
| 1279 ScopedVector<autofill::PasswordForm> temp_keychain_forms = | 1240 std::vector<std::unique_ptr<PasswordForm>> temp_keychain_forms = |
| 1280 keychain_adapter.PasswordsFillingForm(*realm, form.scheme); | 1241 keychain_adapter.PasswordsFillingForm(*realm, form.scheme); |
| 1281 AppendSecondToFirst(&keychain_forms, &temp_keychain_forms); | 1242 AppendSecondToFirst(&keychain_forms, &temp_keychain_forms); |
| 1282 } | 1243 } |
| 1283 | 1244 |
| 1284 ScopedVector<autofill::PasswordForm> matched_forms; | 1245 std::vector<std::unique_ptr<PasswordForm>> matched_forms; |
| 1285 internal_keychain_helpers::MergePasswordForms( | 1246 internal_keychain_helpers::MergePasswordForms( |
| 1286 &keychain_forms, &database_forms, &matched_forms); | 1247 &keychain_forms, &database_forms, &matched_forms); |
| 1287 | 1248 |
| 1288 // Strip any blacklist entries out of the unused Keychain array, then take | 1249 // Strip any blacklist entries out of the unused Keychain array, then take |
| 1289 // all the entries that are left (which we can use as imported passwords). | 1250 // all the entries that are left (which we can use as imported passwords). |
| 1290 ScopedVector<PasswordForm> keychain_blacklist_forms; | 1251 std::vector<std::unique_ptr<PasswordForm>> keychain_blacklist_forms; |
| 1291 internal_keychain_helpers::ExtractNonKeychainForms(&keychain_forms, | 1252 internal_keychain_helpers::ExtractNonKeychainForms(&keychain_forms, |
| 1292 &keychain_blacklist_forms); | 1253 &keychain_blacklist_forms); |
| 1293 AppendSecondToFirst(&matched_forms, &keychain_forms); | 1254 AppendSecondToFirst(&matched_forms, &keychain_forms); |
| 1294 | 1255 |
| 1295 if (!database_forms.empty()) { | 1256 if (!database_forms.empty()) { |
| 1296 RemoveDatabaseForms(&database_forms); | 1257 RemoveDatabaseForms(&database_forms); |
| 1297 NotifyLoginsChanged(FormsToRemoveChangeList(database_forms.get())); | 1258 NotifyLoginsChanged(FormsToRemoveChangeList(database_forms)); |
| 1298 } | 1259 } |
| 1299 | 1260 |
| 1300 return password_manager_util::ConvertScopedVector(std::move(matched_forms)); | 1261 return matched_forms; |
| 1301 } | 1262 } |
| 1302 | 1263 |
| 1303 bool PasswordStoreMac::FillAutofillableLogins( | 1264 bool PasswordStoreMac::FillAutofillableLogins( |
| 1304 std::vector<std::unique_ptr<PasswordForm>>* forms) { | 1265 std::vector<std::unique_ptr<PasswordForm>>* forms) { |
| 1305 DCHECK(GetBackgroundTaskRunner()->BelongsToCurrentThread()); | 1266 DCHECK(GetBackgroundTaskRunner()->BelongsToCurrentThread()); |
| 1306 forms->clear(); | 1267 forms->clear(); |
| 1307 | 1268 |
| 1308 std::vector<std::unique_ptr<PasswordForm>> database_forms_new_format; | 1269 std::vector<std::unique_ptr<PasswordForm>> database_forms; |
| 1309 if (!login_metadata_db_ || | 1270 if (!login_metadata_db_ || |
| 1310 !login_metadata_db_->GetAutofillableLogins(&database_forms_new_format)) | 1271 !login_metadata_db_->GetAutofillableLogins(&database_forms)) |
| 1311 return false; | 1272 return false; |
| 1312 ScopedVector<PasswordForm> database_forms = | |
| 1313 ConvertToScopedVector(std::move(database_forms_new_format)); | |
| 1314 | 1273 |
| 1315 ScopedVector<PasswordForm> forms_scopedvector; | |
| 1316 internal_keychain_helpers::GetPasswordsForForms(*keychain_, &database_forms, | 1274 internal_keychain_helpers::GetPasswordsForForms(*keychain_, &database_forms, |
| 1317 &forms_scopedvector); | 1275 forms); |
| 1318 *forms = | |
| 1319 password_manager_util::ConvertScopedVector(std::move(forms_scopedvector)); | |
| 1320 | 1276 |
| 1321 if (!database_forms.empty()) { | 1277 if (!database_forms.empty()) { |
| 1322 RemoveDatabaseForms(&database_forms); | 1278 RemoveDatabaseForms(&database_forms); |
| 1323 NotifyLoginsChanged(FormsToRemoveChangeList(database_forms.get())); | 1279 NotifyLoginsChanged(FormsToRemoveChangeList(database_forms)); |
| 1324 } | 1280 } |
| 1325 | 1281 |
| 1326 return true; | 1282 return true; |
| 1327 } | 1283 } |
| 1328 | 1284 |
| 1329 bool PasswordStoreMac::FillBlacklistLogins( | 1285 bool PasswordStoreMac::FillBlacklistLogins( |
| 1330 std::vector<std::unique_ptr<PasswordForm>>* forms) { | 1286 std::vector<std::unique_ptr<PasswordForm>>* forms) { |
| 1331 DCHECK(GetBackgroundTaskRunner()->BelongsToCurrentThread()); | 1287 DCHECK(GetBackgroundTaskRunner()->BelongsToCurrentThread()); |
| 1332 return login_metadata_db_ && login_metadata_db_->GetBlacklistLogins(forms); | 1288 return login_metadata_db_ && login_metadata_db_->GetBlacklistLogins(forms); |
| 1333 } | 1289 } |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 1354 } | 1310 } |
| 1355 | 1311 |
| 1356 bool PasswordStoreMac::AddToKeychainIfNecessary(const PasswordForm& form) { | 1312 bool PasswordStoreMac::AddToKeychainIfNecessary(const PasswordForm& form) { |
| 1357 if (IsLoginDatabaseOnlyForm(form)) | 1313 if (IsLoginDatabaseOnlyForm(form)) |
| 1358 return true; | 1314 return true; |
| 1359 MacKeychainPasswordFormAdapter keychainAdapter(keychain_.get()); | 1315 MacKeychainPasswordFormAdapter keychainAdapter(keychain_.get()); |
| 1360 return keychainAdapter.AddPassword(form); | 1316 return keychainAdapter.AddPassword(form); |
| 1361 } | 1317 } |
| 1362 | 1318 |
| 1363 bool PasswordStoreMac::DatabaseHasFormMatchingKeychainForm( | 1319 bool PasswordStoreMac::DatabaseHasFormMatchingKeychainForm( |
| 1364 const autofill::PasswordForm& form) { | 1320 const PasswordForm& form) { |
| 1365 DCHECK(login_metadata_db_); | 1321 DCHECK(login_metadata_db_); |
| 1366 bool has_match = false; | 1322 bool has_match = false; |
| 1367 std::vector<std::unique_ptr<PasswordForm>> database_forms; | 1323 std::vector<std::unique_ptr<PasswordForm>> database_forms; |
| 1368 if (!login_metadata_db_->GetLogins( | 1324 if (!login_metadata_db_->GetLogins( |
| 1369 password_manager::PasswordStore::FormDigest(form), &database_forms)) | 1325 password_manager::PasswordStore::FormDigest(form), &database_forms)) |
| 1370 return false; | 1326 return false; |
| 1371 for (const auto& db_form : database_forms) { | 1327 for (const auto& db_form : database_forms) { |
| 1372 // Below we filter out fuzzy matched forms because we are only interested | 1328 // Below we filter out fuzzy matched forms because we are only interested |
| 1373 // in exact ones. | 1329 // in exact ones. |
| 1374 if (!db_form->is_public_suffix_match && | 1330 if (!db_form->is_public_suffix_match && |
| 1375 internal_keychain_helpers::FormsMatchForMerge( | 1331 internal_keychain_helpers::FormsMatchForMerge( |
| 1376 form, *db_form, internal_keychain_helpers::STRICT_FORM_MATCH) && | 1332 form, *db_form, internal_keychain_helpers::STRICT_FORM_MATCH) && |
| 1377 db_form->origin == form.origin) { | 1333 db_form->origin == form.origin) { |
| 1378 has_match = true; | 1334 has_match = true; |
| 1379 break; | 1335 break; |
| 1380 } | 1336 } |
| 1381 } | 1337 } |
| 1382 return has_match; | 1338 return has_match; |
| 1383 } | 1339 } |
| 1384 | 1340 |
| 1385 void PasswordStoreMac::RemoveDatabaseForms( | 1341 void PasswordStoreMac::RemoveDatabaseForms( |
| 1386 ScopedVector<autofill::PasswordForm>* forms) { | 1342 std::vector<std::unique_ptr<PasswordForm>>* forms) { |
| 1387 DCHECK(login_metadata_db_); | 1343 DCHECK(login_metadata_db_); |
| 1388 ScopedVector<autofill::PasswordForm> removed_forms; | 1344 std::vector<std::unique_ptr<PasswordForm>> removed_forms; |
| 1389 MoveAllFormsOut(forms, [this, &removed_forms]( | 1345 for (std::unique_ptr<PasswordForm>& form : *forms) { |
| 1390 std::unique_ptr<autofill::PasswordForm> form) { | |
| 1391 if (login_metadata_db_->RemoveLogin(*form)) | 1346 if (login_metadata_db_->RemoveLogin(*form)) |
| 1392 removed_forms.push_back(std::move(form)); | 1347 removed_forms.push_back(std::move(form)); |
| 1393 }); | 1348 } |
| 1394 removed_forms.swap(*forms); | 1349 removed_forms.swap(*forms); |
| 1395 } | 1350 } |
| 1396 | 1351 |
| 1397 void PasswordStoreMac::RemoveKeychainForms( | 1352 void PasswordStoreMac::RemoveKeychainForms( |
| 1398 const std::vector<PasswordForm*>& forms) { | 1353 const std::vector<std::unique_ptr<PasswordForm>>& forms) { |
| 1399 MacKeychainPasswordFormAdapter owned_keychain_adapter(keychain_.get()); | 1354 MacKeychainPasswordFormAdapter owned_keychain_adapter(keychain_.get()); |
| 1400 owned_keychain_adapter.SetFindsOnlyOwnedItems(true); | 1355 owned_keychain_adapter.SetFindsOnlyOwnedItems(true); |
| 1401 for (std::vector<PasswordForm*>::const_iterator i = forms.begin(); | 1356 for (const auto& form : forms) { |
| 1402 i != forms.end(); ++i) { | 1357 owned_keychain_adapter.RemovePassword(*form); |
| 1403 owned_keychain_adapter.RemovePassword(**i); | |
| 1404 } | 1358 } |
| 1405 } | 1359 } |
| 1406 | 1360 |
| 1407 void PasswordStoreMac::CleanOrphanedForms( | 1361 void PasswordStoreMac::CleanOrphanedForms( |
| 1408 ScopedVector<autofill::PasswordForm>* orphaned_forms) { | 1362 std::vector<std::unique_ptr<PasswordForm>>* orphaned_forms) { |
| 1409 DCHECK(orphaned_forms); | 1363 DCHECK(orphaned_forms); |
| 1410 DCHECK(login_metadata_db_); | 1364 DCHECK(login_metadata_db_); |
| 1411 | 1365 |
| 1412 std::vector<std::unique_ptr<PasswordForm>> database_forms_new_format; | 1366 std::vector<std::unique_ptr<PasswordForm>> database_forms; |
| 1413 if (!login_metadata_db_->GetAutofillableLogins(&database_forms_new_format)) | 1367 if (!login_metadata_db_->GetAutofillableLogins(&database_forms)) |
| 1414 return; | 1368 return; |
| 1415 ScopedVector<PasswordForm> database_forms = | |
| 1416 ConvertToScopedVector(std::move(database_forms_new_format)); | |
| 1417 | 1369 |
| 1418 // Filter forms with corresponding Keychain entry out of |database_forms|. | 1370 // Filter forms with corresponding Keychain entry out of |database_forms|. |
| 1419 ScopedVector<PasswordForm> forms_with_keychain_entry; | 1371 std::vector<std::unique_ptr<PasswordForm>> forms_with_keychain_entry; |
| 1420 internal_keychain_helpers::GetPasswordsForForms(*keychain_, &database_forms, | 1372 internal_keychain_helpers::GetPasswordsForForms(*keychain_, &database_forms, |
| 1421 &forms_with_keychain_entry); | 1373 &forms_with_keychain_entry); |
| 1422 | 1374 |
| 1423 // Clean up any orphaned database entries. | 1375 // Clean up any orphaned database entries. |
| 1424 RemoveDatabaseForms(&database_forms); | 1376 RemoveDatabaseForms(&database_forms); |
| 1425 | 1377 |
| 1426 // Move the orphaned DB forms to the output parameter. | 1378 // Move the orphaned DB forms to the output parameter. |
| 1427 AppendSecondToFirst(orphaned_forms, &database_forms); | 1379 AppendSecondToFirst(orphaned_forms, &database_forms); |
| 1428 } | 1380 } |
| OLD | NEW |