OLD | NEW |
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 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
257 } | 257 } |
258 | 258 |
259 password_manager::PasswordStoreChangeList NativeBackendLibsecret::AddLogin( | 259 password_manager::PasswordStoreChangeList NativeBackendLibsecret::AddLogin( |
260 const PasswordForm& form) { | 260 const PasswordForm& form) { |
261 // Based on LoginDatabase::AddLogin(), we search for an existing match based | 261 // Based on LoginDatabase::AddLogin(), we search for an existing match based |
262 // on origin_url, username_element, username_value, password_element, submit | 262 // on origin_url, username_element, username_value, password_element, submit |
263 // element, and signon_realm first, remove that, and then add the new entry. | 263 // element, and signon_realm first, remove that, and then add the new entry. |
264 // We'd add the new one first, and then delete the original, but then the | 264 // We'd add the new one first, and then delete the original, but then the |
265 // delete might actually delete the newly-added entry! | 265 // delete might actually delete the newly-added entry! |
266 ScopedVector<autofill::PasswordForm> forms; | 266 ScopedVector<autofill::PasswordForm> forms; |
267 AddUpdateLoginSearch(form, &forms.get(), SEARCH_USE_SUBMIT); | 267 AddUpdateLoginSearch(form, SEARCH_USE_SUBMIT, &forms); |
268 password_manager::PasswordStoreChangeList changes; | 268 password_manager::PasswordStoreChangeList changes; |
269 if (forms.size() > 0) { | 269 if (forms.size() > 0) { |
270 if (forms.size() > 1) { | 270 if (forms.size() > 1) { |
271 VLOG(1) << "Adding login when there are " << forms.size() | 271 VLOG(1) << "Adding login when there are " << forms.size() |
272 << " matching logins already! Will replace only the first."; | 272 << " matching logins already! Will replace only the first."; |
273 } | 273 } |
274 | 274 |
275 if (RemoveLogin(*forms[0])) { | 275 if (RemoveLogin(*forms[0])) { |
276 changes.push_back(password_manager::PasswordStoreChange( | 276 changes.push_back(password_manager::PasswordStoreChange( |
277 password_manager::PasswordStoreChange::REMOVE, *forms[0])); | 277 password_manager::PasswordStoreChange::REMOVE, *forms[0])); |
(...skipping 12 matching lines...) Expand all Loading... |
290 // Based on LoginDatabase::UpdateLogin(), we search for forms to update by | 290 // Based on LoginDatabase::UpdateLogin(), we search for forms to update by |
291 // origin_url, username_element, username_value, password_element, and | 291 // origin_url, username_element, username_value, password_element, and |
292 // signon_realm. We then compare the result to the updated form. If they | 292 // signon_realm. We then compare the result to the updated form. If they |
293 // differ in any of the mutable fields, then we remove the original, and | 293 // differ in any of the mutable fields, then we remove the original, and |
294 // then add the new entry. We'd add the new one first, and then delete the | 294 // then add the new entry. We'd add the new one first, and then delete the |
295 // original, but then the delete might actually delete the newly-added entry! | 295 // original, but then the delete might actually delete the newly-added entry! |
296 DCHECK(changes); | 296 DCHECK(changes); |
297 changes->clear(); | 297 changes->clear(); |
298 | 298 |
299 ScopedVector<autofill::PasswordForm> forms; | 299 ScopedVector<autofill::PasswordForm> forms; |
300 AddUpdateLoginSearch(form, &forms.get(), SEARCH_IGNORE_SUBMIT); | 300 AddUpdateLoginSearch(form, SEARCH_IGNORE_SUBMIT, &forms); |
301 | 301 |
302 bool removed = false; | 302 bool removed = false; |
303 for (size_t i = 0; i < forms.size(); ++i) { | 303 for (size_t i = 0; i < forms.size(); ++i) { |
304 if (*forms[i] != form) { | 304 if (*forms[i] != form) { |
305 RemoveLogin(*forms[i]); | 305 RemoveLogin(*forms[i]); |
306 removed = true; | 306 removed = true; |
307 } | 307 } |
308 } | 308 } |
309 if (!removed) | 309 if (!removed) |
310 return true; | 310 return true; |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
345 changes); | 345 changes); |
346 } | 346 } |
347 | 347 |
348 bool NativeBackendLibsecret::RemoveLoginsSyncedBetween( | 348 bool NativeBackendLibsecret::RemoveLoginsSyncedBetween( |
349 base::Time delete_begin, | 349 base::Time delete_begin, |
350 base::Time delete_end, | 350 base::Time delete_end, |
351 password_manager::PasswordStoreChangeList* changes) { | 351 password_manager::PasswordStoreChangeList* changes) { |
352 return RemoveLoginsBetween(delete_begin, delete_end, SYNC_TIMESTAMP, changes); | 352 return RemoveLoginsBetween(delete_begin, delete_end, SYNC_TIMESTAMP, changes); |
353 } | 353 } |
354 | 354 |
355 bool NativeBackendLibsecret::GetLogins(const PasswordForm& form, | 355 bool NativeBackendLibsecret::GetLogins( |
356 PasswordFormList* forms) { | 356 const PasswordForm& form, |
357 return GetLoginsList(forms, &form, ALL_LOGINS); | 357 ScopedVector<autofill::PasswordForm>* forms) { |
| 358 return GetLoginsList(&form, ALL_LOGINS, forms); |
358 } | 359 } |
359 | 360 |
360 void NativeBackendLibsecret::AddUpdateLoginSearch( | 361 void NativeBackendLibsecret::AddUpdateLoginSearch( |
361 const autofill::PasswordForm& lookup_form, | 362 const autofill::PasswordForm& lookup_form, |
362 PasswordFormList* forms, | 363 AddUpdateLoginSearchOptions options, |
363 AddUpdateLoginSearchOptions options) { | 364 ScopedVector<autofill::PasswordForm>* forms) { |
364 LibsecretAttributesBuilder attrs; | 365 LibsecretAttributesBuilder attrs; |
365 attrs.Append("origin_url", lookup_form.origin.spec()); | 366 attrs.Append("origin_url", lookup_form.origin.spec()); |
366 attrs.Append("username_element", UTF16ToUTF8(lookup_form.username_element)); | 367 attrs.Append("username_element", UTF16ToUTF8(lookup_form.username_element)); |
367 attrs.Append("username_value", UTF16ToUTF8(lookup_form.username_value)); | 368 attrs.Append("username_value", UTF16ToUTF8(lookup_form.username_value)); |
368 attrs.Append("password_element", UTF16ToUTF8(lookup_form.password_element)); | 369 attrs.Append("password_element", UTF16ToUTF8(lookup_form.password_element)); |
369 if (options == SEARCH_USE_SUBMIT) | 370 if (options == SEARCH_USE_SUBMIT) |
370 attrs.Append("submit_element", UTF16ToUTF8(lookup_form.submit_element)); | 371 attrs.Append("submit_element", UTF16ToUTF8(lookup_form.submit_element)); |
371 attrs.Append("signon_realm", lookup_form.signon_realm); | 372 attrs.Append("signon_realm", lookup_form.signon_realm); |
372 attrs.Append("application", app_string_); | 373 attrs.Append("application", app_string_); |
373 | 374 |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
419 "application", app_string_.c_str(), nullptr); | 420 "application", app_string_.c_str(), nullptr); |
420 | 421 |
421 if (error) { | 422 if (error) { |
422 VLOG(1) << "Libsecret add raw login failed: " << error->message; | 423 VLOG(1) << "Libsecret add raw login failed: " << error->message; |
423 g_error_free(error); | 424 g_error_free(error); |
424 return false; | 425 return false; |
425 } | 426 } |
426 return true; | 427 return true; |
427 } | 428 } |
428 | 429 |
429 bool NativeBackendLibsecret::GetAutofillableLogins(PasswordFormList* forms) { | 430 bool NativeBackendLibsecret::GetAutofillableLogins( |
430 return GetLoginsList(forms, nullptr, AUTOFILLABLE_LOGINS); | 431 ScopedVector<autofill::PasswordForm>* forms) { |
| 432 return GetLoginsList(nullptr, AUTOFILLABLE_LOGINS, forms); |
431 } | 433 } |
432 | 434 |
433 bool NativeBackendLibsecret::GetBlacklistLogins(PasswordFormList* forms) { | 435 bool NativeBackendLibsecret::GetBlacklistLogins( |
434 return GetLoginsList(forms, nullptr, BLACKLISTED_LOGINS); | 436 ScopedVector<autofill::PasswordForm>* forms) { |
| 437 return GetLoginsList(nullptr, BLACKLISTED_LOGINS, forms); |
435 } | 438 } |
436 | 439 |
437 bool NativeBackendLibsecret::GetLoginsList(PasswordFormList* forms, | 440 bool NativeBackendLibsecret::GetLoginsList( |
438 const PasswordForm* lookup_form, | 441 const PasswordForm* lookup_form, |
439 GetLoginsListOptions options) { | 442 GetLoginsListOptions options, |
| 443 ScopedVector<autofill::PasswordForm>* forms) { |
440 LibsecretAttributesBuilder attrs; | 444 LibsecretAttributesBuilder attrs; |
441 attrs.Append("application", app_string_); | 445 attrs.Append("application", app_string_); |
442 if (options != ALL_LOGINS) | 446 if (options != ALL_LOGINS) |
443 attrs.Append("blacklisted_by_user", options == BLACKLISTED_LOGINS); | 447 attrs.Append("blacklisted_by_user", options == BLACKLISTED_LOGINS); |
444 if (lookup_form && | 448 if (lookup_form && |
445 !password_manager::ShouldPSLDomainMatchingApply( | 449 !password_manager::ShouldPSLDomainMatchingApply( |
446 password_manager::GetRegistryControlledDomain( | 450 password_manager::GetRegistryControlledDomain( |
447 GURL(lookup_form->signon_realm)))) | 451 GURL(lookup_form->signon_realm)))) |
448 attrs.Append("signon_realm", lookup_form->signon_realm); | 452 attrs.Append("signon_realm", lookup_form->signon_realm); |
449 | 453 |
450 GError* error = nullptr; | 454 GError* error = nullptr; |
451 GList* found = secret_service_search_sync(nullptr, // default secret service | 455 GList* found = secret_service_search_sync(nullptr, // default secret service |
452 &kLibsecretSchema, attrs.Get(), | 456 &kLibsecretSchema, attrs.Get(), |
453 SECRET_SEARCH_ALL, | 457 SECRET_SEARCH_ALL, |
454 nullptr, // no cancellable ojbect | 458 nullptr, // no cancellable ojbect |
455 &error); | 459 &error); |
456 if (error) { | 460 if (error) { |
457 VLOG(1) << "Unable to get logins " << error->message; | 461 VLOG(1) << "Unable to get logins " << error->message; |
458 g_error_free(error); | 462 g_error_free(error); |
459 if (found) | 463 if (found) |
460 g_list_free(found); | 464 g_list_free(found); |
461 return false; | 465 return false; |
462 } | 466 } |
463 | 467 |
464 return ConvertFormList(found, lookup_form, forms); | 468 return ConvertFormList(found, lookup_form, forms); |
465 } | 469 } |
466 | 470 |
467 bool NativeBackendLibsecret::GetAllLogins(PasswordFormList* forms) { | 471 bool NativeBackendLibsecret::GetAllLogins( |
468 return GetLoginsList(forms, nullptr, ALL_LOGINS); | 472 ScopedVector<autofill::PasswordForm>* forms) { |
| 473 return GetLoginsList(nullptr, ALL_LOGINS, forms); |
469 } | 474 } |
470 | 475 |
471 bool NativeBackendLibsecret::GetLoginsBetween( | 476 bool NativeBackendLibsecret::GetLoginsBetween( |
472 base::Time get_begin, | 477 base::Time get_begin, |
473 base::Time get_end, | 478 base::Time get_end, |
474 TimestampToCompare date_to_compare, | 479 TimestampToCompare date_to_compare, |
475 PasswordFormList* forms) { | 480 ScopedVector<autofill::PasswordForm>* forms) { |
476 PasswordFormList all_forms; | 481 ScopedVector<autofill::PasswordForm> all_forms; |
477 if (!GetAllLogins(&all_forms)) | 482 if (!GetAllLogins(&all_forms)) |
478 return false; | 483 return false; |
479 | 484 |
480 base::Time autofill::PasswordForm::*date_member = | 485 base::Time autofill::PasswordForm::*date_member = |
481 date_to_compare == CREATION_TIMESTAMP | 486 date_to_compare == CREATION_TIMESTAMP |
482 ? &autofill::PasswordForm::date_created | 487 ? &autofill::PasswordForm::date_created |
483 : &autofill::PasswordForm::date_synced; | 488 : &autofill::PasswordForm::date_synced; |
484 for (size_t i = 0; i < all_forms.size(); ++i) { | 489 for (auto& saved_form : all_forms) { |
485 if (get_begin <= all_forms[i]->*date_member && | 490 if (get_begin <= saved_form->*date_member && |
486 (get_end.is_null() || all_forms[i]->*date_member < get_end)) { | 491 (get_end.is_null() || saved_form->*date_member < get_end)) { |
487 forms->push_back(all_forms[i]); | 492 forms->push_back(saved_form); |
488 } else { | 493 saved_form = nullptr; |
489 delete all_forms[i]; | |
490 } | 494 } |
491 } | 495 } |
492 | 496 |
493 return true; | 497 return true; |
494 } | 498 } |
495 | 499 |
496 bool NativeBackendLibsecret::RemoveLoginsBetween( | 500 bool NativeBackendLibsecret::RemoveLoginsBetween( |
497 base::Time get_begin, | 501 base::Time get_begin, |
498 base::Time get_end, | 502 base::Time get_end, |
499 TimestampToCompare date_to_compare, | 503 TimestampToCompare date_to_compare, |
500 password_manager::PasswordStoreChangeList* changes) { | 504 password_manager::PasswordStoreChangeList* changes) { |
501 DCHECK(changes); | 505 DCHECK(changes); |
502 changes->clear(); | 506 changes->clear(); |
503 ScopedVector<autofill::PasswordForm> forms; | 507 ScopedVector<autofill::PasswordForm> forms; |
504 if (!GetLoginsBetween(get_begin, get_end, date_to_compare, &forms.get())) | 508 if (!GetLoginsBetween(get_begin, get_end, date_to_compare, &forms)) |
505 return false; | 509 return false; |
506 | 510 |
507 bool ok = true; | 511 bool ok = true; |
508 for (size_t i = 0; i < forms.size(); ++i) { | 512 for (size_t i = 0; i < forms.size(); ++i) { |
509 if (RemoveLogin(*forms[i])) { | 513 if (RemoveLogin(*forms[i])) { |
510 changes->push_back(password_manager::PasswordStoreChange( | 514 changes->push_back(password_manager::PasswordStoreChange( |
511 password_manager::PasswordStoreChange::REMOVE, *forms[i])); | 515 password_manager::PasswordStoreChange::REMOVE, *forms[i])); |
512 } else { | 516 } else { |
513 ok = false; | 517 ok = false; |
514 } | 518 } |
515 } | 519 } |
516 return ok; | 520 return ok; |
517 } | 521 } |
518 | 522 |
519 bool NativeBackendLibsecret::ConvertFormList( | 523 bool NativeBackendLibsecret::ConvertFormList( |
520 GList* found, | 524 GList* found, |
521 const PasswordForm* lookup_form, | 525 const PasswordForm* lookup_form, |
522 NativeBackendLibsecret::PasswordFormList* forms) { | 526 ScopedVector<autofill::PasswordForm>* forms) { |
523 password_manager::PSLDomainMatchMetric psl_domain_match_metric = | 527 password_manager::PSLDomainMatchMetric psl_domain_match_metric = |
524 password_manager::PSL_DOMAIN_MATCH_NONE; | 528 password_manager::PSL_DOMAIN_MATCH_NONE; |
525 GError* error = nullptr; | 529 GError* error = nullptr; |
526 for (GList* element = g_list_first(found); element != nullptr; | 530 for (GList* element = g_list_first(found); element != nullptr; |
527 element = g_list_next(element)) { | 531 element = g_list_next(element)) { |
528 SecretItem* secretItem = static_cast<SecretItem*>(element->data); | 532 SecretItem* secretItem = static_cast<SecretItem*>(element->data); |
529 LibsecretLoader::secret_item_load_secret_sync(secretItem, nullptr, &error); | 533 LibsecretLoader::secret_item_load_secret_sync(secretItem, nullptr, &error); |
530 if (error) { | 534 if (error) { |
531 VLOG(1) << "Unable to load secret item" << error->message; | 535 VLOG(1) << "Unable to load secret item" << error->message; |
532 g_error_free(error); | 536 g_error_free(error); |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
578 return true; | 582 return true; |
579 } | 583 } |
580 | 584 |
581 std::string NativeBackendLibsecret::GetProfileSpecificAppString( | 585 std::string NativeBackendLibsecret::GetProfileSpecificAppString( |
582 LocalProfileId id) { | 586 LocalProfileId id) { |
583 // Originally, the application string was always just "chrome" and used only | 587 // Originally, the application string was always just "chrome" and used only |
584 // so that we had *something* to search for since GNOME Keyring won't search | 588 // so that we had *something* to search for since GNOME Keyring won't search |
585 // for nothing. Now we use it to distinguish passwords for different profiles. | 589 // for nothing. Now we use it to distinguish passwords for different profiles. |
586 return base::StringPrintf("%s-%d", kLibsecretAppString, id); | 590 return base::StringPrintf("%s-%d", kLibsecretAppString, id); |
587 } | 591 } |
OLD | NEW |