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
3 // found in the LICENSE file.
5 #include "chrome/browser/safe_browsing/download_protection_service.h"
10 #include "base/base_paths.h"
11 #include "base/bind.h"
12 #include "base/callback.h"
13 #include "base/files/file_path.h"
14 #include "base/files/file_util.h"
15 #include "base/files/scoped_temp_dir.h"
16 #include "base/memory/ref_counted.h"
17 #include "base/memory/scoped_ptr.h"
18 #include "base/message_loop/message_loop.h"
19 #include "base/path_service.h"
20 #include "base/run_loop.h"
21 #include "base/strings/string_number_conversions.h"
22 #include "base/threading/sequenced_worker_pool.h"
23 #include "chrome/browser/history/history_service.h"
24 #include "chrome/browser/history/history_service_factory.h"
25 #include "chrome/browser/safe_browsing/binary_feature_extractor.h"
26 #include "chrome/browser/safe_browsing/database_manager.h"
27 #include "chrome/browser/safe_browsing/download_feedback_service.h"
28 #include "chrome/browser/safe_browsing/safe_browsing_service.h"
29 #include "chrome/common/safe_browsing/csd.pb.h"
30 #include "chrome/test/base/testing_profile.h"
31 #include "content/public/test/mock_download_item.h"
32 #include "content/public/test/test_browser_thread_bundle.h"
33 #include "content/public/test/test_utils.h"
34 #include "net/cert/x509_certificate.h"
35 #include "net/http/http_status_code.h"
36 #include "net/url_request/test_url_fetcher_factory.h"
37 #include "net/url_request/url_fetcher_delegate.h"
38 #include "net/url_request/url_request_status.h"
39 #include "testing/gmock/include/gmock/gmock.h"
40 #include "testing/gtest/include/gtest/gtest.h"
41 #include "third_party/zlib/google/zip.h"
44 #if defined(OS_MACOSX)
45 #include "base/metrics/field_trial.h"
46 #include "components/variations/entropy_provider.h"
49 using ::testing::Assign;
50 using ::testing::ContainerEq;
51 using ::testing::DoAll;
52 using ::testing::ElementsAre;
53 using ::testing::Invoke;
54 using ::testing::Mock;
55 using ::testing::NotNull;
56 using ::testing::Return;
57 using ::testing::ReturnRef;
58 using ::testing::SaveArg;
59 using ::testing::StrictMock;
61 using base::MessageLoop;
62 using content::BrowserThread;
63 namespace safe_browsing {
65 // A SafeBrowsingDatabaseManager implementation that returns a fixed result for
67 class MockSafeBrowsingDatabaseManager : public SafeBrowsingDatabaseManager {
69 explicit MockSafeBrowsingDatabaseManager(SafeBrowsingService* service)
70 : SafeBrowsingDatabaseManager(service) { }
72 MOCK_METHOD1(MatchDownloadWhitelistUrl, bool(const GURL&));
73 MOCK_METHOD1(MatchDownloadWhitelistString, bool(const std::string&));
74 MOCK_METHOD2(CheckDownloadUrl, bool(
75 const std::vector<GURL>& url_chain,
76 SafeBrowsingDatabaseManager::Client* client));
79 virtual ~MockSafeBrowsingDatabaseManager() {}
80 DISALLOW_COPY_AND_ASSIGN(MockSafeBrowsingDatabaseManager);
83 class FakeSafeBrowsingService : public SafeBrowsingService {
85 FakeSafeBrowsingService() { }
87 // Returned pointer has the same lifespan as the database_manager_ refcounted
89 MockSafeBrowsingDatabaseManager* mock_database_manager() {
90 return mock_database_manager_;
94 ~FakeSafeBrowsingService() override {}
96 SafeBrowsingDatabaseManager* CreateDatabaseManager() override {
97 mock_database_manager_ = new MockSafeBrowsingDatabaseManager(this);
98 return mock_database_manager_;
101 void RegisterAllDelayedAnalysis() override {}
104 MockSafeBrowsingDatabaseManager* mock_database_manager_;
106 DISALLOW_COPY_AND_ASSIGN(FakeSafeBrowsingService);
109 class MockBinaryFeatureExtractor : public BinaryFeatureExtractor {
111 MockBinaryFeatureExtractor() {}
112 MOCK_METHOD2(CheckSignature, void(const base::FilePath&,
113 ClientDownloadRequest_SignatureInfo*));
114 MOCK_METHOD2(ExtractImageHeaders, void(const base::FilePath&,
115 ClientDownloadRequest_ImageHeaders*));
118 virtual ~MockBinaryFeatureExtractor() {}
121 DISALLOW_COPY_AND_ASSIGN(MockBinaryFeatureExtractor);
124 class TestURLFetcherWatcher : public net::TestURLFetcherDelegateForTests {
126 explicit TestURLFetcherWatcher(net::TestURLFetcherFactory* factory)
127 : factory_(factory), fetcher_id_(-1) {
128 factory_->SetDelegateForTests(this);
130 ~TestURLFetcherWatcher() {
131 factory_->SetDelegateForTests(NULL);
134 // TestURLFetcherDelegateForTests impl:
135 void OnRequestStart(int fetcher_id) override {
136 fetcher_id_ = fetcher_id;
139 void OnChunkUpload(int fetcher_id) override {}
140 void OnRequestEnd(int fetcher_id) override {}
142 int WaitForRequest() {
148 net::TestURLFetcherFactory* factory_;
150 base::RunLoop run_loop_;
154 ACTION_P(SetCertificateContents, contents) {
155 arg1->add_certificate_chain()->add_element()->set_certificate(contents);
158 ACTION_P(SetDosHeaderContents, contents) {
159 arg1->mutable_pe_headers()->set_dos_header(contents);
162 ACTION_P(TrustSignature, certificate_file) {
163 arg1->set_trusted(true);
164 // Add a certificate chain. Note that we add the certificate twice so that
165 // it appears as its own issuer.
166 std::string cert_data;
167 ASSERT_TRUE(base::ReadFileToString(certificate_file, &cert_data));
168 ClientDownloadRequest_CertificateChain* chain =
169 arg1->add_certificate_chain();
170 chain->add_element()->set_certificate(cert_data);
171 chain->add_element()->set_certificate(cert_data);
174 // We can't call OnSafeBrowsingResult directly because SafeBrowsingCheck does
175 // not have any copy constructor which means it can't be stored in a callback
176 // easily. Note: check will be deleted automatically when the callback is
178 void OnSafeBrowsingResult(
179 SafeBrowsingDatabaseManager::SafeBrowsingCheck* check) {
180 check->client->OnSafeBrowsingResult(*check);
183 ACTION_P(CheckDownloadUrlDone, threat_type) {
184 SafeBrowsingDatabaseManager::SafeBrowsingCheck* check =
185 new SafeBrowsingDatabaseManager::SafeBrowsingCheck(
187 std::vector<SBFullHash>(),
189 safe_browsing_util::BINURL,
190 std::vector<SBThreatType>(1, SB_THREAT_TYPE_BINARY_MALWARE_URL));
191 for (size_t i = 0; i < check->url_results.size(); ++i)
192 check->url_results[i] = threat_type;
193 BrowserThread::PostTask(BrowserThread::IO,
195 base::Bind(&OnSafeBrowsingResult,
196 base::Owned(check)));
199 class DownloadProtectionServiceTest : public testing::Test {
201 DownloadProtectionServiceTest()
202 : test_browser_thread_bundle_(
203 content::TestBrowserThreadBundle::IO_MAINLOOP) {
205 void SetUp() override {
206 #if defined(OS_MACOSX)
207 field_trial_list_.reset(new base::FieldTrialList(
208 new metrics::SHA1EntropyProvider("42")));
209 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
210 "SafeBrowsingOSXClientDownloadPings",
213 // Start real threads for the IO and File threads so that the DCHECKs
214 // to test that we're on the correct thread work.
215 sb_service_ = new StrictMock<FakeSafeBrowsingService>();
216 sb_service_->Initialize();
217 binary_feature_extractor_ = new StrictMock<MockBinaryFeatureExtractor>();
218 download_service_ = sb_service_->download_protection_service();
219 download_service_->binary_feature_extractor_ = binary_feature_extractor_;
220 download_service_->SetEnabled(true);
221 client_download_request_subscription_ =
222 download_service_->RegisterClientDownloadRequestCallback(
223 base::Bind(&DownloadProtectionServiceTest::OnClientDownloadRequest,
224 base::Unretained(this)));
225 base::RunLoop().RunUntilIdle();
228 base::FilePath source_path;
229 ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &source_path));
230 testdata_path_ = source_path
231 .AppendASCII("chrome")
234 .AppendASCII("safe_browsing")
235 .AppendASCII("download_protection");
238 void TearDown() override {
239 client_download_request_subscription_.reset();
240 sb_service_->ShutDown();
241 // Flush all of the thread message loops to ensure that there are no
242 // tasks currently running.
243 FlushThreadMessageLoops();
247 bool RequestContainsResource(const ClientDownloadRequest& request,
248 ClientDownloadRequest::ResourceType type,
249 const std::string& url,
250 const std::string& referrer) {
251 for (int i = 0; i < request.resources_size(); ++i) {
252 if (request.resources(i).url() == url &&
253 request.resources(i).type() == type &&
254 (referrer.empty() || request.resources(i).referrer() == referrer)) {
261 // At this point we only set the server IP for the download itself.
262 bool RequestContainsServerIp(const ClientDownloadRequest& request,
263 const std::string& remote_address) {
264 for (int i = 0; i < request.resources_size(); ++i) {
265 // We want the last DOWNLOAD_URL in the chain.
266 if (request.resources(i).type() == ClientDownloadRequest::DOWNLOAD_URL &&
267 (i + 1 == request.resources_size() ||
268 request.resources(i + 1).type() !=
269 ClientDownloadRequest::DOWNLOAD_URL)) {
270 return remote_address == request.resources(i).remote_ip();
276 // Flushes any pending tasks in the message loops of all threads.
277 void FlushThreadMessageLoops() {
278 BrowserThread::GetBlockingPool()->FlushForTesting();
279 FlushMessageLoop(BrowserThread::IO);
280 base::RunLoop().RunUntilIdle();
283 // Proxy for private method.
284 static void GetCertificateWhitelistStrings(
285 const net::X509Certificate& certificate,
286 const net::X509Certificate& issuer,
287 std::vector<std::string>* whitelist_strings) {
288 DownloadProtectionService::GetCertificateWhitelistStrings(
289 certificate, issuer, whitelist_strings);
292 // Reads a single PEM-encoded certificate from the testdata directory.
293 // Returns NULL on failure.
294 scoped_refptr<net::X509Certificate> ReadTestCertificate(
295 const std::string& filename) {
296 std::string cert_data;
297 if (!base::ReadFileToString(testdata_path_.AppendASCII(filename),
301 net::CertificateList certs =
302 net::X509Certificate::CreateCertificateListFromBytes(
305 net::X509Certificate::FORMAT_PEM_CERT_SEQUENCE);
306 return certs.empty() ? NULL : certs[0];
309 bool HasClientDownloadRequest() const {
310 return last_client_download_request_.get() != NULL;
313 void ClearClientDownloadRequest() { last_client_download_request_.reset(); }
316 // Helper functions for FlushThreadMessageLoops.
317 void RunAllPendingAndQuitUI() {
318 base::MessageLoop::current()->RunUntilIdle();
319 BrowserThread::PostTask(
322 base::Bind(&DownloadProtectionServiceTest::QuitMessageLoop,
323 base::Unretained(this)));
326 void QuitMessageLoop() {
327 base::MessageLoop::current()->Quit();
330 void PostRunMessageLoopTask(BrowserThread::ID thread) {
331 BrowserThread::PostTask(
334 base::Bind(&DownloadProtectionServiceTest::RunAllPendingAndQuitUI,
335 base::Unretained(this)));
338 void FlushMessageLoop(BrowserThread::ID thread) {
339 BrowserThread::PostTask(
342 base::Bind(&DownloadProtectionServiceTest::PostRunMessageLoopTask,
343 base::Unretained(this), thread));
344 MessageLoop::current()->Run();
347 void OnClientDownloadRequest(content::DownloadItem* download,
348 const ClientDownloadRequest* request) {
350 last_client_download_request_.reset(new ClientDownloadRequest(*request));
352 last_client_download_request_.reset();
356 void CheckDoneCallback(
357 DownloadProtectionService::DownloadCheckResult result) {
360 MessageLoop::current()->Quit();
363 void SyncCheckDoneCallback(
364 DownloadProtectionService::DownloadCheckResult result) {
369 void SendURLFetchComplete(net::TestURLFetcher* fetcher) {
370 fetcher->delegate()->OnURLFetchComplete(fetcher);
373 testing::AssertionResult IsResult(
374 DownloadProtectionService::DownloadCheckResult expected) {
376 return testing::AssertionFailure() << "No result";
378 return result_ == expected ?
379 testing::AssertionSuccess() :
380 testing::AssertionFailure() << "Expected " << expected <<
385 scoped_refptr<FakeSafeBrowsingService> sb_service_;
386 scoped_refptr<MockBinaryFeatureExtractor> binary_feature_extractor_;
387 DownloadProtectionService* download_service_;
388 DownloadProtectionService::DownloadCheckResult result_;
390 content::TestBrowserThreadBundle test_browser_thread_bundle_;
391 content::InProcessUtilityThreadHelper in_process_utility_thread_helper_;
392 base::FilePath testdata_path_;
393 #if defined(OS_MACOSX)
394 scoped_ptr<base::FieldTrialList> field_trial_list_;
396 DownloadProtectionService::ClientDownloadRequestSubscription
397 client_download_request_subscription_;
398 scoped_ptr<ClientDownloadRequest> last_client_download_request_;
401 TEST_F(DownloadProtectionServiceTest, CheckClientDownloadInvalidUrl) {
402 base::FilePath a_tmp(FILE_PATH_LITERAL("a.tmp"));
403 base::FilePath a_exe(FILE_PATH_LITERAL("a.exe"));
404 std::vector<GURL> url_chain;
405 GURL referrer("http://www.google.com/");
407 content::MockDownloadItem item;
408 EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp));
409 EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_exe));
410 EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
411 EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
412 EXPECT_CALL(item, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
413 EXPECT_CALL(item, GetTabReferrerUrl())
414 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
415 download_service_->CheckClientDownload(
417 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
418 base::Unretained(this)));
419 MessageLoop::current()->Run();
420 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN));
421 EXPECT_FALSE(HasClientDownloadRequest());
422 Mock::VerifyAndClearExpectations(&item);
424 url_chain.push_back(GURL("file://www.google.com/"));
425 EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp));
426 EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_exe));
427 EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
428 EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
429 EXPECT_CALL(item, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
430 EXPECT_CALL(item, GetTabReferrerUrl())
431 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
432 download_service_->CheckClientDownload(
434 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
435 base::Unretained(this)));
436 MessageLoop::current()->Run();
437 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN));
438 EXPECT_FALSE(HasClientDownloadRequest());
441 TEST_F(DownloadProtectionServiceTest, CheckClientDownloadNotABinary) {
442 base::FilePath a_tmp(FILE_PATH_LITERAL("a.tmp"));
443 base::FilePath a_txt(FILE_PATH_LITERAL("a.txt"));
444 std::vector<GURL> url_chain;
445 GURL referrer("http://www.google.com/");
447 content::MockDownloadItem item;
448 url_chain.push_back(GURL("http://www.example.com/foo"));
449 EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp));
450 EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_txt));
451 EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
452 EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
453 EXPECT_CALL(item, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
454 EXPECT_CALL(item, GetTabReferrerUrl())
455 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
456 download_service_->CheckClientDownload(
458 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
459 base::Unretained(this)));
460 MessageLoop::current()->Run();
461 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN));
462 EXPECT_FALSE(HasClientDownloadRequest());
465 TEST_F(DownloadProtectionServiceTest, CheckClientDownloadWhitelistedUrl) {
466 // Response to any requests will be DANGEROUS.
467 ClientDownloadResponse response;
468 response.set_verdict(ClientDownloadResponse::DANGEROUS);
469 net::FakeURLFetcherFactory factory(NULL);
470 factory.SetFakeResponse(
471 DownloadProtectionService::GetDownloadRequestUrl(),
472 response.SerializeAsString(),
473 net::HTTP_OK, net::URLRequestStatus::SUCCESS);
475 std::string hash = "hash";
476 base::FilePath a_tmp(FILE_PATH_LITERAL("a.tmp"));
477 base::FilePath a_exe(FILE_PATH_LITERAL("a.exe"));
478 std::vector<GURL> url_chain;
481 content::MockDownloadItem item;
482 EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp));
483 EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_exe));
484 EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
485 EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
486 EXPECT_CALL(item, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
487 EXPECT_CALL(item, GetTabReferrerUrl())
488 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
489 EXPECT_CALL(item, GetHash()).WillRepeatedly(ReturnRef(hash));
490 EXPECT_CALL(item, GetReceivedBytes()).WillRepeatedly(Return(100));
491 EXPECT_CALL(item, HasUserGesture()).WillRepeatedly(Return(true));
492 EXPECT_CALL(item, GetRemoteAddress()).WillRepeatedly(Return(""));
493 EXPECT_CALL(*binary_feature_extractor_.get(), CheckSignature(a_tmp, _))
495 EXPECT_CALL(*binary_feature_extractor_.get(), ExtractImageHeaders(a_tmp, _))
498 // We should not get whilelist checks for other URLs than specified below.
499 EXPECT_CALL(*sb_service_->mock_database_manager(),
500 MatchDownloadWhitelistUrl(_)).Times(0);
501 EXPECT_CALL(*sb_service_->mock_database_manager(),
502 MatchDownloadWhitelistUrl(GURL("http://www.evil.com/bla.exe")))
503 .WillRepeatedly(Return(false));
504 EXPECT_CALL(*sb_service_->mock_database_manager(),
505 MatchDownloadWhitelistUrl(GURL("http://www.google.com/a.exe")))
506 .WillRepeatedly(Return(true));
508 // With no referrer and just the bad url, should be marked DANGEROUS.
509 url_chain.push_back(GURL("http://www.evil.com/bla.exe"));
510 download_service_->CheckClientDownload(
512 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
513 base::Unretained(this)));
514 MessageLoop::current()->Run();
516 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS));
518 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN));
521 #if defined(OS_WIN) || defined(OS_MACOSX)
522 // OSX sends pings for evaluation purposes.
523 EXPECT_TRUE(HasClientDownloadRequest());
524 ClearClientDownloadRequest();
526 EXPECT_FALSE(HasClientDownloadRequest());
529 // Check that the referrer is not matched against the whitelist.
530 referrer = GURL("http://www.google.com/");
531 download_service_->CheckClientDownload(
533 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
534 base::Unretained(this)));
535 MessageLoop::current()->Run();
537 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS));
539 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN));
542 #if defined(OS_WIN) || defined(OS_MACOSX)
543 // OSX sends pings for evaluation purposes.
544 EXPECT_TRUE(HasClientDownloadRequest());
545 ClearClientDownloadRequest();
547 EXPECT_FALSE(HasClientDownloadRequest());
550 // Redirect from a site shouldn't be checked either.
551 url_chain.insert(url_chain.begin(), GURL("http://www.google.com/redirect"));
552 download_service_->CheckClientDownload(
554 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
555 base::Unretained(this)));
556 MessageLoop::current()->Run();
558 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS));
560 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN));
563 #if defined(OS_WIN) || defined(OS_MACOSX)
564 // OSX sends pings for evaluation purposes.
565 EXPECT_TRUE(HasClientDownloadRequest());
566 ClearClientDownloadRequest();
568 EXPECT_FALSE(HasClientDownloadRequest());
571 // Only if the final url is whitelisted should it be SAFE.
572 url_chain.push_back(GURL("http://www.google.com/a.exe"));
573 download_service_->CheckClientDownload(
575 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
576 base::Unretained(this)));
577 MessageLoop::current()->Run();
578 #if defined(OS_MACOSX)
579 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN));
581 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
583 // TODO(grt): Make the service produce the request even when the URL is
585 EXPECT_FALSE(HasClientDownloadRequest());
588 TEST_F(DownloadProtectionServiceTest, CheckClientDownloadFetchFailed) {
589 net::FakeURLFetcherFactory factory(NULL);
590 // HTTP request will fail.
591 factory.SetFakeResponse(
592 DownloadProtectionService::GetDownloadRequestUrl(), std::string(),
593 net::HTTP_INTERNAL_SERVER_ERROR, net::URLRequestStatus::FAILED);
595 base::FilePath a_tmp(FILE_PATH_LITERAL("a.tmp"));
596 base::FilePath a_exe(FILE_PATH_LITERAL("a.exe"));
597 std::vector<GURL> url_chain;
598 url_chain.push_back(GURL("http://www.evil.com/a.exe"));
599 GURL referrer("http://www.google.com/");
600 std::string hash = "hash";
602 content::MockDownloadItem item;
603 EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp));
604 EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_exe));
605 EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
606 EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
607 EXPECT_CALL(item, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
608 EXPECT_CALL(item, GetTabReferrerUrl())
609 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
610 EXPECT_CALL(item, GetHash()).WillRepeatedly(ReturnRef(hash));
611 EXPECT_CALL(item, GetReceivedBytes()).WillRepeatedly(Return(100));
612 EXPECT_CALL(item, HasUserGesture()).WillRepeatedly(Return(true));
613 EXPECT_CALL(item, GetRemoteAddress()).WillRepeatedly(Return(""));
615 EXPECT_CALL(*sb_service_->mock_database_manager(),
616 MatchDownloadWhitelistUrl(_))
617 .WillRepeatedly(Return(false));
618 EXPECT_CALL(*binary_feature_extractor_.get(), CheckSignature(a_tmp, _));
619 EXPECT_CALL(*binary_feature_extractor_.get(), ExtractImageHeaders(a_tmp, _));
621 download_service_->CheckClientDownload(
623 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
624 base::Unretained(this)));
625 MessageLoop::current()->Run();
626 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN));
629 TEST_F(DownloadProtectionServiceTest, CheckClientDownloadSuccess) {
630 ClientDownloadResponse response;
631 response.set_verdict(ClientDownloadResponse::SAFE);
632 net::FakeURLFetcherFactory factory(NULL);
633 // Empty response means SAFE.
634 factory.SetFakeResponse(
635 DownloadProtectionService::GetDownloadRequestUrl(),
636 response.SerializeAsString(),
637 net::HTTP_OK, net::URLRequestStatus::SUCCESS);
639 base::FilePath a_tmp(FILE_PATH_LITERAL("a.tmp"));
640 base::FilePath a_exe(FILE_PATH_LITERAL("a.exe"));
641 std::vector<GURL> url_chain;
642 url_chain.push_back(GURL("http://www.evil.com/a.exe"));
643 GURL referrer("http://www.google.com/");
644 std::string hash = "hash";
646 content::MockDownloadItem item;
647 EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp));
648 EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_exe));
649 EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
650 EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
651 EXPECT_CALL(item, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
652 EXPECT_CALL(item, GetTabReferrerUrl())
653 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
654 EXPECT_CALL(item, GetHash()).WillRepeatedly(ReturnRef(hash));
655 EXPECT_CALL(item, GetReceivedBytes()).WillRepeatedly(Return(100));
656 EXPECT_CALL(item, HasUserGesture()).WillRepeatedly(Return(true));
657 EXPECT_CALL(item, GetRemoteAddress()).WillRepeatedly(Return(""));
659 EXPECT_CALL(*sb_service_->mock_database_manager(),
660 MatchDownloadWhitelistUrl(_))
661 .WillRepeatedly(Return(false));
662 EXPECT_CALL(*binary_feature_extractor_.get(), CheckSignature(a_tmp, _))
664 EXPECT_CALL(*binary_feature_extractor_.get(), ExtractImageHeaders(a_tmp, _))
667 download_service_->CheckClientDownload(
669 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
670 base::Unretained(this)));
671 MessageLoop::current()->Run();
673 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
675 // On !OS_WIN, no file types are currently supported. Hence all requests to
676 // CheckClientDownload() result in a verdict of UNKNOWN.
677 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN));
680 #if defined(OS_WIN) || defined(OS_MACOSX)
681 // OSX sends pings for evaluation purposes.
682 EXPECT_TRUE(HasClientDownloadRequest());
683 ClearClientDownloadRequest();
685 EXPECT_FALSE(HasClientDownloadRequest());
688 // Invalid response should result in UNKNOWN.
690 factory.SetFakeResponse(
691 DownloadProtectionService::GetDownloadRequestUrl(),
692 response.SerializePartialAsString(),
693 net::HTTP_OK, net::URLRequestStatus::SUCCESS);
695 download_service_->CheckClientDownload(
697 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
698 base::Unretained(this)));
699 MessageLoop::current()->Run();
700 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN));
701 #if defined(OS_WIN) || defined(OS_MACOSX)
702 EXPECT_TRUE(HasClientDownloadRequest());
703 ClearClientDownloadRequest();
705 EXPECT_FALSE(HasClientDownloadRequest());
707 std::string feedback_ping;
708 std::string feedback_response;
709 EXPECT_FALSE(DownloadFeedbackService::GetPingsForDownloadForTesting(
710 item, &feedback_ping, &feedback_response));
712 // If the response is dangerous the result should also be marked as dangerous.
713 response.set_verdict(ClientDownloadResponse::DANGEROUS);
714 factory.SetFakeResponse(
715 DownloadProtectionService::GetDownloadRequestUrl(),
716 response.SerializeAsString(),
717 net::HTTP_OK, net::URLRequestStatus::SUCCESS);
719 download_service_->CheckClientDownload(
721 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
722 base::Unretained(this)));
723 MessageLoop::current()->Run();
724 EXPECT_FALSE(DownloadFeedbackService::GetPingsForDownloadForTesting(
725 item, &feedback_ping, &feedback_response));
727 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS));
729 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN));
732 #if defined(OS_WIN) || defined(OS_MACOSX)
733 // OSX sends pings for evaluation purposes.
734 EXPECT_TRUE(HasClientDownloadRequest());
735 ClearClientDownloadRequest();
737 EXPECT_FALSE(HasClientDownloadRequest());
740 // If the response is uncommon the result should also be marked as uncommon.
741 response.set_verdict(ClientDownloadResponse::UNCOMMON);
742 factory.SetFakeResponse(
743 DownloadProtectionService::GetDownloadRequestUrl(),
744 response.SerializeAsString(),
745 net::HTTP_OK, net::URLRequestStatus::SUCCESS);
747 download_service_->CheckClientDownload(
749 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
750 base::Unretained(this)));
751 MessageLoop::current()->Run();
753 EXPECT_TRUE(IsResult(DownloadProtectionService::UNCOMMON));
754 EXPECT_TRUE(DownloadFeedbackService::GetPingsForDownloadForTesting(
755 item, &feedback_ping, &feedback_response));
756 ClientDownloadRequest decoded_request;
757 EXPECT_TRUE(decoded_request.ParseFromString(feedback_ping));
758 EXPECT_EQ(url_chain.back().spec(), decoded_request.url());
759 EXPECT_EQ(response.SerializeAsString(), feedback_response);
760 EXPECT_TRUE(HasClientDownloadRequest());
761 ClearClientDownloadRequest();
763 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN));
766 // If the response is dangerous_host the result should also be marked as
768 response.set_verdict(ClientDownloadResponse::DANGEROUS_HOST);
769 factory.SetFakeResponse(
770 DownloadProtectionService::GetDownloadRequestUrl(),
771 response.SerializeAsString(),
772 net::HTTP_OK, net::URLRequestStatus::SUCCESS);
774 download_service_->CheckClientDownload(
776 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
777 base::Unretained(this)));
778 MessageLoop::current()->Run();
780 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS_HOST));
781 EXPECT_TRUE(DownloadFeedbackService::GetPingsForDownloadForTesting(
782 item, &feedback_ping, &feedback_response));
783 EXPECT_EQ(response.SerializeAsString(), feedback_response);
784 EXPECT_TRUE(HasClientDownloadRequest());
785 ClearClientDownloadRequest();
787 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN));
790 // If the response is POTENTIALLY_UNWANTED the result should also be marked as
791 // POTENTIALLY_UNWANTED.
792 response.set_verdict(ClientDownloadResponse::POTENTIALLY_UNWANTED);
793 factory.SetFakeResponse(
794 DownloadProtectionService::GetDownloadRequestUrl(),
795 response.SerializeAsString(),
796 net::HTTP_OK, net::URLRequestStatus::SUCCESS);
798 download_service_->CheckClientDownload(
800 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
801 base::Unretained(this)));
802 MessageLoop::current()->Run();
804 EXPECT_TRUE(IsResult(DownloadProtectionService::POTENTIALLY_UNWANTED));
806 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN));
809 #if defined(OS_WIN) || defined(OS_MACOSX)
810 // OSX sends pings for evaluation purposes.
811 EXPECT_TRUE(HasClientDownloadRequest());
812 ClearClientDownloadRequest();
814 EXPECT_FALSE(HasClientDownloadRequest());
818 TEST_F(DownloadProtectionServiceTest, CheckClientDownloadHTTPS) {
819 ClientDownloadResponse response;
820 response.set_verdict(ClientDownloadResponse::DANGEROUS);
821 net::FakeURLFetcherFactory factory(NULL);
822 factory.SetFakeResponse(
823 DownloadProtectionService::GetDownloadRequestUrl(),
824 response.SerializeAsString(),
825 net::HTTP_OK, net::URLRequestStatus::SUCCESS);
827 base::FilePath a_tmp(FILE_PATH_LITERAL("a.tmp"));
828 base::FilePath a_exe(FILE_PATH_LITERAL("a.exe"));
829 std::vector<GURL> url_chain;
830 url_chain.push_back(GURL("http://www.evil.com/a.exe"));
831 GURL referrer("http://www.google.com/");
832 std::string hash = "hash";
834 content::MockDownloadItem item;
835 EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp));
836 EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_exe));
837 EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
838 EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
839 EXPECT_CALL(item, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
840 EXPECT_CALL(item, GetTabReferrerUrl())
841 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
842 EXPECT_CALL(item, GetHash()).WillRepeatedly(ReturnRef(hash));
843 EXPECT_CALL(item, GetReceivedBytes()).WillRepeatedly(Return(100));
844 EXPECT_CALL(item, HasUserGesture()).WillRepeatedly(Return(true));
845 EXPECT_CALL(item, GetRemoteAddress()).WillRepeatedly(Return(""));
847 EXPECT_CALL(*sb_service_->mock_database_manager(),
848 MatchDownloadWhitelistUrl(_))
849 .WillRepeatedly(Return(false));
850 EXPECT_CALL(*binary_feature_extractor_.get(), CheckSignature(a_tmp, _))
852 EXPECT_CALL(*binary_feature_extractor_.get(), ExtractImageHeaders(a_tmp, _))
855 download_service_->CheckClientDownload(
857 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
858 base::Unretained(this)));
859 MessageLoop::current()->Run();
861 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS));
863 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN));
866 #if defined(OS_WIN) || defined(OS_MACOSX)
867 // OSX sends pings for evaluation purposes.
868 EXPECT_TRUE(HasClientDownloadRequest());
869 ClearClientDownloadRequest();
871 EXPECT_FALSE(HasClientDownloadRequest());
875 TEST_F(DownloadProtectionServiceTest, CheckClientDownloadZip) {
876 ClientDownloadResponse response;
877 response.set_verdict(ClientDownloadResponse::SAFE);
878 net::FakeURLFetcherFactory factory(NULL);
879 // Empty response means SAFE.
880 factory.SetFakeResponse(
881 DownloadProtectionService::GetDownloadRequestUrl(),
882 response.SerializeAsString(),
883 net::HTTP_OK, net::URLRequestStatus::SUCCESS);
885 base::ScopedTempDir download_dir;
886 ASSERT_TRUE(download_dir.CreateUniqueTempDir());
888 base::FilePath a_tmp(download_dir.path().Append(FILE_PATH_LITERAL("a.tmp")));
889 base::FilePath a_zip(FILE_PATH_LITERAL("a.zip"));
890 std::vector<GURL> url_chain;
891 url_chain.push_back(GURL("http://www.evil.com/a.zip"));
892 GURL referrer("http://www.google.com/");
893 std::string hash = "hash";
895 content::MockDownloadItem item;
896 EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp));
897 EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_zip));
898 EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
899 EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
900 EXPECT_CALL(item, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
901 EXPECT_CALL(item, GetTabReferrerUrl())
902 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
903 EXPECT_CALL(item, GetHash()).WillRepeatedly(ReturnRef(hash));
904 EXPECT_CALL(item, GetReceivedBytes()).WillRepeatedly(Return(100));
905 EXPECT_CALL(item, HasUserGesture()).WillRepeatedly(Return(true));
906 EXPECT_CALL(item, GetRemoteAddress()).WillRepeatedly(Return(""));
908 // Write out a zip archive to the temporary file. In this case, it
909 // only contains a text file.
910 base::ScopedTempDir zip_source_dir;
911 ASSERT_TRUE(zip_source_dir.CreateUniqueTempDir());
912 std::string file_contents = "dummy file";
913 ASSERT_EQ(static_cast<int>(file_contents.size()), base::WriteFile(
914 zip_source_dir.path().Append(FILE_PATH_LITERAL("file.txt")),
915 file_contents.data(), file_contents.size()));
916 ASSERT_TRUE(zip::Zip(zip_source_dir.path(), a_tmp, false));
918 download_service_->CheckClientDownload(
920 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
921 base::Unretained(this)));
922 MessageLoop::current()->Run();
923 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN));
924 EXPECT_FALSE(HasClientDownloadRequest());
925 Mock::VerifyAndClearExpectations(sb_service_.get());
926 Mock::VerifyAndClearExpectations(binary_feature_extractor_.get());
928 // Now check with an executable in the zip file as well.
929 ASSERT_EQ(static_cast<int>(file_contents.size()), base::WriteFile(
930 zip_source_dir.path().Append(FILE_PATH_LITERAL("file.exe")),
931 file_contents.data(), file_contents.size()));
932 ASSERT_TRUE(zip::Zip(zip_source_dir.path(), a_tmp, false));
934 EXPECT_CALL(*sb_service_->mock_database_manager(),
935 MatchDownloadWhitelistUrl(_))
936 .WillRepeatedly(Return(false));
938 download_service_->CheckClientDownload(
940 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
941 base::Unretained(this)));
942 MessageLoop::current()->Run();
944 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
946 // For !OS_WIN, no file types are currently supported. Hence the resulting
947 // verdict is UNKNOWN.
948 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN));
951 #if defined(OS_WIN) || defined(OS_MACOSX)
952 // OSX sends pings for evaluation purposes.
953 EXPECT_TRUE(HasClientDownloadRequest());
954 ClearClientDownloadRequest();
956 EXPECT_FALSE(HasClientDownloadRequest());
958 Mock::VerifyAndClearExpectations(binary_feature_extractor_.get());
960 // If the response is dangerous the result should also be marked as
962 response.set_verdict(ClientDownloadResponse::DANGEROUS);
963 factory.SetFakeResponse(
964 DownloadProtectionService::GetDownloadRequestUrl(),
965 response.SerializeAsString(),
966 net::HTTP_OK, net::URLRequestStatus::SUCCESS);
968 download_service_->CheckClientDownload(
970 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
971 base::Unretained(this)));
972 MessageLoop::current()->Run();
974 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS));
976 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN));
979 #if defined(OS_WIN) || defined(OS_MACOSX)
980 // OSX sends pings for evaluation purposes.
981 EXPECT_TRUE(HasClientDownloadRequest());
982 ClearClientDownloadRequest();
984 EXPECT_FALSE(HasClientDownloadRequest());
986 Mock::VerifyAndClearExpectations(binary_feature_extractor_.get());
989 TEST_F(DownloadProtectionServiceTest, CheckClientDownloadCorruptZip) {
990 base::ScopedTempDir download_dir;
991 ASSERT_TRUE(download_dir.CreateUniqueTempDir());
993 base::FilePath a_tmp(download_dir.path().Append(FILE_PATH_LITERAL("a.tmp")));
994 base::FilePath a_zip(FILE_PATH_LITERAL("a.zip"));
995 std::vector<GURL> url_chain;
996 url_chain.push_back(GURL("http://www.evil.com/a.zip"));
997 GURL referrer("http://www.google.com/");
998 std::string hash = "hash";
1000 content::MockDownloadItem item;
1001 EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp));
1002 EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_zip));
1003 EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
1004 EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
1005 EXPECT_CALL(item, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
1006 EXPECT_CALL(item, GetTabReferrerUrl())
1007 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
1008 EXPECT_CALL(item, GetHash()).WillRepeatedly(ReturnRef(hash));
1009 EXPECT_CALL(item, GetReceivedBytes()).WillRepeatedly(Return(100));
1010 EXPECT_CALL(item, HasUserGesture()).WillRepeatedly(Return(true));
1011 EXPECT_CALL(item, GetRemoteAddress()).WillRepeatedly(Return(""));
1013 std::string file_contents = "corrupt zip file";
1014 ASSERT_EQ(static_cast<int>(file_contents.size()), base::WriteFile(
1015 a_tmp, file_contents.data(), file_contents.size()));
1017 download_service_->CheckClientDownload(
1019 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
1020 base::Unretained(this)));
1021 MessageLoop::current()->Run();
1022 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN));
1023 EXPECT_FALSE(HasClientDownloadRequest());
1024 Mock::VerifyAndClearExpectations(sb_service_.get());
1025 Mock::VerifyAndClearExpectations(binary_feature_extractor_.get());
1028 TEST_F(DownloadProtectionServiceTest, CheckClientCrxDownloadSuccess) {
1029 ClientDownloadResponse response;
1030 // Even if the server verdict is dangerous we should return SAFE because
1031 // DownloadProtectionService::IsSupportedDownload() will return false
1032 // for crx downloads.
1033 response.set_verdict(ClientDownloadResponse::DANGEROUS);
1034 net::FakeURLFetcherFactory factory(NULL);
1035 // Empty response means SAFE.
1036 factory.SetFakeResponse(
1037 DownloadProtectionService::GetDownloadRequestUrl(),
1038 response.SerializeAsString(),
1039 net::HTTP_OK, net::URLRequestStatus::SUCCESS);
1041 base::FilePath a_tmp(FILE_PATH_LITERAL("a.tmp"));
1042 base::FilePath a_crx(FILE_PATH_LITERAL("a.crx"));
1043 std::vector<GURL> url_chain;
1044 url_chain.push_back(GURL("http://www.evil.com/a.crx"));
1045 GURL referrer("http://www.google.com/");
1046 std::string hash = "hash";
1048 content::MockDownloadItem item;
1049 EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp));
1050 EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_crx));
1051 EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
1052 EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
1053 EXPECT_CALL(item, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
1054 EXPECT_CALL(item, GetTabReferrerUrl())
1055 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
1056 EXPECT_CALL(item, GetHash()).WillRepeatedly(ReturnRef(hash));
1057 EXPECT_CALL(item, GetReceivedBytes()).WillRepeatedly(Return(100));
1058 EXPECT_CALL(item, HasUserGesture()).WillRepeatedly(Return(true));
1059 EXPECT_CALL(item, GetRemoteAddress()).WillRepeatedly(Return(""));
1061 EXPECT_CALL(*sb_service_->mock_database_manager(),
1062 MatchDownloadWhitelistUrl(_))
1063 .WillRepeatedly(Return(false));
1064 EXPECT_CALL(*binary_feature_extractor_.get(), CheckSignature(a_tmp, _))
1066 EXPECT_CALL(*binary_feature_extractor_.get(), ExtractImageHeaders(a_tmp, _))
1069 EXPECT_FALSE(download_service_->IsSupportedDownload(item, a_crx));
1070 download_service_->CheckClientDownload(
1072 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
1073 base::Unretained(this)));
1074 MessageLoop::current()->Run();
1075 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN));
1078 #if defined(OS_MACOSX)
1079 // TODO(mattm): remove this (see crbug.com/414834).
1080 TEST_F(DownloadProtectionServiceTest,
1081 CheckClientDownloadPingOnOSXRequiresFieldTrial) {
1082 // Clear the field trial that was set in SetUp().
1083 field_trial_list_.reset();
1085 net::TestURLFetcherFactory factory;
1087 base::FilePath tmp_path(FILE_PATH_LITERAL("bla.tmp"));
1088 base::FilePath final_path(FILE_PATH_LITERAL("bla.exe"));
1089 std::vector<GURL> url_chain;
1090 url_chain.push_back(GURL("http://www.google.com/"));
1091 url_chain.push_back(GURL("http://www.google.com/bla.exe"));
1092 GURL referrer("http://www.google.com/");
1093 std::string hash = "hash";
1094 std::string remote_address = "10.11.12.13";
1096 content::MockDownloadItem item;
1097 EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(tmp_path));
1098 EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(final_path));
1099 EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
1100 EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
1101 EXPECT_CALL(item, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
1102 EXPECT_CALL(item, GetTabReferrerUrl())
1103 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
1104 EXPECT_CALL(item, GetHash()).WillRepeatedly(ReturnRef(hash));
1105 EXPECT_CALL(item, GetReceivedBytes()).WillRepeatedly(Return(100));
1106 EXPECT_CALL(item, HasUserGesture()).WillRepeatedly(Return(true));
1107 EXPECT_CALL(item, GetRemoteAddress()).WillRepeatedly(Return(remote_address));
1109 EXPECT_CALL(*sb_service_->mock_database_manager(),
1110 MatchDownloadWhitelistUrl(_))
1111 .WillRepeatedly(Return(false));
1112 EXPECT_CALL(*binary_feature_extractor_.get(), CheckSignature(tmp_path, _))
1113 .WillOnce(SetCertificateContents("dummy cert data"));
1114 EXPECT_CALL(*binary_feature_extractor_.get(),
1115 ExtractImageHeaders(tmp_path, _))
1116 .WillOnce(SetDosHeaderContents("dummy dos header"));
1117 download_service_->CheckClientDownload(
1119 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
1120 base::Unretained(this)));
1122 // SendRequest is not called. Wait for FinishRequest to call our callback.
1123 MessageLoop::current()->Run();
1124 net::TestURLFetcher* fetcher = factory.GetFetcherByID(0);
1125 EXPECT_EQ(NULL, fetcher);
1126 EXPECT_FALSE(HasClientDownloadRequest());
1130 TEST_F(DownloadProtectionServiceTest, CheckClientDownloadValidateRequest) {
1131 net::TestURLFetcherFactory factory;
1133 base::FilePath tmp_path(FILE_PATH_LITERAL("bla.tmp"));
1134 base::FilePath final_path(FILE_PATH_LITERAL("bla.exe"));
1135 std::vector<GURL> url_chain;
1136 url_chain.push_back(GURL("http://www.google.com/"));
1137 url_chain.push_back(GURL("http://www.google.com/bla.exe"));
1138 GURL referrer("http://www.google.com/");
1139 std::string hash = "hash";
1140 std::string remote_address = "10.11.12.13";
1142 content::MockDownloadItem item;
1143 EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(tmp_path));
1144 EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(final_path));
1145 EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
1146 EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
1147 EXPECT_CALL(item, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
1148 EXPECT_CALL(item, GetTabReferrerUrl())
1149 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
1150 EXPECT_CALL(item, GetHash()).WillRepeatedly(ReturnRef(hash));
1151 EXPECT_CALL(item, GetReceivedBytes()).WillRepeatedly(Return(100));
1152 EXPECT_CALL(item, HasUserGesture()).WillRepeatedly(Return(true));
1153 EXPECT_CALL(item, GetRemoteAddress()).WillRepeatedly(Return(remote_address));
1155 EXPECT_CALL(*sb_service_->mock_database_manager(),
1156 MatchDownloadWhitelistUrl(_))
1157 .WillRepeatedly(Return(false));
1158 EXPECT_CALL(*binary_feature_extractor_.get(), CheckSignature(tmp_path, _))
1159 .WillOnce(SetCertificateContents("dummy cert data"));
1160 EXPECT_CALL(*binary_feature_extractor_.get(),
1161 ExtractImageHeaders(tmp_path, _))
1162 .WillOnce(SetDosHeaderContents("dummy dos header"));
1163 download_service_->CheckClientDownload(
1165 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
1166 base::Unretained(this)));
1168 #if !defined(OS_WIN) && !defined(OS_MACOSX)
1169 // SendRequest is not called. Wait for FinishRequest to call our callback.
1170 MessageLoop::current()->Run();
1171 net::TestURLFetcher* fetcher = factory.GetFetcherByID(0);
1172 EXPECT_EQ(NULL, fetcher);
1173 EXPECT_FALSE(HasClientDownloadRequest());
1175 // Run the message loop(s) until SendRequest is called.
1176 FlushThreadMessageLoops();
1177 EXPECT_TRUE(HasClientDownloadRequest());
1178 ClearClientDownloadRequest();
1179 net::TestURLFetcher* fetcher = factory.GetFetcherByID(0);
1180 ASSERT_TRUE(fetcher);
1181 ClientDownloadRequest request;
1182 EXPECT_TRUE(request.ParseFromString(fetcher->upload_data()));
1183 EXPECT_EQ("http://www.google.com/bla.exe", request.url());
1184 EXPECT_EQ(hash, request.digests().sha256());
1185 EXPECT_EQ(item.GetReceivedBytes(), request.length());
1186 EXPECT_EQ(item.HasUserGesture(), request.user_initiated());
1187 EXPECT_TRUE(RequestContainsServerIp(request, remote_address));
1188 EXPECT_EQ(2, request.resources_size());
1189 EXPECT_TRUE(RequestContainsResource(request,
1190 ClientDownloadRequest::DOWNLOAD_REDIRECT,
1191 "http://www.google.com/", ""));
1192 EXPECT_TRUE(RequestContainsResource(request,
1193 ClientDownloadRequest::DOWNLOAD_URL,
1194 "http://www.google.com/bla.exe",
1196 EXPECT_TRUE(request.has_signature());
1197 ASSERT_EQ(1, request.signature().certificate_chain_size());
1198 const ClientDownloadRequest_CertificateChain& chain =
1199 request.signature().certificate_chain(0);
1200 ASSERT_EQ(1, chain.element_size());
1201 EXPECT_EQ("dummy cert data", chain.element(0).certificate());
1202 EXPECT_TRUE(request.has_image_headers());
1203 const ClientDownloadRequest_ImageHeaders& headers =
1204 request.image_headers();
1205 EXPECT_TRUE(headers.has_pe_headers());
1206 EXPECT_TRUE(headers.pe_headers().has_dos_header());
1207 EXPECT_EQ("dummy dos header", headers.pe_headers().dos_header());
1209 // Simulate the request finishing.
1210 base::MessageLoop::current()->PostTask(
1212 base::Bind(&DownloadProtectionServiceTest::SendURLFetchComplete,
1213 base::Unretained(this), fetcher));
1214 MessageLoop::current()->Run();
1218 // Similar to above, but with an unsigned binary.
1219 TEST_F(DownloadProtectionServiceTest,
1220 CheckClientDownloadValidateRequestNoSignature) {
1221 net::TestURLFetcherFactory factory;
1223 base::FilePath tmp_path(FILE_PATH_LITERAL("bla.tmp"));
1224 base::FilePath final_path(FILE_PATH_LITERAL("bla.exe"));
1225 std::vector<GURL> url_chain;
1226 url_chain.push_back(GURL("http://www.google.com/"));
1227 url_chain.push_back(GURL("ftp://www.google.com/bla.exe"));
1228 GURL referrer("http://www.google.com/");
1229 std::string hash = "hash";
1230 std::string remote_address = "10.11.12.13";
1232 content::MockDownloadItem item;
1233 EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(tmp_path));
1234 EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(final_path));
1235 EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
1236 EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
1237 EXPECT_CALL(item, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
1238 EXPECT_CALL(item, GetTabReferrerUrl())
1239 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
1240 EXPECT_CALL(item, GetHash()).WillRepeatedly(ReturnRef(hash));
1241 EXPECT_CALL(item, GetReceivedBytes()).WillRepeatedly(Return(100));
1242 EXPECT_CALL(item, HasUserGesture()).WillRepeatedly(Return(true));
1243 EXPECT_CALL(item, GetRemoteAddress()).WillRepeatedly(Return(remote_address));
1245 EXPECT_CALL(*sb_service_->mock_database_manager(),
1246 MatchDownloadWhitelistUrl(_))
1247 .WillRepeatedly(Return(false));
1248 EXPECT_CALL(*binary_feature_extractor_.get(), CheckSignature(tmp_path, _));
1249 EXPECT_CALL(*binary_feature_extractor_.get(),
1250 ExtractImageHeaders(tmp_path, _));
1251 download_service_->CheckClientDownload(
1253 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
1254 base::Unretained(this)));
1256 #if !defined(OS_WIN) && !defined(OS_MACOSX)
1257 // SendRequest is not called. Wait for FinishRequest to call our callback.
1258 MessageLoop::current()->Run();
1259 net::TestURLFetcher* fetcher = factory.GetFetcherByID(0);
1260 EXPECT_EQ(NULL, fetcher);
1261 EXPECT_FALSE(HasClientDownloadRequest());
1263 // Run the message loop(s) until SendRequest is called.
1264 FlushThreadMessageLoops();
1265 EXPECT_TRUE(HasClientDownloadRequest());
1266 ClearClientDownloadRequest();
1267 net::TestURLFetcher* fetcher = factory.GetFetcherByID(0);
1268 ASSERT_TRUE(fetcher);
1269 ClientDownloadRequest request;
1270 EXPECT_TRUE(request.ParseFromString(fetcher->upload_data()));
1271 EXPECT_EQ("ftp://www.google.com/bla.exe", request.url());
1272 EXPECT_EQ(hash, request.digests().sha256());
1273 EXPECT_EQ(item.GetReceivedBytes(), request.length());
1274 EXPECT_EQ(item.HasUserGesture(), request.user_initiated());
1275 EXPECT_EQ(2, request.resources_size());
1276 EXPECT_TRUE(RequestContainsResource(request,
1277 ClientDownloadRequest::DOWNLOAD_REDIRECT,
1278 "http://www.google.com/", ""));
1279 EXPECT_TRUE(RequestContainsResource(request,
1280 ClientDownloadRequest::DOWNLOAD_URL,
1281 "ftp://www.google.com/bla.exe",
1283 EXPECT_TRUE(request.has_signature());
1284 EXPECT_EQ(0, request.signature().certificate_chain_size());
1286 // Simulate the request finishing.
1287 base::MessageLoop::current()->PostTask(
1289 base::Bind(&DownloadProtectionServiceTest::SendURLFetchComplete,
1290 base::Unretained(this), fetcher));
1291 MessageLoop::current()->Run();
1295 // Similar to above, but with tab history.
1296 TEST_F(DownloadProtectionServiceTest,
1297 CheckClientDownloadValidateRequestTabHistory) {
1298 net::TestURLFetcherFactory factory;
1300 base::ScopedTempDir profile_dir;
1301 ASSERT_TRUE(profile_dir.CreateUniqueTempDir());
1302 TestingProfile profile(profile_dir.path());
1304 profile.CreateHistoryService(true /* delete_file */, false /* no_db */));
1306 base::FilePath tmp_path(FILE_PATH_LITERAL("bla.tmp"));
1307 base::FilePath final_path(FILE_PATH_LITERAL("bla.exe"));
1308 std::vector<GURL> url_chain;
1309 url_chain.push_back(GURL("http://www.google.com/"));
1310 url_chain.push_back(GURL("http://www.google.com/bla.exe"));
1311 GURL referrer("http://www.google.com/");
1312 GURL tab_url("http://tab.com/final");
1313 GURL tab_referrer("http://tab.com/referrer");
1314 std::string hash = "hash";
1315 std::string remote_address = "10.11.12.13";
1317 content::MockDownloadItem item;
1318 EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(tmp_path));
1319 EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(final_path));
1320 EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
1321 EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
1322 EXPECT_CALL(item, GetTabUrl()).WillRepeatedly(ReturnRef(tab_url));
1323 EXPECT_CALL(item, GetTabReferrerUrl())
1324 .WillRepeatedly(ReturnRef(tab_referrer));
1325 EXPECT_CALL(item, GetHash()).WillRepeatedly(ReturnRef(hash));
1326 EXPECT_CALL(item, GetReceivedBytes()).WillRepeatedly(Return(100));
1327 EXPECT_CALL(item, HasUserGesture()).WillRepeatedly(Return(true));
1328 EXPECT_CALL(item, GetRemoteAddress()).WillRepeatedly(Return(remote_address));
1329 EXPECT_CALL(item, GetBrowserContext()).WillRepeatedly(Return(&profile));
1330 EXPECT_CALL(*sb_service_->mock_database_manager(),
1331 MatchDownloadWhitelistUrl(_))
1332 .WillRepeatedly(Return(false));
1333 EXPECT_CALL(*binary_feature_extractor_.get(), CheckSignature(tmp_path, _))
1334 .WillRepeatedly(SetCertificateContents("dummy cert data"));
1335 EXPECT_CALL(*binary_feature_extractor_.get(),
1336 ExtractImageHeaders(tmp_path, _))
1337 .WillRepeatedly(SetDosHeaderContents("dummy dos header"));
1339 // First test with no history match for the tab URL.
1341 TestURLFetcherWatcher fetcher_watcher(&factory);
1342 download_service_->CheckClientDownload(
1344 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
1345 base::Unretained(this)));
1347 #if !defined(OS_WIN) && !defined(OS_MACOSX)
1348 // SendRequest is not called. Wait for FinishRequest to call our callback.
1349 MessageLoop::current()->Run();
1350 net::TestURLFetcher* fetcher = factory.GetFetcherByID(0);
1351 EXPECT_EQ(NULL, fetcher);
1352 EXPECT_FALSE(HasClientDownloadRequest());
1354 EXPECT_EQ(0, fetcher_watcher.WaitForRequest());
1355 EXPECT_TRUE(HasClientDownloadRequest());
1356 ClearClientDownloadRequest();
1357 net::TestURLFetcher* fetcher = factory.GetFetcherByID(0);
1358 ASSERT_TRUE(fetcher);
1359 ClientDownloadRequest request;
1360 EXPECT_TRUE(request.ParseFromString(fetcher->upload_data()));
1361 EXPECT_EQ("http://www.google.com/bla.exe", request.url());
1362 EXPECT_EQ(hash, request.digests().sha256());
1363 EXPECT_EQ(item.GetReceivedBytes(), request.length());
1364 EXPECT_EQ(item.HasUserGesture(), request.user_initiated());
1365 EXPECT_TRUE(RequestContainsServerIp(request, remote_address));
1366 EXPECT_EQ(3, request.resources_size());
1368 RequestContainsResource(request,
1369 ClientDownloadRequest::DOWNLOAD_REDIRECT,
1370 "http://www.google.com/",
1372 EXPECT_TRUE(RequestContainsResource(request,
1373 ClientDownloadRequest::DOWNLOAD_URL,
1374 "http://www.google.com/bla.exe",
1376 EXPECT_TRUE(RequestContainsResource(request,
1377 ClientDownloadRequest::TAB_URL,
1379 tab_referrer.spec()));
1380 EXPECT_TRUE(request.has_signature());
1381 ASSERT_EQ(1, request.signature().certificate_chain_size());
1382 const ClientDownloadRequest_CertificateChain& chain =
1383 request.signature().certificate_chain(0);
1384 ASSERT_EQ(1, chain.element_size());
1385 EXPECT_EQ("dummy cert data", chain.element(0).certificate());
1386 EXPECT_TRUE(request.has_image_headers());
1387 const ClientDownloadRequest_ImageHeaders& headers =
1388 request.image_headers();
1389 EXPECT_TRUE(headers.has_pe_headers());
1390 EXPECT_TRUE(headers.pe_headers().has_dos_header());
1391 EXPECT_EQ("dummy dos header", headers.pe_headers().dos_header());
1393 // Simulate the request finishing.
1394 base::MessageLoop::current()->PostTask(
1396 base::Bind(&DownloadProtectionServiceTest::SendURLFetchComplete,
1397 base::Unretained(this),
1399 MessageLoop::current()->Run();
1403 // Now try with a history match.
1405 history::RedirectList redirects;
1406 redirects.push_back(GURL("http://tab.com/ref1"));
1407 redirects.push_back(GURL("http://tab.com/ref2"));
1408 redirects.push_back(tab_url);
1409 HistoryServiceFactory::GetForProfile(&profile, Profile::EXPLICIT_ACCESS)
1412 reinterpret_cast<history::ContextID>(1),
1416 ui::PAGE_TRANSITION_TYPED,
1417 history::SOURCE_BROWSED,
1420 TestURLFetcherWatcher fetcher_watcher(&factory);
1421 download_service_->CheckClientDownload(
1423 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
1424 base::Unretained(this)));
1425 #if !defined(OS_WIN) && !defined(OS_MACOSX)
1426 // SendRequest is not called. Wait for FinishRequest to call our callback.
1427 MessageLoop::current()->Run();
1428 net::TestURLFetcher* fetcher = factory.GetFetcherByID(0);
1429 EXPECT_EQ(NULL, fetcher);
1430 EXPECT_FALSE(HasClientDownloadRequest());
1432 EXPECT_EQ(0, fetcher_watcher.WaitForRequest());
1433 EXPECT_TRUE(HasClientDownloadRequest());
1434 ClearClientDownloadRequest();
1435 net::TestURLFetcher* fetcher = factory.GetFetcherByID(0);
1436 ASSERT_TRUE(fetcher);
1437 ClientDownloadRequest request;
1438 EXPECT_TRUE(request.ParseFromString(fetcher->upload_data()));
1439 EXPECT_EQ("http://www.google.com/bla.exe", request.url());
1440 EXPECT_EQ(hash, request.digests().sha256());
1441 EXPECT_EQ(item.GetReceivedBytes(), request.length());
1442 EXPECT_EQ(item.HasUserGesture(), request.user_initiated());
1443 EXPECT_TRUE(RequestContainsServerIp(request, remote_address));
1444 EXPECT_EQ(5, request.resources_size());
1446 RequestContainsResource(request,
1447 ClientDownloadRequest::DOWNLOAD_REDIRECT,
1448 "http://www.google.com/",
1450 EXPECT_TRUE(RequestContainsResource(request,
1451 ClientDownloadRequest::DOWNLOAD_URL,
1452 "http://www.google.com/bla.exe",
1454 EXPECT_TRUE(RequestContainsResource(request,
1455 ClientDownloadRequest::TAB_REDIRECT,
1456 "http://tab.com/ref1",
1458 EXPECT_TRUE(RequestContainsResource(request,
1459 ClientDownloadRequest::TAB_REDIRECT,
1460 "http://tab.com/ref2",
1462 EXPECT_TRUE(RequestContainsResource(request,
1463 ClientDownloadRequest::TAB_URL,
1465 tab_referrer.spec()));
1466 EXPECT_TRUE(request.has_signature());
1467 ASSERT_EQ(1, request.signature().certificate_chain_size());
1468 const ClientDownloadRequest_CertificateChain& chain =
1469 request.signature().certificate_chain(0);
1470 ASSERT_EQ(1, chain.element_size());
1471 EXPECT_EQ("dummy cert data", chain.element(0).certificate());
1473 // Simulate the request finishing.
1474 base::MessageLoop::current()->PostTask(
1476 base::Bind(&DownloadProtectionServiceTest::SendURLFetchComplete,
1477 base::Unretained(this),
1479 MessageLoop::current()->Run();
1484 TEST_F(DownloadProtectionServiceTest, TestCheckDownloadUrl) {
1485 std::vector<GURL> url_chain;
1486 url_chain.push_back(GURL("http://www.google.com/"));
1487 url_chain.push_back(GURL("http://www.google.com/bla.exe"));
1488 GURL referrer("http://www.google.com/");
1489 std::string hash = "hash";
1491 content::MockDownloadItem item;
1492 EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
1493 EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
1494 EXPECT_CALL(item, GetHash()).WillRepeatedly(ReturnRef(hash));
1496 // CheckDownloadURL returns immediately which means the client object callback
1497 // will never be called. Nevertheless the callback provided to
1498 // CheckClientDownload must still be called.
1499 EXPECT_CALL(*sb_service_->mock_database_manager(),
1500 CheckDownloadUrl(ContainerEq(url_chain), NotNull()))
1501 .WillOnce(Return(true));
1502 download_service_->CheckDownloadUrl(
1504 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
1505 base::Unretained(this)));
1506 MessageLoop::current()->Run();
1507 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
1508 Mock::VerifyAndClearExpectations(sb_service_.get());
1510 EXPECT_CALL(*sb_service_->mock_database_manager(),
1511 CheckDownloadUrl(ContainerEq(url_chain), NotNull()))
1512 .WillOnce(DoAll(CheckDownloadUrlDone(SB_THREAT_TYPE_SAFE),
1514 download_service_->CheckDownloadUrl(
1516 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
1517 base::Unretained(this)));
1518 MessageLoop::current()->Run();
1519 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
1520 Mock::VerifyAndClearExpectations(sb_service_.get());
1522 EXPECT_CALL(*sb_service_->mock_database_manager(),
1523 CheckDownloadUrl(ContainerEq(url_chain), NotNull()))
1525 CheckDownloadUrlDone(SB_THREAT_TYPE_URL_MALWARE),
1527 download_service_->CheckDownloadUrl(
1529 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
1530 base::Unretained(this)));
1531 MessageLoop::current()->Run();
1532 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
1533 Mock::VerifyAndClearExpectations(sb_service_.get());
1535 EXPECT_CALL(*sb_service_->mock_database_manager(),
1536 CheckDownloadUrl(ContainerEq(url_chain),
1539 CheckDownloadUrlDone(SB_THREAT_TYPE_BINARY_MALWARE_URL),
1541 download_service_->CheckDownloadUrl(
1543 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
1544 base::Unretained(this)));
1545 MessageLoop::current()->Run();
1546 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS));
1549 TEST_F(DownloadProtectionServiceTest, TestDownloadRequestTimeout) {
1550 net::TestURLFetcherFactory factory;
1552 std::vector<GURL> url_chain;
1553 url_chain.push_back(GURL("http://www.evil.com/bla.exe"));
1554 GURL referrer("http://www.google.com/");
1555 base::FilePath tmp_path(FILE_PATH_LITERAL("a.tmp"));
1556 base::FilePath final_path(FILE_PATH_LITERAL("a.exe"));
1557 std::string hash = "hash";
1559 content::MockDownloadItem item;
1560 EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(tmp_path));
1561 EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(final_path));
1562 EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
1563 EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
1564 EXPECT_CALL(item, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
1565 EXPECT_CALL(item, GetTabReferrerUrl())
1566 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
1567 EXPECT_CALL(item, GetHash()).WillRepeatedly(ReturnRef(hash));
1568 EXPECT_CALL(item, GetReceivedBytes()).WillRepeatedly(Return(100));
1569 EXPECT_CALL(item, HasUserGesture()).WillRepeatedly(Return(true));
1570 EXPECT_CALL(item, GetRemoteAddress()).WillRepeatedly(Return(""));
1572 EXPECT_CALL(*sb_service_->mock_database_manager(),
1573 MatchDownloadWhitelistUrl(_))
1574 .WillRepeatedly(Return(false));
1575 EXPECT_CALL(*binary_feature_extractor_.get(), CheckSignature(tmp_path, _));
1576 EXPECT_CALL(*binary_feature_extractor_.get(),
1577 ExtractImageHeaders(tmp_path, _));
1579 download_service_->download_request_timeout_ms_ = 10;
1580 download_service_->CheckClientDownload(
1582 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
1583 base::Unretained(this)));
1585 // The request should time out because the HTTP request hasn't returned
1587 MessageLoop::current()->Run();
1588 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN));
1589 #if defined(OS_WIN) || defined(OS_MACOSX)
1590 EXPECT_TRUE(HasClientDownloadRequest());
1591 ClearClientDownloadRequest();
1593 EXPECT_FALSE(HasClientDownloadRequest());
1597 TEST_F(DownloadProtectionServiceTest, TestDownloadItemDestroyed) {
1598 net::TestURLFetcherFactory factory;
1600 std::vector<GURL> url_chain;
1601 url_chain.push_back(GURL("http://www.evil.com/bla.exe"));
1602 GURL referrer("http://www.google.com/");
1603 GURL tab_url("http://www.google.com/tab");
1604 base::FilePath tmp_path(FILE_PATH_LITERAL("a.tmp"));
1605 base::FilePath final_path(FILE_PATH_LITERAL("a.exe"));
1606 std::string hash = "hash";
1609 content::MockDownloadItem item;
1610 EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(tmp_path));
1611 EXPECT_CALL(item, GetTargetFilePath())
1612 .WillRepeatedly(ReturnRef(final_path));
1613 EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
1614 EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
1615 EXPECT_CALL(item, GetTabUrl()).WillRepeatedly(ReturnRef(tab_url));
1616 EXPECT_CALL(item, GetTabReferrerUrl())
1617 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
1618 EXPECT_CALL(item, GetHash()).WillRepeatedly(ReturnRef(hash));
1619 EXPECT_CALL(item, GetReceivedBytes()).WillRepeatedly(Return(100));
1620 EXPECT_CALL(item, HasUserGesture()).WillRepeatedly(Return(true));
1621 EXPECT_CALL(item, GetRemoteAddress()).WillRepeatedly(Return(""));
1623 EXPECT_CALL(*sb_service_->mock_database_manager(),
1624 MatchDownloadWhitelistUrl(_))
1625 .WillRepeatedly(Return(false));
1626 EXPECT_CALL(*binary_feature_extractor_.get(), CheckSignature(tmp_path, _));
1627 EXPECT_CALL(*binary_feature_extractor_.get(),
1628 ExtractImageHeaders(tmp_path, _));
1630 download_service_->CheckClientDownload(
1632 base::Bind(&DownloadProtectionServiceTest::SyncCheckDoneCallback,
1633 base::Unretained(this)));
1634 // MockDownloadItem going out of scope triggers the OnDownloadDestroyed
1638 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN));
1639 EXPECT_FALSE(HasClientDownloadRequest());
1642 TEST_F(DownloadProtectionServiceTest,
1643 TestDownloadItemDestroyedDuringWhitelistCheck) {
1644 net::TestURLFetcherFactory factory;
1646 std::vector<GURL> url_chain;
1647 url_chain.push_back(GURL("http://www.evil.com/bla.exe"));
1648 GURL referrer("http://www.google.com/");
1649 GURL tab_url("http://www.google.com/tab");
1650 base::FilePath tmp_path(FILE_PATH_LITERAL("a.tmp"));
1651 base::FilePath final_path(FILE_PATH_LITERAL("a.exe"));
1652 std::string hash = "hash";
1654 scoped_ptr<content::MockDownloadItem> item(new content::MockDownloadItem);
1655 EXPECT_CALL(*item, GetFullPath()).WillRepeatedly(ReturnRef(tmp_path));
1656 EXPECT_CALL(*item, GetTargetFilePath())
1657 .WillRepeatedly(ReturnRef(final_path));
1658 EXPECT_CALL(*item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
1659 EXPECT_CALL(*item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
1660 EXPECT_CALL(*item, GetTabUrl()).WillRepeatedly(ReturnRef(tab_url));
1661 EXPECT_CALL(*item, GetTabReferrerUrl())
1662 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
1663 EXPECT_CALL(*item, GetHash()).WillRepeatedly(ReturnRef(hash));
1664 EXPECT_CALL(*item, GetReceivedBytes()).WillRepeatedly(Return(100));
1665 EXPECT_CALL(*item, HasUserGesture()).WillRepeatedly(Return(true));
1666 EXPECT_CALL(*item, GetRemoteAddress()).WillRepeatedly(Return(""));
1668 EXPECT_CALL(*sb_service_->mock_database_manager(),
1669 MatchDownloadWhitelistUrl(_))
1670 .WillRepeatedly(Invoke([&item](const GURL&) {
1674 EXPECT_CALL(*binary_feature_extractor_.get(), CheckSignature(tmp_path, _));
1675 EXPECT_CALL(*binary_feature_extractor_.get(),
1676 ExtractImageHeaders(tmp_path, _));
1678 download_service_->CheckClientDownload(
1680 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
1681 base::Unretained(this)));
1683 MessageLoop::current()->Run();
1684 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN));
1685 EXPECT_FALSE(HasClientDownloadRequest());
1688 TEST_F(DownloadProtectionServiceTest, GetCertificateWhitelistStrings) {
1689 // We'll pass this cert in as the "issuer", even though it isn't really
1690 // used to sign the certs below. GetCertificateWhitelistStirngs doesn't care
1692 scoped_refptr<net::X509Certificate> issuer_cert(
1693 ReadTestCertificate("issuer.pem"));
1694 ASSERT_TRUE(issuer_cert.get());
1695 std::string cert_base = "cert/" + base::HexEncode(
1696 issuer_cert->fingerprint().data,
1697 sizeof(issuer_cert->fingerprint().data));
1699 scoped_refptr<net::X509Certificate> cert(ReadTestCertificate("test_cn.pem"));
1700 ASSERT_TRUE(cert.get());
1701 std::vector<std::string> whitelist_strings;
1702 GetCertificateWhitelistStrings(
1703 *cert.get(), *issuer_cert.get(), &whitelist_strings);
1704 // This also tests escaping of characters in the certificate attributes.
1705 EXPECT_THAT(whitelist_strings, ElementsAre(
1706 cert_base + "/CN=subject%2F%251"));
1708 cert = ReadTestCertificate("test_cn_o.pem");
1709 ASSERT_TRUE(cert.get());
1710 whitelist_strings.clear();
1711 GetCertificateWhitelistStrings(
1712 *cert.get(), *issuer_cert.get(), &whitelist_strings);
1713 EXPECT_THAT(whitelist_strings,
1714 ElementsAre(cert_base + "/CN=subject",
1715 cert_base + "/CN=subject/O=org",
1716 cert_base + "/O=org"));
1718 cert = ReadTestCertificate("test_cn_o_ou.pem");
1719 ASSERT_TRUE(cert.get());
1720 whitelist_strings.clear();
1721 GetCertificateWhitelistStrings(
1722 *cert.get(), *issuer_cert.get(), &whitelist_strings);
1723 EXPECT_THAT(whitelist_strings,
1724 ElementsAre(cert_base + "/CN=subject",
1725 cert_base + "/CN=subject/O=org",
1726 cert_base + "/CN=subject/O=org/OU=unit",
1727 cert_base + "/CN=subject/OU=unit",
1728 cert_base + "/O=org",
1729 cert_base + "/O=org/OU=unit",
1730 cert_base + "/OU=unit"));
1732 cert = ReadTestCertificate("test_cn_ou.pem");
1733 ASSERT_TRUE(cert.get());
1734 whitelist_strings.clear();
1735 GetCertificateWhitelistStrings(
1736 *cert.get(), *issuer_cert.get(), &whitelist_strings);
1737 EXPECT_THAT(whitelist_strings,
1738 ElementsAre(cert_base + "/CN=subject",
1739 cert_base + "/CN=subject/OU=unit",
1740 cert_base + "/OU=unit"));
1742 cert = ReadTestCertificate("test_o.pem");
1743 ASSERT_TRUE(cert.get());
1744 whitelist_strings.clear();
1745 GetCertificateWhitelistStrings(
1746 *cert.get(), *issuer_cert.get(), &whitelist_strings);
1747 EXPECT_THAT(whitelist_strings, ElementsAre(cert_base + "/O=org"));
1749 cert = ReadTestCertificate("test_o_ou.pem");
1750 ASSERT_TRUE(cert.get());
1751 whitelist_strings.clear();
1752 GetCertificateWhitelistStrings(
1753 *cert.get(), *issuer_cert.get(), &whitelist_strings);
1754 EXPECT_THAT(whitelist_strings,
1755 ElementsAre(cert_base + "/O=org",
1756 cert_base + "/O=org/OU=unit",
1757 cert_base + "/OU=unit"));
1759 cert = ReadTestCertificate("test_ou.pem");
1760 ASSERT_TRUE(cert.get());
1761 whitelist_strings.clear();
1762 GetCertificateWhitelistStrings(
1763 *cert.get(), *issuer_cert.get(), &whitelist_strings);
1764 EXPECT_THAT(whitelist_strings, ElementsAre(cert_base + "/OU=unit"));
1766 cert = ReadTestCertificate("test_c.pem");
1767 ASSERT_TRUE(cert.get());
1768 whitelist_strings.clear();
1769 GetCertificateWhitelistStrings(
1770 *cert.get(), *issuer_cert.get(), &whitelist_strings);
1771 EXPECT_THAT(whitelist_strings, ElementsAre());
1773 } // namespace safe_browsing