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 namespace { | |
15 | |
16 #if defined(OFFICIAL_BUILD) | |
17 const char kFolderName[] = "Chrome Keys"; | |
Lei Zhang
2016/07/20 01:08:26
Any chance we can share these with the libsecret i
cfroussios
2016/07/20 15:22:46
I moved them to KeyStorageLinux, mostly because th
| |
18 const char kKey[] = "Chrome Safe Storage"; | |
19 #else | |
20 const char kFolderName[] = "Chromium Keys"; | |
21 const char kKey[] = "Chromium Safe Storage"; | |
22 #endif | |
23 | |
24 } // namespace | |
25 | |
26 KeyStorageKWallet::KeyStorageKWallet(base::nix::DesktopEnvironment desktop_env, | |
27 std::string app_name) | |
28 : desktop_env_(desktop_env), handle_(0), app_name_(std::move(app_name)) {} | |
Lei Zhang
2016/07/20 01:08:26
Should |handle_| be initialized to -1? Is 0 a vali
cfroussios
2016/07/20 15:22:46
Both are invalid values, but let's just use -1, si
| |
29 | |
30 KeyStorageKWallet::~KeyStorageKWallet() { | |
31 // The handle is shared between programs that are using the same wallet. | |
32 // Closing the wallet is a nop in the typical case. | |
33 bool success = true; | |
34 ignore_result(kwallet_dbus_->Close(handle_, false, app_name_, &success)); | |
35 kwallet_dbus_->GetSessionBus()->ShutdownAndBlock(); | |
36 } | |
37 | |
38 bool KeyStorageKWallet::Init() { | |
39 // Initialize using the production KWalletDBus. | |
40 return InitWithKWalletDBus(nullptr); | |
41 } | |
42 | |
43 bool KeyStorageKWallet::InitWithKWalletDBus( | |
44 std::unique_ptr<KWalletDBus> optional_kwallet_dbus_ptr) { | |
45 if (optional_kwallet_dbus_ptr) { | |
46 kwallet_dbus_ = std::move(optional_kwallet_dbus_ptr); | |
47 } else { | |
48 // Initializing with production KWalletDBus | |
49 kwallet_dbus_.reset(new KWalletDBus(desktop_env_)); | |
50 dbus::Bus::Options options; | |
51 options.bus_type = dbus::Bus::SESSION; | |
52 options.connection_type = dbus::Bus::PRIVATE; | |
53 kwallet_dbus_->SetSessionBus(new dbus::Bus(options)); | |
54 } | |
55 | |
56 // If KWallet might not have started, attempt to start it and retry. | |
57 InitResult result = InitWallet(); | |
58 if (result == InitResult::TEMPORARY_FAIL) | |
Lei Zhang
2016/07/20 01:08:26
if (result == InitResult::TEMPORARY_FAIL && kwalle
cfroussios
2016/07/20 15:22:46
I am not a big fan of conditions where the order o
Lei Zhang
2016/07/20 19:15:07
But ordering of execution in if statements do matt
cfroussios
2016/07/21 11:49:45
There might have been a miscommunication. I didn't
Lei Zhang
2016/07/21 21:07:39
My objection is also about readability, but I just
cfroussios
2016/07/22 11:25:25
"Every time I've seen code in Chrome" is not compa
| |
59 if (kwallet_dbus_->StartKWalletd()) | |
60 result = InitWallet(); | |
61 | |
62 return result == InitResult::SUCCESS; | |
63 } | |
64 | |
65 KeyStorageKWallet::InitResult KeyStorageKWallet::InitWallet() { | |
66 // Check that KWallet is enabled. | |
67 bool enabled = false; | |
68 KWalletDBus::Error error = kwallet_dbus_->IsEnabled(&enabled); | |
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 break; | |
76 } | |
77 if (!enabled) | |
78 return InitResult::PERMANENT_FAIL; | |
79 | |
80 // Get the wallet name. | |
81 error = kwallet_dbus_->NetworkWallet(&wallet_name_); | |
82 switch (error) { | |
83 case KWalletDBus::Error::CANNOT_CONTACT: | |
84 return InitResult::TEMPORARY_FAIL; | |
85 case KWalletDBus::Error::CANNOT_READ: | |
86 return InitResult::PERMANENT_FAIL; | |
87 case KWalletDBus::Error::SUCCESS: | |
88 return InitResult::SUCCESS; | |
89 } | |
90 | |
91 NOTREACHED(); | |
92 return InitResult::PERMANENT_FAIL; | |
93 } | |
94 | |
95 std::string KeyStorageKWallet::GetKey() { | |
96 // Get handle | |
97 KWalletDBus::Error error = | |
98 kwallet_dbus_->Open(wallet_name_, app_name_, &handle_); | |
99 if (error || handle_ == -1) | |
100 return std::string(); | |
101 | |
102 // Create folder | |
103 if (!InitFolder()) | |
104 return std::string(); | |
105 | |
106 // Read password | |
107 std::string password; | |
108 error = kwallet_dbus_->ReadPassword(handle_, kFolderName, kKey, app_name_, | |
109 &password); | |
110 if (error) | |
111 return std::string(); | |
112 | |
113 // If there is no entry, generate and write a new password. | |
114 if (password.empty()) { | |
115 base::Base64Encode(base::RandBytesAsString(16), &password); | |
116 bool success; | |
117 error = kwallet_dbus_->WritePassword(handle_, kFolderName, kKey, password, | |
118 app_name_, &success); | |
119 if (error || !success) | |
120 return std::string(); | |
121 } | |
122 | |
123 return password; | |
124 } | |
125 | |
126 bool KeyStorageKWallet::InitFolder() { | |
127 bool has_folder = false; | |
128 KWalletDBus::Error error = | |
129 kwallet_dbus_->HasFolder(handle_, kFolderName, app_name_, &has_folder); | |
130 if (error) | |
131 return false; | |
132 | |
133 if (!has_folder) { | |
134 bool success = false; | |
135 error = | |
136 kwallet_dbus_->CreateFolder(handle_, kFolderName, app_name_, &success); | |
137 if (error || !success) | |
138 return false; | |
139 } | |
140 | |
141 return true; | |
142 } | |
OLD | NEW |