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 |