Chromium Code Reviews| 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 |