Chromium Code Reviews| 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 if (session_bus_) |
| 49 g_object_unref(proxy_); | 50 session_bus_->ShutdownAndBlock(); |
|
satorux1
2011/09/06 20:42:40
This would crash with DCHECK() if D-Bus thread is
Mike Mammarella
2011/09/07 01:01:27
Ah, one of the perils of code you have never actua
| |
| 50 } | 51 } |
| 51 | 52 |
| 52 bool NativeBackendKWallet::Init() { | 53 bool NativeBackendKWallet::Init() { |
| 53 // Get a connection to the session bus. | 54 // Get a connection to the session bus. |
| 54 connection_ = dbus_g_bus_get(DBUS_BUS_SESSION, &error_); | 55 dbus::Bus::Options options; |
| 55 if (CheckError()) | 56 options.bus_type = dbus::Bus::SESSION; |
| 56 return false; | 57 options.connection_type = dbus::Bus::PRIVATE; |
| 58 options.dbus_thread_message_loop_proxy = | |
| 59 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB); | |
|
satorux1
2011/09/06 20:42:40
Why do we use the DB thread? Could you add a comme
Mike Mammarella
2011/09/07 01:01:27
Hmm. Now that I think about it more, I think I can
| |
| 60 return InitWithBus(new dbus::Bus(options)); | |
| 61 } | |
| 57 | 62 |
| 63 // NativeBackendKWallet isn't reference counted, but the one place we post a | |
| 64 // message to it (in InitWithBus below) waits for the task to run. So we can | |
| 65 // disable needing reference counting safely here. | |
| 66 template<> | |
| 67 struct RunnableMethodTraits<NativeBackendKWallet> { | |
| 68 void RetainCallee(NativeBackendKWallet*) {} | |
| 69 void ReleaseCallee(NativeBackendKWallet*) {} | |
| 70 }; | |
| 71 | |
| 72 bool NativeBackendKWallet::InitWithBus(dbus::Bus* bus) { | |
| 73 DCHECK(!session_bus_); | |
| 74 session_bus_ = bus; | |
| 75 kwallet_proxy_ = bus->GetObjectProxy(kKWalletServiceName, kKWalletPath); | |
| 76 | |
| 77 // We must synchronously do a few DBus calls to figure out if initialization | |
| 78 // succeeds, but later, we'll want to do most work on the DB thread. So we | |
| 79 // have to do the initialization on the DB thread here too, and wait for it. | |
| 80 bool success = false; | |
| 81 base::WaitableEvent event(false, false); | |
| 82 BrowserThread::PostTask(BrowserThread::DB, FROM_HERE, | |
| 83 NewRunnableMethod( | |
| 84 this, &NativeBackendKWallet::InitOnDBThread, | |
| 85 &event, &success)); | |
| 86 event.Wait(); | |
| 87 return success; | |
| 88 } | |
| 89 | |
| 90 void NativeBackendKWallet::InitOnDBThread(base::WaitableEvent* event, | |
| 91 bool* success) { | |
| 92 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); | |
| 58 if (!InitWallet()) { | 93 if (!InitWallet()) { |
| 59 // kwalletd may not be running. Try to start it and try again. | 94 // kwalletd may not be running. Try to start it and try again. |
| 60 if (!StartKWalletd() || !InitWallet()) | 95 if (!StartKWalletd() || !InitWallet()) |
| 61 return false; | 96 return; // *success starts out false |
| 97 } | |
| 98 *success = true; | |
| 99 } | |
| 100 | |
| 101 bool NativeBackendKWallet::StartKWalletd() { | |
| 102 // Sadly kwalletd doesn't use DBus activation, so we have to make a call to | |
| 103 // klauncher to start it. | |
| 104 dbus::ObjectProxy* klauncher = | |
| 105 session_bus_->GetObjectProxy(kKLauncherServiceName, kKLauncherPath); | |
| 106 | |
| 107 dbus::MethodCall method_call(kKLauncherInterface, | |
| 108 "start_service_by_desktop_name"); | |
| 109 dbus::MessageWriter builder(&method_call); | |
| 110 dbus::MessageWriter empty(&method_call); | |
| 111 builder.AppendString("kwalletd"); // serviceName | |
| 112 builder.OpenArray("s", &empty); // urls | |
| 113 builder.CloseContainer(&empty); | |
| 114 builder.OpenArray("s", &empty); // envs | |
| 115 builder.CloseContainer(&empty); | |
| 116 builder.AppendString(""); // startup_id | |
| 117 builder.AppendBool(false); // blind | |
| 118 scoped_ptr<dbus::Response> response( | |
| 119 klauncher->CallMethodAndBlock( | |
| 120 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT)); | |
| 121 if (!response.get()) { | |
| 122 LOG(ERROR) << "Error contacting klauncher to start kwalletd"; | |
| 123 return false; | |
| 124 } | |
| 125 dbus::MessageReader reader(response.get()); | |
| 126 int32_t ret = -1; | |
| 127 std::string dbusName; | |
|
satorux1
2011/09/06 20:42:40
dbus_name
Mike Mammarella
2011/09/07 01:01:27
Done. Huh. I wonder where this came from. I'm pret
| |
| 128 std::string error; | |
| 129 int32_t pid = -1; | |
| 130 if (!reader.PopInt32(&ret) || !reader.PopString(&dbusName) || | |
| 131 !reader.PopString(&error) || !reader.PopInt32(&pid)) { | |
| 132 LOG(ERROR) << "Error reading response from klauncher to start kwalletd"; | |
|
satorux1
2011/09/06 20:42:40
You could add << response->ToString(). It'll make
Mike Mammarella
2011/09/07 01:01:27
Done.
| |
| 133 return false; | |
| 134 } | |
| 135 if (!error.empty()) { | |
| 136 LOG(ERROR) << "Error launching kwalletd: " << error; | |
| 137 return false; | |
| 138 } | |
| 139 if (ret) { | |
| 140 LOG(ERROR) << "Error launching kwalletd: " << ret; | |
| 141 return false; | |
| 62 } | 142 } |
|
satorux1
2011/09/06 20:42:40
Maybe you could merge the two conditionals, by usi
Mike Mammarella
2011/09/07 01:01:27
Done.
| |
| 63 | 143 |
| 64 return true; | 144 return true; |
| 65 } | 145 } |
| 66 | 146 |
| 67 bool NativeBackendKWallet::StartKWalletd() { | 147 bool NativeBackendKWallet::InitWallet() { |
| 68 // Sadly kwalletd doesn't use DBUS activation, so we have to make a call to | 148 { |
| 69 // klauncher to start it. | 149 // Check that KWallet is enabled. |
| 70 DBusGProxy* klauncher_proxy = | 150 dbus::MethodCall method_call(kKWalletInterface, "isEnabled"); |
| 71 dbus_g_proxy_new_for_name(connection_, kKLauncherServiceName, | 151 scoped_ptr<dbus::Response> response( |
| 72 kKLauncherPath, kKLauncherInterface); | 152 kwallet_proxy_->CallMethodAndBlock( |
| 73 | 153 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT)); |
| 74 char* empty_string_list = NULL; | 154 if (!response.get()) { |
| 75 int ret = 1; | 155 LOG(ERROR) << "Error contacting kwalletd (isEnabled)"; |
| 76 char* error = NULL; | 156 return false; |
| 77 dbus_g_proxy_call(klauncher_proxy, "start_service_by_desktop_name", &error_, | 157 } |
| 78 G_TYPE_STRING, "kwalletd", // serviceName | 158 dbus::MessageReader reader(response.get()); |
| 79 G_TYPE_STRV, &empty_string_list, // urls | 159 bool enabled = false; |
| 80 G_TYPE_STRV, &empty_string_list, // envs | 160 if (!reader.PopBool(&enabled)) { |
| 81 G_TYPE_STRING, "", // startup_id | 161 LOG(ERROR) << "Error reading response from kwalletd (isEnabled)"; |
|
satorux1
2011/09/06 20:42:40
Likewise, I'd recommend including response->ToStri
Mike Mammarella
2011/09/07 01:01:27
Done.
| |
| 82 G_TYPE_BOOLEAN, (gboolean) false, // blind | 162 return false; |
| 83 G_TYPE_INVALID, | 163 } |
| 84 G_TYPE_INT, &ret, // result | 164 // Not enabled? Don't use KWallet. But also don't warn here. |
| 85 G_TYPE_STRING, NULL, // dubsName | 165 if (!enabled) |
| 86 G_TYPE_STRING, &error, // error | 166 return false; |
| 87 G_TYPE_INT, NULL, // pid | |
| 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 } | 167 } |
| 94 | 168 |
| 95 g_free(error); | 169 { |
| 96 g_object_unref(klauncher_proxy); | 170 // Get the wallet name. |
| 97 | 171 dbus::MethodCall method_call(kKWalletInterface, "networkWallet"); |
| 98 if (CheckError() || ret != 0) | 172 scoped_ptr<dbus::Response> response( |
| 99 return false; | 173 kwallet_proxy_->CallMethodAndBlock( |
| 100 return true; | 174 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT)); |
| 101 } | 175 if (!response.get()) { |
| 102 | 176 LOG(ERROR) << "Error contacting kwalletd (networkWallet)"; |
| 103 bool NativeBackendKWallet::InitWallet() { | 177 return false; |
| 104 // Make a proxy to KWallet. | 178 } |
| 105 proxy_ = dbus_g_proxy_new_for_name(connection_, kKWalletServiceName, | 179 dbus::MessageReader reader(response.get()); |
| 106 kKWalletPath, kKWalletInterface); | 180 if (!reader.PopString(&wallet_name_)) { |
| 107 | 181 LOG(ERROR) << "Error reading response from kwalletd (networkWallet)"; |
| 108 // Check KWallet is enabled. | 182 return false; |
| 109 gboolean is_enabled = false; | 183 } |
| 110 dbus_g_proxy_call(proxy_, "isEnabled", &error_, | 184 } |
| 111 G_TYPE_INVALID, | |
| 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 | 185 |
| 129 return true; | 186 return true; |
| 130 } | 187 } |
| 131 | 188 |
| 132 bool NativeBackendKWallet::AddLogin(const PasswordForm& form) { | 189 bool NativeBackendKWallet::AddLogin(const PasswordForm& form) { |
| 133 int wallet_handle = WalletHandle(); | 190 int wallet_handle = WalletHandle(); |
| 134 if (wallet_handle == kInvalidKWalletHandle) | 191 if (wallet_handle == kInvalidKWalletHandle) |
| 135 return false; | 192 return false; |
| 136 | 193 |
| 137 PasswordFormList forms; | 194 PasswordFormList forms; |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 201 return ok; | 258 return ok; |
| 202 } | 259 } |
| 203 | 260 |
| 204 bool NativeBackendKWallet::RemoveLoginsCreatedBetween( | 261 bool NativeBackendKWallet::RemoveLoginsCreatedBetween( |
| 205 const base::Time& delete_begin, | 262 const base::Time& delete_begin, |
| 206 const base::Time& delete_end) { | 263 const base::Time& delete_end) { |
| 207 int wallet_handle = WalletHandle(); | 264 int wallet_handle = WalletHandle(); |
| 208 if (wallet_handle == kInvalidKWalletHandle) | 265 if (wallet_handle == kInvalidKWalletHandle) |
| 209 return false; | 266 return false; |
| 210 | 267 |
| 211 // We could probably also use readEntryList here. | 268 // We could probably also use readEntryList here. |
|
satorux1
2011/09/06 20:42:40
What's readEntryList? Is this comment still valid?
Mike Mammarella
2011/09/07 01:01:27
It's another possible method call in the KWallet i
| |
| 212 char** realm_list = NULL; | 269 std::vector<std::string> realm_list; |
| 213 dbus_g_proxy_call(proxy_, "entryList", &error_, | 270 { |
| 214 G_TYPE_INT, wallet_handle, // handle | 271 dbus::MethodCall method_call(kKWalletInterface, "entryList"); |
| 215 G_TYPE_STRING, folder_name_.c_str(), // folder | 272 dbus::MessageWriter builder(&method_call); |
| 216 G_TYPE_STRING, app_name_.c_str(), // appid | 273 builder.AppendInt32(wallet_handle); // handle |
| 217 G_TYPE_INVALID, | 274 builder.AppendString(folder_name_); // folder |
| 218 G_TYPE_STRV, &realm_list, | 275 builder.AppendString(app_name_); // appid |
| 219 G_TYPE_INVALID); | 276 scoped_ptr<dbus::Response> response( |
| 220 if (CheckError()) | 277 kwallet_proxy_->CallMethodAndBlock( |
| 221 return false; | 278 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT)); |
| 279 if (!response.get()) { | |
| 280 LOG(ERROR) << "Error contacting kwalletd (entryList)"; | |
| 281 return false; | |
| 282 } | |
| 283 dbus::MessageReader reader(response.get()); | |
| 284 dbus::MessageReader array(response.get()); | |
| 285 if (!reader.PopArray(&array)) { | |
| 286 LOG(ERROR) << "Error reading response from kwalletd (entryList)"; | |
| 287 return false; | |
| 288 } | |
| 289 while (array.HasMoreData()) { | |
| 290 std::string realm; | |
| 291 if (!array.PopString(&realm)) { | |
| 292 LOG(ERROR) << "Error reading response from kwalletd (entryList)"; | |
| 293 return false; | |
| 294 } | |
| 295 realm_list.push_back(realm); | |
| 296 } | |
| 297 } | |
| 222 | 298 |
| 223 bool ok = true; | 299 bool ok = true; |
| 224 for (char** realm = realm_list; *realm; ++realm) { | 300 for (size_t i = 0; i < realm_list.size(); ++i) { |
| 225 GArray* byte_array = NULL; | 301 const std::string& signon_realm = realm_list[i]; |
| 226 dbus_g_proxy_call(proxy_, "readEntry", &error_, | 302 dbus::MethodCall method_call(kKWalletInterface, "readEntry"); |
| 227 G_TYPE_INT, wallet_handle, // handle | 303 dbus::MessageWriter builder(&method_call); |
| 228 G_TYPE_STRING, folder_name_.c_str(), // folder | 304 builder.AppendInt32(wallet_handle); // handle |
| 229 G_TYPE_STRING, *realm, // key | 305 builder.AppendString(folder_name_); // folder |
| 230 G_TYPE_STRING, app_name_.c_str(), // appid | 306 builder.AppendString(signon_realm); // key |
| 231 G_TYPE_INVALID, | 307 builder.AppendString(app_name_); // appid |
| 232 DBUS_TYPE_G_UCHAR_ARRAY, &byte_array, | 308 scoped_ptr<dbus::Response> response( |
| 233 G_TYPE_INVALID); | 309 kwallet_proxy_->CallMethodAndBlock( |
| 234 | 310 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT)); |
| 235 if (CheckError() || !byte_array || | 311 if (!response.get()) { |
| 236 !CheckSerializedValue(byte_array, *realm)) { | 312 LOG(ERROR) << "Error contacting kwalletd (readEntry)"; |
| 237 continue; | 313 continue; |
| 238 } | 314 } |
| 315 dbus::MessageReader reader(response.get()); | |
| 316 uint8_t* bytes = NULL; | |
| 317 size_t length = 0; | |
| 318 if (!reader.PopArrayOfBytes(&bytes, &length)) { | |
| 319 LOG(ERROR) << "Error reading response from kwalletd (readEntry)"; | |
| 320 continue; | |
| 321 } | |
| 322 if (!bytes || !CheckSerializedValue(bytes, length, signon_realm)) | |
| 323 continue; | |
| 239 | 324 |
| 240 string signon_realm(*realm); | 325 // Can't we all just agree on whether bytes are signed or not? Please? |
| 241 Pickle pickle(byte_array->data, byte_array->len); | 326 Pickle pickle(reinterpret_cast<const char*>(bytes), length); |
| 242 PasswordFormList all_forms; | 327 PasswordFormList all_forms; |
| 243 DeserializeValue(signon_realm, pickle, &all_forms); | 328 DeserializeValue(signon_realm, pickle, &all_forms); |
| 244 g_array_free(byte_array, true); | |
| 245 | 329 |
| 246 PasswordFormList kept_forms; | 330 PasswordFormList kept_forms; |
| 247 kept_forms.reserve(all_forms.size()); | 331 kept_forms.reserve(all_forms.size()); |
| 248 for (size_t i = 0; i < all_forms.size(); ++i) { | 332 for (size_t i = 0; i < all_forms.size(); ++i) { |
| 249 if (delete_begin <= all_forms[i]->date_created && | 333 if (delete_begin <= all_forms[i]->date_created && |
| 250 (delete_end.is_null() || all_forms[i]->date_created < delete_end)) { | 334 (delete_end.is_null() || all_forms[i]->date_created < delete_end)) { |
| 251 delete all_forms[i]; | 335 delete all_forms[i]; |
| 252 } else { | 336 } else { |
| 253 kept_forms.push_back(all_forms[i]); | 337 kept_forms.push_back(all_forms[i]); |
| 254 } | 338 } |
| 255 } | 339 } |
| 256 | 340 |
| 257 if (!SetLoginsList(kept_forms, signon_realm, wallet_handle)) | 341 if (!SetLoginsList(kept_forms, signon_realm, wallet_handle)) |
| 258 ok = false; | 342 ok = false; |
| 259 STLDeleteElements(&kept_forms); | 343 STLDeleteElements(&kept_forms); |
| 260 } | 344 } |
| 261 g_strfreev(realm_list); | |
| 262 return ok; | 345 return ok; |
| 263 } | 346 } |
| 264 | 347 |
| 265 bool NativeBackendKWallet::GetLogins(const PasswordForm& form, | 348 bool NativeBackendKWallet::GetLogins(const PasswordForm& form, |
| 266 PasswordFormList* forms) { | 349 PasswordFormList* forms) { |
| 267 int wallet_handle = WalletHandle(); | 350 int wallet_handle = WalletHandle(); |
| 268 if (wallet_handle == kInvalidKWalletHandle) | 351 if (wallet_handle == kInvalidKWalletHandle) |
| 269 return false; | 352 return false; |
| 270 return GetLoginsList(forms, form.signon_realm, wallet_handle); | 353 return GetLoginsList(forms, form.signon_realm, wallet_handle); |
| 271 } | 354 } |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 287 } | 370 } |
| 288 | 371 |
| 289 bool NativeBackendKWallet::GetBlacklistLogins(PasswordFormList* forms) { | 372 bool NativeBackendKWallet::GetBlacklistLogins(PasswordFormList* forms) { |
| 290 int wallet_handle = WalletHandle(); | 373 int wallet_handle = WalletHandle(); |
| 291 if (wallet_handle == kInvalidKWalletHandle) | 374 if (wallet_handle == kInvalidKWalletHandle) |
| 292 return false; | 375 return false; |
| 293 return GetLoginsList(forms, false, wallet_handle); | 376 return GetLoginsList(forms, false, wallet_handle); |
| 294 } | 377 } |
| 295 | 378 |
| 296 bool NativeBackendKWallet::GetLoginsList(PasswordFormList* forms, | 379 bool NativeBackendKWallet::GetLoginsList(PasswordFormList* forms, |
| 297 const string& signon_realm, | 380 const std::string& signon_realm, |
| 298 int wallet_handle) { | 381 int wallet_handle) { |
| 299 // Is there an entry in the wallet? | 382 // Is there an entry in the wallet? |
| 300 gboolean has_entry = false; | 383 { |
| 301 dbus_g_proxy_call(proxy_, "hasEntry", &error_, | 384 dbus::MethodCall method_call(kKWalletInterface, "hasEntry"); |
| 302 G_TYPE_INT, wallet_handle, // handle | 385 dbus::MessageWriter builder(&method_call); |
| 303 G_TYPE_STRING, folder_name_.c_str(), // folder | 386 builder.AppendInt32(wallet_handle); // handle |
| 304 G_TYPE_STRING, signon_realm.c_str(), // key | 387 builder.AppendString(folder_name_); // folder |
| 305 G_TYPE_STRING, app_name_.c_str(), // appid | 388 builder.AppendString(signon_realm); // key |
| 306 G_TYPE_INVALID, | 389 builder.AppendString(app_name_); // appid |
| 307 G_TYPE_BOOLEAN, &has_entry, | 390 scoped_ptr<dbus::Response> response( |
| 308 G_TYPE_INVALID); | 391 kwallet_proxy_->CallMethodAndBlock( |
| 309 | 392 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT)); |
| 310 if (CheckError()) | 393 if (!response.get()) { |
| 311 return false; | 394 LOG(ERROR) << "Error contacting kwalletd (hasEntry)"; |
| 312 if (!has_entry) { | 395 return false; |
| 313 // This is not an error. There just isn't a matching entry. | 396 } |
| 314 return true; | 397 dbus::MessageReader reader(response.get()); |
| 398 bool has_entry = false; | |
| 399 if (!reader.PopBool(&has_entry)) { | |
| 400 LOG(ERROR) << "Error reading response from kwalletd (hasEntry)"; | |
| 401 return false; | |
| 402 } | |
| 403 if (!has_entry) { | |
| 404 // This is not an error. There just isn't a matching entry. | |
| 405 return true; | |
| 406 } | |
| 315 } | 407 } |
| 316 | 408 |
| 317 GArray* byte_array = NULL; | 409 { |
| 318 dbus_g_proxy_call(proxy_, "readEntry", &error_, | 410 dbus::MethodCall method_call(kKWalletInterface, "readEntry"); |
| 319 G_TYPE_INT, wallet_handle, // handle | 411 dbus::MessageWriter builder(&method_call); |
| 320 G_TYPE_STRING, folder_name_.c_str(), // folder | 412 builder.AppendInt32(wallet_handle); // handle |
| 321 G_TYPE_STRING, signon_realm.c_str(), // key | 413 builder.AppendString(folder_name_); // folder |
| 322 G_TYPE_STRING, app_name_.c_str(), // appid | 414 builder.AppendString(signon_realm); // key |
| 323 G_TYPE_INVALID, | 415 builder.AppendString(app_name_); // appid |
| 324 DBUS_TYPE_G_UCHAR_ARRAY, &byte_array, | 416 scoped_ptr<dbus::Response> response( |
| 325 G_TYPE_INVALID); | 417 kwallet_proxy_->CallMethodAndBlock( |
| 418 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT)); | |
| 419 if (!response.get()) { | |
| 420 LOG(ERROR) << "Error contacting kwalletd (readEntry)"; | |
| 421 return false; | |
| 422 } | |
| 423 dbus::MessageReader reader(response.get()); | |
| 424 uint8_t* bytes = NULL; | |
| 425 size_t length = 0; | |
| 426 if (!reader.PopArrayOfBytes(&bytes, &length)) { | |
| 427 LOG(ERROR) << "Error reading response from kwalletd (readEntry)"; | |
| 428 return false; | |
| 429 } | |
| 430 if (!bytes) | |
| 431 return false; | |
| 432 if (!CheckSerializedValue(bytes, length, signon_realm)) { | |
| 433 // This is weird, but we choose not to call it an error. There is an | |
| 434 // invalid entry somehow, but by just ignoring it, we make it easier to | |
| 435 // repair without having to delete it using kwalletmanager (that is, by | |
| 436 // just saving a new password within this realm to overwrite it). | |
| 437 return true; | |
| 438 } | |
| 326 | 439 |
| 327 if (CheckError() || !byte_array) | 440 // Can't we all just agree on whether bytes are signed or not? Please? |
| 328 return false; | 441 Pickle pickle(reinterpret_cast<const char*>(bytes), length); |
| 329 if (!CheckSerializedValue(byte_array, signon_realm.c_str())) { | 442 PasswordFormList all_forms; |
| 330 // This is weird, but we choose not to call it an error. There's an invalid | 443 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 } | 444 } |
| 337 | 445 |
| 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; | 446 return true; |
| 343 } | 447 } |
| 344 | 448 |
| 345 bool NativeBackendKWallet::GetLoginsList(PasswordFormList* forms, | 449 bool NativeBackendKWallet::GetLoginsList(PasswordFormList* forms, |
| 346 bool autofillable, | 450 bool autofillable, |
| 347 int wallet_handle) { | 451 int wallet_handle) { |
| 348 PasswordFormList all_forms; | 452 PasswordFormList all_forms; |
| 349 if (!GetAllLogins(&all_forms, wallet_handle)) | 453 if (!GetAllLogins(&all_forms, wallet_handle)) |
| 350 return false; | 454 return false; |
| 351 | 455 |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 379 delete all_forms[i]; | 483 delete all_forms[i]; |
| 380 } | 484 } |
| 381 } | 485 } |
| 382 | 486 |
| 383 return true; | 487 return true; |
| 384 } | 488 } |
| 385 | 489 |
| 386 bool NativeBackendKWallet::GetAllLogins(PasswordFormList* forms, | 490 bool NativeBackendKWallet::GetAllLogins(PasswordFormList* forms, |
| 387 int wallet_handle) { | 491 int wallet_handle) { |
| 388 // We could probably also use readEntryList here. | 492 // We could probably also use readEntryList here. |
| 389 char** realm_list = NULL; | 493 std::vector<std::string> realm_list; |
| 390 dbus_g_proxy_call(proxy_, "entryList", &error_, | 494 { |
| 391 G_TYPE_INT, wallet_handle, // handle | 495 dbus::MethodCall method_call(kKWalletInterface, "entryList"); |
| 392 G_TYPE_STRING, folder_name_.c_str(), // folder | 496 dbus::MessageWriter builder(&method_call); |
| 393 G_TYPE_STRING, app_name_.c_str(), // appid | 497 builder.AppendInt32(wallet_handle); // handle |
| 394 G_TYPE_INVALID, | 498 builder.AppendString(folder_name_); // folder |
| 395 G_TYPE_STRV, &realm_list, | 499 builder.AppendString(app_name_); // appid |
| 396 G_TYPE_INVALID); | 500 scoped_ptr<dbus::Response> response( |
| 397 if (CheckError()) | 501 kwallet_proxy_->CallMethodAndBlock( |
| 398 return false; | 502 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT)); |
| 503 if (!response.get()) { | |
| 504 LOG(ERROR) << "Error contacting kwalletd (entryList)"; | |
| 505 return false; | |
| 506 } | |
| 507 dbus::MessageReader reader(response.get()); | |
| 508 dbus::MessageReader array(response.get()); | |
| 509 if (!reader.PopArray(&array)) { | |
| 510 LOG(ERROR) << "Error reading response from kwalletd (entryList)"; | |
| 511 return false; | |
| 512 } | |
| 513 while (array.HasMoreData()) { | |
| 514 std::string realm; | |
| 515 if (!array.PopString(&realm)) { | |
| 516 LOG(ERROR) << "Error reading response from kwalletd (entryList)"; | |
| 517 return false; | |
| 518 } | |
| 519 realm_list.push_back(realm); | |
| 520 } | |
| 521 } | |
| 399 | 522 |
| 400 for (char** realm = realm_list; *realm; ++realm) { | 523 for (size_t i = 0; i < realm_list.size(); ++i) { |
| 401 GArray* byte_array = NULL; | 524 const std::string& signon_realm = realm_list[i]; |
| 402 dbus_g_proxy_call(proxy_, "readEntry", &error_, | 525 dbus::MethodCall method_call(kKWalletInterface, "readEntry"); |
| 403 G_TYPE_INT, wallet_handle, // handle | 526 dbus::MessageWriter builder(&method_call); |
| 404 G_TYPE_STRING, folder_name_.c_str(), // folder | 527 builder.AppendInt32(wallet_handle); // handle |
| 405 G_TYPE_STRING, *realm, // key | 528 builder.AppendString(folder_name_); // folder |
| 406 G_TYPE_STRING, app_name_.c_str(), // appid | 529 builder.AppendString(signon_realm); // key |
| 407 G_TYPE_INVALID, | 530 builder.AppendString(app_name_); // appid |
| 408 DBUS_TYPE_G_UCHAR_ARRAY, &byte_array, | 531 scoped_ptr<dbus::Response> response( |
| 409 G_TYPE_INVALID); | 532 kwallet_proxy_->CallMethodAndBlock( |
| 410 | 533 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT)); |
| 411 if (CheckError() || !byte_array || | 534 if (!response.get()) { |
| 412 !CheckSerializedValue(byte_array, *realm)) { | 535 LOG(ERROR) << "Error contacting kwalletd (readEntry)"; |
| 413 continue; | 536 continue; |
| 414 } | 537 } |
| 538 dbus::MessageReader reader(response.get()); | |
| 539 uint8_t* bytes = NULL; | |
| 540 size_t length = 0; | |
| 541 if (!reader.PopArrayOfBytes(&bytes, &length)) { | |
| 542 LOG(ERROR) << "Error reading response from kwalletd (readEntry)"; | |
| 543 continue; | |
| 544 } | |
| 545 if (!bytes || !CheckSerializedValue(bytes, length, signon_realm)) | |
| 546 continue; | |
| 415 | 547 |
| 416 Pickle pickle(byte_array->data, byte_array->len); | 548 // Can't we all just agree on whether bytes are signed or not? Please? |
| 417 DeserializeValue(*realm, pickle, forms); | 549 Pickle pickle(reinterpret_cast<const char*>(bytes), length); |
| 418 g_array_free(byte_array, true); | 550 PasswordFormList all_forms; |
| 551 DeserializeValue(signon_realm, pickle, forms); | |
| 419 } | 552 } |
| 420 g_strfreev(realm_list); | |
| 421 return true; | 553 return true; |
| 422 } | 554 } |
| 423 | 555 |
| 424 bool NativeBackendKWallet::SetLoginsList(const PasswordFormList& forms, | 556 bool NativeBackendKWallet::SetLoginsList(const PasswordFormList& forms, |
| 425 const string& signon_realm, | 557 const std::string& signon_realm, |
| 426 int wallet_handle) { | 558 int wallet_handle) { |
| 427 if (forms.empty()) { | 559 if (forms.empty()) { |
| 428 // No items left? Remove the entry from the wallet. | 560 // No items left? Remove the entry from the wallet. |
| 561 dbus::MethodCall method_call(kKWalletInterface, "removeEntry"); | |
| 562 dbus::MessageWriter builder(&method_call); | |
| 563 builder.AppendInt32(wallet_handle); // handle | |
| 564 builder.AppendString(folder_name_); // folder | |
| 565 builder.AppendString(signon_realm); // key | |
| 566 builder.AppendString(app_name_); // appid | |
| 567 scoped_ptr<dbus::Response> response( | |
| 568 kwallet_proxy_->CallMethodAndBlock( | |
| 569 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT)); | |
| 570 if (!response.get()) { | |
| 571 LOG(ERROR) << "Error contacting kwalletd (removeEntry)"; | |
| 572 return kInvalidKWalletHandle; | |
| 573 } | |
| 574 dbus::MessageReader reader(response.get()); | |
| 429 int ret = 0; | 575 int ret = 0; |
| 430 dbus_g_proxy_call(proxy_, "removeEntry", &error_, | 576 if (!reader.PopInt32(&ret)) { |
| 431 G_TYPE_INT, wallet_handle, // handle | 577 LOG(ERROR) << "Error reading response from kwalletd (removeEntry)"; |
| 432 G_TYPE_STRING, folder_name_.c_str(), // folder | |
| 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; | 578 return false; |
| 579 } | |
| 440 if (ret != 0) | 580 if (ret != 0) |
| 441 LOG(ERROR) << "Bad return code " << ret << " from KWallet removeEntry"; | 581 LOG(ERROR) << "Bad return code " << ret << " from KWallet removeEntry"; |
| 442 return ret == 0; | 582 return ret == 0; |
| 443 } | 583 } |
| 444 | 584 |
| 445 Pickle value; | 585 Pickle value; |
| 446 SerializeValue(forms, &value); | 586 SerializeValue(forms, &value); |
| 447 | 587 |
| 448 // Convert the pickled bytes to a GByteArray. | 588 dbus::MethodCall method_call(kKWalletInterface, "writeEntry"); |
| 449 GArray* byte_array = g_array_sized_new(false, false, sizeof(char), | 589 dbus::MessageWriter builder(&method_call); |
| 450 value.size()); | 590 builder.AppendInt32(wallet_handle); // handle |
| 451 g_array_append_vals(byte_array, value.data(), value.size()); | 591 builder.AppendString(folder_name_); // folder |
| 452 | 592 builder.AppendString(signon_realm); // key |
| 453 // Make the call. | 593 builder.AppendArrayOfBytes(static_cast<const uint8_t*>(value.data()), |
| 594 value.size()); // value | |
| 595 builder.AppendString(app_name_); // appid | |
| 596 scoped_ptr<dbus::Response> response( | |
| 597 kwallet_proxy_->CallMethodAndBlock( | |
| 598 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT)); | |
| 599 if (!response.get()) { | |
| 600 LOG(ERROR) << "Error contacting kwalletd (writeEntry)"; | |
| 601 return kInvalidKWalletHandle; | |
| 602 } | |
| 603 dbus::MessageReader reader(response.get()); | |
| 454 int ret = 0; | 604 int ret = 0; |
| 455 dbus_g_proxy_call(proxy_, "writeEntry", &error_, | 605 if (!reader.PopInt32(&ret)) { |
| 456 G_TYPE_INT, wallet_handle, // handle | 606 LOG(ERROR) << "Error reading response from kwalletd (writeEntry)"; |
| 457 G_TYPE_STRING, folder_name_.c_str(), // folder | |
| 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; | 607 return false; |
| 608 } | |
| 468 if (ret != 0) | 609 if (ret != 0) |
| 469 LOG(ERROR) << "Bad return code " << ret << " from KWallet writeEntry"; | 610 LOG(ERROR) << "Bad return code " << ret << " from KWallet writeEntry"; |
| 470 return ret == 0; | 611 return ret == 0; |
| 471 } | 612 } |
| 472 | 613 |
| 473 bool NativeBackendKWallet::CompareForms(const PasswordForm& a, | 614 bool NativeBackendKWallet::CompareForms(const PasswordForm& a, |
| 474 const PasswordForm& b, | 615 const PasswordForm& b, |
| 475 bool update_check) { | 616 bool update_check) { |
| 476 // An update check doesn't care about the submit element. | 617 // An update check doesn't care about the submit element. |
| 477 if (!update_check && a.submit_element != b.submit_element) | 618 if (!update_check && a.submit_element != b.submit_element) |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 498 pickle->WriteString16(form->password_element); | 639 pickle->WriteString16(form->password_element); |
| 499 pickle->WriteString16(form->password_value); | 640 pickle->WriteString16(form->password_value); |
| 500 pickle->WriteString16(form->submit_element); | 641 pickle->WriteString16(form->submit_element); |
| 501 pickle->WriteBool(form->ssl_valid); | 642 pickle->WriteBool(form->ssl_valid); |
| 502 pickle->WriteBool(form->preferred); | 643 pickle->WriteBool(form->preferred); |
| 503 pickle->WriteBool(form->blacklisted_by_user); | 644 pickle->WriteBool(form->blacklisted_by_user); |
| 504 pickle->WriteInt64(form->date_created.ToTimeT()); | 645 pickle->WriteInt64(form->date_created.ToTimeT()); |
| 505 } | 646 } |
| 506 } | 647 } |
| 507 | 648 |
| 508 bool NativeBackendKWallet::CheckSerializedValue(const GArray* byte_array, | 649 bool NativeBackendKWallet::CheckSerializedValue(const uint8_t* byte_array, |
| 509 const char* realm) { | 650 size_t length, |
| 651 const std::string& realm) { | |
| 510 const Pickle::Header* header = | 652 const Pickle::Header* header = |
| 511 reinterpret_cast<const Pickle::Header*>(byte_array->data); | 653 reinterpret_cast<const Pickle::Header*>(byte_array); |
| 512 if (byte_array->len < sizeof(*header) || | 654 if (length < sizeof(*header) || |
| 513 header->payload_size > byte_array->len - sizeof(*header)) { | 655 header->payload_size > length - sizeof(*header)) { |
| 514 LOG(WARNING) << "Invalid KWallet entry detected (realm: " << realm << ")"; | 656 LOG(WARNING) << "Invalid KWallet entry detected (realm: " << realm << ")"; |
| 515 return false; | 657 return false; |
| 516 } | 658 } |
| 517 return true; | 659 return true; |
| 518 } | 660 } |
| 519 | 661 |
| 520 void NativeBackendKWallet::DeserializeValue(const string& signon_realm, | 662 void NativeBackendKWallet::DeserializeValue(const std::string& signon_realm, |
| 521 const Pickle& pickle, | 663 const Pickle& pickle, |
| 522 PasswordFormList* forms) { | 664 PasswordFormList* forms) { |
| 523 void* iter = NULL; | 665 void* iter = NULL; |
| 524 | 666 |
| 525 int version = -1; | 667 int version = -1; |
| 526 if (!pickle.ReadInt(&iter, &version) || version != kPickleVersion) { | 668 if (!pickle.ReadInt(&iter, &version) || version != kPickleVersion) { |
| 527 // This is the only version so far, so anything else is an error. | 669 // This is the only version so far, so anything else is an error. |
| 528 LOG(ERROR) << "Failed to deserialize KWallet entry " | 670 LOG(ERROR) << "Failed to deserialize KWallet entry " |
| 529 << "(realm: " << signon_realm << ")"; | 671 << "(realm: " << signon_realm << ")"; |
| 530 return; | 672 return; |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 572 break; | 714 break; |
| 573 } | 715 } |
| 574 form->scheme = static_cast<PasswordForm::Scheme>(scheme); | 716 form->scheme = static_cast<PasswordForm::Scheme>(scheme); |
| 575 form->date_created = base::Time::FromTimeT(date_created); | 717 form->date_created = base::Time::FromTimeT(date_created); |
| 576 forms->push_back(form.release()); | 718 forms->push_back(form.release()); |
| 577 } | 719 } |
| 578 } | 720 } |
| 579 | 721 |
| 580 bool NativeBackendKWallet::ReadGURL(const Pickle& pickle, void** iter, | 722 bool NativeBackendKWallet::ReadGURL(const Pickle& pickle, void** iter, |
| 581 GURL* url) { | 723 GURL* url) { |
| 582 string url_string; | 724 std::string url_string; |
| 583 if (!pickle.ReadString(iter, &url_string)) { | 725 if (!pickle.ReadString(iter, &url_string)) { |
| 584 LOG(ERROR) << "Failed to deserialize URL"; | 726 LOG(ERROR) << "Failed to deserialize URL"; |
| 585 *url = GURL(); | 727 *url = GURL(); |
| 586 return false; | 728 return false; |
| 587 } | 729 } |
| 588 *url = GURL(url_string); | 730 *url = GURL(url_string); |
| 589 return true; | 731 return true; |
| 590 } | 732 } |
| 591 | 733 |
| 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() { | 734 int NativeBackendKWallet::WalletHandle() { |
| 603 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); | 735 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); |
| 736 | |
| 604 // Open the wallet. | 737 // Open the wallet. |
| 605 // TODO(mdm): Are we leaking these handles? Find out. | 738 // TODO(mdm): Are we leaking these handles? Find out. |
| 606 int handle = kInvalidKWalletHandle; | 739 int32_t handle = kInvalidKWalletHandle; |
| 607 dbus_g_proxy_call(proxy_, "open", &error_, | 740 { |
| 608 G_TYPE_STRING, wallet_name_.c_str(), // wallet | 741 dbus::MethodCall method_call(kKWalletInterface, "open"); |
| 609 G_TYPE_INT64, 0LL, // wid | 742 dbus::MessageWriter builder(&method_call); |
| 610 G_TYPE_STRING, app_name_.c_str(), // appid | 743 builder.AppendString(wallet_name_); // wallet |
| 611 G_TYPE_INVALID, | 744 builder.AppendInt64(0); // wid |
| 612 G_TYPE_INT, &handle, | 745 builder.AppendString(app_name_); // appid |
| 613 G_TYPE_INVALID); | 746 scoped_ptr<dbus::Response> response( |
| 614 if (CheckError() || handle == kInvalidKWalletHandle) | 747 kwallet_proxy_->CallMethodAndBlock( |
| 615 return kInvalidKWalletHandle; | 748 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT)); |
| 749 if (!response.get()) { | |
| 750 LOG(ERROR) << "Error contacting kwalletd (open)"; | |
| 751 return kInvalidKWalletHandle; | |
| 752 } | |
| 753 dbus::MessageReader reader(response.get()); | |
| 754 if (!reader.PopInt32(&handle)) { | |
| 755 LOG(ERROR) << "Error reading response from kwalletd (open)"; | |
| 756 return kInvalidKWalletHandle; | |
| 757 } | |
| 758 if (handle == kInvalidKWalletHandle) { | |
| 759 LOG(ERROR) << "Error obtaining KWallet handle"; | |
| 760 return kInvalidKWalletHandle; | |
| 761 } | |
| 762 } | |
| 616 | 763 |
| 617 // Check if our folder exists. | 764 // Check if our folder exists. |
| 618 gboolean has_folder = false; | 765 bool has_folder = false; |
| 619 dbus_g_proxy_call(proxy_, "hasFolder", &error_, | 766 { |
| 620 G_TYPE_INT, handle, // handle | 767 dbus::MethodCall method_call(kKWalletInterface, "hasFolder"); |
| 621 G_TYPE_STRING, folder_name_.c_str(), // folder | 768 dbus::MessageWriter builder(&method_call); |
| 622 G_TYPE_STRING, app_name_.c_str(), // appid | 769 builder.AppendInt32(handle); // handle |
| 623 G_TYPE_INVALID, | 770 builder.AppendString(folder_name_); // folder |
| 624 G_TYPE_BOOLEAN, &has_folder, | 771 builder.AppendString(app_name_); // appid |
| 625 G_TYPE_INVALID); | 772 scoped_ptr<dbus::Response> response( |
| 626 if (CheckError()) | 773 kwallet_proxy_->CallMethodAndBlock( |
| 627 return kInvalidKWalletHandle; | 774 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT)); |
| 775 if (!response.get()) { | |
| 776 LOG(ERROR) << "Error contacting kwalletd (hasFolder)"; | |
| 777 return kInvalidKWalletHandle; | |
| 778 } | |
| 779 dbus::MessageReader reader(response.get()); | |
| 780 if (!reader.PopBool(&has_folder)) { | |
| 781 LOG(ERROR) << "Error reading response from kwalletd (hasFolder)"; | |
| 782 return kInvalidKWalletHandle; | |
| 783 } | |
| 784 } | |
| 628 | 785 |
| 629 // Create it if it didn't. | 786 // Create it if it didn't. |
| 630 if (!has_folder) { | 787 if (!has_folder) { |
| 631 gboolean success = false; | 788 dbus::MethodCall method_call(kKWalletInterface, "createFolder"); |
| 632 dbus_g_proxy_call(proxy_, "createFolder", &error_, | 789 dbus::MessageWriter builder(&method_call); |
| 633 G_TYPE_INT, handle, // handle | 790 builder.AppendInt32(handle); // handle |
| 634 G_TYPE_STRING, folder_name_.c_str(), // folder | 791 builder.AppendString(folder_name_); // folder |
| 635 G_TYPE_STRING, app_name_.c_str(), // appid | 792 builder.AppendString(app_name_); // appid |
| 636 G_TYPE_INVALID, | 793 scoped_ptr<dbus::Response> response( |
| 637 G_TYPE_BOOLEAN, &success, | 794 kwallet_proxy_->CallMethodAndBlock( |
| 638 G_TYPE_INVALID); | 795 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT)); |
| 639 if (CheckError() || !success) | 796 if (!response.get()) { |
| 797 LOG(ERROR) << "Error contacting kwalletd (createFolder)"; | |
| 640 return kInvalidKWalletHandle; | 798 return kInvalidKWalletHandle; |
| 799 } | |
| 800 dbus::MessageReader reader(response.get()); | |
| 801 bool success = false; | |
| 802 if (!reader.PopBool(&success)) { | |
| 803 LOG(ERROR) << "Error reading response from kwalletd (createFolder)"; | |
| 804 return kInvalidKWalletHandle; | |
| 805 } | |
| 806 if (!success) { | |
| 807 LOG(ERROR) << "Error creating KWallet folder"; | |
| 808 return kInvalidKWalletHandle; | |
| 809 } | |
| 641 } | 810 } |
| 642 | 811 |
| 643 // Successful initialization. Try migration if necessary. | 812 // Successful initialization. Try migration if necessary. |
| 644 if (!migrate_tried_) | 813 if (!migrate_tried_) |
| 645 MigrateToProfileSpecificLogins(); | 814 MigrateToProfileSpecificLogins(); |
| 646 | 815 |
| 647 return handle; | 816 return handle; |
| 648 } | 817 } |
| 649 | 818 |
| 650 std::string NativeBackendKWallet::GetProfileSpecificFolderName() const { | 819 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, | 862 // 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 | 863 // so we must leave it alone. After a few releases, we'll add code to |
| 695 // delete them, and eventually remove this migration code. | 864 // delete them, and eventually remove this migration code. |
| 696 // TODO(mdm): follow through with the plan above. | 865 // TODO(mdm): follow through with the plan above. |
| 697 PasswordStoreX::SetPasswordsUseLocalProfileId(prefs_); | 866 PasswordStoreX::SetPasswordsUseLocalProfileId(prefs_); |
| 698 } else { | 867 } else { |
| 699 // We failed to migrate for some reason. Use the old folder name. | 868 // We failed to migrate for some reason. Use the old folder name. |
| 700 folder_name_ = kKWalletFolder; | 869 folder_name_ = kKWalletFolder; |
| 701 } | 870 } |
| 702 } | 871 } |
| OLD | NEW |