| OLD | NEW |
| (Empty) | |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "components/password_manager/core/browser/hsts_deleter.h" |
| 6 |
| 7 #include <algorithm> |
| 8 #include <iterator> |
| 9 #include <tuple> |
| 10 |
| 11 #include "base/logging.h" |
| 12 #include "components/autofill/core/common/password_form.h" |
| 13 #include "components/password_manager/core/browser/password_manager_client.h" |
| 14 #include "components/password_manager/core/browser/password_store.h" |
| 15 #include "components/password_manager/core/browser/statistics_table.h" |
| 16 #include "url/url_constants.h" |
| 17 |
| 18 using autofill::PasswordForm; |
| 19 |
| 20 namespace password_manager { |
| 21 |
| 22 HstsDeleter::HstsDeleter(const PasswordManagerClient* client, |
| 23 PasswordStore* password_store) |
| 24 : client_(client), password_store_(password_store) { |
| 25 DCHECK(client_); |
| 26 DCHECK(password_store_); |
| 27 } |
| 28 |
| 29 void HstsDeleter::OnGetPasswordStoreResults( |
| 30 std::vector<std::unique_ptr<PasswordForm>> results) { |
| 31 // Non HTTP or HTTPS credentials are ignored. |
| 32 results.erase(std::remove_if(std::begin(results), std::end(results), |
| 33 [](const std::unique_ptr<PasswordForm>& form) { |
| 34 return !form->origin.SchemeIsHTTPOrHTTPS(); |
| 35 }), |
| 36 std::end(results)); |
| 37 |
| 38 // Move HTTPS forms to the end of the container, |
| 39 auto begin_https = |
| 40 std::partition(std::begin(results), std::end(results), |
| 41 [](const std::unique_ptr<PasswordForm>& form) { |
| 42 return form->origin.SchemeIs(url::kHttpScheme); |
| 43 }); |
| 44 |
| 45 // Move blacklisted HTTP forms to the end of the HTTP form segment. |
| 46 auto begin_blacklisted_http = |
| 47 std::partition(std::begin(results), begin_https, |
| 48 [](const std::unique_ptr<PasswordForm>& form) { |
| 49 return !form->blacklisted_by_user; |
| 50 }); |
| 51 |
| 52 // Remove blacklisted HTTP forms from the password store when HSTS is active |
| 53 // for the given host. |
| 54 std::for_each(begin_blacklisted_http, begin_https, |
| 55 [this](const std::unique_ptr<PasswordForm>& blacklisted_form) { |
| 56 if (client_->IsHSTSActiveForOrigin(blacklisted_form->origin)) |
| 57 password_store_->RemoveLogin(*blacklisted_form); |
| 58 }); |
| 59 |
| 60 // Return early if there are no non-blacklisted HTTP forms. |
| 61 if (std::begin(results) == begin_blacklisted_http) |
| 62 return; |
| 63 |
| 64 // Ignore non HSTS forms. We are explicitly not calling |results.erase| so |
| 65 // that we don't invalidate |begin_https| in case there are no HSTS forms. |
| 66 auto end_hsts = |
| 67 std::remove_if(begin_https, std::end(results), |
| 68 [this](const std::unique_ptr<PasswordForm>& form) { |
| 69 return !client_->IsHSTSActiveForOrigin(form->origin); |
| 70 }); |
| 71 |
| 72 // Sort HSTS forms according to custom comparison function. Consider two forms |
| 73 // equivalent if they have the same host, as well as the same username and |
| 74 // password. |
| 75 const auto form_cmp = [](const std::unique_ptr<PasswordForm>& lhs, |
| 76 const std::unique_ptr<PasswordForm>& rhs) { |
| 77 return std::forward_as_tuple(lhs->origin.host_piece(), lhs->username_value, |
| 78 lhs->password_value) < |
| 79 std::forward_as_tuple(rhs->origin.host_piece(), rhs->username_value, |
| 80 rhs->password_value); |
| 81 }; |
| 82 |
| 83 std::sort(begin_https, end_hsts, form_cmp); |
| 84 |
| 85 // Iterate through HTTP forms and remove them from the password store if there |
| 86 // exists an equivalent HSTS form. |
| 87 std::for_each(std::begin(results), begin_blacklisted_http, |
| 88 [&, this](const std::unique_ptr<PasswordForm>& form) { |
| 89 if (std::binary_search(begin_https, end_hsts, form, form_cmp)) |
| 90 password_store_->RemoveLogin(*form); |
| 91 }); |
| 92 } |
| 93 |
| 94 void HstsDeleter::OnGetSiteStatistics(std::vector<InteractionsStats> stats) { |
| 95 for (const auto& stat : stats) { |
| 96 if (stat.origin_domain.SchemeIs(url::kHttpScheme) && |
| 97 client_->IsHSTSActiveForOrigin(stat.origin_domain)) { |
| 98 password_store_->RemoveSiteStats(stat.origin_domain); |
| 99 } |
| 100 } |
| 101 } |
| 102 |
| 103 } // namespace password_manager |
| OLD | NEW |