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/bind.h" |
| 8 #include "base/bind_helpers.h" |
7 #include "base/build_time.h" | 9 #include "base/build_time.h" |
| 10 #include "base/callback_helpers.h" |
8 #include "base/command_line.h" | 11 #include "base/command_line.h" |
9 #include "base/i18n/rtl.h" | 12 #include "base/i18n/rtl.h" |
10 #include "base/i18n/time_formatting.h" | 13 #include "base/i18n/time_formatting.h" |
11 #include "base/metrics/field_trial.h" | 14 #include "base/metrics/field_trial.h" |
12 #include "base/metrics/histogram.h" | 15 #include "base/metrics/histogram.h" |
| 16 #include "base/prefs/pref_service.h" |
13 #include "base/process/launch.h" | 17 #include "base/process/launch.h" |
14 #include "base/strings/string_number_conversions.h" | 18 #include "base/strings/string_number_conversions.h" |
15 #include "base/strings/string_piece.h" | 19 #include "base/strings/string_piece.h" |
16 #include "base/strings/string_util.h" | 20 #include "base/strings/string_util.h" |
17 #include "base/strings/stringprintf.h" | 21 #include "base/strings/stringprintf.h" |
18 #include "base/strings/utf_string_conversions.h" | 22 #include "base/strings/utf_string_conversions.h" |
19 #include "base/time/time.h" | 23 #include "base/time/time.h" |
20 #include "base/values.h" | 24 #include "base/values.h" |
21 #include "chrome/browser/browser_process.h" | 25 #include "chrome/browser/browser_process.h" |
22 #include "chrome/browser/chrome_notification_types.h" | 26 #include "chrome/browser/chrome_notification_types.h" |
| 27 #include "chrome/browser/interstitials/security_interstitial_metrics_helper.h" |
23 #include "chrome/browser/profiles/profile.h" | 28 #include "chrome/browser/profiles/profile.h" |
24 #include "chrome/browser/renderer_preferences_util.h" | 29 #include "chrome/browser/renderer_preferences_util.h" |
| 30 #include "chrome/browser/safe_browsing/ui_manager.h" |
25 #include "chrome/browser/ssl/ssl_error_classification.h" | 31 #include "chrome/browser/ssl/ssl_error_classification.h" |
26 #include "chrome/browser/ssl/ssl_error_info.h" | 32 #include "chrome/browser/ssl/ssl_error_info.h" |
27 #include "chrome/common/chrome_switches.h" | 33 #include "chrome/common/chrome_switches.h" |
| 34 #include "chrome/common/pref_names.h" |
28 #include "chrome/grit/chromium_strings.h" | 35 #include "chrome/grit/chromium_strings.h" |
29 #include "chrome/grit/generated_resources.h" | 36 #include "chrome/grit/generated_resources.h" |
30 #include "components/google/core/browser/google_util.h" | 37 #include "components/google/core/browser/google_util.h" |
31 #include "content/public/browser/cert_store.h" | 38 #include "content/public/browser/cert_store.h" |
32 #include "content/public/browser/interstitial_page.h" | 39 #include "content/public/browser/interstitial_page.h" |
33 #include "content/public/browser/interstitial_page_delegate.h" | 40 #include "content/public/browser/interstitial_page_delegate.h" |
34 #include "content/public/browser/navigation_controller.h" | 41 #include "content/public/browser/navigation_controller.h" |
35 #include "content/public/browser/navigation_entry.h" | 42 #include "content/public/browser/navigation_entry.h" |
36 #include "content/public/browser/notification_service.h" | 43 #include "content/public/browser/notification_service.h" |
37 #include "content/public/browser/notification_types.h" | 44 #include "content/public/browser/notification_types.h" |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
212 } | 219 } |
213 | 220 |
214 } // namespace | 221 } // namespace |
215 | 222 |
216 // static | 223 // static |
217 InterstitialPageDelegate::TypeID SSLBlockingPage::kTypeForTesting = | 224 InterstitialPageDelegate::TypeID SSLBlockingPage::kTypeForTesting = |
218 &SSLBlockingPage::kTypeForTesting; | 225 &SSLBlockingPage::kTypeForTesting; |
219 | 226 |
220 // Note that we always create a navigation entry with SSL errors. | 227 // Note that we always create a navigation entry with SSL errors. |
221 // No error happening loading a sub-resource triggers an interstitial so far. | 228 // No error happening loading a sub-resource triggers an interstitial so far. |
222 SSLBlockingPage::SSLBlockingPage(content::WebContents* web_contents, | 229 SSLBlockingPage::SSLBlockingPage( |
223 int cert_error, | 230 content::WebContents* web_contents, |
224 const net::SSLInfo& ssl_info, | 231 int cert_error, |
225 const GURL& request_url, | 232 const net::SSLInfo& ssl_info, |
226 int options_mask, | 233 const GURL& request_url, |
227 const base::Time& time_triggered, | 234 int options_mask, |
228 const base::Callback<void(bool)>& callback) | 235 const base::Time& time_triggered, |
| 236 SafeBrowsingUIManager* safe_browsing_ui_manager, |
| 237 const base::Callback<void(bool)>& callback) |
229 : SecurityInterstitialPage(web_contents, request_url), | 238 : SecurityInterstitialPage(web_contents, request_url), |
230 callback_(callback), | 239 callback_(callback), |
231 cert_error_(cert_error), | 240 cert_error_(cert_error), |
232 ssl_info_(ssl_info), | 241 ssl_info_(ssl_info), |
233 overridable_(IsOptionsOverridable(options_mask)), | 242 overridable_(IsOptionsOverridable(options_mask)), |
234 danger_overridable_(true), | 243 danger_overridable_(true), |
235 strict_enforcement_((options_mask & STRICT_ENFORCEMENT) != 0), | 244 strict_enforcement_((options_mask & STRICT_ENFORCEMENT) != 0), |
236 expired_but_previously_allowed_( | 245 expired_but_previously_allowed_( |
237 (options_mask & EXPIRED_BUT_PREVIOUSLY_ALLOWED) != 0), | 246 (options_mask & EXPIRED_BUT_PREVIOUSLY_ALLOWED) != 0), |
238 time_triggered_(time_triggered) { | 247 time_triggered_(time_triggered), |
| 248 safe_browsing_ui_manager_(safe_browsing_ui_manager) { |
239 interstitial_reason_ = | 249 interstitial_reason_ = |
240 IsErrorDueToBadClock(time_triggered_, cert_error_) ? | 250 IsErrorDueToBadClock(time_triggered_, cert_error_) ? |
241 SSL_REASON_BAD_CLOCK : SSL_REASON_SSL; | 251 SSL_REASON_BAD_CLOCK : SSL_REASON_SSL; |
242 | 252 |
243 // We collapse the Rappor metric name to just "ssl" so we don't leak | 253 // We collapse the Rappor metric name to just "ssl" so we don't leak |
244 // the "overridable" bit. We skip Rappor altogether for bad clocks. | 254 // the "overridable" bit. We skip Rappor altogether for bad clocks. |
245 // This must be done after calculating |interstitial_reason_| above. | 255 // This must be done after calculating |interstitial_reason_| above. |
246 metrics_helper_.reset(new SecurityInterstitialMetricsHelper( | 256 metrics_helper_.reset(new SecurityInterstitialMetricsHelper( |
247 web_contents, request_url, GetUmaHistogramPrefix(), kSSLRapporPrefix, | 257 web_contents, request_url, GetUmaHistogramPrefix(), kSSLRapporPrefix, |
248 (interstitial_reason_ == SSL_REASON_BAD_CLOCK | 258 (interstitial_reason_ == SSL_REASON_BAD_CLOCK |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
430 load_time_data->SetString( | 440 load_time_data->SetString( |
431 "expirationDate", | 441 "expirationDate", |
432 base::TimeFormatShortDate(ssl_info_.cert->valid_expiry())); | 442 base::TimeFormatShortDate(ssl_info_.cert->valid_expiry())); |
433 load_time_data->SetString( | 443 load_time_data->SetString( |
434 "currentDate", base::TimeFormatShortDate(time_triggered_)); | 444 "currentDate", base::TimeFormatShortDate(time_triggered_)); |
435 std::vector<std::string> encoded_chain; | 445 std::vector<std::string> encoded_chain; |
436 ssl_info_.cert->GetPEMEncodedChain( | 446 ssl_info_.cert->GetPEMEncodedChain( |
437 &encoded_chain); | 447 &encoded_chain); |
438 load_time_data->SetString( | 448 load_time_data->SetString( |
439 "pem", JoinString(encoded_chain, std::string())); | 449 "pem", JoinString(encoded_chain, std::string())); |
| 450 |
| 451 PopulateExtendedReportingOption(load_time_data); |
| 452 } |
| 453 |
| 454 void SSLBlockingPage::PopulateExtendedReportingOption( |
| 455 base::DictionaryValue* load_time_data) { |
| 456 // Only show the checkbox if not off-the-record and if the |
| 457 // command-line option is set. |
| 458 const bool show = !web_contents()->GetBrowserContext()->IsOffTheRecord() && |
| 459 base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 460 switches::kEnableInvalidCertCollection); |
| 461 |
| 462 load_time_data->SetBoolean(interstitials::kDisplayCheckBox, show); |
| 463 if (!show) |
| 464 return; |
| 465 |
| 466 load_time_data->SetBoolean( |
| 467 interstitials::kBoxChecked, |
| 468 IsPrefEnabled(prefs::kSafeBrowsingExtendedReportingEnabled)); |
| 469 |
| 470 const std::string privacy_link = base::StringPrintf( |
| 471 interstitials::kPrivacyLinkHtml, CMD_OPEN_REPORTING_PRIVACY, |
| 472 l10n_util::GetStringUTF8(IDS_SAFE_BROWSING_PRIVACY_POLICY_PAGE).c_str()); |
| 473 |
| 474 load_time_data->SetString( |
| 475 interstitials::kOptInLink, |
| 476 l10n_util::GetStringFUTF16(IDS_SAFE_BROWSING_MALWARE_REPORTING_AGREE, |
| 477 base::UTF8ToUTF16(privacy_link))); |
440 } | 478 } |
441 | 479 |
442 void SSLBlockingPage::OverrideEntry(NavigationEntry* entry) { | 480 void SSLBlockingPage::OverrideEntry(NavigationEntry* entry) { |
443 int cert_id = content::CertStore::GetInstance()->StoreCert( | 481 int cert_id = content::CertStore::GetInstance()->StoreCert( |
444 ssl_info_.cert.get(), web_contents()->GetRenderProcessHost()->GetID()); | 482 ssl_info_.cert.get(), web_contents()->GetRenderProcessHost()->GetID()); |
445 DCHECK(cert_id); | 483 DCHECK(cert_id); |
446 | 484 |
447 entry->GetSSL().security_style = | 485 entry->GetSSL().security_style = |
448 content::SECURITY_STYLE_AUTHENTICATION_BROKEN; | 486 content::SECURITY_STYLE_AUTHENTICATION_BROKEN; |
449 entry->GetSSL().cert_id = cert_id; | 487 entry->GetSSL().cert_id = cert_id; |
(...skipping 11 matching lines...) Expand all Loading... |
461 case CMD_DONT_PROCEED: { | 499 case CMD_DONT_PROCEED: { |
462 interstitial_page()->DontProceed(); | 500 interstitial_page()->DontProceed(); |
463 break; | 501 break; |
464 } | 502 } |
465 case CMD_PROCEED: { | 503 case CMD_PROCEED: { |
466 if (danger_overridable_) { | 504 if (danger_overridable_) { |
467 interstitial_page()->Proceed(); | 505 interstitial_page()->Proceed(); |
468 } | 506 } |
469 break; | 507 break; |
470 } | 508 } |
| 509 case CMD_DO_REPORT: { |
| 510 SetReportingPreference(true); |
| 511 break; |
| 512 } |
| 513 case CMD_DONT_REPORT: { |
| 514 SetReportingPreference(false); |
| 515 break; |
| 516 } |
471 case CMD_SHOW_MORE_SECTION: { | 517 case CMD_SHOW_MORE_SECTION: { |
472 metrics_helper_->RecordUserInteraction( | 518 metrics_helper_->RecordUserInteraction( |
473 SecurityInterstitialMetricsHelper::SHOW_ADVANCED); | 519 SecurityInterstitialMetricsHelper::SHOW_ADVANCED); |
474 break; | 520 break; |
475 } | 521 } |
476 case CMD_OPEN_HELP_CENTER: { | 522 case CMD_OPEN_HELP_CENTER: { |
477 metrics_helper_->RecordUserInteraction( | 523 metrics_helper_->RecordUserInteraction( |
478 SecurityInterstitialMetricsHelper::SHOW_LEARN_MORE); | 524 SecurityInterstitialMetricsHelper::SHOW_LEARN_MORE); |
479 content::NavigationController::LoadURLParams help_page_params( | 525 content::NavigationController::LoadURLParams help_page_params( |
480 google_util::AppendGoogleLocaleParam( | 526 google_util::AppendGoogleLocaleParam( |
481 GURL(kHelpURL), g_browser_process->GetApplicationLocale())); | 527 GURL(kHelpURL), g_browser_process->GetApplicationLocale())); |
482 web_contents()->GetController().LoadURLWithParams(help_page_params); | 528 web_contents()->GetController().LoadURLWithParams(help_page_params); |
483 break; | 529 break; |
484 } | 530 } |
485 case CMD_RELOAD: { | 531 case CMD_RELOAD: { |
486 metrics_helper_->RecordUserInteraction( | 532 metrics_helper_->RecordUserInteraction( |
487 SecurityInterstitialMetricsHelper::RELOAD); | 533 SecurityInterstitialMetricsHelper::RELOAD); |
488 // The interstitial can't refresh itself. | 534 // The interstitial can't refresh itself. |
489 web_contents()->GetController().Reload(true); | 535 web_contents()->GetController().Reload(true); |
490 break; | 536 break; |
491 } | 537 } |
492 case CMD_OPEN_DATE_SETTINGS: { | 538 case CMD_OPEN_DATE_SETTINGS: { |
493 metrics_helper_->RecordUserInteraction( | 539 metrics_helper_->RecordUserInteraction( |
494 SecurityInterstitialMetricsHelper::OPEN_TIME_SETTINGS); | 540 SecurityInterstitialMetricsHelper::OPEN_TIME_SETTINGS); |
495 LaunchDateAndTimeSettings(); | 541 LaunchDateAndTimeSettings(); |
496 break; | 542 break; |
497 } | 543 } |
| 544 case CMD_OPEN_REPORTING_PRIVACY: |
| 545 OpenExtendedReportingPrivacyPolicy(); |
| 546 break; |
498 case CMD_OPEN_DIAGNOSTIC: | 547 case CMD_OPEN_DIAGNOSTIC: |
499 // Google doesn't currently have a transparency report for SSL. | 548 // Google doesn't currently have a transparency report for SSL. |
500 case CMD_DO_REPORT: | |
501 case CMD_DONT_REPORT: | |
502 case CMD_OPEN_REPORTING_PRIVACY: | |
503 // Chrome doesn't currently do Extended Reporting for SSL. | |
504 NOTREACHED() << "Unexpected command: " << command; | 549 NOTREACHED() << "Unexpected command: " << command; |
505 } | 550 } |
506 } | 551 } |
507 | 552 |
508 void SSLBlockingPage::OverrideRendererPrefs( | 553 void SSLBlockingPage::OverrideRendererPrefs( |
509 content::RendererPreferences* prefs) { | 554 content::RendererPreferences* prefs) { |
510 Profile* profile = Profile::FromBrowserContext( | 555 Profile* profile = Profile::FromBrowserContext( |
511 web_contents()->GetBrowserContext()); | 556 web_contents()->GetBrowserContext()); |
512 renderer_preferences_util::UpdateFromSystemSettings( | 557 renderer_preferences_util::UpdateFromSystemSettings( |
513 prefs, profile, web_contents()); | 558 prefs, profile, web_contents()); |
514 } | 559 } |
515 | 560 |
516 void SSLBlockingPage::OnProceed() { | 561 void SSLBlockingPage::OnProceed() { |
517 metrics_helper_->RecordUserDecision( | 562 metrics_helper_->RecordUserDecision( |
518 SecurityInterstitialMetricsHelper::PROCEED); | 563 SecurityInterstitialMetricsHelper::PROCEED); |
| 564 |
| 565 // Finish collecting information about invalid certificates, if the |
| 566 // user opted in to. |
| 567 FinishCertCollection(); |
| 568 |
519 RecordSSLExpirationPageEventState( | 569 RecordSSLExpirationPageEventState( |
520 expired_but_previously_allowed_, true, overridable_); | 570 expired_but_previously_allowed_, true, overridable_); |
521 // Accepting the certificate resumes the loading of the page. | 571 // Accepting the certificate resumes the loading of the page. |
522 NotifyAllowCertificate(); | 572 NotifyAllowCertificate(); |
523 } | 573 } |
524 | 574 |
525 void SSLBlockingPage::OnDontProceed() { | 575 void SSLBlockingPage::OnDontProceed() { |
526 metrics_helper_->RecordUserDecision( | 576 metrics_helper_->RecordUserDecision( |
527 SecurityInterstitialMetricsHelper::DONT_PROCEED); | 577 SecurityInterstitialMetricsHelper::DONT_PROCEED); |
| 578 |
| 579 // Finish collecting information about invalid certificates, if the |
| 580 // user opted in to. |
| 581 FinishCertCollection(); |
| 582 |
528 RecordSSLExpirationPageEventState( | 583 RecordSSLExpirationPageEventState( |
529 expired_but_previously_allowed_, false, overridable_); | 584 expired_but_previously_allowed_, false, overridable_); |
530 NotifyDenyCertificate(); | 585 NotifyDenyCertificate(); |
531 } | 586 } |
532 | 587 |
533 void SSLBlockingPage::NotifyDenyCertificate() { | 588 void SSLBlockingPage::NotifyDenyCertificate() { |
534 // It's possible that callback_ may not exist if the user clicks "Proceed" | 589 // It's possible that callback_ may not exist if the user clicks "Proceed" |
535 // followed by pressing the back button before the interstitial is hidden. | 590 // followed by pressing the back button before the interstitial is hidden. |
536 // In that case the certificate will still be treated as allowed. | 591 // In that case the certificate will still be treated as allowed. |
537 if (callback_.is_null()) | 592 if (callback_.is_null()) |
(...skipping 27 matching lines...) Expand all Loading... |
565 std::string SSLBlockingPage::GetSamplingEventName() const { | 620 std::string SSLBlockingPage::GetSamplingEventName() const { |
566 std::string event_name(kEventNameBase); | 621 std::string event_name(kEventNameBase); |
567 if (overridable_) | 622 if (overridable_) |
568 event_name.append(kEventOverridable); | 623 event_name.append(kEventOverridable); |
569 else | 624 else |
570 event_name.append(kEventNotOverridable); | 625 event_name.append(kEventNotOverridable); |
571 event_name.append(net::ErrorToString(cert_error_)); | 626 event_name.append(net::ErrorToString(cert_error_)); |
572 return event_name; | 627 return event_name; |
573 } | 628 } |
574 | 629 |
| 630 void SSLBlockingPage::FinishCertCollection() { |
| 631 base::ScopedClosureRunner scoped_callback( |
| 632 certificate_report_callback_for_testing_); |
| 633 |
| 634 if (!base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 635 switches::kEnableInvalidCertCollection) || |
| 636 web_contents()->GetBrowserContext()->IsOffTheRecord()) { |
| 637 return; |
| 638 } |
| 639 |
| 640 const bool enabled = |
| 641 IsPrefEnabled(prefs::kSafeBrowsingExtendedReportingEnabled); |
| 642 |
| 643 if (!enabled) |
| 644 return; |
| 645 |
| 646 metrics_helper_->RecordUserInteraction( |
| 647 SecurityInterstitialMetricsHelper::EXTENDED_REPORTING_IS_ENABLED_SSL); |
| 648 |
| 649 if (certificate_report_callback_for_testing_.is_null()) |
| 650 scoped_callback.Reset(base::Bind(&base::DoNothing)); |
| 651 |
| 652 safe_browsing_ui_manager_->ReportInvalidCertificateChain( |
| 653 request_url().host(), ssl_info_, scoped_callback.Release()); |
| 654 } |
| 655 |
575 // static | 656 // static |
576 bool SSLBlockingPage::IsOptionsOverridable(int options_mask) { | 657 bool SSLBlockingPage::IsOptionsOverridable(int options_mask) { |
577 return (options_mask & SSLBlockingPage::OVERRIDABLE) && | 658 return (options_mask & SSLBlockingPage::OVERRIDABLE) && |
578 !(options_mask & SSLBlockingPage::STRICT_ENFORCEMENT); | 659 !(options_mask & SSLBlockingPage::STRICT_ENFORCEMENT); |
579 } | 660 } |
OLD | NEW |