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

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

Powered by Google App Engine
This is Rietveld 408576698