From d66616a4fa71609231688119c40a3a0ec39a17ab Mon Sep 17 00:00:00 2001 From: Robin Krahl Date: Thu, 7 Jun 2018 03:21:57 +0200 Subject: Implement easier CString creation The new get_cstring method in util returns a Result, so mast callers can just use the ? operator to unwrap the result instead of cumbersome unwrapping code. --- src/auth.rs | 15 ++++++--------- src/device.rs | 36 ++++++++---------------------------- src/otp.rs | 17 +++++++---------- src/pws.rs | 26 +++++++------------------- src/util.rs | 6 +++++- 5 files changed, 33 insertions(+), 67 deletions(-) (limited to 'src') diff --git a/src/auth.rs b/src/auth.rs index 62b851f..8460fae 100644 --- a/src/auth.rs +++ b/src/auth.rs @@ -2,10 +2,9 @@ use config::{Config, RawConfig}; use device::{Device, DeviceWrapper, Pro, Storage}; use nitrokey_sys; use otp::{ConfigureOtp, GenerateOtp, OtpMode, OtpSlotData, RawOtpSlotData}; -use std::ffi::CString; use std::ops::Deref; use std::os::raw::c_int; -use util::{generate_password, get_command_result, result_from_string, CommandError}; +use util::{generate_password, get_command_result, get_cstring, result_from_string, CommandError}; static TEMPORARY_PASSWORD_LENGTH: usize = 25; @@ -150,13 +149,11 @@ where Ok(pw) => pw, Err(_) => return Err((device, CommandError::RngError)), }; - let password = CString::new(password); - if password.is_err() { - return Err((device, CommandError::InvalidString)); - } - - let pw = password.unwrap(); - let password_ptr = pw.as_ptr(); + let password = match get_cstring(password) { + Ok(password) => password, + Err(err) => return Err((device, err)), + }; + let password_ptr = password.as_ptr(); let temp_password_ptr = temp_password.as_ptr() as *const i8; return match callback(password_ptr, temp_password_ptr) { 0 => Ok(A::new(device, temp_password)), diff --git a/src/device.rs b/src/device.rs index c4e83a9..63a5654 100644 --- a/src/device.rs +++ b/src/device.rs @@ -4,8 +4,7 @@ use libc; use nitrokey_sys; use otp::GenerateOtp; use pws::GetPasswordSafe; -use std::ffi::CString; -use util::{get_command_result, get_last_error, result_from_string, CommandError}; +use util::{get_command_result, get_cstring, get_last_error, result_from_string, CommandError}; /// Available Nitrokey models. #[derive(Debug, PartialEq)] @@ -312,13 +311,8 @@ pub trait Device: Authenticate + GetPasswordSafe + GenerateOtp { /// [`InvalidString`]: enum.CommandError.html#variant.InvalidString /// [`WrongPassword`]: enum.CommandError.html#variant.WrongPassword fn change_admin_pin(&self, current: &str, new: &str) -> Result<(), CommandError> { - let current_string = CString::new(current); - let new_string = CString::new(new); - if current_string.is_err() || new_string.is_err() { - return Err(CommandError::InvalidString); - } - let current_string = current_string.unwrap(); - let new_string = new_string.unwrap(); + let current_string = get_cstring(current)?; + let new_string = get_cstring(new)?; unsafe { get_command_result(nitrokey_sys::NK_change_admin_PIN( current_string.as_ptr(), @@ -353,13 +347,8 @@ pub trait Device: Authenticate + GetPasswordSafe + GenerateOtp { /// [`InvalidString`]: enum.CommandError.html#variant.InvalidString /// [`WrongPassword`]: enum.CommandError.html#variant.WrongPassword fn change_user_pin(&self, current: &str, new: &str) -> Result<(), CommandError> { - let current_string = CString::new(current); - let new_string = CString::new(new); - if current_string.is_err() || new_string.is_err() { - return Err(CommandError::InvalidString); - } - let current_string = current_string.unwrap(); - let new_string = new_string.unwrap(); + let current_string = get_cstring(current)?; + let new_string = get_cstring(new)?; unsafe { get_command_result(nitrokey_sys::NK_change_user_PIN( current_string.as_ptr(), @@ -394,13 +383,8 @@ pub trait Device: Authenticate + GetPasswordSafe + GenerateOtp { /// [`InvalidString`]: enum.CommandError.html#variant.InvalidString /// [`WrongPassword`]: enum.CommandError.html#variant.WrongPassword fn unlock_user_pin(&self, admin_pin: &str, user_pin: &str) -> Result<(), CommandError> { - let admin_pin_string = CString::new(admin_pin); - let user_pin_string = CString::new(user_pin); - if admin_pin_string.is_err() || user_pin_string.is_err() { - return Err(CommandError::InvalidString); - } - let admin_pin_string = admin_pin_string.unwrap(); - let user_pin_string = user_pin_string.unwrap(); + let admin_pin_string = get_cstring(admin_pin)?; + let user_pin_string = get_cstring(user_pin)?; unsafe { get_command_result(nitrokey_sys::NK_unlock_user_password( admin_pin_string.as_ptr(), @@ -562,11 +546,7 @@ impl Storage { /// [`InvalidString`]: enum.CommandError.html#variant.InvalidString /// [`WrongPassword`]: enum.CommandError.html#variant.WrongPassword pub fn enable_encrypted_volume(&self, user_pin: &str) -> Result<(), CommandError> { - let user_pin = CString::new(user_pin); - if user_pin.is_err() { - return Err(CommandError::InvalidString); - } - let user_pin = user_pin.unwrap(); + let user_pin = get_cstring(user_pin)?; unsafe { get_command_result(nitrokey_sys::NK_unlock_encrypted_volume(user_pin.as_ptr())) } } diff --git a/src/otp.rs b/src/otp.rs index 1094520..e43b1c8 100644 --- a/src/otp.rs +++ b/src/otp.rs @@ -1,6 +1,6 @@ use nitrokey_sys; use std::ffi::CString; -use util::{get_command_result, result_from_string, CommandError}; +use util::{get_command_result, get_cstring, result_from_string, CommandError}; /// Modes for one-time password generation. #[derive(Debug, PartialEq)] @@ -389,22 +389,19 @@ impl OtpSlotData { impl RawOtpSlotData { pub fn new(data: OtpSlotData) -> Result { - let name = CString::new(data.name); - let secret = CString::new(data.secret); + let name = get_cstring(data.name)?; + let secret = get_cstring(data.secret)?; let use_token_id = data.token_id.is_some(); - let token_id = CString::new(data.token_id.unwrap_or_else(String::new)); - if name.is_err() || secret.is_err() || token_id.is_err() { - return Err(CommandError::InvalidString); - } + let token_id = get_cstring(data.token_id.unwrap_or_else(String::new))?; Ok(RawOtpSlotData { number: data.number, - name: name.unwrap(), - secret: secret.unwrap(), + name, + secret, mode: data.mode, use_enter: data.use_enter, use_token_id, - token_id: token_id.unwrap(), + token_id, }) } } diff --git a/src/pws.rs b/src/pws.rs index bbc19aa..17f247e 100644 --- a/src/pws.rs +++ b/src/pws.rs @@ -1,8 +1,7 @@ use device::{Device, DeviceWrapper, Pro, Storage}; use libc; use nitrokey_sys; -use std::ffi::CString; -use util::{get_command_result, get_last_error, result_from_string, CommandError}; +use util::{get_command_result, get_cstring, get_last_error, result_from_string, CommandError}; /// The number of slots in a [`PasswordSafe`][]. /// @@ -42,7 +41,7 @@ pub const SLOT_COUNT: u8 = 16; /// let device = nitrokey::connect()?; /// let pws = device.get_password_safe("123456")?; /// use_password_safe(&pws); -/// device.lock(); +/// device.lock()?; /// # Ok(()) /// # } /// ``` @@ -87,7 +86,7 @@ pub trait GetPasswordSafe { /// match device.get_password_safe("123456") { /// Ok(pws) => { /// use_password_safe(&pws); - /// device.lock(); + /// device.lock()?; /// }, /// Err(err) => println!("Could not open the password safe: {:?}", err), /// }; @@ -106,11 +105,7 @@ fn get_password_safe<'a>( device: &'a Device, user_pin: &str, ) -> Result, CommandError> { - let user_pin_string = CString::new(user_pin); - if user_pin_string.is_err() { - return Err(CommandError::InvalidString); - } - let user_pin_string = user_pin_string.unwrap(); + let user_pin_string = get_cstring(user_pin)?; let result = unsafe { get_command_result(nitrokey_sys::NK_enable_password_safe( user_pin_string.as_ptr(), @@ -287,16 +282,9 @@ impl<'a> PasswordSafe<'a> { login: &str, password: &str, ) -> Result<(), CommandError> { - let name_string = CString::new(name); - let login_string = CString::new(login); - let password_string = CString::new(password); - if name_string.is_err() || login_string.is_err() || password_string.is_err() { - return Err(CommandError::InvalidString); - } - - let name_string = name_string.unwrap(); - let login_string = login_string.unwrap(); - let password_string = password_string.unwrap(); + let name_string = get_cstring(name)?; + let login_string = get_cstring(login)?; + let password_string = get_cstring(password)?; unsafe { get_command_result(nitrokey_sys::NK_write_password_safe_slot( slot, diff --git a/src/util.rs b/src/util.rs index 1608952..75de799 100644 --- a/src/util.rs +++ b/src/util.rs @@ -2,7 +2,7 @@ use libc::{c_void, free}; use nitrokey_sys; use rand::{OsRng, Rng}; use std; -use std::ffi::CStr; +use std::ffi::{CStr, CString}; use std::os::raw::{c_char, c_int}; /// Error types returned by Nitrokey device or by the library. @@ -110,6 +110,10 @@ pub fn generate_password(length: usize) -> std::io::Result> { return Ok(data); } +pub fn get_cstring>>(s: T) -> Result { + CString::new(s).or(Err(CommandError::InvalidString)) +} + impl From for CommandError { fn from(value: c_int) -> Self { match value { -- cgit v1.2.3