1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
|
#!/bin/sh
# Xreset - runs as root at session end on display :0.
# Return console ownership to root (TakeConsole). Absolute paths.
/bin/chown root /dev/console
/bin/chmod 622 /dev/console
exit 0
Xcursor.theme: whiteglass
xlogin*login.translations: #override \
Ctrl<Key>R: abort-display()\n\
<Key>F1: set-session-argument(failsafe) finish-field()\n\
<Key>Delete: delete-character()\n\
<Key>Left: move-backward-character()\n\
<Key>Right: move-forward-character()\n\
<Key>Home: move-to-begining()\n\
<Key>End: move-to-end()\n\
Ctrl<Key>KP_Enter: set-session-argument(failsafe) finish-field()\n\
<Key>KP_Enter: set-session-argument() finish-field()\n\
Ctrl<Key>Return: set-session-argument(failsafe) finish-field()\n\
<Key>Return: set-session-argument() finish-field()
! `CLIENTHOST` is an xdm token replaced with the system hostname at display
! time (dynamic per machine). Show ONLY the hostname -- deliberately NO
! "Welcome"/invitation language, which has been argued in unauthorized-access
! cases to imply an invitation. Branding lives on the wallpaper wordmark.
xlogin*greeting: CLIENTHOST
! The display IS access-controlled (start.sh starts Xorg with a MIT-MAGIC-COOKIE
! -auth file), but xdm does not track auth for a `foreign` display and would
! otherwise show its scary "This is an unsecure session". Use the same host text.
xlogin*unsecureGreeting: CLIENTHOST
xlogin*namePrompt: \040\040\040\040\040\040\040Login:
xlogin*passwdPrompt: \040\040\040\040Password:
! Mask the password with '*' (keystroke feedback; only exposes length).
xlogin*echoPasswd: true
xlogin*echoPasswdChar: *
xlogin*fail: Login incorrect or forbidden by policy
#if WIDTH > 800
xlogin*greetFont: -adobe-helvetica-bold-o-normal--24-240-75-75-p-138-iso8859-1
xlogin*font: -adobe-helvetica-medium-r-normal--18-180-75-75-p-98-iso8859-1
xlogin*promptFont: -adobe-helvetica-bold-r-normal--18-180-75-75-p-103-iso8859-1
xlogin*failFont: -adobe-helvetica-bold-r-normal--18-180-75-75-p-103-iso8859-1
xlogin*greetFace: Serif-24:bold:italic
xlogin*face: Helvetica-18
xlogin*promptFace: Helvetica-18:bold
xlogin*failFace: Helvetica-18:bold
#else
xlogin*greetFont: -adobe-helvetica-bold-o-normal--17-120-100-100-p-92-iso8859-1
xlogin*font: -adobe-helvetica-medium-r-normal--12-120-75-75-p-67-iso8859-1
xlogin*promptFont: -adobe-helvetica-bold-r-normal--12-120-75-75-p-70-iso8859-1
xlogin*failFont: -adobe-helvetica-bold-o-normal--14-140-75-75-p-82-iso8859-1
xlogin*greetFace: Serif-18:bold:italic
xlogin*face: Helvetica-12
xlogin*promptFace: Helvetica-12:bold
xlogin*failFace: Helvetica-14:bold
#endif
#ifdef COLOR
! Zygaena marine-dark palette
! bg #0d1117 (deep marine)
! text #cfe0e0 (pale teal-grey)
! accent #1fb6b6 (teal - greeting/prompt/input)
! input #161b22 (slightly raised field)
! fail #ff5f56 (warning red)
xlogin*borderWidth: 1
xlogin*frameWidth: 4
xlogin*innerFramesWidth: 1
xlogin*shdColor: #0a0d12
xlogin*hiColor: #1c2530
xlogin*background: #0d1117
xlogin*foreground: #cfe0e0
xlogin*inpColor: #161b22
xlogin*greetColor: #1fb6b6
xlogin*promptColor: #1fb6b6
xlogin*failColor: #ff5f56
*Foreground: #cfe0e0
*Background: #0d1117
#else
xlogin*borderWidth: 3
xlogin*frameWidth: 0
xlogin*innerFramesWidth: 1
xlogin*shdColor: black
xlogin*hiColor: black
#endif
! Off-brand XLibre "X" logo hidden for now; a Zygaena mark (XPM) can be dropped
! in here later. No logoFileName => the greeter shows the login box only.
xlogin*useShape: true
xlogin*logoPadding: 10
! hh-greeter-power: Shutdown/Reboot button bar on the greeter (Zygaena teal).
HhGreeterPower*background: #0d1117
HhGreeterPower*Box.background: #0d1117
HhGreeterPower*Command.background: #12303a
HhGreeterPower*Command.foreground: #54e0e0
HhGreeterPower*Command.borderColor: #1fb6b6
HhGreeterPower*Command.borderWidth: 1
HhGreeterPower*Command.internalWidth: 14
HhGreeterPower*Command.internalHeight: 8
HhGreeterPower*Command.font: -*-helvetica-bold-r-normal-*-14-*-*-*-*-*-iso8859-1
! Confirmation dialog (Shut down? / Reboot?)
HhGreeterPower*Dialog.background: #12303a
HhGreeterPower*Dialog.borderColor: #1fb6b6
HhGreeterPower*Dialog.label.background: #12303a
HhGreeterPower*Dialog.label.foreground: #cfe0e0
HhGreeterPower*Dialog.label.font: -*-helvetica-medium-r-normal-*-14-*-*-*-*-*-iso8859-1
XConsole.text.geometry: 480x130
XConsole.verbose: true
XConsole*iconic: true
XConsole*font: fixed
Chooser*geometry: 700x500+300+200
Chooser*allowShellResize: false
Chooser*viewport.forceBars: true
Chooser*label.font: *-new century schoolbook-bold-i-normal-*-240-*
Chooser*label.label: XDMCP Host Menu from CLIENTHOST
Chooser*list.font: -*-*-medium-r-normal-*-*-230-*-*-c-*-iso8859-1
Chooser*Command.font: *-new century schoolbook-bold-r-normal-*-180-*
#
# Xservers file, Hammerhead workstation
#
# DECOUPLED: our zyginit start.sh launches Xorg itself (xdm-managed startup
# hangs on illumos VT acquisition). xdm therefore manages only the greeter +
# session on the already-running server, declared FOREIGN — xdm does not
# start or stop it. See DESKTOP_XLIBRE_XDM_GREETER_PLAN.md.
#
:0 foreign
#!/bin/sh
# Xsession - runs AS the authenticated user after login (xdm sets
# $USER/$HOME/$DISPLAY/$XAUTHORITY).
#
# Put the Hammerhead desktop config (shipped under /usr/local/etc/xdg) on the
# XDG search path so openbox/tint2/conky find the BRANDED config even for a
# fresh user with no ~/.config. Exported here so it is inherited by the whole
# session tree (including a user's own ~/.xsession, if any).
export XDG_CONFIG_DIRS="/usr/local/etc/xdg:${XDG_CONFIG_DIRS:-/etc/xdg}"
export XDG_DATA_DIRS="/usr/local/share:${XDG_DATA_DIRS:-/usr/share}"
# Seed ~/.config with the Hammerhead desktop defaults if absent, so the
# openbox autostart (tint2/conky/wallpaper) fires even for a fresh user.
/usr/local/bin/hh-desktop-init
# Prefer the user's own ~/.xsession; otherwise the Hammerhead Openbox session.
if [ -x "$HOME/.xsession" ]; then
exec "$HOME/.xsession"
fi
exec /usr/local/bin/openbox-session
#!/bin/sh
# Xsetup_0 - branded backdrop drawn before the xlogin box appears.
# Runs as root on display :0. Absolute paths only.
#
# HOME: xdm's setup env is minimal; feh needs a HOME to read/write its config.
# XAUTHORITY: connect to the access-controlled (foreign) server started by
# the zyginit start.sh with our MIT-MAGIC-COOKIE.
export HOME=/root
export XAUTHORITY=/var/lib/xdm/authdir/authfiles/A:0
/usr/local/bin/xsetroot -solid "#0d1117"
[ -r /usr/local/share/backgrounds/hammerhead.png ] && \
/usr/local/bin/feh --bg-fill /usr/local/share/backgrounds/hammerhead.png &
# Shutdown/Reboot button bar, bottom-right corner (no WM on the greeter).
# Killed by Xstartup on login so it never leaks into the user's session.
/usr/local/bin/hh-greeter-power -geometry -40-12 &
#!/bin/sh
# Xstartup - runs as root at session start on display :0.
# Give console ownership to the logging-in user (GiveConsole). Absolute paths.
/bin/chown "$USER" /dev/console
# Remove the greeter's Shutdown/Reboot button bar so it doesn't leak into the
# user's session (the foreign server is not reset on login).
/usr/bin/pkill -x hh-greeter-power 2>/dev/null
exit 0
#!/bin/sh
# Build script for hammerhead-xdm.
#
# No upstream tarball - all inputs are local files shipped alongside this
# script. This port overlays Hammerhead branding + X-server/session wiring
# onto the stock xdm defaults (installed under $PREFIX/lib/X11/xdm by the
# xdm port), and ships a DISABLED zyginit xdm service under /etc.
set -e
PORTDIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
# --- A. Config overlay -> $PREFIX/lib/X11/xdm/ ---
XDMDIR="$PKGDIR$PREFIX/lib/X11/xdm"
mkdir -p "$XDMDIR"
# Plain config files (mode 644).
install -m 644 "$PORTDIR/xdm-config" "$XDMDIR/xdm-config"
install -m 644 "$PORTDIR/Xservers" "$XDMDIR/Xservers"
install -m 644 "$PORTDIR/Xresources" "$XDMDIR/Xresources"
# Executable X* hook scripts (mode 755).
install -m 755 "$PORTDIR/Xsetup_0" "$XDMDIR/Xsetup_0"
install -m 755 "$PORTDIR/Xsession" "$XDMDIR/Xsession"
install -m 755 "$PORTDIR/Xstartup" "$XDMDIR/Xstartup"
install -m 755 "$PORTDIR/Xreset" "$XDMDIR/Xreset"
# --- A2. hh-greeter-power: Xaw Shutdown/Reboot button bar for the greeter ---
mkdir -p "$PKGDIR$PREFIX/bin"
gcc "$PORTDIR/hh-greeter-power.c" \
-I"$PREFIX/include" -L"$PREFIX/lib" -R"$PREFIX/lib" \
-lXaw7 -lXmu -lXt -lX11 \
-o "$PKGDIR$PREFIX/bin/hh-greeter-power"
# --- B. zyginit service (shipped DISABLED) -> /etc/zyginit/services/xdm/ ---
# Absolute /etc, OUTSIDE $PREFIX. No enabled.d symlink is created.
SVCDIR="$PKGDIR/etc/zyginit/services/xdm"
mkdir -p "$SVCDIR"
install -m 644 "$PORTDIR/service.toml" "$SVCDIR/service.toml"
install -m 755 "$PORTDIR/start.sh" "$SVCDIR/start.sh"
/*
* hh-greeter-power.c - a tiny Athena (Xaw) button bar with Shutdown and
* Reboot buttons for the xdm greeter, each guarded by a confirmation popup.
*
* xdm's classic xlogin greeter has no power buttons, and the greeter display
* runs with no window manager. This standalone client is launched by
* Xsetup_0 (as root, so `zygctl poweroff`/`reboot` have the privilege to run)
* and killed by Xstartup when a session begins, so it never leaks into the
* user's desktop. Styling comes from the HhGreeterPower* resources in
* Xresources (loaded by xrdb); placement from the -geometry Xsetup_0 passes.
*
* Build: cc hh-greeter-power.c -I$PREFIX/include -L$PREFIX/lib -R$PREFIX/lib \
* -lXaw7 -lXmu -lXt -lX11 -o hh-greeter-power
*/
#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>
#include <X11/Shell.h>
#include <X11/Xaw/Box.h>
#include <X11/Xaw/Command.h>
#include <X11/Xaw/Dialog.h>
#include <stdlib.h>
static Widget toplevel;
static Widget confirm_popup = NULL;
static const char *pending_cmd = NULL;
static void
dismiss(void)
{
if (confirm_popup != NULL) {
XtPopdown(confirm_popup);
XtDestroyWidget(confirm_popup);
confirm_popup = NULL;
}
}
static void
do_it(Widget w, XtPointer client, XtPointer call)
{
(void) w; (void) client; (void) call;
if (pending_cmd != NULL)
(void) system(pending_cmd); /* machine goes down; no return expected */
dismiss();
}
static void
cancel(Widget w, XtPointer client, XtPointer call)
{
(void) w; (void) client; (void) call;
dismiss();
}
/* Pop a centered confirmation dialog for a power action. */
static void
confirm(const char *prompt, const char *cmd, const char *okLabel)
{
Widget dlg;
Dimension pw, ph;
Position px, py;
int sw, sh;
dismiss(); /* only one popup at a time */
pending_cmd = cmd;
confirm_popup = XtVaCreatePopupShell("confirm",
transientShellWidgetClass, toplevel, (char *)NULL);
dlg = XtVaCreateManagedWidget("dialog", dialogWidgetClass, confirm_popup,
XtNlabel, prompt, (char *)NULL);
XawDialogAddButton(dlg, okLabel, do_it, NULL);
XawDialogAddButton(dlg, "Cancel", cancel, NULL);
/* Center on screen (no window manager to place it). */
XtRealizeWidget(confirm_popup);
XtVaGetValues(confirm_popup, XtNwidth, &pw, XtNheight, &ph, (char *)NULL);
sw = WidthOfScreen(XtScreen(toplevel));
sh = HeightOfScreen(XtScreen(toplevel));
px = (Position)((sw - (int)pw) / 2);
py = (Position)((sh - (int)ph) / 2);
XtVaSetValues(confirm_popup, XtNx, px, XtNy, py, (char *)NULL);
XtPopup(confirm_popup, XtGrabExclusive);
}
static void
shutdown_cb(Widget w, XtPointer client, XtPointer call)
{
(void) w; (void) client; (void) call;
confirm("Shut down this system?", "/sbin/zygctl poweroff", "Shut down");
}
static void
reboot_cb(Widget w, XtPointer client, XtPointer call)
{
(void) w; (void) client; (void) call;
confirm("Reboot this system?", "/sbin/zygctl reboot", "Reboot");
}
int
main(int argc, char **argv)
{
XtAppContext app;
Widget box, sd, rb;
toplevel = XtOpenApplication(&app, "HhGreeterPower", NULL, 0, &argc, argv,
NULL, applicationShellWidgetClass, NULL, 0);
box = XtVaCreateManagedWidget("box", boxWidgetClass, toplevel,
XtNorientation, XtorientHorizontal, (char *)NULL);
sd = XtVaCreateManagedWidget("Shutdown", commandWidgetClass, box,
(char *)NULL);
XtAddCallback(sd, XtNcallback, shutdown_cb, NULL);
rb = XtVaCreateManagedWidget("Reboot", commandWidgetClass, box,
(char *)NULL);
XtAddCallback(rb, XtNcallback, reboot_cb, NULL);
XtRealizeWidget(toplevel);
XtAppMainLoop(app);
return 0;
}
# hammerhead-xdm - Zygaena branding + X-server/session wiring overlaid onto
# xdm's installed default config, plus Hammerhead's first port-provided
# zyginit service (shipped DISABLED).
#
# No upstream source: all inputs are local config files shipped alongside
# build.sh. This port depends on xdm (which installs the stock defaults we
# overlay) and hammerhead-desktop (Openbox session + branded backdrop).
# See build.sh and docs/roadmap/DESKTOP_XLIBRE_XDM_GREETER_PLAN.md.
[package]
name = "hammerhead-xdm"
version = "1.0.0"
release = 12
description = "Zygaena marine-dark xdm greeter branding, system Xsession/Xservers wiring, and a disabled zyginit xdm service"
url = "https://git.sharkos.one/zygaena/hammerhead"
license = "CDDL-1.0"
maintainer = "Chris Tusa <chris.tusa@leafscale.com>"
arch = "x86_64"
[dependencies]
# xsetroot: Xsetup_0 paints a solid backdrop; xrdb: xdm loads the branded
# Xresources onto the greeter; xauth: start.sh sets the MIT-MAGIC-COOKIE for
# the decoupled (foreign) server (release 3).
runtime = ["xdm", "hammerhead-desktop", "xsetroot", "xrdb", "xauth"]
# libXaw/libXt/libXmu: to compile hh-greeter-power (the greeter's Xaw
# Shutdown/Reboot button bar).
build = ["libXaw", "libXt", "libXmu", "libX11"]
[build]
parallel = false
# Hammerhead's first port-provided zyginit service.
# Graphical login via xdm on the console framebuffer. Runs as ROOT (xdm
# itself drops privileges per session), so NO `user` field. Shipped
# DISABLED: this port creates no /etc/zyginit/enabled.d/xdm symlink.
#
# Coexists with console-login: the decoupled X server lives on its own VT
# (vtdaemon holds vt1, X gets vt2), so it does NOT contend for /dev/console.
# Ctrl-Alt-F# switches between the greeter (vt2) and the text consoles.
[service]
name = "xdm"
description = "Graphical login (xdm on the console framebuffer)"
type = "daemon"
[exec]
start = "/etc/zyginit/services/xdm/start.sh"
[dependencies]
# vtdaemon MUST be up first: it configures the kernel VT subsystem, without
# which Xorg's VT_WAITACTIVE bring-up hangs (started with no ctty by zyginit).
requires = ["utmpd", "filesystem", "vtdaemon"]
after = ["devfs"]
[contract]
param = ["inherit", "noorphan"]
fatal = ["hwerr"]
[restart]
on = "failure"
delay = 5
max_retries = 3
#!/bin/zsh
# zyginit start hook for the Hammerhead xdm graphical login.
#
# DECOUPLED server model: xdm-managed X-server startup hangs on illumos VT
# acquisition ("using VT number 2" never completes) — while a separately
# started server works fine. So we start our own Xorg here (the proven M2/M3
# launch), then run xdm against it as a FOREIGN display (xdm draws only the
# greeter + runs the session; it does not start/stop the server). See
# docs/roadmap/DESKTOP_XLIBRE_XDM_GREETER_PLAN.md.
#
# MIT-MAGIC-COOKIE-1 access control so the display is authorized (no
# "unsecure session" warning). Absolute paths only (zyginit convention).
set -u
XAUTHDIR=/var/lib/xdm/authdir/authfiles
XAUTH="$XAUTHDIR/A:0"
# Robustness: a crashed prior instance (or a zyginit restart whose
# backgrounded Xorg orphaned past the contract teardown) can leave a stale
# server, X lock, or xdm pid file. Clear them first so a restart does NOT
# accumulate X servers. We are still zsh here (xdm is exec'd at the end), so
# pkill xdm cannot hit this script.
/usr/bin/pkill -9 -x Xorg 2>/dev/null
/usr/bin/pkill -9 -x xdm 2>/dev/null
/bin/sleep 1
/bin/mkdir -p "$XAUTHDIR"
/bin/rm -f "$XAUTH" /var/run/xdm.pid /tmp/.X0-lock /tmp/.X11-unix/X0 2>/dev/null
# Fresh cookie, shared between the server (-auth) and every X client via
# XAUTHORITY (xdm greeter, Xsetup, and the user session all inherit it).
COOKIE=$(/usr/bin/openssl rand -hex 16)
/usr/local/bin/xauth -f "$XAUTH" add :0 . "$COOKIE"
export XAUTHORITY="$XAUTH"
# Start Xorg with auth, in the background (the launch that works on our console).
/usr/local/bin/Xorg :0 -nolisten tcp -auth "$XAUTH" -config /etc/X11/xorg.conf &
# Wait for the server socket (illumos has no seq/timeout(1)).
i=0
while [ ! -S /tmp/.X11-unix/X0 ] && [ "$i" -lt 60 ]; do /bin/sleep 0.25; i=$((i + 1)); done
/bin/sleep 1
# Run xdm on the foreign, authorized server. exec so zyginit supervises xdm;
# Xorg is in the same process contract and is torn down with the service.
exec /usr/local/bin/xdm -nodaemon -config /usr/local/lib/X11/xdm/xdm-config
!
! Hammerhead xdm-config: overlaid onto the stock xdm default. Only the
! display-:0 startup/reset hooks are re-pointed at our Xstartup/Xreset
! (GiveConsole/TakeConsole console-ownership handling); the setup, session,
! and resources hooks already reference the paths we ship. XDMCP stays OFF.
!
DisplayManager.authDir: /var/lib/xdm
DisplayManager.errorLogFile: /var/log/xdm.log
DisplayManager.pidFile: /var/run/xdm.pid
DisplayManager.keyFile: /usr/local/lib/X11/xdm/xdm-keys
DisplayManager.servers: /usr/local/lib/X11/xdm/Xservers
DisplayManager.accessFile: /usr/local/lib/X11/xdm/Xaccess
DisplayManager*resources: /usr/local/lib/X11/xdm/Xresources
DisplayManager.willing: su nobody -s /bin/sh -c /usr/local/lib/X11/xdm/Xwilling
! All displays should use authorization, but we cannot be sure
! X terminals may not be configured that way, so they will require
! individual resource settings.
DisplayManager*authorize: true
!
DisplayManager*chooser: /usr/local/lib/X11/xdm/chooser
DisplayManager*startup: /usr/local/lib/X11/xdm/Xstartup
DisplayManager*session: /usr/local/lib/X11/xdm/Xsession
DisplayManager*reset: /usr/local/lib/X11/xdm/Xreset
DisplayManager*authComplain: true
! The following resources set up display :0 as the console.
DisplayManager._0.setup: /usr/local/lib/X11/xdm/Xsetup_0
DisplayManager._0.startup: /usr/local/lib/X11/xdm/Xstartup
DisplayManager._0.reset: /usr/local/lib/X11/xdm/Xreset
DisplayManager._0.session: /usr/local/lib/X11/xdm/Xsession
DisplayManager*loginmoveInterval: 10
! SECURITY: do not listen for XDMCP or Chooser requests
! Comment out this line if you want to manage X terminals with xdm
DisplayManager.requestPort: 0
|