use std::{ fs::{read_dir, read_to_string}, io::Read, }; static WARNING_LINKS: [&str; 1] = ["https://lore.kernel.org/lkml/20211223141113.1240679-2-Jason@zx2c4.com/"]; fn ensure_safe_kernel_version() { let kernel_version = read_to_string("/proc/version").expect("/proc/version"); let v = kernel_version .split(' ') .nth(2) .expect("Unable to parse kernel version") .split('.') .take(2) .map(str::parse) .map(|x| x.expect("Unable to parse kernel version number")) .collect::>(); let [major, minor, ..] = v.as_slice() else { panic!("Unable to determine major and minor: {kernel_version}"); }; assert!( [major, minor] > [&5, &4], "kernel can't generate clean entropy: {}", WARNING_LINKS[0] ); } fn ensure_offline() { let paths = read_dir("/sys/class/net").expect("Unable to read network interfaces"); for entry in paths { let mut path = entry.expect("Unable to read directory entry").path(); if path .as_os_str() .to_str() .expect("Unable to decode UTF-8 filepath") .split('/') .last() .unwrap() == "lo" { continue; } path.push("operstate"); let isup = read_to_string(&path).expect("Unable to read operstate of network interfaces"); assert_ne!(isup.trim(), "up", "No network interfaces should be up"); } } pub fn ensure_safe() { if !std::env::vars() .any(|(name, _)| name == "SHOOT_SELF_IN_FOOT" || name == "INSECURE_HARDWARE_ALLOWED") { ensure_safe_kernel_version(); ensure_offline(); } } pub fn generate_entropy_of_size(byte_count: usize) -> Result, std::io::Error> { let mut vec = vec![0u8; byte_count]; let mut entropy_file = std::fs::File::open("/dev/urandom")?; entropy_file.read_exact(&mut vec[..])?; Ok(vec) }