// Copyright 2020 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/weblayer_security_blocking_page_factory.h" #include "build/build_config.h" #include "components/captive_portal/core/buildflags.h" #include "components/security_interstitials/content/content_metrics_helper.h" #include "components/security_interstitials/content/insecure_form_blocking_page.h" #include "components/security_interstitials/content/settings_page_helper.h" #include "components/security_interstitials/content/ssl_blocking_page.h" #include "components/security_interstitials/core/metrics_helper.h" #include "content/public/browser/web_contents.h" #include "weblayer/browser/captive_portal_service_factory.h" #include "weblayer/browser/insecure_form_controller_client.h" #include "weblayer/browser/ssl_error_controller_client.h" #if BUILDFLAG(IS_ANDROID) #include "content/public/browser/page_navigator.h" #include "content/public/browser/web_contents.h" #include "content/public/common/referrer.h" #include "ui/base/window_open_disposition.h" #endif namespace weblayer { namespace { #if BUILDFLAG(IS_ANDROID) GURL GetCaptivePortalLoginPageUrlInternal() { // NOTE: This is taken from the default login URL in //chrome's // CaptivePortalHelper.java, which is used in the implementation referenced // in OpenLoginPage() below. return GURL("http://connectivitycheck.gstatic.com/generate_204"); } #endif void OpenLoginPage(content::WebContents* web_contents) { // TODO(https://crbug.com/1030692): Componentize and share the // Android implementation from //chrome's // ChromeSecurityBlockingPageFactory::OpenLoginPage(), from which this is // adapted. #if BUILDFLAG(IS_ANDROID) content::OpenURLParams params(GetCaptivePortalLoginPageUrlInternal(), content::Referrer(), WindowOpenDisposition::NEW_FOREGROUND_TAB, ui::PAGE_TRANSITION_LINK, false); web_contents->OpenURL(params); #else NOTIMPLEMENTED(); #endif } std::unique_ptr CreateMetricsHelperAndStartRecording(content::WebContents* web_contents, const GURL& request_url, const std::string& metric_prefix, bool overridable) { security_interstitials::MetricsHelper::ReportDetails report_details; report_details.metric_prefix = metric_prefix; auto metrics_helper = std::make_unique( /*history_service=*/nullptr, request_url, report_details); #if BUILDFLAG(ENABLE_CAPTIVE_PORTAL_DETECTION) metrics_helper.get()->StartRecordingCaptivePortalMetrics( CaptivePortalServiceFactory::GetForBrowserContext( web_contents->GetBrowserContext()), overridable); #endif return metrics_helper; } std::unique_ptr CreateSettingsPageHelper() { // TODO(crbug.com/1078381): Set settings_page_helper once enhanced protection // is supported on weblayer. return nullptr; } } // namespace std::unique_ptr WebLayerSecurityBlockingPageFactory::CreateSSLPage( 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 GURL& support_url, std::unique_ptr ssl_cert_reporter) { bool overridable = SSLBlockingPage::IsOverridable(options_mask); auto controller_client = std::make_unique( web_contents, cert_error, ssl_info, request_url, CreateMetricsHelperAndStartRecording( web_contents, request_url, overridable ? "ssl_overridable" : "ssl_nonoverridable", overridable), CreateSettingsPageHelper()); auto interstitial_page = std::make_unique( web_contents, cert_error, ssl_info, request_url, options_mask, base::Time::NowFromSystemTime(), /*support_url=*/GURL(), std::move(ssl_cert_reporter), overridable, /*can_show_enhanced_protection_message=*/false, std::move(controller_client)); return interstitial_page; } std::unique_ptr WebLayerSecurityBlockingPageFactory::CreateCaptivePortalBlockingPage( content::WebContents* web_contents, const GURL& request_url, const GURL& login_url, std::unique_ptr ssl_cert_reporter, const net::SSLInfo& ssl_info, int cert_error) { auto controller_client = std::make_unique( web_contents, cert_error, ssl_info, request_url, CreateMetricsHelperAndStartRecording(web_contents, request_url, "captive_portal", false), CreateSettingsPageHelper()); auto interstitial_page = std::make_unique( web_contents, request_url, login_url, std::move(ssl_cert_reporter), /*can_show_enhanced_protection_message=*/false, ssl_info, std::move(controller_client), base::BindRepeating(&OpenLoginPage)); return interstitial_page; } std::unique_ptr WebLayerSecurityBlockingPageFactory::CreateBadClockBlockingPage( content::WebContents* web_contents, int cert_error, const net::SSLInfo& ssl_info, const GURL& request_url, const base::Time& time_triggered, ssl_errors::ClockState clock_state, std::unique_ptr ssl_cert_reporter) { auto controller_client = std::make_unique( web_contents, cert_error, ssl_info, request_url, CreateMetricsHelperAndStartRecording(web_contents, request_url, "bad_clock", false), CreateSettingsPageHelper()); auto interstitial_page = std::make_unique( web_contents, cert_error, ssl_info, request_url, base::Time::NowFromSystemTime(), /*can_show_enhanced_protection_message=*/false, clock_state, std::move(ssl_cert_reporter), std::move(controller_client)); return interstitial_page; } std::unique_ptr WebLayerSecurityBlockingPageFactory::CreateMITMSoftwareBlockingPage( content::WebContents* web_contents, int cert_error, const GURL& request_url, std::unique_ptr ssl_cert_reporter, const net::SSLInfo& ssl_info, const std::string& mitm_software_name) { auto controller_client = std::make_unique( web_contents, cert_error, ssl_info, request_url, CreateMetricsHelperAndStartRecording(web_contents, request_url, "mitm_software", false), CreateSettingsPageHelper()); auto interstitial_page = std::make_unique( web_contents, cert_error, request_url, std::move(ssl_cert_reporter), /*can_show_enhanced_protection_message=*/false, ssl_info, mitm_software_name, /*is_enterprise_managed=*/false, std::move(controller_client)); return interstitial_page; } std::unique_ptr WebLayerSecurityBlockingPageFactory::CreateBlockedInterceptionBlockingPage( content::WebContents* web_contents, int cert_error, const GURL& request_url, std::unique_ptr ssl_cert_reporter, const net::SSLInfo& ssl_info) { auto controller_client = std::make_unique( web_contents, cert_error, ssl_info, request_url, CreateMetricsHelperAndStartRecording(web_contents, request_url, "blocked_interception", false), CreateSettingsPageHelper()); auto interstitial_page = std::make_unique( web_contents, cert_error, request_url, std::move(ssl_cert_reporter), /*can_show_enhanced_protection_message=*/false, ssl_info, std::move(controller_client)); return interstitial_page; } std::unique_ptr WebLayerSecurityBlockingPageFactory::CreateInsecureFormBlockingPage( content::WebContents* web_contents, const GURL& request_url) { std::unique_ptr client = std::make_unique(web_contents, request_url); auto page = std::make_unique( web_contents, request_url, std::move(client)); return page; } std::unique_ptr WebLayerSecurityBlockingPageFactory::CreateHttpsOnlyModeBlockingPage( content::WebContents* web_contents, const GURL& request_url) { // HTTPS-only mode is not implemented for weblayer. return nullptr; } #if BUILDFLAG(IS_ANDROID) // static GURL WebLayerSecurityBlockingPageFactory:: GetCaptivePortalLoginPageUrlForTesting() { return GetCaptivePortalLoginPageUrlInternal(); } #endif } // namespace weblayer