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