// Copyright 2019 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 "kerberos/krb5_jail_wrapper.h"

#include <vector>

#include <sys/wait.h>

#include <base/check.h>
#include <base/check_op.h>
#include <base/files/file_util.h>
#include <base/files/scoped_file.h>
#include <base/logging.h>
#include <base/process/process.h>

namespace kerberos {
namespace {

constexpr char kerberosd_exec[] = "kerberosd-exec";

// Timeout for child processes.
constexpr base::TimeDelta kProcessExitTimeout = base::TimeDelta::FromMinutes(3);

bool g_change_user_disabled_for_testing = false;

// Read/write for owner, read for group.
constexpr int kFileMode_rw_r = base::FILE_PERMISSION_READ_BY_USER |
                               base::FILE_PERMISSION_WRITE_BY_USER |
                               base::FILE_PERMISSION_READ_BY_GROUP;

// Forks a process to a parent and a jailed child process and manages a pipe for
// data transfer from the child to the parent.
class MinijailForker {
 public:
  // Forks the process into a parent and a child process and puts the child in a
  // jail because it was naughty. Also sets up a pipe to send data from the
  // child to the parent.
  MinijailForker();
  ~MinijailForker();

  // Returns true if the current process is the child process.
  // Returns false for the parent process.
  bool IsChild() const { return child_pid_ == 0; }

  //
  // Child interface. DCHECKs IsChild().
  //

  // Writes the |error| status to the data pipe.
  void Child_WriteError(ErrorType error);

  // Writes the |tgt_status| code to the data pipe.
  void Child_WriteTgtStatus(const Krb5Interface::TgtStatus& tgt_status);

  // Writes the config validation |error_info| to the data pipe.
  void Child_WriteErrorInfo(const ConfigErrorInfo& error_info);

  // Exits the process with code 0 if no error occurred and 1 otherwise.
  void Child_Exit();

  //
  // Parent interface. DCHECKs !IsChild().
  //

  // Waits for the child process to exit. Sets |error_| to true in case the
  // child didn't exit with status 0.
  void Parent_Wait();

  // Reads an error status from the data pipe.
  ErrorType Parent_ReadError();

  // Reads a TGT status from the data pipe.
  Krb5Interface::TgtStatus Parent_ReadTgtStatus();

  // Reads config validation error info from the data pipe.
  ConfigErrorInfo Parent_ReadErrorInfo();

 private:
  // Writes |data| of size |data_size| to the data pipe. Sets |error_| on error.
  // Note: Assumes that all data fits into the pipe buffer. If the pipe buffer
  // is exceeded, |error_| is set to true.
  void Child_Write(const void* data, size_t data_size);

  // Reads |data| of size |data_size| from the data pipe. |data| must be big
  // enough to hold |data_size| bytes. Sets |error_| on error.
  void Parent_Read(void* data, size_t data_size);

