123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292 |
- // 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/safe_browsing/safe_browsing_service.h"
- #include <memory>
- #include "base/bind.h"
- #include "base/path_service.h"
- #include "components/prefs/pref_service.h"
- #include "components/safe_browsing/android/remote_database_manager.h"
- #include "components/safe_browsing/android/safe_browsing_api_handler_bridge.h"
- #include "components/safe_browsing/content/browser/browser_url_loader_throttle.h"
- #include "components/safe_browsing/content/browser/mojo_safe_browsing_impl.h"
- #include "components/safe_browsing/content/browser/safe_browsing_navigation_throttle.h"
- #include "components/safe_browsing/content/browser/safe_browsing_network_context.h"
- #include "components/safe_browsing/content/browser/triggers/trigger_manager.h"
- #include "components/safe_browsing/core/browser/realtime/url_lookup_service.h"
- #include "components/safe_browsing/core/common/safe_browsing_prefs.h"
- #include "content/public/browser/browser_context.h"
- #include "content/public/browser/browser_task_traits.h"
- #include "content/public/browser/browser_thread.h"
- #include "content/public/browser/network_service_instance.h"
- #include "content/public/browser/render_process_host.h"
- #include "content/public/browser/resource_context.h"
- #include "services/cert_verifier/public/mojom/cert_verifier_service_factory.mojom.h"
- #include "services/network/public/mojom/network_context.mojom.h"
- #include "services/network/public/mojom/network_service.mojom.h"
- #include "third_party/blink/public/common/loader/url_loader_throttle.h"
- #include "weblayer/browser/browser_context_impl.h"
- #include "weblayer/browser/browser_process.h"
- #include "weblayer/browser/safe_browsing/url_checker_delegate_impl.h"
- #include "weblayer/browser/safe_browsing/weblayer_safe_browsing_blocking_page_factory.h"
- #include "weblayer/browser/safe_browsing/weblayer_ui_manager_delegate.h"
- #include "weblayer/common/features.h"
- namespace weblayer {
- namespace {
- network::mojom::NetworkContextParamsPtr CreateDefaultNetworkContextParams(
- const std::string& user_agent) {
- network::mojom::NetworkContextParamsPtr network_context_params =
- network::mojom::NetworkContextParams::New();
- network_context_params->cert_verifier_params = content::GetCertVerifierParams(
- cert_verifier::mojom::CertVerifierCreationParams::New());
- network_context_params->user_agent = user_agent;
- return network_context_params;
- }
- // Helper method that checks the RenderProcessHost is still alive and checks the
- // latest Safe Browsing pref value on the UI thread before hopping over to the
- // IO thread.
- void MaybeCreateSafeBrowsing(
- int rph_id,
- content::ResourceContext* resource_context,
- base::RepeatingCallback<scoped_refptr<safe_browsing::UrlCheckerDelegate>()>
- get_checker_delegate,
- mojo::PendingReceiver<safe_browsing::mojom::SafeBrowsing> receiver) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
- content::RenderProcessHost* render_process_host =
- content::RenderProcessHost::FromID(rph_id);
- if (!render_process_host)
- return;
- bool is_safe_browsing_enabled = safe_browsing::IsSafeBrowsingEnabled(
- *static_cast<BrowserContextImpl*>(
- render_process_host->GetBrowserContext())
- ->pref_service());
- if (!is_safe_browsing_enabled)
- return;
- content::GetIOThreadTaskRunner({})->PostTask(
- FROM_HERE,
- base::BindOnce(&safe_browsing::MojoSafeBrowsingImpl::MaybeCreate, rph_id,
- resource_context, std::move(get_checker_delegate),
- std::move(receiver)));
- }
- } // namespace
- SafeBrowsingService::SafeBrowsingService(const std::string& user_agent)
- : user_agent_(user_agent) {}
- SafeBrowsingService::~SafeBrowsingService() = default;
- void SafeBrowsingService::Initialize() {
- DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
- if (network_context_) {
- // already initialized
- return;
- }
- base::FilePath user_data_dir;
- bool result =
- base::PathService::Get(base::DIR_ANDROID_APP_DATA, &user_data_dir);
- DCHECK(result);
- // safebrowsing network context needs to be created on the UI thread.
- network_context_ =
- std::make_unique<safe_browsing::SafeBrowsingNetworkContext>(
- user_data_dir, /*trigger_migration=*/false,
- base::BindRepeating(CreateDefaultNetworkContextParams, user_agent_));
- CreateSafeBrowsingUIManager();
- // Needs to happen after |ui_manager_| is created.
- CreateTriggerManager();
- }
- std::unique_ptr<blink::URLLoaderThrottle>
- SafeBrowsingService::CreateURLLoaderThrottle(
- const base::RepeatingCallback<content::WebContents*()>& wc_getter,
- int frame_tree_node_id,
- safe_browsing::RealTimeUrlLookupServiceBase* url_lookup_service) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
- return safe_browsing::BrowserURLLoaderThrottle::Create(
- base::BindOnce(
- [](SafeBrowsingService* sb_service) {
- return sb_service->GetSafeBrowsingUrlCheckerDelegate();
- },
- base::Unretained(this)),
- wc_getter, frame_tree_node_id,
- url_lookup_service ? url_lookup_service->GetWeakPtr() : nullptr);
- }
- std::unique_ptr<content::NavigationThrottle>
- SafeBrowsingService::MaybeCreateSafeBrowsingNavigationThrottleFor(
- content::NavigationHandle* handle) {
- if (!base::FeatureList::IsEnabled(features::kWebLayerSafeBrowsing)) {
- return nullptr;
- }
- return safe_browsing::SafeBrowsingNavigationThrottle::MaybeCreateThrottleFor(
- handle, GetSafeBrowsingUIManager().get());
- }
- scoped_refptr<safe_browsing::UrlCheckerDelegate>
- SafeBrowsingService::GetSafeBrowsingUrlCheckerDelegate() {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- if (!safe_browsing_url_checker_delegate_) {
- safe_browsing_url_checker_delegate_ = new UrlCheckerDelegateImpl(
- GetSafeBrowsingDBManager(), GetSafeBrowsingUIManager());
- }
- return safe_browsing_url_checker_delegate_;
- }
- scoped_refptr<safe_browsing::RemoteSafeBrowsingDatabaseManager>
- SafeBrowsingService::GetSafeBrowsingDBManager() {
- if (!safe_browsing_db_manager_) {
- CreateAndStartSafeBrowsingDBManager();
- }
- return safe_browsing_db_manager_;
- }
- scoped_refptr<safe_browsing::SafeBrowsingUIManager>
- SafeBrowsingService::GetSafeBrowsingUIManager() {
- return ui_manager_;
- }
- safe_browsing::TriggerManager* SafeBrowsingService::GetTriggerManager() {
- return trigger_manager_.get();
- }
- void SafeBrowsingService::CreateSafeBrowsingUIManager() {
- DCHECK(!ui_manager_);
- ui_manager_ = new safe_browsing::SafeBrowsingUIManager(
- std::make_unique<WebLayerSafeBrowsingUIManagerDelegate>(),
- std::make_unique<WebLayerSafeBrowsingBlockingPageFactory>(),
- GURL(url::kAboutBlankURL));
- }
- void SafeBrowsingService::CreateTriggerManager() {
- DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
- trigger_manager_ = std::make_unique<safe_browsing::TriggerManager>(
- ui_manager_.get(), BrowserProcess::GetInstance()->GetLocalState());
- }
- void SafeBrowsingService::CreateAndStartSafeBrowsingDBManager() {
- DCHECK(!safe_browsing_db_manager_);
- safe_browsing_db_manager_ =
- new safe_browsing::RemoteSafeBrowsingDatabaseManager();
- if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)) {
- // Posting a task to start the DB here ensures that it will be started by
- // the time that a consumer uses it on the IO thread, as such a consumer
- // would need to make it available for usage on the IO thread via a
- // PostTask() that will be ordered after this one.
- content::GetIOThreadTaskRunner({})->PostTask(
- FROM_HERE,
- base::BindOnce(
- &SafeBrowsingService::StartSafeBrowsingDBManagerOnIOThread,
- base::Unretained(this)));
- } else {
- StartSafeBrowsingDBManagerOnIOThread();
- }
- }
- void SafeBrowsingService::StartSafeBrowsingDBManagerOnIOThread() {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- DCHECK(safe_browsing_db_manager_);
- if (started_db_manager_)
- return;
- started_db_manager_ = true;
- // V4ProtocolConfig is not used. Just create one with empty values.
- safe_browsing::V4ProtocolConfig config("", false, "", "");
- safe_browsing_db_manager_->StartOnIOThread(GetURLLoaderFactoryOnIOThread(),
- config);
- }
- scoped_refptr<network::SharedURLLoaderFactory>
- SafeBrowsingService::GetURLLoaderFactoryOnIOThread() {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- if (!shared_url_loader_factory_on_io_) {
- content::GetUIThreadTaskRunner({})->PostTask(
- FROM_HERE,
- base::BindOnce(&SafeBrowsingService::CreateURLLoaderFactoryForIO,
- base::Unretained(this),
- url_loader_factory_on_io_.BindNewPipeAndPassReceiver()));
- shared_url_loader_factory_on_io_ =
- base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
- url_loader_factory_on_io_.get());
- }
- return shared_url_loader_factory_on_io_;
- }
- void SafeBrowsingService::CreateURLLoaderFactoryForIO(
- mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
- auto url_loader_factory_params =
- network::mojom::URLLoaderFactoryParams::New();
- url_loader_factory_params->process_id = network::mojom::kBrowserProcessId;
- url_loader_factory_params->is_corb_enabled = false;
- network_context_->GetNetworkContext()->CreateURLLoaderFactory(
- std::move(receiver), std::move(url_loader_factory_params));
- }
- void SafeBrowsingService::AddInterface(
- service_manager::BinderRegistry* registry,
- content::RenderProcessHost* render_process_host) {
- content::ResourceContext* resource_context =
- render_process_host->GetBrowserContext()->GetResourceContext();
- registry->AddInterface(
- base::BindRepeating(
- &MaybeCreateSafeBrowsing, render_process_host->GetID(),
- resource_context,
- base::BindRepeating(
- &SafeBrowsingService::GetSafeBrowsingUrlCheckerDelegate,
- base::Unretained(this))),
- content::GetUIThreadTaskRunner({}));
- }
- void SafeBrowsingService::StopDBManager() {
- content::GetIOThreadTaskRunner({})->PostTask(
- FROM_HERE, base::BindOnce(&SafeBrowsingService::StopDBManagerOnIOThread,
- base::Unretained(this)));
- }
- void SafeBrowsingService::StopDBManagerOnIOThread() {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- if (safe_browsing_db_manager_) {
- safe_browsing_db_manager_->StopOnIOThread(true /*shutdown*/);
- safe_browsing_db_manager_.reset();
- started_db_manager_ = false;
- }
- }
- network::mojom::NetworkContext* SafeBrowsingService::GetNetworkContext() {
- if (!network_context_)
- return nullptr;
- return network_context_->GetNetworkContext();
- }
- scoped_refptr<network::SharedURLLoaderFactory>
- SafeBrowsingService::GetURLLoaderFactory() {
- if (!network_context_)
- return nullptr;
- return network_context_->GetURLLoaderFactory();
- }
- } // namespace weblayer
|