diff --git a/recipes/arje-logind-compat.toml b/recipes/arje-logind-compat.toml index 95a1f148..fa13dd80 100644 --- a/recipes/arje-logind-compat.toml +++ b/recipes/arje-logind-compat.toml @@ -42,3 +42,38 @@ compiler = "zig-cc" target = "x86_64-linux-musl" link = "static" flags = ["-p", "arje-compat", "--bin", "arje-logind-compat"] + +# ── La POLÍTICA D-Bus viaja con el artefacto, no con la imagen ────────────────────────────────── +# El `system.conf` de dbus trae `` por defecto: cada servicio de sistema aporta su +# propio fichero de política, y el de login1 normalmente lo instala systemd. Acá no hay systemd, así +# que hasta hoy lo escribía `scripts/gnome/qemu-desktop-image.sh` — con un TODO al lado diciendo que +# ése no era su lugar. Y no lo era: **un servicio que no puede adueñarse de su nombre no es un +# servicio**, así que la política es parte de lo que este paquete PROMETE, igual que el binario. +# Dejarla en el script de una imagen significaba que cualquier otra imagen —metal, KDE, mirada— tenía +# el daemon y no podía usarlo. +# +# `allow own` sólo a root (es quien lo lanza) y `send_destination` a cualquiera, porque mutter y el +# resto consultan login1 sin ser root. +# +# La fase `install` REPLICA el default del lab para Cargo (copiar los ejecutables de target/release a +# /usr/bin) y le agrega el fichero. Sobrescribir la fase es la única forma: el default no tiene un +# gancho para material extra. +[build.phases] +install = ''' +set -e +mkdir -p /out/usr/bin /out/usr/share/dbus-1/system.d +find target/release -maxdepth 1 -type f -perm -100 -exec cp {} /out/usr/bin/ \; +cat > /out/usr/share/dbus-1/system.d/org.freedesktop.login1.conf <<'XML' + + + + + + + + + + +XML +''' diff --git a/recipes/arje-polkit-compat.toml b/recipes/arje-polkit-compat.toml index 4a72768d..d86291d3 100644 --- a/recipes/arje-polkit-compat.toml +++ b/recipes/arje-polkit-compat.toml @@ -49,3 +49,36 @@ compiler = "zig-cc" target = "x86_64-linux-musl" link = "static" flags = ["-p", "arje-compat", "--bin", "arje-polkit-compat"] + +# ── La POLÍTICA D-Bus viaja con el artefacto ─────────────────────────────────────────────────── +# Misma razón que en arje-logind-compat: un servicio que no puede adueñarse de su nombre no es un +# servicio, así que su política es parte de lo que el paquete promete. Hasta hoy la escribía el script +# de la imagen de GNOME, con lo cual el shim existía para las otras imágenes y no servía en ellas. +# +# ⚠ EL NOMBRE `zz-` NO ES DECORATIVO. A diferencia de login1, acá el nombre YA TIENE política: la trae +# el artefacto de `polkit`, y permite `own` sólo al usuario **polkitd** — este shim corre como root, así +# que con ella sola se lo niegan. dbus lee `system.d` en ORDEN ALFABÉTICO y las reglas posteriores +# ganan, de modo que un fichero que ordene después AÑADE el permiso sin descartar el resto de la +# política de upstream (que además trae las reglas de `AuthenticationAgent`). Reescribir la de polkit +# habría sido pisar un artefacto sellado. +[build.phases] +install = ''' +set -e +mkdir -p /out/usr/bin /out/usr/share/dbus-1/system.d +find target/release -maxdepth 1 -type f -perm -100 -exec cp {} /out/usr/bin/ \; +cat > /out/usr/share/dbus-1/system.d/zz-arje-polkit-compat.conf <<'XML' + + + + + + + + + + + +XML +''' diff --git a/scripts/gnome/qemu-desktop-image.sh b/scripts/gnome/qemu-desktop-image.sh index 0f169d37..be6e68e0 100755 --- a/scripts/gnome/qemu-desktop-image.sh +++ b/scripts/gnome/qemu-desktop-image.sh @@ -99,36 +99,22 @@ if [ -n "${ALC_BIN:-}" ] && [ -x "$ALC_BIN" ]; then echo " ⚠ binario LOCAL (no sellado): $ALC_BIN" elif ALC="${ALC:-store/$(./target/release/hammer --store store hash recipes/arje-logind-compat.toml 2>/dev/null | tail -1 | sed 's/^b3://')-arje-logind-compat}"; [ -d "$ALC" ]; then install -Dm755 "$ALC"/usr/bin/arje-logind-compat "$MERGED"/usr/bin/arje-logind-compat + # …y su POLÍTICA D-Bus, que desde 2026-07-30 viaja en el artefacto. Se copia, no se escribe: el + # dueño del fichero es el paquete. Ojo — inyectar «sólo el binario» era el bug que destapó la + # comprobación de abajo: el artefacto traía el .conf y la imagen lo dejaba afuera. + install -d "$MERGED/usr/share/dbus-1/system.d" + cp -a --remove-destination "$ALC"/usr/share/dbus-1/system.d/. "$MERGED"/usr/share/dbus-1/system.d/ 2>/dev/null || true echo " ✓ $(basename "$ALC" | cut -c1-12)" else echo " ✗ falta arje-logind-compat en store/ — mutter no hallará sesión" >&2; exit 1 fi -echo "==> política D-Bus para org.freedesktop.login1" -# Segundo muro del mismo eslabón: con el bus ya visible, dbus RECHAZA que el daemon se adueñe del -# nombre — "not allowed to own the service org.freedesktop.login1 due to security policies". El -# system.conf de dbus trae `` por defecto: cada servicio de sistema aporta su propio -# fichero de política, y systemd normalmente instala el de login1. Acá no hay systemd, y el artefacto -# de arje-logind-compat es sólo el binario ⇒ nadie pone la política. La escribimos: root puede -# adueñarse del nombre, y cualquiera puede hablarle (mutter consulta login1 sin ser root). -# TODO: esto pertenece al artefacto de arje-logind-compat, no a la imagen; acá está de forma -# explícita para que se vea qué falta empaquetar del lado de arje. +# La POLÍTICA D-Bus de login1 YA NO SE ESCRIBE ACÁ (2026-07-30): la trae el artefacto de +# `arje-logind-compat`, que es su dueño. Este bloque tenía un TODO diciendo exactamente eso, y estaba +# bien puesto: un servicio que no puede adueñarse de su nombre no es un servicio, así que su política +# es parte de lo que el paquete promete. Teniéndola acá, cualquier OTRA imagen —metal, KDE, mirada— +# se llevaba el daemon y no podía usarlo. Se comprueba abajo, junto con la de polkit. install -d "$MERGED/usr/share/dbus-1/system.d" -cat > "$MERGED/usr/share/dbus-1/system.d/org.freedesktop.login1.conf" <<'XML' - - - - - - - - - - -XML -chmod 644 "$MERGED/usr/share/dbus-1/system.d/org.freedesktop.login1.conf" -echo " ✓ org.freedesktop.login1.conf" echo "==> inyectando arje-polkit-compat (el PolicyKit1 del fractal) + su política" # EL TERCER ESLABÓN DEL MISMO TIPO, y lo destapó la lista de nombres del bus: accounts-daemon y @@ -139,40 +125,28 @@ echo "==> inyectando arje-polkit-compat (el PolicyKit1 del fractal) + su políti # ⚠ El shim autoriza TODO (postura de sistema confiado ya tomada por arje) — ver su receta. if APC="${APC:-store/$(./target/release/hammer --store store hash recipes/arje-polkit-compat.toml 2>/dev/null | tail -1 | sed 's/^b3://')-arje-polkit-compat}"; [ -d "$APC" ]; then install -Dm755 "$APC"/usr/bin/arje-polkit-compat "$MERGED"/usr/bin/arje-polkit-compat + install -d "$MERGED/usr/share/dbus-1/system.d" + cp -a --remove-destination "$APC"/usr/share/dbus-1/system.d/. "$MERGED"/usr/share/dbus-1/system.d/ 2>/dev/null || true echo " ✓ $(basename "$APC" | cut -c1-12)" else echo " ✗ falta arje-polkit-compat en store/ — accounts-daemon y upowerd no adquirirán su nombre" >&2 exit 1 fi -# A DIFERENCIA de login1, acá el nombre YA tiene política: la trae el artefacto de `polkit`. Pero -# permite `own` sólo al usuario **polkitd**, y nuestro shim corre como root ⇒ dbus se lo niega. +# Su política tampoco se escribe acá: viaja en el artefacto (ver recipes/arje-polkit-compat.toml, que +# explica por qué el fichero se llama `zz-` y no reemplaza al de polkit). # -# Se agrega un fichero APARTE en vez de reescribir el de polkit, por dos razones: -# 1. dbus lee todo `system.d` en orden alfabético y las reglas posteriores ganan, así que un -# `zz-…` añade el permiso sin descartar el resto de la política de upstream (que además trae las -# reglas de `AuthenticationAgent`). -# 2. **el fichero de polkit es un HARDLINK DE SÓLO LECTURA del store** — el rootfs fundido se arma -# con hardlinks a los artefactos sellados, que están a 0444. Un `cat >` encima falla con -# `Permission denied`, y eso ya rompió un build de esta imagen. Regla para este script: nunca -# sobrescribir un fichero que venga de un artefacto; agregar al lado, o `rm -f` primero para -# romper el enlace (y entonces se está pisando algo sellado, que es una decisión, no un descuido). -cat > "$MERGED/usr/share/dbus-1/system.d/zz-arje-polkit-compat.conf" <<'XML' - - - - - - - - - - - -XML -chmod 644 "$MERGED/usr/share/dbus-1/system.d/zz-arje-polkit-compat.conf" -echo " ✓ zz-arje-polkit-compat.conf (añade own= para root sobre la política de polkit)" +# ── COMPROBACIÓN, que es lo que reemplaza a escribirlas ──────────────────────────────────────── +# Mover algo a un artefacto sólo es una mejora si se NOTA cuando falta. Sin esto, un artefacto viejo +# sin su .conf daría el mismo fallo tardío y confuso de antes: el daemon arranca, no adquiere el +# nombre, y el escritorio espera 25 s por servicio sin decir por qué. +for pol in org.freedesktop.login1.conf zz-arje-polkit-compat.conf; do + if [ -f "$MERGED/usr/share/dbus-1/system.d/$pol" ]; then + echo " ✓ $pol (del artefacto)" + else + echo " ✗ falta $pol — el artefacto que lo trae es viejo; re-sellá su receta" >&2 + exit 1 + fi +done echo "==> usuario messagebus (el system bus hace setuid a él)" for f in passwd:messagebus:x:81:81:messagebus:/dev/null:/sbin/nologin group:messagebus:x:81:; do