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

Side by Side Diff: chrome/browser/ssl/ssl_blocking_page.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 (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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_blocking_page.h" 5 #include "chrome/browser/ssl/ssl_blocking_page.h"
6 6
7 #include "base/build_time.h" 7 #include "base/build_time.h"
8 #include "base/command_line.h" 8 #include "base/command_line.h"
9 #include "base/i18n/rtl.h" 9 #include "base/i18n/rtl.h"
10 #include "base/i18n/time_formatting.h" 10 #include "base/i18n/time_formatting.h"
(...skipping 27 matching lines...) Expand all
38 #include "content/public/common/ssl_status.h" 38 #include "content/public/common/ssl_status.h"
39 #include "grit/browser_resources.h" 39 #include "grit/browser_resources.h"
40 #include "net/base/hash_value.h" 40 #include "net/base/hash_value.h"
41 #include "net/base/net_errors.h" 41 #include "net/base/net_errors.h"
42 #include "net/base/net_util.h" 42 #include "net/base/net_util.h"
43 #include "ui/base/l10n/l10n_util.h" 43 #include "ui/base/l10n/l10n_util.h"
44 #include "ui/base/resource/resource_bundle.h" 44 #include "ui/base/resource/resource_bundle.h"
45 #include "ui/base/webui/jstemplate_builder.h" 45 #include "ui/base/webui/jstemplate_builder.h"
46 #include "ui/base/webui/web_ui_util.h" 46 #include "ui/base/webui/web_ui_util.h"
47 47
48 #if defined(ENABLE_CAPTIVE_PORTAL_DETECTION)
49 #include "chrome/browser/captive_portal/captive_portal_service.h"
50 #include "chrome/browser/captive_portal/captive_portal_service_factory.h"
51 #endif
52
53 #if defined(ENABLE_EXTENSIONS) 48 #if defined(ENABLE_EXTENSIONS)
54 #include "chrome/browser/extensions/api/experience_sampling_private/experience_s ampling.h" 49 #include "chrome/browser/extensions/api/experience_sampling_private/experience_s ampling.h"
55 #endif 50 #endif
56 51
57 #if defined(OS_WIN) 52 #if defined(OS_WIN)
58 #include "base/base_paths_win.h" 53 #include "base/base_paths_win.h"
59 #include "base/path_service.h" 54 #include "base/path_service.h"
60 #include "base/strings/string16.h" 55 #include "base/strings/string16.h"
61 #include "base/win/windows_version.h" 56 #include "base/win/windows_version.h"
62 #endif 57 #endif
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
98 DONT_PROCEED_NAME, 93 DONT_PROCEED_NAME,
99 DONT_PROCEED_DATE, 94 DONT_PROCEED_DATE,
100 DONT_PROCEED_AUTHORITY, 95 DONT_PROCEED_AUTHORITY,
101 MORE, 96 MORE,
102 SHOW_UNDERSTAND, // Used by the summer 2013 Finch trial. Deprecated. 97 SHOW_UNDERSTAND, // Used by the summer 2013 Finch trial. Deprecated.
103 SHOW_INTERNAL_HOSTNAME, 98 SHOW_INTERNAL_HOSTNAME,
104 PROCEED_INTERNAL_HOSTNAME, 99 PROCEED_INTERNAL_HOSTNAME,
105 SHOW_NEW_SITE, 100 SHOW_NEW_SITE,
106 PROCEED_NEW_SITE, 101 PROCEED_NEW_SITE,
107 PROCEED_MANUAL_NONOVERRIDABLE, 102 PROCEED_MANUAL_NONOVERRIDABLE,
108 CAPTIVE_PORTAL_DETECTION_ENABLED, 103 // Captive Portal errors moved to ssl_error_classification.
109 CAPTIVE_PORTAL_DETECTION_ENABLED_OVERRIDABLE, 104 DEPRECATED_CAPTIVE_PORTAL_DETECTION_ENABLED,
110 CAPTIVE_PORTAL_PROBE_COMPLETED, 105 DEPRECATED_CAPTIVE_PORTAL_DETECTION_ENABLED_OVERRIDABLE,
111 CAPTIVE_PORTAL_PROBE_COMPLETED_OVERRIDABLE, 106 DEPRECATED_CAPTIVE_PORTAL_PROBE_COMPLETED,
112 CAPTIVE_PORTAL_NO_RESPONSE, 107 DEPRECATED_CAPTIVE_PORTAL_PROBE_COMPLETED_OVERRIDABLE,
113 CAPTIVE_PORTAL_NO_RESPONSE_OVERRIDABLE, 108 DEPRECATED_CAPTIVE_PORTAL_NO_RESPONSE,
114 CAPTIVE_PORTAL_DETECTED, 109 DEPRECATED_CAPTIVE_PORTAL_NO_RESPONSE_OVERRIDABLE,
115 CAPTIVE_PORTAL_DETECTED_OVERRIDABLE, 110 DEPRECATED_CAPTIVE_PORTAL_DETECTED,
111 DEPRECATED_CAPTIVE_PORTAL_DETECTED_OVERRIDABLE,
116 UNUSED_BLOCKING_PAGE_EVENT, 112 UNUSED_BLOCKING_PAGE_EVENT,
117 }; 113 };
118 114
119 // Events for UMA. Do not reorder or change! 115 // Events for UMA. Do not reorder or change!
120 enum SSLExpirationAndDecision { 116 enum SSLExpirationAndDecision {
121 EXPIRED_AND_PROCEED, 117 EXPIRED_AND_PROCEED,
122 EXPIRED_AND_DO_NOT_PROCEED, 118 EXPIRED_AND_DO_NOT_PROCEED,
123 NOT_EXPIRED_AND_PROCEED, 119 NOT_EXPIRED_AND_PROCEED,
124 NOT_EXPIRED_AND_DO_NOT_PROCEED, 120 NOT_EXPIRED_AND_DO_NOT_PROCEED,
125 END_OF_SSL_EXPIRATION_AND_DECISION, 121 END_OF_SSL_EXPIRATION_AND_DECISION,
(...skipping 29 matching lines...) Expand all
155 event, 151 event,
156 END_OF_SSL_EXPIRATION_AND_DECISION); 152 END_OF_SSL_EXPIRATION_AND_DECISION);
157 } 153 }
158 } 154 }
159 155
160 void RecordSSLBlockingPageDetailedStats(bool proceed, 156 void RecordSSLBlockingPageDetailedStats(bool proceed,
161 int cert_error, 157 int cert_error,
162 bool overridable, 158 bool overridable,
163 bool internal, 159 bool internal,
164 int num_visits, 160 int num_visits,
165 bool captive_portal_detection_enabled,
166 bool captive_portal_probe_completed,
167 bool captive_portal_no_response,
168 bool captive_portal_detected,
169 bool expired_but_previously_allowed) { 161 bool expired_but_previously_allowed) {
170 UMA_HISTOGRAM_ENUMERATION("interstitial.ssl_error_type", 162 UMA_HISTOGRAM_ENUMERATION("interstitial.ssl_error_type",
171 SSLErrorInfo::NetErrorToErrorType(cert_error), SSLErrorInfo::END_OF_ENUM); 163 SSLErrorInfo::NetErrorToErrorType(cert_error), SSLErrorInfo::END_OF_ENUM);
172 RecordSSLExpirationPageEventState( 164 RecordSSLExpirationPageEventState(
173 expired_but_previously_allowed, proceed, overridable); 165 expired_but_previously_allowed, proceed, overridable);
174 #if defined(ENABLE_CAPTIVE_PORTAL_DETECTION)
175 if (captive_portal_detection_enabled)
176 RecordSSLBlockingPageEventStats(
177 overridable ?
178 CAPTIVE_PORTAL_DETECTION_ENABLED_OVERRIDABLE :
179 CAPTIVE_PORTAL_DETECTION_ENABLED);
180 if (captive_portal_probe_completed)
181 RecordSSLBlockingPageEventStats(
182 overridable ?
183 CAPTIVE_PORTAL_PROBE_COMPLETED_OVERRIDABLE :
184 CAPTIVE_PORTAL_PROBE_COMPLETED);
185 // Log only one of portal detected and no response results.
186 if (captive_portal_detected)
187 RecordSSLBlockingPageEventStats(
188 overridable ?
189 CAPTIVE_PORTAL_DETECTED_OVERRIDABLE :
190 CAPTIVE_PORTAL_DETECTED);
191 else if (captive_portal_no_response)
192 RecordSSLBlockingPageEventStats(
193 overridable ?
194 CAPTIVE_PORTAL_NO_RESPONSE_OVERRIDABLE :
195 CAPTIVE_PORTAL_NO_RESPONSE);
196 #endif
197 if (!overridable) { 166 if (!overridable) {
198 if (proceed) { 167 if (proceed) {
199 RecordSSLBlockingPageEventStats(PROCEED_MANUAL_NONOVERRIDABLE); 168 RecordSSLBlockingPageEventStats(PROCEED_MANUAL_NONOVERRIDABLE);
200 } 169 }
201 // Overridable is false if the user didn't have any option except to turn 170 // Overridable is false if the user didn't have any option except to turn
202 // back. If that's the case, don't record some of the metrics. 171 // back. If that's the case, don't record some of the metrics.
203 return; 172 return;
204 } 173 }
205 if (num_visits == 0) 174 if (num_visits == 0)
206 RecordSSLBlockingPageEventStats(SHOW_NEW_SITE); 175 RecordSSLBlockingPageEventStats(SHOW_NEW_SITE);
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
339 web_contents_(web_contents), 308 web_contents_(web_contents),
340 cert_error_(cert_error), 309 cert_error_(cert_error),
341 ssl_info_(ssl_info), 310 ssl_info_(ssl_info),
342 request_url_(request_url), 311 request_url_(request_url),
343 overridable_(options_mask & OVERRIDABLE && 312 overridable_(options_mask & OVERRIDABLE &&
344 !(options_mask & STRICT_ENFORCEMENT)), 313 !(options_mask & STRICT_ENFORCEMENT)),
345 strict_enforcement_((options_mask & STRICT_ENFORCEMENT) != 0), 314 strict_enforcement_((options_mask & STRICT_ENFORCEMENT) != 0),
346 interstitial_page_(NULL), 315 interstitial_page_(NULL),
347 internal_(false), 316 internal_(false),
348 num_visits_(-1), 317 num_visits_(-1),
349 captive_portal_detection_enabled_(false),
350 captive_portal_probe_completed_(false),
351 captive_portal_no_response_(false),
352 captive_portal_detected_(false),
353 expired_but_previously_allowed_( 318 expired_but_previously_allowed_(
354 (options_mask & EXPIRED_BUT_PREVIOUSLY_ALLOWED) != 0) { 319 (options_mask & EXPIRED_BUT_PREVIOUSLY_ALLOWED) != 0) {
355 Profile* profile = Profile::FromBrowserContext( 320 Profile* profile = Profile::FromBrowserContext(
356 web_contents->GetBrowserContext()); 321 web_contents->GetBrowserContext());
357 // For UMA stats. 322 // For UMA stats.
358 if (net::IsHostnameNonUnique(request_url_.HostNoBrackets())) 323 if (net::IsHostnameNonUnique(request_url_.HostNoBrackets()))
359 internal_ = true; 324 internal_ = true;
360 RecordSSLBlockingPageEventStats(SHOW_ALL); 325 RecordSSLBlockingPageEventStats(SHOW_ALL);
361 if (overridable_) { 326 if (overridable_) {
362 RecordSSLBlockingPageEventStats(SHOW_OVERRIDABLE); 327 RecordSSLBlockingPageEventStats(SHOW_OVERRIDABLE);
363 if (internal_) 328 if (internal_)
364 RecordSSLBlockingPageEventStats(SHOW_INTERNAL_HOSTNAME); 329 RecordSSLBlockingPageEventStats(SHOW_INTERNAL_HOSTNAME);
365 HistoryService* history_service = HistoryServiceFactory::GetForProfile( 330 HistoryService* history_service = HistoryServiceFactory::GetForProfile(
366 profile, Profile::EXPLICIT_ACCESS); 331 profile, Profile::EXPLICIT_ACCESS);
367 if (history_service) { 332 if (history_service) {
368 history_service->GetVisibleVisitCountToHost( 333 history_service->GetVisibleVisitCountToHost(
369 request_url_, 334 request_url_,
370 base::Bind(&SSLBlockingPage::OnGotHistoryCount, 335 base::Bind(&SSLBlockingPage::OnGotHistoryCount,
371 base::Unretained(this)), 336 base::Unretained(this)),
372 &request_tracker_); 337 &request_tracker_);
373 } 338 }
374 } 339 }
375 340
376 SSLErrorClassification ssl_error_classification( 341 ssl_error_classification_.reset(new SSLErrorClassification(
342 web_contents_,
377 base::Time::NowFromSystemTime(), 343 base::Time::NowFromSystemTime(),
378 request_url_, 344 request_url_,
379 *ssl_info_.cert.get()); 345 cert_error_,
380 ssl_error_classification.RecordUMAStatistics(overridable_, cert_error_); 346 *ssl_info_.cert.get()));
347 ssl_error_classification_->RecordUMAStatistics(overridable_);
381 348
382 #if defined(ENABLE_CAPTIVE_PORTAL_DETECTION) 349 #if defined(ENABLE_CAPTIVE_PORTAL_DETECTION)
383 CaptivePortalService* captive_portal_service = 350 ssl_error_classification_->RecordCaptivePortalUMAStatistics(overridable_);
384 CaptivePortalServiceFactory::GetForProfile(profile);
385 captive_portal_detection_enabled_ = captive_portal_service ->enabled();
386 captive_portal_service ->DetectCaptivePortal();
387 registrar_.Add(this,
388 chrome::NOTIFICATION_CAPTIVE_PORTAL_CHECK_RESULT,
389 content::Source<Profile>(profile));
390 #endif 351 #endif
391 352
392 #if defined(ENABLE_EXTENSIONS) 353 #if defined(ENABLE_EXTENSIONS)
393 // ExperienceSampling: Set up new sampling event for this interstitial. 354 // ExperienceSampling: Set up new sampling event for this interstitial.
394 std::string event_name(kEventNameBase); 355 std::string event_name(kEventNameBase);
395 if (overridable_ && !strict_enforcement_) 356 if (overridable_ && !strict_enforcement_)
396 event_name.append(kEventOverridable); 357 event_name.append(kEventOverridable);
397 else 358 else
398 event_name.append(kEventNotOverridable); 359 event_name.append(kEventNotOverridable);
399 event_name.append(net::ErrorToString(cert_error_)); 360 event_name.append(net::ErrorToString(cert_error_));
400 sampling_event_.reset(new ExperienceSamplingEvent( 361 sampling_event_.reset(new ExperienceSamplingEvent(
401 event_name, 362 event_name,
402 request_url_, 363 request_url_,
403 web_contents_->GetLastCommittedURL(), 364 web_contents_->GetLastCommittedURL(),
404 web_contents_->GetBrowserContext())); 365 web_contents_->GetBrowserContext()));
405 #endif 366 #endif
406 367
407 // Creating an interstitial without showing (e.g. from chrome://interstitials) 368 // Creating an interstitial without showing (e.g. from chrome://interstitials)
408 // it leaks memory, so don't create it here. 369 // it leaks memory, so don't create it here.
409 } 370 }
410 371
411 SSLBlockingPage::~SSLBlockingPage() { 372 SSLBlockingPage::~SSLBlockingPage() {
373 // InvalidCommonNameSeverityScore() and InvalidDateSeverityScore() are in the
374 // destructor because they depend on knowing whether captive portal detection
375 // happened before the user made a decision.
376 SSLErrorInfo::ErrorType type =
377 SSLErrorInfo::NetErrorToErrorType(cert_error_);
378 switch (type) {
379 case SSLErrorInfo::CERT_DATE_INVALID: {
palmer 2014/08/30 00:28:19 Nit: These case blocks don't need { } because no n
felt 2014/08/30 01:11:52 Done.
380 ssl_error_classification_->InvalidDateSeverityScore();
381 break;
382 }
383 case SSLErrorInfo::CERT_COMMON_NAME_INVALID: {
384 ssl_error_classification_->InvalidCommonNameSeverityScore();
385 break;
386 }
387 default:
388 break;
389 }
412 if (!callback_.is_null()) { 390 if (!callback_.is_null()) {
413 RecordSSLBlockingPageDetailedStats(false, 391 RecordSSLBlockingPageDetailedStats(false,
414 cert_error_, 392 cert_error_,
415 overridable_, 393 overridable_,
416 internal_, 394 internal_,
417 num_visits_, 395 num_visits_,
418 captive_portal_detection_enabled_,
419 captive_portal_probe_completed_,
420 captive_portal_no_response_,
421 captive_portal_detected_,
422 expired_but_previously_allowed_); 396 expired_but_previously_allowed_);
423 // The page is closed without the user having chosen what to do, default to 397 // The page is closed without the user having chosen what to do, default to
424 // deny. 398 // deny.
425 NotifyDenyCertificate(); 399 NotifyDenyCertificate();
426 } 400 }
427 } 401 }
428 402
429 void SSLBlockingPage::Show() { 403 void SSLBlockingPage::Show() {
430 DCHECK(!interstitial_page_); 404 DCHECK(!interstitial_page_);
431 interstitial_page_ = InterstitialPage::Create( 405 interstitial_page_ = InterstitialPage::Create(
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
608 web_contents_->GetBrowserContext()); 582 web_contents_->GetBrowserContext());
609 renderer_preferences_util::UpdateFromSystemSettings(prefs, profile); 583 renderer_preferences_util::UpdateFromSystemSettings(prefs, profile);
610 } 584 }
611 585
612 void SSLBlockingPage::OnProceed() { 586 void SSLBlockingPage::OnProceed() {
613 RecordSSLBlockingPageDetailedStats(true, 587 RecordSSLBlockingPageDetailedStats(true,
614 cert_error_, 588 cert_error_,
615 overridable_, 589 overridable_,
616 internal_, 590 internal_,
617 num_visits_, 591 num_visits_,
618 captive_portal_detection_enabled_,
619 captive_portal_probe_completed_,
620 captive_portal_no_response_,
621 captive_portal_detected_,
622 expired_but_previously_allowed_); 592 expired_but_previously_allowed_);
623 #if defined(ENABLE_EXTENSIONS) 593 #if defined(ENABLE_EXTENSIONS)
624 // ExperienceSampling: Notify that user decided to proceed. 594 // ExperienceSampling: Notify that user decided to proceed.
625 if (sampling_event_.get()) 595 if (sampling_event_.get())
626 sampling_event_->CreateUserDecisionEvent(ExperienceSamplingEvent::kProceed); 596 sampling_event_->CreateUserDecisionEvent(ExperienceSamplingEvent::kProceed);
627 #endif 597 #endif
598
628 // Accepting the certificate resumes the loading of the page. 599 // Accepting the certificate resumes the loading of the page.
629 NotifyAllowCertificate(); 600 NotifyAllowCertificate();
630 } 601 }
631 602
632 void SSLBlockingPage::OnDontProceed() { 603 void SSLBlockingPage::OnDontProceed() {
633 RecordSSLBlockingPageDetailedStats(false, 604 RecordSSLBlockingPageDetailedStats(false,
634 cert_error_, 605 cert_error_,
635 overridable_, 606 overridable_,
636 internal_, 607 internal_,
637 num_visits_, 608 num_visits_,
638 captive_portal_detection_enabled_,
639 captive_portal_probe_completed_,
640 captive_portal_no_response_,
641 captive_portal_detected_,
642 expired_but_previously_allowed_); 609 expired_but_previously_allowed_);
643 #if defined(ENABLE_EXTENSIONS) 610 #if defined(ENABLE_EXTENSIONS)
644 // ExperienceSampling: Notify that user decided to not proceed. 611 // ExperienceSampling: Notify that user decided to not proceed.
645 // This also occurs if the user navigates away or closes the tab. 612 // This also occurs if the user navigates away or closes the tab.
646 if (sampling_event_.get()) 613 if (sampling_event_.get())
647 sampling_event_->CreateUserDecisionEvent(ExperienceSamplingEvent::kDeny); 614 sampling_event_->CreateUserDecisionEvent(ExperienceSamplingEvent::kDeny);
648 #endif 615 #endif
649 NotifyDenyCertificate(); 616 NotifyDenyCertificate();
650 } 617 }
651 618
(...skipping 30 matching lines...) Expand all
682 for (; i < 5; i++) { 649 for (; i < 5; i++) {
683 strings->SetString(keys[i], std::string()); 650 strings->SetString(keys[i], std::string());
684 } 651 }
685 } 652 }
686 653
687 void SSLBlockingPage::OnGotHistoryCount(bool success, 654 void SSLBlockingPage::OnGotHistoryCount(bool success,
688 int num_visits, 655 int num_visits,
689 base::Time first_visit) { 656 base::Time first_visit) {
690 num_visits_ = num_visits; 657 num_visits_ = num_visits;
691 } 658 }
692
693 void SSLBlockingPage::Observe(
694 int type,
695 const content::NotificationSource& source,
696 const content::NotificationDetails& details) {
697 #if defined(ENABLE_CAPTIVE_PORTAL_DETECTION)
698 // When detection is disabled, captive portal service always sends
699 // RESULT_INTERNET_CONNECTED. Ignore any probe results in that case.
700 if (!captive_portal_detection_enabled_)
701 return;
702 if (type == chrome::NOTIFICATION_CAPTIVE_PORTAL_CHECK_RESULT) {
703 captive_portal_probe_completed_ = true;
704 CaptivePortalService::Results* results =
705 content::Details<CaptivePortalService::Results>(
706 details).ptr();
707 // If a captive portal was detected at any point when the interstitial was
708 // displayed, assume that the interstitial was caused by a captive portal.
709 // Example scenario:
710 // 1- Interstitial displayed and captive portal detected, setting the flag.
711 // 2- Captive portal detection automatically opens portal login page.
712 // 3- User logs in on the portal login page.
713 // A notification will be received here for RESULT_INTERNET_CONNECTED. Make
714 // sure we don't clear the captive portal flag, since the interstitial was
715 // potentially caused by the captive portal.
716 captive_portal_detected_ = captive_portal_detected_ ||
717 (results->result == captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL);
718 // Also keep track of non-HTTP portals and error cases.
719 captive_portal_no_response_ = captive_portal_no_response_ ||
720 (results->result == captive_portal::RESULT_NO_RESPONSE);
721 }
722 #endif
723 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698