/*
 * Copyright 2018 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 <fcntl.h>
#include <sys/mount.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/un.h>
#include <unistd.h>

#include <string>
#include <vector>

#include <base/at_exit.h>
#include <base/bind.h>
#include <base/callback_helpers.h>
#include <base/files/file_enumerator.h>
#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/files/scoped_file.h>
#include <base/json/json_reader.h>
#include <base/logging.h>
#include <base/macros.h>
#include <base/process/launch.h>
#include <base/strings/string_util.h>
#include <base/sys_info.h>
#include <base/values.h>
#include <brillo/flag_helper.h>
#include <brillo/syslog_logging.h>

namespace {

constexpr char kRuntimePath[] = "/run/arc/adbd";
constexpr char kConfigFSPath[] = "/dev/config";
constexpr char kFunctionFSPath[] = "/dev/usb-ffs/adb";
constexpr char kConfigPath[] = "/etc/arc/adbd.json";

// The shifted u/gid of the shell user, used by Android's adbd.
constexpr uid_t kShellUgid = 657360;

// The blob that is sent to FunctionFS to setup the adb gadget. This works for
// newer kernels (>=3.18). This and the following blobs were created by
// https://android.googlesource.com/platform/system/core/+/master/adb/daemon/usb.cpp
constexpr const uint8_t kControlPayloadV2[] = {
    0x03, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00,
    0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
    0x01, 0x00, 0x00, 0x00, 0x09, 0x04, 0x00, 0x00, 0x02, 0xFF, 0x42, 0x01,
    0x01, 0x07, 0x05, 0x01, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x82, 0x02,
    0x40, 0x00, 0x00, 0x09, 0x04, 0x00, 0x00, 0x02, 0xFF, 0x42, 0x01, 0x01,
    0x07, 0x05, 0x01, 0x02, 0x00, 0x02, 0x00, 0x07, 0x05, 0x82, 0x02, 0x00,
    0x02, 0x00, 0x09, 0x04, 0x00, 0x00, 0x02, 0xFF, 0x42, 0x01, 0x01, 0x07,
    0x05, 0x01, 0x02, 0x00, 0x04, 0x00, 0x06, 0x30, 0x00, 0x00, 0x00, 0x00,
    0x07, 0x05, 0x82, 0x02, 0x00, 0x04, 0x00, 0x06, 0x30, 0x00, 0x00, 0x00,
    0x00, 0x01, 0x23, 0x00, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00,
    0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

// The blob that is sent to FunctionFS to setup the adb gadget. This works
// for older kernels.
constexpr const uint8_t kControlPayloadV1[] = {
    0x01, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00,
    0x00, 0x03, 0x00, 0x00, 0x00, 0x09, 0x04, 0x00, 0x00, 0x02, 0xFF,
    0x42, 0x01, 0x01, 0x07, 0x05, 0x01, 0x02, 0x40, 0x00, 0x00, 0x07,
    0x05, 0x82, 0x02, 0x40, 0x00, 0x00, 0x09, 0x04, 0x00, 0x00, 0x02,
    0xFF, 0x42, 0x01, 0x01, 0x07, 0x05, 0x01, 0x02, 0x00, 0x02, 0x00,
    0x07, 0x05, 0x82, 0x02, 0x00, 0x02, 0x00};

// The blob that is sent to FunctionFS to setup the name of the gadget. It is
// "ADB Interface".
constexpr const uint8_t kControlStrings[] = {
    0x02, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
    0x00, 0x01, 0x00, 0x00, 0x00, 0x09, 0x04, 0x41, 0x44, 0x42, 0x20,
    0x49, 0x6E, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x00};

// TODO(lhchavez): Remove once libchrome rolls and provides this method.
std::string GetStrippedReleaseBoard() {
  std::string board = base::SysInfo::GetLsbReleaseBoard();
  const size_t index = board.find("-signed-");
  if (index != std::string::npos)
    board.resize(index);

  return base::ToLowerASCII(board);
}

// Returns the name of the UDC driver that is available in the system, or an
// empty string if none are available.
std::string GetUDCDriver() {
  base::FileEnumerator udc_enum(
      base::FilePath("/sys/class/udc/"), false /* recursive */,
      base::FileEnumerator::FILES | base::FileEnumerator::SHOW_SYM_LINKS);
  const base::FilePath name = udc_enum.Next();
  if (name.empty())
    return std::string();
  // We expect to only have one UDC driver in the system, so we can just return
  // the first file in the directory.
  return name.BaseName().value();
}

