// 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/memory/singleton.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task_runner_util.h"
#include "base/threading/thread_task_runner_handle.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/plugins/plugins_field_trial.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/chrome_features.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/rappor/rappor_service_impl.h"
#include "components/ukm/content/source_url_recorder.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();
  }

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

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

  ~PluginInfoHostImplShutdownNotifierFactory() override {}

  DISALLOW_COPY_AND_ASSIGN(PluginInfoHostImplShutdownNotifierFactory);
};

#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),
      resource_context_(profile->GetResourceContext()),
#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());
  allow_outdated_plugins_.MoveToThread(
      content::BrowserThread::GetTaskRunnerForThread(
          content::BrowserThread::IO));
  run_all_flash_in_allow_mode_.Init(prefs::kRunAllFlashInAllowMode,
                                    profile->GetPrefs());
  run_all_flash_in_allow_mode_.MoveToThread(
      content::BrowserThread::GetTaskRunnerForThread(
          content::BrowserThread::IO));
}

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

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

PluginInfoHostImpl::PluginInfoHostImpl(int render_process_id, Profile* profile)
    : context_(render_process_id, profile),
      main_thread_task_runner_(base::ThreadTaskRunnerHandle::Get()),
      binding_(this) {
  shutdown_notifier_ =
      PluginInfoHostImplShutdownNotifierFactory::GetInstance()
          ->Get(profile)
          ->Subscribe(base::Bind(&PluginInfoHostImpl::ShutdownOnUIThread,
                                 base::Unretained(this)));
}

void PluginInfoHostImpl::ShutdownOnUIThread() {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  context_.ShutdownOnUIThread();
  shutdown_notifier_.reset();
}

void PluginInfoHostImplTraits::Destruct(const PluginInfoHostImpl* impl) {
  content::BrowserThread::PostTask(
      content::BrowserThread::IO, FROM_HERE,
      base::BindOnce(&PluginInfoHostImpl::DestructOnBrowserThread,
                     base::Unretained(impl)));
}

void PluginInfoHostImpl::DestructOnBrowserThread() const {
  binding_.Close();
  // Destroy on the UI thread because we contain a |PrefMember|.
  content::BrowserThread::DeleteOnUIThread::Destruct(this);
}

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

PluginInfoHostImpl::~PluginInfoHostImpl() {}

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

void PluginInfoHostImpl::OnPluginInfoHostRequest(
    chrome::mojom::PluginInfoHostAssociatedRequest request) {
  binding_.Bind(std::move(request));
}

void PluginInfoHostImpl::GetPluginInfo(int32_t render_frame_id,
                                       const GURL& url,
                                       const url::Origin& origin,
                                       const std::string& mime_type,
                                       const GetPluginInfoCallback& callback) {
  GetPluginInfo_Params params = {render_frame_id, url, origin, mime_type};
  PluginService::GetInstance()->GetPlugins(base::BindOnce(
      &PluginInfoHostImpl::PluginsLoaded, this, 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.render_frame_id, params.url,
                                 params.main_frame_origin, params.mime_type,
                                 &output->status, &output->plugin,
                                 &output->actual_mime_type, &plugin_metadata)) {
    context_.DecidePluginStatus(
        params.url, params.main_frame_origin, output->plugin,
        plugin_metadata->GetSecurityStatus(output->plugin),
        plugin_metadata->identifier(), &output->status);
  }

  if (output->status == chrome::mojom::PluginStatus::kNotFound) {
    // Check to see if the component updater can fetch an implementation.
    base::PostTaskAndReplyWithResult(
        main_thread_task_runner_.get(), FROM_HERE,
        base::BindOnce(
            &component_updater::ComponentUpdateService::GetComponentForMimeType,
            base::Unretained(g_browser_process->component_updater()),
            params.mime_type),
        base::BindOnce(&PluginInfoHostImpl::ComponentPluginLookupDone, this,
                       params, std::move(output), std::move(callback),
                       std::move(plugin_metadata)));
  } else {
    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;
  }

  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);

  // TODO(tommycli): Remove once we deprecate the plugin ASK policy.
  bool legacy_ask_user = plugin_setting == CONTENT_SETTING_ASK;
  plugin_setting = PluginsFieldTrial::EffectiveContentSetting(
      host_content_settings_map_, CONTENT_SETTINGS_TYPE_PLUGINS,
      plugin_setting);

  DCHECK(plugin_setting != CONTENT_SETTING_DEFAULT);
  DCHECK(plugin_setting != CONTENT_SETTING_ASK);

  if (*status == chrome::mojom::PluginStatus::kFlashHiddenPreferHtml) {
    if (plugin_setting == CONTENT_SETTING_BLOCK) {
      *status = is_managed && !legacy_ask_user
                    ? chrome::mojom::PluginStatus::kBlockedByPolicy
                    : chrome::mojom::PluginStatus::kBlockedNoLoading;
    }
    return;
  }

