From f49e61589e32217f97c94aa86d826f6b65170fba Mon Sep 17 00:00:00 2001 From: Robin Krahl Date: Mon, 28 Jan 2019 12:27:15 +0000 Subject: Require mutable reference if method changes device state Previously, all methods that access a Nitrokey device took a reference to the device as input. This method changes methods that change the device state to require a mutable reference instead. In most case, this is straightforward as the method writes data to the device (for example write_config or change_user_pin). But there are two edge cases: - Authenticating with a PIN changes the device state as it may decrease the PIN retry counter if the authentication fails. - Generating an HOTP code changes the device state as it increases the HOTP counter. --- src/otp.rs | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'src/otp.rs') diff --git a/src/otp.rs b/src/otp.rs index abaff66..ee142c7 100644 --- a/src/otp.rs +++ b/src/otp.rs @@ -38,7 +38,7 @@ pub trait ConfigureOtp { /// let device = nitrokey::connect()?; /// let slot_data = OtpSlotData::new(1, "test", "01234567890123456689", OtpMode::SixDigits); /// match device.authenticate_admin("12345678") { - /// Ok(admin) => { + /// Ok(mut admin) => { /// match admin.write_hotp_slot(slot_data, 0) { /// Ok(()) => println!("Successfully wrote slot."), /// Err(err) => eprintln!("Could not write slot: {}", err), @@ -53,7 +53,7 @@ pub trait ConfigureOtp { /// [`InvalidSlot`]: enum.LibraryError.html#variant.InvalidSlot /// [`InvalidString`]: enum.LibraryError.html#variant.InvalidString /// [`NoName`]: enum.CommandError.html#variant.NoName - fn write_hotp_slot(&self, data: OtpSlotData, counter: u64) -> Result<(), Error>; + fn write_hotp_slot(&mut self, data: OtpSlotData, counter: u64) -> Result<(), Error>; /// Configure a TOTP slot with the given data and set the TOTP time window to the given value /// (default 30). @@ -74,7 +74,7 @@ pub trait ConfigureOtp { /// let device = nitrokey::connect()?; /// let slot_data = OtpSlotData::new(1, "test", "01234567890123456689", OtpMode::EightDigits); /// match device.authenticate_admin("12345678") { - /// Ok(admin) => { + /// Ok(mut admin) => { /// match admin.write_totp_slot(slot_data, 30) { /// Ok(()) => println!("Successfully wrote slot."), /// Err(err) => eprintln!("Could not write slot: {}", err), @@ -89,7 +89,7 @@ pub trait ConfigureOtp { /// [`InvalidSlot`]: enum.LibraryError.html#variant.InvalidSlot /// [`InvalidString`]: enum.LibraryError.html#variant.InvalidString /// [`NoName`]: enum.CommandError.html#variant.NoName - fn write_totp_slot(&self, data: OtpSlotData, time_window: u16) -> Result<(), Error>; + fn write_totp_slot(&mut self, data: OtpSlotData, time_window: u16) -> Result<(), Error>; /// Erases an HOTP slot. /// @@ -106,7 +106,7 @@ pub trait ConfigureOtp { /// # fn try_main() -> Result<(), Error> { /// let device = nitrokey::connect()?; /// match device.authenticate_admin("12345678") { - /// Ok(admin) => { + /// Ok(mut admin) => { /// match admin.erase_hotp_slot(1) { /// Ok(()) => println!("Successfully erased slot."), /// Err(err) => eprintln!("Could not erase slot: {}", err), @@ -119,7 +119,7 @@ pub trait ConfigureOtp { /// ``` /// /// [`InvalidSlot`]: enum.LibraryError.html#variant.InvalidSlot - fn erase_hotp_slot(&self, slot: u8) -> Result<(), Error>; + fn erase_hotp_slot(&mut self, slot: u8) -> Result<(), Error>; /// Erases a TOTP slot. /// @@ -136,7 +136,7 @@ pub trait ConfigureOtp { /// # fn try_main() -> Result<(), Error> { /// let device = nitrokey::connect()?; /// match device.authenticate_admin("12345678") { - /// Ok(admin) => { + /// Ok(mut admin) => { /// match admin.erase_totp_slot(1) { /// Ok(()) => println!("Successfully erased slot."), /// Err(err) => eprintln!("Could not erase slot: {}", err), @@ -149,7 +149,7 @@ pub trait ConfigureOtp { /// ``` /// /// [`InvalidSlot`]: enum.LibraryError.html#variant.InvalidSlot - fn erase_totp_slot(&self, slot: u8) -> Result<(), Error>; + fn erase_totp_slot(&mut self, slot: u8) -> Result<(), Error>; } /// Provides methods to generate OTP codes and to query OTP slots on a Nitrokey @@ -171,7 +171,7 @@ pub trait GenerateOtp { /// # use nitrokey::Error; /// /// # fn try_main() -> Result<(), Error> { - /// let device = nitrokey::connect()?; + /// let mut device = nitrokey::connect()?; /// let time = time::SystemTime::now().duration_since(time::UNIX_EPOCH); /// match time { /// Ok(time) => device.set_time(time.as_secs(), false)?, @@ -187,7 +187,7 @@ pub trait GenerateOtp { /// /// [`get_totp_code`]: #method.get_totp_code /// [`Timestamp`]: enum.CommandError.html#variant.Timestamp - fn set_time(&self, time: u64, force: bool) -> Result<(), Error> { + fn set_time(&mut self, time: u64, force: bool) -> Result<(), Error> { let result = if force { unsafe { nitrokey_sys::NK_totp_set_time(time) } } else { @@ -270,7 +270,7 @@ pub trait GenerateOtp { /// # use nitrokey::Error; /// /// # fn try_main() -> Result<(), Error> { - /// let device = nitrokey::connect()?; + /// let mut device = nitrokey::connect()?; /// let code = device.get_hotp_code(1)?; /// println!("Generated HOTP code on slot 1: {}", code); /// # Ok(()) @@ -281,7 +281,7 @@ pub trait GenerateOtp { /// [`InvalidSlot`]: enum.LibraryError.html#variant.InvalidSlot /// [`NotAuthorized`]: enum.CommandError.html#variant.NotAuthorized /// [`SlotNotProgrammed`]: enum.CommandError.html#variant.SlotNotProgrammed - fn get_hotp_code(&self, slot: u8) -> Result { + fn get_hotp_code(&mut self, slot: u8) -> Result { result_from_string(unsafe { nitrokey_sys::NK_get_hotp_code(slot) }) } @@ -305,7 +305,7 @@ pub trait GenerateOtp { /// # use nitrokey::Error; /// /// # fn try_main() -> Result<(), Error> { - /// let device = nitrokey::connect()?; + /// let mut device = nitrokey::connect()?; /// let time = time::SystemTime::now().duration_since(time::UNIX_EPOCH); /// match time { /// Ok(time) => { -- cgit v1.2.1 From 0972bbe82623c3d9649b6023d8f50d304aa0cde6 Mon Sep 17 00:00:00 2001 From: Robin Krahl Date: Mon, 28 Jan 2019 14:24:12 +0000 Subject: Refactor User and Admin to use a mutable reference MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In the initial nitrokey-rs implementation, the Admin and the User struct take the Device by value to make sure that the user cannot initiate a second authentication while this first is still active (which would invalidate the temporary password). Now we realized that this is not necessary – taking a mutable reference has the same effect, but leads to a much cleaner API. This patch refactors the Admin and User structs – and all dependent code – to use a mutable reference instead of a Device value. --- src/otp.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'src/otp.rs') diff --git a/src/otp.rs b/src/otp.rs index ee142c7..a8dd20b 100644 --- a/src/otp.rs +++ b/src/otp.rs @@ -35,7 +35,7 @@ pub trait ConfigureOtp { /// # use nitrokey::Error; /// /// # fn try_main() -> Result<(), Error> { - /// let device = nitrokey::connect()?; + /// let mut device = nitrokey::connect()?; /// let slot_data = OtpSlotData::new(1, "test", "01234567890123456689", OtpMode::SixDigits); /// match device.authenticate_admin("12345678") { /// Ok(mut admin) => { @@ -44,7 +44,7 @@ pub trait ConfigureOtp { /// Err(err) => eprintln!("Could not write slot: {}", err), /// } /// }, - /// Err((_, err)) => eprintln!("Could not authenticate as admin: {}", err), + /// Err(err) => eprintln!("Could not authenticate as admin: {}", err), /// } /// # Ok(()) /// # } @@ -71,7 +71,7 @@ pub trait ConfigureOtp { /// # use nitrokey::Error; /// /// # fn try_main() -> Result<(), Error> { - /// let device = nitrokey::connect()?; + /// let mut device = nitrokey::connect()?; /// let slot_data = OtpSlotData::new(1, "test", "01234567890123456689", OtpMode::EightDigits); /// match device.authenticate_admin("12345678") { /// Ok(mut admin) => { @@ -80,7 +80,7 @@ pub trait ConfigureOtp { /// Err(err) => eprintln!("Could not write slot: {}", err), /// } /// }, - /// Err((_, err)) => eprintln!("Could not authenticate as admin: {}", err), + /// Err(err) => eprintln!("Could not authenticate as admin: {}", err), /// } /// # Ok(()) /// # } @@ -104,7 +104,7 @@ pub trait ConfigureOtp { /// # use nitrokey::Error; /// /// # fn try_main() -> Result<(), Error> { - /// let device = nitrokey::connect()?; + /// let mut device = nitrokey::connect()?; /// match device.authenticate_admin("12345678") { /// Ok(mut admin) => { /// match admin.erase_hotp_slot(1) { @@ -112,7 +112,7 @@ pub trait ConfigureOtp { /// Err(err) => eprintln!("Could not erase slot: {}", err), /// } /// }, - /// Err((_, err)) => eprintln!("Could not authenticate as admin: {}", err), + /// Err(err) => eprintln!("Could not authenticate as admin: {}", err), /// } /// # Ok(()) /// # } @@ -134,7 +134,7 @@ pub trait ConfigureOtp { /// # use nitrokey::Error; /// /// # fn try_main() -> Result<(), Error> { - /// let device = nitrokey::connect()?; + /// let mut device = nitrokey::connect()?; /// match device.authenticate_admin("12345678") { /// Ok(mut admin) => { /// match admin.erase_totp_slot(1) { @@ -142,7 +142,7 @@ pub trait ConfigureOtp { /// Err(err) => eprintln!("Could not erase slot: {}", err), /// } /// }, - /// Err((_, err)) => eprintln!("Could not authenticate as admin: {}", err), + /// Err(err) => eprintln!("Could not authenticate as admin: {}", err), /// } /// # Ok(()) /// # } -- cgit v1.2.1