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