// Copyright (c) 2012 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 "permission_broker/permission_broker.h"

#include <fcntl.h>
#include <linux/usb/ch9.h>
#include <linux/usbdevice_fs.h>
#include <sys/epoll.h>
#include <sys/ioctl.h>
#include <unistd.h>

#include <memory>
#include <string>
#include <utility>
#include <vector>

#include <base/bind.h>
#include <base/callback.h>
#include <base/compiler_specific.h>
#include <base/logging.h>
#include <base/posix/eintr_wrapper.h>
#include <brillo/userdb_utils.h>
#include <chromeos/dbus/service_constants.h>

#include "permission_broker/allow_group_tty_device_rule.h"
#include "permission_broker/allow_hidraw_device_rule.h"
#include "permission_broker/allow_tty_device_rule.h"
#include "permission_broker/allow_usb_device_rule.h"
#include "permission_broker/deny_claimed_hidraw_device_rule.h"
#include "permission_broker/deny_claimed_usb_device_rule.h"
#include "permission_broker/deny_fwupdate_hidraw_device_rule.h"
#include "permission_broker/deny_group_tty_device_rule.h"
#include "permission_broker/deny_uninitialized_device_rule.h"
#include "permission_broker/deny_unsafe_hidraw_device_rule.h"
#include "permission_broker/deny_usb_device_class_rule.h"
#include "permission_broker/deny_usb_vendor_id_rule.h"
#include "permission_broker/libusb_wrapper.h"
#include "permission_broker/rule.h"
#include "permission_broker/usb_control.h"

using permission_broker::AllowGroupTtyDeviceRule;
using permission_broker::AllowHidrawDeviceRule;
using permission_broker::AllowTtyDeviceRule;
using permission_broker::AllowUsbDeviceRule;
using permission_broker::DenyClaimedHidrawDeviceRule;
using permission_broker::DenyClaimedUsbDeviceRule;
using permission_broker::DenyGroupTtyDeviceRule;
using permission_broker::DenyUninitializedDeviceRule;
using permission_broker::DenyUnsafeHidrawDeviceRule;
using permission_broker::DenyUsbDeviceClassRule;
using permission_broker::DenyUsbVendorIdRule;
using permission_broker::PermissionBroker;

namespace {
const uint16_t kLinuxFoundationUsbVendorId = 0x1d6b;

const char kErrorDomainPermissionBroker[] = "permission_broker";
const char kPermissionDeniedError[] = "permission_denied";
const char kOpenFailedError[] = "open_failed";

constexpr uint32_t kAllInterfacesMask = ~0U;
}  // namespace

