aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Mueller <deso@posteo.net>2017-04-09 20:53:54 -0700
committerDaniel Mueller <deso@posteo.net>2017-04-09 20:53:54 -0700
commit3ce72e0ce1a0442786bc2600a7f276ae1994d90e (patch)
tree3263b7bf43242520d421f7af14367d273e544f15
parent1e4a359f42e081851b98a12511ffe24968bfc6da (diff)
downloadnitrocli-3ce72e0ce1a0442786bc2600a7f276ae1994d90e.tar.gz
nitrocli-3ce72e0ce1a0442786bc2600a7f276ae1994d90e.tar.bz2
Wait until encrypted volume is opened/closed
Until now we treated any response but "ok" and "idle" to the encrypted volume opening command as an error and reported it. However, the opening process is a potentially long running and it is very likely that the nitrokey reports a couple of "busy" messages. This change implements the logic to wait until the nitrokey either reports an error or a successful open.
-rw-r--r--nitrocli/src/main.rs41
1 files changed, 39 insertions, 2 deletions
diff --git a/nitrocli/src/main.rs b/nitrocli/src/main.rs
index 2408188..f3f7d7f 100644
--- a/nitrocli/src/main.rs
+++ b/nitrocli/src/main.rs
@@ -228,6 +228,25 @@ fn status() -> Result<()> {
}
+/// Poll the nitrokey until it reports to no longer be busy.
+fn wait(handle: &mut libhid::Handle) -> Result<nitrokey::StorageStatus> {
+ type Response = nitrokey::Response<nitrokey::StorageResponse>;
+
+ loop {
+ thread::sleep(time::Duration::from_millis(SEND_RECV_DELAY_MS));
+
+ let report = receive::<nitrokey::EmptyPayload>(handle)?;
+ let response = AsRef::<Response>::as_ref(&report.data);
+ let status = response.data.storage_status;
+
+ if status != nitrokey::StorageStatus::Busy &&
+ status != nitrokey::StorageStatus::BusyProgressbar {
+ return Ok(status);
+ }
+ }
+}
+
+
/// Open the encrypted volume on the nitrokey.
fn open() -> Result<()> {
type Response = nitrokey::Response<nitrokey::StorageResponse>;
@@ -241,7 +260,7 @@ fn open() -> Result<()> {
let report = transmit::<_, nitrokey::EmptyPayload>(handle, &report)?;
let response = AsRef::<Response>::as_ref(&report.data);
- let status = response.data.storage_status;
+ let mut status = response.data.storage_status;
if status == nitrokey::StorageStatus::WrongPassword {
pinentry::clear_passphrase()?;
@@ -254,6 +273,10 @@ fn open() -> Result<()> {
let error = "Opening encrypted volume failed: Wrong password";
return Err(Error::Error(error.to_string()));
}
+ if status == nitrokey::StorageStatus::Busy ||
+ status == nitrokey::StorageStatus::BusyProgressbar {
+ status = wait(handle)?;
+ }
if status != nitrokey::StorageStatus::Okay && status != nitrokey::StorageStatus::Idle {
let status = format!("{:?}", status);
let error = format!("Opening encrypted volume failed: {}", status);
@@ -267,11 +290,25 @@ fn open() -> Result<()> {
/// Close the previously opened encrypted volume.
fn close() -> Result<()> {
+ type Response = nitrokey::Response<nitrokey::StorageResponse>;
+
return nitrokey_do(&|handle| {
let payload = nitrokey::DisableEncryptedVolumeCommand::new();
let report = nitrokey::Report::from(payload);
- transmit::<_, nitrokey::EmptyPayload>(handle, &report)?;
+ let report = transmit::<_, nitrokey::EmptyPayload>(handle, &report)?;
+ let response = AsRef::<Response>::as_ref(&report.data);
+ let mut status = response.data.storage_status;
+
+ if status == nitrokey::StorageStatus::Busy ||
+ status == nitrokey::StorageStatus::BusyProgressbar {
+ status = wait(handle)?;
+ }
+ if status != nitrokey::StorageStatus::Okay && status != nitrokey::StorageStatus::Idle {
+ let status = format!("{:?}", status);
+ let error = format!("Closing encrypted volume failed: {}", status);
+ return Err(Error::Error(error));
+ }
return Ok(());
});
}