// 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 <errno.h>
#include <fcntl.h>
#include <grp.h>
#include <poll.h>
#include <pwd.h>
#include <signal.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>

#include <sys/ioctl.h>
#include <sys/signalfd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/wait.h>

#include <linux/vm_sockets.h>  // Needs to come after sys/socket.h

#include <algorithm>
#include <memory>
#include <string>

#include <base/at_exit.h>
#include <base/bind.h>
#include <base/callback_helpers.h>
#include <base/check_op.h>
#include <base/files/file_util.h>
#include <base/files/scoped_file.h>
#include <base/location.h>
#include <base/logging.h>
#include <base/macros.h>
#include <base/posix/eintr_wrapper.h>
#include <base/stl_util.h>
#include <base/strings/string_split.h>
#include <base/strings/stringprintf.h>
#include <brillo/asynchronous_signal_handler.h>
#include <brillo/flag_helper.h>
#include <brillo/message_loops/base_message_loop.h>
#include <brillo/syslog_logging.h>
#include <chromeos/constants/vm_tools.h>
#include <vm_protos/proto_bindings/vsh.pb.h>

#include "vm_tools/vsh/utils.h"
#include "vm_tools/vsh/vsh_forwarder.h"

using std::string;
using vm_tools::vsh::RecvMessage;
using vm_tools::vsh::SendMessage;
using vm_tools::vsh::Shutdown;
using vm_tools::vsh::VshForwarder;

