update proxmox-tfa to 2.0
and fix still-very-bad updater usage in config api call... Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
This commit is contained in:
parent
0fee4ff2a4
commit
e6e2927e72
@ -100,7 +100,7 @@ proxmox-lang = "1"
|
|||||||
proxmox-router = { version = "1.1", features = [ "cli" ] }
|
proxmox-router = { version = "1.1", features = [ "cli" ] }
|
||||||
proxmox-schema = { version = "1", features = [ "api-macro" ] }
|
proxmox-schema = { version = "1", features = [ "api-macro" ] }
|
||||||
proxmox-section-config = "1"
|
proxmox-section-config = "1"
|
||||||
proxmox-tfa = { version = "1.3", features = [ "api", "api-types" ] }
|
proxmox-tfa = { version = "2", features = [ "api", "api-types" ] }
|
||||||
proxmox-time = "1"
|
proxmox-time = "1"
|
||||||
proxmox-uuid = "1"
|
proxmox-uuid = "1"
|
||||||
proxmox-serde = "0.1"
|
proxmox-serde = "0.1"
|
||||||
|
@ -228,6 +228,7 @@ fn add_tfa_entry(
|
|||||||
value,
|
value,
|
||||||
challenge,
|
challenge,
|
||||||
r#type,
|
r#type,
|
||||||
|
None,
|
||||||
)?;
|
)?;
|
||||||
crate::config::tfa::write(&data)?;
|
crate::config::tfa::write(&data)?;
|
||||||
Ok(out)
|
Ok(out)
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
//! For now this only has the TFA subdir, which is in this file.
|
//! For now this only has the TFA subdir, which is in this file.
|
||||||
//! If we add more, it should be moved into a sub module.
|
//! If we add more, it should be moved into a sub module.
|
||||||
|
|
||||||
use anyhow::Error;
|
use anyhow::{format_err, Error};
|
||||||
use hex::FromHex;
|
use hex::FromHex;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use proxmox_router::{Router, RpcEnvironment, Permission, SubdirMap};
|
|
||||||
use proxmox_schema::api;
|
|
||||||
use proxmox_router::list_subdirs_api_method;
|
use proxmox_router::list_subdirs_api_method;
|
||||||
|
use proxmox_router::{Permission, Router, RpcEnvironment, SubdirMap};
|
||||||
|
use proxmox_schema::api;
|
||||||
|
|
||||||
use pbs_api_types::PROXMOX_CONFIG_DIGEST_SCHEMA;
|
use pbs_api_types::PROXMOX_CONFIG_DIGEST_SCHEMA;
|
||||||
|
|
||||||
@ -47,6 +48,15 @@ pub fn get_webauthn_config(
|
|||||||
Ok(Some(config))
|
Ok(Some(config))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[api()]
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "kebab-case")]
|
||||||
|
/// Deletable property name
|
||||||
|
pub enum DeletableProperty {
|
||||||
|
/// Delete the origin property.
|
||||||
|
Origin,
|
||||||
|
}
|
||||||
|
|
||||||
#[api(
|
#[api(
|
||||||
protected: true,
|
protected: true,
|
||||||
input: {
|
input: {
|
||||||
@ -55,6 +65,14 @@ pub fn get_webauthn_config(
|
|||||||
flatten: true,
|
flatten: true,
|
||||||
type: WebauthnConfigUpdater,
|
type: WebauthnConfigUpdater,
|
||||||
},
|
},
|
||||||
|
delete: {
|
||||||
|
description: "List of properties to delete.",
|
||||||
|
type: Array,
|
||||||
|
optional: true,
|
||||||
|
items: {
|
||||||
|
type: DeletableProperty,
|
||||||
|
}
|
||||||
|
},
|
||||||
digest: {
|
digest: {
|
||||||
optional: true,
|
optional: true,
|
||||||
schema: PROXMOX_CONFIG_DIGEST_SCHEMA,
|
schema: PROXMOX_CONFIG_DIGEST_SCHEMA,
|
||||||
@ -65,6 +83,7 @@ pub fn get_webauthn_config(
|
|||||||
/// Update the TFA configuration.
|
/// Update the TFA configuration.
|
||||||
pub fn update_webauthn_config(
|
pub fn update_webauthn_config(
|
||||||
webauthn: WebauthnConfigUpdater,
|
webauthn: WebauthnConfigUpdater,
|
||||||
|
delete: Option<Vec<DeletableProperty>>,
|
||||||
digest: Option<String>,
|
digest: Option<String>,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
let _lock = tfa::write_lock();
|
let _lock = tfa::write_lock();
|
||||||
@ -79,13 +98,34 @@ pub fn update_webauthn_config(
|
|||||||
&crate::config::tfa::webauthn_config_digest(&wa)?,
|
&crate::config::tfa::webauthn_config_digest(&wa)?,
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
if let Some(ref rp) = webauthn.rp { wa.rp = rp.clone(); }
|
|
||||||
if let Some(ref origin) = webauthn.origin { wa.origin = origin.clone(); }
|
if let Some(delete) = delete {
|
||||||
if let Some(ref id) = webauthn.id { wa.id = id.clone(); }
|
for delete in delete {
|
||||||
|
match delete {
|
||||||
|
DeletableProperty::Origin => {
|
||||||
|
wa.origin = None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(rp) = webauthn.rp {
|
||||||
|
wa.rp = rp;
|
||||||
|
}
|
||||||
|
if webauthn.origin.is_some() {
|
||||||
|
wa.origin = webauthn.origin;
|
||||||
|
}
|
||||||
|
if let Some(id) = webauthn.id {
|
||||||
|
wa.id = id;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
let rp = webauthn.rp.unwrap();
|
let rp = webauthn
|
||||||
let origin = webauthn.origin.unwrap();
|
.rp
|
||||||
let id = webauthn.id.unwrap();
|
.ok_or_else(|| format_err!("missing proeprty: 'rp'"))?;
|
||||||
|
let origin = webauthn.origin;
|
||||||
|
let id = webauthn
|
||||||
|
.id
|
||||||
|
.ok_or_else(|| format_err!("missing property: 'id'"))?;
|
||||||
tfa.webauthn = Some(WebauthnConfig { rp, origin, id });
|
tfa.webauthn = Some(WebauthnConfig { rp, origin, id });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,7 +127,7 @@ impl TfaUserChallengeData {
|
|||||||
/// Get an optional TFA challenge for a user.
|
/// Get an optional TFA challenge for a user.
|
||||||
pub fn login_challenge(userid: &Userid) -> Result<Option<TfaChallenge>, Error> {
|
pub fn login_challenge(userid: &Userid) -> Result<Option<TfaChallenge>, Error> {
|
||||||
let _lock = write_lock()?;
|
let _lock = write_lock()?;
|
||||||
read()?.authentication_challenge(UserAccess, userid.as_str())
|
read()?.authentication_challenge(UserAccess, userid.as_str(), None)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add a TOTP entry for a user. Returns the ID.
|
/// Add a TOTP entry for a user. Returns the ID.
|
||||||
@ -176,7 +176,7 @@ pub fn add_webauthn_registration(userid: &Userid, description: String) -> Result
|
|||||||
let _lock = crate::config::tfa::write_lock();
|
let _lock = crate::config::tfa::write_lock();
|
||||||
let mut data = read()?;
|
let mut data = read()?;
|
||||||
let challenge =
|
let challenge =
|
||||||
data.webauthn_registration_challenge(UserAccess, userid.as_str(), description)?;
|
data.webauthn_registration_challenge(UserAccess, userid.as_str(), description, None)?;
|
||||||
write(&data)?;
|
write(&data)?;
|
||||||
Ok(challenge)
|
Ok(challenge)
|
||||||
}
|
}
|
||||||
@ -189,7 +189,8 @@ pub fn finish_webauthn_registration(
|
|||||||
) -> Result<String, Error> {
|
) -> Result<String, Error> {
|
||||||
let _lock = crate::config::tfa::write_lock();
|
let _lock = crate::config::tfa::write_lock();
|
||||||
let mut data = read()?;
|
let mut data = read()?;
|
||||||
let id = data.webauthn_registration_finish(UserAccess, userid.as_str(), challenge, response)?;
|
let id =
|
||||||
|
data.webauthn_registration_finish(UserAccess, userid.as_str(), challenge, response, None)?;
|
||||||
write(&data)?;
|
write(&data)?;
|
||||||
Ok(id)
|
Ok(id)
|
||||||
}
|
}
|
||||||
@ -203,7 +204,7 @@ pub fn verify_challenge(
|
|||||||
let _lock = crate::config::tfa::write_lock();
|
let _lock = crate::config::tfa::write_lock();
|
||||||
let mut data = read()?;
|
let mut data = read()?;
|
||||||
if data
|
if data
|
||||||
.verify(UserAccess, userid.as_str(), challenge, response)?
|
.verify(UserAccess, userid.as_str(), challenge, response, None)?
|
||||||
.needs_saving()
|
.needs_saving()
|
||||||
{
|
{
|
||||||
write(&data)?;
|
write(&data)?;
|
||||||
@ -261,11 +262,10 @@ impl proxmox_tfa::api::OpenUserChallengeData for UserAccess {
|
|||||||
Err(err) => {
|
Err(err) => {
|
||||||
eprintln!(
|
eprintln!(
|
||||||
"failed to parse challenge data for user {}: {}",
|
"failed to parse challenge data for user {}: {}",
|
||||||
userid,
|
userid, err
|
||||||
err
|
|
||||||
);
|
);
|
||||||
Default::default()
|
Default::default()
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user