main.rs

crates/veilvoice-cli/src/main.rs

veilvoice-cli · 3461 lines · read the source here · or on GitHub

veilvoice, the command-line interface.

Everything VeilVoice does, available without a desktop: it runs over SSH, in a container, and on machines that have no GUI toolkit at all. The same engine backs both this and the graphical app.

What is here

Twenty subcommands, and they divide into five groups:

  • Audio -- anonymise a file, live scramble a microphone, list devices, conversation for a recording with several people in it.
  • Privacy of the files themselves -- clean metadata, encrypt, decrypt, keygen, shred.
  • Watching the machine -- watch the microphone and camera, guard VeilVoice's own files against tampering, sentry for canaries and how fast a folder is changing, capture for which screen recorders are running.
  • The app lock -- lock set|status|change|remove, and policy for settings somebody has fixed so the interface cannot turn them off.
  • Getting it onto the machine -- install, uninstall, companions, and gui to open the desktop application.

That last group is a front end over veilvoice_setup, which the desktop application's setup tab also calls. The careful part -- editing PATH -- has one implementation and one set of tests, rather than one per front end.

Two behaviours that surprise people, on purpose

anonymise writes <out>.veil, not a bare WAV. Recordings are encrypted at rest by default. --encrypt=false opts out and requires --yes, because an unsealed recording is the thing somebody later wishes they had not produced. The wiki explains where the WAV went.

The front-ends refuse rather than downgrade. Asked to encrypt with nothing to encrypt with, this exits with an error instead of writing plain audio and mentioning it. Quiet degradation to a weaker posture is the defect class this project has found in itself most often.

Passphrase prompts cannot be piped

rpassword needs a real console; piping a passphrase in blocks on CONIN$ rather than reading it. That is a property of terminal input, not a bug here, and it means anything that prompts cannot be smoke-tested from a non-interactive shell. The layer beneath each prompt is therefore tested instead -- see crate::atrest and crate::lock, where the logic lives precisely so it can be reached without a terminal.

A clap ordering rule worth knowing

An argument declared beside #[command(subcommand)] must precede the subcommand on the command line unless it is marked global = true. So veilvoice lock --path X status parses and veilvoice lock status --path X does not, except that --path is now global specifically so both do.

In plain words

This is VeilVoice without a window.

Everything the program does, typed instead of clicked: disguise a recording, scramble a microphone while you talk, seal a file, strip a photograph's hidden labels, handle a recording with several people in it.

It is the same code underneath, so it works the same way -- over a remote connection, on a machine with no desktop, or from a script that runs it a thousand times.

WHAT THIS FILE CONTAINS

3461 lines defining 29 functions (0 public), 13 types and 0 constants. Everything below is read out of the source, so it cannot disagree with the code.

The types it owns.

  • struct Cli line 118
  • enum Command line 124
  • enum FixCommand line 731 · The corrections veilvoice conversation fix can make.
  • enum ConversationCommand line 815
  • enum AppctlCommand line 973 · What veilvoice capture can do.
  • enum InputCommand line 1000
  • enum CaptureCommand line 1013
  • enum MandateCommand line 1053 · What veilvoice mandate can do.
  • enum PolicyCommand line 1089 · What veilvoice policy can do.
  • enum SentryCommand line 1142 · What veilvoice sentry can do.
  • enum CleanPolicy line 1203
  • struct Tuning line 2196 · The engine settings a user can reach from the command line.
  • struct AtRest line 2273 · What to do with the result once it exists.

WHAT CALLS WHAT

