diff options
-rw-r--r-- | nitrocli/src/args.rs | 28 | ||||
-rw-r--r-- | nitrocli/src/commands.rs | 11 |
2 files changed, 38 insertions, 1 deletions
diff --git a/nitrocli/src/args.rs b/nitrocli/src/args.rs index c27fbc2..5c2cbb8 100644 --- a/nitrocli/src/args.rs +++ b/nitrocli/src/args.rs @@ -83,6 +83,7 @@ impl str::FromStr for Command { #[derive(Debug)] enum OtpCommand { + Clear, Get, Set, } @@ -90,6 +91,7 @@ enum OtpCommand { impl OtpCommand { fn execute(&self, args: Vec<String>) -> Result<()> { match *self { + OtpCommand::Clear => otp_clear(args), OtpCommand::Get => otp_get(args), OtpCommand::Set => otp_set(args), } @@ -102,6 +104,7 @@ impl fmt::Display for OtpCommand { f, "{}", match *self { + OtpCommand::Clear => "clear", OtpCommand::Get => "get", OtpCommand::Set => "set", } @@ -114,6 +117,7 @@ impl str::FromStr for OtpCommand { fn from_str(s: &str) -> std::result::Result<Self, Self::Err> { match s { + "clear" => Ok(OtpCommand::Clear), "get" => Ok(OtpCommand::Get), "set" => Ok(OtpCommand::Set), _ => Err(()), @@ -245,7 +249,7 @@ fn otp(args: Vec<String>) -> Result<()> { let _ = parser.refer(&mut subcommand).required().add_argument( "subcommand", argparse::Store, - "The subcommand to execute (get|set)", + "The subcommand to execute (clear|get|set)", ); let _ = parser.refer(&mut subargs).add_argument( "arguments", @@ -348,6 +352,28 @@ pub fn otp_set(args: Vec<String>) -> Result<()> { commands::otp_set(data, algorithm, counter, time_window, ascii) } +/// Clear an OTP slot. +fn otp_clear(args: Vec<String>) -> Result<()> { + let mut slot: u8 = 0; + let mut algorithm = OtpAlgorithm::Totp; + let mut parser = argparse::ArgumentParser::new(); + parser.set_description("Clears a one-time password slot"); + let _ = parser.refer(&mut slot).required().add_argument( + "slot", + argparse::Store, + "The OTP slot to clear", + ); + let _ = parser.refer(&mut algorithm).add_option( + &["-a", "--algorithm"], + argparse::Store, + "The OTP algorithm to use (hotp|totp)", + ); + parse(&parser, args)?; + drop(parser); + + commands::otp_clear(slot, algorithm) +} + /// 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 8dc8c42..93e9bd3 100644 --- a/nitrocli/src/commands.rs +++ b/nitrocli/src/commands.rs @@ -322,6 +322,17 @@ pub fn otp_set( Ok(()) } +/// Clear an OTP slot. +pub fn otp_clear(slot: u8, algorithm: args::OtpAlgorithm) -> Result<()> { + let device = authenticate_admin(get_device()?)?; + match algorithm { + args::OtpAlgorithm::Hotp => device.erase_hotp_slot(slot), + args::OtpAlgorithm::Totp => device.erase_totp_slot(slot), + } + .map_err(|err| get_error("Could not clear OTP slot", &err))?; + Ok(()) +} + #[cfg(test)] mod tests { use super::*; |