// Copyright 2020 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/syslog/guest_collector.h"

#include <fcntl.h>
#include <signal.h>
#include <stdint.h>
#include <string.h>
#include <sys/signalfd.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/sysinfo.h>
#include <sys/un.h>

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

#include <memory>
#include <string>
#include <utility>

#include <base/bind.h>
#include <base/bind_helpers.h>
#include <base/callback.h>
#include <base/location.h>
#include <base/logging.h>
#include <base/memory/ptr_util.h>
#include <base/posix/eintr_wrapper.h>
#include <base/strings/string_number_conversions.h>
#include <base/strings/string_piece.h>
#include <base/strings/stringprintf.h>
#include <base/threading/thread_task_runner_handle.h>
#include <base/time/time.h>
#include <chromeos/scoped_minijail.h>
#include <grpcpp/grpcpp.h>

#include "vm_tools/syslog/parser.h"

namespace pb = google::protobuf;

namespace vm_tools {
namespace syslog {

namespace {
// Path to the standard syslog listening path.
constexpr char kDevLog[] = "/dev/log";

// Known host port for the LogCollector service.
constexpr unsigned int kLogCollectorPort = 9999;

// Path to the standard empty directory where we will jail the daemon.
constexpr char kPivotRoot[] = "/mnt/empty";

// Name for the "syslog" user and group.
constexpr char kSyslog[] = "syslog";
}  // namespace

std::unique_ptr<GuestCollector> GuestCollector::Create(
    base::Closure shutdown_closure) {
  auto collector = base::WrapUnique<GuestCollector>(
      new GuestCollector(std::move(shutdown_closure)));

  if (!collector->Init()) {
    collector.reset();
  }
  return collector;
}

GuestCollector::GuestCollector(base::Closure shutdown_closure)
    : shutdown_closure_(std::move(shutdown_closure)), weak_factory_(this) {}

GuestCollector::~GuestCollector() {
  FlushLogs();
}

bool GuestCollector::Init() {
  if (!BindLogSocket(base::FilePath(kDevLog))) {
    return false;
  }
  if (!StartWatcher(kFlushPeriod)) {
    return false;
  }

  // Start listening for SIGTERM.
  sigset_t mask;
  sigemptyset(&mask);
  sigaddset(&mask, SIGTERM);

  signal_fd_.reset(signalfd(-1, &mask, SFD_CLOEXEC | SFD_NONBLOCK));
  if (!signal_fd_.is_valid()) {
    PLOG(ERROR) << "Unable to create signalfd";
    return false;
  }
  signal_controller_ = base::FileDescriptorWatcher::WatchReadable(
      signal_fd_.get(), base::BindRepeating(&GuestCollector::OnSignalReadable,
                                            base::Unretained(this)));
  if (!signal_controller_) {
    LOG(ERROR) << "Failed to watch signal file descriptor";
    return false;
  }

  // Block the standard SIGTERM handler since we will be getting it via the
  // signalfd.
  sigprocmask(SIG_BLOCK, &mask, nullptr);

  // Create the stub to the LogCollector service on the host.
  stub_ = vm_tools::LogCollector::NewStub(grpc::CreateChannel(
      base::StringPrintf("vsock:%u:%u", VMADDR_CID_HOST, kLogCollectorPort),
      grpc::InsecureChannelCredentials()));
  if (!stub_) {
    LOG(ERROR) << "Failed to create stub for LogCollector service";
    return false;
  }

  return EnterJail();
}

void GuestCollector::OnSignalReadable() {
  signalfd_siginfo info;
  if (read(signal_fd_.get(), &info, sizeof(info)) != sizeof(info)) {
    PLOG(ERROR) << "Failed to read from signalfd";
  }
  DCHECK_EQ(info.ssi_signo, SIGTERM);

  base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, shutdown_closure_);
}

bool GuestCollector::SendUserLogs() {
  vm_tools::EmptyMessage response;
  grpc::Status status;

  grpc::ClientContext ctx;
  status = stub_->CollectUserLogs(&ctx, syslog_request(), &response);

  if (!status.ok()) {
    LOG(ERROR) << "Failed to send user logs to LogCollector service.  Error "
               << "code " << status.error_code() << ": "
               << status.error_message();
    return false;
  }
  return true;
}

bool GuestCollector::EnterJail() {
  // Drop all unnecessary privileges.
  ScopedMinijail jail(minijail_new());
  if (!jail) {
    PLOG(ERROR) << "Failed to create minijail";
    return false;
  }

  minijail_change_user(jail.get(), kSyslog);
  minijail_change_group(jail.get(), kSyslog);
  minijail_no_new_privs(jail.get());

  // Pivot into an empty directory where we have no permissions.
  minijail_namespace_vfs(jail.get());
  minijail_enter_pivot_root(jail.get(), kPivotRoot);

  minijail_enter(jail.get());

  // Everything succeeded.
  return true;
}

std::unique_ptr<GuestCollector> GuestCollector::CreateForTesting(
    base::ScopedFD syslog_fd,
    std::unique_ptr<vm_tools::LogCollector::Stub> stub) {
  CHECK(stub);
  auto collector =
      base::WrapUnique<GuestCollector>(new GuestCollector(base::Closure()));

  if (!collector->InitForTesting(std::move(syslog_fd), std::move(stub))) {
    collector.reset();
  }

  return collector;
}

bool GuestCollector::InitForTesting(
    base::ScopedFD syslog_fd,
    std::unique_ptr<vm_tools::LogCollector::Stub> stub) {
  // Store the stub for the LogCollector.
  stub_ = std::move(stub);
  SetSyslogFDForTesting(std::move(syslog_fd));
  // Start listening on the syslog socket.
  return StartWatcher(kFlushPeriodForTesting);
}

}  // namespace syslog
}  // namespace vm_tools
