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"
11 #include "base/base_paths.h"
12 #include "base/bind.h"
13 #include "base/callback.h"
14 #include "base/files/file_path.h"
15 #include "base/files/file_util.h"
16 #include "base/files/scoped_temp_dir.h"
17 #include "base/memory/ref_counted.h"
18 #include "base/memory/scoped_ptr.h"
19 #include "base/message_loop/message_loop.h"
20 #include "base/path_service.h"
21 #include "base/run_loop.h"
22 #include "base/strings/string_number_conversions.h"
23 #include "base/threading/sequenced_worker_pool.h"
24 #include "chrome/browser/history/history_service_factory.h"
25 #include "chrome/browser/safe_browsing/database_manager.h"
26 #include "chrome/browser/safe_browsing/download_feedback_service.h"
27 #include "chrome/browser/safe_browsing/local_database_manager.h"
28 #include "chrome/browser/safe_browsing/safe_browsing_service.h"
29 #include "chrome/browser/safe_browsing/test_database_manager.h"
30 #include "chrome/common/safe_browsing/binary_feature_extractor.h"
31 #include "chrome/common/safe_browsing/csd.pb.h"
32 #include "chrome/test/base/testing_profile.h"
33 #include "components/history/core/browser/history_service.h"
34 #include "content/public/browser/download_danger_type.h"
35 #include "content/public/browser/page_navigator.h"
36 #include "content/public/test/mock_download_item.h"
37 #include "content/public/test/test_browser_thread_bundle.h"
38 #include "content/public/test/test_utils.h"
39 #include "net/base/url_util.h"
40 #include "net/cert/x509_certificate.h"
41 #include "net/http/http_status_code.h"
42 #include "net/url_request/test_url_fetcher_factory.h"
43 #include "net/url_request/url_fetcher_delegate.h"
44 #include "net/url_request/url_request_status.h"
45 #include "testing/gmock/include/gmock/gmock.h"
46 #include "testing/gtest/include/gtest/gtest.h"
47 #include "third_party/zlib/google/zip.h"
50 using ::testing::Assign
;
51 using ::testing::ContainerEq
;
52 using ::testing::DoAll
;
53 using ::testing::ElementsAre
;
54 using ::testing::Invoke
;
55 using ::testing::Mock
;
56 using ::testing::NotNull
;
57 using ::testing::Return
;
58 using ::testing::ReturnRef
;
59 using ::testing::SaveArg
;
60 using ::testing::StrictMock
;
62 using base::MessageLoop
;
63 using content::BrowserThread
;
64 namespace safe_browsing
{
66 // A SafeBrowsingDatabaseManager implementation that returns a fixed result for
68 class MockSafeBrowsingDatabaseManager
: public TestSafeBrowsingDatabaseManager
{
70 MockSafeBrowsingDatabaseManager() {}
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();
98 return mock_database_manager_
;
101 SafeBrowsingProtocolManagerDelegate
* GetProtocolManagerDelegate() override
{
102 // Our SafeBrowsingDatabaseManager doesn't implement this delegate.
106 void RegisterAllDelayedAnalysis() override
{}
109 MockSafeBrowsingDatabaseManager
* mock_database_manager_
;
111 DISALLOW_COPY_AND_ASSIGN(FakeSafeBrowsingService
);
114 class MockBinaryFeatureExtractor
: public BinaryFeatureExtractor
{
116 MockBinaryFeatureExtractor() {}
117 MOCK_METHOD2(CheckSignature
, void(const base::FilePath
&,
118 ClientDownloadRequest_SignatureInfo
*));
119 MOCK_METHOD4(ExtractImageFeatures
, bool(
120 const base::FilePath
&,
121 ExtractHeadersOption
,
122 ClientDownloadRequest_ImageHeaders
*,
123 google::protobuf::RepeatedPtrField
<std::string
>*));
126 virtual ~MockBinaryFeatureExtractor() {}
129 DISALLOW_COPY_AND_ASSIGN(MockBinaryFeatureExtractor
);
132 class TestURLFetcherWatcher
: public net::TestURLFetcherDelegateForTests
{
134 explicit TestURLFetcherWatcher(net::TestURLFetcherFactory
* factory
)
135 : factory_(factory
), fetcher_id_(-1) {
136 factory_
->SetDelegateForTests(this);
138 ~TestURLFetcherWatcher() {
139 factory_
->SetDelegateForTests(NULL
);
142 // TestURLFetcherDelegateForTests impl:
143 void OnRequestStart(int fetcher_id
) override
{
144 fetcher_id_
= fetcher_id
;
147 void OnChunkUpload(int fetcher_id
) override
{}
148 void OnRequestEnd(int fetcher_id
) override
{}
150 int WaitForRequest() {
156 net::TestURLFetcherFactory
* factory_
;
158 base::RunLoop run_loop_
;
162 ACTION_P(SetCertificateContents
, contents
) {
163 arg1
->add_certificate_chain()->add_element()->set_certificate(contents
);
166 ACTION_P(SetDosHeaderContents
, contents
) {
167 arg2
->mutable_pe_headers()->set_dos_header(contents
);
171 ACTION_P(TrustSignature
, certificate_file
) {
172 arg1
->set_trusted(true);
173 // Add a certificate chain. Note that we add the certificate twice so that
174 // it appears as its own issuer.
175 std::string cert_data
;
176 ASSERT_TRUE(base::ReadFileToString(certificate_file
, &cert_data
));
177 ClientDownloadRequest_CertificateChain
* chain
=
178 arg1
->add_certificate_chain();
179 chain
->add_element()->set_certificate(cert_data
);
180 chain
->add_element()->set_certificate(cert_data
);
183 // We can't call OnSafeBrowsingResult directly because SafeBrowsingCheck does
184 // not have any copy constructor which means it can't be stored in a callback
185 // easily. Note: check will be deleted automatically when the callback is
187 void OnSafeBrowsingResult(
188 LocalSafeBrowsingDatabaseManager::SafeBrowsingCheck
* check
) {
189 check
->OnSafeBrowsingResult();
192 ACTION_P(CheckDownloadUrlDone
, threat_type
) {
193 // TODO(nparker): Remove use of SafeBrowsingCheck and instead call
194 // client->OnCheckDownloadUrlResult(..) directly.
195 LocalSafeBrowsingDatabaseManager::SafeBrowsingCheck
* check
=
196 new LocalSafeBrowsingDatabaseManager::SafeBrowsingCheck(
198 std::vector
<SBFullHash
>(),
200 safe_browsing_util::BINURL
,
201 std::vector
<SBThreatType
>(1, SB_THREAT_TYPE_BINARY_MALWARE_URL
));
202 for (size_t i
= 0; i
< check
->url_results
.size(); ++i
)
203 check
->url_results
[i
] = threat_type
;
204 BrowserThread::PostTask(BrowserThread::IO
,
206 base::Bind(&OnSafeBrowsingResult
,
207 base::Owned(check
)));
210 class DownloadProtectionServiceTest
: public testing::Test
{
212 DownloadProtectionServiceTest()
213 : test_browser_thread_bundle_(
214 content::TestBrowserThreadBundle::IO_MAINLOOP
) {
216 void SetUp() override
{
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 static const ClientDownloadRequest_ArchivedBinary
* GetRequestArchivedBinary(
283 const ClientDownloadRequest
& request
,
284 const std::string
& file_basename
) {
285 for (const auto& archived_binary
: request
.archived_binary()) {
286 if (archived_binary
.file_basename() == file_basename
)
287 return &archived_binary
;
292 // Flushes any pending tasks in the message loops of all threads.
293 void FlushThreadMessageLoops() {
294 BrowserThread::GetBlockingPool()->FlushForTesting();
295 FlushMessageLoop(BrowserThread::IO
);
296 base::RunLoop().RunUntilIdle();
299 // Proxy for private method.
300 static void GetCertificateWhitelistStrings(
301 const net::X509Certificate
& certificate
,
302 const net::X509Certificate
& issuer
,
303 std::vector
<std::string
>* whitelist_strings
) {
304 DownloadProtectionService::GetCertificateWhitelistStrings(
305 certificate
, issuer
, whitelist_strings
);
308 // Reads a single PEM-encoded certificate from the testdata directory.
309 // Returns NULL on failure.
310 scoped_refptr
<net::X509Certificate
> ReadTestCertificate(
311 const std::string
& filename
) {
312 std::string cert_data
;
313 if (!base::ReadFileToString(testdata_path_
.AppendASCII(filename
),
317 net::CertificateList certs
=
318 net::X509Certificate::CreateCertificateListFromBytes(
321 net::X509Certificate::FORMAT_PEM_CERT_SEQUENCE
);
322 return certs
.empty() ? NULL
: certs
[0];
325 const ClientDownloadRequest
* GetClientDownloadRequest() const {
326 return last_client_download_request_
.get();
329 bool HasClientDownloadRequest() const {
330 return last_client_download_request_
.get() != NULL
;
333 void ClearClientDownloadRequest() { last_client_download_request_
.reset(); }
336 // Helper functions for FlushThreadMessageLoops.
337 void RunAllPendingAndQuitUI() {
338 base::MessageLoop::current()->RunUntilIdle();
339 BrowserThread::PostTask(
342 base::Bind(&DownloadProtectionServiceTest::QuitMessageLoop
,
343 base::Unretained(this)));
346 void QuitMessageLoop() {
347 base::MessageLoop::current()->Quit();
350 void PostRunMessageLoopTask(BrowserThread::ID thread
) {
351 BrowserThread::PostTask(
354 base::Bind(&DownloadProtectionServiceTest::RunAllPendingAndQuitUI
,
355 base::Unretained(this)));
358 void FlushMessageLoop(BrowserThread::ID thread
) {
359 BrowserThread::PostTask(
362 base::Bind(&DownloadProtectionServiceTest::PostRunMessageLoopTask
,
363 base::Unretained(this), thread
));
364 MessageLoop::current()->Run();
367 void OnClientDownloadRequest(content::DownloadItem
* download
,
368 const ClientDownloadRequest
* request
) {
370 last_client_download_request_
.reset(new ClientDownloadRequest(*request
));
372 last_client_download_request_
.reset();
376 void CheckDoneCallback(
377 DownloadProtectionService::DownloadCheckResult result
) {
380 MessageLoop::current()->Quit();
383 void SyncCheckDoneCallback(
384 DownloadProtectionService::DownloadCheckResult result
) {
389 void SendURLFetchComplete(net::TestURLFetcher
* fetcher
) {
390 fetcher
->delegate()->OnURLFetchComplete(fetcher
);
393 testing::AssertionResult
IsResult(
394 DownloadProtectionService::DownloadCheckResult expected
) {
396 return testing::AssertionFailure() << "No result";
398 return result_
== expected
?
399 testing::AssertionSuccess() :
400 testing::AssertionFailure() << "Expected " << expected
<<
405 scoped_refptr
<FakeSafeBrowsingService
> sb_service_
;
406 scoped_refptr
<MockBinaryFeatureExtractor
> binary_feature_extractor_
;
407 DownloadProtectionService
* download_service_
;
408 DownloadProtectionService::DownloadCheckResult result_
;
410 content::TestBrowserThreadBundle test_browser_thread_bundle_
;
411 content::InProcessUtilityThreadHelper in_process_utility_thread_helper_
;
412 base::FilePath testdata_path_
;
413 DownloadProtectionService::ClientDownloadRequestSubscription
414 client_download_request_subscription_
;
415 scoped_ptr
<ClientDownloadRequest
> last_client_download_request_
;
418 TEST_F(DownloadProtectionServiceTest
, CheckClientDownloadInvalidUrl
) {
419 base::FilePath
a_tmp(FILE_PATH_LITERAL("a.tmp"));
420 base::FilePath
a_exe(FILE_PATH_LITERAL("a.exe"));
421 std::vector
<GURL
> url_chain
;
422 GURL
referrer("http://www.google.com/");
424 content::MockDownloadItem item
;
425 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp
));
426 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_exe
));
427 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
428 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
429 EXPECT_CALL(item
, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
430 EXPECT_CALL(item
, GetTabReferrerUrl())
431 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
432 download_service_
->CheckClientDownload(
434 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
435 base::Unretained(this)));
436 MessageLoop::current()->Run();
437 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
438 EXPECT_FALSE(HasClientDownloadRequest());
439 Mock::VerifyAndClearExpectations(&item
);
441 url_chain
.push_back(GURL("file://www.google.com/"));
442 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp
));
443 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_exe
));
444 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
445 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
446 EXPECT_CALL(item
, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
447 EXPECT_CALL(item
, GetTabReferrerUrl())
448 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
449 download_service_
->CheckClientDownload(
451 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
452 base::Unretained(this)));
453 MessageLoop::current()->Run();
454 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
455 EXPECT_FALSE(HasClientDownloadRequest());
458 TEST_F(DownloadProtectionServiceTest
, CheckClientDownloadNotABinary
) {
459 base::FilePath
a_tmp(FILE_PATH_LITERAL("a.tmp"));
460 base::FilePath
a_txt(FILE_PATH_LITERAL("a.txt"));
461 std::vector
<GURL
> url_chain
;
462 GURL
referrer("http://www.google.com/");
464 content::MockDownloadItem item
;
465 url_chain
.push_back(GURL("http://www.example.com/foo"));
466 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp
));
467 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_txt
));
468 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
469 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
470 EXPECT_CALL(item
, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
471 EXPECT_CALL(item
, GetTabReferrerUrl())
472 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
473 download_service_
->CheckClientDownload(
475 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
476 base::Unretained(this)));
477 MessageLoop::current()->Run();
478 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
479 EXPECT_FALSE(HasClientDownloadRequest());
482 TEST_F(DownloadProtectionServiceTest
, CheckClientDownloadWhitelistedUrl
) {
483 // Response to any requests will be DANGEROUS.
484 ClientDownloadResponse response
;
485 response
.set_verdict(ClientDownloadResponse::DANGEROUS
);
486 net::FakeURLFetcherFactory
factory(NULL
);
487 factory
.SetFakeResponse(
488 DownloadProtectionService::GetDownloadRequestUrl(),
489 response
.SerializeAsString(),
490 net::HTTP_OK
, net::URLRequestStatus::SUCCESS
);
492 std::string hash
= "hash";
493 base::FilePath
a_tmp(FILE_PATH_LITERAL("a.tmp"));
494 base::FilePath
a_exe(FILE_PATH_LITERAL("a.exe"));
495 std::vector
<GURL
> url_chain
;
498 content::MockDownloadItem item
;
499 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp
));
500 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_exe
));
501 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
502 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
503 EXPECT_CALL(item
, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
504 EXPECT_CALL(item
, GetTabReferrerUrl())
505 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
506 EXPECT_CALL(item
, GetHash()).WillRepeatedly(ReturnRef(hash
));
507 EXPECT_CALL(item
, GetReceivedBytes()).WillRepeatedly(Return(100));
508 EXPECT_CALL(item
, HasUserGesture()).WillRepeatedly(Return(true));
509 EXPECT_CALL(item
, GetRemoteAddress()).WillRepeatedly(Return(""));
510 EXPECT_CALL(*binary_feature_extractor_
.get(), CheckSignature(a_tmp
, _
))
512 EXPECT_CALL(*binary_feature_extractor_
.get(),
513 ExtractImageFeatures(
514 a_tmp
, BinaryFeatureExtractor::kDefaultOptions
, _
, _
))
517 // We should not get whilelist checks for other URLs than specified below.
518 EXPECT_CALL(*sb_service_
->mock_database_manager(),
519 MatchDownloadWhitelistUrl(_
)).Times(0);
520 EXPECT_CALL(*sb_service_
->mock_database_manager(),
521 MatchDownloadWhitelistUrl(GURL("http://www.evil.com/bla.exe")))
522 .WillRepeatedly(Return(false));
523 EXPECT_CALL(*sb_service_
->mock_database_manager(),
524 MatchDownloadWhitelistUrl(GURL("http://www.google.com/a.exe")))
525 .WillRepeatedly(Return(true));
527 // With no referrer and just the bad url, should be marked DANGEROUS.
528 url_chain
.push_back(GURL("http://www.evil.com/bla.exe"));
529 download_service_
->CheckClientDownload(
531 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
532 base::Unretained(this)));
533 MessageLoop::current()->Run();
535 #if defined(OS_WIN) || defined(OS_MACOSX)
536 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS
));
537 EXPECT_TRUE(HasClientDownloadRequest());
538 ClearClientDownloadRequest();
540 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
541 EXPECT_FALSE(HasClientDownloadRequest());
544 // Check that the referrer is not matched against the whitelist.
545 referrer
= GURL("http://www.google.com/");
546 download_service_
->CheckClientDownload(
548 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
549 base::Unretained(this)));
550 MessageLoop::current()->Run();
552 #if defined(OS_WIN) || defined(OS_MACOSX)
553 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS
));
554 EXPECT_TRUE(HasClientDownloadRequest());
555 ClearClientDownloadRequest();
557 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
558 EXPECT_FALSE(HasClientDownloadRequest());
561 // Redirect from a site shouldn't be checked either.
562 url_chain
.insert(url_chain
.begin(), GURL("http://www.google.com/redirect"));
563 download_service_
->CheckClientDownload(
565 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
566 base::Unretained(this)));
567 MessageLoop::current()->Run();
569 #if defined(OS_WIN) || defined(OS_MACOSX)
570 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS
));
571 EXPECT_TRUE(HasClientDownloadRequest());
572 ClearClientDownloadRequest();
574 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
575 EXPECT_FALSE(HasClientDownloadRequest());
578 // Only if the final url is whitelisted should it be SAFE.
579 url_chain
.push_back(GURL("http://www.google.com/a.exe"));
580 download_service_
->CheckClientDownload(
582 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
583 base::Unretained(this)));
584 MessageLoop::current()->Run();
585 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE
));
586 // TODO(grt): Make the service produce the request even when the URL is
588 EXPECT_FALSE(HasClientDownloadRequest());
591 TEST_F(DownloadProtectionServiceTest
, CheckClientDownloadFetchFailed
) {
592 net::FakeURLFetcherFactory
factory(NULL
);
593 // HTTP request will fail.
594 factory
.SetFakeResponse(
595 DownloadProtectionService::GetDownloadRequestUrl(), std::string(),
596 net::HTTP_INTERNAL_SERVER_ERROR
, net::URLRequestStatus::FAILED
);
598 base::FilePath
a_tmp(FILE_PATH_LITERAL("a.tmp"));
599 base::FilePath
a_exe(FILE_PATH_LITERAL("a.exe"));
600 std::vector
<GURL
> url_chain
;
601 url_chain
.push_back(GURL("http://www.evil.com/a.exe"));
602 GURL
referrer("http://www.google.com/");
603 std::string hash
= "hash";
605 content::MockDownloadItem item
;
606 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp
));
607 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_exe
));
608 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
609 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
610 EXPECT_CALL(item
, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
611 EXPECT_CALL(item
, GetTabReferrerUrl())
612 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
613 EXPECT_CALL(item
, GetHash()).WillRepeatedly(ReturnRef(hash
));
614 EXPECT_CALL(item
, GetReceivedBytes()).WillRepeatedly(Return(100));
615 EXPECT_CALL(item
, HasUserGesture()).WillRepeatedly(Return(true));
616 EXPECT_CALL(item
, GetRemoteAddress()).WillRepeatedly(Return(""));
618 EXPECT_CALL(*sb_service_
->mock_database_manager(),
619 MatchDownloadWhitelistUrl(_
))
620 .WillRepeatedly(Return(false));
621 EXPECT_CALL(*binary_feature_extractor_
.get(), CheckSignature(a_tmp
, _
));
623 *binary_feature_extractor_
.get(),
624 ExtractImageFeatures(a_tmp
, BinaryFeatureExtractor::kDefaultOptions
,
627 download_service_
->CheckClientDownload(
629 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
630 base::Unretained(this)));
631 MessageLoop::current()->Run();
632 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
635 TEST_F(DownloadProtectionServiceTest
, CheckClientDownloadSuccess
) {
636 ClientDownloadResponse response
;
637 response
.set_verdict(ClientDownloadResponse::SAFE
);
638 net::FakeURLFetcherFactory
factory(NULL
);
639 // Empty response means SAFE.
640 factory
.SetFakeResponse(
641 DownloadProtectionService::GetDownloadRequestUrl(),
642 response
.SerializeAsString(),
643 net::HTTP_OK
, net::URLRequestStatus::SUCCESS
);
645 base::FilePath
a_tmp(FILE_PATH_LITERAL("a.tmp"));
646 base::FilePath
a_exe(FILE_PATH_LITERAL("a.exe"));
647 std::vector
<GURL
> url_chain
;
648 url_chain
.push_back(GURL("http://www.evil.com/a.exe"));
649 GURL
referrer("http://www.google.com/");
650 std::string hash
= "hash";
652 content::MockDownloadItem item
;
653 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp
));
654 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_exe
));
655 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
656 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
657 EXPECT_CALL(item
, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
658 EXPECT_CALL(item
, GetTabReferrerUrl())
659 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
660 EXPECT_CALL(item
, GetHash()).WillRepeatedly(ReturnRef(hash
));
661 EXPECT_CALL(item
, GetReceivedBytes()).WillRepeatedly(Return(100));
662 EXPECT_CALL(item
, HasUserGesture()).WillRepeatedly(Return(true));
663 EXPECT_CALL(item
, GetRemoteAddress()).WillRepeatedly(Return(""));
665 EXPECT_CALL(*sb_service_
->mock_database_manager(),
666 MatchDownloadWhitelistUrl(_
))
667 .WillRepeatedly(Return(false));
668 EXPECT_CALL(*binary_feature_extractor_
.get(), CheckSignature(a_tmp
, _
))
670 EXPECT_CALL(*binary_feature_extractor_
.get(),
671 ExtractImageFeatures(
672 a_tmp
, BinaryFeatureExtractor::kDefaultOptions
, _
, _
))
675 download_service_
->CheckClientDownload(
677 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
678 base::Unretained(this)));
679 MessageLoop::current()->Run();
681 #if defined(OS_WIN) || defined(OS_MACOSX)
682 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE
));
683 EXPECT_TRUE(HasClientDownloadRequest());
684 ClearClientDownloadRequest();
686 // On !(OS_WIN || OS_MACOSX), no file types are currently supported. Hence all
687 // requests to CheckClientDownload() result in a verdict of UNKNOWN.
688 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
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 #if defined(OS_WIN) || defined(OS_MACOSX)
732 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS
));
733 EXPECT_TRUE(HasClientDownloadRequest());
734 ClearClientDownloadRequest();
736 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
737 EXPECT_FALSE(HasClientDownloadRequest());
740 // If the response is uncommon the result should also be marked as uncommon.
741 response
.set_verdict(ClientDownloadResponse::UNCOMMON
);
742 factory
.SetFakeResponse(
743 DownloadProtectionService::GetDownloadRequestUrl(),
744 response
.SerializeAsString(),
745 net::HTTP_OK
, net::URLRequestStatus::SUCCESS
);
747 download_service_
->CheckClientDownload(
749 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
750 base::Unretained(this)));
751 MessageLoop::current()->Run();
752 #if defined(OS_WIN) || defined(OS_MACOSX)
753 EXPECT_TRUE(IsResult(DownloadProtectionService::UNCOMMON
));
754 EXPECT_TRUE(DownloadFeedbackService::GetPingsForDownloadForTesting(
755 item
, &feedback_ping
, &feedback_response
));
756 ClientDownloadRequest decoded_request
;
757 EXPECT_TRUE(decoded_request
.ParseFromString(feedback_ping
));
758 EXPECT_EQ(url_chain
.back().spec(), decoded_request
.url());
759 EXPECT_EQ(response
.SerializeAsString(), feedback_response
);
760 EXPECT_TRUE(HasClientDownloadRequest());
761 ClearClientDownloadRequest();
763 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
766 // If the response is dangerous_host the result should also be marked as
768 response
.set_verdict(ClientDownloadResponse::DANGEROUS_HOST
);
769 factory
.SetFakeResponse(
770 DownloadProtectionService::GetDownloadRequestUrl(),
771 response
.SerializeAsString(),
772 net::HTTP_OK
, net::URLRequestStatus::SUCCESS
);
774 download_service_
->CheckClientDownload(
776 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
777 base::Unretained(this)));
778 MessageLoop::current()->Run();
779 #if defined(OS_WIN) || defined(OS_MACOSX)
780 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS_HOST
));
781 EXPECT_TRUE(DownloadFeedbackService::GetPingsForDownloadForTesting(
782 item
, &feedback_ping
, &feedback_response
));
783 EXPECT_EQ(response
.SerializeAsString(), feedback_response
);
784 EXPECT_TRUE(HasClientDownloadRequest());
785 ClearClientDownloadRequest();
787 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
790 // If the response is POTENTIALLY_UNWANTED the result should also be marked as
791 // POTENTIALLY_UNWANTED.
792 response
.set_verdict(ClientDownloadResponse::POTENTIALLY_UNWANTED
);
793 factory
.SetFakeResponse(
794 DownloadProtectionService::GetDownloadRequestUrl(),
795 response
.SerializeAsString(),
796 net::HTTP_OK
, net::URLRequestStatus::SUCCESS
);
798 download_service_
->CheckClientDownload(
800 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
801 base::Unretained(this)));
802 MessageLoop::current()->Run();
804 #if defined(OS_WIN) || defined(OS_MACOSX)
805 EXPECT_TRUE(IsResult(DownloadProtectionService::POTENTIALLY_UNWANTED
));
806 EXPECT_TRUE(HasClientDownloadRequest());
807 ClearClientDownloadRequest();
809 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
810 EXPECT_FALSE(HasClientDownloadRequest());
814 TEST_F(DownloadProtectionServiceTest
, CheckClientDownloadHTTPS
) {
815 ClientDownloadResponse response
;
816 response
.set_verdict(ClientDownloadResponse::DANGEROUS
);
817 net::FakeURLFetcherFactory
factory(NULL
);
818 factory
.SetFakeResponse(
819 DownloadProtectionService::GetDownloadRequestUrl(),
820 response
.SerializeAsString(),
821 net::HTTP_OK
, net::URLRequestStatus::SUCCESS
);
823 base::FilePath
a_tmp(FILE_PATH_LITERAL("a.tmp"));
824 base::FilePath
a_exe(FILE_PATH_LITERAL("a.exe"));
825 std::vector
<GURL
> url_chain
;
826 url_chain
.push_back(GURL("http://www.evil.com/a.exe"));
827 GURL
referrer("http://www.google.com/");
828 std::string hash
= "hash";
830 content::MockDownloadItem item
;
831 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp
));
832 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_exe
));
833 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
834 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
835 EXPECT_CALL(item
, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
836 EXPECT_CALL(item
, GetTabReferrerUrl())
837 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
838 EXPECT_CALL(item
, GetHash()).WillRepeatedly(ReturnRef(hash
));
839 EXPECT_CALL(item
, GetReceivedBytes()).WillRepeatedly(Return(100));
840 EXPECT_CALL(item
, HasUserGesture()).WillRepeatedly(Return(true));
841 EXPECT_CALL(item
, GetRemoteAddress()).WillRepeatedly(Return(""));
843 EXPECT_CALL(*sb_service_
->mock_database_manager(),
844 MatchDownloadWhitelistUrl(_
))
845 .WillRepeatedly(Return(false));
846 EXPECT_CALL(*binary_feature_extractor_
.get(), CheckSignature(a_tmp
, _
))
848 EXPECT_CALL(*binary_feature_extractor_
.get(),
849 ExtractImageFeatures(
850 a_tmp
, BinaryFeatureExtractor::kDefaultOptions
, _
, _
))
853 download_service_
->CheckClientDownload(
855 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
856 base::Unretained(this)));
857 MessageLoop::current()->Run();
859 #if defined(OS_WIN) || defined(OS_MACOSX)
860 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS
));
861 EXPECT_TRUE(HasClientDownloadRequest());
862 ClearClientDownloadRequest();
864 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
865 EXPECT_FALSE(HasClientDownloadRequest());
869 TEST_F(DownloadProtectionServiceTest
, CheckClientDownloadBlob
) {
870 ClientDownloadResponse response
;
871 response
.set_verdict(ClientDownloadResponse::DANGEROUS
);
872 net::FakeURLFetcherFactory
factory(NULL
);
873 factory
.SetFakeResponse(DownloadProtectionService::GetDownloadRequestUrl(),
874 response
.SerializeAsString(), net::HTTP_OK
,
875 net::URLRequestStatus::SUCCESS
);
877 base::FilePath
a_tmp(FILE_PATH_LITERAL("a.tmp"));
878 base::FilePath
a_exe(FILE_PATH_LITERAL("a.exe"));
879 std::vector
<GURL
> url_chain
;
881 GURL("blob:http://www.evil.com/50b85f60-71e4-11e4-82f8-0800200c9a66"));
882 GURL
referrer("http://www.google.com/");
883 std::string hash
= "hash";
885 content::MockDownloadItem item
;
886 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp
));
887 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_exe
));
888 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
889 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
890 EXPECT_CALL(item
, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
891 EXPECT_CALL(item
, GetTabReferrerUrl())
892 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
893 EXPECT_CALL(item
, GetHash()).WillRepeatedly(ReturnRef(hash
));
894 EXPECT_CALL(item
, GetReceivedBytes()).WillRepeatedly(Return(100));
895 EXPECT_CALL(item
, HasUserGesture()).WillRepeatedly(Return(true));
896 EXPECT_CALL(item
, GetRemoteAddress()).WillRepeatedly(Return(""));
898 EXPECT_CALL(*sb_service_
->mock_database_manager(),
899 MatchDownloadWhitelistUrl(_
)).WillRepeatedly(Return(false));
900 EXPECT_CALL(*binary_feature_extractor_
.get(), CheckSignature(a_tmp
, _
))
902 EXPECT_CALL(*binary_feature_extractor_
.get(),
903 ExtractImageFeatures(
904 a_tmp
, BinaryFeatureExtractor::kDefaultOptions
, _
, _
))
907 download_service_
->CheckClientDownload(
909 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
910 base::Unretained(this)));
911 MessageLoop::current()->Run();
913 #if defined(OS_WIN) || defined(OS_MACOSX)
914 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS
));
915 EXPECT_TRUE(HasClientDownloadRequest());
916 ClearClientDownloadRequest();
918 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
919 EXPECT_FALSE(HasClientDownloadRequest());
923 TEST_F(DownloadProtectionServiceTest
, CheckClientDownloadData
) {
924 ClientDownloadResponse response
;
925 response
.set_verdict(ClientDownloadResponse::DANGEROUS
);
926 net::FakeURLFetcherFactory
factory(NULL
);
927 factory
.SetFakeResponse(DownloadProtectionService::GetDownloadRequestUrl(),
928 response
.SerializeAsString(), net::HTTP_OK
,
929 net::URLRequestStatus::SUCCESS
);
931 base::FilePath
a_tmp(FILE_PATH_LITERAL("a.tmp"));
932 base::FilePath
a_exe(FILE_PATH_LITERAL("a.exe"));
933 std::vector
<GURL
> url_chain
;
935 GURL("data:text/html:base64,"));
937 GURL("data:text/html:base64,blahblahblah"));
939 GURL("data:application/octet-stream:base64,blahblah"));
940 GURL
referrer("data:text/html:base64,foobar");
941 std::string hash
= "hash";
943 content::MockDownloadItem item
;
944 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp
));
945 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_exe
));
946 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
947 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
948 EXPECT_CALL(item
, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
949 EXPECT_CALL(item
, GetTabReferrerUrl())
950 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
951 EXPECT_CALL(item
, GetHash()).WillRepeatedly(ReturnRef(hash
));
952 EXPECT_CALL(item
, GetReceivedBytes()).WillRepeatedly(Return(100));
953 EXPECT_CALL(item
, HasUserGesture()).WillRepeatedly(Return(true));
954 EXPECT_CALL(item
, GetRemoteAddress()).WillRepeatedly(Return(""));
956 EXPECT_CALL(*sb_service_
->mock_database_manager(),
957 MatchDownloadWhitelistUrl(_
)).WillRepeatedly(Return(false));
958 EXPECT_CALL(*binary_feature_extractor_
.get(), CheckSignature(a_tmp
, _
))
960 EXPECT_CALL(*binary_feature_extractor_
.get(),
961 ExtractImageFeatures(
962 a_tmp
, BinaryFeatureExtractor::kDefaultOptions
, _
, _
))
965 download_service_
->CheckClientDownload(
967 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
968 base::Unretained(this)));
969 MessageLoop::current()->Run();
971 #if defined(OS_WIN) || defined(OS_MACOSX)
972 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS
));
973 ASSERT_TRUE(HasClientDownloadRequest());
974 const ClientDownloadRequest
& request
= *GetClientDownloadRequest();
975 const char kExpectedUrl
[] =
976 "data:application/octet-stream:base64,"
977 "ACBF6DFC6F907662F566CA0241DFE8690C48661F440BA1BBD0B86C582845CCC8";
978 const char kExpectedRedirect1
[] = "data:text/html:base64,";
979 const char kExpectedRedirect2
[] =
980 "data:text/html:base64,"
981 "620680767E15717A57DB11D94D1BEBD32B3344EBC5994DF4FB07B0D473F4EF6B";
982 const char kExpectedReferrer
[] =
983 "data:text/html:base64,"
984 "06E2C655B9F7130B508FFF86FD19B57E6BF1A1CFEFD6EFE1C3EB09FE24EF456A";
985 EXPECT_EQ(hash
, request
.digests().sha256());
986 EXPECT_EQ(kExpectedUrl
, request
.url());
987 EXPECT_EQ(3, request
.resources_size());
988 EXPECT_TRUE(RequestContainsResource(request
,
989 ClientDownloadRequest::DOWNLOAD_REDIRECT
,
990 kExpectedRedirect1
, ""));
991 EXPECT_TRUE(RequestContainsResource(request
,
992 ClientDownloadRequest::DOWNLOAD_REDIRECT
,
993 kExpectedRedirect2
, ""));
994 EXPECT_TRUE(RequestContainsResource(request
,
995 ClientDownloadRequest::DOWNLOAD_URL
,
996 kExpectedUrl
, kExpectedReferrer
));
997 ClearClientDownloadRequest();
999 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
1000 EXPECT_FALSE(HasClientDownloadRequest());
1004 TEST_F(DownloadProtectionServiceTest
, CheckClientDownloadZip
) {
1005 ClientDownloadResponse response
;
1006 response
.set_verdict(ClientDownloadResponse::SAFE
);
1007 net::FakeURLFetcherFactory
factory(NULL
);
1008 // Empty response means SAFE.
1009 factory
.SetFakeResponse(
1010 DownloadProtectionService::GetDownloadRequestUrl(),
1011 response
.SerializeAsString(),
1012 net::HTTP_OK
, net::URLRequestStatus::SUCCESS
);
1014 base::ScopedTempDir download_dir
;
1015 ASSERT_TRUE(download_dir
.CreateUniqueTempDir());
1017 base::FilePath
a_tmp(download_dir
.path().Append(FILE_PATH_LITERAL("a.tmp")));
1018 base::FilePath
a_zip(FILE_PATH_LITERAL("a.zip"));
1019 std::vector
<GURL
> url_chain
;
1020 url_chain
.push_back(GURL("http://www.evil.com/a.zip"));
1021 GURL
referrer("http://www.google.com/");
1022 std::string hash
= "hash";
1024 content::MockDownloadItem item
;
1025 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp
));
1026 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_zip
));
1027 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
1028 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
1029 EXPECT_CALL(item
, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
1030 EXPECT_CALL(item
, GetTabReferrerUrl())
1031 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
1032 EXPECT_CALL(item
, GetHash()).WillRepeatedly(ReturnRef(hash
));
1033 EXPECT_CALL(item
, GetReceivedBytes()).WillRepeatedly(Return(100));
1034 EXPECT_CALL(item
, HasUserGesture()).WillRepeatedly(Return(true));
1035 EXPECT_CALL(item
, GetRemoteAddress()).WillRepeatedly(Return(""));
1037 // Write out a zip archive to the temporary file. In this case, it
1038 // only contains a text file.
1039 base::ScopedTempDir zip_source_dir
;
1040 ASSERT_TRUE(zip_source_dir
.CreateUniqueTempDir());
1041 std::string file_contents
= "dummy file";
1042 ASSERT_EQ(static_cast<int>(file_contents
.size()), base::WriteFile(
1043 zip_source_dir
.path().Append(FILE_PATH_LITERAL("file.txt")),
1044 file_contents
.data(), file_contents
.size()));
1045 ASSERT_TRUE(zip::Zip(zip_source_dir
.path(), a_tmp
, false));
1047 download_service_
->CheckClientDownload(
1049 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
1050 base::Unretained(this)));
1051 MessageLoop::current()->Run();
1052 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
1053 EXPECT_FALSE(HasClientDownloadRequest());
1054 Mock::VerifyAndClearExpectations(sb_service_
.get());
1055 Mock::VerifyAndClearExpectations(binary_feature_extractor_
.get());
1057 // Now check with an executable in the zip file as well.
1058 ASSERT_EQ(static_cast<int>(file_contents
.size()), base::WriteFile(
1059 zip_source_dir
.path().Append(FILE_PATH_LITERAL("file.exe")),
1060 file_contents
.data(), file_contents
.size()));
1061 ASSERT_TRUE(zip::Zip(zip_source_dir
.path(), a_tmp
, false));
1063 EXPECT_CALL(*sb_service_
->mock_database_manager(),
1064 MatchDownloadWhitelistUrl(_
))
1065 .WillRepeatedly(Return(false));
1067 download_service_
->CheckClientDownload(
1069 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
1070 base::Unretained(this)));
1071 MessageLoop::current()->Run();
1073 #if defined(OS_WIN) || defined(OS_MACOSX)
1074 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE
));
1075 EXPECT_TRUE(HasClientDownloadRequest());
1076 const ClientDownloadRequest
& request
= *GetClientDownloadRequest();
1077 EXPECT_TRUE(request
.has_download_type());
1078 EXPECT_EQ(ClientDownloadRequest_DownloadType_ZIPPED_EXECUTABLE
,
1079 request
.download_type());
1080 EXPECT_EQ(1, request
.archived_binary_size());
1081 const ClientDownloadRequest_ArchivedBinary
* archived_binary
=
1082 GetRequestArchivedBinary(request
, "file.exe");
1083 ASSERT_NE(nullptr, archived_binary
);
1084 EXPECT_EQ(ClientDownloadRequest_DownloadType_WIN_EXECUTABLE
,
1085 archived_binary
->download_type());
1086 EXPECT_EQ(static_cast<int64_t>(file_contents
.size()),
1087 archived_binary
->length());
1088 ClearClientDownloadRequest();
1090 // For !(OS_WIN || OS_MACOSX), no file types are currently supported. Hence
1091 // the resulting verdict is UNKNOWN.
1092 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
1093 EXPECT_FALSE(HasClientDownloadRequest());
1095 Mock::VerifyAndClearExpectations(binary_feature_extractor_
.get());
1097 // If the response is dangerous the result should also be marked as
1099 response
.set_verdict(ClientDownloadResponse::DANGEROUS
);
1100 factory
.SetFakeResponse(
1101 DownloadProtectionService::GetDownloadRequestUrl(),
1102 response
.SerializeAsString(),
1103 net::HTTP_OK
, net::URLRequestStatus::SUCCESS
);
1105 download_service_
->CheckClientDownload(
1107 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
1108 base::Unretained(this)));
1109 MessageLoop::current()->Run();
1111 #if defined(OS_WIN) || defined(OS_MACOSX)
1112 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS
));
1113 EXPECT_TRUE(HasClientDownloadRequest());
1114 ClearClientDownloadRequest();
1116 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
1117 EXPECT_FALSE(HasClientDownloadRequest());
1119 Mock::VerifyAndClearExpectations(binary_feature_extractor_
.get());
1121 // Repeat the test with an archive inside the zip file in addition to the
1123 ASSERT_EQ(static_cast<int>(file_contents
.size()),
1125 zip_source_dir
.path().Append(FILE_PATH_LITERAL("file.rar")),
1126 file_contents
.data(), file_contents
.size()));
1127 ASSERT_TRUE(zip::Zip(zip_source_dir
.path(), a_tmp
, false));
1129 download_service_
->CheckClientDownload(
1130 &item
, base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
1131 base::Unretained(this)));
1132 MessageLoop::current()->Run();
1134 #if defined(OS_WIN) || defined(OS_MACOSX)
1135 ASSERT_TRUE(HasClientDownloadRequest());
1136 EXPECT_EQ(1, GetClientDownloadRequest()->archived_binary_size());
1137 EXPECT_TRUE(GetClientDownloadRequest()->has_download_type());
1138 EXPECT_EQ(ClientDownloadRequest_DownloadType_ZIPPED_EXECUTABLE
,
1139 GetClientDownloadRequest()->download_type());
1140 ClearClientDownloadRequest();
1142 // For !(OS_WIN || OS_MACOSX), no file types are currently supported. Hence
1143 // the resulting verdict is UNKNOWN.
1144 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
1145 EXPECT_FALSE(HasClientDownloadRequest());
1147 Mock::VerifyAndClearExpectations(binary_feature_extractor_
.get());
1149 // Repeat the test with just the archive inside the zip file.
1151 base::DeleteFile(zip_source_dir
.path().AppendASCII("file.exe"), false));
1152 ASSERT_TRUE(zip::Zip(zip_source_dir
.path(), a_tmp
, false));
1154 download_service_
->CheckClientDownload(
1155 &item
, base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
1156 base::Unretained(this)));
1157 MessageLoop::current()->Run();
1159 #if defined(OS_WIN) || defined(OS_MACOSX)
1160 ASSERT_TRUE(HasClientDownloadRequest());
1161 EXPECT_EQ(0, GetClientDownloadRequest()->archived_binary_size());
1162 EXPECT_TRUE(GetClientDownloadRequest()->has_download_type());
1163 EXPECT_EQ(ClientDownloadRequest_DownloadType_ZIPPED_ARCHIVE
,
1164 GetClientDownloadRequest()->download_type());
1165 ClearClientDownloadRequest();
1167 // For !(OS_WIN || OS_MACOSX), no file types are currently supported. Hence
1168 // the resulting verdict is UNKNOWN.
1169 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
1170 EXPECT_FALSE(HasClientDownloadRequest());
1172 Mock::VerifyAndClearExpectations(binary_feature_extractor_
.get());
1175 TEST_F(DownloadProtectionServiceTest
, CheckClientDownloadCorruptZip
) {
1176 base::ScopedTempDir download_dir
;
1177 ASSERT_TRUE(download_dir
.CreateUniqueTempDir());
1179 base::FilePath
a_tmp(download_dir
.path().Append(FILE_PATH_LITERAL("a.tmp")));
1180 base::FilePath
a_zip(FILE_PATH_LITERAL("a.zip"));
1181 std::vector
<GURL
> url_chain
;
1182 url_chain
.push_back(GURL("http://www.evil.com/a.zip"));
1183 GURL
referrer("http://www.google.com/");
1184 std::string hash
= "hash";
1186 content::MockDownloadItem item
;
1187 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp
));
1188 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_zip
));
1189 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
1190 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
1191 EXPECT_CALL(item
, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
1192 EXPECT_CALL(item
, GetTabReferrerUrl())
1193 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
1194 EXPECT_CALL(item
, GetHash()).WillRepeatedly(ReturnRef(hash
));
1195 EXPECT_CALL(item
, GetReceivedBytes()).WillRepeatedly(Return(100));
1196 EXPECT_CALL(item
, HasUserGesture()).WillRepeatedly(Return(true));
1197 EXPECT_CALL(item
, GetRemoteAddress()).WillRepeatedly(Return(""));
1199 std::string file_contents
= "corrupt zip file";
1200 ASSERT_EQ(static_cast<int>(file_contents
.size()), base::WriteFile(
1201 a_tmp
, file_contents
.data(), file_contents
.size()));
1203 download_service_
->CheckClientDownload(
1205 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
1206 base::Unretained(this)));
1207 MessageLoop::current()->Run();
1208 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
1209 EXPECT_FALSE(HasClientDownloadRequest());
1210 Mock::VerifyAndClearExpectations(sb_service_
.get());
1211 Mock::VerifyAndClearExpectations(binary_feature_extractor_
.get());
1214 TEST_F(DownloadProtectionServiceTest
, CheckClientCrxDownloadSuccess
) {
1215 ClientDownloadResponse response
;
1216 // Even if the server verdict is dangerous we should return SAFE because
1217 // DownloadProtectionService::IsSupportedDownload() will return false
1218 // for crx downloads.
1219 response
.set_verdict(ClientDownloadResponse::DANGEROUS
);
1220 net::FakeURLFetcherFactory
factory(NULL
);
1221 // Empty response means SAFE.
1222 factory
.SetFakeResponse(
1223 DownloadProtectionService::GetDownloadRequestUrl(),
1224 response
.SerializeAsString(),
1225 net::HTTP_OK
, net::URLRequestStatus::SUCCESS
);
1227 base::FilePath
a_tmp(FILE_PATH_LITERAL("a.tmp"));
1228 base::FilePath
a_crx(FILE_PATH_LITERAL("a.crx"));
1229 std::vector
<GURL
> url_chain
;
1230 url_chain
.push_back(GURL("http://www.evil.com/a.crx"));
1231 GURL
referrer("http://www.google.com/");
1232 std::string hash
= "hash";
1234 content::MockDownloadItem item
;
1235 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp
));
1236 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_crx
));
1237 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
1238 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
1239 EXPECT_CALL(item
, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
1240 EXPECT_CALL(item
, GetTabReferrerUrl())
1241 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
1242 EXPECT_CALL(item
, GetHash()).WillRepeatedly(ReturnRef(hash
));
1243 EXPECT_CALL(item
, GetReceivedBytes()).WillRepeatedly(Return(100));
1244 EXPECT_CALL(item
, HasUserGesture()).WillRepeatedly(Return(true));
1245 EXPECT_CALL(item
, GetRemoteAddress()).WillRepeatedly(Return(""));
1247 EXPECT_CALL(*sb_service_
->mock_database_manager(),
1248 MatchDownloadWhitelistUrl(_
))
1249 .WillRepeatedly(Return(false));
1250 EXPECT_CALL(*binary_feature_extractor_
.get(), CheckSignature(a_tmp
, _
))
1252 EXPECT_CALL(*binary_feature_extractor_
.get(),
1253 ExtractImageFeatures(
1254 a_tmp
, BinaryFeatureExtractor::kDefaultOptions
, _
, _
))
1257 EXPECT_FALSE(download_service_
->IsSupportedDownload(item
, a_crx
));
1258 download_service_
->CheckClientDownload(
1260 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
1261 base::Unretained(this)));
1262 MessageLoop::current()->Run();
1263 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
1266 TEST_F(DownloadProtectionServiceTest
, CheckClientDownloadValidateRequest
) {
1267 net::TestURLFetcherFactory factory
;
1269 base::FilePath
tmp_path(FILE_PATH_LITERAL("bla.tmp"));
1270 base::FilePath
final_path(FILE_PATH_LITERAL("bla.exe"));
1271 std::vector
<GURL
> url_chain
;
1272 url_chain
.push_back(GURL("http://www.google.com/"));
1273 url_chain
.push_back(GURL("http://www.google.com/bla.exe"));
1274 GURL
referrer("http://www.google.com/");
1275 std::string hash
= "hash";
1276 std::string remote_address
= "10.11.12.13";
1278 content::MockDownloadItem item
;
1279 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(tmp_path
));
1280 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(final_path
));
1281 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
1282 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
1283 EXPECT_CALL(item
, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
1284 EXPECT_CALL(item
, GetTabReferrerUrl())
1285 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
1286 EXPECT_CALL(item
, GetHash()).WillRepeatedly(ReturnRef(hash
));
1287 EXPECT_CALL(item
, GetReceivedBytes()).WillRepeatedly(Return(100));
1288 EXPECT_CALL(item
, HasUserGesture()).WillRepeatedly(Return(true));
1289 EXPECT_CALL(item
, GetRemoteAddress()).WillRepeatedly(Return(remote_address
));
1291 EXPECT_CALL(*sb_service_
->mock_database_manager(),
1292 MatchDownloadWhitelistUrl(_
))
1293 .WillRepeatedly(Return(false));
1294 EXPECT_CALL(*binary_feature_extractor_
.get(), CheckSignature(tmp_path
, _
))
1295 .WillOnce(SetCertificateContents("dummy cert data"));
1297 *binary_feature_extractor_
.get(),
1298 ExtractImageFeatures(tmp_path
, BinaryFeatureExtractor::kDefaultOptions
,
1300 .WillOnce(SetDosHeaderContents("dummy dos header"));
1301 download_service_
->CheckClientDownload(
1303 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
1304 base::Unretained(this)));
1306 #if !defined(OS_WIN) && !defined(OS_MACOSX)
1307 // SendRequest is not called. Wait for FinishRequest to call our callback.
1308 MessageLoop::current()->Run();
1309 net::TestURLFetcher
* fetcher
= factory
.GetFetcherByID(0);
1310 EXPECT_EQ(NULL
, fetcher
);
1311 EXPECT_FALSE(HasClientDownloadRequest());
1313 // Run the message loop(s) until SendRequest is called.
1314 FlushThreadMessageLoops();
1315 EXPECT_TRUE(HasClientDownloadRequest());
1316 ClearClientDownloadRequest();
1317 net::TestURLFetcher
* fetcher
= factory
.GetFetcherByID(0);
1318 ASSERT_TRUE(fetcher
);
1319 ClientDownloadRequest request
;
1320 EXPECT_TRUE(request
.ParseFromString(fetcher
->upload_data()));
1321 EXPECT_EQ("http://www.google.com/bla.exe", request
.url());
1322 EXPECT_EQ(hash
, request
.digests().sha256());
1323 EXPECT_EQ(item
.GetReceivedBytes(), request
.length());
1324 EXPECT_EQ(item
.HasUserGesture(), request
.user_initiated());
1325 EXPECT_TRUE(RequestContainsServerIp(request
, remote_address
));
1326 EXPECT_EQ(2, request
.resources_size());
1327 EXPECT_TRUE(RequestContainsResource(request
,
1328 ClientDownloadRequest::DOWNLOAD_REDIRECT
,
1329 "http://www.google.com/", ""));
1330 EXPECT_TRUE(RequestContainsResource(request
,
1331 ClientDownloadRequest::DOWNLOAD_URL
,
1332 "http://www.google.com/bla.exe",
1334 EXPECT_TRUE(request
.has_signature());
1335 ASSERT_EQ(1, request
.signature().certificate_chain_size());
1336 const ClientDownloadRequest_CertificateChain
& chain
=
1337 request
.signature().certificate_chain(0);
1338 ASSERT_EQ(1, chain
.element_size());
1339 EXPECT_EQ("dummy cert data", chain
.element(0).certificate());
1340 EXPECT_TRUE(request
.has_image_headers());
1341 const ClientDownloadRequest_ImageHeaders
& headers
=
1342 request
.image_headers();
1343 EXPECT_TRUE(headers
.has_pe_headers());
1344 EXPECT_TRUE(headers
.pe_headers().has_dos_header());
1345 EXPECT_EQ("dummy dos header", headers
.pe_headers().dos_header());
1347 // Simulate the request finishing.
1348 base::MessageLoop::current()->PostTask(
1350 base::Bind(&DownloadProtectionServiceTest::SendURLFetchComplete
,
1351 base::Unretained(this), fetcher
));
1352 MessageLoop::current()->Run();
1356 // Similar to above, but with an unsigned binary.
1357 TEST_F(DownloadProtectionServiceTest
,
1358 CheckClientDownloadValidateRequestNoSignature
) {
1359 net::TestURLFetcherFactory factory
;
1361 base::FilePath
tmp_path(FILE_PATH_LITERAL("bla.tmp"));
1362 base::FilePath
final_path(FILE_PATH_LITERAL("bla.exe"));
1363 std::vector
<GURL
> url_chain
;
1364 url_chain
.push_back(GURL("http://www.google.com/"));
1365 url_chain
.push_back(GURL("ftp://www.google.com/bla.exe"));
1366 GURL
referrer("http://www.google.com/");
1367 std::string hash
= "hash";
1368 std::string remote_address
= "10.11.12.13";
1370 content::MockDownloadItem item
;
1371 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(tmp_path
));
1372 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(final_path
));
1373 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
1374 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
1375 EXPECT_CALL(item
, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
1376 EXPECT_CALL(item
, GetTabReferrerUrl())
1377 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
1378 EXPECT_CALL(item
, GetHash()).WillRepeatedly(ReturnRef(hash
));
1379 EXPECT_CALL(item
, GetReceivedBytes()).WillRepeatedly(Return(100));
1380 EXPECT_CALL(item
, HasUserGesture()).WillRepeatedly(Return(true));
1381 EXPECT_CALL(item
, GetRemoteAddress()).WillRepeatedly(Return(remote_address
));
1383 EXPECT_CALL(*sb_service_
->mock_database_manager(),
1384 MatchDownloadWhitelistUrl(_
))
1385 .WillRepeatedly(Return(false));
1386 EXPECT_CALL(*binary_feature_extractor_
.get(), CheckSignature(tmp_path
, _
));
1387 EXPECT_CALL(*binary_feature_extractor_
.get(),
1388 ExtractImageFeatures(tmp_path
,
1389 BinaryFeatureExtractor::kDefaultOptions
,
1391 download_service_
->CheckClientDownload(
1393 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
1394 base::Unretained(this)));
1396 #if !defined(OS_WIN) && !defined(OS_MACOSX)
1397 // SendRequest is not called. Wait for FinishRequest to call our callback.
1398 MessageLoop::current()->Run();
1399 net::TestURLFetcher
* fetcher
= factory
.GetFetcherByID(0);
1400 EXPECT_EQ(NULL
, fetcher
);
1401 EXPECT_FALSE(HasClientDownloadRequest());
1403 // Run the message loop(s) until SendRequest is called.
1404 FlushThreadMessageLoops();
1405 EXPECT_TRUE(HasClientDownloadRequest());
1406 ClearClientDownloadRequest();
1407 net::TestURLFetcher
* fetcher
= factory
.GetFetcherByID(0);
1408 ASSERT_TRUE(fetcher
);
1409 ClientDownloadRequest request
;
1410 EXPECT_TRUE(request
.ParseFromString(fetcher
->upload_data()));
1411 EXPECT_EQ("ftp://www.google.com/bla.exe", request
.url());
1412 EXPECT_EQ(hash
, request
.digests().sha256());
1413 EXPECT_EQ(item
.GetReceivedBytes(), request
.length());
1414 EXPECT_EQ(item
.HasUserGesture(), request
.user_initiated());
1415 EXPECT_EQ(2, request
.resources_size());
1416 EXPECT_TRUE(RequestContainsResource(request
,
1417 ClientDownloadRequest::DOWNLOAD_REDIRECT
,
1418 "http://www.google.com/", ""));
1419 EXPECT_TRUE(RequestContainsResource(request
,
1420 ClientDownloadRequest::DOWNLOAD_URL
,
1421 "ftp://www.google.com/bla.exe",
1423 EXPECT_TRUE(request
.has_signature());
1424 EXPECT_EQ(0, request
.signature().certificate_chain_size());
1426 // Simulate the request finishing.
1427 base::MessageLoop::current()->PostTask(
1429 base::Bind(&DownloadProtectionServiceTest::SendURLFetchComplete
,
1430 base::Unretained(this), fetcher
));
1431 MessageLoop::current()->Run();
1435 // Similar to above, but with tab history.
1436 TEST_F(DownloadProtectionServiceTest
,
1437 CheckClientDownloadValidateRequestTabHistory
) {
1438 net::TestURLFetcherFactory factory
;
1440 base::ScopedTempDir profile_dir
;
1441 ASSERT_TRUE(profile_dir
.CreateUniqueTempDir());
1442 TestingProfile
profile(profile_dir
.path());
1444 profile
.CreateHistoryService(true /* delete_file */, false /* no_db */));
1446 base::FilePath
tmp_path(FILE_PATH_LITERAL("bla.tmp"));
1447 base::FilePath
final_path(FILE_PATH_LITERAL("bla.exe"));
1448 std::vector
<GURL
> url_chain
;
1449 url_chain
.push_back(GURL("http://www.google.com/"));
1450 url_chain
.push_back(GURL("http://www.google.com/bla.exe"));
1451 GURL
referrer("http://www.google.com/");
1452 GURL
tab_url("http://tab.com/final");
1453 GURL
tab_referrer("http://tab.com/referrer");
1454 std::string hash
= "hash";
1455 std::string remote_address
= "10.11.12.13";
1457 content::MockDownloadItem item
;
1458 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(tmp_path
));
1459 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(final_path
));
1460 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
1461 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
1462 EXPECT_CALL(item
, GetTabUrl()).WillRepeatedly(ReturnRef(tab_url
));
1463 EXPECT_CALL(item
, GetTabReferrerUrl())
1464 .WillRepeatedly(ReturnRef(tab_referrer
));
1465 EXPECT_CALL(item
, GetHash()).WillRepeatedly(ReturnRef(hash
));
1466 EXPECT_CALL(item
, GetReceivedBytes()).WillRepeatedly(Return(100));
1467 EXPECT_CALL(item
, HasUserGesture()).WillRepeatedly(Return(true));
1468 EXPECT_CALL(item
, GetRemoteAddress()).WillRepeatedly(Return(remote_address
));
1469 EXPECT_CALL(item
, GetBrowserContext()).WillRepeatedly(Return(&profile
));
1470 EXPECT_CALL(*sb_service_
->mock_database_manager(),
1471 MatchDownloadWhitelistUrl(_
))
1472 .WillRepeatedly(Return(false));
1473 EXPECT_CALL(*binary_feature_extractor_
.get(), CheckSignature(tmp_path
, _
))
1474 .WillRepeatedly(SetCertificateContents("dummy cert data"));
1476 *binary_feature_extractor_
.get(),
1477 ExtractImageFeatures(tmp_path
, BinaryFeatureExtractor::kDefaultOptions
,
1479 .WillRepeatedly(SetDosHeaderContents("dummy dos header"));
1481 // First test with no history match for the tab URL.
1483 TestURLFetcherWatcher
fetcher_watcher(&factory
);
1484 download_service_
->CheckClientDownload(
1486 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
1487 base::Unretained(this)));
1489 #if !defined(OS_WIN) && !defined(OS_MACOSX)
1490 // SendRequest is not called. Wait for FinishRequest to call our callback.
1491 MessageLoop::current()->Run();
1492 net::TestURLFetcher
* fetcher
= factory
.GetFetcherByID(0);
1493 EXPECT_EQ(NULL
, fetcher
);
1494 EXPECT_FALSE(HasClientDownloadRequest());
1496 EXPECT_EQ(0, fetcher_watcher
.WaitForRequest());
1497 EXPECT_TRUE(HasClientDownloadRequest());
1498 ClearClientDownloadRequest();
1499 net::TestURLFetcher
* fetcher
= factory
.GetFetcherByID(0);
1500 ASSERT_TRUE(fetcher
);
1501 ClientDownloadRequest request
;
1502 EXPECT_TRUE(request
.ParseFromString(fetcher
->upload_data()));
1503 EXPECT_EQ("http://www.google.com/bla.exe", request
.url());
1504 EXPECT_EQ(hash
, request
.digests().sha256());
1505 EXPECT_EQ(item
.GetReceivedBytes(), request
.length());
1506 EXPECT_EQ(item
.HasUserGesture(), request
.user_initiated());
1507 EXPECT_TRUE(RequestContainsServerIp(request
, remote_address
));
1508 EXPECT_EQ(3, request
.resources_size());
1510 RequestContainsResource(request
,
1511 ClientDownloadRequest::DOWNLOAD_REDIRECT
,
1512 "http://www.google.com/",
1514 EXPECT_TRUE(RequestContainsResource(request
,
1515 ClientDownloadRequest::DOWNLOAD_URL
,
1516 "http://www.google.com/bla.exe",
1518 EXPECT_TRUE(RequestContainsResource(request
,
1519 ClientDownloadRequest::TAB_URL
,
1521 tab_referrer
.spec()));
1522 EXPECT_TRUE(request
.has_signature());
1523 ASSERT_EQ(1, request
.signature().certificate_chain_size());
1524 const ClientDownloadRequest_CertificateChain
& chain
=
1525 request
.signature().certificate_chain(0);
1526 ASSERT_EQ(1, chain
.element_size());
1527 EXPECT_EQ("dummy cert data", chain
.element(0).certificate());
1528 EXPECT_TRUE(request
.has_image_headers());
1529 const ClientDownloadRequest_ImageHeaders
& headers
=
1530 request
.image_headers();
1531 EXPECT_TRUE(headers
.has_pe_headers());
1532 EXPECT_TRUE(headers
.pe_headers().has_dos_header());
1533 EXPECT_EQ("dummy dos header", headers
.pe_headers().dos_header());
1535 // Simulate the request finishing.
1536 base::MessageLoop::current()->PostTask(
1538 base::Bind(&DownloadProtectionServiceTest::SendURLFetchComplete
,
1539 base::Unretained(this),
1541 MessageLoop::current()->Run();
1545 // Now try with a history match.
1547 history::RedirectList redirects
;
1548 redirects
.push_back(GURL("http://tab.com/ref1"));
1549 redirects
.push_back(GURL("http://tab.com/ref2"));
1550 redirects
.push_back(tab_url
);
1551 HistoryServiceFactory::GetForProfile(&profile
,
1552 ServiceAccessType::EXPLICIT_ACCESS
)
1555 reinterpret_cast<history::ContextID
>(1),
1559 ui::PAGE_TRANSITION_TYPED
,
1560 history::SOURCE_BROWSED
,
1563 TestURLFetcherWatcher
fetcher_watcher(&factory
);
1564 download_service_
->CheckClientDownload(
1566 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
1567 base::Unretained(this)));
1568 #if !defined(OS_WIN) && !defined(OS_MACOSX)
1569 // SendRequest is not called. Wait for FinishRequest to call our callback.
1570 MessageLoop::current()->Run();
1571 net::TestURLFetcher
* fetcher
= factory
.GetFetcherByID(0);
1572 EXPECT_EQ(NULL
, fetcher
);
1573 EXPECT_FALSE(HasClientDownloadRequest());
1575 EXPECT_EQ(0, fetcher_watcher
.WaitForRequest());
1576 EXPECT_TRUE(HasClientDownloadRequest());
1577 ClearClientDownloadRequest();
1578 net::TestURLFetcher
* fetcher
= factory
.GetFetcherByID(0);
1579 ASSERT_TRUE(fetcher
);
1580 ClientDownloadRequest request
;
1581 EXPECT_TRUE(request
.ParseFromString(fetcher
->upload_data()));
1582 EXPECT_EQ("http://www.google.com/bla.exe", request
.url());
1583 EXPECT_EQ(hash
, request
.digests().sha256());
1584 EXPECT_EQ(item
.GetReceivedBytes(), request
.length());
1585 EXPECT_EQ(item
.HasUserGesture(), request
.user_initiated());
1586 EXPECT_TRUE(RequestContainsServerIp(request
, remote_address
));
1587 EXPECT_EQ(5, request
.resources_size());
1589 RequestContainsResource(request
,
1590 ClientDownloadRequest::DOWNLOAD_REDIRECT
,
1591 "http://www.google.com/",
1593 EXPECT_TRUE(RequestContainsResource(request
,
1594 ClientDownloadRequest::DOWNLOAD_URL
,
1595 "http://www.google.com/bla.exe",
1597 EXPECT_TRUE(RequestContainsResource(request
,
1598 ClientDownloadRequest::TAB_REDIRECT
,
1599 "http://tab.com/ref1",
1601 EXPECT_TRUE(RequestContainsResource(request
,
1602 ClientDownloadRequest::TAB_REDIRECT
,
1603 "http://tab.com/ref2",
1605 EXPECT_TRUE(RequestContainsResource(request
,
1606 ClientDownloadRequest::TAB_URL
,
1608 tab_referrer
.spec()));
1609 EXPECT_TRUE(request
.has_signature());
1610 ASSERT_EQ(1, request
.signature().certificate_chain_size());
1611 const ClientDownloadRequest_CertificateChain
& chain
=
1612 request
.signature().certificate_chain(0);
1613 ASSERT_EQ(1, chain
.element_size());
1614 EXPECT_EQ("dummy cert data", chain
.element(0).certificate());
1616 // Simulate the request finishing.
1617 base::MessageLoop::current()->PostTask(
1619 base::Bind(&DownloadProtectionServiceTest::SendURLFetchComplete
,
1620 base::Unretained(this),
1622 MessageLoop::current()->Run();
1627 TEST_F(DownloadProtectionServiceTest
, TestCheckDownloadUrl
) {
1628 std::vector
<GURL
> url_chain
;
1629 url_chain
.push_back(GURL("http://www.google.com/"));
1630 url_chain
.push_back(GURL("http://www.google.com/bla.exe"));
1631 GURL
referrer("http://www.google.com/");
1632 std::string hash
= "hash";
1634 content::MockDownloadItem item
;
1635 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
1636 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
1637 EXPECT_CALL(item
, GetHash()).WillRepeatedly(ReturnRef(hash
));
1639 // CheckDownloadURL returns immediately which means the client object callback
1640 // will never be called. Nevertheless the callback provided to
1641 // CheckClientDownload must still be called.
1642 EXPECT_CALL(*sb_service_
->mock_database_manager(),
1643 CheckDownloadUrl(ContainerEq(url_chain
), NotNull()))
1644 .WillOnce(Return(true));
1645 download_service_
->CheckDownloadUrl(
1647 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
1648 base::Unretained(this)));
1649 MessageLoop::current()->Run();
1650 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE
));
1651 Mock::VerifyAndClearExpectations(sb_service_
.get());
1653 EXPECT_CALL(*sb_service_
->mock_database_manager(),
1654 CheckDownloadUrl(ContainerEq(url_chain
), NotNull()))
1655 .WillOnce(DoAll(CheckDownloadUrlDone(SB_THREAT_TYPE_SAFE
),
1657 download_service_
->CheckDownloadUrl(
1659 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
1660 base::Unretained(this)));
1661 MessageLoop::current()->Run();
1662 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE
));
1663 Mock::VerifyAndClearExpectations(sb_service_
.get());
1665 EXPECT_CALL(*sb_service_
->mock_database_manager(),
1666 CheckDownloadUrl(ContainerEq(url_chain
), NotNull()))
1668 CheckDownloadUrlDone(SB_THREAT_TYPE_URL_MALWARE
),
1670 download_service_
->CheckDownloadUrl(
1672 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
1673 base::Unretained(this)));
1674 MessageLoop::current()->Run();
1675 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE
));
1676 Mock::VerifyAndClearExpectations(sb_service_
.get());
1678 EXPECT_CALL(*sb_service_
->mock_database_manager(),
1679 CheckDownloadUrl(ContainerEq(url_chain
),
1682 CheckDownloadUrlDone(SB_THREAT_TYPE_BINARY_MALWARE_URL
),
1684 download_service_
->CheckDownloadUrl(
1686 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
1687 base::Unretained(this)));
1688 MessageLoop::current()->Run();
1689 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS
));
1692 TEST_F(DownloadProtectionServiceTest
, TestDownloadRequestTimeout
) {
1693 net::TestURLFetcherFactory factory
;
1695 std::vector
<GURL
> url_chain
;
1696 url_chain
.push_back(GURL("http://www.evil.com/bla.exe"));
1697 GURL
referrer("http://www.google.com/");
1698 base::FilePath
tmp_path(FILE_PATH_LITERAL("a.tmp"));
1699 base::FilePath
final_path(FILE_PATH_LITERAL("a.exe"));
1700 std::string hash
= "hash";
1702 content::MockDownloadItem item
;
1703 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(tmp_path
));
1704 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(final_path
));
1705 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
1706 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
1707 EXPECT_CALL(item
, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
1708 EXPECT_CALL(item
, GetTabReferrerUrl())
1709 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
1710 EXPECT_CALL(item
, GetHash()).WillRepeatedly(ReturnRef(hash
));
1711 EXPECT_CALL(item
, GetReceivedBytes()).WillRepeatedly(Return(100));
1712 EXPECT_CALL(item
, HasUserGesture()).WillRepeatedly(Return(true));
1713 EXPECT_CALL(item
, GetRemoteAddress()).WillRepeatedly(Return(""));
1715 EXPECT_CALL(*sb_service_
->mock_database_manager(),
1716 MatchDownloadWhitelistUrl(_
))
1717 .WillRepeatedly(Return(false));
1718 EXPECT_CALL(*binary_feature_extractor_
.get(), CheckSignature(tmp_path
, _
));
1719 EXPECT_CALL(*binary_feature_extractor_
.get(),
1720 ExtractImageFeatures(tmp_path
,
1721 BinaryFeatureExtractor::kDefaultOptions
,
1724 download_service_
->download_request_timeout_ms_
= 10;
1725 download_service_
->CheckClientDownload(
1727 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
1728 base::Unretained(this)));
1730 // The request should time out because the HTTP request hasn't returned
1732 MessageLoop::current()->Run();
1733 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
1734 #if defined(OS_WIN) || defined(OS_MACOSX)
1735 EXPECT_TRUE(HasClientDownloadRequest());
1736 ClearClientDownloadRequest();
1738 EXPECT_FALSE(HasClientDownloadRequest());
1742 TEST_F(DownloadProtectionServiceTest
, TestDownloadItemDestroyed
) {
1743 net::TestURLFetcherFactory factory
;
1745 std::vector
<GURL
> url_chain
;
1746 url_chain
.push_back(GURL("http://www.evil.com/bla.exe"));
1747 GURL
referrer("http://www.google.com/");
1748 GURL
tab_url("http://www.google.com/tab");
1749 base::FilePath
tmp_path(FILE_PATH_LITERAL("a.tmp"));
1750 base::FilePath
final_path(FILE_PATH_LITERAL("a.exe"));
1751 std::string hash
= "hash";
1754 content::MockDownloadItem item
;
1755 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(tmp_path
));
1756 EXPECT_CALL(item
, GetTargetFilePath())
1757 .WillRepeatedly(ReturnRef(final_path
));
1758 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
1759 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
1760 EXPECT_CALL(item
, GetTabUrl()).WillRepeatedly(ReturnRef(tab_url
));
1761 EXPECT_CALL(item
, GetTabReferrerUrl())
1762 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
1763 EXPECT_CALL(item
, GetHash()).WillRepeatedly(ReturnRef(hash
));
1764 EXPECT_CALL(item
, GetReceivedBytes()).WillRepeatedly(Return(100));
1765 EXPECT_CALL(item
, HasUserGesture()).WillRepeatedly(Return(true));
1766 EXPECT_CALL(item
, GetRemoteAddress()).WillRepeatedly(Return(""));
1768 EXPECT_CALL(*sb_service_
->mock_database_manager(),
1769 MatchDownloadWhitelistUrl(_
))
1770 .WillRepeatedly(Return(false));
1771 EXPECT_CALL(*binary_feature_extractor_
.get(), CheckSignature(tmp_path
, _
));
1772 EXPECT_CALL(*binary_feature_extractor_
.get(),
1773 ExtractImageFeatures(
1774 tmp_path
, BinaryFeatureExtractor::kDefaultOptions
, _
, _
));
1776 download_service_
->CheckClientDownload(
1778 base::Bind(&DownloadProtectionServiceTest::SyncCheckDoneCallback
,
1779 base::Unretained(this)));
1780 // MockDownloadItem going out of scope triggers the OnDownloadDestroyed
1784 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
1785 EXPECT_FALSE(HasClientDownloadRequest());
1788 TEST_F(DownloadProtectionServiceTest
,
1789 TestDownloadItemDestroyedDuringWhitelistCheck
) {
1790 net::TestURLFetcherFactory factory
;
1792 std::vector
<GURL
> url_chain
;
1793 url_chain
.push_back(GURL("http://www.evil.com/bla.exe"));
1794 GURL
referrer("http://www.google.com/");
1795 GURL
tab_url("http://www.google.com/tab");
1796 base::FilePath
tmp_path(FILE_PATH_LITERAL("a.tmp"));
1797 base::FilePath
final_path(FILE_PATH_LITERAL("a.exe"));
1798 std::string hash
= "hash";
1800 scoped_ptr
<content::MockDownloadItem
> item(new content::MockDownloadItem
);
1801 EXPECT_CALL(*item
, GetFullPath()).WillRepeatedly(ReturnRef(tmp_path
));
1802 EXPECT_CALL(*item
, GetTargetFilePath())
1803 .WillRepeatedly(ReturnRef(final_path
));
1804 EXPECT_CALL(*item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
1805 EXPECT_CALL(*item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
1806 EXPECT_CALL(*item
, GetTabUrl()).WillRepeatedly(ReturnRef(tab_url
));
1807 EXPECT_CALL(*item
, GetTabReferrerUrl())
1808 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
1809 EXPECT_CALL(*item
, GetHash()).WillRepeatedly(ReturnRef(hash
));
1810 EXPECT_CALL(*item
, GetReceivedBytes()).WillRepeatedly(Return(100));
1811 EXPECT_CALL(*item
, HasUserGesture()).WillRepeatedly(Return(true));
1812 EXPECT_CALL(*item
, GetRemoteAddress()).WillRepeatedly(Return(""));
1814 EXPECT_CALL(*sb_service_
->mock_database_manager(),
1815 MatchDownloadWhitelistUrl(_
))
1816 .WillRepeatedly(Invoke([&item
](const GURL
&) {
1820 EXPECT_CALL(*binary_feature_extractor_
.get(), CheckSignature(tmp_path
, _
));
1821 EXPECT_CALL(*binary_feature_extractor_
.get(),
1822 ExtractImageFeatures(tmp_path
,
1823 BinaryFeatureExtractor::kDefaultOptions
,
1826 download_service_
->CheckClientDownload(
1828 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
1829 base::Unretained(this)));
1831 MessageLoop::current()->Run();
1832 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
1833 EXPECT_FALSE(HasClientDownloadRequest());
1836 TEST_F(DownloadProtectionServiceTest
, GetCertificateWhitelistStrings
) {
1837 // We'll pass this cert in as the "issuer", even though it isn't really
1838 // used to sign the certs below. GetCertificateWhitelistStirngs doesn't care
1840 scoped_refptr
<net::X509Certificate
> issuer_cert(
1841 ReadTestCertificate("issuer.pem"));
1842 ASSERT_TRUE(issuer_cert
.get());
1843 std::string cert_base
= "cert/" + base::HexEncode(
1844 issuer_cert
->fingerprint().data
,
1845 sizeof(issuer_cert
->fingerprint().data
));
1847 scoped_refptr
<net::X509Certificate
> cert(ReadTestCertificate("test_cn.pem"));
1848 ASSERT_TRUE(cert
.get());
1849 std::vector
<std::string
> whitelist_strings
;
1850 GetCertificateWhitelistStrings(
1851 *cert
.get(), *issuer_cert
.get(), &whitelist_strings
);
1852 // This also tests escaping of characters in the certificate attributes.
1853 EXPECT_THAT(whitelist_strings
, ElementsAre(
1854 cert_base
+ "/CN=subject%2F%251"));
1856 cert
= ReadTestCertificate("test_cn_o.pem");
1857 ASSERT_TRUE(cert
.get());
1858 whitelist_strings
.clear();
1859 GetCertificateWhitelistStrings(
1860 *cert
.get(), *issuer_cert
.get(), &whitelist_strings
);
1861 EXPECT_THAT(whitelist_strings
,
1862 ElementsAre(cert_base
+ "/CN=subject",
1863 cert_base
+ "/CN=subject/O=org",
1864 cert_base
+ "/O=org"));
1866 cert
= ReadTestCertificate("test_cn_o_ou.pem");
1867 ASSERT_TRUE(cert
.get());
1868 whitelist_strings
.clear();
1869 GetCertificateWhitelistStrings(
1870 *cert
.get(), *issuer_cert
.get(), &whitelist_strings
);
1871 EXPECT_THAT(whitelist_strings
,
1872 ElementsAre(cert_base
+ "/CN=subject",
1873 cert_base
+ "/CN=subject/O=org",
1874 cert_base
+ "/CN=subject/O=org/OU=unit",
1875 cert_base
+ "/CN=subject/OU=unit",
1876 cert_base
+ "/O=org",
1877 cert_base
+ "/O=org/OU=unit",
1878 cert_base
+ "/OU=unit"));
1880 cert
= ReadTestCertificate("test_cn_ou.pem");
1881 ASSERT_TRUE(cert
.get());
1882 whitelist_strings
.clear();
1883 GetCertificateWhitelistStrings(
1884 *cert
.get(), *issuer_cert
.get(), &whitelist_strings
);
1885 EXPECT_THAT(whitelist_strings
,
1886 ElementsAre(cert_base
+ "/CN=subject",
1887 cert_base
+ "/CN=subject/OU=unit",
1888 cert_base
+ "/OU=unit"));
1890 cert
= ReadTestCertificate("test_o.pem");
1891 ASSERT_TRUE(cert
.get());
1892 whitelist_strings
.clear();
1893 GetCertificateWhitelistStrings(
1894 *cert
.get(), *issuer_cert
.get(), &whitelist_strings
);
1895 EXPECT_THAT(whitelist_strings
, ElementsAre(cert_base
+ "/O=org"));
1897 cert
= ReadTestCertificate("test_o_ou.pem");
1898 ASSERT_TRUE(cert
.get());
1899 whitelist_strings
.clear();
1900 GetCertificateWhitelistStrings(
1901 *cert
.get(), *issuer_cert
.get(), &whitelist_strings
);
1902 EXPECT_THAT(whitelist_strings
,
1903 ElementsAre(cert_base
+ "/O=org",
1904 cert_base
+ "/O=org/OU=unit",
1905 cert_base
+ "/OU=unit"));
1907 cert
= ReadTestCertificate("test_ou.pem");
1908 ASSERT_TRUE(cert
.get());
1909 whitelist_strings
.clear();
1910 GetCertificateWhitelistStrings(
1911 *cert
.get(), *issuer_cert
.get(), &whitelist_strings
);
1912 EXPECT_THAT(whitelist_strings
, ElementsAre(cert_base
+ "/OU=unit"));
1914 cert
= ReadTestCertificate("test_c.pem");
1915 ASSERT_TRUE(cert
.get());
1916 whitelist_strings
.clear();
1917 GetCertificateWhitelistStrings(
1918 *cert
.get(), *issuer_cert
.get(), &whitelist_strings
);
1919 EXPECT_THAT(whitelist_strings
, ElementsAre());
1924 class MockPageNavigator
: public content::PageNavigator
{
1926 MOCK_METHOD1(OpenURL
, content::WebContents
*(const content::OpenURLParams
&));
1929 // A custom matcher that matches a OpenURLParams value with a url with a query
1930 // parameter patching |value|.
1931 MATCHER_P(OpenURLParamsWithContextValue
, value
, "") {
1932 std::string query_value
;
1933 return net::GetValueForKeyInQuery(arg
.url
, "ctx", &query_value
) &&
1934 query_value
== value
;
1939 // ShowDetailsForDownload() should open a URL showing more information about why
1940 // a download was flagged by SafeBrowsing. The URL should have a &ctx= parameter
1941 // whose value is the DownloadDangerType.
1942 TEST_F(DownloadProtectionServiceTest
, ShowDetailsForDownloadHasContext
) {
1943 StrictMock
<MockPageNavigator
> mock_page_navigator
;
1944 StrictMock
<content::MockDownloadItem
> mock_download_item
;
1946 EXPECT_CALL(mock_download_item
, GetDangerType())
1947 .WillOnce(Return(content::DOWNLOAD_DANGER_TYPE_DANGEROUS_HOST
));
1948 EXPECT_CALL(mock_page_navigator
, OpenURL(OpenURLParamsWithContextValue("7")));
1950 download_service_
->ShowDetailsForDownload(mock_download_item
,
1951 &mock_page_navigator
);
1954 } // namespace safe_browsing