| 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_gnome_x.h" | 5 #include "chrome/browser/password_manager/native_backend_gnome_x.h" |
| 6 | 6 |
| 7 #include <dlfcn.h> | 7 #include <dlfcn.h> |
| 8 #include <gnome-keyring.h> | 8 #include <gnome-keyring.h> |
| 9 | 9 |
| 10 #include <map> | 10 #include <map> |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 140 base::StringToInt64(string_attr_map["date_synced"], &date_synced); | 140 base::StringToInt64(string_attr_map["date_synced"], &date_synced); |
| 141 form->date_synced = base::Time::FromInternalValue(date_synced); | 141 form->date_synced = base::Time::FromInternalValue(date_synced); |
| 142 form->display_name = UTF8ToUTF16(string_attr_map["display_name"]); | 142 form->display_name = UTF8ToUTF16(string_attr_map["display_name"]); |
| 143 form->avatar_url = GURL(string_attr_map["avatar_url"]); | 143 form->avatar_url = GURL(string_attr_map["avatar_url"]); |
| 144 form->federation_url = GURL(string_attr_map["federation_url"]); | 144 form->federation_url = GURL(string_attr_map["federation_url"]); |
| 145 form->is_zero_click = uint_attr_map["is_zero_click"]; | 145 form->is_zero_click = uint_attr_map["is_zero_click"]; |
| 146 | 146 |
| 147 return form.Pass(); | 147 return form.Pass(); |
| 148 } | 148 } |
| 149 | 149 |
| 150 // Parse all the results from the given GList into a PasswordFormList, and free | 150 // Parse all the results from the given GList into a |
| 151 // the GList. PasswordForms are allocated on the heap, and should be deleted by | 151 // ScopedVector<autofill::PasswordForm>, and free the GList. PasswordForms are |
| 152 // the consumer. If not NULL, |lookup_form| is used to filter out results -- | 152 // allocated on the heap, and should be deleted by the consumer. If not NULL, |
| 153 // only credentials with signon realms passing the PSL matching against | 153 // |lookup_form| is used to filter out results -- only credentials with signon |
| 154 // |lookup_form->signon_realm| will be kept. PSL matched results get their | 154 // realms passing the PSL matching against |lookup_form->signon_realm| will be |
| 155 // signon_realm, origin, and action rewritten to those of |lookup_form_|, with | 155 // kept. PSL matched results get their signon_realm, origin, and action |
| 156 // the original signon_realm saved into the result's original_signon_realm data | 156 // rewritten to those of |lookup_form_|, with the original signon_realm saved |
| 157 // member. | 157 // into the result's original_signon_realm data member. |
| 158 void ConvertFormList(GList* found, | 158 void ConvertFormList(GList* found, |
| 159 const PasswordForm* lookup_form, | 159 const PasswordForm* lookup_form, |
| 160 NativeBackendGnome::PasswordFormList* forms) { | 160 ScopedVector<autofill::PasswordForm>* forms) { |
| 161 password_manager::PSLDomainMatchMetric psl_domain_match_metric = | 161 password_manager::PSLDomainMatchMetric psl_domain_match_metric = |
| 162 password_manager::PSL_DOMAIN_MATCH_NONE; | 162 password_manager::PSL_DOMAIN_MATCH_NONE; |
| 163 for (GList* element = g_list_first(found); element != NULL; | 163 for (GList* element = g_list_first(found); element != NULL; |
| 164 element = g_list_next(element)) { | 164 element = g_list_next(element)) { |
| 165 GnomeKeyringFound* data = static_cast<GnomeKeyringFound*>(element->data); | 165 GnomeKeyringFound* data = static_cast<GnomeKeyringFound*>(element->data); |
| 166 GnomeKeyringAttributeList* attrs = data->attributes; | 166 GnomeKeyringAttributeList* attrs = data->attributes; |
| 167 | 167 |
| 168 scoped_ptr<PasswordForm> form(FormFromAttributes(attrs)); | 168 scoped_ptr<PasswordForm> form(FormFromAttributes(attrs)); |
| 169 if (form) { | 169 if (form) { |
| 170 if (lookup_form && form->signon_realm != lookup_form->signon_realm) { | 170 if (lookup_form && form->signon_realm != lookup_form->signon_realm) { |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 248 // PasswordStore expects of us. (It will then in turn switch back to the | 248 // PasswordStore expects of us. (It will then in turn switch back to the |
| 249 // original caller to send the asynchronous reply to the original request.) | 249 // original caller to send the asynchronous reply to the original request.) |
| 250 | 250 |
| 251 // This class represents a call to a GNOME Keyring method. A RunnableMethod | 251 // This class represents a call to a GNOME Keyring method. A RunnableMethod |
| 252 // should be posted to the UI thread to call one of its action methods, and then | 252 // should be posted to the UI thread to call one of its action methods, and then |
| 253 // a WaitResult() method should be called to wait for the result. Each instance | 253 // a WaitResult() method should be called to wait for the result. Each instance |
| 254 // supports only one outstanding method at a time, though multiple instances may | 254 // supports only one outstanding method at a time, though multiple instances may |
| 255 // be used in parallel. | 255 // be used in parallel. |
| 256 class GKRMethod : public GnomeKeyringLoader { | 256 class GKRMethod : public GnomeKeyringLoader { |
| 257 public: | 257 public: |
| 258 typedef NativeBackendGnome::PasswordFormList PasswordFormList; | |
| 259 | |
| 260 GKRMethod() : event_(false, false), result_(GNOME_KEYRING_RESULT_CANCELLED) {} | 258 GKRMethod() : event_(false, false), result_(GNOME_KEYRING_RESULT_CANCELLED) {} |
| 261 | 259 |
| 262 // Action methods. These call gnome_keyring_* functions. Call from UI thread. | 260 // Action methods. These call gnome_keyring_* functions. Call from UI thread. |
| 263 // See GetProfileSpecificAppString() for more information on the app string. | 261 // See GetProfileSpecificAppString() for more information on the app string. |
| 264 void AddLogin(const PasswordForm& form, const char* app_string); | 262 void AddLogin(const PasswordForm& form, const char* app_string); |
| 265 void AddLoginSearch(const PasswordForm& form, const char* app_string); | 263 void AddLoginSearch(const PasswordForm& form, const char* app_string); |
| 266 void UpdateLoginSearch(const PasswordForm& form, const char* app_string); | 264 void UpdateLoginSearch(const PasswordForm& form, const char* app_string); |
| 267 void RemoveLogin(const PasswordForm& form, const char* app_string); | 265 void RemoveLogin(const PasswordForm& form, const char* app_string); |
| 268 void GetLogins(const PasswordForm& form, const char* app_string); | 266 void GetLogins(const PasswordForm& form, const char* app_string); |
| 269 void GetLoginsList(uint32_t blacklisted_by_user, const char* app_string); | 267 void GetLoginsList(uint32_t blacklisted_by_user, const char* app_string); |
| 270 void GetAllLogins(const char* app_string); | 268 void GetAllLogins(const char* app_string); |
| 271 | 269 |
| 272 // Use after AddLogin, RemoveLogin. | 270 // Use after AddLogin, RemoveLogin. |
| 273 GnomeKeyringResult WaitResult(); | 271 GnomeKeyringResult WaitResult(); |
| 274 | 272 |
| 275 // Use after AddLoginSearch, UpdateLoginSearch, GetLogins, GetLoginsList, | 273 // Use after AddLoginSearch, UpdateLoginSearch, GetLogins, GetLoginsList, |
| 276 // GetAllLogins. | 274 // GetAllLogins. |
| 277 GnomeKeyringResult WaitResult(PasswordFormList* forms); | 275 GnomeKeyringResult WaitResult(ScopedVector<autofill::PasswordForm>* forms); |
| 278 | 276 |
| 279 private: | 277 private: |
| 280 struct GnomeKeyringAttributeListFreeDeleter { | 278 struct GnomeKeyringAttributeListFreeDeleter { |
| 281 inline void operator()(void* list) const { | 279 inline void operator()(void* list) const { |
| 282 gnome_keyring_attribute_list_free( | 280 gnome_keyring_attribute_list_free( |
| 283 static_cast<GnomeKeyringAttributeList*>(list)); | 281 static_cast<GnomeKeyringAttributeList*>(list)); |
| 284 } | 282 } |
| 285 }; | 283 }; |
| 286 | 284 |
| 287 typedef scoped_ptr<GnomeKeyringAttributeList, | 285 typedef scoped_ptr<GnomeKeyringAttributeList, |
| (...skipping 11 matching lines...) Expand all Loading... |
| 299 guint32 value); | 297 guint32 value); |
| 300 | 298 |
| 301 // All these callbacks are called on UI thread. | 299 // All these callbacks are called on UI thread. |
| 302 static void OnOperationDone(GnomeKeyringResult result, gpointer data); | 300 static void OnOperationDone(GnomeKeyringResult result, gpointer data); |
| 303 | 301 |
| 304 static void OnOperationGetList(GnomeKeyringResult result, GList* list, | 302 static void OnOperationGetList(GnomeKeyringResult result, GList* list, |
| 305 gpointer data); | 303 gpointer data); |
| 306 | 304 |
| 307 base::WaitableEvent event_; | 305 base::WaitableEvent event_; |
| 308 GnomeKeyringResult result_; | 306 GnomeKeyringResult result_; |
| 309 NativeBackendGnome::PasswordFormList forms_; | 307 ScopedVector<autofill::PasswordForm> forms_; |
| 310 // If the credential search is specified by a single form and needs to use PSL | 308 // If the credential search is specified by a single form and needs to use PSL |
| 311 // matching, then the specifying form is stored in |lookup_form_|. If PSL | 309 // matching, then the specifying form is stored in |lookup_form_|. If PSL |
| 312 // matching is used to find a result, then the results signon realm, origin | 310 // matching is used to find a result, then the results signon realm, origin |
| 313 // and action are stored are replaced by those of |lookup_form_|. | 311 // and action are stored are replaced by those of |lookup_form_|. |
| 314 // Additionally, |lookup_form_->signon_realm| is also used to narrow down the | 312 // Additionally, |lookup_form_->signon_realm| is also used to narrow down the |
| 315 // found logins to those which indeed PSL-match the look-up. And finally, | 313 // found logins to those which indeed PSL-match the look-up. And finally, |
| 316 // |lookup_form_| set to NULL means that PSL matching is not required. | 314 // |lookup_form_| set to NULL means that PSL matching is not required. |
| 317 scoped_ptr<PasswordForm> lookup_form_; | 315 scoped_ptr<PasswordForm> lookup_form_; |
| 318 }; | 316 }; |
| 319 | 317 |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 459 /*data=*/this, | 457 /*data=*/this, |
| 460 /*destroy_data=*/NULL); | 458 /*destroy_data=*/NULL); |
| 461 } | 459 } |
| 462 | 460 |
| 463 GnomeKeyringResult GKRMethod::WaitResult() { | 461 GnomeKeyringResult GKRMethod::WaitResult() { |
| 464 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); | 462 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); |
| 465 event_.Wait(); | 463 event_.Wait(); |
| 466 return result_; | 464 return result_; |
| 467 } | 465 } |
| 468 | 466 |
| 469 GnomeKeyringResult GKRMethod::WaitResult(PasswordFormList* forms) { | 467 GnomeKeyringResult GKRMethod::WaitResult( |
| 468 ScopedVector<autofill::PasswordForm>* forms) { |
| 470 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); | 469 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); |
| 471 event_.Wait(); | 470 event_.Wait(); |
| 472 if (forms->empty()) { | 471 if (forms->empty()) { |
| 473 // Normal case. Avoid extra allocation by swapping. | 472 // Normal case. Avoid extra allocation by swapping. |
| 474 forms->swap(forms_); | 473 forms->swap(forms_); |
| 475 } else { | 474 } else { |
| 476 // Rare case. Append forms_ to *forms. | 475 // Rare case. Append forms_ to *forms. |
| 477 forms->insert(forms->end(), forms_.begin(), forms_.end()); | 476 forms->insert(forms->end(), forms_.begin(), forms_.end()); |
| 478 forms_.clear(); | 477 forms_.weak_clear(); |
| 479 } | 478 } |
| 480 return result_; | 479 return result_; |
| 481 } | 480 } |
| 482 | 481 |
| 483 // static | 482 // static |
| 484 void GKRMethod::AppendString(GKRMethod::ScopedAttributeList* list, | 483 void GKRMethod::AppendString(GKRMethod::ScopedAttributeList* list, |
| 485 const char* name, | 484 const char* name, |
| 486 const char* value) { | 485 const char* value) { |
| 487 gnome_keyring_attribute_list_append_string(list->get(), name, value); | 486 gnome_keyring_attribute_list_append_string(list->get(), name, value); |
| 488 } | 487 } |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 557 // element, and signon_realm first, remove that, and then add the new entry. | 556 // element, and signon_realm first, remove that, and then add the new entry. |
| 558 // We'd add the new one first, and then delete the original, but then the | 557 // We'd add the new one first, and then delete the original, but then the |
| 559 // delete might actually delete the newly-added entry! | 558 // delete might actually delete the newly-added entry! |
| 560 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); | 559 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); |
| 561 GKRMethod method; | 560 GKRMethod method; |
| 562 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | 561 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
| 563 base::Bind(&GKRMethod::AddLoginSearch, | 562 base::Bind(&GKRMethod::AddLoginSearch, |
| 564 base::Unretained(&method), | 563 base::Unretained(&method), |
| 565 form, app_string_.c_str())); | 564 form, app_string_.c_str())); |
| 566 ScopedVector<autofill::PasswordForm> forms; | 565 ScopedVector<autofill::PasswordForm> forms; |
| 567 GnomeKeyringResult result = method.WaitResult(&forms.get()); | 566 GnomeKeyringResult result = method.WaitResult(&forms); |
| 568 if (result != GNOME_KEYRING_RESULT_OK && | 567 if (result != GNOME_KEYRING_RESULT_OK && |
| 569 result != GNOME_KEYRING_RESULT_NO_MATCH) { | 568 result != GNOME_KEYRING_RESULT_NO_MATCH) { |
| 570 LOG(ERROR) << "Keyring find failed: " | 569 LOG(ERROR) << "Keyring find failed: " |
| 571 << gnome_keyring_result_to_message(result); | 570 << gnome_keyring_result_to_message(result); |
| 572 return password_manager::PasswordStoreChangeList(); | 571 return password_manager::PasswordStoreChangeList(); |
| 573 } | 572 } |
| 574 password_manager::PasswordStoreChangeList changes; | 573 password_manager::PasswordStoreChangeList changes; |
| 575 if (forms.size() > 0) { | 574 if (forms.size() > 0) { |
| 576 if (forms.size() > 1) { | 575 if (forms.size() > 1) { |
| 577 LOG(WARNING) << "Adding login when there are " << forms.size() | 576 LOG(WARNING) << "Adding login when there are " << forms.size() |
| (...skipping 23 matching lines...) Expand all Loading... |
| 601 // original, but then the delete might actually delete the newly-added entry! | 600 // original, but then the delete might actually delete the newly-added entry! |
| 602 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); | 601 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); |
| 603 DCHECK(changes); | 602 DCHECK(changes); |
| 604 changes->clear(); | 603 changes->clear(); |
| 605 GKRMethod method; | 604 GKRMethod method; |
| 606 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | 605 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
| 607 base::Bind(&GKRMethod::UpdateLoginSearch, | 606 base::Bind(&GKRMethod::UpdateLoginSearch, |
| 608 base::Unretained(&method), | 607 base::Unretained(&method), |
| 609 form, app_string_.c_str())); | 608 form, app_string_.c_str())); |
| 610 ScopedVector<autofill::PasswordForm> forms; | 609 ScopedVector<autofill::PasswordForm> forms; |
| 611 GnomeKeyringResult result = method.WaitResult(&forms.get()); | 610 GnomeKeyringResult result = method.WaitResult(&forms); |
| 612 if (result != GNOME_KEYRING_RESULT_OK) { | 611 if (result != GNOME_KEYRING_RESULT_OK) { |
| 613 LOG(ERROR) << "Keyring find failed: " | 612 LOG(ERROR) << "Keyring find failed: " |
| 614 << gnome_keyring_result_to_message(result); | 613 << gnome_keyring_result_to_message(result); |
| 615 return false; | 614 return false; |
| 616 } | 615 } |
| 617 | 616 |
| 618 bool removed = false; | 617 bool removed = false; |
| 619 for (size_t i = 0; i < forms.size(); ++i) { | 618 for (size_t i = 0; i < forms.size(); ++i) { |
| 620 if (*forms[i] != form) { | 619 if (*forms[i] != form) { |
| 621 RemoveLogin(*forms[i]); | 620 RemoveLogin(*forms[i]); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 660 delete_begin, delete_end, CREATION_TIMESTAMP, changes); | 659 delete_begin, delete_end, CREATION_TIMESTAMP, changes); |
| 661 } | 660 } |
| 662 | 661 |
| 663 bool NativeBackendGnome::RemoveLoginsSyncedBetween( | 662 bool NativeBackendGnome::RemoveLoginsSyncedBetween( |
| 664 base::Time delete_begin, | 663 base::Time delete_begin, |
| 665 base::Time delete_end, | 664 base::Time delete_end, |
| 666 password_manager::PasswordStoreChangeList* changes) { | 665 password_manager::PasswordStoreChangeList* changes) { |
| 667 return RemoveLoginsBetween(delete_begin, delete_end, SYNC_TIMESTAMP, changes); | 666 return RemoveLoginsBetween(delete_begin, delete_end, SYNC_TIMESTAMP, changes); |
| 668 } | 667 } |
| 669 | 668 |
| 670 bool NativeBackendGnome::GetLogins(const PasswordForm& form, | 669 bool NativeBackendGnome::GetLogins( |
| 671 PasswordFormList* forms) { | 670 const PasswordForm& form, |
| 671 ScopedVector<autofill::PasswordForm>* forms) { |
| 672 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); | 672 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); |
| 673 GKRMethod method; | 673 GKRMethod method; |
| 674 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | 674 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
| 675 base::Bind(&GKRMethod::GetLogins, | 675 base::Bind(&GKRMethod::GetLogins, |
| 676 base::Unretained(&method), | 676 base::Unretained(&method), |
| 677 form, app_string_.c_str())); | 677 form, app_string_.c_str())); |
| 678 GnomeKeyringResult result = method.WaitResult(forms); | 678 GnomeKeyringResult result = method.WaitResult(forms); |
| 679 if (result == GNOME_KEYRING_RESULT_NO_MATCH) | 679 if (result == GNOME_KEYRING_RESULT_NO_MATCH) |
| 680 return true; | 680 return true; |
| 681 if (result != GNOME_KEYRING_RESULT_OK) { | 681 if (result != GNOME_KEYRING_RESULT_OK) { |
| 682 LOG(ERROR) << "Keyring find failed: " | 682 LOG(ERROR) << "Keyring find failed: " |
| 683 << gnome_keyring_result_to_message(result); | 683 << gnome_keyring_result_to_message(result); |
| 684 return false; | 684 return false; |
| 685 } | 685 } |
| 686 return true; | 686 return true; |
| 687 } | 687 } |
| 688 | 688 |
| 689 bool NativeBackendGnome::GetAutofillableLogins(PasswordFormList* forms) { | 689 bool NativeBackendGnome::GetAutofillableLogins( |
| 690 return GetLoginsList(forms, true); | 690 ScopedVector<autofill::PasswordForm>* forms) { |
| 691 return GetLoginsList(true, forms); |
| 691 } | 692 } |
| 692 | 693 |
| 693 bool NativeBackendGnome::GetBlacklistLogins(PasswordFormList* forms) { | 694 bool NativeBackendGnome::GetBlacklistLogins( |
| 694 return GetLoginsList(forms, false); | 695 ScopedVector<autofill::PasswordForm>* forms) { |
| 696 return GetLoginsList(false, forms); |
| 695 } | 697 } |
| 696 | 698 |
| 697 bool NativeBackendGnome::GetLoginsList(PasswordFormList* forms, | 699 bool NativeBackendGnome::GetLoginsList( |
| 698 bool autofillable) { | 700 bool autofillable, |
| 701 ScopedVector<autofill::PasswordForm>* forms) { |
| 699 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); | 702 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); |
| 700 | 703 |
| 701 uint32_t blacklisted_by_user = !autofillable; | 704 uint32_t blacklisted_by_user = !autofillable; |
| 702 | 705 |
| 703 GKRMethod method; | 706 GKRMethod method; |
| 704 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | 707 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
| 705 base::Bind(&GKRMethod::GetLoginsList, | 708 base::Bind(&GKRMethod::GetLoginsList, |
| 706 base::Unretained(&method), | 709 base::Unretained(&method), |
| 707 blacklisted_by_user, app_string_.c_str())); | 710 blacklisted_by_user, app_string_.c_str())); |
| 708 GnomeKeyringResult result = method.WaitResult(forms); | 711 GnomeKeyringResult result = method.WaitResult(forms); |
| 709 if (result == GNOME_KEYRING_RESULT_NO_MATCH) | 712 if (result == GNOME_KEYRING_RESULT_NO_MATCH) |
| 710 return true; | 713 return true; |
| 711 if (result != GNOME_KEYRING_RESULT_OK) { | 714 if (result != GNOME_KEYRING_RESULT_OK) { |
| 712 LOG(ERROR) << "Keyring find failed: " | 715 LOG(ERROR) << "Keyring find failed: " |
| 713 << gnome_keyring_result_to_message(result); | 716 << gnome_keyring_result_to_message(result); |
| 714 return false; | 717 return false; |
| 715 } | 718 } |
| 716 return true; | 719 return true; |
| 717 } | 720 } |
| 718 | 721 |
| 719 bool NativeBackendGnome::GetAllLogins(PasswordFormList* forms) { | 722 bool NativeBackendGnome::GetAllLogins( |
| 723 ScopedVector<autofill::PasswordForm>* forms) { |
| 720 GKRMethod method; | 724 GKRMethod method; |
| 721 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | 725 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
| 722 base::Bind(&GKRMethod::GetAllLogins, | 726 base::Bind(&GKRMethod::GetAllLogins, |
| 723 base::Unretained(&method), | 727 base::Unretained(&method), |
| 724 app_string_.c_str())); | 728 app_string_.c_str())); |
| 725 GnomeKeyringResult result = method.WaitResult(forms); | 729 GnomeKeyringResult result = method.WaitResult(forms); |
| 726 if (result == GNOME_KEYRING_RESULT_NO_MATCH) | 730 if (result == GNOME_KEYRING_RESULT_NO_MATCH) |
| 727 return true; | 731 return true; |
| 728 if (result != GNOME_KEYRING_RESULT_OK) { | 732 if (result != GNOME_KEYRING_RESULT_OK) { |
| 729 LOG(ERROR) << "Keyring find failed: " | 733 LOG(ERROR) << "Keyring find failed: " |
| 730 << gnome_keyring_result_to_message(result); | 734 << gnome_keyring_result_to_message(result); |
| 731 return false; | 735 return false; |
| 732 } | 736 } |
| 733 return true; | 737 return true; |
| 734 } | 738 } |
| 735 | 739 |
| 736 bool NativeBackendGnome::GetLoginsBetween(base::Time get_begin, | 740 bool NativeBackendGnome::GetLoginsBetween( |
| 737 base::Time get_end, | 741 base::Time get_begin, |
| 738 TimestampToCompare date_to_compare, | 742 base::Time get_end, |
| 739 PasswordFormList* forms) { | 743 TimestampToCompare date_to_compare, |
| 744 ScopedVector<autofill::PasswordForm>* forms) { |
| 740 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); | 745 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); |
| 741 // We could walk the list and add items as we find them, but it is much | 746 // We could walk the list and add items as we find them, but it is much |
| 742 // easier to build the list and then filter the results. | 747 // easier to build the list and then filter the results. |
| 743 PasswordFormList all_forms; | 748 ScopedVector<autofill::PasswordForm> all_forms; |
| 744 if (!GetAllLogins(&all_forms)) | 749 if (!GetAllLogins(&all_forms)) |
| 745 return false; | 750 return false; |
| 746 | 751 |
| 747 base::Time autofill::PasswordForm::*date_member = | 752 base::Time autofill::PasswordForm::*date_member = |
| 748 date_to_compare == CREATION_TIMESTAMP | 753 date_to_compare == CREATION_TIMESTAMP |
| 749 ? &autofill::PasswordForm::date_created | 754 ? &autofill::PasswordForm::date_created |
| 750 : &autofill::PasswordForm::date_synced; | 755 : &autofill::PasswordForm::date_synced; |
| 751 for (size_t i = 0; i < all_forms.size(); ++i) { | 756 for (auto& saved_form : all_forms) { |
| 752 if (get_begin <= all_forms[i]->*date_member && | 757 if (get_begin <= saved_form->*date_member && |
| 753 (get_end.is_null() || all_forms[i]->*date_member < get_end)) { | 758 (get_end.is_null() || saved_form->*date_member < get_end)) { |
| 754 forms->push_back(all_forms[i]); | 759 forms->push_back(saved_form); |
| 755 } else { | 760 saved_form = nullptr; |
| 756 delete all_forms[i]; | |
| 757 } | 761 } |
| 758 } | 762 } |
| 759 | 763 |
| 760 return true; | 764 return true; |
| 761 } | 765 } |
| 762 | 766 |
| 763 bool NativeBackendGnome::RemoveLoginsBetween( | 767 bool NativeBackendGnome::RemoveLoginsBetween( |
| 764 base::Time get_begin, | 768 base::Time get_begin, |
| 765 base::Time get_end, | 769 base::Time get_end, |
| 766 TimestampToCompare date_to_compare, | 770 TimestampToCompare date_to_compare, |
| 767 password_manager::PasswordStoreChangeList* changes) { | 771 password_manager::PasswordStoreChangeList* changes) { |
| 768 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); | 772 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); |
| 769 DCHECK(changes); | 773 DCHECK(changes); |
| 770 changes->clear(); | 774 changes->clear(); |
| 771 // We could walk the list and delete items as we find them, but it is much | 775 // We could walk the list and delete items as we find them, but it is much |
| 772 // easier to build the list and use RemoveLogin() to delete them. | 776 // easier to build the list and use RemoveLogin() to delete them. |
| 773 ScopedVector<autofill::PasswordForm> forms; | 777 ScopedVector<autofill::PasswordForm> forms; |
| 774 if (!GetLoginsBetween(get_begin, get_end, date_to_compare, &forms.get())) | 778 if (!GetLoginsBetween(get_begin, get_end, date_to_compare, &forms)) |
| 775 return false; | 779 return false; |
| 776 | 780 |
| 777 bool ok = true; | 781 bool ok = true; |
| 778 for (size_t i = 0; i < forms.size(); ++i) { | 782 for (size_t i = 0; i < forms.size(); ++i) { |
| 779 if (RemoveLogin(*forms[i])) { | 783 if (RemoveLogin(*forms[i])) { |
| 780 changes->push_back(password_manager::PasswordStoreChange( | 784 changes->push_back(password_manager::PasswordStoreChange( |
| 781 password_manager::PasswordStoreChange::REMOVE, *forms[i])); | 785 password_manager::PasswordStoreChange::REMOVE, *forms[i])); |
| 782 } else { | 786 } else { |
| 783 ok = false; | 787 ok = false; |
| 784 } | 788 } |
| 785 } | 789 } |
| 786 return ok; | 790 return ok; |
| 787 } | 791 } |
| 788 | 792 |
| 789 std::string NativeBackendGnome::GetProfileSpecificAppString() const { | 793 std::string NativeBackendGnome::GetProfileSpecificAppString() const { |
| 790 // Originally, the application string was always just "chrome" and used only | 794 // Originally, the application string was always just "chrome" and used only |
| 791 // so that we had *something* to search for since GNOME Keyring won't search | 795 // so that we had *something* to search for since GNOME Keyring won't search |
| 792 // for nothing. Now we use it to distinguish passwords for different profiles. | 796 // for nothing. Now we use it to distinguish passwords for different profiles. |
| 793 return base::StringPrintf("%s-%d", kGnomeKeyringAppString, profile_id_); | 797 return base::StringPrintf("%s-%d", kGnomeKeyringAppString, profile_id_); |
| 794 } | 798 } |
| OLD | NEW |