blob: ab3fd0de9e0794c2a74ff3574533fddb9a7ca696 [file] [log] [blame]
[email protected]dca589ef2012-01-09 11:53:321// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]8aa7a412011-11-07 12:33:422// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Nicholas Verned391eae2017-11-13 02:41:385#include "chrome/browser/plugins/plugin_info_host_impl.h"
[email protected]8aa7a412011-11-07 12:33:426
avib896c712015-12-26 02:10:437#include <stddef.h>
dcheng4af48582016-04-19 00:29:358
wafflescd59e9b2016-08-30 04:34:449#include <algorithm>
dcheng4af48582016-04-19 00:29:3510#include <memory>
dchenge73d8520c2015-12-27 01:19:0911#include <utility>
avib896c712015-12-26 02:10:4312
[email protected]8aa7a412011-11-07 12:33:4213#include "base/bind.h"
thestigd6e438182017-06-01 23:16:2714#include "base/memory/ptr_util.h"
rbpotter654f42d2016-12-02 22:17:0715#include "base/memory/singleton.h"
[email protected]e309f312013-06-07 21:50:0816#include "base/strings/utf_string_conversions.h"
waffles77255cc2016-08-02 17:25:1217#include "base/task_runner_util.h"
gabb15e19072016-05-11 20:45:4118#include "base/threading/thread_task_runner_handle.h"
avib896c712015-12-26 02:10:4319#include "build/build_config.h"
wfhdfcab2e42014-11-07 06:48:3220#include "chrome/browser/browser_process.h"
peconn5100d432015-09-16 12:03:0821#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
[email protected]6be31d202013-02-01 18:20:5422#include "chrome/browser/plugins/chrome_plugin_service_filter.h"
[email protected]cd33d282012-09-21 12:53:0423#include "chrome/browser/plugins/plugin_finder.h"
[email protected]de75c702012-09-25 23:06:0224#include "chrome/browser/plugins/plugin_metadata.h"
[email protected]601e3c82013-10-03 01:31:2025#include "chrome/browser/plugins/plugin_prefs.h"
raymes978301a22016-09-22 00:54:2826#include "chrome/browser/plugins/plugin_utils.h"
trizzofoa1b970452016-08-26 02:33:2527#include "chrome/browser/plugins/plugins_field_trial.h"
[email protected]8aa7a412011-11-07 12:33:4228#include "chrome/browser/profiles/profile.h"
wfhdfcab2e42014-11-07 06:48:3229#include "chrome/browser/ui/browser_otr_state.h"
Scott Violet6200d332018-02-23 21:29:2330#include "chrome/common/buildflags.h"
wafflescd59e9b2016-08-30 04:34:4431#include "chrome/common/chrome_content_client.h"
tommyclic0c4f942016-09-19 19:35:0032#include "chrome/common/chrome_features.h"
Nicholas Verneb5df4f72017-11-08 09:12:0733#include "chrome/common/plugin.mojom.h"
[email protected]8aa7a412011-11-07 12:33:4234#include "chrome/common/pref_names.h"
waffles77255cc2016-08-02 17:25:1235#include "components/component_updater/component_updater_service.h"
mukai8eaec822014-10-25 17:53:1636#include "components/content_settings/core/browser/content_settings_utils.h"
37#include "components/content_settings/core/browser/host_content_settings_map.h"
mukai077089f2014-09-11 18:41:5238#include "components/content_settings/core/common/content_settings.h"
rbpotter654f42d2016-12-02 22:17:0739#include "components/keyed_service/content/browser_context_keyed_service_shutdown_notifier_factory.h"
Scott Violet9ae82892018-03-01 18:38:1240#include "components/nacl/common/buildflags.h"
Bernhard Bauer19190732017-09-28 09:03:3341#include "components/pref_registry/pref_registry_syncable.h"
brettwb1fc1b82016-02-02 00:19:0842#include "components/prefs/pref_service.h"
nzolghadrd87a308d2016-12-07 15:45:5643#include "components/rappor/rappor_service_impl.h"
Steven Holtef0f46772017-12-11 20:54:5144#include "components/ukm/content/source_url_recorder.h"
[email protected]8aa7a412011-11-07 12:33:4245#include "content/public/browser/browser_thread.h"
[email protected]3a5180ae2011-12-21 02:39:3846#include "content/public/browser/plugin_service.h"
[email protected]31f376c2012-03-13 16:43:0947#include "content/public/browser/plugin_service_filter.h"
tommycli910b4082017-04-03 17:04:1548#include "content/public/browser/render_frame_host.h"
wfhdfcab2e42014-11-07 06:48:3249#include "content/public/common/content_constants.h"
brettw00899e62016-11-12 02:10:1750#include "extensions/features/features.h"
wfhdfcab2e42014-11-07 06:48:3251#include "net/base/registry_controlled_domains/registry_controlled_domain.h"
brettwc5fcdd02016-10-12 07:25:1252#include "ppapi/features/features.h"
Steven Holtef0f46772017-12-11 20:54:5153#include "services/metrics/public/cpp/ukm_builders.h"
Mounir Lamourifd9dcefa2017-07-06 10:26:5554#include "services/metrics/public/cpp/ukm_recorder.h"
[email protected]761fa4702013-07-02 15:25:1555#include "url/gurl.h"
tommyclif2a1e9f2016-10-06 18:34:3656#include "url/origin.h"
[email protected]b9b88a082013-03-21 03:51:0257
brettw00899e62016-11-12 02:10:1758#if BUILDFLAG(ENABLE_EXTENSIONS)
fsamuel8dfa19a2015-05-05 01:00:3959#include "components/guest_view/browser/guest_view_base.h"
Sadrul Habib Chowdhuryf43c33c2014-12-04 15:53:5260#include "extensions/browser/extension_registry.h"
hanxi0d0a1e92014-08-26 18:39:4861#include "extensions/browser/guest_view/web_view/web_view_renderer_state.h"
lfg44c8a68f2015-04-16 16:38:1562#include "extensions/common/constants.h"
Sadrul Habib Chowdhuryf43c33c2014-12-04 15:53:5263#include "extensions/common/extension.h"
64#include "extensions/common/manifest_handlers/webview_info.h"
[email protected]21a20132014-07-16 00:48:5965#endif
66
Nico Weberaf3b00b2017-09-11 17:58:1767#if BUILDFLAG(ENABLE_NACL)
[email protected]e0ff1aa2014-08-16 01:38:1168#include "components/nacl/common/nacl_constants.h"
69#endif
70
[email protected]3a5180ae2011-12-21 02:39:3871using content::PluginService;
[email protected]d7bd3e52013-07-21 04:29:2072using content::WebPluginInfo;
[email protected]3a5180ae2011-12-21 02:39:3873
[email protected]b9b88a082013-03-21 03:51:0274namespace {
75
Daniel Bratell84928c52018-01-16 21:40:3476class PluginInfoHostImplShutdownNotifierFactory
rbpotter654f42d2016-12-02 22:17:0777 : public BrowserContextKeyedServiceShutdownNotifierFactory {
78 public:
Daniel Bratell84928c52018-01-16 21:40:3479 static PluginInfoHostImplShutdownNotifierFactory* GetInstance() {
80 return base::Singleton<PluginInfoHostImplShutdownNotifierFactory>::get();
rbpotter654f42d2016-12-02 22:17:0781 }
82
83 private:
Daniel Bratell84928c52018-01-16 21:40:3484 friend struct base::DefaultSingletonTraits<
85 PluginInfoHostImplShutdownNotifierFactory>;
rbpotter654f42d2016-12-02 22:17:0786
Daniel Bratell84928c52018-01-16 21:40:3487 PluginInfoHostImplShutdownNotifierFactory()
rbpotter654f42d2016-12-02 22:17:0788 : BrowserContextKeyedServiceShutdownNotifierFactory(
Nicholas Verned391eae2017-11-13 02:41:3889 "PluginInfoHostImpl") {}
rbpotter654f42d2016-12-02 22:17:0790
Daniel Bratell84928c52018-01-16 21:40:3491 ~PluginInfoHostImplShutdownNotifierFactory() override {}
rbpotter654f42d2016-12-02 22:17:0792
Daniel Bratell84928c52018-01-16 21:40:3493 DISALLOW_COPY_AND_ASSIGN(PluginInfoHostImplShutdownNotifierFactory);
rbpotter654f42d2016-12-02 22:17:0794};
95
brettw00899e62016-11-12 02:10:1796#if BUILDFLAG(ENABLE_EXTENSIONS)
Sadrul Habib Chowdhuryf43c33c2014-12-04 15:53:5297// Returns whether a request from a plugin to load |resource| from a renderer
98// with process id |process_id| is a request for an internal resource by an app
99// listed in |accessible_resources| in its manifest.
100bool IsPluginLoadingAccessibleResourceInWebView(
101 extensions::ExtensionRegistry* extension_registry,
102 int process_id,
103 const GURL& resource) {
104 extensions::WebViewRendererState* renderer_state =
105 extensions::WebViewRendererState::GetInstance();
106 std::string partition_id;
107 if (!renderer_state->IsGuest(process_id) ||
108 !renderer_state->GetPartitionID(process_id, &partition_id)) {
109 return false;
110 }
111
112 const std::string extension_id = resource.host();
paulmeyerad727fc62015-09-09 15:29:59113 const extensions::Extension* extension = extension_registry->GetExtensionById(
114 extension_id, extensions::ExtensionRegistry::ENABLED);
115 if (!extension || !extensions::WebviewInfo::IsResourceWebviewAccessible(
Nicholas Verned391eae2017-11-13 02:41:38116 extension, partition_id, resource.path())) {
Sadrul Habib Chowdhuryf43c33c2014-12-04 15:53:52117 return false;
118 }
119
120 // Make sure the renderer making the request actually belongs to the
121 // same extension.
122 std::string owner_extension;
123 return renderer_state->GetOwnerInfo(process_id, nullptr, &owner_extension) &&
124 owner_extension == extension_id;
125}
brettw00899e62016-11-12 02:10:17126#endif // BUILDFLAG(ENABLE_EXTENSIONS)
Sadrul Habib Chowdhuryf43c33c2014-12-04 15:53:52127
[email protected]b9b88a082013-03-21 03:51:02128} // namespace
129
Nicholas Verned391eae2017-11-13 02:41:38130PluginInfoHostImpl::Context::Context(int render_process_id, Profile* profile)
[email protected]0a8f3a7f2012-01-17 16:17:19131 : render_process_id_(render_process_id),
[email protected]df02aca2012-02-09 21:03:20132 resource_context_(profile->GetResourceContext()),
brettw00899e62016-11-12 02:10:17133#if BUILDFLAG(ENABLE_EXTENSIONS)
Sadrul Habib Chowdhuryf43c33c2014-12-04 15:53:52134 extension_registry_(extensions::ExtensionRegistry::Get(profile)),
135#endif
Nicholas Verned391eae2017-11-13 02:41:38136 host_content_settings_map_(
137 HostContentSettingsMapFactory::GetForProfile(profile)),
[email protected]601e3c82013-10-03 01:31:20138 plugin_prefs_(PluginPrefs::GetForProfile(profile)) {
[email protected]8aa7a412011-11-07 12:33:42139 allow_outdated_plugins_.Init(prefs::kPluginsAllowOutdated,
[email protected]96a5c342012-12-04 18:14:02140 profile->GetPrefs());
[email protected]6a1c98e02012-10-24 21:49:43141 allow_outdated_plugins_.MoveToThread(
thestig529ad8a2016-07-08 20:30:12142 content::BrowserThread::GetTaskRunnerForThread(
[email protected]6a1c98e02012-10-24 21:49:43143 content::BrowserThread::IO));
Bernhard Bauer19190732017-09-28 09:03:33144 run_all_flash_in_allow_mode_.Init(prefs::kRunAllFlashInAllowMode,
145 profile->GetPrefs());
146 run_all_flash_in_allow_mode_.MoveToThread(
147 content::BrowserThread::GetTaskRunnerForThread(
148 content::BrowserThread::IO));
[email protected]8aa7a412011-11-07 12:33:42149}
150
Nicholas Verned391eae2017-11-13 02:41:38151PluginInfoHostImpl::Context::~Context() {}
[email protected]0a8f3a7f2012-01-17 16:17:19152
Nicholas Verned391eae2017-11-13 02:41:38153void PluginInfoHostImpl::Context::ShutdownOnUIThread() {
rbpotter654f42d2016-12-02 22:17:07154 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
rbpotter654f42d2016-12-02 22:17:07155 allow_outdated_plugins_.Destroy();
Bernhard Bauer19190732017-09-28 09:03:33156 run_all_flash_in_allow_mode_.Destroy();
rbpotter654f42d2016-12-02 22:17:07157}
158
Nicholas Verned391eae2017-11-13 02:41:38159PluginInfoHostImpl::PluginInfoHostImpl(int render_process_id, Profile* profile)
160 : context_(render_process_id, profile),
tommycli910b4082017-04-03 17:04:15161 main_thread_task_runner_(base::ThreadTaskRunnerHandle::Get()),
Nicholas Verneb5df4f72017-11-08 09:12:07162 binding_(this) {
rbpotter654f42d2016-12-02 22:17:07163 shutdown_notifier_ =
Daniel Bratell84928c52018-01-16 21:40:34164 PluginInfoHostImplShutdownNotifierFactory::GetInstance()
165 ->Get(profile)
166 ->Subscribe(base::Bind(&PluginInfoHostImpl::ShutdownOnUIThread,
167 base::Unretained(this)));
rbpotter654f42d2016-12-02 22:17:07168}
169
Nicholas Verned391eae2017-11-13 02:41:38170void PluginInfoHostImpl::ShutdownOnUIThread() {
rbpotter654f42d2016-12-02 22:17:07171 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
172 context_.ShutdownOnUIThread();
173 shutdown_notifier_.reset();
[email protected]0a8f3a7f2012-01-17 16:17:19174}
175
Nicholas Verned391eae2017-11-13 02:41:38176void PluginInfoHostImplTraits::Destruct(const PluginInfoHostImpl* impl) {
Nicholas Verne4ec6cda2017-11-11 11:36:25177 content::BrowserThread::PostTask(
178 content::BrowserThread::IO, FROM_HERE,
Nicholas Verned391eae2017-11-13 02:41:38179 base::BindOnce(&PluginInfoHostImpl::DestructOnBrowserThread,
180 base::Unretained(impl)));
Nicholas Verne4ec6cda2017-11-11 11:36:25181}
182
Nicholas Verned391eae2017-11-13 02:41:38183void PluginInfoHostImpl::DestructOnBrowserThread() const {
Nicholas Verneb5df4f72017-11-08 09:12:07184 binding_.Close();
[email protected]8aa7a412011-11-07 12:33:42185 // Destroy on the UI thread because we contain a |PrefMember|.
186 content::BrowserThread::DeleteOnUIThread::Destruct(this);
187}
188
Bernhard Bauer19190732017-09-28 09:03:33189// static
Nicholas Verned391eae2017-11-13 02:41:38190void PluginInfoHostImpl::RegisterUserPrefs(
Bernhard Bauer19190732017-09-28 09:03:33191 user_prefs::PrefRegistrySyncable* registry) {
192 registry->RegisterBooleanPref(prefs::kPluginsAllowOutdated, false);
Bernhard Bauer19190732017-09-28 09:03:33193 registry->RegisterBooleanPref(prefs::kRunAllFlashInAllowMode, false);
194}
195
Nicholas Verned391eae2017-11-13 02:41:38196PluginInfoHostImpl::~PluginInfoHostImpl() {}
[email protected]649d1c02012-04-27 02:56:21197
Nicholas Verned391eae2017-11-13 02:41:38198struct PluginInfoHostImpl::GetPluginInfo_Params {
[email protected]60eca4eb2013-12-06 00:02:16199 int render_frame_id;
[email protected]8aa7a412011-11-07 12:33:42200 GURL url;
tommyclif2a1e9f2016-10-06 18:34:36201 url::Origin main_frame_origin;
[email protected]8aa7a412011-11-07 12:33:42202 std::string mime_type;
203};
204
Nicholas Verned391eae2017-11-13 02:41:38205void PluginInfoHostImpl::OnPluginInfoHostRequest(
Nicholas Verneb5df4f72017-11-08 09:12:07206 chrome::mojom::PluginInfoHostAssociatedRequest request) {
207 binding_.Bind(std::move(request));
208}
209
Nicholas Verned391eae2017-11-13 02:41:38210void PluginInfoHostImpl::GetPluginInfo(int32_t render_frame_id,
211 const GURL& url,
212 const url::Origin& origin,
213 const std::string& mime_type,
214 const GetPluginInfoCallback& callback) {
Nicholas Verneb5df4f72017-11-08 09:12:07215 GetPluginInfo_Params params = {render_frame_id, url, origin, mime_type};
Nicholas Verned391eae2017-11-13 02:41:38216 PluginService::GetInstance()->GetPlugins(base::BindOnce(
217 &PluginInfoHostImpl::PluginsLoaded, this, params, std::move(callback)));
[email protected]8aa7a412011-11-07 12:33:42218}
219
Nicholas Verned391eae2017-11-13 02:41:38220void PluginInfoHostImpl::PluginsLoaded(
[email protected]8aa7a412011-11-07 12:33:42221 const GetPluginInfo_Params& params,
Nicholas Verneb5df4f72017-11-08 09:12:07222 GetPluginInfoCallback callback,
[email protected]dfdfeb72012-06-08 11:29:02223 const std::vector<WebPluginInfo>& plugins) {
Nicholas Verneb5df4f72017-11-08 09:12:07224 chrome::mojom::PluginInfoPtr output = chrome::mojom::PluginInfo::New();
[email protected]79fa3362012-03-28 16:21:11225 // This also fills in |actual_mime_type|.
dcheng4af48582016-04-19 00:29:35226 std::unique_ptr<PluginMetadata> plugin_metadata;
[email protected]60eca4eb2013-12-06 00:02:16227 if (context_.FindEnabledPlugin(params.render_frame_id, params.url,
tommyclif2a1e9f2016-10-06 18:34:36228 params.main_frame_origin, params.mime_type,
waffles77255cc2016-08-02 17:25:12229 &output->status, &output->plugin,
230 &output->actual_mime_type, &plugin_metadata)) {
tommyclie97656b82016-11-30 16:43:00231 context_.DecidePluginStatus(
232 params.url, params.main_frame_origin, output->plugin,
233 plugin_metadata->GetSecurityStatus(output->plugin),
234 plugin_metadata->identifier(), &output->status);
[email protected]79fa3362012-03-28 16:21:11235 }
[email protected]cd33d282012-09-21 12:53:04236
Nicholas Verneb5df4f72017-11-08 09:12:07237 if (output->status == chrome::mojom::PluginStatus::kNotFound) {
waffles77255cc2016-08-02 17:25:12238 // Check to see if the component updater can fetch an implementation.
239 base::PostTaskAndReplyWithResult(
240 main_thread_task_runner_.get(), FROM_HERE,
Nicholas Verneb5df4f72017-11-08 09:12:07241 base::BindOnce(
waffles77255cc2016-08-02 17:25:12242 &component_updater::ComponentUpdateService::GetComponentForMimeType,
243 base::Unretained(g_browser_process->component_updater()),
244 params.mime_type),
Nicholas Verned391eae2017-11-13 02:41:38245 base::BindOnce(&PluginInfoHostImpl::ComponentPluginLookupDone, this,
246 params, std::move(output), std::move(callback),
Nicholas Verneb5df4f72017-11-08 09:12:07247 std::move(plugin_metadata)));
waffles77255cc2016-08-02 17:25:12248 } else {
Nicholas Verneb5df4f72017-11-08 09:12:07249 GetPluginInfoFinish(params, std::move(output), std::move(callback),
250 std::move(plugin_metadata));
wfhbe79ad52014-11-07 19:02:07251 }
[email protected]8aa7a412011-11-07 12:33:42252}
253
Nicholas Verned391eae2017-11-13 02:41:38254void PluginInfoHostImpl::Context::DecidePluginStatus(
tommyclie97656b82016-11-30 16:43:00255 const GURL& url,
256 const url::Origin& main_frame_origin,
[email protected]546abf32012-09-14 16:55:09257 const WebPluginInfo& plugin,
tommyclie97656b82016-11-30 16:43:00258 PluginMetadata::SecurityStatus security_status,
259 const std::string& plugin_identifier,
Nicholas Verneb5df4f72017-11-08 09:12:07260 chrome::mojom::PluginStatus* status) const {
tommyclie97656b82016-11-30 16:43:00261 if (security_status == PluginMetadata::SECURITY_STATUS_FULLY_TRUSTED) {
Nicholas Verneb5df4f72017-11-08 09:12:07262 *status = chrome::mojom::PluginStatus::kAllowed;
wfhe53608b2016-04-07 02:18:53263 return;
264 }
265
[email protected]8aa7a412011-11-07 12:33:42266 ContentSetting plugin_setting = CONTENT_SETTING_DEFAULT;
267 bool uses_default_content_setting = true;
[email protected]6a9d1deb2014-01-13 19:39:41268 bool is_managed = false;
tommyclie86b2982015-03-16 20:16:45269 // Check plugin content settings. The primary URL is the top origin URL and
270 // the secondary URL is the plugin URL.
raymes978301a22016-09-22 00:54:28271 PluginUtils::GetPluginContentSetting(
tommyclie97656b82016-11-30 16:43:00272 host_content_settings_map_, plugin, main_frame_origin, url,
273 plugin_identifier, &plugin_setting, &uses_default_content_setting,
274 &is_managed);
tommyclie2b1f1b2015-03-31 22:54:59275
tommyclif0555a52015-05-13 15:43:42276 // TODO(tommycli): Remove once we deprecate the plugin ASK policy.
tommyclid727a4c2015-04-21 16:35:05277 bool legacy_ask_user = plugin_setting == CONTENT_SETTING_ASK;
trizzofoa1b970452016-08-26 02:33:25278 plugin_setting = PluginsFieldTrial::EffectiveContentSetting(
raymesb512db82016-10-11 23:07:27279 host_content_settings_map_, CONTENT_SETTINGS_TYPE_PLUGINS,
280 plugin_setting);
tommyclie2b1f1b2015-03-31 22:54:59281
[email protected]8aa7a412011-11-07 12:33:42282 DCHECK(plugin_setting != CONTENT_SETTING_DEFAULT);
tommyclie2b1f1b2015-03-31 22:54:59283 DCHECK(plugin_setting != CONTENT_SETTING_ASK);
[email protected]8aa7a412011-11-07 12:33:42284
Nicholas Verneb5df4f72017-11-08 09:12:07285 if (*status == chrome::mojom::PluginStatus::kFlashHiddenPreferHtml) {
tommyclie97656b82016-11-30 16:43:00286 if (plugin_setting == CONTENT_SETTING_BLOCK) {
287 *status = is_managed && !legacy_ask_user
Nicholas Verneb5df4f72017-11-08 09:12:07288 ? chrome::mojom::PluginStatus::kBlockedByPolicy
289 : chrome::mojom::PluginStatus::kBlockedNoLoading;
tommyclie97656b82016-11-30 16:43:00290 }
291 return;
292 }
293
bauerbecab4f52017-03-13 20:16:41294#if BUILDFLAG(ENABLE_PLUGINS)
tommyclie86b2982015-03-16 20:16:45295 // Check if the plugin is outdated.
tommyclie97656b82016-11-30 16:43:00296 if (security_status == PluginMetadata::SECURITY_STATUS_OUT_OF_DATE &&
[email protected]9f230ed2012-05-24 11:19:40297 !allow_outdated_plugins_.GetValue()) {
[email protected]8aa7a412011-11-07 12:33:42298 if (allow_outdated_plugins_.IsManaged()) {
Nicholas Verneb5df4f72017-11-08 09:12:07299 *status = chrome::mojom::PluginStatus::kOutdatedDisallowed;
[email protected]8aa7a412011-11-07 12:33:42300 } else {
Nicholas Verneb5df4f72017-11-08 09:12:07301 *status = chrome::mojom::PluginStatus::kOutdatedBlocked;
[email protected]8aa7a412011-11-07 12:33:42302 }
303 return;
304 }
bauerbecab4f52017-03-13 20:16:41305#endif // BUILDFLAG(ENABLE_PLUGINS)
[email protected]ef97ce342012-09-24 20:05:02306
tommyclie86b2982015-03-16 20:16:45307 // Check if the plugin is crashing too much.
[email protected]ef97ce342012-09-24 20:05:02308 if (PluginService::GetInstance()->IsPluginUnstable(plugin.path) &&
Nicholas Verned391eae2017-11-13 02:41:38309 plugin_setting != CONTENT_SETTING_BLOCK && uses_default_content_setting) {
Nicholas Verneb5df4f72017-11-08 09:12:07310 *status = chrome::mojom::PluginStatus::kUnauthorized;
[email protected]ef97ce342012-09-24 20:05:02311 return;
312 }
[email protected]8aa7a412011-11-07 12:33:42313
brettw00899e62016-11-12 02:10:17314#if BUILDFLAG(ENABLE_EXTENSIONS)
Sadrul Habib Chowdhuryf43c33c2014-12-04 15:53:52315 // If an app has explicitly made internal resources available by listing them
316 // in |accessible_resources| in the manifest, then allow them to be loaded by
317 // plugins inside a guest-view.
tommyclie97656b82016-11-30 16:43:00318 if (url.SchemeIs(extensions::kExtensionScheme) && !is_managed &&
lfg44c8a68f2015-04-16 16:38:15319 plugin_setting == CONTENT_SETTING_BLOCK &&
tommyclie97656b82016-11-30 16:43:00320 IsPluginLoadingAccessibleResourceInWebView(extension_registry_,
321 render_process_id_, url)) {
Sadrul Habib Chowdhuryf43c33c2014-12-04 15:53:52322 plugin_setting = CONTENT_SETTING_ALLOW;
323 }
brettw00899e62016-11-12 02:10:17324#endif // BUILDFLAG(ENABLE_EXTENSIONS)
Sadrul Habib Chowdhuryf43c33c2014-12-04 15:53:52325
tommycli608ec89b2016-09-28 16:39:00326 if (plugin_setting == CONTENT_SETTING_DETECT_IMPORTANT_CONTENT ||
327 (plugin_setting == CONTENT_SETTING_ALLOW &&
Bernhard Bauer19190732017-09-28 09:03:33328 PluginUtils::ShouldPreferHtmlOverPlugins(host_content_settings_map_) &&
329 !run_all_flash_in_allow_mode_.GetValue())) {
Nicholas Verneb5df4f72017-11-08 09:12:07330 *status = chrome::mojom::PluginStatus::kPlayImportantContent;
tommyclie2b1f1b2015-03-31 22:54:59331 } else if (plugin_setting == CONTENT_SETTING_BLOCK) {
tommyclid727a4c2015-04-21 16:35:05332 // For managed users with the ASK policy, we allow manually running plugins
333 // via context menu. This is the closest to admin intent.
334 *status = is_managed && !legacy_ask_user
Nicholas Verneb5df4f72017-11-08 09:12:07335 ? chrome::mojom::PluginStatus::kBlockedByPolicy
336 : chrome::mojom::PluginStatus::kBlocked;
[email protected]6a9d1deb2014-01-13 19:39:41337 }
[email protected]aea757d2013-09-27 22:27:38338
brettw00899e62016-11-12 02:10:17339#if BUILDFLAG(ENABLE_EXTENSIONS)
tommycli550b2222015-09-03 21:06:10340 // Allow an embedder of <webview> to block a plugin from being loaded inside
341 // the guest. In order to do this, set the status to 'Unauthorized' here,
342 // and update the status as appropriate depending on the response from the
343 // embedder.
Nicholas Verneb5df4f72017-11-08 09:12:07344 if (*status == chrome::mojom::PluginStatus::kAllowed ||
345 *status == chrome::mojom::PluginStatus::kBlocked ||
346 *status == chrome::mojom::PluginStatus::kPlayImportantContent) {
[email protected]140d6cd92014-08-12 18:26:46347 if (extensions::WebViewRendererState::GetInstance()->IsGuest(
tommycli550b2222015-09-03 21:06:10348 render_process_id_))
Nicholas Verneb5df4f72017-11-08 09:12:07349 *status = chrome::mojom::PluginStatus::kUnauthorized;
[email protected]aea757d2013-09-27 22:27:38350 }
tommycli550b2222015-09-03 21:06:10351#endif
[email protected]8aa7a412011-11-07 12:33:42352}
353
Nicholas Verned391eae2017-11-13 02:41:38354bool PluginInfoHostImpl::Context::FindEnabledPlugin(
[email protected]60eca4eb2013-12-06 00:02:16355 int render_frame_id,
[email protected]8aa7a412011-11-07 12:33:42356 const GURL& url,
tommyclif2a1e9f2016-10-06 18:34:36357 const url::Origin& main_frame_origin,
[email protected]8aa7a412011-11-07 12:33:42358 const std::string& mime_type,
Nicholas Verneb5df4f72017-11-08 09:12:07359 chrome::mojom::PluginStatus* status,
[email protected]dfdfeb72012-06-08 11:29:02360 WebPluginInfo* plugin,
[email protected]4da405672012-10-25 10:43:03361 std::string* actual_mime_type,
dcheng4af48582016-04-19 00:29:35362 std::unique_ptr<PluginMetadata>* plugin_metadata) const {
Nicholas Verneb5df4f72017-11-08 09:12:07363 *status = chrome::mojom::PluginStatus::kAllowed;
bauerb96d29c02015-04-09 08:40:35364
[email protected]8aa7a412011-11-07 12:33:42365 bool allow_wildcard = true;
[email protected]dfdfeb72012-06-08 11:29:02366 std::vector<WebPluginInfo> matching_plugins;
[email protected]8aa7a412011-11-07 12:33:42367 std::vector<std::string> mime_types;
368 PluginService::GetInstance()->GetPluginInfoArray(
369 url, mime_type, allow_wildcard, &matching_plugins, &mime_types);
wafflescd59e9b2016-08-30 04:34:44370#if defined(GOOGLE_CHROME_BUILD)
371 base::FilePath not_present =
372 base::FilePath::FromUTF8Unsafe(ChromeContentClient::kNotPresent);
373 matching_plugins.erase(
Nicholas Verned391eae2017-11-13 02:41:38374 std::remove_if(matching_plugins.begin(), matching_plugins.end(),
375 [&not_present](const WebPluginInfo& info) {
376 return info.path == not_present;
377 }),
wafflescd59e9b2016-08-30 04:34:44378 matching_plugins.end());
379#endif // defined(GOOGLE_CHROME_BUILD)
[email protected]4da405672012-10-25 10:43:03380 if (matching_plugins.empty()) {
Nicholas Verneb5df4f72017-11-08 09:12:07381 *status = chrome::mojom::PluginStatus::kNotFound;
[email protected]4da405672012-10-25 10:43:03382 return false;
383 }
384
[email protected]3a5180ae2011-12-21 02:39:38385 content::PluginServiceFilter* filter =
386 PluginService::GetInstance()->GetFilter();
[email protected]4da405672012-10-25 10:43:03387 size_t i = 0;
388 for (; i < matching_plugins.size(); ++i) {
Nicholas Verned391eae2017-11-13 02:41:38389 if (!filter || filter->IsPluginAvailable(
390 render_process_id_, render_frame_id, resource_context_,
391 url, main_frame_origin, &matching_plugins[i])) {
[email protected]4da405672012-10-25 10:43:03392 break;
[email protected]8aa7a412011-11-07 12:33:42393 }
394 }
395
tommyclie86b2982015-03-16 20:16:45396 // If we broke out of the loop, we have found an enabled plugin.
[email protected]4da405672012-10-25 10:43:03397 bool enabled = i < matching_plugins.size();
398 if (!enabled) {
tommyclie86b2982015-03-16 20:16:45399 // Otherwise, we only found disabled plugins, so we take the first one.
[email protected]4da405672012-10-25 10:43:03400 i = 0;
Nicholas Verneb5df4f72017-11-08 09:12:07401 *status = chrome::mojom::PluginStatus::kDisabled;
tommyclic0c4f942016-09-19 19:35:00402
raymesb512db82016-10-11 23:07:27403 if (PluginUtils::ShouldPreferHtmlOverPlugins(host_content_settings_map_) &&
tommyclic0c4f942016-09-19 19:35:00404 matching_plugins[0].name ==
405 base::ASCIIToUTF16(content::kFlashPluginName)) {
Nicholas Verneb5df4f72017-11-08 09:12:07406 *status = chrome::mojom::PluginStatus::kFlashHiddenPreferHtml;
tommyclie97656b82016-11-30 16:43:00407
408 // In the Prefer HTML case, the plugin is actually enabled, but hidden.
409 // It will still be blocked in the body of DecidePluginStatus.
410 enabled = true;
tommyclic0c4f942016-09-19 19:35:00411 }
[email protected]4da405672012-10-25 10:43:03412 }
413
414 *plugin = matching_plugins[i];
415 *actual_mime_type = mime_types[i];
416 if (plugin_metadata)
417 *plugin_metadata = PluginFinder::GetInstance()->GetPluginMetadata(*plugin);
418
419 return enabled;
[email protected]8aa7a412011-11-07 12:33:42420}
421
Nicholas Verned391eae2017-11-13 02:41:38422void PluginInfoHostImpl::ComponentPluginLookupDone(
waffles77255cc2016-08-02 17:25:12423 const GetPluginInfo_Params& params,
Nicholas Verneb5df4f72017-11-08 09:12:07424 chrome::mojom::PluginInfoPtr output,
425 GetPluginInfoCallback callback,
waffles77255cc2016-08-02 17:25:12426 std::unique_ptr<PluginMetadata> plugin_metadata,
waffles77255cc2016-08-02 17:25:12427 std::unique_ptr<component_updater::ComponentInfo> cus_plugin_info) {
428 if (cus_plugin_info) {
Nicholas Verneb5df4f72017-11-08 09:12:07429 output->status = chrome::mojom::PluginStatus::kComponentUpdateRequired;
wafflese7759f72016-10-10 23:41:25430#if defined(OS_LINUX)
431 if (cus_plugin_info->version != base::Version("0")) {
Nicholas Verneb5df4f72017-11-08 09:12:07432 output->status = chrome::mojom::PluginStatus::kRestartRequired;
wafflese7759f72016-10-10 23:41:25433 }
thestigd6e438182017-06-01 23:16:27434#endif
Jeremy Romanec48d7a2018-03-01 17:35:09435 plugin_metadata = std::make_unique<PluginMetadata>(
waffles77255cc2016-08-02 17:25:12436 cus_plugin_info->id, cus_plugin_info->name, false, GURL(), GURL(),
thestigd6e438182017-06-01 23:16:27437 base::ASCIIToUTF16(cus_plugin_info->id), std::string());
waffles77255cc2016-08-02 17:25:12438 }
Nicholas Verneb5df4f72017-11-08 09:12:07439 GetPluginInfoFinish(params, std::move(output), std::move(callback),
440 std::move(plugin_metadata));
waffles77255cc2016-08-02 17:25:12441}
442
Nicholas Verned391eae2017-11-13 02:41:38443void PluginInfoHostImpl::GetPluginInfoFinish(
waffles77255cc2016-08-02 17:25:12444 const GetPluginInfo_Params& params,
Nicholas Verneb5df4f72017-11-08 09:12:07445 chrome::mojom::PluginInfoPtr output,
446 GetPluginInfoCallback callback,
447 std::unique_ptr<PluginMetadata> plugin_metadata) {
waffles77255cc2016-08-02 17:25:12448 if (plugin_metadata) {
449 output->group_identifier = plugin_metadata->identifier();
450 output->group_name = plugin_metadata->name();
451 }
452
453 context_.MaybeGrantAccess(output->status, output->plugin.path);
454
Nicholas Verneb5df4f72017-11-08 09:12:07455 if (output->status != chrome::mojom::PluginStatus::kNotFound) {
waffles77255cc2016-08-02 17:25:12456 main_thread_task_runner_->PostTask(
tommycli910b4082017-04-03 17:04:15457 FROM_HERE,
Nicholas Verned391eae2017-11-13 02:41:38458 base::BindOnce(&PluginInfoHostImpl::ReportMetrics, this,
tzik3f7781d2017-04-20 17:09:33459 params.render_frame_id, output->actual_mime_type,
Steven Holtef0f46772017-12-11 20:54:51460 params.url, params.main_frame_origin));
waffles77255cc2016-08-02 17:25:12461 }
Nicholas Verneb5df4f72017-11-08 09:12:07462 std::move(callback).Run(std::move(output));
waffles77255cc2016-08-02 17:25:12463}
464
Nicholas Verned391eae2017-11-13 02:41:38465void PluginInfoHostImpl::ReportMetrics(int render_frame_id,
466 const base::StringPiece& mime_type,
467 const GURL& url,
Steven Holtef0f46772017-12-11 20:54:51468 const url::Origin& main_frame_origin) {
tommycli910b4082017-04-03 17:04:15469 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
470
471 content::RenderFrameHost* frame = content::RenderFrameHost::FromID(
472 context_.render_process_id(), render_frame_id);
473 content::WebContents* web_contents =
474 content::WebContents::FromRenderFrameHost(frame);
475 // This can occur the web contents has already been closed or navigated away.
476 if (!web_contents)
477 return;
478
479 if (web_contents->GetBrowserContext()->IsOffTheRecord())
480 return;
481
482 rappor::RapporServiceImpl* rappor_service =
483 g_browser_process->rappor_service();
484 if (!rappor_service)
485 return;
486 if (main_frame_origin.unique())
487 return;
488
489 if (mime_type != content::kFlashPluginSwfMimeType &&
490 mime_type != content::kFlashPluginSplMimeType) {
491 return;
492 }
493
494 rappor_service->RecordSampleString(
495 "Plugins.FlashOriginUrl", rappor::ETLD_PLUS_ONE_RAPPOR_TYPE,
496 net::registry_controlled_domains::GetDomainAndRegistry(
497 main_frame_origin.GetURL(),
498 net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES));
499 rappor_service->RecordSampleString(
500 "Plugins.FlashUrl", rappor::ETLD_PLUS_ONE_RAPPOR_TYPE,
501 net::registry_controlled_domains::GetDomainAndRegistry(
502 url, net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES));
503
Steven Holtef0f46772017-12-11 20:54:51504 ukm::builders::Plugins_FlashInstance(
505 ukm::GetSourceIdForWebContentsDocument(web_contents))
506 .Record(ukm::UkmRecorder::Get());
tommycli910b4082017-04-03 17:04:15507}
508
Nicholas Verned391eae2017-11-13 02:41:38509void PluginInfoHostImpl::Context::MaybeGrantAccess(
Nicholas Verneb5df4f72017-11-08 09:12:07510 chrome::mojom::PluginStatus status,
[email protected]650b2d52013-02-10 03:41:45511 const base::FilePath& path) const {
Nicholas Verneb5df4f72017-11-08 09:12:07512 if (status == chrome::mojom::PluginStatus::kAllowed ||
513 status == chrome::mojom::PluginStatus::kPlayImportantContent) {
[email protected]6be31d202013-02-01 18:20:54514 ChromePluginServiceFilter::GetInstance()->AuthorizePlugin(
515 render_process_id_, path);
516 }
517}
518
Nicholas Verned391eae2017-11-13 02:41:38519bool PluginInfoHostImpl::Context::IsPluginEnabled(
[email protected]4cbbeb42014-07-22 19:29:38520 const content::WebPluginInfo& plugin) const {
521 return plugin_prefs_->IsPluginEnabled(plugin);
522}