manifest.rs

crates/veilvoice-guard/src/manifest.rs

veilvoice-guard · 730 lines · read the source here · or on GitHub

The integrity manifest: what the files were, and what they are now.

Format

Deliberately a text format, one record per line:

VEILGUARD1
<sha256 hex>  <size>  <path>
...

Text rather than a packed binary layout because the point of the file is to be checkable. Someone who suspects tampering can read it with cat and compare a digest by hand with sha256sum, without this crate and without trusting it. A binary format would have been marginally smaller and would have made the honest response to "prove it" be "run my tool again".

Paths are stored with forward slashes so a manifest written on Windows still reads on Linux, and are rejected if they contain a newline -- otherwise a filename could forge a record.

In plain words

The written record of what VeilVoice's files were, so a later check can tell whether they still are.

It is plain text on purpose: you can read it, diff it and keep a copy somewhere else. A record you cannot inspect is one you have to take on trust, which rather defeats the point of having it.

WHAT THIS FILE CONTAINS

730 lines defining 18 functions (15 public), 4 types and 1 constant. Everything below is read out of the source, so it cannot disagree with the code.

The types it owns.

  • struct Entry line 43 · One recorded file.
  • enum Change line 52 · How a file differs from its record.
  • struct Report line 110 · The result of checking a manifest against the disk.
  • struct Manifest line 126 · A record of a set of files.

What happens when it runs. These are the ways in: public, and nothing else in this file calls them, so they are what an outside caller reaches first.

  • Change::path line 84 · The path this change concerns.
  • Change::describe line 94 · A single line for a terminal or a log.
  • Report::is_clean line 119 · Whether anything at all differs.
  • Manifest::of line 190 · Record every readable file in paths.
    reaches digest_of, normalise, unrecordable
  • Manifest::len line 215 · How many files are recorded.
  • Manifest::is_empty line 220 · Whether nothing is recorded.
  • Manifest::paths line 225 · The recorded paths, in order.
  • Manifest::check line 234 · Compare the record against what is on disk now.
    reaches digest_of, normalise
  • Manifest::save line 370 · Write the manifest to path in the clear.
    reaches to_text
  • Manifest::load line 381 · Read a manifest written by Manifest::save.
    reaches parse, unrecordable
  • Manifest::seal line 395 · Seal the manifest under a passphrase.
    reaches to_text
  • Manifest::open_sealed line 424 · Open a manifest sealed by Manifest::seal.
    reaches parse, unrecordable
  • files_in line 441 · Every file directly inside dir, for use as check's extra argument.

WHAT CALLS WHAT

Change::path line 84 Change::describe line 94 Report::is_clean line 119 normalise line 134 unrecordable line 157 digest_of line 173 Manifest::of line 190 Manifest::len line 215 Manifest::is_empty line 220 Manifest::paths line 225 Manifest::check line 234 Manifest::to_text line 275 Manifest::parse line 285 Manifest::save line 370 Manifest::load line 381 Manifest::seal line 395 Manifest::open_sealed line 424 files_in line 441 entry: a way in: public, and nothing in this file calls it api: public, and also used inside this file helper: private to this file dashed: a call that goes back up, or across a wrapped rank The functions this file defines, and the calls between them. An edge means the callee's name appears, called, inside the caller's body. This is a syntactic reading, not a type-resolved one.

The functions this file defines, and the calls between them. An edge means the callee's name appears, called, inside the caller's body. This is a syntactic reading, not a type-resolved one.

