fix(selfupdate): verify the archive before replacing the binary
`mdrs selfupdate` replaced the running binary with whatever the release endpoint returned, checking only that the transport succeeded. Nothing proved the archive was the one the release publishes. - Compare the downloaded archive against the release's `.sha256` asset and abort the update on a mismatch. - Report a release that publishes no checksum as unverified, rather than letting its absence pass for a verified download. - Exclude `.sha256` assets when matching the archive for the build target: those assets carry the target name too. - Write and upload a checksum beside every archive, from the Gitea release workflow and the three local build scripts.
This commit is contained in:
@@ -58,7 +58,10 @@ for TARGET in "${TARGETS[@]}"; do
|
||||
|
||||
ARCHIVE="mdrs-${VERSION}-${TARGET}.tar.gz"
|
||||
tar -czf "${ARCHIVE}" -C "target/${TARGET}/release" mdrs
|
||||
ARCHIVES+=("${ARCHIVE}")
|
||||
# Uploaded alongside the archive so `mdrs selfupdate` can check what it fetched.
|
||||
sha256sum "${ARCHIVE}" > "${ARCHIVE}.sha256" 2>/dev/null \
|
||||
|| shasum -a 256 "${ARCHIVE}" > "${ARCHIVE}.sha256"
|
||||
ARCHIVES+=("${ARCHIVE}" "${ARCHIVE}.sha256")
|
||||
echo " Created: ${ARCHIVE}"
|
||||
done
|
||||
|
||||
|
||||
@@ -46,7 +46,10 @@ for TARGET in "${TARGETS[@]}"; do
|
||||
|
||||
ARCHIVE="mdrs-${VERSION}-${TARGET}.tar.gz"
|
||||
tar -czf "${ARCHIVE}" -C "target/${TARGET}/release" mdrs
|
||||
ARCHIVES+=("${ARCHIVE}")
|
||||
# Uploaded alongside the archive so `mdrs selfupdate` can check what it fetched.
|
||||
sha256sum "${ARCHIVE}" > "${ARCHIVE}.sha256" 2>/dev/null \
|
||||
|| shasum -a 256 "${ARCHIVE}" > "${ARCHIVE}.sha256"
|
||||
ARCHIVES+=("${ARCHIVE}" "${ARCHIVE}.sha256")
|
||||
echo " Created: ${ARCHIVE}"
|
||||
done
|
||||
|
||||
|
||||
@@ -55,6 +55,10 @@ cargo build --release --target $Target
|
||||
|
||||
$Archive = "mdrs-$Version-$Target.zip"
|
||||
Compress-Archive -Force -Path "target\$Target\release\mdrs.exe" -DestinationPath $Archive
|
||||
# Written alongside the archive so `mdrs selfupdate` can check what it fetched.
|
||||
$Checksum = "$Archive.sha256"
|
||||
$Hash = (Get-FileHash -Algorithm SHA256 -Path $Archive).Hash.ToLower()
|
||||
"$Hash $Archive" | Set-Content -NoNewline -Encoding ascii $Checksum
|
||||
Write-Host " Created: $Archive"
|
||||
|
||||
# Upload to Gitea if token is provided
|
||||
@@ -87,14 +91,16 @@ $Release = Invoke-RestMethod -Method Get -Uri "$ServerUrl/api/v1/repos/$Reposito
|
||||
-Headers @{ Authorization = "Bearer $GiteaToken" }
|
||||
$ReleaseId = $Release.id
|
||||
|
||||
Write-Host "==> Uploading $Archive (release id: $ReleaseId) ..."
|
||||
$ArchivePath = Join-Path $RepoRoot $Archive
|
||||
& curl.exe -sf -X POST `
|
||||
-H "Authorization: Bearer $GiteaToken" `
|
||||
-F "attachment=@$ArchivePath" `
|
||||
"$ServerUrl/api/v1/repos/$Repository/releases/$ReleaseId/assets" | Out-Null
|
||||
if ($LASTEXITCODE -ne 0) { Write-Error "Upload failed (exit code $LASTEXITCODE)"; exit 1 }
|
||||
Write-Host " Done."
|
||||
foreach ($Name in @($Archive, $Checksum)) {
|
||||
Write-Host "==> Uploading $Name (release id: $ReleaseId) ..."
|
||||
$AssetPath = Join-Path $RepoRoot $Name
|
||||
& curl.exe -sf -X POST `
|
||||
-H "Authorization: Bearer $GiteaToken" `
|
||||
-F "attachment=@$AssetPath" `
|
||||
"$ServerUrl/api/v1/repos/$Repository/releases/$ReleaseId/assets" | Out-Null
|
||||
if ($LASTEXITCODE -ne 0) { Write-Error "Upload failed (exit code $LASTEXITCODE)"; exit 1 }
|
||||
Write-Host " Done."
|
||||
}
|
||||
|
||||
Write-Host ""
|
||||
Write-Host "==> Upload complete: $ServerUrl/$Repository/releases/tag/$Tag"
|
||||
|
||||
Reference in New Issue
Block a user