From 23d04521570a42598437dc088c52a916be5e0a6c Mon Sep 17 00:00:00 2001 From: enricobuehler Date: Tue, 11 Aug 2026 20:21:16 +0200 Subject: [PATCH] feat(host): GameStream opt-in on every route; the native plane is deny(unsafe_code)-enforced MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The user direction after WP0: ENet exists only for Moonlight, so the native plane must be provably safe and the compat planes a deliberate choice. Opt-in, everywhere. Windows already was (unchecked installer task). The three opt-out surfaces are flipped: the shipped systemd user unit (deb/RPM/Arch/ sysext) no longer bakes --gamestream into ExecStart — a new PUNKTFUNK_GAMESTREAM=1 host.env knob (pf-host-config, OR-ed with the CLI flag) is the packaged opt-in; the NixOS module default goes true→false, with a module-check assertion that unset = native-only; the Deck installer takes --gamestream to opt in (--no-gamestream kept as explicit-off). Docs (quickstart, running-as-a-service, moonlight, ubuntu/fedora/arch firewall sections, gnome/sway, how-it-works) rewritten to the opt-in shape; the CHANGELOG carries the upgrade note. Enforced-safe. punktfunk-core is #![deny(unsafe_code)] crate-wide — every module that parses network bytes is safe Rust as a compile error, not a census result. Carve-outs are exactly two documented classes, neither of which interprets attacker bytes: the client surface (abi, client) and the transport syscall-batching shims (udp/{apple,linux,windows}, qos_windows). In punktfunk-host, the modules a secure-default host exposes — native (cfg-not-test: its tests exercise the client C ABI on purpose), native_pairing, mgmt, mgmt_token, discovery, wol — are #[forbid(unsafe_code)]. Gates: Linux amd64 container clippy --all-targets -D warnings clean over core+host-config+host; core 204 tests green under the deny; mgmt 46/46, control 6/6. .133 Windows clippy (shipped features, clean-first, sentinel-checked) clean — covers the qos_windows/udp-windows carve-outs. macOS + iOS cargo check green (the apple.rs carve-out compiles for real). --- CHANGELOG.md | 38 +++++++++++++++++ crates/pf-host-config/src/lib.rs | 10 +++++ crates/punktfunk-core/src/abi.rs | 5 +++ crates/punktfunk-core/src/client/mod.rs | 5 +++ crates/punktfunk-core/src/lib.rs | 10 +++++ .../src/transport/qos_windows.rs | 4 ++ .../punktfunk-core/src/transport/udp/apple.rs | 4 ++ .../punktfunk-core/src/transport/udp/linux.rs | 4 ++ .../src/transport/udp/windows.rs | 4 ++ crates/punktfunk-host/src/main.rs | 20 ++++++++- docs-site/content/docs/arch.md | 14 ++++--- docs-site/content/docs/fedora.md | 13 +++--- docs-site/content/docs/gnome.md | 6 +-- docs-site/content/docs/how-it-works.md | 5 ++- docs-site/content/docs/moonlight.md | 25 ++++++----- docs-site/content/docs/quickstart.md | 11 ++--- .../content/docs/running-as-a-service.md | 42 ++++++++++--------- docs-site/content/docs/sway.md | 6 +-- docs-site/content/docs/ubuntu.md | 20 ++++----- packaging/kde/host.env | 4 ++ packaging/nix/module-check.nix | 11 +++++ packaging/nix/nixos-module.nix | 8 ++-- scripts/host.env.example | 7 ++++ scripts/punktfunk-host.service | 13 +++--- scripts/steamdeck/install.sh | 15 +++---- 25 files changed, 222 insertions(+), 82 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 67317f3c..ad393341 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,44 @@ with the version table of the release you are moving to, then read **Breaking ch ## v0.27.1 — in development +### GameStream is now opt-in on EVERY route (⚠ packager-visible default change) + +The secure native-only host is the default everywhere; the Moonlight-compat planes (plain-HTTP +pairing + the legacy GCM path, security-review #5/#9) are enabled only by an explicit choice: + +- **The shipped systemd user unit** (`scripts/punktfunk-host.service`, installed by deb/RPM/Arch/ + sysext) runs bare `serve` — `--gamestream` is no longer baked into `ExecStart`. Opt in via the + new **`PUNKTFUNK_GAMESTREAM=1`** knob in `host.env` (pf-host-config; equivalent to the flag — + either source enables), so no unit editing survives-upgrades dance is needed. + ⚠ **Upgrade note:** a packaged host that served Moonlight by default becomes native-only until + the operator sets the knob (a hand-made `ExecStart` drop-in keeps winning as before). +- **NixOS module**: `services.punktfunk.host.gamestream` default flipped `true` → `false` + (module-check gained a "default is native-only" assertion); enabling it still opens the + GameStream firewall ports. +- **Steam Deck installer**: `--gamestream` opts in (was on-by-default with `--no-gamestream`; + the old flag is still accepted as explicit-off). +- Windows was already opt-in (unchecked installer task) and is unchanged. + +### The ENet control port now exists only while a pairing does (rust-safety WP0) + +`rusty_enet` — a c2rust-style transpile of C ENet, and the host's only pre-auth-reachable unsafe +surface — no longer listens unconditionally: UDP 47999 binds when the paired-client list becomes +non-empty and is torn down when the last pairing is removed (a live client gets the same +TERMINATION+disconnect farewell as a host-side session end). Pairing itself is HTTPS on nvhttp and +never touches the port, so a never-paired `--gamestream` host exposes no ENet at all. En route: +the management API's unpair endpoint never persisted (`save_paired` was missing), so an unpair +lasted only until the next restart — fixed. `rusty_enet` is now pinned `=0.4.0`. + +### Memory-safety, compiler-enforced (embedder-visible lint tightening) + +`punktfunk-core` now carries `#![deny(unsafe_code)]` crate-wide: everything that parses network +bytes is safe Rust by compiler-enforced invariant. The documented `#![allow]` carve-outs are the +client surface (`abi`, `client`) and the platform syscall-batching shims under `transport` +(`udp/{apple,linux,windows}`, `qos_windows`) — none of which interpret attacker bytes. In +`punktfunk-host`, the modules a secure-default host exposes (`native`, `native_pairing`, `mgmt`, +`mgmt_token`, `discovery`, `wol`) are `#[forbid(unsafe_code)]`. If you embed `punktfunk-core` and +patch it, new unsafe outside the carve-outs is now a compile error. + ### NixOS + KDE — session detection, the other half 🛑 **v0.27.0's NixOS session-detection fix did not reach a stock NixOS + Plasma 6 box.** It resolved diff --git a/crates/pf-host-config/src/lib.rs b/crates/pf-host-config/src/lib.rs index b532dcfe..fcdb4b9e 100644 --- a/crates/pf-host-config/src/lib.rs +++ b/crates/pf-host-config/src/lib.rs @@ -144,6 +144,13 @@ pub struct HostConfig { /// text ("Living Room PC"); the DNS-level `