| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/safe_browsing/download_protection_service.h" | 5 #include "chrome/browser/safe_browsing/download_protection_service.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/compiler_specific.h" | 8 #include "base/compiler_specific.h" |
| 9 #include "base/format_macros.h" | 9 #include "base/format_macros.h" |
| 10 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
| (...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 248 const content::DownloadItem& item, | 248 const content::DownloadItem& item, |
| 249 const DownloadProtectionService::CheckDownloadCallback& callback, | 249 const DownloadProtectionService::CheckDownloadCallback& callback, |
| 250 const scoped_refptr<SafeBrowsingUIManager>& ui_manager, | 250 const scoped_refptr<SafeBrowsingUIManager>& ui_manager, |
| 251 const scoped_refptr<SafeBrowsingDatabaseManager>& database_manager) | 251 const scoped_refptr<SafeBrowsingDatabaseManager>& database_manager) |
| 252 : DownloadSBClient(item, callback, ui_manager, | 252 : DownloadSBClient(item, callback, ui_manager, |
| 253 DOWNLOAD_URL_CHECKS_TOTAL, | 253 DOWNLOAD_URL_CHECKS_TOTAL, |
| 254 DOWNLOAD_URL_CHECKS_MALWARE), | 254 DOWNLOAD_URL_CHECKS_MALWARE), |
| 255 database_manager_(database_manager) { } | 255 database_manager_(database_manager) { } |
| 256 | 256 |
| 257 void StartCheck() override { | 257 void StartCheck() override { |
| 258 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 258 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 259 if (!database_manager_.get() || | 259 if (!database_manager_.get() || |
| 260 database_manager_->CheckDownloadUrl(url_chain_, this)) { | 260 database_manager_->CheckDownloadUrl(url_chain_, this)) { |
| 261 CheckDone(SB_THREAT_TYPE_SAFE); | 261 CheckDone(SB_THREAT_TYPE_SAFE); |
| 262 } else { | 262 } else { |
| 263 AddRef(); // SafeBrowsingService takes a pointer not a scoped_refptr. | 263 AddRef(); // SafeBrowsingService takes a pointer not a scoped_refptr. |
| 264 } | 264 } |
| 265 } | 265 } |
| 266 | 266 |
| 267 bool IsDangerous(SBThreatType threat_type) const override { | 267 bool IsDangerous(SBThreatType threat_type) const override { |
| 268 return threat_type == SB_THREAT_TYPE_BINARY_MALWARE_URL; | 268 return threat_type == SB_THREAT_TYPE_BINARY_MALWARE_URL; |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 306 zipped_executable_(false), | 306 zipped_executable_(false), |
| 307 callback_(callback), | 307 callback_(callback), |
| 308 service_(service), | 308 service_(service), |
| 309 binary_feature_extractor_(binary_feature_extractor), | 309 binary_feature_extractor_(binary_feature_extractor), |
| 310 database_manager_(database_manager), | 310 database_manager_(database_manager), |
| 311 pingback_enabled_(service_->enabled()), | 311 pingback_enabled_(service_->enabled()), |
| 312 finished_(false), | 312 finished_(false), |
| 313 type_(ClientDownloadRequest::WIN_EXECUTABLE), | 313 type_(ClientDownloadRequest::WIN_EXECUTABLE), |
| 314 start_time_(base::TimeTicks::Now()), | 314 start_time_(base::TimeTicks::Now()), |
| 315 weakptr_factory_(this) { | 315 weakptr_factory_(this) { |
| 316 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 316 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 317 item_->AddObserver(this); | 317 item_->AddObserver(this); |
| 318 } | 318 } |
| 319 | 319 |
| 320 void Start() { | 320 void Start() { |
| 321 DVLOG(2) << "Starting SafeBrowsing download check for: " | 321 DVLOG(2) << "Starting SafeBrowsing download check for: " |
| 322 << item_->DebugString(true); | 322 << item_->DebugString(true); |
| 323 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 323 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 324 // TODO(noelutz): implement some cache to make sure we don't issue the same | 324 // TODO(noelutz): implement some cache to make sure we don't issue the same |
| 325 // request over and over again if a user downloads the same binary multiple | 325 // request over and over again if a user downloads the same binary multiple |
| 326 // times. | 326 // times. |
| 327 DownloadCheckResultReason reason = REASON_MAX; | 327 DownloadCheckResultReason reason = REASON_MAX; |
| 328 if (!IsSupportedDownload( | 328 if (!IsSupportedDownload( |
| 329 *item_, item_->GetTargetFilePath(), &reason, &type_)) { | 329 *item_, item_->GetTargetFilePath(), &reason, &type_)) { |
| 330 switch (reason) { | 330 switch (reason) { |
| 331 case REASON_EMPTY_URL_CHAIN: | 331 case REASON_EMPTY_URL_CHAIN: |
| 332 case REASON_INVALID_URL: | 332 case REASON_INVALID_URL: |
| 333 case REASON_UNSUPPORTED_URL_SCHEME: | 333 case REASON_UNSUPPORTED_URL_SCHEME: |
| (...skipping 21 matching lines...) Expand all Loading... |
| 355 } else { | 355 } else { |
| 356 DCHECK(!download_protection_util::IsArchiveFile( | 356 DCHECK(!download_protection_util::IsArchiveFile( |
| 357 item_->GetTargetFilePath())); | 357 item_->GetTargetFilePath())); |
| 358 StartExtractFileFeatures(); | 358 StartExtractFileFeatures(); |
| 359 } | 359 } |
| 360 } | 360 } |
| 361 | 361 |
| 362 // Start a timeout to cancel the request if it takes too long. | 362 // Start a timeout to cancel the request if it takes too long. |
| 363 // This should only be called after we have finished accessing the file. | 363 // This should only be called after we have finished accessing the file. |
| 364 void StartTimeout() { | 364 void StartTimeout() { |
| 365 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 365 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 366 if (!service_) { | 366 if (!service_) { |
| 367 // Request has already been cancelled. | 367 // Request has already been cancelled. |
| 368 return; | 368 return; |
| 369 } | 369 } |
| 370 timeout_start_time_ = base::TimeTicks::Now(); | 370 timeout_start_time_ = base::TimeTicks::Now(); |
| 371 BrowserThread::PostDelayedTask( | 371 BrowserThread::PostDelayedTask( |
| 372 BrowserThread::UI, | 372 BrowserThread::UI, |
| 373 FROM_HERE, | 373 FROM_HERE, |
| 374 base::Bind(&CheckClientDownloadRequest::Cancel, | 374 base::Bind(&CheckClientDownloadRequest::Cancel, |
| 375 weakptr_factory_.GetWeakPtr()), | 375 weakptr_factory_.GetWeakPtr()), |
| 376 base::TimeDelta::FromMilliseconds( | 376 base::TimeDelta::FromMilliseconds( |
| 377 service_->download_request_timeout_ms())); | 377 service_->download_request_timeout_ms())); |
| 378 } | 378 } |
| 379 | 379 |
| 380 // Canceling a request will cause us to always report the result as UNKNOWN | 380 // Canceling a request will cause us to always report the result as UNKNOWN |
| 381 // unless a pending request is about to call FinishRequest. | 381 // unless a pending request is about to call FinishRequest. |
| 382 void Cancel() { | 382 void Cancel() { |
| 383 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 383 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 384 if (fetcher_.get()) { | 384 if (fetcher_.get()) { |
| 385 // The DownloadProtectionService is going to release its reference, so we | 385 // The DownloadProtectionService is going to release its reference, so we |
| 386 // might be destroyed before the URLFetcher completes. Cancel the | 386 // might be destroyed before the URLFetcher completes. Cancel the |
| 387 // fetcher so it does not try to invoke OnURLFetchComplete. | 387 // fetcher so it does not try to invoke OnURLFetchComplete. |
| 388 fetcher_.reset(); | 388 fetcher_.reset(); |
| 389 } | 389 } |
| 390 // Note: If there is no fetcher, then some callback is still holding a | 390 // Note: If there is no fetcher, then some callback is still holding a |
| 391 // reference to this object. We'll eventually wind up in some method on | 391 // reference to this object. We'll eventually wind up in some method on |
| 392 // the UI thread that will call FinishRequest() again. If FinishRequest() | 392 // the UI thread that will call FinishRequest() again. If FinishRequest() |
| 393 // is called a second time, it will be a no-op. | 393 // is called a second time, it will be a no-op. |
| 394 FinishRequest(UNKNOWN, REASON_REQUEST_CANCELED); | 394 FinishRequest(UNKNOWN, REASON_REQUEST_CANCELED); |
| 395 // Calling FinishRequest might delete this object, we may be deleted by | 395 // Calling FinishRequest might delete this object, we may be deleted by |
| 396 // this point. | 396 // this point. |
| 397 } | 397 } |
| 398 | 398 |
| 399 // content::DownloadItem::Observer implementation. | 399 // content::DownloadItem::Observer implementation. |
| 400 void OnDownloadDestroyed(content::DownloadItem* download) override { | 400 void OnDownloadDestroyed(content::DownloadItem* download) override { |
| 401 Cancel(); | 401 Cancel(); |
| 402 DCHECK(item_ == NULL); | 402 DCHECK(item_ == NULL); |
| 403 } | 403 } |
| 404 | 404 |
| 405 // From the net::URLFetcherDelegate interface. | 405 // From the net::URLFetcherDelegate interface. |
| 406 void OnURLFetchComplete(const net::URLFetcher* source) override { | 406 void OnURLFetchComplete(const net::URLFetcher* source) override { |
| 407 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 407 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 408 DCHECK_EQ(source, fetcher_.get()); | 408 DCHECK_EQ(source, fetcher_.get()); |
| 409 DVLOG(2) << "Received a response for URL: " | 409 DVLOG(2) << "Received a response for URL: " |
| 410 << item_->GetUrlChain().back() << ": success=" | 410 << item_->GetUrlChain().back() << ": success=" |
| 411 << source->GetStatus().is_success() << " response_code=" | 411 << source->GetStatus().is_success() << " response_code=" |
| 412 << source->GetResponseCode(); | 412 << source->GetResponseCode(); |
| 413 if (source->GetStatus().is_success()) { | 413 if (source->GetStatus().is_success()) { |
| 414 UMA_HISTOGRAM_SPARSE_SLOWLY( | 414 UMA_HISTOGRAM_SPARSE_SLOWLY( |
| 415 "SBClientDownload.DownloadRequestResponseCode", | 415 "SBClientDownload.DownloadRequestResponseCode", |
| 416 source->GetResponseCode()); | 416 source->GetResponseCode()); |
| 417 } | 417 } |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 497 } | 497 } |
| 498 *type = download_protection_util::GetDownloadType(target_path); | 498 *type = download_protection_util::GetDownloadType(target_path); |
| 499 return true; | 499 return true; |
| 500 } | 500 } |
| 501 | 501 |
| 502 private: | 502 private: |
| 503 friend struct BrowserThread::DeleteOnThread<BrowserThread::UI>; | 503 friend struct BrowserThread::DeleteOnThread<BrowserThread::UI>; |
| 504 friend class base::DeleteHelper<CheckClientDownloadRequest>; | 504 friend class base::DeleteHelper<CheckClientDownloadRequest>; |
| 505 | 505 |
| 506 ~CheckClientDownloadRequest() override { | 506 ~CheckClientDownloadRequest() override { |
| 507 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 507 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 508 DCHECK(item_ == NULL); | 508 DCHECK(item_ == NULL); |
| 509 } | 509 } |
| 510 | 510 |
| 511 void OnFileFeatureExtractionDone() { | 511 void OnFileFeatureExtractionDone() { |
| 512 // This can run in any thread, since it just posts more messages. | 512 // This can run in any thread, since it just posts more messages. |
| 513 | 513 |
| 514 // TODO(noelutz): DownloadInfo should also contain the IP address of | 514 // TODO(noelutz): DownloadInfo should also contain the IP address of |
| 515 // every URL in the redirect chain. We also should check whether the | 515 // every URL in the redirect chain. We also should check whether the |
| 516 // download URL is hosted on the internal network. | 516 // download URL is hosted on the internal network. |
| 517 BrowserThread::PostTask( | 517 BrowserThread::PostTask( |
| 518 BrowserThread::IO, | 518 BrowserThread::IO, |
| 519 FROM_HERE, | 519 FROM_HERE, |
| 520 base::Bind(&CheckClientDownloadRequest::CheckWhitelists, this)); | 520 base::Bind(&CheckClientDownloadRequest::CheckWhitelists, this)); |
| 521 | 521 |
| 522 // We wait until after the file checks finish to start the timeout, as | 522 // We wait until after the file checks finish to start the timeout, as |
| 523 // windows can cause permissions errors if the timeout fired while we were | 523 // windows can cause permissions errors if the timeout fired while we were |
| 524 // checking the file signature and we tried to complete the download. | 524 // checking the file signature and we tried to complete the download. |
| 525 BrowserThread::PostTask( | 525 BrowserThread::PostTask( |
| 526 BrowserThread::UI, | 526 BrowserThread::UI, |
| 527 FROM_HERE, | 527 FROM_HERE, |
| 528 base::Bind(&CheckClientDownloadRequest::StartTimeout, this)); | 528 base::Bind(&CheckClientDownloadRequest::StartTimeout, this)); |
| 529 } | 529 } |
| 530 | 530 |
| 531 void StartExtractFileFeatures() { | 531 void StartExtractFileFeatures() { |
| 532 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 532 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 533 DCHECK(item_); // Called directly from Start(), item should still exist. | 533 DCHECK(item_); // Called directly from Start(), item should still exist. |
| 534 // Since we do blocking I/O, offload this to a worker thread. | 534 // Since we do blocking I/O, offload this to a worker thread. |
| 535 // The task does not need to block shutdown. | 535 // The task does not need to block shutdown. |
| 536 BrowserThread::GetBlockingPool()->PostWorkerTaskWithShutdownBehavior( | 536 BrowserThread::GetBlockingPool()->PostWorkerTaskWithShutdownBehavior( |
| 537 FROM_HERE, | 537 FROM_HERE, |
| 538 base::Bind(&CheckClientDownloadRequest::ExtractFileFeatures, | 538 base::Bind(&CheckClientDownloadRequest::ExtractFileFeatures, |
| 539 this, item_->GetFullPath()), | 539 this, item_->GetFullPath()), |
| 540 base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN); | 540 base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN); |
| 541 } | 541 } |
| 542 | 542 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 563 nullptr /* signed_data */)) { | 563 nullptr /* signed_data */)) { |
| 564 image_headers_.reset(); | 564 image_headers_.reset(); |
| 565 } | 565 } |
| 566 UMA_HISTOGRAM_TIMES("SBClientDownload.ExtractImageHeadersTime", | 566 UMA_HISTOGRAM_TIMES("SBClientDownload.ExtractImageHeadersTime", |
| 567 base::TimeTicks::Now() - start_time); | 567 base::TimeTicks::Now() - start_time); |
| 568 | 568 |
| 569 OnFileFeatureExtractionDone(); | 569 OnFileFeatureExtractionDone(); |
| 570 } | 570 } |
| 571 | 571 |
| 572 void StartExtractZipFeatures() { | 572 void StartExtractZipFeatures() { |
| 573 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 573 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 574 DCHECK(item_); // Called directly from Start(), item should still exist. | 574 DCHECK(item_); // Called directly from Start(), item should still exist. |
| 575 zip_analysis_start_time_ = base::TimeTicks::Now(); | 575 zip_analysis_start_time_ = base::TimeTicks::Now(); |
| 576 // We give the zip analyzer a weak pointer to this object. Since the | 576 // We give the zip analyzer a weak pointer to this object. Since the |
| 577 // analyzer is refcounted, it might outlive the request. | 577 // analyzer is refcounted, it might outlive the request. |
| 578 analyzer_ = new SandboxedZipAnalyzer( | 578 analyzer_ = new SandboxedZipAnalyzer( |
| 579 item_->GetFullPath(), | 579 item_->GetFullPath(), |
| 580 base::Bind(&CheckClientDownloadRequest::OnZipAnalysisFinished, | 580 base::Bind(&CheckClientDownloadRequest::OnZipAnalysisFinished, |
| 581 weakptr_factory_.GetWeakPtr())); | 581 weakptr_factory_.GetWeakPtr())); |
| 582 analyzer_->Start(); | 582 analyzer_->Start(); |
| 583 } | 583 } |
| 584 | 584 |
| 585 void OnZipAnalysisFinished(const zip_analyzer::Results& results) { | 585 void OnZipAnalysisFinished(const zip_analyzer::Results& results) { |
| 586 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 586 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 587 if (!service_) | 587 if (!service_) |
| 588 return; | 588 return; |
| 589 if (results.success) { | 589 if (results.success) { |
| 590 zipped_executable_ = results.has_executable; | 590 zipped_executable_ = results.has_executable; |
| 591 archived_binary_.CopyFrom(results.archived_binary); | 591 archived_binary_.CopyFrom(results.archived_binary); |
| 592 DVLOG(1) << "Zip analysis finished for " << item_->GetFullPath().value() | 592 DVLOG(1) << "Zip analysis finished for " << item_->GetFullPath().value() |
| 593 << ", has_executable=" << results.has_executable | 593 << ", has_executable=" << results.has_executable |
| 594 << " has_archive=" << results.has_archive; | 594 << " has_archive=" << results.has_archive; |
| 595 } else { | 595 } else { |
| 596 DVLOG(1) << "Zip analysis failed for " << item_->GetFullPath().value(); | 596 DVLOG(1) << "Zip analysis failed for " << item_->GetFullPath().value(); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 607 return; | 607 return; |
| 608 } | 608 } |
| 609 OnFileFeatureExtractionDone(); | 609 OnFileFeatureExtractionDone(); |
| 610 } | 610 } |
| 611 | 611 |
| 612 static void RecordCountOfSignedOrWhitelistedDownload() { | 612 static void RecordCountOfSignedOrWhitelistedDownload() { |
| 613 UMA_HISTOGRAM_COUNTS("SBClientDownload.SignedOrWhitelistedDownload", 1); | 613 UMA_HISTOGRAM_COUNTS("SBClientDownload.SignedOrWhitelistedDownload", 1); |
| 614 } | 614 } |
| 615 | 615 |
| 616 void CheckWhitelists() { | 616 void CheckWhitelists() { |
| 617 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 617 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 618 | 618 |
| 619 if (!database_manager_.get()) { | 619 if (!database_manager_.get()) { |
| 620 PostFinishTask(UNKNOWN, REASON_SB_DISABLED); | 620 PostFinishTask(UNKNOWN, REASON_SB_DISABLED); |
| 621 return; | 621 return; |
| 622 } | 622 } |
| 623 | 623 |
| 624 const GURL& url = url_chain_.back(); | 624 const GURL& url = url_chain_.back(); |
| 625 if (url.is_valid() && database_manager_->MatchDownloadWhitelistUrl(url)) { | 625 if (url.is_valid() && database_manager_->MatchDownloadWhitelistUrl(url)) { |
| 626 DVLOG(2) << url << " is on the download whitelist."; | 626 DVLOG(2) << url << " is on the download whitelist."; |
| 627 RecordCountOfSignedOrWhitelistedDownload(); | 627 RecordCountOfSignedOrWhitelistedDownload(); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 668 BrowserThread::PostTask( | 668 BrowserThread::PostTask( |
| 669 BrowserThread::UI, | 669 BrowserThread::UI, |
| 670 FROM_HERE, | 670 FROM_HERE, |
| 671 base::Bind(&CheckClientDownloadRequest::GetTabRedirects, this)); | 671 base::Bind(&CheckClientDownloadRequest::GetTabRedirects, this)); |
| 672 #else | 672 #else |
| 673 PostFinishTask(UNKNOWN, REASON_OS_NOT_SUPPORTED); | 673 PostFinishTask(UNKNOWN, REASON_OS_NOT_SUPPORTED); |
| 674 #endif | 674 #endif |
| 675 } | 675 } |
| 676 | 676 |
| 677 void GetTabRedirects() { | 677 void GetTabRedirects() { |
| 678 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 678 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 679 if (!service_) | 679 if (!service_) |
| 680 return; | 680 return; |
| 681 | 681 |
| 682 if (!tab_url_.is_valid()) { | 682 if (!tab_url_.is_valid()) { |
| 683 SendRequest(); | 683 SendRequest(); |
| 684 return; | 684 return; |
| 685 } | 685 } |
| 686 | 686 |
| 687 Profile* profile = Profile::FromBrowserContext(item_->GetBrowserContext()); | 687 Profile* profile = Profile::FromBrowserContext(item_->GetBrowserContext()); |
| 688 history::HistoryService* history = HistoryServiceFactory::GetForProfile( | 688 history::HistoryService* history = HistoryServiceFactory::GetForProfile( |
| 689 profile, ServiceAccessType::EXPLICIT_ACCESS); | 689 profile, ServiceAccessType::EXPLICIT_ACCESS); |
| 690 if (!history) { | 690 if (!history) { |
| 691 SendRequest(); | 691 SendRequest(); |
| 692 return; | 692 return; |
| 693 } | 693 } |
| 694 | 694 |
| 695 history->QueryRedirectsTo( | 695 history->QueryRedirectsTo( |
| 696 tab_url_, | 696 tab_url_, |
| 697 base::Bind(&CheckClientDownloadRequest::OnGotTabRedirects, | 697 base::Bind(&CheckClientDownloadRequest::OnGotTabRedirects, |
| 698 base::Unretained(this), | 698 base::Unretained(this), |
| 699 tab_url_), | 699 tab_url_), |
| 700 &request_tracker_); | 700 &request_tracker_); |
| 701 } | 701 } |
| 702 | 702 |
| 703 void OnGotTabRedirects(const GURL& url, | 703 void OnGotTabRedirects(const GURL& url, |
| 704 const history::RedirectList* redirect_list) { | 704 const history::RedirectList* redirect_list) { |
| 705 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 705 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 706 DCHECK_EQ(url, tab_url_); | 706 DCHECK_EQ(url, tab_url_); |
| 707 if (!service_) | 707 if (!service_) |
| 708 return; | 708 return; |
| 709 | 709 |
| 710 if (!redirect_list->empty()) { | 710 if (!redirect_list->empty()) { |
| 711 tab_redirects_.insert( | 711 tab_redirects_.insert( |
| 712 tab_redirects_.end(), redirect_list->rbegin(), redirect_list->rend()); | 712 tab_redirects_.end(), redirect_list->rbegin(), redirect_list->rend()); |
| 713 } | 713 } |
| 714 | 714 |
| 715 SendRequest(); | 715 SendRequest(); |
| 716 } | 716 } |
| 717 | 717 |
| 718 void SendRequest() { | 718 void SendRequest() { |
| 719 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 719 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 720 | 720 |
| 721 // This is our last chance to check whether the request has been canceled | 721 // This is our last chance to check whether the request has been canceled |
| 722 // before sending it. | 722 // before sending it. |
| 723 if (!service_) | 723 if (!service_) |
| 724 return; | 724 return; |
| 725 | 725 |
| 726 ClientDownloadRequest request; | 726 ClientDownloadRequest request; |
| 727 request.set_url(SanitizeUrl(item_->GetUrlChain().back())); | 727 request.set_url(SanitizeUrl(item_->GetUrlChain().back())); |
| 728 request.mutable_digests()->set_sha256(item_->GetHash()); | 728 request.mutable_digests()->set_sha256(item_->GetHash()); |
| 729 request.set_length(item_->GetReceivedBytes()); | 729 request.set_length(item_->GetReceivedBytes()); |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 800 DownloadCheckResultReason reason) { | 800 DownloadCheckResultReason reason) { |
| 801 BrowserThread::PostTask( | 801 BrowserThread::PostTask( |
| 802 BrowserThread::UI, | 802 BrowserThread::UI, |
| 803 FROM_HERE, | 803 FROM_HERE, |
| 804 base::Bind(&CheckClientDownloadRequest::FinishRequest, this, result, | 804 base::Bind(&CheckClientDownloadRequest::FinishRequest, this, result, |
| 805 reason)); | 805 reason)); |
| 806 } | 806 } |
| 807 | 807 |
| 808 void FinishRequest(DownloadCheckResult result, | 808 void FinishRequest(DownloadCheckResult result, |
| 809 DownloadCheckResultReason reason) { | 809 DownloadCheckResultReason reason) { |
| 810 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 810 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 811 if (finished_) { | 811 if (finished_) { |
| 812 return; | 812 return; |
| 813 } | 813 } |
| 814 finished_ = true; | 814 finished_ = true; |
| 815 // Ensure the timeout task is cancelled while we still have a non-zero | 815 // Ensure the timeout task is cancelled while we still have a non-zero |
| 816 // refcount. (crbug.com/240449) | 816 // refcount. (crbug.com/240449) |
| 817 weakptr_factory_.InvalidateWeakPtrs(); | 817 weakptr_factory_.InvalidateWeakPtrs(); |
| 818 if (!request_start_time_.is_null()) { | 818 if (!request_start_time_.is_null()) { |
| 819 UMA_HISTOGRAM_ENUMERATION("SBClientDownload.DownloadRequestNetworkStats", | 819 UMA_HISTOGRAM_ENUMERATION("SBClientDownload.DownloadRequestNetworkStats", |
| 820 reason, | 820 reason, |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 860 service->RequestFinished(this); | 860 service->RequestFinished(this); |
| 861 // DownloadProtectionService::RequestFinished will decrement our refcount, | 861 // DownloadProtectionService::RequestFinished will decrement our refcount, |
| 862 // so we may be deleted now. | 862 // so we may be deleted now. |
| 863 } else { | 863 } else { |
| 864 callback_.Run(UNKNOWN); | 864 callback_.Run(UNKNOWN); |
| 865 } | 865 } |
| 866 } | 866 } |
| 867 | 867 |
| 868 bool CertificateChainIsWhitelisted( | 868 bool CertificateChainIsWhitelisted( |
| 869 const ClientDownloadRequest_CertificateChain& chain) { | 869 const ClientDownloadRequest_CertificateChain& chain) { |
| 870 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 870 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 871 if (chain.element_size() < 2) { | 871 if (chain.element_size() < 2) { |
| 872 // We need to have both a signing certificate and its issuer certificate | 872 // We need to have both a signing certificate and its issuer certificate |
| 873 // present to construct a whitelist entry. | 873 // present to construct a whitelist entry. |
| 874 return false; | 874 return false; |
| 875 } | 875 } |
| 876 scoped_refptr<net::X509Certificate> cert = | 876 scoped_refptr<net::X509Certificate> cert = |
| 877 net::X509Certificate::CreateFromBytes( | 877 net::X509Certificate::CreateFromBytes( |
| 878 chain.element(0).certificate().data(), | 878 chain.element(0).certificate().data(), |
| 879 chain.element(0).certificate().size()); | 879 chain.element(0).certificate().size()); |
| 880 if (!cert.get()) { | 880 if (!cert.get()) { |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 954 feedback_service_(new DownloadFeedbackService( | 954 feedback_service_(new DownloadFeedbackService( |
| 955 request_context_getter, BrowserThread::GetBlockingPool())) { | 955 request_context_getter, BrowserThread::GetBlockingPool())) { |
| 956 | 956 |
| 957 if (sb_service) { | 957 if (sb_service) { |
| 958 ui_manager_ = sb_service->ui_manager(); | 958 ui_manager_ = sb_service->ui_manager(); |
| 959 database_manager_ = sb_service->database_manager(); | 959 database_manager_ = sb_service->database_manager(); |
| 960 } | 960 } |
| 961 } | 961 } |
| 962 | 962 |
| 963 DownloadProtectionService::~DownloadProtectionService() { | 963 DownloadProtectionService::~DownloadProtectionService() { |
| 964 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 964 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 965 CancelPendingRequests(); | 965 CancelPendingRequests(); |
| 966 } | 966 } |
| 967 | 967 |
| 968 void DownloadProtectionService::SetEnabled(bool enabled) { | 968 void DownloadProtectionService::SetEnabled(bool enabled) { |
| 969 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 969 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 970 if (enabled == enabled_) { | 970 if (enabled == enabled_) { |
| 971 return; | 971 return; |
| 972 } | 972 } |
| 973 enabled_ = enabled; | 973 enabled_ = enabled; |
| 974 if (!enabled_) { | 974 if (!enabled_) { |
| 975 CancelPendingRequests(); | 975 CancelPendingRequests(); |
| 976 } | 976 } |
| 977 } | 977 } |
| 978 | 978 |
| 979 void DownloadProtectionService::CheckClientDownload( | 979 void DownloadProtectionService::CheckClientDownload( |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1015 item, target_path, &reason, &type) && | 1015 item, target_path, &reason, &type) && |
| 1016 (ClientDownloadRequest::CHROME_EXTENSION != type)); | 1016 (ClientDownloadRequest::CHROME_EXTENSION != type)); |
| 1017 #else | 1017 #else |
| 1018 return false; | 1018 return false; |
| 1019 #endif | 1019 #endif |
| 1020 } | 1020 } |
| 1021 | 1021 |
| 1022 DownloadProtectionService::ClientDownloadRequestSubscription | 1022 DownloadProtectionService::ClientDownloadRequestSubscription |
| 1023 DownloadProtectionService::RegisterClientDownloadRequestCallback( | 1023 DownloadProtectionService::RegisterClientDownloadRequestCallback( |
| 1024 const ClientDownloadRequestCallback& callback) { | 1024 const ClientDownloadRequestCallback& callback) { |
| 1025 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 1025 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 1026 return client_download_request_callbacks_.Add(callback); | 1026 return client_download_request_callbacks_.Add(callback); |
| 1027 } | 1027 } |
| 1028 | 1028 |
| 1029 void DownloadProtectionService::CancelPendingRequests() { | 1029 void DownloadProtectionService::CancelPendingRequests() { |
| 1030 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 1030 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 1031 for (std::set<scoped_refptr<CheckClientDownloadRequest> >::iterator it = | 1031 for (std::set<scoped_refptr<CheckClientDownloadRequest> >::iterator it = |
| 1032 download_requests_.begin(); | 1032 download_requests_.begin(); |
| 1033 it != download_requests_.end();) { | 1033 it != download_requests_.end();) { |
| 1034 // We need to advance the iterator before we cancel because canceling | 1034 // We need to advance the iterator before we cancel because canceling |
| 1035 // the request will invalidate it when RequestFinished is called below. | 1035 // the request will invalidate it when RequestFinished is called below. |
| 1036 scoped_refptr<CheckClientDownloadRequest> tmp = *it++; | 1036 scoped_refptr<CheckClientDownloadRequest> tmp = *it++; |
| 1037 tmp->Cancel(); | 1037 tmp->Cancel(); |
| 1038 } | 1038 } |
| 1039 DCHECK(download_requests_.empty()); | 1039 DCHECK(download_requests_.empty()); |
| 1040 } | 1040 } |
| 1041 | 1041 |
| 1042 void DownloadProtectionService::RequestFinished( | 1042 void DownloadProtectionService::RequestFinished( |
| 1043 CheckClientDownloadRequest* request) { | 1043 CheckClientDownloadRequest* request) { |
| 1044 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 1044 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 1045 std::set<scoped_refptr<CheckClientDownloadRequest> >::iterator it = | 1045 std::set<scoped_refptr<CheckClientDownloadRequest> >::iterator it = |
| 1046 download_requests_.find(request); | 1046 download_requests_.find(request); |
| 1047 DCHECK(it != download_requests_.end()); | 1047 DCHECK(it != download_requests_.end()); |
| 1048 download_requests_.erase(*it); | 1048 download_requests_.erase(*it); |
| 1049 } | 1049 } |
| 1050 | 1050 |
| 1051 void DownloadProtectionService::ShowDetailsForDownload( | 1051 void DownloadProtectionService::ShowDetailsForDownload( |
| 1052 const content::DownloadItem& item, | 1052 const content::DownloadItem& item, |
| 1053 content::PageNavigator* navigator) { | 1053 content::PageNavigator* navigator) { |
| 1054 GURL learn_more_url(chrome::kDownloadScanningLearnMoreURL); | 1054 GURL learn_more_url(chrome::kDownloadScanningLearnMoreURL); |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1141 GURL DownloadProtectionService::GetDownloadRequestUrl() { | 1141 GURL DownloadProtectionService::GetDownloadRequestUrl() { |
| 1142 GURL url(kDownloadRequestUrl); | 1142 GURL url(kDownloadRequestUrl); |
| 1143 std::string api_key = google_apis::GetAPIKey(); | 1143 std::string api_key = google_apis::GetAPIKey(); |
| 1144 if (!api_key.empty()) | 1144 if (!api_key.empty()) |
| 1145 url = url.Resolve("?key=" + net::EscapeQueryParamValue(api_key, true)); | 1145 url = url.Resolve("?key=" + net::EscapeQueryParamValue(api_key, true)); |
| 1146 | 1146 |
| 1147 return url; | 1147 return url; |
| 1148 } | 1148 } |
| 1149 | 1149 |
| 1150 } // namespace safe_browsing | 1150 } // namespace safe_browsing |
| OLD | NEW |