use std::path::Path;
use anyhow::{Context as _, Result, bail};
use openmoat_core::{CompiledPolicy, Decision, Taint, Verdict};
use openmoat_hosts::{HookEvent, Host};
use crate::context;
use crate::home::Home;
use crate::realpath::FsPathResolver;
pub fn of_session(
home: &Home,
host: Host,
session: &str,
policy: &CompiledPolicy<'_>,
cwd: &str,
) -> Result<Taint> {
let events = home
.open_audit()?
.session(session)
.context("reading this session from the audit log")?;
let mut taint = Taint::default();
for event in events
.iter()
.filter(|e| e.host == host.id() && ran(host, e.verdict))
{
if event.action_unreadable {
bail!("audit event {} of this session cannot be decoded", event.id);
}
let Some(action) = &event.action else {
continue;
};
let cwd = event
.cwd
.as_deref()
.map_or_else(|| cwd.to_owned(), |c| context::path_string(Path::new(c)));
taint.absorb(policy.exposure(action, &cwd, &FsPathResolver));
}
Ok(taint)
}
fn ran(host: Host, verdict: Verdict) -> bool {
host.answer(&HookEvent::PreToolUse, &Decision::new(verdict))
.verdict
!= Verdict::Deny
}