# Virtual terminal login

This package contains tools for running and managing TUI login services on both kernel and user-space virtual terminals. It also contains pre-written service bundles for such TUI login services.

## What the service bundle `run` scripts look like

The `run` scripts are interpreted by `nosh` and are created from a template with the terminal name hardwired.

A `run` script to provide TUI login on kernel virtual terminal `/dev/ttyv4` would be something like this:

>     #!/bin/nosh
>     clearenv
>     # what ttymon(1M) did
>     vc-get-terminal ttyv4
>     setsid
>     open-controlling-terminal --revoke
>     vc-reset-terminal
>     # what login(1M) did
>     login-envuidgid --tui-level ascii
>     local-reaper yes
>     login-giveown-controlling-terminal
>     setuidgid-fromenv
>     userenv-fromenv --default-path --default-tools --default-term --default-timezone --default-locale --set-dbus --set-xdg --set-other
>     chdir-home
>     login-shell

A `run` script for a service to provide TUI login on user-space virtual terminal `/run/dev/vc1` would be something like:

>     #!/bin/nosh
>     clearenv
>     # what ttymon(1M) did
>     vc-get-terminal vc1/tty
>     setsid
>     open-controlling-terminal
>     # what login(1M) did
>     login-envuidgid
>     local-reaper yes
>     login-giveown-controlling-terminal
>     setuidgid-fromenv
>     userenv-fromenv --default-path --default-tools --default-term --default-timezone --default-locale --set-dbus --set-xdg --set-other
>     chdir-home
>     login-shell

## Script composition and the toolset

`run` scripts are recomposable and these chains are an example of that. One can adjust the behaviour of the service to suit particular needs by altering the tool chain or particular tool options.

### `getty` is history, once again.

The use of `getty` in terminal login has been obsolete since 1988, when one of the earliest service management systems for Unix superseded it with its own mechanisms. That is likewise the case here. Login services for virtual terminals do not need `getty` programs, of any flavour; everything remaining that they need being provided by the service management system itself.

What the 1980s Service Access Facility's `sac` and `ttymon` provided by their service management system, are similarly provided by this service management system and chain-loading toolkit as follows:

- `service-manager` handles restarting the service after logout.

- `vc-get-terminal` sets the `TERM` environment variable.

- `open-controlling-terminal` opens the terminal device file and makes it the session's controlling terminal.

- `vc-reset-terminal` re-initializes the terminal device line discipline to sane states and the connected terminal to text mode with the initial character attributes, colours, and character repertoire.

### Virtual terminals are simpler than real terminals

Login services for virtual terminals have to do a lot less than the login services of real terminals, however implemented. Weitse Venema's `agetty` was itself overkill for virtual terminals, and superseded at the turn of the 21st century by the likes of Florian La Roche's `fgetty` or Felix von Leitner's `mingetty`.

Several parts of virtual terminal login services are specialized, hardwiring things that are variable for real terminals, but that are in fact invariant for virtual terminals.

- Serial-line getty programs like Gert Doering's `mgetty` and Weitse Venema's `agetty` deal in things like modem connect strings, serial line speeds, auto-detection by sending BREAK or by pressing the carriage return key multiple times, modem flow control, parity, dial-out interlocks, and suchlike. None of those things apply to virtual terminals; and the tools are simpler for having no dealings with them.

- As their names suggest, `vc-get-terminal` and `vc-reset-terminal` are specialized tools for virtual terminals; those are what they are designed for and what they primarily target. Both the terminal types set by the former and the control sequences emitted by the latter are fixed and determined by the user-space terminal emulator or the terminal emulator in the operating system kernel, and won't change in the way that real terminals attached to serial lines can.

### User space virtual terminals are simpler to handle than kernel virtual terminals.

For user-space virtual terminals especially, login services are even more minimal than "minimal `getty`" was. There are some differences between user-space and kernel virtual terminals that simplify such scripts yet further:

- User-space virtual terminals are created afresh (a new pseudo-terminal back end and front end pair) at service start, so there is no need for the `--revoke` or `--vhangup` option to `open-controlling-terminal`,

- On Linux and BSDs, kernel virtual terminals may retain terminal state from previous logins that affects the viewability of subsequent logins. Existing processes can also end up retaining open file descriptors for the terminal device. To forcibly reset a kernel virtual terminal, using mechanisms that are specific to kernel virtual terminals, one can employ the `--hard-reset`, `--text-mode` and other options to `vc-reset-terminal`; and to forcibly remove access to open file descriptors one can employ the `--vhangup` or `--revoke` options to `open-controlling-terminal`.

  User-space virtual terminals are initialized into a sane state (both the line discipline and the terminal emulator's attributes, colours, and character repertoire) at start and do not have a graphics mode, so there is no need for `vc-reset-terminal` at all.

### `login` is history, too.

Previous versions of this toolkit relied upon the an external `login` program, usually supplied by the operating system, employed in conjunction with chain-loading tools such as `login-banner` and `login-prompt`. With `login-envuidgid` in the chain, none of those are necessary any more.

Some `login` programs employ an idle timeout feature, whereby they exit if login has not completed within a set period of time, such as 60 seconds. Terminal login as a proper service, managed by a service manager, operates suboptimally if the service is continually exiting, because `login` has timed out, every 60 seconds. (At the very least, it is annoying chaff in the service logs.) Thus previous versions of this toolkit used `login-prompt` in the chain, ensuring that the service did not keep timing out and exiting.

`login` presented a dumb "glass TTY" login dialogue, with just the editing functionality provided by the line discipline in the kernel; because it could be potentially be invoked against real terminals of minimal functionality, down to terminals that printed on paper (and so had to use printable characters for line kill and character erase). Logging in on a line printer is still the UI of `login` to this day. But virtual terminals have known minimal capabilities greater than that. They always support cursor addressing; aren't paper; and always support ECMA-48 control sequences for colours and character attributes.

`login-envuidgid` can thus present a full-screen TUI login dialogue. Kernel virtual terminals' support of Unicode is spotty, but on user-space virtual terminals this TUI can moreover employ Unicode box drawing, block, and MouseText characters to provide a pseudo-windowing user interface at least as good as the Apple IIc. (Yes, it is saying something that `login`'s UI can be improved upon by boldly marching forward to the time of the Apple IIc. It's also saying something to observe that virtual terminals have been around since MultiScreen in the days of SCO Unix, but it wasn't until almost a quarter of the way into the 21st century that any terminal login user interface took them up on their capabilities.)

### Setting up user login shell state

The tail end of the chain behaves somewhat akin to Bernstein checkpassword, as this is the conventional way in which login processes are set up:

- `setuidgid-fromenv` drops superuser privileges irrevocably and makes the process run as the account chosen with `login-envuidgid`.

- `userenv-fromenv` sets up the environment variables for that account, including `USER`, `HOME`, and `SHELL`, deliberately doing so with only the privileges of the chosen account, so that it doesn't bypass security restrictions on `login.conf` that might apply to that user.

- `chdir-home` changes to the home directory just set in an environment variable, again deliberately doing so with only the privileges of the chosen account.

- `login-shell` chain-loads the login shell just set in an environment variable.