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 |