// Copyright 2015 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/extensions/chrome_content_verifier_delegate.h"

#include <algorithm>
#include <memory>
#include <set>
#include <vector>

#include "base/base_switches.h"
#include "base/command_line.h"
#include "base/metrics/field_trial.h"
#include "base/metrics/histogram_macros.h"
#include "base/no_destructor.h"
#include "base/strings/string_piece.h"
#include "base/strings/string_util.h"
#include "base/syslog_logging.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/version.h"
#include "build/branding_buildflags.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/install_verifier.h"
#include "chrome/browser/extensions/policy_extension_reinstaller.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/extensions/extension_constants.h"
#include "extensions/browser/disable_reason.h"
#include "extensions/browser/extension_prefs.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/extension_system.h"
#include "extensions/browser/management_policy.h"
#include "extensions/browser/pref_types.h"
#include "extensions/common/extension_urls.h"
#include "extensions/common/extensions_client.h"
#include "extensions/common/manifest.h"
#include "extensions/common/manifest_url_handlers.h"
#include "net/base/backoff_entry.h"
#include "net/base/escape.h"

#if BUILDFLAG(IS_CHROMEOS_ASH)
#include "chrome/browser/extensions/extension_assets_manager_chromeos.h"
#endif

namespace extensions {

namespace {

base::Optional<ChromeContentVerifierDelegate::VerifyInfo::Mode>&
GetModeForTesting() {
  static base::NoDestructor<
      base::Optional<ChromeContentVerifierDelegate::VerifyInfo::Mode>>
      testing_mode;
  return *testing_mode;
}

const char kContentVerificationExperimentName[] =
    "ExtensionContentVerification";

}  // namespace

ChromeContentVerifierDelegate::VerifyInfo::VerifyInfo(Mode mode,
                                                      bool is_from_webstore,
                                                      bool should_repair)
    : mode(mode),
      is_from_webstore(is_from_webstore),
      should_repair(should_repair) {}

// static
ChromeContentVerifierDelegate::VerifyInfo::Mode
ChromeContentVerifierDelegate::GetDefaultMode() {
  if (GetModeForTesting())
    return *GetModeForTesting();

  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();

  VerifyInfo::Mode experiment_value;
#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
  experiment_value = VerifyInfo::Mode::ENFORCE_STRICT;
#else
  experiment_value = VerifyInfo::Mode::NONE;
#endif
  const std::string group =
      base::FieldTrialList::FindFullName(kContentVerificationExperimentName);
  if (group == "EnforceStrict")
    experiment_value = VerifyInfo::Mode::ENFORCE_STRICT;
  else if (group == "Enforce")
    experiment_value = VerifyInfo::Mode::ENFORCE;
  else if (group == "Bootstrap")
    experiment_value = VerifyInfo::Mode::BOOTSTRAP;
  else if (group == "None")
    experiment_value = VerifyInfo::Mode::NONE;

  // The field trial value that normally comes from the server can be
  // overridden on the command line, which we don't want to allow since
  // malware can set chrome command line flags. There isn't currently a way
  // to find out what the server-provided value is in this case, so we
  // conservatively default to the strictest mode if we detect our experiment
  // name being overridden.
  if (command_line->HasSwitch(::switches::kForceFieldTrials)) {
    std::string forced_trials =
        command_line->GetSwitchValueASCII(::switches::kForceFieldTrials);
    if (forced_trials.find(kContentVerificationExperimentName) !=
        std::string::npos)
      experiment_value = VerifyInfo::Mode::ENFORCE_STRICT;
  }

  VerifyInfo::Mode cmdline_value = VerifyInfo::Mode::NONE;
  if (command_line->HasSwitch(::switches::kExtensionContentVerification)) {
    std::string switch_value = command_line->GetSwitchValueASCII(
        ::switches::kExtensionContentVerification);
    if (switch_value == ::switches::kExtensionContentVerificationBootstrap)
      cmdline_value = VerifyInfo::Mode::BOOTSTRAP;
    else if (switch_value == ::switches::kExtensionContentVerificationEnforce)
      cmdline_value = VerifyInfo::Mode::ENFORCE;
    else if (switch_value ==
             ::switches::kExtensionContentVerificationEnforceStrict)
      cmdline_value = VerifyInfo::Mode::ENFORCE_STRICT;
    else
      // If no value was provided (or the wrong one), just default to enforce.
      cmdline_value = VerifyInfo::Mode::ENFORCE;
  }

  // We don't want to allow the command-line flags to eg disable enforcement
  // if the experiment group says it should be on, or malware may just modify
  // the command line flags. So return the more restrictive of the 2 values.
  return std::max(experiment_value, cmdline_value);
}

// static
void ChromeContentVerifierDelegate::SetDefaultModeForTesting(
    base::Optional<VerifyInfo::Mode> mode) {
  DCHECK(!GetModeForTesting() || !mode)
      << "Verification mode already overridden, unset it first.";
  GetModeForTesting() = mode;
}

ChromeContentVerifierDelegate::ChromeContentVerifierDelegate(
    content::BrowserContext* context)
    : context_(context),
      default_mode_(GetDefaultMode()),
      policy_extension_reinstaller_(
          std::make_unique<PolicyExtensionReinstaller>(context_)) {}

ChromeContentVerifierDelegate::~ChromeContentVerifierDelegate() {
}

ContentVerifierDelegate::VerifierSourceType
ChromeContentVerifierDelegate::GetVerifierSourceType(
    const Extension& extension) {
  const VerifyInfo info = GetVerifyInfo(extension);
  if (info.mode == VerifyInfo::Mode::NONE)
    return VerifierSourceType::NONE;
  if (info.is_from_webstore)
    return VerifierSourceType::SIGNED_HASHES;
  return VerifierSourceType::UNSIGNED_HASHES;
}

ContentVerifierKey ChromeContentVerifierDelegate::GetPublicKey() {
  return ContentVerifierKey(kWebstoreSignaturesPublicKey,
                            kWebstoreSignaturesPublicKeySize);
}

GURL ChromeContentVerifierDelegate::GetSignatureFetchUrl(
    const std::string& extension_id,
    const base::Version& version) {
  // TODO(asargent) Factor out common code from the extension updater's
  // ManifestFetchData class that can be shared for use here.
  std::string id_part = "id=" + extension_id;
  std::string version_part = "v=" + version.GetString();
  std::string x_value = net::EscapeQueryParamValue(
      base::JoinString({"uc", "installsource=signature", id_part, version_part},
                       "&"),
      true);
  std::string query = "response=redirect&x=" + x_value;

  GURL base_url = extension_urls::GetWebstoreUpdateUrl();
  GURL::Replacements replacements;
  replacements.SetQuery(query.c_str(), url::Component(0, query.length()));
  return base_url.ReplaceComponents(replacements);
}

std::set<base::FilePath> ChromeContentVerifierDelegate::GetBrowserImagePaths(
    const extensions::Extension* extension) {
  return ExtensionsClient::Get()->GetBrowserImagePaths(extension);
}

void ChromeContentVerifierDelegate::VerifyFailed(
    const std::string& extension_id,
    ContentVerifyJob::FailureReason reason) {
  ExtensionRegistry* registry = ExtensionRegistry::Get(context_);
  const Extension* extension =
      registry->GetExtensionById(extension_id, ExtensionRegistry::ENABLED);
  if (!extension)
    return;

  ExtensionSystem* system = ExtensionSystem::Get(context_);
  if (!system->extension_service()) {
    // Some tests will add an extension to the registry, but there are no
    // subsystems.
    return;
  }

  ExtensionService* service = system->extension_service();
  PendingExtensionManager* pending_manager =
      service->pending_extension_manager();

  const VerifyInfo info = GetVerifyInfo(*extension);

  if (reason == ContentVerifyJob::MISSING_ALL_HASHES) {
    // If the failure was due to hashes missing, only "enforce_strict" would
    // disable the extension, but not "enforce".
    if (info.mode != VerifyInfo::Mode::ENFORCE_STRICT)
      return;

    // If a non-webstore extension has no computed hashes for content
    // verification, leave it as is for now.
    // See https://crbug.com/958794#c22 for more details.
    // TODO(https://crbug.com/1044572): Schedule the extension for reinstall.
    if (!info.is_from_webstore) {
      if (!base::Contains(would_be_reinstalled_ids_, extension_id)) {
        pending_manager->RecordPolicyReinstallReason(
            PendingExtensionManager::PolicyReinstallReason::
                NO_UNSIGNED_HASHES_FOR_NON_WEBSTORE_SKIP);
        would_be_reinstalled_ids_.insert(extension_id);
      }
      return;
    }
  }

  const bool should_disable = info.mode >= VerifyInfo::Mode::ENFORCE;
  // Configuration when we should repair extension, but not disable it, is
  // invalid.
  DCHECK(!info.should_repair || should_disable);

  if (!should_disable) {
    if (!base::Contains(would_be_disabled_ids_, extension_id)) {
      UMA_HISTOGRAM_BOOLEAN("Extensions.CorruptExtensionWouldBeDisabled", true);
      would_be_disabled_ids_.insert(extension_id);
    }
    return;
  }

  if (info.should_repair) {
    if (pending_manager->IsPolicyReinstallForCorruptionExpected(extension_id))
      return;
    SYSLOG(WARNING) << "Corruption detected in policy extension "
                    << extension_id
                    << " installed at: " << extension->path().value()
                    << ", from webstore: " << info.is_from_webstore;
    pending_manager->ExpectPolicyReinstallForCorruption(
        extension_id, info.is_from_webstore
                          ? PendingExtensionManager::PolicyReinstallReason::
                                CORRUPTION_DETECTED_WEBSTORE
                          : PendingExtensionManager::PolicyReinstallReason::
                                CORRUPTION_DETECTED_NON_WEBSTORE);
    service->DisableExtension(extension_id, disable_reason::DISABLE_CORRUPTED);
    // Attempt to reinstall.
    policy_extension_reinstaller_->NotifyExtensionDisabledDueToCorruption();
    return;
  }

  DCHECK(should_disable);
  DLOG(WARNING) << "Disabling extension " << extension_id << " ('"
                << extension->name()
                << "') due to content verification failure. In tests you "
                << "might want to use a ScopedIgnoreContentVerifierForTest "
                << "instance to prevent this.";
  service->DisableExtension(extension_id, disable_reason::DISABLE_CORRUPTED);
  ExtensionPrefs::Get(context_)->IncrementPref(
      extensions::kCorruptedDisableCount);
  UMA_HISTOGRAM_BOOLEAN("Extensions.CorruptExtensionBecameDisabled", true);
  UMA_HISTOGRAM_ENUMERATION("Extensions.CorruptExtensionDisabledReason", reason,
                            ContentVerifyJob::FAILURE_REASON_MAX);
}

void ChromeContentVerifierDelegate::Shutdown() {
  // Shut down |policy_extension_reinstaller_| on its creation thread. |this|
  // can be destroyed through InfoMap on IO thread, we do not want to destroy
  // |policy_extension_reinstaller_| there.
  policy_extension_reinstaller_.reset();
}

bool ChromeContentVerifierDelegate::IsFromWebstore(
    const Extension& extension) const {
  // Use the InstallVerifier's |IsFromStore| method to avoid discrepancies
  // between which extensions are considered in-store.
  // See https://crbug.com/766806 for details.
  if (!InstallVerifier::IsFromStore(extension, context_)) {
    // It's possible that the webstore update url was overridden for testing
    // so also consider extensions with the default (production) update url
    // to be from the store as well. Therefore update URL is compared with
    // |GetDefaultWebstoreUpdateUrl|, not the |GetWebstoreUpdateUrl| used by
    // |IsWebstoreUpdateUrl|.
    ExtensionManagement* extension_management =
        ExtensionManagementFactory::GetForBrowserContext(context_);
    if (extension_management->GetEffectiveUpdateURL(extension) !=
        extension_urls::GetDefaultWebstoreUpdateUrl()) {
      return false;
    }
  }
  return true;
}

ChromeContentVerifierDelegate::VerifyInfo
ChromeContentVerifierDelegate::GetVerifyInfo(const Extension& extension) const {
  ManagementPolicy* management_policy =
      ExtensionSystem::Get(context_)->management_policy();

  // Magement policy may be not configured in some tests.
  bool should_repair = management_policy &&
                       management_policy->ShouldRepairIfCorrupted(&extension);
  bool is_from_webstore = IsFromWebstore(extension);

#if BUILDFLAG(IS_CHROMEOS_ASH)
  if (ExtensionAssetsManagerChromeOS::IsSharedInstall(&extension)) {
    return VerifyInfo(VerifyInfo::Mode::ENFORCE_STRICT, is_from_webstore,
                      should_repair);
  }
#endif

  if (should_repair)
    return VerifyInfo(default_mode_, is_from_webstore, should_repair);

  if (!extension.is_extension() && !extension.is_legacy_packaged_app())
    return VerifyInfo(VerifyInfo::Mode::NONE, is_from_webstore, should_repair);
  if (!Manifest::IsAutoUpdateableLocation(extension.location()))
    return VerifyInfo(VerifyInfo::Mode::NONE, is_from_webstore, should_repair);
  if (!is_from_webstore)
    return VerifyInfo(VerifyInfo::Mode::NONE, is_from_webstore, should_repair);

  return VerifyInfo(default_mode_, is_from_webstore, should_repair);
}

}  // namespace extensions
