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