fdroid-publish: find_tool must test its result (ls|tail exits 0 on no match)
An empty SDK build-tools glob was reported as found, so the signer check ran nothing and refused a correctly signed APK with an empty signer. An unreadable signer now warns and defers to the host's pinned-cert check; only a real mismatch fails. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
624415406f
commit
3d3f8360ae
1 file changed
+15
-6
@@ -54,17 +54,26 @@ find_tool() { # newest build-tools copy of $1 under the Android SDK, or PATH
|
|||||||
command -v "$1" 2>/dev/null && return 0
|
command -v "$1" 2>/dev/null && return 0
|
||||||
for sdk in "${ANDROID_HOME:-}" "${ANDROID_SDK_ROOT:-}" /opt/android-sdk /opt/android/sdk /usr/lib/android-sdk; do
|
for sdk in "${ANDROID_HOME:-}" "${ANDROID_SDK_ROOT:-}" /opt/android-sdk /opt/android/sdk /usr/lib/android-sdk; do
|
||||||
[ -n "$sdk" ] && [ -d "$sdk/build-tools" ] || continue
|
[ -n "$sdk" ] && [ -d "$sdk/build-tools" ] || continue
|
||||||
ls -d "$sdk"/build-tools/*/"$1" 2>/dev/null | sort -V | tail -n1 && return 0
|
# Test the RESULT, not the pipeline: `ls … | tail` exits 0 even when ls found
|
||||||
|
# nothing, which once reported an empty path as found (empty signer → refusal).
|
||||||
|
p=$(ls -d "$sdk"/build-tools/*/"$1" 2>/dev/null | sort -V | tail -n1)
|
||||||
|
[ -n "$p" ] && [ -x "$p" ] && { printf '%s
|
||||||
|
' "$p"; return 0; }
|
||||||
done
|
done
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
# Signer check before anything leaves the runner, so a mis-signed build fails
|
# Signer check before anything leaves the runner, so a mis-signed build fails
|
||||||
# here with a clear message instead of as CERT_MISMATCH on the host.
|
# here with a clear message instead of as CERT_MISMATCH on the host.
|
||||||
if apksigner=$(find_tool apksigner); then
|
if apksigner=$(find_tool apksigner) && [ -n "$apksigner" ]; then
|
||||||
got=$("$apksigner" verify --print-certs "$apk" 2>/dev/null | sed -n 's/^Signer #1 certificate SHA-256 digest: //p' | head -n1 | tr 'A-F' 'a-f')
|
got=$("$apksigner" verify --print-certs "$apk" 2>/dev/null | sed -n 's/^Signer #1 certificate SHA-256 digest: //p' | head -n1 | tr 'A-F' 'a-f' || true)
|
||||||
[ "$got" = "$cert" ] || fail "APK signer $got is not the pinned $app cert $cert — refusing to publish"
|
if [ -z "$got" ]; then
|
||||||
say "signer cert: OK ($cert)"
|
say "::warning::apksigner at $apksigner printed no signer; the repo host verifies the cert"
|
||||||
|
elif [ "$got" != "$cert" ]; then
|
||||||
|
fail "APK signer $got is not the pinned $app cert $cert — refusing to publish"
|
||||||
|
else
|
||||||
|
say "signer cert: OK ($cert)"
|
||||||
|
fi
|
||||||
else
|
else
|
||||||
say "signer cert: apksigner not found here; the repo host verifies it"
|
say "signer cert: apksigner not found here; the repo host verifies it"
|
||||||
fi
|
fi
|
||||||
@@ -72,7 +81,7 @@ fi
|
|||||||
if [ -z "$version_code" ]; then
|
if [ -z "$version_code" ]; then
|
||||||
# Needed for the no-downgrade guard below. A bare runner image (the promote
|
# Needed for the no-downgrade guard below. A bare runner image (the promote
|
||||||
# workflow's) has no Android SDK, so fetch Debian's aapt rather than guess.
|
# workflow's) has no Android SDK, so fetch Debian's aapt rather than guess.
|
||||||
if ! aapt=$(find_tool aapt2 || find_tool aapt); then
|
if ! aapt=$(find_tool aapt2 || find_tool aapt) || [ -z "$aapt" ]; then
|
||||||
SUDO=; [ "$(id -u)" -eq 0 ] || SUDO=sudo
|
SUDO=; [ "$(id -u)" -eq 0 ] || SUDO=sudo
|
||||||
{ $SUDO apt-get update -qq && $SUDO apt-get install -y -qq aapt; } >/dev/null 2>&1 || true
|
{ $SUDO apt-get update -qq && $SUDO apt-get install -y -qq aapt; } >/dev/null 2>&1 || true
|
||||||
aapt=$(command -v aapt || true)
|
aapt=$(command -v aapt || true)
|
||||||
|
|||||||
Reference in new issue
Block a user