Skip to content

Commit

Permalink
Return errors from YubiKey::open_by_serial that indicate a key may …
Browse files Browse the repository at this point in the history
…exist (iqlusioninc#477)

* Return errors from `YubiKey::open_by_serial` that indicate a key may exist

The only such error at the moment is `pcsc::Error::SharingViolation`, which
indicates a transient failure to access a specific reader that could have
been the one we needed (and so a future retry might succeed).

Closes iqlusioninc#458.

* Avoid resetting unused devices in YubiKey::open_by_serial

We only connect to readers so that we can determine their serial. We
now try to ensure that the order in which we connect to them doesn't
have an effect on their state after we are done.
  • Loading branch information
str4d authored Feb 12, 2023
1 parent d55079f commit 0809f30
Showing 1 changed file with 24 additions and 3 deletions.
27 changes: 24 additions & 3 deletions src/yubikey.rs
Original file line number Diff line number Diff line change
Expand Up @@ -205,19 +205,40 @@ impl YubiKey {
pub fn open_by_serial(serial: Serial) -> Result<Self> {
let mut readers = Context::open()?;

let mut open_error = None;

for reader in readers.iter()? {
let yubikey = match reader.open() {
Ok(yk) => yk,
Err(_) => continue,
Err(e) => {
// Save the first error we see that indicates we might have been able
// to find a matching YubiKey.
if open_error.is_none() {
if let Error::PcscError {
inner: Some(pcsc::Error::SharingViolation),
} = e
{
open_error = Some(e);
}
}
continue;
}
};

if serial == yubikey.serial() {
return Ok(yubikey);
} else {
// We didn't want this YubiKey; don't reset it.
let _ = yubikey.disconnect(pcsc::Disposition::LeaveCard);
}
}

error!("no YubiKey detected with serial: {}", serial);
Err(Error::NotFound)
Err(if let Some(e) = open_error {
e
} else {
error!("no YubiKey detected with serial: {}", serial);
Error::NotFound
})
}

/// Reconnect to a YubiKey.
Expand Down

0 comments on commit 0809f30

Please sign in to comment.