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