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 // This test creates a safebrowsing service using test safebrowsing database
      6 // and a test protocol manager. It is used to test logics in safebrowsing
      7 // service.
      8 
      9 #include <algorithm>
     10 
     11 #include "base/bind.h"
     12 #include "base/command_line.h"
     13 #include "base/files/file_path.h"
     14 #include "base/files/scoped_temp_dir.h"
     15 #include "base/memory/ref_counted.h"
     16 #include "base/metrics/field_trial.h"
     17 #include "base/path_service.h"
     18 #include "base/prefs/pref_service.h"
     19 #include "base/strings/string_split.h"
     20 #include "base/test/thread_test_helper.h"
     21 #include "base/time/time.h"
     22 #include "chrome/browser/browser_process.h"
     23 #include "chrome/browser/chrome_notification_types.h"
     24 #include "chrome/browser/prerender/prerender_manager.h"
     25 #include "chrome/browser/profiles/profile.h"
     26 #include "chrome/browser/profiles/profile_manager.h"
     27 #include "chrome/browser/profiles/startup_task_runner_service.h"
     28 #include "chrome/browser/profiles/startup_task_runner_service_factory.h"
     29 #include "chrome/browser/safe_browsing/client_side_detection_service.h"
     30 #include "chrome/browser/safe_browsing/database_manager.h"
     31 #include "chrome/browser/safe_browsing/protocol_manager.h"
     32 #include "chrome/browser/safe_browsing/safe_browsing_database.h"
     33 #include "chrome/browser/safe_browsing/safe_browsing_service.h"
     34 #include "chrome/browser/safe_browsing/safe_browsing_util.h"
     35 #include "chrome/browser/safe_browsing/ui_manager.h"
     36 #include "chrome/browser/ui/browser.h"
     37 #include "chrome/browser/ui/tabs/tab_strip_model.h"
     38 #include "chrome/common/chrome_paths.h"
     39 #include "chrome/common/chrome_switches.h"
     40 #include "chrome/common/pref_names.h"
     41 #include "chrome/test/base/in_process_browser_test.h"
     42 #include "chrome/test/base/ui_test_utils.h"
     43 #include "content/public/browser/web_contents.h"
     44 #include "net/cookies/cookie_store.h"
     45 #include "sql/connection.h"
     46 #include "sql/statement.h"
     47 #include "testing/gmock/include/gmock/gmock.h"
     48 
     49 #if defined(OS_CHROMEOS)
     50 #include "chromeos/chromeos_switches.h"
     51 #endif
     52 
     53 using content::BrowserThread;
     54 using content::InterstitialPage;
     55 using content::WebContents;
     56 using ::testing::_;
     57 using ::testing::Mock;
     58 using ::testing::StrictMock;
     59 
     60 namespace {
     61 
     62 void InvokeFullHashCallback(
     63     SafeBrowsingProtocolManager::FullHashCallback callback,
     64     const std::vector<SBFullHashResult>& result) {
     65   callback.Run(result, base::TimeDelta::FromMinutes(45));
     66 }
     67 
     68 class FakeSafeBrowsingService : public SafeBrowsingService {
     69  public:
     70   explicit FakeSafeBrowsingService(const std::string& url_prefix)
     71       : url_prefix_(url_prefix) {}
     72 
     73   virtual SafeBrowsingProtocolConfig GetProtocolConfig() const OVERRIDE {
     74     SafeBrowsingProtocolConfig config;
     75     config.url_prefix = url_prefix_;
     76     // Makes sure the auto update is not triggered. The tests will force the
     77     // update when needed.
     78     config.disable_auto_update = true;
     79     config.client_name = "browser_tests";
     80     return config;
     81   }
     82 
     83  private:
     84   virtual ~FakeSafeBrowsingService() {}
     85 
     86   std::string url_prefix_;
     87 
     88   DISALLOW_COPY_AND_ASSIGN(FakeSafeBrowsingService);
     89 };
     90 
     91 // Factory that creates FakeSafeBrowsingService instances.
     92 class TestSafeBrowsingServiceFactory : public SafeBrowsingServiceFactory {
     93  public:
     94   explicit TestSafeBrowsingServiceFactory(const std::string& url_prefix)
     95       : url_prefix_(url_prefix) {}
     96 
     97   virtual SafeBrowsingService* CreateSafeBrowsingService() OVERRIDE {
     98     return new FakeSafeBrowsingService(url_prefix_);
     99   }
    100 
    101  private:
    102   std::string url_prefix_;
    103 };
    104 
    105 // A SafeBrowingDatabase class that allows us to inject the malicious URLs.
    106 class TestSafeBrowsingDatabase :  public SafeBrowsingDatabase {
    107  public:
    108   TestSafeBrowsingDatabase() {}
    109 
    110   virtual ~TestSafeBrowsingDatabase() {}
    111 
    112   // Initializes the database with the given filename.
    113   virtual void Init(const base::FilePath& filename) OVERRIDE {}
    114 
    115   // Deletes the current database and creates a new one.
    116   virtual bool ResetDatabase() OVERRIDE {
    117     badurls_.clear();
    118     return true;
    119   }
    120 
    121   // Called on the IO thread to check if the given URL is safe or not.  If we
    122   // can synchronously determine that the URL is safe, CheckUrl returns true,
    123   // otherwise it returns false.
    124   virtual bool ContainsBrowseUrl(
    125       const GURL& url,
    126       std::vector<SBPrefix>* prefix_hits,
    127       std::vector<SBFullHashResult>* cache_hits) OVERRIDE {
    128     cache_hits->clear();
    129     return ContainsUrl(safe_browsing_util::MALWARE,
    130                        safe_browsing_util::PHISH,
    131                        std::vector<GURL>(1, url),
    132                        prefix_hits);
    133   }
    134   virtual bool ContainsDownloadUrl(
    135       const std::vector<GURL>& urls,
    136       std::vector<SBPrefix>* prefix_hits) OVERRIDE {
    137     bool found = ContainsUrl(safe_browsing_util::BINURL,
    138                              safe_browsing_util::BINURL,
    139                              urls,
    140                              prefix_hits);
    141     if (!found)
    142       return false;
    143     DCHECK_LE(1U, prefix_hits->size());
    144     return true;
    145   }
    146   virtual bool ContainsCsdWhitelistedUrl(const GURL& url) OVERRIDE {
    147     return true;
    148   }
    149   virtual bool ContainsDownloadWhitelistedString(
    150       const std::string& str) OVERRIDE {
    151     return true;
    152   }
    153   virtual bool ContainsDownloadWhitelistedUrl(const GURL& url) OVERRIDE {
    154     return true;
    155   }
    156   virtual bool ContainsExtensionPrefixes(
    157       const std::vector<SBPrefix>& prefixes,
    158       std::vector<SBPrefix>* prefix_hits) OVERRIDE {
    159     return true;
    160   }
    161   virtual bool ContainsSideEffectFreeWhitelistUrl(const GURL& url) OVERRIDE {
    162     return true;
    163   }
    164   virtual bool ContainsMalwareIP(const std::string& ip_address) OVERRIDE {
    165     return true;
    166   }
    167   virtual bool UpdateStarted(std::vector<SBListChunkRanges>* lists) OVERRIDE {
    168     ADD_FAILURE() << "Not implemented.";
    169     return false;
    170   }
    171   virtual void InsertChunks(
    172       const std::string& list_name,
    173       const std::vector<SBChunkData*>& chunks) OVERRIDE {
    174     ADD_FAILURE() << "Not implemented.";
    175   }
    176   virtual void DeleteChunks(
    177       const std::vector<SBChunkDelete>& chunk_deletes) OVERRIDE {
    178     ADD_FAILURE() << "Not implemented.";
    179   }
    180   virtual void UpdateFinished(bool update_succeeded) OVERRIDE {
    181     ADD_FAILURE() << "Not implemented.";
    182   }
    183   virtual void CacheHashResults(
    184       const std::vector<SBPrefix>& prefixes,
    185       const std::vector<SBFullHashResult>& cache_hits,
    186       const base::TimeDelta& cache_lifetime) OVERRIDE {
    187     // Do nothing for the cache.
    188   }
    189   virtual bool IsMalwareIPMatchKillSwitchOn() OVERRIDE {
    190     return false;
    191   }
    192   virtual bool IsCsdWhitelistKillSwitchOn() OVERRIDE {
    193     return false;
    194   }
    195 
    196   // Fill up the database with test URL.
    197   void AddUrl(const GURL& url,
    198               int list_id,
    199               const std::vector<SBPrefix>& prefix_hits) {
    200     badurls_[url.spec()].list_id = list_id;
    201     badurls_[url.spec()].prefix_hits = prefix_hits;
    202   }
    203 
    204   // Fill up the database with test hash digest.
    205   void AddDownloadPrefix(SBPrefix prefix) {
    206     download_digest_prefix_.insert(prefix);
    207   }
    208 
    209  private:
    210   struct Hits {
    211     int list_id;
    212     std::vector<SBPrefix> prefix_hits;
    213   };
    214 
    215   bool ContainsUrl(int list_id0,
    216                    int list_id1,
    217                    const std::vector<GURL>& urls,
    218                    std::vector<SBPrefix>* prefix_hits) {
    219     bool hit = false;
    220     for (size_t i = 0; i < urls.size(); ++i) {
    221       const GURL& url = urls[i];
    222       base::hash_map<std::string, Hits>::const_iterator
    223           badurls_it = badurls_.find(url.spec());
    224 
    225       if (badurls_it == badurls_.end())
    226         continue;
    227 
    228       if (badurls_it->second.list_id == list_id0 ||
    229           badurls_it->second.list_id == list_id1) {
    230         prefix_hits->insert(prefix_hits->end(),
    231                             badurls_it->second.prefix_hits.begin(),
    232                             badurls_it->second.prefix_hits.end());
    233         hit = true;
    234       }
    235     }
    236     return hit;
    237   }
    238 
    239   base::hash_map<std::string, Hits> badurls_;
    240   base::hash_set<SBPrefix> download_digest_prefix_;
    241 };
    242 
    243 // Factory that creates TestSafeBrowsingDatabase instances.
    244 class TestSafeBrowsingDatabaseFactory : public SafeBrowsingDatabaseFactory {
    245  public:
    246   TestSafeBrowsingDatabaseFactory() : db_(NULL) {}
    247   virtual ~TestSafeBrowsingDatabaseFactory() {}
    248 
    249   virtual SafeBrowsingDatabase* CreateSafeBrowsingDatabase(
    250       bool enable_download_protection,
    251       bool enable_client_side_whitelist,
    252       bool enable_download_whitelist,
    253       bool enable_extension_blacklist,
    254       bool enable_side_effect_free_whitelist,
    255       bool enable_ip_blacklist) OVERRIDE {
    256     db_ = new TestSafeBrowsingDatabase();
    257     return db_;
    258   }
    259   TestSafeBrowsingDatabase* GetDb() {
    260     return db_;
    261   }
    262  private:
    263   // Owned by the SafebrowsingService.
    264   TestSafeBrowsingDatabase* db_;
    265 };
    266 
    267 // A TestProtocolManager that could return fixed responses from
    268 // safebrowsing server for testing purpose.
    269 class TestProtocolManager :  public SafeBrowsingProtocolManager {
    270  public:
    271   TestProtocolManager(SafeBrowsingProtocolManagerDelegate* delegate,
    272                       net::URLRequestContextGetter* request_context_getter,
    273                       const SafeBrowsingProtocolConfig& config)
    274       : SafeBrowsingProtocolManager(delegate, request_context_getter, config) {
    275     create_count_++;
    276   }
    277 
    278   virtual ~TestProtocolManager() {
    279     delete_count_++;
    280   }
    281 
    282   // This function is called when there is a prefix hit in local safebrowsing
    283   // database and safebrowsing service issues a get hash request to backends.
    284   // We return a result from the prefilled full_hashes_ hash_map to simulate
    285   // server's response. At the same time, latency is added to simulate real
    286   // life network issues.
    287   virtual void GetFullHash(
    288       const std::vector<SBPrefix>& prefixes,
    289       SafeBrowsingProtocolManager::FullHashCallback callback,
    290       bool is_download) OVERRIDE {
    291     BrowserThread::PostDelayedTask(
    292         BrowserThread::IO, FROM_HERE,
    293         base::Bind(InvokeFullHashCallback, callback, full_hashes_),
    294         delay_);
    295   }
    296 
    297   // Prepare the GetFullHash results for the next request.
    298   void SetGetFullHashResponse(const SBFullHashResult& full_hash_result) {
    299     full_hashes_.clear();
    300     full_hashes_.push_back(full_hash_result);
    301   }
    302 
    303   void IntroduceDelay(const base::TimeDelta& delay) {
    304     delay_ = delay;
    305   }
    306 
    307   static int create_count() {
    308     return create_count_;
    309   }
    310 
    311   static int delete_count() {
    312     return delete_count_;
    313   }
    314 
    315  private:
    316   std::vector<SBFullHashResult> full_hashes_;
    317   base::TimeDelta delay_;
    318   static int create_count_;
    319   static int delete_count_;
    320 };
    321 
    322 // static
    323 int TestProtocolManager::create_count_ = 0;
    324 // static
    325 int TestProtocolManager::delete_count_ = 0;
    326 
    327 // Factory that creates TestProtocolManager instances.
    328 class TestSBProtocolManagerFactory : public SBProtocolManagerFactory {
    329  public:
    330   TestSBProtocolManagerFactory() : pm_(NULL) {}
    331   virtual ~TestSBProtocolManagerFactory() {}
    332 
    333   virtual SafeBrowsingProtocolManager* CreateProtocolManager(
    334       SafeBrowsingProtocolManagerDelegate* delegate,
    335       net::URLRequestContextGetter* request_context_getter,
    336       const SafeBrowsingProtocolConfig& config) OVERRIDE {
    337     pm_ = new TestProtocolManager(delegate, request_context_getter, config);
    338     return pm_;
    339   }
    340 
    341   TestProtocolManager* GetProtocolManager() {
    342     return pm_;
    343   }
    344 
    345  private:
    346   // Owned by the SafebrowsingService.
    347   TestProtocolManager* pm_;
    348 };
    349 
    350 class MockObserver : public SafeBrowsingUIManager::Observer {
    351  public:
    352   MockObserver() {}
    353   virtual ~MockObserver() {}
    354   MOCK_METHOD1(OnSafeBrowsingHit,
    355                void(const SafeBrowsingUIManager::UnsafeResource&));
    356   MOCK_METHOD1(OnSafeBrowsingMatch,
    357                void(const SafeBrowsingUIManager::UnsafeResource&));
    358 };
    359 
    360 MATCHER_P(IsUnsafeResourceFor, url, "") {
    361   return (arg.url.spec() == url.spec() &&
    362           arg.threat_type != SB_THREAT_TYPE_SAFE);
    363 }
    364 
    365 }  // namespace
    366 
    367 // Tests the safe browsing blocking page in a browser.
    368 class SafeBrowsingServiceTest : public InProcessBrowserTest {
    369  public:
    370   SafeBrowsingServiceTest() {
    371   }
    372 
    373   static void GenUrlFullhashResult(const GURL& url,
    374                                    int list_id,
    375                                    SBFullHashResult* full_hash) {
    376     std::string host;
    377     std::string path;
    378     safe_browsing_util::CanonicalizeUrl(url, &host, &path, NULL);
    379     full_hash->hash = SBFullHashForString(host + path);
    380     full_hash->list_id = list_id;
    381   }
    382 
    383   virtual void SetUp() {
    384     // InProcessBrowserTest::SetUp() instantiates SafebrowsingService and
    385     // RegisterFactory has to be called before SafeBrowsingService is created.
    386     sb_factory_.reset(new TestSafeBrowsingServiceFactory(
    387         "https://definatelynotarealdomain/safebrowsing"));
    388     SafeBrowsingService::RegisterFactory(sb_factory_.get());
    389     SafeBrowsingDatabase::RegisterFactory(&db_factory_);
    390     SafeBrowsingProtocolManager::RegisterFactory(&pm_factory_);
    391     InProcessBrowserTest::SetUp();
    392   }
    393 
    394   virtual void TearDown() {
    395     InProcessBrowserTest::TearDown();
    396 
    397     // Unregister test factories after InProcessBrowserTest::TearDown
    398     // (which destructs SafeBrowsingService).
    399     SafeBrowsingDatabase::RegisterFactory(NULL);
    400     SafeBrowsingProtocolManager::RegisterFactory(NULL);
    401     SafeBrowsingService::RegisterFactory(NULL);
    402   }
    403 
    404   virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
    405     // Makes sure the auto update is not triggered during the test.
    406     // This test will fill up the database using testing prefixes
    407     // and urls.
    408     command_line->AppendSwitch(switches::kSbDisableAutoUpdate);
    409 #if defined(OS_CHROMEOS)
    410     command_line->AppendSwitch(
    411         chromeos::switches::kIgnoreUserProfileMappingForTests);
    412 #endif
    413   }
    414 
    415   virtual void SetUpInProcessBrowserTestFixture() {
    416     ASSERT_TRUE(test_server()->Start());
    417   }
    418 
    419   // This will setup the "url" prefix in database and prepare protocol manager
    420   // to response with |full_hash| for get full hash request.
    421   void SetupResponseForUrl(const GURL& url, const SBFullHashResult& full_hash) {
    422     std::vector<SBPrefix> prefix_hits;
    423     prefix_hits.push_back(full_hash.hash.prefix);
    424 
    425     // Make sure the full hits is empty unless we need to test the
    426     // full hash is hit in database's local cache.
    427     TestSafeBrowsingDatabase* db = db_factory_.GetDb();
    428     db->AddUrl(url, full_hash.list_id, prefix_hits);
    429 
    430     TestProtocolManager* pm = pm_factory_.GetProtocolManager();
    431     pm->SetGetFullHashResponse(full_hash);
    432   }
    433 
    434   bool ShowingInterstitialPage() {
    435     WebContents* contents =
    436         browser()->tab_strip_model()->GetActiveWebContents();
    437     InterstitialPage* interstitial_page = contents->GetInterstitialPage();
    438     return interstitial_page != NULL;
    439   }
    440 
    441   void IntroduceGetHashDelay(const base::TimeDelta& delay) {
    442     pm_factory_.GetProtocolManager()->IntroduceDelay(delay);
    443   }
    444 
    445   base::TimeDelta GetCheckTimeout(SafeBrowsingService* sb_service) {
    446     return sb_service->database_manager()->check_timeout_;
    447   }
    448 
    449   void SetCheckTimeout(SafeBrowsingService* sb_service,
    450                        const base::TimeDelta& delay) {
    451     sb_service->database_manager()->check_timeout_ = delay;
    452   }
    453 
    454   void CreateCSDService() {
    455     safe_browsing::ClientSideDetectionService* csd_service =
    456         safe_browsing::ClientSideDetectionService::Create(NULL);
    457     SafeBrowsingService* sb_service =
    458         g_browser_process->safe_browsing_service();
    459     sb_service->csd_service_.reset(csd_service);
    460     sb_service->RefreshState();
    461   }
    462 
    463   void ProceedAndWhitelist(
    464       const SafeBrowsingUIManager::UnsafeResource& resource) {
    465     std::vector<SafeBrowsingUIManager::UnsafeResource> resources;
    466     resources.push_back(resource);
    467     BrowserThread::PostTask(
    468         BrowserThread::IO, FROM_HERE,
    469         base::Bind(&SafeBrowsingUIManager::OnBlockingPageDone,
    470                    g_browser_process->safe_browsing_service()->ui_manager(),
    471                    resources, true));
    472     WaitForIOThread();
    473   }
    474 
    475  protected:
    476   StrictMock<MockObserver> observer_;
    477 
    478   // Temporary profile dir for test cases that create a second profile.  This is
    479   // owned by the SafeBrowsingServiceTest object so that it will not get
    480   // destructed until after the test Browser has been torn down, since the
    481   // ImportantFileWriter may still be modifying it after the Profile object has
    482   // been destroyed.
    483   base::ScopedTempDir temp_profile_dir_;
    484 
    485   // Waits for pending tasks on the IO thread to complete. This is useful
    486   // to wait for the SafeBrowsingService to finish loading/stopping.
    487   void WaitForIOThread() {
    488     scoped_refptr<base::ThreadTestHelper> io_helper(new base::ThreadTestHelper(
    489         BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO).get()));
    490     ASSERT_TRUE(io_helper->Run());
    491   }
    492 
    493  private:
    494   scoped_ptr<TestSafeBrowsingServiceFactory> sb_factory_;
    495   TestSafeBrowsingDatabaseFactory db_factory_;
    496   TestSBProtocolManagerFactory pm_factory_;
    497 
    498   DISALLOW_COPY_AND_ASSIGN(SafeBrowsingServiceTest);
    499 };
    500 
    501 namespace {
    502 
    503 const char kEmptyPage[] = "files/empty.html";
    504 const char kMalwareFile[] = "files/downloads/dangerous/dangerous.exe";
    505 const char kMalwarePage[] = "files/safe_browsing/malware.html";
    506 
    507 // This test goes through DownloadResourceHandler.
    508 IN_PROC_BROWSER_TEST_F(SafeBrowsingServiceTest, Malware) {
    509   GURL url = test_server()->GetURL(kEmptyPage);
    510   g_browser_process->safe_browsing_service()->
    511       ui_manager()->AddObserver(&observer_);
    512 
    513   // After adding the url to safebrowsing database and getfullhash result,
    514   // we should see the interstitial page.
    515   SBFullHashResult malware_full_hash;
    516   GenUrlFullhashResult(url, safe_browsing_util::MALWARE, &malware_full_hash);
    517   EXPECT_CALL(observer_,
    518               OnSafeBrowsingMatch(IsUnsafeResourceFor(url))).Times(1);
    519   EXPECT_CALL(observer_, OnSafeBrowsingHit(IsUnsafeResourceFor(url))).Times(1);
    520   SetupResponseForUrl(url, malware_full_hash);
    521   ui_test_utils::NavigateToURL(browser(), url);
    522   EXPECT_TRUE(ShowingInterstitialPage());
    523   g_browser_process->safe_browsing_service()->
    524       ui_manager()->RemoveObserver(&observer_);
    525 }
    526 
    527 IN_PROC_BROWSER_TEST_F(SafeBrowsingServiceTest, DISABLED_MalwareWithWhitelist) {
    528   GURL url = test_server()->GetURL(kEmptyPage);
    529   g_browser_process->safe_browsing_service()->
    530       ui_manager()->AddObserver(&observer_);
    531 
    532   // After adding the url to safebrowsing database and getfullhash result,
    533   // we should see the interstitial page.
    534   SBFullHashResult malware_full_hash;
    535   GenUrlFullhashResult(url, safe_browsing_util::MALWARE, &malware_full_hash);
    536   EXPECT_CALL(observer_,
    537               OnSafeBrowsingMatch(IsUnsafeResourceFor(url))).Times(1);
    538   EXPECT_CALL(observer_, OnSafeBrowsingHit(IsUnsafeResourceFor(url))).Times(1)
    539       .WillOnce(testing::Invoke(
    540           this, &SafeBrowsingServiceTest::ProceedAndWhitelist));
    541   SetupResponseForUrl(url, malware_full_hash);
    542 
    543   ui_test_utils::NavigateToURL(browser(), url);
    544   // Mock calls OnBlockingPageDone set to proceed, so the interstitial
    545   // is removed.
    546   EXPECT_FALSE(ShowingInterstitialPage());
    547   Mock::VerifyAndClearExpectations(&observer_);
    548 
    549   // Navigate back to kEmptyPage -- should hit the whitelist, and send a match
    550   // call, but no hit call.
    551   EXPECT_CALL(observer_,
    552               OnSafeBrowsingMatch(IsUnsafeResourceFor(url))).Times(1);
    553   EXPECT_CALL(observer_, OnSafeBrowsingHit(IsUnsafeResourceFor(url))).Times(0);
    554   ui_test_utils::NavigateToURL(browser(), url);
    555   EXPECT_FALSE(ShowingInterstitialPage());
    556 
    557   g_browser_process->safe_browsing_service()->
    558       ui_manager()->RemoveObserver(&observer_);
    559 }
    560 
    561 const char kPrefetchMalwarePage[] = "files/safe_browsing/prefetch_malware.html";
    562 
    563 // This test confirms that prefetches don't themselves get the
    564 // interstitial treatment.
    565 IN_PROC_BROWSER_TEST_F(SafeBrowsingServiceTest, Prefetch) {
    566   GURL url = test_server()->GetURL(kPrefetchMalwarePage);
    567   GURL malware_url = test_server()->GetURL(kMalwarePage);
    568   g_browser_process->safe_browsing_service()->
    569       ui_manager()->AddObserver(&observer_);
    570 
    571   class SetPrefetchForTest {
    572    public:
    573     explicit SetPrefetchForTest(bool prefetch)
    574         : old_prerender_mode_(prerender::PrerenderManager::GetMode()) {
    575       std::string exp_group = prefetch ? "ExperimentYes" : "ExperimentNo";
    576       base::FieldTrialList::CreateFieldTrial("Prefetch", exp_group);
    577 
    578       prerender::PrerenderManager::SetMode(
    579           prerender::PrerenderManager::PRERENDER_MODE_DISABLED);
    580     }
    581 
    582     ~SetPrefetchForTest() {
    583       prerender::PrerenderManager::SetMode(old_prerender_mode_);
    584     }
    585 
    586    private:
    587     prerender::PrerenderManager::PrerenderManagerMode old_prerender_mode_;
    588   } set_prefetch_for_test(true);
    589 
    590   // Even though we have added this uri to the safebrowsing database and
    591   // getfullhash result, we should not see the interstitial page since the
    592   // only malware was a prefetch target.
    593   SBFullHashResult malware_full_hash;
    594   GenUrlFullhashResult(malware_url, safe_browsing_util::MALWARE,
    595                        &malware_full_hash);
    596   SetupResponseForUrl(malware_url, malware_full_hash);
    597   ui_test_utils::NavigateToURL(browser(), url);
    598   EXPECT_FALSE(ShowingInterstitialPage());
    599   Mock::VerifyAndClear(&observer_);
    600 
    601   // However, when we navigate to the malware page, we should still get
    602   // the interstitial.
    603   EXPECT_CALL(observer_, OnSafeBrowsingMatch(IsUnsafeResourceFor(malware_url)))
    604       .Times(1);
    605   EXPECT_CALL(observer_, OnSafeBrowsingHit(IsUnsafeResourceFor(malware_url)))
    606       .Times(1);
    607   ui_test_utils::NavigateToURL(browser(), malware_url);
    608   EXPECT_TRUE(ShowingInterstitialPage());
    609   Mock::VerifyAndClear(&observer_);
    610   g_browser_process->safe_browsing_service()->
    611       ui_manager()->RemoveObserver(&observer_);
    612 }
    613 
    614 }  // namespace
    615 
    616 class TestSBClient
    617     : public base::RefCountedThreadSafe<TestSBClient>,
    618       public SafeBrowsingDatabaseManager::Client {
    619  public:
    620   TestSBClient()
    621     : threat_type_(SB_THREAT_TYPE_SAFE),
    622       safe_browsing_service_(g_browser_process->safe_browsing_service()) {
    623   }
    624 
    625   SBThreatType GetThreatType() const {
    626     return threat_type_;
    627   }
    628 
    629   void CheckDownloadUrl(const std::vector<GURL>& url_chain) {
    630     BrowserThread::PostTask(
    631         BrowserThread::IO, FROM_HERE,
    632         base::Bind(&TestSBClient::CheckDownloadUrlOnIOThread,
    633                    this, url_chain));
    634     content::RunMessageLoop();  // Will stop in OnCheckDownloadUrlResult.
    635   }
    636 
    637  private:
    638   friend class base::RefCountedThreadSafe<TestSBClient>;
    639   virtual ~TestSBClient() {}
    640 
    641   void CheckDownloadUrlOnIOThread(const std::vector<GURL>& url_chain) {
    642     safe_browsing_service_->database_manager()->
    643         CheckDownloadUrl(url_chain, this);
    644   }
    645 
    646   // Called when the result of checking a download URL is known.
    647   virtual void OnCheckDownloadUrlResult(const std::vector<GURL>& url_chain,
    648                                         SBThreatType threat_type) OVERRIDE {
    649     threat_type_ = threat_type;
    650     BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
    651                             base::Bind(&TestSBClient::DownloadCheckDone, this));
    652   }
    653 
    654   void DownloadCheckDone() {
    655     base::MessageLoopForUI::current()->Quit();
    656   }
    657 
    658   SBThreatType threat_type_;
    659   SafeBrowsingService* safe_browsing_service_;
    660 
    661   DISALLOW_COPY_AND_ASSIGN(TestSBClient);
    662 };
    663 
    664 // These tests use SafeBrowsingService::Client to directly interact with
    665 // SafeBrowsingService.
    666 namespace {
    667 
    668 IN_PROC_BROWSER_TEST_F(SafeBrowsingServiceTest, CheckDownloadUrl) {
    669   GURL badbin_url = test_server()->GetURL(kMalwareFile);
    670   std::vector<GURL> badbin_urls(1, badbin_url);
    671 
    672   scoped_refptr<TestSBClient> client(new TestSBClient);
    673   client->CheckDownloadUrl(badbin_urls);
    674 
    675   // Since badbin_url is not in database, it is considered to be safe.
    676   EXPECT_EQ(SB_THREAT_TYPE_SAFE, client->GetThreatType());
    677 
    678   SBFullHashResult full_hash_result;
    679   GenUrlFullhashResult(badbin_url, safe_browsing_util::BINURL,
    680                        &full_hash_result);
    681   SetupResponseForUrl(badbin_url, full_hash_result);
    682 
    683   client->CheckDownloadUrl(badbin_urls);
    684 
    685   // Now, the badbin_url is not safe since it is added to download database.
    686   EXPECT_EQ(SB_THREAT_TYPE_BINARY_MALWARE_URL, client->GetThreatType());
    687 }
    688 
    689 IN_PROC_BROWSER_TEST_F(SafeBrowsingServiceTest, CheckDownloadUrlRedirects) {
    690   GURL original_url = test_server()->GetURL(kEmptyPage);
    691   GURL badbin_url = test_server()->GetURL(kMalwareFile);
    692   GURL final_url = test_server()->GetURL(kEmptyPage);
    693   std::vector<GURL> badbin_urls;
    694   badbin_urls.push_back(original_url);
    695   badbin_urls.push_back(badbin_url);
    696   badbin_urls.push_back(final_url);
    697 
    698   scoped_refptr<TestSBClient> client(new TestSBClient);
    699   client->CheckDownloadUrl(badbin_urls);
    700 
    701   // Since badbin_url is not in database, it is considered to be safe.
    702   EXPECT_EQ(SB_THREAT_TYPE_SAFE, client->GetThreatType());
    703 
    704   SBFullHashResult full_hash_result;
    705   GenUrlFullhashResult(badbin_url, safe_browsing_util::BINURL,
    706                        &full_hash_result);
    707   SetupResponseForUrl(badbin_url, full_hash_result);
    708 
    709   client->CheckDownloadUrl(badbin_urls);
    710 
    711   // Now, the badbin_url is not safe since it is added to download database.
    712   EXPECT_EQ(SB_THREAT_TYPE_BINARY_MALWARE_URL, client->GetThreatType());
    713 }
    714 
    715 IN_PROC_BROWSER_TEST_F(SafeBrowsingServiceTest, CheckDownloadUrlTimedOut) {
    716   GURL badbin_url = test_server()->GetURL(kMalwareFile);
    717   std::vector<GURL> badbin_urls(1, badbin_url);
    718 
    719   scoped_refptr<TestSBClient> client(new TestSBClient);
    720   SBFullHashResult full_hash_result;
    721   GenUrlFullhashResult(badbin_url, safe_browsing_util::BINURL,
    722                        &full_hash_result);
    723   SetupResponseForUrl(badbin_url, full_hash_result);
    724   client->CheckDownloadUrl(badbin_urls);
    725 
    726   // badbin_url is not safe since it is added to download database.
    727   EXPECT_EQ(SB_THREAT_TYPE_BINARY_MALWARE_URL, client->GetThreatType());
    728 
    729   //
    730   // Now introducing delays and we should hit timeout.
    731   //
    732   SafeBrowsingService* sb_service = g_browser_process->safe_browsing_service();
    733   base::TimeDelta default_urlcheck_timeout = GetCheckTimeout(sb_service);
    734   IntroduceGetHashDelay(base::TimeDelta::FromSeconds(1));
    735   SetCheckTimeout(sb_service, base::TimeDelta::FromMilliseconds(1));
    736   client->CheckDownloadUrl(badbin_urls);
    737 
    738   // There should be a timeout and the hash would be considered as safe.
    739   EXPECT_EQ(SB_THREAT_TYPE_SAFE, client->GetThreatType());
    740 
    741   // Need to set the timeout back to the default value.
    742   SetCheckTimeout(sb_service, default_urlcheck_timeout);
    743 }
    744 
    745 IN_PROC_BROWSER_TEST_F(SafeBrowsingServiceTest, StartAndStop) {
    746   CreateCSDService();
    747   SafeBrowsingService* sb_service = g_browser_process->safe_browsing_service();
    748   safe_browsing::ClientSideDetectionService* csd_service =
    749       sb_service->safe_browsing_detection_service();
    750   PrefService* pref_service = browser()->profile()->GetPrefs();
    751 
    752   ASSERT_TRUE(sb_service != NULL);
    753   ASSERT_TRUE(csd_service != NULL);
    754   ASSERT_TRUE(pref_service != NULL);
    755 
    756   EXPECT_TRUE(pref_service->GetBoolean(prefs::kSafeBrowsingEnabled));
    757 
    758   // SBS might still be starting, make sure this doesn't flake.
    759   WaitForIOThread();
    760   EXPECT_TRUE(sb_service->enabled());
    761   EXPECT_TRUE(csd_service->enabled());
    762 
    763   // Add a new Profile. SBS should keep running.
    764   ASSERT_TRUE(temp_profile_dir_.CreateUniqueTempDir());
    765   scoped_ptr<Profile> profile2(Profile::CreateProfile(
    766       temp_profile_dir_.path(), NULL, Profile::CREATE_MODE_SYNCHRONOUS));
    767   ASSERT_TRUE(profile2.get() != NULL);
    768   StartupTaskRunnerServiceFactory::GetForProfile(profile2.get())->
    769               StartDeferredTaskRunners();
    770   PrefService* pref_service2 = profile2->GetPrefs();
    771   EXPECT_TRUE(pref_service2->GetBoolean(prefs::kSafeBrowsingEnabled));
    772   // We don't expect the state to have changed, but if it did, wait for it.
    773   WaitForIOThread();
    774   EXPECT_TRUE(sb_service->enabled());
    775   EXPECT_TRUE(csd_service->enabled());
    776 
    777   // Change one of the prefs. SBS should keep running.
    778   pref_service->SetBoolean(prefs::kSafeBrowsingEnabled, false);
    779   WaitForIOThread();
    780   EXPECT_TRUE(sb_service->enabled());
    781   EXPECT_TRUE(csd_service->enabled());
    782 
    783   // Change the other pref. SBS should stop now.
    784   pref_service2->SetBoolean(prefs::kSafeBrowsingEnabled, false);
    785   WaitForIOThread();
    786   EXPECT_FALSE(sb_service->enabled());
    787   EXPECT_FALSE(csd_service->enabled());
    788 
    789   // Turn it back on. SBS comes back.
    790   pref_service2->SetBoolean(prefs::kSafeBrowsingEnabled, true);
    791   WaitForIOThread();
    792   EXPECT_TRUE(sb_service->enabled());
    793   EXPECT_TRUE(csd_service->enabled());
    794 
    795   // Delete the Profile. SBS stops again.
    796   pref_service2 = NULL;
    797   profile2.reset();
    798   WaitForIOThread();
    799   EXPECT_FALSE(sb_service->enabled());
    800   EXPECT_FALSE(csd_service->enabled());
    801 }
    802 
    803 }  // namespace
    804 
    805 class SafeBrowsingServiceShutdownTest : public SafeBrowsingServiceTest {
    806  public:
    807   virtual void TearDown() OVERRIDE {
    808     // Browser should be fully torn down by now, so we can safely check these
    809     // counters.
    810     EXPECT_EQ(1, TestProtocolManager::create_count());
    811     EXPECT_EQ(1, TestProtocolManager::delete_count());
    812 
    813     SafeBrowsingServiceTest::TearDown();
    814   }
    815 
    816   // An observer that returns back to test code after a new profile is
    817   // initialized.
    818   void OnUnblockOnProfileCreation(Profile* profile,
    819                                   Profile::CreateStatus status) {
    820     if (status == Profile::CREATE_STATUS_INITIALIZED) {
    821       profile2_ = profile;
    822       base::MessageLoop::current()->Quit();
    823     }
    824   }
    825 
    826  protected:
    827   Profile* profile2_;
    828 };
    829 
    830 IN_PROC_BROWSER_TEST_F(SafeBrowsingServiceShutdownTest,
    831                        DontStartAfterShutdown) {
    832   CreateCSDService();
    833   SafeBrowsingService* sb_service = g_browser_process->safe_browsing_service();
    834   safe_browsing::ClientSideDetectionService* csd_service =
    835       sb_service->safe_browsing_detection_service();
    836   PrefService* pref_service = browser()->profile()->GetPrefs();
    837 
    838   ASSERT_TRUE(sb_service != NULL);
    839   ASSERT_TRUE(csd_service != NULL);
    840   ASSERT_TRUE(pref_service != NULL);
    841 
    842   EXPECT_TRUE(pref_service->GetBoolean(prefs::kSafeBrowsingEnabled));
    843 
    844   // SBS might still be starting, make sure this doesn't flake.
    845   WaitForIOThread();
    846   EXPECT_EQ(1, TestProtocolManager::create_count());
    847   EXPECT_EQ(0, TestProtocolManager::delete_count());
    848 
    849   // Create an additional profile.  We need to use the ProfileManager so that
    850   // the profile will get destroyed in the normal browser shutdown process.
    851   ProfileManager* profile_manager = g_browser_process->profile_manager();
    852   ASSERT_TRUE(temp_profile_dir_.CreateUniqueTempDir());
    853   profile_manager->CreateProfileAsync(
    854       temp_profile_dir_.path(),
    855       base::Bind(&SafeBrowsingServiceShutdownTest::OnUnblockOnProfileCreation,
    856                  this),
    857       base::string16(), base::string16(), std::string());
    858 
    859   // Spin to allow profile creation to take place, loop is terminated
    860   // by OnUnblockOnProfileCreation when the profile is created.
    861   content::RunMessageLoop();
    862 
    863   PrefService* pref_service2 = profile2_->GetPrefs();
    864   EXPECT_TRUE(pref_service2->GetBoolean(prefs::kSafeBrowsingEnabled));
    865 
    866   // We don't expect the state to have changed, but if it did, wait for it.
    867   WaitForIOThread();
    868   EXPECT_EQ(1, TestProtocolManager::create_count());
    869   EXPECT_EQ(0, TestProtocolManager::delete_count());
    870 
    871   // End the test, shutting down the browser.
    872   // SafeBrowsingServiceShutdownTest::TearDown will check the create_count and
    873   // delete_count again.
    874 }
    875 
    876 class SafeBrowsingDatabaseManagerCookieTest : public InProcessBrowserTest {
    877  public:
    878   SafeBrowsingDatabaseManagerCookieTest() {}
    879 
    880   virtual void SetUp() OVERRIDE {
    881     // We need to start the test server to get the host&port in the url.
    882     ASSERT_TRUE(test_server()->Start());
    883 
    884     // Point to the testing server for all SafeBrowsing requests.
    885     GURL url_prefix = test_server()->GetURL(
    886         "expect-and-set-cookie?expect=a%3db"
    887         "&set=c%3dd%3b%20Expires=Fri,%2001%20Jan%202038%2001:01:01%20GMT"
    888         "&data=foo#");
    889     sb_factory_.reset(new TestSafeBrowsingServiceFactory(url_prefix.spec()));
    890     SafeBrowsingService::RegisterFactory(sb_factory_.get());
    891 
    892     InProcessBrowserTest::SetUp();
    893   }
    894 
    895   virtual void TearDown() OVERRIDE {
    896     InProcessBrowserTest::TearDown();
    897 
    898     SafeBrowsingService::RegisterFactory(NULL);
    899   }
    900 
    901   virtual bool SetUpUserDataDirectory() OVERRIDE {
    902     base::FilePath cookie_path(
    903         SafeBrowsingService::GetCookieFilePathForTesting());
    904     EXPECT_FALSE(base::PathExists(cookie_path));
    905 
    906     base::FilePath test_dir;
    907     if (!PathService::Get(chrome::DIR_TEST_DATA, &test_dir)) {
    908       EXPECT_TRUE(false);
    909       return false;
    910     }
    911 
    912     // Initialize the SafeBrowsing cookies with a pre-created cookie store.  It
    913     // contains a single cookie, for domain 127.0.0.1, with value a=b, and
    914     // expires in 2038.
    915     base::FilePath initial_cookies = test_dir.AppendASCII("safe_browsing")
    916         .AppendASCII("Safe Browsing Cookies");
    917     if (!base::CopyFile(initial_cookies, cookie_path)) {
    918       EXPECT_TRUE(false);
    919       return false;
    920     }
    921 
    922     sql::Connection db;
    923     if (!db.Open(cookie_path)) {
    924       EXPECT_TRUE(false);
    925       return false;
    926     }
    927     // Ensure the host value in the cookie file matches the test server we will
    928     // be connecting to.
    929     sql::Statement smt(db.GetUniqueStatement(
    930         "UPDATE cookies SET host_key = ?"));
    931     if (!smt.is_valid()) {
    932       EXPECT_TRUE(false);
    933       return false;
    934     }
    935     if (!smt.BindString(0, test_server()->host_port_pair().host())) {
    936       EXPECT_TRUE(false);
    937       return false;
    938     }
    939     if (!smt.Run()) {
    940       EXPECT_TRUE(false);
    941       return false;
    942     }
    943 
    944     return InProcessBrowserTest::SetUpUserDataDirectory();
    945   }
    946 
    947   virtual void TearDownInProcessBrowserTestFixture() OVERRIDE {
    948     InProcessBrowserTest::TearDownInProcessBrowserTestFixture();
    949 
    950     sql::Connection db;
    951     base::FilePath cookie_path(
    952         SafeBrowsingService::GetCookieFilePathForTesting());
    953     ASSERT_TRUE(db.Open(cookie_path));
    954 
    955     sql::Statement smt(db.GetUniqueStatement(
    956         "SELECT name, value FROM cookies ORDER BY name"));
    957     ASSERT_TRUE(smt.is_valid());
    958 
    959     ASSERT_TRUE(smt.Step());
    960     ASSERT_EQ("a", smt.ColumnString(0));
    961     ASSERT_EQ("b", smt.ColumnString(1));
    962     ASSERT_TRUE(smt.Step());
    963     ASSERT_EQ("c", smt.ColumnString(0));
    964     ASSERT_EQ("d", smt.ColumnString(1));
    965     EXPECT_FALSE(smt.Step());
    966   }
    967 
    968   virtual void SetUpOnMainThread() OVERRIDE {
    969     sb_service_ = g_browser_process->safe_browsing_service();
    970     ASSERT_TRUE(sb_service_.get() != NULL);
    971   }
    972 
    973   virtual void CleanUpOnMainThread() OVERRIDE {
    974     sb_service_ = NULL;
    975   }
    976 
    977   void ForceUpdate() {
    978     sb_service_->protocol_manager()->ForceScheduleNextUpdate(
    979         base::TimeDelta::FromSeconds(0));
    980   }
    981 
    982   scoped_refptr<SafeBrowsingService> sb_service_;
    983 
    984  private:
    985   scoped_ptr<TestSafeBrowsingServiceFactory> sb_factory_;
    986 
    987   DISALLOW_COPY_AND_ASSIGN(SafeBrowsingDatabaseManagerCookieTest);
    988 };
    989 
    990 // Test that a Safe Browsing database update request both sends cookies and can
    991 // save cookies.
    992 IN_PROC_BROWSER_TEST_F(SafeBrowsingDatabaseManagerCookieTest,
    993                        TestSBUpdateCookies) {
    994   content::WindowedNotificationObserver observer(
    995       chrome::NOTIFICATION_SAFE_BROWSING_UPDATE_COMPLETE,
    996       content::Source<SafeBrowsingDatabaseManager>(
    997           sb_service_->database_manager().get()));
    998   BrowserThread::PostTask(
    999       BrowserThread::IO,
   1000       FROM_HERE,
   1001       base::Bind(&SafeBrowsingDatabaseManagerCookieTest::ForceUpdate, this));
   1002   observer.Wait();
   1003 }
   1004