Cast: Stop logging kVideoFrameSentToEncoder and rename a couple events.
[chromium-blink-merge.git] / chrome / browser / safe_browsing / safe_browsing_service_browsertest.cc
blobab6d68d178a6965282dcea46fc6638d3cb4fdfb1
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/files/file_path.h"
13 #include "base/files/scoped_temp_dir.h"
14 #include "base/memory/ref_counted.h"
15 #include "base/metrics/field_trial.h"
16 #include "base/path_service.h"
17 #include "base/prefs/pref_service.h"
18 #include "base/strings/string_split.h"
19 #include "base/test/thread_test_helper.h"
20 #include "base/time/time.h"
21 #include "chrome/browser/browser_process.h"
22 #include "chrome/browser/chrome_notification_types.h"
23 #include "chrome/browser/prerender/prerender_manager.h"
24 #include "chrome/browser/profiles/profile.h"
25 #include "chrome/browser/profiles/profile_manager.h"
26 #include "chrome/browser/profiles/startup_task_runner_service.h"
27 #include "chrome/browser/profiles/startup_task_runner_service_factory.h"
28 #include "chrome/browser/safe_browsing/client_side_detection_service.h"
29 #include "chrome/browser/safe_browsing/database_manager.h"
30 #include "chrome/browser/safe_browsing/protocol_manager.h"
31 #include "chrome/browser/safe_browsing/safe_browsing_database.h"
32 #include "chrome/browser/safe_browsing/safe_browsing_service.h"
33 #include "chrome/browser/safe_browsing/safe_browsing_util.h"
34 #include "chrome/browser/safe_browsing/ui_manager.h"
35 #include "chrome/browser/ui/browser.h"
36 #include "chrome/browser/ui/tabs/tab_strip_model.h"
37 #include "chrome/common/chrome_paths.h"
38 #include "chrome/common/pref_names.h"
39 #include "chrome/test/base/in_process_browser_test.h"
40 #include "chrome/test/base/ui_test_utils.h"
41 #include "content/public/browser/web_contents.h"
42 #include "net/cookies/cookie_store.h"
43 #include "sql/connection.h"
44 #include "sql/statement.h"
45 #include "testing/gmock/include/gmock/gmock.h"
47 using content::BrowserThread;
48 using content::InterstitialPage;
49 using content::WebContents;
50 using ::testing::_;
51 using ::testing::Mock;
52 using ::testing::StrictMock;
54 namespace {
56 void InvokeFullHashCallback(
57 SafeBrowsingProtocolManager::FullHashCallback callback,
58 const std::vector<SBFullHashResult>& result) {
59 callback.Run(result, true);
62 class FakeSafeBrowsingService : public SafeBrowsingService {
63 public:
64 explicit FakeSafeBrowsingService(const std::string& url_prefix)
65 : url_prefix_(url_prefix) {}
67 virtual SafeBrowsingProtocolConfig GetProtocolConfig() const OVERRIDE {
68 SafeBrowsingProtocolConfig config;
69 config.url_prefix = url_prefix_;
70 // Makes sure the auto update is not triggered. The tests will force the
71 // update when needed.
72 config.disable_auto_update = true;
73 config.client_name = "browser_tests";
74 return config;
77 private:
78 virtual ~FakeSafeBrowsingService() {}
80 std::string url_prefix_;
82 DISALLOW_COPY_AND_ASSIGN(FakeSafeBrowsingService);
85 // Factory that creates FakeSafeBrowsingService instances.
86 class TestSafeBrowsingServiceFactory : public SafeBrowsingServiceFactory {
87 public:
88 explicit TestSafeBrowsingServiceFactory(const std::string& url_prefix)
89 : url_prefix_(url_prefix) {}
91 virtual SafeBrowsingService* CreateSafeBrowsingService() OVERRIDE {
92 return new FakeSafeBrowsingService(url_prefix_);
95 private:
96 std::string url_prefix_;
99 // A SafeBrowingDatabase class that allows us to inject the malicious URLs.
100 class TestSafeBrowsingDatabase : public SafeBrowsingDatabase {
101 public:
102 TestSafeBrowsingDatabase() {}
104 virtual ~TestSafeBrowsingDatabase() {}
106 // Initializes the database with the given filename.
107 virtual void Init(const base::FilePath& filename) OVERRIDE {}
109 // Deletes the current database and creates a new one.
110 virtual bool ResetDatabase() OVERRIDE {
111 badurls_.clear();
112 return true;
115 // Called on the IO thread to check if the given URL is safe or not. If we
116 // can synchronously determine that the URL is safe, CheckUrl returns true,
117 // otherwise it returns false.
118 virtual bool ContainsBrowseUrl(const GURL& url,
119 std::vector<SBPrefix>* prefix_hits,
120 std::vector<SBFullHashResult>* cached_hits,
121 base::Time last_update) OVERRIDE {
122 std::vector<GURL> urls(1, url);
123 return ContainsUrl(safe_browsing_util::MALWARE,
124 safe_browsing_util::PHISH,
125 urls, prefix_hits, cached_hits);
127 virtual bool ContainsDownloadUrl(
128 const std::vector<GURL>& urls,
129 std::vector<SBPrefix>* prefix_hits) OVERRIDE {
130 std::vector<SBFullHashResult> full_hits;
131 bool found = ContainsUrl(safe_browsing_util::BINURL,
132 safe_browsing_util::BINURL,
133 urls, prefix_hits, &full_hits);
134 if (!found)
135 return false;
136 DCHECK_LE(1U, prefix_hits->size());
137 return true;
139 virtual bool ContainsCsdWhitelistedUrl(const GURL& url) OVERRIDE {
140 return true;
142 virtual bool ContainsDownloadWhitelistedString(
143 const std::string& str) OVERRIDE {
144 return true;
146 virtual bool ContainsDownloadWhitelistedUrl(const GURL& url) OVERRIDE {
147 return true;
149 virtual bool ContainsExtensionPrefixes(
150 const std::vector<SBPrefix>& prefixes,
151 std::vector<SBPrefix>* prefix_hits) OVERRIDE {
152 return true;
154 virtual bool ContainsSideEffectFreeWhitelistUrl(const GURL& url) OVERRIDE {
155 return true;
157 virtual bool ContainsMalwareIP(const std::string& ip_address) OVERRIDE {
158 return true;
160 virtual bool UpdateStarted(std::vector<SBListChunkRanges>* lists) OVERRIDE {
161 ADD_FAILURE() << "Not implemented.";
162 return false;
164 virtual void InsertChunks(const std::string& list_name,
165 const SBChunkList& chunks) OVERRIDE {
166 ADD_FAILURE() << "Not implemented.";
168 virtual void DeleteChunks(
169 const std::vector<SBChunkDelete>& chunk_deletes) OVERRIDE {
170 ADD_FAILURE() << "Not implemented.";
172 virtual void UpdateFinished(bool update_succeeded) OVERRIDE {
173 ADD_FAILURE() << "Not implemented.";
175 virtual void CacheHashResults(const std::vector<SBPrefix>& prefixes,
176 const std::vector<SBFullHashResult>& full_hits) OVERRIDE {
177 // Do nothing for the cache.
179 virtual bool IsMalwareIPMatchKillSwitchOn() OVERRIDE {
180 return false;
183 // Fill up the database with test URL.
184 void AddUrl(const GURL& url,
185 int list_id,
186 const std::vector<SBPrefix>& prefix_hits,
187 const std::vector<SBFullHashResult>& full_hits) {
188 badurls_[url.spec()].list_id = list_id;
189 badurls_[url.spec()].prefix_hits = prefix_hits;
190 badurls_[url.spec()].full_hits = full_hits;
193 // Fill up the database with test hash digest.
194 void AddDownloadPrefix(SBPrefix prefix) {
195 download_digest_prefix_.insert(prefix);
198 private:
199 struct Hits {
200 int list_id;
201 std::vector<SBPrefix> prefix_hits;
202 std::vector<SBFullHashResult> full_hits;
205 bool ContainsUrl(int list_id0,
206 int list_id1,
207 const std::vector<GURL>& urls,
208 std::vector<SBPrefix>* prefix_hits,
209 std::vector<SBFullHashResult>* full_hits) {
210 bool hit = false;
211 for (size_t i = 0; i < urls.size(); ++i) {
212 const GURL& url = urls[i];
213 base::hash_map<std::string, Hits>::const_iterator
214 badurls_it = badurls_.find(url.spec());
216 if (badurls_it == badurls_.end())
217 continue;
219 if (badurls_it->second.list_id == list_id0 ||
220 badurls_it->second.list_id == list_id1) {
221 prefix_hits->insert(prefix_hits->end(),
222 badurls_it->second.prefix_hits.begin(),
223 badurls_it->second.prefix_hits.end());
224 full_hits->insert(full_hits->end(),
225 badurls_it->second.full_hits.begin(),
226 badurls_it->second.full_hits.end());
227 hit = true;
231 return hit;
234 base::hash_map<std::string, Hits> badurls_;
235 base::hash_set<SBPrefix> download_digest_prefix_;
238 // Factory that creates TestSafeBrowsingDatabase instances.
239 class TestSafeBrowsingDatabaseFactory : public SafeBrowsingDatabaseFactory {
240 public:
241 TestSafeBrowsingDatabaseFactory() : db_(NULL) {}
242 virtual ~TestSafeBrowsingDatabaseFactory() {}
244 virtual SafeBrowsingDatabase* CreateSafeBrowsingDatabase(
245 bool enable_download_protection,
246 bool enable_client_side_whitelist,
247 bool enable_download_whitelist,
248 bool enable_extension_blacklist,
249 bool enable_side_effect_free_whitelist,
250 bool enable_ip_blacklist) OVERRIDE {
251 db_ = new TestSafeBrowsingDatabase();
252 return db_;
254 TestSafeBrowsingDatabase* GetDb() {
255 return db_;
257 private:
258 // Owned by the SafebrowsingService.
259 TestSafeBrowsingDatabase* db_;
262 // A TestProtocolManager that could return fixed responses from
263 // safebrowsing server for testing purpose.
264 class TestProtocolManager : public SafeBrowsingProtocolManager {
265 public:
266 TestProtocolManager(SafeBrowsingProtocolManagerDelegate* delegate,
267 net::URLRequestContextGetter* request_context_getter,
268 const SafeBrowsingProtocolConfig& config)
269 : SafeBrowsingProtocolManager(delegate, request_context_getter, config) {
270 create_count_++;
273 virtual ~TestProtocolManager() {
274 delete_count_++;
277 // This function is called when there is a prefix hit in local safebrowsing
278 // database and safebrowsing service issues a get hash request to backends.
279 // We return a result from the prefilled full_hashes_ hash_map to simulate
280 // server's response. At the same time, latency is added to simulate real
281 // life network issues.
282 virtual void GetFullHash(
283 const std::vector<SBPrefix>& prefixes,
284 SafeBrowsingProtocolManager::FullHashCallback callback,
285 bool is_download) OVERRIDE {
286 BrowserThread::PostDelayedTask(
287 BrowserThread::IO, FROM_HERE,
288 base::Bind(InvokeFullHashCallback, callback, full_hashes_),
289 delay_);
292 // Prepare the GetFullHash results for the next request.
293 void SetGetFullHashResponse(const SBFullHashResult& full_hash_result) {
294 full_hashes_.clear();
295 full_hashes_.push_back(full_hash_result);
298 void IntroduceDelay(const base::TimeDelta& delay) {
299 delay_ = delay;
302 static int create_count() {
303 return create_count_;
306 static int delete_count() {
307 return delete_count_;
310 private:
311 std::vector<SBFullHashResult> full_hashes_;
312 base::TimeDelta delay_;
313 static int create_count_;
314 static int delete_count_;
317 // static
318 int TestProtocolManager::create_count_ = 0;
319 // static
320 int TestProtocolManager::delete_count_ = 0;
322 // Factory that creates TestProtocolManager instances.
323 class TestSBProtocolManagerFactory : public SBProtocolManagerFactory {
324 public:
325 TestSBProtocolManagerFactory() : pm_(NULL) {}
326 virtual ~TestSBProtocolManagerFactory() {}
328 virtual SafeBrowsingProtocolManager* CreateProtocolManager(
329 SafeBrowsingProtocolManagerDelegate* delegate,
330 net::URLRequestContextGetter* request_context_getter,
331 const SafeBrowsingProtocolConfig& config) OVERRIDE {
332 pm_ = new TestProtocolManager(delegate, request_context_getter, config);
333 return pm_;
336 TestProtocolManager* GetProtocolManager() {
337 return pm_;
340 private:
341 // Owned by the SafebrowsingService.
342 TestProtocolManager* pm_;
345 class MockObserver : public SafeBrowsingUIManager::Observer {
346 public:
347 MockObserver() {}
348 virtual ~MockObserver() {}
349 MOCK_METHOD1(OnSafeBrowsingHit,
350 void(const SafeBrowsingUIManager::UnsafeResource&));
351 MOCK_METHOD1(OnSafeBrowsingMatch,
352 void(const SafeBrowsingUIManager::UnsafeResource&));
355 MATCHER_P(IsUnsafeResourceFor, url, "") {
356 return (arg.url.spec() == url.spec() &&
357 arg.threat_type != SB_THREAT_TYPE_SAFE);
360 } // namespace
362 // Tests the safe browsing blocking page in a browser.
363 class SafeBrowsingServiceTest : public InProcessBrowserTest {
364 public:
365 SafeBrowsingServiceTest() {
368 static void GenUrlFullhashResult(const GURL& url,
369 int list_id,
370 SBFullHashResult* full_hash) {
371 std::string host;
372 std::string path;
373 safe_browsing_util::CanonicalizeUrl(url, &host, &path, NULL);
374 full_hash->hash = SBFullHashForString(host + path);
375 full_hash->list_id = list_id;
378 virtual void SetUp() {
379 // InProcessBrowserTest::SetUp() instantiates SafebrowsingService and
380 // RegisterFactory has to be called before SafeBrowsingService is created.
381 sb_factory_.reset(new TestSafeBrowsingServiceFactory(
382 "https://definatelynotarealdomain/safebrowsing"));
383 SafeBrowsingService::RegisterFactory(sb_factory_.get());
384 SafeBrowsingDatabase::RegisterFactory(&db_factory_);
385 SafeBrowsingProtocolManager::RegisterFactory(&pm_factory_);
386 InProcessBrowserTest::SetUp();
389 virtual void TearDown() {
390 InProcessBrowserTest::TearDown();
392 // Unregister test factories after InProcessBrowserTest::TearDown
393 // (which destructs SafeBrowsingService).
394 SafeBrowsingDatabase::RegisterFactory(NULL);
395 SafeBrowsingProtocolManager::RegisterFactory(NULL);
396 SafeBrowsingService::RegisterFactory(NULL);
399 virtual void SetUpInProcessBrowserTestFixture() {
400 ASSERT_TRUE(test_server()->Start());
403 // This will setup the "url" prefix in database and prepare protocol manager
404 // to response with |full_hash| for get full hash request.
405 void SetupResponseForUrl(const GURL& url, const SBFullHashResult& full_hash) {
406 std::vector<SBPrefix> prefix_hits;
407 prefix_hits.push_back(full_hash.hash.prefix);
409 // Make sure the full hits is empty unless we need to test the
410 // full hash is hit in database's local cache.
411 std::vector<SBFullHashResult> empty_full_hits;
412 TestSafeBrowsingDatabase* db = db_factory_.GetDb();
413 db->AddUrl(url, full_hash.list_id, prefix_hits, empty_full_hits);
415 TestProtocolManager* pm = pm_factory_.GetProtocolManager();
416 pm->SetGetFullHashResponse(full_hash);
419 // This will setup the binary digest prefix in database and prepare protocol
420 // manager to respond with the result hash.
421 void SetupResponseForDigest(const std::string& digest,
422 const SBFullHashResult& hash_result) {
423 TestSafeBrowsingDatabase* db = db_factory_.GetDb();
424 db->AddDownloadPrefix(
425 safe_browsing_util::StringToSBFullHash(digest).prefix);
427 TestProtocolManager* pm = pm_factory_.GetProtocolManager();
428 pm->SetGetFullHashResponse(hash_result);
431 bool ShowingInterstitialPage() {
432 WebContents* contents =
433 browser()->tab_strip_model()->GetActiveWebContents();
434 InterstitialPage* interstitial_page = contents->GetInterstitialPage();
435 return interstitial_page != NULL;
438 void IntroduceGetHashDelay(const base::TimeDelta& delay) {
439 pm_factory_.GetProtocolManager()->IntroduceDelay(delay);
442 base::TimeDelta GetCheckTimeout(SafeBrowsingService* sb_service) {
443 return sb_service->database_manager()->check_timeout_;
446 void SetCheckTimeout(SafeBrowsingService* sb_service,
447 const base::TimeDelta& delay) {
448 sb_service->database_manager()->check_timeout_ = delay;
451 void CreateCSDService() {
452 safe_browsing::ClientSideDetectionService* csd_service =
453 safe_browsing::ClientSideDetectionService::Create(NULL);
454 SafeBrowsingService* sb_service =
455 g_browser_process->safe_browsing_service();
456 sb_service->csd_service_.reset(csd_service);
457 sb_service->RefreshState();
460 void ProceedAndWhitelist(
461 const SafeBrowsingUIManager::UnsafeResource& resource) {
462 std::vector<SafeBrowsingUIManager::UnsafeResource> resources;
463 resources.push_back(resource);
464 BrowserThread::PostTask(
465 BrowserThread::IO, FROM_HERE,
466 base::Bind(&SafeBrowsingUIManager::OnBlockingPageDone,
467 g_browser_process->safe_browsing_service()->ui_manager(),
468 resources, true));
469 WaitForIOThread();
472 protected:
473 StrictMock<MockObserver> observer_;
475 // Temporary profile dir for test cases that create a second profile. This is
476 // owned by the SafeBrowsingServiceTest object so that it will not get
477 // destructed until after the test Browser has been torn down, since the
478 // ImportantFileWriter may still be modifying it after the Profile object has
479 // been destroyed.
480 base::ScopedTempDir temp_profile_dir_;
482 // Waits for pending tasks on the IO thread to complete. This is useful
483 // to wait for the SafeBrowsingService to finish loading/stopping.
484 void WaitForIOThread() {
485 scoped_refptr<base::ThreadTestHelper> io_helper(new base::ThreadTestHelper(
486 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO).get()));
487 ASSERT_TRUE(io_helper->Run());
490 private:
491 scoped_ptr<TestSafeBrowsingServiceFactory> sb_factory_;
492 TestSafeBrowsingDatabaseFactory db_factory_;
493 TestSBProtocolManagerFactory pm_factory_;
495 DISALLOW_COPY_AND_ASSIGN(SafeBrowsingServiceTest);
498 namespace {
500 const char kEmptyPage[] = "files/empty.html";
501 const char kMalwareFile[] = "files/downloads/dangerous/dangerous.exe";
502 const char kMalwarePage[] = "files/safe_browsing/malware.html";
504 // This test goes through DownloadResourceHandler.
505 IN_PROC_BROWSER_TEST_F(SafeBrowsingServiceTest, Malware) {
506 GURL url = test_server()->GetURL(kEmptyPage);
507 g_browser_process->safe_browsing_service()->
508 ui_manager()->AddObserver(&observer_);
510 // After adding the url to safebrowsing database and getfullhash result,
511 // we should see the interstitial page.
512 SBFullHashResult malware_full_hash;
513 GenUrlFullhashResult(url, safe_browsing_util::MALWARE, &malware_full_hash);
514 EXPECT_CALL(observer_,
515 OnSafeBrowsingMatch(IsUnsafeResourceFor(url))).Times(1);
516 EXPECT_CALL(observer_, OnSafeBrowsingHit(IsUnsafeResourceFor(url))).Times(1);
517 SetupResponseForUrl(url, malware_full_hash);
518 ui_test_utils::NavigateToURL(browser(), url);
519 EXPECT_TRUE(ShowingInterstitialPage());
520 g_browser_process->safe_browsing_service()->
521 ui_manager()->RemoveObserver(&observer_);
524 IN_PROC_BROWSER_TEST_F(SafeBrowsingServiceTest, DISABLED_MalwareWithWhitelist) {
525 GURL url = test_server()->GetURL(kEmptyPage);
526 g_browser_process->safe_browsing_service()->
527 ui_manager()->AddObserver(&observer_);
529 // After adding the url to safebrowsing database and getfullhash result,
530 // we should see the interstitial page.
531 SBFullHashResult malware_full_hash;
532 GenUrlFullhashResult(url, safe_browsing_util::MALWARE, &malware_full_hash);
533 EXPECT_CALL(observer_,
534 OnSafeBrowsingMatch(IsUnsafeResourceFor(url))).Times(1);
535 EXPECT_CALL(observer_, OnSafeBrowsingHit(IsUnsafeResourceFor(url))).Times(1)
536 .WillOnce(testing::Invoke(
537 this, &SafeBrowsingServiceTest::ProceedAndWhitelist));
538 SetupResponseForUrl(url, malware_full_hash);
540 ui_test_utils::NavigateToURL(browser(), url);
541 // Mock calls OnBlockingPageDone set to proceed, so the interstitial
542 // is removed.
543 EXPECT_FALSE(ShowingInterstitialPage());
544 Mock::VerifyAndClearExpectations(&observer_);
546 // Navigate back to kEmptyPage -- should hit the whitelist, and send a match
547 // call, but no hit call.
548 EXPECT_CALL(observer_,
549 OnSafeBrowsingMatch(IsUnsafeResourceFor(url))).Times(1);
550 EXPECT_CALL(observer_, OnSafeBrowsingHit(IsUnsafeResourceFor(url))).Times(0);
551 ui_test_utils::NavigateToURL(browser(), url);
552 EXPECT_FALSE(ShowingInterstitialPage());
554 g_browser_process->safe_browsing_service()->
555 ui_manager()->RemoveObserver(&observer_);
558 const char kPrefetchMalwarePage[] = "files/safe_browsing/prefetch_malware.html";
560 // This test confirms that prefetches don't themselves get the
561 // interstitial treatment.
562 IN_PROC_BROWSER_TEST_F(SafeBrowsingServiceTest, Prefetch) {
563 GURL url = test_server()->GetURL(kPrefetchMalwarePage);
564 GURL malware_url = test_server()->GetURL(kMalwarePage);
565 g_browser_process->safe_browsing_service()->
566 ui_manager()->AddObserver(&observer_);
568 class SetPrefetchForTest {
569 public:
570 explicit SetPrefetchForTest(bool prefetch)
571 : old_prerender_mode_(prerender::PrerenderManager::GetMode()) {
572 std::string exp_group = prefetch ? "ExperimentYes" : "ExperimentNo";
573 base::FieldTrialList::CreateFieldTrial("Prefetch", exp_group);
575 prerender::PrerenderManager::SetMode(
576 prerender::PrerenderManager::PRERENDER_MODE_DISABLED);
579 ~SetPrefetchForTest() {
580 prerender::PrerenderManager::SetMode(old_prerender_mode_);
583 private:
584 prerender::PrerenderManager::PrerenderManagerMode old_prerender_mode_;
585 } set_prefetch_for_test(true);
587 // Even though we have added this uri to the safebrowsing database and
588 // getfullhash result, we should not see the interstitial page since the
589 // only malware was a prefetch target.
590 SBFullHashResult malware_full_hash;
591 GenUrlFullhashResult(malware_url, safe_browsing_util::MALWARE,
592 &malware_full_hash);
593 SetupResponseForUrl(malware_url, malware_full_hash);
594 ui_test_utils::NavigateToURL(browser(), url);
595 EXPECT_FALSE(ShowingInterstitialPage());
596 Mock::VerifyAndClear(&observer_);
598 // However, when we navigate to the malware page, we should still get
599 // the interstitial.
600 EXPECT_CALL(observer_, OnSafeBrowsingMatch(IsUnsafeResourceFor(malware_url)))
601 .Times(1);
602 EXPECT_CALL(observer_, OnSafeBrowsingHit(IsUnsafeResourceFor(malware_url)))
603 .Times(1);
604 ui_test_utils::NavigateToURL(browser(), malware_url);
605 EXPECT_TRUE(ShowingInterstitialPage());
606 Mock::VerifyAndClear(&observer_);
607 g_browser_process->safe_browsing_service()->
608 ui_manager()->RemoveObserver(&observer_);
611 } // namespace
613 class TestSBClient
614 : public base::RefCountedThreadSafe<TestSBClient>,
615 public SafeBrowsingDatabaseManager::Client {
616 public:
617 TestSBClient()
618 : threat_type_(SB_THREAT_TYPE_SAFE),
619 safe_browsing_service_(g_browser_process->safe_browsing_service()) {
622 SBThreatType GetThreatType() const {
623 return threat_type_;
626 void CheckDownloadUrl(const std::vector<GURL>& url_chain) {
627 BrowserThread::PostTask(
628 BrowserThread::IO, FROM_HERE,
629 base::Bind(&TestSBClient::CheckDownloadUrlOnIOThread,
630 this, url_chain));
631 content::RunMessageLoop(); // Will stop in OnCheckDownloadUrlResult.
634 private:
635 friend class base::RefCountedThreadSafe<TestSBClient>;
636 virtual ~TestSBClient() {}
638 void CheckDownloadUrlOnIOThread(const std::vector<GURL>& url_chain) {
639 safe_browsing_service_->database_manager()->
640 CheckDownloadUrl(url_chain, this);
643 // Called when the result of checking a download URL is known.
644 virtual void OnCheckDownloadUrlResult(const std::vector<GURL>& url_chain,
645 SBThreatType threat_type) OVERRIDE {
646 threat_type_ = threat_type;
647 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
648 base::Bind(&TestSBClient::DownloadCheckDone, this));
651 void DownloadCheckDone() {
652 base::MessageLoopForUI::current()->Quit();
655 SBThreatType threat_type_;
656 SafeBrowsingService* safe_browsing_service_;
658 DISALLOW_COPY_AND_ASSIGN(TestSBClient);
661 // These tests use SafeBrowsingService::Client to directly interact with
662 // SafeBrowsingService.
663 namespace {
665 IN_PROC_BROWSER_TEST_F(SafeBrowsingServiceTest, CheckDownloadUrl) {
666 GURL badbin_url = test_server()->GetURL(kMalwareFile);
667 std::vector<GURL> badbin_urls(1, badbin_url);
669 scoped_refptr<TestSBClient> client(new TestSBClient);
670 client->CheckDownloadUrl(badbin_urls);
672 // Since badbin_url is not in database, it is considered to be safe.
673 EXPECT_EQ(SB_THREAT_TYPE_SAFE, client->GetThreatType());
675 SBFullHashResult full_hash_result;
676 GenUrlFullhashResult(badbin_url, safe_browsing_util::BINURL,
677 &full_hash_result);
678 SetupResponseForUrl(badbin_url, full_hash_result);
680 client->CheckDownloadUrl(badbin_urls);
682 // Now, the badbin_url is not safe since it is added to download database.
683 EXPECT_EQ(SB_THREAT_TYPE_BINARY_MALWARE_URL, client->GetThreatType());
686 IN_PROC_BROWSER_TEST_F(SafeBrowsingServiceTest, CheckDownloadUrlRedirects) {
687 GURL original_url = test_server()->GetURL(kEmptyPage);
688 GURL badbin_url = test_server()->GetURL(kMalwareFile);
689 GURL final_url = test_server()->GetURL(kEmptyPage);
690 std::vector<GURL> badbin_urls;
691 badbin_urls.push_back(original_url);
692 badbin_urls.push_back(badbin_url);
693 badbin_urls.push_back(final_url);
695 scoped_refptr<TestSBClient> client(new TestSBClient);
696 client->CheckDownloadUrl(badbin_urls);
698 // Since badbin_url is not in database, it is considered to be safe.
699 EXPECT_EQ(SB_THREAT_TYPE_SAFE, client->GetThreatType());
701 SBFullHashResult full_hash_result;
702 GenUrlFullhashResult(badbin_url, safe_browsing_util::BINURL,
703 &full_hash_result);
704 SetupResponseForUrl(badbin_url, full_hash_result);
706 client->CheckDownloadUrl(badbin_urls);
708 // Now, the badbin_url is not safe since it is added to download database.
709 EXPECT_EQ(SB_THREAT_TYPE_BINARY_MALWARE_URL, client->GetThreatType());
712 IN_PROC_BROWSER_TEST_F(SafeBrowsingServiceTest, CheckDownloadUrlTimedOut) {
713 GURL badbin_url = test_server()->GetURL(kMalwareFile);
714 std::vector<GURL> badbin_urls(1, badbin_url);
716 scoped_refptr<TestSBClient> client(new TestSBClient);
717 SBFullHashResult full_hash_result;
718 GenUrlFullhashResult(badbin_url, safe_browsing_util::BINURL,
719 &full_hash_result);
720 SetupResponseForUrl(badbin_url, full_hash_result);
721 client->CheckDownloadUrl(badbin_urls);
723 // badbin_url is not safe since it is added to download database.
724 EXPECT_EQ(SB_THREAT_TYPE_BINARY_MALWARE_URL, client->GetThreatType());
727 // Now introducing delays and we should hit timeout.
729 SafeBrowsingService* sb_service = g_browser_process->safe_browsing_service();
730 base::TimeDelta default_urlcheck_timeout =
731 GetCheckTimeout(sb_service);
732 IntroduceGetHashDelay(base::TimeDelta::FromSeconds(1));
733 SetCheckTimeout(sb_service, base::TimeDelta::FromMilliseconds(1));
734 client->CheckDownloadUrl(badbin_urls);
736 // There should be a timeout and the hash would be considered as safe.
737 EXPECT_EQ(SB_THREAT_TYPE_SAFE, client->GetThreatType());
739 // Need to set the timeout back to the default value.
740 SetCheckTimeout(sb_service, default_urlcheck_timeout);
743 IN_PROC_BROWSER_TEST_F(SafeBrowsingServiceTest, StartAndStop) {
744 CreateCSDService();
745 SafeBrowsingService* sb_service = g_browser_process->safe_browsing_service();
746 safe_browsing::ClientSideDetectionService* csd_service =
747 sb_service->safe_browsing_detection_service();
748 PrefService* pref_service = browser()->profile()->GetPrefs();
750 ASSERT_TRUE(sb_service != NULL);
751 ASSERT_TRUE(csd_service != NULL);
752 ASSERT_TRUE(pref_service != NULL);
754 EXPECT_TRUE(pref_service->GetBoolean(prefs::kSafeBrowsingEnabled));
756 // SBS might still be starting, make sure this doesn't flake.
757 WaitForIOThread();
758 EXPECT_TRUE(sb_service->enabled());
759 EXPECT_TRUE(csd_service->enabled());
761 // Add a new Profile. SBS should keep running.
762 ASSERT_TRUE(temp_profile_dir_.CreateUniqueTempDir());
763 scoped_ptr<Profile> profile2(Profile::CreateProfile(
764 temp_profile_dir_.path(), NULL, Profile::CREATE_MODE_SYNCHRONOUS));
765 ASSERT_TRUE(profile2.get() != NULL);
766 StartupTaskRunnerServiceFactory::GetForProfile(profile2.get())->
767 StartDeferredTaskRunners();
768 PrefService* pref_service2 = profile2->GetPrefs();
769 EXPECT_TRUE(pref_service2->GetBoolean(prefs::kSafeBrowsingEnabled));
770 // We don't expect the state to have changed, but if it did, wait for it.
771 WaitForIOThread();
772 EXPECT_TRUE(sb_service->enabled());
773 EXPECT_TRUE(csd_service->enabled());
775 // Change one of the prefs. SBS should keep running.
776 pref_service->SetBoolean(prefs::kSafeBrowsingEnabled, false);
777 WaitForIOThread();
778 EXPECT_TRUE(sb_service->enabled());
779 EXPECT_TRUE(csd_service->enabled());
781 // Change the other pref. SBS should stop now.
782 pref_service2->SetBoolean(prefs::kSafeBrowsingEnabled, false);
783 WaitForIOThread();
784 EXPECT_FALSE(sb_service->enabled());
785 EXPECT_FALSE(csd_service->enabled());
787 // Turn it back on. SBS comes back.
788 pref_service2->SetBoolean(prefs::kSafeBrowsingEnabled, true);
789 WaitForIOThread();
790 EXPECT_TRUE(sb_service->enabled());
791 EXPECT_TRUE(csd_service->enabled());
793 // Delete the Profile. SBS stops again.
794 pref_service2 = NULL;
795 profile2.reset();
796 WaitForIOThread();
797 EXPECT_FALSE(sb_service->enabled());
798 EXPECT_FALSE(csd_service->enabled());
801 } // namespace
803 class SafeBrowsingServiceShutdownTest : public SafeBrowsingServiceTest {
804 public:
805 virtual void TearDown() OVERRIDE {
806 // Browser should be fully torn down by now, so we can safely check these
807 // counters.
808 EXPECT_EQ(1, TestProtocolManager::create_count());
809 EXPECT_EQ(1, TestProtocolManager::delete_count());
811 SafeBrowsingServiceTest::TearDown();
814 // An observer that returns back to test code after a new profile is
815 // initialized.
816 void OnUnblockOnProfileCreation(Profile* profile,
817 Profile::CreateStatus status) {
818 if (status == Profile::CREATE_STATUS_INITIALIZED) {
819 profile2_ = profile;
820 base::MessageLoop::current()->Quit();
824 protected:
825 Profile* profile2_;
828 IN_PROC_BROWSER_TEST_F(SafeBrowsingServiceShutdownTest,
829 DontStartAfterShutdown) {
830 CreateCSDService();
831 SafeBrowsingService* sb_service = g_browser_process->safe_browsing_service();
832 safe_browsing::ClientSideDetectionService* csd_service =
833 sb_service->safe_browsing_detection_service();
834 PrefService* pref_service = browser()->profile()->GetPrefs();
836 ASSERT_TRUE(sb_service != NULL);
837 ASSERT_TRUE(csd_service != NULL);
838 ASSERT_TRUE(pref_service != NULL);
840 EXPECT_TRUE(pref_service->GetBoolean(prefs::kSafeBrowsingEnabled));
842 // SBS might still be starting, make sure this doesn't flake.
843 WaitForIOThread();
844 EXPECT_EQ(1, TestProtocolManager::create_count());
845 EXPECT_EQ(0, TestProtocolManager::delete_count());
847 // Create an additional profile. We need to use the ProfileManager so that
848 // the profile will get destroyed in the normal browser shutdown process.
849 ProfileManager* profile_manager = g_browser_process->profile_manager();
850 ASSERT_TRUE(temp_profile_dir_.CreateUniqueTempDir());
851 profile_manager->CreateProfileAsync(
852 temp_profile_dir_.path(),
853 base::Bind(&SafeBrowsingServiceShutdownTest::OnUnblockOnProfileCreation,
854 this),
855 base::string16(), base::string16(), std::string());
857 // Spin to allow profile creation to take place, loop is terminated
858 // by OnUnblockOnProfileCreation when the profile is created.
859 content::RunMessageLoop();
861 PrefService* pref_service2 = profile2_->GetPrefs();
862 EXPECT_TRUE(pref_service2->GetBoolean(prefs::kSafeBrowsingEnabled));
864 // We don't expect the state to have changed, but if it did, wait for it.
865 WaitForIOThread();
866 EXPECT_EQ(1, TestProtocolManager::create_count());
867 EXPECT_EQ(0, TestProtocolManager::delete_count());
869 // End the test, shutting down the browser.
870 // SafeBrowsingServiceShutdownTest::TearDown will check the create_count and
871 // delete_count again.
874 class SafeBrowsingDatabaseManagerCookieTest : public InProcessBrowserTest {
875 public:
876 SafeBrowsingDatabaseManagerCookieTest() {}
878 virtual void SetUp() OVERRIDE {
879 // We need to start the test server to get the host&port in the url.
880 ASSERT_TRUE(test_server()->Start());
882 // Point to the testing server for all SafeBrowsing requests.
883 GURL url_prefix = test_server()->GetURL(
884 "expect-and-set-cookie?expect=a%3db"
885 "&set=c%3dd%3b%20Expires=Fri,%2001%20Jan%202038%2001:01:01%20GMT"
886 "&data=foo#");
887 sb_factory_.reset(new TestSafeBrowsingServiceFactory(url_prefix.spec()));
888 SafeBrowsingService::RegisterFactory(sb_factory_.get());
890 InProcessBrowserTest::SetUp();
893 virtual void TearDown() OVERRIDE {
894 InProcessBrowserTest::TearDown();
896 SafeBrowsingService::RegisterFactory(NULL);
899 virtual bool SetUpUserDataDirectory() OVERRIDE {
900 base::FilePath cookie_path(
901 SafeBrowsingService::GetCookieFilePathForTesting());
902 EXPECT_FALSE(base::PathExists(cookie_path));
904 base::FilePath test_dir;
905 if (!PathService::Get(chrome::DIR_TEST_DATA, &test_dir)) {
906 EXPECT_TRUE(false);
907 return false;
910 // Initialize the SafeBrowsing cookies with a pre-created cookie store. It
911 // contains a single cookie, for domain 127.0.0.1, with value a=b, and
912 // expires in 2038.
913 base::FilePath initial_cookies = test_dir.AppendASCII("safe_browsing")
914 .AppendASCII("Safe Browsing Cookies");
915 if (!base::CopyFile(initial_cookies, cookie_path)) {
916 EXPECT_TRUE(false);
917 return false;
920 sql::Connection db;
921 if (!db.Open(cookie_path)) {
922 EXPECT_TRUE(false);
923 return false;
925 // Ensure the host value in the cookie file matches the test server we will
926 // be connecting to.
927 sql::Statement smt(db.GetUniqueStatement(
928 "UPDATE cookies SET host_key = ?"));
929 if (!smt.is_valid()) {
930 EXPECT_TRUE(false);
931 return false;
933 if (!smt.BindString(0, test_server()->host_port_pair().host())) {
934 EXPECT_TRUE(false);
935 return false;
937 if (!smt.Run()) {
938 EXPECT_TRUE(false);
939 return false;
942 return InProcessBrowserTest::SetUpUserDataDirectory();
945 virtual void TearDownInProcessBrowserTestFixture() OVERRIDE {
946 InProcessBrowserTest::TearDownInProcessBrowserTestFixture();
948 sql::Connection db;
949 base::FilePath cookie_path(
950 SafeBrowsingService::GetCookieFilePathForTesting());
951 ASSERT_TRUE(db.Open(cookie_path));
953 sql::Statement smt(db.GetUniqueStatement(
954 "SELECT name, value FROM cookies ORDER BY name"));
955 ASSERT_TRUE(smt.is_valid());
957 ASSERT_TRUE(smt.Step());
958 ASSERT_EQ("a", smt.ColumnString(0));
959 ASSERT_EQ("b", smt.ColumnString(1));
960 ASSERT_TRUE(smt.Step());
961 ASSERT_EQ("c", smt.ColumnString(0));
962 ASSERT_EQ("d", smt.ColumnString(1));
963 EXPECT_FALSE(smt.Step());
966 virtual void SetUpOnMainThread() OVERRIDE {
967 sb_service_ = g_browser_process->safe_browsing_service();
968 ASSERT_TRUE(sb_service_.get() != NULL);
971 virtual void CleanUpOnMainThread() OVERRIDE {
972 sb_service_ = NULL;
975 void ForceUpdate() {
976 sb_service_->protocol_manager()->ForceScheduleNextUpdate(
977 base::TimeDelta::FromSeconds(0));
980 scoped_refptr<SafeBrowsingService> sb_service_;
982 private:
983 scoped_ptr<TestSafeBrowsingServiceFactory> sb_factory_;
985 DISALLOW_COPY_AND_ASSIGN(SafeBrowsingDatabaseManagerCookieTest);
988 // Test that a Safe Browsing database update request both sends cookies and can
989 // save cookies.
990 IN_PROC_BROWSER_TEST_F(SafeBrowsingDatabaseManagerCookieTest,
991 TestSBUpdateCookies) {
992 content::WindowedNotificationObserver observer(
993 chrome::NOTIFICATION_SAFE_BROWSING_UPDATE_COMPLETE,
994 content::Source<SafeBrowsingDatabaseManager>(
995 sb_service_->database_manager().get()));
996 BrowserThread::PostTask(
997 BrowserThread::IO,
998 FROM_HERE,
999 base::Bind(&SafeBrowsingDatabaseManagerCookieTest::ForceUpdate, this));
1000 observer.Wait();