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/native_backend_kwallet_x.h" | 5 #include "chrome/browser/password_manager/native_backend_kwallet_x.h" |
6 | 6 |
7 #include <vector> | 7 #include <vector> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
349 kept_forms.push_back(all_forms[i]); | 349 kept_forms.push_back(all_forms[i]); |
350 } | 350 } |
351 | 351 |
352 // Update the entry in the wallet, possibly deleting it. | 352 // Update the entry in the wallet, possibly deleting it. |
353 bool ok = SetLoginsList(kept_forms, form.signon_realm, wallet_handle); | 353 bool ok = SetLoginsList(kept_forms, form.signon_realm, wallet_handle); |
354 | 354 |
355 STLDeleteElements(&kept_forms); | 355 STLDeleteElements(&kept_forms); |
356 return ok; | 356 return ok; |
357 } | 357 } |
358 | 358 |
359 bool NativeBackendKWallet::RemoveLoginsCreatedBetween( | 359 bool NativeBackendKWallet::RemoveLoginsCreatedBetween(base::Time delete_begin, |
360 const base::Time& delete_begin, | 360 base::Time delete_end) { |
361 const base::Time& delete_end) { | 361 password_manager::PasswordStoreChangeList changes; |
362 int wallet_handle = WalletHandle(); | 362 return RemoveLoginsBetween(delete_begin, delete_end, true, &changes); |
363 if (wallet_handle == kInvalidKWalletHandle) | 363 } |
364 return false; | |
365 | 364 |
366 // We could probably also use readEntryList here. | 365 bool NativeBackendKWallet::RemoveLoginsSyncedBetween( |
367 std::vector<std::string> realm_list; | 366 base::Time delete_begin, |
368 { | 367 base::Time delete_end, |
369 dbus::MethodCall method_call(kKWalletInterface, "entryList"); | 368 password_manager::PasswordStoreChangeList* changes) { |
370 dbus::MessageWriter builder(&method_call); | 369 return RemoveLoginsBetween(delete_begin, delete_end, false, changes); |
371 builder.AppendInt32(wallet_handle); // handle | |
372 builder.AppendString(folder_name_); // folder | |
373 builder.AppendString(app_name_); // appid | |
374 scoped_ptr<dbus::Response> response( | |
375 kwallet_proxy_->CallMethodAndBlock( | |
376 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT)); | |
377 if (!response.get()) { | |
378 LOG(ERROR) << "Error contacting kwalletd (entryList)"; | |
379 return false; | |
380 } | |
381 dbus::MessageReader reader(response.get()); | |
382 dbus::MessageReader array(response.get()); | |
383 if (!reader.PopArray(&array)) { | |
384 LOG(ERROR) << "Error reading response from kwalletd (entryList): " | |
385 << response->ToString(); | |
386 return false; | |
387 } | |
388 while (array.HasMoreData()) { | |
389 std::string realm; | |
390 if (!array.PopString(&realm)) { | |
391 LOG(ERROR) << "Error reading response from kwalletd (entryList): " | |
392 << response->ToString(); | |
393 return false; | |
394 } | |
395 realm_list.push_back(realm); | |
396 } | |
397 } | |
398 | |
399 bool ok = true; | |
400 for (size_t i = 0; i < realm_list.size(); ++i) { | |
401 const std::string& signon_realm = realm_list[i]; | |
402 dbus::MethodCall method_call(kKWalletInterface, "readEntry"); | |
403 dbus::MessageWriter builder(&method_call); | |
404 builder.AppendInt32(wallet_handle); // handle | |
405 builder.AppendString(folder_name_); // folder | |
406 builder.AppendString(signon_realm); // key | |
407 builder.AppendString(app_name_); // appid | |
408 scoped_ptr<dbus::Response> response( | |
409 kwallet_proxy_->CallMethodAndBlock( | |
410 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT)); | |
411 if (!response.get()) { | |
412 LOG(ERROR) << "Error contacting kwalletd (readEntry)"; | |
413 continue; | |
414 } | |
415 dbus::MessageReader reader(response.get()); | |
416 const uint8_t* bytes = NULL; | |
417 size_t length = 0; | |
418 if (!reader.PopArrayOfBytes(&bytes, &length)) { | |
419 LOG(ERROR) << "Error reading response from kwalletd (readEntry): " | |
420 << response->ToString(); | |
421 continue; | |
422 } | |
423 if (!bytes || !CheckSerializedValue(bytes, length, signon_realm)) | |
424 continue; | |
425 | |
426 // Can't we all just agree on whether bytes are signed or not? Please? | |
427 Pickle pickle(reinterpret_cast<const char*>(bytes), length); | |
428 PasswordFormList all_forms; | |
429 DeserializeValue(signon_realm, pickle, &all_forms); | |
430 | |
431 PasswordFormList kept_forms; | |
432 kept_forms.reserve(all_forms.size()); | |
433 for (size_t i = 0; i < all_forms.size(); ++i) { | |
434 if (delete_begin <= all_forms[i]->date_created && | |
435 (delete_end.is_null() || all_forms[i]->date_created < delete_end)) { | |
436 delete all_forms[i]; | |
437 } else { | |
438 kept_forms.push_back(all_forms[i]); | |
439 } | |
440 } | |
441 | |
442 if (!SetLoginsList(kept_forms, signon_realm, wallet_handle)) | |
443 ok = false; | |
444 STLDeleteElements(&kept_forms); | |
445 } | |
446 return ok; | |
447 } | 370 } |
448 | 371 |
449 bool NativeBackendKWallet::GetLogins(const PasswordForm& form, | 372 bool NativeBackendKWallet::GetLogins(const PasswordForm& form, |
450 PasswordFormList* forms) { | 373 PasswordFormList* forms) { |
451 int wallet_handle = WalletHandle(); | 374 int wallet_handle = WalletHandle(); |
452 if (wallet_handle == kInvalidKWalletHandle) | 375 if (wallet_handle == kInvalidKWalletHandle) |
453 return false; | 376 return false; |
454 return GetLoginsList(forms, form.signon_realm, wallet_handle); | 377 return GetLoginsList(forms, form.signon_realm, wallet_handle); |
455 } | 378 } |
456 | 379 |
457 bool NativeBackendKWallet::GetLoginsCreatedBetween(const base::Time& get_begin, | 380 bool NativeBackendKWallet::GetLoginsCreatedBetween(base::Time get_begin, |
458 const base::Time& get_end, | 381 base::Time get_end, |
459 PasswordFormList* forms) { | 382 PasswordFormList* forms) { |
460 int wallet_handle = WalletHandle(); | 383 int wallet_handle = WalletHandle(); |
461 if (wallet_handle == kInvalidKWalletHandle) | 384 if (wallet_handle == kInvalidKWalletHandle) |
462 return false; | 385 return false; |
463 return GetLoginsList(forms, get_begin, get_end, wallet_handle); | 386 return GetLoginsList(forms, get_begin, get_end, wallet_handle, true); |
464 } | 387 } |
465 | 388 |
466 bool NativeBackendKWallet::GetAutofillableLogins(PasswordFormList* forms) { | 389 bool NativeBackendKWallet::GetAutofillableLogins(PasswordFormList* forms) { |
467 int wallet_handle = WalletHandle(); | 390 int wallet_handle = WalletHandle(); |
468 if (wallet_handle == kInvalidKWalletHandle) | 391 if (wallet_handle == kInvalidKWalletHandle) |
469 return false; | 392 return false; |
470 return GetLoginsList(forms, true, wallet_handle); | 393 return GetLoginsList(forms, true, wallet_handle); |
471 } | 394 } |
472 | 395 |
473 bool NativeBackendKWallet::GetBlacklistLogins(PasswordFormList* forms) { | 396 bool NativeBackendKWallet::GetBlacklistLogins(PasswordFormList* forms) { |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
561 for (size_t i = 0; i < all_forms.size(); ++i) { | 484 for (size_t i = 0; i < all_forms.size(); ++i) { |
562 if (all_forms[i]->blacklisted_by_user == !autofillable) | 485 if (all_forms[i]->blacklisted_by_user == !autofillable) |
563 forms->push_back(all_forms[i]); | 486 forms->push_back(all_forms[i]); |
564 else | 487 else |
565 delete all_forms[i]; | 488 delete all_forms[i]; |
566 } | 489 } |
567 | 490 |
568 return true; | 491 return true; |
569 } | 492 } |
570 | 493 |
571 bool NativeBackendKWallet::GetLoginsList(PasswordFormList* forms, | 494 bool NativeBackendKWallet::GetLoginsList(PasswordFormList* forms, |
vabr (Chromium)
2014/06/17 15:28:40
This method looks sufficiently similar to NativeBa
vasilii
2014/06/17 17:24:14
PasswordStoreX::NativeBackend is an interface. It
| |
572 const base::Time& begin, | 495 const base::Time& begin, |
573 const base::Time& end, | 496 const base::Time& end, |
574 int wallet_handle) { | 497 int wallet_handle, |
498 bool date_is_creation) { | |
575 PasswordFormList all_forms; | 499 PasswordFormList all_forms; |
576 if (!GetAllLogins(&all_forms, wallet_handle)) | 500 if (!GetAllLogins(&all_forms, wallet_handle)) |
577 return false; | 501 return false; |
578 | 502 |
579 // We have to read all the entries, and then filter them here. | 503 // We have to read all the entries, and then filter them here. |
504 base::Time autofill::PasswordForm::*date_member = date_is_creation ? | |
505 &autofill::PasswordForm::date_created : | |
506 &autofill::PasswordForm::date_synced; | |
580 forms->reserve(forms->size() + all_forms.size()); | 507 forms->reserve(forms->size() + all_forms.size()); |
581 for (size_t i = 0; i < all_forms.size(); ++i) { | 508 for (size_t i = 0; i < all_forms.size(); ++i) { |
582 if (begin <= all_forms[i]->date_created && | 509 if (begin <= all_forms[i]->*date_member && |
583 (end.is_null() || all_forms[i]->date_created < end)) { | 510 (end.is_null() || all_forms[i]->*date_member < end)) { |
584 forms->push_back(all_forms[i]); | 511 forms->push_back(all_forms[i]); |
585 } else { | 512 } else { |
586 delete all_forms[i]; | 513 delete all_forms[i]; |
587 } | 514 } |
588 } | 515 } |
589 | 516 |
590 return true; | 517 return true; |
591 } | 518 } |
592 | 519 |
593 bool NativeBackendKWallet::GetAllLogins(PasswordFormList* forms, | 520 bool NativeBackendKWallet::GetAllLogins(PasswordFormList* forms, |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
702 if (!reader.PopInt32(&ret)) { | 629 if (!reader.PopInt32(&ret)) { |
703 LOG(ERROR) << "Error reading response from kwalletd (writeEntry): " | 630 LOG(ERROR) << "Error reading response from kwalletd (writeEntry): " |
704 << response->ToString(); | 631 << response->ToString(); |
705 return false; | 632 return false; |
706 } | 633 } |
707 if (ret != 0) | 634 if (ret != 0) |
708 LOG(ERROR) << "Bad return code " << ret << " from KWallet writeEntry"; | 635 LOG(ERROR) << "Bad return code " << ret << " from KWallet writeEntry"; |
709 return ret == 0; | 636 return ret == 0; |
710 } | 637 } |
711 | 638 |
639 bool NativeBackendKWallet::RemoveLoginsBetween( | |
640 base::Time delete_begin, | |
641 base::Time delete_end, | |
642 bool date_is_creation, | |
643 password_manager::PasswordStoreChangeList* changes) { | |
644 DCHECK(changes); | |
645 changes->clear(); | |
646 int wallet_handle = WalletHandle(); | |
647 if (wallet_handle == kInvalidKWalletHandle) | |
648 return false; | |
649 | |
650 // We could probably also use readEntryList here. | |
651 std::vector<std::string> realm_list; | |
652 { | |
653 dbus::MethodCall method_call(kKWalletInterface, "entryList"); | |
654 dbus::MessageWriter builder(&method_call); | |
655 builder.AppendInt32(wallet_handle); // handle | |
656 builder.AppendString(folder_name_); // folder | |
657 builder.AppendString(app_name_); // appid | |
658 scoped_ptr<dbus::Response> response( | |
659 kwallet_proxy_->CallMethodAndBlock( | |
660 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT)); | |
661 if (!response.get()) { | |
662 LOG(ERROR) << "Error contacting kwalletd (entryList)"; | |
663 return false; | |
664 } | |
665 dbus::MessageReader reader(response.get()); | |
666 dbus::MessageReader array(response.get()); | |
667 if (!reader.PopArray(&array)) { | |
668 LOG(ERROR) << "Error reading response from kwalletd (entryList): " | |
669 << response->ToString(); | |
670 return false; | |
671 } | |
672 while (array.HasMoreData()) { | |
673 std::string realm; | |
674 if (!array.PopString(&realm)) { | |
675 LOG(ERROR) << "Error reading response from kwalletd (entryList): " | |
676 << response->ToString(); | |
677 return false; | |
678 } | |
679 realm_list.push_back(realm); | |
680 } | |
681 } | |
682 | |
683 bool ok = true; | |
684 for (size_t i = 0; i < realm_list.size(); ++i) { | |
685 const std::string& signon_realm = realm_list[i]; | |
686 dbus::MethodCall method_call(kKWalletInterface, "readEntry"); | |
687 dbus::MessageWriter builder(&method_call); | |
688 builder.AppendInt32(wallet_handle); // handle | |
689 builder.AppendString(folder_name_); // folder | |
690 builder.AppendString(signon_realm); // key | |
691 builder.AppendString(app_name_); // appid | |
692 scoped_ptr<dbus::Response> response( | |
693 kwallet_proxy_->CallMethodAndBlock( | |
694 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT)); | |
695 if (!response.get()) { | |
696 LOG(ERROR) << "Error contacting kwalletd (readEntry)"; | |
697 continue; | |
698 } | |
699 dbus::MessageReader reader(response.get()); | |
700 const uint8_t* bytes = NULL; | |
701 size_t length = 0; | |
702 if (!reader.PopArrayOfBytes(&bytes, &length)) { | |
703 LOG(ERROR) << "Error reading response from kwalletd (readEntry): " | |
704 << response->ToString(); | |
705 continue; | |
706 } | |
707 if (!bytes || !CheckSerializedValue(bytes, length, signon_realm)) | |
708 continue; | |
709 | |
710 // Can't we all just agree on whether bytes are signed or not? Please? | |
711 Pickle pickle(reinterpret_cast<const char*>(bytes), length); | |
712 PasswordFormList all_forms; | |
713 DeserializeValue(signon_realm, pickle, &all_forms); | |
714 | |
715 PasswordFormList kept_forms; | |
716 kept_forms.reserve(all_forms.size()); | |
717 base::Time autofill::PasswordForm::*date_member = date_is_creation ? | |
718 &autofill::PasswordForm::date_created : | |
719 &autofill::PasswordForm::date_synced; | |
720 for (size_t i = 0; i < all_forms.size(); ++i) { | |
721 if (delete_begin <= all_forms[i]->*date_member && | |
722 (delete_end.is_null() || all_forms[i]->*date_member < delete_end)) { | |
723 changes->push_back(password_manager::PasswordStoreChange( | |
724 password_manager::PasswordStoreChange::REMOVE, *all_forms[i])); | |
725 delete all_forms[i]; | |
726 } else { | |
727 kept_forms.push_back(all_forms[i]); | |
728 } | |
729 } | |
730 | |
731 if (!SetLoginsList(kept_forms, signon_realm, wallet_handle)) { | |
732 ok = false; | |
733 changes->clear(); | |
734 } | |
735 STLDeleteElements(&kept_forms); | |
736 } | |
737 return ok; | |
738 } | |
739 | |
712 // static | 740 // static |
713 void NativeBackendKWallet::SerializeValue(const PasswordFormList& forms, | 741 void NativeBackendKWallet::SerializeValue(const PasswordFormList& forms, |
714 Pickle* pickle) { | 742 Pickle* pickle) { |
715 pickle->WriteInt(kPickleVersion); | 743 pickle->WriteInt(kPickleVersion); |
716 pickle->WriteUInt64(forms.size()); | 744 pickle->WriteUInt64(forms.size()); |
717 for (PasswordFormList::const_iterator it = forms.begin(); | 745 for (PasswordFormList::const_iterator it = forms.begin(); |
718 it != forms.end(); ++it) { | 746 it != forms.end(); ++it) { |
719 const PasswordForm* form = *it; | 747 const PasswordForm* form = *it; |
720 pickle->WriteInt(form->scheme); | 748 pickle->WriteInt(form->scheme); |
721 pickle->WriteString(form->origin.spec()); | 749 pickle->WriteString(form->origin.spec()); |
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
944 } | 972 } |
945 | 973 |
946 return handle; | 974 return handle; |
947 } | 975 } |
948 | 976 |
949 std::string NativeBackendKWallet::GetProfileSpecificFolderName() const { | 977 std::string NativeBackendKWallet::GetProfileSpecificFolderName() const { |
950 // Originally, the folder name was always just "Chrome Form Data". | 978 // Originally, the folder name was always just "Chrome Form Data". |
951 // Now we use it to distinguish passwords for different profiles. | 979 // Now we use it to distinguish passwords for different profiles. |
952 return base::StringPrintf("%s (%d)", kKWalletFolder, profile_id_); | 980 return base::StringPrintf("%s (%d)", kKWalletFolder, profile_id_); |
953 } | 981 } |
OLD | NEW |