// Copyright (c) 2013 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/component_updater/pepper_flash_component_installer.h"

#include <stddef.h>

#include <memory>
#include <string>
#include <utility>
#include <vector>

#include "base/base_paths.h"
#include "base/bind.h"
#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/json/json_reader.h"
#include "base/logging.h"
#include "base/memory/ref_counted.h"
#include "base/path_service.h"
#include "base/stl_util.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task/post_task.h"
#include "base/version.h"
#include "build/build_config.h"
#include "chrome/browser/component_updater/component_installer_errors.h"
#include "chrome/browser/plugins/plugin_prefs.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_content_client.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/pepper_flash.h"
#include "chrome/common/ppapi_utils.h"
#include "components/component_updater/component_installer.h"
#include "components/component_updater/component_updater_service.h"
#include "components/update_client/update_client.h"
#include "components/update_client/update_client_errors.h"
#include "components/update_client/utils.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/plugin_service.h"
#include "content/public/common/content_constants.h"
#include "content/public/common/pepper_plugin_info.h"
#include "crypto/sha2.h"
#include "ppapi/shared_impl/ppapi_permissions.h"

#if defined(OS_CHROMEOS)
#include "chrome/browser/chromeos/settings/cros_settings.h"
#include "chrome/browser/ui/ash/system_tray_client.h"
#include "chrome/common/chrome_features.h"
#include "chromeos/dbus/dbus_method_call_status.h"
#include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/dbus/image_loader_client.h"
#elif defined(OS_LINUX)
#include "chrome/common/component_flash_hint_file_linux.h"
#endif  // defined(OS_CHROMEOS)

using content::BrowserThread;
using content::PluginService;

namespace component_updater {

namespace {

#if defined(GOOGLE_CHROME_BUILD)
#if defined(OS_CHROMEOS)
// CRX hash for Chrome OS. The extension id is:
// ckjlcfmdbdglblbjglepgnoekdnkoklc.
const uint8_t kFlashSha2Hash[] = {
    0x2a, 0x9b, 0x25, 0xc3, 0x13, 0x6b, 0x1b, 0x19, 0x6b, 0x4f, 0x6d,
    0xe4, 0xa3, 0xda, 0xea, 0xb2, 0x67, 0xeb, 0xf0, 0xbb, 0x1f, 0x48,
    0xa2, 0x73, 0xea, 0x47, 0x11, 0xc8, 0x2b, 0xd9, 0x03, 0xb5};
#else
// CRX hash. The extension id is: mimojjlkmoijpicakmndhoigimigcmbb.
const uint8_t kFlashSha2Hash[] = {
    0xc8, 0xce, 0x99, 0xba, 0xce, 0x89, 0xf8, 0x20, 0xac, 0xd3, 0x7e,
    0x86, 0x8c, 0x86, 0x2c, 0x11, 0xb9, 0x40, 0xc5, 0x55, 0xaf, 0x08,
    0x63, 0x70, 0x54, 0xf9, 0x56, 0xd3, 0xe7, 0x88, 0xba, 0x8c};
#endif  // defined(OS_CHROMEOS)
static_assert(base::size(kFlashSha2Hash) == crypto::kSHA256Length,
              "Wrong hash length");

#if defined(OS_CHROMEOS)
void LogRegistrationResult(base::Optional<bool> result) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  if (!result.has_value()) {
    LOG(ERROR) << "Call to imageloader service failed.";
    return;
  }
  if (!result.value()) {
    LOG(ERROR) << "Component flash registration failed";
    return;
  }
  SystemTrayClient* tray = SystemTrayClient::Get();
  if (tray) {
    tray->SetFlashUpdateAvailable();
  }
}

void ImageLoaderRegistration(const std::string& version,
                             const base::FilePath& install_dir) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  chromeos::ImageLoaderClient* loader =
      chromeos::DBusThreadManager::Get()->GetImageLoaderClient();

  if (loader) {
    loader->RegisterComponent("PepperFlashPlayer", version, install_dir.value(),
                              base::BindOnce(&LogRegistrationResult));
  } else {
    LOG(ERROR) << "Failed to get ImageLoaderClient object.";
  }
}

// Determine whether or not to skip registering flash component updates.
bool SkipFlashRegistration(ComponentUpdateService* cus) {
  if (!base::FeatureList::IsEnabled(features::kCrosCompUpdates))
    return true;

  // If the version of Chrome is pinned on the device (probably via enterprise
  // policy), do not component update Flash player.
  chromeos::CrosSettingsProvider::TrustedStatus status =
      chromeos::CrosSettings::Get()->PrepareTrustedValues(
          base::Bind(&RegisterPepperFlashComponent, cus));

  // Only if the settings are trusted, read the update settings and allow them
  // to disable Flash component updates. If the settings are untrusted, then we
  // fail-safe and allow the security updates.
  std::string version_prefix;
  bool update_disabled = false;
  switch (status) {
    case chromeos::CrosSettingsProvider::TEMPORARILY_UNTRUSTED:
      // Return and allow flash registration to occur once the settings are
      // trusted.
      return true;
    case chromeos::CrosSettingsProvider::TRUSTED:
      chromeos::CrosSettings::Get()->GetBoolean(chromeos::kUpdateDisabled,
                                                &update_disabled);
      chromeos::CrosSettings::Get()->GetString(chromeos::kTargetVersionPrefix,
                                               &version_prefix);

      return update_disabled || !version_prefix.empty();
    case chromeos::CrosSettingsProvider::PERMANENTLY_UNTRUSTED:
      return false;
  }

  // Default to not skipping component flash registration since updates are
  // security critical.
  return false;
}
#endif  // defined(OS_CHROMEOS)
#endif  // defined(GOOGLE_CHROME_BUILD)

