| 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/base64.h" |
| 10 #include "base/environment.h" | 10 #include "base/environment.h" |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 68 base::TimeDelta GetNextUpdateIntervalFromFinch() { | 68 base::TimeDelta GetNextUpdateIntervalFromFinch() { |
| 69 std::string num_str = variations::GetVariationParamValue( | 69 std::string num_str = variations::GetVariationParamValue( |
| 70 kSBUpdateFrequencyFinchExperiment, kSBUpdateFrequencyFinchParam); | 70 kSBUpdateFrequencyFinchExperiment, kSBUpdateFrequencyFinchParam); |
| 71 int finch_next_update_interval_minutes = 0; | 71 int finch_next_update_interval_minutes = 0; |
| 72 if (!base::StringToInt(num_str, &finch_next_update_interval_minutes)) { | 72 if (!base::StringToInt(num_str, &finch_next_update_interval_minutes)) { |
| 73 finch_next_update_interval_minutes = 0; // Defaults to 0. | 73 finch_next_update_interval_minutes = 0; // Defaults to 0. |
| 74 } | 74 } |
| 75 return base::TimeDelta::FromMinutes(finch_next_update_interval_minutes); | 75 return base::TimeDelta::FromMinutes(finch_next_update_interval_minutes); |
| 76 } | 76 } |
| 77 | 77 |
| 78 // Enumerate V4 parsing failures for histogramming purposes. DO NOT CHANGE |
| 79 // THE ORDERING OF THESE VALUES. |
| 80 enum ParseResultType { |
| 81 // Error parsing the protocol buffer from a string. |
| 82 PARSE_FROM_STRING_ERROR = 0, |
| 83 |
| 84 // A match in the response had an unexpected THREAT_ENTRY_TYPE. |
| 85 UNEXPECTED_THREAT_ENTRY_TYPE_ERROR = 1, |
| 86 |
| 87 // A match in the response had an unexpected THREAT_TYPE. |
| 88 UNEXPECTED_THREAT_TYPE_ERROR = 2, |
| 89 |
| 90 // A match in the response had an unexpected PLATFORM_TYPE. |
| 91 UNEXPECTED_PLATFORM_TYPE_ERROR = 3, |
| 92 |
| 93 // A match in teh response contained no metadata where metadata was |
| 94 // expected. |
| 95 NO_METADATA_ERROR = 4, |
| 96 |
| 97 // Memory space for histograms is determined by the max. ALWAYS |
| 98 // ADD NEW VALUES BEFORE THIS ONE. |
| 99 PARSE_GET_HASH_RESULT_MAX = 5 |
| 100 }; |
| 101 |
| 102 // Record parsing errors of a GetHash result. |
| 103 void RecordParseGetHashResult(ParseResultType result_type) { |
| 104 UMA_HISTOGRAM_ENUMERATION("SafeBrowsing.ParseV4HashResult", result_type, |
| 105 PARSE_GET_HASH_RESULT_MAX); |
| 106 } |
| 107 |
| 78 } // namespace | 108 } // namespace |
| 79 | 109 |
| 80 namespace safe_browsing { | 110 namespace safe_browsing { |
| 81 | 111 |
| 82 // Minimum time, in seconds, from start up before we must issue an update query. | 112 // Minimum time, in seconds, from start up before we must issue an update query. |
| 83 static const int kSbTimerStartIntervalSecMin = 60; | 113 static const int kSbTimerStartIntervalSecMin = 60; |
| 84 | 114 |
| 85 // Maximum time, in seconds, from start up before we must issue an update query. | 115 // Maximum time, in seconds, from start up before we must issue an update query. |
| 86 static const int kSbTimerStartIntervalSecMax = 300; | 116 static const int kSbTimerStartIntervalSecMax = 300; |
| 87 | 117 |
| (...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 307 return req_base64; | 337 return req_base64; |
| 308 } | 338 } |
| 309 | 339 |
| 310 bool SafeBrowsingProtocolManager::ParseV4HashResponse( | 340 bool SafeBrowsingProtocolManager::ParseV4HashResponse( |
| 311 const std::string& data, | 341 const std::string& data, |
| 312 std::vector<SBFullHashResult>* full_hashes, | 342 std::vector<SBFullHashResult>* full_hashes, |
| 313 base::TimeDelta* negative_cache_duration) { | 343 base::TimeDelta* negative_cache_duration) { |
| 314 FindFullHashesResponse response; | 344 FindFullHashesResponse response; |
| 315 | 345 |
| 316 if (!response.ParseFromString(data)) { | 346 if (!response.ParseFromString(data)) { |
| 317 // TODO(kcarattini): Add UMA. | 347 RecordParseGetHashResult(PARSE_FROM_STRING_ERROR); |
| 318 return false; | 348 return false; |
| 319 } | 349 } |
| 320 | 350 |
| 321 if (response.has_negative_cache_duration()) { | 351 if (response.has_negative_cache_duration()) { |
| 322 // Seconds resolution is good enough so we ignore the nanos field. | 352 // Seconds resolution is good enough so we ignore the nanos field. |
| 323 *negative_cache_duration = base::TimeDelta::FromSeconds( | 353 *negative_cache_duration = base::TimeDelta::FromSeconds( |
| 324 response.negative_cache_duration().seconds()); | 354 response.negative_cache_duration().seconds()); |
| 325 } | 355 } |
| 326 | 356 |
| 327 if (response.has_minimum_wait_duration()) { | 357 if (response.has_minimum_wait_duration()) { |
| 328 // Seconds resolution is good enough so we ignore the nanos field. | 358 // Seconds resolution is good enough so we ignore the nanos field. |
| 329 next_gethash_v4_time_ = Time::Now() + base::TimeDelta::FromSeconds( | 359 next_gethash_v4_time_ = Time::Now() + base::TimeDelta::FromSeconds( |
| 330 response.minimum_wait_duration().seconds()); | 360 response.minimum_wait_duration().seconds()); |
| 331 } | 361 } |
| 332 | 362 |
| 333 // Loop over the threat matches and fill in full_hashes. | 363 // Loop over the threat matches and fill in full_hashes. |
| 334 for (const ThreatMatch& match : response.matches()) { | 364 for (const ThreatMatch& match : response.matches()) { |
| 335 // Make sure the platform and threat entry type match. | 365 // Make sure the platform and threat entry type match. |
| 336 if (!(match.has_threat_entry_type() && | 366 if (!(match.has_threat_entry_type() && |
| 337 match.threat_entry_type() == URL_EXPRESSION && | 367 match.threat_entry_type() == URL_EXPRESSION && |
| 338 match.has_threat())) { | 368 match.has_threat())) { |
| 339 continue; | 369 RecordParseGetHashResult(UNEXPECTED_THREAT_ENTRY_TYPE_ERROR); |
| 370 return false; |
| 340 } | 371 } |
| 341 | 372 |
| 342 // Fill in the full hash. | 373 // Fill in the full hash. |
| 343 SBFullHashResult result; | 374 SBFullHashResult result; |
| 344 result.hash = StringToSBFullHash(match.threat().hash()); | 375 result.hash = StringToSBFullHash(match.threat().hash()); |
| 345 | 376 |
| 346 if (match.has_cache_duration()) { | 377 if (match.has_cache_duration()) { |
| 347 // Seconds resolution is good enough so we ignore the nanos field. | 378 // Seconds resolution is good enough so we ignore the nanos field. |
| 348 result.cache_duration = base::TimeDelta::FromSeconds( | 379 result.cache_duration = base::TimeDelta::FromSeconds( |
| 349 match.cache_duration().seconds()); | 380 match.cache_duration().seconds()); |
| 350 } | 381 } |
| 351 | 382 |
| 352 // Different threat types will handle the metadata differently. | 383 // Different threat types will handle the metadata differently. |
| 353 if (match.has_threat_type() && match.threat_type() == API_ABUSE && | 384 if (match.has_threat_type() && match.threat_type() == API_ABUSE) { |
| 354 match.has_platform_type() && | 385 if (match.has_platform_type() && |
| 355 match.platform_type() == CHROME_PLATFORM && | 386 match.platform_type() == CHROME_PLATFORM) { |
| 356 match.has_threat_entry_metadata()) { | 387 if (match.has_threat_entry_metadata()) { |
| 357 // For API Abuse, store a csv of the returned permissions. | 388 // For API Abuse, store a csv of the returned permissions. |
| 358 for (const ThreatEntryMetadata::MetadataEntry& m : | 389 for (const ThreatEntryMetadata::MetadataEntry& m : |
| 359 match.threat_entry_metadata().entries()) { | 390 match.threat_entry_metadata().entries()) { |
| 360 if (m.key() == "permission") { | 391 if (m.key() == "permission") { |
| 361 result.metadata += m.value() + ","; | 392 result.metadata += m.value() + ","; |
| 393 } |
| 394 } |
| 395 } else { |
| 396 RecordParseGetHashResult(NO_METADATA_ERROR); |
| 397 return false; |
| 362 } | 398 } |
| 399 } else { |
| 400 RecordParseGetHashResult(UNEXPECTED_PLATFORM_TYPE_ERROR); |
| 401 return false; |
| 363 } | 402 } |
| 364 } else { | 403 } else { |
| 365 // TODO(kcarattini): Add UMA for unexpected threat type match. | 404 RecordParseGetHashResult(UNEXPECTED_THREAT_TYPE_ERROR); |
| 366 return false; | 405 return false; |
| 367 } | 406 } |
| 368 | 407 |
| 369 full_hashes->push_back(result); | 408 full_hashes->push_back(result); |
| 370 } | 409 } |
| 371 return true; | 410 return true; |
| 372 } | 411 } |
| 373 | 412 |
| 374 void SafeBrowsingProtocolManager::GetV4FullHashes( | 413 void SafeBrowsingProtocolManager::GetV4FullHashes( |
| 375 const std::vector<SBPrefix>& prefixes, | 414 const std::vector<SBPrefix>& prefixes, |
| (...skipping 658 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1034 SafeBrowsingProtocolManager::FullHashDetails::FullHashDetails( | 1073 SafeBrowsingProtocolManager::FullHashDetails::FullHashDetails( |
| 1035 FullHashCallback callback, | 1074 FullHashCallback callback, |
| 1036 bool is_download) | 1075 bool is_download) |
| 1037 : callback(callback), is_download(is_download) {} | 1076 : callback(callback), is_download(is_download) {} |
| 1038 | 1077 |
| 1039 SafeBrowsingProtocolManager::FullHashDetails::~FullHashDetails() {} | 1078 SafeBrowsingProtocolManager::FullHashDetails::~FullHashDetails() {} |
| 1040 | 1079 |
| 1041 SafeBrowsingProtocolManagerDelegate::~SafeBrowsingProtocolManagerDelegate() {} | 1080 SafeBrowsingProtocolManagerDelegate::~SafeBrowsingProtocolManagerDelegate() {} |
| 1042 | 1081 |
| 1043 } // namespace safe_browsing | 1082 } // namespace safe_browsing |
| OLD | NEW |