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

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

Issue 164332: Use real creator code for Keychain items (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 11 years, 4 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 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 <string> 9 #include <string>
10 #include <vector> 10 #include <vector>
11 11
12 #include "base/logging.h" 12 #include "base/logging.h"
13 #include "base/mac_util.h"
13 #include "base/stl_util-inl.h" 14 #include "base/stl_util-inl.h"
14 #include "base/string_util.h" 15 #include "base/string_util.h"
15 #include "chrome/browser/keychain_mac.h" 16 #include "chrome/browser/keychain_mac.h"
16 #include "chrome/browser/password_manager/login_database_mac.h" 17 #include "chrome/browser/password_manager/login_database_mac.h"
17 18
18 using webkit_glue::PasswordForm; 19 using webkit_glue::PasswordForm;
19 20
20 static const OSType kChromeKeychainCreatorCode = 'rimZ';
21
22 // Utility class to handle the details of constructing and running a keychain 21 // Utility class to handle the details of constructing and running a keychain
23 // search from a set of attributes. 22 // search from a set of attributes.
24 class KeychainSearch { 23 class KeychainSearch {
25 public: 24 public:
26 KeychainSearch(const MacKeychain& keychain); 25 KeychainSearch(const MacKeychain& keychain);
27 ~KeychainSearch(); 26 ~KeychainSearch();
28 27
29 // Sets up a keycahin search based on an non "null" (NULL for char*, 28 // Sets up a keycahin search based on an non "null" (NULL for char*,
30 // The appropriate "Any" entry for other types) arguments. 29 // The appropriate "Any" entry for other types) arguments.
31 // 30 //
(...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after
431 database_blacklist_forms.begin(), 430 database_blacklist_forms.begin(),
432 database_blacklist_forms.end()); 431 database_blacklist_forms.end());
433 432
434 // Clear out all the Keychain entries we used. 433 // Clear out all the Keychain entries we used.
435 DeleteVectorElementsInSet(keychain_forms, used_keychain_forms); 434 DeleteVectorElementsInSet(keychain_forms, used_keychain_forms);
436 } 435 }
437 436
438 std::vector<PasswordForm*> GetPasswordsForForms( 437 std::vector<PasswordForm*> GetPasswordsForForms(
439 const MacKeychain& keychain, std::vector<PasswordForm*>* database_forms) { 438 const MacKeychain& keychain, std::vector<PasswordForm*>* database_forms) {
440 MacKeychainPasswordFormAdapter keychain_adapter(&keychain); 439 MacKeychainPasswordFormAdapter keychain_adapter(&keychain);
441 440
442 std::vector<PasswordForm*> merged_forms; 441 std::vector<PasswordForm*> merged_forms;
443 for (std::vector<PasswordForm*>::iterator i = database_forms->begin(); 442 for (std::vector<PasswordForm*>::iterator i = database_forms->begin();
444 i != database_forms->end();) { 443 i != database_forms->end();) {
445 std::vector<PasswordForm*> db_form_container(1, *i); 444 std::vector<PasswordForm*> db_form_container(1, *i);
446 std::vector<PasswordForm*> keychain_matches = 445 std::vector<PasswordForm*> keychain_matches =
447 keychain_adapter.PasswordsMergeableWithForm(**i); 446 keychain_adapter.PasswordsMergeableWithForm(**i);
448 MergePasswordForms(&keychain_matches, &db_form_container, &merged_forms); 447 MergePasswordForms(&keychain_matches, &db_form_container, &merged_forms);
449 if (db_form_container.size() == 0) { 448 if (db_form_container.size() == 0) {
450 i = database_forms->erase(i); 449 i = database_forms->erase(i);
451 } else { 450 } else {
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
500 return NULL; 499 return NULL;
501 } 500 }
502 501
503 std::vector<PasswordForm*> 502 std::vector<PasswordForm*>
504 MacKeychainPasswordFormAdapter::GetAllPasswordFormPasswords() { 503 MacKeychainPasswordFormAdapter::GetAllPasswordFormPasswords() {
505 SecAuthenticationType supported_auth_types[] = { 504 SecAuthenticationType supported_auth_types[] = {
506 kSecAuthenticationTypeHTMLForm, 505 kSecAuthenticationTypeHTMLForm,
507 kSecAuthenticationTypeHTTPBasic, 506 kSecAuthenticationTypeHTTPBasic,
508 kSecAuthenticationTypeHTTPDigest, 507 kSecAuthenticationTypeHTTPDigest,
509 }; 508 };
510 OSType creator = finds_only_owned_ ? kChromeKeychainCreatorCode : 0;
511 509
512 std::vector<SecKeychainItemRef> matches; 510 std::vector<SecKeychainItemRef> matches;
513 for (unsigned int i = 0; i < arraysize(supported_auth_types); ++i) { 511 for (unsigned int i = 0; i < arraysize(supported_auth_types); ++i) {
514 KeychainSearch keychain_search(*keychain_); 512 KeychainSearch keychain_search(*keychain_);
515 keychain_search.Init(NULL, 0, kSecProtocolTypeAny, supported_auth_types[i], 513 keychain_search.Init(NULL, 0, kSecProtocolTypeAny, supported_auth_types[i],
516 NULL, NULL, NULL, creator); 514 NULL, NULL, NULL, CreatorCodeForSearch());
517 keychain_search.FindMatchingItems(&matches); 515 keychain_search.FindMatchingItems(&matches);
518 } 516 }
519 517
520 return ConvertKeychainItemsToForms(&matches); 518 return ConvertKeychainItemsToForms(&matches);
521 } 519 }
522 520
523 bool MacKeychainPasswordFormAdapter::AddPassword(const PasswordForm& form) { 521 bool MacKeychainPasswordFormAdapter::AddPassword(const PasswordForm& form) {
524 // We should never be trying to store a blacklist in the keychain. 522 // We should never be trying to store a blacklist in the keychain.
525 DCHECK(!form.blacklisted_by_user); 523 DCHECK(!form.blacklisted_by_user);
526 524
(...skipping 13 matching lines...) Expand all
540 SecKeychainItemRef new_item = NULL; 538 SecKeychainItemRef new_item = NULL;
541 OSStatus result = keychain_->AddInternetPassword( 539 OSStatus result = keychain_->AddInternetPassword(
542 NULL, server.size(), server.c_str(), 540 NULL, server.size(), server.c_str(),
543 security_domain.size(), security_domain.c_str(), 541 security_domain.size(), security_domain.c_str(),
544 username.size(), username.c_str(), 542 username.size(), username.c_str(),
545 path.size(), path.c_str(), 543 path.size(), path.c_str(),
546 port, protocol, AuthTypeForScheme(form.scheme), 544 port, protocol, AuthTypeForScheme(form.scheme),
547 password.size(), password.c_str(), &new_item); 545 password.size(), password.c_str(), &new_item);
548 546
549 if (result == noErr) { 547 if (result == noErr) {
550 SetKeychainItemCreatorCode(new_item, kChromeKeychainCreatorCode); 548 SetKeychainItemCreatorCode(new_item, mac_util::CreatorCodeForApplication());
551 keychain_->Free(new_item); 549 keychain_->Free(new_item);
552 } else if (result == errSecDuplicateItem) { 550 } else if (result == errSecDuplicateItem) {
553 // If we collide with an existing item, find and update it instead. 551 // If we collide with an existing item, find and update it instead.
554 SecKeychainItemRef existing_item = KeychainItemForForm(form); 552 SecKeychainItemRef existing_item = KeychainItemForForm(form);
555 if (!existing_item) { 553 if (!existing_item) {
556 return false; 554 return false;
557 } 555 }
558 bool changed = SetKeychainItemPassword(existing_item, password); 556 bool changed = SetKeychainItemPassword(existing_item, password);
559 keychain_->Free(existing_item); 557 keychain_->Free(existing_item);
560 return changed; 558 return changed;
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
634 // TODO(stuartmorgan): Proxies will currently fail here, since their 632 // TODO(stuartmorgan): Proxies will currently fail here, since their
635 // signon_realm is not a URL. We need to detect the proxy case and handle 633 // signon_realm is not a URL. We need to detect the proxy case and handle
636 // it specially. 634 // it specially.
637 return matches; 635 return matches;
638 } 636 }
639 SecProtocolType protocol = is_secure ? kSecProtocolTypeHTTPS 637 SecProtocolType protocol = is_secure ? kSecProtocolTypeHTTPS
640 : kSecProtocolTypeHTTP; 638 : kSecProtocolTypeHTTP;
641 SecAuthenticationType auth_type = AuthTypeForScheme(scheme); 639 SecAuthenticationType auth_type = AuthTypeForScheme(scheme);
642 const char* auth_domain = (scheme == PasswordForm::SCHEME_HTML) ? 640 const char* auth_domain = (scheme == PasswordForm::SCHEME_HTML) ?
643 NULL : security_domain.c_str(); 641 NULL : security_domain.c_str();
644 OSType creator = finds_only_owned_ ? kChromeKeychainCreatorCode : 0;
645
646 KeychainSearch keychain_search(*keychain_); 642 KeychainSearch keychain_search(*keychain_);
647 keychain_search.Init(server.c_str(), port, protocol, auth_type, 643 keychain_search.Init(server.c_str(), port, protocol, auth_type,
648 auth_domain, path, username, creator); 644 auth_domain, path, username, CreatorCodeForSearch());
649 keychain_search.FindMatchingItems(&matches); 645 keychain_search.FindMatchingItems(&matches);
650 return matches; 646 return matches;
651 } 647 }
652 648
653 // TODO(stuartmorgan): signon_realm for proxies is not yet supported. 649 // TODO(stuartmorgan): signon_realm for proxies is not yet supported.
654 bool MacKeychainPasswordFormAdapter::ExtractSignonRealmComponents( 650 bool MacKeychainPasswordFormAdapter::ExtractSignonRealmComponents(
655 const std::string& signon_realm, std::string* server, int* port, 651 const std::string& signon_realm, std::string* server, int* port,
656 bool* is_secure, std::string* security_domain) { 652 bool* is_secure, std::string* security_domain) {
657 // The signon_realm will be the Origin portion of a URL for an HTML form, 653 // The signon_realm will be the Origin portion of a URL for an HTML form,
658 // and the same but with the security domain as a path for HTTP auth. 654 // and the same but with the security domain as a path for HTTP auth.
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
698 bool MacKeychainPasswordFormAdapter::SetKeychainItemCreatorCode( 694 bool MacKeychainPasswordFormAdapter::SetKeychainItemCreatorCode(
699 const SecKeychainItemRef& keychain_item, OSType creator_code) { 695 const SecKeychainItemRef& keychain_item, OSType creator_code) {
700 SecKeychainAttribute attr = { kSecCreatorItemAttr, sizeof(creator_code), 696 SecKeychainAttribute attr = { kSecCreatorItemAttr, sizeof(creator_code),
701 &creator_code }; 697 &creator_code };
702 SecKeychainAttributeList attrList = { 1, &attr }; 698 SecKeychainAttributeList attrList = { 1, &attr };
703 OSStatus result = keychain_->ItemModifyAttributesAndData(keychain_item, 699 OSStatus result = keychain_->ItemModifyAttributesAndData(keychain_item,
704 &attrList, 0, NULL); 700 &attrList, 0, NULL);
705 return result == noErr; 701 return result == noErr;
706 } 702 }
707 703
704 OSType MacKeychainPasswordFormAdapter::CreatorCodeForSearch() {
705 return finds_only_owned_ ? mac_util::CreatorCodeForApplication() : 0;
706 }
707
708 #pragma mark - 708 #pragma mark -
709 709
710 PasswordStoreMac::PasswordStoreMac(MacKeychain* keychain, 710 PasswordStoreMac::PasswordStoreMac(MacKeychain* keychain,
711 LoginDatabaseMac* login_db) 711 LoginDatabaseMac* login_db)
712 : keychain_(keychain), login_metadata_db_(login_db) { 712 : keychain_(keychain), login_metadata_db_(login_db) {
713 DCHECK(keychain_.get()); 713 DCHECK(keychain_.get());
714 DCHECK(login_metadata_db_.get()); 714 DCHECK(login_metadata_db_.get());
715 } 715 }
716 716
717 PasswordStoreMac::~PasswordStoreMac() {} 717 PasswordStoreMac::~PasswordStoreMac() {}
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
806 806
807 void PasswordStoreMac::GetBlacklistLoginsImpl(GetLoginsRequest* request) { 807 void PasswordStoreMac::GetBlacklistLoginsImpl(GetLoginsRequest* request) {
808 std::vector<PasswordForm*> database_forms; 808 std::vector<PasswordForm*> database_forms;
809 login_metadata_db_->GetBlacklistLogins(&database_forms); 809 login_metadata_db_->GetBlacklistLogins(&database_forms);
810 NotifyConsumer(request, database_forms); 810 NotifyConsumer(request, database_forms);
811 } 811 }
812 812
813 void PasswordStoreMac::GetAutofillableLoginsImpl(GetLoginsRequest* request) { 813 void PasswordStoreMac::GetAutofillableLoginsImpl(GetLoginsRequest* request) {
814 std::vector<PasswordForm*> database_forms; 814 std::vector<PasswordForm*> database_forms;
815 login_metadata_db_->GetAutofillableLogins(&database_forms); 815 login_metadata_db_->GetAutofillableLogins(&database_forms);
816 816
817 std::vector<PasswordForm*> merged_forms = 817 std::vector<PasswordForm*> merged_forms =
818 internal_keychain_helpers::GetPasswordsForForms(*keychain_, 818 internal_keychain_helpers::GetPasswordsForForms(*keychain_,
819 &database_forms); 819 &database_forms);
820 820
821 // Clean up any orphaned database entries. 821 // Clean up any orphaned database entries.
822 RemoveDatabaseForms(database_forms); 822 RemoveDatabaseForms(database_forms);
823 STLDeleteElements(&database_forms); 823 STLDeleteElements(&database_forms);
824 824
825 NotifyConsumer(request, merged_forms); 825 NotifyConsumer(request, merged_forms);
826 } 826 }
827 827
828 bool PasswordStoreMac::AddToKeychainIfNecessary(const PasswordForm& form) { 828 bool PasswordStoreMac::AddToKeychainIfNecessary(const PasswordForm& form) {
829 if (form.blacklisted_by_user) { 829 if (form.blacklisted_by_user) {
830 return true; 830 return true;
831 } 831 }
832 MacKeychainPasswordFormAdapter keychainAdapter(keychain_.get()); 832 MacKeychainPasswordFormAdapter keychainAdapter(keychain_.get());
833 return keychainAdapter.AddPassword(form); 833 return keychainAdapter.AddPassword(form);
834 } 834 }
(...skipping 11 matching lines...) Expand all
846 break; 846 break;
847 } 847 }
848 } 848 }
849 STLDeleteElements(&database_forms); 849 STLDeleteElements(&database_forms);
850 return has_match; 850 return has_match;
851 } 851 }
852 852
853 std::vector<PasswordForm*> PasswordStoreMac::GetUnusedKeychainForms() { 853 std::vector<PasswordForm*> PasswordStoreMac::GetUnusedKeychainForms() {
854 std::vector<PasswordForm*> database_forms; 854 std::vector<PasswordForm*> database_forms;
855 login_metadata_db_->GetAutofillableLogins(&database_forms); 855 login_metadata_db_->GetAutofillableLogins(&database_forms);
856 856
857 MacKeychainPasswordFormAdapter owned_keychain_adapter(keychain_.get()); 857 MacKeychainPasswordFormAdapter owned_keychain_adapter(keychain_.get());
858 owned_keychain_adapter.SetFindsOnlyOwnedItems(true); 858 owned_keychain_adapter.SetFindsOnlyOwnedItems(true);
859 std::vector<PasswordForm*> owned_keychain_forms = 859 std::vector<PasswordForm*> owned_keychain_forms =
860 owned_keychain_adapter.GetAllPasswordFormPasswords(); 860 owned_keychain_adapter.GetAllPasswordFormPasswords();
861 861
862 // Run a merge; anything left in owned_keychain_forms when we are done no 862 // Run a merge; anything left in owned_keychain_forms when we are done no
863 // longer has a matching database entry. 863 // longer has a matching database entry.
864 std::vector<PasswordForm*> merged_forms; 864 std::vector<PasswordForm*> merged_forms;
865 internal_keychain_helpers::MergePasswordForms(&owned_keychain_forms, 865 internal_keychain_helpers::MergePasswordForms(&owned_keychain_forms,
866 &database_forms, 866 &database_forms,
867 &merged_forms); 867 &merged_forms);
868 STLDeleteElements(&merged_forms); 868 STLDeleteElements(&merged_forms);
869 STLDeleteElements(&database_forms); 869 STLDeleteElements(&database_forms);
870 870
871 return owned_keychain_forms; 871 return owned_keychain_forms;
872 } 872 }
873 873
874 void PasswordStoreMac::RemoveDatabaseForms( 874 void PasswordStoreMac::RemoveDatabaseForms(
875 const std::vector<PasswordForm*>& forms) { 875 const std::vector<PasswordForm*>& forms) {
876 for (std::vector<PasswordForm*>::const_iterator i = forms.begin(); 876 for (std::vector<PasswordForm*>::const_iterator i = forms.begin();
877 i != forms.end(); ++i) { 877 i != forms.end(); ++i) {
878 login_metadata_db_->RemoveLogin(**i); 878 login_metadata_db_->RemoveLogin(**i);
879 } 879 }
880 } 880 }
881 881
882 void PasswordStoreMac::RemoveKeychainForms( 882 void PasswordStoreMac::RemoveKeychainForms(
883 const std::vector<PasswordForm*>& forms) { 883 const std::vector<PasswordForm*>& forms) {
884 MacKeychainPasswordFormAdapter owned_keychain_adapter(keychain_.get()); 884 MacKeychainPasswordFormAdapter owned_keychain_adapter(keychain_.get());
885 owned_keychain_adapter.SetFindsOnlyOwnedItems(true); 885 owned_keychain_adapter.SetFindsOnlyOwnedItems(true);
886 for (std::vector<PasswordForm*>::const_iterator i = forms.begin(); 886 for (std::vector<PasswordForm*>::const_iterator i = forms.begin();
887 i != forms.end(); ++i) { 887 i != forms.end(); ++i) {
888 owned_keychain_adapter.RemovePassword(**i); 888 owned_keychain_adapter.RemovePassword(**i);
889 } 889 }
890 } 890 }
OLDNEW
« no previous file with comments | « chrome/browser/importer/importer.cc ('k') | chrome/browser/password_manager/password_store_mac_internal.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698