aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--nitrocli/src/args.rs22
-rw-r--r--nitrocli/src/commands.rs35
2 files changed, 56 insertions, 1 deletions
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<String>) -> 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<String>) -> Result<()> {
commands::pws_clear(slot)
}
+/// Print the status of the PWS slots.
+fn pws_status(args: Vec<String>) -> 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<String>) -> Result<(Command, Vec<String>)> {
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::*;