aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Mueller <deso@posteo.net>2019-07-14 19:19:04 -0700
committerDaniel Mueller <deso@posteo.net>2019-07-14 19:19:04 -0700
commit49f5194e16db47b6de9847b79840c6fe35e0df8c (patch)
tree613e28edd2cfc542045ea32ec6e86afc2ccf04e7
parentf3a1b0b3c3cd628ecbfa45c3023956d44a4154a4 (diff)
downloadnitrocli-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.rs49
-rw-r--r--nitrocli/src/error.rs9
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())