Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(81)

Side by Side Diff: chrome/browser/password_manager/native_backend_libsecret.cc

Issue 906973007: PasswordStore: Clean up expectations about rewriting vectors of forms (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2015 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2015 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_libsecret.h" 5 #include "chrome/browser/password_manager/native_backend_libsecret.h"
6 6
7 #include <dlfcn.h> 7 #include <dlfcn.h>
8 #include <list> 8 #include <list>
9 9
10 #include "base/basictypes.h" 10 #include "base/basictypes.h"
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after
272 return LoadLibsecret() && LibsecretIsAvailable(); 272 return LoadLibsecret() && LibsecretIsAvailable();
273 } 273 }
274 274
275 password_manager::PasswordStoreChangeList NativeBackendLibsecret::AddLogin( 275 password_manager::PasswordStoreChangeList NativeBackendLibsecret::AddLogin(
276 const PasswordForm& form) { 276 const PasswordForm& form) {
277 // Based on LoginDatabase::AddLogin(), we search for an existing match based 277 // Based on LoginDatabase::AddLogin(), we search for an existing match based
278 // on origin_url, username_element, username_value, password_element, submit 278 // on origin_url, username_element, username_value, password_element, submit
279 // element, and signon_realm first, remove that, and then add the new entry. 279 // element, and signon_realm first, remove that, and then add the new entry.
280 // We'd add the new one first, and then delete the original, but then the 280 // We'd add the new one first, and then delete the original, but then the
281 // delete might actually delete the newly-added entry! 281 // delete might actually delete the newly-added entry!
282 ScopedVector<autofill::PasswordForm> forms; 282 ScopedVector<autofill::PasswordForm> forms =
283 AddUpdateLoginSearch(form, SEARCH_USE_SUBMIT, &forms); 283 AddUpdateLoginSearch(form, SEARCH_USE_SUBMIT);
284 password_manager::PasswordStoreChangeList changes; 284 password_manager::PasswordStoreChangeList changes;
285 if (forms.size() > 0) { 285 if (forms.size() > 0) {
286 if (forms.size() > 1) { 286 if (forms.size() > 1) {
287 VLOG(1) << "Adding login when there are " << forms.size() 287 VLOG(1) << "Adding login when there are " << forms.size()
288 << " matching logins already! Will replace only the first."; 288 << " matching logins already! Will replace only the first.";
289 } 289 }
290 290
291 if (RemoveLogin(*forms[0])) { 291 if (RemoveLogin(*forms[0])) {
292 changes.push_back(password_manager::PasswordStoreChange( 292 changes.push_back(password_manager::PasswordStoreChange(
293 password_manager::PasswordStoreChange::REMOVE, *forms[0])); 293 password_manager::PasswordStoreChange::REMOVE, *forms[0]));
(...skipping 11 matching lines...) Expand all
305 password_manager::PasswordStoreChangeList* changes) { 305 password_manager::PasswordStoreChangeList* changes) {
306 // Based on LoginDatabase::UpdateLogin(), we search for forms to update by 306 // Based on LoginDatabase::UpdateLogin(), we search for forms to update by
307 // origin_url, username_element, username_value, password_element, and 307 // origin_url, username_element, username_value, password_element, and
308 // signon_realm. We then compare the result to the updated form. If they 308 // signon_realm. We then compare the result to the updated form. If they
309 // differ in any of the mutable fields, then we remove the original, and 309 // differ in any of the mutable fields, then we remove the original, and
310 // then add the new entry. We'd add the new one first, and then delete the 310 // then add the new entry. We'd add the new one first, and then delete the
311 // original, but then the delete might actually delete the newly-added entry! 311 // original, but then the delete might actually delete the newly-added entry!
312 DCHECK(changes); 312 DCHECK(changes);
313 changes->clear(); 313 changes->clear();
314 314
315 ScopedVector<autofill::PasswordForm> forms; 315 ScopedVector<autofill::PasswordForm> forms =
316 AddUpdateLoginSearch(form, SEARCH_IGNORE_SUBMIT, &forms); 316 AddUpdateLoginSearch(form, SEARCH_IGNORE_SUBMIT);
317 317
318 bool removed = false; 318 bool removed = false;
319 for (size_t i = 0; i < forms.size(); ++i) { 319 for (size_t i = 0; i < forms.size(); ++i) {
320 if (*forms[i] != form) { 320 if (*forms[i] != form) {
321 RemoveLogin(*forms[i]); 321 RemoveLogin(*forms[i]);
322 removed = true; 322 removed = true;
323 } 323 }
324 } 324 }
325 if (!removed) 325 if (!removed)
326 return true; 326 return true;
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
367 password_manager::PasswordStoreChangeList* changes) { 367 password_manager::PasswordStoreChangeList* changes) {
368 return RemoveLoginsBetween(delete_begin, delete_end, SYNC_TIMESTAMP, changes); 368 return RemoveLoginsBetween(delete_begin, delete_end, SYNC_TIMESTAMP, changes);
369 } 369 }
370 370
371 bool NativeBackendLibsecret::GetLogins( 371 bool NativeBackendLibsecret::GetLogins(
372 const PasswordForm& form, 372 const PasswordForm& form,
373 ScopedVector<autofill::PasswordForm>* forms) { 373 ScopedVector<autofill::PasswordForm>* forms) {
374 return GetLoginsList(&form, ALL_LOGINS, forms); 374 return GetLoginsList(&form, ALL_LOGINS, forms);
375 } 375 }
376 376
377 void NativeBackendLibsecret::AddUpdateLoginSearch( 377 ScopedVector<autofill::PasswordForm>
378 NativeBackendLibsecret::AddUpdateLoginSearch(
378 const autofill::PasswordForm& lookup_form, 379 const autofill::PasswordForm& lookup_form,
379 AddUpdateLoginSearchOptions options, 380 AddUpdateLoginSearchOptions options) {
380 ScopedVector<autofill::PasswordForm>* forms) {
381 LibsecretAttributesBuilder attrs; 381 LibsecretAttributesBuilder attrs;
382 attrs.Append("origin_url", lookup_form.origin.spec()); 382 attrs.Append("origin_url", lookup_form.origin.spec());
383 attrs.Append("username_element", UTF16ToUTF8(lookup_form.username_element)); 383 attrs.Append("username_element", UTF16ToUTF8(lookup_form.username_element));
384 attrs.Append("username_value", UTF16ToUTF8(lookup_form.username_value)); 384 attrs.Append("username_value", UTF16ToUTF8(lookup_form.username_value));
385 attrs.Append("password_element", UTF16ToUTF8(lookup_form.password_element)); 385 attrs.Append("password_element", UTF16ToUTF8(lookup_form.password_element));
386 if (options == SEARCH_USE_SUBMIT) 386 if (options == SEARCH_USE_SUBMIT)
387 attrs.Append("submit_element", UTF16ToUTF8(lookup_form.submit_element)); 387 attrs.Append("submit_element", UTF16ToUTF8(lookup_form.submit_element));
388 attrs.Append("signon_realm", lookup_form.signon_realm); 388 attrs.Append("signon_realm", lookup_form.signon_realm);
389 attrs.Append("application", app_string_); 389 attrs.Append("application", app_string_);
390 390
391 GError* error = nullptr; 391 GError* error = nullptr;
392 GList* found = secret_service_search_sync(nullptr, // default secret service 392 GList* found = secret_service_search_sync(nullptr, // default secret service
393 &kLibsecretSchema, attrs.Get(), 393 &kLibsecretSchema, attrs.Get(),
394 SECRET_SEARCH_ALL, 394 SECRET_SEARCH_ALL,
395 nullptr, // no cancellable ojbect 395 nullptr, // no cancellable ojbect
396 &error); 396 &error);
397 if (error) { 397 if (error) {
398 VLOG(1) << "Unable to get logins " << error->message; 398 VLOG(1) << "Unable to get logins " << error->message;
399 g_error_free(error); 399 g_error_free(error);
400 if (found) 400 if (found)
401 g_list_free(found); 401 g_list_free(found);
402 return; 402 return ScopedVector<autofill::PasswordForm>();
403 } 403 }
404 404
405 ConvertFormList(found, &lookup_form, forms); 405 return ConvertFormList(found, &lookup_form);
406 } 406 }
407 407
408 bool NativeBackendLibsecret::RawAddLogin(const PasswordForm& form) { 408 bool NativeBackendLibsecret::RawAddLogin(const PasswordForm& form) {
409 int64 date_created = form.date_created.ToInternalValue(); 409 int64 date_created = form.date_created.ToInternalValue();
410 // If we are asked to save a password with 0 date, use the current time. 410 // If we are asked to save a password with 0 date, use the current time.
411 // We don't want to actually save passwords as though on January 1, 1601. 411 // We don't want to actually save passwords as though on January 1, 1601.
412 if (!date_created) 412 if (!date_created)
413 date_created = base::Time::Now().ToInternalValue(); 413 date_created = base::Time::Now().ToInternalValue();
414 int64 date_synced = form.date_synced.ToInternalValue(); 414 int64 date_synced = form.date_synced.ToInternalValue();
415 GError* error = nullptr; 415 GError* error = nullptr;
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
456 456
457 bool NativeBackendLibsecret::GetBlacklistLogins( 457 bool NativeBackendLibsecret::GetBlacklistLogins(
458 ScopedVector<autofill::PasswordForm>* forms) { 458 ScopedVector<autofill::PasswordForm>* forms) {
459 return GetLoginsList(nullptr, BLACKLISTED_LOGINS, forms); 459 return GetLoginsList(nullptr, BLACKLISTED_LOGINS, forms);
460 } 460 }
461 461
462 bool NativeBackendLibsecret::GetLoginsList( 462 bool NativeBackendLibsecret::GetLoginsList(
463 const PasswordForm* lookup_form, 463 const PasswordForm* lookup_form,
464 GetLoginsListOptions options, 464 GetLoginsListOptions options,
465 ScopedVector<autofill::PasswordForm>* forms) { 465 ScopedVector<autofill::PasswordForm>* forms) {
466 forms->clear();
466 LibsecretAttributesBuilder attrs; 467 LibsecretAttributesBuilder attrs;
467 attrs.Append("application", app_string_); 468 attrs.Append("application", app_string_);
468 if (options != ALL_LOGINS) 469 if (options != ALL_LOGINS)
469 attrs.Append("blacklisted_by_user", options == BLACKLISTED_LOGINS); 470 attrs.Append("blacklisted_by_user", options == BLACKLISTED_LOGINS);
470 if (lookup_form && 471 if (lookup_form &&
471 !password_manager::ShouldPSLDomainMatchingApply( 472 !password_manager::ShouldPSLDomainMatchingApply(
472 password_manager::GetRegistryControlledDomain( 473 password_manager::GetRegistryControlledDomain(
473 GURL(lookup_form->signon_realm)))) 474 GURL(lookup_form->signon_realm))))
474 attrs.Append("signon_realm", lookup_form->signon_realm); 475 attrs.Append("signon_realm", lookup_form->signon_realm);
475 476
476 GError* error = nullptr; 477 GError* error = nullptr;
477 GList* found = secret_service_search_sync(nullptr, // default secret service 478 GList* found = secret_service_search_sync(nullptr, // default secret service
478 &kLibsecretSchema, attrs.Get(), 479 &kLibsecretSchema, attrs.Get(),
479 SECRET_SEARCH_ALL, 480 SECRET_SEARCH_ALL,
480 nullptr, // no cancellable ojbect 481 nullptr, // no cancellable ojbect
481 &error); 482 &error);
482 if (error) { 483 if (error) {
483 VLOG(1) << "Unable to get logins " << error->message; 484 VLOG(1) << "Unable to get logins " << error->message;
484 g_error_free(error); 485 g_error_free(error);
485 if (found) 486 if (found)
486 g_list_free(found); 487 g_list_free(found);
487 return false; 488 return false;
488 } 489 }
489 490
490 return ConvertFormList(found, lookup_form, forms); 491 *forms = ConvertFormList(found, lookup_form);
491 } 492 return true;
492
493 bool NativeBackendLibsecret::GetAllLogins(
494 ScopedVector<autofill::PasswordForm>* forms) {
495 return GetLoginsList(nullptr, ALL_LOGINS, forms);
496 } 493 }
497 494
498 bool NativeBackendLibsecret::GetLoginsBetween( 495 bool NativeBackendLibsecret::GetLoginsBetween(
499 base::Time get_begin, 496 base::Time get_begin,
500 base::Time get_end, 497 base::Time get_end,
501 TimestampToCompare date_to_compare, 498 TimestampToCompare date_to_compare,
502 ScopedVector<autofill::PasswordForm>* forms) { 499 ScopedVector<autofill::PasswordForm>* forms) {
503 ScopedVector<autofill::PasswordForm> all_forms; 500 ScopedVector<autofill::PasswordForm> all_forms;
504 if (!GetAllLogins(&all_forms)) 501 if (!GetLoginsList(nullptr, ALL_LOGINS, forms))
505 return false; 502 return false;
506 503
507 base::Time autofill::PasswordForm::*date_member = 504 base::Time autofill::PasswordForm::*date_member =
508 date_to_compare == CREATION_TIMESTAMP 505 date_to_compare == CREATION_TIMESTAMP
509 ? &autofill::PasswordForm::date_created 506 ? &autofill::PasswordForm::date_created
510 : &autofill::PasswordForm::date_synced; 507 : &autofill::PasswordForm::date_synced;
511 for (auto& saved_form : all_forms) { 508 for (auto& saved_form : all_forms) {
512 if (get_begin <= saved_form->*date_member && 509 if (get_begin <= saved_form->*date_member &&
513 (get_end.is_null() || saved_form->*date_member < get_end)) { 510 (get_end.is_null() || saved_form->*date_member < get_end)) {
514 forms->push_back(saved_form); 511 forms->push_back(saved_form);
(...skipping 20 matching lines...) Expand all
535 if (RemoveLogin(*forms[i])) { 532 if (RemoveLogin(*forms[i])) {
536 changes->push_back(password_manager::PasswordStoreChange( 533 changes->push_back(password_manager::PasswordStoreChange(
537 password_manager::PasswordStoreChange::REMOVE, *forms[i])); 534 password_manager::PasswordStoreChange::REMOVE, *forms[i]));
538 } else { 535 } else {
539 ok = false; 536 ok = false;
540 } 537 }
541 } 538 }
542 return ok; 539 return ok;
543 } 540 }
544 541
545 bool NativeBackendLibsecret::ConvertFormList( 542 ScopedVector<autofill::PasswordForm> NativeBackendLibsecret::ConvertFormList(
546 GList* found, 543 GList* found,
547 const PasswordForm* lookup_form, 544 const PasswordForm* lookup_form) {
548 ScopedVector<autofill::PasswordForm>* forms) { 545 ScopedVector<autofill::PasswordForm> forms;
549 password_manager::PSLDomainMatchMetric psl_domain_match_metric = 546 password_manager::PSLDomainMatchMetric psl_domain_match_metric =
550 password_manager::PSL_DOMAIN_MATCH_NONE; 547 password_manager::PSL_DOMAIN_MATCH_NONE;
551 GError* error = nullptr; 548 GError* error = nullptr;
552 for (GList* element = g_list_first(found); element != nullptr; 549 for (GList* element = g_list_first(found); element != nullptr;
553 element = g_list_next(element)) { 550 element = g_list_next(element)) {
554 SecretItem* secretItem = static_cast<SecretItem*>(element->data); 551 SecretItem* secretItem = static_cast<SecretItem*>(element->data);
555 LibsecretLoader::secret_item_load_secret_sync(secretItem, nullptr, &error); 552 LibsecretLoader::secret_item_load_secret_sync(secretItem, nullptr, &error);
556 if (error) { 553 if (error) {
557 VLOG(1) << "Unable to load secret item" << error->message; 554 VLOG(1) << "Unable to load secret item" << error->message;
558 g_error_free(error); 555 g_error_free(error);
(...skipping 17 matching lines...) Expand all
576 form->signon_realm = lookup_form->signon_realm; 573 form->signon_realm = lookup_form->signon_realm;
577 form->origin = lookup_form->origin; 574 form->origin = lookup_form->origin;
578 } 575 }
579 SecretValue* secretValue = secret_item_get_secret(secretItem); 576 SecretValue* secretValue = secret_item_get_secret(secretItem);
580 if (secretValue) { 577 if (secretValue) {
581 form->password_value = UTF8ToUTF16(secret_value_get_text(secretValue)); 578 form->password_value = UTF8ToUTF16(secret_value_get_text(secretValue));
582 secret_value_unref(secretValue); 579 secret_value_unref(secretValue);
583 } else { 580 } else {
584 VLOG(1) << "Unable to access password from list element!"; 581 VLOG(1) << "Unable to access password from list element!";
585 } 582 }
586 forms->push_back(form.release()); 583 forms.push_back(form.release());
587 } else { 584 } else {
588 VLOG(1) << "Could not initialize PasswordForm from attributes!"; 585 VLOG(1) << "Could not initialize PasswordForm from attributes!";
589 } 586 }
590 } 587 }
591 588
592 if (lookup_form) { 589 if (lookup_form) {
593 const GURL signon_realm(lookup_form->signon_realm); 590 const GURL signon_realm(lookup_form->signon_realm);
594 std::string registered_domain = 591 std::string registered_domain =
595 password_manager::GetRegistryControlledDomain(signon_realm); 592 password_manager::GetRegistryControlledDomain(signon_realm);
596 UMA_HISTOGRAM_ENUMERATION( 593 UMA_HISTOGRAM_ENUMERATION(
597 "PasswordManager.PslDomainMatchTriggering", 594 "PasswordManager.PslDomainMatchTriggering",
598 password_manager::ShouldPSLDomainMatchingApply(registered_domain) 595 password_manager::ShouldPSLDomainMatchingApply(registered_domain)
599 ? psl_domain_match_metric 596 ? psl_domain_match_metric
600 : password_manager::PSL_DOMAIN_MATCH_NOT_USED, 597 : password_manager::PSL_DOMAIN_MATCH_NOT_USED,
601 password_manager::PSL_DOMAIN_MATCH_COUNT); 598 password_manager::PSL_DOMAIN_MATCH_COUNT);
602 } 599 }
603 g_list_free(found); 600 g_list_free(found);
604 return true; 601 return forms.Pass();
605 } 602 }
606 603
607 std::string NativeBackendLibsecret::GetProfileSpecificAppString( 604 std::string NativeBackendLibsecret::GetProfileSpecificAppString(
608 LocalProfileId id) { 605 LocalProfileId id) {
609 // Originally, the application string was always just "chrome" and used only 606 // Originally, the application string was always just "chrome" and used only
610 // so that we had *something* to search for since GNOME Keyring won't search 607 // so that we had *something* to search for since GNOME Keyring won't search
611 // for nothing. Now we use it to distinguish passwords for different profiles. 608 // for nothing. Now we use it to distinguish passwords for different profiles.
612 return base::StringPrintf("%s-%d", kLibsecretAppString, id); 609 return base::StringPrintf("%s-%d", kLibsecretAppString, id);
613 } 610 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698