| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/files/scoped_temp_dir.h" | 5 #include "base/files/scoped_temp_dir.h" |
| 6 #include "base/memory/ptr_util.h" | 6 #include "base/memory/ptr_util.h" |
| 7 #include "base/memory/ref_counted.h" | 7 #include "base/memory/ref_counted.h" |
| 8 #include "base/run_loop.h" | 8 #include "base/run_loop.h" |
| 9 #include "base/strings/stringprintf.h" |
| 9 #include "base/test/test_simple_task_runner.h" | 10 #include "base/test/test_simple_task_runner.h" |
| 10 #include "components/safe_browsing_db/v4_database.h" | 11 #include "components/safe_browsing_db/v4_database.h" |
| 11 #include "components/safe_browsing_db/v4_local_database_manager.h" | 12 #include "components/safe_browsing_db/v4_local_database_manager.h" |
| 12 #include "components/safe_browsing_db/v4_test_util.h" | 13 #include "components/safe_browsing_db/v4_test_util.h" |
| 13 #include "content/public/test/test_browser_thread_bundle.h" | 14 #include "content/public/test/test_browser_thread_bundle.h" |
| 14 #include "crypto/sha2.h" | 15 #include "crypto/sha2.h" |
| 15 #include "net/url_request/test_url_fetcher_factory.h" | 16 #include "net/url_request/test_url_fetcher_factory.h" |
| 16 #include "testing/platform_test.h" | 17 #include "testing/platform_test.h" |
| 17 | 18 |
| 18 namespace safe_browsing { | 19 namespace safe_browsing { |
| 19 | 20 |
| 20 namespace { | 21 namespace { |
| 21 | 22 |
| 22 // Utility function for populating hashes. | 23 // Utility function for populating hashes. |
| 23 FullHash HashForUrl(const GURL& url) { | 24 FullHash HashForUrl(const GURL& url) { |
| 24 std::vector<FullHash> full_hashes; | 25 std::vector<FullHash> full_hashes; |
| 25 V4ProtocolManagerUtil::UrlToFullHashes(url, &full_hashes); | 26 V4ProtocolManagerUtil::UrlToFullHashes(url, &full_hashes); |
| 26 // ASSERT_GE(full_hashes.size(), 1u); | 27 // ASSERT_GE(full_hashes.size(), 1u); |
| 27 return full_hashes[0]; | 28 return full_hashes[0]; |
| 28 } | 29 } |
| 29 | 30 |
| 31 // A fullhash response containing no matches. |
| 32 std::string GetEmptyV4HashResponse() { |
| 33 FindFullHashesResponse res; |
| 34 res.mutable_negative_cache_duration()->set_seconds(600); |
| 35 |
| 36 std::string res_data; |
| 37 res.SerializeToString(&res_data); |
| 38 return res_data; |
| 39 } |
| 40 |
| 30 } // namespace | 41 } // namespace |
| 31 | 42 |
| 32 class FakeV4Database : public V4Database { | 43 class FakeV4Database : public V4Database { |
| 33 public: | 44 public: |
| 34 static void Create( | 45 static void Create( |
| 35 const scoped_refptr<base::SequencedTaskRunner>& db_task_runner, | 46 const scoped_refptr<base::SequencedTaskRunner>& db_task_runner, |
| 36 std::unique_ptr<StoreMap> store_map, | 47 std::unique_ptr<StoreMap> store_map, |
| 37 const StoreAndHashPrefixes& store_and_hash_prefixes, | 48 const StoreAndHashPrefixes& store_and_hash_prefixes, |
| 38 NewDatabaseReadyCallback new_db_callback, | 49 NewDatabaseReadyCallback new_db_callback, |
| 39 bool stores_available) { | 50 bool stores_available) { |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 89 : V4Database(db_task_runner, std::move(store_map)), | 100 : V4Database(db_task_runner, std::move(store_map)), |
| 90 store_and_hash_prefixes_(store_and_hash_prefixes), | 101 store_and_hash_prefixes_(store_and_hash_prefixes), |
| 91 stores_available_(stores_available) {} | 102 stores_available_(stores_available) {} |
| 92 | 103 |
| 93 const StoreAndHashPrefixes store_and_hash_prefixes_; | 104 const StoreAndHashPrefixes store_and_hash_prefixes_; |
| 94 const bool stores_available_; | 105 const bool stores_available_; |
| 95 }; | 106 }; |
| 96 | 107 |
| 97 class TestClient : public SafeBrowsingDatabaseManager::Client { | 108 class TestClient : public SafeBrowsingDatabaseManager::Client { |
| 98 public: | 109 public: |
| 99 TestClient(SBThreatType sb_threat_type, const GURL& url) | 110 TestClient(SBThreatType sb_threat_type, |
| 100 : expected_sb_threat_type(sb_threat_type), expected_url(url) {} | 111 const GURL& url, |
| 112 V4LocalDatabaseManager* manager_to_cancel = nullptr) |
| 113 : expected_sb_threat_type(sb_threat_type), |
| 114 expected_url(url), |
| 115 result_received_(false), |
| 116 manager_to_cancel_(manager_to_cancel) {} |
| 101 | 117 |
| 102 void OnCheckBrowseUrlResult(const GURL& url, | 118 void OnCheckBrowseUrlResult(const GURL& url, |
| 103 SBThreatType threat_type, | 119 SBThreatType threat_type, |
| 104 const ThreatMetadata& metadata) override { | 120 const ThreatMetadata& metadata) override { |
| 105 DCHECK_EQ(expected_url, url); | 121 DCHECK_EQ(expected_url, url); |
| 106 DCHECK_EQ(expected_sb_threat_type, threat_type); | 122 DCHECK_EQ(expected_sb_threat_type, threat_type); |
| 123 result_received_ = true; |
| 124 if (manager_to_cancel_) { |
| 125 manager_to_cancel_->CancelCheck(this); |
| 126 } |
| 107 } | 127 } |
| 108 | 128 |
| 109 SBThreatType expected_sb_threat_type; | 129 SBThreatType expected_sb_threat_type; |
| 110 GURL expected_url; | 130 GURL expected_url; |
| 131 bool result_received_; |
| 132 V4LocalDatabaseManager* manager_to_cancel_; |
| 111 }; | 133 }; |
| 112 | 134 |
| 113 class FakeV4LocalDatabaseManager : public V4LocalDatabaseManager { | 135 class FakeV4LocalDatabaseManager : public V4LocalDatabaseManager { |
| 114 public: | 136 public: |
| 115 void PerformFullHashCheck(std::unique_ptr<PendingCheck> check, | 137 void PerformFullHashCheck(std::unique_ptr<PendingCheck> check, |
| 116 const FullHashToStoreAndHashPrefixesMap& | 138 const FullHashToStoreAndHashPrefixesMap& |
| 117 full_hash_to_store_and_hash_prefixes) override { | 139 full_hash_to_store_and_hash_prefixes) override { |
| 118 perform_full_hash_check_called_ = true; | 140 perform_full_hash_check_called_ = true; |
| 119 } | 141 } |
| 120 | 142 |
| (...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 341 | 363 |
| 342 ResetV4Database(); | 364 ResetV4Database(); |
| 343 v4_local_database_manager_->CheckBrowseUrl(url, &client); | 365 v4_local_database_manager_->CheckBrowseUrl(url, &client); |
| 344 // The database is unavailable so the check should get queued. | 366 // The database is unavailable so the check should get queued. |
| 345 EXPECT_EQ(1ul, GetQueuedChecks().size()); | 367 EXPECT_EQ(1ul, GetQueuedChecks().size()); |
| 346 | 368 |
| 347 StopLocalDatabaseManager(); | 369 StopLocalDatabaseManager(); |
| 348 EXPECT_TRUE(GetQueuedChecks().empty()); | 370 EXPECT_TRUE(GetQueuedChecks().empty()); |
| 349 } | 371 } |
| 350 | 372 |
| 373 // Verify that a window where checks cannot be cancelled is closed. |
| 374 TEST_F(V4LocalDatabaseManagerTest, CancelPending) { |
| 375 WaitForTasksOnTaskRunner(); |
| 376 net::FakeURLFetcherFactory factory(NULL); |
| 377 // TODO(shess): Modify this to use a mock protocol manager instead |
| 378 // of faking the requests. |
| 379 const char* kReqs[] = { |
| 380 // OSX |
| 381 "Cg8KCHVuaXR0ZXN0EgMxLjAaJwgBCAIIAwgGCAcICAgJCAoQBBAIGgcKBWVXGg-" |
| 382 "pIAEgAyAEIAUgBg==", |
| 383 |
| 384 // Linux |
| 385 "Cg8KCHVuaXR0ZXN0EgMxLjAaJwgBCAIIAwgGCAcICAgJCAoQAhAIGgcKBWVXGg-" |
| 386 "pIAEgAyAEIAUgBg==", |
| 387 |
| 388 // Windows |
| 389 "Cg8KCHVuaXR0ZXN0EgMxLjAaJwgBCAIIAwgGCAcICAgJCAoQARAIGgcKBWVXGg-" |
| 390 "pIAEgAyAEIAUgBg==", |
| 391 }; |
| 392 for (const char* req : kReqs) { |
| 393 const GURL url( |
| 394 base::StringPrintf("https://safebrowsing.googleapis.com/v4/" |
| 395 "fullHashes:find?$req=%s" |
| 396 "&$ct=application/x-protobuf&key=test_key_param", |
| 397 req)); |
| 398 factory.SetFakeResponse(url, GetEmptyV4HashResponse(), net::HTTP_OK, |
| 399 net::URLRequestStatus::SUCCESS); |
| 400 } |
| 401 |
| 402 const GURL url("http://example.com/a/"); |
| 403 const HashPrefix hash_prefix("eW\x1A\xF\xA9"); |
| 404 |
| 405 StoreAndHashPrefixes store_and_hash_prefixes; |
| 406 store_and_hash_prefixes.emplace_back(GetUrlMalwareId(), hash_prefix); |
| 407 ReplaceV4Database(store_and_hash_prefixes); |
| 408 |
| 409 // Test that a request flows through to the callback. |
| 410 { |
| 411 TestClient client(SB_THREAT_TYPE_SAFE, url); |
| 412 EXPECT_FALSE(v4_local_database_manager_->CheckBrowseUrl(url, &client)); |
| 413 EXPECT_FALSE(client.result_received_); |
| 414 WaitForTasksOnTaskRunner(); |
| 415 EXPECT_TRUE(client.result_received_); |
| 416 } |
| 417 |
| 418 // Test that cancel prevents the callback from being called. |
| 419 { |
| 420 TestClient client(SB_THREAT_TYPE_SAFE, url); |
| 421 EXPECT_FALSE(v4_local_database_manager_->CheckBrowseUrl(url, &client)); |
| 422 v4_local_database_manager_->CancelCheck(&client); |
| 423 EXPECT_FALSE(client.result_received_); |
| 424 WaitForTasksOnTaskRunner(); |
| 425 EXPECT_FALSE(client.result_received_); |
| 426 } |
| 427 } |
| 428 |
| 429 // When the database load flushes the queued requests, make sure that |
| 430 // CancelCheck() is not fatal in the client callback. |
| 431 TEST_F(V4LocalDatabaseManagerTest, CancelQueued) { |
| 432 const GURL url("http://example.com/a/"); |
| 433 |
| 434 TestClient client1(SB_THREAT_TYPE_SAFE, url, |
| 435 v4_local_database_manager_.get()); |
| 436 TestClient client2(SB_THREAT_TYPE_SAFE, url); |
| 437 EXPECT_FALSE(v4_local_database_manager_->CheckBrowseUrl(url, &client1)); |
| 438 EXPECT_FALSE(v4_local_database_manager_->CheckBrowseUrl(url, &client2)); |
| 439 EXPECT_EQ(2ul, GetQueuedChecks().size()); |
| 440 EXPECT_FALSE(client1.result_received_); |
| 441 EXPECT_FALSE(client2.result_received_); |
| 442 WaitForTasksOnTaskRunner(); |
| 443 EXPECT_TRUE(client1.result_received_); |
| 444 EXPECT_TRUE(client2.result_received_); |
| 445 } |
| 446 |
| 351 // This test is somewhat similar to TestCheckBrowseUrlWithFakeDbReturnsMatch but | 447 // This test is somewhat similar to TestCheckBrowseUrlWithFakeDbReturnsMatch but |
| 352 // it uses a fake V4LocalDatabaseManager to assert that PerformFullHashCheck is | 448 // it uses a fake V4LocalDatabaseManager to assert that PerformFullHashCheck is |
| 353 // called async. | 449 // called async. |
| 354 TEST_F(V4LocalDatabaseManagerTest, PerformFullHashCheckCalledAsync) { | 450 TEST_F(V4LocalDatabaseManagerTest, PerformFullHashCheckCalledAsync) { |
| 355 SetupFakeManager(); | 451 SetupFakeManager(); |
| 356 net::TestURLFetcherFactory factory; | 452 net::TestURLFetcherFactory factory; |
| 357 | 453 |
| 358 StoreAndHashPrefixes store_and_hash_prefixes; | 454 StoreAndHashPrefixes store_and_hash_prefixes; |
| 359 store_and_hash_prefixes.emplace_back(GetUrlMalwareId(), | 455 store_and_hash_prefixes.emplace_back(GetUrlMalwareId(), |
| 360 HashPrefix("eW\x1A\xF\xA9")); | 456 HashPrefix("eW\x1A\xF\xA9")); |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 519 EXPECT_FALSE(FakeV4LocalDatabaseManager::PerformFullHashCheckCalled( | 615 EXPECT_FALSE(FakeV4LocalDatabaseManager::PerformFullHashCheckCalled( |
| 520 v4_local_database_manager_)); | 616 v4_local_database_manager_)); |
| 521 } | 617 } |
| 522 | 618 |
| 523 // TODO(nparker): Add tests for | 619 // TODO(nparker): Add tests for |
| 524 // CheckDownloadUrl() | 620 // CheckDownloadUrl() |
| 525 // CheckExtensionIDs() | 621 // CheckExtensionIDs() |
| 526 // CheckResourceUrl() | 622 // CheckResourceUrl() |
| 527 | 623 |
| 528 } // namespace safe_browsing | 624 } // namespace safe_browsing |
| OLD | NEW |