// Copyright 2017 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 "imageloader/helper_process_proxy.h"

#include <poll.h>
#include <signal.h>
#include <sys/socket.h>

#include <utility>
#include <vector>

#include <base/posix/eintr_wrapper.h>
#include <base/process/launch.h>

#include "imageloader/component.h"
#include "imageloader/imageloader_impl.h"
#include "imageloader/ipc.pb.h"
#include "imageloader/verity_mounter.h"

namespace imageloader {

namespace {
constexpr int kPollingTimeoutSeconds = 10;
}  // namespace

void HelperProcessProxy::Start(int argc,
                               char* argv[],
                               const std::string& fd_arg) {
  int control[2];

  if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, control) != 0)
    PLOG(FATAL) << "socketpair failed";

  control_fd_.reset(control[0]);
  const int subprocess_fd = control[1];

  CHECK_GE(argc, 1);
  std::vector<std::string> child_argv;
  for (int i = 0; i < argc; i++)
    child_argv.push_back(argv[i]);

  child_argv.push_back(fd_arg + "=" + std::to_string(subprocess_fd));

  base::FileHandleMappingVector fd_mapping;
  fd_mapping.push_back({subprocess_fd, subprocess_fd});

  base::LaunchOptions options;
  options.fds_to_remap = std::move(fd_mapping);

  base::Process p = base::LaunchProcess(child_argv, options);
  CHECK(p.IsValid());
  pid_ = p.Pid();
}

std::unique_ptr<CommandResponse> HelperProcessProxy::SendCommand(
    const ImageCommand& image_command, struct msghdr* msg) {
  std::vector<char> msg_buf(image_command.ByteSizeLong());
  if (!image_command.SerializeToArray(msg_buf.data(), msg_buf.size()))
    LOG(FATAL) << "error serializing protobuf";

  struct iovec iov[1];
  iov[0].iov_base = msg_buf.data();
  iov[0].iov_len = image_command.ByteSizeLong();

  msg->msg_iov = iov;
  msg->msg_iovlen = sizeof(iov) / sizeof(iov[0]);

  if (sendmsg(control_fd_.get(), msg, 0) < 0)
    PLOG(FATAL) << "sendmsg failed";

  return WaitForResponse();
}

bool HelperProcessProxy::SendMountCommand(int fd,
                                          const std::string& path,
                                          FileSystem fs_type,
                                          const std::string& table) {
  struct msghdr msg = {0};
  char fds[CMSG_SPACE(sizeof(fd))];
  memset(fds, '\0', sizeof(fds));

  // 1. Construct message object.
  ImageCommand image_command;
  image_command.mutable_mount_command()->set_mount_path(path);
  image_command.mutable_mount_command()->set_table(table);

  // Convert the internal enum to the protobuf enum.
  switch (fs_type) {
    case FileSystem::kExt4:
      image_command.mutable_mount_command()->set_fs_type(MountCommand::EXT4);
      break;
    case FileSystem::kSquashFS:
      image_command.mutable_mount_command()->set_fs_type(MountCommand::SQUASH);
      break;
    default:
      LOG(FATAL) << "Unknown file system type passed to helper process.";
  }

  // 2. Encode the fd into message.
  msg.msg_control = fds;
  msg.msg_controllen = sizeof(fds);

  struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msg);
  cmsg->cmsg_level = SOL_SOCKET;
  cmsg->cmsg_type = SCM_RIGHTS;
  cmsg->cmsg_len = CMSG_LEN(sizeof(fd));

  // Move the file descriptor into the payload.
  memmove(CMSG_DATA(cmsg), &fd, sizeof(fd));
  msg.msg_controllen = cmsg->cmsg_len;

  // 3. Send the command.
  return SendCommand(image_command, &msg)->success();
}

bool HelperProcessProxy::SendUnmountAllCommand(
    bool dry_run,
    const std::string& rootpath,
    std::vector<std::string>* paths) {
  struct msghdr msg = {0};

  // 1. Construct message object.
  ImageCommand image_command;
  image_command.mutable_unmount_all_command()->set_dry_run(dry_run);
  image_command.mutable_unmount_all_command()->set_unmount_rootpath(rootpath);

  // 2. Send the command.
  std::unique_ptr<CommandResponse> response = SendCommand(image_command, &msg);

  // 3. Process return value.
  if (paths) {
    for (int i = 0; i < response->paths_size(); i++) {
      std::string path(response->paths(i));
      paths->push_back(path);
    }
  }
  return response->success();
}

bool HelperProcessProxy::SendUnmountCommand(const std::string& path) {
  struct msghdr msg = {0};

  // 1. Construct message object.
  ImageCommand image_command;
  image_command.mutable_unmount_command()->set_unmount_path(path);

  // 2. Send the command.
  return SendCommand(image_command, &msg)->success();
}

std::unique_ptr<CommandResponse> HelperProcessProxy::WaitForResponse() {
  struct pollfd pfd;
  pfd.fd = control_fd_.get();
  pfd.events = POLLIN;

  CHECK_LE(kDMSetupTimeoutSeconds, kPollingTimeoutSeconds);
  int rc = poll(&pfd, 1, kPollingTimeoutSeconds * 1000 /* (ms) */);
  PCHECK(rc >= 0 || errno == EINTR);

  std::unique_ptr<CommandResponse> response =
      std::make_unique<CommandResponse>();
  if (pfd.revents & POLLIN) {
    char buffer[4096];
    memset(buffer, '\0', sizeof(buffer));
    ssize_t bytes =
        HANDLE_EINTR(read(control_fd_.get(), buffer, sizeof(buffer)));
    PCHECK(bytes != -1);

    if (!response->ParseFromArray(buffer, bytes)) {
      LOG(FATAL) << "could not deserialize protobuf: " << buffer;
    }
  }

  return response;
}

}  // namespace imageloader
