Rewrite moongreet from Python to Rust (v0.3.0)

Complete rewrite of the greetd greeter from Python/PyGObject to Rust/gtk4-rs
for consistency with moonset, single binary without Python runtime, and
improved security through Rust memory safety.

Modules: main, greeter, ipc, config, i18n, users, sessions, power
86 unit tests covering all modules including login_worker IPC flow.
Security hardening: shell-word splitting for exec_cmd, absolute path
validation for session binaries, session-name sanitization, absolute
loginctl path, atomic IPC writes.
This commit is contained in:
2026-03-27 22:08:33 +01:00
parent de0b1d40ba
commit 226bbb75e4
39 changed files with 4395 additions and 2768 deletions
+30 -23
View File
@@ -1,51 +1,58 @@
# Moongreet
A greetd greeter for Wayland, built with Python + GTK4 + gtk4-layer-shell.
A greetd greeter for Wayland, built with Rust + GTK4 + gtk4-layer-shell.
Part of the Moonarch ecosystem.
## Features
- **greetd IPC** — Communicates via `$GREETD_SOCK` (length-prefixed JSON)
- **User list** — Parsed from `/etc/passwd` (UID 100065533)
- **Avatars** — AccountsService icons, `~/.face` fallback, default SVG
- **Avatars** — AccountsService icons, `~/.face` fallback, default SVG with theme tinting
- **Sessions** — Discovered from `/usr/share/wayland-sessions/` and `/usr/share/xsessions/`
- **Last user** — Remembered in `/var/cache/moongreet/last-user`
- **Last user/session** — Remembered in `/var/cache/moongreet/`
- **Power actions** — Reboot / Shutdown via `loginctl`
- **Layer Shell** — Fullscreen via gtk4-layer-shell
- **Layer Shell** — Fullscreen via gtk4-layer-shell (TOP layer)
- **Multi-monitor** — Greeter on primary, wallpaper on all monitors
- **i18n** — German and English (auto-detected from system locale)
- **Faillock warning** — Warns after 2 failed attempts, locked message after 3
## Requirements
- Python 3.11+
- GTK 4, PyGObject
- GTK 4
- gtk4-layer-shell (for Wayland fullscreen)
- greetd
## Building
```bash
cargo build --release
```
## Installation
```bash
uv pip install .
# Install binary
sudo install -Dm755 target/release/moongreet /usr/bin/moongreet
# Install config
sudo mkdir -p /etc/moongreet
sudo cp config/moongreet.toml /etc/moongreet/moongreet.toml
```
## System Setup
1. Copy configuration:
```bash
sudo mkdir -p /etc/moongreet
sudo cp config/moongreet.toml /etc/moongreet/moongreet.toml
```
1. Edit `/etc/moongreet/moongreet.toml` — set an absolute path for the wallpaper.
2. Edit `/etc/moongreet/moongreet.toml` — set an absolute path for the wallpaper.
3. Create cache directory:
2. Create cache directory:
```bash
sudo mkdir -p /var/cache/moongreet
sudo mkdir -p /var/cache/moongreet/last-session
sudo chown greeter:greeter /var/cache/moongreet
```
4. Configure greetd (`/etc/greetd/config.toml`):
3. Configure greetd (`/etc/greetd/config.toml`):
```ini
[default_session]
command = "moongreet"
command = "niri -c /etc/greetd/niri-greeter.kdl"
user = "greeter"
```
@@ -53,13 +60,13 @@ uv pip install .
```bash
# Run tests
uv run pytest tests/ -v
cargo test
# Type checking
uv run pyright src/
# Build release
cargo build --release
# Run locally (without greetd)
uv run moongreet
# Run locally (without greetd, needs LD_PRELOAD for layer-shell)
LD_PRELOAD=/usr/lib/libgtk4-layer-shell.so ./target/release/moongreet
```
## License