aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin Krahl <robin.krahl@ireas.org>2018-12-25 10:34:27 +0100
committerDaniel Mueller <deso@posteo.net>2018-12-27 11:12:58 -0800
commit57e8db75c69cc3831b9c5843c95fcd02afe1ee9b (patch)
tree96f38e7bdcc7b68d9011668dec494ee7784f35e4
parent21e7c36a0ae14f2200e806fcf66cbe0836cc2ec0 (diff)
downloadnitrocli-57e8db75c69cc3831b9c5843c95fcd02afe1ee9b.tar.gz
nitrocli-57e8db75c69cc3831b9c5843c95fcd02afe1ee9b.tar.bz2
Implement the config command
This patch adds the top-level config command. Its subcommands will provide access to the device configuration.
-rw-r--r--nitrocli/CHANGELOG.md1
-rw-r--r--nitrocli/src/args.rs72
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<T> = result::Result<T, Error>;
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),
@@ -82,6 +86,42 @@ impl str::FromStr for Command {
}
#[derive(Debug)]
+enum ConfigCommand {
+ Get,
+}
+
+impl ConfigCommand {
+ fn execute(&self, _args: Vec<String>) -> 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<Self, Self::Err> {
+ match s {
+ "get" => Ok(ConfigCommand::Get),
+ _ => Err(()),
+ }
+ }
+}
+
+#[derive(Debug)]
enum OtpCommand {
Clear,
Get,
@@ -118,7 +158,7 @@ impl fmt::Display for OtpCommand {
impl str::FromStr for OtpCommand {
type Err = ();
- fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
+ fn from_str(s: &str) -> result::Result<Self, Self::Err> {
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<Self, Self::Err> {
+ fn from_str(s: &str) -> result::Result<Self, Self::Err> {
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<Self, Self::Err> {
+ fn from_str(s: &str) -> result::Result<Self, Self::Err> {
match s {
"6" => Ok(OtpMode::SixDigits),
"8" => Ok(OtpMode::EightDigits),
@@ -244,6 +284,30 @@ fn clear(args: Vec<String>) -> Result<()> {
commands::clear()
}
+/// Execute a config subcommand.
+fn config(args: Vec<String>) -> 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<String>) -> Result<()> {
let mut subcommand = OtpCommand::Get;
@@ -404,7 +468,7 @@ fn parse_arguments(args: Vec<String>) -> Result<(Command, Vec<String>)> {
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",