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/browser/render_process_host.h"
29 #include "content/public/test/mock_download_item.h"
30 #include "content/public/test/test_browser_thread_bundle.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 content::RenderProcessHost::SetRunRendererInProcess(true);
161 // Start real threads for the IO and File threads so that the DCHECKs
162 // to test that we're on the correct thread work.
163 sb_service_
= new StrictMock
<FakeSafeBrowsingService
>();
164 sb_service_
->Initialize();
165 signature_util_
= new StrictMock
<MockSignatureUtil
>();
166 download_service_
= sb_service_
->download_protection_service();
167 download_service_
->signature_util_
= signature_util_
;
168 download_service_
->SetEnabled(true);
169 base::RunLoop().RunUntilIdle();
172 base::FilePath source_path
;
173 ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT
, &source_path
));
174 testdata_path_
= source_path
175 .AppendASCII("chrome")
178 .AppendASCII("safe_browsing")
179 .AppendASCII("download_protection");
182 virtual void TearDown() {
183 sb_service_
->ShutDown();
184 // Flush all of the thread message loops to ensure that there are no
185 // tasks currently running.
186 FlushThreadMessageLoops();
188 content::RenderProcessHost::SetRunRendererInProcess(false);
191 bool RequestContainsResource(const ClientDownloadRequest
& request
,
192 ClientDownloadRequest::ResourceType type
,
193 const std::string
& url
,
194 const std::string
& referrer
) {
195 for (int i
= 0; i
< request
.resources_size(); ++i
) {
196 if (request
.resources(i
).url() == url
&&
197 request
.resources(i
).type() == type
&&
198 (referrer
.empty() || request
.resources(i
).referrer() == referrer
)) {
205 // At this point we only set the server IP for the download itself.
206 bool RequestContainsServerIp(const ClientDownloadRequest
& request
,
207 const std::string
& remote_address
) {
208 for (int i
= 0; i
< request
.resources_size(); ++i
) {
209 // We want the last DOWNLOAD_URL in the chain.
210 if (request
.resources(i
).type() == ClientDownloadRequest::DOWNLOAD_URL
&&
211 (i
+ 1 == request
.resources_size() ||
212 request
.resources(i
+ 1).type() !=
213 ClientDownloadRequest::DOWNLOAD_URL
)) {
214 return remote_address
== request
.resources(i
).remote_ip();
220 // Flushes any pending tasks in the message loops of all threads.
221 void FlushThreadMessageLoops() {
222 BrowserThread::GetBlockingPool()->FlushForTesting();
223 FlushMessageLoop(BrowserThread::IO
);
224 base::RunLoop().RunUntilIdle();
227 // Proxy for private method.
228 static void GetCertificateWhitelistStrings(
229 const net::X509Certificate
& certificate
,
230 const net::X509Certificate
& issuer
,
231 std::vector
<std::string
>* whitelist_strings
) {
232 DownloadProtectionService::GetCertificateWhitelistStrings(
233 certificate
, issuer
, whitelist_strings
);
236 // Reads a single PEM-encoded certificate from the testdata directory.
237 // Returns NULL on failure.
238 scoped_refptr
<net::X509Certificate
> ReadTestCertificate(
239 const std::string
& filename
) {
240 std::string cert_data
;
241 if (!base::ReadFileToString(testdata_path_
.AppendASCII(filename
),
245 net::CertificateList certs
=
246 net::X509Certificate::CreateCertificateListFromBytes(
249 net::X509Certificate::FORMAT_PEM_CERT_SEQUENCE
);
250 return certs
.empty() ? NULL
: certs
[0];
254 // Helper functions for FlushThreadMessageLoops.
255 void RunAllPendingAndQuitUI() {
256 base::MessageLoop::current()->RunUntilIdle();
257 BrowserThread::PostTask(
260 base::Bind(&DownloadProtectionServiceTest::QuitMessageLoop
,
261 base::Unretained(this)));
264 void QuitMessageLoop() {
265 base::MessageLoop::current()->Quit();
268 void PostRunMessageLoopTask(BrowserThread::ID thread
) {
269 BrowserThread::PostTask(
272 base::Bind(&DownloadProtectionServiceTest::RunAllPendingAndQuitUI
,
273 base::Unretained(this)));
276 void FlushMessageLoop(BrowserThread::ID thread
) {
277 BrowserThread::PostTask(
280 base::Bind(&DownloadProtectionServiceTest::PostRunMessageLoopTask
,
281 base::Unretained(this), thread
));
282 MessageLoop::current()->Run();
286 void CheckDoneCallback(
287 DownloadProtectionService::DownloadCheckResult result
) {
290 MessageLoop::current()->Quit();
293 void SyncCheckDoneCallback(
294 DownloadProtectionService::DownloadCheckResult result
) {
299 void SendURLFetchComplete(net::TestURLFetcher
* fetcher
) {
300 fetcher
->delegate()->OnURLFetchComplete(fetcher
);
303 testing::AssertionResult
IsResult(
304 DownloadProtectionService::DownloadCheckResult expected
) {
306 return testing::AssertionFailure() << "No result";
308 return result_
== expected
?
309 testing::AssertionSuccess() :
310 testing::AssertionFailure() << "Expected " << expected
<<
315 scoped_refptr
<FakeSafeBrowsingService
> sb_service_
;
316 scoped_refptr
<MockSignatureUtil
> signature_util_
;
317 DownloadProtectionService
* download_service_
;
318 DownloadProtectionService::DownloadCheckResult result_
;
320 content::TestBrowserThreadBundle test_browser_thread_bundle_
;
321 base::FilePath testdata_path_
;
324 TEST_F(DownloadProtectionServiceTest
, CheckClientDownloadInvalidUrl
) {
325 base::FilePath
a_tmp(FILE_PATH_LITERAL("a.tmp"));
326 base::FilePath
a_exe(FILE_PATH_LITERAL("a.exe"));
327 std::vector
<GURL
> url_chain
;
328 GURL
referrer("http://www.google.com/");
330 content::MockDownloadItem item
;
331 EXPECT_CALL(item
, AddObserver(_
));
332 EXPECT_CALL(item
, RemoveObserver(_
));
333 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp
));
334 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_exe
));
335 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
336 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
337 download_service_
->CheckClientDownload(
339 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
340 base::Unretained(this)));
341 MessageLoop::current()->Run();
342 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE
));
343 Mock::VerifyAndClearExpectations(&item
);
345 url_chain
.push_back(GURL("file://www.google.com/"));
346 EXPECT_CALL(item
, AddObserver(_
));
347 EXPECT_CALL(item
, RemoveObserver(_
));
348 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp
));
349 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_exe
));
350 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
351 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
352 download_service_
->CheckClientDownload(
354 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
355 base::Unretained(this)));
356 MessageLoop::current()->Run();
357 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE
));
360 TEST_F(DownloadProtectionServiceTest
, CheckClientDownloadWhitelistedUrl
) {
361 base::FilePath
a_tmp(FILE_PATH_LITERAL("a.tmp"));
362 base::FilePath
a_exe(FILE_PATH_LITERAL("a.exe"));
363 std::vector
<GURL
> url_chain
;
364 url_chain
.push_back(GURL("http://www.evil.com/bla.exe"));
365 url_chain
.push_back(GURL("http://www.google.com/a.exe"));
366 GURL
referrer("http://www.google.com/");
368 content::MockDownloadItem item
;
369 EXPECT_CALL(item
, AddObserver(_
)).Times(2);
370 EXPECT_CALL(item
, RemoveObserver(_
)).Times(2);
371 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp
));
372 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_exe
));
373 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
374 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
375 EXPECT_CALL(*sb_service_
->mock_database_manager(),
376 MatchDownloadWhitelistUrl(_
))
377 .WillRepeatedly(Return(false));
378 EXPECT_CALL(*sb_service_
->mock_database_manager(),
379 MatchDownloadWhitelistUrl(GURL("http://www.google.com/a.exe")))
380 .WillRepeatedly(Return(true));
381 EXPECT_CALL(*signature_util_
.get(), CheckSignature(a_tmp
, _
)).Times(2);
383 download_service_
->CheckClientDownload(
385 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
386 base::Unretained(this)));
387 MessageLoop::current()->Run();
388 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE
));
390 // Check that the referrer is matched against the whitelist.
391 url_chain
.pop_back();
392 referrer
= GURL("http://www.google.com/a.exe");
393 download_service_
->CheckClientDownload(
395 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
396 base::Unretained(this)));
397 MessageLoop::current()->Run();
398 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE
));
401 TEST_F(DownloadProtectionServiceTest
, CheckClientDownloadFetchFailed
) {
402 net::FakeURLFetcherFactory
factory(NULL
);
403 // HTTP request will fail.
404 factory
.SetFakeResponse(
405 DownloadProtectionService::GetDownloadRequestUrl(), std::string(),
406 net::HTTP_INTERNAL_SERVER_ERROR
, net::URLRequestStatus::FAILED
);
408 base::FilePath
a_tmp(FILE_PATH_LITERAL("a.tmp"));
409 base::FilePath
a_exe(FILE_PATH_LITERAL("a.exe"));
410 std::vector
<GURL
> url_chain
;
411 url_chain
.push_back(GURL("http://www.evil.com/a.exe"));
412 GURL
referrer("http://www.google.com/");
413 std::string hash
= "hash";
415 content::MockDownloadItem item
;
416 EXPECT_CALL(item
, AddObserver(_
));
417 EXPECT_CALL(item
, RemoveObserver(_
));
418 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp
));
419 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_exe
));
420 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
421 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
422 EXPECT_CALL(item
, GetHash()).WillRepeatedly(ReturnRef(hash
));
423 EXPECT_CALL(item
, GetReceivedBytes()).WillRepeatedly(Return(100));
424 EXPECT_CALL(item
, HasUserGesture()).WillRepeatedly(Return(true));
425 EXPECT_CALL(item
, GetRemoteAddress()).WillRepeatedly(Return(""));
427 EXPECT_CALL(*sb_service_
->mock_database_manager(),
428 MatchDownloadWhitelistUrl(_
))
429 .WillRepeatedly(Return(false));
430 EXPECT_CALL(*signature_util_
.get(), CheckSignature(a_tmp
, _
));
432 download_service_
->CheckClientDownload(
434 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
435 base::Unretained(this)));
436 MessageLoop::current()->Run();
437 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE
));
440 TEST_F(DownloadProtectionServiceTest
, CheckClientDownloadSuccess
) {
441 ClientDownloadResponse response
;
442 response
.set_verdict(ClientDownloadResponse::SAFE
);
443 net::FakeURLFetcherFactory
factory(NULL
);
444 // Empty response means SAFE.
445 factory
.SetFakeResponse(
446 DownloadProtectionService::GetDownloadRequestUrl(),
447 response
.SerializeAsString(),
448 net::HTTP_OK
, net::URLRequestStatus::SUCCESS
);
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
;
453 url_chain
.push_back(GURL("http://www.evil.com/a.exe"));
454 GURL
referrer("http://www.google.com/");
455 std::string hash
= "hash";
457 content::MockDownloadItem item
;
458 EXPECT_CALL(item
, AddObserver(_
)).Times(6);
459 EXPECT_CALL(item
, RemoveObserver(_
)).Times(6);
460 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp
));
461 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_exe
));
462 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
463 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
464 EXPECT_CALL(item
, GetHash()).WillRepeatedly(ReturnRef(hash
));
465 EXPECT_CALL(item
, GetReceivedBytes()).WillRepeatedly(Return(100));
466 EXPECT_CALL(item
, HasUserGesture()).WillRepeatedly(Return(true));
467 EXPECT_CALL(item
, GetRemoteAddress()).WillRepeatedly(Return(""));
469 EXPECT_CALL(*sb_service_
->mock_database_manager(),
470 MatchDownloadWhitelistUrl(_
))
471 .WillRepeatedly(Return(false));
472 EXPECT_CALL(*signature_util_
.get(), CheckSignature(a_tmp
, _
)).Times(6);
474 download_service_
->CheckClientDownload(
476 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
477 base::Unretained(this)));
478 MessageLoop::current()->Run();
479 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE
));
481 // Invalid response should be safe too.
483 factory
.SetFakeResponse(
484 DownloadProtectionService::GetDownloadRequestUrl(),
485 response
.SerializePartialAsString(),
486 net::HTTP_OK
, net::URLRequestStatus::SUCCESS
);
488 download_service_
->CheckClientDownload(
490 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
491 base::Unretained(this)));
492 MessageLoop::current()->Run();
493 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE
));
494 std::string feedback_ping
;
495 std::string feedback_response
;
496 EXPECT_FALSE(DownloadFeedbackService::GetPingsForDownloadForTesting(
497 item
, &feedback_ping
, &feedback_response
));
499 // If the response is dangerous the result should also be marked as dangerous.
500 response
.set_verdict(ClientDownloadResponse::DANGEROUS
);
501 factory
.SetFakeResponse(
502 DownloadProtectionService::GetDownloadRequestUrl(),
503 response
.SerializeAsString(),
504 net::HTTP_OK
, net::URLRequestStatus::SUCCESS
);
506 download_service_
->CheckClientDownload(
508 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
509 base::Unretained(this)));
510 MessageLoop::current()->Run();
511 EXPECT_FALSE(DownloadFeedbackService::GetPingsForDownloadForTesting(
512 item
, &feedback_ping
, &feedback_response
));
514 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS
));
516 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE
));
519 // If the response is uncommon the result should also be marked as uncommon.
520 response
.set_verdict(ClientDownloadResponse::UNCOMMON
);
521 factory
.SetFakeResponse(
522 DownloadProtectionService::GetDownloadRequestUrl(),
523 response
.SerializeAsString(),
524 net::HTTP_OK
, net::URLRequestStatus::SUCCESS
);
526 download_service_
->CheckClientDownload(
528 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
529 base::Unretained(this)));
530 MessageLoop::current()->Run();
532 EXPECT_TRUE(IsResult(DownloadProtectionService::UNCOMMON
));
533 EXPECT_TRUE(DownloadFeedbackService::GetPingsForDownloadForTesting(
534 item
, &feedback_ping
, &feedback_response
));
535 ClientDownloadRequest decoded_request
;
536 EXPECT_TRUE(decoded_request
.ParseFromString(feedback_ping
));
537 EXPECT_EQ(url_chain
.back().spec(), decoded_request
.url());
538 EXPECT_EQ(response
.SerializeAsString(), feedback_response
);
540 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE
));
543 // If the response is dangerous_host the result should also be marked as
545 response
.set_verdict(ClientDownloadResponse::DANGEROUS_HOST
);
546 factory
.SetFakeResponse(
547 DownloadProtectionService::GetDownloadRequestUrl(),
548 response
.SerializeAsString(),
549 net::HTTP_OK
, net::URLRequestStatus::SUCCESS
);
551 download_service_
->CheckClientDownload(
553 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
554 base::Unretained(this)));
555 MessageLoop::current()->Run();
557 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS_HOST
));
558 EXPECT_TRUE(DownloadFeedbackService::GetPingsForDownloadForTesting(
559 item
, &feedback_ping
, &feedback_response
));
560 EXPECT_EQ(response
.SerializeAsString(), feedback_response
);
562 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE
));
565 // If the response is POTENTIALLY_UNWANTED the result should also be marked as
566 // POTENTIALLY_UNWANTED.
567 response
.set_verdict(ClientDownloadResponse::POTENTIALLY_UNWANTED
);
568 factory
.SetFakeResponse(
569 DownloadProtectionService::GetDownloadRequestUrl(),
570 response
.SerializeAsString(),
571 net::HTTP_OK
, net::URLRequestStatus::SUCCESS
);
573 download_service_
->CheckClientDownload(
575 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
576 base::Unretained(this)));
577 MessageLoop::current()->Run();
579 EXPECT_TRUE(IsResult(DownloadProtectionService::POTENTIALLY_UNWANTED
));
581 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE
));
585 TEST_F(DownloadProtectionServiceTest
, CheckClientDownloadHTTPS
) {
586 ClientDownloadResponse response
;
587 response
.set_verdict(ClientDownloadResponse::DANGEROUS
);
588 net::FakeURLFetcherFactory
factory(NULL
);
589 factory
.SetFakeResponse(
590 DownloadProtectionService::GetDownloadRequestUrl(),
591 response
.SerializeAsString(),
592 net::HTTP_OK
, net::URLRequestStatus::SUCCESS
);
594 base::FilePath
a_tmp(FILE_PATH_LITERAL("a.tmp"));
595 base::FilePath
a_exe(FILE_PATH_LITERAL("a.exe"));
596 std::vector
<GURL
> url_chain
;
597 url_chain
.push_back(GURL("http://www.evil.com/a.exe"));
598 GURL
referrer("http://www.google.com/");
599 std::string hash
= "hash";
601 content::MockDownloadItem item
;
602 EXPECT_CALL(item
, AddObserver(_
)).Times(1);
603 EXPECT_CALL(item
, RemoveObserver(_
)).Times(1);
604 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp
));
605 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_exe
));
606 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
607 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
608 EXPECT_CALL(item
, GetHash()).WillRepeatedly(ReturnRef(hash
));
609 EXPECT_CALL(item
, GetReceivedBytes()).WillRepeatedly(Return(100));
610 EXPECT_CALL(item
, HasUserGesture()).WillRepeatedly(Return(true));
611 EXPECT_CALL(item
, GetRemoteAddress()).WillRepeatedly(Return(""));
613 EXPECT_CALL(*sb_service_
->mock_database_manager(),
614 MatchDownloadWhitelistUrl(_
))
615 .WillRepeatedly(Return(false));
616 EXPECT_CALL(*signature_util_
.get(), CheckSignature(a_tmp
, _
)).Times(1);
618 download_service_
->CheckClientDownload(
620 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
621 base::Unretained(this)));
622 MessageLoop::current()->Run();
624 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS
));
626 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE
));
630 TEST_F(DownloadProtectionServiceTest
, CheckClientDownloadZip
) {
631 ClientDownloadResponse response
;
632 response
.set_verdict(ClientDownloadResponse::SAFE
);
633 net::FakeURLFetcherFactory
factory(NULL
);
634 // Empty response means SAFE.
635 factory
.SetFakeResponse(
636 DownloadProtectionService::GetDownloadRequestUrl(),
637 response
.SerializeAsString(),
638 net::HTTP_OK
, net::URLRequestStatus::SUCCESS
);
640 base::ScopedTempDir download_dir
;
641 ASSERT_TRUE(download_dir
.CreateUniqueTempDir());
643 base::FilePath
a_tmp(download_dir
.path().Append(FILE_PATH_LITERAL("a.tmp")));
644 base::FilePath
a_zip(FILE_PATH_LITERAL("a.zip"));
645 std::vector
<GURL
> url_chain
;
646 url_chain
.push_back(GURL("http://www.evil.com/a.zip"));
647 GURL
referrer("http://www.google.com/");
648 std::string hash
= "hash";
650 content::MockDownloadItem item
;
651 EXPECT_CALL(item
, AddObserver(_
)).Times(3);
652 EXPECT_CALL(item
, RemoveObserver(_
)).Times(3);
653 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp
));
654 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_zip
));
655 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
656 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
657 EXPECT_CALL(item
, GetHash()).WillRepeatedly(ReturnRef(hash
));
658 EXPECT_CALL(item
, GetReceivedBytes()).WillRepeatedly(Return(100));
659 EXPECT_CALL(item
, HasUserGesture()).WillRepeatedly(Return(true));
660 EXPECT_CALL(item
, GetRemoteAddress()).WillRepeatedly(Return(""));
662 // Write out a zip archive to the temporary file. In this case, it
663 // only contains a text file.
664 base::ScopedTempDir zip_source_dir
;
665 ASSERT_TRUE(zip_source_dir
.CreateUniqueTempDir());
666 std::string file_contents
= "dummy file";
667 ASSERT_EQ(static_cast<int>(file_contents
.size()), file_util::WriteFile(
668 zip_source_dir
.path().Append(FILE_PATH_LITERAL("file.txt")),
669 file_contents
.data(), file_contents
.size()));
670 ASSERT_TRUE(zip::Zip(zip_source_dir
.path(), a_tmp
, false));
672 download_service_
->CheckClientDownload(
674 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
675 base::Unretained(this)));
676 MessageLoop::current()->Run();
677 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE
));
678 Mock::VerifyAndClearExpectations(sb_service_
.get());
679 Mock::VerifyAndClearExpectations(signature_util_
.get());
681 // Now check with an executable in the zip file as well.
682 ASSERT_EQ(static_cast<int>(file_contents
.size()), file_util::WriteFile(
683 zip_source_dir
.path().Append(FILE_PATH_LITERAL("file.exe")),
684 file_contents
.data(), file_contents
.size()));
685 ASSERT_TRUE(zip::Zip(zip_source_dir
.path(), a_tmp
, false));
687 EXPECT_CALL(*sb_service_
->mock_database_manager(),
688 MatchDownloadWhitelistUrl(_
))
689 .WillRepeatedly(Return(false));
691 download_service_
->CheckClientDownload(
693 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
694 base::Unretained(this)));
695 MessageLoop::current()->Run();
696 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE
));
697 Mock::VerifyAndClearExpectations(signature_util_
.get());
699 // If the response is dangerous the result should also be marked as
701 response
.set_verdict(ClientDownloadResponse::DANGEROUS
);
702 factory
.SetFakeResponse(
703 DownloadProtectionService::GetDownloadRequestUrl(),
704 response
.SerializeAsString(),
705 net::HTTP_OK
, net::URLRequestStatus::SUCCESS
);
707 download_service_
->CheckClientDownload(
709 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
710 base::Unretained(this)));
711 MessageLoop::current()->Run();
713 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS
));
715 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE
));
717 Mock::VerifyAndClearExpectations(signature_util_
.get());
720 TEST_F(DownloadProtectionServiceTest
, CheckClientDownloadCorruptZip
) {
721 base::ScopedTempDir download_dir
;
722 ASSERT_TRUE(download_dir
.CreateUniqueTempDir());
724 base::FilePath
a_tmp(download_dir
.path().Append(FILE_PATH_LITERAL("a.tmp")));
725 base::FilePath
a_zip(FILE_PATH_LITERAL("a.zip"));
726 std::vector
<GURL
> url_chain
;
727 url_chain
.push_back(GURL("http://www.evil.com/a.zip"));
728 GURL
referrer("http://www.google.com/");
729 std::string hash
= "hash";
731 content::MockDownloadItem item
;
732 EXPECT_CALL(item
, AddObserver(_
)).Times(1);
733 EXPECT_CALL(item
, RemoveObserver(_
)).Times(1);
734 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp
));
735 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_zip
));
736 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
737 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
738 EXPECT_CALL(item
, GetHash()).WillRepeatedly(ReturnRef(hash
));
739 EXPECT_CALL(item
, GetReceivedBytes()).WillRepeatedly(Return(100));
740 EXPECT_CALL(item
, HasUserGesture()).WillRepeatedly(Return(true));
741 EXPECT_CALL(item
, GetRemoteAddress()).WillRepeatedly(Return(""));
743 std::string file_contents
= "corrupt zip file";
744 ASSERT_EQ(static_cast<int>(file_contents
.size()), file_util::WriteFile(
745 a_tmp
, file_contents
.data(), file_contents
.size()));
747 download_service_
->CheckClientDownload(
749 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
750 base::Unretained(this)));
751 MessageLoop::current()->Run();
752 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE
));
753 Mock::VerifyAndClearExpectations(sb_service_
.get());
754 Mock::VerifyAndClearExpectations(signature_util_
.get());
757 TEST_F(DownloadProtectionServiceTest
, CheckClientCrxDownloadSuccess
) {
758 ClientDownloadResponse response
;
759 // Even if the server verdict is dangerous we should return SAFE because
760 // DownloadProtectionService::IsSupportedDownload() will return false
761 // for crx downloads.
762 response
.set_verdict(ClientDownloadResponse::DANGEROUS
);
763 net::FakeURLFetcherFactory
factory(NULL
);
764 // Empty response means SAFE.
765 factory
.SetFakeResponse(
766 DownloadProtectionService::GetDownloadRequestUrl(),
767 response
.SerializeAsString(),
768 net::HTTP_OK
, net::URLRequestStatus::SUCCESS
);
770 base::FilePath
a_tmp(FILE_PATH_LITERAL("a.tmp"));
771 base::FilePath
a_crx(FILE_PATH_LITERAL("a.crx"));
772 std::vector
<GURL
> url_chain
;
773 url_chain
.push_back(GURL("http://www.evil.com/a.crx"));
774 GURL
referrer("http://www.google.com/");
775 std::string hash
= "hash";
777 content::MockDownloadItem item
;
778 EXPECT_CALL(item
, AddObserver(_
)).Times(1);
779 EXPECT_CALL(item
, RemoveObserver(_
)).Times(1);
780 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp
));
781 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_crx
));
782 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
783 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
784 EXPECT_CALL(item
, GetHash()).WillRepeatedly(ReturnRef(hash
));
785 EXPECT_CALL(item
, GetReceivedBytes()).WillRepeatedly(Return(100));
786 EXPECT_CALL(item
, HasUserGesture()).WillRepeatedly(Return(true));
787 EXPECT_CALL(item
, GetRemoteAddress()).WillRepeatedly(Return(""));
789 EXPECT_CALL(*sb_service_
->mock_database_manager(),
790 MatchDownloadWhitelistUrl(_
))
791 .WillRepeatedly(Return(false));
792 EXPECT_CALL(*signature_util_
.get(), CheckSignature(a_tmp
, _
)).Times(1);
794 EXPECT_FALSE(download_service_
->IsSupportedDownload(item
, a_crx
));
795 download_service_
->CheckClientDownload(
797 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
798 base::Unretained(this)));
799 MessageLoop::current()->Run();
800 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE
));
803 TEST_F(DownloadProtectionServiceTest
, CheckClientDownloadValidateRequest
) {
804 net::TestURLFetcherFactory factory
;
806 base::FilePath
tmp_path(FILE_PATH_LITERAL("bla.tmp"));
807 base::FilePath
final_path(FILE_PATH_LITERAL("bla.exe"));
808 std::vector
<GURL
> url_chain
;
809 url_chain
.push_back(GURL("http://www.google.com/"));
810 url_chain
.push_back(GURL("http://www.google.com/bla.exe"));
811 GURL
referrer("http://www.google.com/");
812 std::string hash
= "hash";
813 std::string remote_address
= "10.11.12.13";
815 content::MockDownloadItem item
;
816 EXPECT_CALL(item
, AddObserver(_
)).Times(1);
817 EXPECT_CALL(item
, RemoveObserver(_
)).Times(1);
818 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(tmp_path
));
819 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(final_path
));
820 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
821 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
822 EXPECT_CALL(item
, GetHash()).WillRepeatedly(ReturnRef(hash
));
823 EXPECT_CALL(item
, GetReceivedBytes()).WillRepeatedly(Return(100));
824 EXPECT_CALL(item
, HasUserGesture()).WillRepeatedly(Return(true));
825 EXPECT_CALL(item
, GetRemoteAddress()).WillRepeatedly(Return(remote_address
));
827 EXPECT_CALL(*sb_service_
->mock_database_manager(),
828 MatchDownloadWhitelistUrl(_
))
829 .WillRepeatedly(Return(false));
830 EXPECT_CALL(*signature_util_
.get(), CheckSignature(tmp_path
, _
))
831 .WillOnce(SetCertificateContents("dummy cert data"));
832 download_service_
->CheckClientDownload(
834 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
835 base::Unretained(this)));
838 // SendRequest is not called. Wait for FinishRequest to call our callback.
839 MessageLoop::current()->Run();
840 net::TestURLFetcher
* fetcher
= factory
.GetFetcherByID(0);
841 EXPECT_EQ(NULL
, fetcher
);
843 // Run the message loop(s) until SendRequest is called.
844 FlushThreadMessageLoops();
845 net::TestURLFetcher
* fetcher
= factory
.GetFetcherByID(0);
846 ASSERT_TRUE(fetcher
);
847 ClientDownloadRequest request
;
848 EXPECT_TRUE(request
.ParseFromString(fetcher
->upload_data()));
849 EXPECT_EQ("http://www.google.com/bla.exe", request
.url());
850 EXPECT_EQ(hash
, request
.digests().sha256());
851 EXPECT_EQ(item
.GetReceivedBytes(), request
.length());
852 EXPECT_EQ(item
.HasUserGesture(), request
.user_initiated());
853 EXPECT_TRUE(RequestContainsServerIp(request
, remote_address
));
854 EXPECT_EQ(2, request
.resources_size());
855 EXPECT_TRUE(RequestContainsResource(request
,
856 ClientDownloadRequest::DOWNLOAD_REDIRECT
,
857 "http://www.google.com/", ""));
858 EXPECT_TRUE(RequestContainsResource(request
,
859 ClientDownloadRequest::DOWNLOAD_URL
,
860 "http://www.google.com/bla.exe",
862 EXPECT_TRUE(request
.has_signature());
863 ASSERT_EQ(1, request
.signature().certificate_chain_size());
864 const ClientDownloadRequest_CertificateChain
& chain
=
865 request
.signature().certificate_chain(0);
866 ASSERT_EQ(1, chain
.element_size());
867 EXPECT_EQ("dummy cert data", chain
.element(0).certificate());
869 // Simulate the request finishing.
870 base::MessageLoop::current()->PostTask(
872 base::Bind(&DownloadProtectionServiceTest::SendURLFetchComplete
,
873 base::Unretained(this), fetcher
));
874 MessageLoop::current()->Run();
878 // Similar to above, but with an unsigned binary.
879 TEST_F(DownloadProtectionServiceTest
,
880 CheckClientDownloadValidateRequestNoSignature
) {
881 net::TestURLFetcherFactory factory
;
883 base::FilePath
tmp_path(FILE_PATH_LITERAL("bla.tmp"));
884 base::FilePath
final_path(FILE_PATH_LITERAL("bla.exe"));
885 std::vector
<GURL
> url_chain
;
886 url_chain
.push_back(GURL("http://www.google.com/"));
887 url_chain
.push_back(GURL("ftp://www.google.com/bla.exe"));
888 GURL
referrer("http://www.google.com/");
889 std::string hash
= "hash";
890 std::string remote_address
= "10.11.12.13";
892 content::MockDownloadItem item
;
893 EXPECT_CALL(item
, AddObserver(_
)).Times(1);
894 EXPECT_CALL(item
, RemoveObserver(_
)).Times(1);
895 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(tmp_path
));
896 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(final_path
));
897 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
898 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
899 EXPECT_CALL(item
, GetHash()).WillRepeatedly(ReturnRef(hash
));
900 EXPECT_CALL(item
, GetReceivedBytes()).WillRepeatedly(Return(100));
901 EXPECT_CALL(item
, HasUserGesture()).WillRepeatedly(Return(true));
902 EXPECT_CALL(item
, GetRemoteAddress()).WillRepeatedly(Return(remote_address
));
904 EXPECT_CALL(*sb_service_
->mock_database_manager(),
905 MatchDownloadWhitelistUrl(_
))
906 .WillRepeatedly(Return(false));
907 EXPECT_CALL(*signature_util_
.get(), CheckSignature(tmp_path
, _
));
908 download_service_
->CheckClientDownload(
910 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
911 base::Unretained(this)));
914 // SendRequest is not called. Wait for FinishRequest to call our callback.
915 MessageLoop::current()->Run();
916 net::TestURLFetcher
* fetcher
= factory
.GetFetcherByID(0);
917 EXPECT_EQ(NULL
, fetcher
);
919 // Run the message loop(s) until SendRequest is called.
920 FlushThreadMessageLoops();
921 net::TestURLFetcher
* fetcher
= factory
.GetFetcherByID(0);
922 ASSERT_TRUE(fetcher
);
923 ClientDownloadRequest request
;
924 EXPECT_TRUE(request
.ParseFromString(fetcher
->upload_data()));
925 EXPECT_EQ("ftp://www.google.com/bla.exe", request
.url());
926 EXPECT_EQ(hash
, request
.digests().sha256());
927 EXPECT_EQ(item
.GetReceivedBytes(), request
.length());
928 EXPECT_EQ(item
.HasUserGesture(), request
.user_initiated());
929 EXPECT_EQ(2, request
.resources_size());
930 EXPECT_TRUE(RequestContainsResource(request
,
931 ClientDownloadRequest::DOWNLOAD_REDIRECT
,
932 "http://www.google.com/", ""));
933 EXPECT_TRUE(RequestContainsResource(request
,
934 ClientDownloadRequest::DOWNLOAD_URL
,
935 "ftp://www.google.com/bla.exe",
937 EXPECT_TRUE(request
.has_signature());
938 EXPECT_EQ(0, request
.signature().certificate_chain_size());
940 // Simulate the request finishing.
941 base::MessageLoop::current()->PostTask(
943 base::Bind(&DownloadProtectionServiceTest::SendURLFetchComplete
,
944 base::Unretained(this), fetcher
));
945 MessageLoop::current()->Run();
949 TEST_F(DownloadProtectionServiceTest
, TestCheckDownloadUrl
) {
950 std::vector
<GURL
> url_chain
;
951 url_chain
.push_back(GURL("http://www.google.com/"));
952 url_chain
.push_back(GURL("http://www.google.com/bla.exe"));
953 GURL
referrer("http://www.google.com/");
954 std::string hash
= "hash";
956 content::MockDownloadItem item
;
957 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
958 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
959 EXPECT_CALL(item
, GetHash()).WillRepeatedly(ReturnRef(hash
));
961 // CheckDownloadURL returns immediately which means the client object callback
962 // will never be called. Nevertheless the callback provided to
963 // CheckClientDownload must still be called.
964 EXPECT_CALL(*sb_service_
->mock_database_manager(),
965 CheckDownloadUrl(ContainerEq(url_chain
), NotNull()))
966 .WillOnce(Return(true));
967 download_service_
->CheckDownloadUrl(
969 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
970 base::Unretained(this)));
971 MessageLoop::current()->Run();
972 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE
));
973 Mock::VerifyAndClearExpectations(sb_service_
.get());
975 EXPECT_CALL(*sb_service_
->mock_database_manager(),
976 CheckDownloadUrl(ContainerEq(url_chain
), NotNull()))
977 .WillOnce(DoAll(CheckDownloadUrlDone(SB_THREAT_TYPE_SAFE
),
979 download_service_
->CheckDownloadUrl(
981 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
982 base::Unretained(this)));
983 MessageLoop::current()->Run();
984 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE
));
985 Mock::VerifyAndClearExpectations(sb_service_
.get());
987 EXPECT_CALL(*sb_service_
->mock_database_manager(),
988 CheckDownloadUrl(ContainerEq(url_chain
), NotNull()))
990 CheckDownloadUrlDone(SB_THREAT_TYPE_URL_MALWARE
),
992 download_service_
->CheckDownloadUrl(
994 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
995 base::Unretained(this)));
996 MessageLoop::current()->Run();
997 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE
));
998 Mock::VerifyAndClearExpectations(sb_service_
.get());
1000 EXPECT_CALL(*sb_service_
->mock_database_manager(),
1001 CheckDownloadUrl(ContainerEq(url_chain
),
1004 CheckDownloadUrlDone(SB_THREAT_TYPE_BINARY_MALWARE_URL
),
1006 download_service_
->CheckDownloadUrl(
1008 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
1009 base::Unretained(this)));
1010 MessageLoop::current()->Run();
1011 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS
));
1014 TEST_F(DownloadProtectionServiceTest
, TestDownloadRequestTimeout
) {
1015 net::TestURLFetcherFactory factory
;
1017 std::vector
<GURL
> url_chain
;
1018 url_chain
.push_back(GURL("http://www.evil.com/bla.exe"));
1019 GURL
referrer("http://www.google.com/");
1020 base::FilePath
tmp_path(FILE_PATH_LITERAL("a.tmp"));
1021 base::FilePath
final_path(FILE_PATH_LITERAL("a.exe"));
1022 std::string hash
= "hash";
1024 content::MockDownloadItem item
;
1025 EXPECT_CALL(item
, AddObserver(_
)).Times(1);
1026 EXPECT_CALL(item
, RemoveObserver(_
)).Times(1);
1027 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(tmp_path
));
1028 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(final_path
));
1029 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
1030 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
1031 EXPECT_CALL(item
, GetHash()).WillRepeatedly(ReturnRef(hash
));
1032 EXPECT_CALL(item
, GetReceivedBytes()).WillRepeatedly(Return(100));
1033 EXPECT_CALL(item
, HasUserGesture()).WillRepeatedly(Return(true));
1034 EXPECT_CALL(item
, GetRemoteAddress()).WillRepeatedly(Return(""));
1036 EXPECT_CALL(*sb_service_
->mock_database_manager(),
1037 MatchDownloadWhitelistUrl(_
))
1038 .WillRepeatedly(Return(false));
1039 EXPECT_CALL(*signature_util_
.get(), CheckSignature(tmp_path
, _
));
1041 download_service_
->download_request_timeout_ms_
= 10;
1042 download_service_
->CheckClientDownload(
1044 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
1045 base::Unretained(this)));
1047 // The request should time out because the HTTP request hasn't returned
1049 MessageLoop::current()->Run();
1050 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE
));
1053 TEST_F(DownloadProtectionServiceTest
, TestDownloadItemDestroyed
) {
1054 net::TestURLFetcherFactory factory
;
1056 std::vector
<GURL
> url_chain
;
1057 url_chain
.push_back(GURL("http://www.evil.com/bla.exe"));
1058 GURL
referrer("http://www.google.com/");
1059 base::FilePath
tmp_path(FILE_PATH_LITERAL("a.tmp"));
1060 base::FilePath
final_path(FILE_PATH_LITERAL("a.exe"));
1061 std::string hash
= "hash";
1063 content::MockDownloadItem item
;
1064 content::DownloadItem::Observer
* observer
= NULL
;
1065 EXPECT_CALL(item
, AddObserver(_
)).WillOnce(SaveArg
<0>(&observer
));
1066 EXPECT_CALL(item
, RemoveObserver(_
)).WillOnce(Assign(
1067 &observer
, static_cast<content::DownloadItem::Observer
*>(NULL
)));
1068 EXPECT_CALL(item
, GetFullPath()).WillRepeatedly(ReturnRef(tmp_path
));
1069 EXPECT_CALL(item
, GetTargetFilePath()).WillRepeatedly(ReturnRef(final_path
));
1070 EXPECT_CALL(item
, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain
));
1071 EXPECT_CALL(item
, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer
));
1072 EXPECT_CALL(item
, GetHash()).WillRepeatedly(ReturnRef(hash
));
1073 EXPECT_CALL(item
, GetReceivedBytes()).WillRepeatedly(Return(100));
1074 EXPECT_CALL(item
, HasUserGesture()).WillRepeatedly(Return(true));
1075 EXPECT_CALL(item
, GetRemoteAddress()).WillRepeatedly(Return(""));
1077 EXPECT_CALL(*sb_service_
->mock_database_manager(),
1078 MatchDownloadWhitelistUrl(_
))
1079 .WillRepeatedly(Return(false));
1080 EXPECT_CALL(*signature_util_
.get(), CheckSignature(tmp_path
, _
));
1082 download_service_
->CheckClientDownload(
1084 base::Bind(&DownloadProtectionServiceTest::SyncCheckDoneCallback
,
1085 base::Unretained(this)));
1087 ASSERT_TRUE(observer
!= NULL
);
1088 observer
->OnDownloadDestroyed(&item
);
1090 EXPECT_TRUE(observer
== NULL
);
1091 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE
));
1094 TEST_F(DownloadProtectionServiceTest
, GetCertificateWhitelistStrings
) {
1095 // We'll pass this cert in as the "issuer", even though it isn't really
1096 // used to sign the certs below. GetCertificateWhitelistStirngs doesn't care
1098 scoped_refptr
<net::X509Certificate
> issuer_cert(
1099 ReadTestCertificate("issuer.pem"));
1100 ASSERT_TRUE(issuer_cert
.get());
1101 std::string cert_base
= "cert/" + base::HexEncode(
1102 issuer_cert
->fingerprint().data
,
1103 sizeof(issuer_cert
->fingerprint().data
));
1105 scoped_refptr
<net::X509Certificate
> cert(ReadTestCertificate("test_cn.pem"));
1106 ASSERT_TRUE(cert
.get());
1107 std::vector
<std::string
> whitelist_strings
;
1108 GetCertificateWhitelistStrings(
1109 *cert
.get(), *issuer_cert
.get(), &whitelist_strings
);
1110 // This also tests escaping of characters in the certificate attributes.
1111 EXPECT_THAT(whitelist_strings
, ElementsAre(
1112 cert_base
+ "/CN=subject%2F%251"));
1114 cert
= ReadTestCertificate("test_cn_o.pem");
1115 ASSERT_TRUE(cert
.get());
1116 whitelist_strings
.clear();
1117 GetCertificateWhitelistStrings(
1118 *cert
.get(), *issuer_cert
.get(), &whitelist_strings
);
1119 EXPECT_THAT(whitelist_strings
,
1120 ElementsAre(cert_base
+ "/CN=subject",
1121 cert_base
+ "/CN=subject/O=org",
1122 cert_base
+ "/O=org"));
1124 cert
= ReadTestCertificate("test_cn_o_ou.pem");
1125 ASSERT_TRUE(cert
.get());
1126 whitelist_strings
.clear();
1127 GetCertificateWhitelistStrings(
1128 *cert
.get(), *issuer_cert
.get(), &whitelist_strings
);
1129 EXPECT_THAT(whitelist_strings
,
1130 ElementsAre(cert_base
+ "/CN=subject",
1131 cert_base
+ "/CN=subject/O=org",
1132 cert_base
+ "/CN=subject/O=org/OU=unit",
1133 cert_base
+ "/CN=subject/OU=unit",
1134 cert_base
+ "/O=org",
1135 cert_base
+ "/O=org/OU=unit",
1136 cert_base
+ "/OU=unit"));
1138 cert
= ReadTestCertificate("test_cn_ou.pem");
1139 ASSERT_TRUE(cert
.get());
1140 whitelist_strings
.clear();
1141 GetCertificateWhitelistStrings(
1142 *cert
.get(), *issuer_cert
.get(), &whitelist_strings
);
1143 EXPECT_THAT(whitelist_strings
,
1144 ElementsAre(cert_base
+ "/CN=subject",
1145 cert_base
+ "/CN=subject/OU=unit",
1146 cert_base
+ "/OU=unit"));
1148 cert
= ReadTestCertificate("test_o.pem");
1149 ASSERT_TRUE(cert
.get());
1150 whitelist_strings
.clear();
1151 GetCertificateWhitelistStrings(
1152 *cert
.get(), *issuer_cert
.get(), &whitelist_strings
);
1153 EXPECT_THAT(whitelist_strings
, ElementsAre(cert_base
+ "/O=org"));
1155 cert
= ReadTestCertificate("test_o_ou.pem");
1156 ASSERT_TRUE(cert
.get());
1157 whitelist_strings
.clear();
1158 GetCertificateWhitelistStrings(
1159 *cert
.get(), *issuer_cert
.get(), &whitelist_strings
);
1160 EXPECT_THAT(whitelist_strings
,
1161 ElementsAre(cert_base
+ "/O=org",
1162 cert_base
+ "/O=org/OU=unit",
1163 cert_base
+ "/OU=unit"));
1165 cert
= ReadTestCertificate("test_ou.pem");
1166 ASSERT_TRUE(cert
.get());
1167 whitelist_strings
.clear();
1168 GetCertificateWhitelistStrings(
1169 *cert
.get(), *issuer_cert
.get(), &whitelist_strings
);
1170 EXPECT_THAT(whitelist_strings
, ElementsAre(cert_base
+ "/OU=unit"));
1172 cert
= ReadTestCertificate("test_c.pem");
1173 ASSERT_TRUE(cert
.get());
1174 whitelist_strings
.clear();
1175 GetCertificateWhitelistStrings(
1176 *cert
.get(), *issuer_cert
.get(), &whitelist_strings
);
1177 EXPECT_THAT(whitelist_strings
, ElementsAre());
1179 } // namespace safe_browsing