// 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 "vm_tools/maitred/service_impl.h"

#include <arpa/inet.h>
#include <errno.h>
#include <fcntl.h>
#include <linux/sockios.h>
#include <net/if.h>
#include <net/route.h>
#include <netinet/in.h>
#include <stdint.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/mount.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>

#include <linux/vm_sockets.h>

#include <map>
#include <string>
#include <utility>
#include <vector>

#include <base/files/file_util.h>
#include <base/files/scoped_file.h>
#include <base/logging.h>
#include <base/posix/eintr_wrapper.h>
#include <base/posix/safe_strerror.h>
#include <base/process/launch.h>
#include <base/strings/stringprintf.h>
#include <base/strings/string_util.h>

using std::string;

namespace vm_tools {
namespace maitred {
namespace {

// Default name of the interface in the VM.
constexpr char kInterfaceName[] = "eth0";
constexpr char kLoopbackName[] = "lo";

constexpr char kHostIpPath[] = "/run/host_ip";

const std::vector<string> kDefaultNameservers = {"8.8.8.8", "8.8.4.4"};
constexpr char kResolvConfOptions[] =
    "options single-request timeout:1 attempts:5\n";
constexpr char kResolvConfPath[] = "/run/resolv.conf";
constexpr char kRunPath[] = "/run";
constexpr char kTmpResolvConfPath[] = "/run/resolv.conf.tmp";

// How long to wait before timing out on `lxd waitready`.
constexpr int kLxdWaitreadyTimeoutSeconds = 120;

// Common environment for all LXD functionality.
const std::map<string, string> kLxdEnv = {
    {"LXD_DIR", "/mnt/stateful/lxd"},
    {"LXD_CONF", "/mnt/stateful/lxd_conf"},
    {"LXD_UNPRIVILEGED_ONLY", "true"},
};

// Convert a 32-bit int in network byte order into a printable string.
string AddressToString(uint32_t address) {
  struct in_addr in = {
      .s_addr = address,
  };
  char buf[INET_ADDRSTRLEN];
  if (inet_ntop(AF_INET, &in, buf, INET_ADDRSTRLEN) == nullptr) {
    PLOG(ERROR) << "Failed to parse address " << address;
    return string("<unknown>");
  }

  return string(buf);
}

// Set a network interface's flags to be up and running. Returns 0 on success,
// or the saved errno otherwise.
int EnableInterface(int sockfd, const char* ifname) {
  struct ifreq ifr;
  int ret;
  memset(&ifr, 0, sizeof(ifr));
  strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));

  ret = HANDLE_EINTR(ioctl(sockfd, SIOCGIFFLAGS, &ifr));
  if (ret) {
    int saved_errno = errno;
    PLOG(ERROR) << "Failed to fetch flags for interface " << ifname;
    return saved_errno;
  }

  ifr.ifr_flags |= IFF_UP | IFF_RUNNING;
  ret = HANDLE_EINTR(ioctl(sockfd, SIOCSIFFLAGS, &ifr));
  if (ret) {
    int saved_errno = errno;
    PLOG(ERROR) << "Failed to set flags for interface " << ifname;
    return saved_errno;
  }

