Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 // This file should not be build on Android but is currently getting built. | 5 // This file should not be build on Android but is currently getting built. |
| 6 // TODO(vakh): Fix that: http://crbug.com/621647 | 6 // TODO(vakh): Fix that: http://crbug.com/621647 |
| 7 | 7 |
| 8 #include "components/safe_browsing_db/v4_local_database_manager.h" | 8 #include "components/safe_browsing_db/v4_local_database_manager.h" |
| 9 | 9 |
| 10 #include <vector> | 10 #include <vector> |
| 11 | 11 |
| 12 #include "base/bind_helpers.h" | |
| 12 #include "base/callback.h" | 13 #include "base/callback.h" |
| 14 #include "base/memory/ptr_util.h" | |
| 13 #include "content/public/browser/browser_thread.h" | 15 #include "content/public/browser/browser_thread.h" |
| 14 | 16 |
| 15 using content::BrowserThread; | 17 using content::BrowserThread; |
| 16 | 18 |
| 17 namespace safe_browsing { | 19 namespace safe_browsing { |
| 18 | 20 |
| 19 namespace { | 21 namespace { |
| 20 | 22 |
| 23 const ThreatSeverity kLeastSeverity = | |
| 24 std::numeric_limits<ThreatSeverity>::max(); | |
| 25 | |
| 21 // TODO(vakh): Implement this to populate the vector appopriately. | 26 // TODO(vakh): Implement this to populate the vector appopriately. |
| 22 // Filed as http://crbug.com/608075 | 27 // Filed as http://crbug.com/608075 |
| 28 // Any stores added/removed to/from here likely need an update in | |
| 29 // GetSBThreatTypeForList | |
|
Nathan Parker
2016/09/20 17:51:09
Maybe you can enforce that with a compile-time ass
vakh (use Gerrit instead)
2016/09/20 18:21:16
I am using the GetChromeUrlApiId store in tests bu
| |
| 23 StoreIdAndFileNames GetStoreIdAndFileNames() { | 30 StoreIdAndFileNames GetStoreIdAndFileNames() { |
| 24 return StoreIdAndFileNames( | 31 return StoreIdAndFileNames( |
| 25 {StoreIdAndFileName(GetUrlMalwareId(), "UrlMalware.store"), | 32 {StoreIdAndFileName(GetUrlMalwareId(), "UrlMalware.store"), |
| 26 StoreIdAndFileName(GetUrlSocEngId(), "UrlSoceng.store")}); | 33 StoreIdAndFileName(GetUrlSocEngId(), "UrlSoceng.store")}); |
| 27 } | 34 } |
| 28 | 35 |
| 36 // Returns the SBThreatType corresponding to a given SafeBrowsing list. | |
| 37 SBThreatType GetSBThreatTypeForList(const UpdateListIdentifier& list_id) { | |
| 38 if (list_id == GetChromeUrlApiId()) { | |
|
Nathan Parker
2016/09/20 17:51:09
nit: When this list gets longer, you might want an
vakh (use Gerrit instead)
2016/09/20 18:21:17
Acknowledged.
Scott Hess - ex-Googler
2016/09/20 21:55:55
This kind of stuff in the old code feels like the
vakh (use Gerrit instead)
2016/09/21 17:43:40
You're right. I did not put it there because the S
| |
| 39 return SB_THREAT_TYPE_API_ABUSE; | |
| 40 } else if (list_id == GetUrlMalwareId()) { | |
| 41 return SB_THREAT_TYPE_URL_MALWARE; | |
| 42 } else if (list_id == GetUrlSocEngId()) { | |
| 43 return SB_THREAT_TYPE_URL_PHISHING; | |
| 44 } else { | |
| 45 NOTREACHED() << "Unknown list encountered in GetSBThreatTypeForList"; | |
| 46 return SB_THREAT_TYPE_SAFE; | |
| 47 } | |
| 48 } | |
| 49 | |
| 50 // Returns the severity information about a given SafeBrowsing list. The lowest | |
| 51 // value is 0, which represents the most severe list. | |
| 52 ThreatSeverity GetThreatSeverity(const UpdateListIdentifier& list_id) { | |
| 53 switch (list_id.threat_type) { | |
| 54 case MALWARE_THREAT: | |
| 55 case SOCIAL_ENGINEERING_PUBLIC: | |
| 56 return 0; | |
| 57 case API_ABUSE: | |
| 58 return 1; | |
| 59 default: | |
| 60 NOTREACHED() << "Unexpected ThreatType encountered in GetThreatSeverity"; | |
| 61 return kLeastSeverity; | |
| 62 } | |
| 63 } | |
| 64 | |
| 29 } // namespace | 65 } // namespace |
| 30 | 66 |
| 67 V4LocalDatabaseManager::PendingCheck::PendingCheck(CheckType check_type, | |
| 68 Client* client, | |
| 69 const GURL& url) | |
| 70 : check_type(check_type), | |
| 71 client(client), | |
| 72 url(url), | |
| 73 result_threat_type(SB_THREAT_TYPE_SAFE) {} | |
| 74 | |
| 75 V4LocalDatabaseManager::PendingCheck::~PendingCheck() {} | |
| 76 | |
| 31 V4LocalDatabaseManager::V4LocalDatabaseManager(const base::FilePath& base_path) | 77 V4LocalDatabaseManager::V4LocalDatabaseManager(const base::FilePath& base_path) |
| 32 : base_path_(base_path), | 78 : base_path_(base_path), |
| 33 enabled_(false), | 79 enabled_(false), |
| 34 store_id_file_names_(GetStoreIdAndFileNames()) { | 80 store_id_file_names_(GetStoreIdAndFileNames()) { |
| 35 DCHECK(!base_path_.empty()); | 81 DCHECK(!base_path_.empty()); |
| 36 DCHECK(!store_id_file_names_.empty()); | 82 DCHECK(!store_id_file_names_.empty()); |
| 37 | 83 |
| 38 DVLOG(1) << "V4LocalDatabaseManager::V4LocalDatabaseManager: " | 84 DVLOG(1) << "V4LocalDatabaseManager::V4LocalDatabaseManager: " |
| 39 << "base_path_: " << base_path_.AsUTF8Unsafe(); | 85 << "base_path_: " << base_path_.AsUTF8Unsafe(); |
| 40 } | 86 } |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 133 } | 179 } |
| 134 | 180 |
| 135 bool V4LocalDatabaseManager::IsCsdWhitelistKillSwitchOn() { | 181 bool V4LocalDatabaseManager::IsCsdWhitelistKillSwitchOn() { |
| 136 // TODO(vakh): Implement this skeleton. | 182 // TODO(vakh): Implement this skeleton. |
| 137 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 183 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 138 return true; | 184 return true; |
| 139 } | 185 } |
| 140 | 186 |
| 141 bool V4LocalDatabaseManager::CheckBrowseUrl(const GURL& url, Client* client) { | 187 bool V4LocalDatabaseManager::CheckBrowseUrl(const GURL& url, Client* client) { |
| 142 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 188 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 189 | |
| 143 if (!enabled_ || !CanCheckUrl(url)) { | 190 if (!enabled_ || !CanCheckUrl(url)) { |
| 144 return true; | 191 return true; |
| 145 } | 192 } |
| 146 | 193 |
| 147 if (v4_database_) { | 194 if (v4_database_) { |
| 148 std::unordered_set<FullHash> full_hashes; | 195 std::unordered_set<FullHash> full_hashes; |
| 149 V4ProtocolManagerUtil::UrlToFullHashes(url, &full_hashes); | 196 V4ProtocolManagerUtil::UrlToFullHashes(url, &full_hashes); |
| 150 | 197 |
| 151 std::unordered_set<UpdateListIdentifier> stores_to_look( | 198 std::unordered_set<UpdateListIdentifier> stores_to_look( |
| 152 {GetUrlMalwareId(), GetUrlSocEngId()}); | 199 {GetUrlMalwareId(), GetUrlSocEngId()}); |
| 153 std::unordered_set<HashPrefix> matched_hash_prefixes; | 200 std::unordered_set<HashPrefix> matched_hash_prefixes; |
| 154 std::unordered_set<UpdateListIdentifier> matched_stores; | 201 std::unordered_set<UpdateListIdentifier> matched_stores; |
| 155 StoreAndHashPrefixes matched_store_and_full_hashes; | 202 StoreAndHashPrefixes matched_store_and_hash_prefixes; |
| 156 FullHashToStoreAndHashPrefixesMap full_hash_to_store_and_hash_prefixes; | 203 FullHashToStoreAndHashPrefixesMap full_hash_to_store_and_hash_prefixes; |
| 157 for (const auto& full_hash : full_hashes) { | 204 for (const auto& full_hash : full_hashes) { |
| 158 matched_store_and_full_hashes.clear(); | 205 matched_store_and_hash_prefixes.clear(); |
| 159 v4_database_->GetStoresMatchingFullHash(full_hash, stores_to_look, | 206 v4_database_->GetStoresMatchingFullHash(full_hash, stores_to_look, |
| 160 &matched_store_and_full_hashes); | 207 &matched_store_and_hash_prefixes); |
| 161 if (!matched_store_and_full_hashes.empty()) { | 208 if (!matched_store_and_hash_prefixes.empty()) { |
| 162 full_hash_to_store_and_hash_prefixes[full_hash] = | 209 full_hash_to_store_and_hash_prefixes[full_hash] = |
| 163 matched_store_and_full_hashes; | 210 matched_store_and_hash_prefixes; |
| 164 } | 211 } |
| 165 } | 212 } |
| 166 | 213 |
| 167 if (full_hash_to_store_and_hash_prefixes.empty()) { | 214 if (full_hash_to_store_and_hash_prefixes.empty()) { |
| 168 return true; | 215 return true; |
| 169 } else { | 216 } else { |
| 170 // TODO(vakh): Pass more information to the callback for it to be able to | 217 std::unique_ptr<PendingCheck> pending_check = |
| 171 // do something meaningful. | 218 base::MakeUnique<PendingCheck>(CheckType::CHECK_BROWSE_URL, client, |
| 219 url); | |
| 220 | |
| 172 v4_get_hash_protocol_manager_->GetFullHashes( | 221 v4_get_hash_protocol_manager_->GetFullHashes( |
| 173 full_hash_to_store_and_hash_prefixes, | 222 full_hash_to_store_and_hash_prefixes, |
| 174 base::Bind(&V4LocalDatabaseManager::OnFullHashResponse, | 223 base::Bind(&V4LocalDatabaseManager::OnFullHashResponse, |
| 175 base::Unretained(this))); | 224 base::Unretained(this), base::Passed(&pending_check))); |
| 225 | |
| 226 pending_clients_.insert(client); | |
| 227 | |
| 176 return false; | 228 return false; |
| 177 } | 229 } |
| 178 } else { | 230 } else { |
| 179 // TODO(vakh): Queue the check and process it when the database becomes | 231 // TODO(vakh): Queue the check and process it when the database becomes |
| 180 // ready. | 232 // ready. |
| 181 return false; | 233 return false; |
| 182 } | 234 } |
| 183 } | 235 } |
| 184 | 236 |
| 237 // static | |
| 238 void V4LocalDatabaseManager::GetSeverestThreatTypeAndMetadata( | |
| 239 SBThreatType* result_threat_type, | |
| 240 ThreatMetadata* metadata, | |
| 241 const std::vector<FullHashInfo>& full_hash_infos) { | |
| 242 DCHECK(result_threat_type); | |
| 243 DCHECK(metadata); | |
| 244 | |
| 245 ThreatSeverity most_severe_yet = kLeastSeverity; | |
| 246 for (size_t i = 0; i < full_hash_infos.size(); i++) { | |
|
Nathan Parker
2016/09/20 17:51:09
nit: for (const FullHashInfo& fi : full_hash_infos
vakh (use Gerrit instead)
2016/09/20 18:21:16
Done.
| |
| 247 const FullHashInfo& fhi = full_hash_infos[i]; | |
| 248 ThreatSeverity severity = GetThreatSeverity(fhi.list_id); | |
| 249 if (severity < most_severe_yet) { | |
| 250 most_severe_yet = severity; | |
| 251 *result_threat_type = GetSBThreatTypeForList(fhi.list_id); | |
| 252 *metadata = fhi.metadata; | |
| 253 } | |
| 254 } | |
| 255 } | |
| 256 | |
| 185 void V4LocalDatabaseManager::OnFullHashResponse( | 257 void V4LocalDatabaseManager::OnFullHashResponse( |
| 258 std::unique_ptr<PendingCheck> pending_check, | |
| 186 const std::vector<FullHashInfo>& full_hash_infos) { | 259 const std::vector<FullHashInfo>& full_hash_infos) { |
| 260 DCHECK_CURRENTLY_ON(BrowserThread::IO); | |
| 261 | |
| 262 if (!enabled_) { | |
| 263 DCHECK(pending_clients_.empty()); | |
| 264 return; | |
| 265 } | |
| 266 | |
| 267 auto it = pending_clients_.find(pending_check->client); | |
| 268 if (it == pending_clients_.end()) { | |
| 269 // The check has since been cancelled. | |
| 270 return; | |
| 271 } | |
| 272 | |
| 273 if (full_hash_infos.empty()) { | |
| 274 // The resource is not known to be unsafe. Respond right away. | |
| 275 RespondToClient(std::move(pending_check)); | |
| 276 return; | |
| 277 } | |
| 278 | |
| 279 GetSeverestThreatTypeAndMetadata(&pending_check->result_threat_type, | |
| 280 &pending_check->url_metadata, | |
| 281 full_hash_infos); | |
| 282 | |
| 283 RespondToClient(std::move(pending_check)); | |
| 284 pending_clients_.erase(it); | |
| 285 } | |
| 286 | |
| 287 void V4LocalDatabaseManager::RespondToClient( | |
| 288 std::unique_ptr<PendingCheck> pending_check) { | |
| 289 DCHECK(pending_check.get()); | |
| 290 DCHECK_EQ(CheckType::CHECK_BROWSE_URL, pending_check->check_type); | |
| 187 // TODO(vakh): Implement this skeleton. | 291 // TODO(vakh): Implement this skeleton. |
| 188 } | 292 } |
| 189 | 293 |
| 190 void V4LocalDatabaseManager::CancelCheck(Client* client) { | 294 void V4LocalDatabaseManager::CancelCheck(Client* client) { |
| 191 // TODO(vakh): Implement this skeleton. | |
| 192 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 295 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 193 DCHECK(enabled_); | 296 DCHECK(enabled_); |
| 297 | |
| 298 auto it = pending_clients_.find(client); | |
| 299 if (it != pending_clients_.end()) { | |
| 300 pending_clients_.erase(it); | |
| 301 } | |
| 302 | |
| 303 // TODO(vakh): Handle the case of queued checks. | |
| 194 } | 304 } |
| 195 | 305 |
| 196 void V4LocalDatabaseManager::StartOnIOThread( | 306 void V4LocalDatabaseManager::StartOnIOThread( |
| 197 net::URLRequestContextGetter* request_context_getter, | 307 net::URLRequestContextGetter* request_context_getter, |
| 198 const V4ProtocolConfig& config) { | 308 const V4ProtocolConfig& config) { |
| 199 SafeBrowsingDatabaseManager::StartOnIOThread(request_context_getter, config); | 309 SafeBrowsingDatabaseManager::StartOnIOThread(request_context_getter, config); |
| 200 | 310 |
| 201 db_updated_callback_ = base::Bind(&V4LocalDatabaseManager::DatabaseUpdated, | 311 db_updated_callback_ = base::Bind(&V4LocalDatabaseManager::DatabaseUpdated, |
| 202 base::Unretained(this)); | 312 base::Unretained(this)); |
| 203 | 313 |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 255 // Schedule the deletion of v4_database off IO thread. | 365 // Schedule the deletion of v4_database off IO thread. |
| 256 V4Database::Destroy(std::move(v4_database)); | 366 V4Database::Destroy(std::move(v4_database)); |
| 257 } | 367 } |
| 258 } | 368 } |
| 259 | 369 |
| 260 void V4LocalDatabaseManager::StopOnIOThread(bool shutdown) { | 370 void V4LocalDatabaseManager::StopOnIOThread(bool shutdown) { |
| 261 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 371 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 262 | 372 |
| 263 enabled_ = false; | 373 enabled_ = false; |
| 264 | 374 |
| 375 pending_clients_.clear(); | |
| 376 | |
| 265 // Delete the V4Database. Any pending writes to disk are completed. | 377 // Delete the V4Database. Any pending writes to disk are completed. |
| 266 // This operation happens on the task_runner on which v4_database_ operates | 378 // This operation happens on the task_runner on which v4_database_ operates |
| 267 // and doesn't block the IO thread. | 379 // and doesn't block the IO thread. |
| 268 V4Database::Destroy(std::move(v4_database_)); | 380 V4Database::Destroy(std::move(v4_database_)); |
| 269 | 381 |
| 270 // Delete the V4UpdateProtocolManager. | 382 // Delete the V4UpdateProtocolManager. |
| 271 // This cancels any in-flight update request. | 383 // This cancels any in-flight update request. |
| 272 v4_update_protocol_manager_.reset(); | 384 v4_update_protocol_manager_.reset(); |
| 273 | 385 |
| 274 db_updated_callback_.Reset(); | 386 db_updated_callback_.Reset(); |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 293 std::unordered_set<UpdateListIdentifier> | 405 std::unordered_set<UpdateListIdentifier> |
| 294 V4LocalDatabaseManager::GetStoresForFullHashRequests() { | 406 V4LocalDatabaseManager::GetStoresForFullHashRequests() { |
| 295 std::unordered_set<UpdateListIdentifier> stores_for_full_hash; | 407 std::unordered_set<UpdateListIdentifier> stores_for_full_hash; |
| 296 for (auto it : store_id_file_names_) { | 408 for (auto it : store_id_file_names_) { |
| 297 stores_for_full_hash.insert(it.list_id); | 409 stores_for_full_hash.insert(it.list_id); |
| 298 } | 410 } |
| 299 return stores_for_full_hash; | 411 return stores_for_full_hash; |
| 300 } | 412 } |
| 301 | 413 |
| 302 } // namespace safe_browsing | 414 } // namespace safe_browsing |
| OLD | NEW |