// 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 "vm_tools/concierge/plugin_vm_helper.h"

#include <sys/mount.h>

#include <algorithm>
#include <memory>
#include <string>
#include <utility>
#include <vector>

#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/json/json_reader.h>
#include <base/strings/string_piece.h>
#include <base/strings/string_util.h>
#include <base/strings/stringprintf.h>
#include <base/logging.h>
#include <base/values.h>
#include <chromeos/scoped_minijail.h>
#include <dbus/object_proxy.h>

#include "vm_tools/concierge/vmplugin_dispatcher_interface.h"

namespace vm_tools {
namespace concierge {
namespace pvm {
namespace helper {
namespace {

constexpr char kDlcPath[] = "/run/imageloader/pita/package/root";

constexpr char kVmHelperCommand[] = "opt/pita/pvm_helper";
constexpr char kVmHelperPolicyPath[] = "opt/pita/policy/pvm_helper.policy";

constexpr char kDispatcherSocketPath[] = "/run/pvm/vmplugin_dispatcher.socket";

// Minimal set of devices needed by the helpers.
constexpr const char* kDeviceNames[] = {"full", "null", "urandom", "zero"};

ScopedMinijail SetupSandbox(const base::FilePath& policy_file) {
  ScopedMinijail jail(minijail_new());
  if (!jail) {
    LOG(ERROR) << "Unable to create minijail";
    return ScopedMinijail();
  }

  minijail_namespace_pids(jail.get());
  minijail_namespace_user(jail.get());
  minijail_namespace_vfs(jail.get());
  minijail_namespace_ipc(jail.get());
  minijail_namespace_net(jail.get());
  minijail_namespace_cgroups(jail.get());
  minijail_namespace_uts(jail.get());

  std::string uid_map = base::StringPrintf("0 %d 1", geteuid());
  std::string gid_map = base::StringPrintf("0 %d 1", getegid());
  minijail_uidmap(jail.get(), uid_map.c_str());
  minijail_gidmap(jail.get(), gid_map.c_str());

  // Use a seccomp filter.
  minijail_log_seccomp_filter_failures(jail.get());
  minijail_parse_seccomp_filters(jail.get(), policy_file.value().c_str());
  minijail_use_seccomp_filter(jail.get());

  // We will manage this process's lifetime.
  minijail_run_as_init(jail.get());

  // The helpers do not require any capabilities.
  minijail_no_new_privs(jail.get());
  minijail_use_caps(jail.get(), 0);

  if (minijail_enter_pivot_root(jail.get(), "/mnt/empty") < 0) {
    LOG(ERROR) << "Failed to pivot root to /mnt/empty";
    return ScopedMinijail();
  }

  // Set up minimal set of mounts for the helpers to run.
  if (minijail_mount_with_data(jail.get(), "none", "/", "tmpfs",
                               MS_NOSUID | MS_NODEV | MS_NOEXEC,
                               "size=67108864") < 0) {
    LOG(ERROR) << "Failed to mount root tmpfs";
    return ScopedMinijail();
  }

  if (minijail_bind(jail.get(), "/opt/pita/", "/opt/pita", 0)) {
    LOG(ERROR) << "Failed to bind-mount /opt/pita";
    return ScopedMinijail();
  }

  if (minijail_bind(jail.get(), "/run/pvm", "/run/pvm", 1)) {
    LOG(ERROR) << "Failed to bind-mount /run/pvm";
    return ScopedMinijail();
  }

  // Create a minimal /dev with a very restricted set of device nodes.
  // We can't use minijail_mount_dev() because Chrome OS LSM module
  // does not allow unprivileged users mount filesystems other than
  // tmpfs.
  for (auto dev : kDeviceNames) {
    base::FilePath path(base::FilePath("/dev").Append(dev));
    if (minijail_bind(jail.get(), path.value().c_str(), path.value().c_str(),
                      true /* writeable */) < 0) {
      LOG(ERROR) << "Failed to bind-mount " << path.value();
      return ScopedMinijail();
    }
  }

  // Close all file descriptors we may have.
  minijail_close_open_fds(jail.get());

  return jail;
}

bool ConsumeFileDescriptor(int fd, std::string* contents) {
  base::FilePath path(base::StringPrintf("/proc/self/fd/%d", fd));
  return base::ReadFileToString(path, contents);
}

bool ExecutePvmHelper(const std::string& owner_id,
                      std::vector<std::string> params,
                      std::string* stdout_str = nullptr,
                      std::string* stderr_str = nullptr) {
  const base::FilePath path_prefix(kDlcPath);
  ScopedMinijail jail = SetupSandbox(path_prefix.Append(kVmHelperPolicyPath));
  if (!jail)
    return false;

  std::vector<std::string> args;
  args.emplace_back(path_prefix.Append(kVmHelperCommand).value());
  for (auto& param : params)
    args.emplace_back(std::move(param));
  args.emplace_back("--socket-path");
  args.emplace_back(kDispatcherSocketPath);
  args.emplace_back("--user-identity");
  args.emplace_back(owner_id);

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

  pid_t pid = -1;
  int child_stdout = -1, child_stderr = -1;
  int ret =
      minijail_run_pid_pipes(jail.get(), args_ptr[0], args_ptr.data(), &pid,
                             nullptr, stdout_str ? &child_stdout : nullptr,
                             stderr_str ? &child_stderr : nullptr);
  if (ret != 0) {
    LOG(ERROR) << "failed to execute helper in minijail: " << ret;
    return false;
  }

  if (stdout_str) {
    if (child_stdout >= 0) {
      ConsumeFileDescriptor(child_stdout, stdout_str);
      close(child_stdout);
    }
  }

  if (stderr_str) {
    if (child_stderr >= 0) {
      ConsumeFileDescriptor(child_stderr, stderr_str);
      close(child_stderr);
    }
  }

  // Always call minijail_wait(), otherwise exit code is never
  // queried and the process is left dangling.
  int exit_code = minijail_wait(jail.get());
  jail.reset();

  switch (exit_code) {
    case 0:
      return true;

    case MINIJAIL_ERR_JAIL:
      LOG(ERROR) << "helper failed because seccomp blocked a system call";
      return false;

    default:
      LOG(ERROR) << "helper for '" << args[1]
                 << "' failed with error: " << exit_code;
      return false;
  }
}

static std::unique_ptr<base::DictionaryValue> GetVmInfo(const VmId& vm_id) {
  std::string output;
  if (!ExecutePvmHelper(vm_id.owner_id(),
                        {"list", "--info", "--json", vm_id.name()}, &output)) {
    return nullptr;
  }

  auto result = base::JSONReader::Read(output);
  if (!result) {
    LOG(ERROR) << "GetVmInfo(" << vm_id << "): Failed to parse VM info";
    return nullptr;
  }

  if (!result->is_list()) {
    LOG(ERROR) << "GetVmInfo(" << vm_id
               << "): Expected to find a list at top level";
    return nullptr;
  }

  const base::ListValue* list;
  if (!result->GetAsList(&list)) {
    LOG(ERROR) << "GetVmInfo(" << vm_id << "): Failed to parse top level list";
    return nullptr;
  }

  if (list->GetSize() != 1) {
    LOG(ERROR) << "GetVmInfo(" << vm_id << "): Unexpected list size of "
               << list->GetSize();
    return nullptr;
  }

  const base::DictionaryValue* vm_info;
  if (!list->GetDictionary(0, &vm_info)) {
    LOG(ERROR) << "GetVmInfo(" << vm_id
               << "): Failed to fetch VM info dictionary";
    return nullptr;
  }

  return vm_info->CreateDeepCopy();
}

bool DisconnectDevice(const VmId& vm_id, const std::string& device_name) {
  return ExecutePvmHelper(
      vm_id.owner_id(),
      {"set", vm_id.name(), "--device-disconnect", device_name});
}

}  // namespace

bool IsDlcVm() {
  return base::PathExists(base::FilePath(kDlcPath));
}

bool CreateVm(const VmId& vm_id, std::vector<std::string> params) {
  std::vector<std::string> args = {
      "create",
      vm_id.name(),
  };
  std::move(params.begin(), params.end(), std::back_inserter(args));
  return ExecutePvmHelper(vm_id.owner_id(), std::move(args));
}

bool AttachIso(const VmId& vm_id,
               const std::string& cdrom_name,
               const std::string& iso_name) {
  std::vector<std::string> args = {
      "set",     vm_id.name(), "--device-set", cdrom_name,
      "--image", iso_name,     "--connect",
  };
  return ExecutePvmHelper(vm_id.owner_id(), std::move(args));
}

bool CreateCdromDevice(const VmId& vm_id, const std::string& iso_name) {
  std::vector<std::string> args = {
      "set",     vm_id.name(), "--device-add", "cdrom",
      "--image", iso_name,     "--connect",
  };
  return ExecutePvmHelper(vm_id.owner_id(), std::move(args));
}

bool DeleteVm(const VmId& vm_id) {
  return ExecutePvmHelper(vm_id.owner_id(), {"delete", vm_id.name()});
}

void CleanUpAfterInstall(const VmId& vm_id, const base::FilePath& iso_path) {
  auto vm_info = GetVmInfo(vm_id);
  if (!vm_info) {
    LOG(ERROR) << "Failed to obtain VM info for " << vm_id;
    return;
  }

  const base::DictionaryValue* hardware;
  if (!vm_info->GetDictionary("Hardware", &hardware)) {
    LOG(ERROR) << "Failed to obtain hardware info for " << vm_id;
    return;
  }

  base::DictionaryValue::Iterator it(*hardware);
  for (; !it.IsAtEnd(); it.Advance()) {
    if (!base::StartsWith(it.key(), "cdrom"))
      continue;

    const base::DictionaryValue* cdrom;
    if (!it.value().GetAsDictionary(&cdrom)) {
      LOG(WARNING) << "Hardware node " << it.key() << " in " << vm_id
                   << "is not a dictionary";
      continue;
    }

    std::string image_name;
    if (!cdrom->GetString("image", &image_name))
      continue;  // The device is not backed by an image.

    LOG(INFO) << "CDROM image: " << image_name;

    if (image_name != "/iso/install.iso" &&
        image_name != "/opt/pita/tools/tools.iso")
      continue;

    std::string state;
    if (!cdrom->GetString("state", &state) || state != "disconnected") {
      if (!DisconnectDevice(vm_id, it.key())) {
        LOG(ERROR) << "Failed to disconnect " << it.key() << " from " << vm_id;
        continue;
      }
    }

    if (image_name == "/iso/install.iso") {
      base::FilePath image_path = iso_path.Append("install.iso");
      if (base::PathExists(image_path) && !DeleteFile(image_path)) {
        LOG(WARNING) << "Failed to delete " << image_path.value();
      }
    }
  }
}

bool ToggleSharedProfile(scoped_refptr<dbus::Bus> bus,
                         dbus::ObjectProxy* dispatcher_proxy,
                         const VmId& vm_id,
                         std::vector<std::string> params,
                         std::string* failure_message) {
  if (params.size() != 1 || (params[0] != "on" && params[0] != "off")) {
    *failure_message = "Invalid setting for the shared profile option";
    return false;
  }

  bool is_shut_down;
  if (!dispatcher::IsVmShutDown(bus, dispatcher_proxy, vm_id, &is_shut_down)) {
    *failure_message = "Unable to query VM state";
    return false;
  }

  if (!is_shut_down) {
    *failure_message = "The VM is not shut down";
    return false;
  }

  std::vector<std::string> args = {
      "set",
      vm_id.name(),
      "--shared-profile",
      params[0],
  };

  if (!ExecutePvmHelper(vm_id.owner_id(), std::move(args))) {
    *failure_message = "Failed to toggle shared profile option";
    return false;
  }

  return true;
}

}  // namespace helper
}  // namespace pvm
}  // namespace concierge
}  // namespace vm_tools
