slock-pam_auth-20190207-35633d4.diff - sites - public wiki contents of suckless.org
(HTM) git clone git://git.suckless.org/sites
(DIR) Log
(DIR) Files
(DIR) Refs
---
slock-pam_auth-20190207-35633d4.diff (4270B)
---
1 diff --git a/config.def.h b/config.def.h
2 index 9855e21..19e7f62 100644
3 --- a/config.def.h
4 +++ b/config.def.h
5 @@ -6,7 +6,11 @@ static const char *colorname[NUMCOLS] = {
6 [INIT] = "black", /* after initialization */
7 [INPUT] = "#005577", /* during input */
8 [FAILED] = "#CC3333", /* wrong password */
9 + [PAM] = "#9400D3", /* waiting for PAM */
10 };
11
12 /* treat a cleared input like a wrong password (color) */
13 static const int failonclear = 1;
14 +
15 +/* PAM service that's used for authentication */
16 +static const char* pam_service = "login";
17 diff --git a/config.mk b/config.mk
18 index 74429ae..6e82074 100644
19 --- a/config.mk
20 +++ b/config.mk
21 @@ -12,7 +12,7 @@ X11LIB = /usr/X11R6/lib
22
23 # includes and libs
24 INCS = -I. -I/usr/include -I${X11INC}
25 -LIBS = -L/usr/lib -lc -lcrypt -L${X11LIB} -lX11 -lXext -lXrandr
26 +LIBS = -L/usr/lib -lc -lcrypt -L${X11LIB} -lX11 -lXext -lXrandr -lpam
27
28 # flags
29 CPPFLAGS = -DVERSION=\"${VERSION}\" -D_DEFAULT_SOURCE -DHAVE_SHADOW_H
30 diff --git a/slock.c b/slock.c
31 index 5ae738c..3a8da42 100644
32 --- a/slock.c
33 +++ b/slock.c
34 @@ -18,16 +18,22 @@
35 #include <X11/keysym.h>
36 #include <X11/Xlib.h>
37 #include <X11/Xutil.h>
38 +#include <security/pam_appl.h>
39 +#include <security/pam_misc.h>
40
41 #include "arg.h"
42 #include "util.h"
43
44 char *argv0;
45 +static int pam_conv(int num_msg, const struct pam_message **msg, struct pam_response **resp, void *appdata_ptr);
46 +struct pam_conv pamc = {pam_conv, NULL};
47 +char passwd[256];
48
49 enum {
50 INIT,
51 INPUT,
52 FAILED,
53 + PAM,
54 NUMCOLS
55 };
56
57 @@ -57,6 +63,31 @@ die(const char *errstr, ...)
58 exit(1);
59 }
60
61 +static int
62 +pam_conv(int num_msg, const struct pam_message **msg,
63 + struct pam_response **resp, void *appdata_ptr)
64 +{
65 + int retval = PAM_CONV_ERR;
66 + for(int i=0; i<num_msg; i++) {
67 + if (msg[i]->msg_style == PAM_PROMPT_ECHO_OFF &&
68 + strncmp(msg[i]->msg, "Password: ", 10) == 0) {
69 + struct pam_response *resp_msg = malloc(sizeof(struct pam_response));
70 + if (!resp_msg)
71 + die("malloc failed\n");
72 + char *password = malloc(strlen(passwd) + 1);
73 + if (!password)
74 + die("malloc failed\n");
75 + memset(password, 0, strlen(passwd) + 1);
76 + strcpy(password, passwd);
77 + resp_msg->resp_retcode = 0;
78 + resp_msg->resp = password;
79 + resp[i] = resp_msg;
80 + retval = PAM_SUCCESS;
81 + }
82 + }
83 + return retval;
84 +}
85 +
86 #ifdef __linux__
87 #include <fcntl.h>
88 #include <linux/oom.h>
89 @@ -121,6 +152,8 @@ gethash(void)
90 }
91 #endif /* HAVE_SHADOW_H */
92
93 + /* pam, store user name */
94 + hash = pw->pw_name;
95 return hash;
96 }
97
98 @@ -129,11 +162,12 @@ readpw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens,
99 const char *hash)
100 {
101 XRRScreenChangeNotifyEvent *rre;
102 - char buf[32], passwd[256], *inputhash;
103 - int num, screen, running, failure, oldc;
104 + char buf[32];
105 + int num, screen, running, failure, oldc, retval;
106 unsigned int len, color;
107 KeySym ksym;
108 XEvent ev;
109 + pam_handle_t *pamh;
110
111 len = 0;
112 running = 1;
113 @@ -160,10 +194,26 @@ readpw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens,
114 case XK_Return:
115 passwd[len] = '\0';
116 errno = 0;
117 - if (!(inputhash = crypt(passwd, hash)))
118 - fprintf(stderr, "slock: crypt: %s\n", strerror(errno));
119 + retval = pam_start(pam_service, hash, &pamc, &pamh);
120 + color = PAM;
121 + for (screen = 0; screen < nscreens; screen++) {
122 + XSetWindowBackground(dpy, locks[screen]->win, locks[screen]->colors[color]);
123 + XClearWindow(dpy, locks[screen]->win);
124 + XRaiseWindow(dpy, locks[screen]->win);
125 + }
126 + XSync(dpy, False);
127 +
128 + if (retval == PAM_SUCCESS)
129 + retval = pam_authenticate(pamh, 0);
130 + if (retval == PAM_SUCCESS)
131 + retval = pam_acct_mgmt(pamh, 0);
132 +
133 + running = 1;
134 + if (retval == PAM_SUCCESS)
135 + running = 0;
136 else
137 - running = !!strcmp(inputhash, hash);
138 + fprintf(stderr, "slock: %s\n", pam_strerror(pamh, retval));
139 + pam_end(pamh, retval);
140 if (running) {
141 XBell(dpy, 100);
142 failure = 1;
143 @@ -339,10 +389,9 @@ main(int argc, char **argv) {
144 dontkillme();
145 #endif
146
147 + /* the contents of hash are used to transport the current user name */
148 hash = gethash();
149 errno = 0;
150 - if (!crypt("", hash))
151 - die("slock: crypt: %s\n", strerror(errno));
152
153 if (!(dpy = XOpenDisplay(NULL)))
154 die("slock: cannot open display\n");