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

Side by Side Diff: chrome/browser/password_manager/native_backend_kwallet_x.cc

Issue 7835021: Linux: use our spiffy new DBus client library for KWallet, instead of dbus-glib. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 9 years, 3 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
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(
satorux1 2011/09/12 19:28:57 base::Bind is preferable.
Mike Mammarella 2011/09/12 21:26:13 I am inclined to stick with this for now since I k
satorux1 2011/09/12 22:28:21 That's fine, but it should be as easy as: Browser
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(
satorux1 2011/09/12 19:28:57 ditto.
Mike Mammarella 2011/09/12 21:26:13 same
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()) {
satorux1 2011/09/12 19:28:57 This is a bit tricky. You might want to add a comm
Mike Mammarella 2011/09/12 21:26:13 Done.
93 session_bus_ = optional_bus;
94 } else {
95 // Get a connection to the session bus.
96 dbus::Bus::Options options;
97 options.bus_type = dbus::Bus::SESSION;
98 options.connection_type = dbus::Bus::PRIVATE;
99 session_bus_ = new dbus::Bus(options);
100 }
101 kwallet_proxy_ =
102 session_bus_->GetObjectProxy(kKWalletServiceName, kKWalletPath);
103 // kwalletd may not be running. If it fails to initialize, try to start it
104 // and then try to initialize it again. (Note the short-circuit evaluation.)
105 *success = InitWallet() || (StartKWalletd() && InitWallet());
satorux1 2011/09/12 19:28:57 I wasn't sure if || had higher precedence than =.
Mike Mammarella 2011/09/12 21:26:13 Some of the operators (the bitwise ones especially
106 if (event)
107 event->Signal();
108 }
109
110 bool NativeBackendKWallet::StartKWalletd() {
satorux1 2011/09/12 19:28:57 You might want to add DCHECK(BrowserThread::Curr
Mike Mammarella 2011/09/12 21:26:13 Done.
111 // Sadly kwalletd doesn't use DBus activation, so we have to make a call to
112 // klauncher to start it.
113 dbus::ObjectProxy* klauncher =
114 session_bus_->GetObjectProxy(kKLauncherServiceName, kKLauncherPath);
115
116 dbus::MethodCall method_call(kKLauncherInterface,
117 "start_service_by_desktop_name");
118 dbus::MessageWriter builder(&method_call);
119 dbus::MessageWriter empty(&method_call);
120 builder.AppendString("kwalletd"); // serviceName
121 builder.OpenArray("s", &empty); // urls
122 builder.CloseContainer(&empty);
123 builder.OpenArray("s", &empty); // envs
124 builder.CloseContainer(&empty);
125 builder.AppendString(""); // startup_id
126 builder.AppendBool(false); // blind
127 scoped_ptr<dbus::Response> response(
128 klauncher->CallMethodAndBlock(
129 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT));
130 if (!response.get()) {
131 LOG(ERROR) << "Error contacting klauncher to start kwalletd";
56 return false; 132 return false;
57 133 }
58 if (!InitWallet()) { 134 dbus::MessageReader reader(response.get());
59 // kwalletd may not be running. Try to start it and try again. 135 int32_t ret = -1;
60 if (!StartKWalletd() || !InitWallet()) 136 std::string dbus_name;
61 return false; 137 std::string error;
138 int32_t pid = -1;
139 if (!reader.PopInt32(&ret) || !reader.PopString(&dbus_name) ||
140 !reader.PopString(&error) || !reader.PopInt32(&pid)) {
141 LOG(ERROR) << "Error reading response from klauncher to start kwalletd: "
142 << response->ToString();
143 return false;
144 }
145 if (!error.empty() || ret) {
146 LOG(ERROR) << "Error launching kwalletd: error '" << error << "' "
147 << " (code " << ret << ")";
148 return false;
62 } 149 }
63 150
64 return true; 151 return true;
65 } 152 }
66 153
67 bool NativeBackendKWallet::StartKWalletd() { 154 bool NativeBackendKWallet::InitWallet() {
satorux1 2011/09/12 19:28:57 You might want to add DCHECK(BrowserThread::Curr
Mike Mammarella 2011/09/12 21:26:13 Done.
68 // Sadly kwalletd doesn't use DBUS activation, so we have to make a call to 155 {
69 // klauncher to start it. 156 // Check that KWallet is enabled.
70 DBusGProxy* klauncher_proxy = 157 dbus::MethodCall method_call(kKWalletInterface, "isEnabled");
71 dbus_g_proxy_new_for_name(connection_, kKLauncherServiceName, 158 scoped_ptr<dbus::Response> response(
72 kKLauncherPath, kKLauncherInterface); 159 kwallet_proxy_->CallMethodAndBlock(
73 160 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT));
74 char* empty_string_list = NULL; 161 if (!response.get()) {
75 int ret = 1; 162 LOG(ERROR) << "Error contacting kwalletd (isEnabled)";
76 char* error = NULL; 163 return false;
77 dbus_g_proxy_call(klauncher_proxy, "start_service_by_desktop_name", &error_, 164 }
78 G_TYPE_STRING, "kwalletd", // serviceName 165 dbus::MessageReader reader(response.get());
79 G_TYPE_STRV, &empty_string_list, // urls 166 bool enabled = false;
80 G_TYPE_STRV, &empty_string_list, // envs 167 if (!reader.PopBool(&enabled)) {
81 G_TYPE_STRING, "", // startup_id 168 LOG(ERROR) << "Error reading response from kwalletd (isEnabled): "
82 G_TYPE_BOOLEAN, (gboolean) false, // blind 169 << response->ToString();
83 G_TYPE_INVALID, 170 return false;
84 G_TYPE_INT, &ret, // result 171 }
85 G_TYPE_STRING, NULL, // dubsName 172 // Not enabled? Don't use KWallet. But also don't warn here.
86 G_TYPE_STRING, &error, // error 173 if (!enabled)
87 G_TYPE_INT, NULL, // pid 174 return false;
satorux1 2011/09/12 19:28:57 VLOG(1) may be helpful for debugging?
Mike Mammarella 2011/09/12 21:26:13 Done.
88 G_TYPE_INVALID);
89
90 if (error && *error) {
91 LOG(ERROR) << "Error launching kwalletd: " << error;
92 ret = 1; // Make sure we return false after freeing.
93 } 175 }
94 176
95 g_free(error); 177 {
96 g_object_unref(klauncher_proxy); 178 // Get the wallet name.
97 179 dbus::MethodCall method_call(kKWalletInterface, "networkWallet");
98 if (CheckError() || ret != 0) 180 scoped_ptr<dbus::Response> response(
99 return false; 181 kwallet_proxy_->CallMethodAndBlock(
100 return true; 182 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT));
101 } 183 if (!response.get()) {
102 184 LOG(ERROR) << "Error contacting kwalletd (networkWallet)";
103 bool NativeBackendKWallet::InitWallet() { 185 return false;
104 // Make a proxy to KWallet. 186 }
105 proxy_ = dbus_g_proxy_new_for_name(connection_, kKWalletServiceName, 187 dbus::MessageReader reader(response.get());
106 kKWalletPath, kKWalletInterface); 188 if (!reader.PopString(&wallet_name_)) {
107 189 LOG(ERROR) << "Error reading response from kwalletd (networkWallet): "
108 // Check KWallet is enabled. 190 << response->ToString();
109 gboolean is_enabled = false; 191 return false;
110 dbus_g_proxy_call(proxy_, "isEnabled", &error_, 192 }
111 G_TYPE_INVALID, 193 }
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 194
129 return true; 195 return true;
130 } 196 }
131 197
132 bool NativeBackendKWallet::AddLogin(const PasswordForm& form) { 198 bool NativeBackendKWallet::AddLogin(const PasswordForm& form) {
133 int wallet_handle = WalletHandle(); 199 int wallet_handle = WalletHandle();
134 if (wallet_handle == kInvalidKWalletHandle) 200 if (wallet_handle == kInvalidKWalletHandle)
135 return false; 201 return false;
136 202
137 PasswordFormList forms; 203 PasswordFormList forms;
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
196 262
197 // Update the entry in the wallet, possibly deleting it. 263 // Update the entry in the wallet, possibly deleting it.
198 bool ok = SetLoginsList(kept_forms, form.signon_realm, wallet_handle); 264 bool ok = SetLoginsList(kept_forms, form.signon_realm, wallet_handle);
199 265
200 STLDeleteElements(&kept_forms); 266 STLDeleteElements(&kept_forms);
201 return ok; 267 return ok;
202 } 268 }
203 269
204 bool NativeBackendKWallet::RemoveLoginsCreatedBetween( 270 bool NativeBackendKWallet::RemoveLoginsCreatedBetween(
205 const base::Time& delete_begin, 271 const base::Time& delete_begin,
206 const base::Time& delete_end) { 272 const base::Time& delete_end) {
satorux1 2011/09/12 19:28:57 You might want to add DCHECK(BrowserThread::Curr
Mike Mammarella 2011/09/12 21:26:13 WalletHandle() has such a check, and this method n
satorux1 2011/09/12 22:28:21 It's a matter of taste so it's up to you, but I th
207 int wallet_handle = WalletHandle(); 273 int wallet_handle = WalletHandle();
208 if (wallet_handle == kInvalidKWalletHandle) 274 if (wallet_handle == kInvalidKWalletHandle)
209 return false; 275 return false;
210 276
211 // We could probably also use readEntryList here. 277 // We could probably also use readEntryList here.
212 char** realm_list = NULL; 278 std::vector<std::string> realm_list;
213 dbus_g_proxy_call(proxy_, "entryList", &error_, 279 {
214 G_TYPE_INT, wallet_handle, // handle 280 dbus::MethodCall method_call(kKWalletInterface, "entryList");
215 G_TYPE_STRING, folder_name_.c_str(), // folder 281 dbus::MessageWriter builder(&method_call);
216 G_TYPE_STRING, app_name_.c_str(), // appid 282 builder.AppendInt32(wallet_handle); // handle
217 G_TYPE_INVALID, 283 builder.AppendString(folder_name_); // folder
218 G_TYPE_STRV, &realm_list, 284 builder.AppendString(app_name_); // appid
219 G_TYPE_INVALID); 285 scoped_ptr<dbus::Response> response(
220 if (CheckError()) 286 kwallet_proxy_->CallMethodAndBlock(
221 return false; 287 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT));
288 if (!response.get()) {
289 LOG(ERROR) << "Error contacting kwalletd (entryList)";
290 return false;
291 }
292 dbus::MessageReader reader(response.get());
293 dbus::MessageReader array(response.get());
294 if (!reader.PopArray(&array)) {
295 LOG(ERROR) << "Error reading response from kwalletd (entryList): "
296 << response->ToString();
297 return false;
298 }
299 while (array.HasMoreData()) {
300 std::string realm;
301 if (!array.PopString(&realm)) {
302 LOG(ERROR) << "Error reading response from kwalletd (entryList): "
303 << response->ToString();
304 return false;
305 }
306 realm_list.push_back(realm);
307 }
308 }
222 309
223 bool ok = true; 310 bool ok = true;
224 for (char** realm = realm_list; *realm; ++realm) { 311 for (size_t i = 0; i < realm_list.size(); ++i) {
225 GArray* byte_array = NULL; 312 const std::string& signon_realm = realm_list[i];
226 dbus_g_proxy_call(proxy_, "readEntry", &error_, 313 dbus::MethodCall method_call(kKWalletInterface, "readEntry");
227 G_TYPE_INT, wallet_handle, // handle 314 dbus::MessageWriter builder(&method_call);
228 G_TYPE_STRING, folder_name_.c_str(), // folder 315 builder.AppendInt32(wallet_handle); // handle
229 G_TYPE_STRING, *realm, // key 316 builder.AppendString(folder_name_); // folder
230 G_TYPE_STRING, app_name_.c_str(), // appid 317 builder.AppendString(signon_realm); // key
231 G_TYPE_INVALID, 318 builder.AppendString(app_name_); // appid
232 DBUS_TYPE_G_UCHAR_ARRAY, &byte_array, 319 scoped_ptr<dbus::Response> response(
233 G_TYPE_INVALID); 320 kwallet_proxy_->CallMethodAndBlock(
234 321 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT));
235 if (CheckError() || !byte_array || 322 if (!response.get()) {
236 !CheckSerializedValue(byte_array, *realm)) { 323 LOG(ERROR) << "Error contacting kwalletd (readEntry)";
237 continue; 324 continue;
238 } 325 }
326 dbus::MessageReader reader(response.get());
327 uint8_t* bytes = NULL;
328 size_t length = 0;
329 if (!reader.PopArrayOfBytes(&bytes, &length)) {
330 LOG(ERROR) << "Error reading response from kwalletd (readEntry): "
331 << response->ToString();
332 continue;
333 }
334 if (!bytes || !CheckSerializedValue(bytes, length, signon_realm))
335 continue;
239 336
240 string signon_realm(*realm); 337 // Can't we all just agree on whether bytes are signed or not? Please?
241 Pickle pickle(byte_array->data, byte_array->len); 338 Pickle pickle(reinterpret_cast<const char*>(bytes), length);
242 PasswordFormList all_forms; 339 PasswordFormList all_forms;
243 DeserializeValue(signon_realm, pickle, &all_forms); 340 DeserializeValue(signon_realm, pickle, &all_forms);
244 g_array_free(byte_array, true);
245 341
246 PasswordFormList kept_forms; 342 PasswordFormList kept_forms;
247 kept_forms.reserve(all_forms.size()); 343 kept_forms.reserve(all_forms.size());
248 for (size_t i = 0; i < all_forms.size(); ++i) { 344 for (size_t i = 0; i < all_forms.size(); ++i) {
249 if (delete_begin <= all_forms[i]->date_created && 345 if (delete_begin <= all_forms[i]->date_created &&
250 (delete_end.is_null() || all_forms[i]->date_created < delete_end)) { 346 (delete_end.is_null() || all_forms[i]->date_created < delete_end)) {
251 delete all_forms[i]; 347 delete all_forms[i];
252 } else { 348 } else {
253 kept_forms.push_back(all_forms[i]); 349 kept_forms.push_back(all_forms[i]);
254 } 350 }
255 } 351 }
256 352
257 if (!SetLoginsList(kept_forms, signon_realm, wallet_handle)) 353 if (!SetLoginsList(kept_forms, signon_realm, wallet_handle))
258 ok = false; 354 ok = false;
259 STLDeleteElements(&kept_forms); 355 STLDeleteElements(&kept_forms);
260 } 356 }
261 g_strfreev(realm_list);
262 return ok; 357 return ok;
263 } 358 }
264 359
265 bool NativeBackendKWallet::GetLogins(const PasswordForm& form, 360 bool NativeBackendKWallet::GetLogins(const PasswordForm& form,
266 PasswordFormList* forms) { 361 PasswordFormList* forms) {
267 int wallet_handle = WalletHandle(); 362 int wallet_handle = WalletHandle();
268 if (wallet_handle == kInvalidKWalletHandle) 363 if (wallet_handle == kInvalidKWalletHandle)
269 return false; 364 return false;
270 return GetLoginsList(forms, form.signon_realm, wallet_handle); 365 return GetLoginsList(forms, form.signon_realm, wallet_handle);
271 } 366 }
(...skipping 15 matching lines...) Expand all
287 } 382 }
288 383
289 bool NativeBackendKWallet::GetBlacklistLogins(PasswordFormList* forms) { 384 bool NativeBackendKWallet::GetBlacklistLogins(PasswordFormList* forms) {
290 int wallet_handle = WalletHandle(); 385 int wallet_handle = WalletHandle();
291 if (wallet_handle == kInvalidKWalletHandle) 386 if (wallet_handle == kInvalidKWalletHandle)
292 return false; 387 return false;
293 return GetLoginsList(forms, false, wallet_handle); 388 return GetLoginsList(forms, false, wallet_handle);
294 } 389 }
295 390
296 bool NativeBackendKWallet::GetLoginsList(PasswordFormList* forms, 391 bool NativeBackendKWallet::GetLoginsList(PasswordFormList* forms,
297 const string& signon_realm, 392 const std::string& signon_realm,
298 int wallet_handle) { 393 int wallet_handle) {
satorux1 2011/09/12 19:28:57 You might want to add DCHECK(BrowserThread::Curr
Mike Mammarella 2011/09/12 21:26:13 Although this method doesn't actually call WalletH
299 // Is there an entry in the wallet? 394 // Is there an entry in the wallet?
300 gboolean has_entry = false; 395 {
301 dbus_g_proxy_call(proxy_, "hasEntry", &error_, 396 dbus::MethodCall method_call(kKWalletInterface, "hasEntry");
302 G_TYPE_INT, wallet_handle, // handle 397 dbus::MessageWriter builder(&method_call);
303 G_TYPE_STRING, folder_name_.c_str(), // folder 398 builder.AppendInt32(wallet_handle); // handle
304 G_TYPE_STRING, signon_realm.c_str(), // key 399 builder.AppendString(folder_name_); // folder
305 G_TYPE_STRING, app_name_.c_str(), // appid 400 builder.AppendString(signon_realm); // key
306 G_TYPE_INVALID, 401 builder.AppendString(app_name_); // appid
307 G_TYPE_BOOLEAN, &has_entry, 402 scoped_ptr<dbus::Response> response(
308 G_TYPE_INVALID); 403 kwallet_proxy_->CallMethodAndBlock(
309 404 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT));
310 if (CheckError()) 405 if (!response.get()) {
311 return false; 406 LOG(ERROR) << "Error contacting kwalletd (hasEntry)";
312 if (!has_entry) { 407 return false;
313 // This is not an error. There just isn't a matching entry. 408 }
314 return true; 409 dbus::MessageReader reader(response.get());
410 bool has_entry = false;
411 if (!reader.PopBool(&has_entry)) {
412 LOG(ERROR) << "Error reading response from kwalletd (hasEntry): "
413 << response->ToString();
414 return false;
415 }
416 if (!has_entry) {
417 // This is not an error. There just isn't a matching entry.
418 return true;
419 }
315 } 420 }
316 421
317 GArray* byte_array = NULL; 422 {
318 dbus_g_proxy_call(proxy_, "readEntry", &error_, 423 dbus::MethodCall method_call(kKWalletInterface, "readEntry");
319 G_TYPE_INT, wallet_handle, // handle 424 dbus::MessageWriter builder(&method_call);
320 G_TYPE_STRING, folder_name_.c_str(), // folder 425 builder.AppendInt32(wallet_handle); // handle
321 G_TYPE_STRING, signon_realm.c_str(), // key 426 builder.AppendString(folder_name_); // folder
322 G_TYPE_STRING, app_name_.c_str(), // appid 427 builder.AppendString(signon_realm); // key
323 G_TYPE_INVALID, 428 builder.AppendString(app_name_); // appid
324 DBUS_TYPE_G_UCHAR_ARRAY, &byte_array, 429 scoped_ptr<dbus::Response> response(
325 G_TYPE_INVALID); 430 kwallet_proxy_->CallMethodAndBlock(
431 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT));
432 if (!response.get()) {
433 LOG(ERROR) << "Error contacting kwalletd (readEntry)";
434 return false;
435 }
436 dbus::MessageReader reader(response.get());
437 uint8_t* bytes = NULL;
438 size_t length = 0;
439 if (!reader.PopArrayOfBytes(&bytes, &length)) {
440 LOG(ERROR) << "Error reading response from kwalletd (readEntry): "
441 << response->ToString();
442 return false;
443 }
444 if (!bytes)
445 return false;
446 if (!CheckSerializedValue(bytes, length, signon_realm)) {
447 // This is weird, but we choose not to call it an error. There is an
448 // invalid entry somehow, but by just ignoring it, we make it easier to
449 // repair without having to delete it using kwalletmanager (that is, by
450 // just saving a new password within this realm to overwrite it).
satorux1 2011/09/12 19:28:57 Worth adding a LOG(WARNING) or something?
Mike Mammarella 2011/09/12 21:26:13 CheckSerializedValue() has one.
451 return true;
452 }
326 453
327 if (CheckError() || !byte_array) 454 // Can't we all just agree on whether bytes are signed or not? Please?
328 return false; 455 Pickle pickle(reinterpret_cast<const char*>(bytes), length);
329 if (!CheckSerializedValue(byte_array, signon_realm.c_str())) { 456 PasswordFormList all_forms;
330 // This is weird, but we choose not to call it an error. There's an invalid 457 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 } 458 }
337 459
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; 460 return true;
343 } 461 }
344 462
345 bool NativeBackendKWallet::GetLoginsList(PasswordFormList* forms, 463 bool NativeBackendKWallet::GetLoginsList(PasswordFormList* forms,
346 bool autofillable, 464 bool autofillable,
347 int wallet_handle) { 465 int wallet_handle) {
348 PasswordFormList all_forms; 466 PasswordFormList all_forms;
349 if (!GetAllLogins(&all_forms, wallet_handle)) 467 if (!GetAllLogins(&all_forms, wallet_handle))
350 return false; 468 return false;
351 469
(...skipping 25 matching lines...) Expand all
377 forms->push_back(all_forms[i]); 495 forms->push_back(all_forms[i]);
378 } else { 496 } else {
379 delete all_forms[i]; 497 delete all_forms[i];
380 } 498 }
381 } 499 }
382 500
383 return true; 501 return true;
384 } 502 }
385 503
386 bool NativeBackendKWallet::GetAllLogins(PasswordFormList* forms, 504 bool NativeBackendKWallet::GetAllLogins(PasswordFormList* forms,
387 int wallet_handle) { 505 int wallet_handle) {
satorux1 2011/09/12 19:28:57 You might want to add DCHECK(BrowserThread::Curr
Mike Mammarella 2011/09/12 21:26:13 Same reasoning about WalletHandle().
388 // We could probably also use readEntryList here. 506 // We could probably also use readEntryList here.
389 char** realm_list = NULL; 507 std::vector<std::string> realm_list;
390 dbus_g_proxy_call(proxy_, "entryList", &error_, 508 {
391 G_TYPE_INT, wallet_handle, // handle 509 dbus::MethodCall method_call(kKWalletInterface, "entryList");
392 G_TYPE_STRING, folder_name_.c_str(), // folder 510 dbus::MessageWriter builder(&method_call);
393 G_TYPE_STRING, app_name_.c_str(), // appid 511 builder.AppendInt32(wallet_handle); // handle
394 G_TYPE_INVALID, 512 builder.AppendString(folder_name_); // folder
395 G_TYPE_STRV, &realm_list, 513 builder.AppendString(app_name_); // appid
396 G_TYPE_INVALID); 514 scoped_ptr<dbus::Response> response(
397 if (CheckError()) 515 kwallet_proxy_->CallMethodAndBlock(
398 return false; 516 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT));
517 if (!response.get()) {
518 LOG(ERROR) << "Error contacting kwalletd (entryList)";
519 return false;
520 }
521 dbus::MessageReader reader(response.get());
522 dbus::MessageReader array(response.get());
523 if (!reader.PopArray(&array)) {
524 LOG(ERROR) << "Error reading response from kwalletd (entryList): "
525 << response->ToString();
526 return false;
527 }
528 while (array.HasMoreData()) {
satorux1 2011/09/12 19:28:57 This is the second time I see this. I guess it's w
Mike Mammarella 2011/09/12 21:26:13 That would be useful. I'll consider adding one in
529 std::string realm;
530 if (!array.PopString(&realm)) {
531 LOG(ERROR) << "Error reading response from kwalletd (entryList): "
532 << response->ToString();
533 return false;
534 }
535 realm_list.push_back(realm);
536 }
537 }
399 538
400 for (char** realm = realm_list; *realm; ++realm) { 539 for (size_t i = 0; i < realm_list.size(); ++i) {
401 GArray* byte_array = NULL; 540 const std::string& signon_realm = realm_list[i];
402 dbus_g_proxy_call(proxy_, "readEntry", &error_, 541 dbus::MethodCall method_call(kKWalletInterface, "readEntry");
403 G_TYPE_INT, wallet_handle, // handle 542 dbus::MessageWriter builder(&method_call);
404 G_TYPE_STRING, folder_name_.c_str(), // folder 543 builder.AppendInt32(wallet_handle); // handle
405 G_TYPE_STRING, *realm, // key 544 builder.AppendString(folder_name_); // folder
406 G_TYPE_STRING, app_name_.c_str(), // appid 545 builder.AppendString(signon_realm); // key
407 G_TYPE_INVALID, 546 builder.AppendString(app_name_); // appid
408 DBUS_TYPE_G_UCHAR_ARRAY, &byte_array, 547 scoped_ptr<dbus::Response> response(
409 G_TYPE_INVALID); 548 kwallet_proxy_->CallMethodAndBlock(
410 549 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT));
411 if (CheckError() || !byte_array || 550 if (!response.get()) {
412 !CheckSerializedValue(byte_array, *realm)) { 551 LOG(ERROR) << "Error contacting kwalletd (readEntry)";
413 continue; 552 continue;
414 } 553 }
554 dbus::MessageReader reader(response.get());
555 uint8_t* bytes = NULL;
556 size_t length = 0;
557 if (!reader.PopArrayOfBytes(&bytes, &length)) {
558 LOG(ERROR) << "Error reading response from kwalletd (readEntry): "
559 << response->ToString();
560 continue;
561 }
562 if (!bytes || !CheckSerializedValue(bytes, length, signon_realm))
563 continue;
415 564
416 Pickle pickle(byte_array->data, byte_array->len); 565 // Can't we all just agree on whether bytes are signed or not? Please?
417 DeserializeValue(*realm, pickle, forms); 566 Pickle pickle(reinterpret_cast<const char*>(bytes), length);
418 g_array_free(byte_array, true); 567 PasswordFormList all_forms;
568 DeserializeValue(signon_realm, pickle, forms);
419 } 569 }
420 g_strfreev(realm_list);
421 return true; 570 return true;
422 } 571 }
423 572
424 bool NativeBackendKWallet::SetLoginsList(const PasswordFormList& forms, 573 bool NativeBackendKWallet::SetLoginsList(const PasswordFormList& forms,
425 const string& signon_realm, 574 const std::string& signon_realm,
426 int wallet_handle) { 575 int wallet_handle) {
satorux1 2011/09/12 19:28:57 You might want to add DCHECK(BrowserThread::Curr
Mike Mammarella 2011/09/12 21:26:13 Same.
427 if (forms.empty()) { 576 if (forms.empty()) {
428 // No items left? Remove the entry from the wallet. 577 // No items left? Remove the entry from the wallet.
578 dbus::MethodCall method_call(kKWalletInterface, "removeEntry");
579 dbus::MessageWriter builder(&method_call);
580 builder.AppendInt32(wallet_handle); // handle
581 builder.AppendString(folder_name_); // folder
582 builder.AppendString(signon_realm); // key
583 builder.AppendString(app_name_); // appid
584 scoped_ptr<dbus::Response> response(
585 kwallet_proxy_->CallMethodAndBlock(
586 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT));
587 if (!response.get()) {
588 LOG(ERROR) << "Error contacting kwalletd (removeEntry)";
589 return kInvalidKWalletHandle;
590 }
591 dbus::MessageReader reader(response.get());
429 int ret = 0; 592 int ret = 0;
430 dbus_g_proxy_call(proxy_, "removeEntry", &error_, 593 if (!reader.PopInt32(&ret)) {
431 G_TYPE_INT, wallet_handle, // handle 594 LOG(ERROR) << "Error reading response from kwalletd (removeEntry): "
432 G_TYPE_STRING, folder_name_.c_str(), // folder 595 << 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; 596 return false;
597 }
440 if (ret != 0) 598 if (ret != 0)
441 LOG(ERROR) << "Bad return code " << ret << " from KWallet removeEntry"; 599 LOG(ERROR) << "Bad return code " << ret << " from KWallet removeEntry";
442 return ret == 0; 600 return ret == 0;
443 } 601 }
444 602
445 Pickle value; 603 Pickle value;
446 SerializeValue(forms, &value); 604 SerializeValue(forms, &value);
447 605
448 // Convert the pickled bytes to a GByteArray. 606 dbus::MethodCall method_call(kKWalletInterface, "writeEntry");
449 GArray* byte_array = g_array_sized_new(false, false, sizeof(char), 607 dbus::MessageWriter builder(&method_call);
450 value.size()); 608 builder.AppendInt32(wallet_handle); // handle
451 g_array_append_vals(byte_array, value.data(), value.size()); 609 builder.AppendString(folder_name_); // folder
452 610 builder.AppendString(signon_realm); // key
453 // Make the call. 611 builder.AppendArrayOfBytes(static_cast<const uint8_t*>(value.data()),
612 value.size()); // value
613 builder.AppendString(app_name_); // appid
614 scoped_ptr<dbus::Response> response(
615 kwallet_proxy_->CallMethodAndBlock(
616 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT));
617 if (!response.get()) {
618 LOG(ERROR) << "Error contacting kwalletd (writeEntry)";
619 return kInvalidKWalletHandle;
620 }
621 dbus::MessageReader reader(response.get());
454 int ret = 0; 622 int ret = 0;
455 dbus_g_proxy_call(proxy_, "writeEntry", &error_, 623 if (!reader.PopInt32(&ret)) {
456 G_TYPE_INT, wallet_handle, // handle 624 LOG(ERROR) << "Error reading response from kwalletd (writeEntry): "
457 G_TYPE_STRING, folder_name_.c_str(), // folder 625 << 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; 626 return false;
627 }
468 if (ret != 0) 628 if (ret != 0)
469 LOG(ERROR) << "Bad return code " << ret << " from KWallet writeEntry"; 629 LOG(ERROR) << "Bad return code " << ret << " from KWallet writeEntry";
470 return ret == 0; 630 return ret == 0;
471 } 631 }
472 632
473 bool NativeBackendKWallet::CompareForms(const PasswordForm& a, 633 bool NativeBackendKWallet::CompareForms(const PasswordForm& a,
474 const PasswordForm& b, 634 const PasswordForm& b,
475 bool update_check) { 635 bool update_check) {
476 // An update check doesn't care about the submit element. 636 // An update check doesn't care about the submit element.
477 if (!update_check && a.submit_element != b.submit_element) 637 if (!update_check && a.submit_element != b.submit_element)
(...skipping 20 matching lines...) Expand all
498 pickle->WriteString16(form->password_element); 658 pickle->WriteString16(form->password_element);
499 pickle->WriteString16(form->password_value); 659 pickle->WriteString16(form->password_value);
500 pickle->WriteString16(form->submit_element); 660 pickle->WriteString16(form->submit_element);
501 pickle->WriteBool(form->ssl_valid); 661 pickle->WriteBool(form->ssl_valid);
502 pickle->WriteBool(form->preferred); 662 pickle->WriteBool(form->preferred);
503 pickle->WriteBool(form->blacklisted_by_user); 663 pickle->WriteBool(form->blacklisted_by_user);
504 pickle->WriteInt64(form->date_created.ToTimeT()); 664 pickle->WriteInt64(form->date_created.ToTimeT());
505 } 665 }
506 } 666 }
507 667
508 bool NativeBackendKWallet::CheckSerializedValue(const GArray* byte_array, 668 bool NativeBackendKWallet::CheckSerializedValue(const uint8_t* byte_array,
509 const char* realm) { 669 size_t length,
670 const std::string& realm) {
510 const Pickle::Header* header = 671 const Pickle::Header* header =
511 reinterpret_cast<const Pickle::Header*>(byte_array->data); 672 reinterpret_cast<const Pickle::Header*>(byte_array);
512 if (byte_array->len < sizeof(*header) || 673 if (length < sizeof(*header) ||
513 header->payload_size > byte_array->len - sizeof(*header)) { 674 header->payload_size > length - sizeof(*header)) {
514 LOG(WARNING) << "Invalid KWallet entry detected (realm: " << realm << ")"; 675 LOG(WARNING) << "Invalid KWallet entry detected (realm: " << realm << ")";
515 return false; 676 return false;
516 } 677 }
517 return true; 678 return true;
518 } 679 }
519 680
520 void NativeBackendKWallet::DeserializeValue(const string& signon_realm, 681 void NativeBackendKWallet::DeserializeValue(const std::string& signon_realm,
521 const Pickle& pickle, 682 const Pickle& pickle,
522 PasswordFormList* forms) { 683 PasswordFormList* forms) {
523 void* iter = NULL; 684 void* iter = NULL;
524 685
525 int version = -1; 686 int version = -1;
526 if (!pickle.ReadInt(&iter, &version) || version != kPickleVersion) { 687 if (!pickle.ReadInt(&iter, &version) || version != kPickleVersion) {
527 // This is the only version so far, so anything else is an error. 688 // This is the only version so far, so anything else is an error.
528 LOG(ERROR) << "Failed to deserialize KWallet entry " 689 LOG(ERROR) << "Failed to deserialize KWallet entry "
529 << "(realm: " << signon_realm << ")"; 690 << "(realm: " << signon_realm << ")";
530 return; 691 return;
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
572 break; 733 break;
573 } 734 }
574 form->scheme = static_cast<PasswordForm::Scheme>(scheme); 735 form->scheme = static_cast<PasswordForm::Scheme>(scheme);
575 form->date_created = base::Time::FromTimeT(date_created); 736 form->date_created = base::Time::FromTimeT(date_created);
576 forms->push_back(form.release()); 737 forms->push_back(form.release());
577 } 738 }
578 } 739 }
579 740
580 bool NativeBackendKWallet::ReadGURL(const Pickle& pickle, void** iter, 741 bool NativeBackendKWallet::ReadGURL(const Pickle& pickle, void** iter,
581 GURL* url) { 742 GURL* url) {
582 string url_string; 743 std::string url_string;
583 if (!pickle.ReadString(iter, &url_string)) { 744 if (!pickle.ReadString(iter, &url_string)) {
584 LOG(ERROR) << "Failed to deserialize URL"; 745 LOG(ERROR) << "Failed to deserialize URL";
585 *url = GURL(); 746 *url = GURL();
586 return false; 747 return false;
587 } 748 }
588 *url = GURL(url_string); 749 *url = GURL(url_string);
589 return true; 750 return true;
590 } 751 }
591 752
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() { 753 int NativeBackendKWallet::WalletHandle() {
603 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 754 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
755
604 // Open the wallet. 756 // Open the wallet.
605 // TODO(mdm): Are we leaking these handles? Find out. 757 // TODO(mdm): Are we leaking these handles? Find out.
606 int handle = kInvalidKWalletHandle; 758 int32_t handle = kInvalidKWalletHandle;
607 dbus_g_proxy_call(proxy_, "open", &error_, 759 {
608 G_TYPE_STRING, wallet_name_.c_str(), // wallet 760 dbus::MethodCall method_call(kKWalletInterface, "open");
609 G_TYPE_INT64, 0LL, // wid 761 dbus::MessageWriter builder(&method_call);
610 G_TYPE_STRING, app_name_.c_str(), // appid 762 builder.AppendString(wallet_name_); // wallet
611 G_TYPE_INVALID, 763 builder.AppendInt64(0); // wid
612 G_TYPE_INT, &handle, 764 builder.AppendString(app_name_); // appid
613 G_TYPE_INVALID); 765 scoped_ptr<dbus::Response> response(
614 if (CheckError() || handle == kInvalidKWalletHandle) 766 kwallet_proxy_->CallMethodAndBlock(
615 return kInvalidKWalletHandle; 767 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT));
768 if (!response.get()) {
769 LOG(ERROR) << "Error contacting kwalletd (open)";
770 return kInvalidKWalletHandle;
771 }
772 dbus::MessageReader reader(response.get());
773 if (!reader.PopInt32(&handle)) {
774 LOG(ERROR) << "Error reading response from kwalletd (open): "
775 << response->ToString();
776 return kInvalidKWalletHandle;
777 }
778 if (handle == kInvalidKWalletHandle) {
779 LOG(ERROR) << "Error obtaining KWallet handle";
780 return kInvalidKWalletHandle;
781 }
782 }
616 783
617 // Check if our folder exists. 784 // Check if our folder exists.
618 gboolean has_folder = false; 785 bool has_folder = false;
619 dbus_g_proxy_call(proxy_, "hasFolder", &error_, 786 {
620 G_TYPE_INT, handle, // handle 787 dbus::MethodCall method_call(kKWalletInterface, "hasFolder");
621 G_TYPE_STRING, folder_name_.c_str(), // folder 788 dbus::MessageWriter builder(&method_call);
622 G_TYPE_STRING, app_name_.c_str(), // appid 789 builder.AppendInt32(handle); // handle
623 G_TYPE_INVALID, 790 builder.AppendString(folder_name_); // folder
624 G_TYPE_BOOLEAN, &has_folder, 791 builder.AppendString(app_name_); // appid
625 G_TYPE_INVALID); 792 scoped_ptr<dbus::Response> response(
626 if (CheckError()) 793 kwallet_proxy_->CallMethodAndBlock(
627 return kInvalidKWalletHandle; 794 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT));
795 if (!response.get()) {
796 LOG(ERROR) << "Error contacting kwalletd (hasFolder)";
797 return kInvalidKWalletHandle;
798 }
799 dbus::MessageReader reader(response.get());
800 if (!reader.PopBool(&has_folder)) {
801 LOG(ERROR) << "Error reading response from kwalletd (hasFolder): "
802 << response->ToString();
803 return kInvalidKWalletHandle;
804 }
805 }
628 806
629 // Create it if it didn't. 807 // Create it if it didn't.
630 if (!has_folder) { 808 if (!has_folder) {
631 gboolean success = false; 809 dbus::MethodCall method_call(kKWalletInterface, "createFolder");
632 dbus_g_proxy_call(proxy_, "createFolder", &error_, 810 dbus::MessageWriter builder(&method_call);
633 G_TYPE_INT, handle, // handle 811 builder.AppendInt32(handle); // handle
634 G_TYPE_STRING, folder_name_.c_str(), // folder 812 builder.AppendString(folder_name_); // folder
635 G_TYPE_STRING, app_name_.c_str(), // appid 813 builder.AppendString(app_name_); // appid
636 G_TYPE_INVALID, 814 scoped_ptr<dbus::Response> response(
637 G_TYPE_BOOLEAN, &success, 815 kwallet_proxy_->CallMethodAndBlock(
638 G_TYPE_INVALID); 816 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT));
639 if (CheckError() || !success) 817 if (!response.get()) {
818 LOG(ERROR) << "Error contacting kwalletd (createFolder)";
640 return kInvalidKWalletHandle; 819 return kInvalidKWalletHandle;
820 }
821 dbus::MessageReader reader(response.get());
822 bool success = false;
823 if (!reader.PopBool(&success)) {
824 LOG(ERROR) << "Error reading response from kwalletd (createFolder): "
825 << response->ToString();
826 return kInvalidKWalletHandle;
827 }
828 if (!success) {
829 LOG(ERROR) << "Error creating KWallet folder";
830 return kInvalidKWalletHandle;
831 }
641 } 832 }
642 833
643 // Successful initialization. Try migration if necessary. 834 // Successful initialization. Try migration if necessary.
644 if (!migrate_tried_) 835 if (!migrate_tried_)
645 MigrateToProfileSpecificLogins(); 836 MigrateToProfileSpecificLogins();
646 837
647 return handle; 838 return handle;
648 } 839 }
649 840
650 std::string NativeBackendKWallet::GetProfileSpecificFolderName() const { 841 std::string NativeBackendKWallet::GetProfileSpecificFolderName() const {
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
693 // Each other profile must be able to migrate the shared data as well, 884 // 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 885 // so we must leave it alone. After a few releases, we'll add code to
695 // delete them, and eventually remove this migration code. 886 // delete them, and eventually remove this migration code.
696 // TODO(mdm): follow through with the plan above. 887 // TODO(mdm): follow through with the plan above.
697 PasswordStoreX::SetPasswordsUseLocalProfileId(prefs_); 888 PasswordStoreX::SetPasswordsUseLocalProfileId(prefs_);
698 } else { 889 } else {
699 // We failed to migrate for some reason. Use the old folder name. 890 // We failed to migrate for some reason. Use the old folder name.
700 folder_name_ = kKWalletFolder; 891 folder_name_ = kKWalletFolder;
701 } 892 }
702 } 893 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698