// 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/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(),
                                 static_cast<const char*>(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
