Initial commit

This commit is contained in:
Arda Xi
2018-12-27 20:22:33 +01:00
commit 640023e0f8
12 changed files with 1889 additions and 0 deletions

86
src/hid_linux.rs Normal file
View File

@@ -0,0 +1,86 @@
// This file is part of ctap, a Rust implementation of the FIDO2 protocol.
// Copyright (c) Ariën Holthuizen <contact@ardaxi.com>
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.
use std::io;
use std::fs;
use std::path::PathBuf;
use byteorder::{ByteOrder, LittleEndian};
pub use super::hid_common::*;
static REPORT_DESCRIPTOR_KEY_MASK: u8 = 0xfc;
static LONG_ITEM_ENCODING: u8 = 0xfe;
static USAGE_PAGE: u8 = 0x04;
static USAGE: u8 = 0x08;
static REPORT_SIZE: u8 = 0x74;
pub fn enumerate() -> io::Result<Vec<DeviceInfo>> {
fs::read_dir("/sys/class/hidraw")?
.filter_map(|entry| entry.ok())
.map(|entry| path_to_device(&entry.path()))
.collect()
}
fn path_to_device(path: &PathBuf) -> io::Result<DeviceInfo> {
let mut rd_path = path.clone();
rd_path.push("device/report_descriptor");
let rd = fs::read(rd_path)?;
let mut usage_page: u16 = 0;
let mut usage: u16 = 0;
let mut report_size: u16 = 0;
let mut pos: usize = 0;
while pos < rd.len() {
let key = rd[pos];
let mut key_size: usize = 1;
let mut size: u8;
if key == LONG_ITEM_ENCODING {
key_size = 3;
size = rd[pos + 1];
} else {
size = key & 0x03;
if size == 0x03 {
size = 0x04
}
}
if key & REPORT_DESCRIPTOR_KEY_MASK == USAGE_PAGE {
if size != 2 {
usage_page = u16::from(rd[pos + 1])
} else {
usage_page = LittleEndian::read_u16(&rd[(pos + 1)..(pos + 1 + (size as usize))]);
}
}
if key & REPORT_DESCRIPTOR_KEY_MASK == USAGE {
if size != 2 {
usage = u16::from(rd[pos + 1])
} else {
usage = LittleEndian::read_u16(&rd[(pos + 1)..(pos + 1 + (size as usize))]);
}
}
if key & REPORT_DESCRIPTOR_KEY_MASK == REPORT_SIZE {
if size != 2 {
report_size = u16::from(rd[pos + 1])
} else {
report_size = LittleEndian::read_u16(&rd[(pos + 1)..(pos + 1 + (size as usize))]);
}
}
pos = pos + key_size + size as usize;
}
let mut device_path = PathBuf::from("/dev");
device_path.push(path.file_name().unwrap());
Ok(DeviceInfo {
path: device_path,
usage_page,
usage,
})
}