about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPatryk Niedźwiedziński <pniedzwiedzinski19@gmail.com>2020-12-04 12:46:12 +0100
committerPatryk Niedźwiedziński <pniedzwiedzinski19@gmail.com>2020-12-04 12:46:12 +0100
commit48c708af222cd4120d81565200e046dc3414b3b1 (patch)
tree9d335905f92bea03e9baf747cc653bff216342da
parent3b87be08e7846acd493c95bceb8e13bbea032ffb (diff)
downloaddots-48c708af222cd4120d81565200e046dc3414b3b1.tar.gz
dots-48c708af222cd4120d81565200e046dc3414b3b1.zip
Update slock
-rw-r--r--modules/slock.nix19
-rw-r--r--platforms/linux/configuration.nix6
-rw-r--r--platforms/linux/xorg/config.h2
-rw-r--r--platforms/linux/xorg/slock/slock-capscolor-20170106-2d2a21a.diff86
-rw-r--r--platforms/linux/xorg/slock/slock-dpms-1.4.diff62
-rw-r--r--platforms/linux/xorg/slock/slock-message-20191002-b46028b.diff250
-rw-r--r--platforms/linux/xorg/slock/slock-pam_auth-20190207-35633d4.diff154
7 files changed, 577 insertions, 2 deletions
diff --git a/modules/slock.nix b/modules/slock.nix
new file mode 100644
index 0000000..df6f23c
--- /dev/null
+++ b/modules/slock.nix
@@ -0,0 +1,19 @@
+{ pkgs, ... }:
+
+let
+  slock = pkgs.slock.overrideAttrs(oldAttrs: {
+    buildInputs = oldAttrs.buildInputs ++ [
+      # pkgs.imlib2
+      # pkgs.linux-pam
+      pkgs.xlibs.libXinerama
+    ];
+    patches = [
+      # ../platforms/linux/xorg/slock/slock-pam_auth-20190207-35633d4.diff
+      ../platforms/linux/xorg/slock/slock-capscolor-20170106-2d2a21a.diff
+      ../platforms/linux/xorg/slock/slock-dpms-1.4.diff
+    ];
+  });
+in {
+  environment.systemPackages = [ slock ];
+  security.wrappers.slock.source = "${slock}/bin/slock";
+}
diff --git a/platforms/linux/configuration.nix b/platforms/linux/configuration.nix
index a472bb9..f65f430 100644
--- a/platforms/linux/configuration.nix
+++ b/platforms/linux/configuration.nix
@@ -41,6 +41,7 @@ in
       ../../modules/dockd.nix
       ../../modules/trackpad.nix
       ../../modules/agetty.nix
+      ../../modules/slock.nix
       ../../hardware-configuration.nix
     ];
 
@@ -214,7 +215,6 @@ in
   };
 
   programs.vim.defaultEditor = true;
-  programs.slock.enable = true;
   programs.browserpass.enable = true;
   programs.dockd.enable = true;
   programs.adb.enable = true;
@@ -233,6 +233,7 @@ in
 
   services.agetty = {
     defaultUser = "pn";
+    # autologinUser = "pn";
   };
 
   # Enable the OpenSSH daemon.
@@ -327,6 +328,9 @@ in
   security.pam.u2f = {
     enable = true;
     cue = true;
+    interactive = true;
+    #control = "required";
+    #control = "requisite";
   };
 
 
