Commit Graph
3 Commits
Author SHA1 Message Date
enricobuehlerandClaude Opus 5 93902ff60e feat(packaging/bazzite): the sysext feed is signed, and the client refuses one that isn't
`punktfunk-sysext` checked the SHA256 of every image it downloaded, which sounds
like verification but isn't: SHA256SUMS lives on the same registry as the images
it describes, so anything able to replace an image could replace its checksum in
the same request. The checksum only ever proved the download wasn't corrupted.

Each feed now carries SHA256SUMS.asc, a detached OpenPGP signature over the
manifest, and the client verifies it before believing a line of it. The key is
packages@unom.io (AF245C506F4E4763) — the same one that already signs our RPMs,
so boxes have one key to trust and we have one key to rotate. Its public half is
baked into the script rather than fetched from the feed, because a key you fetch
from the thing you're authenticating authenticates nothing; gpg (present on
Bazzite) does the verifying against a throwaway keyring holding only that key, so
"good signature" and "signed by us" are the same statement.

Rollout: stable feeds only publish on a tag, so a `--seal` mode re-signs an
existing manifest without rebuilding an image, and every rpm.yml run seals the
OTHER channel of its Fedora major too. Canary pushes are frequent, so all live
feeds seal within a day of this landing and a key rotation propagates without
republishing anything. Until a feed is sealed the client refuses it and says so,
naming PUNKTFUNK_SYSEXT_ALLOW_UNSIGNED=1 as the informed way through.

Two things testing changed. The baked-key fingerprint check compared against an
empty string — the armor block is a single-quoted shell literal, so the extracted
range carried `FEED_KEY='` on its first line and gpg saw no armor at all; every
publish would have "mismatched" and, on a tag, failed the release. And `status`
captured fetch_manifest's stderr but only printed it on failure, swallowing the
ALLOW_UNSIGNED warning precisely when someone was running unverified.

Verified end to end on Bazzite 44 against a file:// feed with a throwaway key:
unsigned feed refused; ALLOW_UNSIGNED=1 proceeds and says so; wrong signer
rejected; tampered manifest rejected; good signature accepted; `update` exits 1
before touching anything on a bad feed. Publisher side: signs when the baked key
matches, refuses on mismatch, refuses with no key, and its signature round-trips
through the real client. shellcheck clean.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-29 12:12:21 +02:00
enricobuehlerandClaude Fable 5 ef39050dbc docs: repo-wide housekeeping — sync README & docs with the code as shipped
windows-drivers / probe-and-proto (push) Successful in 47s
ci / web (push) Successful in 58s
apple / swift (push) Successful in 1m13s
decky / build-publish (push) Successful in 16s
ci / docs-site (push) Successful in 1m19s
docker / build-push (--build-arg FEDORA_VERSION=44, ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm) (push) Successful in 12s
docker / build-push (ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Successful in 9s
docker / build-push (ci, ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Successful in 8s
docker / build-push (., web/Dockerfile, punktfunk-web) (push) Successful in 43s
windows-drivers / driver-build (push) Successful in 1m45s
docker / build-push (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Successful in 55s
ci / bench (push) Successful in 7m18s
flatpak / build-publish (push) Successful in 6m18s
docker / deploy-docs (push) Successful in 25s
windows-host / package (push) Successful in 8m31s
release / apple (push) Successful in 11m41s
android / android (push) Successful in 13m4s
windows-msix / package (arm64, C:\Users\Public\ffmpeg-arm64, --no-default-features, aarch64-pc-windows-msvc, C:\t-a64) (push) Successful in 1m57s
windows-msix / package (x64, C:\Users\Public\ffmpeg, , x86_64-pc-windows-msvc, C:\t) (push) Successful in 2m16s
arch / build-publish (push) Successful in 16m24s
windows / build (aarch64-pc-windows-msvc) (push) Successful in 1m6s
deb / build-publish (push) Successful in 17m54s
windows / build (x86_64-pc-windows-msvc) (push) Successful in 1m27s
ci / rust (push) Successful in 18m23s
apple / screenshots (push) Successful in 5m58s
rpm / build-publish (43, bazzite, punktfunk-fedora-rpm) (push) Successful in 20m24s
rpm / build-publish (44, fedora-44, punktfunk-fedora44-rpm) (push) Successful in 18m43s
Six parallel audits swept the root docs, docs-site, every per-directory
README, and the packaging docs; every claim below was verified against
the source before editing.

- README: Layout gains the six missing crates (pf-client-core,
  pf-presenter, pf-console-ui, pf-ffvk, pf-driver-proto, punktfunk-tray),
  clients/session, api/ and ci/; Linux/Windows client rows reflect the
  shell + Vulkan-session split and the Vulkan Video -> VAAPI/D3D11VA ->
  software decode chains; the "every client over a C ABI" claim is
  corrected (Rust clients link the core directly); tiered stats overlay
  + console shell noted; Apple row mentions AV1.
- CONTRIBUTING: drop the dead CLAUDE.md link (deliberately untracked);
  point at the README's build/invariants sections. SECURITY: 0.9.0.
- host-cli/pairing: --allow-pairing/--require-pairing are no-op legacy
  names — pairing is required by default, --allow-tofu is the real flag;
  document --data-port and --idle-timeout-ms.
- configuration: document PUNKTFUNK_RECOVER_SESSION_CMD (session-crash
  recovery hook), PUNKTFUNK_MDNS, PUNKTFUNK_DATA_PORT.
- virtual-displays/gnome: GNOME per-client scaling shipped (host-
  persisted) — flip the  to  and describe how it works.
- stats: new "Detail levels" section (Off/Compact/Normal/Detailed +
  per-platform cycle gestures); retire the GTK hand-off note.
- clients/install-client/status/roadmap: decode chains, Windows client
  validation narrowed to HDR-only pending, adaptive bitrate, console
  shell, Apple AV1, Windows host vendor list.
- Sub-READMEs: clients/linux rewritten for the re-architecture; session
  Windows decode rung + d3d11va knob; Windows tiered overlay; Android
  minSdk 28; decky file table; host zerocopy/ path; scripts port
  47992 and steamos-host.md; pf-dualsense source path.
- packaging: canary version bases are tag-derived (<next-minor> via
  pf-version.sh/.ps1), codecs-extra not ffmpeg-full, document the
  pinned offline-Skia tarball + SKIA_BINARIES_URL and vulkan-headers.
- Convert 15 dangling design/*.md links to the punktfunk-planning
  prose convention (those docs live in the private planning repo).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-10 09:13:42 +02:00
enricobuehlerandClaude Opus 4.8 be6c71aed6 feat(security): finish Windows firewall Public opt-in wiring + vuln-disclosure + doc cleanup
Firewall (the service.rs core landed in 796d381): scope the web-console rule
(TCP 47992) to Domain+Private by default with a `--allow-public-network` opt-in
that deletes-then-re-adds the rule, and add the installer "Allow connections on
Public networks" task (unchecked) forwarding the flag to `service install` and
`web setup`. Default is now trusted-networks-only; Public is explicit.

Vulnerability disclosure: SECURITY.md (report to security@punktfunk.com, scope,
SLAs, safe harbor), a Gitea issue-template contact link, a README security line,
and a Reporting section on the docs Security page.

Docs: the Security page now documents the Private/Domain firewall default (and
how to fix a misclassified-Public network / opt in); removed internal design-doc
and CLAUDE.md links from the user-facing docs.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-03 14:08:17 +00:00