flavour_for line 1225 explain_verification line 1245 main line 1323 run line 1365 run_ffmpeg line 1933 list_volumes line 2008 list_companions line 2056 offer_line line 2089 install_companion line 2113 reseed_range_from line 2215 config line 2235 describe_reseed_range line 2254 describe_reseed line 2264 anonymise line 2283 live line 2426 list_devices line 2658 read_named line 2709 video_plan line 2724 write_named line 2741 clean line 2746 encrypt line 2764 decrypt line 2795 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. 22 of 28 functions are drawn; the diagram is bounded at 22 so it stays readable.

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. 22 of 28 functions are drawn; the diagram is bounded at 22 so it stays readable.

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_flavour_for["flavour_for<br/>line 1225"]
    n_explain_verification["explain_verification<br/>line 1245"]
    n_main["main<br/>line 1323"]
    n_run["run<br/>line 1365"]
    n_run_ffmpeg["run_ffmpeg<br/>line 1933"]
    n_list_volumes["list_volumes<br/>line 2008"]
    n_list_companions["list_companions<br/>line 2056"]
    n_offer_line["offer_line<br/>line 2089"]
    n_install_companion["install_companion<br/>line 2113"]
    n_reseed_range_from["reseed_range_from<br/>line 2215"]
    n_config["config<br/>line 2235"]
    n_describe_reseed_range["describe_reseed_range<br/>line 2254"]
    n_describe_reseed["describe_reseed<br/>line 2264"]
    n_anonymise["anonymise<br/>line 2283"]
    n_live["live<br/>line 2426"]
    n_list_devices["list_devices<br/>line 2658"]
    n_read_named["read_named<br/>line 2709"]
    n_video_plan["video_plan<br/>line 2724"]
    n_write_named["write_named<br/>line 2741"]
    n_clean["clean<br/>line 2746"]
    n_encrypt["encrypt<br/>line 2764"]
    n_decrypt["decrypt<br/>line 2795"]
    n_anonymise --> n_config
    n_anonymise --> n_describe_reseed_range
    n_clean --> n_read_named
    n_decrypt --> n_read_named
    n_describe_reseed_range --> n_describe_reseed
    n_encrypt --> n_read_named
    n_encrypt --> n_write_named
    n_install_companion --> n_offer_line
    n_list_companions --> n_offer_line
    n_live --> n_config
    n_live --> n_describe_reseed_range
    n_main --> n_run
    n_run --> n_anonymise
    n_run --> n_clean
    n_run --> n_config
    n_run --> n_decrypt
    n_run --> n_encrypt
    n_run --> n_explain_verification
    n_run --> n_flavour_for
    n_run --> n_install_companion
    n_run --> n_list_companions
    n_run --> n_list_devices
    n_run --> n_list_volumes
    n_run --> n_live
    n_run --> n_reseed_range_from
    n_run --> n_run_ffmpeg
    n_run --> n_video_plan
    click n_flavour_for href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-cli/src/main.rs#L1225" "open the source"
    click n_explain_verification href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-cli/src/main.rs#L1245" "open the source"
    click n_main href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-cli/src/main.rs#L1323" "open the source"
    click n_run href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-cli/src/main.rs#L1365" "open the source"
    click n_run_ffmpeg href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-cli/src/main.rs#L1933" "open the source"
    click n_list_volumes href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-cli/src/main.rs#L2008" "open the source"
    click n_list_companions href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-cli/src/main.rs#L2056" "open the source"
    click n_offer_line href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-cli/src/main.rs#L2089" "open the source"
    click n_install_companion href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-cli/src/main.rs#L2113" "open the source"
    click n_reseed_range_from href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-cli/src/main.rs#L2215" "open the source"
    click n_config href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-cli/src/main.rs#L2235" "open the source"
    click n_describe_reseed_range href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-cli/src/main.rs#L2254" "open the source"
    click n_describe_reseed href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-cli/src/main.rs#L2264" "open the source"
    click n_anonymise href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-cli/src/main.rs#L2283" "open the source"
    click n_live href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-cli/src/main.rs#L2426" "open the source"
    click n_list_devices href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-cli/src/main.rs#L2658" "open the source"
    click n_read_named href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-cli/src/main.rs#L2709" "open the source"
    click n_video_plan href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-cli/src/main.rs#L2724" "open the source"
    click n_write_named href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-cli/src/main.rs#L2741" "open the source"
    click n_clean href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-cli/src/main.rs#L2746" "open the source"
    click n_encrypt href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-cli/src/main.rs#L2764" "open the source"
    click n_decrypt href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-cli/src/main.rs#L2795" "open the source"
    classDef helper fill:#1f2335,stroke:#bb9af7,color:#c0caf5
    class n_flavour_for,n_explain_verification,n_main,n_run,n_run_ffmpeg,n_list_volumes,n_list_companions,n_offer_line,n_install_companion,n_reseed_range_from,n_config,n_describe_reseed_range,n_describe_reseed,n_anonymise,n_live,n_list_devices,n_read_named,n_video_plan,n_write_named,n_clean,n_encrypt,n_decrypt 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
Cli struct118
Command enum124
conversation::Fix::from fn712
FixCommand enum731The corrections veilvoice conversation fix can make.
ConversationCommand enum815
AppctlCommand enum973What veilvoice capture can do.
InputCommand enum1000
CaptureCommand enum1013
MandateCommand enum1053What veilvoice mandate can do.
PolicyCommand enum1089What veilvoice policy can do.
SentryCommand enum1142What veilvoice sentry can do.
CleanPolicy enum1203
Policy::from fn1211
flavour_for fn1225The verification script's spelling for a system, in one place.
explain_verification fn1245What checking a release actually involves, and who does which part.
main fn1323Parse the command line and turn a failure into an exit code and a message.
run fn1365Carry out one subcommand.
run_ffmpeg fn1933Roadmap items 87 and 88.
list_volumes fn2008Report the encrypted volumes this machine is offering.
list_companions fn2056Report every companion that means anything on this platform.
offer_line fn2089One line describing what VeilVoice can do about a missing companion.
install_companion fn2113Act on one named companion.
Tuning struct2196The engine settings a user can reach from the command line.
reseed_range_from fn2215Turn --reseed-range into a range, or into the reason it was not one.
config fn2235The de-identification settings a Tuning describes, with every figure clamped.
describe_reseed_range fn2254How a randomised roll range reads in the output.
describe_reseed fn2264How the seed-rolling setting reads in the output.
AtRest struct2273What to do with the result once it exists.
anonymise fn2283veilvoice anonymise: veil a recording and write it somewhere else.
live fn2426veilvoice live: veil the microphone as it is heard, with an optional preview.
list_devices fn2658veilvoice devices: every input and output this machine reports.
read_named pub(crate) fn2709Read a file, naming it if that fails.
video_plan pub(crate) fn2724Read a --size and an --fps into a render plan, saying what was decided.
write_named pub(crate) fn2741Write a file, naming it if that fails.
clean fn2746veilvoice clean: strip the metadata a file carries, in place.
encrypt fn2764veilvoice encrypt: seal a file, to a passphrase or to a public key.
decrypt fn2795veilvoice decrypt: open a sealed file, given the passphrase or the secret key.
load_secret_key fn2827Load a private key file, which is itself a password-locked container.
keygen fn2837veilvoice keygen: write a new key pair, refusing to overwrite either file.
watch fn2913Report, and keep reporting, what is using the microphone and camera.
shred fn3003Destroy a file's contents, then delete it.
info fn3072veilvoice info: the versions, and what this build was compiled to do.