Normally, there is is a single per-user domterm server process.
When you run the domterm
command it will look for a
domterm server process; if there is no running server, the
domterm
command will “daemonize” itself and become the server.
Otherwise, the domterm
process will be a client,
and forward the requested action to the server.
Communication between a domterm
client and a server
uses Unix domain sockets. By default, this socket will
be bound to the file $XDG_RUNTIME_DIR/domterm/default.socket
.
We make use of Unix file permission to
ensure that the client and the server run on behalf of the same user.
(This could be generalized to allow groups to co-operate, by setting
permissions appropriately, but this has not been explored.)
When you run a new session, that creates a new user process, under control of the domterm server.
The above client-server architecture is same as used by tmux
.
The front-end is a separate program that handles the user interface. It is a web browser or an application that embeds a web browser, like Electron. The domterm server is also a web server that supports both http and the WebSockets protocols. The domterm server forwards output from a user process to the associated browser and vice versa: The server uses a pty for the input/output of the user process, and forwards that input/output to the browser using a websocket connection. Normally, the server creates a new browser instance, with a specified URL. When the corresponding page is loaded, the browser runs JavaScript that requests a WebSocket connection with the server.
The obvious concern is that a different malicious browser might try
to establish a connection with the server, which would allow executing
arbitrary commands on behalf of the user. To thwart that, the server
generates a 60-bit random key, and requires this server key to be present
in any connection attempts. This means the browser JavaScript process
must know the server key when it creates a websocket connection.
The server must pass the key to the browser in a secure way.
A simple way is to pass the key along with the URL used to start
the browser, but that would typically require the key to be
part of the browser’s command-line, which is not secure.
(It can can viewed with tools like ps
.)
FIXME - OBSOSLTE:
Instead, the server creates a new file .domterm/default.html
in the user’s home directory, and uses that as the URL:
$ ${BROWSER} "file://${HOME}/.domain/default.html"
This file (only readable by the user) includes the following:
DomTerm.server_key = '${SERVER_KEY}';
The ${SERVER_KEY}
is substituted when the file is created,
and used when the browser needs to make a websocket connection to the
server.
Again, we depend on Unix file permissions so only a process running
as the correct user can read default.html
, extract the
server key, and make a valid connection back to the server.
Obviously, it could be very useful to handle networked connections,
with a browser on one machine managing a user process on another.
While one can always run ssh
, this does not support
detaching from and re-attaching to a session smoothly.
For now, you have to use ssh
in combination with tmux
or screen
; we hope to have a smoother interface after studying
the issue. It would presumably use forwarding using ssh,
or https
, or a combination.
Some related links