| 1 | #!/usr/bin/env bash |
| 2 | # Single owner of the temporary unsigned manual-download Desktop exception. |
| 3 | # |
| 4 | # The exception removes only Windows Authenticode/SignPath. minisign, SHA-256, |
| 5 | # artifact identity, native builds, and startup verification always stay on, and |
| 6 | # no Desktop update entry point may advance while it is active. |
| 7 | # |
| 8 | # A row carries a candidate SHA only when its tag was already immutable at |
| 9 | # approval time. Those rows are historical recoveries and must run with |
| 10 | # allow_recovery=true. A row approved before its candidate exists carries no |
| 11 | # SHA, so it must keep the normal candidate and push-CI validation instead of |
| 12 | # trading that validation away for the signing exception. |
| 13 | set -euo pipefail |
| 14 | |
| 15 | # Approved tag -> pinned candidate SHA ("" when the candidate is validated by |
| 16 | # the normal stable path). Adding a row is the authorization boundary; every |
| 17 | # caller reads it from here so an exception cannot drift between surfaces. |
| 18 | manual_desktop_exception_sha() { |
| 19 | case "$1" in |
| 20 | desktop-v1.38.8) printf '%s' 7278072720a2dc7a31cce0eec18c1eacc149c0e0 ;; |
| 21 | desktop-v1.38.9) printf '%s' dc915ab97bfdeb5d0e414916c0f58708dca80051 ;; |
| 22 | *) return 1 ;; |
| 23 | esac |
| 24 | } |
| 25 | |
| 26 | # validate DESKTOP_TAG [CANDIDATE_SHA] [ALLOW_RECOVERY] |
| 27 | # Empty optional arguments are not checked, so a caller that cannot observe a |
| 28 | # value never weakens the rule for a caller that can. |
| 29 | manual_desktop_exception_validate() { |
| 30 | local tag="${1:-}" sha="${2:-}" allow_recovery="${3:-}" pinned |
| 31 | |
| 32 | if ! pinned="$(manual_desktop_exception_sha "$tag")"; then |
| 33 | echo "manual Desktop exception is not approved for tag: ${tag:-<empty>}" >&2 |
| 34 | return 1 |
| 35 | fi |
| 36 | |
| 37 | if [ -n "$pinned" ]; then |
| 38 | if [ -n "$sha" ] && [ "$sha" != "$pinned" ]; then |
| 39 | echo "manual Desktop exception for $tag is pinned to candidate $pinned, got $sha" >&2 |
| 40 | return 1 |
| 41 | fi |
| 42 | if [ -n "$allow_recovery" ] && [ "$allow_recovery" != "true" ]; then |
| 43 | echo "manual Desktop exception for $tag is an immutable recovery and requires allow_recovery=true" >&2 |
| 44 | return 1 |
| 45 | fi |
| 46 | return 0 |
| 47 | fi |
| 48 | |
| 49 | if [ "$allow_recovery" = "true" ]; then |
| 50 | echo "manual Desktop exception for $tag must keep normal candidate validation (allow_recovery=false)" >&2 |
| 51 | return 1 |
| 52 | fi |
| 53 | return 0 |
| 54 | } |
| 55 | |
| 56 | if [ "${BASH_SOURCE[0]}" = "$0" ]; then |
| 57 | case "${1:-}" in |
| 58 | validate) |
| 59 | shift |
| 60 | manual_desktop_exception_validate "$@" |
| 61 | ;; |
| 62 | *) |
| 63 | echo "usage: $0 validate DESKTOP_TAG [CANDIDATE_SHA] [ALLOW_RECOVERY]" >&2 |
| 64 | exit 2 |
| 65 | ;; |
| 66 | esac |
| 67 | fi |
| 68 |