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 |