1c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh/*	$NetBSD: privsep.c,v 1.6 2006/09/09 16:22:10 manu Exp $	*/
20a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* Id: privsep.c,v 1.15 2005/08/08 11:23:44 vanhu Exp */
40a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
50a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
60a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * Copyright (C) 2004 Emmanuel Dreyfus
70a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * All rights reserved.
80a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *
90a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * Redistribution and use in source and binary forms, with or without
100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * modification, are permitted provided that the following conditions
110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * are met:
120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * 1. Redistributions of source code must retain the above copyright
130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *    notice, this list of conditions and the following disclaimer.
140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * 2. Redistributions in binary form must reproduce the above copyright
150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *    notice, this list of conditions and the following disclaimer in the
160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *    documentation and/or other materials provided with the distribution.
170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * 3. Neither the name of the project nor the names of its contributors
180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *    may be used to endorse or promote products derived from this software
190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *    without specific prior written permission.
200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *
210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * SUCH DAMAGE.
320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "config.h"
350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <unistd.h>
370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <string.h>
380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef __NetBSD__
390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <stdlib.h>	/* for setproctitle */
400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <errno.h>
420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <signal.h>
430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <pwd.h>
440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <sys/socket.h>
460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <sys/param.h>
470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "gcmalloc.h"
490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "vmbuf.h"
500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "misc.h"
510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "plog.h"
520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "var.h"
53c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#include "libpfkey.h"
540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "crypto_openssl.h"
560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "isakmp_var.h"
570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "isakmp.h"
580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_HYBRID
590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "resolv.h"
600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "isakmp_xauth.h"
610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "isakmp_cfg.h"
620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "localconf.h"
640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "remoteconf.h"
650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "admin.h"
660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "sockmisc.h"
670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "privsep.h"
680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int privsep_sock[2] = { -1, -1 };
700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int privsep_recv(int, struct privsep_com_msg **, size_t *);
720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int privsep_send(int, struct privsep_com_msg *, size_t);
730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int safety_check(struct privsep_com_msg *, int i);
740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int port_check(int);
750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int unsafe_env(char *const *);
760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int unknown_name(int);
770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int unsafe_path(char *, int);
780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangprivsep_send(sock, buf, len)
810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int sock;
820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct privsep_com_msg *buf;
830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	size_t len;
840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (buf == NULL)
860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 0;
870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (sendto(sock, (char *)buf, len, 0, NULL, 0) == -1) {
890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    "privsep_send failed: %s\n",
910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    strerror(errno));
920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	racoon_free((char *)buf);
960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
1020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangprivsep_recv(sock, bufp, lenp)
1030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int sock;
1040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct privsep_com_msg **bufp;
1050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	size_t *lenp;
1060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
1070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct admin_com com;
1080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct admin_com *combuf;
1090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	size_t len;
1100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	*bufp = NULL;
1120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	*lenp = 0;
1130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* Get the header */
1150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	while ((len = recvfrom(sock, (char *)&com,
1160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    sizeof(com), MSG_PEEK, NULL, NULL)) == -1) {
1170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (errno == EINTR)
1180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			continue;
1190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
1210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    "privsep_recv failed: %s\n",
1220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    strerror(errno));
1230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
1240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
125c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
1260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* Check for short packets */
1270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (len < sizeof(com)) {
1280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
1290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    "corrupted privsep message (short header)\n");
1300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
1310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
1320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* Allocate buffer for the whole message */
1340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((combuf = (struct admin_com *)racoon_malloc(com.ac_len)) == NULL) {
1350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
1360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    "failed to allocate memory: %s\n", strerror(errno));
1370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
1380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
1390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* Get the whole buffer */
1410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	while ((len = recvfrom(sock, (char *)combuf,
1420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    com.ac_len, 0, NULL, NULL)) == -1) {
1430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (errno == EINTR)
1440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			continue;
1450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
1460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    "failed to recv privsep command: %s\n",
1470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    strerror(errno));
1480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
1490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
1500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* We expect len to match */
1520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (len != com.ac_len) {
1530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
1540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    "corrupted privsep message (short packet)\n");
1550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
1560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
1570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	*bufp = (struct privsep_com_msg *)combuf;
1590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	*lenp = len;
1600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
1620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
1630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
1650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangprivsep_init(void)
1660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
1670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int i;
1680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	pid_t child_pid;
1690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* If running as root, we don't use the privsep code path */
1710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (lcconf->uid == 0)
1720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 0;
1730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/*
1750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * When running privsep, certificate and script paths
1760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * are mandatory, as they enable us to check path safety
177c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	 * in the privilegied instance
1780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 */
1790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((lcconf->pathinfo[LC_PATHTYPE_CERT] == NULL) ||
1800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    (lcconf->pathinfo[LC_PATHTYPE_SCRIPT] == NULL)) {
1810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL, "privilege separation "
1820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		   "require path cert and path script in the config file\n");
1830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
1840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
1850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
186c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	if (socketpair(PF_LOCAL, SOCK_DGRAM, 0, privsep_sock) != 0) {
1870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
1880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    "Cannot allocate privsep_sock: %s\n", strerror(errno));
1890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
1900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
1910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch (child_pid = fork()) {
1930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case -1:
1940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL, "Cannot fork privsep: %s\n",
1950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    strerror(errno));
1960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
1970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
1980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case 0: /* Child: drop privileges */
2000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (lcconf->chroot != NULL) {
2010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (chdir(lcconf->chroot) != 0) {
2020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
2030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				    "Cannot chdir(%s): %s\n", lcconf->chroot,
2040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				    strerror(errno));
2050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				return -1;
2060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
2070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (chroot(lcconf->chroot) != 0) {
2080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
2090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				    "Cannot chroot(%s): %s\n", lcconf->chroot,
2100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				    strerror(errno));
2110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				return -1;
2120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
2130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
2140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (setgid(lcconf->gid) != 0) {
2160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
2170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    "Cannot setgid(%d): %s\n", lcconf->gid,
2180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    strerror(errno));
2190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
2200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
2210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (setegid(lcconf->gid) != 0) {
2230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
2240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    "Cannot setegid(%d): %s\n", lcconf->gid,
2250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    strerror(errno));
2260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
2270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
2280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (setuid(lcconf->uid) != 0) {
2300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
2310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    "Cannot setuid(%d): %s\n", lcconf->uid,
2320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    strerror(errno));
2330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
2340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
2350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (seteuid(lcconf->uid) != 0) {
2370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
2380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    "Cannot seteuid(%d): %s\n", lcconf->uid,
2390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    strerror(errno));
2400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
2410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
2420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 0;
2440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
2450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
246c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	default: /* Parent: privilegied process */
2470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
2480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
2490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/*
2510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * Close everything except the socketpair,
2520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * and stdout if running in the forground.
2530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 */
2540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (i = sysconf(_SC_OPEN_MAX); i > 0; i--) {
2550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (i == privsep_sock[0])
2560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			continue;
257c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		if (i == privsep_sock[1])
258c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			continue;
2590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if ((f_foreground) && (i == 1))
2600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			continue;
2610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		(void)close(i);
2620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
2630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* Above trickery closed the log file, reopen it */
2650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	ploginit();
2660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_INFO, LOCATION, NULL,
268c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	    "racoon privilegied process running with PID %d\n", getpid());
269f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh
270c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#ifdef __NetBSD__
2710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	setproctitle("[priv]");
2720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
2730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
274c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	/*
275c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	 * Don't catch any signal
2760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * This duplicate session:signals[], which is static...
2770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 */
2780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	signal(SIGHUP, SIG_DFL);
2790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	signal(SIGINT, SIG_DFL);
2800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	signal(SIGTERM, SIG_DFL);
2810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	signal(SIGUSR1, SIG_DFL);
2820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	signal(SIGUSR2, SIG_DFL);
2830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	signal(SIGCHLD, SIG_DFL);
2840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	while (1) {
2860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		size_t len;
2870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		struct privsep_com_msg *combuf;
2880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		struct privsep_com_msg *reply;
2890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		char *data;
2900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		size_t *buflen;
2910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		size_t totallen;
2920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		char *bufs[PRIVSEP_NBUF_MAX];
2930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		int i;
2940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (privsep_recv(privsep_sock[0], &combuf, &len) != 0)
2960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto out;
2970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* Safety checks and gather the data */
2990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (len < sizeof(*combuf)) {
3000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
3010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    "corrupted privsep message (short buflen)\n");
3020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto out;
3030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
3040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		data = (char *)(combuf + 1);
3060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		totallen = sizeof(*combuf);
3070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		for (i = 0; i < PRIVSEP_NBUF_MAX; i++) {
3080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			bufs[i] = (char *)data;
3090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			data += combuf->bufs.buflen[i];
3100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			totallen += combuf->bufs.buflen[i];
3110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
3120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (totallen > len) {
3140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
3150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    "corrupted privsep message (bufs too big)\n");
3160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto out;
3170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
3180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* Prepare the reply buffer */
3200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if ((reply = racoon_malloc(sizeof(*reply))) == NULL) {
3210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
3220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    "Cannot allocate reply buffer: %s\n",
3230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    strerror(errno));
3240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto out;
3250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
3260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		bzero(reply, sizeof(*reply));
3270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		reply->hdr.ac_cmd = combuf->hdr.ac_cmd;
3280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		reply->hdr.ac_len = sizeof(*reply);
3290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		switch(combuf->hdr.ac_cmd) {
3310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/*
3320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * XXX Improvement: instead of returning the key,
3330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * stuff eay_get_pkcs1privkey and eay_get_x509sign
334c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		 * together and sign the hash in the privilegied
3350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * instance?
3360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * pro: the key remains inaccessible to unpriv
3370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * con: a compromised unpriv racoon can still sign anything
3380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 */
3390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case PRIVSEP_EAY_GET_PKCS1PRIVKEY: {
3400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			vchar_t *privkey;
3410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* Make sure the string is NULL terminated */
3430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (safety_check(combuf, 0) != 0)
3440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
3450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			bufs[0][combuf->bufs.buflen[0] - 1] = '\0';
3460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (unsafe_path(bufs[0], LC_PATHTYPE_CERT) != 0) {
3480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
3490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				    "privsep_eay_get_pkcs1privkey: "
3500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				    "unsafe cert \"%s\"\n", bufs[0]);
3510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
3520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_DEBUG, LOCATION, NULL,
3540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    "eay_get_pkcs1privkey(\"%s\")\n", bufs[0]);
3550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if ((privkey = eay_get_pkcs1privkey(bufs[0])) == NULL){
3570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				reply->hdr.ac_errno = errno;
3580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
3590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
3600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			reply->bufs.buflen[0] = privkey->l;
3620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			reply->hdr.ac_len = sizeof(*reply) + privkey->l;
3630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			reply = racoon_realloc(reply, reply->hdr.ac_len);
3640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (reply == NULL) {
3650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
3660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				    "Cannot allocate reply buffer: %s\n",
3670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				    strerror(errno));
3680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				goto out;
3690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
3700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			memcpy(reply + 1, privkey->v, privkey->l);
3720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			vfree(privkey);
3730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
3740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
3750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case PRIVSEP_SCRIPT_EXEC: {
3770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			char *script;
3780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			int name;
3790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			char **envp = NULL;
3800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			int envc = 0;
3810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			int count = 0;
3820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			int i;
3830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/*
3850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 * First count the bufs, and make sure strings
3860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 * are NULL terminated.
3870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 *
3880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 * We expect: script, name, envp[], void
3890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 */
3900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (safety_check(combuf, 0) != 0)
3910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
3920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			bufs[0][combuf->bufs.buflen[0] - 1] = '\0';
3930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			count++;	/* script */
3940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			count++;	/* name */
3960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			for (; count < PRIVSEP_NBUF_MAX; count++) {
3980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				if (combuf->bufs.buflen[count] == 0)
3990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					break;
4000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				bufs[count]
4010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				    [combuf->bufs.buflen[count] - 1] = '\0';
4020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				envc++;
4030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
4040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* count a void buf and perform safety check */
4060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			count++;
4070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (count >= PRIVSEP_NBUF_MAX) {
4080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
4090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				    "privsep_script_exec: too many args\n");
4100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				goto out;
4110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
4120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/*
4150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 * Allocate the arrays for envp
4160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 */
4170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			envp = racoon_malloc((envc + 1) * sizeof(char *));
4180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (envp == NULL) {
4190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
4200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				    "cannot allocate memory: %s\n",
4210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				    strerror(errno));
4220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				goto out;
4230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
4240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			bzero(envp, (envc + 1) * sizeof(char *));
4250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/*
4280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 * Populate script, name and envp
4290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 */
4300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			count = 0;
4310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			script = bufs[count++];
4320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (combuf->bufs.buflen[count] != sizeof(name)) {
4340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
4350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				    "privsep_script_exec: corrupted message\n");
4360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				goto out;
4370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
4380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			memcpy((char *)&name, bufs[count++], sizeof(name));
4390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			for (i = 0; combuf->bufs.buflen[count]; count++)
4410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				envp[i++] = bufs[count];
4420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			count++;		/* void */
4440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_DEBUG, LOCATION, NULL,
4460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    "script_exec(\"%s\", %d, %p)\n",
4470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    script, name, envp);
4480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/*
4500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 * Check env for dangerous variables
4510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 * Check script path and name
4520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 * Perform fork and execve
4530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 */
4540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if ((unsafe_env(envp) == 0) &&
4550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    (unknown_name(name) == 0) &&
4560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    (unsafe_path(script, LC_PATHTYPE_SCRIPT) == 0))
4570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				(void)script_exec(script, name, envp);
4580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			else
4590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
4600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				    "privsep_script_exec: "
4610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				    "unsafe script \"%s\"\n", script);
4620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			racoon_free(envp);
4640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
4650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
4660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case PRIVSEP_GETPSK: {
4680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			vchar_t *psk;
4690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			int keylen;
4700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* Make sure the string is NULL terminated */
4720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (safety_check(combuf, 0) != 0)
4730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
4740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			bufs[0][combuf->bufs.buflen[0] - 1] = '\0';
4750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (combuf->bufs.buflen[1] != sizeof(keylen)) {
4770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
4780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				    "privsep_getpsk: corrupted message\n");
4790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				goto out;
4800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
4810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			memcpy(&keylen, bufs[1], sizeof(keylen));
4820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_DEBUG, LOCATION, NULL,
4840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    "getpsk(\"%s\", %d)\n", bufs[0], keylen);
4850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if ((psk = getpsk(bufs[0], keylen)) == NULL) {
4870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				reply->hdr.ac_errno = errno;
4880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
4890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
4900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			reply->bufs.buflen[0] = psk->l;
4920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			reply->hdr.ac_len = sizeof(*reply) + psk->l;
4930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			reply = racoon_realloc(reply, reply->hdr.ac_len);
4940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (reply == NULL) {
4950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
4960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				    "Cannot allocate reply buffer: %s\n",
4970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				    strerror(errno));
4980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				goto out;
4990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
5000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			memcpy(reply + 1, psk->v, psk->l);
5020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			vfree(psk);
5030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
5040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
5050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_HYBRID
5070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case PRIVSEP_ACCOUNTING_SYSTEM: {
5080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			int pool_size;
5090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			int port;
5100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			int inout;
5110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			struct sockaddr *raddr;
5120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (safety_check(combuf, 0) != 0)
5140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
5150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (safety_check(combuf, 1) != 0)
5160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
5170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (safety_check(combuf, 2) != 0)
5180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
5190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (safety_check(combuf, 3) != 0)
5200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
5210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			memcpy(&port, bufs[0], sizeof(port));
5230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			raddr = (struct sockaddr *)bufs[1];
5240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			bufs[2][combuf->bufs.buflen[2] - 1] = '\0';
5260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			memcpy(&inout, bufs[3], sizeof(port));
5270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (port_check(port) != 0)
5290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
5300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_DEBUG, LOCATION, NULL,
5320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    "accounting_system(%d, %s, %s)\n",
5330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    port, saddr2str(raddr), bufs[2]);
5340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			errno = 0;
5360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (isakmp_cfg_accounting_system(port,
5370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    raddr, bufs[2], inout) != 0) {
5380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				if (errno == 0)
5390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					reply->hdr.ac_errno = EINVAL;
5400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				else
5410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					reply->hdr.ac_errno = errno;
5420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
5430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
5440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
5450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case PRIVSEP_XAUTH_LOGIN_SYSTEM: {
5460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (safety_check(combuf, 0) != 0)
5470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
5480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			bufs[0][combuf->bufs.buflen[0] - 1] = '\0';
5490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (safety_check(combuf, 1) != 0)
5510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
5520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			bufs[1][combuf->bufs.buflen[1] - 1] = '\0';
5530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_DEBUG, LOCATION, NULL,
5550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    "xauth_login_system(\"%s\", <password>)\n",
5560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    bufs[0]);
5570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			errno = 0;
5590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (xauth_login_system(bufs[0], bufs[1]) != 0) {
5600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				if (errno == 0)
5610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					reply->hdr.ac_errno = EINVAL;
5620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				else
5630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					reply->hdr.ac_errno = errno;
5640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
5650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
5660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
5670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_LIBPAM
5680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case PRIVSEP_ACCOUNTING_PAM: {
5690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			int port;
5700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			int inout;
5710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			int pool_size;
5720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (safety_check(combuf, 0) != 0)
5740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
5750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (safety_check(combuf, 1) != 0)
5760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
5770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (safety_check(combuf, 2) != 0)
5780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
5790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			memcpy(&port, bufs[0], sizeof(port));
5810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			memcpy(&inout, bufs[1], sizeof(inout));
5820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			memcpy(&pool_size, bufs[2], sizeof(pool_size));
5830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (pool_size != isakmp_cfg_config.pool_size)
5850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				if (isakmp_cfg_resize_pool(pool_size) != 0)
5860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					break;
5870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (port_check(port) != 0)
5890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
5900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_DEBUG, LOCATION, NULL,
5920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    "isakmp_cfg_accounting_pam(%d, %d)\n",
5930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    port, inout);
5940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			errno = 0;
5960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (isakmp_cfg_accounting_pam(port, inout) != 0) {
5970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				if (errno == 0)
5980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					reply->hdr.ac_errno = EINVAL;
5990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				else
6000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					reply->hdr.ac_errno = errno;
6010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
6020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
6030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
6040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case PRIVSEP_XAUTH_LOGIN_PAM: {
6060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			int port;
6070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			int pool_size;
6080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			struct sockaddr *raddr;
6090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (safety_check(combuf, 0) != 0)
6110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
6120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (safety_check(combuf, 1) != 0)
6130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
6140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (safety_check(combuf, 2) != 0)
6150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
6160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (safety_check(combuf, 3) != 0)
6170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
6180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (safety_check(combuf, 4) != 0)
6190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
6200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			memcpy(&port, bufs[0], sizeof(port));
6220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			memcpy(&pool_size, bufs[1], sizeof(pool_size));
6230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			raddr = (struct sockaddr *)bufs[2];
6240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			bufs[3][combuf->bufs.buflen[3] - 1] = '\0';
6260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			bufs[4][combuf->bufs.buflen[4] - 1] = '\0';
6270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (pool_size != isakmp_cfg_config.pool_size)
6290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				if (isakmp_cfg_resize_pool(pool_size) != 0)
6300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					break;
6310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (port_check(port) != 0)
6330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
6340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_DEBUG, LOCATION, NULL,
6360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    "xauth_login_pam(%d, %s, \"%s\", <password>)\n",
6370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    port, saddr2str(raddr), bufs[3]);
6380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			errno = 0;
6400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (xauth_login_pam(port,
6410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    raddr, bufs[3], bufs[4]) != 0) {
6420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				if (errno == 0)
6430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					reply->hdr.ac_errno = EINVAL;
6440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				else
6450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					reply->hdr.ac_errno = errno;
6460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
6470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
6480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
6490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case PRIVSEP_CLEANUP_PAM: {
6510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			int port;
6520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			int pool_size;
6530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (safety_check(combuf, 0) != 0)
6550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
6560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (safety_check(combuf, 1) != 0)
6570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
6580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			memcpy(&port, bufs[0], sizeof(port));
6600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			memcpy(&pool_size, bufs[1], sizeof(pool_size));
6610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (pool_size != isakmp_cfg_config.pool_size)
6630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				if (isakmp_cfg_resize_pool(pool_size) != 0)
6640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					break;
6650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (port_check(port) != 0)
6670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
6680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_DEBUG, LOCATION, NULL,
6700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    "cleanup_pam(%d)\n", port);
6710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			cleanup_pam(port);
6730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			reply->hdr.ac_errno = 0;
6740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
6760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
6770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif /* HAVE_LIBPAM */
6780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif /* ENABLE_HYBRID */
6790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		default:
6810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
6820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    "unexpected privsep command %d\n",
6830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    combuf->hdr.ac_cmd);
6840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto out;
6850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
6860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
6870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* This frees reply */
6890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (privsep_send(privsep_sock[0],
690c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		    reply, reply->hdr.ac_len) != 0)
6910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto out;
6920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		racoon_free(combuf);
6940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
6950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangout:
697c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	plog(LLV_INFO, LOCATION, NULL, "privsep exit\n");
6980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	_exit(0);
6990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
7000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
7030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangprivsep_eay_get_pkcs1privkey(path)
7040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *path;
7050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
7060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *privkey;
7070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct privsep_com_msg *msg;
7080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	size_t len;
7090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (geteuid() == 0)
7110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return eay_get_pkcs1privkey(path);
7120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	len = sizeof(*msg) + strlen(path) + 1;
7140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((msg = racoon_malloc(len)) == NULL) {
7150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
7160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    "Cannot allocate memory: %s\n", strerror(errno));
7170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
7180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
7190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	bzero(msg, len);
7200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	msg->hdr.ac_cmd = PRIVSEP_EAY_GET_PKCS1PRIVKEY;
7210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	msg->hdr.ac_len = len;
7220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	msg->bufs.buflen[0] = len - sizeof(*msg);
7230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memcpy(msg + 1, path, msg->bufs.buflen[0]);
7240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (privsep_send(privsep_sock[1], msg, len) != 0)
7260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
7270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (privsep_recv(privsep_sock[1], &msg, &len) != 0)
7290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
7300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (msg->hdr.ac_errno != 0) {
7320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		errno = msg->hdr.ac_errno;
7330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto out;
7340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
7350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((privkey = vmalloc(len - sizeof(*msg))) == NULL)
7370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto out;
7380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memcpy(privkey->v, msg + 1, privkey->l);
7400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	racoon_free(msg);
7410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return privkey;
7420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangout:
7440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	racoon_free(msg);
7450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return NULL;
7460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
7470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
748c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh/*
749c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh * No prigilege separation trick here, we just open PFKEY before
750c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh * dropping root privs and we remember it later.
751c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh */
752c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehstatic int  pfkey_socket = -1;
753c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehint
754c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehprivsep_pfkey_open(void)
755c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh{
756c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	int ps;
757c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
758c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	if (pfkey_socket != -1)
759c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		return pfkey_socket;
760c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
761c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	ps = pfkey_open();
762c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	if (ps != -1)
763c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		pfkey_socket = ps;
764c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
765c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	return ps;
766c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh}
767c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
768c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh/*
769c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh * Consequence of the above trickery: don't
770c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh * really close PFKEY as we never re-open it.
771c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh */
772c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehvoid
773c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehprivsep_pfkey_close(ps)
774c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	int ps;
775c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh{
776c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	return;
777c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh}
778c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
7790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
7800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangprivsep_script_exec(script, name, envp)
7810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *script;
7820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int name;
7830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *const envp[];
7840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
7850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int count = 0;
7860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *const *c;
7870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *data;
7880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	size_t len;
7890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct privsep_com_msg *msg;
7900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (geteuid() == 0)
7920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return script_exec(script, name, envp);
7930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((msg = racoon_malloc(sizeof(*msg))) == NULL) {
7950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
7960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    "Cannot allocate memory: %s\n", strerror(errno));
7970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
7980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
7990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	bzero(msg, sizeof(*msg));
8010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	msg->hdr.ac_cmd = PRIVSEP_SCRIPT_EXEC;
8020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	msg->hdr.ac_len = sizeof(*msg);
8030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/*
8050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * We send:
8060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * script, name, envp[0], ... envp[N], void
8070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 */
8080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/*
8100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * Safety check on the counts: PRIVSEP_NBUF_MAX max
8110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 */
8120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	count = 0;
8130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	count++;					/* script */
8140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	count++;					/* name */
8150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (c = envp; *c; c++)				/* envp */
8160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		count++;
8170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	count++;					/* void */
8180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (count > PRIVSEP_NBUF_MAX) {
8200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL, "Unexpected error: "
8210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    "privsep_script_exec count > PRIVSEP_NBUF_MAX\n");
8220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		racoon_free(msg);
8230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
8240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
8250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/*
8280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * Compute the length
8290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 */
8300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	count = 0;
8310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	msg->bufs.buflen[count] = strlen(script) + 1;	/* script */
8320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	msg->hdr.ac_len += msg->bufs.buflen[count++];
8330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	msg->bufs.buflen[count] = sizeof(name);		/* name */
8350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	msg->hdr.ac_len += msg->bufs.buflen[count++];
8360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (c = envp; *c; c++) {			/* envp */
8380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		msg->bufs.buflen[count] = strlen(*c) + 1;
8390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		msg->hdr.ac_len += msg->bufs.buflen[count++];
8400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
8410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	msg->bufs.buflen[count] = 0; 			/* void */
8430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	msg->hdr.ac_len += msg->bufs.buflen[count++];
8440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((msg = racoon_realloc(msg, msg->hdr.ac_len)) == NULL) {
8460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
8470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    "Cannot allocate memory: %s\n", strerror(errno));
8480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
8490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
8500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/*
8520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * Now copy the data
8530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 */
8540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	data = (char *)(msg + 1);
8550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	count = 0;
8560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memcpy(data, (char *)script, msg->bufs.buflen[count]);	/* script */
8580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	data += msg->bufs.buflen[count++];
8590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memcpy(data, (char *)&name, msg->bufs.buflen[count]);	/* name */
8610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	data += msg->bufs.buflen[count++];
8620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (c = envp; *c; c++) {				/* envp */
8640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		memcpy(data, *c, msg->bufs.buflen[count]);
8650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		data += msg->bufs.buflen[count++];
8660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
8670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	count++;						/* void */
8690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/*
8710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * And send it!
8720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 */
8730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (privsep_send(privsep_sock[1], msg, msg->hdr.ac_len) != 0)
8740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
8750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (privsep_recv(privsep_sock[1], &msg, &len) != 0)
8770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
8780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (msg->hdr.ac_errno != 0) {
8800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		errno = msg->hdr.ac_errno;
8810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		racoon_free(msg);
8820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
8830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
8840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	racoon_free(msg);
8860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
8870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
8880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
8900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangprivsep_getpsk(str, keylen)
8910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	const char *str;
8920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int keylen;
8930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
8940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *psk;
8950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct privsep_com_msg *msg;
8960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	size_t len;
8970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int *keylenp;
8980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *data;
8990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (geteuid() == 0)
9010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return getpsk(str, keylen);
9020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	len = sizeof(*msg) + strlen(str) + 1 + sizeof(keylen);
9040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((msg = racoon_malloc(len)) == NULL) {
9050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
9060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    "Cannot allocate memory: %s\n", strerror(errno));
9070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
9080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
9090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	bzero(msg, len);
9100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	msg->hdr.ac_cmd = PRIVSEP_GETPSK;
9110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	msg->hdr.ac_len = len;
9120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	data = (char *)(msg + 1);
9140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	msg->bufs.buflen[0] = strlen(str) + 1;
9150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memcpy(data, str, msg->bufs.buflen[0]);
9160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	data += msg->bufs.buflen[0];
9180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	msg->bufs.buflen[1] = sizeof(keylen);
9190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memcpy(data, &keylen, sizeof(keylen));
9200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (privsep_send(privsep_sock[1], msg, len) != 0)
9220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
9230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (privsep_recv(privsep_sock[1], &msg, &len) != 0)
9250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
9260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (msg->hdr.ac_errno != 0) {
9280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		errno = msg->hdr.ac_errno;
9290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto out;
9300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
9310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((psk = vmalloc(len - sizeof(*msg))) == NULL)
9330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto out;
9340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memcpy(psk->v, msg + 1, psk->l);
9360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	racoon_free(msg);
9370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return psk;
9380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangout:
9400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	racoon_free(msg);
9410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return NULL;
9420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
9430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_HYBRID
9450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
9460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangprivsep_xauth_login_system(usr, pwd)
9470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *usr;
9480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *pwd;
9490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
9500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct privsep_com_msg *msg;
9510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	size_t len;
9520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *data;
9530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (geteuid() == 0)
9550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return xauth_login_system(usr, pwd);
9560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	len = sizeof(*msg) + strlen(usr) + 1 + strlen(pwd) + 1;
9580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((msg = racoon_malloc(len)) == NULL) {
9590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
9600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    "Cannot allocate memory: %s\n", strerror(errno));
9610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
9620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
9630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	bzero(msg, len);
9640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	msg->hdr.ac_cmd = PRIVSEP_XAUTH_LOGIN_SYSTEM;
9650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	msg->hdr.ac_len = len;
9660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	data = (char *)(msg + 1);
9680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	msg->bufs.buflen[0] = strlen(usr) + 1;
9690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memcpy(data, usr, msg->bufs.buflen[0]);
9700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	data += msg->bufs.buflen[0];
9710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	msg->bufs.buflen[1] = strlen(pwd) + 1;
9730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memcpy(data, pwd, msg->bufs.buflen[1]);
9740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (privsep_send(privsep_sock[1], msg, len) != 0)
9760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
9770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (privsep_recv(privsep_sock[1], &msg, &len) != 0)
9790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
9800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (msg->hdr.ac_errno != 0) {
9820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		racoon_free(msg);
9830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
9840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
9850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	racoon_free(msg);
9870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
9880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
9890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
9910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangprivsep_accounting_system(port, raddr, usr, inout)
9920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int port;
9930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sockaddr *raddr;
9940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *usr;
9950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int inout;
9960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
9970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct privsep_com_msg *msg;
9980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	size_t len;
9990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *data;
10000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int result;
10010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (geteuid() == 0)
10030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return isakmp_cfg_accounting_system(port, raddr,
10040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						    usr, inout);
10050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	len = sizeof(*msg)
10070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    + sizeof(port)
10080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    + sysdep_sa_len(raddr)
10090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    + strlen(usr) + 1
10100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    + sizeof(inout);
10110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((msg = racoon_malloc(len)) == NULL) {
10130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
10140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    "Cannot allocate memory: %s\n", strerror(errno));
10150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
10160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
10170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	bzero(msg, len);
10180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	msg->hdr.ac_cmd = PRIVSEP_ACCOUNTING_SYSTEM;
10190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	msg->hdr.ac_len = len;
10200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	msg->bufs.buflen[0] = sizeof(port);
10210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	msg->bufs.buflen[1] = sysdep_sa_len(raddr);
10220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	msg->bufs.buflen[2] = strlen(usr) + 1;
10230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	msg->bufs.buflen[3] = sizeof(inout);
10240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	data = (char *)(msg + 1);
10260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memcpy(data, &port, msg->bufs.buflen[0]);
10270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	data += msg->bufs.buflen[0];
10290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memcpy(data, raddr, msg->bufs.buflen[1]);
10300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	data += msg->bufs.buflen[1];
10320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memcpy(data, usr, msg->bufs.buflen[2]);
10330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	data += msg->bufs.buflen[2];
10350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memcpy(data, &inout, msg->bufs.buflen[3]);
10360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (privsep_send(privsep_sock[1], msg, len) != 0)
10380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
10390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (privsep_recv(privsep_sock[1], &msg, &len) != 0)
10410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
10420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (msg->hdr.ac_errno != 0) {
10440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		errno = msg->hdr.ac_errno;
10450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto out;
10460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
10470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	racoon_free(msg);
10490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
10500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangout:
10520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	racoon_free(msg);
10530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return -1;
10540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
10550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
10570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangport_check(port)
10580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int port;
10590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
10600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((port < 0) || (port >= isakmp_cfg_config.pool_size)) {
10610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
10620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    "privsep: port %d outside of allowed range [0,%zu]\n",
10630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    port, isakmp_cfg_config.pool_size - 1);
10640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
10650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
10660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
10680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
10690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
10700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
10720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangsafety_check(msg, index)
10730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct privsep_com_msg *msg;
10740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int index;
10750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
10760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (index >= PRIVSEP_NBUF_MAX) {
10770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
10780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    "privsep: Corrupted message, too many buffers\n");
10790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
10800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
10810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (msg->bufs.buflen[index] == 0) {
10830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
10840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    "privsep: Corrupted message, unexpected void buffer\n");
10850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
10860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
10870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
10890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
10900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
1092c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh * Filter unsafe environement variables
10930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
10940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
10950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangunsafe_env(envp)
10960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *const *envp;
10970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
10980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *const *e;
10990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *const *be;
11000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *const bad_env[] = { "PATH=", "LD_LIBRARY_PATH=", "IFS=", NULL };
11010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (e = envp; *e; e++) {
11030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		for (be = bad_env; *be; be++) {
11040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (strncmp(*e, *be, strlen(*be)) == 0) {
11050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				goto found;
11060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
11070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
11080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
11090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
11110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangfound:
11120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_ERROR, LOCATION, NULL,
1113c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	    "privsep_script_exec: unsafe environement variable\n");
11140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return -1;
11150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
11160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
11180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * Check path safety
11190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
11200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
11210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangunsafe_path(script, pathtype)
11220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *script;
11230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int pathtype;
11240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
11250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *path;
11260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char rpath[MAXPATHLEN + 1];
11270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	size_t len;
11280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (script == NULL)
11300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
11310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	path = lcconf->pathinfo[pathtype];
11330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* No path was given for scripts: skip the check */
11350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (path == NULL)
11360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 0;
11370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (realpath(script, rpath) == NULL) {
11390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
11400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    "script path \"%s\" is invalid\n", script);
11410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
11420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
11430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	len = strlen(path);
11450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (strncmp(path, rpath, len) != 0)
11460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
11470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
11490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
11500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
11520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangunknown_name(name)
11530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int name;
11540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
11550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((name < 0) || (name > SCRIPT_MAX)) {
11560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
11570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    "privsep_script_exec: unsafe name index\n");
11580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
11590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
11600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
11620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
11630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_LIBPAM
11650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
11660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangprivsep_accounting_pam(port, inout)
11670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int port;
11680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int inout;
11690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
11700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct privsep_com_msg *msg;
11710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	size_t len;
11720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int *port_data;
11730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int *inout_data;
11740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int *pool_size_data;
11750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int result;
11760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (geteuid() == 0)
11780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return isakmp_cfg_accounting_pam(port, inout);
11790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	len = sizeof(*msg)
11810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    + sizeof(port)
11820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    + sizeof(inout)
11830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    + sizeof(isakmp_cfg_config.pool_size);
11840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((msg = racoon_malloc(len)) == NULL) {
11860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
11870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    "Cannot allocate memory: %s\n", strerror(errno));
11880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
11890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
11900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	bzero(msg, len);
11910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	msg->hdr.ac_cmd = PRIVSEP_ACCOUNTING_PAM;
11920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	msg->hdr.ac_len = len;
11930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	msg->bufs.buflen[0] = sizeof(port);
11940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	msg->bufs.buflen[1] = sizeof(inout);
11950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	msg->bufs.buflen[2] = sizeof(isakmp_cfg_config.pool_size);
11960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	port_data = (int *)(msg + 1);
11980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	inout_data = (int *)(port_data + 1);
11990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	pool_size_data = (int *)(inout_data + 1);
12000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	*port_data = port;
12020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	*inout_data = inout;
12030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	*pool_size_data = isakmp_cfg_config.pool_size;
12040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (privsep_send(privsep_sock[1], msg, len) != 0)
12060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
12070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (privsep_recv(privsep_sock[1], &msg, &len) != 0)
12090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
12100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (msg->hdr.ac_errno != 0) {
12120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		errno = msg->hdr.ac_errno;
12130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto out;
12140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
12150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	racoon_free(msg);
12170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
12180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangout:
12200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	racoon_free(msg);
12210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return -1;
12220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
12230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
12250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangprivsep_xauth_login_pam(port, raddr, usr, pwd)
12260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int port;
12270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sockaddr *raddr;
12280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *usr;
12290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *pwd;
12300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
12310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct privsep_com_msg *msg;
12320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	size_t len;
12330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *data;
12340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int result;
12350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (geteuid() == 0)
12370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return xauth_login_pam(port, raddr, usr, pwd);
12380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	len = sizeof(*msg)
12400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    + sizeof(port)
12410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    + sizeof(isakmp_cfg_config.pool_size)
12420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    + sysdep_sa_len(raddr)
12430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    + strlen(usr) + 1
12440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    + strlen(pwd) + 1;
12450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((msg = racoon_malloc(len)) == NULL) {
12470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
12480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    "Cannot allocate memory: %s\n", strerror(errno));
12490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
12500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
12510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	bzero(msg, len);
12520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	msg->hdr.ac_cmd = PRIVSEP_XAUTH_LOGIN_PAM;
12530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	msg->hdr.ac_len = len;
12540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	msg->bufs.buflen[0] = sizeof(port);
12550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	msg->bufs.buflen[1] = sizeof(isakmp_cfg_config.pool_size);
12560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	msg->bufs.buflen[2] = sysdep_sa_len(raddr);
12570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	msg->bufs.buflen[3] = strlen(usr) + 1;
12580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	msg->bufs.buflen[4] = strlen(pwd) + 1;
12590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	data = (char *)(msg + 1);
12610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memcpy(data, &port, msg->bufs.buflen[0]);
12620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	data += msg->bufs.buflen[0];
12640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memcpy(data, &isakmp_cfg_config.pool_size, msg->bufs.buflen[1]);
12650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	data += msg->bufs.buflen[1];
12670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memcpy(data, raddr, msg->bufs.buflen[2]);
12680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	data += msg->bufs.buflen[2];
12700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memcpy(data, usr, msg->bufs.buflen[3]);
12710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	data += msg->bufs.buflen[3];
12730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memcpy(data, pwd, msg->bufs.buflen[4]);
12740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (privsep_send(privsep_sock[1], msg, len) != 0)
12760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
12770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (privsep_recv(privsep_sock[1], &msg, &len) != 0)
12790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
12800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (msg->hdr.ac_errno != 0) {
12820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		errno = msg->hdr.ac_errno;
12830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto out;
12840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
12850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	racoon_free(msg);
12870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
12880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangout:
12900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	racoon_free(msg);
12910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return -1;
12920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
12930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid
12950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangprivsep_cleanup_pam(port)
12960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int port;
12970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
12980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct privsep_com_msg *msg;
12990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	size_t len;
13000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *data;
13010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int result;
13020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (geteuid() == 0)
13040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return cleanup_pam(port);
13050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	len = sizeof(*msg)
13070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    + sizeof(port)
13080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    + sizeof(isakmp_cfg_config.pool_size);
13090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((msg = racoon_malloc(len)) == NULL) {
13110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
13120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    "Cannot allocate memory: %s\n", strerror(errno));
13130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return;
13140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
13150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	bzero(msg, len);
13160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	msg->hdr.ac_cmd = PRIVSEP_CLEANUP_PAM;
13170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	msg->hdr.ac_len = len;
13180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	msg->bufs.buflen[0] = sizeof(port);
13190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	msg->bufs.buflen[1] = sizeof(isakmp_cfg_config.pool_size);
13200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	data = (char *)(msg + 1);
13220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memcpy(data, &port, msg->bufs.buflen[0]);
13230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	data += msg->bufs.buflen[0];
13250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memcpy(data, &isakmp_cfg_config.pool_size, msg->bufs.buflen[1]);
13260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (privsep_send(privsep_sock[1], msg, len) != 0)
13280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return;
13290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (privsep_recv(privsep_sock[1], &msg, &len) != 0)
13310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return;
13320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (msg->hdr.ac_errno != 0)
13340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		errno = msg->hdr.ac_errno;
13350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	racoon_free(msg);
13370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return;
13380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
13390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
1340