OLD | NEW |
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 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
80 | 80 |
81 // Events for UMA. Do not reorder or change! | 81 // Events for UMA. Do not reorder or change! |
82 enum SSLExpirationAndDecision { | 82 enum SSLExpirationAndDecision { |
83 EXPIRED_AND_PROCEED, | 83 EXPIRED_AND_PROCEED, |
84 EXPIRED_AND_DO_NOT_PROCEED, | 84 EXPIRED_AND_DO_NOT_PROCEED, |
85 NOT_EXPIRED_AND_PROCEED, | 85 NOT_EXPIRED_AND_PROCEED, |
86 NOT_EXPIRED_AND_DO_NOT_PROCEED, | 86 NOT_EXPIRED_AND_DO_NOT_PROCEED, |
87 END_OF_SSL_EXPIRATION_AND_DECISION, | 87 END_OF_SSL_EXPIRATION_AND_DECISION, |
88 }; | 88 }; |
89 | 89 |
| 90 // Rappor prefix |
| 91 const char kSSLRapporPrefix[] = "ssl"; |
| 92 |
90 void RecordSSLExpirationPageEventState(bool expired_but_previously_allowed, | 93 void RecordSSLExpirationPageEventState(bool expired_but_previously_allowed, |
91 bool proceed, | 94 bool proceed, |
92 bool overridable) { | 95 bool overridable) { |
93 SSLExpirationAndDecision event; | 96 SSLExpirationAndDecision event; |
94 if (expired_but_previously_allowed && proceed) | 97 if (expired_but_previously_allowed && proceed) |
95 event = EXPIRED_AND_PROCEED; | 98 event = EXPIRED_AND_PROCEED; |
96 else if (expired_but_previously_allowed && !proceed) | 99 else if (expired_but_previously_allowed && !proceed) |
97 event = EXPIRED_AND_DO_NOT_PROCEED; | 100 event = EXPIRED_AND_DO_NOT_PROCEED; |
98 else if (!expired_but_previously_allowed && proceed) | 101 else if (!expired_but_previously_allowed && proceed) |
99 event = NOT_EXPIRED_AND_PROCEED; | 102 event = NOT_EXPIRED_AND_PROCEED; |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
226 ssl_info_(ssl_info), | 229 ssl_info_(ssl_info), |
227 overridable_(IsOptionsOverridable(options_mask)), | 230 overridable_(IsOptionsOverridable(options_mask)), |
228 danger_overridable_(true), | 231 danger_overridable_(true), |
229 strict_enforcement_((options_mask & STRICT_ENFORCEMENT) != 0), | 232 strict_enforcement_((options_mask & STRICT_ENFORCEMENT) != 0), |
230 expired_but_previously_allowed_( | 233 expired_but_previously_allowed_( |
231 (options_mask & EXPIRED_BUT_PREVIOUSLY_ALLOWED) != 0) { | 234 (options_mask & EXPIRED_BUT_PREVIOUSLY_ALLOWED) != 0) { |
232 interstitial_reason_ = | 235 interstitial_reason_ = |
233 IsErrorDueToBadClock(base::Time::NowFromSystemTime(), cert_error_) ? | 236 IsErrorDueToBadClock(base::Time::NowFromSystemTime(), cert_error_) ? |
234 SSL_REASON_BAD_CLOCK : SSL_REASON_SSL; | 237 SSL_REASON_BAD_CLOCK : SSL_REASON_SSL; |
235 | 238 |
| 239 // We collapse the Rappor metric name to just "ssl" so we don't leak |
| 240 // the "overridable" bit. We skip Rappor altogether for bad clocks. |
236 // This must be done after calculating |interstitial_reason_| above. | 241 // This must be done after calculating |interstitial_reason_| above. |
237 uma_helper_.reset(new SecurityInterstitialUmaHelper( | 242 metrics_helper_.reset(new SecurityInterstitialMetricsHelper( |
238 web_contents, request_url, GetHistogramPrefix(), GetSamplingEventName())); | 243 web_contents, request_url, GetUmaHistogramPrefix(), kSSLRapporPrefix, |
239 uma_helper_->RecordUserDecision(SecurityInterstitialUmaHelper::SHOW); | 244 (interstitial_reason_ == SSL_REASON_BAD_CLOCK |
240 uma_helper_->RecordUserInteraction( | 245 ? SecurityInterstitialMetricsHelper::SKIP_RAPPOR |
241 SecurityInterstitialUmaHelper::TOTAL_VISITS); | 246 : SecurityInterstitialMetricsHelper::REPORT_RAPPOR), |
| 247 GetSamplingEventName())); |
| 248 |
| 249 metrics_helper_->RecordUserDecision(SecurityInterstitialMetricsHelper::SHOW); |
| 250 metrics_helper_->RecordUserInteraction( |
| 251 SecurityInterstitialMetricsHelper::TOTAL_VISITS); |
242 | 252 |
243 ssl_error_classification_.reset(new SSLErrorClassification( | 253 ssl_error_classification_.reset(new SSLErrorClassification( |
244 web_contents, | 254 web_contents, |
245 base::Time::NowFromSystemTime(), | 255 base::Time::NowFromSystemTime(), |
246 request_url, | 256 request_url, |
247 cert_error_, | 257 cert_error_, |
248 *ssl_info_.cert.get())); | 258 *ssl_info_.cert.get())); |
249 ssl_error_classification_->RecordUMAStatistics(overridable_); | 259 ssl_error_classification_->RecordUMAStatistics(overridable_); |
250 #if defined(ENABLE_CAPTIVE_PORTAL_DETECTION) | 260 #if defined(ENABLE_CAPTIVE_PORTAL_DETECTION) |
251 ssl_error_classification_->RecordCaptivePortalUMAStatistics(overridable_); | 261 ssl_error_classification_->RecordCaptivePortalUMAStatistics(overridable_); |
252 #endif | 262 #endif |
253 | 263 |
254 // Creating an interstitial without showing (e.g. from chrome://interstitials) | 264 // Creating an interstitial without showing (e.g. from chrome://interstitials) |
255 // it leaks memory, so don't create it here. | 265 // it leaks memory, so don't create it here. |
256 } | 266 } |
257 | 267 |
258 bool SSLBlockingPage::ShouldCreateNewNavigation() const { | 268 bool SSLBlockingPage::ShouldCreateNewNavigation() const { |
259 return true; | 269 return true; |
260 } | 270 } |
261 | 271 |
262 const void* SSLBlockingPage::GetTypeForTesting() const { | 272 const void* SSLBlockingPage::GetTypeForTesting() const { |
263 return SSLBlockingPage::kTypeForTesting; | 273 return SSLBlockingPage::kTypeForTesting; |
264 } | 274 } |
265 | 275 |
266 SSLBlockingPage::~SSLBlockingPage() { | 276 SSLBlockingPage::~SSLBlockingPage() { |
267 if (!callback_.is_null()) { | 277 if (!callback_.is_null()) { |
268 // The page is closed without the user having chosen what to do, default to | 278 // The page is closed without the user having chosen what to do, default to |
269 // deny. | 279 // deny. |
270 uma_helper_->RecordUserDecision( | 280 metrics_helper_->RecordUserDecision( |
271 SecurityInterstitialUmaHelper::DONT_PROCEED); | 281 SecurityInterstitialMetricsHelper::DONT_PROCEED); |
272 RecordSSLExpirationPageEventState( | 282 RecordSSLExpirationPageEventState( |
273 expired_but_previously_allowed_, false, overridable_); | 283 expired_but_previously_allowed_, false, overridable_); |
274 NotifyDenyCertificate(); | 284 NotifyDenyCertificate(); |
275 } | 285 } |
276 } | 286 } |
277 | 287 |
278 void SSLBlockingPage::PopulateInterstitialStrings( | 288 void SSLBlockingPage::PopulateInterstitialStrings( |
279 base::DictionaryValue* load_time_data) { | 289 base::DictionaryValue* load_time_data) { |
280 CHECK(load_time_data); | 290 CHECK(load_time_data); |
281 base::string16 url(GetFormattedHostName()); | 291 base::string16 url(GetFormattedHostName()); |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
444 interstitial_page()->DontProceed(); | 454 interstitial_page()->DontProceed(); |
445 break; | 455 break; |
446 } | 456 } |
447 case CMD_PROCEED: { | 457 case CMD_PROCEED: { |
448 if (danger_overridable_) { | 458 if (danger_overridable_) { |
449 interstitial_page()->Proceed(); | 459 interstitial_page()->Proceed(); |
450 } | 460 } |
451 break; | 461 break; |
452 } | 462 } |
453 case CMD_MORE: { | 463 case CMD_MORE: { |
454 uma_helper_->RecordUserInteraction( | 464 metrics_helper_->RecordUserInteraction( |
455 SecurityInterstitialUmaHelper::SHOW_ADVANCED); | 465 SecurityInterstitialMetricsHelper::SHOW_ADVANCED); |
456 break; | 466 break; |
457 } | 467 } |
458 case CMD_RELOAD: { | 468 case CMD_RELOAD: { |
459 uma_helper_->RecordUserInteraction( | 469 metrics_helper_->RecordUserInteraction( |
460 SecurityInterstitialUmaHelper::RELOAD); | 470 SecurityInterstitialMetricsHelper::RELOAD); |
461 // The interstitial can't refresh itself. | 471 // The interstitial can't refresh itself. |
462 web_contents()->GetController().Reload(true); | 472 web_contents()->GetController().Reload(true); |
463 break; | 473 break; |
464 } | 474 } |
465 case CMD_HELP: { | 475 case CMD_HELP: { |
466 uma_helper_->RecordUserInteraction( | 476 metrics_helper_->RecordUserInteraction( |
467 SecurityInterstitialUmaHelper::SHOW_LEARN_MORE); | 477 SecurityInterstitialMetricsHelper::SHOW_LEARN_MORE); |
468 content::NavigationController::LoadURLParams help_page_params( | 478 content::NavigationController::LoadURLParams help_page_params( |
469 google_util::AppendGoogleLocaleParam( | 479 google_util::AppendGoogleLocaleParam( |
470 GURL(kHelpURL), g_browser_process->GetApplicationLocale())); | 480 GURL(kHelpURL), g_browser_process->GetApplicationLocale())); |
471 web_contents()->GetController().LoadURLWithParams(help_page_params); | 481 web_contents()->GetController().LoadURLWithParams(help_page_params); |
472 break; | 482 break; |
473 } | 483 } |
474 case CMD_CLOCK: { | 484 case CMD_CLOCK: { |
475 uma_helper_->RecordUserInteraction( | 485 metrics_helper_->RecordUserInteraction( |
476 SecurityInterstitialUmaHelper::OPEN_TIME_SETTINGS); | 486 SecurityInterstitialMetricsHelper::OPEN_TIME_SETTINGS); |
477 LaunchDateAndTimeSettings(); | 487 LaunchDateAndTimeSettings(); |
478 break; | 488 break; |
479 } | 489 } |
480 default: { | 490 default: { |
481 NOTREACHED(); | 491 NOTREACHED(); |
482 } | 492 } |
483 } | 493 } |
484 } | 494 } |
485 | 495 |
486 void SSLBlockingPage::OverrideRendererPrefs( | 496 void SSLBlockingPage::OverrideRendererPrefs( |
487 content::RendererPreferences* prefs) { | 497 content::RendererPreferences* prefs) { |
488 Profile* profile = Profile::FromBrowserContext( | 498 Profile* profile = Profile::FromBrowserContext( |
489 web_contents()->GetBrowserContext()); | 499 web_contents()->GetBrowserContext()); |
490 renderer_preferences_util::UpdateFromSystemSettings( | 500 renderer_preferences_util::UpdateFromSystemSettings( |
491 prefs, profile, web_contents()); | 501 prefs, profile, web_contents()); |
492 } | 502 } |
493 | 503 |
494 void SSLBlockingPage::OnProceed() { | 504 void SSLBlockingPage::OnProceed() { |
495 uma_helper_->RecordUserDecision(SecurityInterstitialUmaHelper::PROCEED); | 505 metrics_helper_->RecordUserDecision( |
| 506 SecurityInterstitialMetricsHelper::PROCEED); |
496 RecordSSLExpirationPageEventState( | 507 RecordSSLExpirationPageEventState( |
497 expired_but_previously_allowed_, true, overridable_); | 508 expired_but_previously_allowed_, true, overridable_); |
498 // Accepting the certificate resumes the loading of the page. | 509 // Accepting the certificate resumes the loading of the page. |
499 NotifyAllowCertificate(); | 510 NotifyAllowCertificate(); |
500 } | 511 } |
501 | 512 |
502 void SSLBlockingPage::OnDontProceed() { | 513 void SSLBlockingPage::OnDontProceed() { |
503 uma_helper_->RecordUserDecision(SecurityInterstitialUmaHelper::DONT_PROCEED); | 514 metrics_helper_->RecordUserDecision( |
| 515 SecurityInterstitialMetricsHelper::DONT_PROCEED); |
504 RecordSSLExpirationPageEventState( | 516 RecordSSLExpirationPageEventState( |
505 expired_but_previously_allowed_, false, overridable_); | 517 expired_but_previously_allowed_, false, overridable_); |
506 NotifyDenyCertificate(); | 518 NotifyDenyCertificate(); |
507 } | 519 } |
508 | 520 |
509 void SSLBlockingPage::NotifyDenyCertificate() { | 521 void SSLBlockingPage::NotifyDenyCertificate() { |
510 // It's possible that callback_ may not exist if the user clicks "Proceed" | 522 // It's possible that callback_ may not exist if the user clicks "Proceed" |
511 // followed by pressing the back button before the interstitial is hidden. | 523 // followed by pressing the back button before the interstitial is hidden. |
512 // In that case the certificate will still be treated as allowed. | 524 // In that case the certificate will still be treated as allowed. |
513 if (callback_.is_null()) | 525 if (callback_.is_null()) |
514 return; | 526 return; |
515 | 527 |
516 callback_.Run(false); | 528 callback_.Run(false); |
517 callback_.Reset(); | 529 callback_.Reset(); |
518 } | 530 } |
519 | 531 |
520 void SSLBlockingPage::NotifyAllowCertificate() { | 532 void SSLBlockingPage::NotifyAllowCertificate() { |
521 DCHECK(!callback_.is_null()); | 533 DCHECK(!callback_.is_null()); |
522 | 534 |
523 callback_.Run(true); | 535 callback_.Run(true); |
524 callback_.Reset(); | 536 callback_.Reset(); |
525 } | 537 } |
526 | 538 |
527 std::string SSLBlockingPage::GetHistogramPrefix() const { | 539 std::string SSLBlockingPage::GetUmaHistogramPrefix() const { |
528 switch (interstitial_reason_) { | 540 switch (interstitial_reason_) { |
529 case SSL_REASON_SSL: | 541 case SSL_REASON_SSL: |
530 if (overridable_) | 542 if (overridable_) |
531 return "ssl_overridable"; | 543 return "ssl_overridable"; |
532 else | 544 else |
533 return "ssl_nonoverridable"; | 545 return "ssl_nonoverridable"; |
534 case SSL_REASON_BAD_CLOCK: | 546 case SSL_REASON_BAD_CLOCK: |
535 return "bad_clock"; | 547 return "bad_clock"; |
536 } | 548 } |
537 NOTREACHED(); | 549 NOTREACHED(); |
538 return std::string(); | 550 return std::string(); |
539 } | 551 } |
540 | 552 |
541 std::string SSLBlockingPage::GetSamplingEventName() const { | 553 std::string SSLBlockingPage::GetSamplingEventName() const { |
542 std::string event_name(kEventNameBase); | 554 std::string event_name(kEventNameBase); |
543 if (overridable_) | 555 if (overridable_) |
544 event_name.append(kEventOverridable); | 556 event_name.append(kEventOverridable); |
545 else | 557 else |
546 event_name.append(kEventNotOverridable); | 558 event_name.append(kEventNotOverridable); |
547 event_name.append(net::ErrorToString(cert_error_)); | 559 event_name.append(net::ErrorToString(cert_error_)); |
548 return event_name; | 560 return event_name; |
549 } | 561 } |
550 | 562 |
551 // static | 563 // static |
552 bool SSLBlockingPage::IsOptionsOverridable(int options_mask) { | 564 bool SSLBlockingPage::IsOptionsOverridable(int options_mask) { |
553 return (options_mask & SSLBlockingPage::OVERRIDABLE) && | 565 return (options_mask & SSLBlockingPage::OVERRIDABLE) && |
554 !(options_mask & SSLBlockingPage::STRICT_ENFORCEMENT); | 566 !(options_mask & SSLBlockingPage::STRICT_ENFORCEMENT); |
555 } | 567 } |
OLD | NEW |