// Represents a loadable kernel module. This is then converted to a modprobe(8)
// invocation.
struct AdbdConfigurationKernelModule {
  // Name of the kernel module.
  std::string name;

  // Optional parameters to the module.
  std::vector<std::string> parameters;
};

// Represents the configuration for the service.
struct AdbdConfiguration {
  // The USB product ID. Is SoC-specific.
  std::string usb_product_id;

  // Optional list of kernel modules that need to be loaded before setting up
  // the USB gadget.
  std::vector<AdbdConfigurationKernelModule> kernel_modules;
};

// Returns the USB product ID for the current device, or an empty string if the
// device does not support ADB over USB.
bool GetConfiguration(AdbdConfiguration* config) {
  std::string config_json_data;
  if (!base::ReadFileToString(base::FilePath(kConfigPath), &config_json_data)) {
    PLOG(ERROR) << "Failed to read config from " << kConfigPath;
    return false;
  }

  std::string error_msg;
  std::unique_ptr<const base::Value> config_root_val =
      base::JSONReader::ReadAndReturnError(
          config_json_data, base::JSON_PARSE_RFC, nullptr /* error_code_out */,
          &error_msg, nullptr /* error_line_out */,
          nullptr /* error_column_out */);
  if (!config_root_val) {
    LOG(ERROR) << "Failed to parse adb.json: " << error_msg;
    return false;
  }
  const base::DictionaryValue* config_root_dict = nullptr;
  if (!config_root_val->GetAsDictionary(&config_root_dict)) {
    LOG(ERROR) << "Failed to parse root dictionary from adb.json";
    return false;
  }
  if (!config_root_dict->GetString("usbProductId", &config->usb_product_id)) {
    LOG(ERROR) << "Failed to parse usbProductId";
    return false;
  }
  const base::ListValue* kernel_module_list = nullptr;
  // kernelModules are optional.
  if (config_root_dict->GetList("kernelModules", &kernel_module_list)) {
    for (const auto& kernel_module_value :
         base::ValueReferenceAdapter(*kernel_module_list)) {
      AdbdConfigurationKernelModule module;
      const base::DictionaryValue* kernel_module_dict = nullptr;
      if (!kernel_module_value.GetAsDictionary(&kernel_module_dict)) {
        LOG(ERROR) << "kernelModules contains a non-dictionary";
        return false;
      }
      if (!kernel_module_dict->GetString("name", &module.name)) {
        LOG(ERROR) << "Failed to parse kernelModules.name";
        return false;
      }
      const base::ListValue* parameter_list = nullptr;
      if (kernel_module_dict->GetList("parameters", &parameter_list)) {
        // Parameters are optional.
        for (const auto& parameter_value :
             base::ValueReferenceAdapter(*parameter_list)) {
          std::string parameter;
          if (!parameter_value.GetAsString(&parameter)) {
            LOG(ERROR) << "kernelModules.parameters contains a non-string";
            return false;
          }
          module.parameters.emplace_back(parameter);
        }
      }
      config->kernel_modules.emplace_back(module);
    }
  }

  return true;
}

// Writes a string to a file. Returns false if the full string was not able to
// be written.
bool WriteFile(const base::FilePath& filename, const std::string& contents) {
  int bytes_written =
      base::WriteFile(filename, contents.c_str(), contents.size());
  if (bytes_written == -1) {
    PLOG(ERROR) << "Failed to write '" << contents << "' to "
                << filename.value();
    return false;
  }
  if (bytes_written < contents.size()) {
    LOG(ERROR) << "Truncated write '" << contents << "' to "
               << filename.value();
    return false;
  }
  return true;
}

