Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(205)

Side by Side Diff: chrome/browser/safe_browsing/database_manager.cc

Issue 11615011: Small modifications to safebrowsing code to make it simpler to add the extension (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix compiler Created 7 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 "base/bind.h" 7 #include "base/bind.h"
8 #include "base/bind_helpers.h" 8 #include "base/bind_helpers.h"
9 #include "base/callback.h" 9 #include "base/callback.h"
10 #include "base/command_line.h" 10 #include "base/command_line.h"
(...skipping 17 matching lines...) Expand all
28 #include "chrome/common/chrome_paths.h" 28 #include "chrome/common/chrome_paths.h"
29 #include "chrome/common/chrome_switches.h" 29 #include "chrome/common/chrome_switches.h"
30 #include "chrome/common/url_constants.h" 30 #include "chrome/common/url_constants.h"
31 #include "content/public/browser/browser_thread.h" 31 #include "content/public/browser/browser_thread.h"
32 #include "content/public/browser/notification_service.h" 32 #include "content/public/browser/notification_service.h"
33 33
34 using content::BrowserThread; 34 using content::BrowserThread;
35 35
36 namespace { 36 namespace {
37 37
38 // When download url check takes this long, client's callback will be called 38 // Timeout for match checks, e.g. download URLs, hashes.
39 // without waiting for the result. 39 const int kCheckTimeoutMs = 10000;
40 const int64 kDownloadUrlCheckTimeoutMs = 10000;
41
42 // Similar to kDownloadUrlCheckTimeoutMs, but for download hash checks.
43 const int64 kDownloadHashCheckTimeoutMs = 10000;
44 40
45 // Records disposition information about the check. |hit| should be 41 // Records disposition information about the check. |hit| should be
46 // |true| if there were any prefix hits in |full_hashes|. 42 // |true| if there were any prefix hits in |full_hashes|.
47 void RecordGetHashCheckStatus( 43 void RecordGetHashCheckStatus(
48 bool hit, 44 bool hit,
49 bool is_download, 45 safe_browsing_util::ListType check_type,
50 const std::vector<SBFullHashResult>& full_hashes) { 46 const std::vector<SBFullHashResult>& full_hashes) {
51 SafeBrowsingProtocolManager::ResultType result; 47 SafeBrowsingProtocolManager::ResultType result;
52 if (full_hashes.empty()) { 48 if (full_hashes.empty()) {
53 result = SafeBrowsingProtocolManager::GET_HASH_FULL_HASH_EMPTY; 49 result = SafeBrowsingProtocolManager::GET_HASH_FULL_HASH_EMPTY;
54 } else if (hit) { 50 } else if (hit) {
55 result = SafeBrowsingProtocolManager::GET_HASH_FULL_HASH_HIT; 51 result = SafeBrowsingProtocolManager::GET_HASH_FULL_HASH_HIT;
56 } else { 52 } else {
57 result = SafeBrowsingProtocolManager::GET_HASH_FULL_HASH_MISS; 53 result = SafeBrowsingProtocolManager::GET_HASH_FULL_HASH_MISS;
58 } 54 }
55 bool is_download = check_type == safe_browsing_util::BINURL ||
56 check_type == safe_browsing_util::BINHASH;
59 SafeBrowsingProtocolManager::RecordGetHashResult(is_download, result); 57 SafeBrowsingProtocolManager::RecordGetHashResult(is_download, result);
60 } 58 }
61 59
62 } // namespace 60 } // namespace
63 61
64 SafeBrowsingDatabaseManager::SafeBrowsingCheck::SafeBrowsingCheck() 62 SafeBrowsingDatabaseManager::SafeBrowsingCheck::SafeBrowsingCheck(
65 : full_hash(NULL), 63 safe_browsing_util::ListType check_type)
66 client(NULL), 64 : client(NULL),
67 need_get_hash(false), 65 need_get_hash(false),
68 threat_type(SB_THREAT_TYPE_SAFE), 66 check_type(check_type),
69 is_download(false),
70 timeout_factory_(NULL) { 67 timeout_factory_(NULL) {
71 } 68 }
72 69
73 SafeBrowsingDatabaseManager::SafeBrowsingCheck::~SafeBrowsingCheck() {} 70 SafeBrowsingDatabaseManager::SafeBrowsingCheck::~SafeBrowsingCheck() {}
74 71
72 // Gets the max threat type from a map of entity -> threat type. If all
73 // entities are safe then this will be SB_THREAT_TYPE_SAFE.
74 //
75 // This is really just a semi-arbitrary way to choose a single threat type from
76 // many. Under normal circumstances there will only be one type, and SAFE
77 // threats will be filtered out.
78 template<typename T>
79 SBThreatType GetMaxThreatType(const std::map<T, SBThreatType>& threats) {
80 SBThreatType max = SB_THREAT_TYPE_SAFE;
81 for (typename std::map<T, SBThreatType>::const_iterator it = threats.begin();
82 it != threats.end(); ++it) {
83 if (it->second > max)
84 max = it->second;
85 }
86 return max;
87 }
88
75 void SafeBrowsingDatabaseManager::Client::OnSafeBrowsingResult( 89 void SafeBrowsingDatabaseManager::Client::OnSafeBrowsingResult(
76 const SafeBrowsingCheck& check) { 90 const SafeBrowsingCheck& check) {
77 if (!check.urls.empty()) { 91 if (!check.urls.empty()) {
78 92 DCHECK(check.full_hashes.empty());
79 DCHECK(!check.full_hash.get()); 93 switch (check.check_type) {
80 if (!check.is_download) { 94 case safe_browsing_util::MALWARE:
81 DCHECK_EQ(1U, check.urls.size()); 95 case safe_browsing_util::PHISH:
82 OnCheckBrowseUrlResult(check.urls[0], check.threat_type); 96 DCHECK_EQ(1U, check.urls.size());
83 } else { 97 OnCheckBrowseUrlResult(check.urls[0],
84 OnCheckDownloadUrlResult(check.urls, check.threat_type); 98 GetMaxThreatType(check.url_threats));
Scott Hess - ex-Googler 2013/01/11 23:44:05 If url_threats were a parallel vector pre-filled w
not at google - send to devlin 2013/01/14 23:00:55 Done.
99 break;
100 case safe_browsing_util::BINURL:
101 OnCheckDownloadUrlResult(check.urls,
102 GetMaxThreatType(check.url_threats));
Scott Hess - ex-Googler 2013/01/11 23:44:05 And this would be *max_element(url_threats.begin()
not at google - send to devlin 2013/01/14 23:00:55 Done.
103 break;
104 default:
105 NOTREACHED();
85 } 106 }
86 } else if (check.full_hash.get()) { 107 } else if (!check.full_hashes.empty()) {
87 OnCheckDownloadHashResult( 108 switch (check.check_type) {
88 safe_browsing_util::SBFullHashToString(*check.full_hash), 109 case safe_browsing_util::BINHASH:
89 check.threat_type); 110 DCHECK_EQ(1u, check.full_hashes.size());
111 OnCheckDownloadHashResult(
112 safe_browsing_util::SBFullHashToString(check.full_hashes[0]),
113 GetMaxThreatType(check.full_hash_threats));
Scott Hess - ex-Googler 2013/01/11 23:44:05 Likewise here, just a different vector.
not at google - send to devlin 2013/01/14 23:00:55 Done.
114 break;
115 default:
116 NOTREACHED();
117 }
90 } else { 118 } else {
91 NOTREACHED(); 119 NOTREACHED();
92 } 120 }
93 } 121 }
94 122
95 SafeBrowsingDatabaseManager::SafeBrowsingDatabaseManager( 123 SafeBrowsingDatabaseManager::SafeBrowsingDatabaseManager(
96 const scoped_refptr<SafeBrowsingService>& service) 124 const scoped_refptr<SafeBrowsingService>& service)
97 : sb_service_(service), 125 : sb_service_(service),
98 database_(NULL), 126 database_(NULL),
99 enabled_(false), 127 enabled_(false),
100 enable_download_protection_(false), 128 enable_download_protection_(false),
101 enable_csd_whitelist_(false), 129 enable_csd_whitelist_(false),
102 enable_download_whitelist_(false), 130 enable_download_whitelist_(false),
103 update_in_progress_(false), 131 update_in_progress_(false),
104 database_update_in_progress_(false), 132 database_update_in_progress_(false),
105 closing_database_(false), 133 closing_database_(false),
106 download_urlcheck_timeout_ms_(kDownloadUrlCheckTimeoutMs), 134 download_url_check_timeout_(
107 download_hashcheck_timeout_ms_(kDownloadHashCheckTimeoutMs) { 135 base::TimeDelta::FromMilliseconds(kCheckTimeoutMs)),
136 download_hash_check_timeout_(
137 base::TimeDelta::FromMilliseconds(kCheckTimeoutMs)) {
Scott Hess - ex-Googler 2013/01/11 23:44:05 If they're going to be the same, do they need to b
not at google - send to devlin 2013/01/14 23:00:55 No idea, I assumed it was this way for some good r
108 DCHECK(sb_service_ != NULL); 138 DCHECK(sb_service_ != NULL);
109 139
110 CommandLine* cmdline = CommandLine::ForCurrentProcess(); 140 CommandLine* cmdline = CommandLine::ForCurrentProcess();
111 enable_download_protection_ = 141 enable_download_protection_ =
112 !cmdline->HasSwitch(switches::kSbDisableDownloadProtection); 142 !cmdline->HasSwitch(switches::kSbDisableDownloadProtection);
113 143
114 // We only download the csd-whitelist if client-side phishing detection is 144 // We only download the csd-whitelist if client-side phishing detection is
115 // enabled. 145 // enabled.
116 enable_csd_whitelist_ = 146 enable_csd_whitelist_ =
117 !cmdline->HasSwitch(switches::kDisableClientSidePhishingDetection); 147 !cmdline->HasSwitch(switches::kDisableClientSidePhishingDetection);
118 148
119 // TODO(noelutz): remove this boolean variable since it should always be true 149 // TODO(noelutz): remove this boolean variable since it should always be true
120 // if SafeBrowsing is enabled. Unfortunately, we have no test data for this 150 // if SafeBrowsing is enabled. Unfortunately, we have no test data for this
121 // list right now. This means that we need to be able to disable this list 151 // list right now. This means that we need to be able to disable this list
122 // for the SafeBrowsing test to pass. 152 // for the SafeBrowsing test to pass.
123 enable_download_whitelist_ = enable_csd_whitelist_; 153 enable_download_whitelist_ = enable_csd_whitelist_;
124
125 } 154 }
126 155
127 SafeBrowsingDatabaseManager::~SafeBrowsingDatabaseManager() { 156 SafeBrowsingDatabaseManager::~SafeBrowsingDatabaseManager() {
128 // We should have already been shut down. If we're still enabled, then the 157 // We should have already been shut down. If we're still enabled, then the
129 // database isn't going to be closed properly, which could lead to corruption. 158 // database isn't going to be closed properly, which could lead to corruption.
130 DCHECK(!enabled_); 159 DCHECK(!enabled_);
131 } 160 }
132 161
133 bool SafeBrowsingDatabaseManager::CanCheckUrl(const GURL& url) const { 162 bool SafeBrowsingDatabaseManager::CanCheckUrl(const GURL& url) const {
134 return url.SchemeIs(chrome::kFtpScheme) || 163 return url.SchemeIs(chrome::kFtpScheme) ||
135 url.SchemeIs(chrome::kHttpScheme) || 164 url.SchemeIs(chrome::kHttpScheme) ||
136 url.SchemeIs(chrome::kHttpsScheme); 165 url.SchemeIs(chrome::kHttpsScheme);
137 } 166 }
138 167
139 bool SafeBrowsingDatabaseManager::CheckDownloadUrl( 168 bool SafeBrowsingDatabaseManager::CheckDownloadUrl(
140 const std::vector<GURL>& url_chain, 169 const std::vector<GURL>& url_chain,
141 Client* client) { 170 Client* client) {
142 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 171 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
143 if (!enabled_ || !enable_download_protection_) 172 if (!enabled_ || !enable_download_protection_)
144 return true; 173 return true;
145 174
146 // We need to check the database for url prefix, and later may fetch the url 175 // We need to check the database for url prefix, and later may fetch the url
147 // from the safebrowsing backends. These need to be asynchronous. 176 // from the safebrowsing backends. These need to be asynchronous.
148 SafeBrowsingCheck* check = new SafeBrowsingCheck(); 177 SafeBrowsingCheck* check = new SafeBrowsingCheck(safe_browsing_util::BINURL);
149 check->urls = url_chain; 178 check->urls = url_chain;
150 StartDownloadCheck( 179 StartSafeBrowsingCheck(
151 check, 180 check,
152 client, 181 client,
153 base::Bind(&SafeBrowsingDatabaseManager::CheckDownloadUrlOnSBThread, this, 182 base::Bind(&SafeBrowsingDatabaseManager::CheckDownloadUrlOnSBThread, this,
154 check), 183 check),
155 download_urlcheck_timeout_ms_); 184 download_url_check_timeout_);
156 return false; 185 return false;
157 } 186 }
158 187
159 bool SafeBrowsingDatabaseManager::CheckDownloadHash( 188 bool SafeBrowsingDatabaseManager::CheckDownloadHash(
160 const std::string& full_hash, 189 const std::string& full_hash,
161 Client* client) { 190 Client* client) {
162 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 191 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
163 DCHECK(!full_hash.empty()); 192 DCHECK(!full_hash.empty());
164 if (!enabled_ || !enable_download_protection_ || full_hash.empty()) 193 if (!enabled_ || !enable_download_protection_ || full_hash.empty())
165 return true; 194 return true;
166 195
167 // We need to check the database for url prefix, and later may fetch the url 196 // We need to check the database for url prefix, and later may fetch the url
168 // from the safebrowsing backends. These need to be asynchronous. 197 // from the safebrowsing backends. These need to be asynchronous.
169 SafeBrowsingCheck* check = new SafeBrowsingCheck(); 198 SafeBrowsingCheck* check = new SafeBrowsingCheck(safe_browsing_util::BINHASH);
170 check->full_hash.reset(new SBFullHash); 199 check->full_hashes.push_back(
171 safe_browsing_util::StringToSBFullHash(full_hash, check->full_hash.get()); 200 safe_browsing_util::StringToSBFullHash(full_hash));
172 StartDownloadCheck( 201 StartSafeBrowsingCheck(
173 check, 202 check,
174 client, 203 client,
175 base::Bind(&SafeBrowsingDatabaseManager::CheckDownloadHashOnSBThread,this, 204 base::Bind(&SafeBrowsingDatabaseManager::CheckDownloadHashOnSBThread,this,
176 check), 205 check),
177 download_hashcheck_timeout_ms_); 206 download_hash_check_timeout_);
178 return false; 207 return false;
179 } 208 }
180 209
181 bool SafeBrowsingDatabaseManager::MatchCsdWhitelistUrl(const GURL& url) { 210 bool SafeBrowsingDatabaseManager::MatchCsdWhitelistUrl(const GURL& url) {
182 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 211 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
183 if (!enabled_ || !enable_csd_whitelist_ || !MakeDatabaseAvailable()) { 212 if (!enabled_ || !enable_csd_whitelist_ || !MakeDatabaseAvailable()) {
184 // There is something funky going on here -- for example, perhaps the user 213 // There is something funky going on here -- for example, perhaps the user
185 // has not restarted since enabling metrics reporting, so we haven't 214 // has not restarted since enabling metrics reporting, so we haven't
186 // enabled the csd whitelist yet. Just to be safe we return true in this 215 // enabled the csd whitelist yet. Just to be safe we return true in this
187 // case. 216 // case.
(...skipping 24 matching lines...) Expand all
212 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 241 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
213 if (!enabled_) 242 if (!enabled_)
214 return true; 243 return true;
215 244
216 if (!CanCheckUrl(url)) 245 if (!CanCheckUrl(url))
217 return true; 246 return true;
218 247
219 const base::TimeTicks start = base::TimeTicks::Now(); 248 const base::TimeTicks start = base::TimeTicks::Now();
220 if (!MakeDatabaseAvailable()) { 249 if (!MakeDatabaseAvailable()) {
221 QueuedCheck check; 250 QueuedCheck check;
251 check.check_type = safe_browsing_util::MALWARE; // or PHISH
222 check.client = client; 252 check.client = client;
223 check.url = url; 253 check.url = url;
224 check.start = start; 254 check.start = start;
225 queued_checks_.push_back(check); 255 queued_checks_.push_back(check);
226 return false; 256 return false;
227 } 257 }
228 258
229 std::string list; 259 std::string list;
230 std::vector<SBPrefix> prefix_hits; 260 std::vector<SBPrefix> prefix_hits;
231 std::vector<SBFullHashResult> full_hits; 261 std::vector<SBFullHashResult> full_hits;
232 262
233 bool prefix_match = 263 bool prefix_match =
234 database_->ContainsBrowseUrl(url, &list, &prefix_hits, &full_hits, 264 database_->ContainsBrowseUrl(url, &list, &prefix_hits, &full_hits,
235 sb_service_->protocol_manager()->last_update()); 265 sb_service_->protocol_manager()->last_update());
236 266
237 UMA_HISTOGRAM_TIMES("SB2.FilterCheck", base::TimeTicks::Now() - start); 267 UMA_HISTOGRAM_TIMES("SB2.FilterCheck", base::TimeTicks::Now() - start);
238 268
239 if (!prefix_match) 269 if (!prefix_match)
240 return true; // URL is okay. 270 return true; // URL is okay.
241 271
242 // Needs to be asynchronous, since we could be in the constructor of a 272 // Needs to be asynchronous, since we could be in the constructor of a
243 // ResourceDispatcherHost event handler which can't pause there. 273 // ResourceDispatcherHost event handler which can't pause there.
244 SafeBrowsingCheck* check = new SafeBrowsingCheck(); 274 SafeBrowsingCheck* check =
275 new SafeBrowsingCheck(safe_browsing_util::MALWARE); // or PHISH
245 check->urls.push_back(url); 276 check->urls.push_back(url);
246 check->client = client; 277 check->client = client;
247 check->threat_type = SB_THREAT_TYPE_SAFE;
248 check->is_download = false;
249 check->need_get_hash = full_hits.empty(); 278 check->need_get_hash = full_hits.empty();
250 check->prefix_hits.swap(prefix_hits); 279 check->prefix_hits.swap(prefix_hits);
251 check->full_hits.swap(full_hits); 280 check->full_hits.swap(full_hits);
252 checks_.insert(check); 281 checks_.insert(check);
253 282
254 BrowserThread::PostTask( 283 BrowserThread::PostTask(
255 BrowserThread::IO, FROM_HERE, 284 BrowserThread::IO, FROM_HERE,
256 base::Bind(&SafeBrowsingDatabaseManager::OnCheckDone, this, check)); 285 base::Bind(&SafeBrowsingDatabaseManager::OnCheckDone, this, check));
257 286
258 return false; 287 return false;
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
396 if (!enabled_) 425 if (!enabled_)
397 return; 426 return;
398 427
399 enabled_ = false; 428 enabled_ = false;
400 429
401 // Delete queued checks, calling back any clients with 'SB_THREAT_TYPE_SAFE'. 430 // Delete queued checks, calling back any clients with 'SB_THREAT_TYPE_SAFE'.
402 // If we don't do this here we may fail to close the database below. 431 // If we don't do this here we may fail to close the database below.
403 while (!queued_checks_.empty()) { 432 while (!queued_checks_.empty()) {
404 QueuedCheck queued = queued_checks_.front(); 433 QueuedCheck queued = queued_checks_.front();
405 if (queued.client) { 434 if (queued.client) {
406 SafeBrowsingCheck sb_check; 435 SafeBrowsingCheck sb_check(queued.check_type);
407 sb_check.urls.push_back(queued.url); 436 sb_check.urls.push_back(queued.url);
408 sb_check.client = queued.client; 437 sb_check.client = queued.client;
409 sb_check.threat_type = SB_THREAT_TYPE_SAFE;
410 queued.client->OnSafeBrowsingResult(sb_check); 438 queued.client->OnSafeBrowsingResult(sb_check);
411 } 439 }
412 queued_checks_.pop_front(); 440 queued_checks_.pop_front();
413 } 441 }
414 442
415 // Close the database. We don't simply DeleteSoon() because if a close is 443 // Close the database. We don't simply DeleteSoon() because if a close is
416 // already pending, we'll double-free, and we don't set |database_| to NULL 444 // already pending, we'll double-free, and we don't set |database_| to NULL
417 // because if there is still anything running on the db thread, it could 445 // because if there is still anything running on the db thread, it could
418 // create a new database object (via GetDatabase()) that would then leak. 446 // create a new database object (via GetDatabase()) that would then leak.
419 CloseDatabase(); 447 CloseDatabase();
(...skipping 11 matching lines...) Expand all
431 safe_browsing_thread_.reset(); 459 safe_browsing_thread_.reset();
432 } 460 }
433 461
434 // Delete pending checks, calling back any clients with 'SB_THREAT_TYPE_SAFE'. 462 // Delete pending checks, calling back any clients with 'SB_THREAT_TYPE_SAFE'.
435 // We have to do this after the db thread returns because methods on it can 463 // We have to do this after the db thread returns because methods on it can
436 // have copies of these pointers, so deleting them might lead to accessing 464 // have copies of these pointers, so deleting them might lead to accessing
437 // garbage. 465 // garbage.
438 for (CurrentChecks::iterator it = checks_.begin(); 466 for (CurrentChecks::iterator it = checks_.begin();
439 it != checks_.end(); ++it) { 467 it != checks_.end(); ++it) {
440 SafeBrowsingCheck* check = *it; 468 SafeBrowsingCheck* check = *it;
441 if (check->client) { 469 if (check->client)
442 check->threat_type = SB_THREAT_TYPE_SAFE;
443 check->client->OnSafeBrowsingResult(*check); 470 check->client->OnSafeBrowsingResult(*check);
444 }
445 } 471 }
446 STLDeleteElements(&checks_); 472 STLDeleteElements(&checks_);
447 473
448 gethash_requests_.clear(); 474 gethash_requests_.clear();
449 } 475 }
450 476
451 bool SafeBrowsingDatabaseManager::DatabaseAvailable() const { 477 bool SafeBrowsingDatabaseManager::DatabaseAvailable() const {
452 base::AutoLock lock(database_lock_); 478 base::AutoLock lock(database_lock_);
453 return !closing_database_ && (database_ != NULL); 479 return !closing_database_ && (database_ != NULL);
454 } 480 }
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
554 GetHashRequestors requestors; 580 GetHashRequestors requestors;
555 requestors.push_back(check); 581 requestors.push_back(check);
556 gethash_requests_[prefix] = requestors; 582 gethash_requests_[prefix] = requestors;
557 } 583 }
558 584
559 // Reset the start time so that we can measure the network time without the 585 // Reset the start time so that we can measure the network time without the
560 // database time. 586 // database time.
561 check->start = base::TimeTicks::Now(); 587 check->start = base::TimeTicks::Now();
562 // Note: If |this| is deleted or stopped, the protocol_manager will 588 // Note: If |this| is deleted or stopped, the protocol_manager will
563 // be destroyed as well - hence it's OK to do unretained in this case. 589 // be destroyed as well - hence it's OK to do unretained in this case.
590 bool is_download = check->check_type == safe_browsing_util::BINURL ||
591 check->check_type == safe_browsing_util::BINHASH;
564 sb_service_->protocol_manager()->GetFullHash( 592 sb_service_->protocol_manager()->GetFullHash(
565 check->prefix_hits, 593 check->prefix_hits,
566 base::Bind(&SafeBrowsingDatabaseManager::HandleGetHashResults, 594 base::Bind(&SafeBrowsingDatabaseManager::HandleGetHashResults,
567 base::Unretained(this), 595 base::Unretained(this),
568 check), 596 check),
569 check->is_download); 597 is_download);
570 } else { 598 } else {
571 // We may have cached results for previous GetHash queries. Since 599 // We may have cached results for previous GetHash queries. Since
572 // this data comes from cache, don't histogram hits. 600 // this data comes from cache, don't histogram hits.
573 HandleOneCheck(check, check->full_hits); 601 HandleOneCheck(check, check->full_hits);
574 } 602 }
575 } 603 }
576 604
577 void SafeBrowsingDatabaseManager::GetAllChunksFromDatabase( 605 void SafeBrowsingDatabaseManager::GetAllChunksFromDatabase(
578 GetChunksCallback callback) { 606 GetChunksCallback callback) {
579 DCHECK_EQ(MessageLoop::current(), safe_browsing_thread_->message_loop()); 607 DCHECK_EQ(MessageLoop::current(), safe_browsing_thread_->message_loop());
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
623 // below will add the check back to the queue, and we'll infinite-loop. 651 // below will add the check back to the queue, and we'll infinite-loop.
624 DCHECK(DatabaseAvailable()); 652 DCHECK(DatabaseAvailable());
625 while (!queued_checks_.empty()) { 653 while (!queued_checks_.empty()) {
626 QueuedCheck check = queued_checks_.front(); 654 QueuedCheck check = queued_checks_.front();
627 DCHECK(!check.start.is_null()); 655 DCHECK(!check.start.is_null());
628 HISTOGRAM_TIMES("SB.QueueDelay", base::TimeTicks::Now() - check.start); 656 HISTOGRAM_TIMES("SB.QueueDelay", base::TimeTicks::Now() - check.start);
629 // If CheckUrl() determines the URL is safe immediately, it doesn't call the 657 // If CheckUrl() determines the URL is safe immediately, it doesn't call the
630 // client's handler function (because normally it's being directly called by 658 // client's handler function (because normally it's being directly called by
631 // the client). Since we're not the client, we have to convey this result. 659 // the client). Since we're not the client, we have to convey this result.
632 if (check.client && CheckBrowseUrl(check.url, check.client)) { 660 if (check.client && CheckBrowseUrl(check.url, check.client)) {
633 SafeBrowsingCheck sb_check; 661 SafeBrowsingCheck sb_check(check.check_type);
634 sb_check.urls.push_back(check.url); 662 sb_check.urls.push_back(check.url);
635 sb_check.client = check.client; 663 sb_check.client = check.client;
636 sb_check.threat_type = SB_THREAT_TYPE_SAFE;
637 check.client->OnSafeBrowsingResult(sb_check); 664 check.client->OnSafeBrowsingResult(sb_check);
638 } 665 }
639 queued_checks_.pop_front(); 666 queued_checks_.pop_front();
640 } 667 }
641 } 668 }
642 669
643 void SafeBrowsingDatabaseManager::AddDatabaseChunks( 670 void SafeBrowsingDatabaseManager::AddDatabaseChunks(
644 const std::string& list_name, SBChunkList* chunks, 671 const std::string& list_name, SBChunkList* chunks,
645 AddChunksCallback callback) { 672 AddChunksCallback callback) {
646 DCHECK_EQ(MessageLoop::current(), safe_browsing_thread_->message_loop()); 673 DCHECK_EQ(MessageLoop::current(), safe_browsing_thread_->message_loop());
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
731 const std::vector<SBPrefix>& prefixes, 758 const std::vector<SBPrefix>& prefixes,
732 const std::vector<SBFullHashResult>& full_hashes) { 759 const std::vector<SBFullHashResult>& full_hashes) {
733 DCHECK_EQ(MessageLoop::current(), safe_browsing_thread_->message_loop()); 760 DCHECK_EQ(MessageLoop::current(), safe_browsing_thread_->message_loop());
734 GetDatabase()->CacheHashResults(prefixes, full_hashes); 761 GetDatabase()->CacheHashResults(prefixes, full_hashes);
735 } 762 }
736 763
737 void SafeBrowsingDatabaseManager::OnHandleGetHashResults( 764 void SafeBrowsingDatabaseManager::OnHandleGetHashResults(
738 SafeBrowsingCheck* check, 765 SafeBrowsingCheck* check,
739 const std::vector<SBFullHashResult>& full_hashes) { 766 const std::vector<SBFullHashResult>& full_hashes) {
740 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 767 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
741 bool is_download = check->is_download; 768 safe_browsing_util::ListType check_type = check->check_type;
742 SBPrefix prefix = check->prefix_hits[0]; 769 SBPrefix prefix = check->prefix_hits[0];
743 GetHashRequests::iterator it = gethash_requests_.find(prefix); 770 GetHashRequests::iterator it = gethash_requests_.find(prefix);
744 if (check->prefix_hits.size() > 1 || it == gethash_requests_.end()) { 771 if (check->prefix_hits.size() > 1 || it == gethash_requests_.end()) {
745 const bool hit = HandleOneCheck(check, full_hashes); 772 const bool hit = HandleOneCheck(check, full_hashes);
746 RecordGetHashCheckStatus(hit, is_download, full_hashes); 773 RecordGetHashCheckStatus(hit, check_type, full_hashes);
747 return; 774 return;
748 } 775 }
749 776
750 // Call back all interested parties, noting if any has a hit. 777 // Call back all interested parties, noting if any has a hit.
751 GetHashRequestors& requestors = it->second; 778 GetHashRequestors& requestors = it->second;
752 bool hit = false; 779 bool hit = false;
753 for (GetHashRequestors::iterator r = requestors.begin(); 780 for (GetHashRequestors::iterator r = requestors.begin();
754 r != requestors.end(); ++r) { 781 r != requestors.end(); ++r) {
755 if (HandleOneCheck(*r, full_hashes)) 782 if (HandleOneCheck(*r, full_hashes))
756 hit = true; 783 hit = true;
757 } 784 }
758 RecordGetHashCheckStatus(hit, is_download, full_hashes); 785 RecordGetHashCheckStatus(hit, check_type, full_hashes);
759 786
760 gethash_requests_.erase(it); 787 gethash_requests_.erase(it);
761 } 788 }
762 789
763 bool SafeBrowsingDatabaseManager::HandleOneCheck( 790 bool SafeBrowsingDatabaseManager::HandleOneCheck(
764 SafeBrowsingCheck* check, 791 SafeBrowsingCheck* check,
765 const std::vector<SBFullHashResult>& full_hashes) { 792 const std::vector<SBFullHashResult>& full_hashes) {
766 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 793 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
767 DCHECK(check); 794 DCHECK(check);
768 795
769 // Always calculate the index, for recording hits. 796 for (std::vector<GURL>::iterator it = check->urls.begin();
770 int index = -1; 797 it != check->urls.end(); ++it) {
771 if (!check->urls.empty()) { 798 int index = safe_browsing_util::GetUrlHashIndex(*it, full_hashes);
772 for (size_t i = 0; i < check->urls.size(); ++i) { 799 if (index == -1)
773 index = safe_browsing_util::GetUrlHashIndex(check->urls[i], full_hashes); 800 continue;
774 if (index != -1) 801 SBThreatType threat =
775 break; 802 GetThreatTypeFromListname(full_hashes[index].list_name);
776 } 803 if (threat != SB_THREAT_TYPE_SAFE)
777 } else { 804 check->url_threats[*it] = threat;
778 index = safe_browsing_util::GetHashIndex(*(check->full_hash), full_hashes); 805 else
806 NOTREACHED();
779 } 807 }
780 808
781 // |client| is NULL if the request was cancelled. 809 for (std::vector<SBFullHash>::iterator it = check->full_hashes.begin();
782 if (check->client) { 810 it != check->full_hashes.end(); ++it) {
783 check->threat_type = SB_THREAT_TYPE_SAFE; 811 int index = safe_browsing_util::GetHashIndex(*it, full_hashes);
784 if (index != -1) { 812 if (index == -1)
785 check->threat_type = GetThreatTypeFromListname( 813 continue;
786 full_hashes[index].list_name); 814 SBThreatType threat =
787 } 815 GetThreatTypeFromListname(full_hashes[index].list_name);
816 if (threat != SB_THREAT_TYPE_SAFE)
817 check->full_hash_threats[*it] = threat;
818 else
819 NOTREACHED();
788 } 820 }
821
789 SafeBrowsingCheckDone(check); 822 SafeBrowsingCheckDone(check);
790 return (index != -1); 823 return check->url_threats.empty() && check->full_hash_threats.empty();
791 } 824 }
792 825
793 void SafeBrowsingDatabaseManager::CheckDownloadHashOnSBThread( 826 void SafeBrowsingDatabaseManager::CheckDownloadHashOnSBThread(
794 SafeBrowsingCheck* check) { 827 SafeBrowsingCheck* check) {
795 DCHECK_EQ(MessageLoop::current(), safe_browsing_thread_->message_loop()); 828 DCHECK_EQ(MessageLoop::current(), safe_browsing_thread_->message_loop());
796 DCHECK(enable_download_protection_); 829 DCHECK(enable_download_protection_);
797 830
798 if (!database_->ContainsDownloadHashPrefix(check->full_hash->prefix)) { 831 DCHECK_EQ(1u, check->full_hashes.size());
832 SBFullHash full_hash = check->full_hashes[0];
833
834 if (!database_->ContainsDownloadHashPrefix(full_hash.prefix)) {
799 // Good, we don't have hash for this url prefix. 835 // Good, we don't have hash for this url prefix.
800 check->threat_type = SB_THREAT_TYPE_SAFE;
801 BrowserThread::PostTask( 836 BrowserThread::PostTask(
802 BrowserThread::IO, FROM_HERE, 837 BrowserThread::IO, FROM_HERE,
803 base::Bind(&SafeBrowsingDatabaseManager::CheckDownloadHashDone, this, 838 base::Bind(&SafeBrowsingDatabaseManager::CheckDownloadHashDone, this,
804 check)); 839 check));
805 return; 840 return;
806 } 841 }
807 842
808 check->need_get_hash = true; 843 check->need_get_hash = true;
809 check->prefix_hits.push_back(check->full_hash->prefix); 844 check->prefix_hits.push_back(full_hash.prefix);
810 BrowserThread::PostTask( 845 BrowserThread::PostTask(
811 BrowserThread::IO, FROM_HERE, 846 BrowserThread::IO, FROM_HERE,
812 base::Bind(&SafeBrowsingDatabaseManager::OnCheckDone, this, check)); 847 base::Bind(&SafeBrowsingDatabaseManager::OnCheckDone, this, check));
813 } 848 }
814 849
815 void SafeBrowsingDatabaseManager::CheckDownloadUrlOnSBThread( 850 void SafeBrowsingDatabaseManager::CheckDownloadUrlOnSBThread(
816 SafeBrowsingCheck* check) { 851 SafeBrowsingCheck* check) {
817 DCHECK_EQ(MessageLoop::current(), safe_browsing_thread_->message_loop()); 852 DCHECK_EQ(MessageLoop::current(), safe_browsing_thread_->message_loop());
818 DCHECK(enable_download_protection_); 853 DCHECK(enable_download_protection_);
819 854
820 std::vector<SBPrefix> prefix_hits; 855 std::vector<SBPrefix> prefix_hits;
821 856
822 if (!database_->ContainsDownloadUrl(check->urls, &prefix_hits)) { 857 if (!database_->ContainsDownloadUrl(check->urls, &prefix_hits)) {
823 // Good, we don't have hash for this url prefix. 858 // Good, we don't have hash for this url prefix.
824 check->threat_type = SB_THREAT_TYPE_SAFE;
825 BrowserThread::PostTask( 859 BrowserThread::PostTask(
826 BrowserThread::IO, FROM_HERE, 860 BrowserThread::IO, FROM_HERE,
827 base::Bind(&SafeBrowsingDatabaseManager::CheckDownloadUrlDone, this, 861 base::Bind(&SafeBrowsingDatabaseManager::CheckDownloadUrlDone, this,
828 check)); 862 check));
829 return; 863 return;
830 } 864 }
831 865
832 check->need_get_hash = true; 866 check->need_get_hash = true;
833 check->prefix_hits.clear(); 867 check->prefix_hits.clear();
834 check->prefix_hits = prefix_hits; 868 check->prefix_hits = prefix_hits;
835 BrowserThread::PostTask( 869 BrowserThread::PostTask(
836 BrowserThread::IO, FROM_HERE, 870 BrowserThread::IO, FROM_HERE,
837 base::Bind(&SafeBrowsingDatabaseManager::OnCheckDone, this, check)); 871 base::Bind(&SafeBrowsingDatabaseManager::OnCheckDone, this, check));
838 } 872 }
839 873
840 void SafeBrowsingDatabaseManager::TimeoutCallback(SafeBrowsingCheck* check) { 874 void SafeBrowsingDatabaseManager::TimeoutCallback(SafeBrowsingCheck* check) {
841 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 875 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
842 DCHECK(check); 876 DCHECK(check);
843 877
844 if (!enabled_) 878 if (!enabled_)
845 return; 879 return;
846 880
847 DCHECK(checks_.find(check) != checks_.end()); 881 DCHECK(checks_.find(check) != checks_.end());
848 DCHECK_EQ(check->threat_type, SB_THREAT_TYPE_SAFE);
849 if (check->client) { 882 if (check->client) {
850 check->client->OnSafeBrowsingResult(*check); 883 check->client->OnSafeBrowsingResult(*check);
851 check->client = NULL; 884 check->client = NULL;
852 } 885 }
853 } 886 }
854 887
855 void SafeBrowsingDatabaseManager::CheckDownloadUrlDone( 888 void SafeBrowsingDatabaseManager::CheckDownloadUrlDone(
856 SafeBrowsingCheck* check) { 889 SafeBrowsingCheck* check) {
857 DCHECK(enable_download_protection_); 890 DCHECK(enable_download_protection_);
858 SafeBrowsingCheckDone(check); 891 SafeBrowsingCheckDone(check);
859 } 892 }
860 893
861 void SafeBrowsingDatabaseManager::CheckDownloadHashDone( 894 void SafeBrowsingDatabaseManager::CheckDownloadHashDone(
862 SafeBrowsingCheck* check) { 895 SafeBrowsingCheck* check) {
863 DCHECK(enable_download_protection_); 896 DCHECK(enable_download_protection_);
864 SafeBrowsingCheckDone(check); 897 SafeBrowsingCheckDone(check);
865 } 898 }
866 899
867 void SafeBrowsingDatabaseManager::SafeBrowsingCheckDone( 900 void SafeBrowsingDatabaseManager::SafeBrowsingCheckDone(
868 SafeBrowsingCheck* check) { 901 SafeBrowsingCheck* check) {
869 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 902 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
870 DCHECK(check); 903 DCHECK(check);
871 904
872 if (!enabled_) 905 if (!enabled_)
873 return; 906 return;
874 907
875 VLOG(1) << "SafeBrowsingCheckDone: " << check->threat_type; 908 VLOG(1) << "SafeBrowsingCheckDone: " <<
909 check->url_threats.size() << " URL hits, " <<
910 check->full_hash_threats.size() << " hash hits";
876 DCHECK(checks_.find(check) != checks_.end()); 911 DCHECK(checks_.find(check) != checks_.end());
877 if (check->client) 912 if (check->client)
878 check->client->OnSafeBrowsingResult(*check); 913 check->client->OnSafeBrowsingResult(*check);
879 checks_.erase(check); 914 checks_.erase(check);
880 delete check; 915 delete check;
881 } 916 }
882 917
883 void SafeBrowsingDatabaseManager::StartDownloadCheck(SafeBrowsingCheck* check, 918 void SafeBrowsingDatabaseManager::StartSafeBrowsingCheck(
884 Client* client, 919 SafeBrowsingCheck* check,
885 const base::Closure& task, 920 Client* client,
886 int64 timeout_ms) { 921 const base::Closure& task,
887 922 const base::TimeDelta& timeout) {
888 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 923 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
889 check->client = client; 924 check->client = client;
890 check->threat_type = SB_THREAT_TYPE_SAFE;
891 check->is_download = true;
892 check->timeout_factory_.reset( 925 check->timeout_factory_.reset(
893 new base::WeakPtrFactory<SafeBrowsingDatabaseManager>(this)); 926 new base::WeakPtrFactory<SafeBrowsingDatabaseManager>(this));
894 checks_.insert(check); 927 checks_.insert(check);
895 928
896 safe_browsing_thread_->message_loop()->PostTask(FROM_HERE, task); 929 safe_browsing_thread_->message_loop()->PostTask(FROM_HERE, task);
897 930
898 MessageLoop::current()->PostDelayedTask(FROM_HERE, 931 MessageLoop::current()->PostDelayedTask(FROM_HERE,
899 base::Bind(&SafeBrowsingDatabaseManager::TimeoutCallback, 932 base::Bind(&SafeBrowsingDatabaseManager::TimeoutCallback,
900 check->timeout_factory_->GetWeakPtr(), check), 933 check->timeout_factory_->GetWeakPtr(), check),
901 base::TimeDelta::FromMilliseconds(timeout_ms)); 934 timeout);
902 } 935 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698