#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_DETECT_IMPORTANT_CONTENT ||
      (plugin_setting == CONTENT_SETTING_ALLOW &&
       PluginUtils::ShouldPreferHtmlOverPlugins(host_content_settings_map_) &&
       !run_all_flash_in_allow_mode_.GetValue())) {
    *status = chrome::mojom::PluginStatus::kPlayImportantContent;
  } else if (plugin_setting == CONTENT_SETTING_BLOCK) {
    // For managed users with the ASK policy, we allow manually running plugins
    // via context menu. This is the closest to admin intent.
    *status = is_managed && !legacy_ask_user
                  ? 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(
    int render_frame_id,
    const GURL& url,
    const url::Origin& main_frame_origin,
    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 defined(GOOGLE_CHROME_BUILD)
  base::FilePath not_present =
      base::FilePath::FromUTF8Unsafe(ChromeContentClient::kNotPresent);
  matching_plugins.erase(
      std::remove_if(matching_plugins.begin(), matching_plugins.end(),
                     [&not_present](const WebPluginInfo& info) {
                       return info.path == not_present;
                     }),
      matching_plugins.end());
#endif  // defined(GOOGLE_CHROME_BUILD)
  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_, render_frame_id, resource_context_,
                       url, main_frame_origin, &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;

    if (PluginUtils::ShouldPreferHtmlOverPlugins(host_content_settings_map_) &&
        matching_plugins[0].name ==
            base::ASCIIToUTF16(content::kFlashPluginName)) {
      *status = chrome::mojom::PluginStatus::kFlashHiddenPreferHtml;

      // In the Prefer HTML case, the plugin is actually enabled, but hidden.
      // It will still be blocked in the body of DecidePluginStatus.
      enabled = true;
    }
  }

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

  return enabled;
}

void PluginInfoHostImpl::ComponentPluginLookupDone(
    const GetPluginInfo_Params& params,
    chrome::mojom::PluginInfoPtr output,
    GetPluginInfoCallback callback,
    std::unique_ptr<PluginMetadata> plugin_metadata,
    std::unique_ptr<component_updater::ComponentInfo> cus_plugin_info) {
  if (cus_plugin_info) {
    output->status = chrome::mojom::PluginStatus::kComponentUpdateRequired;
#if defined(OS_LINUX)
    if (cus_plugin_info->version != base::Version("0")) {
      output->status = chrome::mojom::PluginStatus::kRestartRequired;
    }
#endif
    plugin_metadata = std::make_unique<PluginMetadata>(
        cus_plugin_info->id, cus_plugin_info->name, false, GURL(), GURL(),
        base::ASCIIToUTF16(cus_plugin_info->id), std::string());
  }
  GetPluginInfoFinish(params, std::move(output), std::move(callback),
                      std::move(plugin_metadata));
}

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);

  if (output->status != chrome::mojom::PluginStatus::kNotFound) {
    main_thread_task_runner_->PostTask(
        FROM_HERE,
        base::BindOnce(&PluginInfoHostImpl::ReportMetrics, this,
                       params.render_frame_id, output->actual_mime_type,
                       params.url, params.main_frame_origin));
  }
  std::move(callback).Run(std::move(output));
}

void PluginInfoHostImpl::ReportMetrics(int render_frame_id,
                                       const base::StringPiece& mime_type,
                                       const GURL& url,
                                       const url::Origin& main_frame_origin) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

  content::RenderFrameHost* frame = content::RenderFrameHost::FromID(
      context_.render_process_id(), render_frame_id);
  content::WebContents* web_contents =
      content::WebContents::FromRenderFrameHost(frame);
  // This can occur the web contents has already been closed or navigated away.
  if (!web_contents)
    return;

  if (web_contents->GetBrowserContext()->IsOffTheRecord())
    return;

  rappor::RapporServiceImpl* rappor_service =
      g_browser_process->rappor_service();
  if (!rappor_service)
    return;
  if (main_frame_origin.unique())
    return;

  if (mime_type != content::kFlashPluginSwfMimeType &&
      mime_type != content::kFlashPluginSplMimeType) {
    return;
  }

  rappor_service->RecordSampleString(
      "Plugins.FlashOriginUrl", rappor::ETLD_PLUS_ONE_RAPPOR_TYPE,
      net::registry_controlled_domains::GetDomainAndRegistry(
          main_frame_origin.GetURL(),
          net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES));
  rappor_service->RecordSampleString(
      "Plugins.FlashUrl", rappor::ETLD_PLUS_ONE_RAPPOR_TYPE,
      net::registry_controlled_domains::GetDomainAndRegistry(
          url, net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES));

  ukm::builders::Plugins_FlashInstance(
      ukm::GetSourceIdForWebContentsDocument(web_contents))
      .Record(ukm::UkmRecorder::Get());
}

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);
}
