Commit 40121f83 authored by Colin Blundell's avatar Colin Blundell Committed by Commit Bot

[WebLayer] Integrate showing bad clock interstitial

This CL integrates a check for whether to display the bad clock
interstitial into WebLayer's SSLErrorHandler. The check is modeled on
that in //chrome's SSLErrorHandler. However, we did not port the
fetch of NetworkTimeTracker's time into //weblayer: this fetch
introduces a fair degree of complexity into the flow by making it
asynchronous, and it is not relevant on Android, where such fetches
are not supported. This fetch will be incorporated when WebLayer
shares //chrome's SSLErrorHandler implementation as part of
crbug.com/1026547.

Just like in Chrome, the bad clock interstitial is shown when there
is an expired certificate and the network time is reported as being
ahead or behind of the actual time. The network time is not always
seeded, in which case the application defaults to showing the generic
SSL interstitial. In particular, for Chrome on Android the network time
is seeded either via sync or via the Variations Service. The latter
will apply in WebLayer once variations is integrated.

This CL adds a browsertest of the relevant functionality; the
browsertest is adapted from one in //chrome and manually sets the
network time in order to trigger the bad clock interstitial showing.
(I did a similar exercise in the shell locally on Android and Linux to
verify the showing of the interstitial).

Note that opening the date/time from the interstitial is not yet
supported; a followup CL will bring up that support by sharing the
relevant implementation from //chrome.

