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 |
55 // Events for UMA. Do not reorder or change! | |
56 enum SSLInterstitialCauseCaptivePortal { | |
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 | |
45 // Scores/weights which will be constant through all the SSL error types. | 68 // Scores/weights which will be constant through all the SSL error types. |
46 static const float kServerWeight = 0.5f; | 69 static const float kServerWeight = 0.5f; |
47 static const float kClientWeight = 0.5f; | 70 static const float kClientWeight = 0.5f; |
48 | 71 |
49 void RecordSSLInterstitialCause(bool overridable, SSLInterstitialCause event) { | 72 void RecordSSLInterstitialCause(bool overridable, SSLInterstitialCause event) { |
50 if (overridable) { | 73 if (overridable) { |
51 UMA_HISTOGRAM_ENUMERATION("interstitial.ssl.cause.overridable", event, | 74 UMA_HISTOGRAM_ENUMERATION("interstitial.ssl.cause.overridable", event, |
52 UNUSED_INTERSTITIAL_CAUSE_ENTRY); | 75 UNUSED_INTERSTITIAL_CAUSE_ENTRY); |
53 } else { | 76 } else { |
54 UMA_HISTOGRAM_ENUMERATION("interstitial.ssl.cause.nonoverridable", event, | 77 UMA_HISTOGRAM_ENUMERATION("interstitial.ssl.cause.nonoverridable", event, |
55 UNUSED_INTERSTITIAL_CAUSE_ENTRY); | 78 UNUSED_INTERSTITIAL_CAUSE_ENTRY); |
56 } | 79 } |
57 } | 80 } |
58 | 81 |
82 #if defined(ENABLE_CAPTIVE_PORTAL_DETECTION) | |
83 void RecordCaptivePortalEventStats(SSLInterstitialCauseCaptivePortal event) { | |
84 UMA_HISTOGRAM_ENUMERATION("interstitial.ssl.captive_portal", | |
85 event, | |
86 UNUSED_CAPTIVE_PORTAL_EVENT); | |
87 #endif | |
88 } | |
89 | |
59 int GetLevensteinDistance(const std::string& str1, | 90 int GetLevensteinDistance(const std::string& str1, |
60 const std::string& str2) { | 91 const std::string& str2) { |
61 if (str1 == str2) | 92 if (str1 == str2) |
62 return 0; | 93 return 0; |
63 if (str1.size() == 0) | 94 if (str1.size() == 0) |
64 return str2.size(); | 95 return str2.size(); |
65 if (str2.size() == 0) | 96 if (str2.size() == 0) |
66 return str1.size(); | 97 return str1.size(); |
67 std::vector<int> kFirstRow(str2.size() + 1, 0); | 98 std::vector<int> kFirstRow(str2.size() + 1, 0); |
68 std::vector<int> kSecondRow(str2.size() + 1, 0); | 99 std::vector<int> kSecondRow(str2.size() + 1, 0); |
69 | 100 |
70 for (size_t i = 0; i < kFirstRow.size(); ++i) | 101 for (size_t i = 0; i < kFirstRow.size(); ++i) |
71 kFirstRow[i] = i; | 102 kFirstRow[i] = i; |
72 for (size_t i = 0; i < str1.size(); ++i) { | 103 for (size_t i = 0; i < str1.size(); ++i) { |
73 kSecondRow[0] = i + 1; | 104 kSecondRow[0] = i + 1; |
74 for (size_t j = 0; j < str2.size(); ++j) { | 105 for (size_t j = 0; j < str2.size(); ++j) { |
75 int cost = str1[i] == str2[j] ? 0 : 1; | 106 int cost = str1[i] == str2[j] ? 0 : 1; |
76 kSecondRow[j+1] = std::min(std::min( | 107 kSecondRow[j+1] = std::min(std::min( |
77 kSecondRow[j] + 1, kFirstRow[j + 1] + 1), kFirstRow[j] + cost); | 108 kSecondRow[j] + 1, kFirstRow[j + 1] + 1), kFirstRow[j] + cost); |
78 } | 109 } |
79 for (size_t j = 0; j < kFirstRow.size(); j++) | 110 for (size_t j = 0; j < kFirstRow.size(); j++) |
80 kFirstRow[j] = kSecondRow[j]; | 111 kFirstRow[j] = kSecondRow[j]; |
81 } | 112 } |
82 return kSecondRow[str2.size()]; | 113 return kSecondRow[str2.size()]; |
83 } | 114 } |
84 | 115 |
85 } // namespace | 116 } // namespace |
86 | 117 |
87 SSLErrorClassification::SSLErrorClassification( | 118 SSLErrorClassification::SSLErrorClassification( |
119 content::WebContents* web_contents, | |
88 const base::Time& current_time, | 120 const base::Time& current_time, |
89 const GURL& url, | 121 const GURL& url, |
122 int cert_error, | |
90 const net::X509Certificate& cert) | 123 const net::X509Certificate& cert) |
91 : current_time_(current_time), | 124 : web_contents_(web_contents), |
125 current_time_(current_time), | |
92 request_url_(url), | 126 request_url_(url), |
93 cert_(cert) { } | 127 cert_error_(cert_error), |
128 cert_(cert), | |
129 captive_portal_detection_enabled_(false), | |
130 captive_portal_probe_completed_(false), | |
131 captive_portal_no_response_(false), | |
132 captive_portal_detected_(false) { | |
133 #if defined(ENABLE_CAPTIVE_PORTAL_DETECTION) | |
134 Profile* profile = Profile::FromBrowserContext( | |
135 web_contents_->GetBrowserContext()); | |
136 CaptivePortalService* captive_portal_service = | |
137 CaptivePortalServiceFactory::GetForProfile(profile); | |
138 captive_portal_detection_enabled_ = captive_portal_service->enabled(); | |
139 captive_portal_service->DetectCaptivePortal(); | |
140 registrar_.Add(this, | |
141 chrome::NOTIFICATION_CAPTIVE_PORTAL_CHECK_RESULT, | |
142 content::Source<Profile>(profile)); | |
143 #endif | |
144 } | |
94 | 145 |
95 SSLErrorClassification::~SSLErrorClassification() { } | 146 SSLErrorClassification::~SSLErrorClassification() { } |
96 | 147 |
97 float SSLErrorClassification::InvalidDateSeverityScore( | 148 void SSLErrorClassification::RecordCaptivePortalUMAStatistics( |
98 int cert_error) const { | 149 bool overridable) const { |
150 #if defined(ENABLE_CAPTIVE_PORTAL_DETECTION) | |
151 if (captive_portal_detection_enabled_) | |
152 RecordCaptivePortalEventStats( | |
153 overridable ? | |
154 CAPTIVE_PORTAL_DETECTION_ENABLED_OVERRIDABLE : | |
155 CAPTIVE_PORTAL_DETECTION_ENABLED); | |
156 if (captive_portal_probe_completed_) | |
157 RecordCaptivePortalEventStats( | |
158 overridable ? | |
159 CAPTIVE_PORTAL_PROBE_COMPLETED_OVERRIDABLE : | |
160 CAPTIVE_PORTAL_PROBE_COMPLETED); | |
161 // Log only one of portal detected and no response results. | |
162 if (captive_portal_detected_) | |
163 RecordCaptivePortalEventStats( | |
164 overridable ? | |
165 CAPTIVE_PORTAL_DETECTED_OVERRIDABLE : | |
166 CAPTIVE_PORTAL_DETECTED); | |
167 else if (captive_portal_no_response_) | |
168 RecordCaptivePortalEventStats( | |
169 overridable ? | |
170 CAPTIVE_PORTAL_NO_RESPONSE_OVERRIDABLE : | |
171 CAPTIVE_PORTAL_NO_RESPONSE); | |
172 #endif | |
173 } | |
174 | |
175 void SSLErrorClassification::InvalidDateSeverityScore() { | |
99 SSLErrorInfo::ErrorType type = | 176 SSLErrorInfo::ErrorType type = |
100 SSLErrorInfo::NetErrorToErrorType(cert_error); | 177 SSLErrorInfo::NetErrorToErrorType(cert_error_); |
101 DCHECK(type == SSLErrorInfo::CERT_DATE_INVALID); | 178 DCHECK(type == SSLErrorInfo::CERT_DATE_INVALID); |
179 | |
102 // Client-side characteristics. Check whether or not the system's clock is | 180 // 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 | 181 // wrong and whether or not the user has encountered this error before. |
104 // before. | |
105 float severity_date_score = 0.0f; | 182 float severity_date_score = 0.0f; |
106 | 183 |
107 static const float kCertificateExpiredWeight = 0.3f; | 184 static const float kCertificateExpiredWeight = 0.3f; |
108 static const float kNotYetValidWeight = 0.2f; | 185 static const float kNotYetValidWeight = 0.2f; |
109 | 186 |
110 static const float kSystemClockWeight = 0.75f; | 187 static const float kSystemClockWeight = 0.75f; |
111 static const float kSystemClockWrongWeight = 0.1f; | 188 static const float kSystemClockWrongWeight = 0.1f; |
112 static const float kSystemClockRightWeight = 1.0f; | 189 static const float kSystemClockRightWeight = 1.0f; |
113 | 190 |
114 if (IsUserClockInThePast(current_time_) || | 191 if (IsUserClockInThePast(current_time_) || |
115 IsUserClockInTheFuture(current_time_)) { | 192 IsUserClockInTheFuture(current_time_)) { |
116 severity_date_score += kClientWeight * kSystemClockWeight * | 193 severity_date_score += kClientWeight * kSystemClockWeight * |
117 kSystemClockWrongWeight; | 194 kSystemClockWrongWeight; |
118 } else { | 195 } else { |
119 severity_date_score += kClientWeight * kSystemClockWeight * | 196 severity_date_score += kClientWeight * kSystemClockWeight * |
120 kSystemClockRightWeight; | 197 kSystemClockRightWeight; |
121 } | 198 } |
122 // TODO(radhikabhar): (crbug.com/393262) Check website settings. | 199 // TODO(radhikabhar): (crbug.com/393262) Check website settings. |
123 | 200 |
124 // Server-side characteristics. Check whether the certificate has expired or | 201 // 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 | 202 // is not yet valid. If the certificate has expired then factor the time which |
126 // has passed since expiry. | 203 // has passed since expiry. |
127 if (cert_.HasExpired()) { | 204 if (cert_.HasExpired()) { |
128 severity_date_score += kServerWeight * kCertificateExpiredWeight * | 205 severity_date_score += kServerWeight * kCertificateExpiredWeight * |
129 CalculateScoreTimePassedSinceExpiry(); | 206 CalculateScoreTimePassedSinceExpiry(); |
130 } | 207 } |
131 if (current_time_ < cert_.valid_start()) | 208 if (current_time_ < cert_.valid_start()) |
132 severity_date_score += kServerWeight * kNotYetValidWeight; | 209 severity_date_score += kServerWeight * kNotYetValidWeight; |
133 return severity_date_score; | 210 // TODO(radhikabhar): Record the severity score in a histogram. This will be |
palmer
2014/08/30 00:28:19
TODO(felt) or TODO(palmer), now
felt
2014/08/30 01:11:52
Done.
| |
211 // in the next CL - just called the function in ssl_blocking_page.cc. | |
134 } | 212 } |
135 | 213 |
136 float SSLErrorClassification::InvalidCommonNameSeverityScore( | 214 void SSLErrorClassification::InvalidCommonNameSeverityScore() { |
137 int cert_error) const { | |
138 SSLErrorInfo::ErrorType type = | 215 SSLErrorInfo::ErrorType type = |
139 SSLErrorInfo::NetErrorToErrorType(cert_error); | 216 SSLErrorInfo::NetErrorToErrorType(cert_error_); |
140 DCHECK(type == SSLErrorInfo::CERT_COMMON_NAME_INVALID); | 217 DCHECK(type == SSLErrorInfo::CERT_COMMON_NAME_INVALID); |
141 float severity_name_score = 0.0f; | 218 float severity_name_score = 0.0f; |
142 | 219 |
143 static const float kWWWDifferenceWeight = 0.3f; | 220 static const float kWWWDifferenceWeight = 0.3f; |
144 static const float kNameUnderAnyNamesWeight = 0.2f; | 221 static const float kNameUnderAnyNamesWeight = 0.2f; |
145 static const float kAnyNamesUnderNameWeight = 1.0f; | 222 static const float kAnyNamesUnderNameWeight = 1.0f; |
146 static const float kLikelyMultiTenantHostingWeight = 0.1f; | 223 static const float kLikelyMultiTenantHostingWeight = 0.1f; |
147 | 224 |
148 std::string host_name = request_url_.host(); | 225 std::string host_name = request_url_.host(); |
149 if (IsHostNameKnownTLD(host_name)) { | 226 if (IsHostNameKnownTLD(host_name)) { |
150 Tokens host_name_tokens = Tokenize(host_name); | 227 Tokens host_name_tokens = Tokenize(host_name); |
151 if (IsWWWSubDomainMatch()) | 228 if (IsWWWSubDomainMatch()) |
152 severity_name_score += kServerWeight * kWWWDifferenceWeight; | 229 severity_name_score += kServerWeight * kWWWDifferenceWeight; |
153 if (IsSubDomainOutsideWildcard(host_name_tokens)) | 230 if (IsSubDomainOutsideWildcard(host_name_tokens)) |
154 severity_name_score += kServerWeight * kWWWDifferenceWeight; | 231 severity_name_score += kServerWeight * kWWWDifferenceWeight; |
155 | 232 |
156 std::vector<std::string> dns_names; | 233 std::vector<std::string> dns_names; |
157 cert_.GetDNSNames(&dns_names); | 234 cert_.GetDNSNames(&dns_names); |
158 std::vector<Tokens> dns_name_tokens = GetTokenizedDNSNames(dns_names); | 235 std::vector<Tokens> dns_name_tokens = GetTokenizedDNSNames(dns_names); |
159 if (NameUnderAnyNames(host_name_tokens, dns_name_tokens)) | 236 if (NameUnderAnyNames(host_name_tokens, dns_name_tokens)) |
160 severity_name_score += kServerWeight * kNameUnderAnyNamesWeight; | 237 severity_name_score += kServerWeight * kNameUnderAnyNamesWeight; |
161 // Inverse case is more likely to be a MITM attack. | 238 // Inverse case is more likely to be a MITM attack. |
162 if (AnyNamesUnderName(dns_name_tokens, host_name_tokens)) | 239 if (AnyNamesUnderName(dns_name_tokens, host_name_tokens)) |
163 severity_name_score += kServerWeight * kAnyNamesUnderNameWeight; | 240 severity_name_score += kServerWeight * kAnyNamesUnderNameWeight; |
164 if (IsCertLikelyFromMultiTenantHosting()) | 241 if (IsCertLikelyFromMultiTenantHosting()) |
165 severity_name_score += kServerWeight * kLikelyMultiTenantHostingWeight; | 242 severity_name_score += kServerWeight * kLikelyMultiTenantHostingWeight; |
166 } | 243 } |
167 return severity_name_score; | 244 |
245 static const float kEnvironmentWeight = 0.25f; | |
246 | |
247 severity_name_score += kClientWeight * kEnvironmentWeight * | |
248 CalculateScoreEnvironments(); | |
249 // TODO(radhikabhar): Record the severity score in a histogram. Same as above | |
palmer
2014/08/30 00:28:19
same
felt
2014/08/30 01:11:52
Done.
| |
250 // - this will be in the next CL. So just called the function in the | |
251 // ssl_blocking_page.cc. | |
168 } | 252 } |
169 | 253 |
170 void SSLErrorClassification::RecordUMAStatistics(bool overridable, | 254 void SSLErrorClassification::RecordUMAStatistics( |
171 int cert_error) { | 255 bool overridable) const { |
172 SSLErrorInfo::ErrorType type = | 256 SSLErrorInfo::ErrorType type = |
173 SSLErrorInfo::NetErrorToErrorType(cert_error); | 257 SSLErrorInfo::NetErrorToErrorType(cert_error_); |
174 switch (type) { | 258 switch (type) { |
175 case SSLErrorInfo::CERT_DATE_INVALID: { | 259 case SSLErrorInfo::CERT_DATE_INVALID: { |
176 if (IsUserClockInThePast(base::Time::NowFromSystemTime())) | 260 if (IsUserClockInThePast(base::Time::NowFromSystemTime())) |
177 RecordSSLInterstitialCause(overridable, CLOCK_PAST); | 261 RecordSSLInterstitialCause(overridable, CLOCK_PAST); |
178 if (IsUserClockInTheFuture(base::Time::NowFromSystemTime())) | 262 if (IsUserClockInTheFuture(base::Time::NowFromSystemTime())) |
179 RecordSSLInterstitialCause(overridable, CLOCK_FUTURE); | 263 RecordSSLInterstitialCause(overridable, CLOCK_FUTURE); |
180 break; | 264 break; |
181 } | 265 } |
182 case SSLErrorInfo::CERT_COMMON_NAME_INVALID: { | 266 case SSLErrorInfo::CERT_COMMON_NAME_INVALID: { |
183 std::string host_name = request_url_.host(); | 267 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; | 305 static const float kMediumThresholdWeight = 0.3f; |
222 static const float kLowThresholdWeight = 0.2f; | 306 static const float kLowThresholdWeight = 0.2f; |
223 if (time_passed >= kHighThreshold) | 307 if (time_passed >= kHighThreshold) |
224 return kHighThresholdWeight; | 308 return kHighThresholdWeight; |
225 else if (time_passed >= kLowThreshold) | 309 else if (time_passed >= kLowThreshold) |
226 return kMediumThresholdWeight; | 310 return kMediumThresholdWeight; |
227 else | 311 else |
228 return kLowThresholdWeight; | 312 return kLowThresholdWeight; |
229 } | 313 } |
230 | 314 |
315 float SSLErrorClassification::CalculateScoreEnvironments() const { | |
316 static const float kWifiWeight = 0.7f; | |
317 static const float kCellularWeight = 0.7f; | |
318 static const float kEthernetWeight = 0.7f; | |
319 static const float kOtherWeight = 0.7f; | |
320 net::NetworkChangeNotifier::ConnectionType type = | |
321 net::NetworkChangeNotifier::GetConnectionType(); | |
322 if (type == net::NetworkChangeNotifier::CONNECTION_WIFI) | |
323 return kWifiWeight; | |
324 if (type == net::NetworkChangeNotifier::CONNECTION_2G || | |
325 type == net::NetworkChangeNotifier::CONNECTION_3G || | |
326 type == net::NetworkChangeNotifier::CONNECTION_4G ) { | |
327 return kCellularWeight; | |
328 } | |
329 if (type == net::NetworkChangeNotifier::CONNECTION_ETHERNET) | |
330 return kEthernetWeight; | |
331 #if defined(ENABLE_CAPTIVE_PORTAL_DETECTION) | |
332 // Assume if captive portals are detected then the user is connected using a | |
333 // hot spot. | |
334 static const float kHotspotWeight = 0.2f; | |
335 if (captive_portal_probe_completed_ && captive_portal_detected_) | |
336 return kHotspotWeight; | |
337 #endif | |
338 return kOtherWeight; | |
339 } | |
340 | |
231 bool SSLErrorClassification::IsUserClockInThePast(const base::Time& time_now) { | 341 bool SSLErrorClassification::IsUserClockInThePast(const base::Time& time_now) { |
232 base::Time build_time = base::GetBuildTime(); | 342 base::Time build_time = base::GetBuildTime(); |
233 if (time_now < build_time - base::TimeDelta::FromDays(2)) | 343 if (time_now < build_time - base::TimeDelta::FromDays(2)) |
234 return true; | 344 return true; |
235 return false; | 345 return false; |
236 } | 346 } |
237 | 347 |
238 bool SSLErrorClassification::IsUserClockInTheFuture( | 348 bool SSLErrorClassification::IsUserClockInTheFuture( |
239 const base::Time& time_now) { | 349 const base::Time& time_now) { |
240 base::Time build_time = base::GetBuildTime(); | 350 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; | 549 static const int kMinimumEditDsitance = 5; |
440 for (size_t i = 0; i < dns_names_size; ++i) { | 550 for (size_t i = 0; i < dns_names_size; ++i) { |
441 for (size_t j = i + 1; j < dns_names_size; ++j) { | 551 for (size_t j = i + 1; j < dns_names_size; ++j) { |
442 int edit_distance = GetLevensteinDistance(dns_names[i], dns_names[j]); | 552 int edit_distance = GetLevensteinDistance(dns_names[i], dns_names[j]); |
443 if (edit_distance < kMinimumEditDsitance) | 553 if (edit_distance < kMinimumEditDsitance) |
444 return false; | 554 return false; |
445 } | 555 } |
446 } | 556 } |
447 return true; | 557 return true; |
448 } | 558 } |
559 | |
560 void SSLErrorClassification::Observe( | |
561 int type, | |
562 const content::NotificationSource& source, | |
563 const content::NotificationDetails& details) { | |
564 #if defined(ENABLE_CAPTIVE_PORTAL_DETECTION) | |
565 // When detection is disabled, captive portal service always sends | |
566 // RESULT_INTERNET_CONNECTED. Ignore any probe results in that case. | |
567 if (!captive_portal_detection_enabled_) | |
568 return; | |
569 if (type == chrome::NOTIFICATION_CAPTIVE_PORTAL_CHECK_RESULT) { | |
570 captive_portal_probe_completed_ = true; | |
571 CaptivePortalService::Results* results = | |
572 content::Details<CaptivePortalService::Results>( | |
573 details).ptr(); | |
574 // If a captive portal was detected at any point when the interstitial was | |
575 // displayed, assume that the interstitial was caused by a captive portal. | |
576 // Example scenario: | |
577 // 1- Interstitial displayed and captive portal detected, setting the flag. | |
578 // 2- Captive portal detection automatically opens portal login page. | |
579 // 3- User logs in on the portal login page. | |
580 // A notification will be received here for RESULT_INTERNET_CONNECTED. Make | |
581 // sure we don't clear the captive protal flag, since the interstitial was | |
582 // potentially caused by the captive portal. | |
583 captive_portal_detected_ = captive_portal_detected_ || | |
584 (results->result == captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL); | |
585 // Also keep track of non-HTTP portals and error cases. | |
586 captive_portal_no_response_ = captive_portal_no_response_ || | |
587 (results->result == captive_portal::RESULT_NO_RESPONSE); | |
588 } | |
589 #endif | |
590 } | |
OLD | NEW |