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