  return 0;
}

// Prints an error log with the message in |error| concatenated with the
// string representation of the current value of errno. The same error message
// will also be stored in |out_error|.
void PLogAndSaveError(const string& error, string* out_error) {
  string error_with_strerror = error + ": " + base::safe_strerror(errno);
  LOG(ERROR) << error_with_strerror;
  out_error->assign(error_with_strerror);
}

// Writes a resolv.conf with the supplied |nameservers| and |search_domains|.
// The default Chrome OS resolver options will be used. Returns true on
// success, and returns false on failure with an error message stored in
// |out_error|.
bool WriteResolvConf(const std::vector<string> nameservers,
                     const std::vector<string> search_domains,
                     string* out_error) {
  DCHECK(out_error);

  base::ScopedFD resolv_fd(
      HANDLE_EINTR(open(kRunPath, O_TMPFILE | O_WRONLY | O_CLOEXEC, 0644)));
  if (!resolv_fd.is_valid()) {
    PLogAndSaveError(
        base::StringPrintf("failed to open tmpfile in %s", kRunPath),
        out_error);
    return false;
  }

  for (auto& ns : nameservers) {
    string nameserver_line = base::StringPrintf("nameserver %s\n", ns.c_str());
    if (!base::WriteFileDescriptor(resolv_fd.get(), nameserver_line.c_str(),
                                   nameserver_line.length())) {
      PLogAndSaveError("failed to write nameserver to tmpfile", out_error);
      return false;
    }
  }

  if (!search_domains.empty()) {
    string search_domains_line = base::StringPrintf(
        "search %s\n", base::JoinString(search_domains, " ").c_str());
    if (!base::WriteFileDescriptor(resolv_fd.get(), search_domains_line.c_str(),
                                   search_domains_line.length())) {
      PLogAndSaveError("failed to write search domains to tmpfile", out_error);
      return false;
    }
  }

  if (!base::WriteFileDescriptor(resolv_fd.get(), kResolvConfOptions,
                                 strlen(kResolvConfOptions))) {
    PLogAndSaveError("failed to write resolver options to tmpfile", out_error);
    return false;
  }

  // The file has been successfully written to, so link it into place.
  // First link it to a named file with linkat(2), then atomically move it
  // into place with rename(2). linkat(2) will not overwrite the destination,
  // hence the need to do this in two steps.
  const base::FilePath source_path(
      base::StringPrintf("/proc/self/fd/%d", resolv_fd.get()));
  if (HANDLE_EINTR(linkat(AT_FDCWD, source_path.value().c_str(), AT_FDCWD,
                          kTmpResolvConfPath, AT_SYMLINK_FOLLOW)) < 0) {
    PLogAndSaveError(
        base::StringPrintf("failed to link tmpfile to %s", kTmpResolvConfPath),
        out_error);
    return false;
  }

  if (HANDLE_EINTR(rename(kTmpResolvConfPath, kResolvConfPath)) < 0) {
    PLogAndSaveError(
        base::StringPrintf("failed to rename tmpfile to %s", kResolvConfPath),
        out_error);
    return false;
  }

  return true;
}

}  // namespace

ServiceImpl::ServiceImpl(std::unique_ptr<vm_tools::maitred::Init> init)
    : init_(std::move(init)) {}

bool ServiceImpl::Init() {
  string error;

  return WriteResolvConf(kDefaultNameservers, {}, &error);
}

