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 3 // found in the LICENSE file. 4 5 #include "components/policy/core/browser/url_blacklist_manager.h" 6 7 #include <ostream> 8 9 #include "base/basictypes.h" 10 #include "base/callback.h" 11 #include "base/message_loop/message_loop.h" 12 #include "base/message_loop/message_loop_proxy.h" 13 #include "base/prefs/pref_registry_simple.h" 14 #include "base/prefs/testing_pref_service.h" 15 #include "chrome/browser/policy/policy_helpers.h" 16 #include "components/policy/core/common/policy_pref_names.h" 17 #include "components/url_fixer/url_fixer.h" 18 #include "google_apis/gaia/gaia_urls.h" 19 #include "net/base/load_flags.h" 20 #include "net/base/net_errors.h" 21 #include "net/base/request_priority.h" 22 #include "net/url_request/url_request.h" 23 #include "net/url_request/url_request_test_util.h" 24 #include "testing/gtest/include/gtest/gtest.h" 25 #include "url/gurl.h" 26 27 // TODO(joaodasilva): this file should be moved next to 28 // components/policy/core/browser/url_blacklist_manager.(cc|h). 29 // However, url_fixer_upper.h can't be included from the component. Rather 30 // than having it mocked out, the actual url_fixer::SegmentURL call is used 31 // to make sure that the parsing of URL filters is correct. 32 33 namespace policy { 34 35 namespace { 36 37 // Helper to get the disambiguated SegmentURL() function. 38 URLBlacklist::SegmentURLCallback GetSegmentURLCallback() { 39 return url_fixer::SegmentURL; 40 } 41 42 class TestingURLBlacklistManager : public URLBlacklistManager { 43 public: 44 explicit TestingURLBlacklistManager(PrefService* pref_service) 45 : URLBlacklistManager(pref_service, 46 base::MessageLoopProxy::current(), 47 base::MessageLoopProxy::current(), 48 GetSegmentURLCallback(), 49 base::Bind(OverrideBlacklistForURL)), 50 update_called_(0), 51 set_blacklist_called_(false) {} 52 53 virtual ~TestingURLBlacklistManager() { 54 } 55 56 // Make this method public for testing. 57 using URLBlacklistManager::ScheduleUpdate; 58 59 // Makes a direct call to UpdateOnIO during tests. 60 void UpdateOnIOForTesting() { 61 scoped_ptr<base::ListValue> block(new base::ListValue); 62 block->Append(new base::StringValue("example.com")); 63 scoped_ptr<base::ListValue> allow(new base::ListValue); 64 URLBlacklistManager::UpdateOnIO(block.Pass(), allow.Pass()); 65 } 66 67 // URLBlacklistManager overrides: 68 virtual void SetBlacklist(scoped_ptr<URLBlacklist> blacklist) OVERRIDE { 69 set_blacklist_called_ = true; 70 URLBlacklistManager::SetBlacklist(blacklist.Pass()); 71 } 72 73 virtual void Update() OVERRIDE { 74 update_called_++; 75 URLBlacklistManager::Update(); 76 } 77 78 int update_called() const { return update_called_; } 79 bool set_blacklist_called() const { return set_blacklist_called_; } 80 81 private: 82 int update_called_; 83 bool set_blacklist_called_; 84 85 DISALLOW_COPY_AND_ASSIGN(TestingURLBlacklistManager); 86 }; 87 88 class URLBlacklistManagerTest : public testing::Test { 89 protected: 90 URLBlacklistManagerTest() {} 91 92 virtual void SetUp() OVERRIDE { 93 pref_service_.registry()->RegisterListPref(policy_prefs::kUrlBlacklist); 94 pref_service_.registry()->RegisterListPref(policy_prefs::kUrlWhitelist); 95 blacklist_manager_.reset(new TestingURLBlacklistManager(&pref_service_)); 96 loop_.RunUntilIdle(); 97 } 98 99 virtual void TearDown() OVERRIDE { 100 if (blacklist_manager_.get()) 101 blacklist_manager_->ShutdownOnUIThread(); 102 loop_.RunUntilIdle(); 103 // Delete |blacklist_manager_| while |io_thread_| is mapping IO to 104 // |loop_|. 105 blacklist_manager_.reset(); 106 } 107 108 base::MessageLoopForIO loop_; 109 TestingPrefServiceSimple pref_service_; 110 scoped_ptr<TestingURLBlacklistManager> blacklist_manager_; 111 }; 112 113 // Parameters for the FilterToComponents test. 114 struct FilterTestParams { 115 public: 116 FilterTestParams(const std::string& filter, const std::string& scheme, 117 const std::string& host, bool match_subdomains, uint16 port, 118 const std::string& path) 119 : filter_(filter), scheme_(scheme), host_(host), 120 match_subdomains_(match_subdomains), port_(port), path_(path) {} 121 122 FilterTestParams(const FilterTestParams& params) 123 : filter_(params.filter_), scheme_(params.scheme_), host_(params.host_), 124 match_subdomains_(params.match_subdomains_), port_(params.port_), 125 path_(params.path_) {} 126 127 const FilterTestParams& operator=(const FilterTestParams& params) { 128 filter_ = params.filter_; 129 scheme_ = params.scheme_; 130 host_ = params.host_; 131 match_subdomains_ = params.match_subdomains_; 132 port_ = params.port_; 133 path_ = params.path_; 134 return *this; 135 } 136 137 const std::string& filter() const { return filter_; } 138 const std::string& scheme() const { return scheme_; } 139 const std::string& host() const { return host_; } 140 bool match_subdomains() const { return match_subdomains_; } 141 uint16 port() const { return port_; } 142 const std::string& path() const { return path_; } 143 144 private: 145 std::string filter_; 146 std::string scheme_; 147 std::string host_; 148 bool match_subdomains_; 149 uint16 port_; 150 std::string path_; 151 }; 152 153 // Make Valgrind happy. Without this function, a generic one will print the 154 // raw bytes in FilterTestParams, which due to some likely padding will access 155 // uninitialized memory. 156 void PrintTo(const FilterTestParams& params, std::ostream* os) { 157 *os << params.filter(); 158 } 159 160 class URLBlacklistFilterToComponentsTest 161 : public testing::TestWithParam<FilterTestParams> { 162 public: 163 URLBlacklistFilterToComponentsTest() {} 164 165 private: 166 DISALLOW_COPY_AND_ASSIGN(URLBlacklistFilterToComponentsTest); 167 }; 168 169 } // namespace 170 171 TEST_P(URLBlacklistFilterToComponentsTest, FilterToComponents) { 172 std::string scheme; 173 std::string host; 174 bool match_subdomains = true; 175 uint16 port = 42; 176 std::string path; 177 178 URLBlacklist::FilterToComponents(GetSegmentURLCallback(), 179 GetParam().filter(), 180 &scheme, 181 &host, 182 &match_subdomains, 183 &port, 184 &path, 185 NULL); 186 EXPECT_EQ(GetParam().scheme(), scheme); 187 EXPECT_EQ(GetParam().host(), host); 188 EXPECT_EQ(GetParam().match_subdomains(), match_subdomains); 189 EXPECT_EQ(GetParam().port(), port); 190 EXPECT_EQ(GetParam().path(), path); 191 } 192 193 TEST_F(URLBlacklistManagerTest, SingleUpdateForTwoPrefChanges) { 194 base::ListValue* blacklist = new base::ListValue; 195 blacklist->Append(new base::StringValue("*.google.com")); 196 base::ListValue* whitelist = new base::ListValue; 197 whitelist->Append(new base::StringValue("mail.google.com")); 198 pref_service_.SetManagedPref(policy_prefs::kUrlBlacklist, blacklist); 199 pref_service_.SetManagedPref(policy_prefs::kUrlBlacklist, whitelist); 200 loop_.RunUntilIdle(); 201 202 EXPECT_EQ(1, blacklist_manager_->update_called()); 203 } 204 205 TEST_F(URLBlacklistManagerTest, ShutdownWithPendingTask0) { 206 // Post an update task to the UI thread. 207 blacklist_manager_->ScheduleUpdate(); 208 // Shutdown comes before the task is executed. 209 blacklist_manager_->ShutdownOnUIThread(); 210 blacklist_manager_.reset(); 211 // Run the task after shutdown and deletion. 212 loop_.RunUntilIdle(); 213 } 214 215 TEST_F(URLBlacklistManagerTest, ShutdownWithPendingTask1) { 216 // Post an update task. 217 blacklist_manager_->ScheduleUpdate(); 218 // Shutdown comes before the task is executed. 219 blacklist_manager_->ShutdownOnUIThread(); 220 // Run the task after shutdown, but before deletion. 221 loop_.RunUntilIdle(); 222 223 EXPECT_EQ(0, blacklist_manager_->update_called()); 224 blacklist_manager_.reset(); 225 loop_.RunUntilIdle(); 226 } 227 228 TEST_F(URLBlacklistManagerTest, ShutdownWithPendingTask2) { 229 // This posts a task to the FILE thread. 230 blacklist_manager_->UpdateOnIOForTesting(); 231 // But shutdown happens before it is done. 232 blacklist_manager_->ShutdownOnUIThread(); 233 234 EXPECT_FALSE(blacklist_manager_->set_blacklist_called()); 235 blacklist_manager_.reset(); 236 loop_.RunUntilIdle(); 237 } 238 239 INSTANTIATE_TEST_CASE_P( 240 URLBlacklistFilterToComponentsTestInstance, 241 URLBlacklistFilterToComponentsTest, 242 testing::Values( 243 FilterTestParams("google.com", 244 std::string(), 245 ".google.com", 246 true, 247 0u, 248 std::string()), 249 FilterTestParams(".google.com", 250 std::string(), 251 "google.com", 252 false, 253 0u, 254 std::string()), 255 FilterTestParams("http://google.com", 256 "http", 257 ".google.com", 258 true, 259 0u, 260 std::string()), 261 FilterTestParams("google.com/", 262 std::string(), 263 ".google.com", 264 true, 265 0u, 266 "/"), 267 FilterTestParams("http://google.com:8080/whatever", 268 "http", 269 ".google.com", 270 true, 271 8080u, 272 "/whatever"), 273 FilterTestParams("http://user:pass@google.com:8080/whatever", 274 "http", 275 ".google.com", 276 true, 277 8080u, 278 "/whatever"), 279 FilterTestParams("123.123.123.123", 280 std::string(), 281 "123.123.123.123", 282 false, 283 0u, 284 std::string()), 285 FilterTestParams("https://123.123.123.123", 286 "https", 287 "123.123.123.123", 288 false, 289 0u, 290 std::string()), 291 FilterTestParams("123.123.123.123/", 292 std::string(), 293 "123.123.123.123", 294 false, 295 0u, 296 "/"), 297 FilterTestParams("http://123.123.123.123:123/whatever", 298 "http", 299 "123.123.123.123", 300 false, 301 123u, 302 "/whatever"), 303 FilterTestParams("*", 304 std::string(), 305 std::string(), 306 true, 307 0u, 308 std::string()), 309 FilterTestParams("ftp://*", 310 "ftp", 311 std::string(), 312 true, 313 0u, 314 std::string()), 315 FilterTestParams("http://*/whatever", 316 "http", 317 std::string(), 318 true, 319 0u, 320 "/whatever"))); 321 322 TEST_F(URLBlacklistManagerTest, Filtering) { 323 URLBlacklist blacklist(GetSegmentURLCallback()); 324 325 // Block domain and all subdomains, for any filtered scheme. 326 scoped_ptr<base::ListValue> blocked(new base::ListValue); 327 blocked->Append(new base::StringValue("google.com")); 328 blacklist.Block(blocked.get()); 329 EXPECT_TRUE(blacklist.IsURLBlocked(GURL("http://google.com"))); 330 EXPECT_TRUE(blacklist.IsURLBlocked(GURL("http://google.com/"))); 331 EXPECT_TRUE(blacklist.IsURLBlocked(GURL("http://google.com/whatever"))); 332 EXPECT_TRUE(blacklist.IsURLBlocked(GURL("https://google.com/"))); 333 EXPECT_FALSE(blacklist.IsURLBlocked(GURL("bogus://google.com/"))); 334 EXPECT_FALSE(blacklist.IsURLBlocked(GURL("http://notgoogle.com/"))); 335 EXPECT_TRUE(blacklist.IsURLBlocked(GURL("http://mail.google.com"))); 336 EXPECT_TRUE(blacklist.IsURLBlocked(GURL("http://x.mail.google.com"))); 337 EXPECT_TRUE(blacklist.IsURLBlocked(GURL("https://x.mail.google.com/"))); 338 EXPECT_TRUE(blacklist.IsURLBlocked(GURL("http://x.y.google.com/a/b"))); 339 EXPECT_FALSE(blacklist.IsURLBlocked(GURL("http://youtube.com/"))); 340 341 // Filter only http, ftp and ws schemes. 342 blocked.reset(new base::ListValue); 343 blocked->Append(new base::StringValue("http://secure.com")); 344 blocked->Append(new base::StringValue("ftp://secure.com")); 345 blocked->Append(new base::StringValue("ws://secure.com")); 346 blacklist.Block(blocked.get()); 347 EXPECT_TRUE(blacklist.IsURLBlocked(GURL("http://secure.com"))); 348 EXPECT_TRUE(blacklist.IsURLBlocked(GURL("http://secure.com/whatever"))); 349 EXPECT_TRUE(blacklist.IsURLBlocked(GURL("ftp://secure.com/"))); 350 EXPECT_TRUE(blacklist.IsURLBlocked(GURL("ws://secure.com"))); 351 EXPECT_FALSE(blacklist.IsURLBlocked(GURL("https://secure.com/"))); 352 EXPECT_FALSE(blacklist.IsURLBlocked(GURL("wss://secure.com"))); 353 EXPECT_TRUE(blacklist.IsURLBlocked(GURL("http://www.secure.com"))); 354 EXPECT_FALSE(blacklist.IsURLBlocked(GURL("https://www.secure.com"))); 355 EXPECT_FALSE(blacklist.IsURLBlocked(GURL("wss://www.secure.com"))); 356 357 // Filter only a certain path prefix. 358 blocked.reset(new base::ListValue); 359 blocked->Append(new base::StringValue("path.to/ruin")); 360 blacklist.Block(blocked.get()); 361 EXPECT_TRUE(blacklist.IsURLBlocked(GURL("http://path.to/ruin"))); 362 EXPECT_TRUE(blacklist.IsURLBlocked(GURL("https://path.to/ruin"))); 363 EXPECT_TRUE(blacklist.IsURLBlocked(GURL("http://path.to/ruins"))); 364 EXPECT_TRUE(blacklist.IsURLBlocked(GURL("http://path.to/ruin/signup"))); 365 EXPECT_TRUE(blacklist.IsURLBlocked(GURL("http://www.path.to/ruin"))); 366 EXPECT_FALSE(blacklist.IsURLBlocked(GURL("http://path.to/fortune"))); 367 368 // Filter only a certain path prefix and scheme. 369 blocked.reset(new base::ListValue); 370 blocked->Append(new base::StringValue("https://s.aaa.com/path")); 371 blacklist.Block(blocked.get()); 372 EXPECT_TRUE(blacklist.IsURLBlocked(GURL("https://s.aaa.com/path"))); 373 EXPECT_TRUE(blacklist.IsURLBlocked(GURL("https://s.aaa.com/path/bbb"))); 374 EXPECT_FALSE(blacklist.IsURLBlocked(GURL("http://s.aaa.com/path"))); 375 EXPECT_FALSE(blacklist.IsURLBlocked(GURL("https://aaa.com/path"))); 376 EXPECT_FALSE(blacklist.IsURLBlocked(GURL("https://x.aaa.com/path"))); 377 EXPECT_FALSE(blacklist.IsURLBlocked(GURL("https://s.aaa.com/bbb"))); 378 EXPECT_FALSE(blacklist.IsURLBlocked(GURL("https://s.aaa.com/"))); 379 380 // Filter only ws and wss schemes. 381 blocked.reset(new base::ListValue); 382 blocked->Append(new base::StringValue("ws://ws.aaa.com")); 383 blocked->Append(new base::StringValue("wss://ws.aaa.com")); 384 blacklist.Block(blocked.get()); 385 EXPECT_TRUE(blacklist.IsURLBlocked(GURL("ws://ws.aaa.com"))); 386 EXPECT_TRUE(blacklist.IsURLBlocked(GURL("wss://ws.aaa.com"))); 387 EXPECT_FALSE(blacklist.IsURLBlocked(GURL("http://ws.aaa.com"))); 388 EXPECT_FALSE(blacklist.IsURLBlocked(GURL("https://ws.aaa.com"))); 389 EXPECT_FALSE(blacklist.IsURLBlocked(GURL("ftp://ws.aaa.com"))); 390 391 // Test exceptions to path prefixes, and most specific matches. 392 blocked.reset(new base::ListValue); 393 scoped_ptr<base::ListValue> allowed(new base::ListValue); 394 blocked->Append(new base::StringValue("s.xxx.com/a")); 395 allowed->Append(new base::StringValue("s.xxx.com/a/b")); 396 blocked->Append(new base::StringValue("https://s.xxx.com/a/b/c")); 397 allowed->Append(new base::StringValue("https://s.xxx.com/a/b/c/d")); 398 blacklist.Block(blocked.get()); 399 blacklist.Allow(allowed.get()); 400 EXPECT_TRUE(blacklist.IsURLBlocked(GURL("http://s.xxx.com/a"))); 401 EXPECT_TRUE(blacklist.IsURLBlocked(GURL("http://s.xxx.com/a/x"))); 402 EXPECT_TRUE(blacklist.IsURLBlocked(GURL("https://s.xxx.com/a/x"))); 403 EXPECT_FALSE(blacklist.IsURLBlocked(GURL("http://s.xxx.com/a/b"))); 404 EXPECT_FALSE(blacklist.IsURLBlocked(GURL("https://s.xxx.com/a/b"))); 405 EXPECT_FALSE(blacklist.IsURLBlocked(GURL("http://s.xxx.com/a/b/x"))); 406 EXPECT_FALSE(blacklist.IsURLBlocked(GURL("http://s.xxx.com/a/b/c"))); 407 EXPECT_TRUE(blacklist.IsURLBlocked(GURL("https://s.xxx.com/a/b/c"))); 408 EXPECT_TRUE(blacklist.IsURLBlocked(GURL("https://s.xxx.com/a/b/c/x"))); 409 EXPECT_FALSE(blacklist.IsURLBlocked(GURL("https://s.xxx.com/a/b/c/d"))); 410 EXPECT_FALSE(blacklist.IsURLBlocked(GURL("http://s.xxx.com/a/b/c/d"))); 411 EXPECT_FALSE(blacklist.IsURLBlocked(GURL("https://s.xxx.com/a/b/c/d/x"))); 412 EXPECT_FALSE(blacklist.IsURLBlocked(GURL("http://s.xxx.com/a/b/c/d/x"))); 413 EXPECT_FALSE(blacklist.IsURLBlocked(GURL("http://xxx.com/a"))); 414 EXPECT_FALSE(blacklist.IsURLBlocked(GURL("http://xxx.com/a/b"))); 415 416 // Block an ip address. 417 blocked.reset(new base::ListValue); 418 blocked->Append(new base::StringValue("123.123.123.123")); 419 blacklist.Block(blocked.get()); 420 EXPECT_TRUE(blacklist.IsURLBlocked(GURL("http://123.123.123.123/"))); 421 EXPECT_FALSE(blacklist.IsURLBlocked(GURL("http://123.123.123.124/"))); 422 423 // Open an exception. 424 allowed.reset(new base::ListValue); 425 allowed->Append(new base::StringValue("plus.google.com")); 426 blacklist.Allow(allowed.get()); 427 EXPECT_TRUE(blacklist.IsURLBlocked(GURL("http://google.com/"))); 428 EXPECT_TRUE(blacklist.IsURLBlocked(GURL("http://www.google.com/"))); 429 EXPECT_FALSE(blacklist.IsURLBlocked(GURL("http://plus.google.com/"))); 430 431 // Open an exception only when using https for mail. 432 allowed.reset(new base::ListValue); 433 allowed->Append(new base::StringValue("https://mail.google.com")); 434 blacklist.Allow(allowed.get()); 435 EXPECT_TRUE(blacklist.IsURLBlocked(GURL("http://google.com/"))); 436 EXPECT_TRUE(blacklist.IsURLBlocked(GURL("http://mail.google.com/"))); 437 EXPECT_TRUE(blacklist.IsURLBlocked(GURL("http://www.google.com/"))); 438 EXPECT_TRUE(blacklist.IsURLBlocked(GURL("https://www.google.com/"))); 439 EXPECT_FALSE(blacklist.IsURLBlocked(GURL("https://mail.google.com/"))); 440 441 // Match exactly "google.com", only for http. Subdomains without exceptions 442 // are still blocked. 443 allowed.reset(new base::ListValue); 444 allowed->Append(new base::StringValue("http://.google.com")); 445 blacklist.Allow(allowed.get()); 446 EXPECT_FALSE(blacklist.IsURLBlocked(GURL("http://google.com/"))); 447 EXPECT_TRUE(blacklist.IsURLBlocked(GURL("https://google.com/"))); 448 EXPECT_TRUE(blacklist.IsURLBlocked(GURL("http://www.google.com/"))); 449 450 // A smaller path match in an exact host overrides a longer path for hosts 451 // that also match subdomains. 452 blocked.reset(new base::ListValue); 453 blocked->Append(new base::StringValue("yyy.com/aaa")); 454 blacklist.Block(blocked.get()); 455 allowed.reset(new base::ListValue); 456 allowed->Append(new base::StringValue(".yyy.com/a")); 457 blacklist.Allow(allowed.get()); 458 EXPECT_FALSE(blacklist.IsURLBlocked(GURL("http://yyy.com"))); 459 EXPECT_FALSE(blacklist.IsURLBlocked(GURL("http://yyy.com/aaa"))); 460 EXPECT_FALSE(blacklist.IsURLBlocked(GURL("http://yyy.com/aaa2"))); 461 EXPECT_FALSE(blacklist.IsURLBlocked(GURL("http://www.yyy.com"))); 462 EXPECT_TRUE(blacklist.IsURLBlocked(GURL("http://www.yyy.com/aaa"))); 463 EXPECT_TRUE(blacklist.IsURLBlocked(GURL("http://www.yyy.com/aaa2"))); 464 465 // If the exact entry is both allowed and blocked, allowing takes precedence. 466 blocked.reset(new base::ListValue); 467 blocked->Append(new base::StringValue("example.com")); 468 blacklist.Block(blocked.get()); 469 allowed.reset(new base::ListValue); 470 allowed->Append(new base::StringValue("example.com")); 471 blacklist.Allow(allowed.get()); 472 EXPECT_FALSE(blacklist.IsURLBlocked(GURL("http://example.com"))); 473 } 474 475 TEST_F(URLBlacklistManagerTest, QueryParameters) { 476 URLBlacklist blacklist(GetSegmentURLCallback()); 477 scoped_ptr<base::ListValue> blocked(new base::ListValue); 478 scoped_ptr<base::ListValue> allowed(new base::ListValue); 479 480 // Block domain and all subdomains, for any filtered scheme. 481 blocked->AppendString("youtube.com"); 482 allowed->AppendString("youtube.com/watch?v=XYZ"); 483 blacklist.Block(blocked.get()); 484 blacklist.Allow(allowed.get()); 485 486 EXPECT_TRUE(blacklist.IsURLBlocked(GURL("http://youtube.com"))); 487 EXPECT_TRUE(blacklist.IsURLBlocked(GURL("http://youtube.com/watch?v=123"))); 488 EXPECT_TRUE( 489 blacklist.IsURLBlocked(GURL("http://youtube.com/watch?v=123&v=XYZ"))); 490 EXPECT_TRUE( 491 blacklist.IsURLBlocked(GURL("http://youtube.com/watch?v=XYZ&v=123"))); 492 EXPECT_FALSE(blacklist.IsURLBlocked(GURL("http://youtube.com/watch?v=XYZ"))); 493 EXPECT_FALSE( 494 blacklist.IsURLBlocked(GURL("http://youtube.com/watch?v=XYZ&foo=bar"))); 495 EXPECT_FALSE( 496 blacklist.IsURLBlocked(GURL("http://youtube.com/watch?foo=bar&v=XYZ"))); 497 498 allowed.reset(new base::ListValue); 499 allowed->AppendString("youtube.com/watch?av=XYZ&ag=123"); 500 blacklist.Allow(allowed.get()); 501 EXPECT_TRUE(blacklist.IsURLBlocked(GURL("http://youtube.com"))); 502 EXPECT_TRUE(blacklist.IsURLBlocked(GURL("http://youtube.com/watch?av=123"))); 503 EXPECT_TRUE(blacklist.IsURLBlocked(GURL("http://youtube.com/watch?av=XYZ"))); 504 EXPECT_TRUE( 505 blacklist.IsURLBlocked(GURL("http://youtube.com/watch?av=123&ag=XYZ"))); 506 EXPECT_TRUE( 507 blacklist.IsURLBlocked(GURL("http://youtube.com/watch?ag=XYZ&av=123"))); 508 EXPECT_FALSE( 509 blacklist.IsURLBlocked(GURL("http://youtube.com/watch?av=XYZ&ag=123"))); 510 EXPECT_FALSE( 511 blacklist.IsURLBlocked(GURL("http://youtube.com/watch?ag=123&av=XYZ"))); 512 EXPECT_TRUE(blacklist.IsURLBlocked( 513 GURL("http://youtube.com/watch?av=XYZ&ag=123&av=123"))); 514 EXPECT_TRUE(blacklist.IsURLBlocked( 515 GURL("http://youtube.com/watch?av=XYZ&ag=123&ag=1234"))); 516 517 allowed.reset(new base::ListValue); 518 allowed->AppendString("youtube.com/watch?foo=bar*&vid=2*"); 519 blacklist.Allow(allowed.get()); 520 EXPECT_TRUE(blacklist.IsURLBlocked(GURL("http://youtube.com"))); 521 EXPECT_TRUE(blacklist.IsURLBlocked(GURL("http://youtube.com/watch?vid=2"))); 522 EXPECT_TRUE(blacklist.IsURLBlocked(GURL("http://youtube.com/watch?foo=bar"))); 523 EXPECT_FALSE( 524 blacklist.IsURLBlocked(GURL("http://youtube.com/watch?vid=2&foo=bar"))); 525 EXPECT_FALSE( 526 blacklist.IsURLBlocked(GURL("http://youtube.com/watch?vid=2&foo=bar1"))); 527 EXPECT_FALSE( 528 blacklist.IsURLBlocked(GURL("http://youtube.com/watch?vid=234&foo=bar"))); 529 EXPECT_FALSE(blacklist.IsURLBlocked( 530 GURL("http://youtube.com/watch?vid=234&foo=bar23"))); 531 532 blocked.reset(new base::ListValue); 533 blocked->AppendString("youtube1.com/disallow?v=44678"); 534 blacklist.Block(blocked.get()); 535 EXPECT_FALSE(blacklist.IsURLBlocked(GURL("http://youtube1.com"))); 536 EXPECT_FALSE(blacklist.IsURLBlocked(GURL("http://youtube1.com?v=123"))); 537 // Path does not match 538 EXPECT_FALSE(blacklist.IsURLBlocked(GURL("http://youtube1.com?v=44678"))); 539 EXPECT_TRUE( 540 blacklist.IsURLBlocked(GURL("http://youtube1.com/disallow?v=44678"))); 541 EXPECT_FALSE( 542 blacklist.IsURLBlocked(GURL("http://youtube1.com/disallow?v=4467"))); 543 EXPECT_FALSE(blacklist.IsURLBlocked( 544 GURL("http://youtube1.com/disallow?v=4467&v=123"))); 545 EXPECT_TRUE(blacklist.IsURLBlocked( 546 GURL("http://youtube1.com/disallow?v=4467&v=123&v=44678"))); 547 548 blocked.reset(new base::ListValue); 549 blocked->AppendString("youtube1.com/disallow?g=*"); 550 blacklist.Block(blocked.get()); 551 EXPECT_FALSE(blacklist.IsURLBlocked(GURL("http://youtube1.com"))); 552 EXPECT_FALSE(blacklist.IsURLBlocked(GURL("http://youtube1.com?ag=123"))); 553 EXPECT_TRUE( 554 blacklist.IsURLBlocked(GURL("http://youtube1.com/disallow?g=123"))); 555 EXPECT_TRUE( 556 blacklist.IsURLBlocked(GURL("http://youtube1.com/disallow?ag=13&g=123"))); 557 558 blocked.reset(new base::ListValue); 559 blocked->AppendString("youtube2.com/disallow?a*"); 560 blacklist.Block(blocked.get()); 561 EXPECT_FALSE(blacklist.IsURLBlocked(GURL("http://youtube2.com"))); 562 EXPECT_TRUE(blacklist.IsURLBlocked( 563 GURL("http://youtube2.com/disallow?b=123&a21=467"))); 564 EXPECT_TRUE( 565 blacklist.IsURLBlocked(GURL("http://youtube2.com/disallow?abba=true"))); 566 EXPECT_FALSE( 567 blacklist.IsURLBlocked(GURL("http://youtube2.com/disallow?baba=true"))); 568 569 allowed.reset(new base::ListValue); 570 blocked.reset(new base::ListValue); 571 blocked->AppendString("youtube3.com"); 572 allowed->AppendString("youtube3.com/watch?fo*"); 573 blacklist.Block(blocked.get()); 574 blacklist.Allow(allowed.get()); 575 EXPECT_TRUE(blacklist.IsURLBlocked(GURL("http://youtube3.com"))); 576 EXPECT_TRUE( 577 blacklist.IsURLBlocked(GURL("http://youtube3.com/watch?b=123&a21=467"))); 578 EXPECT_FALSE(blacklist.IsURLBlocked( 579 GURL("http://youtube3.com/watch?b=123&a21=467&foo1"))); 580 EXPECT_FALSE(blacklist.IsURLBlocked( 581 GURL("http://youtube3.com/watch?b=123&a21=467&foo=bar"))); 582 EXPECT_FALSE(blacklist.IsURLBlocked( 583 GURL("http://youtube3.com/watch?b=123&a21=467&fo=ba"))); 584 EXPECT_FALSE( 585 blacklist.IsURLBlocked(GURL("http://youtube3.com/watch?foriegn=true"))); 586 EXPECT_FALSE(blacklist.IsURLBlocked(GURL("http://youtube3.com/watch?fold"))); 587 588 allowed.reset(new base::ListValue); 589 blocked.reset(new base::ListValue); 590 blocked->AppendString("youtube4.com"); 591 allowed->AppendString("youtube4.com?*"); 592 blacklist.Block(blocked.get()); 593 blacklist.Allow(allowed.get()); 594 EXPECT_TRUE(blacklist.IsURLBlocked(GURL("http://youtube4.com"))); 595 EXPECT_FALSE(blacklist.IsURLBlocked(GURL("http://youtube4.com/?hello"))); 596 EXPECT_FALSE(blacklist.IsURLBlocked(GURL("http://youtube4.com/?foo"))); 597 598 allowed.reset(new base::ListValue); 599 blocked.reset(new base::ListValue); 600 blocked->AppendString("youtube5.com?foo=bar"); 601 allowed->AppendString("youtube5.com?foo1=bar1&foo2=bar2&"); 602 blacklist.Block(blocked.get()); 603 blacklist.Allow(allowed.get()); 604 EXPECT_FALSE(blacklist.IsURLBlocked(GURL("http://youtube5.com"))); 605 EXPECT_TRUE(blacklist.IsURLBlocked(GURL("http://youtube5.com/?foo=bar&a=b"))); 606 // More specific filter is given precedence. 607 EXPECT_FALSE(blacklist.IsURLBlocked( 608 GURL("http://youtube5.com/?a=b&foo=bar&foo1=bar1&foo2=bar2"))); 609 } 610 611 TEST_F(URLBlacklistManagerTest, BlockAllWithExceptions) { 612 URLBlacklist blacklist(GetSegmentURLCallback()); 613 614 scoped_ptr<base::ListValue> blocked(new base::ListValue); 615 scoped_ptr<base::ListValue> allowed(new base::ListValue); 616 blocked->Append(new base::StringValue("*")); 617 allowed->Append(new base::StringValue(".www.google.com")); 618 allowed->Append(new base::StringValue("plus.google.com")); 619 allowed->Append(new base::StringValue("https://mail.google.com")); 620 allowed->Append(new base::StringValue("https://very.safe/path")); 621 blacklist.Block(blocked.get()); 622 blacklist.Allow(allowed.get()); 623 EXPECT_TRUE(blacklist.IsURLBlocked(GURL("http://random.com"))); 624 EXPECT_TRUE(blacklist.IsURLBlocked(GURL("http://google.com"))); 625 EXPECT_TRUE(blacklist.IsURLBlocked(GURL("http://s.www.google.com"))); 626 EXPECT_FALSE(blacklist.IsURLBlocked(GURL("http://www.google.com"))); 627 EXPECT_FALSE(blacklist.IsURLBlocked(GURL("http://plus.google.com"))); 628 EXPECT_FALSE(blacklist.IsURLBlocked(GURL("http://s.plus.google.com"))); 629 EXPECT_TRUE(blacklist.IsURLBlocked(GURL("http://mail.google.com"))); 630 EXPECT_FALSE(blacklist.IsURLBlocked(GURL("https://mail.google.com"))); 631 EXPECT_FALSE(blacklist.IsURLBlocked(GURL("https://s.mail.google.com"))); 632 EXPECT_TRUE(blacklist.IsURLBlocked(GURL("https://very.safe/"))); 633 EXPECT_TRUE(blacklist.IsURLBlocked(GURL("http://very.safe/path"))); 634 EXPECT_FALSE(blacklist.IsURLBlocked(GURL("https://very.safe/path"))); 635 } 636 637 TEST_F(URLBlacklistManagerTest, DontBlockResources) { 638 scoped_ptr<URLBlacklist> blacklist(new URLBlacklist(GetSegmentURLCallback())); 639 scoped_ptr<base::ListValue> blocked(new base::ListValue); 640 blocked->Append(new base::StringValue("google.com")); 641 blacklist->Block(blocked.get()); 642 blacklist_manager_->SetBlacklist(blacklist.Pass()); 643 EXPECT_TRUE(blacklist_manager_->IsURLBlocked(GURL("http://google.com"))); 644 645 net::TestURLRequestContext context; 646 net::URLRequest request( 647 GURL("http://google.com"), net::DEFAULT_PRIORITY, NULL, &context); 648 649 int reason = net::ERR_UNEXPECTED; 650 // Background requests aren't filtered. 651 EXPECT_FALSE(blacklist_manager_->IsRequestBlocked(request, &reason)); 652 653 // Main frames are filtered. 654 request.SetLoadFlags(net::LOAD_MAIN_FRAME); 655 EXPECT_TRUE(blacklist_manager_->IsRequestBlocked(request, &reason)); 656 EXPECT_EQ(net::ERR_BLOCKED_BY_ADMINISTRATOR, reason); 657 658 // On most platforms, sync gets a free pass due to signin flows. 659 bool block_signin_urls = false; 660 #if defined(OS_CHROMEOS) 661 // There are no sync specific signin flows on Chrome OS, so no special 662 // treatment. 663 block_signin_urls = true; 664 #endif 665 666 GURL sync_url(GaiaUrls::GetInstance()->service_login_url().Resolve( 667 "?service=chromiumsync")); 668 net::URLRequest sync_request(sync_url, net::DEFAULT_PRIORITY, NULL, &context); 669 sync_request.SetLoadFlags(net::LOAD_MAIN_FRAME); 670 EXPECT_EQ(block_signin_urls, 671 blacklist_manager_->IsRequestBlocked(sync_request, &reason)); 672 } 673 674 } // namespace policy 675