1 /* $OpenBSD: monitor.c,v 1.83 2023/02/08 08:03:11 tb 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/types.h>
28 #include <sys/socket.h>
29 #include <sys/ioctl.h>
30 #include <sys/stat.h>
31 #include <sys/wait.h>
32 #include <netinet/in.h>
33
34 #include <dirent.h>
35 #include <errno.h>
36 #include <fcntl.h>
37 #include <pwd.h>
38 #include <signal.h>
39 #include <stdlib.h>
40 #include <string.h>
41 #include <unistd.h>
42 #include <limits.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[PATH_MAX];
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(const 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
monitor_init(int debug)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
monitor_exit(int code)147 monitor_exit(int code)
148 {
149 int status = 0, gotstatus = 0;
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 if (pid != -1)
160 gotstatus = 1;
161
162 /* Remove FIFO and pid files. */
163 unlink(ui_fifo);
164 unlink(pid_file);
165 }
166
167 close(m_state.s);
168 if (code == 0 && gotstatus)
169 exit(WIFEXITED(status)? WEXITSTATUS(status) : 1);
170 else
171 exit(code);
172 }
173
174 int
monitor_pf_key_v2_open(void)175 monitor_pf_key_v2_open(void)
176 {
177 int err, cmd;
178
179 cmd = MONITOR_PFKEY_OPEN;
180 must_write(&cmd, sizeof cmd);
181
182 must_read(&err, sizeof err);
183 if (err < 0) {
184 log_error("monitor_pf_key_v2_open: parent could not create "
185 "PF_KEY socket");
186 return -1;
187 }
188 pf_key_v2_socket = mm_receive_fd(m_state.s);
189 if (pf_key_v2_socket < 0) {
190 log_error("monitor_pf_key_v2_open: mm_receive_fd() failed");
191 return -1;
192 }
193
194 return pf_key_v2_socket;
195 }
196
197 int
monitor_open(const char * path,int flags,mode_t mode)198 monitor_open(const char *path, int flags, mode_t mode)
199 {
200 size_t len;
201 int fd, err, cmd;
202 char pathreal[PATH_MAX];
203
204 if (path[0] == '/')
205 strlcpy(pathreal, path, sizeof pathreal);
206 else
207 snprintf(pathreal, sizeof pathreal, "%s/%s", m_state.root,
208 path);
209
210 cmd = MONITOR_GET_FD;
211 must_write(&cmd, sizeof cmd);
212
213 len = strlen(pathreal);
214 must_write(&len, sizeof len);
215 must_write(&pathreal, len);
216
217 must_write(&flags, sizeof flags);
218 must_write(&mode, sizeof mode);
219
220 must_read(&err, sizeof err);
221 if (err != 0) {
222 errno = err;
223 return -1;
224 }
225
226 fd = mm_receive_fd(m_state.s);
227 if (fd < 0) {
228 log_error("monitor_open: mm_receive_fd () failed");
229 return -1;
230 }
231
232 return fd;
233 }
234
235 FILE *
monitor_fopen(const char * path,const char * mode)236 monitor_fopen(const char *path, const char *mode)
237 {
238 FILE *fp;
239 int fd, flags = 0, saved_errno;
240 mode_t mask, cur_umask;
241
242 /* Only the child process is supposed to run this. */
243 if (m_state.pid)
244 log_fatal("[priv] bad call to monitor_fopen");
245
246 switch (mode[0]) {
247 case 'r':
248 flags = (mode[1] == '+' ? O_RDWR : O_RDONLY);
249 break;
250 case 'w':
251 flags = (mode[1] == '+' ? O_RDWR : O_WRONLY) | O_CREAT |
252 O_TRUNC;
253 break;
254 case 'a':
255 flags = (mode[1] == '+' ? O_RDWR : O_WRONLY) | O_CREAT |
256 O_APPEND;
257 break;
258 default:
259 log_fatal("monitor_fopen: bad call");
260 }
261
262 cur_umask = umask(0);
263 (void)umask(cur_umask);
264 mask = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
265 mask &= ~cur_umask;
266
267 fd = monitor_open(path, flags, mask);
268 if (fd < 0)
269 return NULL;
270
271 /* Got the fd, attach a FILE * to it. */
272 fp = fdopen(fd, mode);
273 if (!fp) {
274 log_error("monitor_fopen: fdopen() failed");
275 saved_errno = errno;
276 close(fd);
277 errno = saved_errno;
278 return NULL;
279 }
280 return fp;
281 }
282
283 int
monitor_stat(const char * path,struct stat * sb)284 monitor_stat(const char *path, struct stat *sb)
285 {
286 int fd, r, saved_errno;
287
288 /* O_NONBLOCK is needed for stat'ing fifos. */
289 fd = monitor_open(path, O_RDONLY | O_NONBLOCK, 0);
290 if (fd < 0)
291 return -1;
292
293 r = fstat(fd, sb);
294 saved_errno = errno;
295 close(fd);
296 errno = saved_errno;
297 return r;
298 }
299
300 int
monitor_setsockopt(int s,int level,int optname,const void * optval,socklen_t optlen)301 monitor_setsockopt(int s, int level, int optname, const void *optval,
302 socklen_t optlen)
303 {
304 int ret, err, cmd;
305
306 cmd = MONITOR_SETSOCKOPT;
307 must_write(&cmd, sizeof cmd);
308 if (mm_send_fd(m_state.s, s)) {
309 log_print("monitor_setsockopt: read/write error");
310 return -1;
311 }
312
313 must_write(&level, sizeof level);
314 must_write(&optname, sizeof optname);
315 must_write(&optlen, sizeof optlen);
316 must_write(optval, optlen);
317
318 must_read(&err, sizeof err);
319 must_read(&ret, sizeof ret);
320 if (err != 0)
321 errno = err;
322 return ret;
323 }
324
325 int
monitor_bind(int s,const struct sockaddr * name,socklen_t namelen)326 monitor_bind(int s, const struct sockaddr *name, socklen_t namelen)
327 {
328 int ret, err, cmd;
329
330 cmd = MONITOR_BIND;
331 must_write(&cmd, sizeof cmd);
332 if (mm_send_fd(m_state.s, s)) {
333 log_print("monitor_bind: read/write error");
334 return -1;
335 }
336
337 must_write(&namelen, sizeof namelen);
338 must_write(name, namelen);
339
340 must_read(&err, sizeof err);
341 must_read(&ret, sizeof ret);
342 if (err != 0)
343 errno = err;
344 return ret;
345 }
346
347 int
monitor_req_readdir(const char * filename)348 monitor_req_readdir(const char *filename)
349 {
350 int cmd, err;
351 size_t len;
352
353 cmd = MONITOR_REQ_READDIR;
354 must_write(&cmd, sizeof cmd);
355
356 len = strlen(filename);
357 must_write(&len, sizeof len);
358 must_write(filename, len);
359
360 must_read(&err, sizeof err);
361 if (err == -1)
362 must_read(&errno, sizeof errno);
363
364 return err;
365 }
366
367 int
monitor_readdir(char * file,size_t size)368 monitor_readdir(char *file, size_t size)
369 {
370 int fd;
371 size_t len;
372
373 must_read(&len, sizeof len);
374 if (len == 0)
375 return -1;
376 if (len >= size)
377 log_fatal("monitor_readdir: received bad length from monitor");
378 must_read(file, len);
379 file[len] = '\0';
380 fd = mm_receive_fd(m_state.s);
381 return fd;
382 }
383
384 void
monitor_init_done(void)385 monitor_init_done(void)
386 {
387 int cmd;
388
389 cmd = MONITOR_INIT_DONE;
390 must_write(&cmd, sizeof cmd);
391 }
392
393 /*
394 * Start of code running with privileges (the monitor process).
395 */
396
397 static void
set_monitor_signals(void)398 set_monitor_signals(void)
399 {
400 int n;
401
402 for (n = 1; n < _NSIG; n++)
403 signal(n, SIG_DFL);
404
405 /* Forward some signals to the child. */
406 signal(SIGTERM, sig_pass_to_chld);
407 signal(SIGHUP, sig_pass_to_chld);
408 signal(SIGUSR1, sig_pass_to_chld);
409 }
410
411 static void
sig_pass_to_chld(int sig)412 sig_pass_to_chld(int sig)
413 {
414 int oerrno = errno;
415
416 if (m_state.pid > 0)
417 kill(m_state.pid, sig);
418 errno = oerrno;
419 }
420
421 /* This function is where the privileged process waits(loops) indefinitely. */
422 void
monitor_loop(int debug)423 monitor_loop(int debug)
424 {
425 int msgcode;
426
427 if (!debug)
428 log_to(0);
429
430 for (;;) {
431 must_read(&msgcode, sizeof msgcode);
432
433 switch (msgcode) {
434 case MONITOR_GET_FD:
435 m_priv_getfd();
436 break;
437
438 case MONITOR_PFKEY_OPEN:
439 LOG_DBG((LOG_MISC, 80,
440 "monitor_loop: MONITOR_PFKEY_OPEN"));
441 m_priv_pfkey_open();
442 break;
443
444 case MONITOR_SETSOCKOPT:
445 LOG_DBG((LOG_MISC, 80,
446 "monitor_loop: MONITOR_SETSOCKOPT"));
447 m_priv_setsockopt();
448 break;
449
450 case MONITOR_BIND:
451 LOG_DBG((LOG_MISC, 80,
452 "monitor_loop: MONITOR_BIND"));
453 m_priv_bind();
454 break;
455
456 case MONITOR_REQ_READDIR:
457 LOG_DBG((LOG_MISC, 80,
458 "monitor_loop: MONITOR_REQ_READDIR"));
459 m_priv_req_readdir();
460 break;
461
462 case MONITOR_INIT_DONE:
463 LOG_DBG((LOG_MISC, 80,
464 "monitor_loop: MONITOR_INIT_DONE"));
465 break;
466
467 case MONITOR_SHUTDOWN:
468 LOG_DBG((LOG_MISC, 80,
469 "monitor_loop: MONITOR_SHUTDOWN"));
470 break;
471
472 default:
473 log_print("monitor_loop: got unknown code %d",
474 msgcode);
475 }
476 }
477
478 exit(0);
479 }
480
481
482 /* Privileged: called by monitor_loop. */
483 static void
m_priv_pfkey_open(void)484 m_priv_pfkey_open(void)
485 {
486 int fd, err = 0;
487
488 fd = pf_key_v2_open();
489 if (fd < 0)
490 err = -1;
491
492 must_write(&err, sizeof err);
493
494 if (fd > 0 && mm_send_fd(m_state.s, fd)) {
495 log_error("m_priv_pfkey_open: read/write operation failed");
496 close(fd);
497 return;
498 }
499 close(fd);
500 }
501
502 /* Privileged: called by monitor_loop. */
503 static void
m_priv_getfd(void)504 m_priv_getfd(void)
505 {
506 char path[PATH_MAX];
507 size_t len;
508 int v, flags, ret;
509 int err = 0;
510 mode_t mode;
511
512 must_read(&len, sizeof len);
513 if (len == 0 || len >= sizeof path)
514 log_fatal("m_priv_getfd: invalid pathname length");
515
516 must_read(path, len);
517 path[len] = '\0';
518 if (strlen(path) != len)
519 log_fatal("m_priv_getfd: invalid pathname");
520
521 must_read(&flags, sizeof flags);
522 must_read(&mode, sizeof mode);
523
524 if ((ret = m_priv_local_sanitize_path(path, sizeof path, flags))
525 != 0) {
526 if (errno != ENOENT)
527 log_print("m_priv_getfd: illegal path \"%s\"", path);
528 err = errno;
529 v = -1;
530 } else {
531 if ((v = open(path, flags, mode)) == -1)
532 err = errno;
533 }
534
535 must_write(&err, sizeof err);
536
537 if (v != -1) {
538 if (mm_send_fd(m_state.s, v) == -1)
539 log_error("m_priv_getfd: sending fd failed");
540 close(v);
541 }
542 }
543
544 /* Privileged: called by monitor_loop. */
545 static void
m_priv_setsockopt(void)546 m_priv_setsockopt(void)
547 {
548 int sock, level, optname, v;
549 int err = 0;
550 char *optval = 0;
551 socklen_t optlen;
552
553 sock = mm_receive_fd(m_state.s);
554 if (sock < 0) {
555 log_print("m_priv_setsockopt: read/write error");
556 return;
557 }
558
559 must_read(&level, sizeof level);
560 must_read(&optname, sizeof optname);
561 must_read(&optlen, sizeof optlen);
562
563 optval = malloc(optlen);
564 if (!optval) {
565 log_print("m_priv_setsockopt: malloc failed");
566 close(sock);
567 return;
568 }
569
570 must_read(optval, optlen);
571
572 if (m_priv_check_sockopt(level, optname) != 0) {
573 err = EACCES;
574 v = -1;
575 } else {
576 v = setsockopt(sock, level, optname, optval, optlen);
577 if (v < 0)
578 err = errno;
579 }
580
581 close(sock);
582 sock = -1;
583
584 must_write(&err, sizeof err);
585 must_write(&v, sizeof v);
586
587 free(optval);
588 return;
589 }
590
591 /* Privileged: called by monitor_loop. */
592 static void
m_priv_bind(void)593 m_priv_bind(void)
594 {
595 int sock, v, err = 0;
596 struct sockaddr *name = 0;
597 socklen_t namelen;
598
599 sock = mm_receive_fd(m_state.s);
600 if (sock < 0) {
601 log_print("m_priv_bind: read/write error");
602 return;
603 }
604
605 must_read(&namelen, sizeof namelen);
606 name = malloc(namelen);
607 if (!name) {
608 log_print("m_priv_bind: malloc failed");
609 close(sock);
610 return;
611 }
612 must_read((char *)name, namelen);
613
614 if (m_priv_check_bind(name, namelen) != 0) {
615 err = EACCES;
616 v = -1;
617 } else {
618 v = bind(sock, name, namelen);
619 if (v == -1) {
620 log_error("m_priv_bind: bind(%d,%p,%d) returned %d",
621 sock, name, namelen, v);
622 err = errno;
623 }
624 }
625
626 close(sock);
627 sock = -1;
628
629 must_write(&err, sizeof err);
630 must_write(&v, sizeof v);
631
632 free(name);
633 return;
634 }
635
636 /*
637 * Help functions, used by both privileged and unprivileged code
638 */
639
640 /*
641 * Read data with the assertion that it all must come through, or else abort
642 * the process. Based on atomicio() from openssh.
643 */
644 static void
must_read(void * buf,size_t n)645 must_read(void *buf, size_t n)
646 {
647 char *s = buf;
648 size_t pos = 0;
649 ssize_t res;
650
651 while (n > pos) {
652 res = read(m_state.s, s + pos, n - pos);
653 switch (res) {
654 case -1:
655 if (errno == EINTR || errno == EAGAIN)
656 continue;
657 case 0:
658 monitor_exit(0);
659 default:
660 pos += res;
661 }
662 }
663 }
664
665 /*
666 * Write data with the assertion that it all has to be written, or else abort
667 * the process. Based on atomicio() from openssh.
668 */
669 static void
must_write(const void * buf,size_t n)670 must_write(const void *buf, size_t n)
671 {
672 const char *s = buf;
673 size_t pos = 0;
674 ssize_t res;
675
676 while (n > pos) {
677 res = write(m_state.s, s + pos, n - pos);
678 switch (res) {
679 case -1:
680 if (errno == EINTR || errno == EAGAIN)
681 continue;
682 case 0:
683 monitor_exit(0);
684 default:
685 pos += res;
686 }
687 }
688 }
689
690 /* Check that path/mode is permitted. */
691 static int
m_priv_local_sanitize_path(const char * path,size_t pmax,int flags)692 m_priv_local_sanitize_path(const char *path, size_t pmax, int flags)
693 {
694 char new_path[PATH_MAX], var_run[PATH_MAX], *enddir;
695
696 /*
697 * We only permit paths starting with
698 * /etc/isakmpd/ (read only)
699 * /var/run/ (rw)
700 */
701
702 if (realpath(path, new_path) == NULL) {
703 if (errno != ENOENT)
704 return 1;
705 /*
706 * It is ok if the directory exists,
707 * but the file should be created.
708 */
709 if (strlcpy(new_path, path, sizeof(new_path)) >=
710 sizeof(new_path))
711 return 1;
712 enddir = strrchr(new_path, '/');
713 if (enddir == NULL || enddir[1] == '\0')
714 return 1;
715 enddir[1] = '\0';
716 if (realpath(new_path, new_path) == NULL) {
717 errno = ENOENT;
718 return 1;
719 }
720 enddir = strrchr(path, '/');
721 strlcat(new_path, enddir, sizeof(new_path));
722 }
723
724 if (realpath("/var/run/", var_run) == NULL)
725 return 1;
726 strlcat(var_run, "/", sizeof(var_run));
727
728 if (strncmp(var_run, new_path, strlen(var_run)) == 0)
729 return 0;
730
731 if (strncmp(ISAKMPD_ROOT, new_path, strlen(ISAKMPD_ROOT)) == 0 &&
732 (flags & O_ACCMODE) == O_RDONLY)
733 return 0;
734
735 errno = EACCES;
736 return 1;
737 }
738
739 /* Check setsockopt */
740 static int
m_priv_check_sockopt(int level,int name)741 m_priv_check_sockopt(int level, int name)
742 {
743 switch (level) {
744 /* These are allowed */
745 case SOL_SOCKET:
746 case IPPROTO_IP:
747 case IPPROTO_IPV6:
748 break;
749
750 default:
751 log_print("m_priv_check_sockopt: Illegal level %d", level);
752 return 1;
753 }
754
755 switch (name) {
756 /* These are allowed */
757 case SO_REUSEPORT:
758 case SO_REUSEADDR:
759 case IP_AUTH_LEVEL:
760 case IP_ESP_TRANS_LEVEL:
761 case IP_ESP_NETWORK_LEVEL:
762 case IP_IPCOMP_LEVEL:
763 case IPV6_AUTH_LEVEL:
764 case IPV6_ESP_TRANS_LEVEL:
765 case IPV6_ESP_NETWORK_LEVEL:
766 case IPV6_IPCOMP_LEVEL:
767 break;
768
769 default:
770 log_print("m_priv_check_sockopt: Illegal option name %d",
771 name);
772 return 1;
773 }
774
775 return 0;
776 }
777
778 /* Check bind */
779 static int
m_priv_check_bind(const struct sockaddr * sa,socklen_t salen)780 m_priv_check_bind(const struct sockaddr *sa, socklen_t salen)
781 {
782 in_port_t port;
783
784 if (sa == NULL) {
785 log_print("NULL address");
786 return 1;
787 }
788 if (SA_LEN(sa) != salen) {
789 log_print("Length mismatch: %lu %lu", (unsigned long)sa->sa_len,
790 (unsigned long)salen);
791 return 1;
792 }
793 switch (sa->sa_family) {
794 case AF_INET:
795 if (salen != sizeof(struct sockaddr_in)) {
796 log_print("Invalid inet address length");
797 return 1;
798 }
799 port = ((const struct sockaddr_in *)sa)->sin_port;
800 break;
801 case AF_INET6:
802 if (salen != sizeof(struct sockaddr_in6)) {
803 log_print("Invalid inet6 address length");
804 return 1;
805 }
806 port = ((const struct sockaddr_in6 *)sa)->sin6_port;
807 break;
808 default:
809 log_print("Unknown address family");
810 return 1;
811 }
812
813 port = ntohs(port);
814
815 if (port != ISAKMP_PORT_DEFAULT && port < 1024) {
816 log_print("Disallowed port %u", port);
817 return 1;
818 }
819 return 0;
820 }
821
822 static void
m_priv_req_readdir(void)823 m_priv_req_readdir(void)
824 {
825 size_t len;
826 char path[PATH_MAX];
827 DIR *dp;
828 struct dirent *file;
829 struct stat sb;
830 int off, size, fd, ret, serrno;
831
832 must_read(&len, sizeof len);
833 if (len == 0 || len >= sizeof path)
834 log_fatal("m_priv_req_readdir: invalid pathname length");
835 must_read(path, len);
836 path[len] = '\0';
837 if (strlen(path) != len)
838 log_fatal("m_priv_req_readdir: invalid pathname");
839
840 off = strlen(path);
841 size = sizeof path - off;
842
843 if ((dp = opendir(path)) == NULL) {
844 serrno = errno;
845 ret = -1;
846 must_write(&ret, sizeof ret);
847 must_write(&serrno, sizeof serrno);
848 return;
849 }
850
851 /* report opendir() success */
852 ret = 0;
853 must_write(&ret, sizeof ret);
854
855 while ((file = readdir(dp)) != NULL) {
856 strlcpy(path + off, file->d_name, size);
857
858 if (m_priv_local_sanitize_path(path, sizeof path, O_RDONLY)
859 != 0)
860 continue;
861 fd = open(path, O_RDONLY);
862 if (fd == -1) {
863 log_error("m_priv_req_readdir: open "
864 "(\"%s\", O_RDONLY, 0) failed", path);
865 continue;
866 }
867 if ((fstat(fd, &sb) == -1) ||
868 !(S_ISREG(sb.st_mode) || S_ISLNK(sb.st_mode))) {
869 close(fd);
870 continue;
871 }
872
873 len = strlen(path);
874 must_write(&len, sizeof len);
875 must_write(path, len);
876
877 mm_send_fd(m_state.s, fd);
878 close(fd);
879 }
880 closedir(dp);
881
882 len = 0;
883 must_write(&len, sizeof len);
884 }
885