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