// Copyright 2016 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.

#include "authpolicy/process_executor.h"

#include <stdlib.h>
#include <algorithm>
#include <utility>

#include <base/check.h>
#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/strings/string_split.h>
#include <base/strings/stringprintf.h>
#include <libminijail.h>
#include <scoped_minijail.h>

#include "authpolicy/anonymizer.h"
#include "authpolicy/log_colors.h"
#include "authpolicy/platform_helper.h"
#include "authpolicy/samba_helper.h"

namespace authpolicy {
namespace {

// Prevent some environment variables from being wiped since they're used by
// tests. crbug.com/718182.
struct EnvVarDef {
  const char* name_equals;  // "name="
  size_t size;              // strlen("name=")
};

// Note: strlen doesn't work with constexpr.
#define DEFINE_ENV_VAR(name) \
  { name "=", sizeof(name "=") - 1 }

constexpr EnvVarDef kWhitelistedEnvVars[]{
    DEFINE_ENV_VAR("ASAN_OPTIONS"),  DEFINE_ENV_VAR("LSAN_OPTIONS"),
    DEFINE_ENV_VAR("MSAN_OPTIONS"),  DEFINE_ENV_VAR("TSAN_OPTIONS"),
    DEFINE_ENV_VAR("UBSAN_OPTIONS"),
};

#undef DEFINE_ENV_VAR

}  // namespace

ProcessExecutor::ProcessExecutor(std::vector<std::string> args)
    : args_(std::move(args)) {}

void ProcessExecutor::SetInputFile(int fd) {
  input_fd_ = fd;
}

void ProcessExecutor::SetInputString(const std::string& input_str) {
  input_str_ = input_str;
}

void ProcessExecutor::SetEnv(const std::string& key, const std::string& value) {
  env_map_[key] = value;
}

void ProcessExecutor::SetSeccompFilter(const std::string& policy_file) {
  seccomp_policy_file_ = policy_file;
}

void ProcessExecutor::LogSeccompFilterFailures(bool enabled) {
  log_seccomp_failures_ = enabled;
}

void ProcessExecutor::SetNoNewPrivs(bool enabled) {
  no_new_privs_ = enabled;
}

void ProcessExecutor::KeepSupplementaryGroups(bool enabled) {
  keep_supplementary_flags_ = enabled;
}

void ProcessExecutor::LogCommand(bool enabled) {
  log_command_ = enabled;
}

void ProcessExecutor::LogOutput(bool enabled) {
  log_output_ = enabled;
}

void ProcessExecutor::LogOutputOnError(bool enabled) {
  log_output_on_error_ = enabled;
}

void ProcessExecutor::SetAnonymizer(Anonymizer* anonymizer) {
  anonymizer_ = anonymizer;
}

bool ProcessExecutor::Execute() {
  ResetOutput();
  if (args_.empty() || args_[0].empty())
    return true;

  bool need_anonymizer = log_command_ || log_output_ || log_output_on_error_;
  CHECK(anonymizer_ || !need_anonymizer) << "Logs must be anonymized";

  if (!base::FilePath(args_[0]).IsAbsolute()) {
    LOG(ERROR) << "Command must be specified by absolute path.";
    exit_code_ = kExitCodeInternalError;
    return false;
  }

  if (log_command_ && LOG_IS_ON(INFO)) {
    std::string cmd = args_[0];
    for (size_t n = 1; n < args_.size(); ++n)
      cmd += base::StringPrintf(" '%s'", args_[n].c_str());
    LOG(INFO) << kColorCommand << "Executing " << anonymizer_->Process(cmd)
              << kColorReset;
  }

  // Convert args to array of pointers. Must be nullptr terminated.
  std::vector<char*> args_ptr;
  for (const auto& arg : args_)
    args_ptr.push_back(const_cast<char*>(arg.c_str()));
  args_ptr.push_back(nullptr);

  // Save old environment and set ours. Note that clearenv() doesn't actually
  // delete any pointers, so we can just keep the old pointers.
  std::vector<char*> old_environ;
  for (char** env = environ; env != nullptr && *env != nullptr; ++env)
    old_environ.push_back(*env);
  clearenv();

  // Store strings in list because putenv requires pointers to stay alive.
  std::vector<std::string> env_list;
  for (const auto& env : env_map_) {
    env_list.push_back(env.first + "=" + env.second);
    putenv(const_cast<char*>(env_list.back().c_str()));
  }

  // Add back whitelisted env vars. Note that |whitelisted_var.name_equals| is
  // name= and |env| is name=value. A linear search seems fine, but consider
  // using a map if kWhitelistedEnvVars grows.
  for (char* env : old_environ) {
    for (const EnvVarDef& whitelisted_var : kWhitelistedEnvVars) {
      if (strncmp(env, whitelisted_var.name_equals, whitelisted_var.size) == 0)
        putenv(env);
    }
  }

  // Prepare minijail.
  ScopedMinijail jail(minijail_new());
  if (log_seccomp_failures_)
    minijail_log_seccomp_filter_failures(jail.get());
  if (!seccomp_policy_file_.empty()) {
    minijail_parse_seccomp_filters(jail.get(), seccomp_policy_file_.c_str());
    minijail_use_seccomp_filter(jail.get());
  }
  if (no_new_privs_)
    minijail_no_new_privs(jail.get());
  if (keep_supplementary_flags_)
    minijail_keep_supplementary_gids(jail.get());

  // Execute the command.
  pid_t pid = -1;
  int child_stdin = -1, child_stdout = -1, child_stderr = -1;
  minijail_run_pid_pipes(jail.get(), args_ptr[0], args_ptr.data(), &pid,
                         &child_stdin, &child_stdout, &child_stderr);

  // Make sure the pipes never block.
  if (!base::SetNonBlocking(child_stdin))
    LOG(WARNING) << "Failed to set stdin non-blocking";
  if (!base::SetNonBlocking(child_stdout))
    LOG(WARNING) << "Failed to set stdout non-blocking";
  if (!base::SetNonBlocking(child_stderr))
    LOG(WARNING) << "Failed to set stderr non-blocking";

  // Restore the environment.
  clearenv();
  for (char* env : old_environ)
    putenv(env);

  if (perform_pipe_io_after_process_exit_for_testing_)
    exit_code_ = minijail_wait(jail.get());

  // Write to child_stdin and read from child_stdout and child_stderr while
  // there is still data to read/write.
  bool io_success =
      PerformPipeIo(child_stdin, child_stdout, child_stderr, input_fd_,
                    input_str_, &out_data_, &err_data_);

  // Wait for the process to exit.
  if (!perform_pipe_io_after_process_exit_for_testing_)
    exit_code_ = minijail_wait(jail.get());
  jail.reset();

  // Print out a useful error message for seccomp failures.
  if (exit_code_ == MINIJAIL_ERR_JAIL)
    LOG(ERROR) << "Seccomp filter blocked a system call";

  // Always exit AFTER minijail_wait! If we do it before, the exit code is never
  // queried and the process is left dangling.
  if (!io_success) {
    LOG(ERROR) << "IO failed";
    exit_code_ = kExitCodeInternalError;
    return false;
  }

  output_logged_ = false;
  if (log_output_ || (log_output_on_error_ && exit_code_ != 0))
    LogOutputOnce();
  LOG_IF(INFO, log_command_)
      << kColorCommand << "Exit code: " << exit_code_ << kColorReset;

  return exit_code_ == 0;
}

void ProcessExecutor::LogOutputOnce() {
  if (output_logged_ || args_.empty() || !(log_output_on_error_ || log_output_))
    return;
  LogLongString(kColorCommandStdout, args_[0] + " stdout: ", out_data_,
                anonymizer_);
  LogLongString(kColorCommandStderr, args_[0] + " stderr: ", err_data_,
                anonymizer_);
  output_logged_ = true;
}

void ProcessExecutor::SetPerformPipeIoAfterProcessExitForTesting(
    bool perform_pipe_io_after_process_exit_for_testing) {
  perform_pipe_io_after_process_exit_for_testing_ =
      perform_pipe_io_after_process_exit_for_testing;
}

void ProcessExecutor::ResetOutput() {
  exit_code_ = 0;
  out_data_.clear();
  err_data_.clear();
}

}  // namespace authpolicy
