make closing socket the responsibility of respond
[gemrepl.git] / README
blobc74437e1b5d2c80a08991765c62135199239c9f8
1 # Requirements
2 A gemini server with SCGI capabilities.
3 This includes at least molly-brown, GLV-1.12556, gemserv, and stargazer.
5 # Building
6 ```
7 make
8 ```
10 # Basic usage
11 Configure your server to use SCGI with a given socket path,
12 e.g. in molly-brown config add something like:
13 ```
14 [SCGIPaths]
15 "/gemrepl" = "/tmp/gemrepl_socket"
16 ```
18 Then run gemrepl as
19 ```
20 gemrepl -s /tmp/gemrepl_socket COMMAND ARGS
21 ```
22 (you may want to try with 'cat' as the command while testing your setup).
23 For simplicity, you can run gemrepl as the same user as the server; see 
24 Permissions below for a better approach.
26 When a user requests "/gemrepl" and presents a client certificate, an instance 
27 of the command will be spawned. On each subsequent request with the same 
28 client certificate, the query (if any) will be written to the process, and any 
29 (timely) output of the process will be given in the response.
31 See the examples/ directory for ideas of how this could be used.
33 # Security
34 Perhaps it should go without saying, but be careful with this! You are 
35 allowing arbitrary internet users to run COMMAND on your machine and to write 
36 arbitrary input to it. Be sure that they can't get a shell this way!
38 You should also worry about DoS. A limited number of subprocesses will be 
39 spawned, after which the longest-idle process will be killed to allow a new 
40 one to be spawned. If COMMAND is going to consume significant resources, you 
41 may wish to use the --max-children option to reduce this maximum.
43 # Communication with child processes
44 By default, gemrepl relies on (configurable) timeouts to determine when the 
45 child has stopped writing and is waiting for input. Alternatively,
46 the child can write to file descriptor 3 to indicate when it is expecting 
47 input. To do this, it should write '<' to 3 whenever it is about to read 
48 stdin, and '>' as soon as it has finished reading. This method leads to 
49 perfect synchronisation as long as the child never pauses long enough to 
50 trigger a timeout, and reads one a line at a time, and the user sends one line 
51 with each request. More generally, desynchronisation can still occur, but 
52 should be quickly recovered from.
54 By default, the output of the process is presented unquoted as text/gemini, 
55 and it is expected to use unix-style newlines. See the --format and 
56 --no-lf-crlf options for other possibilities. 
58 # Environment variables
59 The spawned command will be passed the sha256 hex-encoded hash of the client 
60 certificate in the environment variable TLS_CLIENT_HASH.
62 More precisely, this is the behaviour with molly-brown and GLV-1.12556;
63 in general the value of the variable will be what the server sends as 
64 TLS_CLIENT_HASH with any prefix "SHA256:" stripped.
66 SPAWN_PARAMETER will be set to the query, if any, of the request which 
67 initially spawned the command.
69 # Permissions
70 The socket file will be created, after first unlinking any existing file at 
71 the given path. The gemini server must have read-write access to the socket 
72 file. For safety, you may want to run the gemrepl process and the server as a 
73 different users. One way to achieve this is to have both users part of a 
74 common group, then run gemrepl as that group (e.g. using sg) with umask 0007.
75 Example:
76 ```
77 sg gemini "umask 0007; gemrepl -s /tmp/test_socket cat"
78 ```