Home | History | Annotate | Line # | Download | only in racoon
      1 /*	$NetBSD: isakmp_cfg.c,v 1.31 2025/03/08 16:39:08 christos Exp $	*/
      2 
      3 /* Id: isakmp_cfg.c,v 1.55 2006/08/22 18:17:17 manubsd Exp */
      4 
      5 /*
      6  * Copyright (C) 2004-2006 Emmanuel Dreyfus
      7  * All rights reserved.
      8  *
      9  * Redistribution and use in source and binary forms, with or without
     10  * modification, are permitted provided that the following conditions
     11  * are met:
     12  * 1. Redistributions of source code must retain the above copyright
     13  *    notice, this list of conditions and the following disclaimer.
     14  * 2. Redistributions in binary form must reproduce the above copyright
     15  *    notice, this list of conditions and the following disclaimer in the
     16  *    documentation and/or other materials provided with the distribution.
     17  * 3. Neither the name of the project nor the names of its contributors
     18  *    may be used to endorse or promote products derived from this software
     19  *    without specific prior written permission.
     20  *
     21  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
     22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
     25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     31  * SUCH DAMAGE.
     32  */
     33 
     34 #include "config.h"
     35 
     36 #include <sys/types.h>
     37 #include <sys/param.h>
     38 #include <sys/socket.h>
     39 #include <sys/queue.h>
     40 
     41 #include <utmpx.h>
     42 #if defined(__APPLE__) && defined(__MACH__)
     43 #include <util.h>
     44 #endif
     45 
     46 #ifdef __FreeBSD__
     47 # include <libutil.h>
     48 #endif
     49 #ifdef __NetBSD__
     50 #  include <util.h>
     51 #endif
     52 
     53 #include <netinet/in.h>
     54 #include <arpa/inet.h>
     55 
     56 #include <stdlib.h>
     57 #include <stdio.h>
     58 #include <string.h>
     59 #include <errno.h>
     60 #if TIME_WITH_SYS_TIME
     61 # include <sys/time.h>
     62 # include <time.h>
     63 #else
     64 # if HAVE_SYS_TIME_H
     65 #  include <sys/time.h>
     66 # else
     67 #  include <time.h>
     68 # endif
     69 #endif
     70 #include <netdb.h>
     71 #ifdef HAVE_UNISTD_H
     72 #include <unistd.h>
     73 #endif
     74 #if HAVE_STDINT_H
     75 #include <stdint.h>
     76 #endif
     77 #include <ctype.h>
     78 #include <resolv.h>
     79 
     80 #ifdef HAVE_LIBRADIUS
     81 #include <sys/utsname.h>
     82 #include <radlib.h>
     83 #endif
     84 
     85 #include "var.h"
     86 #include "misc.h"
     87 #include "vmbuf.h"
     88 #include "plog.h"
     89 #include "sockmisc.h"
     90 #include "schedule.h"
     91 #include "debug.h"
     92 
     93 #include "isakmp_var.h"
     94 #include "isakmp.h"
     95 #include "handler.h"
     96 #include "evt.h"
     97 #include "throttle.h"
     98 #include "remoteconf.h"
     99 #include "crypto_openssl.h"
    100 #include "isakmp_inf.h"
    101 #include "isakmp_xauth.h"
    102 #include "isakmp_unity.h"
    103 #include "isakmp_cfg.h"
    104 #include "strnames.h"
    105 #include "admin.h"
    106 #include "privsep.h"
    107 
    108 struct isakmp_cfg_config isakmp_cfg_config;
    109 
    110 static vchar_t *buffer_cat(vchar_t *s, vchar_t *append);
    111 static vchar_t *isakmp_cfg_net(struct ph1handle *, struct isakmp_data *);
    112 #if 0
    113 static vchar_t *isakmp_cfg_void(struct ph1handle *, struct isakmp_data *);
    114 #endif
    115 static vchar_t *isakmp_cfg_addr4(struct ph1handle *,
    116 				 struct isakmp_data *, in_addr_t *);
    117 static vchar_t *isakmp_cfg_addrnet4(struct ph1handle *,
    118 				 struct isakmp_data *, in_addr_t *, in_addr_t *);
    119 static void isakmp_cfg_getaddr4(struct isakmp_data *, struct in_addr *);
    120 static vchar_t *isakmp_cfg_addr4_list(struct ph1handle *,
    121 				      struct isakmp_data *, in_addr_t *, int);
    122 static void isakmp_cfg_appendaddr4(struct isakmp_data *,
    123 				   struct in_addr *, int *, int);
    124 static void isakmp_cfg_getstring(struct isakmp_data *,char *);
    125 static void isakmp_cfg_iplist_to_str(char *, int, void *, int);
    126 
    127 #define ISAKMP_CFG_LOGIN	1
    128 #define ISAKMP_CFG_LOGOUT	2
    129 static int isakmp_cfg_accounting(struct ph1handle *, int);
    130 #ifdef HAVE_LIBRADIUS
    131 static int isakmp_cfg_accounting_radius(struct ph1handle *, int);
    132 #endif
    133 
    134 /*
    135  * Handle an ISAKMP config mode packet
    136  * We expect HDR, HASH, ATTR
    137  */
    138 void
    139 isakmp_cfg_r(struct ph1handle *iph1, vchar_t *msg)
    140 {
    141 	struct isakmp *packet;
    142 	struct isakmp_gen *ph;
    143 	size_t tlen;
    144 	char *npp;
    145 	int np;
    146 	vchar_t *dmsg;
    147 	struct isakmp_ivm *ivm;
    148 
    149 	/* Check that the packet is long enough to have a header */
    150 	if (msg->l < sizeof(*packet)) {
    151 	     plog(LLV_ERROR, LOCATION, NULL, "Unexpected short packet\n");
    152 	     return;
    153 	}
    154 
    155 	packet = (struct isakmp *)msg->v;
    156 
    157 	/* Is it encrypted? It should be encrypted */
    158 	if ((packet->flags & ISAKMP_FLAG_E) == 0) {
    159 		plog(LLV_ERROR, LOCATION, NULL,
    160 		    "User credentials sent in cleartext!\n");
    161 		return;
    162 	}
    163 
    164 	/*
    165 	 * Decrypt the packet. If this is the beginning of a new
    166 	 * exchange, reinitialize the IV
    167 	 */
    168 	if (iph1->mode_cfg->ivm == NULL ||
    169 	    iph1->mode_cfg->last_msgid != packet->msgid )
    170 		iph1->mode_cfg->ivm =
    171 		    isakmp_cfg_newiv(iph1, packet->msgid);
    172 	ivm = iph1->mode_cfg->ivm;
    173 
    174 	dmsg = oakley_do_decrypt(iph1, msg, ivm->iv, ivm->ive);
    175 	if (dmsg == NULL) {
    176 		plog(LLV_ERROR, LOCATION, NULL,
    177 		    "failed to decrypt message\n");
    178 		return;
    179 	}
    180 
    181 	plog(LLV_DEBUG, LOCATION, NULL, "MODE_CFG packet\n");
    182 	plogdump(LLV_DEBUG, dmsg->v, dmsg->l);
    183 
    184 	/* Now work with the decrypted packet */
    185 	packet = (struct isakmp *)dmsg->v;
    186 	tlen = dmsg->l - sizeof(*packet);
    187 	ph = (struct isakmp_gen *)(packet + 1);
    188 
    189 	np = packet->np;
    190 	while ((tlen > 0) && (np != ISAKMP_NPTYPE_NONE)) {
    191 		/* Check that the payload header fits in the packet */
    192 		if (tlen < sizeof(*ph)) {
    193 			 plog(LLV_WARNING, LOCATION, NULL,
    194 			      "Short payload header\n");
    195 			 goto out;
    196 		}
    197 
    198 		/* Check that the payload fits in the packet */
    199 		if (tlen < ntohs(ph->len)) {
    200 			plog(LLV_WARNING, LOCATION, NULL,
    201 			      "Short payload\n");
    202 			goto out;
    203 		}
    204 
    205 		plog(LLV_DEBUG, LOCATION, NULL, "Seen payload %d\n", np);
    206 		plogdump(LLV_DEBUG, ph, ntohs(ph->len));
    207 
    208 		switch(np) {
    209 		case ISAKMP_NPTYPE_HASH: {
    210 			vchar_t *check;
    211 			vchar_t *payload;
    212 			size_t plen;
    213 			struct isakmp_gen *nph;
    214 
    215 			plen = ntohs(ph->len);
    216 			nph = (struct isakmp_gen *)((char *)ph + plen);
    217 			plen = ntohs(nph->len);
    218 
    219 			if ((payload = vmalloc(plen)) == NULL) {
    220 				plog(LLV_ERROR, LOCATION, NULL,
    221 				    "Cannot allocate memory\n");
    222 				goto out;
    223 			}
    224 			memcpy(payload->v, nph, plen);
    225 
    226 			if ((check = oakley_compute_hash1(iph1,
    227 			    packet->msgid, payload)) == NULL) {
    228 				plog(LLV_ERROR, LOCATION, NULL,
    229 				    "Cannot compute hash\n");
    230 				vfree(payload);
    231 				goto out;
    232 			}
    233 
    234 			if (memcmp(ph + 1, check->v, check->l) != 0) {
    235 				plog(LLV_ERROR, LOCATION, NULL,
    236 				    "Hash verification failed\n");
    237 				vfree(payload);
    238 				vfree(check);
    239 				goto out;
    240 			}
    241 			vfree(payload);
    242 			vfree(check);
    243 			break;
    244 		}
    245 		case ISAKMP_NPTYPE_ATTR: {
    246 			struct isakmp_pl_attr *attrpl;
    247 
    248 			attrpl = (struct isakmp_pl_attr *)ph;
    249 			isakmp_cfg_attr_r(iph1, packet->msgid, attrpl);
    250 
    251 			break;
    252 		}
    253 		default:
    254 			 plog(LLV_WARNING, LOCATION, NULL,
    255 			      "Unexpected next payload %d\n", np);
    256 			 /* Skip to the next payload */
    257 			 break;
    258 		}
    259 
    260 		/* Move to the next payload */
    261 		np = ph->np;
    262 		tlen -= ntohs(ph->len);
    263 		npp = (char *)ph;
    264 		ph = (struct isakmp_gen *)(npp + ntohs(ph->len));
    265 	}
    266 
    267 out:
    268 	vfree(dmsg);
    269 }
    270 
    271 int
    272 isakmp_cfg_attr_r(struct ph1handle *iph1, uint32_t msgid,
    273     struct isakmp_pl_attr *attrpl)
    274 {
    275 	int type = attrpl->type;
    276 
    277 	plog(LLV_DEBUG, LOCATION, NULL,
    278 	     "Configuration exchange type %s\n", s_isakmp_cfg_ptype(type));
    279 	switch (type) {
    280 	case ISAKMP_CFG_ACK:
    281 		/* ignore, but this is the time to reinit the IV */
    282 		oakley_delivm(iph1->mode_cfg->ivm);
    283 		iph1->mode_cfg->ivm = NULL;
    284 		return 0;
    285 
    286 	case ISAKMP_CFG_REPLY:
    287 		return isakmp_cfg_reply(iph1, attrpl);
    288 
    289 	case ISAKMP_CFG_REQUEST:
    290 		iph1->msgid = msgid;
    291 		return isakmp_cfg_request(iph1, attrpl);
    292 
    293 	case ISAKMP_CFG_SET:
    294 		iph1->msgid = msgid;
    295 		return isakmp_cfg_set(iph1, attrpl);
    296 
    297 	default:
    298 		plog(LLV_WARNING, LOCATION, NULL,
    299 		     "Unepected configuration exchange type %d\n", type);
    300 		return -1;
    301 	}
    302 }
    303 
    304 int
    305 isakmp_cfg_reply(struct ph1handle *iph1, struct isakmp_pl_attr *attrpl)
    306 {
    307 	struct isakmp_data *attr;
    308 	size_t tlen;
    309 	size_t alen;
    310 	char *npp;
    311 	int type;
    312 	int error;
    313 
    314 	tlen = ntohs(attrpl->h.len);
    315 	attr = (struct isakmp_data *)(attrpl + 1);
    316 	tlen -= sizeof(*attrpl);
    317 
    318 	while (tlen > 0) {
    319 		type = ntohs(attr->type);
    320 
    321 		/* Handle short attributes */
    322 		if ((type & ISAKMP_GEN_MASK) == ISAKMP_GEN_TV) {
    323 			type &= ~ISAKMP_GEN_MASK;
    324 
    325 			plog(LLV_DEBUG, LOCATION, NULL,
    326 			     "Short attribute %s = %d\n",
    327 			     s_isakmp_cfg_type(type), ntohs(attr->lorv));
    328 
    329 			switch (type) {
    330 			case XAUTH_TYPE:
    331 				if ((error = xauth_attr_reply(iph1,
    332 				    attr, ntohs(attrpl->id))) != 0)
    333 					return error;
    334 				break;
    335 
    336 			default:
    337 				plog(LLV_WARNING, LOCATION, NULL,
    338 				     "Ignored short attribute %s\n",
    339 				     s_isakmp_cfg_type(type));
    340 				break;
    341 			}
    342 
    343 			tlen -= sizeof(*attr);
    344 			attr++;
    345 			continue;
    346 		}
    347 
    348 		type = ntohs(attr->type);
    349 		alen = ntohs(attr->lorv);
    350 
    351 		/* Check that the attribute fit in the packet */
    352 		if (tlen < alen) {
    353 			plog(LLV_ERROR, LOCATION, NULL,
    354 			     "Short attribute %s\n",
    355 			     s_isakmp_cfg_type(type));
    356 			return -1;
    357 		}
    358 
    359 		plog(LLV_DEBUG, LOCATION, NULL,
    360 		     "Attribute %s, len %zu\n",
    361 		     s_isakmp_cfg_type(type), alen);
    362 
    363 		switch(type) {
    364 		case XAUTH_TYPE:
    365 		case XAUTH_USER_NAME:
    366 		case XAUTH_USER_PASSWORD:
    367 		case XAUTH_PASSCODE:
    368 		case XAUTH_MESSAGE:
    369 		case XAUTH_CHALLENGE:
    370 		case XAUTH_DOMAIN:
    371 		case XAUTH_STATUS:
    372 		case XAUTH_NEXT_PIN:
    373 		case XAUTH_ANSWER:
    374 			if ((error = xauth_attr_reply(iph1,
    375 			    attr, ntohs(attrpl->id))) != 0)
    376 				return error;
    377 			break;
    378 		case INTERNAL_IP4_ADDRESS:
    379 			isakmp_cfg_getaddr4(attr, &iph1->mode_cfg->addr4);
    380 			iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_ADDR4;
    381 			break;
    382 		case INTERNAL_IP4_NETMASK:
    383 			isakmp_cfg_getaddr4(attr, &iph1->mode_cfg->mask4);
    384 			iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_MASK4;
    385 			break;
    386 		case INTERNAL_IP4_DNS:
    387 			isakmp_cfg_appendaddr4(attr,
    388 			    &iph1->mode_cfg->dns4[iph1->mode_cfg->dns4_index],
    389 			    &iph1->mode_cfg->dns4_index, MAXNS);
    390 			iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_DNS4;
    391 			break;
    392 		case INTERNAL_IP4_NBNS:
    393 			isakmp_cfg_appendaddr4(attr,
    394 			    &iph1->mode_cfg->wins4[iph1->mode_cfg->wins4_index],
    395 			    &iph1->mode_cfg->wins4_index, MAXNS);
    396 			iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_WINS4;
    397 			break;
    398 		case UNITY_DEF_DOMAIN:
    399 			isakmp_cfg_getstring(attr,
    400 			    iph1->mode_cfg->default_domain);
    401 			iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_DEFAULT_DOMAIN;
    402 			break;
    403 		case UNITY_SPLIT_INCLUDE:
    404 		case UNITY_LOCAL_LAN:
    405 		case UNITY_SPLITDNS_NAME:
    406 		case UNITY_BANNER:
    407 		case UNITY_SAVE_PASSWD:
    408 		case UNITY_NATT_PORT:
    409 		case UNITY_PFS:
    410 		case UNITY_FW_TYPE:
    411 		case UNITY_BACKUP_SERVERS:
    412 		case UNITY_DDNS_HOSTNAME:
    413 			isakmp_unity_reply(iph1, attr);
    414 			break;
    415 		case INTERNAL_IP4_SUBNET:
    416 		case INTERNAL_ADDRESS_EXPIRY:
    417 		default:
    418 			plog(LLV_WARNING, LOCATION, NULL,
    419 			     "Ignored attribute %s\n",
    420 			     s_isakmp_cfg_type(type));
    421 			break;
    422 		}
    423 
    424 		npp = (char *)attr;
    425 		attr = (struct isakmp_data *)(npp + sizeof(*attr) + alen);
    426 		tlen -= (sizeof(*attr) + alen);
    427 	}
    428 
    429 	/*
    430 	 * Call the SA up script hook now that we have the configuration
    431 	 * It is done at the end of phase 1 if ISAKMP mode config is not
    432 	 * requested.
    433 	 */
    434 
    435 	if ((iph1->status == PHASE1ST_ESTABLISHED) &&
    436 	    iph1->rmconf->mode_cfg) {
    437 		switch (iph1->approval->authmethod) {
    438 		case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I:
    439 		case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
    440 		/* Unimplemented */
    441 		case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I:
    442 		case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I:
    443 		case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I:
    444 		case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I:
    445 		case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I:
    446 		case OAKLEY_ATTR_AUTH_METHOD_RSASIG:
    447 			script_hook(iph1, SCRIPT_PHASE1_UP);
    448 			break;
    449 		default:
    450 			break;
    451 		}
    452 	}
    453 
    454 
    455 #ifdef ENABLE_ADMINPORT
    456 	{
    457 		vchar_t *buf;
    458 
    459 		alen = ntohs(attrpl->h.len) - sizeof(*attrpl);
    460 		if ((buf = vmalloc(alen)) == NULL) {
    461 			plog(LLV_WARNING, LOCATION, NULL,
    462 			    "Cannot allocate memory: %s\n", strerror(errno));
    463 		} else {
    464 			memcpy(buf->v, attrpl + 1, buf->l);
    465 			evt_phase1(iph1, EVT_PHASE1_MODE_CFG, buf);
    466 			vfree(buf);
    467 		}
    468 	}
    469 #endif
    470 
    471 	return 0;
    472 }
    473 
    474 int
    475 isakmp_cfg_request(struct ph1handle *iph1, struct isakmp_pl_attr *attrpl)
    476 {
    477 	struct isakmp_data *attr;
    478 	size_t tlen;
    479 	size_t alen;
    480 	char *npp;
    481 	vchar_t *payload;
    482 	struct isakmp_pl_attr *reply;
    483 	vchar_t *reply_attr;
    484 	int type;
    485 	int error = -1;
    486 
    487 	if ((payload = vmalloc(sizeof(*reply))) == NULL) {
    488 		plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
    489 		return -1;
    490 	}
    491 	memset(payload->v, 0, sizeof(*reply));
    492 
    493 	tlen = ntohs(attrpl->h.len);
    494 	attr = (struct isakmp_data *)(attrpl + 1);
    495 	tlen -= sizeof(*attrpl);
    496 
    497 	while (tlen > 0) {
    498 		reply_attr = NULL;
    499 		type = ntohs(attr->type);
    500 
    501 		/* Handle short attributes */
    502 		if ((type & ISAKMP_GEN_MASK) == ISAKMP_GEN_TV) {
    503 			type &= ~ISAKMP_GEN_MASK;
    504 
    505 			plog(LLV_DEBUG, LOCATION, NULL,
    506 			     "Short attribute %s = %d\n",
    507 			     s_isakmp_cfg_type(type), ntohs(attr->lorv));
    508 
    509 			switch (type) {
    510 			case XAUTH_TYPE:
    511 				reply_attr = isakmp_xauth_req(iph1, attr);
    512 				break;
    513 			default:
    514 				plog(LLV_WARNING, LOCATION, NULL,
    515 				     "Ignored short attribute %s\n",
    516 				     s_isakmp_cfg_type(type));
    517 				break;
    518 			}
    519 
    520 			tlen -= sizeof(*attr);
    521 			attr++;
    522 
    523 			if (reply_attr != NULL) {
    524 				payload = buffer_cat(payload, reply_attr);
    525 				vfree(reply_attr);
    526 			}
    527 
    528 			continue;
    529 		}
    530 
    531 		type = ntohs(attr->type);
    532 		alen = ntohs(attr->lorv);
    533 
    534 		/* Check that the attribute fit in the packet */
    535 		if (tlen < alen) {
    536 			plog(LLV_ERROR, LOCATION, NULL,
    537 			     "Short attribute %s\n",
    538 			     s_isakmp_cfg_type(type));
    539 			goto end;
    540 		}
    541 
    542 		plog(LLV_DEBUG, LOCATION, NULL,
    543 		     "Attribute %s, len %zu\n",
    544 		     s_isakmp_cfg_type(type), alen);
    545 
    546 		switch(type) {
    547 		case INTERNAL_IP4_ADDRESS:
    548 		case INTERNAL_IP4_NETMASK:
    549 		case INTERNAL_IP4_DNS:
    550 		case INTERNAL_IP4_NBNS:
    551 		case INTERNAL_IP4_SUBNET:
    552 			reply_attr = isakmp_cfg_net(iph1, attr);
    553 			break;
    554 
    555 		case XAUTH_TYPE:
    556 		case XAUTH_USER_NAME:
    557 		case XAUTH_USER_PASSWORD:
    558 		case XAUTH_PASSCODE:
    559 		case XAUTH_MESSAGE:
    560 		case XAUTH_CHALLENGE:
    561 		case XAUTH_DOMAIN:
    562 		case XAUTH_STATUS:
    563 		case XAUTH_NEXT_PIN:
    564 		case XAUTH_ANSWER:
    565 			reply_attr = isakmp_xauth_req(iph1, attr);
    566 			break;
    567 
    568 		case APPLICATION_VERSION:
    569 			reply_attr = isakmp_cfg_string(iph1,
    570 			    attr, ISAKMP_CFG_RACOON_VERSION);
    571 			break;
    572 
    573 		case UNITY_BANNER:
    574 		case UNITY_PFS:
    575 		case UNITY_SAVE_PASSWD:
    576 		case UNITY_DEF_DOMAIN:
    577 		case UNITY_DDNS_HOSTNAME:
    578 		case UNITY_FW_TYPE:
    579 		case UNITY_SPLITDNS_NAME:
    580 		case UNITY_SPLIT_INCLUDE:
    581 		case UNITY_LOCAL_LAN:
    582 		case UNITY_NATT_PORT:
    583 		case UNITY_BACKUP_SERVERS:
    584 			reply_attr = isakmp_unity_req(iph1, attr);
    585 			break;
    586 
    587 		case INTERNAL_ADDRESS_EXPIRY:
    588 		default:
    589 			plog(LLV_WARNING, LOCATION, NULL,
    590 			     "Ignored attribute %s\n",
    591 			     s_isakmp_cfg_type(type));
    592 			break;
    593 		}
    594 
    595 		npp = (char *)attr;
    596 		attr = (struct isakmp_data *)(npp + sizeof(*attr) + alen);
    597 		tlen -= (sizeof(*attr) + alen);
    598 
    599 		if (reply_attr != NULL) {
    600 			payload = buffer_cat(payload, reply_attr);
    601 			vfree(reply_attr);
    602 		}
    603 
    604 	}
    605 
    606 	reply = (struct isakmp_pl_attr *)payload->v;
    607 	reply->h.len = htons(payload->l);
    608 	reply->type = ISAKMP_CFG_REPLY;
    609 	reply->id = attrpl->id;
    610 
    611 	plog(LLV_DEBUG, LOCATION, NULL,
    612 		    "Sending MODE_CFG REPLY\n");
    613 
    614 	error = isakmp_cfg_send(iph1, payload,
    615 	    ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 0);
    616 
    617 	if (iph1->status == PHASE1ST_ESTABLISHED) {
    618 		switch (iph1->approval->authmethod) {
    619 		case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R:
    620 		case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R:
    621 		/* Unimplemented */
    622 		case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R:
    623 		case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R:
    624 		case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R:
    625 		case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R:
    626 		case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R:
    627 		case OAKLEY_ATTR_AUTH_METHOD_RSASIG:
    628 			script_hook(iph1, SCRIPT_PHASE1_UP);
    629 			break;
    630 		default:
    631 			break;
    632 		}
    633 	}
    634 
    635 end:
    636 	vfree(payload);
    637 
    638 	return error;
    639 }
    640 
    641 int
    642 isakmp_cfg_set(struct ph1handle *iph1, struct isakmp_pl_attr *attrpl)
    643 {
    644 	struct isakmp_data *attr;
    645 	size_t tlen;
    646 	size_t alen;
    647 	char *npp;
    648 	vchar_t *payload;
    649 	struct isakmp_pl_attr *reply;
    650 	vchar_t *reply_attr;
    651 	int type;
    652 	int error = -1;
    653 
    654 	if ((payload = vmalloc(sizeof(*reply))) == NULL) {
    655 		plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
    656 		return -1;
    657 	}
    658 	memset(payload->v, 0, sizeof(*reply));
    659 
    660 	tlen = ntohs(attrpl->h.len);
    661 	attr = (struct isakmp_data *)(attrpl + 1);
    662 	tlen -= sizeof(*attrpl);
    663 
    664 	/*
    665 	 * We should send ack for the attributes we accepted
    666 	 */
    667 	while (tlen > 0) {
    668 		reply_attr = NULL;
    669 		type = ntohs(attr->type);
    670 
    671 		plog(LLV_DEBUG, LOCATION, NULL,
    672 		     "Attribute %s\n",
    673 		     s_isakmp_cfg_type(type & ~ISAKMP_GEN_MASK));
    674 
    675 		switch (type & ~ISAKMP_GEN_MASK) {
    676 		case XAUTH_STATUS:
    677 			reply_attr = isakmp_xauth_set(iph1, attr);
    678 			break;
    679 		default:
    680 			plog(LLV_DEBUG, LOCATION, NULL,
    681 			     "Unexpected SET attribute %s\n",
    682 		     	     s_isakmp_cfg_type(type & ~ISAKMP_GEN_MASK));
    683 			break;
    684 		}
    685 
    686 		if (reply_attr != NULL) {
    687 			payload = buffer_cat(payload, reply_attr);
    688 			vfree(reply_attr);
    689 		}
    690 
    691 		/*
    692 		 * Move to next attribute. If we run out of the packet,
    693 		 * tlen becomes negative and we exit.
    694 		 */
    695 		if ((type & ISAKMP_GEN_MASK) == ISAKMP_GEN_TV) {
    696 			tlen -= sizeof(*attr);
    697 			attr++;
    698 		} else {
    699 			alen = ntohs(attr->lorv);
    700 			tlen -= (sizeof(*attr) + alen);
    701 			npp = (char *)attr;
    702 			attr = (struct isakmp_data *)
    703 			    (npp + sizeof(*attr) + alen);
    704 		}
    705 	}
    706 
    707 	reply = (struct isakmp_pl_attr *)payload->v;
    708 	reply->h.len = htons(payload->l);
    709 	reply->type = ISAKMP_CFG_ACK;
    710 	reply->id = attrpl->id;
    711 
    712 	plog(LLV_DEBUG, LOCATION, NULL,
    713 		     "Sending MODE_CFG ACK\n");
    714 
    715 	error = isakmp_cfg_send(iph1, payload,
    716 	    ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 0);
    717 
    718 	if (iph1->mode_cfg->flags & ISAKMP_CFG_DELETE_PH1) {
    719 		if (iph1->status == PHASE1ST_ESTABLISHED ||
    720 		    iph1->status == PHASE1ST_DYING)
    721 			isakmp_info_send_d1(iph1);
    722 		remph1(iph1);
    723 		delph1(iph1);
    724 		iph1 = NULL;
    725 	}
    726 
    727 	vfree(payload);
    728 
    729 	/*
    730 	 * If required, request ISAKMP mode config information
    731 	 */
    732 	if ((iph1 != NULL) && (iph1->rmconf->mode_cfg) && (error == 0))
    733 		error = isakmp_cfg_getconfig(iph1);
    734 
    735 	return error;
    736 }
    737 
    738 
    739 static vchar_t *
    740 buffer_cat(vchar_t *s, vchar_t *append)
    741 {
    742 	vchar_t *new;
    743 
    744 	new = vmalloc(s->l + append->l);
    745 	if (new == NULL) {
    746 		plog(LLV_ERROR, LOCATION, NULL,
    747 		    "Cannot allocate memory\n");
    748 		return s;
    749 	}
    750 
    751 	memcpy(new->v, s->v, s->l);
    752 	memcpy(new->v + s->l, append->v, append->l);
    753 
    754 	vfree(s);
    755 	return new;
    756 }
    757 
    758 static vchar_t *
    759 isakmp_cfg_net(struct ph1handle *iph1, struct isakmp_data *attr)
    760 {
    761 	int type;
    762 	int confsource;
    763 
    764 	type = ntohs(attr->type);
    765 
    766 	/*
    767 	 * Don't give an address to a peer that did not succeed Xauth
    768 	 */
    769 	if (xauth_check(iph1) != 0) {
    770 		plog(LLV_ERROR, LOCATION, NULL,
    771 		    "Attempt to start phase config whereas Xauth failed\n");
    772 		return NULL;
    773 	}
    774 
    775 	confsource = isakmp_cfg_config.confsource;
    776 	/*
    777 	 * If we have to fall back to a local
    778 	 * configuration source, we will jump
    779 	 * back to this point.
    780 	 */
    781 retry_source:
    782 
    783 	switch(type) {
    784 	case INTERNAL_IP4_ADDRESS:
    785 		switch(confsource) {
    786 #ifdef HAVE_LIBLDAP
    787 		case ISAKMP_CFG_CONF_LDAP:
    788 			if (iph1->mode_cfg->flags & ISAKMP_CFG_ADDR4_EXTERN)
    789 			    break;
    790 			plog(LLV_INFO, LOCATION, NULL,
    791 			    "No IP from LDAP, using local pool\n");
    792 			/* FALLTHROUGH */
    793 			confsource = ISAKMP_CFG_CONF_LOCAL;
    794 			goto retry_source;
    795 #endif
    796 #ifdef HAVE_LIBRADIUS
    797 		case ISAKMP_CFG_CONF_RADIUS:
    798 			if ((iph1->mode_cfg->flags & ISAKMP_CFG_ADDR4_EXTERN)
    799 			    && (iph1->mode_cfg->addr4.s_addr != htonl(-2)))
    800 			    /*
    801 			     * -2 is 255.255.255.254, RADIUS uses that
    802 			     * to instruct the NAS to use a local pool
    803 			     */
    804 			    break;
    805 			plog(LLV_INFO, LOCATION, NULL,
    806 			    "No IP from RADIUS, using local pool\n");
    807 			/* FALLTHROUGH */
    808 			confsource = ISAKMP_CFG_CONF_LOCAL;
    809 			goto retry_source;
    810 #endif
    811 		case ISAKMP_CFG_CONF_LOCAL:
    812 			if (isakmp_cfg_getport(iph1) == -1) {
    813 				plog(LLV_ERROR, LOCATION, NULL,
    814 				    "Port pool depleted\n");
    815 				break;
    816 			}
    817 
    818 			iph1->mode_cfg->addr4.s_addr =
    819 			    htonl(ntohl(isakmp_cfg_config.network4)
    820 			    + iph1->mode_cfg->port);
    821 			iph1->mode_cfg->flags |= ISAKMP_CFG_ADDR4_LOCAL;
    822 			break;
    823 
    824 		default:
    825 			plog(LLV_ERROR, LOCATION, NULL,
    826 			    "Unexpected confsource\n");
    827 		}
    828 
    829 		if (isakmp_cfg_accounting(iph1, ISAKMP_CFG_LOGIN) != 0)
    830 			plog(LLV_ERROR, LOCATION, NULL, "Accounting failed\n");
    831 
    832 		return isakmp_cfg_addr4(iph1,
    833 		    attr, &iph1->mode_cfg->addr4.s_addr);
    834 
    835 	case INTERNAL_IP4_NETMASK:
    836 		switch(confsource) {
    837 #ifdef HAVE_LIBLDAP
    838 		case ISAKMP_CFG_CONF_LDAP:
    839 			if (iph1->mode_cfg->flags & ISAKMP_CFG_MASK4_EXTERN)
    840 				break;
    841 			plog(LLV_INFO, LOCATION, NULL,
    842 			    "No mask from LDAP, using local pool\n");
    843 			/* FALLTHROUGH */
    844 			confsource = ISAKMP_CFG_CONF_LOCAL;
    845 			goto retry_source;
    846 #endif
    847 #ifdef HAVE_LIBRADIUS
    848 		case ISAKMP_CFG_CONF_RADIUS:
    849 			if (iph1->mode_cfg->flags & ISAKMP_CFG_MASK4_EXTERN)
    850 				break;
    851 			plog(LLV_INFO, LOCATION, NULL,
    852 			    "No mask from RADIUS, using local pool\n");
    853 			/* FALLTHROUGH */
    854 			confsource = ISAKMP_CFG_CONF_LOCAL;
    855 			goto retry_source;
    856 #endif
    857 		case ISAKMP_CFG_CONF_LOCAL:
    858 			iph1->mode_cfg->mask4.s_addr
    859 			    = isakmp_cfg_config.netmask4;
    860 			iph1->mode_cfg->flags |= ISAKMP_CFG_MASK4_LOCAL;
    861 			break;
    862 
    863 		default:
    864 			plog(LLV_ERROR, LOCATION, NULL,
    865 			    "Unexpected confsource\n");
    866 		}
    867 		return isakmp_cfg_addr4(iph1, attr,
    868 		    &iph1->mode_cfg->mask4.s_addr);
    869 
    870 	case INTERNAL_IP4_DNS:
    871 		return isakmp_cfg_addr4_list(iph1,
    872 		    attr, &isakmp_cfg_config.dns4[0],
    873 		    isakmp_cfg_config.dns4_index);
    874 
    875 	case INTERNAL_IP4_NBNS:
    876 		return isakmp_cfg_addr4_list(iph1,
    877 		    attr, &isakmp_cfg_config.nbns4[0],
    878 		    isakmp_cfg_config.nbns4_index);
    879 
    880 	case INTERNAL_IP4_SUBNET:
    881 		if(isakmp_cfg_config.splitnet_count > 0){
    882 			return isakmp_cfg_addrnet4(iph1, attr,
    883 						    &isakmp_cfg_config.splitnet_list->network.addr4.s_addr,
    884 						    &isakmp_cfg_config.splitnet_list->network.mask4.s_addr);
    885 		}else{
    886 			plog(LLV_INFO, LOCATION, NULL,
    887 			     "%s requested but no splitnet in configuration\n",
    888 			     s_isakmp_cfg_type(type));
    889 		}
    890 		break;
    891 
    892 	default:
    893 		plog(LLV_ERROR, LOCATION, NULL, "Unexpected type %d\n", type);
    894 		break;
    895 	}
    896 	return NULL;
    897 }
    898 
    899 #if 0
    900 static vchar_t *
    901 isakmp_cfg_void(struct ph1handle *iph1, struct isakmp_data *attr)
    902 {
    903 	vchar_t *buffer;
    904 	struct isakmp_data *new;
    905 
    906 	if ((buffer = vmalloc(sizeof(*attr))) == NULL) {
    907 		plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
    908 		return NULL;
    909 	}
    910 
    911 	new = (struct isakmp_data *)buffer->v;
    912 
    913 	new->type = attr->type;
    914 	new->lorv = htons(0);
    915 
    916 	return buffer;
    917 }
    918 #endif
    919 
    920 /*ARGSUSED*/
    921 vchar_t *
    922 isakmp_cfg_copy(struct ph1handle *iph1 __unused, struct isakmp_data *attr)
    923 {
    924 	vchar_t *buffer;
    925 	size_t len = 0;
    926 
    927 	if ((ntohs(attr->type) & ISAKMP_GEN_MASK) == ISAKMP_GEN_TLV)
    928 		len = ntohs(attr->lorv);
    929 
    930 	if ((buffer = vmalloc(sizeof(*attr) + len)) == NULL) {
    931 		plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
    932 		return NULL;
    933 	}
    934 
    935 	memcpy(buffer->v, attr, sizeof(*attr) + ntohs(attr->lorv));
    936 
    937 	return buffer;
    938 }
    939 
    940 /*ARGSUSED*/
    941 vchar_t *
    942 isakmp_cfg_short(struct ph1handle *iph1 __unused, struct isakmp_data *attr, int value)
    943 {
    944 	vchar_t *buffer;
    945 	struct isakmp_data *new;
    946 	int type;
    947 
    948 	if ((buffer = vmalloc(sizeof(*attr))) == NULL) {
    949 		plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
    950 		return NULL;
    951 	}
    952 
    953 	new = (struct isakmp_data *)buffer->v;
    954 	type = ntohs(attr->type) & ~ISAKMP_GEN_MASK;
    955 
    956 	new->type = htons(type | ISAKMP_GEN_TV);
    957 	new->lorv = htons(value);
    958 
    959 	return buffer;
    960 }
    961 
    962 /*ARGSUSED*/
    963 vchar_t *
    964 isakmp_cfg_varlen(struct ph1handle *iph1 __unused, struct isakmp_data *attr,
    965     const char *string, size_t len)
    966 {
    967 	vchar_t *buffer;
    968 	struct isakmp_data *new;
    969 	char *data;
    970 
    971 	if (!len)
    972 		return NULL;
    973 
    974 	if ((buffer = vmalloc(sizeof(*attr) + len)) == NULL) {
    975 		plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
    976 		return NULL;
    977 	}
    978 
    979 	new = (struct isakmp_data *)buffer->v;
    980 
    981 	new->type = attr->type;
    982 	new->lorv = htons(len);
    983 	data = (char *)(new + 1);
    984 
    985 	memcpy(data, string, len);
    986 
    987 	return buffer;
    988 }
    989 
    990 vchar_t *
    991 isakmp_cfg_string(struct ph1handle *iph1, struct isakmp_data *attr,
    992     const char *string)
    993 {
    994 	size_t len = strlen(string);
    995 	return isakmp_cfg_varlen(iph1, attr, string, len);
    996 }
    997 
    998 /*ARGSUSED*/
    999 static vchar_t *
   1000 isakmp_cfg_addr4(struct ph1handle *iph1 __unused, struct isakmp_data *attr,
   1001     in_addr_t *addr)
   1002 {
   1003 	vchar_t *buffer;
   1004 	struct isakmp_data *new;
   1005 	size_t len;
   1006 
   1007 	len = sizeof(*addr);
   1008 	if ((buffer = vmalloc(sizeof(*attr) + len)) == NULL) {
   1009 		plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
   1010 		return NULL;
   1011 	}
   1012 
   1013 	new = (struct isakmp_data *)buffer->v;
   1014 
   1015 	new->type = attr->type;
   1016 	new->lorv = htons(len);
   1017 	memcpy(new + 1, addr, len);
   1018 
   1019 	return buffer;
   1020 }
   1021 
   1022 /*ARGSUSED*/
   1023 static vchar_t *
   1024 isakmp_cfg_addrnet4(struct ph1handle *iph1 __unused, struct isakmp_data *attr,
   1025     in_addr_t *addr, in_addr_t *mask)
   1026 {
   1027 	vchar_t *buffer;
   1028 	struct isakmp_data *new;
   1029 	size_t len;
   1030 	in_addr_t netbuff[2];
   1031 
   1032 	len = sizeof(netbuff);
   1033 	if ((buffer = vmalloc(sizeof(*attr) + len)) == NULL) {
   1034 		plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
   1035 		return NULL;
   1036 	}
   1037 
   1038 	new = (struct isakmp_data *)buffer->v;
   1039 
   1040 	new->type = attr->type;
   1041 	new->lorv = htons(len);
   1042 	netbuff[0]=*addr;
   1043 	netbuff[1]=*mask;
   1044 	memcpy(new + 1, netbuff, len);
   1045 
   1046 	return buffer;
   1047 }
   1048 
   1049 
   1050 /*ARGSUSED*/
   1051 static vchar_t *
   1052 isakmp_cfg_addr4_list(struct ph1handle *iph1 __unused, struct isakmp_data *attr,
   1053     in_addr_t *addr, int nbr)
   1054 {
   1055 	int error = -1;
   1056 	vchar_t *buffer = NULL;
   1057 	vchar_t *bufone = NULL;
   1058 	struct isakmp_data *new;
   1059 	size_t len;
   1060 	int i;
   1061 
   1062 	len = sizeof(*addr);
   1063 	if ((buffer = vmalloc(0)) == NULL) {
   1064 		plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
   1065 		goto out;
   1066 	}
   1067 	for(i = 0; i < nbr; i++) {
   1068 		if ((bufone = vmalloc(sizeof(*attr) + len)) == NULL) {
   1069 			plog(LLV_ERROR, LOCATION, NULL,
   1070 			    "Cannot allocate memory\n");
   1071 			goto out;
   1072 		}
   1073 		new = (struct isakmp_data *)bufone->v;
   1074 		new->type = attr->type;
   1075 		new->lorv = htons(len);
   1076 		memcpy(new + 1, &addr[i], len);
   1077 		new += (len + sizeof(*attr));
   1078 		buffer = buffer_cat(buffer, bufone);
   1079 		vfree(bufone);
   1080 	}
   1081 
   1082 	error = 0;
   1083 
   1084 out:
   1085 	if ((error != 0) && (buffer != NULL)) {
   1086 		vfree(buffer);
   1087 		buffer = NULL;
   1088 	}
   1089 
   1090 	return buffer;
   1091 }
   1092 
   1093 struct isakmp_ivm *
   1094 isakmp_cfg_newiv(struct ph1handle *iph1, uint32_t msgid)
   1095 {
   1096 	struct isakmp_cfg_state *ics = iph1->mode_cfg;
   1097 
   1098 	if (ics == NULL) {
   1099 		plog(LLV_ERROR, LOCATION, NULL,
   1100 		    "isakmp_cfg_newiv called without mode config state\n");
   1101 		return NULL;
   1102 	}
   1103 
   1104 	if (ics->ivm != NULL)
   1105 		oakley_delivm(ics->ivm);
   1106 
   1107 	ics->ivm = oakley_newiv2(iph1, msgid);
   1108 	ics->last_msgid = msgid;
   1109 
   1110 	return ics->ivm;
   1111 }
   1112 
   1113 /* Derived from isakmp_info_send_common */
   1114 int
   1115 isakmp_cfg_send(struct ph1handle *iph1, vchar_t *payload, uint32_t np,
   1116     int flags, int new_exchange)
   1117 {
   1118 	struct ph2handle *iph2 = NULL;
   1119 	vchar_t *hash = NULL;
   1120 	struct isakmp *isakmp;
   1121 	struct isakmp_gen *gen;
   1122 	char *p;
   1123 	size_t tlen;
   1124 	int error = -1;
   1125 	struct isakmp_cfg_state *ics = iph1->mode_cfg;
   1126 
   1127 	/* Check if phase 1 is established */
   1128 	if ((iph1->status < PHASE1ST_ESTABLISHED) ||
   1129 	    (iph1->local == NULL) ||
   1130 	    (iph1->remote == NULL)) {
   1131 		plog(LLV_ERROR, LOCATION, NULL,
   1132 		    "ISAKMP mode config exchange with immature phase 1\n");
   1133 		goto end;
   1134 	}
   1135 
   1136 	/* add new entry to isakmp status table */
   1137 	iph2 = newph2();
   1138 	if (iph2 == NULL)
   1139 		goto end;
   1140 
   1141 	iph2->dst = dupsaddr(iph1->remote);
   1142 	if (iph2->dst == NULL) {
   1143 		delph2(iph2);
   1144 		goto end;
   1145 	}
   1146 	iph2->src = dupsaddr(iph1->local);
   1147 	if (iph2->src == NULL) {
   1148 		delph2(iph2);
   1149 		goto end;
   1150 	}
   1151 
   1152 	iph2->side = INITIATOR;
   1153 	iph2->status = PHASE2ST_START;
   1154 
   1155 	if (new_exchange)
   1156 		iph2->msgid = isakmp_newmsgid2(iph1);
   1157 	else
   1158 		iph2->msgid = iph1->msgid;
   1159 
   1160 	/* get IV and HASH(1) if skeyid_a was generated. */
   1161 	if (iph1->skeyid_a != NULL) {
   1162 		if (new_exchange) {
   1163 			if (isakmp_cfg_newiv(iph1, iph2->msgid) == NULL) {
   1164 				delph2(iph2);
   1165 				goto end;
   1166 			}
   1167 		}
   1168 
   1169 		/* generate HASH(1) */
   1170 		hash = oakley_compute_hash1(iph1, iph2->msgid, payload);
   1171 		if (hash == NULL) {
   1172 			delph2(iph2);
   1173 			goto end;
   1174 		}
   1175 
   1176 		/* initialized total buffer length */
   1177 		tlen = hash->l;
   1178 		tlen += sizeof(*gen);
   1179 	} else {
   1180 		/* IKE-SA is not established */
   1181 		hash = NULL;
   1182 
   1183 		/* initialized total buffer length */
   1184 		tlen = 0;
   1185 	}
   1186 	if ((flags & ISAKMP_FLAG_A) == 0)
   1187 		iph2->flags = (hash == NULL ? 0 : ISAKMP_FLAG_E);
   1188 	else
   1189 		iph2->flags = (hash == NULL ? 0 : ISAKMP_FLAG_A);
   1190 
   1191 	insph2(iph2);
   1192 	bindph12(iph1, iph2);
   1193 
   1194 	tlen += sizeof(*isakmp) + payload->l;
   1195 
   1196 	/* create buffer for isakmp payload */
   1197 	iph2->sendbuf = vmalloc(tlen);
   1198 	if (iph2->sendbuf == NULL) {
   1199 		plog(LLV_ERROR, LOCATION, NULL,
   1200 			"failed to get buffer to send.\n");
   1201 		goto err;
   1202 	}
   1203 
   1204 	/* create isakmp header */
   1205 	isakmp = (struct isakmp *)iph2->sendbuf->v;
   1206 	memcpy(&isakmp->i_ck, &iph1->index.i_ck, sizeof(cookie_t));
   1207 	memcpy(&isakmp->r_ck, &iph1->index.r_ck, sizeof(cookie_t));
   1208 	isakmp->np = hash == NULL ? (np & 0xff) : ISAKMP_NPTYPE_HASH;
   1209 	isakmp->v = iph1->version;
   1210 	isakmp->etype = ISAKMP_ETYPE_CFG;
   1211 	isakmp->flags = iph2->flags;
   1212 	memcpy(&isakmp->msgid, &iph2->msgid, sizeof(isakmp->msgid));
   1213 	isakmp->len = htonl(tlen);
   1214 	p = (char *)(isakmp + 1);
   1215 
   1216 	/* create HASH payload */
   1217 	if (hash != NULL) {
   1218 		gen = (struct isakmp_gen *)p;
   1219 		gen->np = np & 0xff;
   1220 		gen->len = htons(sizeof(*gen) + hash->l);
   1221 		p += sizeof(*gen);
   1222 		memcpy(p, hash->v, hash->l);
   1223 		p += hash->l;
   1224 	}
   1225 
   1226 	/* add payload */
   1227 	memcpy(p, payload->v, payload->l);
   1228 	p += payload->l;
   1229 
   1230 #ifdef HAVE_PRINT_ISAKMP_C
   1231 	isakmp_printpacket(iph2->sendbuf, iph1->local, iph1->remote, 1);
   1232 #endif
   1233 
   1234 	plog(LLV_DEBUG, LOCATION, NULL, "MODE_CFG packet to send\n");
   1235 	plogdump(LLV_DEBUG, iph2->sendbuf->v, iph2->sendbuf->l);
   1236 
   1237 	/* encoding */
   1238 	if (ISSET(isakmp->flags, ISAKMP_FLAG_E)) {
   1239 		vchar_t *tmp;
   1240 
   1241 		tmp = oakley_do_encrypt(iph2->ph1, iph2->sendbuf,
   1242 			ics->ivm->ive, ics->ivm->iv);
   1243 		VPTRINIT(iph2->sendbuf);
   1244 		if (tmp == NULL)
   1245 			goto err;
   1246 		iph2->sendbuf = tmp;
   1247 	}
   1248 
   1249 	/* HDR*, HASH(1), ATTR */
   1250 	if (isakmp_send(iph2->ph1, iph2->sendbuf) < 0) {
   1251 		VPTRINIT(iph2->sendbuf);
   1252 		goto err;
   1253 	}
   1254 
   1255 	plog(LLV_DEBUG, LOCATION, NULL,
   1256 		"sendto mode config %s.\n", s_isakmp_nptype(np));
   1257 
   1258 	/*
   1259 	 * XXX We might need to resend the message...
   1260 	 */
   1261 
   1262 	error = 0;
   1263 	VPTRINIT(iph2->sendbuf);
   1264 
   1265 err:
   1266 	if (iph2->sendbuf != NULL)
   1267 		vfree(iph2->sendbuf);
   1268 
   1269 	remph2(iph2);
   1270 	delph2(iph2);
   1271 end:
   1272 	if (hash)
   1273 		vfree(hash);
   1274 	return error;
   1275 }
   1276 
   1277 
   1278 void
   1279 isakmp_cfg_rmstate(struct ph1handle *iph1)
   1280 {
   1281 	struct isakmp_cfg_state *state = iph1->mode_cfg;
   1282 
   1283 	if (isakmp_cfg_accounting(iph1, ISAKMP_CFG_LOGOUT) != 0)
   1284 		plog(LLV_ERROR, LOCATION, NULL, "Accounting failed\n");
   1285 
   1286 	if (state->flags & ISAKMP_CFG_PORT_ALLOCATED)
   1287 		isakmp_cfg_putport(iph1, state->port);
   1288 
   1289 	/* Delete the IV if it's still there */
   1290 	if(iph1->mode_cfg->ivm) {
   1291 		oakley_delivm(iph1->mode_cfg->ivm);
   1292 		iph1->mode_cfg->ivm = NULL;
   1293 	}
   1294 
   1295 	/* Free any allocated splitnet lists */
   1296 	if(iph1->mode_cfg->split_include != NULL)
   1297 		splitnet_list_free(iph1->mode_cfg->split_include,
   1298 			&iph1->mode_cfg->include_count);
   1299 	if(iph1->mode_cfg->split_local != NULL)
   1300 		splitnet_list_free(iph1->mode_cfg->split_local,
   1301 			&iph1->mode_cfg->local_count);
   1302 
   1303 	xauth_rmstate(&state->xauth);
   1304 
   1305 	racoon_free(state);
   1306 	iph1->mode_cfg = NULL;
   1307 
   1308 	return;
   1309 }
   1310 
   1311 struct isakmp_cfg_state *
   1312 isakmp_cfg_mkstate(void)
   1313 {
   1314 	struct isakmp_cfg_state *state;
   1315 
   1316 	if ((state = racoon_malloc(sizeof(*state))) == NULL) {
   1317 		plog(LLV_ERROR, LOCATION, NULL,
   1318 		    "Cannot allocate memory for mode config state\n");
   1319 		return NULL;
   1320 	}
   1321 	memset(state, 0, sizeof(*state));
   1322 
   1323 	return state;
   1324 }
   1325 
   1326 int
   1327 isakmp_cfg_getport(struct ph1handle *iph1)
   1328 {
   1329 	unsigned int i;
   1330 	size_t size = isakmp_cfg_config.pool_size;
   1331 
   1332 	if (iph1->mode_cfg->flags & ISAKMP_CFG_PORT_ALLOCATED)
   1333 		return iph1->mode_cfg->port;
   1334 
   1335 	if (isakmp_cfg_config.port_pool == NULL) {
   1336 		plog(LLV_ERROR, LOCATION, NULL,
   1337 		    "isakmp_cfg_config.port_pool == NULL\n");
   1338 		return -1;
   1339 	}
   1340 
   1341 	for (i = 0; i < size; i++) {
   1342 		if (isakmp_cfg_config.port_pool[i].used == 0)
   1343 			break;
   1344 	}
   1345 
   1346 	if (i == size) {
   1347 		plog(LLV_ERROR, LOCATION, NULL,
   1348 		    "No more addresses available\n");
   1349 			return -1;
   1350 	}
   1351 
   1352 	isakmp_cfg_config.port_pool[i].used = 1;
   1353 
   1354 	plog(LLV_INFO, LOCATION, NULL, "Using port %d\n", i);
   1355 
   1356 	iph1->mode_cfg->flags |= ISAKMP_CFG_PORT_ALLOCATED;
   1357 	iph1->mode_cfg->port = i;
   1358 
   1359 	return i;
   1360 }
   1361 
   1362 int
   1363 isakmp_cfg_putport(struct ph1handle *iph1, unsigned int index)
   1364 {
   1365 	if (isakmp_cfg_config.port_pool == NULL) {
   1366 		plog(LLV_ERROR, LOCATION, NULL,
   1367 		    "isakmp_cfg_config.port_pool == NULL\n");
   1368 		return -1;
   1369 	}
   1370 
   1371 	if (isakmp_cfg_config.port_pool[index].used == 0) {
   1372 		plog(LLV_ERROR, LOCATION, NULL,
   1373 		    "Attempt to release an unallocated address (port %d)\n",
   1374 		    index);
   1375 		return -1;
   1376 	}
   1377 
   1378 #ifdef HAVE_LIBPAM
   1379 	/* Cleanup PAM status associated with the port */
   1380 	if (isakmp_cfg_config.authsource == ISAKMP_CFG_AUTH_PAM)
   1381 		privsep_cleanup_pam(index);
   1382 #endif
   1383 	isakmp_cfg_config.port_pool[index].used = 0;
   1384 	iph1->mode_cfg->flags &= ISAKMP_CFG_PORT_ALLOCATED;
   1385 
   1386 	plog(LLV_INFO, LOCATION, NULL, "Released port %d\n", index);
   1387 
   1388 	return 0;
   1389 }
   1390 
   1391 #ifdef HAVE_LIBPAM
   1392 void
   1393 cleanup_pam(int port)
   1394 {
   1395 	if (isakmp_cfg_config.port_pool[port].pam != NULL) {
   1396 		pam_end(isakmp_cfg_config.port_pool[port].pam, PAM_SUCCESS);
   1397 		isakmp_cfg_config.port_pool[port].pam = NULL;
   1398 	}
   1399 
   1400 	return;
   1401 }
   1402 #endif
   1403 
   1404 /* Accounting, only for RADIUS or PAM */
   1405 static int
   1406 isakmp_cfg_accounting(struct ph1handle *iph1, int inout)
   1407 {
   1408 #ifdef HAVE_LIBPAM
   1409 	if (isakmp_cfg_config.accounting == ISAKMP_CFG_ACCT_PAM)
   1410 		return privsep_accounting_pam(iph1->mode_cfg->port,
   1411 		    inout);
   1412 #endif
   1413 #ifdef HAVE_LIBRADIUS
   1414 	if (isakmp_cfg_config.accounting == ISAKMP_CFG_ACCT_RADIUS)
   1415 		return isakmp_cfg_accounting_radius(iph1, inout);
   1416 #endif
   1417 	if (isakmp_cfg_config.accounting == ISAKMP_CFG_ACCT_SYSTEM)
   1418 		return privsep_accounting_system(iph1->mode_cfg->port,
   1419 			iph1->remote, iph1->mode_cfg->login, inout);
   1420 	return 0;
   1421 }
   1422 
   1423 #ifdef HAVE_LIBPAM
   1424 int
   1425 isakmp_cfg_accounting_pam(int port, int inout)
   1426 {
   1427 	int error = 0;
   1428 	pam_handle_t *pam;
   1429 
   1430 	if (isakmp_cfg_config.port_pool == NULL) {
   1431 		plog(LLV_ERROR, LOCATION, NULL,
   1432 		    "isakmp_cfg_config.port_pool == NULL\n");
   1433 		return -1;
   1434 	}
   1435 
   1436 	pam = isakmp_cfg_config.port_pool[port].pam;
   1437 	if (pam == NULL) {
   1438 		plog(LLV_ERROR, LOCATION, NULL, "pam handle is NULL\n");
   1439 		return -1;
   1440 	}
   1441 
   1442 	switch (inout) {
   1443 	case ISAKMP_CFG_LOGIN:
   1444 		error = pam_open_session(pam, 0);
   1445 		break;
   1446 	case ISAKMP_CFG_LOGOUT:
   1447 		error = pam_close_session(pam, 0);
   1448 		pam_end(pam, error);
   1449 		isakmp_cfg_config.port_pool[port].pam = NULL;
   1450 		break;
   1451 	default:
   1452 		plog(LLV_ERROR, LOCATION, NULL, "Unepected inout\n");
   1453 		break;
   1454 	}
   1455 
   1456 	if (error != 0) {
   1457 		plog(LLV_ERROR, LOCATION, NULL,
   1458 		    "pam_open_session/pam_close_session failed: %s\n",
   1459 		    pam_strerror(pam, error));
   1460 		return -1;
   1461         }
   1462 
   1463 	return 0;
   1464 }
   1465 #endif /* HAVE_LIBPAM */
   1466 
   1467 #ifdef HAVE_LIBRADIUS
   1468 static int
   1469 isakmp_cfg_accounting_radius(struct ph1handle *iph1, int inout)
   1470 {
   1471 	if (rad_create_request(radius_acct_state,
   1472 	    RAD_ACCOUNTING_REQUEST) != 0) {
   1473 		plog(LLV_ERROR, LOCATION, NULL,
   1474 		    "rad_create_request failed: %s\n",
   1475 		    rad_strerror(radius_acct_state));
   1476 		return -1;
   1477 	}
   1478 
   1479 	if (rad_put_string(radius_acct_state, RAD_USER_NAME,
   1480 	    iph1->mode_cfg->login) != 0) {
   1481 		plog(LLV_ERROR, LOCATION, NULL,
   1482 		    "rad_put_string failed: %s\n",
   1483 		    rad_strerror(radius_acct_state));
   1484 		return -1;
   1485 	}
   1486 
   1487 	switch (inout) {
   1488 	case ISAKMP_CFG_LOGIN:
   1489 		inout = RAD_START;
   1490 		break;
   1491 	case ISAKMP_CFG_LOGOUT:
   1492 		inout = RAD_STOP;
   1493 		break;
   1494 	default:
   1495 		plog(LLV_ERROR, LOCATION, NULL, "Unepected inout\n");
   1496 		break;
   1497 	}
   1498 
   1499 	if (rad_put_addr(radius_acct_state,
   1500 	    RAD_FRAMED_IP_ADDRESS, iph1->mode_cfg->addr4) != 0) {
   1501 		plog(LLV_ERROR, LOCATION, NULL,
   1502 		    "rad_put_addr failed: %s\n",
   1503 		    rad_strerror(radius_acct_state));
   1504 		return -1;
   1505 	}
   1506 
   1507 	if (rad_put_addr(radius_acct_state,
   1508 	    RAD_LOGIN_IP_HOST, iph1->mode_cfg->addr4) != 0) {
   1509 		plog(LLV_ERROR, LOCATION, NULL,
   1510 		    "rad_put_addr failed: %s\n",
   1511 		    rad_strerror(radius_acct_state));
   1512 		return -1;
   1513 	}
   1514 
   1515 	if (rad_put_int(radius_acct_state, RAD_ACCT_STATUS_TYPE, inout) != 0) {
   1516 		plog(LLV_ERROR, LOCATION, NULL,
   1517 		    "rad_put_int failed: %s\n",
   1518 		    rad_strerror(radius_acct_state));
   1519 		return -1;
   1520 	}
   1521 
   1522 	if (isakmp_cfg_radius_common(radius_acct_state,
   1523 	    iph1->mode_cfg->port) != 0)
   1524 		return -1;
   1525 
   1526 	if (rad_send_request(radius_acct_state) != RAD_ACCOUNTING_RESPONSE) {
   1527 		plog(LLV_ERROR, LOCATION, NULL,
   1528 		    "rad_send_request failed: %s\n",
   1529 		    rad_strerror(radius_acct_state));
   1530 		return -1;
   1531 	}
   1532 
   1533 	return 0;
   1534 }
   1535 #endif /* HAVE_LIBRADIUS */
   1536 
   1537 /*
   1538  * Attributes common to all RADIUS requests
   1539  */
   1540 #ifdef HAVE_LIBRADIUS
   1541 int
   1542 isakmp_cfg_radius_common(struct rad_handle *radius_state, int port)
   1543 {
   1544 	struct utsname name;
   1545 	static struct hostent *host = NULL;
   1546 	struct in_addr nas_addr;
   1547 
   1548 	/*
   1549 	 * Find our own IP by resolving our nodename
   1550 	 */
   1551 	if (host == NULL) {
   1552 		if (uname(&name) != 0) {
   1553 			plog(LLV_ERROR, LOCATION, NULL,
   1554 			    "uname failed: %s\n", strerror(errno));
   1555 			return -1;
   1556 		}
   1557 
   1558 		if ((host = gethostbyname(name.nodename)) == NULL) {
   1559 			plog(LLV_ERROR, LOCATION, NULL,
   1560 			    "gethostbyname failed: %s\n", strerror(errno));
   1561 			return -1;
   1562 		}
   1563 	}
   1564 
   1565 	memcpy(&nas_addr, host->h_addr, sizeof(nas_addr));
   1566 	if (rad_put_addr(radius_state, RAD_NAS_IP_ADDRESS, nas_addr) != 0) {
   1567 		plog(LLV_ERROR, LOCATION, NULL,
   1568 		    "rad_put_addr failed: %s\n",
   1569 		    rad_strerror(radius_state));
   1570 		return -1;
   1571 	}
   1572 
   1573 	if (rad_put_int(radius_state, RAD_NAS_PORT, port) != 0) {
   1574 		plog(LLV_ERROR, LOCATION, NULL,
   1575 		    "rad_put_int failed: %s\n",
   1576 		    rad_strerror(radius_state));
   1577 		return -1;
   1578 	}
   1579 
   1580 	if (rad_put_int(radius_state, RAD_NAS_PORT_TYPE, RAD_VIRTUAL) != 0) {
   1581 		plog(LLV_ERROR, LOCATION, NULL,
   1582 		    "rad_put_int failed: %s\n",
   1583 		    rad_strerror(radius_state));
   1584 		return -1;
   1585 	}
   1586 
   1587 	if (rad_put_int(radius_state, RAD_SERVICE_TYPE, RAD_FRAMED) != 0) {
   1588 		plog(LLV_ERROR, LOCATION, NULL,
   1589 		    "rad_put_int failed: %s\n",
   1590 		    rad_strerror(radius_state));
   1591 		return -1;
   1592 	}
   1593 
   1594 	return 0;
   1595 }
   1596 #endif
   1597 
   1598 /*
   1599 	Logs the user into the utmp system files.
   1600 */
   1601 
   1602 int
   1603 isakmp_cfg_accounting_system(int port, struct sockaddr *raddr, char *usr,
   1604     int inout)
   1605 {
   1606 	struct utmpx ut;
   1607 	char addr[NI_MAXHOST];
   1608 
   1609 	if (usr == NULL || usr[0]=='\0') {
   1610 		plog(LLV_ERROR, LOCATION, NULL,
   1611 			"system accounting : no login found\n");
   1612 		return -1;
   1613 	}
   1614 
   1615 	memset(&ut, 0, sizeof ut);
   1616 	gettimeofday((struct timeval *)&ut.ut_tv, NULL);
   1617 	snprintf(ut.ut_id, sizeof ut.ut_id, TERMSPEC, port);
   1618 
   1619 	switch (inout) {
   1620 	case ISAKMP_CFG_LOGIN:
   1621 		ut.ut_type = USER_PROCESS;
   1622 		strncpy(ut.ut_user, usr, sizeof ut.ut_user);
   1623 
   1624 		GETNAMEINFO_NULL(raddr, addr);
   1625 		strncpy(ut.ut_host, addr, sizeof ut.ut_host);
   1626 
   1627 		plog(LLV_INFO, LOCATION, NULL,
   1628 			"Accounting : '%s' logging on '%s' from %s.\n",
   1629 			ut.ut_user, ut.ut_id, addr);
   1630 
   1631 		pututxline(&ut);
   1632 
   1633 		break;
   1634 	case ISAKMP_CFG_LOGOUT:
   1635 		ut.ut_type = DEAD_PROCESS;
   1636 
   1637 		plog(LLV_INFO, LOCATION, NULL,
   1638 			"Accounting : '%s' unlogging from '%s'.\n",
   1639 			usr, ut.ut_id);
   1640 
   1641 		pututxline(&ut);
   1642 
   1643 		break;
   1644 	default:
   1645 		plog(LLV_ERROR, LOCATION, NULL, "Unepected inout\n");
   1646 		break;
   1647 	}
   1648 
   1649 	return 0;
   1650 }
   1651 
   1652 int
   1653 isakmp_cfg_getconfig(struct ph1handle *iph1)
   1654 {
   1655 	vchar_t *buffer;
   1656 	struct isakmp_pl_attr *attrpl;
   1657 	struct isakmp_data *attr;
   1658 	size_t len;
   1659 	int error;
   1660 	int attrcount;
   1661 	int i;
   1662 	int attrlist[] = {
   1663 		INTERNAL_IP4_ADDRESS,
   1664 		INTERNAL_IP4_NETMASK,
   1665 		INTERNAL_IP4_DNS,
   1666 		INTERNAL_IP4_NBNS,
   1667 		UNITY_BANNER,
   1668 		UNITY_DEF_DOMAIN,
   1669 		UNITY_SPLITDNS_NAME,
   1670 		UNITY_SPLIT_INCLUDE,
   1671 		UNITY_LOCAL_LAN,
   1672 		APPLICATION_VERSION,
   1673 	};
   1674 
   1675 	attrcount = sizeof(attrlist) / sizeof(*attrlist);
   1676 	len = sizeof(*attrpl) + sizeof(*attr) * attrcount;
   1677 
   1678 	if ((buffer = vmalloc(len)) == NULL) {
   1679 		plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
   1680 		return -1;
   1681 	}
   1682 
   1683 	attrpl = (struct isakmp_pl_attr *)buffer->v;
   1684 	attrpl->h.len = htons(len);
   1685 	attrpl->type = ISAKMP_CFG_REQUEST;
   1686 	attrpl->id = htons((uint16_t)(eay_random() & 0xffff));
   1687 
   1688 	attr = (struct isakmp_data *)(attrpl + 1);
   1689 
   1690 	for (i = 0; i < attrcount; i++) {
   1691 		attr->type = htons(attrlist[i]);
   1692 		attr->lorv = htons(0);
   1693 		attr++;
   1694 	}
   1695 
   1696 	plog(LLV_DEBUG, LOCATION, NULL,
   1697 		    "Sending MODE_CFG REQUEST\n");
   1698 
   1699 	error = isakmp_cfg_send(iph1, buffer,
   1700 	    ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 1);
   1701 
   1702 	vfree(buffer);
   1703 
   1704 	return error;
   1705 }
   1706 
   1707 static void
   1708 isakmp_cfg_getaddr4(struct isakmp_data *attr, struct in_addr *ip)
   1709 {
   1710 	size_t alen = ntohs(attr->lorv);
   1711 	in_addr_t *addr;
   1712 
   1713 	if (alen != sizeof(*ip)) {
   1714 		plog(LLV_ERROR, LOCATION, NULL, "Bad IPv4 address len\n");
   1715 		return;
   1716 	}
   1717 
   1718 	addr = (in_addr_t *)(attr + 1);
   1719 	ip->s_addr = *addr;
   1720 
   1721 	return;
   1722 }
   1723 
   1724 static void
   1725 isakmp_cfg_appendaddr4(struct isakmp_data *attr, struct in_addr *ip,
   1726     int *num, int max)
   1727 {
   1728 	size_t alen = ntohs(attr->lorv);
   1729 	in_addr_t *addr;
   1730 
   1731 	if (alen != sizeof(*ip)) {
   1732 		plog(LLV_ERROR, LOCATION, NULL, "Bad IPv4 address len\n");
   1733 		return;
   1734 	}
   1735 	if (*num == max) {
   1736 		plog(LLV_ERROR, LOCATION, NULL, "Too many addresses given\n");
   1737 		return;
   1738 	}
   1739 
   1740 	addr = (in_addr_t *)(attr + 1);
   1741 	ip->s_addr = *addr;
   1742 	(*num)++;
   1743 
   1744 	return;
   1745 }
   1746 
   1747 static void
   1748 isakmp_cfg_getstring(struct isakmp_data *attr, char *str)
   1749 {
   1750 	size_t alen = ntohs(attr->lorv);
   1751 	char *src;
   1752 	src = (char *)(attr + 1);
   1753 
   1754 	memcpy(str, src, (alen > MAXPATHLEN ? MAXPATHLEN : alen));
   1755 
   1756 	return;
   1757 }
   1758 
   1759 #define IP_MAX 40
   1760 
   1761 void
   1762 isakmp_cfg_iplist_to_str(char *dest, int count, void *addr, int withmask)
   1763 {
   1764 	int i;
   1765 	size_t p;
   1766 	int l;
   1767 	struct unity_network tmp;
   1768 	for(i = 0, p = 0; i < count; i++) {
   1769 		if(withmask == 1)
   1770 			l = sizeof(struct unity_network);
   1771 		else
   1772 			l = sizeof(struct in_addr);
   1773 		memcpy(&tmp, addr, l);
   1774 		addr = (char *)addr + l;
   1775 		if((uint32_t)tmp.addr4.s_addr == 0)
   1776 			break;
   1777 
   1778 		inet_ntop(AF_INET, &tmp.addr4, dest + p, IP_MAX);
   1779 		p += strlen(dest + p);
   1780 		if(withmask == 1) {
   1781 			dest[p] = '/';
   1782 			p++;
   1783 			inet_ntop(AF_INET, &tmp.mask4, dest + p, IP_MAX);
   1784 			p += strlen(dest + p);
   1785 		}
   1786 		dest[p] = ' ';
   1787 		p++;
   1788 	}
   1789 	if(p > 0)
   1790 		dest[p-1] = '\0';
   1791 	else
   1792 		dest[0] = '\0';
   1793 }
   1794 
   1795 int
   1796 isakmp_cfg_setenv(struct ph1handle *iph1, char ***envp, int *envc)
   1797 {
   1798 	char addrstr[IP_MAX];
   1799 	char addrlist[IP_MAX * MAXNS + MAXNS];
   1800 	char *splitlist = addrlist;
   1801 	char *splitlist_cidr;
   1802 	char defdom[MAXPATHLEN + 1];
   1803 	int cidr, tmp;
   1804 	char cidrstr[4];
   1805 
   1806 	plog(LLV_DEBUG, LOCATION, NULL, "Starting a script.\n");
   1807 
   1808 	/*
   1809 	 * Internal IPv4 address, either if
   1810 	 * we are a client or a server.
   1811 	 */
   1812 	if ((iph1->mode_cfg->flags & ISAKMP_CFG_GOT_ADDR4) ||
   1813 #ifdef HAVE_LIBLDAP
   1814 	    (iph1->mode_cfg->flags & ISAKMP_CFG_ADDR4_EXTERN) ||
   1815 #endif
   1816 #ifdef HAVE_LIBRADIUS
   1817 	    (iph1->mode_cfg->flags & ISAKMP_CFG_ADDR4_EXTERN) ||
   1818 #endif
   1819 	    (iph1->mode_cfg->flags & ISAKMP_CFG_ADDR4_LOCAL)) {
   1820 		inet_ntop(AF_INET, &iph1->mode_cfg->addr4,
   1821 		    addrstr, IP_MAX);
   1822 	} else
   1823 		addrstr[0] = '\0';
   1824 
   1825 	if (script_env_append(envp, envc, "INTERNAL_ADDR4", addrstr) != 0) {
   1826 		plog(LLV_ERROR, LOCATION, NULL, "Cannot set INTERNAL_ADDR4\n");
   1827 		return -1;
   1828 	}
   1829 
   1830 	if (iph1->mode_cfg->xauth.authdata.generic.usr != NULL) {
   1831 		if (script_env_append(envp, envc, "XAUTH_USER",
   1832 		    iph1->mode_cfg->xauth.authdata.generic.usr) != 0) {
   1833 			plog(LLV_ERROR, LOCATION, NULL,
   1834 			    "Cannot set XAUTH_USER\n");
   1835 			return -1;
   1836 		}
   1837 	}
   1838 
   1839 	/* Internal IPv4 mask */
   1840 	if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_MASK4)
   1841 		inet_ntop(AF_INET, &iph1->mode_cfg->mask4,
   1842 		    addrstr, IP_MAX);
   1843 	else
   1844 		addrstr[0] = '\0';
   1845 
   1846 	/*
   1847 	 * During several releases, documentation adverised INTERNAL_NETMASK4
   1848 	 * while code was using INTERNAL_MASK4. We now do both.
   1849 	 */
   1850 
   1851 	if (script_env_append(envp, envc, "INTERNAL_MASK4", addrstr) != 0) {
   1852 		plog(LLV_ERROR, LOCATION, NULL, "Cannot set INTERNAL_MASK4\n");
   1853 		return -1;
   1854 	}
   1855 
   1856 	if (script_env_append(envp, envc, "INTERNAL_NETMASK4", addrstr) != 0) {
   1857 		plog(LLV_ERROR, LOCATION, NULL,
   1858 		    "Cannot set INTERNAL_NETMASK4\n");
   1859 		return -1;
   1860 	}
   1861 
   1862 	tmp = ntohl(iph1->mode_cfg->mask4.s_addr);
   1863 	for (cidr = 0; tmp != 0; cidr++)
   1864 		tmp <<= 1;
   1865 	snprintf(cidrstr, 3, "%d", cidr);
   1866 
   1867 	if (script_env_append(envp, envc, "INTERNAL_CIDR4", cidrstr) != 0) {
   1868 		plog(LLV_ERROR, LOCATION, NULL, "Cannot set INTERNAL_CIDR4\n");
   1869 		return -1;
   1870 	}
   1871 
   1872 	/* Internal IPv4 DNS */
   1873 	if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_DNS4) {
   1874 		/* First Internal IPv4 DNS (for compatibilty with older code */
   1875 		inet_ntop(AF_INET, &iph1->mode_cfg->dns4[0],
   1876 		    addrstr, IP_MAX);
   1877 
   1878 		/* Internal IPv4 DNS - all */
   1879 		isakmp_cfg_iplist_to_str(addrlist, iph1->mode_cfg->dns4_index,
   1880 			(void *)iph1->mode_cfg->dns4, 0);
   1881 	} else {
   1882 		addrstr[0] = '\0';
   1883 		addrlist[0] = '\0';
   1884 	}
   1885 
   1886 	if (script_env_append(envp, envc, "INTERNAL_DNS4", addrstr) != 0) {
   1887 		plog(LLV_ERROR, LOCATION, NULL, "Cannot set INTERNAL_DNS4\n");
   1888 		return -1;
   1889 	}
   1890 	if (script_env_append(envp, envc, "INTERNAL_DNS4_LIST", addrlist) != 0) {
   1891 		plog(LLV_ERROR, LOCATION, NULL,
   1892 		    "Cannot set INTERNAL_DNS4_LIST\n");
   1893 		return -1;
   1894 	}
   1895 
   1896 	/* Internal IPv4 WINS */
   1897 	if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_WINS4) {
   1898 		/*
   1899 		 * First Internal IPv4 WINS
   1900 		 * (for compatibilty with older code
   1901 		 */
   1902 		inet_ntop(AF_INET, &iph1->mode_cfg->wins4[0],
   1903 		    addrstr, IP_MAX);
   1904 
   1905 		/* Internal IPv4 WINS - all */
   1906 		isakmp_cfg_iplist_to_str(addrlist, iph1->mode_cfg->wins4_index,
   1907 			(void *)iph1->mode_cfg->wins4, 0);
   1908 	} else {
   1909 		addrstr[0] = '\0';
   1910 		addrlist[0] = '\0';
   1911 	}
   1912 
   1913 	if (script_env_append(envp, envc, "INTERNAL_WINS4", addrstr) != 0) {
   1914 		plog(LLV_ERROR, LOCATION, NULL,
   1915 		    "Cannot set INTERNAL_WINS4\n");
   1916 		return -1;
   1917 	}
   1918 	if (script_env_append(envp, envc,
   1919 	    "INTERNAL_WINS4_LIST", addrlist) != 0) {
   1920 		plog(LLV_ERROR, LOCATION, NULL,
   1921 		    "Cannot set INTERNAL_WINS4_LIST\n");
   1922 		return -1;
   1923 	}
   1924 
   1925 	/* Default domain */
   1926 	if(iph1->mode_cfg->flags & ISAKMP_CFG_GOT_DEFAULT_DOMAIN)
   1927 		strncpy(defdom,
   1928 		    iph1->mode_cfg->default_domain,
   1929 		    MAXPATHLEN + 1);
   1930 	else
   1931 		defdom[0] = '\0';
   1932 
   1933 	if (script_env_append(envp, envc, "DEFAULT_DOMAIN", defdom) != 0) {
   1934 		plog(LLV_ERROR, LOCATION, NULL,
   1935 		    "Cannot set DEFAULT_DOMAIN\n");
   1936 		return -1;
   1937 	}
   1938 
   1939 	/* Split networks */
   1940 	if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_SPLIT_INCLUDE) {
   1941 		splitlist =
   1942 		    splitnet_list_2str(iph1->mode_cfg->split_include, NETMASK);
   1943 		splitlist_cidr =
   1944 		    splitnet_list_2str(iph1->mode_cfg->split_include, CIDR);
   1945 	} else {
   1946 		splitlist = addrlist;
   1947 		splitlist_cidr = addrlist;
   1948 		addrlist[0] = '\0';
   1949 	}
   1950 
   1951 	if (script_env_append(envp, envc, "SPLIT_INCLUDE", splitlist) != 0) {
   1952 		plog(LLV_ERROR, LOCATION, NULL, "Cannot set SPLIT_INCLUDE\n");
   1953 		return -1;
   1954 	}
   1955 	if (script_env_append(envp, envc,
   1956 	    "SPLIT_INCLUDE_CIDR", splitlist_cidr) != 0) {
   1957 		plog(LLV_ERROR, LOCATION, NULL,
   1958 		     "Cannot set SPLIT_INCLUDE_CIDR\n");
   1959 		return -1;
   1960 	}
   1961 	if (splitlist != addrlist)
   1962 		racoon_free(splitlist);
   1963 	if (splitlist_cidr != addrlist)
   1964 		racoon_free(splitlist_cidr);
   1965 
   1966 	if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_SPLIT_LOCAL) {
   1967 		splitlist =
   1968 		    splitnet_list_2str(iph1->mode_cfg->split_local, NETMASK);
   1969 		splitlist_cidr =
   1970 		    splitnet_list_2str(iph1->mode_cfg->split_local, CIDR);
   1971 	} else {
   1972 		splitlist = addrlist;
   1973 		splitlist_cidr = addrlist;
   1974 		addrlist[0] = '\0';
   1975 	}
   1976 
   1977 	if (script_env_append(envp, envc, "SPLIT_LOCAL", splitlist) != 0) {
   1978 		plog(LLV_ERROR, LOCATION, NULL, "Cannot set SPLIT_LOCAL\n");
   1979 		return -1;
   1980 	}
   1981 	if (script_env_append(envp, envc,
   1982 	    "SPLIT_LOCAL_CIDR", splitlist_cidr) != 0) {
   1983 		plog(LLV_ERROR, LOCATION, NULL,
   1984 		     "Cannot set SPLIT_LOCAL_CIDR\n");
   1985 		return -1;
   1986 	}
   1987 	if (splitlist != addrlist)
   1988 		racoon_free(splitlist);
   1989 	if (splitlist_cidr != addrlist)
   1990 		racoon_free(splitlist_cidr);
   1991 
   1992 	return 0;
   1993 }
   1994 
   1995 int
   1996 isakmp_cfg_resize_pool(int size)
   1997 {
   1998 	struct isakmp_cfg_port *new_pool;
   1999 	size_t len;
   2000 	size_t i;
   2001 
   2002 	if (size == isakmp_cfg_config.pool_size)
   2003 		return 0;
   2004 
   2005 	plog(LLV_INFO, LOCATION, NULL,
   2006 	    "Resize address pool from %zu to %d\n",
   2007 	    isakmp_cfg_config.pool_size, size);
   2008 
   2009 	/* If a pool already exists, check if we can shrink it */
   2010 	if ((isakmp_cfg_config.port_pool != NULL) &&
   2011 	    (size < isakmp_cfg_config.pool_size)) {
   2012 		for (i = isakmp_cfg_config.pool_size-1; i >= size; --i) {
   2013 			if (isakmp_cfg_config.port_pool[i].used) {
   2014 				plog(LLV_ERROR, LOCATION, NULL,
   2015 				    "resize pool from %zu to %d impossible "
   2016 				    "port %zu is in use\n",
   2017 				    isakmp_cfg_config.pool_size, size, i);
   2018 				size = i;
   2019 				break;
   2020 			}
   2021 		}
   2022 	}
   2023 
   2024 	len = size * sizeof(*isakmp_cfg_config.port_pool);
   2025 	new_pool = racoon_realloc(isakmp_cfg_config.port_pool, len);
   2026 	if (new_pool == NULL) {
   2027 		plog(LLV_ERROR, LOCATION, NULL,
   2028 		    "resize pool from %zu to %d impossible: %s",
   2029 		    isakmp_cfg_config.pool_size, size, strerror(errno));
   2030 		return -1;
   2031 	}
   2032 
   2033 	/* If size increase, intialize correctly the new records */
   2034 	if (size > isakmp_cfg_config.pool_size) {
   2035 		size_t unit;
   2036 		size_t old_size;
   2037 
   2038 		unit =  sizeof(*isakmp_cfg_config.port_pool);
   2039 		old_size = isakmp_cfg_config.pool_size;
   2040 
   2041 		bzero((char *)new_pool + (old_size * unit),
   2042 		    (size - old_size) * unit);
   2043 	}
   2044 
   2045 	isakmp_cfg_config.port_pool = new_pool;
   2046 	isakmp_cfg_config.pool_size = size;
   2047 
   2048 	return 0;
   2049 }
   2050 
   2051 int
   2052 isakmp_cfg_init(int cold)
   2053 {
   2054 	int i;
   2055 
   2056 	isakmp_cfg_config.network4 = (in_addr_t)0x00000000;
   2057 	isakmp_cfg_config.netmask4 = (in_addr_t)0x00000000;
   2058 	for (i = 0; i < MAXNS; i++)
   2059 		isakmp_cfg_config.dns4[i] = (in_addr_t)0x00000000;
   2060 	isakmp_cfg_config.dns4_index = 0;
   2061 	for (i = 0; i < MAXWINS; i++)
   2062 		isakmp_cfg_config.nbns4[i] = (in_addr_t)0x00000000;
   2063 	isakmp_cfg_config.nbns4_index = 0;
   2064 	if (cold == ISAKMP_CFG_INIT_COLD)
   2065 		isakmp_cfg_config.port_pool = NULL;
   2066 	isakmp_cfg_config.authsource = ISAKMP_CFG_AUTH_SYSTEM;
   2067 	isakmp_cfg_config.groupsource = ISAKMP_CFG_GROUP_SYSTEM;
   2068 	if (cold == ISAKMP_CFG_INIT_COLD) {
   2069 		if (isakmp_cfg_config.grouplist != NULL) {
   2070 			for (i = 0; i < isakmp_cfg_config.groupcount; i++)
   2071 				racoon_free(isakmp_cfg_config.grouplist[i]);
   2072 			racoon_free(isakmp_cfg_config.grouplist);
   2073 		}
   2074 	}
   2075 	isakmp_cfg_config.grouplist = NULL;
   2076 	isakmp_cfg_config.groupcount = 0;
   2077 	isakmp_cfg_config.confsource = ISAKMP_CFG_CONF_LOCAL;
   2078 	isakmp_cfg_config.accounting = ISAKMP_CFG_ACCT_NONE;
   2079 	if (cold == ISAKMP_CFG_INIT_COLD)
   2080 		isakmp_cfg_config.pool_size = 0;
   2081 	isakmp_cfg_config.auth_throttle = THROTTLE_PENALTY;
   2082 	strlcpy(isakmp_cfg_config.default_domain, ISAKMP_CFG_DEFAULT_DOMAIN,
   2083 	    MAXPATHLEN);
   2084 	strlcpy(isakmp_cfg_config.motd, ISAKMP_CFG_MOTD, MAXPATHLEN);
   2085 
   2086 	if (cold != ISAKMP_CFG_INIT_COLD )
   2087 		if (isakmp_cfg_config.splitnet_list != NULL)
   2088 			splitnet_list_free(isakmp_cfg_config.splitnet_list,
   2089 				&isakmp_cfg_config.splitnet_count);
   2090 	isakmp_cfg_config.splitnet_list = NULL;
   2091 	isakmp_cfg_config.splitnet_count = 0;
   2092 	isakmp_cfg_config.splitnet_type = 0;
   2093 
   2094 	isakmp_cfg_config.pfs_group = 0;
   2095 	isakmp_cfg_config.save_passwd = 0;
   2096 
   2097 	if (cold != ISAKMP_CFG_INIT_COLD )
   2098 		if (isakmp_cfg_config.splitdns_list != NULL)
   2099 			racoon_free(isakmp_cfg_config.splitdns_list);
   2100 	isakmp_cfg_config.splitdns_list = NULL;
   2101 	isakmp_cfg_config.splitdns_len = 0;
   2102 
   2103 #if 0
   2104 	int error;
   2105 	if (cold == ISAKMP_CFG_INIT_COLD) {
   2106 		if ((error = isakmp_cfg_resize_pool(ISAKMP_CFG_MAX_CNX)) != 0)
   2107 			return error;
   2108 	}
   2109 #endif
   2110 
   2111 	return 0;
   2112 }
   2113 
   2114