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}"
);
}
}
}