diff options
author | Daniel Mueller <deso@posteo.net> | 2017-04-09 19:36:35 -0700 |
---|---|---|
committer | Daniel Mueller <deso@posteo.net> | 2017-04-09 19:36:35 -0700 |
commit | f94d04578f44fc79212550203838f7c78e1ac414 (patch) | |
tree | 903bdcdd5edde580a557509ec55acfd1a5edad0f /nitrocli/src/main.rs | |
parent | c441df2c153c811af19f37bdfdc45a13c36e8f14 (diff) | |
download | nitrocli-f94d04578f44fc79212550203838f7c78e1ac414.tar.gz nitrocli-f94d04578f44fc79212550203838f7c78e1ac414.tar.bz2 |
Add 'status' command
The nitrokey supports a status command that instructs it to report
details about itself. This data includes general useful information such
as the current version of the firmware being installed along with more
contextual bits such as the number of remaining retries for the user
and admin PINs or whether the different volumes (unencrypted, encrypted,
hidden) are writable.
This change introduces the 'status' command line option that can be used
to retrieve this information from the nitrokey and to display it.
Diffstat (limited to 'nitrocli/src/main.rs')
-rw-r--r-- | nitrocli/src/main.rs | 82 |
1 files changed, 81 insertions, 1 deletions
diff --git a/nitrocli/src/main.rs b/nitrocli/src/main.rs index 32ecb3a..92aa79e 100644 --- a/nitrocli/src/main.rs +++ b/nitrocli/src/main.rs @@ -148,6 +148,86 @@ fn nitrokey_do(function: &NitroFunc) -> Result<()> { } +/// Pretty print the response of a status command. +fn print_status(response: &nitrokey::DeviceStatusResponse) { + println!("Status:"); + // We omit displaying information about the smartcard here as this + // program really is only about the SD card portion of the device. + println!(" SD card ID: {:#x}", response.active_sdcard_id); + println!(" firmware version: {}.{}", + response.version_major, + response.version_minor); + println!(" firmware: {}", + if response.firmware_locked != 0 { + "locked".to_string() + } else { + "unlocked".to_string() + }); + println!(" storage keys: {}", + if response.storage_keys_missing == 0 { + "created".to_string() + } else { + "not created".to_string() + }); + println!(" user retry count: {}", + response.user_password_retry_count); + println!(" admin retry count: {}", + response.admin_password_retry_count); + println!(" volumes:"); + println!(" unencrypted: {}", + if response.volume_active & nitrokey::VOLUME_ACTIVE_UNENCRYPTED == 0 { + "inactive" + } else if response.unencrypted_volume_read_only != 0 { + "read-only" + } else { + "active" + }); + println!(" encrypted: {}", + if response.volume_active & nitrokey::VOLUME_ACTIVE_ENCRYPTED == 0 { + "inactive" + } else if response.encrypted_volume_read_only != 0 { + "read-only" + } else { + "active" + }); + println!(" hidden: {}", + if response.volume_active & nitrokey::VOLUME_ACTIVE_HIDDEN == 0 { + "inactive" + } else if response.hidden_volume_read_only != 0 { + "read-only" + } else { + "active" + }); +} + + +/// Inquire the status of the nitrokey. +fn status() -> Result<()> { + type Response = nitrokey::Response<nitrokey::DeviceStatusResponse>; + + return nitrokey_do(&|handle| { + let payload = nitrokey::DeviceStatusCommand::new(); + let report = nitrokey::Report::from(payload); + + let report = transmit::<_, nitrokey::EmptyPayload>(handle, &report)?; + let response = &AsRef::<Response>::as_ref(&report.data).data; + + // TODO: We should probably check the success of the command as + // well. + if response.magic != nitrokey::MAGIC_NUMBER_STICK20_CONFIG { + let error = format!("Status response contains invalid magic: {:#x} \ + (expected: {:#x})", + response.magic, + nitrokey::MAGIC_NUMBER_STICK20_CONFIG); + return Err(Error::Error(error.to_string())); + } + + print_status(response); + return Ok(()); + }); +} + + /// Open the encrypted volume on the nitrokey. fn open() -> Result<()> { return nitrokey_do(&|handle| { @@ -203,7 +283,7 @@ fn run() -> i32 { return 1; } - commands!(&argv[1], [open, close]); + commands!(&argv[1], [open, close, status]); } fn main() { |