Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(348)

Side by Side Diff: chrome/browser/password_manager/native_backend_kwallet_x.cc

Issue 2057123002: Refactor native_backend_kwallet_x (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: cleanup Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 <stddef.h> 7 #include <stddef.h>
8 #include <stdint.h> 8 #include <stdint.h>
9 9
10 #include <map> 10 #include <map>
11 #include <utility> 11 #include <utility>
12 #include <vector> 12 #include <vector>
13 13
14 #include "base/bind.h" 14 #include "base/bind.h"
15 #include "base/logging.h" 15 #include "base/logging.h"
16 #include "base/metrics/histogram.h" 16 #include "base/metrics/histogram.h"
17 #include "base/pickle.h" 17 #include "base/pickle.h"
18 #include "base/stl_util.h" 18 #include "base/stl_util.h"
19 #include "base/strings/stringprintf.h" 19 #include "base/strings/stringprintf.h"
20 #include "base/synchronization/waitable_event.h" 20 #include "base/synchronization/waitable_event.h"
21 #include "base/threading/thread_restrictions.h" 21 #include "base/threading/thread_restrictions.h"
22 #include "chrome/grit/chromium_strings.h" 22 #include "chrome/grit/chromium_strings.h"
23 #include "components/autofill/core/common/password_form.h" 23 #include "components/autofill/core/common/password_form.h"
24 #include "components/password_manager/core/browser/password_manager_util.h" 24 #include "components/password_manager/core/browser/password_manager_util.h"
25 #include "content/public/browser/browser_thread.h" 25 #include "content/public/browser/browser_thread.h"
26 #include "dbus/bus.h" 26 #include "dbus/bus.h"
27 #include "dbus/message.h" 27 #include "dbus/message.h"
28 #include "dbus/object_path.h" 28 #include "dbus/object_path.h"
29 #include "dbus/object_proxy.h"
30 #include "ui/base/l10n/l10n_util.h" 29 #include "ui/base/l10n/l10n_util.h"
31 #include "url/origin.h" 30 #include "url/origin.h"
32 31
33 using autofill::PasswordForm; 32 using autofill::PasswordForm;
34 using content::BrowserThread; 33 using content::BrowserThread;
35 34
36 namespace { 35 namespace {
37 36
38 // In case the fields in the pickle ever change, version them so we can try to 37 // In case the fields in the pickle ever change, version them so we can try to
39 // read old pickles. (Note: do not eat old pickles past the expiration date.) 38 // read old pickles. (Note: do not eat old pickles past the expiration date.)
40 const int kPickleVersion = 8; 39 const int kPickleVersion = 8;
41 40
42 // We could localize this string, but then changing your locale would cause 41 // We could localize this string, but then changing your locale would cause
43 // you to lose access to all your stored passwords. Maybe best not to do that. 42 // you to lose access to all your stored passwords. Maybe best not to do that.
44 // Name of the folder to store passwords in. 43 // Name of the folder to store passwords in.
45 const char kKWalletFolder[] = "Chrome Form Data"; 44 const char kKWalletFolder[] = "Chrome Form Data";
46 45
47 // DBus service, path, and interface names for klauncher and kwalletd.
48 const char kKWalletDName[] = "kwalletd";
49 const char kKWalletD5Name[] = "kwalletd5";
50 const char kKWalletServiceName[] = "org.kde.kwalletd";
51 const char kKWallet5ServiceName[] = "org.kde.kwalletd5";
52 const char kKWalletPath[] = "/modules/kwalletd";
53 const char kKWallet5Path[] = "/modules/kwalletd5";
54 const char kKWalletInterface[] = "org.kde.KWallet";
55 const char kKLauncherServiceName[] = "org.kde.klauncher";
56 const char kKLauncherPath[] = "/KLauncher";
57 const char kKLauncherInterface[] = "org.kde.KLauncher";
58
59 // Checks a serialized list of PasswordForms for sanity. Returns true if OK. 46 // Checks a serialized list of PasswordForms for sanity. Returns true if OK.
60 // Note that |realm| is only used for generating a useful warning message. 47 // Note that |realm| is only used for generating a useful warning message.
61 bool CheckSerializedValue(const uint8_t* byte_array, 48 bool CheckSerializedValue(const uint8_t* byte_array,
62 size_t length, 49 size_t length,
63 const std::string& realm) { 50 const std::string& realm) {
64 const base::Pickle::Header* header = 51 const base::Pickle::Header* header =
65 reinterpret_cast<const base::Pickle::Header*>(byte_array); 52 reinterpret_cast<const base::Pickle::Header*>(byte_array);
66 if (length < sizeof(*header) || 53 if (length < sizeof(*header) ||
67 header->payload_size > length - sizeof(*header)) { 54 header->payload_size > length - sizeof(*header)) {
68 LOG(WARNING) << "Invalid KWallet entry detected (realm: " << realm << ")"; 55 LOG(WARNING) << "Invalid KWallet entry detected (realm: " << realm << ")";
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after
296 } 283 }
297 284
298 void UMALogDeserializationStatus(bool success) { 285 void UMALogDeserializationStatus(bool success) {
299 UMA_HISTOGRAM_BOOLEAN("PasswordManager.KWalletDeserializationStatus", 286 UMA_HISTOGRAM_BOOLEAN("PasswordManager.KWalletDeserializationStatus",
300 success); 287 success);
301 } 288 }
302 289
303 } // namespace 290 } // namespace
304 291
305 NativeBackendKWallet::NativeBackendKWallet( 292 NativeBackendKWallet::NativeBackendKWallet(
306 LocalProfileId id, base::nix::DesktopEnvironment desktop_env) 293 LocalProfileId id,
294 base::nix::DesktopEnvironment desktop_env)
307 : profile_id_(id), 295 : profile_id_(id),
308 kwallet_proxy_(nullptr), 296 kwallet_dbus_(desktop_env),
309 app_name_(l10n_util::GetStringUTF8(IDS_PRODUCT_NAME)) { 297 app_name_(l10n_util::GetStringUTF8(IDS_PRODUCT_NAME)) {
310 folder_name_ = GetProfileSpecificFolderName(); 298 folder_name_ = GetProfileSpecificFolderName();
311
312 if (desktop_env == base::nix::DESKTOP_ENVIRONMENT_KDE5) {
313 dbus_service_name_ = kKWallet5ServiceName;
314 dbus_path_ = kKWallet5Path;
315 kwalletd_name_ = kKWalletD5Name;
316 } else {
317 dbus_service_name_ = kKWalletServiceName;
318 dbus_path_ = kKWalletPath;
319 kwalletd_name_ = kKWalletDName;
320 }
321 } 299 }
322 300
323 NativeBackendKWallet::~NativeBackendKWallet() { 301 NativeBackendKWallet::~NativeBackendKWallet() {
324 // This destructor is called on the thread that is destroying the Profile 302 // This destructor is called on the thread that is destroying the Profile
325 // containing the PasswordStore that owns this NativeBackend. Generally that 303 // containing the PasswordStore that owns this NativeBackend. Generally that
326 // won't be the DB thread; it will be the UI thread. So we post a message to 304 // won't be the DB thread; it will be the UI thread. So we post a message to
327 // shut it down on the DB thread, and it will be destructed afterward when the 305 // shut it down on the DB thread, and it will be destructed afterward when the
328 // scoped_refptr<dbus::Bus> goes out of scope. The NativeBackend will be 306 // scoped_refptr<dbus::Bus> goes out of scope. The NativeBackend will be
329 // destroyed before that occurs, but that's OK. 307 // destroyed before that occurs, but that's OK.
330 if (session_bus_.get()) { 308 if (kwallet_dbus_.GetBus()) {
331 BrowserThread::PostTask(BrowserThread::DB, FROM_HERE, 309 BrowserThread::PostTask(
332 base::Bind(&dbus::Bus::ShutdownAndBlock, 310 BrowserThread::DB, FROM_HERE,
333 session_bus_.get())); 311 base::Bind(&dbus::Bus::ShutdownAndBlock, kwallet_dbus_.GetBus()));
334 } 312 }
335 } 313 }
336 314
337 bool NativeBackendKWallet::Init() { 315 bool NativeBackendKWallet::Init() {
338 // Without the |optional_bus| parameter, a real bus will be instantiated. 316 // Without the |optional_bus| parameter, a real bus will be instantiated.
339 return InitWithBus(scoped_refptr<dbus::Bus>()); 317 return InitWithBus(scoped_refptr<dbus::Bus>());
340 } 318 }
341 319
342 bool NativeBackendKWallet::InitWithBus(scoped_refptr<dbus::Bus> optional_bus) { 320 bool NativeBackendKWallet::InitWithBus(scoped_refptr<dbus::Bus> optional_bus) {
343 // We must synchronously do a few DBus calls to figure out if initialization 321 // We must synchronously do a few DBus calls to figure out if initialization
(...skipping 12 matching lines...) Expand all
356 // This ScopedAllowWait should not be here. http://crbug.com/125331 334 // This ScopedAllowWait should not be here. http://crbug.com/125331
357 base::ThreadRestrictions::ScopedAllowWait allow_wait; 335 base::ThreadRestrictions::ScopedAllowWait allow_wait;
358 event.Wait(); 336 event.Wait();
359 return success; 337 return success;
360 } 338 }
361 339
362 void NativeBackendKWallet::InitOnDBThread(scoped_refptr<dbus::Bus> optional_bus, 340 void NativeBackendKWallet::InitOnDBThread(scoped_refptr<dbus::Bus> optional_bus,
363 base::WaitableEvent* event, 341 base::WaitableEvent* event,
364 bool* success) { 342 bool* success) {
365 DCHECK_CURRENTLY_ON(BrowserThread::DB); 343 DCHECK_CURRENTLY_ON(BrowserThread::DB);
366 DCHECK(!session_bus_.get()); 344 DCHECK(!kwallet_dbus_.GetBus());
367 if (optional_bus.get()) { 345 if (optional_bus.get()) {
368 // The optional_bus parameter is given when this method is called in tests. 346 // The optional_bus parameter is given when this method is called in tests.
369 session_bus_ = optional_bus; 347 kwallet_dbus_.SetSessionBus(optional_bus);
370 } else { 348 } else {
371 // Get a (real) connection to the session bus. 349 // Get a (real) connection to the session bus.
372 dbus::Bus::Options options; 350 dbus::Bus::Options options;
373 options.bus_type = dbus::Bus::SESSION; 351 options.bus_type = dbus::Bus::SESSION;
374 options.connection_type = dbus::Bus::PRIVATE; 352 options.connection_type = dbus::Bus::PRIVATE;
375 session_bus_ = new dbus::Bus(options); 353 kwallet_dbus_.SetSessionBus(new dbus::Bus(options));
376 } 354 }
377 kwallet_proxy_ =
378 session_bus_->GetObjectProxy(dbus_service_name_,
379 dbus::ObjectPath(dbus_path_));
380 // kwalletd may not be running. If we get a temporary failure initializing it, 355 // kwalletd may not be running. If we get a temporary failure initializing it,
381 // try to start it and then try again. (Note the short-circuit evaluation.) 356 // try to start it and then try again. (Note the short-circuit evaluation.)
382 const InitResult result = InitWallet(); 357 const InitResult result = InitWallet();
383 *success = (result == INIT_SUCCESS || 358 *success = (result == INIT_SUCCESS ||
384 (result == TEMPORARY_FAIL && 359 (result == TEMPORARY_FAIL &&
385 StartKWalletd() && InitWallet() == INIT_SUCCESS)); 360 StartKWalletd() && InitWallet() == INIT_SUCCESS));
386 event->Signal(); 361 event->Signal();
387 } 362 }
388 363
389 bool NativeBackendKWallet::StartKWalletd() { 364 bool NativeBackendKWallet::StartKWalletd() {
390 DCHECK_CURRENTLY_ON(BrowserThread::DB); 365 DCHECK_CURRENTLY_ON(BrowserThread::DB);
391 // Sadly kwalletd doesn't use DBus activation, so we have to make a call to 366 // Sadly kwalletd doesn't use DBus activation, so we have to make a call to
392 // klauncher to start it. 367 // klauncher to start it.
vasilii 2016/06/10 16:58:10 Obsolete.
cfroussios 2016/06/16 12:29:08 Done.
393 dbus::ObjectProxy* klauncher = 368 return kwallet_dbus_.StartKWalletd();
394 session_bus_->GetObjectProxy(kKLauncherServiceName,
395 dbus::ObjectPath(kKLauncherPath));
396
397 dbus::MethodCall method_call(kKLauncherInterface,
398 "start_service_by_desktop_name");
399 dbus::MessageWriter builder(&method_call);
400 std::vector<std::string> empty;
401 builder.AppendString(kwalletd_name_); // serviceName
402 builder.AppendArrayOfStrings(empty); // urls
403 builder.AppendArrayOfStrings(empty); // envs
404 builder.AppendString(std::string()); // startup_id
405 builder.AppendBool(false); // blind
406 std::unique_ptr<dbus::Response> response(klauncher->CallMethodAndBlock(
407 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT));
408 if (!response.get()) {
409 LOG(ERROR) << "Error contacting klauncher to start " << kwalletd_name_;
410 return false;
411 }
412 dbus::MessageReader reader(response.get());
413 int32_t ret = -1;
414 std::string dbus_name;
415 std::string error;
416 int32_t pid = -1;
417 if (!reader.PopInt32(&ret) || !reader.PopString(&dbus_name) ||
418 !reader.PopString(&error) || !reader.PopInt32(&pid)) {
419 LOG(ERROR) << "Error reading response from klauncher to start "
420 << kwalletd_name_ << ": " << response->ToString();
421 return false;
422 }
423 if (!error.empty() || ret) {
424 LOG(ERROR) << "Error launching " << kwalletd_name_ << ": error '" << error
425 << "' (code " << ret << ")";
426 return false;
427 }
428
429 return true;
430 } 369 }
431 370
432 NativeBackendKWallet::InitResult NativeBackendKWallet::InitWallet() { 371 NativeBackendKWallet::InitResult NativeBackendKWallet::InitWallet() {
433 DCHECK_CURRENTLY_ON(BrowserThread::DB); 372 DCHECK_CURRENTLY_ON(BrowserThread::DB);
434 {
435 // Check that KWallet is enabled.
436 dbus::MethodCall method_call(kKWalletInterface, "isEnabled");
437 std::unique_ptr<dbus::Response> response(kwallet_proxy_->CallMethodAndBlock(
438 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT));
439 if (!response.get()) {
440 LOG(ERROR) << "Error contacting " << kwalletd_name_ << " (isEnabled)";
441 return TEMPORARY_FAIL;
442 }
443 dbus::MessageReader reader(response.get());
444 bool enabled = false;
445 if (!reader.PopBool(&enabled)) {
446 LOG(ERROR) << "Error reading response from " << kwalletd_name_
447 << " (isEnabled): " << response->ToString();
448 return PERMANENT_FAIL;
449 }
450 // Not enabled? Don't use KWallet. But also don't warn here.
451 if (!enabled) {
452 VLOG(1) << kwalletd_name_ << " reports that KWallet is not enabled.";
453 return PERMANENT_FAIL;
454 }
455 }
456 373
457 { 374 KWalletDBus::Error error;
458 // Get the wallet name. 375
459 dbus::MethodCall method_call(kKWalletInterface, "networkWallet"); 376 // Check that KWallet is enabled.
460 std::unique_ptr<dbus::Response> response(kwallet_proxy_->CallMethodAndBlock( 377 bool enabled;
vasilii 2016/06/10 16:58:10 init please
cfroussios 2016/06/16 12:29:09 Done.
461 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT)); 378 error = kwallet_dbus_.IsEnabled(&enabled);
vasilii 2016/06/10 16:58:10 KWalletDBus::Error error = ...
cfroussios 2016/06/16 12:29:09 Done.
462 if (!response.get()) { 379 if (error == KWalletDBus::Error::CANNOT_CONTACT)
463 LOG(ERROR) << "Error contacting " << kwalletd_name_ << " (networkWallet)"; 380 return TEMPORARY_FAIL;
464 return TEMPORARY_FAIL; 381 if (error == KWalletDBus::Error::CANNOT_READ)
465 } 382 return PERMANENT_FAIL;
466 dbus::MessageReader reader(response.get()); 383 if (!enabled)
467 if (!reader.PopString(&wallet_name_)) { 384 return PERMANENT_FAIL;
468 LOG(ERROR) << "Error reading response from " << kwalletd_name_ 385
469 << " (networkWallet): " << response->ToString(); 386 // Get the wallet name.
470 return PERMANENT_FAIL; 387 error = kwallet_dbus_.NetworkWallet(&wallet_name_);
471 } 388 if (error == KWalletDBus::Error::CANNOT_CONTACT)
472 } 389 return TEMPORARY_FAIL;
390 if (error == KWalletDBus::Error::CANNOT_READ)
vasilii 2016/06/10 16:58:10 switch is more appropriate here and above. If you
cfroussios 2016/06/16 12:29:09 Done.
391 return PERMANENT_FAIL;
473 392
474 return INIT_SUCCESS; 393 return INIT_SUCCESS;
475 } 394 }
476 395
477 password_manager::PasswordStoreChangeList NativeBackendKWallet::AddLogin( 396 password_manager::PasswordStoreChangeList NativeBackendKWallet::AddLogin(
478 const PasswordForm& form) { 397 const PasswordForm& form) {
479 int wallet_handle = WalletHandle(); 398 int wallet_handle = WalletHandle();
480 if (wallet_handle == kInvalidKWalletHandle) 399 if (wallet_handle == kInvalidKWalletHandle)
481 return password_manager::PasswordStoreChangeList(); 400 return password_manager::PasswordStoreChangeList();
482 401
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
631 return false; 550 return false;
632 return GetAllLoginsInternal(wallet_handle, forms); 551 return GetAllLoginsInternal(wallet_handle, forms);
633 } 552 }
634 553
635 bool NativeBackendKWallet::GetLoginsList( 554 bool NativeBackendKWallet::GetLoginsList(
636 const std::string& signon_realm, 555 const std::string& signon_realm,
637 int wallet_handle, 556 int wallet_handle,
638 ScopedVector<autofill::PasswordForm>* forms) { 557 ScopedVector<autofill::PasswordForm>* forms) {
639 forms->clear(); 558 forms->clear();
640 // Is there an entry in the wallet? 559 // Is there an entry in the wallet?
641 { 560 bool has_entry = false;
642 dbus::MethodCall method_call(kKWalletInterface, "hasEntry"); 561 KWalletDBus::Error error = kwallet_dbus_.HasEntry(
643 dbus::MessageWriter builder(&method_call); 562 &has_entry, wallet_handle, folder_name_, signon_realm, app_name_);
644 builder.AppendInt32(wallet_handle); // handle 563 if (error)
645 builder.AppendString(folder_name_); // folder 564 return false;
646 builder.AppendString(signon_realm); // key 565 if (!has_entry)
647 builder.AppendString(app_name_); // appid 566 return true;
648 std::unique_ptr<dbus::Response> response(kwallet_proxy_->CallMethodAndBlock( 567
649 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT)); 568 const uint8_t* bytes = nullptr;
650 if (!response.get()) { 569 size_t length = 0;
651 LOG(ERROR) << "Error contacting " << kwalletd_name_ << " (hasEntry)"; 570 error = kwallet_dbus_.ReadEntry(&bytes, &length, wallet_handle, folder_name_,
652 return false; 571 signon_realm, app_name_);
653 } 572 if (error)
654 dbus::MessageReader reader(response.get()); 573 return false;
655 bool has_entry = false; 574 if (!CheckSerializedValue(bytes, length, signon_realm)) {
656 if (!reader.PopBool(&has_entry)) { 575 // This is weird, but we choose not to call it an error. There is an
657 LOG(ERROR) << "Error reading response from " << kwalletd_name_ 576 // invalid entry somehow, but by just ignoring it, we make it easier to
658 << " (hasEntry): " << response->ToString(); 577 // repair without having to delete it using kwalletmanager (that is, by
659 return false; 578 // just saving a new password within this realm to overwrite it).
660 } 579 return true;
661 if (!has_entry) {
662 // This is not an error. There just isn't a matching entry.
663 return true;
664 }
665 } 580 }
666 581
667 { 582 // Can't we all just agree on whether bytes are signed or not? Please?
668 dbus::MethodCall method_call(kKWalletInterface, "readEntry"); 583 base::Pickle pickle(reinterpret_cast<const char*>(bytes), length);
vasilii 2016/06/10 16:58:10 Would static_cast works here?
cfroussios 2016/06/16 12:29:09 Compile-time error.
669 dbus::MessageWriter builder(&method_call); 584 *forms = DeserializeValue(signon_realm, pickle);
670 builder.AppendInt32(wallet_handle); // handle
671 builder.AppendString(folder_name_); // folder
672 builder.AppendString(signon_realm); // key
673 builder.AppendString(app_name_); // appid
674 std::unique_ptr<dbus::Response> response(kwallet_proxy_->CallMethodAndBlock(
675 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT));
676 if (!response.get()) {
677 LOG(ERROR) << "Error contacting " << kwalletd_name_ << " (readEntry)";
678 return false;
679 }
680 dbus::MessageReader reader(response.get());
681 const uint8_t* bytes = nullptr;
682 size_t length = 0;
683 if (!reader.PopArrayOfBytes(&bytes, &length)) {
684 LOG(ERROR) << "Error reading response from " << kwalletd_name_
685 << " (readEntry): " << response->ToString();
686 return false;
687 }
688 if (!bytes)
689 return false;
690 if (!CheckSerializedValue(bytes, length, signon_realm)) {
691 // This is weird, but we choose not to call it an error. There is an
692 // invalid entry somehow, but by just ignoring it, we make it easier to
693 // repair without having to delete it using kwalletmanager (that is, by
694 // just saving a new password within this realm to overwrite it).
695 return true;
696 }
697
698 // Can't we all just agree on whether bytes are signed or not? Please?
699 base::Pickle pickle(reinterpret_cast<const char*>(bytes), length);
700 *forms = DeserializeValue(signon_realm, pickle);
701 }
702 585
703 return true; 586 return true;
704 } 587 }
705 588
706 bool NativeBackendKWallet::GetLoginsList( 589 bool NativeBackendKWallet::GetLoginsList(
707 BlacklistOptions options, 590 BlacklistOptions options,
708 int wallet_handle, 591 int wallet_handle,
709 ScopedVector<autofill::PasswordForm>* forms) { 592 ScopedVector<autofill::PasswordForm>* forms) {
710 forms->clear(); 593 forms->clear();
711 ScopedVector<autofill::PasswordForm> all_forms; 594 ScopedVector<autofill::PasswordForm> all_forms;
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
748 631
749 return true; 632 return true;
750 } 633 }
751 634
752 bool NativeBackendKWallet::GetAllLoginsInternal( 635 bool NativeBackendKWallet::GetAllLoginsInternal(
753 int wallet_handle, 636 int wallet_handle,
754 ScopedVector<autofill::PasswordForm>* forms) { 637 ScopedVector<autofill::PasswordForm>* forms) {
755 // We could probably also use readEntryList here. 638 // We could probably also use readEntryList here.
756 std::vector<std::string> realm_list; 639 std::vector<std::string> realm_list;
757 { 640 {
758 dbus::MethodCall method_call(kKWalletInterface, "entryList"); 641 KWalletDBus::Error error = kwallet_dbus_.EntryList(
759 dbus::MessageWriter builder(&method_call); 642 &realm_list, wallet_handle, folder_name_, app_name_);
760 builder.AppendInt32(wallet_handle); // handle 643 if (error)
761 builder.AppendString(folder_name_); // folder
762 builder.AppendString(app_name_); // appid
763 std::unique_ptr<dbus::Response> response(kwallet_proxy_->CallMethodAndBlock(
764 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT));
765 if (!response.get()) {
766 LOG(ERROR) << "Error contacting " << kwalletd_name_ << " (entryList)";
767 return false; 644 return false;
768 }
769 dbus::MessageReader reader(response.get());
770 if (!reader.PopArrayOfStrings(&realm_list)) {
771 LOG(ERROR) << "Error reading response from " << kwalletd_name_
772 << "(entryList): " << response->ToString();
773 return false;
774 }
775 } 645 }
776 646
777 forms->clear(); 647 forms->clear();
778 for (const std::string& signon_realm : realm_list) { 648 for (const std::string& signon_realm : realm_list) {
779 dbus::MethodCall method_call(kKWalletInterface, "readEntry");
780 dbus::MessageWriter builder(&method_call);
781 builder.AppendInt32(wallet_handle); // handle
782 builder.AppendString(folder_name_); // folder
783 builder.AppendString(signon_realm); // key
784 builder.AppendString(app_name_); // appid
785 std::unique_ptr<dbus::Response> response(kwallet_proxy_->CallMethodAndBlock(
786 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT));
787 if (!response.get()) {
788 LOG(ERROR) << "Error contacting " << kwalletd_name_ << "(readEntry)";
789 return false;
790 }
791 dbus::MessageReader reader(response.get());
792 const uint8_t* bytes = nullptr; 649 const uint8_t* bytes = nullptr;
793 size_t length = 0; 650 size_t length = 0;
794 if (!reader.PopArrayOfBytes(&bytes, &length)) { 651 KWalletDBus::Error error = kwallet_dbus_.ReadEntry(
795 LOG(ERROR) << "Error reading response from " << kwalletd_name_ 652 &bytes, &length, wallet_handle, folder_name_, signon_realm, app_name_);
796 << " (readEntry): " << response->ToString(); 653 if (error)
797 return false; 654 return false;
798 }
799 if (!bytes || !CheckSerializedValue(bytes, length, signon_realm)) 655 if (!bytes || !CheckSerializedValue(bytes, length, signon_realm))
800 continue; 656 continue;
801 657
802 // Can't we all just agree on whether bytes are signed or not? Please? 658 // Can't we all just agree on whether bytes are signed or not? Please?
803 base::Pickle pickle(reinterpret_cast<const char*>(bytes), length); 659 base::Pickle pickle(reinterpret_cast<const char*>(bytes), length);
804 AppendSecondToFirst(forms, DeserializeValue(signon_realm, pickle)); 660 AppendSecondToFirst(forms, DeserializeValue(signon_realm, pickle));
805 } 661 }
806 return true; 662 return true;
807 } 663 }
808 664
809 bool NativeBackendKWallet::SetLoginsList( 665 bool NativeBackendKWallet::SetLoginsList(
810 const std::vector<autofill::PasswordForm*>& forms, 666 const std::vector<autofill::PasswordForm*>& forms,
811 const std::string& signon_realm, 667 const std::string& signon_realm,
812 int wallet_handle) { 668 int wallet_handle) {
813 if (forms.empty()) { 669 if (forms.empty()) {
814 // No items left? Remove the entry from the wallet. 670 int ret = 0;
815 dbus::MethodCall method_call(kKWalletInterface, "removeEntry"); 671 KWalletDBus::Error error = kwallet_dbus_.RemoveEntry(
816 dbus::MessageWriter builder(&method_call); 672 &ret, wallet_handle, folder_name_, signon_realm, app_name_);
817 builder.AppendInt32(wallet_handle); // handle 673 if (error == KWalletDBus::CANNOT_CONTACT)
818 builder.AppendString(folder_name_); // folder 674 // TODO(cfroussios) how does this make sense? kInvalidKWalletHandle == -1
vasilii 2016/06/10 16:58:10 nonsense.
cfroussios 2016/06/16 12:29:09 Done.
819 builder.AppendString(signon_realm); // key
820 builder.AppendString(app_name_); // appid
821 std::unique_ptr<dbus::Response> response(kwallet_proxy_->CallMethodAndBlock(
822 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT));
823 if (!response.get()) {
824 LOG(ERROR) << "Error contacting " << kwalletd_name_ << " (removeEntry)";
825 return kInvalidKWalletHandle; 675 return kInvalidKWalletHandle;
826 } 676 if (error == KWalletDBus::CANNOT_READ)
827 dbus::MessageReader reader(response.get());
828 int ret = 0;
829 if (!reader.PopInt32(&ret)) {
830 LOG(ERROR) << "Error reading response from " << kwalletd_name_
831 << " (removeEntry): " << response->ToString();
832 return false; 677 return false;
833 }
834 if (ret != 0) 678 if (ret != 0)
835 LOG(ERROR) << "Bad return code " << ret << " from KWallet removeEntry"; 679 LOG(ERROR) << "Bad return code " << ret << " from KWallet removeEntry";
836 return ret == 0; 680 return ret == 0;
837 } 681 }
838 682
839 base::Pickle value; 683 base::Pickle value;
840 SerializeValue(forms, &value); 684 SerializeValue(forms, &value);
841 685
842 dbus::MethodCall method_call(kKWalletInterface, "writeEntry"); 686 int ret = 0;
843 dbus::MessageWriter builder(&method_call); 687 KWalletDBus::Error error = kwallet_dbus_.WriteEntry(
844 builder.AppendInt32(wallet_handle); // handle 688 &ret, wallet_handle, folder_name_, signon_realm,
845 builder.AppendString(folder_name_); // folder 689 static_cast<const uint8_t*>(value.data()), value.size(), app_name_);
846 builder.AppendString(signon_realm); // key 690 if (error == KWalletDBus::CANNOT_CONTACT)
847 builder.AppendArrayOfBytes(static_cast<const uint8_t*>(value.data()),
848 value.size()); // value
849 builder.AppendString(app_name_); // appid
850 std::unique_ptr<dbus::Response> response(kwallet_proxy_->CallMethodAndBlock(
851 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT));
852 if (!response.get()) {
853 LOG(ERROR) << "Error contacting " << kwalletd_name_ << " (writeEntry)";
854 return kInvalidKWalletHandle; 691 return kInvalidKWalletHandle;
vasilii 2016/06/10 16:58:10 nonsense again
cfroussios 2016/06/16 12:29:09 Done.
855 } 692 if (error == KWalletDBus::CANNOT_READ)
856 dbus::MessageReader reader(response.get());
857 int ret = 0;
858 if (!reader.PopInt32(&ret)) {
859 LOG(ERROR) << "Error reading response from " << kwalletd_name_
860 << " (writeEntry): " << response->ToString();
861 return false; 693 return false;
862 }
863 if (ret != 0) 694 if (ret != 0)
864 LOG(ERROR) << "Bad return code " << ret << " from KWallet writeEntry"; 695 LOG(ERROR) << "Bad return code " << ret << " from KWallet writeEntry";
865 return ret == 0; 696 return ret == 0;
866 } 697 }
867 698
868 bool NativeBackendKWallet::RemoveLoginsBetween( 699 bool NativeBackendKWallet::RemoveLoginsBetween(
869 base::Time delete_begin, 700 base::Time delete_begin,
870 base::Time delete_end, 701 base::Time delete_end,
871 TimestampToCompare date_to_compare, 702 TimestampToCompare date_to_compare,
872 password_manager::PasswordStoreChangeList* changes) { 703 password_manager::PasswordStoreChangeList* changes) {
873 DCHECK(changes); 704 DCHECK(changes);
874 changes->clear(); 705 changes->clear();
875 int wallet_handle = WalletHandle(); 706 int wallet_handle = WalletHandle();
876 if (wallet_handle == kInvalidKWalletHandle) 707 if (wallet_handle == kInvalidKWalletHandle)
877 return false; 708 return false;
878 709
879 // We could probably also use readEntryList here. 710 // We could probably also use readEntryList here.
880 std::vector<std::string> realm_list; 711 std::vector<std::string> realm_list;
881 { 712 {
882 dbus::MethodCall method_call(kKWalletInterface, "entryList"); 713 KWalletDBus::Error error = kwallet_dbus_.EntryList(
883 dbus::MessageWriter builder(&method_call); 714 &realm_list, wallet_handle, folder_name_, app_name_);
884 builder.AppendInt32(wallet_handle); // handle 715 if (error)
885 builder.AppendString(folder_name_); // folder
886 builder.AppendString(app_name_); // appid
887 std::unique_ptr<dbus::Response> response(kwallet_proxy_->CallMethodAndBlock(
888 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT));
889 if (!response.get()) {
890 LOG(ERROR) << "Error contacting " << kwalletd_name_ << " (entryList)";
891 return false; 716 return false;
892 }
893 dbus::MessageReader reader(response.get());
894 dbus::MessageReader array(response.get());
895 if (!reader.PopArray(&array)) {
896 LOG(ERROR) << "Error reading response from " << kwalletd_name_
897 << " (entryList): " << response->ToString();
898 return false;
899 }
900 while (array.HasMoreData()) {
901 std::string realm;
902 if (!array.PopString(&realm)) {
903 LOG(ERROR) << "Error reading response from " << kwalletd_name_
904 << " (entryList): " << response->ToString();
905 return false;
906 }
907 realm_list.push_back(realm);
908 }
909 } 717 }
910 718
911 bool ok = true; 719 bool ok = true;
912 for (size_t i = 0; i < realm_list.size(); ++i) { 720 for (size_t i = 0; i < realm_list.size(); ++i) {
913 const std::string& signon_realm = realm_list[i]; 721 const std::string& signon_realm = realm_list[i];
914 dbus::MethodCall method_call(kKWalletInterface, "readEntry"); 722
915 dbus::MessageWriter builder(&method_call);
916 builder.AppendInt32(wallet_handle); // handle
917 builder.AppendString(folder_name_); // folder
918 builder.AppendString(signon_realm); // key
919 builder.AppendString(app_name_); // appid
920 std::unique_ptr<dbus::Response> response(kwallet_proxy_->CallMethodAndBlock(
921 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT));
922 if (!response.get()) {
923 LOG(ERROR) << "Error contacting " << kwalletd_name_ << " (readEntry)";
924 continue;
925 }
926 dbus::MessageReader reader(response.get());
927 const uint8_t* bytes = nullptr; 723 const uint8_t* bytes = nullptr;
928 size_t length = 0; 724 size_t length = 0;
929 if (!reader.PopArrayOfBytes(&bytes, &length)) { 725 KWalletDBus::Error error = kwallet_dbus_.ReadEntry(
930 LOG(ERROR) << "Error reading response from " << kwalletd_name_ 726 &bytes, &length, wallet_handle, folder_name_, signon_realm, app_name_);
931 << " (readEntry): " << response->ToString(); 727 if (error)
932 continue; 728 continue;
933 }
934 if (!bytes || !CheckSerializedValue(bytes, length, signon_realm)) 729 if (!bytes || !CheckSerializedValue(bytes, length, signon_realm))
935 continue; 730 continue;
936 731
937 // Can't we all just agree on whether bytes are signed or not? Please? 732 // Can't we all just agree on whether bytes are signed or not? Please?
938 base::Pickle pickle(reinterpret_cast<const char*>(bytes), length); 733 base::Pickle pickle(reinterpret_cast<const char*>(bytes), length);
939 ScopedVector<autofill::PasswordForm> all_forms = 734 ScopedVector<autofill::PasswordForm> all_forms =
940 DeserializeValue(signon_realm, pickle); 735 DeserializeValue(signon_realm, pickle);
941 736
942 ScopedVector<autofill::PasswordForm> kept_forms; 737 ScopedVector<autofill::PasswordForm> kept_forms;
943 kept_forms.reserve(all_forms.size()); 738 kept_forms.reserve(all_forms.size());
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1001 UMALogDeserializationStatus(success); 796 UMALogDeserializationStatus(success);
1002 return forms; 797 return forms;
1003 } 798 }
1004 799
1005 int NativeBackendKWallet::WalletHandle() { 800 int NativeBackendKWallet::WalletHandle() {
1006 DCHECK_CURRENTLY_ON(BrowserThread::DB); 801 DCHECK_CURRENTLY_ON(BrowserThread::DB);
1007 802
1008 // Open the wallet. 803 // Open the wallet.
1009 // TODO(mdm): Are we leaking these handles? Find out. 804 // TODO(mdm): Are we leaking these handles? Find out.
1010 int32_t handle = kInvalidKWalletHandle; 805 int32_t handle = kInvalidKWalletHandle;
1011 { 806 {
vasilii 2016/06/10 16:58:10 what is the point of those {} here and before?
cfroussios 2016/06/16 12:29:09 The previous author preferred scoping reappearing
1012 dbus::MethodCall method_call(kKWalletInterface, "open"); 807 KWalletDBus::Error error =
1013 dbus::MessageWriter builder(&method_call); 808 kwallet_dbus_.Open(&handle, wallet_name_, app_name_);
1014 builder.AppendString(wallet_name_); // wallet 809 if (error)
1015 builder.AppendInt64(0); // wid
1016 builder.AppendString(app_name_); // appid
1017 std::unique_ptr<dbus::Response> response(kwallet_proxy_->CallMethodAndBlock(
1018 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT));
1019 if (!response.get()) {
1020 LOG(ERROR) << "Error contacting " << kwalletd_name_ << " (open)";
1021 return kInvalidKWalletHandle; 810 return kInvalidKWalletHandle;
1022 }
1023 dbus::MessageReader reader(response.get());
1024 if (!reader.PopInt32(&handle)) {
1025 LOG(ERROR) << "Error reading response from " << kwalletd_name_
1026 << " (open): " << response->ToString();
1027 return kInvalidKWalletHandle;
1028 }
1029 if (handle == kInvalidKWalletHandle) { 811 if (handle == kInvalidKWalletHandle) {
1030 LOG(ERROR) << "Error obtaining KWallet handle"; 812 LOG(ERROR) << "Error obtaining KWallet handle";
1031 return kInvalidKWalletHandle; 813 return kInvalidKWalletHandle;
1032 } 814 }
1033 } 815 }
1034 816
1035 // Check if our folder exists. 817 // Check if our folder exists.
1036 bool has_folder = false; 818 bool has_folder = false;
1037 { 819 {
1038 dbus::MethodCall method_call(kKWalletInterface, "hasFolder"); 820 KWalletDBus::Error error =
1039 dbus::MessageWriter builder(&method_call); 821 kwallet_dbus_.HasFolder(&has_folder, handle, folder_name_, app_name_);
1040 builder.AppendInt32(handle); // handle 822 if (error)
1041 builder.AppendString(folder_name_); // folder
1042 builder.AppendString(app_name_); // appid
1043 std::unique_ptr<dbus::Response> response(kwallet_proxy_->CallMethodAndBlock(
1044 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT));
1045 if (!response.get()) {
1046 LOG(ERROR) << "Error contacting " << kwalletd_name_ << " (hasFolder)";
1047 return kInvalidKWalletHandle; 823 return kInvalidKWalletHandle;
1048 }
1049 dbus::MessageReader reader(response.get());
1050 if (!reader.PopBool(&has_folder)) {
1051 LOG(ERROR) << "Error reading response from " << kwalletd_name_
1052 << " (hasFolder): " << response->ToString();
1053 return kInvalidKWalletHandle;
1054 }
1055 } 824 }
1056 825
1057 // Create it if it didn't. 826 // Create it if it didn't.
1058 if (!has_folder) { 827 if (!has_folder) {
1059 dbus::MethodCall method_call(kKWalletInterface, "createFolder"); 828 bool success = false;
1060 dbus::MessageWriter builder(&method_call); 829 KWalletDBus::Error error =
1061 builder.AppendInt32(handle); // handle 830 kwallet_dbus_.CreateFolder(&success, handle, folder_name_, app_name_);
1062 builder.AppendString(folder_name_); // folder 831 if (error)
1063 builder.AppendString(app_name_); // appid
1064 std::unique_ptr<dbus::Response> response(kwallet_proxy_->CallMethodAndBlock(
1065 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT));
1066 if (!response.get()) {
1067 LOG(ERROR) << "Error contacting << " << kwalletd_name_
1068 << " (createFolder)";
1069 return kInvalidKWalletHandle; 832 return kInvalidKWalletHandle;
1070 }
1071 dbus::MessageReader reader(response.get());
1072 bool success = false;
1073 if (!reader.PopBool(&success)) {
1074 LOG(ERROR) << "Error reading response from " << kwalletd_name_
1075 << " (createFolder): " << response->ToString();
1076 return kInvalidKWalletHandle;
1077 }
1078 if (!success) { 833 if (!success) {
1079 LOG(ERROR) << "Error creating KWallet folder"; 834 LOG(ERROR) << "Error creating KWallet folder";
1080 return kInvalidKWalletHandle; 835 return kInvalidKWalletHandle;
1081 } 836 }
1082 } 837 }
1083 838
1084 return handle; 839 return handle;
1085 } 840 }
1086 841
1087 std::string NativeBackendKWallet::GetProfileSpecificFolderName() const { 842 std::string NativeBackendKWallet::GetProfileSpecificFolderName() const {
1088 // Originally, the folder name was always just "Chrome Form Data". 843 // Originally, the folder name was always just "Chrome Form Data".
1089 // Now we use it to distinguish passwords for different profiles. 844 // Now we use it to distinguish passwords for different profiles.
1090 return base::StringPrintf("%s (%d)", kKWalletFolder, profile_id_); 845 return base::StringPrintf("%s (%d)", kKWalletFolder, profile_id_);
1091 } 846 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698