| 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 |