Skip to content

Commit

Permalink
Fix a panic during Yubikey register/login
Browse files Browse the repository at this point in the history
The yubico crate uses blocking reqwest, and we called the `verify` from
a async thread. To prevent issues we need to wrap it within a
`spawn_blocking`.
  • Loading branch information
BlackDex committed Dec 18, 2022
1 parent d0b53a6 commit b60a4a6
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 7 deletions.
14 changes: 8 additions & 6 deletions src/api/core/two_factor/yubikey.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,14 +67,16 @@ fn get_yubico_credentials() -> Result<(String, String), Error> {
}
}

fn verify_yubikey_otp(otp: String) -> EmptyResult {
async fn verify_yubikey_otp(otp: String) -> EmptyResult {
let (yubico_id, yubico_secret) = get_yubico_credentials()?;

let config = Config::default().set_client_id(yubico_id).set_key(yubico_secret);

match CONFIG.yubico_server() {
Some(server) => verify(otp, config.set_api_hosts(vec![server])),
None => verify(otp, config),
Some(server) => {
tokio::task::spawn_blocking(move || verify(otp, config.set_api_hosts(vec![server]))).await.unwrap()
}
None => tokio::task::spawn_blocking(move || verify(otp, config)).await.unwrap(),
}
.map_res("Failed to verify OTP")
.and(Ok(()))
Expand Down Expand Up @@ -152,7 +154,7 @@ async fn activate_yubikey(
continue;
}

verify_yubikey_otp(yubikey.to_owned()).map_res("Invalid Yubikey OTP provided")?;
verify_yubikey_otp(yubikey.to_owned()).await.map_res("Invalid Yubikey OTP provided")?;
}

let yubikey_ids: Vec<String> = yubikeys.into_iter().map(|x| (x[..12]).to_owned()).collect();
Expand Down Expand Up @@ -188,7 +190,7 @@ async fn activate_yubikey_put(
activate_yubikey(data, headers, conn, ip).await
}

pub fn validate_yubikey_login(response: &str, twofactor_data: &str) -> EmptyResult {
pub async fn validate_yubikey_login(response: &str, twofactor_data: &str) -> EmptyResult {
if response.len() != 44 {
err!("Invalid Yubikey OTP length");
}
Expand All @@ -200,7 +202,7 @@ pub fn validate_yubikey_login(response: &str, twofactor_data: &str) -> EmptyResu
err!("Given Yubikey is not registered");
}

let result = verify_yubikey_otp(response.to_owned());
let result = verify_yubikey_otp(response.to_owned()).await;

match result {
Ok(_answer) => Ok(()),
Expand Down
2 changes: 1 addition & 1 deletion src/api/identity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,7 @@ async fn twofactor_auth(
Some(TwoFactorType::Webauthn) => {
_tf::webauthn::validate_webauthn_login(user_uuid, twofactor_code, conn).await?
}
Some(TwoFactorType::YubiKey) => _tf::yubikey::validate_yubikey_login(twofactor_code, &selected_data?)?,
Some(TwoFactorType::YubiKey) => _tf::yubikey::validate_yubikey_login(twofactor_code, &selected_data?).await?,
Some(TwoFactorType::Duo) => {
_tf::duo::validate_duo_login(data.username.as_ref().unwrap().trim(), twofactor_code, conn).await?
}
Expand Down

0 comments on commit b60a4a6

Please sign in to comment.