Update mojo surfaces bindings and mojo/cc/ glue
[chromium-blink-merge.git] / chrome / browser / safe_browsing / safe_browsing_service_browsertest.cc
blobb8f9bc302cdfd24f93960755e01c73c81f16004b
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 "net/cookies/cookie_store.h"
45 #include "sql/connection.h"
46 #include "sql/statement.h"
47 #include "testing/gmock/include/gmock/gmock.h"
49 #if defined(OS_CHROMEOS)
50 #include "chromeos/chromeos_switches.h"
51 #endif
53 using content::BrowserThread;
54 using content::InterstitialPage;
55 using content::WebContents;
56 using ::testing::_;
57 using ::testing::Mock;
58 using ::testing::StrictMock;
60 namespace {
62 void InvokeFullHashCallback(
63 SafeBrowsingProtocolManager::FullHashCallback callback,
64 const std::vector<SBFullHashResult>& result) {
65 callback.Run(result, base::TimeDelta::FromMinutes(45));
68 class FakeSafeBrowsingService : public SafeBrowsingService {
69 public:
70 explicit FakeSafeBrowsingService(const std::string& url_prefix)
71 : url_prefix_(url_prefix) {}
73 virtual SafeBrowsingProtocolConfig GetProtocolConfig() const OVERRIDE {
74 SafeBrowsingProtocolConfig config;
75 config.url_prefix = url_prefix_;
76 // Makes sure the auto update is not triggered. The tests will force the
77 // update when needed.
78 config.disable_auto_update = true;
79 #if defined(OS_ANDROID)
80 config.disable_connection_check = true;
81 #endif
82 config.client_name = "browser_tests";
83 return config;
86 private:
87 virtual ~FakeSafeBrowsingService() {}
89 std::string url_prefix_;
91 DISALLOW_COPY_AND_ASSIGN(FakeSafeBrowsingService);
94 // Factory that creates FakeSafeBrowsingService instances.
95 class TestSafeBrowsingServiceFactory : public SafeBrowsingServiceFactory {
96 public:
97 explicit TestSafeBrowsingServiceFactory(const std::string& url_prefix)
98 : url_prefix_(url_prefix) {}
100 virtual SafeBrowsingService* CreateSafeBrowsingService() OVERRIDE {
101 return new FakeSafeBrowsingService(url_prefix_);
104 private:
105 std::string url_prefix_;
108 // A SafeBrowingDatabase class that allows us to inject the malicious URLs.
109 class TestSafeBrowsingDatabase : public SafeBrowsingDatabase {
110 public:
111 TestSafeBrowsingDatabase() {}
113 virtual ~TestSafeBrowsingDatabase() {}
115 // Initializes the database with the given filename.
116 virtual void Init(const base::FilePath& filename) OVERRIDE {}
118 // Deletes the current database and creates a new one.
119 virtual bool ResetDatabase() OVERRIDE {
120 badurls_.clear();
121 return true;
124 // Called on the IO thread to check if the given URL is safe or not. If we
125 // can synchronously determine that the URL is safe, CheckUrl returns true,
126 // otherwise it returns false.
127 virtual bool ContainsBrowseUrl(
128 const GURL& url,
129 std::vector<SBPrefix>* prefix_hits,
130 std::vector<SBFullHashResult>* cache_hits) OVERRIDE {
131 cache_hits->clear();
132 return ContainsUrl(safe_browsing_util::MALWARE,
133 safe_browsing_util::PHISH,
134 std::vector<GURL>(1, url),
135 prefix_hits);
137 virtual bool ContainsDownloadUrl(
138 const std::vector<GURL>& urls,
139 std::vector<SBPrefix>* prefix_hits) OVERRIDE {
140 bool found = ContainsUrl(safe_browsing_util::BINURL,
141 safe_browsing_util::BINURL,
142 urls,
143 prefix_hits);
144 if (!found)
145 return false;
146 DCHECK_LE(1U, prefix_hits->size());
147 return true;
149 virtual bool ContainsCsdWhitelistedUrl(const GURL& url) OVERRIDE {
150 return true;
152 virtual bool ContainsDownloadWhitelistedString(
153 const std::string& str) OVERRIDE {
154 return true;
156 virtual bool ContainsDownloadWhitelistedUrl(const GURL& url) OVERRIDE {
157 return true;
159 virtual bool ContainsExtensionPrefixes(
160 const std::vector<SBPrefix>& prefixes,
161 std::vector<SBPrefix>* prefix_hits) OVERRIDE {
162 return true;
164 virtual bool ContainsSideEffectFreeWhitelistUrl(const GURL& url) OVERRIDE {
165 return true;
167 virtual bool ContainsMalwareIP(const std::string& ip_address) OVERRIDE {
168 return true;
170 virtual bool UpdateStarted(std::vector<SBListChunkRanges>* lists) OVERRIDE {
171 ADD_FAILURE() << "Not implemented.";
172 return false;
174 virtual void InsertChunks(
175 const std::string& list_name,
176 const std::vector<SBChunkData*>& chunks) OVERRIDE {
177 ADD_FAILURE() << "Not implemented.";
179 virtual void DeleteChunks(
180 const std::vector<SBChunkDelete>& chunk_deletes) OVERRIDE {
181 ADD_FAILURE() << "Not implemented.";
183 virtual void UpdateFinished(bool update_succeeded) OVERRIDE {
184 ADD_FAILURE() << "Not implemented.";
186 virtual void CacheHashResults(
187 const std::vector<SBPrefix>& prefixes,
188 const std::vector<SBFullHashResult>& cache_hits,
189 const base::TimeDelta& cache_lifetime) OVERRIDE {
190 // Do nothing for the cache.
192 virtual bool IsMalwareIPMatchKillSwitchOn() OVERRIDE {
193 return false;
195 virtual bool IsCsdWhitelistKillSwitchOn() OVERRIDE {
196 return false;
199 // Fill up the database with test URL.
200 void AddUrl(const GURL& url,
201 int list_id,
202 const std::vector<SBPrefix>& prefix_hits) {
203 badurls_[url.spec()].list_id = list_id;
204 badurls_[url.spec()].prefix_hits = prefix_hits;
207 // Fill up the database with test hash digest.
208 void AddDownloadPrefix(SBPrefix prefix) {
209 download_digest_prefix_.insert(prefix);
212 private:
213 struct Hits {
214 int list_id;
215 std::vector<SBPrefix> prefix_hits;
218 bool ContainsUrl(int list_id0,
219 int list_id1,
220 const std::vector<GURL>& urls,
221 std::vector<SBPrefix>* prefix_hits) {
222 bool hit = false;
223 for (size_t i = 0; i < urls.size(); ++i) {
224 const GURL& url = urls[i];
225 base::hash_map<std::string, Hits>::const_iterator
226 badurls_it = badurls_.find(url.spec());
228 if (badurls_it == badurls_.end())
229 continue;
231 if (badurls_it->second.list_id == list_id0 ||
232 badurls_it->second.list_id == list_id1) {
233 prefix_hits->insert(prefix_hits->end(),
234 badurls_it->second.prefix_hits.begin(),
235 badurls_it->second.prefix_hits.end());
236 hit = true;
239 return hit;
242 base::hash_map<std::string, Hits> badurls_;
243 base::hash_set<SBPrefix> download_digest_prefix_;
246 // Factory that creates TestSafeBrowsingDatabase instances.
247 class TestSafeBrowsingDatabaseFactory : public SafeBrowsingDatabaseFactory {
248 public:
249 TestSafeBrowsingDatabaseFactory() : db_(NULL) {}
250 virtual ~TestSafeBrowsingDatabaseFactory() {}
252 virtual SafeBrowsingDatabase* CreateSafeBrowsingDatabase(
253 bool enable_download_protection,
254 bool enable_client_side_whitelist,
255 bool enable_download_whitelist,
256 bool enable_extension_blacklist,
257 bool enable_side_effect_free_whitelist,
258 bool enable_ip_blacklist) OVERRIDE {
259 db_ = new TestSafeBrowsingDatabase();
260 return db_;
262 TestSafeBrowsingDatabase* GetDb() {
263 return db_;
265 private:
266 // Owned by the SafebrowsingService.
267 TestSafeBrowsingDatabase* db_;
270 // A TestProtocolManager that could return fixed responses from
271 // safebrowsing server for testing purpose.
272 class TestProtocolManager : public SafeBrowsingProtocolManager {
273 public:
274 TestProtocolManager(SafeBrowsingProtocolManagerDelegate* delegate,
275 net::URLRequestContextGetter* request_context_getter,
276 const SafeBrowsingProtocolConfig& config)
277 : SafeBrowsingProtocolManager(delegate, request_context_getter, config) {
278 create_count_++;
281 virtual ~TestProtocolManager() {
282 delete_count_++;
285 // This function is called when there is a prefix hit in local safebrowsing
286 // database and safebrowsing service issues a get hash request to backends.
287 // We return a result from the prefilled full_hashes_ hash_map to simulate
288 // server's response. At the same time, latency is added to simulate real
289 // life network issues.
290 virtual void GetFullHash(
291 const std::vector<SBPrefix>& prefixes,
292 SafeBrowsingProtocolManager::FullHashCallback callback,
293 bool is_download) OVERRIDE {
294 BrowserThread::PostDelayedTask(
295 BrowserThread::IO, FROM_HERE,
296 base::Bind(InvokeFullHashCallback, callback, full_hashes_),
297 delay_);
300 // Prepare the GetFullHash results for the next request.
301 void SetGetFullHashResponse(const SBFullHashResult& full_hash_result) {
302 full_hashes_.clear();
303 full_hashes_.push_back(full_hash_result);
306 void IntroduceDelay(const base::TimeDelta& delay) {
307 delay_ = delay;
310 static int create_count() {
311 return create_count_;
314 static int delete_count() {
315 return delete_count_;
318 private:
319 std::vector<SBFullHashResult> full_hashes_;
320 base::TimeDelta delay_;
321 static int create_count_;
322 static int delete_count_;
325 // static
326 int TestProtocolManager::create_count_ = 0;
327 // static
328 int TestProtocolManager::delete_count_ = 0;
330 // Factory that creates TestProtocolManager instances.
331 class TestSBProtocolManagerFactory : public SBProtocolManagerFactory {
332 public:
333 TestSBProtocolManagerFactory() : pm_(NULL) {}
334 virtual ~TestSBProtocolManagerFactory() {}
336 virtual SafeBrowsingProtocolManager* CreateProtocolManager(
337 SafeBrowsingProtocolManagerDelegate* delegate,
338 net::URLRequestContextGetter* request_context_getter,
339 const SafeBrowsingProtocolConfig& config) OVERRIDE {
340 pm_ = new TestProtocolManager(delegate, request_context_getter, config);
341 return pm_;
344 TestProtocolManager* GetProtocolManager() {
345 return pm_;
348 private:
349 // Owned by the SafebrowsingService.
350 TestProtocolManager* pm_;
353 class MockObserver : public SafeBrowsingUIManager::Observer {
354 public:
355 MockObserver() {}
356 virtual ~MockObserver() {}
357 MOCK_METHOD1(OnSafeBrowsingHit,
358 void(const SafeBrowsingUIManager::UnsafeResource&));
359 MOCK_METHOD1(OnSafeBrowsingMatch,
360 void(const SafeBrowsingUIManager::UnsafeResource&));
363 MATCHER_P(IsUnsafeResourceFor, url, "") {
364 return (arg.url.spec() == url.spec() &&
365 arg.threat_type != SB_THREAT_TYPE_SAFE);
368 } // namespace
370 // Tests the safe browsing blocking page in a browser.
371 class SafeBrowsingServiceTest : public InProcessBrowserTest {
372 public:
373 SafeBrowsingServiceTest() {
376 static void GenUrlFullhashResult(const GURL& url,
377 int list_id,
378 SBFullHashResult* full_hash) {
379 std::string host;
380 std::string path;
381 safe_browsing_util::CanonicalizeUrl(url, &host, &path, NULL);
382 full_hash->hash = SBFullHashForString(host + path);
383 full_hash->list_id = list_id;
386 virtual void SetUp() {
387 // InProcessBrowserTest::SetUp() instantiates SafebrowsingService and
388 // RegisterFactory has to be called before SafeBrowsingService is created.
389 sb_factory_.reset(new TestSafeBrowsingServiceFactory(
390 "https://definatelynotarealdomain/safebrowsing"));
391 SafeBrowsingService::RegisterFactory(sb_factory_.get());
392 SafeBrowsingDatabase::RegisterFactory(&db_factory_);
393 SafeBrowsingProtocolManager::RegisterFactory(&pm_factory_);
394 InProcessBrowserTest::SetUp();
397 virtual void TearDown() {
398 InProcessBrowserTest::TearDown();
400 // Unregister test factories after InProcessBrowserTest::TearDown
401 // (which destructs SafeBrowsingService).
402 SafeBrowsingDatabase::RegisterFactory(NULL);
403 SafeBrowsingProtocolManager::RegisterFactory(NULL);
404 SafeBrowsingService::RegisterFactory(NULL);
407 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
408 // Makes sure the auto update is not triggered during the test.
409 // This test will fill up the database using testing prefixes
410 // and urls.
411 command_line->AppendSwitch(switches::kSbDisableAutoUpdate);
412 #if defined(OS_CHROMEOS)
413 command_line->AppendSwitch(
414 chromeos::switches::kIgnoreUserProfileMappingForTests);
415 #endif
418 virtual void SetUpInProcessBrowserTestFixture() {
419 ASSERT_TRUE(test_server()->Start());
422 // This will setup the "url" prefix in database and prepare protocol manager
423 // to response with |full_hash| for get full hash request.
424 void SetupResponseForUrl(const GURL& url, const SBFullHashResult& full_hash) {
425 std::vector<SBPrefix> prefix_hits;
426 prefix_hits.push_back(full_hash.hash.prefix);
428 // Make sure the full hits is empty unless we need to test the
429 // full hash is hit in database's local cache.
430 TestSafeBrowsingDatabase* db = db_factory_.GetDb();
431 db->AddUrl(url, full_hash.list_id, prefix_hits);
433 TestProtocolManager* pm = pm_factory_.GetProtocolManager();
434 pm->SetGetFullHashResponse(full_hash);
437 bool ShowingInterstitialPage() {
438 WebContents* contents =
439 browser()->tab_strip_model()->GetActiveWebContents();
440 InterstitialPage* interstitial_page = contents->GetInterstitialPage();
441 return interstitial_page != NULL;
444 void IntroduceGetHashDelay(const base::TimeDelta& delay) {
445 pm_factory_.GetProtocolManager()->IntroduceDelay(delay);
448 base::TimeDelta GetCheckTimeout(SafeBrowsingService* sb_service) {
449 return sb_service->database_manager()->check_timeout_;
452 void SetCheckTimeout(SafeBrowsingService* sb_service,
453 const base::TimeDelta& delay) {
454 sb_service->database_manager()->check_timeout_ = delay;
457 void CreateCSDService() {
458 safe_browsing::ClientSideDetectionService* csd_service =
459 safe_browsing::ClientSideDetectionService::Create(NULL);
460 SafeBrowsingService* sb_service =
461 g_browser_process->safe_browsing_service();
462 sb_service->csd_service_.reset(csd_service);
463 sb_service->RefreshState();
466 void ProceedAndWhitelist(
467 const SafeBrowsingUIManager::UnsafeResource& resource) {
468 std::vector<SafeBrowsingUIManager::UnsafeResource> resources;
469 resources.push_back(resource);
470 BrowserThread::PostTask(
471 BrowserThread::IO, FROM_HERE,
472 base::Bind(&SafeBrowsingUIManager::OnBlockingPageDone,
473 g_browser_process->safe_browsing_service()->ui_manager(),
474 resources, true));
475 WaitForIOThread();
478 protected:
479 StrictMock<MockObserver> observer_;
481 // Temporary profile dir for test cases that create a second profile. This is
482 // owned by the SafeBrowsingServiceTest object so that it will not get
483 // destructed until after the test Browser has been torn down, since the
484 // ImportantFileWriter may still be modifying it after the Profile object has
485 // been destroyed.
486 base::ScopedTempDir temp_profile_dir_;
488 // Waits for pending tasks on the IO thread to complete. This is useful
489 // to wait for the SafeBrowsingService to finish loading/stopping.
490 void WaitForIOThread() {
491 scoped_refptr<base::ThreadTestHelper> io_helper(new base::ThreadTestHelper(
492 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO).get()));
493 ASSERT_TRUE(io_helper->Run());
496 private:
497 scoped_ptr<TestSafeBrowsingServiceFactory> sb_factory_;
498 TestSafeBrowsingDatabaseFactory db_factory_;
499 TestSBProtocolManagerFactory pm_factory_;
501 DISALLOW_COPY_AND_ASSIGN(SafeBrowsingServiceTest);
504 namespace {
506 const char kEmptyPage[] = "files/empty.html";
507 const char kMalwareFile[] = "files/downloads/dangerous/dangerous.exe";
508 const char kMalwarePage[] = "files/safe_browsing/malware.html";
510 // This test goes through DownloadResourceHandler.
511 IN_PROC_BROWSER_TEST_F(SafeBrowsingServiceTest, Malware) {
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 GenUrlFullhashResult(url, safe_browsing_util::MALWARE, &malware_full_hash);
520 EXPECT_CALL(observer_,
521 OnSafeBrowsingMatch(IsUnsafeResourceFor(url))).Times(1);
522 EXPECT_CALL(observer_, OnSafeBrowsingHit(IsUnsafeResourceFor(url))).Times(1);
523 SetupResponseForUrl(url, malware_full_hash);
524 ui_test_utils::NavigateToURL(browser(), url);
525 EXPECT_TRUE(ShowingInterstitialPage());
526 g_browser_process->safe_browsing_service()->
527 ui_manager()->RemoveObserver(&observer_);
530 IN_PROC_BROWSER_TEST_F(SafeBrowsingServiceTest, DISABLED_MalwareWithWhitelist) {
531 GURL url = test_server()->GetURL(kEmptyPage);
532 g_browser_process->safe_browsing_service()->
533 ui_manager()->AddObserver(&observer_);
535 // After adding the url to safebrowsing database and getfullhash result,
536 // we should see the interstitial page.
537 SBFullHashResult malware_full_hash;
538 GenUrlFullhashResult(url, safe_browsing_util::MALWARE, &malware_full_hash);
539 EXPECT_CALL(observer_,
540 OnSafeBrowsingMatch(IsUnsafeResourceFor(url))).Times(1);
541 EXPECT_CALL(observer_, OnSafeBrowsingHit(IsUnsafeResourceFor(url))).Times(1)
542 .WillOnce(testing::Invoke(
543 this, &SafeBrowsingServiceTest::ProceedAndWhitelist));
544 SetupResponseForUrl(url, malware_full_hash);
546 ui_test_utils::NavigateToURL(browser(), url);
547 // Mock calls OnBlockingPageDone set to proceed, so the interstitial
548 // is removed.
549 EXPECT_FALSE(ShowingInterstitialPage());
550 Mock::VerifyAndClearExpectations(&observer_);
552 // Navigate back to kEmptyPage -- should hit the whitelist, and send a match
553 // call, but no hit call.
554 EXPECT_CALL(observer_,
555 OnSafeBrowsingMatch(IsUnsafeResourceFor(url))).Times(1);
556 EXPECT_CALL(observer_, OnSafeBrowsingHit(IsUnsafeResourceFor(url))).Times(0);
557 ui_test_utils::NavigateToURL(browser(), url);
558 EXPECT_FALSE(ShowingInterstitialPage());
560 g_browser_process->safe_browsing_service()->
561 ui_manager()->RemoveObserver(&observer_);
564 const char kPrefetchMalwarePage[] = "files/safe_browsing/prefetch_malware.html";
566 // This test confirms that prefetches don't themselves get the
567 // interstitial treatment.
568 IN_PROC_BROWSER_TEST_F(SafeBrowsingServiceTest, Prefetch) {
569 GURL url = test_server()->GetURL(kPrefetchMalwarePage);
570 GURL malware_url = test_server()->GetURL(kMalwarePage);
571 g_browser_process->safe_browsing_service()->
572 ui_manager()->AddObserver(&observer_);
574 class SetPrefetchForTest {
575 public:
576 explicit SetPrefetchForTest(bool prefetch)
577 : old_prerender_mode_(prerender::PrerenderManager::GetMode()) {
578 std::string exp_group = prefetch ? "ExperimentYes" : "ExperimentNo";
579 base::FieldTrialList::CreateFieldTrial("Prefetch", exp_group);
581 prerender::PrerenderManager::SetMode(
582 prerender::PrerenderManager::PRERENDER_MODE_DISABLED);
585 ~SetPrefetchForTest() {
586 prerender::PrerenderManager::SetMode(old_prerender_mode_);
589 private:
590 prerender::PrerenderManager::PrerenderManagerMode old_prerender_mode_;
591 } set_prefetch_for_test(true);
593 // Even though we have added this uri to the safebrowsing database and
594 // getfullhash result, we should not see the interstitial page since the
595 // only malware was a prefetch target.
596 SBFullHashResult malware_full_hash;
597 GenUrlFullhashResult(malware_url, safe_browsing_util::MALWARE,
598 &malware_full_hash);
599 SetupResponseForUrl(malware_url, malware_full_hash);
600 ui_test_utils::NavigateToURL(browser(), url);
601 EXPECT_FALSE(ShowingInterstitialPage());
602 Mock::VerifyAndClear(&observer_);
604 // However, when we navigate to the malware page, we should still get
605 // the interstitial.
606 EXPECT_CALL(observer_, OnSafeBrowsingMatch(IsUnsafeResourceFor(malware_url)))
607 .Times(1);
608 EXPECT_CALL(observer_, OnSafeBrowsingHit(IsUnsafeResourceFor(malware_url)))
609 .Times(1);
610 ui_test_utils::NavigateToURL(browser(), malware_url);
611 EXPECT_TRUE(ShowingInterstitialPage());
612 Mock::VerifyAndClear(&observer_);
613 g_browser_process->safe_browsing_service()->
614 ui_manager()->RemoveObserver(&observer_);
617 } // namespace
619 class TestSBClient
620 : public base::RefCountedThreadSafe<TestSBClient>,
621 public SafeBrowsingDatabaseManager::Client {
622 public:
623 TestSBClient()
624 : threat_type_(SB_THREAT_TYPE_SAFE),
625 safe_browsing_service_(g_browser_process->safe_browsing_service()) {
628 SBThreatType GetThreatType() const {
629 return threat_type_;
632 void CheckDownloadUrl(const std::vector<GURL>& url_chain) {
633 BrowserThread::PostTask(
634 BrowserThread::IO, FROM_HERE,
635 base::Bind(&TestSBClient::CheckDownloadUrlOnIOThread,
636 this, url_chain));
637 content::RunMessageLoop(); // Will stop in OnCheckDownloadUrlResult.
640 private:
641 friend class base::RefCountedThreadSafe<TestSBClient>;
642 virtual ~TestSBClient() {}
644 void CheckDownloadUrlOnIOThread(const std::vector<GURL>& url_chain) {
645 safe_browsing_service_->database_manager()->
646 CheckDownloadUrl(url_chain, this);
649 // Called when the result of checking a download URL is known.
650 virtual void OnCheckDownloadUrlResult(const std::vector<GURL>& url_chain,
651 SBThreatType threat_type) OVERRIDE {
652 threat_type_ = threat_type;
653 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
654 base::Bind(&TestSBClient::DownloadCheckDone, this));
657 void DownloadCheckDone() {
658 base::MessageLoopForUI::current()->Quit();
661 SBThreatType threat_type_;
662 SafeBrowsingService* safe_browsing_service_;
664 DISALLOW_COPY_AND_ASSIGN(TestSBClient);
667 // These tests use SafeBrowsingService::Client to directly interact with
668 // SafeBrowsingService.
669 namespace {
671 IN_PROC_BROWSER_TEST_F(SafeBrowsingServiceTest, CheckDownloadUrl) {
672 GURL badbin_url = test_server()->GetURL(kMalwareFile);
673 std::vector<GURL> badbin_urls(1, badbin_url);
675 scoped_refptr<TestSBClient> client(new TestSBClient);
676 client->CheckDownloadUrl(badbin_urls);
678 // Since badbin_url is not in database, it is considered to be safe.
679 EXPECT_EQ(SB_THREAT_TYPE_SAFE, client->GetThreatType());
681 SBFullHashResult full_hash_result;
682 GenUrlFullhashResult(badbin_url, safe_browsing_util::BINURL,
683 &full_hash_result);
684 SetupResponseForUrl(badbin_url, full_hash_result);
686 client->CheckDownloadUrl(badbin_urls);
688 // Now, the badbin_url is not safe since it is added to download database.
689 EXPECT_EQ(SB_THREAT_TYPE_BINARY_MALWARE_URL, client->GetThreatType());
692 IN_PROC_BROWSER_TEST_F(SafeBrowsingServiceTest, CheckDownloadUrlRedirects) {
693 GURL original_url = test_server()->GetURL(kEmptyPage);
694 GURL badbin_url = test_server()->GetURL(kMalwareFile);
695 GURL final_url = test_server()->GetURL(kEmptyPage);
696 std::vector<GURL> badbin_urls;
697 badbin_urls.push_back(original_url);
698 badbin_urls.push_back(badbin_url);
699 badbin_urls.push_back(final_url);
701 scoped_refptr<TestSBClient> client(new TestSBClient);
702 client->CheckDownloadUrl(badbin_urls);
704 // Since badbin_url is not in database, it is considered to be safe.
705 EXPECT_EQ(SB_THREAT_TYPE_SAFE, client->GetThreatType());
707 SBFullHashResult full_hash_result;
708 GenUrlFullhashResult(badbin_url, safe_browsing_util::BINURL,
709 &full_hash_result);
710 SetupResponseForUrl(badbin_url, full_hash_result);
712 client->CheckDownloadUrl(badbin_urls);
714 // Now, the badbin_url is not safe since it is added to download database.
715 EXPECT_EQ(SB_THREAT_TYPE_BINARY_MALWARE_URL, client->GetThreatType());
718 #if defined(OS_WIN)
719 // http://crbug.com/396409
720 #define MAYBE_CheckDownloadUrlTimedOut DISABLED_CheckDownloadUrlTimedOut
721 #else
722 #define MAYBE_CheckDownloadUrlTimedOut CheckDownloadUrlTimedOut
723 #endif
724 IN_PROC_BROWSER_TEST_F(SafeBrowsingServiceTest,
725 MAYBE_CheckDownloadUrlTimedOut) {
726 GURL badbin_url = test_server()->GetURL(kMalwareFile);
727 std::vector<GURL> badbin_urls(1, badbin_url);
729 scoped_refptr<TestSBClient> client(new TestSBClient);
730 SBFullHashResult full_hash_result;
731 GenUrlFullhashResult(badbin_url, safe_browsing_util::BINURL,
732 &full_hash_result);
733 SetupResponseForUrl(badbin_url, full_hash_result);
734 client->CheckDownloadUrl(badbin_urls);
736 // badbin_url is not safe since it is added to download database.
737 EXPECT_EQ(SB_THREAT_TYPE_BINARY_MALWARE_URL, client->GetThreatType());
740 // Now introducing delays and we should hit timeout.
742 SafeBrowsingService* sb_service = g_browser_process->safe_browsing_service();
743 base::TimeDelta default_urlcheck_timeout = GetCheckTimeout(sb_service);
744 IntroduceGetHashDelay(base::TimeDelta::FromSeconds(1));
745 SetCheckTimeout(sb_service, base::TimeDelta::FromMilliseconds(1));
746 client->CheckDownloadUrl(badbin_urls);
748 // There should be a timeout and the hash would be considered as safe.
749 EXPECT_EQ(SB_THREAT_TYPE_SAFE, client->GetThreatType());
751 // Need to set the timeout back to the default value.
752 SetCheckTimeout(sb_service, default_urlcheck_timeout);
755 IN_PROC_BROWSER_TEST_F(SafeBrowsingServiceTest, StartAndStop) {
756 CreateCSDService();
757 SafeBrowsingService* sb_service = g_browser_process->safe_browsing_service();
758 safe_browsing::ClientSideDetectionService* csd_service =
759 sb_service->safe_browsing_detection_service();
760 PrefService* pref_service = browser()->profile()->GetPrefs();
762 ASSERT_TRUE(sb_service != NULL);
763 ASSERT_TRUE(csd_service != NULL);
764 ASSERT_TRUE(pref_service != NULL);
766 EXPECT_TRUE(pref_service->GetBoolean(prefs::kSafeBrowsingEnabled));
768 // SBS might still be starting, make sure this doesn't flake.
769 WaitForIOThread();
770 EXPECT_TRUE(sb_service->enabled());
771 EXPECT_TRUE(csd_service->enabled());
773 // Add a new Profile. SBS should keep running.
774 ASSERT_TRUE(temp_profile_dir_.CreateUniqueTempDir());
775 scoped_ptr<Profile> profile2(Profile::CreateProfile(
776 temp_profile_dir_.path(), NULL, Profile::CREATE_MODE_SYNCHRONOUS));
777 ASSERT_TRUE(profile2.get() != NULL);
778 StartupTaskRunnerServiceFactory::GetForProfile(profile2.get())->
779 StartDeferredTaskRunners();
780 PrefService* pref_service2 = profile2->GetPrefs();
781 EXPECT_TRUE(pref_service2->GetBoolean(prefs::kSafeBrowsingEnabled));
782 // We don't expect the state to have changed, but if it did, wait for it.
783 WaitForIOThread();
784 EXPECT_TRUE(sb_service->enabled());
785 EXPECT_TRUE(csd_service->enabled());
787 // Change one of the prefs. SBS should keep running.
788 pref_service->SetBoolean(prefs::kSafeBrowsingEnabled, false);
789 WaitForIOThread();
790 EXPECT_TRUE(sb_service->enabled());
791 EXPECT_TRUE(csd_service->enabled());
793 // Change the other pref. SBS should stop now.
794 pref_service2->SetBoolean(prefs::kSafeBrowsingEnabled, false);
795 WaitForIOThread();
796 EXPECT_FALSE(sb_service->enabled());
797 EXPECT_FALSE(csd_service->enabled());
799 // Turn it back on. SBS comes back.
800 pref_service2->SetBoolean(prefs::kSafeBrowsingEnabled, true);
801 WaitForIOThread();
802 EXPECT_TRUE(sb_service->enabled());
803 EXPECT_TRUE(csd_service->enabled());
805 // Delete the Profile. SBS stops again.
806 pref_service2 = NULL;
807 profile2.reset();
808 WaitForIOThread();
809 EXPECT_FALSE(sb_service->enabled());
810 EXPECT_FALSE(csd_service->enabled());
813 } // namespace
815 class SafeBrowsingServiceShutdownTest : public SafeBrowsingServiceTest {
816 public:
817 virtual void TearDown() OVERRIDE {
818 // Browser should be fully torn down by now, so we can safely check these
819 // counters.
820 EXPECT_EQ(1, TestProtocolManager::create_count());
821 EXPECT_EQ(1, TestProtocolManager::delete_count());
823 SafeBrowsingServiceTest::TearDown();
826 // An observer that returns back to test code after a new profile is
827 // initialized.
828 void OnUnblockOnProfileCreation(Profile* profile,
829 Profile::CreateStatus status) {
830 if (status == Profile::CREATE_STATUS_INITIALIZED) {
831 profile2_ = profile;
832 base::MessageLoop::current()->Quit();
836 protected:
837 Profile* profile2_;
840 IN_PROC_BROWSER_TEST_F(SafeBrowsingServiceShutdownTest,
841 DontStartAfterShutdown) {
842 CreateCSDService();
843 SafeBrowsingService* sb_service = g_browser_process->safe_browsing_service();
844 safe_browsing::ClientSideDetectionService* csd_service =
845 sb_service->safe_browsing_detection_service();
846 PrefService* pref_service = browser()->profile()->GetPrefs();
848 ASSERT_TRUE(sb_service != NULL);
849 ASSERT_TRUE(csd_service != NULL);
850 ASSERT_TRUE(pref_service != NULL);
852 EXPECT_TRUE(pref_service->GetBoolean(prefs::kSafeBrowsingEnabled));
854 // SBS might still be starting, make sure this doesn't flake.
855 WaitForIOThread();
856 EXPECT_EQ(1, TestProtocolManager::create_count());
857 EXPECT_EQ(0, TestProtocolManager::delete_count());
859 // Create an additional profile. We need to use the ProfileManager so that
860 // the profile will get destroyed in the normal browser shutdown process.
861 ProfileManager* profile_manager = g_browser_process->profile_manager();
862 ASSERT_TRUE(temp_profile_dir_.CreateUniqueTempDir());
863 profile_manager->CreateProfileAsync(
864 temp_profile_dir_.path(),
865 base::Bind(&SafeBrowsingServiceShutdownTest::OnUnblockOnProfileCreation,
866 this),
867 base::string16(), base::string16(), std::string());
869 // Spin to allow profile creation to take place, loop is terminated
870 // by OnUnblockOnProfileCreation when the profile is created.
871 content::RunMessageLoop();
873 PrefService* pref_service2 = profile2_->GetPrefs();
874 EXPECT_TRUE(pref_service2->GetBoolean(prefs::kSafeBrowsingEnabled));
876 // We don't expect the state to have changed, but if it did, wait for it.
877 WaitForIOThread();
878 EXPECT_EQ(1, TestProtocolManager::create_count());
879 EXPECT_EQ(0, TestProtocolManager::delete_count());
881 // End the test, shutting down the browser.
882 // SafeBrowsingServiceShutdownTest::TearDown will check the create_count and
883 // delete_count again.
886 class SafeBrowsingDatabaseManagerCookieTest : public InProcessBrowserTest {
887 public:
888 SafeBrowsingDatabaseManagerCookieTest() {}
890 virtual void SetUp() OVERRIDE {
891 // We need to start the test server to get the host&port in the url.
892 ASSERT_TRUE(test_server()->Start());
894 // Point to the testing server for all SafeBrowsing requests.
895 GURL url_prefix = test_server()->GetURL(
896 "expect-and-set-cookie?expect=a%3db"
897 "&set=c%3dd%3b%20Expires=Fri,%2001%20Jan%202038%2001:01:01%20GMT"
898 "&data=foo#");
899 sb_factory_.reset(new TestSafeBrowsingServiceFactory(url_prefix.spec()));
900 SafeBrowsingService::RegisterFactory(sb_factory_.get());
902 InProcessBrowserTest::SetUp();
905 virtual void TearDown() OVERRIDE {
906 InProcessBrowserTest::TearDown();
908 SafeBrowsingService::RegisterFactory(NULL);
911 virtual bool SetUpUserDataDirectory() OVERRIDE {
912 base::FilePath cookie_path(
913 SafeBrowsingService::GetCookieFilePathForTesting());
914 EXPECT_FALSE(base::PathExists(cookie_path));
916 base::FilePath test_dir;
917 if (!PathService::Get(chrome::DIR_TEST_DATA, &test_dir)) {
918 EXPECT_TRUE(false);
919 return false;
922 // Initialize the SafeBrowsing cookies with a pre-created cookie store. It
923 // contains a single cookie, for domain 127.0.0.1, with value a=b, and
924 // expires in 2038.
925 base::FilePath initial_cookies = test_dir.AppendASCII("safe_browsing")
926 .AppendASCII("Safe Browsing Cookies");
927 if (!base::CopyFile(initial_cookies, cookie_path)) {
928 EXPECT_TRUE(false);
929 return false;
932 sql::Connection db;
933 if (!db.Open(cookie_path)) {
934 EXPECT_TRUE(false);
935 return false;
937 // Ensure the host value in the cookie file matches the test server we will
938 // be connecting to.
939 sql::Statement smt(db.GetUniqueStatement(
940 "UPDATE cookies SET host_key = ?"));
941 if (!smt.is_valid()) {
942 EXPECT_TRUE(false);
943 return false;
945 if (!smt.BindString(0, test_server()->host_port_pair().host())) {
946 EXPECT_TRUE(false);
947 return false;
949 if (!smt.Run()) {
950 EXPECT_TRUE(false);
951 return false;
954 return InProcessBrowserTest::SetUpUserDataDirectory();
957 virtual void TearDownInProcessBrowserTestFixture() OVERRIDE {
958 InProcessBrowserTest::TearDownInProcessBrowserTestFixture();
960 sql::Connection db;
961 base::FilePath cookie_path(
962 SafeBrowsingService::GetCookieFilePathForTesting());
963 ASSERT_TRUE(db.Open(cookie_path));
965 sql::Statement smt(db.GetUniqueStatement(
966 "SELECT name, value FROM cookies ORDER BY name"));
967 ASSERT_TRUE(smt.is_valid());
969 ASSERT_TRUE(smt.Step());
970 ASSERT_EQ("a", smt.ColumnString(0));
971 ASSERT_EQ("b", smt.ColumnString(1));
972 ASSERT_TRUE(smt.Step());
973 ASSERT_EQ("c", smt.ColumnString(0));
974 ASSERT_EQ("d", smt.ColumnString(1));
975 EXPECT_FALSE(smt.Step());
978 virtual void SetUpOnMainThread() OVERRIDE {
979 sb_service_ = g_browser_process->safe_browsing_service();
980 ASSERT_TRUE(sb_service_.get() != NULL);
983 virtual void TearDownOnMainThread() OVERRIDE {
984 sb_service_ = NULL;
987 void ForceUpdate() {
988 sb_service_->protocol_manager()->ForceScheduleNextUpdate(
989 base::TimeDelta::FromSeconds(0));
992 scoped_refptr<SafeBrowsingService> sb_service_;
994 private:
995 scoped_ptr<TestSafeBrowsingServiceFactory> sb_factory_;
997 DISALLOW_COPY_AND_ASSIGN(SafeBrowsingDatabaseManagerCookieTest);
1000 // Test that a Safe Browsing database update request both sends cookies and can
1001 // save cookies.
1002 IN_PROC_BROWSER_TEST_F(SafeBrowsingDatabaseManagerCookieTest,
1003 TestSBUpdateCookies) {
1004 content::WindowedNotificationObserver observer(
1005 chrome::NOTIFICATION_SAFE_BROWSING_UPDATE_COMPLETE,
1006 content::Source<SafeBrowsingDatabaseManager>(
1007 sb_service_->database_manager().get()));
1008 BrowserThread::PostTask(
1009 BrowserThread::IO,
1010 FROM_HERE,
1011 base::Bind(&SafeBrowsingDatabaseManagerCookieTest::ForceUpdate, this));
1012 observer.Wait();