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 |