  ScopedMinijail jail_;
  base::ScopedFD pipe_read_end_;
  base::ScopedFD pipe_write_end_;
  pid_t child_pid_ = -1;
  bool error_ = false;
};

MinijailForker::MinijailForker() : jail_(minijail_new()) {
  // Create pipes for data transfer from child to parent.
  int pipe_fd[2];
  if (!base::CreateLocalNonBlockingPipe(pipe_fd)) {
    LOG(ERROR) << "Failed to create pipe";
    error_ = true;
    return;
  }
  pipe_read_end_.reset(pipe_fd[0]);
  pipe_write_end_.reset(pipe_fd[1]);

  // Change uid to kerberosd-exec.
  if (!g_change_user_disabled_for_testing)
    CHECK_EQ(0, minijail_change_user(jail_.get(), kerberosd_exec));

  // Required since we don't have the caps to wipe supplementary groups.
  minijail_keep_supplementary_gids(jail_.get());

  // Fork the process.
  child_pid_ = minijail_fork(jail_.get());
  if (child_pid_ < 0) {
    PLOG(ERROR) << "Failed to fork process and enter jail";
    error_ = true;
    return;
  }
}

MinijailForker::~MinijailForker() = default;

void MinijailForker::Child_WriteError(ErrorType error) {
  Child_Write(&error, sizeof(error));
}

void MinijailForker::Child_WriteTgtStatus(
    const Krb5Interface::TgtStatus& tgt_status) {
  Child_Write(&tgt_status.validity_seconds,
              sizeof(tgt_status.validity_seconds));
  Child_Write(&tgt_status.renewal_seconds, sizeof(tgt_status.renewal_seconds));
}

void MinijailForker::Child_WriteErrorInfo(const ConfigErrorInfo& error_info) {
  std::vector<uint8_t> buffer(error_info.ByteSizeLong());
  CHECK(error_info.SerializeToArray(buffer.data(), buffer.size()));
  int buffer_size = static_cast<int>(buffer.size());
  Child_Write(&buffer_size, sizeof(buffer_size));
  Child_Write(buffer.data(), buffer.size());
}

void MinijailForker::Child_Exit() {
  DCHECK(IsChild());
  exit(error_ ? 1 : 0);
}

void MinijailForker::Parent_Wait() {
  DCHECK(!IsChild());

  auto process = base::Process::Open(child_pid_);
  int exit_code = -1;
  if (!process.WaitForExitWithTimeout(kProcessExitTimeout, &exit_code)) {
    LOG(ERROR) << "Child process timed out";
    process.Terminate(-1 /* exit_code */, false /* wait */);
    error_ = true;
    return;
  }

  if (exit_code != 0) {
    LOG(ERROR) << "Child process exited with code " << exit_code;
    error_ = true;
  }
}

ErrorType MinijailForker::Parent_ReadError() {
  // Handle internal errors, don't try to read ErrorType, it might block.
  ErrorType error = ERROR_JAIL_FAILURE;
  if (error_)
    return error;

  Parent_Read(&error, sizeof(error));
  return error_ ? ERROR_JAIL_FAILURE : error;
}

Krb5Interface::TgtStatus MinijailForker::Parent_ReadTgtStatus() {
  // Handle internal errors, don't try to read the TGT status, it might block.
  Krb5Interface::TgtStatus tgt_status;
  if (error_)
    return tgt_status;

  Parent_Read(&tgt_status.validity_seconds,
              sizeof(tgt_status.validity_seconds));
  Parent_Read(&tgt_status.renewal_seconds, sizeof(tgt_status.renewal_seconds));
  return tgt_status;
}

ConfigErrorInfo MinijailForker::Parent_ReadErrorInfo() {
  // Handle internal errors, don't try to read the error info, it might block.
  ConfigErrorInfo error_info;
  if (error_)
    return error_info;

  int buffer_size = 0;
  Parent_Read(&buffer_size, sizeof(buffer_size));
  if (buffer_size == 0)
    return error_info;

  std::vector<uint8_t> buffer;
  buffer.resize(buffer_size);
  Parent_Read(buffer.data(), buffer_size);
  error_info.ParseFromArray(buffer.data(), buffer_size);
  return error_info;
}

void MinijailForker::Child_Write(const void* data, size_t data_size) {
  DCHECK(IsChild());
  if (!base::WriteFileDescriptor(
          pipe_write_end_.get(),
          base::make_span(static_cast<const uint8_t*>(data), data_size))) {
    LOG(ERROR) << "Failed to write " << data_size << " bytes";
    error_ = true;
  }
}

void MinijailForker::Parent_Read(void* data, size_t data_size) {
  DCHECK(!IsChild());
  if (HANDLE_EINTR(read(pipe_read_end_.get(), data, data_size)) !=
      static_cast<int>(data_size)) {
    LOG(ERROR) << "Failed to read " << data_size << " bytes";
    error_ = true;
  }
}

// If |error| is ERROR_NONE, gives TGT at |krb5cc_path| group read permission
// (for the kerberosd group), so that the kerberosd user can read it.
void SetTgtFilePermissions(const base::FilePath& krb5cc_path, ErrorType error) {
  if (error == ERROR_NONE)
    CHECK(base::SetPosixFilePermissions(krb5cc_path, kFileMode_rw_r));
}

}  // namespace

Krb5JailWrapper::Krb5JailWrapper(std::unique_ptr<Krb5Interface> krb5)
    : krb5_(std::move(krb5)) {}

Krb5JailWrapper::~Krb5JailWrapper() = default;

ErrorType Krb5JailWrapper::AcquireTgt(const std::string& principal_name,
                                      const std::string& password,
                                      const base::FilePath& krb5cc_path,
                                      const base::FilePath& krb5conf_path) {
  MinijailForker forker;

  if (forker.IsChild()) {
    ErrorType error =
        krb5_->AcquireTgt(principal_name, password, krb5cc_path, krb5conf_path);
    SetTgtFilePermissions(krb5cc_path, error);
    forker.Child_WriteError(error);
    forker.Child_Exit();
  }

  forker.Parent_Wait();
  return forker.Parent_ReadError();
}

ErrorType Krb5JailWrapper::RenewTgt(const std::string& principal_name,
                                    const base::FilePath& krb5cc_path,
                                    const base::FilePath& krb5conf_path) {
  MinijailForker forker;

  if (forker.IsChild()) {
    ErrorType error =
        krb5_->RenewTgt(principal_name, krb5cc_path, krb5conf_path);
    SetTgtFilePermissions(krb5cc_path, error);
    forker.Child_WriteError(error);
    forker.Child_Exit();
  }

  forker.Parent_Wait();
  return forker.Parent_ReadError();
}

ErrorType Krb5JailWrapper::GetTgtStatus(const base::FilePath& krb5cc_path,
                                        Krb5Interface::TgtStatus* status) {
  MinijailForker forker;

  if (forker.IsChild()) {
    ErrorType error = krb5_->GetTgtStatus(krb5cc_path, status);
    forker.Child_WriteTgtStatus(*status);
    forker.Child_WriteError(error);
    forker.Child_Exit();
  }

  forker.Parent_Wait();
  *status = forker.Parent_ReadTgtStatus();
  return forker.Parent_ReadError();
}

ErrorType Krb5JailWrapper::ValidateConfig(const std::string& krb5conf,
                                          ConfigErrorInfo* error_info) {
  MinijailForker forker;

  if (forker.IsChild()) {
    ErrorType error = krb5_->ValidateConfig(krb5conf, error_info);
    forker.Child_WriteErrorInfo(*error_info);
    forker.Child_WriteError(error);
    forker.Child_Exit();
  }

  forker.Parent_Wait();
  *error_info = forker.Parent_ReadErrorInfo();
  return forker.Parent_ReadError();
}

// static
void Krb5JailWrapper::DisableChangeUserForTesting(bool disabled) {
  g_change_user_disabled_for_testing = disabled;
}

}  // namespace kerberos