grpc::Status ServiceImpl::ConfigureNetwork(grpc::ServerContext* ctx,
                                           const NetworkConfigRequest* request,
                                           EmptyMessage* response) {
  static_assert(sizeof(uint32_t) == sizeof(in_addr_t),
                "in_addr_t is not the same width as uint32_t");
  LOG(INFO) << "Received network configuration request";

  const IPv4Config& ipv4_config = request->ipv4_config();
  if (ipv4_config.address() == 0) {
    return grpc::Status(grpc::INVALID_ARGUMENT, "IPv4 address cannot be 0");
  }
  if (ipv4_config.netmask() == 0) {
    return grpc::Status(grpc::INVALID_ARGUMENT, "IPv4 netmask cannot be 0");
  }
  if (ipv4_config.gateway() == 0) {
    return grpc::Status(grpc::INVALID_ARGUMENT, "IPv4 gateway cannot be 0");
  }

  base::ScopedFD fd(socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0));
  if (!fd.is_valid()) {
    int saved_errno = errno;
    PLOG(ERROR) << "Failed to create socket";
    return grpc::Status(grpc::INTERNAL, string("failed to create socket: ") +
                                            strerror(saved_errno));
  }

  // Set up the address.
  struct ifreq ifr;
  memset(&ifr, 0, sizeof(ifr));
  strncpy(ifr.ifr_name, kInterfaceName, sizeof(ifr.ifr_name));

  // Holy fuck, who designed this interface?  Did you know that ifr_addr and
  // ifr_name are actually macros?!?  For example, ifr_addr expands to
  // ifr_ifru.ifru_addr and ifr_name expands to ifr_ifrn.ifrn_name.  This is
  // because the address, the flags, the netmask, and basically everything
  // else all share the same underlying storage via a union.  "Let's just put
  // everything into one union.  Who needs type safety anyway?". smh.
  struct sockaddr_in* addr =
      reinterpret_cast<struct sockaddr_in*>(&ifr.ifr_addr);
  addr->sin_family = AF_INET;
  addr->sin_addr.s_addr = static_cast<in_addr_t>(ipv4_config.address());

  if (HANDLE_EINTR(ioctl(fd.get(), SIOCSIFADDR, &ifr)) != 0) {
    int saved_errno = errno;
    PLOG(ERROR) << "Failed to set IPv4 address for interface " << kInterfaceName
                << " to " << AddressToString(ipv4_config.address());
    return grpc::Status(grpc::INTERNAL, string("failed to set IPv4 address: ") +
                                            strerror(saved_errno));
  }

  LOG(INFO) << "Set IPv4 address for interface " << kInterfaceName << " to "
            << AddressToString(ipv4_config.address());

  // Set the netmask.
  struct sockaddr_in* netmask =
      reinterpret_cast<struct sockaddr_in*>(&ifr.ifr_netmask);
  netmask->sin_family = AF_INET;
  netmask->sin_addr.s_addr = static_cast<in_addr_t>(ipv4_config.netmask());

  if (HANDLE_EINTR(ioctl(fd.get(), SIOCSIFNETMASK, &ifr)) != 0) {
    int saved_errno = errno;
    PLOG(ERROR) << "Failed to set IPv4 netmask for interface " << kInterfaceName
                << " to " << AddressToString(ipv4_config.netmask());
    return grpc::Status(grpc::INTERNAL, string("failed to set IPv4 netmask: ") +
                                            strerror(saved_errno));
  }

  LOG(INFO) << "Set IPv4 netmask for interface " << kInterfaceName << " to "
            << AddressToString(ipv4_config.netmask());

  // Set the interface up and running.  This needs to happen before the kernel
  // will let us set the gateway.
  int ret = EnableInterface(fd.get(), kInterfaceName);
  if (ret) {
    return grpc::Status(
        grpc::INTERNAL,
        string("failed to enable network interface: ") + strerror(ret));
  }
  LOG(INFO) << "Set interface " << kInterfaceName << " up and running";

  // Bring up the loopback interface too.
  ret = EnableInterface(fd.get(), kLoopbackName);
  if (ret) {
    return grpc::Status(
        grpc::INTERNAL,
        string("failed to enable loopback interface") + strerror(ret));
  }

  // Set the gateway.
  struct rtentry route;
  memset(&route, 0, sizeof(route));

  struct sockaddr_in* gateway =
      reinterpret_cast<struct sockaddr_in*>(&route.rt_gateway);
  gateway->sin_family = AF_INET;
  gateway->sin_addr.s_addr = static_cast<in_addr_t>(ipv4_config.gateway());

  struct sockaddr_in* dst =
      reinterpret_cast<struct sockaddr_in*>(&route.rt_dst);
  dst->sin_family = AF_INET;
  dst->sin_addr.s_addr = INADDR_ANY;

  struct sockaddr_in* genmask =
      reinterpret_cast<struct sockaddr_in*>(&route.rt_genmask);
  genmask->sin_family = AF_INET;
  genmask->sin_addr.s_addr = INADDR_ANY;

  route.rt_flags = RTF_UP | RTF_GATEWAY;

  string gateway_str = AddressToString(ipv4_config.gateway());
  if (HANDLE_EINTR(ioctl(fd.get(), SIOCADDRT, &route)) != 0) {
    int saved_errno = errno;
    PLOG(ERROR) << "Failed to set default IPv4 gateway for interface "
                << kInterfaceName << " to " << gateway_str;
    return grpc::Status(grpc::INTERNAL, string("failed to set IPv4 gateway: ") +
                                            strerror(saved_errno));
  }

  LOG(INFO) << "Set default IPv4 gateway for interface " << kInterfaceName
            << " to " << gateway_str;

  // Write the host IP address to a file for LXD containers to use.
  base::FilePath host_ip_path(kHostIpPath);
  size_t gateway_str_len = gateway_str.size();
  if (base::WriteFile(host_ip_path, gateway_str.c_str(), gateway_str_len) !=
      gateway_str_len) {
    LOG(ERROR) << "Failed to write host IPv4 address to file";
    return grpc::Status(grpc::INTERNAL, "failed to write host IPv4 address");
  }

  if (!base::SetPosixFilePermissions(host_ip_path, 0644)) {
    LOG(ERROR) << "Failed to set host IPv4 address file permissions";
    return grpc::Status(grpc::INTERNAL,
                        "failed to set host IPv4 address permissions");
  }

  return grpc::Status::OK;
}

