summaryrefslogtreecommitdiff
path: root/core/slogin/slogin.c
diff options
context:
space:
mode:
Diffstat (limited to 'core/slogin/slogin.c')
-rw-r--r--core/slogin/slogin.c186
1 files changed, 77 insertions, 109 deletions
diff --git a/core/slogin/slogin.c b/core/slogin/slogin.c
index 24a534b..1978d71 100644
--- a/core/slogin/slogin.c
+++ b/core/slogin/slogin.c
@@ -1,8 +1,5 @@
/* See LICENSE file for license details. */
#define _XOPEN_SOURCE 700
-#include <X11/Xlib.h>
-#include <X11/Xft/Xft.h>
-#include <X11/keysym.h>
#include <unistd.h>
#include <pwd.h>
#include <grp.h>
@@ -12,6 +9,8 @@
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
+#include <termios.h>
+#include <sys/wait.h>
#include "../accent.h"
#include "config.h"
@@ -36,6 +35,29 @@ updateaccent(void)
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)
{
@@ -68,126 +90,72 @@ auth(const char *user, const char *pass)
}
static void
-runsession(const char *user, const char *pass)
+readinput(char *buf, size_t len)
{
- struct passwd *pw;
- if (!auth(user, pass))
- return;
- if (!(pw = getpwnam(user)))
- return;
- 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);
- chdir(pw->pw_dir);
- setsid();
- execvp(logincmd[0], (char *const *)logincmd);
- die("slogin: exec failed\n");
+ if (!fgets(buf, len, stdin))
+ buf[0] = '\0';
+ buf[strcspn(buf, "\n")] = '\0';
}
static void
-drawscreen(Display *dpy, Window win, XftDraw *draw, XftFont *font,
- XftColor *fg, XftColor *accent,
- const char *user, const char *pass, int stage)
+readpass(char *buf, size_t len)
{
- char buf[256];
- int width = DisplayWidth(dpy, DefaultScreen(dpy));
- int height = DisplayHeight(dpy, DefaultScreen(dpy));
- int w = 400, h = 100;
- int x = (width - w)/2;
- int y = (height - h)/2;
- GC gc = DefaultGC(dpy, DefaultScreen(dpy));
-
- XClearWindow(dpy, win);
- XSetForeground(dpy, gc, accent->pixel);
- XDrawRectangle(dpy, win, gc, x, y, w, h);
+ 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);
+}
- if (stage == 0)
- snprintf(buf, sizeof buf, "login: %s", user);
- else {
- char stars[sizeof buf];
- size_t i, len = strlen(pass);
- for (i = 0; i < len && i < sizeof stars - 1; i++)
- stars[i] = '*';
- stars[i] = '\0';
- snprintf(buf, sizeof buf, "password: %s", stars);
+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);
}
- XftDrawStringUtf8(draw, fg, font, x + 20, y + h/2 + font->ascent/2,
- (XftChar8 *)buf, strlen(buf));
- XFlush(dpy);
+ waitpid(pid, NULL, 0);
}
int
main(void)
{
- Display *dpy;
- int scr;
- Window root, win;
- XEvent ev;
- XftDraw *xdraw;
- XftFont *font;
- XftColor xfg, xbg, xaccent;
- char user[64] = "", pass[64] = "";
- int stage = 0;
- KeySym ksym;
- char buf[32];
- int len;
-
- updateaccent();
- if (!(dpy = XOpenDisplay(NULL)))
- die("slogin: cannot open display\n");
- scr = DefaultScreen(dpy);
- root = RootWindow(dpy, scr);
- win = XCreateSimpleWindow(dpy, root, 0, 0,
- DisplayWidth(dpy, scr), DisplayHeight(dpy, scr),
- 0, BlackPixel(dpy, scr), BlackPixel(dpy, scr));
- XSelectInput(dpy, win, KeyPressMask | ExposureMask);
- XMapRaised(dpy, win);
-
- font = XftFontOpenName(dpy, scr, fontname);
- if (!font)
- die("slogin: cannot load font\n");
- xdraw = XftDrawCreate(dpy, win, DefaultVisual(dpy, scr), DefaultColormap(dpy, scr));
- XftColorAllocName(dpy, DefaultVisual(dpy, scr), DefaultColormap(dpy, scr), fgcolor, &xfg);
- XftColorAllocName(dpy, DefaultVisual(dpy, scr), DefaultColormap(dpy, scr), bgcolor, &xbg);
- XftColorAllocName(dpy, DefaultVisual(dpy, scr), DefaultColormap(dpy, scr), accentcol, &xaccent);
- XSetWindowBackground(dpy, win, xbg.pixel);
- XClearWindow(dpy, win);
+ char user[64];
+ char pass[64];
for (;;) {
- XNextEvent(dpy, &ev);
- if (ev.type == Expose) {
- drawscreen(dpy, win, xdraw, font, &xfg, &xaccent,
- user, pass, stage);
- } else if (ev.type == KeyPress) {
- len = XLookupString(&ev.xkey, buf, sizeof buf, &ksym, NULL);
- if (ksym == XK_Return) {
- if (stage == 0)
- stage = 1;
- else {
- runsession(user, pass);
- stage = 0;
- user[0] = pass[0] = '\0';
- }
- } else if (ksym == XK_BackSpace) {
- if (stage == 0 && strlen(user) > 0)
- user[strlen(user)-1] = '\0';
- else if (stage == 1 && strlen(pass) > 0)
- pass[strlen(pass)-1] = '\0';
- } else if (len && buf[0] >= ' ' && buf[0] <= '~') {
- if (stage == 0 && strlen(user) + len < sizeof user) {
- strncat(user, buf, len);
- user[strlen(user)] = '\0';
- } else if (stage == 1 && strlen(pass) + len < sizeof pass) {
- strncat(pass, buf, len);
- pass[strlen(pass)] = '\0';
- }
- }
- drawscreen(dpy, win, xdraw, font, &xfg, &xaccent,
- user, pass, stage);
+ 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;
}