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