[SSL] Componentize MITMSoftwareBlockingPage

All //chrome-level dependencies have been cleaned in a preceding CL.

Bug: 1030692
Change-Id: Ice24a7c19661f54d9b1fd081cc88a0c0237cc0e1
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1992070
Reviewed-by: Carlos IL <[email protected]>
Commit-Queue: Colin Blundell <[email protected]>
Cr-Commit-Position: refs/heads/master@{#731283}
diff --git a/components/security_interstitials/content/BUILD.gn b/components/security_interstitials/content/BUILD.gn
index f349c31..2c330c4 100644
--- a/components/security_interstitials/content/BUILD.gn
+++ b/components/security_interstitials/content/BUILD.gn
@@ -19,6 +19,8 @@
     "connection_help_ui.h",
     "known_interception_disclosure_ui.cc",
     "known_interception_disclosure_ui.h",
+    "mitm_software_blocking_page.cc",
+    "mitm_software_blocking_page.h",
     "origin_policy_interstitial_page.cc",
     "origin_policy_interstitial_page.h",
     "origin_policy_ui.cc",
diff --git a/components/security_interstitials/content/mitm_software_blocking_page.cc b/components/security_interstitials/content/mitm_software_blocking_page.cc
new file mode 100644
index 0000000..035fdd1c
--- /dev/null
+++ b/components/security_interstitials/content/mitm_software_blocking_page.cc
@@ -0,0 +1,108 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/security_interstitials/content/mitm_software_blocking_page.h"
+
+#include <utility>
+
+#include "components/safe_browsing/core/common/safe_browsing_prefs.h"
+#include "components/security_interstitials/content/cert_report_helper.h"
+#include "components/security_interstitials/content/security_interstitial_controller_client.h"
+#include "components/security_interstitials/content/ssl_cert_reporter.h"
+#include "components/security_interstitials/core/metrics_helper.h"
+#include "content/public/browser/interstitial_page.h"
+#include "content/public/browser/interstitial_page_delegate.h"
+#include "content/public/browser/navigation_controller.h"
+#include "content/public/browser/navigation_entry.h"
+#include "content/public/browser/render_process_host.h"
+#include "content/public/browser/render_view_host.h"
+#include "content/public/browser/ssl_status.h"
+#include "content/public/browser/web_contents.h"
+#include "net/base/net_errors.h"
+
+using content::InterstitialPageDelegate;
+using content::NavigationController;
+using content::NavigationEntry;
+
+namespace {}  // namespace
+
+// static
+const InterstitialPageDelegate::TypeID
+    MITMSoftwareBlockingPage::kTypeForTesting =
+        &MITMSoftwareBlockingPage::kTypeForTesting;
+
+// Note that we always create a navigation entry with SSL errors.
+// No error happening loading a sub-resource triggers an interstitial so far.
+// Creating an interstitial without showing (e.g. from chrome://interstitials)
+// it leaks memory, so don't create it here.
+MITMSoftwareBlockingPage::MITMSoftwareBlockingPage(
+    content::WebContents* web_contents,
+    int cert_error,
+    const GURL& request_url,
+    std::unique_ptr<SSLCertReporter> ssl_cert_reporter,
+    const net::SSLInfo& ssl_info,
+    const std::string& mitm_software_name,
+    bool is_enterprise_managed,
+    std::unique_ptr<
+        security_interstitials::SecurityInterstitialControllerClient>
+        controller_client)
+    : SSLBlockingPageBase(web_contents,
+                          CertificateErrorReport::INTERSTITIAL_MITM_SOFTWARE,
+                          ssl_info,
+                          request_url,
+                          std::move(ssl_cert_reporter),
+                          false /* overridable */,
+                          base::Time::Now(),
+                          std::move(controller_client)),
+
+      ssl_info_(ssl_info),
+      mitm_software_ui_(
+          new security_interstitials::MITMSoftwareUI(request_url,
+                                                     cert_error,
+                                                     ssl_info,
+                                                     mitm_software_name,
+                                                     is_enterprise_managed,
+                                                     controller())) {}
+
+MITMSoftwareBlockingPage::~MITMSoftwareBlockingPage() = default;
+
+bool MITMSoftwareBlockingPage::ShouldCreateNewNavigation() const {
+  return true;
+}
+
+InterstitialPageDelegate::TypeID MITMSoftwareBlockingPage::GetTypeForTesting() {
+  return MITMSoftwareBlockingPage::kTypeForTesting;
+}
+
+void MITMSoftwareBlockingPage::PopulateInterstitialStrings(
+    base::DictionaryValue* load_time_data) {
+  mitm_software_ui_->PopulateStringsForHTML(load_time_data);
+  cert_report_helper()->PopulateExtendedReportingOption(load_time_data);
+}
+
+void MITMSoftwareBlockingPage::OverrideEntry(NavigationEntry* entry) {
+  entry->GetSSL() = content::SSLStatus(ssl_info_);
+}
+
+// This handles the commands sent from the interstitial JavaScript.
+void MITMSoftwareBlockingPage::CommandReceived(const std::string& command) {
+  if (command == "\"pageLoadComplete\"") {
+    // content::WaitForRenderFrameReady sends this message when the page
+    // load completes. Ignore it.
+    return;
+  }
+
+  int cmd = 0;
+  bool retval = base::StringToInt(command, &cmd);
+  DCHECK(retval);
+
+  // Let the CertReportHelper handle commands first, This allows it to get set
+  // up to send reports, so that the report is populated properly if
+  // MITMSoftwareUI's command handling triggers a report to be sent.
+  cert_report_helper()->HandleReportingCommands(
+      static_cast<security_interstitials::SecurityInterstitialCommand>(cmd),
+      controller()->GetPrefService());
+  mitm_software_ui_->HandleCommand(
+      static_cast<security_interstitials::SecurityInterstitialCommand>(cmd));
+}
diff --git a/components/security_interstitials/content/mitm_software_blocking_page.h b/components/security_interstitials/content/mitm_software_blocking_page.h
new file mode 100644
index 0000000..89b0146
--- /dev/null
+++ b/components/security_interstitials/content/mitm_software_blocking_page.h
@@ -0,0 +1,71 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_SECURITY_INTERSTITIALS_CONTENT_MITM_SOFTWARE_BLOCKING_PAGE_H_
+#define COMPONENTS_SECURITY_INTERSTITIALS_CONTENT_MITM_SOFTWARE_BLOCKING_PAGE_H_
+
+#include <memory>
+#include <string>
+
+#include "base/macros.h"
+#include "components/security_interstitials/content/ssl_blocking_page_base.h"
+#include "components/security_interstitials/content/ssl_cert_reporter.h"
+#include "components/security_interstitials/core/mitm_software_ui.h"
+#include "components/ssl_errors/error_classification.h"
+#include "content/public/browser/certificate_request_result_type.h"
+#include "net/ssl/ssl_info.h"
+
+class GURL;
+
+// This class is responsible for showing/hiding the interstitial page that
+// occurs when an SSL error is caused by any sort of MITM software. MITM
+// software includes antiviruses, firewalls, proxies or any other non-malicious
+// software that intercepts and rewrites the user's connection. This class
+// creates the interstitial UI using security_interstitials::MITMSoftwareUI and
+// then displays it. It deletes itself when the interstitial page is closed.
+class MITMSoftwareBlockingPage : public SSLBlockingPageBase {
+ public:
+  // Interstitial type, used in tests.
+  static const InterstitialPageDelegate::TypeID kTypeForTesting;
+
+  // If the blocking page isn't shown, the caller is responsible for cleaning
+  // up the blocking page. Otherwise, the interstitial takes ownership when
+  // shown.
+  MITMSoftwareBlockingPage(
+      content::WebContents* web_contents,
+      int cert_error,
+      const GURL& request_url,
+      std::unique_ptr<SSLCertReporter> ssl_cert_reporter,
+      const net::SSLInfo& ssl_info,
+      const std::string& mitm_software_name,
+      bool is_enterprise_managed,
+      std::unique_ptr<
+          security_interstitials::SecurityInterstitialControllerClient>
+          controller_client);
+
+  ~MITMSoftwareBlockingPage() override;
+
+  // InterstitialPageDelegate method:
+  InterstitialPageDelegate::TypeID GetTypeForTesting() override;
+
+ protected:
+  // InterstitialPageDelegate implementation:
+  void CommandReceived(const std::string& command) override;
+  void OverrideEntry(content::NavigationEntry* entry) override;
+
+  // SecurityInterstitialPage implementation:
+  bool ShouldCreateNewNavigation() const override;
+  void PopulateInterstitialStrings(
+      base::DictionaryValue* load_time_data) override;
+
+ private:
+  const net::SSLInfo ssl_info_;
+
+  const std::unique_ptr<security_interstitials::MITMSoftwareUI>
+      mitm_software_ui_;
+
+  DISALLOW_COPY_AND_ASSIGN(MITMSoftwareBlockingPage);
+};
+
+#endif  // COMPONENTS_SECURITY_INTERSTITIALS_CONTENT_MITM_SOFTWARE_BLOCKING_PAGE_H_