// Copyright 2019 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/download/mixed_content_download_blocking.h"

#include <string>

#include "base/metrics/field_trial_params.h"
#include "base/metrics/histogram_functions.h"
#include "base/optional.h"
#include "base/strings/string_split.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "build/build_config.h"
#include "chrome/common/chrome_features.h"
#include "content/public/browser/download_item_utils.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/origin_util.h"
#include "third_party/blink/public/mojom/devtools/console_message.mojom.h"
#include "url/gurl.h"
#include "url/origin.h"

namespace {

// Map the string file extension to the corresponding histogram enum.
InsecureDownloadExtensions GetExtensionEnumFromString(
    const std::string& extension) {
  if (extension.empty())
    return InsecureDownloadExtensions::kNone;

  auto lower_extension = base::ToLowerASCII(extension);
  for (auto candidate : kExtensionsToEnum) {
    if (candidate.extension == lower_extension)
      return candidate.value;
  }
  return InsecureDownloadExtensions::kUnknown;
}

// Get the appropriate histogram metric name for the initiator/download security
// state combo.
std::string GetDownloadBlockingExtensionMetricName(
    base::Optional<url::Origin> initiator,
    bool dl_secure) {
  if (!initiator.has_value()) {
    if (dl_secure)
      return kInsecureDownloadHistogramInitiatorUnknownTargetSecure;
    return kInsecureDownloadHistogramInitiatorUnknownTargetInsecure;
  }

  if (initiator->GetURL().SchemeIsCryptographic()) {
    if (dl_secure)
      return kInsecureDownloadHistogramInitiatorSecureTargetSecure;
    return kInsecureDownloadHistogramInitiatorSecureTargetInsecure;
  }

  if (dl_secure)
    return kInsecureDownloadHistogramInitiatorInsecureTargetSecure;
  return kInsecureDownloadHistogramInitiatorInsecureTargetInsecure;
}

// Get appropriate enum value for the initiator/download security state combo
// for histogram reporting.
InsecureDownloadSecurityStatus GetDownloadBlockingEnum(
    base::Optional<url::Origin> initiator,
    bool dl_secure) {
  if (!initiator.has_value()) {
    if (dl_secure)
      return InsecureDownloadSecurityStatus::kInitiatorUnknownFileSecure;
    return InsecureDownloadSecurityStatus::kInitiatorUnknownFileInsecure;
  }

  if (initiator->GetURL().SchemeIsCryptographic()) {
    if (dl_secure)
      return InsecureDownloadSecurityStatus::kInitiatorSecureFileSecure;
    return InsecureDownloadSecurityStatus::kInitiatorSecureFileInsecure;
  }

  if (dl_secure)
    return InsecureDownloadSecurityStatus::kInitiatorInsecureFileSecure;
  return InsecureDownloadSecurityStatus::kInitiatorInsecureFileInsecure;
}

}  // namespace

bool ShouldBlockFileAsMixedContent(const base::FilePath& path,
                                   const download::DownloadItem& item) {
  // Extensions must be in lower case! Extensions are compared against save path
  // determined by Chrome prior to the user seeing a file picker.
  const std::vector<std::string> kDefaultUnsafeExtensions = {
      "exe", "scr", "msi", "vb",  "dmg", "pkg", "crx",
      "gz",  "zip", "bz2", "rar", "7z",  "tar",
  };

  // Evaluate download security
  const GURL& dl_url = item.GetURL();
  bool is_download_secure = content::IsOriginSecure(dl_url) ||
                            dl_url.SchemeIsBlob() || dl_url.SchemeIsFile();
  bool is_redirect_chain_secure = true;
  for (const auto& url : item.GetUrlChain()) {
    if (!content::IsOriginSecure(url)) {
      is_redirect_chain_secure = false;
      break;
    }
  }
  is_download_secure = is_download_secure && is_redirect_chain_secure;

  // Check field trials for override of the unsafe extensions.
  std::string field_trial_arg = base::GetFieldTrialParamValueByFeature(
      features::kTreatUnsafeDownloadsAsActive,
      features::kTreatUnsafeDownloadsAsActiveParamName);
  std::vector<base::StringPiece> unsafe_extensions = base::SplitStringPiece(
      field_trial_arg, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
  if (unsafe_extensions.empty()) {
    unsafe_extensions.insert(unsafe_extensions.end(),
                             kDefaultUnsafeExtensions.begin(),
                             kDefaultUnsafeExtensions.end());
  }

  auto initiator = item.GetRequestInitiator();

  // Then see if that extension is blocked
  bool found_blocked_extension = false;
#if defined(OS_WIN)
  std::string extension(base::WideToUTF8(path.FinalExtension()));
#else
  std::string extension(path.FinalExtension());
#endif
  if (!extension.empty()) {
    extension = extension.substr(1);  // Omit leading dot.
    for (const auto& unsafe_extension : unsafe_extensions) {
      if (base::LowerCaseEqualsASCII(extension, unsafe_extension)) {
        found_blocked_extension = true;
        break;
      }
    }
  }

  base::UmaHistogramEnumeration(
      GetDownloadBlockingExtensionMetricName(initiator, is_download_secure),
      GetExtensionEnumFromString(extension));
  base::UmaHistogramEnumeration(
      kInsecureDownloadHistogramName,
      GetDownloadBlockingEnum(initiator, is_download_secure));

  if (!(initiator.has_value() && initiator->GetURL().SchemeIsCryptographic() &&
        !is_download_secure && found_blocked_extension &&
        base::FeatureList::IsEnabled(
            features::kTreatUnsafeDownloadsAsActive))) {
    return false;
  }

  content::WebContents* web_contents =
      content::DownloadItemUtils::GetWebContents(&item);
  if (web_contents) {
    web_contents->GetMainFrame()->AddMessageToConsole(
        blink::mojom::ConsoleMessageLevel::kError,
        base::StringPrintf(
            "Mixed Content: The site at '%s' was loaded over a secure "
            "connection, but the file at '%s' was %s an insecure "
            "connection. This file should be served over HTTPS.",
            initiator->GetURL().spec().c_str(), item.GetURL().spec().c_str(),
            (is_redirect_chain_secure ? "loaded over" : "redirected through")));
  }

  return true;
}
