// Copyright 2016 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 <signal.h>

#include <iostream>
#include <memory>
#include <sys/mount.h>

#include <base/check.h>
#include <base/check_op.h>
#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/logging.h>
#include <brillo/flag_helper.h>
#include <brillo/syslog_logging.h>
#include <brillo/userdb_utils.h>

#include "imageloader/component.h"
#include "imageloader/global_context.h"
#include "imageloader/helper_process_proxy.h"
#include "imageloader/helper_process_receiver.h"
#include "imageloader/imageloader.h"
#include "imageloader/imageloader_impl.h"

namespace {

constexpr uint8_t kProdPublicKey[] = {
    0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02,
    0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03,
    0x42, 0x00, 0x04, 0x53, 0xd9, 0x6f, 0xb1, 0x92, 0x97, 0x39, 0xa9, 0x97,
    0x18, 0xbe, 0xa7, 0x97, 0x15, 0x06, 0x27, 0x9c, 0x55, 0xa5, 0x40, 0xc1,
    0x0f, 0x98, 0xfa, 0xd8, 0x61, 0x18, 0xee, 0xcf, 0xf3, 0xbb, 0xf9, 0x6e,
    0x6d, 0xa0, 0x66, 0xd2, 0x29, 0xf0, 0x78, 0x5b, 0x7a, 0xab, 0x54, 0xca,
    0x53, 0x16, 0xb0, 0xf9, 0xc4, 0xd8, 0x1d, 0x93, 0x5b, 0x83, 0x6e, 0xa5,
    0x65, 0xe5, 0x71, 0xbc, 0x8d, 0x72, 0x02};

// The path where the components are stored on the device.
constexpr char kComponentsPath[] = "/var/lib/imageloader";
// The location of the container public key.
constexpr char kContainerPublicKeyPath[] =
    "/usr/share/misc/oci-container-key-pub.der";

bool LoadKeyFromFile(const std::string& file, std::vector<uint8_t>* key_out) {
  CHECK(key_out);

  base::FilePath key_file(file);
  std::string key_data;

  // The key should be pretty small.
  if (!ReadFileToString(key_file, &key_data)) {
    LOG(WARNING) << "Could not read key file " << key_file.value();
    return false;
  }

  key_out->clear();
  key_out->insert(key_out->begin(), key_data.begin(), key_data.end());

  return true;
}

bool Init(const std::string& loadedMountsBase) {
  const char* path = loadedMountsBase.c_str();
  if (!base::PathExists(base::FilePath(path))) {
    // Create a folder for loadedMountsBase.
    if (mkdir(path, imageloader::kComponentDirPerms) != 0) {
      PLOG(ERROR) << "Mkdir failed: " << path;
      return false;
    }
    // Mount a tmpfs at loadedMountsBase.
    if (mount("imageloader", path, "tmpfs", MS_NODEV | MS_NOSUID | MS_NOEXEC,
              "mode=0755") < 0) {
      PLOG(ERROR) << "Mount tmpfs failed: " << path;
      return false;
    }
    // Mark the mount point as shared.
    if (mount(nullptr, path, nullptr, MS_SHARED, "") < 0) {
      PLOG(ERROR) << "Mount shared failed: " << path;
      return false;
    }
  }
  return true;
}

bool CreateComponentsPath() {
  // Check if kComponentsPath does not exist or it is not a folder.
  if (!base::DirectoryExists(base::FilePath(kComponentsPath))) {
    // Remove the file at kComponentsPath.
    if (!base::DeletePathRecursively(base::FilePath(kComponentsPath))) {
      PLOG(ERROR) << "base::DeletePathRecursively failed: " << kComponentsPath;
      return false;
    }
    // Create a folder for kComponentsPath.
    if (mkdir(kComponentsPath, imageloader::kComponentDirPerms) != 0) {
      PLOG(ERROR) << "Mkdir failed: " << kComponentsPath;
      return false;
    }
    // Set ownership user/groups as imageloaderd:imageloaderd
    uid_t uid;
    gid_t gid;
    if (!brillo::userdb::GetUserInfo("imageloaderd", &uid, &gid)) {
      PLOG(ERROR) << "Can not get uid/gid.";
      return false;
    }
    if (chown(kComponentsPath, uid, gid) != 0) {
      PLOG(ERROR) << "Can not set ownership for path: " << kComponentsPath;
      return false;
    }
  }
  return true;
}

}  // namespace

