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

nordisk/holger

server/lib/src/twin_tls/mtls_off.rs

//! **No mutual TLS** (a build without `estate`, H2's estate cut): the upstream and the
//! downstream link no `nordisk-twin`. No replication credential can exist in this build
//! ([`Credential`] is uninhabited), one found on disk is refused by name rather than
//! ignored, and a config that declares a `replication_door` refuses the start.

use super::*;
use std::sync::Arc;

/// What a build without the estate says, by name, wherever the twin's TLS would run.
pub const NO_ESTATE: &str = "this holger was built without the estate (feature `estate`): the twin over mutual TLS (nordisk-twin) is not in this build";

/// A replication credential; uninhabited without `estate`.
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Credential {}

impl Credential {
    /// The doors it dials: unreachable, there is none.
    pub fn doors(&self) -> Vec<String> {
        match *self {}
    }
}

/// The installed credential of `purpose`: never one in this build. A credential
/// directory left on disk (the box was an estate box) is refused by name, so a twin
/// never silently follows in the clear past a credential it cannot read.
pub fn load(root: &Path, purpose: Purpose) -> Result<Option<Credential>, String> {
    load_dir(&purpose.dir(root))
}

/// [`load`] over a credential directory (a mirror source's `Twin { ron_dir }`).
pub fn load_dir(dir: &Path) -> Result<Option<Credential>, String> {
    if dir.exists() {
        return Err(ec::TWIN_PAIRING_REFUSED.tag(format!(
            "{NO_ESTATE}, so the replication credential under {} cannot be read",
            dir.display()
        )));
    }
    Ok(None)
}

/// A channel over a credential: unreachable, there is none.
pub async fn channel(cred: &Credential) -> Result<(tonic::transport::Channel, String), String> {
    match *cred {}
}

/// The replication door is not in this build: the start is refused by name.
pub fn serve_door(
    _root: &Path,
    _cfg: &ReplicationDoorConfig,
    _bind: &str,
    _grpc: Arc<crate::grpc::HolgerGrpc>,
    _posture: Arc<crate::twin::TwinPosture>,
    _max_body_bytes: usize,
) -> anyhow::Result<SocketAddr> {
    anyhow::bail!(ec::TWIN_NO_REPLICATION_DOOR.tag(format!(
        "{NO_ESTATE}: the config declares a `replication_door`. REFUSING TO START."
    )))
}

/// What `InstallTwinCertificate` answers (nordisk-twin's `credential::Installed`); never
/// made in this build.
#[derive(Debug, Clone)]
pub struct Installed {
    pub days_left: i64,
    pub not_after: i64,
    pub renewal: bool,
}

fn refused() -> String {
    ec::TWIN_PAIRING_REFUSED.tag(format!("{NO_ESTATE}: this box pairs no replication reader"))
}

/// **`TwinCsr`**: refused by name in this build.
pub fn request(
    _root: &Path,
    _purpose: Purpose,
    _is_twin: bool,
) -> Result<(String, String), String> {
    Err(refused())
}

/// **`IssueTwinCertificate`**: refused by name in this build.
pub fn issue(
    _root: &Path,
    _principal: &str,
    _csr_pem: &str,
    _is_twin: bool,
) -> Result<Issued, String> {
    Err(refused())
}

/// **`InstallTwinCertificate`**: refused by name in this build.
pub fn install(
    _root: &Path,
    _purpose: Purpose,
    _is_twin: bool,
    _cert_pem: &str,
    _ca_pem: &str,
    _port: u32,
    _hosts: &[String],
) -> Result<Installed, String> {
    Err(refused())
}

/// The deliberate re-point: refused by name in this build.
#[allow(clippy::too_many_arguments)]
pub fn repoint(
    _root: &Path,
    _is_twin: bool,
    _primary: &str,
    _cert_pem: &str,
    _ca_pem: &str,
    _port: u32,
    _hosts: &[String],
    _now_unix: u64,
) -> Result<(Installed, crate::twin::RoleRecord), String> {
    Err(refused())
}

/// The door shows no identity in this build.
pub fn door_identity_pem() -> Option<String> {
    None
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn without_the_estate_no_credential_is_read_and_one_on_disk_is_refused_by_name() {
        let root = std::env::temp_dir().join(format!("holger-twin-tls-off-{}", std::process::id()));
        let _ = std::fs::remove_dir_all(&root);
        assert!(
            load(&root, Purpose::Twin).unwrap().is_none(),
            "nothing on disk: not certified"
        );
        std::fs::create_dir_all(Purpose::Recharge.dir(&root)).unwrap();
        let e = load(&root, Purpose::Recharge).unwrap_err();
        assert!(
            e.contains(ec::TWIN_PAIRING_REFUSED.code) && e.contains("without the estate"),
            "{e}"
        );
        let _ = std::fs::remove_dir_all(&root);
    }

    #[test]
    fn without_the_estate_a_declared_door_refuses_the_start() {
        let root = std::env::temp_dir();
        let grpc = Arc::new(crate::grpc::HolgerGrpc::new(
            crate::exposed::fast_routes::FastRoutes::new(Vec::new()),
        ));
        let e = serve_door(
            &root,
            &ReplicationDoorConfig::default(),
            "127.0.0.1:0",
            grpc,
            Arc::new(Default::default()),
            1,
        )
        .unwrap_err()
        .to_string();
        assert!(
            e.contains(ec::TWIN_NO_REPLICATION_DOOR.code) && e.contains("REFUSING TO START"),
            "{e}"
        );
        assert!(door_identity_pem().is_none());
    }

    #[test]
    fn without_the_estate_every_pairing_step_is_refused_by_name() {
        let root = std::env::temp_dir();
        for e in [
            request(&root, Purpose::Twin, true).unwrap_err(),
            issue(&root, TWIN_PRINCIPAL, "csr", false)
                .map(|_| ())
                .unwrap_err(),
            install(&root, Purpose::Twin, true, "c", "ca", 1, &[])
                .map(|_| ())
                .unwrap_err(),
            repoint(&root, true, "p", "c", "ca", 1, &[], 0)
                .map(|_| ())
                .unwrap_err(),
        ] {
            assert!(
                e.contains(ec::TWIN_PAIRING_REFUSED.code) && e.contains("without the estate"),
                "{e}"
            );
        }
    }
}