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