From 0c679b30ef04de8bc556ce33b305d3ccf740a970 Mon Sep 17 00:00:00 2001 From: Robin Krahl Date: Thu, 27 Dec 2018 17:49:14 +0100 Subject: Implement the pws status subcommand This patch implements the pws status command that can be used to print status information for the slots in the password safe. --- nitrocli/src/args.rs | 22 +++++++++++++++++++++- nitrocli/src/commands.rs | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/nitrocli/src/args.rs b/nitrocli/src/args.rs index 28ccb1f..4cf6258 100644 --- a/nitrocli/src/args.rs +++ b/nitrocli/src/args.rs @@ -329,6 +329,7 @@ enum PwsCommand { Clear, Get, Set, + Status, } impl PwsCommand { @@ -337,6 +338,7 @@ impl PwsCommand { PwsCommand::Clear => pws_clear(args), PwsCommand::Get => pws_get(args), PwsCommand::Set => pws_set(args), + PwsCommand::Status => pws_status(args), } } } @@ -350,6 +352,7 @@ impl fmt::Display for PwsCommand { PwsCommand::Clear => "clear", PwsCommand::Get => "get", PwsCommand::Set => "set", + PwsCommand::Status => "status", } ) } @@ -363,6 +366,7 @@ impl str::FromStr for PwsCommand { "clear" => Ok(PwsCommand::Clear), "get" => Ok(PwsCommand::Get), "set" => Ok(PwsCommand::Set), + "status" => Ok(PwsCommand::Status), _ => Err(()), } } @@ -804,7 +808,7 @@ fn pws(args: Vec) -> Result<()> { let _ = parser.refer(&mut subcommand).required().add_argument( "subcommand", argparse::Store, - "The subcommand to execute (clear|get|set)", + "The subcommand to execute (clear|get|set|status)", ); let _ = parser.refer(&mut subargs).add_argument( "arguments", @@ -909,6 +913,22 @@ fn pws_clear(args: Vec) -> Result<()> { commands::pws_clear(slot) } +/// Print the status of the PWS slots. +fn pws_status(args: Vec) -> Result<()> { + let mut all = false; + let mut parser = argparse::ArgumentParser::new(); + parser.set_description("Prints the status of the PWS slots"); + let _ = parser.refer(&mut all).add_option( + &["-a", "--all"], + argparse::StoreTrue, + "Show slots that are not programmed", + ); + parse(&parser, args)?; + drop(parser); + + commands::pws_status(all) +} + /// Parse the command-line arguments and return the selected command and /// the remaining arguments for the command. fn parse_arguments(args: Vec) -> Result<(Command, Vec)> { diff --git a/nitrocli/src/commands.rs b/nitrocli/src/commands.rs index 4deb1a7..c903cfd 100644 --- a/nitrocli/src/commands.rs +++ b/nitrocli/src/commands.rs @@ -20,6 +20,7 @@ use std::fmt; use std::result; use std::time; +use std::u8; use nitrokey::ConfigureOtp; use nitrokey::Device; @@ -602,6 +603,40 @@ pub fn pws_clear(slot: u8) -> Result<()> { .map_err(|err| get_error("Could not clear PWS slot", &err)) } +fn print_pws_slot(pws: &nitrokey::PasswordSafe<'_>, slot: usize, programmed: bool) -> Result<()> { + if slot > u8::MAX as usize { + return Err(Error::Error("Invalid PWS slot number".to_string())); + } + let slot = slot as u8; + let name = if programmed { + pws + .get_slot_name(slot) + .map_err(|err| get_error("Could not read PWS slot", &err))? + } else { + "[not programmed]".to_string() + }; + println!("{}\t{}", slot, name); + Ok(()) +} + +/// Print the status of all PWS slots. +pub fn pws_status(all: bool) -> Result<()> { + let device = get_device()?; + let pws = get_password_safe(&device)?; + let slots = pws + .get_slot_status() + .map_err(|err| get_error("Could not read PWS slot status", &err))?; + println!("slot\tname"); + for (i, &value) in slots + .into_iter() + .enumerate() + .filter(|(_, &value)| all || value) + { + print_pws_slot(&pws, i, value)?; + } + Ok(()) +} + #[cfg(test)] mod tests { use super::*; -- cgit v1.2.1