Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 <vector> | 5 #include <vector> |
| 6 | 6 |
| 7 #include "chrome/browser/ssl/ssl_error_classification.h" | 7 #include "chrome/browser/ssl/ssl_error_classification.h" |
| 8 | 8 |
| 9 #include "base/build_time.h" | 9 #include "base/build_time.h" |
| 10 #include "base/metrics/field_trial.h" | 10 #include "base/metrics/field_trial.h" |
| 11 #include "base/metrics/histogram.h" | 11 #include "base/metrics/histogram.h" |
| 12 #include "base/strings/string_split.h" | 12 #include "base/strings/string_split.h" |
| 13 #include "base/strings/utf_string_conversions.h" | 13 #include "base/strings/utf_string_conversions.h" |
| 14 #include "base/time/time.h" | 14 #include "base/time/time.h" |
| 15 #include "chrome/browser/browser_process.h" | |
| 16 #include "chrome/browser/chrome_notification_types.h" | |
| 17 #include "chrome/browser/profiles/profile.h" | |
| 15 #include "chrome/browser/ssl/ssl_error_info.h" | 18 #include "chrome/browser/ssl/ssl_error_info.h" |
| 19 #include "content/public/browser/notification_service.h" | |
| 20 #include "content/public/browser/web_contents.h" | |
| 16 #include "net/base/net_util.h" | 21 #include "net/base/net_util.h" |
| 17 #include "net/base/registry_controlled_domains/registry_controlled_domain.h" | 22 #include "net/base/registry_controlled_domains/registry_controlled_domain.h" |
| 18 #include "net/cert/x509_cert_types.h" | 23 #include "net/cert/x509_cert_types.h" |
| 19 #include "net/cert/x509_certificate.h" | 24 #include "net/cert/x509_certificate.h" |
| 20 #include "url/gurl.h" | 25 #include "url/gurl.h" |
| 21 | 26 |
| 22 using base::Time; | 27 #if defined(ENABLE_CAPTIVE_PORTAL_DETECTION) |
| 23 using base::TimeTicks; | 28 #include "chrome/browser/captive_portal/captive_portal_service.h" |
| 24 using base::TimeDelta; | 29 #include "chrome/browser/captive_portal/captive_portal_service_factory.h" |
| 30 #endif | |
| 25 | 31 |
| 26 #if defined(OS_WIN) | 32 #if defined(OS_WIN) |
| 27 #include "base/win/windows_version.h" | 33 #include "base/win/windows_version.h" |
| 28 #endif | 34 #endif |
| 29 | 35 |
| 36 using base::Time; | |
| 37 using base::TimeTicks; | |
| 38 using base::TimeDelta; | |
| 39 | |
| 30 namespace { | 40 namespace { |
| 31 | 41 |
| 32 // Events for UMA. Do not reorder or change! | 42 // Events for UMA. Do not reorder or change! |
| 33 enum SSLInterstitialCause { | 43 enum SSLInterstitialCause { |
| 34 CLOCK_PAST, | 44 CLOCK_PAST, |
| 35 CLOCK_FUTURE, | 45 CLOCK_FUTURE, |
| 36 WWW_SUBDOMAIN_MATCH, | 46 WWW_SUBDOMAIN_MATCH, |
| 37 SUBDOMAIN_MATCH, | 47 SUBDOMAIN_MATCH, |
| 38 SUBDOMAIN_INVERSE_MATCH, | 48 SUBDOMAIN_INVERSE_MATCH, |
| 39 SUBDOMAIN_OUTSIDE_WILDCARD, | 49 SUBDOMAIN_OUTSIDE_WILDCARD, |
| 40 HOST_NAME_NOT_KNOWN_TLD, | 50 HOST_NAME_NOT_KNOWN_TLD, |
| 41 LIKELY_MULTI_TENANT_HOSTING, | 51 LIKELY_MULTI_TENANT_HOSTING, |
| 42 UNUSED_INTERSTITIAL_CAUSE_ENTRY, | 52 UNUSED_INTERSTITIAL_CAUSE_ENTRY, |
| 43 }; | 53 }; |
| 44 | 54 |
| 45 // Scores/weights which will be constant through all the SSL error types. | 55 // Events for UMA. Do not reorder or change! |
| 46 static const float kServerWeight = 0.5f; | 56 enum SSLInterstitialCauseCaptivePortal { |
| 47 static const float kClientWeight = 0.5f; | 57 CAPTIVE_PORTAL_DETECTION_ENABLED, |
| 58 CAPTIVE_PORTAL_DETECTION_ENABLED_OVERRIDABLE, | |
| 59 CAPTIVE_PORTAL_PROBE_COMPLETED, | |
| 60 CAPTIVE_PORTAL_PROBE_COMPLETED_OVERRIDABLE, | |
| 61 CAPTIVE_PORTAL_NO_RESPONSE, | |
| 62 CAPTIVE_PORTAL_NO_RESPONSE_OVERRIDABLE, | |
| 63 CAPTIVE_PORTAL_DETECTED, | |
| 64 CAPTIVE_PORTAL_DETECTED_OVERRIDABLE, | |
| 65 UNUSED_CAPTIVE_PORTAL_EVENT, | |
| 66 }; | |
| 67 | |
| 68 void RecordSSLInterstitialSeverityScore(float ssl_severity_score, | |
| 69 int cert_error) { | |
| 70 if (SSLErrorInfo::NetErrorToErrorType(cert_error) == | |
| 71 SSLErrorInfo::CERT_DATE_INVALID) { | |
| 72 UMA_HISTOGRAM_CUSTOM_COUNTS("interstitial.ssl.severity_score.date_invalid", | |
| 73 static_cast<int>(ssl_severity_score * 100), | |
| 74 0, 100, 20); | |
|
felt
2014/08/15 15:11:04
is "20" the number of buckets? what kind of granul
radhikabhar
2014/08/15 18:28:28
That's right 20 is the number of bucket counts. We
felt
2014/08/15 19:06:19
my understanding is that it's logarithmic or some
radhikabhar
2014/08/15 20:28:57
I don't think so it is logarathmic
palmer
2014/09/09 00:13:51
It looks like there is a standard macro for counts
| |
| 75 } | |
| 76 if (SSLErrorInfo::NetErrorToErrorType(cert_error) == | |
| 77 SSLErrorInfo::CERT_COMMON_NAME_INVALID) { | |
| 78 UMA_HISTOGRAM_CUSTOM_COUNTS( | |
| 79 "interstitial.ssl.severity_score.common_name_invalid", | |
| 80 static_cast<int>(ssl_severity_score * 100), | |
| 81 0, 100, 20); | |
| 82 } | |
| 83 | |
| 84 } | |
| 48 | 85 |
| 49 void RecordSSLInterstitialCause(bool overridable, SSLInterstitialCause event) { | 86 void RecordSSLInterstitialCause(bool overridable, SSLInterstitialCause event) { |
| 50 if (overridable) { | 87 if (overridable) { |
| 51 UMA_HISTOGRAM_ENUMERATION("interstitial.ssl.cause.overridable", event, | 88 UMA_HISTOGRAM_ENUMERATION("interstitial.ssl.cause.overridable", event, |
| 52 UNUSED_INTERSTITIAL_CAUSE_ENTRY); | 89 UNUSED_INTERSTITIAL_CAUSE_ENTRY); |
| 53 } else { | 90 } else { |
| 54 UMA_HISTOGRAM_ENUMERATION("interstitial.ssl.cause.nonoverridable", event, | 91 UMA_HISTOGRAM_ENUMERATION("interstitial.ssl.cause.nonoverridable", event, |
| 55 UNUSED_INTERSTITIAL_CAUSE_ENTRY); | 92 UNUSED_INTERSTITIAL_CAUSE_ENTRY); |
| 56 } | 93 } |
| 57 } | 94 } |
| 58 | 95 |
| 96 void RecordCaptivePortalEventStats(SSLInterstitialCauseCaptivePortal event) { | |
| 97 UMA_HISTOGRAM_ENUMERATION("interstitial.ssl.captive_portal", | |
| 98 event, | |
| 99 UNUSED_CAPTIVE_PORTAL_EVENT); | |
| 100 } | |
| 101 | |
| 102 // Scores/weights which will be constant through all the SSL error types. | |
| 103 static const float kServerWeight = 0.5f; | |
| 104 static const float kClientWeight = 0.5f; | |
| 105 | |
| 59 int GetLevensteinDistance(const std::string& str1, | 106 int GetLevensteinDistance(const std::string& str1, |
| 60 const std::string& str2) { | 107 const std::string& str2) { |
| 61 if (str1 == str2) | 108 if (str1 == str2) |
| 62 return 0; | 109 return 0; |
| 63 if (str1.size() == 0) | 110 if (str1.size() == 0) |
| 64 return str2.size(); | 111 return str2.size(); |
| 65 if (str2.size() == 0) | 112 if (str2.size() == 0) |
| 66 return str1.size(); | 113 return str1.size(); |
| 67 std::vector<int> kFirstRow(str2.size() + 1, 0); | 114 std::vector<int> kFirstRow(str2.size() + 1, 0); |
| 68 std::vector<int> kSecondRow(str2.size() + 1, 0); | 115 std::vector<int> kSecondRow(str2.size() + 1, 0); |
| 69 | 116 |
| 70 for (size_t i = 0; i < kFirstRow.size(); ++i) | 117 for (size_t i = 0; i < kFirstRow.size(); ++i) |
| 71 kFirstRow[i] = i; | 118 kFirstRow[i] = i; |
| 72 for (size_t i = 0; i < str1.size(); ++i) { | 119 for (size_t i = 0; i < str1.size(); ++i) { |
| 73 kSecondRow[0] = i + 1; | 120 kSecondRow[0] = i + 1; |
| 74 for (size_t j = 0; j < str2.size(); ++j) { | 121 for (size_t j = 0; j < str2.size(); ++j) { |
| 75 int cost = str1[i] == str2[j] ? 0 : 1; | 122 int cost = str1[i] == str2[j] ? 0 : 1; |
| 76 kSecondRow[j+1] = std::min(std::min( | 123 kSecondRow[j+1] = std::min(std::min( |
| 77 kSecondRow[j] + 1, kFirstRow[j + 1] + 1), kFirstRow[j] + cost); | 124 kSecondRow[j] + 1, kFirstRow[j + 1] + 1), kFirstRow[j] + cost); |
| 78 } | 125 } |
| 79 for (size_t j = 0; j < kFirstRow.size(); j++) | 126 for (size_t j = 0; j < kFirstRow.size(); j++) |
| 80 kFirstRow[j] = kSecondRow[j]; | 127 kFirstRow[j] = kSecondRow[j]; |
| 81 } | 128 } |
| 82 return kSecondRow[str2.size()]; | 129 return kSecondRow[str2.size()]; |
| 83 } | 130 } |
| 84 | 131 |
| 85 } // namespace | 132 } // namespace |
| 86 | 133 |
| 87 SSLErrorClassification::SSLErrorClassification( | 134 SSLErrorClassification::SSLErrorClassification( |
| 135 content::WebContents* web_contents, | |
| 88 const base::Time& current_time, | 136 const base::Time& current_time, |
| 89 const GURL& url, | 137 const GURL& url, |
| 138 int cert_error, | |
| 90 const net::X509Certificate& cert) | 139 const net::X509Certificate& cert) |
| 91 : current_time_(current_time), | 140 : web_contents_(web_contents), |
| 141 current_time_(current_time), | |
| 92 request_url_(url), | 142 request_url_(url), |
| 93 cert_(cert) { } | 143 cert_error_(cert_error), |
| 144 cert_(cert), | |
| 145 captive_portal_detection_enabled_(false), | |
| 146 captive_portal_probe_completed_(false), | |
| 147 captive_portal_no_response_(false), | |
| 148 captive_portal_detected_(false) { | |
| 149 #if defined(ENABLE_CAPTIVE_PORTAL_DETECTION) | |
| 150 Profile* profile = Profile::FromBrowserContext( | |
| 151 web_contents_->GetBrowserContext()); | |
| 152 CaptivePortalService* captive_portal_service = | |
| 153 CaptivePortalServiceFactory::GetForProfile(profile); | |
| 154 captive_portal_detection_enabled_ = captive_portal_service->enabled(); | |
| 155 captive_portal_service->DetectCaptivePortal(); | |
| 156 registrar_.Add(this, | |
| 157 chrome::NOTIFICATION_CAPTIVE_PORTAL_CHECK_RESULT, | |
| 158 content::Source<Profile>(profile)); | |
| 159 #endif | |
| 160 } | |
| 94 | 161 |
| 95 SSLErrorClassification::~SSLErrorClassification() { } | 162 SSLErrorClassification::~SSLErrorClassification() { } |
| 96 | 163 |
| 97 float SSLErrorClassification::InvalidDateSeverityScore( | 164 void SSLErrorClassification::RecordCaptivePortalUMAStatistics( |
| 98 int cert_error) const { | 165 bool overridable) const { |
| 166 #if defined(ENABLE_CAPTIVE_PORTAL_DETECTION) | |
| 167 if (captive_portal_detection_enabled_) | |
| 168 RecordCaptivePortalEventStats( | |
| 169 overridable ? | |
| 170 CAPTIVE_PORTAL_DETECTION_ENABLED_OVERRIDABLE : | |
| 171 CAPTIVE_PORTAL_DETECTION_ENABLED); | |
| 172 if (captive_portal_probe_completed_) | |
| 173 RecordCaptivePortalEventStats( | |
| 174 overridable ? | |
| 175 CAPTIVE_PORTAL_PROBE_COMPLETED_OVERRIDABLE : | |
| 176 CAPTIVE_PORTAL_PROBE_COMPLETED); | |
| 177 // Log only one of portal detected and no response results. | |
| 178 if (captive_portal_detected_) | |
| 179 RecordCaptivePortalEventStats( | |
| 180 overridable ? | |
| 181 CAPTIVE_PORTAL_DETECTED_OVERRIDABLE : | |
| 182 CAPTIVE_PORTAL_DETECTED); | |
| 183 else if (captive_portal_no_response_) | |
| 184 RecordCaptivePortalEventStats( | |
| 185 overridable ? | |
| 186 CAPTIVE_PORTAL_NO_RESPONSE_OVERRIDABLE : | |
| 187 CAPTIVE_PORTAL_NO_RESPONSE); | |
| 188 #endif | |
| 189 } | |
| 190 | |
| 191 void SSLErrorClassification::InvalidDateSeverityScore() { | |
| 99 SSLErrorInfo::ErrorType type = | 192 SSLErrorInfo::ErrorType type = |
| 100 SSLErrorInfo::NetErrorToErrorType(cert_error); | 193 SSLErrorInfo::NetErrorToErrorType(cert_error_); |
| 101 DCHECK(type == SSLErrorInfo::CERT_DATE_INVALID); | 194 DCHECK(type == SSLErrorInfo::CERT_DATE_INVALID); |
| 195 | |
| 102 // Client-side characteristics. Check whether or not the system's clock is | 196 // Client-side characteristics. Check whether or not the system's clock is |
| 103 // wrong and whether or not the user has already encountered this error | 197 // wrong and whether or not the user has encountered this error before. |
| 104 // before. | |
| 105 float severity_date_score = 0.0f; | 198 float severity_date_score = 0.0f; |
| 106 | 199 |
| 107 static const float kCertificateExpiredWeight = 0.3f; | 200 static const float kCertificateExpiredWeight = 0.3f; |
| 108 static const float kNotYetValidWeight = 0.2f; | 201 static const float kNotYetValidWeight = 0.2f; |
| 109 | 202 |
| 110 static const float kSystemClockWeight = 0.75f; | 203 static const float kSystemClockWeight = 0.75f; |
| 111 static const float kSystemClockWrongWeight = 0.1f; | 204 static const float kSystemClockWrongWeight = 0.1f; |
| 112 static const float kSystemClockRightWeight = 1.0f; | 205 static const float kSystemClockRightWeight = 1.0f; |
| 113 | 206 |
| 114 if (IsUserClockInThePast(current_time_) || | 207 if (IsUserClockInThePast(current_time_) || |
| 115 IsUserClockInTheFuture(current_time_)) { | 208 IsUserClockInTheFuture(current_time_)) { |
| 116 severity_date_score += kClientWeight * kSystemClockWeight * | 209 severity_date_score += kClientWeight * kSystemClockWeight * |
| 117 kSystemClockWrongWeight; | 210 kSystemClockWrongWeight; |
| 118 } else { | 211 } else { |
| 119 severity_date_score += kClientWeight * kSystemClockWeight * | 212 severity_date_score += kClientWeight * kSystemClockWeight * |
| 120 kSystemClockRightWeight; | 213 kSystemClockRightWeight; |
| 121 } | 214 } |
| 122 // TODO(radhikabhar): (crbug.com/393262) Check website settings. | 215 // TODO(radhikabhar): (crbug.com/393262) Check website settings. |
| 123 | 216 |
| 124 // Server-side characteristics. Check whether the certificate has expired or | 217 // Server-side characteristics. Check whether the certificate has expired or |
| 125 // is not yet valid. If the certificate has expired then factor the time which | 218 // is not yet valid. If the certificate has expired then factor the time which |
| 126 // has passed since expiry. | 219 // has passed since expiry. |
| 127 if (cert_.HasExpired()) { | 220 if (cert_.HasExpired()) { |
| 128 severity_date_score += kServerWeight * kCertificateExpiredWeight * | 221 severity_date_score += kServerWeight * kCertificateExpiredWeight * |
| 129 CalculateScoreTimePassedSinceExpiry(); | 222 CalculateScoreTimePassedSinceExpiry(); |
| 130 } | 223 } |
| 131 if (current_time_ < cert_.valid_start()) | 224 if (current_time_ < cert_.valid_start()) |
| 132 severity_date_score += kServerWeight * kNotYetValidWeight; | 225 severity_date_score += kServerWeight * kNotYetValidWeight; |
| 133 return severity_date_score; | 226 |
| 227 RecordSSLInterstitialSeverityScore(severity_date_score, cert_error_); | |
| 134 } | 228 } |
| 135 | 229 |
| 136 float SSLErrorClassification::InvalidCommonNameSeverityScore( | 230 void SSLErrorClassification::InvalidCommonNameSeverityScore() { |
| 137 int cert_error) const { | |
| 138 SSLErrorInfo::ErrorType type = | 231 SSLErrorInfo::ErrorType type = |
| 139 SSLErrorInfo::NetErrorToErrorType(cert_error); | 232 SSLErrorInfo::NetErrorToErrorType(cert_error_); |
| 140 DCHECK(type == SSLErrorInfo::CERT_COMMON_NAME_INVALID); | 233 DCHECK(type == SSLErrorInfo::CERT_COMMON_NAME_INVALID); |
| 141 float severity_name_score = 0.0f; | 234 float severity_name_score = 0.0f; |
| 142 | 235 |
| 143 static const float kWWWDifferenceWeight = 0.3f; | 236 static const float kWWWDifferenceWeight = 0.3f; |
| 144 static const float kNameUnderAnyNamesWeight = 0.2f; | 237 static const float kNameUnderAnyNamesWeight = 0.2f; |
| 145 static const float kAnyNamesUnderNameWeight = 1.0f; | 238 static const float kAnyNamesUnderNameWeight = 1.0f; |
| 146 static const float kLikelyMultiTenantHostingWeight = 0.1f; | 239 static const float kLikelyMultiTenantHostingWeight = 0.1f; |
| 147 | 240 |
| 148 std::string host_name = request_url_.host(); | 241 std::string host_name = request_url_.host(); |
| 149 if (IsHostNameKnownTLD(host_name)) { | 242 if (IsHostNameKnownTLD(host_name)) { |
| 150 Tokens host_name_tokens = Tokenize(host_name); | 243 Tokens host_name_tokens = Tokenize(host_name); |
| 151 if (IsWWWSubDomainMatch()) | 244 if (IsWWWSubDomainMatch()) |
| 152 severity_name_score += kServerWeight * kWWWDifferenceWeight; | 245 severity_name_score += kServerWeight * kWWWDifferenceWeight; |
| 153 if (IsSubDomainOutsideWildcard(host_name_tokens)) | 246 if (IsSubDomainOutsideWildcard(host_name_tokens)) |
| 154 severity_name_score += kServerWeight * kWWWDifferenceWeight; | 247 severity_name_score += kServerWeight * kWWWDifferenceWeight; |
| 155 | 248 |
| 156 std::vector<std::string> dns_names; | 249 std::vector<std::string> dns_names; |
| 157 cert_.GetDNSNames(&dns_names); | 250 cert_.GetDNSNames(&dns_names); |
| 158 std::vector<Tokens> dns_name_tokens = GetTokenizedDNSNames(dns_names); | 251 std::vector<Tokens> dns_name_tokens = GetTokenizedDNSNames(dns_names); |
| 159 if (NameUnderAnyNames(host_name_tokens, dns_name_tokens)) | 252 if (NameUnderAnyNames(host_name_tokens, dns_name_tokens)) |
| 160 severity_name_score += kServerWeight * kNameUnderAnyNamesWeight; | 253 severity_name_score += kServerWeight * kNameUnderAnyNamesWeight; |
| 161 // Inverse case is more likely to be a MITM attack. | 254 // Inverse case is more likely to be a MITM attack. |
| 162 if (AnyNamesUnderName(dns_name_tokens, host_name_tokens)) | 255 if (AnyNamesUnderName(dns_name_tokens, host_name_tokens)) |
| 163 severity_name_score += kServerWeight * kAnyNamesUnderNameWeight; | 256 severity_name_score += kServerWeight * kAnyNamesUnderNameWeight; |
| 164 if (IsCertLikelyFromMultiTenantHosting()) | 257 if (IsCertLikelyFromMultiTenantHosting()) |
| 165 severity_name_score += kServerWeight * kLikelyMultiTenantHostingWeight; | 258 severity_name_score += kServerWeight * kLikelyMultiTenantHostingWeight; |
| 166 } | 259 } |
| 167 return severity_name_score; | 260 |
| 261 static const float kEnvironmentWeight = 0.25f; | |
| 262 | |
| 263 severity_name_score += kClientWeight * kEnvironmentWeight * | |
| 264 CalculateScoreEnvironments(); | |
| 265 | |
| 266 RecordSSLInterstitialSeverityScore(severity_name_score, cert_error_); | |
| 168 } | 267 } |
| 169 | 268 |
| 170 void SSLErrorClassification::RecordUMAStatistics(bool overridable, | 269 void SSLErrorClassification::RecordUMAStatistics( |
| 171 int cert_error) { | 270 bool overridable) const { |
| 172 SSLErrorInfo::ErrorType type = | 271 SSLErrorInfo::ErrorType type = |
| 173 SSLErrorInfo::NetErrorToErrorType(cert_error); | 272 SSLErrorInfo::NetErrorToErrorType(cert_error_); |
| 174 switch (type) { | 273 switch (type) { |
| 175 case SSLErrorInfo::CERT_DATE_INVALID: { | 274 case SSLErrorInfo::CERT_DATE_INVALID: { |
| 176 if (IsUserClockInThePast(base::Time::NowFromSystemTime())) | 275 if (IsUserClockInThePast(base::Time::NowFromSystemTime())) |
| 177 RecordSSLInterstitialCause(overridable, CLOCK_PAST); | 276 RecordSSLInterstitialCause(overridable, CLOCK_PAST); |
| 178 if (IsUserClockInTheFuture(base::Time::NowFromSystemTime())) | 277 if (IsUserClockInTheFuture(base::Time::NowFromSystemTime())) |
| 179 RecordSSLInterstitialCause(overridable, CLOCK_FUTURE); | 278 RecordSSLInterstitialCause(overridable, CLOCK_FUTURE); |
| 180 break; | 279 break; |
| 181 } | 280 } |
| 182 case SSLErrorInfo::CERT_COMMON_NAME_INVALID: { | 281 case SSLErrorInfo::CERT_COMMON_NAME_INVALID: { |
| 183 std::string host_name = request_url_.host(); | 282 std::string host_name = request_url_.host(); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 221 static const float kMediumThresholdWeight = 0.3f; | 320 static const float kMediumThresholdWeight = 0.3f; |
| 222 static const float kLowThresholdWeight = 0.2f; | 321 static const float kLowThresholdWeight = 0.2f; |
| 223 if (time_passed >= kHighThreshold) | 322 if (time_passed >= kHighThreshold) |
| 224 return kHighThresholdWeight; | 323 return kHighThresholdWeight; |
| 225 else if (time_passed >= kLowThreshold) | 324 else if (time_passed >= kLowThreshold) |
| 226 return kMediumThresholdWeight; | 325 return kMediumThresholdWeight; |
| 227 else | 326 else |
| 228 return kLowThresholdWeight; | 327 return kLowThresholdWeight; |
| 229 } | 328 } |
| 230 | 329 |
| 330 float SSLErrorClassification::CalculateScoreEnvironments() const { | |
| 331 static const float kWifiWeight = 0.7f; | |
| 332 static const float kCellularWeight = 0.7f; | |
| 333 static const float kHotspotWeight = 0.2f; | |
| 334 static const float kEthernetWeight = 0.7f; | |
| 335 static const float kOtherWeight = 0.7f; | |
| 336 net::NetworkChangeNotifier::ConnectionType type = | |
| 337 net::NetworkChangeNotifier::GetConnectionType(); | |
| 338 if (type == net::NetworkChangeNotifier::CONNECTION_WIFI) | |
| 339 return kWifiWeight; | |
| 340 if (type == net::NetworkChangeNotifier::CONNECTION_2G || | |
| 341 type == net::NetworkChangeNotifier::CONNECTION_3G || | |
| 342 type == net::NetworkChangeNotifier::CONNECTION_4G ) { | |
| 343 return kCellularWeight; | |
| 344 } | |
| 345 if (type == net::NetworkChangeNotifier::CONNECTION_ETHERNET) | |
| 346 return kEthernetWeight; | |
| 347 #if defined(ENABLE_CAPTIVE_PORTAL_DETECTION) | |
| 348 // Assume if captive portals are detected then the user is connected using a | |
| 349 // hot spot. | |
| 350 if (captive_portal_probe_completed_ && captive_portal_detected_) | |
| 351 return kHotspotWeight; | |
| 352 #endif | |
| 353 return kOtherWeight; | |
| 354 } | |
| 355 | |
| 231 bool SSLErrorClassification::IsUserClockInThePast(const base::Time& time_now) { | 356 bool SSLErrorClassification::IsUserClockInThePast(const base::Time& time_now) { |
| 232 base::Time build_time = base::GetBuildTime(); | 357 base::Time build_time = base::GetBuildTime(); |
| 233 if (time_now < build_time - base::TimeDelta::FromDays(2)) | 358 if (time_now < build_time - base::TimeDelta::FromDays(2)) |
| 234 return true; | 359 return true; |
| 235 return false; | 360 return false; |
| 236 } | 361 } |
| 237 | 362 |
| 238 bool SSLErrorClassification::IsUserClockInTheFuture( | 363 bool SSLErrorClassification::IsUserClockInTheFuture( |
| 239 const base::Time& time_now) { | 364 const base::Time& time_now) { |
| 240 base::Time build_time = base::GetBuildTime(); | 365 base::Time build_time = base::GetBuildTime(); |
| (...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 439 static const int kMinimumEditDsitance = 5; | 564 static const int kMinimumEditDsitance = 5; |
| 440 for (size_t i = 0; i < dns_names_size; ++i) { | 565 for (size_t i = 0; i < dns_names_size; ++i) { |
| 441 for (size_t j = i + 1; j < dns_names_size; ++j) { | 566 for (size_t j = i + 1; j < dns_names_size; ++j) { |
| 442 int edit_distance = GetLevensteinDistance(dns_names[i], dns_names[j]); | 567 int edit_distance = GetLevensteinDistance(dns_names[i], dns_names[j]); |
| 443 if (edit_distance < kMinimumEditDsitance) | 568 if (edit_distance < kMinimumEditDsitance) |
| 444 return false; | 569 return false; |
| 445 } | 570 } |
| 446 } | 571 } |
| 447 return true; | 572 return true; |
| 448 } | 573 } |
| 574 | |
| 575 void SSLErrorClassification::Observe( | |
| 576 int type, | |
| 577 const content::NotificationSource& source, | |
| 578 const content::NotificationDetails& details) { | |
| 579 #if defined(ENABLE_CAPTIVE_PORTAL_DETECTION) | |
| 580 // When detection is disabled, captive portal service always sends | |
| 581 // RESULT_INTERNET_CONNECTED. Ignore any probe results in that case. | |
| 582 if (!captive_portal_detection_enabled_) | |
| 583 return; | |
| 584 if (type == chrome::NOTIFICATION_CAPTIVE_PORTAL_CHECK_RESULT) { | |
| 585 captive_portal_probe_completed_ = true; | |
| 586 CaptivePortalService::Results* results = | |
| 587 content::Details<CaptivePortalService::Results>( | |
| 588 details).ptr(); | |
| 589 // If a captive portal was detected at any point when the interstitial was | |
| 590 // displayed, assume that the interstitial was caused by a captive portal. | |
| 591 // Example scenario: | |
| 592 // 1- Interstitial displayed and captive portal detected, setting the flag. | |
| 593 // 2- Captive portal detection automatically opens portal login page. | |
| 594 // 3- User logs in on the portal login page. | |
| 595 // A notification will be received here for RESULT_INTERNET_CONNECTED. Make | |
| 596 // sure we don't clear the captive protal flag, since the interstitial was | |
| 597 // potentially caused by the captive portal. | |
| 598 captive_portal_detected_ = captive_portal_detected_ || | |
| 599 (results->result == captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL); | |
| 600 // Also keep track of non-HTTP portals and error cases. | |
| 601 captive_portal_no_response_ = captive_portal_no_response_ || | |
| 602 (results->result == captive_portal::RESULT_NO_RESPONSE); | |
| 603 } | |
| 604 #endif | |
| 605 } | |
| OLD | NEW |