grpc::Status ServiceImpl::Shutdown(grpc::ServerContext* ctx,
                                   const EmptyMessage* request,
                                   EmptyMessage* response) {
  LOG(INFO) << "Received shutdown request";

  if (!init_) {
    return grpc::Status(grpc::FAILED_PRECONDITION, "not running as init");
  }

  init_->Shutdown();

  shutdown_cb_.Run();

  return grpc::Status::OK;
}

grpc::Status ServiceImpl::LaunchProcess(
    grpc::ServerContext* ctx,
    const vm_tools::LaunchProcessRequest* request,
    vm_tools::LaunchProcessResponse* response) {
  LOG(INFO) << "Received request to launch process";
  if (!init_) {
    return grpc::Status(grpc::FAILED_PRECONDITION, "not running as init");
  }

  if (request->argv_size() <= 0) {
    return grpc::Status(grpc::INVALID_ARGUMENT, "missing argv");
  }

  if (request->respawn() && request->wait_for_exit()) {
    return grpc::Status(grpc::INVALID_ARGUMENT,
                        "respawn and wait_for_exit cannot both be true");
  }

  std::vector<string> argv(request->argv().begin(), request->argv().end());
  std::map<string, string> env;
  for (const auto& pair : request->env()) {
    env[pair.first] = pair.second;
  }

  Init::ProcessLaunchInfo launch_info;
  if (!init_->Spawn(std::move(argv), std::move(env), request->respawn(),
                    request->use_console(), request->wait_for_exit(),
                    &launch_info)) {
    return grpc::Status(grpc::INTERNAL, "failed to spawn process");
  }

  switch (launch_info.status) {
    case Init::ProcessStatus::UNKNOWN:
      LOG(WARNING) << "Child process has unknown status";

      response->set_status(vm_tools::UNKNOWN);
      break;
    case Init::ProcessStatus::EXITED:
      LOG(INFO) << "Requested process " << request->argv()[0] << " exited with "
                << "status " << launch_info.code;

      response->set_status(vm_tools::EXITED);
      response->set_code(launch_info.code);
      break;
    case Init::ProcessStatus::SIGNALED:
      LOG(INFO) << "Requested process " << request->argv()[0] << " killed by "
                << "signal " << launch_info.code;

      response->set_status(vm_tools::SIGNALED);
      response->set_code(launch_info.code);
      break;
    case Init::ProcessStatus::LAUNCHED:
      LOG(INFO) << "Launched process " << request->argv()[0];

      response->set_status(vm_tools::LAUNCHED);
      break;
    case Init::ProcessStatus::FAILED:
      LOG(ERROR) << "Failed to launch requested process";

      response->set_status(vm_tools::FAILED);
      break;
  }

  // Return OK no matter what because the RPC itself succeeded even if there
  // was an issue with launching the process.
  return grpc::Status::OK;
}

