diff options
| author | Robin Krahl <robin.krahl@ireas.org> | 2019-01-17 04:15:31 +0000 | 
|---|---|---|
| committer | Robin Krahl <robin.krahl@ireas.org> | 2019-01-20 21:08:26 +0000 | 
| commit | 944e1fa0d51e547dde2a9368d2b8431b109f63c4 (patch) | |
| tree | 0a8b2d5bb9a00149cefb6eecaaf8ac556e961690 | |
| parent | cafc3a6f8cfb9f82343c1d3fe843c7f8d7ef1136 (diff) | |
| download | nitrokey-rs-944e1fa0d51e547dde2a9368d2b8431b109f63c4.tar.gz nitrokey-rs-944e1fa0d51e547dde2a9368d2b8431b109f63c4.tar.bz2 | |
Move the CommandError::Unknown to Error
An error code can not only indiciate a command error, but also a library
or device communication error.  Therefore, the variant for an unknown
error code should be placed in the top-level Error enum instead of the
CommandError enum.
| -rw-r--r-- | CHANGELOG.md | 3 | ||||
| -rw-r--r-- | src/auth.rs | 4 | ||||
| -rw-r--r-- | src/error.rs | 61 | ||||
| -rw-r--r-- | src/util.rs | 2 | ||||
| -rw-r--r-- | tests/pws.rs | 2 | 
5 files changed, 40 insertions, 32 deletions
| diff --git a/CHANGELOG.md b/CHANGELOG.md index 5a78724..def5273 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,8 @@    - Implement `std::error::Error` for `CommandError`.    - Add the `Error` enum and the `Result` typedef.    - Return `Error` instead of `CommandError` in all public functions. -  - Move the `CommandError::RngError` variant to `Error::RandError`. +  - Move the `CommandError::RngError` variant to `Error::RandError` and the +    `CommandError::Unknown` variant to `Error::Unknown`.  # v0.3.4 (2019-01-20)  - Fix authentication methods that assumed that `char` is signed. diff --git a/src/auth.rs b/src/auth.rs index 509d3aa..e05f6b3 100644 --- a/src/auth.rs +++ b/src/auth.rs @@ -6,7 +6,7 @@ use nitrokey_sys;  use crate::config::{Config, RawConfig};  use crate::device::{Device, DeviceWrapper, Pro, Storage}; -use crate::error::{CommandError, Error}; +use crate::error::Error;  use crate::otp::{ConfigureOtp, GenerateOtp, OtpMode, OtpSlotData, RawOtpSlotData};  use crate::util::{generate_password, get_command_result, get_cstring, result_from_string}; @@ -161,7 +161,7 @@ where      let temp_password_ptr = temp_password.as_ptr() as *const c_char;      return match callback(password_ptr, temp_password_ptr) {          0 => Ok(A::new(device, temp_password)), -        rv => Err((device, CommandError::from(rv).into())), +        rv => Err((device, Error::from(rv))),      };  } diff --git a/src/error.rs b/src/error.rs index dfe1680..c5a975e 100644 --- a/src/error.rs +++ b/src/error.rs @@ -13,6 +13,18 @@ pub enum Error {      CommunicationError(CommunicationError),      /// An error that occured during random number generation.      RandError(rand_core::Error), +    /// An unknown error returned by libnitrokey. +    Unknown(i64), +} + +impl From<raw::c_int> for Error { +    fn from(code: raw::c_int) -> Self { +        if let Some(err) = CommandError::try_from(code) { +            Error::CommandError(err) +        } else { +            Error::Unknown(code.into()) +        } +    }  }  impl From<CommandError> for Error { @@ -33,6 +45,7 @@ impl error::Error for Error {              Error::CommandError(ref err) => Some(err),              Error::CommunicationError(_) => None,              Error::RandError(ref err) => Some(err), +            Error::Unknown(_) => None,          }      }  } @@ -43,6 +56,7 @@ impl fmt::Display for Error {              Error::CommandError(ref err) => write!(f, "Command error: {}", err),              Error::CommunicationError(_) => write!(f, "Placeholder"),              Error::RandError(ref err) => write!(f, "RNG error: {}", err), +            Error::Unknown(ref err) => write!(f, "Unknown error: {}", err),          }      }  } @@ -74,8 +88,6 @@ pub enum CommandError {      UnknownCommand,      /// AES decryption failed.      AesDecryptionFailed, -    /// An unknown error occurred. -    Unknown(i64),      /// An unspecified error occurred.      Undefined,      /// You passed a string containing a null byte. @@ -98,6 +110,26 @@ pub enum CommunicationError {  }  impl CommandError { +    fn try_from(value: raw::c_int) -> Option<Self> { +        match value { +            1 => Some(CommandError::WrongCrc), +            2 => Some(CommandError::WrongSlot), +            3 => Some(CommandError::SlotNotProgrammed), +            4 => Some(CommandError::WrongPassword), +            5 => Some(CommandError::NotAuthorized), +            6 => Some(CommandError::Timestamp), +            7 => Some(CommandError::NoName), +            8 => Some(CommandError::NotSupported), +            9 => Some(CommandError::UnknownCommand), +            10 => Some(CommandError::AesDecryptionFailed), +            200 => Some(CommandError::StringTooLong), +            201 => Some(CommandError::InvalidSlot), +            202 => Some(CommandError::InvalidHexString), +            203 => Some(CommandError::TargetBufferTooSmall), +            _ => None, +        } +    } +      fn as_str(&self) -> borrow::Cow<'static, str> {          match *self {              CommandError::WrongCrc => { @@ -116,9 +148,6 @@ impl CommandError {              CommandError::NotSupported => "This command is not supported by this device".into(),              CommandError::UnknownCommand => "This command is unknown".into(),              CommandError::AesDecryptionFailed => "AES decryption failed".into(), -            CommandError::Unknown(x) => { -                borrow::Cow::from(format!("An unknown error occurred ({})", x)) -            }              CommandError::Undefined => "An unspecified error occurred".into(),              CommandError::InvalidString => "You passed a string containing a null byte".into(),              CommandError::StringTooLong => "The supplied string is too long".into(), @@ -138,25 +167,3 @@ impl fmt::Display for CommandError {          write!(f, "{}", self.as_str())      }  } - -impl From<raw::c_int> for CommandError { -    fn from(value: raw::c_int) -> Self { -        match value { -            1 => CommandError::WrongCrc, -            2 => CommandError::WrongSlot, -            3 => CommandError::SlotNotProgrammed, -            4 => CommandError::WrongPassword, -            5 => CommandError::NotAuthorized, -            6 => CommandError::Timestamp, -            7 => CommandError::NoName, -            8 => CommandError::NotSupported, -            9 => CommandError::UnknownCommand, -            10 => CommandError::AesDecryptionFailed, -            200 => CommandError::StringTooLong, -            201 => CommandError::InvalidSlot, -            202 => CommandError::InvalidHexString, -            203 => CommandError::TargetBufferTooSmall, -            x => CommandError::Unknown(x.into()), -        } -    } -} diff --git a/src/util.rs b/src/util.rs index 06bb854..3b9904f 100644 --- a/src/util.rs +++ b/src/util.rs @@ -54,7 +54,7 @@ pub fn result_from_string(ptr: *const c_char) -> Result<String, Error> {  pub fn get_command_result(value: c_int) -> Result<(), Error> {      match value {          0 => Ok(()), -        other => Err(CommandError::from(other).into()), +        other => Err(Error::from(other)),      }  } diff --git a/tests/pws.rs b/tests/pws.rs index f12af48..a4647bd 100644 --- a/tests/pws.rs +++ b/tests/pws.rs @@ -21,7 +21,7 @@ fn get_slot_name_direct(slot: u8) -> Result<String, Error> {              let error = unsafe { nitrokey_sys::NK_get_last_command_status() } as c_int;              match error {                  0 => Ok(s), -                other => Err(CommandError::from(other).into()), +                other => Err(Error::from(other)),              }          }          false => Ok(s), | 
