Skip to content

Fail unseal-key prompts on EOF - #819

Merged
sehkone merged 1 commit into
mainfrom
sehkone/issue-818
Aug 12, 2026
Merged

Fail unseal-key prompts on EOF#819
sehkone merged 1 commit into
mainfrom
sehkone/issue-818

Conversation

@sehkone

@sehkone sehkone commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Fixes the third of the tree's interactive readers. prompt_unseal_keys_interactive discarded the byte count read_line returns, so an exhausted stdin was indistinguishable from a blank line.

The reachable path is a plain operator mistake: answer the threshold, paste fewer shares than that, press Ctrl-D. Every remaining read returned Ok(0), the vector filled with empty strings, and save_unseal_keys truncated an existing unseal-keys.txt to blank lines, printed "saved" and exited zero. Nothing surfaced until read_unseal_keys_from_file filtered the blanks and bailed with Unseal key file is empty — by which point OpenBao is sealed and the shares are off the host.

Changes

  • Check the count from read_line and bail with error_prompt_eof() at both prompts. A blank line the operator typed still behaves as it did.
  • Read through an injected &mut dyn BufRead so both branches are testable without process stdin. prompt_unseal_keys_interactive keeps its name, parameters and pub(crate) visibility, so both call sites are untouched.
  • A threshold that does not parse now carries error_invalid_unseal_threshold instead of error_prompt_read_failed, which was attached to a parse failure.
  • Both prompt strings come from i18n. They were hardcoded in English while the declarations, accessors and Korean translations already existed, so BOOTROOT_LANG=ko rendered English here. The English strings are byte-identical, so default-locale output does not move.

Test plan

  • Seven unit tests: EOF at the threshold, EOF right after the threshold (the reported destruction path), EOF partway through the shares, a full answer set, a supplied threshold skipping the threshold prompt, a non-numeric threshold, and a blank threshold staying a parse failure rather than becoming an EOF error.
  • cargo test — all pass. The eight bootroot_rotate failures on my machine are the Docker daemon being absent (dial unix /var/run/docker.sock), unrelated to this change.
  • cargo clippy --all-targets -- -D warnings and cargo fmt -- --check --config group_imports=StdExternalCrate are clean.
  • Manual, both locales: BOOTROOT_LANG=ko bootroot openbao save-unseal-keys --secrets-dir <tempdir> renders the Korean prompts, and Ctrl-D exits nonzero without creating the file.

Preflight E2E was not run: this touches no Docker lifecycle, no E2E script and no code path they exercise — init prompts for unseal keys through its own reader, and the other caller of this one is guarded by is_terminal().

Closes #818

`read_line` reports EOF as `Ok(0)`, and the count was discarded, so an
exhausted stdin was indistinguishable from a blank line. Answering the
threshold and then pressing Ctrl-D left every remaining share as an
empty string, which `save_unseal_keys` wrote over an existing key file
before reporting success and exiting zero.

Check the count and fail instead, reading through an injected
`BufRead` so both branches are reachable from a test without touching
process stdin.

While here, attribute a threshold that does not parse to
`error_invalid_unseal_threshold` rather than to a read failure, and
take both prompt strings from i18n. They were hardcoded in English
even though the declarations, accessors and Korean translations all
existed already.

Closes #818
@sehkone
sehkone merged commit 6a24757 into main Aug 12, 2026
18 checks passed
@sehkone
sehkone deleted the sehkone/issue-818 branch August 12, 2026 22:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Fail openbao save-unseal-keys prompts on EOF instead of writing blank keys

1 participant