| 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/safe_browsing/database_manager.h" | 5 #include "chrome/browser/safe_browsing/database_manager.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/bind_helpers.h" | 10 #include "base/bind_helpers.h" |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 65 const std::vector<SBThreatType>& expected_threats) { | 65 const std::vector<SBThreatType>& expected_threats) { |
| 66 return expected_threats.end() != std::find(expected_threats.begin(), | 66 return expected_threats.end() != std::find(expected_threats.begin(), |
| 67 expected_threats.end(), | 67 expected_threats.end(), |
| 68 threat_type); | 68 threat_type); |
| 69 } | 69 } |
| 70 | 70 |
| 71 // Return the list id from the first result in |full_hashes| which matches | 71 // Return the list id from the first result in |full_hashes| which matches |
| 72 // |hash|, or INVALID if none match. | 72 // |hash|, or INVALID if none match. |
| 73 safe_browsing_util::ListType GetHashThreatListType( | 73 safe_browsing_util::ListType GetHashThreatListType( |
| 74 const SBFullHash& hash, | 74 const SBFullHash& hash, |
| 75 const std::vector<SBFullHashResult>& full_hashes) { | 75 const std::vector<SBFullHashResult>& full_hashes, |
| 76 size_t* index) { |
| 76 for (size_t i = 0; i < full_hashes.size(); ++i) { | 77 for (size_t i = 0; i < full_hashes.size(); ++i) { |
| 77 if (SBFullHashEqual(hash, full_hashes[i].hash)) | 78 if (SBFullHashEqual(hash, full_hashes[i].hash)) { |
| 79 if (index) |
| 80 *index = i; |
| 78 return static_cast<safe_browsing_util::ListType>(full_hashes[i].list_id); | 81 return static_cast<safe_browsing_util::ListType>(full_hashes[i].list_id); |
| 82 } |
| 79 } | 83 } |
| 80 return safe_browsing_util::INVALID; | 84 return safe_browsing_util::INVALID; |
| 81 } | 85 } |
| 82 | 86 |
| 83 // Given a URL, compare all the possible host + path full hashes to the set of | 87 // Given a URL, compare all the possible host + path full hashes to the set of |
| 84 // provided full hashes. Returns the list id of the a matching result from | 88 // provided full hashes. Returns the list id of the a matching result from |
| 85 // |full_hashes|, or INVALID if none match. | 89 // |full_hashes|, or INVALID if none match. |
| 86 safe_browsing_util::ListType GetUrlThreatListType( | 90 safe_browsing_util::ListType GetUrlThreatListType( |
| 87 const GURL& url, | 91 const GURL& url, |
| 88 const std::vector<SBFullHashResult>& full_hashes) { | 92 const std::vector<SBFullHashResult>& full_hashes, |
| 93 size_t* index) { |
| 89 if (full_hashes.empty()) | 94 if (full_hashes.empty()) |
| 90 return safe_browsing_util::INVALID; | 95 return safe_browsing_util::INVALID; |
| 91 | 96 |
| 92 std::vector<std::string> patterns; | 97 std::vector<std::string> patterns; |
| 93 safe_browsing_util::GeneratePatternsToCheck(url, &patterns); | 98 safe_browsing_util::GeneratePatternsToCheck(url, &patterns); |
| 94 | 99 |
| 95 for (size_t i = 0; i < patterns.size(); ++i) { | 100 for (size_t i = 0; i < patterns.size(); ++i) { |
| 96 safe_browsing_util::ListType threat = | 101 safe_browsing_util::ListType threat = GetHashThreatListType( |
| 97 GetHashThreatListType(SBFullHashForString(patterns[i]), full_hashes); | 102 SBFullHashForString(patterns[i]), full_hashes, index); |
| 98 if (threat != safe_browsing_util::INVALID) | 103 if (threat != safe_browsing_util::INVALID) |
| 99 return threat; | 104 return threat; |
| 100 } | 105 } |
| 101 return safe_browsing_util::INVALID; | 106 return safe_browsing_util::INVALID; |
| 102 } | 107 } |
| 103 | 108 |
| 104 SBThreatType GetThreatTypeFromListType(safe_browsing_util::ListType list_type) { | 109 SBThreatType GetThreatTypeFromListType(safe_browsing_util::ListType list_type) { |
| 105 switch (list_type) { | 110 switch (list_type) { |
| 106 case safe_browsing_util::PHISH: | 111 case safe_browsing_util::PHISH: |
| 107 return SB_THREAT_TYPE_URL_PHISHING; | 112 return SB_THREAT_TYPE_URL_PHISHING; |
| 108 case safe_browsing_util::MALWARE: | 113 case safe_browsing_util::MALWARE: |
| 109 return SB_THREAT_TYPE_URL_MALWARE; | 114 return SB_THREAT_TYPE_URL_MALWARE; |
| 110 case safe_browsing_util::BINURL: | 115 case safe_browsing_util::BINURL: |
| 111 return SB_THREAT_TYPE_BINARY_MALWARE_URL; | 116 return SB_THREAT_TYPE_BINARY_MALWARE_URL; |
| 112 case safe_browsing_util::EXTENSIONBLACKLIST: | 117 case safe_browsing_util::EXTENSIONBLACKLIST: |
| 113 return SB_THREAT_TYPE_EXTENSION; | 118 return SB_THREAT_TYPE_EXTENSION; |
| 114 default: | 119 default: |
| 115 DVLOG(1) << "Unknown safe browsing list id " << list_type; | 120 DVLOG(1) << "Unknown safe browsing list id " << list_type; |
| 116 return SB_THREAT_TYPE_SAFE; | 121 return SB_THREAT_TYPE_SAFE; |
| 117 } | 122 } |
| 118 } | 123 } |
| 119 | 124 |
| 120 } // namespace | 125 } // namespace |
| 121 | 126 |
| 122 // static | 127 // static |
| 123 SBThreatType SafeBrowsingDatabaseManager::GetHashThreatType( | 128 SBThreatType SafeBrowsingDatabaseManager::GetHashThreatType( |
| 124 const SBFullHash& hash, | 129 const SBFullHash& hash, |
| 125 const std::vector<SBFullHashResult>& full_hashes) { | 130 const std::vector<SBFullHashResult>& full_hashes) { |
| 126 return GetThreatTypeFromListType(GetHashThreatListType(hash, full_hashes)); | 131 return GetThreatTypeFromListType( |
| 132 GetHashThreatListType(hash, full_hashes, NULL)); |
| 127 } | 133 } |
| 128 | 134 |
| 129 // static | 135 // static |
| 130 SBThreatType SafeBrowsingDatabaseManager::GetUrlThreatType( | 136 SBThreatType SafeBrowsingDatabaseManager::GetUrlThreatType( |
| 131 const GURL& url, | 137 const GURL& url, |
| 132 const std::vector<SBFullHashResult>& full_hashes) { | 138 const std::vector<SBFullHashResult>& full_hashes, |
| 133 return GetThreatTypeFromListType(GetUrlThreatListType(url, full_hashes)); | 139 size_t* index) { |
| 140 return GetThreatTypeFromListType( |
| 141 GetUrlThreatListType(url, full_hashes, index)); |
| 134 } | 142 } |
| 135 | 143 |
| 136 SafeBrowsingDatabaseManager::SafeBrowsingCheck::SafeBrowsingCheck( | 144 SafeBrowsingDatabaseManager::SafeBrowsingCheck::SafeBrowsingCheck( |
| 137 const std::vector<GURL>& urls, | 145 const std::vector<GURL>& urls, |
| 138 const std::vector<SBFullHash>& full_hashes, | 146 const std::vector<SBFullHash>& full_hashes, |
| 139 Client* client, | 147 Client* client, |
| 140 safe_browsing_util::ListType check_type, | 148 safe_browsing_util::ListType check_type, |
| 141 const std::vector<SBThreatType>& expected_threats) | 149 const std::vector<SBThreatType>& expected_threats) |
| 142 : urls(urls), | 150 : urls(urls), |
| 143 url_results(urls.size(), SB_THREAT_TYPE_SAFE), | 151 url_results(urls.size(), SB_THREAT_TYPE_SAFE), |
| 152 url_metadata(urls.size()), |
| 144 full_hashes(full_hashes), | 153 full_hashes(full_hashes), |
| 145 full_hash_results(full_hashes.size(), SB_THREAT_TYPE_SAFE), | 154 full_hash_results(full_hashes.size(), SB_THREAT_TYPE_SAFE), |
| 146 client(client), | 155 client(client), |
| 147 need_get_hash(false), | 156 need_get_hash(false), |
| 148 check_type(check_type), | 157 check_type(check_type), |
| 149 expected_threats(expected_threats) { | 158 expected_threats(expected_threats) { |
| 150 DCHECK_EQ(urls.empty(), !full_hashes.empty()) | 159 DCHECK_EQ(urls.empty(), !full_hashes.empty()) |
| 151 << "Exactly one of urls and full_hashes must be set"; | 160 << "Exactly one of urls and full_hashes must be set"; |
| 152 } | 161 } |
| 153 | 162 |
| 154 SafeBrowsingDatabaseManager::SafeBrowsingCheck::~SafeBrowsingCheck() {} | 163 SafeBrowsingDatabaseManager::SafeBrowsingCheck::~SafeBrowsingCheck() {} |
| 155 | 164 |
| 156 void SafeBrowsingDatabaseManager::Client::OnSafeBrowsingResult( | 165 void SafeBrowsingDatabaseManager::Client::OnSafeBrowsingResult( |
| 157 const SafeBrowsingCheck& check) { | 166 const SafeBrowsingCheck& check) { |
| 158 DCHECK_EQ(check.urls.size(), check.url_results.size()); | 167 DCHECK_EQ(check.urls.size(), check.url_results.size()); |
| 159 DCHECK_EQ(check.full_hashes.size(), check.full_hash_results.size()); | 168 DCHECK_EQ(check.full_hashes.size(), check.full_hash_results.size()); |
| 160 if (!check.urls.empty()) { | 169 if (!check.urls.empty()) { |
| 161 DCHECK(check.full_hashes.empty()); | 170 DCHECK(check.full_hashes.empty()); |
| 162 switch (check.check_type) { | 171 switch (check.check_type) { |
| 163 case safe_browsing_util::MALWARE: | 172 case safe_browsing_util::MALWARE: |
| 164 case safe_browsing_util::PHISH: | 173 case safe_browsing_util::PHISH: |
| 165 DCHECK_EQ(1u, check.urls.size()); | 174 DCHECK_EQ(1u, check.urls.size()); |
| 166 OnCheckBrowseUrlResult(check.urls[0], check.url_results[0]); | 175 OnCheckBrowseUrlResult( |
| 176 check.urls[0], check.url_results[0], check.url_metadata[0]); |
| 167 break; | 177 break; |
| 168 case safe_browsing_util::BINURL: | 178 case safe_browsing_util::BINURL: |
| 169 DCHECK_EQ(check.urls.size(), check.url_results.size()); | 179 DCHECK_EQ(check.urls.size(), check.url_results.size()); |
| 170 OnCheckDownloadUrlResult( | 180 OnCheckDownloadUrlResult( |
| 171 check.urls, | 181 check.urls, |
| 172 *std::max_element(check.url_results.begin(), | 182 *std::max_element(check.url_results.begin(), |
| 173 check.url_results.end())); | 183 check.url_results.end())); |
| 174 break; | 184 break; |
| 175 default: | 185 default: |
| 176 NOTREACHED(); | 186 NOTREACHED(); |
| (...skipping 758 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 935 // here concerns me. It is likely that SAFE is an expected outcome, which | 945 // here concerns me. It is likely that SAFE is an expected outcome, which |
| 936 // means all of those loops run to completion. Refactoring this to generate a | 946 // means all of those loops run to completion. Refactoring this to generate a |
| 937 // set of sorted items to compare in sequence would probably improve things. | 947 // set of sorted items to compare in sequence would probably improve things. |
| 938 // | 948 // |
| 939 // Additionally, the set of patterns generated from the urls is very similar | 949 // Additionally, the set of patterns generated from the urls is very similar |
| 940 // to the patterns generated in ContainsBrowseUrl() and other database checks, | 950 // to the patterns generated in ContainsBrowseUrl() and other database checks, |
| 941 // which are called from this code. Refactoring that across the checks could | 951 // which are called from this code. Refactoring that across the checks could |
| 942 // interact well with batching the checks here. | 952 // interact well with batching the checks here. |
| 943 | 953 |
| 944 for (size_t i = 0; i < check->urls.size(); ++i) { | 954 for (size_t i = 0; i < check->urls.size(); ++i) { |
| 945 SBThreatType threat = GetUrlThreatType(check->urls[i], full_hashes); | 955 size_t threat_index; |
| 956 SBThreatType threat = |
| 957 GetUrlThreatType(check->urls[i], full_hashes, &threat_index); |
| 946 if (threat != SB_THREAT_TYPE_SAFE && | 958 if (threat != SB_THREAT_TYPE_SAFE && |
| 947 IsExpectedThreat(threat, check->expected_threats)) { | 959 IsExpectedThreat(threat, check->expected_threats)) { |
| 948 check->url_results[i] = threat; | 960 check->url_results[i] = threat; |
| 961 check->url_metadata[i] = full_hashes[threat_index].metadata; |
| 949 is_threat = true; | 962 is_threat = true; |
| 950 } | 963 } |
| 951 } | 964 } |
| 952 | 965 |
| 953 for (size_t i = 0; i < check->full_hashes.size(); ++i) { | 966 for (size_t i = 0; i < check->full_hashes.size(); ++i) { |
| 954 SBThreatType threat = GetHashThreatType(check->full_hashes[i], full_hashes); | 967 SBThreatType threat = GetHashThreatType(check->full_hashes[i], full_hashes); |
| 955 if (threat != SB_THREAT_TYPE_SAFE && | 968 if (threat != SB_THREAT_TYPE_SAFE && |
| 956 IsExpectedThreat(threat, check->expected_threats)) { | 969 IsExpectedThreat(threat, check->expected_threats)) { |
| 957 check->full_hash_results[i] = threat; | 970 check->full_hash_results[i] = threat; |
| 958 is_threat = true; | 971 is_threat = true; |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1061 new base::WeakPtrFactory<SafeBrowsingDatabaseManager>(this)); | 1074 new base::WeakPtrFactory<SafeBrowsingDatabaseManager>(this)); |
| 1062 checks_.insert(check); | 1075 checks_.insert(check); |
| 1063 | 1076 |
| 1064 safe_browsing_thread_->message_loop()->PostTask(FROM_HERE, task); | 1077 safe_browsing_thread_->message_loop()->PostTask(FROM_HERE, task); |
| 1065 | 1078 |
| 1066 base::MessageLoop::current()->PostDelayedTask(FROM_HERE, | 1079 base::MessageLoop::current()->PostDelayedTask(FROM_HERE, |
| 1067 base::Bind(&SafeBrowsingDatabaseManager::TimeoutCallback, | 1080 base::Bind(&SafeBrowsingDatabaseManager::TimeoutCallback, |
| 1068 check->timeout_factory_->GetWeakPtr(), check), | 1081 check->timeout_factory_->GetWeakPtr(), check), |
| 1069 check_timeout_); | 1082 check_timeout_); |
| 1070 } | 1083 } |
| OLD | NEW |