/*
 * 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 "arc/adbd/adbd.h"

#include <fcntl.h>
#include <sys/mount.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/un.h>
#include <unistd.h>

#include <linux/vm_sockets.h>  // NOLINT - needs to be after sys/socket.h

#include <memory>

#include <base/bind.h>
#include <base/callback_helpers.h>
#include <base/files/file_enumerator.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/posix/eintr_wrapper.h>
#include <base/strings/string_util.h>
#include <base/system/sys_info.h>
#include <base/threading/platform_thread.h>
#include <base/time/time.h>
#include <base/values.h>

#include "arc/adbd/arcvm_sock_to_usb.h"
#include "arc/adbd/arcvm_usb_to_sock.h"

namespace adbd {
namespace {

constexpr uint16_t kAdbVsockPort = 5555;
constexpr char kRuntimePath[] = "/run/arc/adbd";
constexpr char kConfigFSPath[] = "/dev/config";
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/+/HEAD/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};

// 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(
        HANDLE_EINTR(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;
}

// Writes a string to a file. Returns false if the full string was not able to
// be written.
// TODO(crbug.com/1094927): Remove after r780000 uprev and replace usages by
// base::WriteFile.
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;
}

}  // namespace

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;
}

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;
  }

  auto config_root = base::JSONReader::ReadAndReturnValueWithError(
      config_json_data, base::JSON_PARSE_RFC);
  if (!config_root.value) {
    LOG(ERROR) << "Failed to parse adb.json: " << config_root.error_message;
    return false;
  }
  if (!config_root.value->is_dict()) {
    LOG(ERROR) << "Failed to parse root dictionary from adb.json";
    return false;
  }
  const std::string* usb_product_id =
      config_root.value->FindStringKey("usbProductId");
  if (!usb_product_id) {
    LOG(ERROR) << "Failed to parse usbProductId";
    return false;
  }
  config->usb_product_id = *usb_product_id;
  // kernelModules are optional.
  const base::Value* kernel_module_list =
      config_root.value->FindListKey("kernelModules");
  if (kernel_module_list) {
    for (const auto& kernel_module_value : kernel_module_list->GetList()) {
      AdbdConfigurationKernelModule module;
      if (!kernel_module_value.is_dict()) {
        LOG(ERROR) << "kernelModules contains a non-dictionary";
        return false;
      }
      const std::string* module_name =
          kernel_module_value.FindStringKey("name");
      if (!module_name) {
        LOG(ERROR) << "Failed to parse kernelModules.name";
        return false;
      }
      module.name = *module_name;
      const base::Value* module_parameters =
          kernel_module_value.FindListKey("parameters");
      if (module_parameters) {
        // Parameters are optional.
        for (const auto& parameter_value : module_parameters->GetList()) {
          if (!parameter_value.is_string()) {
            LOG(ERROR) << "kernelModules.parameters contains a non-string";
            return false;
          }
          module.parameters.emplace_back(parameter_value.GetString());
        }
      }
      config->kernel_modules.emplace_back(module);
    }
  }

  return true;
}

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);
}

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();
}

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;
    }
  }
  // Argument-dependent lookup puts base::WriteFile into the candidates of
  // overload resolution although this is in the adbd namespace.
  // In libchrome r780000, the variant
  // base::WriteFile(const FilePath& filename, StringPiece data) will be added
  // which causes ambiguity to calling adbd::WriteFile.
  if (!adbd::WriteFile(gadget_path.Append("idVendor"), "0x18d1"))
    return false;
  if (!adbd::WriteFile(gadget_path.Append("idProduct"), usb_product_id))
    return false;
  if (!adbd::WriteFile(gadget_path.Append("strings/0x409/serialnumber"),
                       serialnumber)) {
    return false;
  }
  if (!adbd::WriteFile(gadget_path.Append("strings/0x409/manufacturer"),
                       "google"))
    return false;
  if (!adbd::WriteFile(gadget_path.Append("strings/0x409/product"),
                       usb_product_name))
    return false;
  if (!adbd::WriteFile(gadget_path.Append("configs/b.1/MaxPower"), "500"))
    return false;

  return true;
}

bool BindMountUsbBulkEndpoints() {
  const base::FilePath functionfs_path(kFunctionFSPath);
  const base::FilePath runtime_path(kRuntimePath);

  for (const auto& endpoint : {"ep1", "ep2"}) {
    if (!BindMountFile(functionfs_path.Append(endpoint),
                       runtime_path.Append(endpoint))) {
      return false;
    }
  }
  return true;
}

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(HANDLE_EINTR(
      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();
  }

  return control_file;
}

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;
}

// Initializes vsock connection.
base::ScopedFD InitializeVSockConnection(uint32_t cid) {
  CHECK_GE(cid, adbd::kFirstGuestVmAddr);

  base::ScopedFD vsock_sock(socket(AF_VSOCK, SOCK_STREAM, 0));
  if (!vsock_sock.is_valid()) {
    PLOG(ERROR) << "Failed to create vsock socket";
    return base::ScopedFD();
  }
  struct sockaddr_vm addr_vm = {};
  addr_vm.svm_family = AF_VSOCK;
  addr_vm.svm_port = kAdbVsockPort;
  addr_vm.svm_cid = cid;
  if (HANDLE_EINTR(connect(vsock_sock.get(),
                           reinterpret_cast<const struct sockaddr*>(&addr_vm),
                           sizeof(addr_vm))) < 0) {
    PLOG(WARNING) << "Failed to connect to vsock socket";
    return base::ScopedFD();
  }
  LOG(INFO) << "Connected to ARCVM";
  return vsock_sock;
}

void StartArcVmAdbBridge(uint32_t cid) {
  constexpr base::TimeDelta kConnectInterval = base::TimeDelta::FromSeconds(15);
  constexpr int kMaxRetries = 4;

  int retries = kMaxRetries;
  auto vsock_sock = InitializeVSockConnection(cid);
  while (!vsock_sock.is_valid()) {
    if (--retries < 0) {
      LOG(ERROR) << "Too many retries; giving up";
      _exit(EXIT_FAILURE);
    }
    // This path may be taken when guest's adbd hasn't started listening to the
    // socket yet. To work around the case, retry connecting to the socket after
    // a short sleep.
    // TODO(crbug.com/1126289): Remove the retry hack.
    base::PlatformThread::Sleep(kConnectInterval);
    vsock_sock = InitializeVSockConnection(cid);
  }

  // Channel direction is from device side, instead of USB perspective.
  const base::FilePath ep_out =
      base::FilePath(adbd::kFunctionFSPath).Append("ep1");
  base::ScopedFD ep_out_fd(
      HANDLE_EINTR(open(ep_out.value().c_str(), O_RDONLY)));
  if (!ep_out_fd.is_valid()) {
    PLOG(ERROR) << "Failed to open OUT usb endpoint";
    _exit(EXIT_FAILURE);
  }
  auto sock_fd = vsock_sock.get();
  std::unique_ptr<ArcVmUsbToSock> ch_in =
      std::make_unique<ArcVmUsbToSock>(sock_fd, ep_out_fd.get());
  if (!ch_in->Start()) {
    LOG(ERROR) << "IN Channel failed to start";
    _exit(EXIT_FAILURE);
  }
  const base::FilePath ep_in =
      base::FilePath(adbd::kFunctionFSPath).Append("ep2");
  base::ScopedFD ep_in_fd(HANDLE_EINTR(open(ep_in.value().c_str(), O_WRONLY)));
  if (!ep_in_fd.is_valid()) {
    PLOG(ERROR) << "Failed to open OUT usb endpoint";
    _exit(EXIT_FAILURE);
  }
  std::unique_ptr<ArcVmSockToUsb> ch_out =
      std::make_unique<ArcVmSockToUsb>(sock_fd, ep_in_fd.get());
  if (!ch_out->Start()) {
    LOG(ERROR) << "OUT Channel failed to start";
    _exit(EXIT_FAILURE);
  }
  LOG(INFO) << "arcvm adbd USB bridge started";
  // The function will not return here because the execution is waiting
  // for threads to join but that won't happen in normal cases.
}

}  // namespace adbd
