// Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// This class is most definitely NOT re-entrant.

#include "login_manager/browser_job.h"

#include <errno.h>
#include <inttypes.h>
#include <signal.h>
#include <stdint.h>
#include <stdlib.h>

#include <algorithm>
#include <queue>
#include <utility>

#include <base/check.h>
#include <base/check_op.h>
#include <base/json/json_writer.h>
#include <base/logging.h>
#include <base/rand_util.h>
#include <base/stl_util.h>
#include <base/strings/string_number_conversions.h>
#include <base/strings/string_util.h>
#include <base/values.h>
#include <chromeos/switches/chrome_switches.h>

#include "login_manager/file_checker.h"
#include "login_manager/login_metrics.h"
#include "login_manager/subprocess.h"
#include "login_manager/system_utils.h"

namespace login_manager {

const char BrowserJobInterface::kLoginManagerFlag[] = "--login-manager";
const char BrowserJobInterface::kLoginUserFlag[] = "--login-user=";
const char BrowserJobInterface::kLoginProfileFlag[] = "--login-profile=";
const char BrowserJobInterface::kCrashLoopBeforeFlag[] = "--crash-loop-before=";

const char BrowserJob::kFirstExecAfterBootFlag[] = "--first-exec-after-boot";

// Check for last 4 runs with extra args to detect startup crash. 4 allows
// the case of applying flags in guest sessions, where we have:
//   1st chrome start to show the login screen
//   2nd chrome start to enter guest sessions
//   3rd chrome start to apply flags from about:flags page
// If `kUseExtraArgsRuns` is 3 and the 3rd run is less than
// `kRestartWindowSecond` seconds (60s) apart from 1st run, it would be
// considered as too crashy and flags are dropped for the 3rd run.
// See https://crbug.com/1129951.
const int BrowserJob::kUseExtraArgsRuns = 4;
static_assert(BrowserJob::kUseExtraArgsRuns > 1,
              "kUseExtraArgsRuns should be greater than 1 because extra "
              "arguments could need one restart to apply them.");

const int BrowserJob::kRestartTries = BrowserJob::kUseExtraArgsRuns + 2;
const time_t BrowserJob::kRestartWindowSeconds = 60;

const char BrowserJobInterface::kGuestSessionFlag[] = "--bwsi";

namespace {

constexpr char kVmoduleFlag[] = "--vmodule=";
constexpr char kEnableFeaturesFlag[] = "--enable-features=";
constexpr char kDisableFeaturesFlag[] = "--disable-features=";
constexpr char kEnableBlinkFeaturesFlag[] = "--enable-blink-features=";
constexpr char kDisableBlinkFeaturesFlag[] = "--disable-blink-features=";
constexpr char kSafeModeFlag[] = "--safe-mode";

constexpr char kSessionManagerSafeModeEnabled[] =
    "SessionManager.SafeModeEnabled";

// Erases all occurrences of |arg| within |args|. Returns true if any entries
// were removed or false otherwise.
bool RemoveArgs(std::vector<std::string>* args, const std::string& arg) {
  std::vector<std::string>::iterator new_end =
      std::remove(args->begin(), args->end(), arg);
  if (new_end == args->end())
    return false;

  args->erase(new_end, args->end());
  return true;
}

// Joins the values of all switches in |args| prefixed by |prefix| using
// |separator| and appends a merged version of the switch. If |keep_existing| is
// true, all earlier occurrences of the switch are preserved; otherwise, they
// are removed.
void MergeSwitches(std::vector<std::string>* args,
                   const std::string& prefix,
                   const std::string& separator,
                   bool keep_existing) {
  std::string values;
  auto head = args->begin();
  for (const auto& arg : *args) {
    bool match = base::StartsWith(arg, prefix, base::CompareCase::SENSITIVE);
    if (match) {
      if (!values.empty())
        values += separator;
      values += arg.substr(prefix.size());
    }
    if (!match || keep_existing) {
      *head++ = arg;
    }
  }
  if (head != args->end())
    args->erase(head, args->end());
  if (!values.empty())
    args->push_back(prefix + values);
}

std::string GetUnprefixedFlagName(const std::string& flag) {
  static const char* const kSwitchPrefixes[] = {"--", "-"};

  std::string unprefixed = flag;
  for (const char* const prefix : kSwitchPrefixes) {
    std::string prefix_str(prefix);
    if (flag.rfind(prefix, 0) == 0) {
      unprefixed = flag.substr(prefix_str.length());
      break;
    }
  }

  return unprefixed.substr(0, unprefixed.find('='));
}

}  // namespace

BrowserJob::BrowserJob(const std::vector<std::string>& arguments,
                       const std::vector<std::string>& environment_variables,
                       FileChecker* checker,
                       LoginMetrics* metrics,
                       SystemUtils* utils,
                       const BrowserJob::Config& cfg,
                       std::unique_ptr<SubprocessInterface> subprocess)
    : arguments_(arguments),
      environment_variables_(environment_variables),
      file_checker_(checker),
      login_metrics_(metrics),
      system_(utils),
      start_times_(std::deque<time_t>(kRestartTries, 0)),
      config_(cfg),
      subprocess_(std::move(subprocess)) {
  // Take over managing kLoginManagerFlag.
  if (RemoveArgs(&arguments_, kLoginManagerFlag)) {
    removed_login_manager_flag_ = true;
    login_arguments_.push_back(kLoginManagerFlag);
  }
}

BrowserJob::~BrowserJob() {}

pid_t BrowserJob::CurrentPid() const {
  return subprocess_->GetPid();
}

bool BrowserJob::IsGuestSession() {
  return base::STLCount(arguments_, kGuestSessionFlag) > 0;
}

bool BrowserJob::ShouldRunBrowser() {
  return !file_checker_ || !file_checker_->exists();
}

bool BrowserJob::ShouldStop() const {
  return system_->time(nullptr) - start_times_.front() < kRestartWindowSeconds;
}

void BrowserJob::RecordTime() {
  start_times_.push_back(system_->time(nullptr));
  start_times_.pop_front();
  DCHECK_EQ(kRestartTries, start_times_.size());
}

bool BrowserJob::RunInBackground() {
  CHECK(login_metrics_);
  bool first_boot = !login_metrics_->HasRecordedChromeExec();
  login_metrics_->RecordStats("chrome-exec");

  RecordTime();

  extra_one_time_arguments_.clear();
  if (first_boot)
    extra_one_time_arguments_.push_back(kFirstExecAfterBootFlag);

  // Must happen after RecordTime(). After RecordTime(), ShouldStop() is
  // basically returning what it would return if this instance of the browser
  // crashed and wanted to be restarted again.
  if (ShouldStop()) {
    // This might be the last restart left in a crash-loop. If so, we don't want
    // crash_reporter to do its normal behavior of writing the crash dump into
    // the user directory, because after that next Chrome crash, the user will
    // be logged out, at which point the crash dump will become inaccessible.
    // Instead, instruct crash_reporter to keep the crash dump in-memory and
    // immediately upload it using UploadSingleCrash.
    time_t crash_loop_before = start_times_.front() + kRestartWindowSeconds;
    std::string crash_loop_before_arg =
        kCrashLoopBeforeFlag +
        base::NumberToString(static_cast<uint64_t>(crash_loop_before));
    extra_one_time_arguments_.push_back(crash_loop_before_arg);
  }

  const std::vector<std::string> argv(ExportArgv());
  const std::vector<std::string> env_vars(ExportEnvironmentVariables());
  LOG(INFO) << "Running browser " << base::JoinString(argv, " ");

  bool enter_existing_mount_ns = false;
  if (IsGuestSession()) {
    if (config_.isolate_guest_session &&
        config_.chrome_mount_ns_path.has_value()) {
      enter_existing_mount_ns = true;
    } else {
      LOG(INFO) << "Entering new mount namespace for browser.";
      subprocess_->UseNewMountNamespace();
    }
  } else {
    // Regular session.
    if (config_.isolate_regular_session &&
        config_.chrome_mount_ns_path.has_value()) {
      enter_existing_mount_ns = true;
    }
  }

  if (enter_existing_mount_ns) {
    base::FilePath ns_path = config_.chrome_mount_ns_path.value();
    LOG(INFO) << "Entering mount namespace '" << ns_path.value()
              << "' for browser";
    subprocess_->EnterExistingMountNamespace(ns_path);
  }

  return subprocess_->ForkAndExec(argv, env_vars);
}

void BrowserJob::KillEverything(int signal, const std::string& message) {
  if (subprocess_->GetPid() < 0)
    return;

  LOG(INFO) << "Terminating process group for browser " << subprocess_->GetPid()
            << " with signal " << signal << ": " << message;
  subprocess_->KillEverything(signal);
}

void BrowserJob::Kill(int signal, const std::string& message) {
  const pid_t pid = subprocess_->GetPid();
  if (pid < 0)
    return;

  LOG(INFO) << "Terminating browser process " << pid << " with signal "
            << signal << ": " << message;
  subprocess_->Kill(signal);
}

bool BrowserJob::WaitForExit(base::TimeDelta timeout) {
  const pid_t pid = subprocess_->GetPid();
  if (pid < 0)
    return true;

  return system_->ProcessGroupIsGone(pid, timeout);
}

void BrowserJob::AbortAndKillAll(base::TimeDelta timeout) {
  const pid_t pid = subprocess_->GetPid();
  if (pid < 0)
    return;

  if (system_->ProcessGroupIsGone(pid, base::TimeDelta())) {
    DLOG(INFO) << "Cleaned up browser process " << pid;
    return;
  }

  if (!system_->ProcessIsGone(pid, base::TimeDelta())) {
    LOG(WARNING) << "Aborting browser process " << pid;

    std::string message = "Browser aborted";
    // Send a SIGABRT to the browser process so that it generates a crash
    // report. We don't send SIGABRT to the other processes because the reports
    // are often corrupt and we aren't getting any value out of them.
    Kill(SIGABRT, message);

    // Wait to allow Breakpad or Crashpad time to collect the crash report.
    if (system_->ProcessGroupIsGone(pid, timeout)) {
      DLOG(INFO) << "browser group " << pid << " gone after SIGABRT wait";
      return;
    }
  }

  std::string message = base::StringPrintf(
      "Browser group took more than %" PRId64 " seconds to exit after signal.",
      timeout.InSeconds());
  LOG(WARNING) << "Killing browser process " << pid << "'s process group "
               << timeout.InSeconds() << " seconds after sending SIGABRT";
  KillEverything(SIGKILL, message);

  constexpr base::TimeDelta kTimeoutForSecondKill =
      base::TimeDelta::FromSeconds(1);
  if (!system_->ProcessGroupIsGone(pid, kTimeoutForSecondKill)) {
    LOG(WARNING) << "Browser process " << pid << "'s group still not gone "
                 << kTimeoutForSecondKill << " after sending SIGKILL signal";
  }
}

// When user logs in we want to restart chrome in browsing mode with
// user signed in. Hence we remove --login-manager flag and add
// --login-user=|account_id| and --login-profile=|userhash| flags.
void BrowserJob::StartSession(const std::string& account_id,
                              const std::string& userhash) {
  if (!session_already_started_) {
    login_arguments_.clear();
    login_arguments_.push_back(kLoginUserFlag + account_id);
    login_arguments_.push_back(kLoginProfileFlag + userhash);
  }
  session_already_started_ = true;
}

void BrowserJob::StopSession() {
  login_arguments_.clear();
  if (removed_login_manager_flag_) {
    login_arguments_.push_back(kLoginManagerFlag);
    removed_login_manager_flag_ = false;
  }
}

const std::string BrowserJob::GetName() const {
  base::FilePath exec_file(arguments_[0]);
  return exec_file.BaseName().value();
}

void BrowserJob::SetArguments(const std::vector<std::string>& arguments) {
  // Ensure we preserve the program name to be executed, if we have one.
  std::string argv0;
  if (!arguments_.empty())
    argv0 = arguments_[0];

  arguments_ = arguments;

  if (!argv0.empty()) {
    if (arguments_.size())
      arguments_[0] = argv0;
    else
      arguments_.push_back(argv0);
  }
}

void BrowserJob::SetExtraArguments(const std::vector<std::string>& arguments) {
  extra_arguments_.clear();
  auto is_not_unsafe = [](const std::string& flag) {
    // A list of flags that shouldn't be user-configurable on Chrome OS.
    // Keeping this the list watertight will be hard to impossible in practice,
    // so this is only a temporary measure until we have a more robust solution
    // for flag handling. See crbug.com/1073940 for details.
    static const char* const kUnsafeFlags[] = {
        "allow-sandbox-debugging",
        "disable-gpu-sandbox",
        "disable-namespace-sandbox",
        "disable-seccomp-filter-sandbox",
        "disable-setuid-sandbox",
        "gpu-launcher",
        "no-sandbox",
        "no-zygote-sandbox",
        "ppapi-plugin-launcher",
        "remote-debugging-port",
        "renderer-cmd-prefix",
        "single-process",
        "utility-cmd-prefix",
    };
    return std::find(std::begin(kUnsafeFlags), std::end(kUnsafeFlags),
                     GetUnprefixedFlagName(flag)) == std::end(kUnsafeFlags);
  };
  std::copy_if(arguments.begin(), arguments.end(),
               std::back_inserter(extra_arguments_), is_not_unsafe);
}

void BrowserJob::SetFeatureFlags(
    const std::vector<std::string>& feature_flags) {
  feature_flags_ = feature_flags;
}

void BrowserJob::SetTestArguments(const std::vector<std::string>& arguments) {
  test_arguments_ = arguments;
}

void BrowserJob::SetAdditionalEnvironmentVariables(
    const std::vector<std::string>& env_vars) {
  additional_environment_variables_ = env_vars;
}

void BrowserJob::ClearPid() {
  subprocess_->ClearPid();
}

std::vector<std::string> BrowserJob::ExportArgv() const {
  std::vector<std::string> to_return(arguments_.begin(), arguments_.end());
  to_return.insert(to_return.end(), login_arguments_.begin(),
                   login_arguments_.end());

  if (ShouldDropExtraArguments()) {
    LOG(WARNING) << "Dropping extra arguments and setting safe-mode switch due "
                    "to crashy browser.";
    to_return.emplace_back(kSafeModeFlag);
    login_metrics_->ReportCrosEvent(kSessionManagerSafeModeEnabled);
  } else {
    to_return.insert(to_return.end(), extra_arguments_.begin(),
                     extra_arguments_.end());

    // Encode feature flags.
    std::vector<base::Value> feature_flag_list;
    for (const auto& feature_flag : feature_flags_) {
      feature_flag_list.emplace_back(base::Value(feature_flag));
    }
    if (!feature_flag_list.empty()) {
      std::sort(feature_flag_list.begin(), feature_flag_list.end());
      std::string encoded;
      base::JSONWriter::Write(base::Value(std::move(feature_flag_list)),
                              &encoded);
      to_return.push_back(base::StringPrintf(
          "--%s=%s", chromeos::switches::kFeatureFlags, encoded.c_str()));
    }
  }

  if (!extra_one_time_arguments_.empty()) {
    to_return.insert(to_return.end(), extra_one_time_arguments_.begin(),
                     extra_one_time_arguments_.end());
  }

  to_return.insert(to_return.end(), test_arguments_.begin(),
                   test_arguments_.end());

  // Chrome doesn't support repeated switches in most cases. Merge switches
  // containing comma-separated values that may be supplied via multiple sources
  // (e.g. chrome_setup.cc, chrome://flags, Telemetry).
  //
  // --enable-features and --disable-features may be placed within sentinel
  // values (--flag-switches-begin/end, --policy-switches-begin/end). To
  // preserve those positions, keep the existing flags while also appending
  // merged versions at the end of the command line. Chrome will use the final,
  // merged flags: https://crbug.com/767266
  //
  // Chrome merges --enable-blink-features and --disable-blink-features for
  // renderer processes (see content::FeaturesFromSwitch()), but we still merge
  // the values here to produce shorter command lines.
  MergeSwitches(&to_return, kVmoduleFlag, ",", false /* keep_existing */);
  MergeSwitches(&to_return, kEnableFeaturesFlag, ",", true /* keep_existing */);
  MergeSwitches(&to_return, kDisableFeaturesFlag, ",",
                true /* keep_existing */);
  MergeSwitches(&to_return, kEnableBlinkFeaturesFlag, ",",
                false /* keep_existing */);
  MergeSwitches(&to_return, kDisableBlinkFeaturesFlag, ",",
                false /* keep_existing */);

  return to_return;
}

std::vector<std::string> BrowserJob::ExportEnvironmentVariables() const {
  std::vector<std::string> vars = environment_variables_;
  vars.insert(vars.end(), additional_environment_variables_.begin(),
              additional_environment_variables_.end());
  return vars;
}

bool BrowserJob::ShouldDropExtraArguments() const {
  // Check start_time_with_extra_args != 0 so that test cases such as
  // SetExtraArguments and ExportArgv pass without mocking time().
  const time_t start_time_with_extra_args =
      start_times_[kRestartTries - kUseExtraArgsRuns];
  return (start_time_with_extra_args != 0 &&
          system_->time(nullptr) - start_time_with_extra_args <
              kRestartWindowSeconds);
}

}  // namespace login_manager
