From 9b5eeefd1e6377e4fdb6c4055ea4554b4e7b3897 Mon Sep 17 00:00:00 2001 From: "J.C. Jones" Date: Thu, 11 May 2017 10:34:23 -0700 Subject: [PATCH] Set a common API for the 'main' method --- src/bin/main.rs | 139 ++++-------------------------------------------- 1 file changed, 11 insertions(+), 128 deletions(-) diff --git a/src/bin/main.rs b/src/bin/main.rs index dfa5746..ea880a5 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -5,125 +5,18 @@ use crypto::sha2::Sha256; extern crate base64; extern crate u2fhid; use std::{io, thread, time}; -use std::io::{Read, Write}; -use std::sync::mpsc::{channel, Sender, Receiver, RecvTimeoutError}; -use std::sync::{Arc, Mutex}; -use std::time::{Duration, Instant}; +use std::sync::mpsc::channel; +use std::time::Duration; use u2fhid::U2FDevice; const PARAMETER_SIZE : usize = 32; -enum Command { - Register, - Sign, -} - -pub struct WorkUnit -{ - timeout: Duration, - start_time: Instant, - command: Command, - challenge: Vec, - application: Vec, - key_handle: Option>, - result_tx: Sender>> -} - pub struct U2FManager { - work_tx: Sender, -} - -pub fn open_u2f_manager() -> io::Result { - let (mut tx, rx) = channel::(); - let manager = U2FManager{ - work_tx: tx, - }; - - if let Err(e) = thread::Builder::new().name("HID Runloop".to_string()).spawn(move || { - U2FManager::worker_loop(rx); - }) { - return Err(e); - } - Ok(manager) } impl U2FManager { - fn worker_loop(work_rx: Receiver) { - let platform = match u2fhid::platform::open_platform_manager() { - Ok(v) => v, - Err(e) => panic!("Failure to open platform HID support: {}", e), - }; - - let mut current_job : Option = None; - loop { - println!("Doing work"); - - // Get new work - match work_rx.recv_timeout(Duration::from_millis(100)) { - Ok(v) => { - // TODO: Cancel existing job? - current_job = Some(v) - }, - Err(e) => { - if e != RecvTimeoutError::Timeout { - panic!("whoa now {}", e); - } - }, - }; - - current_job = match current_job { - Some(job) => { - let mut done = false; - let security_keys = match platform.find_keys() { - Ok(v) => v, - Err(e) => panic!("Problem enumerating keys, {}", e), - }; - - for mut device_obj in security_keys { - println!("iterating now"); - if let Ok(_) = U2FManager::perform_job_for_key(&mut device_obj, &job) { - done = true; - break; - } - } - - if job.start_time.elapsed() > job.timeout { - job.result_tx.send(Err(io::Error::new(io::ErrorKind::TimedOut, "Timed out"))); - done = true; - } - - if done { - None - } else { - Some(job) - } - }, - None => None, // Nothing to do - } - } - } - - pub fn perform_job_for_key(dev: &mut T, job: &WorkUnit) -> io::Result<()> - where T: U2FDevice + Read + Write - { - let result = match job.command { - Command::Register => { - u2fhid::u2f_register(dev, &job.challenge, &job.application) - }, - Command::Sign => { - // It'd be an error if key_handle was None here - let keybytes = job.key_handle.as_ref().unwrap(); - u2fhid::u2f_sign(dev, &job.challenge, &job.application, keybytes) - }, - }; - - match result { - Ok(bytes) => { - job.result_tx.send(Ok(bytes)); - Ok(()) - }, - Err(e) => Err(e), - } + pub fn new() -> U2FManager { + U2FManager{} } pub fn register(&self, timeout_sec: u8, challenge: Vec, application: Vec, callback: F) @@ -134,24 +27,14 @@ impl U2FManager { return; } - let (result_tx, result_rx) = channel::>>(); + let timeout = Duration::from_secs(timeout_sec as u64); - if let Err(e) = self.work_tx.send(WorkUnit{ - timeout: Duration::from_secs(timeout_sec as u64), - start_time: Instant::now(), - command: Command::Register, - challenge: challenge, - application: application, - key_handle: None, - result_tx: result_tx, + if let Err(e) = thread::Builder::new().name("Register Runloop".to_string()).spawn(move || { + let manager = u2fhid::platform::new(); + let result = manager.register(timeout, challenge, application); + callback(result); }) { - callback(Err(io::Error::new(io::ErrorKind::Other, format!("Send error {}", e)))); - return; - } - - match result_rx.recv() { - Ok(v) => callback(v), - Err(e) => callback(Err(io::Error::new(io::ErrorKind::Other, e))), + callback(Err(e)); } } @@ -194,7 +77,7 @@ fn main() { application.result(&mut app_bytes); let (tx, rx) = channel(); - let manager = open_u2f_manager().unwrap(); + let manager = U2FManager::new(); manager.register(15, chall_bytes, app_bytes, move |result| { // Ship back to the main thread