// Copyright (c) 2012 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 "chrome/browser/plugins/plugin_info_host_impl.h"

#include <stddef.h>

#include <algorithm>
#include <memory>
#include <utility>

#include "base/bind.h"
#include "base/containers/cxx20_erase.h"
#include "base/memory/singleton.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task/post_task.h"
#include "base/task/task_runner_util.h"
#include "build/branding_buildflags.h"
#include "build/build_config.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
#include "chrome/browser/plugins/chrome_plugin_service_filter.h"
#include "chrome/browser/plugins/plugin_finder.h"
#include "chrome/browser/plugins/plugin_metadata.h"
#include "chrome/browser/plugins/plugin_prefs.h"
#include "chrome/browser/plugins/plugin_utils.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser_otr_state.h"
#include "chrome/common/buildflags.h"
#include "chrome/common/chrome_content_client.h"
#include "chrome/common/plugin.mojom.h"
#include "chrome/common/pref_names.h"
#include "components/component_updater/component_updater_service.h"
#include "components/content_settings/core/browser/content_settings_utils.h"
#include "components/content_settings/core/browser/host_content_settings_map.h"
#include "components/content_settings/core/common/content_settings.h"
#include "components/keyed_service/content/browser_context_keyed_service_shutdown_notifier_factory.h"
#include "components/nacl/common/buildflags.h"
#include "components/pref_registry/pref_registry_syncable.h"
#include "components/prefs/pref_service.h"
#include "components/ukm/content/source_url_recorder.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/plugin_service.h"
#include "content/public/browser/plugin_service_filter.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/common/content_constants.h"
#include "extensions/buildflags/buildflags.h"
#include "net/base/registry_controlled_domains/registry_controlled_domain.h"
#include "ppapi/buildflags/buildflags.h"
#include "services/metrics/public/cpp/ukm_builders.h"
#include "services/metrics/public/cpp/ukm_recorder.h"
#include "url/gurl.h"
#include "url/origin.h"

#if BUILDFLAG(ENABLE_EXTENSIONS)
#include "components/guest_view/browser/guest_view_base.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/guest_view/web_view/web_view_renderer_state.h"
#include "extensions/common/constants.h"
#include "extensions/common/extension.h"
#include "extensions/common/manifest_handlers/webview_info.h"
#endif

#if BUILDFLAG(ENABLE_NACL)
#include "components/nacl/common/nacl_constants.h"
#endif

using content::PluginService;
using content::WebPluginInfo;

namespace {

class PluginInfoHostImplShutdownNotifierFactory
    : public BrowserContextKeyedServiceShutdownNotifierFactory {
 public:
  static PluginInfoHostImplShutdownNotifierFactory* GetInstance() {
    return base::Singleton<PluginInfoHostImplShutdownNotifierFactory>::get();
  }

  PluginInfoHostImplShutdownNotifierFactory(
      const PluginInfoHostImplShutdownNotifierFactory&) = delete;
  PluginInfoHostImplShutdownNotifierFactory& operator=(
      const PluginInfoHostImplShutdownNotifierFactory&) = delete;

 private:
  friend struct base::DefaultSingletonTraits<
      PluginInfoHostImplShutdownNotifierFactory>;

  PluginInfoHostImplShutdownNotifierFactory()
      : BrowserContextKeyedServiceShutdownNotifierFactory(
            "PluginInfoHostImpl") {}

  ~PluginInfoHostImplShutdownNotifierFactory() override {}
};

#if BUILDFLAG(ENABLE_EXTENSIONS)
// Returns whether a request from a plugin to load |resource| from a renderer
// with process id |process_id| is a request for an internal resource by an app
// listed in |accessible_resources| in its manifest.
bool IsPluginLoadingAccessibleResourceInWebView(
    extensions::ExtensionRegistry* extension_registry,
    int process_id,
    const GURL& resource) {
  extensions::WebViewRendererState* renderer_state =
      extensions::WebViewRendererState::GetInstance();
  std::string partition_id;
  if (!renderer_state->IsGuest(process_id) ||
      !renderer_state->GetPartitionID(process_id, &partition_id)) {
    return false;
  }

  const std::string extension_id = resource.host();
  const extensions::Extension* extension = extension_registry->GetExtensionById(
      extension_id, extensions::ExtensionRegistry::ENABLED);
  if (!extension || !extensions::WebviewInfo::IsResourceWebviewAccessible(
                        extension, partition_id, resource.path())) {
    return false;
  }

  // Make sure the renderer making the request actually belongs to the
  // same extension.
  std::string owner_extension;
  return renderer_state->GetOwnerInfo(process_id, nullptr, &owner_extension) &&
         owner_extension == extension_id;
}
#endif  // BUILDFLAG(ENABLE_EXTENSIONS)

}  // namespace

PluginInfoHostImpl::Context::Context(int render_process_id, Profile* profile)
    : render_process_id_(render_process_id),
#if BUILDFLAG(ENABLE_EXTENSIONS)
      extension_registry_(extensions::ExtensionRegistry::Get(profile)),
