// -*- coding: utf-8 -*- // // pwman-f2e // // Copyright 2023 Michael Büsch // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // mod ctap; mod hid; use anyhow::{self as ah, Context as _}; use privdrop::PrivDrop; use std::thread::sleep; use std::time::Duration; use crate::ctap::Ctap; use crate::hid::CtapHid; fn main() -> ah::Result<()> { let mut hid = CtapHid::new().context("Failed to create emulated HID device.")?; let mut ctap = Ctap::new(); // Drop root privileges. //TODO config user/group PrivDrop::default() .user("mb") .group("mb") .apply() .context("Failed to drop privileges.")?; loop { let mut error = false; if let Err(e) = hid.read() { eprintln!("HID read error: {e}"); error = true; } if !error { for (cid, command) in hid.get_commands() { match ctap.handle_command(command) { Ok(response) => { if let Err(e) = hid.send_response(cid, response) { eprintln!("HID write error: {e}"); error = true; } } Err(e) => { eprintln!("Failed to handle CTAP command: {e}"); error = true; } } } } if error { sleep(Duration::from_millis(500)); } else { sleep(Duration::from_millis(10)); } } } // vim: ts=4 sw=4 expandtab