Blame


1 8ad1c570 2021-05-09 op /*
2 8ad1c570 2021-05-09 op * Copyright (c) 2021 Omar Polo <op@omarpolo.com>
3 8ad1c570 2021-05-09 op *
4 8ad1c570 2021-05-09 op * Permission to use, copy, modify, and distribute this software for any
5 8ad1c570 2021-05-09 op * purpose with or without fee is hereby granted, provided that the above
6 8ad1c570 2021-05-09 op * copyright notice and this permission notice appear in all copies.
7 8ad1c570 2021-05-09 op *
8 8ad1c570 2021-05-09 op * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 8ad1c570 2021-05-09 op * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 8ad1c570 2021-05-09 op * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 8ad1c570 2021-05-09 op * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 8ad1c570 2021-05-09 op * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 8ad1c570 2021-05-09 op * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 8ad1c570 2021-05-09 op * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 8ad1c570 2021-05-09 op */
16 8ad1c570 2021-05-09 op
17 8ad1c570 2021-05-09 op #include "gmid.h"
18 8ad1c570 2021-05-09 op
19 8ad1c570 2021-05-09 op #include <assert.h>
20 8ad1c570 2021-05-09 op #include <errno.h>
21 8ad1c570 2021-05-09 op #include <string.h>
22 df5058c9 2023-06-05 op
23 df5058c9 2023-06-05 op #include "log.h"
24 8ad1c570 2021-05-09 op
25 8ad1c570 2021-05-09 op /*
26 8ad1c570 2021-05-09 op * Sometimes it can be useful to inspect the fastcgi traffic as
27 8ad1c570 2021-05-09 op * received by gmid.
28 8ad1c570 2021-05-09 op *
29 8ad1c570 2021-05-09 op * This will make gmid connect to a `debug.sock' socket (that must
30 8ad1c570 2021-05-09 op * exists) in the current directory and send there a copy of what gets
31 8ad1c570 2021-05-09 op * read. The socket can be created and monitored e.g. with
32 8ad1c570 2021-05-09 op *
33 8ad1c570 2021-05-09 op * rm -f debug.sock ; nc -Ulk ./debug.sock | hexdump -C
34 8ad1c570 2021-05-09 op *
35 8ad1c570 2021-05-09 op * NB: the sandbox must be disabled for this to work.
36 8ad1c570 2021-05-09 op */
37 8ad1c570 2021-05-09 op #define DEBUG_FCGI 0
38 8ad1c570 2021-05-09 op
39 f740b61b 2021-06-11 op #if DEBUG_FCGI
40 8ad1c570 2021-05-09 op # include <sys/un.h>
41 8ad1c570 2021-05-09 op static int debug_socket = -1;
42 8ad1c570 2021-05-09 op #endif
43 8ad1c570 2021-05-09 op
44 8ad1c570 2021-05-09 op struct fcgi_header {
45 8ad1c570 2021-05-09 op unsigned char version;
46 8ad1c570 2021-05-09 op unsigned char type;
47 8ad1c570 2021-05-09 op unsigned char req_id1;
48 8ad1c570 2021-05-09 op unsigned char req_id0;
49 8ad1c570 2021-05-09 op unsigned char content_len1;
50 8ad1c570 2021-05-09 op unsigned char content_len0;
51 8ad1c570 2021-05-09 op unsigned char padding;
52 8ad1c570 2021-05-09 op unsigned char reserved;
53 8ad1c570 2021-05-09 op };
54 8ad1c570 2021-05-09 op
55 8ad1c570 2021-05-09 op /*
56 8ad1c570 2021-05-09 op * number of bytes in a FCGI_HEADER. Future version of the protocol
57 8ad1c570 2021-05-09 op * will not reduce this number.
58 8ad1c570 2021-05-09 op */
59 8ad1c570 2021-05-09 op #define FCGI_HEADER_LEN 8
60 8ad1c570 2021-05-09 op
61 8ad1c570 2021-05-09 op /*
62 8ad1c570 2021-05-09 op * values for the version component
63 8ad1c570 2021-05-09 op */
64 8ad1c570 2021-05-09 op #define FCGI_VERSION_1 1
65 8ad1c570 2021-05-09 op
66 8ad1c570 2021-05-09 op /*
67 8ad1c570 2021-05-09 op * values for the type component
68 8ad1c570 2021-05-09 op */
69 8ad1c570 2021-05-09 op #define FCGI_BEGIN_REQUEST 1
70 8ad1c570 2021-05-09 op #define FCGI_ABORT_REQUEST 2
71 8ad1c570 2021-05-09 op #define FCGI_END_REQUEST 3
72 8ad1c570 2021-05-09 op #define FCGI_PARAMS 4
73 8ad1c570 2021-05-09 op #define FCGI_STDIN 5
74 8ad1c570 2021-05-09 op #define FCGI_STDOUT 6
75 8ad1c570 2021-05-09 op #define FCGI_STDERR 7
76 8ad1c570 2021-05-09 op #define FCGI_DATA 8
77 8ad1c570 2021-05-09 op #define FCGI_GET_VALUES 9
78 8ad1c570 2021-05-09 op #define FCGI_GET_VALUES_RESULT 10
79 8ad1c570 2021-05-09 op #define FCGI_UNKNOWN_TYPE 11
80 8ad1c570 2021-05-09 op #define FCGI_MAXTYPE (FCGI_UNKNOWN_TYPE)
81 8ad1c570 2021-05-09 op
82 8ad1c570 2021-05-09 op struct fcgi_begin_req {
83 8ad1c570 2021-05-09 op unsigned char role1;
84 8ad1c570 2021-05-09 op unsigned char role0;
85 8ad1c570 2021-05-09 op unsigned char flags;
86 8ad1c570 2021-05-09 op unsigned char reserved[5];
87 8ad1c570 2021-05-09 op };
88 8ad1c570 2021-05-09 op
89 8ad1c570 2021-05-09 op struct fcgi_begin_req_record {
90 8ad1c570 2021-05-09 op struct fcgi_header header;
91 8ad1c570 2021-05-09 op struct fcgi_begin_req body;
92 8ad1c570 2021-05-09 op };
93 8ad1c570 2021-05-09 op
94 8ad1c570 2021-05-09 op /*
95 8ad1c570 2021-05-09 op * mask for flags;
96 8ad1c570 2021-05-09 op */
97 8ad1c570 2021-05-09 op #define FCGI_KEEP_CONN 1
98 8ad1c570 2021-05-09 op
99 8ad1c570 2021-05-09 op /*
100 8ad1c570 2021-05-09 op * values for the role
101 8ad1c570 2021-05-09 op */
102 8ad1c570 2021-05-09 op #define FCGI_RESPONDER 1
103 8ad1c570 2021-05-09 op #define FCGI_AUTHORIZER 2
104 8ad1c570 2021-05-09 op #define FCGI_FILTER 3
105 8ad1c570 2021-05-09 op
106 8ad1c570 2021-05-09 op struct fcgi_end_req_body {
107 8ad1c570 2021-05-09 op unsigned char app_status3;
108 8ad1c570 2021-05-09 op unsigned char app_status2;
109 8ad1c570 2021-05-09 op unsigned char app_status1;
110 8ad1c570 2021-05-09 op unsigned char app_status0;
111 8ad1c570 2021-05-09 op unsigned char proto_status;
112 8ad1c570 2021-05-09 op unsigned char reserved[3];
113 8ad1c570 2021-05-09 op };
114 8ad1c570 2021-05-09 op
115 8ad1c570 2021-05-09 op /*
116 8ad1c570 2021-05-09 op * values for proto_status
117 8ad1c570 2021-05-09 op */
118 8ad1c570 2021-05-09 op #define FCGI_REQUEST_COMPLETE 0
119 8ad1c570 2021-05-09 op #define FCGI_CANT_MPX_CONN 1
120 8ad1c570 2021-05-09 op #define FCGI_OVERLOADED 2
121 8ad1c570 2021-05-09 op #define FCGI_UNKNOWN_ROLE 3
122 8ad1c570 2021-05-09 op
123 8ad1c570 2021-05-09 op /*
124 8ad1c570 2021-05-09 op * Variable names for FCGI_GET_VALUES / FCGI_GET_VALUES_RESULT
125 8ad1c570 2021-05-09 op * records.
126 8ad1c570 2021-05-09 op */
127 8ad1c570 2021-05-09 op #define FCGI_MAX_CONNS "FCGI_MAX_CONNS"
128 8ad1c570 2021-05-09 op #define FCGI_MAX_REQS "FCGI_MAX_REQS"
129 8ad1c570 2021-05-09 op #define FCGI_MPXS_CONNS "FCGI_MPXS_CONNS"
130 8ad1c570 2021-05-09 op
131 8ad1c570 2021-05-09 op static int
132 4cd25209 2021-10-07 op prepare_header(struct fcgi_header *h, int type, size_t size,
133 8ad1c570 2021-05-09 op size_t padding)
134 8ad1c570 2021-05-09 op {
135 4cd25209 2021-10-07 op int id = 1;
136 4cd25209 2021-10-07 op
137 8ad1c570 2021-05-09 op memset(h, 0, sizeof(*h));
138 8ad1c570 2021-05-09 op
139 8ad1c570 2021-05-09 op h->version = FCGI_VERSION_1;
140 4842c72d 2021-10-18 op h->type = type;
141 8ad1c570 2021-05-09 op h->req_id1 = (id >> 8);
142 8ad1c570 2021-05-09 op h->req_id0 = (id & 0xFF);
143 8ad1c570 2021-05-09 op h->content_len1 = (size >> 8);
144 8ad1c570 2021-05-09 op h->content_len0 = (size & 0xFF);
145 8ad1c570 2021-05-09 op h->padding = padding;
146 8ad1c570 2021-05-09 op
147 8ad1c570 2021-05-09 op return 0;
148 8ad1c570 2021-05-09 op }
149 8ad1c570 2021-05-09 op
150 8ad1c570 2021-05-09 op static int
151 4cd25209 2021-10-07 op fcgi_begin_request(struct bufferevent *bev)
152 8ad1c570 2021-05-09 op {
153 8ad1c570 2021-05-09 op struct fcgi_begin_req_record r;
154 8ad1c570 2021-05-09 op
155 8ad1c570 2021-05-09 op memset(&r, 0, sizeof(r));
156 4cd25209 2021-10-07 op prepare_header(&r.header, FCGI_BEGIN_REQUEST, sizeof(r.body), 0);
157 8ad1c570 2021-05-09 op assert(sizeof(r.body) == FCGI_HEADER_LEN);
158 8ad1c570 2021-05-09 op
159 8ad1c570 2021-05-09 op r.body.role1 = 0;
160 8ad1c570 2021-05-09 op r.body.role0 = FCGI_RESPONDER;
161 8ad1c570 2021-05-09 op r.body.flags = FCGI_KEEP_CONN;
162 8ad1c570 2021-05-09 op
163 741b69be 2021-09-26 op if (bufferevent_write(bev, &r, sizeof(r)) == -1)
164 8ad1c570 2021-05-09 op return -1;
165 8ad1c570 2021-05-09 op return 0;
166 8ad1c570 2021-05-09 op }
167 8ad1c570 2021-05-09 op
168 8ad1c570 2021-05-09 op static int
169 4cd25209 2021-10-07 op fcgi_send_param(struct bufferevent *bev, const char *name,
170 741b69be 2021-09-26 op const char *value)
171 8ad1c570 2021-05-09 op {
172 8ad1c570 2021-05-09 op struct fcgi_header h;
173 4842c72d 2021-10-18 op uint32_t namlen, vallen, padlen;
174 8ad1c570 2021-05-09 op uint8_t s[8];
175 8ad1c570 2021-05-09 op size_t size;
176 e5d82d94 2022-03-19 op const char padding[8] = { 0 };
177 8ad1c570 2021-05-09 op
178 8ad1c570 2021-05-09 op namlen = strlen(name);
179 8ad1c570 2021-05-09 op vallen = strlen(value);
180 8ad1c570 2021-05-09 op size = namlen + vallen + 8; /* 4 for the sizes */
181 8ad1c570 2021-05-09 op padlen = (8 - (size & 0x7)) & 0x7;
182 8ad1c570 2021-05-09 op
183 8ad1c570 2021-05-09 op s[0] = ( namlen >> 24) | 0x80;
184 8ad1c570 2021-05-09 op s[1] = ((namlen >> 16) & 0xFF);
185 8ad1c570 2021-05-09 op s[2] = ((namlen >> 8) & 0xFF);
186 8ad1c570 2021-05-09 op s[3] = ( namlen & 0xFF);
187 8ad1c570 2021-05-09 op
188 8ad1c570 2021-05-09 op s[4] = ( vallen >> 24) | 0x80;
189 8ad1c570 2021-05-09 op s[5] = ((vallen >> 16) & 0xFF);
190 8ad1c570 2021-05-09 op s[6] = ((vallen >> 8) & 0xFF);
191 8ad1c570 2021-05-09 op s[7] = ( vallen & 0xFF);
192 8ad1c570 2021-05-09 op
193 4cd25209 2021-10-07 op prepare_header(&h, FCGI_PARAMS, size, padlen);
194 8ad1c570 2021-05-09 op
195 741b69be 2021-09-26 op if (bufferevent_write(bev, &h, sizeof(h)) == -1 ||
196 741b69be 2021-09-26 op bufferevent_write(bev, s, sizeof(s)) == -1 ||
197 741b69be 2021-09-26 op bufferevent_write(bev, name, namlen) == -1 ||
198 741b69be 2021-09-26 op bufferevent_write(bev, value, vallen) == -1 ||
199 741b69be 2021-09-26 op bufferevent_write(bev, padding, padlen) == -1)
200 8ad1c570 2021-05-09 op return -1;
201 8ad1c570 2021-05-09 op
202 8ad1c570 2021-05-09 op return 0;
203 8ad1c570 2021-05-09 op }
204 8ad1c570 2021-05-09 op
205 8ad1c570 2021-05-09 op static int
206 4cd25209 2021-10-07 op fcgi_end_param(struct bufferevent *bev)
207 8ad1c570 2021-05-09 op {
208 8ad1c570 2021-05-09 op struct fcgi_header h;
209 8ad1c570 2021-05-09 op
210 4cd25209 2021-10-07 op prepare_header(&h, FCGI_PARAMS, 0, 0);
211 741b69be 2021-09-26 op if (bufferevent_write(bev, &h, sizeof(h)) == -1)
212 8ad1c570 2021-05-09 op return -1;
213 8ad1c570 2021-05-09 op
214 4cd25209 2021-10-07 op prepare_header(&h, FCGI_STDIN, 0, 0);
215 741b69be 2021-09-26 op if (bufferevent_write(bev, &h, sizeof(h)) == -1)
216 8ad1c570 2021-05-09 op return -1;
217 8ad1c570 2021-05-09 op
218 8ad1c570 2021-05-09 op return 0;
219 8ad1c570 2021-05-09 op }
220 8ad1c570 2021-05-09 op
221 8ad1c570 2021-05-09 op static inline int
222 8ad1c570 2021-05-09 op recid(struct fcgi_header *h)
223 8ad1c570 2021-05-09 op {
224 4cd25209 2021-10-07 op return h->req_id0 + (h->req_id1 << 8);
225 8ad1c570 2021-05-09 op }
226 8ad1c570 2021-05-09 op
227 8ad1c570 2021-05-09 op static inline int
228 8ad1c570 2021-05-09 op reclen(struct fcgi_header *h)
229 8ad1c570 2021-05-09 op {
230 8ad1c570 2021-05-09 op return h->content_len0 + (h->content_len1 << 8);
231 8ad1c570 2021-05-09 op }
232 8ad1c570 2021-05-09 op
233 090b8a89 2021-07-06 op void
234 741b69be 2021-09-26 op fcgi_read(struct bufferevent *bev, void *d)
235 8ad1c570 2021-05-09 op {
236 4cd25209 2021-10-07 op struct client *c = d;
237 741b69be 2021-09-26 op struct evbuffer *src = EVBUFFER_INPUT(bev);
238 741b69be 2021-09-26 op struct fcgi_header hdr;
239 8ad1c570 2021-05-09 op struct fcgi_end_req_body end;
240 8ad1c570 2021-05-09 op size_t len;
241 8ad1c570 2021-05-09 op
242 741b69be 2021-09-26 op #if DEBUG_FCGI
243 741b69be 2021-09-26 op if (debug_socket == -1) {
244 741b69be 2021-09-26 op struct sockaddr_un addr;
245 8ad1c570 2021-05-09 op
246 741b69be 2021-09-26 op if ((debug_socket = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
247 741b69be 2021-09-26 op err(1, "socket");
248 8ad1c570 2021-05-09 op
249 741b69be 2021-09-26 op memset(&addr, 0, sizeof(addr));
250 741b69be 2021-09-26 op addr.sun_family = AF_UNIX;
251 741b69be 2021-09-26 op strlcpy(addr.sun_path, "./debug.sock", sizeof(addr.sun_path));
252 741b69be 2021-09-26 op if (connect(debug_socket, (struct sockaddr*)&addr, sizeof(addr))
253 741b69be 2021-09-26 op == -1)
254 741b69be 2021-09-26 op err(1, "connect");
255 741b69be 2021-09-26 op }
256 741b69be 2021-09-26 op #endif
257 8ad1c570 2021-05-09 op
258 741b69be 2021-09-26 op for (;;) {
259 741b69be 2021-09-26 op if (EVBUFFER_LENGTH(src) < sizeof(hdr))
260 741b69be 2021-09-26 op return;
261 090b8a89 2021-07-06 op
262 741b69be 2021-09-26 op memcpy(&hdr, EVBUFFER_DATA(src), sizeof(hdr));
263 8ad1c570 2021-05-09 op
264 4cd25209 2021-10-07 op if (recid(&hdr) != 1) {
265 741b69be 2021-09-26 op log_err(NULL,
266 4cd25209 2021-10-07 op "got invalid client id %d from fcgi backend",
267 4cd25209 2021-10-07 op recid(&hdr));
268 8ad1c570 2021-05-09 op goto err;
269 741b69be 2021-09-26 op }
270 741b69be 2021-09-26 op
271 741b69be 2021-09-26 op len = reclen(&hdr);
272 8ad1c570 2021-05-09 op
273 741b69be 2021-09-26 op if (EVBUFFER_LENGTH(src) < sizeof(hdr) + len + hdr.padding)
274 741b69be 2021-09-26 op return;
275 8ad1c570 2021-05-09 op
276 741b69be 2021-09-26 op #if DEBUG_FCGI
277 c016b65c 2021-10-02 op write(debug_socket, EVBUFFER_DATA(src),
278 741b69be 2021-09-26 op sizeof(hdr) + len + hdr.padding);
279 741b69be 2021-09-26 op #endif
280 741b69be 2021-09-26 op
281 741b69be 2021-09-26 op evbuffer_drain(src, sizeof(hdr));
282 741b69be 2021-09-26 op
283 741b69be 2021-09-26 op switch (hdr.type) {
284 741b69be 2021-09-26 op case FCGI_END_REQUEST:
285 741b69be 2021-09-26 op if (len != sizeof(end)) {
286 741b69be 2021-09-26 op log_err(NULL,
287 741b69be 2021-09-26 op "got invalid end request record size");
288 741b69be 2021-09-26 op goto err;
289 741b69be 2021-09-26 op }
290 741b69be 2021-09-26 op bufferevent_read(bev, &end, sizeof(end));
291 741b69be 2021-09-26 op
292 741b69be 2021-09-26 op /* TODO: do something with the status? */
293 efe7d180 2021-10-02 op c->type = REQUEST_DONE;
294 efe7d180 2021-10-02 op client_write(c->bev, c);
295 17493a48 2022-11-27 op return;
296 741b69be 2021-09-26 op
297 741b69be 2021-09-26 op case FCGI_STDERR:
298 741b69be 2021-09-26 op /* discard stderr (for now) */
299 741b69be 2021-09-26 op evbuffer_drain(src, len);
300 741b69be 2021-09-26 op break;
301 741b69be 2021-09-26 op
302 741b69be 2021-09-26 op case FCGI_STDOUT:
303 d046e4d6 2021-10-04 op bufferevent_write(c->bev, EVBUFFER_DATA(src), len);
304 d046e4d6 2021-10-04 op evbuffer_drain(src, len);
305 741b69be 2021-09-26 op break;
306 8ad1c570 2021-05-09 op
307 741b69be 2021-09-26 op default:
308 741b69be 2021-09-26 op log_err(NULL, "got invalid fcgi record (type=%d)",
309 741b69be 2021-09-26 op hdr.type);
310 741b69be 2021-09-26 op goto err;
311 741b69be 2021-09-26 op }
312 8ad1c570 2021-05-09 op
313 741b69be 2021-09-26 op evbuffer_drain(src, hdr.padding);
314 741b69be 2021-09-26 op }
315 090b8a89 2021-07-06 op
316 741b69be 2021-09-26 op err:
317 4cd25209 2021-10-07 op fcgi_error(bev, EVBUFFER_ERROR, c);
318 741b69be 2021-09-26 op }
319 741b69be 2021-09-26 op
320 741b69be 2021-09-26 op void
321 741b69be 2021-09-26 op fcgi_write(struct bufferevent *bev, void *d)
322 741b69be 2021-09-26 op {
323 741b69be 2021-09-26 op /*
324 741b69be 2021-09-26 op * There's no much use for the write callback.
325 741b69be 2021-09-26 op */
326 8ad1c570 2021-05-09 op return;
327 741b69be 2021-09-26 op }
328 8ad1c570 2021-05-09 op
329 741b69be 2021-09-26 op void
330 741b69be 2021-09-26 op fcgi_error(struct bufferevent *bev, short err, void *d)
331 741b69be 2021-09-26 op {
332 4cd25209 2021-10-07 op struct client *c = d;
333 741b69be 2021-09-26 op
334 5f37f9c2 2021-10-02 op if (!(err & (EVBUFFER_ERROR|EVBUFFER_EOF)))
335 5f37f9c2 2021-10-02 op log_warn(NULL, "unknown event error (%x): %s",
336 5f37f9c2 2021-10-02 op err, strerror(errno));
337 741b69be 2021-09-26 op
338 4cd25209 2021-10-07 op c->type = REQUEST_DONE;
339 4cd25209 2021-10-07 op if (c->code != 0)
340 4cd25209 2021-10-07 op client_close(c);
341 4cd25209 2021-10-07 op else
342 4cd25209 2021-10-07 op start_reply(c, CGI_ERROR, "CGI error");
343 8ad1c570 2021-05-09 op }
344 8ad1c570 2021-05-09 op
345 8ad1c570 2021-05-09 op void
346 4cd25209 2021-10-07 op fcgi_req(struct client *c)
347 8ad1c570 2021-05-09 op {
348 f740b61b 2021-06-11 op char addr[NI_MAXHOST], buf[22];
349 97b306cb 2022-11-27 op char *qs;
350 d1051bfa 2021-05-15 op int e;
351 f740b61b 2021-06-11 op time_t tim;
352 f740b61b 2021-06-11 op struct tm tminfo;
353 f740b61b 2021-06-11 op struct envlist *p;
354 d1051bfa 2021-05-15 op
355 59c7ee13 2021-07-06 op e = getnameinfo((struct sockaddr*)&c->addr, sizeof(c->addr),
356 d1051bfa 2021-05-15 op addr, sizeof(addr),
357 d1051bfa 2021-05-15 op NULL, 0,
358 d1051bfa 2021-05-15 op NI_NUMERICHOST);
359 d1051bfa 2021-05-15 op if (e != 0)
360 df5058c9 2023-06-05 op fatalx("getnameinfo failed: %s", gai_strerror(e));
361 d1051bfa 2021-05-15 op
362 4cd25209 2021-10-07 op fcgi_begin_request(c->cgibev);
363 4cd25209 2021-10-07 op fcgi_send_param(c->cgibev, "GATEWAY_INTERFACE", "CGI/1.1");
364 4cd25209 2021-10-07 op fcgi_send_param(c->cgibev, "GEMINI_URL_PATH", c->iri.path);
365 4cd25209 2021-10-07 op fcgi_send_param(c->cgibev, "QUERY_STRING", c->iri.query);
366 4cd25209 2021-10-07 op fcgi_send_param(c->cgibev, "REMOTE_ADDR", addr);
367 4cd25209 2021-10-07 op fcgi_send_param(c->cgibev, "REMOTE_HOST", addr);
368 4cd25209 2021-10-07 op fcgi_send_param(c->cgibev, "REQUEST_METHOD", "");
369 4cd25209 2021-10-07 op fcgi_send_param(c->cgibev, "SERVER_NAME", c->iri.host);
370 4cd25209 2021-10-07 op fcgi_send_param(c->cgibev, "SERVER_PROTOCOL", "GEMINI");
371 4cd25209 2021-10-07 op fcgi_send_param(c->cgibev, "SERVER_SOFTWARE", GMID_VERSION);
372 50a8f910 2022-10-30 op
373 97b306cb 2022-11-27 op if (*c->iri.query != '\0' &&
374 97b306cb 2022-11-27 op strchr(c->iri.query, '=') == NULL &&
375 97b306cb 2022-11-27 op (qs = strdup(c->iri.query)) != NULL) {
376 97b306cb 2022-11-27 op pct_decode_str(qs);
377 97b306cb 2022-11-27 op fcgi_send_param(c->cgibev, "GEMINI_SEARCH_STRING", qs);
378 97b306cb 2022-11-27 op free(qs);
379 97b306cb 2022-11-27 op }
380 97b306cb 2022-11-27 op
381 50a8f910 2022-10-30 op TAILQ_FOREACH(p, &c->host->params, envs) {
382 50a8f910 2022-10-30 op fcgi_send_param(c->cgibev, p->name, p->value);
383 50a8f910 2022-10-30 op }
384 f740b61b 2021-06-11 op
385 f740b61b 2021-06-11 op if (tls_peer_cert_provided(c->ctx)) {
386 4cd25209 2021-10-07 op fcgi_send_param(c->cgibev, "AUTH_TYPE", "CERTIFICATE");
387 4cd25209 2021-10-07 op fcgi_send_param(c->cgibev, "REMOTE_USER",
388 f740b61b 2021-06-11 op tls_peer_cert_subject(c->ctx));
389 4cd25209 2021-10-07 op fcgi_send_param(c->cgibev, "TLS_CLIENT_ISSUER",
390 f740b61b 2021-06-11 op tls_peer_cert_issuer(c->ctx));
391 4cd25209 2021-10-07 op fcgi_send_param(c->cgibev, "TLS_CLIENT_HASH",
392 f740b61b 2021-06-11 op tls_peer_cert_hash(c->ctx));
393 4cd25209 2021-10-07 op fcgi_send_param(c->cgibev, "TLS_VERSION",
394 f740b61b 2021-06-11 op tls_conn_version(c->ctx));
395 4cd25209 2021-10-07 op fcgi_send_param(c->cgibev, "TLS_CIPHER",
396 f740b61b 2021-06-11 op tls_conn_cipher(c->ctx));
397 8ad1c570 2021-05-09 op
398 f740b61b 2021-06-11 op snprintf(buf, sizeof(buf), "%d",
399 f740b61b 2021-06-11 op tls_conn_cipher_strength(c->ctx));
400 4cd25209 2021-10-07 op fcgi_send_param(c->cgibev, "TLS_CIPHER_STRENGTH", buf);
401 f740b61b 2021-06-11 op
402 f740b61b 2021-06-11 op tim = tls_peer_cert_notbefore(c->ctx);
403 f740b61b 2021-06-11 op strftime(buf, sizeof(buf), "%FT%TZ",
404 f740b61b 2021-06-11 op gmtime_r(&tim, &tminfo));
405 4cd25209 2021-10-07 op fcgi_send_param(c->cgibev, "TLS_CLIENT_NOT_BEFORE", buf);
406 f740b61b 2021-06-11 op
407 f740b61b 2021-06-11 op tim = tls_peer_cert_notafter(c->ctx);
408 f740b61b 2021-06-11 op strftime(buf, sizeof(buf), "%FT%TZ",
409 f740b61b 2021-06-11 op gmtime_r(&tim, &tminfo));
410 4cd25209 2021-10-07 op fcgi_send_param(c->cgibev, "TLS_CLIENT_NOT_AFTER", buf);
411 f740b61b 2021-06-11 op
412 f740b61b 2021-06-11 op } else
413 4cd25209 2021-10-07 op fcgi_send_param(c->cgibev, "AUTH_TYPE", "");
414 f740b61b 2021-06-11 op
415 4cd25209 2021-10-07 op if (fcgi_end_param(c->cgibev) == -1)
416 4cd25209 2021-10-07 op fcgi_error(c->cgibev, EVBUFFER_ERROR, c);
417 8ad1c570 2021-05-09 op }