GoogleURLTrackerInfoBarDelegate: Initialize uninitialized member in constructor.
[chromium-blink-merge.git] / chrome / browser / safe_browsing / safe_browsing_service_browsertest.cc
blob8caf1c590068414f289f961d54132859b872f9a6
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 config.client_name = "browser_tests";
80 return config;
83 private:
84 virtual ~FakeSafeBrowsingService() {}
86 std::string url_prefix_;
88 DISALLOW_COPY_AND_ASSIGN(FakeSafeBrowsingService);
91 // Factory that creates FakeSafeBrowsingService instances.
92 class TestSafeBrowsingServiceFactory : public SafeBrowsingServiceFactory {
93 public:
94 explicit TestSafeBrowsingServiceFactory(const std::string& url_prefix)
95 : url_prefix_(url_prefix) {}
97 virtual SafeBrowsingService* CreateSafeBrowsingService() OVERRIDE {
98 return new FakeSafeBrowsingService(url_prefix_);
101 private:
102 std::string url_prefix_;
105 // A SafeBrowingDatabase class that allows us to inject the malicious URLs.
106 class TestSafeBrowsingDatabase : public SafeBrowsingDatabase {
107 public:
108 TestSafeBrowsingDatabase() {}
110 virtual ~TestSafeBrowsingDatabase() {}
112 // Initializes the database with the given filename.
113 virtual void Init(const base::FilePath& filename) OVERRIDE {}
115 // Deletes the current database and creates a new one.
116 virtual bool ResetDatabase() OVERRIDE {
117 badurls_.clear();
118 return true;
121 // Called on the IO thread to check if the given URL is safe or not. If we
122 // can synchronously determine that the URL is safe, CheckUrl returns true,
123 // otherwise it returns false.
124 virtual bool ContainsBrowseUrl(
125 const GURL& url,
126 std::vector<SBPrefix>* prefix_hits,
127 std::vector<SBFullHashResult>* cache_hits) OVERRIDE {
128 cache_hits->clear();
129 return ContainsUrl(safe_browsing_util::MALWARE,
130 safe_browsing_util::PHISH,
131 std::vector<GURL>(1, url),
132 prefix_hits);
134 virtual bool ContainsDownloadUrl(
135 const std::vector<GURL>& urls,
136 std::vector<SBPrefix>* prefix_hits) OVERRIDE {
137 bool found = ContainsUrl(safe_browsing_util::BINURL,
138 safe_browsing_util::BINURL,
139 urls,
140 prefix_hits);
141 if (!found)
142 return false;
143 DCHECK_LE(1U, prefix_hits->size());
144 return true;
146 virtual bool ContainsCsdWhitelistedUrl(const GURL& url) OVERRIDE {
147 return true;
149 virtual bool ContainsDownloadWhitelistedString(
150 const std::string& str) OVERRIDE {
151 return true;
153 virtual bool ContainsDownloadWhitelistedUrl(const GURL& url) OVERRIDE {
154 return true;
156 virtual bool ContainsExtensionPrefixes(
157 const std::vector<SBPrefix>& prefixes,
158 std::vector<SBPrefix>* prefix_hits) OVERRIDE {
159 return true;
161 virtual bool ContainsSideEffectFreeWhitelistUrl(const GURL& url) OVERRIDE {
162 return true;
164 virtual bool ContainsMalwareIP(const std::string& ip_address) OVERRIDE {
165 return true;
167 virtual bool UpdateStarted(std::vector<SBListChunkRanges>* lists) OVERRIDE {
168 ADD_FAILURE() << "Not implemented.";
169 return false;
171 virtual void InsertChunks(const std::string& list_name,
172 const SBChunkList& chunks) OVERRIDE {
173 ADD_FAILURE() << "Not implemented.";
175 virtual void DeleteChunks(
176 const std::vector<SBChunkDelete>& chunk_deletes) OVERRIDE {
177 ADD_FAILURE() << "Not implemented.";
179 virtual void UpdateFinished(bool update_succeeded) OVERRIDE {
180 ADD_FAILURE() << "Not implemented.";
182 virtual void CacheHashResults(
183 const std::vector<SBPrefix>& prefixes,
184 const std::vector<SBFullHashResult>& cache_hits,
185 const base::TimeDelta& cache_lifetime) OVERRIDE {
186 // Do nothing for the cache.
188 virtual bool IsMalwareIPMatchKillSwitchOn() OVERRIDE {
189 return false;
191 virtual bool IsCsdWhitelistKillSwitchOn() OVERRIDE {
192 return false;
195 // Fill up the database with test URL.
196 void AddUrl(const GURL& url,
197 int list_id,
198 const std::vector<SBPrefix>& prefix_hits) {
199 badurls_[url.spec()].list_id = list_id;
200 badurls_[url.spec()].prefix_hits = prefix_hits;
203 // Fill up the database with test hash digest.
204 void AddDownloadPrefix(SBPrefix prefix) {
205 download_digest_prefix_.insert(prefix);
208 private:
209 struct Hits {
210 int list_id;
211 std::vector<SBPrefix> prefix_hits;
214 bool ContainsUrl(int list_id0,
215 int list_id1,
216 const std::vector<GURL>& urls,
217 std::vector<SBPrefix>* prefix_hits) {
218 bool hit = false;
219 for (size_t i = 0; i < urls.size(); ++i) {
220 const GURL& url = urls[i];
221 base::hash_map<std::string, Hits>::const_iterator
222 badurls_it = badurls_.find(url.spec());
224 if (badurls_it == badurls_.end())
225 continue;
227 if (badurls_it->second.list_id == list_id0 ||
228 badurls_it->second.list_id == list_id1) {
229 prefix_hits->insert(prefix_hits->end(),
230 badurls_it->second.prefix_hits.begin(),
231 badurls_it->second.prefix_hits.end());
232 hit = true;
235 return hit;
238 base::hash_map<std::string, Hits> badurls_;
239 base::hash_set<SBPrefix> download_digest_prefix_;
242 // Factory that creates TestSafeBrowsingDatabase instances.
243 class TestSafeBrowsingDatabaseFactory : public SafeBrowsingDatabaseFactory {
244 public:
245 TestSafeBrowsingDatabaseFactory() : db_(NULL) {}
246 virtual ~TestSafeBrowsingDatabaseFactory() {}
248 virtual SafeBrowsingDatabase* CreateSafeBrowsingDatabase(
249 bool enable_download_protection,
250 bool enable_client_side_whitelist,
251 bool enable_download_whitelist,
252 bool enable_extension_blacklist,
253 bool enable_side_effect_free_whitelist,
254 bool enable_ip_blacklist) OVERRIDE {
255 db_ = new TestSafeBrowsingDatabase();
256 return db_;
258 TestSafeBrowsingDatabase* GetDb() {
259 return db_;
261 private:
262 // Owned by the SafebrowsingService.
263 TestSafeBrowsingDatabase* db_;
266 // A TestProtocolManager that could return fixed responses from
267 // safebrowsing server for testing purpose.
268 class TestProtocolManager : public SafeBrowsingProtocolManager {
269 public:
270 TestProtocolManager(SafeBrowsingProtocolManagerDelegate* delegate,
271 net::URLRequestContextGetter* request_context_getter,
272 const SafeBrowsingProtocolConfig& config)
273 : SafeBrowsingProtocolManager(delegate, request_context_getter, config) {
274 create_count_++;
277 virtual ~TestProtocolManager() {
278 delete_count_++;
281 // This function is called when there is a prefix hit in local safebrowsing
282 // database and safebrowsing service issues a get hash request to backends.
283 // We return a result from the prefilled full_hashes_ hash_map to simulate
284 // server's response. At the same time, latency is added to simulate real
285 // life network issues.
286 virtual void GetFullHash(
287 const std::vector<SBPrefix>& prefixes,
288 SafeBrowsingProtocolManager::FullHashCallback callback,
289 bool is_download) OVERRIDE {
290 BrowserThread::PostDelayedTask(
291 BrowserThread::IO, FROM_HERE,
292 base::Bind(InvokeFullHashCallback, callback, full_hashes_),
293 delay_);
296 // Prepare the GetFullHash results for the next request.
297 void SetGetFullHashResponse(const SBFullHashResult& full_hash_result) {
298 full_hashes_.clear();
299 full_hashes_.push_back(full_hash_result);
302 void IntroduceDelay(const base::TimeDelta& delay) {
303 delay_ = delay;
306 static int create_count() {
307 return create_count_;
310 static int delete_count() {
311 return delete_count_;
314 private:
315 std::vector<SBFullHashResult> full_hashes_;
316 base::TimeDelta delay_;
317 static int create_count_;
318 static int delete_count_;
321 // static
322 int TestProtocolManager::create_count_ = 0;
323 // static
324 int TestProtocolManager::delete_count_ = 0;
326 // Factory that creates TestProtocolManager instances.
327 class TestSBProtocolManagerFactory : public SBProtocolManagerFactory {
328 public:
329 TestSBProtocolManagerFactory() : pm_(NULL) {}
330 virtual ~TestSBProtocolManagerFactory() {}
332 virtual SafeBrowsingProtocolManager* CreateProtocolManager(
333 SafeBrowsingProtocolManagerDelegate* delegate,
334 net::URLRequestContextGetter* request_context_getter,
335 const SafeBrowsingProtocolConfig& config) OVERRIDE {
336 pm_ = new TestProtocolManager(delegate, request_context_getter, config);
337 return pm_;
340 TestProtocolManager* GetProtocolManager() {
341 return pm_;
344 private:
345 // Owned by the SafebrowsingService.
346 TestProtocolManager* pm_;
349 class MockObserver : public SafeBrowsingUIManager::Observer {
350 public:
351 MockObserver() {}
352 virtual ~MockObserver() {}
353 MOCK_METHOD1(OnSafeBrowsingHit,
354 void(const SafeBrowsingUIManager::UnsafeResource&));
355 MOCK_METHOD1(OnSafeBrowsingMatch,
356 void(const SafeBrowsingUIManager::UnsafeResource&));
359 MATCHER_P(IsUnsafeResourceFor, url, "") {
360 return (arg.url.spec() == url.spec() &&
361 arg.threat_type != SB_THREAT_TYPE_SAFE);
364 } // namespace
366 // Tests the safe browsing blocking page in a browser.
367 class SafeBrowsingServiceTest : public InProcessBrowserTest {
368 public:
369 SafeBrowsingServiceTest() {
372 static void GenUrlFullhashResult(const GURL& url,
373 int list_id,
374 SBFullHashResult* full_hash) {
375 std::string host;
376 std::string path;
377 safe_browsing_util::CanonicalizeUrl(url, &host, &path, NULL);
378 full_hash->hash = SBFullHashForString(host + path);
379 full_hash->list_id = list_id;
382 virtual void SetUp() {
383 // InProcessBrowserTest::SetUp() instantiates SafebrowsingService and
384 // RegisterFactory has to be called before SafeBrowsingService is created.
385 sb_factory_.reset(new TestSafeBrowsingServiceFactory(
386 "https://definatelynotarealdomain/safebrowsing"));
387 SafeBrowsingService::RegisterFactory(sb_factory_.get());
388 SafeBrowsingDatabase::RegisterFactory(&db_factory_);
389 SafeBrowsingProtocolManager::RegisterFactory(&pm_factory_);
390 InProcessBrowserTest::SetUp();
393 virtual void TearDown() {
394 InProcessBrowserTest::TearDown();
396 // Unregister test factories after InProcessBrowserTest::TearDown
397 // (which destructs SafeBrowsingService).
398 SafeBrowsingDatabase::RegisterFactory(NULL);
399 SafeBrowsingProtocolManager::RegisterFactory(NULL);
400 SafeBrowsingService::RegisterFactory(NULL);
403 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
404 // Makes sure the auto update is not triggered during the test.
405 // This test will fill up the database using testing prefixes
406 // and urls.
407 command_line->AppendSwitch(switches::kSbDisableAutoUpdate);
408 #if defined(OS_CHROMEOS)
409 command_line->AppendSwitch(
410 chromeos::switches::kIgnoreUserProfileMappingForTests);
411 #endif
414 virtual void SetUpInProcessBrowserTestFixture() {
415 ASSERT_TRUE(test_server()->Start());
418 // This will setup the "url" prefix in database and prepare protocol manager
419 // to response with |full_hash| for get full hash request.
420 void SetupResponseForUrl(const GURL& url, const SBFullHashResult& full_hash) {
421 std::vector<SBPrefix> prefix_hits;
422 prefix_hits.push_back(full_hash.hash.prefix);
424 // Make sure the full hits is empty unless we need to test the
425 // full hash is hit in database's local cache.
426 TestSafeBrowsingDatabase* db = db_factory_.GetDb();
427 db->AddUrl(url, full_hash.list_id, prefix_hits);
429 TestProtocolManager* pm = pm_factory_.GetProtocolManager();
430 pm->SetGetFullHashResponse(full_hash);
433 bool ShowingInterstitialPage() {
434 WebContents* contents =
435 browser()->tab_strip_model()->GetActiveWebContents();
436 InterstitialPage* interstitial_page = contents->GetInterstitialPage();
437 return interstitial_page != NULL;
440 void IntroduceGetHashDelay(const base::TimeDelta& delay) {
441 pm_factory_.GetProtocolManager()->IntroduceDelay(delay);
444 base::TimeDelta GetCheckTimeout(SafeBrowsingService* sb_service) {
445 return sb_service->database_manager()->check_timeout_;
448 void SetCheckTimeout(SafeBrowsingService* sb_service,
449 const base::TimeDelta& delay) {
450 sb_service->database_manager()->check_timeout_ = delay;
453 void CreateCSDService() {
454 safe_browsing::ClientSideDetectionService* csd_service =
455 safe_browsing::ClientSideDetectionService::Create(NULL);
456 SafeBrowsingService* sb_service =
457 g_browser_process->safe_browsing_service();
458 sb_service->csd_service_.reset(csd_service);
459 sb_service->RefreshState();
462 void ProceedAndWhitelist(
463 const SafeBrowsingUIManager::UnsafeResource& resource) {
464 std::vector<SafeBrowsingUIManager::UnsafeResource> resources;
465 resources.push_back(resource);
466 BrowserThread::PostTask(
467 BrowserThread::IO, FROM_HERE,
468 base::Bind(&SafeBrowsingUIManager::OnBlockingPageDone,
469 g_browser_process->safe_browsing_service()->ui_manager(),
470 resources, true));
471 WaitForIOThread();
474 protected:
475 StrictMock<MockObserver> observer_;
477 // Temporary profile dir for test cases that create a second profile. This is
478 // owned by the SafeBrowsingServiceTest object so that it will not get
479 // destructed until after the test Browser has been torn down, since the
480 // ImportantFileWriter may still be modifying it after the Profile object has
481 // been destroyed.
482 base::ScopedTempDir temp_profile_dir_;
484 // Waits for pending tasks on the IO thread to complete. This is useful
485 // to wait for the SafeBrowsingService to finish loading/stopping.
486 void WaitForIOThread() {
487 scoped_refptr<base::ThreadTestHelper> io_helper(new base::ThreadTestHelper(
488 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO).get()));
489 ASSERT_TRUE(io_helper->Run());
492 private:
493 scoped_ptr<TestSafeBrowsingServiceFactory> sb_factory_;
494 TestSafeBrowsingDatabaseFactory db_factory_;
495 TestSBProtocolManagerFactory pm_factory_;
497 DISALLOW_COPY_AND_ASSIGN(SafeBrowsingServiceTest);
500 namespace {
502 const char kEmptyPage[] = "files/empty.html";
503 const char kMalwareFile[] = "files/downloads/dangerous/dangerous.exe";
504 const char kMalwarePage[] = "files/safe_browsing/malware.html";
506 // This test goes through DownloadResourceHandler.
507 IN_PROC_BROWSER_TEST_F(SafeBrowsingServiceTest, Malware) {
508 GURL url = test_server()->GetURL(kEmptyPage);
509 g_browser_process->safe_browsing_service()->
510 ui_manager()->AddObserver(&observer_);
512 // After adding the url to safebrowsing database and getfullhash result,
513 // we should see the interstitial page.
514 SBFullHashResult malware_full_hash;
515 GenUrlFullhashResult(url, safe_browsing_util::MALWARE, &malware_full_hash);
516 EXPECT_CALL(observer_,
517 OnSafeBrowsingMatch(IsUnsafeResourceFor(url))).Times(1);
518 EXPECT_CALL(observer_, OnSafeBrowsingHit(IsUnsafeResourceFor(url))).Times(1);
519 SetupResponseForUrl(url, malware_full_hash);
520 ui_test_utils::NavigateToURL(browser(), url);
521 EXPECT_TRUE(ShowingInterstitialPage());
522 g_browser_process->safe_browsing_service()->
523 ui_manager()->RemoveObserver(&observer_);
526 IN_PROC_BROWSER_TEST_F(SafeBrowsingServiceTest, DISABLED_MalwareWithWhitelist) {
527 GURL url = test_server()->GetURL(kEmptyPage);
528 g_browser_process->safe_browsing_service()->
529 ui_manager()->AddObserver(&observer_);
531 // After adding the url to safebrowsing database and getfullhash result,
532 // we should see the interstitial page.
533 SBFullHashResult malware_full_hash;
534 GenUrlFullhashResult(url, safe_browsing_util::MALWARE, &malware_full_hash);
535 EXPECT_CALL(observer_,
536 OnSafeBrowsingMatch(IsUnsafeResourceFor(url))).Times(1);
537 EXPECT_CALL(observer_, OnSafeBrowsingHit(IsUnsafeResourceFor(url))).Times(1)
538 .WillOnce(testing::Invoke(
539 this, &SafeBrowsingServiceTest::ProceedAndWhitelist));
540 SetupResponseForUrl(url, malware_full_hash);
542 ui_test_utils::NavigateToURL(browser(), url);
543 // Mock calls OnBlockingPageDone set to proceed, so the interstitial
544 // is removed.
545 EXPECT_FALSE(ShowingInterstitialPage());
546 Mock::VerifyAndClearExpectations(&observer_);
548 // Navigate back to kEmptyPage -- should hit the whitelist, and send a match
549 // call, but no hit call.
550 EXPECT_CALL(observer_,
551 OnSafeBrowsingMatch(IsUnsafeResourceFor(url))).Times(1);
552 EXPECT_CALL(observer_, OnSafeBrowsingHit(IsUnsafeResourceFor(url))).Times(0);
553 ui_test_utils::NavigateToURL(browser(), url);
554 EXPECT_FALSE(ShowingInterstitialPage());
556 g_browser_process->safe_browsing_service()->
557 ui_manager()->RemoveObserver(&observer_);
560 const char kPrefetchMalwarePage[] = "files/safe_browsing/prefetch_malware.html";
562 // This test confirms that prefetches don't themselves get the
563 // interstitial treatment.
564 IN_PROC_BROWSER_TEST_F(SafeBrowsingServiceTest, Prefetch) {
565 GURL url = test_server()->GetURL(kPrefetchMalwarePage);
566 GURL malware_url = test_server()->GetURL(kMalwarePage);
567 g_browser_process->safe_browsing_service()->
568 ui_manager()->AddObserver(&observer_);
570 class SetPrefetchForTest {
571 public:
572 explicit SetPrefetchForTest(bool prefetch)
573 : old_prerender_mode_(prerender::PrerenderManager::GetMode()) {
574 std::string exp_group = prefetch ? "ExperimentYes" : "ExperimentNo";
575 base::FieldTrialList::CreateFieldTrial("Prefetch", exp_group);
577 prerender::PrerenderManager::SetMode(
578 prerender::PrerenderManager::PRERENDER_MODE_DISABLED);
581 ~SetPrefetchForTest() {
582 prerender::PrerenderManager::SetMode(old_prerender_mode_);
585 private:
586 prerender::PrerenderManager::PrerenderManagerMode old_prerender_mode_;
587 } set_prefetch_for_test(true);
589 // Even though we have added this uri to the safebrowsing database and
590 // getfullhash result, we should not see the interstitial page since the
591 // only malware was a prefetch target.
592 SBFullHashResult malware_full_hash;
593 GenUrlFullhashResult(malware_url, safe_browsing_util::MALWARE,
594 &malware_full_hash);
595 SetupResponseForUrl(malware_url, malware_full_hash);
596 ui_test_utils::NavigateToURL(browser(), url);
597 EXPECT_FALSE(ShowingInterstitialPage());
598 Mock::VerifyAndClear(&observer_);
600 // However, when we navigate to the malware page, we should still get
601 // the interstitial.
602 EXPECT_CALL(observer_, OnSafeBrowsingMatch(IsUnsafeResourceFor(malware_url)))
603 .Times(1);
604 EXPECT_CALL(observer_, OnSafeBrowsingHit(IsUnsafeResourceFor(malware_url)))
605 .Times(1);
606 ui_test_utils::NavigateToURL(browser(), malware_url);
607 EXPECT_TRUE(ShowingInterstitialPage());
608 Mock::VerifyAndClear(&observer_);
609 g_browser_process->safe_browsing_service()->
610 ui_manager()->RemoveObserver(&observer_);
613 } // namespace
615 class TestSBClient
616 : public base::RefCountedThreadSafe<TestSBClient>,
617 public SafeBrowsingDatabaseManager::Client {
618 public:
619 TestSBClient()
620 : threat_type_(SB_THREAT_TYPE_SAFE),
621 safe_browsing_service_(g_browser_process->safe_browsing_service()) {
624 SBThreatType GetThreatType() const {
625 return threat_type_;
628 void CheckDownloadUrl(const std::vector<GURL>& url_chain) {
629 BrowserThread::PostTask(
630 BrowserThread::IO, FROM_HERE,
631 base::Bind(&TestSBClient::CheckDownloadUrlOnIOThread,
632 this, url_chain));
633 content::RunMessageLoop(); // Will stop in OnCheckDownloadUrlResult.
636 private:
637 friend class base::RefCountedThreadSafe<TestSBClient>;
638 virtual ~TestSBClient() {}
640 void CheckDownloadUrlOnIOThread(const std::vector<GURL>& url_chain) {
641 safe_browsing_service_->database_manager()->
642 CheckDownloadUrl(url_chain, this);
645 // Called when the result of checking a download URL is known.
646 virtual void OnCheckDownloadUrlResult(const std::vector<GURL>& url_chain,
647 SBThreatType threat_type) OVERRIDE {
648 threat_type_ = threat_type;
649 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
650 base::Bind(&TestSBClient::DownloadCheckDone, this));
653 void DownloadCheckDone() {
654 base::MessageLoopForUI::current()->Quit();
657 SBThreatType threat_type_;
658 SafeBrowsingService* safe_browsing_service_;
660 DISALLOW_COPY_AND_ASSIGN(TestSBClient);
663 // These tests use SafeBrowsingService::Client to directly interact with
664 // SafeBrowsingService.
665 namespace {
667 IN_PROC_BROWSER_TEST_F(SafeBrowsingServiceTest, CheckDownloadUrl) {
668 GURL badbin_url = test_server()->GetURL(kMalwareFile);
669 std::vector<GURL> badbin_urls(1, badbin_url);
671 scoped_refptr<TestSBClient> client(new TestSBClient);
672 client->CheckDownloadUrl(badbin_urls);
674 // Since badbin_url is not in database, it is considered to be safe.
675 EXPECT_EQ(SB_THREAT_TYPE_SAFE, client->GetThreatType());
677 SBFullHashResult full_hash_result;
678 GenUrlFullhashResult(badbin_url, safe_browsing_util::BINURL,
679 &full_hash_result);
680 SetupResponseForUrl(badbin_url, full_hash_result);
682 client->CheckDownloadUrl(badbin_urls);
684 // Now, the badbin_url is not safe since it is added to download database.
685 EXPECT_EQ(SB_THREAT_TYPE_BINARY_MALWARE_URL, client->GetThreatType());
688 IN_PROC_BROWSER_TEST_F(SafeBrowsingServiceTest, CheckDownloadUrlRedirects) {
689 GURL original_url = test_server()->GetURL(kEmptyPage);
690 GURL badbin_url = test_server()->GetURL(kMalwareFile);
691 GURL final_url = test_server()->GetURL(kEmptyPage);
692 std::vector<GURL> badbin_urls;
693 badbin_urls.push_back(original_url);
694 badbin_urls.push_back(badbin_url);
695 badbin_urls.push_back(final_url);
697 scoped_refptr<TestSBClient> client(new TestSBClient);
698 client->CheckDownloadUrl(badbin_urls);
700 // Since badbin_url is not in database, it is considered to be safe.
701 EXPECT_EQ(SB_THREAT_TYPE_SAFE, client->GetThreatType());
703 SBFullHashResult full_hash_result;
704 GenUrlFullhashResult(badbin_url, safe_browsing_util::BINURL,
705 &full_hash_result);
706 SetupResponseForUrl(badbin_url, full_hash_result);
708 client->CheckDownloadUrl(badbin_urls);
710 // Now, the badbin_url is not safe since it is added to download database.
711 EXPECT_EQ(SB_THREAT_TYPE_BINARY_MALWARE_URL, client->GetThreatType());
714 IN_PROC_BROWSER_TEST_F(SafeBrowsingServiceTest, CheckDownloadUrlTimedOut) {
715 GURL badbin_url = test_server()->GetURL(kMalwareFile);
716 std::vector<GURL> badbin_urls(1, badbin_url);
718 scoped_refptr<TestSBClient> client(new TestSBClient);
719 SBFullHashResult full_hash_result;
720 GenUrlFullhashResult(badbin_url, safe_browsing_util::BINURL,
721 &full_hash_result);
722 SetupResponseForUrl(badbin_url, full_hash_result);
723 client->CheckDownloadUrl(badbin_urls);
725 // badbin_url is not safe since it is added to download database.
726 EXPECT_EQ(SB_THREAT_TYPE_BINARY_MALWARE_URL, client->GetThreatType());
729 // Now introducing delays and we should hit timeout.
731 SafeBrowsingService* sb_service = g_browser_process->safe_browsing_service();
732 base::TimeDelta default_urlcheck_timeout = GetCheckTimeout(sb_service);
733 IntroduceGetHashDelay(base::TimeDelta::FromSeconds(1));
734 SetCheckTimeout(sb_service, base::TimeDelta::FromMilliseconds(1));
735 client->CheckDownloadUrl(badbin_urls);
737 // There should be a timeout and the hash would be considered as safe.
738 EXPECT_EQ(SB_THREAT_TYPE_SAFE, client->GetThreatType());
740 // Need to set the timeout back to the default value.
741 SetCheckTimeout(sb_service, default_urlcheck_timeout);
744 IN_PROC_BROWSER_TEST_F(SafeBrowsingServiceTest, StartAndStop) {
745 CreateCSDService();
746 SafeBrowsingService* sb_service = g_browser_process->safe_browsing_service();
747 safe_browsing::ClientSideDetectionService* csd_service =
748 sb_service->safe_browsing_detection_service();
749 PrefService* pref_service = browser()->profile()->GetPrefs();
751 ASSERT_TRUE(sb_service != NULL);
752 ASSERT_TRUE(csd_service != NULL);
753 ASSERT_TRUE(pref_service != NULL);
755 EXPECT_TRUE(pref_service->GetBoolean(prefs::kSafeBrowsingEnabled));
757 // SBS might still be starting, make sure this doesn't flake.
758 WaitForIOThread();
759 EXPECT_TRUE(sb_service->enabled());
760 EXPECT_TRUE(csd_service->enabled());
762 // Add a new Profile. SBS should keep running.
763 ASSERT_TRUE(temp_profile_dir_.CreateUniqueTempDir());
764 scoped_ptr<Profile> profile2(Profile::CreateProfile(
765 temp_profile_dir_.path(), NULL, Profile::CREATE_MODE_SYNCHRONOUS));
766 ASSERT_TRUE(profile2.get() != NULL);
767 StartupTaskRunnerServiceFactory::GetForProfile(profile2.get())->
768 StartDeferredTaskRunners();
769 PrefService* pref_service2 = profile2->GetPrefs();
770 EXPECT_TRUE(pref_service2->GetBoolean(prefs::kSafeBrowsingEnabled));
771 // We don't expect the state to have changed, but if it did, wait for it.
772 WaitForIOThread();
773 EXPECT_TRUE(sb_service->enabled());
774 EXPECT_TRUE(csd_service->enabled());
776 // Change one of the prefs. SBS should keep running.
777 pref_service->SetBoolean(prefs::kSafeBrowsingEnabled, false);
778 WaitForIOThread();
779 EXPECT_TRUE(sb_service->enabled());
780 EXPECT_TRUE(csd_service->enabled());
782 // Change the other pref. SBS should stop now.
783 pref_service2->SetBoolean(prefs::kSafeBrowsingEnabled, false);
784 WaitForIOThread();
785 EXPECT_FALSE(sb_service->enabled());
786 EXPECT_FALSE(csd_service->enabled());
788 // Turn it back on. SBS comes back.
789 pref_service2->SetBoolean(prefs::kSafeBrowsingEnabled, true);
790 WaitForIOThread();
791 EXPECT_TRUE(sb_service->enabled());
792 EXPECT_TRUE(csd_service->enabled());
794 // Delete the Profile. SBS stops again.
795 pref_service2 = NULL;
796 profile2.reset();
797 WaitForIOThread();
798 EXPECT_FALSE(sb_service->enabled());
799 EXPECT_FALSE(csd_service->enabled());
802 } // namespace
804 class SafeBrowsingServiceShutdownTest : public SafeBrowsingServiceTest {
805 public:
806 virtual void TearDown() OVERRIDE {
807 // Browser should be fully torn down by now, so we can safely check these
808 // counters.
809 EXPECT_EQ(1, TestProtocolManager::create_count());
810 EXPECT_EQ(1, TestProtocolManager::delete_count());
812 SafeBrowsingServiceTest::TearDown();
815 // An observer that returns back to test code after a new profile is
816 // initialized.
817 void OnUnblockOnProfileCreation(Profile* profile,
818 Profile::CreateStatus status) {
819 if (status == Profile::CREATE_STATUS_INITIALIZED) {
820 profile2_ = profile;
821 base::MessageLoop::current()->Quit();
825 protected:
826 Profile* profile2_;
829 IN_PROC_BROWSER_TEST_F(SafeBrowsingServiceShutdownTest,
830 DontStartAfterShutdown) {
831 CreateCSDService();
832 SafeBrowsingService* sb_service = g_browser_process->safe_browsing_service();
833 safe_browsing::ClientSideDetectionService* csd_service =
834 sb_service->safe_browsing_detection_service();
835 PrefService* pref_service = browser()->profile()->GetPrefs();
837 ASSERT_TRUE(sb_service != NULL);
838 ASSERT_TRUE(csd_service != NULL);
839 ASSERT_TRUE(pref_service != NULL);
841 EXPECT_TRUE(pref_service->GetBoolean(prefs::kSafeBrowsingEnabled));
843 // SBS might still be starting, make sure this doesn't flake.
844 WaitForIOThread();
845 EXPECT_EQ(1, TestProtocolManager::create_count());
846 EXPECT_EQ(0, TestProtocolManager::delete_count());
848 // Create an additional profile. We need to use the ProfileManager so that
849 // the profile will get destroyed in the normal browser shutdown process.
850 ProfileManager* profile_manager = g_browser_process->profile_manager();
851 ASSERT_TRUE(temp_profile_dir_.CreateUniqueTempDir());
852 profile_manager->CreateProfileAsync(
853 temp_profile_dir_.path(),
854 base::Bind(&SafeBrowsingServiceShutdownTest::OnUnblockOnProfileCreation,
855 this),
856 base::string16(), base::string16(), std::string());
858 // Spin to allow profile creation to take place, loop is terminated
859 // by OnUnblockOnProfileCreation when the profile is created.
860 content::RunMessageLoop();
862 PrefService* pref_service2 = profile2_->GetPrefs();
863 EXPECT_TRUE(pref_service2->GetBoolean(prefs::kSafeBrowsingEnabled));
865 // We don't expect the state to have changed, but if it did, wait for it.
866 WaitForIOThread();
867 EXPECT_EQ(1, TestProtocolManager::create_count());
868 EXPECT_EQ(0, TestProtocolManager::delete_count());
870 // End the test, shutting down the browser.
871 // SafeBrowsingServiceShutdownTest::TearDown will check the create_count and
872 // delete_count again.
875 class SafeBrowsingDatabaseManagerCookieTest : public InProcessBrowserTest {
876 public:
877 SafeBrowsingDatabaseManagerCookieTest() {}
879 virtual void SetUp() OVERRIDE {
880 // We need to start the test server to get the host&port in the url.
881 ASSERT_TRUE(test_server()->Start());
883 // Point to the testing server for all SafeBrowsing requests.
884 GURL url_prefix = test_server()->GetURL(
885 "expect-and-set-cookie?expect=a%3db"
886 "&set=c%3dd%3b%20Expires=Fri,%2001%20Jan%202038%2001:01:01%20GMT"
887 "&data=foo#");
888 sb_factory_.reset(new TestSafeBrowsingServiceFactory(url_prefix.spec()));
889 SafeBrowsingService::RegisterFactory(sb_factory_.get());
891 InProcessBrowserTest::SetUp();
894 virtual void TearDown() OVERRIDE {
895 InProcessBrowserTest::TearDown();
897 SafeBrowsingService::RegisterFactory(NULL);
900 virtual bool SetUpUserDataDirectory() OVERRIDE {
901 base::FilePath cookie_path(
902 SafeBrowsingService::GetCookieFilePathForTesting());
903 EXPECT_FALSE(base::PathExists(cookie_path));
905 base::FilePath test_dir;
906 if (!PathService::Get(chrome::DIR_TEST_DATA, &test_dir)) {
907 EXPECT_TRUE(false);
908 return false;
911 // Initialize the SafeBrowsing cookies with a pre-created cookie store. It
912 // contains a single cookie, for domain 127.0.0.1, with value a=b, and
913 // expires in 2038.
914 base::FilePath initial_cookies = test_dir.AppendASCII("safe_browsing")
915 .AppendASCII("Safe Browsing Cookies");
916 if (!base::CopyFile(initial_cookies, cookie_path)) {
917 EXPECT_TRUE(false);
918 return false;
921 sql::Connection db;
922 if (!db.Open(cookie_path)) {
923 EXPECT_TRUE(false);
924 return false;
926 // Ensure the host value in the cookie file matches the test server we will
927 // be connecting to.
928 sql::Statement smt(db.GetUniqueStatement(
929 "UPDATE cookies SET host_key = ?"));
930 if (!smt.is_valid()) {
931 EXPECT_TRUE(false);
932 return false;
934 if (!smt.BindString(0, test_server()->host_port_pair().host())) {
935 EXPECT_TRUE(false);
936 return false;
938 if (!smt.Run()) {
939 EXPECT_TRUE(false);
940 return false;
943 return InProcessBrowserTest::SetUpUserDataDirectory();
946 virtual void TearDownInProcessBrowserTestFixture() OVERRIDE {
947 InProcessBrowserTest::TearDownInProcessBrowserTestFixture();
949 sql::Connection db;
950 base::FilePath cookie_path(
951 SafeBrowsingService::GetCookieFilePathForTesting());
952 ASSERT_TRUE(db.Open(cookie_path));
954 sql::Statement smt(db.GetUniqueStatement(
955 "SELECT name, value FROM cookies ORDER BY name"));
956 ASSERT_TRUE(smt.is_valid());
958 ASSERT_TRUE(smt.Step());
959 ASSERT_EQ("a", smt.ColumnString(0));
960 ASSERT_EQ("b", smt.ColumnString(1));
961 ASSERT_TRUE(smt.Step());
962 ASSERT_EQ("c", smt.ColumnString(0));
963 ASSERT_EQ("d", smt.ColumnString(1));
964 EXPECT_FALSE(smt.Step());
967 virtual void SetUpOnMainThread() OVERRIDE {
968 sb_service_ = g_browser_process->safe_browsing_service();
969 ASSERT_TRUE(sb_service_.get() != NULL);
972 virtual void CleanUpOnMainThread() OVERRIDE {
973 sb_service_ = NULL;
976 void ForceUpdate() {
977 sb_service_->protocol_manager()->ForceScheduleNextUpdate(
978 base::TimeDelta::FromSeconds(0));
981 scoped_refptr<SafeBrowsingService> sb_service_;
983 private:
984 scoped_ptr<TestSafeBrowsingServiceFactory> sb_factory_;
986 DISALLOW_COPY_AND_ASSIGN(SafeBrowsingDatabaseManagerCookieTest);
989 // Test that a Safe Browsing database update request both sends cookies and can
990 // save cookies.
991 IN_PROC_BROWSER_TEST_F(SafeBrowsingDatabaseManagerCookieTest,
992 TestSBUpdateCookies) {
993 content::WindowedNotificationObserver observer(
994 chrome::NOTIFICATION_SAFE_BROWSING_UPDATE_COMPLETE,
995 content::Source<SafeBrowsingDatabaseManager>(
996 sb_service_->database_manager().get()));
997 BrowserThread::PostTask(
998 BrowserThread::IO,
999 FROM_HERE,
1000 base::Bind(&SafeBrowsingDatabaseManagerCookieTest::ForceUpdate, this));
1001 observer.Wait();