// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/ui/webui/sandbox/sandbox_handler.h"

#include <utility>

#include "base/functional/bind.h"
#include "base/numerics/safe_conversions.h"
#include "base/values.h"
#include "content/public/browser/browser_child_process_host_iterator.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/child_process_data.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/web_ui.h"
#include "content/public/common/process_type.h"
#include "sandbox/policy/features.h"
#include "sandbox/policy/win/sandbox_win.h"

using content::BrowserChildProcessHostIterator;
using content::ChildProcessData;
using content::RenderProcessHost;

namespace sandbox_handler {
namespace {

base::Value::List FetchBrowserChildProcesses() {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  base::Value::List browser_processes;

  for (BrowserChildProcessHostIterator itr; !itr.Done(); ++itr) {
    const ChildProcessData& process_data = itr.GetData();
    // Only add processes that have already started, i.e. with valid handles.
    if (!process_data.GetProcess().IsValid()) {
      continue;
    }
    base::Value::Dict proc;
    proc.Set("processId",
             base::strict_cast<double>(process_data.GetProcess().Pid()));
    proc.Set("processType",
             content::GetProcessTypeNameInEnglish(process_data.process_type));
    proc.Set("name", process_data.name);
    proc.Set("metricsName", process_data.metrics_name);
    proc.Set("sandboxType",
             sandbox::policy::SandboxWin::GetSandboxTypeInEnglish(
                 process_data.sandbox_type));
    browser_processes.Append(std::move(proc));
  }

  return browser_processes;
}

base::Value::List FetchRenderHostProcesses() {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  base::Value::List renderer_processes;

  for (RenderProcessHost::iterator it(RenderProcessHost::AllHostsIterator());
       !it.IsAtEnd(); it.Advance()) {
    RenderProcessHost* host = it.GetCurrentValue();
    // Skip processes that might not have started yet.
    if (!host->GetProcess().IsValid()) {
      continue;
    }

    base::Value::Dict proc;
    proc.Set("processId", base::strict_cast<double>(host->GetProcess().Pid()));
    renderer_processes.Append(std::move(proc));
  }

  return renderer_processes;
}

base::Value::Dict FeatureToValue(const base::Feature& feature) {
  base::Value::Dict feature_info;
  feature_info.Set("name", feature.name);
  feature_info.Set("enabled", base::FeatureList::IsEnabled(feature));
  return feature_info;
}

base::Value::List FetchSandboxFeatures() {
  base::Value::List features;
  features.Append(
      FeatureToValue(sandbox::policy::features::kNetworkServiceSandbox));
  features.Append(
      FeatureToValue(sandbox::policy::features::kRendererAppContainer));
  features.Append(FeatureToValue(
      sandbox::policy::features::kWinSboxDisableExtensionPoints));
  features.Append(
      FeatureToValue(sandbox::policy::features::kWinSboxZeroAppShim));
  features.Append(
      FeatureToValue(sandbox::policy::features::kWinSboxNoFakeGdiInit));
  features.Append(FeatureToValue(
      sandbox::policy::features::kWinSboxRestrictCoreSharingOnRenderer));
  features.Append(
      FeatureToValue(sandbox::policy::features::kEnableCsrssLockdown));
  return features;
}

}  // namespace

SandboxHandler::SandboxHandler() = default;
SandboxHandler::~SandboxHandler() = default;

void SandboxHandler::RegisterMessages() {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

  web_ui()->RegisterMessageCallback(
      "requestSandboxDiagnostics",
      base::BindRepeating(&SandboxHandler::HandleRequestSandboxDiagnostics,
                          base::Unretained(this)));
}

void SandboxHandler::HandleRequestSandboxDiagnostics(
    const base::Value::List& args) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

  CHECK_EQ(1U, args.size());
  sandbox_diagnostics_callback_id_ = args[0].Clone();

  AllowJavascript();

  browser_processes_ = FetchBrowserChildProcesses();

  sandbox::policy::SandboxWin::GetPolicyDiagnostics(
      base::BindOnce(&SandboxHandler::FetchSandboxDiagnosticsCompleted,
                     weak_ptr_factory_.GetWeakPtr()));
}

// This runs nested inside SandboxWin so we get out quickly.
void SandboxHandler::FetchSandboxDiagnosticsCompleted(
    base::Value sandbox_policies) {
  sandbox_policies_ = std::move(sandbox_policies);
  content::GetUIThreadTaskRunner({})->PostTask(
      FROM_HERE, base::BindOnce(&SandboxHandler::GetRendererProcessesAndFinish,
                                weak_ptr_factory_.GetWeakPtr()));
}

void SandboxHandler::GetRendererProcessesAndFinish() {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

  auto renderer_processes = FetchRenderHostProcesses();
  base::Value::Dict results;
  results.Set("browser", std::move(browser_processes_));
  results.Set("policies", std::move(sandbox_policies_));
  results.Set("renderer", std::move(renderer_processes));
  results.Set("features", FetchSandboxFeatures());
  ResolveJavascriptCallback(sandbox_diagnostics_callback_id_,
                            std::move(results));
}

}  // namespace sandbox_handler
