Install fingerprintd from the registry, so the image unlocks with a finger
Some checks failed
image / image (push) Failing after 57m23s
Some checks failed
image / image (push) Failing after 57m23s
The daemon's own package CI publishes it to the registry the same way imsd's does, so the image takes it from there: the exact apk a user later gets via apk upgrade, sha256-pinned, re-signed for the chroot. Section 3b now fetches both sets, and every fetched file must have a pin -- the check used to be `grep . | sha256sum -c`, which an empty pin list would have sailed through with nothing checked. Three apks: the daemon, its systemd units, and the session agent, which does nothing until a user writes ~/.config/fingerprintd/fingers.conf. The daemon needs the kernel aport's CONFIG_QCOMTEE=m (pkgrel 101) and fp6-vendor-blobs 1-r2's mbn directive to reassemble the trustlet, both built in this run; 0.2.3 says >=1-r2 so a mismatched pair is refused rather than installed. The CI publish step skips fingerprintd-* like imsd-*: registry-sourced, not ours to republish. README: fingerprint in the list, and the two things a user will otherwise report as a dead sensor -- the lock screen listens for 60 seconds after it appears, and a held press is what the matcher was measured on -- plus the untested question of stock Android's own fingerprints after using this. Verified on the dev phone (fp6 repo journal/fingerprint/, 2026-09-05): the registry 0.2.2 package enrols through Plasma's Users page and unlocks the lock screen; 0.2.3 differs by the dependency and a post-upgrade restart. The image build itself, with the fprintd purge inside the chroot, runs first in CI.
This commit is contained in:
parent
155b427478
commit
2a4427919e
3 changed files with 67 additions and 20 deletions
|
|
@ -50,8 +50,8 @@ jobs:
|
||||||
# the FP6 patches to the next upstream version bump. Requires the
|
# the FP6 patches to the next upstream version bump. Requires the
|
||||||
# PACKAGE_TOKEN repo secret (catbot account, package:write scope);
|
# PACKAGE_TOKEN repo secret (catbot account, package:write scope);
|
||||||
# skips quietly until it exists. 409 = same version already published.
|
# skips quietly until it exists. 409 = same version already published.
|
||||||
# imsd is skipped: build.sh 3b took it FROM the registry (re-signed
|
# imsd and fingerprintd are skipped: build.sh 3b took them FROM the
|
||||||
# for the chroot), so it is not ours to publish.
|
# registry (re-signed for the chroot), so they are not ours to publish.
|
||||||
- name: Publish packages to the apk registry
|
- name: Publish packages to the apk registry
|
||||||
env:
|
env:
|
||||||
PACKAGE_TOKEN: ${{ secrets.PACKAGE_TOKEN }}
|
PACKAGE_TOKEN: ${{ secrets.PACKAGE_TOKEN }}
|
||||||
|
|
@ -65,7 +65,7 @@ jobs:
|
||||||
for f in /home/build/.local/var/pmbootstrap/packages/*/aarch64/*.apk; do
|
for f in /home/build/.local/var/pmbootstrap/packages/*/aarch64/*.apk; do
|
||||||
[ -e "$f" ] || continue
|
[ -e "$f" ] || continue
|
||||||
case "$(basename "$f")" in
|
case "$(basename "$f")" in
|
||||||
imsd-*) echo "registry-sourced, not republished: $(basename "$f")"; continue ;;
|
imsd-*|fingerprintd-*) echo "registry-sourced, not republished: $(basename "$f")"; continue ;;
|
||||||
esac
|
esac
|
||||||
found=1
|
found=1
|
||||||
code=$(curl -s -o /dev/null -w '%{http_code}' \
|
code=$(curl -s -o /dev/null -w '%{http_code}' \
|
||||||
|
|
|
||||||
26
README.md
26
README.md
|
|
@ -14,7 +14,9 @@ Maintained by [Jorijn van der Graaf](https://catcrafts.net/about)
|
||||||
|
|
||||||
Everything on the `combined-stable` branch: display, touch, wifi, cellular
|
Everything on the `combined-stable` branch: display, touch, wifi, cellular
|
||||||
data, NFC (reader), speaker audio, microphone, IMU, magnetometer, barometer,
|
data, NFC (reader), speaker audio, microphone, IMU, magnetometer, barometer,
|
||||||
ambient light/proximity plus VoLTE calls (both directions) through imsd.
|
ambient light/proximity, fingerprint unlock through
|
||||||
|
[fingerprintd](https://forgejo.catcrafts.net/Catcrafts/fingerprintd), plus
|
||||||
|
VoLTE calls (both directions) through imsd.
|
||||||
|
|
||||||
## Flashing
|
## Flashing
|
||||||
|
|
||||||
|
|
@ -50,3 +52,25 @@ Find it in a stock-firmware capture or your carrier's IMS documentation, then
|
||||||
file to exist). See the
|
file to exist). See the
|
||||||
[imsd README](https://forgejo.catcrafts.net/Catcrafts/imsd) for the full
|
[imsd README](https://forgejo.catcrafts.net/Catcrafts/imsd) for the full
|
||||||
variable reference and carrier assumptions.
|
variable reference and carrier assumptions.
|
||||||
|
|
||||||
|
## Fingerprint
|
||||||
|
|
||||||
|
Enrol under **Settings → Users** (Plasma's own fingerprint page; the `fprintd`
|
||||||
|
command-line tools are not installed, fingerprintd replaces that package).
|
||||||
|
**Hold** the finger on the sensor for each of the ~20 presses rather than
|
||||||
|
tapping it; a held press is what the matcher was measured on.
|
||||||
|
|
||||||
|
Two things to know:
|
||||||
|
|
||||||
|
- The lock screen listens for a finger for **60 seconds after it appears**.
|
||||||
|
A press after that reaches nothing and looks like a dead sensor. Lock and
|
||||||
|
unlock again to re-arm it.
|
||||||
|
- The matcher is the phone's own proprietary trustlet, reassembled from the
|
||||||
|
stock modem partition on first boot and never shipped by us. Templates are
|
||||||
|
stored on the Android `persist` partition, sealed to the same hardware
|
||||||
|
anti-rollback counter stock Android uses. Whether fingerprints enrolled under
|
||||||
|
stock Android survive a return to it after using this has **not** been
|
||||||
|
tested.
|
||||||
|
|
||||||
|
A finger can also run something in your session on a match
|
||||||
|
(`~/.config/fingerprintd/fingers.conf`, see the fingerprintd README).
|
||||||
|
|
|
||||||
53
build.sh
53
build.sh
|
|
@ -1,6 +1,7 @@
|
||||||
#!/bin/sh -eu
|
#!/bin/sh -eu
|
||||||
# fp6-img pipeline: build a flashable postmarketOS image for the Fairphone 6
|
# fp6-img pipeline: build a flashable postmarketOS image for the Fairphone 6
|
||||||
# with the Catcrafts kernel (milos-linux combined-stable) and imsd (VoLTE)
|
# with the Catcrafts kernel (milos-linux combined-stable), imsd (VoLTE) and
|
||||||
|
# fingerprintd (fingerprint unlock)
|
||||||
# installed from the Catcrafts apk registry.
|
# installed from the Catcrafts apk registry.
|
||||||
#
|
#
|
||||||
# Runs in CI inside an Alpine container on the privileged "pmos" runner
|
# Runs in CI inside an Alpine container on the privileged "pmos" runner
|
||||||
|
|
@ -30,6 +31,19 @@ IMSD_SHA256="
|
||||||
f1c317d7ff9448c05df068d683d31da08e4bfc074704d96cf52cb8acbdee6304 imsd-0.3.1-r0.apk
|
f1c317d7ff9448c05df068d683d31da08e4bfc074704d96cf52cb8acbdee6304 imsd-0.3.1-r0.apk
|
||||||
a78ef31fc2943ac02e120c46df26353d515ac9840d959cf5193b2afe1c665fa6 imsd-systemd-0.3.1-r0.apk
|
a78ef31fc2943ac02e120c46df26353d515ac9840d959cf5193b2afe1c665fa6 imsd-systemd-0.3.1-r0.apk
|
||||||
"
|
"
|
||||||
|
# fingerprintd (fingerprint unlock) comes from the same registry the same way:
|
||||||
|
# its repo's package CI is the only producer, and the same pinning rule holds.
|
||||||
|
# Three apks: the daemon, its systemd units, and the session agent (inert
|
||||||
|
# until a user writes ~/.config/fingerprintd/fingers.conf). Needs the kernel
|
||||||
|
# aport's CONFIG_QCOMTEE=m (pkgrel 101) and fp6-vendor-blobs >= 1-r2, both
|
||||||
|
# built in this run. 0.2.3: 0.2.2 (enrol, unlock, agent, actions) + the
|
||||||
|
# versioned blobs dependency + a post-upgrade daemon restart.
|
||||||
|
FPD_VERSION=0.2.3-r0
|
||||||
|
FPD_SHA256="
|
||||||
|
3e28f0c1a9a844592ab6878b2dfc0d8f91674549e44bdc1652e7d7d029de1765 fingerprintd-0.2.3-r0.apk
|
||||||
|
0cc46eba5c6c77d5bb54cd9f0e2902f7644720f9c98153062ffa33e19ca36889 fingerprintd-systemd-0.2.3-r0.apk
|
||||||
|
6dfdbc6f971ba4b8f811f828e5868869c7d71fea6c7045e2bffd51bf2736c040 fingerprintd-agent-0.2.3-r0.apk
|
||||||
|
"
|
||||||
PMAPORTS_REPO=https://gitlab.postmarketos.org/postmarketOS/pmaports.git
|
PMAPORTS_REPO=https://gitlab.postmarketos.org/postmarketOS/pmaports.git
|
||||||
|
|
||||||
cd "$(dirname "$0")"
|
cd "$(dirname "$0")"
|
||||||
|
|
@ -215,7 +229,7 @@ aports = $WORK/pmaports
|
||||||
device = fairphone-fp6
|
device = fairphone-fp6
|
||||||
ui = plasma-mobile
|
ui = plasma-mobile
|
||||||
systemd = always
|
systemd = always
|
||||||
extra_packages = soc-fairphone-fp6-audio,callaudioshim,imsd,fp6-device-tweaks,fp6-charging-mode,catcrafts-fp6-repo,postmarketos-base-ui-audio-backend-pipewire,pipewire-pulse,pipewire-echo-cancel
|
extra_packages = soc-fairphone-fp6-audio,callaudioshim,imsd,fingerprintd,fingerprintd-systemd,fingerprintd-agent,fp6-device-tweaks,fp6-charging-mode,catcrafts-fp6-repo,postmarketos-base-ui-audio-backend-pipewire,pipewire-pulse,pipewire-echo-cancel
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
# All four source tarballs are generated locally above, so every checksum
|
# All four source tarballs are generated locally above, so every checksum
|
||||||
|
|
@ -244,9 +258,9 @@ retry "build modemmanager" pmbootstrap $NOCROSS build --arch aarch64 modemmanage
|
||||||
# patched -r2 exists for the publish step even if the install set resolves
|
# patched -r2 exists for the publish step even if the install set resolves
|
||||||
# it before the overlay is considered.
|
# it before the overlay is considered.
|
||||||
retry "build libcamera" pmbootstrap $NOCROSS build --arch aarch64 libcamera
|
retry "build libcamera" pmbootstrap $NOCROSS build --arch aarch64 libcamera
|
||||||
# --- 3b. imsd: the published apk, not a local build --------------------------
|
# --- 3b. imsd + fingerprintd: the published apks, not local builds -----------
|
||||||
# The imsd repo's package CI is the only producer of the imsd apk; the image
|
# Each repo's package CI is the only producer of its apk; the image installs
|
||||||
# installs the exact registry package users later get via 'apk upgrade'.
|
# the exact registry package users later get via 'apk upgrade'.
|
||||||
# pmbootstrap has no knob for a third-party repository, and after the main
|
# pmbootstrap has no knob for a third-party repository, and after the main
|
||||||
# 'apk add' it re-adds every package found in its local packages dir BY FILE
|
# 'apk add' it re-adds every package found in its local packages dir BY FILE
|
||||||
# PATH — which makes apk verify the package's own signature, and registry
|
# PATH — which makes apk verify the package's own signature, and registry
|
||||||
|
|
@ -256,13 +270,21 @@ retry "build libcamera" pmbootstrap $NOCROSS build --arch aarch64 libcamera
|
||||||
# stay byte-identical, so the identity checksum equals the registry's), drop
|
# stay byte-identical, so the identity checksum equals the registry's), drop
|
||||||
# into the local packages dir, re-index. The abuild key exists because the
|
# into the local packages dir, re-index. The abuild key exists because the
|
||||||
# builds above initialized the buildroot.
|
# builds above initialized the buildroot.
|
||||||
IMSD_DL="$WORK/imsd-apk"
|
REG_DL="$WORK/registry-apks"
|
||||||
rm -rf "$IMSD_DL"
|
rm -rf "$REG_DL"
|
||||||
mkdir -p "$IMSD_DL"
|
mkdir -p "$REG_DL"
|
||||||
for _f in "imsd-$IMSD_VERSION.apk" "imsd-systemd-$IMSD_VERSION.apk"; do
|
for _f in "imsd-$IMSD_VERSION.apk" "imsd-systemd-$IMSD_VERSION.apk" \
|
||||||
retry "fetch $_f" curl -fsSL -o "$IMSD_DL/$_f" "$IMSD_REGISTRY/aarch64/$_f"
|
"fingerprintd-$FPD_VERSION.apk" "fingerprintd-systemd-$FPD_VERSION.apk" \
|
||||||
|
"fingerprintd-agent-$FPD_VERSION.apk"; do
|
||||||
|
# every fetched file must have a pin: 'grep .' below drops empty lines,
|
||||||
|
# so an empty pin list would otherwise pass the check with nothing checked
|
||||||
|
printf '%s\n' "$IMSD_SHA256" "$FPD_SHA256" | grep -q " $_f\$" || {
|
||||||
|
echo "no sha256 pin for $_f - add it to IMSD_SHA256/FPD_SHA256" >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
retry "fetch $_f" curl -fsSL -o "$REG_DL/$_f" "$IMSD_REGISTRY/aarch64/$_f"
|
||||||
done
|
done
|
||||||
(cd "$IMSD_DL" && printf '%s\n' "$IMSD_SHA256" | grep . | sha256sum -c -)
|
(cd "$REG_DL" && printf '%s\n' "$IMSD_SHA256" "$FPD_SHA256" | grep . | sha256sum -c -)
|
||||||
ABUILD_KEY=$(echo "$WORKDIR"/config_abuild/*.rsa)
|
ABUILD_KEY=$(echo "$WORKDIR"/config_abuild/*.rsa)
|
||||||
if [ ! -f "$ABUILD_KEY" ]; then
|
if [ ! -f "$ABUILD_KEY" ]; then
|
||||||
echo "expected exactly one abuild key in $WORKDIR/config_abuild" >&2
|
echo "expected exactly one abuild key in $WORKDIR/config_abuild" >&2
|
||||||
|
|
@ -271,9 +293,9 @@ fi
|
||||||
# abuild-keygen ran inside the chroot as pmbootstrap's user (uid 12345), so
|
# abuild-keygen ran inside the chroot as pmbootstrap's user (uid 12345), so
|
||||||
# the key is 0600 to that uid and unreadable here (run 49 died on exactly
|
# the key is 0600 to that uid and unreadable here (run 49 died on exactly
|
||||||
# this); sign from a private copy taken via sudo, then drop it.
|
# this); sign from a private copy taken via sudo, then drop it.
|
||||||
KEYCOPY="$IMSD_DL/abuild-key.rsa"
|
KEYCOPY="$REG_DL/abuild-key.rsa"
|
||||||
sudo install -m 0600 -o "$(id -un)" "$ABUILD_KEY" "$KEYCOPY"
|
sudo install -m 0600 -o "$(id -un)" "$ABUILD_KEY" "$KEYCOPY"
|
||||||
for _f in "$IMSD_DL"/*.apk; do
|
for _f in "$REG_DL"/*.apk; do
|
||||||
python3 ./apk-resign.py "$_f" "$KEYCOPY" "$(basename "$ABUILD_KEY").pub"
|
python3 ./apk-resign.py "$_f" "$KEYCOPY" "$(basename "$ABUILD_KEY").pub"
|
||||||
done
|
done
|
||||||
rm -f "$KEYCOPY"
|
rm -f "$KEYCOPY"
|
||||||
|
|
@ -286,11 +308,11 @@ if [ ! -d "$PKGDIR" ]; then
|
||||||
echo "$PKGDIR missing - the package builds above should have created it" >&2
|
echo "$PKGDIR missing - the package builds above should have created it" >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
for _f in "$IMSD_DL"/*.apk; do
|
for _f in "$REG_DL"/*.apk; do
|
||||||
sudo install -m 0644 -o "$(stat -c %u "$PKGDIR")" -g "$(stat -c %g "$PKGDIR")" \
|
sudo install -m 0644 -o "$(stat -c %u "$PKGDIR")" -g "$(stat -c %g "$PKGDIR")" \
|
||||||
"$_f" "$PKGDIR/$(basename "$_f")"
|
"$_f" "$PKGDIR/$(basename "$_f")"
|
||||||
done
|
done
|
||||||
rm -f "$IMSD_DL"/*.apk
|
rm -f "$REG_DL"/*.apk
|
||||||
pmbootstrap index
|
pmbootstrap index
|
||||||
|
|
||||||
# --- 4. build the image -------------------------------------------------------
|
# --- 4. build the image -------------------------------------------------------
|
||||||
|
|
@ -323,6 +345,7 @@ cp README.md install.sh "$STAGE/fp6-img/"
|
||||||
echo "built: $(date -u +%Y-%m-%dT%H:%M:%SZ)"
|
echo "built: $(date -u +%Y-%m-%dT%H:%M:%SZ)"
|
||||||
echo "default login: user / 147147 (same as official postmarketOS images)"
|
echo "default login: user / 147147 (same as official postmarketOS images)"
|
||||||
echo "imsd: $IMSD_REGISTRY imsd-$IMSD_VERSION (registry package, sha256-pinned)"
|
echo "imsd: $IMSD_REGISTRY imsd-$IMSD_VERSION (registry package, sha256-pinned)"
|
||||||
|
echo "fingerprintd: $IMSD_REGISTRY fingerprintd-$FPD_VERSION (registry package, sha256-pinned)"
|
||||||
} > "$STAGE/fp6-img/build-info.txt"
|
} > "$STAGE/fp6-img/build-info.txt"
|
||||||
# sums of the extracted contents
|
# sums of the extracted contents
|
||||||
(cd "$STAGE/fp6-img" && sha256sum -- * > sha256sums.txt)
|
(cd "$STAGE/fp6-img" && sha256sum -- * > sha256sums.txt)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue