OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 <stddef.h> | 7 #include <stddef.h> |
8 #include <stdint.h> | 8 #include <stdint.h> |
9 | 9 |
| 10 #include <iterator> |
10 #include <map> | 11 #include <map> |
11 #include <utility> | 12 #include <utility> |
12 #include <vector> | 13 #include <vector> |
13 | 14 |
14 #include "base/bind.h" | 15 #include "base/bind.h" |
15 #include "base/logging.h" | 16 #include "base/logging.h" |
| 17 #include "base/memory/ptr_util.h" |
16 #include "base/metrics/histogram_macros.h" | 18 #include "base/metrics/histogram_macros.h" |
17 #include "base/pickle.h" | 19 #include "base/pickle.h" |
18 #include "base/stl_util.h" | 20 #include "base/stl_util.h" |
19 #include "base/strings/stringprintf.h" | 21 #include "base/strings/stringprintf.h" |
20 #include "base/synchronization/waitable_event.h" | 22 #include "base/synchronization/waitable_event.h" |
21 #include "base/threading/thread_restrictions.h" | 23 #include "base/threading/thread_restrictions.h" |
22 #include "chrome/grit/chromium_strings.h" | 24 #include "chrome/grit/chromium_strings.h" |
23 #include "components/autofill/core/common/password_form.h" | 25 #include "components/autofill/core/common/password_form.h" |
24 #include "components/password_manager/core/browser/password_manager_util.h" | 26 #include "components/password_manager/core/browser/password_manager_util.h" |
25 #include "content/public/browser/browser_thread.h" | 27 #include "content/public/browser/browser_thread.h" |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
107 // the pickle as 32 bits. We used to use Pickle::WriteSize() to write the number | 109 // the pickle as 32 bits. We used to use Pickle::WriteSize() to write the number |
108 // of password forms, but that has a different size on 32- and 64-bit systems. | 110 // of password forms, but that has a different size on 32- and 64-bit systems. |
109 // So, now we always write a 64-bit quantity, but we support trying to read it | 111 // So, now we always write a 64-bit quantity, but we support trying to read it |
110 // as either size when reading old pickles that fail to deserialize using the | 112 // as either size when reading old pickles that fail to deserialize using the |
111 // native size. Returns true on success. | 113 // native size. Returns true on success. |
112 bool DeserializeValueSize(const std::string& signon_realm, | 114 bool DeserializeValueSize(const std::string& signon_realm, |
113 const base::PickleIterator& init_iter, | 115 const base::PickleIterator& init_iter, |
114 int version, | 116 int version, |
115 bool size_32, | 117 bool size_32, |
116 bool warn_only, | 118 bool warn_only, |
117 ScopedVector<autofill::PasswordForm>* forms) { | 119 std::vector<std::unique_ptr<PasswordForm>>* forms) { |
118 base::PickleIterator iter = init_iter; | 120 base::PickleIterator iter = init_iter; |
119 | 121 |
120 size_t count = 0; | 122 size_t count = 0; |
121 if (size_32) { | 123 if (size_32) { |
122 uint32_t count_32 = 0; | 124 uint32_t count_32 = 0; |
123 if (!iter.ReadUInt32(&count_32)) { | 125 if (!iter.ReadUInt32(&count_32)) { |
124 LOG(ERROR) << "Failed to deserialize KWallet entry " | 126 LOG(ERROR) << "Failed to deserialize KWallet entry " |
125 << "(realm: " << signon_realm << ")"; | 127 << "(realm: " << signon_realm << ")"; |
126 return false; | 128 return false; |
127 } | 129 } |
(...skipping 17 matching lines...) Expand all Loading... |
145 // read it. (That is, when we're reading the native architecture size.) | 147 // read it. (That is, when we're reading the native architecture size.) |
146 if (!warn_only) { | 148 if (!warn_only) { |
147 LOG(ERROR) << "Suspiciously large number of entries in KWallet entry " | 149 LOG(ERROR) << "Suspiciously large number of entries in KWallet entry " |
148 << "(" << count << "; realm: " << signon_realm << ")"; | 150 << "(" << count << "; realm: " << signon_realm << ")"; |
149 } | 151 } |
150 return false; | 152 return false; |
151 } | 153 } |
152 | 154 |
153 // We'll swap |converted_forms| with |*forms| on success, to make sure we | 155 // We'll swap |converted_forms| with |*forms| on success, to make sure we |
154 // don't return partial results on failure. | 156 // don't return partial results on failure. |
155 ScopedVector<autofill::PasswordForm> converted_forms; | 157 std::vector<std::unique_ptr<PasswordForm>> converted_forms; |
156 converted_forms.reserve(count); | 158 converted_forms.reserve(count); |
157 for (size_t i = 0; i < count; ++i) { | 159 for (size_t i = 0; i < count; ++i) { |
158 std::unique_ptr<PasswordForm> form(new PasswordForm()); | 160 std::unique_ptr<PasswordForm> form(new PasswordForm()); |
159 form->signon_realm.assign(signon_realm); | 161 form->signon_realm.assign(signon_realm); |
160 | 162 |
161 int scheme = 0; | 163 int scheme = 0; |
162 int64_t date_created = 0; | 164 int64_t date_created = 0; |
163 int type = 0; | 165 int type = 0; |
164 int generation_upload_status = 0; | 166 int generation_upload_status = 0; |
165 // Note that these will be read back in the order listed due to | 167 // Note that these will be read back in the order listed due to |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
242 } | 244 } |
243 | 245 |
244 converted_forms.push_back(std::move(form)); | 246 converted_forms.push_back(std::move(form)); |
245 } | 247 } |
246 | 248 |
247 forms->swap(converted_forms); | 249 forms->swap(converted_forms); |
248 return true; | 250 return true; |
249 } | 251 } |
250 | 252 |
251 // Serializes a list of PasswordForms to be stored in the wallet. | 253 // Serializes a list of PasswordForms to be stored in the wallet. |
252 void SerializeValue(const std::vector<autofill::PasswordForm*>& forms, | 254 void SerializeValue(const std::vector<std::unique_ptr<PasswordForm>>& forms, |
253 base::Pickle* pickle) { | 255 base::Pickle* pickle) { |
254 pickle->WriteInt(kPickleVersion); | 256 pickle->WriteInt(kPickleVersion); |
255 pickle->WriteUInt64(forms.size()); | 257 pickle->WriteUInt64(forms.size()); |
256 for (autofill::PasswordForm* form : forms) { | 258 for (const auto& form : forms) { |
257 pickle->WriteInt(form->scheme); | 259 pickle->WriteInt(form->scheme); |
258 pickle->WriteString(form->origin.spec()); | 260 pickle->WriteString(form->origin.spec()); |
259 pickle->WriteString(form->action.spec()); | 261 pickle->WriteString(form->action.spec()); |
260 pickle->WriteString16(form->username_element); | 262 pickle->WriteString16(form->username_element); |
261 pickle->WriteString16(form->username_value); | 263 pickle->WriteString16(form->username_value); |
262 pickle->WriteString16(form->password_element); | 264 pickle->WriteString16(form->password_element); |
263 pickle->WriteString16(form->password_value); | 265 pickle->WriteString16(form->password_value); |
264 pickle->WriteString16(form->submit_element); | 266 pickle->WriteString16(form->submit_element); |
265 pickle->WriteBool(form->preferred); | 267 pickle->WriteBool(form->preferred); |
266 pickle->WriteBool(form->blacklisted_by_user); | 268 pickle->WriteBool(form->blacklisted_by_user); |
267 pickle->WriteInt64(form->date_created.ToInternalValue()); | 269 pickle->WriteInt64(form->date_created.ToInternalValue()); |
268 pickle->WriteInt(form->type); | 270 pickle->WriteInt(form->type); |
269 pickle->WriteInt(form->times_used); | 271 pickle->WriteInt(form->times_used); |
270 autofill::SerializeFormData(form->form_data, pickle); | 272 autofill::SerializeFormData(form->form_data, pickle); |
271 pickle->WriteInt64(form->date_synced.ToInternalValue()); | 273 pickle->WriteInt64(form->date_synced.ToInternalValue()); |
272 pickle->WriteString16(form->display_name); | 274 pickle->WriteString16(form->display_name); |
273 pickle->WriteString(form->icon_url.spec()); | 275 pickle->WriteString(form->icon_url.spec()); |
274 // We serialize unique origins as "", in order to make other systems that | 276 // We serialize unique origins as "", in order to make other systems that |
275 // read from the login database happy. https://crbug.com/591310 | 277 // read from the login database happy. https://crbug.com/591310 |
276 pickle->WriteString(form->federation_origin.unique() | 278 pickle->WriteString(form->federation_origin.unique() |
277 ? std::string() | 279 ? std::string() |
278 : form->federation_origin.Serialize()); | 280 : form->federation_origin.Serialize()); |
279 pickle->WriteBool(form->skip_zero_click); | 281 pickle->WriteBool(form->skip_zero_click); |
280 pickle->WriteInt(form->generation_upload_status); | 282 pickle->WriteInt(form->generation_upload_status); |
281 } | 283 } |
282 } | 284 } |
283 | 285 |
284 // Moves the content of |second| to the end of |first|. | |
285 void AppendSecondToFirst(ScopedVector<autofill::PasswordForm>* first, | |
286 ScopedVector<autofill::PasswordForm> second) { | |
287 first->reserve(first->size() + second.size()); | |
288 first->insert(first->end(), second.begin(), second.end()); | |
289 second.weak_clear(); | |
290 } | |
291 | |
292 void UMALogDeserializationStatus(bool success) { | 286 void UMALogDeserializationStatus(bool success) { |
293 UMA_HISTOGRAM_BOOLEAN("PasswordManager.KWalletDeserializationStatus", | 287 UMA_HISTOGRAM_BOOLEAN("PasswordManager.KWalletDeserializationStatus", |
294 success); | 288 success); |
295 } | 289 } |
296 | 290 |
297 } // namespace | 291 } // namespace |
298 | 292 |
299 NativeBackendKWallet::NativeBackendKWallet( | 293 NativeBackendKWallet::NativeBackendKWallet( |
300 LocalProfileId id, | 294 LocalProfileId id, |
301 base::nix::DesktopEnvironment desktop_env) | 295 base::nix::DesktopEnvironment desktop_env) |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
399 NOTREACHED(); | 393 NOTREACHED(); |
400 return PERMANENT_FAIL; | 394 return PERMANENT_FAIL; |
401 } | 395 } |
402 | 396 |
403 password_manager::PasswordStoreChangeList NativeBackendKWallet::AddLogin( | 397 password_manager::PasswordStoreChangeList NativeBackendKWallet::AddLogin( |
404 const PasswordForm& form) { | 398 const PasswordForm& form) { |
405 int wallet_handle = WalletHandle(); | 399 int wallet_handle = WalletHandle(); |
406 if (wallet_handle == kInvalidKWalletHandle) | 400 if (wallet_handle == kInvalidKWalletHandle) |
407 return password_manager::PasswordStoreChangeList(); | 401 return password_manager::PasswordStoreChangeList(); |
408 | 402 |
409 ScopedVector<autofill::PasswordForm> forms; | 403 std::vector<std::unique_ptr<PasswordForm>> forms; |
410 if (!GetLoginsList(form.signon_realm, wallet_handle, &forms)) | 404 if (!GetLoginsList(form.signon_realm, wallet_handle, &forms)) |
411 return password_manager::PasswordStoreChangeList(); | 405 return password_manager::PasswordStoreChangeList(); |
412 | 406 |
413 auto it = std::partition(forms.begin(), forms.end(), | 407 auto it = std::partition( |
414 [&form](const PasswordForm* current_form) { | 408 forms.begin(), forms.end(), |
415 return !ArePasswordFormUniqueKeyEqual(form, *current_form); | 409 [&form](const std::unique_ptr<PasswordForm>& current_form) { |
416 }); | 410 return !ArePasswordFormUniqueKeyEqual(form, *current_form); |
| 411 }); |
417 password_manager::PasswordStoreChangeList changes; | 412 password_manager::PasswordStoreChangeList changes; |
418 if (it != forms.end()) { | 413 if (it != forms.end()) { |
419 // It's an update. | 414 // It's an update. |
420 changes.push_back(password_manager::PasswordStoreChange( | 415 changes.push_back(password_manager::PasswordStoreChange( |
421 password_manager::PasswordStoreChange::REMOVE, **it)); | 416 password_manager::PasswordStoreChange::REMOVE, **it)); |
422 forms.erase(it, forms.end()); | 417 forms.erase(it, forms.end()); |
423 } | 418 } |
424 | 419 |
425 forms.push_back(new PasswordForm(form)); | 420 forms.push_back(base::MakeUnique<PasswordForm>(form)); |
426 changes.push_back(password_manager::PasswordStoreChange( | 421 changes.push_back(password_manager::PasswordStoreChange( |
427 password_manager::PasswordStoreChange::ADD, form)); | 422 password_manager::PasswordStoreChange::ADD, form)); |
428 | 423 |
429 bool ok = SetLoginsList(forms.get(), form.signon_realm, wallet_handle); | 424 bool ok = SetLoginsList(forms, form.signon_realm, wallet_handle); |
430 if (!ok) | 425 if (!ok) |
431 changes.clear(); | 426 changes.clear(); |
432 | 427 |
433 return changes; | 428 return changes; |
434 } | 429 } |
435 | 430 |
436 bool NativeBackendKWallet::UpdateLogin( | 431 bool NativeBackendKWallet::UpdateLogin( |
437 const PasswordForm& form, | 432 const PasswordForm& form, |
438 password_manager::PasswordStoreChangeList* changes) { | 433 password_manager::PasswordStoreChangeList* changes) { |
439 DCHECK(changes); | 434 DCHECK(changes); |
440 int wallet_handle = WalletHandle(); | 435 int wallet_handle = WalletHandle(); |
441 if (wallet_handle == kInvalidKWalletHandle) | 436 if (wallet_handle == kInvalidKWalletHandle) |
442 return false; | 437 return false; |
443 | 438 |
444 ScopedVector<autofill::PasswordForm> forms; | 439 std::vector<std::unique_ptr<PasswordForm>> forms; |
445 if (!GetLoginsList(form.signon_realm, wallet_handle, &forms)) | 440 if (!GetLoginsList(form.signon_realm, wallet_handle, &forms)) |
446 return false; | 441 return false; |
447 | 442 |
448 auto it = std::partition(forms.begin(), forms.end(), | 443 auto it = std::partition( |
449 [&form](const PasswordForm* current_form) { | 444 forms.begin(), forms.end(), |
450 return !ArePasswordFormUniqueKeyEqual(form, *current_form); | 445 [&form](const std::unique_ptr<PasswordForm>& current_form) { |
451 }); | 446 return !ArePasswordFormUniqueKeyEqual(form, *current_form); |
| 447 }); |
452 | 448 |
453 if (it == forms.end()) | 449 if (it == forms.end()) |
454 return true; | 450 return true; |
455 | 451 |
456 forms.erase(it, forms.end()); | 452 forms.erase(it, forms.end()); |
457 forms.push_back(new PasswordForm(form)); | 453 forms.push_back(base::MakeUnique<PasswordForm>(form)); |
458 if (SetLoginsList(forms.get(), form.signon_realm, wallet_handle)) { | 454 if (SetLoginsList(forms, form.signon_realm, wallet_handle)) { |
459 changes->push_back(password_manager::PasswordStoreChange( | 455 changes->push_back(password_manager::PasswordStoreChange( |
460 password_manager::PasswordStoreChange::UPDATE, form)); | 456 password_manager::PasswordStoreChange::UPDATE, form)); |
461 return true; | 457 return true; |
462 } | 458 } |
463 | 459 |
464 return false; | 460 return false; |
465 } | 461 } |
466 | 462 |
467 bool NativeBackendKWallet::RemoveLogin( | 463 bool NativeBackendKWallet::RemoveLogin( |
468 const PasswordForm& form, | 464 const PasswordForm& form, |
469 password_manager::PasswordStoreChangeList* changes) { | 465 password_manager::PasswordStoreChangeList* changes) { |
470 DCHECK(changes); | 466 DCHECK(changes); |
471 int wallet_handle = WalletHandle(); | 467 int wallet_handle = WalletHandle(); |
472 if (wallet_handle == kInvalidKWalletHandle) | 468 if (wallet_handle == kInvalidKWalletHandle) |
473 return false; | 469 return false; |
474 | 470 |
475 ScopedVector<autofill::PasswordForm> all_forms; | 471 std::vector<std::unique_ptr<PasswordForm>> all_forms; |
476 if (!GetLoginsList(form.signon_realm, wallet_handle, &all_forms)) | 472 if (!GetLoginsList(form.signon_realm, wallet_handle, &all_forms)) |
477 return false; | 473 return false; |
478 | 474 |
479 ScopedVector<autofill::PasswordForm> kept_forms; | 475 std::vector<std::unique_ptr<PasswordForm>> kept_forms; |
480 kept_forms.reserve(all_forms.size()); | 476 kept_forms.reserve(all_forms.size()); |
481 for (auto*& saved_form : all_forms) { | 477 for (std::unique_ptr<PasswordForm>& saved_form : all_forms) { |
482 if (!ArePasswordFormUniqueKeyEqual(form, *saved_form)) { | 478 if (!ArePasswordFormUniqueKeyEqual(form, *saved_form)) { |
483 kept_forms.push_back(saved_form); | 479 kept_forms.push_back(std::move(saved_form)); |
484 saved_form = nullptr; | |
485 } | 480 } |
486 } | 481 } |
487 | 482 |
488 if (kept_forms.size() != all_forms.size()) { | 483 if (kept_forms.size() != all_forms.size()) { |
489 changes->push_back(password_manager::PasswordStoreChange( | 484 changes->push_back(password_manager::PasswordStoreChange( |
490 password_manager::PasswordStoreChange::REMOVE, form)); | 485 password_manager::PasswordStoreChange::REMOVE, form)); |
491 return SetLoginsList(kept_forms.get(), form.signon_realm, wallet_handle); | 486 return SetLoginsList(kept_forms, form.signon_realm, wallet_handle); |
492 } | 487 } |
493 | 488 |
494 return true; | 489 return true; |
495 } | 490 } |
496 | 491 |
497 bool NativeBackendKWallet::RemoveLoginsCreatedBetween( | 492 bool NativeBackendKWallet::RemoveLoginsCreatedBetween( |
498 base::Time delete_begin, | 493 base::Time delete_begin, |
499 base::Time delete_end, | 494 base::Time delete_end, |
500 password_manager::PasswordStoreChangeList* changes) { | 495 password_manager::PasswordStoreChangeList* changes) { |
501 return RemoveLoginsBetween( | 496 return RemoveLoginsBetween( |
502 delete_begin, delete_end, CREATION_TIMESTAMP, changes); | 497 delete_begin, delete_end, CREATION_TIMESTAMP, changes); |
503 } | 498 } |
504 | 499 |
505 bool NativeBackendKWallet::RemoveLoginsSyncedBetween( | 500 bool NativeBackendKWallet::RemoveLoginsSyncedBetween( |
506 base::Time delete_begin, | 501 base::Time delete_begin, |
507 base::Time delete_end, | 502 base::Time delete_end, |
508 password_manager::PasswordStoreChangeList* changes) { | 503 password_manager::PasswordStoreChangeList* changes) { |
509 return RemoveLoginsBetween(delete_begin, delete_end, SYNC_TIMESTAMP, changes); | 504 return RemoveLoginsBetween(delete_begin, delete_end, SYNC_TIMESTAMP, changes); |
510 } | 505 } |
511 | 506 |
512 bool NativeBackendKWallet::DisableAutoSignInForOrigins( | 507 bool NativeBackendKWallet::DisableAutoSignInForOrigins( |
513 const base::Callback<bool(const GURL&)>& origin_filter, | 508 const base::Callback<bool(const GURL&)>& origin_filter, |
514 password_manager::PasswordStoreChangeList* changes) { | 509 password_manager::PasswordStoreChangeList* changes) { |
515 ScopedVector<autofill::PasswordForm> all_forms; | 510 std::vector<std::unique_ptr<PasswordForm>> all_forms; |
516 if (!GetAllLogins(&all_forms)) | 511 if (!GetAllLogins(&all_forms)) |
517 return false; | 512 return false; |
518 | 513 |
519 for (auto* form : all_forms) { | 514 for (const std::unique_ptr<PasswordForm>& form : all_forms) { |
520 if (origin_filter.Run(form->origin) && !form->skip_zero_click) { | 515 if (origin_filter.Run(form->origin) && !form->skip_zero_click) { |
521 form->skip_zero_click = true; | 516 form->skip_zero_click = true; |
522 if (!UpdateLogin(*form, changes)) | 517 if (!UpdateLogin(*form, changes)) |
523 return false; | 518 return false; |
524 } | 519 } |
525 } | 520 } |
526 return true; | 521 return true; |
527 } | 522 } |
528 | 523 |
529 bool NativeBackendKWallet::GetLogins( | 524 bool NativeBackendKWallet::GetLogins( |
530 const password_manager::PasswordStore::FormDigest& form, | 525 const password_manager::PasswordStore::FormDigest& form, |
531 ScopedVector<autofill::PasswordForm>* forms) { | 526 std::vector<std::unique_ptr<PasswordForm>>* forms) { |
532 int wallet_handle = WalletHandle(); | 527 int wallet_handle = WalletHandle(); |
533 if (wallet_handle == kInvalidKWalletHandle) | 528 if (wallet_handle == kInvalidKWalletHandle) |
534 return false; | 529 return false; |
535 return GetLoginsList(form.signon_realm, wallet_handle, forms); | 530 return GetLoginsList(form.signon_realm, wallet_handle, forms); |
536 } | 531 } |
537 | 532 |
538 bool NativeBackendKWallet::GetAutofillableLogins( | 533 bool NativeBackendKWallet::GetAutofillableLogins( |
539 ScopedVector<autofill::PasswordForm>* forms) { | 534 std::vector<std::unique_ptr<PasswordForm>>* forms) { |
540 int wallet_handle = WalletHandle(); | 535 int wallet_handle = WalletHandle(); |
541 if (wallet_handle == kInvalidKWalletHandle) | 536 if (wallet_handle == kInvalidKWalletHandle) |
542 return false; | 537 return false; |
543 return GetLoginsList(BlacklistOptions::AUTOFILLABLE, wallet_handle, forms); | 538 return GetLoginsList(BlacklistOptions::AUTOFILLABLE, wallet_handle, forms); |
544 } | 539 } |
545 | 540 |
546 bool NativeBackendKWallet::GetBlacklistLogins( | 541 bool NativeBackendKWallet::GetBlacklistLogins( |
547 ScopedVector<autofill::PasswordForm>* forms) { | 542 std::vector<std::unique_ptr<PasswordForm>>* forms) { |
548 int wallet_handle = WalletHandle(); | 543 int wallet_handle = WalletHandle(); |
549 if (wallet_handle == kInvalidKWalletHandle) | 544 if (wallet_handle == kInvalidKWalletHandle) |
550 return false; | 545 return false; |
551 return GetLoginsList(BlacklistOptions::BLACKLISTED, wallet_handle, forms); | 546 return GetLoginsList(BlacklistOptions::BLACKLISTED, wallet_handle, forms); |
552 } | 547 } |
553 | 548 |
554 bool NativeBackendKWallet::GetAllLogins( | 549 bool NativeBackendKWallet::GetAllLogins( |
555 ScopedVector<autofill::PasswordForm>* forms) { | 550 std::vector<std::unique_ptr<PasswordForm>>* forms) { |
556 int wallet_handle = WalletHandle(); | 551 int wallet_handle = WalletHandle(); |
557 if (wallet_handle == kInvalidKWalletHandle) | 552 if (wallet_handle == kInvalidKWalletHandle) |
558 return false; | 553 return false; |
559 return GetAllLoginsInternal(wallet_handle, forms); | 554 return GetAllLoginsInternal(wallet_handle, forms); |
560 } | 555 } |
561 | 556 |
562 bool NativeBackendKWallet::GetLoginsList( | 557 bool NativeBackendKWallet::GetLoginsList( |
563 const std::string& signon_realm, | 558 const std::string& signon_realm, |
564 int wallet_handle, | 559 int wallet_handle, |
565 ScopedVector<autofill::PasswordForm>* forms) { | 560 std::vector<std::unique_ptr<PasswordForm>>* forms) { |
566 forms->clear(); | 561 forms->clear(); |
567 // Is there an entry in the wallet? | 562 // Is there an entry in the wallet? |
568 bool has_entry = false; | 563 bool has_entry = false; |
569 KWalletDBus::Error error = kwallet_dbus_.HasEntry( | 564 KWalletDBus::Error error = kwallet_dbus_.HasEntry( |
570 wallet_handle, folder_name_, signon_realm, app_name_, &has_entry); | 565 wallet_handle, folder_name_, signon_realm, app_name_, &has_entry); |
571 if (error) | 566 if (error) |
572 return false; | 567 return false; |
573 if (!has_entry) | 568 if (!has_entry) |
574 return true; | 569 return true; |
575 | 570 |
(...skipping 15 matching lines...) Expand all Loading... |
591 base::Pickle pickle(reinterpret_cast<const char*>(bytes.data()), | 586 base::Pickle pickle(reinterpret_cast<const char*>(bytes.data()), |
592 bytes.size()); | 587 bytes.size()); |
593 *forms = DeserializeValue(signon_realm, pickle); | 588 *forms = DeserializeValue(signon_realm, pickle); |
594 | 589 |
595 return true; | 590 return true; |
596 } | 591 } |
597 | 592 |
598 bool NativeBackendKWallet::GetLoginsList( | 593 bool NativeBackendKWallet::GetLoginsList( |
599 BlacklistOptions options, | 594 BlacklistOptions options, |
600 int wallet_handle, | 595 int wallet_handle, |
601 ScopedVector<autofill::PasswordForm>* forms) { | 596 std::vector<std::unique_ptr<PasswordForm>>* forms) { |
602 forms->clear(); | 597 forms->clear(); |
603 ScopedVector<autofill::PasswordForm> all_forms; | 598 std::vector<std::unique_ptr<PasswordForm>> all_forms; |
604 if (!GetAllLoginsInternal(wallet_handle, &all_forms)) | 599 if (!GetAllLoginsInternal(wallet_handle, &all_forms)) |
605 return false; | 600 return false; |
606 | 601 |
607 // Remove the duplicate sync tags. | 602 // Remove the duplicate sync tags. |
608 ScopedVector<autofill::PasswordForm> duplicates; | 603 std::vector<std::unique_ptr<PasswordForm>> duplicates; |
609 password_manager_util::FindDuplicates(&all_forms, &duplicates, nullptr); | 604 password_manager_util::FindDuplicates(&all_forms, &duplicates, nullptr); |
610 if (!duplicates.empty()) { | 605 if (!duplicates.empty()) { |
611 // Fill the signon realms to be updated. | 606 // Fill the signon realms to be updated. |
612 std::map<std::string, std::vector<autofill::PasswordForm*>> update_forms; | 607 std::map<std::string, std::vector<std::unique_ptr<PasswordForm>>> |
613 for (autofill::PasswordForm* form : duplicates) { | 608 update_forms; |
| 609 for (const auto& form : duplicates) { |
614 update_forms.insert(std::make_pair( | 610 update_forms.insert(std::make_pair( |
615 form->signon_realm, std::vector<autofill::PasswordForm*>())); | 611 form->signon_realm, std::vector<std::unique_ptr<PasswordForm>>())); |
616 } | 612 } |
617 | 613 |
618 // Fill the actual forms to be saved. | 614 // Fill the actual forms to be saved. |
619 for (autofill::PasswordForm* form : all_forms) { | 615 for (const auto& form : all_forms) { |
620 auto it = update_forms.find(form->signon_realm); | 616 auto it = update_forms.find(form->signon_realm); |
621 if (it != update_forms.end()) | 617 if (it != update_forms.end()) |
622 it->second.push_back(form); | 618 it->second.push_back(base::MakeUnique<PasswordForm>(*form)); |
623 } | 619 } |
624 | 620 |
625 // Update the backend. | 621 // Update the backend. |
626 for (const auto& forms : update_forms) { | 622 for (const auto& update_forms_for_realm : update_forms) { |
627 if (!SetLoginsList(forms.second, forms.first, wallet_handle)) | 623 if (!SetLoginsList(update_forms_for_realm.second, |
| 624 update_forms_for_realm.first, wallet_handle)) { |
628 return false; | 625 return false; |
| 626 } |
629 } | 627 } |
630 } | 628 } |
631 // We have to read all the entries, and then filter them here. | 629 // We have to read all the entries, and then filter them here. |
632 forms->reserve(all_forms.size()); | 630 forms->reserve(all_forms.size()); |
633 for (auto*& saved_form : all_forms) { | 631 for (std::unique_ptr<PasswordForm>& saved_form : all_forms) { |
634 if (saved_form->blacklisted_by_user == | 632 if (saved_form->blacklisted_by_user == |
635 (options == BlacklistOptions::BLACKLISTED)) { | 633 (options == BlacklistOptions::BLACKLISTED)) { |
636 forms->push_back(saved_form); | 634 forms->push_back(std::move(saved_form)); |
637 saved_form = nullptr; | |
638 } | 635 } |
639 } | 636 } |
640 | 637 |
641 return true; | 638 return true; |
642 } | 639 } |
643 | 640 |
644 bool NativeBackendKWallet::GetAllLoginsInternal( | 641 bool NativeBackendKWallet::GetAllLoginsInternal( |
645 int wallet_handle, | 642 int wallet_handle, |
646 ScopedVector<autofill::PasswordForm>* forms) { | 643 std::vector<std::unique_ptr<PasswordForm>>* forms) { |
647 // We could probably also use readEntryList here. | 644 // We could probably also use readEntryList here. |
648 std::vector<std::string> realm_list; | 645 std::vector<std::string> realm_list; |
649 KWalletDBus::Error error = kwallet_dbus_.EntryList( | 646 KWalletDBus::Error error = kwallet_dbus_.EntryList( |
650 wallet_handle, folder_name_, app_name_, &realm_list); | 647 wallet_handle, folder_name_, app_name_, &realm_list); |
651 if (error) | 648 if (error) |
652 return false; | 649 return false; |
653 | 650 |
654 forms->clear(); | 651 forms->clear(); |
655 for (const std::string& signon_realm : realm_list) { | 652 for (const std::string& signon_realm : realm_list) { |
656 std::vector<uint8_t> bytes; | 653 std::vector<uint8_t> bytes; |
657 KWalletDBus::Error error = kwallet_dbus_.ReadEntry( | 654 KWalletDBus::Error error = kwallet_dbus_.ReadEntry( |
658 wallet_handle, folder_name_, signon_realm, app_name_, &bytes); | 655 wallet_handle, folder_name_, signon_realm, app_name_, &bytes); |
659 if (error) | 656 if (error) |
660 return false; | 657 return false; |
661 if (bytes.empty() || | 658 if (bytes.empty() || |
662 !CheckSerializedValue(bytes.data(), bytes.size(), signon_realm)) | 659 !CheckSerializedValue(bytes.data(), bytes.size(), signon_realm)) |
663 continue; | 660 continue; |
664 | 661 |
665 // Can't we all just agree on whether bytes are signed or not? Please? | 662 // Can't we all just agree on whether bytes are signed or not? Please? |
666 base::Pickle pickle(reinterpret_cast<const char*>(bytes.data()), | 663 base::Pickle pickle(reinterpret_cast<const char*>(bytes.data()), |
667 bytes.size()); | 664 bytes.size()); |
668 AppendSecondToFirst(forms, DeserializeValue(signon_realm, pickle)); | 665 std::vector<std::unique_ptr<PasswordForm>> from_pickle = |
| 666 DeserializeValue(signon_realm, pickle); |
| 667 forms->reserve(forms->size() + from_pickle.size()); |
| 668 std::move(from_pickle.begin(), from_pickle.end(), |
| 669 std::back_inserter(*forms)); |
669 } | 670 } |
670 return true; | 671 return true; |
671 } | 672 } |
672 | 673 |
673 bool NativeBackendKWallet::SetLoginsList( | 674 bool NativeBackendKWallet::SetLoginsList( |
674 const std::vector<autofill::PasswordForm*>& forms, | 675 const std::vector<std::unique_ptr<PasswordForm>>& forms, |
675 const std::string& signon_realm, | 676 const std::string& signon_realm, |
676 int wallet_handle) { | 677 int wallet_handle) { |
677 if (forms.empty()) { | 678 if (forms.empty()) { |
678 int ret = 0; | 679 int ret = 0; |
679 KWalletDBus::Error error = kwallet_dbus_.RemoveEntry( | 680 KWalletDBus::Error error = kwallet_dbus_.RemoveEntry( |
680 wallet_handle, folder_name_, signon_realm, app_name_, &ret); | 681 wallet_handle, folder_name_, signon_realm, app_name_, &ret); |
681 if (error) | 682 if (error) |
682 return false; | 683 return false; |
683 if (ret != 0) | 684 if (ret != 0) |
684 LOG(ERROR) << "Bad return code " << ret << " from KWallet removeEntry"; | 685 LOG(ERROR) << "Bad return code " << ret << " from KWallet removeEntry"; |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
726 wallet_handle, folder_name_, signon_realm, app_name_, &bytes); | 727 wallet_handle, folder_name_, signon_realm, app_name_, &bytes); |
727 if (error) | 728 if (error) |
728 continue; | 729 continue; |
729 if (bytes.size() == 0 || | 730 if (bytes.size() == 0 || |
730 !CheckSerializedValue(bytes.data(), bytes.size(), signon_realm)) | 731 !CheckSerializedValue(bytes.data(), bytes.size(), signon_realm)) |
731 continue; | 732 continue; |
732 | 733 |
733 // Can't we all just agree on whether bytes are signed or not? Please? | 734 // Can't we all just agree on whether bytes are signed or not? Please? |
734 base::Pickle pickle(reinterpret_cast<const char*>(bytes.data()), | 735 base::Pickle pickle(reinterpret_cast<const char*>(bytes.data()), |
735 bytes.size()); | 736 bytes.size()); |
736 ScopedVector<autofill::PasswordForm> all_forms = | 737 std::vector<std::unique_ptr<PasswordForm>> all_forms = |
737 DeserializeValue(signon_realm, pickle); | 738 DeserializeValue(signon_realm, pickle); |
738 | 739 |
739 ScopedVector<autofill::PasswordForm> kept_forms; | 740 std::vector<std::unique_ptr<PasswordForm>> kept_forms; |
740 kept_forms.reserve(all_forms.size()); | 741 kept_forms.reserve(all_forms.size()); |
741 base::Time autofill::PasswordForm::*date_member = | 742 base::Time PasswordForm::*date_member = |
742 date_to_compare == CREATION_TIMESTAMP | 743 date_to_compare == CREATION_TIMESTAMP ? &PasswordForm::date_created |
743 ? &autofill::PasswordForm::date_created | 744 : &PasswordForm::date_synced; |
744 : &autofill::PasswordForm::date_synced; | 745 for (std::unique_ptr<PasswordForm>& saved_form : all_forms) { |
745 for (auto*& saved_form : all_forms) { | 746 if (delete_begin <= saved_form.get()->*date_member && |
746 if (delete_begin <= saved_form->*date_member && | 747 (delete_end.is_null() || |
747 (delete_end.is_null() || saved_form->*date_member < delete_end)) { | 748 saved_form.get()->*date_member < delete_end)) { |
748 changes->push_back(password_manager::PasswordStoreChange( | 749 changes->push_back(password_manager::PasswordStoreChange( |
749 password_manager::PasswordStoreChange::REMOVE, *saved_form)); | 750 password_manager::PasswordStoreChange::REMOVE, *saved_form)); |
750 } else { | 751 } else { |
751 kept_forms.push_back(saved_form); | 752 kept_forms.push_back(std::move(saved_form)); |
752 saved_form = nullptr; | |
753 } | 753 } |
754 } | 754 } |
755 | 755 |
756 if (!SetLoginsList(kept_forms.get(), signon_realm, wallet_handle)) { | 756 if (!SetLoginsList(kept_forms, signon_realm, wallet_handle)) { |
757 ok = false; | 757 ok = false; |
758 changes->clear(); | 758 changes->clear(); |
759 } | 759 } |
760 } | 760 } |
761 return ok; | 761 return ok; |
762 } | 762 } |
763 | 763 |
764 // static | 764 // static |
765 ScopedVector<autofill::PasswordForm> NativeBackendKWallet::DeserializeValue( | 765 std::vector<std::unique_ptr<PasswordForm>> |
766 const std::string& signon_realm, | 766 NativeBackendKWallet::DeserializeValue(const std::string& signon_realm, |
767 const base::Pickle& pickle) { | 767 const base::Pickle& pickle) { |
768 base::PickleIterator iter(pickle); | 768 base::PickleIterator iter(pickle); |
769 | 769 |
770 int version = -1; | 770 int version = -1; |
771 if (!iter.ReadInt(&version) || | 771 if (!iter.ReadInt(&version) || |
772 version < 0 || version > kPickleVersion) { | 772 version < 0 || version > kPickleVersion) { |
773 LOG(ERROR) << "Failed to deserialize KWallet entry " | 773 LOG(ERROR) << "Failed to deserialize KWallet entry " |
774 << "(realm: " << signon_realm << ")"; | 774 << "(realm: " << signon_realm << ")"; |
775 return ScopedVector<autofill::PasswordForm>(); | 775 return std::vector<std::unique_ptr<PasswordForm>>(); |
776 } | 776 } |
777 | 777 |
778 ScopedVector<autofill::PasswordForm> forms; | 778 std::vector<std::unique_ptr<PasswordForm>> forms; |
779 bool success = true; | 779 bool success = true; |
780 if (version > 0) { | 780 if (version > 0) { |
781 // In current pickles, we expect 64-bit sizes. Failure is an error. | 781 // In current pickles, we expect 64-bit sizes. Failure is an error. |
782 success = DeserializeValueSize( | 782 success = DeserializeValueSize( |
783 signon_realm, iter, version, false, false, &forms); | 783 signon_realm, iter, version, false, false, &forms); |
784 UMALogDeserializationStatus(success); | 784 UMALogDeserializationStatus(success); |
785 return forms; | 785 return forms; |
786 } | 786 } |
787 | 787 |
788 const bool size_32 = sizeof(size_t) == sizeof(uint32_t); | 788 const bool size_32 = sizeof(size_t) == sizeof(uint32_t); |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
834 } | 834 } |
835 | 835 |
836 return handle; | 836 return handle; |
837 } | 837 } |
838 | 838 |
839 std::string NativeBackendKWallet::GetProfileSpecificFolderName() const { | 839 std::string NativeBackendKWallet::GetProfileSpecificFolderName() const { |
840 // Originally, the folder name was always just "Chrome Form Data". | 840 // Originally, the folder name was always just "Chrome Form Data". |
841 // Now we use it to distinguish passwords for different profiles. | 841 // Now we use it to distinguish passwords for different profiles. |
842 return base::StringPrintf("%s (%d)", kKWalletFolder, profile_id_); | 842 return base::StringPrintf("%s (%d)", kKWalletFolder, profile_id_); |
843 } | 843 } |
OLD | NEW |