| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 "components/safe_browsing_db/v4_get_hash_protocol_manager.h" | 5 #include "components/safe_browsing_db/v4_get_hash_protocol_manager.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "base/base64.h" | 9 #include "base/base64.h" |
| 10 #include "base/macros.h" | 10 #include "base/macros.h" |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 109 | 109 |
| 110 V4GetHashProtocolManager::V4GetHashProtocolManager( | 110 V4GetHashProtocolManager::V4GetHashProtocolManager( |
| 111 net::URLRequestContextGetter* request_context_getter, | 111 net::URLRequestContextGetter* request_context_getter, |
| 112 const V4ProtocolConfig& config) | 112 const V4ProtocolConfig& config) |
| 113 : gethash_error_count_(0), | 113 : gethash_error_count_(0), |
| 114 gethash_back_off_mult_(1), | 114 gethash_back_off_mult_(1), |
| 115 next_gethash_time_(Time::FromDoubleT(0)), | 115 next_gethash_time_(Time::FromDoubleT(0)), |
| 116 config_(config), | 116 config_(config), |
| 117 request_context_getter_(request_context_getter), | 117 request_context_getter_(request_context_getter), |
| 118 url_fetcher_id_(0), | 118 url_fetcher_id_(0), |
| 119 clock_(new base::DefaultClock()) { | 119 clock_(new base::DefaultClock()) {} |
| 120 } | |
| 121 | 120 |
| 122 V4GetHashProtocolManager::~V4GetHashProtocolManager() { | 121 V4GetHashProtocolManager::~V4GetHashProtocolManager() { |
| 123 // Delete in-progress SafeBrowsing requests. | 122 // Delete in-progress SafeBrowsing requests. |
| 124 STLDeleteContainerPairFirstPointers(hash_requests_.begin(), | 123 STLDeleteContainerPairFirstPointers(hash_requests_.begin(), |
| 125 hash_requests_.end()); | 124 hash_requests_.end()); |
| 126 hash_requests_.clear(); | 125 hash_requests_.clear(); |
| 127 } | 126 } |
| 128 | 127 |
| 129 // static | 128 // static |
| 130 void V4GetHashProtocolManager::RegisterFactory( | 129 void V4GetHashProtocolManager::RegisterFactory( |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 167 FindFullHashesResponse response; | 166 FindFullHashesResponse response; |
| 168 | 167 |
| 169 if (!response.ParseFromString(data)) { | 168 if (!response.ParseFromString(data)) { |
| 170 RecordParseGetHashResult(PARSE_FROM_STRING_ERROR); | 169 RecordParseGetHashResult(PARSE_FROM_STRING_ERROR); |
| 171 return false; | 170 return false; |
| 172 } | 171 } |
| 173 | 172 |
| 174 // negative_cache_duration should always be set. | 173 // negative_cache_duration should always be set. |
| 175 DCHECK(response.has_negative_cache_duration()); | 174 DCHECK(response.has_negative_cache_duration()); |
| 176 // Seconds resolution is good enough so we ignore the nanos field. | 175 // Seconds resolution is good enough so we ignore the nanos field. |
| 177 *negative_cache_expire = clock_->Now() + base::TimeDelta::FromSeconds( | 176 *negative_cache_expire = |
| 178 response.negative_cache_duration().seconds()); | 177 clock_->Now() + base::TimeDelta::FromSeconds( |
| 178 response.negative_cache_duration().seconds()); |
| 179 | 179 |
| 180 if (response.has_minimum_wait_duration()) { | 180 if (response.has_minimum_wait_duration()) { |
| 181 // Seconds resolution is good enough so we ignore the nanos field. | 181 // Seconds resolution is good enough so we ignore the nanos field. |
| 182 next_gethash_time_ = | 182 next_gethash_time_ = |
| 183 clock_->Now() + base::TimeDelta::FromSeconds( | 183 clock_->Now() + base::TimeDelta::FromSeconds( |
| 184 response.minimum_wait_duration().seconds()); | 184 response.minimum_wait_duration().seconds()); |
| 185 } | 185 } |
| 186 | 186 |
| 187 // We only expect one threat type per request, so we make sure | 187 // We only expect one threat type per request, so we make sure |
| 188 // the threat types are consistent between matches. | 188 // the threat types are consistent between matches. |
| 189 ThreatType expected_threat_type = THREAT_TYPE_UNSPECIFIED; | 189 ThreatType expected_threat_type = THREAT_TYPE_UNSPECIFIED; |
| 190 | 190 |
| 191 // Loop over the threat matches and fill in full_hashes. | 191 // Loop over the threat matches and fill in full_hashes. |
| 192 for (const ThreatMatch& match : response.matches()) { | 192 for (const ThreatMatch& match : response.matches()) { |
| 193 // Make sure the platform and threat entry type match. | 193 // Make sure the platform and threat entry type match. |
| 194 if (!(match.has_threat_entry_type() && | 194 if (!(match.has_threat_entry_type() && match.threat_entry_type() == URL && |
| 195 match.threat_entry_type() == URL && match.has_threat())) { | 195 match.has_threat())) { |
| 196 RecordParseGetHashResult(UNEXPECTED_THREAT_ENTRY_TYPE_ERROR); | 196 RecordParseGetHashResult(UNEXPECTED_THREAT_ENTRY_TYPE_ERROR); |
| 197 return false; | 197 return false; |
| 198 } | 198 } |
| 199 | 199 |
| 200 if (!match.has_threat_type()) { | 200 if (!match.has_threat_type()) { |
| 201 RecordParseGetHashResult(UNEXPECTED_THREAT_TYPE_ERROR); | 201 RecordParseGetHashResult(UNEXPECTED_THREAT_TYPE_ERROR); |
| 202 return false; | 202 return false; |
| 203 } | 203 } |
| 204 | 204 |
| 205 if (expected_threat_type == THREAT_TYPE_UNSPECIFIED) { | 205 if (expected_threat_type == THREAT_TYPE_UNSPECIFIED) { |
| 206 expected_threat_type = match.threat_type(); | 206 expected_threat_type = match.threat_type(); |
| 207 } else if (match.threat_type() != expected_threat_type) { | 207 } else if (match.threat_type() != expected_threat_type) { |
| 208 RecordParseGetHashResult(INCONSISTENT_THREAT_TYPE_ERROR); | 208 RecordParseGetHashResult(INCONSISTENT_THREAT_TYPE_ERROR); |
| 209 return false; | 209 return false; |
| 210 } | 210 } |
| 211 | 211 |
| 212 // Fill in the full hash. | 212 // Fill in the full hash. |
| 213 SBFullHashResult result; | 213 SBFullHashResult result; |
| 214 result.hash = StringToSBFullHash(match.threat().hash()); | 214 result.hash = StringToSBFullHash(match.threat().hash()); |
| 215 | 215 |
| 216 if (match.has_cache_duration()) { | 216 if (match.has_cache_duration()) { |
| 217 // Seconds resolution is good enough so we ignore the nanos field. | 217 // Seconds resolution is good enough so we ignore the nanos field. |
| 218 result.cache_expire_after = clock_->Now() + | 218 result.cache_expire_after = |
| 219 clock_->Now() + |
| 219 base::TimeDelta::FromSeconds(match.cache_duration().seconds()); | 220 base::TimeDelta::FromSeconds(match.cache_duration().seconds()); |
| 220 } else { | 221 } else { |
| 221 result.cache_expire_after = clock_->Now(); | 222 result.cache_expire_after = clock_->Now(); |
| 222 } | 223 } |
| 223 | 224 |
| 224 // Different threat types will handle the metadata differently. | 225 // Different threat types will handle the metadata differently. |
| 225 if (match.threat_type() == API_ABUSE) { | 226 if (match.threat_type() == API_ABUSE) { |
| 226 if (match.has_platform_type() && | 227 if (match.has_platform_type() && |
| 227 match.platform_type() == CHROME_PLATFORM) { | 228 match.platform_type() == CHROME_PLATFORM) { |
| 228 if (match.has_threat_entry_metadata()) { | 229 if (match.has_threat_entry_metadata()) { |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 311 RecordGetHashResult(V4OperationResult::BACKOFF_ERROR); | 312 RecordGetHashResult(V4OperationResult::BACKOFF_ERROR); |
| 312 } else { | 313 } else { |
| 313 RecordGetHashResult(V4OperationResult::MIN_WAIT_DURATION_ERROR); | 314 RecordGetHashResult(V4OperationResult::MIN_WAIT_DURATION_ERROR); |
| 314 } | 315 } |
| 315 std::vector<SBFullHashResult> full_hashes; | 316 std::vector<SBFullHashResult> full_hashes; |
| 316 callback.Run(full_hashes, base::Time()); | 317 callback.Run(full_hashes, base::Time()); |
| 317 return; | 318 return; |
| 318 } | 319 } |
| 319 | 320 |
| 320 std::string req_base64 = GetHashRequest(prefixes, platforms, threat_type); | 321 std::string req_base64 = GetHashRequest(prefixes, platforms, threat_type); |
| 321 GURL gethash_url = GetHashUrl(req_base64); | 322 GURL gethash_url; |
| 323 net::HttpRequestHeaders headers; |
| 324 GetHashUrlAndHeaders(req_base64, &gethash_url, &headers); |
| 322 | 325 |
| 323 net::URLFetcher* fetcher = | 326 net::URLFetcher* fetcher = |
| 324 net::URLFetcher::Create(url_fetcher_id_++, gethash_url, | 327 net::URLFetcher::Create(url_fetcher_id_++, gethash_url, |
| 325 net::URLFetcher::GET, this) | 328 net::URLFetcher::GET, this) |
| 326 .release(); | 329 .release(); |
| 330 fetcher->SetExtraRequestHeaders(headers.ToString()); |
| 327 hash_requests_[fetcher] = callback; | 331 hash_requests_[fetcher] = callback; |
| 328 | 332 |
| 329 fetcher->SetLoadFlags(net::LOAD_DISABLE_CACHE); | 333 fetcher->SetLoadFlags(net::LOAD_DISABLE_CACHE); |
| 330 fetcher->SetRequestContext(request_context_getter_.get()); | 334 fetcher->SetRequestContext(request_context_getter_.get()); |
| 331 fetcher->Start(); | 335 fetcher->Start(); |
| 332 } | 336 } |
| 333 | 337 |
| 334 void V4GetHashProtocolManager::GetFullHashesWithApis( | 338 void V4GetHashProtocolManager::GetFullHashesWithApis( |
| 335 const std::vector<SBPrefix>& prefixes, | 339 const std::vector<SBPrefix>& prefixes, |
| 336 FullHashCallback callback) { | 340 FullHashCallback callback) { |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 396 hash_requests_.erase(it); | 400 hash_requests_.erase(it); |
| 397 } | 401 } |
| 398 | 402 |
| 399 void V4GetHashProtocolManager::HandleGetHashError(const Time& now) { | 403 void V4GetHashProtocolManager::HandleGetHashError(const Time& now) { |
| 400 DCHECK(CalledOnValidThread()); | 404 DCHECK(CalledOnValidThread()); |
| 401 base::TimeDelta next = V4ProtocolManagerUtil::GetNextBackOffInterval( | 405 base::TimeDelta next = V4ProtocolManagerUtil::GetNextBackOffInterval( |
| 402 &gethash_error_count_, &gethash_back_off_mult_); | 406 &gethash_error_count_, &gethash_back_off_mult_); |
| 403 next_gethash_time_ = now + next; | 407 next_gethash_time_ = now + next; |
| 404 } | 408 } |
| 405 | 409 |
| 406 GURL V4GetHashProtocolManager::GetHashUrl(const std::string& req_base64) const { | 410 void V4GetHashProtocolManager::GetHashUrlAndHeaders( |
| 407 return V4ProtocolManagerUtil::GetRequestUrl(req_base64, "encodedFullHashes", | 411 const std::string& req_base64, |
| 408 config_); | 412 GURL* gurl, |
| 413 net::HttpRequestHeaders* headers) const { |
| 414 V4ProtocolManagerUtil::GetRequestUrlAndHeaders(req_base64, "fullHashes:find", |
| 415 config_, gurl, headers); |
| 409 } | 416 } |
| 410 | 417 |
| 411 | |
| 412 } // namespace safe_browsing | 418 } // namespace safe_browsing |
| OLD | NEW |