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).
64 lines
4.3 KiB
Desktop File
64 lines
4.3 KiB
Desktop File
# punktfunk streaming host — systemd USER unit. Runs the SECURE native-only host by default
|
|
# (punktfunk/1 clients + the management API; no plain-HTTP pairing / legacy GCM nonce reuse —
|
|
# security-review #5/#9). Stock-Moonlight (GameStream) compat is OPT-IN: add
|
|
# PUNKTFUNK_GAMESTREAM=1
|
|
# to ~/.config/punktfunk/host.env (the EnvironmentFile below) and restart — no unit editing
|
|
# needed. Only do that on a TRUSTED LAN; it opens the compat planes' extra ports too.
|
|
#
|
|
# Install (against an already-running compositor session — the host auto-detects and follows it,
|
|
# so host.env needs no backend config):
|
|
# mkdir -p ~/.config/systemd/user && cp scripts/punktfunk-host.service ~/.config/systemd/user/
|
|
# cp scripts/host.env.example ~/.config/punktfunk/host.env # defaults are right for a desktop
|
|
# systemctl --user daemon-reload && systemctl --user enable --now punktfunk-host
|
|
#
|
|
# On that desktop-login route, ALSO install scripts/punktfunk-host-desktop-session.conf as a drop-in:
|
|
# it binds the host to graphical-session.target, so a Plasma/GNOME restart restarts the host instead
|
|
# of leaving it holding a dead Wayland socket + portal connection (the PartOf= below only covers the
|
|
# appliance route, where we start the compositor ourselves). The drop-in's header has the commands.
|
|
#
|
|
# The host does NOT need the login shell's environment: it detects the live session itself per
|
|
# connect and derives WAYLAND_DISPLAY, XDG_RUNTIME_DIR, DBUS_SESSION_BUS_ADDRESS, XDG_CURRENT_DESKTOP,
|
|
# HYPRLAND_INSTANCE_SIGNATURE and SWAYSOCK from the running compositor (vdisplay::apply_session_env).
|
|
# So host.env carries policy, not session plumbing, and `systemctl --user import-environment` is not
|
|
# a prerequisite — the host pushes the live values into the manager env itself when a session switch
|
|
# needs the portal to re-read them.
|
|
#
|
|
# Self-contained boot appliance (no login, no manual steps after boot). These routes PIN the
|
|
# backend via PUNKTFUNK_COMPOSITOR — correct for a dedicated single-session box, but it turns off
|
|
# live-session auto-detection, so never do it on a desktop that switches sessions (Game Mode etc.):
|
|
# - kwin backend (stream the Plasma desktop): also install + enable
|
|
# punktfunk-kde-session.service (it brings up the headless KWin session this After=s), and use
|
|
# the shipped packaging/kde/host.env (pins kwin + WAYLAND_DISPLAY=wayland-kde on purpose).
|
|
# - gamescope backend (stream a nested app, no desktop): set PUNKTFUNK_COMPOSITOR=gamescope in
|
|
# host.env — the host spawns gamescope per session, so no kde-session unit is needed.
|
|
# Then `sudo loginctl enable-linger "$USER"` so user units start at boot, and reboot.
|
|
#
|
|
# The host LISTENS as soon as it starts and only touches the compositor per session (on a client
|
|
# connect), so the After= below is a soft ordering, not a hard readiness gate — the kde-session
|
|
# unit (when present) just needs to be up by the time a client streams (seconds later, user-driven).
|
|
# A missing After= unit (e.g. gamescope backend, no kde-session installed) is simply ignored.
|
|
[Unit]
|
|
Description=punktfunk streaming host (punktfunk/1; +GameStream when PUNKTFUNK_GAMESTREAM=1)
|
|
After=pipewire.service punktfunk-kde-session.service
|
|
# PartOf the kwin session (when present): the host's libei input uses the RemoteDesktop portal,
|
|
# whose D-Bus connection goes stale if the compositor session restarts the portal under it — the
|
|
# in-process reopen loop can't recover that, but a full restart re-establishes it. So restart the
|
|
# host whenever the kde-session restarts. Ignored when punktfunk-kde-session isn't installed
|
|
# (gamescope / other backends).
|
|
PartOf=punktfunk-kde-session.service
|
|
|
|
[Service]
|
|
# '-' optional: NO package creates this file — deb/RPM/Arch ship only host.env.* templates under
|
|
# /usr/share and the postinst merely prints the copy command — so a mandatory read would fail a
|
|
# fresh install outright ("Failed to load environment files"), before the host ever ran. Absent
|
|
# just means every knob at its default (pf-host-config has one for each), which is exactly what
|
|
# `punktfunk-host serve` by hand already does. Contrast punktfunk-web.service, which marks
|
|
# mgmt-token mandatory ON PURPOSE so Restart waits for the host to write it — this is not that.
|
|
EnvironmentFile=-%h/.config/punktfunk/host.env
|
|
ExecStart=%h/punktfunk/target/release/punktfunk-host serve
|
|
Restart=on-failure
|
|
RestartSec=2
|
|
|
|
[Install]
|
|
WantedBy=default.target
|