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 <map> 6 #include <queue> 7 #include <string> 8 9 #include "base/bind.h" 10 #include "base/callback.h" 11 #include "base/logging.h" 12 #include "base/memory/scoped_ptr.h" 13 #include "base/message_loop/message_loop.h" 14 #include "base/time/time.h" 15 #include "chrome/browser/safe_browsing/client_side_detection_service.h" 16 #include "chrome/common/safe_browsing/client_model.pb.h" 17 #include "chrome/common/safe_browsing/csd.pb.h" 18 #include "content/public/test/test_browser_thread.h" 19 #include "crypto/sha2.h" 20 #include "net/url_request/test_url_fetcher_factory.h" 21 #include "net/url_request/url_request_status.h" 22 #include "testing/gmock/include/gmock/gmock.h" 23 #include "testing/gtest/include/gtest/gtest.h" 24 #include "url/gurl.h" 25 26 using ::testing::_; 27 using ::testing::Invoke; 28 using ::testing::Mock; 29 using ::testing::StrictMock; 30 using content::BrowserThread; 31 32 namespace safe_browsing { 33 namespace { 34 class MockClientSideDetectionService : public ClientSideDetectionService { 35 public: 36 MockClientSideDetectionService() : ClientSideDetectionService(NULL) {} 37 virtual ~MockClientSideDetectionService() {} 38 39 MOCK_METHOD1(EndFetchModel, void(ClientModelStatus)); 40 MOCK_METHOD1(ScheduleFetchModel, void(int64)); 41 42 void Schedule(int64) { 43 // Ignore the delay when testing. 44 StartFetchModel(); 45 } 46 47 void Disable(int) { 48 // Ignore the status. 49 SetEnabledAndRefreshState(false); 50 } 51 52 private: 53 DISALLOW_COPY_AND_ASSIGN(MockClientSideDetectionService); 54 }; 55 56 ACTION(QuitCurrentMessageLoop) { 57 base::MessageLoop::current()->Quit(); 58 } 59 60 } // namespace 61 62 class ClientSideDetectionServiceTest : public testing::Test { 63 protected: 64 virtual void SetUp() { 65 file_thread_.reset(new content::TestBrowserThread(BrowserThread::FILE, 66 &msg_loop_)); 67 68 factory_.reset(new net::FakeURLFetcherFactory(NULL)); 69 70 browser_thread_.reset(new content::TestBrowserThread(BrowserThread::UI, 71 &msg_loop_)); 72 } 73 74 virtual void TearDown() { 75 msg_loop_.RunUntilIdle(); 76 csd_service_.reset(); 77 file_thread_.reset(); 78 browser_thread_.reset(); 79 } 80 81 bool SendClientReportPhishingRequest(const GURL& phishing_url, 82 float score) { 83 ClientPhishingRequest* request = new ClientPhishingRequest(); 84 request->set_url(phishing_url.spec()); 85 request->set_client_score(score); 86 request->set_is_phishing(true); // client thinks the URL is phishing. 87 csd_service_->SendClientReportPhishingRequest( 88 request, 89 base::Bind(&ClientSideDetectionServiceTest::SendRequestDone, 90 base::Unretained(this))); 91 phishing_url_ = phishing_url; 92 msg_loop_.Run(); // Waits until callback is called. 93 return is_phishing_; 94 } 95 96 bool SendClientReportMalwareRequest(const GURL& url) { 97 scoped_ptr<ClientMalwareRequest> request(new ClientMalwareRequest()); 98 request->set_url(url.spec()); 99 csd_service_->SendClientReportMalwareRequest( 100 request.release(), 101 base::Bind(&ClientSideDetectionServiceTest::SendMalwareRequestDone, 102 base::Unretained(this))); 103 phishing_url_ = url; 104 msg_loop_.Run(); // Waits until callback is called. 105 return is_malware_; 106 } 107 108 void SetModelFetchResponse(std::string response_data, bool success) { 109 factory_->SetFakeResponse(ClientSideDetectionService::kClientModelUrl, 110 response_data, success); 111 } 112 113 void SetClientReportPhishingResponse(std::string response_data, 114 bool success) { 115 factory_->SetFakeResponse( 116 ClientSideDetectionService::GetClientReportUrl( 117 ClientSideDetectionService::kClientReportPhishingUrl), 118 response_data, success); 119 } 120 121 void SetClientReportMalwareResponse(std::string response_data, 122 bool success) { 123 factory_->SetFakeResponse( 124 ClientSideDetectionService::GetClientReportUrl( 125 ClientSideDetectionService::kClientReportMalwareUrl), 126 response_data, success); 127 } 128 129 int GetNumReports(std::queue<base::Time>* report_times) { 130 return csd_service_->GetNumReports(report_times); 131 } 132 133 std::queue<base::Time>& GetPhishingReportTimes() { 134 return csd_service_->phishing_report_times_; 135 } 136 137 std::queue<base::Time>& GetMalwareReportTimes() { 138 return csd_service_->malware_report_times_; 139 } 140 141 void SetCache(const GURL& gurl, bool is_phishing, base::Time time) { 142 csd_service_->cache_[gurl] = 143 make_linked_ptr(new ClientSideDetectionService::CacheState(is_phishing, 144 time)); 145 } 146 147 void TestCache() { 148 ClientSideDetectionService::PhishingCache& cache = csd_service_->cache_; 149 base::Time now = base::Time::Now(); 150 base::Time time = 151 now - base::TimeDelta::FromDays( 152 ClientSideDetectionService::kNegativeCacheIntervalDays) + 153 base::TimeDelta::FromMinutes(5); 154 cache[GURL("http://first.url.com/")] = 155 make_linked_ptr(new ClientSideDetectionService::CacheState(false, 156 time)); 157 158 time = 159 now - base::TimeDelta::FromDays( 160 ClientSideDetectionService::kNegativeCacheIntervalDays) - 161 base::TimeDelta::FromHours(1); 162 cache[GURL("http://second.url.com/")] = 163 make_linked_ptr(new ClientSideDetectionService::CacheState(false, 164 time)); 165 166 time = 167 now - base::TimeDelta::FromMinutes( 168 ClientSideDetectionService::kPositiveCacheIntervalMinutes) - 169 base::TimeDelta::FromMinutes(5); 170 cache[GURL("http://third.url.com/")] = 171 make_linked_ptr(new ClientSideDetectionService::CacheState(true, time)); 172 173 time = 174 now - base::TimeDelta::FromMinutes( 175 ClientSideDetectionService::kPositiveCacheIntervalMinutes) + 176 base::TimeDelta::FromMinutes(5); 177 cache[GURL("http://fourth.url.com/")] = 178 make_linked_ptr(new ClientSideDetectionService::CacheState(true, time)); 179 180 csd_service_->UpdateCache(); 181 182 // 3 elements should be in the cache, the first, third, and fourth. 183 EXPECT_EQ(3U, cache.size()); 184 EXPECT_TRUE(cache.find(GURL("http://first.url.com/")) != cache.end()); 185 EXPECT_TRUE(cache.find(GURL("http://third.url.com/")) != cache.end()); 186 EXPECT_TRUE(cache.find(GURL("http://fourth.url.com/")) != cache.end()); 187 188 // While 3 elements remain, only the first and the fourth are actually 189 // valid. 190 bool is_phishing; 191 EXPECT_TRUE(csd_service_->GetValidCachedResult( 192 GURL("http://first.url.com"), &is_phishing)); 193 EXPECT_FALSE(is_phishing); 194 EXPECT_FALSE(csd_service_->GetValidCachedResult( 195 GURL("http://third.url.com"), &is_phishing)); 196 EXPECT_TRUE(csd_service_->GetValidCachedResult( 197 GURL("http://fourth.url.com"), &is_phishing)); 198 EXPECT_TRUE(is_phishing); 199 } 200 201 void AddFeature(const std::string& name, double value, 202 ClientPhishingRequest* request) { 203 ClientPhishingRequest_Feature* feature = request->add_feature_map(); 204 feature->set_name(name); 205 feature->set_value(value); 206 } 207 208 void AddNonModelFeature(const std::string& name, double value, 209 ClientPhishingRequest* request) { 210 ClientPhishingRequest_Feature* feature = 211 request->add_non_model_feature_map(); 212 feature->set_name(name); 213 feature->set_value(value); 214 } 215 216 protected: 217 scoped_ptr<ClientSideDetectionService> csd_service_; 218 scoped_ptr<net::FakeURLFetcherFactory> factory_; 219 base::MessageLoop msg_loop_; 220 221 private: 222 void SendRequestDone(GURL phishing_url, bool is_phishing) { 223 ASSERT_EQ(phishing_url, phishing_url_); 224 is_phishing_ = is_phishing; 225 msg_loop_.Quit(); 226 } 227 228 void SendMalwareRequestDone(GURL url, bool is_malware) { 229 ASSERT_EQ(phishing_url_, url); 230 is_malware_ = is_malware; 231 msg_loop_.Quit(); 232 } 233 scoped_ptr<content::TestBrowserThread> browser_thread_; 234 scoped_ptr<content::TestBrowserThread> file_thread_; 235 236 GURL phishing_url_; 237 bool is_phishing_; 238 bool is_malware_; 239 }; 240 241 TEST_F(ClientSideDetectionServiceTest, FetchModelTest) { 242 // We don't want to use a real service class here because we can't call 243 // the real EndFetchModel. It would reschedule a reload which might 244 // make the test flaky. 245 MockClientSideDetectionService service; 246 EXPECT_CALL(service, ScheduleFetchModel(_)).Times(1); 247 service.SetEnabledAndRefreshState(true); 248 249 // The model fetch failed. 250 SetModelFetchResponse("blamodel", false /* failure */); 251 EXPECT_CALL(service, EndFetchModel( 252 ClientSideDetectionService::MODEL_FETCH_FAILED)) 253 .WillOnce(QuitCurrentMessageLoop()); 254 service.StartFetchModel(); 255 msg_loop_.Run(); // EndFetchModel will quit the message loop. 256 Mock::VerifyAndClearExpectations(&service); 257 258 // Empty model file. 259 SetModelFetchResponse(std::string(), true /* success */); 260 EXPECT_CALL(service, EndFetchModel(ClientSideDetectionService::MODEL_EMPTY)) 261 .WillOnce(QuitCurrentMessageLoop()); 262 service.StartFetchModel(); 263 msg_loop_.Run(); // EndFetchModel will quit the message loop. 264 Mock::VerifyAndClearExpectations(&service); 265 266 // Model is too large. 267 SetModelFetchResponse( 268 std::string(ClientSideDetectionService::kMaxModelSizeBytes + 1, 'x'), 269 true /* success */); 270 EXPECT_CALL(service, EndFetchModel( 271 ClientSideDetectionService::MODEL_TOO_LARGE)) 272 .WillOnce(QuitCurrentMessageLoop()); 273 service.StartFetchModel(); 274 msg_loop_.Run(); // EndFetchModel will quit the message loop. 275 Mock::VerifyAndClearExpectations(&service); 276 277 // Unable to parse the model file. 278 SetModelFetchResponse("Invalid model file", true /* success */); 279 EXPECT_CALL(service, EndFetchModel( 280 ClientSideDetectionService::MODEL_PARSE_ERROR)) 281 .WillOnce(QuitCurrentMessageLoop()); 282 service.StartFetchModel(); 283 msg_loop_.Run(); // EndFetchModel will quit the message loop. 284 Mock::VerifyAndClearExpectations(&service); 285 286 // Model that is missing some required fields (missing the version field). 287 ClientSideModel model; 288 model.set_max_words_per_term(4); 289 SetModelFetchResponse(model.SerializePartialAsString(), true /* success */); 290 EXPECT_CALL(service, EndFetchModel( 291 ClientSideDetectionService::MODEL_MISSING_FIELDS)) 292 .WillOnce(QuitCurrentMessageLoop()); 293 service.StartFetchModel(); 294 msg_loop_.Run(); // EndFetchModel will quit the message loop. 295 Mock::VerifyAndClearExpectations(&service); 296 297 // Model that points to hashes that don't exist. 298 model.set_version(10); 299 model.add_hashes("bla"); 300 model.add_page_term(1); // Should be 0 instead of 1. 301 SetModelFetchResponse(model.SerializePartialAsString(), true /* success */); 302 EXPECT_CALL(service, EndFetchModel( 303 ClientSideDetectionService::MODEL_BAD_HASH_IDS)) 304 .WillOnce(QuitCurrentMessageLoop()); 305 service.StartFetchModel(); 306 msg_loop_.Run(); // EndFetchModel will quit the message loop. 307 Mock::VerifyAndClearExpectations(&service); 308 model.set_page_term(0, 0); 309 310 // Model version number is wrong. 311 model.set_version(-1); 312 SetModelFetchResponse(model.SerializeAsString(), true /* success */); 313 EXPECT_CALL(service, EndFetchModel( 314 ClientSideDetectionService::MODEL_INVALID_VERSION_NUMBER)) 315 .WillOnce(QuitCurrentMessageLoop()); 316 service.StartFetchModel(); 317 msg_loop_.Run(); // EndFetchModel will quit the message loop. 318 Mock::VerifyAndClearExpectations(&service); 319 320 // Normal model. 321 model.set_version(10); 322 SetModelFetchResponse(model.SerializeAsString(), true /* success */); 323 EXPECT_CALL(service, EndFetchModel( 324 ClientSideDetectionService::MODEL_SUCCESS)) 325 .WillOnce(QuitCurrentMessageLoop()); 326 service.StartFetchModel(); 327 msg_loop_.Run(); // EndFetchModel will quit the message loop. 328 Mock::VerifyAndClearExpectations(&service); 329 330 // Model version number is decreasing. Set the model version number of the 331 // model that is currently loaded in the service object to 11. 332 service.model_.reset(new ClientSideModel(model)); 333 service.model_->set_version(11); 334 SetModelFetchResponse(model.SerializeAsString(), true /* success */); 335 EXPECT_CALL(service, EndFetchModel( 336 ClientSideDetectionService::MODEL_INVALID_VERSION_NUMBER)) 337 .WillOnce(QuitCurrentMessageLoop()); 338 service.StartFetchModel(); 339 msg_loop_.Run(); // EndFetchModel will quit the message loop. 340 Mock::VerifyAndClearExpectations(&service); 341 342 // Model version hasn't changed since the last reload. 343 service.model_->set_version(10); 344 SetModelFetchResponse(model.SerializeAsString(), true /* success */); 345 EXPECT_CALL(service, EndFetchModel( 346 ClientSideDetectionService::MODEL_NOT_CHANGED)) 347 .WillOnce(QuitCurrentMessageLoop()); 348 service.StartFetchModel(); 349 msg_loop_.Run(); // EndFetchModel will quit the message loop. 350 Mock::VerifyAndClearExpectations(&service); 351 } 352 353 TEST_F(ClientSideDetectionServiceTest, ServiceObjectDeletedBeforeCallbackDone) { 354 SetModelFetchResponse("bogus model", true /* success */); 355 csd_service_.reset(ClientSideDetectionService::Create(NULL)); 356 csd_service_->SetEnabledAndRefreshState(true); 357 EXPECT_TRUE(csd_service_.get() != NULL); 358 // We delete the client-side detection service class even though the callbacks 359 // haven't run yet. 360 csd_service_.reset(); 361 // Waiting for the callbacks to run should not crash even if the service 362 // object is gone. 363 msg_loop_.RunUntilIdle(); 364 } 365 366 TEST_F(ClientSideDetectionServiceTest, SendClientReportPhishingRequest) { 367 SetModelFetchResponse("bogus model", true /* success */); 368 csd_service_.reset(ClientSideDetectionService::Create(NULL)); 369 csd_service_->SetEnabledAndRefreshState(true); 370 371 GURL url("http://a.com/"); 372 float score = 0.4f; // Some random client score. 373 374 base::Time before = base::Time::Now(); 375 376 // Invalid response body from the server. 377 SetClientReportPhishingResponse("invalid proto response", true /* success */); 378 EXPECT_FALSE(SendClientReportPhishingRequest(url, score)); 379 380 // Normal behavior. 381 ClientPhishingResponse response; 382 response.set_phishy(true); 383 SetClientReportPhishingResponse(response.SerializeAsString(), 384 true /* success */); 385 EXPECT_TRUE(SendClientReportPhishingRequest(url, score)); 386 387 // This request will fail 388 GURL second_url("http://b.com/"); 389 response.set_phishy(false); 390 SetClientReportPhishingResponse(response.SerializeAsString(), 391 false /* success */); 392 EXPECT_FALSE(SendClientReportPhishingRequest(second_url, score)); 393 394 base::Time after = base::Time::Now(); 395 396 // Check that we have recorded all 3 requests within the correct time range. 397 std::queue<base::Time>& report_times = GetPhishingReportTimes(); 398 EXPECT_EQ(3U, report_times.size()); 399 while (!report_times.empty()) { 400 base::Time time = report_times.back(); 401 report_times.pop(); 402 EXPECT_LE(before, time); 403 EXPECT_GE(after, time); 404 } 405 406 // Only the first url should be in the cache. 407 bool is_phishing; 408 EXPECT_TRUE(csd_service_->IsInCache(url)); 409 EXPECT_TRUE(csd_service_->GetValidCachedResult(url, &is_phishing)); 410 EXPECT_TRUE(is_phishing); 411 EXPECT_FALSE(csd_service_->IsInCache(second_url)); 412 } 413 414 TEST_F(ClientSideDetectionServiceTest, SendClientReportMalwareRequest) { 415 SetModelFetchResponse("bogus model", true /* success */); 416 csd_service_.reset(ClientSideDetectionService::Create(NULL)); 417 csd_service_->SetEnabledAndRefreshState(true); 418 GURL url("http://a.com/"); 419 420 base::Time before = base::Time::Now(); 421 422 // Invalid response body from the server. 423 SetClientReportMalwareResponse("invalid proto response", true /* success */); 424 EXPECT_FALSE(SendClientReportMalwareRequest(url)); 425 426 // Normal behavior. 427 ClientMalwareResponse response; 428 response.set_blacklist(true); 429 SetClientReportMalwareResponse(response.SerializeAsString(), true); 430 EXPECT_TRUE(SendClientReportMalwareRequest(url)); 431 432 // This request will fail 433 response.set_blacklist(false); 434 SetClientReportMalwareResponse(response.SerializeAsString(), 435 false /* success */); 436 EXPECT_FALSE(SendClientReportMalwareRequest(url)); 437 438 // server blacklist decision is false, and response is succesful 439 response.set_blacklist(false); 440 SetClientReportMalwareResponse(response.SerializeAsString(), true); 441 EXPECT_FALSE(SendClientReportMalwareRequest(url)); 442 443 // Check that we have recorded all 4 requests within the correct time range. 444 base::Time after = base::Time::Now(); 445 std::queue<base::Time>& report_times = GetMalwareReportTimes(); 446 EXPECT_EQ(4U, report_times.size()); 447 448 // Another normal behavior will fail because of the limit is hit 449 response.set_blacklist(true); 450 SetClientReportMalwareResponse(response.SerializeAsString(), true); 451 EXPECT_FALSE(SendClientReportMalwareRequest(url)); 452 453 report_times = GetMalwareReportTimes(); 454 EXPECT_EQ(4U, report_times.size()); 455 while (!report_times.empty()) { 456 base::Time time = report_times.back(); 457 report_times.pop(); 458 EXPECT_LE(before, time); 459 EXPECT_GE(after, time); 460 } 461 } 462 463 TEST_F(ClientSideDetectionServiceTest, GetNumReportTest) { 464 SetModelFetchResponse("bogus model", true /* success */); 465 csd_service_.reset(ClientSideDetectionService::Create(NULL)); 466 467 std::queue<base::Time>& report_times = GetPhishingReportTimes(); 468 base::Time now = base::Time::Now(); 469 base::TimeDelta twenty_five_hours = base::TimeDelta::FromHours(25); 470 report_times.push(now - twenty_five_hours); 471 report_times.push(now - twenty_five_hours); 472 report_times.push(now); 473 report_times.push(now); 474 475 EXPECT_EQ(2, GetNumReports(&report_times)); 476 } 477 478 TEST_F(ClientSideDetectionServiceTest, CacheTest) { 479 SetModelFetchResponse("bogus model", true /* success */); 480 csd_service_.reset(ClientSideDetectionService::Create(NULL)); 481 482 TestCache(); 483 } 484 485 TEST_F(ClientSideDetectionServiceTest, IsPrivateIPAddress) { 486 SetModelFetchResponse("bogus model", true /* success */); 487 csd_service_.reset(ClientSideDetectionService::Create(NULL)); 488 489 EXPECT_TRUE(csd_service_->IsPrivateIPAddress("10.1.2.3")); 490 EXPECT_TRUE(csd_service_->IsPrivateIPAddress("127.0.0.1")); 491 EXPECT_TRUE(csd_service_->IsPrivateIPAddress("172.24.3.4")); 492 EXPECT_TRUE(csd_service_->IsPrivateIPAddress("192.168.1.1")); 493 EXPECT_TRUE(csd_service_->IsPrivateIPAddress("fc00::")); 494 EXPECT_TRUE(csd_service_->IsPrivateIPAddress("fec0::")); 495 EXPECT_TRUE(csd_service_->IsPrivateIPAddress("fec0:1:2::3")); 496 EXPECT_TRUE(csd_service_->IsPrivateIPAddress("::1")); 497 498 EXPECT_FALSE(csd_service_->IsPrivateIPAddress("1.2.3.4")); 499 EXPECT_FALSE(csd_service_->IsPrivateIPAddress("200.1.1.1")); 500 EXPECT_FALSE(csd_service_->IsPrivateIPAddress("2001:0db8:ac10:fe01::")); 501 502 // If the address can't be parsed, the default is true. 503 EXPECT_TRUE(csd_service_->IsPrivateIPAddress("blah")); 504 } 505 506 TEST_F(ClientSideDetectionServiceTest, SetBadSubnets) { 507 ClientSideModel model; 508 ClientSideDetectionService::BadSubnetMap bad_subnets; 509 ClientSideDetectionService::SetBadSubnets(model, &bad_subnets); 510 EXPECT_EQ(0U, bad_subnets.size()); 511 512 // Bad subnets are skipped. 513 ClientSideModel::IPSubnet* subnet = model.add_bad_subnet(); 514 subnet->set_prefix(std::string(crypto::kSHA256Length, '.')); 515 subnet->set_size(130); // Invalid size. 516 517 subnet = model.add_bad_subnet(); 518 subnet->set_prefix(std::string(crypto::kSHA256Length, '.')); 519 subnet->set_size(-1); // Invalid size. 520 521 subnet = model.add_bad_subnet(); 522 subnet->set_prefix(std::string(16, '.')); // Invalid len. 523 subnet->set_size(64); 524 525 ClientSideDetectionService::SetBadSubnets(model, &bad_subnets); 526 EXPECT_EQ(0U, bad_subnets.size()); 527 528 subnet = model.add_bad_subnet(); 529 subnet->set_prefix(std::string(crypto::kSHA256Length, '.')); 530 subnet->set_size(64); 531 532 subnet = model.add_bad_subnet(); 533 subnet->set_prefix(std::string(crypto::kSHA256Length, ',')); 534 subnet->set_size(64); 535 536 subnet = model.add_bad_subnet(); 537 subnet->set_prefix(std::string(crypto::kSHA256Length, '.')); 538 subnet->set_size(128); 539 540 subnet = model.add_bad_subnet(); 541 subnet->set_prefix(std::string(crypto::kSHA256Length, '.')); 542 subnet->set_size(100); 543 544 ClientSideDetectionService::SetBadSubnets(model, &bad_subnets); 545 EXPECT_EQ(3U, bad_subnets.size()); 546 ClientSideDetectionService::BadSubnetMap::const_iterator it; 547 std::string mask = std::string(8, '\xFF') + std::string(8, '\x00'); 548 EXPECT_TRUE(bad_subnets.count(mask)); 549 EXPECT_TRUE(bad_subnets[mask].count(std::string(crypto::kSHA256Length, '.'))); 550 EXPECT_TRUE(bad_subnets[mask].count(std::string(crypto::kSHA256Length, ','))); 551 552 mask = std::string(16, '\xFF'); 553 EXPECT_TRUE(bad_subnets.count(mask)); 554 EXPECT_TRUE(bad_subnets[mask].count(std::string(crypto::kSHA256Length, '.'))); 555 556 mask = std::string(12, '\xFF') + "\xF0" + std::string(3, '\x00'); 557 EXPECT_TRUE(bad_subnets.count(mask)); 558 EXPECT_TRUE(bad_subnets[mask].count(std::string(crypto::kSHA256Length, '.'))); 559 } 560 561 TEST_F(ClientSideDetectionServiceTest, IsBadIpAddress) { 562 ClientSideModel model; 563 // IPv6 exact match for: 2620:0:1000:3103:21a:a0ff:fe10:786e. 564 ClientSideModel::IPSubnet* subnet = model.add_bad_subnet(); 565 subnet->set_prefix(crypto::SHA256HashString(std::string( 566 "\x26\x20\x00\x00\x10\x00\x31\x03\x02\x1a\xa0\xff\xfe\x10\x78\x6e", 16))); 567 subnet->set_size(128); 568 569 // IPv6 prefix match for: fe80::21a:a0ff:fe10:786e/64. 570 subnet = model.add_bad_subnet(); 571 subnet->set_prefix(crypto::SHA256HashString(std::string( 572 "\xfe\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 16))); 573 subnet->set_size(64); 574 575 // IPv4 exact match for ::ffff:192.0.2.128. 576 subnet = model.add_bad_subnet(); 577 subnet->set_prefix(crypto::SHA256HashString(std::string( 578 "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xc0\x00\x02\x80", 16))); 579 subnet->set_size(128); 580 581 // IPv4 prefix match (/8) for ::ffff:192.1.1.0. 582 subnet = model.add_bad_subnet(); 583 subnet->set_prefix(crypto::SHA256HashString(std::string( 584 "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xc0\x01\x01\x00", 16))); 585 subnet->set_size(120); 586 587 // IPv4 prefix match (/9) for ::ffff:192.1.122.0. 588 subnet = model.add_bad_subnet(); 589 subnet->set_prefix(crypto::SHA256HashString(std::string( 590 "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xc0\x01\x7a\x00", 16))); 591 subnet->set_size(119); 592 593 // IPv4 prefix match (/15) for ::ffff:192.1.128.0. 594 subnet = model.add_bad_subnet(); 595 subnet->set_prefix(crypto::SHA256HashString(std::string( 596 "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xc0\x01\x80\x00", 16))); 597 subnet->set_size(113); 598 599 csd_service_.reset(ClientSideDetectionService::Create(NULL)); 600 ClientSideDetectionService::SetBadSubnets( 601 model, &(csd_service_->bad_subnets_)); 602 EXPECT_FALSE(csd_service_->IsBadIpAddress("blabla")); 603 EXPECT_FALSE(csd_service_->IsBadIpAddress(std::string())); 604 605 EXPECT_TRUE(csd_service_->IsBadIpAddress( 606 "2620:0:1000:3103:21a:a0ff:fe10:786e")); 607 EXPECT_FALSE(csd_service_->IsBadIpAddress( 608 "2620:0:1000:3103:21a:a0ff:fe10:786f")); 609 610 EXPECT_TRUE(csd_service_->IsBadIpAddress("fe80::21a:a0ff:fe10:786e")); 611 EXPECT_TRUE(csd_service_->IsBadIpAddress("fe80::31a:a0ff:fe10:786e")); 612 EXPECT_TRUE(csd_service_->IsBadIpAddress("fe80::21a:a0ff:fe10:786f")); 613 EXPECT_FALSE(csd_service_->IsBadIpAddress("fe81::21a:a0ff:fe10:786e")); 614 615 EXPECT_TRUE(csd_service_->IsBadIpAddress("192.0.2.128")); 616 EXPECT_TRUE(csd_service_->IsBadIpAddress("::ffff:192.0.2.128")); 617 EXPECT_FALSE(csd_service_->IsBadIpAddress("192.0.2.129")); 618 619 EXPECT_TRUE(csd_service_->IsBadIpAddress("192.1.1.0")); 620 EXPECT_TRUE(csd_service_->IsBadIpAddress("192.1.1.255")); 621 EXPECT_TRUE(csd_service_->IsBadIpAddress("192.1.1.10")); 622 EXPECT_TRUE(csd_service_->IsBadIpAddress("::ffff:192.1.1.2")); 623 624 EXPECT_FALSE(csd_service_->IsBadIpAddress("192.1.121.255")); 625 EXPECT_TRUE(csd_service_->IsBadIpAddress("192.1.122.0")); 626 EXPECT_TRUE(csd_service_->IsBadIpAddress("::ffff:192.1.122.1")); 627 EXPECT_TRUE(csd_service_->IsBadIpAddress("192.1.122.255")); 628 EXPECT_TRUE(csd_service_->IsBadIpAddress("192.1.123.0")); 629 EXPECT_TRUE(csd_service_->IsBadIpAddress("192.1.123.255")); 630 EXPECT_FALSE(csd_service_->IsBadIpAddress("192.1.124.0")); 631 632 EXPECT_FALSE(csd_service_->IsBadIpAddress("192.1.127.255")); 633 EXPECT_TRUE(csd_service_->IsBadIpAddress("192.1.128.0")); 634 EXPECT_TRUE(csd_service_->IsBadIpAddress("::ffff:192.1.128.1")); 635 EXPECT_TRUE(csd_service_->IsBadIpAddress("192.1.128.255")); 636 EXPECT_TRUE(csd_service_->IsBadIpAddress("192.1.255.0")); 637 EXPECT_TRUE(csd_service_->IsBadIpAddress("192.1.255.255")); 638 EXPECT_FALSE(csd_service_->IsBadIpAddress("192.2.0.0")); 639 } 640 641 TEST_F(ClientSideDetectionServiceTest, ModelHasValidHashIds) { 642 ClientSideModel model; 643 EXPECT_TRUE(ClientSideDetectionService::ModelHasValidHashIds(model)); 644 model.add_hashes("bla"); 645 EXPECT_TRUE(ClientSideDetectionService::ModelHasValidHashIds(model)); 646 model.add_page_term(0); 647 EXPECT_TRUE(ClientSideDetectionService::ModelHasValidHashIds(model)); 648 649 model.add_page_term(-1); 650 EXPECT_FALSE(ClientSideDetectionService::ModelHasValidHashIds(model)); 651 model.set_page_term(1, 1); 652 EXPECT_FALSE(ClientSideDetectionService::ModelHasValidHashIds(model)); 653 model.set_page_term(1, 0); 654 EXPECT_TRUE(ClientSideDetectionService::ModelHasValidHashIds(model)); 655 656 // Test bad rules. 657 model.add_hashes("blu"); 658 ClientSideModel::Rule* rule = model.add_rule(); 659 rule->add_feature(0); 660 rule->add_feature(1); 661 rule->set_weight(0.1f); 662 EXPECT_TRUE(ClientSideDetectionService::ModelHasValidHashIds(model)); 663 664 rule = model.add_rule(); 665 rule->add_feature(0); 666 rule->add_feature(1); 667 rule->add_feature(-1); 668 rule->set_weight(0.2f); 669 EXPECT_FALSE(ClientSideDetectionService::ModelHasValidHashIds(model)); 670 671 rule->set_feature(2, 2); 672 EXPECT_FALSE(ClientSideDetectionService::ModelHasValidHashIds(model)); 673 674 rule->set_feature(2, 1); 675 EXPECT_TRUE(ClientSideDetectionService::ModelHasValidHashIds(model)); 676 } 677 678 TEST_F(ClientSideDetectionServiceTest, SetEnabledAndRefreshState) { 679 // Check that the model isn't downloaded until the service is enabled. 680 csd_service_.reset(ClientSideDetectionService::Create(NULL)); 681 EXPECT_FALSE(csd_service_->enabled()); 682 EXPECT_TRUE(csd_service_->model_fetcher_.get() == NULL); 683 684 // Use a MockClientSideDetectionService for the rest of the test, to avoid 685 // the scheduling delay. 686 MockClientSideDetectionService* service = 687 new StrictMock<MockClientSideDetectionService>(); 688 csd_service_.reset(service); 689 EXPECT_FALSE(csd_service_->enabled()); 690 EXPECT_TRUE(csd_service_->model_fetcher_.get() == NULL); 691 // No calls expected yet. 692 Mock::VerifyAndClearExpectations(service); 693 694 ClientSideModel model; 695 model.set_version(10); 696 model.set_max_words_per_term(4); 697 SetModelFetchResponse(model.SerializeAsString(), true /* success */); 698 EXPECT_CALL(*service, ScheduleFetchModel(_)) 699 .WillOnce(Invoke(service, &MockClientSideDetectionService::Schedule)); 700 EXPECT_CALL(*service, EndFetchModel( 701 ClientSideDetectionService::MODEL_SUCCESS)) 702 .WillOnce(QuitCurrentMessageLoop()); 703 csd_service_->SetEnabledAndRefreshState(true); 704 EXPECT_TRUE(csd_service_->model_fetcher_.get() != NULL); 705 msg_loop_.Run(); // EndFetchModel will quit the message loop. 706 Mock::VerifyAndClearExpectations(service); 707 708 // Check that enabling again doesn't request the model. 709 csd_service_->SetEnabledAndRefreshState(true); 710 // No calls expected. 711 Mock::VerifyAndClearExpectations(service); 712 713 // Check that disabling the service cancels pending requests. 714 EXPECT_CALL(*service, ScheduleFetchModel(_)) 715 .WillOnce(Invoke(service, &MockClientSideDetectionService::Schedule)); 716 csd_service_->SetEnabledAndRefreshState(false); 717 csd_service_->SetEnabledAndRefreshState(true); 718 Mock::VerifyAndClearExpectations(service); 719 EXPECT_TRUE(csd_service_->model_fetcher_.get() != NULL); 720 csd_service_->SetEnabledAndRefreshState(false); 721 EXPECT_TRUE(csd_service_->model_fetcher_.get() == NULL); 722 msg_loop_.RunUntilIdle(); 723 // No calls expected. 724 Mock::VerifyAndClearExpectations(service); 725 726 // Requests always return false when the service is disabled. 727 ClientPhishingResponse response; 728 response.set_phishy(true); 729 SetClientReportPhishingResponse(response.SerializeAsString(), 730 true /* success */); 731 EXPECT_FALSE(SendClientReportPhishingRequest(GURL("http://a.com/"), 0.4f)); 732 733 // Pending requests also return false if the service is disabled before they 734 // report back. 735 EXPECT_CALL(*service, ScheduleFetchModel(_)) 736 .WillOnce(Invoke(service, &MockClientSideDetectionService::Schedule)); 737 EXPECT_CALL(*service, EndFetchModel( 738 ClientSideDetectionService::MODEL_NOT_CHANGED)) 739 .WillOnce(Invoke(service, &MockClientSideDetectionService::Disable)); 740 csd_service_->SetEnabledAndRefreshState(true); 741 EXPECT_FALSE(SendClientReportPhishingRequest(GURL("http://a.com/"), 0.4f)); 742 Mock::VerifyAndClearExpectations(service); 743 } 744 } // namespace safe_browsing 745