| 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/mac/keychain_reauthorize.h" | 5 #include "chrome/browser/mac/keychain_reauthorize.h" |
| 6 | 6 |
| 7 #import <Foundation/Foundation.h> | 7 #import <Foundation/Foundation.h> |
| 8 #include <Security/Security.h> | 8 #include <Security/Security.h> |
| 9 | 9 |
| 10 #include <algorithm> | 10 #include <algorithm> |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 111 } // namespace | 111 } // namespace |
| 112 | 112 |
| 113 void KeychainReauthorize() { | 113 void KeychainReauthorize() { |
| 114 ScopedSecKeychainSetUserInteractionAllowed user_interaction_allowed(FALSE); | 114 ScopedSecKeychainSetUserInteractionAllowed user_interaction_allowed(FALSE); |
| 115 | 115 |
| 116 // Apple's documentation (Keychain Services Reference, Constants/Mac OS X | 116 // Apple's documentation (Keychain Services Reference, Constants/Mac OS X |
| 117 // Keychain Services API Constants/Keychain Item Class Constants) says to | 117 // Keychain Services API Constants/Keychain Item Class Constants) says to |
| 118 // use CSSM_DL_DB_RECORD_ALL_KEYS, but that doesn't work. | 118 // use CSSM_DL_DB_RECORD_ALL_KEYS, but that doesn't work. |
| 119 // CSSM_DL_DB_RECORD_ANY (as used by SecurityTool's keychain-dump) does | 119 // CSSM_DL_DB_RECORD_ANY (as used by SecurityTool's keychain-dump) does |
| 120 // work. | 120 // work. |
| 121 base::mac::ScopedCFTypeRef<SecKeychainSearchRef> search( | 121 base::ScopedCFTypeRef<SecKeychainSearchRef> search( |
| 122 CrSKeychainSearchCreateFromAttributes(NULL, | 122 CrSKeychainSearchCreateFromAttributes(NULL, CSSM_DL_DB_RECORD_ANY, NULL)); |
| 123 CSSM_DL_DB_RECORD_ANY, | |
| 124 NULL)); | |
| 125 | 123 |
| 126 base::mac::ScopedCFTypeRef<SecTrustedApplicationRef> this_application( | 124 base::ScopedCFTypeRef<SecTrustedApplicationRef> this_application( |
| 127 CrSTrustedApplicationCreateFromPath(NULL)); | 125 CrSTrustedApplicationCreateFromPath(NULL)); |
| 128 | 126 |
| 129 std::vector<std::string> requirement_matches = | 127 std::vector<std::string> requirement_matches = |
| 130 GetRequirementMatches(this_application); | 128 GetRequirementMatches(this_application); |
| 131 | 129 |
| 132 std::vector<CrSKeychainItemAndAccess> items_and_reauthorized_accesses = | 130 std::vector<CrSKeychainItemAndAccess> items_and_reauthorized_accesses = |
| 133 KCSearchToKCItemsAndReauthorizedAccesses(search, | 131 KCSearchToKCItemsAndReauthorizedAccesses(search, |
| 134 requirement_matches, | 132 requirement_matches, |
| 135 this_application); | 133 this_application); |
| 136 | 134 |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 171 UMA_HISTOGRAM_COUNTS("OSX.KeychainReauthorizeIfNeededAtUpdateSuccess", | 169 UMA_HISTOGRAM_COUNTS("OSX.KeychainReauthorizeIfNeededAtUpdateSuccess", |
| 172 pref_value); | 170 pref_value); |
| 173 } | 171 } |
| 174 } | 172 } |
| 175 } | 173 } |
| 176 | 174 |
| 177 namespace { | 175 namespace { |
| 178 | 176 |
| 179 std::string RequirementStringForApplication( | 177 std::string RequirementStringForApplication( |
| 180 SecTrustedApplicationRef application) { | 178 SecTrustedApplicationRef application) { |
| 181 base::mac::ScopedCFTypeRef<SecRequirementRef> requirement( | 179 base::ScopedCFTypeRef<SecRequirementRef> requirement( |
| 182 CrSTrustedApplicationCopyRequirement(application)); | 180 CrSTrustedApplicationCopyRequirement(application)); |
| 183 base::mac::ScopedCFTypeRef<CFStringRef> requirement_string_cf( | 181 base::ScopedCFTypeRef<CFStringRef> requirement_string_cf( |
| 184 CrSRequirementCopyString(requirement, kSecCSDefaultFlags)); | 182 CrSRequirementCopyString(requirement, kSecCSDefaultFlags)); |
| 185 if (!requirement_string_cf) { | 183 if (!requirement_string_cf) { |
| 186 return std::string(); | 184 return std::string(); |
| 187 } | 185 } |
| 188 | 186 |
| 189 std::string requirement_string = | 187 std::string requirement_string = |
| 190 base::SysCFStringRefToUTF8(requirement_string_cf); | 188 base::SysCFStringRefToUTF8(requirement_string_cf); |
| 191 | 189 |
| 192 return requirement_string; | 190 return requirement_string; |
| 193 } | 191 } |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 291 | 289 |
| 292 return requirement_matches; | 290 return requirement_matches; |
| 293 } | 291 } |
| 294 | 292 |
| 295 std::vector<CrSKeychainItemAndAccess> KCSearchToKCItemsAndReauthorizedAccesses( | 293 std::vector<CrSKeychainItemAndAccess> KCSearchToKCItemsAndReauthorizedAccesses( |
| 296 SecKeychainSearchRef search, | 294 SecKeychainSearchRef search, |
| 297 const std::vector<std::string>& requirement_matches, | 295 const std::vector<std::string>& requirement_matches, |
| 298 SecTrustedApplicationRef this_application) { | 296 SecTrustedApplicationRef this_application) { |
| 299 std::vector<CrSKeychainItemAndAccess> items_and_accesses; | 297 std::vector<CrSKeychainItemAndAccess> items_and_accesses; |
| 300 | 298 |
| 301 base::mac::ScopedCFTypeRef<SecKeychainItemRef> item; | 299 base::ScopedCFTypeRef<SecKeychainItemRef> item; |
| 302 while (item.reset(CrSKeychainSearchCopyNext(search)), item) { | 300 while (item.reset(CrSKeychainSearchCopyNext(search)), item) { |
| 303 scoped_ptr<CrSKeychainItemAndAccess> item_and_access( | 301 scoped_ptr<CrSKeychainItemAndAccess> item_and_access( |
| 304 KCItemToKCItemAndReauthorizedAccess(item, | 302 KCItemToKCItemAndReauthorizedAccess(item, |
| 305 requirement_matches, | 303 requirement_matches, |
| 306 this_application)); | 304 this_application)); |
| 307 | 305 |
| 308 if (item_and_access.get()) { | 306 if (item_and_access.get()) { |
| 309 items_and_accesses.push_back(*item_and_access); | 307 items_and_accesses.push_back(*item_and_access); |
| 310 } | 308 } |
| 311 } | 309 } |
| 312 | 310 |
| 313 return items_and_accesses; | 311 return items_and_accesses; |
| 314 } | 312 } |
| 315 | 313 |
| 316 CrSKeychainItemAndAccess* KCItemToKCItemAndReauthorizedAccess( | 314 CrSKeychainItemAndAccess* KCItemToKCItemAndReauthorizedAccess( |
| 317 SecKeychainItemRef item, | 315 SecKeychainItemRef item, |
| 318 const std::vector<std::string>& requirement_matches, | 316 const std::vector<std::string>& requirement_matches, |
| 319 SecTrustedApplicationRef this_application) { | 317 SecTrustedApplicationRef this_application) { |
| 320 if (!CrSKeychainItemTestAccess(item)) { | 318 if (!CrSKeychainItemTestAccess(item)) { |
| 321 return NULL; | 319 return NULL; |
| 322 } | 320 } |
| 323 | 321 |
| 324 base::mac::ScopedCFTypeRef<SecAccessRef> access( | 322 base::ScopedCFTypeRef<SecAccessRef> access(CrSKeychainItemCopyAccess(item)); |
| 325 CrSKeychainItemCopyAccess(item)); | 323 base::ScopedCFTypeRef<CFArrayRef> acl_list(CrSAccessCopyACLList(access)); |
| 326 base::mac::ScopedCFTypeRef<CFArrayRef> acl_list( | |
| 327 CrSAccessCopyACLList(access)); | |
| 328 if (!acl_list) { | 324 if (!acl_list) { |
| 329 return NULL; | 325 return NULL; |
| 330 } | 326 } |
| 331 | 327 |
| 332 bool acl_list_modified = ReauthorizeACLList(acl_list, | 328 bool acl_list_modified = ReauthorizeACLList(acl_list, |
| 333 requirement_matches, | 329 requirement_matches, |
| 334 this_application); | 330 this_application); |
| 335 if (!acl_list_modified) { | 331 if (!acl_list_modified) { |
| 336 return NULL; | 332 return NULL; |
| 337 } | 333 } |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 437 items_and_reauthorized_accesses.begin(); | 433 items_and_reauthorized_accesses.begin(); |
| 438 iterator != items_and_reauthorized_accesses.end(); | 434 iterator != items_and_reauthorized_accesses.end(); |
| 439 ++iterator) { | 435 ++iterator) { |
| 440 WriteKCItemAndReauthorizedAccess(*iterator); | 436 WriteKCItemAndReauthorizedAccess(*iterator); |
| 441 } | 437 } |
| 442 } | 438 } |
| 443 | 439 |
| 444 void WriteKCItemAndReauthorizedAccess( | 440 void WriteKCItemAndReauthorizedAccess( |
| 445 const CrSKeychainItemAndAccess& item_and_reauthorized_access) { | 441 const CrSKeychainItemAndAccess& item_and_reauthorized_access) { |
| 446 SecKeychainItemRef old_item = item_and_reauthorized_access.item(); | 442 SecKeychainItemRef old_item = item_and_reauthorized_access.item(); |
| 447 base::mac::ScopedCFTypeRef<SecKeychainRef> keychain( | 443 base::ScopedCFTypeRef<SecKeychainRef> keychain( |
| 448 CrSKeychainItemCopyKeychain(old_item)); | 444 CrSKeychainItemCopyKeychain(old_item)); |
| 449 | 445 |
| 450 ScopedCrSKeychainItemAttributesAndData old_attributes_and_data( | 446 ScopedCrSKeychainItemAttributesAndData old_attributes_and_data( |
| 451 CrSKeychainItemCopyAttributesAndData(keychain, old_item)); | 447 CrSKeychainItemCopyAttributesAndData(keychain, old_item)); |
| 452 if (!old_attributes_and_data.get()) { | 448 if (!old_attributes_and_data.get()) { |
| 453 return; | 449 return; |
| 454 } | 450 } |
| 455 | 451 |
| 456 // CrSKeychainItemCreateFromContent (SecKeychainItemCreateFromContent) | 452 // CrSKeychainItemCreateFromContent (SecKeychainItemCreateFromContent) |
| 457 // returns errKCNoSuchAttr (errSecNoSuchAttr) when asked to add an item of | 453 // returns errKCNoSuchAttr (errSecNoSuchAttr) when asked to add an item of |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 494 *old_attributes_and_data.get(); | 490 *old_attributes_and_data.get(); |
| 495 new_attributes_and_data.attribute_list = &new_attribute_list; | 491 new_attributes_and_data.attribute_list = &new_attribute_list; |
| 496 | 492 |
| 497 // Delete the item last, to give everything else above a chance to bail | 493 // Delete the item last, to give everything else above a chance to bail |
| 498 // out early, and to ensure that the old item is still present while it | 494 // out early, and to ensure that the old item is still present while it |
| 499 // may still be used by the above code. | 495 // may still be used by the above code. |
| 500 if (!CrSKeychainItemDelete(old_item)) { | 496 if (!CrSKeychainItemDelete(old_item)) { |
| 501 return; | 497 return; |
| 502 } | 498 } |
| 503 | 499 |
| 504 base::mac::ScopedCFTypeRef<SecKeychainItemRef> new_item( | 500 base::ScopedCFTypeRef<SecKeychainItemRef> new_item( |
| 505 CrSKeychainItemCreateFromContent(new_attributes_and_data, | 501 CrSKeychainItemCreateFromContent(new_attributes_and_data, |
| 506 keychain, | 502 keychain, |
| 507 item_and_reauthorized_access.access())); | 503 item_and_reauthorized_access.access())); |
| 508 } | 504 } |
| 509 | 505 |
| 510 std::vector<SecKeychainAttribute> KCAttributesWithoutZeroLength( | 506 std::vector<SecKeychainAttribute> KCAttributesWithoutZeroLength( |
| 511 SecKeychainAttributeList* old_attribute_list) { | 507 SecKeychainAttributeList* old_attribute_list) { |
| 512 UInt32 old_attribute_count = old_attribute_list->count; | 508 UInt32 old_attribute_count = old_attribute_list->count; |
| 513 std::vector<SecKeychainAttribute> new_attributes; | 509 std::vector<SecKeychainAttribute> new_attributes; |
| 514 new_attributes.reserve(old_attribute_count); | 510 new_attributes.reserve(old_attribute_count); |
| 515 for (UInt32 old_attribute_index = 0; | 511 for (UInt32 old_attribute_index = 0; |
| 516 old_attribute_index < old_attribute_count; | 512 old_attribute_index < old_attribute_count; |
| 517 ++old_attribute_index) { | 513 ++old_attribute_index) { |
| 518 SecKeychainAttribute* attribute = | 514 SecKeychainAttribute* attribute = |
| 519 &old_attribute_list->attr[old_attribute_index]; | 515 &old_attribute_list->attr[old_attribute_index]; |
| 520 if (attribute->length) { | 516 if (attribute->length) { |
| 521 new_attributes.push_back(*attribute); | 517 new_attributes.push_back(*attribute); |
| 522 } | 518 } |
| 523 } | 519 } |
| 524 | 520 |
| 525 return new_attributes; | 521 return new_attributes; |
| 526 } | 522 } |
| 527 | 523 |
| 528 } // namespace | 524 } // namespace |
| 529 | 525 |
| 530 } // namespace chrome | 526 } // namespace chrome |
| OLD | NEW |