descriptionWraps line-based interactive programs for use over gemini
ownermbays@sdf.org
last changeSat, 22 Jul 2023 00:00:00 +0000 (22 00:00 +0000)
content tags
add:
README
# Requirements
A gemini server with SCGI capabilities.
This includes at least molly-brown, GLV-1.12556, gemserv, and stargazer.

# Building
```
make
```

# Basic usage
Configure your server to use SCGI with a given socket path,
e.g. in molly-brown config add something like:
```
[SCGIPaths]
"/gemrepl" = "/tmp/gemrepl_socket"
```

Then run gemrepl as
```
gemrepl -s /tmp/gemrepl_socket COMMAND ARGS
```
(you may want to try with 'cat' as the command while testing your setup).
For simplicity, you can run gemrepl as the same user as the server; see 
Permissions below for a better approach.

When a user requests "/gemrepl" and presents a client certificate, an instance 
of the command will be spawned. On each subsequent request with the same 
client certificate, the query (if any) will be written to the process, and any 
(timely) output of the process will be given in the response.

See the examples/ directory for ideas of how this could be used.

# Security
Perhaps it should go without saying, but be careful with this! You are 
allowing arbitrary internet users to run COMMAND on your machine and to write 
arbitrary input to it. Be sure that they can't get a shell this way!

You should also worry about DoS. A limited number of subprocesses will be 
spawned, after which the longest-idle process will be killed to allow a new 
one to be spawned. If COMMAND is going to consume significant resources, you 
may wish to use the --max-children option to reduce this maximum.

# Communication with child processes
By default, gemrepl relies on (configurable) timeouts to determine when the 
child has stopped writing and is waiting for input. Alternatively,
the child can write to file descriptor 3 to indicate when it is expecting 
input. To do this, it should write '<' to 3 whenever it is about to read a 
single line from stdin, and '>' once it has finished reading. This method 
leads to perfect synchronisation as long as the child never pauses long enough 
to trigger a timeout.

By default, the output of the process is presented unquoted as text/gemini. 
See the --format option for other possibilities. 

# Environment variables
The spawned command will be passed the sha256 hex-encoded hash of the client 
certificate in the environment variable TLS_CLIENT_HASH.

More precisely, this is the behaviour with molly-brown and GLV-1.12556;
in general the value of the variable will be what the server sends as 
TLS_CLIENT_HASH with any prefix "SHA256:" stripped.

SPAWN_PARAMETER will be set to the query, if any, of the request which 
initially spawned the command.

# Permissions
The socket file will be created, after first unlinking any existing file at 
the given path. The gemini server must have read-write access to the socket 
file. For safety, you may want to run the gemrepl process and the server as a 
different users. One way to achieve this is to have both users part of a 
common group, then run gemrepl as that group (e.g. using sg) with umask 0007.
Example:
```
sg gemini "umask 0007; gemrepl -s /tmp/test_socket cat"
```
shortlog
2023-07-22 mbaysdon't munge "=> ?!"master
2023-07-22 mbaysby default, write command link only if no other command...
2023-07-22 mbaysmunge links to handle following links from an old state
2023-07-22 mbaysremove unnecessary \r
2023-07-22 mbaysincrease sleep on HUP
2023-07-22 mbaysremove unnecessary newline conversion
2023-07-22 mbaysadd link to start new session on child death
2023-07-15 mbays--single-session
2023-07-12 mbaysadd --no-link option
2022-02-05 mbaysadd --synchronous
2022-02-05 mbayssuppress death message in raw mode
2022-02-05 mbaysremove support for non-strict linebasedness
2022-02-05 mbaysadd --strict-lines
2021-06-15 mbaysadd gemscgi_wrap
2021-06-12 mbaysfix bad pointers
2021-06-12 mbaysfix multiline
...
heads
15 months ago master