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