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

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

Issue 1365733005: Split captive portal metrics out of SSLErrorClassification (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Compiler error fix possibly for realsies Created 5 years, 2 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/histogram.h" 10 #include "base/metrics/histogram_macros.h"
11 #include "base/strings/string_split.h" 11 #include "base/strings/string_split.h"
12 #include "base/strings/utf_string_conversions.h" 12 #include "base/strings/utf_string_conversions.h"
13 #include "base/time/time.h" 13 #include "base/time/time.h"
14 #include "chrome/browser/browser_process.h"
15 #include "chrome/browser/chrome_notification_types.h"
16 #include "chrome/browser/profiles/profile.h"
17 #include "components/ssl_errors/error_info.h" 14 #include "components/ssl_errors/error_info.h"
18 #include "content/public/browser/notification_service.h"
19 #include "content/public/browser/web_contents.h"
20 #include "net/base/net_util.h" 15 #include "net/base/net_util.h"
21 #include "net/base/registry_controlled_domains/registry_controlled_domain.h" 16 #include "net/base/registry_controlled_domains/registry_controlled_domain.h"
22 #include "net/cert/x509_cert_types.h" 17 #include "net/cert/x509_cert_types.h"
23 #include "net/cert/x509_certificate.h" 18 #include "net/cert/x509_certificate.h"
24 #include "url/gurl.h" 19 #include "url/gurl.h"
25 20
26 #if defined(ENABLE_CAPTIVE_PORTAL_DETECTION)
27 #include "chrome/browser/captive_portal/captive_portal_service.h"
28 #include "chrome/browser/captive_portal/captive_portal_service_factory.h"
29 #endif
30
31 #if defined(OS_WIN) 21 #if defined(OS_WIN)
32 #include "base/win/win_util.h" 22 #include "base/win/win_util.h"
33 #include "base/win/windows_version.h" 23 #include "base/win/windows_version.h"
34 #endif 24 #endif
35 25
36 using base::Time; 26 using base::Time;
37 using base::TimeTicks; 27 using base::TimeTicks;
38 using base::TimeDelta; 28 using base::TimeDelta;
39 29
40 namespace { 30 namespace {
41 31
42 // Events for UMA. Do not reorder or change! 32 // Events for UMA. Do not reorder or change!
43 enum SSLInterstitialCause { 33 enum SSLInterstitialCause {
44 CLOCK_PAST, 34 CLOCK_PAST,
45 CLOCK_FUTURE, 35 CLOCK_FUTURE,
46 WWW_SUBDOMAIN_MATCH, 36 WWW_SUBDOMAIN_MATCH,
47 SUBDOMAIN_MATCH, 37 SUBDOMAIN_MATCH,
48 SUBDOMAIN_INVERSE_MATCH, 38 SUBDOMAIN_INVERSE_MATCH,
49 SUBDOMAIN_OUTSIDE_WILDCARD, 39 SUBDOMAIN_OUTSIDE_WILDCARD,
50 HOST_NAME_NOT_KNOWN_TLD, 40 HOST_NAME_NOT_KNOWN_TLD,
51 LIKELY_MULTI_TENANT_HOSTING, 41 LIKELY_MULTI_TENANT_HOSTING,
52 LOCALHOST, 42 LOCALHOST,
53 PRIVATE_URL, 43 PRIVATE_URL,
54 AUTHORITY_ERROR_CAPTIVE_PORTAL, 44 AUTHORITY_ERROR_CAPTIVE_PORTAL, // Deprecated in M47.
55 SELF_SIGNED, 45 SELF_SIGNED,
56 EXPIRED_RECENTLY, 46 EXPIRED_RECENTLY,
57 LIKELY_SAME_DOMAIN, 47 LIKELY_SAME_DOMAIN,
58 UNUSED_INTERSTITIAL_CAUSE_ENTRY, 48 UNUSED_INTERSTITIAL_CAUSE_ENTRY,
59 }; 49 };
60 50
61 // Events for UMA. Do not reorder or change!
62 enum SSLInterstitialCauseCaptivePortal {
63 CAPTIVE_PORTAL_ALL,
64 CAPTIVE_PORTAL_DETECTION_ENABLED,
65 CAPTIVE_PORTAL_DETECTION_ENABLED_OVERRIDABLE,
66 CAPTIVE_PORTAL_PROBE_COMPLETED,
67 CAPTIVE_PORTAL_PROBE_COMPLETED_OVERRIDABLE,
68 CAPTIVE_PORTAL_NO_RESPONSE,
69 CAPTIVE_PORTAL_NO_RESPONSE_OVERRIDABLE,
70 CAPTIVE_PORTAL_DETECTED,
71 CAPTIVE_PORTAL_DETECTED_OVERRIDABLE,
72 UNUSED_CAPTIVE_PORTAL_EVENT,
73 };
74
75 void RecordSSLInterstitialCause(bool overridable, SSLInterstitialCause event) { 51 void RecordSSLInterstitialCause(bool overridable, SSLInterstitialCause event) {
76 if (overridable) { 52 if (overridable) {
77 UMA_HISTOGRAM_ENUMERATION("interstitial.ssl.cause.overridable", event, 53 UMA_HISTOGRAM_ENUMERATION("interstitial.ssl.cause.overridable", event,
78 UNUSED_INTERSTITIAL_CAUSE_ENTRY); 54 UNUSED_INTERSTITIAL_CAUSE_ENTRY);
79 } else { 55 } else {
80 UMA_HISTOGRAM_ENUMERATION("interstitial.ssl.cause.nonoverridable", event, 56 UMA_HISTOGRAM_ENUMERATION("interstitial.ssl.cause.nonoverridable", event,
81 UNUSED_INTERSTITIAL_CAUSE_ENTRY); 57 UNUSED_INTERSTITIAL_CAUSE_ENTRY);
82 } 58 }
83 } 59 }
84 60
85 #if defined(ENABLE_CAPTIVE_PORTAL_DETECTION)
86 void RecordCaptivePortalEventStats(SSLInterstitialCauseCaptivePortal event) {
87 UMA_HISTOGRAM_ENUMERATION("interstitial.ssl.captive_portal",
88 event,
89 UNUSED_CAPTIVE_PORTAL_EVENT);
90 }
91 #endif
92
93 int GetLevensteinDistance(const std::string& str1, 61 int GetLevensteinDistance(const std::string& str1,
94 const std::string& str2) { 62 const std::string& str2) {
95 if (str1 == str2) 63 if (str1 == str2)
96 return 0; 64 return 0;
97 if (str1.size() == 0) 65 if (str1.size() == 0)
98 return str2.size(); 66 return str2.size();
99 if (str2.size() == 0) 67 if (str2.size() == 0)
100 return str1.size(); 68 return str1.size();
101 std::vector<int> kFirstRow(str2.size() + 1, 0); 69 std::vector<int> kFirstRow(str2.size() + 1, 0);
102 std::vector<int> kSecondRow(str2.size() + 1, 0); 70 std::vector<int> kSecondRow(str2.size() + 1, 0);
(...skipping 11 matching lines...) Expand all
114 kFirstRow[j] = kSecondRow[j]; 82 kFirstRow[j] = kSecondRow[j];
115 } 83 }
116 return kSecondRow[str2.size()]; 84 return kSecondRow[str2.size()];
117 } 85 }
118 86
119 // The time to use when doing build time operations in browser tests. 87 // The time to use when doing build time operations in browser tests.
120 base::Time g_testing_build_time; 88 base::Time g_testing_build_time;
121 89
122 } // namespace 90 } // namespace
123 91
124 SSLErrorClassification::SSLErrorClassification( 92 SSLErrorClassification::SSLErrorClassification(const base::Time& current_time,
125 content::WebContents* web_contents, 93 const GURL& url,
126 const base::Time& current_time, 94 int cert_error,
127 const GURL& url, 95 const net::X509Certificate& cert)
128 int cert_error, 96 : current_time_(current_time),
129 const net::X509Certificate& cert) 97 request_url_(url),
130 : web_contents_(web_contents), 98 cert_error_(cert_error),
131 current_time_(current_time), 99 cert_(cert) {}
132 request_url_(url),
133 cert_error_(cert_error),
134 cert_(cert),
135 captive_portal_detection_enabled_(false),
136 captive_portal_probe_completed_(false),
137 captive_portal_no_response_(false),
138 captive_portal_detected_(false) {
139 #if defined(ENABLE_CAPTIVE_PORTAL_DETECTION)
140 Profile* profile = Profile::FromBrowserContext(
141 web_contents_->GetBrowserContext());
142 captive_portal_detection_enabled_ =
143 CaptivePortalServiceFactory::GetForProfile(profile)->enabled();
144 registrar_.Add(this,
145 chrome::NOTIFICATION_CAPTIVE_PORTAL_CHECK_RESULT,
146 content::Source<Profile>(profile));
147 #endif
148 }
149 100
150 SSLErrorClassification::~SSLErrorClassification() { } 101 SSLErrorClassification::~SSLErrorClassification() { }
151 102
152 void SSLErrorClassification::RecordCaptivePortalUMAStatistics(
153 bool overridable) const {
154 #if defined(ENABLE_CAPTIVE_PORTAL_DETECTION)
155 RecordCaptivePortalEventStats(CAPTIVE_PORTAL_ALL);
156 if (captive_portal_detection_enabled_)
157 RecordCaptivePortalEventStats(
158 overridable ?
159 CAPTIVE_PORTAL_DETECTION_ENABLED_OVERRIDABLE :
160 CAPTIVE_PORTAL_DETECTION_ENABLED);
161 if (captive_portal_probe_completed_)
162 RecordCaptivePortalEventStats(
163 overridable ?
164 CAPTIVE_PORTAL_PROBE_COMPLETED_OVERRIDABLE :
165 CAPTIVE_PORTAL_PROBE_COMPLETED);
166 // Log only one of portal detected and no response results.
167 if (captive_portal_detected_)
168 RecordCaptivePortalEventStats(
169 overridable ?
170 CAPTIVE_PORTAL_DETECTED_OVERRIDABLE :
171 CAPTIVE_PORTAL_DETECTED);
172 else if (captive_portal_no_response_)
173 RecordCaptivePortalEventStats(
174 overridable ?
175 CAPTIVE_PORTAL_NO_RESPONSE_OVERRIDABLE :
176 CAPTIVE_PORTAL_NO_RESPONSE);
177 #endif
178 }
179
180 void SSLErrorClassification::RecordUMAStatistics( 103 void SSLErrorClassification::RecordUMAStatistics(
181 bool overridable) const { 104 bool overridable) const {
182 ssl_errors::ErrorInfo::ErrorType type = 105 ssl_errors::ErrorInfo::ErrorType type =
183 ssl_errors::ErrorInfo::NetErrorToErrorType(cert_error_); 106 ssl_errors::ErrorInfo::NetErrorToErrorType(cert_error_);
184 UMA_HISTOGRAM_ENUMERATION("interstitial.ssl_error_type", type, 107 UMA_HISTOGRAM_ENUMERATION("interstitial.ssl_error_type", type,
185 ssl_errors::ErrorInfo::END_OF_ENUM); 108 ssl_errors::ErrorInfo::END_OF_ENUM);
186 switch (type) { 109 switch (type) {
187 case ssl_errors::ErrorInfo::CERT_DATE_INVALID: { 110 case ssl_errors::ErrorInfo::CERT_DATE_INVALID: {
188 if (IsUserClockInThePast(base::Time::NowFromSystemTime())) { 111 if (IsUserClockInThePast(base::Time::NowFromSystemTime())) {
189 RecordSSLInterstitialCause(overridable, CLOCK_PAST); 112 RecordSSLInterstitialCause(overridable, CLOCK_PAST);
(...skipping 28 matching lines...) Expand all
218 RecordSSLInterstitialCause(overridable, HOST_NAME_NOT_KNOWN_TLD); 141 RecordSSLInterstitialCause(overridable, HOST_NAME_NOT_KNOWN_TLD);
219 } 142 }
220 break; 143 break;
221 } 144 }
222 case ssl_errors::ErrorInfo::CERT_AUTHORITY_INVALID: { 145 case ssl_errors::ErrorInfo::CERT_AUTHORITY_INVALID: {
223 const std::string& hostname = request_url_.HostNoBrackets(); 146 const std::string& hostname = request_url_.HostNoBrackets();
224 if (net::IsLocalhost(hostname)) 147 if (net::IsLocalhost(hostname))
225 RecordSSLInterstitialCause(overridable, LOCALHOST); 148 RecordSSLInterstitialCause(overridable, LOCALHOST);
226 if (IsHostnameNonUniqueOrDotless(hostname)) 149 if (IsHostnameNonUniqueOrDotless(hostname))
227 RecordSSLInterstitialCause(overridable, PRIVATE_URL); 150 RecordSSLInterstitialCause(overridable, PRIVATE_URL);
228 if (captive_portal_probe_completed_ && captive_portal_detected_)
229 RecordSSLInterstitialCause(overridable, AUTHORITY_ERROR_CAPTIVE_PORTAL);
230 if (net::X509Certificate::IsSelfSigned(cert_.os_cert_handle())) 151 if (net::X509Certificate::IsSelfSigned(cert_.os_cert_handle()))
231 RecordSSLInterstitialCause(overridable, SELF_SIGNED); 152 RecordSSLInterstitialCause(overridable, SELF_SIGNED);
232 break; 153 break;
233 } 154 }
234 default: 155 default:
235 break; 156 break;
236 } 157 }
237 UMA_HISTOGRAM_ENUMERATION("interstitial.ssl.connection_type", 158 UMA_HISTOGRAM_ENUMERATION("interstitial.ssl.connection_type",
238 net::NetworkChangeNotifier::GetConnectionType(), 159 net::NetworkChangeNotifier::GetConnectionType(),
239 net::NetworkChangeNotifier::CONNECTION_LAST); 160 net::NetworkChangeNotifier::CONNECTION_LAST);
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after
514 return std::find(dns_names_domain.begin(), dns_names_domain.end() - 1, 435 return std::find(dns_names_domain.begin(), dns_names_domain.end() - 1,
515 host_name_domain) != dns_names_domain.end() - 1; 436 host_name_domain) != dns_names_domain.end() - 1;
516 } 437 }
517 438
518 // static 439 // static
519 bool SSLErrorClassification::IsHostnameNonUniqueOrDotless( 440 bool SSLErrorClassification::IsHostnameNonUniqueOrDotless(
520 const std::string& hostname) { 441 const std::string& hostname) {
521 return net::IsHostnameNonUnique(hostname) || 442 return net::IsHostnameNonUnique(hostname) ||
522 hostname.find('.') == std::string::npos; 443 hostname.find('.') == std::string::npos;
523 } 444 }
524
525 void SSLErrorClassification::Observe(
526 int type,
527 const content::NotificationSource& source,
528 const content::NotificationDetails& details) {
529 #if defined(ENABLE_CAPTIVE_PORTAL_DETECTION)
530 // When detection is disabled, captive portal service always sends
531 // RESULT_INTERNET_CONNECTED. Ignore any probe results in that case.
532 if (!captive_portal_detection_enabled_)
533 return;
534 if (type == chrome::NOTIFICATION_CAPTIVE_PORTAL_CHECK_RESULT) {
535 captive_portal_probe_completed_ = true;
536 CaptivePortalService::Results* results =
537 content::Details<CaptivePortalService::Results>(details).ptr();
538 // If a captive portal was detected at any point when the interstitial was
539 // displayed, assume that the interstitial was caused by a captive portal.
540 // Example scenario:
541 // 1- Interstitial displayed and captive portal detected, setting the flag.
542 // 2- Captive portal detection automatically opens portal login page.
543 // 3- User logs in on the portal login page.
544 // A notification will be received here for RESULT_INTERNET_CONNECTED. Make
545 // sure we don't clear the captive protal flag, since the interstitial was
546 // potentially caused by the captive portal.
547 captive_portal_detected_ = captive_portal_detected_ ||
548 (results->result == captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL);
549 // Also keep track of non-HTTP portals and error cases.
550 captive_portal_no_response_ = captive_portal_no_response_ ||
551 (results->result == captive_portal::RESULT_NO_RESPONSE);
552 }
553 #endif
554 }
OLDNEW
« no previous file with comments | « chrome/browser/ssl/ssl_error_classification.h ('k') | chrome/browser/ssl/ssl_error_classification_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698