• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 //
5 // This test creates a safebrowsing service using test safebrowsing database
6 // and a test protocol manager. It is used to test logics in safebrowsing
7 // service.
8 
9 #include "base/command_line.h"
10 #include "base/memory/ref_counted.h"
11 #include "base/metrics/histogram.h"
12 #include "crypto/sha2.h"
13 #include "chrome/browser/browser_process.h"
14 #include "chrome/browser/safe_browsing/safe_browsing_database.h"
15 #include "chrome/browser/safe_browsing/safe_browsing_service.h"
16 #include "chrome/browser/safe_browsing/safe_browsing_util.h"
17 #include "chrome/browser/safe_browsing/protocol_manager.h"
18 #include "chrome/browser/ui/browser.h"
19 #include "chrome/common/chrome_switches.h"
20 #include "chrome/test/in_process_browser_test.h"
21 #include "chrome/test/ui_test_utils.h"
22 #include "content/browser/browser_thread.h"
23 #include "content/browser/renderer_host/resource_dispatcher_host.h"
24 #include "content/browser/tab_contents/tab_contents.h"
25 #include "content/browser/tab_contents/tab_contents_view.h"
26 
27 using base::Histogram;
28 using base::StatisticsRecorder;
29 
30 // A SafeBrowingDatabase class that allows us to inject the malicious URLs.
31 class TestSafeBrowsingDatabase :  public SafeBrowsingDatabase {
32  public:
TestSafeBrowsingDatabase()33   TestSafeBrowsingDatabase() {}
34 
~TestSafeBrowsingDatabase()35   virtual ~TestSafeBrowsingDatabase() {}
36 
37   // Initializes the database with the given filename.
Init(const FilePath & filename)38   virtual void Init(const FilePath& filename) {}
39 
40   // Deletes the current database and creates a new one.
ResetDatabase()41   virtual bool ResetDatabase() {
42     badurls_.clear();
43     return true;
44   }
45 
46   // Called on the IO thread to check if the given URL is safe or not.  If we
47   // can synchronously determine that the URL is safe, CheckUrl returns true,
48   // otherwise it returns false.
ContainsBrowseUrl(const GURL & url,std::string * matching_list,std::vector<SBPrefix> * prefix_hits,std::vector<SBFullHashResult> * full_hits,base::Time last_update)49   virtual bool ContainsBrowseUrl(const GURL& url,
50                                  std::string* matching_list,
51                                  std::vector<SBPrefix>* prefix_hits,
52                                  std::vector<SBFullHashResult>* full_hits,
53                                  base::Time last_update) {
54     std::vector<GURL> urls(1, url);
55     return ContainsUrl(safe_browsing_util::kMalwareList,
56                        safe_browsing_util::kPhishingList,
57                        urls, prefix_hits, full_hits);
58   }
ContainsDownloadUrl(const std::vector<GURL> & urls,std::vector<SBPrefix> * prefix_hits)59   virtual bool ContainsDownloadUrl(const std::vector<GURL>& urls,
60                                    std::vector<SBPrefix>* prefix_hits) {
61     std::vector<SBFullHashResult> full_hits;
62     bool found = ContainsUrl(safe_browsing_util::kBinUrlList,
63                              safe_browsing_util::kBinHashList,
64                              urls, prefix_hits, &full_hits);
65     if (!found)
66       return false;
67     DCHECK_LE(1U, prefix_hits->size());
68     return true;
69   }
ContainsDownloadHashPrefix(const SBPrefix & prefix)70   virtual bool ContainsDownloadHashPrefix(const SBPrefix& prefix) {
71     return download_digest_prefix_.count(prefix) > 0;
72   }
ContainsCsdWhitelistedUrl(const GURL & url)73   virtual bool ContainsCsdWhitelistedUrl(const GURL& url) {
74     return true;
75   }
UpdateStarted(std::vector<SBListChunkRanges> * lists)76   virtual bool UpdateStarted(std::vector<SBListChunkRanges>* lists) {
77     ADD_FAILURE() << "Not implemented.";
78     return false;
79   }
InsertChunks(const std::string & list_name,const SBChunkList & chunks)80   virtual void InsertChunks(const std::string& list_name,
81                             const SBChunkList& chunks) {
82     ADD_FAILURE() << "Not implemented.";
83   }
DeleteChunks(const std::vector<SBChunkDelete> & chunk_deletes)84   virtual void DeleteChunks(const std::vector<SBChunkDelete>& chunk_deletes) {
85     ADD_FAILURE() << "Not implemented.";
86   }
UpdateFinished(bool update_succeeded)87   virtual void UpdateFinished(bool update_succeeded) {
88     ADD_FAILURE() << "Not implemented.";
89   }
CacheHashResults(const std::vector<SBPrefix> & prefixes,const std::vector<SBFullHashResult> & full_hits)90   virtual void CacheHashResults(const std::vector<SBPrefix>& prefixes,
91       const std::vector<SBFullHashResult>& full_hits) {
92     // Do nothing for the cache.
93     return;
94   }
95 
96   // Fill up the database with test URL.
AddUrl(const GURL & url,const std::string & list_name,const std::vector<SBPrefix> & prefix_hits,const std::vector<SBFullHashResult> & full_hits)97   void AddUrl(const GURL& url,
98               const std::string& list_name,
99               const std::vector<SBPrefix>& prefix_hits,
100               const std::vector<SBFullHashResult>& full_hits) {
101     badurls_[url.spec()].list_name = list_name;
102     badurls_[url.spec()].prefix_hits = prefix_hits;
103     badurls_[url.spec()].full_hits = full_hits;
104   }
105 
106   // Fill up the database with test hash digest.
AddDownloadPrefix(SBPrefix prefix)107   void AddDownloadPrefix(SBPrefix prefix) {
108     download_digest_prefix_.insert(prefix);
109   }
110 
111  private:
112   struct Hits {
113     std::string list_name;
114     std::vector<SBPrefix> prefix_hits;
115     std::vector<SBFullHashResult> full_hits;
116   };
117 
ContainsUrl(const std::string & list_name0,const std::string & list_name1,const std::vector<GURL> & urls,std::vector<SBPrefix> * prefix_hits,std::vector<SBFullHashResult> * full_hits)118   bool ContainsUrl(const std::string& list_name0,
119                    const std::string& list_name1,
120                    const std::vector<GURL>& urls,
121                    std::vector<SBPrefix>* prefix_hits,
122                    std::vector<SBFullHashResult>* full_hits) {
123     bool hit = false;
124     for (size_t i = 0; i < urls.size(); ++i) {
125       const GURL& url = urls[i];
126       base::hash_map<std::string, Hits>::const_iterator
127           badurls_it = badurls_.find(url.spec());
128 
129       if (badurls_it == badurls_.end())
130         continue;
131 
132       if (badurls_it->second.list_name == list_name0 ||
133           badurls_it->second.list_name == list_name1) {
134         prefix_hits->insert(prefix_hits->end(),
135                             badurls_it->second.prefix_hits.begin(),
136                             badurls_it->second.prefix_hits.end());
137         full_hits->insert(full_hits->end(),
138                           badurls_it->second.full_hits.begin(),
139                           badurls_it->second.full_hits.end());
140         hit = true;
141       }
142 
143     }
144     return hit;
145   }
146 
147   base::hash_map<std::string, Hits> badurls_;
148   base::hash_set<SBPrefix> download_digest_prefix_;
149 };
150 
151 // Factory that creates TestSafeBrowsingDatabase instances.
152 class TestSafeBrowsingDatabaseFactory : public SafeBrowsingDatabaseFactory {
153  public:
TestSafeBrowsingDatabaseFactory()154   TestSafeBrowsingDatabaseFactory() : db_(NULL) {}
~TestSafeBrowsingDatabaseFactory()155   virtual ~TestSafeBrowsingDatabaseFactory() {}
156 
CreateSafeBrowsingDatabase(bool enable_download_protection,bool enable_client_side_whitelist)157   virtual SafeBrowsingDatabase* CreateSafeBrowsingDatabase(
158       bool enable_download_protection,
159       bool enable_client_side_whitelist) {
160     db_ = new TestSafeBrowsingDatabase();
161     return db_;
162   }
GetDb()163   TestSafeBrowsingDatabase* GetDb() {
164     return db_;
165   }
166  private:
167   // Owned by the SafebrowsingService.
168   TestSafeBrowsingDatabase* db_;
169 };
170 
171 // A TestProtocolManager that could return fixed responses from
172 // safebrowsing server for testing purpose.
173 class TestProtocolManager :  public SafeBrowsingProtocolManager {
174  public:
TestProtocolManager(SafeBrowsingService * sb_service,const std::string & client_name,const std::string & client_key,const std::string & wrapped_key,net::URLRequestContextGetter * request_context_getter,const std::string & info_url_prefix,const std::string & mackey_url_prefix,bool disable_auto_update)175   TestProtocolManager(SafeBrowsingService* sb_service,
176                       const std::string& client_name,
177                       const std::string& client_key,
178                       const std::string& wrapped_key,
179                       net::URLRequestContextGetter* request_context_getter,
180                       const std::string& info_url_prefix,
181                       const std::string& mackey_url_prefix,
182                       bool disable_auto_update)
183       : SafeBrowsingProtocolManager(sb_service, client_name, client_key,
184                                     wrapped_key, request_context_getter,
185                                     info_url_prefix, mackey_url_prefix,
186                                     disable_auto_update),
187         sb_service_(sb_service),
188         delay_ms_(0) {
189   }
190 
191   // This function is called when there is a prefix hit in local safebrowsing
192   // database and safebrowsing service issues a get hash request to backends.
193   // We return a result from the prefilled full_hashes_ hash_map to simulate
194   // server's response. At the same time, latency is added to simulate real
195   // life network issues.
GetFullHash(SafeBrowsingService::SafeBrowsingCheck * check,const std::vector<SBPrefix> & prefixes)196   virtual void GetFullHash(SafeBrowsingService::SafeBrowsingCheck* check,
197                            const std::vector<SBPrefix>& prefixes) {
198     // When we get a valid response, always cache the result.
199     bool cancache = true;
200     BrowserThread::PostDelayedTask(
201         BrowserThread::IO, FROM_HERE,
202         NewRunnableMethod(
203             sb_service_, &SafeBrowsingService::HandleGetHashResults,
204             check, full_hashes_, cancache),
205         delay_ms_);
206   }
207 
208   // Prepare the GetFullHash results for the next request.
SetGetFullHashResponse(const SBFullHashResult & full_hash_result)209   void SetGetFullHashResponse(const SBFullHashResult& full_hash_result) {
210     full_hashes_.clear();
211     full_hashes_.push_back(full_hash_result);
212   }
213 
IntroduceDelay(int64 ms)214   void IntroduceDelay(int64 ms) {
215     delay_ms_ = ms;
216   }
217 
218  private:
219   std::vector<SBFullHashResult> full_hashes_;
220   SafeBrowsingService* sb_service_;
221   int64 delay_ms_;
222 };
223 
224 // Factory that creates TestProtocolManager instances.
225 class TestSBProtocolManagerFactory : public SBProtocolManagerFactory {
226  public:
TestSBProtocolManagerFactory()227   TestSBProtocolManagerFactory() : pm_(NULL) {}
~TestSBProtocolManagerFactory()228   virtual ~TestSBProtocolManagerFactory() {}
229 
CreateProtocolManager(SafeBrowsingService * sb_service,const std::string & client_name,const std::string & client_key,const std::string & wrapped_key,net::URLRequestContextGetter * request_context_getter,const std::string & info_url_prefix,const std::string & mackey_url_prefix,bool disable_auto_update)230   virtual SafeBrowsingProtocolManager* CreateProtocolManager(
231       SafeBrowsingService* sb_service,
232       const std::string& client_name,
233       const std::string& client_key,
234       const std::string& wrapped_key,
235       net::URLRequestContextGetter* request_context_getter,
236       const std::string& info_url_prefix,
237       const std::string& mackey_url_prefix,
238       bool disable_auto_update) {
239     pm_ = new TestProtocolManager(
240         sb_service, client_name, client_key, wrapped_key,
241         request_context_getter, info_url_prefix, mackey_url_prefix,
242         disable_auto_update);
243     return pm_;
244   }
GetProtocolManager()245   TestProtocolManager* GetProtocolManager() {
246     return pm_;
247   }
248  private:
249   // Owned by the SafebrowsingService.
250   TestProtocolManager* pm_;
251 };
252 
253 // Tests the safe browsing blocking page in a browser.
254 class SafeBrowsingServiceTest : public InProcessBrowserTest {
255  public:
SafeBrowsingServiceTest()256   SafeBrowsingServiceTest() {
257   }
258 
GenUrlFullhashResult(const GURL & url,const std::string & list_name,int add_chunk_id,SBFullHashResult * full_hash)259   static void GenUrlFullhashResult(const GURL& url,
260                                    const std::string& list_name,
261                                    int add_chunk_id,
262                                    SBFullHashResult* full_hash) {
263     std::string host;
264     std::string path;
265     safe_browsing_util::CanonicalizeUrl(url, &host, &path, NULL);
266     crypto::SHA256HashString(host + path, &full_hash->hash,
267                              sizeof(SBFullHash));
268     full_hash->list_name = list_name;
269     full_hash->add_chunk_id = add_chunk_id;
270   }
271 
GenDigestFullhashResult(const std::string & full_digest,const std::string & list_name,int add_chunk_id,SBFullHashResult * full_hash)272   static void GenDigestFullhashResult(const std::string& full_digest,
273                                       const std::string& list_name,
274                                       int add_chunk_id,
275                                       SBFullHashResult* full_hash) {
276     safe_browsing_util::StringToSBFullHash(full_digest, &full_hash->hash);
277     full_hash->list_name = list_name;
278     full_hash->add_chunk_id = add_chunk_id;
279   }
280 
SetUp()281   virtual void SetUp() {
282     // InProcessBrowserTest::SetUp() intantiates SafebrowsingService and
283     // RegisterFactory has to be called before SafeBrowsingService is created.
284     SafeBrowsingDatabase::RegisterFactory(&db_factory_);
285     SafeBrowsingProtocolManager::RegisterFactory(&pm_factory_);
286     InProcessBrowserTest::SetUp();
287   }
288 
TearDown()289   virtual void TearDown() {
290     InProcessBrowserTest::TearDown();
291 
292     // Unregister test factories after InProcessBrowserTest::TearDown
293     // (which destructs SafeBrowsingService).
294     SafeBrowsingDatabase::RegisterFactory(NULL);
295     SafeBrowsingProtocolManager::RegisterFactory(NULL);
296   }
297 
SetUpCommandLine(CommandLine * command_line)298   virtual void SetUpCommandLine(CommandLine* command_line) {
299     // Makes sure the auto update is not triggered during the test.
300     // This test will fill up the database using testing prefixes
301     // and urls.
302     command_line->AppendSwitch(switches::kSbDisableAutoUpdate);
303   }
304 
SetUpInProcessBrowserTestFixture()305   virtual void SetUpInProcessBrowserTestFixture() {
306     ASSERT_TRUE(test_server()->Start());
307   }
308 
309   // This will setup the "url" prefix in database and prepare protocol manager
310   // to response with |full_hash| for get full hash request.
SetupResponseForUrl(const GURL & url,const SBFullHashResult & full_hash)311   void SetupResponseForUrl(const GURL& url, const SBFullHashResult& full_hash) {
312     std::vector<SBPrefix> prefix_hits;
313     prefix_hits.push_back(full_hash.hash.prefix);
314 
315     // Make sure the full hits is empty unless we need to test the
316     // full hash is hit in database's local cache.
317     std::vector<SBFullHashResult> empty_full_hits;
318     TestSafeBrowsingDatabase* db = db_factory_.GetDb();
319     db->AddUrl(url, full_hash.list_name, prefix_hits, empty_full_hits);
320 
321     TestProtocolManager* pm = pm_factory_.GetProtocolManager();
322     pm->SetGetFullHashResponse(full_hash);
323   }
324 
325   // This will setup the binary digest prefix in database and prepare protocol
326   // manager to response with |full_hash| for get full hash request.
SetupResponseForDigest(const std::string & digest,const SBFullHashResult & hash_result)327   void SetupResponseForDigest(const std::string& digest,
328                               const SBFullHashResult& hash_result) {
329     TestSafeBrowsingDatabase* db = db_factory_.GetDb();
330     SBFullHash full_hash;
331     safe_browsing_util::StringToSBFullHash(digest, &full_hash);
332     db->AddDownloadPrefix(full_hash.prefix);
333 
334     TestProtocolManager* pm = pm_factory_.GetProtocolManager();
335     pm->SetGetFullHashResponse(hash_result);
336   }
337 
ShowingInterstitialPage()338   bool ShowingInterstitialPage() {
339     TabContents* contents = browser()->GetSelectedTabContents();
340     InterstitialPage* interstitial_page = contents->interstitial_page();
341     return interstitial_page != NULL;
342   }
343 
IntroduceGetHashDelay(int64 ms)344   void IntroduceGetHashDelay(int64 ms) {
345     pm_factory_.GetProtocolManager()->IntroduceDelay(ms);
346   }
347 
DownloadUrlCheckTimeout(SafeBrowsingService * sb_service)348   int64 DownloadUrlCheckTimeout(SafeBrowsingService* sb_service) {
349     return sb_service->download_urlcheck_timeout_ms_;
350   }
351 
DownloadHashCheckTimeout(SafeBrowsingService * sb_service)352   int64 DownloadHashCheckTimeout(SafeBrowsingService* sb_service) {
353     return sb_service->download_hashcheck_timeout_ms_;
354   }
355 
SetDownloadUrlCheckTimeout(SafeBrowsingService * sb_service,int64 ms)356   void SetDownloadUrlCheckTimeout(SafeBrowsingService* sb_service, int64 ms) {
357     sb_service->download_urlcheck_timeout_ms_ = ms;
358   }
359 
SetDownloadHashCheckTimeout(SafeBrowsingService * sb_service,int64 ms)360   void SetDownloadHashCheckTimeout(SafeBrowsingService* sb_service, int64 ms) {
361     sb_service->download_hashcheck_timeout_ms_ = ms;
362   }
363 
364  private:
365   TestSafeBrowsingDatabaseFactory db_factory_;
366   TestSBProtocolManagerFactory pm_factory_;
367 
368   DISALLOW_COPY_AND_ASSIGN(SafeBrowsingServiceTest);
369 };
370 
371 namespace {
372 
373 const char kEmptyPage[] = "files/empty.html";
374 const char kMalwareFile[] = "files/downloads/dangerous/dangerous.exe";
375 const char kMalwareIframe[] = "files/safe_browsing/malware_iframe.html";
376 const char kMalwarePage[] = "files/safe_browsing/malware.html";
377 
378 // This test goes through DownloadResourceHandler.
IN_PROC_BROWSER_TEST_F(SafeBrowsingServiceTest,Malware)379 IN_PROC_BROWSER_TEST_F(SafeBrowsingServiceTest, Malware) {
380   GURL url = test_server()->GetURL(kEmptyPage);
381 
382   // After adding the url to safebrowsing database and getfullhash result,
383   // we should see the interstitial page.
384   SBFullHashResult malware_full_hash;
385   int chunk_id = 0;
386   GenUrlFullhashResult(url, safe_browsing_util::kMalwareList, chunk_id,
387                        &malware_full_hash);
388   SetupResponseForUrl(url, malware_full_hash);
389   ui_test_utils::NavigateToURL(browser(), url);
390   EXPECT_TRUE(ShowingInterstitialPage());
391 }
392 
393 const char kPrefetchMalwarePage[] = "files/safe_browsing/prefetch_malware.html";
394 
395 // This test confirms that prefetches don't themselves get the
396 // interstitial treatment.
IN_PROC_BROWSER_TEST_F(SafeBrowsingServiceTest,Prefetch)397 IN_PROC_BROWSER_TEST_F(SafeBrowsingServiceTest, Prefetch) {
398   GURL url = test_server()->GetURL(kPrefetchMalwarePage);
399   GURL malware_url = test_server()->GetURL(kMalwarePage);
400 
401   class SetPrefetchForTest {
402    public:
403     explicit SetPrefetchForTest(bool prefetch)
404         : old_prefetch_state_(ResourceDispatcherHost::is_prefetch_enabled()) {
405       ResourceDispatcherHost::set_is_prefetch_enabled(prefetch);
406     }
407 
408     ~SetPrefetchForTest() {
409       ResourceDispatcherHost::set_is_prefetch_enabled(old_prefetch_state_);
410     }
411    private:
412     bool old_prefetch_state_;
413   } set_prefetch_for_test(true);
414 
415   // Even though we have added this uri to the safebrowsing database and
416   // getfullhash result, we should not see the interstitial page since the
417   // only malware was a prefetch target.
418   SBFullHashResult malware_full_hash;
419   int chunk_id = 0;
420   GenUrlFullhashResult(malware_url, safe_browsing_util::kMalwareList,
421                        chunk_id, &malware_full_hash);
422   SetupResponseForUrl(malware_url, malware_full_hash);
423   ui_test_utils::NavigateToURL(browser(), url);
424   EXPECT_FALSE(ShowingInterstitialPage());
425 
426   // However, when we navigate to the malware page, we should still get
427   // the interstitial.
428   ui_test_utils::NavigateToURL(browser(), malware_url);
429   EXPECT_TRUE(ShowingInterstitialPage());
430 }
431 
432 }  // namespace
433 
434 class TestSBClient
435     : public base::RefCountedThreadSafe<TestSBClient>,
436       public SafeBrowsingService::Client {
437  public:
TestSBClient()438   TestSBClient() : result_(SafeBrowsingService::SAFE),
439                    safe_browsing_service_(g_browser_process->
440                                           resource_dispatcher_host()->
441                                           safe_browsing_service()) {
442   }
443 
GetResult()444   int GetResult() {
445     return result_;
446   }
447 
CheckDownloadUrl(const std::vector<GURL> & url_chain)448   void CheckDownloadUrl(const std::vector<GURL>& url_chain) {
449     BrowserThread::PostTask(
450         BrowserThread::IO, FROM_HERE,
451         NewRunnableMethod(this,
452                           &TestSBClient::CheckDownloadUrlOnIOThread,
453                           url_chain));
454     ui_test_utils::RunMessageLoop();  // Will stop in OnDownloadUrlCheckResult.
455   }
456 
CheckDownloadHash(const std::string & full_hash)457   void CheckDownloadHash(const std::string& full_hash) {
458     BrowserThread::PostTask(
459         BrowserThread::IO, FROM_HERE,
460         NewRunnableMethod(this,
461                           &TestSBClient::CheckDownloadHashOnIOThread,
462                           full_hash));
463     ui_test_utils::RunMessageLoop();  // Will stop in OnDownloadHashCheckResult.
464   }
465 
466  private:
CheckDownloadUrlOnIOThread(const std::vector<GURL> & url_chain)467   void CheckDownloadUrlOnIOThread(const std::vector<GURL>& url_chain) {
468     safe_browsing_service_->CheckDownloadUrl(url_chain, this);
469   }
470 
CheckDownloadHashOnIOThread(const std::string & full_hash)471   void CheckDownloadHashOnIOThread(const std::string& full_hash) {
472     safe_browsing_service_->CheckDownloadHash(full_hash, this);
473   }
474 
475   // Called when the result of checking a download URL is known.
OnDownloadUrlCheckResult(const std::vector<GURL> & url_chain,SafeBrowsingService::UrlCheckResult result)476   void OnDownloadUrlCheckResult(const std::vector<GURL>& url_chain,
477                                 SafeBrowsingService::UrlCheckResult result) {
478     result_ = result;
479     BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
480       NewRunnableMethod(this, &TestSBClient::DownloadCheckDone));
481   }
482 
483   // Called when the result of checking a download hash is known.
OnDownloadHashCheckResult(const std::string & hash,SafeBrowsingService::UrlCheckResult result)484   void OnDownloadHashCheckResult(const std::string& hash,
485                                  SafeBrowsingService::UrlCheckResult result) {
486     result_ = result;
487     BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
488       NewRunnableMethod(this, &TestSBClient::DownloadCheckDone));
489   }
490 
DownloadCheckDone()491   void DownloadCheckDone() {
492     MessageLoopForUI::current()->Quit();
493   }
494 
495   SafeBrowsingService::UrlCheckResult result_;
496   SafeBrowsingService* safe_browsing_service_;
497 
498   DISALLOW_COPY_AND_ASSIGN(TestSBClient);
499 };
500 
501 // These tests use SafeBrowsingService::Client to directly interact with
502 // SafeBrowsingService.
503 namespace {
504 
IN_PROC_BROWSER_TEST_F(SafeBrowsingServiceTest,CheckDownloadUrl)505 IN_PROC_BROWSER_TEST_F(SafeBrowsingServiceTest, CheckDownloadUrl) {
506   GURL badbin_url = test_server()->GetURL(kMalwareFile);
507   std::vector<GURL> badbin_urls(1, badbin_url);
508 
509   scoped_refptr<TestSBClient> client(new TestSBClient);
510   client->CheckDownloadUrl(badbin_urls);
511 
512   // Since badbin_url is not in database, it is considered to be safe.
513   EXPECT_EQ(SafeBrowsingService::SAFE, client->GetResult());
514 
515   SBFullHashResult full_hash_result;
516   int chunk_id = 0;
517   GenUrlFullhashResult(badbin_url, safe_browsing_util::kBinUrlList,
518                        chunk_id, &full_hash_result);
519   SetupResponseForUrl(badbin_url, full_hash_result);
520 
521   client->CheckDownloadUrl(badbin_urls);
522 
523   // Now, the badbin_url is not safe since it is added to download database.
524   EXPECT_EQ(SafeBrowsingService::BINARY_MALWARE_URL, client->GetResult());
525 }
526 
IN_PROC_BROWSER_TEST_F(SafeBrowsingServiceTest,CheckDownloadUrlRedirects)527 IN_PROC_BROWSER_TEST_F(SafeBrowsingServiceTest, CheckDownloadUrlRedirects) {
528   GURL original_url = test_server()->GetURL(kEmptyPage);
529   GURL badbin_url = test_server()->GetURL(kMalwareFile);
530   GURL final_url = test_server()->GetURL(kEmptyPage);
531   std::vector<GURL> badbin_urls;
532   badbin_urls.push_back(original_url);
533   badbin_urls.push_back(badbin_url);
534   badbin_urls.push_back(final_url);
535 
536   scoped_refptr<TestSBClient> client(new TestSBClient);
537   client->CheckDownloadUrl(badbin_urls);
538 
539   // Since badbin_url is not in database, it is considered to be safe.
540   EXPECT_EQ(SafeBrowsingService::SAFE, client->GetResult());
541 
542   SBFullHashResult full_hash_result;
543   int chunk_id = 0;
544   GenUrlFullhashResult(badbin_url, safe_browsing_util::kBinUrlList,
545                        chunk_id, &full_hash_result);
546   SetupResponseForUrl(badbin_url, full_hash_result);
547 
548   client->CheckDownloadUrl(badbin_urls);
549 
550   // Now, the badbin_url is not safe since it is added to download database.
551   EXPECT_EQ(SafeBrowsingService::BINARY_MALWARE_URL, client->GetResult());
552 }
553 
IN_PROC_BROWSER_TEST_F(SafeBrowsingServiceTest,CheckDownloadHash)554 IN_PROC_BROWSER_TEST_F(SafeBrowsingServiceTest, CheckDownloadHash) {
555   const std::string full_hash = "12345678902234567890323456789012";
556 
557   scoped_refptr<TestSBClient> client(new TestSBClient);
558   client->CheckDownloadHash(full_hash);
559 
560   // Since badbin_url is not in database, it is considered to be safe.
561   EXPECT_EQ(SafeBrowsingService::SAFE, client->GetResult());
562 
563   SBFullHashResult full_hash_result;
564   int chunk_id = 0;
565   GenDigestFullhashResult(full_hash, safe_browsing_util::kBinHashList,
566                           chunk_id, &full_hash_result);
567   SetupResponseForDigest(full_hash, full_hash_result);
568 
569   client->CheckDownloadHash(full_hash);
570 
571   // Now, the badbin_url is not safe since it is added to download database.
572   EXPECT_EQ(SafeBrowsingService::BINARY_MALWARE_HASH, client->GetResult());
573 }
574 
IN_PROC_BROWSER_TEST_F(SafeBrowsingServiceTest,CheckDownloadUrlTimedOut)575 IN_PROC_BROWSER_TEST_F(SafeBrowsingServiceTest, CheckDownloadUrlTimedOut) {
576   GURL badbin_url = test_server()->GetURL(kMalwareFile);
577   std::vector<GURL> badbin_urls(1, badbin_url);
578 
579   scoped_refptr<TestSBClient> client(new TestSBClient);
580   SBFullHashResult full_hash_result;
581   int chunk_id = 0;
582   GenUrlFullhashResult(badbin_url, safe_browsing_util::kBinUrlList,
583                        chunk_id, &full_hash_result);
584   SetupResponseForUrl(badbin_url, full_hash_result);
585   client->CheckDownloadUrl(badbin_urls);
586 
587   // badbin_url is not safe since it is added to download database.
588   EXPECT_EQ(SafeBrowsingService::BINARY_MALWARE_URL, client->GetResult());
589 
590   //
591   // Now introducing delays and we should hit timeout.
592   //
593   SafeBrowsingService* sb_service =
594       g_browser_process->resource_dispatcher_host()->safe_browsing_service();
595   const int64 kOneSec = 1000;
596   const int64 kOneMs = 1;
597   int64 default_urlcheck_timeout = DownloadUrlCheckTimeout(sb_service);
598   IntroduceGetHashDelay(kOneSec);
599   SetDownloadUrlCheckTimeout(sb_service, kOneMs);
600   client->CheckDownloadUrl(badbin_urls);
601 
602   // There should be a timeout and the hash would be considered as safe.
603   EXPECT_EQ(SafeBrowsingService::SAFE, client->GetResult());
604 
605   // Need to set the timeout back to the default value.
606   SetDownloadHashCheckTimeout(sb_service, default_urlcheck_timeout);
607 }
608 
IN_PROC_BROWSER_TEST_F(SafeBrowsingServiceTest,CheckDownloadHashTimedOut)609 IN_PROC_BROWSER_TEST_F(SafeBrowsingServiceTest, CheckDownloadHashTimedOut) {
610   const std::string full_hash = "12345678902234567890323456789012";
611 
612   scoped_refptr<TestSBClient> client(new TestSBClient);
613   SBFullHashResult full_hash_result;
614   int chunk_id = 0;
615   GenDigestFullhashResult(full_hash, safe_browsing_util::kBinHashList,
616                           chunk_id, &full_hash_result);
617   SetupResponseForDigest(full_hash, full_hash_result);
618   client->CheckDownloadHash(full_hash);
619 
620   // The badbin_url is not safe since it is added to download database.
621   EXPECT_EQ(SafeBrowsingService::BINARY_MALWARE_HASH, client->GetResult());
622 
623   //
624   // Now introducing delays and we should hit timeout.
625   //
626   SafeBrowsingService* sb_service =
627       g_browser_process->resource_dispatcher_host()->safe_browsing_service();
628   const int64 kOneSec = 1000;
629   const int64 kOneMs = 1;
630   int64 default_hashcheck_timeout = DownloadHashCheckTimeout(sb_service);
631   IntroduceGetHashDelay(kOneSec);
632   SetDownloadHashCheckTimeout(sb_service, kOneMs);
633   client->CheckDownloadHash(full_hash);
634 
635   // There should be a timeout and the hash would be considered as safe.
636   EXPECT_EQ(SafeBrowsingService::SAFE, client->GetResult());
637 
638   // Need to set the timeout back to the default value.
639   SetDownloadHashCheckTimeout(sb_service, default_hashcheck_timeout);
640 }
641 
642 }  // namespace
643