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 #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 <vector> | 12 #include <vector> |
12 | 13 |
13 #include "base/callback.h" | 14 #include "base/callback.h" |
14 #include "base/debug/crash_logging.h" | 15 #include "base/debug/crash_logging.h" |
15 #include "base/debug/stack_trace.h" | 16 #include "base/debug/stack_trace.h" |
16 #include "base/logging.h" | 17 #include "base/logging.h" |
17 #include "base/mac/mac_logging.h" | 18 #include "base/mac/mac_logging.h" |
18 #include "base/mac/mac_util.h" | 19 #include "base/mac/mac_util.h" |
19 #include "base/message_loop/message_loop.h" | 20 #include "base/message_loop/message_loop.h" |
20 #include "base/stl_util.h" | 21 #include "base/stl_util.h" |
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
229 switch (auth_type) { | 230 switch (auth_type) { |
230 case kSecAuthenticationTypeHTMLForm: return PasswordForm::SCHEME_HTML; | 231 case kSecAuthenticationTypeHTMLForm: return PasswordForm::SCHEME_HTML; |
231 case kSecAuthenticationTypeHTTPBasic: return PasswordForm::SCHEME_BASIC; | 232 case kSecAuthenticationTypeHTTPBasic: return PasswordForm::SCHEME_BASIC; |
232 case kSecAuthenticationTypeHTTPDigest: return PasswordForm::SCHEME_DIGEST; | 233 case kSecAuthenticationTypeHTTPDigest: return PasswordForm::SCHEME_DIGEST; |
233 default: return PasswordForm::SCHEME_OTHER; | 234 default: return PasswordForm::SCHEME_OTHER; |
234 } | 235 } |
235 } | 236 } |
236 | 237 |
237 bool FillPasswordFormFromKeychainItem(const AppleKeychain& keychain, | 238 bool FillPasswordFormFromKeychainItem(const AppleKeychain& keychain, |
238 const SecKeychainItemRef& keychain_item, | 239 const SecKeychainItemRef& keychain_item, |
239 PasswordForm* form) { | 240 PasswordForm* form, |
241 bool extract_password_data) { | |
240 DCHECK(form); | 242 DCHECK(form); |
241 | 243 |
242 SecKeychainAttributeInfo attrInfo; | 244 SecKeychainAttributeInfo attrInfo; |
243 UInt32 tags[] = { kSecAccountItemAttr, | 245 UInt32 tags[] = { kSecAccountItemAttr, |
244 kSecServerItemAttr, | 246 kSecServerItemAttr, |
245 kSecPortItemAttr, | 247 kSecPortItemAttr, |
246 kSecPathItemAttr, | 248 kSecPathItemAttr, |
247 kSecProtocolItemAttr, | 249 kSecProtocolItemAttr, |
248 kSecAuthenticationTypeItemAttr, | 250 kSecAuthenticationTypeItemAttr, |
249 kSecSecurityDomainItemAttr, | 251 kSecSecurityDomainItemAttr, |
250 kSecCreationDateItemAttr, | 252 kSecCreationDateItemAttr, |
251 kSecNegativeItemAttr }; | 253 kSecNegativeItemAttr }; |
252 attrInfo.count = arraysize(tags); | 254 attrInfo.count = arraysize(tags); |
253 attrInfo.tag = tags; | 255 attrInfo.tag = tags; |
254 attrInfo.format = NULL; | 256 attrInfo.format = NULL; |
255 | 257 |
256 SecKeychainAttributeList *attrList; | 258 SecKeychainAttributeList *attrList; |
257 UInt32 password_length; | 259 UInt32 password_length; |
258 void* password_data; | 260 |
261 // If |extract_password_data| is false, do not pass in a reference to | |
262 // |password_data|. ItemCopyAttributesAndData will then extract only the | |
263 // attributes of |keychain_item| (doesn't require OS authorization), and not | |
264 // attempt to extract its password data (requires OS authorization). | |
265 void* password_data = NULL; | |
266 void** password_data_ref = extract_password_data ? &password_data : NULL; | |
267 | |
259 OSStatus result = keychain.ItemCopyAttributesAndData(keychain_item, &attrInfo, | 268 OSStatus result = keychain.ItemCopyAttributesAndData(keychain_item, &attrInfo, |
260 NULL, &attrList, | 269 NULL, &attrList, |
261 &password_length, | 270 &password_length, |
262 &password_data); | 271 password_data_ref); |
263 | 272 |
264 if (result != noErr) { | 273 if (result != noErr) { |
265 // We don't log errSecAuthFailed because that just means that the user | 274 // We don't log errSecAuthFailed because that just means that the user |
266 // chose not to allow us access to the item. | 275 // chose not to allow us access to the item. |
267 if (result != errSecAuthFailed) { | 276 if (result != errSecAuthFailed) { |
268 OSSTATUS_LOG(ERROR, result) << "Keychain data load failed"; | 277 OSSTATUS_LOG(ERROR, result) << "Keychain data load failed"; |
269 } | 278 } |
270 return false; | 279 return false; |
271 } | 280 } |
272 | 281 |
273 UTF8ToUTF16(static_cast<const char *>(password_data), password_length, | 282 if (extract_password_data) { |
274 &(form->password_value)); | 283 UTF8ToUTF16(static_cast<const char *>(password_data), password_length, |
284 &(form->password_value)); | |
285 } | |
275 | 286 |
276 int port = kAnyPort; | 287 int port = kAnyPort; |
277 std::string server; | 288 std::string server; |
278 std::string security_domain; | 289 std::string security_domain; |
279 std::string path; | 290 std::string path; |
280 for (unsigned int i = 0; i < attrList->count; i++) { | 291 for (unsigned int i = 0; i < attrList->count; i++) { |
281 SecKeychainAttribute attr = attrList->attr[i]; | 292 SecKeychainAttribute attr = attrList->attr[i]; |
282 if (!attr.data) { | 293 if (!attr.data) { |
283 continue; | 294 continue; |
284 } | 295 } |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
326 form->blacklisted_by_user = true; | 337 form->blacklisted_by_user = true; |
327 } | 338 } |
328 break; | 339 break; |
329 } | 340 } |
330 } | 341 } |
331 keychain.ItemFreeAttributesAndData(attrList, password_data); | 342 keychain.ItemFreeAttributesAndData(attrList, password_data); |
332 | 343 |
333 // kSecNegativeItemAttr doesn't seem to actually be in widespread use. In | 344 // kSecNegativeItemAttr doesn't seem to actually be in widespread use. In |
334 // practice, other browsers seem to use a "" or " " password (and a special | 345 // practice, other browsers seem to use a "" or " " password (and a special |
335 // user name) to indicated blacklist entries. | 346 // user name) to indicated blacklist entries. |
336 if (form->password_value.empty() || EqualsASCII(form->password_value, " ")) { | 347 if (extract_password_data && (form->password_value.empty() || |
348 EqualsASCII(form->password_value, " "))) { | |
337 form->blacklisted_by_user = true; | 349 form->blacklisted_by_user = true; |
338 } | 350 } |
339 | 351 |
340 form->origin = URLFromComponents(form->ssl_valid, server, port, path); | 352 form->origin = URLFromComponents(form->ssl_valid, server, port, path); |
341 // TODO(stuartmorgan): Handle proxies, which need a different signon_realm | 353 // TODO(stuartmorgan): Handle proxies, which need a different signon_realm |
342 // format. | 354 // format. |
343 form->signon_realm = form->origin.GetOrigin().spec(); | 355 form->signon_realm = form->origin.GetOrigin().spec(); |
344 if (form->scheme != PasswordForm::SCHEME_HTML) { | 356 if (form->scheme != PasswordForm::SCHEME_HTML) { |
345 form->signon_realm.append(security_domain); | 357 form->signon_realm.append(security_domain); |
346 } | 358 } |
347 return true; | 359 return true; |
348 } | 360 } |
349 | 361 |
350 bool FormsMatchForMerge(const PasswordForm& form_a, | 362 bool FormsMatchForMerge(const PasswordForm& form_a, |
351 const PasswordForm& form_b) { | 363 const PasswordForm& form_b) { |
352 // We never merge blacklist entries between our store and the keychain. | 364 // We never merge blacklist entries between our store and the keychain. |
353 if (form_a.blacklisted_by_user || form_b.blacklisted_by_user) { | 365 if (form_a.blacklisted_by_user || form_b.blacklisted_by_user) { |
stuartmorgan
2013/09/30 22:39:12
As far as I can tell, you are pulling a bunch of p
Raghu Simha
2013/10/02 02:09:50
There is a filtering step for blacklisted password
| |
354 return false; | 366 return false; |
355 } | 367 } |
356 return form_a.scheme == form_b.scheme && | 368 return form_a.scheme == form_b.scheme && |
357 form_a.signon_realm == form_b.signon_realm && | 369 form_a.signon_realm == form_b.signon_realm && |
358 form_a.username_value == form_b.username_value; | 370 form_a.username_value == form_b.username_value; |
359 } | 371 } |
360 | 372 |
361 // Returns an the best match for |form| from |keychain_forms|, or NULL if there | 373 // Returns an the best match for |form| from |keychain_forms|, or NULL if there |
362 // is no suitable match. | 374 // is no suitable match. |
363 PasswordForm* BestKeychainFormForForm( | 375 PasswordForm* BestKeychainFormForForm( |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
439 | 451 |
440 // Add in the blacklist entries from the database. | 452 // Add in the blacklist entries from the database. |
441 merged_forms->insert(merged_forms->end(), | 453 merged_forms->insert(merged_forms->end(), |
442 database_blacklist_forms.begin(), | 454 database_blacklist_forms.begin(), |
443 database_blacklist_forms.end()); | 455 database_blacklist_forms.end()); |
444 | 456 |
445 // Clear out all the Keychain entries we used. | 457 // Clear out all the Keychain entries we used. |
446 DeleteVectorElementsInSet(keychain_forms, used_keychain_forms); | 458 DeleteVectorElementsInSet(keychain_forms, used_keychain_forms); |
447 } | 459 } |
448 | 460 |
461 std::vector<MacKeychainPasswordFormAdapter::ItemFormPair> | |
462 GetAllKeychainItemAttributesAsPasswordForms( | |
463 std::vector<SecKeychainItemRef>* keychain_items, | |
464 const AppleKeychain& keychain) { | |
465 DCHECK(keychain_items); | |
466 MacKeychainPasswordFormAdapter keychain_adapter(&keychain); | |
467 *keychain_items = keychain_adapter.GetAllPasswordFormKeychainItems(); | |
468 std::vector<MacKeychainPasswordFormAdapter::ItemFormPair> item_form_pairs; | |
469 for (std::vector<SecKeychainItemRef>::iterator i = keychain_items->begin(); | |
470 i != keychain_items->end(); ++i) { | |
471 PasswordForm* form_without_password = new PasswordForm(); | |
472 internal_keychain_helpers::FillPasswordFormFromKeychainItem( | |
473 keychain, | |
474 *i, | |
475 form_without_password, | |
476 false); // Load password attributes, but not password data. | |
477 item_form_pairs.push_back(std::make_pair(&(*i), form_without_password)); | |
478 } | |
479 return item_form_pairs; | |
480 } | |
481 | |
449 std::vector<PasswordForm*> GetPasswordsForForms( | 482 std::vector<PasswordForm*> GetPasswordsForForms( |
450 const AppleKeychain& keychain, | 483 const AppleKeychain& keychain, |
451 std::vector<PasswordForm*>* database_forms) { | 484 std::vector<PasswordForm*>* database_forms) { |
485 // First load the attributes of all items in the keychain without loading | |
486 // their password data, and then match items in |database_forms| against them. | |
487 // This avoids individually searching through the keychain for passwords | |
488 // matching each form in |database_forms|, and results in a significant | |
489 // performance gain, replacing O(N) keychain search operations with a single | |
490 // operation that loads all keychain items, and then selective reads of only | |
491 // the relevant passwords. See crbug.com/263685. | |
492 std::vector<SecKeychainItemRef> keychain_items; | |
493 std::vector<MacKeychainPasswordFormAdapter::ItemFormPair> item_form_pairs = | |
494 GetAllKeychainItemAttributesAsPasswordForms(&keychain_items, keychain); | |
495 | |
496 // Next, compare the attributes of the PasswordForms in |database_forms| | |
497 // against those in |item_form_pairs|, and extract password data for each | |
498 // matching PasswordForm using its corresponding SecKeychainItemRef. | |
452 MacKeychainPasswordFormAdapter keychain_adapter(&keychain); | 499 MacKeychainPasswordFormAdapter keychain_adapter(&keychain); |
453 | |
454 std::vector<PasswordForm*> merged_forms; | 500 std::vector<PasswordForm*> merged_forms; |
455 for (std::vector<PasswordForm*>::iterator i = database_forms->begin(); | 501 for (std::vector<PasswordForm*>::iterator i = database_forms->begin(); |
456 i != database_forms->end();) { | 502 i != database_forms->end();) { |
457 std::vector<PasswordForm*> db_form_container(1, *i); | 503 std::vector<PasswordForm*> db_form_container(1, *i); |
458 std::vector<PasswordForm*> keychain_matches = | 504 std::vector<PasswordForm*> keychain_matches = |
459 keychain_adapter.PasswordsMergeableWithForm(**i); | 505 keychain_adapter.ExtractPasswordsMergeableWithForm(item_form_pairs, |
506 **i); | |
460 MergePasswordForms(&keychain_matches, &db_form_container, &merged_forms); | 507 MergePasswordForms(&keychain_matches, &db_form_container, &merged_forms); |
461 if (db_form_container.empty()) { | 508 if (db_form_container.empty()) { |
462 i = database_forms->erase(i); | 509 i = database_forms->erase(i); |
463 } else { | 510 } else { |
464 ++i; | 511 ++i; |
465 } | 512 } |
466 STLDeleteElements(&keychain_matches); | 513 STLDeleteElements(&keychain_matches); |
467 } | 514 } |
515 | |
516 // Clean up temporary PasswordForms and SecKeychainItemRefs. | |
517 STLDeleteContainerPairSecondPointers(item_form_pairs.begin(), | |
518 item_form_pairs.end()); | |
519 for (std::vector<SecKeychainItemRef>::iterator i = keychain_items.begin(); | |
520 i != keychain_items.end(); ++i) { | |
521 keychain.Free(*i); | |
522 } | |
468 return merged_forms; | 523 return merged_forms; |
469 } | 524 } |
470 | 525 |
471 class Thread : public base::Thread { | 526 class Thread : public base::Thread { |
472 public: | 527 public: |
473 Thread(const char* name) : base::Thread(name) {} | 528 Thread(const char* name) : base::Thread(name) {} |
474 virtual ~Thread() { | 529 virtual ~Thread() { |
475 base::debug::SetCrashKeyToStackTrace( | 530 base::debug::SetCrashKeyToStackTrace( |
476 crash_keys::mac::kPasswordThreadDtorTrace, base::debug::StackTrace()); | 531 crash_keys::mac::kPasswordThreadDtorTrace, base::debug::StackTrace()); |
477 } | 532 } |
(...skipping 11 matching lines...) Expand all Loading... | |
489 std::vector<PasswordForm*> | 544 std::vector<PasswordForm*> |
490 MacKeychainPasswordFormAdapter::PasswordsFillingForm( | 545 MacKeychainPasswordFormAdapter::PasswordsFillingForm( |
491 const PasswordForm& query_form) { | 546 const PasswordForm& query_form) { |
492 std::vector<SecKeychainItemRef> keychain_items = | 547 std::vector<SecKeychainItemRef> keychain_items = |
493 MatchingKeychainItems(query_form.signon_realm, query_form.scheme, | 548 MatchingKeychainItems(query_form.signon_realm, query_form.scheme, |
494 NULL, NULL); | 549 NULL, NULL); |
495 | 550 |
496 return ConvertKeychainItemsToForms(&keychain_items); | 551 return ConvertKeychainItemsToForms(&keychain_items); |
497 } | 552 } |
498 | 553 |
554 bool MacKeychainPasswordFormAdapter::FormIsValidAndMatchesOtherForm( | |
555 const PasswordForm& query_form, | |
556 const PasswordForm& other_form) { | |
557 std::string server; | |
558 std::string security_domain; | |
559 int port; | |
560 bool is_secure; | |
561 if (!ExtractSignonRealmComponents(query_form.signon_realm, &server, &port, | |
562 &is_secure, &security_domain)) { | |
563 return false; | |
564 } | |
565 return internal_keychain_helpers::FormsMatchForMerge(query_form, other_form); | |
566 } | |
567 | |
499 std::vector<PasswordForm*> | 568 std::vector<PasswordForm*> |
500 MacKeychainPasswordFormAdapter::PasswordsMergeableWithForm( | 569 MacKeychainPasswordFormAdapter::ExtractPasswordsMergeableWithForm( |
stuartmorgan
2013/09/30 22:39:12
AFAICT this no longer operates on the keychain in
Raghu Simha
2013/10/02 02:09:50
We reference the keychain in line 580, while calli
| |
570 const std::vector<ItemFormPair>& item_form_pairs, | |
501 const PasswordForm& query_form) { | 571 const PasswordForm& query_form) { |
502 std::string username = UTF16ToUTF8(query_form.username_value); | 572 std::vector<PasswordForm*> matches; |
503 std::vector<SecKeychainItemRef> keychain_items = | 573 for (std::vector<ItemFormPair>::const_iterator i = item_form_pairs.begin(); |
504 MatchingKeychainItems(query_form.signon_realm, query_form.scheme, | 574 i != item_form_pairs.end(); ++i) { |
505 NULL, username.c_str()); | 575 if (FormIsValidAndMatchesOtherForm(query_form, *(i->second))) { |
506 | 576 // Create a new object, since the caller is responsible for deleting the |
507 return ConvertKeychainItemsToForms(&keychain_items); | 577 // returned forms. |
stuartmorgan
2013/09/30 22:39:12
Feel free to use ScopedVector anywhere it makes li
Raghu Simha
2013/10/02 02:09:50
I did consider using a ScopedVector here, but ende
| |
578 PasswordForm* form_with_password = new PasswordForm(); | |
579 internal_keychain_helpers::FillPasswordFormFromKeychainItem( | |
580 *keychain_, | |
581 *(i->first), | |
582 form_with_password, | |
583 true); // Load password attributes and data. | |
584 matches.push_back(form_with_password); | |
585 } | |
586 } | |
587 return matches; | |
508 } | 588 } |
509 | 589 |
510 PasswordForm* MacKeychainPasswordFormAdapter::PasswordExactlyMatchingForm( | 590 PasswordForm* MacKeychainPasswordFormAdapter::PasswordExactlyMatchingForm( |
511 const PasswordForm& query_form) { | 591 const PasswordForm& query_form) { |
512 SecKeychainItemRef keychain_item = KeychainItemForForm(query_form); | 592 SecKeychainItemRef keychain_item = KeychainItemForForm(query_form); |
513 if (keychain_item) { | 593 if (keychain_item) { |
514 PasswordForm* form = new PasswordForm(); | 594 PasswordForm* form = new PasswordForm(); |
515 internal_keychain_helpers::FillPasswordFormFromKeychainItem(*keychain_, | 595 internal_keychain_helpers::FillPasswordFormFromKeychainItem(*keychain_, |
516 keychain_item, | 596 keychain_item, |
517 form); | 597 form, |
598 true); | |
518 keychain_->Free(keychain_item); | 599 keychain_->Free(keychain_item); |
519 return form; | 600 return form; |
520 } | 601 } |
521 return NULL; | 602 return NULL; |
522 } | 603 } |
523 | 604 |
524 bool MacKeychainPasswordFormAdapter::HasPasswordsMergeableWithForm( | 605 bool MacKeychainPasswordFormAdapter::HasPasswordsMergeableWithForm( |
525 const PasswordForm& query_form) { | 606 const PasswordForm& query_form) { |
526 std::string username = UTF16ToUTF8(query_form.username_value); | 607 std::string username = UTF16ToUTF8(query_form.username_value); |
527 std::vector<SecKeychainItemRef> matches = | 608 std::vector<SecKeychainItemRef> matches = |
528 MatchingKeychainItems(query_form.signon_realm, query_form.scheme, | 609 MatchingKeychainItems(query_form.signon_realm, query_form.scheme, |
529 NULL, username.c_str()); | 610 NULL, username.c_str()); |
530 for (std::vector<SecKeychainItemRef>::iterator i = matches.begin(); | 611 for (std::vector<SecKeychainItemRef>::iterator i = matches.begin(); |
531 i != matches.end(); ++i) { | 612 i != matches.end(); ++i) { |
532 keychain_->Free(*i); | 613 keychain_->Free(*i); |
533 } | 614 } |
534 | 615 |
535 return !matches.empty(); | 616 return !matches.empty(); |
536 } | 617 } |
537 | 618 |
538 std::vector<PasswordForm*> | 619 std::vector<SecKeychainItemRef> |
539 MacKeychainPasswordFormAdapter::GetAllPasswordFormPasswords() { | 620 MacKeychainPasswordFormAdapter::GetAllPasswordFormKeychainItems() { |
540 SecAuthenticationType supported_auth_types[] = { | 621 SecAuthenticationType supported_auth_types[] = { |
541 kSecAuthenticationTypeHTMLForm, | 622 kSecAuthenticationTypeHTMLForm, |
542 kSecAuthenticationTypeHTTPBasic, | 623 kSecAuthenticationTypeHTTPBasic, |
543 kSecAuthenticationTypeHTTPDigest, | 624 kSecAuthenticationTypeHTTPDigest, |
544 }; | 625 }; |
545 | 626 |
546 std::vector<SecKeychainItemRef> matches; | 627 std::vector<SecKeychainItemRef> matches; |
547 for (unsigned int i = 0; i < arraysize(supported_auth_types); ++i) { | 628 for (unsigned int i = 0; i < arraysize(supported_auth_types); ++i) { |
548 KeychainSearch keychain_search(*keychain_); | 629 KeychainSearch keychain_search(*keychain_); |
549 keychain_search.Init(NULL, 0, kSecProtocolTypeAny, supported_auth_types[i], | 630 keychain_search.Init(NULL, 0, kSecProtocolTypeAny, supported_auth_types[i], |
550 NULL, NULL, NULL, CreatorCodeForSearch()); | 631 NULL, NULL, NULL, CreatorCodeForSearch()); |
551 keychain_search.FindMatchingItems(&matches); | 632 keychain_search.FindMatchingItems(&matches); |
552 } | 633 } |
634 return matches; | |
635 } | |
553 | 636 |
554 return ConvertKeychainItemsToForms(&matches); | 637 std::vector<PasswordForm*> |
638 MacKeychainPasswordFormAdapter::GetAllPasswordFormPasswords() { | |
639 std::vector<SecKeychainItemRef> items = GetAllPasswordFormKeychainItems(); | |
640 return ConvertKeychainItemsToForms(&items); | |
555 } | 641 } |
556 | 642 |
557 bool MacKeychainPasswordFormAdapter::AddPassword(const PasswordForm& form) { | 643 bool MacKeychainPasswordFormAdapter::AddPassword(const PasswordForm& form) { |
558 // We should never be trying to store a blacklist in the keychain. | 644 // We should never be trying to store a blacklist in the keychain. |
559 DCHECK(!form.blacklisted_by_user); | 645 DCHECK(!form.blacklisted_by_user); |
560 | 646 |
561 std::string server; | 647 std::string server; |
562 std::string security_domain; | 648 std::string security_domain; |
563 int port; | 649 int port; |
564 bool is_secure; | 650 bool is_secure; |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
612 finds_only_owned_ = finds_only_owned; | 698 finds_only_owned_ = finds_only_owned; |
613 } | 699 } |
614 | 700 |
615 std::vector<PasswordForm*> | 701 std::vector<PasswordForm*> |
616 MacKeychainPasswordFormAdapter::ConvertKeychainItemsToForms( | 702 MacKeychainPasswordFormAdapter::ConvertKeychainItemsToForms( |
617 std::vector<SecKeychainItemRef>* items) { | 703 std::vector<SecKeychainItemRef>* items) { |
618 std::vector<PasswordForm*> keychain_forms; | 704 std::vector<PasswordForm*> keychain_forms; |
619 for (std::vector<SecKeychainItemRef>::const_iterator i = items->begin(); | 705 for (std::vector<SecKeychainItemRef>::const_iterator i = items->begin(); |
620 i != items->end(); ++i) { | 706 i != items->end(); ++i) { |
621 PasswordForm* form = new PasswordForm(); | 707 PasswordForm* form = new PasswordForm(); |
622 if (internal_keychain_helpers::FillPasswordFormFromKeychainItem(*keychain_, | 708 if (internal_keychain_helpers::FillPasswordFormFromKeychainItem( |
623 *i, form)) { | 709 *keychain_, *i, form, true)) { |
624 keychain_forms.push_back(form); | 710 keychain_forms.push_back(form); |
625 } | 711 } |
626 keychain_->Free(*i); | 712 keychain_->Free(*i); |
627 } | 713 } |
628 items->clear(); | 714 items->clear(); |
629 return keychain_forms; | 715 return keychain_forms; |
630 } | 716 } |
631 | 717 |
632 SecKeychainItemRef MacKeychainPasswordFormAdapter::KeychainItemForForm( | 718 SecKeychainItemRef MacKeychainPasswordFormAdapter::KeychainItemForForm( |
633 const PasswordForm& form) { | 719 const PasswordForm& form) { |
(...skipping 397 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1031 owned_keychain_adapter.SetFindsOnlyOwnedItems(true); | 1117 owned_keychain_adapter.SetFindsOnlyOwnedItems(true); |
1032 for (std::vector<PasswordForm*>::const_iterator i = forms.begin(); | 1118 for (std::vector<PasswordForm*>::const_iterator i = forms.begin(); |
1033 i != forms.end(); ++i) { | 1119 i != forms.end(); ++i) { |
1034 owned_keychain_adapter.RemovePassword(**i); | 1120 owned_keychain_adapter.RemovePassword(**i); |
1035 } | 1121 } |
1036 } | 1122 } |
1037 | 1123 |
1038 void PasswordStoreMac::CreateNotificationService() { | 1124 void PasswordStoreMac::CreateNotificationService() { |
1039 notification_service_.reset(content::NotificationService::Create()); | 1125 notification_service_.reset(content::NotificationService::Create()); |
1040 } | 1126 } |
OLD | NEW |