int main(int argc, char** argv) {
  base::AtExitManager exit_manager;
  brillo::InitLog(brillo::kLogToSyslog | brillo::kLogToStderrIfTty);

  DEFINE_uint64(forward_to_host_port, 0, "Port to forward to on the host");
  DEFINE_bool(inherit_env, false, "Inherit the current environment variables");
  DEFINE_string(default_user, "chronos", "Default login user");
  DEFINE_bool(allow_to_switch_user, true,
              "Allow to switch to another user on login");

  brillo::FlagHelper::Init(argc, argv, "vsh daemon");
  base::CommandLine* cl = base::CommandLine::ForCurrentProcess();
  if (cl->GetArgs().size() > 0) {
    LOG(ERROR) << "Unknown extra command line arguments; exiting";
    return EXIT_FAILURE;
  }

  if (FLAGS_forward_to_host_port != 0) {
    uint32_t port = static_cast<uint32_t>(FLAGS_forward_to_host_port);
    if (port != FLAGS_forward_to_host_port) {
      LOG(ERROR) << "Port " << FLAGS_forward_to_host_port
                 << " is not a valid port";
      return EXIT_FAILURE;
    }

    base::ScopedFD sock_fd(socket(AF_VSOCK, SOCK_STREAM | SOCK_CLOEXEC, 0));
    if (!sock_fd.is_valid()) {
      PLOG(ERROR) << "Failed to open vsock socket";
      return EXIT_FAILURE;
    }

    struct sockaddr_vm addr;
    memset(&addr, 0, sizeof(addr));
    addr.svm_family = AF_VSOCK;
    addr.svm_port = port;
    addr.svm_cid = 2;

    if (HANDLE_EINTR(connect(sock_fd.get(),
                             reinterpret_cast<struct sockaddr*>(&addr),
                             sizeof(addr))) < 0) {
      PLOG(ERROR) << "Failed to connect to vsh client";
      return EXIT_FAILURE;
    }

    // Set up and start the message loop.
    brillo::BaseMessageLoop message_loop;
    message_loop.SetAsCurrent();
    auto forwarder = VshForwarder::Create(std::move(sock_fd), FLAGS_inherit_env,
                                          std::move(FLAGS_default_user),
                                          FLAGS_allow_to_switch_user);

    if (!forwarder) {
      return EXIT_FAILURE;
    }

    message_loop.Run();
    return EXIT_SUCCESS;
  }

  // Create a socket to listen for incoming vsh connections.
  base::ScopedFD sock_fd(socket(AF_VSOCK, SOCK_STREAM | SOCK_CLOEXEC, 0));
  if (!sock_fd.is_valid()) {
    PLOG(ERROR) << "Failed to create socket";
    return EXIT_FAILURE;
  }

  struct sockaddr_vm addr;
  memset(&addr, 0, sizeof(addr));
  addr.svm_family = AF_VSOCK;
  addr.svm_port = vm_tools::kVshPort;
  addr.svm_cid = VMADDR_CID_ANY;

  if (bind(sock_fd.get(), reinterpret_cast<const struct sockaddr*>(&addr),
           sizeof(addr)) < 0) {
    PLOG(ERROR) << "Failed to bind vshd port";
    return EXIT_FAILURE;
  }

  // Allow a backlog of up to 32 connections. This is exceedingly generous since
  // this daemon forks after accepting a connection.
  if (listen(sock_fd.get(), 32) < 0) {
    PLOG(ERROR) << "Failed to listen";
    return EXIT_FAILURE;
  }

  // Block SIGCHLD and set up a signalfd so the main daemon can reap its
  // children.
  sigset_t sigchld_mask, saved_mask;
  int result = sigemptyset(&sigchld_mask);
  DCHECK_EQ(result, 0);
  result = sigaddset(&sigchld_mask, SIGCHLD);
  DCHECK_EQ(result, 0);
  if (sigprocmask(SIG_BLOCK, &sigchld_mask, &saved_mask) < 0) {
    PLOG(ERROR) << "Failed to block SIGCHLD";
    return EXIT_FAILURE;
  }

  base::ScopedFD signal_fd(
      signalfd(-1, &sigchld_mask, SFD_NONBLOCK | SFD_CLOEXEC));
  if (!signal_fd.is_valid()) {
    PLOG(ERROR) << "Failed to set up signalfd";
    return EXIT_FAILURE;
  }

  struct pollfd pollfds[] = {
      {signal_fd.get(), POLLIN, 0},
      {sock_fd.get(), POLLIN, 0},
  };
  const int num_pollfds = base::size(pollfds);

  while (true) {
    if (poll(pollfds, num_pollfds, -1) < 0) {
      PLOG(ERROR) << "Failed to poll";
      return EXIT_FAILURE;
    }

    for (int i = 0; i < num_pollfds; i++) {
      if (!(pollfds[i].revents & POLLIN))
        continue;

      if (i == 0) {
        // signalfd.
        struct signalfd_siginfo siginfo;
        if (read(signal_fd.get(), &siginfo, sizeof(siginfo)) !=
            sizeof(siginfo)) {
          PLOG(ERROR) << "Failed to read entire signalfd siginfo";
          continue;
        }
        DCHECK_EQ(siginfo.ssi_signo, SIGCHLD);

        // Reap any child exit statuses.
        while (waitpid(-1, nullptr, WNOHANG) > 0)
          continue;
      } else if (i == 1) {
        // sock_fd.
        struct sockaddr_vm peer_addr;
        socklen_t addr_size = sizeof(peer_addr);
        base::ScopedFD peer_sock_fd(HANDLE_EINTR(accept4(
            sock_fd.get(), reinterpret_cast<struct sockaddr*>(&peer_addr),
            &addr_size, SOCK_CLOEXEC)));
        if (!peer_sock_fd.is_valid()) {
          PLOG(ERROR) << "Failed to accept connection from client";
          continue;
        }

        int pid = fork();

        if (pid == 0) {
          // The child needs to restore the original signal mask, and close
          // the listening sock_fd and signalfd manually. These fds will be
          // closed automatically on exec() anyway, but it's better not to allow
          // the unprivileged forwarder to have access to either of these.
          if (sigprocmask(SIG_SETMASK, &saved_mask, nullptr) < 0) {
            PLOG(ERROR) << "Failed to restore signal mask after fork";
          }
          sock_fd.reset();
          signal_fd.reset();
          // Set up and start the message loop.
          brillo::BaseMessageLoop message_loop;
          message_loop.SetAsCurrent();
          auto forwarder = VshForwarder::Create(
              std::move(peer_sock_fd), FLAGS_inherit_env,
              std::move(FLAGS_default_user), FLAGS_allow_to_switch_user);

          if (!forwarder) {
            return EXIT_FAILURE;
          }

          message_loop.Run();
          return EXIT_SUCCESS;
        }
      }
    }
  }

  return EXIT_SUCCESS;
}
