diff options
-rw-r--r-- | nitrocli/CHANGELOG.md | 2 | ||||
-rw-r--r-- | nitrocli/README.md | 9 | ||||
-rw-r--r-- | nitrocli/doc/nitrocli.1 | 19 | ||||
-rw-r--r-- | nitrocli/src/args.rs | 88 | ||||
-rw-r--r-- | nitrocli/src/commands.rs | 4 | ||||
-rw-r--r-- | nitrocli/src/main.rs | 2 |
6 files changed, 95 insertions, 29 deletions
diff --git a/nitrocli/CHANGELOG.md b/nitrocli/CHANGELOG.md index 682995a..813f853 100644 --- a/nitrocli/CHANGELOG.md +++ b/nitrocli/CHANGELOG.md @@ -8,6 +8,8 @@ Unreleased - 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 +- Moved `open` and `close` commands as subcommands into newly introduced + `storage` command - 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/README.md b/nitrocli/README.md index 3e0b518..b28f09e 100644 --- a/nitrocli/README.md +++ b/nitrocli/README.md @@ -11,10 +11,11 @@ nitrocli certain commands on the [Nitrokey Storage][nitrokey-storage] device. The following commands are currently supported: -- open: Open the encrypted volume. The user PIN needs to be entered. -- close: Close the encrypted volume. - status: Report status information about the Nitrokey. - clear: Remove the user and admin PIN from gpg-agent's cache. +- storage: Work with the Nitrokey's storage. + - open: Open the encrypted volume. The user PIN needs to be entered. + - close: Close the encrypted volume. - otp: Access one-time passwords (OTP). - get: Generate a one-time password. - set: Set an OTP slot. @@ -38,7 +39,7 @@ parameter (note that some commands are organized through subcommands, which are required as well), e.g.: ```bash # Open the nitrokey's encrypted volume. -$ nitrocli open +$ nitrocli storage open $ nitrocli status Status: @@ -57,7 +58,7 @@ Status: hidden: inactive # Close it again. -$ nitrocli close +$ nitrocli storage close ``` diff --git a/nitrocli/doc/nitrocli.1 b/nitrocli/doc/nitrocli.1 index e345cdb..44d41fd 100644 --- a/nitrocli/doc/nitrocli.1 +++ b/nitrocli/doc/nitrocli.1 @@ -12,14 +12,6 @@ It can be used to access the encrypted volume and the one-time password generato .SH COMMANDS .SS General .TP -.B nitrocli open -Open the encrypted volume on the Nitrokey Storage. -The user PIN that is required to open the volume is queried using -\fBpinentry\fR(1) and cached by \fBgpg-agent\fR(1). -.TP -.B nitrocli close -Close the encrypted volume on the Nitrokey Storage. -.TP .B nitrocli status Print the status of the connected Nitrokey device, including the stick serial number, SD card serial number, the firmware version and the PIN retry count. @@ -28,6 +20,17 @@ of the volumes. .TP .B nitrocli clear Clear the passphrases cached by the other commands. + +.SS Storage +.TP +\fBnitrocli storage open +Open the encrypted volume on the Nitrokey Storage. +The user PIN that is required to open the volume is queried using +\fBpinentry\fR(1) and cached by \fBgpg-agent\fR(1). +.TP +\fBnitrocli storage close +Close the encrypted volume on the Nitrokey Storage. + .SS One-time passwords .TP \fBnitrocli otp get \fIslot \fR[\fB-a\fR|\fB--algorithm \fIalgorithm\fR] diff --git a/nitrocli/src/args.rs b/nitrocli/src/args.rs index 36da560..d7a6d25 100644 --- a/nitrocli/src/args.rs +++ b/nitrocli/src/args.rs @@ -31,11 +31,10 @@ type Result<T> = result::Result<T, Error>; #[derive(Debug)] pub enum Command { Clear, - Close, Config, - Open, Otp, Status, + Storage, } impl Command { @@ -43,11 +42,10 @@ impl Command { pub fn execute(&self, args: Vec<String>) -> Result<()> { 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), + Command::Storage => storage(args), } } } @@ -59,11 +57,10 @@ 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", + Command::Storage => "storage", } ) } @@ -75,11 +72,10 @@ impl str::FromStr for Command { fn from_str(s: &str) -> result::Result<Self, Self::Err> { 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), + "storage" => Ok(Command::Storage), _ => Err(()), } } @@ -297,24 +293,88 @@ fn status(args: Vec<String>) -> Result<()> { } /// Open the encrypted volume on the nitrokey. -fn open(args: Vec<String>) -> Result<()> { +fn storage_open(args: Vec<String>) -> Result<()> { let mut parser = argparse::ArgumentParser::new(); parser.set_description("Opens the encrypted volume on a Nitrokey Storage"); parse(&parser, args)?; - commands::open() + commands::storage_open() } /// Close the previously opened encrypted volume. -fn close(args: Vec<String>) -> Result<()> { +fn storage_close(args: Vec<String>) -> Result<()> { let mut parser = argparse::ArgumentParser::new(); parser.set_description("Closes the encrypted volume on a Nitrokey Storage"); parse(&parser, args)?; - commands::close() + commands::storage_close() +} + +#[derive(Debug)] +enum StorageCommand { + Close, + Open, +} + +impl StorageCommand { + fn execute(&self, args: Vec<String>) -> Result<()> { + match *self { + StorageCommand::Close => storage_close(args), + StorageCommand::Open => storage_open(args), + } + } +} + +impl fmt::Display for StorageCommand { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!( + f, + "{}", + match *self { + StorageCommand::Close => "close", + StorageCommand::Open => "open", + } + ) + } +} + +impl str::FromStr for StorageCommand { + type Err = (); + + fn from_str(s: &str) -> result::Result<Self, Self::Err> { + match s { + "close" => Ok(StorageCommand::Close), + "open" => Ok(StorageCommand::Open), + _ => Err(()), + } + } +} + +/// Execute a storage subcommand. +fn storage(args: Vec<String>) -> Result<()> { + let mut subcommand = StorageCommand::Open; + let mut subargs = vec![]; + let mut parser = argparse::ArgumentParser::new(); + parser.set_description("Interacts with the device's storage"); + let _ = parser.refer(&mut subcommand).required().add_argument( + "subcommand", + argparse::Store, + "The subcommand to execute (open|close)", + ); + 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 storage {}", subcommand)); + subcommand.execute(subargs) } -/// Clear the PIN stored when opening the nitrokey's encrypted volume. +/// Clear the PIN as cached by various other commands. fn clear(args: Vec<String>) -> Result<()> { let mut parser = argparse::ArgumentParser::new(); parser.set_description("Clears the cached passphrases"); @@ -584,7 +644,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|config|open|otp|status)", + "The command to execute (clear|config|otp|status|storage)", ); let _ = parser.refer(&mut subargs).add_argument( "arguments", diff --git a/nitrocli/src/commands.rs b/nitrocli/src/commands.rs index 9aef2de..fdfe049 100644 --- a/nitrocli/src/commands.rs +++ b/nitrocli/src/commands.rs @@ -243,7 +243,7 @@ pub fn status() -> Result<()> { } /// Open the encrypted volume on the nitrokey. -pub fn open() -> Result<()> { +pub fn storage_open() -> Result<()> { let device = get_storage_device()?; try_with_passphrase( pinentry::PinType::User, @@ -258,7 +258,7 @@ extern "C" { } /// Close the previously opened encrypted volume. -pub fn close() -> Result<()> { +pub fn storage_close() -> Result<()> { // Flush all filesystem caches to disk. We are mostly interested in // making sure that the encrypted volume on the nitrokey we are // about to close is not closed while not all data was written to diff --git a/nitrocli/src/main.rs b/nitrocli/src/main.rs index 8a20494..4f39fdb 100644 --- a/nitrocli/src/main.rs +++ b/nitrocli/src/main.rs @@ -66,7 +66,7 @@ )] //! Nitrocli is a program providing a command line interface to certain -//! commands of the Nitrokey Storage device. +//! commands of Nitrokey Pro and Storage devices. mod args; mod commands; |