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