From 5214f4e3ea62575ad3f214493436f6aafc0eb7a0 Mon Sep 17 00:00:00 2001 From: Benjamin Chausse Date: Sat, 5 Mar 2022 15:26:44 -0500 Subject: Rewrite with dwmlogo pam xresources --- patch/slock-dwmlogo-20210324.diff | 246 +++++++++++++++++++++++++++ patch/slock-pam_auth-20190207-35633d4.diff | 154 +++++++++++++++++ patch/slock-xresources-20191126-53e56c7.diff | 159 +++++++++++++++++ 3 files changed, 559 insertions(+) create mode 100644 patch/slock-dwmlogo-20210324.diff create mode 100644 patch/slock-pam_auth-20190207-35633d4.diff create mode 100644 patch/slock-xresources-20191126-53e56c7.diff (limited to 'patch') diff --git a/patch/slock-dwmlogo-20210324.diff b/patch/slock-dwmlogo-20210324.diff new file mode 100644 index 0000000..90625ea --- /dev/null +++ b/patch/slock-dwmlogo-20210324.diff @@ -0,0 +1,246 @@ +diff --git a/config.def.h b/config.def.h +index 9855e21..0940fb8 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -3,10 +3,30 @@ static const char *user = "nobody"; + static const char *group = "nogroup"; + + static const char *colorname[NUMCOLS] = { +- [INIT] = "black", /* after initialization */ ++ [BACKGROUND] = "black", /* after initialization */ ++ [INIT] = "#2d2d2d", /* after initialization */ + [INPUT] = "#005577", /* during input */ + [FAILED] = "#CC3333", /* wrong password */ + }; + + /* treat a cleared input like a wrong password (color) */ + static const int failonclear = 1; ++ ++/* insert grid pattern with scale 1:1, the size can be changed with logosize */ ++static const int logosize = 75; ++static const int logow = 12; /* grid width and height for right center alignment*/ ++static const int logoh = 6; ++ ++static XRectangle rectangles[9] = { ++ /* x y w h */ ++ { 0, 3, 1, 3 }, ++ { 1, 3, 2, 1 }, ++ { 0, 5, 8, 1 }, ++ { 3, 0, 1, 5 }, ++ { 5, 3, 1, 2 }, ++ { 7, 3, 1, 2 }, ++ { 8, 3, 4, 1 }, ++ { 9, 4, 1, 2 }, ++ { 11, 4, 1, 2 }, ++ ++}; +diff --git a/config.mk b/config.mk +index 74429ae..08356e8 100644 +--- a/config.mk ++++ b/config.mk +@@ -10,12 +10,20 @@ MANPREFIX = ${PREFIX}/share/man + X11INC = /usr/X11R6/include + X11LIB = /usr/X11R6/lib + ++# Xinerama, comment if you don't want it ++XINERAMALIBS = -lXinerama ++XINERAMAFLAGS = -DXINERAMA ++ ++# freetype ++FREETYPELIBS = -lXft ++FREETYPEINC = /usr/include/freetype2 ++ + # includes and libs +-INCS = -I. -I/usr/include -I${X11INC} +-LIBS = -L/usr/lib -lc -lcrypt -L${X11LIB} -lX11 -lXext -lXrandr ++INCS = -I. -I/usr/include -I${X11INC} -I${FREETYPEINC} ++LIBS = -L/usr/lib -lc -lcrypt -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} -lXext -lXrandr + + # flags +-CPPFLAGS = -DVERSION=\"${VERSION}\" -D_DEFAULT_SOURCE -DHAVE_SHADOW_H ++CPPFLAGS = -DVERSION=\"${VERSION}\" -D_DEFAULT_SOURCE -DHAVE_SHADOW_H ${XINERAMAFLAGS} + CFLAGS = -std=c99 -pedantic -Wall -Os ${INCS} ${CPPFLAGS} + LDFLAGS = -s ${LIBS} + COMPATSRC = explicit_bzero.c +diff --git a/slock.c b/slock.c +index 5ae738c..3ea9b7f 100644 +--- a/slock.c ++++ b/slock.c +@@ -1,5 +1,6 @@ + /* See LICENSE file for license details. */ +-#define _XOPEN_SOURCE 500 ++#define _XOPEN_SOURCE 500 ++#define LENGTH(X) (sizeof X / sizeof X[0]) + #if HAVE_SHADOW_H + #include + #endif +@@ -15,9 +16,13 @@ + #include + #include + #include ++#ifdef XINERAMA ++#include ++#endif + #include + #include + #include ++#include + + #include "arg.h" + #include "util.h" +@@ -25,17 +30,25 @@ + char *argv0; + + enum { ++ BACKGROUND, + INIT, + INPUT, + FAILED, + NUMCOLS + }; + ++#include "config.h" ++ + struct lock { + int screen; + Window root, win; + Pixmap pmap; + unsigned long colors[NUMCOLS]; ++ unsigned int x, y; ++ unsigned int xoff, yoff, mw, mh; ++ Drawable drawable; ++ GC gc; ++ XRectangle rectangles[LENGTH(rectangles)]; + }; + + struct xrandr { +@@ -44,8 +57,6 @@ struct xrandr { + int errbase; + }; + +-#include "config.h" +- + static void + die(const char *errstr, ...) + { +@@ -124,6 +135,32 @@ gethash(void) + return hash; + } + ++static void ++resizerectangles(struct lock *lock) ++{ ++ int i; ++ ++ for (i = 0; i < LENGTH(rectangles); i++){ ++ lock->rectangles[i].x = (rectangles[i].x * logosize) ++ + lock->xoff + ((lock->mw) / 2) - (logow / 2 * logosize); ++ lock->rectangles[i].y = (rectangles[i].y * logosize) ++ + lock->yoff + ((lock->mh) / 2) - (logoh / 2 * logosize); ++ lock->rectangles[i].width = rectangles[i].width * logosize; ++ lock->rectangles[i].height = rectangles[i].height * logosize; ++ } ++} ++ ++static void ++drawlogo(Display *dpy, struct lock *lock, int color) ++{ ++ XSetForeground(dpy, lock->gc, lock->colors[BACKGROUND]); ++ XFillRectangle(dpy, lock->drawable, lock->gc, 0, 0, lock->x, lock->y); ++ XSetForeground(dpy, lock->gc, lock->colors[color]); ++ XFillRectangles(dpy, lock->drawable, lock->gc, lock->rectangles, LENGTH(rectangles)); ++ XCopyArea(dpy, lock->drawable, lock->win, lock->gc, 0, 0, lock->x, lock->y, 0, 0); ++ XSync(dpy, False); ++} ++ + static void + readpw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens, + const char *hash) +@@ -190,10 +227,7 @@ readpw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens, + color = len ? INPUT : ((failure || failonclear) ? FAILED : INIT); + if (running && oldc != color) { + for (screen = 0; screen < nscreens; screen++) { +- XSetWindowBackground(dpy, +- locks[screen]->win, +- locks[screen]->colors[color]); +- XClearWindow(dpy, locks[screen]->win); ++ drawlogo(dpy, locks[screen], color); + } + oldc = color; + } +@@ -228,6 +262,10 @@ lockscreen(Display *dpy, struct xrandr *rr, int screen) + XColor color, dummy; + XSetWindowAttributes wa; + Cursor invisible; ++#ifdef XINERAMA ++ XineramaScreenInfo *info; ++ int n; ++#endif + + if (dpy == NULL || screen < 0 || !(lock = malloc(sizeof(struct lock)))) + return NULL; +@@ -241,12 +279,31 @@ lockscreen(Display *dpy, struct xrandr *rr, int screen) + lock->colors[i] = color.pixel; + } + ++ lock->x = DisplayWidth(dpy, lock->screen); ++ lock->y = DisplayHeight(dpy, lock->screen); ++#ifdef XINERAMA ++ if ((info = XineramaQueryScreens(dpy, &n))) { ++ lock->xoff = info[0].x_org; ++ lock->yoff = info[0].y_org; ++ lock->mw = info[0].width; ++ lock->mh = info[0].height; ++ } else ++#endif ++ { ++ lock->xoff = lock->yoff = 0; ++ lock->mw = lock->x; ++ lock->mh = lock->y; ++ } ++ lock->drawable = XCreatePixmap(dpy, lock->root, ++ lock->x, lock->y, DefaultDepth(dpy, screen)); ++ lock->gc = XCreateGC(dpy, lock->root, 0, NULL); ++ XSetLineAttributes(dpy, lock->gc, 1, LineSolid, CapButt, JoinMiter); ++ + /* init */ + wa.override_redirect = 1; +- wa.background_pixel = lock->colors[INIT]; ++ wa.background_pixel = lock->colors[BACKGROUND]; + lock->win = XCreateWindow(dpy, lock->root, 0, 0, +- DisplayWidth(dpy, lock->screen), +- DisplayHeight(dpy, lock->screen), ++ lock->x, lock->y, + 0, DefaultDepth(dpy, lock->screen), + CopyFromParent, + DefaultVisual(dpy, lock->screen), +@@ -256,6 +313,8 @@ lockscreen(Display *dpy, struct xrandr *rr, int screen) + &color, &color, 0, 0); + XDefineCursor(dpy, lock->win, invisible); + ++ resizerectangles(lock); ++ + /* Try to grab mouse pointer *and* keyboard for 600ms, else fail the lock */ + for (i = 0, ptgrab = kbgrab = -1; i < 6; i++) { + if (ptgrab != GrabSuccess) { +@@ -276,6 +335,7 @@ lockscreen(Display *dpy, struct xrandr *rr, int screen) + XRRSelectInput(dpy, lock->win, RRScreenChangeNotifyMask); + + XSelectInput(dpy, lock->root, SubstructureNotifyMask); ++ drawlogo(dpy, lock, INIT); + return lock; + } + +@@ -391,5 +451,12 @@ main(int argc, char **argv) { + /* everything is now blank. Wait for the correct password */ + readpw(dpy, &rr, locks, nscreens, hash); + ++ for (nlocks = 0, s = 0; s < nscreens; s++) { ++ XFreePixmap(dpy, locks[s]->drawable); ++ XFreeGC(dpy, locks[s]->gc); ++ } ++ ++ XSync(dpy, 0); ++ XCloseDisplay(dpy); + return 0; + } diff --git a/patch/slock-pam_auth-20190207-35633d4.diff b/patch/slock-pam_auth-20190207-35633d4.diff new file mode 100644 index 0000000..136f4b5 --- /dev/null +++ b/patch/slock-pam_auth-20190207-35633d4.diff @@ -0,0 +1,154 @@ +diff --git a/config.def.h b/config.def.h +index 9855e21..19e7f62 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -6,7 +6,11 @@ static const char *colorname[NUMCOLS] = { + [INIT] = "black", /* after initialization */ + [INPUT] = "#005577", /* during input */ + [FAILED] = "#CC3333", /* wrong password */ ++ [PAM] = "#9400D3", /* waiting for PAM */ + }; + + /* treat a cleared input like a wrong password (color) */ + static const int failonclear = 1; ++ ++/* PAM service that's used for authentication */ ++static const char* pam_service = "login"; +diff --git a/config.mk b/config.mk +index 74429ae..6e82074 100644 +--- a/config.mk ++++ b/config.mk +@@ -12,7 +12,7 @@ X11LIB = /usr/X11R6/lib + + # includes and libs + INCS = -I. -I/usr/include -I${X11INC} +-LIBS = -L/usr/lib -lc -lcrypt -L${X11LIB} -lX11 -lXext -lXrandr ++LIBS = -L/usr/lib -lc -lcrypt -L${X11LIB} -lX11 -lXext -lXrandr -lpam + + # flags + CPPFLAGS = -DVERSION=\"${VERSION}\" -D_DEFAULT_SOURCE -DHAVE_SHADOW_H +diff --git a/slock.c b/slock.c +index 5ae738c..3a8da42 100644 +--- a/slock.c ++++ b/slock.c +@@ -18,16 +18,22 @@ + #include + #include + #include ++#include ++#include + + #include "arg.h" + #include "util.h" + + char *argv0; ++static int pam_conv(int num_msg, const struct pam_message **msg, struct pam_response **resp, void *appdata_ptr); ++struct pam_conv pamc = {pam_conv, NULL}; ++char passwd[256]; + + enum { + INIT, + INPUT, + FAILED, ++ PAM, + NUMCOLS + }; + +@@ -57,6 +63,31 @@ die(const char *errstr, ...) + exit(1); + } + ++static int ++pam_conv(int num_msg, const struct pam_message **msg, ++ struct pam_response **resp, void *appdata_ptr) ++{ ++ int retval = PAM_CONV_ERR; ++ for(int i=0; imsg_style == PAM_PROMPT_ECHO_OFF && ++ strncmp(msg[i]->msg, "Password: ", 10) == 0) { ++ struct pam_response *resp_msg = malloc(sizeof(struct pam_response)); ++ if (!resp_msg) ++ die("malloc failed\n"); ++ char *password = malloc(strlen(passwd) + 1); ++ if (!password) ++ die("malloc failed\n"); ++ memset(password, 0, strlen(passwd) + 1); ++ strcpy(password, passwd); ++ resp_msg->resp_retcode = 0; ++ resp_msg->resp = password; ++ resp[i] = resp_msg; ++ retval = PAM_SUCCESS; ++ } ++ } ++ return retval; ++} ++ + #ifdef __linux__ + #include + #include +@@ -121,6 +152,8 @@ gethash(void) + } + #endif /* HAVE_SHADOW_H */ + ++ /* pam, store user name */ ++ hash = pw->pw_name; + return hash; + } + +@@ -129,11 +162,12 @@ readpw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens, + const char *hash) + { + XRRScreenChangeNotifyEvent *rre; +- char buf[32], passwd[256], *inputhash; +- int num, screen, running, failure, oldc; ++ char buf[32]; ++ int num, screen, running, failure, oldc, retval; + unsigned int len, color; + KeySym ksym; + XEvent ev; ++ pam_handle_t *pamh; + + len = 0; + running = 1; +@@ -160,10 +194,26 @@ readpw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens, + case XK_Return: + passwd[len] = '\0'; + errno = 0; +- if (!(inputhash = crypt(passwd, hash))) +- fprintf(stderr, "slock: crypt: %s\n", strerror(errno)); ++ retval = pam_start(pam_service, hash, &pamc, &pamh); ++ color = PAM; ++ for (screen = 0; screen < nscreens; screen++) { ++ XSetWindowBackground(dpy, locks[screen]->win, locks[screen]->colors[color]); ++ XClearWindow(dpy, locks[screen]->win); ++ XRaiseWindow(dpy, locks[screen]->win); ++ } ++ XSync(dpy, False); ++ ++ if (retval == PAM_SUCCESS) ++ retval = pam_authenticate(pamh, 0); ++ if (retval == PAM_SUCCESS) ++ retval = pam_acct_mgmt(pamh, 0); ++ ++ running = 1; ++ if (retval == PAM_SUCCESS) ++ running = 0; + else +- running = !!strcmp(inputhash, hash); ++ fprintf(stderr, "slock: %s\n", pam_strerror(pamh, retval)); ++ pam_end(pamh, retval); + if (running) { + XBell(dpy, 100); + failure = 1; +@@ -339,10 +389,9 @@ main(int argc, char **argv) { + dontkillme(); + #endif + ++ /* the contents of hash are used to transport the current user name */ + hash = gethash(); + errno = 0; +- if (!crypt("", hash)) +- die("slock: crypt: %s\n", strerror(errno)); + + if (!(dpy = XOpenDisplay(NULL))) + die("slock: cannot open display\n"); diff --git a/patch/slock-xresources-20191126-53e56c7.diff b/patch/slock-xresources-20191126-53e56c7.diff new file mode 100644 index 0000000..524e338 --- /dev/null +++ b/patch/slock-xresources-20191126-53e56c7.diff @@ -0,0 +1,159 @@ +From 53e56c751b3f2be4154760788850c51dbffc0add Mon Sep 17 00:00:00 2001 +From: Arnas Udovicius +Date: Tue, 26 Nov 2019 16:16:15 +0200 +Subject: [PATCH] Read colors from Xresources + +--- + config.def.h | 14 +++++++++-- + slock.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++ + util.h | 3 +++ + 3 files changed, 83 insertions(+), 2 deletions(-) + +diff --git a/config.def.h b/config.def.h +index 6288856..bfc1ba0 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -3,11 +3,21 @@ static const char *user = "nobody"; + static const char *group = "nogroup"; + + static const char *colorname[NUMCOLS] = { +- [INIT] = "black", /* after initialization */ +- [INPUT] = "#005577", /* during input */ ++ [INIT] = "black", /* after initialization */ ++ [INPUT] = "#005577", /* during input */ + [FAILED] = "#CC3333", /* wrong password */ + [CAPS] = "red", /* CapsLock on */ + }; + ++/* ++ * Xresources preferences to load at startup ++ */ ++ResourcePref resources[] = { ++ { "color0", STRING, &colorname[INIT] }, ++ { "color4", STRING, &colorname[INPUT] }, ++ { "color1", STRING, &colorname[FAILED] }, ++ { "color3", STRING, &colorname[CAPS] }, ++}; ++ + /* treat a cleared input like a wrong password (color) */ + static const int failonclear = 1; +diff --git a/slock.c b/slock.c +index 5f4fb7a..2395547 100644 +--- a/slock.c ++++ b/slock.c +@@ -6,6 +6,7 @@ + + #include + #include ++#include + #include + #include + #include +@@ -19,6 +20,7 @@ + #include + #include + #include ++#include + + #include "arg.h" + #include "util.h" +@@ -46,6 +48,19 @@ struct xrandr { + int errbase; + }; + ++/* Xresources preferences */ ++enum resource_type { ++ STRING = 0, ++ INTEGER = 1, ++ FLOAT = 2 ++}; ++ ++typedef struct { ++ char *name; ++ enum resource_type type; ++ void *dst; ++} ResourcePref; ++ + #include "config.h" + + static void +@@ -306,6 +321,57 @@ lockscreen(Display *dpy, struct xrandr *rr, int screen) + return NULL; + } + ++int ++resource_load(XrmDatabase db, char *name, enum resource_type rtype, void *dst) ++{ ++ char **sdst = dst; ++ int *idst = dst; ++ float *fdst = dst; ++ ++ char fullname[256]; ++ char fullclass[256]; ++ char *type; ++ XrmValue ret; ++ ++ snprintf(fullname, sizeof(fullname), "%s.%s", "slock", name); ++ snprintf(fullclass, sizeof(fullclass), "%s.%s", "Slock", name); ++ fullname[sizeof(fullname) - 1] = fullclass[sizeof(fullclass) - 1] = '\0'; ++ ++ XrmGetResource(db, fullname, fullclass, &type, &ret); ++ if (ret.addr == NULL || strncmp("String", type, 64)) ++ return 1; ++ ++ switch (rtype) { ++ case STRING: ++ *sdst = ret.addr; ++ break; ++ case INTEGER: ++ *idst = strtoul(ret.addr, NULL, 10); ++ break; ++ case FLOAT: ++ *fdst = strtof(ret.addr, NULL); ++ break; ++ } ++ return 0; ++} ++ ++void ++config_init(Display *dpy) ++{ ++ char *resm; ++ XrmDatabase db; ++ ResourcePref *p; ++ ++ XrmInitialize(); ++ resm = XResourceManagerString(dpy); ++ if (!resm) ++ return; ++ ++ db = XrmGetStringDatabase(resm); ++ for (p = resources; p < resources + LEN(resources); p++) ++ resource_load(db, p->name, p->type, p->dst); ++} ++ + static void + usage(void) + { +@@ -364,6 +430,8 @@ main(int argc, char **argv) { + if (setuid(duid) < 0) + die("slock: setuid: %s\n", strerror(errno)); + ++ config_init(dpy); ++ + /* check for Xrandr support */ + rr.active = XRRQueryExtension(dpy, &rr.evbase, &rr.errbase); + +diff --git a/util.h b/util.h +index 6f748b8..148dbc1 100644 +--- a/util.h ++++ b/util.h +@@ -1,2 +1,5 @@ ++/* macros */ ++#define LEN(a) (sizeof(a) / sizeof(a)[0]) ++ + #undef explicit_bzero + void explicit_bzero(void *, size_t); +-- +2.24.0 + -- cgit v1.2.3