Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Topic/restructure storage cmd #87

Merged
merged 3 commits into from
Jun 6, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Prev Previous commit
Next Next commit
Make storage hidden subcommand a top-level command
This patch marks the next step in the process of restructuring the
storage command. Specifically, it promotes the storage hidden subcommand
to a top-level command, hidden.
  • Loading branch information
d-e-s-o committed May 27, 2019
commit a00e3f75349dc5f48abf441fd4e5c369c2e2055a
1 change: 1 addition & 0 deletions nitrocli/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
Unreleased
----------
- Changed `storage hidden` subcommand to `hidden` top-level command
- Removed `storage status` subcommand
- Moved its output into `status` command

Expand Down
10 changes: 5 additions & 5 deletions nitrocli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@ The following commands are currently supported:
- config: Access the Nitrokey's configuration
- get: Read the current configuration.
- set: Change the configuration.
- storage: Work with the Nitrokey's storage.
- storage: Work with the Nitrokey Storage's storage.
- open: Open the encrypted volume. The user PIN needs to be entered.
- close: Close the encrypted volume.
- hidden:
- create: Create a hidden volume.
- open: Open a hidden volume with a password.
- close: Close a hidden volume.
- hidden: Work with the Nitrokey Storage's hidden volume.
- create: Create a hidden volume.
- open: Open a hidden volume with a password.
- close: Close a hidden volume.
- otp: Access one-time passwords (OTP).
- get: Generate a one-time password.
- set: Set an OTP slot.
Expand Down
10 changes: 5 additions & 5 deletions nitrocli/doc/nitrocli.1
Original file line number Diff line number Diff line change
Expand Up @@ -71,22 +71,22 @@ The user PIN that is required to open the volume is queried using
\fBnitrocli storage close
Close the encrypted volume on the Nitrokey Storage.
.TP
\fBnitrocli storage hidden create \fIslot\fR \fIstart\fR \fIend\fR
\fBnitrocli hidden create \fIslot\fR \fIstart\fR \fIend\fR
Create a new hidden volume inside the encrypted volume. \fIslot\fR must indicate
one of the four available slots. \fIstart\fR and \fIend\fR represent,
respectively, the start and end position of the hidden volume inside the
encrypted volume, as a percentage of the encrypted volume's size.
This command requires a password which is later used to look up the hidden
volume to open. Unlike a PIN, this password is not cached by \fBgpg\-agent\fR(1).
.TP
\fBnitrocli storage hidden open
\fBnitrocli hidden open
Open a hidden volume. The volume to open is determined based on the password
entered, which must have a minimum of six characters. Only one hidden volume can
be active at any point in time and previously opened volumes will be
automatically closed. Similarly, the encrypted volume will be closed if it was
open.
.TP
\fBnitrocli storage hidden close
\fBnitrocli hidden close
Close a hidden volume.

.SS One-time passwords
Expand Down Expand Up @@ -275,7 +275,7 @@ The new user PIN to set. This variable is only used by the \fBpin set\fR command
for the \fBuser\fR type.
.TP
.B NITROCLI_PASSWORD
A password used by commands that require one (e.g., \fBstorage hidden open\fR).
A password used by commands that require one (e.g., \fBhidden open\fR).
.TP
.B NITROCLI_NO_CACHE
If this variable is present in the environment, do not cache any inquired
Expand All @@ -288,7 +288,7 @@ Use the \fBpin clear\fR command to clear secrets from the cache.
.SS Storage
Create a hidden volume in the first available slot, starting at half the size of
the encrypted volume (i.e., 50%) and stretching all the way to its end (100%):
$ \fBnitrocli storage hidden create 0 50 100\fR
$ \fBnitrocli hidden create 0 50 100\fR

