sites

public wiki contents of suckless.org
git clone git://git.suckless.org/sites
Log | Files | 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");