Change-Id: I176a342c5de328441d26a22f28742dba6793a1ed
Bug: 1025059
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1983170
Commit-Queue: Colin Blundell <blundell@chromium.org>
Reviewed-by: default avatarJohn Abd-El-Malek <jam@chromium.org>
Cr-Commit-Position: refs/heads/master@{#730170}
parent 0cf1a9ff
......@@ -220,6 +220,7 @@ jumbo_static_library("weblayer_lib") {
"//components/security_interstitials/content/renderer:security_interstitial_page_controller",
"//components/security_interstitials/core",
"//components/spellcheck:buildflags",
"//components/ssl_errors",
"//components/startup_metric_utils/browser:lib",
"//components/user_prefs",
"//components/version_info",
......
......@@ -16,6 +16,7 @@ include_rules = [
"+components/safe_browsing",
"+components/security_interstitials",
"+components/spellcheck/browser",
"+components/ssl_errors",
"+components/startup_metric_utils",
"+components/version_info",
"+components/web_cache/browser",
......
......@@ -24,6 +24,8 @@ BrowserProcess* g_browser_process = nullptr;
std::unique_ptr<PrefService> CreatePrefService() {
auto pref_registry = base::MakeRefCounted<PrefRegistrySimple>();
network_time::NetworkTimeTracker::RegisterPrefs(pref_registry.get());
PrefServiceFactory pref_service_factory;
pref_service_factory.set_user_prefs(
base::MakeRefCounted<InMemoryPrefStore>());
......
This diff is collapsed.
......@@ -51,4 +51,8 @@ void SSLErrorControllerClient::OpenUrlInNewForegroundTab(const GURL& url) {
OpenUrlInCurrentTab(url);
}
bool SSLErrorControllerClient::CanLaunchDateAndTimeSettings() {
return true;
}
} // namespace weblayer
......@@ -38,6 +38,7 @@ class SSLErrorControllerClient
void GoBack() override;
void Proceed() override;
void OpenUrlInNewForegroundTab(const GURL& url) override;
bool CanLaunchDateAndTimeSettings() override;
private:
const int cert_error_;
......
......@@ -6,6 +6,7 @@
#include "base/threading/thread_task_runner_handle.h"
#include "build/build_config.h"
#include "components/security_interstitials/content/bad_clock_blocking_page.h"
#include "components/security_interstitials/content/captive_portal_blocking_page.h"
#include "components/security_interstitials/content/ssl_blocking_page.h"
#include "components/security_interstitials/content/ssl_cert_reporter.h"
......@@ -13,6 +14,8 @@
#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 "components/ssl_errors/error_info.h"
#include "weblayer/browser/browser_process.h"
#include "weblayer/browser/ssl_error_controller_client.h"
#include "weblayer/browser/weblayer_content_browser_overlay_manifest.h"
......@@ -146,6 +149,40 @@ void ShowSSLInterstitial(
base::WrapUnique(interstitial_page)));
}
// Constructs and shows a bad clock interstitial. Adapted from //chrome's
// SSLErrorHandlerDelegateImpl::ShowCaptivePortalInterstitial().
void ShowBadClockInterstitial(
content::WebContents* web_contents,
int cert_error,
const net::SSLInfo& ssl_info,
const GURL& request_url,
ssl_errors::ClockState clock_state,
std::unique_ptr<SSLCertReporter> ssl_cert_reporter,
base::OnceCallback<
void(std::unique_ptr<security_interstitials::SecurityInterstitialPage>)>
blocking_page_ready_callback) {
security_interstitials::MetricsHelper::ReportDetails report_details;
report_details.metric_prefix = "bad_clock";
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 BadClockBlockingPage(
web_contents, cert_error, ssl_info, request_url,
base::Time::NowFromSystemTime(), clock_state,
std::move(ssl_cert_reporter), 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(
......@@ -157,7 +194,35 @@ void HandleSSLError(
base::OnceCallback<
void(std::unique_ptr<security_interstitials::SecurityInterstitialPage>)>
blocking_page_ready_callback) {
// First check for captive portal.
// Check for a clock error.
if (ssl_errors::ErrorInfo::NetErrorToErrorType(cert_error) ==
ssl_errors::ErrorInfo::CERT_DATE_INVALID) {
// This implementation is adapted from //chrome's
// SSLErrorHandler::HandleCertDateInvalidErrorImpl(). Note that we did not
// port the fetch of NetworkTimeTracker's time made in //chrome's
// SSLErrorHandler::HandleCertDateInvalidError() into //weblayer: this
// fetch introduces a fair degree of complexity into the flow by making it
// asynchronous, and it is not relevant on Android, where such fetches are
// not supported. This fetch will be incorporated when WebLayer shares
// //chrome's SSLErrorHandler implementation as part of crbug.com/1026547.
const base::Time now = base::Time::NowFromSystemTime();
network_time::NetworkTimeTracker* tracker =
BrowserProcess::GetInstance()->GetNetworkTimeTracker();
ssl_errors::ClockState clock_state =
ssl_errors::GetClockState(now, tracker);
if (clock_state == ssl_errors::CLOCK_STATE_FUTURE ||
clock_state == ssl_errors::CLOCK_STATE_PAST) {
ShowBadClockInterstitial(web_contents, cert_error, ssl_info, request_url,
clock_state, std::move(ssl_cert_reporter),
std::move(blocking_page_ready_callback));
return;
}
}
// Next check for a captive portal.
// TODO(https://crbug.com/1030692): Share the check for known captive
// portal certificates from //chrome's SSLErrorHandler:757.
......
......@@ -7,6 +7,12 @@ IDS_CAPTIVE_PORTAL_PRIMARY_PARAGRAPH_NO_LOGIN_URL_WIFI_SSID
IDS_CAPTIVE_PORTAL_PRIMARY_PARAGRAPH_WIFI
IDS_CAPTIVE_PORTAL_PRIMARY_PARAGRAPH_WIRED
IDS_CAPTIVE_PORTAL_PRIMARY_PARAGRAPH_WIFI_SSID
IDS_CLOCK_ERROR_AHEAD_HEADING
IDS_CLOCK_ERROR_BEHIND_HEADING
IDS_CLOCK_ERROR_EXPLANATION
IDS_CLOCK_ERROR_PRIMARY_PARAGRAPH
IDS_CLOCK_ERROR_TITLE
IDS_CLOCK_ERROR_UPDATE_DATE_AND_TIME
IDS_SSL_OPEN_DETAILS_BUTTON
IDS_SSL_CLOSE_DETAILS_BUTTON
IDS_SSL_NONOVERRIDABLE_HSTS
......
......@@ -81,6 +81,7 @@ test("weblayer_browsertests") {
"//components/autofill/core/browser",
"//components/autofill/core/browser:test_support",
"//components/autofill/core/common",
"//components/network_time",
"//components/security_interstitials/content:security_interstitial_page",
"//content/public/browser",
"//content/test:test_support",
......
......@@ -4,6 +4,7 @@
#include "weblayer/test/interstitial_utils.h"
#include "components/security_interstitials/content/bad_clock_blocking_page.h"
#include "components/security_interstitials/content/captive_portal_blocking_page.h"
#include "components/security_interstitials/content/security_interstitial_tab_helper.h"
#include "components/security_interstitials/content/ssl_blocking_page.h"
......@@ -57,4 +58,9 @@ bool IsShowingCaptivePortalInterstitial(Tab* tab) {
tab, CaptivePortalBlockingPage::kTypeForTesting);
}
bool IsShowingBadClockInterstitial(Tab* tab) {
return IsShowingInterstitialOfType(tab,
BadClockBlockingPage::kTypeForTesting);
}
} // namespace weblayer
......@@ -24,6 +24,9 @@ bool IsShowingSSLInterstitial(Tab* tab);
// |tab|.
bool IsShowingCaptivePortalInterstitial(Tab* tab);
// Returns true iff a bad clock interstitial is currently displaying in |tab|.
bool IsShowingBadClockInterstitial(Tab* tab);
} // namespace weblayer
#endif // WEBLAYER_TEST_INTERSTITIAL_UTILS_H_
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