| 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   InitResult result = InitWallet(); | 
 |   45   // If KWallet might not have started, attempt to start it and retry. | 
 |   46   if (result == InitResult::TEMPORARY_FAIL && kwallet_dbus_->StartKWalletd()) | 
 |   47     result = InitWallet(); | 
 |   48  | 
 |   49   return result == InitResult::SUCCESS; | 
 |   50 } | 
 |   51  | 
 |   52 KeyStorageKWallet::InitResult KeyStorageKWallet::InitWallet() { | 
 |   53   // Check that KWallet is enabled. | 
 |   54   bool enabled = false; | 
 |   55   KWalletDBus::Error error = kwallet_dbus_->IsEnabled(&enabled); | 
 |   56   switch (error) { | 
 |   57     case KWalletDBus::Error::CANNOT_CONTACT: | 
 |   58       return InitResult::TEMPORARY_FAIL; | 
 |   59     case KWalletDBus::Error::CANNOT_READ: | 
 |   60       return InitResult::PERMANENT_FAIL; | 
 |   61     case KWalletDBus::Error::SUCCESS: | 
 |   62       break; | 
 |   63   } | 
 |   64   if (!enabled) | 
 |   65     return InitResult::PERMANENT_FAIL; | 
 |   66  | 
 |   67   // Get the wallet name. | 
 |   68   error = kwallet_dbus_->NetworkWallet(&wallet_name_); | 
 |   69   switch (error) { | 
 |   70     case KWalletDBus::Error::CANNOT_CONTACT: | 
 |   71       return InitResult::TEMPORARY_FAIL; | 
 |   72     case KWalletDBus::Error::CANNOT_READ: | 
 |   73       return InitResult::PERMANENT_FAIL; | 
 |   74     case KWalletDBus::Error::SUCCESS: | 
 |   75       return InitResult::SUCCESS; | 
 |   76   } | 
 |   77  | 
 |   78   NOTREACHED(); | 
 |   79   return InitResult::PERMANENT_FAIL; | 
 |   80 } | 
 |   81  | 
 |   82 std::string KeyStorageKWallet::GetKey() { | 
 |   83   // Get handle | 
 |   84   KWalletDBus::Error error = | 
 |   85       kwallet_dbus_->Open(wallet_name_, app_name_, &handle_); | 
 |   86   if (error || handle_ == -1) | 
 |   87     return std::string(); | 
 |   88  | 
 |   89   // Create folder | 
 |   90   if (!InitFolder()) | 
 |   91     return std::string(); | 
 |   92  | 
 |   93   // Read password | 
 |   94   std::string password; | 
 |   95   error = | 
 |   96       kwallet_dbus_->ReadPassword(handle_, KeyStorageLinux::kFolderName, | 
 |   97                                   KeyStorageLinux::kKey, app_name_, &password); | 
 |   98   if (error) | 
 |   99     return std::string(); | 
 |  100  | 
 |  101   // If there is no entry, generate and write a new password. | 
 |  102   if (password.empty()) { | 
 |  103     base::Base64Encode(base::RandBytesAsString(16), &password); | 
 |  104     bool success; | 
 |  105     error = kwallet_dbus_->WritePassword(handle_, KeyStorageLinux::kFolderName, | 
 |  106                                          KeyStorageLinux::kKey, password, | 
 |  107                                          app_name_, &success); | 
 |  108     if (error || !success) | 
 |  109       return std::string(); | 
 |  110   } | 
 |  111  | 
 |  112   return password; | 
 |  113 } | 
 |  114  | 
 |  115 bool KeyStorageKWallet::InitFolder() { | 
 |  116   bool has_folder = false; | 
 |  117   KWalletDBus::Error error = kwallet_dbus_->HasFolder( | 
 |  118       handle_, KeyStorageLinux::kFolderName, app_name_, &has_folder); | 
 |  119   if (error) | 
 |  120     return false; | 
 |  121  | 
 |  122   if (!has_folder) { | 
 |  123     bool success = false; | 
 |  124     error = kwallet_dbus_->CreateFolder(handle_, KeyStorageLinux::kFolderName, | 
 |  125                                         app_name_, &success); | 
 |  126     if (error || !success) | 
 |  127       return false; | 
 |  128   } | 
 |  129  | 
 |  130   return true; | 
 |  131 } | 
| OLD | NEW |