| OLD | NEW |
| 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> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/bind_helpers.h" | 10 #include "base/bind_helpers.h" |
| (...skipping 548 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 559 return; | 559 return; |
| 560 | 560 |
| 561 closing_database_ = true; | 561 closing_database_ = true; |
| 562 if (safe_browsing_thread_.get()) { | 562 if (safe_browsing_thread_.get()) { |
| 563 safe_browsing_thread_->message_loop()->PostTask(FROM_HERE, | 563 safe_browsing_thread_->message_loop()->PostTask(FROM_HERE, |
| 564 base::Bind(&SafeBrowsingDatabaseManager::OnCloseDatabase, this)); | 564 base::Bind(&SafeBrowsingDatabaseManager::OnCloseDatabase, this)); |
| 565 } | 565 } |
| 566 } | 566 } |
| 567 | 567 |
| 568 SafeBrowsingDatabase* SafeBrowsingDatabaseManager::GetDatabase() { | 568 SafeBrowsingDatabase* SafeBrowsingDatabaseManager::GetDatabase() { |
| 569 DCHECK_EQ(MessageLoop::current(), safe_browsing_thread_->message_loop()); | 569 DCHECK_EQ(base::MessageLoop::current(), |
| 570 safe_browsing_thread_->message_loop()); |
| 570 if (database_) | 571 if (database_) |
| 571 return database_; | 572 return database_; |
| 572 startup_metric_utils::ScopedSlowStartupUMA | 573 startup_metric_utils::ScopedSlowStartupUMA |
| 573 scoped_timer("Startup.SlowStartupSafeBrowsingGetDatabase"); | 574 scoped_timer("Startup.SlowStartupSafeBrowsingGetDatabase"); |
| 574 const base::TimeTicks before = base::TimeTicks::Now(); | 575 const base::TimeTicks before = base::TimeTicks::Now(); |
| 575 | 576 |
| 576 SafeBrowsingDatabase* database = | 577 SafeBrowsingDatabase* database = |
| 577 SafeBrowsingDatabase::Create(enable_download_protection_, | 578 SafeBrowsingDatabase::Create(enable_download_protection_, |
| 578 enable_csd_whitelist_, | 579 enable_csd_whitelist_, |
| 579 enable_download_whitelist_, | 580 enable_download_whitelist_, |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 643 is_download); | 644 is_download); |
| 644 } else { | 645 } else { |
| 645 // We may have cached results for previous GetHash queries. Since | 646 // We may have cached results for previous GetHash queries. Since |
| 646 // this data comes from cache, don't histogram hits. | 647 // this data comes from cache, don't histogram hits. |
| 647 HandleOneCheck(check, check->full_hits); | 648 HandleOneCheck(check, check->full_hits); |
| 648 } | 649 } |
| 649 } | 650 } |
| 650 | 651 |
| 651 void SafeBrowsingDatabaseManager::GetAllChunksFromDatabase( | 652 void SafeBrowsingDatabaseManager::GetAllChunksFromDatabase( |
| 652 GetChunksCallback callback) { | 653 GetChunksCallback callback) { |
| 653 DCHECK_EQ(MessageLoop::current(), safe_browsing_thread_->message_loop()); | 654 DCHECK_EQ(base::MessageLoop::current(), |
| 655 safe_browsing_thread_->message_loop()); |
| 654 | 656 |
| 655 bool database_error = true; | 657 bool database_error = true; |
| 656 std::vector<SBListChunkRanges> lists; | 658 std::vector<SBListChunkRanges> lists; |
| 657 DCHECK(!database_update_in_progress_); | 659 DCHECK(!database_update_in_progress_); |
| 658 database_update_in_progress_ = true; | 660 database_update_in_progress_ = true; |
| 659 GetDatabase(); // This guarantees that |database_| is non-NULL. | 661 GetDatabase(); // This guarantees that |database_| is non-NULL. |
| 660 if (database_->UpdateStarted(&lists)) { | 662 if (database_->UpdateStarted(&lists)) { |
| 661 database_error = false; | 663 database_error = false; |
| 662 } else { | 664 } else { |
| 663 database_->UpdateFinished(false); | 665 database_->UpdateFinished(false); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 710 check.check_type); | 712 check.check_type); |
| 711 check.client->OnSafeBrowsingResult(sb_check); | 713 check.client->OnSafeBrowsingResult(sb_check); |
| 712 } | 714 } |
| 713 queued_checks_.pop_front(); | 715 queued_checks_.pop_front(); |
| 714 } | 716 } |
| 715 } | 717 } |
| 716 | 718 |
| 717 void SafeBrowsingDatabaseManager::AddDatabaseChunks( | 719 void SafeBrowsingDatabaseManager::AddDatabaseChunks( |
| 718 const std::string& list_name, SBChunkList* chunks, | 720 const std::string& list_name, SBChunkList* chunks, |
| 719 AddChunksCallback callback) { | 721 AddChunksCallback callback) { |
| 720 DCHECK_EQ(MessageLoop::current(), safe_browsing_thread_->message_loop()); | 722 DCHECK_EQ(base::MessageLoop::current(), |
| 723 safe_browsing_thread_->message_loop()); |
| 721 if (chunks) { | 724 if (chunks) { |
| 722 GetDatabase()->InsertChunks(list_name, *chunks); | 725 GetDatabase()->InsertChunks(list_name, *chunks); |
| 723 delete chunks; | 726 delete chunks; |
| 724 } | 727 } |
| 725 BrowserThread::PostTask( | 728 BrowserThread::PostTask( |
| 726 BrowserThread::IO, FROM_HERE, | 729 BrowserThread::IO, FROM_HERE, |
| 727 base::Bind(&SafeBrowsingDatabaseManager::OnAddChunksComplete, this, | 730 base::Bind(&SafeBrowsingDatabaseManager::OnAddChunksComplete, this, |
| 728 callback)); | 731 callback)); |
| 729 } | 732 } |
| 730 | 733 |
| 731 void SafeBrowsingDatabaseManager::DeleteDatabaseChunks( | 734 void SafeBrowsingDatabaseManager::DeleteDatabaseChunks( |
| 732 std::vector<SBChunkDelete>* chunk_deletes) { | 735 std::vector<SBChunkDelete>* chunk_deletes) { |
| 733 DCHECK_EQ(MessageLoop::current(), safe_browsing_thread_->message_loop()); | 736 DCHECK_EQ(base::MessageLoop::current(), |
| 737 safe_browsing_thread_->message_loop()); |
| 734 if (chunk_deletes) { | 738 if (chunk_deletes) { |
| 735 GetDatabase()->DeleteChunks(*chunk_deletes); | 739 GetDatabase()->DeleteChunks(*chunk_deletes); |
| 736 delete chunk_deletes; | 740 delete chunk_deletes; |
| 737 } | 741 } |
| 738 } | 742 } |
| 739 | 743 |
| 740 SBThreatType SafeBrowsingDatabaseManager::GetThreatTypeFromListname( | 744 SBThreatType SafeBrowsingDatabaseManager::GetThreatTypeFromListname( |
| 741 const std::string& list_name) { | 745 const std::string& list_name) { |
| 742 if (safe_browsing_util::IsPhishingList(list_name)) { | 746 if (safe_browsing_util::IsPhishingList(list_name)) { |
| 743 return SB_THREAT_TYPE_URL_PHISHING; | 747 return SB_THREAT_TYPE_URL_PHISHING; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 758 if (safe_browsing_util::IsExtensionList(list_name)) { | 762 if (safe_browsing_util::IsExtensionList(list_name)) { |
| 759 return SB_THREAT_TYPE_EXTENSION; | 763 return SB_THREAT_TYPE_EXTENSION; |
| 760 } | 764 } |
| 761 | 765 |
| 762 DVLOG(1) << "Unknown safe browsing list " << list_name; | 766 DVLOG(1) << "Unknown safe browsing list " << list_name; |
| 763 return SB_THREAT_TYPE_SAFE; | 767 return SB_THREAT_TYPE_SAFE; |
| 764 } | 768 } |
| 765 | 769 |
| 766 void SafeBrowsingDatabaseManager::DatabaseUpdateFinished( | 770 void SafeBrowsingDatabaseManager::DatabaseUpdateFinished( |
| 767 bool update_succeeded) { | 771 bool update_succeeded) { |
| 768 DCHECK_EQ(MessageLoop::current(), safe_browsing_thread_->message_loop()); | 772 DCHECK_EQ(base::MessageLoop::current(), |
| 773 safe_browsing_thread_->message_loop()); |
| 769 GetDatabase()->UpdateFinished(update_succeeded); | 774 GetDatabase()->UpdateFinished(update_succeeded); |
| 770 DCHECK(database_update_in_progress_); | 775 DCHECK(database_update_in_progress_); |
| 771 database_update_in_progress_ = false; | 776 database_update_in_progress_ = false; |
| 772 BrowserThread::PostTask( | 777 BrowserThread::PostTask( |
| 773 BrowserThread::UI, FROM_HERE, | 778 BrowserThread::UI, FROM_HERE, |
| 774 base::Bind(&SafeBrowsingDatabaseManager::NotifyDatabaseUpdateFinished, | 779 base::Bind(&SafeBrowsingDatabaseManager::NotifyDatabaseUpdateFinished, |
| 775 this, update_succeeded)); | 780 this, update_succeeded)); |
| 776 } | 781 } |
| 777 | 782 |
| 778 void SafeBrowsingDatabaseManager::NotifyDatabaseUpdateFinished( | 783 void SafeBrowsingDatabaseManager::NotifyDatabaseUpdateFinished( |
| 779 bool update_succeeded) { | 784 bool update_succeeded) { |
| 780 content::NotificationService::current()->Notify( | 785 content::NotificationService::current()->Notify( |
| 781 chrome::NOTIFICATION_SAFE_BROWSING_UPDATE_COMPLETE, | 786 chrome::NOTIFICATION_SAFE_BROWSING_UPDATE_COMPLETE, |
| 782 content::Source<SafeBrowsingDatabaseManager>(this), | 787 content::Source<SafeBrowsingDatabaseManager>(this), |
| 783 content::Details<bool>(&update_succeeded)); | 788 content::Details<bool>(&update_succeeded)); |
| 784 } | 789 } |
| 785 | 790 |
| 786 void SafeBrowsingDatabaseManager::OnCloseDatabase() { | 791 void SafeBrowsingDatabaseManager::OnCloseDatabase() { |
| 787 DCHECK_EQ(MessageLoop::current(), safe_browsing_thread_->message_loop()); | 792 DCHECK_EQ(base::MessageLoop::current(), |
| 793 safe_browsing_thread_->message_loop()); |
| 788 DCHECK(closing_database_); | 794 DCHECK(closing_database_); |
| 789 | 795 |
| 790 // Because |closing_database_| is true, nothing on the IO thread will be | 796 // Because |closing_database_| is true, nothing on the IO thread will be |
| 791 // accessing the database, so it's safe to delete and then NULL the pointer. | 797 // accessing the database, so it's safe to delete and then NULL the pointer. |
| 792 delete database_; | 798 delete database_; |
| 793 database_ = NULL; | 799 database_ = NULL; |
| 794 | 800 |
| 795 // Acquiring the lock here guarantees correct ordering between the resetting | 801 // Acquiring the lock here guarantees correct ordering between the resetting |
| 796 // of |database_| above and of |closing_database_| below, which ensures there | 802 // of |database_| above and of |closing_database_| below, which ensures there |
| 797 // won't be a window during which the IO thread falsely believes the database | 803 // won't be a window during which the IO thread falsely believes the database |
| 798 // is available. | 804 // is available. |
| 799 base::AutoLock lock(database_lock_); | 805 base::AutoLock lock(database_lock_); |
| 800 closing_database_ = false; | 806 closing_database_ = false; |
| 801 } | 807 } |
| 802 | 808 |
| 803 void SafeBrowsingDatabaseManager::OnResetDatabase() { | 809 void SafeBrowsingDatabaseManager::OnResetDatabase() { |
| 804 DCHECK_EQ(MessageLoop::current(), safe_browsing_thread_->message_loop()); | 810 DCHECK_EQ(base::MessageLoop::current(), |
| 811 safe_browsing_thread_->message_loop()); |
| 805 GetDatabase()->ResetDatabase(); | 812 GetDatabase()->ResetDatabase(); |
| 806 } | 813 } |
| 807 | 814 |
| 808 void SafeBrowsingDatabaseManager::CacheHashResults( | 815 void SafeBrowsingDatabaseManager::CacheHashResults( |
| 809 const std::vector<SBPrefix>& prefixes, | 816 const std::vector<SBPrefix>& prefixes, |
| 810 const std::vector<SBFullHashResult>& full_hashes) { | 817 const std::vector<SBFullHashResult>& full_hashes) { |
| 811 DCHECK_EQ(MessageLoop::current(), safe_browsing_thread_->message_loop()); | 818 DCHECK_EQ(base::MessageLoop::current(), |
| 819 safe_browsing_thread_->message_loop()); |
| 812 GetDatabase()->CacheHashResults(prefixes, full_hashes); | 820 GetDatabase()->CacheHashResults(prefixes, full_hashes); |
| 813 } | 821 } |
| 814 | 822 |
| 815 void SafeBrowsingDatabaseManager::OnHandleGetHashResults( | 823 void SafeBrowsingDatabaseManager::OnHandleGetHashResults( |
| 816 SafeBrowsingCheck* check, | 824 SafeBrowsingCheck* check, |
| 817 const std::vector<SBFullHashResult>& full_hashes) { | 825 const std::vector<SBFullHashResult>& full_hashes) { |
| 818 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 826 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 819 safe_browsing_util::ListType check_type = check->check_type; | 827 safe_browsing_util::ListType check_type = check->check_type; |
| 820 SBPrefix prefix = check->prefix_hits[0]; | 828 SBPrefix prefix = check->prefix_hits[0]; |
| 821 GetHashRequests::iterator it = gethash_requests_.find(prefix); | 829 GetHashRequests::iterator it = gethash_requests_.find(prefix); |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 875 NOTREACHED(); | 883 NOTREACHED(); |
| 876 } | 884 } |
| 877 } | 885 } |
| 878 | 886 |
| 879 SafeBrowsingCheckDone(check); | 887 SafeBrowsingCheckDone(check); |
| 880 return is_threat; | 888 return is_threat; |
| 881 } | 889 } |
| 882 | 890 |
| 883 void SafeBrowsingDatabaseManager::CheckDownloadHashOnSBThread( | 891 void SafeBrowsingDatabaseManager::CheckDownloadHashOnSBThread( |
| 884 SafeBrowsingCheck* check) { | 892 SafeBrowsingCheck* check) { |
| 885 DCHECK_EQ(MessageLoop::current(), safe_browsing_thread_->message_loop()); | 893 DCHECK_EQ(base::MessageLoop::current(), |
| 894 safe_browsing_thread_->message_loop()); |
| 886 DCHECK(enable_download_protection_); | 895 DCHECK(enable_download_protection_); |
| 887 | 896 |
| 888 DCHECK_EQ(1u, check->full_hashes.size()); | 897 DCHECK_EQ(1u, check->full_hashes.size()); |
| 889 SBFullHash full_hash = check->full_hashes[0]; | 898 SBFullHash full_hash = check->full_hashes[0]; |
| 890 | 899 |
| 891 if (!database_->ContainsDownloadHashPrefix(full_hash.prefix)) { | 900 if (!database_->ContainsDownloadHashPrefix(full_hash.prefix)) { |
| 892 // Good, we don't have hash for this url prefix. | 901 // Good, we don't have hash for this url prefix. |
| 893 BrowserThread::PostTask( | 902 BrowserThread::PostTask( |
| 894 BrowserThread::IO, FROM_HERE, | 903 BrowserThread::IO, FROM_HERE, |
| 895 base::Bind(&SafeBrowsingDatabaseManager::CheckDownloadHashDone, this, | 904 base::Bind(&SafeBrowsingDatabaseManager::CheckDownloadHashDone, this, |
| 896 check)); | 905 check)); |
| 897 return; | 906 return; |
| 898 } | 907 } |
| 899 | 908 |
| 900 check->need_get_hash = true; | 909 check->need_get_hash = true; |
| 901 check->prefix_hits.push_back(full_hash.prefix); | 910 check->prefix_hits.push_back(full_hash.prefix); |
| 902 BrowserThread::PostTask( | 911 BrowserThread::PostTask( |
| 903 BrowserThread::IO, FROM_HERE, | 912 BrowserThread::IO, FROM_HERE, |
| 904 base::Bind(&SafeBrowsingDatabaseManager::OnCheckDone, this, check)); | 913 base::Bind(&SafeBrowsingDatabaseManager::OnCheckDone, this, check)); |
| 905 } | 914 } |
| 906 | 915 |
| 907 void SafeBrowsingDatabaseManager::CheckDownloadUrlOnSBThread( | 916 void SafeBrowsingDatabaseManager::CheckDownloadUrlOnSBThread( |
| 908 SafeBrowsingCheck* check) { | 917 SafeBrowsingCheck* check) { |
| 909 DCHECK_EQ(MessageLoop::current(), safe_browsing_thread_->message_loop()); | 918 DCHECK_EQ(base::MessageLoop::current(), |
| 919 safe_browsing_thread_->message_loop()); |
| 910 DCHECK(enable_download_protection_); | 920 DCHECK(enable_download_protection_); |
| 911 | 921 |
| 912 std::vector<SBPrefix> prefix_hits; | 922 std::vector<SBPrefix> prefix_hits; |
| 913 | 923 |
| 914 if (!database_->ContainsDownloadUrl(check->urls, &prefix_hits)) { | 924 if (!database_->ContainsDownloadUrl(check->urls, &prefix_hits)) { |
| 915 // Good, we don't have hash for this url prefix. | 925 // Good, we don't have hash for this url prefix. |
| 916 BrowserThread::PostTask( | 926 BrowserThread::PostTask( |
| 917 BrowserThread::IO, FROM_HERE, | 927 BrowserThread::IO, FROM_HERE, |
| 918 base::Bind(&SafeBrowsingDatabaseManager::CheckDownloadUrlDone, this, | 928 base::Bind(&SafeBrowsingDatabaseManager::CheckDownloadUrlDone, this, |
| 919 check)); | 929 check)); |
| 920 return; | 930 return; |
| 921 } | 931 } |
| 922 | 932 |
| 923 check->need_get_hash = true; | 933 check->need_get_hash = true; |
| 924 check->prefix_hits.clear(); | 934 check->prefix_hits.clear(); |
| 925 check->prefix_hits = prefix_hits; | 935 check->prefix_hits = prefix_hits; |
| 926 BrowserThread::PostTask( | 936 BrowserThread::PostTask( |
| 927 BrowserThread::IO, FROM_HERE, | 937 BrowserThread::IO, FROM_HERE, |
| 928 base::Bind(&SafeBrowsingDatabaseManager::OnCheckDone, this, check)); | 938 base::Bind(&SafeBrowsingDatabaseManager::OnCheckDone, this, check)); |
| 929 } | 939 } |
| 930 | 940 |
| 931 void SafeBrowsingDatabaseManager::CheckExtensionIDsOnSBThread( | 941 void SafeBrowsingDatabaseManager::CheckExtensionIDsOnSBThread( |
| 932 SafeBrowsingCheck* check) { | 942 SafeBrowsingCheck* check) { |
| 933 DCHECK_EQ(MessageLoop::current(), safe_browsing_thread_->message_loop()); | 943 DCHECK_EQ(base::MessageLoop::current(), |
| 944 safe_browsing_thread_->message_loop()); |
| 934 | 945 |
| 935 std::vector<SBPrefix> prefixes; | 946 std::vector<SBPrefix> prefixes; |
| 936 for (std::vector<SBFullHash>::iterator it = check->full_hashes.begin(); | 947 for (std::vector<SBFullHash>::iterator it = check->full_hashes.begin(); |
| 937 it != check->full_hashes.end(); ++it) { | 948 it != check->full_hashes.end(); ++it) { |
| 938 prefixes.push_back((*it).prefix); | 949 prefixes.push_back((*it).prefix); |
| 939 } | 950 } |
| 940 database_->ContainsExtensionPrefixes(prefixes, &check->prefix_hits); | 951 database_->ContainsExtensionPrefixes(prefixes, &check->prefix_hits); |
| 941 | 952 |
| 942 if (check->prefix_hits.empty()) { | 953 if (check->prefix_hits.empty()) { |
| 943 // No matches for any extensions. | 954 // No matches for any extensions. |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1001 void SafeBrowsingDatabaseManager::StartSafeBrowsingCheck( | 1012 void SafeBrowsingDatabaseManager::StartSafeBrowsingCheck( |
| 1002 SafeBrowsingCheck* check, | 1013 SafeBrowsingCheck* check, |
| 1003 const base::Closure& task) { | 1014 const base::Closure& task) { |
| 1004 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 1015 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 1005 check->timeout_factory_.reset( | 1016 check->timeout_factory_.reset( |
| 1006 new base::WeakPtrFactory<SafeBrowsingDatabaseManager>(this)); | 1017 new base::WeakPtrFactory<SafeBrowsingDatabaseManager>(this)); |
| 1007 checks_.insert(check); | 1018 checks_.insert(check); |
| 1008 | 1019 |
| 1009 safe_browsing_thread_->message_loop()->PostTask(FROM_HERE, task); | 1020 safe_browsing_thread_->message_loop()->PostTask(FROM_HERE, task); |
| 1010 | 1021 |
| 1011 MessageLoop::current()->PostDelayedTask(FROM_HERE, | 1022 base::MessageLoop::current()->PostDelayedTask( |
| 1023 FROM_HERE, |
| 1012 base::Bind(&SafeBrowsingDatabaseManager::TimeoutCallback, | 1024 base::Bind(&SafeBrowsingDatabaseManager::TimeoutCallback, |
| 1013 check->timeout_factory_->GetWeakPtr(), check), | 1025 check->timeout_factory_->GetWeakPtr(), |
| 1026 check), |
| 1014 check_timeout_); | 1027 check_timeout_); |
| 1015 } | 1028 } |
| OLD | NEW |