| OLD | NEW |
| 1 // Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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/password_store_kwallet.h" | 5 #include "chrome/browser/password_manager/password_store_kwallet.h" |
| 6 | 6 |
| 7 #include <sstream> | 7 #include <sstream> |
| 8 | 8 |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/md5.h" | 10 #include "base/md5.h" |
| 11 #include "base/pickle.h" | 11 #include "base/pickle.h" |
| 12 #include "base/stl_util-inl.h" |
| 12 #include "base/string_util.h" | 13 #include "base/string_util.h" |
| 13 #include "base/task.h" | 14 #include "base/task.h" |
| 14 | 15 |
| 15 using std::string; | 16 using std::string; |
| 16 using std::vector; | 17 using std::vector; |
| 18 using webkit_glue::PasswordForm; |
| 17 | 19 |
| 20 // We could localize these strings, but then changing your locale would cause |
| 21 // you to lose access to all your stored passwords. Maybe best not to do that. |
| 18 const char* PasswordStoreKWallet::kAppId = "Chrome"; | 22 const char* PasswordStoreKWallet::kAppId = "Chrome"; |
| 19 const char* PasswordStoreKWallet::kKWalletFolder = "Chrome Form Data"; | 23 const char* PasswordStoreKWallet::kKWalletFolder = "Chrome Form Data"; |
| 20 | 24 |
| 21 const char* PasswordStoreKWallet::kKWalletServiceName = "org.kde.kwalletd"; | 25 const char* PasswordStoreKWallet::kKWalletServiceName = "org.kde.kwalletd"; |
| 22 const char* PasswordStoreKWallet::kKWalletPath = "/modules/kwalletd"; | 26 const char* PasswordStoreKWallet::kKWalletPath = "/modules/kwalletd"; |
| 23 const char* PasswordStoreKWallet::kKWalletInterface = "org.kde.KWallet"; | 27 const char* PasswordStoreKWallet::kKWalletInterface = "org.kde.KWallet"; |
| 24 const char* PasswordStoreKWallet::kKLauncherServiceName = "org.kde.klauncher"; | 28 const char* PasswordStoreKWallet::kKLauncherServiceName = "org.kde.klauncher"; |
| 25 const char* PasswordStoreKWallet::kKLauncherPath = "/KLauncher"; | 29 const char* PasswordStoreKWallet::kKLauncherPath = "/KLauncher"; |
| 26 const char* PasswordStoreKWallet::kKLauncherInterface = "org.kde.KLauncher"; | 30 const char* PasswordStoreKWallet::kKLauncherInterface = "org.kde.KLauncher"; |
| 27 | 31 |
| 28 PasswordStoreKWallet::PasswordStoreKWallet() | 32 PasswordStoreKWallet::PasswordStoreKWallet(LoginDatabase* login_db, |
| 33 Profile* profile, |
| 34 WebDataService* web_data_service) |
| 29 : error_(NULL), | 35 : error_(NULL), |
| 30 connection_(NULL), | 36 connection_(NULL), |
| 31 proxy_(NULL) { | 37 proxy_(NULL) { |
| 32 } | 38 } |
| 33 | 39 |
| 34 PasswordStoreKWallet::~PasswordStoreKWallet() { | 40 PasswordStoreKWallet::~PasswordStoreKWallet() { |
| 35 if (proxy_) { | 41 if (proxy_) { |
| 36 g_object_unref(proxy_); | 42 g_object_unref(proxy_); |
| 37 } | 43 } |
| 38 } | 44 } |
| 39 | 45 |
| 40 bool PasswordStoreKWallet::Init() { | 46 bool PasswordStoreKWallet::Init() { |
| 41 thread_.reset(new base::Thread("Chrome_KeyringThread")); | |
| 42 | |
| 43 if (!thread_->Start()) { | |
| 44 thread_.reset(NULL); | |
| 45 return false; | |
| 46 } | |
| 47 | |
| 48 // Initialize threading in dbus-glib - it should be fine for | 47 // Initialize threading in dbus-glib - it should be fine for |
| 49 // dbus_g_thread_init to be called multiple times. | 48 // dbus_g_thread_init to be called multiple times. |
| 50 if (!g_thread_supported()) | 49 if (!g_thread_supported()) |
| 51 g_thread_init(NULL); | 50 g_thread_init(NULL); |
| 52 dbus_g_thread_init(); | 51 dbus_g_thread_init(); |
| 53 | 52 |
| 54 // Get a connection to the session bus. | 53 // Get a connection to the session bus. |
| 55 connection_ = dbus_g_bus_get(DBUS_BUS_SESSION, &error_); | 54 connection_ = dbus_g_bus_get(DBUS_BUS_SESSION, &error_); |
| 56 if (CheckError()) | 55 if (CheckError()) |
| 57 return false; | 56 return false; |
| 58 | 57 |
| 59 if (!StartKWalletd()) return false; | 58 if (!InitWallet()) { |
| 60 if (!InitWallet()) return false; | 59 // kwalletd may not be running. Try to start it and try again. |
| 60 if (!StartKWalletd() || !InitWallet()) |
| 61 return false; |
| 62 } |
| 61 | 63 |
| 62 return true; | 64 return true; |
| 63 } | 65 } |
| 64 | 66 |
| 65 bool PasswordStoreKWallet::StartKWalletd() { | 67 bool PasswordStoreKWallet::StartKWalletd() { |
| 66 // Sadly kwalletd doesn't use DBUS activation, so we have to make a call to | 68 // Sadly kwalletd doesn't use DBUS activation, so we have to make a call to |
| 67 // klauncher to start it. | 69 // klauncher to start it. |
| 68 DBusGProxy* klauncher_proxy = | 70 DBusGProxy* klauncher_proxy = |
| 69 dbus_g_proxy_new_for_name(connection_, kKLauncherServiceName, | 71 dbus_g_proxy_new_for_name(connection_, kKLauncherServiceName, |
| 70 kKLauncherPath, kKLauncherInterface); | 72 kKLauncherPath, kKLauncherInterface); |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 127 return true; | 129 return true; |
| 128 } | 130 } |
| 129 | 131 |
| 130 void PasswordStoreKWallet::AddLoginImpl(const PasswordForm& form) { | 132 void PasswordStoreKWallet::AddLoginImpl(const PasswordForm& form) { |
| 131 AutoLock l(kwallet_lock_); | 133 AutoLock l(kwallet_lock_); |
| 132 int wallet_handle = WalletHandle(); | 134 int wallet_handle = WalletHandle(); |
| 133 if (wallet_handle == kInvalidKWalletHandle) | 135 if (wallet_handle == kInvalidKWalletHandle) |
| 134 return; | 136 return; |
| 135 | 137 |
| 136 PasswordFormList forms; | 138 PasswordFormList forms; |
| 137 GetLoginsList(&forms, form, wallet_handle); | 139 GetLoginsList(&forms, form.signon_realm, wallet_handle); |
| 138 | 140 |
| 139 forms.push_back(const_cast<PasswordForm*>(&form)); | 141 forms.push_back(new PasswordForm(form)); |
| 142 SetLoginsList(forms, form.signon_realm, wallet_handle); |
| 140 | 143 |
| 141 SetLoginsList(forms, form, wallet_handle); | 144 STLDeleteElements(&forms); |
| 142 } | 145 } |
| 143 | 146 |
| 144 void PasswordStoreKWallet::UpdateLoginImpl(const PasswordForm& form) { | 147 void PasswordStoreKWallet::UpdateLoginImpl(const PasswordForm& form) { |
| 145 AutoLock l(kwallet_lock_); | 148 AutoLock l(kwallet_lock_); |
| 146 int wallet_handle = WalletHandle(); | 149 int wallet_handle = WalletHandle(); |
| 147 if (wallet_handle == kInvalidKWalletHandle) | 150 if (wallet_handle == kInvalidKWalletHandle) |
| 148 return; | 151 return; |
| 149 | 152 |
| 150 PasswordFormList forms; | 153 PasswordFormList forms; |
| 151 GetLoginsList(&forms, form, wallet_handle); | 154 GetLoginsList(&forms, form.signon_realm, wallet_handle); |
| 152 | 155 |
| 153 for (uint i = 0; i < forms.size(); ++i) { | 156 for (size_t i = 0; i < forms.size(); ++i) { |
| 154 if (CompareForms(form, *forms[i])) { | 157 if (CompareForms(form, *forms[i], true)) |
| 155 forms.erase(forms.begin() + i); | 158 *forms[i] = form; |
| 156 forms.insert(forms.begin() + i, const_cast<PasswordForm*>(&form)); | |
| 157 } | |
| 158 } | 159 } |
| 159 | 160 |
| 160 SetLoginsList(forms, form, wallet_handle); | 161 SetLoginsList(forms, form.signon_realm, wallet_handle); |
| 162 |
| 163 STLDeleteElements(&forms); |
| 161 } | 164 } |
| 162 | 165 |
| 163 void PasswordStoreKWallet::RemoveLoginImpl(const PasswordForm& form) { | 166 void PasswordStoreKWallet::RemoveLoginImpl(const PasswordForm& form) { |
| 164 AutoLock l(kwallet_lock_); | 167 AutoLock l(kwallet_lock_); |
| 165 int wallet_handle = WalletHandle(); | 168 int wallet_handle = WalletHandle(); |
| 166 if (wallet_handle == kInvalidKWalletHandle) | 169 if (wallet_handle == kInvalidKWalletHandle) |
| 167 return; | 170 return; |
| 168 | 171 |
| 169 PasswordFormList forms; | 172 PasswordFormList all_forms; |
| 170 GetLoginsList(&forms, form, wallet_handle); | 173 GetLoginsList(&all_forms, form.signon_realm, wallet_handle); |
| 171 | 174 |
| 172 for (uint i = 0; i < forms.size(); ++i) { | 175 PasswordFormList kept_forms; |
| 173 if (CompareForms(form, *forms[i])) { | 176 kept_forms.reserve(all_forms.size()); |
| 174 forms.erase(forms.begin() + i); | 177 for (size_t i = 0; i < all_forms.size(); ++i) { |
| 175 --i; | 178 if (CompareForms(form, *all_forms[i], false)) |
| 176 } | 179 delete all_forms[i]; |
| 180 else |
| 181 kept_forms.push_back(all_forms[i]); |
| 177 } | 182 } |
| 178 | 183 |
| 179 if (forms.empty()) { | 184 // Update the entry in the wallet. |
| 180 // No items left? Remove the entry from the wallet. | 185 SetLoginsList(kept_forms, form.signon_realm, wallet_handle); |
| 181 int ret = 0; | 186 STLDeleteElements(&kept_forms); |
| 182 dbus_g_proxy_call(proxy_, "removeEntry", &error_, | |
| 183 G_TYPE_INT, wallet_handle, // handle | |
| 184 G_TYPE_STRING, kKWalletFolder, // folder | |
| 185 G_TYPE_STRING, form.signon_realm.c_str(), // key | |
| 186 G_TYPE_STRING, kAppId, // appid | |
| 187 G_TYPE_INVALID, | |
| 188 G_TYPE_INT, &ret, | |
| 189 G_TYPE_INVALID); | |
| 190 CheckError(); | |
| 191 if (ret) | |
| 192 LOG(ERROR) << "Bad return code " << ret << " from kwallet removeEntry"; | |
| 193 } else { | |
| 194 // Otherwise update the entry in the wallet. | |
| 195 SetLoginsList(forms, form, wallet_handle); | |
| 196 } | |
| 197 } | 187 } |
| 198 | 188 |
| 199 void PasswordStoreKWallet::GetLoginsImpl(GetLoginsRequest* request) { | 189 void PasswordStoreKWallet::RemoveLoginsCreatedBetweenImpl( |
| 190 const base::Time& delete_begin, |
| 191 const base::Time& delete_end) { |
| 192 AutoLock l(kwallet_lock_); |
| 193 int wallet_handle = WalletHandle(); |
| 194 if (wallet_handle == kInvalidKWalletHandle) |
| 195 return; |
| 196 |
| 197 // We could probably also use readEntryList here. |
| 198 char** realm_list = NULL; |
| 199 dbus_g_proxy_call(proxy_, "entryList", &error_, |
| 200 G_TYPE_INT, wallet_handle, // handle |
| 201 G_TYPE_STRING, kKWalletFolder, // folder |
| 202 G_TYPE_STRING, kAppId, // appid |
| 203 G_TYPE_INVALID, |
| 204 G_TYPE_STRV, &realm_list, |
| 205 G_TYPE_INVALID); |
| 206 if (CheckError()) |
| 207 return; |
| 208 |
| 209 for (char** realm = realm_list; *realm; ++realm) { |
| 210 GArray* byte_array = NULL; |
| 211 dbus_g_proxy_call(proxy_, "readEntry", &error_, |
| 212 G_TYPE_INT, wallet_handle, // handle |
| 213 G_TYPE_STRING, kKWalletFolder, // folder |
| 214 G_TYPE_STRING, *realm, // key |
| 215 G_TYPE_STRING, kAppId, // appid |
| 216 G_TYPE_INVALID, |
| 217 DBUS_TYPE_G_UCHAR_ARRAY, &byte_array, |
| 218 G_TYPE_INVALID); |
| 219 |
| 220 if (CheckError() || !byte_array || !byte_array->len) |
| 221 continue; |
| 222 |
| 223 string signon_realm(*realm); |
| 224 Pickle pickle(byte_array->data, byte_array->len); |
| 225 PasswordFormList all_forms; |
| 226 DeserializeValue(signon_realm, pickle, &all_forms); |
| 227 g_array_free(byte_array, true); |
| 228 |
| 229 PasswordFormList kept_forms; |
| 230 kept_forms.reserve(all_forms.size()); |
| 231 for (size_t i = 0; i < all_forms.size(); ++i) { |
| 232 if (delete_begin <= all_forms[i]->date_created && |
| 233 (delete_end.is_null() || all_forms[i]->date_created < delete_end)) { |
| 234 delete all_forms[i]; |
| 235 } else { |
| 236 kept_forms.push_back(all_forms[i]); |
| 237 } |
| 238 } |
| 239 |
| 240 SetLoginsList(kept_forms, signon_realm, wallet_handle); |
| 241 STLDeleteElements(&kept_forms); |
| 242 } |
| 243 g_strfreev(realm_list); |
| 244 } |
| 245 |
| 246 void PasswordStoreKWallet::GetLoginsImpl(GetLoginsRequest* request, |
| 247 const PasswordForm& form) { |
| 200 PasswordFormList forms; | 248 PasswordFormList forms; |
| 201 | 249 |
| 202 AutoLock l(kwallet_lock_); | 250 AutoLock l(kwallet_lock_); |
| 203 int wallet_handle = WalletHandle(); | 251 int wallet_handle = WalletHandle(); |
| 204 if (wallet_handle != kInvalidKWalletHandle) | 252 if (wallet_handle != kInvalidKWalletHandle) |
| 205 GetLoginsList(&forms, request->form, wallet_handle); | 253 GetLoginsList(&forms, form.signon_realm, wallet_handle); |
| 206 | 254 |
| 207 NotifyConsumer(request, forms); | 255 NotifyConsumer(request, forms); |
| 208 } | 256 } |
| 209 | 257 |
| 258 void PasswordStoreKWallet::GetAutofillableLoginsImpl( |
| 259 GetLoginsRequest* request) { |
| 260 std::vector<PasswordForm*> forms; |
| 261 FillAutofillableLogins(&forms); |
| 262 NotifyConsumer(request, forms); |
| 263 } |
| 264 |
| 265 void PasswordStoreKWallet::GetBlacklistLoginsImpl( |
| 266 GetLoginsRequest* request) { |
| 267 std::vector<PasswordForm*> forms; |
| 268 FillBlacklistLogins(&forms); |
| 269 NotifyConsumer(request, forms); |
| 270 } |
| 271 |
| 272 bool PasswordStoreKWallet::FillAutofillableLogins( |
| 273 std::vector<PasswordForm*>* forms) { |
| 274 return FillSomeLogins(true, forms); |
| 275 } |
| 276 |
| 277 bool PasswordStoreKWallet::FillBlacklistLogins( |
| 278 std::vector<PasswordForm*>* forms) { |
| 279 return FillSomeLogins(false, forms); |
| 280 } |
| 281 |
| 210 void PasswordStoreKWallet::GetLoginsList(PasswordFormList* forms, | 282 void PasswordStoreKWallet::GetLoginsList(PasswordFormList* forms, |
| 211 const PasswordForm& key, | 283 const string& signon_realm, |
| 212 int wallet_handle) { | 284 int wallet_handle) { |
| 213 // Is there an entry in the wallet? | 285 // Is there an entry in the wallet? |
| 214 gboolean has_entry = false; | 286 gboolean has_entry = false; |
| 215 dbus_g_proxy_call(proxy_, "hasEntry", &error_, | 287 dbus_g_proxy_call(proxy_, "hasEntry", &error_, |
| 216 G_TYPE_INT, wallet_handle, // handle | 288 G_TYPE_INT, wallet_handle, // handle |
| 217 G_TYPE_STRING, kKWalletFolder, // folder | 289 G_TYPE_STRING, kKWalletFolder, // folder |
| 218 G_TYPE_STRING, key.signon_realm.c_str(), // key | 290 G_TYPE_STRING, signon_realm.c_str(), // key |
| 219 G_TYPE_STRING, kAppId, // appid | 291 G_TYPE_STRING, kAppId, // appid |
| 220 G_TYPE_INVALID, | 292 G_TYPE_INVALID, |
| 221 G_TYPE_BOOLEAN, &has_entry, | 293 G_TYPE_BOOLEAN, &has_entry, |
| 222 G_TYPE_INVALID); | 294 G_TYPE_INVALID); |
| 223 | 295 |
| 224 if (CheckError() || !has_entry) | 296 if (CheckError() || !has_entry) |
| 225 return; | 297 return; |
| 226 | 298 |
| 227 GArray* byte_array = NULL; | 299 GArray* byte_array = NULL; |
| 228 dbus_g_proxy_call(proxy_, "readEntry", &error_, | 300 dbus_g_proxy_call(proxy_, "readEntry", &error_, |
| 229 G_TYPE_INT, wallet_handle, // handle | 301 G_TYPE_INT, wallet_handle, // handle |
| 230 G_TYPE_STRING, kKWalletFolder, // folder | 302 G_TYPE_STRING, kKWalletFolder, // folder |
| 231 G_TYPE_STRING, key.signon_realm.c_str(), // key | 303 G_TYPE_STRING, signon_realm.c_str(), // key |
| 232 G_TYPE_STRING, kAppId, // appid | 304 G_TYPE_STRING, kAppId, // appid |
| 233 G_TYPE_INVALID, | 305 G_TYPE_INVALID, |
| 234 DBUS_TYPE_G_UCHAR_ARRAY, &byte_array, | 306 DBUS_TYPE_G_UCHAR_ARRAY, &byte_array, |
| 235 G_TYPE_INVALID); | 307 G_TYPE_INVALID); |
| 236 | 308 |
| 237 if (CheckError() || !byte_array || !byte_array->len) | 309 if (CheckError() || !byte_array || !byte_array->len) |
| 238 return; | 310 return; |
| 239 | 311 |
| 240 Pickle pickle(byte_array->data, byte_array->len); | 312 Pickle pickle(byte_array->data, byte_array->len); |
| 241 DeserializeValue(key, pickle, forms); | 313 DeserializeValue(signon_realm, pickle, forms); |
| 314 g_array_free(byte_array, true); |
| 242 } | 315 } |
| 243 | 316 |
| 244 void PasswordStoreKWallet::SetLoginsList(const PasswordFormList& forms, | 317 void PasswordStoreKWallet::SetLoginsList(const PasswordFormList& forms, |
| 245 const PasswordForm& key, | 318 const string& signon_realm, |
| 246 int wallet_handle) { | 319 int wallet_handle) { |
| 320 if (forms.empty()) { |
| 321 // No items left? Remove the entry from the wallet. |
| 322 int ret = 0; |
| 323 dbus_g_proxy_call(proxy_, "removeEntry", &error_, |
| 324 G_TYPE_INT, wallet_handle, // handle |
| 325 G_TYPE_STRING, kKWalletFolder, // folder |
| 326 G_TYPE_STRING, signon_realm.c_str(), // key |
| 327 G_TYPE_STRING, kAppId, // appid |
| 328 G_TYPE_INVALID, |
| 329 G_TYPE_INT, &ret, |
| 330 G_TYPE_INVALID); |
| 331 CheckError(); |
| 332 if (ret != 0) |
| 333 LOG(ERROR) << "Bad return code " << ret << " from kwallet removeEntry"; |
| 334 return; |
| 335 } |
| 336 |
| 247 Pickle value; | 337 Pickle value; |
| 248 SerializeValue(forms, &value); | 338 SerializeValue(forms, &value); |
| 249 | 339 |
| 250 // Convert the pickled bytes to a GByteArray. | 340 // Convert the pickled bytes to a GByteArray. |
| 251 GArray* byte_array = g_array_sized_new(false, false, sizeof(char), | 341 GArray* byte_array = g_array_sized_new(false, false, sizeof(char), |
| 252 value.size()); | 342 value.size()); |
| 253 g_array_append_vals(byte_array, value.data(), value.size()); | 343 g_array_append_vals(byte_array, value.data(), value.size()); |
| 254 | 344 |
| 255 // Make the call. | 345 // Make the call. |
| 256 int ret = 0; | 346 int ret = 0; |
| 257 dbus_g_proxy_call(proxy_, "writeEntry", &error_, | 347 dbus_g_proxy_call(proxy_, "writeEntry", &error_, |
| 258 G_TYPE_INT, wallet_handle, // handle | 348 G_TYPE_INT, wallet_handle, // handle |
| 259 G_TYPE_STRING, kKWalletFolder, // folder | 349 G_TYPE_STRING, kKWalletFolder, // folder |
| 260 G_TYPE_STRING, key.signon_realm.c_str(), // key | 350 G_TYPE_STRING, signon_realm.c_str(), // key |
| 261 DBUS_TYPE_G_UCHAR_ARRAY, byte_array, // value | 351 DBUS_TYPE_G_UCHAR_ARRAY, byte_array, // value |
| 262 G_TYPE_STRING, kAppId, // appid | 352 G_TYPE_STRING, kAppId, // appid |
| 263 G_TYPE_INVALID, | 353 G_TYPE_INVALID, |
| 264 G_TYPE_INT, &ret, | 354 G_TYPE_INT, &ret, |
| 265 G_TYPE_INVALID); | 355 G_TYPE_INVALID); |
| 266 g_array_free(byte_array, true); | 356 g_array_free(byte_array, true); |
| 267 | 357 |
| 268 CheckError(); | 358 CheckError(); |
| 269 if (ret) | 359 if (ret != 0) |
| 270 LOG(ERROR) << "Bad return code " << ret << " from kwallet writeEntry"; | 360 LOG(ERROR) << "Bad return code " << ret << " from kwallet writeEntry"; |
| 271 } | 361 } |
| 272 | 362 |
| 363 bool PasswordStoreKWallet::FillSomeLogins(bool autofillable, |
| 364 PasswordFormList* forms) { |
| 365 AutoLock l(kwallet_lock_); |
| 366 int wallet_handle = WalletHandle(); |
| 367 if (wallet_handle == kInvalidKWalletHandle) |
| 368 return false; |
| 369 |
| 370 // We could probably also use readEntryList here. |
| 371 char** realm_list = NULL; |
| 372 dbus_g_proxy_call(proxy_, "entryList", &error_, |
| 373 G_TYPE_INT, wallet_handle, // handle |
| 374 G_TYPE_STRING, kKWalletFolder, // folder |
| 375 G_TYPE_STRING, kAppId, // appid |
| 376 G_TYPE_INVALID, |
| 377 G_TYPE_STRV, &realm_list, |
| 378 G_TYPE_INVALID); |
| 379 if (CheckError()) |
| 380 return false; |
| 381 |
| 382 PasswordFormList all_forms; |
| 383 for (char** realm = realm_list; *realm; ++realm) { |
| 384 GArray* byte_array = NULL; |
| 385 dbus_g_proxy_call(proxy_, "readEntry", &error_, |
| 386 G_TYPE_INT, wallet_handle, // handle |
| 387 G_TYPE_STRING, kKWalletFolder, // folder |
| 388 G_TYPE_STRING, *realm, // key |
| 389 G_TYPE_STRING, kAppId, // appid |
| 390 G_TYPE_INVALID, |
| 391 DBUS_TYPE_G_UCHAR_ARRAY, &byte_array, |
| 392 G_TYPE_INVALID); |
| 393 |
| 394 if (CheckError() || !byte_array || !byte_array->len) |
| 395 continue; |
| 396 |
| 397 Pickle pickle(byte_array->data, byte_array->len); |
| 398 DeserializeValue(*realm, pickle, &all_forms); |
| 399 g_array_free(byte_array, true); |
| 400 } |
| 401 g_strfreev(realm_list); |
| 402 |
| 403 // We have to read all the entries, and then filter them here. |
| 404 forms->reserve(forms->size() + all_forms.size()); |
| 405 for (size_t i = 0; i < all_forms.size(); ++i) { |
| 406 if (all_forms[i]->blacklisted_by_user == !autofillable) |
| 407 forms->push_back(all_forms[i]); |
| 408 else |
| 409 delete all_forms[i]; |
| 410 } |
| 411 |
| 412 return true; |
| 413 } |
| 414 |
| 273 bool PasswordStoreKWallet::CompareForms(const PasswordForm& a, | 415 bool PasswordStoreKWallet::CompareForms(const PasswordForm& a, |
| 274 const PasswordForm& b) { | 416 const PasswordForm& b, |
| 417 bool update_check) { |
| 418 // An update check doesn't care about the submit element. |
| 419 if (!update_check && a.submit_element != b.submit_element) |
| 420 return false; |
| 275 return a.origin == b.origin && | 421 return a.origin == b.origin && |
| 276 a.password_element == b.password_element && | 422 a.password_element == b.password_element && |
| 277 a.signon_realm == b.signon_realm && | 423 a.signon_realm == b.signon_realm && |
| 278 a.submit_element == b.submit_element && | |
| 279 a.username_element == b.username_element && | 424 a.username_element == b.username_element && |
| 280 a.username_value == b.username_value; | 425 a.username_value == b.username_value; |
| 281 } | 426 } |
| 282 | 427 |
| 283 void PasswordStoreKWallet::SerializeValue(const PasswordFormList& forms, | 428 void PasswordStoreKWallet::SerializeValue(const PasswordFormList& forms, |
| 284 Pickle* pickle) { | 429 Pickle* pickle) { |
| 285 pickle->WriteInt(forms.size()); | 430 pickle->WriteInt(kPickleVersion); |
| 431 pickle->WriteSize(forms.size()); |
| 286 for (PasswordFormList::const_iterator it = forms.begin() ; | 432 for (PasswordFormList::const_iterator it = forms.begin() ; |
| 287 it != forms.end() ; ++it) { | 433 it != forms.end() ; ++it) { |
| 288 const PasswordForm* form = *it; | 434 const PasswordForm* form = *it; |
| 289 pickle->WriteInt(form->scheme); | 435 pickle->WriteInt(form->scheme); |
| 290 pickle->WriteString(form->origin.spec()); | 436 pickle->WriteString(form->origin.spec()); |
| 291 pickle->WriteString(form->action.spec()); | 437 pickle->WriteString(form->action.spec()); |
| 292 pickle->WriteWString(form->username_element); | 438 pickle->WriteString16(form->username_element); |
| 293 pickle->WriteWString(form->username_value); | 439 pickle->WriteString16(form->username_value); |
| 294 pickle->WriteWString(form->password_element); | 440 pickle->WriteString16(form->password_element); |
| 295 pickle->WriteWString(form->password_value); | 441 pickle->WriteString16(form->password_value); |
| 296 pickle->WriteWString(form->submit_element); | 442 pickle->WriteString16(form->submit_element); |
| 297 pickle->WriteBool(form->ssl_valid); | 443 pickle->WriteBool(form->ssl_valid); |
| 298 pickle->WriteBool(form->preferred); | 444 pickle->WriteBool(form->preferred); |
| 299 pickle->WriteBool(form->blacklisted_by_user); | 445 pickle->WriteBool(form->blacklisted_by_user); |
| 446 pickle->WriteInt64(form->date_created.ToTimeT()); |
| 300 } | 447 } |
| 301 } | 448 } |
| 302 | 449 |
| 303 void PasswordStoreKWallet::DeserializeValue(const PasswordForm& key, | 450 void PasswordStoreKWallet::DeserializeValue(const string& signon_realm, |
| 304 const Pickle& pickle, | 451 const Pickle& pickle, |
| 305 PasswordFormList* forms) { | 452 PasswordFormList* forms) { |
| 306 void* iter = NULL; | 453 void* iter = NULL; |
| 307 | 454 |
| 308 int count = 0; | 455 int version = -1; |
| 309 pickle.ReadInt(&iter, &count); | 456 pickle.ReadInt(&iter, &version); |
| 457 if (version != kPickleVersion) { |
| 458 // This is the only version so far, so anything else is an error. |
| 459 return; |
| 460 } |
| 310 | 461 |
| 311 for (int i = 0; i < count; ++i) { | 462 size_t count = 0; |
| 463 pickle.ReadSize(&iter, &count); |
| 464 |
| 465 forms->reserve(forms->size() + count); |
| 466 for (size_t i = 0; i < count; ++i) { |
| 312 PasswordForm* form = new PasswordForm(); | 467 PasswordForm* form = new PasswordForm(); |
| 313 form->signon_realm.assign(key.signon_realm); | 468 form->signon_realm.assign(signon_realm); |
| 314 | 469 |
| 315 pickle.ReadInt(&iter, reinterpret_cast<int*>(&form->scheme)); | 470 int scheme = 0; |
| 471 pickle.ReadInt(&iter, &scheme); |
| 472 form->scheme = static_cast<PasswordForm::Scheme>(scheme); |
| 316 ReadGURL(pickle, &iter, &form->origin); | 473 ReadGURL(pickle, &iter, &form->origin); |
| 317 ReadGURL(pickle, &iter, &form->action); | 474 ReadGURL(pickle, &iter, &form->action); |
| 318 pickle.ReadWString(&iter, &form->username_element); | 475 pickle.ReadString16(&iter, &form->username_element); |
| 319 pickle.ReadWString(&iter, &form->username_value); | 476 pickle.ReadString16(&iter, &form->username_value); |
| 320 pickle.ReadWString(&iter, &form->password_element); | 477 pickle.ReadString16(&iter, &form->password_element); |
| 321 pickle.ReadWString(&iter, &form->password_value); | 478 pickle.ReadString16(&iter, &form->password_value); |
| 322 pickle.ReadWString(&iter, &form->submit_element); | 479 pickle.ReadString16(&iter, &form->submit_element); |
| 323 pickle.ReadBool(&iter, &form->ssl_valid); | 480 pickle.ReadBool(&iter, &form->ssl_valid); |
| 324 pickle.ReadBool(&iter, &form->preferred); | 481 pickle.ReadBool(&iter, &form->preferred); |
| 325 pickle.ReadBool(&iter, &form->blacklisted_by_user); | 482 pickle.ReadBool(&iter, &form->blacklisted_by_user); |
| 483 int64 date_created = 0; |
| 484 pickle.ReadInt64(&iter, &date_created); |
| 485 form->date_created = base::Time::FromTimeT(date_created); |
| 326 forms->push_back(form); | 486 forms->push_back(form); |
| 327 } | 487 } |
| 328 } | 488 } |
| 329 | 489 |
| 330 void PasswordStoreKWallet::ReadGURL(const Pickle& pickle, void** iter, | 490 void PasswordStoreKWallet::ReadGURL(const Pickle& pickle, void** iter, |
| 331 GURL* url) { | 491 GURL* url) { |
| 332 string url_string; | 492 string url_string; |
| 333 pickle.ReadString(iter, &url_string); | 493 pickle.ReadString(iter, &url_string); |
| 334 *url = GURL(url_string); | 494 *url = GURL(url_string); |
| 335 } | 495 } |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 378 G_TYPE_STRING, kAppId, // appid | 538 G_TYPE_STRING, kAppId, // appid |
| 379 G_TYPE_INVALID, | 539 G_TYPE_INVALID, |
| 380 G_TYPE_BOOLEAN, &success, | 540 G_TYPE_BOOLEAN, &success, |
| 381 G_TYPE_INVALID); | 541 G_TYPE_INVALID); |
| 382 if (CheckError() || !success) | 542 if (CheckError() || !success) |
| 383 return kInvalidKWalletHandle; | 543 return kInvalidKWalletHandle; |
| 384 } | 544 } |
| 385 | 545 |
| 386 return handle; | 546 return handle; |
| 387 } | 547 } |
| OLD | NEW |