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 const ClientDownloadRequest
* GetClientDownloadRequest() const {
310 return last_client_download_request_
.get();
313 bool HasClientDownloadRequest() const {
314 return last_client_download_request_
.get() != NULL
;
317 void ClearClientDownloadRequest() { last_client_download_request_
.reset(); }
320 // Helper functions for FlushThreadMessageLoops.
321 void RunAllPendingAndQuitUI() {
322 base::MessageLoop::current()->RunUntilIdle();
323 BrowserThread::PostTask(
326 base::Bind(&DownloadProtectionServiceTest::QuitMessageLoop
,
327 base::Unretained(this)));
330 void QuitMessageLoop() {
331 base::MessageLoop::current()->Quit();
334 void PostRunMessageLoopTask(BrowserThread::ID thread
) {
335 BrowserThread::PostTask(
338 base::Bind(&DownloadProtectionServiceTest::RunAllPendingAndQuitUI
,
339 base::Unretained(this)));
342 void FlushMessageLoop(BrowserThread::ID thread
) {
343 BrowserThread::PostTask(
346 base::Bind(&DownloadProtectionServiceTest::PostRunMessageLoopTask
,
347 base::Unretained(this), thread
));
348 MessageLoop::current()->Run();
351 void OnClientDownloadRequest(content::DownloadItem
* download
,
352 const ClientDownloadRequest
* request
) {
354 last_client_download_request_
.reset(new ClientDownloadRequest(*request
));
356 last_client_download_request_
.reset();
360 void CheckDoneCallback(
361 DownloadProtectionService::DownloadCheckResult result
) {
364 MessageLoop::current()->Quit();
367 void SyncCheckDoneCallback(
368 DownloadProtectionService::DownloadCheckResult result
) {
373 void SendURLFetchComplete(net::TestURLFetcher
* fetcher
) {
374 fetcher
->delegate()->OnURLFetchComplete(fetcher
);
377 testing::AssertionResult
IsResult(
378 DownloadProtectionService::DownloadCheckResult expected
) {
380 return testing::AssertionFailure() << "No result";
382 return result_
== expected
?
383 testing::AssertionSuccess() :
384 testing::AssertionFailure() << "Expected " << expected
<<
389 scoped_refptr
<FakeSafeBrowsingService
> sb_service_
;
390 scoped_refptr
<MockBinaryFeatureExtractor
> binary_feature_extractor_
;
391 DownloadProtectionService
* download_service_
;
392 DownloadProtectionService::DownloadCheckResult result_
;
394 content::TestBrowserThreadBundle test_browser_thread_bundle_
;
395 content::InProcessUtilityThreadHelper in_process_utility_thread_helper_
;
396 base::FilePath testdata_path_
;
397 #if defined(OS_MACOSX)
398 scoped_ptr
<base::FieldTrialList
> field_trial_list_
;
400 DownloadProtectionService::ClientDownloadRequestSubscription
401 client_download_request_subscription_
;
402 scoped_ptr
<ClientDownloadRequest
> last_client_download_request_
;
405 TEST_F(DownloadProtectionServiceTest
, CheckClientDownloadInvalidUrl
) {
406 base::FilePath
a_tmp(FILE_PATH_LITERAL("a.tmp"));
407 base::FilePath
a_exe(FILE_PATH_LITERAL("a.exe"));
408 std::vector
<GURL
> url_chain
;
409 GURL
referrer("http://www.google.com/");
411 content::MockDownloadItem item
;
412 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp
));
413 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_exe
));
414 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
415 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
416 EXPECT_CALL(item
, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
417 EXPECT_CALL(item
, GetTabReferrerUrl())
418 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
419 download_service_
->CheckClientDownload(
421 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
422 base::Unretained(this)));
423 MessageLoop::current()->Run();
424 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
425 EXPECT_FALSE(HasClientDownloadRequest());
426 Mock::VerifyAndClearExpectations(&item
);
428 url_chain
.push_back(GURL("file://www.google.com/"));
429 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp
));
430 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_exe
));
431 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
432 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
433 EXPECT_CALL(item
, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
434 EXPECT_CALL(item
, GetTabReferrerUrl())
435 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
436 download_service_
->CheckClientDownload(
438 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
439 base::Unretained(this)));
440 MessageLoop::current()->Run();
441 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
442 EXPECT_FALSE(HasClientDownloadRequest());
445 TEST_F(DownloadProtectionServiceTest
, CheckClientDownloadNotABinary
) {
446 base::FilePath
a_tmp(FILE_PATH_LITERAL("a.tmp"));
447 base::FilePath
a_txt(FILE_PATH_LITERAL("a.txt"));
448 std::vector
<GURL
> url_chain
;
449 GURL
referrer("http://www.google.com/");
451 content::MockDownloadItem item
;
452 url_chain
.push_back(GURL("http://www.example.com/foo"));
453 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp
));
454 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_txt
));
455 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
456 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
457 EXPECT_CALL(item
, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
458 EXPECT_CALL(item
, GetTabReferrerUrl())
459 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
460 download_service_
->CheckClientDownload(
462 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
463 base::Unretained(this)));
464 MessageLoop::current()->Run();
465 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
466 EXPECT_FALSE(HasClientDownloadRequest());
469 TEST_F(DownloadProtectionServiceTest
, CheckClientDownloadWhitelistedUrl
) {
470 // Response to any requests will be DANGEROUS.
471 ClientDownloadResponse response
;
472 response
.set_verdict(ClientDownloadResponse::DANGEROUS
);
473 net::FakeURLFetcherFactory
factory(NULL
);
474 factory
.SetFakeResponse(
475 DownloadProtectionService::GetDownloadRequestUrl(),
476 response
.SerializeAsString(),
477 net::HTTP_OK
, net::URLRequestStatus::SUCCESS
);
479 std::string hash
= "hash";
480 base::FilePath
a_tmp(FILE_PATH_LITERAL("a.tmp"));
481 base::FilePath
a_exe(FILE_PATH_LITERAL("a.exe"));
482 std::vector
<GURL
> url_chain
;
485 content::MockDownloadItem item
;
486 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp
));
487 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_exe
));
488 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
489 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
490 EXPECT_CALL(item
, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
491 EXPECT_CALL(item
, GetTabReferrerUrl())
492 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
493 EXPECT_CALL(item
, GetHash()).WillRepeatedly(ReturnRef(hash
));
494 EXPECT_CALL(item
, GetReceivedBytes()).WillRepeatedly(Return(100));
495 EXPECT_CALL(item
, HasUserGesture()).WillRepeatedly(Return(true));
496 EXPECT_CALL(item
, GetRemoteAddress()).WillRepeatedly(Return(""));
497 EXPECT_CALL(*binary_feature_extractor_
.get(), CheckSignature(a_tmp
, _
))
499 EXPECT_CALL(*binary_feature_extractor_
.get(), ExtractImageHeaders(a_tmp
, _
))
502 // We should not get whilelist checks for other URLs than specified below.
503 EXPECT_CALL(*sb_service_
->mock_database_manager(),
504 MatchDownloadWhitelistUrl(_
)).Times(0);
505 EXPECT_CALL(*sb_service_
->mock_database_manager(),
506 MatchDownloadWhitelistUrl(GURL("http://www.evil.com/bla.exe")))
507 .WillRepeatedly(Return(false));
508 EXPECT_CALL(*sb_service_
->mock_database_manager(),
509 MatchDownloadWhitelistUrl(GURL("http://www.google.com/a.exe")))
510 .WillRepeatedly(Return(true));
512 // With no referrer and just the bad url, should be marked DANGEROUS.
513 url_chain
.push_back(GURL("http://www.evil.com/bla.exe"));
514 download_service_
->CheckClientDownload(
516 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
517 base::Unretained(this)));
518 MessageLoop::current()->Run();
520 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS
));
522 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
525 #if defined(OS_WIN) || defined(OS_MACOSX)
526 // OSX sends pings for evaluation purposes.
527 EXPECT_TRUE(HasClientDownloadRequest());
528 ClearClientDownloadRequest();
530 EXPECT_FALSE(HasClientDownloadRequest());
533 // Check that the referrer is not matched against the whitelist.
534 referrer
= GURL("http://www.google.com/");
535 download_service_
->CheckClientDownload(
537 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
538 base::Unretained(this)));
539 MessageLoop::current()->Run();
541 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS
));
543 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
546 #if defined(OS_WIN) || defined(OS_MACOSX)
547 // OSX sends pings for evaluation purposes.
548 EXPECT_TRUE(HasClientDownloadRequest());
549 ClearClientDownloadRequest();
551 EXPECT_FALSE(HasClientDownloadRequest());
554 // Redirect from a site shouldn't be checked either.
555 url_chain
.insert(url_chain
.begin(), GURL("http://www.google.com/redirect"));
556 download_service_
->CheckClientDownload(
558 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
559 base::Unretained(this)));
560 MessageLoop::current()->Run();
562 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS
));
564 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
567 #if defined(OS_WIN) || defined(OS_MACOSX)
568 // OSX sends pings for evaluation purposes.
569 EXPECT_TRUE(HasClientDownloadRequest());
570 ClearClientDownloadRequest();
572 EXPECT_FALSE(HasClientDownloadRequest());
575 // Only if the final url is whitelisted should it be SAFE.
576 url_chain
.push_back(GURL("http://www.google.com/a.exe"));
577 download_service_
->CheckClientDownload(
579 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
580 base::Unretained(this)));
581 MessageLoop::current()->Run();
582 #if defined(OS_MACOSX)
583 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
585 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE
));
587 // TODO(grt): Make the service produce the request even when the URL is
589 EXPECT_FALSE(HasClientDownloadRequest());
592 TEST_F(DownloadProtectionServiceTest
, CheckClientDownloadFetchFailed
) {
593 net::FakeURLFetcherFactory
factory(NULL
);
594 // HTTP request will fail.
595 factory
.SetFakeResponse(
596 DownloadProtectionService::GetDownloadRequestUrl(), std::string(),
597 net::HTTP_INTERNAL_SERVER_ERROR
, net::URLRequestStatus::FAILED
);
599 base::FilePath
a_tmp(FILE_PATH_LITERAL("a.tmp"));
600 base::FilePath
a_exe(FILE_PATH_LITERAL("a.exe"));
601 std::vector
<GURL
> url_chain
;
602 url_chain
.push_back(GURL("http://www.evil.com/a.exe"));
603 GURL
referrer("http://www.google.com/");
604 std::string hash
= "hash";
606 content::MockDownloadItem item
;
607 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp
));
608 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_exe
));
609 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
610 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
611 EXPECT_CALL(item
, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
612 EXPECT_CALL(item
, GetTabReferrerUrl())
613 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
614 EXPECT_CALL(item
, GetHash()).WillRepeatedly(ReturnRef(hash
));
615 EXPECT_CALL(item
, GetReceivedBytes()).WillRepeatedly(Return(100));
616 EXPECT_CALL(item
, HasUserGesture()).WillRepeatedly(Return(true));
617 EXPECT_CALL(item
, GetRemoteAddress()).WillRepeatedly(Return(""));
619 EXPECT_CALL(*sb_service_
->mock_database_manager(),
620 MatchDownloadWhitelistUrl(_
))
621 .WillRepeatedly(Return(false));
622 EXPECT_CALL(*binary_feature_extractor_
.get(), CheckSignature(a_tmp
, _
));
623 EXPECT_CALL(*binary_feature_extractor_
.get(), ExtractImageHeaders(a_tmp
, _
));
625 download_service_
->CheckClientDownload(
627 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
628 base::Unretained(this)));
629 MessageLoop::current()->Run();
630 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
633 TEST_F(DownloadProtectionServiceTest
, CheckClientDownloadSuccess
) {
634 ClientDownloadResponse response
;
635 response
.set_verdict(ClientDownloadResponse::SAFE
);
636 net::FakeURLFetcherFactory
factory(NULL
);
637 // Empty response means SAFE.
638 factory
.SetFakeResponse(
639 DownloadProtectionService::GetDownloadRequestUrl(),
640 response
.SerializeAsString(),
641 net::HTTP_OK
, net::URLRequestStatus::SUCCESS
);
643 base::FilePath
a_tmp(FILE_PATH_LITERAL("a.tmp"));
644 base::FilePath
a_exe(FILE_PATH_LITERAL("a.exe"));
645 std::vector
<GURL
> url_chain
;
646 url_chain
.push_back(GURL("http://www.evil.com/a.exe"));
647 GURL
referrer("http://www.google.com/");
648 std::string hash
= "hash";
650 content::MockDownloadItem item
;
651 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp
));
652 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_exe
));
653 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
654 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
655 EXPECT_CALL(item
, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
656 EXPECT_CALL(item
, GetTabReferrerUrl())
657 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
658 EXPECT_CALL(item
, GetHash()).WillRepeatedly(ReturnRef(hash
));
659 EXPECT_CALL(item
, GetReceivedBytes()).WillRepeatedly(Return(100));
660 EXPECT_CALL(item
, HasUserGesture()).WillRepeatedly(Return(true));
661 EXPECT_CALL(item
, GetRemoteAddress()).WillRepeatedly(Return(""));
663 EXPECT_CALL(*sb_service_
->mock_database_manager(),
664 MatchDownloadWhitelistUrl(_
))
665 .WillRepeatedly(Return(false));
666 EXPECT_CALL(*binary_feature_extractor_
.get(), CheckSignature(a_tmp
, _
))
668 EXPECT_CALL(*binary_feature_extractor_
.get(), ExtractImageHeaders(a_tmp
, _
))
671 download_service_
->CheckClientDownload(
673 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
674 base::Unretained(this)));
675 MessageLoop::current()->Run();
677 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE
));
679 // On !OS_WIN, no file types are currently supported. Hence all requests to
680 // CheckClientDownload() result in a verdict of UNKNOWN.
681 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
684 #if defined(OS_WIN) || defined(OS_MACOSX)
685 // OSX sends pings for evaluation purposes.
686 EXPECT_TRUE(HasClientDownloadRequest());
687 ClearClientDownloadRequest();
689 EXPECT_FALSE(HasClientDownloadRequest());
692 // Invalid response should result in UNKNOWN.
694 factory
.SetFakeResponse(
695 DownloadProtectionService::GetDownloadRequestUrl(),
696 response
.SerializePartialAsString(),
697 net::HTTP_OK
, net::URLRequestStatus::SUCCESS
);
699 download_service_
->CheckClientDownload(
701 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
702 base::Unretained(this)));
703 MessageLoop::current()->Run();
704 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
705 #if defined(OS_WIN) || defined(OS_MACOSX)
706 EXPECT_TRUE(HasClientDownloadRequest());
707 ClearClientDownloadRequest();
709 EXPECT_FALSE(HasClientDownloadRequest());
711 std::string feedback_ping
;
712 std::string feedback_response
;
713 EXPECT_FALSE(DownloadFeedbackService::GetPingsForDownloadForTesting(
714 item
, &feedback_ping
, &feedback_response
));
716 // If the response is dangerous the result should also be marked as dangerous.
717 response
.set_verdict(ClientDownloadResponse::DANGEROUS
);
718 factory
.SetFakeResponse(
719 DownloadProtectionService::GetDownloadRequestUrl(),
720 response
.SerializeAsString(),
721 net::HTTP_OK
, net::URLRequestStatus::SUCCESS
);
723 download_service_
->CheckClientDownload(
725 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
726 base::Unretained(this)));
727 MessageLoop::current()->Run();
728 EXPECT_FALSE(DownloadFeedbackService::GetPingsForDownloadForTesting(
729 item
, &feedback_ping
, &feedback_response
));
731 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS
));
733 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
736 #if defined(OS_WIN) || defined(OS_MACOSX)
737 // OSX sends pings for evaluation purposes.
738 EXPECT_TRUE(HasClientDownloadRequest());
739 ClearClientDownloadRequest();
741 EXPECT_FALSE(HasClientDownloadRequest());
744 // If the response is uncommon the result should also be marked as uncommon.
745 response
.set_verdict(ClientDownloadResponse::UNCOMMON
);
746 factory
.SetFakeResponse(
747 DownloadProtectionService::GetDownloadRequestUrl(),
748 response
.SerializeAsString(),
749 net::HTTP_OK
, net::URLRequestStatus::SUCCESS
);
751 download_service_
->CheckClientDownload(
753 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
754 base::Unretained(this)));
755 MessageLoop::current()->Run();
757 EXPECT_TRUE(IsResult(DownloadProtectionService::UNCOMMON
));
758 EXPECT_TRUE(DownloadFeedbackService::GetPingsForDownloadForTesting(
759 item
, &feedback_ping
, &feedback_response
));
760 ClientDownloadRequest decoded_request
;
761 EXPECT_TRUE(decoded_request
.ParseFromString(feedback_ping
));
762 EXPECT_EQ(url_chain
.back().spec(), decoded_request
.url());
763 EXPECT_EQ(response
.SerializeAsString(), feedback_response
);
764 EXPECT_TRUE(HasClientDownloadRequest());
765 ClearClientDownloadRequest();
767 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
770 // If the response is dangerous_host the result should also be marked as
772 response
.set_verdict(ClientDownloadResponse::DANGEROUS_HOST
);
773 factory
.SetFakeResponse(
774 DownloadProtectionService::GetDownloadRequestUrl(),
775 response
.SerializeAsString(),
776 net::HTTP_OK
, net::URLRequestStatus::SUCCESS
);
778 download_service_
->CheckClientDownload(
780 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
781 base::Unretained(this)));
782 MessageLoop::current()->Run();
784 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS_HOST
));
785 EXPECT_TRUE(DownloadFeedbackService::GetPingsForDownloadForTesting(
786 item
, &feedback_ping
, &feedback_response
));
787 EXPECT_EQ(response
.SerializeAsString(), feedback_response
);
788 EXPECT_TRUE(HasClientDownloadRequest());
789 ClearClientDownloadRequest();
791 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
794 // If the response is POTENTIALLY_UNWANTED the result should also be marked as
795 // POTENTIALLY_UNWANTED.
796 response
.set_verdict(ClientDownloadResponse::POTENTIALLY_UNWANTED
);
797 factory
.SetFakeResponse(
798 DownloadProtectionService::GetDownloadRequestUrl(),
799 response
.SerializeAsString(),
800 net::HTTP_OK
, net::URLRequestStatus::SUCCESS
);
802 download_service_
->CheckClientDownload(
804 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
805 base::Unretained(this)));
806 MessageLoop::current()->Run();
808 EXPECT_TRUE(IsResult(DownloadProtectionService::POTENTIALLY_UNWANTED
));
810 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
813 #if defined(OS_WIN) || defined(OS_MACOSX)
814 // OSX sends pings for evaluation purposes.
815 EXPECT_TRUE(HasClientDownloadRequest());
816 ClearClientDownloadRequest();
818 EXPECT_FALSE(HasClientDownloadRequest());
822 TEST_F(DownloadProtectionServiceTest
, CheckClientDownloadHTTPS
) {
823 ClientDownloadResponse response
;
824 response
.set_verdict(ClientDownloadResponse::DANGEROUS
);
825 net::FakeURLFetcherFactory
factory(NULL
);
826 factory
.SetFakeResponse(
827 DownloadProtectionService::GetDownloadRequestUrl(),
828 response
.SerializeAsString(),
829 net::HTTP_OK
, net::URLRequestStatus::SUCCESS
);
831 base::FilePath
a_tmp(FILE_PATH_LITERAL("a.tmp"));
832 base::FilePath
a_exe(FILE_PATH_LITERAL("a.exe"));
833 std::vector
<GURL
> url_chain
;
834 url_chain
.push_back(GURL("http://www.evil.com/a.exe"));
835 GURL
referrer("http://www.google.com/");
836 std::string hash
= "hash";
838 content::MockDownloadItem item
;
839 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp
));
840 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_exe
));
841 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
842 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
843 EXPECT_CALL(item
, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
844 EXPECT_CALL(item
, GetTabReferrerUrl())
845 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
846 EXPECT_CALL(item
, GetHash()).WillRepeatedly(ReturnRef(hash
));
847 EXPECT_CALL(item
, GetReceivedBytes()).WillRepeatedly(Return(100));
848 EXPECT_CALL(item
, HasUserGesture()).WillRepeatedly(Return(true));
849 EXPECT_CALL(item
, GetRemoteAddress()).WillRepeatedly(Return(""));
851 EXPECT_CALL(*sb_service_
->mock_database_manager(),
852 MatchDownloadWhitelistUrl(_
))
853 .WillRepeatedly(Return(false));
854 EXPECT_CALL(*binary_feature_extractor_
.get(), CheckSignature(a_tmp
, _
))
856 EXPECT_CALL(*binary_feature_extractor_
.get(), ExtractImageHeaders(a_tmp
, _
))
859 download_service_
->CheckClientDownload(
861 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
862 base::Unretained(this)));
863 MessageLoop::current()->Run();
865 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS
));
867 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
870 #if defined(OS_WIN) || defined(OS_MACOSX)
871 // OSX sends pings for evaluation purposes.
872 EXPECT_TRUE(HasClientDownloadRequest());
873 ClearClientDownloadRequest();
875 EXPECT_FALSE(HasClientDownloadRequest());
879 TEST_F(DownloadProtectionServiceTest
, CheckClientDownloadBlob
) {
880 ClientDownloadResponse response
;
881 response
.set_verdict(ClientDownloadResponse::DANGEROUS
);
882 net::FakeURLFetcherFactory
factory(NULL
);
883 factory
.SetFakeResponse(DownloadProtectionService::GetDownloadRequestUrl(),
884 response
.SerializeAsString(), net::HTTP_OK
,
885 net::URLRequestStatus::SUCCESS
);
887 base::FilePath
a_tmp(FILE_PATH_LITERAL("a.tmp"));
888 base::FilePath
a_exe(FILE_PATH_LITERAL("a.exe"));
889 std::vector
<GURL
> url_chain
;
891 GURL("blob:http://www.evil.com/50b85f60-71e4-11e4-82f8-0800200c9a66"));
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_exe
));
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 EXPECT_CALL(*sb_service_
->mock_database_manager(),
909 MatchDownloadWhitelistUrl(_
)).WillRepeatedly(Return(false));
910 EXPECT_CALL(*binary_feature_extractor_
.get(), CheckSignature(a_tmp
, _
))
912 EXPECT_CALL(*binary_feature_extractor_
.get(), ExtractImageHeaders(a_tmp
, _
))
915 download_service_
->CheckClientDownload(
917 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
918 base::Unretained(this)));
919 MessageLoop::current()->Run();
921 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS
));
923 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
926 #if defined(OS_WIN) || defined(OS_MACOSX)
927 // OSX sends pings for evaluation purposes.
928 EXPECT_TRUE(HasClientDownloadRequest());
929 ClearClientDownloadRequest();
931 EXPECT_FALSE(HasClientDownloadRequest());
935 TEST_F(DownloadProtectionServiceTest
, CheckClientDownloadData
) {
936 ClientDownloadResponse response
;
937 response
.set_verdict(ClientDownloadResponse::DANGEROUS
);
938 net::FakeURLFetcherFactory
factory(NULL
);
939 factory
.SetFakeResponse(DownloadProtectionService::GetDownloadRequestUrl(),
940 response
.SerializeAsString(), net::HTTP_OK
,
941 net::URLRequestStatus::SUCCESS
);
943 base::FilePath
a_tmp(FILE_PATH_LITERAL("a.tmp"));
944 base::FilePath
a_exe(FILE_PATH_LITERAL("a.exe"));
945 std::vector
<GURL
> url_chain
;
947 GURL("data:text/html:base64,"));
949 GURL("data:text/html:base64,blahblahblah"));
951 GURL("data:application/octet-stream:base64,blahblah"));
952 GURL
referrer("data:text/html:base64,foobar");
953 std::string hash
= "hash";
955 content::MockDownloadItem item
;
956 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp
));
957 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_exe
));
958 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
959 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
960 EXPECT_CALL(item
, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
961 EXPECT_CALL(item
, GetTabReferrerUrl())
962 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
963 EXPECT_CALL(item
, GetHash()).WillRepeatedly(ReturnRef(hash
));
964 EXPECT_CALL(item
, GetReceivedBytes()).WillRepeatedly(Return(100));
965 EXPECT_CALL(item
, HasUserGesture()).WillRepeatedly(Return(true));
966 EXPECT_CALL(item
, GetRemoteAddress()).WillRepeatedly(Return(""));
968 EXPECT_CALL(*sb_service_
->mock_database_manager(),
969 MatchDownloadWhitelistUrl(_
)).WillRepeatedly(Return(false));
970 EXPECT_CALL(*binary_feature_extractor_
.get(), CheckSignature(a_tmp
, _
))
972 EXPECT_CALL(*binary_feature_extractor_
.get(), ExtractImageHeaders(a_tmp
, _
))
975 download_service_
->CheckClientDownload(
977 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
978 base::Unretained(this)));
979 MessageLoop::current()->Run();
981 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS
));
983 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
986 #if defined(OS_WIN) || defined(OS_MACOSX)
987 // OSX sends pings for evaluation purposes.
988 ASSERT_TRUE(HasClientDownloadRequest());
989 const ClientDownloadRequest
& request
= *GetClientDownloadRequest();
990 const char kExpectedUrl
[] =
991 "data:application/octet-stream:base64,"
992 "ACBF6DFC6F907662F566CA0241DFE8690C48661F440BA1BBD0B86C582845CCC8";
993 const char kExpectedRedirect1
[] = "data:text/html:base64,";
994 const char kExpectedRedirect2
[] =
995 "data:text/html:base64,"
996 "620680767E15717A57DB11D94D1BEBD32B3344EBC5994DF4FB07B0D473F4EF6B";
997 const char kExpectedReferrer
[] =
998 "data:text/html:base64,"
999 "06E2C655B9F7130B508FFF86FD19B57E6BF1A1CFEFD6EFE1C3EB09FE24EF456A";
1000 EXPECT_EQ(hash
, request
.digests().sha256());
1001 EXPECT_EQ(kExpectedUrl
, request
.url());
1002 EXPECT_EQ(3, request
.resources_size());
1003 EXPECT_TRUE(RequestContainsResource(request
,
1004 ClientDownloadRequest::DOWNLOAD_REDIRECT
,
1005 kExpectedRedirect1
, ""));
1006 EXPECT_TRUE(RequestContainsResource(request
,
1007 ClientDownloadRequest::DOWNLOAD_REDIRECT
,
1008 kExpectedRedirect2
, ""));
1009 EXPECT_TRUE(RequestContainsResource(request
,
1010 ClientDownloadRequest::DOWNLOAD_URL
,
1011 kExpectedUrl
, kExpectedReferrer
));
1012 ClearClientDownloadRequest();
1014 EXPECT_FALSE(HasClientDownloadRequest());
1018 TEST_F(DownloadProtectionServiceTest
, CheckClientDownloadZip
) {
1019 ClientDownloadResponse response
;
1020 response
.set_verdict(ClientDownloadResponse::SAFE
);
1021 net::FakeURLFetcherFactory
factory(NULL
);
1022 // Empty response means SAFE.
1023 factory
.SetFakeResponse(
1024 DownloadProtectionService::GetDownloadRequestUrl(),
1025 response
.SerializeAsString(),
1026 net::HTTP_OK
, net::URLRequestStatus::SUCCESS
);
1028 base::ScopedTempDir download_dir
;
1029 ASSERT_TRUE(download_dir
.CreateUniqueTempDir());
1031 base::FilePath
a_tmp(download_dir
.path().Append(FILE_PATH_LITERAL("a.tmp")));
1032 base::FilePath
a_zip(FILE_PATH_LITERAL("a.zip"));
1033 std::vector
<GURL
> url_chain
;
1034 url_chain
.push_back(GURL("http://www.evil.com/a.zip"));
1035 GURL
referrer("http://www.google.com/");
1036 std::string hash
= "hash";
1038 content::MockDownloadItem item
;
1039 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp
));
1040 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_zip
));
1041 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
1042 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
1043 EXPECT_CALL(item
, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
1044 EXPECT_CALL(item
, GetTabReferrerUrl())
1045 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
1046 EXPECT_CALL(item
, GetHash()).WillRepeatedly(ReturnRef(hash
));
1047 EXPECT_CALL(item
, GetReceivedBytes()).WillRepeatedly(Return(100));
1048 EXPECT_CALL(item
, HasUserGesture()).WillRepeatedly(Return(true));
1049 EXPECT_CALL(item
, GetRemoteAddress()).WillRepeatedly(Return(""));
1051 // Write out a zip archive to the temporary file. In this case, it
1052 // only contains a text file.
1053 base::ScopedTempDir zip_source_dir
;
1054 ASSERT_TRUE(zip_source_dir
.CreateUniqueTempDir());
1055 std::string file_contents
= "dummy file";
1056 ASSERT_EQ(static_cast<int>(file_contents
.size()), base::WriteFile(
1057 zip_source_dir
.path().Append(FILE_PATH_LITERAL("file.txt")),
1058 file_contents
.data(), file_contents
.size()));
1059 ASSERT_TRUE(zip::Zip(zip_source_dir
.path(), a_tmp
, false));
1061 download_service_
->CheckClientDownload(
1063 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
1064 base::Unretained(this)));
1065 MessageLoop::current()->Run();
1066 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
1067 EXPECT_FALSE(HasClientDownloadRequest());
1068 Mock::VerifyAndClearExpectations(sb_service_
.get());
1069 Mock::VerifyAndClearExpectations(binary_feature_extractor_
.get());
1071 // Now check with an executable in the zip file as well.
1072 ASSERT_EQ(static_cast<int>(file_contents
.size()), base::WriteFile(
1073 zip_source_dir
.path().Append(FILE_PATH_LITERAL("file.exe")),
1074 file_contents
.data(), file_contents
.size()));
1075 ASSERT_TRUE(zip::Zip(zip_source_dir
.path(), a_tmp
, false));
1077 EXPECT_CALL(*sb_service_
->mock_database_manager(),
1078 MatchDownloadWhitelistUrl(_
))
1079 .WillRepeatedly(Return(false));
1081 download_service_
->CheckClientDownload(
1083 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
1084 base::Unretained(this)));
1085 MessageLoop::current()->Run();
1087 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE
));
1089 // For !OS_WIN, no file types are currently supported. Hence the resulting
1090 // verdict is UNKNOWN.
1091 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
1094 #if defined(OS_WIN) || defined(OS_MACOSX)
1095 // OSX sends pings for evaluation purposes.
1096 EXPECT_TRUE(HasClientDownloadRequest());
1097 ClearClientDownloadRequest();
1099 EXPECT_FALSE(HasClientDownloadRequest());
1101 Mock::VerifyAndClearExpectations(binary_feature_extractor_
.get());
1103 // If the response is dangerous the result should also be marked as
1105 response
.set_verdict(ClientDownloadResponse::DANGEROUS
);
1106 factory
.SetFakeResponse(
1107 DownloadProtectionService::GetDownloadRequestUrl(),
1108 response
.SerializeAsString(),
1109 net::HTTP_OK
, net::URLRequestStatus::SUCCESS
);
1111 download_service_
->CheckClientDownload(
1113 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
1114 base::Unretained(this)));
1115 MessageLoop::current()->Run();
1117 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS
));
1119 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
1122 #if defined(OS_WIN) || defined(OS_MACOSX)
1123 // OSX sends pings for evaluation purposes.
1124 EXPECT_TRUE(HasClientDownloadRequest());
1125 ClearClientDownloadRequest();
1127 EXPECT_FALSE(HasClientDownloadRequest());
1129 Mock::VerifyAndClearExpectations(binary_feature_extractor_
.get());
1132 TEST_F(DownloadProtectionServiceTest
, CheckClientDownloadCorruptZip
) {
1133 base::ScopedTempDir download_dir
;
1134 ASSERT_TRUE(download_dir
.CreateUniqueTempDir());
1136 base::FilePath
a_tmp(download_dir
.path().Append(FILE_PATH_LITERAL("a.tmp")));
1137 base::FilePath
a_zip(FILE_PATH_LITERAL("a.zip"));
1138 std::vector
<GURL
> url_chain
;
1139 url_chain
.push_back(GURL("http://www.evil.com/a.zip"));
1140 GURL
referrer("http://www.google.com/");
1141 std::string hash
= "hash";
1143 content::MockDownloadItem item
;
1144 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp
));
1145 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_zip
));
1146 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
1147 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
1148 EXPECT_CALL(item
, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
1149 EXPECT_CALL(item
, GetTabReferrerUrl())
1150 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
1151 EXPECT_CALL(item
, GetHash()).WillRepeatedly(ReturnRef(hash
));
1152 EXPECT_CALL(item
, GetReceivedBytes()).WillRepeatedly(Return(100));
1153 EXPECT_CALL(item
, HasUserGesture()).WillRepeatedly(Return(true));
1154 EXPECT_CALL(item
, GetRemoteAddress()).WillRepeatedly(Return(""));
1156 std::string file_contents
= "corrupt zip file";
1157 ASSERT_EQ(static_cast<int>(file_contents
.size()), base::WriteFile(
1158 a_tmp
, file_contents
.data(), file_contents
.size()));
1160 download_service_
->CheckClientDownload(
1162 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
1163 base::Unretained(this)));
1164 MessageLoop::current()->Run();
1165 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
1166 EXPECT_FALSE(HasClientDownloadRequest());
1167 Mock::VerifyAndClearExpectations(sb_service_
.get());
1168 Mock::VerifyAndClearExpectations(binary_feature_extractor_
.get());
1171 TEST_F(DownloadProtectionServiceTest
, CheckClientCrxDownloadSuccess
) {
1172 ClientDownloadResponse response
;
1173 // Even if the server verdict is dangerous we should return SAFE because
1174 // DownloadProtectionService::IsSupportedDownload() will return false
1175 // for crx downloads.
1176 response
.set_verdict(ClientDownloadResponse::DANGEROUS
);
1177 net::FakeURLFetcherFactory
factory(NULL
);
1178 // Empty response means SAFE.
1179 factory
.SetFakeResponse(
1180 DownloadProtectionService::GetDownloadRequestUrl(),
1181 response
.SerializeAsString(),
1182 net::HTTP_OK
, net::URLRequestStatus::SUCCESS
);
1184 base::FilePath
a_tmp(FILE_PATH_LITERAL("a.tmp"));
1185 base::FilePath
a_crx(FILE_PATH_LITERAL("a.crx"));
1186 std::vector
<GURL
> url_chain
;
1187 url_chain
.push_back(GURL("http://www.evil.com/a.crx"));
1188 GURL
referrer("http://www.google.com/");
1189 std::string hash
= "hash";
1191 content::MockDownloadItem item
;
1192 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp
));
1193 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_crx
));
1194 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
1195 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
1196 EXPECT_CALL(item
, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
1197 EXPECT_CALL(item
, GetTabReferrerUrl())
1198 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
1199 EXPECT_CALL(item
, GetHash()).WillRepeatedly(ReturnRef(hash
));
1200 EXPECT_CALL(item
, GetReceivedBytes()).WillRepeatedly(Return(100));
1201 EXPECT_CALL(item
, HasUserGesture()).WillRepeatedly(Return(true));
1202 EXPECT_CALL(item
, GetRemoteAddress()).WillRepeatedly(Return(""));
1204 EXPECT_CALL(*sb_service_
->mock_database_manager(),
1205 MatchDownloadWhitelistUrl(_
))
1206 .WillRepeatedly(Return(false));
1207 EXPECT_CALL(*binary_feature_extractor_
.get(), CheckSignature(a_tmp
, _
))
1209 EXPECT_CALL(*binary_feature_extractor_
.get(), ExtractImageHeaders(a_tmp
, _
))
1212 EXPECT_FALSE(download_service_
->IsSupportedDownload(item
, a_crx
));
1213 download_service_
->CheckClientDownload(
1215 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
1216 base::Unretained(this)));
1217 MessageLoop::current()->Run();
1218 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
1221 #if defined(OS_MACOSX)
1222 // TODO(mattm): remove this (see crbug.com/414834).
1223 TEST_F(DownloadProtectionServiceTest
,
1224 CheckClientDownloadPingOnOSXRequiresFieldTrial
) {
1225 // Clear the field trial that was set in SetUp().
1226 field_trial_list_
.reset();
1228 net::TestURLFetcherFactory factory
;
1230 base::FilePath
tmp_path(FILE_PATH_LITERAL("bla.tmp"));
1231 base::FilePath
final_path(FILE_PATH_LITERAL("bla.exe"));
1232 std::vector
<GURL
> url_chain
;
1233 url_chain
.push_back(GURL("http://www.google.com/"));
1234 url_chain
.push_back(GURL("http://www.google.com/bla.exe"));
1235 GURL
referrer("http://www.google.com/");
1236 std::string hash
= "hash";
1237 std::string remote_address
= "10.11.12.13";
1239 content::MockDownloadItem item
;
1240 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(tmp_path
));
1241 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(final_path
));
1242 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
1243 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
1244 EXPECT_CALL(item
, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
1245 EXPECT_CALL(item
, GetTabReferrerUrl())
1246 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
1247 EXPECT_CALL(item
, GetHash()).WillRepeatedly(ReturnRef(hash
));
1248 EXPECT_CALL(item
, GetReceivedBytes()).WillRepeatedly(Return(100));
1249 EXPECT_CALL(item
, HasUserGesture()).WillRepeatedly(Return(true));
1250 EXPECT_CALL(item
, GetRemoteAddress()).WillRepeatedly(Return(remote_address
));
1252 EXPECT_CALL(*sb_service_
->mock_database_manager(),
1253 MatchDownloadWhitelistUrl(_
))
1254 .WillRepeatedly(Return(false));
1255 EXPECT_CALL(*binary_feature_extractor_
.get(), CheckSignature(tmp_path
, _
))
1256 .WillOnce(SetCertificateContents("dummy cert data"));
1257 EXPECT_CALL(*binary_feature_extractor_
.get(),
1258 ExtractImageHeaders(tmp_path
, _
))
1259 .WillOnce(SetDosHeaderContents("dummy dos header"));
1260 download_service_
->CheckClientDownload(
1262 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
1263 base::Unretained(this)));
1265 // SendRequest is not called. Wait for FinishRequest to call our callback.
1266 MessageLoop::current()->Run();
1267 net::TestURLFetcher
* fetcher
= factory
.GetFetcherByID(0);
1268 EXPECT_EQ(NULL
, fetcher
);
1269 EXPECT_FALSE(HasClientDownloadRequest());
1273 TEST_F(DownloadProtectionServiceTest
, CheckClientDownloadValidateRequest
) {
1274 net::TestURLFetcherFactory factory
;
1276 base::FilePath
tmp_path(FILE_PATH_LITERAL("bla.tmp"));
1277 base::FilePath
final_path(FILE_PATH_LITERAL("bla.exe"));
1278 std::vector
<GURL
> url_chain
;
1279 url_chain
.push_back(GURL("http://www.google.com/"));
1280 url_chain
.push_back(GURL("http://www.google.com/bla.exe"));
1281 GURL
referrer("http://www.google.com/");
1282 std::string hash
= "hash";
1283 std::string remote_address
= "10.11.12.13";
1285 content::MockDownloadItem item
;
1286 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(tmp_path
));
1287 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(final_path
));
1288 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
1289 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
1290 EXPECT_CALL(item
, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
1291 EXPECT_CALL(item
, GetTabReferrerUrl())
1292 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
1293 EXPECT_CALL(item
, GetHash()).WillRepeatedly(ReturnRef(hash
));
1294 EXPECT_CALL(item
, GetReceivedBytes()).WillRepeatedly(Return(100));
1295 EXPECT_CALL(item
, HasUserGesture()).WillRepeatedly(Return(true));
1296 EXPECT_CALL(item
, GetRemoteAddress()).WillRepeatedly(Return(remote_address
));
1298 EXPECT_CALL(*sb_service_
->mock_database_manager(),
1299 MatchDownloadWhitelistUrl(_
))
1300 .WillRepeatedly(Return(false));
1301 EXPECT_CALL(*binary_feature_extractor_
.get(), CheckSignature(tmp_path
, _
))
1302 .WillOnce(SetCertificateContents("dummy cert data"));
1303 EXPECT_CALL(*binary_feature_extractor_
.get(),
1304 ExtractImageHeaders(tmp_path
, _
))
1305 .WillOnce(SetDosHeaderContents("dummy dos header"));
1306 download_service_
->CheckClientDownload(
1308 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
1309 base::Unretained(this)));
1311 #if !defined(OS_WIN) && !defined(OS_MACOSX)
1312 // SendRequest is not called. Wait for FinishRequest to call our callback.
1313 MessageLoop::current()->Run();
1314 net::TestURLFetcher
* fetcher
= factory
.GetFetcherByID(0);
1315 EXPECT_EQ(NULL
, fetcher
);
1316 EXPECT_FALSE(HasClientDownloadRequest());
1318 // Run the message loop(s) until SendRequest is called.
1319 FlushThreadMessageLoops();
1320 EXPECT_TRUE(HasClientDownloadRequest());
1321 ClearClientDownloadRequest();
1322 net::TestURLFetcher
* fetcher
= factory
.GetFetcherByID(0);
1323 ASSERT_TRUE(fetcher
);
1324 ClientDownloadRequest request
;
1325 EXPECT_TRUE(request
.ParseFromString(fetcher
->upload_data()));
1326 EXPECT_EQ("http://www.google.com/bla.exe", request
.url());
1327 EXPECT_EQ(hash
, request
.digests().sha256());
1328 EXPECT_EQ(item
.GetReceivedBytes(), request
.length());
1329 EXPECT_EQ(item
.HasUserGesture(), request
.user_initiated());
1330 EXPECT_TRUE(RequestContainsServerIp(request
, remote_address
));
1331 EXPECT_EQ(2, request
.resources_size());
1332 EXPECT_TRUE(RequestContainsResource(request
,
1333 ClientDownloadRequest::DOWNLOAD_REDIRECT
,
1334 "http://www.google.com/", ""));
1335 EXPECT_TRUE(RequestContainsResource(request
,
1336 ClientDownloadRequest::DOWNLOAD_URL
,
1337 "http://www.google.com/bla.exe",
1339 EXPECT_TRUE(request
.has_signature());
1340 ASSERT_EQ(1, request
.signature().certificate_chain_size());
1341 const ClientDownloadRequest_CertificateChain
& chain
=
1342 request
.signature().certificate_chain(0);
1343 ASSERT_EQ(1, chain
.element_size());
1344 EXPECT_EQ("dummy cert data", chain
.element(0).certificate());
1345 EXPECT_TRUE(request
.has_image_headers());
1346 const ClientDownloadRequest_ImageHeaders
& headers
=
1347 request
.image_headers();
1348 EXPECT_TRUE(headers
.has_pe_headers());
1349 EXPECT_TRUE(headers
.pe_headers().has_dos_header());
1350 EXPECT_EQ("dummy dos header", headers
.pe_headers().dos_header());
1352 // Simulate the request finishing.
1353 base::MessageLoop::current()->PostTask(
1355 base::Bind(&DownloadProtectionServiceTest::SendURLFetchComplete
,
1356 base::Unretained(this), fetcher
));
1357 MessageLoop::current()->Run();
1361 // Similar to above, but with an unsigned binary.
1362 TEST_F(DownloadProtectionServiceTest
,
1363 CheckClientDownloadValidateRequestNoSignature
) {
1364 net::TestURLFetcherFactory factory
;
1366 base::FilePath
tmp_path(FILE_PATH_LITERAL("bla.tmp"));
1367 base::FilePath
final_path(FILE_PATH_LITERAL("bla.exe"));
1368 std::vector
<GURL
> url_chain
;
1369 url_chain
.push_back(GURL("http://www.google.com/"));
1370 url_chain
.push_back(GURL("ftp://www.google.com/bla.exe"));
1371 GURL
referrer("http://www.google.com/");
1372 std::string hash
= "hash";
1373 std::string remote_address
= "10.11.12.13";
1375 content::MockDownloadItem item
;
1376 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(tmp_path
));
1377 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(final_path
));
1378 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
1379 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
1380 EXPECT_CALL(item
, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
1381 EXPECT_CALL(item
, GetTabReferrerUrl())
1382 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
1383 EXPECT_CALL(item
, GetHash()).WillRepeatedly(ReturnRef(hash
));
1384 EXPECT_CALL(item
, GetReceivedBytes()).WillRepeatedly(Return(100));
1385 EXPECT_CALL(item
, HasUserGesture()).WillRepeatedly(Return(true));
1386 EXPECT_CALL(item
, GetRemoteAddress()).WillRepeatedly(Return(remote_address
));
1388 EXPECT_CALL(*sb_service_
->mock_database_manager(),
1389 MatchDownloadWhitelistUrl(_
))
1390 .WillRepeatedly(Return(false));
1391 EXPECT_CALL(*binary_feature_extractor_
.get(), CheckSignature(tmp_path
, _
));
1392 EXPECT_CALL(*binary_feature_extractor_
.get(),
1393 ExtractImageHeaders(tmp_path
, _
));
1394 download_service_
->CheckClientDownload(
1396 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
1397 base::Unretained(this)));
1399 #if !defined(OS_WIN) && !defined(OS_MACOSX)
1400 // SendRequest is not called. Wait for FinishRequest to call our callback.
1401 MessageLoop::current()->Run();
1402 net::TestURLFetcher
* fetcher
= factory
.GetFetcherByID(0);
1403 EXPECT_EQ(NULL
, fetcher
);
1404 EXPECT_FALSE(HasClientDownloadRequest());
1406 // Run the message loop(s) until SendRequest is called.
1407 FlushThreadMessageLoops();
1408 EXPECT_TRUE(HasClientDownloadRequest());
1409 ClearClientDownloadRequest();
1410 net::TestURLFetcher
* fetcher
= factory
.GetFetcherByID(0);
1411 ASSERT_TRUE(fetcher
);
1412 ClientDownloadRequest request
;
1413 EXPECT_TRUE(request
.ParseFromString(fetcher
->upload_data()));
1414 EXPECT_EQ("ftp://www.google.com/bla.exe", request
.url());
1415 EXPECT_EQ(hash
, request
.digests().sha256());
1416 EXPECT_EQ(item
.GetReceivedBytes(), request
.length());
1417 EXPECT_EQ(item
.HasUserGesture(), request
.user_initiated());
1418 EXPECT_EQ(2, request
.resources_size());
1419 EXPECT_TRUE(RequestContainsResource(request
,
1420 ClientDownloadRequest::DOWNLOAD_REDIRECT
,
1421 "http://www.google.com/", ""));
1422 EXPECT_TRUE(RequestContainsResource(request
,
1423 ClientDownloadRequest::DOWNLOAD_URL
,
1424 "ftp://www.google.com/bla.exe",
1426 EXPECT_TRUE(request
.has_signature());
1427 EXPECT_EQ(0, request
.signature().certificate_chain_size());
1429 // Simulate the request finishing.
1430 base::MessageLoop::current()->PostTask(
1432 base::Bind(&DownloadProtectionServiceTest::SendURLFetchComplete
,
1433 base::Unretained(this), fetcher
));
1434 MessageLoop::current()->Run();
1438 // Similar to above, but with tab history.
1439 TEST_F(DownloadProtectionServiceTest
,
1440 CheckClientDownloadValidateRequestTabHistory
) {
1441 net::TestURLFetcherFactory factory
;
1443 base::ScopedTempDir profile_dir
;
1444 ASSERT_TRUE(profile_dir
.CreateUniqueTempDir());
1445 TestingProfile
profile(profile_dir
.path());
1447 profile
.CreateHistoryService(true /* delete_file */, false /* no_db */));
1449 base::FilePath
tmp_path(FILE_PATH_LITERAL("bla.tmp"));
1450 base::FilePath
final_path(FILE_PATH_LITERAL("bla.exe"));
1451 std::vector
<GURL
> url_chain
;
1452 url_chain
.push_back(GURL("http://www.google.com/"));
1453 url_chain
.push_back(GURL("http://www.google.com/bla.exe"));
1454 GURL
referrer("http://www.google.com/");
1455 GURL
tab_url("http://tab.com/final");
1456 GURL
tab_referrer("http://tab.com/referrer");
1457 std::string hash
= "hash";
1458 std::string remote_address
= "10.11.12.13";
1460 content::MockDownloadItem item
;
1461 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(tmp_path
));
1462 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(final_path
));
1463 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
1464 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
1465 EXPECT_CALL(item
, GetTabUrl()).WillRepeatedly(ReturnRef(tab_url
));
1466 EXPECT_CALL(item
, GetTabReferrerUrl())
1467 .WillRepeatedly(ReturnRef(tab_referrer
));
1468 EXPECT_CALL(item
, GetHash()).WillRepeatedly(ReturnRef(hash
));
1469 EXPECT_CALL(item
, GetReceivedBytes()).WillRepeatedly(Return(100));
1470 EXPECT_CALL(item
, HasUserGesture()).WillRepeatedly(Return(true));
1471 EXPECT_CALL(item
, GetRemoteAddress()).WillRepeatedly(Return(remote_address
));
1472 EXPECT_CALL(item
, GetBrowserContext()).WillRepeatedly(Return(&profile
));
1473 EXPECT_CALL(*sb_service_
->mock_database_manager(),
1474 MatchDownloadWhitelistUrl(_
))
1475 .WillRepeatedly(Return(false));
1476 EXPECT_CALL(*binary_feature_extractor_
.get(), CheckSignature(tmp_path
, _
))
1477 .WillRepeatedly(SetCertificateContents("dummy cert data"));
1478 EXPECT_CALL(*binary_feature_extractor_
.get(),
1479 ExtractImageHeaders(tmp_path
, _
))
1480 .WillRepeatedly(SetDosHeaderContents("dummy dos header"));
1482 // First test with no history match for the tab URL.
1484 TestURLFetcherWatcher
fetcher_watcher(&factory
);
1485 download_service_
->CheckClientDownload(
1487 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
1488 base::Unretained(this)));
1490 #if !defined(OS_WIN) && !defined(OS_MACOSX)
1491 // SendRequest is not called. Wait for FinishRequest to call our callback.
1492 MessageLoop::current()->Run();
1493 net::TestURLFetcher
* fetcher
= factory
.GetFetcherByID(0);
1494 EXPECT_EQ(NULL
, fetcher
);
1495 EXPECT_FALSE(HasClientDownloadRequest());
1497 EXPECT_EQ(0, fetcher_watcher
.WaitForRequest());
1498 EXPECT_TRUE(HasClientDownloadRequest());
1499 ClearClientDownloadRequest();
1500 net::TestURLFetcher
* fetcher
= factory
.GetFetcherByID(0);
1501 ASSERT_TRUE(fetcher
);
1502 ClientDownloadRequest request
;
1503 EXPECT_TRUE(request
.ParseFromString(fetcher
->upload_data()));
1504 EXPECT_EQ("http://www.google.com/bla.exe", request
.url());
1505 EXPECT_EQ(hash
, request
.digests().sha256());
1506 EXPECT_EQ(item
.GetReceivedBytes(), request
.length());
1507 EXPECT_EQ(item
.HasUserGesture(), request
.user_initiated());
1508 EXPECT_TRUE(RequestContainsServerIp(request
, remote_address
));
1509 EXPECT_EQ(3, request
.resources_size());
1511 RequestContainsResource(request
,
1512 ClientDownloadRequest::DOWNLOAD_REDIRECT
,
1513 "http://www.google.com/",
1515 EXPECT_TRUE(RequestContainsResource(request
,
1516 ClientDownloadRequest::DOWNLOAD_URL
,
1517 "http://www.google.com/bla.exe",
1519 EXPECT_TRUE(RequestContainsResource(request
,
1520 ClientDownloadRequest::TAB_URL
,
1522 tab_referrer
.spec()));
1523 EXPECT_TRUE(request
.has_signature());
1524 ASSERT_EQ(1, request
.signature().certificate_chain_size());
1525 const ClientDownloadRequest_CertificateChain
& chain
=
1526 request
.signature().certificate_chain(0);
1527 ASSERT_EQ(1, chain
.element_size());
1528 EXPECT_EQ("dummy cert data", chain
.element(0).certificate());
1529 EXPECT_TRUE(request
.has_image_headers());
1530 const ClientDownloadRequest_ImageHeaders
& headers
=
1531 request
.image_headers();
1532 EXPECT_TRUE(headers
.has_pe_headers());
1533 EXPECT_TRUE(headers
.pe_headers().has_dos_header());
1534 EXPECT_EQ("dummy dos header", headers
.pe_headers().dos_header());
1536 // Simulate the request finishing.
1537 base::MessageLoop::current()->PostTask(
1539 base::Bind(&DownloadProtectionServiceTest::SendURLFetchComplete
,
1540 base::Unretained(this),
1542 MessageLoop::current()->Run();
1546 // Now try with a history match.
1548 history::RedirectList redirects
;
1549 redirects
.push_back(GURL("http://tab.com/ref1"));
1550 redirects
.push_back(GURL("http://tab.com/ref2"));
1551 redirects
.push_back(tab_url
);
1552 HistoryServiceFactory::GetForProfile(&profile
,
1553 ServiceAccessType::EXPLICIT_ACCESS
)
1556 reinterpret_cast<history::ContextID
>(1),
1560 ui::PAGE_TRANSITION_TYPED
,
1561 history::SOURCE_BROWSED
,
1564 TestURLFetcherWatcher
fetcher_watcher(&factory
);
1565 download_service_
->CheckClientDownload(
1567 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
1568 base::Unretained(this)));
1569 #if !defined(OS_WIN) && !defined(OS_MACOSX)
1570 // SendRequest is not called. Wait for FinishRequest to call our callback.
1571 MessageLoop::current()->Run();
1572 net::TestURLFetcher
* fetcher
= factory
.GetFetcherByID(0);
1573 EXPECT_EQ(NULL
, fetcher
);
1574 EXPECT_FALSE(HasClientDownloadRequest());
1576 EXPECT_EQ(0, fetcher_watcher
.WaitForRequest());
1577 EXPECT_TRUE(HasClientDownloadRequest());
1578 ClearClientDownloadRequest();
1579 net::TestURLFetcher
* fetcher
= factory
.GetFetcherByID(0);
1580 ASSERT_TRUE(fetcher
);
1581 ClientDownloadRequest request
;
1582 EXPECT_TRUE(request
.ParseFromString(fetcher
->upload_data()));
1583 EXPECT_EQ("http://www.google.com/bla.exe", request
.url());
1584 EXPECT_EQ(hash
, request
.digests().sha256());
1585 EXPECT_EQ(item
.GetReceivedBytes(), request
.length());
1586 EXPECT_EQ(item
.HasUserGesture(), request
.user_initiated());
1587 EXPECT_TRUE(RequestContainsServerIp(request
, remote_address
));
1588 EXPECT_EQ(5, request
.resources_size());
1590 RequestContainsResource(request
,
1591 ClientDownloadRequest::DOWNLOAD_REDIRECT
,
1592 "http://www.google.com/",
1594 EXPECT_TRUE(RequestContainsResource(request
,
1595 ClientDownloadRequest::DOWNLOAD_URL
,
1596 "http://www.google.com/bla.exe",
1598 EXPECT_TRUE(RequestContainsResource(request
,
1599 ClientDownloadRequest::TAB_REDIRECT
,
1600 "http://tab.com/ref1",
1602 EXPECT_TRUE(RequestContainsResource(request
,
1603 ClientDownloadRequest::TAB_REDIRECT
,
1604 "http://tab.com/ref2",
1606 EXPECT_TRUE(RequestContainsResource(request
,
1607 ClientDownloadRequest::TAB_URL
,
1609 tab_referrer
.spec()));
1610 EXPECT_TRUE(request
.has_signature());
1611 ASSERT_EQ(1, request
.signature().certificate_chain_size());
1612 const ClientDownloadRequest_CertificateChain
& chain
=
1613 request
.signature().certificate_chain(0);
1614 ASSERT_EQ(1, chain
.element_size());
1615 EXPECT_EQ("dummy cert data", chain
.element(0).certificate());
1617 // Simulate the request finishing.
1618 base::MessageLoop::current()->PostTask(
1620 base::Bind(&DownloadProtectionServiceTest::SendURLFetchComplete
,
1621 base::Unretained(this),
1623 MessageLoop::current()->Run();
1628 TEST_F(DownloadProtectionServiceTest
, TestCheckDownloadUrl
) {
1629 std::vector
<GURL
> url_chain
;
1630 url_chain
.push_back(GURL("http://www.google.com/"));
1631 url_chain
.push_back(GURL("http://www.google.com/bla.exe"));
1632 GURL
referrer("http://www.google.com/");
1633 std::string hash
= "hash";
1635 content::MockDownloadItem item
;
1636 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
1637 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
1638 EXPECT_CALL(item
, GetHash()).WillRepeatedly(ReturnRef(hash
));
1640 // CheckDownloadURL returns immediately which means the client object callback
1641 // will never be called. Nevertheless the callback provided to
1642 // CheckClientDownload must still be called.
1643 EXPECT_CALL(*sb_service_
->mock_database_manager(),
1644 CheckDownloadUrl(ContainerEq(url_chain
), NotNull()))
1645 .WillOnce(Return(true));
1646 download_service_
->CheckDownloadUrl(
1648 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
1649 base::Unretained(this)));
1650 MessageLoop::current()->Run();
1651 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE
));
1652 Mock::VerifyAndClearExpectations(sb_service_
.get());
1654 EXPECT_CALL(*sb_service_
->mock_database_manager(),
1655 CheckDownloadUrl(ContainerEq(url_chain
), NotNull()))
1656 .WillOnce(DoAll(CheckDownloadUrlDone(SB_THREAT_TYPE_SAFE
),
1658 download_service_
->CheckDownloadUrl(
1660 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
1661 base::Unretained(this)));
1662 MessageLoop::current()->Run();
1663 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE
));
1664 Mock::VerifyAndClearExpectations(sb_service_
.get());
1666 EXPECT_CALL(*sb_service_
->mock_database_manager(),
1667 CheckDownloadUrl(ContainerEq(url_chain
), NotNull()))
1669 CheckDownloadUrlDone(SB_THREAT_TYPE_URL_MALWARE
),
1671 download_service_
->CheckDownloadUrl(
1673 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
1674 base::Unretained(this)));
1675 MessageLoop::current()->Run();
1676 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE
));
1677 Mock::VerifyAndClearExpectations(sb_service_
.get());
1679 EXPECT_CALL(*sb_service_
->mock_database_manager(),
1680 CheckDownloadUrl(ContainerEq(url_chain
),
1683 CheckDownloadUrlDone(SB_THREAT_TYPE_BINARY_MALWARE_URL
),
1685 download_service_
->CheckDownloadUrl(
1687 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
1688 base::Unretained(this)));
1689 MessageLoop::current()->Run();
1690 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS
));
1693 TEST_F(DownloadProtectionServiceTest
, TestDownloadRequestTimeout
) {
1694 net::TestURLFetcherFactory factory
;
1696 std::vector
<GURL
> url_chain
;
1697 url_chain
.push_back(GURL("http://www.evil.com/bla.exe"));
1698 GURL
referrer("http://www.google.com/");
1699 base::FilePath
tmp_path(FILE_PATH_LITERAL("a.tmp"));
1700 base::FilePath
final_path(FILE_PATH_LITERAL("a.exe"));
1701 std::string hash
= "hash";
1703 content::MockDownloadItem item
;
1704 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(tmp_path
));
1705 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(final_path
));
1706 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
1707 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
1708 EXPECT_CALL(item
, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
1709 EXPECT_CALL(item
, GetTabReferrerUrl())
1710 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
1711 EXPECT_CALL(item
, GetHash()).WillRepeatedly(ReturnRef(hash
));
1712 EXPECT_CALL(item
, GetReceivedBytes()).WillRepeatedly(Return(100));
1713 EXPECT_CALL(item
, HasUserGesture()).WillRepeatedly(Return(true));
1714 EXPECT_CALL(item
, GetRemoteAddress()).WillRepeatedly(Return(""));
1716 EXPECT_CALL(*sb_service_
->mock_database_manager(),
1717 MatchDownloadWhitelistUrl(_
))
1718 .WillRepeatedly(Return(false));
1719 EXPECT_CALL(*binary_feature_extractor_
.get(), CheckSignature(tmp_path
, _
));
1720 EXPECT_CALL(*binary_feature_extractor_
.get(),
1721 ExtractImageHeaders(tmp_path
, _
));
1723 download_service_
->download_request_timeout_ms_
= 10;
1724 download_service_
->CheckClientDownload(
1726 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
1727 base::Unretained(this)));
1729 // The request should time out because the HTTP request hasn't returned
1731 MessageLoop::current()->Run();
1732 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
1733 #if defined(OS_WIN) || defined(OS_MACOSX)
1734 EXPECT_TRUE(HasClientDownloadRequest());
1735 ClearClientDownloadRequest();
1737 EXPECT_FALSE(HasClientDownloadRequest());
1741 TEST_F(DownloadProtectionServiceTest
, TestDownloadItemDestroyed
) {
1742 net::TestURLFetcherFactory factory
;
1744 std::vector
<GURL
> url_chain
;
1745 url_chain
.push_back(GURL("http://www.evil.com/bla.exe"));
1746 GURL
referrer("http://www.google.com/");
1747 GURL
tab_url("http://www.google.com/tab");
1748 base::FilePath
tmp_path(FILE_PATH_LITERAL("a.tmp"));
1749 base::FilePath
final_path(FILE_PATH_LITERAL("a.exe"));
1750 std::string hash
= "hash";
1753 content::MockDownloadItem item
;
1754 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(tmp_path
));
1755 EXPECT_CALL(item
, GetTargetFilePath())
1756 .WillRepeatedly(ReturnRef(final_path
));
1757 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
1758 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
1759 EXPECT_CALL(item
, GetTabUrl()).WillRepeatedly(ReturnRef(tab_url
));
1760 EXPECT_CALL(item
, GetTabReferrerUrl())
1761 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
1762 EXPECT_CALL(item
, GetHash()).WillRepeatedly(ReturnRef(hash
));
1763 EXPECT_CALL(item
, GetReceivedBytes()).WillRepeatedly(Return(100));
1764 EXPECT_CALL(item
, HasUserGesture()).WillRepeatedly(Return(true));
1765 EXPECT_CALL(item
, GetRemoteAddress()).WillRepeatedly(Return(""));
1767 EXPECT_CALL(*sb_service_
->mock_database_manager(),
1768 MatchDownloadWhitelistUrl(_
))
1769 .WillRepeatedly(Return(false));
1770 EXPECT_CALL(*binary_feature_extractor_
.get(), CheckSignature(tmp_path
, _
));
1771 EXPECT_CALL(*binary_feature_extractor_
.get(),
1772 ExtractImageHeaders(tmp_path
, _
));
1774 download_service_
->CheckClientDownload(
1776 base::Bind(&DownloadProtectionServiceTest::SyncCheckDoneCallback
,
1777 base::Unretained(this)));
1778 // MockDownloadItem going out of scope triggers the OnDownloadDestroyed
1782 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
1783 EXPECT_FALSE(HasClientDownloadRequest());
1786 TEST_F(DownloadProtectionServiceTest
,
1787 TestDownloadItemDestroyedDuringWhitelistCheck
) {
1788 net::TestURLFetcherFactory factory
;
1790 std::vector
<GURL
> url_chain
;
1791 url_chain
.push_back(GURL("http://www.evil.com/bla.exe"));
1792 GURL
referrer("http://www.google.com/");
1793 GURL
tab_url("http://www.google.com/tab");
1794 base::FilePath
tmp_path(FILE_PATH_LITERAL("a.tmp"));
1795 base::FilePath
final_path(FILE_PATH_LITERAL("a.exe"));
1796 std::string hash
= "hash";
1798 scoped_ptr
<content::MockDownloadItem
> item(new content::MockDownloadItem
);
1799 EXPECT_CALL(*item
, GetFullPath()).WillRepeatedly(ReturnRef(tmp_path
));
1800 EXPECT_CALL(*item
, GetTargetFilePath())
1801 .WillRepeatedly(ReturnRef(final_path
));
1802 EXPECT_CALL(*item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
1803 EXPECT_CALL(*item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
1804 EXPECT_CALL(*item
, GetTabUrl()).WillRepeatedly(ReturnRef(tab_url
));
1805 EXPECT_CALL(*item
, GetTabReferrerUrl())
1806 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
1807 EXPECT_CALL(*item
, GetHash()).WillRepeatedly(ReturnRef(hash
));
1808 EXPECT_CALL(*item
, GetReceivedBytes()).WillRepeatedly(Return(100));
1809 EXPECT_CALL(*item
, HasUserGesture()).WillRepeatedly(Return(true));
1810 EXPECT_CALL(*item
, GetRemoteAddress()).WillRepeatedly(Return(""));
1812 EXPECT_CALL(*sb_service_
->mock_database_manager(),
1813 MatchDownloadWhitelistUrl(_
))
1814 .WillRepeatedly(Invoke([&item
](const GURL
&) {
1818 EXPECT_CALL(*binary_feature_extractor_
.get(), CheckSignature(tmp_path
, _
));
1819 EXPECT_CALL(*binary_feature_extractor_
.get(),
1820 ExtractImageHeaders(tmp_path
, _
));
1822 download_service_
->CheckClientDownload(
1824 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
1825 base::Unretained(this)));
1827 MessageLoop::current()->Run();
1828 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
1829 EXPECT_FALSE(HasClientDownloadRequest());
1832 TEST_F(DownloadProtectionServiceTest
, GetCertificateWhitelistStrings
) {
1833 // We'll pass this cert in as the "issuer", even though it isn't really
1834 // used to sign the certs below. GetCertificateWhitelistStirngs doesn't care
1836 scoped_refptr
<net::X509Certificate
> issuer_cert(
1837 ReadTestCertificate("issuer.pem"));
1838 ASSERT_TRUE(issuer_cert
.get());
1839 std::string cert_base
= "cert/" + base::HexEncode(
1840 issuer_cert
->fingerprint().data
,
1841 sizeof(issuer_cert
->fingerprint().data
));
1843 scoped_refptr
<net::X509Certificate
> cert(ReadTestCertificate("test_cn.pem"));
1844 ASSERT_TRUE(cert
.get());
1845 std::vector
<std::string
> whitelist_strings
;
1846 GetCertificateWhitelistStrings(
1847 *cert
.get(), *issuer_cert
.get(), &whitelist_strings
);
1848 // This also tests escaping of characters in the certificate attributes.
1849 EXPECT_THAT(whitelist_strings
, ElementsAre(
1850 cert_base
+ "/CN=subject%2F%251"));
1852 cert
= ReadTestCertificate("test_cn_o.pem");
1853 ASSERT_TRUE(cert
.get());
1854 whitelist_strings
.clear();
1855 GetCertificateWhitelistStrings(
1856 *cert
.get(), *issuer_cert
.get(), &whitelist_strings
);
1857 EXPECT_THAT(whitelist_strings
,
1858 ElementsAre(cert_base
+ "/CN=subject",
1859 cert_base
+ "/CN=subject/O=org",
1860 cert_base
+ "/O=org"));
1862 cert
= ReadTestCertificate("test_cn_o_ou.pem");
1863 ASSERT_TRUE(cert
.get());
1864 whitelist_strings
.clear();
1865 GetCertificateWhitelistStrings(
1866 *cert
.get(), *issuer_cert
.get(), &whitelist_strings
);
1867 EXPECT_THAT(whitelist_strings
,
1868 ElementsAre(cert_base
+ "/CN=subject",
1869 cert_base
+ "/CN=subject/O=org",
1870 cert_base
+ "/CN=subject/O=org/OU=unit",
1871 cert_base
+ "/CN=subject/OU=unit",
1872 cert_base
+ "/O=org",
1873 cert_base
+ "/O=org/OU=unit",
1874 cert_base
+ "/OU=unit"));
1876 cert
= ReadTestCertificate("test_cn_ou.pem");
1877 ASSERT_TRUE(cert
.get());
1878 whitelist_strings
.clear();
1879 GetCertificateWhitelistStrings(
1880 *cert
.get(), *issuer_cert
.get(), &whitelist_strings
);
1881 EXPECT_THAT(whitelist_strings
,
1882 ElementsAre(cert_base
+ "/CN=subject",
1883 cert_base
+ "/CN=subject/OU=unit",
1884 cert_base
+ "/OU=unit"));
1886 cert
= ReadTestCertificate("test_o.pem");
1887 ASSERT_TRUE(cert
.get());
1888 whitelist_strings
.clear();
1889 GetCertificateWhitelistStrings(
1890 *cert
.get(), *issuer_cert
.get(), &whitelist_strings
);
1891 EXPECT_THAT(whitelist_strings
, ElementsAre(cert_base
+ "/O=org"));
1893 cert
= ReadTestCertificate("test_o_ou.pem");
1894 ASSERT_TRUE(cert
.get());
1895 whitelist_strings
.clear();
1896 GetCertificateWhitelistStrings(
1897 *cert
.get(), *issuer_cert
.get(), &whitelist_strings
);
1898 EXPECT_THAT(whitelist_strings
,
1899 ElementsAre(cert_base
+ "/O=org",
1900 cert_base
+ "/O=org/OU=unit",
1901 cert_base
+ "/OU=unit"));
1903 cert
= ReadTestCertificate("test_ou.pem");
1904 ASSERT_TRUE(cert
.get());
1905 whitelist_strings
.clear();
1906 GetCertificateWhitelistStrings(
1907 *cert
.get(), *issuer_cert
.get(), &whitelist_strings
);
1908 EXPECT_THAT(whitelist_strings
, ElementsAre(cert_base
+ "/OU=unit"));
1910 cert
= ReadTestCertificate("test_c.pem");
1911 ASSERT_TRUE(cert
.get());
1912 whitelist_strings
.clear();
1913 GetCertificateWhitelistStrings(
1914 *cert
.get(), *issuer_cert
.get(), &whitelist_strings
);
1915 EXPECT_THAT(whitelist_strings
, ElementsAre());
1917 } // namespace safe_browsing