markdown · 7464 bytes Raw Blame History

gardm Architecture

Overview

gardm is the display manager for the gar desktop suite. It follows a daemon + greeter architecture similar to greetd, providing clean separation between authentication/session management and the user interface.

Components

┌─────────────────────────────────────────────────────────────┐
│                         gardmd                               │
│                   (Display Manager Daemon)                   │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────────────┐  │
│  │    PAM      │  │   X11/Xorg  │  │  Session Manager    │  │
│  │ Integration │  │   Control   │  │  (systemd-logind)   │  │
│  └─────────────┘  └─────────────┘  └─────────────────────┘  │
│                          │                                   │
│                    Unix Socket IPC                           │
│                          │                                   │
└──────────────────────────┼──────────────────────────────────┘
                           │
┌──────────────────────────┼──────────────────────────────────┐
│                          ▼                                   │
│                   gardm-greeter                              │
│                   (Graphical UI)                             │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────────────┐  │
│  │   Cairo/    │  │   garbg     │  │    User Input       │  │
│  │   Pango     │  │ Integration │  │   (login form)      │  │
│  └─────────────┘  └─────────────┘  └─────────────────────┘  │
└─────────────────────────────────────────────────────────────┘

gardmd (Daemon)

The privileged daemon that runs as root. Responsibilities:

  1. X11 Server Management: Start/stop Xorg server on appropriate VT
  2. PAM Authentication: Verify user credentials via /etc/pam.d/gardm
  3. Session Launching: Start selected session (gar, other WMs/DEs)
  4. systemd-logind Integration: Register sessions, handle multi-seat
  5. IPC Server: Listen on Unix socket for greeter commands

gardm-greeter (Frontend)

The unprivileged graphical interface. Runs as dedicated gardm user. Responsibilities:

  1. User Interface: Render login form, session selector, power buttons
  2. garbg Integration: Display same wallpaper that gar session will use
  3. Visual Effects: Blur background, animations, theming
  4. IPC Client: Send auth requests to daemon, receive responses

IPC Protocol

JSON-based protocol over Unix socket at /run/gardm.sock:

Requests (Greeter → Daemon)

// Create authentication session
{ "type": "create_session", "username": "user" }

// Attempt authentication
{ "type": "authenticate", "response": "password123" }

// Start session after successful auth
{ "type": "start_session", "cmd": ["gar-session.sh"], "env": [] }

// Cancel current auth attempt
{ "type": "cancel_session" }

// System actions
{ "type": "shutdown" }
{ "type": "reboot" }
{ "type": "suspend" }

Responses (Daemon → Greeter)

// Success
{ "type": "success" }

// Auth prompt (PAM asking for input)
{ "type": "auth_prompt", "prompt": "Password:", "echo": false }

// Auth info message
{ "type": "auth_info", "message": "..." }

// Auth error
{ "type": "auth_error", "message": "Authentication failed" }

// General error
{ "type": "error", "message": "..." }

Session Discovery

