Chromium Code Reviews| 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 <chrome/browser/password_manager/kwallet_dbus.h> | |
| 6 | |
| 7 #include <algorithm> | |
| 8 #include <memory> | |
| 9 | |
| 10 #include "base/logging.h" | |
| 11 #include "dbus/message.h" | |
| 12 #include "dbus/object_proxy.h" | |
| 13 | |
| 14 namespace { | |
| 15 | |
| 16 // DBus service, path, and interface names for klauncher and kwalletd. | |
| 17 const char kKWalletDName[] = "kwalletd"; | |
| 18 const char kKWalletD5Name[] = "kwalletd5"; | |
| 19 const char kKWalletServiceName[] = "org.kde.kwalletd"; | |
| 20 const char kKWallet5ServiceName[] = "org.kde.kwalletd5"; | |
| 21 const char kKWalletPath[] = "/modules/kwalletd"; | |
| 22 const char kKWallet5Path[] = "/modules/kwalletd5"; | |
| 23 const char kKWalletInterface[] = "org.kde.KWallet"; | |
| 24 const char kKLauncherServiceName[] = "org.kde.klauncher"; | |
| 25 const char kKLauncherPath[] = "/KLauncher"; | |
| 26 const char kKLauncherInterface[] = "org.kde.KLauncher"; | |
| 27 | |
| 28 } // namespace | |
| 29 | |
| 30 KWalletDBus::KWalletDBus(base::nix::DesktopEnvironment desktop_env) | |
| 31 : session_bus_(nullptr), kwallet_proxy_(nullptr) { | |
| 32 if (desktop_env == base::nix::DESKTOP_ENVIRONMENT_KDE5) { | |
| 33 dbus_service_name_ = kKWallet5ServiceName; | |
| 34 dbus_path_ = kKWallet5Path; | |
| 35 kwalletd_name_ = kKWalletD5Name; | |
| 36 } else { | |
| 37 dbus_service_name_ = kKWalletServiceName; | |
| 38 dbus_path_ = kKWalletPath; | |
| 39 kwalletd_name_ = kKWalletDName; | |
| 40 } | |
| 41 } | |
| 42 | |
| 43 KWalletDBus::~KWalletDBus() = default; | |
| 44 | |
| 45 dbus::Bus* KWalletDBus::GetSessionBus() { | |
| 46 return session_bus_.get(); | |
| 47 } | |
| 48 | |
| 49 void KWalletDBus::SetSessionBus(scoped_refptr<dbus::Bus> session_bus) { | |
| 50 session_bus_ = session_bus; | |
| 51 kwallet_proxy_ = session_bus_->GetObjectProxy(dbus_service_name_, | |
| 52 dbus::ObjectPath(dbus_path_)); | |
| 53 } | |
| 54 | |
| 55 bool KWalletDBus::StartKWalletd() { | |
| 56 dbus::ObjectProxy* klauncher = session_bus_->GetObjectProxy( | |
| 57 kKLauncherServiceName, dbus::ObjectPath(kKLauncherPath)); | |
| 58 | |
| 59 dbus::MethodCall method_call(kKLauncherInterface, | |
| 60 "start_service_by_desktop_name"); | |
| 61 dbus::MessageWriter builder(&method_call); | |
| 62 std::vector<std::string> empty; | |
| 63 builder.AppendString(kwalletd_name_); // serviceName | |
| 64 builder.AppendArrayOfStrings(empty); // urls | |
| 65 builder.AppendArrayOfStrings(empty); // envs | |
| 66 builder.AppendString(std::string()); // startup_id | |
| 67 builder.AppendBool(false); // blind | |
| 68 std::unique_ptr<dbus::Response> response(klauncher->CallMethodAndBlock( | |
| 69 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT)); | |
| 70 if (!response.get()) { | |
| 71 LOG(ERROR) << "Error contacting klauncher to start " << kwalletd_name_; | |
| 72 return false; | |
| 73 } | |
| 74 dbus::MessageReader reader(response.get()); | |
| 75 int32_t ret = -1; | |
| 76 std::string dbus_name; | |
| 77 std::string error; | |
| 78 int32_t pid = -1; | |
| 79 if (!reader.PopInt32(&ret) || !reader.PopString(&dbus_name) || | |
| 80 !reader.PopString(&error) || !reader.PopInt32(&pid)) { | |
| 81 LOG(ERROR) << "Error reading response from klauncher to start " | |
| 82 << kwalletd_name_ << ": " << response->ToString(); | |
| 83 return false; | |
| 84 } | |
| 85 if (!error.empty() || ret) { | |
| 86 LOG(ERROR) << "Error launching " << kwalletd_name_ << ": error '" << error | |
| 87 << "' (code " << ret << ")"; | |
| 88 return false; | |
| 89 } | |
| 90 | |
| 91 return true; | |
| 92 } | |
| 93 | |
| 94 KWalletDBus::Error KWalletDBus::IsEnabled(bool* enabled) { | |
| 95 dbus::MethodCall method_call(kKWalletInterface, "isEnabled"); | |
| 96 std::unique_ptr<dbus::Response> response(kwallet_proxy_->CallMethodAndBlock( | |
| 97 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT)); | |
| 98 if (!response.get()) { | |
| 99 LOG(ERROR) << "Error contacting " << kwalletd_name_ << " (isEnabled)"; | |
| 100 return CANNOT_CONTACT; | |
| 101 } | |
| 102 dbus::MessageReader reader(response.get()); | |
| 103 if (!reader.PopBool(enabled)) { | |
| 104 LOG(ERROR) << "Error reading response from " << kwalletd_name_ | |
| 105 << " (isEnabled): " << response->ToString(); | |
| 106 return CANNOT_READ; | |
| 107 } | |
| 108 // Not enabled? Don't use KWallet. But also don't warn here. | |
| 109 if (!enabled) { | |
| 110 VLOG(1) << kwalletd_name_ << " reports that KWallet is not enabled."; | |
| 111 } | |
| 112 | |
| 113 return SUCCESS; | |
| 114 } | |
| 115 | |
| 116 KWalletDBus::Error KWalletDBus::NetworkWallet(std::string* wallet_name) { | |
| 117 // Get the wallet name. | |
| 118 dbus::MethodCall method_call(kKWalletInterface, "networkWallet"); | |
| 119 std::unique_ptr<dbus::Response> response(kwallet_proxy_->CallMethodAndBlock( | |
| 120 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT)); | |
| 121 if (!response.get()) { | |
| 122 LOG(ERROR) << "Error contacting " << kwalletd_name_ << " (networkWallet)"; | |
| 123 return CANNOT_CONTACT; | |
| 124 } | |
| 125 dbus::MessageReader reader(response.get()); | |
| 126 if (!reader.PopString(wallet_name)) { | |
| 127 LOG(ERROR) << "Error reading response from " << kwalletd_name_ | |
| 128 << " (networkWallet): " << response->ToString(); | |
| 129 return CANNOT_READ; | |
| 130 } | |
| 131 | |
| 132 return SUCCESS; | |
| 133 } | |
| 134 | |
| 135 KWalletDBus::Error KWalletDBus::HasEntry(const int wallet_handle, | |
| 136 const std::string& folder_name, | |
| 137 const std::string& signon_realm, | |
| 138 const std::string& app_name, | |
| 139 bool* has_entry) { | |
| 140 dbus::MethodCall method_call(kKWalletInterface, "hasEntry"); | |
| 141 dbus::MessageWriter builder(&method_call); | |
| 142 builder.AppendInt32(wallet_handle); // handle | |
| 143 builder.AppendString(folder_name); // folder | |
| 144 builder.AppendString(signon_realm); // key | |
| 145 builder.AppendString(app_name); // appid | |
| 146 std::unique_ptr<dbus::Response> response(kwallet_proxy_->CallMethodAndBlock( | |
| 147 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT)); | |
| 148 if (!response.get()) { | |
| 149 LOG(ERROR) << "Error contacting " << kwalletd_name_ << " (hasEntry)"; | |
| 150 return CANNOT_CONTACT; | |
| 151 } | |
| 152 dbus::MessageReader reader(response.get()); | |
| 153 if (!reader.PopBool(has_entry)) { | |
| 154 LOG(ERROR) << "Error reading response from " << kwalletd_name_ | |
| 155 << " (hasEntry): " << response->ToString(); | |
| 156 return CANNOT_READ; | |
| 157 } | |
| 158 return SUCCESS; | |
| 159 } | |
| 160 | |
| 161 KWalletDBus::Error KWalletDBus::ReadEntry(const int wallet_handle, | |
| 162 const std::string& folder_name, | |
| 163 const std::string& signon_realm, | |
| 164 const std::string& app_name, | |
| 165 std::vector<uint8_t>* bytes_ptr) { | |
| 166 dbus::MethodCall method_call(kKWalletInterface, "readEntry"); | |
| 167 dbus::MessageWriter builder(&method_call); | |
| 168 builder.AppendInt32(wallet_handle); // handle | |
| 169 builder.AppendString(folder_name); // folder | |
| 170 builder.AppendString(signon_realm); // key | |
| 171 builder.AppendString(app_name); // appid | |
| 172 std::unique_ptr<dbus::Response> response(kwallet_proxy_->CallMethodAndBlock( | |
| 173 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT)); | |
| 174 if (!response.get()) { | |
| 175 LOG(ERROR) << "Error contacting " << kwalletd_name_ << " (readEntry)"; | |
| 176 return CANNOT_CONTACT; | |
| 177 } | |
| 178 size_t length = -1; | |
|
vasilii
2016/06/16 17:54:43
Why is so strange value?
cfroussios
2016/06/17 12:17:26
I initialize to invalid values to make more visibl
vasilii
2016/06/17 14:43:40
We don't want to fail more likely ;-) Also we don'
cfroussios
2016/06/20 13:00:43
Done.
| |
| 179 const uint8_t* bytes_temp = nullptr; | |
| 180 dbus::MessageReader reader(response.get()); | |
| 181 if (!reader.PopArrayOfBytes(&bytes_temp, &length)) { | |
| 182 LOG(ERROR) << "Error reading response from " << kwalletd_name_ | |
| 183 << " (readEntry): " << response->ToString(); | |
| 184 return CANNOT_READ; | |
| 185 } | |
| 186 if (bytes_temp) { | |
| 187 bytes_ptr->assign(bytes_temp, bytes_temp + length); | |
| 188 } else { | |
| 189 bytes_ptr->clear(); | |
| 190 } | |
| 191 return SUCCESS; | |
| 192 } | |
| 193 | |
| 194 KWalletDBus::Error KWalletDBus::EntryList( | |
| 195 const int wallet_handle, | |
| 196 const std::string& folder_name, | |
| 197 const std::string& app_name, | |
| 198 std::vector<std::string>* entry_list_ptr) { | |
| 199 dbus::MethodCall method_call(kKWalletInterface, "entryList"); | |
| 200 dbus::MessageWriter builder(&method_call); | |
| 201 builder.AppendInt32(wallet_handle); // handle | |
| 202 builder.AppendString(folder_name); // folder | |
| 203 builder.AppendString(app_name); // appid | |
| 204 std::unique_ptr<dbus::Response> response(kwallet_proxy_->CallMethodAndBlock( | |
| 205 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT)); | |
| 206 if (!response.get()) { | |
| 207 LOG(ERROR) << "Error contacting " << kwalletd_name_ << " (entryList)"; | |
| 208 return CANNOT_CONTACT; | |
| 209 } | |
| 210 dbus::MessageReader reader(response.get()); | |
| 211 if (!reader.PopArrayOfStrings(entry_list_ptr)) { | |
| 212 LOG(ERROR) << "Error reading response from " << kwalletd_name_ | |
| 213 << "(entryList): " << response->ToString(); | |
| 214 return CANNOT_READ; | |
| 215 } | |
| 216 return SUCCESS; | |
| 217 } | |
| 218 | |
| 219 KWalletDBus::Error KWalletDBus::RemoveEntry(const int wallet_handle, | |
| 220 const std::string& folder_name, | |
| 221 const std::string& signon_realm, | |
| 222 const std::string& app_name, | |
| 223 int* return_code_ptr) { | |
| 224 dbus::MethodCall method_call(kKWalletInterface, "removeEntry"); | |
| 225 dbus::MessageWriter builder(&method_call); | |
| 226 builder.AppendInt32(wallet_handle); // handle | |
| 227 builder.AppendString(folder_name); // folder | |
| 228 builder.AppendString(signon_realm); // key | |
| 229 builder.AppendString(app_name); // appid | |
| 230 std::unique_ptr<dbus::Response> response(kwallet_proxy_->CallMethodAndBlock( | |
| 231 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT)); | |
| 232 if (!response.get()) { | |
| 233 LOG(ERROR) << "Error contacting " << kwalletd_name_ << " (removeEntry)"; | |
| 234 return CANNOT_CONTACT; | |
| 235 } | |
| 236 dbus::MessageReader reader(response.get()); | |
| 237 if (!reader.PopInt32(return_code_ptr)) { | |
| 238 LOG(ERROR) << "Error reading response from " << kwalletd_name_ | |
| 239 << " (removeEntry): " << response->ToString(); | |
| 240 return CANNOT_READ; | |
| 241 } | |
| 242 return SUCCESS; | |
| 243 } | |
| 244 | |
| 245 KWalletDBus::Error KWalletDBus::WriteEntry(const int wallet_handle, | |
| 246 const std::string& folder_name, | |
| 247 const std::string& signon_realm, | |
| 248 const std::string& app_name, | |
| 249 const uint8_t* data, | |
| 250 const size_t length, | |
| 251 int* return_code_ptr) { | |
| 252 dbus::MethodCall method_call(kKWalletInterface, "writeEntry"); | |
| 253 dbus::MessageWriter builder(&method_call); | |
| 254 builder.AppendInt32(wallet_handle); // handle | |
| 255 builder.AppendString(folder_name); // folder | |
| 256 builder.AppendString(signon_realm); // key | |
| 257 builder.AppendArrayOfBytes(data, length); // value | |
| 258 builder.AppendString(app_name); // appid | |
| 259 std::unique_ptr<dbus::Response> response(kwallet_proxy_->CallMethodAndBlock( | |
| 260 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT)); | |
| 261 if (!response.get()) { | |
| 262 LOG(ERROR) << "Error contacting " << kwalletd_name_ << " (writeEntry)"; | |
| 263 return CANNOT_CONTACT; | |
| 264 } | |
| 265 dbus::MessageReader reader(response.get()); | |
| 266 if (!reader.PopInt32(return_code_ptr)) { | |
| 267 LOG(ERROR) << "Error reading response from " << kwalletd_name_ | |
| 268 << " (writeEntry): " << response->ToString(); | |
| 269 return CANNOT_READ; | |
| 270 } | |
| 271 return SUCCESS; | |
| 272 } | |
| 273 | |
| 274 KWalletDBus::Error KWalletDBus::Open(const std::string& wallet_name, | |
| 275 const std::string& app_name, | |
| 276 int* handle_ptr) { | |
| 277 dbus::MethodCall method_call(kKWalletInterface, "open"); | |
| 278 dbus::MessageWriter builder(&method_call); | |
| 279 builder.AppendString(wallet_name); // wallet | |
| 280 builder.AppendInt64(0); // wid | |
| 281 builder.AppendString(app_name); // appid | |
| 282 std::unique_ptr<dbus::Response> response(kwallet_proxy_->CallMethodAndBlock( | |
| 283 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT)); | |
| 284 if (!response.get()) { | |
| 285 LOG(ERROR) << "Error contacting " << kwalletd_name_ << " (open)"; | |
| 286 return CANNOT_CONTACT; | |
| 287 } | |
| 288 dbus::MessageReader reader(response.get()); | |
| 289 if (!reader.PopInt32(handle_ptr)) { | |
| 290 LOG(ERROR) << "Error reading response from " << kwalletd_name_ | |
| 291 << " (open): " << response->ToString(); | |
| 292 return CANNOT_READ; | |
| 293 } | |
| 294 return SUCCESS; | |
| 295 } | |
| 296 | |
| 297 KWalletDBus::Error KWalletDBus::HasFolder(const int handle, | |
| 298 const std::string& folder_name, | |
| 299 const std::string& app_name, | |
| 300 bool* has_folder_ptr) { | |
| 301 dbus::MethodCall method_call(kKWalletInterface, "hasFolder"); | |
| 302 dbus::MessageWriter builder(&method_call); | |
| 303 builder.AppendInt32(handle); // handle | |
| 304 builder.AppendString(folder_name); // folder | |
| 305 builder.AppendString(app_name); // appid | |
| 306 std::unique_ptr<dbus::Response> response(kwallet_proxy_->CallMethodAndBlock( | |
| 307 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT)); | |
| 308 if (!response.get()) { | |
| 309 LOG(ERROR) << "Error contacting " << kwalletd_name_ << " (hasFolder)"; | |
| 310 return CANNOT_CONTACT; | |
| 311 } | |
| 312 dbus::MessageReader reader(response.get()); | |
| 313 if (!reader.PopBool(has_folder_ptr)) { | |
| 314 LOG(ERROR) << "Error reading response from " << kwalletd_name_ | |
| 315 << " (hasFolder): " << response->ToString(); | |
| 316 return CANNOT_READ; | |
| 317 } | |
| 318 return SUCCESS; | |
| 319 } | |
| 320 | |
| 321 KWalletDBus::Error KWalletDBus::CreateFolder(const int handle, | |
| 322 const std::string& folder_name, | |
| 323 const std::string& app_name, | |
| 324 bool* success_ptr) { | |
| 325 dbus::MethodCall method_call(kKWalletInterface, "createFolder"); | |
| 326 dbus::MessageWriter builder(&method_call); | |
| 327 builder.AppendInt32(handle); // handle | |
| 328 builder.AppendString(folder_name); // folder | |
| 329 builder.AppendString(app_name); // appid | |
| 330 std::unique_ptr<dbus::Response> response(kwallet_proxy_->CallMethodAndBlock( | |
| 331 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT)); | |
| 332 if (!response.get()) { | |
| 333 LOG(ERROR) << "Error contacting << " << kwalletd_name_ << " (createFolder)"; | |
| 334 return CANNOT_CONTACT; | |
| 335 } | |
| 336 dbus::MessageReader reader(response.get()); | |
| 337 if (!reader.PopBool(success_ptr)) { | |
| 338 LOG(ERROR) << "Error reading response from " << kwalletd_name_ | |
| 339 << " (createFolder): " << response->ToString(); | |
| 340 return CANNOT_READ; | |
| 341 } | |
| 342 return SUCCESS; | |
| 343 } | |
| OLD | NEW |