Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(580)

Side by Side Diff: chrome/browser/password_manager/password_store_mac.cc

Issue 825773003: PasswordStore: Use ScopedVector to express ownership of forms (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix one more use-after-free Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 #include "chrome/browser/password_manager/password_store_mac_internal.h" 6 #include "chrome/browser/password_manager/password_store_mac_internal.h"
7 7
8 #include <CoreServices/CoreServices.h> 8 #include <CoreServices/CoreServices.h>
9 #include <set> 9 #include <set>
10 #include <string> 10 #include <string>
11 #include <utility> 11 #include <utility>
12 #include <vector> 12 #include <vector>
13 13
14 #include "base/callback.h" 14 #include "base/callback.h"
15 #include "base/logging.h" 15 #include "base/logging.h"
16 #include "base/mac/foundation_util.h" 16 #include "base/mac/foundation_util.h"
17 #include "base/mac/mac_logging.h" 17 #include "base/mac/mac_logging.h"
18 #include "base/memory/scoped_vector.h"
19 #include "base/message_loop/message_loop.h" 18 #include "base/message_loop/message_loop.h"
20 #include "base/stl_util.h" 19 #include "base/stl_util.h"
21 #include "base/strings/string_util.h" 20 #include "base/strings/string_util.h"
22 #include "base/strings/utf_string_conversions.h" 21 #include "base/strings/utf_string_conversions.h"
23 #include "chrome/browser/mac/security_wrappers.h" 22 #include "chrome/browser/mac/security_wrappers.h"
24 #include "components/password_manager/core/browser/login_database.h" 23 #include "components/password_manager/core/browser/login_database.h"
25 #include "components/password_manager/core/browser/password_store_change.h" 24 #include "components/password_manager/core/browser/password_store_change.h"
26 #include "content/public/browser/browser_thread.h" 25 #include "content/public/browser/browser_thread.h"
27 #include "crypto/apple_keychain.h" 26 #include "crypto/apple_keychain.h"
28 27
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
182 PasswordStoreChangeList FormsToRemoveChangeList( 181 PasswordStoreChangeList FormsToRemoveChangeList(
183 const std::vector<PasswordForm*>& forms) { 182 const std::vector<PasswordForm*>& forms) {
184 PasswordStoreChangeList changes; 183 PasswordStoreChangeList changes;
185 for (std::vector<PasswordForm*>::const_iterator i = forms.begin(); 184 for (std::vector<PasswordForm*>::const_iterator i = forms.begin();
186 i != forms.end(); ++i) { 185 i != forms.end(); ++i) {
187 changes.push_back(PasswordStoreChange(PasswordStoreChange::REMOVE, **i)); 186 changes.push_back(PasswordStoreChange(PasswordStoreChange::REMOVE, **i));
188 } 187 }
189 return changes; 188 return changes;
190 } 189 }
191 190
191 // Moves the content of |second| to the end of |first|.
192 void AppendSecondToFirst(ScopedVector<autofill::PasswordForm>* first,
193 ScopedVector<autofill::PasswordForm>* second) {
194 first->insert(first->end(), second->begin(), second->end());
195 second->weak_clear();
196 }
197
192 } // namespace 198 } // namespace
193 199
194 #pragma mark - 200 #pragma mark -
195 201
196 // TODO(stuartmorgan): Convert most of this to private helpers in 202 // TODO(stuartmorgan): Convert most of this to private helpers in
197 // MacKeychainPasswordFormAdapter once it has sufficient higher-level public 203 // MacKeychainPasswordFormAdapter once it has sufficient higher-level public
198 // methods to provide test coverage. 204 // methods to provide test coverage.
199 namespace internal_keychain_helpers { 205 namespace internal_keychain_helpers {
200 206
201 // Returns a URL built from the given components. To create a URL without a 207 // Returns a URL built from the given components. To create a URL without a
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after
411 if (base_form.origin == (*i)->origin) { 417 if (base_form.origin == (*i)->origin) {
412 return *i; 418 return *i;
413 } else if (!partial_match) { 419 } else if (!partial_match) {
414 partial_match = *i; 420 partial_match = *i;
415 } 421 }
416 } 422 }
417 } 423 }
418 return partial_match; 424 return partial_match;
419 } 425 }
420 426
421 // Returns entries from |forms| that are blacklist entries, after removing 427 // Moves entries from |forms| that are blacklist entries into |blacklist|.
422 // them from |forms|. 428 void ExtractBlacklistForms(ScopedVector<autofill::PasswordForm>* forms,
423 std::vector<PasswordForm*> ExtractBlacklistForms( 429 ScopedVector<autofill::PasswordForm>* blacklist) {
424 std::vector<PasswordForm*>* forms) { 430 blacklist->reserve(blacklist->size() + forms->size());
425 std::vector<PasswordForm*> blacklist_forms; 431 ScopedVector<autofill::PasswordForm> non_blacklist;
426 for (std::vector<PasswordForm*>::iterator i = forms->begin(); 432 for (auto& form : *forms) {
427 i != forms->end();) { 433 if (form->blacklisted_by_user)
428 PasswordForm* form = *i; 434 blacklist->push_back(form);
429 if (form->blacklisted_by_user) { 435 else
430 blacklist_forms.push_back(form); 436 non_blacklist.push_back(form);
431 i = forms->erase(i); 437 form = nullptr;
432 } else {
433 ++i;
434 }
435 } 438 }
436 return blacklist_forms; 439 forms->swap(non_blacklist);
437 } 440 }
438 441
439 // Deletes and removes from v any element that exists in s. 442 // Takes |keychain_forms| and |database_forms| and moves the following 2 types
440 template <class T> 443 // of forms to |merged_forms|: (1) blacklisted |database_forms|, (2)
441 void DeleteVectorElementsInSet(std::vector<T*>* v, const std::set<T*>& s) { 444 // |database_forms| which have a corresponding entry in |keychain_forms|. The
442 for (typename std::vector<T*>::iterator i = v->begin(); i != v->end();) { 445 // database forms of type (2) have their password value updated from the
443 T* element = *i; 446 // corresponding keychain form, and all the keychain forms corresponding to some
444 if (s.find(element) != s.end()) { 447 // database form are removed from |keychain_forms| and deleted.
445 delete element; 448 void MergePasswordForms(ScopedVector<autofill::PasswordForm>* keychain_forms,
446 i = v->erase(i); 449 ScopedVector<autofill::PasswordForm>* database_forms,
447 } else { 450 ScopedVector<autofill::PasswordForm>* merged_forms) {
448 ++i;
449 }
450 }
451 }
452
453 void MergePasswordForms(std::vector<PasswordForm*>* keychain_forms,
454 std::vector<PasswordForm*>* database_forms,
455 std::vector<PasswordForm*>* merged_forms) {
456 // Pull out the database blacklist items, since they are used as-is rather 451 // Pull out the database blacklist items, since they are used as-is rather
457 // than being merged with keychain forms. 452 // than being merged with keychain forms.
458 std::vector<PasswordForm*> database_blacklist_forms = 453 ExtractBlacklistForms(database_forms, merged_forms);
459 ExtractBlacklistForms(database_forms);
460 454
461 // Merge the normal entries. 455 // Merge the normal entries.
462 std::set<PasswordForm*> used_keychain_forms; 456 ScopedVector<autofill::PasswordForm> unused_database_forms;
463 for (std::vector<PasswordForm*>::iterator i = database_forms->begin(); 457 unused_database_forms.reserve(database_forms->size());
464 i != database_forms->end();) { 458 std::set<autofill::PasswordForm*> used_keychain_forms;
465 PasswordForm* db_form = *i; 459 for (auto& db_form : *database_forms) {
466 PasswordForm* best_match = BestKeychainFormForForm(*db_form, 460 PasswordForm* best_match =
467 keychain_forms); 461 BestKeychainFormForForm(*db_form, &keychain_forms->get());
468 if (best_match) { 462 if (best_match) {
469 used_keychain_forms.insert(best_match); 463 used_keychain_forms.insert(best_match);
470 db_form->password_value = best_match->password_value; 464 db_form->password_value = best_match->password_value;
471 merged_forms->push_back(db_form); 465 merged_forms->push_back(db_form);
472 i = database_forms->erase(i);
473 } else { 466 } else {
474 ++i; 467 unused_database_forms.push_back(db_form);
468 }
469 db_form = nullptr;
470 }
471 database_forms->swap(unused_database_forms);
472
473 // Clear out all the Keychain entries we used.
474 ScopedVector<autofill::PasswordForm> unused_keychain_forms;
475 unused_keychain_forms.reserve(keychain_forms->size());
476 for (auto& keychain_form : *keychain_forms) {
477 if (!ContainsKey(used_keychain_forms, keychain_form)) {
478 unused_keychain_forms.push_back(keychain_form);
479 keychain_form = nullptr;
475 } 480 }
476 } 481 }
477 482 keychain_forms->swap(unused_keychain_forms);
478 // Add in the blacklist entries from the database.
479 merged_forms->insert(merged_forms->end(),
480 database_blacklist_forms.begin(),
481 database_blacklist_forms.end());
482
483 // Clear out all the Keychain entries we used.
484 DeleteVectorElementsInSet(keychain_forms, used_keychain_forms);
485 } 483 }
486 484
487 std::vector<ItemFormPair> ExtractAllKeychainItemAttributesIntoPasswordForms( 485 std::vector<ItemFormPair> ExtractAllKeychainItemAttributesIntoPasswordForms(
488 std::vector<SecKeychainItemRef>* keychain_items, 486 std::vector<SecKeychainItemRef>* keychain_items,
489 const AppleKeychain& keychain) { 487 const AppleKeychain& keychain) {
490 DCHECK(keychain_items); 488 DCHECK(keychain_items);
491 MacKeychainPasswordFormAdapter keychain_adapter(&keychain); 489 MacKeychainPasswordFormAdapter keychain_adapter(&keychain);
492 *keychain_items = keychain_adapter.GetAllPasswordFormKeychainItems(); 490 *keychain_items = keychain_adapter.GetAllPasswordFormKeychainItems();
493 std::vector<ItemFormPair> item_form_pairs; 491 std::vector<ItemFormPair> item_form_pairs;
494 for (std::vector<SecKeychainItemRef>::iterator i = keychain_items->begin(); 492 for (std::vector<SecKeychainItemRef>::iterator i = keychain_items->begin();
495 i != keychain_items->end(); ++i) { 493 i != keychain_items->end(); ++i) {
496 PasswordForm* form_without_password = new PasswordForm(); 494 PasswordForm* form_without_password = new PasswordForm();
497 internal_keychain_helpers::FillPasswordFormFromKeychainItem( 495 internal_keychain_helpers::FillPasswordFormFromKeychainItem(
498 keychain, 496 keychain,
499 *i, 497 *i,
500 form_without_password, 498 form_without_password,
501 false); // Load password attributes, but not password data. 499 false); // Load password attributes, but not password data.
502 item_form_pairs.push_back(std::make_pair(&(*i), form_without_password)); 500 item_form_pairs.push_back(std::make_pair(&(*i), form_without_password));
503 } 501 }
504 return item_form_pairs; 502 return item_form_pairs;
505 } 503 }
506 504
507 std::vector<PasswordForm*> GetPasswordsForForms( 505 void GetPasswordsForForms(const AppleKeychain& keychain,
508 const AppleKeychain& keychain, 506 ScopedVector<autofill::PasswordForm>* database_forms,
509 std::vector<PasswordForm*>* database_forms) { 507 ScopedVector<autofill::PasswordForm>* passwords) {
510 // First load the attributes of all items in the keychain without loading 508 // First load the attributes of all items in the keychain without loading
511 // their password data, and then match items in |database_forms| against them. 509 // their password data, and then match items in |database_forms| against them.
512 // This avoids individually searching through the keychain for passwords 510 // This avoids individually searching through the keychain for passwords
513 // matching each form in |database_forms|, and results in a significant 511 // matching each form in |database_forms|, and results in a significant
514 // performance gain, replacing O(N) keychain search operations with a single 512 // performance gain, replacing O(N) keychain search operations with a single
515 // operation that loads all keychain items, and then selective reads of only 513 // operation that loads all keychain items, and then selective reads of only
516 // the relevant passwords. See crbug.com/263685. 514 // the relevant passwords. See crbug.com/263685.
517 std::vector<SecKeychainItemRef> keychain_items; 515 std::vector<SecKeychainItemRef> keychain_items;
518 std::vector<ItemFormPair> item_form_pairs = 516 std::vector<ItemFormPair> item_form_pairs =
519 ExtractAllKeychainItemAttributesIntoPasswordForms(&keychain_items, 517 ExtractAllKeychainItemAttributesIntoPasswordForms(&keychain_items,
520 keychain); 518 keychain);
521 519
522 // Next, compare the attributes of the PasswordForms in |database_forms| 520 // Next, compare the attributes of the PasswordForms in |database_forms|
523 // against those in |item_form_pairs|, and extract password data for each 521 // against those in |item_form_pairs|, and extract password data for each
524 // matching PasswordForm using its corresponding SecKeychainItemRef. 522 // matching PasswordForm using its corresponding SecKeychainItemRef.
525 std::vector<PasswordForm*> merged_forms; 523 ScopedVector<autofill::PasswordForm> unused_db_forms;
526 for (std::vector<PasswordForm*>::iterator i = database_forms->begin(); 524 unused_db_forms.reserve(database_forms->size());
527 i != database_forms->end();) { 525 for (auto& db_form : *database_forms) {
528 std::vector<PasswordForm*> db_form_container(1, *i); 526 ScopedVector<autofill::PasswordForm> keychain_matches(
vasilii 2015/01/28 15:09:03 nit: ScopedVector<autofill::PasswordForm> keychain
vabr (Chromium) 2015/01/28 16:36:27 Done. You are right: Both the r-value constructor
vasilii 2015/01/28 17:27:22 There is no operator= here. "MyObject o = somethin
529 std::vector<PasswordForm*> keychain_matches = 527 ExtractPasswordsMergeableWithForm(keychain, item_form_pairs, *db_form));
530 ExtractPasswordsMergeableWithForm(keychain, item_form_pairs, **i); 528
531 MergePasswordForms(&keychain_matches, &db_form_container, &merged_forms); 529 ScopedVector<autofill::PasswordForm> db_form_container;
532 if (db_form_container.empty()) { 530 db_form_container.push_back(db_form);
533 i = database_forms->erase(i); 531 db_form = nullptr;
534 } else { 532 MergePasswordForms(&keychain_matches, &db_form_container, passwords);
535 ++i; 533 unused_db_forms.insert(unused_db_forms.end(), db_form_container.begin(),
536 } 534 db_form_container.end());
537 STLDeleteElements(&keychain_matches); 535 db_form_container.weak_clear();
538 } 536 }
537 database_forms->swap(unused_db_forms);
539 538
540 // Clean up temporary PasswordForms and SecKeychainItemRefs.
541 STLDeleteContainerPairSecondPointers(item_form_pairs.begin(), 539 STLDeleteContainerPairSecondPointers(item_form_pairs.begin(),
542 item_form_pairs.end()); 540 item_form_pairs.end());
543 for (std::vector<SecKeychainItemRef>::iterator i = keychain_items.begin(); 541 for (SecKeychainItemRef item : keychain_items) {
544 i != keychain_items.end(); ++i) { 542 keychain.Free(item);
545 keychain.Free(*i);
546 } 543 }
547 return merged_forms;
548 } 544 }
549 545
550 // TODO(stuartmorgan): signon_realm for proxies is not yet supported. 546 // TODO(stuartmorgan): signon_realm for proxies is not yet supported.
551 bool ExtractSignonRealmComponents(const std::string& signon_realm, 547 bool ExtractSignonRealmComponents(const std::string& signon_realm,
552 std::string* server, 548 std::string* server,
553 UInt32* port, 549 UInt32* port,
554 bool* is_secure, 550 bool* is_secure,
555 std::string* security_domain) { 551 std::string* security_domain) {
556 // The signon_realm will be the Origin portion of a URL for an HTML form, 552 // The signon_realm will be the Origin portion of a URL for an HTML form,
557 // and the same but with the security domain as a path for HTTP auth. 553 // and the same but with the security domain as a path for HTTP auth.
(...skipping 25 matching lines...) Expand all
583 UInt32 port; 579 UInt32 port;
584 bool is_secure; 580 bool is_secure;
585 if (!ExtractSignonRealmComponents(query_form.signon_realm, &server, &port, 581 if (!ExtractSignonRealmComponents(query_form.signon_realm, &server, &port,
586 &is_secure, &security_domain)) { 582 &is_secure, &security_domain)) {
587 return false; 583 return false;
588 } 584 }
589 return internal_keychain_helpers::FormsMatchForMerge( 585 return internal_keychain_helpers::FormsMatchForMerge(
590 query_form, other_form, STRICT_FORM_MATCH); 586 query_form, other_form, STRICT_FORM_MATCH);
591 } 587 }
592 588
593 std::vector<PasswordForm*> ExtractPasswordsMergeableWithForm( 589 ScopedVector<autofill::PasswordForm> ExtractPasswordsMergeableWithForm(
594 const AppleKeychain& keychain, 590 const AppleKeychain& keychain,
595 const std::vector<ItemFormPair>& item_form_pairs, 591 const std::vector<ItemFormPair>& item_form_pairs,
596 const PasswordForm& query_form) { 592 const PasswordForm& query_form) {
597 std::vector<PasswordForm*> matches; 593 ScopedVector<autofill::PasswordForm> matches;
598 for (std::vector<ItemFormPair>::const_iterator i = item_form_pairs.begin(); 594 for (std::vector<ItemFormPair>::const_iterator i = item_form_pairs.begin();
599 i != item_form_pairs.end(); ++i) { 595 i != item_form_pairs.end(); ++i) {
600 if (FormIsValidAndMatchesOtherForm(query_form, *(i->second))) { 596 if (FormIsValidAndMatchesOtherForm(query_form, *(i->second))) {
601 // Create a new object, since the caller is responsible for deleting the 597 // Create a new object, since the caller is responsible for deleting the
602 // returned forms. 598 // returned forms.
603 scoped_ptr<PasswordForm> form_with_password(new PasswordForm()); 599 scoped_ptr<PasswordForm> form_with_password(new PasswordForm());
604 internal_keychain_helpers::FillPasswordFormFromKeychainItem( 600 internal_keychain_helpers::FillPasswordFormFromKeychainItem(
605 keychain, 601 keychain, *(i->first), form_with_password.get(),
606 *(i->first),
607 form_with_password.get(),
608 true); // Load password attributes and data. 602 true); // Load password attributes and data.
609 // Do not include blacklisted items found in the keychain. 603 // Do not include blacklisted items found in the keychain.
610 if (!form_with_password->blacklisted_by_user) 604 if (!form_with_password->blacklisted_by_user)
611 matches.push_back(form_with_password.release()); 605 matches.push_back(form_with_password.release());
612 } 606 }
613 } 607 }
614 return matches; 608 return matches.Pass();
615 } 609 }
616 610
617 } // namespace internal_keychain_helpers 611 } // namespace internal_keychain_helpers
618 612
619 #pragma mark - 613 #pragma mark -
620 614
621 MacKeychainPasswordFormAdapter::MacKeychainPasswordFormAdapter( 615 MacKeychainPasswordFormAdapter::MacKeychainPasswordFormAdapter(
622 const AppleKeychain* keychain) 616 const AppleKeychain* keychain)
623 : keychain_(keychain), finds_only_owned_(false) { 617 : keychain_(keychain), finds_only_owned_(false) {
624 } 618 }
625 619
626 std::vector<PasswordForm*> MacKeychainPasswordFormAdapter::PasswordsFillingForm( 620 ScopedVector<autofill::PasswordForm>
621 MacKeychainPasswordFormAdapter::PasswordsFillingForm(
627 const std::string& signon_realm, 622 const std::string& signon_realm,
628 PasswordForm::Scheme scheme) { 623 PasswordForm::Scheme scheme) {
629 std::vector<SecKeychainItemRef> keychain_items = 624 std::vector<SecKeychainItemRef> keychain_items =
630 MatchingKeychainItems(signon_realm, scheme, NULL, NULL); 625 MatchingKeychainItems(signon_realm, scheme, NULL, NULL);
631
632 return ConvertKeychainItemsToForms(&keychain_items); 626 return ConvertKeychainItemsToForms(&keychain_items);
633 } 627 }
634 628
635 bool MacKeychainPasswordFormAdapter::HasPasswordExactlyMatchingForm( 629 bool MacKeychainPasswordFormAdapter::HasPasswordExactlyMatchingForm(
636 const PasswordForm& query_form) { 630 const PasswordForm& query_form) {
637 SecKeychainItemRef keychain_item = KeychainItemForForm(query_form); 631 SecKeychainItemRef keychain_item = KeychainItemForForm(query_form);
638 if (keychain_item) { 632 if (keychain_item) {
639 keychain_->Free(keychain_item); 633 keychain_->Free(keychain_item);
640 return true; 634 return true;
641 } 635 }
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
674 &supported_auth_types[i], 668 &supported_auth_types[i],
675 NULL, 669 NULL,
676 NULL, 670 NULL,
677 NULL, 671 NULL,
678 creator ? &creator : NULL); 672 creator ? &creator : NULL);
679 keychain_search.FindMatchingItems(&matches); 673 keychain_search.FindMatchingItems(&matches);
680 } 674 }
681 return matches; 675 return matches;
682 } 676 }
683 677
684 std::vector<PasswordForm*> 678 ScopedVector<autofill::PasswordForm>
685 MacKeychainPasswordFormAdapter::GetAllPasswordFormPasswords() { 679 MacKeychainPasswordFormAdapter::GetAllPasswordFormPasswords() {
686 std::vector<SecKeychainItemRef> items = GetAllPasswordFormKeychainItems(); 680 std::vector<SecKeychainItemRef> items = GetAllPasswordFormKeychainItems();
687 return ConvertKeychainItemsToForms(&items); 681 return ConvertKeychainItemsToForms(&items);
688 } 682 }
689 683
690 bool MacKeychainPasswordFormAdapter::AddPassword(const PasswordForm& form) { 684 bool MacKeychainPasswordFormAdapter::AddPassword(const PasswordForm& form) {
691 // We should never be trying to store a blacklist in the keychain. 685 // We should never be trying to store a blacklist in the keychain.
692 DCHECK(!form.blacklisted_by_user); 686 DCHECK(!form.blacklisted_by_user);
693 687
694 std::string server; 688 std::string server;
695 std::string security_domain; 689 std::string security_domain;
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
738 OSStatus result = keychain_->ItemDelete(keychain_item); 732 OSStatus result = keychain_->ItemDelete(keychain_item);
739 keychain_->Free(keychain_item); 733 keychain_->Free(keychain_item);
740 return result == noErr; 734 return result == noErr;
741 } 735 }
742 736
743 void MacKeychainPasswordFormAdapter::SetFindsOnlyOwnedItems( 737 void MacKeychainPasswordFormAdapter::SetFindsOnlyOwnedItems(
744 bool finds_only_owned) { 738 bool finds_only_owned) {
745 finds_only_owned_ = finds_only_owned; 739 finds_only_owned_ = finds_only_owned;
746 } 740 }
747 741
748 std::vector<PasswordForm*> 742 ScopedVector<autofill::PasswordForm>
749 MacKeychainPasswordFormAdapter::ConvertKeychainItemsToForms( 743 MacKeychainPasswordFormAdapter::ConvertKeychainItemsToForms(
750 std::vector<SecKeychainItemRef>* items) { 744 std::vector<SecKeychainItemRef>* items) {
751 std::vector<PasswordForm*> keychain_forms; 745 ScopedVector<autofill::PasswordForm> forms;
752 for (std::vector<SecKeychainItemRef>::const_iterator i = items->begin(); 746 for (SecKeychainItemRef item : *items) {
753 i != items->end(); ++i) { 747 scoped_ptr<PasswordForm> form(new PasswordForm());
754 PasswordForm* form = new PasswordForm();
755 if (internal_keychain_helpers::FillPasswordFormFromKeychainItem( 748 if (internal_keychain_helpers::FillPasswordFormFromKeychainItem(
756 *keychain_, *i, form, true)) { 749 *keychain_, item, form.get(), true)) {
757 keychain_forms.push_back(form); 750 forms.push_back(form.release());
758 } 751 }
759 keychain_->Free(*i); 752 keychain_->Free(item);
760 } 753 }
761 items->clear(); 754 items->clear();
762 return keychain_forms; 755 return forms.Pass();
763 } 756 }
764 757
765 SecKeychainItemRef MacKeychainPasswordFormAdapter::KeychainItemForForm( 758 SecKeychainItemRef MacKeychainPasswordFormAdapter::KeychainItemForForm(
766 const PasswordForm& form) { 759 const PasswordForm& form) {
767 // We don't store blacklist entries in the keychain, so the answer to "what 760 // We don't store blacklist entries in the keychain, so the answer to "what
768 // Keychain item goes with this form" is always "nothing" for blacklists. 761 // Keychain item goes with this form" is always "nothing" for blacklists.
769 if (form.blacklisted_by_user) { 762 if (form.blacklisted_by_user) {
770 return NULL; 763 return NULL;
771 } 764 }
772 765
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after
976 969
977 changes.push_back(PasswordStoreChange(PasswordStoreChange::REMOVE, form)); 970 changes.push_back(PasswordStoreChange(PasswordStoreChange::REMOVE, form));
978 } 971 }
979 return changes; 972 return changes;
980 } 973 }
981 974
982 PasswordStoreChangeList PasswordStoreMac::RemoveLoginsCreatedBetweenImpl( 975 PasswordStoreChangeList PasswordStoreMac::RemoveLoginsCreatedBetweenImpl(
983 base::Time delete_begin, 976 base::Time delete_begin,
984 base::Time delete_end) { 977 base::Time delete_end) {
985 PasswordStoreChangeList changes; 978 PasswordStoreChangeList changes;
986 ScopedVector<PasswordForm> forms; 979 ScopedVector<PasswordForm> forms_to_remove;
987 if (login_metadata_db_ && 980 if (login_metadata_db_ &&
988 login_metadata_db_->GetLoginsCreatedBetween(delete_begin, delete_end, 981 login_metadata_db_->GetLoginsCreatedBetween(delete_begin, delete_end,
989 &forms.get()) && 982 &forms_to_remove) &&
990 login_metadata_db_->RemoveLoginsCreatedBetween(delete_begin, 983 login_metadata_db_->RemoveLoginsCreatedBetween(delete_begin,
991 delete_end)) { 984 delete_end)) {
992 RemoveKeychainForms(forms.get()); 985 RemoveKeychainForms(forms_to_remove.get());
993 CleanOrphanedForms(&forms.get()); 986 CleanOrphanedForms(&forms_to_remove); // Add the orphaned forms.
994 changes = FormsToRemoveChangeList(forms.get()); 987 changes = FormsToRemoveChangeList(forms_to_remove.get());
995 LogStatsForBulkDeletion(changes.size()); 988 LogStatsForBulkDeletion(changes.size());
996 } 989 }
997 return changes; 990 return changes;
998 } 991 }
999 992
1000 PasswordStoreChangeList PasswordStoreMac::RemoveLoginsSyncedBetweenImpl( 993 PasswordStoreChangeList PasswordStoreMac::RemoveLoginsSyncedBetweenImpl(
1001 base::Time delete_begin, 994 base::Time delete_begin,
1002 base::Time delete_end) { 995 base::Time delete_end) {
1003 PasswordStoreChangeList changes; 996 PasswordStoreChangeList changes;
1004 ScopedVector<PasswordForm> forms; 997 ScopedVector<PasswordForm> forms_to_remove;
1005 if (login_metadata_db_ && 998 if (login_metadata_db_ &&
1006 login_metadata_db_->GetLoginsSyncedBetween(delete_begin, delete_end, 999 login_metadata_db_->GetLoginsSyncedBetween(delete_begin, delete_end,
1007 &forms.get()) && 1000 &forms_to_remove) &&
1008 login_metadata_db_->RemoveLoginsSyncedBetween(delete_begin, delete_end)) { 1001 login_metadata_db_->RemoveLoginsSyncedBetween(delete_begin, delete_end)) {
1009 RemoveKeychainForms(forms.get()); 1002 RemoveKeychainForms(forms_to_remove.get());
1010 CleanOrphanedForms(&forms.get()); 1003 CleanOrphanedForms(&forms_to_remove); // Add the orphaned forms_to_remove.
1011 changes = FormsToRemoveChangeList(forms.get()); 1004 changes = FormsToRemoveChangeList(forms_to_remove.get());
1012 LogStatsForBulkDeletionDuringRollback(changes.size()); 1005 LogStatsForBulkDeletionDuringRollback(changes.size());
1013 } 1006 }
1014 return changes; 1007 return changes;
1015 } 1008 }
1016 1009
1017 void PasswordStoreMac::GetLoginsImpl( 1010 void PasswordStoreMac::GetLoginsImpl(
1018 const autofill::PasswordForm& form, 1011 const autofill::PasswordForm& form,
1019 AuthorizationPromptPolicy prompt_policy, 1012 AuthorizationPromptPolicy prompt_policy,
1020 const ConsumerCallbackRunner& callback_runner) { 1013 const ConsumerCallbackRunner& callback_runner) {
1021 chrome::ScopedSecKeychainSetUserInteractionAllowed user_interaction_allowed( 1014 chrome::ScopedSecKeychainSetUserInteractionAllowed user_interaction_allowed(
1022 prompt_policy == ALLOW_PROMPT); 1015 prompt_policy == ALLOW_PROMPT);
1023 1016
1024 if (!login_metadata_db_) { 1017 if (!login_metadata_db_) {
1025 callback_runner.Run(std::vector<PasswordForm*>()); 1018 callback_runner.Run(ScopedVector<autofill::PasswordForm>());
1026 return; 1019 return;
1027 } 1020 }
1028 1021
1029 ScopedVector<PasswordForm> database_forms; 1022 ScopedVector<PasswordForm> database_forms;
1030 login_metadata_db_->GetLogins(form, &database_forms.get()); 1023 login_metadata_db_->GetLogins(form, &database_forms);
1031 1024
1032 // Let's gather all signon realms we want to match with keychain entries. 1025 // Let's gather all signon realms we want to match with keychain entries.
1033 std::set<std::string> realm_set; 1026 std::set<std::string> realm_set;
1034 realm_set.insert(form.signon_realm); 1027 realm_set.insert(form.signon_realm);
1035 for (std::vector<PasswordForm*>::const_iterator db_form = 1028 for (const autofill::PasswordForm* db_form : database_forms) {
1036 database_forms.begin();
1037 db_form != database_forms.end();
1038 ++db_form) {
1039 // TODO(vabr): We should not be getting different schemes here. 1029 // TODO(vabr): We should not be getting different schemes here.
1040 // http://crbug.com/340112 1030 // http://crbug.com/340112
1041 if (form.scheme != (*db_form)->scheme) 1031 if (form.scheme != db_form->scheme)
1042 continue; // Forms with different schemes never match. 1032 continue; // Forms with different schemes never match.
1043 const std::string& original_singon_realm((*db_form)->original_signon_realm); 1033 const std::string& original_singon_realm(db_form->original_signon_realm);
1044 if (!original_singon_realm.empty()) 1034 if (!original_singon_realm.empty())
1045 realm_set.insert(original_singon_realm); 1035 realm_set.insert(original_singon_realm);
1046 } 1036 }
1047 std::vector<PasswordForm*> keychain_forms; 1037 ScopedVector<autofill::PasswordForm> keychain_forms;
1048 for (std::set<std::string>::const_iterator realm = realm_set.begin(); 1038 for (std::set<std::string>::const_iterator realm = realm_set.begin();
1049 realm != realm_set.end(); 1039 realm != realm_set.end(); ++realm) {
1050 ++realm) {
1051 MacKeychainPasswordFormAdapter keychain_adapter(keychain_.get()); 1040 MacKeychainPasswordFormAdapter keychain_adapter(keychain_.get());
1052 std::vector<PasswordForm*> temp_keychain_forms = 1041 ScopedVector<autofill::PasswordForm> temp_keychain_forms(
1053 keychain_adapter.PasswordsFillingForm(*realm, form.scheme); 1042 keychain_adapter.PasswordsFillingForm(*realm, form.scheme));
1054 keychain_forms.insert(keychain_forms.end(), 1043 AppendSecondToFirst(&keychain_forms, &temp_keychain_forms);
1055 temp_keychain_forms.begin(),
1056 temp_keychain_forms.end());
1057 } 1044 }
1058 1045
1059 std::vector<PasswordForm*> matched_forms; 1046 ScopedVector<autofill::PasswordForm> matched_forms;
1060 internal_keychain_helpers::MergePasswordForms(&keychain_forms, 1047 internal_keychain_helpers::MergePasswordForms(
1061 &database_forms.get(), 1048 &keychain_forms, &database_forms, &matched_forms);
1062 &matched_forms);
1063 1049
1064 // Strip any blacklist entries out of the unused Keychain array, then take 1050 // Strip any blacklist entries out of the unused Keychain array, then take
1065 // all the entries that are left (which we can use as imported passwords). 1051 // all the entries that are left (which we can use as imported passwords).
1066 ScopedVector<PasswordForm> keychain_blacklist_forms; 1052 ScopedVector<PasswordForm> keychain_blacklist_forms;
1067 internal_keychain_helpers::ExtractBlacklistForms(&keychain_forms).swap( 1053 internal_keychain_helpers::ExtractBlacklistForms(&keychain_forms,
1068 keychain_blacklist_forms.get()); 1054 &keychain_blacklist_forms);
1069 matched_forms.insert(matched_forms.end(), 1055 matched_forms.insert(matched_forms.end(),
1070 keychain_forms.begin(), 1056 keychain_forms.begin(),
1071 keychain_forms.end()); 1057 keychain_forms.end());
1072 keychain_forms.clear(); 1058 keychain_forms.weak_clear();
1073 1059
1074 if (!database_forms.empty()) { 1060 if (!database_forms.empty()) {
1075 RemoveDatabaseForms(database_forms.get()); 1061 RemoveDatabaseForms(database_forms.get());
1076 NotifyLoginsChanged(FormsToRemoveChangeList(database_forms.get())); 1062 NotifyLoginsChanged(FormsToRemoveChangeList(database_forms.get()));
1077 } 1063 }
1078 1064
1079 callback_runner.Run(matched_forms); 1065 callback_runner.Run(matched_forms.Pass());
1080 } 1066 }
1081 1067
1082 void PasswordStoreMac::GetBlacklistLoginsImpl(GetLoginsRequest* request) { 1068 void PasswordStoreMac::GetBlacklistLoginsImpl(GetLoginsRequest* request) {
1083 FillBlacklistLogins(request->result()); 1069 ScopedVector<autofill::PasswordForm> obtained_forms;
1070 FillBlacklistLogins(&obtained_forms);
1071 request->result()->swap(obtained_forms.get());
1084 ForwardLoginsResult(request); 1072 ForwardLoginsResult(request);
1085 } 1073 }
1086 1074
1087 void PasswordStoreMac::GetAutofillableLoginsImpl(GetLoginsRequest* request) { 1075 void PasswordStoreMac::GetAutofillableLoginsImpl(GetLoginsRequest* request) {
1088 FillAutofillableLogins(request->result()); 1076 ScopedVector<autofill::PasswordForm> obtained_forms;
1077 FillAutofillableLogins(&obtained_forms);
1078 request->result()->swap(obtained_forms.get());
1089 ForwardLoginsResult(request); 1079 ForwardLoginsResult(request);
1090 } 1080 }
1091 1081
1092 bool PasswordStoreMac::FillAutofillableLogins( 1082 bool PasswordStoreMac::FillAutofillableLogins(
1093 std::vector<PasswordForm*>* forms) { 1083 ScopedVector<autofill::PasswordForm>* forms) {
1094 DCHECK(thread_->message_loop() == base::MessageLoop::current()); 1084 DCHECK(thread_->message_loop() == base::MessageLoop::current());
1095 1085
1096 ScopedVector<PasswordForm> database_forms; 1086 ScopedVector<PasswordForm> database_forms;
1097 if (!login_metadata_db_ || 1087 if (!login_metadata_db_ ||
1098 !login_metadata_db_->GetAutofillableLogins(&database_forms.get())) 1088 !login_metadata_db_->GetAutofillableLogins(&database_forms))
1099 return false; 1089 return false;
1100 1090
1101 std::vector<PasswordForm*> merged_forms = 1091 internal_keychain_helpers::GetPasswordsForForms(*keychain_, &database_forms,
1102 internal_keychain_helpers::GetPasswordsForForms(*keychain_, 1092 forms);
1103 &database_forms.get());
1104 1093
1105 if (!database_forms.empty()) { 1094 if (!database_forms.empty()) {
1106 RemoveDatabaseForms(database_forms.get()); 1095 RemoveDatabaseForms(database_forms.get());
1107 NotifyLoginsChanged(FormsToRemoveChangeList(database_forms.get())); 1096 NotifyLoginsChanged(FormsToRemoveChangeList(database_forms.get()));
1108 } 1097 }
1109 1098
1110 forms->insert(forms->end(), merged_forms.begin(), merged_forms.end());
1111 return true; 1099 return true;
1112 } 1100 }
1113 1101
1114 bool PasswordStoreMac::FillBlacklistLogins( 1102 bool PasswordStoreMac::FillBlacklistLogins(
1115 std::vector<PasswordForm*>* forms) { 1103 ScopedVector<autofill::PasswordForm>* forms) {
1116 DCHECK(thread_->message_loop() == base::MessageLoop::current()); 1104 DCHECK(thread_->message_loop() == base::MessageLoop::current());
1117 return login_metadata_db_ && login_metadata_db_->GetBlacklistLogins(forms); 1105 return login_metadata_db_ && login_metadata_db_->GetBlacklistLogins(forms);
1118 } 1106 }
1119 1107
1120 bool PasswordStoreMac::AddToKeychainIfNecessary(const PasswordForm& form) { 1108 bool PasswordStoreMac::AddToKeychainIfNecessary(const PasswordForm& form) {
1121 if (form.blacklisted_by_user) { 1109 if (form.blacklisted_by_user) {
1122 return true; 1110 return true;
1123 } 1111 }
1124 MacKeychainPasswordFormAdapter keychainAdapter(keychain_.get()); 1112 MacKeychainPasswordFormAdapter keychainAdapter(keychain_.get());
1125 return keychainAdapter.AddPassword(form); 1113 return keychainAdapter.AddPassword(form);
1126 } 1114 }
1127 1115
1128 bool PasswordStoreMac::DatabaseHasFormMatchingKeychainForm( 1116 bool PasswordStoreMac::DatabaseHasFormMatchingKeychainForm(
1129 const autofill::PasswordForm& form) { 1117 const autofill::PasswordForm& form) {
1130 DCHECK(login_metadata_db_); 1118 DCHECK(login_metadata_db_);
1131 bool has_match = false; 1119 bool has_match = false;
1132 std::vector<PasswordForm*> database_forms; 1120 ScopedVector<autofill::PasswordForm> database_forms;
1133 login_metadata_db_->GetLogins(form, &database_forms); 1121 login_metadata_db_->GetLogins(form, &database_forms);
1134 for (std::vector<PasswordForm*>::iterator i = database_forms.begin(); 1122 for (const autofill::PasswordForm* db_form : database_forms) {
1135 i != database_forms.end(); ++i) {
1136 // Below we filter out forms with non-empty original_signon_realm, because 1123 // Below we filter out forms with non-empty original_signon_realm, because
1137 // those signal fuzzy matches, and we are only interested in exact ones. 1124 // those signal fuzzy matches, and we are only interested in exact ones.
1138 if ((*i)->original_signon_realm.empty() && 1125 if (db_form->original_signon_realm.empty() &&
1139 internal_keychain_helpers::FormsMatchForMerge( 1126 internal_keychain_helpers::FormsMatchForMerge(
1140 form, **i, internal_keychain_helpers::STRICT_FORM_MATCH) && 1127 form, *db_form, internal_keychain_helpers::STRICT_FORM_MATCH) &&
1141 (*i)->origin == form.origin) { 1128 db_form->origin == form.origin) {
1142 has_match = true; 1129 has_match = true;
1143 break; 1130 break;
1144 } 1131 }
1145 } 1132 }
1146 STLDeleteElements(&database_forms);
1147 return has_match; 1133 return has_match;
1148 } 1134 }
1149 1135
1150 void PasswordStoreMac::RemoveDatabaseForms( 1136 void PasswordStoreMac::RemoveDatabaseForms(
1151 const std::vector<PasswordForm*>& forms) { 1137 const std::vector<PasswordForm*>& forms) {
1152 DCHECK(login_metadata_db_); 1138 DCHECK(login_metadata_db_);
1153 for (std::vector<PasswordForm*>::const_iterator i = forms.begin(); 1139 for (std::vector<PasswordForm*>::const_iterator i = forms.begin();
1154 i != forms.end(); ++i) { 1140 i != forms.end(); ++i) {
1155 login_metadata_db_->RemoveLogin(**i); 1141 login_metadata_db_->RemoveLogin(**i);
1156 } 1142 }
1157 } 1143 }
1158 1144
1159 void PasswordStoreMac::RemoveKeychainForms( 1145 void PasswordStoreMac::RemoveKeychainForms(
1160 const std::vector<PasswordForm*>& forms) { 1146 const std::vector<PasswordForm*>& forms) {
1161 MacKeychainPasswordFormAdapter owned_keychain_adapter(keychain_.get()); 1147 MacKeychainPasswordFormAdapter owned_keychain_adapter(keychain_.get());
1162 owned_keychain_adapter.SetFindsOnlyOwnedItems(true); 1148 owned_keychain_adapter.SetFindsOnlyOwnedItems(true);
1163 for (std::vector<PasswordForm*>::const_iterator i = forms.begin(); 1149 for (std::vector<PasswordForm*>::const_iterator i = forms.begin();
1164 i != forms.end(); ++i) { 1150 i != forms.end(); ++i) {
1165 owned_keychain_adapter.RemovePassword(**i); 1151 owned_keychain_adapter.RemovePassword(**i);
1166 } 1152 }
1167 } 1153 }
1168 1154
1169 void PasswordStoreMac::CleanOrphanedForms(std::vector<PasswordForm*>* forms) { 1155 void PasswordStoreMac::CleanOrphanedForms(
1170 DCHECK(forms); 1156 ScopedVector<autofill::PasswordForm>* orphaned_forms) {
1157 DCHECK(orphaned_forms);
1171 DCHECK(login_metadata_db_); 1158 DCHECK(login_metadata_db_);
1172 1159
1173 std::vector<PasswordForm*> database_forms; 1160 ScopedVector<autofill::PasswordForm> database_forms;
1174 login_metadata_db_->GetAutofillableLogins(&database_forms); 1161 login_metadata_db_->GetAutofillableLogins(&database_forms);
1175 1162
1176 ScopedVector<PasswordForm> merged_forms; 1163 // Filter forms with corresponding Keychain entry out of |database_forms|.
1177 merged_forms.get() = internal_keychain_helpers::GetPasswordsForForms( 1164 ScopedVector<PasswordForm> forms_with_keychain_entry;
1178 *keychain_, &database_forms); 1165 internal_keychain_helpers::GetPasswordsForForms(*keychain_, &database_forms,
1166 &forms_with_keychain_entry);
1179 1167
1180 // Clean up any orphaned database entries. 1168 // Clean up any orphaned database entries.
1181 RemoveDatabaseForms(database_forms); 1169 RemoveDatabaseForms(database_forms.get());
1182 1170
1183 forms->insert(forms->end(), database_forms.begin(), database_forms.end()); 1171 // Move the orphaned DB forms to the output parameter.
1172 orphaned_forms->insert(orphaned_forms->end(), database_forms.begin(),
1173 database_forms.end());
1174 database_forms.weak_clear();
1184 } 1175 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698