summaryrefslogtreecommitdiffstats
path: root/patches/source/rxvt-unicode/rxvt-unicode.utempter.diff
diff options
context:
space:
mode:
author Patrick J Volkerding <volkerdi@slackware.com>2023-01-04 02:18:08 +0000
committer Eric Hameleers <alien@slackware.com>2023-01-04 13:30:28 +0100
commite054e8d54f8b4a065c842d44956d26c368af3b03 (patch)
treec7195c6b4aefd52758f4a1489c19e0df2898e170 /patches/source/rxvt-unicode/rxvt-unicode.utempter.diff
parentd404417adc9bf3045ef8e5b44b10bc8dfdf1e9b8 (diff)
downloadcurrent-e054e8d54f8b4a065c842d44956d26c368af3b03.tar.gz
current-e054e8d54f8b4a065c842d44956d26c368af3b03.tar.xz
Wed Jan 4 02:18:08 UTC 202320230104021808_15.0
patches/packages/libtiff-4.4.0-x86_64-1_slack15.0.txz: Upgraded. Patched various security bugs. For more information, see: https://www.cve.org/CVERecord?id=CVE-2022-2056 https://www.cve.org/CVERecord?id=CVE-2022-2057 https://www.cve.org/CVERecord?id=CVE-2022-2058 https://www.cve.org/CVERecord?id=CVE-2022-3970 https://www.cve.org/CVERecord?id=CVE-2022-34526 (* Security fix *) patches/packages/rxvt-unicode-9.26-x86_64-3_slack15.0.txz: Rebuilt. When the "background" extension was loaded, an attacker able to control the data written to the terminal would be able to execute arbitrary code as the terminal's user. Thanks to David Leadbeater and Ben Collver. For more information, see: https://www.openwall.com/lists/oss-security/2022/12/05/1 https://www.cve.org/CVERecord?id=CVE-2022-4170 (* Security fix *) patches/packages/whois-5.5.15-x86_64-1_slack15.0.txz: Upgraded. Updated the .bd, .nz and .tv TLD servers. Added the .llyw.cymru, .gov.scot and .gov.wales SLD servers. Updated the .ac.uk and .gov.uk SLD servers. Recursion has been enabled for whois.nic.tv. Updated the list of new gTLDs with four generic TLDs assigned in October 2013 which were missing due to a bug. Removed 4 new gTLDs which are no longer active. Added the Georgian translation, contributed by Temuri Doghonadze. Updated the Finnish translation, contributed by Lauri Nurmi.
Diffstat (limited to 'patches/source/rxvt-unicode/rxvt-unicode.utempter.diff')
-rw-r--r--patches/source/rxvt-unicode/rxvt-unicode.utempter.diff1183
1 files changed, 1183 insertions, 0 deletions
diff --git a/patches/source/rxvt-unicode/rxvt-unicode.utempter.diff b/patches/source/rxvt-unicode/rxvt-unicode.utempter.diff
new file mode 100644
index 000000000..d56c13522
--- /dev/null
+++ b/patches/source/rxvt-unicode/rxvt-unicode.utempter.diff
@@ -0,0 +1,1183 @@
+--- ./configure.ac.orig 2015-06-17 06:57:42.000000000 -0500
++++ ./configure.ac 2018-03-31 11:21:43.971399093 -0500
+@@ -113,7 +113,6 @@
+ support_fading=no
+ support_keepscrolling=no
+ support_selectionscrolling=no
+- support_lastlog=no
+ support_mousewheel=no
+ support_mouseslipwheel=no
+ support_text_blink=no
+@@ -121,8 +120,6 @@
+ support_scroll_rxvt=no
+ support_scroll_next=no
+ support_scroll_xterm=no
+- support_utmp=no
+- support_wtmp=no
+ support_xim=no
+ support_pixbuf=no
+ support_startup_notification=no
+@@ -141,7 +138,6 @@
+ support_fading=yes
+ support_keepscrolling=yes
+ support_selectionscrolling=yes
+- support_lastlog=yes
+ support_mousewheel=yes
+ support_mouseslipwheel=yes
+ support_text_blink=yes
+@@ -149,8 +145,6 @@
+ support_scroll_rxvt=yes
+ support_scroll_next=yes
+ support_scroll_xterm=yes
+- support_utmp=yes
+- support_wtmp=yes
+ support_xim=yes
+ support_pixbuf=yes
+ support_startup_notification=yes
+@@ -513,8 +507,6 @@
+ dnl# --------------------------------------------------------------------------
+ AC_CHECK_FUNCS(unsetenv)
+
+-UTMP_CHECK
+-
+ dnl# --------------------------------------------------------------------------
+
+ dnl# --------------------------------------------------------------------------
+--- ./config.h.in.orig 2015-06-17 06:57:42.000000000 -0500
++++ ./config.h.in 2018-03-31 11:21:43.970399093 -0500
+@@ -75,9 +75,6 @@
+ /* Define to 1 if you have the `kqueue' function. */
+ #undef HAVE_KQUEUE
+
+-/* Define to 1 if you have the <lastlog.h> header file. */
+-#undef HAVE_LASTLOG_H
+-
+ /* Define to 1 if you have the `rt' library (-lrt). */
+ #undef HAVE_LIBRT
+
+@@ -156,18 +153,6 @@
+ /* Define to 1 if you have the <stropts.h> header file. */
+ #undef HAVE_STROPTS_H
+
+-/* Define to 1 if the system has the type `struct lastlog'. */
+-#undef HAVE_STRUCT_LASTLOG
+-
+-/* Define to 1 if the system has the type `struct lastlogx'. */
+-#undef HAVE_STRUCT_LASTLOGX
+-
+-/* Define to 1 if the system has the type `struct utmp'. */
+-#undef HAVE_STRUCT_UTMP
+-
+-/* Define to 1 if the system has the type `struct utmpx'. */
+-#undef HAVE_STRUCT_UTMPX
+-
+ /* Define to 1 if you have the <sys/byteorder.h> header file. */
+ #undef HAVE_SYS_BYTEORDER_H
+
+@@ -214,33 +199,9 @@
+ /* Define to 1 if you have the `unsetenv' function. */
+ #undef HAVE_UNSETENV
+
+-/* Define to 1 if you have the `updlastlogx' function. */
+-#undef HAVE_UPDLASTLOGX
+-
+-/* Define to 1 if you have the `updwtmp' function. */
+-#undef HAVE_UPDWTMP
+-
+-/* Define to 1 if you have the `updwtmpx' function. */
+-#undef HAVE_UPDWTMPX
+-
+ /* Define to 1 if you have the <util.h> header file. */
+ #undef HAVE_UTIL_H
+
+-/* Define to 1 if you have the <utmpx.h> header file. */
+-#undef HAVE_UTMPX_H
+-
+-/* Define if struct utmpx contains ut_host */
+-#undef HAVE_UTMPX_HOST
+-
+-/* Define to 1 if you have the <utmp.h> header file. */
+-#undef HAVE_UTMP_H
+-
+-/* Define if struct utmp contains ut_host */
+-#undef HAVE_UTMP_HOST
+-
+-/* Define if struct utmp contains ut_pid */
+-#undef HAVE_UTMP_PID
+-
+ /* Define to 1 if you have the <wchar.h> header file. */
+ #undef HAVE_WCHAR_H
+
+@@ -262,9 +223,6 @@
+ /* Define if you want ISO 14755 extended support */
+ #undef ISO_14755
+
+-/* Define if you want to have lastlog support when utmp/utmpx is enabled */
+-#undef LASTLOG_SUPPORT
+-
+ /* Define to have CTRL cause wheel events to accelerate scrolling. Release
+ CTRL to halt scrolling */
+ #undef MOUSE_SLIP_WHEELING
+@@ -322,21 +280,6 @@
+ /* Define if you want to hide the pointer while typing */
+ #undef POINTER_BLANK
+
+-/* Define to a fallback location of lastlogx */
+-#undef PT_LASTLOGX_FILE
+-
+-/* Define to a fallback location of lastlog */
+-#undef PT_LASTLOG_FILE
+-
+-/* Define to a fallback location of utmp */
+-#undef PT_UTMP_FILE
+-
+-/* Define to a fallback location of wtmpx */
+-#undef PT_WTMPX_FILE
+-
+-/* Define to a fallback location of wtmp */
+-#undef PT_WTMP_FILE
+-
+ /* Resource class */
+ #undef RESCLASS
+
+@@ -409,12 +352,6 @@
+ for multibyte characters input */
+ #undef USE_XIM
+
+-/* Define if you want to have utmp/utmpx support */
+-#undef UTMP_SUPPORT
+-
+-/* Define if you want to have wtmp support when utmp/utmpx is enabled */
+-#undef WTMP_SUPPORT
+-
+ /* Define to enable xft support */
+ #undef XFT
+
+@@ -451,10 +388,6 @@
+ /* Enable declarations of msg_control and msg_controllen on Solaris */
+ #undef _XOPEN_SOURCE
+
+-/* Enable declarations in utmp.h on Solaris when the XPG4v2 namespace is
+- active */
+-#undef __EXTENSIONS__
+-
+ /* Define to `int' if <sys/types.h> doesn't define. */
+ #undef gid_t
+
+--- ./libptytty/ptytty.m4.orig 2015-05-11 17:24:03.000000000 -0500
++++ ./libptytty/ptytty.m4 2018-03-31 11:24:41.669415706 -0500
+@@ -51,143 +51,6 @@
+ fi
+ ])
+
+-AC_DEFUN([UTMP_CHECK],
+-[
+-support_utmp=yes
+-support_wtmp=yes
+-support_lastlog=yes
+-
+-AC_ARG_ENABLE(utmp,
+- [AS_HELP_STRING([--enable-utmp],[enable utmp (utmpx) support])],
+- [if test x$enableval = xyes -o x$enableval = xno; then
+- support_utmp=$enableval
+- fi])
+-
+-AC_ARG_ENABLE(wtmp,
+- [AS_HELP_STRING([--enable-wtmp],[enable wtmp (wtmpx) support (requires --enable-utmp)])],
+- [if test x$enableval = xyes -o x$enableval = xno; then
+- support_wtmp=$enableval
+- fi])
+-
+-AC_ARG_ENABLE(lastlog,
+- [AS_HELP_STRING([--enable-lastlog],[enable lastlog support (requires --enable-utmp)])],
+- [if test x$enableval = xyes -o x$enableval = xno; then
+- support_lastlog=$enableval
+- fi])
+-
+-if test x$support_utmp = xyes; then
+- AC_DEFINE(UTMP_SUPPORT, 1, Define if you want to have utmp/utmpx support)
+-fi
+-if test x$support_wtmp = xyes; then
+- AC_DEFINE(WTMP_SUPPORT, 1, Define if you want to have wtmp support when utmp/utmpx is enabled)
+-fi
+-if test x$support_lastlog = xyes; then
+- AC_DEFINE(LASTLOG_SUPPORT, 1, Define if you want to have lastlog support when utmp/utmpx is enabled)
+-fi
+-
+-AC_CHECK_FUNCS( \
+- updwtmp \
+- updwtmpx \
+- updlastlogx \
+-)
+-
+-AC_CHECK_HEADERS(lastlog.h)
+-
+-case $host in
+- *-*-solaris*)
+- AC_DEFINE(__EXTENSIONS__, 1, Enable declarations in utmp.h on Solaris when the XPG4v2 namespace is active)
+- ;;
+-esac
+-
+-dnl# --------------------------------------------------------------------------
+-dnl# DO ALL UTMP AND WTMP CHECKING
+-dnl# --------------------------------------------------------------------------
+-dnl# check for host field in utmp structure
+-
+-dnl# --------------------------------------------
+-AC_CHECK_HEADERS(utmp.h, [
+-AC_CHECK_TYPES([struct utmp], [], [], [
+-#include <sys/types.h>
+-#include <utmp.h>
+-])
+-
+-AC_CHECK_MEMBER([struct utmp.ut_host],
+-[AC_DEFINE(HAVE_UTMP_HOST, 1, Define if struct utmp contains ut_host)], [], [
+-#include <sys/types.h>
+-#include <utmp.h>
+-])
+-
+-AC_CHECK_MEMBER([struct utmp.ut_pid],
+-[AC_DEFINE(HAVE_UTMP_PID, 1, Define if struct utmp contains ut_pid)], [], [
+-#include <sys/types.h>
+-#include <utmp.h>
+-])
+-]) dnl# AC_CHECK_HEADERS(utmp.h
+-
+-dnl# --------------------------------------------
+-
+-AC_CHECK_HEADERS(utmpx.h, [
+-AC_CHECK_TYPES([struct utmpx], [], [], [
+-#include <sys/types.h>
+-#include <utmpx.h>
+-])
+-
+-AC_CHECK_MEMBER([struct utmpx.ut_host],
+-[AC_DEFINE(HAVE_UTMPX_HOST, 1, Define if struct utmpx contains ut_host)], [], [
+-#include <sys/types.h>
+-#include <utmpx.h>
+-])
+-]) dnl# AC_CHECK_HEADERS(utmpx.h
+-
+-dnl# --------------------------------------------------------------------------
+-dnl# check for struct lastlog
+-AC_CHECK_TYPES([struct lastlog], [], [], [
+-#include <sys/types.h>
+-#include <utmp.h>
+-#ifdef HAVE_LASTLOG_H
+-#include <lastlog.h>
+-#endif
+-])
+-
+-dnl# check for struct lastlogx
+-AC_CHECK_TYPES([struct lastlogx], [], [], [
+-#include <sys/types.h>
+-#include <utmpx.h>
+-#ifdef HAVE_LASTLOG_H
+-#include <lastlog.h>
+-#endif
+-])
+-
+-dnl# --------------------------------------------------------------------------
+-dnl# FIND FILES
+-dnl# --------------------------------------------------------------------------
+-
+-dnl# find utmp
+-PT_FIND_FILE([utmp], [PT_UTMP_FILE],
+-["/var/run/utmp" "/var/adm/utmp" "/etc/utmp" "/usr/etc/utmp" "/usr/adm/utmp"])
+-
+-dnl# --------------------------------------------------------------------------
+-
+-dnl# find wtmp
+-PT_FIND_FILE([wtmp], [PT_WTMP_FILE],
+-["/var/log/wtmp" "/var/adm/wtmp" "/etc/wtmp" "/usr/etc/wtmp" "/usr/adm/wtmp"])
+-dnl# --------------------------------------------------------------------------
+-
+-dnl# find wtmpx
+-PT_FIND_FILE([wtmpx], [PT_WTMPX_FILE],
+-["/var/log/wtmpx" "/var/adm/wtmpx"])
+-dnl# --------------------------------------------------------------------------
+-
+-dnl# find lastlog
+-PT_FIND_FILE([lastlog], [PT_LASTLOG_FILE],
+-["/var/log/lastlog" "/var/adm/lastlog"])
+-dnl# --------------------------------------------------------------------------
+-
+-dnl# find lastlogx
+-PT_FIND_FILE([lastlogx], [PT_LASTLOGX_FILE],
+-["/var/log/lastlogx" "/var/adm/lastlogx"])
+-])
+-
+ AC_DEFUN([SCM_RIGHTS_CHECK],
+ [
+ AH_TEMPLATE([_XOPEN_SOURCE], [Enable declarations of msg_control and msg_controllen on Solaris])
+--- ./libptytty/src/proxy.C.orig 2015-04-11 13:27:01.000000000 -0500
++++ ./libptytty/src/proxy.C 2018-03-31 11:25:17.787419082 -0500
+@@ -1,351 +0,0 @@
+-/*----------------------------------------------------------------------*
+- * File: proxy.C
+- *----------------------------------------------------------------------*
+- *
+- * All portions of code are copyright by their respective author/s.
+- * Copyright (c) 2006 Marc Lehmann <schmorp@schmorp.de>
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License as published by
+- * the Free Software Foundation; either version 2 of the License, or
+- * (at your option) any later version.
+- *
+- * This program is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+- * GNU General Public License for more details.
+- *
+- * You should have received a copy of the GNU General Public License
+- * along with this program; if not, write to the Free Software
+- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+- *---------------------------------------------------------------------*/
+-
+-#include "config.h"
+-
+-#include "ptytty.h"
+-
+-#include "estl.h"
+-
+-#include <stdio.h>
+-#include <string.h>
+-#include <signal.h>
+-
+-#include <sys/types.h>
+-#include <sys/socket.h>
+-#include <unistd.h>
+-#include <fcntl.h>
+-#include <errno.h>
+-
+-// helper/proxy support
+-
+-#if PTYTTY_HELPER
+-
+-static int sock_fd = -1, lock_fd = -1;
+-static int helper_pid;
+-
+-struct command
+-{
+- enum { get, login, destroy } type;
+-
+- ptytty *id;
+-
+- bool login_shell;
+- int cmd_pid;
+- char hostname[512]; // arbitrary, but should be plenty
+-};
+-
+-struct ptytty_proxy : ptytty
+-{
+- ptytty *id;
+-
+- ptytty_proxy ()
+- : id(0)
+- {
+- }
+-
+- ~ptytty_proxy ();
+-
+- bool get ();
+- void login (int cmd_pid, bool login_shell, const char *hostname);
+-};
+-
+-#if PTYTTY_REENTRANT
+-# define NEED_TOKEN do { char ch; read (lock_fd, &ch , 1); } while (0)
+-# define GIVE_TOKEN write (lock_fd, &lock_fd, 1)
+-#else
+-# define NEED_TOKEN (void)0
+-# define GIVE_TOKEN (void)0
+-#endif
+-
+-bool
+-ptytty_proxy::get ()
+-{
+- NEED_TOKEN;
+-
+- command cmd;
+-
+- cmd.type = command::get;
+-
+- write (sock_fd, &cmd, sizeof (cmd));
+-
+- if (read (sock_fd, &id, sizeof (id)) != sizeof (id))
+- PTYTTY_FATAL ("protocol error while creating pty using helper process, aborting.\n");
+-
+- if (!id)
+- {
+- GIVE_TOKEN;
+- return false;
+- }
+-
+- if ((pty = recv_fd (sock_fd)) < 0
+- || (tty = recv_fd (sock_fd)) < 0)
+- PTYTTY_FATAL ("protocol error while reading pty/tty fds from helper process, aborting.\n");
+-
+- GIVE_TOKEN;
+- return true;
+-}
+-
+-void
+-ptytty_proxy::login (int cmd_pid, bool login_shell, const char *hostname)
+-{
+- NEED_TOKEN;
+-
+- command cmd;
+-
+- cmd.type = command::login;
+- cmd.id = id;
+- cmd.cmd_pid = cmd_pid;
+- cmd.login_shell = login_shell;
+- strncpy (cmd.hostname, hostname, sizeof (cmd.hostname));
+-
+- write (sock_fd, &cmd, sizeof (cmd));
+-
+- GIVE_TOKEN;
+-}
+-
+-ptytty_proxy::~ptytty_proxy ()
+-{
+- if (id)
+- {
+- close_tty ();
+-
+- if (pty >= 0)
+- close (pty);
+-
+- NEED_TOKEN;
+-
+- command cmd;
+-
+- cmd.type = command::destroy;
+- cmd.id = id;
+-
+- write (sock_fd, &cmd, sizeof (cmd));
+-
+- GIVE_TOKEN;
+- }
+-}
+-
+-static
+-void serve ()
+-{
+- command cmd;
+- vector<ptytty *> ptys;
+-
+- for (;;)
+- {
+- GIVE_TOKEN;
+-
+- if (read (sock_fd, &cmd, sizeof (command)) != sizeof (command))
+- break;
+-
+- if (cmd.type == command::get)
+- {
+- // -> id ptyfd ttyfd
+- cmd.id = new ptytty_unix;
+-
+- if (cmd.id->get ())
+- {
+- write (sock_fd, &cmd.id, sizeof (cmd.id));
+- ptys.push_back (cmd.id);
+-
+- ptytty::send_fd (sock_fd, cmd.id->pty);
+- ptytty::send_fd (sock_fd, cmd.id->tty);
+-
+- cmd.id->close_tty ();
+- }
+- else
+- {
+- delete cmd.id;
+- cmd.id = 0;
+- write (sock_fd, &cmd.id, sizeof (cmd.id));
+- }
+- }
+- else if (cmd.type == command::login)
+- {
+-#if UTMP_SUPPORT
+- if (find (ptys.begin (), ptys.end (), cmd.id) != ptys.end ())
+- {
+- cmd.hostname[sizeof (cmd.hostname) - 1] = 0;
+- cmd.id->login (cmd.cmd_pid, cmd.login_shell, cmd.hostname);
+- }
+-#endif
+- }
+- else if (cmd.type == command::destroy)
+- {
+- vector<ptytty *>::iterator pty = find (ptys.begin (), ptys.end (), cmd.id);
+-
+- if (pty != ptys.end ())
+- {
+- delete *pty;
+- ptys.erase (pty);
+- }
+- }
+- else
+- break;
+-
+- NEED_TOKEN;
+- }
+-
+- // destroy all ptys
+- for (vector<ptytty *>::iterator i = ptys.end (); i-- > ptys.begin (); )
+- delete *i;
+-}
+-
+-void
+-ptytty::use_helper ()
+-{
+- if (sock_fd >= 0)
+- return;
+-
+- int sv[2];
+-
+- if (socketpair (AF_UNIX, SOCK_STREAM, 0, sv))
+- PTYTTY_FATAL ("could not create socket to communicate with pty/sessiondb helper, aborting.\n");
+-
+-#if PTYTTY_REENTRANT
+- int lv[2];
+-
+- if (socketpair (AF_UNIX, SOCK_STREAM, 0, lv))
+- PTYTTY_FATAL ("could not create socket to communicate with pty/sessiondb helper, aborting.\n");
+-#endif
+-
+- helper_pid = fork ();
+-
+- if (helper_pid < 0)
+- PTYTTY_FATAL ("could not create pty/sessiondb helper process, aborting.\n");
+-
+- if (helper_pid)
+- {
+- // client, process
+- sock_fd = sv[0];
+- close (sv[1]);
+- fcntl (sock_fd, F_SETFD, FD_CLOEXEC);
+-#if PTYTTY_REENTRANT
+- lock_fd = lv[0];
+- close (lv[1]);
+- fcntl (lock_fd, F_SETFD, FD_CLOEXEC);
+-#endif
+- }
+- else
+- {
+- // server, pty-helper
+- sock_fd = sv[1];
+-#if PTYTTY_REENTRANT
+- lock_fd = lv[1];
+-#endif
+-
+- chdir ("/");
+-
+- signal (SIGHUP, SIG_IGN);
+- signal (SIGTERM, SIG_IGN);
+- signal (SIGINT, SIG_IGN);
+- signal (SIGPIPE, SIG_IGN);
+-
+- for (int fd = 0; fd < 1023; fd++)
+- if (fd != sock_fd && fd != lock_fd)
+- close (fd);
+-
+- serve ();
+- _exit (EXIT_SUCCESS);
+- }
+-}
+-
+-#endif
+-
+-ptytty *
+-ptytty::create ()
+-{
+-#if PTYTTY_HELPER
+- if (helper_pid)
+- // use helper process
+- return new ptytty_proxy;
+- else
+-#endif
+- return new ptytty_unix;
+-}
+-
+-void
+-ptytty::sanitise_stdfd ()
+-{
+- // sanitise stdin/stdout/stderr to point to *something*.
+- for (int fd = 0; fd <= 2; ++fd)
+- if (fcntl (fd, F_GETFL) < 0 && errno == EBADF)
+- {
+- int fd2 = open ("/dev/tty", fd ? O_WRONLY : O_RDONLY);
+-
+- if (fd2 < 0)
+- fd2 = open ("/dev/null", fd ? O_WRONLY : O_RDONLY);
+-
+- if (fd2 != fd)
+- PTYTTY_FATAL ("unable to sanitise fds, aborting.\n");
+- }
+-}
+-
+-void
+-ptytty::init ()
+-{
+- sanitise_stdfd ();
+-
+- uid_t uid = getuid ();
+- gid_t gid = getgid ();
+-
+- // before doing anything else, check for setuid/setgid operation,
+- // start the helper process and drop privileges
+- if (uid != geteuid ()
+- || gid != getegid ())
+- {
+-#if PTYTTY_HELPER
+- use_helper ();
+-#else
+- PTYTTY_WARN ("running setuid/setgid without pty helper compiled in, continuing unprivileged.\n");
+-#endif
+-
+- drop_privileges ();
+- }
+-}
+-
+-void
+-ptytty::drop_privileges ()
+-{
+- uid_t uid = getuid ();
+- gid_t gid = getgid ();
+-
+- // drop privileges
+-#if HAVE_SETRESUID
+- setresgid (gid, gid, gid);
+- setresuid (uid, uid, uid);
+-#elif HAVE_SETREUID
+- setregid (gid, gid);
+- setreuid (uid, uid);
+-#elif HAVE_SETUID
+- setgid (gid);
+- setuid (uid);
+-#else
+-# error no way to drop privileges, configure failed?
+-#endif
+-
+- if (uid != geteuid ()
+- || gid != getegid ())
+- PTYTTY_FATAL ("unable to drop privileges, aborting.\n");
+-}
+-
+--- ./libptytty/src/ptytty.h.orig 2014-11-16 06:22:34.000000000 -0600
++++ ./libptytty/src/ptytty.h 2018-03-31 11:21:57.530400360 -0500
+@@ -8,23 +8,10 @@
+ # define NO_SETOWNER_TTYDEV 1
+ #endif
+
+-#if UTMP_SUPPORT
+-# if defined(__GLIBC__)
+-# undef HAVE_STRUCT_UTMPX
+-# endif
+-
+-# if ! defined(HAVE_STRUCT_UTMPX) && ! defined(HAVE_STRUCT_UTMP)
+-# error cannot build with utmp support - no utmp or utmpx struct found
+-# endif
+-
+-#endif
+-
+ struct ptytty_unix : ptytty
+ {
+ char *name;
+
+- void log_session (bool login, const char *hostname);
+-
+ public:
+
+ ptytty_unix ();
+@@ -35,13 +22,10 @@
+
+ void login (int cmd_pid, bool login_shell, const char *hostname);
+
+-#if UTMP_SUPPORT
+- int utmp_pos;
+ int cmd_pid;
+ bool login_shell;
+
+ void logout ();
+-#endif
+ };
+
+ #endif
+--- ./libptytty/src/ptytty.C.orig 2015-05-11 17:24:03.000000000 -0500
++++ ./libptytty/src/ptytty.C 2018-03-31 11:21:57.529400360 -0500
+@@ -217,6 +217,29 @@
+ return 0;
+ }
+
++ptytty *
++ptytty::create ()
++{
++ return new ptytty_unix;
++}
++
++void
++ptytty::sanitise_stdfd ()
++{
++ // sanitise stdin/stdout/stderr to point to *something*.
++ for (int fd = 0; fd <= 2; ++fd)
++ if (fcntl (fd, F_GETFL) < 0 && errno == EBADF)
++ {
++ int fd2 = open ("/dev/tty", fd ? O_WRONLY : O_RDONLY);
++
++ if (fd2 < 0)
++ fd2 = open ("/dev/null", fd ? O_WRONLY : O_RDONLY);
++
++ if (fd2 != fd)
++ abort ();
++ }
++}
++
+ void
+ ptytty::close_tty ()
+ {
+@@ -287,16 +310,12 @@
+ ptytty_unix::ptytty_unix ()
+ {
+ name = 0;
+-#if UTMP_SUPPORT
+ cmd_pid = 0;
+-#endif
+ }
+
+ ptytty_unix::~ptytty_unix ()
+ {
+-#if UTMP_SUPPORT
+ logout ();
+-#endif
+ put ();
+ }
+
+@@ -390,18 +409,6 @@
+ }
+ #endif
+
+-#if UTMP_SUPPORT
+-# if defined(HAVE_STRUCT_UTMP) && !defined(HAVE_UTMP_PID)
+- int fd_stdin = dup (STDIN_FILENO);
+- dup2 (tty, STDIN_FILENO);
+-
+- utmp_pos = ttyslot ();
+-
+- dup2 (fd_stdin, STDIN_FILENO);
+- close (fd_stdin);
+-# endif
+-#endif
+-
+ return true;
+ }
+
+--- ./libptytty/src/logging.C.orig 2014-11-16 06:22:34.000000000 -0600
++++ ./libptytty/src/logging.C 2018-03-31 11:21:57.527400360 -0500
+@@ -36,251 +36,8 @@
+
+ #include "ptytty.h"
+
+-#include <sys/types.h>
++#include "utempter.h"
+
+-#if UTMP_SUPPORT
+-
+-#ifdef HAVE_UTMPX_H
+-# include <utmpx.h>
+-#endif
+-#ifdef HAVE_UTMP_H
+-# include <utmp.h>
+-#endif
+-#ifdef HAVE_LASTLOG_H
+-# include <lastlog.h>
+-#endif
+-
+-#if !defined(UTMP_FILE)
+-# if defined(_PATH_UTMP)
+-# define UTMP_FILE _PATH_UTMP
+-# elif defined(PT_UTMP_FILE)
+-# define UTMP_FILE PT_UTMP_FILE
+-# endif
+-#endif
+-#if !defined(WTMP_FILE)
+-# if defined(_PATH_WTMP)
+-# define WTMP_FILE _PATH_WTMP
+-# elif defined(PT_WTMP_FILE)
+-# define WTMP_FILE PT_WTMP_FILE
+-# endif
+-#endif
+-#if !defined(WTMPX_FILE)
+-# if defined(_PATH_WTMPX)
+-# define WTMPX_FILE _PATH_WTMPX
+-# elif defined(PT_WTMPX_FILE)
+-# define WTMPX_FILE PT_WTMPX_FILE
+-# endif
+-#endif
+-#if !defined(LASTLOG_FILE)
+-# if defined(_PATH_LASTLOG)
+-# define LASTLOG_FILE _PATH_LASTLOG
+-# elif defined(PT_LASTLOG_FILE)
+-# define LASTLOG_FILE PT_LASTLOG_FILE
+-# endif
+-#endif
+-#if !defined(LASTLOGX_FILE)
+-# if defined(_PATH_LASTLOGX)
+-# define LASTLOGX_FILE _PATH_LASTLOGX
+-# elif defined(PT_LASTLOGX_FILE)
+-# define LASTLOGX_FILE PT_LASTLOGX_FILE
+-# endif
+-#endif
+-
+-#include <pwd.h>
+-
+-#include <stdio.h>
+-#include <string.h>
+-
+-#include <sys/stat.h>
+-#include <fcntl.h>
+-#include <unistd.h>
+-#include <time.h>
+-#include <errno.h>
+-
+-/*
+- * BSD style utmp entry
+- * ut_line, ut_name, ut_host, ut_time
+- * SYSV style utmp (and utmpx) entry
+- * ut_user, ut_id, ut_line, ut_pid, ut_type, ut_exit, ut_time
+- */
+-
+-/* ------------------------------------------------------------------------- */
+-/*
+- * Write a BSD style utmp entry
+- */
+-#if defined(HAVE_STRUCT_UTMP) && !defined(HAVE_UTMP_PID)
+-static void
+-write_bsd_utmp (int utmp_pos, struct utmp *ut)
+-{
+- int fd;
+-
+- if (utmp_pos <= 0 || (fd = open (UTMP_FILE, O_WRONLY)) == -1)
+- return;
+-
+- if (lseek (fd, (off_t) (utmp_pos * sizeof (struct utmp)), SEEK_SET) != -1)
+- write (fd, ut, sizeof (struct utmp));
+- close (fd);
+-}
+-#endif
+-
+-/* ------------------------------------------------------------------------- */
+-/*
+- * Update a BSD style wtmp entry
+- */
+-#if defined(WTMP_SUPPORT) && !defined(HAVE_UPDWTMP) && defined(HAVE_STRUCT_UTMP)
+-static void
+-update_wtmp (const char *fname, const struct utmp *ut)
+-{
+- int fd, gotlock, retry;
+- struct flock lck; /* fcntl locking scheme */
+- struct stat sbuf;
+-
+- if ((fd = open (fname, O_WRONLY | O_APPEND, 0)) < 0)
+- return;
+-
+- lck.l_whence = SEEK_END; /* start lock at current eof */
+- lck.l_len = 0; /* end at ``largest possible eof'' */
+- lck.l_start = 0;
+- lck.l_type = F_WRLCK; /* we want a write lock */
+-
+- /* attempt lock with F_SETLK; F_SETLKW would cause a deadlock! */
+- for (retry = 10, gotlock = 0; retry--;)
+- if (fcntl (fd, F_SETLK, &lck) != -1)
+- {
+- gotlock = 1;
+- break;
+- }
+- else if (errno != EAGAIN && errno != EACCES)
+- break;
+-
+- if (gotlock)
+- {
+- if (fstat (fd, &sbuf) == 0)
+- if (write (fd, ut, sizeof (struct utmp)) != sizeof (struct utmp))
+- ftruncate (fd, sbuf.st_size); /* remove bad writes */
+-
+- lck.l_type = F_UNLCK; /* unlocking the file */
+- fcntl (fd, F_SETLK, &lck);
+- }
+-
+- close (fd);
+-}
+-#endif
+-
+-/* ------------------------------------------------------------------------- */
+-#ifdef LASTLOG_SUPPORT
+-static void
+-update_lastlog (const char *pty, const char *host)
+-{
+-# if defined(HAVE_STRUCT_LASTLOGX) && defined(HAVE_UPDLASTLOGX)
+- struct lastlogx llx;
+-# endif
+-# ifdef HAVE_STRUCT_LASTLOG
+- int fd;
+- struct lastlog ll;
+-# endif
+-
+-# if defined(HAVE_STRUCT_LASTLOGX) && defined(HAVE_UPDLASTLOGX)
+- memset (&llx, 0, sizeof (llx));
+- llx.ll_tv.tv_sec = time (NULL);
+- llx.ll_tv.tv_usec = 0;
+- strncpy (llx.ll_line, pty, sizeof (llx.ll_line));
+- strncpy (llx.ll_host, host, sizeof (llx.ll_host));
+- updlastlogx (LASTLOGX_FILE, getuid (), &llx);
+-# endif
+-
+-# ifdef HAVE_STRUCT_LASTLOG
+- memset (&ll, 0, sizeof (ll));
+- ll.ll_time = time (NULL);
+- strncpy (ll.ll_line, pty, sizeof (ll.ll_line));
+- strncpy (ll.ll_host, host, sizeof (ll.ll_host));
+- if ((fd = open (LASTLOG_FILE, O_RDWR)) != -1)
+- {
+- if (lseek (fd, (off_t) (getuid () * sizeof (ll)),
+- SEEK_SET) != -1)
+- write (fd, &ll, sizeof (ll));
+- close (fd);
+- }
+-# endif /* HAVE_STRUCT_LASTLOG */
+-}
+-#endif /* LASTLOG_SUPPORT */
+-
+-#if defined(HAVE_UTMP_PID) || defined(HAVE_STRUCT_UTMPX)
+-static void
+-fill_id (char *id, const char *line, size_t id_size)
+-{
+- size_t len = strlen (line);
+-
+- if (len > id_size)
+- line += len - id_size;
+- strncpy (id, line, id_size);
+-}
+-#endif
+-
+-#ifdef HAVE_STRUCT_UTMP
+-static void
+-fill_utmp (struct utmp *ut, bool login, int pid, const char *line, const char *user, const char *host)
+-{
+- memset (ut, 0, sizeof (struct utmp));
+-
+- strncpy (ut->ut_line, line, sizeof (ut->ut_line));
+-# ifdef HAVE_UTMP_PID
+- fill_id (ut->ut_id, line, sizeof (ut->ut_id));
+- ut->ut_pid = pid;
+- ut->ut_type = login ? USER_PROCESS : DEAD_PROCESS;
+-# endif
+- ut->ut_time = time (NULL);
+-
+- if (login)
+- {
+-# ifdef HAVE_UTMP_PID
+- strncpy (ut->ut_user, user, sizeof (ut->ut_user));
+-# else
+- strncpy (ut->ut_name, user, sizeof (ut->ut_name));
+-# endif
+-# ifdef HAVE_UTMP_HOST
+- strncpy (ut->ut_host, host, sizeof (ut->ut_host));
+-# endif
+- }
+-}
+-#endif
+-
+-#ifdef HAVE_STRUCT_UTMPX
+-static void
+-fill_utmpx (struct utmpx *utx, bool login, int pid, const char *line, const char *user, const char *host)
+-{
+- memset (utx, 0, sizeof (struct utmpx));
+-
+- // posix says that ut_line is not meaningful for DEAD_PROCESS
+- // records, but most implementations of last use ut_line to
+- // associate records in wtmp file
+- strncpy (utx->ut_line, line, sizeof (utx->ut_line));
+- fill_id (utx->ut_id, line, sizeof (utx->ut_id));
+- utx->ut_pid = pid;
+- utx->ut_type = login ? USER_PROCESS : DEAD_PROCESS;
+- utx->ut_tv.tv_sec = time (NULL);
+- utx->ut_tv.tv_usec = 0;
+-
+- // posix says that ut_user is not meaningful for DEAD_PROCESS
+- // records, but solaris utmp_update helper requires that the ut_user
+- // field of a DEAD_PROCESS entry matches the one of an existing
+- // USER_PROCESS entry for the same line, if any
+- strncpy (utx->ut_user, user, sizeof (utx->ut_user));
+-
+- if (login)
+- {
+-# ifdef HAVE_UTMPX_HOST
+- strncpy (utx->ut_host, host, sizeof (utx->ut_host));
+-# endif
+- }
+-}
+-#endif
+-
+-/* ------------------------------------------------------------------------- */
+-
+-/*
+- * make and write utmp and wtmp entries
+- */
+ void
+ ptytty_unix::login (int cmd_pid, bool login_shell, const char *hostname)
+ {
+@@ -290,97 +47,17 @@
+ this->cmd_pid = cmd_pid;
+ this->login_shell = login_shell;
+
+- log_session (true, hostname);
+-}
+-
+-void
+-ptytty_unix::log_session (bool login, const char *hostname)
+-{
+- struct passwd *pwent = getpwuid (getuid ());
+- const char *user = (pwent && pwent->pw_name) ? pwent->pw_name : "?";
+-
+- const char *pty = name;
+-
+- if (!strncmp (pty, "/dev/", 5))
+- pty += 5; /* skip /dev/ prefix */
+-
+-#ifdef HAVE_STRUCT_UTMP
+- struct utmp *tmput;
+- struct utmp ut;
+- fill_utmp (&ut, login, cmd_pid, pty, user, hostname);
+-#endif
+-
+-#ifdef HAVE_STRUCT_UTMPX
+- struct utmpx *tmputx;
+- struct utmpx utx;
+- fill_utmpx (&utx, login, cmd_pid, pty, user, hostname);
+-#endif
+-
+-#ifdef HAVE_STRUCT_UTMP
+-# ifdef HAVE_UTMP_PID
+- setutent ();
+- if (login || ((tmput = getutid (&ut)) && tmput->ut_pid == cmd_pid))
+- pututline (&ut);
+- endutent ();
+-# else
+- write_bsd_utmp (utmp_pos, &ut);
+-# endif
+-#endif
+-
+-#ifdef HAVE_STRUCT_UTMPX
+- setutxent ();
+- if (login || ((tmputx = getutxid (&utx)) && tmputx->ut_pid == cmd_pid))
+- pututxline (&utx);
+- endutxent ();
+-#endif
+-
+-#ifdef WTMP_SUPPORT
+- if (login_shell)
+- {
+-# ifdef HAVE_STRUCT_UTMP
+-# ifdef HAVE_UPDWTMP
+- updwtmp (WTMP_FILE, &ut);
+-# else
+- update_wtmp (WTMP_FILE, &ut);
+-# endif
+-# endif
+-# if defined(HAVE_STRUCT_UTMPX) && defined(HAVE_UPDWTMPX)
+- updwtmpx (WTMPX_FILE, &utx);
+-# endif
+- }
+-#endif
+-
+-#ifdef LASTLOG_SUPPORT
+- if (login_shell)
+- if (login)
+- {
+- if (pwent)
+- update_lastlog (pty, hostname);
+- else
+- PTYTTY_WARN ("no entry in password file, not updating lastlog.\n");
+- }
+-#endif
++ utempter_add_record(pty, hostname);
+ }
+
+-/* ------------------------------------------------------------------------- */
+-/*
+- * remove utmp and wtmp entries
+- */
+ void
+ ptytty_unix::logout ()
+ {
+ if (!cmd_pid)
+ return;
+
+- log_session (false, 0);
++ utempter_remove_record(pty);
+
+ cmd_pid = 0;
+ }
+
+-#else
+-void
+-ptytty_unix::login (int cmd_pid, bool login_shell, const char *hostname)
+-{
+-}
+-#endif
+-
+--- ./src/Makefile.in.orig 2016-01-23 14:09:22.000000000 -0600
++++ ./src/Makefile.in 2018-03-31 11:21:43.963399092 -0500
+@@ -64,10 +64,10 @@
+ all: allbin
+
+ rxvt: rxvt.o $(COMMON)
+- $(LINK) -o $@ rxvt.o $(COMMON) $(LIBS) $(XLIB) $(PERLLIB)
++ $(LINK) -o $@ rxvt.o $(COMMON) $(LIBS) $(XLIB) $(PERLLIB) -lutempter
+
+ rxvtd: rxvtd.o $(COMMON) $(COMMON_DAEMON)
+- $(LINK) -o $@ rxvtd.o $(COMMON) $(COMMON_DAEMON) $(LIBS) $(XLIB) $(PERLLIB)
++ $(LINK) -o $@ rxvtd.o $(COMMON) $(COMMON_DAEMON) $(LIBS) $(XLIB) $(PERLLIB) -lutempter
+
+ rxvtc: rxvtc.o $(COMMON_DAEMON) fdpass_wrapper.o
+ $(LINK) -o $@ rxvtc.o $(COMMON_DAEMON) fdpass_wrapper.o $(LIBS)
+@@ -205,7 +205,7 @@
+ ptytty_wrapper.o: ../libptytty/src/libptytty.h rxvtperl.h hookinc.h rsinc.h
+ ptytty_wrapper.o: optinc.h ../libptytty/src/logging.C
+ ptytty_wrapper.o: ../libptytty/src/ptytty.h ../libptytty/src/ptytty_conf.h
+-ptytty_wrapper.o: ../libptytty/src/proxy.C ../libptytty/src/ptytty.C
++ptytty_wrapper.o: ../libptytty/src/ptytty.C
+ rxvt.o: ../config.h rxvt.h feature.h ../libptytty/src/ecb.h encoding.h
+ rxvt.o: rxvtutil.h ../libptytty/src/estl.h emman.h rxvtfont.h rxvttoolkit.h
+ rxvt.o: ev_cpp.h ../config.h ../libev/ev++.h ../libev/ev.h callback.h
+--- ./src/rxvt.C.orig 2014-12-12 19:00:23.000000000 -0600
++++ ./src/rxvt.C 2018-03-31 11:21:43.965399092 -0500
+@@ -30,7 +30,7 @@
+ main (int argc, char *argv[])
+ try
+ {
+- ptytty::init ();
++ ptytty::sanitise_stdfd ();
+ rxvt_init ();
+
+ rxvt_term *t = new rxvt_term;
+--- ./src/ptytty_wrapper.C.orig 2014-12-12 19:00:23.000000000 -0600
++++ ./src/ptytty_wrapper.C 2018-03-31 11:21:43.961399092 -0500
+@@ -7,5 +7,4 @@
+ #define PTYTTY_WARN rxvt_warn
+
+ #include "logging.C"
+-#include "proxy.C"
+ #include "ptytty.C"
+--- ./src/rxvtd.C.orig 2014-12-26 16:34:13.000000000 -0600
++++ ./src/rxvtd.C 2018-03-31 11:21:43.960399092 -0500
+@@ -227,7 +227,7 @@
+ int
+ main (int argc, char *argv[])
+ {
+- ptytty::init ();
++ ptytty::sanitise_stdfd ();
+
+ static char opt_fork, opt_opendisplay, opt_quiet;
+ #if ENABLE_PERL