aboutsummaryrefslogtreecommitdiff
path: root/nitrocli/src/main.rs
diff options
context:
space:
mode:
authorDaniel Mueller <deso@posteo.net>2017-04-09 19:36:35 -0700
committerDaniel Mueller <deso@posteo.net>2017-04-09 19:36:35 -0700
commitf94d04578f44fc79212550203838f7c78e1ac414 (patch)
tree903bdcdd5edde580a557509ec55acfd1a5edad0f /nitrocli/src/main.rs
parentc441df2c153c811af19f37bdfdc45a13c36e8f14 (diff)
downloadnitrocli-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.rs82
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() {