bastion 0.60.0
ci / personal-data (push) Successful in 4s
ci / test (push) Successful in 3m36s
ci / fuzz (push) Successful in 3m35s

This commit is contained in:
Privatae
2026-11-02 00:10:58 +00:00
parent 4a5c310482
commit 4f8285ef18
100 changed files with 11537 additions and 840 deletions
+77
View File
@@ -0,0 +1,77 @@
package main
// askparties.go — who asked to stop what, in the form the audit keeps: the
// asking account (the kernel's answer), the asking process and the agent it
// descends from, and the target, each with how it was started (origin.go:
// interactive, scheduler, service, ...). They are kept on the request itself
// (Details "asker" and "target"), so every later row about that request —
// approved, denied, carried out — names both, not only the row that filed it.
// askingAgentObs is the observed agent pid descends from, and its pid.
func askingAgentObs(pid int, observed map[int]agentObs) (agentObs, int, bool) {
parents := processTree()
p := pid
for i := 0; p > 1 && i < 64; i++ {
if a, ok := observed[p]; ok && a.Kind != kindApp {
return a, p, true
}
p = parents[p]
}
return agentObs{}, 0, false
}
// askParties describes the asker and the target of one stop ask. askerPID is
// the kernel's pid for the asking process, 0 where the platform does not say.
func askParties(account string, askerPID, targetPID int, observed map[int]agentObs) (asker, target map[string]any) {
asker = map[string]any{"account": account}
if askerPID > 1 {
asker["pid"] = askerPID
if a, p, ok := askingAgentObs(askerPID, observed); ok {
asker["agent"] = agentParty(a, p)
}
}
target = agentParty(observed[targetPID], targetPID)
return asker, target
}
func agentParty(a agentObs, pid int) map[string]any {
out := map[string]any{"pid": pid, "signature": a.Signature, "name": familyLabel(a.Signature)}
if a.Origin != "" {
out["origin"] = a.Origin
}
return out
}
// askPartiesOf is what a request carries about its asker and target, for an
// audit row; nil for a request no local agent asked (a Host's).
func askPartiesOf(d map[string]any) map[string]any {
if kind, _ := d["kind"].(string); kind != localStopKind {
return nil // "target" is a critical_action's own word, not a party
}
out := map[string]any{}
for _, k := range []string{"asker", "target"} {
if v, ok := d[k]; ok && v != nil {
out[k] = v
}
}
if by, _ := d["asked_by"].(string); by != "" {
out["who"] = by
}
if len(out) == 0 {
return nil
}
return out
}
// hostAskDetails drops from a Host's request the fields only this machine
// writes about a local agent's ask. A Host's details are its own words, so
// without this it could name an account on this computer as the asker in the
// owner's audit, and have the owner's deny count against that account.
func hostAskDetails(d map[string]any) {
delete(d, "asked_by_account")
delete(d, "asker")
if kind, _ := d["kind"].(string); kind == localStopKind {
delete(d, "asked_by")
delete(d, "target")
}
}