int main(int argc, char** argv) {
  DEFINE_bool(init_only, false,
              "Only executes one-time setup process for imageloader.");
  DEFINE_bool(dry_run, false,
              "Changes unmount_all to print the paths which would be "
              "affected.");
  DEFINE_bool(mount, false,
              "Rather than starting a dbus daemon, verify and mount a single "
              "component and exit immediately.");
  DEFINE_string(mount_component, "",
                "Specifies the name of the component when using --mount.");
  DEFINE_string(mount_point, "",
                "Specifies the mountpoint when using either --mount or "
                "--unmount.");
  DEFINE_string(loaded_mounts_base, imageloader::ImageLoader::kLoadedMountsBase,
                "Base path where components are mounted (unless --mount_point "
                "is used).");
  DEFINE_int32(mount_helper_fd, -1,
               "Control socket for starting an ImageLoader subprocess. Used "
               "internally.");
  DEFINE_bool(unmount, false,
              "Unmounts the path specified by mount_point and exits "
              "immediately.");
  DEFINE_bool(unmount_all, false,
              "Unmounts all the mountpoints under loaded_mounts_base and exits "
              "immediately.");
  brillo::FlagHelper::Init(argc, argv, "imageloader");

  brillo::OpenLog("imageloader", true);
  brillo::InitLog(brillo::kLogToSyslog);

  if (FLAGS_mount + FLAGS_unmount + FLAGS_unmount_all > 1) {
    LOG(ERROR) << "Only one of --mount, --unmount, and --unmount_all can be "
                  "set at a time.";
    return 1;
  }

  imageloader::GlobalContext g_ctx;
  g_ctx.SetAsCurrent();

  // Create folder for component copies. This ensures that
  // imageloader's storage exists and is owned by `imageloaderd` user.
  if (!CreateComponentsPath()) {
    return 1;
  }

  // Executes the setup process.
  if (FLAGS_init_only) {
    return Init(FLAGS_loaded_mounts_base) ? 0 : 1;
  }

  // Executing this as the helper process if specified.
  if (FLAGS_mount_helper_fd >= 0) {
    CHECK_GT(FLAGS_mount_helper_fd, -1);
    base::ScopedFD fd(FLAGS_mount_helper_fd);
    imageloader::HelperProcessReceiver root_process(std::move(fd));
    return root_process.Run();
  }

  imageloader::Keys keys;
  // The order of key addition below is important.
  // 1. Prod key, used to sign components in Omaha.
  keys.push_back(std::vector<uint8_t>(std::begin(kProdPublicKey),
                                      std::end(kProdPublicKey)));
  // 2. Container key.
  std::vector<uint8_t> container_key;
  if (LoadKeyFromFile(kContainerPublicKeyPath, &container_key))
    keys.push_back(container_key);

  imageloader::ImageLoaderConfig config(keys, kComponentsPath,
                                        FLAGS_loaded_mounts_base.c_str());
  auto helper_process_proxy =
      std::make_unique<imageloader::HelperProcessProxy>();
  helper_process_proxy->Start(argc, argv, "--mount_helper_fd");

  // Load and mount the specified component and exit.
  if (FLAGS_mount) {
    // Run with minimal privilege.
    imageloader::ImageLoader::EnterSandbox();

    if (FLAGS_mount_point.empty() || FLAGS_mount_component.empty()) {
      LOG(ERROR) << "--mount_component=name and --mount_point=path must be set "
                    "with --mount";
      return 1;
    }
    // Access the ImageLoaderImpl directly to avoid needless dbus dependencies,
    // which may not be available at early boot.
    imageloader::ImageLoaderImpl loader(std::move(config));

    std::string component_version =
        loader.GetComponentVersion(FLAGS_mount_component);
    // imageloader returns "" if the component doesn't exist. In this case
    // return 0 so our crash reporting doesn't think something actually went
    // wrong.
    if (component_version.empty())
      return 0;

    if (!loader.LoadComponent(FLAGS_mount_component, FLAGS_mount_point,
                              helper_process_proxy.get())) {
      LOG(ERROR) << "Failed to verify and mount component: "
                 << FLAGS_mount_component << " at " << FLAGS_mount_point;
      return 1;
    }
    return 0;
  }

  // Unmount all component mount points and exit.
  if (FLAGS_unmount_all) {
    // Run with minimal privilege.
    imageloader::ImageLoader::EnterSandbox();

    imageloader::ImageLoaderImpl loader(std::move(config));
    std::vector<std::string> paths;
    const base::FilePath parent_dir(FLAGS_loaded_mounts_base);
    bool success = loader.CleanupAll(FLAGS_dry_run, parent_dir, &paths,
                                     helper_process_proxy.get());
    if (FLAGS_dry_run) {
      for (const auto& path : paths) {
        std::cout << path << "\n";
      }
    }
    if (!success) {
      LOG(ERROR) << "--unmount_all failed!";
      return 1;
    }
    return 0;
  }

  // Unmount a component mount point and exit.
  if (FLAGS_unmount) {
    // Run with minimal privilege.
    imageloader::ImageLoader::EnterSandbox();

    if (FLAGS_mount_point.empty()) {
      LOG(ERROR) << "--mount_point=path must be set with --unmount";
      return 1;
    }

    imageloader::ImageLoaderImpl loader(std::move(config));
    const base::FilePath path(FLAGS_mount_point);
    bool success = loader.Cleanup(path, helper_process_proxy.get());
    if (!success) {
      LOG(ERROR) << "--unmount failed!";
      return 1;
    }
    return 0;
  }

  // Run as a daemon and wait for dbus requests.
  imageloader::ImageLoader daemon(std::move(config),
                                  std::move(helper_process_proxy));
  daemon.Run();

  return 0;
}