diff --git a/platforms/linux/xorg/config.h b/platforms/linux/xorg/config.h
index a3287dd..5807cdf 100644
--- a/platforms/linux/xorg/config.h
+++ b/platforms/linux/xorg/config.h
@@ -194,7 +194,7 @@ static Key keys[] = {
 	/* { MODKEY|ShiftMask,		XK_c,		spawn,		SHCMD("") }, */
 	/* V is automatically bound above in STACKKEYS */
 	{ MODKEY,			XK_b,		togglebar,	{0} },
-	/* { MODKEY|ShiftMask,		XK_b,		spawn,		SHCMD("") }, */
+	{ MODKEY|ShiftMask,		XK_b,		spawn,	SHCMD("y2mpv") },
 	{ MODKEY,			XK_n,		spawn,		SHCMD(TERMINAL " -e nvim -c VimwikiIndex") },
 	{ MODKEY|ShiftMask,		XK_n,		spawn,		SHCMD(TERMINAL " -e newsboat; pkill -RTMIN+6 dwmblocks") },
 	{ MODKEY,			XK_m,		spawn,		SHCMD(TERMINAL " -e ncmpcpp") },
diff --git a/platforms/linux/xorg/slock/slock-capscolor-20170106-2d2a21a.diff b/platforms/linux/xorg/slock/slock-capscolor-20170106-2d2a21a.diff
new file mode 100644
index 0000000..82c5543
--- /dev/null
+++ b/platforms/linux/xorg/slock/slock-capscolor-20170106-2d2a21a.diff
@@ -0,0 +1,86 @@
+From 95463f58beb669d9221881deac3b6df7d9c4f162 Mon Sep 17 00:00:00 2001
+From: Klemens Nanni <kl3@posteo.org>
+Date: Fri, 2 Sep 2016 14:53:30 +0200
+Subject: [PATCH] Indicate the state of CapsLock through a different color
+
+---
+ config.def.h |  1 +
+ slock.c      | 15 ++++++++++++---
+ 2 files changed, 13 insertions(+), 3 deletions(-)
+
+diff --git a/config.def.h b/config.def.h
+index 9855e21..6288856 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -6,6 +6,7 @@ static const char *colorname[NUMCOLS] = {
+ 	[INIT] =   "black",     /* after initialization */
+ 	[INPUT] =  "#005577",   /* during input */
+ 	[FAILED] = "#CC3333",   /* wrong password */
++	[CAPS] = "red",         /* CapsLock on */
+ };
+
+ /* treat a cleared input like a wrong password (color) */
+diff --git a/slock.c b/slock.c
+index d55eb3d..d7804f1 100644
+--- a/slock.c
++++ b/slock.c
+@@ -18,6 +18,7 @@
+ #include <X11/keysym.h>
+ #include <X11/Xlib.h>
+ #include <X11/Xutil.h>
++#include <X11/XKBlib.h>
+
+ #include "arg.h"
+ #include "util.h"
+@@ -28,6 +29,7 @@ enum {
+ 	INIT,
+ 	INPUT,
+ 	FAILED,
++	CAPS,
+ 	NUMCOLS
+ };
+
+@@ -130,16 +132,20 @@ readpw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens,
+ {
+ 	XRRScreenChangeNotifyEvent *rre;
+ 	char buf[32], passwd[256], *inputhash;
+-	int num, screen, running, failure, oldc;
+-	unsigned int len, color;
++	int caps, num, screen, running, failure, oldc;
++	unsigned int len, color, indicators;
+ 	KeySym ksym;
+ 	XEvent ev;
+
+ 	len = 0;
++	caps = 0;
+ 	running = 1;
+ 	failure = 0;
+ 	oldc = INIT;
+
++	if (!XkbGetIndicatorState(dpy, XkbUseCoreKbd, &indicators))
++		caps = indicators & 1;
++
+ 	while (running && !XNextEvent(dpy, &ev)) {
+ 		if (ev.type == KeyPress) {
+ 			explicit_bzero(&buf, sizeof(buf));
+@@ -179,6 +185,9 @@ readpw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens,
+ 				if (len)
+ 					passwd[len--] = '\0';
+ 				break;
++			case XK_Caps_Lock:
++				caps = !caps;
++				break;
+ 			default:
+ 				if (num && !iscntrl((int)buf[0]) &&
+ 				    (len + num < sizeof(passwd))) {
+@@ -187,7 +196,7 @@ readpw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens,
+ 				}
+ 				break;
+ 			}
+-			color = len ? INPUT : ((failure || failonclear) ? FAILED : INIT);
++			color = len ? (caps ? CAPS : INPUT) : (failure || failonclear ? FAILED : INIT);
+ 			if (running && oldc != color) {
+ 				for (screen = 0; screen < nscreens; screen++) {
+ 					XSetWindowBackground(dpy,
+--
+2.11.0
diff --git a/platforms/linux/xorg/slock/slock-dpms-1.4.diff b/platforms/linux/xorg/slock/slock-dpms-1.4.diff
new file mode 100644
index 0000000..027bbf7
--- /dev/null
+++ b/platforms/linux/xorg/slock/slock-dpms-1.4.diff
@@ -0,0 +1,62 @@
+diff --git a/config.def.h b/config.def.h
+index 9855e21..d01bd38 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -10,3 +10,6 @@ static const char *colorname[NUMCOLS] = {
+ 
+ /* treat a cleared input like a wrong password (color) */
+ static const int failonclear = 1;
++
++/* time in seconds before the monitor shuts down */
++static const int monitortime = 5;
+diff --git a/slock.c b/slock.c
+index d2f0886..f65a43b 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/dpms.h>
+ #include <X11/keysym.h>
+ #include <X11/Xlib.h>
+ #include <X11/Xutil.h>
+@@ -306,6 +307,7 @@ main(int argc, char **argv) {
+ 	const char *hash;
+ 	Display *dpy;
+ 	int s, nlocks, nscreens;
++	CARD16 standby, suspend, off;
+ 
+ 	ARGBEGIN {
+ 	case 'v':
+@@ -366,6 +368,20 @@ main(int argc, char **argv) {
+ 	if (nlocks != nscreens)
+ 		return 1;
+ 
++	/* DPMS magic to disable the monitor */
++	if (!DPMSCapable(dpy))
++		die("slock: DPMSCapable failed\n");
++	if (!DPMSEnable(dpy))
++		die("slock: DPMSEnable failed\n");
++	if (!DPMSGetTimeouts(dpy, &standby, &suspend, &off))
++		die("slock: DPMSGetTimeouts failed\n");
++	if (!standby || !suspend || !off)
++		die("slock: at least one DPMS variable is zero\n");
++	if (!DPMSSetTimeouts(dpy, monitortime, monitortime, monitortime))
++		die("slock: DPMSSetTimeouts failed\n");
++
++	XSync(dpy, 0);
++
+ 	/* run post-lock command */
+ 	if (argc > 0) {
+ 		switch (fork()) {
+@@ -383,5 +399,9 @@ main(int argc, char **argv) {
+ 	/* everything is now blank. Wait for the correct password */
+ 	readpw(dpy, &rr, locks, nscreens, hash);
+ 
++	/* reset DPMS values to inital ones */
++	DPMSSetTimeouts(dpy, standby, suspend, off);
++	XSync(dpy, 0);
++
+ 	return 0;
+ }
diff --git a/platforms/linux/xorg/slock/slock-message-20191002-b46028b.diff b/platforms/linux/xorg/slock/slock-message-20191002-b46028b.diff
new file mode 100644
index 0000000..61ea1e8
--- /dev/null
+++ b/platforms/linux/xorg/slock/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] = {
+
+ /* time in seconds before the monitor shuts down */
+ static const int monitortime = 5;
++
++/* 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/dpms.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/platforms/linux/xorg/slock/slock-pam_auth-20190207-35633d4.diff b/platforms/linux/xorg/slock/slock-pam_auth-20190207-35633d4.diff
new file mode 100644
index 0000000..34b12af
--- /dev/null
+++ b/platforms/linux/xorg/slock/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 = "u2f";
+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");