diff --git a/Cargo.toml b/Cargo.toml index dc7b02d..85af95d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -35,7 +35,7 @@ proxmox-openid = "0.9.8" proxmox-resource-scheduling = "0.2.1" proxmox-subscription = "0.3" proxmox-sys = "0.4.2" -proxmox-tfa = { version = "3", features = ["api"] } +proxmox-tfa = { version = "4", features = ["api"] } proxmox-time = "1.1.3" [patch.crates-io] diff --git a/pmg-rs/debian/control b/pmg-rs/debian/control index ca22f0a..8d4a125 100644 --- a/pmg-rs/debian/control +++ b/pmg-rs/debian/control @@ -25,8 +25,8 @@ Build-Depends: librust-proxmox-http-0.8+default-dev, librust-proxmox-subscription-0.3+default-dev, librust-proxmox-sys-0.4+default-dev (>= 0.4.2-~~), - librust-proxmox-tfa-3+api-dev, - librust-proxmox-tfa-3+default-dev, + librust-proxmox-tfa-4+api-dev, + librust-proxmox-tfa-4+default-dev, librust-proxmox-time-1+default-dev (>= 1.1.3-~~), librust-serde-1+default-dev, librust-serde-bytes-0.11+default-dev, diff --git a/pmg-rs/src/tfa.rs b/pmg-rs/src/tfa.rs index 6e5207e..a14f1ee 100644 --- a/pmg-rs/src/tfa.rs +++ b/pmg-rs/src/tfa.rs @@ -255,6 +255,67 @@ mod export { } } + /// Takes the TFA challenge string (which is a json object) and verifies ther esponse against + /// it. + /// + /// Returns a result hash of the form: + /// ```text + /// { + /// "result": bool, // whether TFA was successful + /// "needs-saving": bool, // whether the user config needs saving + /// "tfa-limit-reached": bool, // whether the TFA limit was reached (config needs saving) + /// "totp-limit-reached": bool, // whether the TOTP limit was reached (config needs saving) + /// } + /// ``` + #[export] + fn authentication_verify2( + #[raw] raw_this: Value, + //#[try_from_ref] this: &Tfa, + userid: &str, + challenge: &str, //super::TfaChallenge, + response: &str, + origin: Option, + ) -> Result { + let this: &Tfa = (&raw_this).try_into()?; + let challenge: super::TfaChallenge = serde_json::from_str(challenge)?; + let response: super::TfaResponse = response.parse()?; + let mut inner = this.inner.lock().unwrap(); + let result = inner.verify( + &UserAccess::new(&raw_this)?, + userid, + &challenge, + response, + origin.as_ref(), + ); + Ok(match result { + TfaResult::Success { needs_saving } => TfaReturnValue { + result: true, + needs_saving, + ..Default::default() + }, + TfaResult::Locked => TfaReturnValue::default(), + TfaResult::Failure { + needs_saving, + totp_limit_reached, + tfa_limit_reached, + } => TfaReturnValue { + result: false, + needs_saving, + totp_limit_reached, + tfa_limit_reached, + }, + }) + } + + #[derive(Default, serde::Serialize)] + #[serde(rename_all = "kebab-case")] + struct TfaReturnValue { + result: bool, + needs_saving: bool, + totp_limit_reached: bool, + tfa_limit_reached: bool, + } + /// DEBUG HELPER: Get the current TOTP value for a given TOTP URI. #[export] fn get_current_totp_value(otp_uri: &str) -> Result { @@ -528,8 +589,9 @@ impl proxmox_tfa::api::OpenUserChallengeData for UserAccess { } } - fn check_valid_totp_code(&self, _: &str, _: i64) -> bool { - todo!() + // TODO: enable once we have UI/API admin stuff to unlock locked accounts + fn enable_lockout(&self) -> bool { + false } } diff --git a/pve-rs/debian/control b/pve-rs/debian/control index 17e495b..b15ae7c 100644 --- a/pve-rs/debian/control +++ b/pve-rs/debian/control @@ -23,11 +23,11 @@ Build-Depends: librust-proxmox-http-0.8+client-trait-dev, librust-proxmox-http-0.8+default-dev, librust-proxmox-openid-0.9+default-dev (>= 0.9.8-~~), - librust-proxmox-resource-scheduling-0.2+default-dev, + librust-proxmox-resource-scheduling-0.2+default-dev (>= 0.2.1-~~), librust-proxmox-subscription-0.3+default-dev, librust-proxmox-sys-0.4+default-dev (>= 0.4.2-~~), - librust-proxmox-tfa-3+api-dev, - librust-proxmox-tfa-3+default-dev, + librust-proxmox-tfa-4+api-dev, + librust-proxmox-tfa-4+default-dev, librust-proxmox-time-1+default-dev (>= 1.1.3-~~), librust-serde-1+default-dev, librust-serde-bytes-0.11+default-dev, diff --git a/pve-rs/src/tfa.rs b/pve-rs/src/tfa.rs index dcba485..aab7f2e 100644 --- a/pve-rs/src/tfa.rs +++ b/pve-rs/src/tfa.rs @@ -306,9 +306,6 @@ mod export { /// Takes the TFA challenge string (which is a json object) and verifies ther esponse against /// it. /// - /// NOTE: This returns a boolean whether the config data needs to be *saved* after this call - /// (to use up recovery keys!). - /// /// Returns a result hash of the form: /// ```text /// { @@ -997,7 +994,7 @@ impl proxmox_tfa::api::OpenUserChallengeData for UserAccess { } /// TODO: Enable this once we can consider most clusters to support the new format. - fn enable_lockout() -> bool { + fn enable_lockout(&self) -> bool { false } }