Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / safe_browsing / download_protection_service_unittest.cc
blob4752b16f9d62d429103953d34fecfe0ca53c35d1
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"
7 #include <map>
8 #include <string>
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"
39 #include "url/gurl.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;
51 using ::testing::_;
52 using base::MessageLoop;
53 using content::BrowserThread;
54 namespace safe_browsing {
55 namespace {
56 // A SafeBrowsingDatabaseManager implementation that returns a fixed result for
57 // a given URL.
58 class MockSafeBrowsingDatabaseManager : public SafeBrowsingDatabaseManager {
59 public:
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));
69 private:
70 virtual ~MockSafeBrowsingDatabaseManager() {}
71 DISALLOW_COPY_AND_ASSIGN(MockSafeBrowsingDatabaseManager);
74 class FakeSafeBrowsingService : public SafeBrowsingService {
75 public:
76 FakeSafeBrowsingService() { }
78 // Returned pointer has the same lifespan as the database_manager_ refcounted
79 // object.
80 MockSafeBrowsingDatabaseManager* mock_database_manager() {
81 return mock_database_manager_;
84 protected:
85 virtual ~FakeSafeBrowsingService() { }
87 virtual SafeBrowsingDatabaseManager* CreateDatabaseManager() OVERRIDE {
88 mock_database_manager_ = new MockSafeBrowsingDatabaseManager(this);
89 return mock_database_manager_;
92 private:
93 MockSafeBrowsingDatabaseManager* mock_database_manager_;
95 DISALLOW_COPY_AND_ASSIGN(FakeSafeBrowsingService);
98 class MockSignatureUtil : public SignatureUtil {
99 public:
100 MockSignatureUtil() {}
101 MOCK_METHOD2(CheckSignature, void (const base::FilePath&,
102 ClientDownloadRequest_SignatureInfo*));
104 protected:
105 virtual ~MockSignatureUtil() {}
107 private:
108 DISALLOW_COPY_AND_ASSIGN(MockSignatureUtil);
110 } // namespace
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
131 // deleted.
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(
140 arg0,
141 std::vector<SBFullHash>(),
142 arg1,
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,
148 FROM_HERE,
149 base::Bind(&OnSafeBrowsingResult,
150 base::Owned(check)));
153 class DownloadProtectionServiceTest : public testing::Test {
154 protected:
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();
169 has_result_ = false;
171 base::FilePath source_path;
172 ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &source_path));
173 testdata_path_ = source_path
174 .AppendASCII("chrome")
175 .AppendASCII("test")
176 .AppendASCII("data")
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();
186 sb_service_ = NULL;
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)) {
197 return true;
200 return false;
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();
215 return false;
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),
240 &cert_data)) {
241 return NULL;
243 net::CertificateList certs =
244 net::X509Certificate::CreateCertificateListFromBytes(
245 cert_data.data(),
246 cert_data.size(),
247 net::X509Certificate::FORMAT_PEM_CERT_SEQUENCE);
248 return certs.empty() ? NULL : certs[0];
251 private:
252 // Helper functions for FlushThreadMessageLoops.
253 void RunAllPendingAndQuitUI() {
254 base::MessageLoop::current()->RunUntilIdle();
255 BrowserThread::PostTask(
256 BrowserThread::UI,
257 FROM_HERE,
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(
268 thread,
269 FROM_HERE,
270 base::Bind(&DownloadProtectionServiceTest::RunAllPendingAndQuitUI,
271 base::Unretained(this)));
274 void FlushMessageLoop(BrowserThread::ID thread) {
275 BrowserThread::PostTask(
276 BrowserThread::UI,
277 FROM_HERE,
278 base::Bind(&DownloadProtectionServiceTest::PostRunMessageLoopTask,
279 base::Unretained(this), thread));
280 MessageLoop::current()->Run();
283 public:
284 void CheckDoneCallback(
285 DownloadProtectionService::DownloadCheckResult result) {
286 result_ = result;
287 has_result_ = true;
288 MessageLoop::current()->Quit();
291 void SyncCheckDoneCallback(
292 DownloadProtectionService::DownloadCheckResult result) {
293 result_ = result;
294 has_result_ = true;
297 void SendURLFetchComplete(net::TestURLFetcher* fetcher) {
298 fetcher->delegate()->OnURLFetchComplete(fetcher);
301 testing::AssertionResult IsResult(
302 DownloadProtectionService::DownloadCheckResult expected) {
303 if (!has_result_)
304 return testing::AssertionFailure() << "No result";
305 has_result_ = false;
306 return result_ == expected ?
307 testing::AssertionSuccess() :
308 testing::AssertionFailure() << "Expected " << expected <<
309 ", got " << result_;
312 protected:
313 scoped_refptr<FakeSafeBrowsingService> sb_service_;
314 scoped_refptr<MockSignatureUtil> signature_util_;
315 DownloadProtectionService* download_service_;
316 DownloadProtectionService::DownloadCheckResult result_;
317 bool has_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(
337 &item,
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(
352 &item,
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(
383 &item,
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(
393 &item,
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(
432 &item,
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(
474 &item,
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.
481 response.Clear();
482 factory.SetFakeResponse(
483 DownloadProtectionService::GetDownloadRequestUrl(),
484 response.SerializePartialAsString(),
485 net::HTTP_OK, net::URLRequestStatus::SUCCESS);
487 download_service_->CheckClientDownload(
488 &item,
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(
506 &item,
507 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
508 base::Unretained(this)));
509 MessageLoop::current()->Run();
510 EXPECT_FALSE(DownloadFeedbackService::GetPingsForDownloadForTesting(
511 item, &feedback_ping, &feedback_response));
512 #if defined(OS_WIN)
513 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS));
514 #else
515 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
516 #endif
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(
526 &item,
527 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
528 base::Unretained(this)));
529 MessageLoop::current()->Run();
530 #if defined(OS_WIN)
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);
538 #else
539 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
540 #endif
542 // If the response is dangerous_host the result should also be marked as
543 // dangerous_host.
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(
551 &item,
552 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
553 base::Unretained(this)));
554 MessageLoop::current()->Run();
555 #if defined(OS_WIN)
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);
560 #else
561 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
562 #endif
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(
573 &item,
574 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
575 base::Unretained(this)));
576 MessageLoop::current()->Run();
577 #if defined(OS_WIN)
578 EXPECT_TRUE(IsResult(DownloadProtectionService::POTENTIALLY_UNWANTED));
579 #else
580 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
581 #endif
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(
618 &item,
619 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
620 base::Unretained(this)));
621 MessageLoop::current()->Run();
622 #if defined(OS_WIN)
623 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS));
624 #else
625 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
626 #endif
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(
672 &item,
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(
691 &item,
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
699 // dangerous.
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(
707 &item,
708 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
709 base::Unretained(this)));
710 MessageLoop::current()->Run();
711 #if defined(OS_WIN)
712 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS));
713 #else
714 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
715 #endif
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(
747 &item,
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(
795 &item,
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(
832 &item,
833 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
834 base::Unretained(this)));
836 #if !defined(OS_WIN)
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);
841 #else
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",
860 referrer.spec()));
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(
870 FROM_HERE,
871 base::Bind(&DownloadProtectionServiceTest::SendURLFetchComplete,
872 base::Unretained(this), fetcher));
873 MessageLoop::current()->Run();
874 #endif
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(
908 &item,
909 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
910 base::Unretained(this)));
912 #if !defined(OS_WIN)
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);
917 #else
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",
935 referrer.spec()));
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(
941 FROM_HERE,
942 base::Bind(&DownloadProtectionServiceTest::SendURLFetchComplete,
943 base::Unretained(this), fetcher));
944 MessageLoop::current()->Run();
945 #endif
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(
967 item,
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),
977 Return(false)));
978 download_service_->CheckDownloadUrl(
979 item,
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()))
988 .WillOnce(DoAll(
989 CheckDownloadUrlDone(SB_THREAT_TYPE_URL_MALWARE),
990 Return(false)));
991 download_service_->CheckDownloadUrl(
992 item,
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),
1001 NotNull()))
1002 .WillOnce(DoAll(
1003 CheckDownloadUrlDone(SB_THREAT_TYPE_BINARY_MALWARE_URL),
1004 Return(false)));
1005 download_service_->CheckDownloadUrl(
1006 item,
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(
1042 &item,
1043 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
1044 base::Unretained(this)));
1046 // The request should time out because the HTTP request hasn't returned
1047 // anything yet.
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(
1082 &item,
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
1096 // about this.
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