The same graph as Mermaid source
%%{init: {"theme":"base","themeVariables":{"background":"#1a1b26","primaryColor":"#1f2335","primaryTextColor":"#c0caf5","primaryBorderColor":"#7aa2f7","secondaryColor":"#16161e","tertiaryColor":"#16161e","lineColor":"#737aa2","textColor":"#c0caf5","mainBkg":"#1f2335","nodeBorder":"#7aa2f7","clusterBkg":"#16161e","clusterBorder":"#2f3549","fontFamily":"ui-monospace, SFMono-Regular, Consolas, monospace","fontSize":"14px"}}}%%
flowchart TD
    n_path(["Change::path<br/>line 84"])
    n_describe(["Change::describe<br/>line 94"])
    n_is_clean(["Report::is_clean<br/>line 119"])
    n_normalise["normalise<br/>line 134"]
    n_unrecordable["unrecordable<br/>line 157"]
    n_digest_of["digest_of<br/>line 173"]
    n_of(["Manifest::of<br/>line 190"])
    n_len(["Manifest::len<br/>line 215"])
    n_is_empty(["Manifest::is_empty<br/>line 220"])
    n_paths(["Manifest::paths<br/>line 225"])
    n_check(["Manifest::check<br/>line 234"])
    n_to_text["Manifest::to_text<br/>line 275"]
    n_parse["Manifest::parse<br/>line 285"]
    n_save(["Manifest::save<br/>line 370"])
    n_load(["Manifest::load<br/>line 381"])
    n_seal(["Manifest::seal<br/>line 395"])
    n_open_sealed(["Manifest::open_sealed<br/>line 424"])
    n_files_in(["files_in<br/>line 441"])
    n_check --> n_digest_of
    n_check --> n_normalise
    n_load --> n_parse
    n_of --> n_digest_of
    n_of --> n_normalise
    n_of --> n_unrecordable
    n_open_sealed --> n_parse
    n_parse --> n_unrecordable
    n_save --> n_to_text
    n_seal --> n_to_text
    click n_path href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-guard/src/manifest.rs#L84" "open the source"
    click n_describe href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-guard/src/manifest.rs#L94" "open the source"
    click n_is_clean href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-guard/src/manifest.rs#L119" "open the source"
    click n_normalise href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-guard/src/manifest.rs#L134" "open the source"
    click n_unrecordable href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-guard/src/manifest.rs#L157" "open the source"
    click n_digest_of href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-guard/src/manifest.rs#L173" "open the source"
    click n_of href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-guard/src/manifest.rs#L190" "open the source"
    click n_len href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-guard/src/manifest.rs#L215" "open the source"
    click n_is_empty href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-guard/src/manifest.rs#L220" "open the source"
    click n_paths href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-guard/src/manifest.rs#L225" "open the source"
    click n_check href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-guard/src/manifest.rs#L234" "open the source"
    click n_to_text href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-guard/src/manifest.rs#L275" "open the source"
    click n_parse href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-guard/src/manifest.rs#L285" "open the source"
    click n_save href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-guard/src/manifest.rs#L370" "open the source"
    click n_load href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-guard/src/manifest.rs#L381" "open the source"
    click n_seal href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-guard/src/manifest.rs#L395" "open the source"
    click n_open_sealed href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-guard/src/manifest.rs#L424" "open the source"
    click n_files_in href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-guard/src/manifest.rs#L441" "open the source"
    classDef entry fill:#1f2335,stroke:#7aa2f7,color:#c0caf5
    class n_path,n_describe,n_is_clean,n_of,n_len,n_is_empty,n_paths,n_check,n_save,n_load,n_seal,n_open_sealed,n_files_in entry
    classDef api fill:#1f2335,stroke:#7dcfff,color:#c0caf5
    class n_to_text,n_parse api
    classDef helper fill:#1f2335,stroke:#bb9af7,color:#c0caf5
    class n_normalise,n_unrecordable,n_digest_of helper

This site loads no third-party script, so it cannot run Mermaid; the diagram above is the same nodes and edges drawn by the generator instead. GitHub renders the source below directly.

ITEMS

ItemLineDocumentation
MAGIC pub(crate) const39Magic first line.
Entry pub struct43One recorded file.
Change pub enum52How a file differs from its record.
Change::path pub fn84The path this change concerns.
Change::describe pub fn94A single line for a terminal or a log.
Report pub struct110The result of checking a manifest against the disk.
Report::is_clean pub fn119Whether anything at all differs.
Manifest pub struct126A record of a set of files.
normalise fn134Normalise a path for storage: forward slashes, no leading ./.
unrecordable fn157Why this path cannot go in a manifest, if it cannot.
digest_of fn173
Manifest::of pub fn190Record every readable file in paths.
Manifest::len pub fn215How many files are recorded.
Manifest::is_empty pub fn220Whether nothing is recorded.
Manifest::paths pub fn225The recorded paths, in order.
Manifest::check pub fn234Compare the record against what is on disk now.
Manifest::to_text pub fn275Serialise to the text format described at the top of this module.
Manifest::parse pub fn285Parse the text format.
Manifest::save pub fn370Write the manifest to path in the clear.
Manifest::load pub fn381Read a manifest written by Manifest::save.
Manifest::seal pub fn395Seal the manifest under a passphrase.
Manifest::open_sealed pub fn424Open a manifest sealed by Manifest::seal.
files_in pub fn441Every file directly inside dir, for use as check's extra argument.