From 89b8a947e5c622272362e967847eb19337aa68da Mon Sep 17 00:00:00 2001 From: Robin Krahl Date: Mon, 28 May 2018 22:02:10 +0000 Subject: Add rudimentary support for the Nitrokey Storage This patch adds the Storage struct and the test-storage feature. It also enables all currently supported Pro commands for the Storage. --- src/device.rs | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 66 insertions(+), 2 deletions(-) (limited to 'src/device.rs') diff --git a/src/device.rs b/src/device.rs index 684f64a..1201540 100644 --- a/src/device.rs +++ b/src/device.rs @@ -54,7 +54,7 @@ enum Model { #[derive(Debug)] pub enum DeviceWrapper { /// A Nitrokey Storage device. - Storage(()), + Storage(Storage), /// A Nitrokey Pro device. Pro(Pro), } @@ -101,6 +101,48 @@ pub enum DeviceWrapper { #[derive(Debug)] pub struct Pro {} +/// A Nitrokey Storage device without user or admin authentication. +/// +/// Use the global function [`connect`][] to obtain an instance wrapper or the method +/// [`connect`][`Storage::connect`] to directly obtain an instance. If you want to execute a +/// command that requires user or admin authentication, use [`authenticate_admin`][] or +/// [`authenticate_user`][]. +/// +/// # Examples +/// +/// Authentication with error handling: +/// +/// ```no_run +/// use nitrokey::{Authenticate, User, Storage}; +/// # use nitrokey::CommandError; +/// +/// fn perform_user_task(device: &User) {} +/// fn perform_other_task(device: &Storage) {} +/// +/// # fn try_main() -> Result<(), CommandError> { +/// let device = nitrokey::Storage::connect()?; +/// let device = match device.authenticate_user("123456") { +/// Ok(user) => { +/// perform_user_task(&user); +/// user.device() +/// }, +/// Err((device, err)) => { +/// println!("Could not authenticate as user: {:?}", err); +/// device +/// }, +/// }; +/// perform_other_task(&device); +/// # Ok(()) +/// # } +/// ``` +/// +/// [`authenticate_admin`]: trait.Authenticate.html#method.authenticate_admin +/// [`authenticate_user`]: trait.Authenticate.html#method.authenticate_user +/// [`connect`]: fn.connect.html +/// [`Storage::connect`]: #method.connect +#[derive(Debug)] +pub struct Storage {} + /// A Nitrokey device. /// /// This trait provides the commands that can be executed without authentication and that are @@ -368,7 +410,7 @@ fn connect_model(model: Model) -> bool { impl DeviceWrapper { fn device(&self) -> &Device { match *self { - DeviceWrapper::Storage(_) => panic!("..."), + DeviceWrapper::Storage(ref storage) => storage, DeviceWrapper::Pro(ref pro) => pro, } } @@ -415,3 +457,25 @@ impl Drop for Pro { impl Device for Pro {} impl GenerateOtp for Pro {} + +impl Storage { + pub fn connect() -> Result { + // TODO: maybe Option instead of Result? + match connect_model(Model::Storage) { + true => Ok(Storage {}), + false => Err(CommandError::Unknown), + } + } +} + +impl Drop for Storage { + fn drop(&mut self) { + unsafe { + nitrokey_sys::NK_logout(); + } + } +} + +impl Device for Storage {} + +impl GenerateOtp for Storage {} -- cgit v1.2.1