Commit fbc20852 authored by Colin Blundell's avatar Colin Blundell Committed by Commit Bot

WebLayer: Reuse SSLBlockingPage from //components

This CL ports WebLayer to share the //components-level SSLBlockingPage
rather than having a custom fork.

Changes to enable this:

- The configuration done in //weblayer's SSLBlockingPage::Create() is
  moved to //weblayer's SSLErrorHandler::ShowSSLInterstitial()

Differences between //weblayer's ssl_blocking_page.cc and the
//components-level ssl_blocking_page.cc mainly relate to the latter's
usage of CertReportHelper, which helps report invalid certificate
chains:

- The latter calls CertReportHelper::PopulateExtendedReportingOption()
  in its PopulateInterstitialStrings() method
- The latter calls CertReportHelper::HandleReportingCommands()
  in its CommandReceived() method
- The latter inherits SSLBlockingPageBase::OnInterstitialClosing(),
  which calls UpdateMetricsAfterSecurityInterstitial() and
  CertReportHelper::FinishCertCollection() [the //weblayer version's
  impl of OnInterstitialClosing() is empty]

A final difference is that the latter inherits
SSLBlockingPageBase::OverrideRendererPrefs(), which takes action if
|renderer_pref_callback_| is non-null. In the //weblayer context
|renderer_pref_callback_| *is* null as
SSLBlockingPageBase::set_renderer_pref_callback() is never invoked,
so this particular difference won't have any behavioral impact.

