xref: /openbsd-src/usr.sbin/slowcgi/slowcgi.c (revision 505ee9ea3b177e2387d907a91ca7da069f3f14d8)
1 /*	$OpenBSD: slowcgi.c,v 1.57 2020/05/11 10:40:12 claudio Exp $ */
2 /*
3  * Copyright (c) 2013 David Gwynne <dlg@openbsd.org>
4  * Copyright (c) 2013 Florian Obser <florian@openbsd.org>
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 #include <sys/types.h>
20 #include <sys/ioctl.h>
21 #include <sys/queue.h>
22 #include <sys/socket.h>
23 #include <sys/stat.h>
24 #include <sys/time.h>
25 #include <sys/un.h>
26 #include <sys/wait.h>
27 #include <arpa/inet.h>
28 #include <err.h>
29 #include <fcntl.h>
30 #include <errno.h>
31 #include <event.h>
32 #include <limits.h>
33 #include <pwd.h>
34 #include <signal.h>
35 #include <stdarg.h>
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <string.h>
39 #include <syslog.h>
40 #include <unistd.h>
41 
42 #define TIMEOUT_DEFAULT		 120
43 #define SLOWCGI_USER		 "www"
44 
45 #define FCGI_CONTENT_SIZE	 65535
46 #define FCGI_PADDING_SIZE	 255
47 #define FCGI_RECORD_SIZE	 \
48     (sizeof(struct fcgi_record_header) + FCGI_CONTENT_SIZE + FCGI_PADDING_SIZE)
49 
50 #define FCGI_ALIGNMENT		 8
51 #define FCGI_ALIGN(n)		 \
52     (((n) + (FCGI_ALIGNMENT - 1)) & ~(FCGI_ALIGNMENT - 1))
53 
54 #define STDOUT_DONE		 1
55 #define STDERR_DONE		 2
56 #define SCRIPT_DONE		 4
57 
58 #define FCGI_BEGIN_REQUEST	 1
59 #define FCGI_ABORT_REQUEST	 2
60 #define FCGI_END_REQUEST	 3
61 #define FCGI_PARAMS		 4
62 #define FCGI_STDIN		 5
63 #define FCGI_STDOUT		 6
64 #define FCGI_STDERR		 7
65 #define FCGI_DATA		 8
66 #define FCGI_GET_VALUES		 9
67 #define FCGI_GET_VALUES_RESULT	10
68 #define FCGI_UNKNOWN_TYPE	11
69 #define FCGI_MAXTYPE		(FCGI_UNKNOWN_TYPE)
70 
71 #define FCGI_REQUEST_COMPLETE	0
72 #define FCGI_CANT_MPX_CONN	1
73 #define FCGI_OVERLOADED		2
74 #define FCGI_UNKNOWN_ROLE	3
75 
76 #define FD_RESERVE		5
77 #define FD_NEEDED		6
78 int cgi_inflight = 0;
79 
80 struct listener {
81 	struct event	ev, pause;
82 };
83 
84 struct env_val {
85 	SLIST_ENTRY(env_val)	 entry;
86 	char			*val;
87 };
88 SLIST_HEAD(env_head, env_val);
89 
90 struct fcgi_record_header {
91 	uint8_t		version;
92 	uint8_t		type;
93 	uint16_t	id;
94 	uint16_t	content_len;
95 	uint8_t		padding_len;
96 	uint8_t		reserved;
97 }__packed;
98 
99 struct fcgi_response {
100 	TAILQ_ENTRY(fcgi_response)	entry;
101 	uint8_t				data[FCGI_RECORD_SIZE];
102 	size_t				data_pos;
103 	size_t				data_len;
104 };
105 TAILQ_HEAD(fcgi_response_head, fcgi_response);
106 
107 struct fcgi_stdin {
108 	TAILQ_ENTRY(fcgi_stdin)	entry;
109 	uint8_t			data[FCGI_RECORD_SIZE];
110 	size_t			data_pos;
111 	size_t			data_len;
112 };
113 TAILQ_HEAD(fcgi_stdin_head, fcgi_stdin);
114 
115 struct request {
116 	struct event			ev;
117 	struct event			resp_ev;
118 	struct event			tmo;
119 	int				fd;
120 	uint8_t				buf[FCGI_RECORD_SIZE];
121 	size_t				buf_pos;
122 	size_t				buf_len;
123 	struct fcgi_response_head	response_head;
124 	struct fcgi_stdin_head		stdin_head;
125 	uint16_t			id;
126 	char				script_name[PATH_MAX];
127 	struct env_head			env;
128 	int				env_count;
129 	pid_t				script_pid;
130 	int				script_status;
131 	struct event			script_ev;
132 	struct event			script_err_ev;
133 	struct event			script_stdin_ev;
134 	int				stdin_fd_closed;
135 	int				stdout_fd_closed;
136 	int				stderr_fd_closed;
137 	uint8_t				script_flags;
138 	uint8_t				request_started;
139 	int				inflight_fds_accounted;
140 };
141 
142 struct requests {
143 	SLIST_ENTRY(requests)	 entry;
144 	struct request		*request;
145 };
146 SLIST_HEAD(requests_head, requests);
147 
148 struct slowcgi_proc {
149 	struct requests_head	requests;
150 	struct event		ev_sigchld;
151 	struct event		ev_sigpipe;
152 };
153 
154 struct fcgi_begin_request_body {
155 	uint16_t	role;
156 	uint8_t		flags;
157 	uint8_t		reserved[5];
158 }__packed;
159 
160 struct fcgi_end_request_body {
161 	uint32_t	app_status;
162 	uint8_t		protocol_status;
163 	uint8_t		reserved[3];
164 }__packed;
165 
166 __dead void	usage(void);
167 int		slowcgi_listen(char *, struct passwd *);
168 void		slowcgi_paused(int, short, void *);
169 int		accept_reserve(int, struct sockaddr *, socklen_t *, int,
170 		    volatile int *);
171 void		slowcgi_accept(int, short, void *);
172 void		slowcgi_request(int, short, void *);
173 void		slowcgi_response(int, short, void *);
174 void		slowcgi_add_response(struct request *, struct fcgi_response *);
175 void		slowcgi_timeout(int, short, void *);
176 void		slowcgi_sig_handler(int, short, void *);
177 size_t		parse_record(uint8_t * , size_t, struct request *);
178 void		parse_begin_request(uint8_t *, uint16_t, struct request *,
179 		    uint16_t);
180 void		parse_params(uint8_t *, uint16_t, struct request *, uint16_t);
181 void		parse_stdin(uint8_t *, uint16_t, struct request *, uint16_t);
182 void		exec_cgi(struct request *);
183 void		script_in(int, struct event *, struct request *, uint8_t);
184 void		script_std_in(int, short, void *);
185 void		script_err_in(int, short, void *);
186 void		script_out(int, short, void *);
187 void		create_end_record(struct request *);
188 void		dump_fcgi_record(const char *,
189 		    struct fcgi_record_header *);
190 void		dump_fcgi_record_header(const char *,
191 		    struct fcgi_record_header *);
192 void		dump_fcgi_begin_request_body(const char *,
193 		    struct fcgi_begin_request_body *);
194 void		dump_fcgi_end_request_body(const char *,
195 		    struct fcgi_end_request_body *);
196 void		cleanup_request(struct request *);
197 
198 struct loggers {
199 	__dead void (*err)(int, const char *, ...)
200 	    __attribute__((__format__ (printf, 2, 3)));
201 	__dead void (*errx)(int, const char *, ...)
202 	    __attribute__((__format__ (printf, 2, 3)));
203 	void (*warn)(const char *, ...)
204 	    __attribute__((__format__ (printf, 1, 2)));
205 	void (*warnx)(const char *, ...)
206 	    __attribute__((__format__ (printf, 1, 2)));
207 	void (*info)(const char *, ...)
208 	    __attribute__((__format__ (printf, 1, 2)));
209 	void (*debug)(const char *, ...)
210 	    __attribute__((__format__ (printf, 1, 2)));
211 };
212 
213 const struct loggers conslogger = {
214 	err,
215 	errx,
216 	warn,
217 	warnx,
218 	warnx, /* info */
219 	warnx /* debug */
220 };
221 
222 __dead void	syslog_err(int, const char *, ...)
223 		    __attribute__((__format__ (printf, 2, 3)));
224 __dead void	syslog_errx(int, const char *, ...)
225 		    __attribute__((__format__ (printf, 2, 3)));
226 void		syslog_warn(const char *, ...)
227 		    __attribute__((__format__ (printf, 1, 2)));
228 void		syslog_warnx(const char *, ...)
229 		    __attribute__((__format__ (printf, 1, 2)));
230 void		syslog_info(const char *, ...)
231 		    __attribute__((__format__ (printf, 1, 2)));
232 void		syslog_debug(const char *, ...)
233 		    __attribute__((__format__ (printf, 1, 2)));
234 void		syslog_vstrerror(int, int, const char *, va_list)
235 		    __attribute__((__format__ (printf, 3, 0)));
236 
237 const struct loggers syslogger = {
238 	syslog_err,
239 	syslog_errx,
240 	syslog_warn,
241 	syslog_warnx,
242 	syslog_info,
243 	syslog_debug
244 };
245 
246 const struct loggers *logger = &conslogger;
247 
248 #define lerr(_e, _f...) logger->err((_e), _f)
249 #define lerrx(_e, _f...) logger->errx((_e), _f)
250 #define lwarn(_f...) logger->warn(_f)
251 #define lwarnx(_f...) logger->warnx(_f)
252 #define linfo(_f...) logger->info(_f)
253 #define ldebug(_f...) logger->debug(_f)
254 
255 __dead void
256 usage(void)
257 {
258 	extern char *__progname;
259 	fprintf(stderr,
260 	    "usage: %s [-d] [-p path] [-s socket] [-U user] [-u user]\n",
261 	    __progname);
262 	exit(1);
263 }
264 
265 struct timeval		timeout = { TIMEOUT_DEFAULT, 0 };
266 struct slowcgi_proc	slowcgi_proc;
267 int			debug = 0;
268 int			on = 1;
269 char			*fcgi_socket = "/var/www/run/slowcgi.sock";
270 
271 int
272 main(int argc, char *argv[])
273 {
274 	extern char *__progname;
275 	struct listener	*l = NULL;
276 	struct passwd	*pw;
277 	struct stat	 sb;
278 	int		 c, fd;
279 	const char	*chrootpath = NULL;
280 	const char	*sock_user = SLOWCGI_USER;
281 	const char	*slowcgi_user = SLOWCGI_USER;
282 
283 	/*
284 	 * Ensure we have fds 0-2 open so that we have no fd overlaps
285 	 * in exec_cgi() later. Just exit on error, we don't have enough
286 	 * fds open to output an error message anywhere.
287 	 */
288 	for (c=0; c < 3; c++) {
289 		if (fstat(c, &sb) == -1) {
290 			if ((fd = open("/dev/null", O_RDWR)) != -1) {
291 				if (dup2(fd, c) == -1)
292 					exit(1);
293 				if (fd > c)
294 					close(fd);
295 			} else
296 				exit(1);
297 		}
298 	}
299 
300 	while ((c = getopt(argc, argv, "dp:s:U:u:")) != -1) {
301 		switch (c) {
302 		case 'd':
303 			debug++;
304 			break;
305 		case 'p':
306 			chrootpath = optarg;
307 			break;
308 		case 's':
309 			fcgi_socket = optarg;
310 			break;
311 		case 'U':
312 			sock_user = optarg;
313 			break;
314 		case 'u':
315 			slowcgi_user = optarg;
316 			break;
317 		default:
318 			usage();
319 			/* NOTREACHED */
320 		}
321 	}
322 
323 	if (geteuid() != 0)
324 		errx(1, "need root privileges");
325 
326 	if (!debug && daemon(0, 0) == -1)
327 		err(1, "daemon");
328 
329 	if (!debug) {
330 		openlog(__progname, LOG_PID|LOG_NDELAY, LOG_DAEMON);
331 		logger = &syslogger;
332 	}
333 
334 	ldebug("sock_user: %s", sock_user);
335 	pw = getpwnam(sock_user);
336 	if (pw == NULL)
337 		lerrx(1, "no %s user", sock_user);
338 
339 	fd = slowcgi_listen(fcgi_socket, pw);
340 
341 	ldebug("slowcgi_user: %s", slowcgi_user);
342 	pw = getpwnam(slowcgi_user);
343 	if (pw == NULL)
344 		lerrx(1, "no %s user", slowcgi_user);
345 
346 	if (chrootpath == NULL)
347 		chrootpath = pw->pw_dir;
348 
349 	if (chroot(chrootpath) == -1)
350 		lerr(1, "chroot(%s)", chrootpath);
351 
352 	ldebug("chroot: %s", chrootpath);
353 
354 	if (chdir("/") == -1)
355 		lerr(1, "chdir(/)");
356 
357 	if (setgroups(1, &pw->pw_gid) ||
358 	    setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) ||
359 	    setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid))
360 		lerr(1, "unable to revoke privs");
361 
362 	if (pledge("stdio rpath unix proc exec", NULL) == -1)
363 		lerr(1, "pledge");
364 
365 	SLIST_INIT(&slowcgi_proc.requests);
366 	event_init();
367 
368 	l = calloc(1, sizeof(*l));
369 	if (l == NULL)
370 		lerr(1, "listener ev alloc");
371 
372 	event_set(&l->ev, fd, EV_READ | EV_PERSIST, slowcgi_accept, l);
373 	event_add(&l->ev, NULL);
374 	evtimer_set(&l->pause, slowcgi_paused, l);
375 
376 	signal_set(&slowcgi_proc.ev_sigchld, SIGCHLD, slowcgi_sig_handler,
377 	    &slowcgi_proc);
378 	signal_set(&slowcgi_proc.ev_sigpipe, SIGPIPE, slowcgi_sig_handler,
379 	    &slowcgi_proc);
380 
381 	signal_add(&slowcgi_proc.ev_sigchld, NULL);
382 	signal_add(&slowcgi_proc.ev_sigpipe, NULL);
383 
384 	event_dispatch();
385 	return (0);
386 }
387 
388 int
389 slowcgi_listen(char *path, struct passwd *pw)
390 {
391 	struct sockaddr_un	 sun;
392 	mode_t			 old_umask;
393 	int			 fd;
394 
395 	if ((fd = socket(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC,
396 	    0)) == -1)
397 		lerr(1, "slowcgi_listen: socket");
398 
399 	bzero(&sun, sizeof(sun));
400 	sun.sun_family = AF_UNIX;
401 	if (strlcpy(sun.sun_path, path, sizeof(sun.sun_path)) >=
402 	    sizeof(sun.sun_path))
403 		lerrx(1, "socket path too long");
404 
405 	if (unlink(path) == -1)
406 		if (errno != ENOENT)
407 			lerr(1, "slowcgi_listen: unlink %s", path);
408 
409 	old_umask = umask(S_IXUSR|S_IXGRP|S_IWOTH|S_IROTH|S_IXOTH);
410 
411 	if (bind(fd, (struct sockaddr *)&sun, sizeof(sun)) == -1)
412 		lerr(1,"slowcgi_listen: bind: %s", path);
413 
414 	umask(old_umask);
415 
416 	if (chown(path, pw->pw_uid, pw->pw_gid) == -1)
417 		lerr(1, "slowcgi_listen: chown: %s", path);
418 
419 	if (listen(fd, 5) == -1)
420 		lerr(1, "listen");
421 
422 	ldebug("socket: %s", path);
423 	return fd;
424 }
425 
426 void
427 slowcgi_paused(int fd, short events, void *arg)
428 {
429 	struct listener	*l = arg;
430 	event_add(&l->ev, NULL);
431 }
432 
433 int
434 accept_reserve(int sockfd, struct sockaddr *addr, socklen_t *addrlen,
435     int reserve, volatile int *counter)
436 {
437 	int ret;
438 	if (getdtablecount() + reserve +
439 	    ((*counter + 1) * FD_NEEDED) >= getdtablesize()) {
440 		ldebug("inflight fds exceeded");
441 		errno = EMFILE;
442 		return -1;
443 	}
444 
445 	if ((ret = accept4(sockfd, addr, addrlen, SOCK_NONBLOCK | SOCK_CLOEXEC))
446 	    > -1) {
447 		(*counter)++;
448 		ldebug("inflight incremented, now %d", *counter);
449 	}
450 	return ret;
451 }
452 
453 void
454 slowcgi_accept(int fd, short events, void *arg)
455 {
456 	struct listener		*l;
457 	struct sockaddr_storage	 ss;
458 	struct timeval		 backoff;
459 	struct request		*c;
460 	struct requests		*requests;
461 	socklen_t		 len;
462 	int			 s;
463 
464 	l = arg;
465 	backoff.tv_sec = 1;
466 	backoff.tv_usec = 0;
467 	c = NULL;
468 
469 	len = sizeof(ss);
470 	if ((s = accept_reserve(fd, (struct sockaddr *)&ss,
471 	    &len, FD_RESERVE, &cgi_inflight)) == -1) {
472 		switch (errno) {
473 		case EINTR:
474 		case EWOULDBLOCK:
475 		case ECONNABORTED:
476 			return;
477 		case EMFILE:
478 		case ENFILE:
479 			event_del(&l->ev);
480 			evtimer_add(&l->pause, &backoff);
481 			return;
482 		default:
483 			lerr(1, "accept");
484 		}
485 	}
486 
487 	c = calloc(1, sizeof(*c));
488 	if (c == NULL) {
489 		lwarn("cannot calloc request");
490 		close(s);
491 		cgi_inflight--;
492 		return;
493 	}
494 	requests = calloc(1, sizeof(*requests));
495 	if (requests == NULL) {
496 		lwarn("cannot calloc requests");
497 		close(s);
498 		cgi_inflight--;
499 		free(c);
500 		return;
501 	}
502 	c->fd = s;
503 	c->buf_pos = 0;
504 	c->buf_len = 0;
505 	c->request_started = 0;
506 	c->stdin_fd_closed = c->stdout_fd_closed = c->stderr_fd_closed = 0;
507 	c->inflight_fds_accounted = 0;
508 	TAILQ_INIT(&c->response_head);
509 	TAILQ_INIT(&c->stdin_head);
510 
511 	event_set(&c->ev, s, EV_READ | EV_PERSIST, slowcgi_request, c);
512 	event_add(&c->ev, NULL);
513 	event_set(&c->resp_ev, s, EV_WRITE | EV_PERSIST, slowcgi_response, c);
514 	evtimer_set(&c->tmo, slowcgi_timeout, c);
515 	evtimer_add(&c->tmo, &timeout);
516 	requests->request = c;
517 	SLIST_INSERT_HEAD(&slowcgi_proc.requests, requests, entry);
518 }
519 
520 void
521 slowcgi_timeout(int fd, short events, void *arg)
522 {
523 	cleanup_request((struct request*) arg);
524 }
525 
526 void
527 slowcgi_sig_handler(int sig, short event, void *arg)
528 {
529 	struct request		*c;
530 	struct requests		*ncs;
531 	struct slowcgi_proc	*p;
532 	pid_t			 pid;
533 	int			 status;
534 
535 	p = arg;
536 
537 	switch (sig) {
538 	case SIGCHLD:
539 		while ((pid = waitpid(WAIT_ANY, &status, WNOHANG)) > 0) {
540 			c = NULL;
541 			SLIST_FOREACH(ncs, &p->requests, entry)
542 				if (ncs->request->script_pid == pid) {
543 					c = ncs->request;
544 					break;
545 				}
546 			if (c == NULL) {
547 				lwarnx("caught exit of unknown child %i", pid);
548 				continue;
549 			}
550 
551 			if (WIFSIGNALED(status))
552 				c->script_status = WTERMSIG(status);
553 			else
554 				c->script_status = WEXITSTATUS(status);
555 
556 			if (c->script_flags == (STDOUT_DONE | STDERR_DONE))
557 				create_end_record(c);
558 			c->script_flags |= SCRIPT_DONE;
559 
560 			ldebug("wait: %s", c->script_name);
561 		}
562 		if (pid == -1 && errno != ECHILD)
563 			lwarn("waitpid");
564 		break;
565 	case SIGPIPE:
566 		/* ignore */
567 		break;
568 	default:
569 		lerr(1, "unexpected signal: %d", sig);
570 		break;
571 	}
572 }
573 
574 void
575 slowcgi_add_response(struct request *c, struct fcgi_response *resp)
576 {
577 	struct fcgi_record_header	*header;
578 	size_t				 padded_len;
579 
580 	header = (struct fcgi_record_header*)resp->data;
581 
582 	/* The FastCGI spec suggests to align the output buffer */
583 	padded_len = FCGI_ALIGN(resp->data_len);
584 	if (padded_len > resp->data_len) {
585 		/* There should always be FCGI_PADDING_SIZE bytes left */
586 		if (padded_len > FCGI_RECORD_SIZE)
587 			lerr(1, "response too long");
588 		header->padding_len = padded_len - resp->data_len;
589 		resp->data_len = padded_len;
590 	}
591 
592 	TAILQ_INSERT_TAIL(&c->response_head, resp, entry);
593 	event_add(&c->resp_ev, NULL);
594 }
595 
596 void
597 slowcgi_response(int fd, short events, void *arg)
598 {
599 	struct request			*c;
600 	struct fcgi_record_header	*header;
601 	struct fcgi_response		*resp;
602 	ssize_t				 n;
603 
604 	c = arg;
605 
606 	while ((resp = TAILQ_FIRST(&c->response_head))) {
607 		header = (struct fcgi_record_header*) resp->data;
608 		if (debug > 1)
609 			dump_fcgi_record("resp ", header);
610 
611 		n = write(fd, resp->data + resp->data_pos, resp->data_len);
612 		if (n == -1) {
613 			if (errno == EAGAIN || errno == EINTR)
614 				return;
615 			cleanup_request(c);
616 			return;
617 		}
618 		resp->data_pos += n;
619 		resp->data_len -= n;
620 		if (resp->data_len == 0) {
621 			TAILQ_REMOVE(&c->response_head, resp, entry);
622 			free(resp);
623 		}
624 	}
625 
626 	if (TAILQ_EMPTY(&c->response_head)) {
627 		if (c->script_flags == (STDOUT_DONE | STDERR_DONE |
628 		    SCRIPT_DONE))
629 			cleanup_request(c);
630 		else
631 			event_del(&c->resp_ev);
632 	}
633 }
634 
635 void
636 slowcgi_request(int fd, short events, void *arg)
637 {
638 	struct request	*c;
639 	ssize_t		 n;
640 	size_t		 parsed;
641 
642 	c = arg;
643 
644 	n = read(fd, c->buf + c->buf_pos + c->buf_len,
645 	    FCGI_RECORD_SIZE - c->buf_pos-c->buf_len);
646 
647 	switch (n) {
648 	case -1:
649 		switch (errno) {
650 		case EINTR:
651 		case EAGAIN:
652 			return;
653 		default:
654 			goto fail;
655 		}
656 		break;
657 
658 	case 0:
659 		ldebug("closed connection");
660 		goto fail;
661 	default:
662 		break;
663 	}
664 
665 	c->buf_len += n;
666 
667 	/*
668 	 * Parse the records as they are received. Per the FastCGI
669 	 * specification, the server need only receive the FastCGI
670 	 * parameter records in full; it is free to begin execution
671 	 * at that point, which is what happens here.
672 	 */
673 	do {
674 		parsed = parse_record(c->buf + c->buf_pos, c->buf_len, c);
675 		c->buf_pos += parsed;
676 		c->buf_len -= parsed;
677 	} while (parsed > 0 && c->buf_len > 0);
678 
679 	/* Make space for further reads */
680 	if (c->buf_len > 0) {
681 		bcopy(c->buf + c->buf_pos, c->buf, c->buf_len);
682 		c->buf_pos = 0;
683 	}
684 	return;
685 fail:
686 	cleanup_request(c);
687 }
688 
689 void
690 parse_begin_request(uint8_t *buf, uint16_t n, struct request *c, uint16_t id)
691 {
692 	/* XXX -- FCGI_CANT_MPX_CONN */
693 	if (c->request_started) {
694 		lwarnx("unexpected FCGI_BEGIN_REQUEST, ignoring");
695 		return;
696 	}
697 
698 	if (n != sizeof(struct fcgi_begin_request_body)) {
699 		lwarnx("wrong size %d != %lu", n,
700 		    sizeof(struct fcgi_begin_request_body));
701 		return;
702 	}
703 
704 	c->request_started = 1;
705 
706 	c->id = id;
707 	SLIST_INIT(&c->env);
708 	c->env_count = 0;
709 }
710 
711 void
712 parse_params(uint8_t *buf, uint16_t n, struct request *c, uint16_t id)
713 {
714 	struct env_val			*env_entry;
715 	uint32_t			 name_len, val_len;
716 
717 	if (!c->request_started) {
718 		lwarnx("FCGI_PARAMS without FCGI_BEGIN_REQUEST, ignoring");
719 		return;
720 	}
721 
722 	if (c->id != id) {
723 		lwarnx("unexpected id, ignoring");
724 		return;
725 	}
726 
727 	/*
728 	 * If this is the last FastCGI parameter record,
729 	 * begin execution of the CGI script.
730 	 */
731 	if (n == 0) {
732 		exec_cgi(c);
733 		return;
734 	}
735 
736 	while (n > 0) {
737 		if (buf[0] >> 7 == 0) {
738 			name_len = buf[0];
739 			n--;
740 			buf++;
741 		} else {
742 			if (n > 3) {
743 				name_len = ((buf[0] & 0x7f) << 24) +
744 				    (buf[1] << 16) + (buf[2] << 8) + buf[3];
745 				n -= 4;
746 				buf += 4;
747 			} else
748 				return;
749 		}
750 
751 		if (n > 0) {
752 			if (buf[0] >> 7 == 0) {
753 				val_len = buf[0];
754 				n--;
755 				buf++;
756 			} else {
757 				if (n > 3) {
758 					val_len = ((buf[0] & 0x7f) << 24) +
759 					    (buf[1] << 16) + (buf[2] << 8) +
760 					     buf[3];
761 					n -= 4;
762 					buf += 4;
763 				} else
764 					return;
765 			}
766 		} else
767 			return;
768 
769 		if (n < name_len + val_len)
770 			return;
771 
772 		if ((env_entry = malloc(sizeof(struct env_val))) == NULL) {
773 			lwarnx("cannot allocate env_entry");
774 			return;
775 		}
776 
777 		if ((env_entry->val = calloc(sizeof(char), name_len + val_len +
778 		    2)) == NULL) {
779 			lwarnx("cannot allocate env_entry->val");
780 			free(env_entry);
781 			return;
782 		}
783 
784 		bcopy(buf, env_entry->val, name_len);
785 		buf += name_len;
786 		n -= name_len;
787 
788 		env_entry->val[name_len] = '\0';
789 		if (val_len < PATH_MAX && strcmp(env_entry->val,
790 		    "SCRIPT_NAME") == 0 && c->script_name[0] == '\0') {
791 			bcopy(buf, c->script_name, val_len);
792 			c->script_name[val_len] = '\0';
793 		} else if (val_len < PATH_MAX && strcmp(env_entry->val,
794 		    "SCRIPT_FILENAME") == 0) {
795 			bcopy(buf, c->script_name, val_len);
796 			c->script_name[val_len] = '\0';
797 		}
798 		env_entry->val[name_len] = '=';
799 
800 		bcopy(buf, (env_entry->val) + name_len + 1, val_len);
801 		buf += val_len;
802 		n -= val_len;
803 
804 		SLIST_INSERT_HEAD(&c->env, env_entry, entry);
805 		ldebug("env[%d], %s", c->env_count, env_entry->val);
806 		c->env_count++;
807 	}
808 }
809 
810 void
811 parse_stdin(uint8_t *buf, uint16_t n, struct request *c, uint16_t id)
812 {
813 	struct fcgi_stdin	*node;
814 
815 	if (c->id != id) {
816 		lwarnx("unexpected id, ignoring");
817 		return;
818 	}
819 
820 	if ((node = calloc(1, sizeof(struct fcgi_stdin))) == NULL) {
821 		lwarnx("cannot calloc stdin node");
822 		return;
823 	}
824 
825 	bcopy(buf, node->data, n);
826 	node->data_pos = 0;
827 	node->data_len = n;
828 
829 	TAILQ_INSERT_TAIL(&c->stdin_head, node, entry);
830 
831 	if (event_initialized(&c->script_stdin_ev))
832 		event_add(&c->script_stdin_ev, NULL);
833 }
834 
835 size_t
836 parse_record(uint8_t *buf, size_t n, struct request *c)
837 {
838 	struct fcgi_record_header	*h;
839 
840 	if (n < sizeof(struct fcgi_record_header))
841 		return (0);
842 
843 	h = (struct fcgi_record_header*) buf;
844 
845 	if (debug > 1)
846 		dump_fcgi_record("", h);
847 
848 	if (n < sizeof(struct fcgi_record_header) + ntohs(h->content_len)
849 	    + h->padding_len)
850 		return (0);
851 
852 	if (h->version != 1)
853 		lerrx(1, "wrong version");
854 
855 	switch (h->type) {
856 	case FCGI_BEGIN_REQUEST:
857 		parse_begin_request(buf + sizeof(struct fcgi_record_header),
858 		    ntohs(h->content_len), c, ntohs(h->id));
859 		break;
860 	case FCGI_PARAMS:
861 		parse_params(buf + sizeof(struct fcgi_record_header),
862 		    ntohs(h->content_len), c, ntohs(h->id));
863 		break;
864 	case FCGI_STDIN:
865 		parse_stdin(buf + sizeof(struct fcgi_record_header),
866 		    ntohs(h->content_len), c, ntohs(h->id));
867 		break;
868 	default:
869 		lwarnx("unimplemented type %d", h->type);
870 		break;
871 	}
872 
873 	return (sizeof(struct fcgi_record_header) + ntohs(h->content_len)
874 	    + h->padding_len);
875 }
876 
877 /*
878  * Fork a new CGI process to handle the request, translating
879  * between FastCGI parameter records and CGI's environment variables,
880  * as well as between the CGI process' stdin/stdout and the
881  * corresponding FastCGI records.
882  */
883 void
884 exec_cgi(struct request *c)
885 {
886 	struct env_val	*env_entry;
887 	int		 s_in[2], s_out[2], s_err[2], i;
888 	pid_t		 pid;
889 	char		*argv[2];
890 	char		**env;
891 	char		*path;
892 
893 	i = 0;
894 
895 	if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, s_in) == -1)
896 		lerr(1, "socketpair");
897 	if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, s_out) == -1)
898 		lerr(1, "socketpair");
899 	if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, s_err) == -1)
900 		lerr(1, "socketpair");
901 	cgi_inflight--;
902 	c->inflight_fds_accounted = 1;
903 	ldebug("fork: %s", c->script_name);
904 
905 	switch (pid = fork()) {
906 	case -1:
907 		c->script_status = errno;
908 
909 		lwarn("fork");
910 
911 		close(s_in[0]);
912 		close(s_out[0]);
913 		close(s_err[0]);
914 
915 		close(s_in[1]);
916 		close(s_out[1]);
917 		close(s_err[1]);
918 
919 		c->stdin_fd_closed = c->stdout_fd_closed =
920 		    c->stderr_fd_closed = 1;
921 		c->script_flags = (STDOUT_DONE | STDERR_DONE | SCRIPT_DONE);
922 
923 		create_end_record(c);
924 		return;
925 	case 0:
926 		/* Child process */
927 		if (pledge("stdio rpath exec", NULL) == -1)
928 			lerr(1, "pledge");
929 		close(s_in[0]);
930 		close(s_out[0]);
931 		close(s_err[0]);
932 
933 		if (dup2(s_in[1], STDIN_FILENO) == -1)
934 			_exit(1);
935 		if (dup2(s_out[1], STDOUT_FILENO) == -1)
936 			_exit(1);
937 		if (dup2(s_err[1], STDERR_FILENO) == -1)
938 			_exit(1);
939 
940 		close(s_in[1]);
941 		close(s_out[1]);
942 		close(s_err[1]);
943 
944 		path = strrchr(c->script_name, '/');
945 		if (path != NULL) {
946 			if (path != c->script_name) {
947 				*path = '\0';
948 				if (chdir(c->script_name) == -1)
949 					lwarn("cannot chdir to %s",
950 					    c->script_name);
951 				*path = '/';
952 			} else
953 				if (chdir("/") == -1)
954 					lwarn("cannot chdir to /");
955 		}
956 
957 		argv[0] = c->script_name;
958 		argv[1] = NULL;
959 		if ((env = calloc(c->env_count + 1, sizeof(char*))) == NULL)
960 			_exit(1);
961 		SLIST_FOREACH(env_entry, &c->env, entry)
962 			env[i++] = env_entry->val;
963 		env[i++] = NULL;
964 		execve(c->script_name, argv, env);
965 		lwarn("execve %s", c->script_name);
966 		_exit(1);
967 
968 	}
969 
970 	/* Parent process*/
971 	close(s_in[1]);
972 	close(s_out[1]);
973 	close(s_err[1]);
974 
975 	fcntl(s_in[0], F_SETFD, FD_CLOEXEC);
976 	fcntl(s_out[0], F_SETFD, FD_CLOEXEC);
977 	fcntl(s_err[0], F_SETFD, FD_CLOEXEC);
978 
979 	if (ioctl(s_in[0], FIONBIO, &on) == -1)
980 		lerr(1, "script ioctl(FIONBIO)");
981 	if (ioctl(s_out[0], FIONBIO, &on) == -1)
982 		lerr(1, "script ioctl(FIONBIO)");
983 	if (ioctl(s_err[0], FIONBIO, &on) == -1)
984 		lerr(1, "script ioctl(FIONBIO)");
985 
986 	c->script_pid = pid;
987 	event_set(&c->script_stdin_ev, s_in[0], EV_WRITE | EV_PERSIST,
988 	    script_out, c);
989 	event_add(&c->script_stdin_ev, NULL);
990 	event_set(&c->script_ev, s_out[0], EV_READ | EV_PERSIST,
991 	    script_std_in, c);
992 	event_add(&c->script_ev, NULL);
993 	event_set(&c->script_err_ev, s_err[0], EV_READ | EV_PERSIST,
994 	    script_err_in, c);
995 	event_add(&c->script_err_ev, NULL);
996 }
997 
998 void
999 create_end_record(struct request *c)
1000 {
1001 	struct fcgi_response		*resp;
1002 	struct fcgi_record_header	*header;
1003 	struct fcgi_end_request_body	*end_request;
1004 
1005 	if ((resp = calloc(1, sizeof(struct fcgi_response))) == NULL) {
1006 		lwarnx("cannot malloc fcgi_response");
1007 		return;
1008 	}
1009 	header = (struct fcgi_record_header*) resp->data;
1010 	header->version = 1;
1011 	header->type = FCGI_END_REQUEST;
1012 	header->id = htons(c->id);
1013 	header->content_len = htons(sizeof(struct
1014 	    fcgi_end_request_body));
1015 	header->padding_len = 0;
1016 	header->reserved = 0;
1017 	end_request = (struct fcgi_end_request_body *) (resp->data +
1018 	    sizeof(struct fcgi_record_header));
1019 	end_request->app_status = htonl(c->script_status);
1020 	end_request->protocol_status = FCGI_REQUEST_COMPLETE;
1021 	end_request->reserved[0] = 0;
1022 	end_request->reserved[1] = 0;
1023 	end_request->reserved[2] = 0;
1024 	resp->data_pos = 0;
1025 	resp->data_len = sizeof(struct fcgi_end_request_body) +
1026 	    sizeof(struct fcgi_record_header);
1027 	slowcgi_add_response(c, resp);
1028 }
1029 
1030 void
1031 script_in(int fd, struct event *ev, struct request *c, uint8_t type)
1032 {
1033 	struct fcgi_response		*resp;
1034 	struct fcgi_record_header	*header;
1035 	ssize_t				 n;
1036 
1037 	if ((resp = calloc(1, sizeof(struct fcgi_response))) == NULL) {
1038 		lwarnx("cannot malloc fcgi_response");
1039 		return;
1040 	}
1041 	header = (struct fcgi_record_header*) resp->data;
1042 	header->version = 1;
1043 	header->type = type;
1044 	header->id = htons(c->id);
1045 	header->padding_len = 0;
1046 	header->reserved = 0;
1047 
1048 	n = read(fd, resp->data + sizeof(struct fcgi_record_header),
1049 	    FCGI_CONTENT_SIZE);
1050 
1051 	if (n == -1) {
1052 		switch (errno) {
1053 		case EINTR:
1054 		case EAGAIN:
1055 			free(resp);
1056 			return;
1057 		default:
1058 			n = 0; /* fake empty FCGI_STD{OUT,ERR} response */
1059 		}
1060 	}
1061 	header->content_len = htons(n);
1062 	resp->data_pos = 0;
1063 	resp->data_len = n + sizeof(struct fcgi_record_header);
1064 	slowcgi_add_response(c, resp);
1065 
1066 	if (n == 0) {
1067 		if (type == FCGI_STDOUT)
1068 			c->script_flags |= STDOUT_DONE;
1069 		else
1070 			c->script_flags |= STDERR_DONE;
1071 
1072 		if (c->script_flags == (STDOUT_DONE | STDERR_DONE |
1073 		    SCRIPT_DONE)) {
1074 			create_end_record(c);
1075 		}
1076 		event_del(ev);
1077 		close(fd);
1078 		if (type == FCGI_STDOUT)
1079 			c->stdout_fd_closed = 1;
1080 		else
1081 			c->stderr_fd_closed = 1;
1082 	}
1083 }
1084 
1085 void
1086 script_std_in(int fd, short events, void *arg)
1087 {
1088 	struct request *c = arg;
1089 	script_in(fd, &c->script_ev, c, FCGI_STDOUT);
1090 }
1091 
1092 void
1093 script_err_in(int fd, short events, void *arg)
1094 {
1095 	struct request *c = arg;
1096 	script_in(fd, &c->script_err_ev, c, FCGI_STDERR);
1097 }
1098 
1099 void
1100 script_out(int fd, short events, void *arg)
1101 {
1102 	struct request		*c;
1103 	struct fcgi_stdin	*node;
1104 	ssize_t			 n;
1105 
1106 	c = arg;
1107 
1108 	while ((node = TAILQ_FIRST(&c->stdin_head))) {
1109 		if (node->data_len == 0) { /* end of stdin marker */
1110 			close(fd);
1111 			c->stdin_fd_closed = 1;
1112 			break;
1113 		}
1114 		n = write(fd, node->data + node->data_pos, node->data_len);
1115 		if (n == -1) {
1116 			if (errno == EAGAIN || errno == EINTR)
1117 				return;
1118 			event_del(&c->script_stdin_ev);
1119 			return;
1120 		}
1121 		node->data_pos += n;
1122 		node->data_len -= n;
1123 		if (node->data_len == 0) {
1124 			TAILQ_REMOVE(&c->stdin_head, node, entry);
1125 			free(node);
1126 		}
1127 	}
1128 	event_del(&c->script_stdin_ev);
1129 }
1130 
1131 void
1132 cleanup_request(struct request *c)
1133 {
1134 	struct fcgi_response	*resp;
1135 	struct fcgi_stdin	*stdin_node;
1136 	struct env_val		*env_entry;
1137 	struct requests		*ncs, *tcs;
1138 
1139 	evtimer_del(&c->tmo);
1140 	if (event_initialized(&c->ev))
1141 		event_del(&c->ev);
1142 	if (event_initialized(&c->resp_ev))
1143 		event_del(&c->resp_ev);
1144 	if (event_initialized(&c->script_ev)) {
1145 		if (!c->stdout_fd_closed)
1146 			close(EVENT_FD(&c->script_ev));
1147 		event_del(&c->script_ev);
1148 	}
1149 	if (event_initialized(&c->script_err_ev)) {
1150 		if (!c->stderr_fd_closed)
1151 			close(EVENT_FD(&c->script_err_ev));
1152 		event_del(&c->script_err_ev);
1153 	}
1154 	if (event_initialized(&c->script_stdin_ev)) {
1155 		if (!c->stdin_fd_closed)
1156 			close(EVENT_FD(&c->script_stdin_ev));
1157 		event_del(&c->script_stdin_ev);
1158 	}
1159 	close(c->fd);
1160 	while (!SLIST_EMPTY(&c->env)) {
1161 		env_entry = SLIST_FIRST(&c->env);
1162 		SLIST_REMOVE_HEAD(&c->env, entry);
1163 		free(env_entry->val);
1164 		free(env_entry);
1165 	}
1166 
1167 	while ((resp = TAILQ_FIRST(&c->response_head))) {
1168 		TAILQ_REMOVE(&c->response_head, resp, entry);
1169 		free(resp);
1170 	}
1171 	while ((stdin_node = TAILQ_FIRST(&c->stdin_head))) {
1172 		TAILQ_REMOVE(&c->stdin_head, stdin_node, entry);
1173 		free(stdin_node);
1174 	}
1175 	SLIST_FOREACH_SAFE(ncs, &slowcgi_proc.requests, entry, tcs) {
1176 		if (ncs->request == c) {
1177 			SLIST_REMOVE(&slowcgi_proc.requests, ncs, requests,
1178 			    entry);
1179 			free(ncs);
1180 			break;
1181 		}
1182 	}
1183 	if (! c->inflight_fds_accounted)
1184 		cgi_inflight--;
1185 	free(c);
1186 }
1187 
1188 void
1189 dump_fcgi_record(const char *p, struct fcgi_record_header *h)
1190 {
1191 	dump_fcgi_record_header(p, h);
1192 
1193 	if (h->type == FCGI_BEGIN_REQUEST)
1194 		dump_fcgi_begin_request_body(p,
1195 		    (struct fcgi_begin_request_body *)(h + 1));
1196 	else if (h->type == FCGI_END_REQUEST)
1197 		dump_fcgi_end_request_body(p,
1198 		    (struct fcgi_end_request_body *)(h + 1));
1199 }
1200 
1201 void
1202 dump_fcgi_record_header(const char* p, struct fcgi_record_header *h)
1203 {
1204 	ldebug("%sversion:         %d", p, h->version);
1205 	ldebug("%stype:            %d", p, h->type);
1206 	ldebug("%srequestId:       %d", p, ntohs(h->id));
1207 	ldebug("%scontentLength:   %d", p, ntohs(h->content_len));
1208 	ldebug("%spaddingLength:   %d", p, h->padding_len);
1209 	ldebug("%sreserved:        %d", p, h->reserved);
1210 }
1211 
1212 void
1213 dump_fcgi_begin_request_body(const char *p, struct fcgi_begin_request_body *b)
1214 {
1215 	ldebug("%srole             %d", p, ntohs(b->role));
1216 	ldebug("%sflags            %d", p, b->flags);
1217 }
1218 
1219 void
1220 dump_fcgi_end_request_body(const char *p, struct fcgi_end_request_body *b)
1221 {
1222 	ldebug("%sappStatus:       %d", p, ntohl(b->app_status));
1223 	ldebug("%sprotocolStatus:  %d", p, b->protocol_status);
1224 }
1225 
1226 void
1227 syslog_vstrerror(int e, int priority, const char *fmt, va_list ap)
1228 {
1229 	char *s;
1230 
1231 	if (vasprintf(&s, fmt, ap) == -1) {
1232 		syslog(LOG_EMERG, "unable to alloc in syslog_vstrerror");
1233 		exit(1);
1234 	}
1235 	syslog(priority, "%s: %s", s, strerror(e));
1236 	free(s);
1237 }
1238 
1239 __dead void
1240 syslog_err(int ecode, const char *fmt, ...)
1241 {
1242 	va_list ap;
1243 
1244 	va_start(ap, fmt);
1245 	syslog_vstrerror(errno, LOG_CRIT, fmt, ap);
1246 	va_end(ap);
1247 	exit(ecode);
1248 }
1249 
1250 __dead void
1251 syslog_errx(int ecode, const char *fmt, ...)
1252 {
1253 	va_list ap;
1254 
1255 	va_start(ap, fmt);
1256 	vsyslog(LOG_CRIT, fmt, ap);
1257 	va_end(ap);
1258 	exit(ecode);
1259 }
1260 
1261 void
1262 syslog_warn(const char *fmt, ...)
1263 {
1264 	va_list ap;
1265 
1266 	va_start(ap, fmt);
1267 	syslog_vstrerror(errno, LOG_ERR, fmt, ap);
1268 	va_end(ap);
1269 }
1270 
1271 void
1272 syslog_warnx(const char *fmt, ...)
1273 {
1274 	va_list ap;
1275 
1276 	va_start(ap, fmt);
1277 	vsyslog(LOG_ERR, fmt, ap);
1278 	va_end(ap);
1279 }
1280 
1281 void
1282 syslog_info(const char *fmt, ...)
1283 {
1284 	va_list ap;
1285 
1286 	va_start(ap, fmt);
1287 	vsyslog(LOG_INFO, fmt, ap);
1288 	va_end(ap);
1289 }
1290 
1291 void
1292 syslog_debug(const char *fmt, ...)
1293 {
1294 	va_list ap;
1295 
1296 	va_start(ap, fmt);
1297 	vsyslog(LOG_DEBUG, fmt, ap);
1298 	va_end(ap);
1299 }
1300