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