Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / ssl / ssl_blocking_page.cc
index 61c2c2f..8eb5375 100644 (file)
 #include "base/process/launch.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_piece.h"
+#include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/time/time.h"
 #include "base/values.h"
+#include "chrome/browser/browser_process.h"
 #include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/history/history_service_factory.h"
 #include "chrome/browser/profiles/profile.h"
@@ -24,6 +26,9 @@
 #include "chrome/browser/ssl/ssl_error_classification.h"
 #include "chrome/browser/ssl/ssl_error_info.h"
 #include "chrome/common/chrome_switches.h"
+#include "chrome/grit/chromium_strings.h"
+#include "chrome/grit/generated_resources.h"
+#include "components/google/core/browser/google_util.h"
 #include "content/public/browser/cert_store.h"
 #include "content/public/browser/interstitial_page.h"
 #include "content/public/browser/navigation_controller.h"
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/common/ssl_status.h"
-#include "grit/app_locale_settings.h"
 #include "grit/browser_resources.h"
-#include "grit/chromium_strings.h"
-#include "grit/generated_resources.h"
 #include "net/base/hash_value.h"
 #include "net/base/net_errors.h"
 #include "net/base/net_util.h"
 #include "ui/base/webui/jstemplate_builder.h"
 #include "ui/base/webui/web_ui_util.h"
 
-#if defined(ENABLE_CAPTIVE_PORTAL_DETECTION)
-#include "chrome/browser/captive_portal/captive_portal_service.h"
-#include "chrome/browser/captive_portal/captive_portal_service_factory.h"
-#endif
-
 #if defined(ENABLE_EXTENSIONS)
 #include "chrome/browser/extensions/api/experience_sampling_private/experience_sampling.h"
 #endif