// Sets up all the necessary kernel modules for the device.
bool SetupKernelModules(
    const std::vector<AdbdConfigurationKernelModule>& kernel_modules) {
  for (const auto& kernel_module : kernel_modules) {
    std::vector<std::string> argv;
    argv.emplace_back("/sbin/modprobe");
    argv.emplace_back(kernel_module.name);
    argv.insert(std::end(argv), std::begin(kernel_module.parameters),
                std::end(kernel_module.parameters));
    base::Process process(base::LaunchProcess(argv, base::LaunchOptions()));
    if (!process.IsValid()) {
      PLOG(ERROR) << "Failed to invoke /sbin/modprobe " << kernel_module.name;
      return false;
    }
    int exit_code = -1;
    if (!process.WaitForExit(&exit_code)) {
      PLOG(ERROR) << "Failed to wait for /sbin/modprobe " << kernel_module.name;
      return false;
    }
    if (exit_code != 0) {
      LOG(ERROR) << "Invocation of /sbin/modprobe " << kernel_module.name
                 << " exited with non-zero code " << exit_code;
      return false;
    }
  }
  return true;
}

// Sets up the ConfigFS files to be able to use the ADB gadget. The
// |serialnumber| parameter is used to setup how the device appears in "adb
// devices". The |usb_product_id| and |usb_product_name| parameters are used so
// that the USB gadget self-reports as Android running in Chrome OS.
bool SetupConfigFS(const std::string& serialnumber,
                   const std::string& usb_product_id,
                   const std::string& usb_product_name) {
  const base::FilePath configfs_directory(kConfigFSPath);
  if (!base::CreateDirectory(configfs_directory)) {
    PLOG(ERROR) << "Failed to create " << configfs_directory.value();
    return false;
  }
  if (mount("configfs", configfs_directory.value().c_str(), "configfs",
            MS_NOEXEC | MS_NOSUID | MS_NODEV, nullptr) == -1) {
    PLOG(ERROR) << "Failed to mount configfs";
    return false;
  }

  // Setup the gadget.
  const base::FilePath gadget_path = configfs_directory.Append("usb_gadget/g1");
  if (!base::CreateDirectory(gadget_path.Append("functions/ffs.adb"))) {
    PLOG(ERROR) << "Failed to create ffs.adb directory";
    return false;
  }
  if (!base::CreateDirectory(gadget_path.Append("configs/b.1/strings/0x409"))) {
    PLOG(ERROR) << "Failed to create configs/b.1/strings directory";
    return false;
  }
  if (!base::CreateDirectory(gadget_path.Append("strings/0x409"))) {
    PLOG(ERROR) << "Failed to create config strings directory";
    return false;
  }
  const base::FilePath function_symlink_path =
      gadget_path.Append("configs/b.1/f1");
  if (!base::PathExists(function_symlink_path)) {
    if (!base::CreateSymbolicLink(gadget_path.Append("functions/ffs.adb"),
                                  function_symlink_path)) {
      PLOG(ERROR) << "Failed to create symbolic link";
      return false;
    }
  }
  if (!WriteFile(gadget_path.Append("idVendor"), "0x18d1"))
    return false;
  if (!WriteFile(gadget_path.Append("idProduct"), usb_product_id))
    return false;
  if (!WriteFile(gadget_path.Append("strings/0x409/serialnumber"),
                 serialnumber)) {
    return false;
  }
  if (!WriteFile(gadget_path.Append("strings/0x409/manufacturer"), "google"))
    return false;
  if (!WriteFile(gadget_path.Append("strings/0x409/product"), usb_product_name))
    return false;
  if (!WriteFile(gadget_path.Append("configs/b.1/MaxPower"), "500"))
    return false;

  return true;
}