namespace permission_broker {

PermissionBroker::PermissionBroker(scoped_refptr<dbus::Bus> bus,
                                   const std::string& udev_run_path,
                                   const base::TimeDelta& poll_interval)
    : org::chromium::PermissionBrokerAdaptor(this),
      rule_engine_(udev_run_path, poll_interval),
      dbus_object_(
          nullptr, bus, dbus::ObjectPath(kPermissionBrokerServicePath)),
      port_tracker_(),
      usb_control_(std::make_unique<UsbDeviceManager>()) {
  rule_engine_.AddRule(new AllowUsbDeviceRule());
  rule_engine_.AddRule(new AllowTtyDeviceRule());
  rule_engine_.AddRule(new DenyClaimedUsbDeviceRule());
  rule_engine_.AddRule(new DenyUninitializedDeviceRule());
  rule_engine_.AddRule(new DenyUsbDeviceClassRule(USB_CLASS_HUB));
  rule_engine_.AddRule(new DenyUsbVendorIdRule(kLinuxFoundationUsbVendorId));
  rule_engine_.AddRule(new AllowHidrawDeviceRule());
  rule_engine_.AddRule(new AllowGroupTtyDeviceRule("serial"));
  rule_engine_.AddRule(new DenyGroupTtyDeviceRule("modem"));
  rule_engine_.AddRule(new DenyGroupTtyDeviceRule("tty"));
  rule_engine_.AddRule(new DenyGroupTtyDeviceRule("uucp"));
  rule_engine_.AddRule(new DenyClaimedHidrawDeviceRule());
  rule_engine_.AddRule(new DenyUnsafeHidrawDeviceRule());
  rule_engine_.AddRule(new DenyFwUpdateHidrawDeviceRule());
}

PermissionBroker::~PermissionBroker() = default;

void PermissionBroker::RegisterAsync(
    const brillo::dbus_utils::AsyncEventSequencer::CompletionAction& cb) {
  RegisterWithDBusObject(&dbus_object_);
  dbus_object_.RegisterAsync(cb);
}

bool PermissionBroker::CheckPathAccess(const std::string& in_path) {
  Rule::Result result = rule_engine_.ProcessPath(in_path);
  return result == Rule::ALLOW || result == Rule::ALLOW_WITH_LOCKDOWN ||
         result == Rule::ALLOW_WITH_DETACH;
}

bool PermissionBroker::OpenPath(brillo::ErrorPtr* error,
                                const std::string& in_path,
                                brillo::dbus_utils::FileDescriptor* out_fd) {
  VLOG(1) << "Received OpenPath request";
  return OpenPathImpl(error, in_path, kAllInterfacesMask, kInvalidLifelineFD,
                      out_fd);
}

bool PermissionBroker::ClaimDevicePath(
    brillo::ErrorPtr* error,
    const std::string& in_path,
    uint32_t drop_privileges_mask,
    const base::ScopedFD& in_lifeline_fd,
    brillo::dbus_utils::FileDescriptor* out_fd) {
  VLOG(1) << "Received ClaimDevicePath request";
  return OpenPathImpl(error, in_path, drop_privileges_mask,
                      in_lifeline_fd.get(), out_fd);
}

bool PermissionBroker::RequestLoopbackTcpPortLockdown(
    uint16_t in_port, const base::ScopedFD& in_lifeline_fd) {
  return port_tracker_.LockDownLoopbackTcpPort(in_port, in_lifeline_fd.get());
}

bool PermissionBroker::RequestTcpPortAccess(
    uint16_t in_port,
    const std::string& in_interface,
    const base::ScopedFD& in_lifeline_fd) {
  return port_tracker_.AllowTcpPortAccess(in_port, in_interface,
                                          in_lifeline_fd.get());
}

bool PermissionBroker::RequestUdpPortAccess(
    uint16_t in_port,
    const std::string& in_interface,
    const base::ScopedFD& in_lifeline_fd) {
  return port_tracker_.AllowUdpPortAccess(in_port, in_interface,
                                          in_lifeline_fd.get());
}

bool PermissionBroker::ReleaseTcpPort(uint16_t in_port,
                                      const std::string& in_interface) {
  return port_tracker_.RevokeTcpPortAccess(in_port, in_interface);
}

bool PermissionBroker::ReleaseUdpPort(uint16_t in_port,
                                      const std::string& in_interface) {
  return port_tracker_.RevokeUdpPortAccess(in_port, in_interface);
}

bool PermissionBroker::ReleaseLoopbackTcpPort(uint16_t in_port) {
  return port_tracker_.ReleaseLoopbackTcpPort(in_port);
}

bool PermissionBroker::RequestTcpPortForward(uint16_t in_port,
                                             const std::string& in_interface,
                                             const std::string& dst_ip,
                                             uint16_t dst_port,
                                             const base::ScopedFD& dbus_fd) {
  return port_tracker_.StartTcpPortForwarding(in_port, in_interface, dst_ip,
                                              dst_port, dbus_fd.get());
}

bool PermissionBroker::RequestUdpPortForward(uint16_t in_port,
                                             const std::string& in_interface,
                                             const std::string& dst_ip,
                                             uint16_t dst_port,
                                             const base::ScopedFD& dbus_fd) {
  return port_tracker_.StartUdpPortForwarding(in_port, in_interface, dst_ip,
                                              dst_port, dbus_fd.get());
}

bool PermissionBroker::ReleaseTcpPortForward(uint16_t in_port,
                                             const std::string& in_interface) {
  return port_tracker_.StopTcpPortForwarding(in_port, in_interface);
}

bool PermissionBroker::ReleaseUdpPortForward(uint16_t in_port,
                                             const std::string& in_interface) {
  return port_tracker_.StopUdpPortForwarding(in_port, in_interface);
}

void PowerCycleUsbPortsResultCallback(
    std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<bool>> response,
    bool result) {
  response->Return(result);
}

void PermissionBroker::PowerCycleUsbPorts(
    std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<bool>> response,
    uint16_t in_vid,
    uint16_t in_pid,
    int64_t in_delay) {
  usb_control_.PowerCycleUsbPorts(base::Bind(&PowerCycleUsbPortsResultCallback,
                                             base::Passed(std::move(response))),
                                  in_vid, in_pid,
                                  base::TimeDelta::FromInternalValue(in_delay));
}

bool PermissionBroker::OpenPathImpl(
    brillo::ErrorPtr* error,
    const std::string& in_path,
    uint32_t drop_privileges_mask,
    int lifeline_fd,
    brillo::dbus_utils::FileDescriptor* out_fd) {
  Rule::Result rule_result = rule_engine_.ProcessPath(in_path);
  if (rule_result != Rule::ALLOW && rule_result != Rule::ALLOW_WITH_LOCKDOWN &&
      rule_result != Rule::ALLOW_WITH_DETACH) {
    brillo::Error::AddToPrintf(
        error, FROM_HERE, kErrorDomainPermissionBroker, kPermissionDeniedError,
        "Permission to open '%s' denied", in_path.c_str());
    return false;
  }

  base::ScopedFD fd(HANDLE_EINTR(open(in_path.c_str(), O_RDWR)));
  if (!fd.is_valid()) {
    brillo::errors::system::AddSystemError(error, FROM_HERE, errno);
    brillo::Error::AddToPrintf(error, FROM_HERE, kErrorDomainPermissionBroker,
                               kOpenFailedError, "Failed to open path '%s'",
                               in_path.c_str());
    return false;
  }

  if (rule_result == Rule::ALLOW_WITH_DETACH) {
    if (!usb_driver_tracker_.DetachPathFromKernel(fd.get(), lifeline_fd,
                                                  in_path))
      return false;
  }

  // When the rule result is ALLOW_WITH_LOCKDOWN and the mask is
  // |kAllInterfacesMask| (allowing all interfaces), we still call the
  // USBDEVFS_DROP_PRIVILEGES ioctl.
  // This prevents the use of the USBDEVFS_DISCONNECT ioctl as well as
  // USBDEVFS_SETCONFIGURATION and USBDEVFS_RESET when these could be used to
  // detach a kernel driver by changing the device configuration. That's the
  // "drop privileges" part.
  if (rule_result == Rule::ALLOW_WITH_LOCKDOWN ||
      drop_privileges_mask != kAllInterfacesMask) {
    if (ioctl(fd.get(), USBDEVFS_DROP_PRIVILEGES, &drop_privileges_mask) < 0) {
      brillo::errors::system::AddSystemError(error, FROM_HERE, errno);
      brillo::Error::AddToPrintf(
          error, FROM_HERE, kErrorDomainPermissionBroker, kOpenFailedError,
          "USBDEVFS_DROP_PRIVILEGES ioctl failed on '%s'", in_path.c_str());
      return false;
    }
  }

  *out_fd = std::move(fd);
  return true;
}

}  // namespace permission_broker
