Chromium Code Reviews| 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::inserter(*forms, forms->end())); | |
|
vasilii
2016/12/12 18:10:57
back_inserter?
vabr (Chromium)
2016/12/12 18:34:26
Done.
| |
| 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 |