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