11c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh/*	$NetBSD: admin.c,v 1.17.6.3 2009/04/20 13:32:57 tteras Exp $	*/
20a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* Id: admin.c,v 1.25 2006/04/06 14:31:04 manubsd Exp */
40a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
50a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
60a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
70a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * All rights reserved.
81c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh *
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.
201c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh *
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 <sys/types.h>
370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <sys/param.h>
380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <sys/socket.h>
390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <sys/signal.h>
400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <sys/stat.h>
410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <sys/un.h>
420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <net/pfkeyv2.h>
440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <netinet/in.h>
460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include PATH_IPSEC_H
470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <stdlib.h>
500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <stdio.h>
510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <string.h>
520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <errno.h>
530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <netdb.h>
540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_UNISTD_H
550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <unistd.h>
560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_HYBRID
580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <resolv.h>
590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "var.h"
620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "misc.h"
630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "vmbuf.h"
640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "plog.h"
650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "sockmisc.h"
660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "debug.h"
670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "schedule.h"
690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "localconf.h"
700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "remoteconf.h"
710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "grabmyaddr.h"
720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "isakmp_var.h"
730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "isakmp.h"
740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "oakley.h"
750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "handler.h"
760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "evt.h"
770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "pfkey.h"
780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "ipsec_doi.h"
790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "admin.h"
800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "admin_var.h"
810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "isakmp_inf.h"
820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_HYBRID
830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "isakmp_cfg.h"
840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "session.h"
860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "gcmalloc.h"
870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_ADMINPORT
890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangchar *adminsock_path = ADMINSOCK_PATH;
900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wanguid_t adminsock_owner = 0;
910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wanggid_t adminsock_group = 0;
920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangmode_t adminsock_mode = 0600;
930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic struct sockaddr_un sunaddr;
950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int admin_process __P((int, char *));
960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int admin_reply __P((int, struct admin_com *, vchar_t *));
970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangadmin_handler()
1000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
1010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int so2;
1020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sockaddr_storage from;
1030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	socklen_t fromlen = sizeof(from);
1040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct admin_com com;
1050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *combuf = NULL;
1060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int len, error = -1;
1070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	so2 = accept(lcconf->sock_admin, (struct sockaddr *)&from, &fromlen);
1090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (so2 < 0) {
1100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
1110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"failed to accept admin command: %s\n",
1120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			strerror(errno));
1130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
1140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
1150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* get buffer length */
1170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	while ((len = recv(so2, (char *)&com, sizeof(com), MSG_PEEK)) < 0) {
1180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (errno == EINTR)
1190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			continue;
1200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
1210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"failed to recv admin command: %s\n",
1220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			strerror(errno));
1230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
1240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
1250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* sanity check */
1270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (len < sizeof(com)) {
1280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
1290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"invalid header length of admin command\n");
1300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
1310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
1320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* get buffer to receive */
1340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((combuf = racoon_malloc(com.ac_len)) == 0) {
1350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
1360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"failed to alloc buffer for admin command\n");
1370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
1380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
1390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* get real data */
1410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	while ((len = recv(so2, combuf, com.ac_len, 0)) < 0) {
1420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (errno == EINTR)
1430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			continue;
1440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
1450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"failed to recv admin command: %s\n",
1460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			strerror(errno));
1470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
1480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
1490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (com.ac_cmd == ADMIN_RELOAD_CONF) {
1510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* reload does not work at all! */
1520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		signal_handler(SIGHUP);
1530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
1540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
1550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	error = admin_process(so2, combuf);
1570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang    end:
1590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	(void)close(so2);
1600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (combuf)
1610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		racoon_free(combuf);
1620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return error;
1640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
1650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
1670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * main child's process.
1680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
1690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
1700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangadmin_process(so2, combuf)
1710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int so2;
1720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *combuf;
1730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
1740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct admin_com *com = (struct admin_com *)combuf;
1750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *buf = NULL;
1760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *id = NULL;
1770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *key = NULL;
1780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int idtype = 0;
1790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int error = -1;
1800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	com->ac_errno = 0;
1820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch (com->ac_cmd) {
1840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case ADMIN_RELOAD_CONF:
1850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* don't entered because of proccessing it in other place. */
1860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL, "should never reach here\n");
1870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto out;
1880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case ADMIN_SHOW_SCHED:
1900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	{
1910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		caddr_t p = NULL;
1920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		int len;
1930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		com->ac_errno = -1;
1950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (sched_dump(&p, &len) == -1)
1970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto out2;
1980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if ((buf = vmalloc(len)) == NULL)
2000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto out2;
2010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		memcpy(buf->v, p, len);
2030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		com->ac_errno = 0;
2050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangout2:
2060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		racoon_free(p);
2070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
2080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
2090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case ADMIN_SHOW_EVT:
2110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* It's not really an error, don't force racoonctl to quit */
2120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if ((buf = evt_dump()) == NULL)
2131c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh			com->ac_errno = 0;
2140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
2150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case ADMIN_SHOW_SA:
2170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case ADMIN_FLUSH_SA:
2180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    {
2190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		switch (com->ac_proto) {
2200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case ADMIN_PROTO_ISAKMP:
2210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			switch (com->ac_cmd) {
2220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case ADMIN_SHOW_SA:
2230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				buf = dumpph1();
2240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				if (buf == NULL)
2250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					com->ac_errno = -1;
2260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
2270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case ADMIN_FLUSH_SA:
2280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				flushph1();
2290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
2300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
2310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
2320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case ADMIN_PROTO_IPSEC:
2330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case ADMIN_PROTO_AH:
2340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case ADMIN_PROTO_ESP:
2350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			switch (com->ac_cmd) {
2360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case ADMIN_SHOW_SA:
2370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    {
2380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				u_int p;
2390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				p = admin2pfkey_proto(com->ac_proto);
2400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				if (p == -1)
2410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					goto out;
2420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				buf = pfkey_dump_sadb(p);
2430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				if (buf == NULL)
2440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					com->ac_errno = -1;
2450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    }
2460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
2470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case ADMIN_FLUSH_SA:
2480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				pfkey_flush_sadb(com->ac_proto);
2490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
2500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
2510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
2520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case ADMIN_PROTO_INTERNAL:
2540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			switch (com->ac_cmd) {
2550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case ADMIN_SHOW_SA:
2560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				buf = NULL; /*XXX dumpph2(&error);*/
2570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				if (buf == NULL)
2580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					com->ac_errno = error;
2590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
2600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case ADMIN_FLUSH_SA:
2610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				/*XXX flushph2();*/
2620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				com->ac_errno = 0;
2630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
2640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
2650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
2660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		default:
2680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* ignore */
2690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			com->ac_errno = -1;
2700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
2710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    }
2720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
2730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case ADMIN_DELETE_SA: {
2750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		struct ph1handle *iph1;
2760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		struct sockaddr *dst;
2770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		struct sockaddr *src;
2780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		char *loc, *rem;
2790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		src = (struct sockaddr *)
2810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			&((struct admin_com_indexes *)
2820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    ((caddr_t)com + sizeof(*com)))->src;
2830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		dst = (struct sockaddr *)
2840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			&((struct admin_com_indexes *)
2850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    ((caddr_t)com + sizeof(*com)))->dst;
2860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		loc = racoon_strdup(saddrwop2str(src));
2880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		rem = racoon_strdup(saddrwop2str(dst));
2890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		STRDUP_FATAL(loc);
2900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		STRDUP_FATAL(rem);
2910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if ((iph1 = getph1byaddrwop(src, dst)) == NULL) {
2931c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh			plog(LLV_ERROR, LOCATION, NULL,
2940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    "phase 1 for %s -> %s not found\n", loc, rem);
2950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		} else {
2960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (iph1->status == PHASE1ST_ESTABLISHED)
2970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				isakmp_info_send_d1(iph1);
2980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			purge_remote(iph1);
2990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
3000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		racoon_free(loc);
3020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		racoon_free(rem);
3030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
3050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
3060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_HYBRID
3080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case ADMIN_LOGOUT_USER: {
3090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		struct ph1handle *iph1;
3101c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh		char user[LOGINLEN+1];
3111c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh		int found = 0, len = com->ac_len - sizeof(com);
3120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3131c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh		if (len > LOGINLEN) {
3140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
3150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    "malformed message (login too long)\n");
3160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
3170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
3180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3191c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh		memcpy(user, (char *)(com + 1), len);
3201c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh		user[len] = 0;
3211c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh
3220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		found = purgeph1bylogin(user);
3231c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh		plog(LLV_INFO, LOCATION, NULL,
3240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    "deleted %d SA for user \"%s\"\n", found, user);
3250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
3270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
3280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
3290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case ADMIN_DELETE_ALL_SA_DST: {
3310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		struct ph1handle *iph1;
3320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		struct sockaddr *dst;
3330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		char *loc, *rem;
3340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		dst = (struct sockaddr *)
3360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			&((struct admin_com_indexes *)
3370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    ((caddr_t)com + sizeof(*com)))->dst;
3380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		rem = racoon_strdup(saddrwop2str(dst));
3400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		STRDUP_FATAL(rem);
3410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3421c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh		plog(LLV_INFO, LOCATION, NULL,
3430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    "Flushing all SAs for peer %s\n", rem);
3440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		while ((iph1 = getph1bydstaddrwop(dst)) != NULL) {
3460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			loc = racoon_strdup(saddrwop2str(iph1->local));
3470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			STRDUP_FATAL(loc);
3480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (iph1->status == PHASE1ST_ESTABLISHED)
3500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				isakmp_info_send_d1(iph1);
3510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			purge_remote(iph1);
3520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			racoon_free(loc);
3540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
3551c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh
3560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		racoon_free(rem);
3570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
3590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
3600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case ADMIN_ESTABLISH_SA_PSK: {
3620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		struct admin_com_psk *acp;
3630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		char *data;
3640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		com->ac_cmd = ADMIN_ESTABLISH_SA;
3660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		acp = (struct admin_com_psk *)
3681c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh		    ((char *)com + sizeof(*com) +
3690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    sizeof(struct admin_com_indexes));
3700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		idtype = acp->id_type;
3720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if ((id = vmalloc(acp->id_len)) == NULL) {
3740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
3751c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh			    "cannot allocate memory: %s\n",
3760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    strerror(errno));
3770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
3780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
3790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		data = (char *)(acp + 1);
3800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		memcpy(id->v, data, id->l);
3810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if ((key = vmalloc(acp->key_len)) == NULL) {
3830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
3841c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh			    "cannot allocate memory: %s\n",
3850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    strerror(errno));
3860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			vfree(id);
3870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			id = NULL;
3880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
3890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
3900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		data = (char *)(data + acp->id_len);
3910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		memcpy(key->v, data, key->l);
3920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
3930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* FALLTHROUGH */
3940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case ADMIN_ESTABLISH_SA:
3950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    {
3960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		struct sockaddr *dst;
3970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		struct sockaddr *src;
3980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		src = (struct sockaddr *)
3990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			&((struct admin_com_indexes *)
4000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    ((caddr_t)com + sizeof(*com)))->src;
4010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		dst = (struct sockaddr *)
4020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			&((struct admin_com_indexes *)
4030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    ((caddr_t)com + sizeof(*com)))->dst;
4040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		switch (com->ac_proto) {
4060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case ADMIN_PROTO_ISAKMP: {
4070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			struct remoteconf *rmconf;
4080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			struct sockaddr *remote = NULL;
4090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			struct sockaddr *local = NULL;
4100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			u_int16_t port;
4110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			com->ac_errno = -1;
4130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* search appropreate configuration */
4150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			rmconf = getrmconf(dst);
4160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (rmconf == NULL) {
4170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
4180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"no configuration found "
4190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"for %s\n", saddrwop2str(dst));
4200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				goto out1;
4210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
4220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* get remote IP address and port number. */
4240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if ((remote = dupsaddr(dst)) == NULL)
4250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				goto out1;
4260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			port = extract_port(rmconf->remote);
4280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (set_port(remote, port) == NULL)
4290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				goto out1;
4300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* get local address */
4320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if ((local = dupsaddr(src)) == NULL)
4330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				goto out1;
4340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			port = getmyaddrsport(local);
4360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (set_port(local, port) == NULL)
4370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				goto out1;
4380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_HYBRID
4400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* Set the id and key */
4410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (id && key) {
4420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				if (xauth_rmconf_used(&rmconf->xauth) == -1)
4430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					goto out1;
4440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				if (rmconf->xauth->login != NULL) {
4460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					vfree(rmconf->xauth->login);
4470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					rmconf->xauth->login = NULL;
4480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				}
4490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				if (rmconf->xauth->pass != NULL) {
4500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					vfree(rmconf->xauth->pass);
4510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					rmconf->xauth->pass = NULL;
4520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				}
4530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				rmconf->xauth->login = id;
4550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				rmconf->xauth->pass = key;
4560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
4570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
4581c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh
4590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_INFO, LOCATION, NULL,
4600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"accept a request to establish IKE-SA: "
4610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"%s\n", saddrwop2str(remote));
4620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* begin ident mode */
4640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (isakmp_ph1begin_i(rmconf, remote, local) < 0)
4650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				goto out1;
4660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			com->ac_errno = 0;
4680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangout1:
4690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (local != NULL)
4700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				racoon_free(local);
4710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (remote != NULL)
4720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				racoon_free(remote);
4730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
4740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
4750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case ADMIN_PROTO_AH:
4760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case ADMIN_PROTO_ESP:
4770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
4780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		default:
4790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* ignore */
4800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			com->ac_errno = -1;
4810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
4820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    }
4830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
4840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	default:
4860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
4870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"invalid command: %d\n", com->ac_cmd);
4880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		com->ac_errno = -1;
4890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
4900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((error = admin_reply(so2, com, buf)) != 0)
4920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto out;
4930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	error = 0;
4950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangout:
4960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (buf != NULL)
4970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		vfree(buf);
4980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return error;
5000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
5010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
5030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangadmin_reply(so, combuf, buf)
5040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int so;
5050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct admin_com *combuf;
5060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *buf;
5070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
5080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int tlen;
5090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *retbuf = NULL;
5100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (buf != NULL)
5120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		tlen = sizeof(*combuf) + buf->l;
5130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	else
5140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		tlen = sizeof(*combuf);
5150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	retbuf = racoon_calloc(1, tlen);
5170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (retbuf == NULL) {
5180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
5190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"failed to allocate admin buffer\n");
5200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
5210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
5220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memcpy(retbuf, combuf, sizeof(*combuf));
5240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	((struct admin_com *)retbuf)->ac_len = tlen;
5250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (buf != NULL)
5270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		memcpy(retbuf + sizeof(*combuf), buf->v, buf->l);
5280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	tlen = send(so, retbuf, tlen, 0);
5300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	racoon_free(retbuf);
5310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (tlen < 0) {
5320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
5330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"failed to send admin command: %s\n",
5340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			strerror(errno));
5350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
5360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
5370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
5390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
5400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* ADMIN_PROTO -> SADB_SATYPE */
5420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
5430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangadmin2pfkey_proto(proto)
5440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int proto;
5450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
5460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch (proto) {
5470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case ADMIN_PROTO_IPSEC:
5480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return SADB_SATYPE_UNSPEC;
5490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case ADMIN_PROTO_AH:
5500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return SADB_SATYPE_AH;
5510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case ADMIN_PROTO_ESP:
5520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return SADB_SATYPE_ESP;
5530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	default:
5540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
5550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"unsupported proto for admin: %d\n", proto);
5560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
5570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
5580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/*NOTREACHED*/
5590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
5600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
5620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangadmin_init()
5630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
5640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (adminsock_path == NULL) {
5650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		lcconf->sock_admin = -1;
5660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 0;
5670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
5680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memset(&sunaddr, 0, sizeof(sunaddr));
5700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	sunaddr.sun_family = AF_UNIX;
5710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	snprintf(sunaddr.sun_path, sizeof(sunaddr.sun_path),
5720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		"%s", adminsock_path);
5730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	lcconf->sock_admin = socket(AF_UNIX, SOCK_STREAM, 0);
5750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (lcconf->sock_admin == -1) {
5760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
5770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"socket: %s\n", strerror(errno));
5780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
5790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
5800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	unlink(sunaddr.sun_path);
5820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (bind(lcconf->sock_admin, (struct sockaddr *)&sunaddr,
5830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			sizeof(sunaddr)) != 0) {
5840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
5850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"bind(sockname:%s): %s\n",
5860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			sunaddr.sun_path, strerror(errno));
5870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		(void)close(lcconf->sock_admin);
5880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
5890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
5900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (chown(sunaddr.sun_path, adminsock_owner, adminsock_group) != 0) {
5921c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh		plog(LLV_ERROR, LOCATION, NULL,
5931c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh		    "chown(%s, %d, %d): %s\n",
5941c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh		    sunaddr.sun_path, adminsock_owner,
5950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    adminsock_group, strerror(errno));
5960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		(void)close(lcconf->sock_admin);
5970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
5980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
5990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (chmod(sunaddr.sun_path, adminsock_mode) != 0) {
6011c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh		plog(LLV_ERROR, LOCATION, NULL,
6021c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh		    "chmod(%s, 0%03o): %s\n",
6030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    sunaddr.sun_path, adminsock_mode, strerror(errno));
6040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		(void)close(lcconf->sock_admin);
6050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
6060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
6070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (listen(lcconf->sock_admin, 5) != 0) {
6090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
6100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"listen(sockname:%s): %s\n",
6110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			sunaddr.sun_path, strerror(errno));
6120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		(void)close(lcconf->sock_admin);
6130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
6140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
6150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_DEBUG, LOCATION, NULL,
6160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		"open %s as racoon management.\n", sunaddr.sun_path);
6170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
6190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
6200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
6220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangadmin_close()
6230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
6240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	close(lcconf->sock_admin);
6250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
6260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
6270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
6286b112236f31ae21c11e416d3dd5d265a5cc5177aChung-yih Wang
629