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

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: cleanup Created 8 years 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 }
59 SafeBrowsingProtocolManager::RecordGetHashResult(is_download, result); 55 SafeBrowsingProtocolManager::RecordGetHashResult(check_type, result);
60 } 56 }
61 57
62 } // namespace 58 } // namespace
63 59
64 SafeBrowsingDatabaseManager::SafeBrowsingCheck::SafeBrowsingCheck() 60 SafeBrowsingDatabaseManager::SafeBrowsingCheck::SafeBrowsingCheck(
65 : full_hash(NULL), 61 safe_browsing_util::ListType check_type)
66 client(NULL), 62 : client(NULL),
67 need_get_hash(false), 63 need_get_hash(false),
68 threat_type(SB_THREAT_TYPE_SAFE), 64 check_type(check_type),
69 is_download(false),
70 timeout_factory_(NULL) { 65 timeout_factory_(NULL) {
71 } 66 }
72 67
73 SafeBrowsingDatabaseManager::SafeBrowsingCheck::~SafeBrowsingCheck() {} 68 SafeBrowsingDatabaseManager::SafeBrowsingCheck::~SafeBrowsingCheck() {}
74 69
75 void SafeBrowsingDatabaseManager::Client::OnSafeBrowsingResult( 70 void SafeBrowsingDatabaseManager::Client::OnSafeBrowsingResult(
76 const SafeBrowsingCheck& check) { 71 const SafeBrowsingCheck& check) {
77 if (!check.urls.empty()) { 72 if (!check.urls.empty()) {
78 73 DCHECK(check.full_hashes.empty());
79 DCHECK(!check.full_hash.get()); 74 switch (check.check_type) {
80 if (!check.is_download) { 75 case safe_browsing_util::MALWARE:
81 DCHECK_EQ(1U, check.urls.size()); 76 case safe_browsing_util::PHISH:
82 OnCheckBrowseUrlResult(check.urls[0], check.threat_type); 77 DCHECK_EQ(1U, check.urls.size());
83 } else { 78 OnCheckBrowseUrlResult(
84 OnCheckDownloadUrlResult(check.urls, check.threat_type); 79 check.urls[0],
80 check.url_threats.empty() ? SB_THREAT_TYPE_SAFE
81 : check.url_threats.begin()->second);
82 break;
83 case safe_browsing_util::BINURL:
84 OnCheckDownloadUrlResult(
85 check.urls,
86 check.url_threats.empty() ? SB_THREAT_TYPE_SAFE
87 : SB_THREAT_TYPE_BINARY_MALWARE_URL);
88 break;
89 default:
90 NOTREACHED();
85 } 91 }
86 } else if (check.full_hash.get()) { 92 } else if (!check.full_hashes.empty()) {
87 OnCheckDownloadHashResult( 93 switch (check.check_type) {
88 safe_browsing_util::SBFullHashToString(*check.full_hash), 94 case safe_browsing_util::BINHASH:
89 check.threat_type); 95 DCHECK_EQ(1u, check.full_hashes.size());
96 OnCheckDownloadHashResult(
97 safe_browsing_util::SBFullHashToString(check.full_hashes[0]),
98 check.full_hash_threats.empty()
99 ? SB_THREAT_TYPE_SAFE
100 : SB_THREAT_TYPE_BINARY_MALWARE_HASH);
101 break;
102 default:
103 NOTREACHED();
104 }
90 } else { 105 } else {
91 NOTREACHED(); 106 NOTREACHED();
92 } 107 }
93 } 108 }
94 109
95 SafeBrowsingDatabaseManager::SafeBrowsingDatabaseManager( 110 SafeBrowsingDatabaseManager::SafeBrowsingDatabaseManager(
96 const scoped_refptr<SafeBrowsingService>& service) 111 const scoped_refptr<SafeBrowsingService>& service)
97 : sb_service_(service), 112 : sb_service_(service),
98 database_(NULL), 113 database_(NULL),
99 enabled_(false), 114 enabled_(false),
100 enable_download_protection_(false), 115 enable_download_protection_(false),
101 enable_csd_whitelist_(false), 116 enable_csd_whitelist_(false),
102 enable_download_whitelist_(false), 117 enable_download_whitelist_(false),
103 update_in_progress_(false), 118 update_in_progress_(false),
104 database_update_in_progress_(false), 119 database_update_in_progress_(false),
105 closing_database_(false), 120 closing_database_(false),
106 download_urlcheck_timeout_ms_(kDownloadUrlCheckTimeoutMs), 121 download_url_check_timeout_(
107 download_hashcheck_timeout_ms_(kDownloadHashCheckTimeoutMs) { 122 base::TimeDelta::FromMilliseconds(kCheckTimeoutMs)),
123 download_hash_check_timeout_(
124 base::TimeDelta::FromMilliseconds(kCheckTimeoutMs)) {
108 DCHECK(sb_service_ != NULL); 125 DCHECK(sb_service_ != NULL);
109 126
110 CommandLine* cmdline = CommandLine::ForCurrentProcess(); 127 CommandLine* cmdline = CommandLine::ForCurrentProcess();
111 enable_download_protection_ = 128 enable_download_protection_ =
112 !cmdline->HasSwitch(switches::kSbDisableDownloadProtection); 129 !cmdline->HasSwitch(switches::kSbDisableDownloadProtection);
113 130
114 // We only download the csd-whitelist if client-side phishing detection is 131 // We only download the csd-whitelist if client-side phishing detection is
115 // enabled. 132 // enabled.
116 enable_csd_whitelist_ = 133 enable_csd_whitelist_ =
117 !cmdline->HasSwitch(switches::kDisableClientSidePhishingDetection); 134 !cmdline->HasSwitch(switches::kDisableClientSidePhishingDetection);
118 135
119 // TODO(noelutz): remove this boolean variable since it should always be true 136 // 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 137 // 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 138 // list right now. This means that we need to be able to disable this list
122 // for the SafeBrowsing test to pass. 139 // for the SafeBrowsing test to pass.
123 enable_download_whitelist_ = enable_csd_whitelist_; 140 enable_download_whitelist_ = enable_csd_whitelist_;
124
125 } 141 }
126 142
127 SafeBrowsingDatabaseManager::~SafeBrowsingDatabaseManager() { 143 SafeBrowsingDatabaseManager::~SafeBrowsingDatabaseManager() {
128 // We should have already been shut down. If we're still enabled, then the 144 // 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. 145 // database isn't going to be closed properly, which could lead to corruption.
130 DCHECK(!enabled_); 146 DCHECK(!enabled_);
131 } 147 }
132 148
133 bool SafeBrowsingDatabaseManager::CanCheckUrl(const GURL& url) const { 149 bool SafeBrowsingDatabaseManager::CanCheckUrl(const GURL& url) const {
134 return url.SchemeIs(chrome::kFtpScheme) || 150 return url.SchemeIs(chrome::kFtpScheme) ||
135 url.SchemeIs(chrome::kHttpScheme) || 151 url.SchemeIs(chrome::kHttpScheme) ||
136 url.SchemeIs(chrome::kHttpsScheme); 152 url.SchemeIs(chrome::kHttpsScheme);
137 } 153 }
138 154
139 bool SafeBrowsingDatabaseManager::CheckDownloadUrl( 155 bool SafeBrowsingDatabaseManager::CheckDownloadUrl(
140 const std::vector<GURL>& url_chain, 156 const std::vector<GURL>& url_chain,
141 Client* client) { 157 Client* client) {
142 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 158 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
143 if (!enabled_ || !enable_download_protection_) 159 if (!enabled_ || !enable_download_protection_)
144 return true; 160 return true;
145 161
146 // We need to check the database for url prefix, and later may fetch the url 162 // 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. 163 // from the safebrowsing backends. These need to be asynchronous.
148 SafeBrowsingCheck* check = new SafeBrowsingCheck(); 164 SafeBrowsingCheck* check = new SafeBrowsingCheck(safe_browsing_util::BINURL);
149 check->urls = url_chain; 165 check->urls = url_chain;
150 StartDownloadCheck( 166 StartSafeBrowsingCheck(
151 check, 167 check,
152 client, 168 client,
153 base::Bind(&SafeBrowsingDatabaseManager::CheckDownloadUrlOnSBThread, this, 169 base::Bind(&SafeBrowsingDatabaseManager::CheckDownloadUrlOnSBThread, this,
154 check), 170 check),
155 download_urlcheck_timeout_ms_); 171 download_url_check_timeout_);
156 return false; 172 return false;
157 } 173 }
158 174
159 bool SafeBrowsingDatabaseManager::CheckDownloadHash( 175 bool SafeBrowsingDatabaseManager::CheckDownloadHash(
160 const std::string& full_hash, 176 const std::string& full_hash,
161 Client* client) { 177 Client* client) {
162 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 178 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
163 DCHECK(!full_hash.empty()); 179 DCHECK(!full_hash.empty());
164 if (!enabled_ || !enable_download_protection_ || full_hash.empty()) 180 if (!enabled_ || !enable_download_protection_ || full_hash.empty())
165 return true; 181 return true;
166 182
167 // We need to check the database for url prefix, and later may fetch the url 183 // 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. 184 // from the safebrowsing backends. These need to be asynchronous.
169 SafeBrowsingCheck* check = new SafeBrowsingCheck(); 185 SafeBrowsingCheck* check = new SafeBrowsingCheck(safe_browsing_util::BINHASH);
170 check->full_hash.reset(new SBFullHash); 186 SBFullHash sb_hash;
171 safe_browsing_util::StringToSBFullHash(full_hash, check->full_hash.get()); 187 safe_browsing_util::StringToSBFullHash(full_hash, &sb_hash);
172 StartDownloadCheck( 188 check->full_hashes.push_back(sb_hash);
189 StartSafeBrowsingCheck(
173 check, 190 check,
174 client, 191 client,
175 base::Bind(&SafeBrowsingDatabaseManager::CheckDownloadHashOnSBThread,this, 192 base::Bind(&SafeBrowsingDatabaseManager::CheckDownloadHashOnSBThread,this,
176 check), 193 check),
177 download_hashcheck_timeout_ms_); 194 download_hash_check_timeout_);
178 return false; 195 return false;
179 } 196 }
180 197
181 bool SafeBrowsingDatabaseManager::MatchCsdWhitelistUrl(const GURL& url) { 198 bool SafeBrowsingDatabaseManager::MatchCsdWhitelistUrl(const GURL& url) {
182 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 199 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
183 if (!enabled_ || !enable_csd_whitelist_ || !MakeDatabaseAvailable()) { 200 if (!enabled_ || !enable_csd_whitelist_ || !MakeDatabaseAvailable()) {
184 // There is something funky going on here -- for example, perhaps the user 201 // There is something funky going on here -- for example, perhaps the user
185 // has not restarted since enabling metrics reporting, so we haven't 202 // 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 203 // enabled the csd whitelist yet. Just to be safe we return true in this
187 // case. 204 // case.
(...skipping 24 matching lines...) Expand all
212 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 229 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
213 if (!enabled_) 230 if (!enabled_)
214 return true; 231 return true;
215 232
216 if (!CanCheckUrl(url)) 233 if (!CanCheckUrl(url))
217 return true; 234 return true;
218 235
219 const base::TimeTicks start = base::TimeTicks::Now(); 236 const base::TimeTicks start = base::TimeTicks::Now();
220 if (!MakeDatabaseAvailable()) { 237 if (!MakeDatabaseAvailable()) {
221 QueuedCheck check; 238 QueuedCheck check;
239 check.check_type = safe_browsing_util::MALWARE; // or PHISH
222 check.client = client; 240 check.client = client;
223 check.url = url; 241 check.url = url;
224 check.start = start; 242 check.start = start;
225 queued_checks_.push_back(check); 243 queued_checks_.push_back(check);
226 return false; 244 return false;
227 } 245 }
228 246
229 std::string list; 247 std::string list;
230 std::vector<SBPrefix> prefix_hits; 248 std::vector<SBPrefix> prefix_hits;
231 std::vector<SBFullHashResult> full_hits; 249 std::vector<SBFullHashResult> full_hits;
232 250
233 bool prefix_match = 251 bool prefix_match =
234 database_->ContainsBrowseUrl(url, &list, &prefix_hits, &full_hits, 252 database_->ContainsBrowseUrl(url, &list, &prefix_hits, &full_hits,
235 sb_service_->protocol_manager()->last_update()); 253 sb_service_->protocol_manager()->last_update());
236 254
237 UMA_HISTOGRAM_TIMES("SB2.FilterCheck", base::TimeTicks::Now() - start); 255 UMA_HISTOGRAM_TIMES("SB2.FilterCheck", base::TimeTicks::Now() - start);
238 256
239 if (!prefix_match) 257 if (!prefix_match)
240 return true; // URL is okay. 258 return true; // URL is okay.
241 259
242 // Needs to be asynchronous, since we could be in the constructor of a 260 // Needs to be asynchronous, since we could be in the constructor of a
243 // ResourceDispatcherHost event handler which can't pause there. 261 // ResourceDispatcherHost event handler which can't pause there.
244 SafeBrowsingCheck* check = new SafeBrowsingCheck(); 262 SafeBrowsingCheck* check =
263 new SafeBrowsingCheck(safe_browsing_util::MALWARE); // or PHISH
245 check->urls.push_back(url); 264 check->urls.push_back(url);
246 check->client = client; 265 check->client = client;
247 check->threat_type = SB_THREAT_TYPE_SAFE;
248 check->is_download = false;
249 check->need_get_hash = full_hits.empty(); 266 check->need_get_hash = full_hits.empty();
250 check->prefix_hits.swap(prefix_hits); 267 check->prefix_hits.swap(prefix_hits);
251 check->full_hits.swap(full_hits); 268 check->full_hits.swap(full_hits);
252 checks_.insert(check); 269 checks_.insert(check);
253 270
254 BrowserThread::PostTask( 271 BrowserThread::PostTask(
255 BrowserThread::IO, FROM_HERE, 272 BrowserThread::IO, FROM_HERE,
256 base::Bind(&SafeBrowsingDatabaseManager::OnCheckDone, this, check)); 273 base::Bind(&SafeBrowsingDatabaseManager::OnCheckDone, this, check));
257 274
258 return false; 275 return false;
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
394 if (!enabled_) 411 if (!enabled_)
395 return; 412 return;
396 413
397 enabled_ = false; 414 enabled_ = false;
398 415
399 // Delete queued checks, calling back any clients with 'SB_THREAT_TYPE_SAFE'. 416 // Delete queued checks, calling back any clients with 'SB_THREAT_TYPE_SAFE'.
400 // If we don't do this here we may fail to close the database below. 417 // If we don't do this here we may fail to close the database below.
401 while (!queued_checks_.empty()) { 418 while (!queued_checks_.empty()) {
402 QueuedCheck queued = queued_checks_.front(); 419 QueuedCheck queued = queued_checks_.front();
403 if (queued.client) { 420 if (queued.client) {
404 SafeBrowsingCheck sb_check; 421 SafeBrowsingCheck sb_check(queued.check_type);
405 sb_check.urls.push_back(queued.url); 422 sb_check.urls.push_back(queued.url);
406 sb_check.client = queued.client; 423 sb_check.client = queued.client;
407 sb_check.threat_type = SB_THREAT_TYPE_SAFE;
408 queued.client->OnSafeBrowsingResult(sb_check); 424 queued.client->OnSafeBrowsingResult(sb_check);
409 } 425 }
410 queued_checks_.pop_front(); 426 queued_checks_.pop_front();
411 } 427 }
412 428
413 // Close the database. We don't simply DeleteSoon() because if a close is 429 // Close the database. We don't simply DeleteSoon() because if a close is
414 // already pending, we'll double-free, and we don't set |database_| to NULL 430 // already pending, we'll double-free, and we don't set |database_| to NULL
415 // because if there is still anything running on the db thread, it could 431 // because if there is still anything running on the db thread, it could
416 // create a new database object (via GetDatabase()) that would then leak. 432 // create a new database object (via GetDatabase()) that would then leak.
417 CloseDatabase(); 433 CloseDatabase();
(...skipping 11 matching lines...) Expand all
429 safe_browsing_thread_.reset(); 445 safe_browsing_thread_.reset();
430 } 446 }
431 447
432 // Delete pending checks, calling back any clients with 'SB_THREAT_TYPE_SAFE'. 448 // Delete pending checks, calling back any clients with 'SB_THREAT_TYPE_SAFE'.
433 // We have to do this after the db thread returns because methods on it can 449 // We have to do this after the db thread returns because methods on it can
434 // have copies of these pointers, so deleting them might lead to accessing 450 // have copies of these pointers, so deleting them might lead to accessing
435 // garbage. 451 // garbage.
436 for (CurrentChecks::iterator it = checks_.begin(); 452 for (CurrentChecks::iterator it = checks_.begin();
437 it != checks_.end(); ++it) { 453 it != checks_.end(); ++it) {
438 SafeBrowsingCheck* check = *it; 454 SafeBrowsingCheck* check = *it;
439 if (check->client) { 455 if (check->client)
440 check->threat_type = SB_THREAT_TYPE_SAFE;
441 check->client->OnSafeBrowsingResult(*check); 456 check->client->OnSafeBrowsingResult(*check);
442 }
443 } 457 }
444 STLDeleteElements(&checks_); 458 STLDeleteElements(&checks_);
445 459
446 gethash_requests_.clear(); 460 gethash_requests_.clear();
447 } 461 }
448 462
449 bool SafeBrowsingDatabaseManager::DatabaseAvailable() const { 463 bool SafeBrowsingDatabaseManager::DatabaseAvailable() const {
450 base::AutoLock lock(database_lock_); 464 base::AutoLock lock(database_lock_);
451 return !closing_database_ && (database_ != NULL); 465 return !closing_database_ && (database_ != NULL);
452 } 466 }
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
552 GetHashRequestors requestors; 566 GetHashRequestors requestors;
553 requestors.push_back(check); 567 requestors.push_back(check);
554 gethash_requests_[prefix] = requestors; 568 gethash_requests_[prefix] = requestors;
555 } 569 }
556 570
557 // Reset the start time so that we can measure the network time without the 571 // Reset the start time so that we can measure the network time without the
558 // database time. 572 // database time.
559 check->start = base::TimeTicks::Now(); 573 check->start = base::TimeTicks::Now();
560 // Note: If |this| is deleted or stopped, the protocol_manager will 574 // Note: If |this| is deleted or stopped, the protocol_manager will
561 // be destroyed as well - hence it's OK to do unretained in this case. 575 // be destroyed as well - hence it's OK to do unretained in this case.
576 bool is_download = check->check_type == safe_browsing_util::BINURL ||
577 check->check_type == safe_browsing_util::BINHASH;
562 sb_service_->protocol_manager()->GetFullHash( 578 sb_service_->protocol_manager()->GetFullHash(
563 check->prefix_hits, 579 check->prefix_hits,
564 base::Bind(&SafeBrowsingDatabaseManager::HandleGetHashResults, 580 base::Bind(&SafeBrowsingDatabaseManager::HandleGetHashResults,
565 base::Unretained(this), 581 base::Unretained(this),
566 check), 582 check),
567 check->is_download); 583 is_download);
568 } else { 584 } else {
569 // We may have cached results for previous GetHash queries. Since 585 // We may have cached results for previous GetHash queries. Since
570 // this data comes from cache, don't histogram hits. 586 // this data comes from cache, don't histogram hits.
571 HandleOneCheck(check, check->full_hits); 587 HandleOneCheck(check, check->full_hits);
572 } 588 }
573 } 589 }
574 590
575 void SafeBrowsingDatabaseManager::GetAllChunksFromDatabase( 591 void SafeBrowsingDatabaseManager::GetAllChunksFromDatabase(
576 GetChunksCallback callback) { 592 GetChunksCallback callback) {
577 DCHECK_EQ(MessageLoop::current(), safe_browsing_thread_->message_loop()); 593 DCHECK_EQ(MessageLoop::current(), safe_browsing_thread_->message_loop());
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
620 // below will add the check back to the queue, and we'll infinite-loop. 636 // below will add the check back to the queue, and we'll infinite-loop.
621 DCHECK(DatabaseAvailable()); 637 DCHECK(DatabaseAvailable());
622 while (!queued_checks_.empty()) { 638 while (!queued_checks_.empty()) {
623 QueuedCheck check = queued_checks_.front(); 639 QueuedCheck check = queued_checks_.front();
624 DCHECK(!check.start.is_null()); 640 DCHECK(!check.start.is_null());
625 HISTOGRAM_TIMES("SB.QueueDelay", base::TimeTicks::Now() - check.start); 641 HISTOGRAM_TIMES("SB.QueueDelay", base::TimeTicks::Now() - check.start);
626 // If CheckUrl() determines the URL is safe immediately, it doesn't call the 642 // If CheckUrl() determines the URL is safe immediately, it doesn't call the
627 // client's handler function (because normally it's being directly called by 643 // client's handler function (because normally it's being directly called by
628 // the client). Since we're not the client, we have to convey this result. 644 // the client). Since we're not the client, we have to convey this result.
629 if (check.client && CheckBrowseUrl(check.url, check.client)) { 645 if (check.client && CheckBrowseUrl(check.url, check.client)) {
630 SafeBrowsingCheck sb_check; 646 SafeBrowsingCheck sb_check(check.check_type);
631 sb_check.urls.push_back(check.url); 647 sb_check.urls.push_back(check.url);
632 sb_check.client = check.client; 648 sb_check.client = check.client;
633 sb_check.threat_type = SB_THREAT_TYPE_SAFE;
634 check.client->OnSafeBrowsingResult(sb_check); 649 check.client->OnSafeBrowsingResult(sb_check);
635 } 650 }
636 queued_checks_.pop_front(); 651 queued_checks_.pop_front();
637 } 652 }
638 } 653 }
639 654
640 void SafeBrowsingDatabaseManager::HandleChunkForDatabase( 655 void SafeBrowsingDatabaseManager::HandleChunkForDatabase(
641 const std::string& list_name, SBChunkList* chunks) { 656 const std::string& list_name, SBChunkList* chunks) {
642 DCHECK_EQ(MessageLoop::current(), safe_browsing_thread_->message_loop()); 657 DCHECK_EQ(MessageLoop::current(), safe_browsing_thread_->message_loop());
643 if (chunks) { 658 if (chunks) {
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
726 const std::vector<SBPrefix>& prefixes, 741 const std::vector<SBPrefix>& prefixes,
727 const std::vector<SBFullHashResult>& full_hashes) { 742 const std::vector<SBFullHashResult>& full_hashes) {
728 DCHECK_EQ(MessageLoop::current(), safe_browsing_thread_->message_loop()); 743 DCHECK_EQ(MessageLoop::current(), safe_browsing_thread_->message_loop());
729 GetDatabase()->CacheHashResults(prefixes, full_hashes); 744 GetDatabase()->CacheHashResults(prefixes, full_hashes);
730 } 745 }
731 746
732 void SafeBrowsingDatabaseManager::OnHandleGetHashResults( 747 void SafeBrowsingDatabaseManager::OnHandleGetHashResults(
733 SafeBrowsingCheck* check, 748 SafeBrowsingCheck* check,
734 const std::vector<SBFullHashResult>& full_hashes) { 749 const std::vector<SBFullHashResult>& full_hashes) {
735 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 750 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
736 bool is_download = check->is_download; 751 safe_browsing_util::ListType check_type = check->check_type;
737 SBPrefix prefix = check->prefix_hits[0]; 752 SBPrefix prefix = check->prefix_hits[0];
738 GetHashRequests::iterator it = gethash_requests_.find(prefix); 753 GetHashRequests::iterator it = gethash_requests_.find(prefix);
739 if (check->prefix_hits.size() > 1 || it == gethash_requests_.end()) { 754 if (check->prefix_hits.size() > 1 || it == gethash_requests_.end()) {
740 const bool hit = HandleOneCheck(check, full_hashes); 755 const bool hit = HandleOneCheck(check, full_hashes);
741 RecordGetHashCheckStatus(hit, is_download, full_hashes); 756 RecordGetHashCheckStatus(hit, check_type, full_hashes);
742 return; 757 return;
743 } 758 }
744 759
745 // Call back all interested parties, noting if any has a hit. 760 // Call back all interested parties, noting if any has a hit.
746 GetHashRequestors& requestors = it->second; 761 GetHashRequestors& requestors = it->second;
747 bool hit = false; 762 bool hit = false;
748 for (GetHashRequestors::iterator r = requestors.begin(); 763 for (GetHashRequestors::iterator r = requestors.begin();
749 r != requestors.end(); ++r) { 764 r != requestors.end(); ++r) {
750 if (HandleOneCheck(*r, full_hashes)) 765 if (HandleOneCheck(*r, full_hashes))
751 hit = true; 766 hit = true;
752 } 767 }
753 RecordGetHashCheckStatus(hit, is_download, full_hashes); 768 RecordGetHashCheckStatus(hit, check_type, full_hashes);
754 769
755 gethash_requests_.erase(it); 770 gethash_requests_.erase(it);
756 } 771 }
757 772
758 bool SafeBrowsingDatabaseManager::HandleOneCheck( 773 bool SafeBrowsingDatabaseManager::HandleOneCheck(
759 SafeBrowsingCheck* check, 774 SafeBrowsingCheck* check,
760 const std::vector<SBFullHashResult>& full_hashes) { 775 const std::vector<SBFullHashResult>& full_hashes) {
761 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 776 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
762 DCHECK(check); 777 DCHECK(check);
763 778
764 // Always calculate the index, for recording hits. 779 for (std::vector<GURL>::iterator it = check->urls.begin();
765 int index = -1; 780 it != check->urls.end(); ++it) {
766 if (!check->urls.empty()) { 781 int index = safe_browsing_util::GetUrlHashIndex(*it, full_hashes);
767 for (size_t i = 0; i < check->urls.size(); ++i) { 782 if (index != -1) {
768 index = safe_browsing_util::GetUrlHashIndex(check->urls[i], full_hashes); 783 check->url_threats[*it] =
769 if (index != -1) 784 GetThreatTypeFromListname(full_hashes[index].list_name);
770 break;
771 } 785 }
772 } else {
773 index = safe_browsing_util::GetHashIndex(*(check->full_hash), full_hashes);
774 } 786 }
775 787
776 // |client| is NULL if the request was cancelled. 788 for (std::vector<SBFullHash>::iterator it = check->full_hashes.begin();
777 if (check->client) { 789 it != check->full_hashes.end(); ++it) {
778 check->threat_type = SB_THREAT_TYPE_SAFE; 790 int index = safe_browsing_util::GetHashIndex(*it, full_hashes);
779 if (index != -1) { 791 if (index != -1) {
780 check->threat_type = GetThreatTypeFromListname( 792 check->full_hash_threats[*it] =
781 full_hashes[index].list_name); 793 GetThreatTypeFromListname(full_hashes[index].list_name);
782 } 794 }
783 } 795 }
796
784 SafeBrowsingCheckDone(check); 797 SafeBrowsingCheckDone(check);
785 return (index != -1); 798 return check->url_threats.empty() && check->full_hash_threats.empty();
786 } 799 }
787 800
788 void SafeBrowsingDatabaseManager::CheckDownloadHashOnSBThread( 801 void SafeBrowsingDatabaseManager::CheckDownloadHashOnSBThread(
789 SafeBrowsingCheck* check) { 802 SafeBrowsingCheck* check) {
790 DCHECK_EQ(MessageLoop::current(), safe_browsing_thread_->message_loop()); 803 DCHECK_EQ(MessageLoop::current(), safe_browsing_thread_->message_loop());
791 DCHECK(enable_download_protection_); 804 DCHECK(enable_download_protection_);
792 805
793 if (!database_->ContainsDownloadHashPrefix(check->full_hash->prefix)) { 806 DCHECK_EQ(1u, check->full_hashes.size());
807 SBFullHash full_hash = check->full_hashes[0];
808
809 if (!database_->ContainsDownloadHashPrefix(full_hash.prefix)) {
794 // Good, we don't have hash for this url prefix. 810 // Good, we don't have hash for this url prefix.
795 check->threat_type = SB_THREAT_TYPE_SAFE;
796 BrowserThread::PostTask( 811 BrowserThread::PostTask(
797 BrowserThread::IO, FROM_HERE, 812 BrowserThread::IO, FROM_HERE,
798 base::Bind(&SafeBrowsingDatabaseManager::CheckDownloadHashDone, this, 813 base::Bind(&SafeBrowsingDatabaseManager::CheckDownloadHashDone, this,
799 check)); 814 check));
800 return; 815 return;
801 } 816 }
802 817
803 check->need_get_hash = true; 818 check->need_get_hash = true;
804 check->prefix_hits.push_back(check->full_hash->prefix); 819 check->prefix_hits.push_back(full_hash.prefix);
805 BrowserThread::PostTask( 820 BrowserThread::PostTask(
806 BrowserThread::IO, FROM_HERE, 821 BrowserThread::IO, FROM_HERE,
807 base::Bind(&SafeBrowsingDatabaseManager::OnCheckDone, this, check)); 822 base::Bind(&SafeBrowsingDatabaseManager::OnCheckDone, this, check));
808 } 823 }
809 824
810 void SafeBrowsingDatabaseManager::CheckDownloadUrlOnSBThread( 825 void SafeBrowsingDatabaseManager::CheckDownloadUrlOnSBThread(
811 SafeBrowsingCheck* check) { 826 SafeBrowsingCheck* check) {
812 DCHECK_EQ(MessageLoop::current(), safe_browsing_thread_->message_loop()); 827 DCHECK_EQ(MessageLoop::current(), safe_browsing_thread_->message_loop());
813 DCHECK(enable_download_protection_); 828 DCHECK(enable_download_protection_);
814 829
815 std::vector<SBPrefix> prefix_hits; 830 std::vector<SBPrefix> prefix_hits;
816 831
817 if (!database_->ContainsDownloadUrl(check->urls, &prefix_hits)) { 832 if (!database_->ContainsDownloadUrl(check->urls, &prefix_hits)) {
818 // Good, we don't have hash for this url prefix. 833 // Good, we don't have hash for this url prefix.
819 check->threat_type = SB_THREAT_TYPE_SAFE;
820 BrowserThread::PostTask( 834 BrowserThread::PostTask(
821 BrowserThread::IO, FROM_HERE, 835 BrowserThread::IO, FROM_HERE,
822 base::Bind(&SafeBrowsingDatabaseManager::CheckDownloadUrlDone, this, 836 base::Bind(&SafeBrowsingDatabaseManager::CheckDownloadUrlDone, this,
823 check)); 837 check));
824 return; 838 return;
825 } 839 }
826 840
827 check->need_get_hash = true; 841 check->need_get_hash = true;
828 check->prefix_hits.clear(); 842 check->prefix_hits.clear();
829 check->prefix_hits = prefix_hits; 843 check->prefix_hits = prefix_hits;
830 BrowserThread::PostTask( 844 BrowserThread::PostTask(
831 BrowserThread::IO, FROM_HERE, 845 BrowserThread::IO, FROM_HERE,
832 base::Bind(&SafeBrowsingDatabaseManager::OnCheckDone, this, check)); 846 base::Bind(&SafeBrowsingDatabaseManager::OnCheckDone, this, check));
833 } 847 }
834 848
835 void SafeBrowsingDatabaseManager::TimeoutCallback(SafeBrowsingCheck* check) { 849 void SafeBrowsingDatabaseManager::TimeoutCallback(SafeBrowsingCheck* check) {
836 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 850 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
837 DCHECK(check); 851 DCHECK(check);
838 852
839 if (!enabled_) 853 if (!enabled_)
840 return; 854 return;
841 855
842 DCHECK(checks_.find(check) != checks_.end()); 856 DCHECK(checks_.find(check) != checks_.end());
843 DCHECK_EQ(check->threat_type, SB_THREAT_TYPE_SAFE);
844 if (check->client) { 857 if (check->client) {
845 check->client->OnSafeBrowsingResult(*check); 858 check->client->OnSafeBrowsingResult(*check);
846 check->client = NULL; 859 check->client = NULL;
847 } 860 }
848 } 861 }
849 862
850 void SafeBrowsingDatabaseManager::CheckDownloadUrlDone( 863 void SafeBrowsingDatabaseManager::CheckDownloadUrlDone(
851 SafeBrowsingCheck* check) { 864 SafeBrowsingCheck* check) {
852 DCHECK(enable_download_protection_); 865 DCHECK(enable_download_protection_);
853 SafeBrowsingCheckDone(check); 866 SafeBrowsingCheckDone(check);
854 } 867 }
855 868
856 void SafeBrowsingDatabaseManager::CheckDownloadHashDone( 869 void SafeBrowsingDatabaseManager::CheckDownloadHashDone(
857 SafeBrowsingCheck* check) { 870 SafeBrowsingCheck* check) {
858 DCHECK(enable_download_protection_); 871 DCHECK(enable_download_protection_);
859 SafeBrowsingCheckDone(check); 872 SafeBrowsingCheckDone(check);
860 } 873 }
861 874
862 void SafeBrowsingDatabaseManager::SafeBrowsingCheckDone( 875 void SafeBrowsingDatabaseManager::SafeBrowsingCheckDone(
863 SafeBrowsingCheck* check) { 876 SafeBrowsingCheck* check) {
864 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 877 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
865 DCHECK(check); 878 DCHECK(check);
866 879
867 if (!enabled_) 880 if (!enabled_)
868 return; 881 return;
869 882
870 VLOG(1) << "SafeBrowsingCheckDone: " << check->threat_type; 883 VLOG(1) << "SafeBrowsingCheckDone: " <<
884 check->url_threats.size() << " URL hits, " <<
885 check->full_hash_threats.size() << " hash hits";
871 DCHECK(checks_.find(check) != checks_.end()); 886 DCHECK(checks_.find(check) != checks_.end());
872 if (check->client) 887 if (check->client)
873 check->client->OnSafeBrowsingResult(*check); 888 check->client->OnSafeBrowsingResult(*check);
874 checks_.erase(check); 889 checks_.erase(check);
875 delete check; 890 delete check;
876 } 891 }
877 892
878 void SafeBrowsingDatabaseManager::StartDownloadCheck(SafeBrowsingCheck* check, 893 void SafeBrowsingDatabaseManager::StartSafeBrowsingCheck(
879 Client* client, 894 SafeBrowsingCheck* check,
880 const base::Closure& task, 895 Client* client,
881 int64 timeout_ms) { 896 const base::Closure& task,
882 897 const base::TimeDelta& timeout) {
883 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 898 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
884 check->client = client; 899 check->client = client;
885 check->threat_type = SB_THREAT_TYPE_SAFE;
886 check->is_download = true;
887 check->timeout_factory_.reset( 900 check->timeout_factory_.reset(
888 new base::WeakPtrFactory<SafeBrowsingDatabaseManager>(this)); 901 new base::WeakPtrFactory<SafeBrowsingDatabaseManager>(this));
889 checks_.insert(check); 902 checks_.insert(check);
890 903
891 safe_browsing_thread_->message_loop()->PostTask(FROM_HERE, task); 904 safe_browsing_thread_->message_loop()->PostTask(FROM_HERE, task);
892 905
893 MessageLoop::current()->PostDelayedTask(FROM_HERE, 906 MessageLoop::current()->PostDelayedTask(FROM_HERE,
894 base::Bind(&SafeBrowsingDatabaseManager::TimeoutCallback, 907 base::Bind(&SafeBrowsingDatabaseManager::TimeoutCallback,
895 check->timeout_factory_->GetWeakPtr(), check), 908 check->timeout_factory_->GetWeakPtr(), check),
896 base::TimeDelta::FromMilliseconds(timeout_ms)); 909 timeout);
897 } 910 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698