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