// 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/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_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";
}

namespace permission_broker {

#if USE_CONTAINERS
class JailRequestHandler : public device_jail::DeviceJailServer::Delegate {
 public:
  explicit JailRequestHandler(RuleEngine* rule_engine)
    : rule_engine_(rule_engine) {}

  jail_request_result HandleRequest(const std::string& path) override {
    switch (rule_engine_->ProcessPath(path)) {
    case Rule::ALLOW:
      return JAIL_REQUEST_ALLOW;
    case Rule::ALLOW_WITH_LOCKDOWN:
      return JAIL_REQUEST_ALLOW_WITH_LOCKDOWN;
    case Rule::ALLOW_WITH_DETACH:
      return JAIL_REQUEST_ALLOW_WITH_DETACH;
    default:
      LOG(WARNING) << "Unknown rule engine response";
      // fallthrough
    case Rule::DENY:
      return JAIL_REQUEST_DENY;
    }
  }

 private:
  RuleEngine* rule_engine_;  // weak
};
#endif  // USE_CONTAINERS

PermissionBroker::PermissionBroker(scoped_refptr<dbus::Bus> bus,
                                   const std::string& access_group_name,
                                   const std::string& udev_run_path,
                                   int poll_interval_msecs)
    : org::chromium::PermissionBrokerAdaptor(this),
      rule_engine_(udev_run_path, poll_interval_msecs),
      dbus_object_(nullptr, bus,
                   dbus::ObjectPath(kPermissionBrokerServicePath)),
      port_tracker_(&firewall_),
      usb_control_(std::make_unique<UsbDeviceManager>()) {
  CHECK(brillo::userdb::GetGroupInfo(access_group_name, &access_group_))
      << "You must specify a group name via the --access_group flag.";
  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 DenyUsbDeviceClassRule(USB_CLASS_MASS_STORAGE));
  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());

#if USE_CONTAINERS
  // Try to serve device_jail requests. If we can't, it's not a huge deal.
  jail_server_ = device_jail::DeviceJailServer::CreateAndListen(
      std::make_unique<JailRequestHandler>(&rule_engine_),
      base::MessageLoopForIO::current());
  if (!jail_server_)
    LOG(WARNING) << "Jail server failed to start";
#else
  DLOG(INFO) << "Device jail support is turned off";
#endif
}

PermissionBroker::~PermissionBroker() {}

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::RequestPathAccess(const std::string& in_path,
                                         int32_t in_interface_id) {
  if (rule_engine_.ProcessPath(in_path) == Rule::ALLOW) {
    return GrantAccess(in_path);
  }
  return false;
}

bool PermissionBroker::OpenPath(brillo::ErrorPtr* error,
                                const std::string& in_path,
                                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;
  }

  uint32_t mask = -1U;
  if (rule_result == Rule::ALLOW_WITH_LOCKDOWN) {
    if (ioctl(fd.get(), USBDEVFS_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;
    }
  }

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

  *out_fd = fd.get();
  return true;
}

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::RequestVpnSetup(
    const std::vector<std::string>& usernames,
    const std::string& interface,
    const base::ScopedFD& in_lifeline_fd) {
  return port_tracker_.PerformVpnSetup(usernames, interface,
                                       in_lifeline_fd.get());
}

bool PermissionBroker::RemoveVpnSetup() {
  return port_tracker_.RemoveVpnSetup();
}

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::GrantAccess(const std::string& path) {
  if (chown(path.c_str(), -1, access_group_)) {
    PLOG(INFO) << "Could not grant access to " << path;
    return false;
  }
  return true;
}

}  // namespace permission_broker
