diff options
| author | Robin Krahl <robin.krahl@ireas.org> | 2018-05-22 21:41:30 +0000 | 
|---|---|---|
| committer | Robin Krahl <robin.krahl@ireas.org> | 2018-05-22 23:42:18 +0200 | 
| commit | 2ec913fdcadef73281ec30f96c0fc7cd00a4ed26 (patch) | |
| tree | fa70814910ced501f6b63030cc783127b928898e /src | |
| parent | 105dcead4890bee529f4ae9833892cdd1a4f8014 (diff) | |
| download | nitrokey-rs-2ec913fdcadef73281ec30f96c0fc7cd00a4ed26.tar.gz nitrokey-rs-2ec913fdcadef73281ec30f96c0fc7cd00a4ed26.tar.bz2 | |
Move the authenticate methods to a new Authenticate trait
Diffstat (limited to 'src')
| -rw-r--r-- | src/device.rs | 121 | ||||
| -rw-r--r-- | src/lib.rs | 8 | ||||
| -rw-r--r-- | src/otp.rs | 8 | ||||
| -rw-r--r-- | src/tests/pro.rs | 2 | 
4 files changed, 80 insertions, 59 deletions
| diff --git a/src/device.rs b/src/device.rs index ce45a50..ab90d3d 100644 --- a/src/device.rs +++ b/src/device.rs @@ -28,7 +28,7 @@ pub enum Model {  /// Authentication with error handling:  ///  /// ```no_run -/// use nitrokey::{UnauthenticatedDevice, UserAuthenticatedDevice}; +/// use nitrokey::{Authenticate, UnauthenticatedDevice, UserAuthenticatedDevice};  /// # use nitrokey::CommandError;  ///  /// fn perform_user_task(device: &UserAuthenticatedDevice) {} @@ -51,8 +51,8 @@ pub enum Model {  /// # }  /// ```  /// -/// [`authenticate_admin`]: #method.authenticate_admin -/// [`authenticate_user`]: #method.authenticate_user +/// [`authenticate_admin`]: trait.Authenticate.html#method.authenticate_admin +/// [`authenticate_user`]: trait.Authenticate.html#method.authenticate_user  /// [`connect`]: fn.connect.html  /// [`connect_model`]: fn.connect_model.html  #[derive(Debug)] @@ -64,7 +64,7 @@ pub struct UnauthenticatedDevice {}  /// method on an [`UnauthenticatedDevice`][].  To get back to an  /// unauthenticated device, use the [`device`][] method.  /// -/// [`authenticate_admin`]: struct.UnauthenticatedDevice#method.authenticate_admin +/// [`authenticate_admin`]: trait.Authenticate.html#method.authenticate_admin  /// [`device`]: #method.device  /// [`UnauthenticatedDevice`]: struct.UnauthenticatedDevice.html  #[derive(Debug)] @@ -79,7 +79,7 @@ pub struct UserAuthenticatedDevice {  /// method on an [`UnauthenticatedDevice`][].  To get back to an  /// unauthenticated device, use the [`device`][] method.  /// -/// [`authenticate_admin`]: struct.UnauthenticatedDevice#method.authenticate_admin +/// [`authenticate_admin`]: trait.Authenticate.html#method.authenticate_admin  /// [`device`]: #method.device  /// [`UnauthenticatedDevice`]: struct.UnauthenticatedDevice.html  #[derive(Debug)] @@ -350,38 +350,10 @@ pub trait Device {      }  } -trait AuthenticatedDevice { -    fn new(device: UnauthenticatedDevice, temp_password: Vec<u8>) -> Self; -} - -impl UnauthenticatedDevice { -    fn authenticate<D, T>( -        self, -        password: &str, -        callback: T, -    ) -> Result<D, (UnauthenticatedDevice, CommandError)> -    where -        D: AuthenticatedDevice, -        T: Fn(*const i8, *const i8) -> c_int, -    { -        let temp_password = match generate_password(TEMPORARY_PASSWORD_LENGTH) { -            Ok(pw) => pw, -            Err(_) => return Err((self, CommandError::RngError)), -        }; -        let password = CString::new(password); -        if password.is_err() { -            return Err((self, CommandError::InvalidString)); -        } - -        let pw = password.unwrap(); -        let password_ptr = pw.as_ptr(); -        let temp_password_ptr = temp_password.as_ptr() as *const i8; -        return match callback(password_ptr, temp_password_ptr) { -            0 => Ok(D::new(self, temp_password)), -            rv => Err((self, CommandError::from(rv))), -        }; -    } - +/// Provides methods to authenticate as a user or as an admin using a PIN.  The authenticated +/// methods will consume the current device instance.  On success, they return the authenticated +/// device.  Otherwise, they return the current unauthenticated device and the error code. +pub trait Authenticate {      /// Performs user authentication.  This method consumes the device.  If      /// successful, an authenticated device is returned.  Otherwise, the      /// current unauthenticated device and the error are returned. @@ -398,7 +370,7 @@ impl UnauthenticatedDevice {      /// # Example      ///      /// ```no_run -    /// use nitrokey::{UnauthenticatedDevice, UserAuthenticatedDevice}; +    /// use nitrokey::{Authenticate, UnauthenticatedDevice, UserAuthenticatedDevice};      /// # use nitrokey::CommandError;      ///      /// fn perform_user_task(device: &UserAuthenticatedDevice) {} @@ -424,14 +396,12 @@ impl UnauthenticatedDevice {      /// [`InvalidString`]: enum.CommandError.html#variant.InvalidString      /// [`RngError`]: enum.CommandError.html#variant.RngError      /// [`WrongPassword`]: enum.CommandError.html#variant.WrongPassword -    pub fn authenticate_user( +    fn authenticate_user(          self,          password: &str, -    ) -> Result<UserAuthenticatedDevice, (UnauthenticatedDevice, CommandError)> { -        return self.authenticate(password, |password_ptr, temp_password_ptr| unsafe { -            nitrokey_sys::NK_user_authenticate(password_ptr, temp_password_ptr) -        }); -    } +    ) -> Result<UserAuthenticatedDevice, (Self, CommandError)> +    where +        Self: Sized;      /// Performs admin authentication.  This method consumes the device.  If      /// successful, an authenticated device is returned.  Otherwise, the @@ -449,7 +419,7 @@ impl UnauthenticatedDevice {      /// # Example      ///      /// ```no_run -    /// use nitrokey::{AdminAuthenticatedDevice, UnauthenticatedDevice}; +    /// use nitrokey::{Authenticate, AdminAuthenticatedDevice, UnauthenticatedDevice};      /// # use nitrokey::CommandError;      ///      /// fn perform_admin_task(device: &AdminAuthenticatedDevice) {} @@ -475,10 +445,61 @@ impl UnauthenticatedDevice {      /// [`InvalidString`]: enum.CommandError.html#variant.InvalidString      /// [`RngError`]: enum.CommandError.html#variant.RngError      /// [`WrongPassword`]: enum.CommandError.html#variant.WrongPassword -    pub fn authenticate_admin( +    fn authenticate_admin( +        self, +        password: &str, +    ) -> Result<AdminAuthenticatedDevice, (Self, CommandError)> +    where +        Self: Sized; +} + +trait AuthenticatedDevice { +    fn new(device: UnauthenticatedDevice, temp_password: Vec<u8>) -> Self; +} + +impl UnauthenticatedDevice { +    fn authenticate<D, T>( +        self, +        password: &str, +        callback: T, +    ) -> Result<D, (UnauthenticatedDevice, CommandError)> +    where +        D: AuthenticatedDevice, +        T: Fn(*const i8, *const i8) -> c_int, +    { +        let temp_password = match generate_password(TEMPORARY_PASSWORD_LENGTH) { +            Ok(pw) => pw, +            Err(_) => return Err((self, CommandError::RngError)), +        }; +        let password = CString::new(password); +        if password.is_err() { +            return Err((self, CommandError::InvalidString)); +        } + +        let pw = password.unwrap(); +        let password_ptr = pw.as_ptr(); +        let temp_password_ptr = temp_password.as_ptr() as *const i8; +        return match callback(password_ptr, temp_password_ptr) { +            0 => Ok(D::new(self, temp_password)), +            rv => Err((self, CommandError::from(rv))), +        }; +    } +} + +impl Authenticate for UnauthenticatedDevice { +    fn authenticate_user( +        self, +        password: &str, +    ) -> Result<UserAuthenticatedDevice, (Self, CommandError)> { +        return self.authenticate(password, |password_ptr, temp_password_ptr| unsafe { +            nitrokey_sys::NK_user_authenticate(password_ptr, temp_password_ptr) +        }); +    } + +    fn authenticate_admin(          self,          password: &str, -    ) -> Result<AdminAuthenticatedDevice, (UnauthenticatedDevice, CommandError)> { +    ) -> Result<AdminAuthenticatedDevice, (Self, CommandError)> {          return self.authenticate(password, |password_ptr, temp_password_ptr| unsafe {              nitrokey_sys::NK_first_authenticate(password_ptr, temp_password_ptr)          }); @@ -521,7 +542,7 @@ impl GenerateOtp for UserAuthenticatedDevice {      /// # Example      ///      /// ```no_run -    /// use nitrokey::{Device, GenerateOtp}; +    /// use nitrokey::{Authenticate, GenerateOtp};      /// # use nitrokey::CommandError;      ///      /// # fn try_main() -> Result<(), CommandError> { @@ -562,7 +583,7 @@ impl GenerateOtp for UserAuthenticatedDevice {      /// # Example      ///      /// ```no_run -    /// use nitrokey::{Device, GenerateOtp}; +    /// use nitrokey::{Authenticate, GenerateOtp};      /// # use nitrokey::CommandError;      ///      /// # fn try_main() -> Result<(), CommandError> { @@ -623,7 +644,7 @@ impl AdminAuthenticatedDevice {      /// # Example      ///      /// ```no_run -    /// use nitrokey::Config; +    /// use nitrokey::{Authenticate, Config};      /// # use nitrokey::CommandError;      ///      /// # fn try_main() -> Result<(), CommandError> { @@ -38,7 +38,7 @@  //! Configure an HOTP slot:  //!  //! ```no_run -//! use nitrokey::{CommandStatus, ConfigureOtp, Device, OtpMode, OtpSlotData}; +//! use nitrokey::{Authenticate, CommandStatus, ConfigureOtp, OtpMode, OtpSlotData};  //! # use nitrokey::CommandError;  //!  //! # fn try_main() -> Result<(), (CommandError)> { @@ -73,8 +73,8 @@  //! # }  //! ```  //! -//! [`authenticate_admin`]: struct.UnauthenticatedDevice.html#method.authenticate_admin -//! [`authenticate_user`]: struct.UnauthenticatedDevice.html#method.authenticate_user +//! [`authenticate_admin`]: trait.Authenticate.html#method.authenticate_admin +//! [`authenticate_user`]: trait.Authenticate.html#method.authenticate_user  //! [`connect`]: fn.connect.html  //! [`connect_model`]: fn.connect_model.html  //! [`device`]: struct.AuthenticatedDevice.html#method.device @@ -96,7 +96,7 @@ mod util;  mod tests;  pub use config::Config; -pub use device::{AdminAuthenticatedDevice, Device, Model, UnauthenticatedDevice, +pub use device::{AdminAuthenticatedDevice, Authenticate, Device, Model, UnauthenticatedDevice,                   UserAuthenticatedDevice};  pub use otp::{ConfigureOtp, GenerateOtp, OtpMode, OtpSlotData};  pub use util::{CommandError, CommandStatus, LogLevel}; @@ -25,7 +25,7 @@ pub trait ConfigureOtp {      /// # Example      ///      /// ```no_run -    /// use nitrokey::{CommandStatus, ConfigureOtp, OtpMode, OtpSlotData}; +    /// use nitrokey::{Authenticate, CommandStatus, ConfigureOtp, OtpMode, OtpSlotData};      /// # use nitrokey::CommandError;      ///      /// # fn try_main() -> Result<(), (CommandError)> { @@ -61,7 +61,7 @@ pub trait ConfigureOtp {      /// # Example      ///      /// ```no_run -    /// use nitrokey::{CommandStatus, ConfigureOtp, OtpMode, OtpSlotData}; +    /// use nitrokey::{Authenticate, CommandStatus, ConfigureOtp, OtpMode, OtpSlotData};      /// # use nitrokey::CommandError;      ///      /// # fn try_main() -> Result<(), (CommandError)> { @@ -94,7 +94,7 @@ pub trait ConfigureOtp {      /// # Example      ///      /// ```no_run -    /// use nitrokey::{CommandStatus, ConfigureOtp}; +    /// use nitrokey::{Authenticate, CommandStatus, ConfigureOtp};      /// # use nitrokey::CommandError;      ///      /// # fn try_main() -> Result<(), (CommandError)> { @@ -124,7 +124,7 @@ pub trait ConfigureOtp {      /// # Example      ///      /// ```no_run -    /// use nitrokey::{CommandStatus, ConfigureOtp}; +    /// use nitrokey::{Authenticate, CommandStatus, ConfigureOtp};      /// # use nitrokey::CommandError;      ///      /// # fn try_main() -> Result<(), (CommandError)> { diff --git a/src/tests/pro.rs b/src/tests/pro.rs index 71daa78..8476451 100644 --- a/src/tests/pro.rs +++ b/src/tests/pro.rs @@ -1,5 +1,5 @@  use std::ffi::CStr; -use {AdminAuthenticatedDevice, CommandError, CommandStatus, Config, ConfigureOtp, +use {AdminAuthenticatedDevice, Authenticate, CommandError, CommandStatus, Config, ConfigureOtp,       Device, GenerateOtp, Model, OtpMode, OtpSlotData, UnauthenticatedDevice};  static ADMIN_PASSWORD: &str = "12345678"; | 
