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( |
363 if (wallet_handle == kInvalidKWalletHandle) | 363 delete_begin, delete_end, CREATION_TIMESTAMP, &changes); |
364 return false; | 364 } |
365 | 365 |
366 // We could probably also use readEntryList here. | 366 bool NativeBackendKWallet::RemoveLoginsSyncedBetween( |
367 std::vector<std::string> realm_list; | 367 base::Time delete_begin, |
368 { | 368 base::Time delete_end, |
369 dbus::MethodCall method_call(kKWalletInterface, "entryList"); | 369 password_manager::PasswordStoreChangeList* changes) { |
370 dbus::MessageWriter builder(&method_call); | 370 return RemoveLoginsBetween(delete_begin, delete_end, SYNC_TIMESTAMP, 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 } | 371 } |
448 | 372 |
449 bool NativeBackendKWallet::GetLogins(const PasswordForm& form, | 373 bool NativeBackendKWallet::GetLogins(const PasswordForm& form, |
450 PasswordFormList* forms) { | 374 PasswordFormList* forms) { |
451 int wallet_handle = WalletHandle(); | 375 int wallet_handle = WalletHandle(); |
452 if (wallet_handle == kInvalidKWalletHandle) | 376 if (wallet_handle == kInvalidKWalletHandle) |
453 return false; | 377 return false; |
454 return GetLoginsList(forms, form.signon_realm, wallet_handle); | 378 return GetLoginsList(forms, form.signon_realm, wallet_handle); |
455 } | 379 } |
456 | 380 |
457 bool NativeBackendKWallet::GetLoginsCreatedBetween(const base::Time& get_begin, | 381 bool NativeBackendKWallet::GetLoginsCreatedBetween(base::Time get_begin, |
458 const base::Time& get_end, | 382 base::Time get_end, |
459 PasswordFormList* forms) { | 383 PasswordFormList* forms) { |
460 int wallet_handle = WalletHandle(); | 384 int wallet_handle = WalletHandle(); |
461 if (wallet_handle == kInvalidKWalletHandle) | 385 if (wallet_handle == kInvalidKWalletHandle) |
462 return false; | 386 return false; |
463 return GetLoginsList(forms, get_begin, get_end, wallet_handle); | 387 return GetLoginsList( |
| 388 forms, get_begin, get_end, wallet_handle, CREATION_TIMESTAMP); |
464 } | 389 } |
465 | 390 |
466 bool NativeBackendKWallet::GetAutofillableLogins(PasswordFormList* forms) { | 391 bool NativeBackendKWallet::GetAutofillableLogins(PasswordFormList* forms) { |
467 int wallet_handle = WalletHandle(); | 392 int wallet_handle = WalletHandle(); |
468 if (wallet_handle == kInvalidKWalletHandle) | 393 if (wallet_handle == kInvalidKWalletHandle) |
469 return false; | 394 return false; |
470 return GetLoginsList(forms, true, wallet_handle); | 395 return GetLoginsList(forms, true, wallet_handle); |
471 } | 396 } |
472 | 397 |
473 bool NativeBackendKWallet::GetBlacklistLogins(PasswordFormList* forms) { | 398 bool NativeBackendKWallet::GetBlacklistLogins(PasswordFormList* forms) { |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
564 else | 489 else |
565 delete all_forms[i]; | 490 delete all_forms[i]; |
566 } | 491 } |
567 | 492 |
568 return true; | 493 return true; |
569 } | 494 } |
570 | 495 |
571 bool NativeBackendKWallet::GetLoginsList(PasswordFormList* forms, | 496 bool NativeBackendKWallet::GetLoginsList(PasswordFormList* forms, |
572 const base::Time& begin, | 497 const base::Time& begin, |
573 const base::Time& end, | 498 const base::Time& end, |
574 int wallet_handle) { | 499 int wallet_handle, |
| 500 TimestampToCompare date_to_compare) { |
575 PasswordFormList all_forms; | 501 PasswordFormList all_forms; |
576 if (!GetAllLogins(&all_forms, wallet_handle)) | 502 if (!GetAllLogins(&all_forms, wallet_handle)) |
577 return false; | 503 return false; |
578 | 504 |
579 // We have to read all the entries, and then filter them here. | 505 // We have to read all the entries, and then filter them here. |
| 506 base::Time autofill::PasswordForm::*date_member = |
| 507 date_to_compare == CREATION_TIMESTAMP |
| 508 ? &autofill::PasswordForm::date_created |
| 509 : &autofill::PasswordForm::date_synced; |
580 forms->reserve(forms->size() + all_forms.size()); | 510 forms->reserve(forms->size() + all_forms.size()); |
581 for (size_t i = 0; i < all_forms.size(); ++i) { | 511 for (size_t i = 0; i < all_forms.size(); ++i) { |
582 if (begin <= all_forms[i]->date_created && | 512 if (begin <= all_forms[i]->*date_member && |
583 (end.is_null() || all_forms[i]->date_created < end)) { | 513 (end.is_null() || all_forms[i]->*date_member < end)) { |
584 forms->push_back(all_forms[i]); | 514 forms->push_back(all_forms[i]); |
585 } else { | 515 } else { |
586 delete all_forms[i]; | 516 delete all_forms[i]; |
587 } | 517 } |
588 } | 518 } |
589 | 519 |
590 return true; | 520 return true; |
591 } | 521 } |
592 | 522 |
593 bool NativeBackendKWallet::GetAllLogins(PasswordFormList* forms, | 523 bool NativeBackendKWallet::GetAllLogins(PasswordFormList* forms, |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
702 if (!reader.PopInt32(&ret)) { | 632 if (!reader.PopInt32(&ret)) { |
703 LOG(ERROR) << "Error reading response from kwalletd (writeEntry): " | 633 LOG(ERROR) << "Error reading response from kwalletd (writeEntry): " |
704 << response->ToString(); | 634 << response->ToString(); |
705 return false; | 635 return false; |
706 } | 636 } |
707 if (ret != 0) | 637 if (ret != 0) |
708 LOG(ERROR) << "Bad return code " << ret << " from KWallet writeEntry"; | 638 LOG(ERROR) << "Bad return code " << ret << " from KWallet writeEntry"; |
709 return ret == 0; | 639 return ret == 0; |
710 } | 640 } |
711 | 641 |
| 642 bool NativeBackendKWallet::RemoveLoginsBetween( |
| 643 base::Time delete_begin, |
| 644 base::Time delete_end, |
| 645 TimestampToCompare date_to_compare, |
| 646 password_manager::PasswordStoreChangeList* changes) { |
| 647 DCHECK(changes); |
| 648 changes->clear(); |
| 649 int wallet_handle = WalletHandle(); |
| 650 if (wallet_handle == kInvalidKWalletHandle) |
| 651 return false; |
| 652 |
| 653 // We could probably also use readEntryList here. |
| 654 std::vector<std::string> realm_list; |
| 655 { |
| 656 dbus::MethodCall method_call(kKWalletInterface, "entryList"); |
| 657 dbus::MessageWriter builder(&method_call); |
| 658 builder.AppendInt32(wallet_handle); // handle |
| 659 builder.AppendString(folder_name_); // folder |
| 660 builder.AppendString(app_name_); // appid |
| 661 scoped_ptr<dbus::Response> response(kwallet_proxy_->CallMethodAndBlock( |
| 662 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT)); |
| 663 if (!response.get()) { |
| 664 LOG(ERROR) << "Error contacting kwalletd (entryList)"; |
| 665 return false; |
| 666 } |
| 667 dbus::MessageReader reader(response.get()); |
| 668 dbus::MessageReader array(response.get()); |
| 669 if (!reader.PopArray(&array)) { |
| 670 LOG(ERROR) << "Error reading response from kwalletd (entryList): " |
| 671 << response->ToString(); |
| 672 return false; |
| 673 } |
| 674 while (array.HasMoreData()) { |
| 675 std::string realm; |
| 676 if (!array.PopString(&realm)) { |
| 677 LOG(ERROR) << "Error reading response from kwalletd (entryList): " |
| 678 << response->ToString(); |
| 679 return false; |
| 680 } |
| 681 realm_list.push_back(realm); |
| 682 } |
| 683 } |
| 684 |
| 685 bool ok = true; |
| 686 for (size_t i = 0; i < realm_list.size(); ++i) { |
| 687 const std::string& signon_realm = realm_list[i]; |
| 688 dbus::MethodCall method_call(kKWalletInterface, "readEntry"); |
| 689 dbus::MessageWriter builder(&method_call); |
| 690 builder.AppendInt32(wallet_handle); // handle |
| 691 builder.AppendString(folder_name_); // folder |
| 692 builder.AppendString(signon_realm); // key |
| 693 builder.AppendString(app_name_); // appid |
| 694 scoped_ptr<dbus::Response> response(kwallet_proxy_->CallMethodAndBlock( |
| 695 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT)); |
| 696 if (!response.get()) { |
| 697 LOG(ERROR) << "Error contacting kwalletd (readEntry)"; |
| 698 continue; |
| 699 } |
| 700 dbus::MessageReader reader(response.get()); |
| 701 const uint8_t* bytes = NULL; |
| 702 size_t length = 0; |
| 703 if (!reader.PopArrayOfBytes(&bytes, &length)) { |
| 704 LOG(ERROR) << "Error reading response from kwalletd (readEntry): " |
| 705 << response->ToString(); |
| 706 continue; |
| 707 } |
| 708 if (!bytes || !CheckSerializedValue(bytes, length, signon_realm)) |
| 709 continue; |
| 710 |
| 711 // Can't we all just agree on whether bytes are signed or not? Please? |
| 712 Pickle pickle(reinterpret_cast<const char*>(bytes), length); |
| 713 PasswordFormList all_forms; |
| 714 DeserializeValue(signon_realm, pickle, &all_forms); |
| 715 |
| 716 PasswordFormList kept_forms; |
| 717 kept_forms.reserve(all_forms.size()); |
| 718 base::Time autofill::PasswordForm::*date_member = |
| 719 date_to_compare == CREATION_TIMESTAMP |
| 720 ? &autofill::PasswordForm::date_created |
| 721 : &autofill::PasswordForm::date_synced; |
| 722 for (size_t i = 0; i < all_forms.size(); ++i) { |
| 723 if (delete_begin <= all_forms[i]->*date_member && |
| 724 (delete_end.is_null() || all_forms[i]->*date_member < delete_end)) { |
| 725 changes->push_back(password_manager::PasswordStoreChange( |
| 726 password_manager::PasswordStoreChange::REMOVE, *all_forms[i])); |
| 727 delete all_forms[i]; |
| 728 } else { |
| 729 kept_forms.push_back(all_forms[i]); |
| 730 } |
| 731 } |
| 732 |
| 733 if (!SetLoginsList(kept_forms, signon_realm, wallet_handle)) { |
| 734 ok = false; |
| 735 changes->clear(); |
| 736 } |
| 737 STLDeleteElements(&kept_forms); |
| 738 } |
| 739 return ok; |
| 740 } |
| 741 |
712 // static | 742 // static |
713 void NativeBackendKWallet::SerializeValue(const PasswordFormList& forms, | 743 void NativeBackendKWallet::SerializeValue(const PasswordFormList& forms, |
714 Pickle* pickle) { | 744 Pickle* pickle) { |
715 pickle->WriteInt(kPickleVersion); | 745 pickle->WriteInt(kPickleVersion); |
716 pickle->WriteUInt64(forms.size()); | 746 pickle->WriteUInt64(forms.size()); |
717 for (PasswordFormList::const_iterator it = forms.begin(); | 747 for (PasswordFormList::const_iterator it = forms.begin(); |
718 it != forms.end(); ++it) { | 748 it != forms.end(); ++it) { |
719 const PasswordForm* form = *it; | 749 const PasswordForm* form = *it; |
720 pickle->WriteInt(form->scheme); | 750 pickle->WriteInt(form->scheme); |
721 pickle->WriteString(form->origin.spec()); | 751 pickle->WriteString(form->origin.spec()); |
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
944 } | 974 } |
945 | 975 |
946 return handle; | 976 return handle; |
947 } | 977 } |
948 | 978 |
949 std::string NativeBackendKWallet::GetProfileSpecificFolderName() const { | 979 std::string NativeBackendKWallet::GetProfileSpecificFolderName() const { |
950 // Originally, the folder name was always just "Chrome Form Data". | 980 // Originally, the folder name was always just "Chrome Form Data". |
951 // Now we use it to distinguish passwords for different profiles. | 981 // Now we use it to distinguish passwords for different profiles. |
952 return base::StringPrintf("%s (%d)", kKWalletFolder, profile_id_); | 982 return base::StringPrintf("%s (%d)", kKWalletFolder, profile_id_); |
953 } | 983 } |
OLD | NEW |