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/file_util.h"
14 #include "base/files/file_path.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/safe_browsing/database_manager.h"
24 #include "chrome/browser/safe_browsing/download_feedback_service.h"
25 #include "chrome/browser/safe_browsing/safe_browsing_service.h"
26 #include "chrome/browser/safe_browsing/signature_util.h"
27 #include "chrome/common/safe_browsing/csd.pb.h"
28 #include "content/public/test/mock_download_item.h"
29 #include "content/public/test/test_browser_thread_bundle.h"
30 #include "content/public/test/test_utils.h"
31 #include "net/cert/x509_certificate.h"
32 #include "net/http/http_status_code.h"
33 #include "net/url_request/test_url_fetcher_factory.h"
34 #include "net/url_request/url_fetcher_delegate.h"
35 #include "net/url_request/url_request_status.h"
36 #include "testing/gmock/include/gmock/gmock.h"
37 #include "testing/gtest/include/gtest/gtest.h"
38 #include "third_party/zlib/google/zip.h"
41 using ::testing::Assign
;
42 using ::testing::ContainerEq
;
43 using ::testing::DoAll
;
44 using ::testing::ElementsAre
;
45 using ::testing::Mock
;
46 using ::testing::NotNull
;
47 using ::testing::Return
;
48 using ::testing::ReturnRef
;
49 using ::testing::SaveArg
;
50 using ::testing::StrictMock
;
52 using base::MessageLoop
;
53 using content::BrowserThread
;
54 namespace safe_browsing
{
56 // A SafeBrowsingDatabaseManager implementation that returns a fixed result for
58 class MockSafeBrowsingDatabaseManager
: public SafeBrowsingDatabaseManager
{
60 explicit MockSafeBrowsingDatabaseManager(SafeBrowsingService
* service
)
61 : SafeBrowsingDatabaseManager(service
) { }
63 MOCK_METHOD1(MatchDownloadWhitelistUrl
, bool(const GURL
&));
64 MOCK_METHOD1(MatchDownloadWhitelistString
, bool(const std::string
&));
65 MOCK_METHOD2(CheckDownloadUrl
, bool(
66 const std::vector
<GURL
>& url_chain
,
67 SafeBrowsingDatabaseManager::Client
* client
));
70 virtual ~MockSafeBrowsingDatabaseManager() {}
71 DISALLOW_COPY_AND_ASSIGN(MockSafeBrowsingDatabaseManager
);
74 class FakeSafeBrowsingService
: public SafeBrowsingService
{
76 FakeSafeBrowsingService() { }
78 // Returned pointer has the same lifespan as the database_manager_ refcounted
80 MockSafeBrowsingDatabaseManager
* mock_database_manager() {
81 return mock_database_manager_
;
85 virtual ~FakeSafeBrowsingService() { }
87 virtual SafeBrowsingDatabaseManager
* CreateDatabaseManager() OVERRIDE
{
88 mock_database_manager_
= new MockSafeBrowsingDatabaseManager(this);
89 return mock_database_manager_
;
93 MockSafeBrowsingDatabaseManager
* mock_database_manager_
;
95 DISALLOW_COPY_AND_ASSIGN(FakeSafeBrowsingService
);
98 class MockSignatureUtil
: public SignatureUtil
{
100 MockSignatureUtil() {}
101 MOCK_METHOD2(CheckSignature
, void (const base::FilePath
&,
102 ClientDownloadRequest_SignatureInfo
*));
105 virtual ~MockSignatureUtil() {}
108 DISALLOW_COPY_AND_ASSIGN(MockSignatureUtil
);
112 ACTION_P(SetCertificateContents
, contents
) {
113 arg1
->add_certificate_chain()->add_element()->set_certificate(contents
);
116 ACTION_P(TrustSignature
, certificate_file
) {
117 arg1
->set_trusted(true);
118 // Add a certificate chain. Note that we add the certificate twice so that
119 // it appears as its own issuer.
120 std::string cert_data
;
121 ASSERT_TRUE(base::ReadFileToString(certificate_file
, &cert_data
));
122 ClientDownloadRequest_CertificateChain
* chain
=
123 arg1
->add_certificate_chain();
124 chain
->add_element()->set_certificate(cert_data
);
125 chain
->add_element()->set_certificate(cert_data
);
128 // We can't call OnSafeBrowsingResult directly because SafeBrowsingCheck does
129 // not have any copy constructor which means it can't be stored in a callback
130 // easily. Note: check will be deleted automatically when the callback is
132 void OnSafeBrowsingResult(
133 SafeBrowsingDatabaseManager::SafeBrowsingCheck
* check
) {
134 check
->client
->OnSafeBrowsingResult(*check
);
137 ACTION_P(CheckDownloadUrlDone
, threat_type
) {
138 SafeBrowsingDatabaseManager::SafeBrowsingCheck
* check
=
139 new SafeBrowsingDatabaseManager::SafeBrowsingCheck(
141 std::vector
<SBFullHash
>(),
143 safe_browsing_util::BINURL
,
144 std::vector
<SBThreatType
>(1, SB_THREAT_TYPE_BINARY_MALWARE_URL
));
145 for (size_t i
= 0; i
< check
->url_results
.size(); ++i
)
146 check
->url_results
[i
] = threat_type
;
147 BrowserThread::PostTask(BrowserThread::IO
,
149 base::Bind(&OnSafeBrowsingResult
,
150 base::Owned(check
)));
153 class DownloadProtectionServiceTest
: public testing::Test
{
155 DownloadProtectionServiceTest()
156 : test_browser_thread_bundle_(
157 content::TestBrowserThreadBundle::IO_MAINLOOP
) {
159 virtual void SetUp() {
160 // Start real threads for the IO and File threads so that the DCHECKs
161 // to test that we're on the correct thread work.
162 sb_service_
= new StrictMock
<FakeSafeBrowsingService
>();
163 sb_service_
->Initialize();
164 signature_util_
= new StrictMock
<MockSignatureUtil
>();
165 download_service_
= sb_service_
->download_protection_service();
166 download_service_
->signature_util_
= signature_util_
;
167 download_service_
->SetEnabled(true);
168 base::RunLoop().RunUntilIdle();
171 base::FilePath source_path
;
172 ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT
, &source_path
));
173 testdata_path_
= source_path
174 .AppendASCII("chrome")
177 .AppendASCII("safe_browsing")
178 .AppendASCII("download_protection");
181 virtual void TearDown() {
182 sb_service_
->ShutDown();
183 // Flush all of the thread message loops to ensure that there are no
184 // tasks currently running.
185 FlushThreadMessageLoops();
189 bool RequestContainsResource(const ClientDownloadRequest
& request
,
190 ClientDownloadRequest::ResourceType type
,
191 const std::string
& url
,
192 const std::string
& referrer
) {
193 for (int i
= 0; i
< request
.resources_size(); ++i
) {
194 if (request
.resources(i
).url() == url
&&
195 request
.resources(i
).type() == type
&&
196 (referrer
.empty() || request
.resources(i
).referrer() == referrer
)) {
203 // At this point we only set the server IP for the download itself.
204 bool RequestContainsServerIp(const ClientDownloadRequest
& request
,
205 const std::string
& remote_address
) {
206 for (int i
= 0; i
< request
.resources_size(); ++i
) {
207 // We want the last DOWNLOAD_URL in the chain.
208 if (request
.resources(i
).type() == ClientDownloadRequest::DOWNLOAD_URL
&&
209 (i
+ 1 == request
.resources_size() ||
210 request
.resources(i
+ 1).type() !=
211 ClientDownloadRequest::DOWNLOAD_URL
)) {
212 return remote_address
== request
.resources(i
).remote_ip();
218 // Flushes any pending tasks in the message loops of all threads.
219 void FlushThreadMessageLoops() {
220 BrowserThread::GetBlockingPool()->FlushForTesting();
221 FlushMessageLoop(BrowserThread::IO
);
222 base::RunLoop().RunUntilIdle();
225 // Proxy for private method.
226 static void GetCertificateWhitelistStrings(
227 const net::X509Certificate
& certificate
,
228 const net::X509Certificate
& issuer
,
229 std::vector
<std::string
>* whitelist_strings
) {
230 DownloadProtectionService::GetCertificateWhitelistStrings(
231 certificate
, issuer
, whitelist_strings
);
234 // Reads a single PEM-encoded certificate from the testdata directory.
235 // Returns NULL on failure.
236 scoped_refptr
<net::X509Certificate
> ReadTestCertificate(
237 const std::string
& filename
) {
238 std::string cert_data
;
239 if (!base::ReadFileToString(testdata_path_
.AppendASCII(filename
),
243 net::CertificateList certs
=
244 net::X509Certificate::CreateCertificateListFromBytes(
247 net::X509Certificate::FORMAT_PEM_CERT_SEQUENCE
);
248 return certs
.empty() ? NULL
: certs
[0];
252 // Helper functions for FlushThreadMessageLoops.
253 void RunAllPendingAndQuitUI() {
254 base::MessageLoop::current()->RunUntilIdle();
255 BrowserThread::PostTask(
258 base::Bind(&DownloadProtectionServiceTest::QuitMessageLoop
,
259 base::Unretained(this)));
262 void QuitMessageLoop() {
263 base::MessageLoop::current()->Quit();
266 void PostRunMessageLoopTask(BrowserThread::ID thread
) {
267 BrowserThread::PostTask(
270 base::Bind(&DownloadProtectionServiceTest::RunAllPendingAndQuitUI
,
271 base::Unretained(this)));
274 void FlushMessageLoop(BrowserThread::ID thread
) {
275 BrowserThread::PostTask(
278 base::Bind(&DownloadProtectionServiceTest::PostRunMessageLoopTask
,
279 base::Unretained(this), thread
));
280 MessageLoop::current()->Run();
284 void CheckDoneCallback(
285 DownloadProtectionService::DownloadCheckResult result
) {
288 MessageLoop::current()->Quit();
291 void SyncCheckDoneCallback(
292 DownloadProtectionService::DownloadCheckResult result
) {
297 void SendURLFetchComplete(net::TestURLFetcher
* fetcher
) {
298 fetcher
->delegate()->OnURLFetchComplete(fetcher
);
301 testing::AssertionResult
IsResult(
302 DownloadProtectionService::DownloadCheckResult expected
) {
304 return testing::AssertionFailure() << "No result";
306 return result_
== expected
?
307 testing::AssertionSuccess() :
308 testing::AssertionFailure() << "Expected " << expected
<<
313 scoped_refptr
<FakeSafeBrowsingService
> sb_service_
;
314 scoped_refptr
<MockSignatureUtil
> signature_util_
;
315 DownloadProtectionService
* download_service_
;
316 DownloadProtectionService::DownloadCheckResult result_
;
318 content::TestBrowserThreadBundle test_browser_thread_bundle_
;
319 content::InProcessUtilityThreadHelper in_process_utility_thread_helper_
;
320 base::FilePath testdata_path_
;
323 TEST_F(DownloadProtectionServiceTest
, CheckClientDownloadInvalidUrl
) {
324 base::FilePath
a_tmp(FILE_PATH_LITERAL("a.tmp"));
325 base::FilePath
a_exe(FILE_PATH_LITERAL("a.exe"));
326 std::vector
<GURL
> url_chain
;
327 GURL
referrer("http://www.google.com/");
329 content::MockDownloadItem item
;
330 EXPECT_CALL(item
, AddObserver(_
));
331 EXPECT_CALL(item
, RemoveObserver(_
));
332 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp
));
333 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_exe
));
334 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
335 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
336 download_service_
->CheckClientDownload(
338 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
339 base::Unretained(this)));
340 MessageLoop::current()->Run();
341 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE
));
342 Mock::VerifyAndClearExpectations(&item
);
344 url_chain
.push_back(GURL("file://www.google.com/"));
345 EXPECT_CALL(item
, AddObserver(_
));
346 EXPECT_CALL(item
, RemoveObserver(_
));
347 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp
));
348 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_exe
));
349 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
350 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
351 download_service_
->CheckClientDownload(
353 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
354 base::Unretained(this)));
355 MessageLoop::current()->Run();
356 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE
));
359 TEST_F(DownloadProtectionServiceTest
, CheckClientDownloadWhitelistedUrl
) {
360 base::FilePath
a_tmp(FILE_PATH_LITERAL("a.tmp"));
361 base::FilePath
a_exe(FILE_PATH_LITERAL("a.exe"));
362 std::vector
<GURL
> url_chain
;
363 url_chain
.push_back(GURL("http://www.evil.com/bla.exe"));
364 url_chain
.push_back(GURL("http://www.google.com/a.exe"));
365 GURL
referrer("http://www.google.com/");
367 content::MockDownloadItem item
;
368 EXPECT_CALL(item
, AddObserver(_
)).Times(2);
369 EXPECT_CALL(item
, RemoveObserver(_
)).Times(2);
370 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp
));
371 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_exe
));
372 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
373 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
374 EXPECT_CALL(*sb_service_
->mock_database_manager(),
375 MatchDownloadWhitelistUrl(_
))
376 .WillRepeatedly(Return(false));
377 EXPECT_CALL(*sb_service_
->mock_database_manager(),
378 MatchDownloadWhitelistUrl(GURL("http://www.google.com/a.exe")))
379 .WillRepeatedly(Return(true));
380 EXPECT_CALL(*signature_util_
.get(), CheckSignature(a_tmp
, _
)).Times(2);
382 download_service_
->CheckClientDownload(
384 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
385 base::Unretained(this)));
386 MessageLoop::current()->Run();
387 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE
));
389 // Check that the referrer is matched against the whitelist.
390 url_chain
.pop_back();
391 referrer
= GURL("http://www.google.com/a.exe");
392 download_service_
->CheckClientDownload(
394 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
395 base::Unretained(this)));
396 MessageLoop::current()->Run();
397 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE
));
400 TEST_F(DownloadProtectionServiceTest
, CheckClientDownloadFetchFailed
) {
401 net::FakeURLFetcherFactory
factory(NULL
);
402 // HTTP request will fail.
403 factory
.SetFakeResponse(
404 DownloadProtectionService::GetDownloadRequestUrl(), std::string(),
405 net::HTTP_INTERNAL_SERVER_ERROR
, net::URLRequestStatus::FAILED
);
407 base::FilePath
a_tmp(FILE_PATH_LITERAL("a.tmp"));
408 base::FilePath
a_exe(FILE_PATH_LITERAL("a.exe"));
409 std::vector
<GURL
> url_chain
;
410 url_chain
.push_back(GURL("http://www.evil.com/a.exe"));
411 GURL
referrer("http://www.google.com/");
412 std::string hash
= "hash";
414 content::MockDownloadItem item
;
415 EXPECT_CALL(item
, AddObserver(_
));
416 EXPECT_CALL(item
, RemoveObserver(_
));
417 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp
));
418 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_exe
));
419 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
420 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
421 EXPECT_CALL(item
, GetHash()).WillRepeatedly(ReturnRef(hash
));
422 EXPECT_CALL(item
, GetReceivedBytes()).WillRepeatedly(Return(100));
423 EXPECT_CALL(item
, HasUserGesture()).WillRepeatedly(Return(true));
424 EXPECT_CALL(item
, GetRemoteAddress()).WillRepeatedly(Return(""));
426 EXPECT_CALL(*sb_service_
->mock_database_manager(),
427 MatchDownloadWhitelistUrl(_
))
428 .WillRepeatedly(Return(false));
429 EXPECT_CALL(*signature_util_
.get(), CheckSignature(a_tmp
, _
));
431 download_service_
->CheckClientDownload(
433 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
434 base::Unretained(this)));
435 MessageLoop::current()->Run();
436 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE
));
439 TEST_F(DownloadProtectionServiceTest
, CheckClientDownloadSuccess
) {
440 ClientDownloadResponse response
;
441 response
.set_verdict(ClientDownloadResponse::SAFE
);
442 net::FakeURLFetcherFactory
factory(NULL
);
443 // Empty response means SAFE.
444 factory
.SetFakeResponse(
445 DownloadProtectionService::GetDownloadRequestUrl(),
446 response
.SerializeAsString(),
447 net::HTTP_OK
, net::URLRequestStatus::SUCCESS
);
449 base::FilePath
a_tmp(FILE_PATH_LITERAL("a.tmp"));
450 base::FilePath
a_exe(FILE_PATH_LITERAL("a.exe"));
451 std::vector
<GURL
> url_chain
;
452 url_chain
.push_back(GURL("http://www.evil.com/a.exe"));
453 GURL
referrer("http://www.google.com/");
454 std::string hash
= "hash";
456 content::MockDownloadItem item
;
457 EXPECT_CALL(item
, AddObserver(_
)).Times(6);
458 EXPECT_CALL(item
, RemoveObserver(_
)).Times(6);
459 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp
));
460 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_exe
));
461 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
462 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
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(""));
468 EXPECT_CALL(*sb_service_
->mock_database_manager(),
469 MatchDownloadWhitelistUrl(_
))
470 .WillRepeatedly(Return(false));
471 EXPECT_CALL(*signature_util_
.get(), CheckSignature(a_tmp
, _
)).Times(6);
473 download_service_
->CheckClientDownload(
475 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
476 base::Unretained(this)));
477 MessageLoop::current()->Run();
478 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE
));
480 // Invalid response should be safe too.
482 factory
.SetFakeResponse(
483 DownloadProtectionService::GetDownloadRequestUrl(),
484 response
.SerializePartialAsString(),
485 net::HTTP_OK
, net::URLRequestStatus::SUCCESS
);
487 download_service_
->CheckClientDownload(
489 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
490 base::Unretained(this)));
491 MessageLoop::current()->Run();
492 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE
));
493 std::string feedback_ping
;
494 std::string feedback_response
;
495 EXPECT_FALSE(DownloadFeedbackService::GetPingsForDownloadForTesting(
496 item
, &feedback_ping
, &feedback_response
));
498 // If the response is dangerous the result should also be marked as dangerous.
499 response
.set_verdict(ClientDownloadResponse::DANGEROUS
);
500 factory
.SetFakeResponse(
501 DownloadProtectionService::GetDownloadRequestUrl(),
502 response
.SerializeAsString(),
503 net::HTTP_OK
, net::URLRequestStatus::SUCCESS
);
505 download_service_
->CheckClientDownload(
507 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
508 base::Unretained(this)));
509 MessageLoop::current()->Run();
510 EXPECT_FALSE(DownloadFeedbackService::GetPingsForDownloadForTesting(
511 item
, &feedback_ping
, &feedback_response
));
513 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS
));
515 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE
));
518 // If the response is uncommon the result should also be marked as uncommon.
519 response
.set_verdict(ClientDownloadResponse::UNCOMMON
);
520 factory
.SetFakeResponse(
521 DownloadProtectionService::GetDownloadRequestUrl(),
522 response
.SerializeAsString(),
523 net::HTTP_OK
, net::URLRequestStatus::SUCCESS
);
525 download_service_
->CheckClientDownload(
527 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
528 base::Unretained(this)));
529 MessageLoop::current()->Run();
531 EXPECT_TRUE(IsResult(DownloadProtectionService::UNCOMMON
));
532 EXPECT_TRUE(DownloadFeedbackService::GetPingsForDownloadForTesting(
533 item
, &feedback_ping
, &feedback_response
));
534 ClientDownloadRequest decoded_request
;
535 EXPECT_TRUE(decoded_request
.ParseFromString(feedback_ping
));
536 EXPECT_EQ(url_chain
.back().spec(), decoded_request
.url());
537 EXPECT_EQ(response
.SerializeAsString(), feedback_response
);
539 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE
));
542 // If the response is dangerous_host the result should also be marked as
544 response
.set_verdict(ClientDownloadResponse::DANGEROUS_HOST
);
545 factory
.SetFakeResponse(
546 DownloadProtectionService::GetDownloadRequestUrl(),
547 response
.SerializeAsString(),
548 net::HTTP_OK
, net::URLRequestStatus::SUCCESS
);
550 download_service_
->CheckClientDownload(
552 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
553 base::Unretained(this)));
554 MessageLoop::current()->Run();
556 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS_HOST
));
557 EXPECT_TRUE(DownloadFeedbackService::GetPingsForDownloadForTesting(
558 item
, &feedback_ping
, &feedback_response
));
559 EXPECT_EQ(response
.SerializeAsString(), feedback_response
);
561 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE
));
564 // If the response is POTENTIALLY_UNWANTED the result should also be marked as
565 // POTENTIALLY_UNWANTED.
566 response
.set_verdict(ClientDownloadResponse::POTENTIALLY_UNWANTED
);
567 factory
.SetFakeResponse(
568 DownloadProtectionService::GetDownloadRequestUrl(),
569 response
.SerializeAsString(),
570 net::HTTP_OK
, net::URLRequestStatus::SUCCESS
);
572 download_service_
->CheckClientDownload(
574 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
575 base::Unretained(this)));
576 MessageLoop::current()->Run();
578 EXPECT_TRUE(IsResult(DownloadProtectionService::POTENTIALLY_UNWANTED
));
580 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE
));
584 TEST_F(DownloadProtectionServiceTest
, CheckClientDownloadHTTPS
) {
585 ClientDownloadResponse response
;
586 response
.set_verdict(ClientDownloadResponse::DANGEROUS
);
587 net::FakeURLFetcherFactory
factory(NULL
);
588 factory
.SetFakeResponse(
589 DownloadProtectionService::GetDownloadRequestUrl(),
590 response
.SerializeAsString(),
591 net::HTTP_OK
, net::URLRequestStatus::SUCCESS
);
593 base::FilePath
a_tmp(FILE_PATH_LITERAL("a.tmp"));
594 base::FilePath
a_exe(FILE_PATH_LITERAL("a.exe"));
595 std::vector
<GURL
> url_chain
;
596 url_chain
.push_back(GURL("http://www.evil.com/a.exe"));
597 GURL
referrer("http://www.google.com/");
598 std::string hash
= "hash";
600 content::MockDownloadItem item
;
601 EXPECT_CALL(item
, AddObserver(_
)).Times(1);
602 EXPECT_CALL(item
, RemoveObserver(_
)).Times(1);
603 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp
));
604 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_exe
));
605 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
606 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
607 EXPECT_CALL(item
, GetHash()).WillRepeatedly(ReturnRef(hash
));
608 EXPECT_CALL(item
, GetReceivedBytes()).WillRepeatedly(Return(100));
609 EXPECT_CALL(item
, HasUserGesture()).WillRepeatedly(Return(true));
610 EXPECT_CALL(item
, GetRemoteAddress()).WillRepeatedly(Return(""));
612 EXPECT_CALL(*sb_service_
->mock_database_manager(),
613 MatchDownloadWhitelistUrl(_
))
614 .WillRepeatedly(Return(false));
615 EXPECT_CALL(*signature_util_
.get(), CheckSignature(a_tmp
, _
)).Times(1);
617 download_service_
->CheckClientDownload(
619 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
620 base::Unretained(this)));
621 MessageLoop::current()->Run();
623 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS
));
625 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE
));
629 TEST_F(DownloadProtectionServiceTest
, CheckClientDownloadZip
) {
630 ClientDownloadResponse response
;
631 response
.set_verdict(ClientDownloadResponse::SAFE
);
632 net::FakeURLFetcherFactory
factory(NULL
);
633 // Empty response means SAFE.
634 factory
.SetFakeResponse(
635 DownloadProtectionService::GetDownloadRequestUrl(),
636 response
.SerializeAsString(),
637 net::HTTP_OK
, net::URLRequestStatus::SUCCESS
);
639 base::ScopedTempDir download_dir
;
640 ASSERT_TRUE(download_dir
.CreateUniqueTempDir());
642 base::FilePath
a_tmp(download_dir
.path().Append(FILE_PATH_LITERAL("a.tmp")));
643 base::FilePath
a_zip(FILE_PATH_LITERAL("a.zip"));
644 std::vector
<GURL
> url_chain
;
645 url_chain
.push_back(GURL("http://www.evil.com/a.zip"));
646 GURL
referrer("http://www.google.com/");
647 std::string hash
= "hash";
649 content::MockDownloadItem item
;
650 EXPECT_CALL(item
, AddObserver(_
)).Times(3);
651 EXPECT_CALL(item
, RemoveObserver(_
)).Times(3);
652 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp
));
653 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_zip
));
654 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
655 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
656 EXPECT_CALL(item
, GetHash()).WillRepeatedly(ReturnRef(hash
));
657 EXPECT_CALL(item
, GetReceivedBytes()).WillRepeatedly(Return(100));
658 EXPECT_CALL(item
, HasUserGesture()).WillRepeatedly(Return(true));
659 EXPECT_CALL(item
, GetRemoteAddress()).WillRepeatedly(Return(""));
661 // Write out a zip archive to the temporary file. In this case, it
662 // only contains a text file.
663 base::ScopedTempDir zip_source_dir
;
664 ASSERT_TRUE(zip_source_dir
.CreateUniqueTempDir());
665 std::string file_contents
= "dummy file";
666 ASSERT_EQ(static_cast<int>(file_contents
.size()), file_util::WriteFile(
667 zip_source_dir
.path().Append(FILE_PATH_LITERAL("file.txt")),
668 file_contents
.data(), file_contents
.size()));
669 ASSERT_TRUE(zip::Zip(zip_source_dir
.path(), a_tmp
, false));
671 download_service_
->CheckClientDownload(
673 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
674 base::Unretained(this)));
675 MessageLoop::current()->Run();
676 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE
));
677 Mock::VerifyAndClearExpectations(sb_service_
.get());
678 Mock::VerifyAndClearExpectations(signature_util_
.get());
680 // Now check with an executable in the zip file as well.
681 ASSERT_EQ(static_cast<int>(file_contents
.size()), file_util::WriteFile(
682 zip_source_dir
.path().Append(FILE_PATH_LITERAL("file.exe")),
683 file_contents
.data(), file_contents
.size()));
684 ASSERT_TRUE(zip::Zip(zip_source_dir
.path(), a_tmp
, false));
686 EXPECT_CALL(*sb_service_
->mock_database_manager(),
687 MatchDownloadWhitelistUrl(_
))
688 .WillRepeatedly(Return(false));
690 download_service_
->CheckClientDownload(
692 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
693 base::Unretained(this)));
694 MessageLoop::current()->Run();
695 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE
));
696 Mock::VerifyAndClearExpectations(signature_util_
.get());
698 // If the response is dangerous the result should also be marked as
700 response
.set_verdict(ClientDownloadResponse::DANGEROUS
);
701 factory
.SetFakeResponse(
702 DownloadProtectionService::GetDownloadRequestUrl(),
703 response
.SerializeAsString(),
704 net::HTTP_OK
, net::URLRequestStatus::SUCCESS
);
706 download_service_
->CheckClientDownload(
708 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
709 base::Unretained(this)));
710 MessageLoop::current()->Run();
712 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS
));
714 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE
));
716 Mock::VerifyAndClearExpectations(signature_util_
.get());
719 TEST_F(DownloadProtectionServiceTest
, CheckClientDownloadCorruptZip
) {
720 base::ScopedTempDir download_dir
;
721 ASSERT_TRUE(download_dir
.CreateUniqueTempDir());
723 base::FilePath
a_tmp(download_dir
.path().Append(FILE_PATH_LITERAL("a.tmp")));
724 base::FilePath
a_zip(FILE_PATH_LITERAL("a.zip"));
725 std::vector
<GURL
> url_chain
;
726 url_chain
.push_back(GURL("http://www.evil.com/a.zip"));
727 GURL
referrer("http://www.google.com/");
728 std::string hash
= "hash";
730 content::MockDownloadItem item
;
731 EXPECT_CALL(item
, AddObserver(_
)).Times(1);
732 EXPECT_CALL(item
, RemoveObserver(_
)).Times(1);
733 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp
));
734 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_zip
));
735 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
736 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
737 EXPECT_CALL(item
, GetHash()).WillRepeatedly(ReturnRef(hash
));
738 EXPECT_CALL(item
, GetReceivedBytes()).WillRepeatedly(Return(100));
739 EXPECT_CALL(item
, HasUserGesture()).WillRepeatedly(Return(true));
740 EXPECT_CALL(item
, GetRemoteAddress()).WillRepeatedly(Return(""));
742 std::string file_contents
= "corrupt zip file";
743 ASSERT_EQ(static_cast<int>(file_contents
.size()), file_util::WriteFile(
744 a_tmp
, file_contents
.data(), file_contents
.size()));
746 download_service_
->CheckClientDownload(
748 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
749 base::Unretained(this)));
750 MessageLoop::current()->Run();
751 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE
));
752 Mock::VerifyAndClearExpectations(sb_service_
.get());
753 Mock::VerifyAndClearExpectations(signature_util_
.get());
756 TEST_F(DownloadProtectionServiceTest
, CheckClientCrxDownloadSuccess
) {
757 ClientDownloadResponse response
;
758 // Even if the server verdict is dangerous we should return SAFE because
759 // DownloadProtectionService::IsSupportedDownload() will return false
760 // for crx downloads.
761 response
.set_verdict(ClientDownloadResponse::DANGEROUS
);
762 net::FakeURLFetcherFactory
factory(NULL
);
763 // Empty response means SAFE.
764 factory
.SetFakeResponse(
765 DownloadProtectionService::GetDownloadRequestUrl(),
766 response
.SerializeAsString(),
767 net::HTTP_OK
, net::URLRequestStatus::SUCCESS
);
769 base::FilePath
a_tmp(FILE_PATH_LITERAL("a.tmp"));
770 base::FilePath
a_crx(FILE_PATH_LITERAL("a.crx"));
771 std::vector
<GURL
> url_chain
;
772 url_chain
.push_back(GURL("http://www.evil.com/a.crx"));
773 GURL
referrer("http://www.google.com/");
774 std::string hash
= "hash";
776 content::MockDownloadItem item
;
777 EXPECT_CALL(item
, AddObserver(_
)).Times(1);
778 EXPECT_CALL(item
, RemoveObserver(_
)).Times(1);
779 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp
));
780 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_crx
));
781 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
782 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
783 EXPECT_CALL(item
, GetHash()).WillRepeatedly(ReturnRef(hash
));
784 EXPECT_CALL(item
, GetReceivedBytes()).WillRepeatedly(Return(100));
785 EXPECT_CALL(item
, HasUserGesture()).WillRepeatedly(Return(true));
786 EXPECT_CALL(item
, GetRemoteAddress()).WillRepeatedly(Return(""));
788 EXPECT_CALL(*sb_service_
->mock_database_manager(),
789 MatchDownloadWhitelistUrl(_
))
790 .WillRepeatedly(Return(false));
791 EXPECT_CALL(*signature_util_
.get(), CheckSignature(a_tmp
, _
)).Times(1);
793 EXPECT_FALSE(download_service_
->IsSupportedDownload(item
, a_crx
));
794 download_service_
->CheckClientDownload(
796 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
797 base::Unretained(this)));
798 MessageLoop::current()->Run();
799 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE
));
802 TEST_F(DownloadProtectionServiceTest
, CheckClientDownloadValidateRequest
) {
803 net::TestURLFetcherFactory factory
;
805 base::FilePath
tmp_path(FILE_PATH_LITERAL("bla.tmp"));
806 base::FilePath
final_path(FILE_PATH_LITERAL("bla.exe"));
807 std::vector
<GURL
> url_chain
;
808 url_chain
.push_back(GURL("http://www.google.com/"));
809 url_chain
.push_back(GURL("http://www.google.com/bla.exe"));
810 GURL
referrer("http://www.google.com/");
811 std::string hash
= "hash";
812 std::string remote_address
= "10.11.12.13";
814 content::MockDownloadItem item
;
815 EXPECT_CALL(item
, AddObserver(_
)).Times(1);
816 EXPECT_CALL(item
, RemoveObserver(_
)).Times(1);
817 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(tmp_path
));
818 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(final_path
));
819 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
820 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
821 EXPECT_CALL(item
, GetHash()).WillRepeatedly(ReturnRef(hash
));
822 EXPECT_CALL(item
, GetReceivedBytes()).WillRepeatedly(Return(100));
823 EXPECT_CALL(item
, HasUserGesture()).WillRepeatedly(Return(true));
824 EXPECT_CALL(item
, GetRemoteAddress()).WillRepeatedly(Return(remote_address
));
826 EXPECT_CALL(*sb_service_
->mock_database_manager(),
827 MatchDownloadWhitelistUrl(_
))
828 .WillRepeatedly(Return(false));
829 EXPECT_CALL(*signature_util_
.get(), CheckSignature(tmp_path
, _
))
830 .WillOnce(SetCertificateContents("dummy cert data"));
831 download_service_
->CheckClientDownload(
833 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
834 base::Unretained(this)));
837 // SendRequest is not called. Wait for FinishRequest to call our callback.
838 MessageLoop::current()->Run();
839 net::TestURLFetcher
* fetcher
= factory
.GetFetcherByID(0);
840 EXPECT_EQ(NULL
, fetcher
);
842 // Run the message loop(s) until SendRequest is called.
843 FlushThreadMessageLoops();
844 net::TestURLFetcher
* fetcher
= factory
.GetFetcherByID(0);
845 ASSERT_TRUE(fetcher
);
846 ClientDownloadRequest request
;
847 EXPECT_TRUE(request
.ParseFromString(fetcher
->upload_data()));
848 EXPECT_EQ("http://www.google.com/bla.exe", request
.url());
849 EXPECT_EQ(hash
, request
.digests().sha256());
850 EXPECT_EQ(item
.GetReceivedBytes(), request
.length());
851 EXPECT_EQ(item
.HasUserGesture(), request
.user_initiated());
852 EXPECT_TRUE(RequestContainsServerIp(request
, remote_address
));
853 EXPECT_EQ(2, request
.resources_size());
854 EXPECT_TRUE(RequestContainsResource(request
,
855 ClientDownloadRequest::DOWNLOAD_REDIRECT
,
856 "http://www.google.com/", ""));
857 EXPECT_TRUE(RequestContainsResource(request
,
858 ClientDownloadRequest::DOWNLOAD_URL
,
859 "http://www.google.com/bla.exe",
861 EXPECT_TRUE(request
.has_signature());
862 ASSERT_EQ(1, request
.signature().certificate_chain_size());
863 const ClientDownloadRequest_CertificateChain
& chain
=
864 request
.signature().certificate_chain(0);
865 ASSERT_EQ(1, chain
.element_size());
866 EXPECT_EQ("dummy cert data", chain
.element(0).certificate());
868 // Simulate the request finishing.
869 base::MessageLoop::current()->PostTask(
871 base::Bind(&DownloadProtectionServiceTest::SendURLFetchComplete
,
872 base::Unretained(this), fetcher
));
873 MessageLoop::current()->Run();
877 // Similar to above, but with an unsigned binary.
878 TEST_F(DownloadProtectionServiceTest
,
879 CheckClientDownloadValidateRequestNoSignature
) {
880 net::TestURLFetcherFactory factory
;
882 base::FilePath
tmp_path(FILE_PATH_LITERAL("bla.tmp"));
883 base::FilePath
final_path(FILE_PATH_LITERAL("bla.exe"));
884 std::vector
<GURL
> url_chain
;
885 url_chain
.push_back(GURL("http://www.google.com/"));
886 url_chain
.push_back(GURL("ftp://www.google.com/bla.exe"));
887 GURL
referrer("http://www.google.com/");
888 std::string hash
= "hash";
889 std::string remote_address
= "10.11.12.13";
891 content::MockDownloadItem item
;
892 EXPECT_CALL(item
, AddObserver(_
)).Times(1);
893 EXPECT_CALL(item
, RemoveObserver(_
)).Times(1);
894 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(tmp_path
));
895 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(final_path
));
896 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
897 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
898 EXPECT_CALL(item
, GetHash()).WillRepeatedly(ReturnRef(hash
));
899 EXPECT_CALL(item
, GetReceivedBytes()).WillRepeatedly(Return(100));
900 EXPECT_CALL(item
, HasUserGesture()).WillRepeatedly(Return(true));
901 EXPECT_CALL(item
, GetRemoteAddress()).WillRepeatedly(Return(remote_address
));
903 EXPECT_CALL(*sb_service_
->mock_database_manager(),
904 MatchDownloadWhitelistUrl(_
))
905 .WillRepeatedly(Return(false));
906 EXPECT_CALL(*signature_util_
.get(), CheckSignature(tmp_path
, _
));
907 download_service_
->CheckClientDownload(
909 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
910 base::Unretained(this)));
913 // SendRequest is not called. Wait for FinishRequest to call our callback.
914 MessageLoop::current()->Run();
915 net::TestURLFetcher
* fetcher
= factory
.GetFetcherByID(0);
916 EXPECT_EQ(NULL
, fetcher
);
918 // Run the message loop(s) until SendRequest is called.
919 FlushThreadMessageLoops();
920 net::TestURLFetcher
* fetcher
= factory
.GetFetcherByID(0);
921 ASSERT_TRUE(fetcher
);
922 ClientDownloadRequest request
;
923 EXPECT_TRUE(request
.ParseFromString(fetcher
->upload_data()));
924 EXPECT_EQ("ftp://www.google.com/bla.exe", request
.url());
925 EXPECT_EQ(hash
, request
.digests().sha256());
926 EXPECT_EQ(item
.GetReceivedBytes(), request
.length());
927 EXPECT_EQ(item
.HasUserGesture(), request
.user_initiated());
928 EXPECT_EQ(2, request
.resources_size());
929 EXPECT_TRUE(RequestContainsResource(request
,
930 ClientDownloadRequest::DOWNLOAD_REDIRECT
,
931 "http://www.google.com/", ""));
932 EXPECT_TRUE(RequestContainsResource(request
,
933 ClientDownloadRequest::DOWNLOAD_URL
,
934 "ftp://www.google.com/bla.exe",
936 EXPECT_TRUE(request
.has_signature());
937 EXPECT_EQ(0, request
.signature().certificate_chain_size());
939 // Simulate the request finishing.
940 base::MessageLoop::current()->PostTask(
942 base::Bind(&DownloadProtectionServiceTest::SendURLFetchComplete
,
943 base::Unretained(this), fetcher
));
944 MessageLoop::current()->Run();
948 TEST_F(DownloadProtectionServiceTest
, TestCheckDownloadUrl
) {
949 std::vector
<GURL
> url_chain
;
950 url_chain
.push_back(GURL("http://www.google.com/"));
951 url_chain
.push_back(GURL("http://www.google.com/bla.exe"));
952 GURL
referrer("http://www.google.com/");
953 std::string hash
= "hash";
955 content::MockDownloadItem item
;
956 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
957 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
958 EXPECT_CALL(item
, GetHash()).WillRepeatedly(ReturnRef(hash
));
960 // CheckDownloadURL returns immediately which means the client object callback
961 // will never be called. Nevertheless the callback provided to
962 // CheckClientDownload must still be called.
963 EXPECT_CALL(*sb_service_
->mock_database_manager(),
964 CheckDownloadUrl(ContainerEq(url_chain
), NotNull()))
965 .WillOnce(Return(true));
966 download_service_
->CheckDownloadUrl(
968 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
969 base::Unretained(this)));
970 MessageLoop::current()->Run();
971 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE
));
972 Mock::VerifyAndClearExpectations(sb_service_
.get());
974 EXPECT_CALL(*sb_service_
->mock_database_manager(),
975 CheckDownloadUrl(ContainerEq(url_chain
), NotNull()))
976 .WillOnce(DoAll(CheckDownloadUrlDone(SB_THREAT_TYPE_SAFE
),
978 download_service_
->CheckDownloadUrl(
980 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
981 base::Unretained(this)));
982 MessageLoop::current()->Run();
983 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE
));
984 Mock::VerifyAndClearExpectations(sb_service_
.get());
986 EXPECT_CALL(*sb_service_
->mock_database_manager(),
987 CheckDownloadUrl(ContainerEq(url_chain
), NotNull()))
989 CheckDownloadUrlDone(SB_THREAT_TYPE_URL_MALWARE
),
991 download_service_
->CheckDownloadUrl(
993 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
994 base::Unretained(this)));
995 MessageLoop::current()->Run();
996 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE
));
997 Mock::VerifyAndClearExpectations(sb_service_
.get());
999 EXPECT_CALL(*sb_service_
->mock_database_manager(),
1000 CheckDownloadUrl(ContainerEq(url_chain
),
1003 CheckDownloadUrlDone(SB_THREAT_TYPE_BINARY_MALWARE_URL
),
1005 download_service_
->CheckDownloadUrl(
1007 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
1008 base::Unretained(this)));
1009 MessageLoop::current()->Run();
1010 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS
));
1013 TEST_F(DownloadProtectionServiceTest
, TestDownloadRequestTimeout
) {
1014 net::TestURLFetcherFactory factory
;
1016 std::vector
<GURL
> url_chain
;
1017 url_chain
.push_back(GURL("http://www.evil.com/bla.exe"));
1018 GURL
referrer("http://www.google.com/");
1019 base::FilePath
tmp_path(FILE_PATH_LITERAL("a.tmp"));
1020 base::FilePath
final_path(FILE_PATH_LITERAL("a.exe"));
1021 std::string hash
= "hash";
1023 content::MockDownloadItem item
;
1024 EXPECT_CALL(item
, AddObserver(_
)).Times(1);
1025 EXPECT_CALL(item
, RemoveObserver(_
)).Times(1);
1026 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(tmp_path
));
1027 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(final_path
));
1028 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
1029 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
1030 EXPECT_CALL(item
, GetHash()).WillRepeatedly(ReturnRef(hash
));
1031 EXPECT_CALL(item
, GetReceivedBytes()).WillRepeatedly(Return(100));
1032 EXPECT_CALL(item
, HasUserGesture()).WillRepeatedly(Return(true));
1033 EXPECT_CALL(item
, GetRemoteAddress()).WillRepeatedly(Return(""));
1035 EXPECT_CALL(*sb_service_
->mock_database_manager(),
1036 MatchDownloadWhitelistUrl(_
))
1037 .WillRepeatedly(Return(false));
1038 EXPECT_CALL(*signature_util_
.get(), CheckSignature(tmp_path
, _
));
1040 download_service_
->download_request_timeout_ms_
= 10;
1041 download_service_
->CheckClientDownload(
1043 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
1044 base::Unretained(this)));
1046 // The request should time out because the HTTP request hasn't returned
1048 MessageLoop::current()->Run();
1049 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE
));
1052 TEST_F(DownloadProtectionServiceTest
, TestDownloadItemDestroyed
) {
1053 net::TestURLFetcherFactory factory
;
1055 std::vector
<GURL
> url_chain
;
1056 url_chain
.push_back(GURL("http://www.evil.com/bla.exe"));
1057 GURL
referrer("http://www.google.com/");
1058 base::FilePath
tmp_path(FILE_PATH_LITERAL("a.tmp"));
1059 base::FilePath
final_path(FILE_PATH_LITERAL("a.exe"));
1060 std::string hash
= "hash";
1062 content::MockDownloadItem item
;
1063 content::DownloadItem::Observer
* observer
= NULL
;
1064 EXPECT_CALL(item
, AddObserver(_
)).WillOnce(SaveArg
<0>(&observer
));
1065 EXPECT_CALL(item
, RemoveObserver(_
)).WillOnce(Assign(
1066 &observer
, static_cast<content::DownloadItem::Observer
*>(NULL
)));
1067 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(tmp_path
));
1068 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(final_path
));
1069 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
1070 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
1071 EXPECT_CALL(item
, GetHash()).WillRepeatedly(ReturnRef(hash
));
1072 EXPECT_CALL(item
, GetReceivedBytes()).WillRepeatedly(Return(100));
1073 EXPECT_CALL(item
, HasUserGesture()).WillRepeatedly(Return(true));
1074 EXPECT_CALL(item
, GetRemoteAddress()).WillRepeatedly(Return(""));
1076 EXPECT_CALL(*sb_service_
->mock_database_manager(),
1077 MatchDownloadWhitelistUrl(_
))
1078 .WillRepeatedly(Return(false));
1079 EXPECT_CALL(*signature_util_
.get(), CheckSignature(tmp_path
, _
));
1081 download_service_
->CheckClientDownload(
1083 base::Bind(&DownloadProtectionServiceTest::SyncCheckDoneCallback
,
1084 base::Unretained(this)));
1086 ASSERT_TRUE(observer
!= NULL
);
1087 observer
->OnDownloadDestroyed(&item
);
1089 EXPECT_TRUE(observer
== NULL
);
1090 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE
));
1093 TEST_F(DownloadProtectionServiceTest
, GetCertificateWhitelistStrings
) {
1094 // We'll pass this cert in as the "issuer", even though it isn't really
1095 // used to sign the certs below. GetCertificateWhitelistStirngs doesn't care
1097 scoped_refptr
<net::X509Certificate
> issuer_cert(
1098 ReadTestCertificate("issuer.pem"));
1099 ASSERT_TRUE(issuer_cert
.get());
1100 std::string cert_base
= "cert/" + base::HexEncode(
1101 issuer_cert
->fingerprint().data
,
1102 sizeof(issuer_cert
->fingerprint().data
));
1104 scoped_refptr
<net::X509Certificate
> cert(ReadTestCertificate("test_cn.pem"));
1105 ASSERT_TRUE(cert
.get());
1106 std::vector
<std::string
> whitelist_strings
;
1107 GetCertificateWhitelistStrings(
1108 *cert
.get(), *issuer_cert
.get(), &whitelist_strings
);
1109 // This also tests escaping of characters in the certificate attributes.
1110 EXPECT_THAT(whitelist_strings
, ElementsAre(
1111 cert_base
+ "/CN=subject%2F%251"));
1113 cert
= ReadTestCertificate("test_cn_o.pem");
1114 ASSERT_TRUE(cert
.get());
1115 whitelist_strings
.clear();
1116 GetCertificateWhitelistStrings(
1117 *cert
.get(), *issuer_cert
.get(), &whitelist_strings
);
1118 EXPECT_THAT(whitelist_strings
,
1119 ElementsAre(cert_base
+ "/CN=subject",
1120 cert_base
+ "/CN=subject/O=org",
1121 cert_base
+ "/O=org"));
1123 cert
= ReadTestCertificate("test_cn_o_ou.pem");
1124 ASSERT_TRUE(cert
.get());
1125 whitelist_strings
.clear();
1126 GetCertificateWhitelistStrings(
1127 *cert
.get(), *issuer_cert
.get(), &whitelist_strings
);
1128 EXPECT_THAT(whitelist_strings
,
1129 ElementsAre(cert_base
+ "/CN=subject",
1130 cert_base
+ "/CN=subject/O=org",
1131 cert_base
+ "/CN=subject/O=org/OU=unit",
1132 cert_base
+ "/CN=subject/OU=unit",
1133 cert_base
+ "/O=org",
1134 cert_base
+ "/O=org/OU=unit",
1135 cert_base
+ "/OU=unit"));
1137 cert
= ReadTestCertificate("test_cn_ou.pem");
1138 ASSERT_TRUE(cert
.get());
1139 whitelist_strings
.clear();
1140 GetCertificateWhitelistStrings(
1141 *cert
.get(), *issuer_cert
.get(), &whitelist_strings
);
1142 EXPECT_THAT(whitelist_strings
,
1143 ElementsAre(cert_base
+ "/CN=subject",
1144 cert_base
+ "/CN=subject/OU=unit",
1145 cert_base
+ "/OU=unit"));
1147 cert
= ReadTestCertificate("test_o.pem");
1148 ASSERT_TRUE(cert
.get());
1149 whitelist_strings
.clear();
1150 GetCertificateWhitelistStrings(
1151 *cert
.get(), *issuer_cert
.get(), &whitelist_strings
);
1152 EXPECT_THAT(whitelist_strings
, ElementsAre(cert_base
+ "/O=org"));
1154 cert
= ReadTestCertificate("test_o_ou.pem");
1155 ASSERT_TRUE(cert
.get());
1156 whitelist_strings
.clear();
1157 GetCertificateWhitelistStrings(
1158 *cert
.get(), *issuer_cert
.get(), &whitelist_strings
);
1159 EXPECT_THAT(whitelist_strings
,
1160 ElementsAre(cert_base
+ "/O=org",
1161 cert_base
+ "/O=org/OU=unit",
1162 cert_base
+ "/OU=unit"));
1164 cert
= ReadTestCertificate("test_ou.pem");
1165 ASSERT_TRUE(cert
.get());
1166 whitelist_strings
.clear();
1167 GetCertificateWhitelistStrings(
1168 *cert
.get(), *issuer_cert
.get(), &whitelist_strings
);
1169 EXPECT_THAT(whitelist_strings
, ElementsAre(cert_base
+ "/OU=unit"));
1171 cert
= ReadTestCertificate("test_c.pem");
1172 ASSERT_TRUE(cert
.get());
1173 whitelist_strings
.clear();
1174 GetCertificateWhitelistStrings(
1175 *cert
.get(), *issuer_cert
.get(), &whitelist_strings
);
1176 EXPECT_THAT(whitelist_strings
, ElementsAre());
1178 } // namespace safe_browsing