(Fix): replaced hardcoded C.__uint32_t / C.__int32_t casts with a C helper function (auth/utmpx_time.h) that lets the compiler handle type conversion.
This commit is contained in:
4
.gitignore
vendored
4
.gitignore
vendored
@@ -3,4 +3,6 @@ go_project_build_documentation.md
|
|||||||
documentation.md
|
documentation.md
|
||||||
|
|
||||||
session.md
|
session.md
|
||||||
build/*
|
build/*
|
||||||
|
examples/*
|
||||||
|
things_todo.md
|
||||||
37
CHANGELOG.md
Normal file
37
CHANGELOG.md
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
# Changelog
|
||||||
|
|
||||||
|
## 0.1.0 — Unreleased
|
||||||
|
|
||||||
|
first public release
|
||||||
|
|
||||||
|
### What's In
|
||||||
|
|
||||||
|
- tui login screen with username/password fields, session switcher, and status messages
|
||||||
|
- supports x11, wayland, and tty sessions
|
||||||
|
- pam authentication via cgo (thread-locked for safety)
|
||||||
|
- faillock integration — detects lockouts, shows remaining attempts, admin bypass via ctrl+u
|
||||||
|
- conway's game of life background rendered at 30 fps with unicode half-block characters
|
||||||
|
- spring animation on switcher transitions
|
||||||
|
- shake animation on failed login
|
||||||
|
- caps lock indicator via ioctl
|
||||||
|
- configurable power controls (shutdown/reboot on f1/f2 by default)
|
||||||
|
- toml configuration with `$VARIABLE` substitution
|
||||||
|
- preview mode (`--preview`) to test the login screen without leaving your session
|
||||||
|
- utmpx user accounting (glibc only)
|
||||||
|
- x11 session setup — xauthority cookies, sigusr1 handshake, server timeout
|
||||||
|
- privilege dropping for child processes
|
||||||
|
- log piping with 64 mb cap
|
||||||
|
|
||||||
|
### Recent Fixes
|
||||||
|
|
||||||
|
- **utmpx time field portability** — replaced hardcoded `C.__uint32_t` / `C.__int32_t` casts with a C helper function (`auth/utmpx_time.h`) that lets the compiler handle type conversion. fixes build failure on systems where `ut_tv` uses `struct timeval` instead of the 32/64 compat struct
|
||||||
|
- **makefile `deps` target** — added `make deps` to automatically install `libpam0g-dev` and `build-essential`, and verify go is present
|
||||||
|
- **readme overhaul** — rewrote for clarity: added "what problem does this solve", "how it works", known issues, simpler install instructions, and proper dependency listing
|
||||||
|
|
||||||
|
### What's Missing
|
||||||
|
|
||||||
|
- no tests
|
||||||
|
- session spawning uses `ForkExec` which is less clean than the original fork-then-exec model
|
||||||
|
- not all config options affect the rendering yet
|
||||||
|
- occasional terminal state corruption on abrupt exit
|
||||||
|
- automata background can flicker on rapid terminal resizes
|
||||||
18
Makefile
18
Makefile
@@ -33,9 +33,25 @@ RST := \033[0m
|
|||||||
|
|
||||||
## ─── targets ────────────────────────────────────────────────
|
## ─── targets ────────────────────────────────────────────────
|
||||||
|
|
||||||
.PHONY: all build install uninstall clean test lint fmt vet \
|
.PHONY: all deps build install uninstall clean test lint fmt vet \
|
||||||
run-preview release help
|
run-preview release help
|
||||||
|
|
||||||
|
deps: ## install system dependencies
|
||||||
|
@printf " $(BLUE)%-10s$(RST) checking dependencies...\n" "DEPS"
|
||||||
|
@if ! dpkg -s libpam0g-dev >/dev/null 2>&1; then \
|
||||||
|
printf " $(YELLOW)%-10s$(RST) sudo apt install -y libpam0g-dev\n" ""; \
|
||||||
|
sudo apt install -y libpam0g-dev; \
|
||||||
|
fi
|
||||||
|
@if ! dpkg -s build-essential >/dev/null 2>&1; then \
|
||||||
|
printf " $(YELLOW)%-10s$(RST) sudo apt install -y build-essential\n" ""; \
|
||||||
|
sudo apt install -y build-essential; \
|
||||||
|
fi
|
||||||
|
@if ! command -v go >/dev/null 2>&1; then \
|
||||||
|
printf " $(RED)%-10s$(RST) go not found — install go 1.22+\n" ""; \
|
||||||
|
exit 1; \
|
||||||
|
fi
|
||||||
|
@printf " $(GREEN)%-10s$(RST) dependencies ok\n" "DEPS"
|
||||||
|
|
||||||
all: build ## build the release binary
|
all: build ## build the release binary
|
||||||
|
|
||||||
build: $(BUILD_DIR)/$(BINARY) ## compile latchd
|
build: $(BUILD_DIR)/$(BINARY) ## compile latchd
|
||||||
|
|||||||
23
README.md
23
README.md
@@ -44,31 +44,18 @@ This project is a work in progress. here's what you should know:
|
|||||||
|
|
||||||
### from source
|
### from source
|
||||||
|
|
||||||
you need go 1.22 or later and `libpam-dev` (or your distro's equivalent).
|
you need go 1.22 or later, `libpam0g-dev` (debian/ubuntu) or `pam-devel` (rhel/fedora) or `pam` (arch), and a c compiler (`build-essential`).
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# clone and build
|
make deps # install system dependencies
|
||||||
cd src
|
sudo make install # build, install binary + configs + systemd unit
|
||||||
go build -ldflags="-s -w" -o latchd .
|
|
||||||
sudo cp latchd /usr/bin/
|
|
||||||
|
|
||||||
# set up config and session directories
|
|
||||||
sudo mkdir -p /etc/latchd/wms /etc/latchd/wayland /var/log /var/cache
|
|
||||||
sudo cp ../extra/config.toml /etc/latchd/config.toml
|
|
||||||
sudo cp ../extra/xsetup.sh /etc/latchd/xsetup.sh
|
|
||||||
sudo cp ../extra/lemurs.pam /etc/pam.d/latchd
|
|
||||||
sudo cp ../extra/lemurs.service /etc/systemd/system/latchd.service
|
|
||||||
|
|
||||||
# enable the service
|
|
||||||
sudo systemctl enable latchd
|
sudo systemctl enable latchd
|
||||||
```
|
```
|
||||||
|
|
||||||
you can also use the makefile:
|
to test without rebooting:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
make build # compile to build/latchd
|
make run-preview
|
||||||
sudo make install # install to /usr/bin and set up systemd
|
|
||||||
make run-preview # test the login screen in your current terminal
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### arch
|
### arch
|
||||||
|
|||||||
@@ -6,8 +6,10 @@ package auth
|
|||||||
/*
|
/*
|
||||||
#include <utmpx.h>
|
#include <utmpx.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/time.h>
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "utmpx_time.h"
|
||||||
*/
|
*/
|
||||||
import "C"
|
import "C"
|
||||||
import (
|
import (
|
||||||
@@ -49,8 +51,7 @@ func AddUtmpx(user string, tty uint8, pid uint32) *UtmpxSession {
|
|||||||
ut.ut_id[0] = C.char(ttyCh)
|
ut.ut_id[0] = C.char(ttyCh)
|
||||||
|
|
||||||
us := time.Now().UnixMicro()
|
us := time.Now().UnixMicro()
|
||||||
ut.ut_tv.tv_sec = C.__uint32_t(us / 1_000_000)
|
C.latchd_set_utmpx_time(&ut, C.int64_t(us/1_000_000), C.int32_t(us%1_000_000))
|
||||||
ut.ut_tv.tv_usec = C.__int32_t(us % 1_000_000)
|
|
||||||
|
|
||||||
C.setutxent()
|
C.setutxent()
|
||||||
C.pututxline(&ut)
|
C.pututxline(&ut)
|
||||||
|
|||||||
9
src/auth/utmpx_time.h
Normal file
9
src/auth/utmpx_time.h
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
// Helper: assign seconds + microseconds to utmpx's ut_tv field.
|
||||||
|
// The C compiler handles the type conversion, so this works whether
|
||||||
|
// ut_tv is struct timeval (long tv_sec/tv_usec) or the compat struct
|
||||||
|
// (__uint32_t tv_sec / __int32_t tv_usec).
|
||||||
|
|
||||||
|
static inline void latchd_set_utmpx_time(struct utmpx *ut, int64_t sec, int32_t usec) {
|
||||||
|
ut->ut_tv.tv_sec = sec;
|
||||||
|
ut->ut_tv.tv_usec = usec;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user