// Bind-mounts a file located in |source| to |target|. It also makes it be owned
// and only writable by Android shell.
bool BindMountFile(const base::FilePath& source, const base::FilePath& target) {
  if (!base::PathExists(target)) {
    base::ScopedFD target_file(
        open(target.value().c_str(), O_WRONLY | O_CREAT, 0600));
    if (!target_file.is_valid()) {
      PLOG(ERROR) << "Failed to touch " << target.value();
      return false;
    }
  }
  if (chown(source.value().c_str(), kShellUgid, kShellUgid) == -1) {
    PLOG(ERROR) << "Failed to chown " << source.value()
                << " to Android's shell user";
    return false;
  }
  if (mount(source.value().c_str(), target.value().c_str(), nullptr, MS_BIND,
            nullptr) == -1) {
    PLOG(ERROR) << "Failed to mount " << target.value();
    return false;
  }
  return true;
}

// Sets up FunctionFS and returns an open FD to the control endpoint of the
// fully setup ADB gadget. The gadget will be torn down if the FD is closed when
// this program exits.
base::ScopedFD SetupFunctionFS(const std::string& udc_driver_name) {
  const base::FilePath functionfs_path(kFunctionFSPath);

  // Create the FunctionFS mount.
  if (!base::CreateDirectory(functionfs_path)) {
    PLOG(ERROR) << "Failed to create " << functionfs_path.value();
    return base::ScopedFD();
  }
  if (mount("adb", functionfs_path.value().c_str(), "functionfs",
            MS_NOEXEC | MS_NOSUID | MS_NODEV, nullptr) == -1) {
    PLOG(ERROR) << "Failed to mount functionfs";
    return base::ScopedFD();
  }

  // Send the configuration to the real control endpoint.
  base::ScopedFD control_file(
      open(functionfs_path.Append("ep0").value().c_str(), O_WRONLY));
  if (!control_file.is_valid()) {
    PLOG(ERROR) << "Failed to open control file";
    return base::ScopedFD();
  }
  if (!base::WriteFileDescriptor(
          control_file.get(), reinterpret_cast<const char*>(kControlPayloadV2),
          sizeof(kControlPayloadV2))) {
    PLOG(WARNING) << "Failed to write the V2 control payload, "
                     "trying to write the V1 control payload";
    if (!base::WriteFileDescriptor(
            control_file.get(),
            reinterpret_cast<const char*>(kControlPayloadV1),
            sizeof(kControlPayloadV1))) {
      PLOG(ERROR) << "Failed to write the V1 control payload";
      return base::ScopedFD();
    }
  }
  if (!base::WriteFileDescriptor(control_file.get(),
                                 reinterpret_cast<const char*>(kControlStrings),
                                 sizeof(kControlStrings))) {
    PLOG(ERROR) << "Failed to write the control strings";
    return base::ScopedFD();
  }
  if (!WriteFile(base::FilePath("/dev/config/usb_gadget/g1/UDC"),
                 udc_driver_name)) {
    return base::ScopedFD();
  }

  // Bind-mount the bulk-in/bulk-out endpoints into the shared mount.
  const base::FilePath runtime_path(kRuntimePath);
  for (const auto& endpoint : {"ep1", "ep2"}) {
    if (!BindMountFile(functionfs_path.Append(endpoint),
                       runtime_path.Append(endpoint))) {
      return base::ScopedFD();
    }
  }

  return control_file;
}

// Creates a FIFO at |path|, owned and only writable by the Android shell user.
bool CreatePipe(const base::FilePath& path) {
  // Create the FIFO at a temporary path. We will call rename(2) later to make
  // the whole operation atomic.
  const base::FilePath tmp_path = path.AddExtension(".tmp");
  if (unlink(tmp_path.value().c_str()) == -1 && errno != ENOENT) {
    PLOG(ERROR) << "Failed to remove stale FIFO at " << tmp_path.value();
    return false;
  }
  if (mkfifo(tmp_path.value().c_str(), 0600) == -1) {
    PLOG(ERROR) << "Failed to create FIFO at " << tmp_path.value();
    return false;
  }
  // base::Unretained is safe since the closure will be run before |tmp_path|
  // goes out of scope.
  base::ScopedClosureRunner unlink_fifo(base::Bind(
      base::IgnoreResult(&unlink), base::Unretained(tmp_path.value().c_str())));
  if (chown(tmp_path.value().c_str(), kShellUgid, kShellUgid) == -1) {
    PLOG(ERROR) << "Failed to chown FIFO at " << tmp_path.value()
                << " to Android's shell user";
    return false;
  }
  if (rename(tmp_path.value().c_str(), path.value().c_str()) == -1) {
    PLOG(ERROR) << "Failed to rename FIFO at " << tmp_path.value() << " to "
                << path.value();
    return false;
  }
  ignore_result(unlink_fifo.Release());
  return true;
}

}  // namespace

