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