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