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

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: Address Matt's comment. 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 whitelists.
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()) {
(...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after
388 return prefix_set.release(); 391 return prefix_set.release();
389 } 392 }
390 393
391 } // namespace 394 } // namespace
392 395
393 // The default SafeBrowsingDatabaseFactory. 396 // The default SafeBrowsingDatabaseFactory.
394 class SafeBrowsingDatabaseFactoryImpl : public SafeBrowsingDatabaseFactory { 397 class SafeBrowsingDatabaseFactoryImpl : public SafeBrowsingDatabaseFactory {
395 public: 398 public:
396 virtual SafeBrowsingDatabase* CreateSafeBrowsingDatabase( 399 virtual SafeBrowsingDatabase* CreateSafeBrowsingDatabase(
397 bool enable_download_protection, 400 bool enable_download_protection,
398 bool enable_client_side_whitelist) { 401 bool enable_client_side_whitelist,
402 bool enable_download_whitelist) {
399 return new SafeBrowsingDatabaseNew( 403 return new SafeBrowsingDatabaseNew(
400 new SafeBrowsingStoreFile, 404 new SafeBrowsingStoreFile,
401 enable_download_protection ? new SafeBrowsingStoreFile : NULL, 405 enable_download_protection ? new SafeBrowsingStoreFile : NULL,
402 enable_client_side_whitelist ? new SafeBrowsingStoreFile : NULL); 406 enable_client_side_whitelist ? new SafeBrowsingStoreFile : NULL,
407 enable_download_whitelist ? new SafeBrowsingStoreFile : NULL);
403 } 408 }
404 409
405 SafeBrowsingDatabaseFactoryImpl() { } 410 SafeBrowsingDatabaseFactoryImpl() { }
406 411
407 private: 412 private:
408 DISALLOW_COPY_AND_ASSIGN(SafeBrowsingDatabaseFactoryImpl); 413 DISALLOW_COPY_AND_ASSIGN(SafeBrowsingDatabaseFactoryImpl);
409 }; 414 };
410 415
411 // static 416 // static
412 SafeBrowsingDatabaseFactory* SafeBrowsingDatabase::factory_ = NULL; 417 SafeBrowsingDatabaseFactory* SafeBrowsingDatabase::factory_ = NULL;
413 418
414 // Factory method, non-thread safe. Caller has to make sure this s called 419 // Factory method, non-thread safe. Caller has to make sure this s called
415 // on SafeBrowsing Thread. 420 // on SafeBrowsing Thread.
416 // TODO(shess): There's no need for a factory any longer. Convert 421 // TODO(shess): There's no need for a factory any longer. Convert
417 // SafeBrowsingDatabaseNew to SafeBrowsingDatabase, and have Create() 422 // SafeBrowsingDatabaseNew to SafeBrowsingDatabase, and have Create()
418 // callers just construct things directly. 423 // callers just construct things directly.
419 SafeBrowsingDatabase* SafeBrowsingDatabase::Create( 424 SafeBrowsingDatabase* SafeBrowsingDatabase::Create(
420 bool enable_download_protection, 425 bool enable_download_protection,
421 bool enable_client_side_whitelist) { 426 bool enable_client_side_whitelist,
427 bool enable_download_whitelist) {
422 if (!factory_) 428 if (!factory_)
423 factory_ = new SafeBrowsingDatabaseFactoryImpl(); 429 factory_ = new SafeBrowsingDatabaseFactoryImpl();
424 return factory_->CreateSafeBrowsingDatabase(enable_download_protection, 430 return factory_->CreateSafeBrowsingDatabase(enable_download_protection,
425 enable_client_side_whitelist); 431 enable_client_side_whitelist,
432 enable_download_whitelist);
426 } 433 }
427 434
428 SafeBrowsingDatabase::~SafeBrowsingDatabase() { 435 SafeBrowsingDatabase::~SafeBrowsingDatabase() {
429 } 436 }
430 437
431 // static 438 // static
432 FilePath SafeBrowsingDatabase::BrowseDBFilename( 439 FilePath SafeBrowsingDatabase::BrowseDBFilename(
433 const FilePath& db_base_filename) { 440 const FilePath& db_base_filename) {
434 return FilePath(db_base_filename.value() + kBrowseDBFile); 441 return FilePath(db_base_filename.value() + kBrowseDBFile);
435 } 442 }
436 443
437 // static 444 // static
438 FilePath SafeBrowsingDatabase::DownloadDBFilename( 445 FilePath SafeBrowsingDatabase::DownloadDBFilename(
439 const FilePath& db_base_filename) { 446 const FilePath& db_base_filename) {
440 return FilePath(db_base_filename.value() + kDownloadDBFile); 447 return FilePath(db_base_filename.value() + kDownloadDBFile);
441 } 448 }
442 449
443 // static 450 // static
444 FilePath SafeBrowsingDatabase::BloomFilterForFilename( 451 FilePath SafeBrowsingDatabase::BloomFilterForFilename(
445 const FilePath& db_filename) { 452 const FilePath& db_filename) {
446 return FilePath(db_filename.value() + kBloomFilterFile); 453 return FilePath(db_filename.value() + kBloomFilterFile);
447 } 454 }
448 455
449 // static 456 // static
450 FilePath SafeBrowsingDatabase::CsdWhitelistDBFilename( 457 FilePath SafeBrowsingDatabase::CsdWhitelistDBFilename(
451 const FilePath& db_filename) { 458 const FilePath& db_filename) {
452 return FilePath(db_filename.value() + kCsdWhitelistDBFile); 459 return FilePath(db_filename.value() + kCsdWhitelistDBFile);
453 } 460 }
454 461
462 // static
463 FilePath SafeBrowsingDatabase::DownloadWhitelistDBFilename(
464 const FilePath& db_filename) {
465 return FilePath(db_filename.value() + kDownloadWhitelistDBFile);
466 }
467
455 SafeBrowsingStore* SafeBrowsingDatabaseNew::GetStore(const int list_id) { 468 SafeBrowsingStore* SafeBrowsingDatabaseNew::GetStore(const int list_id) {
456 if (list_id == safe_browsing_util::PHISH || 469 if (list_id == safe_browsing_util::PHISH ||
457 list_id == safe_browsing_util::MALWARE) { 470 list_id == safe_browsing_util::MALWARE) {
458 return browse_store_.get(); 471 return browse_store_.get();
459 } else if (list_id == safe_browsing_util::BINURL || 472 } else if (list_id == safe_browsing_util::BINURL ||
460 list_id == safe_browsing_util::BINHASH) { 473 list_id == safe_browsing_util::BINHASH) {
461 return download_store_.get(); 474 return download_store_.get();
462 } else if (list_id == safe_browsing_util::CSDWHITELIST) { 475 } else if (list_id == safe_browsing_util::CSDWHITELIST) {
463 return csd_whitelist_store_.get(); 476 return csd_whitelist_store_.get();
477 } else if (list_id == safe_browsing_util::DOWNLOADWHITELIST) {
478 return download_whitelist_store_.get();
464 } 479 }
465 return NULL; 480 return NULL;
466 } 481 }
467 482
468 // static 483 // static
469 void SafeBrowsingDatabase::RecordFailure(FailureType failure_type) { 484 void SafeBrowsingDatabase::RecordFailure(FailureType failure_type) {
470 UMA_HISTOGRAM_ENUMERATION("SB2.DatabaseFailure", failure_type, 485 UMA_HISTOGRAM_ENUMERATION("SB2.DatabaseFailure", failure_type,
471 FAILURE_DATABASE_MAX); 486 FAILURE_DATABASE_MAX);
472 } 487 }
473 488
474 SafeBrowsingDatabaseNew::SafeBrowsingDatabaseNew() 489 SafeBrowsingDatabaseNew::SafeBrowsingDatabaseNew()
475 : creation_loop_(MessageLoop::current()), 490 : creation_loop_(MessageLoop::current()),
476 browse_store_(new SafeBrowsingStoreFile), 491 browse_store_(new SafeBrowsingStoreFile),
477 download_store_(NULL), 492 download_store_(NULL),
478 csd_whitelist_store_(NULL), 493 csd_whitelist_store_(NULL),
494 download_whitelist_store_(NULL),
479 ALLOW_THIS_IN_INITIALIZER_LIST(reset_factory_(this)) { 495 ALLOW_THIS_IN_INITIALIZER_LIST(reset_factory_(this)) {
480 DCHECK(browse_store_.get()); 496 DCHECK(browse_store_.get());
481 DCHECK(!download_store_.get()); 497 DCHECK(!download_store_.get());
482 DCHECK(!csd_whitelist_store_.get()); 498 DCHECK(!csd_whitelist_store_.get());
499 DCHECK(!download_whitelist_store_.get());
483 } 500 }
484 501
485 SafeBrowsingDatabaseNew::SafeBrowsingDatabaseNew( 502 SafeBrowsingDatabaseNew::SafeBrowsingDatabaseNew(
486 SafeBrowsingStore* browse_store, 503 SafeBrowsingStore* browse_store,
487 SafeBrowsingStore* download_store, 504 SafeBrowsingStore* download_store,
488 SafeBrowsingStore* csd_whitelist_store) 505 SafeBrowsingStore* csd_whitelist_store,
506 SafeBrowsingStore* download_whitelist_store)
489 : creation_loop_(MessageLoop::current()), 507 : creation_loop_(MessageLoop::current()),
490 browse_store_(browse_store), 508 browse_store_(browse_store),
491 download_store_(download_store), 509 download_store_(download_store),
492 csd_whitelist_store_(csd_whitelist_store), 510 csd_whitelist_store_(csd_whitelist_store),
511 download_whitelist_store_(download_whitelist_store),
493 ALLOW_THIS_IN_INITIALIZER_LIST(reset_factory_(this)), 512 ALLOW_THIS_IN_INITIALIZER_LIST(reset_factory_(this)),
494 corruption_detected_(false) { 513 corruption_detected_(false) {
495 DCHECK(browse_store_.get()); 514 DCHECK(browse_store_.get());
496 } 515 }
497 516
498 SafeBrowsingDatabaseNew::~SafeBrowsingDatabaseNew() { 517 SafeBrowsingDatabaseNew::~SafeBrowsingDatabaseNew() {
499 DCHECK_EQ(creation_loop_, MessageLoop::current()); 518 DCHECK_EQ(creation_loop_, MessageLoop::current());
500 } 519 }
501 520
502 void SafeBrowsingDatabaseNew::Init(const FilePath& filename_base) { 521 void SafeBrowsingDatabaseNew::Init(const FilePath& filename_base) {
503 DCHECK_EQ(creation_loop_, MessageLoop::current()); 522 DCHECK_EQ(creation_loop_, MessageLoop::current());
504 // Ensure we haven't been run before. 523 // Ensure we haven't been run before.
505 DCHECK(browse_filename_.empty()); 524 DCHECK(browse_filename_.empty());
506 DCHECK(download_filename_.empty()); 525 DCHECK(download_filename_.empty());
507 DCHECK(csd_whitelist_filename_.empty()); 526 DCHECK(csd_whitelist_filename_.empty());
527 DCHECK(download_whitelist_filename_.empty());
508 528
509 browse_filename_ = BrowseDBFilename(filename_base); 529 browse_filename_ = BrowseDBFilename(filename_base);
510 bloom_filter_filename_ = BloomFilterForFilename(browse_filename_); 530 bloom_filter_filename_ = BloomFilterForFilename(browse_filename_);
511 531
512 browse_store_->Init( 532 browse_store_->Init(
513 browse_filename_, 533 browse_filename_,
514 NewCallback(this, &SafeBrowsingDatabaseNew::HandleCorruptDatabase)); 534 NewCallback(this, &SafeBrowsingDatabaseNew::HandleCorruptDatabase));
515 DVLOG(1) << "Init browse store: " << browse_filename_.value(); 535 DVLOG(1) << "Init browse store: " << browse_filename_.value();
516 536
517 { 537 {
(...skipping 16 matching lines...) Expand all
534 } 554 }
535 555
536 if (csd_whitelist_store_.get()) { 556 if (csd_whitelist_store_.get()) {
537 csd_whitelist_filename_ = CsdWhitelistDBFilename(filename_base); 557 csd_whitelist_filename_ = CsdWhitelistDBFilename(filename_base);
538 csd_whitelist_store_->Init( 558 csd_whitelist_store_->Init(
539 csd_whitelist_filename_, 559 csd_whitelist_filename_,
540 NewCallback(this, &SafeBrowsingDatabaseNew::HandleCorruptDatabase)); 560 NewCallback(this, &SafeBrowsingDatabaseNew::HandleCorruptDatabase));
541 DVLOG(1) << "Init csd whitelist store: " << csd_whitelist_filename_.value(); 561 DVLOG(1) << "Init csd whitelist store: " << csd_whitelist_filename_.value();
542 std::vector<SBAddFullHash> full_hashes; 562 std::vector<SBAddFullHash> full_hashes;
543 if (csd_whitelist_store_->GetAddFullHashes(&full_hashes)) { 563 if (csd_whitelist_store_->GetAddFullHashes(&full_hashes)) {
544 LoadCsdWhitelist(full_hashes); 564 LoadWhitelist(full_hashes, &csd_whitelist_);
545 } else { 565 } else {
546 CsdWhitelistAllUrls(); 566 WhitelistEverything(&csd_whitelist_);
547 } 567 }
548 } else { 568 } else {
549 CsdWhitelistAllUrls(); // Just to be safe. 569 WhitelistEverything(&csd_whitelist_); // Just to be safe.
570 }
571
572 if (download_whitelist_store_.get()) {
573 download_whitelist_filename_ = DownloadWhitelistDBFilename(filename_base);
574 download_whitelist_store_->Init(
575 download_whitelist_filename_,
576 NewCallback(this, &SafeBrowsingDatabaseNew::HandleCorruptDatabase));
577 DVLOG(1) << "Init download whitelist store: "
578 << download_whitelist_filename_.value();
579 std::vector<SBAddFullHash> full_hashes;
580 if (download_whitelist_store_->GetAddFullHashes(&full_hashes)) {
581 LoadWhitelist(full_hashes, &download_whitelist_);
582 } else {
583 WhitelistEverything(&download_whitelist_);
584 }
585 } else {
586 WhitelistEverything(&download_whitelist_); // Just to be safe.
550 } 587 }
551 } 588 }
552 589
553 bool SafeBrowsingDatabaseNew::ResetDatabase() { 590 bool SafeBrowsingDatabaseNew::ResetDatabase() {
554 DCHECK_EQ(creation_loop_, MessageLoop::current()); 591 DCHECK_EQ(creation_loop_, MessageLoop::current());
555 592
556 // Delete files on disk. 593 // Delete files on disk.
557 // TODO(shess): Hard to see where one might want to delete without a 594 // TODO(shess): Hard to see where one might want to delete without a
558 // reset. Perhaps inline |Delete()|? 595 // reset. Perhaps inline |Delete()|?
559 if (!Delete()) 596 if (!Delete())
560 return false; 597 return false;
561 598
562 // Reset objects in memory. 599 // Reset objects in memory.
563 { 600 {
564 base::AutoLock locked(lookup_lock_); 601 base::AutoLock locked(lookup_lock_);
565 full_browse_hashes_.clear(); 602 full_browse_hashes_.clear();
566 pending_browse_hashes_.clear(); 603 pending_browse_hashes_.clear();
567 prefix_miss_cache_.clear(); 604 prefix_miss_cache_.clear();
568 // TODO(shess): This could probably be |bloom_filter_.reset()|. 605 // TODO(shess): This could probably be |bloom_filter_.reset()|.
569 browse_bloom_filter_ = new BloomFilter(BloomFilter::kBloomFilterMinSize * 606 browse_bloom_filter_ = new BloomFilter(BloomFilter::kBloomFilterMinSize *
570 BloomFilter::kBloomFilterSizeRatio); 607 BloomFilter::kBloomFilterSizeRatio);
571 // TODO(shess): It is simpler for the code to assume that presence 608 // TODO(shess): It is simpler for the code to assume that presence
572 // of a bloom filter always implies presence of a prefix set. 609 // of a bloom filter always implies presence of a prefix set.
573 prefix_set_.reset(new safe_browsing::PrefixSet(std::vector<SBPrefix>())); 610 prefix_set_.reset(new safe_browsing::PrefixSet(std::vector<SBPrefix>()));
574 } 611 }
575 // Wants to acquire the lock itself. 612 // Wants to acquire the lock itself.
576 CsdWhitelistAllUrls(); 613 WhitelistEverything(&csd_whitelist_);
614 WhitelistEverything(&download_whitelist_);
577 615
578 return true; 616 return true;
579 } 617 }
580 618
581 // TODO(lzheng): Remove matching_list, it is not used anywhere. 619 // TODO(lzheng): Remove matching_list, it is not used anywhere.
582 bool SafeBrowsingDatabaseNew::ContainsBrowseUrl( 620 bool SafeBrowsingDatabaseNew::ContainsBrowseUrl(
583 const GURL& url, 621 const GURL& url,
584 std::string* matching_list, 622 std::string* matching_list,
585 std::vector<SBPrefix>* prefix_hits, 623 std::vector<SBPrefix>* prefix_hits,
586 std::vector<SBFullHashResult>* full_hits, 624 std::vector<SBFullHashResult>* full_hits,
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
706 std::vector<SBPrefix> prefix_hits; 744 std::vector<SBPrefix> prefix_hits;
707 return MatchDownloadAddPrefixes(safe_browsing_util::BINHASH % 2, 745 return MatchDownloadAddPrefixes(safe_browsing_util::BINHASH % 2,
708 prefixes, 746 prefixes,
709 &prefix_hits); 747 &prefix_hits);
710 } 748 }
711 749
712 bool SafeBrowsingDatabaseNew::ContainsCsdWhitelistedUrl(const GURL& url) { 750 bool SafeBrowsingDatabaseNew::ContainsCsdWhitelistedUrl(const GURL& url) {
713 // This method is theoretically thread-safe but we expect all calls to 751 // This method is theoretically thread-safe but we expect all calls to
714 // originate from the IO thread. 752 // originate from the IO thread.
715 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 753 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; 754 std::vector<SBFullHash> full_hashes;
721 BrowseFullHashesToCheck(url, true, &full_hashes); 755 BrowseFullHashesToCheck(url, true, &full_hashes);
722 for (std::vector<SBFullHash>::const_iterator it = full_hashes.begin(); 756 return ContainsWhitelistedHashes(csd_whitelist_, full_hashes);
723 it != full_hashes.end(); ++it) { 757 }
724 if (std::binary_search(csd_whitelist_.begin(), csd_whitelist_.end(), *it)) 758
759 bool SafeBrowsingDatabaseNew::ContainsDownloadWhitelistedUrl(const GURL& url) {
760 std::vector<SBFullHash> full_hashes;
761 BrowseFullHashesToCheck(url, true, &full_hashes);
762 return ContainsWhitelistedHashes(download_whitelist_, full_hashes);
763 }
764
765 bool SafeBrowsingDatabaseNew::ContainsDownloadWhitelistedString(
766 const std::string& str) {
767 SBFullHash hash;
768 crypto::SHA256HashString(str, &hash, sizeof(hash));
769 std::vector<SBFullHash> hashes;
770 hashes.push_back(hash);
771 return ContainsWhitelistedHashes(download_whitelist_, hashes);
772 }
773
774 bool SafeBrowsingDatabaseNew::ContainsWhitelistedHashes(
775 const SBWhitelist& whitelist,
776 const std::vector<SBFullHash>& hashes) {
777 base::AutoLock l(lookup_lock_);
778 if (whitelist.second)
779 return true;
780 for (std::vector<SBFullHash>::const_iterator it = hashes.begin();
781 it != hashes.end(); ++it) {
782 if (std::binary_search(whitelist.first.begin(), whitelist.first.end(), *it))
725 return true; 783 return true;
726 } 784 }
727 return false; 785 return false;
728 } 786 }
729 787
730 // Helper to insert entries for all of the prefixes or full hashes in 788 // Helper to insert entries for all of the prefixes or full hashes in
731 // |entry| into the store. 789 // |entry| into the store.
732 void SafeBrowsingDatabaseNew::InsertAdd(int chunk_id, SBPrefix host, 790 void SafeBrowsingDatabaseNew::InsertAdd(int chunk_id, SBPrefix host,
733 const SBEntry* entry, int list_id) { 791 const SBEntry* entry, int list_id) {
734 DCHECK_EQ(creation_loop_, MessageLoop::current()); 792 DCHECK_EQ(creation_loop_, MessageLoop::current());
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after
972 return false; 1030 return false;
973 } 1031 }
974 1032
975 if (download_store_.get() && !download_store_->BeginUpdate()) { 1033 if (download_store_.get() && !download_store_->BeginUpdate()) {
976 RecordFailure(FAILURE_DOWNLOAD_DATABASE_UPDATE_BEGIN); 1034 RecordFailure(FAILURE_DOWNLOAD_DATABASE_UPDATE_BEGIN);
977 HandleCorruptDatabase(); 1035 HandleCorruptDatabase();
978 return false; 1036 return false;
979 } 1037 }
980 1038
981 if (csd_whitelist_store_.get() && !csd_whitelist_store_->BeginUpdate()) { 1039 if (csd_whitelist_store_.get() && !csd_whitelist_store_->BeginUpdate()) {
982 RecordFailure(FAILURE_CSD_WHITELIST_DATABASE_UPDATE_BEGIN); 1040 RecordFailure(FAILURE_WHITELIST_DATABASE_UPDATE_BEGIN);
983 HandleCorruptDatabase(); 1041 HandleCorruptDatabase();
984 return false; 1042 return false;
985 } 1043 }
1044
1045 if (download_whitelist_store_.get() &&
1046 !download_whitelist_store_->BeginUpdate()) {
1047 RecordFailure(FAILURE_WHITELIST_DATABASE_UPDATE_BEGIN);
1048 HandleCorruptDatabase();
1049 return false;
1050 }
986 1051
987 std::vector<std::string> browse_listnames; 1052 std::vector<std::string> browse_listnames;
988 browse_listnames.push_back(safe_browsing_util::kMalwareList); 1053 browse_listnames.push_back(safe_browsing_util::kMalwareList);
989 browse_listnames.push_back(safe_browsing_util::kPhishingList); 1054 browse_listnames.push_back(safe_browsing_util::kPhishingList);
990 UpdateChunkRanges(browse_store_.get(), browse_listnames, lists); 1055 UpdateChunkRanges(browse_store_.get(), browse_listnames, lists);
991 1056
992 if (download_store_.get()) { 1057 if (download_store_.get()) {
993 std::vector<std::string> download_listnames; 1058 std::vector<std::string> download_listnames;
994 download_listnames.push_back(safe_browsing_util::kBinUrlList); 1059 download_listnames.push_back(safe_browsing_util::kBinUrlList);
995 download_listnames.push_back(safe_browsing_util::kBinHashList); 1060 download_listnames.push_back(safe_browsing_util::kBinHashList);
996 UpdateChunkRanges(download_store_.get(), download_listnames, lists); 1061 UpdateChunkRanges(download_store_.get(), download_listnames, lists);
997 } 1062 }
998 1063
999 if (csd_whitelist_store_.get()) { 1064 if (csd_whitelist_store_.get()) {
1000 std::vector<std::string> csd_whitelist_listnames; 1065 std::vector<std::string> csd_whitelist_listnames;
1001 csd_whitelist_listnames.push_back(safe_browsing_util::kCsdWhiteList); 1066 csd_whitelist_listnames.push_back(safe_browsing_util::kCsdWhiteList);
1002 UpdateChunkRanges(csd_whitelist_store_.get(), 1067 UpdateChunkRanges(csd_whitelist_store_.get(),
1003 csd_whitelist_listnames, lists); 1068 csd_whitelist_listnames, lists);
1004 } 1069 }
1005 1070
1071 if (download_whitelist_store_.get()) {
1072 std::vector<std::string> download_whitelist_listnames;
1073 download_whitelist_listnames.push_back(
1074 safe_browsing_util::kDownloadWhiteList);
1075 UpdateChunkRanges(download_whitelist_store_.get(),
1076 download_whitelist_listnames, lists);
1077 }
1078
1006 corruption_detected_ = false; 1079 corruption_detected_ = false;
1007 change_detected_ = false; 1080 change_detected_ = false;
1008 return true; 1081 return true;
1009 } 1082 }
1010 1083
1011 void SafeBrowsingDatabaseNew::UpdateFinished(bool update_succeeded) { 1084 void SafeBrowsingDatabaseNew::UpdateFinished(bool update_succeeded) {
1012 DCHECK_EQ(creation_loop_, MessageLoop::current()); 1085 DCHECK_EQ(creation_loop_, MessageLoop::current());
1013 if (corruption_detected_) 1086 if (corruption_detected_)
1014 return; 1087 return;
1015 1088
1016 // Unroll the transaction if there was a protocol error or if the 1089 // Unroll the transaction if there was a protocol error or if the
1017 // transaction was empty. This will leave the bloom filter, the 1090 // transaction was empty. This will leave the bloom filter, the
1018 // pending hashes, and the prefix miss cache in place. 1091 // pending hashes, and the prefix miss cache in place.
1019 if (!update_succeeded || !change_detected_) { 1092 if (!update_succeeded || !change_detected_) {
1020 // Track empty updates to answer questions at http://crbug.com/72216 . 1093 // Track empty updates to answer questions at http://crbug.com/72216 .
1021 if (update_succeeded && !change_detected_) 1094 if (update_succeeded && !change_detected_)
1022 UMA_HISTOGRAM_COUNTS("SB2.DatabaseUpdateKilobytes", 0); 1095 UMA_HISTOGRAM_COUNTS("SB2.DatabaseUpdateKilobytes", 0);
1023 browse_store_->CancelUpdate(); 1096 browse_store_->CancelUpdate();
1024 if (download_store_.get()) 1097 if (download_store_.get())
1025 download_store_->CancelUpdate(); 1098 download_store_->CancelUpdate();
1026 if (csd_whitelist_store_.get()) 1099 if (csd_whitelist_store_.get())
1027 csd_whitelist_store_->CancelUpdate(); 1100 csd_whitelist_store_->CancelUpdate();
1101 if (download_whitelist_store_.get())
1102 download_whitelist_store_->CancelUpdate();
1028 return; 1103 return;
1029 } 1104 }
1030 1105
1031 // for download 1106 // for download
1032 UpdateDownloadStore(); 1107 UpdateDownloadStore();
1033 // for browsing 1108 // for browsing
1034 UpdateBrowseStore(); 1109 UpdateBrowseStore();
1035 // for csd whitelist 1110 // for csd and download whitelists.
1036 UpdateCsdWhitelistStore(); 1111 UpdateWhitelistStore(csd_whitelist_filename_,
1112 csd_whitelist_store_.get(),
1113 &csd_whitelist_);
1114 UpdateWhitelistStore(download_whitelist_filename_,
1115 download_whitelist_store_.get(),
1116 &download_whitelist_);
1037 } 1117 }
1038 1118
1039 void SafeBrowsingDatabaseNew::UpdateCsdWhitelistStore() { 1119 void SafeBrowsingDatabaseNew::UpdateWhitelistStore(
1040 if (!csd_whitelist_store_.get()) 1120 const FilePath& store_filename,
1121 SafeBrowsingStore* store,
1122 SBWhitelist* whitelist) {
1123 if (!store)
1041 return; 1124 return;
1042 1125
1043 // For the csd whitelist, we don't cache and save full hashes since all 1126 // For the whitelists, we don't cache and save full hashes since all
1044 // hashes are already full. 1127 // hashes are already full.
1045 std::vector<SBAddFullHash> empty_add_hashes; 1128 std::vector<SBAddFullHash> empty_add_hashes;
1046 1129
1047 // Not needed for the csd whitelist. 1130 // Not needed for the whitelists.
1048 std::set<SBPrefix> empty_miss_cache; 1131 std::set<SBPrefix> empty_miss_cache;
1049 1132
1050 // Note: prefixes will not be empty. The current data store implementation 1133 // Note: prefixes will not be empty. The current data store implementation
1051 // stores all full-length hashes as both full and prefix hashes. 1134 // stores all full-length hashes as both full and prefix hashes.
1052 std::vector<SBAddPrefix> prefixes; 1135 std::vector<SBAddPrefix> prefixes;
1053 std::vector<SBAddFullHash> full_hashes; 1136 std::vector<SBAddFullHash> full_hashes;
1054 if (!csd_whitelist_store_->FinishUpdate(empty_add_hashes, 1137 if (!store->FinishUpdate(empty_add_hashes, empty_miss_cache, &prefixes,
1055 empty_miss_cache, 1138 &full_hashes)) {
1056 &prefixes, 1139 RecordFailure(FAILURE_WHITELIST_DATABASE_UPDATE_FINISH);
1057 &full_hashes)) { 1140 WhitelistEverything(whitelist);
1058 RecordFailure(FAILURE_CSD_WHITELIST_DATABASE_UPDATE_FINISH);
1059 CsdWhitelistAllUrls();
1060 return; 1141 return;
1061 } 1142 }
1062 1143
1063 #if defined(OS_MACOSX) 1144 #if defined(OS_MACOSX)
1064 base::mac::SetFileBackupExclusion(csd_whitelist_filename_); 1145 base::mac::SetFileBackupExclusion(store_filename);
1065 #endif 1146 #endif
1066 1147
1067 LoadCsdWhitelist(full_hashes); 1148 LoadWhitelist(full_hashes, whitelist);
1068 } 1149 }
1069 1150
1070 void SafeBrowsingDatabaseNew::UpdateDownloadStore() { 1151 void SafeBrowsingDatabaseNew::UpdateDownloadStore() {
1071 if (!download_store_.get()) 1152 if (!download_store_.get())
1072 return; 1153 return;
1073 1154
1074 // For download, we don't cache and save full hashes. 1155 // For download, we don't cache and save full hashes.
1075 std::vector<SBAddFullHash> empty_add_hashes; 1156 std::vector<SBAddFullHash> empty_add_hashes;
1076 1157
1077 // For download, backend lookup happens only if a prefix is in add list. 1158 // 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 1353
1273 const bool r2 = download_store_.get() ? download_store_->Delete() : true; 1354 const bool r2 = download_store_.get() ? download_store_->Delete() : true;
1274 if (!r2) 1355 if (!r2)
1275 RecordFailure(FAILURE_DATABASE_STORE_DELETE); 1356 RecordFailure(FAILURE_DATABASE_STORE_DELETE);
1276 1357
1277 const bool r3 = csd_whitelist_store_.get() ? 1358 const bool r3 = csd_whitelist_store_.get() ?
1278 csd_whitelist_store_->Delete() : true; 1359 csd_whitelist_store_->Delete() : true;
1279 if (!r3) 1360 if (!r3)
1280 RecordFailure(FAILURE_DATABASE_STORE_DELETE); 1361 RecordFailure(FAILURE_DATABASE_STORE_DELETE);
1281 1362
1282 const bool r4 = file_util::Delete(bloom_filter_filename_, false); 1363 const bool r4 = download_whitelist_store_.get() ?
1364 download_whitelist_store_->Delete() : true;
1283 if (!r4) 1365 if (!r4)
1366 RecordFailure(FAILURE_DATABASE_STORE_DELETE);
1367
1368 const bool r5 = file_util::Delete(bloom_filter_filename_, false);
1369 if (!r5)
1284 RecordFailure(FAILURE_DATABASE_FILTER_DELETE); 1370 RecordFailure(FAILURE_DATABASE_FILTER_DELETE);
1285 return r1 && r2 && r3 && r4; 1371 return r1 && r2 && r3 && r4 && r5;
1286 } 1372 }
1287 1373
1288 void SafeBrowsingDatabaseNew::WriteBloomFilter() { 1374 void SafeBrowsingDatabaseNew::WriteBloomFilter() {
1289 DCHECK_EQ(creation_loop_, MessageLoop::current()); 1375 DCHECK_EQ(creation_loop_, MessageLoop::current());
1290 1376
1291 if (!browse_bloom_filter_.get()) 1377 if (!browse_bloom_filter_.get())
1292 return; 1378 return;
1293 1379
1294 const base::TimeTicks before = base::TimeTicks::Now(); 1380 const base::TimeTicks before = base::TimeTicks::Now();
1295 const bool write_ok = browse_bloom_filter_->WriteFile(bloom_filter_filename_); 1381 const bool write_ok = browse_bloom_filter_->WriteFile(bloom_filter_filename_);
1296 DVLOG(1) << "SafeBrowsingDatabaseNew wrote bloom filter in " 1382 DVLOG(1) << "SafeBrowsingDatabaseNew wrote bloom filter in "
1297 << (base::TimeTicks::Now() - before).InMilliseconds() << " ms"; 1383 << (base::TimeTicks::Now() - before).InMilliseconds() << " ms";
1298 1384
1299 if (!write_ok) 1385 if (!write_ok)
1300 RecordFailure(FAILURE_DATABASE_FILTER_WRITE); 1386 RecordFailure(FAILURE_DATABASE_FILTER_WRITE);
1301 1387
1302 #if defined(OS_MACOSX) 1388 #if defined(OS_MACOSX)
1303 base::mac::SetFileBackupExclusion(bloom_filter_filename_); 1389 base::mac::SetFileBackupExclusion(bloom_filter_filename_);
1304 #endif 1390 #endif
1305 } 1391 }
1306 1392
1307 void SafeBrowsingDatabaseNew::CsdWhitelistAllUrls() { 1393 void SafeBrowsingDatabaseNew::WhitelistEverything(SBWhitelist* whitelist) {
1308 base::AutoLock locked(lookup_lock_); 1394 base::AutoLock locked(lookup_lock_);
1309 csd_whitelist_all_urls_ = true; 1395 whitelist->second = true;
1310 csd_whitelist_.clear(); 1396 whitelist->first.clear();
1311 } 1397 }
1312 1398
1313 void SafeBrowsingDatabaseNew::LoadCsdWhitelist( 1399 void SafeBrowsingDatabaseNew::LoadWhitelist(
1314 const std::vector<SBAddFullHash>& full_hashes) { 1400 const std::vector<SBAddFullHash>& full_hashes,
1401 SBWhitelist* whitelist) {
1315 DCHECK_EQ(creation_loop_, MessageLoop::current()); 1402 DCHECK_EQ(creation_loop_, MessageLoop::current());
1316 if (full_hashes.size() > kMaxCsdWhitelistSize) { 1403 if (full_hashes.size() > kMaxWhitelistSize) {
1317 CsdWhitelistAllUrls(); 1404 WhitelistEverything(whitelist);
1318 return; 1405 return;
1319 } 1406 }
1320 1407
1321 std::vector<SBFullHash> new_csd_whitelist; 1408 std::vector<SBFullHash> new_whitelist;
1322 for (std::vector<SBAddFullHash>::const_iterator it = full_hashes.begin(); 1409 for (std::vector<SBAddFullHash>::const_iterator it = full_hashes.begin();
1323 it != full_hashes.end(); ++it) { 1410 it != full_hashes.end(); ++it) {
1324 new_csd_whitelist.push_back(it->full_hash); 1411 new_whitelist.push_back(it->full_hash);
1325 } 1412 }
1326 std::sort(new_csd_whitelist.begin(), new_csd_whitelist.end()); 1413 std::sort(new_whitelist.begin(), new_whitelist.end());
1327 1414
1328 SBFullHash kill_switch; 1415 SBFullHash kill_switch;
1329 crypto::SHA256HashString(kCsdKillSwitchUrl, &kill_switch, 1416 crypto::SHA256HashString(kWhitelistKillSwitchUrl, &kill_switch,
1330 sizeof(kill_switch)); 1417 sizeof(kill_switch));
1331 if (std::binary_search(new_csd_whitelist.begin(), new_csd_whitelist.end(), 1418 if (std::binary_search(new_whitelist.begin(), new_whitelist.end(),
1332 kill_switch)) { 1419 kill_switch)) {
1333 // The kill switch is whitelisted hence we whitelist all URLs. 1420 // The kill switch is whitelisted hence we whitelist all URLs.
1334 CsdWhitelistAllUrls(); 1421 WhitelistEverything(whitelist);
1335 } else { 1422 } else {
1336 base::AutoLock locked(lookup_lock_); 1423 base::AutoLock locked(lookup_lock_);
1337 csd_whitelist_all_urls_ = false; 1424 whitelist->second = false;
1338 csd_whitelist_.swap(new_csd_whitelist); 1425 whitelist->first.swap(new_whitelist);
1339 } 1426 }
1340 } 1427 }
OLDNEW
« no previous file with comments | « chrome/browser/safe_browsing/safe_browsing_database.h ('k') | chrome/browser/safe_browsing/safe_browsing_database_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698