OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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/protocol_manager.h" | 5 #include "chrome/browser/safe_browsing/protocol_manager.h" |
6 | 6 |
7 #ifndef NDEBUG | 7 #ifndef NDEBUG |
8 #include "base/base64.h" | 8 #include "base/base64.h" |
9 #endif | 9 #endif |
10 #include "base/environment.h" | 10 #include "base/environment.h" |
(...skipping 29 matching lines...) Expand all Loading... |
40 | 40 |
41 | 41 |
42 // SafeBrowsingProtocolManager implementation ---------------------------------- | 42 // SafeBrowsingProtocolManager implementation ---------------------------------- |
43 | 43 |
44 SafeBrowsingProtocolManager::SafeBrowsingProtocolManager( | 44 SafeBrowsingProtocolManager::SafeBrowsingProtocolManager( |
45 SafeBrowsingService* sb_service, | 45 SafeBrowsingService* sb_service, |
46 const std::string& client_name, | 46 const std::string& client_name, |
47 const std::string& client_key, | 47 const std::string& client_key, |
48 const std::string& wrapped_key, | 48 const std::string& wrapped_key, |
49 URLRequestContextGetter* request_context_getter, | 49 URLRequestContextGetter* request_context_getter, |
50 const std::string& info_url_prefix, | 50 const std::string& http_url_prefix, |
51 const std::string& mackey_url_prefix, | 51 const std::string& https_url_prefix, |
52 bool disable_auto_update) | 52 bool disable_auto_update) |
53 : sb_service_(sb_service), | 53 : sb_service_(sb_service), |
54 request_type_(NO_REQUEST), | 54 request_type_(NO_REQUEST), |
55 update_error_count_(0), | 55 update_error_count_(0), |
56 gethash_error_count_(0), | 56 gethash_error_count_(0), |
57 update_back_off_mult_(1), | 57 update_back_off_mult_(1), |
58 gethash_back_off_mult_(1), | 58 gethash_back_off_mult_(1), |
59 next_update_sec_(-1), | 59 next_update_sec_(-1), |
60 update_state_(FIRST_REQUEST), | 60 update_state_(FIRST_REQUEST), |
61 initial_request_(true), | 61 initial_request_(true), |
62 chunk_pending_to_write_(false), | 62 chunk_pending_to_write_(false), |
63 client_key_(client_key), | 63 client_key_(client_key), |
64 wrapped_key_(wrapped_key), | 64 wrapped_key_(wrapped_key), |
65 update_size_(0), | 65 update_size_(0), |
66 client_name_(client_name), | 66 client_name_(client_name), |
67 request_context_getter_(request_context_getter), | 67 request_context_getter_(request_context_getter), |
68 info_url_prefix_(info_url_prefix), | 68 http_url_prefix_(http_url_prefix), |
69 mackey_url_prefix_(mackey_url_prefix), | 69 https_url_prefix_(https_url_prefix), |
70 disable_auto_update_(disable_auto_update) { | 70 disable_auto_update_(disable_auto_update) { |
71 DCHECK(!info_url_prefix_.empty() && !mackey_url_prefix_.empty()); | 71 DCHECK(!http_url_prefix_.empty() && !https_url_prefix_.empty()); |
72 | 72 |
73 // Set the backoff multiplier fuzz to a random value between 0 and 1. | 73 // Set the backoff multiplier fuzz to a random value between 0 and 1. |
74 back_off_fuzz_ = static_cast<float>(base::RandDouble()); | 74 back_off_fuzz_ = static_cast<float>(base::RandDouble()); |
75 // The first update must happen between 1-5 minutes of start up. | 75 // The first update must happen between 1-5 minutes of start up. |
76 next_update_sec_ = base::RandInt(60, kSbTimerStartIntervalSec); | 76 next_update_sec_ = base::RandInt(60, kSbTimerStartIntervalSec); |
77 | 77 |
78 chrome::VersionInfo version_info; | 78 chrome::VersionInfo version_info; |
79 if (!version_info.is_valid() || version_info.Version().empty()) | 79 if (!version_info.is_valid() || version_info.Version().empty()) |
80 version_ = "0.1"; | 80 version_ = "0.1"; |
81 else | 81 else |
82 version_ = version_info.Version(); | 82 version_ = version_info.Version(); |
83 } | 83 } |
84 | 84 |
85 SafeBrowsingProtocolManager::~SafeBrowsingProtocolManager() { | 85 SafeBrowsingProtocolManager::~SafeBrowsingProtocolManager() { |
86 // Delete in-progress SafeBrowsing requests. | 86 // Delete in-progress SafeBrowsing requests. |
87 STLDeleteContainerPairFirstPointers(hash_requests_.begin(), | 87 STLDeleteContainerPairFirstPointers(hash_requests_.begin(), |
88 hash_requests_.end()); | 88 hash_requests_.end()); |
89 hash_requests_.clear(); | 89 hash_requests_.clear(); |
90 | 90 |
91 // Delete in-progress safebrowsing reports. | 91 // Delete in-progress safebrowsing reports (hits and details). |
92 STLDeleteContainerPointers(safebrowsing_reports_.begin(), | 92 STLDeleteContainerPointers(safebrowsing_reports_.begin(), |
93 safebrowsing_reports_.end()); | 93 safebrowsing_reports_.end()); |
94 safebrowsing_reports_.clear(); | 94 safebrowsing_reports_.clear(); |
95 } | 95 } |
96 | 96 |
97 // Public API used by the SafeBrowsingService ---------------------------------- | 97 // Public API used by the SafeBrowsingService ---------------------------------- |
98 | 98 |
99 // We can only have one update or chunk request outstanding, but there may be | 99 // We can only have one update or chunk request outstanding, but there may be |
100 // multiple GetHash requests pending since we don't want to serialize them and | 100 // multiple GetHash requests pending since we don't want to serialize them and |
101 // slow down the user. | 101 // slow down the user. |
(...skipping 479 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
581 chunk_pending_to_write_ = false; | 581 chunk_pending_to_write_ = false; |
582 | 582 |
583 if (chunk_request_urls_.empty()) { | 583 if (chunk_request_urls_.empty()) { |
584 UMA_HISTOGRAM_LONG_TIMES("SB2.Update", Time::Now() - last_update_); | 584 UMA_HISTOGRAM_LONG_TIMES("SB2.Update", Time::Now() - last_update_); |
585 UpdateFinished(true); | 585 UpdateFinished(true); |
586 } else { | 586 } else { |
587 IssueChunkRequest(); | 587 IssueChunkRequest(); |
588 } | 588 } |
589 } | 589 } |
590 | 590 |
| 591 // Sends a SafeBrowsing "hit" for UMA users. |
591 void SafeBrowsingProtocolManager::ReportSafeBrowsingHit( | 592 void SafeBrowsingProtocolManager::ReportSafeBrowsingHit( |
592 const GURL& malicious_url, | 593 const GURL& malicious_url, |
593 const GURL& page_url, | 594 const GURL& page_url, |
594 const GURL& referrer_url, | 595 const GURL& referrer_url, |
595 bool is_subresource, | 596 bool is_subresource, |
596 SafeBrowsingService::UrlCheckResult threat_type) { | 597 SafeBrowsingService::UrlCheckResult threat_type) { |
597 GURL report_url = SafeBrowsingReportUrl(malicious_url, page_url, | 598 GURL report_url = SafeBrowsingHitUrl(malicious_url, page_url, |
598 referrer_url, is_subresource, | 599 referrer_url, is_subresource, |
599 threat_type); | 600 threat_type); |
600 URLFetcher* report = new URLFetcher(report_url, URLFetcher::GET, this); | 601 URLFetcher* report = new URLFetcher(report_url, URLFetcher::GET, this); |
601 report->set_load_flags(net::LOAD_DISABLE_CACHE); | 602 report->set_load_flags(net::LOAD_DISABLE_CACHE); |
602 report->set_request_context(request_context_getter_); | 603 report->set_request_context(request_context_getter_); |
603 report->Start(); | 604 report->Start(); |
604 safebrowsing_reports_.insert(report); | 605 safebrowsing_reports_.insert(report); |
605 } | 606 } |
606 | 607 |
| 608 // Sends malware details for users who opt-in. |
| 609 void SafeBrowsingProtocolManager::ReportMalwareDetails( |
| 610 const std::string& report) { |
| 611 GURL report_url = MalwareDetailsUrl(); |
| 612 URLFetcher* fetcher = new URLFetcher(report_url, URLFetcher::POST, this); |
| 613 fetcher->set_load_flags(net::LOAD_DISABLE_CACHE); |
| 614 fetcher->set_request_context(request_context_getter_); |
| 615 fetcher->set_upload_data("application/octet-stream", report); |
| 616 // Don't try too hard to send reports on failures. |
| 617 fetcher->set_automatically_retry_on_5xx(false); |
| 618 fetcher->Start(); |
| 619 safebrowsing_reports_.insert(fetcher); |
| 620 } |
| 621 |
| 622 |
607 // static | 623 // static |
608 std::string SafeBrowsingProtocolManager::FormatList( | 624 std::string SafeBrowsingProtocolManager::FormatList( |
609 const SBListChunkRanges& list, bool use_mac) { | 625 const SBListChunkRanges& list, bool use_mac) { |
610 std::string formatted_results; | 626 std::string formatted_results; |
611 formatted_results.append(list.name); | 627 formatted_results.append(list.name); |
612 formatted_results.append(";"); | 628 formatted_results.append(";"); |
613 if (!list.adds.empty()) { | 629 if (!list.adds.empty()) { |
614 formatted_results.append("a:" + list.adds); | 630 formatted_results.append("a:" + list.adds); |
615 if (!list.subs.empty() || use_mac) | 631 if (!list.subs.empty() || use_mac) |
616 formatted_results.append(":"); | 632 formatted_results.append(":"); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
655 client_name.c_str(), version.c_str()); | 671 client_name.c_str(), version.c_str()); |
656 if (!additional_query.empty()) { | 672 if (!additional_query.empty()) { |
657 DCHECK(url.find("?") != std::string::npos); | 673 DCHECK(url.find("?") != std::string::npos); |
658 url.append("&"); | 674 url.append("&"); |
659 url.append(additional_query); | 675 url.append(additional_query); |
660 } | 676 } |
661 return url; | 677 return url; |
662 } | 678 } |
663 | 679 |
664 GURL SafeBrowsingProtocolManager::UpdateUrl(bool use_mac) const { | 680 GURL SafeBrowsingProtocolManager::UpdateUrl(bool use_mac) const { |
665 std::string url = ComposeUrl(info_url_prefix_, "downloads", client_name_, | 681 std::string url = ComposeUrl(http_url_prefix_, "downloads", client_name_, |
666 version_, additional_query_); | 682 version_, additional_query_); |
667 if (use_mac) { | 683 if (use_mac) { |
668 url.append("&wrkey="); | 684 url.append("&wrkey="); |
669 url.append(wrapped_key_); | 685 url.append(wrapped_key_); |
670 } | 686 } |
671 return GURL(url); | 687 return GURL(url); |
672 } | 688 } |
673 | 689 |
674 GURL SafeBrowsingProtocolManager::GetHashUrl(bool use_mac) const { | 690 GURL SafeBrowsingProtocolManager::GetHashUrl(bool use_mac) const { |
675 std::string url= ComposeUrl(info_url_prefix_, "gethash", client_name_, | 691 std::string url= ComposeUrl(http_url_prefix_, "gethash", client_name_, |
676 version_, additional_query_); | 692 version_, additional_query_); |
677 if (use_mac) { | 693 if (use_mac) { |
678 url.append("&wrkey="); | 694 url.append("&wrkey="); |
679 url.append(wrapped_key_); | 695 url.append(wrapped_key_); |
680 } | 696 } |
681 return GURL(url); | 697 return GURL(url); |
682 } | 698 } |
683 | 699 |
684 GURL SafeBrowsingProtocolManager::MacKeyUrl() const { | 700 GURL SafeBrowsingProtocolManager::MacKeyUrl() const { |
685 return GURL(ComposeUrl(mackey_url_prefix_, "newkey", client_name_, version_, | 701 return GURL(ComposeUrl(https_url_prefix_, "newkey", client_name_, version_, |
686 additional_query_)); | 702 additional_query_)); |
687 } | 703 } |
688 | 704 |
689 GURL SafeBrowsingProtocolManager::SafeBrowsingReportUrl( | 705 GURL SafeBrowsingProtocolManager::SafeBrowsingHitUrl( |
690 const GURL& malicious_url, const GURL& page_url, | 706 const GURL& malicious_url, const GURL& page_url, |
691 const GURL& referrer_url, bool is_subresource, | 707 const GURL& referrer_url, bool is_subresource, |
692 SafeBrowsingService::UrlCheckResult threat_type) const { | 708 SafeBrowsingService::UrlCheckResult threat_type) const { |
693 DCHECK(threat_type == SafeBrowsingService::URL_MALWARE || | 709 DCHECK(threat_type == SafeBrowsingService::URL_MALWARE || |
694 threat_type == SafeBrowsingService::URL_PHISHING); | 710 threat_type == SafeBrowsingService::URL_PHISHING); |
695 std::string url = ComposeUrl(info_url_prefix_, "report", client_name_, | 711 // The malware and phishing hits go over HTTP. |
| 712 std::string url = ComposeUrl(http_url_prefix_, "report", client_name_, |
696 version_, additional_query_); | 713 version_, additional_query_); |
697 return GURL(StringPrintf("%s&evts=%s&evtd=%s&evtr=%s&evhr=%s&evtb=%d", | 714 return GURL(StringPrintf("%s&evts=%s&evtd=%s&evtr=%s&evhr=%s&evtb=%d", |
698 url.c_str(), | 715 url.c_str(), |
699 (threat_type == SafeBrowsingService::URL_MALWARE) ? | 716 (threat_type == SafeBrowsingService::URL_MALWARE) ? |
700 "malblhit" : "phishblhit", | 717 "malblhit" : "phishblhit", |
701 EscapeQueryParamValue(malicious_url.spec(), true).c_str(), | 718 EscapeQueryParamValue(malicious_url.spec(), true).c_str(), |
702 EscapeQueryParamValue(page_url.spec(), true).c_str(), | 719 EscapeQueryParamValue(page_url.spec(), true).c_str(), |
703 EscapeQueryParamValue(referrer_url.spec(), true).c_str(), | 720 EscapeQueryParamValue(referrer_url.spec(), true).c_str(), |
704 is_subresource)); | 721 is_subresource)); |
705 } | 722 } |
706 | 723 |
| 724 GURL SafeBrowsingProtocolManager::MalwareDetailsUrl() const { |
| 725 // The malware details go over HTTPS. |
| 726 std::string url = StringPrintf( |
| 727 "%s/clientreport/malware?client=%s&appver=%s&pver=1.0", |
| 728 https_url_prefix_.c_str(), |
| 729 client_name_.c_str(), |
| 730 version_.c_str()); |
| 731 return GURL(url); |
| 732 } |
| 733 |
707 GURL SafeBrowsingProtocolManager::NextChunkUrl(const std::string& url) const { | 734 GURL SafeBrowsingProtocolManager::NextChunkUrl(const std::string& url) const { |
708 std::string next_url; | 735 std::string next_url; |
709 if (!StartsWithASCII(url, "http://", false) && | 736 if (!StartsWithASCII(url, "http://", false) && |
710 !StartsWithASCII(url, "https://", false)) { | 737 !StartsWithASCII(url, "https://", false)) { |
711 next_url.append("http://"); | 738 next_url.append("http://"); |
712 next_url.append(url); | 739 next_url.append(url); |
713 } else { | 740 } else { |
714 next_url = url; | 741 next_url = url; |
715 } | 742 } |
716 if (!additional_query_.empty()) { | 743 if (!additional_query_.empty()) { |
717 if (next_url.find("?") != std::string::npos) { | 744 if (next_url.find("?") != std::string::npos) { |
718 next_url.append("&"); | 745 next_url.append("&"); |
719 } else { | 746 } else { |
720 next_url.append("?"); | 747 next_url.append("?"); |
721 } | 748 } |
722 next_url.append(additional_query_); | 749 next_url.append(additional_query_); |
723 } | 750 } |
724 return GURL(next_url); | 751 return GURL(next_url); |
725 } | 752 } |
OLD | NEW |