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");