Documentation
¶
Overview ¶
Package spool persists scan results to disk as they are produced.
Results never accumulate in memory: a bodyfile for a million-inode image is well over a hundred megabytes on its own, and it is one of hundreds of outputs. Each output target gets an append-only file with a buffered writer, which is crash-tolerant by construction (a torn final line is the only failure mode), greppable while a long acquisition is still running, and streams back with no seeking.
The line format is UAC's own, not JSON, so the output tree is byte-comparable against the shell implementation and readable by the same downstream tools.
Divergence from UAC ¶
One difference is deliberate: control bytes in a path are escaped before a record is written. UAC passes filenames through find(1) and stat(1) verbatim, so a file whose name contains a newline splits its record in two and lets a suspect fabricate evidence by naming a file. See escapeControl.
The output is also written 0600 under 0700 directories rather than world-readable, because a collection contains whatever the image did -- /etc/shadow, private keys, credential stores.
Index ¶
Constants ¶
const ( OutputFilePerm = 0600 OutputDirPerm = 0700 )
OutputFilePerm and OutputDirPerm keep a collection readable only by the examiner who made it.
The output is not ordinary program output: a collection contains /etc/shadow, SSH private keys, browser credential stores and anything else the artifacts asked for. Written 0644 under a 0755 directory, as it was, every local user on a shared analysis workstation could read the contents of the image -- material the tool went to some length to read safely in the first place.
Variables ¶
This section is empty.
Functions ¶
func Lines ¶
Lines streams a spool file back without loading it. This is what a leaf collector's ScanResults hands the caller.
func SanitizeName ¶
SanitizeName mirrors UAC's output filename sanitiser: characters that cannot appear in a filename on every supported platform become underscores.
Types ¶
type Entry ¶
type Entry struct {
Collector string // rule id that produced it
Kind string // bodyfile | hashes | paths | copies | errors
Path string // absolute path of the spool file
Rel string // path relative to the output root
Lines int64
Bytes int64
}
Entry describes one spool file in the manifest.
type Store ¶
type Store struct {
Root string
// contains filtered or unexported fields
}
Store owns the output tree and hands out writers. Writers are memoised per relative path, so several rules sharing an output_file append to one file exactly as they do under UAC.
func NewStore ¶
NewStore prepares an output tree.
The directory must be absent or empty. Appending a second acquisition to an existing one produces line-oriented outputs containing both while copied files are selectively overwritten, and the manifest counts only what this run wrote -- a mixture that looks like a single coherent collection and is not.
type Writer ¶
type Writer struct {
// contains filtered or unexported fields
}
Writer is an append-only line sink.