int main(int argc, char** argv) {
  DEFINE_string(serialnumber, "", "Serial number of the Android container");

  base::AtExitManager at_exit;

  brillo::FlagHelper::Init(argc, argv, "ADB over USB proxy.");
  brillo::InitLog(brillo::kLogToSyslog | brillo::kLogToStderrIfTty);

  const base::FilePath runtime_path(kRuntimePath);

  AdbdConfiguration config;
  if (!GetConfiguration(&config)) {
    LOG(INFO) << "Unable to find the configuration for this service. "
              << "This device does not support ADB over USB.";
    return 0;
  }

  const std::string board = GetStrippedReleaseBoard();

  const base::FilePath control_pipe_path = runtime_path.Append("ep0");
  if (!CreatePipe(control_pipe_path))
    return 1;

  char buffer[4096];

  bool configured = false;
  base::ScopedFD control_file;
  while (true) {
    LOG(INFO) << "arc-adbd ready to receive connections";
    // O_RDONLY on a FIFO waits until another endpoint has opened the file with
    // O_WRONLY or O_RDWR.
    base::ScopedFD control_pipe(
        open(control_pipe_path.value().c_str(), O_RDONLY));
    if (!control_pipe.is_valid()) {
      PLOG(ERROR) << "Failed to open FIFO at " << control_pipe_path.value();
      return 1;
    }
    LOG(INFO) << "arc-adbd connected";

    // Given that a FIFO can be opened by multiple processes, once a process has
    // opened it, we atomically replace it with a new FIFO (by using rename(2))
    // so no other process can open it. This causes that when that process
    // close(2)s the FD, we will get an EOF when we attempt to read(2) from it.
    // This also causes any other process that attempts to open the new FIFO to
    // block until we are done processing the current one.
    //
    // There is a very small chance there is a race here if multiple processes
    // get to open the FIFO between the point in time where this process opens
    // the FIFO and CreatePipe() returns. That seems unavoidable, but should not
    // present too much of a problem since exactly one process in Android has
    // the correct user to open this file in the first place (adbd).
    if (!CreatePipe(control_pipe_path))
      return 1;

    // Once adbd has opened the control pipe, we set up the adb gadget on behalf
    // of that process, if we have not already.
    if (!configured) {
      if (!SetupKernelModules(config.kernel_modules)) {
        LOG(ERROR) << "Failed to load kernel modules";
        return 1;
      }
      const std::string udc_driver_name = GetUDCDriver();
      if (udc_driver_name.empty()) {
        LOG(ERROR)
            << "Unable to find any registered UDC drivers in /sys/class/udc/. "
            << "This device does not support ADB using GadgetFS.";
        return 1;
      }
      if (!SetupConfigFS(FLAGS_serialnumber, config.usb_product_id, board)) {
        LOG(ERROR) << "Failed to configure ConfigFS";
        return 1;
      }
      control_file = SetupFunctionFS(udc_driver_name);
      if (!control_file.is_valid()) {
        LOG(ERROR) << "Failed to configure FunctionFS";
        return 1;
      }

      configured = true;
    }

    // Drain the FIFO and wait until the other side closes it.
    // The data that is sent is kControlPayloadV2 (or kControlPayloadV1)
    // followed by kControlStrings. We ignore it completely since we have
    // already sent it to the underlying FunctionFS file, and also to avoid
    // parsing it to decrease the attack surface area.
    while (true) {
      ssize_t bytes_read = read(control_pipe.get(), buffer, sizeof(buffer));
      if (bytes_read < 0)
        PLOG(ERROR) << "Failed to read from FIFO";
      if (bytes_read <= 0)
        break;
    }
  }

  return 0;
}
