Home | History | Annotate | Download | only in safe_browsing
      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/command_line.h"
     14 #include "base/file_util.h"
     15 #include "base/files/file_path.h"
     16 #include "base/files/scoped_temp_dir.h"
     17 #include "base/memory/ref_counted.h"
     18 #include "base/memory/scoped_ptr.h"
     19 #include "base/message_loop/message_loop.h"
     20 #include "base/path_service.h"
     21 #include "base/run_loop.h"
     22 #include "base/strings/string_number_conversions.h"
     23 #include "base/threading/sequenced_worker_pool.h"
     24 #include "chrome/browser/safe_browsing/database_manager.h"
     25 #include "chrome/browser/safe_browsing/download_feedback_service.h"
     26 #include "chrome/browser/safe_browsing/safe_browsing_service.h"
     27 #include "chrome/browser/safe_browsing/signature_util.h"
     28 #include "chrome/common/chrome_switches.h"
     29 #include "chrome/common/safe_browsing/csd.pb.h"
     30 #include "content/public/browser/render_process_host.h"
     31 #include "content/public/test/mock_download_item.h"
     32 #include "content/public/test/test_browser_thread_bundle.h"
     33 #include "net/cert/x509_certificate.h"
     34 #include "net/url_request/test_url_fetcher_factory.h"
     35 #include "net/url_request/url_fetcher_delegate.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(file_util::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   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     CommandLine::ForCurrentProcess()->AppendSwitch(
    161         switches::kSbEnableDownloadFeedback);
    162     // Start real threads for the IO and File threads so that the DCHECKs
    163     // to test that we're on the correct thread work.
    164     sb_service_ = new StrictMock<FakeSafeBrowsingService>();
    165     sb_service_->Initialize();
    166     signature_util_ = new StrictMock<MockSignatureUtil>();
    167     download_service_ = sb_service_->download_protection_service();
    168     download_service_->signature_util_ = signature_util_;
    169     download_service_->SetEnabled(true);
    170     base::RunLoop().RunUntilIdle();
    171     has_result_ = false;
    172 
    173     base::FilePath source_path;
    174     ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &source_path));
    175     testdata_path_ = source_path
    176         .AppendASCII("chrome")
    177         .AppendASCII("test")
    178         .AppendASCII("data")
    179         .AppendASCII("safe_browsing")
    180         .AppendASCII("download_protection");
    181   }
    182 
    183   virtual void TearDown() {
    184     sb_service_->ShutDown();
    185     // Flush all of the thread message loops to ensure that there are no
    186     // tasks currently running.
    187     FlushThreadMessageLoops();
    188     sb_service_ = NULL;
    189     content::RenderProcessHost::SetRunRendererInProcess(false);
    190   }
    191 
    192   bool RequestContainsResource(const ClientDownloadRequest& request,
    193                                ClientDownloadRequest::ResourceType type,
    194                                const std::string& url,
    195                                const std::string& referrer) {
    196     for (int i = 0; i < request.resources_size(); ++i) {
    197       if (request.resources(i).url() == url &&
    198           request.resources(i).type() == type &&
    199           (referrer.empty() || request.resources(i).referrer() == referrer)) {
    200         return true;
    201       }
    202     }
    203     return false;
    204   }
    205 
    206   // At this point we only set the server IP for the download itself.
    207   bool RequestContainsServerIp(const ClientDownloadRequest& request,
    208                                const std::string& remote_address) {
    209     for (int i = 0; i < request.resources_size(); ++i) {
    210       // We want the last DOWNLOAD_URL in the chain.
    211       if (request.resources(i).type() == ClientDownloadRequest::DOWNLOAD_URL &&
    212           (i + 1 == request.resources_size() ||
    213            request.resources(i + 1).type() !=
    214            ClientDownloadRequest::DOWNLOAD_URL)) {
    215         return remote_address == request.resources(i).remote_ip();
    216       }
    217     }
    218     return false;
    219   }
    220 
    221   // Flushes any pending tasks in the message loops of all threads.
    222   void FlushThreadMessageLoops() {
    223     BrowserThread::GetBlockingPool()->FlushForTesting();
    224     FlushMessageLoop(BrowserThread::IO);
    225     base::RunLoop().RunUntilIdle();
    226   }
    227 
    228   // Proxy for private method.
    229   static void GetCertificateWhitelistStrings(
    230       const net::X509Certificate& certificate,
    231       const net::X509Certificate& issuer,
    232       std::vector<std::string>* whitelist_strings) {
    233     DownloadProtectionService::GetCertificateWhitelistStrings(
    234         certificate, issuer, whitelist_strings);
    235   }
    236 
    237   // Reads a single PEM-encoded certificate from the testdata directory.
    238   // Returns NULL on failure.
    239   scoped_refptr<net::X509Certificate> ReadTestCertificate(
    240       const std::string& filename) {
    241     std::string cert_data;
    242     if (!file_util::ReadFileToString(testdata_path_.AppendASCII(filename),
    243                                      &cert_data)) {
    244       return NULL;
    245     }
    246     net::CertificateList certs =
    247         net::X509Certificate::CreateCertificateListFromBytes(
    248             cert_data.data(),
    249             cert_data.size(),
    250             net::X509Certificate::FORMAT_PEM_CERT_SEQUENCE);
    251     return certs.empty() ? NULL : certs[0];
    252   }
    253 
    254  private:
    255   // Helper functions for FlushThreadMessageLoops.
    256   void RunAllPendingAndQuitUI() {
    257     base::MessageLoop::current()->RunUntilIdle();
    258     BrowserThread::PostTask(
    259         BrowserThread::UI,
    260         FROM_HERE,
    261         base::Bind(&DownloadProtectionServiceTest::QuitMessageLoop,
    262                    base::Unretained(this)));
    263   }
    264 
    265   void QuitMessageLoop() {
    266     base::MessageLoop::current()->Quit();
    267   }
    268 
    269   void PostRunMessageLoopTask(BrowserThread::ID thread) {
    270     BrowserThread::PostTask(
    271         thread,
    272         FROM_HERE,
    273         base::Bind(&DownloadProtectionServiceTest::RunAllPendingAndQuitUI,
    274                    base::Unretained(this)));
    275   }
    276 
    277   void FlushMessageLoop(BrowserThread::ID thread) {
    278     BrowserThread::PostTask(
    279         BrowserThread::UI,
    280         FROM_HERE,
    281         base::Bind(&DownloadProtectionServiceTest::PostRunMessageLoopTask,
    282                    base::Unretained(this), thread));
    283     MessageLoop::current()->Run();
    284   }
    285 
    286  public:
    287   void CheckDoneCallback(
    288       DownloadProtectionService::DownloadCheckResult result) {
    289     result_ = result;
    290     has_result_ = true;
    291     MessageLoop::current()->Quit();
    292   }
    293 
    294   void SyncCheckDoneCallback(
    295       DownloadProtectionService::DownloadCheckResult result) {
    296     result_ = result;
    297     has_result_ = true;
    298   }
    299 
    300   void SendURLFetchComplete(net::TestURLFetcher* fetcher) {
    301     fetcher->delegate()->OnURLFetchComplete(fetcher);
    302   }
    303 
    304   testing::AssertionResult IsResult(
    305       DownloadProtectionService::DownloadCheckResult expected) {
    306     if (!has_result_)
    307       return testing::AssertionFailure() << "No result";
    308     has_result_ = false;
    309     return result_ == expected ?
    310         testing::AssertionSuccess() :
    311         testing::AssertionFailure() << "Expected " << expected <<
    312                                        ", got " << result_;
    313   }
    314 
    315  protected:
    316   scoped_refptr<FakeSafeBrowsingService> sb_service_;
    317   scoped_refptr<MockSignatureUtil> signature_util_;
    318   DownloadProtectionService* download_service_;
    319   DownloadProtectionService::DownloadCheckResult result_;
    320   bool has_result_;
    321   content::TestBrowserThreadBundle test_browser_thread_bundle_;
    322   base::FilePath testdata_path_;
    323 };
    324 
    325 TEST_F(DownloadProtectionServiceTest, CheckClientDownloadInvalidUrl) {
    326   base::FilePath a_tmp(FILE_PATH_LITERAL("a.tmp"));
    327   base::FilePath a_exe(FILE_PATH_LITERAL("a.exe"));
    328   std::vector<GURL> url_chain;
    329   GURL referrer("http://www.google.com/");
    330 
    331   content::MockDownloadItem item;
    332   EXPECT_CALL(item, AddObserver(_));
    333   EXPECT_CALL(item, RemoveObserver(_));
    334   EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp));
    335   EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_exe));
    336   EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
    337   EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
    338   download_service_->CheckClientDownload(
    339       &item,
    340       base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
    341                  base::Unretained(this)));
    342   MessageLoop::current()->Run();
    343   EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
    344   Mock::VerifyAndClearExpectations(&item);
    345 
    346   url_chain.push_back(GURL("file://www.google.com/"));
    347   EXPECT_CALL(item, AddObserver(_));
    348   EXPECT_CALL(item, RemoveObserver(_));
    349   EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp));
    350   EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_exe));
    351   EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
    352   EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
    353   download_service_->CheckClientDownload(
    354       &item,
    355       base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
    356                  base::Unretained(this)));
    357   MessageLoop::current()->Run();
    358   EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
    359 }
    360 
    361 TEST_F(DownloadProtectionServiceTest, CheckClientDownloadWhitelistedUrl) {
    362   base::FilePath a_tmp(FILE_PATH_LITERAL("a.tmp"));
    363   base::FilePath a_exe(FILE_PATH_LITERAL("a.exe"));
    364   std::vector<GURL> url_chain;
    365   url_chain.push_back(GURL("http://www.evil.com/bla.exe"));
    366   url_chain.push_back(GURL("http://www.google.com/a.exe"));
    367   GURL referrer("http://www.google.com/");
    368 
    369   content::MockDownloadItem item;
    370   EXPECT_CALL(item, AddObserver(_)).Times(2);
    371   EXPECT_CALL(item, RemoveObserver(_)).Times(2);
    372   EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp));
    373   EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_exe));
    374   EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
    375   EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
    376   EXPECT_CALL(*sb_service_->mock_database_manager(),
    377               MatchDownloadWhitelistUrl(_))
    378       .WillRepeatedly(Return(false));
    379   EXPECT_CALL(*sb_service_->mock_database_manager(),
    380               MatchDownloadWhitelistUrl(GURL("http://www.google.com/a.exe")))
    381       .WillRepeatedly(Return(true));
    382   EXPECT_CALL(*signature_util_.get(), CheckSignature(a_tmp, _)).Times(2);
    383 
    384   download_service_->CheckClientDownload(
    385       &item,
    386       base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
    387                  base::Unretained(this)));
    388   MessageLoop::current()->Run();
    389   EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
    390 
    391   // Check that the referrer is matched against the whitelist.
    392   url_chain.pop_back();
    393   referrer = GURL("http://www.google.com/a.exe");
    394   download_service_->CheckClientDownload(
    395       &item,
    396       base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
    397                  base::Unretained(this)));
    398   MessageLoop::current()->Run();
    399   EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
    400 }
    401 
    402 TEST_F(DownloadProtectionServiceTest, CheckClientDownloadFetchFailed) {
    403   net::FakeURLFetcherFactory factory(NULL);
    404   // HTTP request will fail.
    405   factory.SetFakeResponse(
    406       DownloadProtectionService::GetDownloadRequestUrl(), std::string(), false);
    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       true);
    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       true);
    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       true);
    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       true);
    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       true);
    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       true);
    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       true);
    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       true);
    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       true);
    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       true);
    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
   1180