Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / safe_browsing / download_protection_service_unittest.cc
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.
4
5 #include "chrome/browser/safe_browsing/download_protection_service.h"
6
7 #include <map>
8 #include <string>
9
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"
43
44 #if defined(OS_MACOSX)
45 #include "base/metrics/field_trial.h"
46 #include "components/variations/entropy_provider.h"
47 #endif
48
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) { }
70
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));
76
77  private:
78   virtual ~MockSafeBrowsingDatabaseManager() {}
79   DISALLOW_COPY_AND_ASSIGN(MockSafeBrowsingDatabaseManager);
80 };
81
82 class FakeSafeBrowsingService : public SafeBrowsingService {
83  public:
84   FakeSafeBrowsingService() { }
85
86   // Returned pointer has the same lifespan as the database_manager_ refcounted
87   // object.
88   MockSafeBrowsingDatabaseManager* mock_database_manager() {
89     return mock_database_manager_;
90   }
91
92  protected:
93   virtual ~FakeSafeBrowsingService() { }
94
95   virtual SafeBrowsingDatabaseManager* CreateDatabaseManager() OVERRIDE {
96     mock_database_manager_ = new MockSafeBrowsingDatabaseManager(this);
97     return mock_database_manager_;
98   }
99
100   virtual void RegisterAllDelayedAnalysis() OVERRIDE { }
101
102  private:
103   MockSafeBrowsingDatabaseManager* mock_database_manager_;
104
105   DISALLOW_COPY_AND_ASSIGN(FakeSafeBrowsingService);
106 };
107
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*));
115
116  protected:
117   virtual ~MockBinaryFeatureExtractor() {}
118
119  private:
120   DISALLOW_COPY_AND_ASSIGN(MockBinaryFeatureExtractor);
121 };
122
123 class TestURLFetcherWatcher : public net::TestURLFetcherDelegateForTests {
124  public:
125   explicit TestURLFetcherWatcher(net::TestURLFetcherFactory* factory)
126       : factory_(factory), fetcher_id_(-1) {
127     factory_->SetDelegateForTests(this);
128   }
129   ~TestURLFetcherWatcher() {
130     factory_->SetDelegateForTests(NULL);
131   }
132
133   // TestURLFetcherDelegateForTests impl:
134   virtual void OnRequestStart(int fetcher_id) OVERRIDE {
135     fetcher_id_ = fetcher_id;
136     run_loop_.Quit();
137   }
138   virtual void OnChunkUpload(int fetcher_id) OVERRIDE {}
139   virtual void OnRequestEnd(int fetcher_id) OVERRIDE {}
140
141   int WaitForRequest() {
142     run_loop_.Run();
143     return fetcher_id_;
144   }
145
146  private:
147   net::TestURLFetcherFactory* factory_;
148   int fetcher_id_;
149   base::RunLoop run_loop_;
150 };
151 }  // namespace
152
153 ACTION_P(SetCertificateContents, contents) {
154   arg1->add_certificate_chain()->add_element()->set_certificate(contents);
155 }
156
157 ACTION_P(SetDosHeaderContents, contents) {
158   arg1->mutable_pe_headers()->set_dos_header(contents);
159 }
160
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);
171 }
172
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);
180 }
181
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)));
196 }
197
198 class DownloadProtectionServiceTest : public testing::Test {
199  protected:
200   DownloadProtectionServiceTest()
201       : test_browser_thread_bundle_(
202             content::TestBrowserThreadBundle::IO_MAINLOOP) {
203   }
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;
222
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");
231   }
232
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;
239   }
240
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;
250       }
251     }
252     return false;
253   }
254
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();
265       }
266     }
267     return false;
268   }
269
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();
275   }
276
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);
284   }
285
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;
294     }
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];
301   }
302
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)));
312   }
313
314   void QuitMessageLoop() {
315     base::MessageLoop::current()->Quit();
316   }
317
318   void PostRunMessageLoopTask(BrowserThread::ID thread) {
319     BrowserThread::PostTask(
320         thread,
321         FROM_HERE,
322         base::Bind(&DownloadProtectionServiceTest::RunAllPendingAndQuitUI,
323                    base::Unretained(this)));
324   }
325
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();
333   }
334
335  public:
336   void CheckDoneCallback(
337       DownloadProtectionService::DownloadCheckResult result) {
338     result_ = result;
339     has_result_ = true;
340     MessageLoop::current()->Quit();
341   }
342
343   void SyncCheckDoneCallback(
344       DownloadProtectionService::DownloadCheckResult result) {
345     result_ = result;
346     has_result_ = true;
347   }
348
349   void SendURLFetchComplete(net::TestURLFetcher* fetcher) {
350     fetcher->delegate()->OnURLFetchComplete(fetcher);
351   }
352
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_;
362   }
363
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
376 };
377
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/");
383
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);
399
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));
414 }
415
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/");
421
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));
437 }
438
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);
448
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;
454
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);
471
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));
481
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
494
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
507
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
520
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
533 }
534
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);
541
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";
548
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(""));
561
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, _));
567
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));
574 }
575
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);
585
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";
592
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(""));
605
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);
613
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
626
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);
633
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));
644
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);
651
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
664
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);
671
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
688
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);
696
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
710
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);
718
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
729 }
730
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);
739
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";
746
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(""));
759
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);
767
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
778 }
779
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);
789
790   base::ScopedTempDir download_dir;
791   ASSERT_TRUE(download_dir.CreateUniqueTempDir());
792
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";
799
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(""));
812
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));
822
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());
831
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));
837
838   EXPECT_CALL(*sb_service_->mock_database_manager(),
839               MatchDownloadWhitelistUrl(_))
840       .WillRepeatedly(Return(false));
841
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());
855
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);
863
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());
875 }
876
877 TEST_F(DownloadProtectionServiceTest, CheckClientDownloadCorruptZip) {
878   base::ScopedTempDir download_dir;
879   ASSERT_TRUE(download_dir.CreateUniqueTempDir());
880
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";
887
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(""));
900
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()));
904
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());
913 }
914
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);
927
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";
934
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(""));
947
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);
955
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));
963 }
964
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();
971
972   net::TestURLFetcherFactory factory;
973
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";
982
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));
995
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)));
1008
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);
1013 }
1014 #endif
1015
1016 TEST_F(DownloadProtectionServiceTest, CheckClientDownloadValidateRequest) {
1017   net::TestURLFetcherFactory factory;
1018
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";
1027
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));
1040
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)));
1053
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());
1091
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
1099 }
1100
1101 // Similar to above, but with an unsigned binary.
1102 TEST_F(DownloadProtectionServiceTest,
1103        CheckClientDownloadValidateRequestNoSignature) {
1104   net::TestURLFetcherFactory factory;
1105
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";
1114
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));
1127
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)));
1138
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());
1165
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
1173 }
1174
1175 // Similar to above, but with tab history.
1176 TEST_F(DownloadProtectionServiceTest,
1177        CheckClientDownloadValidateRequestTabHistory) {
1178   net::TestURLFetcherFactory factory;
1179
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 */));
1185
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";
1196
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"));
1218
1219   // First test with no history match for the tab URL.
1220   {
1221     TestURLFetcherWatcher fetcher_watcher(&factory);
1222     download_service_->CheckClientDownload(
1223         &item,
1224         base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
1225                    base::Unretained(this)));
1226
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());
1269
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
1278   }
1279
1280   // Now try with a history match.
1281   {
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),
1290                   0,
1291                   GURL(),
1292                   redirects,
1293                   ui::PAGE_TRANSITION_TYPED,
1294                   history::SOURCE_BROWSED,
1295                   false);
1296
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());
1346
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
1355   }
1356 }
1357
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";
1364
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));
1369
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());
1383
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());
1395
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());
1408
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));
1421 }
1422
1423 TEST_F(DownloadProtectionServiceTest, TestDownloadRequestTimeout) {
1424   net::TestURLFetcherFactory factory;
1425
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";
1432
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(""));
1445
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, _));
1452
1453   download_service_->download_request_timeout_ms_ = 10;
1454   download_service_->CheckClientDownload(
1455       &item,
1456       base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
1457                  base::Unretained(this)));
1458
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));
1463 }
1464
1465 TEST_F(DownloadProtectionServiceTest, TestDownloadItemDestroyed) {
1466   net::TestURLFetcherFactory factory;
1467
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";
1474
1475   {
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(""));
1489
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, _));
1496
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.
1503   }
1504
1505   EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN));
1506 }
1507
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));
1518
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"));
1527
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"));
1537
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"));
1551
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"));
1561
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"));
1568
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"));
1578
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"));
1585
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());
1592 }
1593 }  // namespace safe_browsing