diff options
author | Daniel Mueller <deso@posteo.net> | 2019-07-14 19:19:04 -0700 |
---|---|---|
committer | Daniel Mueller <deso@posteo.net> | 2019-07-14 19:19:04 -0700 |
commit | 49f5194e16db47b6de9847b79840c6fe35e0df8c (patch) | |
tree | 613e28edd2cfc542045ea32ec6e86afc2ccf04e7 | |
parent | f3a1b0b3c3cd628ecbfa45c3023956d44a4154a4 (diff) | |
download | nitrocli-49f5194e16db47b6de9847b79840c6fe35e0df8c.tar.gz nitrocli-49f5194e16db47b6de9847b79840c6fe35e0df8c.tar.bz2 |
Introduce with_password_safe function
Similar to the with_*device functions introduced in a previous change,
this change introduces a with_password_safe function that is a short
hand for opening the Nitrokey, retrieving a handle to the password safe,
and invoking a user-supplied function on it.
This function will allow us to prevent life time inference problems
caused by passing around a PasswordSafe object, which will contain an
additional reference (and with that, lifetime) in nitrokey version 0.4.
-rw-r--r-- | nitrocli/src/commands.rs | 49 | ||||
-rw-r--r-- | nitrocli/src/error.rs | 9 |
2 files changed, 35 insertions, 23 deletions
diff --git a/nitrocli/src/commands.rs b/nitrocli/src/commands.rs index ea91727..b5fc282 100644 --- a/nitrocli/src/commands.rs +++ b/nitrocli/src/commands.rs @@ -28,6 +28,7 @@ use libc::sync; use nitrokey::ConfigureOtp; use nitrokey::Device; use nitrokey::GenerateOtp; +use nitrokey::GetPasswordSafe; use crate::args; use crate::error; @@ -96,23 +97,29 @@ where op(ctx, device) } -/// Open the password safe on the given device. -fn get_password_safe<'dev, D>( - ctx: &mut args::ExecCtx<'_>, - device: &'dev D, -) -> Result<nitrokey::PasswordSafe<'dev>> +/// Connect to any Nitrokey device, retrieve a password safe handle, and +/// do something with it. +fn with_password_safe<F>(ctx: &mut args::ExecCtx<'_>, mut op: F) -> Result<()> where - D: Device, + F: FnMut(&mut args::ExecCtx<'_>, nitrokey::PasswordSafe<'_>) -> Result<()>, { - let pin_entry = pinentry::PinEntry::from(pinentry::PinType::User, device)?; - - try_with_pin_and_data( - ctx, - &pin_entry, - "Could not access the password safe", - (), - |_ctx, _, pin| device.get_password_safe(pin).map_err(|err| ((), err)), - ) + with_device(ctx, |ctx, device| { + let pin_entry = pinentry::PinEntry::from(pinentry::PinType::User, &device)?; + try_with_pin_and_data( + ctx, + &pin_entry, + "Could not access the password safe", + (), + move |ctx, _, pin| { + let pws = device + .get_password_safe(pin) + .map_err(|err| ((), Error::from(err)))?; + + op(ctx, pws).map_err(|err| ((), err)) + }, + ) + })?; + Ok(()) } /// Authenticate the given device using the given PIN type and operation. @@ -851,8 +858,7 @@ pub fn pws_get( show_password: bool, quiet: bool, ) -> Result<()> { - with_device(ctx, |ctx, device| { - let pws = get_password_safe(ctx, &device)?; + with_password_safe(ctx, |ctx, pws| { check_slot(&pws, slot)?; let show_all = !show_name && !show_login && !show_password; @@ -877,8 +883,7 @@ pub fn pws_set( login: &str, password: &str, ) -> Result<()> { - with_device(ctx, |ctx, device| { - let pws = get_password_safe(ctx, &device)?; + with_password_safe(ctx, |_ctx, pws| { pws .write_slot(slot, name, login, password) .map_err(|err| get_error("Could not write PWS slot", err)) @@ -887,8 +892,7 @@ pub fn pws_set( /// Clear a PWS slot. pub fn pws_clear(ctx: &mut args::ExecCtx<'_>, slot: u8) -> Result<()> { - with_device(ctx, |ctx, device| { - let pws = get_password_safe(ctx, &device)?; + with_password_safe(ctx, |_ctx, pws| { pws .erase_slot(slot) .map_err(|err| get_error("Could not clear PWS slot", err)) @@ -918,8 +922,7 @@ fn print_pws_slot( /// Print the status of all PWS slots. pub fn pws_status(ctx: &mut args::ExecCtx<'_>, all: bool) -> Result<()> { - with_device(ctx, |ctx, device| { - let pws = get_password_safe(ctx, &device)?; + with_password_safe(ctx, |ctx, pws| { let slots = pws .get_slot_status() .map_err(|err| get_error("Could not read PWS slot status", err))?; diff --git a/nitrocli/src/error.rs b/nitrocli/src/error.rs index d1eb2eb..c0e7403 100644 --- a/nitrocli/src/error.rs +++ b/nitrocli/src/error.rs @@ -47,6 +47,15 @@ pub enum Error { Error(String), } +impl TryInto<nitrokey::CommandError> for Error { + fn try_into(self) -> Result<nitrokey::CommandError, Error> { + match self { + Error::CommandError(_, err) => Ok(err), + err => Err(err), + } + } +} + impl From<&str> for Error { fn from(s: &str) -> Error { Error::Error(s.to_string()) |