diff options
Diffstat (limited to 'nitrokey')
-rw-r--r-- | nitrokey/CHANGELOG.md | 13 | ||||
-rw-r--r-- | nitrokey/Cargo.toml | 6 | ||||
-rw-r--r-- | nitrokey/README.md | 15 | ||||
-rw-r--r-- | nitrokey/src/auth.rs | 14 | ||||
-rw-r--r-- | nitrokey/src/config.rs | 2 | ||||
-rw-r--r-- | nitrokey/src/device.rs | 99 | ||||
-rw-r--r-- | nitrokey/src/lib.rs | 22 | ||||
-rw-r--r-- | nitrokey/src/otp.rs | 8 | ||||
-rw-r--r-- | nitrokey/src/pws.rs | 19 | ||||
-rw-r--r-- | nitrokey/src/tests/mod.rs | 4 | ||||
-rw-r--r-- | nitrokey/src/tests/util.rs | 11 | ||||
-rw-r--r-- | nitrokey/src/util.rs | 19 | ||||
-rw-r--r-- | nitrokey/tests/device.rs (renamed from nitrokey/src/tests/device.rs) | 109 | ||||
-rw-r--r-- | nitrokey/tests/otp.rs (renamed from nitrokey/src/tests/otp.rs) | 10 | ||||
-rw-r--r-- | nitrokey/tests/pws.rs (renamed from nitrokey/src/tests/pws.rs) | 45 | ||||
-rw-r--r-- | nitrokey/tests/util/mod.rs | 8 |
16 files changed, 260 insertions, 144 deletions
diff --git a/nitrokey/CHANGELOG.md b/nitrokey/CHANGELOG.md index a60d6a7..5064d4f 100644 --- a/nitrokey/CHANGELOG.md +++ b/nitrokey/CHANGELOG.md @@ -1,3 +1,16 @@ +# v0.2.3 (2018-12-31) + +- Dummy release to fix an issue with the crates.io tarball. + +# v0.2.2 (2018-12-30) + +- Update to Rust edition 2018. +- Remove the `test-no-device` feature. +- Update the rand dependency to version 0.6. +- Add function `Device::get_model` that returns the connected model. +- Derive the `Copy` and `Clone` traits for the enums `CommandError`, `LogLevel` + and `OtpMode` + # v0.2.1 (2018-12-10) - Re-export `device::{StorageStatus, VolumeStatus}` in `lib.rs`. diff --git a/nitrokey/Cargo.toml b/nitrokey/Cargo.toml index dad751b..6369fba 100644 --- a/nitrokey/Cargo.toml +++ b/nitrokey/Cargo.toml @@ -1,7 +1,8 @@ [package] name = "nitrokey" -version = "0.2.1" +version = "0.2.3" authors = ["Robin Krahl <robin.krahl@ireas.org>"] +edition = "2018" homepage = "https://code.ireas.org/nitrokey-rs/" repository = "https://git.ireas.org/nitrokey-rs/" documentation = "https://docs.rs/nitrokey" @@ -12,11 +13,10 @@ readme = "README.md" license = "MIT" [features] -test-no-device = [] test-pro = [] test-storage = [] [dependencies] libc = "0.2" nitrokey-sys = "3.4.1" -rand = "0.4" +rand = "0.6" diff --git a/nitrokey/README.md b/nitrokey/README.md index 6039943..568b1d4 100644 --- a/nitrokey/README.md +++ b/nitrokey/README.md @@ -4,11 +4,6 @@ A libnitrokey wrapper for Rust providing access to Nitrokey devices. [Documentation][] -```toml -[dependencies] -nitrokey = "0.2.1" -``` - ## Compatibility The required [`libnitrokey`][] version is built from source. The host system @@ -35,12 +30,12 @@ supported by `nitrokey-rs`: ## Tests This crate has three test suites that can be selected using features. One test -suite (feature `test-no-device`) assumes that no Nitrokey device is connected. -The two other test suites require a Nitrokey Pro (feature `test-pro`) or a -Nitrokey Storage (feature `test-storage`) to be connected. +suite assumes that no Nitrokey device is connected. It is run if no other test +suite is selected. The two other test suites require a Nitrokey Pro (feature +`test-pro`) or a Nitrokey Storage (feature `test-storage`) to be connected. Use the `--features` option for Cargo to select one of the test suites. You -cannot select more than one of the test suites at the same time. Note that the +should select more than one of the test suites at the same time. Note that the test suites that require a Nitrokey device assume that the device’s passwords are the factory defaults (admin password `12345678` and user password `123456`). Running the test suite with a device with different passwords might @@ -54,7 +49,7 @@ the test executable. In conclusion, you can use these commands to run the test suites: ``` -$ cargo test --features test-no-device -- --test-threads 1 +$ cargo test $ cargo test --features test-pro -- --test-threads 1 $ cargo test --features test-storage -- --test-threads 1 ``` diff --git a/nitrokey/src/auth.rs b/nitrokey/src/auth.rs index 0918222..017cdbb 100644 --- a/nitrokey/src/auth.rs +++ b/nitrokey/src/auth.rs @@ -1,10 +1,14 @@ -use config::{Config, RawConfig}; -use device::{Device, DeviceWrapper, Pro, Storage}; -use nitrokey_sys; -use otp::{ConfigureOtp, GenerateOtp, OtpMode, OtpSlotData, RawOtpSlotData}; use std::ops::Deref; use std::os::raw::c_int; -use util::{generate_password, get_command_result, get_cstring, result_from_string, CommandError}; + +use nitrokey_sys; + +use crate::config::{Config, RawConfig}; +use crate::device::{Device, DeviceWrapper, Pro, Storage}; +use crate::otp::{ConfigureOtp, GenerateOtp, OtpMode, OtpSlotData, RawOtpSlotData}; +use crate::util::{ + generate_password, get_command_result, get_cstring, result_from_string, CommandError, +}; static TEMPORARY_PASSWORD_LENGTH: usize = 25; diff --git a/nitrokey/src/config.rs b/nitrokey/src/config.rs index 33bf256..2ce6f77 100644 --- a/nitrokey/src/config.rs +++ b/nitrokey/src/config.rs @@ -1,4 +1,4 @@ -use util::CommandError; +use crate::util::CommandError; /// The configuration for a Nitrokey. #[derive(Clone, Copy, Debug, PartialEq)] diff --git a/nitrokey/src/device.rs b/nitrokey/src/device.rs index f135261..9c6608d 100644 --- a/nitrokey/src/device.rs +++ b/nitrokey/src/device.rs @@ -1,20 +1,38 @@ -use auth::Authenticate; -use config::{Config, RawConfig}; +use std::fmt; + use libc; use nitrokey_sys; -use otp::GenerateOtp; -use pws::GetPasswordSafe; -use util::{get_command_result, get_cstring, get_last_error, result_from_string, CommandError}; + +use crate::auth::Authenticate; +use crate::config::{Config, RawConfig}; +use crate::otp::GenerateOtp; +use crate::pws::GetPasswordSafe; +use crate::util::{ + get_command_result, get_cstring, get_last_error, result_from_string, CommandError, +}; /// Available Nitrokey models. -#[derive(Debug, PartialEq)] -enum Model { +#[derive(Clone, Copy, Debug, PartialEq)] +pub enum Model { /// The Nitrokey Storage. Storage, /// The Nitrokey Pro. Pro, } +impl fmt::Display for Model { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!( + f, + "{}", + match *self { + Model::Pro => "Pro", + Model::Storage => "Storage", + } + ) + } +} + /// A wrapper for a Nitrokey device of unknown type. /// /// Use the function [`connect`][] to obtain a wrapped instance. The wrapper implements all traits @@ -210,6 +228,21 @@ pub struct StorageStatus { /// This trait provides the commands that can be executed without authentication and that are /// present on all supported Nitrokey devices. pub trait Device: Authenticate + GetPasswordSafe + GenerateOtp { + /// Returns the model of the connected Nitrokey device. + /// + /// # Example + /// + /// ```no_run + /// use nitrokey::Device; + /// # use nitrokey::CommandError; + /// + /// # fn try_main() -> Result<(), CommandError> { + /// let device = nitrokey::connect()?; + /// println!("Connected to a Nitrokey {}", device.get_model()); + /// # Ok(()) + /// # } + fn get_model(&self) -> Model; + /// Returns the serial number of the Nitrokey device. The serial number is the string /// representation of a hex number. /// @@ -536,7 +569,7 @@ fn connect_model(model: Model) -> bool { } impl DeviceWrapper { - fn device(&self) -> &Device { + fn device(&self) -> &dyn Device { match *self { DeviceWrapper::Storage(ref storage) => storage, DeviceWrapper::Pro(ref pro) => pro, @@ -562,9 +595,30 @@ impl GenerateOtp for DeviceWrapper { } } -impl Device for DeviceWrapper {} +impl Device for DeviceWrapper { + fn get_model(&self) -> Model { + match *self { + DeviceWrapper::Pro(_) => Model::Pro, + DeviceWrapper::Storage(_) => Model::Storage, + } + } +} impl Pro { + /// Connects to a Nitrokey Pro. + /// + /// # Example + /// + /// ``` + /// use nitrokey::Pro; + /// + /// fn use_pro(device: Pro) {} + /// + /// match nitrokey::Pro::connect() { + /// Ok(device) => use_pro(device), + /// Err(err) => println!("Could not connect to the Nitrokey Pro: {}", err), + /// } + /// ``` pub fn connect() -> Result<Pro, CommandError> { // TODO: maybe Option instead of Result? match connect_model(Model::Pro) { @@ -582,11 +636,29 @@ impl Drop for Pro { } } -impl Device for Pro {} +impl Device for Pro { + fn get_model(&self) -> Model { + Model::Pro + } +} impl GenerateOtp for Pro {} impl Storage { + /// Connects to a Nitrokey Storage. + /// + /// # Example + /// + /// ``` + /// use nitrokey::Storage; + /// + /// fn use_storage(device: Storage) {} + /// + /// match nitrokey::Storage::connect() { + /// Ok(device) => use_storage(device), + /// Err(err) => println!("Could not connect to the Nitrokey Storage: {}", err), + /// } + /// ``` pub fn connect() -> Result<Storage, CommandError> { // TODO: maybe Option instead of Result? match connect_model(Model::Storage) { @@ -661,7 +733,6 @@ impl Storage { unsafe { get_command_result(nitrokey_sys::NK_lock_encrypted_volume()) } } - /// Returns the status of the connected storage device. /// /// # Example @@ -715,7 +786,11 @@ impl Drop for Storage { } } -impl Device for Storage {} +impl Device for Storage { + fn get_model(&self) -> Model { + Model::Storage + } +} impl GenerateOtp for Storage {} diff --git a/nitrokey/src/lib.rs b/nitrokey/src/lib.rs index e70aa73..9f21518 100644 --- a/nitrokey/src/lib.rs +++ b/nitrokey/src/lib.rs @@ -84,25 +84,25 @@ //! [`DeviceWrapper`]: enum.DeviceWrapper.html //! [`User`]: struct.User.html -extern crate libc; -extern crate nitrokey_sys; -extern crate rand; +#![warn(missing_docs, rust_2018_compatibility, rust_2018_idioms, unused)] mod auth; mod config; mod device; mod otp; mod pws; -#[cfg(test)] -mod tests; mod util; -pub use auth::{Admin, Authenticate, User}; -pub use config::Config; -pub use device::{connect, Device, DeviceWrapper, Pro, Storage, StorageStatus, VolumeStatus}; -pub use otp::{ConfigureOtp, GenerateOtp, OtpMode, OtpSlotData}; -pub use pws::{GetPasswordSafe, PasswordSafe, SLOT_COUNT}; -pub use util::{CommandError, LogLevel}; +use nitrokey_sys; + +pub use crate::auth::{Admin, Authenticate, User}; +pub use crate::config::Config; +pub use crate::device::{ + connect, Device, DeviceWrapper, Model, Pro, Storage, StorageStatus, VolumeStatus, +}; +pub use crate::otp::{ConfigureOtp, GenerateOtp, OtpMode, OtpSlotData}; +pub use crate::pws::{GetPasswordSafe, PasswordSafe, SLOT_COUNT}; +pub use crate::util::{CommandError, LogLevel}; /// Enables or disables debug output. Calling this method with `true` is equivalent to setting the /// log level to `Debug`; calling it with `false` is equivalent to the log level `Error` (see diff --git a/nitrokey/src/otp.rs b/nitrokey/src/otp.rs index 00a5e5e..6f6bd80 100644 --- a/nitrokey/src/otp.rs +++ b/nitrokey/src/otp.rs @@ -1,9 +1,11 @@ -use nitrokey_sys; use std::ffi::CString; -use util::{get_command_result, get_cstring, result_from_string, CommandError}; + +use nitrokey_sys; + +use crate::util::{get_command_result, get_cstring, result_from_string, CommandError}; /// Modes for one-time password generation. -#[derive(Debug, PartialEq)] +#[derive(Clone, Copy, Debug, PartialEq)] pub enum OtpMode { /// Generate one-time passwords with six digits. SixDigits, diff --git a/nitrokey/src/pws.rs b/nitrokey/src/pws.rs index c20fe9d..08ac365 100644 --- a/nitrokey/src/pws.rs +++ b/nitrokey/src/pws.rs @@ -1,7 +1,10 @@ -use device::{Device, DeviceWrapper, Pro, Storage}; use libc; use nitrokey_sys; -use util::{get_command_result, get_cstring, get_last_error, result_from_string, CommandError}; + +use crate::device::{Device, DeviceWrapper, Pro, Storage}; +use crate::util::{ + get_command_result, get_cstring, get_last_error, result_from_string, CommandError, +}; /// The number of slots in a [`PasswordSafe`][]. /// @@ -51,7 +54,7 @@ pub const SLOT_COUNT: u8 = 16; /// [`lock`]: trait.Device.html#method.lock /// [`GetPasswordSafe`]: trait.GetPasswordSafe.html pub struct PasswordSafe<'a> { - _device: &'a Device, + _device: &'a dyn Device, } /// Provides access to a [`PasswordSafe`][]. @@ -98,11 +101,11 @@ pub trait GetPasswordSafe { /// [`lock`]: trait.Device.html#method.lock /// [`InvalidString`]: enum.CommandError.html#variant.InvalidString /// [`WrongPassword`]: enum.CommandError.html#variant.WrongPassword - fn get_password_safe(&self, user_pin: &str) -> Result<PasswordSafe, CommandError>; + fn get_password_safe(&self, user_pin: &str) -> Result<PasswordSafe<'_>, CommandError>; } fn get_password_safe<'a>( - device: &'a Device, + device: &'a dyn Device, user_pin: &str, ) -> Result<PasswordSafe<'a>, CommandError> { let user_pin_string = get_cstring(user_pin)?; @@ -333,19 +336,19 @@ impl<'a> Drop for PasswordSafe<'a> { } impl GetPasswordSafe for Pro { - fn get_password_safe(&self, user_pin: &str) -> Result<PasswordSafe, CommandError> { + fn get_password_safe(&self, user_pin: &str) -> Result<PasswordSafe<'_>, CommandError> { get_password_safe(self, user_pin) } } impl GetPasswordSafe for Storage { - fn get_password_safe(&self, user_pin: &str) -> Result<PasswordSafe, CommandError> { + fn get_password_safe(&self, user_pin: &str) -> Result<PasswordSafe<'_>, CommandError> { get_password_safe(self, user_pin) } } impl GetPasswordSafe for DeviceWrapper { - fn get_password_safe(&self, user_pin: &str) -> Result<PasswordSafe, CommandError> { + fn get_password_safe(&self, user_pin: &str) -> Result<PasswordSafe<'_>, CommandError> { get_password_safe(self, user_pin) } } diff --git a/nitrokey/src/tests/mod.rs b/nitrokey/src/tests/mod.rs deleted file mode 100644 index 34ca0aa..0000000 --- a/nitrokey/src/tests/mod.rs +++ /dev/null @@ -1,4 +0,0 @@ -mod device; -mod otp; -mod pws; -mod util; diff --git a/nitrokey/src/tests/util.rs b/nitrokey/src/tests/util.rs deleted file mode 100644 index c6fbb8f..0000000 --- a/nitrokey/src/tests/util.rs +++ /dev/null @@ -1,11 +0,0 @@ -pub static ADMIN_PASSWORD: &str = "12345678"; -pub static USER_PASSWORD: &str = "123456"; - -#[cfg(feature = "test-no-device")] -pub type Target = ::Pro; - -#[cfg(feature = "test-pro")] -pub type Target = ::Pro; - -#[cfg(feature = "test-storage")] -pub type Target = ::Storage; diff --git a/nitrokey/src/util.rs b/nitrokey/src/util.rs index 6f4fbb0..a2e957e 100644 --- a/nitrokey/src/util.rs +++ b/nitrokey/src/util.rs @@ -1,13 +1,12 @@ -use libc::{c_void, free}; -use nitrokey_sys; -use rand::{OsRng, Rng}; -use std; use std::ffi::{CStr, CString}; use std::fmt; use std::os::raw::{c_char, c_int}; +use libc::{c_void, free}; +use rand::Rng; + /// Error types returned by Nitrokey device or by the library. -#[derive(Debug, PartialEq)] +#[derive(Clone, Copy, Debug, PartialEq)] pub enum CommandError { /// A packet with a wrong checksum has been sent or received. WrongCrc, @@ -44,7 +43,7 @@ pub enum CommandError { /// /// Setting the log level to a lower level enables all output from higher levels too. Currently, /// only the log levels `Warning`, `DebugL1`, `Debug` and `DebugL2` are actually used. -#[derive(Debug, PartialEq)] +#[derive(Clone, Copy, Debug, PartialEq)] pub enum LogLevel { /// Error messages. Currently not used. Error, @@ -101,12 +100,8 @@ pub fn get_last_error() -> CommandError { } pub fn generate_password(length: usize) -> std::io::Result<Vec<u8>> { - let mut rng = match OsRng::new() { - Ok(rng) => rng, - Err(err) => return Err(err), - }; let mut data = vec![0u8; length]; - rng.fill_bytes(&mut data[..]); + rand::thread_rng().fill(&mut data[..]); return Ok(data); } @@ -115,7 +110,7 @@ pub fn get_cstring<T: Into<Vec<u8>>>(s: T) -> Result<CString, CommandError> { } impl fmt::Display for CommandError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let msg = match *self { CommandError::WrongCrc => "A packet with a wrong checksum has been sent or received", CommandError::WrongSlot => "The given OTP slot does not exist", diff --git a/nitrokey/src/tests/device.rs b/nitrokey/tests/device.rs index fed465d..26afa62 100644 --- a/nitrokey/src/tests/device.rs +++ b/nitrokey/tests/device.rs @@ -1,8 +1,12 @@ +mod util; + use std::ffi::CStr; use std::process::Command; use std::{thread, time}; -use tests::util::{Target, ADMIN_PASSWORD, USER_PASSWORD}; -use {Authenticate, CommandError, Config, Device, Storage}; + +use nitrokey::{Authenticate, CommandError, Config, Device, Storage}; + +use crate::util::{Target, ADMIN_PASSWORD, USER_PASSWORD}; static ADMIN_NEW_PASSWORD: &str = "1234567890"; static USER_NEW_PASSWORD: &str = "abcdefghij"; @@ -15,45 +19,45 @@ fn count_nitrokey_block_devices() -> usize { .expect("Could not list block devices"); String::from_utf8_lossy(&output.stdout) .split("\n") - .filter(|&s| s == "Nitrokey Storage") + .filter(|&s| s.replace("_", " ") == "Nitrokey Storage") .count() } #[test] -#[cfg_attr(not(feature = "test-no-device"), ignore)] +#[cfg_attr(any(feature = "test-pro", feature = "test-storage"), ignore)] fn connect_no_device() { - assert!(::connect().is_err()); - assert!(::Pro::connect().is_err()); - assert!(::Storage::connect().is_err()); + assert!(nitrokey::connect().is_err()); + assert!(nitrokey::Pro::connect().is_err()); + assert!(nitrokey::Storage::connect().is_err()); } #[test] #[cfg_attr(not(feature = "test-pro"), ignore)] fn connect_pro() { - assert!(::connect().is_ok()); - assert!(::Pro::connect().is_ok()); - assert!(::Storage::connect().is_err()); - match ::connect().unwrap() { - ::DeviceWrapper::Pro(_) => assert!(true), - ::DeviceWrapper::Storage(_) => assert!(false), + assert!(nitrokey::connect().is_ok()); + assert!(nitrokey::Pro::connect().is_ok()); + assert!(nitrokey::Storage::connect().is_err()); + match nitrokey::connect().unwrap() { + nitrokey::DeviceWrapper::Pro(_) => assert!(true), + nitrokey::DeviceWrapper::Storage(_) => assert!(false), }; } #[test] #[cfg_attr(not(feature = "test-storage"), ignore)] fn connect_storage() { - assert!(::connect().is_ok()); - assert!(::Pro::connect().is_err()); - assert!(::Storage::connect().is_ok()); - match ::connect().unwrap() { - ::DeviceWrapper::Pro(_) => assert!(false), - ::DeviceWrapper::Storage(_) => assert!(true), + assert!(nitrokey::connect().is_ok()); + assert!(nitrokey::Pro::connect().is_err()); + assert!(nitrokey::Storage::connect().is_ok()); + match nitrokey::connect().unwrap() { + nitrokey::DeviceWrapper::Pro(_) => assert!(false), + nitrokey::DeviceWrapper::Storage(_) => assert!(true), }; } fn assert_empty_serial_number() { unsafe { - let ptr = ::nitrokey_sys::NK_device_serial_number(); + let ptr = nitrokey_sys::NK_device_serial_number(); assert!(!ptr.is_null()); let cstr = CStr::from_ptr(ptr); assert_eq!(cstr.to_string_lossy(), ""); @@ -77,6 +81,23 @@ fn disconnect() { assert_empty_serial_number(); } +fn require_model(model: nitrokey::Model) { + assert_eq!(model, nitrokey::connect().unwrap().get_model()); + assert_eq!(model, Target::connect().unwrap().get_model()); +} + +#[test] +#[cfg_attr(not(feature = "test-pro"), ignore)] +fn get_model_pro() { + require_model(nitrokey::Model::Pro); +} + +#[test] +#[cfg_attr(not(feature = "test-storage"), ignore)] +fn get_model_storage() { + require_model(nitrokey::Model::Storage); +} + #[test] #[cfg_attr(not(any(feature = "test-pro", feature = "test-storage")), ignore)] fn get_serial_number() { @@ -163,11 +184,9 @@ fn change_user_pin() { let device = device.authenticate_user(USER_PASSWORD).unwrap().device(); let device = device.authenticate_user(USER_NEW_PASSWORD).unwrap_err().0; - assert!( - device - .change_user_pin(USER_PASSWORD, USER_NEW_PASSWORD) - .is_ok() - ); + assert!(device + .change_user_pin(USER_PASSWORD, USER_NEW_PASSWORD) + .is_ok()); let device = device.authenticate_user(USER_PASSWORD).unwrap_err().0; let device = device @@ -178,11 +197,9 @@ fn change_user_pin() { let result = device.change_user_pin(USER_PASSWORD, USER_PASSWORD); assert_eq!(Err(CommandError::WrongPassword), result); - assert!( - device - .change_user_pin(USER_NEW_PASSWORD, USER_PASSWORD) - .is_ok() - ); + assert!(device + .change_user_pin(USER_NEW_PASSWORD, USER_PASSWORD) + .is_ok()); let device = device.authenticate_user(USER_PASSWORD).unwrap().device(); assert!(device.authenticate_user(USER_NEW_PASSWORD).is_err()); @@ -195,11 +212,9 @@ fn change_admin_pin() { let device = device.authenticate_admin(ADMIN_PASSWORD).unwrap().device(); let device = device.authenticate_admin(ADMIN_NEW_PASSWORD).unwrap_err().0; - assert!( - device - .change_admin_pin(ADMIN_PASSWORD, ADMIN_NEW_PASSWORD) - .is_ok() - ); + assert!(device + .change_admin_pin(ADMIN_PASSWORD, ADMIN_NEW_PASSWORD) + .is_ok()); let device = device.authenticate_admin(ADMIN_PASSWORD).unwrap_err().0; let device = device @@ -212,11 +227,9 @@ fn change_admin_pin() { device.change_admin_pin(ADMIN_PASSWORD, ADMIN_PASSWORD) ); - assert!( - device - .change_admin_pin(ADMIN_NEW_PASSWORD, ADMIN_PASSWORD) - .is_ok() - ); + assert!(device + .change_admin_pin(ADMIN_NEW_PASSWORD, ADMIN_PASSWORD) + .is_ok()); let device = device.authenticate_admin(ADMIN_PASSWORD).unwrap().device(); device.authenticate_admin(ADMIN_NEW_PASSWORD).unwrap_err(); @@ -235,11 +248,9 @@ fn require_failed_user_login(device: Target, password: &str, error: CommandError fn unlock_user_pin() { let device = Target::connect().unwrap(); let device = device.authenticate_user(USER_PASSWORD).unwrap().device(); - assert!( - device - .unlock_user_pin(ADMIN_PASSWORD, USER_PASSWORD) - .is_ok() - ); + assert!(device + .unlock_user_pin(ADMIN_PASSWORD, USER_PASSWORD) + .is_ok()); assert_eq!( Err(CommandError::WrongPassword), device.unlock_user_pin(USER_PASSWORD, USER_PASSWORD) @@ -255,11 +266,9 @@ fn unlock_user_pin() { Err(CommandError::WrongPassword), device.unlock_user_pin(USER_PASSWORD, USER_PASSWORD) ); - assert!( - device - .unlock_user_pin(ADMIN_PASSWORD, USER_PASSWORD) - .is_ok() - ); + assert!(device + .unlock_user_pin(ADMIN_PASSWORD, USER_PASSWORD) + .is_ok()); device.authenticate_user(USER_PASSWORD).unwrap(); } diff --git a/nitrokey/src/tests/otp.rs b/nitrokey/tests/otp.rs index cf71d9d..8e7ae08 100644 --- a/nitrokey/src/tests/otp.rs +++ b/nitrokey/tests/otp.rs @@ -1,6 +1,12 @@ +mod util; + use std::ops::Deref; -use tests::util::{Target, ADMIN_PASSWORD, USER_PASSWORD}; -use {Admin, Authenticate, CommandError, Config, ConfigureOtp, GenerateOtp, OtpMode, OtpSlotData}; + +use nitrokey::{ + Admin, Authenticate, CommandError, Config, ConfigureOtp, GenerateOtp, OtpMode, OtpSlotData, +}; + +use crate::util::{Target, ADMIN_PASSWORD, USER_PASSWORD}; // test suite according to RFC 4226, Appendix D static HOTP_SECRET: &str = "3132333435363738393031323334353637383930"; diff --git a/nitrokey/src/tests/pws.rs b/nitrokey/tests/pws.rs index f581515..875324b 100644 --- a/nitrokey/src/tests/pws.rs +++ b/nitrokey/tests/pws.rs @@ -1,8 +1,31 @@ -use device::Device; +mod util; + +use std::ffi::CStr; + +use libc::{c_int, c_void, free}; +use nitrokey::{CommandError, Device, GetPasswordSafe, PasswordSafe, SLOT_COUNT}; use nitrokey_sys; -use pws::{GetPasswordSafe, PasswordSafe, SLOT_COUNT}; -use tests::util::{Target, ADMIN_PASSWORD, USER_PASSWORD}; -use util::{result_from_string, CommandError}; + +use crate::util::{Target, ADMIN_PASSWORD, USER_PASSWORD}; + +fn get_slot_name_direct(slot: u8) -> Result<String, CommandError> { + let ptr = unsafe { nitrokey_sys::NK_get_password_safe_slot_name(slot) }; + if ptr.is_null() { + return Err(CommandError::Unknown); + } + let s = unsafe { CStr::from_ptr(ptr).to_string_lossy().into_owned() }; + unsafe { free(ptr as *mut c_void) }; + match s.is_empty() { + true => { + let error = unsafe { nitrokey_sys::NK_get_last_command_status() } as c_int; + match error { + 0 => Err(CommandError::Unknown), + other => Err(CommandError::from(other)), + } + } + false => Ok(s), + } +} fn get_pws(device: &Target) -> PasswordSafe { device.get_password_safe(USER_PASSWORD).unwrap() @@ -12,11 +35,9 @@ fn get_pws(device: &Target) -> PasswordSafe { #[cfg_attr(not(any(feature = "test-pro", feature = "test-storage")), ignore)] fn enable() { let device = Target::connect().unwrap(); - assert!( - device - .get_password_safe(&(USER_PASSWORD.to_owned() + "123")) - .is_err() - ); + assert!(device + .get_password_safe(&(USER_PASSWORD.to_owned() + "123")) + .is_err()); assert!(device.get_password_safe(USER_PASSWORD).is_ok()); assert!(device.get_password_safe(ADMIN_PASSWORD).is_err()); assert!(device.get_password_safe(USER_PASSWORD).is_ok()); @@ -30,13 +51,13 @@ fn drop() { let pws = get_pws(&device); assert!(pws.write_slot(1, "name", "login", "password").is_ok()); assert_eq!("name", pws.get_slot_name(1).unwrap()); - let result = result_from_string(unsafe { nitrokey_sys::NK_get_password_safe_slot_name(1) }); + let result = get_slot_name_direct(1); assert_eq!(Ok(String::from("name")), result); } - let result = result_from_string(unsafe { nitrokey_sys::NK_get_password_safe_slot_name(1) }); + let result = get_slot_name_direct(1); assert_eq!(Ok(String::from("name")), result); assert!(device.lock().is_ok()); - let result = result_from_string(unsafe { nitrokey_sys::NK_get_password_safe_slot_name(1) }); + let result = get_slot_name_direct(1); assert_eq!(Err(CommandError::NotAuthorized), result); } diff --git a/nitrokey/tests/util/mod.rs b/nitrokey/tests/util/mod.rs new file mode 100644 index 0000000..c2c94e2 --- /dev/null +++ b/nitrokey/tests/util/mod.rs @@ -0,0 +1,8 @@ +pub static ADMIN_PASSWORD: &str = "12345678"; +pub static USER_PASSWORD: &str = "123456"; + +#[cfg(not(feature = "test-storage"))] +pub type Target = nitrokey::Pro; + +#[cfg(feature = "test-storage")] +pub type Target = nitrokey::Storage; |