#[derive(Debug)]
pub(crate) struct HostDiagnostic {
pub(crate) client: String,
operator: String,
}
impl HostDiagnostic {
pub(crate) fn new(client: impl Into<String>, operator: impl Into<String>) -> Self {
Self {
client: client.into(),
operator: operator.into(),
}
}
pub(crate) fn operator(&self) -> &str {
&self.operator
}
pub(crate) fn into_client(self) -> String {
self.client
}
}
#[cfg(test)]
const CLIENT_FORBIDDEN_TOKENS: &[&str] = &[
"/var/",
"/dev/",
"/proc/",
"/sys/",
"/usr/",
"/etc/",
"/tmp/",
"/home/",
"/boxes/",
".wslconfig",
"/users/",
"/applications/",
"/system/",
"/private/",
".log",
"stderr",
"console output",
"debug files",
"sudo",
"dmesg",
"strace",
"rust_log",
"modprobe",
"lsmod",
"usermod",
"sysctl",
"apparmor_parser",
"apt install",
"which boxlite",
"diagnostic commands",
"shim",
"krun",
"gvproxy",
"bwrap",
"bubblewrap",
"apparmor",
"boxlite-guest",
"securityoptions",
];
#[cfg(test)]
pub(crate) fn assert_client_safe(client: &str, box_id: &str) {
let haystack = client.to_ascii_lowercase();
for token in CLIENT_FORBIDDEN_TOKENS {
assert!(
!haystack.contains(&token.to_ascii_lowercase()),
"client message leaks operator-only token {token:?}:\n{client}"
);
}
assert!(
!client.contains(box_id),
"client message leaks box id {box_id:?}:\n{client}"
);
}