Index: chrome/browser/safe_browsing/local_database_manager.cc |
diff --git a/chrome/browser/safe_browsing/local_database_manager.cc b/chrome/browser/safe_browsing/local_database_manager.cc |
index 9763d6eb649d869ccf3777dfa697d6542b6a8a67..38395ff0ab41e6bbdd8233aef4d3cd0641dc4629 100644 |
--- a/chrome/browser/safe_browsing/local_database_manager.cc |
+++ b/chrome/browser/safe_browsing/local_database_manager.cc |
@@ -5,6 +5,7 @@ |
#include "chrome/browser/safe_browsing/local_database_manager.h" |
#include <algorithm> |
+#include <limits> |
#include "base/bind.h" |
#include "base/bind_helpers.h" |
@@ -72,6 +73,34 @@ bool IsExpectedThreat( |
threat_type); |
} |
+// Returns threat level of the list. Lists with lower threat levels are more |
+// severe than lists with higher threat levels. Zero is the severest threat |
+// level possible. |
+int GetThreatSeverity(ListType threat) { |
+ switch (threat) { |
+ case MALWARE: // Falls through. |
+ case PHISH: // Falls through. |
+ case BINURL: // Falls through. |
+ case CSDWHITELIST: // Falls through. |
+ case DOWNLOADWHITELIST: // Falls through. |
+ case INCLUSIONWHITELIST: // Falls through. |
+ case MODULEWHITELIST: // Falls through. |
+ case EXTENSIONBLACKLIST: // Falls through. |
+ case IPBLACKLIST: |
+ return 0; |
+ case UNWANTEDURL: |
+ // UNWANTEDURL is considered less severe than other threats. |
+ return 1; |
+ case RESOURCEBLACKLIST: |
+ // RESOURCEBLACKLIST is even less severe than UNWANTEDURL. |
+ return 2; |
+ case INVALID: |
+ return std::numeric_limits<int>::max(); |
+ } |
+ NOTREACHED(); |
+ return -1; |
+} |
+ |
// Return the severest list id from the results in |full_hashes| which matches |
// |hash|, or INVALID if none match. |
ListType GetHashSeverestThreatListType( |
@@ -79,35 +108,20 @@ ListType GetHashSeverestThreatListType( |
const std::vector<SBFullHashResult>& full_hashes, |
size_t* index) { |
ListType pending_threat = INVALID; |
+ int pending_threat_severity = GetThreatSeverity(INVALID); |
for (size_t i = 0; i < full_hashes.size(); ++i) { |
if (SBFullHashEqual(hash, full_hashes[i].hash)) { |
const ListType threat = |
static_cast<ListType>(full_hashes[i].list_id); |
- switch (threat) { |
- case INVALID: |
- // |full_hashes| should never contain INVALID as a |list_id|. |
- NOTREACHED(); |
- break; |
- case MALWARE: // Falls through. |
- case PHISH: // Falls through. |
- case BINURL: // Falls through. |
- case CSDWHITELIST: // Falls through. |
- case DOWNLOADWHITELIST: // Falls through. |
- case INCLUSIONWHITELIST: // Falls through. |
- case MODULEWHITELIST: // Falls through. |
- case EXTENSIONBLACKLIST: // Falls through. |
- case IPBLACKLIST: |
- if (index) |
- *index = i; |
- return threat; |
- case UNWANTEDURL: |
- // UNWANTEDURL is considered less severe than other threats, keep |
- // looking. |
- pending_threat = threat; |
- if (index) |
- *index = i; |
- break; |
+ int threat_severity = GetThreatSeverity(threat); |
+ if (threat_severity < pending_threat_severity) { |
+ pending_threat = threat; |
+ pending_threat_severity = threat_severity; |
+ if (index) |
+ *index = i; |
} |
+ if (pending_threat_severity == 0) |
+ return pending_threat; |
} |
} |
return pending_threat; |
@@ -127,29 +141,17 @@ ListType GetUrlSeverestThreatListType( |
GeneratePatternsToCheck(url, &patterns); |
ListType pending_threat = INVALID; |
+ int pending_threat_severity = GetThreatSeverity(INVALID); |
for (size_t i = 0; i < patterns.size(); ++i) { |
ListType threat = GetHashSeverestThreatListType( |
SBFullHashForString(patterns[i]), full_hashes, index); |
- switch (threat) { |
- case INVALID: |
- // Ignore patterns with no matching threat. |
- break; |
- case MALWARE: // Falls through. |
- case PHISH: // Falls through. |
- case BINURL: // Falls through. |
- case CSDWHITELIST: // Falls through. |
- case DOWNLOADWHITELIST: // Falls through. |
- case INCLUSIONWHITELIST: // Falls through. |
- case MODULEWHITELIST: // Falls through. |
- case EXTENSIONBLACKLIST: // Falls through. |
- case IPBLACKLIST: |
- return threat; |
- case UNWANTEDURL: |
- // UNWANTEDURL is considered less severe than other threats, keep |
- // looking. |
- pending_threat = threat; |
- break; |
+ int threat_severity = GetThreatSeverity(threat); |
+ if (threat_severity < pending_threat_severity) { |
+ pending_threat = threat; |
+ pending_threat_severity = threat_severity; |
} |
+ if (pending_threat_severity == 0) |
+ return pending_threat; |
} |
return pending_threat; |
} |
@@ -166,6 +168,8 @@ SBThreatType GetThreatTypeFromListType(ListType list_type) { |
return SB_THREAT_TYPE_BINARY_MALWARE_URL; |
case EXTENSIONBLACKLIST: |
return SB_THREAT_TYPE_EXTENSION; |
+ case RESOURCEBLACKLIST: |
+ return SB_THREAT_TYPE_BLACKLISTED_RESOURCE; |
default: |
DVLOG(1) << "Unknown safe browsing list id " << list_type; |
return SB_THREAT_TYPE_SAFE; |
@@ -200,6 +204,7 @@ LocalSafeBrowsingDatabaseManager::SafeBrowsingCheck::SafeBrowsingCheck( |
: urls(urls), |
url_results(urls.size(), SB_THREAT_TYPE_SAFE), |
url_metadata(urls.size()), |
+ url_hit_hash(urls.size()), |
full_hashes(full_hashes), |
full_hash_results(full_hashes.size(), SB_THREAT_TYPE_SAFE), |
client(client), |
@@ -235,6 +240,11 @@ void LocalSafeBrowsingDatabaseManager::SafeBrowsingCheck:: |
client->OnCheckDownloadUrlResult( |
urls, *std::max_element(url_results.begin(), url_results.end())); |
break; |
+ case RESOURCEBLACKLIST: |
+ DCHECK_EQ(1u, urls.size()); |
+ client->OnCheckResourceUrlResult(urls[0], url_results[0], |
+ url_hit_hash[0]); |
+ break; |
default: |
NOTREACHED(); |
} |
@@ -389,6 +399,36 @@ bool LocalSafeBrowsingDatabaseManager::CheckExtensionIDs( |
return false; |
} |
+bool LocalSafeBrowsingDatabaseManager::CheckResourceUrl( |
+ const GURL& url, Client* client) { |
+ DCHECK_CURRENTLY_ON(BrowserThread::IO); |
+ |
+ if (!enabled_ || !CanCheckUrl(url)) |
+ return true; |
+ |
+ std::vector<SBThreatType> expected_threats = |
+ {SB_THREAT_TYPE_BLACKLISTED_RESOURCE}; |
+ |
+ if (!MakeDatabaseAvailable()) { |
+ QueuedCheck queued_check(RESOURCEBLACKLIST, client, url, |
+ expected_threats, base::TimeTicks::Now()); |
+ queued_checks_.push_back(queued_check); |
+ return false; |
+ } |
+ |
+ SafeBrowsingCheck* check = |
+ new SafeBrowsingCheck({url}, std::vector<SBFullHash>(), client, |
+ RESOURCEBLACKLIST, expected_threats); |
+ |
+ std::vector<SBPrefix> prefixes; |
+ SafeBrowsingDatabase::GetDownloadUrlPrefixes(check->urls, &prefixes); |
+ StartSafeBrowsingCheck( |
+ check, |
+ base::Bind(&LocalSafeBrowsingDatabaseManager::CheckResourceUrlOnSBThread, |
+ this, prefixes)); |
+ return false; |
+} |
+ |
bool LocalSafeBrowsingDatabaseManager::MatchMalwareIP( |
const std::string& ip_address) { |
DCHECK_CURRENTLY_ON(BrowserThread::IO); |
@@ -1110,6 +1150,9 @@ bool LocalSafeBrowsingDatabaseManager::HandleOneCheck( |
if (threat != SB_THREAT_TYPE_SAFE) { |
check->url_results[i] = threat; |
check->url_metadata[i] = expected_full_hashes[threat_index].metadata; |
+ const SBFullHash& hash = expected_full_hashes[threat_index].hash; |
+ check->url_hit_hash[i] = std::string(hash.full_hash, |
+ arraysize(hash.full_hash)); |
is_threat = true; |
} |
} |
@@ -1167,6 +1210,18 @@ LocalSafeBrowsingDatabaseManager::CheckExtensionIDsOnSBThread( |
return prefix_hits; |
} |
+std::vector<SBPrefix> |
+LocalSafeBrowsingDatabaseManager::CheckResourceUrlOnSBThread( |
+ const std::vector<SBPrefix>& prefixes) { |
+ DCHECK(safe_browsing_task_runner_->RunsTasksOnCurrentThread()); |
+ |
+ std::vector<SBPrefix> prefix_hits; |
+ const bool result = |
+ database_->ContainsResourceUrlPrefixes(prefixes, &prefix_hits); |
+ DCHECK_EQ(result, !prefix_hits.empty()); |
+ return prefix_hits; |
+} |
+ |
void LocalSafeBrowsingDatabaseManager::TimeoutCallback( |
SafeBrowsingCheck* check) { |
DCHECK_CURRENTLY_ON(BrowserThread::IO); |