summaryrefslogtreecommitdiff
path: root/desktop/i3lock/i3lock-2.10-no-pam.patch
diff options
context:
space:
mode:
Diffstat (limited to 'desktop/i3lock/i3lock-2.10-no-pam.patch')
-rw-r--r--desktop/i3lock/i3lock-2.10-no-pam.patch364
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