// 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 <dbus/dbus-glib.h>
#include <dbus/dbus-glib-lowlevel.h>
#include <gflags/gflags.h>
#include <glib.h>
#include <grp.h>
#include <libudev.h>
#include <poll.h>
#include <stdint.h>
#include <sys/inotify.h>
#include <sys/types.h>
#include <unistd.h>

#include <string>
#include <vector>

#include "base/logging.h"
#include "base/stl_util.h"
#include "base/strings/stringprintf.h"
#include "chromeos/dbus/dbus.h"
#include "chromeos/dbus/service_constants.h"
#include "permission_broker/rule.h"

DEFINE_string(access_group, "", "The group which has resource access granted "
              "to it. Must not be empty.");
DEFINE_int32(poll_interval, 100, "The interval at which to poll for udev "
             "events");

using std::string;
using std::vector;

namespace permission_broker {

PermissionBroker::PermissionBroker(const gid_t access_group)
    : udev_(udev_new()), access_group_(access_group) {}

PermissionBroker::PermissionBroker() : udev_(udev_new()) {
  CHECK(udev_) << "Could not create udev context, is sysfs mounted?";
  CHECK(!FLAGS_access_group.empty()) << "You must specify a group name via the "
                                     << "--access_group flag.";

  struct group *access_group = getgrnam(FLAGS_access_group.c_str());
  CHECK(access_group) << "Could not resolve \"" << FLAGS_access_group << "\" "
                      << "to a named group.";
  access_group_ = access_group->gr_gid;
}

PermissionBroker::~PermissionBroker() {
  STLDeleteContainerPointers(rules_.begin(), rules_.end());
  udev_unref(udev_);
}

void PermissionBroker::Run() {
  DBusConnection *const connection = dbus_g_connection_get_connection(
      chromeos::dbus::GetSystemBusConnection().g_connection());
  CHECK(connection) << "Cannot connect to system bus";

  DBusError error;
  dbus_error_init(&error);
  dbus_bus_request_name(connection,
      permission_broker::kPermissionBrokerServiceName, 0, &error);
  if (dbus_error_is_set(&error)) {
    LOG(FATAL) << "Failed to register "
               << permission_broker::kPermissionBrokerServiceName
               << ": " << error.message;
    dbus_error_free(&error);
    return;
  }

  DBusObjectPathVTable vtable;
  memset(&vtable, 0, sizeof(vtable));
  vtable.message_function = &MainDBusMethodHandler;

  const dbus_bool_t registration_result = dbus_connection_register_object_path(
      connection, kPermissionBrokerServicePath, &vtable, this);
  CHECK(registration_result) << "Could not register object path";

  GMainLoop *const loop = g_main_loop_new(NULL, false);
  g_main_loop_run(loop);
}

void PermissionBroker::AddUsbException(const uint16_t vendor_id,
                                       const uint16_t product_id) {
  usb_exceptions_.insert(std::make_pair(vendor_id, product_id));
}

void PermissionBroker::AddRule(Rule *rule) {
  CHECK(rule) << "Cannot add NULL as a rule.";
  rules_.push_back(rule);
}

bool PermissionBroker::ProcessPath(const string &path,
                                   int interface_id) {
  WaitForEmptyUdevQueue();

  LOG(INFO) << "ProcessPath(" << path << ")";
  Rule::Result result = Rule::IGNORE;
  for (unsigned int i = 0; i < rules_.size(); ++i) {
    const Rule::Result rule_result = rules_[i]->Process(path,
                                                        interface_id);
    LOG(INFO) << "  " << rules_[i]->name() << ": "
              << Rule::ResultToString(rule_result);
    if (rule_result == Rule::DENY)
      return false;
    else if (rule_result == Rule::ALLOW)
      result = Rule::ALLOW;
  }
  LOG(INFO) << "Verdict for " << path << ": " << Rule::ResultToString(result);

  if (result == Rule::ALLOW)
    return GrantAccess(path);
  return false;
}

bool PermissionBroker::GrantAccess(const std::string &path) {
  if (chown(path.c_str(), -1, access_group_)) {
    LOG(INFO) << "Could not grant access to " << path;
    return false;
  }
  return true;
}

bool PermissionBroker::ExpandUsbIdentifiersToPaths(
    const uint16_t vendor_id,
    const uint16_t product_id,
    vector<string> *paths) {
  CHECK(paths) << "Cannot invoke ExpandUsbIdentifiersToPaths with NULL paths.";
  paths->clear();

  struct udev_enumerate *const enumerate = udev_enumerate_new(udev_);
  udev_enumerate_add_match_is_initialized(enumerate);
  udev_enumerate_add_match_subsystem(enumerate, "usb");
  udev_enumerate_add_match_sysattr(
      enumerate, "idVendor", base::StringPrintf("%.4x", vendor_id).c_str());
  udev_enumerate_add_match_sysattr(
      enumerate, "idProduct", base::StringPrintf("%.4x", product_id).c_str());
  udev_enumerate_scan_devices(enumerate);

  struct udev_list_entry *entry = NULL;
  udev_list_entry_foreach(entry, udev_enumerate_get_list_entry(enumerate)) {
    const char *const path = udev_list_entry_get_name(entry);
    struct udev_device *device = udev_device_new_from_syspath(udev_, path);
    paths->push_back(udev_device_get_devnode(device));
    udev_device_unref(device);
  }

  udev_enumerate_unref(enumerate);
  return !paths->empty();
}

void PermissionBroker::WaitForEmptyUdevQueue() {
  struct udev_queue *queue = udev_queue_new(udev_);
  if (udev_queue_get_queue_is_empty(queue)) {
    udev_queue_unref(queue);
    return;
  }

  struct pollfd udev_poll;
  memset(&udev_poll, 0, sizeof(udev_poll));
  udev_poll.fd = inotify_init();
  udev_poll.events = POLLIN;

  const char *run_path = udev_get_run_path(udev_);
  int watch = inotify_add_watch(udev_poll.fd, run_path, IN_MOVED_TO);
  CHECK(watch != -1) << "Could not add watch for udev run path.";

  while (!udev_queue_get_queue_is_empty(queue)) {
    if (poll(&udev_poll, 1, FLAGS_poll_interval) > 0) {
      char buffer[sizeof(struct inotify_event)];
      const ssize_t result = read(udev_poll.fd, buffer, sizeof(buffer));
      if (result < 0)
        LOG(WARNING) << "Did not read complete udev event.";
    }
  }
  udev_queue_unref(queue);
  close(udev_poll.fd);
}

DBusHandlerResult PermissionBroker::MainDBusMethodHandler(
    DBusConnection *connection, DBusMessage *message, void *data) {
  CHECK(connection) << "Missing connection.";
  CHECK(message) << "Missing method.";
  CHECK(data) << "Missing pointer to broker.";

  if (dbus_message_get_type(message) != DBUS_MESSAGE_TYPE_METHOD_CALL)
    return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;

  string interface(dbus_message_get_interface(message));
  if (interface != kPermissionBrokerInterface)
    return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;

  DBusMessage *reply = NULL;
  string member(dbus_message_get_member(message));
  PermissionBroker *const broker = static_cast<PermissionBroker*>(data);
  if (member == kRequestPathAccess)
    reply = broker->HandleRequestPathAccessMethod(message);
  else if (member == kRequestUsbAccess)
    reply = broker->HandleRequestUsbAccessMethod(message);
  else
    return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;

  CHECK(dbus_connection_send(connection, reply, NULL));
  dbus_message_unref(reply);

  return DBUS_HANDLER_RESULT_HANDLED;
}

DBusMessage *PermissionBroker::HandleRequestPathAccessMethod(
    DBusMessage *message) {
  DBusMessage *reply = dbus_message_new_method_return(message);
  CHECK(reply) << "Could not allocate reply message for method call";

  dbus_bool_t success = false;
  char *path = NULL;
  int interface_id = Rule::ANY_INTERFACE;

  DBusError error;
  dbus_error_init(&error);
  if (!dbus_message_get_args(message, &error,
                             DBUS_TYPE_STRING, &path,
                             DBUS_TYPE_INT32, &interface_id,
                             DBUS_TYPE_INVALID)) {
    interface_id = Rule::ANY_INTERFACE;
    if (!dbus_message_get_args(message, &error,
                               DBUS_TYPE_STRING, &path,
                               DBUS_TYPE_INVALID)) {
      LOG(WARNING) << "Error parsing arguments: " << error.message;
      dbus_error_free(&error);

      dbus_message_append_args(reply,
                               DBUS_TYPE_BOOLEAN, &success,
                               DBUS_TYPE_INVALID);
      return reply;
    }
  }

  success = ProcessPath(path, interface_id);
  dbus_message_append_args(reply,
                           DBUS_TYPE_BOOLEAN, &success,
                           DBUS_TYPE_INVALID);
  return reply;
}

DBusMessage *PermissionBroker::HandleRequestUsbAccessMethod(
    DBusMessage *message) {
  DBusMessage *reply = dbus_message_new_method_return(message);
  CHECK(reply) << "Could not allocate reply message for method call";

  dbus_bool_t success = false;
  uint16_t vendor_id;
  uint16_t product_id;
  int interface_id = Rule::ANY_INTERFACE;

  DBusError error;
  dbus_error_init(&error);
  if (!dbus_message_get_args(message, &error,
                             DBUS_TYPE_UINT16, &vendor_id,
                             DBUS_TYPE_UINT16, &product_id,
                             DBUS_TYPE_INT32, &interface_id,
                             DBUS_TYPE_INVALID)) {
    interface_id = Rule::ANY_INTERFACE;
    if (!dbus_message_get_args(message, &error,
                               DBUS_TYPE_UINT16, &vendor_id,
                               DBUS_TYPE_UINT16, &product_id,
                               DBUS_TYPE_INVALID)) {
      LOG(WARNING) << "Error parsing arguments: " << error.message;
      dbus_error_free(&error);

      dbus_message_append_args(reply,
                               DBUS_TYPE_BOOLEAN, &success,
                               DBUS_TYPE_INVALID);
      return reply;
    }
  }

  if (ContainsKey(usb_exceptions_, std::make_pair(vendor_id, product_id))) {
    success = true;
  } else {
    vector<string> paths;
    if (ExpandUsbIdentifiersToPaths(vendor_id,
                                    product_id,
                                    &paths)) {
      success = true;
      for (unsigned int i = 0; i < paths.size(); ++i)
        success &= ProcessPath(paths[i], interface_id);
    } else {
      LOG(INFO) << "Could not expand (" << vendor_id << ", " << product_id
                << ") to a list of device nodes.";
    }
  }

  dbus_message_append_args(reply,
                           DBUS_TYPE_BOOLEAN, &success,
                           DBUS_TYPE_INVALID);
  return reply;
}

}  // namespace permission_broker
