slock

My slock fork
git clone https://git.kausban.com/slock/raw/.git
Log | Files | Refs | README

commit 1fa79b109665606fc9c3a1600a8925c56c95295a
Author: kausban <mail@kausban.com>
Date:   Sun, 15 Dec 2019 02:56:29 +0100

initial commit.

Diffstat:
APKGBUILD | 40++++++++++++++++++++++++++++++++++++++++
AREADME.md | 14++++++++++++++
Aconfig.h | 27+++++++++++++++++++++++++++
Aslock-message-20191002-b46028b.diff | 250+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aslock-message-20191215-post_pam.diff | 231+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aslock-pam_auth-20190207-35633d4.diff | 154+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
6 files changed, 716 insertions(+), 0 deletions(-)

diff --git a/PKGBUILD b/PKGBUILD @@ -0,0 +1,40 @@ +# Maintainer: Sergej Pupykin <pupykin.s+arch@gmail.com> +# Contributor: Sebastian A. Liem <sebastian at liem dot se> + +pkgname=slock +pkgver=1.4 +pkgrel=3 +pkgdesc="A simple screen locker for X" +arch=('x86_64') +url="https://tools.suckless.org/slock" +license=('MIT') +depends=('libxext' 'libxrandr') +source=("https://dl.suckless.org/tools/$pkgname-$pkgver.tar.gz" + slock-pam_auth-20190207-35633d4.diff + slock-message-20191215-post_pam.diff + config.h) +#source=("slock-$pkgver.tar.bz2::https://hg.suckless.org/slock/archive/$_pkgver.tar.gz") +md5sums=('f91dd5ba50ce7bd1842caeca067086a3' + 'eddc691152663c3f623ad63649b93bc2' + '030f0ba0039750b67460f0b4b0ad147b' + 'f282e1e40e71a2e0fb0c6731c012695b') + +prepare() { + cd "$srcdir/slock-$pkgver" + cp $srcdir/config.h config.h + sed -i 's|static const char \*group = "nogroup";|static const char *group = "nobody";|' config.def.h + sed -ri 's/((CPP|C|LD)FLAGS) =/\1 +=/g' config.mk + patch -p1 -i "${srcdir}/slock-pam_auth-20190207-35633d4.diff" + patch -p1 -i "${srcdir}/slock-message-20191215-post_pam.diff" +} + +build() { + cd "$srcdir/slock-$pkgver" + make X11INC=/usr/include/X11 X11LIB=/usr/lib/X11 +} + +package() { + cd "$srcdir/slock-$pkgver" + make PREFIX=/usr DESTDIR="$pkgdir" install + install -m644 -D LICENSE "$pkgdir/usr/share/licenses/$pkgname/LICENSE" +} diff --git a/README.md b/README.md @@ -0,0 +1,14 @@ +# Personal slock build +includes patches for: +1. pam - https://tools.suckless.org/slock/patches/pam_auth/ +2. messages - https://tools.suckless.org/slock/patches/pam_auth/ + +# pam hints +set user and group in config.h to something that can use pam ($USER or root) + +for fingerprint add: "auth sufficient pam_fprintd.so" to /etc/pam.d/system-local-login + +The following is nice in sudo. Allows to use password or fingerprint + auth required pam_env.so + auth sufficient pam_unix.so try_first_pass likeauth nullok + auth sufficient pam_fprintd.so diff --git a/config.h b/config.h @@ -0,0 +1,27 @@ + +/* user and group to drop privileges to */ +static const char *user = "lamdacore"; +static const char *group = "lamdacore"; + +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"; + +/* default message */ +static const char * message = "Suckless: Software that sucks less."; + +/* text color */ +static const char * text_color = "#ffffff"; + +/* text size (must be a valid size) */ +static const char * font_name = "fixed"; + diff --git a/slock-message-20191002-b46028b.diff b/slock-message-20191002-b46028b.diff @@ -0,0 +1,250 @@ +From b46028b2797b886154258dcafe71c349cdc68b43 Mon Sep 17 00:00:00 2001 +From: Blair Drummond <blair.robert.drummond@gmail.com> +Date: Wed, 2 Oct 2019 14:59:00 -0400 +Subject: [PATCH] Add a message command. Fixes old version's bugs. + +--- + config.def.h | 9 ++++ + config.mk | 2 +- + slock.1 | 7 +++ + slock.c | 120 +++++++++++++++++++++++++++++++++++++++++++++++++-- + 4 files changed, 133 insertions(+), 5 deletions(-) + +diff --git a/config.def.h b/config.def.h +index 9855e21..c2a0ab2 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -10,3 +10,12 @@ static const char *colorname[NUMCOLS] = { + + /* treat a cleared input like a wrong password (color) */ + static const int failonclear = 1; ++ ++/* default message */ ++static const char * message = "Suckless: Software that sucks less."; ++ ++/* text color */ ++static const char * text_color = "#ffffff"; ++ ++/* text size (must be a valid size) */ ++static const char * font_name = "6x10"; +diff --git a/config.mk b/config.mk +index 74429ae..c4ccf66 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 -lXinerama + + # flags + CPPFLAGS = -DVERSION=\"${VERSION}\" -D_DEFAULT_SOURCE -DHAVE_SHADOW_H +diff --git a/slock.1 b/slock.1 +index 82cdcd6..946165f 100644 +--- a/slock.1 ++++ b/slock.1 +@@ -6,6 +6,8 @@ + .Sh SYNOPSIS + .Nm + .Op Fl v ++.Op Fl f ++.Op Fl m Ar message + .Op Ar cmd Op Ar arg ... + .Sh DESCRIPTION + .Nm +@@ -16,6 +18,11 @@ is executed after the screen has been locked. + .Bl -tag -width Ds + .It Fl v + Print version information to stdout and exit. ++.It Fl f ++List all valid X fonts and exit. ++.It Fl m Ar message ++Overrides default slock lock message. ++.TP + .El + .Sh SECURITY CONSIDERATIONS + To make sure a locked screen can not be bypassed by switching VTs +diff --git a/slock.c b/slock.c +index 5ae738c..610929b 100644 +--- a/slock.c ++++ b/slock.c +@@ -15,6 +15,7 @@ + #include <unistd.h> + #include <sys/types.h> + #include <X11/extensions/Xrandr.h> ++#include <X11/extensions/Xinerama.h> + #include <X11/keysym.h> + #include <X11/Xlib.h> + #include <X11/Xutil.h> +@@ -24,6 +25,9 @@ + + char *argv0; + ++/* global count to prevent repeated error messages */ ++int count_error = 0; ++ + enum { + INIT, + INPUT, +@@ -83,6 +87,98 @@ dontkillme(void) + } + #endif + ++static void ++writemessage(Display *dpy, Window win, int screen) ++{ ++ int len, line_len, width, height, s_width, s_height, i, j, k, tab_replace, tab_size; ++ XGCValues gr_values; ++ XFontStruct *fontinfo; ++ XColor color, dummy; ++ XineramaScreenInfo *xsi; ++ GC gc; ++ fontinfo = XLoadQueryFont(dpy, font_name); ++ ++ if (fontinfo == NULL) { ++ if (count_error == 0) { ++ fprintf(stderr, "slock: Unable to load font \"%s\"\n", font_name); ++ fprintf(stderr, "slock: Try listing fonts with 'slock -f'\n"); ++ count_error++; ++ } ++ return; ++ } ++ ++ tab_size = 8 * XTextWidth(fontinfo, " ", 1); ++ ++ XAllocNamedColor(dpy, DefaultColormap(dpy, screen), ++ text_color, &color, &dummy); ++ ++ gr_values.font = fontinfo->fid; ++ gr_values.foreground = color.pixel; ++ gc=XCreateGC(dpy,win,GCFont+GCForeground, &gr_values); ++ ++ /* To prevent "Uninitialized" warnings. */ ++ xsi = NULL; ++ ++ /* ++ * Start formatting and drawing text ++ */ ++ ++ len = strlen(message); ++ ++ /* Max max line length (cut at '\n') */ ++ line_len = 0; ++ k = 0; ++ for (i = j = 0; i < len; i++) { ++ if (message[i] == '\n') { ++ if (i - j > line_len) ++ line_len = i - j; ++ k++; ++ i++; ++ j = i; ++ } ++ } ++ /* If there is only one line */ ++ if (line_len == 0) ++ line_len = len; ++ ++ if (XineramaIsActive(dpy)) { ++ xsi = XineramaQueryScreens(dpy, &i); ++ s_width = xsi[0].width; ++ s_height = xsi[0].height; ++ } else { ++ s_width = DisplayWidth(dpy, screen); ++ s_height = DisplayHeight(dpy, screen); ++ } ++ ++ height = s_height*3/7 - (k*20)/3; ++ width = (s_width - XTextWidth(fontinfo, message, line_len))/2; ++ ++ /* Look for '\n' and print the text between them. */ ++ for (i = j = k = 0; i <= len; i++) { ++ /* i == len is the special case for the last line */ ++ if (i == len || message[i] == '\n') { ++ tab_replace = 0; ++ while (message[j] == '\t' && j < i) { ++ tab_replace++; ++ j++; ++ } ++ ++ XDrawString(dpy, win, gc, width + tab_size*tab_replace, height + 20*k, message + j, i - j); ++ while (i < len && message[i] == '\n') { ++ i++; ++ j = i; ++ k++; ++ } ++ } ++ } ++ ++ /* xsi should not be NULL anyway if Xinerama is active, but to be safe */ ++ if (XineramaIsActive(dpy) && xsi != NULL) ++ XFree(xsi); ++} ++ ++ ++ + static const char * + gethash(void) + { +@@ -194,6 +290,7 @@ readpw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens, + locks[screen]->win, + locks[screen]->colors[color]); + XClearWindow(dpy, locks[screen]->win); ++ writemessage(dpy, locks[screen]->win, screen); + } + oldc = color; + } +@@ -300,7 +397,7 @@ lockscreen(Display *dpy, struct xrandr *rr, int screen) + static void + usage(void) + { +- die("usage: slock [-v] [cmd [arg ...]]\n"); ++ die("usage: slock [-v] [-f] [-m message] [cmd [arg ...]]\n"); + } + + int +@@ -313,12 +410,25 @@ main(int argc, char **argv) { + gid_t dgid; + const char *hash; + Display *dpy; +- int s, nlocks, nscreens; ++ int i, s, nlocks, nscreens; ++ int count_fonts; ++ char **font_names; + + ARGBEGIN { + case 'v': + fprintf(stderr, "slock-"VERSION"\n"); + return 0; ++ case 'm': ++ message = EARGF(usage()); ++ break; ++ case 'f': ++ if (!(dpy = XOpenDisplay(NULL))) ++ die("slock: cannot open display\n"); ++ font_names = XListFonts(dpy, "*", 10000 /* list 10000 fonts*/, &count_fonts); ++ for (i=0; i<count_fonts; i++) { ++ fprintf(stderr, "%s\n", *(font_names+i)); ++ } ++ return 0; + default: + usage(); + } ARGEND +@@ -363,10 +473,12 @@ main(int argc, char **argv) { + if (!(locks = calloc(nscreens, sizeof(struct lock *)))) + die("slock: out of memory\n"); + for (nlocks = 0, s = 0; s < nscreens; s++) { +- if ((locks[s] = lockscreen(dpy, &rr, s)) != NULL) ++ if ((locks[s] = lockscreen(dpy, &rr, s)) != NULL) { ++ writemessage(dpy, locks[s]->win, s); + nlocks++; +- else ++ } else { + break; ++ } + } + XSync(dpy, 0); + +-- +2.20.1 + diff --git a/slock-message-20191215-post_pam.diff b/slock-message-20191215-post_pam.diff @@ -0,0 +1,231 @@ +diff --unified --recursive --text --color a/config.def.h b/config.def.h +--- a/config.def.h 2019-12-15 02:32:55.802402599 +0100 ++++ b/config.def.h 2019-12-15 02:34:38.442408519 +0100 +@@ -14,3 +14,12 @@ + + /* PAM service that's used for authentication */ + static const char* pam_service = "login"; ++ ++/* default message */ ++static const char * message = "Suckless: Software that sucks less."; ++ ++/* text color */ ++static const char * text_color = "#ffffff"; ++ ++/* text size (must be a valid size) */ ++static const char * font_name = "6x10"; +diff --unified --recursive --text --color a/config.mk b/config.mk +--- a/config.mk 2019-12-15 02:32:55.802402599 +0100 ++++ b/config.mk 2019-12-15 02:34:48.715742442 +0100 +@@ -12,7 +12,7 @@ + + # includes and libs + INCS = -I. -I/usr/include -I${X11INC} +-LIBS = -L/usr/lib -lc -lcrypt -L${X11LIB} -lX11 -lXext -lXrandr -lpam ++LIBS = -L/usr/lib -lc -lcrypt -L${X11LIB} -lX11 -lXext -lXrandr -lpam -lXinerama + + # flags + CPPFLAGS += -DVERSION=\"${VERSION}\" -D_DEFAULT_SOURCE -DHAVE_SHADOW_H +diff --unified --recursive --text --color a/slock.1 b/slock.1 +--- a/slock.1 2016-11-20 01:31:23.000000000 +0100 ++++ b/slock.1 2019-12-15 02:34:07.839073423 +0100 +@@ -6,6 +6,8 @@ + .Sh SYNOPSIS + .Nm + .Op Fl v ++.Op Fl f ++.Op Fl m Ar message + .Op Ar cmd Op Ar arg ... + .Sh DESCRIPTION + .Nm +@@ -16,6 +18,11 @@ + .Bl -tag -width Ds + .It Fl v + Print version information to stdout and exit. ++.It Fl f ++List all valid X fonts and exit. ++.It Fl m Ar message ++Overrides default slock lock message. ++.TP + .El + .Sh SECURITY CONSIDERATIONS + To make sure a locked screen can not be bypassed by switching VTs +diff --unified --recursive --text --color a/slock.c b/slock.c +--- a/slock.c 2019-12-15 02:32:55.802402599 +0100 ++++ b/slock.c 2019-12-15 02:34:07.839073423 +0100 +@@ -15,6 +15,7 @@ + #include <unistd.h> + #include <sys/types.h> + #include <X11/extensions/Xrandr.h> ++#include <X11/extensions/Xinerama.h> + #include <X11/keysym.h> + #include <X11/Xlib.h> + #include <X11/Xutil.h> +@@ -29,6 +30,9 @@ + struct pam_conv pamc = {pam_conv, NULL}; + char passwd[256]; + ++/* global count to prevent repeated error messages */ ++int count_error = 0; ++ + enum { + INIT, + INPUT, +@@ -114,6 +118,98 @@ + } + #endif + ++static void ++writemessage(Display *dpy, Window win, int screen) ++{ ++ int len, line_len, width, height, s_width, s_height, i, j, k, tab_replace, tab_size; ++ XGCValues gr_values; ++ XFontStruct *fontinfo; ++ XColor color, dummy; ++ XineramaScreenInfo *xsi; ++ GC gc; ++ fontinfo = XLoadQueryFont(dpy, font_name); ++ ++ if (fontinfo == NULL) { ++ if (count_error == 0) { ++ fprintf(stderr, "slock: Unable to load font \"%s\"\n", font_name); ++ fprintf(stderr, "slock: Try listing fonts with 'slock -f'\n"); ++ count_error++; ++ } ++ return; ++ } ++ ++ tab_size = 8 * XTextWidth(fontinfo, " ", 1); ++ ++ XAllocNamedColor(dpy, DefaultColormap(dpy, screen), ++ text_color, &color, &dummy); ++ ++ gr_values.font = fontinfo->fid; ++ gr_values.foreground = color.pixel; ++ gc=XCreateGC(dpy,win,GCFont+GCForeground, &gr_values); ++ ++ /* To prevent "Uninitialized" warnings. */ ++ xsi = NULL; ++ ++ /* ++ * Start formatting and drawing text ++ */ ++ ++ len = strlen(message); ++ ++ /* Max max line length (cut at '\n') */ ++ line_len = 0; ++ k = 0; ++ for (i = j = 0; i < len; i++) { ++ if (message[i] == '\n') { ++ if (i - j > line_len) ++ line_len = i - j; ++ k++; ++ i++; ++ j = i; ++ } ++ } ++ /* If there is only one line */ ++ if (line_len == 0) ++ line_len = len; ++ ++ if (XineramaIsActive(dpy)) { ++ xsi = XineramaQueryScreens(dpy, &i); ++ s_width = xsi[0].width; ++ s_height = xsi[0].height; ++ } else { ++ s_width = DisplayWidth(dpy, screen); ++ s_height = DisplayHeight(dpy, screen); ++ } ++ ++ height = s_height*3/7 - (k*20)/3; ++ width = (s_width - XTextWidth(fontinfo, message, line_len))/2; ++ ++ /* Look for '\n' and print the text between them. */ ++ for (i = j = k = 0; i <= len; i++) { ++ /* i == len is the special case for the last line */ ++ if (i == len || message[i] == '\n') { ++ tab_replace = 0; ++ while (message[j] == '\t' && j < i) { ++ tab_replace++; ++ j++; ++ } ++ ++ XDrawString(dpy, win, gc, width + tab_size*tab_replace, height + 20*k, message + j, i - j); ++ while (i < len && message[i] == '\n') { ++ i++; ++ j = i; ++ k++; ++ } ++ } ++ } ++ ++ /* xsi should not be NULL anyway if Xinerama is active, but to be safe */ ++ if (XineramaIsActive(dpy) && xsi != NULL) ++ XFree(xsi); ++} ++ ++ ++ + static const char * + gethash(void) + { +@@ -244,6 +340,7 @@ + locks[screen]->win, + locks[screen]->colors[color]); + XClearWindow(dpy, locks[screen]->win); ++ writemessage(dpy, locks[screen]->win, screen); + } + oldc = color; + } +@@ -342,7 +439,7 @@ + static void + usage(void) + { +- die("usage: slock [-v] [cmd [arg ...]]\n"); ++ die("usage: slock [-v] [-f] [-m message] [cmd [arg ...]]\n"); + } + + int +@@ -355,12 +452,25 @@ + gid_t dgid; + const char *hash; + Display *dpy; +- int s, nlocks, nscreens; ++ int i, s, nlocks, nscreens; ++ int count_fonts; ++ char **font_names; + + ARGBEGIN { + case 'v': + fprintf(stderr, "slock-"VERSION"\n"); + return 0; ++ case 'm': ++ message = EARGF(usage()); ++ break; ++ case 'f': ++ if (!(dpy = XOpenDisplay(NULL))) ++ die("slock: cannot open display\n"); ++ font_names = XListFonts(dpy, "*", 10000 /* list 10000 fonts*/, &count_fonts); ++ for (i=0; i<count_fonts; i++) { ++ fprintf(stderr, "%s\n", *(font_names+i)); ++ } ++ return 0; + default: + usage(); + } ARGEND +@@ -404,10 +514,12 @@ + if (!(locks = calloc(nscreens, sizeof(struct lock *)))) + die("slock: out of memory\n"); + for (nlocks = 0, s = 0; s < nscreens; s++) { +- if ((locks[s] = lockscreen(dpy, &rr, s)) != NULL) ++ if ((locks[s] = lockscreen(dpy, &rr, s)) != NULL) { ++ writemessage(dpy, locks[s]->win, s); + nlocks++; +- else ++ } else { + break; ++ } + } + XSync(dpy, 0); + diff --git a/slock-pam_auth-20190207-35633d4.diff b/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 <X11/keysym.h> + #include <X11/Xlib.h> + #include <X11/Xutil.h> ++#include <security/pam_appl.h> ++#include <security/pam_misc.h> + + #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; i<num_msg; i++) { ++ if (msg[i]->msg_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 <fcntl.h> + #include <linux/oom.h> +@@ -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");