.SS One-time passwords
Configure a one-time password slot with a hexadecimal secret representation:
Expand Down
Binary file modified nitrocli/doc/nitrocli.1.pdf
Binary file not shown.
34 changes: 13 additions & 21 deletions nitrocli/src/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ impl From<DeviceModel> for nitrokey::Model {
#[allow(unused_doc_comments)]
Enum! {Command, [
Config => ("config", config),
Hidden => ("hidden", hidden),
Lock => ("lock", lock),
Otp => ("otp", otp),
Pin => ("pin", pin),
Expand Down Expand Up @@ -248,7 +249,6 @@ fn reset(ctx: &mut ExecCtx<'_>, args: Vec<String>) -> Result<()> {

Enum! {StorageCommand, [
Close => ("close", storage_close),
Hidden => ("hidden", storage_hidden),
Open => ("open", storage_open),
]}

Expand Down Expand Up @@ -295,13 +295,13 @@ fn storage_close(ctx: &mut ExecCtx<'_>, args: Vec<String>) -> Result<()> {
}

Enum! {HiddenCommand, [
Close => ("close", storage_hidden_close),
Create => ("create", storage_hidden_create),
Open => ("open", storage_hidden_open),
Close => ("close", hidden_close),
Create => ("create", hidden_create),
Open => ("open", hidden_open),
]}

/// Execute a storage hidden subcommand.
fn storage_hidden(ctx: &mut ExecCtx<'_>, args: Vec<String>) -> Result<()> {
/// Execute a hidden subcommand.
fn hidden(ctx: &mut ExecCtx<'_>, args: Vec<String>) -> Result<()> {
let mut subcommand = HiddenCommand::Open;
let help = cmd_help!(subcommand);
let mut subargs = vec![];
Expand All @@ -320,19 +320,11 @@ fn storage_hidden(ctx: &mut ExecCtx<'_>, args: Vec<String>) -> Result<()> {
parser.stop_on_first_argument(true);
parse(ctx, parser, args)?;

subargs.insert(
0,
format!(
"nitrocli {} {} {}",
Command::Storage,
StorageCommand::Hidden,
subcommand
),
);
subargs.insert(0, format!("nitrocli {} {}", Command::Hidden, subcommand));
subcommand.execute(ctx, subargs)
}

fn storage_hidden_create(ctx: &mut ExecCtx<'_>, args: Vec<String>) -> Result<()> {
fn hidden_create(ctx: &mut ExecCtx<'_>, args: Vec<String>) -> Result<()> {
let mut slot: u8 = 0;
let mut start: u8 = 0;
let mut end: u8 = 0;
Expand All @@ -357,23 +349,23 @@ fn storage_hidden_create(ctx: &mut ExecCtx<'_>, args: Vec<String>) -> Result<()>
);
parse(ctx, parser, args)?;

commands::storage_hidden_create(ctx, slot, start, end)
commands::hidden_create(ctx, slot, start, end)
}

fn storage_hidden_open(ctx: &mut ExecCtx<'_>, args: Vec<String>) -> Result<()> {
fn hidden_open(ctx: &mut ExecCtx<'_>, args: Vec<String>) -> Result<()> {
let mut parser = argparse::ArgumentParser::new();
parser.set_description("Opens a hidden volume on a Nitrokey Storage");
parse(ctx, parser, args)?;

commands::storage_hidden_open(ctx)
commands::hidden_open(ctx)
}

fn storage_hidden_close(ctx: &mut ExecCtx<'_>, args: Vec<String>) -> Result<()> {
fn hidden_close(ctx: &mut ExecCtx<'_>, args: Vec<String>) -> Result<()> {
let mut parser = argparse::ArgumentParser::new();
parser.set_description("Closes the hidden volume on a Nitrokey Storage");
parse(ctx, parser, args)?;

commands::storage_hidden_close(ctx)
commands::hidden_close(ctx)
}

/// Execute a config subcommand.
Expand Down
11 changes: 3 additions & 8 deletions nitrocli/src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -389,12 +389,7 @@ pub fn storage_close(ctx: &mut args::ExecCtx<'_>) -> Result<()> {
}

/// Create a hidden volume.
pub fn storage_hidden_create(
ctx: &mut args::ExecCtx<'_>,
slot: u8,
start: u8,
end: u8,
) -> Result<()> {
pub fn hidden_create(ctx: &mut args::ExecCtx<'_>, slot: u8, start: u8, end: u8) -> Result<()> {
let device = get_storage_device(ctx)?;
let pwd_entry = pinentry::PwdEntry::from(&device)?;
let pwd = if let Some(pwd) = &ctx.password {
Expand All @@ -412,7 +407,7 @@ pub fn storage_hidden_create(
}

/// Open a hidden volume.
pub fn storage_hidden_open(ctx: &mut args::ExecCtx<'_>) -> Result<()> {
pub fn hidden_open(ctx: &mut args::ExecCtx<'_>) -> Result<()> {
let device = get_storage_device(ctx)?;
let pwd_entry = pinentry::PwdEntry::from(&device)?;
let pwd = if let Some(pwd) = &ctx.password {
Expand All @@ -434,7 +429,7 @@ pub fn storage_hidden_open(ctx: &mut args::ExecCtx<'_>) -> Result<()> {
}

/// Close a previously opened hidden volume.
pub fn storage_hidden_close(ctx: &mut args::ExecCtx<'_>) -> Result<()> {
pub fn hidden_close(ctx: &mut args::ExecCtx<'_>) -> Result<()> {
unsafe { sync() };

get_storage_device(ctx)?
Expand Down
44 changes: 44 additions & 0 deletions nitrocli/src/tests/hidden.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// hidden.rs

// *************************************************************************
// * Copyright (C) 2019 Daniel Mueller ([email protected]) *
// * *
// * This program is free software: you can redistribute it and/or modify *
// * it under the terms of the GNU General Public License as published by *
// * the Free Software Foundation, either version 3 of the License, or *
// * (at your option) any later version. *
// * *
// * This program is distributed in the hope that it will be useful, *
// * but WITHOUT ANY WARRANTY; without even the implied warranty of *
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
// * GNU General Public License for more details. *
// * *
// * You should have received a copy of the GNU General Public License *
// * along with this program. If not, see <http:https://www.gnu.org/licenses/>. *
// *************************************************************************

use super::*;

#[test_device]
fn hidden_create_open_close(device: nitrokey::Storage) -> crate::Result<()> {
let mut ncli = Nitrocli::with_dev(device);
let out = ncli.handle(&["hidden", "create", "0", "50", "100"])?;
assert!(out.is_empty());

let out = ncli.handle(&["hidden", "open"])?;
assert!(out.is_empty());

let device = nitrokey::Storage::connect()?;
assert!(!device.get_status()?.encrypted_volume.active);
assert!(device.get_status()?.hidden_volume.active);
drop(device);

let out = ncli.handle(&["hidden", "close"])?;
assert!(out.is_empty());

let device = nitrokey::Storage::connect()?;
assert!(!device.get_status()?.encrypted_volume.active);
assert!(!device.get_status()?.hidden_volume.active);

Ok(())
}
1 change: 1 addition & 0 deletions nitrocli/src/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ const NITROKEY_DEFAULT_USER_PIN: &str = "123456";
fn dummy() {}

mod config;
mod hidden;
mod lock;
mod otp;
mod pin;
Expand Down
24 changes: 0 additions & 24 deletions nitrocli/src/tests/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,27 +88,3 @@ fn encrypted_open_close(device: nitrokey::Storage) -> crate::Result<()> {

Ok(())
}

#[test_device]
fn hidden_create_open_close(device: nitrokey::Storage) -> crate::Result<()> {
let mut ncli = Nitrocli::with_dev(device);
let out = ncli.handle(&["storage", "hidden", "create", "0", "50", "100"])?;
assert!(out.is_empty());

let out = ncli.handle(&["storage", "hidden", "open"])?;
assert!(out.is_empty());

let device = nitrokey::Storage::connect()?;
assert!(!device.get_status()?.encrypted_volume.active);
assert!(device.get_status()?.hidden_volume.active);
drop(device);

let out = ncli.handle(&["storage", "hidden", "close"])?;
assert!(out.is_empty());

let device = nitrokey::Storage::connect()?;
assert!(!device.get_status()?.encrypted_volume.active);
assert!(!device.get_status()?.hidden_volume.active);

Ok(())
}