1 // Copyright 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 #include "base/bind.h" 6 #include "base/message_loop/message_loop.h" 7 #include "base/run_loop.h" 8 #include "base/stl_util.h" 9 #include "chrome/browser/extensions/blacklist.h" 10 #include "chrome/browser/extensions/blacklist_state_fetcher.h" 11 #include "chrome/browser/extensions/fake_safe_browsing_database_manager.h" 12 #include "chrome/browser/extensions/test_blacklist.h" 13 #include "chrome/browser/extensions/test_blacklist_state_fetcher.h" 14 #include "chrome/browser/extensions/test_extension_prefs.h" 15 #include "content/public/test/test_browser_thread_bundle.h" 16 #include "extensions/browser/extension_prefs.h" 17 #include "testing/gtest/include/gtest/gtest.h" 18 19 namespace extensions { 20 namespace { 21 22 std::set<std::string> Set(const std::string& a) { 23 std::set<std::string> set; 24 set.insert(a); 25 return set; 26 } 27 std::set<std::string> Set(const std::string& a, const std::string& b) { 28 std::set<std::string> set = Set(a); 29 set.insert(b); 30 return set; 31 } 32 std::set<std::string> Set(const std::string& a, 33 const std::string& b, 34 const std::string& c) { 35 std::set<std::string> set = Set(a, b); 36 set.insert(c); 37 return set; 38 } 39 std::set<std::string> Set(const std::string& a, 40 const std::string& b, 41 const std::string& c, 42 const std::string& d) { 43 std::set<std::string> set = Set(a, b, c); 44 set.insert(d); 45 return set; 46 } 47 48 class BlacklistTest : public testing::Test { 49 public: 50 BlacklistTest() 51 : test_prefs_(base::MessageLoopProxy::current()) {} 52 53 protected: 54 ExtensionPrefs* prefs() { 55 return test_prefs_.prefs(); 56 } 57 58 std::string AddExtension(const std::string& id) { 59 return test_prefs_.AddExtension(id)->id(); 60 } 61 62 private: 63 content::TestBrowserThreadBundle browser_thread_bundle_; 64 65 TestExtensionPrefs test_prefs_; 66 }; 67 68 template<typename T> 69 void Assign(T *to, const T& from) { 70 *to = from; 71 } 72 73 } // namespace 74 75 TEST_F(BlacklistTest, OnlyIncludesRequestedIDs) { 76 std::string a = AddExtension("a"); 77 std::string b = AddExtension("b"); 78 std::string c = AddExtension("c"); 79 80 Blacklist blacklist(prefs()); 81 TestBlacklist tester(&blacklist); 82 tester.SetBlacklistState(a, BLACKLISTED_MALWARE, false); 83 tester.SetBlacklistState(b, BLACKLISTED_MALWARE, false); 84 85 EXPECT_EQ(BLACKLISTED_MALWARE, tester.GetBlacklistState(a)); 86 EXPECT_EQ(BLACKLISTED_MALWARE, tester.GetBlacklistState(b)); 87 EXPECT_EQ(NOT_BLACKLISTED, tester.GetBlacklistState(c)); 88 89 std::set<std::string> blacklisted_ids; 90 blacklist.GetMalwareIDs( 91 Set(a, c), base::Bind(&Assign<std::set<std::string> >, &blacklisted_ids)); 92 base::RunLoop().RunUntilIdle(); 93 94 EXPECT_EQ(Set(a), blacklisted_ids); 95 } 96 97 TEST_F(BlacklistTest, SafeBrowsing) { 98 std::string a = AddExtension("a"); 99 100 Blacklist blacklist(prefs()); 101 TestBlacklist tester(&blacklist); 102 tester.DisableSafeBrowsing(); 103 104 EXPECT_EQ(NOT_BLACKLISTED, tester.GetBlacklistState(a)); 105 106 tester.SetBlacklistState(a, BLACKLISTED_MALWARE, false); 107 // The manager is still disabled at this point, so it won't be blacklisted. 108 EXPECT_EQ(NOT_BLACKLISTED, tester.GetBlacklistState(a)); 109 110 tester.EnableSafeBrowsing(); 111 tester.NotifyUpdate(); 112 base::RunLoop().RunUntilIdle(); 113 // Now it should be. 114 EXPECT_EQ(BLACKLISTED_MALWARE, tester.GetBlacklistState(a)); 115 116 tester.Clear(true); 117 // Safe browsing blacklist empty, now enabled. 118 EXPECT_EQ(NOT_BLACKLISTED, tester.GetBlacklistState(a)); 119 } 120 121 // Tests that Blacklist clears the old prefs blacklist on startup. 122 TEST_F(BlacklistTest, ClearsPreferencesBlacklist) { 123 std::string a = AddExtension("a"); 124 std::string b = AddExtension("b"); 125 126 // Blacklist an installed extension. 127 prefs()->SetExtensionBlacklisted(a, true); 128 129 // Blacklist some non-installed extensions. This is what the old preferences 130 // blacklist looked like. 131 std::string c = "cccccccccccccccccccccccccccccccc"; 132 std::string d = "dddddddddddddddddddddddddddddddd"; 133 prefs()->SetExtensionBlacklisted(c, true); 134 prefs()->SetExtensionBlacklisted(d, true); 135 136 EXPECT_EQ(Set(a, c, d), prefs()->GetBlacklistedExtensions()); 137 138 Blacklist blacklist(prefs()); 139 TestBlacklist tester(&blacklist); 140 141 // Blacklist has been cleared. Only the installed extension "a" left. 142 EXPECT_EQ(Set(a), prefs()->GetBlacklistedExtensions()); 143 EXPECT_TRUE(prefs()->GetInstalledExtensionInfo(a).get()); 144 EXPECT_TRUE(prefs()->GetInstalledExtensionInfo(b).get()); 145 146 // "a" won't actually be *blacklisted* since it doesn't appear in 147 // safebrowsing. Blacklist no longer reads from prefs. This is purely a 148 // concern of somebody else (currently, ExtensionService). 149 std::set<std::string> blacklisted_ids; 150 blacklist.GetMalwareIDs(Set(a, b, c, d), 151 base::Bind(&Assign<std::set<std::string> >, 152 &blacklisted_ids)); 153 base::RunLoop().RunUntilIdle(); 154 EXPECT_EQ(std::set<std::string>(), blacklisted_ids); 155 156 // Prefs are still unaffected for installed extensions, though. 157 EXPECT_TRUE(prefs()->IsExtensionBlacklisted(a)); 158 EXPECT_FALSE(prefs()->IsExtensionBlacklisted(b)); 159 EXPECT_FALSE(prefs()->IsExtensionBlacklisted(c)); 160 EXPECT_FALSE(prefs()->IsExtensionBlacklisted(d)); 161 } 162 163 // Test getting different blacklist states from Blacklist. 164 TEST_F(BlacklistTest, GetBlacklistStates) { 165 Blacklist blacklist(prefs()); 166 TestBlacklist tester(&blacklist); 167 168 std::string a = AddExtension("a"); 169 std::string b = AddExtension("b"); 170 std::string c = AddExtension("c"); 171 std::string d = AddExtension("d"); 172 std::string e = AddExtension("e"); 173 174 tester.SetBlacklistState(a, BLACKLISTED_MALWARE, false); 175 tester.SetBlacklistState(b, BLACKLISTED_SECURITY_VULNERABILITY, false); 176 tester.SetBlacklistState(c, BLACKLISTED_CWS_POLICY_VIOLATION, false); 177 tester.SetBlacklistState(d, BLACKLISTED_POTENTIALLY_UNWANTED, false); 178 179 Blacklist::BlacklistStateMap states_abc; 180 Blacklist::BlacklistStateMap states_bcd; 181 blacklist.GetBlacklistedIDs(Set(a, b, c, e), 182 base::Bind(&Assign<Blacklist::BlacklistStateMap>, 183 &states_abc)); 184 blacklist.GetBlacklistedIDs(Set(b, c, d, e), 185 base::Bind(&Assign<Blacklist::BlacklistStateMap>, 186 &states_bcd)); 187 base::RunLoop().RunUntilIdle(); 188 189 EXPECT_EQ(BLACKLISTED_MALWARE, states_abc[a]); 190 EXPECT_EQ(BLACKLISTED_SECURITY_VULNERABILITY, states_abc[b]); 191 EXPECT_EQ(BLACKLISTED_CWS_POLICY_VIOLATION, states_abc[c]); 192 EXPECT_EQ(BLACKLISTED_SECURITY_VULNERABILITY, states_bcd[b]); 193 EXPECT_EQ(BLACKLISTED_CWS_POLICY_VIOLATION, states_bcd[c]); 194 EXPECT_EQ(BLACKLISTED_POTENTIALLY_UNWANTED, states_bcd[d]); 195 EXPECT_EQ(states_abc.end(), states_abc.find(e)); 196 EXPECT_EQ(states_bcd.end(), states_bcd.find(e)); 197 198 int old_request_count = tester.fetcher()->request_count(); 199 Blacklist::BlacklistStateMap states_ad; 200 blacklist.GetBlacklistedIDs(Set(a, d, e), 201 base::Bind(&Assign<Blacklist::BlacklistStateMap>, 202 &states_ad)); 203 base::RunLoop().RunUntilIdle(); 204 EXPECT_EQ(BLACKLISTED_MALWARE, states_ad[a]); 205 EXPECT_EQ(BLACKLISTED_POTENTIALLY_UNWANTED, states_ad[d]); 206 EXPECT_EQ(states_ad.end(), states_ad.find(e)); 207 EXPECT_EQ(old_request_count, tester.fetcher()->request_count()); 208 } 209 210 // Test both Blacklist and BlacklistStateFetcher by requesting the blacklist 211 // states, sending fake requests and parsing the responses. 212 TEST_F(BlacklistTest, FetchBlacklistStates) { 213 Blacklist blacklist(prefs()); 214 scoped_refptr<FakeSafeBrowsingDatabaseManager> blacklist_db( 215 new FakeSafeBrowsingDatabaseManager(true)); 216 Blacklist::ScopedDatabaseManagerForTest scoped_blacklist_db(blacklist_db); 217 218 std::string a = AddExtension("a"); 219 std::string b = AddExtension("b"); 220 std::string c = AddExtension("c"); 221 222 blacklist_db->Enable(); 223 blacklist_db->SetUnsafe(a, b); 224 225 // Prepare real fetcher. 226 BlacklistStateFetcher* fetcher = new BlacklistStateFetcher(); 227 TestBlacklistStateFetcher fetcher_tester(fetcher); 228 blacklist.SetBlacklistStateFetcherForTest(fetcher); 229 230 fetcher_tester.SetBlacklistVerdict( 231 a, ClientCRXListInfoResponse_Verdict_CWS_POLICY_VIOLATION); 232 fetcher_tester.SetBlacklistVerdict( 233 b, ClientCRXListInfoResponse_Verdict_POTENTIALLY_UNWANTED); 234 235 Blacklist::BlacklistStateMap states; 236 blacklist.GetBlacklistedIDs( 237 Set(a, b, c), base::Bind(&Assign<Blacklist::BlacklistStateMap>, &states)); 238 base::RunLoop().RunUntilIdle(); 239 240 // Two fetchers should be created. 241 EXPECT_TRUE(fetcher_tester.HandleFetcher(0)); 242 EXPECT_TRUE(fetcher_tester.HandleFetcher(1)); 243 244 EXPECT_EQ(BLACKLISTED_CWS_POLICY_VIOLATION, states[a]); 245 EXPECT_EQ(BLACKLISTED_POTENTIALLY_UNWANTED, states[b]); 246 EXPECT_EQ(states.end(), states.find(c)); 247 248 Blacklist::BlacklistStateMap cached_states; 249 250 blacklist.GetBlacklistedIDs( 251 Set(a, b, c), base::Bind(&Assign<Blacklist::BlacklistStateMap>, 252 &cached_states)); 253 base::RunLoop().RunUntilIdle(); 254 255 // No new fetchers. 256 EXPECT_FALSE(fetcher_tester.HandleFetcher(2)); 257 EXPECT_EQ(BLACKLISTED_CWS_POLICY_VIOLATION, cached_states[a]); 258 EXPECT_EQ(BLACKLISTED_POTENTIALLY_UNWANTED, cached_states[b]); 259 EXPECT_EQ(cached_states.end(), cached_states.find(c)); 260 } 261 262 } // namespace extensions 263