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

#include <libminijail.h>
#include <scoped_minijail.h>
#include <sysexits.h>

#include <string>
#include <utility>

#include <base/files/file_path.h>
#include <base/threading/thread_task_runner_handle.h>
#include <chromeos/dbus/service_constants.h>

namespace imageloader {

namespace {
constexpr char kSeccompFilterPath[] =
    "/usr/share/policy/imageloader-seccomp.policy";
}  // namespace

// static
const char ImageLoader::kImageLoaderGroupName[] = "imageloaderd";
const char ImageLoader::kImageLoaderUserName[] = "imageloaderd";
const int ImageLoader::kShutdownTimeoutMilliseconds = 20000;
const char ImageLoader::kLoadedMountsBase[] = "/run/imageloader";

ImageLoader::ImageLoader(ImageLoaderConfig config,
                         std::unique_ptr<HelperProcessProxy> proxy)
    : DBusServiceDaemon(kImageLoaderServiceName),
      impl_(std::move(config)),
      helper_process_proxy_(std::move(proxy)) {}

ImageLoader::~ImageLoader() = default;

// static
void ImageLoader::EnterSandbox() {
  ScopedMinijail jail(minijail_new());
  minijail_no_new_privs(jail.get());
  minijail_use_seccomp_filter(jail.get());
  minijail_parse_seccomp_filters(jail.get(), kSeccompFilterPath);
  minijail_reset_signal_mask(jail.get());
  minijail_namespace_ipc(jail.get());
  minijail_namespace_net(jail.get());
  minijail_remount_proc_readonly(jail.get());
  CHECK_EQ(0, minijail_change_user(jail.get(), kImageLoaderUserName));
  CHECK_EQ(0, minijail_change_group(jail.get(), kImageLoaderGroupName));
  minijail_enter(jail.get());
}

int ImageLoader::OnInit() {
  // Run with minimal privileges.
  EnterSandbox();

  int return_code = brillo::DBusServiceDaemon::OnInit();
  if (return_code != EX_OK)
    return return_code;

  process_reaper_.Register(this);
  process_reaper_.WatchForChild(
      FROM_HERE, helper_process_proxy_->pid(),
      base::Bind(&ImageLoader::OnSubprocessExited, weak_factory_.GetWeakPtr(),
                 helper_process_proxy_->pid()));

  PostponeShutdown();

  return EX_OK;
}

void ImageLoader::RegisterDBusObjectsAsync(
    brillo::dbus_utils::AsyncEventSequencer* sequencer) {
  dbus_object_.reset(new brillo::dbus_utils::DBusObject(
      nullptr, bus_,
      org::chromium::ImageLoaderInterfaceAdaptor::GetObjectPath()));
  dbus_adaptor_.RegisterWithDBusObject(dbus_object_.get());
  dbus_object_->RegisterAsync(
      sequencer->GetHandler("ImageLoader.RegisterAsync() failed.", true));
}

void ImageLoader::OnShutdown(int* return_code) {
  brillo::DBusServiceDaemon::OnShutdown(return_code);
}

void ImageLoader::OnSubprocessExited(pid_t pid, const siginfo_t& info) {
  LOG(FATAL) << "Subprocess " << pid << " exited unexpectedly.";
}

void ImageLoader::PostponeShutdown() {
  shutdown_callback_.Reset(
      base::Bind(&brillo::Daemon::Quit, base::Unretained(this)));
  base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
      FROM_HERE, shutdown_callback_.callback(),
      base::TimeDelta::FromMilliseconds(kShutdownTimeoutMilliseconds));
}

bool ImageLoader::RegisterComponent(
    brillo::ErrorPtr* err,
    const std::string& name,
    const std::string& version,
    const std::string& component_folder_abs_path,
    bool* out_success) {
  *out_success =
      impl_.RegisterComponent(name, version, component_folder_abs_path);
  PostponeShutdown();
  return true;
}

bool ImageLoader::GetComponentVersion(brillo::ErrorPtr* err,
                                      const std::string& name,
                                      std::string* out_version) {
  *out_version = impl_.GetComponentVersion(name);
  PostponeShutdown();
  return true;
}

bool ImageLoader::LoadComponent(brillo::ErrorPtr* err,
                                const std::string& name,
                                std::string* out_mount_point) {
  *out_mount_point = impl_.LoadComponent(name, helper_process_proxy_.get());
  PostponeShutdown();
  return true;
}

bool ImageLoader::LoadComponentAtPath(brillo::ErrorPtr* err,
                                      const std::string& name,
                                      const std::string& absolute_path,
                                      std::string* out_mount_point) {
  *out_mount_point = impl_.LoadComponentAtPath(
      name, base::FilePath(absolute_path), helper_process_proxy_.get());
  PostponeShutdown();
  return true;
}

bool ImageLoader::LoadDlcImage(brillo::ErrorPtr* err,
                               const std::string& id,
                               const std::string& package,
                               const std::string& a_or_b,
                               std::string* out_mount_point) {
  *out_mount_point =
      impl_.LoadDlcImage(id, package, a_or_b, helper_process_proxy_.get());
  PostponeShutdown();
  return true;
}

bool ImageLoader::RemoveComponent(brillo::ErrorPtr* err,
                                  const std::string& name,
                                  bool* out_success) {
  *out_success = impl_.RemoveComponent(name);
  PostponeShutdown();
  return true;
}

bool ImageLoader::GetComponentMetadata(
    brillo::ErrorPtr* err,
    const std::string& name,
    std::map<std::string, std::string>* out_metadata) {
  if (!impl_.GetComponentMetadata(name, out_metadata))
    out_metadata->clear();
  PostponeShutdown();
  return true;
}

bool ImageLoader::UnmountComponent(brillo::ErrorPtr* err,
                                   const std::string& name,
                                   bool* out_success) {
  base::FilePath component_mount_root =
      base::FilePath(imageloader::ImageLoader::kLoadedMountsBase).Append(name);
  *out_success = impl_.CleanupAll(false, component_mount_root, nullptr,
                                  helper_process_proxy_.get());
  PostponeShutdown();
  return true;
}

bool ImageLoader::UnloadDlcImage(brillo::ErrorPtr* err,
                                 const std::string& id,
                                 const std::string& package,
                                 bool* out_success) {
  *out_success = impl_.UnloadDlcImage(id, package, helper_process_proxy_.get());
  PostponeShutdown();
  return true;
}

}  // namespace imageloader
