// 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/logging.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
