#!/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 \ CtrlR: abort-display()\n\ F1: set-session-argument(failsafe) finish-field()\n\ Delete: delete-character()\n\ Left: move-backward-character()\n\ Right: move-forward-character()\n\ Home: move-to-begining()\n\ End: move-to-end()\n\ CtrlKP_Enter: set-session-argument(failsafe) finish-field()\n\ KP_Enter: set-session-argument() finish-field()\n\ CtrlReturn: set-session-argument(failsafe) finish-field()\n\ 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 #include #include #include #include #include #include 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 " 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