| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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 // Unit tests for the SafeBrowsing storage system. | 5 // Unit tests for the SafeBrowsing storage system. |
| 6 | 6 |
| 7 #include "chrome/browser/safe_browsing/safe_browsing_database.h" | 7 #include "chrome/browser/safe_browsing/safe_browsing_database.h" |
| 8 | 8 |
| 9 #include "base/files/file_util.h" | 9 #include "base/files/file_util.h" |
| 10 #include "base/files/scoped_temp_dir.h" | 10 #include "base/files/scoped_temp_dir.h" |
| 11 #include "base/logging.h" | 11 #include "base/logging.h" |
| 12 #include "base/memory/scoped_vector.h" | 12 #include "base/memory/scoped_vector.h" |
| 13 #include "base/message_loop/message_loop.h" | 13 #include "base/message_loop/message_loop.h" |
| 14 #include "base/sha1.h" | 14 #include "base/sha1.h" |
| 15 #include "base/strings/string_number_conversions.h" | 15 #include "base/strings/string_number_conversions.h" |
| 16 #include "base/strings/string_split.h" | 16 #include "base/strings/string_split.h" |
| 17 #include "base/time/time.h" | 17 #include "base/time/time.h" |
| 18 #include "chrome/browser/safe_browsing/chunk.pb.h" | 18 #include "chrome/browser/safe_browsing/chunk.pb.h" |
| 19 #include "chrome/browser/safe_browsing/safe_browsing_store_file.h" | 19 #include "chrome/browser/safe_browsing/safe_browsing_store_file.h" |
| 20 #include "content/public/test/test_browser_thread_bundle.h" | |
| 21 #include "crypto/sha2.h" | 20 #include "crypto/sha2.h" |
| 22 #include "net/base/net_util.h" | 21 #include "net/base/net_util.h" |
| 23 #include "sql/connection.h" | 22 #include "sql/connection.h" |
| 24 #include "sql/statement.h" | 23 #include "sql/statement.h" |
| 25 #include "testing/gtest/include/gtest/gtest.h" | 24 #include "testing/gtest/include/gtest/gtest.h" |
| 26 #include "testing/platform_test.h" | 25 #include "testing/platform_test.h" |
| 27 #include "url/gurl.h" | 26 #include "url/gurl.h" |
| 28 | 27 |
| 29 using base::Time; | 28 using base::Time; |
| 30 using base::TimeDelta; | 29 using base::TimeDelta; |
| (...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 324 void SubDelChunk(const std::string& list, int chunk_id) { | 323 void SubDelChunk(const std::string& list, int chunk_id) { |
| 325 DelChunk(list, chunk_id, true); | 324 DelChunk(list, chunk_id, true); |
| 326 } | 325 } |
| 327 | 326 |
| 328 // Utility function for setting up the database for the caching test. | 327 // Utility function for setting up the database for the caching test. |
| 329 void PopulateDatabaseForCacheTest(); | 328 void PopulateDatabaseForCacheTest(); |
| 330 | 329 |
| 331 scoped_ptr<SafeBrowsingDatabaseNew> database_; | 330 scoped_ptr<SafeBrowsingDatabaseNew> database_; |
| 332 base::FilePath database_filename_; | 331 base::FilePath database_filename_; |
| 333 base::ScopedTempDir temp_dir_; | 332 base::ScopedTempDir temp_dir_; |
| 334 | |
| 335 // We expect most checks made on |database_| to be made from the IO thread. | |
| 336 // Use this ThreadBundle to fake the IO thread in the main message loop in | |
| 337 // these tests. | |
| 338 content::TestBrowserThreadBundle thread_bundle_; | |
| 339 }; | 333 }; |
| 340 | 334 |
| 341 // Tests retrieving list name information. | 335 // Tests retrieving list name information. |
| 342 TEST_F(SafeBrowsingDatabaseTest, ListNameForBrowse) { | 336 TEST_F(SafeBrowsingDatabaseTest, ListNameForBrowse) { |
| 343 std::vector<SBListChunkRanges> lists; | 337 std::vector<SBListChunkRanges> lists; |
| 344 ScopedVector<SBChunkData> chunks; | 338 ScopedVector<SBChunkData> chunks; |
| 345 | 339 |
| 346 chunks.push_back(AddChunkPrefixValue(1, "www.evil.com/malware.html")); | 340 chunks.push_back(AddChunkPrefixValue(1, "www.evil.com/malware.html")); |
| 347 chunks.push_back(AddChunkPrefixValue(2, "www.foo.com/malware.html")); | 341 chunks.push_back(AddChunkPrefixValue(2, "www.foo.com/malware.html")); |
| 348 chunks.push_back(AddChunkPrefixValue(3, "www.whatever.com/malware.html")); | 342 chunks.push_back(AddChunkPrefixValue(3, "www.whatever.com/malware.html")); |
| (...skipping 480 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 829 chunks.push_back(AddChunkPrefix2Value(1, | 823 chunks.push_back(AddChunkPrefix2Value(1, |
| 830 "www.evil.com/phishing.html", | 824 "www.evil.com/phishing.html", |
| 831 "www.evil.com/malware.html")); | 825 "www.evil.com/malware.html")); |
| 832 | 826 |
| 833 std::vector<SBListChunkRanges> lists; | 827 std::vector<SBListChunkRanges> lists; |
| 834 ASSERT_TRUE(database_->UpdateStarted(&lists)); | 828 ASSERT_TRUE(database_->UpdateStarted(&lists)); |
| 835 database_->InsertChunks(safe_browsing_util::kMalwareList, chunks.get()); | 829 database_->InsertChunks(safe_browsing_util::kMalwareList, chunks.get()); |
| 836 database_->UpdateFinished(true); | 830 database_->UpdateFinished(true); |
| 837 | 831 |
| 838 // Cache should be cleared after updating. | 832 // Cache should be cleared after updating. |
| 839 EXPECT_TRUE(database_->prefix_gethash_cache_.empty()); | 833 EXPECT_TRUE( |
| 834 database_->GetUnsynchronizedPrefixGetHashCacheForTesting()->empty()); |
| 840 | 835 |
| 841 SBFullHashResult full_hash; | 836 SBFullHashResult full_hash; |
| 842 full_hash.list_id = safe_browsing_util::MALWARE; | 837 full_hash.list_id = safe_browsing_util::MALWARE; |
| 843 | 838 |
| 844 std::vector<SBFullHashResult> results; | 839 std::vector<SBFullHashResult> results; |
| 845 std::vector<SBPrefix> prefixes; | 840 std::vector<SBPrefix> prefixes; |
| 846 | 841 |
| 847 // Add a fullhash result for each prefix. | 842 // Add a fullhash result for each prefix. |
| 848 full_hash.hash = SBFullHashForString("www.evil.com/phishing.html"); | 843 full_hash.hash = SBFullHashForString("www.evil.com/phishing.html"); |
| 849 results.push_back(full_hash); | 844 results.push_back(full_hash); |
| 850 prefixes.push_back(full_hash.hash.prefix); | 845 prefixes.push_back(full_hash.hash.prefix); |
| 851 | 846 |
| 852 full_hash.hash = SBFullHashForString("www.evil.com/malware.html"); | 847 full_hash.hash = SBFullHashForString("www.evil.com/malware.html"); |
| 853 results.push_back(full_hash); | 848 results.push_back(full_hash); |
| 854 prefixes.push_back(full_hash.hash.prefix); | 849 prefixes.push_back(full_hash.hash.prefix); |
| 855 | 850 |
| 856 database_->CacheHashResults(prefixes, results, kCacheLifetime); | 851 database_->CacheHashResults(prefixes, results, kCacheLifetime); |
| 857 } | 852 } |
| 858 | 853 |
| 859 TEST_F(SafeBrowsingDatabaseTest, HashCaching) { | 854 TEST_F(SafeBrowsingDatabaseTest, HashCaching) { |
| 860 PopulateDatabaseForCacheTest(); | 855 PopulateDatabaseForCacheTest(); |
| 861 | 856 |
| 862 // We should have both full hashes in the cache. | 857 // We should have both full hashes in the cache. |
| 863 EXPECT_EQ(2U, database_->prefix_gethash_cache_.size()); | 858 EXPECT_EQ(2U, |
| 859 database_->GetUnsynchronizedPrefixGetHashCacheForTesting()->size()); |
| 864 | 860 |
| 865 // Test the cache lookup for the first prefix. | 861 // Test the cache lookup for the first prefix. |
| 866 std::vector<SBPrefix> prefix_hits; | 862 std::vector<SBPrefix> prefix_hits; |
| 867 std::vector<SBFullHashResult> cache_hits; | 863 std::vector<SBFullHashResult> cache_hits; |
| 868 EXPECT_TRUE(database_->ContainsBrowseUrl( | 864 EXPECT_TRUE(database_->ContainsBrowseUrl( |
| 869 GURL("http://www.evil.com/phishing.html"), &prefix_hits, &cache_hits)); | 865 GURL("http://www.evil.com/phishing.html"), &prefix_hits, &cache_hits)); |
| 870 EXPECT_TRUE(prefix_hits.empty()); | 866 EXPECT_TRUE(prefix_hits.empty()); |
| 871 ASSERT_EQ(1U, cache_hits.size()); | 867 ASSERT_EQ(1U, cache_hits.size()); |
| 872 EXPECT_TRUE(SBFullHashEqual( | 868 EXPECT_TRUE(SBFullHashEqual( |
| 873 cache_hits[0].hash, SBFullHashForString("www.evil.com/phishing.html"))); | 869 cache_hits[0].hash, SBFullHashForString("www.evil.com/phishing.html"))); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 909 GURL("http://www.evil.com/phishing.html"), &prefix_hits, &cache_hits)); | 905 GURL("http://www.evil.com/phishing.html"), &prefix_hits, &cache_hits)); |
| 910 prefix_hits.clear(); | 906 prefix_hits.clear(); |
| 911 cache_hits.clear(); | 907 cache_hits.clear(); |
| 912 | 908 |
| 913 // Test that an AddDel for the original chunk removes the last cached entry. | 909 // Test that an AddDel for the original chunk removes the last cached entry. |
| 914 ASSERT_TRUE(database_->UpdateStarted(&lists)); | 910 ASSERT_TRUE(database_->UpdateStarted(&lists)); |
| 915 AddDelChunk(safe_browsing_util::kMalwareList, 1); | 911 AddDelChunk(safe_browsing_util::kMalwareList, 1); |
| 916 database_->UpdateFinished(true); | 912 database_->UpdateFinished(true); |
| 917 EXPECT_FALSE(database_->ContainsBrowseUrl( | 913 EXPECT_FALSE(database_->ContainsBrowseUrl( |
| 918 GURL("http://www.evil.com/malware.html"), &prefix_hits, &cache_hits)); | 914 GURL("http://www.evil.com/malware.html"), &prefix_hits, &cache_hits)); |
| 919 EXPECT_TRUE(database_->prefix_gethash_cache_.empty()); | 915 EXPECT_TRUE( |
| 916 database_->GetUnsynchronizedPrefixGetHashCacheForTesting()->empty()); |
| 920 prefix_hits.clear(); | 917 prefix_hits.clear(); |
| 921 cache_hits.clear(); | 918 cache_hits.clear(); |
| 922 | 919 |
| 923 // Test that the cache won't return expired values. First we have to adjust | 920 // Test that the cache won't return expired values. First we have to adjust |
| 924 // the cached entries' received time to make them older, since the database | 921 // the cached entries' received time to make them older, since the database |
| 925 // cache insert uses Time::Now(). First, store some entries. | 922 // cache insert uses Time::Now(). First, store some entries. |
| 926 PopulateDatabaseForCacheTest(); | 923 PopulateDatabaseForCacheTest(); |
| 927 | 924 |
| 928 std::map<SBPrefix, SBCachedFullHashResult>* hash_cache = | 925 SafeBrowsingDatabaseNew::PrefixGetHashCache* hash_cache = |
| 929 &database_->prefix_gethash_cache_; | 926 database_->GetUnsynchronizedPrefixGetHashCacheForTesting(); |
| 930 EXPECT_EQ(2U, hash_cache->size()); | 927 EXPECT_EQ(2U, hash_cache->size()); |
| 931 | 928 |
| 932 // Now adjust one of the entries times to be in the past. | 929 // Now adjust one of the entries times to be in the past. |
| 933 const SBPrefix key = SBPrefixForString("www.evil.com/malware.html"); | 930 const SBPrefix key = SBPrefixForString("www.evil.com/malware.html"); |
| 934 std::map<SBPrefix, SBCachedFullHashResult>::iterator iter = | 931 SafeBrowsingDatabaseNew::PrefixGetHashCache::iterator iter = |
| 935 hash_cache->find(key); | 932 hash_cache->find(key); |
| 936 ASSERT_TRUE(iter != hash_cache->end()); | 933 ASSERT_TRUE(iter != hash_cache->end()); |
| 937 iter->second.expire_after = Time::Now() - TimeDelta::FromMinutes(1); | 934 iter->second.expire_after = Time::Now() - TimeDelta::FromMinutes(1); |
| 938 | 935 |
| 939 EXPECT_TRUE(database_->ContainsBrowseUrl( | 936 EXPECT_TRUE(database_->ContainsBrowseUrl( |
| 940 GURL("http://www.evil.com/malware.html"), &prefix_hits, &cache_hits)); | 937 GURL("http://www.evil.com/malware.html"), &prefix_hits, &cache_hits)); |
| 941 EXPECT_EQ(1U, prefix_hits.size()); | 938 EXPECT_EQ(1U, prefix_hits.size()); |
| 942 EXPECT_TRUE(cache_hits.empty()); | 939 EXPECT_TRUE(cache_hits.empty()); |
| 943 // Expired entry should have been removed from cache. | 940 // Expired entry should have been removed from cache. |
| 944 EXPECT_EQ(1U, hash_cache->size()); | 941 EXPECT_EQ(1U, hash_cache->size()); |
| (...skipping 939 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1884 | 1881 |
| 1885 // Remove kFullHash1_1 from the database. | 1882 // Remove kFullHash1_1 from the database. |
| 1886 chunks.clear(); | 1883 chunks.clear(); |
| 1887 chunks.push_back(SubChunkFullHash(11, kFullHash1_1, 1)); | 1884 chunks.push_back(SubChunkFullHash(11, kFullHash1_1, 1)); |
| 1888 | 1885 |
| 1889 ASSERT_TRUE(database_->UpdateStarted(&lists)); | 1886 ASSERT_TRUE(database_->UpdateStarted(&lists)); |
| 1890 database_->InsertChunks(safe_browsing_util::kMalwareList, chunks.get()); | 1887 database_->InsertChunks(safe_browsing_util::kMalwareList, chunks.get()); |
| 1891 database_->UpdateFinished(true); | 1888 database_->UpdateFinished(true); |
| 1892 | 1889 |
| 1893 // Cache should be cleared after updating. | 1890 // Cache should be cleared after updating. |
| 1894 EXPECT_TRUE(database_->prefix_gethash_cache_.empty()); | 1891 EXPECT_TRUE( |
| 1892 database_->GetUnsynchronizedPrefixGetHashCacheForTesting()->empty()); |
| 1895 | 1893 |
| 1896 { | 1894 { |
| 1897 // Now the database doesn't contain kFullHash1_1. | 1895 // Now the database doesn't contain kFullHash1_1. |
| 1898 std::vector<SBFullHash> full_hashes(1, kFullHash1_1); | 1896 std::vector<SBFullHash> full_hashes(1, kFullHash1_1); |
| 1899 std::vector<SBPrefix> prefix_hits; | 1897 std::vector<SBPrefix> prefix_hits; |
| 1900 std::vector<SBFullHashResult> cache_hits; | 1898 std::vector<SBFullHashResult> cache_hits; |
| 1901 EXPECT_FALSE(database_->ContainsBrowseUrlHashesForTesting( | 1899 EXPECT_FALSE(database_->ContainsBrowseUrlHashesForTesting( |
| 1902 full_hashes, &prefix_hits, &cache_hits)); | 1900 full_hashes, &prefix_hits, &cache_hits)); |
| 1903 | 1901 |
| 1904 // Nor kFullHash1_3. | 1902 // Nor kFullHash1_3. |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1921 | 1919 |
| 1922 // Remove kFullHash1_2 from the database. | 1920 // Remove kFullHash1_2 from the database. |
| 1923 chunks.clear(); | 1921 chunks.clear(); |
| 1924 chunks.push_back(SubChunkFullHash(12, kFullHash1_2, 2)); | 1922 chunks.push_back(SubChunkFullHash(12, kFullHash1_2, 2)); |
| 1925 | 1923 |
| 1926 ASSERT_TRUE(database_->UpdateStarted(&lists)); | 1924 ASSERT_TRUE(database_->UpdateStarted(&lists)); |
| 1927 database_->InsertChunks(safe_browsing_util::kMalwareList, chunks.get()); | 1925 database_->InsertChunks(safe_browsing_util::kMalwareList, chunks.get()); |
| 1928 database_->UpdateFinished(true); | 1926 database_->UpdateFinished(true); |
| 1929 | 1927 |
| 1930 // Cache should be cleared after updating. | 1928 // Cache should be cleared after updating. |
| 1931 EXPECT_TRUE(database_->prefix_gethash_cache_.empty()); | 1929 EXPECT_TRUE( |
| 1930 database_->GetUnsynchronizedPrefixGetHashCacheForTesting()->empty()); |
| 1932 | 1931 |
| 1933 { | 1932 { |
| 1934 // None are present. | 1933 // None are present. |
| 1935 std::vector<SBFullHash> full_hashes; | 1934 std::vector<SBFullHash> full_hashes; |
| 1936 std::vector<SBPrefix> prefix_hits; | 1935 std::vector<SBPrefix> prefix_hits; |
| 1937 std::vector<SBFullHashResult> cache_hits; | 1936 std::vector<SBFullHashResult> cache_hits; |
| 1938 full_hashes.push_back(kFullHash1_1); | 1937 full_hashes.push_back(kFullHash1_1); |
| 1939 full_hashes.push_back(kFullHash1_2); | 1938 full_hashes.push_back(kFullHash1_2); |
| 1940 full_hashes.push_back(kFullHash1_3); | 1939 full_hashes.push_back(kFullHash1_3); |
| 1941 EXPECT_FALSE(database_->ContainsBrowseUrlHashesForTesting( | 1940 EXPECT_FALSE(database_->ContainsBrowseUrlHashesForTesting( |
| (...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2136 GURL(std::string("http://") + kExampleCollision), | 2135 GURL(std::string("http://") + kExampleCollision), |
| 2137 &prefix_hits, &cache_hits)); | 2136 &prefix_hits, &cache_hits)); |
| 2138 ASSERT_EQ(1U, prefix_hits.size()); | 2137 ASSERT_EQ(1U, prefix_hits.size()); |
| 2139 EXPECT_EQ(SBPrefixForString(kExampleCollision), prefix_hits[0]); | 2138 EXPECT_EQ(SBPrefixForString(kExampleCollision), prefix_hits[0]); |
| 2140 EXPECT_TRUE(cache_hits.empty()); | 2139 EXPECT_TRUE(cache_hits.empty()); |
| 2141 | 2140 |
| 2142 // This prefix collides, but no full hash match. | 2141 // This prefix collides, but no full hash match. |
| 2143 EXPECT_FALSE(database_->ContainsBrowseUrl( | 2142 EXPECT_FALSE(database_->ContainsBrowseUrl( |
| 2144 GURL(std::string("http://") + kExampleFine), &prefix_hits, &cache_hits)); | 2143 GURL(std::string("http://") + kExampleFine), &prefix_hits, &cache_hits)); |
| 2145 } | 2144 } |
| OLD | NEW |