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

Unified Diff: components/os_crypt/key_storage_kwallet.cc

Issue 2150543002: OSCrypt supports encryption with KWallet (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: feedback Created 4 years, 5 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 side-by-side diff with in-line comments
Download patch
Index: components/os_crypt/key_storage_kwallet.cc
diff --git a/components/os_crypt/key_storage_kwallet.cc b/components/os_crypt/key_storage_kwallet.cc
new file mode 100644
index 0000000000000000000000000000000000000000..b1d34cc5a974a83a4b1362d6c36eb0dd450d0ab9
--- /dev/null
+++ b/components/os_crypt/key_storage_kwallet.cc
@@ -0,0 +1,131 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/os_crypt/key_storage_kwallet.h"
+
+#include <utility>
+
+#include "base/base64.h"
+#include "base/rand_util.h"
+#include "components/os_crypt/kwallet_dbus.h"
+#include "dbus/bus.h"
+
+KeyStorageKWallet::KeyStorageKWallet(base::nix::DesktopEnvironment desktop_env,
+ std::string app_name)
+ : desktop_env_(desktop_env), handle_(-1), app_name_(std::move(app_name)) {}
+
+KeyStorageKWallet::~KeyStorageKWallet() {
+ // The handle is shared between programs that are using the same wallet.
+ // Closing the wallet is a nop in the typical case.
+ bool success = true;
+ ignore_result(kwallet_dbus_->Close(handle_, false, app_name_, &success));
+ kwallet_dbus_->GetSessionBus()->ShutdownAndBlock();
+}
+
+bool KeyStorageKWallet::Init() {
+ // Initialize using the production KWalletDBus.
+ return InitWithKWalletDBus(nullptr);
+}
+
+bool KeyStorageKWallet::InitWithKWalletDBus(
+ std::unique_ptr<KWalletDBus> optional_kwallet_dbus_ptr) {
+ if (optional_kwallet_dbus_ptr) {
+ kwallet_dbus_ = std::move(optional_kwallet_dbus_ptr);
+ } else {
+ // Initializing with production KWalletDBus
+ kwallet_dbus_.reset(new KWalletDBus(desktop_env_));
+ dbus::Bus::Options options;
+ options.bus_type = dbus::Bus::SESSION;
+ options.connection_type = dbus::Bus::PRIVATE;
+ kwallet_dbus_->SetSessionBus(new dbus::Bus(options));
+ }
+
+ InitResult result = InitWallet();
+ // If KWallet might not have started, attempt to start it and retry.
+ if (result == InitResult::TEMPORARY_FAIL && kwallet_dbus_->StartKWalletd())
+ result = InitWallet();
+
+ return result == InitResult::SUCCESS;
+}
+
+KeyStorageKWallet::InitResult KeyStorageKWallet::InitWallet() {
+ // Check that KWallet is enabled.
+ bool enabled = false;
+ KWalletDBus::Error error = kwallet_dbus_->IsEnabled(&enabled);
+ switch (error) {
+ case KWalletDBus::Error::CANNOT_CONTACT:
+ return InitResult::TEMPORARY_FAIL;
+ case KWalletDBus::Error::CANNOT_READ:
+ return InitResult::PERMANENT_FAIL;
+ case KWalletDBus::Error::SUCCESS:
+ break;
+ }
+ if (!enabled)
+ return InitResult::PERMANENT_FAIL;
+
+ // Get the wallet name.
+ error = kwallet_dbus_->NetworkWallet(&wallet_name_);
+ switch (error) {
+ case KWalletDBus::Error::CANNOT_CONTACT:
+ return InitResult::TEMPORARY_FAIL;
+ case KWalletDBus::Error::CANNOT_READ:
+ return InitResult::PERMANENT_FAIL;
+ case KWalletDBus::Error::SUCCESS:
+ return InitResult::SUCCESS;
+ }
+
+ NOTREACHED();
+ return InitResult::PERMANENT_FAIL;
+}
+
+std::string KeyStorageKWallet::GetKey() {
+ // Get handle
+ KWalletDBus::Error error =
+ kwallet_dbus_->Open(wallet_name_, app_name_, &handle_);
+ if (error || handle_ == -1)
+ return std::string();
+
+ // Create folder
+ if (!InitFolder())
+ return std::string();
+
+ // Read password
+ std::string password;
+ error =
+ kwallet_dbus_->ReadPassword(handle_, KeyStorageLinux::kFolderName,
+ KeyStorageLinux::kKey, app_name_, &password);
+ if (error)
+ return std::string();
+
+ // If there is no entry, generate and write a new password.
+ if (password.empty()) {
+ base::Base64Encode(base::RandBytesAsString(16), &password);
+ bool success;
+ error = kwallet_dbus_->WritePassword(handle_, KeyStorageLinux::kFolderName,
+ KeyStorageLinux::kKey, password,
+ app_name_, &success);
+ if (error || !success)
+ return std::string();
+ }
+
+ return password;
+}
+
+bool KeyStorageKWallet::InitFolder() {
+ bool has_folder = false;
+ KWalletDBus::Error error = kwallet_dbus_->HasFolder(
+ handle_, KeyStorageLinux::kFolderName, app_name_, &has_folder);
+ if (error)
+ return false;
+
+ if (!has_folder) {
+ bool success = false;
+ error = kwallet_dbus_->CreateFolder(handle_, KeyStorageLinux::kFolderName,
+ app_name_, &success);
+ if (error || !success)
+ return false;
+ }
+
+ return true;
+}

Powered by Google App Engine
This is Rietveld 408576698