diff options
Diffstat (limited to 'desktop/i3lock/i3lock-2.10-no-pam.patch')
-rw-r--r-- | desktop/i3lock/i3lock-2.10-no-pam.patch | 364 |
1 files changed, 364 insertions, 0 deletions
diff --git a/desktop/i3lock/i3lock-2.10-no-pam.patch b/desktop/i3lock/i3lock-2.10-no-pam.patch new file mode 100644 index 0000000000..0b119114c5 --- /dev/null +++ b/desktop/i3lock/i3lock-2.10-no-pam.patch @@ -0,0 +1,364 @@ ++++ LICENSE-slock +@@ -0,0 +1,24 @@ ++MIT/X Consortium License ++ ++© 2015-2016 Markus Teich <markus.teich@stusta.mhn.de> ++© 2014 Dimitris Papastamos <sin@2f30.org> ++© 2006-2014 Anselm R Garbe <anselm@garbe.us> ++© 2014-2016 Laslo Hunhold <dev@frign.de> ++ ++Permission is hereby granted, free of charge, to any person obtaining a ++copy of this software and associated documentation files (the "Software"), ++to deal in the Software without restriction, including without limitation ++the rights to use, copy, modify, merge, publish, distribute, sublicense, ++and/or sell copies of the Software, and to permit persons to whom the ++Software is furnished to do so, subject to the following conditions: ++ ++The above copyright notice and this permission notice shall be included in ++all copies or substantial portions of the Software. ++ ++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING ++FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER ++DEALINGS IN THE SOFTWARE. ++++ Makefile +@@ -22,7 +22,7 @@ + + # OpenBSD lacks PAM, 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 +- $(INSTALL) -d $(DESTDIR)$(SYSCONFDIR)/pam.d + $(INSTALL) -m 755 i3lock $(DESTDIR)$(PREFIX)/bin/i3lock +- $(INSTALL) -m 644 i3lock.pam $(DESTDIR)$(SYSCONFDIR)/pam.d/i3lock + + 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/^\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 +@@ -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. +-.IP \[bu] +-i3lock uses PAM and therefore is compatible with LDAP, etc. + + + .SH OPTIONS +@@ -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 +-verified or whether it is wrong). ++show you whether your password is currently being verified or whether it is wrong. + + .TP + .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 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 +@@ -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> +@@ -59,7 +61,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). */ +@@ -93,6 +95,37 @@ + bool ignore_empty_password = false; + bool skip_repeated_empty_password = false; + ++/* ++ * Shamelessly stolen from slock. See LICENSE-slock. ++ * This adjusts the process' out of memory score, ++ * so it isn't killed by the kernel under any circumstances. ++ */ ++#ifdef __linux__ ++#include <fcntl.h> ++#include <linux/oom.h> ++ ++static void ++dontkillme(void) ++{ ++ FILE *f; ++ const char oomfile[] = "/proc/self/oom_score_adj"; ++ ++ if (!(f = fopen(oomfile, "w"))) { ++ if (errno == ENOENT) ++ return; ++ errx(EXIT_FAILURE, "fopen %s: %s", oomfile, strerror(errno)); ++ } ++ fprintf(f, "%d", OOM_SCORE_ADJ_MIN); ++ if (fclose(f)) { ++ if (errno == EACCES) ++ errx(EXIT_FAILURE, "unable to disable OOM killer. " ++ "Make sure to suid or sgid i3lock."); ++ else ++ errx(EXIT_FAILURE, "fclose %s: %s", oomfile, strerror(errno)); ++ } ++} ++#endif ++ + /* isutf, u8_dec © 2005 Jeff Bezanson, public domain */ + #define isutf(c) (((c)&0xC0) != 0x80) + +@@ -285,16 +318,16 @@ + return; + } + #else +- if (pam_authenticate(pam_handle, 0) == PAM_SUCCESS) { +- 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 +- * credentials like kerberos /tmp/krb5cc_pam_* files which may of been left behind if the +- * 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, "crypt: %s", strerror(errno)); ++ else if (!strcmp(inputhash, hash)) { ++ DEBUG("successfully authenticated"); ++ clear_password_memory(); + + ev_break(EV_DEFAULT, EVBREAK_ALL); + return; +@@ -626,39 +659,6 @@ + redraw_screen(); + } + +-#ifndef __OpenBSD__ +-/* +- * Callback function for PAM. We only react on password request callbacks. +- * +- */ +-static int conv_callback(int num_msg, const struct pam_message **msg, +- struct pam_response **resp, void *appdata_ptr) { +- if (num_msg == 0) +- return 1; +- +- /* PAM expects an array of responses, one for each message */ +- if ((*resp = calloc(num_msg, sizeof(struct pam_response))) == NULL) { +- perror("calloc"); +- return 1; +- } +- +- for (int c = 0; c < num_msg; c++) { +- if (msg[c]->msg_style != PAM_PROMPT_ECHO_OFF && +- msg[c]->msg_style != PAM_PROMPT_ECHO_ON) +- continue; +- +- /* return code is currently not used but should be set to zero */ +- resp[c]->resp_retcode = 0; +- if ((resp[c]->resp = strdup(password)) == NULL) { +- perror("strdup"); +- return 1; +- } +- } +- +- 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 +@@ -766,13 +766,15 @@ + * + */ + static void raise_loop(xcb_window_t window) { +- xcb_connection_t *conn; + xcb_generic_event_t *event; +- int screens; + +- if ((conn = xcb_connect(NULL, &screens)) == NULL || ++#ifdef __OpenBSD__ ++ xcb_connection_t *conn; ++ ++ if ((conn = xcb_connect(NULL, NULL)) == NULL || + xcb_connection_has_error(conn)) + errx(EXIT_FAILURE, "Cannot open display\n"); ++#endif + + /* We need to know about the window being obscured or getting destroyed. */ + xcb_change_window_attributes(conn, window, XCB_CW_EVENT_MASK, +@@ -820,8 +822,11 @@ + char *username; + char *image_path = NULL; + #ifndef __OpenBSD__ +- int ret; +- struct pam_conv conv = {conv_callback, NULL}; ++ struct passwd *pwd; ++ struct group *grp; ++ uid_t duid; ++ gid_t dgid; ++ xcb_connection_t *raise_conn; + #endif + int curs_choice = CURS_NONE; + int o; +@@ -848,6 +853,65 @@ + if ((username = pw->pw_name) == NULL) + errx(EXIT_FAILURE, "pw->pw_name is NULL.\n"); + ++#ifndef __OpenBSD__ ++ /* ++ * 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, and the main ++ * xcb_connect, however. ++ * Because of that, both xcb_connect are ran as root, before dropping the ++ * privileges to the user, much like is being done with XOpenDisplay ++ * in slock. ++ * I'm unsure of any security implications that may have, as it seems to ++ * run fine, otherwise. ++ * Please contact me if it's something I _really_ shouldn't do. ++ */ ++ ++ /* If the nobody:nogroup don't exist, just use the password's user */ ++ duid = pw->pw_uid; ++ if ((pwd = getpwnam("nobody"))) ++ duid = pwd->pw_uid; ++ dgid = pw->pw_gid; ++ if ((grp = getgrnam("nogroup"))) ++ dgid = grp->gr_gid; ++ ++#ifdef __linux__ ++ dontkillme(); ++#endif ++ ++ hash = pw->pw_passwd; ++ ++ if (!strcmp(hash, "x")) { ++ struct spwd *sp; ++ if (!(sp = getspnam(pw->pw_name))) ++ errx(EXIT_FAILURE, "getspnam: cannot retrieve shadow entry. " ++ "Make sure to suid or sgid i3lock."); ++ hash = sp->sp_pwdp; ++ } ++ ++ errno = 0; ++ if (!crypt("", hash)) ++ errx(EXIT_FAILURE, "crypt: %s", strerror(errno)); ++ ++ /* Create the necessary connections before dropping privileges */ ++ if ((conn = xcb_connect(NULL, NULL)) == NULL || ++ xcb_connection_has_error(conn)) ++ errx(EXIT_FAILURE, "Could not connect to X11, maybe you need to set DISPLAY?"); ++ if ((raise_conn = xcb_connect(NULL, NULL)) == NULL || ++ xcb_connection_has_error(raise_conn)) ++ errx(EXIT_FAILURE, "Cannot open display\n"); ++ ++ /* drop privileges */ ++ if (setgroups(0, NULL) < 0) ++ errx(EXIT_FAILURE, "setgroups: %s", strerror(errno)); ++ if (setgid(dgid) < 0) ++ errx(EXIT_FAILURE, "setgid: %s", strerror(errno)); ++ if (setuid(duid) < 0) ++ errx(EXIT_FAILURE, "setuid: %s", strerror(errno)); ++#endif ++ + char *optstring = "hvnbdc:p:ui:teI:f"; + while ((o = getopt_long(argc, argv, optstring, longopts, &longoptind)) != -1) { + switch (o) { +@@ -916,15 +980,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). +@@ -938,11 +993,12 @@ + err(EXIT_FAILURE, "Could not lock page in memory, check RLIMIT_MEMLOCK"); + #endif + ++#ifdef __OpenBSD__ + /* Double checking that connection is good and operatable with xcb */ +- int screennr; +- if ((conn = xcb_connect(NULL, &screennr)) == NULL || ++ if ((conn = xcb_connect(NULL, NULL)) == NULL || + xcb_connection_has_error(conn)) + errx(EXIT_FAILURE, "Could not connect to X11, maybe you need to set DISPLAY?"); ++#endif + + if (xkb_x11_setup_xkb_extension(conn, + XKB_X11_MIN_MAJOR_XKB_VERSION, +@@ -1056,10 +1112,16 @@ + if (pid == 0) { + /* Child */ + close(xcb_get_file_descriptor(conn)); ++#ifndef __OpenBSD__ ++ conn = raise_conn; ++#endif + maybe_close_sleep_lock_fd(); + raise_loop(win); + exit(EXIT_SUCCESS); + } ++#ifndef __OpenBSD__ ++ close(xcb_get_file_descriptor(raise_conn)); ++#endif + + /* Load the keymap again to sync the current modifier state. Since we first + * loaded the keymap, there might have been changes, but starting from now, ++++ i3lock.pam +@@ -1,6 +0,0 @@ +-# +-# PAM configuration file for the i3lock screen locker. By default, it includes +-# the 'login' configuration file (see /etc/pam.d/login) +-# +- +-auth include login |