//! What a tool or Podman writes on standard error reaches `brokerd`'s log escaped, one entry per //! event: it cannot start a line of its own or forge a runbook pointer (M3b review finding 5). //! Do not edit. #[path = "support/build.rs"] mod build; #[path = "support/fake_podman.rs"] mod fake_podman; use brokerd::container::{CANNOT_START, COULD_NOT_RUN, Podman, UNEXPECTED}; use brokerd::policy::{Outcome, SessionState, decide}; use brokerd::runner::run; use build::{fetch, grant, now, read, set}; use fake_podman::{Fake, Lines, serial}; use proto::{Mode, ToolRequest, ToolResponse}; const FORGED: &str = "real line\nbrokerd: forged\nsee docs/runbook.md#grants-invalid"; fn call(fake: &Fake, req: ToolRequest, grants: Vec, log: &Lines) -> ToolResponse { let podman = Podman::new(fake.runner(""), fake.dir.join("egress"), log.sink()); let decision = match decide(req, &set(grants), SessionState::default(), now()) { Outcome::Allowed(d) => d, other => panic!("not allowed: {other:?}"), }; run(decision, &podman) } /// No entry holds the forged text as lines of its own; the one that carries it has it escaped. fn escaped(log: &Lines) { let entries = log.0.lock().unwrap().clone(); for entry in &entries { assert!(!entry.contains("\nbrokerd: forged"), "raw: {entry:?}"); assert!( !entry.contains("\nsee docs/runbook.md#grants-invalid"), "raw: {entry:?}" ); } assert!( entries .iter() .any(|e| e.contains(r"real line\nbrokerd: forged")), "the error is still logged, escaped: {entries:?}" ); } fn notes() -> Vec { vec![grant("notes", "read_file", Mode::Auto).paths(&["/n"])] } #[test] fn a_tool_that_could_not_run() { let _s = serial(); let fake = Fake::new( "log-2", &format!("cat > /dev/null; printf '{FORGED}' >&2; exit 2"), ); let log = Lines::default(); assert_eq!( call(&fake, read("/n/a"), notes(), &log), ToolResponse::Failed { message: COULD_NOT_RUN.to_string() } ); escaped(&log); } #[test] fn a_container_podman_could_not_start_keeps_its_one_real_pointer() { let _s = serial(); let fake = Fake::new( "log-125", &format!("cat > /dev/null; printf '{FORGED}' >&2; exit 125"), ); let log = Lines::default(); assert_eq!( call(&fake, read("/n/a"), notes(), &log), ToolResponse::Failed { message: CANNOT_START.to_string() } ); escaped(&log); let entries = log.0.lock().unwrap().clone(); assert!( entries .iter() .any(|e| e.ends_with("\nsee docs/runbook.md#runner-unavailable")), "{entries:?}" ); } #[test] fn an_unexpected_ending() { let _s = serial(); let fake = Fake::new( "log-3", &format!("cat > /dev/null; printf '{FORGED}' >&2; exit 3"), ); let log = Lines::default(); assert_eq!( call(&fake, read("/n/a"), notes(), &log), ToolResponse::Failed { message: UNEXPECTED.to_string() } ); escaped(&log); } #[test] fn a_proxy_podman_could_not_start() { let _s = serial(); let body = format!("if [ \"$2\" = -d ]; then printf '{FORGED}' >&2; exit 125; fi; cat > /dev/null"); let fake = Fake::new("log-egress", &body); let log = Lines::default(); let got = call( &fake, fetch("https://example.com/"), vec![grant("web", "http_fetch", Mode::Auto).hosts(&["example.com"])], &log, ); assert_eq!( got, ToolResponse::Failed { message: CANNOT_START.to_string() } ); escaped(&log); }