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