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