include!(concat!(env!("OUT_DIR"), "/embedded.rs"));
use std::fs;
use std::path::PathBuf;
use std::sync::OnceLock;
use anyhow::{Context, Result};
pub fn any_embedded() -> bool {
EMBED_CA.is_some()
|| EMBED_SERVER_CERT.is_some()
|| EMBED_SERVER_KEY.is_some()
|| EMBED_CLIENT_CERT.is_some()
|| EMBED_CLIENT_KEY.is_some()
|| EMBED_SERVER_ADDR.is_some()
|| EMBED_FINGERPRINT.is_some()
|| EMBED_SERVER_NAME.is_some()
}
#[derive(Debug, Default, Clone)]
pub struct Materialized {
pub ca: Option<PathBuf>,
pub server_cert: Option<PathBuf>,
pub server_key: Option<PathBuf>,
pub client_cert: Option<PathBuf>,
pub client_key: Option<PathBuf>,
}
pub fn materialize() -> Result<&'static Materialized> {
static CELL: OnceLock<Materialized> = OnceLock::new();
if let Some(m) = CELL.get() {
return Ok(m);
}
let m = materialize_uncached()?;
Ok(CELL.get_or_init(|| m))
}
fn materialize_uncached() -> Result<Materialized> {
if !any_byte_embedded() {
return Ok(Materialized::default());
}
let dir = std::env::temp_dir().join(format!("rusnel-embed-{}", std::process::id()));
fs::create_dir_all(&dir)
.with_context(|| format!("failed to create embed tempdir {}", dir.display()))?;
Ok(Materialized {
ca: write_if_some(&dir, "ca.pem", EMBED_CA, false)?,
server_cert: write_if_some(&dir, "server.pem", EMBED_SERVER_CERT, false)?,
server_key: write_if_some(&dir, "server.key", EMBED_SERVER_KEY, true)?,
client_cert: write_if_some(&dir, "client.pem", EMBED_CLIENT_CERT, false)?,
client_key: write_if_some(&dir, "client.key", EMBED_CLIENT_KEY, true)?,
})
}
fn any_byte_embedded() -> bool {
EMBED_CA.is_some()
|| EMBED_SERVER_CERT.is_some()
|| EMBED_SERVER_KEY.is_some()
|| EMBED_CLIENT_CERT.is_some()
|| EMBED_CLIENT_KEY.is_some()
}
fn write_if_some(
dir: &std::path::Path,
name: &str,
bytes: Option<&[u8]>,
secret: bool,
) -> Result<Option<PathBuf>> {
let Some(bytes) = bytes else { return Ok(None) };
let path = dir.join(name);
fs::write(&path, bytes).with_context(|| format!("failed to write {}", path.display()))?;
if secret {
#[cfg(unix)]
{
use std::os::unix::fs::PermissionsExt;
let mut perms = fs::metadata(&path)?.permissions();
perms.set_mode(0o600);
fs::set_permissions(&path, perms)?;
}
}
Ok(Some(path))
}