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