--- libptytty/README 2006/01/21 21:54:15 1.1 +++ libptytty/README 2006/09/11 14:11:26 1.6 @@ -1,14 +1,212 @@ NAME - libpty - OS independent and secure pty/tty and utmp/wtmp/lastlog + libptytty - OS independent and secure pty/tty and utmp/wtmp/lastlog handling SYNOPSIS - -lpty + cc ... -lptytty + + #include + + // 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 loginshell from C using libptytty. DESCRIPTION -THE pty CLASS - new pty - ... + 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. + +SECURITY CONSIDERATIONS + *It is of paramount importance that you at least read the following + paragraph!* + + If you are 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" are more + useful. + +C++ INTERFACE: THE ptytty CLASS + STATIC METHODS + ptytty::init () + The default way to initialise libptytty. Must be called imemdiately + as the first thing in the "main" function, or earlier e.g. during + static construction time. The earlier, the better. + + This method 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. + + 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 inconvinient 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. + + ptytty::drop_privileges () + Drops privileges completely, i.e. sets real, effective and saved + user id to the real user id. Also aborts if this cannot be achieved. + Useful to make sure that the process doesn't run with special + privileges. + + 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 convinience 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 sucecssful and -1 otherwise. This method + is only exposed for your convinience 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 to + "ptytty::get". + + bool success = pty->get () + Tries to find, allocate and initialise a new pty/tty pair. Returns + "true" when successful. + + 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". BUGS You kiddin'?