#if !defined(OS_LINUX) && defined(GOOGLE_CHROME_BUILD)
bool MakePepperFlashPluginInfo(const base::FilePath& flash_path,
                               const base::Version& flash_version,
                               bool out_of_process,
                               content::PepperPluginInfo* plugin_info) {
  if (!flash_version.IsValid())
    return false;
  const std::vector<uint32_t> ver_nums = flash_version.components();
  if (ver_nums.size() < 3)
    return false;

  plugin_info->is_internal = false;
  plugin_info->is_out_of_process = out_of_process;
  plugin_info->path = flash_path;
  plugin_info->name = content::kFlashPluginName;
  plugin_info->permissions = kPepperFlashPermissions;

  // The description is like "Shockwave Flash 10.2 r154".
  plugin_info->description = base::StringPrintf("%s %d.%d r%d",
                                                content::kFlashPluginName,
                                                ver_nums[0],
                                                ver_nums[1],
                                                ver_nums[2]);

  plugin_info->version = flash_version.GetString();

  content::WebPluginMimeType swf_mime_type(content::kFlashPluginSwfMimeType,
                                           content::kFlashPluginSwfExtension,
                                           content::kFlashPluginName);
  plugin_info->mime_types.push_back(swf_mime_type);
  content::WebPluginMimeType spl_mime_type(content::kFlashPluginSplMimeType,
                                           content::kFlashPluginSplExtension,
                                           content::kFlashPluginName);
  plugin_info->mime_types.push_back(spl_mime_type);
  return true;
}

// |path| is the path to the latest Chrome-managed Flash installation (bundled
// or component updated).
// |version| is the version of that Flash implementation.
void RegisterPepperFlashWithChrome(const base::FilePath& path,
                                   const base::Version& version) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  content::PepperPluginInfo plugin_info;
  if (!MakePepperFlashPluginInfo(path, version, true, &plugin_info))
    return;
  content::WebPluginInfo web_plugin = plugin_info.ToWebPluginInfo();

  base::FilePath system_flash_path;
  base::PathService::Get(chrome::FILE_PEPPER_FLASH_SYSTEM_PLUGIN,
                         &system_flash_path);

  std::vector<content::WebPluginInfo> plugins;
  PluginService::GetInstance()->GetInternalPlugins(&plugins);
  for (const auto& plugin : plugins) {
    if (!plugin.is_pepper_plugin() || plugin.name != web_plugin.name)
      continue;

    if (plugin.path.value() == ChromeContentClient::kNotPresent) {
      // This is the Flash placeholder; replace it regardless of version or
      // other considerations.
      PluginService::GetInstance()->UnregisterInternalPlugin(plugin.path);
      break;
    }

    base::Version registered_version(base::UTF16ToUTF8(plugin.version));

    // If lower or equal version, never register.
    if (registered_version.IsValid() &&
        version.CompareTo(registered_version) <= 0) {
      return;
    }

    // If the version is newer, remove the old one first.
    PluginService::GetInstance()->UnregisterInternalPlugin(plugin.path);
    break;
  }

  PluginService::GetInstance()->RegisterInternalPlugin(web_plugin, true);
  PluginService::GetInstance()->RefreshPlugins();
}

void UpdatePathService(const base::FilePath& path) {
  base::PathService::Override(chrome::DIR_PEPPER_FLASH_PLUGIN, path);
}
#endif  // !defined(OS_LINUX) && defined(GOOGLE_CHROME_BUILD)

#if defined(GOOGLE_CHROME_BUILD)
class FlashComponentInstallerPolicy : public ComponentInstallerPolicy {
 public:
  FlashComponentInstallerPolicy();
  ~FlashComponentInstallerPolicy() override {}

 private:
  // The following methods override ComponentInstallerPolicy.
  bool SupportsGroupPolicyEnabledComponentUpdates() const override;
  bool RequiresNetworkEncryption() const override;
  update_client::CrxInstaller::Result OnCustomInstall(
      const base::DictionaryValue& manifest,
      const base::FilePath& install_dir) override;
  void OnCustomUninstall() override;
  bool VerifyInstallation(const base::DictionaryValue& manifest,
                          const base::FilePath& install_dir) const override;
  void ComponentReady(const base::Version& version,
                      const base::FilePath& path,
                      std::unique_ptr<base::DictionaryValue> manifest) override;
  base::FilePath GetRelativeInstallDir() const override;
  void GetHash(std::vector<uint8_t>* hash) const override;
  std::string GetName() const override;
  update_client::InstallerAttributes GetInstallerAttributes() const override;
  std::vector<std::string> GetMimeTypes() const override;

