OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/password_manager/native_backend_kwallet_x.h" | 5 #include "chrome/browser/password_manager/native_backend_kwallet_x.h" |
6 | 6 |
7 #include <sstream> | 7 #include <vector> |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/pickle.h" | 10 #include "base/pickle.h" |
11 #include "base/stl_util.h" | 11 #include "base/stl_util.h" |
12 #include "base/stringprintf.h" | 12 #include "base/stringprintf.h" |
| 13 #include "base/synchronization/waitable_event.h" |
13 #include "content/browser/browser_thread.h" | 14 #include "content/browser/browser_thread.h" |
| 15 #include "dbus/bus.h" |
| 16 #include "dbus/message.h" |
| 17 #include "dbus/object_proxy.h" |
14 #include "grit/chromium_strings.h" | 18 #include "grit/chromium_strings.h" |
15 #include "ui/base/l10n/l10n_util.h" | 19 #include "ui/base/l10n/l10n_util.h" |
16 | 20 |
17 using std::string; | |
18 using std::vector; | |
19 using webkit_glue::PasswordForm; | 21 using webkit_glue::PasswordForm; |
20 | 22 |
21 // We could localize this string, but then changing your locale would cause | 23 // We could localize this string, but then changing your locale would cause |
22 // you to lose access to all your stored passwords. Maybe best not to do that. | 24 // you to lose access to all your stored passwords. Maybe best not to do that. |
23 const char NativeBackendKWallet::kKWalletFolder[] = "Chrome Form Data"; | 25 const char NativeBackendKWallet::kKWalletFolder[] = "Chrome Form Data"; |
24 | 26 |
25 const char NativeBackendKWallet::kKWalletServiceName[] = "org.kde.kwalletd"; | 27 const char NativeBackendKWallet::kKWalletServiceName[] = "org.kde.kwalletd"; |
26 const char NativeBackendKWallet::kKWalletPath[] = "/modules/kwalletd"; | 28 const char NativeBackendKWallet::kKWalletPath[] = "/modules/kwalletd"; |
27 const char NativeBackendKWallet::kKWalletInterface[] = "org.kde.KWallet"; | 29 const char NativeBackendKWallet::kKWalletInterface[] = "org.kde.KWallet"; |
28 const char NativeBackendKWallet::kKLauncherServiceName[] = "org.kde.klauncher"; | 30 const char NativeBackendKWallet::kKLauncherServiceName[] = "org.kde.klauncher"; |
29 const char NativeBackendKWallet::kKLauncherPath[] = "/KLauncher"; | 31 const char NativeBackendKWallet::kKLauncherPath[] = "/KLauncher"; |
30 const char NativeBackendKWallet::kKLauncherInterface[] = "org.kde.KLauncher"; | 32 const char NativeBackendKWallet::kKLauncherInterface[] = "org.kde.KLauncher"; |
31 | 33 |
32 NativeBackendKWallet::NativeBackendKWallet(LocalProfileId id, | 34 NativeBackendKWallet::NativeBackendKWallet(LocalProfileId id, |
33 PrefService* prefs) | 35 PrefService* prefs) |
34 : profile_id_(id), prefs_(prefs), | 36 : profile_id_(id), prefs_(prefs), |
35 error_(NULL), connection_(NULL), proxy_(NULL), | |
36 app_name_(l10n_util::GetStringUTF8(IDS_PRODUCT_NAME)) { | 37 app_name_(l10n_util::GetStringUTF8(IDS_PRODUCT_NAME)) { |
37 if (PasswordStoreX::PasswordsUseLocalProfileId(prefs)) { | 38 if (PasswordStoreX::PasswordsUseLocalProfileId(prefs)) { |
38 folder_name_ = GetProfileSpecificFolderName(); | 39 folder_name_ = GetProfileSpecificFolderName(); |
39 // We already did the migration previously. Don't try again. | 40 // We already did the migration previously. Don't try again. |
40 migrate_tried_ = true; | 41 migrate_tried_ = true; |
41 } else { | 42 } else { |
42 folder_name_ = kKWalletFolder; | 43 folder_name_ = kKWalletFolder; |
43 migrate_tried_ = false; | 44 migrate_tried_ = false; |
44 } | 45 } |
45 } | 46 } |
46 | 47 |
47 NativeBackendKWallet::~NativeBackendKWallet() { | 48 NativeBackendKWallet::~NativeBackendKWallet() { |
48 if (proxy_) | 49 // This destructor is called on the thread that is destroying the Profile |
49 g_object_unref(proxy_); | 50 // containing the PasswordStore that owns this NativeBackend. Generally that |
| 51 // won't be the DB thread; it will be the UI thread. So we post a message to |
| 52 // shut it down on the DB thread, and it will be destructed afterward when the |
| 53 // scoped_refptr<dbus::Bus> goes out of scope. The NativeBackend will be |
| 54 // destroyed before that occurs, but that's OK. |
| 55 if (session_bus_.get()) { |
| 56 BrowserThread::PostTask(BrowserThread::DB, FROM_HERE, |
| 57 NewRunnableMethod( |
| 58 session_bus_.get(), |
| 59 &dbus::Bus::ShutdownAndBlock)); |
| 60 } |
50 } | 61 } |
51 | 62 |
52 bool NativeBackendKWallet::Init() { | 63 bool NativeBackendKWallet::Init() { |
53 // Get a connection to the session bus. | 64 // We must synchronously do a few DBus calls to figure out if initialization |
54 connection_ = dbus_g_bus_get(DBUS_BUS_SESSION, &error_); | 65 // succeeds, but later, we'll want to do most work on the DB thread. So we |
55 if (CheckError()) | 66 // have to do the initialization on the DB thread here too, and wait for it. |
| 67 scoped_refptr<dbus::Bus> optional_bus; // Will construct its own. |
| 68 bool success = false; |
| 69 base::WaitableEvent event(false, false); |
| 70 BrowserThread::PostTask(BrowserThread::DB, FROM_HERE, |
| 71 NewRunnableMethod( |
| 72 this, &NativeBackendKWallet::InitWithBus, |
| 73 optional_bus, &event, &success)); |
| 74 event.Wait(); |
| 75 return success; |
| 76 } |
| 77 |
| 78 // NativeBackendKWallet isn't reference counted, but the one place we post a |
| 79 // message to it (in InitWithBus below) waits for the task to run. So we can |
| 80 // disable needing reference counting safely here. |
| 81 template<> |
| 82 struct RunnableMethodTraits<NativeBackendKWallet> { |
| 83 void RetainCallee(NativeBackendKWallet*) {} |
| 84 void ReleaseCallee(NativeBackendKWallet*) {} |
| 85 }; |
| 86 |
| 87 void NativeBackendKWallet::InitWithBus(scoped_refptr<dbus::Bus> optional_bus, |
| 88 base::WaitableEvent* event, |
| 89 bool* success) { |
| 90 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); |
| 91 DCHECK(!session_bus_.get()); |
| 92 if (optional_bus.get()) { |
| 93 // The optional_bus parameter is given when this method is called in tests. |
| 94 session_bus_ = optional_bus; |
| 95 } else { |
| 96 // Get a (real) connection to the session bus. |
| 97 dbus::Bus::Options options; |
| 98 options.bus_type = dbus::Bus::SESSION; |
| 99 options.connection_type = dbus::Bus::PRIVATE; |
| 100 session_bus_ = new dbus::Bus(options); |
| 101 } |
| 102 kwallet_proxy_ = |
| 103 session_bus_->GetObjectProxy(kKWalletServiceName, kKWalletPath); |
| 104 // kwalletd may not be running. If it fails to initialize, try to start it |
| 105 // and then try to initialize it again. (Note the short-circuit evaluation.) |
| 106 *success = (InitWallet() || (StartKWalletd() && InitWallet())); |
| 107 if (event) |
| 108 event->Signal(); |
| 109 } |
| 110 |
| 111 bool NativeBackendKWallet::StartKWalletd() { |
| 112 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); |
| 113 // Sadly kwalletd doesn't use DBus activation, so we have to make a call to |
| 114 // klauncher to start it. |
| 115 dbus::ObjectProxy* klauncher = |
| 116 session_bus_->GetObjectProxy(kKLauncherServiceName, kKLauncherPath); |
| 117 |
| 118 dbus::MethodCall method_call(kKLauncherInterface, |
| 119 "start_service_by_desktop_name"); |
| 120 dbus::MessageWriter builder(&method_call); |
| 121 dbus::MessageWriter empty(&method_call); |
| 122 builder.AppendString("kwalletd"); // serviceName |
| 123 builder.OpenArray("s", &empty); // urls |
| 124 builder.CloseContainer(&empty); |
| 125 builder.OpenArray("s", &empty); // envs |
| 126 builder.CloseContainer(&empty); |
| 127 builder.AppendString(""); // startup_id |
| 128 builder.AppendBool(false); // blind |
| 129 scoped_ptr<dbus::Response> response( |
| 130 klauncher->CallMethodAndBlock( |
| 131 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT)); |
| 132 if (!response.get()) { |
| 133 LOG(ERROR) << "Error contacting klauncher to start kwalletd"; |
56 return false; | 134 return false; |
57 | 135 } |
58 if (!InitWallet()) { | 136 dbus::MessageReader reader(response.get()); |
59 // kwalletd may not be running. Try to start it and try again. | 137 int32_t ret = -1; |
60 if (!StartKWalletd() || !InitWallet()) | 138 std::string dbus_name; |
61 return false; | 139 std::string error; |
| 140 int32_t pid = -1; |
| 141 if (!reader.PopInt32(&ret) || !reader.PopString(&dbus_name) || |
| 142 !reader.PopString(&error) || !reader.PopInt32(&pid)) { |
| 143 LOG(ERROR) << "Error reading response from klauncher to start kwalletd: " |
| 144 << response->ToString(); |
| 145 return false; |
| 146 } |
| 147 if (!error.empty() || ret) { |
| 148 LOG(ERROR) << "Error launching kwalletd: error '" << error << "' " |
| 149 << " (code " << ret << ")"; |
| 150 return false; |
62 } | 151 } |
63 | 152 |
64 return true; | 153 return true; |
65 } | 154 } |
66 | 155 |
67 bool NativeBackendKWallet::StartKWalletd() { | 156 bool NativeBackendKWallet::InitWallet() { |
68 // Sadly kwalletd doesn't use DBUS activation, so we have to make a call to | 157 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); |
69 // klauncher to start it. | 158 { |
70 DBusGProxy* klauncher_proxy = | 159 // Check that KWallet is enabled. |
71 dbus_g_proxy_new_for_name(connection_, kKLauncherServiceName, | 160 dbus::MethodCall method_call(kKWalletInterface, "isEnabled"); |
72 kKLauncherPath, kKLauncherInterface); | 161 scoped_ptr<dbus::Response> response( |
73 | 162 kwallet_proxy_->CallMethodAndBlock( |
74 char* empty_string_list = NULL; | 163 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT)); |
75 int ret = 1; | 164 if (!response.get()) { |
76 char* error = NULL; | 165 LOG(ERROR) << "Error contacting kwalletd (isEnabled)"; |
77 dbus_g_proxy_call(klauncher_proxy, "start_service_by_desktop_name", &error_, | 166 return false; |
78 G_TYPE_STRING, "kwalletd", // serviceName | 167 } |
79 G_TYPE_STRV, &empty_string_list, // urls | 168 dbus::MessageReader reader(response.get()); |
80 G_TYPE_STRV, &empty_string_list, // envs | 169 bool enabled = false; |
81 G_TYPE_STRING, "", // startup_id | 170 if (!reader.PopBool(&enabled)) { |
82 G_TYPE_BOOLEAN, (gboolean) false, // blind | 171 LOG(ERROR) << "Error reading response from kwalletd (isEnabled): " |
83 G_TYPE_INVALID, | 172 << response->ToString(); |
84 G_TYPE_INT, &ret, // result | 173 return false; |
85 G_TYPE_STRING, NULL, // dubsName | 174 } |
86 G_TYPE_STRING, &error, // error | 175 // Not enabled? Don't use KWallet. But also don't warn here. |
87 G_TYPE_INT, NULL, // pid | 176 if (!enabled) { |
88 G_TYPE_INVALID); | 177 VLOG(1) << "kwalletd reports that KWallet is not enabled."; |
89 | 178 return false; |
90 if (error && *error) { | 179 } |
91 LOG(ERROR) << "Error launching kwalletd: " << error; | |
92 ret = 1; // Make sure we return false after freeing. | |
93 } | 180 } |
94 | 181 |
95 g_free(error); | 182 { |
96 g_object_unref(klauncher_proxy); | 183 // Get the wallet name. |
97 | 184 dbus::MethodCall method_call(kKWalletInterface, "networkWallet"); |
98 if (CheckError() || ret != 0) | 185 scoped_ptr<dbus::Response> response( |
99 return false; | 186 kwallet_proxy_->CallMethodAndBlock( |
100 return true; | 187 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT)); |
101 } | 188 if (!response.get()) { |
102 | 189 LOG(ERROR) << "Error contacting kwalletd (networkWallet)"; |
103 bool NativeBackendKWallet::InitWallet() { | 190 return false; |
104 // Make a proxy to KWallet. | 191 } |
105 proxy_ = dbus_g_proxy_new_for_name(connection_, kKWalletServiceName, | 192 dbus::MessageReader reader(response.get()); |
106 kKWalletPath, kKWalletInterface); | 193 if (!reader.PopString(&wallet_name_)) { |
107 | 194 LOG(ERROR) << "Error reading response from kwalletd (networkWallet): " |
108 // Check KWallet is enabled. | 195 << response->ToString(); |
109 gboolean is_enabled = false; | 196 return false; |
110 dbus_g_proxy_call(proxy_, "isEnabled", &error_, | 197 } |
111 G_TYPE_INVALID, | 198 } |
112 G_TYPE_BOOLEAN, &is_enabled, | |
113 G_TYPE_INVALID); | |
114 if (CheckError() || !is_enabled) | |
115 return false; | |
116 | |
117 // Get the wallet name. | |
118 char* wallet_name = NULL; | |
119 dbus_g_proxy_call(proxy_, "networkWallet", &error_, | |
120 G_TYPE_INVALID, | |
121 G_TYPE_STRING, &wallet_name, | |
122 G_TYPE_INVALID); | |
123 if (CheckError() || !wallet_name) | |
124 return false; | |
125 | |
126 wallet_name_.assign(wallet_name); | |
127 g_free(wallet_name); | |
128 | 199 |
129 return true; | 200 return true; |
130 } | 201 } |
131 | 202 |
132 bool NativeBackendKWallet::AddLogin(const PasswordForm& form) { | 203 bool NativeBackendKWallet::AddLogin(const PasswordForm& form) { |
133 int wallet_handle = WalletHandle(); | 204 int wallet_handle = WalletHandle(); |
134 if (wallet_handle == kInvalidKWalletHandle) | 205 if (wallet_handle == kInvalidKWalletHandle) |
135 return false; | 206 return false; |
136 | 207 |
137 PasswordFormList forms; | 208 PasswordFormList forms; |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
202 } | 273 } |
203 | 274 |
204 bool NativeBackendKWallet::RemoveLoginsCreatedBetween( | 275 bool NativeBackendKWallet::RemoveLoginsCreatedBetween( |
205 const base::Time& delete_begin, | 276 const base::Time& delete_begin, |
206 const base::Time& delete_end) { | 277 const base::Time& delete_end) { |
207 int wallet_handle = WalletHandle(); | 278 int wallet_handle = WalletHandle(); |
208 if (wallet_handle == kInvalidKWalletHandle) | 279 if (wallet_handle == kInvalidKWalletHandle) |
209 return false; | 280 return false; |
210 | 281 |
211 // We could probably also use readEntryList here. | 282 // We could probably also use readEntryList here. |
212 char** realm_list = NULL; | 283 std::vector<std::string> realm_list; |
213 dbus_g_proxy_call(proxy_, "entryList", &error_, | 284 { |
214 G_TYPE_INT, wallet_handle, // handle | 285 dbus::MethodCall method_call(kKWalletInterface, "entryList"); |
215 G_TYPE_STRING, folder_name_.c_str(), // folder | 286 dbus::MessageWriter builder(&method_call); |
216 G_TYPE_STRING, app_name_.c_str(), // appid | 287 builder.AppendInt32(wallet_handle); // handle |
217 G_TYPE_INVALID, | 288 builder.AppendString(folder_name_); // folder |
218 G_TYPE_STRV, &realm_list, | 289 builder.AppendString(app_name_); // appid |
219 G_TYPE_INVALID); | 290 scoped_ptr<dbus::Response> response( |
220 if (CheckError()) | 291 kwallet_proxy_->CallMethodAndBlock( |
221 return false; | 292 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT)); |
| 293 if (!response.get()) { |
| 294 LOG(ERROR) << "Error contacting kwalletd (entryList)"; |
| 295 return false; |
| 296 } |
| 297 dbus::MessageReader reader(response.get()); |
| 298 dbus::MessageReader array(response.get()); |
| 299 if (!reader.PopArray(&array)) { |
| 300 LOG(ERROR) << "Error reading response from kwalletd (entryList): " |
| 301 << response->ToString(); |
| 302 return false; |
| 303 } |
| 304 while (array.HasMoreData()) { |
| 305 std::string realm; |
| 306 if (!array.PopString(&realm)) { |
| 307 LOG(ERROR) << "Error reading response from kwalletd (entryList): " |
| 308 << response->ToString(); |
| 309 return false; |
| 310 } |
| 311 realm_list.push_back(realm); |
| 312 } |
| 313 } |
222 | 314 |
223 bool ok = true; | 315 bool ok = true; |
224 for (char** realm = realm_list; *realm; ++realm) { | 316 for (size_t i = 0; i < realm_list.size(); ++i) { |
225 GArray* byte_array = NULL; | 317 const std::string& signon_realm = realm_list[i]; |
226 dbus_g_proxy_call(proxy_, "readEntry", &error_, | 318 dbus::MethodCall method_call(kKWalletInterface, "readEntry"); |
227 G_TYPE_INT, wallet_handle, // handle | 319 dbus::MessageWriter builder(&method_call); |
228 G_TYPE_STRING, folder_name_.c_str(), // folder | 320 builder.AppendInt32(wallet_handle); // handle |
229 G_TYPE_STRING, *realm, // key | 321 builder.AppendString(folder_name_); // folder |
230 G_TYPE_STRING, app_name_.c_str(), // appid | 322 builder.AppendString(signon_realm); // key |
231 G_TYPE_INVALID, | 323 builder.AppendString(app_name_); // appid |
232 DBUS_TYPE_G_UCHAR_ARRAY, &byte_array, | 324 scoped_ptr<dbus::Response> response( |
233 G_TYPE_INVALID); | 325 kwallet_proxy_->CallMethodAndBlock( |
234 | 326 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT)); |
235 if (CheckError() || !byte_array || | 327 if (!response.get()) { |
236 !CheckSerializedValue(byte_array, *realm)) { | 328 LOG(ERROR) << "Error contacting kwalletd (readEntry)"; |
237 continue; | 329 continue; |
238 } | 330 } |
| 331 dbus::MessageReader reader(response.get()); |
| 332 uint8_t* bytes = NULL; |
| 333 size_t length = 0; |
| 334 if (!reader.PopArrayOfBytes(&bytes, &length)) { |
| 335 LOG(ERROR) << "Error reading response from kwalletd (readEntry): " |
| 336 << response->ToString(); |
| 337 continue; |
| 338 } |
| 339 if (!bytes || !CheckSerializedValue(bytes, length, signon_realm)) |
| 340 continue; |
239 | 341 |
240 string signon_realm(*realm); | 342 // Can't we all just agree on whether bytes are signed or not? Please? |
241 Pickle pickle(byte_array->data, byte_array->len); | 343 Pickle pickle(reinterpret_cast<const char*>(bytes), length); |
242 PasswordFormList all_forms; | 344 PasswordFormList all_forms; |
243 DeserializeValue(signon_realm, pickle, &all_forms); | 345 DeserializeValue(signon_realm, pickle, &all_forms); |
244 g_array_free(byte_array, true); | |
245 | 346 |
246 PasswordFormList kept_forms; | 347 PasswordFormList kept_forms; |
247 kept_forms.reserve(all_forms.size()); | 348 kept_forms.reserve(all_forms.size()); |
248 for (size_t i = 0; i < all_forms.size(); ++i) { | 349 for (size_t i = 0; i < all_forms.size(); ++i) { |
249 if (delete_begin <= all_forms[i]->date_created && | 350 if (delete_begin <= all_forms[i]->date_created && |
250 (delete_end.is_null() || all_forms[i]->date_created < delete_end)) { | 351 (delete_end.is_null() || all_forms[i]->date_created < delete_end)) { |
251 delete all_forms[i]; | 352 delete all_forms[i]; |
252 } else { | 353 } else { |
253 kept_forms.push_back(all_forms[i]); | 354 kept_forms.push_back(all_forms[i]); |
254 } | 355 } |
255 } | 356 } |
256 | 357 |
257 if (!SetLoginsList(kept_forms, signon_realm, wallet_handle)) | 358 if (!SetLoginsList(kept_forms, signon_realm, wallet_handle)) |
258 ok = false; | 359 ok = false; |
259 STLDeleteElements(&kept_forms); | 360 STLDeleteElements(&kept_forms); |
260 } | 361 } |
261 g_strfreev(realm_list); | |
262 return ok; | 362 return ok; |
263 } | 363 } |
264 | 364 |
265 bool NativeBackendKWallet::GetLogins(const PasswordForm& form, | 365 bool NativeBackendKWallet::GetLogins(const PasswordForm& form, |
266 PasswordFormList* forms) { | 366 PasswordFormList* forms) { |
267 int wallet_handle = WalletHandle(); | 367 int wallet_handle = WalletHandle(); |
268 if (wallet_handle == kInvalidKWalletHandle) | 368 if (wallet_handle == kInvalidKWalletHandle) |
269 return false; | 369 return false; |
270 return GetLoginsList(forms, form.signon_realm, wallet_handle); | 370 return GetLoginsList(forms, form.signon_realm, wallet_handle); |
271 } | 371 } |
(...skipping 15 matching lines...) Expand all Loading... |
287 } | 387 } |
288 | 388 |
289 bool NativeBackendKWallet::GetBlacklistLogins(PasswordFormList* forms) { | 389 bool NativeBackendKWallet::GetBlacklistLogins(PasswordFormList* forms) { |
290 int wallet_handle = WalletHandle(); | 390 int wallet_handle = WalletHandle(); |
291 if (wallet_handle == kInvalidKWalletHandle) | 391 if (wallet_handle == kInvalidKWalletHandle) |
292 return false; | 392 return false; |
293 return GetLoginsList(forms, false, wallet_handle); | 393 return GetLoginsList(forms, false, wallet_handle); |
294 } | 394 } |
295 | 395 |
296 bool NativeBackendKWallet::GetLoginsList(PasswordFormList* forms, | 396 bool NativeBackendKWallet::GetLoginsList(PasswordFormList* forms, |
297 const string& signon_realm, | 397 const std::string& signon_realm, |
298 int wallet_handle) { | 398 int wallet_handle) { |
299 // Is there an entry in the wallet? | 399 // Is there an entry in the wallet? |
300 gboolean has_entry = false; | 400 { |
301 dbus_g_proxy_call(proxy_, "hasEntry", &error_, | 401 dbus::MethodCall method_call(kKWalletInterface, "hasEntry"); |
302 G_TYPE_INT, wallet_handle, // handle | 402 dbus::MessageWriter builder(&method_call); |
303 G_TYPE_STRING, folder_name_.c_str(), // folder | 403 builder.AppendInt32(wallet_handle); // handle |
304 G_TYPE_STRING, signon_realm.c_str(), // key | 404 builder.AppendString(folder_name_); // folder |
305 G_TYPE_STRING, app_name_.c_str(), // appid | 405 builder.AppendString(signon_realm); // key |
306 G_TYPE_INVALID, | 406 builder.AppendString(app_name_); // appid |
307 G_TYPE_BOOLEAN, &has_entry, | 407 scoped_ptr<dbus::Response> response( |
308 G_TYPE_INVALID); | 408 kwallet_proxy_->CallMethodAndBlock( |
309 | 409 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT)); |
310 if (CheckError()) | 410 if (!response.get()) { |
311 return false; | 411 LOG(ERROR) << "Error contacting kwalletd (hasEntry)"; |
312 if (!has_entry) { | 412 return false; |
313 // This is not an error. There just isn't a matching entry. | 413 } |
314 return true; | 414 dbus::MessageReader reader(response.get()); |
| 415 bool has_entry = false; |
| 416 if (!reader.PopBool(&has_entry)) { |
| 417 LOG(ERROR) << "Error reading response from kwalletd (hasEntry): " |
| 418 << response->ToString(); |
| 419 return false; |
| 420 } |
| 421 if (!has_entry) { |
| 422 // This is not an error. There just isn't a matching entry. |
| 423 return true; |
| 424 } |
315 } | 425 } |
316 | 426 |
317 GArray* byte_array = NULL; | 427 { |
318 dbus_g_proxy_call(proxy_, "readEntry", &error_, | 428 dbus::MethodCall method_call(kKWalletInterface, "readEntry"); |
319 G_TYPE_INT, wallet_handle, // handle | 429 dbus::MessageWriter builder(&method_call); |
320 G_TYPE_STRING, folder_name_.c_str(), // folder | 430 builder.AppendInt32(wallet_handle); // handle |
321 G_TYPE_STRING, signon_realm.c_str(), // key | 431 builder.AppendString(folder_name_); // folder |
322 G_TYPE_STRING, app_name_.c_str(), // appid | 432 builder.AppendString(signon_realm); // key |
323 G_TYPE_INVALID, | 433 builder.AppendString(app_name_); // appid |
324 DBUS_TYPE_G_UCHAR_ARRAY, &byte_array, | 434 scoped_ptr<dbus::Response> response( |
325 G_TYPE_INVALID); | 435 kwallet_proxy_->CallMethodAndBlock( |
| 436 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT)); |
| 437 if (!response.get()) { |
| 438 LOG(ERROR) << "Error contacting kwalletd (readEntry)"; |
| 439 return false; |
| 440 } |
| 441 dbus::MessageReader reader(response.get()); |
| 442 uint8_t* bytes = NULL; |
| 443 size_t length = 0; |
| 444 if (!reader.PopArrayOfBytes(&bytes, &length)) { |
| 445 LOG(ERROR) << "Error reading response from kwalletd (readEntry): " |
| 446 << response->ToString(); |
| 447 return false; |
| 448 } |
| 449 if (!bytes) |
| 450 return false; |
| 451 if (!CheckSerializedValue(bytes, length, signon_realm)) { |
| 452 // This is weird, but we choose not to call it an error. There is an |
| 453 // invalid entry somehow, but by just ignoring it, we make it easier to |
| 454 // repair without having to delete it using kwalletmanager (that is, by |
| 455 // just saving a new password within this realm to overwrite it). |
| 456 return true; |
| 457 } |
326 | 458 |
327 if (CheckError() || !byte_array) | 459 // Can't we all just agree on whether bytes are signed or not? Please? |
328 return false; | 460 Pickle pickle(reinterpret_cast<const char*>(bytes), length); |
329 if (!CheckSerializedValue(byte_array, signon_realm.c_str())) { | 461 PasswordFormList all_forms; |
330 // This is weird, but we choose not to call it an error. There's an invalid | 462 DeserializeValue(signon_realm, pickle, forms); |
331 // entry somehow, but by pretending it just doesn't exist, we make it easier | |
332 // to repair without having to delete it using kwalletmanager (that is, by | |
333 // just saving a new password within this realm to overwrite it). | |
334 g_array_free(byte_array, true); | |
335 return true; | |
336 } | 463 } |
337 | 464 |
338 Pickle pickle(byte_array->data, byte_array->len); | |
339 DeserializeValue(signon_realm, pickle, forms); | |
340 g_array_free(byte_array, true); | |
341 | |
342 return true; | 465 return true; |
343 } | 466 } |
344 | 467 |
345 bool NativeBackendKWallet::GetLoginsList(PasswordFormList* forms, | 468 bool NativeBackendKWallet::GetLoginsList(PasswordFormList* forms, |
346 bool autofillable, | 469 bool autofillable, |
347 int wallet_handle) { | 470 int wallet_handle) { |
348 PasswordFormList all_forms; | 471 PasswordFormList all_forms; |
349 if (!GetAllLogins(&all_forms, wallet_handle)) | 472 if (!GetAllLogins(&all_forms, wallet_handle)) |
350 return false; | 473 return false; |
351 | 474 |
(...skipping 27 matching lines...) Expand all Loading... |
379 delete all_forms[i]; | 502 delete all_forms[i]; |
380 } | 503 } |
381 } | 504 } |
382 | 505 |
383 return true; | 506 return true; |
384 } | 507 } |
385 | 508 |
386 bool NativeBackendKWallet::GetAllLogins(PasswordFormList* forms, | 509 bool NativeBackendKWallet::GetAllLogins(PasswordFormList* forms, |
387 int wallet_handle) { | 510 int wallet_handle) { |
388 // We could probably also use readEntryList here. | 511 // We could probably also use readEntryList here. |
389 char** realm_list = NULL; | 512 std::vector<std::string> realm_list; |
390 dbus_g_proxy_call(proxy_, "entryList", &error_, | 513 { |
391 G_TYPE_INT, wallet_handle, // handle | 514 dbus::MethodCall method_call(kKWalletInterface, "entryList"); |
392 G_TYPE_STRING, folder_name_.c_str(), // folder | 515 dbus::MessageWriter builder(&method_call); |
393 G_TYPE_STRING, app_name_.c_str(), // appid | 516 builder.AppendInt32(wallet_handle); // handle |
394 G_TYPE_INVALID, | 517 builder.AppendString(folder_name_); // folder |
395 G_TYPE_STRV, &realm_list, | 518 builder.AppendString(app_name_); // appid |
396 G_TYPE_INVALID); | 519 scoped_ptr<dbus::Response> response( |
397 if (CheckError()) | 520 kwallet_proxy_->CallMethodAndBlock( |
398 return false; | 521 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT)); |
| 522 if (!response.get()) { |
| 523 LOG(ERROR) << "Error contacting kwalletd (entryList)"; |
| 524 return false; |
| 525 } |
| 526 dbus::MessageReader reader(response.get()); |
| 527 dbus::MessageReader array(response.get()); |
| 528 if (!reader.PopArray(&array)) { |
| 529 LOG(ERROR) << "Error reading response from kwalletd (entryList): " |
| 530 << response->ToString(); |
| 531 return false; |
| 532 } |
| 533 while (array.HasMoreData()) { |
| 534 std::string realm; |
| 535 if (!array.PopString(&realm)) { |
| 536 LOG(ERROR) << "Error reading response from kwalletd (entryList): " |
| 537 << response->ToString(); |
| 538 return false; |
| 539 } |
| 540 realm_list.push_back(realm); |
| 541 } |
| 542 } |
399 | 543 |
400 for (char** realm = realm_list; *realm; ++realm) { | 544 for (size_t i = 0; i < realm_list.size(); ++i) { |
401 GArray* byte_array = NULL; | 545 const std::string& signon_realm = realm_list[i]; |
402 dbus_g_proxy_call(proxy_, "readEntry", &error_, | 546 dbus::MethodCall method_call(kKWalletInterface, "readEntry"); |
403 G_TYPE_INT, wallet_handle, // handle | 547 dbus::MessageWriter builder(&method_call); |
404 G_TYPE_STRING, folder_name_.c_str(), // folder | 548 builder.AppendInt32(wallet_handle); // handle |
405 G_TYPE_STRING, *realm, // key | 549 builder.AppendString(folder_name_); // folder |
406 G_TYPE_STRING, app_name_.c_str(), // appid | 550 builder.AppendString(signon_realm); // key |
407 G_TYPE_INVALID, | 551 builder.AppendString(app_name_); // appid |
408 DBUS_TYPE_G_UCHAR_ARRAY, &byte_array, | 552 scoped_ptr<dbus::Response> response( |
409 G_TYPE_INVALID); | 553 kwallet_proxy_->CallMethodAndBlock( |
410 | 554 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT)); |
411 if (CheckError() || !byte_array || | 555 if (!response.get()) { |
412 !CheckSerializedValue(byte_array, *realm)) { | 556 LOG(ERROR) << "Error contacting kwalletd (readEntry)"; |
413 continue; | 557 continue; |
414 } | 558 } |
| 559 dbus::MessageReader reader(response.get()); |
| 560 uint8_t* bytes = NULL; |
| 561 size_t length = 0; |
| 562 if (!reader.PopArrayOfBytes(&bytes, &length)) { |
| 563 LOG(ERROR) << "Error reading response from kwalletd (readEntry): " |
| 564 << response->ToString(); |
| 565 continue; |
| 566 } |
| 567 if (!bytes || !CheckSerializedValue(bytes, length, signon_realm)) |
| 568 continue; |
415 | 569 |
416 Pickle pickle(byte_array->data, byte_array->len); | 570 // Can't we all just agree on whether bytes are signed or not? Please? |
417 DeserializeValue(*realm, pickle, forms); | 571 Pickle pickle(reinterpret_cast<const char*>(bytes), length); |
418 g_array_free(byte_array, true); | 572 PasswordFormList all_forms; |
| 573 DeserializeValue(signon_realm, pickle, forms); |
419 } | 574 } |
420 g_strfreev(realm_list); | |
421 return true; | 575 return true; |
422 } | 576 } |
423 | 577 |
424 bool NativeBackendKWallet::SetLoginsList(const PasswordFormList& forms, | 578 bool NativeBackendKWallet::SetLoginsList(const PasswordFormList& forms, |
425 const string& signon_realm, | 579 const std::string& signon_realm, |
426 int wallet_handle) { | 580 int wallet_handle) { |
427 if (forms.empty()) { | 581 if (forms.empty()) { |
428 // No items left? Remove the entry from the wallet. | 582 // No items left? Remove the entry from the wallet. |
| 583 dbus::MethodCall method_call(kKWalletInterface, "removeEntry"); |
| 584 dbus::MessageWriter builder(&method_call); |
| 585 builder.AppendInt32(wallet_handle); // handle |
| 586 builder.AppendString(folder_name_); // folder |
| 587 builder.AppendString(signon_realm); // key |
| 588 builder.AppendString(app_name_); // appid |
| 589 scoped_ptr<dbus::Response> response( |
| 590 kwallet_proxy_->CallMethodAndBlock( |
| 591 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT)); |
| 592 if (!response.get()) { |
| 593 LOG(ERROR) << "Error contacting kwalletd (removeEntry)"; |
| 594 return kInvalidKWalletHandle; |
| 595 } |
| 596 dbus::MessageReader reader(response.get()); |
429 int ret = 0; | 597 int ret = 0; |
430 dbus_g_proxy_call(proxy_, "removeEntry", &error_, | 598 if (!reader.PopInt32(&ret)) { |
431 G_TYPE_INT, wallet_handle, // handle | 599 LOG(ERROR) << "Error reading response from kwalletd (removeEntry): " |
432 G_TYPE_STRING, folder_name_.c_str(), // folder | 600 << response->ToString(); |
433 G_TYPE_STRING, signon_realm.c_str(), // key | |
434 G_TYPE_STRING, app_name_.c_str(), // appid | |
435 G_TYPE_INVALID, | |
436 G_TYPE_INT, &ret, | |
437 G_TYPE_INVALID); | |
438 if (CheckError()) | |
439 return false; | 601 return false; |
| 602 } |
440 if (ret != 0) | 603 if (ret != 0) |
441 LOG(ERROR) << "Bad return code " << ret << " from KWallet removeEntry"; | 604 LOG(ERROR) << "Bad return code " << ret << " from KWallet removeEntry"; |
442 return ret == 0; | 605 return ret == 0; |
443 } | 606 } |
444 | 607 |
445 Pickle value; | 608 Pickle value; |
446 SerializeValue(forms, &value); | 609 SerializeValue(forms, &value); |
447 | 610 |
448 // Convert the pickled bytes to a GByteArray. | 611 dbus::MethodCall method_call(kKWalletInterface, "writeEntry"); |
449 GArray* byte_array = g_array_sized_new(false, false, sizeof(char), | 612 dbus::MessageWriter builder(&method_call); |
450 value.size()); | 613 builder.AppendInt32(wallet_handle); // handle |
451 g_array_append_vals(byte_array, value.data(), value.size()); | 614 builder.AppendString(folder_name_); // folder |
452 | 615 builder.AppendString(signon_realm); // key |
453 // Make the call. | 616 builder.AppendArrayOfBytes(static_cast<const uint8_t*>(value.data()), |
| 617 value.size()); // value |
| 618 builder.AppendString(app_name_); // appid |
| 619 scoped_ptr<dbus::Response> response( |
| 620 kwallet_proxy_->CallMethodAndBlock( |
| 621 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT)); |
| 622 if (!response.get()) { |
| 623 LOG(ERROR) << "Error contacting kwalletd (writeEntry)"; |
| 624 return kInvalidKWalletHandle; |
| 625 } |
| 626 dbus::MessageReader reader(response.get()); |
454 int ret = 0; | 627 int ret = 0; |
455 dbus_g_proxy_call(proxy_, "writeEntry", &error_, | 628 if (!reader.PopInt32(&ret)) { |
456 G_TYPE_INT, wallet_handle, // handle | 629 LOG(ERROR) << "Error reading response from kwalletd (writeEntry): " |
457 G_TYPE_STRING, folder_name_.c_str(), // folder | 630 << response->ToString(); |
458 G_TYPE_STRING, signon_realm.c_str(), // key | |
459 DBUS_TYPE_G_UCHAR_ARRAY, byte_array, // value | |
460 G_TYPE_STRING, app_name_.c_str(), // appid | |
461 G_TYPE_INVALID, | |
462 G_TYPE_INT, &ret, | |
463 G_TYPE_INVALID); | |
464 g_array_free(byte_array, true); | |
465 | |
466 if (CheckError()) | |
467 return false; | 631 return false; |
| 632 } |
468 if (ret != 0) | 633 if (ret != 0) |
469 LOG(ERROR) << "Bad return code " << ret << " from KWallet writeEntry"; | 634 LOG(ERROR) << "Bad return code " << ret << " from KWallet writeEntry"; |
470 return ret == 0; | 635 return ret == 0; |
471 } | 636 } |
472 | 637 |
473 bool NativeBackendKWallet::CompareForms(const PasswordForm& a, | 638 bool NativeBackendKWallet::CompareForms(const PasswordForm& a, |
474 const PasswordForm& b, | 639 const PasswordForm& b, |
475 bool update_check) { | 640 bool update_check) { |
476 // An update check doesn't care about the submit element. | 641 // An update check doesn't care about the submit element. |
477 if (!update_check && a.submit_element != b.submit_element) | 642 if (!update_check && a.submit_element != b.submit_element) |
(...skipping 20 matching lines...) Expand all Loading... |
498 pickle->WriteString16(form->password_element); | 663 pickle->WriteString16(form->password_element); |
499 pickle->WriteString16(form->password_value); | 664 pickle->WriteString16(form->password_value); |
500 pickle->WriteString16(form->submit_element); | 665 pickle->WriteString16(form->submit_element); |
501 pickle->WriteBool(form->ssl_valid); | 666 pickle->WriteBool(form->ssl_valid); |
502 pickle->WriteBool(form->preferred); | 667 pickle->WriteBool(form->preferred); |
503 pickle->WriteBool(form->blacklisted_by_user); | 668 pickle->WriteBool(form->blacklisted_by_user); |
504 pickle->WriteInt64(form->date_created.ToTimeT()); | 669 pickle->WriteInt64(form->date_created.ToTimeT()); |
505 } | 670 } |
506 } | 671 } |
507 | 672 |
508 bool NativeBackendKWallet::CheckSerializedValue(const GArray* byte_array, | 673 bool NativeBackendKWallet::CheckSerializedValue(const uint8_t* byte_array, |
509 const char* realm) { | 674 size_t length, |
| 675 const std::string& realm) { |
510 const Pickle::Header* header = | 676 const Pickle::Header* header = |
511 reinterpret_cast<const Pickle::Header*>(byte_array->data); | 677 reinterpret_cast<const Pickle::Header*>(byte_array); |
512 if (byte_array->len < sizeof(*header) || | 678 if (length < sizeof(*header) || |
513 header->payload_size > byte_array->len - sizeof(*header)) { | 679 header->payload_size > length - sizeof(*header)) { |
514 LOG(WARNING) << "Invalid KWallet entry detected (realm: " << realm << ")"; | 680 LOG(WARNING) << "Invalid KWallet entry detected (realm: " << realm << ")"; |
515 return false; | 681 return false; |
516 } | 682 } |
517 return true; | 683 return true; |
518 } | 684 } |
519 | 685 |
520 void NativeBackendKWallet::DeserializeValue(const string& signon_realm, | 686 void NativeBackendKWallet::DeserializeValue(const std::string& signon_realm, |
521 const Pickle& pickle, | 687 const Pickle& pickle, |
522 PasswordFormList* forms) { | 688 PasswordFormList* forms) { |
523 void* iter = NULL; | 689 void* iter = NULL; |
524 | 690 |
525 int version = -1; | 691 int version = -1; |
526 if (!pickle.ReadInt(&iter, &version) || version != kPickleVersion) { | 692 if (!pickle.ReadInt(&iter, &version) || version != kPickleVersion) { |
527 // This is the only version so far, so anything else is an error. | 693 // This is the only version so far, so anything else is an error. |
528 LOG(ERROR) << "Failed to deserialize KWallet entry " | 694 LOG(ERROR) << "Failed to deserialize KWallet entry " |
529 << "(realm: " << signon_realm << ")"; | 695 << "(realm: " << signon_realm << ")"; |
530 return; | 696 return; |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
572 break; | 738 break; |
573 } | 739 } |
574 form->scheme = static_cast<PasswordForm::Scheme>(scheme); | 740 form->scheme = static_cast<PasswordForm::Scheme>(scheme); |
575 form->date_created = base::Time::FromTimeT(date_created); | 741 form->date_created = base::Time::FromTimeT(date_created); |
576 forms->push_back(form.release()); | 742 forms->push_back(form.release()); |
577 } | 743 } |
578 } | 744 } |
579 | 745 |
580 bool NativeBackendKWallet::ReadGURL(const Pickle& pickle, void** iter, | 746 bool NativeBackendKWallet::ReadGURL(const Pickle& pickle, void** iter, |
581 GURL* url) { | 747 GURL* url) { |
582 string url_string; | 748 std::string url_string; |
583 if (!pickle.ReadString(iter, &url_string)) { | 749 if (!pickle.ReadString(iter, &url_string)) { |
584 LOG(ERROR) << "Failed to deserialize URL"; | 750 LOG(ERROR) << "Failed to deserialize URL"; |
585 *url = GURL(); | 751 *url = GURL(); |
586 return false; | 752 return false; |
587 } | 753 } |
588 *url = GURL(url_string); | 754 *url = GURL(url_string); |
589 return true; | 755 return true; |
590 } | 756 } |
591 | 757 |
592 bool NativeBackendKWallet::CheckError() { | |
593 if (error_) { | |
594 LOG(ERROR) << "Failed to complete KWallet call: " << error_->message; | |
595 g_error_free(error_); | |
596 error_ = NULL; | |
597 return true; | |
598 } | |
599 return false; | |
600 } | |
601 | |
602 int NativeBackendKWallet::WalletHandle() { | 758 int NativeBackendKWallet::WalletHandle() { |
603 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); | 759 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); |
| 760 |
604 // Open the wallet. | 761 // Open the wallet. |
605 // TODO(mdm): Are we leaking these handles? Find out. | 762 // TODO(mdm): Are we leaking these handles? Find out. |
606 int handle = kInvalidKWalletHandle; | 763 int32_t handle = kInvalidKWalletHandle; |
607 dbus_g_proxy_call(proxy_, "open", &error_, | 764 { |
608 G_TYPE_STRING, wallet_name_.c_str(), // wallet | 765 dbus::MethodCall method_call(kKWalletInterface, "open"); |
609 G_TYPE_INT64, 0LL, // wid | 766 dbus::MessageWriter builder(&method_call); |
610 G_TYPE_STRING, app_name_.c_str(), // appid | 767 builder.AppendString(wallet_name_); // wallet |
611 G_TYPE_INVALID, | 768 builder.AppendInt64(0); // wid |
612 G_TYPE_INT, &handle, | 769 builder.AppendString(app_name_); // appid |
613 G_TYPE_INVALID); | 770 scoped_ptr<dbus::Response> response( |
614 if (CheckError() || handle == kInvalidKWalletHandle) | 771 kwallet_proxy_->CallMethodAndBlock( |
615 return kInvalidKWalletHandle; | 772 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT)); |
| 773 if (!response.get()) { |
| 774 LOG(ERROR) << "Error contacting kwalletd (open)"; |
| 775 return kInvalidKWalletHandle; |
| 776 } |
| 777 dbus::MessageReader reader(response.get()); |
| 778 if (!reader.PopInt32(&handle)) { |
| 779 LOG(ERROR) << "Error reading response from kwalletd (open): " |
| 780 << response->ToString(); |
| 781 return kInvalidKWalletHandle; |
| 782 } |
| 783 if (handle == kInvalidKWalletHandle) { |
| 784 LOG(ERROR) << "Error obtaining KWallet handle"; |
| 785 return kInvalidKWalletHandle; |
| 786 } |
| 787 } |
616 | 788 |
617 // Check if our folder exists. | 789 // Check if our folder exists. |
618 gboolean has_folder = false; | 790 bool has_folder = false; |
619 dbus_g_proxy_call(proxy_, "hasFolder", &error_, | 791 { |
620 G_TYPE_INT, handle, // handle | 792 dbus::MethodCall method_call(kKWalletInterface, "hasFolder"); |
621 G_TYPE_STRING, folder_name_.c_str(), // folder | 793 dbus::MessageWriter builder(&method_call); |
622 G_TYPE_STRING, app_name_.c_str(), // appid | 794 builder.AppendInt32(handle); // handle |
623 G_TYPE_INVALID, | 795 builder.AppendString(folder_name_); // folder |
624 G_TYPE_BOOLEAN, &has_folder, | 796 builder.AppendString(app_name_); // appid |
625 G_TYPE_INVALID); | 797 scoped_ptr<dbus::Response> response( |
626 if (CheckError()) | 798 kwallet_proxy_->CallMethodAndBlock( |
627 return kInvalidKWalletHandle; | 799 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT)); |
| 800 if (!response.get()) { |
| 801 LOG(ERROR) << "Error contacting kwalletd (hasFolder)"; |
| 802 return kInvalidKWalletHandle; |
| 803 } |
| 804 dbus::MessageReader reader(response.get()); |
| 805 if (!reader.PopBool(&has_folder)) { |
| 806 LOG(ERROR) << "Error reading response from kwalletd (hasFolder): " |
| 807 << response->ToString(); |
| 808 return kInvalidKWalletHandle; |
| 809 } |
| 810 } |
628 | 811 |
629 // Create it if it didn't. | 812 // Create it if it didn't. |
630 if (!has_folder) { | 813 if (!has_folder) { |
631 gboolean success = false; | 814 dbus::MethodCall method_call(kKWalletInterface, "createFolder"); |
632 dbus_g_proxy_call(proxy_, "createFolder", &error_, | 815 dbus::MessageWriter builder(&method_call); |
633 G_TYPE_INT, handle, // handle | 816 builder.AppendInt32(handle); // handle |
634 G_TYPE_STRING, folder_name_.c_str(), // folder | 817 builder.AppendString(folder_name_); // folder |
635 G_TYPE_STRING, app_name_.c_str(), // appid | 818 builder.AppendString(app_name_); // appid |
636 G_TYPE_INVALID, | 819 scoped_ptr<dbus::Response> response( |
637 G_TYPE_BOOLEAN, &success, | 820 kwallet_proxy_->CallMethodAndBlock( |
638 G_TYPE_INVALID); | 821 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT)); |
639 if (CheckError() || !success) | 822 if (!response.get()) { |
| 823 LOG(ERROR) << "Error contacting kwalletd (createFolder)"; |
640 return kInvalidKWalletHandle; | 824 return kInvalidKWalletHandle; |
| 825 } |
| 826 dbus::MessageReader reader(response.get()); |
| 827 bool success = false; |
| 828 if (!reader.PopBool(&success)) { |
| 829 LOG(ERROR) << "Error reading response from kwalletd (createFolder): " |
| 830 << response->ToString(); |
| 831 return kInvalidKWalletHandle; |
| 832 } |
| 833 if (!success) { |
| 834 LOG(ERROR) << "Error creating KWallet folder"; |
| 835 return kInvalidKWalletHandle; |
| 836 } |
641 } | 837 } |
642 | 838 |
643 // Successful initialization. Try migration if necessary. | 839 // Successful initialization. Try migration if necessary. |
644 if (!migrate_tried_) | 840 if (!migrate_tried_) |
645 MigrateToProfileSpecificLogins(); | 841 MigrateToProfileSpecificLogins(); |
646 | 842 |
647 return handle; | 843 return handle; |
648 } | 844 } |
649 | 845 |
650 std::string NativeBackendKWallet::GetProfileSpecificFolderName() const { | 846 std::string NativeBackendKWallet::GetProfileSpecificFolderName() const { |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
693 // Each other profile must be able to migrate the shared data as well, | 889 // Each other profile must be able to migrate the shared data as well, |
694 // so we must leave it alone. After a few releases, we'll add code to | 890 // so we must leave it alone. After a few releases, we'll add code to |
695 // delete them, and eventually remove this migration code. | 891 // delete them, and eventually remove this migration code. |
696 // TODO(mdm): follow through with the plan above. | 892 // TODO(mdm): follow through with the plan above. |
697 PasswordStoreX::SetPasswordsUseLocalProfileId(prefs_); | 893 PasswordStoreX::SetPasswordsUseLocalProfileId(prefs_); |
698 } else { | 894 } else { |
699 // We failed to migrate for some reason. Use the old folder name. | 895 // We failed to migrate for some reason. Use the old folder name. |
700 folder_name_ = kKWalletFolder; | 896 folder_name_ = kKWalletFolder; |
701 } | 897 } |
702 } | 898 } |
OLD | NEW |