|  |  | @ -25,16 +25,19 @@ | 
			
		
	
		
			
				
					|  |  |  | +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 | 
			
		
	
		
			
				
					|  |  |  | +DEALINGS IN THE SOFTWARE.
 | 
			
		
	
		
			
				
					|  |  |  | +++ Makefile
 | 
			
		
	
		
			
				
					|  |  |  | @@ -14,7 +14,7 @@
 | 
			
		
	
		
			
				
					|  |  |  |  CPPFLAGS += -D_GNU_SOURCE | 
			
		
	
		
			
				
					|  |  |  |  CFLAGS += $(shell $(PKG_CONFIG) --cflags cairo xcb-dpms xcb-xinerama xcb-atom xcb-image xcb-xkb xkbcommon xkbcommon-x11) | 
			
		
	
		
			
				
					|  |  |  |  LIBS += $(shell $(PKG_CONFIG) --libs cairo xcb-dpms xcb-xinerama xcb-atom xcb-image xcb-xkb xkbcommon xkbcommon-x11) | 
			
		
	
		
			
				
					|  |  |  | -LIBS += -lpam
 | 
			
		
	
		
			
				
					|  |  |  | +LIBS += -lcrypt
 | 
			
		
	
		
			
				
					|  |  |  | @@ -20,9 +20,9 @@
 | 
			
		
	
		
			
				
					|  |  |  |  LIBS += -lev | 
			
		
	
		
			
				
					|  |  |  |  LIBS += -lm | 
			
		
	
		
			
				
					|  |  |  |   | 
			
		
	
		
			
				
					|  |  |  | @@ -37,9 +37,7 @@
 | 
			
		
	
		
			
				
					|  |  |  | -# OpenBSD lacks PAM, use bsd_auth(3) instead.
 | 
			
		
	
		
			
				
					|  |  |  | +# On OpenBSD we use bsd_auth(3) instead.
 | 
			
		
	
		
			
				
					|  |  |  |  ifneq ($(UNAME),OpenBSD) | 
			
		
	
		
			
				
					|  |  |  | -  LIBS += -lpam
 | 
			
		
	
		
			
				
					|  |  |  | +  LIBS += -lcrypt
 | 
			
		
	
		
			
				
					|  |  |  |  endif | 
			
		
	
		
			
				
					|  |  |  |   | 
			
		
	
		
			
				
					|  |  |  |  FILES:=$(wildcard *.c) | 
			
		
	
		
			
				
					|  |  |  | @@ -50,9 +50,7 @@
 | 
			
		
	
		
			
				
					|  |  |  |   | 
			
		
	
		
			
				
					|  |  |  |  install: all | 
			
		
	
		
			
				
					|  |  |  |  	$(INSTALL) -d $(DESTDIR)$(PREFIX)/bin | 
			
		
	
	
		
			
				
					|  |  | @ -44,8 +47,17 @@ | 
			
		
	
		
			
				
					|  |  |  |   | 
			
		
	
		
			
				
					|  |  |  |  uninstall: | 
			
		
	
		
			
				
					|  |  |  |  	rm -f $(DESTDIR)$(PREFIX)/bin/i3lock | 
			
		
	
		
			
				
					|  |  |  | @@ -61,7 +59,7 @@
 | 
			
		
	
		
			
				
					|  |  |  |  	[ ! -d i3lock-${VERSION} ] || rm -rf i3lock-${VERSION} | 
			
		
	
		
			
				
					|  |  |  |  	[ ! -e i3lock-${VERSION}.tar.bz2 ] || rm i3lock-${VERSION}.tar.bz2 | 
			
		
	
		
			
				
					|  |  |  |  	mkdir i3lock-${VERSION} | 
			
		
	
		
			
				
					|  |  |  | -	cp *.c *.h i3lock.1 i3lock.pam Makefile LICENSE README.md CHANGELOG i3lock-${VERSION}
 | 
			
		
	
		
			
				
					|  |  |  | +	cp *.c *.h i3lock.1 Makefile LICENSE README.md CHANGELOG i3lock-${VERSION}
 | 
			
		
	
		
			
				
					|  |  |  |  	sed -e 's/^I3LOCK_VERSION:=\(.*\)/I3LOCK_VERSION:=$(shell /bin/echo '${I3LOCK_VERSION}' | sed 's/\\/\\\\/g')/g;s/^VERSION:=\(.*\)/VERSION:=${VERSION}/g' Makefile > i3lock-${VERSION}/Makefile | 
			
		
	
		
			
				
					|  |  |  |  	tar cfj i3lock-${VERSION}.tar.bz2 i3lock-${VERSION} | 
			
		
	
		
			
				
					|  |  |  |  	rm -rf i3lock-${VERSION} | 
			
		
	
		
			
				
					|  |  |  | +++ i3lock.1
 | 
			
		
	
		
			
				
					|  |  |  | @@ -45,8 +45,6 @@
 | 
			
		
	
		
			
				
					|  |  |  | @@ -43,8 +43,6 @@
 | 
			
		
	
		
			
				
					|  |  |  |  You can specify either a background color or a PNG image which will be displayed while your screen is locked. | 
			
		
	
		
			
				
					|  |  |  |  .IP \[bu] | 
			
		
	
		
			
				
					|  |  |  |  You can specify whether i3lock should bell upon a wrong password. | 
			
		
	
	
		
			
				
					|  |  | @ -54,55 +66,47 @@ | 
			
		
	
		
			
				
					|  |  |  |   | 
			
		
	
		
			
				
					|  |  |  |   | 
			
		
	
		
			
				
					|  |  |  |  .SH OPTIONS | 
			
		
	
		
			
				
					|  |  |  | @@ -75,7 +73,7 @@
 | 
			
		
	
		
			
				
					|  |  |  | @@ -66,8 +64,7 @@
 | 
			
		
	
		
			
				
					|  |  |  |  .B \-u, \-\-no-unlock-indicator | 
			
		
	
		
			
				
					|  |  |  |  Disable the unlock indicator. i3lock will by default show an unlock indicator | 
			
		
	
		
			
				
					|  |  |  |  after pressing keys. This will give feedback for every keypress and it will | 
			
		
	
		
			
				
					|  |  |  | -show you the current PAM state (whether your password is currently being
 | 
			
		
	
		
			
				
					|  |  |  | +show you the current state (whether your password is currently being
 | 
			
		
	
		
			
				
					|  |  |  |  verified or whether it is wrong). | 
			
		
	
		
			
				
					|  |  |  | -verified or whether it is wrong).
 | 
			
		
	
		
			
				
					|  |  |  | +show you whether your password is currently being verified or whether it is wrong.
 | 
			
		
	
		
			
				
					|  |  |  |   | 
			
		
	
		
			
				
					|  |  |  |  .TP | 
			
		
	
		
			
				
					|  |  |  | @@ -104,7 +102,7 @@
 | 
			
		
	
		
			
				
					|  |  |  |  .BI \-i\  path \fR,\ \fB\-\-image= path | 
			
		
	
		
			
				
					|  |  |  | @@ -95,7 +92,7 @@
 | 
			
		
	
		
			
				
					|  |  |  |  .TP | 
			
		
	
		
			
				
					|  |  |  |  .B \-e, \-\-ignore-empty-password | 
			
		
	
		
			
				
					|  |  |  |  When an empty password is provided by the user, do not validate | 
			
		
	
		
			
				
					|  |  |  | -it. Without this option, the empty password will be provided to PAM
 | 
			
		
	
		
			
				
					|  |  |  | +it. Without this option, the empty password will be checked
 | 
			
		
	
		
			
				
					|  |  |  | +it. Without this option, the empty password will be validated
 | 
			
		
	
		
			
				
					|  |  |  |  and, if invalid, the user will have to wait a few seconds before | 
			
		
	
		
			
				
					|  |  |  |  another try. This can be useful if the XF86ScreenSaver key is used to | 
			
		
	
		
			
				
					|  |  |  |  put a laptop to sleep and bounce on resume or if you happen to wake up | 
			
		
	
		
			
				
					|  |  |  | +++ i3lock.c
 | 
			
		
	
		
			
				
					|  |  |  | @@ -18,7 +18,6 @@
 | 
			
		
	
		
			
				
					|  |  |  |  #include <xcb/xkb.h> | 
			
		
	
		
			
				
					|  |  |  |  #include <err.h> | 
			
		
	
		
			
				
					|  |  |  |  #include <assert.h> | 
			
		
	
		
			
				
					|  |  |  | @@ -21,7 +21,9 @@
 | 
			
		
	
		
			
				
					|  |  |  |  #ifdef __OpenBSD__ | 
			
		
	
		
			
				
					|  |  |  |  #include <bsd_auth.h> | 
			
		
	
		
			
				
					|  |  |  |  #else | 
			
		
	
		
			
				
					|  |  |  | -#include <security/pam_appl.h>
 | 
			
		
	
		
			
				
					|  |  |  | +#include <shadow.h>
 | 
			
		
	
		
			
				
					|  |  |  | +#include <grp.h>
 | 
			
		
	
		
			
				
					|  |  |  | +#include <errno.h>
 | 
			
		
	
		
			
				
					|  |  |  |  #endif | 
			
		
	
		
			
				
					|  |  |  |  #include <getopt.h> | 
			
		
	
		
			
				
					|  |  |  |  #include <string.h> | 
			
		
	
		
			
				
					|  |  |  |  #include <ev.h> | 
			
		
	
		
			
				
					|  |  |  | @@ -28,6 +27,8 @@
 | 
			
		
	
		
			
				
					|  |  |  |  #include <xkbcommon/xkbcommon-x11.h> | 
			
		
	
		
			
				
					|  |  |  |  #include <cairo.h> | 
			
		
	
		
			
				
					|  |  |  |  #include <cairo/cairo-xcb.h> | 
			
		
	
		
			
				
					|  |  |  | +#include <unistd.h>
 | 
			
		
	
		
			
				
					|  |  |  | +#include <shadow.h>
 | 
			
		
	
		
			
				
					|  |  |  |   | 
			
		
	
		
			
				
					|  |  |  |  #include "i3lock.h" | 
			
		
	
		
			
				
					|  |  |  |  #include "xcb.h" | 
			
		
	
		
			
				
					|  |  |  | @@ -49,10 +50,10 @@
 | 
			
		
	
		
			
				
					|  |  |  |  uint32_t last_resolution[2]; | 
			
		
	
		
			
				
					|  |  |  | @@ -57,7 +59,7 @@
 | 
			
		
	
		
			
				
					|  |  |  |  xcb_window_t win; | 
			
		
	
		
			
				
					|  |  |  |  static xcb_cursor_t cursor; | 
			
		
	
		
			
				
					|  |  |  |  #ifndef __OpenBSD__ | 
			
		
	
		
			
				
					|  |  |  | -static pam_handle_t *pam_handle;
 | 
			
		
	
		
			
				
					|  |  |  | +const char *hash = NULL;
 | 
			
		
	
		
			
				
					|  |  |  |  #endif | 
			
		
	
		
			
				
					|  |  |  |  int input_position = 0; | 
			
		
	
		
			
				
					|  |  |  |  /* Holds the password you enter (in UTF-8). */ | 
			
		
	
		
			
				
					|  |  |  |  static char password[512]; | 
			
		
	
		
			
				
					|  |  |  | +const char *pws = NULL;
 | 
			
		
	
		
			
				
					|  |  |  |  static bool beep = false; | 
			
		
	
		
			
				
					|  |  |  |  bool debug_mode = false; | 
			
		
	
		
			
				
					|  |  |  |  bool unlock_indicator = true; | 
			
		
	
		
			
				
					|  |  |  | @@ -80,6 +81,39 @@
 | 
			
		
	
		
			
				
					|  |  |  | @@ -90,6 +92,37 @@
 | 
			
		
	
		
			
				
					|  |  |  |  bool ignore_empty_password = false; | 
			
		
	
		
			
				
					|  |  |  |  bool skip_repeated_empty_password = false; | 
			
		
	
		
			
				
					|  |  |  |   | 
			
		
	
	
		
			
				
					|  |  | @ -114,42 +118,43 @@ | 
			
		
	
		
			
				
					|  |  |  | +#ifdef __linux__
 | 
			
		
	
		
			
				
					|  |  |  | +#include <fcntl.h>
 | 
			
		
	
		
			
				
					|  |  |  | +#include <linux/oom.h>
 | 
			
		
	
		
			
				
					|  |  |  | +#include <errno.h>
 | 
			
		
	
		
			
				
					|  |  |  | +
 | 
			
		
	
		
			
				
					|  |  |  | +static void
 | 
			
		
	
		
			
				
					|  |  |  | +dontkillme(void)
 | 
			
		
	
		
			
				
					|  |  |  | +{
 | 
			
		
	
		
			
				
					|  |  |  | +    int fd;
 | 
			
		
	
		
			
				
					|  |  |  | +    int length;
 | 
			
		
	
		
			
				
					|  |  |  | +    char value[64];
 | 
			
		
	
		
			
				
					|  |  |  | +
 | 
			
		
	
		
			
				
					|  |  |  | +    fd = open("/proc/self/oom_score_adj", O_WRONLY);
 | 
			
		
	
		
			
				
					|  |  |  | +    if (fd < 0 && errno == ENOENT)
 | 
			
		
	
		
			
				
					|  |  |  | +        return;
 | 
			
		
	
		
			
				
					|  |  |  | +	FILE *f;
 | 
			
		
	
		
			
				
					|  |  |  | +	const char oomfile[] = "/proc/self/oom_score_adj";
 | 
			
		
	
		
			
				
					|  |  |  | +
 | 
			
		
	
		
			
				
					|  |  |  | +    /* convert OOM_SCORE_ADJ_MIN to string for writing */
 | 
			
		
	
		
			
				
					|  |  |  | +    length = snprintf(value, sizeof(value), "%d\n", OOM_SCORE_ADJ_MIN);
 | 
			
		
	
		
			
				
					|  |  |  | +
 | 
			
		
	
		
			
				
					|  |  |  | +    /* bail on truncation */
 | 
			
		
	
		
			
				
					|  |  |  | +    if (length >= sizeof(value))
 | 
			
		
	
		
			
				
					|  |  |  | +        errx(EXIT_FAILURE, "buffer too small\n");
 | 
			
		
	
		
			
				
					|  |  |  | +
 | 
			
		
	
		
			
				
					|  |  |  | +    if (fd < 0 || write(fd, value, length) != length || close(fd) != 0)
 | 
			
		
	
		
			
				
					|  |  |  | +        errx(EXIT_FAILURE, "cannot disable the out-of-memory killer for this process (make sure to suid or sgid i3lock)\n");
 | 
			
		
	
		
			
				
					|  |  |  | +	if (!(f = fopen(oomfile, "w"))) {
 | 
			
		
	
		
			
				
					|  |  |  | +		if (errno == ENOENT)
 | 
			
		
	
		
			
				
					|  |  |  | +			return;
 | 
			
		
	
		
			
				
					|  |  |  | +		errx(EXIT_FAILURE, "i3lock: fopen %s: %s", oomfile, strerror(errno));
 | 
			
		
	
		
			
				
					|  |  |  | +	}
 | 
			
		
	
		
			
				
					|  |  |  | +	fprintf(f, "%d", OOM_SCORE_ADJ_MIN);
 | 
			
		
	
		
			
				
					|  |  |  | +	if (fclose(f)) {
 | 
			
		
	
		
			
				
					|  |  |  | +		if (errno == EACCES)
 | 
			
		
	
		
			
				
					|  |  |  | +			errx(EXIT_FAILURE, "i3lock: unable to disable OOM killer. "
 | 
			
		
	
		
			
				
					|  |  |  | +			                   "Make sure to suid or sgid i3lock.");
 | 
			
		
	
		
			
				
					|  |  |  | +		else
 | 
			
		
	
		
			
				
					|  |  |  | +			errx(EXIT_FAILURE, "i3lock: fclose %s: %s", oomfile, strerror(errno));
 | 
			
		
	
		
			
				
					|  |  |  | +	}
 | 
			
		
	
		
			
				
					|  |  |  | +}
 | 
			
		
	
		
			
				
					|  |  |  | +#endif
 | 
			
		
	
		
			
				
					|  |  |  | +
 | 
			
		
	
		
			
				
					|  |  |  |  /* isutf, u8_dec © 2005 Jeff Bezanson, public domain */ | 
			
		
	
		
			
				
					|  |  |  |  #define isutf(c) (((c)&0xC0) != 0x80) | 
			
		
	
		
			
				
					|  |  |  |   | 
			
		
	
		
			
				
					|  |  |  | @@ -235,17 +269,10 @@
 | 
			
		
	
		
			
				
					|  |  |  |      unlock_state = STATE_STARTED; | 
			
		
	
		
			
				
					|  |  |  |      redraw_screen(); | 
			
		
	
		
			
				
					|  |  |  |   | 
			
		
	
		
			
				
					|  |  |  | @@ -281,16 +314,16 @@
 | 
			
		
	
		
			
				
					|  |  |  |          exit(0); | 
			
		
	
		
			
				
					|  |  |  |      } | 
			
		
	
		
			
				
					|  |  |  |  #else | 
			
		
	
		
			
				
					|  |  |  | -    if (pam_authenticate(pam_handle, 0) == PAM_SUCCESS) {
 | 
			
		
	
		
			
				
					|  |  |  | +    if (!strcmp(crypt(password, pws), pws)) {
 | 
			
		
	
		
			
				
					|  |  |  |          DEBUG("successfully authenticated\n"); | 
			
		
	
		
			
				
					|  |  |  |          clear_password_memory(); | 
			
		
	
		
			
				
					|  |  |  | -        DEBUG("successfully authenticated\n");
 | 
			
		
	
		
			
				
					|  |  |  | -        clear_password_memory();
 | 
			
		
	
		
			
				
					|  |  |  | +    /*
 | 
			
		
	
		
			
				
					|  |  |  | +     * Shamelessly stolen from slock. See LICENSE-slock.
 | 
			
		
	
		
			
				
					|  |  |  | +     */
 | 
			
		
	
		
			
				
					|  |  |  | +    char *inputhash;
 | 
			
		
	
		
			
				
					|  |  |  |   | 
			
		
	
		
			
				
					|  |  |  | -        /* PAM credentials should be refreshed, this will for example update any kerberos tickets.
 | 
			
		
	
		
			
				
					|  |  |  | -         * Related to credentials pam_end() needs to be called to cleanup any temporary
 | 
			
		
	
	
		
			
				
					|  |  | @ -157,14 +162,20 @@ | 
			
		
	
		
			
				
					|  |  |  | -         * refresh of the credentials failed. */
 | 
			
		
	
		
			
				
					|  |  |  | -        pam_setcred(pam_handle, PAM_REFRESH_CRED);
 | 
			
		
	
		
			
				
					|  |  |  | -        pam_end(pam_handle, PAM_SUCCESS);
 | 
			
		
	
		
			
				
					|  |  |  | -
 | 
			
		
	
		
			
				
					|  |  |  | +    if (!(inputhash = crypt(password, hash)))
 | 
			
		
	
		
			
				
					|  |  |  | +        fprintf(stderr, "i3lock: crypt: %s", strerror(errno));
 | 
			
		
	
		
			
				
					|  |  |  | +    else if (!strcmp(inputhash, hash)) {
 | 
			
		
	
		
			
				
					|  |  |  | +        DEBUG("successfully authenticated");
 | 
			
		
	
		
			
				
					|  |  |  | +        clear_password_memory();
 | 
			
		
	
		
			
				
					|  |  |  |   | 
			
		
	
		
			
				
					|  |  |  |          exit(0); | 
			
		
	
		
			
				
					|  |  |  |      } | 
			
		
	
		
			
				
					|  |  |  |   | 
			
		
	
		
			
				
					|  |  |  | @@ -580,37 +607,6 @@
 | 
			
		
	
		
			
				
					|  |  |  | @@ -626,39 +659,6 @@
 | 
			
		
	
		
			
				
					|  |  |  |      redraw_screen(); | 
			
		
	
		
			
				
					|  |  |  |  } | 
			
		
	
		
			
				
					|  |  |  |   | 
			
		
	
		
			
				
					|  |  |  |  /* | 
			
		
	
		
			
				
					|  |  |  | -#ifndef __OpenBSD__
 | 
			
		
	
		
			
				
					|  |  |  | -/*
 | 
			
		
	
		
			
				
					|  |  |  | - * Callback function for PAM. We only react on password request callbacks.
 | 
			
		
	
		
			
				
					|  |  |  | - *
 | 
			
		
	
		
			
				
					|  |  |  | - */
 | 
			
		
	
	
		
			
				
					|  |  | @ -194,65 +205,87 @@ | 
			
		
	
		
			
				
					|  |  |  | -
 | 
			
		
	
		
			
				
					|  |  |  | -    return 0;
 | 
			
		
	
		
			
				
					|  |  |  | -}
 | 
			
		
	
		
			
				
					|  |  |  | -#endif
 | 
			
		
	
		
			
				
					|  |  |  | -
 | 
			
		
	
		
			
				
					|  |  |  | -/*
 | 
			
		
	
		
			
				
					|  |  |  |  /* | 
			
		
	
		
			
				
					|  |  |  |   * This callback is only a dummy, see xcb_prepare_cb and xcb_check_cb. | 
			
		
	
		
			
				
					|  |  |  |   * See also man libev(3): "ev_prepare" and "ev_check" - customise your event loop | 
			
		
	
		
			
				
					|  |  |  |   * | 
			
		
	
		
			
				
					|  |  |  | @@ -764,8 +760,6 @@
 | 
			
		
	
		
			
				
					|  |  |  | @@ -813,10 +813,6 @@
 | 
			
		
	
		
			
				
					|  |  |  |      struct passwd *pw; | 
			
		
	
		
			
				
					|  |  |  |      char *username; | 
			
		
	
		
			
				
					|  |  |  |      char *image_path = NULL; | 
			
		
	
		
			
				
					|  |  |  | -#ifndef __OpenBSD__
 | 
			
		
	
		
			
				
					|  |  |  | -    int ret;
 | 
			
		
	
		
			
				
					|  |  |  | -    struct pam_conv conv = {conv_callback, NULL};
 | 
			
		
	
		
			
				
					|  |  |  | -#endif
 | 
			
		
	
		
			
				
					|  |  |  |      int curs_choice = CURS_NONE; | 
			
		
	
		
			
				
					|  |  |  |      int o; | 
			
		
	
		
			
				
					|  |  |  |      int optind = 0; | 
			
		
	
		
			
				
					|  |  |  | @@ -791,6 +785,30 @@
 | 
			
		
	
		
			
				
					|  |  |  | @@ -842,6 +838,48 @@
 | 
			
		
	
		
			
				
					|  |  |  |      if ((username = pw->pw_name) == NULL) | 
			
		
	
		
			
				
					|  |  |  |          errx(EXIT_FAILURE, "pw->pw_name is NULL.\n"); | 
			
		
	
		
			
				
					|  |  |  |   | 
			
		
	
		
			
				
					|  |  |  | +#ifndef __OpenBSD__
 | 
			
		
	
		
			
				
					|  |  |  | +    /*
 | 
			
		
	
		
			
				
					|  |  |  | +     * This piece of code is shamelessly stolen from slock.
 | 
			
		
	
		
			
				
					|  |  |  | +     * See LICENSE-slock.
 | 
			
		
	
		
			
				
					|  |  |  | +     * Shamelessly stolen from slock. See LICENSE-slock.
 | 
			
		
	
		
			
				
					|  |  |  | +     *
 | 
			
		
	
		
			
				
					|  |  |  | +     * Slock has code to make it run as nobody:nogroup, which has the added
 | 
			
		
	
		
			
				
					|  |  |  | +     *  security that the locker can only be killed by root.
 | 
			
		
	
		
			
				
					|  |  |  | +     * It causes problems with the xcb_connect in raise_loop, however,
 | 
			
		
	
		
			
				
					|  |  |  | +     *  and I'm not aware of any other methods to keep the calling user from
 | 
			
		
	
		
			
				
					|  |  |  | +     *  killing the locker.
 | 
			
		
	
		
			
				
					|  |  |  | +     * This means that a malicious program running as your user
 | 
			
		
	
		
			
				
					|  |  |  | +     *  could easily bypass your locker by killing it.
 | 
			
		
	
		
			
				
					|  |  |  | +     * However, if such a program even manages to be running, you're pretty
 | 
			
		
	
		
			
				
					|  |  |  | +     *  screwed regardless.
 | 
			
		
	
		
			
				
					|  |  |  | +     */
 | 
			
		
	
		
			
				
					|  |  |  | +
 | 
			
		
	
		
			
				
					|  |  |  | +#ifdef __linux__
 | 
			
		
	
		
			
				
					|  |  |  | +    dontkillme();
 | 
			
		
	
		
			
				
					|  |  |  | +#endif
 | 
			
		
	
		
			
				
					|  |  |  | +
 | 
			
		
	
		
			
				
					|  |  |  | +    pws = pw->pw_passwd;
 | 
			
		
	
		
			
				
					|  |  |  | +    hash = pw->pw_passwd;
 | 
			
		
	
		
			
				
					|  |  |  | +
 | 
			
		
	
		
			
				
					|  |  |  | +    if (pws[0] == 'x' && pws[1] == '\0') {
 | 
			
		
	
		
			
				
					|  |  |  | +    if (!strcmp(hash, "x")) {
 | 
			
		
	
		
			
				
					|  |  |  | +        struct spwd *sp;
 | 
			
		
	
		
			
				
					|  |  |  | +        if (!(sp = getspnam(getenv("USER"))))
 | 
			
		
	
		
			
				
					|  |  |  | +            errx(EXIT_FAILURE, "cannot retrieve shadow entry (make sure to suid or sgid i3lock)\n");
 | 
			
		
	
		
			
				
					|  |  |  | +        pws = sp->sp_pwdp;
 | 
			
		
	
		
			
				
					|  |  |  | +        if (!(sp = getspnam(pw->pw_name)))
 | 
			
		
	
		
			
				
					|  |  |  | +            errx(EXIT_FAILURE, "i3lock: getspnam: cannot retrieve shadow entry. "
 | 
			
		
	
		
			
				
					|  |  |  | +                               "Make sure to suid or sgid i3lock.");
 | 
			
		
	
		
			
				
					|  |  |  | +        hash = sp->sp_pwdp;
 | 
			
		
	
		
			
				
					|  |  |  | +    }
 | 
			
		
	
		
			
				
					|  |  |  | +
 | 
			
		
	
		
			
				
					|  |  |  | +    /* drop privileges */
 | 
			
		
	
		
			
				
					|  |  |  | +    if (geteuid() == 0 &&
 | 
			
		
	
		
			
				
					|  |  |  | +        ((getegid() != pw->pw_gid && setgid(pw->pw_gid) < 0) || setuid(pw->pw_uid) < 0))
 | 
			
		
	
		
			
				
					|  |  |  | +        errx(EXIT_FAILURE, "cannot drop privileges\n");
 | 
			
		
	
		
			
				
					|  |  |  | +    errno = 0;
 | 
			
		
	
		
			
				
					|  |  |  | +    if (!crypt("", hash))
 | 
			
		
	
		
			
				
					|  |  |  | +        errx(EXIT_FAILURE, "i3lock: crypt: %s", strerror(errno));
 | 
			
		
	
		
			
				
					|  |  |  | +
 | 
			
		
	
		
			
				
					|  |  |  | +    /* End of stolen code */
 | 
			
		
	
		
			
				
					|  |  |  | +    /* drop privileges */
 | 
			
		
	
		
			
				
					|  |  |  | +    if (setgroups(0, NULL) < 0)
 | 
			
		
	
		
			
				
					|  |  |  | +        errx(EXIT_FAILURE, "i3lock: setgroups: %s", strerror(errno));
 | 
			
		
	
		
			
				
					|  |  |  | +    if (setgid(pw->pw_gid) < 0)
 | 
			
		
	
		
			
				
					|  |  |  | +        errx(EXIT_FAILURE, "i3lock: setgid: %s", strerror(errno));
 | 
			
		
	
		
			
				
					|  |  |  | +    if (setuid(pw->pw_uid) < 0)
 | 
			
		
	
		
			
				
					|  |  |  | +        errx(EXIT_FAILURE, "i3lock: setuid: %s", strerror(errno));
 | 
			
		
	
		
			
				
					|  |  |  | +#endif
 | 
			
		
	
		
			
				
					|  |  |  | +
 | 
			
		
	
		
			
				
					|  |  |  |      char *optstring = "hvnbdc:p:ui:teI:f"; | 
			
		
	
		
			
				
					|  |  |  |      while ((o = getopt_long(argc, argv, optstring, longopts, &optind)) != -1) { | 
			
		
	
		
			
				
					|  |  |  |          switch (o) { | 
			
		
	
		
			
				
					|  |  |  | @@ -862,13 +880,6 @@
 | 
			
		
	
		
			
				
					|  |  |  | @@ -910,15 +948,6 @@
 | 
			
		
	
		
			
				
					|  |  |  |       * the unlock indicator upon keypresses. */ | 
			
		
	
		
			
				
					|  |  |  |      srand(time(NULL)); | 
			
		
	
		
			
				
					|  |  |  |   | 
			
		
	
		
			
				
					|  |  |  | -#ifndef __OpenBSD__
 | 
			
		
	
		
			
				
					|  |  |  | -    /* Initialize PAM */
 | 
			
		
	
		
			
				
					|  |  |  | -    if ((ret = pam_start("i3lock", username, &conv, &pam_handle)) != PAM_SUCCESS)
 | 
			
		
	
		
			
				
					|  |  |  | -        errx(EXIT_FAILURE, "PAM: %s", pam_strerror(pam_handle, ret));
 | 
			
		
	
		
			
				
					|  |  |  | -
 | 
			
		
	
		
			
				
					|  |  |  | -    if ((ret = pam_set_item(pam_handle, PAM_TTY, getenv("DISPLAY"))) != PAM_SUCCESS)
 | 
			
		
	
		
			
				
					|  |  |  | -        errx(EXIT_FAILURE, "PAM: %s", pam_strerror(pam_handle, ret));
 | 
			
		
	
		
			
				
					|  |  |  | -#endif
 | 
			
		
	
		
			
				
					|  |  |  | -
 | 
			
		
	
		
			
				
					|  |  |  |  /* Using mlock() as non-super-user seems only possible in Linux. Users of other | 
			
		
	
		
			
				
					|  |  |  |   * operating systems should use encrypted swap/no swap (or remove the ifdef and | 
			
		
	
		
			
				
					|  |  |  |   * run i3lock as super-user). */ | 
			
		
	
		
			
				
					|  |  |  |  /* Using mlock() as non-super-user seems only possible in Linux. | 
			
		
	
		
			
				
					|  |  |  |   * Users of other operating systems should use encrypted swap/no swap | 
			
		
	
		
			
				
					|  |  |  |   * (or remove the ifdef and run i3lock as super-user). | 
			
		
	
		
			
				
					|  |  |  | +++ i3lock.pam
 | 
			
		
	
		
			
				
					|  |  |  | @@ -1,6 +0,0 @@
 | 
			
		
	
		
			
				
					|  |  |  | -#
 |