  DISALLOW_COPY_AND_ASSIGN(FlashComponentInstallerPolicy);
};

FlashComponentInstallerPolicy::FlashComponentInstallerPolicy() {}

bool FlashComponentInstallerPolicy::SupportsGroupPolicyEnabledComponentUpdates()
    const {
  return true;
}

bool FlashComponentInstallerPolicy::RequiresNetworkEncryption() const {
  return false;
}

update_client::CrxInstaller::Result
FlashComponentInstallerPolicy::OnCustomInstall(
    const base::DictionaryValue& manifest,
    const base::FilePath& install_dir) {
  std::string version;
  if (!manifest.GetString("version", &version)) {
    return update_client::ToInstallerResult(
        FlashError::MISSING_VERSION_IN_MANIFEST);
  }

#if defined(OS_CHROMEOS)
  base::CreateSingleThreadTaskRunnerWithTraits({content::BrowserThread::UI})
      ->PostTask(FROM_HERE, base::BindOnce(&ImageLoaderRegistration, version,
                                           install_dir));
#elif defined(OS_LINUX)
  const base::FilePath flash_path =
      install_dir.Append(chrome::kPepperFlashPluginFilename);
  // Populate the component updated flash hint file so that the zygote can
  // locate and preload the latest version of flash.
  if (!component_flash_hint_file::RecordFlashUpdate(flash_path, flash_path,
                                                    version)) {
    return update_client::ToInstallerResult(FlashError::HINT_FILE_RECORD_ERROR);
  }
#endif  // defined(OS_LINUX)
  return update_client::CrxInstaller::Result(update_client::InstallError::NONE);
}

void FlashComponentInstallerPolicy::OnCustomUninstall() {}

void FlashComponentInstallerPolicy::ComponentReady(
    const base::Version& version,
    const base::FilePath& path,
    std::unique_ptr<base::DictionaryValue> manifest) {
#if !defined(OS_LINUX)
  // Installation is done. Now tell the rest of chrome. Both the path service
  // and to the plugin service. On Linux, a restart is required to use the new
  // Flash version, so we do not do this.
  RegisterPepperFlashWithChrome(path.Append(chrome::kPepperFlashPluginFilename),
                                version);
  base::PostTaskWithTraits(FROM_HERE,
                           {base::TaskPriority::BEST_EFFORT, base::MayBlock()},
                           base::BindOnce(&UpdatePathService, path));
#endif  // !defined(OS_LINUX)
}

bool FlashComponentInstallerPolicy::VerifyInstallation(
    const base::DictionaryValue& manifest,
    const base::FilePath& install_dir) const {
  base::Version unused;
  return CheckPepperFlashManifest(manifest, &unused);
}

// The base directory on Windows looks like:
// <profile>\AppData\Local\Google\Chrome\User Data\PepperFlash\.
base::FilePath FlashComponentInstallerPolicy::GetRelativeInstallDir() const {
  return base::FilePath(FILE_PATH_LITERAL("PepperFlash"));
}

void FlashComponentInstallerPolicy::GetHash(std::vector<uint8_t>* hash) const {
  hash->assign(kFlashSha2Hash, kFlashSha2Hash + base::size(kFlashSha2Hash));
}

std::string FlashComponentInstallerPolicy::GetName() const {
  return "Adobe Flash Player";
}

update_client::InstallerAttributes
FlashComponentInstallerPolicy::GetInstallerAttributes() const {
  // For Chrome OS, send the built-in flash player version to the server,
  // otherwise it will serve component updates of outdated flash players.
  update_client::InstallerAttributes attrs;
#if defined(OS_CHROMEOS)
  const std::string flash_version =
      base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
          switches::kPpapiFlashVersion);
  attrs["built_in_version"] = flash_version;
#endif  // #defined(OS_CHROMEOS)
  return attrs;
}

std::vector<std::string> FlashComponentInstallerPolicy::GetMimeTypes() const {
  std::vector<std::string> mime_types;
  mime_types.push_back("application/x-shockwave-flash");
  mime_types.push_back("application/futuresplash");
  return mime_types;
}
#endif  // defined(GOOGLE_CHROME_BUILD)

}  // namespace

void RegisterPepperFlashComponent(ComponentUpdateService* cus) {
#if defined(GOOGLE_CHROME_BUILD)
  // Component updated flash supersedes bundled flash therefore if that one
  // is disabled then this one should never install.
  base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess();
  if (cmd_line->HasSwitch(switches::kDisableBundledPpapiFlash))
    return;

#if defined(OS_CHROMEOS)
  if (SkipFlashRegistration(cus))
    return;
#endif  // defined(OS_CHROMEOS)

  auto installer = base::MakeRefCounted<ComponentInstaller>(
      std::make_unique<FlashComponentInstallerPolicy>());
  installer->Register(cus, base::OnceClosure());
#endif  // defined(GOOGLE_CHROME_BUILD)
}

}  // namespace component_updater
