blob: ee041a8b68db92cf2f3a89d195736e3747104aad [file] [log] [blame]
// 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_error_handler.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_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_ui.h"
#include "weblayer/browser/ssl_error_controller_client.h"
#include "weblayer/browser/weblayer_content_browser_overlay_manifest.h"
namespace weblayer {
namespace {
// Constructs and shows an SSL interstitial. Adapted from //chrome's
// SSLErrorHandlerDelegateImpl::ShowSSLInterstitial().
void ShowSSLInterstitial(
content::WebContents* web_contents,
int cert_error,
const net::SSLInfo& ssl_info,
const GURL& request_url,
std::unique_ptr<SSLCertReporter> ssl_cert_reporter,
const base::Callback<void(content::CertificateRequestResultType)>&
decision_callback,
base::OnceCallback<
void(std::unique_ptr<security_interstitials::SecurityInterstitialPage>)>
blocking_page_ready_callback,
int options_mask) {
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,
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
// HandleSSLError()'s guarantee that it will not invoke this callback
// synchronously.
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::BindOnce(std::move(blocking_page_ready_callback),
base::WrapUnique(interstitial_page)));
}
} // namespace
void HandleSSLError(
content::WebContents* web_contents,
int cert_error,
const net::SSLInfo& ssl_info,
const GURL& request_url,
std::unique_ptr<SSLCertReporter> ssl_cert_reporter,
const base::Callback<void(content::CertificateRequestResultType)>&
decision_callback,
base::OnceCallback<
void(std::unique_ptr<security_interstitials::SecurityInterstitialPage>)>
blocking_page_ready_callback) {
// NOTE: In Chrome hard overrides can be disabled for the Profile by setting
// the kSSLErrorOverrideAllowed preference (which defaults to true) to false.
// However, in WebLayer there is currently no way for the user to set this
// preference.
bool hard_override_disabled = false;
int options_mask = security_interstitials::CalculateSSLErrorOptionsMask(
cert_error, hard_override_disabled, ssl_info.is_fatal_cert_error);
// Handle all errors by showing SSL interstitials. If this needs to get more
// refined in the short-term, can adapt logic from
// SSLErrorHandler::StartHandlingError() as needed (in the long-term, WebLayer
// will most likely share a componentized version of //chrome's
// SSLErrorHandler).
ShowSSLInterstitial(web_contents, cert_error, ssl_info, request_url,
std::move(ssl_cert_reporter),
std::move(decision_callback),
std::move(blocking_page_ready_callback), options_mask);
}
} // namespace weblayer