Chromium Code Reviews| 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" |
| 11 #include "base/metrics/field_trial.h" | 11 #include "base/metrics/field_trial.h" |
| 12 #include "base/metrics/histogram.h" | 12 #include "base/metrics/histogram.h" |
| 13 #include "base/prefs/pref_service.h" | |
| 13 #include "base/process/launch.h" | 14 #include "base/process/launch.h" |
| 14 #include "base/strings/string_number_conversions.h" | 15 #include "base/strings/string_number_conversions.h" |
| 15 #include "base/strings/string_piece.h" | 16 #include "base/strings/string_piece.h" |
| 16 #include "base/strings/string_util.h" | 17 #include "base/strings/string_util.h" |
| 17 #include "base/strings/stringprintf.h" | 18 #include "base/strings/stringprintf.h" |
| 18 #include "base/strings/utf_string_conversions.h" | 19 #include "base/strings/utf_string_conversions.h" |
| 19 #include "base/time/time.h" | 20 #include "base/time/time.h" |
| 20 #include "base/values.h" | 21 #include "base/values.h" |
| 21 #include "chrome/browser/browser_process.h" | 22 #include "chrome/browser/browser_process.h" |
| 22 #include "chrome/browser/chrome_notification_types.h" | 23 #include "chrome/browser/chrome_notification_types.h" |
| 23 #include "chrome/browser/profiles/profile.h" | 24 #include "chrome/browser/profiles/profile.h" |
| 24 #include "chrome/browser/renderer_preferences_util.h" | 25 #include "chrome/browser/renderer_preferences_util.h" |
| 25 #include "chrome/browser/ssl/ssl_error_classification.h" | 26 #include "chrome/browser/ssl/ssl_error_classification.h" |
| 26 #include "chrome/browser/ssl/ssl_error_info.h" | 27 #include "chrome/browser/ssl/ssl_error_info.h" |
| 27 #include "chrome/common/chrome_switches.h" | 28 #include "chrome/common/chrome_switches.h" |
| 29 #include "chrome/common/pref_names.h" | |
| 28 #include "chrome/grit/chromium_strings.h" | 30 #include "chrome/grit/chromium_strings.h" |
| 29 #include "chrome/grit/generated_resources.h" | 31 #include "chrome/grit/generated_resources.h" |
| 30 #include "components/google/core/browser/google_util.h" | 32 #include "components/google/core/browser/google_util.h" |
| 33 #include "content/public/browser/browser_thread.h" | |
| 31 #include "content/public/browser/cert_store.h" | 34 #include "content/public/browser/cert_store.h" |
| 32 #include "content/public/browser/interstitial_page.h" | 35 #include "content/public/browser/interstitial_page.h" |
| 33 #include "content/public/browser/navigation_controller.h" | 36 #include "content/public/browser/navigation_controller.h" |
| 34 #include "content/public/browser/navigation_entry.h" | 37 #include "content/public/browser/navigation_entry.h" |
| 35 #include "content/public/browser/notification_service.h" | 38 #include "content/public/browser/notification_service.h" |
| 36 #include "content/public/browser/notification_types.h" | 39 #include "content/public/browser/notification_types.h" |
| 37 #include "content/public/browser/render_process_host.h" | 40 #include "content/public/browser/render_process_host.h" |
| 38 #include "content/public/browser/render_view_host.h" | 41 #include "content/public/browser/render_view_host.h" |
| 39 #include "content/public/browser/web_contents.h" | 42 #include "content/public/browser/web_contents.h" |
| 40 #include "content/public/common/renderer_preferences.h" | 43 #include "content/public/common/renderer_preferences.h" |
| 41 #include "content/public/common/ssl_status.h" | 44 #include "content/public/common/ssl_status.h" |
| 42 #include "grit/browser_resources.h" | 45 #include "grit/browser_resources.h" |
| 43 #include "net/base/hash_value.h" | 46 #include "net/base/hash_value.h" |
| 44 #include "net/base/net_errors.h" | 47 #include "net/base/net_errors.h" |
| 45 #include "net/base/net_util.h" | 48 #include "net/base/net_util.h" |
| 49 #include "net/url_request/fraudulent_certificate_reporter.h" | |
| 50 #include "net/url_request/url_request_context.h" | |
| 51 #include "net/url_request/url_request_context_getter.h" | |
| 46 #include "ui/base/l10n/l10n_util.h" | 52 #include "ui/base/l10n/l10n_util.h" |
| 47 | 53 |
| 48 #if defined(OS_WIN) | 54 #if defined(OS_WIN) |
| 49 #include "base/base_paths_win.h" | 55 #include "base/base_paths_win.h" |
| 50 #include "base/path_service.h" | 56 #include "base/path_service.h" |
| 51 #include "base/strings/string16.h" | 57 #include "base/strings/string16.h" |
| 52 #include "base/win/windows_version.h" | 58 #include "base/win/windows_version.h" |
| 53 #endif | 59 #endif |
| 54 | 60 |
| 55 #if defined(OS_ANDROID) | 61 #if defined(OS_ANDROID) |
| 56 #include "chrome/browser/android/intent_helper.h" | 62 #include "chrome/browser/android/intent_helper.h" |
| 57 #endif | 63 #endif |
| 58 | 64 |
| 59 #if defined(OS_CHROMEOS) | 65 #if defined(OS_CHROMEOS) |
| 60 #include "chrome/browser/profiles/profile_manager.h" | 66 #include "chrome/browser/profiles/profile_manager.h" |
| 61 #include "chrome/browser/ui/chrome_pages.h" | 67 #include "chrome/browser/ui/chrome_pages.h" |
| 62 #include "chrome/common/url_constants.h" | 68 #include "chrome/common/url_constants.h" |
| 63 #endif | 69 #endif |
| 64 | 70 |
| 65 using base::ASCIIToUTF16; | 71 using base::ASCIIToUTF16; |
| 66 using base::TimeTicks; | 72 using base::TimeTicks; |
| 73 using content::BrowserThread; | |
| 67 using content::InterstitialPage; | 74 using content::InterstitialPage; |
| 68 using content::NavigationController; | 75 using content::NavigationController; |
| 69 using content::NavigationEntry; | 76 using content::NavigationEntry; |
| 70 | 77 |
| 71 namespace { | 78 namespace { |
| 72 | 79 |
| 73 // URL for help page. | 80 // URL for help page. |
| 74 const char kHelpURL[] = "https://support.google.com/chrome/answer/4454607"; | 81 const char kHelpURL[] = "https://support.google.com/chrome/answer/4454607"; |
| 75 | 82 |
| 76 // Constants for the Experience Sampling instrumentation. | 83 // Constants for the Experience Sampling instrumentation. |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 202 | 209 |
| 203 bool IsErrorDueToBadClock(const base::Time& now, int error) { | 210 bool IsErrorDueToBadClock(const base::Time& now, int error) { |
| 204 if (SSLErrorInfo::NetErrorToErrorType(error) != | 211 if (SSLErrorInfo::NetErrorToErrorType(error) != |
| 205 SSLErrorInfo::CERT_DATE_INVALID) { | 212 SSLErrorInfo::CERT_DATE_INVALID) { |
| 206 return false; | 213 return false; |
| 207 } | 214 } |
| 208 return SSLErrorClassification::IsUserClockInThePast(now) || | 215 return SSLErrorClassification::IsUserClockInThePast(now) || |
| 209 SSLErrorClassification::IsUserClockInTheFuture(now); | 216 SSLErrorClassification::IsUserClockInTheFuture(now); |
| 210 } | 217 } |
| 211 | 218 |
| 219 // A helper function that actually sends the cert collection report over | |
| 220 // the network. | |
| 221 void FinishCertCollectionInternal( | |
| 222 const scoped_refptr<net::URLRequestContextGetter>& request_context_getter, | |
| 223 const std::string& hostname, | |
| 224 const net::SSLInfo& ssl_info) { | |
| 225 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
| 226 | |
| 227 net::FraudulentCertificateReporter* reporter = | |
| 228 request_context_getter->GetURLRequestContext() | |
| 229 ->fraudulent_certificate_reporter(); | |
| 230 if (reporter) { | |
| 231 reporter->SendReport( | |
| 232 net::FraudulentCertificateReporter::REPORT_TYPE_EXTENDED_REPORTING, | |
| 233 hostname, ssl_info); | |
| 234 } | |
| 235 } | |
| 236 | |
| 212 } // namespace | 237 } // namespace |
| 213 | 238 |
| 214 // static | 239 // static |
| 215 const void* SSLBlockingPage::kTypeForTesting = | 240 const void* SSLBlockingPage::kTypeForTesting = |
| 216 &SSLBlockingPage::kTypeForTesting; | 241 &SSLBlockingPage::kTypeForTesting; |
| 217 | 242 |
| 218 // Note that we always create a navigation entry with SSL errors. | 243 // Note that we always create a navigation entry with SSL errors. |
| 219 // No error happening loading a sub-resource triggers an interstitial so far. | 244 // No error happening loading a sub-resource triggers an interstitial so far. |
| 220 SSLBlockingPage::SSLBlockingPage(content::WebContents* web_contents, | 245 SSLBlockingPage::SSLBlockingPage(content::WebContents* web_contents, |
| 221 int cert_error, | 246 int cert_error, |
| (...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 423 load_time_data->SetString( | 448 load_time_data->SetString( |
| 424 "issuer", ssl_info_.cert->issuer().GetDisplayName()); | 449 "issuer", ssl_info_.cert->issuer().GetDisplayName()); |
| 425 load_time_data->SetString( | 450 load_time_data->SetString( |
| 426 "expirationDate", | 451 "expirationDate", |
| 427 base::TimeFormatShortDate(ssl_info_.cert->valid_expiry())); | 452 base::TimeFormatShortDate(ssl_info_.cert->valid_expiry())); |
| 428 load_time_data->SetString( | 453 load_time_data->SetString( |
| 429 "currentDate", base::TimeFormatShortDate(now)); | 454 "currentDate", base::TimeFormatShortDate(now)); |
| 430 std::vector<std::string> encoded_chain; | 455 std::vector<std::string> encoded_chain; |
| 431 ssl_info_.cert->GetPEMEncodedChain(&encoded_chain); | 456 ssl_info_.cert->GetPEMEncodedChain(&encoded_chain); |
| 432 load_time_data->SetString("pem", JoinString(encoded_chain, std::string())); | 457 load_time_data->SetString("pem", JoinString(encoded_chain, std::string())); |
| 458 | |
| 459 PopulateExtendedReportingOption(load_time_data); | |
| 460 } | |
| 461 | |
| 462 void SSLBlockingPage::PopulateExtendedReportingOption( | |
| 463 base::DictionaryValue* load_time_data) { | |
| 464 // Only show the checkbox if not off-the-record and if the | |
| 465 // command-line option is set. | |
| 466 const bool show = !web_contents()->GetBrowserContext()->IsOffTheRecord() && | |
| 467 base::CommandLine::ForCurrentProcess()->HasSwitch( | |
| 468 switches::kEnableInvalidCertCollection); | |
| 469 | |
| 470 load_time_data->SetBoolean(interstitials::kDisplayCheckBox, show); | |
| 471 if (!show) | |
| 472 return; | |
| 473 | |
| 474 load_time_data->SetBoolean( | |
| 475 interstitials::kBoxChecked, | |
| 476 IsPrefEnabled(prefs::kSafeBrowsingExtendedReportingEnabled)); | |
| 477 | |
| 478 const std::string privacy_link = base::StringPrintf( | |
| 479 interstitials::kPrivacyLinkHtml, | |
| 480 l10n_util::GetStringUTF8(IDS_SAFE_BROWSING_PRIVACY_POLICY_PAGE).c_str()); | |
| 481 | |
| 482 load_time_data->SetString( | |
| 483 "optInLink", | |
| 484 l10n_util::GetStringFUTF16(IDS_SAFE_BROWSING_MALWARE_REPORTING_AGREE, | |
| 485 base::UTF8ToUTF16(privacy_link))); | |
| 433 } | 486 } |
| 434 | 487 |
| 435 void SSLBlockingPage::OverrideEntry(NavigationEntry* entry) { | 488 void SSLBlockingPage::OverrideEntry(NavigationEntry* entry) { |
| 436 int cert_id = content::CertStore::GetInstance()->StoreCert( | 489 int cert_id = content::CertStore::GetInstance()->StoreCert( |
| 437 ssl_info_.cert.get(), web_contents()->GetRenderProcessHost()->GetID()); | 490 ssl_info_.cert.get(), web_contents()->GetRenderProcessHost()->GetID()); |
| 438 DCHECK(cert_id); | 491 DCHECK(cert_id); |
| 439 | 492 |
| 440 entry->GetSSL().security_style = | 493 entry->GetSSL().security_style = |
| 441 content::SECURITY_STYLE_AUTHENTICATION_BROKEN; | 494 content::SECURITY_STYLE_AUTHENTICATION_BROKEN; |
| 442 entry->GetSSL().cert_id = cert_id; | 495 entry->GetSSL().cert_id = cert_id; |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 455 case CMD_DONT_PROCEED: { | 508 case CMD_DONT_PROCEED: { |
| 456 interstitial_page()->DontProceed(); | 509 interstitial_page()->DontProceed(); |
| 457 break; | 510 break; |
| 458 } | 511 } |
| 459 case CMD_PROCEED: { | 512 case CMD_PROCEED: { |
| 460 if (danger_overridable_) { | 513 if (danger_overridable_) { |
| 461 interstitial_page()->Proceed(); | 514 interstitial_page()->Proceed(); |
| 462 } | 515 } |
| 463 break; | 516 break; |
| 464 } | 517 } |
| 518 case CMD_DO_REPORT: { | |
| 519 SetReportingPreference(true); | |
| 520 break; | |
| 521 } | |
| 522 case CMD_DONT_REPORT: { | |
| 523 SetReportingPreference(false); | |
| 524 break; | |
| 525 } | |
| 465 case CMD_MORE: { | 526 case CMD_MORE: { |
| 466 metrics_helper_->RecordUserInteraction( | 527 metrics_helper_->RecordUserInteraction( |
| 467 SecurityInterstitialMetricsHelper::SHOW_ADVANCED); | 528 SecurityInterstitialMetricsHelper::SHOW_ADVANCED); |
| 468 break; | 529 break; |
| 469 } | 530 } |
| 470 case CMD_RELOAD: { | 531 case CMD_RELOAD: { |
| 471 metrics_helper_->RecordUserInteraction( | 532 metrics_helper_->RecordUserInteraction( |
| 472 SecurityInterstitialMetricsHelper::RELOAD); | 533 SecurityInterstitialMetricsHelper::RELOAD); |
| 473 // The interstitial can't refresh itself. | 534 // The interstitial can't refresh itself. |
| 474 web_contents()->GetController().Reload(true); | 535 web_contents()->GetController().Reload(true); |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 499 content::RendererPreferences* prefs) { | 560 content::RendererPreferences* prefs) { |
| 500 Profile* profile = Profile::FromBrowserContext( | 561 Profile* profile = Profile::FromBrowserContext( |
| 501 web_contents()->GetBrowserContext()); | 562 web_contents()->GetBrowserContext()); |
| 502 renderer_preferences_util::UpdateFromSystemSettings( | 563 renderer_preferences_util::UpdateFromSystemSettings( |
| 503 prefs, profile, web_contents()); | 564 prefs, profile, web_contents()); |
| 504 } | 565 } |
| 505 | 566 |
| 506 void SSLBlockingPage::OnProceed() { | 567 void SSLBlockingPage::OnProceed() { |
| 507 metrics_helper_->RecordUserDecision( | 568 metrics_helper_->RecordUserDecision( |
| 508 SecurityInterstitialMetricsHelper::PROCEED); | 569 SecurityInterstitialMetricsHelper::PROCEED); |
| 570 | |
| 571 // Finish collection information about invalid certificates, if the | |
| 572 // user opted in to. | |
| 573 FinishCertCollection(); | |
| 574 | |
| 509 RecordSSLExpirationPageEventState( | 575 RecordSSLExpirationPageEventState( |
| 510 expired_but_previously_allowed_, true, overridable_); | 576 expired_but_previously_allowed_, true, overridable_); |
| 511 // Accepting the certificate resumes the loading of the page. | 577 // Accepting the certificate resumes the loading of the page. |
| 512 NotifyAllowCertificate(); | 578 NotifyAllowCertificate(); |
| 513 } | 579 } |
| 514 | 580 |
| 515 void SSLBlockingPage::OnDontProceed() { | 581 void SSLBlockingPage::OnDontProceed() { |
| 516 metrics_helper_->RecordUserDecision( | 582 metrics_helper_->RecordUserDecision( |
| 517 SecurityInterstitialMetricsHelper::DONT_PROCEED); | 583 SecurityInterstitialMetricsHelper::DONT_PROCEED); |
| 584 | |
| 585 // Finish collection information about invalid certificates, if the | |
| 586 // user opted in to. | |
| 587 FinishCertCollection(); | |
| 588 | |
| 518 RecordSSLExpirationPageEventState( | 589 RecordSSLExpirationPageEventState( |
| 519 expired_but_previously_allowed_, false, overridable_); | 590 expired_but_previously_allowed_, false, overridable_); |
| 520 NotifyDenyCertificate(); | 591 NotifyDenyCertificate(); |
| 521 } | 592 } |
| 522 | 593 |
| 523 void SSLBlockingPage::NotifyDenyCertificate() { | 594 void SSLBlockingPage::NotifyDenyCertificate() { |
| 524 // It's possible that callback_ may not exist if the user clicks "Proceed" | 595 // It's possible that callback_ may not exist if the user clicks "Proceed" |
| 525 // followed by pressing the back button before the interstitial is hidden. | 596 // followed by pressing the back button before the interstitial is hidden. |
| 526 // In that case the certificate will still be treated as allowed. | 597 // In that case the certificate will still be treated as allowed. |
| 527 if (callback_.is_null()) | 598 if (callback_.is_null()) |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 555 std::string SSLBlockingPage::GetSamplingEventName() const { | 626 std::string SSLBlockingPage::GetSamplingEventName() const { |
| 556 std::string event_name(kEventNameBase); | 627 std::string event_name(kEventNameBase); |
| 557 if (overridable_) | 628 if (overridable_) |
| 558 event_name.append(kEventOverridable); | 629 event_name.append(kEventOverridable); |
| 559 else | 630 else |
| 560 event_name.append(kEventNotOverridable); | 631 event_name.append(kEventNotOverridable); |
| 561 event_name.append(net::ErrorToString(cert_error_)); | 632 event_name.append(net::ErrorToString(cert_error_)); |
| 562 return event_name; | 633 return event_name; |
| 563 } | 634 } |
| 564 | 635 |
| 636 void SSLBlockingPage::FinishCertCollection() { | |
| 637 if (!base::CommandLine::ForCurrentProcess()->HasSwitch( | |
| 638 switches::kEnableInvalidCertCollection)) | |
| 639 return; | |
| 640 | |
| 641 const bool enabled = | |
| 642 IsPrefEnabled(prefs::kSafeBrowsingExtendedReportingEnabled); | |
| 643 UMA_HISTOGRAM_BOOLEAN("SB2.ExtendedReportingIsEnabled", enabled); | |
|
estark
2015/02/28 21:03:11
I'm not quite sure what this is measuring -- shoul
felt
2015/03/02 16:06:58
That's meant to measure how many interstitials had
estark
2015/03/02 16:26:10
Ok! In that case I just moved the off-the-record c
| |
| 644 | |
| 645 if (enabled && !web_contents()->GetBrowserContext()->IsOffTheRecord()) { | |
| 646 scoped_refptr<net::URLRequestContextGetter> request_context_getter = | |
| 647 web_contents()->GetBrowserContext()->GetRequestContext(); | |
| 648 BrowserThread::PostTask( | |
| 649 BrowserThread::IO, FROM_HERE, | |
| 650 base::Bind(FinishCertCollectionInternal, request_context_getter, | |
| 651 request_url().host(), ssl_info_)); | |
| 652 } | |
| 653 } | |
| 654 | |
| 565 // static | 655 // static |
| 566 bool SSLBlockingPage::IsOptionsOverridable(int options_mask) { | 656 bool SSLBlockingPage::IsOptionsOverridable(int options_mask) { |
| 567 return (options_mask & SSLBlockingPage::OVERRIDABLE) && | 657 return (options_mask & SSLBlockingPage::OVERRIDABLE) && |
| 568 !(options_mask & SSLBlockingPage::STRICT_ENFORCEMENT); | 658 !(options_mask & SSLBlockingPage::STRICT_ENFORCEMENT); |
| 569 } | 659 } |
| OLD | NEW |