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 "chrome/browser/safe_browsing/download_protection_service.h" 6 7 #include <map> 8 #include <string> 9 10 #include "base/base_paths.h" 11 #include "base/bind.h" 12 #include "base/callback.h" 13 #include "base/command_line.h" 14 #include "base/file_util.h" 15 #include "base/files/file_path.h" 16 #include "base/files/scoped_temp_dir.h" 17 #include "base/memory/ref_counted.h" 18 #include "base/memory/scoped_ptr.h" 19 #include "base/message_loop/message_loop.h" 20 #include "base/path_service.h" 21 #include "base/run_loop.h" 22 #include "base/strings/string_number_conversions.h" 23 #include "base/threading/sequenced_worker_pool.h" 24 #include "chrome/browser/safe_browsing/database_manager.h" 25 #include "chrome/browser/safe_browsing/download_feedback_service.h" 26 #include "chrome/browser/safe_browsing/safe_browsing_service.h" 27 #include "chrome/browser/safe_browsing/signature_util.h" 28 #include "chrome/common/chrome_switches.h" 29 #include "chrome/common/safe_browsing/csd.pb.h" 30 #include "content/public/browser/render_process_host.h" 31 #include "content/public/test/mock_download_item.h" 32 #include "content/public/test/test_browser_thread_bundle.h" 33 #include "net/cert/x509_certificate.h" 34 #include "net/url_request/test_url_fetcher_factory.h" 35 #include "net/url_request/url_fetcher_delegate.h" 36 #include "testing/gmock/include/gmock/gmock.h" 37 #include "testing/gtest/include/gtest/gtest.h" 38 #include "third_party/zlib/google/zip.h" 39 #include "url/gurl.h" 40 41 using ::testing::Assign; 42 using ::testing::ContainerEq; 43 using ::testing::DoAll; 44 using ::testing::ElementsAre; 45 using ::testing::Mock; 46 using ::testing::NotNull; 47 using ::testing::Return; 48 using ::testing::ReturnRef; 49 using ::testing::SaveArg; 50 using ::testing::StrictMock; 51 using ::testing::_; 52 using base::MessageLoop; 53 using content::BrowserThread; 54 namespace safe_browsing { 55 namespace { 56 // A SafeBrowsingDatabaseManager implementation that returns a fixed result for 57 // a given URL. 58 class MockSafeBrowsingDatabaseManager : public SafeBrowsingDatabaseManager { 59 public: 60 explicit MockSafeBrowsingDatabaseManager(SafeBrowsingService* service) 61 : SafeBrowsingDatabaseManager(service) { } 62 63 MOCK_METHOD1(MatchDownloadWhitelistUrl, bool(const GURL&)); 64 MOCK_METHOD1(MatchDownloadWhitelistString, bool(const std::string&)); 65 MOCK_METHOD2(CheckDownloadUrl, bool( 66 const std::vector<GURL>& url_chain, 67 SafeBrowsingDatabaseManager::Client* client)); 68 69 private: 70 virtual ~MockSafeBrowsingDatabaseManager() {} 71 DISALLOW_COPY_AND_ASSIGN(MockSafeBrowsingDatabaseManager); 72 }; 73 74 class FakeSafeBrowsingService : public SafeBrowsingService { 75 public: 76 FakeSafeBrowsingService() { } 77 78 // Returned pointer has the same lifespan as the database_manager_ refcounted 79 // object. 80 MockSafeBrowsingDatabaseManager* mock_database_manager() { 81 return mock_database_manager_; 82 } 83 84 protected: 85 virtual ~FakeSafeBrowsingService() { } 86 87 virtual SafeBrowsingDatabaseManager* CreateDatabaseManager() OVERRIDE { 88 mock_database_manager_ = new MockSafeBrowsingDatabaseManager(this); 89 return mock_database_manager_; 90 } 91 92 private: 93 MockSafeBrowsingDatabaseManager* mock_database_manager_; 94 95 DISALLOW_COPY_AND_ASSIGN(FakeSafeBrowsingService); 96 }; 97 98 class MockSignatureUtil : public SignatureUtil { 99 public: 100 MockSignatureUtil() {} 101 MOCK_METHOD2(CheckSignature, void (const base::FilePath&, 102 ClientDownloadRequest_SignatureInfo*)); 103 104 protected: 105 virtual ~MockSignatureUtil() {} 106 107 private: 108 DISALLOW_COPY_AND_ASSIGN(MockSignatureUtil); 109 }; 110 } // namespace 111 112 ACTION_P(SetCertificateContents, contents) { 113 arg1->add_certificate_chain()->add_element()->set_certificate(contents); 114 } 115 116 ACTION_P(TrustSignature, certificate_file) { 117 arg1->set_trusted(true); 118 // Add a certificate chain. Note that we add the certificate twice so that 119 // it appears as its own issuer. 120 std::string cert_data; 121 ASSERT_TRUE(file_util::ReadFileToString(certificate_file, &cert_data)); 122 ClientDownloadRequest_CertificateChain* chain = 123 arg1->add_certificate_chain(); 124 chain->add_element()->set_certificate(cert_data); 125 chain->add_element()->set_certificate(cert_data); 126 } 127 128 // We can't call OnSafeBrowsingResult directly because SafeBrowsingCheck does 129 // not have any copy constructor which means it can't be stored in a callback 130 // easily. Note: check will be deleted automatically when the callback is 131 // deleted. 132 void OnSafeBrowsingResult( 133 SafeBrowsingDatabaseManager::SafeBrowsingCheck* check) { 134 check->client->OnSafeBrowsingResult(*check); 135 } 136 137 ACTION_P(CheckDownloadUrlDone, threat_type) { 138 SafeBrowsingDatabaseManager::SafeBrowsingCheck* check = 139 new SafeBrowsingDatabaseManager::SafeBrowsingCheck( 140 arg0, 141 std::vector<SBFullHash>(), 142 arg1, 143 safe_browsing_util::BINURL); 144 for (size_t i = 0; i < check->url_results.size(); ++i) 145 check->url_results[i] = threat_type; 146 BrowserThread::PostTask(BrowserThread::IO, 147 FROM_HERE, 148 base::Bind(&OnSafeBrowsingResult, 149 base::Owned(check))); 150 } 151 152 class DownloadProtectionServiceTest : public testing::Test { 153 protected: 154 DownloadProtectionServiceTest() 155 : test_browser_thread_bundle_( 156 content::TestBrowserThreadBundle::IO_MAINLOOP) { 157 } 158 virtual void SetUp() { 159 content::RenderProcessHost::SetRunRendererInProcess(true); 160 CommandLine::ForCurrentProcess()->AppendSwitch( 161 switches::kSbEnableDownloadFeedback); 162 // Start real threads for the IO and File threads so that the DCHECKs 163 // to test that we're on the correct thread work. 164 sb_service_ = new StrictMock<FakeSafeBrowsingService>(); 165 sb_service_->Initialize(); 166 signature_util_ = new StrictMock<MockSignatureUtil>(); 167 download_service_ = sb_service_->download_protection_service(); 168 download_service_->signature_util_ = signature_util_; 169 download_service_->SetEnabled(true); 170 base::RunLoop().RunUntilIdle(); 171 has_result_ = false; 172 173 base::FilePath source_path; 174 ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &source_path)); 175 testdata_path_ = source_path 176 .AppendASCII("chrome") 177 .AppendASCII("test") 178 .AppendASCII("data") 179 .AppendASCII("safe_browsing") 180 .AppendASCII("download_protection"); 181 } 182 183 virtual void TearDown() { 184 sb_service_->ShutDown(); 185 // Flush all of the thread message loops to ensure that there are no 186 // tasks currently running. 187 FlushThreadMessageLoops(); 188 sb_service_ = NULL; 189 content::RenderProcessHost::SetRunRendererInProcess(false); 190 } 191 192 bool RequestContainsResource(const ClientDownloadRequest& request, 193 ClientDownloadRequest::ResourceType type, 194 const std::string& url, 195 const std::string& referrer) { 196 for (int i = 0; i < request.resources_size(); ++i) { 197 if (request.resources(i).url() == url && 198 request.resources(i).type() == type && 199 (referrer.empty() || request.resources(i).referrer() == referrer)) { 200 return true; 201 } 202 } 203 return false; 204 } 205 206 // At this point we only set the server IP for the download itself. 207 bool RequestContainsServerIp(const ClientDownloadRequest& request, 208 const std::string& remote_address) { 209 for (int i = 0; i < request.resources_size(); ++i) { 210 // We want the last DOWNLOAD_URL in the chain. 211 if (request.resources(i).type() == ClientDownloadRequest::DOWNLOAD_URL && 212 (i + 1 == request.resources_size() || 213 request.resources(i + 1).type() != 214 ClientDownloadRequest::DOWNLOAD_URL)) { 215 return remote_address == request.resources(i).remote_ip(); 216 } 217 } 218 return false; 219 } 220 221 // Flushes any pending tasks in the message loops of all threads. 222 void FlushThreadMessageLoops() { 223 BrowserThread::GetBlockingPool()->FlushForTesting(); 224 FlushMessageLoop(BrowserThread::IO); 225 base::RunLoop().RunUntilIdle(); 226 } 227 228 // Proxy for private method. 229 static void GetCertificateWhitelistStrings( 230 const net::X509Certificate& certificate, 231 const net::X509Certificate& issuer, 232 std::vector<std::string>* whitelist_strings) { 233 DownloadProtectionService::GetCertificateWhitelistStrings( 234 certificate, issuer, whitelist_strings); 235 } 236 237 // Reads a single PEM-encoded certificate from the testdata directory. 238 // Returns NULL on failure. 239 scoped_refptr<net::X509Certificate> ReadTestCertificate( 240 const std::string& filename) { 241 std::string cert_data; 242 if (!file_util::ReadFileToString(testdata_path_.AppendASCII(filename), 243 &cert_data)) { 244 return NULL; 245 } 246 net::CertificateList certs = 247 net::X509Certificate::CreateCertificateListFromBytes( 248 cert_data.data(), 249 cert_data.size(), 250 net::X509Certificate::FORMAT_PEM_CERT_SEQUENCE); 251 return certs.empty() ? NULL : certs[0]; 252 } 253 254 private: 255 // Helper functions for FlushThreadMessageLoops. 256 void RunAllPendingAndQuitUI() { 257 base::MessageLoop::current()->RunUntilIdle(); 258 BrowserThread::PostTask( 259 BrowserThread::UI, 260 FROM_HERE, 261 base::Bind(&DownloadProtectionServiceTest::QuitMessageLoop, 262 base::Unretained(this))); 263 } 264 265 void QuitMessageLoop() { 266 base::MessageLoop::current()->Quit(); 267 } 268 269 void PostRunMessageLoopTask(BrowserThread::ID thread) { 270 BrowserThread::PostTask( 271 thread, 272 FROM_HERE, 273 base::Bind(&DownloadProtectionServiceTest::RunAllPendingAndQuitUI, 274 base::Unretained(this))); 275 } 276 277 void FlushMessageLoop(BrowserThread::ID thread) { 278 BrowserThread::PostTask( 279 BrowserThread::UI, 280 FROM_HERE, 281 base::Bind(&DownloadProtectionServiceTest::PostRunMessageLoopTask, 282 base::Unretained(this), thread)); 283 MessageLoop::current()->Run(); 284 } 285 286 public: 287 void CheckDoneCallback( 288 DownloadProtectionService::DownloadCheckResult result) { 289 result_ = result; 290 has_result_ = true; 291 MessageLoop::current()->Quit(); 292 } 293 294 void SyncCheckDoneCallback( 295 DownloadProtectionService::DownloadCheckResult result) { 296 result_ = result; 297 has_result_ = true; 298 } 299 300 void SendURLFetchComplete(net::TestURLFetcher* fetcher) { 301 fetcher->delegate()->OnURLFetchComplete(fetcher); 302 } 303 304 testing::AssertionResult IsResult( 305 DownloadProtectionService::DownloadCheckResult expected) { 306 if (!has_result_) 307 return testing::AssertionFailure() << "No result"; 308 has_result_ = false; 309 return result_ == expected ? 310 testing::AssertionSuccess() : 311 testing::AssertionFailure() << "Expected " << expected << 312 ", got " << result_; 313 } 314 315 protected: 316 scoped_refptr<FakeSafeBrowsingService> sb_service_; 317 scoped_refptr<MockSignatureUtil> signature_util_; 318 DownloadProtectionService* download_service_; 319 DownloadProtectionService::DownloadCheckResult result_; 320 bool has_result_; 321 content::TestBrowserThreadBundle test_browser_thread_bundle_; 322 base::FilePath testdata_path_; 323 }; 324 325 TEST_F(DownloadProtectionServiceTest, CheckClientDownloadInvalidUrl) { 326 base::FilePath a_tmp(FILE_PATH_LITERAL("a.tmp")); 327 base::FilePath a_exe(FILE_PATH_LITERAL("a.exe")); 328 std::vector<GURL> url_chain; 329 GURL referrer("http://www.google.com/"); 330 331 content::MockDownloadItem item; 332 EXPECT_CALL(item, AddObserver(_)); 333 EXPECT_CALL(item, RemoveObserver(_)); 334 EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp)); 335 EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_exe)); 336 EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain)); 337 EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer)); 338 download_service_->CheckClientDownload( 339 &item, 340 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback, 341 base::Unretained(this))); 342 MessageLoop::current()->Run(); 343 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE)); 344 Mock::VerifyAndClearExpectations(&item); 345 346 url_chain.push_back(GURL("file://www.google.com/")); 347 EXPECT_CALL(item, AddObserver(_)); 348 EXPECT_CALL(item, RemoveObserver(_)); 349 EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp)); 350 EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_exe)); 351 EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain)); 352 EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer)); 353 download_service_->CheckClientDownload( 354 &item, 355 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback, 356 base::Unretained(this))); 357 MessageLoop::current()->Run(); 358 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE)); 359 } 360 361 TEST_F(DownloadProtectionServiceTest, CheckClientDownloadWhitelistedUrl) { 362 base::FilePath a_tmp(FILE_PATH_LITERAL("a.tmp")); 363 base::FilePath a_exe(FILE_PATH_LITERAL("a.exe")); 364 std::vector<GURL> url_chain; 365 url_chain.push_back(GURL("http://www.evil.com/bla.exe")); 366 url_chain.push_back(GURL("http://www.google.com/a.exe")); 367 GURL referrer("http://www.google.com/"); 368 369 content::MockDownloadItem item; 370 EXPECT_CALL(item, AddObserver(_)).Times(2); 371 EXPECT_CALL(item, RemoveObserver(_)).Times(2); 372 EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp)); 373 EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_exe)); 374 EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain)); 375 EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer)); 376 EXPECT_CALL(*sb_service_->mock_database_manager(), 377 MatchDownloadWhitelistUrl(_)) 378 .WillRepeatedly(Return(false)); 379 EXPECT_CALL(*sb_service_->mock_database_manager(), 380 MatchDownloadWhitelistUrl(GURL("http://www.google.com/a.exe"))) 381 .WillRepeatedly(Return(true)); 382 EXPECT_CALL(*signature_util_.get(), CheckSignature(a_tmp, _)).Times(2); 383 384 download_service_->CheckClientDownload( 385 &item, 386 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback, 387 base::Unretained(this))); 388 MessageLoop::current()->Run(); 389 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE)); 390 391 // Check that the referrer is matched against the whitelist. 392 url_chain.pop_back(); 393 referrer = GURL("http://www.google.com/a.exe"); 394 download_service_->CheckClientDownload( 395 &item, 396 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback, 397 base::Unretained(this))); 398 MessageLoop::current()->Run(); 399 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE)); 400 } 401 402 TEST_F(DownloadProtectionServiceTest, CheckClientDownloadFetchFailed) { 403 net::FakeURLFetcherFactory factory(NULL); 404 // HTTP request will fail. 405 factory.SetFakeResponse( 406 DownloadProtectionService::GetDownloadRequestUrl(), std::string(), false); 407 408 base::FilePath a_tmp(FILE_PATH_LITERAL("a.tmp")); 409 base::FilePath a_exe(FILE_PATH_LITERAL("a.exe")); 410 std::vector<GURL> url_chain; 411 url_chain.push_back(GURL("http://www.evil.com/a.exe")); 412 GURL referrer("http://www.google.com/"); 413 std::string hash = "hash"; 414 415 content::MockDownloadItem item; 416 EXPECT_CALL(item, AddObserver(_)); 417 EXPECT_CALL(item, RemoveObserver(_)); 418 EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp)); 419 EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_exe)); 420 EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain)); 421 EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer)); 422 EXPECT_CALL(item, GetHash()).WillRepeatedly(ReturnRef(hash)); 423 EXPECT_CALL(item, GetReceivedBytes()).WillRepeatedly(Return(100)); 424 EXPECT_CALL(item, HasUserGesture()).WillRepeatedly(Return(true)); 425 EXPECT_CALL(item, GetRemoteAddress()).WillRepeatedly(Return("")); 426 427 EXPECT_CALL(*sb_service_->mock_database_manager(), 428 MatchDownloadWhitelistUrl(_)) 429 .WillRepeatedly(Return(false)); 430 EXPECT_CALL(*signature_util_.get(), CheckSignature(a_tmp, _)); 431 432 download_service_->CheckClientDownload( 433 &item, 434 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback, 435 base::Unretained(this))); 436 MessageLoop::current()->Run(); 437 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE)); 438 } 439 440 TEST_F(DownloadProtectionServiceTest, CheckClientDownloadSuccess) { 441 ClientDownloadResponse response; 442 response.set_verdict(ClientDownloadResponse::SAFE); 443 net::FakeURLFetcherFactory factory(NULL); 444 // Empty response means SAFE. 445 factory.SetFakeResponse( 446 DownloadProtectionService::GetDownloadRequestUrl(), 447 response.SerializeAsString(), 448 true); 449 450 base::FilePath a_tmp(FILE_PATH_LITERAL("a.tmp")); 451 base::FilePath a_exe(FILE_PATH_LITERAL("a.exe")); 452 std::vector<GURL> url_chain; 453 url_chain.push_back(GURL("http://www.evil.com/a.exe")); 454 GURL referrer("http://www.google.com/"); 455 std::string hash = "hash"; 456 457 content::MockDownloadItem item; 458 EXPECT_CALL(item, AddObserver(_)).Times(6); 459 EXPECT_CALL(item, RemoveObserver(_)).Times(6); 460 EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp)); 461 EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_exe)); 462 EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain)); 463 EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer)); 464 EXPECT_CALL(item, GetHash()).WillRepeatedly(ReturnRef(hash)); 465 EXPECT_CALL(item, GetReceivedBytes()).WillRepeatedly(Return(100)); 466 EXPECT_CALL(item, HasUserGesture()).WillRepeatedly(Return(true)); 467 EXPECT_CALL(item, GetRemoteAddress()).WillRepeatedly(Return("")); 468 469 EXPECT_CALL(*sb_service_->mock_database_manager(), 470 MatchDownloadWhitelistUrl(_)) 471 .WillRepeatedly(Return(false)); 472 EXPECT_CALL(*signature_util_.get(), CheckSignature(a_tmp, _)).Times(6); 473 474 download_service_->CheckClientDownload( 475 &item, 476 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback, 477 base::Unretained(this))); 478 MessageLoop::current()->Run(); 479 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE)); 480 481 // Invalid response should be safe too. 482 response.Clear(); 483 factory.SetFakeResponse( 484 DownloadProtectionService::GetDownloadRequestUrl(), 485 response.SerializePartialAsString(), 486 true); 487 488 download_service_->CheckClientDownload( 489 &item, 490 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback, 491 base::Unretained(this))); 492 MessageLoop::current()->Run(); 493 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE)); 494 std::string feedback_ping; 495 std::string feedback_response; 496 EXPECT_FALSE(DownloadFeedbackService::GetPingsForDownloadForTesting( 497 item, &feedback_ping, &feedback_response)); 498 499 // If the response is dangerous the result should also be marked as dangerous. 500 response.set_verdict(ClientDownloadResponse::DANGEROUS); 501 factory.SetFakeResponse( 502 DownloadProtectionService::GetDownloadRequestUrl(), 503 response.SerializeAsString(), 504 true); 505 506 download_service_->CheckClientDownload( 507 &item, 508 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback, 509 base::Unretained(this))); 510 MessageLoop::current()->Run(); 511 EXPECT_FALSE(DownloadFeedbackService::GetPingsForDownloadForTesting( 512 item, &feedback_ping, &feedback_response)); 513 #if defined(OS_WIN) 514 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS)); 515 #else 516 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE)); 517 #endif 518 519 // If the response is uncommon the result should also be marked as uncommon. 520 response.set_verdict(ClientDownloadResponse::UNCOMMON); 521 factory.SetFakeResponse( 522 DownloadProtectionService::GetDownloadRequestUrl(), 523 response.SerializeAsString(), 524 true); 525 526 download_service_->CheckClientDownload( 527 &item, 528 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback, 529 base::Unretained(this))); 530 MessageLoop::current()->Run(); 531 #if defined(OS_WIN) 532 EXPECT_TRUE(IsResult(DownloadProtectionService::UNCOMMON)); 533 EXPECT_TRUE(DownloadFeedbackService::GetPingsForDownloadForTesting( 534 item, &feedback_ping, &feedback_response)); 535 ClientDownloadRequest decoded_request; 536 EXPECT_TRUE(decoded_request.ParseFromString(feedback_ping)); 537 EXPECT_EQ(url_chain.back().spec(), decoded_request.url()); 538 EXPECT_EQ(response.SerializeAsString(), feedback_response); 539 #else 540 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE)); 541 #endif 542 543 // If the response is dangerous_host the result should also be marked as 544 // dangerous_host. 545 response.set_verdict(ClientDownloadResponse::DANGEROUS_HOST); 546 factory.SetFakeResponse( 547 DownloadProtectionService::GetDownloadRequestUrl(), 548 response.SerializeAsString(), 549 true); 550 551 download_service_->CheckClientDownload( 552 &item, 553 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback, 554 base::Unretained(this))); 555 MessageLoop::current()->Run(); 556 #if defined(OS_WIN) 557 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS_HOST)); 558 EXPECT_TRUE(DownloadFeedbackService::GetPingsForDownloadForTesting( 559 item, &feedback_ping, &feedback_response)); 560 EXPECT_EQ(response.SerializeAsString(), feedback_response); 561 #else 562 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE)); 563 #endif 564 565 // If the response is POTENTIALLY_UNWANTED the result should also be marked as 566 // POTENTIALLY_UNWANTED. 567 response.set_verdict(ClientDownloadResponse::POTENTIALLY_UNWANTED); 568 factory.SetFakeResponse( 569 DownloadProtectionService::GetDownloadRequestUrl(), 570 response.SerializeAsString(), 571 true); 572 573 download_service_->CheckClientDownload( 574 &item, 575 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback, 576 base::Unretained(this))); 577 MessageLoop::current()->Run(); 578 #if defined(OS_WIN) 579 EXPECT_TRUE(IsResult(DownloadProtectionService::POTENTIALLY_UNWANTED)); 580 #else 581 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE)); 582 #endif 583 } 584 585 TEST_F(DownloadProtectionServiceTest, CheckClientDownloadHTTPS) { 586 ClientDownloadResponse response; 587 response.set_verdict(ClientDownloadResponse::DANGEROUS); 588 net::FakeURLFetcherFactory factory(NULL); 589 factory.SetFakeResponse( 590 DownloadProtectionService::GetDownloadRequestUrl(), 591 response.SerializeAsString(), 592 true); 593 594 base::FilePath a_tmp(FILE_PATH_LITERAL("a.tmp")); 595 base::FilePath a_exe(FILE_PATH_LITERAL("a.exe")); 596 std::vector<GURL> url_chain; 597 url_chain.push_back(GURL("http://www.evil.com/a.exe")); 598 GURL referrer("http://www.google.com/"); 599 std::string hash = "hash"; 600 601 content::MockDownloadItem item; 602 EXPECT_CALL(item, AddObserver(_)).Times(1); 603 EXPECT_CALL(item, RemoveObserver(_)).Times(1); 604 EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp)); 605 EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_exe)); 606 EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain)); 607 EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer)); 608 EXPECT_CALL(item, GetHash()).WillRepeatedly(ReturnRef(hash)); 609 EXPECT_CALL(item, GetReceivedBytes()).WillRepeatedly(Return(100)); 610 EXPECT_CALL(item, HasUserGesture()).WillRepeatedly(Return(true)); 611 EXPECT_CALL(item, GetRemoteAddress()).WillRepeatedly(Return("")); 612 613 EXPECT_CALL(*sb_service_->mock_database_manager(), 614 MatchDownloadWhitelistUrl(_)) 615 .WillRepeatedly(Return(false)); 616 EXPECT_CALL(*signature_util_.get(), CheckSignature(a_tmp, _)).Times(1); 617 618 download_service_->CheckClientDownload( 619 &item, 620 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback, 621 base::Unretained(this))); 622 MessageLoop::current()->Run(); 623 #if defined(OS_WIN) 624 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS)); 625 #else 626 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE)); 627 #endif 628 } 629 630 TEST_F(DownloadProtectionServiceTest, CheckClientDownloadZip) { 631 ClientDownloadResponse response; 632 response.set_verdict(ClientDownloadResponse::SAFE); 633 net::FakeURLFetcherFactory factory(NULL); 634 // Empty response means SAFE. 635 factory.SetFakeResponse( 636 DownloadProtectionService::GetDownloadRequestUrl(), 637 response.SerializeAsString(), 638 true); 639 640 base::ScopedTempDir download_dir; 641 ASSERT_TRUE(download_dir.CreateUniqueTempDir()); 642 643 base::FilePath a_tmp(download_dir.path().Append(FILE_PATH_LITERAL("a.tmp"))); 644 base::FilePath a_zip(FILE_PATH_LITERAL("a.zip")); 645 std::vector<GURL> url_chain; 646 url_chain.push_back(GURL("http://www.evil.com/a.zip")); 647 GURL referrer("http://www.google.com/"); 648 std::string hash = "hash"; 649 650 content::MockDownloadItem item; 651 EXPECT_CALL(item, AddObserver(_)).Times(3); 652 EXPECT_CALL(item, RemoveObserver(_)).Times(3); 653 EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp)); 654 EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_zip)); 655 EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain)); 656 EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer)); 657 EXPECT_CALL(item, GetHash()).WillRepeatedly(ReturnRef(hash)); 658 EXPECT_CALL(item, GetReceivedBytes()).WillRepeatedly(Return(100)); 659 EXPECT_CALL(item, HasUserGesture()).WillRepeatedly(Return(true)); 660 EXPECT_CALL(item, GetRemoteAddress()).WillRepeatedly(Return("")); 661 662 // Write out a zip archive to the temporary file. In this case, it 663 // only contains a text file. 664 base::ScopedTempDir zip_source_dir; 665 ASSERT_TRUE(zip_source_dir.CreateUniqueTempDir()); 666 std::string file_contents = "dummy file"; 667 ASSERT_EQ(static_cast<int>(file_contents.size()), file_util::WriteFile( 668 zip_source_dir.path().Append(FILE_PATH_LITERAL("file.txt")), 669 file_contents.data(), file_contents.size())); 670 ASSERT_TRUE(zip::Zip(zip_source_dir.path(), a_tmp, false)); 671 672 download_service_->CheckClientDownload( 673 &item, 674 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback, 675 base::Unretained(this))); 676 MessageLoop::current()->Run(); 677 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE)); 678 Mock::VerifyAndClearExpectations(sb_service_.get()); 679 Mock::VerifyAndClearExpectations(signature_util_.get()); 680 681 // Now check with an executable in the zip file as well. 682 ASSERT_EQ(static_cast<int>(file_contents.size()), file_util::WriteFile( 683 zip_source_dir.path().Append(FILE_PATH_LITERAL("file.exe")), 684 file_contents.data(), file_contents.size())); 685 ASSERT_TRUE(zip::Zip(zip_source_dir.path(), a_tmp, false)); 686 687 EXPECT_CALL(*sb_service_->mock_database_manager(), 688 MatchDownloadWhitelistUrl(_)) 689 .WillRepeatedly(Return(false)); 690 691 download_service_->CheckClientDownload( 692 &item, 693 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback, 694 base::Unretained(this))); 695 MessageLoop::current()->Run(); 696 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE)); 697 Mock::VerifyAndClearExpectations(signature_util_.get()); 698 699 // If the response is dangerous the result should also be marked as 700 // dangerous. 701 response.set_verdict(ClientDownloadResponse::DANGEROUS); 702 factory.SetFakeResponse( 703 DownloadProtectionService::GetDownloadRequestUrl(), 704 response.SerializeAsString(), 705 true); 706 707 download_service_->CheckClientDownload( 708 &item, 709 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback, 710 base::Unretained(this))); 711 MessageLoop::current()->Run(); 712 #if defined(OS_WIN) 713 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS)); 714 #else 715 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE)); 716 #endif 717 Mock::VerifyAndClearExpectations(signature_util_.get()); 718 } 719 720 TEST_F(DownloadProtectionServiceTest, CheckClientDownloadCorruptZip) { 721 base::ScopedTempDir download_dir; 722 ASSERT_TRUE(download_dir.CreateUniqueTempDir()); 723 724 base::FilePath a_tmp(download_dir.path().Append(FILE_PATH_LITERAL("a.tmp"))); 725 base::FilePath a_zip(FILE_PATH_LITERAL("a.zip")); 726 std::vector<GURL> url_chain; 727 url_chain.push_back(GURL("http://www.evil.com/a.zip")); 728 GURL referrer("http://www.google.com/"); 729 std::string hash = "hash"; 730 731 content::MockDownloadItem item; 732 EXPECT_CALL(item, AddObserver(_)).Times(1); 733 EXPECT_CALL(item, RemoveObserver(_)).Times(1); 734 EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp)); 735 EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_zip)); 736 EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain)); 737 EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer)); 738 EXPECT_CALL(item, GetHash()).WillRepeatedly(ReturnRef(hash)); 739 EXPECT_CALL(item, GetReceivedBytes()).WillRepeatedly(Return(100)); 740 EXPECT_CALL(item, HasUserGesture()).WillRepeatedly(Return(true)); 741 EXPECT_CALL(item, GetRemoteAddress()).WillRepeatedly(Return("")); 742 743 std::string file_contents = "corrupt zip file"; 744 ASSERT_EQ(static_cast<int>(file_contents.size()), file_util::WriteFile( 745 a_tmp, file_contents.data(), file_contents.size())); 746 747 download_service_->CheckClientDownload( 748 &item, 749 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback, 750 base::Unretained(this))); 751 MessageLoop::current()->Run(); 752 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE)); 753 Mock::VerifyAndClearExpectations(sb_service_.get()); 754 Mock::VerifyAndClearExpectations(signature_util_.get()); 755 } 756 757 TEST_F(DownloadProtectionServiceTest, CheckClientCrxDownloadSuccess) { 758 ClientDownloadResponse response; 759 // Even if the server verdict is dangerous we should return SAFE because 760 // DownloadProtectionService::IsSupportedDownload() will return false 761 // for crx downloads. 762 response.set_verdict(ClientDownloadResponse::DANGEROUS); 763 net::FakeURLFetcherFactory factory(NULL); 764 // Empty response means SAFE. 765 factory.SetFakeResponse( 766 DownloadProtectionService::GetDownloadRequestUrl(), 767 response.SerializeAsString(), 768 true); 769 770 base::FilePath a_tmp(FILE_PATH_LITERAL("a.tmp")); 771 base::FilePath a_crx(FILE_PATH_LITERAL("a.crx")); 772 std::vector<GURL> url_chain; 773 url_chain.push_back(GURL("http://www.evil.com/a.crx")); 774 GURL referrer("http://www.google.com/"); 775 std::string hash = "hash"; 776 777 content::MockDownloadItem item; 778 EXPECT_CALL(item, AddObserver(_)).Times(1); 779 EXPECT_CALL(item, RemoveObserver(_)).Times(1); 780 EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp)); 781 EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_crx)); 782 EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain)); 783 EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer)); 784 EXPECT_CALL(item, GetHash()).WillRepeatedly(ReturnRef(hash)); 785 EXPECT_CALL(item, GetReceivedBytes()).WillRepeatedly(Return(100)); 786 EXPECT_CALL(item, HasUserGesture()).WillRepeatedly(Return(true)); 787 EXPECT_CALL(item, GetRemoteAddress()).WillRepeatedly(Return("")); 788 789 EXPECT_CALL(*sb_service_->mock_database_manager(), 790 MatchDownloadWhitelistUrl(_)) 791 .WillRepeatedly(Return(false)); 792 EXPECT_CALL(*signature_util_.get(), CheckSignature(a_tmp, _)).Times(1); 793 794 EXPECT_FALSE(download_service_->IsSupportedDownload(item, a_crx)); 795 download_service_->CheckClientDownload( 796 &item, 797 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback, 798 base::Unretained(this))); 799 MessageLoop::current()->Run(); 800 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE)); 801 } 802 803 TEST_F(DownloadProtectionServiceTest, CheckClientDownloadValidateRequest) { 804 net::TestURLFetcherFactory factory; 805 806 base::FilePath tmp_path(FILE_PATH_LITERAL("bla.tmp")); 807 base::FilePath final_path(FILE_PATH_LITERAL("bla.exe")); 808 std::vector<GURL> url_chain; 809 url_chain.push_back(GURL("http://www.google.com/")); 810 url_chain.push_back(GURL("http://www.google.com/bla.exe")); 811 GURL referrer("http://www.google.com/"); 812 std::string hash = "hash"; 813 std::string remote_address = "10.11.12.13"; 814 815 content::MockDownloadItem item; 816 EXPECT_CALL(item, AddObserver(_)).Times(1); 817 EXPECT_CALL(item, RemoveObserver(_)).Times(1); 818 EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(tmp_path)); 819 EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(final_path)); 820 EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain)); 821 EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer)); 822 EXPECT_CALL(item, GetHash()).WillRepeatedly(ReturnRef(hash)); 823 EXPECT_CALL(item, GetReceivedBytes()).WillRepeatedly(Return(100)); 824 EXPECT_CALL(item, HasUserGesture()).WillRepeatedly(Return(true)); 825 EXPECT_CALL(item, GetRemoteAddress()).WillRepeatedly(Return(remote_address)); 826 827 EXPECT_CALL(*sb_service_->mock_database_manager(), 828 MatchDownloadWhitelistUrl(_)) 829 .WillRepeatedly(Return(false)); 830 EXPECT_CALL(*signature_util_.get(), CheckSignature(tmp_path, _)) 831 .WillOnce(SetCertificateContents("dummy cert data")); 832 download_service_->CheckClientDownload( 833 &item, 834 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback, 835 base::Unretained(this))); 836 837 #if !defined(OS_WIN) 838 // SendRequest is not called. Wait for FinishRequest to call our callback. 839 MessageLoop::current()->Run(); 840 net::TestURLFetcher* fetcher = factory.GetFetcherByID(0); 841 EXPECT_EQ(NULL, fetcher); 842 #else 843 // Run the message loop(s) until SendRequest is called. 844 FlushThreadMessageLoops(); 845 net::TestURLFetcher* fetcher = factory.GetFetcherByID(0); 846 ASSERT_TRUE(fetcher); 847 ClientDownloadRequest request; 848 EXPECT_TRUE(request.ParseFromString(fetcher->upload_data())); 849 EXPECT_EQ("http://www.google.com/bla.exe", request.url()); 850 EXPECT_EQ(hash, request.digests().sha256()); 851 EXPECT_EQ(item.GetReceivedBytes(), request.length()); 852 EXPECT_EQ(item.HasUserGesture(), request.user_initiated()); 853 EXPECT_TRUE(RequestContainsServerIp(request, remote_address)); 854 EXPECT_EQ(2, request.resources_size()); 855 EXPECT_TRUE(RequestContainsResource(request, 856 ClientDownloadRequest::DOWNLOAD_REDIRECT, 857 "http://www.google.com/", "")); 858 EXPECT_TRUE(RequestContainsResource(request, 859 ClientDownloadRequest::DOWNLOAD_URL, 860 "http://www.google.com/bla.exe", 861 referrer.spec())); 862 EXPECT_TRUE(request.has_signature()); 863 ASSERT_EQ(1, request.signature().certificate_chain_size()); 864 const ClientDownloadRequest_CertificateChain& chain = 865 request.signature().certificate_chain(0); 866 ASSERT_EQ(1, chain.element_size()); 867 EXPECT_EQ("dummy cert data", chain.element(0).certificate()); 868 869 // Simulate the request finishing. 870 base::MessageLoop::current()->PostTask( 871 FROM_HERE, 872 base::Bind(&DownloadProtectionServiceTest::SendURLFetchComplete, 873 base::Unretained(this), fetcher)); 874 MessageLoop::current()->Run(); 875 #endif 876 } 877 878 // Similar to above, but with an unsigned binary. 879 TEST_F(DownloadProtectionServiceTest, 880 CheckClientDownloadValidateRequestNoSignature) { 881 net::TestURLFetcherFactory factory; 882 883 base::FilePath tmp_path(FILE_PATH_LITERAL("bla.tmp")); 884 base::FilePath final_path(FILE_PATH_LITERAL("bla.exe")); 885 std::vector<GURL> url_chain; 886 url_chain.push_back(GURL("http://www.google.com/")); 887 url_chain.push_back(GURL("ftp://www.google.com/bla.exe")); 888 GURL referrer("http://www.google.com/"); 889 std::string hash = "hash"; 890 std::string remote_address = "10.11.12.13"; 891 892 content::MockDownloadItem item; 893 EXPECT_CALL(item, AddObserver(_)).Times(1); 894 EXPECT_CALL(item, RemoveObserver(_)).Times(1); 895 EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(tmp_path)); 896 EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(final_path)); 897 EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain)); 898 EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer)); 899 EXPECT_CALL(item, GetHash()).WillRepeatedly(ReturnRef(hash)); 900 EXPECT_CALL(item, GetReceivedBytes()).WillRepeatedly(Return(100)); 901 EXPECT_CALL(item, HasUserGesture()).WillRepeatedly(Return(true)); 902 EXPECT_CALL(item, GetRemoteAddress()).WillRepeatedly(Return(remote_address)); 903 904 EXPECT_CALL(*sb_service_->mock_database_manager(), 905 MatchDownloadWhitelistUrl(_)) 906 .WillRepeatedly(Return(false)); 907 EXPECT_CALL(*signature_util_.get(), CheckSignature(tmp_path, _)); 908 download_service_->CheckClientDownload( 909 &item, 910 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback, 911 base::Unretained(this))); 912 913 #if !defined(OS_WIN) 914 // SendRequest is not called. Wait for FinishRequest to call our callback. 915 MessageLoop::current()->Run(); 916 net::TestURLFetcher* fetcher = factory.GetFetcherByID(0); 917 EXPECT_EQ(NULL, fetcher); 918 #else 919 // Run the message loop(s) until SendRequest is called. 920 FlushThreadMessageLoops(); 921 net::TestURLFetcher* fetcher = factory.GetFetcherByID(0); 922 ASSERT_TRUE(fetcher); 923 ClientDownloadRequest request; 924 EXPECT_TRUE(request.ParseFromString(fetcher->upload_data())); 925 EXPECT_EQ("ftp://www.google.com/bla.exe", request.url()); 926 EXPECT_EQ(hash, request.digests().sha256()); 927 EXPECT_EQ(item.GetReceivedBytes(), request.length()); 928 EXPECT_EQ(item.HasUserGesture(), request.user_initiated()); 929 EXPECT_EQ(2, request.resources_size()); 930 EXPECT_TRUE(RequestContainsResource(request, 931 ClientDownloadRequest::DOWNLOAD_REDIRECT, 932 "http://www.google.com/", "")); 933 EXPECT_TRUE(RequestContainsResource(request, 934 ClientDownloadRequest::DOWNLOAD_URL, 935 "ftp://www.google.com/bla.exe", 936 referrer.spec())); 937 EXPECT_TRUE(request.has_signature()); 938 EXPECT_EQ(0, request.signature().certificate_chain_size()); 939 940 // Simulate the request finishing. 941 base::MessageLoop::current()->PostTask( 942 FROM_HERE, 943 base::Bind(&DownloadProtectionServiceTest::SendURLFetchComplete, 944 base::Unretained(this), fetcher)); 945 MessageLoop::current()->Run(); 946 #endif 947 } 948 949 TEST_F(DownloadProtectionServiceTest, TestCheckDownloadUrl) { 950 std::vector<GURL> url_chain; 951 url_chain.push_back(GURL("http://www.google.com/")); 952 url_chain.push_back(GURL("http://www.google.com/bla.exe")); 953 GURL referrer("http://www.google.com/"); 954 std::string hash = "hash"; 955 956 content::MockDownloadItem item; 957 EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain)); 958 EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer)); 959 EXPECT_CALL(item, GetHash()).WillRepeatedly(ReturnRef(hash)); 960 961 // CheckDownloadURL returns immediately which means the client object callback 962 // will never be called. Nevertheless the callback provided to 963 // CheckClientDownload must still be called. 964 EXPECT_CALL(*sb_service_->mock_database_manager(), 965 CheckDownloadUrl(ContainerEq(url_chain), NotNull())) 966 .WillOnce(Return(true)); 967 download_service_->CheckDownloadUrl( 968 item, 969 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback, 970 base::Unretained(this))); 971 MessageLoop::current()->Run(); 972 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE)); 973 Mock::VerifyAndClearExpectations(sb_service_.get()); 974 975 EXPECT_CALL(*sb_service_->mock_database_manager(), 976 CheckDownloadUrl(ContainerEq(url_chain), NotNull())) 977 .WillOnce(DoAll(CheckDownloadUrlDone(SB_THREAT_TYPE_SAFE), 978 Return(false))); 979 download_service_->CheckDownloadUrl( 980 item, 981 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback, 982 base::Unretained(this))); 983 MessageLoop::current()->Run(); 984 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE)); 985 Mock::VerifyAndClearExpectations(sb_service_.get()); 986 987 EXPECT_CALL(*sb_service_->mock_database_manager(), 988 CheckDownloadUrl(ContainerEq(url_chain), NotNull())) 989 .WillOnce(DoAll( 990 CheckDownloadUrlDone(SB_THREAT_TYPE_URL_MALWARE), 991 Return(false))); 992 download_service_->CheckDownloadUrl( 993 item, 994 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback, 995 base::Unretained(this))); 996 MessageLoop::current()->Run(); 997 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE)); 998 Mock::VerifyAndClearExpectations(sb_service_.get()); 999 1000 EXPECT_CALL(*sb_service_->mock_database_manager(), 1001 CheckDownloadUrl(ContainerEq(url_chain), 1002 NotNull())) 1003 .WillOnce(DoAll( 1004 CheckDownloadUrlDone(SB_THREAT_TYPE_BINARY_MALWARE_URL), 1005 Return(false))); 1006 download_service_->CheckDownloadUrl( 1007 item, 1008 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback, 1009 base::Unretained(this))); 1010 MessageLoop::current()->Run(); 1011 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS)); 1012 } 1013 1014 TEST_F(DownloadProtectionServiceTest, TestDownloadRequestTimeout) { 1015 net::TestURLFetcherFactory factory; 1016 1017 std::vector<GURL> url_chain; 1018 url_chain.push_back(GURL("http://www.evil.com/bla.exe")); 1019 GURL referrer("http://www.google.com/"); 1020 base::FilePath tmp_path(FILE_PATH_LITERAL("a.tmp")); 1021 base::FilePath final_path(FILE_PATH_LITERAL("a.exe")); 1022 std::string hash = "hash"; 1023 1024 content::MockDownloadItem item; 1025 EXPECT_CALL(item, AddObserver(_)).Times(1); 1026 EXPECT_CALL(item, RemoveObserver(_)).Times(1); 1027 EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(tmp_path)); 1028 EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(final_path)); 1029 EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain)); 1030 EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer)); 1031 EXPECT_CALL(item, GetHash()).WillRepeatedly(ReturnRef(hash)); 1032 EXPECT_CALL(item, GetReceivedBytes()).WillRepeatedly(Return(100)); 1033 EXPECT_CALL(item, HasUserGesture()).WillRepeatedly(Return(true)); 1034 EXPECT_CALL(item, GetRemoteAddress()).WillRepeatedly(Return("")); 1035 1036 EXPECT_CALL(*sb_service_->mock_database_manager(), 1037 MatchDownloadWhitelistUrl(_)) 1038 .WillRepeatedly(Return(false)); 1039 EXPECT_CALL(*signature_util_.get(), CheckSignature(tmp_path, _)); 1040 1041 download_service_->download_request_timeout_ms_ = 10; 1042 download_service_->CheckClientDownload( 1043 &item, 1044 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback, 1045 base::Unretained(this))); 1046 1047 // The request should time out because the HTTP request hasn't returned 1048 // anything yet. 1049 MessageLoop::current()->Run(); 1050 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE)); 1051 } 1052 1053 TEST_F(DownloadProtectionServiceTest, TestDownloadItemDestroyed) { 1054 net::TestURLFetcherFactory factory; 1055 1056 std::vector<GURL> url_chain; 1057 url_chain.push_back(GURL("http://www.evil.com/bla.exe")); 1058 GURL referrer("http://www.google.com/"); 1059 base::FilePath tmp_path(FILE_PATH_LITERAL("a.tmp")); 1060 base::FilePath final_path(FILE_PATH_LITERAL("a.exe")); 1061 std::string hash = "hash"; 1062 1063 content::MockDownloadItem item; 1064 content::DownloadItem::Observer* observer = NULL; 1065 EXPECT_CALL(item, AddObserver(_)).WillOnce(SaveArg<0>(&observer)); 1066 EXPECT_CALL(item, RemoveObserver(_)).WillOnce(Assign( 1067 &observer, static_cast<content::DownloadItem::Observer*>(NULL))); 1068 EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(tmp_path)); 1069 EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(final_path)); 1070 EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain)); 1071 EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer)); 1072 EXPECT_CALL(item, GetHash()).WillRepeatedly(ReturnRef(hash)); 1073 EXPECT_CALL(item, GetReceivedBytes()).WillRepeatedly(Return(100)); 1074 EXPECT_CALL(item, HasUserGesture()).WillRepeatedly(Return(true)); 1075 EXPECT_CALL(item, GetRemoteAddress()).WillRepeatedly(Return("")); 1076 1077 EXPECT_CALL(*sb_service_->mock_database_manager(), 1078 MatchDownloadWhitelistUrl(_)) 1079 .WillRepeatedly(Return(false)); 1080 EXPECT_CALL(*signature_util_.get(), CheckSignature(tmp_path, _)); 1081 1082 download_service_->CheckClientDownload( 1083 &item, 1084 base::Bind(&DownloadProtectionServiceTest::SyncCheckDoneCallback, 1085 base::Unretained(this))); 1086 1087 ASSERT_TRUE(observer != NULL); 1088 observer->OnDownloadDestroyed(&item); 1089 1090 EXPECT_TRUE(observer == NULL); 1091 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE)); 1092 } 1093 1094 TEST_F(DownloadProtectionServiceTest, GetCertificateWhitelistStrings) { 1095 // We'll pass this cert in as the "issuer", even though it isn't really 1096 // used to sign the certs below. GetCertificateWhitelistStirngs doesn't care 1097 // about this. 1098 scoped_refptr<net::X509Certificate> issuer_cert( 1099 ReadTestCertificate("issuer.pem")); 1100 ASSERT_TRUE(issuer_cert.get()); 1101 std::string cert_base = "cert/" + base::HexEncode( 1102 issuer_cert->fingerprint().data, 1103 sizeof(issuer_cert->fingerprint().data)); 1104 1105 scoped_refptr<net::X509Certificate> cert(ReadTestCertificate("test_cn.pem")); 1106 ASSERT_TRUE(cert.get()); 1107 std::vector<std::string> whitelist_strings; 1108 GetCertificateWhitelistStrings( 1109 *cert.get(), *issuer_cert.get(), &whitelist_strings); 1110 // This also tests escaping of characters in the certificate attributes. 1111 EXPECT_THAT(whitelist_strings, ElementsAre( 1112 cert_base + "/CN=subject%2F%251")); 1113 1114 cert = ReadTestCertificate("test_cn_o.pem"); 1115 ASSERT_TRUE(cert.get()); 1116 whitelist_strings.clear(); 1117 GetCertificateWhitelistStrings( 1118 *cert.get(), *issuer_cert.get(), &whitelist_strings); 1119 EXPECT_THAT(whitelist_strings, 1120 ElementsAre(cert_base + "/CN=subject", 1121 cert_base + "/CN=subject/O=org", 1122 cert_base + "/O=org")); 1123 1124 cert = ReadTestCertificate("test_cn_o_ou.pem"); 1125 ASSERT_TRUE(cert.get()); 1126 whitelist_strings.clear(); 1127 GetCertificateWhitelistStrings( 1128 *cert.get(), *issuer_cert.get(), &whitelist_strings); 1129 EXPECT_THAT(whitelist_strings, 1130 ElementsAre(cert_base + "/CN=subject", 1131 cert_base + "/CN=subject/O=org", 1132 cert_base + "/CN=subject/O=org/OU=unit", 1133 cert_base + "/CN=subject/OU=unit", 1134 cert_base + "/O=org", 1135 cert_base + "/O=org/OU=unit", 1136 cert_base + "/OU=unit")); 1137 1138 cert = ReadTestCertificate("test_cn_ou.pem"); 1139 ASSERT_TRUE(cert.get()); 1140 whitelist_strings.clear(); 1141 GetCertificateWhitelistStrings( 1142 *cert.get(), *issuer_cert.get(), &whitelist_strings); 1143 EXPECT_THAT(whitelist_strings, 1144 ElementsAre(cert_base + "/CN=subject", 1145 cert_base + "/CN=subject/OU=unit", 1146 cert_base + "/OU=unit")); 1147 1148 cert = ReadTestCertificate("test_o.pem"); 1149 ASSERT_TRUE(cert.get()); 1150 whitelist_strings.clear(); 1151 GetCertificateWhitelistStrings( 1152 *cert.get(), *issuer_cert.get(), &whitelist_strings); 1153 EXPECT_THAT(whitelist_strings, ElementsAre(cert_base + "/O=org")); 1154 1155 cert = ReadTestCertificate("test_o_ou.pem"); 1156 ASSERT_TRUE(cert.get()); 1157 whitelist_strings.clear(); 1158 GetCertificateWhitelistStrings( 1159 *cert.get(), *issuer_cert.get(), &whitelist_strings); 1160 EXPECT_THAT(whitelist_strings, 1161 ElementsAre(cert_base + "/O=org", 1162 cert_base + "/O=org/OU=unit", 1163 cert_base + "/OU=unit")); 1164 1165 cert = ReadTestCertificate("test_ou.pem"); 1166 ASSERT_TRUE(cert.get()); 1167 whitelist_strings.clear(); 1168 GetCertificateWhitelistStrings( 1169 *cert.get(), *issuer_cert.get(), &whitelist_strings); 1170 EXPECT_THAT(whitelist_strings, ElementsAre(cert_base + "/OU=unit")); 1171 1172 cert = ReadTestCertificate("test_c.pem"); 1173 ASSERT_TRUE(cert.get()); 1174 whitelist_strings.clear(); 1175 GetCertificateWhitelistStrings( 1176 *cert.get(), *issuer_cert.get(), &whitelist_strings); 1177 EXPECT_THAT(whitelist_strings, ElementsAre()); 1178 } 1179 } // namespace safe_browsing 1180