aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md2
-rw-r--r--doc/nitrocli.110
-rw-r--r--doc/nitrocli.1.pdfbin42203 -> 42810 bytes
-rw-r--r--src/commands.rs31
-rw-r--r--src/tests/run.rs16
-rw-r--r--src/tests/status.rs20
6 files changed, 60 insertions, 19 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 83fc8d9..248069e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -15,6 +15,8 @@ Unreleased
device to connect to
- Added `--usb-path` option that restricts the USB path of the device to
connect to
+ - Changed the `status` command to print the status for all attached Nitrokey
+ devices that match the specified filter.
- Bumped `structopt` dependency to `0.3.17`
diff --git a/doc/nitrocli.1 b/doc/nitrocli.1
index 6fb1fd9..87b52b4 100644
--- a/doc/nitrocli.1
+++ b/doc/nitrocli.1
@@ -67,10 +67,12 @@ To omit the serial number of Nitrokey Storage devices instead of connecting to
them, set the \fB\-\-no-connect\fR option.
.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. 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.
+Print the status of the attached Nitrokey devices that match the filter
+options (see the Device selection section), including the stick serial number,
+the firmware version, and the PIN retry count.
+For Nitrokey Storage devices, 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.
diff --git a/doc/nitrocli.1.pdf b/doc/nitrocli.1.pdf
index d98ab41..d040b6b 100644
--- a/doc/nitrocli.1.pdf
+++ b/doc/nitrocli.1.pdf
Binary files differ
diff --git a/src/commands.rs b/src/commands.rs
index 597fcd8..a4e805e 100644
--- a/src/commands.rs
+++ b/src/commands.rs
@@ -363,19 +363,24 @@ fn print_storage_status(
}
/// Query and pretty print the status that is common to all Nitrokey devices.
-fn print_status(ctx: &mut Context<'_>, device: &nitrokey::DeviceWrapper<'_>) -> anyhow::Result<()> {
+fn print_status(
+ ctx: &mut Context<'_>,
+ idx: usize,
+ device: &nitrokey::DeviceWrapper<'_>,
+) -> anyhow::Result<()> {
let serial_number = device
.get_serial_number()
.context("Could not query the serial number")?;
println!(
ctx,
- r#"Status:
+ r#"Device #{idx}:
model: {model}
serial number: {id}
firmware version: {fwv}
user retry count: {urc}
admin retry count: {arc}"#,
+ idx = idx,
model = args::DeviceModel::from(device.get_model()).as_user_facing_str(),
id = serial_number,
fwv = device
@@ -402,7 +407,27 @@ fn print_status(ctx: &mut Context<'_>, device: &nitrokey::DeviceWrapper<'_>) ->
/// Inquire the status of the nitrokey.
pub fn status(ctx: &mut Context<'_>) -> anyhow::Result<()> {
- with_device(ctx, |ctx, device| print_status(ctx, &device))
+ let device_infos = find_devices(&ctx.config)?;
+ anyhow::ensure!(
+ !device_infos.is_empty(),
+ "Nitrokey device not found{}",
+ format_filter(&ctx.config)
+ );
+
+ let mut manager =
+ nitrokey::take().context("Failed to acquire access to Nitrokey device manager")?;
+ for (idx, device_info) in device_infos.iter().enumerate() {
+ let device = manager
+ .connect_path(device_info.path.deref())
+ .with_context(|| {
+ format!(
+ "Failed to connect to Nitrokey device at path {}",
+ device_info.path
+ )
+ })?;
+ print_status(ctx, idx, &device)?;
+ }
+ Ok(())
}
/// List the attached Nitrokey devices.
diff --git a/src/tests/run.rs b/src/tests/run.rs
index b39b1da..3dd4c98 100644
--- a/src/tests/run.rs
+++ b/src/tests/run.rs
@@ -113,7 +113,7 @@ fn config_file() {
fn connect_multiple(_model: nitrokey::Model) -> anyhow::Result<()> {
let devices = nitrokey::list_devices()?;
if devices.len() > 1 {
- let res = Nitrocli::new().handle(&["status"]);
+ let res = Nitrocli::new().handle(&["lock"]);
let err = res.unwrap_err().to_string();
assert_eq!(
err,
@@ -190,16 +190,12 @@ fn connect_model(_model: nitrokey::Model) -> anyhow::Result<()> {
model.to_lowercase()
)
);
- } else if count == 1 {
- assert!(res?.contains(&format!("model: {}\n", model)));
} else {
- let err = res.unwrap_err().to_string();
assert_eq!(
- err,
- format!(
- "Multiple Nitrokey devices found (filter: model={}). ",
- model.to_lowercase()
- ) + "Use the --model, --serial-number, and --usb-path options to select one"
+ count,
+ res?
+ .matches(&format!("model: {}\n", model))
+ .count()
);
}
}
@@ -213,7 +209,7 @@ fn connect_usb_path_model_serial(_model: nitrokey::Model) -> anyhow::Result<()>
for device in devices {
let mut args = Vec::new();
args.push("status".to_owned());
- args.push(format!("--usb-path={}", device.path));
+ args.push(format!("--usb-path={}", &device.path));
if let Some(model) = device.model {
args.push(format!("--model={}", model.to_string().to_lowercase()));
}
diff --git a/src/tests/status.rs b/src/tests/status.rs
index fe69d78..1f5bbf7 100644
--- a/src/tests/status.rs
+++ b/src/tests/status.rs
@@ -24,7 +24,7 @@ fn not_found() {
#[test_device(pro)]
fn output_pro(model: nitrokey::Model) -> anyhow::Result<()> {
let re = regex::Regex::new(
- r#"^Status:
+ r#"^Device #0:
model: Pro
serial number: 0x[[:xdigit:]]{8}
firmware version: v\d+\.\d+
@@ -42,7 +42,7 @@ $"#,
#[test_device(storage)]
fn output_storage(model: nitrokey::Model) -> anyhow::Result<()> {
let re = regex::Regex::new(
- r#"^Status:
+ r#"^Device #0:
model: Storage
serial number: 0x[[:xdigit:]]{8}
firmware version: v\d+\.\d+
@@ -64,3 +64,19 @@ $"#,
assert!(re.is_match(&out), out);
Ok(())
}
+
+#[test_device]
+fn output_multiple(_model: nitrokey::Model) -> anyhow::Result<()> {
+ let devices = nitrokey::list_devices()?;
+ let out = Nitrocli::new().handle(&["status"])?;
+ for (idx, device) in devices.iter().enumerate() {
+ assert!(out.contains(&format!("Device #{}:\n", idx)), out);
+ if let Some(model) = device.model {
+ assert!(out.contains(&format!("model: {}\n", model)), out);
+ }
+ if let Some(sn) = device.serial_number {
+ assert!(out.contains(&format!("serial number: {}\n", sn)), out);
+ }
+ }
+ Ok(())
+}