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/protocol_manager.h" | 5 #include "chrome/browser/safe_browsing/protocol_manager.h" |
6 | 6 |
7 #include <utility> | 7 #include <utility> |
8 | 8 |
| 9 #include "base/base64.h" |
9 #include "base/environment.h" | 10 #include "base/environment.h" |
10 #include "base/logging.h" | 11 #include "base/logging.h" |
11 #include "base/macros.h" | 12 #include "base/macros.h" |
12 #include "base/metrics/histogram_macros.h" | 13 #include "base/metrics/histogram_macros.h" |
13 #include "base/metrics/sparse_histogram.h" | 14 #include "base/metrics/sparse_histogram.h" |
14 #include "base/profiler/scoped_tracker.h" | 15 #include "base/profiler/scoped_tracker.h" |
15 #include "base/rand_util.h" | 16 #include "base/rand_util.h" |
16 #include "base/stl_util.h" | 17 #include "base/stl_util.h" |
17 #include "base/strings/string_number_conversions.h" | 18 #include "base/strings/string_number_conversions.h" |
18 #include "base/strings/string_util.h" | 19 #include "base/strings/string_util.h" |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
85 static const int kSbTimerStartIntervalSecMax = 300; | 86 static const int kSbTimerStartIntervalSecMax = 300; |
86 | 87 |
87 // The maximum time, in seconds, to wait for a response to an update request. | 88 // The maximum time, in seconds, to wait for a response to an update request. |
88 static const int kSbMaxUpdateWaitSec = 30; | 89 static const int kSbMaxUpdateWaitSec = 30; |
89 | 90 |
90 // Maximum back off multiplier. | 91 // Maximum back off multiplier. |
91 static const size_t kSbMaxBackOff = 8; | 92 static const size_t kSbMaxBackOff = 8; |
92 | 93 |
93 const char kUmaHashResponseMetricName[] = "SB2.GetHashResponseOrErrorCode"; | 94 const char kUmaHashResponseMetricName[] = "SB2.GetHashResponseOrErrorCode"; |
94 | 95 |
| 96 // The V4 URL prefix where browser fetches hashes from the V4 server. |
| 97 const char kSbV4UrlPrefix[] = "https://safebrowsing.googleapis.com/v4"; |
| 98 |
95 // The default SBProtocolManagerFactory. | 99 // The default SBProtocolManagerFactory. |
96 class SBProtocolManagerFactoryImpl : public SBProtocolManagerFactory { | 100 class SBProtocolManagerFactoryImpl : public SBProtocolManagerFactory { |
97 public: | 101 public: |
98 SBProtocolManagerFactoryImpl() {} | 102 SBProtocolManagerFactoryImpl() {} |
99 ~SBProtocolManagerFactoryImpl() override {} | 103 ~SBProtocolManagerFactoryImpl() override {} |
100 SafeBrowsingProtocolManager* CreateProtocolManager( | 104 SafeBrowsingProtocolManager* CreateProtocolManager( |
101 SafeBrowsingProtocolManagerDelegate* delegate, | 105 SafeBrowsingProtocolManagerDelegate* delegate, |
102 net::URLRequestContextGetter* request_context_getter, | 106 net::URLRequestContextGetter* request_context_getter, |
103 const SafeBrowsingProtocolConfig& config) override { | 107 const SafeBrowsingProtocolConfig& config) override { |
104 return new SafeBrowsingProtocolManager(delegate, request_context_getter, | 108 return new SafeBrowsingProtocolManager(delegate, request_context_getter, |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
189 | 193 |
190 bool SafeBrowsingProtocolManager::IsUpdateScheduled() const { | 194 bool SafeBrowsingProtocolManager::IsUpdateScheduled() const { |
191 return update_timer_.IsRunning(); | 195 return update_timer_.IsRunning(); |
192 } | 196 } |
193 | 197 |
194 SafeBrowsingProtocolManager::~SafeBrowsingProtocolManager() { | 198 SafeBrowsingProtocolManager::~SafeBrowsingProtocolManager() { |
195 // Delete in-progress SafeBrowsing requests. | 199 // Delete in-progress SafeBrowsing requests. |
196 STLDeleteContainerPairFirstPointers(hash_requests_.begin(), | 200 STLDeleteContainerPairFirstPointers(hash_requests_.begin(), |
197 hash_requests_.end()); | 201 hash_requests_.end()); |
198 hash_requests_.clear(); | 202 hash_requests_.clear(); |
| 203 |
| 204 STLDeleteContainerPairFirstPointers(v4_hash_requests_.begin(), |
| 205 v4_hash_requests_.end()); |
| 206 v4_hash_requests_.clear(); |
199 } | 207 } |
200 | 208 |
201 // We can only have one update or chunk request outstanding, but there may be | 209 // We can only have one update or chunk request outstanding, but there may be |
202 // multiple GetHash requests pending since we don't want to serialize them and | 210 // multiple GetHash requests pending since we don't want to serialize them and |
203 // slow down the user. | 211 // slow down the user. |
204 void SafeBrowsingProtocolManager::GetFullHash( | 212 void SafeBrowsingProtocolManager::GetFullHash( |
205 const std::vector<SBPrefix>& prefixes, | 213 const std::vector<SBPrefix>& prefixes, |
206 FullHashCallback callback, | 214 FullHashCallback callback, |
207 bool is_download, | 215 bool is_download, |
208 bool is_extended_reporting) { | 216 bool is_extended_reporting) { |
(...skipping 15 matching lines...) Expand all Loading... |
224 hash_requests_[fetcher] = FullHashDetails(callback, is_download); | 232 hash_requests_[fetcher] = FullHashDetails(callback, is_download); |
225 | 233 |
226 const std::string get_hash = FormatGetHash(prefixes); | 234 const std::string get_hash = FormatGetHash(prefixes); |
227 | 235 |
228 fetcher->SetLoadFlags(net::LOAD_DISABLE_CACHE); | 236 fetcher->SetLoadFlags(net::LOAD_DISABLE_CACHE); |
229 fetcher->SetRequestContext(request_context_getter_.get()); | 237 fetcher->SetRequestContext(request_context_getter_.get()); |
230 fetcher->SetUploadData("text/plain", get_hash); | 238 fetcher->SetUploadData("text/plain", get_hash); |
231 fetcher->Start(); | 239 fetcher->Start(); |
232 } | 240 } |
233 | 241 |
| 242 std::string SafeBrowsingProtocolManager::GetV4HashRequest( |
| 243 const std::vector<SBPrefix>& prefixes, |
| 244 ThreatType threat_type) { |
| 245 // Build the request. Client info and client states are not added to the |
| 246 // request protocol buffer. Client info is passed as params in the url. |
| 247 FindFullHashesRequest req; |
| 248 ThreatInfo* info = req.mutable_threat_info(); |
| 249 info->add_threat_types(threat_type); |
| 250 info->add_platform_types(CHROME_PLATFORM); |
| 251 info->add_threat_entry_types(URL_EXPRESSION); |
| 252 for (const SBPrefix& prefix : prefixes) { |
| 253 std::string hash(reinterpret_cast<const char*>(&prefix), sizeof(SBPrefix)); |
| 254 info->add_threat_entries()->set_hash(hash); |
| 255 } |
| 256 |
| 257 // Serialize and Base64 encode. |
| 258 std::string req_data, req_base64; |
| 259 req.SerializeToString(&req_data); |
| 260 base::Base64Encode(req_data, &req_base64); |
| 261 |
| 262 return req_base64; |
| 263 } |
| 264 |
| 265 void SafeBrowsingProtocolManager::GetV4FullHashes( |
| 266 const std::vector<SBPrefix>& prefixes, |
| 267 ThreatType threat_type, |
| 268 FullHashCallback callback) { |
| 269 DCHECK(CalledOnValidThread()); |
| 270 // TODO(kcarattini): Implement backoff behavior. |
| 271 |
| 272 std::string req_base64 = GetV4HashRequest(prefixes, threat_type); |
| 273 GURL gethash_url = GetV4HashUrl(req_base64); |
| 274 |
| 275 net::URLFetcher* fetcher = |
| 276 net::URLFetcher::Create(url_fetcher_id_++, gethash_url, |
| 277 net::URLFetcher::GET, this) |
| 278 .release(); |
| 279 // TODO(kcarattini): Implement a new response processor. |
| 280 v4_hash_requests_[fetcher] = FullHashDetails(callback, |
| 281 false /* is_download */); |
| 282 |
| 283 fetcher->SetLoadFlags(net::LOAD_DISABLE_CACHE); |
| 284 fetcher->SetRequestContext(request_context_getter_.get()); |
| 285 fetcher->Start(); |
| 286 } |
| 287 |
| 288 void SafeBrowsingProtocolManager::GetFullHashesWithApis( |
| 289 const std::vector<SBPrefix>& prefixes, |
| 290 FullHashCallback callback) { |
| 291 GetV4FullHashes(prefixes, API_ABUSE, callback); |
| 292 } |
| 293 |
234 void SafeBrowsingProtocolManager::GetNextUpdate() { | 294 void SafeBrowsingProtocolManager::GetNextUpdate() { |
235 DCHECK(CalledOnValidThread()); | 295 DCHECK(CalledOnValidThread()); |
236 if (request_.get() || request_type_ != NO_REQUEST) | 296 if (request_.get() || request_type_ != NO_REQUEST) |
237 return; | 297 return; |
238 | 298 |
239 IssueUpdateRequest(); | 299 IssueUpdateRequest(); |
240 } | 300 } |
241 | 301 |
242 // net::URLFetcherDelegate implementation ---------------------------------- | 302 // net::URLFetcherDelegate implementation ---------------------------------- |
243 | 303 |
(...skipping 510 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
754 return GURL(url); | 814 return GURL(url); |
755 } | 815 } |
756 | 816 |
757 GURL SafeBrowsingProtocolManager::GetHashUrl(bool is_extended_reporting) const { | 817 GURL SafeBrowsingProtocolManager::GetHashUrl(bool is_extended_reporting) const { |
758 std::string url = SafeBrowsingProtocolManagerHelper::ComposeUrl( | 818 std::string url = SafeBrowsingProtocolManagerHelper::ComposeUrl( |
759 url_prefix_, "gethash", client_name_, version_, additional_query_, | 819 url_prefix_, "gethash", client_name_, version_, additional_query_, |
760 is_extended_reporting); | 820 is_extended_reporting); |
761 return GURL(url); | 821 return GURL(url); |
762 } | 822 } |
763 | 823 |
| 824 // The API hash call uses the pver4 Safe Browsing server. |
| 825 GURL SafeBrowsingProtocolManager::GetV4HashUrl( |
| 826 const std::string& request_base64) const { |
| 827 std::string url = SafeBrowsingProtocolManagerHelper::ComposePver4Url( |
| 828 kSbV4UrlPrefix, "encodedFullHashes", |
| 829 request_base64, client_name_, version_); |
| 830 return GURL(url); |
| 831 } |
| 832 |
764 GURL SafeBrowsingProtocolManager::NextChunkUrl(const std::string& url) const { | 833 GURL SafeBrowsingProtocolManager::NextChunkUrl(const std::string& url) const { |
765 DCHECK(CalledOnValidThread()); | 834 DCHECK(CalledOnValidThread()); |
766 std::string next_url; | 835 std::string next_url; |
767 if (!base::StartsWith(url, "http://", base::CompareCase::INSENSITIVE_ASCII) && | 836 if (!base::StartsWith(url, "http://", base::CompareCase::INSENSITIVE_ASCII) && |
768 !base::StartsWith(url, "https://", | 837 !base::StartsWith(url, "https://", |
769 base::CompareCase::INSENSITIVE_ASCII)) { | 838 base::CompareCase::INSENSITIVE_ASCII)) { |
770 // Use https if we updated via https, otherwise http (useful for testing). | 839 // Use https if we updated via https, otherwise http (useful for testing). |
771 if (base::StartsWith(url_prefix_, "https://", | 840 if (base::StartsWith(url_prefix_, "https://", |
772 base::CompareCase::INSENSITIVE_ASCII)) | 841 base::CompareCase::INSENSITIVE_ASCII)) |
773 next_url.append("https://"); | 842 next_url.append("https://"); |
(...skipping 20 matching lines...) Expand all Loading... |
794 SafeBrowsingProtocolManager::FullHashDetails::FullHashDetails( | 863 SafeBrowsingProtocolManager::FullHashDetails::FullHashDetails( |
795 FullHashCallback callback, | 864 FullHashCallback callback, |
796 bool is_download) | 865 bool is_download) |
797 : callback(callback), is_download(is_download) {} | 866 : callback(callback), is_download(is_download) {} |
798 | 867 |
799 SafeBrowsingProtocolManager::FullHashDetails::~FullHashDetails() {} | 868 SafeBrowsingProtocolManager::FullHashDetails::~FullHashDetails() {} |
800 | 869 |
801 SafeBrowsingProtocolManagerDelegate::~SafeBrowsingProtocolManagerDelegate() {} | 870 SafeBrowsingProtocolManagerDelegate::~SafeBrowsingProtocolManagerDelegate() {} |
802 | 871 |
803 } // namespace safe_browsing | 872 } // namespace safe_browsing |
OLD | NEW |