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