grpc::Status ServiceImpl::Mount(grpc::ServerContext* ctx,
                                const MountRequest* request,
                                MountResponse* response) {
  LOG(INFO) << "Received mount request";
  int ret = mount(request->source().c_str(), request->target().c_str(),
                  request->fstype().c_str(), request->mountflags(),
                  request->options().c_str());

  if (ret < 0) {
    response->set_error(errno);
    PLOG(ERROR) << "Failed to mount \"" << request->source() << "\" on \""
                << request->target() << "\"";
  } else {
    response->set_error(0);
    LOG(INFO) << "Mounted \"" << request->source() << "\" on \""
              << request->target() << "\"";
  }

  return grpc::Status::OK;
}

grpc::Status ServiceImpl::StartTermina(grpc::ServerContext* ctx,
                                       const StartTerminaRequest* request,
                                       StartTerminaResponse* response) {
  LOG(INFO) << "Received StartTermina request";
  if (!init_) {
    return grpc::Status(grpc::FAILED_PRECONDITION, "not running as init");
  }

  Init::ProcessLaunchInfo launch_info;
  if (!init_->Spawn({"mkfs.btrfs", "/dev/vdb"}, kLxdEnv, false /*respawn*/,
                    false /*use_console*/, true /*wait_for_exit*/,
                    &launch_info)) {
    return grpc::Status(grpc::INTERNAL, "failed to spawn mkfs.btrfs");
  }
  if (launch_info.status != Init::ProcessStatus::EXITED) {
    return grpc::Status(grpc::INTERNAL, "mkfs.btrfs did not complete");
  }
  // mkfs.btrfs will fail if the disk is already formatted as btrfs.
  // Optimistically continue on - if the mount fails, then return an error.

  int ret = mount("/dev/vdb", "/mnt/stateful", "btrfs", 0,
                  "user_subvol_rm_allowed,discard");
  if (ret != 0) {
    int saved_errno = errno;
    PLOG(ERROR) << "Failed to mount stateful disk";
    return grpc::Status(grpc::INTERNAL, string("failed to mount stateful: ") +
                                            strerror(saved_errno));
  }

  if (!init_->Spawn({"lxd", "--group", "lxd", "--syslog"}, kLxdEnv,
                    true /*respawn*/, false /*use_console*/,
                    false /*wait_for_exit*/, &launch_info)) {
    return grpc::Status(grpc::INTERNAL, "failed to spawn lxd");
  }
  if (launch_info.status != Init::ProcessStatus::LAUNCHED) {
    return grpc::Status(grpc::INTERNAL, "lxd did not launch");
  }

  string timeout = std::to_string(kLxdWaitreadyTimeoutSeconds);
  if (!init_->Spawn({"lxd", "waitready", "--timeout", timeout}, kLxdEnv,
                    false /*respawn*/, false /*use_console*/,
                    true /*wait_for_exit*/, &launch_info)) {
    return grpc::Status(grpc::INTERNAL, "failed to spawn lxd waitready");
  }
  if (launch_info.status != Init::ProcessStatus::EXITED) {
    return grpc::Status(grpc::INTERNAL, "lxd waitready did not complete");
  } else if (launch_info.code != 0) {
    return grpc::Status(grpc::INTERNAL, "lxd waitready returned non-zero");
  }

  if (!init_->Spawn({"tremplin", "-lxd_subnet", request->lxd_ipv4_subnet()},
                    kLxdEnv, true /*respawn*/, false /*use_console*/,
                    false /*wait_for_exit*/, &launch_info)) {
    return grpc::Status(grpc::INTERNAL, "failed to spawn tremplin");
  }
  if (launch_info.status != Init::ProcessStatus::LAUNCHED) {
    return grpc::Status(grpc::INTERNAL, "tremplin did not launch");
  }

  return grpc::Status::OK;
}