#endif
      host_content_settings_map_(
          HostContentSettingsMapFactory::GetForProfile(profile)),
      plugin_prefs_(PluginPrefs::GetForProfile(profile)) {
  allow_outdated_plugins_.Init(prefs::kPluginsAllowOutdated,
                               profile->GetPrefs());
}

PluginInfoHostImpl::Context::~Context() {}

void PluginInfoHostImpl::Context::ShutdownOnUIThread() {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  allow_outdated_plugins_.Destroy();
}

PluginInfoHostImpl::PluginInfoHostImpl(int render_process_id, Profile* profile)
    : context_(render_process_id, profile) {
  shutdown_subscription_ =
      PluginInfoHostImplShutdownNotifierFactory::GetInstance()
          ->Get(profile)
          ->Subscribe(base::BindRepeating(
              &PluginInfoHostImpl::ShutdownOnUIThread, base::Unretained(this)));
}

void PluginInfoHostImpl::ShutdownOnUIThread() {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  context_.ShutdownOnUIThread();
  shutdown_subscription_ = {};
}

// static
void PluginInfoHostImpl::RegisterUserPrefs(
    user_prefs::PrefRegistrySyncable* registry) {
  registry->RegisterBooleanPref(prefs::kPluginsAllowOutdated, false);
}

PluginInfoHostImpl::~PluginInfoHostImpl() {}

struct PluginInfoHostImpl::GetPluginInfo_Params {
  GURL url;
  url::Origin main_frame_origin;
  std::string mime_type;
};

void PluginInfoHostImpl::GetPluginInfo(const GURL& url,
                                       const url::Origin& origin,
                                       const std::string& mime_type,
                                       GetPluginInfoCallback callback) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  GetPluginInfo_Params params = {url, origin, mime_type};
  PluginService::GetInstance()->GetPlugins(
      base::BindOnce(&PluginInfoHostImpl::PluginsLoaded,
                     weak_factory_.GetWeakPtr(), params, std::move(callback)));
}

void PluginInfoHostImpl::PluginsLoaded(
    const GetPluginInfo_Params& params,
    GetPluginInfoCallback callback,
    const std::vector<WebPluginInfo>& plugins) {
  chrome::mojom::PluginInfoPtr output = chrome::mojom::PluginInfo::New();
  // This also fills in |actual_mime_type|.
  std::unique_ptr<PluginMetadata> plugin_metadata;
  if (context_.FindEnabledPlugin(params.url, params.mime_type, &output->status,
                                 &output->plugin, &output->actual_mime_type,
                                 &plugin_metadata)) {
    // TODO(crbug.com/1167278): Simplify this once PDF is the only "plugin."
    context_.DecidePluginStatus(
        params.url, params.main_frame_origin, output->plugin,
        plugin_metadata->GetSecurityStatus(output->plugin),
        plugin_metadata->identifier(), &output->status);
  }

  GetPluginInfoFinish(params, std::move(output), std::move(callback),
                      std::move(plugin_metadata));
}

void PluginInfoHostImpl::Context::DecidePluginStatus(
    const GURL& url,
    const url::Origin& main_frame_origin,
    const WebPluginInfo& plugin,
    PluginMetadata::SecurityStatus security_status,
    const std::string& plugin_identifier,
    chrome::mojom::PluginStatus* status) const {
  if (security_status == PluginMetadata::SECURITY_STATUS_FULLY_TRUSTED) {
    *status = chrome::mojom::PluginStatus::kAllowed;
    return;
  }

// This block is separate from the outdated check, because the deprecated UI
// must take precedence over any content setting or HTML5 by Default.
#if BUILDFLAG(ENABLE_PLUGINS)
  if (security_status == PluginMetadata::SECURITY_STATUS_DEPRECATED) {
    *status = chrome::mojom::PluginStatus::kDeprecated;
    return;
  }
#endif

  ContentSetting plugin_setting = CONTENT_SETTING_DEFAULT;
  bool uses_default_content_setting = true;
  bool is_managed = false;
  // Check plugin content settings. The primary URL is the top origin URL and
  // the secondary URL is the plugin URL.
  PluginUtils::GetPluginContentSetting(
      host_content_settings_map_, plugin, main_frame_origin, url,
      plugin_identifier, &plugin_setting, &uses_default_content_setting,
      &is_managed);

  DCHECK(plugin_setting != CONTENT_SETTING_DEFAULT);

#if BUILDFLAG(ENABLE_PLUGINS)
  // Check if the plugin is outdated.
  if (security_status == PluginMetadata::SECURITY_STATUS_OUT_OF_DATE &&
      !allow_outdated_plugins_.GetValue()) {
    if (allow_outdated_plugins_.IsManaged()) {
      *status = chrome::mojom::PluginStatus::kOutdatedDisallowed;
    } else {
      *status = chrome::mojom::PluginStatus::kOutdatedBlocked;
    }
    return;
  }
#endif  // BUILDFLAG(ENABLE_PLUGINS)

  // Check if the plugin is crashing too much.
  if (PluginService::GetInstance()->IsPluginUnstable(plugin.path) &&
      plugin_setting != CONTENT_SETTING_BLOCK && uses_default_content_setting) {
    *status = chrome::mojom::PluginStatus::kUnauthorized;
    return;
  }

#if BUILDFLAG(ENABLE_EXTENSIONS)
  // If an app has explicitly made internal resources available by listing them
  // in |accessible_resources| in the manifest, then allow them to be loaded by
  // plugins inside a guest-view.
  if (url.SchemeIs(extensions::kExtensionScheme) && !is_managed &&
      plugin_setting == CONTENT_SETTING_BLOCK &&
      IsPluginLoadingAccessibleResourceInWebView(extension_registry_,
                                                 render_process_id_, url)) {
    plugin_setting = CONTENT_SETTING_ALLOW;
  }
#endif  // BUILDFLAG(ENABLE_EXTENSIONS)

  if (plugin_setting == CONTENT_SETTING_ASK ||
      plugin_setting == CONTENT_SETTING_ALLOW) {
    *status = chrome::mojom::PluginStatus::kPlayImportantContent;
  } else if (plugin_setting == CONTENT_SETTING_BLOCK) {
    *status = is_managed ? chrome::mojom::PluginStatus::kBlockedByPolicy
                         : chrome::mojom::PluginStatus::kBlocked;
  }

#if BUILDFLAG(ENABLE_EXTENSIONS)
  // Allow an embedder of <webview> to block a plugin from being loaded inside
  // the guest. In order to do this, set the status to 'Unauthorized' here,
  // and update the status as appropriate depending on the response from the
  // embedder.
  if (*status == chrome::mojom::PluginStatus::kAllowed ||
      *status == chrome::mojom::PluginStatus::kBlocked ||
      *status == chrome::mojom::PluginStatus::kPlayImportantContent) {
    if (extensions::WebViewRendererState::GetInstance()->IsGuest(
            render_process_id_))
      *status = chrome::mojom::PluginStatus::kUnauthorized;
  }
#endif
}