Bug: 1025059
Change-Id: I64795ed164cc9e3d778d5ef6d9d505badc9d741a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1924570
Commit-Queue: Colin Blundell <blundell@chromium.org>
Reviewed-by: default avatarEvan Stade <estade@chromium.org>
Reviewed-by: default avatarCarlos IL <carlosil@chromium.org>
Cr-Commit-Position: refs/heads/master@{#719109}
parent 49ace2d5
...@@ -151,8 +151,6 @@ jumbo_static_library("weblayer_lib") { ...@@ -151,8 +151,6 @@ jumbo_static_library("weblayer_lib") {
"browser/navigation_impl.h", "browser/navigation_impl.h",
"browser/profile_impl.cc", "browser/profile_impl.cc",
"browser/profile_impl.h", "browser/profile_impl.h",
"browser/ssl_blocking_page.cc",
"browser/ssl_blocking_page.h",
"browser/ssl_error_controller_client.cc", "browser/ssl_error_controller_client.cc",
"browser/ssl_error_controller_client.h", "browser/ssl_error_controller_client.h",
"browser/ssl_error_handler.cc", "browser/ssl_error_handler.cc",
......
// Copyright 2019 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 "weblayer/browser/ssl_blocking_page.h"
#include <memory>
#include <utility>
#include "base/strings/string_number_conversions.h"
#include "components/security_interstitials/core/metrics_helper.h"
#include "components/security_interstitials/core/ssl_error_options_mask.h"
#include "components/security_interstitials/core/ssl_error_ui.h"
#include "content/public/browser/interstitial_page.h"
#include "content/public/browser/interstitial_page_delegate.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/ssl_status.h"
#include "weblayer/browser/ssl_error_controller_client.h"
namespace weblayer {
// static
const content::InterstitialPageDelegate::TypeID
SSLBlockingPage::kTypeForTesting = &SSLBlockingPage::kTypeForTesting;
// static
SSLBlockingPage* SSLBlockingPage::Create(
content::WebContents* web_contents,
int cert_error,
const net::SSLInfo& ssl_info,
const GURL& request_url,
int options_mask,
const base::Time& time_triggered,
const base::Callback<void(content::CertificateRequestResultType)>&
callback) {
bool overridable = IsOverridable(options_mask);
security_interstitials::MetricsHelper::ReportDetails report_details;
report_details.metric_prefix =
overridable ? "ssl_overridable" : "ssl_nonoverridable";
auto metrics_helper = std::make_unique<security_interstitials::MetricsHelper>(
request_url, report_details, /*history_service=*/nullptr);
return new SSLBlockingPage(web_contents, cert_error, ssl_info, request_url,
options_mask, time_triggered, overridable,
std::move(metrics_helper), callback);
}
bool SSLBlockingPage::ShouldCreateNewNavigation() const {
return true;
}
content::InterstitialPageDelegate::TypeID SSLBlockingPage::GetTypeForTesting() {
return SSLBlockingPage::kTypeForTesting;
}
SSLBlockingPage::~SSLBlockingPage() = default;
void SSLBlockingPage::PopulateInterstitialStrings(
base::DictionaryValue* load_time_data) {
ssl_error_ui_->PopulateStringsForHTML(load_time_data);
}
// Note that we always create a navigation entry with SSL errors.
// No error happening loading a sub-resource triggers an interstitial so far.
SSLBlockingPage::SSLBlockingPage(
content::WebContents* web_contents,
int cert_error,
const net::SSLInfo& ssl_info,
const GURL& request_url,
int options_mask,
const base::Time& time_triggered,
bool overridable,
std::unique_ptr<security_interstitials::MetricsHelper> metrics_helper,
const base::Callback<void(content::CertificateRequestResultType)>& callback)
: security_interstitials::SecurityInterstitialPage(
web_contents,
request_url,
std::make_unique<SSLErrorControllerClient>(
web_contents,
cert_error,
ssl_info,
request_url,
std::move(metrics_helper))),
ssl_info_(ssl_info),
ssl_error_ui_(std::make_unique<security_interstitials::SSLErrorUI>(
request_url,
cert_error,
ssl_info,
options_mask,
time_triggered,
/*support_url=*/GURL(),
controller())) {
DCHECK(callback.is_null());
}
void SSLBlockingPage::OverrideEntry(content::NavigationEntry* entry) {
entry->GetSSL() = content::SSLStatus(ssl_info_);
}
// This handles the commands sent from the interstitial JavaScript.
void SSLBlockingPage::CommandReceived(const std::string& command) {
// content::WaitForRenderFrameReady sends this message when the page
// load completes. Ignore it.
if (command == "\"pageLoadComplete\"")
return;
int cmd = 0;
bool retval = base::StringToInt(command, &cmd);
DCHECK(retval);
ssl_error_ui_->HandleCommand(
static_cast<security_interstitials::SecurityInterstitialCommand>(cmd));
}
void SSLBlockingPage::OnInterstitialClosing() {
// TODO(blundell): Does this need to track metrics analogously to //chrome's
// SSLBlockingPageBase::OnInterstitialClosing()?
}
// static
bool SSLBlockingPage::IsOverridable(int options_mask) {
const bool is_overridable =
(options_mask &
security_interstitials::SSLErrorOptionsMask::SOFT_OVERRIDE_ENABLED) &&
!(options_mask &
security_interstitials::SSLErrorOptionsMask::STRICT_ENFORCEMENT) &&
!(options_mask &
security_interstitials::SSLErrorOptionsMask::HARD_OVERRIDE_DISABLED);
return is_overridable;
}
} // namespace weblayer
// Copyright 2019 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 WEBLAYER_BROWSER_SSL_BLOCKING_PAGE_H_
#define WEBLAYER_BROWSER_SSL_BLOCKING_PAGE_H_
#include <string>
#include "base/callback.h"
#include "base/macros.h"
#include "base/time/time.h"
#include "components/security_interstitials/content/security_interstitial_page.h"
#include "content/public/browser/certificate_request_result_type.h"
#include "net/ssl/ssl_info.h"
#include "url/gurl.h"
namespace security_interstitials {
class MetricsHelper;
class SSLErrorUI;
} // namespace security_interstitials
namespace weblayer {
// A stripped-down version of the class of the same name in
// //chrome/browser/ssl. TODO(estade,blundell): componentize and share instead
// of copying.
class SSLBlockingPage
: public security_interstitials::SecurityInterstitialPage {
public:
// Interstitial type, used in tests.
static const InterstitialPageDelegate::TypeID kTypeForTesting;
~SSLBlockingPage() override;
// Creates an SSL blocking page. If the blocking page isn't shown, the caller
// is responsible for cleaning up the blocking page, otherwise the
// interstitial takes ownership when shown. |options_mask| must be a bitwise
// mask of SSLErrorUI::SSLErrorOptionsMask values.
// This is static because the constructor uses expensive to compute parameters
// more than once (e.g. overrideable).
static SSLBlockingPage* Create(
content::WebContents* web_contents,
int cert_error,
const net::SSLInfo& ssl_info,
const GURL& request_url,
int options_mask,
const base::Time& time_triggered,
const base::Callback<void(content::CertificateRequestResultType)>&
callback);
// InterstitialPageDelegate:
InterstitialPageDelegate::TypeID GetTypeForTesting() override;
// Returns true if |options_mask| refers to a soft-overridable SSL error and
// if SSL error overriding is allowed by policy.
static bool IsOverridable(int options_mask);
// InterstitialPageDelegate.
void CommandReceived(const std::string& command) override;
void OverrideEntry(content::NavigationEntry* entry) override;
void OnInterstitialClosing() override;
// SecurityInterstitialPage:
bool ShouldCreateNewNavigation() const override;
void PopulateInterstitialStrings(
base::DictionaryValue* load_time_data) override;
protected:
SSLBlockingPage(
content::WebContents* web_contents,
int cert_error,
const net::SSLInfo& ssl_info,
const GURL& request_url,
int options_mask,
const base::Time& time_triggered,
bool overrideable,
std::unique_ptr<security_interstitials::MetricsHelper> metrics_helper,
const base::Callback<void(content::CertificateRequestResultType)>&
callback);
private:
base::Callback<void(content::CertificateRequestResultType)> callback_;
const net::SSLInfo ssl_info_;
const std::unique_ptr<security_interstitials::SSLErrorUI> ssl_error_ui_;
DISALLOW_COPY_AND_ASSIGN(SSLBlockingPage);
};
} // namespace weblayer
#endif // WEBLAYER_BROWSER_SSL_BLOCKING_PAGE_H_
...@@ -5,13 +5,17 @@ ...@@ -5,13 +5,17 @@
#include "weblayer/browser/ssl_error_handler.h" #include "weblayer/browser/ssl_error_handler.h"
#include "base/threading/thread_task_runner_handle.h" #include "base/threading/thread_task_runner_handle.h"
#include "components/security_interstitials/content/ssl_blocking_page.h"
#include "components/security_interstitials/content/ssl_cert_reporter.h" #include "components/security_interstitials/content/ssl_cert_reporter.h"
#include "components/security_interstitials/content/ssl_error_navigation_throttle.h" #include "components/security_interstitials/content/ssl_error_navigation_throttle.h"
#include "components/security_interstitials/core/metrics_helper.h"
#include "components/security_interstitials/core/ssl_error_options_mask.h" #include "components/security_interstitials/core/ssl_error_options_mask.h"
#include "components/security_interstitials/core/ssl_error_ui.h" #include "components/security_interstitials/core/ssl_error_ui.h"
#include "weblayer/browser/ssl_blocking_page.h" #include "weblayer/browser/ssl_error_controller_client.h"
#include "weblayer/browser/weblayer_content_browser_overlay_manifest.h" #include "weblayer/browser/weblayer_content_browser_overlay_manifest.h"
namespace weblayer {
namespace { namespace {
// Constructs and shows an SSL interstitial. Adapted from //chrome's // Constructs and shows an SSL interstitial. Adapted from //chrome's
...@@ -28,9 +32,22 @@ void ShowSSLInterstitial( ...@@ -28,9 +32,22 @@ void ShowSSLInterstitial(
void(std::unique_ptr<security_interstitials::SecurityInterstitialPage>)> void(std::unique_ptr<security_interstitials::SecurityInterstitialPage>)>
blocking_page_ready_callback, blocking_page_ready_callback,
int options_mask) { int options_mask) {
auto* interstitial_page = weblayer::SSLBlockingPage::Create( bool overridable = SSLBlockingPage::IsOverridable(options_mask);
security_interstitials::MetricsHelper::ReportDetails report_details;
report_details.metric_prefix =
overridable ? "ssl_overridable" : "ssl_nonoverridable";
auto metrics_helper = std::make_unique<security_interstitials::MetricsHelper>(
request_url, report_details, /*history_service=*/nullptr);
auto controller_client = std::make_unique<SSLErrorControllerClient>(
web_contents, cert_error, ssl_info, request_url,
std::move(metrics_helper));
auto* interstitial_page = new SSLBlockingPage(
web_contents, cert_error, ssl_info, request_url, options_mask, web_contents, cert_error, ssl_info, request_url, options_mask,
base::Time::NowFromSystemTime(), decision_callback); base::Time::NowFromSystemTime(), /*support_url=*/GURL(),
std::move(ssl_cert_reporter), overridable, std::move(controller_client));
// Note: |blocking_page_ready_callback| must be posted due to // Note: |blocking_page_ready_callback| must be posted due to
// HandleSSLError()'s guarantee that it will not invoke this callback // HandleSSLError()'s guarantee that it will not invoke this callback
...@@ -42,8 +59,6 @@ void ShowSSLInterstitial( ...@@ -42,8 +59,6 @@ void ShowSSLInterstitial(
} // namespace } // namespace
namespace weblayer {
void HandleSSLError( void HandleSSLError(
content::WebContents* web_contents, content::WebContents* web_contents,
int cert_error, int cert_error,
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
#include "weblayer/test/interstitial_utils.h" #include "weblayer/test/interstitial_utils.h"
#include "components/security_interstitials/content/security_interstitial_tab_helper.h" #include "components/security_interstitials/content/security_interstitial_tab_helper.h"
#include "weblayer/browser/ssl_blocking_page.h" #include "components/security_interstitials/content/ssl_blocking_page.h"
#include "weblayer/browser/tab_impl.h" #include "weblayer/browser/tab_impl.h"
namespace weblayer { namespace weblayer {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment