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

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

Issue 400323002: Refactor the captive portal code to move from the ssl_blocking_page class to the ssl_error_classific (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Removed Web_Contents() Created 6 years, 4 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 "chrome/browser/ssl/ssl_error_classification.h" 5 #include "chrome/browser/ssl/ssl_error_classification.h"
6 6
7 #include "base/build_time.h" 7 #include "base/build_time.h"
8 #include "base/metrics/field_trial.h" 8 #include "base/metrics/field_trial.h"
9 #include "base/metrics/histogram.h" 9 #include "base/metrics/histogram.h"
10 #include "base/time/time.h" 10 #include "base/time/time.h"
11 #include "chrome/browser/browser_process.h" 11 #include "chrome/browser/browser_process.h"
12 #include "components/network_time/network_time_tracker.h" 12 #include "chrome/browser/chrome_notification_types.h"
13 #include "chrome/browser/profiles/profile.h"
14 #include "content/public/browser/notification_service.h"
15 #include "content/public/browser/web_contents.h"
16 #include "net/base/network_change_notifier.h"
13 #include "net/cert/x509_certificate.h" 17 #include "net/cert/x509_certificate.h"
14 18
19 #if defined(ENABLE_CAPTIVE_PORTAL_DETECTION)
20 #include "chrome/browser/captive_portal/captive_portal_service.h"
21 #include "chrome/browser/captive_portal/captive_portal_service_factory.h"
22 #endif
23
15 using base::Time; 24 using base::Time;
16 using base::TimeTicks; 25 using base::TimeTicks;
17 using base::TimeDelta; 26 using base::TimeDelta;
18 27
19 namespace { 28 namespace {
20 29
21 // Events for UMA. Do not reorder or change! 30 // Events for UMA. Do not reorder or change!
22 enum SSLInterstitialCause { 31 enum SSLInterstitialCause {
23 CLOCK_PAST, 32 CLOCK_PAST,
24 CLOCK_FUTURE, 33 CLOCK_FUTURE,
25 UNUSED_INTERSTITIAL_CAUSE_ENTRY, 34 UNUSED_INTERSTITIAL_CAUSE_ENTRY,
26 }; 35 };
27 36
37 // Events for UMA. Do not reorder or change!
38 enum SSLInterstitialCauseCaptivePortal {
39 CAPTIVE_PORTAL_DETECTION_ENABLED,
40 CAPTIVE_PORTAL_DETECTION_ENABLED_OVERRIDABLE,
41 CAPTIVE_PORTAL_PROBE_COMPLETED,
42 CAPTIVE_PORTAL_PROBE_COMPLETED_OVERRIDABLE,
43 CAPTIVE_PORTAL_NO_RESPONSE,
44 CAPTIVE_PORTAL_NO_RESPONSE_OVERRIDABLE,
45 CAPTIVE_PORTAL_DETECTED,
46 CAPTIVE_PORTAL_DETECTED_OVERRIDABLE,
47 UNUSED_CAPTIVE_PORTAL_EVENT,
48 };
49
28 void RecordSSLInterstitialCause(bool overridable, SSLInterstitialCause event) { 50 void RecordSSLInterstitialCause(bool overridable, SSLInterstitialCause event) {
29 if (overridable) { 51 if (overridable) {
30 UMA_HISTOGRAM_ENUMERATION("interstitial.ssl.cause.overridable", event, 52 UMA_HISTOGRAM_ENUMERATION("interstitial.ssl.cause.overridable", event,
31 UNUSED_INTERSTITIAL_CAUSE_ENTRY); 53 UNUSED_INTERSTITIAL_CAUSE_ENTRY);
32 } else { 54 } else {
33 UMA_HISTOGRAM_ENUMERATION("interstitial.ssl.cause.nonoverridable", event, 55 UMA_HISTOGRAM_ENUMERATION("interstitial.ssl.cause.nonoverridable", event,
34 UNUSED_INTERSTITIAL_CAUSE_ENTRY); 56 UNUSED_INTERSTITIAL_CAUSE_ENTRY);
35 } 57 }
36 } 58 }
37 59
60 void RecordCaptivePortalEventStats(SSLInterstitialCauseCaptivePortal event) {
61 UMA_HISTOGRAM_ENUMERATION("interstitial.ssl.captive_portal",
62 event,
63 UNUSED_CAPTIVE_PORTAL_EVENT);
64 }
65
38 } // namespace 66 } // namespace
39 67
40 SSLErrorClassification::SSLErrorClassification( 68 SSLErrorClassification::SSLErrorClassification(
69 content::WebContents* web_contents,
41 base::Time current_time, 70 base::Time current_time,
42 const net::X509Certificate& cert) 71 const net::X509Certificate& cert)
43 : current_time_(current_time), 72 : web_contents_(web_contents),
44 cert_(cert) { } 73 current_time_(current_time),
74 cert_(cert),
75 captive_portal_detection_enabled_(false),
76 captive_portal_probe_completed_(false),
77 captive_portal_no_response_(false),
78 captive_portal_detected_(false) {
79 #if defined(ENABLE_CAPTIVE_PORTAL_DETECTION)
80 Profile* profile = Profile::FromBrowserContext(
81 web_contents_->GetBrowserContext());
82 CaptivePortalService* captive_portal_service =
83 CaptivePortalServiceFactory::GetForProfile(profile);
84 captive_portal_detection_enabled_ = captive_portal_service ->enabled();
85 captive_portal_service ->DetectCaptivePortal();
86 registrar_.Add(this,
87 chrome::NOTIFICATION_CAPTIVE_PORTAL_CHECK_RESULT,
88 content::Source<Profile>(profile));
89 #endif
90 }
45 91
46 SSLErrorClassification::~SSLErrorClassification() { } 92 SSLErrorClassification::~SSLErrorClassification() { }
47 93
48 float SSLErrorClassification::InvalidDateSeverityScore() const { 94 float SSLErrorClassification::InvalidDateSeverityScore() const {
49 // Client-side characterisitics. Check whether the system's clock is wrong or 95 // Client-side characteristics. Check whether or not the system's clock is
50 // not and whether the user has encountered this error before or not. 96 // wrong and whether or not the user has encountered this error before.
51 float severity_date_score = 0.0f; 97 float severity_date_score = 0.0f;
52 98
53 static const float kClientWeight = 0.5f; 99 static const float kClientWeight = 0.5f;
54 static const float kSystemClockWeight = 0.75f; 100 static const float kSystemClockWeight = 0.75f;
55 static const float kSystemClockWrongWeight = 0.1f; 101 static const float kSystemClockWrongWeight = 0.1f;
56 static const float kSystemClockRightWeight = 1.0f; 102 static const float kSystemClockRightWeight = 1.0f;
57 103
58 static const float kServerWeight = 0.5f; 104 static const float kServerWeight = 0.5f;
59 static const float kCertificateExpiredWeight = 0.3f; 105 static const float kCertificateExpiredWeight = 0.3f;
60 static const float kNotYetValidWeight = 0.2f; 106 static const float kNotYetValidWeight = 0.2f;
(...skipping 13 matching lines...) Expand all
74 // has passed since expiry. 120 // has passed since expiry.
75 if (cert_.HasExpired()) { 121 if (cert_.HasExpired()) {
76 severity_date_score += kServerWeight * kCertificateExpiredWeight * 122 severity_date_score += kServerWeight * kCertificateExpiredWeight *
77 CalculateScoreTimePassedSinceExpiry(); 123 CalculateScoreTimePassedSinceExpiry();
78 } 124 }
79 if (current_time_ < cert_.valid_start()) 125 if (current_time_ < cert_.valid_start())
80 severity_date_score += kServerWeight * kNotYetValidWeight; 126 severity_date_score += kServerWeight * kNotYetValidWeight;
81 return severity_date_score; 127 return severity_date_score;
82 } 128 }
83 129
130 void SSLErrorClassification::RecordUMAStatistics(bool overridable) const {
131 if (IsUserClockInThePast(base::Time::NowFromSystemTime()))
132 RecordSSLInterstitialCause(overridable, CLOCK_PAST);
133 if (IsUserClockInTheFuture(base::Time::NowFromSystemTime()))
134 RecordSSLInterstitialCause(overridable, CLOCK_FUTURE);
135 }
136
137 void SSLErrorClassification::RecordCaptivePortalUMAStatistics(
138 bool overridable) const {
139 #if defined(ENABLE_CAPTIVE_PORTAL_DETECTION)
140 if (captive_portal_detection_enabled_)
141 RecordCaptivePortalEventStats(
142 overridable ?
143 CAPTIVE_PORTAL_DETECTION_ENABLED_OVERRIDABLE :
144 CAPTIVE_PORTAL_DETECTION_ENABLED);
145 if (captive_portal_probe_completed_)
146 RecordCaptivePortalEventStats(
147 overridable ?
148 CAPTIVE_PORTAL_PROBE_COMPLETED_OVERRIDABLE :
149 CAPTIVE_PORTAL_PROBE_COMPLETED);
150 // Log only one of portal detected and no response results.
151 if (captive_portal_detected_)
152 RecordCaptivePortalEventStats(
153 overridable ?
154 CAPTIVE_PORTAL_DETECTED_OVERRIDABLE :
155 CAPTIVE_PORTAL_DETECTED);
156 else if (captive_portal_no_response_)
157 RecordCaptivePortalEventStats(
158 overridable ?
159 CAPTIVE_PORTAL_NO_RESPONSE_OVERRIDABLE :
160 CAPTIVE_PORTAL_NO_RESPONSE);
161 #endif
162 }
163
84 base::TimeDelta SSLErrorClassification::TimePassedSinceExpiry() const { 164 base::TimeDelta SSLErrorClassification::TimePassedSinceExpiry() const {
85 base::TimeDelta delta = current_time_ - cert_.valid_expiry(); 165 base::TimeDelta delta = current_time_ - cert_.valid_expiry();
86 return delta; 166 return delta;
87 } 167 }
88 168
89 float SSLErrorClassification::CalculateScoreTimePassedSinceExpiry() const { 169 float SSLErrorClassification::CalculateScoreTimePassedSinceExpiry() const {
90 base::TimeDelta delta = TimePassedSinceExpiry(); 170 base::TimeDelta delta = TimePassedSinceExpiry();
91 int64 time_passed = delta.InDays(); 171 int64 time_passed = delta.InDays();
92 const int64 kHighThreshold = 7; 172 const int64 kHighThreshold = 7;
93 const int64 kLowThreshold = 4; 173 const int64 kLowThreshold = 4;
94 static const float kHighThresholdWeight = 0.4f; 174 static const float kHighThresholdWeight = 0.4f;
95 static const float kMediumThresholdWeight = 0.3f; 175 static const float kMediumThresholdWeight = 0.3f;
96 static const float kLowThresholdWeight = 0.2f; 176 static const float kLowThresholdWeight = 0.2f;
97 if (time_passed >= kHighThreshold) 177 if (time_passed >= kHighThreshold)
98 return kHighThresholdWeight; 178 return kHighThresholdWeight;
99 else if (time_passed >= kLowThreshold) 179 else if (time_passed >= kLowThreshold)
100 return kMediumThresholdWeight; 180 return kMediumThresholdWeight;
101 else 181 else
102 return kLowThresholdWeight; 182 return kLowThresholdWeight;
103 } 183 }
104 184
185 float SSLErrorClassification::CalculateScoreEnvironments() const {
186 static const float kWifiWeight = 0.7f;
187 static const float kCellularWeight = 0.7f;
188 static const float kHotspotWeight = 0.2f;
189 static const float kEthernetWeight = 0.7f;
190 static const float kOtherWeight = 0.7f;
191 net::NetworkChangeNotifier::ConnectionType type =
192 net::NetworkChangeNotifier::GetConnectionType();
193 if (type == net::NetworkChangeNotifier::CONNECTION_WIFI)
194 return kWifiWeight;
195 if (type == net::NetworkChangeNotifier::CONNECTION_2G ||
196 type == net::NetworkChangeNotifier::CONNECTION_3G ||
197 type == net::NetworkChangeNotifier::CONNECTION_4G ) {
198 return kCellularWeight;
199 }
200 if (type == net::NetworkChangeNotifier::CONNECTION_ETHERNET)
201 return kEthernetWeight;
202 #if defined(ENABLE_CAPTIVE_PORTAL_DETECTION)
203 // Assume if captive portals are detected then the user is connected using a
204 // hot spot.
205 if (captive_portal_detected_)
felt 2014/07/24 01:12:33 captive_portal_detected_ won't have been set yet u
meacer 2014/07/24 01:17:26 Or wait 2 seconds to calculate this score? :-) Bu
radhikabhar 2014/07/24 01:25:17 Doesn't Observe run when we call the registrar.Add
meacer 2014/07/24 01:28:47 Hmm, I think I wanted to say "wait until captive_p
felt 2014/07/24 01:51:08 Observe should run when the notification comes, wh
radhikabhar 2014/07/24 20:21:53 @felt - Will this be correct logic - if !captive_p
206 return kHotspotWeight;
207 #endif
208 return kOtherWeight;
209 }
210
105 bool SSLErrorClassification::IsUserClockInThePast(base::Time time_now) { 211 bool SSLErrorClassification::IsUserClockInThePast(base::Time time_now) {
106 base::Time build_time = base::GetBuildTime(); 212 base::Time build_time = base::GetBuildTime();
107 if (time_now < build_time - base::TimeDelta::FromDays(2)) 213 if (time_now < build_time - base::TimeDelta::FromDays(2))
108 return true; 214 return true;
109 return false; 215 return false;
110 } 216 }
111 217
112 bool SSLErrorClassification::IsUserClockInTheFuture(base::Time time_now) { 218 bool SSLErrorClassification::IsUserClockInTheFuture(base::Time time_now) {
113 base::Time build_time = base::GetBuildTime(); 219 base::Time build_time = base::GetBuildTime();
114 if (time_now > build_time + base::TimeDelta::FromDays(365)) 220 if (time_now > build_time + base::TimeDelta::FromDays(365))
115 return true; 221 return true;
116 return false; 222 return false;
117 } 223 }
118 224
119 void SSLErrorClassification::RecordUMAStatistics(bool overridable) { 225 void SSLErrorClassification::Observe(
120 if (IsUserClockInThePast(base::Time::NowFromSystemTime())) 226 int type,
121 RecordSSLInterstitialCause(overridable, CLOCK_PAST); 227 const content::NotificationSource& source,
122 if (IsUserClockInTheFuture(base::Time::NowFromSystemTime())) 228 const content::NotificationDetails& details) {
123 RecordSSLInterstitialCause(overridable, CLOCK_FUTURE); 229 #if defined(ENABLE_CAPTIVE_PORTAL_DETECTION)
230 // When detection is disabled, captive portal service always sends
231 // RESULT_INTERNET_CONNECTED. Ignore any probe results in that case.
232 if (!captive_portal_detection_enabled_)
233 return;
234 if (type == chrome::NOTIFICATION_CAPTIVE_PORTAL_CHECK_RESULT) {
235 captive_portal_probe_completed_ = true;
236 CaptivePortalService::Results* results =
237 content::Details<CaptivePortalService::Results>(
238 details).ptr();
239 // If a captive portal was detected at any point when the interstitial was
240 // displayed, assume that the interstitial was caused by a captive portal.
241 // Example scenario:
242 // 1- Interstitial displayed and captive portal detected, setting the flag.
243 // 2- Captive portal detection automatically opens portal login page.
244 // 3- User logs in on the portal login page.
245 // A notification will be received here for RESULT_INTERNET_CONNECTED. Make
246 // sure we don't clear the captive protal flag, since the interstitial was
247 // potentially caused by the captive portal.
248 captive_portal_detected_ = captive_portal_detected_ ||
249 (results->result == captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL);
250 // Also keep track of non-HTTP portals and error cases.
251 captive_portal_no_response_ = captive_portal_no_response_ ||
252 (results->result == captive_portal::RESULT_NO_RESPONSE);
253 }
254 #endif
124 } 255 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698