Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 35f1a17cdf | |||
| 48d363bb18 | |||
| 448e4212e3 |
@@ -1,7 +1,5 @@
|
|||||||
# Moongreet
|
# Moongreet
|
||||||
|
|
||||||
**Name**: Selene (Mondgöttin — passend zu Moon-greet)
|
|
||||||
|
|
||||||
## Projekt
|
## Projekt
|
||||||
|
|
||||||
Moongreet ist ein greetd-Greeter für Wayland, gebaut mit Rust + gtk4-rs + gtk4-layer-shell.
|
Moongreet ist ein greetd-Greeter für Wayland, gebaut mit Rust + gtk4-rs + gtk4-layer-shell.
|
||||||
|
|||||||
Generated
+1
-1
@@ -575,7 +575,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "moongreet"
|
name = "moongreet"
|
||||||
version = "0.8.0"
|
version = "0.8.4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"gdk-pixbuf",
|
"gdk-pixbuf",
|
||||||
"gdk4",
|
"gdk4",
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "moongreet"
|
name = "moongreet"
|
||||||
version = "0.8.2"
|
version = "0.8.4"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
description = "A greetd greeter for Wayland with GTK4 and Layer Shell"
|
description = "A greetd greeter for Wayland with GTK4 and Layer Shell"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
|
|||||||
+17
-3
@@ -1,5 +1,19 @@
|
|||||||
# Decisions
|
# Decisions
|
||||||
|
|
||||||
|
## 2026-04-24 – Audit fix: shrink password-in-memory window (v0.8.4)
|
||||||
|
|
||||||
|
- **Who**: ClaudeCode, Dom
|
||||||
|
- **Why**: Security audit flagged the GTK password path as holding more copies of the plaintext password in memory than necessary. `attempt_login` wrapped the already-`Zeroizing<String>` caller value into a second `Zeroizing<String>` (`password.to_string()`), and the GTK `GString` backing `entry.text()` persisted in libc malloc'd memory until the allocator reused the page.
|
||||||
|
- **Tradeoffs**: The GTK `GString` and the libc `strdup` copy on the PAM FFI boundary remain non-zeroizable — this is an inherent GTK/libc limitation, already documented in CLAUDE.md. This change reduces the Rust-owned copies to one and clears the `PasswordEntry` text field immediately after extraction to shorten the GTK-side window.
|
||||||
|
- **How**: (1) `attempt_login` now takes `password: Zeroizing<String>` by value instead of `&str`, moving ownership into the `spawn_blocking` closure. (2) The redundant `Zeroizing::new(password.to_string())` inside `attempt_login` is removed. (3) `password_entry.set_text("")` is called right after the password is extracted from the activate handler, shortening the lifetime of the GTK-internal buffer.
|
||||||
|
|
||||||
|
## 2026-04-21 – Ship polkit rule in moongreet instead of moonarch (v0.8.3)
|
||||||
|
|
||||||
|
- **Who**: ClaudeCode, Dom
|
||||||
|
- **Why**: Reboot/shutdown from the greeter silently failed on a fresh install. The polkit rule that grants the `greeter` user `org.freedesktop.login1.{reboot,power-off}` lived in the moonarch repo but was never installed by any PKGBUILD. The laptop worked only because the rule had been hand-deployed once.
|
||||||
|
- **Tradeoffs**: Rule ownership moves from moonarch (system defaults) to moongreet (greeter-specific auth). Cleaner boundary — moonarch no longer needs to know about the greeter's auth requirements — but it means moongreet is now responsible for a system polkit rule that ties it to a fixed username (`greeter`).
|
||||||
|
- **How**: Source file moved to `moongreet/config/polkit/50-moongreet-power.rules`, installed to `/etc/polkit-1/rules.d/` by `moongreet-git/PKGBUILD`. Old file removed from the moonarch repo.
|
||||||
|
|
||||||
## 2026-04-09 – Monitor hotplug via ListModel items-changed
|
## 2026-04-09 – Monitor hotplug via ListModel items-changed
|
||||||
|
|
||||||
- **Who**: ClaudeCode, Dom
|
- **Who**: ClaudeCode, Dom
|
||||||
@@ -51,7 +65,7 @@
|
|||||||
|
|
||||||
## 2026-03-28 – Remove embedded wallpaper from binary
|
## 2026-03-28 – Remove embedded wallpaper from binary
|
||||||
|
|
||||||
- **Who**: Selene, Dom
|
- **Who**: ClaudeCode, Dom
|
||||||
- **Why**: Wallpaper is installed by moonarch to /usr/share/moonarch/wallpaper.jpg. Embedding a 374K JPEG in the binary is redundant. GTK background color (Catppuccin Mocha base) is a clean fallback.
|
- **Why**: Wallpaper is installed by moonarch to /usr/share/moonarch/wallpaper.jpg. Embedding a 374K JPEG in the binary is redundant. GTK background color (Catppuccin Mocha base) is a clean fallback.
|
||||||
- **Tradeoffs**: Without moonarch installed AND without config, greeter shows plain dark background instead of wallpaper. Acceptable — that's the expected minimal state.
|
- **Tradeoffs**: Without moonarch installed AND without config, greeter shows plain dark background instead of wallpaper. Acceptable — that's the expected minimal state.
|
||||||
- **How**: Remove wallpaper.jpg from GResources, return None from resolve_background_path when no file found, skip wallpaper window creation and background picture when no path available.
|
- **How**: Remove wallpaper.jpg from GResources, return None from resolve_background_path when no file found, skip wallpaper window creation and background picture when no path available.
|
||||||
@@ -65,13 +79,13 @@
|
|||||||
|
|
||||||
## 2026-03-28 – Optional background blur via `image` crate (superseded)
|
## 2026-03-28 – Optional background blur via `image` crate (superseded)
|
||||||
|
|
||||||
- **Who**: Selene, Dom
|
- **Who**: ClaudeCode, Dom
|
||||||
- **Why**: Blurred wallpaper as greeter background is a common UX pattern for login screens
|
- **Why**: Blurred wallpaper as greeter background is a common UX pattern for login screens
|
||||||
- **Tradeoffs**: Adds `image` crate dependency (~15 transitive crates); CPU-side Gaussian blur at load time adds startup latency proportional to image size and sigma. Acceptable because blur runs once and the texture is shared across monitors.
|
- **Tradeoffs**: Adds `image` crate dependency (~15 transitive crates); CPU-side Gaussian blur at load time adds startup latency proportional to image size and sigma. Acceptable because blur runs once and the texture is shared across monitors.
|
||||||
- **How**: `load_background_texture(bg_path, blur_radius)` loads texture, optionally applies `imageops::blur()`, returns blurred `gdk::Texture`. Config option `background-blur: Option<f32>` in `[appearance]` TOML section.
|
- **How**: `load_background_texture(bg_path, blur_radius)` loads texture, optionally applies `imageops::blur()`, returns blurred `gdk::Texture`. Config option `background-blur: Option<f32>` in `[appearance]` TOML section.
|
||||||
|
|
||||||
## 2026-03-28 – Audit fixes for shared wallpaper texture (v0.4.1)
|
## 2026-03-28 – Audit fixes for shared wallpaper texture (v0.4.1)
|
||||||
- **Who**: Selene, Dominik
|
- **Who**: ClaudeCode, Dominik
|
||||||
- **Why**: Quality, performance, and security audits flagged issues in `load_background_texture()`, debug logging, and greetd error handling
|
- **Why**: Quality, performance, and security audits flagged issues in `load_background_texture()`, debug logging, and greetd error handling
|
||||||
- **Tradeoffs**: GResource path now requires UTF-8 (returns `None` for non-UTF-8 instead of aborting); 50 MB wallpaper limit is generous but prevents OOM; debug logging off by default trades observability for security
|
- **Tradeoffs**: GResource path now requires UTF-8 (returns `None` for non-UTF-8 instead of aborting); 50 MB wallpaper limit is generous but prevents OOM; debug logging off by default trades observability for security
|
||||||
- **How**: GResource branch via `resources_lookup_data()` + `from_bytes()` (no abort), file size limit, error details only at debug level, `MOONGREET_DEBUG` env var for log level, greetd retry path truncation matching `show_greetd_error()`
|
- **How**: GResource branch via `resources_lookup_data()` + `from_bytes()` (no abort), file size limit, error details only at debug level, `MOONGREET_DEBUG` env var for log level, greetd retry path truncation matching `show_greetd_error()`
|
||||||
|
|||||||
@@ -60,6 +60,14 @@ sudo cp config/moongreet.toml /etc/moongreet/moongreet.toml
|
|||||||
user = "greeter"
|
user = "greeter"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
4. Install the polkit rule so the greeter user can reboot / power off:
|
||||||
|
```bash
|
||||||
|
sudo install -Dm644 config/polkit/50-moongreet-power.rules \
|
||||||
|
/etc/polkit-1/rules.d/50-moongreet-power.rules
|
||||||
|
```
|
||||||
|
Without this rule, `loginctl reboot` / `loginctl poweroff` fail because
|
||||||
|
greetd's greeter session is inactive in logind.
|
||||||
|
|
||||||
## Development
|
## Development
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
// ABOUTME: Allow the greeter user to reboot and power off without authentication.
|
||||||
|
// ABOUTME: Required because greetd's greeter session is inactive in logind.
|
||||||
|
|
||||||
|
polkit.addRule(function(action, subject) {
|
||||||
|
if (subject.user === "greeter" &&
|
||||||
|
(action.id === "org.freedesktop.login1.reboot" ||
|
||||||
|
action.id === "org.freedesktop.login1.reboot-multiple-sessions" ||
|
||||||
|
action.id === "org.freedesktop.login1.power-off" ||
|
||||||
|
action.id === "org.freedesktop.login1.power-off-multiple-sessions")) {
|
||||||
|
return polkit.Result.YES;
|
||||||
|
}
|
||||||
|
});
|
||||||
+6
-3
@@ -493,6 +493,10 @@ pub fn create_greeter_window(
|
|||||||
let Some(user) = user else { return };
|
let Some(user) = user else { return };
|
||||||
|
|
||||||
let password = Zeroizing::new(entry.text().to_string());
|
let password = Zeroizing::new(entry.text().to_string());
|
||||||
|
// Clear the GTK entry's internal buffer as early as possible. GTK allocates
|
||||||
|
// the backing `GString` via libc malloc, which `zeroize` cannot reach — the
|
||||||
|
// best we can do is shorten the window during which it resides in memory.
|
||||||
|
entry.set_text("");
|
||||||
|
|
||||||
let session = get_selected_session(&session_dropdown, &sessions_rc);
|
let session = get_selected_session(&session_dropdown, &sessions_rc);
|
||||||
let Some(session) = session else {
|
let Some(session) = session else {
|
||||||
@@ -502,7 +506,7 @@ pub fn create_greeter_window(
|
|||||||
|
|
||||||
attempt_login(
|
attempt_login(
|
||||||
&user,
|
&user,
|
||||||
&password,
|
password,
|
||||||
&session,
|
&session,
|
||||||
strings,
|
strings,
|
||||||
&state,
|
&state,
|
||||||
@@ -953,7 +957,7 @@ fn set_login_sensitive(
|
|||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
fn attempt_login(
|
fn attempt_login(
|
||||||
user: &User,
|
user: &User,
|
||||||
password: &str,
|
password: Zeroizing<String>,
|
||||||
session: &Session,
|
session: &Session,
|
||||||
strings: &'static Strings,
|
strings: &'static Strings,
|
||||||
state: &Rc<RefCell<GreeterState>>,
|
state: &Rc<RefCell<GreeterState>>,
|
||||||
@@ -992,7 +996,6 @@ fn attempt_login(
|
|||||||
set_login_sensitive(password_entry, session_dropdown, false);
|
set_login_sensitive(password_entry, session_dropdown, false);
|
||||||
|
|
||||||
let username = user.username.clone();
|
let username = user.username.clone();
|
||||||
let password = Zeroizing::new(password.to_string());
|
|
||||||
let exec_cmd = session.exec_cmd.clone();
|
let exec_cmd = session.exec_cmd.clone();
|
||||||
let session_name = session.name.clone();
|
let session_name = session.name.clone();
|
||||||
let greetd_sock = state.borrow().greetd_sock.clone();
|
let greetd_sock = state.borrow().greetd_sock.clone();
|
||||||
|
|||||||
Reference in New Issue
Block a user