diff options
| author | Daniel Mueller <deso@posteo.net> | 2019-05-27 08:09:48 -0700 | 
|---|---|---|
| committer | Daniel Mueller <deso@posteo.net> | 2019-05-27 08:09:48 -0700 | 
| commit | d35cdf7f0a9822f73f4e1d18494350840de2a421 (patch) | |
| tree | 6d22dd85516c5363a81c9264bc30a53cf244d632 | |
| parent | a7b63f8a0570f0c798af7eaadfaf6f4da14cd54c (diff) | |
| download | nitrocli-d35cdf7f0a9822f73f4e1d18494350840de2a421.tar.gz nitrocli-d35cdf7f0a9822f73f4e1d18494350840de2a421.tar.bz2  | |
Move storage status subcommand into status command
In an attempt to rework the structure of the storage command to better
accommodate future requirements for allowing to change the read-write
state of the unencrypted volume (as well as potentially the encrypted
one), this change removes the storage status subcommand and merges its
output into the storage command.
| -rw-r--r-- | nitrocli/CHANGELOG.md | 6 | ||||
| -rw-r--r-- | nitrocli/README.md | 19 | ||||
| -rw-r--r-- | nitrocli/doc/nitrocli.1 | 9 | ||||
| -rw-r--r-- | nitrocli/doc/nitrocli.1.pdf | bin | 18096 -> 18107 bytes | |||
| -rw-r--r-- | nitrocli/src/args.rs | 10 | ||||
| -rw-r--r-- | nitrocli/src/commands.rs | 88 | ||||
| -rw-r--r-- | nitrocli/src/tests/status.rs | 30 | ||||
| -rw-r--r-- | nitrocli/src/tests/storage.rs | 37 | 
8 files changed, 106 insertions, 93 deletions
diff --git a/nitrocli/CHANGELOG.md b/nitrocli/CHANGELOG.md index 4376d84..aa40810 100644 --- a/nitrocli/CHANGELOG.md +++ b/nitrocli/CHANGELOG.md @@ -1,3 +1,9 @@ +Unreleased +---------- +- Removed `storage status` subcommand +  - Moved its output into `status` command + +  0.2.4  -----  - Added the `reset` command to perform a factory reset diff --git a/nitrocli/README.md b/nitrocli/README.md index 515e06a..280e494 100644 --- a/nitrocli/README.md +++ b/nitrocli/README.md @@ -21,7 +21,6 @@ The following commands are currently supported:  - storage: Work with the Nitrokey's storage.    - open: Open the encrypted volume. The user PIN needs to be entered.    - close: Close the encrypted volume. -  - status: Print information about the Nitrokey's storage.    - hidden:      - create: Create a hidden volume.      - open: Open a hidden volume with a password. @@ -59,16 +58,14 @@ Status:    firmware version:  0.47    user retry count:  3    admin retry count: 3 - -$ nitrocli storage status -Status: -  SD card ID:        0x05dcad1d -  firmware:          unlocked -  storage keys:      created -  volumes: -    unencrypted:     active -    encrypted:       active -    hidden:          inactive +  Storage: +    SD card ID:        0x05dcad1d +    firmware:          unlocked +    storage keys:      created +    volumes: +      unencrypted:     active +      encrypted:       active +      hidden:          inactive  # Close it again.  $ nitrocli storage close diff --git a/nitrocli/doc/nitrocli.1 b/nitrocli/doc/nitrocli.1 index 9029335..ee6ea11 100644 --- a/nitrocli/doc/nitrocli.1 +++ b/nitrocli/doc/nitrocli.1 @@ -34,7 +34,9 @@ Print the nitrocli version and exit.  .TP  .B nitrocli status  Print the status of the connected Nitrokey device, including the stick serial -number, the firmware version, and the PIN retry count. +number, the firmware version, and the PIN retry count. If the device is a +Nitrokey Storage, also print storage related information including the SD card +serial number, the encryption status, and the status of the volumes.  .TP  .B nitrocli lock  Lock the Nitrokey. @@ -69,11 +71,6 @@ 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 status -Print the status of the connected Nitrokey Storage device's storage. The -printed information includes the SD card serial number, the encryption -status, and the status of the volumes. -.TP  \fBnitrocli storage 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, diff --git a/nitrocli/doc/nitrocli.1.pdf b/nitrocli/doc/nitrocli.1.pdf Binary files differindex fa4e4bc..2be0f02 100644 --- a/nitrocli/doc/nitrocli.1.pdf +++ b/nitrocli/doc/nitrocli.1.pdf diff --git a/nitrocli/src/args.rs b/nitrocli/src/args.rs index 10a097e..0b0429a 100644 --- a/nitrocli/src/args.rs +++ b/nitrocli/src/args.rs @@ -250,7 +250,6 @@ Enum! {StorageCommand, [    Close => ("close", storage_close),    Hidden => ("hidden", storage_hidden),    Open => ("open", storage_open), -  Status => ("status", storage_status),  ]}  /// Execute a storage subcommand. @@ -295,15 +294,6 @@ fn storage_close(ctx: &mut ExecCtx<'_>, args: Vec<String>) -> Result<()> {    commands::storage_close(ctx)  } -/// Print the status of the nitrokey's storage. -fn storage_status(ctx: &mut ExecCtx<'_>, args: Vec<String>) -> Result<()> { -  let mut parser = argparse::ArgumentParser::new(); -  parser.set_description("Prints the status of the Nitrokey's storage"); -  parse(ctx, parser, args)?; - -  commands::storage_status(ctx) -} -  Enum! {HiddenCommand, [    Close => ("close", storage_hidden_close),    Create => ("create", storage_hidden_create), diff --git a/nitrocli/src/commands.rs b/nitrocli/src/commands.rs index 7bb314c..d1ded11 100644 --- a/nitrocli/src/commands.rs +++ b/nitrocli/src/commands.rs @@ -258,6 +258,39 @@ where    })  } +/// Pretty print the status of a Nitrokey Storage. +fn print_storage_status( +  ctx: &mut args::ExecCtx<'_>, +  status: &nitrokey::StorageStatus, +) -> Result<()> { +  println!( +    ctx, +    r#"  Storage: +    SD card ID:        {id:#x} +    firmware:          {fw} +    storage keys:      {sk} +    volumes: +      unencrypted:     {vu} +      encrypted:       {ve} +      hidden:          {vh}"#, +    id = status.serial_number_sd_card, +    fw = if status.firmware_locked { +      "locked" +    } else { +      "unlocked" +    }, +    sk = if status.stick_initialized { +      "created" +    } else { +      "not created" +    }, +    vu = get_volume_status(&status.unencrypted_volume), +    ve = get_volume_status(&status.encrypted_volume), +    vh = get_volume_status(&status.hidden_volume), +  )?; +  Ok(()) +} +  /// Query and pretty print the status that is common to all Nitrokey devices.  fn print_status(    ctx: &mut args::ExecCtx<'_>, @@ -267,6 +300,7 @@ fn print_status(    let serial_number = device      .get_serial_number()      .map_err(|err| get_error("Could not query the serial number", err))?; +    println!(      ctx,      r#"Status: @@ -282,7 +316,16 @@ fn print_status(      urc = device.get_user_retry_count(),      arc = device.get_admin_retry_count(),    )?; -  Ok(()) + +  if let nitrokey::DeviceWrapper::Storage(device) = device { +    let status = device +      .get_status() +      .map_err(|err| get_error("Getting Storage status failed", err))?; + +    print_storage_status(ctx, &status) +  } else { +    Ok(()) +  }  }  /// Inquire the status of the nitrokey. @@ -399,49 +442,6 @@ pub fn storage_hidden_close(ctx: &mut args::ExecCtx<'_>) -> Result<()> {      .map_err(|err| get_error("Closing hidden volume failed", err))  } -/// Pretty print the status of a Nitrokey Storage. -fn print_storage_status( -  ctx: &mut args::ExecCtx<'_>, -  status: &nitrokey::StorageStatus, -) -> Result<()> { -  println!( -    ctx, -    r#"Status: -  SD card ID:        {id:#x} -  firmware:          {fw} -  storage keys:      {sk} -  volumes: -    unencrypted:     {vu} -    encrypted:       {ve} -    hidden:          {vh}"#, -    id = status.serial_number_sd_card, -    fw = if status.firmware_locked { -      "locked" -    } else { -      "unlocked" -    }, -    sk = if status.stick_initialized { -      "created" -    } else { -      "not created" -    }, -    vu = get_volume_status(&status.unencrypted_volume), -    ve = get_volume_status(&status.encrypted_volume), -    vh = get_volume_status(&status.hidden_volume), -  )?; -  Ok(()) -} - -/// Connect to and pretty print the status of a Nitrokey Storage. -pub fn storage_status(ctx: &mut args::ExecCtx<'_>) -> Result<()> { -  let device = get_storage_device(ctx)?; -  let status = device -    .get_status() -    .map_err(|err| get_error("Getting Storage status failed", err))?; - -  print_storage_status(ctx, &status) -} -  /// Return a String representation of the given Option.  fn format_option<T: fmt::Display>(option: Option<T>) -> String {    match option { diff --git a/nitrocli/src/tests/status.rs b/nitrocli/src/tests/status.rs index 83ce61f..7aac5ad 100644 --- a/nitrocli/src/tests/status.rs +++ b/nitrocli/src/tests/status.rs @@ -37,10 +37,10 @@ fn not_found() {  }  #[test_device] -fn output(device: nitrokey::DeviceWrapper) -> crate::Result<()> { +fn output_pro(device: nitrokey::Pro) -> crate::Result<()> {    let re = regex::Regex::new(      r#"^Status: -  model:             (Pro|Storage) +  model:             Pro    serial number:     0x[[:xdigit:]]{8}    firmware version:  \d+\.\d+    user retry count:  [0-3] @@ -53,3 +53,29 @@ $"#,    assert!(re.is_match(&out), out);    Ok(())  } + +#[test_device] +fn output_storage(device: nitrokey::Storage) -> crate::Result<()> { +  let re = regex::Regex::new( +    r#"^Status: +  model:             Storage +  serial number:     0x[[:xdigit:]]{8} +  firmware version:  \d+\.\d+ +  user retry count:  [0-3] +  admin retry count: [0-3] +  Storage: +    SD card ID:        0x[[:xdigit:]]{8} +    firmware:          (un)?locked +    storage keys:      (not )?created +    volumes: +      unencrypted:     (read-only|active|inactive) +      encrypted:       (read-only|active|inactive) +      hidden:          (read-only|active|inactive) +$"#, +  ) +  .unwrap(); + +  let out = Nitrocli::with_dev(device).handle(&["status"])?; +  assert!(re.is_match(&out), out); +  Ok(()) +} diff --git a/nitrocli/src/tests/storage.rs b/nitrocli/src/tests/storage.rs index be933ca..5b45bdc 100644 --- a/nitrocli/src/tests/storage.rs +++ b/nitrocli/src/tests/storage.rs @@ -20,15 +20,6 @@  use super::*;  #[test_device] -fn status_on_pro(device: nitrokey::Pro) { -  let res = Nitrocli::with_dev(device).handle(&["storage", "status"]); -  assert_eq!( -    res.unwrap_str_err(), -    "This command is only available on the Nitrokey Storage", -  ); -} - -#[test_device]  fn status_open_close(device: nitrokey::Storage) -> crate::Result<()> {    fn make_re(open: Option<bool>) -> regex::Regex {      let encrypted = match open { @@ -42,14 +33,11 @@ fn status_open_close(device: nitrokey::Storage) -> crate::Result<()> {        None => "(read-only|active|inactive)",      };      let re = format!( -      r#"^Status: -  SD card ID:        0x[[:xdigit:]]{{8}} -  firmware:          (un)?locked -  storage keys:      (not )?created -  volumes: -    unencrypted:     (read-only|active|inactive) -    encrypted:       {} -    hidden:          (read-only|active|inactive) +      r#" +    volumes: +      unencrypted:     (read-only|active|inactive) +      encrypted:       {} +      hidden:          (read-only|active|inactive)  $"#,        encrypted      ); @@ -57,21 +45,30 @@ $"#,    }    let mut ncli = Nitrocli::with_dev(device); -  let out = ncli.handle(&["storage", "status"])?; +  let out = ncli.handle(&["status"])?;    assert!(make_re(None).is_match(&out), out);    let _ = ncli.handle(&["storage", "open"])?; -  let out = ncli.handle(&["storage", "status"])?; +  let out = ncli.handle(&["status"])?;    assert!(make_re(Some(true)).is_match(&out), out);    let _ = ncli.handle(&["storage", "close"])?; -  let out = ncli.handle(&["storage", "status"])?; +  let out = ncli.handle(&["status"])?;    assert!(make_re(Some(false)).is_match(&out), out);    Ok(())  }  #[test_device] +fn encrypted_open_on_pro(device: nitrokey::Pro) { +  let res = Nitrocli::with_dev(device).handle(&["storage", "open"]); +  assert_eq!( +    res.unwrap_str_err(), +    "This command is only available on the Nitrokey Storage", +  ); +} + +#[test_device]  fn encrypted_open_close(device: nitrokey::Storage) -> crate::Result<()> {    let mut ncli = Nitrocli::with_dev(device);    let out = ncli.handle(&["storage", "open"])?;  | 
