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( | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 } |
OLD | NEW |