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_factory.h"
24 #include "chrome/browser/safe_browsing/database_manager.h"
25 #include "chrome/browser/safe_browsing/download_feedback_service.h"
26 #include "chrome/browser/safe_browsing/safe_browsing_service.h"
27 #include "chrome/common/safe_browsing/binary_feature_extractor.h"
28 #include "chrome/common/safe_browsing/csd.pb.h"
29 #include "chrome/test/base/testing_profile.h"
30 #include "components/history/core/browser/history_service.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_METHOD4(ExtractImageFeatures
, bool(
115 const base::FilePath
&,
116 ExtractHeadersOption
,
117 ClientDownloadRequest_ImageHeaders
*,
118 google::protobuf::RepeatedPtrField
<std::string
>*));
121 virtual ~MockBinaryFeatureExtractor() {}
124 DISALLOW_COPY_AND_ASSIGN(MockBinaryFeatureExtractor
);
127 class TestURLFetcherWatcher
: public net::TestURLFetcherDelegateForTests
{
129 explicit TestURLFetcherWatcher(net::TestURLFetcherFactory
* factory
)
130 : factory_(factory
), fetcher_id_(-1) {
131 factory_
->SetDelegateForTests(this);
133 ~TestURLFetcherWatcher() {
134 factory_
->SetDelegateForTests(NULL
);
137 // TestURLFetcherDelegateForTests impl:
138 void OnRequestStart(int fetcher_id
) override
{
139 fetcher_id_
= fetcher_id
;
142 void OnChunkUpload(int fetcher_id
) override
{}
143 void OnRequestEnd(int fetcher_id
) override
{}
145 int WaitForRequest() {
151 net::TestURLFetcherFactory
* factory_
;
153 base::RunLoop run_loop_
;
157 ACTION_P(SetCertificateContents
, contents
) {
158 arg1
->add_certificate_chain()->add_element()->set_certificate(contents
);
161 ACTION_P(SetDosHeaderContents
, contents
) {
162 arg2
->mutable_pe_headers()->set_dos_header(contents
);
166 ACTION_P(TrustSignature
, certificate_file
) {
167 arg1
->set_trusted(true);
168 // Add a certificate chain. Note that we add the certificate twice so that
169 // it appears as its own issuer.
170 std::string cert_data
;
171 ASSERT_TRUE(base::ReadFileToString(certificate_file
, &cert_data
));
172 ClientDownloadRequest_CertificateChain
* chain
=
173 arg1
->add_certificate_chain();
174 chain
->add_element()->set_certificate(cert_data
);
175 chain
->add_element()->set_certificate(cert_data
);
178 // We can't call OnSafeBrowsingResult directly because SafeBrowsingCheck does
179 // not have any copy constructor which means it can't be stored in a callback
180 // easily. Note: check will be deleted automatically when the callback is
182 void OnSafeBrowsingResult(
183 SafeBrowsingDatabaseManager::SafeBrowsingCheck
* check
) {
184 check
->client
->OnSafeBrowsingResult(*check
);
187 ACTION_P(CheckDownloadUrlDone
, threat_type
) {
188 SafeBrowsingDatabaseManager::SafeBrowsingCheck
* check
=
189 new SafeBrowsingDatabaseManager::SafeBrowsingCheck(
191 std::vector
<SBFullHash
>(),
193 safe_browsing_util::BINURL
,
194 std::vector
<SBThreatType
>(1, SB_THREAT_TYPE_BINARY_MALWARE_URL
));
195 for (size_t i
= 0; i
< check
->url_results
.size(); ++i
)
196 check
->url_results
[i
] = threat_type
;
197 BrowserThread::PostTask(BrowserThread::IO
,
199 base::Bind(&OnSafeBrowsingResult
,
200 base::Owned(check
)));
203 class DownloadProtectionServiceTest
: public testing::Test
{
205 DownloadProtectionServiceTest()
206 : test_browser_thread_bundle_(
207 content::TestBrowserThreadBundle::IO_MAINLOOP
) {
209 void SetUp() override
{
210 #if defined(OS_MACOSX)
211 field_trial_list_
.reset(new base::FieldTrialList(
212 new metrics::SHA1EntropyProvider("42")));
213 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
214 "SafeBrowsingOSXClientDownloadPings",
217 // Start real threads for the IO and File threads so that the DCHECKs
218 // to test that we're on the correct thread work.
219 sb_service_
= new StrictMock
<FakeSafeBrowsingService
>();
220 sb_service_
->Initialize();
221 binary_feature_extractor_
= new StrictMock
<MockBinaryFeatureExtractor
>();
222 ON_CALL(*binary_feature_extractor_
, ExtractImageFeatures(_
, _
, _
, _
))
223 .WillByDefault(Return(true));
224 download_service_
= sb_service_
->download_protection_service();
225 download_service_
->binary_feature_extractor_
= binary_feature_extractor_
;
226 download_service_
->SetEnabled(true);
227 client_download_request_subscription_
=
228 download_service_
->RegisterClientDownloadRequestCallback(
229 base::Bind(&DownloadProtectionServiceTest::OnClientDownloadRequest
,
230 base::Unretained(this)));
231 base::RunLoop().RunUntilIdle();
234 base::FilePath source_path
;
235 ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT
, &source_path
));
236 testdata_path_
= source_path
237 .AppendASCII("chrome")
240 .AppendASCII("safe_browsing")
241 .AppendASCII("download_protection");
244 void TearDown() override
{
245 client_download_request_subscription_
.reset();
246 sb_service_
->ShutDown();
247 // Flush all of the thread message loops to ensure that there are no
248 // tasks currently running.
249 FlushThreadMessageLoops();
253 bool RequestContainsResource(const ClientDownloadRequest
& request
,
254 ClientDownloadRequest::ResourceType type
,
255 const std::string
& url
,
256 const std::string
& referrer
) {
257 for (int i
= 0; i
< request
.resources_size(); ++i
) {
258 if (request
.resources(i
).url() == url
&&
259 request
.resources(i
).type() == type
&&
260 (referrer
.empty() || request
.resources(i
).referrer() == referrer
)) {
267 // At this point we only set the server IP for the download itself.
268 bool RequestContainsServerIp(const ClientDownloadRequest
& request
,
269 const std::string
& remote_address
) {
270 for (int i
= 0; i
< request
.resources_size(); ++i
) {
271 // We want the last DOWNLOAD_URL in the chain.
272 if (request
.resources(i
).type() == ClientDownloadRequest::DOWNLOAD_URL
&&
273 (i
+ 1 == request
.resources_size() ||
274 request
.resources(i
+ 1).type() !=
275 ClientDownloadRequest::DOWNLOAD_URL
)) {
276 return remote_address
== request
.resources(i
).remote_ip();
282 // Flushes any pending tasks in the message loops of all threads.
283 void FlushThreadMessageLoops() {
284 BrowserThread::GetBlockingPool()->FlushForTesting();
285 FlushMessageLoop(BrowserThread::IO
);
286 base::RunLoop().RunUntilIdle();
289 // Proxy for private method.
290 static void GetCertificateWhitelistStrings(
291 const net::X509Certificate
& certificate
,
292 const net::X509Certificate
& issuer
,
293 std::vector
<std::string
>* whitelist_strings
) {
294 DownloadProtectionService::GetCertificateWhitelistStrings(
295 certificate
, issuer
, whitelist_strings
);
298 // Reads a single PEM-encoded certificate from the testdata directory.
299 // Returns NULL on failure.
300 scoped_refptr
<net::X509Certificate
> ReadTestCertificate(
301 const std::string
& filename
) {
302 std::string cert_data
;
303 if (!base::ReadFileToString(testdata_path_
.AppendASCII(filename
),
307 net::CertificateList certs
=
308 net::X509Certificate::CreateCertificateListFromBytes(
311 net::X509Certificate::FORMAT_PEM_CERT_SEQUENCE
);
312 return certs
.empty() ? NULL
: certs
[0];
315 const ClientDownloadRequest
* GetClientDownloadRequest() const {
316 return last_client_download_request_
.get();
319 bool HasClientDownloadRequest() const {
320 return last_client_download_request_
.get() != NULL
;
323 void ClearClientDownloadRequest() { last_client_download_request_
.reset(); }
326 // Helper functions for FlushThreadMessageLoops.
327 void RunAllPendingAndQuitUI() {
328 base::MessageLoop::current()->RunUntilIdle();
329 BrowserThread::PostTask(
332 base::Bind(&DownloadProtectionServiceTest::QuitMessageLoop
,
333 base::Unretained(this)));
336 void QuitMessageLoop() {
337 base::MessageLoop::current()->Quit();
340 void PostRunMessageLoopTask(BrowserThread::ID thread
) {
341 BrowserThread::PostTask(
344 base::Bind(&DownloadProtectionServiceTest::RunAllPendingAndQuitUI
,
345 base::Unretained(this)));
348 void FlushMessageLoop(BrowserThread::ID thread
) {
349 BrowserThread::PostTask(
352 base::Bind(&DownloadProtectionServiceTest::PostRunMessageLoopTask
,
353 base::Unretained(this), thread
));
354 MessageLoop::current()->Run();
357 void OnClientDownloadRequest(content::DownloadItem
* download
,
358 const ClientDownloadRequest
* request
) {
360 last_client_download_request_
.reset(new ClientDownloadRequest(*request
));
362 last_client_download_request_
.reset();
366 void CheckDoneCallback(
367 DownloadProtectionService::DownloadCheckResult result
) {
370 MessageLoop::current()->Quit();
373 void SyncCheckDoneCallback(
374 DownloadProtectionService::DownloadCheckResult result
) {
379 void SendURLFetchComplete(net::TestURLFetcher
* fetcher
) {
380 fetcher
->delegate()->OnURLFetchComplete(fetcher
);
383 testing::AssertionResult
IsResult(
384 DownloadProtectionService::DownloadCheckResult expected
) {
386 return testing::AssertionFailure() << "No result";
388 return result_
== expected
?
389 testing::AssertionSuccess() :
390 testing::AssertionFailure() << "Expected " << expected
<<
395 scoped_refptr
<FakeSafeBrowsingService
> sb_service_
;
396 scoped_refptr
<MockBinaryFeatureExtractor
> binary_feature_extractor_
;
397 DownloadProtectionService
* download_service_
;
398 DownloadProtectionService::DownloadCheckResult result_
;
400 content::TestBrowserThreadBundle test_browser_thread_bundle_
;
401 content::InProcessUtilityThreadHelper in_process_utility_thread_helper_
;
402 base::FilePath testdata_path_
;
403 #if defined(OS_MACOSX)
404 scoped_ptr
<base::FieldTrialList
> field_trial_list_
;
406 DownloadProtectionService::ClientDownloadRequestSubscription
407 client_download_request_subscription_
;
408 scoped_ptr
<ClientDownloadRequest
> last_client_download_request_
;
411 TEST_F(DownloadProtectionServiceTest
, CheckClientDownloadInvalidUrl
) {
412 base::FilePath
a_tmp(FILE_PATH_LITERAL("a.tmp"));
413 base::FilePath
a_exe(FILE_PATH_LITERAL("a.exe"));
414 std::vector
<GURL
> url_chain
;
415 GURL
referrer("http://www.google.com/");
417 content::MockDownloadItem item
;
418 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp
));
419 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_exe
));
420 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
421 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
422 EXPECT_CALL(item
, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
423 EXPECT_CALL(item
, GetTabReferrerUrl())
424 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
425 download_service_
->CheckClientDownload(
427 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
428 base::Unretained(this)));
429 MessageLoop::current()->Run();
430 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
431 EXPECT_FALSE(HasClientDownloadRequest());
432 Mock::VerifyAndClearExpectations(&item
);
434 url_chain
.push_back(GURL("file://www.google.com/"));
435 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp
));
436 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_exe
));
437 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
438 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
439 EXPECT_CALL(item
, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
440 EXPECT_CALL(item
, GetTabReferrerUrl())
441 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
442 download_service_
->CheckClientDownload(
444 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
445 base::Unretained(this)));
446 MessageLoop::current()->Run();
447 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
448 EXPECT_FALSE(HasClientDownloadRequest());
451 TEST_F(DownloadProtectionServiceTest
, CheckClientDownloadNotABinary
) {
452 base::FilePath
a_tmp(FILE_PATH_LITERAL("a.tmp"));
453 base::FilePath
a_txt(FILE_PATH_LITERAL("a.txt"));
454 std::vector
<GURL
> url_chain
;
455 GURL
referrer("http://www.google.com/");
457 content::MockDownloadItem item
;
458 url_chain
.push_back(GURL("http://www.example.com/foo"));
459 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp
));
460 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_txt
));
461 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
462 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
463 EXPECT_CALL(item
, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
464 EXPECT_CALL(item
, GetTabReferrerUrl())
465 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
466 download_service_
->CheckClientDownload(
468 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
469 base::Unretained(this)));
470 MessageLoop::current()->Run();
471 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
472 EXPECT_FALSE(HasClientDownloadRequest());
475 TEST_F(DownloadProtectionServiceTest
, CheckClientDownloadWhitelistedUrl
) {
476 // Response to any requests will be DANGEROUS.
477 ClientDownloadResponse response
;
478 response
.set_verdict(ClientDownloadResponse::DANGEROUS
);
479 net::FakeURLFetcherFactory
factory(NULL
);
480 factory
.SetFakeResponse(
481 DownloadProtectionService::GetDownloadRequestUrl(),
482 response
.SerializeAsString(),
483 net::HTTP_OK
, net::URLRequestStatus::SUCCESS
);
485 std::string hash
= "hash";
486 base::FilePath
a_tmp(FILE_PATH_LITERAL("a.tmp"));
487 base::FilePath
a_exe(FILE_PATH_LITERAL("a.exe"));
488 std::vector
<GURL
> url_chain
;
491 content::MockDownloadItem item
;
492 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp
));
493 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_exe
));
494 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
495 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
496 EXPECT_CALL(item
, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
497 EXPECT_CALL(item
, GetTabReferrerUrl())
498 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
499 EXPECT_CALL(item
, GetHash()).WillRepeatedly(ReturnRef(hash
));
500 EXPECT_CALL(item
, GetReceivedBytes()).WillRepeatedly(Return(100));
501 EXPECT_CALL(item
, HasUserGesture()).WillRepeatedly(Return(true));
502 EXPECT_CALL(item
, GetRemoteAddress()).WillRepeatedly(Return(""));
503 EXPECT_CALL(*binary_feature_extractor_
.get(), CheckSignature(a_tmp
, _
))
505 EXPECT_CALL(*binary_feature_extractor_
.get(),
506 ExtractImageFeatures(
507 a_tmp
, BinaryFeatureExtractor::kDefaultOptions
, _
, _
))
510 // We should not get whilelist checks for other URLs than specified below.
511 EXPECT_CALL(*sb_service_
->mock_database_manager(),
512 MatchDownloadWhitelistUrl(_
)).Times(0);
513 EXPECT_CALL(*sb_service_
->mock_database_manager(),
514 MatchDownloadWhitelistUrl(GURL("http://www.evil.com/bla.exe")))
515 .WillRepeatedly(Return(false));
516 EXPECT_CALL(*sb_service_
->mock_database_manager(),
517 MatchDownloadWhitelistUrl(GURL("http://www.google.com/a.exe")))
518 .WillRepeatedly(Return(true));
520 // With no referrer and just the bad url, should be marked DANGEROUS.
521 url_chain
.push_back(GURL("http://www.evil.com/bla.exe"));
522 download_service_
->CheckClientDownload(
524 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
525 base::Unretained(this)));
526 MessageLoop::current()->Run();
528 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS
));
530 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
533 #if defined(OS_WIN) || defined(OS_MACOSX)
534 // OSX sends pings for evaluation purposes.
535 EXPECT_TRUE(HasClientDownloadRequest());
536 ClearClientDownloadRequest();
538 EXPECT_FALSE(HasClientDownloadRequest());
541 // Check that the referrer is not matched against the whitelist.
542 referrer
= GURL("http://www.google.com/");
543 download_service_
->CheckClientDownload(
545 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
546 base::Unretained(this)));
547 MessageLoop::current()->Run();
549 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS
));
551 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
554 #if defined(OS_WIN) || defined(OS_MACOSX)
555 // OSX sends pings for evaluation purposes.
556 EXPECT_TRUE(HasClientDownloadRequest());
557 ClearClientDownloadRequest();
559 EXPECT_FALSE(HasClientDownloadRequest());
562 // Redirect from a site shouldn't be checked either.
563 url_chain
.insert(url_chain
.begin(), GURL("http://www.google.com/redirect"));
564 download_service_
->CheckClientDownload(
566 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
567 base::Unretained(this)));
568 MessageLoop::current()->Run();
570 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS
));
572 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
575 #if defined(OS_WIN) || defined(OS_MACOSX)
576 // OSX sends pings for evaluation purposes.
577 EXPECT_TRUE(HasClientDownloadRequest());
578 ClearClientDownloadRequest();
580 EXPECT_FALSE(HasClientDownloadRequest());
583 // Only if the final url is whitelisted should it be SAFE.
584 url_chain
.push_back(GURL("http://www.google.com/a.exe"));
585 download_service_
->CheckClientDownload(
587 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
588 base::Unretained(this)));
589 MessageLoop::current()->Run();
590 #if defined(OS_MACOSX)
591 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
593 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE
));
595 // TODO(grt): Make the service produce the request even when the URL is
597 EXPECT_FALSE(HasClientDownloadRequest());
600 TEST_F(DownloadProtectionServiceTest
, CheckClientDownloadFetchFailed
) {
601 net::FakeURLFetcherFactory
factory(NULL
);
602 // HTTP request will fail.
603 factory
.SetFakeResponse(
604 DownloadProtectionService::GetDownloadRequestUrl(), std::string(),
605 net::HTTP_INTERNAL_SERVER_ERROR
, net::URLRequestStatus::FAILED
);
607 base::FilePath
a_tmp(FILE_PATH_LITERAL("a.tmp"));
608 base::FilePath
a_exe(FILE_PATH_LITERAL("a.exe"));
609 std::vector
<GURL
> url_chain
;
610 url_chain
.push_back(GURL("http://www.evil.com/a.exe"));
611 GURL
referrer("http://www.google.com/");
612 std::string hash
= "hash";
614 content::MockDownloadItem item
;
615 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp
));
616 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_exe
));
617 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
618 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
619 EXPECT_CALL(item
, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
620 EXPECT_CALL(item
, GetTabReferrerUrl())
621 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
622 EXPECT_CALL(item
, GetHash()).WillRepeatedly(ReturnRef(hash
));
623 EXPECT_CALL(item
, GetReceivedBytes()).WillRepeatedly(Return(100));
624 EXPECT_CALL(item
, HasUserGesture()).WillRepeatedly(Return(true));
625 EXPECT_CALL(item
, GetRemoteAddress()).WillRepeatedly(Return(""));
627 EXPECT_CALL(*sb_service_
->mock_database_manager(),
628 MatchDownloadWhitelistUrl(_
))
629 .WillRepeatedly(Return(false));
630 EXPECT_CALL(*binary_feature_extractor_
.get(), CheckSignature(a_tmp
, _
));
632 *binary_feature_extractor_
.get(),
633 ExtractImageFeatures(a_tmp
, BinaryFeatureExtractor::kDefaultOptions
,
636 download_service_
->CheckClientDownload(
638 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
639 base::Unretained(this)));
640 MessageLoop::current()->Run();
641 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
644 TEST_F(DownloadProtectionServiceTest
, CheckClientDownloadSuccess
) {
645 ClientDownloadResponse response
;
646 response
.set_verdict(ClientDownloadResponse::SAFE
);
647 net::FakeURLFetcherFactory
factory(NULL
);
648 // Empty response means SAFE.
649 factory
.SetFakeResponse(
650 DownloadProtectionService::GetDownloadRequestUrl(),
651 response
.SerializeAsString(),
652 net::HTTP_OK
, net::URLRequestStatus::SUCCESS
);
654 base::FilePath
a_tmp(FILE_PATH_LITERAL("a.tmp"));
655 base::FilePath
a_exe(FILE_PATH_LITERAL("a.exe"));
656 std::vector
<GURL
> url_chain
;
657 url_chain
.push_back(GURL("http://www.evil.com/a.exe"));
658 GURL
referrer("http://www.google.com/");
659 std::string hash
= "hash";
661 content::MockDownloadItem item
;
662 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp
));
663 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_exe
));
664 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
665 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
666 EXPECT_CALL(item
, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
667 EXPECT_CALL(item
, GetTabReferrerUrl())
668 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
669 EXPECT_CALL(item
, GetHash()).WillRepeatedly(ReturnRef(hash
));
670 EXPECT_CALL(item
, GetReceivedBytes()).WillRepeatedly(Return(100));
671 EXPECT_CALL(item
, HasUserGesture()).WillRepeatedly(Return(true));
672 EXPECT_CALL(item
, GetRemoteAddress()).WillRepeatedly(Return(""));
674 EXPECT_CALL(*sb_service_
->mock_database_manager(),
675 MatchDownloadWhitelistUrl(_
))
676 .WillRepeatedly(Return(false));
677 EXPECT_CALL(*binary_feature_extractor_
.get(), CheckSignature(a_tmp
, _
))
679 EXPECT_CALL(*binary_feature_extractor_
.get(),
680 ExtractImageFeatures(
681 a_tmp
, BinaryFeatureExtractor::kDefaultOptions
, _
, _
))
684 download_service_
->CheckClientDownload(
686 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
687 base::Unretained(this)));
688 MessageLoop::current()->Run();
690 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE
));
692 // On !OS_WIN, no file types are currently supported. Hence all requests to
693 // CheckClientDownload() result in a verdict of UNKNOWN.
694 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
697 #if defined(OS_WIN) || defined(OS_MACOSX)
698 // OSX sends pings for evaluation purposes.
699 EXPECT_TRUE(HasClientDownloadRequest());
700 ClearClientDownloadRequest();
702 EXPECT_FALSE(HasClientDownloadRequest());
705 // Invalid response should result in UNKNOWN.
707 factory
.SetFakeResponse(
708 DownloadProtectionService::GetDownloadRequestUrl(),
709 response
.SerializePartialAsString(),
710 net::HTTP_OK
, net::URLRequestStatus::SUCCESS
);
712 download_service_
->CheckClientDownload(
714 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
715 base::Unretained(this)));
716 MessageLoop::current()->Run();
717 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
718 #if defined(OS_WIN) || defined(OS_MACOSX)
719 EXPECT_TRUE(HasClientDownloadRequest());
720 ClearClientDownloadRequest();
722 EXPECT_FALSE(HasClientDownloadRequest());
724 std::string feedback_ping
;
725 std::string feedback_response
;
726 EXPECT_FALSE(DownloadFeedbackService::GetPingsForDownloadForTesting(
727 item
, &feedback_ping
, &feedback_response
));
729 // If the response is dangerous the result should also be marked as dangerous.
730 response
.set_verdict(ClientDownloadResponse::DANGEROUS
);
731 factory
.SetFakeResponse(
732 DownloadProtectionService::GetDownloadRequestUrl(),
733 response
.SerializeAsString(),
734 net::HTTP_OK
, net::URLRequestStatus::SUCCESS
);
736 download_service_
->CheckClientDownload(
738 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
739 base::Unretained(this)));
740 MessageLoop::current()->Run();
741 EXPECT_FALSE(DownloadFeedbackService::GetPingsForDownloadForTesting(
742 item
, &feedback_ping
, &feedback_response
));
744 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS
));
746 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
749 #if defined(OS_WIN) || defined(OS_MACOSX)
750 // OSX sends pings for evaluation purposes.
751 EXPECT_TRUE(HasClientDownloadRequest());
752 ClearClientDownloadRequest();
754 EXPECT_FALSE(HasClientDownloadRequest());
757 // If the response is uncommon the result should also be marked as uncommon.
758 response
.set_verdict(ClientDownloadResponse::UNCOMMON
);
759 factory
.SetFakeResponse(
760 DownloadProtectionService::GetDownloadRequestUrl(),
761 response
.SerializeAsString(),
762 net::HTTP_OK
, net::URLRequestStatus::SUCCESS
);
764 download_service_
->CheckClientDownload(
766 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
767 base::Unretained(this)));
768 MessageLoop::current()->Run();
770 EXPECT_TRUE(IsResult(DownloadProtectionService::UNCOMMON
));
771 EXPECT_TRUE(DownloadFeedbackService::GetPingsForDownloadForTesting(
772 item
, &feedback_ping
, &feedback_response
));
773 ClientDownloadRequest decoded_request
;
774 EXPECT_TRUE(decoded_request
.ParseFromString(feedback_ping
));
775 EXPECT_EQ(url_chain
.back().spec(), decoded_request
.url());
776 EXPECT_EQ(response
.SerializeAsString(), feedback_response
);
777 EXPECT_TRUE(HasClientDownloadRequest());
778 ClearClientDownloadRequest();
780 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
783 // If the response is dangerous_host the result should also be marked as
785 response
.set_verdict(ClientDownloadResponse::DANGEROUS_HOST
);
786 factory
.SetFakeResponse(
787 DownloadProtectionService::GetDownloadRequestUrl(),
788 response
.SerializeAsString(),
789 net::HTTP_OK
, net::URLRequestStatus::SUCCESS
);
791 download_service_
->CheckClientDownload(
793 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
794 base::Unretained(this)));
795 MessageLoop::current()->Run();
797 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS_HOST
));
798 EXPECT_TRUE(DownloadFeedbackService::GetPingsForDownloadForTesting(
799 item
, &feedback_ping
, &feedback_response
));
800 EXPECT_EQ(response
.SerializeAsString(), feedback_response
);
801 EXPECT_TRUE(HasClientDownloadRequest());
802 ClearClientDownloadRequest();
804 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
807 // If the response is POTENTIALLY_UNWANTED the result should also be marked as
808 // POTENTIALLY_UNWANTED.
809 response
.set_verdict(ClientDownloadResponse::POTENTIALLY_UNWANTED
);
810 factory
.SetFakeResponse(
811 DownloadProtectionService::GetDownloadRequestUrl(),
812 response
.SerializeAsString(),
813 net::HTTP_OK
, net::URLRequestStatus::SUCCESS
);
815 download_service_
->CheckClientDownload(
817 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
818 base::Unretained(this)));
819 MessageLoop::current()->Run();
821 EXPECT_TRUE(IsResult(DownloadProtectionService::POTENTIALLY_UNWANTED
));
823 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
826 #if defined(OS_WIN) || defined(OS_MACOSX)
827 // OSX sends pings for evaluation purposes.
828 EXPECT_TRUE(HasClientDownloadRequest());
829 ClearClientDownloadRequest();
831 EXPECT_FALSE(HasClientDownloadRequest());
835 TEST_F(DownloadProtectionServiceTest
, CheckClientDownloadHTTPS
) {
836 ClientDownloadResponse response
;
837 response
.set_verdict(ClientDownloadResponse::DANGEROUS
);
838 net::FakeURLFetcherFactory
factory(NULL
);
839 factory
.SetFakeResponse(
840 DownloadProtectionService::GetDownloadRequestUrl(),
841 response
.SerializeAsString(),
842 net::HTTP_OK
, net::URLRequestStatus::SUCCESS
);
844 base::FilePath
a_tmp(FILE_PATH_LITERAL("a.tmp"));
845 base::FilePath
a_exe(FILE_PATH_LITERAL("a.exe"));
846 std::vector
<GURL
> url_chain
;
847 url_chain
.push_back(GURL("http://www.evil.com/a.exe"));
848 GURL
referrer("http://www.google.com/");
849 std::string hash
= "hash";
851 content::MockDownloadItem item
;
852 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp
));
853 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_exe
));
854 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
855 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
856 EXPECT_CALL(item
, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
857 EXPECT_CALL(item
, GetTabReferrerUrl())
858 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
859 EXPECT_CALL(item
, GetHash()).WillRepeatedly(ReturnRef(hash
));
860 EXPECT_CALL(item
, GetReceivedBytes()).WillRepeatedly(Return(100));
861 EXPECT_CALL(item
, HasUserGesture()).WillRepeatedly(Return(true));
862 EXPECT_CALL(item
, GetRemoteAddress()).WillRepeatedly(Return(""));
864 EXPECT_CALL(*sb_service_
->mock_database_manager(),
865 MatchDownloadWhitelistUrl(_
))
866 .WillRepeatedly(Return(false));
867 EXPECT_CALL(*binary_feature_extractor_
.get(), CheckSignature(a_tmp
, _
))
869 EXPECT_CALL(*binary_feature_extractor_
.get(),
870 ExtractImageFeatures(
871 a_tmp
, BinaryFeatureExtractor::kDefaultOptions
, _
, _
))
874 download_service_
->CheckClientDownload(
876 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
877 base::Unretained(this)));
878 MessageLoop::current()->Run();
880 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS
));
882 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
885 #if defined(OS_WIN) || defined(OS_MACOSX)
886 // OSX sends pings for evaluation purposes.
887 EXPECT_TRUE(HasClientDownloadRequest());
888 ClearClientDownloadRequest();
890 EXPECT_FALSE(HasClientDownloadRequest());
894 TEST_F(DownloadProtectionServiceTest
, CheckClientDownloadBlob
) {
895 ClientDownloadResponse response
;
896 response
.set_verdict(ClientDownloadResponse::DANGEROUS
);
897 net::FakeURLFetcherFactory
factory(NULL
);
898 factory
.SetFakeResponse(DownloadProtectionService::GetDownloadRequestUrl(),
899 response
.SerializeAsString(), net::HTTP_OK
,
900 net::URLRequestStatus::SUCCESS
);
902 base::FilePath
a_tmp(FILE_PATH_LITERAL("a.tmp"));
903 base::FilePath
a_exe(FILE_PATH_LITERAL("a.exe"));
904 std::vector
<GURL
> url_chain
;
906 GURL("blob:http://www.evil.com/50b85f60-71e4-11e4-82f8-0800200c9a66"));
907 GURL
referrer("http://www.google.com/");
908 std::string hash
= "hash";
910 content::MockDownloadItem item
;
911 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp
));
912 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_exe
));
913 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
914 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
915 EXPECT_CALL(item
, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
916 EXPECT_CALL(item
, GetTabReferrerUrl())
917 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
918 EXPECT_CALL(item
, GetHash()).WillRepeatedly(ReturnRef(hash
));
919 EXPECT_CALL(item
, GetReceivedBytes()).WillRepeatedly(Return(100));
920 EXPECT_CALL(item
, HasUserGesture()).WillRepeatedly(Return(true));
921 EXPECT_CALL(item
, GetRemoteAddress()).WillRepeatedly(Return(""));
923 EXPECT_CALL(*sb_service_
->mock_database_manager(),
924 MatchDownloadWhitelistUrl(_
)).WillRepeatedly(Return(false));
925 EXPECT_CALL(*binary_feature_extractor_
.get(), CheckSignature(a_tmp
, _
))
927 EXPECT_CALL(*binary_feature_extractor_
.get(),
928 ExtractImageFeatures(
929 a_tmp
, BinaryFeatureExtractor::kDefaultOptions
, _
, _
))
932 download_service_
->CheckClientDownload(
934 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
935 base::Unretained(this)));
936 MessageLoop::current()->Run();
938 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS
));
940 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
943 #if defined(OS_WIN) || defined(OS_MACOSX)
944 // OSX sends pings for evaluation purposes.
945 EXPECT_TRUE(HasClientDownloadRequest());
946 ClearClientDownloadRequest();
948 EXPECT_FALSE(HasClientDownloadRequest());
952 TEST_F(DownloadProtectionServiceTest
, CheckClientDownloadData
) {
953 ClientDownloadResponse response
;
954 response
.set_verdict(ClientDownloadResponse::DANGEROUS
);
955 net::FakeURLFetcherFactory
factory(NULL
);
956 factory
.SetFakeResponse(DownloadProtectionService::GetDownloadRequestUrl(),
957 response
.SerializeAsString(), net::HTTP_OK
,
958 net::URLRequestStatus::SUCCESS
);
960 base::FilePath
a_tmp(FILE_PATH_LITERAL("a.tmp"));
961 base::FilePath
a_exe(FILE_PATH_LITERAL("a.exe"));
962 std::vector
<GURL
> url_chain
;
964 GURL("data:text/html:base64,"));
966 GURL("data:text/html:base64,blahblahblah"));
968 GURL("data:application/octet-stream:base64,blahblah"));
969 GURL
referrer("data:text/html:base64,foobar");
970 std::string hash
= "hash";
972 content::MockDownloadItem item
;
973 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp
));
974 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_exe
));
975 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
976 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
977 EXPECT_CALL(item
, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
978 EXPECT_CALL(item
, GetTabReferrerUrl())
979 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
980 EXPECT_CALL(item
, GetHash()).WillRepeatedly(ReturnRef(hash
));
981 EXPECT_CALL(item
, GetReceivedBytes()).WillRepeatedly(Return(100));
982 EXPECT_CALL(item
, HasUserGesture()).WillRepeatedly(Return(true));
983 EXPECT_CALL(item
, GetRemoteAddress()).WillRepeatedly(Return(""));
985 EXPECT_CALL(*sb_service_
->mock_database_manager(),
986 MatchDownloadWhitelistUrl(_
)).WillRepeatedly(Return(false));
987 EXPECT_CALL(*binary_feature_extractor_
.get(), CheckSignature(a_tmp
, _
))
989 EXPECT_CALL(*binary_feature_extractor_
.get(),
990 ExtractImageFeatures(
991 a_tmp
, BinaryFeatureExtractor::kDefaultOptions
, _
, _
))
994 download_service_
->CheckClientDownload(
996 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
997 base::Unretained(this)));
998 MessageLoop::current()->Run();
1000 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS
));
1002 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
1005 #if defined(OS_WIN) || defined(OS_MACOSX)
1006 // OSX sends pings for evaluation purposes.
1007 ASSERT_TRUE(HasClientDownloadRequest());
1008 const ClientDownloadRequest
& request
= *GetClientDownloadRequest();
1009 const char kExpectedUrl
[] =
1010 "data:application/octet-stream:base64,"
1011 "ACBF6DFC6F907662F566CA0241DFE8690C48661F440BA1BBD0B86C582845CCC8";
1012 const char kExpectedRedirect1
[] = "data:text/html:base64,";
1013 const char kExpectedRedirect2
[] =
1014 "data:text/html:base64,"
1015 "620680767E15717A57DB11D94D1BEBD32B3344EBC5994DF4FB07B0D473F4EF6B";
1016 const char kExpectedReferrer
[] =
1017 "data:text/html:base64,"
1018 "06E2C655B9F7130B508FFF86FD19B57E6BF1A1CFEFD6EFE1C3EB09FE24EF456A";
1019 EXPECT_EQ(hash
, request
.digests().sha256());
1020 EXPECT_EQ(kExpectedUrl
, request
.url());
1021 EXPECT_EQ(3, request
.resources_size());
1022 EXPECT_TRUE(RequestContainsResource(request
,
1023 ClientDownloadRequest::DOWNLOAD_REDIRECT
,
1024 kExpectedRedirect1
, ""));
1025 EXPECT_TRUE(RequestContainsResource(request
,
1026 ClientDownloadRequest::DOWNLOAD_REDIRECT
,
1027 kExpectedRedirect2
, ""));
1028 EXPECT_TRUE(RequestContainsResource(request
,
1029 ClientDownloadRequest::DOWNLOAD_URL
,
1030 kExpectedUrl
, kExpectedReferrer
));
1031 ClearClientDownloadRequest();
1033 EXPECT_FALSE(HasClientDownloadRequest());
1037 TEST_F(DownloadProtectionServiceTest
, CheckClientDownloadZip
) {
1038 ClientDownloadResponse response
;
1039 response
.set_verdict(ClientDownloadResponse::SAFE
);
1040 net::FakeURLFetcherFactory
factory(NULL
);
1041 // Empty response means SAFE.
1042 factory
.SetFakeResponse(
1043 DownloadProtectionService::GetDownloadRequestUrl(),
1044 response
.SerializeAsString(),
1045 net::HTTP_OK
, net::URLRequestStatus::SUCCESS
);
1047 base::ScopedTempDir download_dir
;
1048 ASSERT_TRUE(download_dir
.CreateUniqueTempDir());
1050 base::FilePath
a_tmp(download_dir
.path().Append(FILE_PATH_LITERAL("a.tmp")));
1051 base::FilePath
a_zip(FILE_PATH_LITERAL("a.zip"));
1052 std::vector
<GURL
> url_chain
;
1053 url_chain
.push_back(GURL("http://www.evil.com/a.zip"));
1054 GURL
referrer("http://www.google.com/");
1055 std::string hash
= "hash";
1057 content::MockDownloadItem item
;
1058 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp
));
1059 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_zip
));
1060 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
1061 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
1062 EXPECT_CALL(item
, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
1063 EXPECT_CALL(item
, GetTabReferrerUrl())
1064 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
1065 EXPECT_CALL(item
, GetHash()).WillRepeatedly(ReturnRef(hash
));
1066 EXPECT_CALL(item
, GetReceivedBytes()).WillRepeatedly(Return(100));
1067 EXPECT_CALL(item
, HasUserGesture()).WillRepeatedly(Return(true));
1068 EXPECT_CALL(item
, GetRemoteAddress()).WillRepeatedly(Return(""));
1070 // Write out a zip archive to the temporary file. In this case, it
1071 // only contains a text file.
1072 base::ScopedTempDir zip_source_dir
;
1073 ASSERT_TRUE(zip_source_dir
.CreateUniqueTempDir());
1074 std::string file_contents
= "dummy file";
1075 ASSERT_EQ(static_cast<int>(file_contents
.size()), base::WriteFile(
1076 zip_source_dir
.path().Append(FILE_PATH_LITERAL("file.txt")),
1077 file_contents
.data(), file_contents
.size()));
1078 ASSERT_TRUE(zip::Zip(zip_source_dir
.path(), a_tmp
, false));
1080 download_service_
->CheckClientDownload(
1082 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
1083 base::Unretained(this)));
1084 MessageLoop::current()->Run();
1085 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
1086 EXPECT_FALSE(HasClientDownloadRequest());
1087 Mock::VerifyAndClearExpectations(sb_service_
.get());
1088 Mock::VerifyAndClearExpectations(binary_feature_extractor_
.get());
1090 // Now check with an executable in the zip file as well.
1091 ASSERT_EQ(static_cast<int>(file_contents
.size()), base::WriteFile(
1092 zip_source_dir
.path().Append(FILE_PATH_LITERAL("file.exe")),
1093 file_contents
.data(), file_contents
.size()));
1094 ASSERT_TRUE(zip::Zip(zip_source_dir
.path(), a_tmp
, false));
1096 EXPECT_CALL(*sb_service_
->mock_database_manager(),
1097 MatchDownloadWhitelistUrl(_
))
1098 .WillRepeatedly(Return(false));
1100 download_service_
->CheckClientDownload(
1102 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
1103 base::Unretained(this)));
1104 MessageLoop::current()->Run();
1106 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE
));
1108 // For !OS_WIN, no file types are currently supported. Hence the resulting
1109 // verdict is UNKNOWN.
1110 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
1113 #if defined(OS_WIN) || defined(OS_MACOSX)
1114 // OSX sends pings for evaluation purposes.
1115 EXPECT_TRUE(HasClientDownloadRequest());
1116 ClearClientDownloadRequest();
1118 EXPECT_FALSE(HasClientDownloadRequest());
1120 Mock::VerifyAndClearExpectations(binary_feature_extractor_
.get());
1122 // If the response is dangerous the result should also be marked as
1124 response
.set_verdict(ClientDownloadResponse::DANGEROUS
);
1125 factory
.SetFakeResponse(
1126 DownloadProtectionService::GetDownloadRequestUrl(),
1127 response
.SerializeAsString(),
1128 net::HTTP_OK
, net::URLRequestStatus::SUCCESS
);
1130 download_service_
->CheckClientDownload(
1132 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
1133 base::Unretained(this)));
1134 MessageLoop::current()->Run();
1136 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS
));
1138 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
1141 #if defined(OS_WIN) || defined(OS_MACOSX)
1142 // OSX sends pings for evaluation purposes.
1143 EXPECT_TRUE(HasClientDownloadRequest());
1144 ClearClientDownloadRequest();
1146 EXPECT_FALSE(HasClientDownloadRequest());
1148 Mock::VerifyAndClearExpectations(binary_feature_extractor_
.get());
1151 TEST_F(DownloadProtectionServiceTest
, CheckClientDownloadCorruptZip
) {
1152 base::ScopedTempDir download_dir
;
1153 ASSERT_TRUE(download_dir
.CreateUniqueTempDir());
1155 base::FilePath
a_tmp(download_dir
.path().Append(FILE_PATH_LITERAL("a.tmp")));
1156 base::FilePath
a_zip(FILE_PATH_LITERAL("a.zip"));
1157 std::vector
<GURL
> url_chain
;
1158 url_chain
.push_back(GURL("http://www.evil.com/a.zip"));
1159 GURL
referrer("http://www.google.com/");
1160 std::string hash
= "hash";
1162 content::MockDownloadItem item
;
1163 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp
));
1164 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_zip
));
1165 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
1166 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
1167 EXPECT_CALL(item
, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
1168 EXPECT_CALL(item
, GetTabReferrerUrl())
1169 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
1170 EXPECT_CALL(item
, GetHash()).WillRepeatedly(ReturnRef(hash
));
1171 EXPECT_CALL(item
, GetReceivedBytes()).WillRepeatedly(Return(100));
1172 EXPECT_CALL(item
, HasUserGesture()).WillRepeatedly(Return(true));
1173 EXPECT_CALL(item
, GetRemoteAddress()).WillRepeatedly(Return(""));
1175 std::string file_contents
= "corrupt zip file";
1176 ASSERT_EQ(static_cast<int>(file_contents
.size()), base::WriteFile(
1177 a_tmp
, file_contents
.data(), file_contents
.size()));
1179 download_service_
->CheckClientDownload(
1181 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
1182 base::Unretained(this)));
1183 MessageLoop::current()->Run();
1184 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
1185 EXPECT_FALSE(HasClientDownloadRequest());
1186 Mock::VerifyAndClearExpectations(sb_service_
.get());
1187 Mock::VerifyAndClearExpectations(binary_feature_extractor_
.get());
1190 TEST_F(DownloadProtectionServiceTest
, CheckClientCrxDownloadSuccess
) {
1191 ClientDownloadResponse response
;
1192 // Even if the server verdict is dangerous we should return SAFE because
1193 // DownloadProtectionService::IsSupportedDownload() will return false
1194 // for crx downloads.
1195 response
.set_verdict(ClientDownloadResponse::DANGEROUS
);
1196 net::FakeURLFetcherFactory
factory(NULL
);
1197 // Empty response means SAFE.
1198 factory
.SetFakeResponse(
1199 DownloadProtectionService::GetDownloadRequestUrl(),
1200 response
.SerializeAsString(),
1201 net::HTTP_OK
, net::URLRequestStatus::SUCCESS
);
1203 base::FilePath
a_tmp(FILE_PATH_LITERAL("a.tmp"));
1204 base::FilePath
a_crx(FILE_PATH_LITERAL("a.crx"));
1205 std::vector
<GURL
> url_chain
;
1206 url_chain
.push_back(GURL("http://www.evil.com/a.crx"));
1207 GURL
referrer("http://www.google.com/");
1208 std::string hash
= "hash";
1210 content::MockDownloadItem item
;
1211 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp
));
1212 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_crx
));
1213 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
1214 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
1215 EXPECT_CALL(item
, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
1216 EXPECT_CALL(item
, GetTabReferrerUrl())
1217 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
1218 EXPECT_CALL(item
, GetHash()).WillRepeatedly(ReturnRef(hash
));
1219 EXPECT_CALL(item
, GetReceivedBytes()).WillRepeatedly(Return(100));
1220 EXPECT_CALL(item
, HasUserGesture()).WillRepeatedly(Return(true));
1221 EXPECT_CALL(item
, GetRemoteAddress()).WillRepeatedly(Return(""));
1223 EXPECT_CALL(*sb_service_
->mock_database_manager(),
1224 MatchDownloadWhitelistUrl(_
))
1225 .WillRepeatedly(Return(false));
1226 EXPECT_CALL(*binary_feature_extractor_
.get(), CheckSignature(a_tmp
, _
))
1228 EXPECT_CALL(*binary_feature_extractor_
.get(),
1229 ExtractImageFeatures(
1230 a_tmp
, BinaryFeatureExtractor::kDefaultOptions
, _
, _
))
1233 EXPECT_FALSE(download_service_
->IsSupportedDownload(item
, a_crx
));
1234 download_service_
->CheckClientDownload(
1236 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
1237 base::Unretained(this)));
1238 MessageLoop::current()->Run();
1239 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
1242 #if defined(OS_MACOSX)
1243 // TODO(mattm): remove this (see crbug.com/414834).
1244 TEST_F(DownloadProtectionServiceTest
,
1245 CheckClientDownloadPingOnOSXRequiresFieldTrial
) {
1246 // Clear the field trial that was set in SetUp().
1247 field_trial_list_
.reset();
1249 net::TestURLFetcherFactory factory
;
1251 base::FilePath
tmp_path(FILE_PATH_LITERAL("bla.tmp"));
1252 base::FilePath
final_path(FILE_PATH_LITERAL("bla.exe"));
1253 std::vector
<GURL
> url_chain
;
1254 url_chain
.push_back(GURL("http://www.google.com/"));
1255 url_chain
.push_back(GURL("http://www.google.com/bla.exe"));
1256 GURL
referrer("http://www.google.com/");
1257 std::string hash
= "hash";
1258 std::string remote_address
= "10.11.12.13";
1260 content::MockDownloadItem item
;
1261 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(tmp_path
));
1262 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(final_path
));
1263 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
1264 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
1265 EXPECT_CALL(item
, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
1266 EXPECT_CALL(item
, GetTabReferrerUrl())
1267 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
1268 EXPECT_CALL(item
, GetHash()).WillRepeatedly(ReturnRef(hash
));
1269 EXPECT_CALL(item
, GetReceivedBytes()).WillRepeatedly(Return(100));
1270 EXPECT_CALL(item
, HasUserGesture()).WillRepeatedly(Return(true));
1271 EXPECT_CALL(item
, GetRemoteAddress()).WillRepeatedly(Return(remote_address
));
1273 EXPECT_CALL(*sb_service_
->mock_database_manager(),
1274 MatchDownloadWhitelistUrl(_
))
1275 .WillRepeatedly(Return(false));
1276 EXPECT_CALL(*binary_feature_extractor_
.get(), CheckSignature(tmp_path
, _
))
1277 .WillOnce(SetCertificateContents("dummy cert data"));
1279 *binary_feature_extractor_
.get(),
1280 ExtractImageFeatures(tmp_path
, BinaryFeatureExtractor::kDefaultOptions
,
1282 .WillOnce(SetDosHeaderContents("dummy dos header"));
1283 download_service_
->CheckClientDownload(
1285 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
1286 base::Unretained(this)));
1288 // SendRequest is not called. Wait for FinishRequest to call our callback.
1289 MessageLoop::current()->Run();
1290 net::TestURLFetcher
* fetcher
= factory
.GetFetcherByID(0);
1291 EXPECT_EQ(NULL
, fetcher
);
1292 EXPECT_FALSE(HasClientDownloadRequest());
1296 TEST_F(DownloadProtectionServiceTest
, CheckClientDownloadValidateRequest
) {
1297 net::TestURLFetcherFactory factory
;
1299 base::FilePath
tmp_path(FILE_PATH_LITERAL("bla.tmp"));
1300 base::FilePath
final_path(FILE_PATH_LITERAL("bla.exe"));
1301 std::vector
<GURL
> url_chain
;
1302 url_chain
.push_back(GURL("http://www.google.com/"));
1303 url_chain
.push_back(GURL("http://www.google.com/bla.exe"));
1304 GURL
referrer("http://www.google.com/");
1305 std::string hash
= "hash";
1306 std::string remote_address
= "10.11.12.13";
1308 content::MockDownloadItem item
;
1309 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(tmp_path
));
1310 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(final_path
));
1311 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
1312 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
1313 EXPECT_CALL(item
, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
1314 EXPECT_CALL(item
, GetTabReferrerUrl())
1315 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
1316 EXPECT_CALL(item
, GetHash()).WillRepeatedly(ReturnRef(hash
));
1317 EXPECT_CALL(item
, GetReceivedBytes()).WillRepeatedly(Return(100));
1318 EXPECT_CALL(item
, HasUserGesture()).WillRepeatedly(Return(true));
1319 EXPECT_CALL(item
, GetRemoteAddress()).WillRepeatedly(Return(remote_address
));
1321 EXPECT_CALL(*sb_service_
->mock_database_manager(),
1322 MatchDownloadWhitelistUrl(_
))
1323 .WillRepeatedly(Return(false));
1324 EXPECT_CALL(*binary_feature_extractor_
.get(), CheckSignature(tmp_path
, _
))
1325 .WillOnce(SetCertificateContents("dummy cert data"));
1327 *binary_feature_extractor_
.get(),
1328 ExtractImageFeatures(tmp_path
, BinaryFeatureExtractor::kDefaultOptions
,
1330 .WillOnce(SetDosHeaderContents("dummy dos header"));
1331 download_service_
->CheckClientDownload(
1333 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
1334 base::Unretained(this)));
1336 #if !defined(OS_WIN) && !defined(OS_MACOSX)
1337 // SendRequest is not called. Wait for FinishRequest to call our callback.
1338 MessageLoop::current()->Run();
1339 net::TestURLFetcher
* fetcher
= factory
.GetFetcherByID(0);
1340 EXPECT_EQ(NULL
, fetcher
);
1341 EXPECT_FALSE(HasClientDownloadRequest());
1343 // Run the message loop(s) until SendRequest is called.
1344 FlushThreadMessageLoops();
1345 EXPECT_TRUE(HasClientDownloadRequest());
1346 ClearClientDownloadRequest();
1347 net::TestURLFetcher
* fetcher
= factory
.GetFetcherByID(0);
1348 ASSERT_TRUE(fetcher
);
1349 ClientDownloadRequest request
;
1350 EXPECT_TRUE(request
.ParseFromString(fetcher
->upload_data()));
1351 EXPECT_EQ("http://www.google.com/bla.exe", request
.url());
1352 EXPECT_EQ(hash
, request
.digests().sha256());
1353 EXPECT_EQ(item
.GetReceivedBytes(), request
.length());
1354 EXPECT_EQ(item
.HasUserGesture(), request
.user_initiated());
1355 EXPECT_TRUE(RequestContainsServerIp(request
, remote_address
));
1356 EXPECT_EQ(2, request
.resources_size());
1357 EXPECT_TRUE(RequestContainsResource(request
,
1358 ClientDownloadRequest::DOWNLOAD_REDIRECT
,
1359 "http://www.google.com/", ""));
1360 EXPECT_TRUE(RequestContainsResource(request
,
1361 ClientDownloadRequest::DOWNLOAD_URL
,
1362 "http://www.google.com/bla.exe",
1364 EXPECT_TRUE(request
.has_signature());
1365 ASSERT_EQ(1, request
.signature().certificate_chain_size());
1366 const ClientDownloadRequest_CertificateChain
& chain
=
1367 request
.signature().certificate_chain(0);
1368 ASSERT_EQ(1, chain
.element_size());
1369 EXPECT_EQ("dummy cert data", chain
.element(0).certificate());
1370 EXPECT_TRUE(request
.has_image_headers());
1371 const ClientDownloadRequest_ImageHeaders
& headers
=
1372 request
.image_headers();
1373 EXPECT_TRUE(headers
.has_pe_headers());
1374 EXPECT_TRUE(headers
.pe_headers().has_dos_header());
1375 EXPECT_EQ("dummy dos header", headers
.pe_headers().dos_header());
1377 // Simulate the request finishing.
1378 base::MessageLoop::current()->PostTask(
1380 base::Bind(&DownloadProtectionServiceTest::SendURLFetchComplete
,
1381 base::Unretained(this), fetcher
));
1382 MessageLoop::current()->Run();
1386 // Similar to above, but with an unsigned binary.
1387 TEST_F(DownloadProtectionServiceTest
,
1388 CheckClientDownloadValidateRequestNoSignature
) {
1389 net::TestURLFetcherFactory factory
;
1391 base::FilePath
tmp_path(FILE_PATH_LITERAL("bla.tmp"));
1392 base::FilePath
final_path(FILE_PATH_LITERAL("bla.exe"));
1393 std::vector
<GURL
> url_chain
;
1394 url_chain
.push_back(GURL("http://www.google.com/"));
1395 url_chain
.push_back(GURL("ftp://www.google.com/bla.exe"));
1396 GURL
referrer("http://www.google.com/");
1397 std::string hash
= "hash";
1398 std::string remote_address
= "10.11.12.13";
1400 content::MockDownloadItem item
;
1401 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(tmp_path
));
1402 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(final_path
));
1403 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
1404 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
1405 EXPECT_CALL(item
, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
1406 EXPECT_CALL(item
, GetTabReferrerUrl())
1407 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
1408 EXPECT_CALL(item
, GetHash()).WillRepeatedly(ReturnRef(hash
));
1409 EXPECT_CALL(item
, GetReceivedBytes()).WillRepeatedly(Return(100));
1410 EXPECT_CALL(item
, HasUserGesture()).WillRepeatedly(Return(true));
1411 EXPECT_CALL(item
, GetRemoteAddress()).WillRepeatedly(Return(remote_address
));
1413 EXPECT_CALL(*sb_service_
->mock_database_manager(),
1414 MatchDownloadWhitelistUrl(_
))
1415 .WillRepeatedly(Return(false));
1416 EXPECT_CALL(*binary_feature_extractor_
.get(), CheckSignature(tmp_path
, _
));
1417 EXPECT_CALL(*binary_feature_extractor_
.get(),
1418 ExtractImageFeatures(tmp_path
,
1419 BinaryFeatureExtractor::kDefaultOptions
,
1421 download_service_
->CheckClientDownload(
1423 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
1424 base::Unretained(this)));
1426 #if !defined(OS_WIN) && !defined(OS_MACOSX)
1427 // SendRequest is not called. Wait for FinishRequest to call our callback.
1428 MessageLoop::current()->Run();
1429 net::TestURLFetcher
* fetcher
= factory
.GetFetcherByID(0);
1430 EXPECT_EQ(NULL
, fetcher
);
1431 EXPECT_FALSE(HasClientDownloadRequest());
1433 // Run the message loop(s) until SendRequest is called.
1434 FlushThreadMessageLoops();
1435 EXPECT_TRUE(HasClientDownloadRequest());
1436 ClearClientDownloadRequest();
1437 net::TestURLFetcher
* fetcher
= factory
.GetFetcherByID(0);
1438 ASSERT_TRUE(fetcher
);
1439 ClientDownloadRequest request
;
1440 EXPECT_TRUE(request
.ParseFromString(fetcher
->upload_data()));
1441 EXPECT_EQ("ftp://www.google.com/bla.exe", request
.url());
1442 EXPECT_EQ(hash
, request
.digests().sha256());
1443 EXPECT_EQ(item
.GetReceivedBytes(), request
.length());
1444 EXPECT_EQ(item
.HasUserGesture(), request
.user_initiated());
1445 EXPECT_EQ(2, request
.resources_size());
1446 EXPECT_TRUE(RequestContainsResource(request
,
1447 ClientDownloadRequest::DOWNLOAD_REDIRECT
,
1448 "http://www.google.com/", ""));
1449 EXPECT_TRUE(RequestContainsResource(request
,
1450 ClientDownloadRequest::DOWNLOAD_URL
,
1451 "ftp://www.google.com/bla.exe",
1453 EXPECT_TRUE(request
.has_signature());
1454 EXPECT_EQ(0, request
.signature().certificate_chain_size());
1456 // Simulate the request finishing.
1457 base::MessageLoop::current()->PostTask(
1459 base::Bind(&DownloadProtectionServiceTest::SendURLFetchComplete
,
1460 base::Unretained(this), fetcher
));
1461 MessageLoop::current()->Run();
1465 // Similar to above, but with tab history.
1466 TEST_F(DownloadProtectionServiceTest
,
1467 CheckClientDownloadValidateRequestTabHistory
) {
1468 net::TestURLFetcherFactory factory
;
1470 base::ScopedTempDir profile_dir
;
1471 ASSERT_TRUE(profile_dir
.CreateUniqueTempDir());
1472 TestingProfile
profile(profile_dir
.path());
1474 profile
.CreateHistoryService(true /* delete_file */, false /* no_db */));
1476 base::FilePath
tmp_path(FILE_PATH_LITERAL("bla.tmp"));
1477 base::FilePath
final_path(FILE_PATH_LITERAL("bla.exe"));
1478 std::vector
<GURL
> url_chain
;
1479 url_chain
.push_back(GURL("http://www.google.com/"));
1480 url_chain
.push_back(GURL("http://www.google.com/bla.exe"));
1481 GURL
referrer("http://www.google.com/");
1482 GURL
tab_url("http://tab.com/final");
1483 GURL
tab_referrer("http://tab.com/referrer");
1484 std::string hash
= "hash";
1485 std::string remote_address
= "10.11.12.13";
1487 content::MockDownloadItem item
;
1488 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(tmp_path
));
1489 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(final_path
));
1490 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
1491 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
1492 EXPECT_CALL(item
, GetTabUrl()).WillRepeatedly(ReturnRef(tab_url
));
1493 EXPECT_CALL(item
, GetTabReferrerUrl())
1494 .WillRepeatedly(ReturnRef(tab_referrer
));
1495 EXPECT_CALL(item
, GetHash()).WillRepeatedly(ReturnRef(hash
));
1496 EXPECT_CALL(item
, GetReceivedBytes()).WillRepeatedly(Return(100));
1497 EXPECT_CALL(item
, HasUserGesture()).WillRepeatedly(Return(true));
1498 EXPECT_CALL(item
, GetRemoteAddress()).WillRepeatedly(Return(remote_address
));
1499 EXPECT_CALL(item
, GetBrowserContext()).WillRepeatedly(Return(&profile
));
1500 EXPECT_CALL(*sb_service_
->mock_database_manager(),
1501 MatchDownloadWhitelistUrl(_
))
1502 .WillRepeatedly(Return(false));
1503 EXPECT_CALL(*binary_feature_extractor_
.get(), CheckSignature(tmp_path
, _
))
1504 .WillRepeatedly(SetCertificateContents("dummy cert data"));
1506 *binary_feature_extractor_
.get(),
1507 ExtractImageFeatures(tmp_path
, BinaryFeatureExtractor::kDefaultOptions
,
1509 .WillRepeatedly(SetDosHeaderContents("dummy dos header"));
1511 // First test with no history match for the tab URL.
1513 TestURLFetcherWatcher
fetcher_watcher(&factory
);
1514 download_service_
->CheckClientDownload(
1516 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
1517 base::Unretained(this)));
1519 #if !defined(OS_WIN) && !defined(OS_MACOSX)
1520 // SendRequest is not called. Wait for FinishRequest to call our callback.
1521 MessageLoop::current()->Run();
1522 net::TestURLFetcher
* fetcher
= factory
.GetFetcherByID(0);
1523 EXPECT_EQ(NULL
, fetcher
);
1524 EXPECT_FALSE(HasClientDownloadRequest());
1526 EXPECT_EQ(0, fetcher_watcher
.WaitForRequest());
1527 EXPECT_TRUE(HasClientDownloadRequest());
1528 ClearClientDownloadRequest();
1529 net::TestURLFetcher
* fetcher
= factory
.GetFetcherByID(0);
1530 ASSERT_TRUE(fetcher
);
1531 ClientDownloadRequest request
;
1532 EXPECT_TRUE(request
.ParseFromString(fetcher
->upload_data()));
1533 EXPECT_EQ("http://www.google.com/bla.exe", request
.url());
1534 EXPECT_EQ(hash
, request
.digests().sha256());
1535 EXPECT_EQ(item
.GetReceivedBytes(), request
.length());
1536 EXPECT_EQ(item
.HasUserGesture(), request
.user_initiated());
1537 EXPECT_TRUE(RequestContainsServerIp(request
, remote_address
));
1538 EXPECT_EQ(3, request
.resources_size());
1540 RequestContainsResource(request
,
1541 ClientDownloadRequest::DOWNLOAD_REDIRECT
,
1542 "http://www.google.com/",
1544 EXPECT_TRUE(RequestContainsResource(request
,
1545 ClientDownloadRequest::DOWNLOAD_URL
,
1546 "http://www.google.com/bla.exe",
1548 EXPECT_TRUE(RequestContainsResource(request
,
1549 ClientDownloadRequest::TAB_URL
,
1551 tab_referrer
.spec()));
1552 EXPECT_TRUE(request
.has_signature());
1553 ASSERT_EQ(1, request
.signature().certificate_chain_size());
1554 const ClientDownloadRequest_CertificateChain
& chain
=
1555 request
.signature().certificate_chain(0);
1556 ASSERT_EQ(1, chain
.element_size());
1557 EXPECT_EQ("dummy cert data", chain
.element(0).certificate());
1558 EXPECT_TRUE(request
.has_image_headers());
1559 const ClientDownloadRequest_ImageHeaders
& headers
=
1560 request
.image_headers();
1561 EXPECT_TRUE(headers
.has_pe_headers());
1562 EXPECT_TRUE(headers
.pe_headers().has_dos_header());
1563 EXPECT_EQ("dummy dos header", headers
.pe_headers().dos_header());
1565 // Simulate the request finishing.
1566 base::MessageLoop::current()->PostTask(
1568 base::Bind(&DownloadProtectionServiceTest::SendURLFetchComplete
,
1569 base::Unretained(this),
1571 MessageLoop::current()->Run();
1575 // Now try with a history match.
1577 history::RedirectList redirects
;
1578 redirects
.push_back(GURL("http://tab.com/ref1"));
1579 redirects
.push_back(GURL("http://tab.com/ref2"));
1580 redirects
.push_back(tab_url
);
1581 HistoryServiceFactory::GetForProfile(&profile
,
1582 ServiceAccessType::EXPLICIT_ACCESS
)
1585 reinterpret_cast<history::ContextID
>(1),
1589 ui::PAGE_TRANSITION_TYPED
,
1590 history::SOURCE_BROWSED
,
1593 TestURLFetcherWatcher
fetcher_watcher(&factory
);
1594 download_service_
->CheckClientDownload(
1596 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
1597 base::Unretained(this)));
1598 #if !defined(OS_WIN) && !defined(OS_MACOSX)
1599 // SendRequest is not called. Wait for FinishRequest to call our callback.
1600 MessageLoop::current()->Run();
1601 net::TestURLFetcher
* fetcher
= factory
.GetFetcherByID(0);
1602 EXPECT_EQ(NULL
, fetcher
);
1603 EXPECT_FALSE(HasClientDownloadRequest());
1605 EXPECT_EQ(0, fetcher_watcher
.WaitForRequest());
1606 EXPECT_TRUE(HasClientDownloadRequest());
1607 ClearClientDownloadRequest();
1608 net::TestURLFetcher
* fetcher
= factory
.GetFetcherByID(0);
1609 ASSERT_TRUE(fetcher
);
1610 ClientDownloadRequest request
;
1611 EXPECT_TRUE(request
.ParseFromString(fetcher
->upload_data()));
1612 EXPECT_EQ("http://www.google.com/bla.exe", request
.url());
1613 EXPECT_EQ(hash
, request
.digests().sha256());
1614 EXPECT_EQ(item
.GetReceivedBytes(), request
.length());
1615 EXPECT_EQ(item
.HasUserGesture(), request
.user_initiated());
1616 EXPECT_TRUE(RequestContainsServerIp(request
, remote_address
));
1617 EXPECT_EQ(5, request
.resources_size());
1619 RequestContainsResource(request
,
1620 ClientDownloadRequest::DOWNLOAD_REDIRECT
,
1621 "http://www.google.com/",
1623 EXPECT_TRUE(RequestContainsResource(request
,
1624 ClientDownloadRequest::DOWNLOAD_URL
,
1625 "http://www.google.com/bla.exe",
1627 EXPECT_TRUE(RequestContainsResource(request
,
1628 ClientDownloadRequest::TAB_REDIRECT
,
1629 "http://tab.com/ref1",
1631 EXPECT_TRUE(RequestContainsResource(request
,
1632 ClientDownloadRequest::TAB_REDIRECT
,
1633 "http://tab.com/ref2",
1635 EXPECT_TRUE(RequestContainsResource(request
,
1636 ClientDownloadRequest::TAB_URL
,
1638 tab_referrer
.spec()));
1639 EXPECT_TRUE(request
.has_signature());
1640 ASSERT_EQ(1, request
.signature().certificate_chain_size());
1641 const ClientDownloadRequest_CertificateChain
& chain
=
1642 request
.signature().certificate_chain(0);
1643 ASSERT_EQ(1, chain
.element_size());
1644 EXPECT_EQ("dummy cert data", chain
.element(0).certificate());
1646 // Simulate the request finishing.
1647 base::MessageLoop::current()->PostTask(
1649 base::Bind(&DownloadProtectionServiceTest::SendURLFetchComplete
,
1650 base::Unretained(this),
1652 MessageLoop::current()->Run();
1657 TEST_F(DownloadProtectionServiceTest
, TestCheckDownloadUrl
) {
1658 std::vector
<GURL
> url_chain
;
1659 url_chain
.push_back(GURL("http://www.google.com/"));
1660 url_chain
.push_back(GURL("http://www.google.com/bla.exe"));
1661 GURL
referrer("http://www.google.com/");
1662 std::string hash
= "hash";
1664 content::MockDownloadItem item
;
1665 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
1666 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
1667 EXPECT_CALL(item
, GetHash()).WillRepeatedly(ReturnRef(hash
));
1669 // CheckDownloadURL returns immediately which means the client object callback
1670 // will never be called. Nevertheless the callback provided to
1671 // CheckClientDownload must still be called.
1672 EXPECT_CALL(*sb_service_
->mock_database_manager(),
1673 CheckDownloadUrl(ContainerEq(url_chain
), NotNull()))
1674 .WillOnce(Return(true));
1675 download_service_
->CheckDownloadUrl(
1677 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
1678 base::Unretained(this)));
1679 MessageLoop::current()->Run();
1680 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE
));
1681 Mock::VerifyAndClearExpectations(sb_service_
.get());
1683 EXPECT_CALL(*sb_service_
->mock_database_manager(),
1684 CheckDownloadUrl(ContainerEq(url_chain
), NotNull()))
1685 .WillOnce(DoAll(CheckDownloadUrlDone(SB_THREAT_TYPE_SAFE
),
1687 download_service_
->CheckDownloadUrl(
1689 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
1690 base::Unretained(this)));
1691 MessageLoop::current()->Run();
1692 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE
));
1693 Mock::VerifyAndClearExpectations(sb_service_
.get());
1695 EXPECT_CALL(*sb_service_
->mock_database_manager(),
1696 CheckDownloadUrl(ContainerEq(url_chain
), NotNull()))
1698 CheckDownloadUrlDone(SB_THREAT_TYPE_URL_MALWARE
),
1700 download_service_
->CheckDownloadUrl(
1702 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
1703 base::Unretained(this)));
1704 MessageLoop::current()->Run();
1705 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE
));
1706 Mock::VerifyAndClearExpectations(sb_service_
.get());
1708 EXPECT_CALL(*sb_service_
->mock_database_manager(),
1709 CheckDownloadUrl(ContainerEq(url_chain
),
1712 CheckDownloadUrlDone(SB_THREAT_TYPE_BINARY_MALWARE_URL
),
1714 download_service_
->CheckDownloadUrl(
1716 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
1717 base::Unretained(this)));
1718 MessageLoop::current()->Run();
1719 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS
));
1722 TEST_F(DownloadProtectionServiceTest
, TestDownloadRequestTimeout
) {
1723 net::TestURLFetcherFactory factory
;
1725 std::vector
<GURL
> url_chain
;
1726 url_chain
.push_back(GURL("http://www.evil.com/bla.exe"));
1727 GURL
referrer("http://www.google.com/");
1728 base::FilePath
tmp_path(FILE_PATH_LITERAL("a.tmp"));
1729 base::FilePath
final_path(FILE_PATH_LITERAL("a.exe"));
1730 std::string hash
= "hash";
1732 content::MockDownloadItem item
;
1733 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(tmp_path
));
1734 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(final_path
));
1735 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
1736 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
1737 EXPECT_CALL(item
, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
1738 EXPECT_CALL(item
, GetTabReferrerUrl())
1739 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
1740 EXPECT_CALL(item
, GetHash()).WillRepeatedly(ReturnRef(hash
));
1741 EXPECT_CALL(item
, GetReceivedBytes()).WillRepeatedly(Return(100));
1742 EXPECT_CALL(item
, HasUserGesture()).WillRepeatedly(Return(true));
1743 EXPECT_CALL(item
, GetRemoteAddress()).WillRepeatedly(Return(""));
1745 EXPECT_CALL(*sb_service_
->mock_database_manager(),
1746 MatchDownloadWhitelistUrl(_
))
1747 .WillRepeatedly(Return(false));
1748 EXPECT_CALL(*binary_feature_extractor_
.get(), CheckSignature(tmp_path
, _
));
1749 EXPECT_CALL(*binary_feature_extractor_
.get(),
1750 ExtractImageFeatures(tmp_path
,
1751 BinaryFeatureExtractor::kDefaultOptions
,
1754 download_service_
->download_request_timeout_ms_
= 10;
1755 download_service_
->CheckClientDownload(
1757 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
1758 base::Unretained(this)));
1760 // The request should time out because the HTTP request hasn't returned
1762 MessageLoop::current()->Run();
1763 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
1764 #if defined(OS_WIN) || defined(OS_MACOSX)
1765 EXPECT_TRUE(HasClientDownloadRequest());
1766 ClearClientDownloadRequest();
1768 EXPECT_FALSE(HasClientDownloadRequest());
1772 TEST_F(DownloadProtectionServiceTest
, TestDownloadItemDestroyed
) {
1773 net::TestURLFetcherFactory factory
;
1775 std::vector
<GURL
> url_chain
;
1776 url_chain
.push_back(GURL("http://www.evil.com/bla.exe"));
1777 GURL
referrer("http://www.google.com/");
1778 GURL
tab_url("http://www.google.com/tab");
1779 base::FilePath
tmp_path(FILE_PATH_LITERAL("a.tmp"));
1780 base::FilePath
final_path(FILE_PATH_LITERAL("a.exe"));
1781 std::string hash
= "hash";
1784 content::MockDownloadItem item
;
1785 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(tmp_path
));
1786 EXPECT_CALL(item
, GetTargetFilePath())
1787 .WillRepeatedly(ReturnRef(final_path
));
1788 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
1789 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
1790 EXPECT_CALL(item
, GetTabUrl()).WillRepeatedly(ReturnRef(tab_url
));
1791 EXPECT_CALL(item
, GetTabReferrerUrl())
1792 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
1793 EXPECT_CALL(item
, GetHash()).WillRepeatedly(ReturnRef(hash
));
1794 EXPECT_CALL(item
, GetReceivedBytes()).WillRepeatedly(Return(100));
1795 EXPECT_CALL(item
, HasUserGesture()).WillRepeatedly(Return(true));
1796 EXPECT_CALL(item
, GetRemoteAddress()).WillRepeatedly(Return(""));
1798 EXPECT_CALL(*sb_service_
->mock_database_manager(),
1799 MatchDownloadWhitelistUrl(_
))
1800 .WillRepeatedly(Return(false));
1801 EXPECT_CALL(*binary_feature_extractor_
.get(), CheckSignature(tmp_path
, _
));
1802 EXPECT_CALL(*binary_feature_extractor_
.get(),
1803 ExtractImageFeatures(
1804 tmp_path
, BinaryFeatureExtractor::kDefaultOptions
, _
, _
));
1806 download_service_
->CheckClientDownload(
1808 base::Bind(&DownloadProtectionServiceTest::SyncCheckDoneCallback
,
1809 base::Unretained(this)));
1810 // MockDownloadItem going out of scope triggers the OnDownloadDestroyed
1814 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
1815 EXPECT_FALSE(HasClientDownloadRequest());
1818 TEST_F(DownloadProtectionServiceTest
,
1819 TestDownloadItemDestroyedDuringWhitelistCheck
) {
1820 net::TestURLFetcherFactory factory
;
1822 std::vector
<GURL
> url_chain
;
1823 url_chain
.push_back(GURL("http://www.evil.com/bla.exe"));
1824 GURL
referrer("http://www.google.com/");
1825 GURL
tab_url("http://www.google.com/tab");
1826 base::FilePath
tmp_path(FILE_PATH_LITERAL("a.tmp"));
1827 base::FilePath
final_path(FILE_PATH_LITERAL("a.exe"));
1828 std::string hash
= "hash";
1830 scoped_ptr
<content::MockDownloadItem
> item(new content::MockDownloadItem
);
1831 EXPECT_CALL(*item
, GetFullPath()).WillRepeatedly(ReturnRef(tmp_path
));
1832 EXPECT_CALL(*item
, GetTargetFilePath())
1833 .WillRepeatedly(ReturnRef(final_path
));
1834 EXPECT_CALL(*item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
1835 EXPECT_CALL(*item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
1836 EXPECT_CALL(*item
, GetTabUrl()).WillRepeatedly(ReturnRef(tab_url
));
1837 EXPECT_CALL(*item
, GetTabReferrerUrl())
1838 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
1839 EXPECT_CALL(*item
, GetHash()).WillRepeatedly(ReturnRef(hash
));
1840 EXPECT_CALL(*item
, GetReceivedBytes()).WillRepeatedly(Return(100));
1841 EXPECT_CALL(*item
, HasUserGesture()).WillRepeatedly(Return(true));
1842 EXPECT_CALL(*item
, GetRemoteAddress()).WillRepeatedly(Return(""));
1844 EXPECT_CALL(*sb_service_
->mock_database_manager(),
1845 MatchDownloadWhitelistUrl(_
))
1846 .WillRepeatedly(Invoke([&item
](const GURL
&) {
1850 EXPECT_CALL(*binary_feature_extractor_
.get(), CheckSignature(tmp_path
, _
));
1851 EXPECT_CALL(*binary_feature_extractor_
.get(),
1852 ExtractImageFeatures(tmp_path
,
1853 BinaryFeatureExtractor::kDefaultOptions
,
1856 download_service_
->CheckClientDownload(
1858 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
1859 base::Unretained(this)));
1861 MessageLoop::current()->Run();
1862 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
1863 EXPECT_FALSE(HasClientDownloadRequest());
1866 TEST_F(DownloadProtectionServiceTest
, GetCertificateWhitelistStrings
) {
1867 // We'll pass this cert in as the "issuer", even though it isn't really
1868 // used to sign the certs below. GetCertificateWhitelistStirngs doesn't care
1870 scoped_refptr
<net::X509Certificate
> issuer_cert(
1871 ReadTestCertificate("issuer.pem"));
1872 ASSERT_TRUE(issuer_cert
.get());
1873 std::string cert_base
= "cert/" + base::HexEncode(
1874 issuer_cert
->fingerprint().data
,
1875 sizeof(issuer_cert
->fingerprint().data
));
1877 scoped_refptr
<net::X509Certificate
> cert(ReadTestCertificate("test_cn.pem"));
1878 ASSERT_TRUE(cert
.get());
1879 std::vector
<std::string
> whitelist_strings
;
1880 GetCertificateWhitelistStrings(
1881 *cert
.get(), *issuer_cert
.get(), &whitelist_strings
);
1882 // This also tests escaping of characters in the certificate attributes.
1883 EXPECT_THAT(whitelist_strings
, ElementsAre(
1884 cert_base
+ "/CN=subject%2F%251"));
1886 cert
= ReadTestCertificate("test_cn_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
,
1892 ElementsAre(cert_base
+ "/CN=subject",
1893 cert_base
+ "/CN=subject/O=org",
1894 cert_base
+ "/O=org"));
1896 cert
= ReadTestCertificate("test_cn_o_ou.pem");
1897 ASSERT_TRUE(cert
.get());
1898 whitelist_strings
.clear();
1899 GetCertificateWhitelistStrings(
1900 *cert
.get(), *issuer_cert
.get(), &whitelist_strings
);
1901 EXPECT_THAT(whitelist_strings
,
1902 ElementsAre(cert_base
+ "/CN=subject",
1903 cert_base
+ "/CN=subject/O=org",
1904 cert_base
+ "/CN=subject/O=org/OU=unit",
1905 cert_base
+ "/CN=subject/OU=unit",
1906 cert_base
+ "/O=org",
1907 cert_base
+ "/O=org/OU=unit",
1908 cert_base
+ "/OU=unit"));
1910 cert
= ReadTestCertificate("test_cn_ou.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
,
1916 ElementsAre(cert_base
+ "/CN=subject",
1917 cert_base
+ "/CN=subject/OU=unit",
1918 cert_base
+ "/OU=unit"));
1920 cert
= ReadTestCertificate("test_o.pem");
1921 ASSERT_TRUE(cert
.get());
1922 whitelist_strings
.clear();
1923 GetCertificateWhitelistStrings(
1924 *cert
.get(), *issuer_cert
.get(), &whitelist_strings
);
1925 EXPECT_THAT(whitelist_strings
, ElementsAre(cert_base
+ "/O=org"));
1927 cert
= ReadTestCertificate("test_o_ou.pem");
1928 ASSERT_TRUE(cert
.get());
1929 whitelist_strings
.clear();
1930 GetCertificateWhitelistStrings(
1931 *cert
.get(), *issuer_cert
.get(), &whitelist_strings
);
1932 EXPECT_THAT(whitelist_strings
,
1933 ElementsAre(cert_base
+ "/O=org",
1934 cert_base
+ "/O=org/OU=unit",
1935 cert_base
+ "/OU=unit"));
1937 cert
= ReadTestCertificate("test_ou.pem");
1938 ASSERT_TRUE(cert
.get());
1939 whitelist_strings
.clear();
1940 GetCertificateWhitelistStrings(
1941 *cert
.get(), *issuer_cert
.get(), &whitelist_strings
);
1942 EXPECT_THAT(whitelist_strings
, ElementsAre(cert_base
+ "/OU=unit"));
1944 cert
= ReadTestCertificate("test_c.pem");
1945 ASSERT_TRUE(cert
.get());
1946 whitelist_strings
.clear();
1947 GetCertificateWhitelistStrings(
1948 *cert
.get(), *issuer_cert
.get(), &whitelist_strings
);
1949 EXPECT_THAT(whitelist_strings
, ElementsAre());
1951 } // namespace safe_browsing