// The probe a run step's isolation is proved with (novox/hq ADR 0448; issue 1309, S19): run inside the step, it says // on stdout every way it reached what a step must not, and "shut off" when it reached none. Its arguments: the files // it must not read (the forge key, a bus login), a TCP address and a unix socket of the machine it must not reach, a // name it must not resolve, and a cache file it writes, which must be unchanged after the step. package main import ( "fmt" "net" "os" "time" ) func main() { if len(os.Args) != 7 { fmt.Println("usage: probe ") os.Exit(2) } key, login, tcp, socket, name, cache := os.Args[1], os.Args[2], os.Args[3], os.Args[4], os.Args[5], os.Args[6] reached := 0 say := func(f string, a ...any) { reached++; fmt.Printf(f+"\n", a...) } for _, f := range []string{key, login} { if _, err := os.ReadFile(f); err == nil { say("read %s", f) } } if c, err := net.DialTimeout("tcp", tcp, 2*time.Second); err == nil { c.Close() say("reached %s", tcp) } if c, err := net.DialTimeout("unix", socket, 2*time.Second); err == nil { c.Close() say("reached %s", socket) } if addrs, err := net.LookupHost(name); err == nil { say("resolved %s to %v", name, addrs) } if home, err := os.UserHomeDir(); err == nil { if entries, err := os.ReadDir(home); err == nil && len(entries) > 0 { say("the home %s holds %d entries", home, len(entries)) } } if err := os.WriteFile(cache, []byte("written by the step\n"), 0o644); err != nil { say("could not write the cache under its throwaway layer: %v", err) } if reached == 0 { fmt.Println("shut off") } }