Provided by: libptytty-dev_2.0-1_amd64 bug

NAME

       libptytty - OS independent and secure pty/tty and utmp/wtmp/lastlog handling

SYNOPSIS

          cc ... -lptytty

          #include <libptytty.h>

          // C++
          ptytty *pty = ptytty::create ();

          if (!pty->get ())
            // error allocating pty

          if (we want utmp)
            pty->login (process_pid, 0, "remote.host");
          else if (we want utmp AND wtmp/lastlog)
            pty->login (process_pid, 1, "remote.host");

          // we are done with it
          delete pty;

          // C
          PTYTTY pty = ptytty_create ();

          if (!ptytty_get (pty))
            // error allocating pty

          if (we want utmp)
            ptytty_login (pty, process_pid, 0, "remote.host");
          else if (we want utmp AND wtmp/lastlog)
            ptytty_login (pty, process_pid, 1, "remote.host");

          // we are done with it
          ptytty_delete (pty);

       See also the eg/ directory, which currently contains the c-sample.c file that spawns a
       login shell from C using libptytty.

DESCRIPTION

       Libptytty is a small library that offers pseudo-tty management in an OS-independent way.
       It was created out of frustration over the many differences of pty/tty handling in
       different operating systems for the use inside "rxvt-unicode".

       In addition to offering mere pty/tty management, it also offers session database support
       (utmp and optional wtmp/lastlog updates for login shells).

       It also supports fork'ing after startup and dropping privileges in the calling process, so
       in case the calling process gets compromised by the user starting the program there is
       less to gain, as only the helper process runs with privileges (e.g. setuid/setgid), which
       reduces the area of attack immensely.

       Libptytty is written in C++, but it also offers a C-only API.

INSTALLATION

       libptytty uses "CMake" as build system. To build libptytty, install "CMake" and run the
       following commands from either the libptytty source directory or a separate build
       directory:

          cmake -DCMAKE_INSTALL_PREFIX=<prefix> -DBUILD_SHARED_LIBS=ON <path/to/libptytty>
          cmake --build .
          cmake --install .

SECURITY CONSIDERATIONS

       It is of paramount importance that you at least read the following paragraph!

       If you write a typical terminal-like program that just wants one or more ptys, you should
       call the "ptytty::init ()" method (C: "ptytty_init ()" function) as the very first thing
       in your program:

          int main (int argc, char *argv[])
          {
             // do nothing here
             ptytty::init ();
             // in C: ptytty_init ();

             // initialise, parse arguments, etc.
          }

       This checks whether the program runs setuid or setgid. If yes then it will fork a helper
       process and drop privileges.

       Some programs need finer control over if and when this helper process is started, and if
       and how to drop privileges. For those programs, the methods "ptytty::use_helper" and
       "ptytty::drop_privileges" (and possibly "ptytty::sanitise_stdfd") are more useful.

