| 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 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 49 safe_browsing_util::ListType check_type, | 49 safe_browsing_util::ListType check_type, |
| 50 const std::vector<SBFullHashResult>& full_hashes) { | 50 const std::vector<SBFullHashResult>& full_hashes) { |
| 51 SafeBrowsingProtocolManager::ResultType result; | 51 SafeBrowsingProtocolManager::ResultType result; |
| 52 if (full_hashes.empty()) { | 52 if (full_hashes.empty()) { |
| 53 result = SafeBrowsingProtocolManager::GET_HASH_FULL_HASH_EMPTY; | 53 result = SafeBrowsingProtocolManager::GET_HASH_FULL_HASH_EMPTY; |
| 54 } else if (hit) { | 54 } else if (hit) { |
| 55 result = SafeBrowsingProtocolManager::GET_HASH_FULL_HASH_HIT; | 55 result = SafeBrowsingProtocolManager::GET_HASH_FULL_HASH_HIT; |
| 56 } else { | 56 } else { |
| 57 result = SafeBrowsingProtocolManager::GET_HASH_FULL_HASH_MISS; | 57 result = SafeBrowsingProtocolManager::GET_HASH_FULL_HASH_MISS; |
| 58 } | 58 } |
| 59 bool is_download = check_type == safe_browsing_util::BINURL || | 59 bool is_download = check_type == safe_browsing_util::BINURL; |
| 60 check_type == safe_browsing_util::BINHASH; | |
| 61 SafeBrowsingProtocolManager::RecordGetHashResult(is_download, result); | 60 SafeBrowsingProtocolManager::RecordGetHashResult(is_download, result); |
| 62 } | 61 } |
| 63 | 62 |
| 64 bool IsExpectedThreat( | 63 bool IsExpectedThreat( |
| 65 const SBThreatType threat_type, | 64 const SBThreatType threat_type, |
| 66 const std::vector<SBThreatType>& expected_threats) { | 65 const std::vector<SBThreatType>& expected_threats) { |
| 67 return expected_threats.end() != std::find(expected_threats.begin(), | 66 return expected_threats.end() != std::find(expected_threats.begin(), |
| 68 expected_threats.end(), | 67 expected_threats.end(), |
| 69 threat_type); | 68 threat_type); |
| 70 } | 69 } |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 108 OnCheckDownloadUrlResult( | 107 OnCheckDownloadUrlResult( |
| 109 check.urls, | 108 check.urls, |
| 110 *std::max_element(check.url_results.begin(), | 109 *std::max_element(check.url_results.begin(), |
| 111 check.url_results.end())); | 110 check.url_results.end())); |
| 112 break; | 111 break; |
| 113 default: | 112 default: |
| 114 NOTREACHED(); | 113 NOTREACHED(); |
| 115 } | 114 } |
| 116 } else if (!check.full_hashes.empty()) { | 115 } else if (!check.full_hashes.empty()) { |
| 117 switch (check.check_type) { | 116 switch (check.check_type) { |
| 118 case safe_browsing_util::BINHASH: | |
| 119 DCHECK_EQ(1u, check.full_hashes.size()); | |
| 120 OnCheckDownloadHashResult( | |
| 121 safe_browsing_util::SBFullHashToString(check.full_hashes[0]), | |
| 122 check.full_hash_results[0]); | |
| 123 break; | |
| 124 case safe_browsing_util::EXTENSIONBLACKLIST: { | 117 case safe_browsing_util::EXTENSIONBLACKLIST: { |
| 125 std::set<std::string> unsafe_extension_ids; | 118 std::set<std::string> unsafe_extension_ids; |
| 126 for (size_t i = 0; i < check.full_hashes.size(); ++i) { | 119 for (size_t i = 0; i < check.full_hashes.size(); ++i) { |
| 127 std::string extension_id = | 120 std::string extension_id = |
| 128 safe_browsing_util::SBFullHashToString(check.full_hashes[i]); | 121 safe_browsing_util::SBFullHashToString(check.full_hashes[i]); |
| 129 if (check.full_hash_results[i] == SB_THREAT_TYPE_EXTENSION) | 122 if (check.full_hash_results[i] == SB_THREAT_TYPE_EXTENSION) |
| 130 unsafe_extension_ids.insert(extension_id); | 123 unsafe_extension_ids.insert(extension_id); |
| 131 } | 124 } |
| 132 OnCheckExtensionsResult(unsafe_extension_ids); | 125 OnCheckExtensionsResult(unsafe_extension_ids); |
| 133 break; | 126 break; |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 227 safe_browsing_util::BINURL, | 220 safe_browsing_util::BINURL, |
| 228 std::vector<SBThreatType>(1, | 221 std::vector<SBThreatType>(1, |
| 229 SB_THREAT_TYPE_BINARY_MALWARE_URL)); | 222 SB_THREAT_TYPE_BINARY_MALWARE_URL)); |
| 230 StartSafeBrowsingCheck( | 223 StartSafeBrowsingCheck( |
| 231 check, | 224 check, |
| 232 base::Bind(&SafeBrowsingDatabaseManager::CheckDownloadUrlOnSBThread, this, | 225 base::Bind(&SafeBrowsingDatabaseManager::CheckDownloadUrlOnSBThread, this, |
| 233 check)); | 226 check)); |
| 234 return false; | 227 return false; |
| 235 } | 228 } |
| 236 | 229 |
| 237 bool SafeBrowsingDatabaseManager::CheckDownloadHash( | |
| 238 const std::string& full_hash, | |
| 239 Client* client) { | |
| 240 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
| 241 DCHECK(!full_hash.empty()); | |
| 242 if (!enabled_ || !enable_download_protection_ || full_hash.empty()) | |
| 243 return true; | |
| 244 | |
| 245 // We need to check the database for url prefix, and later may fetch the url | |
| 246 // from the safebrowsing backends. These need to be asynchronous. | |
| 247 std::vector<SBFullHash> full_hashes( | |
| 248 1, safe_browsing_util::StringToSBFullHash(full_hash)); | |
| 249 SafeBrowsingCheck* check = | |
| 250 new SafeBrowsingCheck(std::vector<GURL>(), | |
| 251 full_hashes, | |
| 252 client, | |
| 253 safe_browsing_util::BINHASH, | |
| 254 std::vector<SBThreatType>(1, | |
| 255 SB_THREAT_TYPE_BINARY_MALWARE_HASH)); | |
| 256 StartSafeBrowsingCheck( | |
| 257 check, | |
| 258 base::Bind(&SafeBrowsingDatabaseManager::CheckDownloadHashOnSBThread,this, | |
| 259 check)); | |
| 260 return false; | |
| 261 } | |
| 262 | |
| 263 bool SafeBrowsingDatabaseManager::CheckExtensionIDs( | 230 bool SafeBrowsingDatabaseManager::CheckExtensionIDs( |
| 264 const std::set<std::string>& extension_ids, | 231 const std::set<std::string>& extension_ids, |
| 265 Client* client) { | 232 Client* client) { |
| 266 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 233 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 267 | 234 |
| 268 if (!enabled_ || !enable_extension_blacklist_) | 235 if (!enabled_ || !enable_extension_blacklist_) |
| 269 return true; | 236 return true; |
| 270 | 237 |
| 271 std::vector<SBFullHash> extension_id_hashes; | 238 std::vector<SBFullHash> extension_id_hashes; |
| 272 std::transform(extension_ids.begin(), extension_ids.end(), | 239 std::transform(extension_ids.begin(), extension_ids.end(), |
| (...skipping 455 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 728 GetHashRequestors requestors; | 695 GetHashRequestors requestors; |
| 729 requestors.push_back(check); | 696 requestors.push_back(check); |
| 730 gethash_requests_[prefix] = requestors; | 697 gethash_requests_[prefix] = requestors; |
| 731 } | 698 } |
| 732 | 699 |
| 733 // Reset the start time so that we can measure the network time without the | 700 // Reset the start time so that we can measure the network time without the |
| 734 // database time. | 701 // database time. |
| 735 check->start = base::TimeTicks::Now(); | 702 check->start = base::TimeTicks::Now(); |
| 736 // Note: If |this| is deleted or stopped, the protocol_manager will | 703 // Note: If |this| is deleted or stopped, the protocol_manager will |
| 737 // be destroyed as well - hence it's OK to do unretained in this case. | 704 // be destroyed as well - hence it's OK to do unretained in this case. |
| 738 bool is_download = check->check_type == safe_browsing_util::BINURL || | 705 bool is_download = check->check_type == safe_browsing_util::BINURL; |
| 739 check->check_type == safe_browsing_util::BINHASH; | |
| 740 sb_service_->protocol_manager()->GetFullHash( | 706 sb_service_->protocol_manager()->GetFullHash( |
| 741 check->prefix_hits, | 707 check->prefix_hits, |
| 742 base::Bind(&SafeBrowsingDatabaseManager::HandleGetHashResults, | 708 base::Bind(&SafeBrowsingDatabaseManager::HandleGetHashResults, |
| 743 base::Unretained(this), | 709 base::Unretained(this), |
| 744 check), | 710 check), |
| 745 is_download); | 711 is_download); |
| 746 } else { | 712 } else { |
| 747 // We may have cached results for previous GetHash queries. Since | 713 // We may have cached results for previous GetHash queries. Since |
| 748 // this data comes from cache, don't histogram hits. | 714 // this data comes from cache, don't histogram hits. |
| 749 HandleOneCheck(check, check->full_hits); | 715 HandleOneCheck(check, check->full_hits); |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 850 } | 816 } |
| 851 | 817 |
| 852 if (safe_browsing_util::IsMalwareList(list_name)) { | 818 if (safe_browsing_util::IsMalwareList(list_name)) { |
| 853 return SB_THREAT_TYPE_URL_MALWARE; | 819 return SB_THREAT_TYPE_URL_MALWARE; |
| 854 } | 820 } |
| 855 | 821 |
| 856 if (safe_browsing_util::IsBadbinurlList(list_name)) { | 822 if (safe_browsing_util::IsBadbinurlList(list_name)) { |
| 857 return SB_THREAT_TYPE_BINARY_MALWARE_URL; | 823 return SB_THREAT_TYPE_BINARY_MALWARE_URL; |
| 858 } | 824 } |
| 859 | 825 |
| 860 if (safe_browsing_util::IsBadbinhashList(list_name)) { | |
| 861 return SB_THREAT_TYPE_BINARY_MALWARE_HASH; | |
| 862 } | |
| 863 | |
| 864 if (safe_browsing_util::IsExtensionList(list_name)) { | 826 if (safe_browsing_util::IsExtensionList(list_name)) { |
| 865 return SB_THREAT_TYPE_EXTENSION; | 827 return SB_THREAT_TYPE_EXTENSION; |
| 866 } | 828 } |
| 867 | 829 |
| 868 DVLOG(1) << "Unknown safe browsing list " << list_name; | 830 DVLOG(1) << "Unknown safe browsing list " << list_name; |
| 869 return SB_THREAT_TYPE_SAFE; | 831 return SB_THREAT_TYPE_SAFE; |
| 870 } | 832 } |
| 871 | 833 |
| 872 void SafeBrowsingDatabaseManager::DatabaseUpdateFinished( | 834 void SafeBrowsingDatabaseManager::DatabaseUpdateFinished( |
| 873 bool update_succeeded) { | 835 bool update_succeeded) { |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 973 IsExpectedThreat(threat, check->expected_threats)) { | 935 IsExpectedThreat(threat, check->expected_threats)) { |
| 974 check->full_hash_results[i] = threat; | 936 check->full_hash_results[i] = threat; |
| 975 is_threat = true; | 937 is_threat = true; |
| 976 } | 938 } |
| 977 } | 939 } |
| 978 | 940 |
| 979 SafeBrowsingCheckDone(check); | 941 SafeBrowsingCheckDone(check); |
| 980 return is_threat; | 942 return is_threat; |
| 981 } | 943 } |
| 982 | 944 |
| 983 void SafeBrowsingDatabaseManager::CheckDownloadHashOnSBThread( | |
| 984 SafeBrowsingCheck* check) { | |
| 985 DCHECK_EQ(base::MessageLoop::current(), | |
| 986 safe_browsing_thread_->message_loop()); | |
| 987 DCHECK(enable_download_protection_); | |
| 988 | |
| 989 DCHECK_EQ(1u, check->full_hashes.size()); | |
| 990 SBFullHash full_hash = check->full_hashes[0]; | |
| 991 | |
| 992 if (!database_->ContainsDownloadHashPrefix(full_hash.prefix)) { | |
| 993 // Good, we don't have hash for this url prefix. | |
| 994 BrowserThread::PostTask( | |
| 995 BrowserThread::IO, FROM_HERE, | |
| 996 base::Bind(&SafeBrowsingDatabaseManager::CheckDownloadHashDone, this, | |
| 997 check)); | |
| 998 return; | |
| 999 } | |
| 1000 | |
| 1001 check->need_get_hash = true; | |
| 1002 check->prefix_hits.push_back(full_hash.prefix); | |
| 1003 BrowserThread::PostTask( | |
| 1004 BrowserThread::IO, FROM_HERE, | |
| 1005 base::Bind(&SafeBrowsingDatabaseManager::OnCheckDone, this, check)); | |
| 1006 } | |
| 1007 | |
| 1008 void SafeBrowsingDatabaseManager::CheckDownloadUrlOnSBThread( | 945 void SafeBrowsingDatabaseManager::CheckDownloadUrlOnSBThread( |
| 1009 SafeBrowsingCheck* check) { | 946 SafeBrowsingCheck* check) { |
| 1010 DCHECK_EQ(base::MessageLoop::current(), | 947 DCHECK_EQ(base::MessageLoop::current(), |
| 1011 safe_browsing_thread_->message_loop()); | 948 safe_browsing_thread_->message_loop()); |
| 1012 DCHECK(enable_download_protection_); | 949 DCHECK(enable_download_protection_); |
| 1013 | 950 |
| 1014 std::vector<SBPrefix> prefix_hits; | 951 std::vector<SBPrefix> prefix_hits; |
| 1015 | 952 |
| 1016 if (!database_->ContainsDownloadUrl(check->urls, &prefix_hits)) { | 953 if (!database_->ContainsDownloadUrl(check->urls, &prefix_hits)) { |
| 1017 // Good, we don't have hash for this url prefix. | 954 // Good, we don't have hash for this url prefix. |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1072 check->client = NULL; | 1009 check->client = NULL; |
| 1073 } | 1010 } |
| 1074 } | 1011 } |
| 1075 | 1012 |
| 1076 void SafeBrowsingDatabaseManager::CheckDownloadUrlDone( | 1013 void SafeBrowsingDatabaseManager::CheckDownloadUrlDone( |
| 1077 SafeBrowsingCheck* check) { | 1014 SafeBrowsingCheck* check) { |
| 1078 DCHECK(enable_download_protection_); | 1015 DCHECK(enable_download_protection_); |
| 1079 SafeBrowsingCheckDone(check); | 1016 SafeBrowsingCheckDone(check); |
| 1080 } | 1017 } |
| 1081 | 1018 |
| 1082 void SafeBrowsingDatabaseManager::CheckDownloadHashDone( | |
| 1083 SafeBrowsingCheck* check) { | |
| 1084 DCHECK(enable_download_protection_); | |
| 1085 SafeBrowsingCheckDone(check); | |
| 1086 } | |
| 1087 | |
| 1088 void SafeBrowsingDatabaseManager::SafeBrowsingCheckDone( | 1019 void SafeBrowsingDatabaseManager::SafeBrowsingCheckDone( |
| 1089 SafeBrowsingCheck* check) { | 1020 SafeBrowsingCheck* check) { |
| 1090 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 1021 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 1091 DCHECK(check); | 1022 DCHECK(check); |
| 1092 | 1023 |
| 1093 if (!enabled_) | 1024 if (!enabled_) |
| 1094 return; | 1025 return; |
| 1095 | 1026 |
| 1096 VLOG(1) << "SafeBrowsingCheckDone"; | 1027 VLOG(1) << "SafeBrowsingCheckDone"; |
| 1097 DCHECK(checks_.find(check) != checks_.end()); | 1028 DCHECK(checks_.find(check) != checks_.end()); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1109 new base::WeakPtrFactory<SafeBrowsingDatabaseManager>(this)); | 1040 new base::WeakPtrFactory<SafeBrowsingDatabaseManager>(this)); |
| 1110 checks_.insert(check); | 1041 checks_.insert(check); |
| 1111 | 1042 |
| 1112 safe_browsing_thread_->message_loop()->PostTask(FROM_HERE, task); | 1043 safe_browsing_thread_->message_loop()->PostTask(FROM_HERE, task); |
| 1113 | 1044 |
| 1114 base::MessageLoop::current()->PostDelayedTask(FROM_HERE, | 1045 base::MessageLoop::current()->PostDelayedTask(FROM_HERE, |
| 1115 base::Bind(&SafeBrowsingDatabaseManager::TimeoutCallback, | 1046 base::Bind(&SafeBrowsingDatabaseManager::TimeoutCallback, |
| 1116 check->timeout_factory_->GetWeakPtr(), check), | 1047 check->timeout_factory_->GetWeakPtr(), check), |
| 1117 check_timeout_); | 1048 check_timeout_); |
| 1118 } | 1049 } |
| OLD | NEW |