| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "components/password_manager/core/browser/password_store.h" | 5 #include "components/password_manager/core/browser/password_store.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/debug/dump_without_crashing.h" | 10 #include "base/debug/dump_without_crashing.h" |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 147 base::Bind(&PasswordStore::RemoveStatisticsCreatedBetweenInternal, this, | 147 base::Bind(&PasswordStore::RemoveStatisticsCreatedBetweenInternal, this, |
| 148 delete_begin, delete_end, completion)); | 148 delete_begin, delete_end, completion)); |
| 149 } | 149 } |
| 150 | 150 |
| 151 void PasswordStore::TrimAffiliationCache() { | 151 void PasswordStore::TrimAffiliationCache() { |
| 152 if (affiliated_match_helper_) | 152 if (affiliated_match_helper_) |
| 153 affiliated_match_helper_->TrimAffiliationCache(); | 153 affiliated_match_helper_->TrimAffiliationCache(); |
| 154 } | 154 } |
| 155 | 155 |
| 156 void PasswordStore::GetLogins(const PasswordForm& form, | 156 void PasswordStore::GetLogins(const PasswordForm& form, |
| 157 AuthorizationPromptPolicy prompt_policy, | |
| 158 PasswordStoreConsumer* consumer) { | 157 PasswordStoreConsumer* consumer) { |
| 159 // Per http://crbug.com/121738, we deliberately ignore saved logins for | 158 // Per http://crbug.com/121738, we deliberately ignore saved logins for |
| 160 // http*://www.google.com/ that were stored prior to 2012. (Google now uses | 159 // http*://www.google.com/ that were stored prior to 2012. (Google now uses |
| 161 // https://accounts.google.com/ for all login forms, so these should be | 160 // https://accounts.google.com/ for all login forms, so these should be |
| 162 // unused.) We don't delete them just yet, and they'll still be visible in the | 161 // unused.) We don't delete them just yet, and they'll still be visible in the |
| 163 // password manager, but we won't use them to autofill any forms. This is a | 162 // password manager, but we won't use them to autofill any forms. This is a |
| 164 // security feature to help minimize damage that can be done by XSS attacks. | 163 // security feature to help minimize damage that can be done by XSS attacks. |
| 165 // TODO(mdm): actually delete them at some point, say M24 or so. | 164 // TODO(mdm): actually delete them at some point, say M24 or so. |
| 166 base::Time ignore_logins_cutoff; // the null time | 165 base::Time ignore_logins_cutoff; // the null time |
| 167 if (form.scheme == PasswordForm::SCHEME_HTML && | 166 if (form.scheme == PasswordForm::SCHEME_HTML && |
| 168 (form.signon_realm == "http://www.google.com" || | 167 (form.signon_realm == "http://www.google.com" || |
| 169 form.signon_realm == "http://www.google.com/" || | 168 form.signon_realm == "http://www.google.com/" || |
| 170 form.signon_realm == "https://www.google.com" || | 169 form.signon_realm == "https://www.google.com" || |
| 171 form.signon_realm == "https://www.google.com/")) { | 170 form.signon_realm == "https://www.google.com/")) { |
| 172 static const base::Time::Exploded exploded_cutoff = | 171 static const base::Time::Exploded exploded_cutoff = |
| 173 { 2012, 1, 0, 1, 0, 0, 0, 0 }; // 00:00 Jan 1 2012 | 172 { 2012, 1, 0, 1, 0, 0, 0, 0 }; // 00:00 Jan 1 2012 |
| 174 ignore_logins_cutoff = base::Time::FromUTCExploded(exploded_cutoff); | 173 ignore_logins_cutoff = base::Time::FromUTCExploded(exploded_cutoff); |
| 175 } | 174 } |
| 176 scoped_ptr<GetLoginsRequest> request(new GetLoginsRequest(consumer)); | 175 scoped_ptr<GetLoginsRequest> request(new GetLoginsRequest(consumer)); |
| 177 request->set_ignore_logins_cutoff(ignore_logins_cutoff); | 176 request->set_ignore_logins_cutoff(ignore_logins_cutoff); |
| 178 | 177 |
| 179 if (affiliated_match_helper_) { | 178 if (affiliated_match_helper_) { |
| 180 affiliated_match_helper_->GetAffiliatedAndroidRealms( | 179 affiliated_match_helper_->GetAffiliatedAndroidRealms( |
| 181 form, base::Bind(&PasswordStore::ScheduleGetLoginsWithAffiliations, | 180 form, base::Bind(&PasswordStore::ScheduleGetLoginsWithAffiliations, |
| 182 this, form, prompt_policy, base::Passed(&request))); | 181 this, form, base::Passed(&request))); |
| 183 } else { | 182 } else { |
| 184 ScheduleTask(base::Bind(&PasswordStore::GetLoginsImpl, this, form, | 183 ScheduleTask(base::Bind(&PasswordStore::GetLoginsImpl, this, form, |
| 185 prompt_policy, base::Passed(&request))); | 184 base::Passed(&request))); |
| 186 } | 185 } |
| 187 } | 186 } |
| 188 | 187 |
| 189 void PasswordStore::GetAutofillableLogins(PasswordStoreConsumer* consumer) { | 188 void PasswordStore::GetAutofillableLogins(PasswordStoreConsumer* consumer) { |
| 190 Schedule(&PasswordStore::GetAutofillableLoginsImpl, consumer); | 189 Schedule(&PasswordStore::GetAutofillableLoginsImpl, consumer); |
| 191 } | 190 } |
| 192 | 191 |
| 193 void PasswordStore::GetBlacklistLogins(PasswordStoreConsumer* consumer) { | 192 void PasswordStore::GetBlacklistLogins(PasswordStoreConsumer* consumer) { |
| 194 Schedule(&PasswordStore::GetBlacklistLoginsImpl, consumer); | 193 Schedule(&PasswordStore::GetBlacklistLoginsImpl, consumer); |
| 195 } | 194 } |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 256 PasswordStore::~PasswordStore() { | 255 PasswordStore::~PasswordStore() { |
| 257 DCHECK(shutdown_called_); | 256 DCHECK(shutdown_called_); |
| 258 } | 257 } |
| 259 | 258 |
| 260 scoped_refptr<base::SingleThreadTaskRunner> | 259 scoped_refptr<base::SingleThreadTaskRunner> |
| 261 PasswordStore::GetBackgroundTaskRunner() { | 260 PasswordStore::GetBackgroundTaskRunner() { |
| 262 return db_thread_runner_; | 261 return db_thread_runner_; |
| 263 } | 262 } |
| 264 | 263 |
| 265 void PasswordStore::GetLoginsImpl(const autofill::PasswordForm& form, | 264 void PasswordStore::GetLoginsImpl(const autofill::PasswordForm& form, |
| 266 AuthorizationPromptPolicy prompt_policy, | |
| 267 scoped_ptr<GetLoginsRequest> request) { | 265 scoped_ptr<GetLoginsRequest> request) { |
| 268 request->NotifyConsumerWithResults(FillMatchingLogins(form, prompt_policy)); | 266 request->NotifyConsumerWithResults(FillMatchingLogins(form)); |
| 269 } | 267 } |
| 270 | 268 |
| 271 | 269 |
| 272 void PasswordStore::LogStatsForBulkDeletion(int num_deletions) { | 270 void PasswordStore::LogStatsForBulkDeletion(int num_deletions) { |
| 273 UMA_HISTOGRAM_COUNTS("PasswordManager.NumPasswordsDeletedByBulkDelete", | 271 UMA_HISTOGRAM_COUNTS("PasswordManager.NumPasswordsDeletedByBulkDelete", |
| 274 num_deletions); | 272 num_deletions); |
| 275 } | 273 } |
| 276 | 274 |
| 277 void PasswordStore::LogStatsForBulkDeletionDuringRollback(int num_deletions) { | 275 void PasswordStore::LogStatsForBulkDeletionDuringRollback(int num_deletions) { |
| 278 UMA_HISTOGRAM_COUNTS("PasswordManager.NumPasswordsDeletedDuringRollback", | 276 UMA_HISTOGRAM_COUNTS("PasswordManager.NumPasswordsDeletedDuringRollback", |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 412 request->NotifyConsumerWithResults(std::move(obtained_forms)); | 410 request->NotifyConsumerWithResults(std::move(obtained_forms)); |
| 413 } | 411 } |
| 414 | 412 |
| 415 void PasswordStore::NotifySiteStats(const GURL& origin_domain, | 413 void PasswordStore::NotifySiteStats(const GURL& origin_domain, |
| 416 scoped_ptr<GetLoginsRequest> request) { | 414 scoped_ptr<GetLoginsRequest> request) { |
| 417 request->NotifyWithSiteStatistics(GetSiteStatsImpl(origin_domain)); | 415 request->NotifyWithSiteStatistics(GetSiteStatsImpl(origin_domain)); |
| 418 } | 416 } |
| 419 | 417 |
| 420 void PasswordStore::GetLoginsWithAffiliationsImpl( | 418 void PasswordStore::GetLoginsWithAffiliationsImpl( |
| 421 const PasswordForm& form, | 419 const PasswordForm& form, |
| 422 AuthorizationPromptPolicy prompt_policy, | |
| 423 scoped_ptr<GetLoginsRequest> request, | 420 scoped_ptr<GetLoginsRequest> request, |
| 424 const std::vector<std::string>& additional_android_realms) { | 421 const std::vector<std::string>& additional_android_realms) { |
| 425 DCHECK(GetBackgroundTaskRunner()->BelongsToCurrentThread()); | 422 DCHECK(GetBackgroundTaskRunner()->BelongsToCurrentThread()); |
| 426 ScopedVector<PasswordForm> results(FillMatchingLogins(form, prompt_policy)); | 423 ScopedVector<PasswordForm> results(FillMatchingLogins(form)); |
| 427 for (const std::string& realm : additional_android_realms) { | 424 for (const std::string& realm : additional_android_realms) { |
| 428 PasswordForm android_form; | 425 PasswordForm android_form; |
| 429 android_form.scheme = PasswordForm::SCHEME_HTML; | 426 android_form.scheme = PasswordForm::SCHEME_HTML; |
| 430 android_form.signon_realm = realm; | 427 android_form.signon_realm = realm; |
| 431 ScopedVector<PasswordForm> more_results( | 428 ScopedVector<PasswordForm> more_results(FillMatchingLogins(android_form)); |
| 432 FillMatchingLogins(android_form, DISALLOW_PROMPT)); | |
| 433 for (PasswordForm* form : more_results) | 429 for (PasswordForm* form : more_results) |
| 434 form->is_affiliation_based_match = true; | 430 form->is_affiliation_based_match = true; |
| 435 ScopedVector<PasswordForm>::iterator it_first_federated = std::partition( | 431 ScopedVector<PasswordForm>::iterator it_first_federated = std::partition( |
| 436 more_results.begin(), more_results.end(), | 432 more_results.begin(), more_results.end(), |
| 437 [](PasswordForm* form) { return form->federation_url.is_empty(); }); | 433 [](PasswordForm* form) { return form->federation_url.is_empty(); }); |
| 438 more_results.erase(it_first_federated, more_results.end()); | 434 more_results.erase(it_first_federated, more_results.end()); |
| 439 password_manager_util::TrimUsernameOnlyCredentials(&more_results); | 435 password_manager_util::TrimUsernameOnlyCredentials(&more_results); |
| 440 results.insert(results.end(), more_results.begin(), more_results.end()); | 436 results.insert(results.end(), more_results.begin(), more_results.end()); |
| 441 more_results.weak_clear(); | 437 more_results.weak_clear(); |
| 442 } | 438 } |
| 443 request->NotifyConsumerWithResults(std::move(results)); | 439 request->NotifyConsumerWithResults(std::move(results)); |
| 444 } | 440 } |
| 445 | 441 |
| 446 void PasswordStore::ScheduleGetLoginsWithAffiliations( | 442 void PasswordStore::ScheduleGetLoginsWithAffiliations( |
| 447 const PasswordForm& form, | 443 const PasswordForm& form, |
| 448 AuthorizationPromptPolicy prompt_policy, | |
| 449 scoped_ptr<GetLoginsRequest> request, | 444 scoped_ptr<GetLoginsRequest> request, |
| 450 const std::vector<std::string>& additional_android_realms) { | 445 const std::vector<std::string>& additional_android_realms) { |
| 451 ScheduleTask(base::Bind(&PasswordStore::GetLoginsWithAffiliationsImpl, this, | 446 ScheduleTask(base::Bind(&PasswordStore::GetLoginsWithAffiliationsImpl, this, |
| 452 form, prompt_policy, base::Passed(&request), | 447 form, base::Passed(&request), |
| 453 additional_android_realms)); | 448 additional_android_realms)); |
| 454 } | 449 } |
| 455 | 450 |
| 456 scoped_ptr<PasswordForm> PasswordStore::GetLoginImpl( | 451 scoped_ptr<PasswordForm> PasswordStore::GetLoginImpl( |
| 457 const PasswordForm& primary_key) { | 452 const PasswordForm& primary_key) { |
| 458 DCHECK(GetBackgroundTaskRunner()->BelongsToCurrentThread()); | 453 DCHECK(GetBackgroundTaskRunner()->BelongsToCurrentThread()); |
| 459 ScopedVector<PasswordForm> candidates( | 454 ScopedVector<PasswordForm> candidates(FillMatchingLogins(primary_key)); |
| 460 FillMatchingLogins(primary_key, DISALLOW_PROMPT)); | |
| 461 for (PasswordForm*& candidate : candidates) { | 455 for (PasswordForm*& candidate : candidates) { |
| 462 if (ArePasswordFormUniqueKeyEqual(*candidate, primary_key) && | 456 if (ArePasswordFormUniqueKeyEqual(*candidate, primary_key) && |
| 463 !candidate->is_public_suffix_match) { | 457 !candidate->is_public_suffix_match) { |
| 464 scoped_ptr<PasswordForm> result(candidate); | 458 scoped_ptr<PasswordForm> result(candidate); |
| 465 candidate = nullptr; | 459 candidate = nullptr; |
| 466 return result; | 460 return result; |
| 467 } | 461 } |
| 468 } | 462 } |
| 469 return make_scoped_ptr<PasswordForm>(nullptr); | 463 return make_scoped_ptr<PasswordForm>(nullptr); |
| 470 } | 464 } |
| (...skipping 20 matching lines...) Expand all Loading... |
| 491 void PasswordStore::UpdateAffiliatedWebLoginsImpl( | 485 void PasswordStore::UpdateAffiliatedWebLoginsImpl( |
| 492 const PasswordForm& updated_android_form, | 486 const PasswordForm& updated_android_form, |
| 493 const std::vector<std::string>& affiliated_web_realms) { | 487 const std::vector<std::string>& affiliated_web_realms) { |
| 494 DCHECK(GetBackgroundTaskRunner()->BelongsToCurrentThread()); | 488 DCHECK(GetBackgroundTaskRunner()->BelongsToCurrentThread()); |
| 495 PasswordStoreChangeList all_changes; | 489 PasswordStoreChangeList all_changes; |
| 496 for (const std::string& affiliated_web_realm : affiliated_web_realms) { | 490 for (const std::string& affiliated_web_realm : affiliated_web_realms) { |
| 497 PasswordForm web_form_template; | 491 PasswordForm web_form_template; |
| 498 web_form_template.scheme = PasswordForm::SCHEME_HTML; | 492 web_form_template.scheme = PasswordForm::SCHEME_HTML; |
| 499 web_form_template.signon_realm = affiliated_web_realm; | 493 web_form_template.signon_realm = affiliated_web_realm; |
| 500 ScopedVector<PasswordForm> web_logins( | 494 ScopedVector<PasswordForm> web_logins( |
| 501 FillMatchingLogins(web_form_template, DISALLOW_PROMPT)); | 495 FillMatchingLogins(web_form_template)); |
| 502 for (PasswordForm* web_login : web_logins) { | 496 for (PasswordForm* web_login : web_logins) { |
| 503 // Do not update HTTP logins, logins saved under insecure conditions, and | 497 // Do not update HTTP logins, logins saved under insecure conditions, and |
| 504 // non-HTML login forms; PSL matches; logins with a different username; | 498 // non-HTML login forms; PSL matches; logins with a different username; |
| 505 // and logins with the same password (to avoid generating no-op updates). | 499 // and logins with the same password (to avoid generating no-op updates). |
| 506 if (!AffiliatedMatchHelper::IsValidWebCredential(*web_login) || | 500 if (!AffiliatedMatchHelper::IsValidWebCredential(*web_login) || |
| 507 web_login->is_public_suffix_match || | 501 web_login->is_public_suffix_match || |
| 508 web_login->username_value != updated_android_form.username_value || | 502 web_login->username_value != updated_android_form.username_value || |
| 509 web_login->password_value == updated_android_form.password_value) | 503 web_login->password_value == updated_android_form.password_value) |
| 510 continue; | 504 continue; |
| 511 | 505 |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 584 syncable_service_.reset(new PasswordSyncableService(this)); | 578 syncable_service_.reset(new PasswordSyncableService(this)); |
| 585 syncable_service_->InjectStartSyncFlare(flare); | 579 syncable_service_->InjectStartSyncFlare(flare); |
| 586 } | 580 } |
| 587 | 581 |
| 588 void PasswordStore::DestroySyncableService() { | 582 void PasswordStore::DestroySyncableService() { |
| 589 DCHECK(GetBackgroundTaskRunner()->BelongsToCurrentThread()); | 583 DCHECK(GetBackgroundTaskRunner()->BelongsToCurrentThread()); |
| 590 syncable_service_.reset(); | 584 syncable_service_.reset(); |
| 591 } | 585 } |
| 592 | 586 |
| 593 } // namespace password_manager | 587 } // namespace password_manager |
| OLD | NEW |