banger/internal/cli
Thales Maciel caa6a2b996
model: validate VM names as DNS labels at CLI + daemon
A VM name flows into five places that all have narrower grammars
than "arbitrary string":

  - the guest's /etc/hostname  (vm_disk.patchRootOverlay)
  - the guest's /etc/hosts      (same)
  - the <name>.vm DNS record    (vmdns.RecordName)
  - the kernel command line     (system.BuildBootArgs*)
  - VM-dir file-path fragments  (layout.VMsDir/<id>, etc.)

Nothing in the chain was validating the input. A name with
whitespace, newline, dot, slash, colon, or = would produce broken
hostnames, weird DNS labels, smuggled kernel cmdline tokens, or
(in the worst case) surprising traversal through the on-disk
layout. Not host shell injection — we already avoid shelling out
with the raw name — but a real correctness and supportability bug.

New: model.ValidateVMName. Rules:

  - 1..63 chars (DNS label max per RFC 1123; also a comfortable
    /etc/hostname cap)
  - lowercase ASCII letters, digits, '-' only
  - no leading or trailing '-'
  - no normalization — the name is the user-visible identifier
    (store key, `ssh <name>.vm`, `vm show`); silently rewriting
    "MyVM" → "myvm" would hand the user back something different
    than they typed

Called from two places:

  - internal/cli/commands_vm.go vmCreateParamsFromFlags — rejects
    bad `--name` values before any RPC. Empty name still passes
    through so the daemon can generate one.
  - internal/daemon/vm_create.go reserveVM — defense in depth for
    any non-CLI RPC caller (SDK, direct JSON over the socket).

Tests:

  - internal/model/vm_name_test.go — exhaustive character-class
    matrix (space, newline, tab, dot, slash, colon, equals, quote,
    control chars, unicode letters, uppercase, leading/trailing
    hyphen, over-length, max-length-exact, digits-only).
  - internal/cli TestVMCreateParamsFromFlagsRejectsInvalidName —
    CLI wire-through + empty-name passthrough.
  - internal/daemon TestReserveVMRejectsInvalidName — daemon
    defense-in-depth (including `box/../evil` path-traversal).
  - scripts/smoke.sh — end-to-end rejection + no-leaked-row
    assertion.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 14:06:40 -03:00
..
aliases_test.go remove vm session feature 2026-04-20 12:47:58 -03:00
banger.go ssh-config: make the ssh <name>.vm shortcut opt-in 2026-04-20 13:57:26 -03:00
bangerd.go Add Go daemon-driven VM control plane 2026-03-16 12:52:54 -03:00
cli_test.go model: validate VM names as DNS labels at CLI + daemon 2026-04-23 14:06:40 -03:00
commands_daemon.go cli + daemon: move test seams off package globals onto injected structs 2026-04-19 19:03:55 -03:00
commands_image.go cli + daemon: move test seams off package globals onto injected structs 2026-04-19 19:03:55 -03:00
commands_internal.go cli + daemon: move test seams off package globals onto injected structs 2026-04-19 19:03:55 -03:00
commands_kernel.go cli + daemon: move test seams off package globals onto injected structs 2026-04-19 19:03:55 -03:00
commands_ssh_config.go cleanup: drop pre-v0.1 migration scaffolding + legacy-behavior refs 2026-04-23 13:56:32 -03:00
commands_vm.go model: validate VM names as DNS labels at CLI + daemon 2026-04-23 14:06:40 -03:00
completion.go remove vm session feature 2026-04-20 12:47:58 -03:00
completion_test.go remove vm session feature 2026-04-20 12:47:58 -03:00
daemon_lifecycle.go cli + daemon: move test seams off package globals onto injected structs 2026-04-19 19:03:55 -03:00
deps.go seams: move the last four package globals onto instance fields 2026-04-22 12:07:14 -03:00
formatters_test.go remove vm session feature 2026-04-20 12:47:58 -03:00
make_bundle_test.go banger internal make-bundle: build image bundles from flat rootfs tars 2026-04-17 15:17:50 -03:00
printers.go remove vm session feature 2026-04-20 12:47:58 -03:00
prune_test.go cli + daemon: move test seams off package globals onto injected structs 2026-04-19 19:03:55 -03:00
ssh.go smoke: five more scenarios + fix exit-code propagation bug the new ones caught 2026-04-22 19:37:07 -03:00
vm_create.go cli + daemon: move test seams off package globals onto injected structs 2026-04-19 19:03:55 -03:00
vm_run.go cleanup: drop pre-v0.1 migration scaffolding + legacy-behavior refs 2026-04-23 13:56:32 -03:00
vm_spec_test.go vm defaults: host-aware sizing + spec line on spawn + doctor check 2026-04-19 13:06:51 -03:00
workspace_preview.go noteUntrackedSkipped: fix subdir underreport + be best-effort everywhere 2026-04-22 12:42:33 -03:00
workspace_preview_test.go noteUntrackedSkipped: fix subdir underreport + be best-effort everywhere 2026-04-22 12:42:33 -03:00