2015-09-25 13:59:30 +02:00
|
|
|
// Copyright (c) 2015 The Chromium Embedded Framework 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 "libcef/browser/plugins/plugin_service_filter.h"
|
|
|
|
|
|
|
|
#include "include/cef_request_context_handler.h"
|
2019-10-01 15:55:16 +02:00
|
|
|
#include "libcef/browser/browser_context.h"
|
2015-09-25 13:59:30 +02:00
|
|
|
#include "libcef/browser/thread_util.h"
|
|
|
|
#include "libcef/browser/web_plugin_impl.h"
|
2020-06-28 20:29:44 +02:00
|
|
|
#include "libcef/common/alloy/alloy_content_client.h"
|
2021-08-19 23:07:44 +02:00
|
|
|
#include "libcef/common/frame_util.h"
|
2015-09-25 13:59:30 +02:00
|
|
|
|
2016-10-17 20:14:44 +02:00
|
|
|
#include "extensions/common/constants.h"
|
|
|
|
|
2017-05-17 11:29:28 +02:00
|
|
|
CefPluginServiceFilter::CefPluginServiceFilter() {}
|
2015-09-25 13:59:30 +02:00
|
|
|
|
|
|
|
bool CefPluginServiceFilter::IsPluginAvailable(
|
|
|
|
int render_process_id,
|
|
|
|
int render_frame_id,
|
|
|
|
const GURL& url,
|
2017-01-19 00:37:56 +01:00
|
|
|
bool is_main_frame,
|
2016-10-21 21:52:29 +02:00
|
|
|
const url::Origin& main_frame_origin,
|
2015-09-25 13:59:30 +02:00
|
|
|
content::WebPluginInfo* plugin) {
|
2019-10-01 15:55:16 +02:00
|
|
|
CEF_REQUIRE_UIT();
|
|
|
|
DCHECK_GT(render_process_id, 0);
|
2017-11-29 00:00:50 +01:00
|
|
|
|
2017-12-07 22:44:24 +01:00
|
|
|
chrome::mojom::PluginStatus status = chrome::mojom::PluginStatus::kAllowed;
|
2016-10-17 20:14:44 +02:00
|
|
|
|
2017-01-19 00:37:56 +01:00
|
|
|
// Perform origin check here because we're passing an empty origin value to
|
|
|
|
// IsPluginAvailable() below.
|
|
|
|
const GURL& policy_url = main_frame_origin.GetURL();
|
|
|
|
if (!policy_url.is_empty() &&
|
|
|
|
policy_url.scheme() == extensions::kExtensionScheme) {
|
|
|
|
// Always allow extension origins to load plugins.
|
|
|
|
// TODO(extensions): Revisit this decision once CEF supports more than just
|
|
|
|
// the PDF extension.
|
|
|
|
return true;
|
|
|
|
}
|
2016-10-17 20:14:44 +02:00
|
|
|
|
2017-01-19 00:37:56 +01:00
|
|
|
// Blink requires this method to return a consistent value during renderer
|
|
|
|
// process initialization and page load, so we always call IsPluginAvailable()
|
|
|
|
// with an empty origin. If we return false then the plugin will not be listed
|
|
|
|
// in navigator.plugins and navigating to the plugin mime type will trigger
|
|
|
|
// the download code path. If we return true then individual plugin instance
|
2020-06-28 20:29:44 +02:00
|
|
|
// loads will be evaluated in
|
|
|
|
// AlloyContentRendererClient::OverrideCreatePlugin, which will result in a
|
|
|
|
// call to CefPluginInfoMessageFilter::PluginsLoaded to retrieve the actual
|
|
|
|
// load decision with a non-empty origin. That will determine whether the
|
|
|
|
// plugin load is allowed or the plugin placeholder is displayed.
|
2019-10-01 15:55:16 +02:00
|
|
|
return IsPluginAvailable(render_process_id, render_frame_id, url,
|
|
|
|
is_main_frame, url::Origin(), plugin, &status);
|
2015-09-25 13:59:30 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
bool CefPluginServiceFilter::CanLoadPlugin(int render_process_id,
|
|
|
|
const base::FilePath& path) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool CefPluginServiceFilter::IsPluginAvailable(
|
2017-01-19 00:37:56 +01:00
|
|
|
int render_process_id,
|
2017-12-07 22:44:24 +01:00
|
|
|
int render_frame_id,
|
2015-09-25 13:59:30 +02:00
|
|
|
const GURL& url,
|
2017-01-19 00:37:56 +01:00
|
|
|
bool is_main_frame,
|
2016-10-21 21:52:29 +02:00
|
|
|
const url::Origin& main_frame_origin,
|
2015-09-25 13:59:30 +02:00
|
|
|
content::WebPluginInfo* plugin,
|
2017-12-07 22:44:24 +01:00
|
|
|
chrome::mojom::PluginStatus* status) {
|
2019-10-01 15:55:16 +02:00
|
|
|
CEF_REQUIRE_UIT();
|
|
|
|
DCHECK_GT(render_process_id, 0);
|
2017-12-07 22:44:24 +01:00
|
|
|
|
|
|
|
if (*status == chrome::mojom::PluginStatus::kNotFound) {
|
2015-09-25 13:59:30 +02:00
|
|
|
// The plugin does not exist so no need to query the handler.
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2020-06-28 20:29:44 +02:00
|
|
|
if (plugin->path == CefString(AlloyContentClient::kPDFPluginPath)) {
|
2015-09-25 13:59:30 +02:00
|
|
|
// Always allow the internal PDF plugin to load.
|
2017-12-07 22:44:24 +01:00
|
|
|
*status = chrome::mojom::PluginStatus::kAllowed;
|
2015-09-25 13:59:30 +02:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2016-10-21 21:52:29 +02:00
|
|
|
const GURL& policy_url = main_frame_origin.GetURL();
|
2016-10-17 20:14:44 +02:00
|
|
|
if (!policy_url.is_empty() &&
|
|
|
|
policy_url.scheme() == extensions::kExtensionScheme) {
|
|
|
|
// Always allow extension origins to load plugins.
|
|
|
|
// TODO(extensions): Revisit this decision once CEF supports more than just
|
|
|
|
// the PDF extension.
|
2017-12-07 22:44:24 +01:00
|
|
|
*status = chrome::mojom::PluginStatus::kAllowed;
|
2016-10-17 20:14:44 +02:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2021-08-19 23:07:44 +02:00
|
|
|
const auto global_id = frame_util::MakeGlobalId(
|
|
|
|
render_process_id, render_frame_id, /*allow_invalid_frame_id=*/true);
|
|
|
|
auto browser_context = CefBrowserContext::FromGlobalId(global_id, false);
|
2019-10-01 15:55:16 +02:00
|
|
|
CefRefPtr<CefRequestContextHandler> handler;
|
|
|
|
if (browser_context) {
|
2021-08-19 23:07:44 +02:00
|
|
|
handler = browser_context->GetHandler(global_id, false);
|
2019-10-01 15:55:16 +02:00
|
|
|
}
|
|
|
|
|
2017-01-19 00:37:56 +01:00
|
|
|
if (!handler) {
|
|
|
|
// No handler so go with the default plugin load decision.
|
2017-12-07 22:44:24 +01:00
|
|
|
return *status != chrome::mojom::PluginStatus::kDisabled;
|
2017-01-19 00:37:56 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// Check for a cached plugin load decision.
|
2019-10-01 15:55:16 +02:00
|
|
|
if (browser_context->HasPluginLoadDecision(render_process_id, plugin->path,
|
|
|
|
is_main_frame, main_frame_origin,
|
|
|
|
status)) {
|
2017-12-07 22:44:24 +01:00
|
|
|
return *status != chrome::mojom::PluginStatus::kDisabled;
|
2017-01-19 00:37:56 +01:00
|
|
|
}
|
2015-09-25 13:59:30 +02:00
|
|
|
|
2017-01-19 00:37:56 +01:00
|
|
|
CefRefPtr<CefWebPluginInfoImpl> pluginInfo(new CefWebPluginInfoImpl(*plugin));
|
|
|
|
|
|
|
|
cef_plugin_policy_t plugin_policy = PLUGIN_POLICY_ALLOW;
|
|
|
|
switch (*status) {
|
2017-12-07 22:44:24 +01:00
|
|
|
case chrome::mojom::PluginStatus::kAllowed:
|
2017-01-19 00:37:56 +01:00
|
|
|
plugin_policy = PLUGIN_POLICY_ALLOW;
|
|
|
|
break;
|
2017-12-07 22:44:24 +01:00
|
|
|
case chrome::mojom::PluginStatus::kBlocked:
|
|
|
|
case chrome::mojom::PluginStatus::kBlockedByPolicy:
|
|
|
|
case chrome::mojom::PluginStatus::kOutdatedBlocked:
|
|
|
|
case chrome::mojom::PluginStatus::kOutdatedDisallowed:
|
|
|
|
case chrome::mojom::PluginStatus::kUnauthorized:
|
2017-01-19 00:37:56 +01:00
|
|
|
plugin_policy = PLUGIN_POLICY_BLOCK;
|
|
|
|
break;
|
2017-12-07 22:44:24 +01:00
|
|
|
case chrome::mojom::PluginStatus::kDisabled:
|
2017-01-19 00:37:56 +01:00
|
|
|
plugin_policy = PLUGIN_POLICY_DISABLE;
|
|
|
|
break;
|
2017-12-07 22:44:24 +01:00
|
|
|
case chrome::mojom::PluginStatus::kPlayImportantContent:
|
2017-01-19 00:37:56 +01:00
|
|
|
plugin_policy = PLUGIN_POLICY_DETECT_IMPORTANT;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
NOTREACHED();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (handler->OnBeforePluginLoad(plugin->mime_types[0].mime_type,
|
2017-05-17 11:29:28 +02:00
|
|
|
url.possibly_invalid_spec(), is_main_frame,
|
2017-01-19 00:37:56 +01:00
|
|
|
policy_url.possibly_invalid_spec(),
|
2017-05-17 11:29:28 +02:00
|
|
|
pluginInfo.get(), &plugin_policy)) {
|
2017-01-19 00:37:56 +01:00
|
|
|
switch (plugin_policy) {
|
|
|
|
case PLUGIN_POLICY_ALLOW:
|
2017-12-07 22:44:24 +01:00
|
|
|
*status = chrome::mojom::PluginStatus::kAllowed;
|
2015-09-25 13:59:30 +02:00
|
|
|
break;
|
2017-01-19 00:37:56 +01:00
|
|
|
case PLUGIN_POLICY_DETECT_IMPORTANT:
|
2017-12-07 22:44:24 +01:00
|
|
|
*status = chrome::mojom::PluginStatus::kPlayImportantContent;
|
2015-09-25 13:59:30 +02:00
|
|
|
break;
|
2017-01-19 00:37:56 +01:00
|
|
|
case PLUGIN_POLICY_BLOCK:
|
2017-12-07 22:44:24 +01:00
|
|
|
*status = chrome::mojom::PluginStatus::kBlocked;
|
2015-09-25 13:59:30 +02:00
|
|
|
break;
|
2017-01-19 00:37:56 +01:00
|
|
|
case PLUGIN_POLICY_DISABLE:
|
2017-12-07 22:44:24 +01:00
|
|
|
*status = chrome::mojom::PluginStatus::kDisabled;
|
2015-09-25 13:59:30 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-01-19 00:37:56 +01:00
|
|
|
// Cache the plugin load decision.
|
2019-10-01 15:55:16 +02:00
|
|
|
browser_context->AddPluginLoadDecision(render_process_id, plugin->path,
|
|
|
|
is_main_frame, main_frame_origin,
|
|
|
|
*status);
|
2017-01-19 00:37:56 +01:00
|
|
|
|
2017-12-07 22:44:24 +01:00
|
|
|
return *status != chrome::mojom::PluginStatus::kDisabled;
|
2015-09-25 13:59:30 +02:00
|
|
|
}
|