Add support for choosing between multiple authenticators

This commit is contained in:
pjht 2023-08-16 11:58:15 -05:00
parent 55112f5869
commit f57c373faa
Signed by: pjht
GPG Key ID: CA239FC6934E6F3A

View File

@ -1,7 +1,7 @@
use std::{ use std::{
fs::Permissions, fs::Permissions,
os::unix::prelude::PermissionsExt, os::unix::prelude::PermissionsExt,
path::{Path, PathBuf}, fmt::Display, path::{Path, PathBuf}, fmt::Display, io::Write,
}; };
use anyhow::anyhow; use anyhow::anyhow;
@ -9,7 +9,7 @@ use bitflags::bitflags;
use clap::{Parser, ValueEnum}; use clap::{Parser, ValueEnum};
use ctap_hid_fido2::{ use ctap_hid_fido2::{
fidokey::{CredentialSupportedKeyType, MakeCredentialArgsBuilder}, fidokey::{CredentialSupportedKeyType, MakeCredentialArgsBuilder},
verifier, FidoKeyHidFactory, LibCfg, verifier, LibCfg, get_fidokey_devices, FidoKeyHid,
}; };
use ssh_encoding::{Decode, Encode, LineEnding}; use ssh_encoding::{Decode, Encode, LineEnding};
use ssh_key::{private, PrivateKey}; use ssh_key::{private, PrivateKey};
@ -89,11 +89,45 @@ fn main() -> anyhow::Result<()> {
let challenge = verifier::create_challenge(); let challenge = verifier::create_challenge();
let devices = get_fidokey_devices();
let device = if devices.len() > 1 {
println!("Availible devices:");
for (i, device) in devices.iter().enumerate() {
println!("\t{}: {}", i + 1, device.product_string);
}
let mut buf = String::new();
loop {
print!("Device number: ");
std::io::stdout().flush()?;
buf.clear();
std::io::stdin().read_line(&mut buf)?;
if let Ok(num) = buf.trim().parse::<usize>() {
if num == 0 {
println!("Invalid number");
continue;
}
if let Some(device) = devices.get(num - 1) {
break device;
} else {
println!("Invalid number");
continue;
}
} else {
println!("Invalid number");
continue;
}
}
} else {
&devices[0]
};
let mut libcfg = LibCfg::init(); let mut libcfg = LibCfg::init();
libcfg.keep_alive_msg = "Touch the authenticator now.".into(); libcfg.keep_alive_msg = "Touch the authenticator now.".into();
let device = FidoKeyHidFactory::create(&libcfg)?; let device = FidoKeyHid::new(&[device.param.clone()], &libcfg)?;
let device_has_pin = device.get_info().map_or(false, |info| info.options.contains(&("clientPin".into(), true)));
let device_has_pin = device.get_info()?.options.contains(&("clientPin".into(), true));
let pin = if device_has_pin { let pin = if device_has_pin {
rpassword::prompt_password("Enter FIDO2 PIN: ")? rpassword::prompt_password("Enter FIDO2 PIN: ")?
} else { } else {