Skip to content

Commit

Permalink
auth: Fix multiple 'sk' keys configured, fails on first
Browse files Browse the repository at this point in the history
When a user has configured two or more 'sk' keys, eg Yubikeys,
pam-ssh-agent will fail if the first configured key isn't currently
plugged in.

Standard SSH utilities gracefully try the next key in this situation, so
we should too.  This is very helpful for users attempting to dogfood
their backup key.  ;-)

We correct this failure by catching the error, and trying the next key.

Signed-off-by: Jason Cooper <[email protected]>
  • Loading branch information
jac-cbi committed Apr 5, 2024
1 parent 52d7a20 commit af738ae
Showing 1 changed file with 15 additions and 2 deletions.
17 changes: 15 additions & 2 deletions src/auth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use crate::log::Log;
use anyhow::{Context, Result};
use getrandom::getrandom;
use signature::Verifier;
use ssh_agent_client_rs::Error as SACError;
use ssh_key::public::KeyData;
use ssh_key::{AuthorizedKeys, PublicKey};
use std::collections::HashSet;
Expand All @@ -28,13 +29,25 @@ pub fn authenticate(
"found a matching key: {}",
key.fingerprint(Default::default())
))?;
return sign_and_verify(key, agent);
// Allow sign_and_verify() to return RemoteFailure (key not loaded / present),
// and try the next configured key
match sign_and_verify(&key, &mut agent) {
Ok(res) => return Ok(res),
Err(e) => {
if let Some(SACError::RemoteFailure) = e.downcast_ref::<SACError>() {
log.debug(format!("SSHAgent: RemoteFailure; trying next key"))?;
continue;
} else {
return Err(e);
}
}
}
}
}
Ok(false)
}

fn sign_and_verify(key: PublicKey, mut agent: impl SSHAgent) -> Result<bool> {
fn sign_and_verify(key: &PublicKey, agent: &mut impl SSHAgent) -> Result<bool> {
let mut data: [u8; CHALLENGE_SIZE] = [0_u8; CHALLENGE_SIZE];
getrandom(data.as_mut_slice())?;
let sig = agent.sign(&key, data.as_ref())?;
Expand Down

0 comments on commit af738ae

Please sign in to comment.