1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/safe_browsing/download_protection_service.h"
10 #include "base/base_paths.h"
11 #include "base/bind.h"
12 #include "base/callback.h"
13 #include "base/files/file_path.h"
14 #include "base/files/file_util.h"
15 #include "base/files/scoped_temp_dir.h"
16 #include "base/memory/ref_counted.h"
17 #include "base/memory/scoped_ptr.h"
18 #include "base/message_loop/message_loop.h"
19 #include "base/path_service.h"
20 #include "base/run_loop.h"
21 #include "base/strings/string_number_conversions.h"
22 #include "base/threading/sequenced_worker_pool.h"
23 #include "chrome/browser/history/history_service.h"
24 #include "chrome/browser/history/history_service_factory.h"
25 #include "chrome/browser/safe_browsing/binary_feature_extractor.h"
26 #include "chrome/browser/safe_browsing/database_manager.h"
27 #include "chrome/browser/safe_browsing/download_feedback_service.h"
28 #include "chrome/browser/safe_browsing/safe_browsing_service.h"
29 #include "chrome/common/safe_browsing/csd.pb.h"
30 #include "chrome/test/base/testing_profile.h"
31 #include "content/public/test/mock_download_item.h"
32 #include "content/public/test/test_browser_thread_bundle.h"
33 #include "content/public/test/test_utils.h"
34 #include "net/cert/x509_certificate.h"
35 #include "net/http/http_status_code.h"
36 #include "net/url_request/test_url_fetcher_factory.h"
37 #include "net/url_request/url_fetcher_delegate.h"
38 #include "net/url_request/url_request_status.h"
39 #include "testing/gmock/include/gmock/gmock.h"
40 #include "testing/gtest/include/gtest/gtest.h"
41 #include "third_party/zlib/google/zip.h"
44 #if defined(OS_MACOSX)
45 #include "base/metrics/field_trial.h"
46 #include "components/variations/entropy_provider.h"
49 using ::testing::Assign
;
50 using ::testing::ContainerEq
;
51 using ::testing::DoAll
;
52 using ::testing::ElementsAre
;
53 using ::testing::Mock
;
54 using ::testing::NotNull
;
55 using ::testing::Return
;
56 using ::testing::ReturnRef
;
57 using ::testing::SaveArg
;
58 using ::testing::StrictMock
;
60 using base::MessageLoop
;
61 using content::BrowserThread
;
62 namespace safe_browsing
{
64 // A SafeBrowsingDatabaseManager implementation that returns a fixed result for
66 class MockSafeBrowsingDatabaseManager
: public SafeBrowsingDatabaseManager
{
68 explicit MockSafeBrowsingDatabaseManager(SafeBrowsingService
* service
)
69 : SafeBrowsingDatabaseManager(service
) { }
71 MOCK_METHOD1(MatchDownloadWhitelistUrl
, bool(const GURL
&));
72 MOCK_METHOD1(MatchDownloadWhitelistString
, bool(const std::string
&));
73 MOCK_METHOD2(CheckDownloadUrl
, bool(
74 const std::vector
<GURL
>& url_chain
,
75 SafeBrowsingDatabaseManager::Client
* client
));
78 virtual ~MockSafeBrowsingDatabaseManager() {}
79 DISALLOW_COPY_AND_ASSIGN(MockSafeBrowsingDatabaseManager
);
82 class FakeSafeBrowsingService
: public SafeBrowsingService
{
84 FakeSafeBrowsingService() { }
86 // Returned pointer has the same lifespan as the database_manager_ refcounted
88 MockSafeBrowsingDatabaseManager
* mock_database_manager() {
89 return mock_database_manager_
;
93 virtual ~FakeSafeBrowsingService() { }
95 virtual SafeBrowsingDatabaseManager
* CreateDatabaseManager() override
{
96 mock_database_manager_
= new MockSafeBrowsingDatabaseManager(this);
97 return mock_database_manager_
;
100 virtual void RegisterAllDelayedAnalysis() override
{ }
103 MockSafeBrowsingDatabaseManager
* mock_database_manager_
;
105 DISALLOW_COPY_AND_ASSIGN(FakeSafeBrowsingService
);
108 class MockBinaryFeatureExtractor
: public BinaryFeatureExtractor
{
110 MockBinaryFeatureExtractor() {}
111 MOCK_METHOD2(CheckSignature
, void(const base::FilePath
&,
112 ClientDownloadRequest_SignatureInfo
*));
113 MOCK_METHOD2(ExtractImageHeaders
, void(const base::FilePath
&,
114 ClientDownloadRequest_ImageHeaders
*));
117 virtual ~MockBinaryFeatureExtractor() {}
120 DISALLOW_COPY_AND_ASSIGN(MockBinaryFeatureExtractor
);
123 class TestURLFetcherWatcher
: public net::TestURLFetcherDelegateForTests
{
125 explicit TestURLFetcherWatcher(net::TestURLFetcherFactory
* factory
)
126 : factory_(factory
), fetcher_id_(-1) {
127 factory_
->SetDelegateForTests(this);
129 ~TestURLFetcherWatcher() {
130 factory_
->SetDelegateForTests(NULL
);
133 // TestURLFetcherDelegateForTests impl:
134 virtual void OnRequestStart(int fetcher_id
) override
{
135 fetcher_id_
= fetcher_id
;
138 virtual void OnChunkUpload(int fetcher_id
) override
{}
139 virtual void OnRequestEnd(int fetcher_id
) override
{}
141 int WaitForRequest() {
147 net::TestURLFetcherFactory
* factory_
;
149 base::RunLoop run_loop_
;
153 ACTION_P(SetCertificateContents
, contents
) {
154 arg1
->add_certificate_chain()->add_element()->set_certificate(contents
);
157 ACTION_P(SetDosHeaderContents
, contents
) {
158 arg1
->mutable_pe_headers()->set_dos_header(contents
);
161 ACTION_P(TrustSignature
, certificate_file
) {
162 arg1
->set_trusted(true);
163 // Add a certificate chain. Note that we add the certificate twice so that
164 // it appears as its own issuer.
165 std::string cert_data
;
166 ASSERT_TRUE(base::ReadFileToString(certificate_file
, &cert_data
));
167 ClientDownloadRequest_CertificateChain
* chain
=
168 arg1
->add_certificate_chain();
169 chain
->add_element()->set_certificate(cert_data
);
170 chain
->add_element()->set_certificate(cert_data
);
173 // We can't call OnSafeBrowsingResult directly because SafeBrowsingCheck does
174 // not have any copy constructor which means it can't be stored in a callback
175 // easily. Note: check will be deleted automatically when the callback is
177 void OnSafeBrowsingResult(
178 SafeBrowsingDatabaseManager::SafeBrowsingCheck
* check
) {
179 check
->client
->OnSafeBrowsingResult(*check
);
182 ACTION_P(CheckDownloadUrlDone
, threat_type
) {
183 SafeBrowsingDatabaseManager::SafeBrowsingCheck
* check
=
184 new SafeBrowsingDatabaseManager::SafeBrowsingCheck(
186 std::vector
<SBFullHash
>(),
188 safe_browsing_util::BINURL
,
189 std::vector
<SBThreatType
>(1, SB_THREAT_TYPE_BINARY_MALWARE_URL
));
190 for (size_t i
= 0; i
< check
->url_results
.size(); ++i
)
191 check
->url_results
[i
] = threat_type
;
192 BrowserThread::PostTask(BrowserThread::IO
,
194 base::Bind(&OnSafeBrowsingResult
,
195 base::Owned(check
)));
198 class DownloadProtectionServiceTest
: public testing::Test
{
200 DownloadProtectionServiceTest()
201 : test_browser_thread_bundle_(
202 content::TestBrowserThreadBundle::IO_MAINLOOP
) {
204 virtual void SetUp() {
205 #if defined(OS_MACOSX)
206 field_trial_list_
.reset(new base::FieldTrialList(
207 new metrics::SHA1EntropyProvider("42")));
208 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
209 "SafeBrowsingOSXClientDownloadPings",
212 // Start real threads for the IO and File threads so that the DCHECKs
213 // to test that we're on the correct thread work.
214 sb_service_
= new StrictMock
<FakeSafeBrowsingService
>();
215 sb_service_
->Initialize();
216 binary_feature_extractor_
= new StrictMock
<MockBinaryFeatureExtractor
>();
217 download_service_
= sb_service_
->download_protection_service();
218 download_service_
->binary_feature_extractor_
= binary_feature_extractor_
;
219 download_service_
->SetEnabled(true);
220 base::RunLoop().RunUntilIdle();
223 base::FilePath source_path
;
224 ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT
, &source_path
));
225 testdata_path_
= source_path
226 .AppendASCII("chrome")
229 .AppendASCII("safe_browsing")
230 .AppendASCII("download_protection");
233 virtual void TearDown() {
234 sb_service_
->ShutDown();
235 // Flush all of the thread message loops to ensure that there are no
236 // tasks currently running.
237 FlushThreadMessageLoops();
241 bool RequestContainsResource(const ClientDownloadRequest
& request
,
242 ClientDownloadRequest::ResourceType type
,
243 const std::string
& url
,
244 const std::string
& referrer
) {
245 for (int i
= 0; i
< request
.resources_size(); ++i
) {
246 if (request
.resources(i
).url() == url
&&
247 request
.resources(i
).type() == type
&&
248 (referrer
.empty() || request
.resources(i
).referrer() == referrer
)) {
255 // At this point we only set the server IP for the download itself.
256 bool RequestContainsServerIp(const ClientDownloadRequest
& request
,
257 const std::string
& remote_address
) {
258 for (int i
= 0; i
< request
.resources_size(); ++i
) {
259 // We want the last DOWNLOAD_URL in the chain.
260 if (request
.resources(i
).type() == ClientDownloadRequest::DOWNLOAD_URL
&&
261 (i
+ 1 == request
.resources_size() ||
262 request
.resources(i
+ 1).type() !=
263 ClientDownloadRequest::DOWNLOAD_URL
)) {
264 return remote_address
== request
.resources(i
).remote_ip();
270 // Flushes any pending tasks in the message loops of all threads.
271 void FlushThreadMessageLoops() {
272 BrowserThread::GetBlockingPool()->FlushForTesting();
273 FlushMessageLoop(BrowserThread::IO
);
274 base::RunLoop().RunUntilIdle();
277 // Proxy for private method.
278 static void GetCertificateWhitelistStrings(
279 const net::X509Certificate
& certificate
,
280 const net::X509Certificate
& issuer
,
281 std::vector
<std::string
>* whitelist_strings
) {
282 DownloadProtectionService::GetCertificateWhitelistStrings(
283 certificate
, issuer
, whitelist_strings
);
286 // Reads a single PEM-encoded certificate from the testdata directory.
287 // Returns NULL on failure.
288 scoped_refptr
<net::X509Certificate
> ReadTestCertificate(
289 const std::string
& filename
) {
290 std::string cert_data
;
291 if (!base::ReadFileToString(testdata_path_
.AppendASCII(filename
),
295 net::CertificateList certs
=
296 net::X509Certificate::CreateCertificateListFromBytes(
299 net::X509Certificate::FORMAT_PEM_CERT_SEQUENCE
);
300 return certs
.empty() ? NULL
: certs
[0];
304 // Helper functions for FlushThreadMessageLoops.
305 void RunAllPendingAndQuitUI() {
306 base::MessageLoop::current()->RunUntilIdle();
307 BrowserThread::PostTask(
310 base::Bind(&DownloadProtectionServiceTest::QuitMessageLoop
,
311 base::Unretained(this)));
314 void QuitMessageLoop() {
315 base::MessageLoop::current()->Quit();
318 void PostRunMessageLoopTask(BrowserThread::ID thread
) {
319 BrowserThread::PostTask(
322 base::Bind(&DownloadProtectionServiceTest::RunAllPendingAndQuitUI
,
323 base::Unretained(this)));
326 void FlushMessageLoop(BrowserThread::ID thread
) {
327 BrowserThread::PostTask(
330 base::Bind(&DownloadProtectionServiceTest::PostRunMessageLoopTask
,
331 base::Unretained(this), thread
));
332 MessageLoop::current()->Run();
336 void CheckDoneCallback(
337 DownloadProtectionService::DownloadCheckResult result
) {
340 MessageLoop::current()->Quit();
343 void SyncCheckDoneCallback(
344 DownloadProtectionService::DownloadCheckResult result
) {
349 void SendURLFetchComplete(net::TestURLFetcher
* fetcher
) {
350 fetcher
->delegate()->OnURLFetchComplete(fetcher
);
353 testing::AssertionResult
IsResult(
354 DownloadProtectionService::DownloadCheckResult expected
) {
356 return testing::AssertionFailure() << "No result";
358 return result_
== expected
?
359 testing::AssertionSuccess() :
360 testing::AssertionFailure() << "Expected " << expected
<<
365 scoped_refptr
<FakeSafeBrowsingService
> sb_service_
;
366 scoped_refptr
<MockBinaryFeatureExtractor
> binary_feature_extractor_
;
367 DownloadProtectionService
* download_service_
;
368 DownloadProtectionService::DownloadCheckResult result_
;
370 content::TestBrowserThreadBundle test_browser_thread_bundle_
;
371 content::InProcessUtilityThreadHelper in_process_utility_thread_helper_
;
372 base::FilePath testdata_path_
;
373 #if defined(OS_MACOSX)
374 scoped_ptr
<base::FieldTrialList
> field_trial_list_
;
378 TEST_F(DownloadProtectionServiceTest
, CheckClientDownloadInvalidUrl
) {
379 base::FilePath
a_tmp(FILE_PATH_LITERAL("a.tmp"));
380 base::FilePath
a_exe(FILE_PATH_LITERAL("a.exe"));
381 std::vector
<GURL
> url_chain
;
382 GURL
referrer("http://www.google.com/");
384 content::MockDownloadItem item
;
385 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp
));
386 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_exe
));
387 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
388 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
389 EXPECT_CALL(item
, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
390 EXPECT_CALL(item
, GetTabReferrerUrl())
391 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
392 download_service_
->CheckClientDownload(
394 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
395 base::Unretained(this)));
396 MessageLoop::current()->Run();
397 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
398 Mock::VerifyAndClearExpectations(&item
);
400 url_chain
.push_back(GURL("file://www.google.com/"));
401 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp
));
402 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_exe
));
403 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
404 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
405 EXPECT_CALL(item
, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
406 EXPECT_CALL(item
, GetTabReferrerUrl())
407 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
408 download_service_
->CheckClientDownload(
410 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
411 base::Unretained(this)));
412 MessageLoop::current()->Run();
413 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
416 TEST_F(DownloadProtectionServiceTest
, CheckClientDownloadNotABinary
) {
417 base::FilePath
a_tmp(FILE_PATH_LITERAL("a.tmp"));
418 base::FilePath
a_txt(FILE_PATH_LITERAL("a.txt"));
419 std::vector
<GURL
> url_chain
;
420 GURL
referrer("http://www.google.com/");
422 content::MockDownloadItem item
;
423 url_chain
.push_back(GURL("http://www.example.com/foo"));
424 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp
));
425 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_txt
));
426 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
427 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
428 EXPECT_CALL(item
, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
429 EXPECT_CALL(item
, GetTabReferrerUrl())
430 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
431 download_service_
->CheckClientDownload(
433 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
434 base::Unretained(this)));
435 MessageLoop::current()->Run();
436 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
439 TEST_F(DownloadProtectionServiceTest
, CheckClientDownloadWhitelistedUrl
) {
440 // Response to any requests will be DANGEROUS.
441 ClientDownloadResponse response
;
442 response
.set_verdict(ClientDownloadResponse::DANGEROUS
);
443 net::FakeURLFetcherFactory
factory(NULL
);
444 factory
.SetFakeResponse(
445 DownloadProtectionService::GetDownloadRequestUrl(),
446 response
.SerializeAsString(),
447 net::HTTP_OK
, net::URLRequestStatus::SUCCESS
);
449 std::string hash
= "hash";
450 base::FilePath
a_tmp(FILE_PATH_LITERAL("a.tmp"));
451 base::FilePath
a_exe(FILE_PATH_LITERAL("a.exe"));
452 std::vector
<GURL
> url_chain
;
455 content::MockDownloadItem item
;
456 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp
));
457 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_exe
));
458 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
459 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
460 EXPECT_CALL(item
, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
461 EXPECT_CALL(item
, GetTabReferrerUrl())
462 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
463 EXPECT_CALL(item
, GetHash()).WillRepeatedly(ReturnRef(hash
));
464 EXPECT_CALL(item
, GetReceivedBytes()).WillRepeatedly(Return(100));
465 EXPECT_CALL(item
, HasUserGesture()).WillRepeatedly(Return(true));
466 EXPECT_CALL(item
, GetRemoteAddress()).WillRepeatedly(Return(""));
467 EXPECT_CALL(*binary_feature_extractor_
.get(), CheckSignature(a_tmp
, _
))
469 EXPECT_CALL(*binary_feature_extractor_
.get(), ExtractImageHeaders(a_tmp
, _
))
472 // We should not get whilelist checks for other URLs than specified below.
473 EXPECT_CALL(*sb_service_
->mock_database_manager(),
474 MatchDownloadWhitelistUrl(_
)).Times(0);
475 EXPECT_CALL(*sb_service_
->mock_database_manager(),
476 MatchDownloadWhitelistUrl(GURL("http://www.evil.com/bla.exe")))
477 .WillRepeatedly(Return(false));
478 EXPECT_CALL(*sb_service_
->mock_database_manager(),
479 MatchDownloadWhitelistUrl(GURL("http://www.google.com/a.exe")))
480 .WillRepeatedly(Return(true));
482 // With no referrer and just the bad url, should be marked DANGEROUS.
483 url_chain
.push_back(GURL("http://www.evil.com/bla.exe"));
484 download_service_
->CheckClientDownload(
486 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
487 base::Unretained(this)));
488 MessageLoop::current()->Run();
490 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS
));
492 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
495 // Check that the referrer is not matched against the whitelist.
496 referrer
= GURL("http://www.google.com/");
497 download_service_
->CheckClientDownload(
499 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
500 base::Unretained(this)));
501 MessageLoop::current()->Run();
503 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS
));
505 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
508 // Redirect from a site shouldn't be checked either.
509 url_chain
.insert(url_chain
.begin(), GURL("http://www.google.com/redirect"));
510 download_service_
->CheckClientDownload(
512 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
513 base::Unretained(this)));
514 MessageLoop::current()->Run();
516 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS
));
518 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
521 // Only if the final url is whitelisted should it be SAFE.
522 url_chain
.push_back(GURL("http://www.google.com/a.exe"));
523 download_service_
->CheckClientDownload(
525 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
526 base::Unretained(this)));
527 MessageLoop::current()->Run();
528 #if defined(OS_MACOSX)
529 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
531 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE
));
535 TEST_F(DownloadProtectionServiceTest
, CheckClientDownloadFetchFailed
) {
536 net::FakeURLFetcherFactory
factory(NULL
);
537 // HTTP request will fail.
538 factory
.SetFakeResponse(
539 DownloadProtectionService::GetDownloadRequestUrl(), std::string(),
540 net::HTTP_INTERNAL_SERVER_ERROR
, net::URLRequestStatus::FAILED
);
542 base::FilePath
a_tmp(FILE_PATH_LITERAL("a.tmp"));
543 base::FilePath
a_exe(FILE_PATH_LITERAL("a.exe"));
544 std::vector
<GURL
> url_chain
;
545 url_chain
.push_back(GURL("http://www.evil.com/a.exe"));
546 GURL
referrer("http://www.google.com/");
547 std::string hash
= "hash";
549 content::MockDownloadItem item
;
550 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp
));
551 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_exe
));
552 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
553 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
554 EXPECT_CALL(item
, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
555 EXPECT_CALL(item
, GetTabReferrerUrl())
556 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
557 EXPECT_CALL(item
, GetHash()).WillRepeatedly(ReturnRef(hash
));
558 EXPECT_CALL(item
, GetReceivedBytes()).WillRepeatedly(Return(100));
559 EXPECT_CALL(item
, HasUserGesture()).WillRepeatedly(Return(true));
560 EXPECT_CALL(item
, GetRemoteAddress()).WillRepeatedly(Return(""));
562 EXPECT_CALL(*sb_service_
->mock_database_manager(),
563 MatchDownloadWhitelistUrl(_
))
564 .WillRepeatedly(Return(false));
565 EXPECT_CALL(*binary_feature_extractor_
.get(), CheckSignature(a_tmp
, _
));
566 EXPECT_CALL(*binary_feature_extractor_
.get(), ExtractImageHeaders(a_tmp
, _
));
568 download_service_
->CheckClientDownload(
570 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
571 base::Unretained(this)));
572 MessageLoop::current()->Run();
573 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
576 TEST_F(DownloadProtectionServiceTest
, CheckClientDownloadSuccess
) {
577 ClientDownloadResponse response
;
578 response
.set_verdict(ClientDownloadResponse::SAFE
);
579 net::FakeURLFetcherFactory
factory(NULL
);
580 // Empty response means SAFE.
581 factory
.SetFakeResponse(
582 DownloadProtectionService::GetDownloadRequestUrl(),
583 response
.SerializeAsString(),
584 net::HTTP_OK
, net::URLRequestStatus::SUCCESS
);
586 base::FilePath
a_tmp(FILE_PATH_LITERAL("a.tmp"));
587 base::FilePath
a_exe(FILE_PATH_LITERAL("a.exe"));
588 std::vector
<GURL
> url_chain
;
589 url_chain
.push_back(GURL("http://www.evil.com/a.exe"));
590 GURL
referrer("http://www.google.com/");
591 std::string hash
= "hash";
593 content::MockDownloadItem item
;
594 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp
));
595 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_exe
));
596 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
597 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
598 EXPECT_CALL(item
, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
599 EXPECT_CALL(item
, GetTabReferrerUrl())
600 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
601 EXPECT_CALL(item
, GetHash()).WillRepeatedly(ReturnRef(hash
));
602 EXPECT_CALL(item
, GetReceivedBytes()).WillRepeatedly(Return(100));
603 EXPECT_CALL(item
, HasUserGesture()).WillRepeatedly(Return(true));
604 EXPECT_CALL(item
, GetRemoteAddress()).WillRepeatedly(Return(""));
606 EXPECT_CALL(*sb_service_
->mock_database_manager(),
607 MatchDownloadWhitelistUrl(_
))
608 .WillRepeatedly(Return(false));
609 EXPECT_CALL(*binary_feature_extractor_
.get(), CheckSignature(a_tmp
, _
))
611 EXPECT_CALL(*binary_feature_extractor_
.get(), ExtractImageHeaders(a_tmp
, _
))
614 download_service_
->CheckClientDownload(
616 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
617 base::Unretained(this)));
618 MessageLoop::current()->Run();
620 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE
));
622 // On !OS_WIN, no file types are currently supported. Hence all erquests to
623 // CheckClientDownload() result in a verdict of UNKNOWN.
624 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
627 // Invalid response should result in UNKNOWN.
629 factory
.SetFakeResponse(
630 DownloadProtectionService::GetDownloadRequestUrl(),
631 response
.SerializePartialAsString(),
632 net::HTTP_OK
, net::URLRequestStatus::SUCCESS
);
634 download_service_
->CheckClientDownload(
636 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
637 base::Unretained(this)));
638 MessageLoop::current()->Run();
639 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
640 std::string feedback_ping
;
641 std::string feedback_response
;
642 EXPECT_FALSE(DownloadFeedbackService::GetPingsForDownloadForTesting(
643 item
, &feedback_ping
, &feedback_response
));
645 // If the response is dangerous the result should also be marked as dangerous.
646 response
.set_verdict(ClientDownloadResponse::DANGEROUS
);
647 factory
.SetFakeResponse(
648 DownloadProtectionService::GetDownloadRequestUrl(),
649 response
.SerializeAsString(),
650 net::HTTP_OK
, net::URLRequestStatus::SUCCESS
);
652 download_service_
->CheckClientDownload(
654 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
655 base::Unretained(this)));
656 MessageLoop::current()->Run();
657 EXPECT_FALSE(DownloadFeedbackService::GetPingsForDownloadForTesting(
658 item
, &feedback_ping
, &feedback_response
));
660 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS
));
662 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
665 // If the response is uncommon the result should also be marked as uncommon.
666 response
.set_verdict(ClientDownloadResponse::UNCOMMON
);
667 factory
.SetFakeResponse(
668 DownloadProtectionService::GetDownloadRequestUrl(),
669 response
.SerializeAsString(),
670 net::HTTP_OK
, net::URLRequestStatus::SUCCESS
);
672 download_service_
->CheckClientDownload(
674 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
675 base::Unretained(this)));
676 MessageLoop::current()->Run();
678 EXPECT_TRUE(IsResult(DownloadProtectionService::UNCOMMON
));
679 EXPECT_TRUE(DownloadFeedbackService::GetPingsForDownloadForTesting(
680 item
, &feedback_ping
, &feedback_response
));
681 ClientDownloadRequest decoded_request
;
682 EXPECT_TRUE(decoded_request
.ParseFromString(feedback_ping
));
683 EXPECT_EQ(url_chain
.back().spec(), decoded_request
.url());
684 EXPECT_EQ(response
.SerializeAsString(), feedback_response
);
686 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
689 // If the response is dangerous_host the result should also be marked as
691 response
.set_verdict(ClientDownloadResponse::DANGEROUS_HOST
);
692 factory
.SetFakeResponse(
693 DownloadProtectionService::GetDownloadRequestUrl(),
694 response
.SerializeAsString(),
695 net::HTTP_OK
, net::URLRequestStatus::SUCCESS
);
697 download_service_
->CheckClientDownload(
699 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
700 base::Unretained(this)));
701 MessageLoop::current()->Run();
703 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS_HOST
));
704 EXPECT_TRUE(DownloadFeedbackService::GetPingsForDownloadForTesting(
705 item
, &feedback_ping
, &feedback_response
));
706 EXPECT_EQ(response
.SerializeAsString(), feedback_response
);
708 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
711 // If the response is POTENTIALLY_UNWANTED the result should also be marked as
712 // POTENTIALLY_UNWANTED.
713 response
.set_verdict(ClientDownloadResponse::POTENTIALLY_UNWANTED
);
714 factory
.SetFakeResponse(
715 DownloadProtectionService::GetDownloadRequestUrl(),
716 response
.SerializeAsString(),
717 net::HTTP_OK
, net::URLRequestStatus::SUCCESS
);
719 download_service_
->CheckClientDownload(
721 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
722 base::Unretained(this)));
723 MessageLoop::current()->Run();
725 EXPECT_TRUE(IsResult(DownloadProtectionService::POTENTIALLY_UNWANTED
));
727 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
731 TEST_F(DownloadProtectionServiceTest
, CheckClientDownloadHTTPS
) {
732 ClientDownloadResponse response
;
733 response
.set_verdict(ClientDownloadResponse::DANGEROUS
);
734 net::FakeURLFetcherFactory
factory(NULL
);
735 factory
.SetFakeResponse(
736 DownloadProtectionService::GetDownloadRequestUrl(),
737 response
.SerializeAsString(),
738 net::HTTP_OK
, net::URLRequestStatus::SUCCESS
);
740 base::FilePath
a_tmp(FILE_PATH_LITERAL("a.tmp"));
741 base::FilePath
a_exe(FILE_PATH_LITERAL("a.exe"));
742 std::vector
<GURL
> url_chain
;
743 url_chain
.push_back(GURL("http://www.evil.com/a.exe"));
744 GURL
referrer("http://www.google.com/");
745 std::string hash
= "hash";
747 content::MockDownloadItem item
;
748 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp
));
749 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_exe
));
750 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
751 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
752 EXPECT_CALL(item
, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
753 EXPECT_CALL(item
, GetTabReferrerUrl())
754 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
755 EXPECT_CALL(item
, GetHash()).WillRepeatedly(ReturnRef(hash
));
756 EXPECT_CALL(item
, GetReceivedBytes()).WillRepeatedly(Return(100));
757 EXPECT_CALL(item
, HasUserGesture()).WillRepeatedly(Return(true));
758 EXPECT_CALL(item
, GetRemoteAddress()).WillRepeatedly(Return(""));
760 EXPECT_CALL(*sb_service_
->mock_database_manager(),
761 MatchDownloadWhitelistUrl(_
))
762 .WillRepeatedly(Return(false));
763 EXPECT_CALL(*binary_feature_extractor_
.get(), CheckSignature(a_tmp
, _
))
765 EXPECT_CALL(*binary_feature_extractor_
.get(), ExtractImageHeaders(a_tmp
, _
))
768 download_service_
->CheckClientDownload(
770 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
771 base::Unretained(this)));
772 MessageLoop::current()->Run();
774 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS
));
776 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
780 TEST_F(DownloadProtectionServiceTest
, CheckClientDownloadZip
) {
781 ClientDownloadResponse response
;
782 response
.set_verdict(ClientDownloadResponse::SAFE
);
783 net::FakeURLFetcherFactory
factory(NULL
);
784 // Empty response means SAFE.
785 factory
.SetFakeResponse(
786 DownloadProtectionService::GetDownloadRequestUrl(),
787 response
.SerializeAsString(),
788 net::HTTP_OK
, net::URLRequestStatus::SUCCESS
);
790 base::ScopedTempDir download_dir
;
791 ASSERT_TRUE(download_dir
.CreateUniqueTempDir());
793 base::FilePath
a_tmp(download_dir
.path().Append(FILE_PATH_LITERAL("a.tmp")));
794 base::FilePath
a_zip(FILE_PATH_LITERAL("a.zip"));
795 std::vector
<GURL
> url_chain
;
796 url_chain
.push_back(GURL("http://www.evil.com/a.zip"));
797 GURL
referrer("http://www.google.com/");
798 std::string hash
= "hash";
800 content::MockDownloadItem item
;
801 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp
));
802 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_zip
));
803 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
804 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
805 EXPECT_CALL(item
, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
806 EXPECT_CALL(item
, GetTabReferrerUrl())
807 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
808 EXPECT_CALL(item
, GetHash()).WillRepeatedly(ReturnRef(hash
));
809 EXPECT_CALL(item
, GetReceivedBytes()).WillRepeatedly(Return(100));
810 EXPECT_CALL(item
, HasUserGesture()).WillRepeatedly(Return(true));
811 EXPECT_CALL(item
, GetRemoteAddress()).WillRepeatedly(Return(""));
813 // Write out a zip archive to the temporary file. In this case, it
814 // only contains a text file.
815 base::ScopedTempDir zip_source_dir
;
816 ASSERT_TRUE(zip_source_dir
.CreateUniqueTempDir());
817 std::string file_contents
= "dummy file";
818 ASSERT_EQ(static_cast<int>(file_contents
.size()), base::WriteFile(
819 zip_source_dir
.path().Append(FILE_PATH_LITERAL("file.txt")),
820 file_contents
.data(), file_contents
.size()));
821 ASSERT_TRUE(zip::Zip(zip_source_dir
.path(), a_tmp
, false));
823 download_service_
->CheckClientDownload(
825 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
826 base::Unretained(this)));
827 MessageLoop::current()->Run();
828 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
829 Mock::VerifyAndClearExpectations(sb_service_
.get());
830 Mock::VerifyAndClearExpectations(binary_feature_extractor_
.get());
832 // Now check with an executable in the zip file as well.
833 ASSERT_EQ(static_cast<int>(file_contents
.size()), base::WriteFile(
834 zip_source_dir
.path().Append(FILE_PATH_LITERAL("file.exe")),
835 file_contents
.data(), file_contents
.size()));
836 ASSERT_TRUE(zip::Zip(zip_source_dir
.path(), a_tmp
, false));
838 EXPECT_CALL(*sb_service_
->mock_database_manager(),
839 MatchDownloadWhitelistUrl(_
))
840 .WillRepeatedly(Return(false));
842 download_service_
->CheckClientDownload(
844 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
845 base::Unretained(this)));
846 MessageLoop::current()->Run();
848 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE
));
850 // For !OS_WIN, no file types are currently supported. Hence the resulting
851 // verdict is UNKNOWN.
852 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
854 Mock::VerifyAndClearExpectations(binary_feature_extractor_
.get());
856 // If the response is dangerous the result should also be marked as
858 response
.set_verdict(ClientDownloadResponse::DANGEROUS
);
859 factory
.SetFakeResponse(
860 DownloadProtectionService::GetDownloadRequestUrl(),
861 response
.SerializeAsString(),
862 net::HTTP_OK
, net::URLRequestStatus::SUCCESS
);
864 download_service_
->CheckClientDownload(
866 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
867 base::Unretained(this)));
868 MessageLoop::current()->Run();
870 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS
));
872 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
874 Mock::VerifyAndClearExpectations(binary_feature_extractor_
.get());
877 TEST_F(DownloadProtectionServiceTest
, CheckClientDownloadCorruptZip
) {
878 base::ScopedTempDir download_dir
;
879 ASSERT_TRUE(download_dir
.CreateUniqueTempDir());
881 base::FilePath
a_tmp(download_dir
.path().Append(FILE_PATH_LITERAL("a.tmp")));
882 base::FilePath
a_zip(FILE_PATH_LITERAL("a.zip"));
883 std::vector
<GURL
> url_chain
;
884 url_chain
.push_back(GURL("http://www.evil.com/a.zip"));
885 GURL
referrer("http://www.google.com/");
886 std::string hash
= "hash";
888 content::MockDownloadItem item
;
889 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp
));
890 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_zip
));
891 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
892 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
893 EXPECT_CALL(item
, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
894 EXPECT_CALL(item
, GetTabReferrerUrl())
895 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
896 EXPECT_CALL(item
, GetHash()).WillRepeatedly(ReturnRef(hash
));
897 EXPECT_CALL(item
, GetReceivedBytes()).WillRepeatedly(Return(100));
898 EXPECT_CALL(item
, HasUserGesture()).WillRepeatedly(Return(true));
899 EXPECT_CALL(item
, GetRemoteAddress()).WillRepeatedly(Return(""));
901 std::string file_contents
= "corrupt zip file";
902 ASSERT_EQ(static_cast<int>(file_contents
.size()), base::WriteFile(
903 a_tmp
, file_contents
.data(), file_contents
.size()));
905 download_service_
->CheckClientDownload(
907 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
908 base::Unretained(this)));
909 MessageLoop::current()->Run();
910 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
911 Mock::VerifyAndClearExpectations(sb_service_
.get());
912 Mock::VerifyAndClearExpectations(binary_feature_extractor_
.get());
915 TEST_F(DownloadProtectionServiceTest
, CheckClientCrxDownloadSuccess
) {
916 ClientDownloadResponse response
;
917 // Even if the server verdict is dangerous we should return SAFE because
918 // DownloadProtectionService::IsSupportedDownload() will return false
919 // for crx downloads.
920 response
.set_verdict(ClientDownloadResponse::DANGEROUS
);
921 net::FakeURLFetcherFactory
factory(NULL
);
922 // Empty response means SAFE.
923 factory
.SetFakeResponse(
924 DownloadProtectionService::GetDownloadRequestUrl(),
925 response
.SerializeAsString(),
926 net::HTTP_OK
, net::URLRequestStatus::SUCCESS
);
928 base::FilePath
a_tmp(FILE_PATH_LITERAL("a.tmp"));
929 base::FilePath
a_crx(FILE_PATH_LITERAL("a.crx"));
930 std::vector
<GURL
> url_chain
;
931 url_chain
.push_back(GURL("http://www.evil.com/a.crx"));
932 GURL
referrer("http://www.google.com/");
933 std::string hash
= "hash";
935 content::MockDownloadItem item
;
936 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp
));
937 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_crx
));
938 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
939 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
940 EXPECT_CALL(item
, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
941 EXPECT_CALL(item
, GetTabReferrerUrl())
942 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
943 EXPECT_CALL(item
, GetHash()).WillRepeatedly(ReturnRef(hash
));
944 EXPECT_CALL(item
, GetReceivedBytes()).WillRepeatedly(Return(100));
945 EXPECT_CALL(item
, HasUserGesture()).WillRepeatedly(Return(true));
946 EXPECT_CALL(item
, GetRemoteAddress()).WillRepeatedly(Return(""));
948 EXPECT_CALL(*sb_service_
->mock_database_manager(),
949 MatchDownloadWhitelistUrl(_
))
950 .WillRepeatedly(Return(false));
951 EXPECT_CALL(*binary_feature_extractor_
.get(), CheckSignature(a_tmp
, _
))
953 EXPECT_CALL(*binary_feature_extractor_
.get(), ExtractImageHeaders(a_tmp
, _
))
956 EXPECT_FALSE(download_service_
->IsSupportedDownload(item
, a_crx
));
957 download_service_
->CheckClientDownload(
959 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
960 base::Unretained(this)));
961 MessageLoop::current()->Run();
962 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
965 #if defined(OS_MACOSX)
966 // TODO(mattm): remove this (see crbug.com/414834).
967 TEST_F(DownloadProtectionServiceTest
,
968 CheckClientDownloadPingOnOSXRequiresFieldTrial
) {
969 // Clear the field trial that was set in SetUp().
970 field_trial_list_
.reset();
972 net::TestURLFetcherFactory factory
;
974 base::FilePath
tmp_path(FILE_PATH_LITERAL("bla.tmp"));
975 base::FilePath
final_path(FILE_PATH_LITERAL("bla.exe"));
976 std::vector
<GURL
> url_chain
;
977 url_chain
.push_back(GURL("http://www.google.com/"));
978 url_chain
.push_back(GURL("http://www.google.com/bla.exe"));
979 GURL
referrer("http://www.google.com/");
980 std::string hash
= "hash";
981 std::string remote_address
= "10.11.12.13";
983 content::MockDownloadItem item
;
984 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(tmp_path
));
985 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(final_path
));
986 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
987 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
988 EXPECT_CALL(item
, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
989 EXPECT_CALL(item
, GetTabReferrerUrl())
990 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
991 EXPECT_CALL(item
, GetHash()).WillRepeatedly(ReturnRef(hash
));
992 EXPECT_CALL(item
, GetReceivedBytes()).WillRepeatedly(Return(100));
993 EXPECT_CALL(item
, HasUserGesture()).WillRepeatedly(Return(true));
994 EXPECT_CALL(item
, GetRemoteAddress()).WillRepeatedly(Return(remote_address
));
996 EXPECT_CALL(*sb_service_
->mock_database_manager(),
997 MatchDownloadWhitelistUrl(_
))
998 .WillRepeatedly(Return(false));
999 EXPECT_CALL(*binary_feature_extractor_
.get(), CheckSignature(tmp_path
, _
))
1000 .WillOnce(SetCertificateContents("dummy cert data"));
1001 EXPECT_CALL(*binary_feature_extractor_
.get(),
1002 ExtractImageHeaders(tmp_path
, _
))
1003 .WillOnce(SetDosHeaderContents("dummy dos header"));
1004 download_service_
->CheckClientDownload(
1006 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
1007 base::Unretained(this)));
1009 // SendRequest is not called. Wait for FinishRequest to call our callback.
1010 MessageLoop::current()->Run();
1011 net::TestURLFetcher
* fetcher
= factory
.GetFetcherByID(0);
1012 EXPECT_EQ(NULL
, fetcher
);
1016 TEST_F(DownloadProtectionServiceTest
, CheckClientDownloadValidateRequest
) {
1017 net::TestURLFetcherFactory factory
;
1019 base::FilePath
tmp_path(FILE_PATH_LITERAL("bla.tmp"));
1020 base::FilePath
final_path(FILE_PATH_LITERAL("bla.exe"));
1021 std::vector
<GURL
> url_chain
;
1022 url_chain
.push_back(GURL("http://www.google.com/"));
1023 url_chain
.push_back(GURL("http://www.google.com/bla.exe"));
1024 GURL
referrer("http://www.google.com/");
1025 std::string hash
= "hash";
1026 std::string remote_address
= "10.11.12.13";
1028 content::MockDownloadItem item
;
1029 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(tmp_path
));
1030 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(final_path
));
1031 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
1032 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
1033 EXPECT_CALL(item
, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
1034 EXPECT_CALL(item
, GetTabReferrerUrl())
1035 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
1036 EXPECT_CALL(item
, GetHash()).WillRepeatedly(ReturnRef(hash
));
1037 EXPECT_CALL(item
, GetReceivedBytes()).WillRepeatedly(Return(100));
1038 EXPECT_CALL(item
, HasUserGesture()).WillRepeatedly(Return(true));
1039 EXPECT_CALL(item
, GetRemoteAddress()).WillRepeatedly(Return(remote_address
));
1041 EXPECT_CALL(*sb_service_
->mock_database_manager(),
1042 MatchDownloadWhitelistUrl(_
))
1043 .WillRepeatedly(Return(false));
1044 EXPECT_CALL(*binary_feature_extractor_
.get(), CheckSignature(tmp_path
, _
))
1045 .WillOnce(SetCertificateContents("dummy cert data"));
1046 EXPECT_CALL(*binary_feature_extractor_
.get(),
1047 ExtractImageHeaders(tmp_path
, _
))
1048 .WillOnce(SetDosHeaderContents("dummy dos header"));
1049 download_service_
->CheckClientDownload(
1051 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
1052 base::Unretained(this)));
1054 #if !defined(OS_WIN) && !defined(OS_MACOSX)
1055 // SendRequest is not called. Wait for FinishRequest to call our callback.
1056 MessageLoop::current()->Run();
1057 net::TestURLFetcher
* fetcher
= factory
.GetFetcherByID(0);
1058 EXPECT_EQ(NULL
, fetcher
);
1060 // Run the message loop(s) until SendRequest is called.
1061 FlushThreadMessageLoops();
1062 net::TestURLFetcher
* fetcher
= factory
.GetFetcherByID(0);
1063 ASSERT_TRUE(fetcher
);
1064 ClientDownloadRequest request
;
1065 EXPECT_TRUE(request
.ParseFromString(fetcher
->upload_data()));
1066 EXPECT_EQ("http://www.google.com/bla.exe", request
.url());
1067 EXPECT_EQ(hash
, request
.digests().sha256());
1068 EXPECT_EQ(item
.GetReceivedBytes(), request
.length());
1069 EXPECT_EQ(item
.HasUserGesture(), request
.user_initiated());
1070 EXPECT_TRUE(RequestContainsServerIp(request
, remote_address
));
1071 EXPECT_EQ(2, request
.resources_size());
1072 EXPECT_TRUE(RequestContainsResource(request
,
1073 ClientDownloadRequest::DOWNLOAD_REDIRECT
,
1074 "http://www.google.com/", ""));
1075 EXPECT_TRUE(RequestContainsResource(request
,
1076 ClientDownloadRequest::DOWNLOAD_URL
,
1077 "http://www.google.com/bla.exe",
1079 EXPECT_TRUE(request
.has_signature());
1080 ASSERT_EQ(1, request
.signature().certificate_chain_size());
1081 const ClientDownloadRequest_CertificateChain
& chain
=
1082 request
.signature().certificate_chain(0);
1083 ASSERT_EQ(1, chain
.element_size());
1084 EXPECT_EQ("dummy cert data", chain
.element(0).certificate());
1085 EXPECT_TRUE(request
.has_image_headers());
1086 const ClientDownloadRequest_ImageHeaders
& headers
=
1087 request
.image_headers();
1088 EXPECT_TRUE(headers
.has_pe_headers());
1089 EXPECT_TRUE(headers
.pe_headers().has_dos_header());
1090 EXPECT_EQ("dummy dos header", headers
.pe_headers().dos_header());
1092 // Simulate the request finishing.
1093 base::MessageLoop::current()->PostTask(
1095 base::Bind(&DownloadProtectionServiceTest::SendURLFetchComplete
,
1096 base::Unretained(this), fetcher
));
1097 MessageLoop::current()->Run();
1101 // Similar to above, but with an unsigned binary.
1102 TEST_F(DownloadProtectionServiceTest
,
1103 CheckClientDownloadValidateRequestNoSignature
) {
1104 net::TestURLFetcherFactory factory
;
1106 base::FilePath
tmp_path(FILE_PATH_LITERAL("bla.tmp"));
1107 base::FilePath
final_path(FILE_PATH_LITERAL("bla.exe"));
1108 std::vector
<GURL
> url_chain
;
1109 url_chain
.push_back(GURL("http://www.google.com/"));
1110 url_chain
.push_back(GURL("ftp://www.google.com/bla.exe"));
1111 GURL
referrer("http://www.google.com/");
1112 std::string hash
= "hash";
1113 std::string remote_address
= "10.11.12.13";
1115 content::MockDownloadItem item
;
1116 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(tmp_path
));
1117 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(final_path
));
1118 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
1119 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
1120 EXPECT_CALL(item
, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
1121 EXPECT_CALL(item
, GetTabReferrerUrl())
1122 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
1123 EXPECT_CALL(item
, GetHash()).WillRepeatedly(ReturnRef(hash
));
1124 EXPECT_CALL(item
, GetReceivedBytes()).WillRepeatedly(Return(100));
1125 EXPECT_CALL(item
, HasUserGesture()).WillRepeatedly(Return(true));
1126 EXPECT_CALL(item
, GetRemoteAddress()).WillRepeatedly(Return(remote_address
));
1128 EXPECT_CALL(*sb_service_
->mock_database_manager(),
1129 MatchDownloadWhitelistUrl(_
))
1130 .WillRepeatedly(Return(false));
1131 EXPECT_CALL(*binary_feature_extractor_
.get(), CheckSignature(tmp_path
, _
));
1132 EXPECT_CALL(*binary_feature_extractor_
.get(),
1133 ExtractImageHeaders(tmp_path
, _
));
1134 download_service_
->CheckClientDownload(
1136 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
1137 base::Unretained(this)));
1139 #if !defined(OS_WIN) && !defined(OS_MACOSX)
1140 // SendRequest is not called. Wait for FinishRequest to call our callback.
1141 MessageLoop::current()->Run();
1142 net::TestURLFetcher
* fetcher
= factory
.GetFetcherByID(0);
1143 EXPECT_EQ(NULL
, fetcher
);
1145 // Run the message loop(s) until SendRequest is called.
1146 FlushThreadMessageLoops();
1147 net::TestURLFetcher
* fetcher
= factory
.GetFetcherByID(0);
1148 ASSERT_TRUE(fetcher
);
1149 ClientDownloadRequest request
;
1150 EXPECT_TRUE(request
.ParseFromString(fetcher
->upload_data()));
1151 EXPECT_EQ("ftp://www.google.com/bla.exe", request
.url());
1152 EXPECT_EQ(hash
, request
.digests().sha256());
1153 EXPECT_EQ(item
.GetReceivedBytes(), request
.length());
1154 EXPECT_EQ(item
.HasUserGesture(), request
.user_initiated());
1155 EXPECT_EQ(2, request
.resources_size());
1156 EXPECT_TRUE(RequestContainsResource(request
,
1157 ClientDownloadRequest::DOWNLOAD_REDIRECT
,
1158 "http://www.google.com/", ""));
1159 EXPECT_TRUE(RequestContainsResource(request
,
1160 ClientDownloadRequest::DOWNLOAD_URL
,
1161 "ftp://www.google.com/bla.exe",
1163 EXPECT_TRUE(request
.has_signature());
1164 EXPECT_EQ(0, request
.signature().certificate_chain_size());
1166 // Simulate the request finishing.
1167 base::MessageLoop::current()->PostTask(
1169 base::Bind(&DownloadProtectionServiceTest::SendURLFetchComplete
,
1170 base::Unretained(this), fetcher
));
1171 MessageLoop::current()->Run();
1175 // Similar to above, but with tab history.
1176 TEST_F(DownloadProtectionServiceTest
,
1177 CheckClientDownloadValidateRequestTabHistory
) {
1178 net::TestURLFetcherFactory factory
;
1180 base::ScopedTempDir profile_dir
;
1181 ASSERT_TRUE(profile_dir
.CreateUniqueTempDir());
1182 TestingProfile
profile(profile_dir
.path());
1184 profile
.CreateHistoryService(true /* delete_file */, false /* no_db */));
1186 base::FilePath
tmp_path(FILE_PATH_LITERAL("bla.tmp"));
1187 base::FilePath
final_path(FILE_PATH_LITERAL("bla.exe"));
1188 std::vector
<GURL
> url_chain
;
1189 url_chain
.push_back(GURL("http://www.google.com/"));
1190 url_chain
.push_back(GURL("http://www.google.com/bla.exe"));
1191 GURL
referrer("http://www.google.com/");
1192 GURL
tab_url("http://tab.com/final");
1193 GURL
tab_referrer("http://tab.com/referrer");
1194 std::string hash
= "hash";
1195 std::string remote_address
= "10.11.12.13";
1197 content::MockDownloadItem item
;
1198 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(tmp_path
));
1199 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(final_path
));
1200 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
1201 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
1202 EXPECT_CALL(item
, GetTabUrl()).WillRepeatedly(ReturnRef(tab_url
));
1203 EXPECT_CALL(item
, GetTabReferrerUrl())
1204 .WillRepeatedly(ReturnRef(tab_referrer
));
1205 EXPECT_CALL(item
, GetHash()).WillRepeatedly(ReturnRef(hash
));
1206 EXPECT_CALL(item
, GetReceivedBytes()).WillRepeatedly(Return(100));
1207 EXPECT_CALL(item
, HasUserGesture()).WillRepeatedly(Return(true));
1208 EXPECT_CALL(item
, GetRemoteAddress()).WillRepeatedly(Return(remote_address
));
1209 EXPECT_CALL(item
, GetBrowserContext()).WillRepeatedly(Return(&profile
));
1210 EXPECT_CALL(*sb_service_
->mock_database_manager(),
1211 MatchDownloadWhitelistUrl(_
))
1212 .WillRepeatedly(Return(false));
1213 EXPECT_CALL(*binary_feature_extractor_
.get(), CheckSignature(tmp_path
, _
))
1214 .WillRepeatedly(SetCertificateContents("dummy cert data"));
1215 EXPECT_CALL(*binary_feature_extractor_
.get(),
1216 ExtractImageHeaders(tmp_path
, _
))
1217 .WillRepeatedly(SetDosHeaderContents("dummy dos header"));
1219 // First test with no history match for the tab URL.
1221 TestURLFetcherWatcher
fetcher_watcher(&factory
);
1222 download_service_
->CheckClientDownload(
1224 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
1225 base::Unretained(this)));
1227 #if !defined(OS_WIN) && !defined(OS_MACOSX)
1228 // SendRequest is not called. Wait for FinishRequest to call our callback.
1229 MessageLoop::current()->Run();
1230 net::TestURLFetcher
* fetcher
= factory
.GetFetcherByID(0);
1231 EXPECT_EQ(NULL
, fetcher
);
1233 EXPECT_EQ(0, fetcher_watcher
.WaitForRequest());
1234 net::TestURLFetcher
* fetcher
= factory
.GetFetcherByID(0);
1235 ASSERT_TRUE(fetcher
);
1236 ClientDownloadRequest request
;
1237 EXPECT_TRUE(request
.ParseFromString(fetcher
->upload_data()));
1238 EXPECT_EQ("http://www.google.com/bla.exe", request
.url());
1239 EXPECT_EQ(hash
, request
.digests().sha256());
1240 EXPECT_EQ(item
.GetReceivedBytes(), request
.length());
1241 EXPECT_EQ(item
.HasUserGesture(), request
.user_initiated());
1242 EXPECT_TRUE(RequestContainsServerIp(request
, remote_address
));
1243 EXPECT_EQ(3, request
.resources_size());
1245 RequestContainsResource(request
,
1246 ClientDownloadRequest::DOWNLOAD_REDIRECT
,
1247 "http://www.google.com/",
1249 EXPECT_TRUE(RequestContainsResource(request
,
1250 ClientDownloadRequest::DOWNLOAD_URL
,
1251 "http://www.google.com/bla.exe",
1253 EXPECT_TRUE(RequestContainsResource(request
,
1254 ClientDownloadRequest::TAB_URL
,
1256 tab_referrer
.spec()));
1257 EXPECT_TRUE(request
.has_signature());
1258 ASSERT_EQ(1, request
.signature().certificate_chain_size());
1259 const ClientDownloadRequest_CertificateChain
& chain
=
1260 request
.signature().certificate_chain(0);
1261 ASSERT_EQ(1, chain
.element_size());
1262 EXPECT_EQ("dummy cert data", chain
.element(0).certificate());
1263 EXPECT_TRUE(request
.has_image_headers());
1264 const ClientDownloadRequest_ImageHeaders
& headers
=
1265 request
.image_headers();
1266 EXPECT_TRUE(headers
.has_pe_headers());
1267 EXPECT_TRUE(headers
.pe_headers().has_dos_header());
1268 EXPECT_EQ("dummy dos header", headers
.pe_headers().dos_header());
1270 // Simulate the request finishing.
1271 base::MessageLoop::current()->PostTask(
1273 base::Bind(&DownloadProtectionServiceTest::SendURLFetchComplete
,
1274 base::Unretained(this),
1276 MessageLoop::current()->Run();
1280 // Now try with a history match.
1282 history::RedirectList redirects
;
1283 redirects
.push_back(GURL("http://tab.com/ref1"));
1284 redirects
.push_back(GURL("http://tab.com/ref2"));
1285 redirects
.push_back(tab_url
);
1286 HistoryServiceFactory::GetForProfile(&profile
, Profile::EXPLICIT_ACCESS
)
1289 reinterpret_cast<history::ContextID
>(1),
1293 ui::PAGE_TRANSITION_TYPED
,
1294 history::SOURCE_BROWSED
,
1297 TestURLFetcherWatcher
fetcher_watcher(&factory
);
1298 download_service_
->CheckClientDownload(
1300 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
1301 base::Unretained(this)));
1302 #if !defined(OS_WIN) && !defined(OS_MACOSX)
1303 // SendRequest is not called. Wait for FinishRequest to call our callback.
1304 MessageLoop::current()->Run();
1305 net::TestURLFetcher
* fetcher
= factory
.GetFetcherByID(0);
1306 EXPECT_EQ(NULL
, fetcher
);
1308 EXPECT_EQ(0, fetcher_watcher
.WaitForRequest());
1309 net::TestURLFetcher
* fetcher
= factory
.GetFetcherByID(0);
1310 ASSERT_TRUE(fetcher
);
1311 ClientDownloadRequest request
;
1312 EXPECT_TRUE(request
.ParseFromString(fetcher
->upload_data()));
1313 EXPECT_EQ("http://www.google.com/bla.exe", request
.url());
1314 EXPECT_EQ(hash
, request
.digests().sha256());
1315 EXPECT_EQ(item
.GetReceivedBytes(), request
.length());
1316 EXPECT_EQ(item
.HasUserGesture(), request
.user_initiated());
1317 EXPECT_TRUE(RequestContainsServerIp(request
, remote_address
));
1318 EXPECT_EQ(5, request
.resources_size());
1320 RequestContainsResource(request
,
1321 ClientDownloadRequest::DOWNLOAD_REDIRECT
,
1322 "http://www.google.com/",
1324 EXPECT_TRUE(RequestContainsResource(request
,
1325 ClientDownloadRequest::DOWNLOAD_URL
,
1326 "http://www.google.com/bla.exe",
1328 EXPECT_TRUE(RequestContainsResource(request
,
1329 ClientDownloadRequest::TAB_REDIRECT
,
1330 "http://tab.com/ref1",
1332 EXPECT_TRUE(RequestContainsResource(request
,
1333 ClientDownloadRequest::TAB_REDIRECT
,
1334 "http://tab.com/ref2",
1336 EXPECT_TRUE(RequestContainsResource(request
,
1337 ClientDownloadRequest::TAB_URL
,
1339 tab_referrer
.spec()));
1340 EXPECT_TRUE(request
.has_signature());
1341 ASSERT_EQ(1, request
.signature().certificate_chain_size());
1342 const ClientDownloadRequest_CertificateChain
& chain
=
1343 request
.signature().certificate_chain(0);
1344 ASSERT_EQ(1, chain
.element_size());
1345 EXPECT_EQ("dummy cert data", chain
.element(0).certificate());
1347 // Simulate the request finishing.
1348 base::MessageLoop::current()->PostTask(
1350 base::Bind(&DownloadProtectionServiceTest::SendURLFetchComplete
,
1351 base::Unretained(this),
1353 MessageLoop::current()->Run();
1358 TEST_F(DownloadProtectionServiceTest
, TestCheckDownloadUrl
) {
1359 std::vector
<GURL
> url_chain
;
1360 url_chain
.push_back(GURL("http://www.google.com/"));
1361 url_chain
.push_back(GURL("http://www.google.com/bla.exe"));
1362 GURL
referrer("http://www.google.com/");
1363 std::string hash
= "hash";
1365 content::MockDownloadItem item
;
1366 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
1367 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
1368 EXPECT_CALL(item
, GetHash()).WillRepeatedly(ReturnRef(hash
));
1370 // CheckDownloadURL returns immediately which means the client object callback
1371 // will never be called. Nevertheless the callback provided to
1372 // CheckClientDownload must still be called.
1373 EXPECT_CALL(*sb_service_
->mock_database_manager(),
1374 CheckDownloadUrl(ContainerEq(url_chain
), NotNull()))
1375 .WillOnce(Return(true));
1376 download_service_
->CheckDownloadUrl(
1378 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
1379 base::Unretained(this)));
1380 MessageLoop::current()->Run();
1381 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE
));
1382 Mock::VerifyAndClearExpectations(sb_service_
.get());
1384 EXPECT_CALL(*sb_service_
->mock_database_manager(),
1385 CheckDownloadUrl(ContainerEq(url_chain
), NotNull()))
1386 .WillOnce(DoAll(CheckDownloadUrlDone(SB_THREAT_TYPE_SAFE
),
1388 download_service_
->CheckDownloadUrl(
1390 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
1391 base::Unretained(this)));
1392 MessageLoop::current()->Run();
1393 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE
));
1394 Mock::VerifyAndClearExpectations(sb_service_
.get());
1396 EXPECT_CALL(*sb_service_
->mock_database_manager(),
1397 CheckDownloadUrl(ContainerEq(url_chain
), NotNull()))
1399 CheckDownloadUrlDone(SB_THREAT_TYPE_URL_MALWARE
),
1401 download_service_
->CheckDownloadUrl(
1403 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
1404 base::Unretained(this)));
1405 MessageLoop::current()->Run();
1406 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE
));
1407 Mock::VerifyAndClearExpectations(sb_service_
.get());
1409 EXPECT_CALL(*sb_service_
->mock_database_manager(),
1410 CheckDownloadUrl(ContainerEq(url_chain
),
1413 CheckDownloadUrlDone(SB_THREAT_TYPE_BINARY_MALWARE_URL
),
1415 download_service_
->CheckDownloadUrl(
1417 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
1418 base::Unretained(this)));
1419 MessageLoop::current()->Run();
1420 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS
));
1423 TEST_F(DownloadProtectionServiceTest
, TestDownloadRequestTimeout
) {
1424 net::TestURLFetcherFactory factory
;
1426 std::vector
<GURL
> url_chain
;
1427 url_chain
.push_back(GURL("http://www.evil.com/bla.exe"));
1428 GURL
referrer("http://www.google.com/");
1429 base::FilePath
tmp_path(FILE_PATH_LITERAL("a.tmp"));
1430 base::FilePath
final_path(FILE_PATH_LITERAL("a.exe"));
1431 std::string hash
= "hash";
1433 content::MockDownloadItem item
;
1434 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(tmp_path
));
1435 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(final_path
));
1436 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
1437 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
1438 EXPECT_CALL(item
, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
1439 EXPECT_CALL(item
, GetTabReferrerUrl())
1440 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
1441 EXPECT_CALL(item
, GetHash()).WillRepeatedly(ReturnRef(hash
));
1442 EXPECT_CALL(item
, GetReceivedBytes()).WillRepeatedly(Return(100));
1443 EXPECT_CALL(item
, HasUserGesture()).WillRepeatedly(Return(true));
1444 EXPECT_CALL(item
, GetRemoteAddress()).WillRepeatedly(Return(""));
1446 EXPECT_CALL(*sb_service_
->mock_database_manager(),
1447 MatchDownloadWhitelistUrl(_
))
1448 .WillRepeatedly(Return(false));
1449 EXPECT_CALL(*binary_feature_extractor_
.get(), CheckSignature(tmp_path
, _
));
1450 EXPECT_CALL(*binary_feature_extractor_
.get(),
1451 ExtractImageHeaders(tmp_path
, _
));
1453 download_service_
->download_request_timeout_ms_
= 10;
1454 download_service_
->CheckClientDownload(
1456 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
1457 base::Unretained(this)));
1459 // The request should time out because the HTTP request hasn't returned
1461 MessageLoop::current()->Run();
1462 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
1465 TEST_F(DownloadProtectionServiceTest
, TestDownloadItemDestroyed
) {
1466 net::TestURLFetcherFactory factory
;
1468 std::vector
<GURL
> url_chain
;
1469 url_chain
.push_back(GURL("http://www.evil.com/bla.exe"));
1470 GURL
referrer("http://www.google.com/");
1471 base::FilePath
tmp_path(FILE_PATH_LITERAL("a.tmp"));
1472 base::FilePath
final_path(FILE_PATH_LITERAL("a.exe"));
1473 std::string hash
= "hash";
1476 content::MockDownloadItem item
;
1477 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(tmp_path
));
1478 EXPECT_CALL(item
, GetTargetFilePath())
1479 .WillRepeatedly(ReturnRef(final_path
));
1480 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
1481 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
1482 EXPECT_CALL(item
, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
1483 EXPECT_CALL(item
, GetTabReferrerUrl())
1484 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
1485 EXPECT_CALL(item
, GetHash()).WillRepeatedly(ReturnRef(hash
));
1486 EXPECT_CALL(item
, GetReceivedBytes()).WillRepeatedly(Return(100));
1487 EXPECT_CALL(item
, HasUserGesture()).WillRepeatedly(Return(true));
1488 EXPECT_CALL(item
, GetRemoteAddress()).WillRepeatedly(Return(""));
1490 EXPECT_CALL(*sb_service_
->mock_database_manager(),
1491 MatchDownloadWhitelistUrl(_
))
1492 .WillRepeatedly(Return(false));
1493 EXPECT_CALL(*binary_feature_extractor_
.get(), CheckSignature(tmp_path
, _
));
1494 EXPECT_CALL(*binary_feature_extractor_
.get(),
1495 ExtractImageHeaders(tmp_path
, _
));
1497 download_service_
->CheckClientDownload(
1499 base::Bind(&DownloadProtectionServiceTest::SyncCheckDoneCallback
,
1500 base::Unretained(this)));
1501 // MockDownloadItem going out of scope triggers the OnDownloadDestroyed
1505 EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN
));
1508 TEST_F(DownloadProtectionServiceTest
, GetCertificateWhitelistStrings
) {
1509 // We'll pass this cert in as the "issuer", even though it isn't really
1510 // used to sign the certs below. GetCertificateWhitelistStirngs doesn't care
1512 scoped_refptr
<net::X509Certificate
> issuer_cert(
1513 ReadTestCertificate("issuer.pem"));
1514 ASSERT_TRUE(issuer_cert
.get());
1515 std::string cert_base
= "cert/" + base::HexEncode(
1516 issuer_cert
->fingerprint().data
,
1517 sizeof(issuer_cert
->fingerprint().data
));
1519 scoped_refptr
<net::X509Certificate
> cert(ReadTestCertificate("test_cn.pem"));
1520 ASSERT_TRUE(cert
.get());
1521 std::vector
<std::string
> whitelist_strings
;
1522 GetCertificateWhitelistStrings(
1523 *cert
.get(), *issuer_cert
.get(), &whitelist_strings
);
1524 // This also tests escaping of characters in the certificate attributes.
1525 EXPECT_THAT(whitelist_strings
, ElementsAre(
1526 cert_base
+ "/CN=subject%2F%251"));
1528 cert
= ReadTestCertificate("test_cn_o.pem");
1529 ASSERT_TRUE(cert
.get());
1530 whitelist_strings
.clear();
1531 GetCertificateWhitelistStrings(
1532 *cert
.get(), *issuer_cert
.get(), &whitelist_strings
);
1533 EXPECT_THAT(whitelist_strings
,
1534 ElementsAre(cert_base
+ "/CN=subject",
1535 cert_base
+ "/CN=subject/O=org",
1536 cert_base
+ "/O=org"));
1538 cert
= ReadTestCertificate("test_cn_o_ou.pem");
1539 ASSERT_TRUE(cert
.get());
1540 whitelist_strings
.clear();
1541 GetCertificateWhitelistStrings(
1542 *cert
.get(), *issuer_cert
.get(), &whitelist_strings
);
1543 EXPECT_THAT(whitelist_strings
,
1544 ElementsAre(cert_base
+ "/CN=subject",
1545 cert_base
+ "/CN=subject/O=org",
1546 cert_base
+ "/CN=subject/O=org/OU=unit",
1547 cert_base
+ "/CN=subject/OU=unit",
1548 cert_base
+ "/O=org",
1549 cert_base
+ "/O=org/OU=unit",
1550 cert_base
+ "/OU=unit"));
1552 cert
= ReadTestCertificate("test_cn_ou.pem");
1553 ASSERT_TRUE(cert
.get());
1554 whitelist_strings
.clear();
1555 GetCertificateWhitelistStrings(
1556 *cert
.get(), *issuer_cert
.get(), &whitelist_strings
);
1557 EXPECT_THAT(whitelist_strings
,
1558 ElementsAre(cert_base
+ "/CN=subject",
1559 cert_base
+ "/CN=subject/OU=unit",
1560 cert_base
+ "/OU=unit"));
1562 cert
= ReadTestCertificate("test_o.pem");
1563 ASSERT_TRUE(cert
.get());
1564 whitelist_strings
.clear();
1565 GetCertificateWhitelistStrings(
1566 *cert
.get(), *issuer_cert
.get(), &whitelist_strings
);
1567 EXPECT_THAT(whitelist_strings
, ElementsAre(cert_base
+ "/O=org"));
1569 cert
= ReadTestCertificate("test_o_ou.pem");
1570 ASSERT_TRUE(cert
.get());
1571 whitelist_strings
.clear();
1572 GetCertificateWhitelistStrings(
1573 *cert
.get(), *issuer_cert
.get(), &whitelist_strings
);
1574 EXPECT_THAT(whitelist_strings
,
1575 ElementsAre(cert_base
+ "/O=org",
1576 cert_base
+ "/O=org/OU=unit",
1577 cert_base
+ "/OU=unit"));
1579 cert
= ReadTestCertificate("test_ou.pem");
1580 ASSERT_TRUE(cert
.get());
1581 whitelist_strings
.clear();
1582 GetCertificateWhitelistStrings(
1583 *cert
.get(), *issuer_cert
.get(), &whitelist_strings
);
1584 EXPECT_THAT(whitelist_strings
, ElementsAre(cert_base
+ "/OU=unit"));
1586 cert
= ReadTestCertificate("test_c.pem");
1587 ASSERT_TRUE(cert
.get());
1588 whitelist_strings
.clear();
1589 GetCertificateWhitelistStrings(
1590 *cert
.get(), *issuer_cert
.get(), &whitelist_strings
);
1591 EXPECT_THAT(whitelist_strings
, ElementsAre());
1593 } // namespace safe_browsing