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

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

Issue 7863006: Add a whitelist for the new binary download protection. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Add comment to describe why we use list id 6 and not 5. Created 9 years, 3 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) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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/safe_browsing_database.h" 5 #include "chrome/browser/safe_browsing/safe_browsing_database.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <iterator> 8 #include <iterator>
9 9
10 #include "base/file_util.h" 10 #include "base/file_util.h"
(...skipping 15 matching lines...) Expand all
26 26
27 namespace { 27 namespace {
28 28
29 // Filename suffix for the bloom filter. 29 // Filename suffix for the bloom filter.
30 const FilePath::CharType kBloomFilterFile[] = FILE_PATH_LITERAL(" Filter 2"); 30 const FilePath::CharType kBloomFilterFile[] = FILE_PATH_LITERAL(" Filter 2");
31 // Filename suffix for download store. 31 // Filename suffix for download store.
32 const FilePath::CharType kDownloadDBFile[] = FILE_PATH_LITERAL(" Download"); 32 const FilePath::CharType kDownloadDBFile[] = FILE_PATH_LITERAL(" Download");
33 // Filename suffix for client-side phishing detection whitelist store. 33 // Filename suffix for client-side phishing detection whitelist store.
34 const FilePath::CharType kCsdWhitelistDBFile[] = 34 const FilePath::CharType kCsdWhitelistDBFile[] =
35 FILE_PATH_LITERAL(" Csd Whitelist"); 35 FILE_PATH_LITERAL(" Csd Whitelist");
36 // Filename suffix for the download whitelist store.
37 const FilePath::CharType kDownloadWhitelistDBFile[] =
38 FILE_PATH_LITERAL(" Download Whitelist");
36 // Filename suffix for browse store. 39 // Filename suffix for browse store.
37 // TODO(lzheng): change to a better name when we change the file format. 40 // TODO(lzheng): change to a better name when we change the file format.
38 const FilePath::CharType kBrowseDBFile[] = FILE_PATH_LITERAL(" Bloom"); 41 const FilePath::CharType kBrowseDBFile[] = FILE_PATH_LITERAL(" Bloom");
39 42
40 // The maximum staleness for a cached entry. 43 // The maximum staleness for a cached entry.
41 const int kMaxStalenessMinutes = 45; 44 const int kMaxStalenessMinutes = 45;
42 45
43 // Maximum number of entries we allow in the client-side phishing detection 46 // Maximum number of entries we allow in any of the two whitelists.
Brian Ryner 2011/09/12 21:45:18 May want to remove "two" so that this comment does
noelutz 2011/09/12 22:09:30 Done.
44 // whitelist. If the whitelist on disk contains more entries then 47 // If a whitelist on disk contains more entries then all lookups to
45 // ContainsCsdWhitelistedUrl will always return true. 48 // the whitelist will be considered a match.
46 const size_t kMaxCsdWhitelistSize = 5000; 49 const size_t kMaxWhitelistSize = 5000;
47 50
48 // If the hash of this exact expression is on the csd whitelist then 51 // If the hash of this exact expression is on a whitelist then all
49 // ContainsCsdWhitelistedUrl will always return true. 52 // lookups to this whitelist will be considered a match.
50 const char kCsdKillSwitchUrl[] = 53 const char kWhitelistKillSwitchUrl[] =
51 "sb-ssl.google.com/safebrowsing/csd/killswitch"; 54 "sb-ssl.google.com/safebrowsing/csd/killswitch"; // Don't change this!
52 55
53 // To save space, the incoming |chunk_id| and |list_id| are combined 56 // To save space, the incoming |chunk_id| and |list_id| are combined
54 // into an |encoded_chunk_id| for storage by shifting the |list_id| 57 // into an |encoded_chunk_id| for storage by shifting the |list_id|
55 // into the low-order bits. These functions decode that information. 58 // into the low-order bits. These functions decode that information.
56 // TODO(lzheng): It was reasonable when database is saved in sqlite, but 59 // TODO(lzheng): It was reasonable when database is saved in sqlite, but
57 // there should be better ways to save chunk_id and list_id after we use 60 // there should be better ways to save chunk_id and list_id after we use
58 // SafeBrowsingStoreFile. 61 // SafeBrowsingStoreFile.
59 int GetListIdBit(const int encoded_chunk_id) { 62 int GetListIdBit(const int encoded_chunk_id) {
60 return encoded_chunk_id & 1; 63 return encoded_chunk_id & 1;
61 } 64 }
62 int DecodeChunkId(int encoded_chunk_id) { 65 int DecodeChunkId(int encoded_chunk_id) {
63 return encoded_chunk_id >> 1; 66 return encoded_chunk_id >> 1;
64 } 67 }
65 int EncodeChunkId(const int chunk, const int list_id) { 68 int EncodeChunkId(const int chunk, const int list_id) {
66 DCHECK_NE(list_id, safe_browsing_util::INVALID); 69 DCHECK_NE(list_id, safe_browsing_util::INVALID);
67 return chunk << 1 | list_id % 2; 70 return chunk << 1 | list_id % 2;
68 } 71 }
69 72
70 // Generate the set of full hashes to check for |url|. If 73 // Generate the set of full hashes to check for |url|. If
71 // |include_whitelist_hashes| is true we will generate additional path-prefixes 74 // |include_whitelist_hashes| is true we will generate additional path-prefixes
72 // to match against the csd whitelist. E.g., if the path-prefix /foo is on the 75 // to match against the csd whitelist. E.g., if the path-prefix /foo is on the
73 // whitelist it should also match /foo/bar which is not the case for all the 76 // whitelist it should also match /foo/bar which is not the case for all the
74 // other lists. 77 // other lists. We'll also always add a pattern for the empty path.
75 // TODO(shess): This function is almost the same as 78 // TODO(shess): This function is almost the same as
76 // |CompareFullHashes()| in safe_browsing_util.cc, except that code 79 // |CompareFullHashes()| in safe_browsing_util.cc, except that code
77 // does an early exit on match. Since match should be the infrequent 80 // does an early exit on match. Since match should be the infrequent
78 // case (phishing or malware found), consider combining this function 81 // case (phishing or malware found), consider combining this function
79 // with that one. 82 // with that one.
80 void BrowseFullHashesToCheck(const GURL& url, 83 void BrowseFullHashesToCheck(const GURL& url,
81 bool include_whitelist_hashes, 84 bool include_whitelist_hashes,
82 std::vector<SBFullHash>* full_hashes) { 85 std::vector<SBFullHash>* full_hashes) {
83 std::vector<std::string> hosts; 86 std::vector<std::string> hosts;
84 if (url.HostIsIPAddress()) { 87 if (url.HostIsIPAddress()) {
85 hosts.push_back(url.host()); 88 hosts.push_back(url.host());
86 } else { 89 } else {
87 safe_browsing_util::GenerateHostsToCheck(url, &hosts); 90 safe_browsing_util::GenerateHostsToCheck(url, &hosts);
88 } 91 }
89 92
90 std::vector<std::string> paths; 93 std::vector<std::string> paths;
91 safe_browsing_util::GeneratePathsToCheck(url, &paths); 94 safe_browsing_util::GeneratePathsToCheck(url, &paths);
92 95
93 for (size_t i = 0; i < hosts.size(); ++i) { 96 for (size_t i = 0; i < hosts.size(); ++i) {
97 bool has_empty_path = false;
Brian Ryner 2011/09/12 21:45:18 I'm not sure I understand the extra logic you're a
noelutz 2011/09/12 22:09:30 Duh! I just realized that I misunderstood Generat
94 for (size_t j = 0; j < paths.size(); ++j) { 98 for (size_t j = 0; j < paths.size(); ++j) {
95 const std::string& path = paths[j]; 99 const std::string& path = paths[j];
100 has_empty_path |= (path == "/");
96 SBFullHash full_hash; 101 SBFullHash full_hash;
97 crypto::SHA256HashString(hosts[i] + path, &full_hash, 102 crypto::SHA256HashString(hosts[i] + path, &full_hash,
98 sizeof(full_hash)); 103 sizeof(full_hash));
99 full_hashes->push_back(full_hash); 104 full_hashes->push_back(full_hash);
100 105
101 // We may have /foo as path-prefix in the whitelist which should 106 // We may have /foo as path-prefix in the whitelist which should
102 // also match with /foo/bar and /foo?bar. Hence, for every path 107 // also match with /foo/bar and /foo?bar. Hence, for every path
103 // that ends in '/' we also add the path without the slash. 108 // that ends in '/' we also add the path without the slash.
104 if (include_whitelist_hashes && 109 if (include_whitelist_hashes &&
105 path.size() > 1 && 110 path.size() > 1 &&
106 path[path.size() - 1] == '/') { 111 path[path.size() - 1] == '/') {
107 crypto::SHA256HashString(hosts[i] + path.substr(0, path.size() - 1), 112 crypto::SHA256HashString(hosts[i] + path.substr(0, path.size() - 1),
108 &full_hash, sizeof(full_hash)); 113 &full_hash, sizeof(full_hash));
109 full_hashes->push_back(full_hash); 114 full_hashes->push_back(full_hash);
110 } 115 }
111 } 116 }
117 // Add the host with an empty path if we haven't already added
118 // this expression to the full_hashes vector.
119 if (!has_empty_path && include_whitelist_hashes) {
120 SBFullHash full_hash;
121 crypto::SHA256HashString(hosts[i] + "/", &full_hash, sizeof(full_hash));
122 full_hashes->push_back(full_hash);
123 }
112 } 124 }
113 } 125 }
114 126
115 // Get the prefixes matching the download |urls|. 127 // Get the prefixes matching the download |urls|.
116 void GetDownloadUrlPrefixes(const std::vector<GURL>& urls, 128 void GetDownloadUrlPrefixes(const std::vector<GURL>& urls,
117 std::vector<SBPrefix>* prefixes) { 129 std::vector<SBPrefix>* prefixes) {
118 std::vector<SBFullHash> full_hashes; 130 std::vector<SBFullHash> full_hashes;
119 for (size_t i = 0; i < urls.size(); ++i) 131 for (size_t i = 0; i < urls.size(); ++i)
120 BrowseFullHashesToCheck(urls[i], false, &full_hashes); 132 BrowseFullHashesToCheck(urls[i], false, &full_hashes);
121 133
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after
388 return prefix_set.release(); 400 return prefix_set.release();
389 } 401 }
390 402
391 } // namespace 403 } // namespace
392 404
393 // The default SafeBrowsingDatabaseFactory. 405 // The default SafeBrowsingDatabaseFactory.
394 class SafeBrowsingDatabaseFactoryImpl : public SafeBrowsingDatabaseFactory { 406 class SafeBrowsingDatabaseFactoryImpl : public SafeBrowsingDatabaseFactory {
395 public: 407 public:
396 virtual SafeBrowsingDatabase* CreateSafeBrowsingDatabase( 408 virtual SafeBrowsingDatabase* CreateSafeBrowsingDatabase(
397 bool enable_download_protection, 409 bool enable_download_protection,
398 bool enable_client_side_whitelist) { 410 bool enable_client_side_whitelist,
411 bool enable_download_whitelist) {
399 return new SafeBrowsingDatabaseNew( 412 return new SafeBrowsingDatabaseNew(
400 new SafeBrowsingStoreFile, 413 new SafeBrowsingStoreFile,
401 enable_download_protection ? new SafeBrowsingStoreFile : NULL, 414 enable_download_protection ? new SafeBrowsingStoreFile : NULL,
402 enable_client_side_whitelist ? new SafeBrowsingStoreFile : NULL); 415 enable_client_side_whitelist ? new SafeBrowsingStoreFile : NULL,
416 enable_download_whitelist ? new SafeBrowsingStoreFile : NULL);
403 } 417 }
404 418
405 SafeBrowsingDatabaseFactoryImpl() { } 419 SafeBrowsingDatabaseFactoryImpl() { }
406 420
407 private: 421 private:
408 DISALLOW_COPY_AND_ASSIGN(SafeBrowsingDatabaseFactoryImpl); 422 DISALLOW_COPY_AND_ASSIGN(SafeBrowsingDatabaseFactoryImpl);
409 }; 423 };
410 424
411 // static 425 // static
412 SafeBrowsingDatabaseFactory* SafeBrowsingDatabase::factory_ = NULL; 426 SafeBrowsingDatabaseFactory* SafeBrowsingDatabase::factory_ = NULL;
413 427
414 // Factory method, non-thread safe. Caller has to make sure this s called 428 // Factory method, non-thread safe. Caller has to make sure this s called
415 // on SafeBrowsing Thread. 429 // on SafeBrowsing Thread.
416 // TODO(shess): There's no need for a factory any longer. Convert 430 // TODO(shess): There's no need for a factory any longer. Convert
417 // SafeBrowsingDatabaseNew to SafeBrowsingDatabase, and have Create() 431 // SafeBrowsingDatabaseNew to SafeBrowsingDatabase, and have Create()
418 // callers just construct things directly. 432 // callers just construct things directly.
419 SafeBrowsingDatabase* SafeBrowsingDatabase::Create( 433 SafeBrowsingDatabase* SafeBrowsingDatabase::Create(
420 bool enable_download_protection, 434 bool enable_download_protection,
421 bool enable_client_side_whitelist) { 435 bool enable_client_side_whitelist,
436 bool enable_download_whitelist) {
422 if (!factory_) 437 if (!factory_)
423 factory_ = new SafeBrowsingDatabaseFactoryImpl(); 438 factory_ = new SafeBrowsingDatabaseFactoryImpl();
424 return factory_->CreateSafeBrowsingDatabase(enable_download_protection, 439 return factory_->CreateSafeBrowsingDatabase(enable_download_protection,
425 enable_client_side_whitelist); 440 enable_client_side_whitelist,
441 enable_download_whitelist);
426 } 442 }
427 443
428 SafeBrowsingDatabase::~SafeBrowsingDatabase() { 444 SafeBrowsingDatabase::~SafeBrowsingDatabase() {
429 } 445 }
430 446
431 // static 447 // static
432 FilePath SafeBrowsingDatabase::BrowseDBFilename( 448 FilePath SafeBrowsingDatabase::BrowseDBFilename(
433 const FilePath& db_base_filename) { 449 const FilePath& db_base_filename) {
434 return FilePath(db_base_filename.value() + kBrowseDBFile); 450 return FilePath(db_base_filename.value() + kBrowseDBFile);
435 } 451 }
436 452
437 // static 453 // static
438 FilePath SafeBrowsingDatabase::DownloadDBFilename( 454 FilePath SafeBrowsingDatabase::DownloadDBFilename(
439 const FilePath& db_base_filename) { 455 const FilePath& db_base_filename) {
440 return FilePath(db_base_filename.value() + kDownloadDBFile); 456 return FilePath(db_base_filename.value() + kDownloadDBFile);
441 } 457 }
442 458
443 // static 459 // static
444 FilePath SafeBrowsingDatabase::BloomFilterForFilename( 460 FilePath SafeBrowsingDatabase::BloomFilterForFilename(
445 const FilePath& db_filename) { 461 const FilePath& db_filename) {
446 return FilePath(db_filename.value() + kBloomFilterFile); 462 return FilePath(db_filename.value() + kBloomFilterFile);
447 } 463 }
448 464
449 // static 465 // static
450 FilePath SafeBrowsingDatabase::CsdWhitelistDBFilename( 466 FilePath SafeBrowsingDatabase::CsdWhitelistDBFilename(
451 const FilePath& db_filename) { 467 const FilePath& db_filename) {
452 return FilePath(db_filename.value() + kCsdWhitelistDBFile); 468 return FilePath(db_filename.value() + kCsdWhitelistDBFile);
453 } 469 }
454 470
471 // static
472 FilePath SafeBrowsingDatabase::DownloadWhitelistDBFilename(
473 const FilePath& db_filename) {
474 return FilePath(db_filename.value() + kDownloadWhitelistDBFile);
475 }
476
455 SafeBrowsingStore* SafeBrowsingDatabaseNew::GetStore(const int list_id) { 477 SafeBrowsingStore* SafeBrowsingDatabaseNew::GetStore(const int list_id) {
456 if (list_id == safe_browsing_util::PHISH || 478 if (list_id == safe_browsing_util::PHISH ||
457 list_id == safe_browsing_util::MALWARE) { 479 list_id == safe_browsing_util::MALWARE) {
458 return browse_store_.get(); 480 return browse_store_.get();
459 } else if (list_id == safe_browsing_util::BINURL || 481 } else if (list_id == safe_browsing_util::BINURL ||
460 list_id == safe_browsing_util::BINHASH) { 482 list_id == safe_browsing_util::BINHASH) {
461 return download_store_.get(); 483 return download_store_.get();
462 } else if (list_id == safe_browsing_util::CSDWHITELIST) { 484 } else if (list_id == safe_browsing_util::CSDWHITELIST) {
463 return csd_whitelist_store_.get(); 485 return csd_whitelist_store_.get();
486 } else if (list_id == safe_browsing_util::DOWNLOADWHITELIST) {
487 return download_whitelist_store_.get();
464 } 488 }
465 return NULL; 489 return NULL;
466 } 490 }
467 491
468 // static 492 // static
469 void SafeBrowsingDatabase::RecordFailure(FailureType failure_type) { 493 void SafeBrowsingDatabase::RecordFailure(FailureType failure_type) {
470 UMA_HISTOGRAM_ENUMERATION("SB2.DatabaseFailure", failure_type, 494 UMA_HISTOGRAM_ENUMERATION("SB2.DatabaseFailure", failure_type,
471 FAILURE_DATABASE_MAX); 495 FAILURE_DATABASE_MAX);
472 } 496 }
473 497
474 SafeBrowsingDatabaseNew::SafeBrowsingDatabaseNew() 498 SafeBrowsingDatabaseNew::SafeBrowsingDatabaseNew()
475 : creation_loop_(MessageLoop::current()), 499 : creation_loop_(MessageLoop::current()),
476 browse_store_(new SafeBrowsingStoreFile), 500 browse_store_(new SafeBrowsingStoreFile),
477 download_store_(NULL), 501 download_store_(NULL),
478 csd_whitelist_store_(NULL), 502 csd_whitelist_store_(NULL),
503 download_whitelist_store_(NULL),
479 ALLOW_THIS_IN_INITIALIZER_LIST(reset_factory_(this)) { 504 ALLOW_THIS_IN_INITIALIZER_LIST(reset_factory_(this)) {
480 DCHECK(browse_store_.get()); 505 DCHECK(browse_store_.get());
481 DCHECK(!download_store_.get()); 506 DCHECK(!download_store_.get());
482 DCHECK(!csd_whitelist_store_.get()); 507 DCHECK(!csd_whitelist_store_.get());
508 DCHECK(!download_whitelist_store_.get());
483 } 509 }
484 510
485 SafeBrowsingDatabaseNew::SafeBrowsingDatabaseNew( 511 SafeBrowsingDatabaseNew::SafeBrowsingDatabaseNew(
486 SafeBrowsingStore* browse_store, 512 SafeBrowsingStore* browse_store,
487 SafeBrowsingStore* download_store, 513 SafeBrowsingStore* download_store,
488 SafeBrowsingStore* csd_whitelist_store) 514 SafeBrowsingStore* csd_whitelist_store,
515 SafeBrowsingStore* download_whitelist_store)
489 : creation_loop_(MessageLoop::current()), 516 : creation_loop_(MessageLoop::current()),
490 browse_store_(browse_store), 517 browse_store_(browse_store),
491 download_store_(download_store), 518 download_store_(download_store),
492 csd_whitelist_store_(csd_whitelist_store), 519 csd_whitelist_store_(csd_whitelist_store),
520 download_whitelist_store_(download_whitelist_store),
493 ALLOW_THIS_IN_INITIALIZER_LIST(reset_factory_(this)), 521 ALLOW_THIS_IN_INITIALIZER_LIST(reset_factory_(this)),
494 corruption_detected_(false) { 522 corruption_detected_(false) {
495 DCHECK(browse_store_.get()); 523 DCHECK(browse_store_.get());
496 } 524 }
497 525
498 SafeBrowsingDatabaseNew::~SafeBrowsingDatabaseNew() { 526 SafeBrowsingDatabaseNew::~SafeBrowsingDatabaseNew() {
499 DCHECK_EQ(creation_loop_, MessageLoop::current()); 527 DCHECK_EQ(creation_loop_, MessageLoop::current());
500 } 528 }
501 529
502 void SafeBrowsingDatabaseNew::Init(const FilePath& filename_base) { 530 void SafeBrowsingDatabaseNew::Init(const FilePath& filename_base) {
503 DCHECK_EQ(creation_loop_, MessageLoop::current()); 531 DCHECK_EQ(creation_loop_, MessageLoop::current());
504 // Ensure we haven't been run before. 532 // Ensure we haven't been run before.
505 DCHECK(browse_filename_.empty()); 533 DCHECK(browse_filename_.empty());
506 DCHECK(download_filename_.empty()); 534 DCHECK(download_filename_.empty());
507 DCHECK(csd_whitelist_filename_.empty()); 535 DCHECK(csd_whitelist_filename_.empty());
536 DCHECK(download_whitelist_filename_.empty());
508 537
509 browse_filename_ = BrowseDBFilename(filename_base); 538 browse_filename_ = BrowseDBFilename(filename_base);
510 bloom_filter_filename_ = BloomFilterForFilename(browse_filename_); 539 bloom_filter_filename_ = BloomFilterForFilename(browse_filename_);
511 540
512 browse_store_->Init( 541 browse_store_->Init(
513 browse_filename_, 542 browse_filename_,
514 NewCallback(this, &SafeBrowsingDatabaseNew::HandleCorruptDatabase)); 543 NewCallback(this, &SafeBrowsingDatabaseNew::HandleCorruptDatabase));
515 DVLOG(1) << "Init browse store: " << browse_filename_.value(); 544 DVLOG(1) << "Init browse store: " << browse_filename_.value();
516 545
517 { 546 {
(...skipping 16 matching lines...) Expand all
534 } 563 }
535 564
536 if (csd_whitelist_store_.get()) { 565 if (csd_whitelist_store_.get()) {
537 csd_whitelist_filename_ = CsdWhitelistDBFilename(filename_base); 566 csd_whitelist_filename_ = CsdWhitelistDBFilename(filename_base);
538 csd_whitelist_store_->Init( 567 csd_whitelist_store_->Init(
539 csd_whitelist_filename_, 568 csd_whitelist_filename_,
540 NewCallback(this, &SafeBrowsingDatabaseNew::HandleCorruptDatabase)); 569 NewCallback(this, &SafeBrowsingDatabaseNew::HandleCorruptDatabase));
541 DVLOG(1) << "Init csd whitelist store: " << csd_whitelist_filename_.value(); 570 DVLOG(1) << "Init csd whitelist store: " << csd_whitelist_filename_.value();
542 std::vector<SBAddFullHash> full_hashes; 571 std::vector<SBAddFullHash> full_hashes;
543 if (csd_whitelist_store_->GetAddFullHashes(&full_hashes)) { 572 if (csd_whitelist_store_->GetAddFullHashes(&full_hashes)) {
544 LoadCsdWhitelist(full_hashes); 573 LoadWhitelist(full_hashes, &csd_whitelist_);
545 } else { 574 } else {
546 CsdWhitelistAllUrls(); 575 WhitelistEverything(&csd_whitelist_);
547 } 576 }
548 } else { 577 } else {
549 CsdWhitelistAllUrls(); // Just to be safe. 578 WhitelistEverything(&csd_whitelist_); // Just to be safe.
579 }
580
581 if (download_whitelist_store_.get()) {
582 download_whitelist_filename_ = DownloadWhitelistDBFilename(filename_base);
583 download_whitelist_store_->Init(
584 download_whitelist_filename_,
585 NewCallback(this, &SafeBrowsingDatabaseNew::HandleCorruptDatabase));
586 DVLOG(1) << "Init download whitelist store: "
587 << download_whitelist_filename_.value();
588 std::vector<SBAddFullHash> full_hashes;
589 if (download_whitelist_store_->GetAddFullHashes(&full_hashes)) {
590 LoadWhitelist(full_hashes, &download_whitelist_);
591 } else {
592 WhitelistEverything(&download_whitelist_);
mattm 2011/09/10 01:55:33 Hm, does this mean that if the whitelist file does
noelutz 2011/09/10 02:30:56 Exactly. That's a precaution to protect the user'
593 }
594 } else {
595 WhitelistEverything(&download_whitelist_); // Just to be safe.
550 } 596 }
551 } 597 }
552 598
553 bool SafeBrowsingDatabaseNew::ResetDatabase() { 599 bool SafeBrowsingDatabaseNew::ResetDatabase() {
554 DCHECK_EQ(creation_loop_, MessageLoop::current()); 600 DCHECK_EQ(creation_loop_, MessageLoop::current());
555 601
556 // Delete files on disk. 602 // Delete files on disk.
557 // TODO(shess): Hard to see where one might want to delete without a 603 // TODO(shess): Hard to see where one might want to delete without a
558 // reset. Perhaps inline |Delete()|? 604 // reset. Perhaps inline |Delete()|?
559 if (!Delete()) 605 if (!Delete())
560 return false; 606 return false;
561 607
562 // Reset objects in memory. 608 // Reset objects in memory.
563 { 609 {
564 base::AutoLock locked(lookup_lock_); 610 base::AutoLock locked(lookup_lock_);
565 full_browse_hashes_.clear(); 611 full_browse_hashes_.clear();
566 pending_browse_hashes_.clear(); 612 pending_browse_hashes_.clear();
567 prefix_miss_cache_.clear(); 613 prefix_miss_cache_.clear();
568 // TODO(shess): This could probably be |bloom_filter_.reset()|. 614 // TODO(shess): This could probably be |bloom_filter_.reset()|.
569 browse_bloom_filter_ = new BloomFilter(BloomFilter::kBloomFilterMinSize * 615 browse_bloom_filter_ = new BloomFilter(BloomFilter::kBloomFilterMinSize *
570 BloomFilter::kBloomFilterSizeRatio); 616 BloomFilter::kBloomFilterSizeRatio);
571 // TODO(shess): It is simpler for the code to assume that presence 617 // TODO(shess): It is simpler for the code to assume that presence
572 // of a bloom filter always implies presence of a prefix set. 618 // of a bloom filter always implies presence of a prefix set.
573 prefix_set_.reset(new safe_browsing::PrefixSet(std::vector<SBPrefix>())); 619 prefix_set_.reset(new safe_browsing::PrefixSet(std::vector<SBPrefix>()));
574 } 620 }
575 // Wants to acquire the lock itself. 621 // Wants to acquire the lock itself.
576 CsdWhitelistAllUrls(); 622 WhitelistEverything(&csd_whitelist_);
623 WhitelistEverything(&download_whitelist_);
577 624
578 return true; 625 return true;
579 } 626 }
580 627
581 // TODO(lzheng): Remove matching_list, it is not used anywhere. 628 // TODO(lzheng): Remove matching_list, it is not used anywhere.
582 bool SafeBrowsingDatabaseNew::ContainsBrowseUrl( 629 bool SafeBrowsingDatabaseNew::ContainsBrowseUrl(
583 const GURL& url, 630 const GURL& url,
584 std::string* matching_list, 631 std::string* matching_list,
585 std::vector<SBPrefix>* prefix_hits, 632 std::vector<SBPrefix>* prefix_hits,
586 std::vector<SBFullHashResult>* full_hits, 633 std::vector<SBFullHashResult>* full_hits,
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
706 std::vector<SBPrefix> prefix_hits; 753 std::vector<SBPrefix> prefix_hits;
707 return MatchDownloadAddPrefixes(safe_browsing_util::BINHASH % 2, 754 return MatchDownloadAddPrefixes(safe_browsing_util::BINHASH % 2,
708 prefixes, 755 prefixes,
709 &prefix_hits); 756 &prefix_hits);
710 } 757 }
711 758
712 bool SafeBrowsingDatabaseNew::ContainsCsdWhitelistedUrl(const GURL& url) { 759 bool SafeBrowsingDatabaseNew::ContainsCsdWhitelistedUrl(const GURL& url) {
713 // This method is theoretically thread-safe but we expect all calls to 760 // This method is theoretically thread-safe but we expect all calls to
714 // originate from the IO thread. 761 // originate from the IO thread.
715 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 762 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
716 base::AutoLock l(lookup_lock_);
717 if (csd_whitelist_all_urls_)
718 return true;
719
720 std::vector<SBFullHash> full_hashes; 763 std::vector<SBFullHash> full_hashes;
721 BrowseFullHashesToCheck(url, true, &full_hashes); 764 BrowseFullHashesToCheck(url, true, &full_hashes);
722 for (std::vector<SBFullHash>::const_iterator it = full_hashes.begin(); 765 return ContainsWhitelistedHashes(csd_whitelist_, full_hashes);
723 it != full_hashes.end(); ++it) { 766 }
724 if (std::binary_search(csd_whitelist_.begin(), csd_whitelist_.end(), *it)) 767
768 bool SafeBrowsingDatabaseNew::ContainsDownloadWhitelistedUrl(const GURL& url) {
769 std::vector<SBFullHash> full_hashes;
770 BrowseFullHashesToCheck(url, true, &full_hashes);
771 return ContainsWhitelistedHashes(download_whitelist_, full_hashes);
772 }
773
774 bool SafeBrowsingDatabaseNew::ContainsDownloadWhitelistedString(
775 const std::string& str) {
776 SBFullHash hash;
777 crypto::SHA256HashString(str, &hash, sizeof(hash));
778 std::vector<SBFullHash> hashes;
779 hashes.push_back(hash);
780 return ContainsWhitelistedHashes(download_whitelist_, hashes);
781 }
782
783 bool SafeBrowsingDatabaseNew::ContainsWhitelistedHashes(
784 const SBWhitelist& whitelist,
785 const std::vector<SBFullHash>& hashes) {
786 base::AutoLock l(lookup_lock_);
787 if (whitelist.second)
788 return true;
789 for (std::vector<SBFullHash>::const_iterator it = hashes.begin();
790 it != hashes.end(); ++it) {
791 if (std::binary_search(whitelist.first.begin(), whitelist.first.end(), *it))
725 return true; 792 return true;
726 } 793 }
727 return false; 794 return false;
728 } 795 }
729 796
730 // Helper to insert entries for all of the prefixes or full hashes in 797 // Helper to insert entries for all of the prefixes or full hashes in
731 // |entry| into the store. 798 // |entry| into the store.
732 void SafeBrowsingDatabaseNew::InsertAdd(int chunk_id, SBPrefix host, 799 void SafeBrowsingDatabaseNew::InsertAdd(int chunk_id, SBPrefix host,
733 const SBEntry* entry, int list_id) { 800 const SBEntry* entry, int list_id) {
734 DCHECK_EQ(creation_loop_, MessageLoop::current()); 801 DCHECK_EQ(creation_loop_, MessageLoop::current());
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after
972 return false; 1039 return false;
973 } 1040 }
974 1041
975 if (download_store_.get() && !download_store_->BeginUpdate()) { 1042 if (download_store_.get() && !download_store_->BeginUpdate()) {
976 RecordFailure(FAILURE_DOWNLOAD_DATABASE_UPDATE_BEGIN); 1043 RecordFailure(FAILURE_DOWNLOAD_DATABASE_UPDATE_BEGIN);
977 HandleCorruptDatabase(); 1044 HandleCorruptDatabase();
978 return false; 1045 return false;
979 } 1046 }
980 1047
981 if (csd_whitelist_store_.get() && !csd_whitelist_store_->BeginUpdate()) { 1048 if (csd_whitelist_store_.get() && !csd_whitelist_store_->BeginUpdate()) {
982 RecordFailure(FAILURE_CSD_WHITELIST_DATABASE_UPDATE_BEGIN); 1049 RecordFailure(FAILURE_WHITELIST_DATABASE_UPDATE_BEGIN);
983 HandleCorruptDatabase(); 1050 HandleCorruptDatabase();
984 return false; 1051 return false;
985 } 1052 }
1053
1054 if (download_whitelist_store_.get() &&
1055 !download_whitelist_store_->BeginUpdate()) {
1056 RecordFailure(FAILURE_WHITELIST_DATABASE_UPDATE_BEGIN);
1057 HandleCorruptDatabase();
1058 return false;
1059 }
986 1060
987 std::vector<std::string> browse_listnames; 1061 std::vector<std::string> browse_listnames;
988 browse_listnames.push_back(safe_browsing_util::kMalwareList); 1062 browse_listnames.push_back(safe_browsing_util::kMalwareList);
989 browse_listnames.push_back(safe_browsing_util::kPhishingList); 1063 browse_listnames.push_back(safe_browsing_util::kPhishingList);
990 UpdateChunkRanges(browse_store_.get(), browse_listnames, lists); 1064 UpdateChunkRanges(browse_store_.get(), browse_listnames, lists);
991 1065
992 if (download_store_.get()) { 1066 if (download_store_.get()) {
993 std::vector<std::string> download_listnames; 1067 std::vector<std::string> download_listnames;
994 download_listnames.push_back(safe_browsing_util::kBinUrlList); 1068 download_listnames.push_back(safe_browsing_util::kBinUrlList);
995 download_listnames.push_back(safe_browsing_util::kBinHashList); 1069 download_listnames.push_back(safe_browsing_util::kBinHashList);
996 UpdateChunkRanges(download_store_.get(), download_listnames, lists); 1070 UpdateChunkRanges(download_store_.get(), download_listnames, lists);
997 } 1071 }
998 1072
999 if (csd_whitelist_store_.get()) { 1073 if (csd_whitelist_store_.get()) {
1000 std::vector<std::string> csd_whitelist_listnames; 1074 std::vector<std::string> csd_whitelist_listnames;
1001 csd_whitelist_listnames.push_back(safe_browsing_util::kCsdWhiteList); 1075 csd_whitelist_listnames.push_back(safe_browsing_util::kCsdWhiteList);
1002 UpdateChunkRanges(csd_whitelist_store_.get(), 1076 UpdateChunkRanges(csd_whitelist_store_.get(),
1003 csd_whitelist_listnames, lists); 1077 csd_whitelist_listnames, lists);
1004 } 1078 }
1005 1079
1080 if (download_whitelist_store_.get()) {
1081 std::vector<std::string> download_whitelist_listnames;
1082 download_whitelist_listnames.push_back(
1083 safe_browsing_util::kDownloadWhiteList);
1084 UpdateChunkRanges(download_whitelist_store_.get(),
1085 download_whitelist_listnames, lists);
1086 }
1087
1006 corruption_detected_ = false; 1088 corruption_detected_ = false;
1007 change_detected_ = false; 1089 change_detected_ = false;
1008 return true; 1090 return true;
1009 } 1091 }
1010 1092
1011 void SafeBrowsingDatabaseNew::UpdateFinished(bool update_succeeded) { 1093 void SafeBrowsingDatabaseNew::UpdateFinished(bool update_succeeded) {
1012 DCHECK_EQ(creation_loop_, MessageLoop::current()); 1094 DCHECK_EQ(creation_loop_, MessageLoop::current());
1013 if (corruption_detected_) 1095 if (corruption_detected_)
1014 return; 1096 return;
1015 1097
1016 // Unroll the transaction if there was a protocol error or if the 1098 // Unroll the transaction if there was a protocol error or if the
1017 // transaction was empty. This will leave the bloom filter, the 1099 // transaction was empty. This will leave the bloom filter, the
1018 // pending hashes, and the prefix miss cache in place. 1100 // pending hashes, and the prefix miss cache in place.
1019 if (!update_succeeded || !change_detected_) { 1101 if (!update_succeeded || !change_detected_) {
1020 // Track empty updates to answer questions at http://crbug.com/72216 . 1102 // Track empty updates to answer questions at http://crbug.com/72216 .
1021 if (update_succeeded && !change_detected_) 1103 if (update_succeeded && !change_detected_)
1022 UMA_HISTOGRAM_COUNTS("SB2.DatabaseUpdateKilobytes", 0); 1104 UMA_HISTOGRAM_COUNTS("SB2.DatabaseUpdateKilobytes", 0);
1023 browse_store_->CancelUpdate(); 1105 browse_store_->CancelUpdate();
1024 if (download_store_.get()) 1106 if (download_store_.get())
1025 download_store_->CancelUpdate(); 1107 download_store_->CancelUpdate();
1026 if (csd_whitelist_store_.get()) 1108 if (csd_whitelist_store_.get())
1027 csd_whitelist_store_->CancelUpdate(); 1109 csd_whitelist_store_->CancelUpdate();
1110 if (download_whitelist_store_.get())
1111 download_whitelist_store_->CancelUpdate();
1028 return; 1112 return;
1029 } 1113 }
1030 1114
1031 // for download 1115 // for download
1032 UpdateDownloadStore(); 1116 UpdateDownloadStore();
1033 // for browsing 1117 // for browsing
1034 UpdateBrowseStore(); 1118 UpdateBrowseStore();
1035 // for csd whitelist 1119 // for csd and download whitelists.
1036 UpdateCsdWhitelistStore(); 1120 UpdateWhitelistStore(csd_whitelist_filename_,
1121 csd_whitelist_store_.get(),
1122 &csd_whitelist_);
1123 UpdateWhitelistStore(download_whitelist_filename_,
1124 download_whitelist_store_.get(),
1125 &download_whitelist_);
1037 } 1126 }
1038 1127
1039 void SafeBrowsingDatabaseNew::UpdateCsdWhitelistStore() { 1128 void SafeBrowsingDatabaseNew::UpdateWhitelistStore(
1040 if (!csd_whitelist_store_.get()) 1129 const FilePath& store_filename,
1130 SafeBrowsingStore* store,
1131 SBWhitelist* whitelist) {
1132 if (!store)
1041 return; 1133 return;
1042 1134
1043 // For the csd whitelist, we don't cache and save full hashes since all 1135 // For the whitelists, we don't cache and save full hashes since all
1044 // hashes are already full. 1136 // hashes are already full.
1045 std::vector<SBAddFullHash> empty_add_hashes; 1137 std::vector<SBAddFullHash> empty_add_hashes;
1046 1138
1047 // Not needed for the csd whitelist. 1139 // Not needed for the whitelists.
1048 std::set<SBPrefix> empty_miss_cache; 1140 std::set<SBPrefix> empty_miss_cache;
1049 1141
1050 // Note: prefixes will not be empty. The current data store implementation 1142 // Note: prefixes will not be empty. The current data store implementation
1051 // stores all full-length hashes as both full and prefix hashes. 1143 // stores all full-length hashes as both full and prefix hashes.
1052 std::vector<SBAddPrefix> prefixes; 1144 std::vector<SBAddPrefix> prefixes;
1053 std::vector<SBAddFullHash> full_hashes; 1145 std::vector<SBAddFullHash> full_hashes;
1054 if (!csd_whitelist_store_->FinishUpdate(empty_add_hashes, 1146 if (!store->FinishUpdate(empty_add_hashes, empty_miss_cache, &prefixes,
1055 empty_miss_cache, 1147 &full_hashes)) {
1056 &prefixes, 1148 RecordFailure(FAILURE_WHITELIST_DATABASE_UPDATE_FINISH);
1057 &full_hashes)) { 1149 WhitelistEverything(whitelist);
1058 RecordFailure(FAILURE_CSD_WHITELIST_DATABASE_UPDATE_FINISH);
1059 CsdWhitelistAllUrls();
1060 return; 1150 return;
1061 } 1151 }
1062 1152
1063 #if defined(OS_MACOSX) 1153 #if defined(OS_MACOSX)
1064 base::mac::SetFileBackupExclusion(csd_whitelist_filename_); 1154 base::mac::SetFileBackupExclusion(store_filename);
1065 #endif 1155 #endif
1066 1156
1067 LoadCsdWhitelist(full_hashes); 1157 LoadWhitelist(full_hashes, whitelist);
1068 } 1158 }
1069 1159
1070 void SafeBrowsingDatabaseNew::UpdateDownloadStore() { 1160 void SafeBrowsingDatabaseNew::UpdateDownloadStore() {
1071 if (!download_store_.get()) 1161 if (!download_store_.get())
1072 return; 1162 return;
1073 1163
1074 // For download, we don't cache and save full hashes. 1164 // For download, we don't cache and save full hashes.
1075 std::vector<SBAddFullHash> empty_add_hashes; 1165 std::vector<SBAddFullHash> empty_add_hashes;
1076 1166
1077 // For download, backend lookup happens only if a prefix is in add list. 1167 // For download, backend lookup happens only if a prefix is in add list.
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
1272 1362
1273 const bool r2 = download_store_.get() ? download_store_->Delete() : true; 1363 const bool r2 = download_store_.get() ? download_store_->Delete() : true;
1274 if (!r2) 1364 if (!r2)
1275 RecordFailure(FAILURE_DATABASE_STORE_DELETE); 1365 RecordFailure(FAILURE_DATABASE_STORE_DELETE);
1276 1366
1277 const bool r3 = csd_whitelist_store_.get() ? 1367 const bool r3 = csd_whitelist_store_.get() ?
1278 csd_whitelist_store_->Delete() : true; 1368 csd_whitelist_store_->Delete() : true;
1279 if (!r3) 1369 if (!r3)
1280 RecordFailure(FAILURE_DATABASE_STORE_DELETE); 1370 RecordFailure(FAILURE_DATABASE_STORE_DELETE);
1281 1371
1282 const bool r4 = file_util::Delete(bloom_filter_filename_, false); 1372 const bool r4 = download_whitelist_store_.get() ?
1373 download_whitelist_store_->Delete() : true;
1283 if (!r4) 1374 if (!r4)
1375 RecordFailure(FAILURE_DATABASE_STORE_DELETE);
1376
1377 const bool r5 = file_util::Delete(bloom_filter_filename_, false);
1378 if (!r5)
1284 RecordFailure(FAILURE_DATABASE_FILTER_DELETE); 1379 RecordFailure(FAILURE_DATABASE_FILTER_DELETE);
1285 return r1 && r2 && r3 && r4; 1380 return r1 && r2 && r3 && r4 && r5;
1286 } 1381 }
1287 1382
1288 void SafeBrowsingDatabaseNew::WriteBloomFilter() { 1383 void SafeBrowsingDatabaseNew::WriteBloomFilter() {
1289 DCHECK_EQ(creation_loop_, MessageLoop::current()); 1384 DCHECK_EQ(creation_loop_, MessageLoop::current());
1290 1385
1291 if (!browse_bloom_filter_.get()) 1386 if (!browse_bloom_filter_.get())
1292 return; 1387 return;
1293 1388
1294 const base::TimeTicks before = base::TimeTicks::Now(); 1389 const base::TimeTicks before = base::TimeTicks::Now();
1295 const bool write_ok = browse_bloom_filter_->WriteFile(bloom_filter_filename_); 1390 const bool write_ok = browse_bloom_filter_->WriteFile(bloom_filter_filename_);
1296 DVLOG(1) << "SafeBrowsingDatabaseNew wrote bloom filter in " 1391 DVLOG(1) << "SafeBrowsingDatabaseNew wrote bloom filter in "
1297 << (base::TimeTicks::Now() - before).InMilliseconds() << " ms"; 1392 << (base::TimeTicks::Now() - before).InMilliseconds() << " ms";
1298 1393
1299 if (!write_ok) 1394 if (!write_ok)
1300 RecordFailure(FAILURE_DATABASE_FILTER_WRITE); 1395 RecordFailure(FAILURE_DATABASE_FILTER_WRITE);
1301 1396
1302 #if defined(OS_MACOSX) 1397 #if defined(OS_MACOSX)
1303 base::mac::SetFileBackupExclusion(bloom_filter_filename_); 1398 base::mac::SetFileBackupExclusion(bloom_filter_filename_);
1304 #endif 1399 #endif
1305 } 1400 }
1306 1401
1307 void SafeBrowsingDatabaseNew::CsdWhitelistAllUrls() { 1402 void SafeBrowsingDatabaseNew::WhitelistEverything(SBWhitelist* whitelist) {
1308 base::AutoLock locked(lookup_lock_); 1403 base::AutoLock locked(lookup_lock_);
1309 csd_whitelist_all_urls_ = true; 1404 whitelist->second = true;
1310 csd_whitelist_.clear(); 1405 whitelist->first.clear();
1311 } 1406 }
1312 1407
1313 void SafeBrowsingDatabaseNew::LoadCsdWhitelist( 1408 void SafeBrowsingDatabaseNew::LoadWhitelist(
1314 const std::vector<SBAddFullHash>& full_hashes) { 1409 const std::vector<SBAddFullHash>& full_hashes,
1410 SBWhitelist* whitelist) {
1315 DCHECK_EQ(creation_loop_, MessageLoop::current()); 1411 DCHECK_EQ(creation_loop_, MessageLoop::current());
1316 if (full_hashes.size() > kMaxCsdWhitelistSize) { 1412 if (full_hashes.size() > kMaxWhitelistSize) {
1317 CsdWhitelistAllUrls(); 1413 WhitelistEverything(whitelist);
1318 return; 1414 return;
1319 } 1415 }
1320 1416
1321 std::vector<SBFullHash> new_csd_whitelist; 1417 std::vector<SBFullHash> new_whitelist;
1322 for (std::vector<SBAddFullHash>::const_iterator it = full_hashes.begin(); 1418 for (std::vector<SBAddFullHash>::const_iterator it = full_hashes.begin();
1323 it != full_hashes.end(); ++it) { 1419 it != full_hashes.end(); ++it) {
1324 new_csd_whitelist.push_back(it->full_hash); 1420 new_whitelist.push_back(it->full_hash);
1325 } 1421 }
1326 std::sort(new_csd_whitelist.begin(), new_csd_whitelist.end()); 1422 std::sort(new_whitelist.begin(), new_whitelist.end());
1327 1423
1328 SBFullHash kill_switch; 1424 SBFullHash kill_switch;
1329 crypto::SHA256HashString(kCsdKillSwitchUrl, &kill_switch, 1425 crypto::SHA256HashString(kWhitelistKillSwitchUrl, &kill_switch,
1330 sizeof(kill_switch)); 1426 sizeof(kill_switch));
1331 if (std::binary_search(new_csd_whitelist.begin(), new_csd_whitelist.end(), 1427 if (std::binary_search(new_whitelist.begin(), new_whitelist.end(),
1332 kill_switch)) { 1428 kill_switch)) {
1333 // The kill switch is whitelisted hence we whitelist all URLs. 1429 // The kill switch is whitelisted hence we whitelist all URLs.
1334 CsdWhitelistAllUrls(); 1430 WhitelistEverything(whitelist);
1335 } else { 1431 } else {
1336 base::AutoLock locked(lookup_lock_); 1432 base::AutoLock locked(lookup_lock_);
1337 csd_whitelist_all_urls_ = false; 1433 whitelist->second = false;
1338 csd_whitelist_.swap(new_csd_whitelist); 1434 whitelist->first.swap(new_whitelist);
1339 } 1435 }
1340 } 1436 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698