GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: sbin/isakmpd/monitor.c Lines: 0 385 0.0 %
Date: 2017-11-07 Branches: 0 192 0.0 %

Line Branch Exec Source
1
/* $OpenBSD: monitor.c,v 1.74 2015/08/20 22:02:21 deraadt 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(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[PATH_MAX];
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[PATH_MAX];
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 = 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 = 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[PATH_MAX];
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
}