diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/arg_util.rs | 2 | ||||
| -rw-r--r-- | src/args.rs | 14 | ||||
| -rw-r--r-- | src/commands.rs | 28 | ||||
| -rw-r--r-- | src/pinentry.rs | 4 | ||||
| -rw-r--r-- | src/tests/list.rs | 2 | ||||
| -rw-r--r-- | src/tests/mod.rs | 1 | ||||
| -rw-r--r-- | src/tests/run.rs | 40 | ||||
| -rw-r--r-- | src/tests/status.rs | 4 | 
8 files changed, 56 insertions, 39 deletions
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<DeviceModel> for nitrokey::Model {    }  } +impl convert::TryFrom<nitrokey::Model> for DeviceModel { +  type Error = anyhow::Error; + +  fn try_from(model: nitrokey::Model) -> Result<DeviceModel, anyhow::Error> { +    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<D>(deserializer: D) -> Result<DeviceModel, D::Error>    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<args::DeviceModel> = 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<args::DeviceModel> = 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::<Vec<_>>());      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]  | 
