// Copyright 2019 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/deny_fwupdate_hidraw_device_rule.h"

#include <libudev.h>
#include <string>
#include <unordered_map>
#include <vector>

#include "base/files/file_path.h"
#include "base/logging.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"

namespace {

const int kElanVendorId = 0x04f3;
const int kMelfasVendorId = 0x1fd2;

// Structure that holds a map of vendor IDs and a list of the blocked product ID
// ranges. These ranges are inclusive.
const permission_broker::RangeListMap kFwUpdateDevices = {
    // Block ELAN touchscreens PID 0x2000 - 0x2FFF and 0x4000 - 0x4FFF. 0x0732
    // is the PID for a device in recovery mode.
    {kElanVendorId, {{0x2000, 0x2fff}, {0x4000, 0x4fff}, {0x0732, 0x0732}}},
    // Melfas USB touchscreen PID 0x8103.
    {kMelfasVendorId, {{0x8103, 0x8103}}},
};

}  // namespace

namespace permission_broker {

DenyFwUpdateHidrawDeviceRule::DenyFwUpdateHidrawDeviceRule()
    : HidrawSubsystemUdevRule("DenyFwUpdateHidrawDeviceRule") {}

Rule::Result DenyFwUpdateHidrawDeviceRule::ProcessHidrawDevice(
    struct udev_device* device) {
  const char* devpath = udev_device_get_devpath(device);
  return IsFwUpdateDevice(devpath, kFwUpdateDevices) ? Rule::DENY
                                                     : Rule::IGNORE;
}

// The vendor and device ID are not in the udev properties. They need to be
// parsed out of the device path:
// e.g. i2c-7/i2c-ELAN900C:00/0018:04F3:2A03.0001/hidraw/hidraw0. The
// important part of the path is 0018:04F3:2A03.0001 where 04F3 is the vendor
// ID and 2A03 is the product ID.
bool DenyFwUpdateHidrawDeviceRule::IsFwUpdateDevice(
    const char* path, const RangeListMap& fwDevices) {
  if (!path) {
    return false;
  }

  // Split the path by directories.
  std::vector<std::string> dirs;
  base::FilePath(path).GetComponents(&dirs);

  for (const auto& dir : dirs) {
    // Split the path by colons (:). We are searching for the pattern:
    // ####:####:####.####
    // All devices that match this pattern need to be checked to ensure that
    // none are blacklisted.
    std::vector<std::string> chunks =
        base::SplitString(dir, ":", base::WhitespaceHandling::TRIM_WHITESPACE,
                          base::SplitResult::SPLIT_WANT_NONEMPTY);

    if (chunks.size() != 3) {
      continue;
    }

    // The vendor ID is the second hex value in the sequence.
    int vendor_id;
    if (!base::HexStringToInt(chunks[1], &vendor_id)) {
      continue;
    }

    // The product ID is the third hex value in the sequence. The period and
    // trailing numbers also need to be trimmed.
    std::string::size_type pos = chunks[2].find('.');
    int product_id;
    if (!base::HexStringToInt(chunks[2].substr(0, pos), &product_id)) {
      continue;
    }

    if (fwDevices.count(vendor_id) != 1) {
      continue;
    }

    for (const auto& range : fwDevices.at(vendor_id)) {
      if (product_id >= range.min && product_id <= range.max) {
        return true;
      }
    }
  }

  return false;
}

}  // namespace permission_broker
