Your browser sucks, JavaScript disabled! Gunnar's console needs JavaScript and WebAssembly. Git over SSH on port 2222 does not.

nordisk/holger

mannequin/src/config.rs

use serde::{Deserialize, Serialize};
use std::path::PathBuf;

/// Configuration for holger-mannequin.
/// If cert fields are empty/None, fresh certs are generated at startup.
/// Otherwise, the supplied certs (inline PEM or file paths) are used.
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct MannequinConfig {
    #[serde(default = "default_port")]
    pub port: u16,

    /// CA certificate: inline PEM string or file path
    #[serde(default)]
    pub ca_cert: Option<CertSource>,

    /// CA private key: inline PEM string or file path
    #[serde(default)]
    pub ca_key: Option<CertSource>,

    /// Default server cert: inline PEM string or file path
    #[serde(default)]
    pub server_cert: Option<CertSource>,

    /// Default server key: inline PEM string or file path
    #[serde(default)]
    pub server_key: Option<CertSource>,
}

/// A certificate/key can be supplied inline (base64/PEM) or as a file path.
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum CertSource {
    Inline(String),
    File { path: PathBuf },
}

impl CertSource {
    pub fn resolve(&self) -> anyhow::Result<String> {
        match self {
            CertSource::Inline(pem) => Ok(pem.clone()),
            CertSource::File { path } => std::fs::read_to_string(path)
                .map_err(|e| anyhow::anyhow!("Failed to read {}: {}", path.display(), e)),
        }
    }
}

fn default_port() -> u16 {
    9999
}

impl MannequinConfig {
    /// Load from a RON file, or return default (generate everything).
    pub fn load(path: &std::path::Path) -> anyhow::Result<Self> {
        let file = std::fs::File::open(path)?;
        let reader = std::io::BufReader::new(file);
        let config: MannequinConfig = ron::de::from_reader(reader)?;
        Ok(config)
    }

    /// Returns true if CA certs are supplied (don't generate).
    pub fn has_ca(&self) -> bool {
        self.ca_cert.is_some() && self.ca_key.is_some()
    }
}