diff --git a/src/auth_state.rs b/src/auth_state.rs index 29caea52..087127e0 100644 --- a/src/auth_state.rs +++ b/src/auth_state.rs @@ -1,6 +1,7 @@ +use std::path::{Path, PathBuf}; + use anyhow::{bail, Error}; use serde_json::{json, Value}; -use nix::unistd::Uid; use proxmox::tools::{ time::epoch_i64, @@ -14,15 +15,23 @@ use proxmox::tools::{ use super::{PublicAuthState, PrivateAuthState}; -fn load_auth_state_locked(realm: &str, default: Option) -> Result<(String, std::fs::File, Vec), Error> { +fn load_auth_state_locked( + state_dir: &Path, + realm: &str, + default: Option, +) -> Result<(PathBuf, std::fs::File, Vec), Error> { + + let mut lock_path = state_dir.to_owned(); + lock_path.push("proxmox-openid-auth-state.lock"); let lock = open_file_locked( - "/tmp/proxmox-openid-auth-state.lock", + lock_path, std::time::Duration::new(10, 0), true )?; - let path = format!("/tmp/proxmox-openid-auth-state-{}", realm); + let mut path = state_dir.to_owned(); + path.push(format!("proxmox-openid-auth-state-{}", realm)); let now = epoch_i64(); @@ -43,27 +52,28 @@ fn load_auth_state_locked(realm: &str, default: Option) -> Result<(String Ok((path, lock, data)) } -fn replace_auth_state(path: &str, data: &Vec, state_owner: Uid) -> Result<(), Error> { +fn replace_auth_state( + path: &Path, + data: &Vec, +) -> Result<(), Error> { let mode = nix::sys::stat::Mode::from_bits_truncate(0o0600); - // set the correct owner/group/permissions while saving file - // owner(rw) = root - let options = CreateOptions::new() - .perm(mode) - .owner(state_owner); - + let options = CreateOptions::new().perm(mode); let raw = serde_json::to_string_pretty(data)?; - replace_file(&path, raw.as_bytes(), options)?; + replace_file(path, raw.as_bytes(), options)?; Ok(()) } -pub fn verify_public_auth_state(state: &str, state_owner: Uid) -> Result<(String, PrivateAuthState), Error> { +pub fn verify_public_auth_state( + state_dir: &Path, + state: &str, +) -> Result<(String, PrivateAuthState), Error> { let public_auth_state: PublicAuthState = serde_json::from_str(state)?; - let (path, _lock, old_data) = load_auth_state_locked(&public_auth_state.realm, None)?; + let (path, _lock, old_data) = load_auth_state_locked(state_dir, &public_auth_state.realm, None)?; let mut data: Vec = Vec::new(); @@ -82,18 +92,18 @@ pub fn verify_public_auth_state(state: &str, state_owner: Uid) -> Result<(String Some(entry) => entry, }; - replace_auth_state(&path, &data, state_owner)?; + replace_auth_state(&path, &data)?; Ok((public_auth_state.realm, entry)) } pub fn store_auth_state( + state_dir: &Path, realm: &str, auth_state: &PrivateAuthState, - state_owner: Uid, ) -> Result<(), Error> { - let (path, _lock, mut data) = load_auth_state_locked(realm, Some(json!([])))?; + let (path, _lock, mut data) = load_auth_state_locked(state_dir, realm, Some(json!([])))?; if data.len() > 100 { bail!("too many pending openid auth request for realm {}", realm); @@ -101,7 +111,7 @@ pub fn store_auth_state( data.push(serde_json::to_value(&auth_state)?); - replace_auth_state(&path, &data, state_owner)?; + replace_auth_state(&path, &data)?; Ok(()) } diff --git a/src/lib.rs b/src/lib.rs index eb2d9c7b..bd3c9af8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,7 +1,8 @@ +use std::path::Path; + use anyhow::{format_err, Error}; use serde::{Deserialize, Serialize}; use url::Url; -use nix::unistd::Uid; mod http_client; pub use http_client::http_client; @@ -112,13 +113,13 @@ impl OpenIdAuthenticator { }) } - pub fn authorize_url(&self, realm: &str, state_owner: Uid) -> Result { + pub fn authorize_url(&self, state_dir: &str, realm: &str) -> Result { let private_auth_state = PrivateAuthState::new(); let public_auth_state = private_auth_state.public_state_string(realm.to_string())?; let nonce = private_auth_state.nonce.clone(); - store_auth_state(realm, &private_auth_state, state_owner)?; + store_auth_state(Path::new(state_dir), realm, &private_auth_state)?; // Generate the authorization URL to which we'll redirect the user. let (authorize_url, _csrf_state, _nonce) = self.client @@ -138,10 +139,10 @@ impl OpenIdAuthenticator { } pub fn verify_public_auth_state( + state_dir: &str, state: &str, - state_owner: Uid, ) -> Result<(String, PrivateAuthState), Error> { - verify_public_auth_state(state, state_owner) + verify_public_auth_state(Path::new(state_dir), state) } pub fn verify_authorization_code(