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

Side by Side Diff: chrome/browser/password_manager/native_backend_gnome_x.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: Fix FillMatchingLogins + a typo Created 5 years, 9 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) 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 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
155 form->avatar_url = GURL(string_attr_map["avatar_url"]); 155 form->avatar_url = GURL(string_attr_map["avatar_url"]);
156 form->federation_url = GURL(string_attr_map["federation_url"]); 156 form->federation_url = GURL(string_attr_map["federation_url"]);
157 form->skip_zero_click = uint_attr_map["skip_zero_click"]; 157 form->skip_zero_click = uint_attr_map["skip_zero_click"];
158 form->generation_upload_status = 158 form->generation_upload_status =
159 static_cast<PasswordForm::GenerationUploadStatus>( 159 static_cast<PasswordForm::GenerationUploadStatus>(
160 uint_attr_map["generation_upload_status"]); 160 uint_attr_map["generation_upload_status"]);
161 161
162 return form.Pass(); 162 return form.Pass();
163 } 163 }
164 164
165 // Parse all the results from the given GList into a 165 // Converts native credentials in |found| to PasswordForms. If not NULL,
vabr (Chromium) 2015/03/09 17:44:15 The gnome_keyring_found_list_free call was dropped
engedy 2015/03/11 19:25:34 Thanks for checking. As per this offline discussio
166 // ScopedVector<autofill::PasswordForm>, and free the GList. PasswordForms are
167 // allocated on the heap, and should be deleted by the consumer. If not NULL,
168 // |lookup_form| is used to filter out results -- only credentials with signon 166 // |lookup_form| is used to filter out results -- only credentials with signon
169 // realms passing the PSL matching against |lookup_form->signon_realm| will be 167 // realms passing the PSL matching against |lookup_form->signon_realm| will be
170 // kept. PSL matched results get their signon_realm, origin, and action 168 // kept. PSL matched results get their signon_realm, origin, and action
171 // rewritten to those of |lookup_form_|, with the original signon_realm saved 169 // rewritten to those of |lookup_form_|, with the original signon_realm saved
172 // into the result's original_signon_realm data member. 170 // into the result's original_signon_realm data member.
173 void ConvertFormList(GList* found, 171 ScopedVector<PasswordForm> ConvertFormList(GList* found,
174 const PasswordForm* lookup_form, 172 const PasswordForm* lookup_form) {
175 ScopedVector<autofill::PasswordForm>* forms) { 173 ScopedVector<PasswordForm> forms;
176 password_manager::PSLDomainMatchMetric psl_domain_match_metric = 174 password_manager::PSLDomainMatchMetric psl_domain_match_metric =
177 password_manager::PSL_DOMAIN_MATCH_NONE; 175 password_manager::PSL_DOMAIN_MATCH_NONE;
178 for (GList* element = g_list_first(found); element; 176 for (GList* element = g_list_first(found); element;
179 element = g_list_next(element)) { 177 element = g_list_next(element)) {
180 GnomeKeyringFound* data = static_cast<GnomeKeyringFound*>(element->data); 178 GnomeKeyringFound* data = static_cast<GnomeKeyringFound*>(element->data);
181 GnomeKeyringAttributeList* attrs = data->attributes; 179 GnomeKeyringAttributeList* attrs = data->attributes;
182 180
183 scoped_ptr<PasswordForm> form(FormFromAttributes(attrs)); 181 scoped_ptr<PasswordForm> form(FormFromAttributes(attrs));
184 if (form) { 182 if (form) {
185 if (lookup_form && form->signon_realm != lookup_form->signon_realm) { 183 if (lookup_form && form->signon_realm != lookup_form->signon_realm) {
186 // This is not an exact match, we try PSL matching. 184 // This is not an exact match, we try PSL matching.
187 if (lookup_form->scheme != PasswordForm::SCHEME_HTML || 185 if (lookup_form->scheme != PasswordForm::SCHEME_HTML ||
188 form->scheme != PasswordForm::SCHEME_HTML || 186 form->scheme != PasswordForm::SCHEME_HTML ||
189 !(password_manager::IsPublicSuffixDomainMatch( 187 !(password_manager::IsPublicSuffixDomainMatch(
190 lookup_form->signon_realm, form->signon_realm))) { 188 lookup_form->signon_realm, form->signon_realm))) {
191 continue; 189 continue;
192 } 190 }
193 psl_domain_match_metric = password_manager::PSL_DOMAIN_MATCH_FOUND; 191 psl_domain_match_metric = password_manager::PSL_DOMAIN_MATCH_FOUND;
194 form->original_signon_realm = form->signon_realm; 192 form->original_signon_realm = form->signon_realm;
195 form->signon_realm = lookup_form->signon_realm; 193 form->signon_realm = lookup_form->signon_realm;
196 form->origin = lookup_form->origin; 194 form->origin = lookup_form->origin;
197 form->action = lookup_form->action; 195 form->action = lookup_form->action;
198 } 196 }
199 if (data->secret) { 197 if (data->secret) {
200 form->password_value = UTF8ToUTF16(data->secret); 198 form->password_value = UTF8ToUTF16(data->secret);
201 } else { 199 } else {
202 LOG(WARNING) << "Unable to access password from list element!"; 200 LOG(WARNING) << "Unable to access password from list element!";
203 } 201 }
204 forms->push_back(form.release()); 202 forms.push_back(form.release());
205 } else { 203 } else {
206 LOG(WARNING) << "Could not initialize PasswordForm from attributes!"; 204 LOG(WARNING) << "Could not initialize PasswordForm from attributes!";
207 } 205 }
208 } 206 }
209 if (lookup_form) { 207 if (lookup_form) {
210 const GURL signon_realm(lookup_form->signon_realm); 208 const GURL signon_realm(lookup_form->signon_realm);
211 std::string registered_domain = 209 std::string registered_domain =
212 password_manager::GetRegistryControlledDomain(signon_realm); 210 password_manager::GetRegistryControlledDomain(signon_realm);
213 UMA_HISTOGRAM_ENUMERATION( 211 UMA_HISTOGRAM_ENUMERATION(
214 "PasswordManager.PslDomainMatchTriggering", 212 "PasswordManager.PslDomainMatchTriggering",
215 password_manager::ShouldPSLDomainMatchingApply(registered_domain) 213 password_manager::ShouldPSLDomainMatchingApply(registered_domain)
216 ? psl_domain_match_metric 214 ? psl_domain_match_metric
217 : password_manager::PSL_DOMAIN_MATCH_NOT_USED, 215 : password_manager::PSL_DOMAIN_MATCH_NOT_USED,
218 password_manager::PSL_DOMAIN_MATCH_COUNT); 216 password_manager::PSL_DOMAIN_MATCH_COUNT);
219 } 217 }
218 return forms.Pass();
220 } 219 }
221 220
222 // Schema is analagous to the fields in PasswordForm. 221 // Schema is analagous to the fields in PasswordForm.
223 // TODO(gcasto): Adding 'form_data' would be nice, but we would need to 222 // TODO(gcasto): Adding 'form_data' would be nice, but we would need to
224 // serialize in a way that is guaranteed to not have any embedded NULLs. Pickle 223 // serialize in a way that is guaranteed to not have any embedded NULLs. Pickle
225 // doesn't make this guarantee, so we just don't serialize this field. Since 224 // doesn't make this guarantee, so we just don't serialize this field. Since
226 // it's only used to crowd source data collection it doesn't matter that much 225 // it's only used to crowd source data collection it doesn't matter that much
227 // if it's not available on this platform. 226 // if it's not available on this platform.
228 const GnomeKeyringPasswordSchema kGnomeSchema = { 227 const GnomeKeyringPasswordSchema kGnomeSchema = {
229 GNOME_KEYRING_ITEM_GENERIC_SECRET, { 228 GNOME_KEYRING_ITEM_GENERIC_SECRET, {
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
280 void UpdateLoginSearch(const PasswordForm& form, const char* app_string); 279 void UpdateLoginSearch(const PasswordForm& form, const char* app_string);
281 void RemoveLogin(const PasswordForm& form, const char* app_string); 280 void RemoveLogin(const PasswordForm& form, const char* app_string);
282 void GetLogins(const PasswordForm& form, const char* app_string); 281 void GetLogins(const PasswordForm& form, const char* app_string);
283 void GetLoginsList(uint32_t blacklisted_by_user, const char* app_string); 282 void GetLoginsList(uint32_t blacklisted_by_user, const char* app_string);
284 void GetAllLogins(const char* app_string); 283 void GetAllLogins(const char* app_string);
285 284
286 // Use after AddLogin, RemoveLogin. 285 // Use after AddLogin, RemoveLogin.
287 GnomeKeyringResult WaitResult(); 286 GnomeKeyringResult WaitResult();
288 287
289 // Use after AddLoginSearch, UpdateLoginSearch, GetLogins, GetLoginsList, 288 // Use after AddLoginSearch, UpdateLoginSearch, GetLogins, GetLoginsList,
290 // GetAllLogins. 289 // GetAllLogins. Replaces the content of |forms| with found logins.
291 GnomeKeyringResult WaitResult(ScopedVector<autofill::PasswordForm>* forms); 290 GnomeKeyringResult WaitResult(ScopedVector<PasswordForm>* forms);
292 291
293 private: 292 private:
294 struct GnomeKeyringAttributeListFreeDeleter { 293 struct GnomeKeyringAttributeListFreeDeleter {
295 inline void operator()(void* list) const { 294 inline void operator()(void* list) const {
296 gnome_keyring_attribute_list_free( 295 gnome_keyring_attribute_list_free(
297 static_cast<GnomeKeyringAttributeList*>(list)); 296 static_cast<GnomeKeyringAttributeList*>(list));
298 } 297 }
299 }; 298 };
300 299
301 typedef scoped_ptr<GnomeKeyringAttributeList, 300 typedef scoped_ptr<GnomeKeyringAttributeList,
302 GnomeKeyringAttributeListFreeDeleter> ScopedAttributeList; 301 GnomeKeyringAttributeListFreeDeleter> ScopedAttributeList;
303 302
304 // Helper methods to abbreviate Gnome Keyring long API names. 303 // Helper methods to abbreviate Gnome Keyring long API names.
305 static void AppendString(ScopedAttributeList* list, 304 static void AppendString(ScopedAttributeList* list,
306 const char* name, 305 const char* name,
307 const char* value); 306 const char* value);
308 static void AppendString(ScopedAttributeList* list, 307 static void AppendString(ScopedAttributeList* list,
309 const char* name, 308 const char* name,
310 const std::string& value); 309 const std::string& value);
311 static void AppendUint32(ScopedAttributeList* list, 310 static void AppendUint32(ScopedAttributeList* list,
312 const char* name, 311 const char* name,
313 guint32 value); 312 guint32 value);
314 313
315 // All these callbacks are called on UI thread. 314 // All these callbacks are called on UI thread.
316 static void OnOperationDone(GnomeKeyringResult result, gpointer data); 315 static void OnOperationDone(GnomeKeyringResult result, gpointer data);
317 316
317 // This is marked as static, but acts on the GKRMethod instance that |data|
318 // points to. Saves |result| to |result_|. If the result is OK, overwrites
319 // |forms_| with the found credentials. Clears |forms_| otherwise.
318 static void OnOperationGetList(GnomeKeyringResult result, GList* list, 320 static void OnOperationGetList(GnomeKeyringResult result, GList* list,
319 gpointer data); 321 gpointer data);
320 322
321 base::WaitableEvent event_; 323 base::WaitableEvent event_;
322 GnomeKeyringResult result_; 324 GnomeKeyringResult result_;
323 ScopedVector<autofill::PasswordForm> forms_; 325 ScopedVector<PasswordForm> forms_;
324 // If the credential search is specified by a single form and needs to use PSL 326 // If the credential search is specified by a single form and needs to use PSL
325 // matching, then the specifying form is stored in |lookup_form_|. If PSL 327 // matching, then the specifying form is stored in |lookup_form_|. If PSL
326 // matching is used to find a result, then the results signon realm, origin 328 // matching is used to find a result, then the results signon realm, origin
327 // and action are stored are replaced by those of |lookup_form_|. 329 // and action are stored are replaced by those of |lookup_form_|.
328 // Additionally, |lookup_form_->signon_realm| is also used to narrow down the 330 // Additionally, |lookup_form_->signon_realm| is also used to narrow down the
329 // found logins to those which indeed PSL-match the look-up. And finally, 331 // found logins to those which indeed PSL-match the look-up. And finally,
330 // |lookup_form_| set to NULL means that PSL matching is not required. 332 // |lookup_form_| set to NULL means that PSL matching is not required.
331 scoped_ptr<PasswordForm> lookup_form_; 333 scoped_ptr<PasswordForm> lookup_form_;
332 }; 334 };
333 335
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
474 /*data=*/this, 476 /*data=*/this,
475 /*destroy_data=*/nullptr); 477 /*destroy_data=*/nullptr);
476 } 478 }
477 479
478 GnomeKeyringResult GKRMethod::WaitResult() { 480 GnomeKeyringResult GKRMethod::WaitResult() {
479 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 481 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
480 event_.Wait(); 482 event_.Wait();
481 return result_; 483 return result_;
482 } 484 }
483 485
484 GnomeKeyringResult GKRMethod::WaitResult( 486 GnomeKeyringResult GKRMethod::WaitResult(ScopedVector<PasswordForm>* forms) {
485 ScopedVector<autofill::PasswordForm>* forms) {
486 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 487 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
487 event_.Wait(); 488 event_.Wait();
488 if (forms->empty()) { 489 forms->swap(forms_);
489 // Normal case. Avoid extra allocation by swapping.
490 forms->swap(forms_);
491 } else {
492 // Rare case. Append forms_ to *forms.
493 forms->insert(forms->end(), forms_.begin(), forms_.end());
494 forms_.weak_clear();
495 }
496 return result_; 490 return result_;
497 } 491 }
498 492
499 // static 493 // static
500 void GKRMethod::AppendString(GKRMethod::ScopedAttributeList* list, 494 void GKRMethod::AppendString(GKRMethod::ScopedAttributeList* list,
501 const char* name, 495 const char* name,
502 const char* value) { 496 const char* value) {
503 gnome_keyring_attribute_list_append_string(list->get(), name, value); 497 gnome_keyring_attribute_list_append_string(list->get(), name, value);
504 } 498 }
505 499
(...skipping 18 matching lines...) Expand all
524 method->event_.Signal(); 518 method->event_.Signal();
525 } 519 }
526 520
527 // static 521 // static
528 void GKRMethod::OnOperationGetList(GnomeKeyringResult result, GList* list, 522 void GKRMethod::OnOperationGetList(GnomeKeyringResult result, GList* list,
529 gpointer data) { 523 gpointer data) {
530 GKRMethod* method = static_cast<GKRMethod*>(data); 524 GKRMethod* method = static_cast<GKRMethod*>(data);
531 method->result_ = result; 525 method->result_ = result;
532 method->forms_.clear(); 526 method->forms_.clear();
533 // |list| will be freed after this callback returns, so convert it now. 527 // |list| will be freed after this callback returns, so convert it now.
534 ConvertFormList(list, method->lookup_form_.get(), &method->forms_); 528 if (result == GNOME_KEYRING_RESULT_OK)
529 method->forms_ = ConvertFormList(list, method->lookup_form_.get());
535 method->lookup_form_.reset(); 530 method->lookup_form_.reset();
536 method->event_.Signal(); 531 method->event_.Signal();
537 } 532 }
538 533
534 // Generates a profile-specific app string based on profile_id.
535 std::string GetProfileSpecificAppString(LocalProfileId profile_id) {
536 // Originally, the application string was always just "chrome" and used only
537 // so that we had *something* to search for since GNOME Keyring won't search
538 // for nothing. Now we use it to distinguish passwords for different profiles.
539 return base::StringPrintf("%s-%d", kGnomeKeyringAppString, profile_id);
540 }
541
539 } // namespace 542 } // namespace
540 543
541 NativeBackendGnome::NativeBackendGnome(LocalProfileId id) 544 NativeBackendGnome::NativeBackendGnome(LocalProfileId id)
542 : profile_id_(id) { 545 : profile_id_(id), app_string_(GetProfileSpecificAppString(id)) {
543 app_string_ = GetProfileSpecificAppString();
544 } 546 }
545 547
546 NativeBackendGnome::~NativeBackendGnome() { 548 NativeBackendGnome::~NativeBackendGnome() {
547 } 549 }
548 550
549 bool NativeBackendGnome::Init() { 551 bool NativeBackendGnome::Init() {
550 return LoadGnomeKeyring() && gnome_keyring_is_available(); 552 return LoadGnomeKeyring() && gnome_keyring_is_available();
551 } 553 }
552 554
553 bool NativeBackendGnome::RawAddLogin(const PasswordForm& form) { 555 bool NativeBackendGnome::RawAddLogin(const PasswordForm& form) {
(...skipping 18 matching lines...) Expand all
572 // on origin_url, username_element, username_value, password_element, submit 574 // on origin_url, username_element, username_value, password_element, submit
573 // element, and signon_realm first, remove that, and then add the new entry. 575 // element, and signon_realm first, remove that, and then add the new entry.
574 // We'd add the new one first, and then delete the original, but then the 576 // We'd add the new one first, and then delete the original, but then the
575 // delete might actually delete the newly-added entry! 577 // delete might actually delete the newly-added entry!
576 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 578 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
577 GKRMethod method; 579 GKRMethod method;
578 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 580 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
579 base::Bind(&GKRMethod::AddLoginSearch, 581 base::Bind(&GKRMethod::AddLoginSearch,
580 base::Unretained(&method), 582 base::Unretained(&method),
581 form, app_string_.c_str())); 583 form, app_string_.c_str()));
582 ScopedVector<autofill::PasswordForm> forms; 584 ScopedVector<PasswordForm> forms;
583 GnomeKeyringResult result = method.WaitResult(&forms); 585 GnomeKeyringResult result = method.WaitResult(&forms);
584 if (result != GNOME_KEYRING_RESULT_OK && 586 if (result != GNOME_KEYRING_RESULT_OK &&
585 result != GNOME_KEYRING_RESULT_NO_MATCH) { 587 result != GNOME_KEYRING_RESULT_NO_MATCH) {
586 LOG(ERROR) << "Keyring find failed: " 588 LOG(ERROR) << "Keyring find failed: "
587 << gnome_keyring_result_to_message(result); 589 << gnome_keyring_result_to_message(result);
588 return password_manager::PasswordStoreChangeList(); 590 return password_manager::PasswordStoreChangeList();
589 } 591 }
590 password_manager::PasswordStoreChangeList changes; 592 password_manager::PasswordStoreChangeList changes;
591 if (forms.size() > 0) { 593 if (forms.size() > 0) {
592 if (forms.size() > 1) { 594 if (forms.size() > 1) {
(...skipping 23 matching lines...) Expand all
616 // then add the new entry. We'd add the new one first, and then delete the 618 // then add the new entry. We'd add the new one first, and then delete the
617 // original, but then the delete might actually delete the newly-added entry! 619 // original, but then the delete might actually delete the newly-added entry!
618 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 620 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
619 DCHECK(changes); 621 DCHECK(changes);
620 changes->clear(); 622 changes->clear();
621 GKRMethod method; 623 GKRMethod method;
622 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 624 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
623 base::Bind(&GKRMethod::UpdateLoginSearch, 625 base::Bind(&GKRMethod::UpdateLoginSearch,
624 base::Unretained(&method), 626 base::Unretained(&method),
625 form, app_string_.c_str())); 627 form, app_string_.c_str()));
626 ScopedVector<autofill::PasswordForm> forms; 628 ScopedVector<PasswordForm> forms;
627 GnomeKeyringResult result = method.WaitResult(&forms); 629 GnomeKeyringResult result = method.WaitResult(&forms);
628 if (result != GNOME_KEYRING_RESULT_OK) { 630 if (result != GNOME_KEYRING_RESULT_OK) {
629 LOG(ERROR) << "Keyring find failed: " 631 LOG(ERROR) << "Keyring find failed: "
630 << gnome_keyring_result_to_message(result); 632 << gnome_keyring_result_to_message(result);
631 return false; 633 return false;
632 } 634 }
633 635
634 bool removed = false; 636 bool removed = false;
635 for (size_t i = 0; i < forms.size(); ++i) { 637 for (size_t i = 0; i < forms.size(); ++i) {
636 if (*forms[i] != form) { 638 if (*forms[i] != form) {
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
676 delete_begin, delete_end, CREATION_TIMESTAMP, changes); 678 delete_begin, delete_end, CREATION_TIMESTAMP, changes);
677 } 679 }
678 680
679 bool NativeBackendGnome::RemoveLoginsSyncedBetween( 681 bool NativeBackendGnome::RemoveLoginsSyncedBetween(
680 base::Time delete_begin, 682 base::Time delete_begin,
681 base::Time delete_end, 683 base::Time delete_end,
682 password_manager::PasswordStoreChangeList* changes) { 684 password_manager::PasswordStoreChangeList* changes) {
683 return RemoveLoginsBetween(delete_begin, delete_end, SYNC_TIMESTAMP, changes); 685 return RemoveLoginsBetween(delete_begin, delete_end, SYNC_TIMESTAMP, changes);
684 } 686 }
685 687
686 bool NativeBackendGnome::GetLogins( 688 bool NativeBackendGnome::GetLogins(const PasswordForm& form,
687 const PasswordForm& form, 689 ScopedVector<PasswordForm>* forms) {
688 ScopedVector<autofill::PasswordForm>* forms) {
689 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 690 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
690 GKRMethod method; 691 GKRMethod method;
691 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 692 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
692 base::Bind(&GKRMethod::GetLogins, 693 base::Bind(&GKRMethod::GetLogins,
693 base::Unretained(&method), 694 base::Unretained(&method),
694 form, app_string_.c_str())); 695 form, app_string_.c_str()));
695 GnomeKeyringResult result = method.WaitResult(forms); 696 GnomeKeyringResult result = method.WaitResult(forms);
696 if (result == GNOME_KEYRING_RESULT_NO_MATCH) 697 if (result == GNOME_KEYRING_RESULT_NO_MATCH)
697 return true; 698 return true;
698 if (result != GNOME_KEYRING_RESULT_OK) { 699 if (result != GNOME_KEYRING_RESULT_OK) {
699 LOG(ERROR) << "Keyring find failed: " 700 LOG(ERROR) << "Keyring find failed: "
700 << gnome_keyring_result_to_message(result); 701 << gnome_keyring_result_to_message(result);
701 return false; 702 return false;
702 } 703 }
703 return true; 704 return true;
704 } 705 }
705 706
706 bool NativeBackendGnome::GetAutofillableLogins( 707 bool NativeBackendGnome::GetAutofillableLogins(
707 ScopedVector<autofill::PasswordForm>* forms) { 708 ScopedVector<PasswordForm>* forms) {
708 return GetLoginsList(true, forms); 709 return GetLoginsList(true, forms);
709 } 710 }
710 711
711 bool NativeBackendGnome::GetBlacklistLogins( 712 bool NativeBackendGnome::GetBlacklistLogins(ScopedVector<PasswordForm>* forms) {
712 ScopedVector<autofill::PasswordForm>* forms) {
713 return GetLoginsList(false, forms); 713 return GetLoginsList(false, forms);
714 } 714 }
715 715
716 bool NativeBackendGnome::GetLoginsList( 716 bool NativeBackendGnome::GetLoginsList(bool autofillable,
717 bool autofillable, 717 ScopedVector<PasswordForm>* forms) {
718 ScopedVector<autofill::PasswordForm>* forms) {
719 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 718 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
720 719
721 uint32_t blacklisted_by_user = !autofillable; 720 uint32_t blacklisted_by_user = !autofillable;
722 721
723 GKRMethod method; 722 GKRMethod method;
724 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 723 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
725 base::Bind(&GKRMethod::GetLoginsList, 724 base::Bind(&GKRMethod::GetLoginsList,
726 base::Unretained(&method), 725 base::Unretained(&method),
727 blacklisted_by_user, app_string_.c_str())); 726 blacklisted_by_user, app_string_.c_str()));
728 GnomeKeyringResult result = method.WaitResult(forms); 727 GnomeKeyringResult result = method.WaitResult(forms);
729 if (result == GNOME_KEYRING_RESULT_NO_MATCH) 728 if (result == GNOME_KEYRING_RESULT_NO_MATCH)
730 return true; 729 return true;
731 if (result != GNOME_KEYRING_RESULT_OK) { 730 if (result != GNOME_KEYRING_RESULT_OK) {
732 LOG(ERROR) << "Keyring find failed: " 731 LOG(ERROR) << "Keyring find failed: "
733 << gnome_keyring_result_to_message(result); 732 << gnome_keyring_result_to_message(result);
734 return false; 733 return false;
735 } 734 }
736 return true; 735 return true;
737 } 736 }
738 737
739 bool NativeBackendGnome::GetAllLogins( 738 bool NativeBackendGnome::GetAllLogins(ScopedVector<PasswordForm>* forms) {
740 ScopedVector<autofill::PasswordForm>* forms) {
741 GKRMethod method; 739 GKRMethod method;
742 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 740 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
743 base::Bind(&GKRMethod::GetAllLogins, 741 base::Bind(&GKRMethod::GetAllLogins,
744 base::Unretained(&method), 742 base::Unretained(&method),
745 app_string_.c_str())); 743 app_string_.c_str()));
746 GnomeKeyringResult result = method.WaitResult(forms); 744 GnomeKeyringResult result = method.WaitResult(forms);
747 if (result == GNOME_KEYRING_RESULT_NO_MATCH) 745 if (result == GNOME_KEYRING_RESULT_NO_MATCH)
748 return true; 746 return true;
749 if (result != GNOME_KEYRING_RESULT_OK) { 747 if (result != GNOME_KEYRING_RESULT_OK) {
750 LOG(ERROR) << "Keyring find failed: " 748 LOG(ERROR) << "Keyring find failed: "
751 << gnome_keyring_result_to_message(result); 749 << gnome_keyring_result_to_message(result);
752 return false; 750 return false;
753 } 751 }
754 return true; 752 return true;
755 } 753 }
756 754
757 bool NativeBackendGnome::GetLoginsBetween( 755 bool NativeBackendGnome::GetLoginsBetween(base::Time get_begin,
758 base::Time get_begin, 756 base::Time get_end,
759 base::Time get_end, 757 TimestampToCompare date_to_compare,
760 TimestampToCompare date_to_compare, 758 ScopedVector<PasswordForm>* forms) {
761 ScopedVector<autofill::PasswordForm>* forms) {
762 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 759 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
760 forms->clear();
763 // We could walk the list and add items as we find them, but it is much 761 // We could walk the list and add items as we find them, but it is much
764 // easier to build the list and then filter the results. 762 // easier to build the list and then filter the results.
765 ScopedVector<autofill::PasswordForm> all_forms; 763 ScopedVector<PasswordForm> all_forms;
766 if (!GetAllLogins(&all_forms)) 764 if (!GetAllLogins(&all_forms))
767 return false; 765 return false;
768 766
769 base::Time autofill::PasswordForm::*date_member = 767 base::Time PasswordForm::*date_member = date_to_compare == CREATION_TIMESTAMP
770 date_to_compare == CREATION_TIMESTAMP 768 ? &PasswordForm::date_created
771 ? &autofill::PasswordForm::date_created 769 : &PasswordForm::date_synced;
772 : &autofill::PasswordForm::date_synced;
773 for (auto& saved_form : all_forms) { 770 for (auto& saved_form : all_forms) {
774 if (get_begin <= saved_form->*date_member && 771 if (get_begin <= saved_form->*date_member &&
775 (get_end.is_null() || saved_form->*date_member < get_end)) { 772 (get_end.is_null() || saved_form->*date_member < get_end)) {
776 forms->push_back(saved_form); 773 forms->push_back(saved_form);
777 saved_form = nullptr; 774 saved_form = nullptr;
778 } 775 }
779 } 776 }
780 777
781 return true; 778 return true;
782 } 779 }
783 780
784 bool NativeBackendGnome::RemoveLoginsBetween( 781 bool NativeBackendGnome::RemoveLoginsBetween(
785 base::Time get_begin, 782 base::Time get_begin,
786 base::Time get_end, 783 base::Time get_end,
787 TimestampToCompare date_to_compare, 784 TimestampToCompare date_to_compare,
788 password_manager::PasswordStoreChangeList* changes) { 785 password_manager::PasswordStoreChangeList* changes) {
789 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 786 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
790 DCHECK(changes); 787 DCHECK(changes);
791 changes->clear(); 788 changes->clear();
792 // We could walk the list and delete items as we find them, but it is much 789 // We could walk the list and delete items as we find them, but it is much
793 // easier to build the list and use RemoveLogin() to delete them. 790 // easier to build the list and use RemoveLogin() to delete them.
794 ScopedVector<autofill::PasswordForm> forms; 791 ScopedVector<PasswordForm> forms;
795 if (!GetLoginsBetween(get_begin, get_end, date_to_compare, &forms)) 792 if (!GetLoginsBetween(get_begin, get_end, date_to_compare, &forms))
796 return false; 793 return false;
797 794
798 bool ok = true; 795 bool ok = true;
799 for (size_t i = 0; i < forms.size(); ++i) { 796 for (size_t i = 0; i < forms.size(); ++i) {
800 if (RemoveLogin(*forms[i])) { 797 if (RemoveLogin(*forms[i])) {
801 changes->push_back(password_manager::PasswordStoreChange( 798 changes->push_back(password_manager::PasswordStoreChange(
802 password_manager::PasswordStoreChange::REMOVE, *forms[i])); 799 password_manager::PasswordStoreChange::REMOVE, *forms[i]));
803 } else { 800 } else {
804 ok = false; 801 ok = false;
805 } 802 }
806 } 803 }
807 return ok; 804 return ok;
808 } 805 }
809
810 std::string NativeBackendGnome::GetProfileSpecificAppString() const {
811 // Originally, the application string was always just "chrome" and used only
812 // so that we had *something* to search for since GNOME Keyring won't search
813 // for nothing. Now we use it to distinguish passwords for different profiles.
814 return base::StringPrintf("%s-%d", kGnomeKeyringAppString, profile_id_);
815 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698