bool PluginInfoHostImpl::Context::FindEnabledPlugin(
    const GURL& url,
    const std::string& mime_type,
    chrome::mojom::PluginStatus* status,
    WebPluginInfo* plugin,
    std::string* actual_mime_type,
    std::unique_ptr<PluginMetadata>* plugin_metadata) const {
  *status = chrome::mojom::PluginStatus::kAllowed;

  bool allow_wildcard = true;
  std::vector<WebPluginInfo> matching_plugins;
  std::vector<std::string> mime_types;
  PluginService::GetInstance()->GetPluginInfoArray(
      url, mime_type, allow_wildcard, &matching_plugins, &mime_types);
#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
  base::EraseIf(matching_plugins, [&](const WebPluginInfo& info) {
    return info.path.value() == ChromeContentClient::kNotPresent;
  });
#endif  // BUILDFLAG(GOOGLE_CHROME_BRANDING)
  if (matching_plugins.empty()) {
    *status = chrome::mojom::PluginStatus::kNotFound;
    return false;
  }

  content::PluginServiceFilter* filter =
      PluginService::GetInstance()->GetFilter();
  size_t i = 0;
  for (; i < matching_plugins.size(); ++i) {
    if (!filter ||
        filter->IsPluginAvailable(render_process_id_, matching_plugins[i])) {
      break;
    }
  }

  // If we broke out of the loop, we have found an enabled plugin.
  bool enabled = i < matching_plugins.size();
  if (!enabled) {
    // Otherwise, we only found disabled plugins, so we take the first one.
    i = 0;
    *status = chrome::mojom::PluginStatus::kDisabled;
  }

  *plugin = matching_plugins[i];
  *actual_mime_type = mime_types[i];
  if (plugin_metadata)
    *plugin_metadata = PluginFinder::GetInstance()->GetPluginMetadata(*plugin);

  return enabled;
}

void PluginInfoHostImpl::GetPluginInfoFinish(
    const GetPluginInfo_Params& params,
    chrome::mojom::PluginInfoPtr output,
    GetPluginInfoCallback callback,
    std::unique_ptr<PluginMetadata> plugin_metadata) {
  if (plugin_metadata) {
    output->group_identifier = plugin_metadata->identifier();
    output->group_name = plugin_metadata->name();
  }

  context_.MaybeGrantAccess(output->status, output->plugin.path);

  std::move(callback).Run(std::move(output));
}

void PluginInfoHostImpl::Context::MaybeGrantAccess(
    chrome::mojom::PluginStatus status,
    const base::FilePath& path) const {
  if (status == chrome::mojom::PluginStatus::kAllowed ||
      status == chrome::mojom::PluginStatus::kPlayImportantContent) {
    ChromePluginServiceFilter::GetInstance()->AuthorizePlugin(
        render_process_id_, path);
  }
}

bool PluginInfoHostImpl::Context::IsPluginEnabled(
    const content::WebPluginInfo& plugin) const {
  return plugin_prefs_->IsPluginEnabled(plugin);
}
