Skip to content

Commit

Permalink
Add the --progress option to the fill command
Browse files Browse the repository at this point in the history
The fill command starts a background operation on a Nitrokey Storage
device that fills the SD card with random data.  This patch adds a new
option, --progress, to the fill command that checks if a fill operation
is already running on the device and shows its progress.
  • Loading branch information
robinkrahl authored and d-e-s-o committed Jan 11, 2021
1 parent e085dcd commit 3152a6d
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 13 deletions.
7 changes: 6 additions & 1 deletion doc/nitrocli.1
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ open.
\fBnitrocli hidden close
Close a hidden volume.
.TP
\fBnitrocli fill\fR
\fBnitrocli fill \fR[\fB\-a\fR|\fB\-\-attach\fR
Fills the SD card with random data, overwriting all existing data.
This operation takes about one hour to finish for a 16 GiB SD card.
It cannot be canceled, even if the \fBnitrocli\fR process is terminated before
Expand All @@ -147,6 +147,11 @@ This command requires the admin PIN.
To avoid accidental calls of this command, the user has to enter the PIN even
if it has been cached.

If the \fB\-\-attach\fR option is set, this command will not start a new fill
operation.
Instead it checks whether a fill operation is currently running on the device
and shows its progress.

.SS One-time passwords
The Nitrokey Pro and the Nitrokey Storage support the generation of one-time
passwords using the HOTP algorithm according to RFC 4226 or the TOTP algorithm
Expand Down
Binary file modified doc/nitrocli.1.pdf
Binary file not shown.
10 changes: 9 additions & 1 deletion src/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ Command! {
/// Interacts with the device's encrypted volume
Encrypted(EncryptedArgs) => |ctx, args: EncryptedArgs| args.subcmd.execute(ctx),
/// Fills the SD card with random data
Fill => crate::commands::fill,
Fill(FillArgs) => |ctx, args: FillArgs| crate::commands::fill(ctx, args.attach),
/// Interacts with the device's hidden volume
Hidden(HiddenArgs) => |ctx, args: HiddenArgs| args.subcmd.execute(ctx),
/// Lists the attached Nitrokey devices
Expand Down Expand Up @@ -189,6 +189,14 @@ Command! {EncryptedCommand, [
Open => crate::commands::encrypted_open,
]}

#[derive(Debug, PartialEq, structopt::StructOpt)]
pub struct FillArgs {
/// Checks if a fill operation is already running and show its progress instead of starting a new
/// operation.
#[structopt(short, long)]
attach: bool,
}

#[derive(Debug, PartialEq, structopt::StructOpt)]
pub struct HiddenArgs {
#[structopt(subcommand)]
Expand Down
29 changes: 20 additions & 9 deletions src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -471,19 +471,30 @@ pub fn list(ctx: &mut Context<'_>, no_connect: bool) -> anyhow::Result<()> {
}

/// Fill the SD card with random data
pub fn fill(ctx: &mut Context<'_>) -> anyhow::Result<()> {
pub fn fill(ctx: &mut Context<'_>, attach: bool) -> anyhow::Result<()> {
with_storage_device(ctx, |ctx, mut device| {
let pin_entry = pinentry::PinEntry::from(args::PinType::Admin, &device)?;
let mut initial_progress = 0;
if attach {
let status = device
.get_operation_status()
.context("Failed to query operation status")?;
match status {
nitrokey::OperationStatus::Ongoing(progress) => initial_progress = progress,
nitrokey::OperationStatus::Idle => anyhow::bail!("No fill operation in progress"),
}
} else {
let pin_entry = pinentry::PinEntry::from(args::PinType::Admin, &device)?;

// Similar to reset, we want the user to re-enter the admin PIN even if is cached to avoid
// accidental data loss.
pinentry::clear(&pin_entry).context("Failed to clear cached secret")?;
// Similar to reset, we want the user to re-enter the admin PIN
// even if is cached to avoid accidental data loss.
pinentry::clear(&pin_entry).context("Failed to clear cached secret")?;

try_with_pin(ctx, &pin_entry, |pin| {
device.fill_sd_card(&pin).context("Failed to fill SD card")
})?;
try_with_pin(ctx, &pin_entry, |pin| {
device.fill_sd_card(&pin).context("Failed to fill SD card")
})?;
}

let mut progress_bar = output::ProgressBar::new();
let mut progress_bar = output::ProgressBar::new(initial_progress);
progress_bar.draw(ctx)?;

while !progress_bar.is_finished() {
Expand Down
4 changes: 2 additions & 2 deletions src/output.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@ pub struct ProgressBar {

impl ProgressBar {
/// Creates a new empty progress bar.
pub fn new() -> ProgressBar {
pub fn new(progress: u8) -> ProgressBar {
ProgressBar {
redraw: true,
progress: 0,
progress,
toggle: false,
finished: false,
}
Expand Down

0 comments on commit 3152a6d

Please sign in to comment.