1 /* $NetBSD: inetd.c,v 1.139 2021/10/17 04:14:49 ryo Exp $ */ 2 3 /*- 4 * Copyright (c) 1998, 2003 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, 9 * NASA Ames Research Center and by Matthias Scheler. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 /* 34 * Copyright (c) 1983, 1991, 1993, 1994 35 * The Regents of the University of California. All rights reserved. 36 * 37 * Redistribution and use in source and binary forms, with or without 38 * modification, are permitted provided that the following conditions 39 * are met: 40 * 1. Redistributions of source code must retain the above copyright 41 * notice, this list of conditions and the following disclaimer. 42 * 2. Redistributions in binary form must reproduce the above copyright 43 * notice, this list of conditions and the following disclaimer in the 44 * documentation and/or other materials provided with the distribution. 45 * 3. Neither the name of the University nor the names of its contributors 46 * may be used to endorse or promote products derived from this software 47 * without specific prior written permission. 48 * 49 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 50 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 51 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 52 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 53 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 54 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 55 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 56 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 57 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 58 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 59 * SUCH DAMAGE. 60 */ 61 62 #include <sys/cdefs.h> 63 #ifndef lint 64 __COPYRIGHT("@(#) Copyright (c) 1983, 1991, 1993, 1994\ 65 The Regents of the University of California. All rights reserved."); 66 #if 0 67 static char sccsid[] = "@(#)inetd.c 8.4 (Berkeley) 4/13/94"; 68 #else 69 __RCSID("$NetBSD: inetd.c,v 1.139 2021/10/17 04:14:49 ryo Exp $"); 70 #endif 71 #endif /* not lint */ 72 73 /* 74 * Inetd - Internet super-server 75 * 76 * This program invokes all internet services as needed. Connection-oriented 77 * services are invoked each time a connection is made, by creating a process. 78 * This process is passed the connection as file descriptor 0 and is expected 79 * to do a getpeername to find out the source host and port. 80 * 81 * Datagram oriented services are invoked when a datagram 82 * arrives; a process is created and passed a pending message 83 * on file descriptor 0. Datagram servers may either connect 84 * to their peer, freeing up the original socket for inetd 85 * to receive further messages on, or ``take over the socket'', 86 * processing all arriving datagrams and, eventually, timing 87 * out. The first type of server is said to be ``multi-threaded''; 88 * the second type of server ``single-threaded''. 89 * 90 * Inetd uses a configuration file which is read at startup 91 * and, possibly, at some later time in response to a hangup signal. 92 * The configuration file is ``free format'' with fields given in the 93 * order shown below. Continuation lines for an entry must being with 94 * a space or tab. All fields must be present in each entry. 95 * 96 * service name must be in /etc/services or must 97 * name a tcpmux service 98 * socket type[:accf[,arg]] stream/dgram/raw/rdm/seqpacket, 99 only stream can name an accept filter 100 * protocol must be in /etc/protocols 101 * wait/nowait[:max] single-threaded/multi-threaded, max # 102 * user[:group] user/group to run daemon as 103 * server program full path name 104 * server program arguments maximum of MAXARGV (64) 105 * 106 * For RPC services 107 * service name/version must be in /etc/rpc 108 * socket type stream/dgram/raw/rdm/seqpacket 109 * protocol must be in /etc/protocols 110 * wait/nowait[:max] single-threaded/multi-threaded 111 * user[:group] user to run daemon as 112 * server program full path name 113 * server program arguments maximum of MAXARGV (64) 114 * 115 * For non-RPC services, the "service name" can be of the form 116 * hostaddress:servicename, in which case the hostaddress is used 117 * as the host portion of the address to listen on. If hostaddress 118 * consists of a single `*' character, INADDR_ANY is used. 119 * 120 * A line can also consist of just 121 * hostaddress: 122 * where hostaddress is as in the preceding paragraph. Such a line must 123 * have no further fields; the specified hostaddress is remembered and 124 * used for all further lines that have no hostaddress specified, 125 * until the next such line (or EOF). (This is why * is provided to 126 * allow explicit specification of INADDR_ANY.) A line 127 * *: 128 * is implicitly in effect at the beginning of the file. 129 * 130 * The hostaddress specifier may (and often will) contain dots; 131 * the service name must not. 132 * 133 * For RPC services, host-address specifiers are accepted and will 134 * work to some extent; however, because of limitations in the 135 * portmapper interface, it will not work to try to give more than 136 * one line for any given RPC service, even if the host-address 137 * specifiers are different. 138 * 139 * TCP services without official port numbers are handled with the 140 * RFC1078-based tcpmux internal service. Tcpmux listens on port 1 for 141 * requests. When a connection is made from a foreign host, the service 142 * requested is passed to tcpmux, which looks it up in the servtab list 143 * and returns the proper entry for the service. Tcpmux returns a 144 * negative reply if the service doesn't exist, otherwise the invoked 145 * server is expected to return the positive reply if the service type in 146 * inetd.conf file has the prefix "tcpmux/". If the service type has the 147 * prefix "tcpmux/+", tcpmux will return the positive reply for the 148 * process; this is for compatibility with older server code, and also 149 * allows you to invoke programs that use stdin/stdout without putting any 150 * special server code in them. Services that use tcpmux are "nowait" 151 * because they do not have a well-known port and hence cannot listen 152 * for new requests. 153 * 154 * Comment lines are indicated by a `#' in column 1. 155 * 156 * #ifdef IPSEC 157 * Comment lines that start with "#@" denote IPsec policy string, as described 158 * in ipsec_set_policy(3). This will affect all the following items in 159 * inetd.conf(8). To reset the policy, just use "#@" line. By default, 160 * there's no IPsec policy. 161 * #endif 162 */ 163 164 /* 165 * Here's the scoop concerning the user:group feature: 166 * 167 * 1) set-group-option off. 168 * 169 * a) user = root: NO setuid() or setgid() is done 170 * 171 * b) other: setuid() 172 * setgid(primary group as found in passwd) 173 * initgroups(name, primary group) 174 * 175 * 2) set-group-option on. 176 * 177 * a) user = root: NO setuid() 178 * setgid(specified group) 179 * NO initgroups() 180 * 181 * b) other: setuid() 182 * setgid(specified group) 183 * initgroups(name, specified group) 184 * 185 */ 186 187 #include <sys/param.h> 188 #include <sys/stat.h> 189 #include <sys/ioctl.h> 190 #include <sys/wait.h> 191 #include <sys/resource.h> 192 #include <sys/event.h> 193 #include <sys/socket.h> 194 #include <sys/queue.h> 195 196 197 #ifndef NO_RPC 198 #define RPC 199 #endif 200 201 #include <net/if.h> 202 203 #ifdef RPC 204 #include <rpc/rpc.h> 205 #include <rpc/rpcb_clnt.h> 206 #include <netconfig.h> 207 #endif 208 209 #include <ctype.h> 210 #include <err.h> 211 #include <errno.h> 212 #include <fcntl.h> 213 #include <glob.h> 214 #include <grp.h> 215 #include <libgen.h> 216 #include <pwd.h> 217 #include <signal.h> 218 #include <stdio.h> 219 #include <stdlib.h> 220 #include <string.h> 221 #include <syslog.h> 222 #include <unistd.h> 223 #include <util.h> 224 #include <ifaddrs.h> 225 226 #include "inetd.h" 227 228 #ifdef LIBWRAP 229 # include <tcpd.h> 230 #ifndef LIBWRAP_ALLOW_FACILITY 231 # define LIBWRAP_ALLOW_FACILITY LOG_AUTH 232 #endif 233 #ifndef LIBWRAP_ALLOW_SEVERITY 234 # define LIBWRAP_ALLOW_SEVERITY LOG_INFO 235 #endif 236 #ifndef LIBWRAP_DENY_FACILITY 237 # define LIBWRAP_DENY_FACILITY LOG_AUTH 238 #endif 239 #ifndef LIBWRAP_DENY_SEVERITY 240 # define LIBWRAP_DENY_SEVERITY LOG_WARNING 241 #endif 242 int allow_severity = LIBWRAP_ALLOW_FACILITY|LIBWRAP_ALLOW_SEVERITY; 243 int deny_severity = LIBWRAP_DENY_FACILITY|LIBWRAP_DENY_SEVERITY; 244 #endif 245 246 static bool foreground; 247 int debug; 248 #ifdef LIBWRAP 249 int lflag; 250 #endif 251 int maxsock; 252 int kq; 253 int options; 254 int timingout; 255 const int niflags = NI_NUMERICHOST | NI_NUMERICSERV; 256 257 #ifndef OPEN_MAX 258 #define OPEN_MAX 64 259 #endif 260 261 /* Reserve some descriptors, 3 stdio + at least: 1 log, 1 conf. file */ 262 #define FD_MARGIN (8) 263 rlim_t rlim_ofile_cur = OPEN_MAX; 264 265 struct rlimit rlim_ofile; 266 267 struct kevent changebuf[64]; 268 size_t changes; 269 270 struct servtab *servtab; 271 272 static ssize_t recvfromto(int, void * restrict, size_t, int, 273 struct sockaddr * restrict, socklen_t * restrict, 274 struct sockaddr * restrict, socklen_t * restrict); 275 static ssize_t sendfromto(int, const void *, size_t, int, 276 const struct sockaddr *, socklen_t, const struct sockaddr *, socklen_t); 277 static void chargen_dg(int, struct servtab *); 278 static void chargen_stream(int, struct servtab *); 279 static void daytime_dg(int, struct servtab *); 280 static void daytime_stream(int, struct servtab *); 281 static void discard_dg(int, struct servtab *); 282 static void discard_stream(int, struct servtab *); 283 static void echo_dg(int, struct servtab *); 284 static void echo_stream(int, struct servtab *); 285 __dead static void goaway(void); 286 static void machtime_dg(int, struct servtab *); 287 static void machtime_stream(int, struct servtab *); 288 static void reapchild(void); 289 static void retry(void); 290 static void run_service(int, struct servtab *, int); 291 static void tcpmux(int, struct servtab *); 292 __dead static void usage(void); 293 static void bump_nofile(void); 294 static void inetd_setproctitle(char *, int); 295 static void initring(void); 296 static uint32_t machtime(void); 297 static int port_good_dg(struct sockaddr *); 298 static int dg_broadcast(struct in_addr *); 299 static int my_kevent(const struct kevent *, size_t, struct kevent *, size_t); 300 static struct kevent *allocchange(void); 301 static int get_line(int, char *, int); 302 static void spawn(struct servtab *, int); 303 304 struct biltin { 305 const char *bi_service; /* internally provided service name */ 306 int bi_socktype; /* type of socket supported */ 307 short bi_fork; /* 1 if should fork before call */ 308 short bi_wait; /* 1 if should wait for child */ 309 void (*bi_fn)(int, struct servtab *); 310 /* function which performs it */ 311 } biltins[] = { 312 /* Echo received data */ 313 { "echo", SOCK_STREAM, true, false, echo_stream }, 314 { "echo", SOCK_DGRAM, false, false, echo_dg }, 315 316 /* Internet /dev/null */ 317 { "discard", SOCK_STREAM, true, false, discard_stream }, 318 { "discard", SOCK_DGRAM, false, false, discard_dg }, 319 320 /* Return 32 bit time since 1970 */ 321 { "time", SOCK_STREAM, false, false, machtime_stream }, 322 { "time", SOCK_DGRAM, false, false, machtime_dg }, 323 324 /* Return human-readable time */ 325 { "daytime", SOCK_STREAM, false, false, daytime_stream }, 326 { "daytime", SOCK_DGRAM, false, false, daytime_dg }, 327 328 /* Familiar character generator */ 329 { "chargen", SOCK_STREAM, true, false, chargen_stream }, 330 { "chargen", SOCK_DGRAM, false, false, chargen_dg }, 331 332 { "tcpmux", SOCK_STREAM, true, false, tcpmux } 333 }; 334 335 /* list of "bad" ports. I.e. ports that are most obviously used for 336 * "cycling packets" denial of service attacks. See /etc/services. 337 * List must end with port number "0". 338 */ 339 340 u_int16_t bad_ports[] = { 7, 9, 13, 19, 37, 0 }; 341 342 343 #define NUMINT (sizeof(intab) / sizeof(struct inent)) 344 const char *CONFIG = _PATH_INETDCONF; 345 346 static int my_signals[] = 347 { SIGALRM, SIGHUP, SIGCHLD, SIGTERM, SIGINT, SIGPIPE }; 348 349 int 350 main(int argc, char *argv[]) 351 { 352 int ch, n, reload = 1; 353 354 while ((ch = getopt(argc, argv, 355 #ifdef LIBWRAP 356 "dfl" 357 #else 358 "df" 359 #endif 360 )) != -1) 361 switch(ch) { 362 case 'd': 363 foreground = true; 364 debug = true; 365 options |= SO_DEBUG; 366 break; 367 case 'f': 368 foreground = true; 369 break; 370 #ifdef LIBWRAP 371 case 'l': 372 lflag = true; 373 break; 374 #endif 375 case '?': 376 default: 377 usage(); 378 } 379 argc -= optind; 380 argv += optind; 381 382 if (argc > 0) 383 CONFIG = argv[0]; 384 385 if (!foreground) 386 daemon(0, 0); 387 openlog("inetd", LOG_PID | LOG_NOWAIT, LOG_DAEMON); 388 pidfile(NULL); 389 390 kq = kqueue(); 391 if (kq < 0) { 392 syslog(LOG_ERR, "kqueue: %m"); 393 return (EXIT_FAILURE); 394 } 395 396 if (getrlimit(RLIMIT_NOFILE, &rlim_ofile) < 0) { 397 syslog(LOG_ERR, "getrlimit: %m"); 398 } else { 399 rlim_ofile_cur = rlim_ofile.rlim_cur; 400 if (rlim_ofile_cur == RLIM_INFINITY) /* ! */ 401 rlim_ofile_cur = OPEN_MAX; 402 } 403 404 for (n = 0; n < (int)__arraycount(my_signals); n++) { 405 int signum; 406 407 signum = my_signals[n]; 408 if (signum != SIGCHLD) 409 (void) signal(signum, SIG_IGN); 410 411 if (signum != SIGPIPE) { 412 struct kevent *ev; 413 414 ev = allocchange(); 415 EV_SET(ev, signum, EVFILT_SIGNAL, EV_ADD | EV_ENABLE, 416 0, 0, 0); 417 } 418 } 419 420 for (;;) { 421 int ctrl; 422 struct kevent eventbuf[64], *ev; 423 struct servtab *sep; 424 425 if (reload) { 426 reload = false; 427 config_root(); 428 } 429 430 n = my_kevent(changebuf, changes, eventbuf, __arraycount(eventbuf)); 431 changes = 0; 432 433 for (ev = eventbuf; n > 0; ev++, n--) { 434 if (ev->filter == EVFILT_SIGNAL) { 435 switch (ev->ident) { 436 case SIGALRM: 437 retry(); 438 break; 439 case SIGCHLD: 440 reapchild(); 441 break; 442 case SIGTERM: 443 case SIGINT: 444 goaway(); 445 break; 446 case SIGHUP: 447 reload = true; 448 break; 449 } 450 continue; 451 } 452 if (ev->filter != EVFILT_READ) 453 continue; 454 sep = (struct servtab *)ev->udata; 455 /* Paranoia */ 456 if ((int)ev->ident != sep->se_fd) 457 continue; 458 DPRINTF(SERV_FMT ": service requested" , SERV_PARAMS(sep)); 459 if (sep->se_wait == 0 && sep->se_socktype == SOCK_STREAM) { 460 /* XXX here do the libwrap check-before-accept*/ 461 ctrl = accept(sep->se_fd, NULL, NULL); 462 DPRINTF(SERV_FMT ": accept, ctrl fd %d", 463 SERV_PARAMS(sep), ctrl); 464 if (ctrl < 0) { 465 if (errno != EINTR) 466 syslog(LOG_WARNING, 467 SERV_FMT ": accept: %m", 468 SERV_PARAMS(sep)); 469 continue; 470 } 471 } else 472 ctrl = sep->se_fd; 473 spawn(sep, ctrl); 474 } 475 } 476 } 477 478 static void 479 spawn(struct servtab *sep, int ctrl) 480 { 481 int dofork; 482 pid_t pid; 483 484 pid = 0; 485 #ifdef LIBWRAP_INTERNAL 486 dofork = true; 487 #else 488 dofork = (sep->se_bi == NULL || sep->se_bi->bi_fork); 489 #endif 490 if (dofork) { 491 if (rl_process(sep, ctrl)) { 492 return; 493 } 494 pid = fork(); 495 if (pid < 0) { 496 syslog(LOG_ERR, "fork: %m"); 497 if (sep->se_wait == 0 && sep->se_socktype == SOCK_STREAM) 498 close(ctrl); 499 sleep(1); 500 return; 501 } 502 if (pid != 0 && sep->se_wait != 0) { 503 struct kevent *ev; 504 505 sep->se_wait = pid; 506 ev = allocchange(); 507 EV_SET(ev, sep->se_fd, EVFILT_READ, 508 EV_DELETE, 0, 0, 0); 509 } 510 if (pid == 0) { 511 size_t n; 512 513 for (n = 0; n < __arraycount(my_signals); n++) 514 (void) signal(my_signals[n], SIG_DFL); 515 /* Don't put services in terminal session */ 516 if (foreground) 517 setsid(); 518 } 519 } 520 if (pid == 0) { 521 run_service(ctrl, sep, dofork); 522 if (dofork) 523 exit(EXIT_SUCCESS); 524 } 525 if (sep->se_wait == 0 && sep->se_socktype == SOCK_STREAM) 526 close(ctrl); 527 } 528 529 static void 530 run_service(int ctrl, struct servtab *sep, int didfork) 531 { 532 struct passwd *pwd; 533 struct group *grp = NULL; /* XXX gcc */ 534 char buf[NI_MAXSERV]; 535 struct servtab *s; 536 #ifdef LIBWRAP 537 char abuf[BUFSIZ]; 538 struct request_info req; 539 int denied; 540 char *service = NULL; /* XXX gcc */ 541 #endif 542 543 #ifdef LIBWRAP 544 #ifndef LIBWRAP_INTERNAL 545 if (sep->se_bi == 0) 546 #endif 547 if (sep->se_wait == 0 && sep->se_socktype == SOCK_STREAM) { 548 request_init(&req, RQ_DAEMON, sep->se_argv[0] != NULL ? 549 sep->se_argv[0] : sep->se_service, RQ_FILE, ctrl, NULL); 550 fromhost(&req); 551 denied = hosts_access(&req) == 0; 552 if (denied || lflag) { 553 if (getnameinfo(&sep->se_ctrladdr, 554 (socklen_t)sep->se_ctrladdr.sa_len, NULL, 0, 555 buf, sizeof(buf), 0) != 0) { 556 /* shouldn't happen */ 557 (void)snprintf(buf, sizeof buf, "%d", 558 ntohs(sep->se_ctrladdr_in.sin_port)); 559 } 560 service = buf; 561 if (req.client->sin != NULL) { 562 sockaddr_snprintf(abuf, sizeof(abuf), "%a", 563 req.client->sin); 564 } else { 565 strcpy(abuf, "(null)"); 566 } 567 } 568 if (denied) { 569 syslog(deny_severity, 570 "refused connection from %.500s(%s), service %s (%s)", 571 eval_client(&req), abuf, service, sep->se_proto); 572 goto reject; 573 } 574 if (lflag) { 575 syslog(allow_severity, 576 "connection from %.500s(%s), service %s (%s)", 577 eval_client(&req), abuf, service, sep->se_proto); 578 } 579 } 580 #endif /* LIBWRAP */ 581 582 if (sep->se_bi != NULL) { 583 if (didfork) { 584 for (s = servtab; s != NULL; s = s->se_next) 585 if (s->se_fd != -1 && s->se_fd != ctrl) { 586 close(s->se_fd); 587 s->se_fd = -1; 588 } 589 } 590 (*sep->se_bi->bi_fn)(ctrl, sep); 591 } else { 592 if ((pwd = getpwnam(sep->se_user)) == NULL) { 593 syslog(LOG_ERR, "%s/%s: %s: No such user", 594 sep->se_service, sep->se_proto, sep->se_user); 595 goto reject; 596 } 597 if (sep->se_group != NULL && 598 (grp = getgrnam(sep->se_group)) == NULL) { 599 syslog(LOG_ERR, "%s/%s: %s: No such group", 600 sep->se_service, sep->se_proto, sep->se_group); 601 goto reject; 602 } 603 if (pwd->pw_uid != 0) { 604 if (sep->se_group != NULL) 605 pwd->pw_gid = grp->gr_gid; 606 if (setgid(pwd->pw_gid) < 0) { 607 syslog(LOG_ERR, 608 "%s/%s: can't set gid %d: %m", sep->se_service, 609 sep->se_proto, pwd->pw_gid); 610 goto reject; 611 } 612 (void) initgroups(pwd->pw_name, 613 pwd->pw_gid); 614 if (setuid(pwd->pw_uid) < 0) { 615 syslog(LOG_ERR, 616 "%s/%s: can't set uid %d: %m", sep->se_service, 617 sep->se_proto, pwd->pw_uid); 618 goto reject; 619 } 620 } else if (sep->se_group != NULL) { 621 (void) setgid((gid_t)grp->gr_gid); 622 } 623 DPRINTF("%d execl %s", 624 getpid(), sep->se_server); 625 /* Set our control descriptor to not close-on-exec... */ 626 if (fcntl(ctrl, F_SETFD, 0) < 0) 627 syslog(LOG_ERR, "fcntl (%d, F_SETFD, 0): %m", ctrl); 628 /* ...and dup it to stdin, stdout, and stderr. */ 629 if (ctrl != 0) { 630 dup2(ctrl, 0); 631 close(ctrl); 632 ctrl = 0; 633 } 634 dup2(0, 1); 635 dup2(0, 2); 636 if (rlim_ofile.rlim_cur != rlim_ofile_cur && 637 setrlimit(RLIMIT_NOFILE, &rlim_ofile) < 0) 638 syslog(LOG_ERR, "setrlimit: %m"); 639 execv(sep->se_server, sep->se_argv); 640 syslog(LOG_ERR, "cannot execute %s: %m", sep->se_server); 641 reject: 642 if (sep->se_socktype != SOCK_STREAM) 643 recv(ctrl, buf, sizeof (buf), 0); 644 _exit(EXIT_FAILURE); 645 } 646 } 647 648 static void 649 reapchild(void) 650 { 651 int status; 652 pid_t pid; 653 struct servtab *sep; 654 655 for (;;) { 656 pid = wait3(&status, WNOHANG, NULL); 657 if (pid <= 0) 658 break; 659 DPRINTF("%d reaped, status %#x", pid, status); 660 for (sep = servtab; sep != NULL; sep = sep->se_next) 661 if (sep->se_wait == pid) { 662 struct kevent *ev; 663 664 if (WIFEXITED(status) && WEXITSTATUS(status)) 665 syslog(LOG_WARNING, 666 "%s: exit status %u", 667 sep->se_server, WEXITSTATUS(status)); 668 else if (WIFSIGNALED(status)) 669 syslog(LOG_WARNING, 670 "%s: exit signal %u", 671 sep->se_server, WTERMSIG(status)); 672 sep->se_wait = 1; 673 ev = allocchange(); 674 EV_SET(ev, sep->se_fd, EVFILT_READ, 675 EV_ADD | EV_ENABLE, 0, 0, (intptr_t)sep); 676 DPRINTF("restored %s, fd %d", 677 sep->se_service, sep->se_fd); 678 } 679 } 680 } 681 682 static void 683 retry(void) 684 { 685 struct servtab *sep; 686 687 timingout = false; 688 for (sep = servtab; sep != NULL; sep = sep->se_next) { 689 if (sep->se_fd == -1 && !ISMUX(sep)) { 690 switch (sep->se_family) { 691 case AF_LOCAL: 692 case AF_INET: 693 #ifdef INET6 694 case AF_INET6: 695 #endif 696 setup(sep); 697 if (sep->se_fd >= 0 && isrpcservice(sep)) 698 register_rpc(sep); 699 break; 700 } 701 } 702 } 703 } 704 705 static void 706 goaway(void) 707 { 708 struct servtab *sep; 709 710 for (sep = servtab; sep != NULL; sep = sep->se_next) { 711 if (sep->se_fd == -1) 712 continue; 713 714 switch (sep->se_family) { 715 case AF_LOCAL: 716 (void)unlink(sep->se_service); 717 break; 718 case AF_INET: 719 #ifdef INET6 720 case AF_INET6: 721 #endif 722 if (sep->se_wait == 1 && isrpcservice(sep)) 723 unregister_rpc(sep); 724 break; 725 } 726 (void)close(sep->se_fd); 727 sep->se_fd = -1; 728 } 729 730 DPRINTF("Going away."); 731 732 exit(EXIT_SUCCESS); 733 } 734 735 void 736 setup(struct servtab *sep) 737 { 738 int on = 1; 739 #ifdef INET6 740 int off = 0; 741 #endif 742 struct kevent *ev; 743 744 if ((sep->se_fd = socket(sep->se_family, sep->se_socktype, 0)) < 0) { 745 DPRINTF("socket failed on " SERV_FMT ": %s", 746 SERV_PARAMS(sep), strerror(errno)); 747 syslog(LOG_ERR, "%s/%s: socket: %m", 748 sep->se_service, sep->se_proto); 749 return; 750 } 751 /* Set all listening sockets to close-on-exec. */ 752 if (fcntl(sep->se_fd, F_SETFD, FD_CLOEXEC) < 0) { 753 syslog(LOG_ERR, SERV_FMT ": fcntl(F_SETFD, FD_CLOEXEC): %m", 754 SERV_PARAMS(sep)); 755 close(sep->se_fd); 756 sep->se_fd = -1; 757 return; 758 } 759 760 #define turnon(fd, opt) \ 761 setsockopt(fd, SOL_SOCKET, opt, &on, (socklen_t)sizeof(on)) 762 if (strcmp(sep->se_proto, "tcp") == 0 && (options & SO_DEBUG) && 763 turnon(sep->se_fd, SO_DEBUG) < 0) 764 syslog(LOG_ERR, "setsockopt (SO_DEBUG): %m"); 765 if (turnon(sep->se_fd, SO_REUSEADDR) < 0) 766 syslog(LOG_ERR, "setsockopt (SO_REUSEADDR): %m"); 767 #undef turnon 768 769 /* Set the socket buffer sizes, if specified. */ 770 if (sep->se_sndbuf != 0 && setsockopt(sep->se_fd, SOL_SOCKET, 771 SO_SNDBUF, &sep->se_sndbuf, (socklen_t)sizeof(sep->se_sndbuf)) < 0) 772 syslog(LOG_ERR, "setsockopt (SO_SNDBUF %d): %m", 773 sep->se_sndbuf); 774 if (sep->se_rcvbuf != 0 && setsockopt(sep->se_fd, SOL_SOCKET, 775 SO_RCVBUF, &sep->se_rcvbuf, (socklen_t)sizeof(sep->se_rcvbuf)) < 0) 776 syslog(LOG_ERR, "setsockopt (SO_RCVBUF %d): %m", 777 sep->se_rcvbuf); 778 #ifdef INET6 779 if (sep->se_family == AF_INET6) { 780 int *v; 781 v = (sep->se_type == FAITH_TYPE) ? &on : &off; 782 if (setsockopt(sep->se_fd, IPPROTO_IPV6, IPV6_FAITH, 783 v, (socklen_t)sizeof(*v)) < 0) 784 syslog(LOG_ERR, "setsockopt (IPV6_FAITH): %m"); 785 } 786 #endif 787 #ifdef IPSEC 788 /* Avoid setting a policy if a policy specifier doesn't exist. */ 789 if (sep->se_policy != NULL) { 790 int e = ipsecsetup(sep->se_family, sep->se_fd, sep->se_policy); 791 if (e < 0) { 792 syslog(LOG_ERR, SERV_FMT ": ipsec setup failed", 793 SERV_PARAMS(sep)); 794 (void)close(sep->se_fd); 795 sep->se_fd = -1; 796 return; 797 } 798 } 799 #endif 800 801 if (bind(sep->se_fd, &sep->se_ctrladdr, sep->se_ctrladdr_size) < 0) { 802 DPRINTF(SERV_FMT ": bind failed: %s", 803 SERV_PARAMS(sep), strerror(errno)); 804 syslog(LOG_ERR, SERV_FMT ": bind: %m", 805 SERV_PARAMS(sep)); 806 (void) close(sep->se_fd); 807 sep->se_fd = -1; 808 if (!timingout) { 809 timingout = true; 810 alarm(RETRYTIME); 811 } 812 return; 813 } 814 if (sep->se_socktype == SOCK_STREAM) 815 listen(sep->se_fd, 10); 816 817 /* for internal dgram, setsockopt() is required for recvfromto() */ 818 if (sep->se_socktype == SOCK_DGRAM && sep->se_bi != NULL) { 819 switch (sep->se_family) { 820 case AF_INET: 821 if (setsockopt(sep->se_fd, IPPROTO_IP, 822 IP_RECVDSTADDR, &on, sizeof(on)) < 0) 823 syslog(LOG_ERR, 824 "setsockopt (IP_RECVDSTADDR): %m"); 825 break; 826 #ifdef INET6 827 case AF_INET6: 828 if (setsockopt(sep->se_fd, IPPROTO_IPV6, 829 IPV6_RECVPKTINFO, &on, sizeof(on)) < 0) 830 syslog(LOG_ERR, 831 "setsockopt (IPV6_RECVPKTINFO): %m"); 832 break; 833 #endif 834 } 835 } 836 837 /* Set the accept filter, if specified. To be done after listen.*/ 838 if (sep->se_accf.af_name[0] != 0 && setsockopt(sep->se_fd, SOL_SOCKET, 839 SO_ACCEPTFILTER, &sep->se_accf, 840 (socklen_t)sizeof(sep->se_accf)) < 0) 841 syslog(LOG_ERR, "setsockopt(SO_ACCEPTFILTER %s): %m", 842 sep->se_accf.af_name); 843 844 ev = allocchange(); 845 EV_SET(ev, sep->se_fd, EVFILT_READ, EV_ADD | EV_ENABLE, 0, 0, 846 (intptr_t)sep); 847 if (sep->se_fd > maxsock) { 848 maxsock = sep->se_fd; 849 if (maxsock > (int)(rlim_ofile_cur - FD_MARGIN)) 850 bump_nofile(); 851 } 852 DPRINTF(SERV_FMT ": registered on fd %d", SERV_PARAMS(sep), sep->se_fd); 853 } 854 855 /* 856 * Finish with a service and its socket. 857 */ 858 void 859 close_sep(struct servtab *sep) 860 { 861 862 if (sep->se_fd >= 0) { 863 (void) close(sep->se_fd); 864 sep->se_fd = -1; 865 } 866 sep->se_count = 0; 867 if (sep->se_ip_max != SERVTAB_UNSPEC_SIZE_T) { 868 rl_clear_ip_list(sep); 869 } 870 } 871 872 void 873 register_rpc(struct servtab *sep) 874 { 875 #ifdef RPC 876 struct netbuf nbuf; 877 struct sockaddr_storage ss; 878 struct netconfig *nconf; 879 socklen_t socklen; 880 int n; 881 882 if ((nconf = getnetconfigent(sep->se_proto+4)) == NULL) { 883 syslog(LOG_ERR, "%s: getnetconfigent failed", 884 sep->se_proto); 885 return; 886 } 887 socklen = sizeof ss; 888 if (getsockname(sep->se_fd, (struct sockaddr *)(void *)&ss, &socklen) < 0) { 889 syslog(LOG_ERR, SERV_FMT ": getsockname: %m", 890 SERV_PARAMS(sep)); 891 return; 892 } 893 894 nbuf.buf = &ss; 895 nbuf.len = ss.ss_len; 896 nbuf.maxlen = sizeof (struct sockaddr_storage); 897 for (n = sep->se_rpcversl; n <= sep->se_rpcversh; n++) { 898 DPRINTF("rpcb_set: %u %d %s %s", 899 sep->se_rpcprog, n, nconf->nc_netid, 900 taddr2uaddr(nconf, &nbuf)); 901 (void)rpcb_unset((unsigned int)sep->se_rpcprog, (unsigned int)n, nconf); 902 if (rpcb_set((unsigned int)sep->se_rpcprog, (unsigned int)n, nconf, &nbuf) == 0) 903 syslog(LOG_ERR, "rpcb_set: %u %d %s %s%s", 904 sep->se_rpcprog, n, nconf->nc_netid, 905 taddr2uaddr(nconf, &nbuf), clnt_spcreateerror("")); 906 } 907 #endif /* RPC */ 908 } 909 910 void 911 unregister_rpc(struct servtab *sep) 912 { 913 #ifdef RPC 914 int n; 915 struct netconfig *nconf; 916 917 if ((nconf = getnetconfigent(sep->se_proto+4)) == NULL) { 918 syslog(LOG_ERR, "%s: getnetconfigent failed", 919 sep->se_proto); 920 return; 921 } 922 923 for (n = sep->se_rpcversl; n <= sep->se_rpcversh; n++) { 924 DPRINTF("rpcb_unset(%u, %d, %s)", 925 sep->se_rpcprog, n, nconf->nc_netid); 926 if (rpcb_unset((unsigned int)sep->se_rpcprog, (unsigned int)n, nconf) == 0) 927 syslog(LOG_ERR, "rpcb_unset(%u, %d, %s) failed\n", 928 sep->se_rpcprog, n, nconf->nc_netid); 929 } 930 #endif /* RPC */ 931 } 932 933 static void 934 inetd_setproctitle(char *a, int s) 935 { 936 socklen_t size; 937 struct sockaddr_storage ss; 938 char hbuf[NI_MAXHOST]; 939 const char *hp; 940 struct sockaddr *sa; 941 942 size = sizeof(ss); 943 sa = (struct sockaddr *)(void *)&ss; 944 if (getpeername(s, sa, &size) == 0) { 945 if (getnameinfo(sa, size, hbuf, (socklen_t)sizeof(hbuf), NULL, 946 0, niflags) != 0) 947 hp = "?"; 948 else 949 hp = hbuf; 950 setproctitle("-%s [%s]", a, hp); 951 } else 952 setproctitle("-%s", a); 953 } 954 955 static void 956 bump_nofile(void) 957 { 958 #define FD_CHUNK 32 959 struct rlimit rl; 960 961 if (getrlimit(RLIMIT_NOFILE, &rl) < 0) { 962 syslog(LOG_ERR, "getrlimit: %m"); 963 return; 964 } 965 rl.rlim_cur = MIN(rl.rlim_max, rl.rlim_cur + FD_CHUNK); 966 if (rl.rlim_cur <= rlim_ofile_cur) { 967 syslog(LOG_ERR, 968 "bump_nofile: cannot extend file limit, max = %d", 969 (int)rl.rlim_cur); 970 return; 971 } 972 973 if (setrlimit(RLIMIT_NOFILE, &rl) < 0) { 974 syslog(LOG_ERR, "setrlimit: %m"); 975 return; 976 } 977 978 rlim_ofile_cur = rl.rlim_cur; 979 return; 980 } 981 982 /* 983 * In order to get the destination address (`to') with recvfromto(), 984 * IP_RECVDSTADDR or IP_RECVPKTINFO for AF_INET, or IPV6_RECVPKTINFO 985 * for AF_INET6, must be enabled with setsockopt(2). 986 * 987 * .sin_port and .sin6_port in 'to' are always stored as zero. 988 * If necessary, extract them using getsockname(2). 989 */ 990 static ssize_t 991 recvfromto(int s, void * restrict buf, size_t len, int flags, 992 struct sockaddr * restrict from, socklen_t * restrict fromlen, 993 struct sockaddr * restrict to, socklen_t * restrict tolen) 994 { 995 struct msghdr msg; 996 struct iovec vec; 997 struct cmsghdr *cmsg; 998 struct sockaddr_storage ss; 999 char cmsgbuf[1024]; 1000 ssize_t rc; 1001 1002 if (to == NULL) 1003 return recvfrom(s, buf, len, flags, from, fromlen); 1004 1005 if (tolen == NULL || fromlen == NULL) { 1006 errno = EFAULT; 1007 return -1; 1008 } 1009 1010 vec.iov_base = buf; 1011 vec.iov_len = len; 1012 msg.msg_name = from; 1013 msg.msg_namelen = *fromlen; 1014 msg.msg_iov = &vec; 1015 msg.msg_iovlen = 1; 1016 msg.msg_control = cmsgbuf; 1017 msg.msg_controllen = sizeof(cmsgbuf); 1018 1019 rc = recvmsg(s, &msg, flags); 1020 if (rc < 0) 1021 return rc; 1022 *fromlen = msg.msg_namelen; 1023 1024 memset(&ss, 0, sizeof(ss)); 1025 for (cmsg = (struct cmsghdr *)CMSG_FIRSTHDR(&msg); cmsg != NULL; 1026 cmsg = (struct cmsghdr *)CMSG_NXTHDR(&msg, cmsg)) { 1027 if (cmsg->cmsg_level == IPPROTO_IP && 1028 cmsg->cmsg_type == IP_RECVDSTADDR) { 1029 struct in_addr *dst = (struct in_addr *)CMSG_DATA(cmsg); 1030 struct sockaddr_in *sin = (struct sockaddr_in *)&ss; 1031 1032 sin->sin_len = sizeof(*sin); 1033 sin->sin_family = AF_INET; 1034 sin->sin_addr = *dst; 1035 break; 1036 } 1037 if (cmsg->cmsg_level == IPPROTO_IP && 1038 cmsg->cmsg_type == IP_PKTINFO) { 1039 struct in_pktinfo *pi = 1040 (struct in_pktinfo *)CMSG_DATA(cmsg); 1041 struct sockaddr_in *sin = (struct sockaddr_in *)&ss; 1042 1043 sin->sin_len = sizeof(*sin); 1044 sin->sin_family = AF_INET; 1045 sin->sin_addr = pi->ipi_addr; 1046 break; 1047 } 1048 #ifdef INET6 1049 if (cmsg->cmsg_level == IPPROTO_IPV6 && 1050 cmsg->cmsg_type == IPV6_PKTINFO) { 1051 struct in6_pktinfo *pi6 = 1052 (struct in6_pktinfo *)CMSG_DATA(cmsg); 1053 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&ss; 1054 1055 sin6->sin6_len = sizeof(*sin6); 1056 sin6->sin6_family = AF_INET6; 1057 sin6->sin6_addr = pi6->ipi6_addr; 1058 if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) || 1059 IN6_IS_ADDR_MC_LINKLOCAL(&sin6->sin6_addr)) 1060 sin6->sin6_scope_id = pi6->ipi6_ifindex; 1061 else 1062 sin6->sin6_scope_id = 0; 1063 break; 1064 } 1065 #endif /* INET6 */ 1066 } 1067 1068 socklen_t sslen = (*tolen < ss.ss_len) ? *tolen : ss.ss_len; 1069 if (sslen > 0) 1070 memcpy(to, &ss, sslen); 1071 *tolen = sslen; 1072 1073 return rc; 1074 } 1075 1076 /* 1077 * When sending, the source port is selected as the one bind(2)'ed 1078 * to the socket. 1079 * .sin_port and .sin6_port in `from' are always ignored. 1080 */ 1081 static ssize_t 1082 sendfromto(int s, const void *buf, size_t len, int flags, 1083 const struct sockaddr *from, socklen_t fromlen, 1084 const struct sockaddr *to, socklen_t tolen) 1085 { 1086 struct msghdr msg; 1087 struct iovec vec; 1088 struct cmsghdr *cmsg; 1089 char cmsgbuf[256]; 1090 __CTASSERT(sizeof(cmsgbuf) > CMSG_SPACE(sizeof(struct in_pktinfo))); 1091 #ifdef INET6 1092 __CTASSERT(sizeof(cmsgbuf) > CMSG_SPACE(sizeof(struct in6_pktinfo))); 1093 #endif 1094 1095 if (from == NULL || fromlen == 0) 1096 return sendto(s, buf, len, flags, to, tolen); 1097 1098 vec.iov_base = __UNCONST(buf); 1099 vec.iov_len = len; 1100 msg.msg_name = __UNCONST(to); 1101 msg.msg_namelen = tolen; 1102 msg.msg_iov = &vec; 1103 msg.msg_iovlen = 1; 1104 msg.msg_control = cmsgbuf; 1105 msg.msg_controllen = 0; 1106 1107 if (fromlen < 2) { /* sa_len + sa_family */ 1108 errno = EINVAL; 1109 return -1; 1110 } 1111 1112 cmsg = (struct cmsghdr *)cmsgbuf; 1113 if (from->sa_family == AF_INET) { 1114 const struct sockaddr_in *from4 = 1115 (const struct sockaddr_in *)from; 1116 struct in_pktinfo *pi; 1117 1118 if (fromlen != sizeof(struct sockaddr_in) || 1119 from4->sin_family != AF_INET) { 1120 errno = EINVAL; 1121 return -1; 1122 } 1123 1124 msg.msg_controllen += CMSG_SPACE(sizeof(struct in_pktinfo)); 1125 cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo)); 1126 cmsg->cmsg_level = IPPROTO_IP; 1127 cmsg->cmsg_type = IP_PKTINFO; 1128 1129 pi = (struct in_pktinfo *)CMSG_DATA(cmsg); 1130 pi->ipi_addr = from4->sin_addr; 1131 pi->ipi_ifindex = 0; 1132 #ifdef INET6 1133 } else if (from->sa_family == AF_INET6) { 1134 const struct sockaddr_in6 *from6 = 1135 (const struct sockaddr_in6 *)from; 1136 struct in6_pktinfo *pi6; 1137 1138 if (fromlen != sizeof(struct sockaddr_in6) || 1139 from6->sin6_family != AF_INET6) { 1140 errno = EINVAL; 1141 return -1; 1142 } 1143 1144 msg.msg_controllen += CMSG_SPACE(sizeof(struct in6_pktinfo)); 1145 cmsg->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo)); 1146 cmsg->cmsg_level = IPPROTO_IPV6; 1147 cmsg->cmsg_type = IPV6_PKTINFO; 1148 1149 pi6 = (struct in6_pktinfo *)CMSG_DATA(cmsg); 1150 pi6->ipi6_addr = from6->sin6_addr; 1151 if (IN6_IS_ADDR_LINKLOCAL(&from6->sin6_addr) || 1152 IN6_IS_ADDR_MC_LINKLOCAL(&from6->sin6_addr)) { 1153 pi6->ipi6_ifindex = from6->sin6_scope_id; 1154 } else { 1155 pi6->ipi6_ifindex = 0; 1156 } 1157 #endif /* INET6 */ 1158 } else { 1159 return sendto(s, buf, len, flags, to, tolen); 1160 } 1161 1162 return sendmsg(s, &msg, flags); 1163 } 1164 1165 /* 1166 * Internet services provided internally by inetd: 1167 */ 1168 #define BUFSIZE 4096 1169 1170 /* ARGSUSED */ 1171 static void 1172 echo_stream(int s, struct servtab *sep) /* Echo service -- echo data back */ 1173 { 1174 char buffer[BUFSIZE]; 1175 ssize_t i; 1176 1177 inetd_setproctitle(sep->se_service, s); 1178 while ((i = read(s, buffer, sizeof(buffer))) > 0 && 1179 write(s, buffer, (size_t)i) > 0) 1180 continue; 1181 } 1182 1183 /* ARGSUSED */ 1184 static void 1185 echo_dg(int s, struct servtab *sep) /* Echo service -- echo data back */ 1186 { 1187 char buffer[BUFSIZE]; 1188 ssize_t i; 1189 socklen_t rsize, lsize; 1190 struct sockaddr_storage remote, local; 1191 struct sockaddr *lsa, *rsa; 1192 1193 rsa = (struct sockaddr *)(void *)&remote; 1194 lsa = (struct sockaddr *)(void *)&local; 1195 rsize = sizeof(remote); 1196 lsize = sizeof(local); 1197 if ((i = recvfromto(s, buffer, sizeof(buffer), 0, 1198 rsa, &rsize, lsa, &lsize)) < 0) 1199 return; 1200 if (port_good_dg(rsa)) 1201 (void) sendfromto(s, buffer, (size_t)i, 0, 1202 lsa, lsize, rsa, rsize); 1203 } 1204 1205 /* ARGSUSED */ 1206 static void 1207 discard_stream(int s, struct servtab *sep) /* Discard service -- ignore data */ 1208 { 1209 char buffer[BUFSIZE]; 1210 1211 inetd_setproctitle(sep->se_service, s); 1212 while ((errno = 0, read(s, buffer, sizeof(buffer)) > 0) || 1213 errno == EINTR) 1214 ; 1215 } 1216 1217 /* ARGSUSED */ 1218 static void 1219 discard_dg(int s, struct servtab *sep) /* Discard service -- ignore data */ 1220 1221 { 1222 char buffer[BUFSIZE]; 1223 1224 (void) read(s, buffer, sizeof(buffer)); 1225 } 1226 1227 #define LINESIZ 72 1228 char ring[128]; 1229 char *endring; 1230 1231 static void 1232 initring(void) 1233 { 1234 int i; 1235 1236 endring = ring; 1237 1238 for (i = 0; i <= 128; ++i) 1239 if (isprint(i)) 1240 *endring++ = (char)i; 1241 } 1242 1243 /* ARGSUSED */ 1244 static void 1245 chargen_stream(int s, struct servtab *sep) /* Character generator */ 1246 { 1247 size_t len; 1248 char *rs, text[LINESIZ+2]; 1249 1250 inetd_setproctitle(sep->se_service, s); 1251 1252 if (endring == NULL) { 1253 initring(); 1254 rs = ring; 1255 } 1256 1257 text[LINESIZ] = '\r'; 1258 text[LINESIZ + 1] = '\n'; 1259 for (rs = ring;;) { 1260 if ((len = (size_t)(endring - rs)) >= LINESIZ) 1261 memmove(text, rs, LINESIZ); 1262 else { 1263 memmove(text, rs, len); 1264 memmove(text + len, ring, LINESIZ - len); 1265 } 1266 if (++rs == endring) 1267 rs = ring; 1268 if (write(s, text, sizeof(text)) != sizeof(text)) 1269 break; 1270 } 1271 } 1272 1273 /* ARGSUSED */ 1274 static void 1275 chargen_dg(int s, struct servtab *sep) /* Character generator */ 1276 { 1277 struct sockaddr_storage remote, local; 1278 struct sockaddr *rsa, *lsa; 1279 static char *rs; 1280 size_t len; 1281 socklen_t rsize, lsize; 1282 char text[LINESIZ+2]; 1283 1284 if (endring == 0) { 1285 initring(); 1286 rs = ring; 1287 } 1288 1289 rsa = (struct sockaddr *)(void *)&remote; 1290 lsa = (struct sockaddr *)(void *)&local; 1291 rsize = sizeof(remote); 1292 lsize = sizeof(local); 1293 if (recvfromto(s, text, sizeof(text), 0, 1294 rsa, &rsize, lsa, &lsize) < 0) 1295 return; 1296 1297 if (!port_good_dg(rsa)) 1298 return; 1299 1300 if ((len = (size_t)(endring - rs)) >= LINESIZ) 1301 memmove(text, rs, LINESIZ); 1302 else { 1303 memmove(text, rs, len); 1304 memmove(text + len, ring, LINESIZ - len); 1305 } 1306 if (++rs == endring) 1307 rs = ring; 1308 text[LINESIZ] = '\r'; 1309 text[LINESIZ + 1] = '\n'; 1310 (void) sendfromto(s, text, sizeof(text), 0, lsa, lsize, rsa, rsize); 1311 } 1312 1313 /* 1314 * Return a machine readable date and time, in the form of the 1315 * number of seconds since midnight, Jan 1, 1900. Since gettimeofday 1316 * returns the number of seconds since midnight, Jan 1, 1970, 1317 * we must add 2208988800 seconds to this figure to make up for 1318 * some seventy years Bell Labs was asleep. 1319 */ 1320 1321 static uint32_t 1322 machtime(void) 1323 { 1324 struct timeval tv; 1325 1326 if (gettimeofday(&tv, NULL) < 0) { 1327 DPRINTF("Unable to get time of day"); 1328 return (0); 1329 } 1330 #define OFFSET ((uint32_t)25567 * 24*60*60) 1331 return (htonl((uint32_t)(tv.tv_sec + OFFSET))); 1332 #undef OFFSET 1333 } 1334 1335 /* ARGSUSED */ 1336 static void 1337 machtime_stream(int s, struct servtab *sep) 1338 { 1339 uint32_t result; 1340 1341 result = machtime(); 1342 (void) write(s, &result, sizeof(result)); 1343 } 1344 1345 /* ARGSUSED */ 1346 void 1347 machtime_dg(int s, struct servtab *sep) 1348 { 1349 uint32_t result; 1350 struct sockaddr_storage remote, local; 1351 struct sockaddr *rsa, *lsa; 1352 socklen_t rsize, lsize; 1353 1354 rsa = (struct sockaddr *)(void *)&remote; 1355 lsa = (struct sockaddr *)(void *)&local; 1356 rsize = sizeof(remote); 1357 lsize = sizeof(local); 1358 if (recvfromto(s, &result, sizeof(result), 0, 1359 rsa, &rsize, lsa, &lsize) < 0) 1360 return; 1361 if (!port_good_dg(rsa)) 1362 return; 1363 result = machtime(); 1364 (void)sendfromto(s, &result, sizeof(result), 0, lsa, lsize, rsa, rsize); 1365 } 1366 1367 /* ARGSUSED */ 1368 static void 1369 daytime_stream(int s,struct servtab *sep) 1370 /* Return human-readable time of day */ 1371 { 1372 char buffer[256]; 1373 time_t clk; 1374 int len; 1375 1376 clk = time((time_t *) 0); 1377 1378 len = snprintf(buffer, sizeof buffer, "%.24s\r\n", ctime(&clk)); 1379 (void) write(s, buffer, (size_t)len); 1380 } 1381 1382 /* ARGSUSED */ 1383 void 1384 daytime_dg(int s, struct servtab *sep) 1385 /* Return human-readable time of day */ 1386 { 1387 char buffer[256]; 1388 time_t clk; 1389 struct sockaddr_storage remote, local; 1390 struct sockaddr *rsa, *lsa; 1391 socklen_t rsize, lsize; 1392 int len; 1393 1394 clk = time((time_t *) 0); 1395 1396 rsa = (struct sockaddr *)(void *)&remote; 1397 lsa = (struct sockaddr *)(void *)&local; 1398 rsize = sizeof(remote); 1399 lsize = sizeof(local); 1400 if (recvfromto(s, buffer, sizeof(buffer), 0, 1401 rsa, &rsize, lsa, &lsize) < 0) 1402 return; 1403 if (!port_good_dg(rsa)) 1404 return; 1405 len = snprintf(buffer, sizeof buffer, "%.24s\r\n", ctime(&clk)); 1406 (void) sendfromto(s, buffer, (size_t)len, 0, lsa, lsize, rsa, rsize); 1407 } 1408 1409 static void 1410 usage(void) 1411 { 1412 #ifdef LIBWRAP 1413 (void)fprintf(stderr, "usage: %s [-dl] [conf]\n", getprogname()); 1414 #else 1415 (void)fprintf(stderr, "usage: %s [-d] [conf]\n", getprogname()); 1416 #endif 1417 exit(EXIT_FAILURE); 1418 } 1419 1420 1421 /* 1422 * Based on TCPMUX.C by Mark K. Lottor November 1988 1423 * sri-nic::ps:<mkl>tcpmux.c 1424 */ 1425 1426 static int /* # of characters upto \r,\n or \0 */ 1427 get_line(int fd, char *buf, int len) 1428 { 1429 int count = 0; 1430 ssize_t n; 1431 1432 do { 1433 n = read(fd, buf, (size_t)(len - count)); 1434 if (n == 0) 1435 return (count); 1436 if (n < 0) 1437 return (-1); 1438 while (--n >= 0) { 1439 if (*buf == '\r' || *buf == '\n' || *buf == '\0') 1440 return (count); 1441 count++; 1442 buf++; 1443 } 1444 } while (count < len); 1445 return (count); 1446 } 1447 1448 #define MAX_SERV_LEN (256+2) /* 2 bytes for \r\n */ 1449 1450 #define strwrite(fd, buf) (void) write(fd, buf, sizeof(buf)-1) 1451 1452 static void 1453 tcpmux(int ctrl, struct servtab *sep) 1454 { 1455 char service[MAX_SERV_LEN+1]; 1456 int len; 1457 1458 /* Get requested service name */ 1459 if ((len = get_line(ctrl, service, MAX_SERV_LEN)) < 0) { 1460 strwrite(ctrl, "-Error reading service name\r\n"); 1461 goto reject; 1462 } 1463 service[len] = '\0'; 1464 1465 DPRINTF("tcpmux: %s: service requested", service); 1466 1467 /* 1468 * Help is a required command, and lists available services, 1469 * one per line. 1470 */ 1471 if (strcasecmp(service, "help") == 0) { 1472 strwrite(ctrl, "+Available services:\r\n"); 1473 strwrite(ctrl, "help\r\n"); 1474 for (sep = servtab; sep != NULL; sep = sep->se_next) { 1475 if (!ISMUX(sep)) 1476 continue; 1477 (void)write(ctrl, sep->se_service, 1478 strlen(sep->se_service)); 1479 strwrite(ctrl, "\r\n"); 1480 } 1481 goto reject; 1482 } 1483 1484 /* Try matching a service in inetd.conf with the request */ 1485 for (sep = servtab; sep != NULL; sep = sep->se_next) { 1486 if (!ISMUX(sep)) 1487 continue; 1488 if (strcasecmp(service, sep->se_service) == 0) { 1489 if (ISMUXPLUS(sep)) 1490 strwrite(ctrl, "+Go\r\n"); 1491 run_service(ctrl, sep, true /* forked */); 1492 return; 1493 } 1494 } 1495 strwrite(ctrl, "-Service not available\r\n"); 1496 reject: 1497 _exit(EXIT_FAILURE); 1498 } 1499 1500 /* 1501 * check if the address/port where send data to is one of the obvious ports 1502 * that are used for denial of service attacks like two echo ports 1503 * just echoing data between them 1504 */ 1505 static int 1506 port_good_dg(struct sockaddr *sa) 1507 { 1508 struct in_addr in; 1509 struct sockaddr_in *sin; 1510 #ifdef INET6 1511 struct in6_addr *in6; 1512 struct sockaddr_in6 *sin6; 1513 #endif 1514 u_int16_t port; 1515 int i; 1516 char hbuf[NI_MAXHOST]; 1517 1518 switch (sa->sa_family) { 1519 case AF_INET: 1520 sin = (struct sockaddr_in *)(void *)sa; 1521 in.s_addr = ntohl(sin->sin_addr.s_addr); 1522 port = ntohs(sin->sin_port); 1523 #ifdef INET6 1524 v4chk: 1525 #endif 1526 if (IN_MULTICAST(in.s_addr)) 1527 goto bad; 1528 switch ((in.s_addr & 0xff000000) >> 24) { 1529 case 0: case 127: case 255: 1530 goto bad; 1531 } 1532 if (dg_broadcast(&in)) 1533 goto bad; 1534 break; 1535 #ifdef INET6 1536 case AF_INET6: 1537 sin6 = (struct sockaddr_in6 *)(void *)sa; 1538 in6 = &sin6->sin6_addr; 1539 port = ntohs(sin6->sin6_port); 1540 if (IN6_IS_ADDR_MULTICAST(in6) || IN6_IS_ADDR_UNSPECIFIED(in6)) 1541 goto bad; 1542 if (IN6_IS_ADDR_V4MAPPED(in6) || IN6_IS_ADDR_V4COMPAT(in6)) { 1543 memcpy(&in, &in6->s6_addr[12], sizeof(in)); 1544 in.s_addr = ntohl(in.s_addr); 1545 goto v4chk; 1546 } 1547 break; 1548 #endif 1549 default: 1550 /* XXX unsupported af, is it safe to assume it to be safe? */ 1551 return true; 1552 } 1553 1554 for (i = 0; bad_ports[i] != 0; i++) { 1555 if (port == bad_ports[i]) 1556 goto bad; 1557 } 1558 1559 return true; 1560 1561 bad: 1562 if (getnameinfo(sa, sa->sa_len, hbuf, (socklen_t)sizeof(hbuf), NULL, 0, 1563 niflags) != 0) 1564 strlcpy(hbuf, "?", sizeof(hbuf)); 1565 syslog(LOG_WARNING,"Possible DoS attack from %s, Port %d", 1566 hbuf, port); 1567 return false; 1568 } 1569 1570 /* XXX need optimization */ 1571 static int 1572 dg_broadcast(struct in_addr *in) 1573 { 1574 struct ifaddrs *ifa, *ifap; 1575 struct sockaddr_in *sin; 1576 1577 if (getifaddrs(&ifap) < 0) 1578 return false; 1579 for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) { 1580 if (ifa->ifa_addr->sa_family != AF_INET || 1581 (ifa->ifa_flags & IFF_BROADCAST) == 0) 1582 continue; 1583 sin = (struct sockaddr_in *)(void *)ifa->ifa_broadaddr; 1584 if (sin->sin_addr.s_addr == in->s_addr) { 1585 freeifaddrs(ifap); 1586 return true; 1587 } 1588 } 1589 freeifaddrs(ifap); 1590 return false; 1591 } 1592 1593 static int 1594 my_kevent(const struct kevent *changelist, size_t nchanges, 1595 struct kevent *eventlist, size_t nevents) 1596 { 1597 int result; 1598 1599 while ((result = kevent(kq, changelist, nchanges, eventlist, nevents, 1600 NULL)) < 0) 1601 if (errno != EINTR) { 1602 syslog(LOG_ERR, "kevent: %m"); 1603 exit(EXIT_FAILURE); 1604 } 1605 1606 return (result); 1607 } 1608 1609 static struct kevent * 1610 allocchange(void) 1611 { 1612 if (changes == __arraycount(changebuf)) { 1613 (void) my_kevent(changebuf, __arraycount(changebuf), NULL, 0); 1614 changes = 0; 1615 } 1616 1617 return (&changebuf[changes++]); 1618 } 1619 1620 bool 1621 try_biltin(struct servtab *sep) 1622 { 1623 for (size_t i = 0; i < __arraycount(biltins); i++) { 1624 if (biltins[i].bi_socktype == sep->se_socktype && 1625 strcmp(biltins[i].bi_service, sep->se_service) == 0) { 1626 sep->se_bi = &biltins[i]; 1627 sep->se_wait = biltins[i].bi_wait; 1628 return true; 1629 } 1630 } 1631 return false; 1632 } 1633