Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(266)

Side by Side Diff: chrome/browser/ssl/ssl_error_classification.cc

Issue 516373003: Refactor captive portal code from SSLBlockingPage to SSLErrorClassification (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Moved ssl_error_classification into a global variable Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698