From 6fce98ec044241abd1d0f54dca307af6cd9f648f 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). --- CHANGELOG.md | 1 + Cargo.lock | 8 ++++---- Cargo.toml | 2 +- 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 | 44 +++++++++++++++++++++++++++----------------- src/tests/status.rs | 4 ++-- 11 files changed, 63 insertions(+), 47 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2a7e46a..a9ff80a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ Unreleased - Added SD card usage information to the output of the `status` command for Storage devices - Bumped `structopt` dependency to `0.3.17` +- Bumped `nitrokey` dependency to `0.8.0` 0.3.4 diff --git a/Cargo.lock b/Cargo.lock index 94126a2..4948736 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -223,9 +223,9 @@ dependencies = [ [[package]] name = "nitrokey" -version = "0.7.1" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62ad51d978a97a526a3501ec6f6304bdd1b6446be1b0302759421f6269b6bc4a" +checksum = "48059f1f469143fd371228e33893e6c76419daa9dcb8c0fac2bc1ef2fdfbb7b1" dependencies = [ "lazy_static", "libc", @@ -235,9 +235,9 @@ dependencies = [ [[package]] name = "nitrokey-sys" -version = "3.5.0" +version = "3.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71c6052aeb37309317d25c8fec2801f271b96c5a15656f2573d8e78ba4124c49" +checksum = "9a6f2fab053a9ac25b0818e9d107f71246b277cbfbe7d22400a0e38896a58321" dependencies = [ "cc", ] diff --git a/Cargo.toml b/Cargo.toml index a24cc81..4fbed9d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -51,7 +51,7 @@ version = "0.2" version = "0.1" [dependencies.nitrokey] -version = "0.7.1" +version = "0.8" [dependencies.progressing] version = "3.0.2" 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 51ac32f..eba9276 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..33191d3 100644 --- a/src/tests/run.rs +++ b/src/tests/run.rs @@ -4,10 +4,13 @@ // SPDX-License-Identifier: GPL-3.0-or-later use std::collections; +use std::convert; +use std::convert::TryInto as _; use std::ops; use std::path; use super::*; +use crate::args; #[test] fn no_command_or_option() { @@ -173,32 +176,33 @@ fn connect_wrong_usb_path(_model: nitrokey::Model) { fn connect_model(_model: nitrokey::Model) -> anyhow::Result<()> { 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 = 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() - ) + format!("Nitrokey device not found (filter: model={})", 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,14 @@ 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 = device.model.map(|nkmodel| { + convert::TryInto::::try_into(nkmodel).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 +243,25 @@ 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 = device.model.map(|nkmodel| { + convert::TryInto::::try_into(nkmodel).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