From fe2f39826ade5a156945dabb8c8ab725378a15c1 Mon Sep 17 00:00:00 2001 From: Robin Krahl Date: Sun, 27 Jan 2019 18:42:14 +0000 Subject: Store mutable reference to Manager in Device In the last patches, we ensured that devices can only be obtained using the Manager struct. But we did not ensure that there is only one device at a time. This patch adds a mutable reference to the Manager instance to the Device implementations. The borrow checker makes sure that there is only one mutable reference at a time. In this patch, we have to remove the old connect, Pro::connect and Storage::connect functions as they do no longer compile. (They discard the MutexGuard which invalidates the reference to the Manager.) Therefore the tests do no longer compile. --- src/pws.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/pws.rs') diff --git a/src/pws.rs b/src/pws.rs index 371de6e..cf2dd42 100644 --- a/src/pws.rs +++ b/src/pws.rs @@ -364,19 +364,19 @@ impl<'a> Drop for PasswordSafe<'a> { } } -impl GetPasswordSafe for Pro { +impl<'a> GetPasswordSafe for Pro<'a> { fn get_password_safe(&mut self, user_pin: &str) -> Result, Error> { get_password_safe(self, user_pin) } } -impl GetPasswordSafe for Storage { +impl<'a> GetPasswordSafe for Storage<'a> { fn get_password_safe(&mut self, user_pin: &str) -> Result, Error> { get_password_safe(self, user_pin) } } -impl GetPasswordSafe for DeviceWrapper { +impl<'a> GetPasswordSafe for DeviceWrapper<'a> { fn get_password_safe(&mut self, user_pin: &str) -> Result, Error> { get_password_safe(self, user_pin) } -- cgit v1.2.1 From 12fa62483cf45d868099d5d4020333af492eebde Mon Sep 17 00:00:00 2001 From: Robin Krahl Date: Tue, 9 Jul 2019 08:09:02 +0000 Subject: Introduce into_manager for Device MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To enable applications like nitrokey-test to go back to a manager instance from a Device instance, we add the into_manager function to the Device trait. To do that, we have to keep track of the Manager’s lifetime by adding a lifetime to Device (and then to some other traits that use Device). --- src/pws.rs | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) (limited to 'src/pws.rs') diff --git a/src/pws.rs b/src/pws.rs index cf2dd42..778765d 100644 --- a/src/pws.rs +++ b/src/pws.rs @@ -57,8 +57,8 @@ pub const SLOT_COUNT: u8 = 16; /// [`lock`]: trait.Device.html#method.lock /// [`GetPasswordSafe`]: trait.GetPasswordSafe.html #[derive(Debug)] -pub struct PasswordSafe<'a> { - _device: &'a dyn Device, +pub struct PasswordSafe<'a, 'b> { + _device: &'a dyn Device<'b>, } /// Provides access to a [`PasswordSafe`][]. @@ -67,7 +67,7 @@ pub struct PasswordSafe<'a> { /// retrieved from it. /// /// [`PasswordSafe`]: struct.PasswordSafe.html -pub trait GetPasswordSafe { +pub trait GetPasswordSafe<'a> { /// Enables and returns the password safe. /// /// The underlying device must always live at least as long as a password safe retrieved from @@ -117,13 +117,13 @@ pub trait GetPasswordSafe { /// [`InvalidString`]: enum.LibraryError.html#variant.InvalidString /// [`Unknown`]: enum.CommandError.html#variant.Unknown /// [`WrongPassword`]: enum.CommandError.html#variant.WrongPassword - fn get_password_safe(&mut self, user_pin: &str) -> Result, Error>; + fn get_password_safe(&mut self, user_pin: &str) -> Result, Error>; } -fn get_password_safe<'a>( - device: &'a dyn Device, +fn get_password_safe<'a, 'b>( + device: &'a dyn Device<'b>, user_pin: &str, -) -> Result, Error> { +) -> Result, Error> { let user_pin_string = get_cstring(user_pin)?; get_command_result(unsafe { nitrokey_sys::NK_enable_password_safe(user_pin_string.as_ptr()) }) .map(|_| PasswordSafe { _device: device }) @@ -137,7 +137,7 @@ fn get_pws_result(s: String) -> Result { } } -impl<'a> PasswordSafe<'a> { +impl<'a, 'b> PasswordSafe<'a, 'b> { /// Returns the status of all password slots. /// /// The status indicates whether a slot is programmed or not. @@ -357,27 +357,27 @@ impl<'a> PasswordSafe<'a> { } } -impl<'a> Drop for PasswordSafe<'a> { +impl<'a, 'b> Drop for PasswordSafe<'a, 'b> { fn drop(&mut self) { // TODO: disable the password safe -- NK_lock_device has side effects on the Nitrokey // Storage, see https://github.com/Nitrokey/nitrokey-storage-firmware/issues/65 } } -impl<'a> GetPasswordSafe for Pro<'a> { - fn get_password_safe(&mut self, user_pin: &str) -> Result, Error> { +impl<'a> GetPasswordSafe<'a> for Pro<'a> { + fn get_password_safe(&mut self, user_pin: &str) -> Result, Error> { get_password_safe(self, user_pin) } } -impl<'a> GetPasswordSafe for Storage<'a> { - fn get_password_safe(&mut self, user_pin: &str) -> Result, Error> { +impl<'a> GetPasswordSafe<'a> for Storage<'a> { + fn get_password_safe(&mut self, user_pin: &str) -> Result, Error> { get_password_safe(self, user_pin) } } -impl<'a> GetPasswordSafe for DeviceWrapper<'a> { - fn get_password_safe(&mut self, user_pin: &str) -> Result, Error> { +impl<'a> GetPasswordSafe<'a> for DeviceWrapper<'a> { + fn get_password_safe(&mut self, user_pin: &str) -> Result, Error> { get_password_safe(self, user_pin) } } -- cgit v1.2.1 From 62e8ee8f5d02511d6eb5dc179b087b04e88c1b94 Mon Sep 17 00:00:00 2001 From: Robin Krahl Date: Sun, 27 Jan 2019 19:52:53 +0000 Subject: Update documentation for Manager refactoring This patch updates the documentation to reflect the latest changes to connection handling. It also updates the doc tests to prefer the new methods over the old ones. --- src/pws.rs | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) (limited to 'src/pws.rs') diff --git a/src/pws.rs b/src/pws.rs index 778765d..3398deb 100644 --- a/src/pws.rs +++ b/src/pws.rs @@ -43,7 +43,8 @@ pub const SLOT_COUNT: u8 = 16; /// } /// /// # fn try_main() -> Result<(), Error> { -/// let mut device = nitrokey::connect()?; +/// let mut manager = nitrokey::take()?; +/// let mut device = manager.connect()?; /// let pws = device.get_password_safe("123456")?; /// use_password_safe(&pws); /// drop(pws); @@ -98,7 +99,8 @@ pub trait GetPasswordSafe<'a> { /// fn use_password_safe(pws: &PasswordSafe) {} /// /// # fn try_main() -> Result<(), Error> { - /// let mut device = nitrokey::connect()?; + /// let mut manager = nitrokey::take()?; + /// let mut device = manager.connect()?; /// match device.get_password_safe("123456") { /// Ok(pws) => { /// use_password_safe(&pws); @@ -149,7 +151,8 @@ impl<'a, 'b> PasswordSafe<'a, 'b> { /// # use nitrokey::Error; /// /// # fn try_main() -> Result<(), Error> { - /// let mut device = nitrokey::connect()?; + /// let mut manager = nitrokey::take()?; + /// let mut device = manager.connect()?; /// let pws = device.get_password_safe("123456")?; /// pws.get_slot_status()?.iter().enumerate().for_each(|(slot, programmed)| { /// let status = match *programmed { @@ -194,7 +197,8 @@ impl<'a, 'b> PasswordSafe<'a, 'b> { /// # use nitrokey::Error; /// /// # fn try_main() -> Result<(), Error> { - /// let mut device = nitrokey::connect()?; + /// let mut manager = nitrokey::take()?; + /// let mut device = manager.connect()?; /// match device.get_password_safe("123456") { /// Ok(pws) => { /// let name = pws.get_slot_name(0)?; @@ -231,7 +235,8 @@ impl<'a, 'b> PasswordSafe<'a, 'b> { /// # use nitrokey::Error; /// /// # fn try_main() -> Result<(), Error> { - /// let mut device = nitrokey::connect()?; + /// let mut manager = nitrokey::take()?; + /// let mut device = manager.connect()?; /// let pws = device.get_password_safe("123456")?; /// let name = pws.get_slot_name(0)?; /// let login = pws.get_slot_login(0)?; @@ -264,7 +269,8 @@ impl<'a, 'b> PasswordSafe<'a, 'b> { /// # use nitrokey::Error; /// /// # fn try_main() -> Result<(), Error> { - /// let mut device = nitrokey::connect()?; + /// let mut manager = nitrokey::take()?; + /// let mut device = manager.connect()?; /// let pws = device.get_password_safe("123456")?; /// let name = pws.get_slot_name(0)?; /// let login = pws.get_slot_login(0)?; @@ -295,7 +301,8 @@ impl<'a, 'b> PasswordSafe<'a, 'b> { /// # use nitrokey::Error; /// /// # fn try_main() -> Result<(), Error> { - /// let mut device = nitrokey::connect()?; + /// let mut manager = nitrokey::take()?; + /// let mut device = manager.connect()?; /// let pws = device.get_password_safe("123456")?; /// let name = pws.get_slot_name(0)?; /// let login = pws.get_slot_login(0)?; @@ -341,7 +348,8 @@ impl<'a, 'b> PasswordSafe<'a, 'b> { /// # use nitrokey::Error; /// /// # fn try_main() -> Result<(), Error> { - /// let mut device = nitrokey::connect()?; + /// let mut manager = nitrokey::take()?; + /// let mut device = manager.connect()?; /// let mut pws = device.get_password_safe("123456")?; /// match pws.erase_slot(0) { /// Ok(()) => println!("Erased slot 0."), -- cgit v1.2.1