git.delta.rocks / jrsonnet / refs/commits / eae9921798a3

difftreelog

source

src/keys.rs1.7 KiBsourcehistory
1use std::str::FromStr;23use crate::{command::CommandExt, host::Config};4use anyhow::{anyhow, Result};5use log::warn;67impl Config {8	pub fn cached_key(&self, host: &str) -> Option<String> {9		let data = self.data();10		let key = data.hosts.get(host).map(|h| &h.encryption_key);11		if let Some(key) = key {12			if key.is_empty() {13				return None;14			}15		}16		key.cloned()17	}18	pub fn update_key(&self, host: &str, key: String) {19		let mut data = self.data_mut();20		let host = data.hosts.entry(host.to_string()).or_default();21		host.encryption_key = key.trim().to_string();22	}23	pub fn update_secret(&self, host: &str, name: &str, value: &[u8]) {24		let mut data = self.data_mut();25		let host = data.hosts.entry(host.to_string()).or_default();26		host.encrypted_secrets.insert(27			name.to_string(),28			format!("[ENCRYPTED:{}]", base64::encode(value)),29		);30	}3132	pub fn key(&self, host: &str) -> anyhow::Result<String> {33		if let Some(key) = self.cached_key(host) {34			Ok(key)35		} else {36			warn!("Loading key for {}", host);37			let key = self38				.command_on("host", "cat", false)39				.arg("/etc/ssh/ssh_host_ed25519_key.pub")40				.run_string()?;41			self.update_key(host, key.clone());42			Ok(key)43		}44	}45	pub fn recipient(&self, host: &str) -> anyhow::Result<age::ssh::Recipient> {46		let key = self.key(host)?;47		age::ssh::Recipient::from_str(&key).map_err(|e| anyhow!("parse recipient error: {:?}", e))48	}4950	pub fn orphaned_data(&self) -> Result<Vec<String>> {51		let mut out = Vec::new();52		let host_names = self.list_hosts()?;53		for hostname in self54			.data()55			.hosts56			.iter()57			.filter(|(_, host)| !host.encryption_key.is_empty())58			.map(|(n, _)| n)59		{60			if !host_names.contains(&hostname.to_owned()) {61				out.push(hostname.to_owned())62			}63		}6465		Ok(out)66	}67}