From 0c513e981f729d11dc7d3b46cf70377f4c972204 Mon Sep 17 00:00:00 2001 From: Lorenz Leutgeb Date: Fri, 3 Oct 2025 09:06:25 +0200 Subject: [PATCH] systemd: Support Credentials Add `mod credential` with `fn path` which implements a simple lookup of systemd credentials. See --- crates/radicle-systemd/src/credential.rs | 46 ++++++++++++++++++++++++ crates/radicle-systemd/src/lib.rs | 2 ++ 2 files changed, 48 insertions(+) create mode 100644 crates/radicle-systemd/src/credential.rs diff --git a/crates/radicle-systemd/src/credential.rs b/crates/radicle-systemd/src/credential.rs new file mode 100644 index 00000000..d367b620 --- /dev/null +++ b/crates/radicle-systemd/src/credential.rs @@ -0,0 +1,46 @@ +use std::env::{var, VarError::*}; +use std::ffi::OsString; +use std::fmt; +use std::path::{is_separator, PathBuf}; + +const CREDENTIALS_DIRECTORY: &str = "CREDENTIALS_DIRECTORY"; + +/// Takes a systemd credential ID. If the environment variable +/// `CREDENTIALS_DIRECTORY` is set and valid Unicode, and the file corresponding +/// to the credential exists, returns the path of the file corresponding to the +/// credential. +/// +/// Absence of the environment variable and inexistence of the file are handled +/// gracefully returning `Ok(None)`. +pub fn path(id: &str) -> Result, PathError> { + use PathError::*; + + if id.contains(is_separator) { + return Err(InvalidCredentialId { id: id.to_owned() }); + } + + let credential = match var(CREDENTIALS_DIRECTORY) { + Err(NotUnicode(os)) => return Err(EnvVarNotUnicode { os }), + Err(NotPresent) => return Ok(None), + Ok(env) => PathBuf::from(env).join(id), + }; + + Ok(credential.exists().then_some(credential)) +} + +/// The error returned by [`path`]. +#[derive(Debug)] +pub enum PathError { + InvalidCredentialId { id: String }, + EnvVarNotUnicode { os: OsString }, +} + +impl fmt::Display for PathError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + use PathError::*; + match self { + InvalidCredentialId { id } => write!(f, "The systemd credential ID '{id}' is invalid."), + EnvVarNotUnicode { os } => write!(f, "The value of environment variable '{CREDENTIALS_DIRECTORY}' is not valid Unicode (it lossily translates to '{}').", os.to_string_lossy()), + } + } +} diff --git a/crates/radicle-systemd/src/lib.rs b/crates/radicle-systemd/src/lib.rs index 5901b89f..0775257f 100644 --- a/crates/radicle-systemd/src/lib.rs +++ b/crates/radicle-systemd/src/lib.rs @@ -5,3 +5,5 @@ pub mod journal; #[cfg(all(feature = "listen", unix))] pub mod listen; + +pub mod credential;