xref: /openbsd/sbin/isakmpd/monitor.c (revision 898184e3)
1 /* $OpenBSD: monitor.c,v 1.72 2010/05/10 02:00:50 krw Exp $	 */
2 
3 /*
4  * Copyright (c) 2003 H�kan Olsson.  All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26 
27 #include <sys/param.h>
28 #include <sys/types.h>
29 #include <sys/socket.h>
30 #include <sys/ioctl.h>
31 #include <sys/stat.h>
32 #include <sys/wait.h>
33 #include <netinet/in.h>
34 
35 #include <dirent.h>
36 #include <errno.h>
37 #include <fcntl.h>
38 #include <pwd.h>
39 #include <signal.h>
40 #include <stdlib.h>
41 #include <string.h>
42 #include <unistd.h>
43 
44 #include <regex.h>
45 #include <keynote.h>
46 
47 #include "conf.h"
48 #include "log.h"
49 #include "monitor.h"
50 #include "policy.h"
51 #include "ui.h"
52 #include "util.h"
53 #include "pf_key_v2.h"
54 
55 struct monitor_state {
56 	pid_t           pid;
57 	int             s;
58 	char            root[MAXPATHLEN];
59 } m_state;
60 
61 extern char *pid_file;
62 
63 extern void	set_slave_signals(void);
64 
65 /* Private functions.  */
66 static void	must_read(void *, size_t);
67 static void	must_write(const void *, size_t);
68 
69 static void	m_priv_getfd(void);
70 static void	m_priv_setsockopt(void);
71 static void	m_priv_req_readdir(void);
72 static void	m_priv_bind(void);
73 static void	m_priv_pfkey_open(void);
74 static int	m_priv_local_sanitize_path(char *, size_t, int);
75 static int	m_priv_check_sockopt(int, int);
76 static int	m_priv_check_bind(const struct sockaddr *, socklen_t);
77 
78 static void	set_monitor_signals(void);
79 static void	sig_pass_to_chld(int);
80 
81 /*
82  * Public functions, unprivileged.
83  */
84 
85 /* Setup monitor context, fork, drop child privs.  */
86 pid_t
87 monitor_init(int debug)
88 {
89 	struct passwd  *pw;
90 	int             p[2];
91 
92 	bzero(&m_state, sizeof m_state);
93 
94 	if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, p) != 0)
95 		log_fatal("monitor_init: socketpair() failed");
96 
97 	pw = getpwnam(ISAKMPD_PRIVSEP_USER);
98 	if (pw == NULL)
99 		log_fatalx("monitor_init: getpwnam(\"%s\") failed",
100 		    ISAKMPD_PRIVSEP_USER);
101 	strlcpy(m_state.root, pw->pw_dir, sizeof m_state.root);
102 
103 	set_monitor_signals();
104 	m_state.pid = fork();
105 
106 	if (m_state.pid == -1)
107 		log_fatal("monitor_init: fork of unprivileged child failed");
108 	if (m_state.pid == 0) {
109 		/* The child process drops privileges. */
110 		set_slave_signals();
111 
112 		if (chroot(pw->pw_dir) != 0 || chdir("/") != 0)
113 			log_fatal("monitor_init: chroot failed");
114 
115 		if (setgroups(1, &pw->pw_gid) == -1 ||
116 		    setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) ||
117 		    setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid))
118 			log_fatal("monitor_init: can't drop privileges");
119 
120 		m_state.s = p[0];
121 		close(p[1]);
122 
123 		LOG_DBG((LOG_MISC, 10,
124 		    "monitor_init: privileges dropped for child process"));
125 	} else {
126 		/* Privileged monitor. */
127 		setproctitle("monitor [priv]");
128 
129 		m_state.s = p[1];
130 		close(p[0]);
131 	}
132 
133 	/* With "-dd", stop and wait here. For gdb "attach" etc.  */
134 	if (debug > 1) {
135 		log_print("monitor_init: stopped %s PID %d fd %d%s",
136 		    m_state.pid ? "priv" : "child", getpid(), m_state.s,
137 		    m_state.pid ? ", waiting for SIGCONT" : "");
138 		kill(getpid(), SIGSTOP);	/* Wait here for SIGCONT.  */
139 		if (m_state.pid)
140 			kill(m_state.pid, SIGCONT); /* Continue child.  */
141 	}
142 
143 	return m_state.pid;
144 }
145 
146 void
147 monitor_exit(int code)
148 {
149 	int status;
150 	pid_t pid;
151 
152 	if (m_state.pid != 0) {
153 		/* When called from the monitor, kill slave and wait for it  */
154 		kill(m_state.pid, SIGTERM);
155 
156 		do {
157 			pid = waitpid(m_state.pid, &status, 0);
158 		} while (pid == -1 && errno == EINTR);
159 
160 		/* Remove FIFO and pid files.  */
161 		unlink(ui_fifo);
162 		unlink(pid_file);
163 	}
164 
165 	close(m_state.s);
166 	exit(code);
167 }
168 
169 int
170 monitor_pf_key_v2_open(void)
171 {
172 	int	err, cmd;
173 
174 	cmd = MONITOR_PFKEY_OPEN;
175 	must_write(&cmd, sizeof cmd);
176 
177 	must_read(&err, sizeof err);
178 	if (err < 0) {
179 		log_error("monitor_pf_key_v2_open: parent could not create "
180 		    "PF_KEY socket");
181 		return -1;
182 	}
183 	pf_key_v2_socket = mm_receive_fd(m_state.s);
184 	if (pf_key_v2_socket < 0) {
185 		log_error("monitor_pf_key_v2_open: mm_receive_fd() failed");
186 		return -1;
187 	}
188 
189 	return pf_key_v2_socket;
190 }
191 
192 int
193 monitor_open(const char *path, int flags, mode_t mode)
194 {
195 	size_t	len;
196 	int	fd, err, cmd;
197 	char	pathreal[MAXPATHLEN];
198 
199 	if (path[0] == '/')
200 		strlcpy(pathreal, path, sizeof pathreal);
201 	else
202 		snprintf(pathreal, sizeof pathreal, "%s/%s", m_state.root,
203 		    path);
204 
205 	cmd = MONITOR_GET_FD;
206 	must_write(&cmd, sizeof cmd);
207 
208 	len = strlen(pathreal);
209 	must_write(&len, sizeof len);
210 	must_write(&pathreal, len);
211 
212 	must_write(&flags, sizeof flags);
213 	must_write(&mode, sizeof mode);
214 
215 	must_read(&err, sizeof err);
216 	if (err != 0) {
217 		errno = err;
218 		return -1;
219 	}
220 
221 	fd = mm_receive_fd(m_state.s);
222 	if (fd < 0) {
223 		log_error("monitor_open: mm_receive_fd () failed");
224 		return -1;
225 	}
226 
227 	return fd;
228 }
229 
230 FILE *
231 monitor_fopen(const char *path, const char *mode)
232 {
233 	FILE	*fp;
234 	int	 fd, flags = 0, saved_errno;
235 	mode_t	 mask, cur_umask;
236 
237 	/* Only the child process is supposed to run this.  */
238 	if (m_state.pid)
239 		log_fatal("[priv] bad call to monitor_fopen");
240 
241 	switch (mode[0]) {
242 	case 'r':
243 		flags = (mode[1] == '+' ? O_RDWR : O_RDONLY);
244 		break;
245 	case 'w':
246 		flags = (mode[1] == '+' ? O_RDWR : O_WRONLY) | O_CREAT |
247 		    O_TRUNC;
248 		break;
249 	case 'a':
250 		flags = (mode[1] == '+' ? O_RDWR : O_WRONLY) | O_CREAT |
251 		    O_APPEND;
252 		break;
253 	default:
254 		log_fatal("monitor_fopen: bad call");
255 	}
256 
257 	cur_umask = umask(0);
258 	(void)umask(cur_umask);
259 	mask = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
260 	mask &= ~cur_umask;
261 
262 	fd = monitor_open(path, flags, mask);
263 	if (fd < 0)
264 		return NULL;
265 
266 	/* Got the fd, attach a FILE * to it.  */
267 	fp = fdopen(fd, mode);
268 	if (!fp) {
269 		log_error("monitor_fopen: fdopen() failed");
270 		saved_errno = errno;
271 		close(fd);
272 		errno = saved_errno;
273 		return NULL;
274 	}
275 	return fp;
276 }
277 
278 int
279 monitor_stat(const char *path, struct stat *sb)
280 {
281 	int	fd, r, saved_errno;
282 
283 	/* O_NONBLOCK is needed for stat'ing fifos. */
284 	fd = monitor_open(path, O_RDONLY | O_NONBLOCK, 0);
285 	if (fd < 0)
286 		return -1;
287 
288 	r = fstat(fd, sb);
289 	saved_errno = errno;
290 	close(fd);
291 	errno = saved_errno;
292 	return r;
293 }
294 
295 int
296 monitor_setsockopt(int s, int level, int optname, const void *optval,
297     socklen_t optlen)
298 {
299 	int	ret, err, cmd;
300 
301 	cmd = MONITOR_SETSOCKOPT;
302 	must_write(&cmd, sizeof cmd);
303 	if (mm_send_fd(m_state.s, s)) {
304 		log_print("monitor_setsockopt: read/write error");
305 		return -1;
306 	}
307 
308 	must_write(&level, sizeof level);
309 	must_write(&optname, sizeof optname);
310 	must_write(&optlen, sizeof optlen);
311 	must_write(optval, optlen);
312 
313 	must_read(&err, sizeof err);
314 	must_read(&ret, sizeof ret);
315 	if (err != 0)
316 		errno = err;
317 	return ret;
318 }
319 
320 int
321 monitor_bind(int s, const struct sockaddr *name, socklen_t namelen)
322 {
323 	int	ret, err, cmd;
324 
325 	cmd = MONITOR_BIND;
326 	must_write(&cmd, sizeof cmd);
327 	if (mm_send_fd(m_state.s, s)) {
328 		log_print("monitor_bind: read/write error");
329 		return -1;
330 	}
331 
332 	must_write(&namelen, sizeof namelen);
333 	must_write(name, namelen);
334 
335 	must_read(&err, sizeof err);
336 	must_read(&ret, sizeof ret);
337 	if (err != 0)
338 		errno = err;
339 	return ret;
340 }
341 
342 int
343 monitor_req_readdir(const char *filename)
344 {
345 	int cmd, err;
346 	size_t len;
347 
348 	cmd = MONITOR_REQ_READDIR;
349 	must_write(&cmd, sizeof cmd);
350 
351 	len = strlen(filename);
352 	must_write(&len, sizeof len);
353 	must_write(filename, len);
354 
355 	must_read(&err, sizeof err);
356 	if (err == -1)
357 		must_read(&errno, sizeof errno);
358 
359 	return err;
360 }
361 
362 int
363 monitor_readdir(char *file, size_t size)
364 {
365 	int fd;
366 	size_t len;
367 
368 	must_read(&len, sizeof len);
369 	if (len == 0)
370 		return -1;
371 	if (len >= size)
372 		log_fatal("monitor_readdir: received bad length from monitor");
373 	must_read(file, len);
374 	file[len] = '\0';
375 	fd = mm_receive_fd(m_state.s);
376 	return fd;
377 }
378 
379 void
380 monitor_init_done(void)
381 {
382 	int	cmd;
383 
384 	cmd = MONITOR_INIT_DONE;
385 	must_write(&cmd, sizeof cmd);
386 }
387 
388 /*
389  * Start of code running with privileges (the monitor process).
390  */
391 
392 static void
393 set_monitor_signals(void)
394 {
395 	int n;
396 
397 	for (n = 1; n < _NSIG; n++)
398 		signal(n, SIG_DFL);
399 
400 	/* Forward some signals to the child. */
401 	signal(SIGTERM, sig_pass_to_chld);
402 	signal(SIGHUP, sig_pass_to_chld);
403 	signal(SIGUSR1, sig_pass_to_chld);
404 }
405 
406 static void
407 sig_pass_to_chld(int sig)
408 {
409 	int	oerrno = errno;
410 
411 	if (m_state.pid > 0)
412 		kill(m_state.pid, sig);
413 	errno = oerrno;
414 }
415 
416 /* This function is where the privileged process waits(loops) indefinitely.  */
417 void
418 monitor_loop(int debug)
419 {
420 	int	 msgcode;
421 
422 	if (!debug)
423 		log_to(0);
424 
425 	for (;;) {
426 		must_read(&msgcode, sizeof msgcode);
427 
428 		switch (msgcode) {
429 		case MONITOR_GET_FD:
430 			m_priv_getfd();
431 			break;
432 
433 		case MONITOR_PFKEY_OPEN:
434 			LOG_DBG((LOG_MISC, 80,
435 			    "monitor_loop: MONITOR_PFKEY_OPEN"));
436 			m_priv_pfkey_open();
437 			break;
438 
439 		case MONITOR_SETSOCKOPT:
440 			LOG_DBG((LOG_MISC, 80,
441 			    "monitor_loop: MONITOR_SETSOCKOPT"));
442 			m_priv_setsockopt();
443 			break;
444 
445 		case MONITOR_BIND:
446 			LOG_DBG((LOG_MISC, 80,
447 			    "monitor_loop: MONITOR_BIND"));
448 			m_priv_bind();
449 			break;
450 
451 		case MONITOR_REQ_READDIR:
452 			LOG_DBG((LOG_MISC, 80,
453 			    "monitor_loop: MONITOR_REQ_READDIR"));
454 			m_priv_req_readdir();
455 			break;
456 
457 		case MONITOR_INIT_DONE:
458 			LOG_DBG((LOG_MISC, 80,
459 			    "monitor_loop: MONITOR_INIT_DONE"));
460 			break;
461 
462 		case MONITOR_SHUTDOWN:
463 			LOG_DBG((LOG_MISC, 80,
464 			    "monitor_loop: MONITOR_SHUTDOWN"));
465 			break;
466 
467 		default:
468 			log_print("monitor_loop: got unknown code %d",
469 			    msgcode);
470 		}
471 	}
472 
473 	exit(0);
474 }
475 
476 
477 /* Privileged: called by monitor_loop.  */
478 static void
479 m_priv_pfkey_open(void)
480 {
481 	int	fd, err = 0;
482 
483 	fd = pf_key_v2_open();
484 	if (fd < 0)
485 		err = -1;
486 
487 	must_write(&err, sizeof err);
488 
489 	if (fd > 0 && mm_send_fd(m_state.s, fd)) {
490 		log_error("m_priv_pfkey_open: read/write operation failed");
491 		close(fd);
492 		return;
493 	}
494 	close(fd);
495 }
496 
497 /* Privileged: called by monitor_loop.  */
498 static void
499 m_priv_getfd(void)
500 {
501 	char	path[MAXPATHLEN];
502 	size_t	len;
503 	int	v, flags, ret;
504 	int	err = 0;
505 	mode_t	mode;
506 
507 	must_read(&len, sizeof len);
508 	if (len == 0 || len >= sizeof path)
509 		log_fatal("m_priv_getfd: invalid pathname length");
510 
511 	must_read(path, len);
512 	path[len] = '\0';
513 	if (strlen(path) != len)
514 		log_fatal("m_priv_getfd: invalid pathname");
515 
516 	must_read(&flags, sizeof flags);
517 	must_read(&mode, sizeof mode);
518 
519 	if ((ret = m_priv_local_sanitize_path(path, sizeof path, flags))
520 	    != 0) {
521 		if (ret == 1)
522 			log_print("m_priv_getfd: illegal path \"%s\"", path);
523 		err = EACCES;
524 		v = -1;
525 	} else {
526 		if ((v = open(path, flags, mode)) == -1)
527 			err = errno;
528 	}
529 
530 	must_write(&err, sizeof err);
531 
532 	if (v != -1) {
533 		if (mm_send_fd(m_state.s, v) == -1)
534 			log_error("m_priv_getfd: sending fd failed");
535 		close(v);
536 	}
537 }
538 
539 /* Privileged: called by monitor_loop.  */
540 static void
541 m_priv_setsockopt(void)
542 {
543 	int		 sock, level, optname, v;
544 	int		 err = 0;
545 	char		*optval = 0;
546 	socklen_t	 optlen;
547 
548 	sock = mm_receive_fd(m_state.s);
549 	if (sock < 0) {
550 		log_print("m_priv_setsockopt: read/write error");
551 		return;
552 	}
553 
554 	must_read(&level, sizeof level);
555 	must_read(&optname, sizeof optname);
556 	must_read(&optlen, sizeof optlen);
557 
558 	optval = (char *)malloc(optlen);
559 	if (!optval) {
560 		log_print("m_priv_setsockopt: malloc failed");
561 		close(sock);
562 		return;
563 	}
564 
565 	must_read(optval, optlen);
566 
567 	if (m_priv_check_sockopt(level, optname) != 0) {
568 		err = EACCES;
569 		v = -1;
570 	} else {
571 		v = setsockopt(sock, level, optname, optval, optlen);
572 		if (v < 0)
573 			err = errno;
574 	}
575 
576 	close(sock);
577 	sock = -1;
578 
579 	must_write(&err, sizeof err);
580 	must_write(&v, sizeof v);
581 
582 	free(optval);
583 	return;
584 }
585 
586 /* Privileged: called by monitor_loop.  */
587 static void
588 m_priv_bind(void)
589 {
590 	int		 sock, v, err = 0;
591 	struct sockaddr *name = 0;
592 	socklen_t        namelen;
593 
594 	sock = mm_receive_fd(m_state.s);
595 	if (sock < 0) {
596 		log_print("m_priv_bind: read/write error");
597 		return;
598 	}
599 
600 	must_read(&namelen, sizeof namelen);
601 	name = (struct sockaddr *)malloc(namelen);
602 	if (!name) {
603 		log_print("m_priv_bind: malloc failed");
604 		close(sock);
605 		return;
606 	}
607 	must_read((char *)name, namelen);
608 
609 	if (m_priv_check_bind(name, namelen) != 0) {
610 		err = EACCES;
611 		v = -1;
612 	} else {
613 		v = bind(sock, name, namelen);
614 		if (v < 0) {
615 			log_error("m_priv_bind: bind(%d,%p,%d) returned %d",
616 			    sock, name, namelen, v);
617 			err = errno;
618 		}
619 	}
620 
621 	close(sock);
622 	sock = -1;
623 
624 	must_write(&err, sizeof err);
625 	must_write(&v, sizeof v);
626 
627 	free(name);
628 	return;
629 }
630 
631 /*
632  * Help functions, used by both privileged and unprivileged code
633  */
634 
635 /*
636  * Read data with the assertion that it all must come through, or else abort
637  * the process.  Based on atomicio() from openssh.
638  */
639 static void
640 must_read(void *buf, size_t n)
641 {
642         char *s = buf;
643 	size_t pos = 0;
644         ssize_t res;
645 
646         while (n > pos) {
647                 res = read(m_state.s, s + pos, n - pos);
648                 switch (res) {
649                 case -1:
650                         if (errno == EINTR || errno == EAGAIN)
651                                 continue;
652                 case 0:
653 			monitor_exit(0);
654                 default:
655                         pos += res;
656                 }
657         }
658 }
659 
660 /*
661  * Write data with the assertion that it all has to be written, or else abort
662  * the process.  Based on atomicio() from openssh.
663  */
664 static void
665 must_write(const void *buf, size_t n)
666 {
667         const char *s = buf;
668 	size_t pos = 0;
669 	ssize_t res;
670 
671         while (n > pos) {
672                 res = write(m_state.s, s + pos, n - pos);
673                 switch (res) {
674                 case -1:
675                         if (errno == EINTR || errno == EAGAIN)
676                                 continue;
677                 case 0:
678 			monitor_exit(0);
679                 default:
680                         pos += res;
681                 }
682         }
683 }
684 
685 /* Check that path/mode is permitted.  */
686 static int
687 m_priv_local_sanitize_path(char *path, size_t pmax, int flags)
688 {
689 	char new_path[PATH_MAX], var_run[PATH_MAX];
690 
691 	/*
692 	 * We only permit paths starting with
693 	 *  /etc/isakmpd/	(read only)
694 	 *  /var/run/		(rw)
695          */
696 
697 	if (realpath(path, new_path) == NULL ||
698 	    realpath("/var/run", var_run) == NULL) {
699 		/*
700                  * We could not decide whether the path is ok or not.
701                  * Indicate this be returning 2.
702 		 */
703 		if (errno == ENOENT)
704 			return 2;
705 		goto bad_path;
706 	}
707 	strlcat(var_run, "/", sizeof(var_run));
708 
709 	if (strncmp(var_run, new_path, strlen(var_run)) == 0)
710 		return 0;
711 
712 	if (strncmp(ISAKMPD_ROOT, new_path, strlen(ISAKMPD_ROOT)) == 0 &&
713 	    (flags & O_ACCMODE) == O_RDONLY)
714 		return 0;
715 
716 bad_path:
717 	return 1;
718 }
719 
720 /* Check setsockopt */
721 static int
722 m_priv_check_sockopt(int level, int name)
723 {
724 	switch (level) {
725 		/* These are allowed */
726 		case SOL_SOCKET:
727 		case IPPROTO_IP:
728 		case IPPROTO_IPV6:
729 		break;
730 
731 	default:
732 		log_print("m_priv_check_sockopt: Illegal level %d", level);
733 		return 1;
734 	}
735 
736 	switch (name) {
737 		/* These are allowed */
738 	case SO_REUSEPORT:
739 	case SO_REUSEADDR:
740 	case IP_AUTH_LEVEL:
741 	case IP_ESP_TRANS_LEVEL:
742 	case IP_ESP_NETWORK_LEVEL:
743 	case IP_IPCOMP_LEVEL:
744 	case IPV6_AUTH_LEVEL:
745 	case IPV6_ESP_TRANS_LEVEL:
746 	case IPV6_ESP_NETWORK_LEVEL:
747 	case IPV6_IPCOMP_LEVEL:
748 		break;
749 
750 	default:
751 		log_print("m_priv_check_sockopt: Illegal option name %d",
752 		    name);
753 		return 1;
754 	}
755 
756 	return 0;
757 }
758 
759 /* Check bind */
760 static int
761 m_priv_check_bind(const struct sockaddr *sa, socklen_t salen)
762 {
763 	in_port_t       port;
764 
765 	if (sa == NULL) {
766 		log_print("NULL address");
767 		return 1;
768 	}
769 	if (SA_LEN(sa) != salen) {
770 		log_print("Length mismatch: %lu %lu", (unsigned long)sa->sa_len,
771 		    (unsigned long)salen);
772 		return 1;
773 	}
774 	switch (sa->sa_family) {
775 	case AF_INET:
776 		if (salen != sizeof(struct sockaddr_in)) {
777 			log_print("Invalid inet address length");
778 			return 1;
779 		}
780 		port = ((const struct sockaddr_in *)sa)->sin_port;
781 		break;
782 	case AF_INET6:
783 		if (salen != sizeof(struct sockaddr_in6)) {
784 			log_print("Invalid inet6 address length");
785 			return 1;
786 		}
787 		port = ((const struct sockaddr_in6 *)sa)->sin6_port;
788 		break;
789 	default:
790 		log_print("Unknown address family");
791 		return 1;
792 	}
793 
794 	port = ntohs(port);
795 
796 	if (port != ISAKMP_PORT_DEFAULT && port < 1024) {
797 		log_print("Disallowed port %u", port);
798 		return 1;
799 	}
800 	return 0;
801 }
802 
803 static void
804 m_priv_req_readdir()
805 {
806 	size_t len;
807 	char path[MAXPATHLEN];
808 	DIR *dp;
809 	struct dirent *file;
810 	struct stat sb;
811 	int off, size, fd, ret, serrno;
812 
813 	must_read(&len, sizeof len);
814 	if (len == 0 || len >= sizeof path)
815 		log_fatal("m_priv_req_readdir: invalid pathname length");
816 	must_read(path, len);
817 	path[len] = '\0';
818 	if (strlen(path) != len)
819 		log_fatal("m_priv_req_readdir: invalid pathname");
820 
821 	off = strlen(path);
822 	size = sizeof path - off;
823 
824 	if ((dp = opendir(path)) == NULL) {
825 		serrno = errno;
826 		ret = -1;
827 		must_write(&ret, sizeof ret);
828 		must_write(&serrno, sizeof serrno);
829 		return;
830 	}
831 
832 	/* report opendir() success */
833 	ret = 0;
834 	must_write(&ret, sizeof ret);
835 
836 	while ((file = readdir(dp)) != NULL) {
837 		strlcpy(path + off, file->d_name, size);
838 
839 		if (m_priv_local_sanitize_path(path, sizeof path, O_RDONLY)
840 		    != 0)
841 			continue;
842 		fd = open(path, O_RDONLY, 0);
843 		if (fd == -1) {
844 			log_error("m_priv_req_readdir: open "
845 			    "(\"%s\", O_RDONLY, 0) failed", path);
846 			continue;
847 		}
848 		if ((fstat(fd, &sb) == -1) ||
849 		    !(S_ISREG(sb.st_mode) || S_ISLNK(sb.st_mode))) {
850 			close(fd);
851 			continue;
852 		}
853 
854 		len = strlen(path);
855 		must_write(&len, sizeof len);
856 		must_write(path, len);
857 
858 		mm_send_fd(m_state.s, fd);
859 		close(fd);
860 	}
861 	closedir(dp);
862 
863 	len = 0;
864 	must_write(&len, sizeof len);
865 }
866