From 4a0c806d83311e991b321642e180e66dc21b6e25 Mon Sep 17 00:00:00 2001 From: auric <104602845+ihateamongus@users.noreply.github.com> Date: Mon, 8 Sep 2025 23:41:35 -0500 Subject: Refactor slogin for framebuffer and OpenRC --- core/slogin/Makefile | 38 +++++++++++ core/slogin/config.def.h | 2 + core/slogin/config.mk | 12 ++++ core/slogin/slogin.c | 161 ++++++++++++++++++++++++++++++++++++++++++++++ core/slogin/slogin.openrc | 9 +++ 5 files changed, 222 insertions(+) create mode 100644 core/slogin/Makefile create mode 100644 core/slogin/config.def.h create mode 100644 core/slogin/config.mk create mode 100644 core/slogin/slogin.c create mode 100644 core/slogin/slogin.openrc diff --git a/core/slogin/Makefile b/core/slogin/Makefile new file mode 100644 index 0000000..0f9b32a --- /dev/null +++ b/core/slogin/Makefile @@ -0,0 +1,38 @@ +# slogin - simple login manager +# See LICENSE file for license details. + +include config.mk + +SRC = slogin.c +OBJ = ${SRC:.c=.o} +RC = slogin.openrc + +all: slogin + +.c.o: + ${CC} -c ${CFLAGS} $< + +${OBJ}: config.h config.mk + +config.h: + cp config.def.h $@ + +slogin: ${OBJ} + ${CC} -o $@ ${OBJ} ${LDFLAGS} + +clean: + rm -f slogin ${OBJ} + +install: all + mkdir -p ${DESTDIR}${PREFIX}/bin + cp -f slogin ${DESTDIR}${PREFIX}/bin + chmod 755 ${DESTDIR}${PREFIX}/bin/slogin + mkdir -p ${DESTDIR}/etc/init.d + cp -f ${RC} ${DESTDIR}/etc/init.d/slogin + chmod 755 ${DESTDIR}/etc/init.d/slogin + +uninstall: + rm -f ${DESTDIR}${PREFIX}/bin/slogin + rm -f ${DESTDIR}/etc/init.d/slogin + +.PHONY: all clean install uninstall diff --git a/core/slogin/config.def.h b/core/slogin/config.def.h new file mode 100644 index 0000000..6e58261 --- /dev/null +++ b/core/slogin/config.def.h @@ -0,0 +1,2 @@ +/* command to run after successful login */ +static const char *logincmd[] = { "startx", NULL }; diff --git a/core/slogin/config.mk b/core/slogin/config.mk new file mode 100644 index 0000000..fcca349 --- /dev/null +++ b/core/slogin/config.mk @@ -0,0 +1,12 @@ +VERSION = 0.2 + +PREFIX = /usr/local +MANPREFIX = ${PREFIX}/share/man + +LIBS = -lcrypt + +CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -DVERSION=\"${VERSION}\" -DHAVE_SHADOW_H +CFLAGS = -std=c99 -pedantic -Wall -Os ${CPPFLAGS} +LDFLAGS = ${LIBS} + +CC = cc diff --git a/core/slogin/slogin.c b/core/slogin/slogin.c new file mode 100644 index 0000000..1978d71 --- /dev/null +++ b/core/slogin/slogin.c @@ -0,0 +1,161 @@ +/* See LICENSE file for license details. */ +#define _XOPEN_SOURCE 700 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../accent.h" +#include "config.h" + +static ColorShm *accentshm; +static char accentcol[8] = "#005577"; + +static void +die(const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + exit(1); +} + +static void +updateaccent(void) +{ + if (!readaccent(&accentshm, accentcol)) + memcpy(accentcol, "#005577", 8); +} + +static void +parseaccent(int *r, int *g, int *b) +{ + unsigned int ri, gi, bi; + if (sscanf(accentcol + 1, "%02x%02x%02x", &ri, &gi, &bi) == 3) { + *r = ri; + *g = gi; + *b = bi; + } else { + *r = 0x00; + *g = 0x55; + *b = 0x77; + } +} + +static void +colored(const char *msg) +{ + int r, g, b; + parseaccent(&r, &g, &b); + printf("\033[38;2;%d;%d;%dm%s\033[0m", r, g, b, msg); +} + +static const char * +gethash(const char *user) +{ + struct passwd *pw; + const char *hash; + if (!(pw = getpwnam(user))) + return NULL; + hash = pw->pw_passwd; +#if HAVE_SHADOW_H + if (!strcmp(hash, "x")) { + struct spwd *sp; + if (!(sp = getspnam(user))) + return NULL; + hash = sp->sp_pwdp; + } +#endif + return hash; +} + +static int +auth(const char *user, const char *pass) +{ + const char *hash = gethash(user); + char *cryptpw; + if (!hash) + return 0; + if (!(cryptpw = crypt(pass, hash))) + return 0; + return !strcmp(cryptpw, hash); +} + +static void +readinput(char *buf, size_t len) +{ + if (!fgets(buf, len, stdin)) + buf[0] = '\0'; + buf[strcspn(buf, "\n")] = '\0'; +} + +static void +readpass(char *buf, size_t len) +{ + struct termios old, new; + tcgetattr(STDIN_FILENO, &old); + new = old; + new.c_lflag &= ~(ECHO); + tcsetattr(STDIN_FILENO, TCSAFLUSH, &new); + readinput(buf, len); + tcsetattr(STDIN_FILENO, TCSAFLUSH, &old); +} + +static void +runsession(const char *user) +{ + struct passwd *pw; + pid_t pid; + if (!(pw = getpwnam(user))) + return; + if ((pid = fork()) == 0) { + if (initgroups(user, pw->pw_gid) < 0) + die("slogin: initgroups failed\n"); + if (setgid(pw->pw_gid) < 0) + die("slogin: setgid failed\n"); + if (setuid(pw->pw_uid) < 0) + die("slogin: setuid failed\n"); + setenv("HOME", pw->pw_dir, 1); + if (chdir(pw->pw_dir) < 0) + die("slogin: chdir failed\n"); + execvp(logincmd[0], (char *const *)logincmd); + _exit(1); + } + waitpid(pid, NULL, 0); +} + +int +main(void) +{ + char user[64]; + char pass[64]; + + for (;;) { + updateaccent(); + printf("\033[2J\033[H"); + colored("login: "); + fflush(stdout); + readinput(user, sizeof user); + colored("password: "); + fflush(stdout); + readpass(pass, sizeof pass); + printf("\n"); + if (auth(user, pass)) { + memset(pass, 0, sizeof pass); + runsession(user); + } else { + colored("Login incorrect\n"); + memset(pass, 0, sizeof pass); + sleep(2); + } + } + return 0; +} diff --git a/core/slogin/slogin.openrc b/core/slogin/slogin.openrc new file mode 100644 index 0000000..2b56a0a --- /dev/null +++ b/core/slogin/slogin.openrc @@ -0,0 +1,9 @@ +#!/sbin/openrc-run +command="/usr/local/bin/slogin" +command_background="no" +description="Minimal framebuffer login that launches X" + +depend() { + need localmount + after bootmisc +} -- cgit v1.2.3