diff options
Diffstat (limited to 'src/device.rs')
-rw-r--r-- | src/device.rs | 160 |
1 files changed, 40 insertions, 120 deletions
diff --git a/src/device.rs b/src/device.rs index 758691d..50ff071 100644 --- a/src/device.rs +++ b/src/device.rs @@ -2,14 +2,13 @@ // SPDX-License-Identifier: MIT use std::fmt; -use std::marker; use libc; use nitrokey_sys; use crate::auth::Authenticate; use crate::config::{Config, RawConfig}; -use crate::error::Error; +use crate::error::{CommunicationError, Error}; use crate::otp::GenerateOtp; use crate::pws::GetPasswordSafe; use crate::util::{ @@ -109,11 +108,11 @@ impl fmt::Display for VolumeMode { /// /// [`connect`]: fn.connect.html #[derive(Debug)] -pub enum DeviceWrapper { +pub enum DeviceWrapper<'a> { /// A Nitrokey Storage device. - Storage(Storage), + Storage(Storage<'a>), /// A Nitrokey Pro device. - Pro(Pro), + Pro(Pro<'a>), } /// A Nitrokey Pro device without user or admin authentication. @@ -156,10 +155,8 @@ pub enum DeviceWrapper { /// [`connect`]: fn.connect.html /// [`Pro::connect`]: #method.connect #[derive(Debug)] -pub struct Pro { - // make sure that users cannot directly instantiate this type - #[doc(hidden)] - marker: marker::PhantomData<()>, +pub struct Pro<'a> { + manager: &'a mut crate::Manager, } /// A Nitrokey Storage device without user or admin authentication. @@ -202,10 +199,8 @@ pub struct Pro { /// [`connect`]: fn.connect.html /// [`Storage::connect`]: #method.connect #[derive(Debug)] -pub struct Storage { - // make sure that users cannot directly instantiate this type - #[doc(hidden)] - marker: marker::PhantomData<()>, +pub struct Storage<'a> { + manager: &'a mut crate::Manager, } /// The status of a volume on a Nitrokey Storage device. @@ -626,32 +621,6 @@ pub trait Device: Authenticate + GetPasswordSafe + GenerateOtp + fmt::Debug { } } -/// Connects to a Nitrokey device. This method can be used to connect to any connected device, -/// both a Nitrokey Pro and a Nitrokey Storage. -/// -/// # Errors -/// -/// - [`NotConnected`][] if no Nitrokey device is connected -/// -/// # Example -/// -/// ``` -/// use nitrokey::DeviceWrapper; -/// -/// fn do_something(device: DeviceWrapper) {} -/// -/// match nitrokey::connect() { -/// Ok(device) => do_something(device), -/// Err(err) => eprintln!("Could not connect to a Nitrokey: {}", err), -/// } -/// ``` -/// -/// [`NotConnected`]: enum.CommunicationError.html#variant.NotConnected -#[deprecated(since = "0.4.0", note = "use `nitrokey::Manager::connect` instead")] -pub fn connect() -> Result<DeviceWrapper, Error> { - crate::take()?.connect().map_err(Into::into) -} - fn get_connected_model() -> Option<Model> { match unsafe { nitrokey_sys::NK_get_device_model() } { nitrokey_sys::NK_device_model_NK_PRO => Some(Model::Pro), @@ -660,15 +629,23 @@ fn get_connected_model() -> Option<Model> { } } -pub(crate) fn create_device_wrapper(model: Model) -> DeviceWrapper { +pub(crate) fn create_device_wrapper( + manager: &mut crate::Manager, + model: Model, +) -> DeviceWrapper<'_> { match model { - Model::Pro => Pro::new().into(), - Model::Storage => Storage::new().into(), + Model::Pro => Pro::new(manager).into(), + Model::Storage => Storage::new(manager).into(), } } -pub(crate) fn get_connected_device() -> Option<DeviceWrapper> { - get_connected_model().map(create_device_wrapper) +pub(crate) fn get_connected_device( + manager: &mut crate::Manager, +) -> Result<DeviceWrapper<'_>, Error> { + match get_connected_model() { + Some(model) => Ok(create_device_wrapper(manager, model)), + None => Err(CommunicationError::NotConnected.into()), + } } pub(crate) fn connect_enum(model: Model) -> bool { @@ -679,7 +656,7 @@ pub(crate) fn connect_enum(model: Model) -> bool { unsafe { nitrokey_sys::NK_login_enum(model) == 1 } } -impl DeviceWrapper { +impl<'a> DeviceWrapper<'a> { fn device(&self) -> &dyn Device { match *self { DeviceWrapper::Storage(ref storage) => storage, @@ -695,19 +672,19 @@ impl DeviceWrapper { } } -impl From<Pro> for DeviceWrapper { - fn from(device: Pro) -> Self { +impl<'a> From<Pro<'a>> for DeviceWrapper<'a> { + fn from(device: Pro<'a>) -> Self { DeviceWrapper::Pro(device) } } -impl From<Storage> for DeviceWrapper { - fn from(device: Storage) -> Self { +impl<'a> From<Storage<'a>> for DeviceWrapper<'a> { + fn from(device: Storage<'a>) -> Self { DeviceWrapper::Storage(device) } } -impl GenerateOtp for DeviceWrapper { +impl<'a> GenerateOtp for DeviceWrapper<'a> { fn get_hotp_slot_name(&self, slot: u8) -> Result<String, Error> { self.device().get_hotp_slot_name(slot) } @@ -725,7 +702,7 @@ impl GenerateOtp for DeviceWrapper { } } -impl Device for DeviceWrapper { +impl<'a> Device for DeviceWrapper<'a> { fn get_model(&self) -> Model { match *self { DeviceWrapper::Pro(_) => Model::Pro, @@ -734,40 +711,13 @@ impl Device for DeviceWrapper { } } -impl Pro { - /// Connects to a Nitrokey Pro. - /// - /// # Errors - /// - /// - [`NotConnected`][] if no Nitrokey device of the given model is connected - /// - /// # Example - /// - /// ``` - /// use nitrokey::Pro; - /// - /// fn use_pro(device: Pro) {} - /// - /// match nitrokey::Pro::connect() { - /// Ok(device) => use_pro(device), - /// Err(err) => eprintln!("Could not connect to the Nitrokey Pro: {}", err), - /// } - /// ``` - /// - /// [`NotConnected`]: enum.CommunicationError.html#variant.NotConnected - #[deprecated(since = "0.4.0", note = "use `nitrokey::Manager::connect_pro` instead")] - pub fn connect() -> Result<Pro, Error> { - crate::take()?.connect_pro().map_err(Into::into) - } - - pub(crate) fn new() -> Pro { - Pro { - marker: marker::PhantomData, - } +impl<'a> Pro<'a> { + pub(crate) fn new(manager: &'a mut crate::Manager) -> Pro<'a> { + Pro { manager } } } -impl Drop for Pro { +impl<'a> Drop for Pro<'a> { fn drop(&mut self) { unsafe { nitrokey_sys::NK_logout(); @@ -775,47 +725,17 @@ impl Drop for Pro { } } -impl Device for Pro { +impl<'a> Device for Pro<'a> { fn get_model(&self) -> Model { Model::Pro } } -impl GenerateOtp for Pro {} +impl<'a> GenerateOtp for Pro<'a> {} -impl Storage { - /// Connects to a Nitrokey Storage. - /// - /// # Errors - /// - /// - [`NotConnected`][] if no Nitrokey device of the given model is connected - /// - /// # Example - /// - /// ``` - /// use nitrokey::Storage; - /// - /// fn use_storage(device: Storage) {} - /// - /// match nitrokey::Storage::connect() { - /// Ok(device) => use_storage(device), - /// Err(err) => eprintln!("Could not connect to the Nitrokey Storage: {}", err), - /// } - /// ``` - /// - /// [`NotConnected`]: enum.CommunicationError.html#variant.NotConnected - #[deprecated( - since = "0.4.0", - note = "use `nitrokey::Manager::connect_storage` instead" - )] - pub fn connect() -> Result<Storage, Error> { - crate::take()?.connect_storage().map_err(Into::into) - } - - pub(crate) fn new() -> Storage { - Storage { - marker: marker::PhantomData, - } +impl<'a> Storage<'a> { + pub(crate) fn new(manager: &'a mut crate::Manager) -> Storage<'a> { + Storage { manager } } /// Changes the update PIN. @@ -1320,7 +1240,7 @@ impl Storage { } } -impl Drop for Storage { +impl<'a> Drop for Storage<'a> { fn drop(&mut self) { unsafe { nitrokey_sys::NK_logout(); @@ -1328,13 +1248,13 @@ impl Drop for Storage { } } -impl Device for Storage { +impl<'a> Device for Storage<'a> { fn get_model(&self) -> Model { Model::Storage } } -impl GenerateOtp for Storage {} +impl<'a> GenerateOtp for Storage<'a> {} impl From<nitrokey_sys::NK_storage_ProductionTest> for StorageProductionInfo { fn from(data: nitrokey_sys::NK_storage_ProductionTest) -> Self { |