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 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 } | |
OLD | NEW |