grpc::Status ServiceImpl::Mount9P(grpc::ServerContext* ctx,
                                  const Mount9PRequest* request,
                                  MountResponse* response) {
  LOG(INFO) << "Received request to mount 9P file system";
  base::ScopedFD server(socket(AF_VSOCK, SOCK_STREAM | SOCK_CLOEXEC, 0));
  if (!server.is_valid()) {
    response->set_error(errno);
    PLOG(ERROR) << "Failed to create vsock socket";
    return grpc::Status(grpc::INTERNAL, "unable to create vsock socket");
  }

  struct sockaddr_vm svm = {
      .svm_family = AF_VSOCK,
      .svm_cid = VMADDR_CID_HOST,
      .svm_port = static_cast<unsigned int>(request->port()),
  };
  if (connect(server.get(), reinterpret_cast<struct sockaddr*>(&svm),
              sizeof(svm)) != 0) {
    response->set_error(errno);
    PLOG(ERROR) << "Unable to connect to server";
    return grpc::Status(grpc::INTERNAL, "unable to connect to server");
  }

  // Do the mount.
  string data = base::StringPrintf(
      "trans=fd,rfdno=%d,wfdno=%d,cache=none,access=any,version=9p2000.L",
      server.get(), server.get());
  if (mount("9p", request->target().c_str(), "9p",
            MS_NOSUID | MS_NODEV | MS_NOEXEC, data.c_str()) != 0) {
    response->set_error(errno);
    PLOG(ERROR) << "Failed to mount 9p file system";
    return grpc::Status(grpc::INTERNAL, "failed to mount file system");
  }

  LOG(INFO) << "Mounted 9P file system on " << request->target();
  return grpc::Status::OK;
}

grpc::Status ServiceImpl::SetResolvConfig(grpc::ServerContext* ctx,
                                          const SetResolvConfigRequest* request,
                                          EmptyMessage* response) {
  LOG(INFO) << "Received request to update VM resolv.conf";
  const vm_tools::ResolvConfig& resolv_config = request->resolv_config();

  std::vector<string> nameservers(resolv_config.nameservers().begin(),
                                  resolv_config.nameservers().end());
  if (nameservers.empty()) {
    LOG(WARNING) << "Host sent empty nameservers list; using default";
    nameservers = kDefaultNameservers;
  }

  std::vector<string> search_domains(resolv_config.search_domains().begin(),
                                     resolv_config.search_domains().end());
  string error;
  if (!WriteResolvConf(nameservers, search_domains, &error)) {
    return grpc::Status(grpc::INTERNAL, error);
  }

  return grpc::Status::OK;
}

grpc::Status ServiceImpl::SetTime(grpc::ServerContext* ctx,
                                  const vm_tools::SetTimeRequest* request,
                                  EmptyMessage* response) {
  struct timeval new_time;
  new_time.tv_sec = request->time().seconds();
  new_time.tv_usec = request->time().nanos() / 1000;

  LOG(INFO) << "Recieved request to set time to " << new_time.tv_sec << "s, "
            << new_time.tv_usec << "us";

  if (new_time.tv_sec == 0) {
    LOG(ERROR) << "Ignored attempt to set time to the epoch";

    return grpc::Status(grpc::INVALID_ARGUMENT,
                        "ignored attempt to set time to the epoch");
  }

  if (settimeofday(&new_time, /*tz=*/nullptr) < 0) {
    string error = strerror(errno);
    LOG(ERROR) << "Failed to set time: " << error;
    return grpc::Status(
        grpc::INTERNAL,
        base::StringPrintf("failed to set time: %s", error.c_str()));
  }

  LOG(INFO) << "Successfully set time.";
  return grpc::Status::OK;
}

}  // namespace maitred
}  // namespace vm_tools