Sessions are discovered from standard locations:

  • /usr/share/xsessions/*.desktop - X11 sessions
  • /usr/share/wayland-sessions/*.desktop - Wayland sessions (future)

gar session file example (/usr/share/xsessions/gar.desktop):

[Desktop Entry]
Name=gar
Comment=Tiling window manager with smart splits
Exec=/usr/local/bin/gar-session.sh
Type=XSession
DesktopNames=gar

User Discovery

Users are enumerated from:

  • /etc/passwd (filter by UID range, shell, home directory existence)
  • AccountsService D-Bus interface (if available)

Hidden users (UID < 1000, nologin shell, system accounts) are filtered out.

garbg Integration

The greeter reads garbg's config to display the same wallpaper:

  1. Read ~/.config/garbg/config.toml for default wallpaper source
  2. Or read playlist state from $XDG_RUNTIME_DIR/garbg-state.json
  3. Apply blur effect for greeter aesthetic
  4. On successful login, gar session starts garbg which shows same image (seamless transition)

Security Model

  • gardmd: Runs as root, handles PAM, minimal attack surface
  • gardm-greeter: Runs as unprivileged gardm user
  • IPC: Socket permissions restrict access to gardm user
  • X11: Greeter runs on isolated X server started by daemon

Configuration

/etc/gardm/config.toml:

[general]
# Default session if user hasn't selected one
default_session = "gar"

# Greeter command
greeter = "/usr/bin/gardm-greeter"

# VT to use (0 = auto-select)
vt = 0

[greeter]
# Theme settings
blur_radius = 20
blur_brightness = 0.7

# Show/hide elements
show_power_buttons = true
show_session_selector = true

# garbg integration
use_garbg_wallpaper = true
fallback_wallpaper = "/usr/share/gardm/backgrounds/default.jpg"

[security]
# Allow empty passwords
allow_empty_password = false

# Lock after N failed attempts (0 = disabled)
lockout_attempts = 5
lockout_duration = 300

PAM Configuration

/etc/pam.d/gardm:

#%PAM-1.0
auth       required     pam_securetty.so
auth       requisite    pam_nologin.so
auth       include      system-local-login
account    include      system-local-login
session    include      system-local-login
password   include      system-local-login

systemd Integration

/usr/lib/systemd/system/gardm.service:

[Unit]
Description=gar Display Manager
After=systemd-user-sessions.service getty@tty1.service plymouth-quit.service
Conflicts=getty@tty1.service

[Service]
ExecStart=/usr/bin/gardmd
Restart=always

[Install]
Alias=display-manager.service

Key Dependencies

Component Crates
gardmd pam, nix, sd-notify, serde, tokio
gardm-greeter x11rb, cairo-rs, pango, image, serde

References

View source
1 # gardm Architecture
2
3 ## Overview
4
5 gardm is the display manager for the gar desktop suite. It follows a **daemon + greeter** architecture similar to [greetd](https://github.com/kennylevinsen/greetd), providing clean separation between authentication/session management and the user interface.
6
7 ## Components
8
9 ```
10 ┌─────────────────────────────────────────────────────────────┐
11 │ gardmd │
12 │ (Display Manager Daemon) │
13 │ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │
14 │ │ PAM │ │ X11/Xorg │ │ Session Manager │ │
15 │ │ Integration │ │ Control │ │ (systemd-logind) │ │
16 │ └─────────────┘ └─────────────┘ └─────────────────────┘ │
17 │ │ │
18 │ Unix Socket IPC │
19 │ │ │
20 └──────────────────────────┼──────────────────────────────────┘
21
22 ┌──────────────────────────┼──────────────────────────────────┐
23 │ ▼ │
24 │ gardm-greeter │
25 │ (Graphical UI) │
26 │ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │
27 │ │ Cairo/ │ │ garbg │ │ User Input │ │
28 │ │ Pango │ │ Integration │ │ (login form) │ │
29 │ └─────────────┘ └─────────────┘ └─────────────────────┘ │
30 └─────────────────────────────────────────────────────────────┘
31 ```
32
33 ### gardmd (Daemon)
34
35 The privileged daemon that runs as root. Responsibilities:
36
37 1. **X11 Server Management**: Start/stop Xorg server on appropriate VT
38 2. **PAM Authentication**: Verify user credentials via `/etc/pam.d/gardm`
39 3. **Session Launching**: Start selected session (gar, other WMs/DEs)
40 4. **systemd-logind Integration**: Register sessions, handle multi-seat
41 5. **IPC Server**: Listen on Unix socket for greeter commands
42
43 ### gardm-greeter (Frontend)
44
45 The unprivileged graphical interface. Runs as dedicated `gardm` user. Responsibilities:
46
47 1. **User Interface**: Render login form, session selector, power buttons
48 2. **garbg Integration**: Display same wallpaper that gar session will use
49 3. **Visual Effects**: Blur background, animations, theming
50 4. **IPC Client**: Send auth requests to daemon, receive responses
51
52 ## IPC Protocol
53
54 JSON-based protocol over Unix socket at `/run/gardm.sock`:
55
56 ### Requests (Greeter → Daemon)
57
58 ```json
59 // Create authentication session
60 { "type": "create_session", "username": "user" }
61
62 // Attempt authentication
63 { "type": "authenticate", "response": "password123" }
64
65 // Start session after successful auth
66 { "type": "start_session", "cmd": ["gar-session.sh"], "env": [] }
67
68 // Cancel current auth attempt
69 { "type": "cancel_session" }
70
71 // System actions
72 { "type": "shutdown" }
73 { "type": "reboot" }
74 { "type": "suspend" }
75 ```
76
77 ### Responses (Daemon → Greeter)
78
79 ```json
80 // Success
81 { "type": "success" }
82
83 // Auth prompt (PAM asking for input)
84 { "type": "auth_prompt", "prompt": "Password:", "echo": false }
85
86 // Auth info message
87 { "type": "auth_info", "message": "..." }
88
89 // Auth error
90 { "type": "auth_error", "message": "Authentication failed" }
91
92 // General error
93 { "type": "error", "message": "..." }
94 ```
95
96 ## Session Discovery
97
98 Sessions are discovered from standard locations:
99
100 - `/usr/share/xsessions/*.desktop` - X11 sessions
101 - `/usr/share/wayland-sessions/*.desktop` - Wayland sessions (future)
102
103 gar session file example (`/usr/share/xsessions/gar.desktop`):
104 ```ini
105 [Desktop Entry]
106 Name=gar
107 Comment=Tiling window manager with smart splits
108 Exec=/usr/local/bin/gar-session.sh
109 Type=XSession
110 DesktopNames=gar
111 ```
112
113 ## User Discovery
114
115 Users are enumerated from:
116
117 - `/etc/passwd` (filter by UID range, shell, home directory existence)
118 - AccountsService D-Bus interface (if available)
119
120 Hidden users (UID < 1000, nologin shell, system accounts) are filtered out.
121
122 ## garbg Integration
123
124 The greeter reads garbg's config to display the same wallpaper:
125
126 1. Read `~/.config/garbg/config.toml` for default wallpaper source
127 2. Or read playlist state from `$XDG_RUNTIME_DIR/garbg-state.json`
128 3. Apply blur effect for greeter aesthetic
129 4. On successful login, gar session starts garbg which shows same image (seamless transition)
130
131 ## Security Model
132
133 - **gardmd**: Runs as root, handles PAM, minimal attack surface
134 - **gardm-greeter**: Runs as unprivileged `gardm` user
135 - **IPC**: Socket permissions restrict access to gardm user
136 - **X11**: Greeter runs on isolated X server started by daemon
137
138 ## Configuration
139
140 `/etc/gardm/config.toml`:
141
142 ```toml
143 [general]
144 # Default session if user hasn't selected one
145 default_session = "gar"
146
147 # Greeter command
148 greeter = "/usr/bin/gardm-greeter"
149
150 # VT to use (0 = auto-select)
151 vt = 0
152
153 [greeter]
154 # Theme settings
155 blur_radius = 20
156 blur_brightness = 0.7
157
158 # Show/hide elements
159 show_power_buttons = true
160 show_session_selector = true
161
162 # garbg integration
163 use_garbg_wallpaper = true
164 fallback_wallpaper = "/usr/share/gardm/backgrounds/default.jpg"
165
166 [security]
167 # Allow empty passwords
168 allow_empty_password = false
169
170 # Lock after N failed attempts (0 = disabled)
171 lockout_attempts = 5
172 lockout_duration = 300
173 ```
174
175 ## PAM Configuration
176
177 `/etc/pam.d/gardm`:
178
179 ```
180 #%PAM-1.0
181 auth required pam_securetty.so
182 auth requisite pam_nologin.so
183 auth include system-local-login
184 account include system-local-login
185 session include system-local-login
186 password include system-local-login
187 ```
188
189 ## systemd Integration
190
191 `/usr/lib/systemd/system/gardm.service`:
192
193 ```ini
194 [Unit]
195 Description=gar Display Manager
196 After=systemd-user-sessions.service getty@tty1.service plymouth-quit.service
197 Conflicts=getty@tty1.service
198
199 [Service]
200 ExecStart=/usr/bin/gardmd
201 Restart=always
202
203 [Install]
204 Alias=display-manager.service
205 ```
206
207 ## Key Dependencies
208
209 | Component | Crates |
210 |-----------|--------|
211 | gardmd | pam, nix, sd-notify, serde, tokio |
212 | gardm-greeter | x11rb, cairo-rs, pango, image, serde |
213
214 ## References
215
216 - [freedesktop.org: Writing Display Managers](https://systemd.io/WRITING_DISPLAY_MANAGERS/)
217 - [greetd](https://github.com/kennylevinsen/greetd) - Architecture inspiration
218 - [SDDM](https://github.com/sddm/sddm) - Feature reference
219 - [LightDM](https://github.com/canonical/lightdm) - Protocol reference