// Copyright 2017 The Fuchsia 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 "src/sys/appmgr/namespace_builder.h"

#include <fcntl.h>
#include <lib/fdio/directory.h>
#include <lib/fdio/fd.h>
#include <lib/fdio/fdio.h>
#include <lib/fdio/limits.h>
#include <stdlib.h>
#include <unistd.h>
#include <zircon/processargs.h>

#include <src/lib/fxl/strings/concatenate.h>

#include "src/lib/files/directory.h"
#include "src/lib/files/path.h"
#include "src/lib/files/unique_fd.h"
#include "src/lib/fsl/io/fd.h"
#include "src/sys/appmgr/allow_list.h"

namespace component {

namespace fio = ::llcpp::fuchsia::io;

constexpr char kDeprecatedDataName[] = "deprecated-data";
constexpr char kBlockedDataName[] = "data";

constexpr char kBuildInfoAllowList[] = "allowlist/build_info.txt";
constexpr char kMiscStorageAllowList[] = "allowlist/deprecated_misc_storage.txt";
constexpr char kGlobalDataAllowList[] = "allowlist/global_data.txt";

NamespaceBuilder::~NamespaceBuilder() = default;

void NamespaceBuilder::AddFlatNamespace(fuchsia::sys::FlatNamespacePtr ns) {
  if (ns && ns->paths.size() == ns->directories.size()) {
    for (size_t i = 0; i < ns->paths.size(); ++i) {
      AddDirectoryIfNotPresent(ns->paths.at(i), std::move(ns->directories.at(i)));
    }
  }
}

void NamespaceBuilder::AddPackage(zx::channel package) {
  PushDirectoryFromChannel("/pkg", std::move(package));
}

void NamespaceBuilder::AddConfigData(const SandboxMetadata& sandbox, const std::string& pkg_name) {
  for (const auto& feature : sandbox.features()) {
    if (feature == "config-data") {
      PushDirectoryFromPathAs("/pkgfs/packages/config-data/0/data/" + pkg_name, "/config/data");
    }
  }
}

void NamespaceBuilder::AddDirectoryIfNotPresent(const std::string& path, zx::channel directory) {
  if (std::find(paths_.begin(), paths_.end(), path) != paths_.end()) {
    FX_LOGS(INFO) << "Namespace conflict for " << ns_id << ": " << path;
    return;
  }
  PushDirectoryFromChannel(path, std::move(directory));
}

void NamespaceBuilder::AddServices(zx::channel services) {
  PushDirectoryFromChannel("/svc", std::move(services));
}

void NamespaceBuilder::AddHub(const HubDirectoryFactory& hub_directory_factory) {
  if (std::find(paths_.begin(), paths_.end(), "/hub") != paths_.end())
    return;
  PushDirectoryFromChannel("/hub", hub_directory_factory());
}

void NamespaceBuilder::AddSandbox(const SandboxMetadata& sandbox,
                                  const HubDirectoryFactory& hub_directory_factory) {
  AddSandbox(
      sandbox, hub_directory_factory,
      [] {
        FX_NOTREACHED() << "IsolatedDataPathFactory unexpectedly used";
        return "";
      },
      [] {
        FX_NOTREACHED() << "IsolatedCachePathFactory unexpectedly used";
        return "";
      },
      [] { return "/tmp"; });
}

void NamespaceBuilder::AddSandbox(const SandboxMetadata& sandbox,
                                  const HubDirectoryFactory& hub_directory_factory,
                                  const IsolatedDataPathFactory& isolated_data_path_factory,
                                  const IsolatedCachePathFactory& isolated_cache_path_factory,
                                  const IsolatedTempPathFactory& isolated_temp_path_factory) {
  for (const auto& path : sandbox.dev()) {
    if (path == "class") {
      FX_LOGS(WARNING) << "Ignoring request for all device classes";
      continue;
    }
    PushDirectoryFromPath("/dev/" + path);
  }

  for (const auto& path : sandbox.system()) {
    // 'deprecated-data' is the value used to access /system/data
    // to request a directory inside /system/data 'deprecated-data/some/path' is supplied
    if (path == kDeprecatedDataName ||
        path.find(fxl::Concatenate({kDeprecatedDataName, "/"})) == 0) {
      FX_LOGS(ERROR) << "Request for 'deprecated-data' by " << ns_id
                     << " ignored, this feature is no longer available";
    } else if (path == kBlockedDataName ||
               path.find(fxl::Concatenate({kBlockedDataName, "/"})) == 0) {
      FX_LOGS(ERROR) << "Request for 'data' in namespace '" << ns_id
                     << "' ignored, this feature is no longer available";
    } else {
      PushDirectoryFromPath("/system/" + path);
    }
  }

  for (const auto& path : sandbox.pkgfs())
    PushDirectoryFromPath("/pkgfs/" + path);

  // Prioritize isolated persistent storage over shell feature, if both are
  // present.
  if (sandbox.HasFeature("isolated-persistent-storage")) {
    PushDirectoryFromPathAs(isolated_data_path_factory(), "/data");
  }

  for (const auto& feature : sandbox.features()) {
    if (feature == "root-ssl-certificates") {
      PushDirectoryFromPathAs("/pkgfs/packages/root_ssl_certificates/0/data", "/config/ssl");
    } else if (feature == "deprecated-shell") {
      PushDirectoryFromPathAs("/pkgfs/packages/root_ssl_certificates/0/data", "/config/ssl");
      PushDirectoryFromPathAs("/pkgfs/packages/shell-commands/0/bin", "/bin");
      PushDirectoryFromPath("/blob");
      PushDirectoryFromPath("/boot");
      // Note that if the 'isolated-persistent-storage' feature is present,
      // this is a no-op since it has handled first above.
      // PushDirectoryFromPath does not override existing directories.
      PushDirectoryFromPath("/data");
      PushDirectoryFromPath("/dev");
      AddHub(hub_directory_factory);
      PushDirectoryFromPath("/pkgfs");
      PushDirectoryFromPath("/system");
      PushDirectoryFromPath("/tmp");
    } else if (feature == "shell-commands") {
      PushDirectoryFromPathAs("/pkgfs/packages/shell-commands/0/bin", "/bin");
    } else if (feature == "vulkan") {
      PushDirectoryFromPath("/dev/class/goldfish-address-space");
      PushDirectoryFromPath("/dev/class/goldfish-control");
      PushDirectoryFromPath("/dev/class/goldfish-pipe");
      PushDirectoryFromPath("/dev/class/gpu");
      PushDirectoryFromPathAs("/pkgfs/packages/config-data/0/data/vulkan-icd/icd.d",
                              "/config/vulkan/icd.d");
    } else if (feature == "isolated-cache-storage") {
      PushDirectoryFromPathAs(isolated_cache_path_factory(), "/cache");
    } else if (feature == "isolated-temp") {
      PushDirectoryFromPathAs(isolated_temp_path_factory(), "/tmp");
    } else if (feature == "hub") {
      AddHub(hub_directory_factory);
      // Begin allowlisted namespace features
    } else if (feature == "build-info") {
      // fxb/50308
      AllowList build_info_allowlist(appmgr_config_dir_, kBuildInfoAllowList);
      FuchsiaPkgUrl pkg_url;
      if (pkg_url.Parse(ns_id) && !build_info_allowlist.IsAllowed(pkg_url)) {
        FX_LOGS(WARNING) << "Component " << ns_id
                         << " is not allowlisted to use build-info. See fxb/50308.";
      }
      PushDirectoryFromPathAs("/pkgfs/packages/build-info/0/data", "/config/build-info");
    } else if (feature == "global-data") {
      AllowList global_data_allowlist(appmgr_config_dir_, kGlobalDataAllowList);
      FuchsiaPkgUrl pkg_url;
      if (pkg_url.Parse(ns_id) && global_data_allowlist.IsAllowed(pkg_url)) {
        PushDirectoryFromPathAsWithPermissions("/data", "/global_data",
                                               fio::OPEN_FLAG_DIRECTORY | fio::OPEN_FLAG_POSIX |
                                                   fio::OPEN_RIGHT_READABLE |
                                                   fio::OPEN_RIGHT_ADMIN);
        PushDirectoryFromPathAsWithPermissions("/tmp", "/global_tmp",
                                               fio::OPEN_FLAG_DIRECTORY | fio::OPEN_FLAG_POSIX |
                                                   fio::OPEN_RIGHT_READABLE |
                                                   fio::OPEN_RIGHT_ADMIN);
      } else {
        FX_LOGS(WARNING) << "Component " << ns_id
                         << " is not allowed to use global-data. Blocked by allowlist.";
      }
    } else if (feature == "deprecated-misc-storage") {
      AllowList misc_storage_allowlist(appmgr_config_dir_, kMiscStorageAllowList);
      FuchsiaPkgUrl pkg_url;
      if (pkg_url.Parse(ns_id) && misc_storage_allowlist.IsAllowed(pkg_url)) {
        const std::string data_dir = "/data/misc";
        if (files::CreateDirectory(data_dir)) {
          PushDirectoryFromPathAs(data_dir, "/misc");
        } else {
          FX_LOGS(ERROR) << "Failed to create deprecated-misc-storage directory";
        }
      } else {
        FX_LOGS(ERROR) << "Component " << ns_id
                       << " is not allowed to use deprecated-misc-storage. Blocked by allowlist.";
      }
    }
  }

  for (const auto& path : sandbox.boot())
    PushDirectoryFromPath("/boot/" + path);
}

void NamespaceBuilder::PushDirectoryFromPath(std::string path) {
  PushDirectoryFromPathAs(path, path);
}

void NamespaceBuilder::PushDirectoryFromPathAs(std::string src_path, std::string dst_path) {
  PushDirectoryFromPathAsWithPermissions(
      std::move(src_path), std::move(dst_path),
      fio::OPEN_FLAG_DIRECTORY | fio::OPEN_FLAG_POSIX | fio::OPEN_RIGHT_READABLE);
}

void NamespaceBuilder::PushDirectoryFromPathAsWithPermissions(std::string src_path,
                                                              std::string dst_path,
                                                              uint64_t flags) {
  if (std::find(paths_.begin(), paths_.end(), dst_path) != paths_.end()) {
    return;
  }
  fbl::unique_fd dir;
  zx_status_t status = fdio_open_fd(src_path.c_str(), flags, dir.reset_and_get_address());
  if (status != ZX_OK) {
    return;
  }
  zx::channel handle = fsl::CloneChannelFromFileDescriptor(dir.get());
  if (!handle) {
    FX_DLOGS(WARNING) << "Failed to clone channel for " << src_path;
    return;
  }
  PushDirectoryFromChannel(std::move(dst_path), std::move(handle));
}

void NamespaceBuilder::PushDirectoryFromChannel(std::string path, zx::channel channel) {
  FX_DCHECK(std::find(paths_.begin(), paths_.end(), path) == paths_.end());
  types_.push_back(PA_HND(PA_NS_DIR, types_.size()));
  handles_.push_back(channel.get());
  paths_.push_back(std::move(path));

  handle_pool_.push_back(std::move(channel));
}

fdio_flat_namespace_t* NamespaceBuilder::Build() {
  path_data_.resize(paths_.size());
  for (size_t i = 0; i < paths_.size(); ++i)
    path_data_[i] = paths_[i].c_str();

  flat_ns_.count = types_.size();
  flat_ns_.handle = handles_.data();
  flat_ns_.type = types_.data();
  flat_ns_.path = path_data_.data();
  Release();
  return &flat_ns_;
}

fuchsia::sys::FlatNamespace NamespaceBuilder::BuildForRunner() {
  fuchsia::sys::FlatNamespace flat_namespace;
  flat_namespace.paths.clear();
  flat_namespace.directories.clear();

  for (auto& path : paths_) {
    flat_namespace.paths.push_back(std::move(path));
  }

  for (auto& handle : handle_pool_) {
    flat_namespace.directories.push_back(std::move(handle));
  }
  return flat_namespace;
}

void NamespaceBuilder::Release() {
  for (auto& handle : handle_pool_)
    (void)handle.release();
  handle_pool_.clear();
}

}  // namespace component
