mirror of
https://github.com/horizon-rust/horizon.git
synced 2026-11-07 11:06:11 -10:00
Every Nightly was signed for the constant "horizon release nightly", and the version a launcher installed it as came from the unsigned GitHub title, so anyone able to edit the release could serve an older signed Nightly as tonight's. - nightly-build.yml signs SHA256SUMS twice with the same key(s): SHA256SUMS.sig for the channel, as before, for installed launchers; SHA256SUMS.v2.sig for nightly-<date>-<commit>, the version the title names (sign_release.sh ALSO_FOR). Both are verified before publishing. - horizon-release-sign: nightly_title_version() parses the title strictly (no fallback to published_at); nightly_digest() takes that version and checks SHA256SUMS.v2.sig for exactly it; is_nightly_build(); SIGNATURE_V2. `verify --signature <file>` checks the v2 file. - Every installer that checks a Nightly moves in the same step: the launcher, horizon-server update and packaging/server/install.sh refuse a Nightly whose title doesn't parse and install it only with a v2 signature for that version. install.ps1 checks no signature (only GitHub's SHA-256), so it has nothing to move. - An older Nightly still installs on request as a rollback with a warning; the launcher's update never moves the selection back to it, and horizon-server prints a rollback notice for --version. - Nightlies from before this change have no v2 signature: the refusal now says so and names `horizon-server rollback`, and docs/security.md "Nightly signatures" describes the changeover (martipops's review of #9129). The launcher's new messages go through trf(), in every language table in English until translated. - tests/install_sh_signature.sh: a v2 Nightly installs as its version; a Nightly with only the channel signature, an older Nightly retitled as a newer one, and an unreadable title are refused (all three installed before this change). Split from #9129, as martipops's review suggested. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01SJ3stK8iXVDXqoi7midcqd