| 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/download_protection_service.h" | 5 #include "chrome/browser/safe_browsing/download_protection_service.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include <map> | 10 #include <map> |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 67 using ::testing::Invoke; | 67 using ::testing::Invoke; |
| 68 using ::testing::Mock; | 68 using ::testing::Mock; |
| 69 using ::testing::NotNull; | 69 using ::testing::NotNull; |
| 70 using ::testing::Return; | 70 using ::testing::Return; |
| 71 using ::testing::ReturnRef; | 71 using ::testing::ReturnRef; |
| 72 using ::testing::SaveArg; | 72 using ::testing::SaveArg; |
| 73 using ::testing::StrictMock; | 73 using ::testing::StrictMock; |
| 74 using ::testing::_; | 74 using ::testing::_; |
| 75 using base::RunLoop; | 75 using base::RunLoop; |
| 76 using content::BrowserThread; | 76 using content::BrowserThread; |
| 77 |
| 77 namespace safe_browsing { | 78 namespace safe_browsing { |
| 79 |
| 78 namespace { | 80 namespace { |
| 81 |
| 79 // A SafeBrowsingDatabaseManager implementation that returns a fixed result for | 82 // A SafeBrowsingDatabaseManager implementation that returns a fixed result for |
| 80 // a given URL. | 83 // a given URL. |
| 81 class MockSafeBrowsingDatabaseManager : public TestSafeBrowsingDatabaseManager { | 84 class MockSafeBrowsingDatabaseManager : public TestSafeBrowsingDatabaseManager { |
| 82 public: | 85 public: |
| 83 MockSafeBrowsingDatabaseManager() {} | 86 MockSafeBrowsingDatabaseManager() {} |
| 84 | 87 |
| 85 MOCK_METHOD1(MatchDownloadWhitelistUrl, bool(const GURL&)); | 88 MOCK_METHOD1(MatchDownloadWhitelistUrl, bool(const GURL&)); |
| 86 MOCK_METHOD1(MatchDownloadWhitelistString, bool(const std::string&)); | 89 MOCK_METHOD1(MatchDownloadWhitelistString, bool(const std::string&)); |
| 87 MOCK_METHOD2(CheckDownloadUrl, bool( | 90 MOCK_METHOD2(CheckDownloadUrl, bool( |
| 88 const std::vector<GURL>& url_chain, | 91 const std::vector<GURL>& url_chain, |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 182 int WaitForRequest() { | 185 int WaitForRequest() { |
| 183 run_loop_.Run(); | 186 run_loop_.Run(); |
| 184 return fetcher_id_; | 187 return fetcher_id_; |
| 185 } | 188 } |
| 186 | 189 |
| 187 private: | 190 private: |
| 188 net::TestURLFetcherFactory* factory_; | 191 net::TestURLFetcherFactory* factory_; |
| 189 int fetcher_id_; | 192 int fetcher_id_; |
| 190 RunLoop run_loop_; | 193 RunLoop run_loop_; |
| 191 }; | 194 }; |
| 195 |
| 192 } // namespace | 196 } // namespace |
| 193 | 197 |
| 194 ACTION_P(SetCertificateContents, contents) { | 198 ACTION_P(SetCertificateContents, contents) { |
| 195 arg1->add_certificate_chain()->add_element()->set_certificate(contents); | 199 arg1->add_certificate_chain()->add_element()->set_certificate(contents); |
| 196 } | 200 } |
| 197 | 201 |
| 198 ACTION_P(SetDosHeaderContents, contents) { | 202 ACTION_P(SetDosHeaderContents, contents) { |
| 199 arg2->mutable_pe_headers()->set_dos_header(contents); | 203 arg2->mutable_pe_headers()->set_dos_header(contents); |
| 200 return true; | 204 return true; |
| 201 } | 205 } |
| 202 | 206 |
| 203 ACTION_P(TrustSignature, certificate_file) { | 207 ACTION_P(TrustSignature, contents) { |
| 204 arg1->set_trusted(true); | 208 arg1->set_trusted(true); |
| 205 // Add a certificate chain. Note that we add the certificate twice so that | 209 // Add a certificate chain. Note that we add the certificate twice so that |
| 206 // it appears as its own issuer. | 210 // it appears as its own issuer. |
| 207 std::string cert_data; | 211 |
| 208 ASSERT_TRUE(base::ReadFileToString(certificate_file, &cert_data)); | |
| 209 ClientDownloadRequest_CertificateChain* chain = | 212 ClientDownloadRequest_CertificateChain* chain = |
| 210 arg1->add_certificate_chain(); | 213 arg1->add_certificate_chain(); |
| 211 chain->add_element()->set_certificate(cert_data); | 214 chain->add_element()->set_certificate(contents.data(), contents.size()); |
| 212 chain->add_element()->set_certificate(cert_data); | 215 chain->add_element()->set_certificate(contents.data(), contents.size()); |
| 213 } | 216 } |
| 214 | 217 |
| 215 // We can't call OnSafeBrowsingResult directly because SafeBrowsingCheck does | 218 // We can't call OnSafeBrowsingResult directly because SafeBrowsingCheck does |
| 216 // not have any copy constructor which means it can't be stored in a callback | 219 // not have any copy constructor which means it can't be stored in a callback |
| 217 // easily. Note: check will be deleted automatically when the callback is | 220 // easily. Note: check will be deleted automatically when the callback is |
| 218 // deleted. | 221 // deleted. |
| 219 void OnSafeBrowsingResult( | 222 void OnSafeBrowsingResult( |
| 220 LocalSafeBrowsingDatabaseManager::SafeBrowsingCheck* check) { | 223 LocalSafeBrowsingDatabaseManager::SafeBrowsingCheck* check) { |
| 221 check->OnSafeBrowsingResult(); | 224 check->OnSafeBrowsingResult(); |
| 222 } | 225 } |
| (...skipping 554 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 777 &item, | 780 &item, |
| 778 std::vector<std::string>(), // empty url_chain | 781 std::vector<std::string>(), // empty url_chain |
| 779 "http://www.google.com/", // referrer | 782 "http://www.google.com/", // referrer |
| 780 FILE_PATH_LITERAL("a.tmp"), // tmp_path | 783 FILE_PATH_LITERAL("a.tmp"), // tmp_path |
| 781 FILE_PATH_LITERAL("a.exe")); // final_path | 784 FILE_PATH_LITERAL("a.exe")); // final_path |
| 782 EXPECT_CALL(*binary_feature_extractor_.get(), CheckSignature(tmp_path_, _)) | 785 EXPECT_CALL(*binary_feature_extractor_.get(), CheckSignature(tmp_path_, _)) |
| 783 .Times(4); | 786 .Times(4); |
| 784 EXPECT_CALL(*binary_feature_extractor_.get(), | 787 EXPECT_CALL(*binary_feature_extractor_.get(), |
| 785 ExtractImageFeatures( | 788 ExtractImageFeatures( |
| 786 tmp_path_, BinaryFeatureExtractor::kDefaultOptions, _, _)) | 789 tmp_path_, BinaryFeatureExtractor::kDefaultOptions, _, _)) |
| 787 .Times(4); | 790 .Times(6); |
| 788 // Assume http://www.whitelist.com/a.exe is on the whitelist. | 791 // Assume http://www.whitelist.com/a.exe is on the whitelist. |
| 789 EXPECT_CALL(*sb_service_->mock_database_manager(), | 792 EXPECT_CALL(*sb_service_->mock_database_manager(), |
| 790 MatchDownloadWhitelistUrl(_)).Times(0); | 793 MatchDownloadWhitelistUrl(_)).Times(0); |
| 791 EXPECT_CALL(*sb_service_->mock_database_manager(), | 794 EXPECT_CALL(*sb_service_->mock_database_manager(), |
| 792 MatchDownloadWhitelistUrl(GURL("http://www.whitelist.com/a.exe"))) | 795 MatchDownloadWhitelistUrl(GURL("http://www.whitelist.com/a.exe"))) |
| 793 .WillRepeatedly(Return(true)); | 796 .WillRepeatedly(Return(true)); |
| 794 url_chain_.push_back(GURL("http://www.whitelist.com/a.exe")); | 797 url_chain_.push_back(GURL("http://www.whitelist.com/a.exe")); |
| 795 // Set sample rate to 1.00, so download_service_ will always send download | 798 // Set sample rate to 1.00, so download_service_ will always send download |
| 796 // pings for whitelisted downloads. | 799 // pings for whitelisted downloads. |
| 797 SetWhitelistedDownloadSampleRate(1.00); | 800 SetWhitelistedDownloadSampleRate(1.00); |
| 798 | 801 |
| 799 { | 802 { |
| 800 // Case (1): is_extended_reporting && is_incognito. | 803 // Case (1): is_extended_reporting && is_incognito. |
| 801 // ClientDownloadRequest should NOT be sent. | 804 // ClientDownloadRequest should NOT be sent. |
| 802 SetExtendedReportingPreference(true); | 805 SetExtendedReportingPreference(true); |
| 803 EXPECT_CALL(item, GetBrowserContext()) | 806 EXPECT_CALL(item, GetBrowserContext()) |
| 804 .WillRepeatedly(Return(profile_->GetOffTheRecordProfile())); | 807 .WillRepeatedly(Return(profile_->GetOffTheRecordProfile())); |
| 805 RunLoop run_loop; | 808 RunLoop run_loop; |
| 806 download_service_->CheckClientDownload( | 809 download_service_->CheckClientDownload( |
| 807 &item, base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback, | 810 &item, base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback, |
| 808 base::Unretained(this), run_loop.QuitClosure())); | 811 base::Unretained(this), run_loop.QuitClosure())); |
| 809 run_loop.Run(); | 812 run_loop.Run(); |
| 810 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE)); | 813 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE)); |
| 811 EXPECT_FALSE(HasClientDownloadRequest()); | 814 EXPECT_FALSE(HasClientDownloadRequest()); |
| 812 } | 815 } |
| 813 { | 816 { |
| 814 // Case (2): is_extended_reporting && !is_incognito. | 817 // Case (2): !is_extended_reporting && is_incognito. |
| 815 // ClientDownloadRequest should be sent. | 818 // ClientDownloadRequest should NOT be sent. |
| 819 SetExtendedReportingPreference(false); |
| 820 EXPECT_CALL(item, GetBrowserContext()) |
| 821 .WillRepeatedly(Return(profile_->GetOffTheRecordProfile())); |
| 822 RunLoop run_loop; |
| 823 download_service_->CheckClientDownload( |
| 824 &item, base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback, |
| 825 base::Unretained(this), run_loop.QuitClosure())); |
| 826 run_loop.Run(); |
| 827 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE)); |
| 828 EXPECT_FALSE(HasClientDownloadRequest()); |
| 829 } |
| 830 { |
| 831 // Case (3): !is_extended_reporting && !is_incognito. |
| 832 // ClientDownloadRequest should NOT be sent. |
| 816 EXPECT_CALL(item, GetBrowserContext()) | 833 EXPECT_CALL(item, GetBrowserContext()) |
| 817 .WillRepeatedly(Return(profile_.get())); | 834 .WillRepeatedly(Return(profile_.get())); |
| 818 RunLoop run_loop; | 835 RunLoop run_loop; |
| 836 download_service_->CheckClientDownload( |
| 837 &item, base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback, |
| 838 base::Unretained(this), run_loop.QuitClosure())); |
| 839 run_loop.Run(); |
| 840 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE)); |
| 841 EXPECT_FALSE(HasClientDownloadRequest()); |
| 842 } |
| 843 { |
| 844 // Case (4): is_extended_reporting && !is_incognito && |
| 845 // Download matches URL whitelist. |
| 846 // ClientDownloadRequest should be sent. |
| 847 SetExtendedReportingPreference(true); |
| 848 EXPECT_CALL(item, GetBrowserContext()) |
| 849 .WillRepeatedly(Return(profile_.get())); |
| 850 RunLoop run_loop; |
| 819 download_service_->CheckClientDownload( | 851 download_service_->CheckClientDownload( |
| 820 &item, base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback, | 852 &item, base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback, |
| 821 base::Unretained(this), run_loop.QuitClosure())); | 853 base::Unretained(this), run_loop.QuitClosure())); |
| 822 run_loop.Run(); | 854 run_loop.Run(); |
| 823 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE)); | 855 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE)); |
| 824 ASSERT_TRUE(HasClientDownloadRequest()); | 856 ASSERT_TRUE(HasClientDownloadRequest()); |
| 825 EXPECT_TRUE(GetClientDownloadRequest()->skipped_url_whitelist()); | 857 EXPECT_TRUE(GetClientDownloadRequest()->skipped_url_whitelist()); |
| 858 EXPECT_FALSE(GetClientDownloadRequest()->skipped_certificate_whitelist()); |
| 826 ClearClientDownloadRequest(); | 859 ClearClientDownloadRequest(); |
| 827 } | 860 } |
| 861 |
| 862 // Setup trusted and whitelisted certificates for test cases (5) and (6). |
| 863 scoped_refptr<net::X509Certificate> test_cert( |
| 864 ReadTestCertificate("test_cn.pem")); |
| 865 ASSERT_TRUE(test_cert.get()); |
| 866 std::string test_cert_der; |
| 867 net::X509Certificate::GetDEREncoded(test_cert->os_cert_handle(), |
| 868 &test_cert_der); |
| 869 EXPECT_CALL(*binary_feature_extractor_.get(), CheckSignature(tmp_path_, _)) |
| 870 .WillRepeatedly(TrustSignature(test_cert_der)); |
| 871 EXPECT_CALL(*sb_service_->mock_database_manager(), |
| 872 MatchDownloadWhitelistString(_)) |
| 873 .WillRepeatedly(Return(true)); |
| 874 |
| 828 { | 875 { |
| 829 // Case (3): !is_extended_reporting && is_incognito. | 876 // Case (5): is_extended_reporting && !is_incognito && |
| 830 // ClientDownloadRequest should NOT be sent. | 877 // Download matches certificate whitelist. |
| 831 SetExtendedReportingPreference(false); | 878 // ClientDownloadRequest should be sent. |
| 832 EXPECT_CALL(item, GetBrowserContext()) | 879 EXPECT_CALL(item, GetBrowserContext()) |
| 833 .WillRepeatedly(Return(profile_->GetOffTheRecordProfile())); | 880 .WillRepeatedly(Return(profile_.get())); |
| 881 EXPECT_CALL( |
| 882 *sb_service_->mock_database_manager(), |
| 883 MatchDownloadWhitelistUrl(GURL("http://www.whitelist.com/a.exe"))) |
| 884 .WillRepeatedly(Return(false)); |
| 834 RunLoop run_loop; | 885 RunLoop run_loop; |
| 835 download_service_->CheckClientDownload( | 886 download_service_->CheckClientDownload( |
| 836 &item, base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback, | 887 &item, base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback, |
| 837 base::Unretained(this), run_loop.QuitClosure())); | 888 base::Unretained(this), run_loop.QuitClosure())); |
| 838 run_loop.Run(); | 889 run_loop.Run(); |
| 839 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE)); | 890 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE)); |
| 840 EXPECT_FALSE(HasClientDownloadRequest()); | 891 ASSERT_TRUE(HasClientDownloadRequest()); |
| 892 EXPECT_FALSE(GetClientDownloadRequest()->skipped_url_whitelist()); |
| 893 EXPECT_TRUE(GetClientDownloadRequest()->skipped_certificate_whitelist()); |
| 894 ClearClientDownloadRequest(); |
| 841 } | 895 } |
| 842 { | 896 { |
| 843 // Case (4): !is_extended_reporting && !is_incognito. | 897 // Case (6): is_extended_reporting && !is_incognito && |
| 844 // ClientDownloadRequest should NOT be sent. | 898 // Download matches both URL and certificate whitelists. |
| 899 // ClientDownloadRequest should be sent. |
| 845 EXPECT_CALL(item, GetBrowserContext()) | 900 EXPECT_CALL(item, GetBrowserContext()) |
| 846 .WillRepeatedly(Return(profile_.get())); | 901 .WillRepeatedly(Return(profile_.get())); |
| 902 EXPECT_CALL( |
| 903 *sb_service_->mock_database_manager(), |
| 904 MatchDownloadWhitelistUrl(GURL("http://www.whitelist.com/a.exe"))) |
| 905 .WillRepeatedly(Return(true)); |
| 847 RunLoop run_loop; | 906 RunLoop run_loop; |
| 848 download_service_->CheckClientDownload( | 907 download_service_->CheckClientDownload( |
| 849 &item, base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback, | 908 &item, base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback, |
| 850 base::Unretained(this), run_loop.QuitClosure())); | 909 base::Unretained(this), run_loop.QuitClosure())); |
| 851 run_loop.Run(); | 910 run_loop.Run(); |
| 852 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE)); | 911 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE)); |
| 853 EXPECT_FALSE(HasClientDownloadRequest()); | 912 ASSERT_TRUE(HasClientDownloadRequest()); |
| 913 EXPECT_TRUE(GetClientDownloadRequest()->skipped_url_whitelist()); |
| 914 // Since download matches URL whitelist and gets sampled, no need to |
| 915 // do certificate whitelist checking and sampling. |
| 916 EXPECT_FALSE(GetClientDownloadRequest()->skipped_certificate_whitelist()); |
| 917 ClearClientDownloadRequest(); |
| 854 } | 918 } |
| 855 } | 919 } |
| 856 | 920 |
| 857 TEST_F(DownloadProtectionServiceTest, CheckClientDownloadSampledFile) { | 921 TEST_F(DownloadProtectionServiceTest, CheckClientDownloadSampledFile) { |
| 858 // Server response will be discarded. | 922 // Server response will be discarded. |
| 859 net::FakeURLFetcherFactory factory(NULL); | 923 net::FakeURLFetcherFactory factory(NULL); |
| 860 PrepareResponse( | 924 PrepareResponse( |
| 861 &factory, ClientDownloadResponse::DANGEROUS, net::HTTP_OK, | 925 &factory, ClientDownloadResponse::DANGEROUS, net::HTTP_OK, |
| 862 net::URLRequestStatus::SUCCESS); | 926 net::URLRequestStatus::SUCCESS); |
| 863 | 927 |
| (...skipping 1436 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2300 &item, base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback, | 2364 &item, base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback, |
| 2301 base::Unretained(this), run_loop.QuitClosure())); | 2365 base::Unretained(this), run_loop.QuitClosure())); |
| 2302 run_loop.Run(); | 2366 run_loop.Run(); |
| 2303 | 2367 |
| 2304 EXPECT_FALSE(HasClientDownloadRequest()); | 2368 EXPECT_FALSE(HasClientDownloadRequest()); |
| 2305 // Overriden by flag: | 2369 // Overriden by flag: |
| 2306 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS)); | 2370 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS)); |
| 2307 } | 2371 } |
| 2308 | 2372 |
| 2309 } // namespace safe_browsing | 2373 } // namespace safe_browsing |
| OLD | NEW |