OLD | NEW |
(Empty) | |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "components/os_crypt/key_storage_kwallet.h" |
| 6 |
| 7 #include <utility> |
| 8 |
| 9 #include "base/base64.h" |
| 10 #include "base/rand_util.h" |
| 11 #include "components/os_crypt/kwallet_dbus.h" |
| 12 #include "dbus/bus.h" |
| 13 |
| 14 KeyStorageKWallet::KeyStorageKWallet(base::nix::DesktopEnvironment desktop_env, |
| 15 std::string app_name) |
| 16 : desktop_env_(desktop_env), handle_(-1), app_name_(std::move(app_name)) {} |
| 17 |
| 18 KeyStorageKWallet::~KeyStorageKWallet() { |
| 19 // The handle is shared between programs that are using the same wallet. |
| 20 // Closing the wallet is a nop in the typical case. |
| 21 bool success = true; |
| 22 ignore_result(kwallet_dbus_->Close(handle_, false, app_name_, &success)); |
| 23 kwallet_dbus_->GetSessionBus()->ShutdownAndBlock(); |
| 24 } |
| 25 |
| 26 bool KeyStorageKWallet::Init() { |
| 27 // Initialize using the production KWalletDBus. |
| 28 return InitWithKWalletDBus(nullptr); |
| 29 } |
| 30 |
| 31 bool KeyStorageKWallet::InitWithKWalletDBus( |
| 32 std::unique_ptr<KWalletDBus> optional_kwallet_dbus_ptr) { |
| 33 if (optional_kwallet_dbus_ptr) { |
| 34 kwallet_dbus_ = std::move(optional_kwallet_dbus_ptr); |
| 35 } else { |
| 36 // Initializing with production KWalletDBus |
| 37 kwallet_dbus_.reset(new KWalletDBus(desktop_env_)); |
| 38 dbus::Bus::Options options; |
| 39 options.bus_type = dbus::Bus::SESSION; |
| 40 options.connection_type = dbus::Bus::PRIVATE; |
| 41 kwallet_dbus_->SetSessionBus(new dbus::Bus(options)); |
| 42 } |
| 43 |
| 44 // If KWallet might not have started, attempt to start it and retry. |
| 45 InitResult result = InitWallet(); |
| 46 if (result == InitResult::TEMPORARY_FAIL) |
| 47 if (kwallet_dbus_->StartKWalletd()) |
| 48 result = InitWallet(); |
| 49 |
| 50 return result == InitResult::SUCCESS; |
| 51 } |
| 52 |
| 53 KeyStorageKWallet::InitResult KeyStorageKWallet::InitWallet() { |
| 54 // Check that KWallet is enabled. |
| 55 bool enabled = false; |
| 56 KWalletDBus::Error error = kwallet_dbus_->IsEnabled(&enabled); |
| 57 switch (error) { |
| 58 case KWalletDBus::Error::CANNOT_CONTACT: |
| 59 return InitResult::TEMPORARY_FAIL; |
| 60 case KWalletDBus::Error::CANNOT_READ: |
| 61 return InitResult::PERMANENT_FAIL; |
| 62 case KWalletDBus::Error::SUCCESS: |
| 63 break; |
| 64 } |
| 65 if (!enabled) |
| 66 return InitResult::PERMANENT_FAIL; |
| 67 |
| 68 // Get the wallet name. |
| 69 error = kwallet_dbus_->NetworkWallet(&wallet_name_); |
| 70 switch (error) { |
| 71 case KWalletDBus::Error::CANNOT_CONTACT: |
| 72 return InitResult::TEMPORARY_FAIL; |
| 73 case KWalletDBus::Error::CANNOT_READ: |
| 74 return InitResult::PERMANENT_FAIL; |
| 75 case KWalletDBus::Error::SUCCESS: |
| 76 return InitResult::SUCCESS; |
| 77 } |
| 78 |
| 79 NOTREACHED(); |
| 80 return InitResult::PERMANENT_FAIL; |
| 81 } |
| 82 |
| 83 std::string KeyStorageKWallet::GetKey() { |
| 84 // Get handle |
| 85 KWalletDBus::Error error = |
| 86 kwallet_dbus_->Open(wallet_name_, app_name_, &handle_); |
| 87 if (error || handle_ == -1) |
| 88 return std::string(); |
| 89 |
| 90 // Create folder |
| 91 if (!InitFolder()) |
| 92 return std::string(); |
| 93 |
| 94 // Read password |
| 95 std::string password; |
| 96 error = |
| 97 kwallet_dbus_->ReadPassword(handle_, KeyStorageLinux::kFolderName, |
| 98 KeyStorageLinux::kKey, app_name_, &password); |
| 99 if (error) |
| 100 return std::string(); |
| 101 |
| 102 // If there is no entry, generate and write a new password. |
| 103 if (password.empty()) { |
| 104 base::Base64Encode(base::RandBytesAsString(16), &password); |
| 105 bool success; |
| 106 error = kwallet_dbus_->WritePassword(handle_, KeyStorageLinux::kFolderName, |
| 107 KeyStorageLinux::kKey, password, |
| 108 app_name_, &success); |
| 109 if (error || !success) |
| 110 return std::string(); |
| 111 } |
| 112 |
| 113 return password; |
| 114 } |
| 115 |
| 116 bool KeyStorageKWallet::InitFolder() { |
| 117 bool has_folder = false; |
| 118 KWalletDBus::Error error = kwallet_dbus_->HasFolder( |
| 119 handle_, KeyStorageLinux::kFolderName, app_name_, &has_folder); |
| 120 if (error) |
| 121 return false; |
| 122 |
| 123 if (!has_folder) { |
| 124 bool success = false; |
| 125 error = kwallet_dbus_->CreateFolder(handle_, KeyStorageLinux::kFolderName, |
| 126 app_name_, &success); |
| 127 if (error || !success) |
| 128 return false; |
| 129 } |
| 130 |
| 131 return true; |
| 132 } |
OLD | NEW |