From adbfa1c12257405112445497324938a011db8664 Mon Sep 17 00:00:00 2001 From: Robin Krahl Date: Fri, 25 Sep 2020 02:06:00 +0200 Subject: Update nitrokey to v0.8.0 This patch updates the nitrokey dependency to version 0.8.0 and applies all breaking changes (Config fields renaming, DeviceWrapper and Model non-exhaustiveness, changed Display implementation for Model). --- src/arg_util.rs | 2 +- src/args.rs | 14 ++++++++++++++ src/commands.rs | 28 +++++++++------------------- src/pinentry.rs | 4 ++-- src/tests/list.rs | 2 +- src/tests/mod.rs | 1 + src/tests/run.rs | 40 ++++++++++++++++++++++++++-------------- src/tests/status.rs | 4 ++-- 8 files changed, 56 insertions(+), 39 deletions(-) (limited to 'src') diff --git a/src/arg_util.rs b/src/arg_util.rs index b1dd60f..563cfd3 100644 --- a/src/arg_util.rs +++ b/src/arg_util.rs @@ -54,7 +54,7 @@ macro_rules! Command { macro_rules! Enum { ( $(#[$docs:meta])* $name:ident, [ $( $var:ident => $str:expr, ) *] ) => { $(#[$docs])* - #[derive(Clone, Copy, Debug, PartialEq)] + #[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)] pub enum $name { $( $var, diff --git a/src/args.rs b/src/args.rs index 8af38ca..e4bc77d 100644 --- a/src/args.rs +++ b/src/args.rs @@ -3,6 +3,8 @@ // Copyright (C) 2020 The Nitrocli Developers // SPDX-License-Identifier: GPL-3.0-or-later +use std::convert; + /// Provides access to a Nitrokey device #[derive(Debug, structopt::StructOpt)] #[structopt(name = "nitrocli")] @@ -59,6 +61,18 @@ impl From for nitrokey::Model { } } +impl convert::TryFrom for DeviceModel { + type Error = anyhow::Error; + + fn try_from(model: nitrokey::Model) -> Result { + match model { + nitrokey::Model::Pro => Ok(DeviceModel::Pro), + nitrokey::Model::Storage => Ok(DeviceModel::Storage), + _ => Err(anyhow::anyhow!("Unsupported device model: {}", model)), + } + } +} + impl<'de> serde::Deserialize<'de> for DeviceModel { fn deserialize(deserializer: D) -> Result where diff --git a/src/commands.rs b/src/commands.rs index 9685050..c5a3b11 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -370,11 +370,7 @@ fn print_storage_status( } /// Query and pretty print the status that is common to all Nitrokey devices. -fn print_status( - ctx: &mut Context<'_>, - model: &'static str, - device: &nitrokey::DeviceWrapper<'_>, -) -> anyhow::Result<()> { +fn print_status(ctx: &mut Context<'_>, device: &nitrokey::DeviceWrapper<'_>) -> anyhow::Result<()> { let serial_number = device .get_serial_number() .context("Could not query the serial number")?; @@ -387,7 +383,7 @@ fn print_status( firmware version: {fwv} user retry count: {urc} admin retry count: {arc}"#, - model = model, + model = device.get_model(), id = serial_number, fwv = device .get_firmware_version() @@ -416,13 +412,7 @@ fn print_status( /// Inquire the status of the nitrokey. pub fn status(ctx: &mut Context<'_>) -> anyhow::Result<()> { - with_device(ctx, |ctx, device| { - let model = match device { - nitrokey::DeviceWrapper::Pro(_) => "Pro", - nitrokey::DeviceWrapper::Storage(_) => "Storage", - }; - print_status(ctx, model, &device) - }) + with_device(ctx, |ctx, device| print_status(ctx, &device)) } /// List the attached Nitrokey devices. @@ -671,9 +661,9 @@ pub fn config_get(ctx: &mut Context<'_>) -> anyhow::Result<()> { capslock binding: {cl} scrollock binding: {sl} require user PIN for OTP: {otp}"#, - nl = format_option(config.numlock), - cl = format_option(config.capslock), - sl = format_option(config.scrollock), + nl = format_option(config.num_lock), + cl = format_option(config.caps_lock), + sl = format_option(config.scroll_lock), otp = config.user_password, )?; Ok(()) @@ -702,9 +692,9 @@ pub fn config_set(ctx: &mut Context<'_>, args: args::ConfigSetArgs) -> anyhow::R .get_config() .context("Failed to get current configuration")?; let config = nitrokey::Config { - numlock: numlock.or(config.numlock), - capslock: capslock.or(config.capslock), - scrollock: scrollock.or(config.scrollock), + num_lock: numlock.or(config.num_lock), + caps_lock: capslock.or(config.caps_lock), + scroll_lock: scrollock.or(config.scroll_lock), user_password: otp_pin.unwrap_or(config.user_password), }; device diff --git a/src/pinentry.rs b/src/pinentry.rs index 3bf67c1..40d916f 100644 --- a/src/pinentry.rs +++ b/src/pinentry.rs @@ -77,7 +77,7 @@ impl SecretEntry for PinEntry { fn description(&self, mode: Mode) -> CowStr { format!( - "{} for\rNitrokey {} {}", + "{} for\r {} {}", match self.pin_type { args::PinType::Admin => match mode { Mode::Choose => "Please enter a new admin PIN", @@ -135,7 +135,7 @@ impl SecretEntry for PwdEntry { fn description(&self, mode: Mode) -> CowStr { format!( - "{} for\rNitrokey {} {}", + "{} for\r {} {}", match mode { Mode::Choose => "Please enter a new hidden volume password", Mode::Confirm => "Please confirm the new hidden volume password", diff --git a/src/tests/list.rs b/src/tests/list.rs index cc969c6..e9f9506 100644 --- a/src/tests/list.rs +++ b/src/tests/list.rs @@ -17,7 +17,7 @@ fn not_connected() -> anyhow::Result<()> { fn connected(model: nitrokey::Model) -> anyhow::Result<()> { let re = regex::Regex::new( r#"^USB path\tmodel\tserial number -([[:^space:]]+\t(Pro|Storage|unknown)\t0x[[:xdigit:]]+ +([[:^space:]]+\t(Nitrokey Pro|Nitrokey Storage|unknown)\t0x[[:xdigit:]]+ )+$"#, ) .unwrap(); diff --git a/src/tests/mod.rs b/src/tests/mod.rs index 1871f3c..23eecc5 100644 --- a/src/tests/mod.rs +++ b/src/tests/mod.rs @@ -78,6 +78,7 @@ impl Nitrocli { match model { nitrokey::Model::Pro => "--model=pro", nitrokey::Model::Storage => "--model=storage", + _ => panic!("Unexpected model in test suite: {}", model), } } diff --git a/src/tests/run.rs b/src/tests/run.rs index b39b1da..c4f8a6b 100644 --- a/src/tests/run.rs +++ b/src/tests/run.rs @@ -7,6 +7,7 @@ use std::collections; use std::ops; use std::path; +use crate::args; use super::*; #[test] @@ -171,34 +172,37 @@ fn connect_wrong_usb_path(_model: nitrokey::Model) { #[test_device] fn connect_model(_model: nitrokey::Model) -> anyhow::Result<()> { + use std::convert::TryInto; + let devices = nitrokey::list_devices()?; let mut model_counts = collections::BTreeMap::new(); - let _ = model_counts.insert(nitrokey::Model::Pro.to_string(), 0); - let _ = model_counts.insert(nitrokey::Model::Storage.to_string(), 0); - for model in devices.iter().filter_map(|d| d.model) { - *model_counts.entry(model.to_string()).or_default() += 1; + let _ = model_counts.insert(args::DeviceModel::Pro, 0); + let _ = model_counts.insert(args::DeviceModel::Storage, 0); + for nkmodel in devices.iter().filter_map(|d| d.model) { + let model: args::DeviceModel = nkmodel.try_into().expect("Unexpected Nitrokey model"); + *model_counts.entry(model).or_default() += 1; } for (model, count) in model_counts { - let res = Nitrocli::new().handle(&["status", &format!("--model={}", model.to_lowercase())]); + let res = Nitrocli::new().handle(&["status", &format!("--model={}", model)]); if count == 0 { let err = res.unwrap_err().to_string(); assert_eq!( err, format!( "Nitrokey device not found (filter: model={})", - model.to_lowercase() + model ) ); } else if count == 1 { - assert!(res?.contains(&format!("model: {}\n", model))); + assert!(res?.contains(&format!("model: {}\n", nitrokey::Model::from(model)))); } else { let err = res.unwrap_err().to_string(); assert_eq!( err, format!( "Multiple Nitrokey devices found (filter: model={}). ", - model.to_lowercase() + model ) + "Use the --model, --serial-number, and --usb-path options to select one" ); } @@ -211,11 +215,15 @@ fn connect_model(_model: nitrokey::Model) -> anyhow::Result<()> { fn connect_usb_path_model_serial(_model: nitrokey::Model) -> anyhow::Result<()> { let devices = nitrokey::list_devices()?; for device in devices { + let model: Option = device.model.map(|nkmodel| { + use std::convert::TryInto; + nkmodel.try_into().expect("Unexpected Nitrokey model") + }); let mut args = Vec::new(); args.push("status".to_owned()); args.push(format!("--usb-path={}", device.path)); - if let Some(model) = device.model { - args.push(format!("--model={}", model.to_string().to_lowercase())); + if let Some(model) = model { + args.push(format!("--model={}", model)); } if let Some(sn) = device.serial_number { args.push(format!("--serial-number={}", sn)); @@ -236,22 +244,26 @@ fn connect_usb_path_model_serial(_model: nitrokey::Model) -> anyhow::Result<()> fn connect_usb_path_model_wrong_serial(_model: nitrokey::Model) -> anyhow::Result<()> { let devices = nitrokey::list_devices()?; for device in devices { + let model: Option = device.model.map(|nkmodel| { + use std::convert::TryInto; + nkmodel.try_into().expect("Unexpected Nitrokey model") + }); let mut args = Vec::new(); args.push("status".to_owned()); args.push(format!("--usb-path={}", device.path)); - if let Some(model) = device.model { - args.push(format!("--model={}", model.to_string().to_lowercase())); + if let Some(model) = model { + args.push(format!("--model={}", model)); } args.push("--serial-number=0xdeadbeef".to_owned()); let res = Nitrocli::new().handle(&args.iter().map(ops::Deref::deref).collect::>()); let err = res.unwrap_err().to_string(); - if let Some(model) = device.model { + if let Some(model) = model { assert_eq!( err, format!( "Nitrokey device not found (filter: model={}, serial number in [0xdeadbeef], usb path={})", - model.to_string().to_lowercase(), + model, device.path ) ); diff --git a/src/tests/status.rs b/src/tests/status.rs index ca16121..873bc69 100644 --- a/src/tests/status.rs +++ b/src/tests/status.rs @@ -25,7 +25,7 @@ fn not_found() { fn output_pro(model: nitrokey::Model) -> anyhow::Result<()> { let re = regex::Regex::new( r#"^Status: - model: Pro + model: Nitrokey Pro serial number: 0x[[:xdigit:]]{8} firmware version: v\d+\.\d+ user retry count: [0-3] @@ -43,7 +43,7 @@ $"#, fn output_storage(model: nitrokey::Model) -> anyhow::Result<()> { let re = regex::Regex::new( r#"^Status: - model: Storage + model: Nitrokey Storage serial number: 0x[[:xdigit:]]{8} firmware version: v\d+\.\d+ user retry count: [0-3] -- cgit v1.2.3