1 /* $OpenBSD: monitor.c,v 1.60 2005/06/13 13:32:59 millert 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 volatile sig_atomic_t sigchlded = 0;
62 extern volatile sig_atomic_t sigtermed;
63 
64 extern void	set_slave_signals(void);
65 
66 /* Private functions.  */
67 static void	must_read(void *, size_t);
68 static void	must_write(const void *, size_t);
69 
70 static void	m_priv_getfd(void);
71 static void	m_priv_setsockopt(void);
72 static void	m_priv_req_readdir(void);
73 static void	m_priv_bind(void);
74 static void	m_priv_ui_init(void);
75 static void	m_priv_pfkey_open(void);
76 static int      m_priv_local_sanitize_path(char *, size_t, int);
77 static int      m_priv_check_sockopt(int, int);
78 static int      m_priv_check_bind(const struct sockaddr *, socklen_t);
79 
80 static void	set_monitor_signals(void);
81 static void	monitor_got_sigchld(int);
82 static void	sig_pass_to_chld(int);
83 
84 /*
85  * Public functions, unprivileged.
86  */
87 
88 /* Setup monitor context, fork, drop child privs.  */
89 pid_t
monitor_init(int debug)90 monitor_init(int debug)
91 {
92 	struct passwd  *pw;
93 	int             p[2];
94 
95 	bzero(&m_state, sizeof m_state);
96 
97 	if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, p) != 0)
98 		log_fatal("monitor_init: socketpair() failed");
99 
100 	pw = getpwnam(ISAKMPD_PRIVSEP_USER);
101 	if (pw == NULL)
102 		log_fatalx("monitor_init: getpwnam(\"%s\") failed",
103 		    ISAKMPD_PRIVSEP_USER);
104 	strlcpy(m_state.root, pw->pw_dir, sizeof m_state.root);
105 
106 	set_monitor_signals();
107 	m_state.pid = fork();
108 
109 	if (m_state.pid == -1)
110 		log_fatal("monitor_init: fork of unprivileged child failed");
111 	if (m_state.pid == 0) {
112 		/* The child process drops privileges. */
113 		set_slave_signals();
114 
115 		if (chroot(pw->pw_dir) != 0 || chdir("/") != 0)
116 			log_fatal("monitor_init: chroot failed");
117 
118 		if (setgroups(1, &pw->pw_gid) == -1 ||
119 		    setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) ||
120 		    setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid))
121 			log_fatal("monitor_init: can't drop privileges");
122 
123 		m_state.s = p[0];
124 		close(p[1]);
125 
126 		LOG_DBG((LOG_MISC, 10,
127 		    "monitor_init: privileges dropped for child process"));
128 	} else {
129 		/* Privileged monitor. */
130 		setproctitle("monitor [priv]");
131 
132 		m_state.s = p[1];
133 		close(p[0]);
134 	}
135 
136 	/* With "-dd", stop and wait here. For gdb "attach" etc.  */
137 	if (debug > 1) {
138 		log_print("monitor_init: stopped %s PID %d fd %d%s",
139 		    m_state.pid ? "priv" : "child", getpid(), m_state.s,
140 		    m_state.pid ? ", waiting for SIGCONT" : "");
141 		kill(getpid(), SIGSTOP);	/* Wait here for SIGCONT.  */
142 		if (m_state.pid)
143 			kill(m_state.pid, SIGCONT); /* Continue child.  */
144 	}
145 
146 	return m_state.pid;
147 }
148 
149 void
monitor_exit(int code)150 monitor_exit(int code)
151 {
152 	if (m_state.pid != 0)
153 		kill(m_state.pid, SIGKILL);
154 
155 	close(m_state.s);
156 	exit(code);
157 }
158 
159 void
monitor_ui_init(void)160 monitor_ui_init(void)
161 {
162 	int	err, cmd;
163 
164 	cmd = MONITOR_UI_INIT;
165 	must_write(&cmd, sizeof cmd);
166 
167 	must_read(&err, sizeof err);
168 	if (err != 0)
169 		log_fatal("monitor_ui_init: parent could not create FIFO "
170 		    "\"%s\"", ui_fifo);
171 
172 	ui_socket = mm_receive_fd(m_state.s);
173 	if (ui_socket < 0)
174 		log_fatal("monitor_ui_init: parent could not create FIFO "
175 		    "\"%s\"", ui_fifo);
176 
177 	return;
178 }
179 
180 int
monitor_pf_key_v2_open(void)181 monitor_pf_key_v2_open(void)
182 {
183 	int	err, cmd;
184 
185 	cmd = MONITOR_PFKEY_OPEN;
186 	must_write(&cmd, sizeof cmd);
187 
188 	must_read(&err, sizeof err);
189 	if (err < 0) {
190 		log_error("monitor_pf_key_v2_open: parent could not create "
191 		    "PF_KEY socket");
192 		return -1;
193 	}
194 	pf_key_v2_socket = mm_receive_fd(m_state.s);
195 	if (pf_key_v2_socket < 0) {
196 		log_error("monitor_pf_key_v2_open: mm_receive_fd() failed: %s",
197 		    strerror(errno));
198 		return -1;
199 	}
200 
201 	return pf_key_v2_socket;
202 }
203 
204 int
monitor_open(const char * path,int flags,mode_t mode)205 monitor_open(const char *path, int flags, mode_t mode)
206 {
207 	size_t	len;
208 	int	fd, err, cmd;
209 	char	pathreal[MAXPATHLEN];
210 
211 	if (path[0] == '/')
212 		strlcpy(pathreal, path, sizeof pathreal);
213 	else
214 		snprintf(pathreal, sizeof pathreal, "%s/%s", m_state.root,
215 		    path);
216 
217 	cmd = MONITOR_GET_FD;
218 	must_write(&cmd, sizeof cmd);
219 
220 	len = strlen(pathreal);
221 	must_write(&len, sizeof len);
222 	must_write(&pathreal, len);
223 
224 	must_write(&flags, sizeof flags);
225 	must_write(&mode, sizeof mode);
226 
227 	must_read(&err, sizeof err);
228 	if (err != 0) {
229 		errno = err;
230 		return -1;
231 	}
232 
233 	fd = mm_receive_fd(m_state.s);
234 	if (fd < 0) {
235 		log_error("monitor_open: mm_receive_fd () failed: %s",
236 		    strerror(errno));
237 		return -1;
238 	}
239 
240 	return fd;
241 }
242 
243 FILE *
monitor_fopen(const char * path,const char * mode)244 monitor_fopen(const char *path, const char *mode)
245 {
246 	FILE	*fp;
247 	int	 fd, flags = 0, saved_errno;
248 	mode_t	 mask, cur_umask;
249 
250 	/* Only the child process is supposed to run this.  */
251 	if (m_state.pid)
252 		log_fatal("[priv] bad call to monitor_fopen");
253 
254 	switch (mode[0]) {
255 	case 'r':
256 		flags = (mode[1] == '+' ? O_RDWR : O_RDONLY);
257 		break;
258 	case 'w':
259 		flags = (mode[1] == '+' ? O_RDWR : O_WRONLY) | O_CREAT |
260 		    O_TRUNC;
261 		break;
262 	case 'a':
263 		flags = (mode[1] == '+' ? O_RDWR : O_WRONLY) | O_CREAT |
264 		    O_APPEND;
265 		break;
266 	default:
267 		log_fatal("monitor_fopen: bad call");
268 	}
269 
270 	cur_umask = umask(0);
271 	(void)umask(cur_umask);
272 	mask = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
273 	mask &= ~cur_umask;
274 
275 	fd = monitor_open(path, flags, mask);
276 	if (fd < 0)
277 		return NULL;
278 
279 	/* Got the fd, attach a FILE * to it.  */
280 	fp = fdopen(fd, mode);
281 	if (!fp) {
282 		log_error("monitor_fopen: fdopen() failed");
283 		saved_errno = errno;
284 		close(fd);
285 		errno = saved_errno;
286 		return NULL;
287 	}
288 	return fp;
289 }
290 
291 int
monitor_stat(const char * path,struct stat * sb)292 monitor_stat(const char *path, struct stat *sb)
293 {
294 	int	fd, r, saved_errno;
295 
296 	/* O_NONBLOCK is needed for stat'ing fifos. */
297 	fd = monitor_open(path, O_RDONLY | O_NONBLOCK, 0);
298 	if (fd < 0)
299 		return -1;
300 
301 	r = fstat(fd, sb);
302 	saved_errno = errno;
303 	close(fd);
304 	errno = saved_errno;
305 	return r;
306 }
307 
308 int
monitor_setsockopt(int s,int level,int optname,const void * optval,socklen_t optlen)309 monitor_setsockopt(int s, int level, int optname, const void *optval,
310     socklen_t optlen)
311 {
312 	int	ret, err, cmd;
313 
314 	cmd = MONITOR_SETSOCKOPT;
315 	must_write(&cmd, sizeof cmd);
316 	if (mm_send_fd(m_state.s, s))
317 		goto errout;
318 
319 	must_write(&level, sizeof level);
320 	must_write(&optname, sizeof optname);
321 	must_write(&optlen, sizeof optlen);
322 	must_write(optval, optlen);
323 
324 	must_read(&err, sizeof err);
325 	must_read(&ret, sizeof ret);
326 	if (err != 0)
327 		errno = err;
328 	return ret;
329 
330 errout:
331 	log_print("monitor_setsockopt: read/write error");
332 	return -1;
333 }
334 
335 int
monitor_bind(int s,const struct sockaddr * name,socklen_t namelen)336 monitor_bind(int s, const struct sockaddr *name, socklen_t namelen)
337 {
338 	int	ret, err, cmd;
339 
340 	cmd = MONITOR_BIND;
341 	must_write(&cmd, sizeof cmd);
342 	if (mm_send_fd(m_state.s, s))
343 		goto errout;
344 
345 	must_write(&namelen, sizeof namelen);
346 	must_write(name, namelen);
347 
348 	must_read(&err, sizeof err);
349 	must_read(&ret, sizeof ret);
350 	if (err != 0)
351 		errno = err;
352 	return ret;
353 
354 errout:
355 	log_print("monitor_bind: read/write error");
356 	return -1;
357 }
358 
359 int
monitor_req_readdir(const char * filename)360 monitor_req_readdir(const char *filename)
361 {
362 	int cmd, err;
363 	size_t len;
364 
365 	cmd = MONITOR_REQ_READDIR;
366 	must_write(&cmd, sizeof cmd);
367 
368 	len = strlen(filename);
369 	must_write(&len, sizeof len);
370 	must_write(filename, len);
371 
372 	must_read(&err, sizeof err);
373 	if (err == -1)
374 		must_read(&errno, sizeof errno);
375 
376 	return (err);
377 }
378 
379 int
monitor_readdir(char * file,size_t size)380 monitor_readdir(char *file, size_t size)
381 {
382 	int fd;
383 	size_t len;
384 
385 	must_read(&len, sizeof len);
386 	if (len == 0)
387 		return -1;
388 	if (len >= size)
389 		log_fatal("monitor_readdir: received bad length from monitor");
390 	must_read(file, len);
391 	file[len] = '\0';
392 	fd = mm_receive_fd(m_state.s);
393 	return fd;
394 }
395 
396 void
monitor_init_done(void)397 monitor_init_done(void)
398 {
399 	int	cmd;
400 
401 	cmd = MONITOR_INIT_DONE;
402 	must_write(&cmd, sizeof cmd);
403 }
404 
405 /*
406  * Start of code running with privileges (the monitor process).
407  */
408 
409 static void
set_monitor_signals(void)410 set_monitor_signals(void)
411 {
412 	int n;
413 
414 	for (n = 0; n < _NSIG; n++)
415 		signal(n, SIG_DFL);
416 
417 	/* If the child dies, we should shutdown also.  */
418 	signal(SIGCHLD, monitor_got_sigchld);
419 
420 	/* Forward some signals to the child. */
421 	signal(SIGTERM, sig_pass_to_chld);
422 	signal(SIGHUP, sig_pass_to_chld);
423 	signal(SIGUSR1, sig_pass_to_chld);
424 }
425 
426 /* ARGSUSED */
427 static void
monitor_got_sigchld(int sig)428 monitor_got_sigchld(int sig)
429 {
430 	sigchlded = 1;
431 }
432 
433 static void
sig_pass_to_chld(int sig)434 sig_pass_to_chld(int sig)
435 {
436 	int	oerrno = errno;
437 
438 	if (m_state.pid > 0)
439 		kill(m_state.pid, sig);
440 	errno = oerrno;
441 }
442 
443 /* This function is where the privileged process waits(loops) indefinitely.  */
444 void
monitor_loop(int debug)445 monitor_loop(int debug)
446 {
447 	pid_t	 pid;
448 	int	 msgcode, status;
449 
450 	if (!debug)
451 		log_to(0);
452 
453 	for (;;) {
454 		/*
455 		 * Currently, there is no need for us to hang around if the
456 		 * child is in the process of shutting down.
457 		 */
458 		if (sigtermed) {
459 			kill(m_state.pid, SIGTERM);
460 			break;
461 		}
462 
463 		if (sigchlded) {
464 			do {
465 				pid = waitpid(m_state.pid, &status, WNOHANG);
466 			} while (pid == -1 && errno == EINTR);
467 
468 			if (pid == m_state.pid && (WIFEXITED(status) ||
469 			    WIFSIGNALED(status))) {
470 				break;
471 			}
472 		}
473 
474 		must_read(&msgcode, sizeof msgcode);
475 
476 		switch (msgcode) {
477 		case MONITOR_GET_FD:
478 			m_priv_getfd();
479 			break;
480 
481 		case MONITOR_UI_INIT:
482 			LOG_DBG((LOG_MISC, 80,
483 			    "monitor_loop: MONITOR_UI_INIT"));
484 			m_priv_ui_init();
485 			break;
486 
487 		case MONITOR_PFKEY_OPEN:
488 			LOG_DBG((LOG_MISC, 80,
489 			    "monitor_loop: MONITOR_PFKEY_OPEN"));
490 			m_priv_pfkey_open();
491 			break;
492 
493 		case MONITOR_SETSOCKOPT:
494 			LOG_DBG((LOG_MISC, 80,
495 			    "monitor_loop: MONITOR_SETSOCKOPT"));
496 			m_priv_setsockopt();
497 			break;
498 
499 		case MONITOR_BIND:
500 			LOG_DBG((LOG_MISC, 80,
501 			    "monitor_loop: MONITOR_BIND"));
502 			m_priv_bind();
503 			break;
504 
505 		case MONITOR_REQ_READDIR:
506 			LOG_DBG((LOG_MISC, 80,
507 			    "monitor_loop: MONITOR_REQ_READDIR"));
508 			m_priv_req_readdir();
509 			break;
510 
511 		case MONITOR_INIT_DONE:
512 			LOG_DBG((LOG_MISC, 80,
513 			    "monitor_loop: MONITOR_INIT_DONE"));
514 			break;
515 
516 		case MONITOR_SHUTDOWN:
517 			LOG_DBG((LOG_MISC, 80,
518 			    "monitor_loop: MONITOR_SHUTDOWN"));
519 			break;
520 
521 		default:
522 			log_print("monitor_loop: got unknown code %d",
523 			    msgcode);
524 		}
525 	}
526 
527 	exit(0);
528 }
529 
530 
531 /* Privileged: called by monitor_loop.  */
532 static void
m_priv_ui_init(void)533 m_priv_ui_init(void)
534 {
535 	int	err = 0;
536 
537 	ui_init();
538 
539 	if (ui_socket < 0)
540 		err = -1;
541 
542 	must_write(&err, sizeof err);
543 
544 	if (ui_socket >= 0 && mm_send_fd(m_state.s, ui_socket)) {
545 		close(ui_socket);
546 		goto errout;
547 	}
548 
549 	/* In case of stdin, we do not close the socket. */
550 	if (ui_socket > 0)
551 		close(ui_socket);
552 	return;
553 
554 errout:
555 	log_error("m_priv_ui_init: read/write operation failed");
556 }
557 
558 /* Privileged: called by monitor_loop.  */
559 static void
m_priv_pfkey_open(void)560 m_priv_pfkey_open(void)
561 {
562 	int	fd, err = 0;
563 
564 	fd = pf_key_v2_open();
565 	if (fd < 0)
566 		err = -1;
567 
568 	must_write(&err, sizeof err);
569 
570 	if (fd > 0 && mm_send_fd(m_state.s, fd)) {
571 		close(fd);
572 		goto errout;
573 	}
574 	close(fd);
575 
576 	return;
577 
578 errout:
579 	log_error("m_priv_pfkey_open: read/write operation failed");
580 }
581 
582 /* Privileged: called by monitor_loop.  */
583 static void
m_priv_getfd(void)584 m_priv_getfd(void)
585 {
586 	char	path[MAXPATHLEN];
587 	size_t	len;
588 	int	v, flags;
589 	int	err = 0;
590 	mode_t	mode;
591 
592 	must_read(&len, sizeof len);
593 	if (len == 0 || len >= sizeof path)
594 		log_fatal("m_priv_getfd: invalid pathname length");
595 
596 	must_read(path, len);
597 	path[len] = '\0';
598 	if (strlen(path) != len)
599 		log_fatal("m_priv_getfd: invalid pathname");
600 
601 	must_read(&flags, sizeof flags);
602 	must_read(&mode, sizeof mode);
603 
604 	if (m_priv_local_sanitize_path(path, sizeof path, flags) != 0) {
605 		err = EACCES;
606 		v = -1;
607 	} else {
608 		v = open(path, flags, mode);
609 		if (v < 0)
610 			err = errno;
611 	}
612 
613 	must_write(&err, sizeof err);
614 
615 	if (v > 0 && mm_send_fd(m_state.s, v)) {
616 		close(v);
617 		goto errout;
618 	}
619 	close(v);
620 	return;
621 
622 errout:
623 	log_error("m_priv_getfd: read/write operation failed");
624 }
625 
626 /* Privileged: called by monitor_loop.  */
627 static void
m_priv_setsockopt(void)628 m_priv_setsockopt(void)
629 {
630 	int		 sock, level, optname, v;
631 	int		 err = 0;
632 	char		*optval = 0;
633 	socklen_t	 optlen;
634 
635 	sock = mm_receive_fd(m_state.s);
636 	if (sock < 0)
637 		goto errout;
638 
639 	must_read(&level, sizeof level);
640 	must_read(&optname, sizeof optname);
641 	must_read(&optlen, sizeof optlen);
642 
643 	optval = (char *)malloc(optlen);
644 	if (!optval)
645 		goto errout;
646 
647 	must_read(optval, optlen);
648 
649 	if (m_priv_check_sockopt(level, optname) != 0) {
650 		err = EACCES;
651 		v = -1;
652 	} else {
653 		v = setsockopt(sock, level, optname, optval, optlen);
654 		if (v < 0)
655 			err = errno;
656 	}
657 
658 	close(sock);
659 	sock = -1;
660 
661 	must_write(&err, sizeof err);
662 	must_write(&v, sizeof v);
663 
664 	free(optval);
665 	return;
666 
667 errout:
668 	log_print("m_priv_setsockopt: read/write error");
669 	if (optval)
670 		free(optval);
671 	if (sock >= 0)
672 		close(sock);
673 }
674 
675 /* Privileged: called by monitor_loop.  */
676 static void
m_priv_bind(void)677 m_priv_bind(void)
678 {
679 	int		 sock, v, err = 0;
680 	struct sockaddr *name = 0;
681 	socklen_t        namelen;
682 
683 	sock = mm_receive_fd(m_state.s);
684 	if (sock < 0)
685 		goto errout;
686 
687 	must_read(&namelen, sizeof namelen);
688 	name = (struct sockaddr *)malloc(namelen);
689 	if (!name)
690 		goto errout;
691 	must_read((char *)name, namelen);
692 
693 	if (m_priv_check_bind(name, namelen) != 0) {
694 		err = EACCES;
695 		v = -1;
696 	} else {
697 		v = bind(sock, name, namelen);
698 		if (v < 0) {
699 			log_error("m_priv_bind: bind(%d,%p,%d) returned %d",
700 			    sock, name, namelen, v);
701 			err = errno;
702 		}
703 	}
704 
705 	close(sock);
706 	sock = -1;
707 
708 	must_write(&err, sizeof err);
709 	must_write(&v, sizeof v);
710 
711 	free(name);
712 	return;
713 
714 errout:
715 	log_print("m_priv_bind: read/write error");
716 	if (name)
717 		free(name);
718 	if (sock >= 0)
719 		close(sock);
720 }
721 
722 /*
723  * Help functions, used by both privileged and unprivileged code
724  */
725 
726 /*
727  * Read data with the assertion that it all must come through, or else abort
728  * the process.  Based on atomicio() from openssh.
729  */
730 static void
must_read(void * buf,size_t n)731 must_read(void *buf, size_t n)
732 {
733         char *s = buf;
734 	size_t pos = 0;
735         ssize_t res;
736 
737         while (n > pos) {
738                 res = read(m_state.s, s + pos, n - pos);
739                 switch (res) {
740                 case -1:
741                         if (errno == EINTR || errno == EAGAIN)
742                                 continue;
743                 case 0:
744 			_exit(0);
745                 default:
746                         pos += res;
747                 }
748         }
749 }
750 
751 /*
752  * Write data with the assertion that it all has to be written, or else abort
753  * the process.  Based on atomicio() from openssh.
754  */
755 static void
must_write(const void * buf,size_t n)756 must_write(const void *buf, size_t n)
757 {
758         const char *s = buf;
759 	size_t pos = 0;
760 	ssize_t res;
761 
762         while (n > pos) {
763                 res = write(m_state.s, s + pos, n - pos);
764                 switch (res) {
765                 case -1:
766                         if (errno == EINTR || errno == EAGAIN)
767                                 continue;
768                 case 0:
769 			_exit(0);
770                 default:
771                         pos += res;
772                 }
773         }
774 }
775 
776 /* Check that path/mode is permitted.  */
777 static int
m_priv_local_sanitize_path(char * path,size_t pmax,int flags)778 m_priv_local_sanitize_path(char *path, size_t pmax, int flags)
779 {
780 	char new_path[PATH_MAX], var_run[PATH_MAX];
781 
782 	/*
783 	 * We only permit paths starting with
784 	 *  /etc/isakmpd/	(read only)
785 	 *  /var/run/		(rw)
786          */
787 
788 	if (realpath(path, new_path) == NULL ||
789 	    realpath("/var/run", var_run) == NULL) {
790 		if (errno == ENOENT)
791 			return 1;
792 		goto bad_path;
793 	}
794 	strlcat(var_run, "/", sizeof(var_run));
795 
796 	if (strncmp(var_run, new_path, strlen(var_run)) == 0)
797 		return 0;
798 
799 	if (strncmp(ISAKMPD_ROOT, new_path, strlen(ISAKMPD_ROOT)) == 0 &&
800 	    (flags & O_ACCMODE) == O_RDONLY)
801 		return 0;
802 
803 bad_path:
804 	log_print("m_priv_local_sanitize_path: illegal path \"%.1023s\", "
805 		  "replaced with \"/dev/null\"", path);
806 	strlcpy(path, "/dev/null", pmax);
807 	return 1;
808 }
809 
810 /* Check setsockopt */
811 static int
m_priv_check_sockopt(int level,int name)812 m_priv_check_sockopt(int level, int name)
813 {
814 	switch (level) {
815 		/* These are allowed */
816 		case SOL_SOCKET:
817 		case IPPROTO_IP:
818 		case IPPROTO_IPV6:
819 		break;
820 
821 	default:
822 		log_print("m_priv_check_sockopt: Illegal level %d", level);
823 		return 1;
824 	}
825 
826 	switch (name) {
827 		/* These are allowed */
828 	case SO_REUSEPORT:
829 	case SO_REUSEADDR:
830 	case IP_AUTH_LEVEL:
831 	case IP_ESP_TRANS_LEVEL:
832 	case IP_ESP_NETWORK_LEVEL:
833 	case IP_IPCOMP_LEVEL:
834 	case IPV6_AUTH_LEVEL:
835 	case IPV6_ESP_TRANS_LEVEL:
836 	case IPV6_ESP_NETWORK_LEVEL:
837 	case IPV6_IPCOMP_LEVEL:
838 		break;
839 
840 	default:
841 		log_print("m_priv_check_sockopt: Illegal option name %d",
842 		    name);
843 		return 1;
844 	}
845 
846 	return 0;
847 }
848 
849 /* Check bind */
850 static int
m_priv_check_bind(const struct sockaddr * sa,socklen_t salen)851 m_priv_check_bind(const struct sockaddr *sa, socklen_t salen)
852 {
853 	in_port_t       port;
854 
855 	if (sa == NULL) {
856 		log_print("NULL address");
857 		return 1;
858 	}
859 	if (SA_LEN(sa) != salen) {
860 		log_print("Length mismatch: %lu %lu", (unsigned long)sa->sa_len,
861 		    (unsigned long)salen);
862 		return 1;
863 	}
864 	switch (sa->sa_family) {
865 	case AF_INET:
866 		if (salen != sizeof(struct sockaddr_in)) {
867 			log_print("Invalid inet address length");
868 			return 1;
869 		}
870 		port = ((const struct sockaddr_in *)sa)->sin_port;
871 		break;
872 	case AF_INET6:
873 		if (salen != sizeof(struct sockaddr_in6)) {
874 			log_print("Invalid inet6 address length");
875 			return 1;
876 		}
877 		port = ((const struct sockaddr_in6 *)sa)->sin6_port;
878 		break;
879 	default:
880 		log_print("Unknown address family");
881 		return 1;
882 	}
883 
884 	port = ntohs(port);
885 
886 	if (port != ISAKMP_PORT_DEFAULT && port < 1024) {
887 		log_print("Disallowed port %u", port);
888 		return 1;
889 	}
890 	return 0;
891 }
892 
893 static void
m_priv_req_readdir()894 m_priv_req_readdir()
895 {
896 	size_t len;
897 	char path[MAXPATHLEN];
898 	DIR *dp;
899 	struct dirent *file;
900 	int off, size, fd, ret, serrno;
901 
902 	must_read(&len, sizeof len);
903 	if (len == 0 || len >= sizeof path)
904 		log_fatal("m_priv_req_readdir: invalid pathname length");
905 	must_read(path, len);
906 	path[len] = '\0';
907 	if (strlen(path) != len)
908 		log_fatal("m_priv_req_readdir: invalid pathname");
909 
910 	off = strlen(path);
911 	size = sizeof path - off;
912 
913 	if ((dp = opendir(path)) == NULL) {
914 		serrno = errno;
915 		ret = -1;
916 		must_write(&ret, sizeof ret);
917 		must_write(&serrno, sizeof serrno);
918 		return;
919 	}
920 
921 	/* report opendir() success */
922 	ret = 0;
923 	must_write(&ret, sizeof ret);
924 
925 	while ((file = readdir(dp)) != NULL) {
926 		strlcpy(path + off, file->d_name, size);
927 
928 		if (file->d_type != DT_REG && file->d_type != DT_LNK)
929 				continue;
930 
931 		if (m_priv_local_sanitize_path(path, sizeof path, O_RDONLY)
932 		    != 0) {
933 			log_errorx("m_priv_req_readdir: invalid dir entry");
934 			continue;
935 		}
936 		fd = open(path, O_RDONLY, 0);
937 		if (fd == -1) {
938 			log_error("m_priv_req_readdir: open "
939 			    "(\"%s\", O_RDONLY, 0) failed", path);
940 			continue;
941 		}
942 
943 		len = strlen(path);
944 		must_write(&len, sizeof len);
945 		must_write(path, len);
946 
947 		mm_send_fd(m_state.s, fd);
948 		close(fd);
949 	}
950 	closedir(dp);
951 
952 	len = 0;
953 	must_write(&len, sizeof len);
954 
955 	return;
956 }
957