C++ INTERFACE: THE ptytty CLASS

   STATIC METHODS
       ptytty::init ()
           The default way to initialise libptytty. Must be called immediately as the first thing
           in the "main" function, or earlier e.g. during static construction time. The earlier,
           the better.

           This method calls "sanitise_stdfd" and then checks whether the program runs with
           setuid/setgid permissions and, if yes, spawns a helper process for pty/tty management.
           It then drops the privileges completely, so the actual program runs without
           setuid/setgid privileges.

           On failure, this method throws a "ptytty_error" exception.

       ptytty::use_helper ()
           Tries to start a helper process that retains privileges even when the calling process
           does not. This is usually called from "ptytty::init" when it detects that the program
           is running setuid or setgid, but can be called manually if it is inconvenient to drop
           privileges at startup, or when you are not running setuid/setgid but want to drop
           privileges (e.g. when running as a root-started daemon).

           This method will try not to start more than one helper process. The same helper
           process can usually be used both from the process starting it and all its fork'ed (not
           exec'ed) children.

           On failure, this method throws a "ptytty_error" exception.

       ptytty::drop_privileges ()
           Drops privileges completely, i.e. sets real, effective and saved user id to the real
           user id. Useful to make sure that the process doesn't run with special privileges.

           On failure, this method throws a "ptytty_error" exception.

       ptytty::sanitise_stdfd ()
           Checks whether file descriptors 0, 1 and 2 (stdin, stdout and stderr) are valid (open)
           and, if not, connects them to /dev/tty or /dev/null if possible. This is necessary
           because libptytty might want to output error messages to those descriptors, which at
           the time of outputting the error message, might be connected to something unsuitable
           opened by the unsuspecting program itself (this can be a security issue).

           On failure, this method throws a "ptytty_error" exception.

       bool success = ptytty::send_fd (int socket, int fd)
           Utility method to send a file descriptor over a unix domain socket. Returns true if
           successful, false otherwise. This method is only exposed for your convenience and is
           not required for normal operation.

       int fd = ptytty::recv_fd (int socket)
           Utility method to receive a file descriptor over a unix domain socket. Returns the fd
           if successful and "-1" otherwise. This method is only exposed for your convenience and
           is not required for normal operation.

       ptytty *pty = ptytty::create ()
           Creates new ptytty object. Creation does not yet do anything besides allocating the
           structure.

           A static method is used because the actual ptytty implementation can differ at
           runtime, so you need a dynamic object creation facility.

   DYNAMIC/SESSION-RELATED DATA MEMBERS AND METHODS
       int pty_fd = pty->pty
       int tty_fd = pty->tty
           These members contain the pty and tty file descriptors, respectively. They initially
           contain "-1" until a successful call to "ptytty::get".

       bool success = pty->get ()
           Tries to find, allocate and initialise a new pty/tty pair. Returns "true" when
           successful.

           If the helper process is running and there is a protocol error, this method throws a
           "ptytty_error" exception.

       pty->login (int cmd_pid, bool login_shell, const char *hostname)
           Creates an entry in the systems session database(s) (utmp, wtmp, lastlog).  "cmd_pid"
           must be the pid of the process representing the session (such as the login shell),
           "login_shell" defines whether the session is associated with a login, which influences
           whether wtmp and lastlog entries are created, and "hostname" should identify the
           "hostname" the user logs in from, which often is the value of the "DISPLAY" variable
           or tty line in case of local logins.

           Calling this method is optional. A session starts at the time of the login call and
           extends until the ptytty object is destroyed.

       pty->close_tty ()
           Closes the tty. Useful after forking in the parent/pty process.

       bool success = pty->make_controlling_tty ()
           Tries to make the pty/tty pair the controlling terminal of the current process. Useful
           after forking in the child/tty process.

       pty->set_utf8_mode (bool on)
           On systems supporting special UTF-8 line disciplines (e.g. Linux), this tries to
           enable this discipline for the given pty. Can be called at any time to change the
           mode.

C INTERFACE: THE ptytty FAMILY OF FUNCTIONS

       ptytty_init ()
           See "ptytty::init ()".

       PTYTTY ptytty_create ()
           Creates a new opaque PTYTTY object and returns it. Do not try to access it in any way
           except by testing it for truthness (e.g. "if (pty) ...."). See "ptytty::create ()".

       int ptytty_pty (PTYTTY ptytty)
           Return the pty file descriptor. See "pty->pty".

       int ptytty_tty (PTYTTY ptytty)
           Return the tty file descriptor. See "pty->tty".

       void ptytty_delete (PTYTTY ptytty)
           Destroys the PTYTTY object, freeing the pty/tty pair and cleaning up the
           utmp/wtmp/lastlog databases, if initialised/used. Same as "delete pty" in C++.

       int ptytty_get (PTYTTY ptytty)
           See "pty->get", returns 0 in case of an error, non-zero otherwise.

       void ptytty_login (PTYTTY ptytty, int cmd_pid, bool login_shell, const char *hostname)
           See "pty->login".

       void ptytty_close_tty (PTYTTY ptytty)
           See "pty->close_tty".

       int ptytty_make_controlling_tty (PTYTTY ptytty)
           See "pty->make_controlling_tty".

       void ptytty_set_utf8_mode (PTYTTY ptytty, int on)
           See "pty->set_utf8_mode".

       void ptytty_drop_privileges ()
           See "ptytty::drop_privileges".

       void ptytty_use_helper ()
           See "ptytty::use_helper".

PORTABILITY

       To date, libptytty has been tested on the following platforms:

       GNU/Linux
       FreeBSD
       NetBSD
       OpenBSD
       macOS
       Solaris
       AIX

BUGS

       You kiddin'?

AUTHORS

       Emanuele Giaquinta <emanuele.giaquinta@gmail.com>, Marc Alexander Lehmann
       <rxvt-unicode@schmorp.de>.