From 57e8db75c69cc3831b9c5843c95fcd02afe1ee9b Mon Sep 17 00:00:00 2001 From: Robin Krahl Date: Tue, 25 Dec 2018 10:34:27 +0100 Subject: Implement the config command This patch adds the top-level config command. Its subcommands will provide access to the device configuration. --- nitrocli/CHANGELOG.md | 1 + nitrocli/src/args.rs | 72 ++++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 69 insertions(+), 4 deletions(-) diff --git a/nitrocli/CHANGELOG.md b/nitrocli/CHANGELOG.md index 65510df..682995a 100644 --- a/nitrocli/CHANGELOG.md +++ b/nitrocli/CHANGELOG.md @@ -7,6 +7,7 @@ Unreleased indirect dependencies - Removed the `hid`, `hidapi-sys` and `pkg-config` dependencies - Added the `otp` command for working with one-time passwords +- Added the `config` command for reading and writing the device configuration - Made `status` command work with Nitrokey Pro devices - Enabled CI pipeline comprising code style conformance checks, linting, and building of the project diff --git a/nitrocli/src/args.rs b/nitrocli/src/args.rs index b48acfa..253d5a0 100644 --- a/nitrocli/src/args.rs +++ b/nitrocli/src/args.rs @@ -32,6 +32,7 @@ type Result = result::Result; pub enum Command { Clear, Close, + Config, Open, Otp, Status, @@ -43,6 +44,7 @@ impl Command { match *self { Command::Clear => clear(args), Command::Close => close(args), + Command::Config => config(args), Command::Open => open(args), Command::Otp => otp(args), Command::Status => status(args), @@ -58,6 +60,7 @@ impl fmt::Display for Command { match *self { Command::Clear => "clear", Command::Close => "close", + Command::Config => "config", Command::Open => "open", Command::Otp => "otp", Command::Status => "status", @@ -73,6 +76,7 @@ impl str::FromStr for Command { match s { "clear" => Ok(Command::Clear), "close" => Ok(Command::Close), + "config" => Ok(Command::Config), "open" => Ok(Command::Open), "otp" => Ok(Command::Otp), "status" => Ok(Command::Status), @@ -81,6 +85,42 @@ impl str::FromStr for Command { } } +#[derive(Debug)] +enum ConfigCommand { + Get, +} + +impl ConfigCommand { + fn execute(&self, _args: Vec) -> Result<()> { + match *self { + ConfigCommand::Get => Err(Error::Error("Not implemented".to_string())), + } + } +} + +impl fmt::Display for ConfigCommand { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!( + f, + "{}", + match *self { + ConfigCommand::Get => "get", + } + ) + } +} + +impl str::FromStr for ConfigCommand { + type Err = (); + + fn from_str(s: &str) -> result::Result { + match s { + "get" => Ok(ConfigCommand::Get), + _ => Err(()), + } + } +} + #[derive(Debug)] enum OtpCommand { Clear, @@ -118,7 +158,7 @@ impl fmt::Display for OtpCommand { impl str::FromStr for OtpCommand { type Err = (); - fn from_str(s: &str) -> std::result::Result { + fn from_str(s: &str) -> result::Result { match s { "clear" => Ok(OtpCommand::Clear), "get" => Ok(OtpCommand::Get), @@ -151,7 +191,7 @@ impl fmt::Display for OtpAlgorithm { impl str::FromStr for OtpAlgorithm { type Err = (); - fn from_str(s: &str) -> std::result::Result { + fn from_str(s: &str) -> result::Result { match s { "hotp" => Ok(OtpAlgorithm::Hotp), "totp" => Ok(OtpAlgorithm::Totp), @@ -182,7 +222,7 @@ impl fmt::Display for OtpMode { impl str::FromStr for OtpMode { type Err = (); - fn from_str(s: &str) -> std::result::Result { + fn from_str(s: &str) -> result::Result { match s { "6" => Ok(OtpMode::SixDigits), "8" => Ok(OtpMode::EightDigits), @@ -244,6 +284,30 @@ fn clear(args: Vec) -> Result<()> { commands::clear() } +/// Execute a config subcommand. +fn config(args: Vec) -> Result<()> { + let mut subcommand = ConfigCommand::Get; + let mut subargs = vec![]; + let mut parser = argparse::ArgumentParser::new(); + parser.set_description("Reads or writes the device configuration"); + let _ = parser.refer(&mut subcommand).required().add_argument( + "subcommand", + argparse::Store, + "The subcommand to execute (get|set)", + ); + let _ = parser.refer(&mut subargs).add_argument( + "arguments", + argparse::List, + "The arguments for the subcommand", + ); + parser.stop_on_first_argument(true); + parse(&parser, args)?; + drop(parser); + + subargs.insert(0, format!("nitrocli config {}", subcommand)); + subcommand.execute(subargs) +} + /// Execute an OTP subcommand. fn otp(args: Vec) -> Result<()> { let mut subcommand = OtpCommand::Get; @@ -404,7 +468,7 @@ fn parse_arguments(args: Vec) -> Result<(Command, Vec)> { let _ = parser.refer(&mut command).required().add_argument( "command", argparse::Store, - "The command to execute (clear|close|open|otp|status)", + "The command to execute (clear|close|config|open|otp|status)", ); let _ = parser.refer(&mut subargs).add_argument( "arguments", -- cgit v1.2.1