@@ -80,6 +77,9 @@ using extensions::ExperienceSamplingEvent;
 
 namespace {
 
+// URL for help page.
+const char kHelpURL[] = "https://support.google.com/chrome/answer/4454607";
+
 // Constants for the Experience Sampling instrumentation.
 #if defined(ENABLE_EXTENSIONS)
 const char kEventNameBase[] = "ssl_interstitial_";
@@ -106,14 +106,15 @@ enum SSLBlockingPageEvent {
   SHOW_NEW_SITE,
   PROCEED_NEW_SITE,
   PROCEED_MANUAL_NONOVERRIDABLE,
-  CAPTIVE_PORTAL_DETECTION_ENABLED,
-  CAPTIVE_PORTAL_DETECTION_ENABLED_OVERRIDABLE,
-  CAPTIVE_PORTAL_PROBE_COMPLETED,
-  CAPTIVE_PORTAL_PROBE_COMPLETED_OVERRIDABLE,
-  CAPTIVE_PORTAL_NO_RESPONSE,
-  CAPTIVE_PORTAL_NO_RESPONSE_OVERRIDABLE,
-  CAPTIVE_PORTAL_DETECTED,
-  CAPTIVE_PORTAL_DETECTED_OVERRIDABLE,
+  // Captive Portal errors moved to ssl_error_classification.
+  DEPRECATED_CAPTIVE_PORTAL_DETECTION_ENABLED,
+  DEPRECATED_CAPTIVE_PORTAL_DETECTION_ENABLED_OVERRIDABLE,
+  DEPRECATED_CAPTIVE_PORTAL_PROBE_COMPLETED,
+  DEPRECATED_CAPTIVE_PORTAL_PROBE_COMPLETED_OVERRIDABLE,
+  DEPRECATED_CAPTIVE_PORTAL_NO_RESPONSE,
+  DEPRECATED_CAPTIVE_PORTAL_NO_RESPONSE_OVERRIDABLE,
+  DEPRECATED_CAPTIVE_PORTAL_DETECTED,
+  DEPRECATED_CAPTIVE_PORTAL_DETECTED_OVERRIDABLE,
   UNUSED_BLOCKING_PAGE_EVENT,
 };
 
@@ -163,38 +164,11 @@ void RecordSSLBlockingPageDetailedStats(bool proceed,
                                         bool overridable,
                                         bool internal,
                                         int num_visits,
-                                        bool captive_portal_detection_enabled,
-                                        bool captive_portal_probe_completed,
-                                        bool captive_portal_no_response,
-                                        bool captive_portal_detected,
                                         bool expired_but_previously_allowed) {
   UMA_HISTOGRAM_ENUMERATION("interstitial.ssl_error_type",
       SSLErrorInfo::NetErrorToErrorType(cert_error), SSLErrorInfo::END_OF_ENUM);
   RecordSSLExpirationPageEventState(
       expired_but_previously_allowed, proceed, overridable);
-#if defined(ENABLE_CAPTIVE_PORTAL_DETECTION)
-  if (captive_portal_detection_enabled)
-    RecordSSLBlockingPageEventStats(
-        overridable ?
-        CAPTIVE_PORTAL_DETECTION_ENABLED_OVERRIDABLE :
-        CAPTIVE_PORTAL_DETECTION_ENABLED);
-  if (captive_portal_probe_completed)
-    RecordSSLBlockingPageEventStats(
-        overridable ?
-        CAPTIVE_PORTAL_PROBE_COMPLETED_OVERRIDABLE :
-        CAPTIVE_PORTAL_PROBE_COMPLETED);
-  // Log only one of portal detected and no response results.
-  if (captive_portal_detected)
-    RecordSSLBlockingPageEventStats(
-        overridable ?
-        CAPTIVE_PORTAL_DETECTED_OVERRIDABLE :
-        CAPTIVE_PORTAL_DETECTED);
-  else if (captive_portal_no_response)
-    RecordSSLBlockingPageEventStats(
-        overridable ?
-        CAPTIVE_PORTAL_NO_RESPONSE_OVERRIDABLE :
-        CAPTIVE_PORTAL_NO_RESPONSE);
-#endif
   if (!overridable) {
     if (proceed) {
       RecordSSLBlockingPageEventStats(PROCEED_MANUAL_NONOVERRIDABLE);
@@ -317,6 +291,15 @@ void LaunchDateAndTimeSettings() {
 #endif
 }
 
+bool IsErrorDueToBadClock(const base::Time& now, int error) {
+  if (SSLErrorInfo::NetErrorToErrorType(error) !=
+          SSLErrorInfo::CERT_DATE_INVALID) {
+    return false;
+  }
+  return SSLErrorClassification::IsUserClockInThePast(now) ||
+      SSLErrorClassification::IsUserClockInTheFuture(now);
+}
+
 }  // namespace
 
 // Note that we always create a navigation entry with SSL errors.
@@ -338,10 +321,6 @@ SSLBlockingPage::SSLBlockingPage(content::WebContents* web_contents,
       interstitial_page_(NULL),
       internal_(false),
       num_visits_(-1),
-      captive_portal_detection_enabled_(false),
-      captive_portal_probe_completed_(false),
-      captive_portal_no_response_(false),
-      captive_portal_detected_(false),
       expired_but_previously_allowed_(
           (options_mask & EXPIRED_BUT_PREVIOUSLY_ALLOWED) != 0) {
   Profile* profile = Profile::FromBrowserContext(
@@ -365,20 +344,16 @@ SSLBlockingPage::SSLBlockingPage(content::WebContents* web_contents,
     }
   }
 
-  SSLErrorClassification ssl_error_classification(
+  ssl_error_classification_.reset(new SSLErrorClassification(
+      web_contents_,
       base::Time::NowFromSystemTime(),
       request_url_,
-      *ssl_info_.cert.get());
-  ssl_error_classification.RecordUMAStatistics(overridable_, cert_error_);
+      cert_error_,
+      *ssl_info_.cert.get()));
+  ssl_error_classification_->RecordUMAStatistics(overridable_);
 
 #if defined(ENABLE_CAPTIVE_PORTAL_DETECTION)
-  CaptivePortalService* captive_portal_service =
-      CaptivePortalServiceFactory::GetForProfile(profile);
-  captive_portal_detection_enabled_ = captive_portal_service ->enabled();
-  captive_portal_service ->DetectCaptivePortal();
-  registrar_.Add(this,
-                 chrome::NOTIFICATION_CAPTIVE_PORTAL_CHECK_RESULT,
-                 content::Source<Profile>(profile));
+  ssl_error_classification_->RecordCaptivePortalUMAStatistics(overridable_);
 #endif
 
 #if defined(ENABLE_EXTENSIONS)
@@ -401,16 +376,27 @@ SSLBlockingPage::SSLBlockingPage(content::WebContents* web_contents,
 }
 
 SSLBlockingPage::~SSLBlockingPage() {
+  // InvalidCommonNameSeverityScore() and InvalidDateSeverityScore() are in the
+  // destructor because they depend on knowing whether captive portal detection
+  // happened before the user made a decision.
+  SSLErrorInfo::ErrorType type =
+      SSLErrorInfo::NetErrorToErrorType(cert_error_);
+  switch (type) {
+    case SSLErrorInfo::CERT_DATE_INVALID:
+      ssl_error_classification_->InvalidDateSeverityScore();
+      break;
+    case SSLErrorInfo::CERT_COMMON_NAME_INVALID:
+      ssl_error_classification_->InvalidCommonNameSeverityScore();
+      break;
+    default:
+      break;
+  }
   if (!callback_.is_null()) {
     RecordSSLBlockingPageDetailedStats(false,
                                        cert_error_,
                                        overridable_,
                                        internal_,
                                        num_visits_,
-                                       captive_portal_detection_enabled_,
-                                       captive_portal_probe_completed_,
-                                       captive_portal_no_response_,
-                                       captive_portal_detected_,
                                        expired_but_previously_allowed_);
     // The page is closed without the user having chosen what to do, default to
     // deny.
@@ -439,20 +425,21 @@ std::string SSLBlockingPage::GetHTMLContents() {
       "tabTitle", l10n_util::GetStringUTF16(IDS_SSL_V2_TITLE));
   load_time_data.SetString(
       "heading", l10n_util::GetStringUTF16(IDS_SSL_V2_HEADING));
-  if ((SSLErrorClassification::IsUserClockInThePast(
-      base::Time::NowFromSystemTime()))
-      && (SSLErrorInfo::NetErrorToErrorType(cert_error_) ==
-          SSLErrorInfo::CERT_DATE_INVALID)) {
+
+  base::Time now = base::Time::NowFromSystemTime();
+  bool bad_clock = IsErrorDueToBadClock(now, cert_error_);
+  if (bad_clock) {
     load_time_data.SetString("primaryParagraph",
                              l10n_util::GetStringFUTF16(
                                  IDS_SSL_CLOCK_ERROR,
                                  url,
-                                 base::TimeFormatShortDate(base::Time::Now())));
+                                 base::TimeFormatShortDate(now)));
   } else {
     load_time_data.SetString(
         "primaryParagraph",
         l10n_util::GetStringFUTF16(IDS_SSL_V2_PRIMARY_PARAGRAPH, url));
   }
+
   load_time_data.SetString(
      "openDetails",
      l10n_util::GetStringUTF16(IDS_SSL_V2_OPEN_DETAILS_BUTTON));
@@ -461,30 +448,39 @@ std::string SSLBlockingPage::GetHTMLContents() {
      l10n_util::GetStringUTF16(IDS_SSL_V2_CLOSE_DETAILS_BUTTON));
   load_time_data.SetString("errorCode", net::ErrorToString(cert_error_));
 
-  if (overridable_) {  // Overridable.
+  if (overridable_) {
     SSLErrorInfo error_info =
         SSLErrorInfo::CreateError(
             SSLErrorInfo::NetErrorToErrorType(cert_error_),
             ssl_info_.cert.get(),
             request_url_);
-    load_time_data.SetString(
-        "explanationParagraph", error_info.details());
+    if (bad_clock) {
+      load_time_data.SetString("explanationParagraph",
+                               l10n_util::GetStringFUTF16(
+                                   IDS_SSL_CLOCK_ERROR_EXPLANATION, url));
+    } else {
+      load_time_data.SetString("explanationParagraph", error_info.details());
+    }
     load_time_data.SetString(
         "primaryButtonText",
         l10n_util::GetStringUTF16(IDS_SSL_OVERRIDABLE_SAFETY_BUTTON));
     load_time_data.SetString(
         "finalParagraph",
-        l10n_util::GetStringFUTF16(IDS_SSL_OVERRIDABLE_PROCEED_PARAGRAPH, url));
-  } else {  // Non-overridable.
-    load_time_data.SetBoolean("overridable", false);
+        l10n_util::GetStringFUTF16(IDS_SSL_OVERRIDABLE_PROCEED_PARAGRAPH,
+                                   url));
+  } else {
     SSLErrorInfo::ErrorType type =
         SSLErrorInfo::NetErrorToErrorType(cert_error_);
     if (type == SSLErrorInfo::CERT_INVALID && SSLErrorClassification::
-        IsWindowsVersionSP3OrLower()) {
+        MaybeWindowsLacksSHA256Support()) {
       load_time_data.SetString(
           "explanationParagraph",
           l10n_util::GetStringFUTF16(
               IDS_SSL_NONOVERRIDABLE_MORE_INVALID_SP3, url));
+    } else if (bad_clock) {
+      load_time_data.SetString("explanationParagraph",
+                               l10n_util::GetStringFUTF16(
+                                   IDS_SSL_CLOCK_ERROR_EXPLANATION, url));
     } else {
       load_time_data.SetString("explanationParagraph",
                                l10n_util::GetStringFUTF16(
@@ -516,9 +512,23 @@ std::string SSLBlockingPage::GetHTMLContents() {
         "finalParagraph", l10n_util::GetStringFUTF16(help_string, url));
   }
 
+  // Set debugging information at the bottom of the warning.
+  load_time_data.SetString(
+      "subject", ssl_info_.cert->subject().GetDisplayName());
+  load_time_data.SetString(
+      "issuer", ssl_info_.cert->issuer().GetDisplayName());
+  load_time_data.SetString(
+      "expirationDate",
+      base::TimeFormatShortDate(ssl_info_.cert->valid_expiry()));
+  load_time_data.SetString(
+      "currentDate", base::TimeFormatShortDate(now));
+  std::vector<std::string> encoded_chain;
+  ssl_info_.cert->GetPEMEncodedChain(&encoded_chain);
+  load_time_data.SetString("pem", JoinString(encoded_chain, std::string()));
+
   base::StringPiece html(
      ResourceBundle::GetSharedInstance().GetRawDataResource(
-         IRD_SSL_INTERSTITIAL_V2_HTML));
+         IRD_SECURITY_INTERSTITIAL_HTML));
   webui::UseVersion2 version;
   return webui::GetI18nTemplateHtml(html, &load_time_data);
 }
@@ -565,8 +575,9 @@ void SSLBlockingPage::CommandReceived(const std::string& command) {
       break;
     }
     case CMD_HELP: {
-      content::NavigationController::LoadURLParams help_page_params(GURL(
-          "https://support.google.com/chrome/answer/4454607"));
+      content::NavigationController::LoadURLParams help_page_params(
+          google_util::AppendGoogleLocaleParam(
+              GURL(kHelpURL), g_browser_process->GetApplicationLocale()));
 #if defined(ENABLE_EXTENSIONS)
       if (sampling_event_.get())
         sampling_event_->set_has_viewed_learn_more(true);
@@ -597,16 +608,13 @@ void SSLBlockingPage::OnProceed() {
                                      overridable_,
                                      internal_,
                                      num_visits_,
-                                     captive_portal_detection_enabled_,
-                                     captive_portal_probe_completed_,
-                                     captive_portal_no_response_,
-                                     captive_portal_detected_,
                                      expired_but_previously_allowed_);
 #if defined(ENABLE_EXTENSIONS)
   // ExperienceSampling: Notify that user decided to proceed.
   if (sampling_event_.get())
     sampling_event_->CreateUserDecisionEvent(ExperienceSamplingEvent::kProceed);
 #endif
+
   // Accepting the certificate resumes the loading of the page.
   NotifyAllowCertificate();
 }
@@ -617,10 +625,6 @@ void SSLBlockingPage::OnDontProceed() {
                                      overridable_,
                                      internal_,
                                      num_visits_,
-                                     captive_portal_detection_enabled_,
-                                     captive_portal_probe_completed_,
-                                     captive_portal_no_response_,
-                                     captive_portal_detected_,
                                      expired_but_previously_allowed_);
 #if defined(ENABLE_EXTENSIONS)
   // ExperienceSampling: Notify that user decided to not proceed.
@@ -671,35 +675,3 @@ void SSLBlockingPage::OnGotHistoryCount(bool success,
                                         base::Time first_visit) {
   num_visits_ = num_visits;
 }
-
-void SSLBlockingPage::Observe(
-    int type,
-    const content::NotificationSource& source,
-    const content::NotificationDetails& details) {
-#if defined(ENABLE_CAPTIVE_PORTAL_DETECTION)
-  // When detection is disabled, captive portal service always sends
-  // RESULT_INTERNET_CONNECTED. Ignore any probe results in that case.
-  if (!captive_portal_detection_enabled_)
-    return;
-  if (type == chrome::NOTIFICATION_CAPTIVE_PORTAL_CHECK_RESULT) {
-    captive_portal_probe_completed_ = true;
-    CaptivePortalService::Results* results =
-        content::Details<CaptivePortalService::Results>(
-            details).ptr();
-    // If a captive portal was detected at any point when the interstitial was
-    // displayed, assume that the interstitial was caused by a captive portal.
-    // Example scenario:
-    // 1- Interstitial displayed and captive portal detected, setting the flag.
-    // 2- Captive portal detection automatically opens portal login page.
-    // 3- User logs in on the portal login page.
-    // A notification will be received here for RESULT_INTERNET_CONNECTED. Make
-    // sure we don't clear the captive portal flag, since the interstitial was
-    // potentially caused by the captive portal.
-    captive_portal_detected_ = captive_portal_detected_ ||
-        (results->result == captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL);
-    // Also keep track of non-HTTP portals and error cases.
-    captive_portal_no_response_ = captive_portal_no_response_ ||
-        (results->result == captive_portal::RESULT_NO_RESPONSE);
-  }
-#endif
-}