xref: /netbsd-src/crypto/dist/ipsec-tools/src/racoon/isakmp_cfg.c (revision 92e958de60c71aa0f2452bd7074cbb006fe6546b)
1 /*	$NetBSD: isakmp_cfg.c,v 1.26 2016/03/09 22:27:17 christos Exp $	*/
2 
3 /* Id: isakmp_cfg.c,v 1.55 2006/08/22 18:17:17 manubsd Exp */
4 
5 /*
6  * Copyright (C) 2004-2006 Emmanuel Dreyfus
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  * 3. Neither the name of the project nor the names of its contributors
18  *    may be used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  */
33 
34 #include "config.h"
35 
36 #include <sys/types.h>
37 #include <sys/param.h>
38 #include <sys/socket.h>
39 #include <sys/queue.h>
40 
41 #include <utmpx.h>
42 #if defined(__APPLE__) && defined(__MACH__)
43 #include <util.h>
44 #endif
45 
46 #ifdef __FreeBSD__
47 # include <libutil.h>
48 #endif
49 #ifdef __NetBSD__
50 #  include <util.h>
51 #endif
52 
53 #include <netinet/in.h>
54 #include <arpa/inet.h>
55 
56 #include <stdlib.h>
57 #include <stdio.h>
58 #include <string.h>
59 #include <errno.h>
60 #if TIME_WITH_SYS_TIME
61 # include <sys/time.h>
62 # include <time.h>
63 #else
64 # if HAVE_SYS_TIME_H
65 #  include <sys/time.h>
66 # else
67 #  include <time.h>
68 # endif
69 #endif
70 #include <netdb.h>
71 #ifdef HAVE_UNISTD_H
72 #include <unistd.h>
73 #endif
74 #if HAVE_STDINT_H
75 #include <stdint.h>
76 #endif
77 #include <ctype.h>
78 #include <resolv.h>
79 
80 #ifdef HAVE_LIBRADIUS
81 #include <sys/utsname.h>
82 #include <radlib.h>
83 #endif
84 
85 #include "var.h"
86 #include "misc.h"
87 #include "vmbuf.h"
88 #include "plog.h"
89 #include "sockmisc.h"
90 #include "schedule.h"
91 #include "debug.h"
92 
93 #include "isakmp_var.h"
94 #include "isakmp.h"
95 #include "handler.h"
96 #include "evt.h"
97 #include "throttle.h"
98 #include "remoteconf.h"
99 #include "crypto_openssl.h"
100 #include "isakmp_inf.h"
101 #include "isakmp_xauth.h"
102 #include "isakmp_unity.h"
103 #include "isakmp_cfg.h"
104 #include "strnames.h"
105 #include "admin.h"
106 #include "privsep.h"
107 
108 struct isakmp_cfg_config isakmp_cfg_config;
109 
110 static vchar_t *buffer_cat(vchar_t *s, vchar_t *append);
111 static vchar_t *isakmp_cfg_net(struct ph1handle *, struct isakmp_data *);
112 #if 0
113 static vchar_t *isakmp_cfg_void(struct ph1handle *, struct isakmp_data *);
114 #endif
115 static vchar_t *isakmp_cfg_addr4(struct ph1handle *,
116 				 struct isakmp_data *, in_addr_t *);
117 static vchar_t *isakmp_cfg_addrnet4(struct ph1handle *,
118 				 struct isakmp_data *, in_addr_t *, in_addr_t *);
119 static void isakmp_cfg_getaddr4(struct isakmp_data *, struct in_addr *);
120 static vchar_t *isakmp_cfg_addr4_list(struct ph1handle *,
121 				      struct isakmp_data *, in_addr_t *, int);
122 static void isakmp_cfg_appendaddr4(struct isakmp_data *,
123 				   struct in_addr *, int *, int);
124 static void isakmp_cfg_getstring(struct isakmp_data *,char *);
125 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 (iph1->approval->authmethod) {
452 		case OAKLEY_ATTR_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 		case OAKLEY_ATTR_AUTH_METHOD_RSASIG:
461 			script_hook(iph1, SCRIPT_PHASE1_UP);
462 			break;
463 		default:
464 			break;
465 		}
466 	}
467 
468 
469 #ifdef ENABLE_ADMINPORT
470 	{
471 		vchar_t *buf;
472 
473 		alen = ntohs(attrpl->h.len) - sizeof(*attrpl);
474 		if ((buf = vmalloc(alen)) == NULL) {
475 			plog(LLV_WARNING, LOCATION, NULL,
476 			    "Cannot allocate memory: %s\n", strerror(errno));
477 		} else {
478 			memcpy(buf->v, attrpl + 1, buf->l);
479 			evt_phase1(iph1, EVT_PHASE1_MODE_CFG, 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 (iph1->approval->authmethod) {
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 		case OAKLEY_ATTR_AUTH_METHOD_RSASIG:
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 (!len)
1006 		return NULL;
1007 
1008 	if ((buffer = vmalloc(sizeof(*attr) + len)) == NULL) {
1009 		plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
1010 		return NULL;
1011 	}
1012 
1013 	new = (struct isakmp_data *)buffer->v;
1014 
1015 	new->type = attr->type;
1016 	new->lorv = htons(len);
1017 	data = (char *)(new + 1);
1018 
1019 	memcpy(data, string, len);
1020 
1021 	return buffer;
1022 }
1023 vchar_t *
1024 isakmp_cfg_string(iph1, attr, string)
1025 	struct ph1handle *iph1;
1026 	struct isakmp_data *attr;
1027 	char *string;
1028 {
1029 	size_t len = strlen(string);
1030 	return isakmp_cfg_varlen(iph1, attr, string, len);
1031 }
1032 
1033 static vchar_t *
1034 isakmp_cfg_addr4(iph1, attr, addr)
1035 	struct ph1handle *iph1;
1036 	struct isakmp_data *attr;
1037 	in_addr_t *addr;
1038 {
1039 	vchar_t *buffer;
1040 	struct isakmp_data *new;
1041 	size_t len;
1042 
1043 	len = sizeof(*addr);
1044 	if ((buffer = vmalloc(sizeof(*attr) + len)) == NULL) {
1045 		plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
1046 		return NULL;
1047 	}
1048 
1049 	new = (struct isakmp_data *)buffer->v;
1050 
1051 	new->type = attr->type;
1052 	new->lorv = htons(len);
1053 	memcpy(new + 1, addr, len);
1054 
1055 	return buffer;
1056 }
1057 
1058 static vchar_t *
1059 isakmp_cfg_addrnet4(iph1, attr, addr, mask)
1060 	struct ph1handle *iph1;
1061 	struct isakmp_data *attr;
1062 	in_addr_t *addr;
1063 	in_addr_t *mask;
1064 {
1065 	vchar_t *buffer;
1066 	struct isakmp_data *new;
1067 	size_t len;
1068 	in_addr_t netbuff[2];
1069 
1070 	len = sizeof(netbuff);
1071 	if ((buffer = vmalloc(sizeof(*attr) + len)) == NULL) {
1072 		plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
1073 		return NULL;
1074 	}
1075 
1076 	new = (struct isakmp_data *)buffer->v;
1077 
1078 	new->type = attr->type;
1079 	new->lorv = htons(len);
1080 	netbuff[0]=*addr;
1081 	netbuff[1]=*mask;
1082 	memcpy(new + 1, netbuff, len);
1083 
1084 	return buffer;
1085 }
1086 
1087 
1088 static vchar_t *
1089 isakmp_cfg_addr4_list(iph1, attr, addr, nbr)
1090 	struct ph1handle *iph1;
1091 	struct isakmp_data *attr;
1092 	in_addr_t *addr;
1093 	int nbr;
1094 {
1095 	int error = -1;
1096 	vchar_t *buffer = NULL;
1097 	vchar_t *bufone = NULL;
1098 	struct isakmp_data *new;
1099 	size_t len;
1100 	int i;
1101 
1102 	len = sizeof(*addr);
1103 	if ((buffer = vmalloc(0)) == NULL) {
1104 		plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
1105 		goto out;
1106 	}
1107 	for(i = 0; i < nbr; i++) {
1108 		if ((bufone = vmalloc(sizeof(*attr) + len)) == NULL) {
1109 			plog(LLV_ERROR, LOCATION, NULL,
1110 			    "Cannot allocate memory\n");
1111 			goto out;
1112 		}
1113 		new = (struct isakmp_data *)bufone->v;
1114 		new->type = attr->type;
1115 		new->lorv = htons(len);
1116 		memcpy(new + 1, &addr[i], len);
1117 		new += (len + sizeof(*attr));
1118 		buffer = buffer_cat(buffer, bufone);
1119 		vfree(bufone);
1120 	}
1121 
1122 	error = 0;
1123 
1124 out:
1125 	if ((error != 0) && (buffer != NULL)) {
1126 		vfree(buffer);
1127 		buffer = NULL;
1128 	}
1129 
1130 	return buffer;
1131 }
1132 
1133 struct isakmp_ivm *
1134 isakmp_cfg_newiv(iph1, msgid)
1135 	struct ph1handle *iph1;
1136 	u_int32_t msgid;
1137 {
1138 	struct isakmp_cfg_state *ics = iph1->mode_cfg;
1139 
1140 	if (ics == NULL) {
1141 		plog(LLV_ERROR, LOCATION, NULL,
1142 		    "isakmp_cfg_newiv called without mode config state\n");
1143 		return NULL;
1144 	}
1145 
1146 	if (ics->ivm != NULL)
1147 		oakley_delivm(ics->ivm);
1148 
1149 	ics->ivm = oakley_newiv2(iph1, msgid);
1150 	ics->last_msgid = msgid;
1151 
1152 	return ics->ivm;
1153 }
1154 
1155 /* Derived from isakmp_info_send_common */
1156 int
1157 isakmp_cfg_send(iph1, payload, np, flags, new_exchange)
1158 	struct ph1handle *iph1;
1159 	vchar_t *payload;
1160 	u_int32_t np;
1161 	int flags;
1162 	int new_exchange;
1163 {
1164 	struct ph2handle *iph2 = NULL;
1165 	vchar_t *hash = NULL;
1166 	struct isakmp *isakmp;
1167 	struct isakmp_gen *gen;
1168 	char *p;
1169 	int tlen;
1170 	int error = -1;
1171 	struct isakmp_cfg_state *ics = iph1->mode_cfg;
1172 
1173 	/* Check if phase 1 is established */
1174 	if ((iph1->status < PHASE1ST_ESTABLISHED) ||
1175 	    (iph1->local == NULL) ||
1176 	    (iph1->remote == NULL)) {
1177 		plog(LLV_ERROR, LOCATION, NULL,
1178 		    "ISAKMP mode config exchange with immature phase 1\n");
1179 		goto end;
1180 	}
1181 
1182 	/* add new entry to isakmp status table */
1183 	iph2 = newph2();
1184 	if (iph2 == NULL)
1185 		goto end;
1186 
1187 	iph2->dst = dupsaddr(iph1->remote);
1188 	if (iph2->dst == NULL) {
1189 		delph2(iph2);
1190 		goto end;
1191 	}
1192 	iph2->src = dupsaddr(iph1->local);
1193 	if (iph2->src == NULL) {
1194 		delph2(iph2);
1195 		goto end;
1196 	}
1197 
1198 	iph2->side = INITIATOR;
1199 	iph2->status = PHASE2ST_START;
1200 
1201 	if (new_exchange)
1202 		iph2->msgid = isakmp_newmsgid2(iph1);
1203 	else
1204 		iph2->msgid = iph1->msgid;
1205 
1206 	/* get IV and HASH(1) if skeyid_a was generated. */
1207 	if (iph1->skeyid_a != NULL) {
1208 		if (new_exchange) {
1209 			if (isakmp_cfg_newiv(iph1, iph2->msgid) == NULL) {
1210 				delph2(iph2);
1211 				goto end;
1212 			}
1213 		}
1214 
1215 		/* generate HASH(1) */
1216 		hash = oakley_compute_hash1(iph1, iph2->msgid, payload);
1217 		if (hash == NULL) {
1218 			delph2(iph2);
1219 			goto end;
1220 		}
1221 
1222 		/* initialized total buffer length */
1223 		tlen = hash->l;
1224 		tlen += sizeof(*gen);
1225 	} else {
1226 		/* IKE-SA is not established */
1227 		hash = NULL;
1228 
1229 		/* initialized total buffer length */
1230 		tlen = 0;
1231 	}
1232 	if ((flags & ISAKMP_FLAG_A) == 0)
1233 		iph2->flags = (hash == NULL ? 0 : ISAKMP_FLAG_E);
1234 	else
1235 		iph2->flags = (hash == NULL ? 0 : ISAKMP_FLAG_A);
1236 
1237 	insph2(iph2);
1238 	bindph12(iph1, iph2);
1239 
1240 	tlen += sizeof(*isakmp) + payload->l;
1241 
1242 	/* create buffer for isakmp payload */
1243 	iph2->sendbuf = vmalloc(tlen);
1244 	if (iph2->sendbuf == NULL) {
1245 		plog(LLV_ERROR, LOCATION, NULL,
1246 			"failed to get buffer to send.\n");
1247 		goto err;
1248 	}
1249 
1250 	/* create isakmp header */
1251 	isakmp = (struct isakmp *)iph2->sendbuf->v;
1252 	memcpy(&isakmp->i_ck, &iph1->index.i_ck, sizeof(cookie_t));
1253 	memcpy(&isakmp->r_ck, &iph1->index.r_ck, sizeof(cookie_t));
1254 	isakmp->np = hash == NULL ? (np & 0xff) : ISAKMP_NPTYPE_HASH;
1255 	isakmp->v = iph1->version;
1256 	isakmp->etype = ISAKMP_ETYPE_CFG;
1257 	isakmp->flags = iph2->flags;
1258 	memcpy(&isakmp->msgid, &iph2->msgid, sizeof(isakmp->msgid));
1259 	isakmp->len = htonl(tlen);
1260 	p = (char *)(isakmp + 1);
1261 
1262 	/* create HASH payload */
1263 	if (hash != NULL) {
1264 		gen = (struct isakmp_gen *)p;
1265 		gen->np = np & 0xff;
1266 		gen->len = htons(sizeof(*gen) + hash->l);
1267 		p += sizeof(*gen);
1268 		memcpy(p, hash->v, hash->l);
1269 		p += hash->l;
1270 	}
1271 
1272 	/* add payload */
1273 	memcpy(p, payload->v, payload->l);
1274 	p += payload->l;
1275 
1276 #ifdef HAVE_PRINT_ISAKMP_C
1277 	isakmp_printpacket(iph2->sendbuf, iph1->local, iph1->remote, 1);
1278 #endif
1279 
1280 	plog(LLV_DEBUG, LOCATION, NULL, "MODE_CFG packet to send\n");
1281 	plogdump(LLV_DEBUG, iph2->sendbuf->v, iph2->sendbuf->l);
1282 
1283 	/* encoding */
1284 	if (ISSET(isakmp->flags, ISAKMP_FLAG_E)) {
1285 		vchar_t *tmp;
1286 
1287 		tmp = oakley_do_encrypt(iph2->ph1, iph2->sendbuf,
1288 			ics->ivm->ive, ics->ivm->iv);
1289 		VPTRINIT(iph2->sendbuf);
1290 		if (tmp == NULL)
1291 			goto err;
1292 		iph2->sendbuf = tmp;
1293 	}
1294 
1295 	/* HDR*, HASH(1), ATTR */
1296 	if (isakmp_send(iph2->ph1, iph2->sendbuf) < 0) {
1297 		VPTRINIT(iph2->sendbuf);
1298 		goto err;
1299 	}
1300 
1301 	plog(LLV_DEBUG, LOCATION, NULL,
1302 		"sendto mode config %s.\n", s_isakmp_nptype(np));
1303 
1304 	/*
1305 	 * XXX We might need to resend the message...
1306 	 */
1307 
1308 	error = 0;
1309 	VPTRINIT(iph2->sendbuf);
1310 
1311 err:
1312 	if (iph2->sendbuf != NULL)
1313 		vfree(iph2->sendbuf);
1314 
1315 	remph2(iph2);
1316 	delph2(iph2);
1317 end:
1318 	if (hash)
1319 		vfree(hash);
1320 	return error;
1321 }
1322 
1323 
1324 void
1325 isakmp_cfg_rmstate(iph1)
1326 	struct ph1handle *iph1;
1327 {
1328 	struct isakmp_cfg_state *state = iph1->mode_cfg;
1329 
1330 	if (isakmp_cfg_accounting(iph1, ISAKMP_CFG_LOGOUT) != 0)
1331 		plog(LLV_ERROR, LOCATION, NULL, "Accounting failed\n");
1332 
1333 	if (state->flags & ISAKMP_CFG_PORT_ALLOCATED)
1334 		isakmp_cfg_putport(iph1, state->port);
1335 
1336 	/* Delete the IV if it's still there */
1337 	if(iph1->mode_cfg->ivm) {
1338 		oakley_delivm(iph1->mode_cfg->ivm);
1339 		iph1->mode_cfg->ivm = NULL;
1340 	}
1341 
1342 	/* Free any allocated splitnet lists */
1343 	if(iph1->mode_cfg->split_include != NULL)
1344 		splitnet_list_free(iph1->mode_cfg->split_include,
1345 			&iph1->mode_cfg->include_count);
1346 	if(iph1->mode_cfg->split_local != NULL)
1347 		splitnet_list_free(iph1->mode_cfg->split_local,
1348 			&iph1->mode_cfg->local_count);
1349 
1350 	xauth_rmstate(&state->xauth);
1351 
1352 	racoon_free(state);
1353 	iph1->mode_cfg = NULL;
1354 
1355 	return;
1356 }
1357 
1358 struct isakmp_cfg_state *
1359 isakmp_cfg_mkstate(void)
1360 {
1361 	struct isakmp_cfg_state *state;
1362 
1363 	if ((state = racoon_malloc(sizeof(*state))) == NULL) {
1364 		plog(LLV_ERROR, LOCATION, NULL,
1365 		    "Cannot allocate memory for mode config state\n");
1366 		return NULL;
1367 	}
1368 	memset(state, 0, sizeof(*state));
1369 
1370 	return state;
1371 }
1372 
1373 int
1374 isakmp_cfg_getport(iph1)
1375 	struct ph1handle *iph1;
1376 {
1377 	unsigned int i;
1378 	size_t size = isakmp_cfg_config.pool_size;
1379 
1380 	if (iph1->mode_cfg->flags & ISAKMP_CFG_PORT_ALLOCATED)
1381 		return iph1->mode_cfg->port;
1382 
1383 	if (isakmp_cfg_config.port_pool == NULL) {
1384 		plog(LLV_ERROR, LOCATION, NULL,
1385 		    "isakmp_cfg_config.port_pool == NULL\n");
1386 		return -1;
1387 	}
1388 
1389 	for (i = 0; i < size; i++) {
1390 		if (isakmp_cfg_config.port_pool[i].used == 0)
1391 			break;
1392 	}
1393 
1394 	if (i == size) {
1395 		plog(LLV_ERROR, LOCATION, NULL,
1396 		    "No more addresses available\n");
1397 			return -1;
1398 	}
1399 
1400 	isakmp_cfg_config.port_pool[i].used = 1;
1401 
1402 	plog(LLV_INFO, LOCATION, NULL, "Using port %d\n", i);
1403 
1404 	iph1->mode_cfg->flags |= ISAKMP_CFG_PORT_ALLOCATED;
1405 	iph1->mode_cfg->port = i;
1406 
1407 	return i;
1408 }
1409 
1410 int
1411 isakmp_cfg_putport(iph1, index)
1412 	struct ph1handle *iph1;
1413 	unsigned int index;
1414 {
1415 	if (isakmp_cfg_config.port_pool == NULL) {
1416 		plog(LLV_ERROR, LOCATION, NULL,
1417 		    "isakmp_cfg_config.port_pool == NULL\n");
1418 		return -1;
1419 	}
1420 
1421 	if (isakmp_cfg_config.port_pool[index].used == 0) {
1422 		plog(LLV_ERROR, LOCATION, NULL,
1423 		    "Attempt to release an unallocated address (port %d)\n",
1424 		    index);
1425 		return -1;
1426 	}
1427 
1428 #ifdef HAVE_LIBPAM
1429 	/* Cleanup PAM status associated with the port */
1430 	if (isakmp_cfg_config.authsource == ISAKMP_CFG_AUTH_PAM)
1431 		privsep_cleanup_pam(index);
1432 #endif
1433 	isakmp_cfg_config.port_pool[index].used = 0;
1434 	iph1->mode_cfg->flags &= ISAKMP_CFG_PORT_ALLOCATED;
1435 
1436 	plog(LLV_INFO, LOCATION, NULL, "Released port %d\n", index);
1437 
1438 	return 0;
1439 }
1440 
1441 #ifdef HAVE_LIBPAM
1442 void
1443 cleanup_pam(port)
1444 	int port;
1445 {
1446 	if (isakmp_cfg_config.port_pool[port].pam != NULL) {
1447 		pam_end(isakmp_cfg_config.port_pool[port].pam, PAM_SUCCESS);
1448 		isakmp_cfg_config.port_pool[port].pam = NULL;
1449 	}
1450 
1451 	return;
1452 }
1453 #endif
1454 
1455 /* Accounting, only for RADIUS or PAM */
1456 static int
1457 isakmp_cfg_accounting(iph1, inout)
1458 	struct ph1handle *iph1;
1459 	int inout;
1460 {
1461 #ifdef HAVE_LIBPAM
1462 	if (isakmp_cfg_config.accounting == ISAKMP_CFG_ACCT_PAM)
1463 		return privsep_accounting_pam(iph1->mode_cfg->port,
1464 		    inout);
1465 #endif
1466 #ifdef HAVE_LIBRADIUS
1467 	if (isakmp_cfg_config.accounting == ISAKMP_CFG_ACCT_RADIUS)
1468 		return isakmp_cfg_accounting_radius(iph1, inout);
1469 #endif
1470 	if (isakmp_cfg_config.accounting == ISAKMP_CFG_ACCT_SYSTEM)
1471 		return privsep_accounting_system(iph1->mode_cfg->port,
1472 			iph1->remote, iph1->mode_cfg->login, inout);
1473 	return 0;
1474 }
1475 
1476 #ifdef HAVE_LIBPAM
1477 int
1478 isakmp_cfg_accounting_pam(port, inout)
1479 	int port;
1480 	int inout;
1481 {
1482 	int error = 0;
1483 	pam_handle_t *pam;
1484 
1485 	if (isakmp_cfg_config.port_pool == NULL) {
1486 		plog(LLV_ERROR, LOCATION, NULL,
1487 		    "isakmp_cfg_config.port_pool == NULL\n");
1488 		return -1;
1489 	}
1490 
1491 	pam = isakmp_cfg_config.port_pool[port].pam;
1492 	if (pam == NULL) {
1493 		plog(LLV_ERROR, LOCATION, NULL, "pam handle is NULL\n");
1494 		return -1;
1495 	}
1496 
1497 	switch (inout) {
1498 	case ISAKMP_CFG_LOGIN:
1499 		error = pam_open_session(pam, 0);
1500 		break;
1501 	case ISAKMP_CFG_LOGOUT:
1502 		error = pam_close_session(pam, 0);
1503 		pam_end(pam, error);
1504 		isakmp_cfg_config.port_pool[port].pam = NULL;
1505 		break;
1506 	default:
1507 		plog(LLV_ERROR, LOCATION, NULL, "Unepected inout\n");
1508 		break;
1509 	}
1510 
1511 	if (error != 0) {
1512 		plog(LLV_ERROR, LOCATION, NULL,
1513 		    "pam_open_session/pam_close_session failed: %s\n",
1514 		    pam_strerror(pam, error));
1515 		return -1;
1516         }
1517 
1518 	return 0;
1519 }
1520 #endif /* HAVE_LIBPAM */
1521 
1522 #ifdef HAVE_LIBRADIUS
1523 static int
1524 isakmp_cfg_accounting_radius(iph1, inout)
1525 	struct ph1handle *iph1;
1526 	int inout;
1527 {
1528 	if (rad_create_request(radius_acct_state,
1529 	    RAD_ACCOUNTING_REQUEST) != 0) {
1530 		plog(LLV_ERROR, LOCATION, NULL,
1531 		    "rad_create_request failed: %s\n",
1532 		    rad_strerror(radius_acct_state));
1533 		return -1;
1534 	}
1535 
1536 	if (rad_put_string(radius_acct_state, RAD_USER_NAME,
1537 	    iph1->mode_cfg->login) != 0) {
1538 		plog(LLV_ERROR, LOCATION, NULL,
1539 		    "rad_put_string failed: %s\n",
1540 		    rad_strerror(radius_acct_state));
1541 		return -1;
1542 	}
1543 
1544 	switch (inout) {
1545 	case ISAKMP_CFG_LOGIN:
1546 		inout = RAD_START;
1547 		break;
1548 	case ISAKMP_CFG_LOGOUT:
1549 		inout = RAD_STOP;
1550 		break;
1551 	default:
1552 		plog(LLV_ERROR, LOCATION, NULL, "Unepected inout\n");
1553 		break;
1554 	}
1555 
1556 	if (rad_put_addr(radius_acct_state,
1557 	    RAD_FRAMED_IP_ADDRESS, iph1->mode_cfg->addr4) != 0) {
1558 		plog(LLV_ERROR, LOCATION, NULL,
1559 		    "rad_put_addr failed: %s\n",
1560 		    rad_strerror(radius_acct_state));
1561 		return -1;
1562 	}
1563 
1564 	if (rad_put_addr(radius_acct_state,
1565 	    RAD_LOGIN_IP_HOST, iph1->mode_cfg->addr4) != 0) {
1566 		plog(LLV_ERROR, LOCATION, NULL,
1567 		    "rad_put_addr failed: %s\n",
1568 		    rad_strerror(radius_acct_state));
1569 		return -1;
1570 	}
1571 
1572 	if (rad_put_int(radius_acct_state, RAD_ACCT_STATUS_TYPE, inout) != 0) {
1573 		plog(LLV_ERROR, LOCATION, NULL,
1574 		    "rad_put_int failed: %s\n",
1575 		    rad_strerror(radius_acct_state));
1576 		return -1;
1577 	}
1578 
1579 	if (isakmp_cfg_radius_common(radius_acct_state,
1580 	    iph1->mode_cfg->port) != 0)
1581 		return -1;
1582 
1583 	if (rad_send_request(radius_acct_state) != RAD_ACCOUNTING_RESPONSE) {
1584 		plog(LLV_ERROR, LOCATION, NULL,
1585 		    "rad_send_request failed: %s\n",
1586 		    rad_strerror(radius_acct_state));
1587 		return -1;
1588 	}
1589 
1590 	return 0;
1591 }
1592 #endif /* HAVE_LIBRADIUS */
1593 
1594 /*
1595  * Attributes common to all RADIUS requests
1596  */
1597 #ifdef HAVE_LIBRADIUS
1598 int
1599 isakmp_cfg_radius_common(radius_state, port)
1600 	struct rad_handle *radius_state;
1601 	int port;
1602 {
1603 	struct utsname name;
1604 	static struct hostent *host = NULL;
1605 	struct in_addr nas_addr;
1606 
1607 	/*
1608 	 * Find our own IP by resolving our nodename
1609 	 */
1610 	if (host == NULL) {
1611 		if (uname(&name) != 0) {
1612 			plog(LLV_ERROR, LOCATION, NULL,
1613 			    "uname failed: %s\n", strerror(errno));
1614 			return -1;
1615 		}
1616 
1617 		if ((host = gethostbyname(name.nodename)) == NULL) {
1618 			plog(LLV_ERROR, LOCATION, NULL,
1619 			    "gethostbyname failed: %s\n", strerror(errno));
1620 			return -1;
1621 		}
1622 	}
1623 
1624 	memcpy(&nas_addr, host->h_addr, sizeof(nas_addr));
1625 	if (rad_put_addr(radius_state, RAD_NAS_IP_ADDRESS, nas_addr) != 0) {
1626 		plog(LLV_ERROR, LOCATION, NULL,
1627 		    "rad_put_addr failed: %s\n",
1628 		    rad_strerror(radius_state));
1629 		return -1;
1630 	}
1631 
1632 	if (rad_put_int(radius_state, RAD_NAS_PORT, port) != 0) {
1633 		plog(LLV_ERROR, LOCATION, NULL,
1634 		    "rad_put_int failed: %s\n",
1635 		    rad_strerror(radius_state));
1636 		return -1;
1637 	}
1638 
1639 	if (rad_put_int(radius_state, RAD_NAS_PORT_TYPE, RAD_VIRTUAL) != 0) {
1640 		plog(LLV_ERROR, LOCATION, NULL,
1641 		    "rad_put_int failed: %s\n",
1642 		    rad_strerror(radius_state));
1643 		return -1;
1644 	}
1645 
1646 	if (rad_put_int(radius_state, RAD_SERVICE_TYPE, RAD_FRAMED) != 0) {
1647 		plog(LLV_ERROR, LOCATION, NULL,
1648 		    "rad_put_int failed: %s\n",
1649 		    rad_strerror(radius_state));
1650 		return -1;
1651 	}
1652 
1653 	return 0;
1654 }
1655 #endif
1656 
1657 /*
1658 	Logs the user into the utmp system files.
1659 */
1660 
1661 int
1662 isakmp_cfg_accounting_system(port, raddr, usr, inout)
1663 	int port;
1664 	struct sockaddr *raddr;
1665 	char *usr;
1666 	int inout;
1667 {
1668 	int error = 0;
1669 	struct utmpx ut;
1670 	char addr[NI_MAXHOST];
1671 
1672 	if (usr == NULL || usr[0]=='\0') {
1673 		plog(LLV_ERROR, LOCATION, NULL,
1674 			"system accounting : no login found\n");
1675 		return -1;
1676 	}
1677 
1678 	memset(&ut, 0, sizeof ut);
1679 	gettimeofday((struct timeval *)&ut.ut_tv, NULL);
1680 	snprintf(ut.ut_id, sizeof ut.ut_id, TERMSPEC, port);
1681 
1682 	switch (inout) {
1683 	case ISAKMP_CFG_LOGIN:
1684 		ut.ut_type = USER_PROCESS;
1685 		strncpy(ut.ut_user, usr, sizeof ut.ut_user);
1686 
1687 		GETNAMEINFO_NULL(raddr, addr);
1688 		strncpy(ut.ut_host, addr, sizeof ut.ut_host);
1689 
1690 		plog(LLV_INFO, LOCATION, NULL,
1691 			"Accounting : '%s' logging on '%s' from %s.\n",
1692 			ut.ut_user, ut.ut_id, addr);
1693 
1694 		pututxline(&ut);
1695 
1696 		break;
1697 	case ISAKMP_CFG_LOGOUT:
1698 		ut.ut_type = DEAD_PROCESS;
1699 
1700 		plog(LLV_INFO, LOCATION, NULL,
1701 			"Accounting : '%s' unlogging from '%s'.\n",
1702 			usr, ut.ut_id);
1703 
1704 		pututxline(&ut);
1705 
1706 		break;
1707 	default:
1708 		plog(LLV_ERROR, LOCATION, NULL, "Unepected inout\n");
1709 		break;
1710 	}
1711 
1712 	return 0;
1713 }
1714 
1715 int
1716 isakmp_cfg_getconfig(iph1)
1717 	struct ph1handle *iph1;
1718 {
1719 	vchar_t *buffer;
1720 	struct isakmp_pl_attr *attrpl;
1721 	struct isakmp_data *attr;
1722 	size_t len;
1723 	int error;
1724 	int attrcount;
1725 	int i;
1726 	int attrlist[] = {
1727 		INTERNAL_IP4_ADDRESS,
1728 		INTERNAL_IP4_NETMASK,
1729 		INTERNAL_IP4_DNS,
1730 		INTERNAL_IP4_NBNS,
1731 		UNITY_BANNER,
1732 		UNITY_DEF_DOMAIN,
1733 		UNITY_SPLITDNS_NAME,
1734 		UNITY_SPLIT_INCLUDE,
1735 		UNITY_LOCAL_LAN,
1736 		APPLICATION_VERSION,
1737 	};
1738 
1739 	attrcount = sizeof(attrlist) / sizeof(*attrlist);
1740 	len = sizeof(*attrpl) + sizeof(*attr) * attrcount;
1741 
1742 	if ((buffer = vmalloc(len)) == NULL) {
1743 		plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
1744 		return -1;
1745 	}
1746 
1747 	attrpl = (struct isakmp_pl_attr *)buffer->v;
1748 	attrpl->h.len = htons(len);
1749 	attrpl->type = ISAKMP_CFG_REQUEST;
1750 	attrpl->id = htons((u_int16_t)(eay_random() & 0xffff));
1751 
1752 	attr = (struct isakmp_data *)(attrpl + 1);
1753 
1754 	for (i = 0; i < attrcount; i++) {
1755 		attr->type = htons(attrlist[i]);
1756 		attr->lorv = htons(0);
1757 		attr++;
1758 	}
1759 
1760 	plog(LLV_DEBUG, LOCATION, NULL,
1761 		    "Sending MODE_CFG REQUEST\n");
1762 
1763 	error = isakmp_cfg_send(iph1, buffer,
1764 	    ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 1);
1765 
1766 	vfree(buffer);
1767 
1768 	return error;
1769 }
1770 
1771 static void
1772 isakmp_cfg_getaddr4(attr, ip)
1773 	struct isakmp_data *attr;
1774 	struct in_addr *ip;
1775 {
1776 	size_t alen = ntohs(attr->lorv);
1777 	in_addr_t *addr;
1778 
1779 	if (alen != sizeof(*ip)) {
1780 		plog(LLV_ERROR, LOCATION, NULL, "Bad IPv4 address len\n");
1781 		return;
1782 	}
1783 
1784 	addr = (in_addr_t *)(attr + 1);
1785 	ip->s_addr = *addr;
1786 
1787 	return;
1788 }
1789 
1790 static void
1791 isakmp_cfg_appendaddr4(attr, ip, num, max)
1792 	struct isakmp_data *attr;
1793 	struct in_addr *ip;
1794 	int *num;
1795 	int max;
1796 {
1797 	size_t alen = ntohs(attr->lorv);
1798 	in_addr_t *addr;
1799 
1800 	if (alen != sizeof(*ip)) {
1801 		plog(LLV_ERROR, LOCATION, NULL, "Bad IPv4 address len\n");
1802 		return;
1803 	}
1804 	if (*num == max) {
1805 		plog(LLV_ERROR, LOCATION, NULL, "Too many addresses given\n");
1806 		return;
1807 	}
1808 
1809 	addr = (in_addr_t *)(attr + 1);
1810 	ip->s_addr = *addr;
1811 	(*num)++;
1812 
1813 	return;
1814 }
1815 
1816 static void
1817 isakmp_cfg_getstring(attr, str)
1818 	struct isakmp_data *attr;
1819 	char *str;
1820 {
1821 	size_t alen = ntohs(attr->lorv);
1822 	char *src;
1823 	src = (char *)(attr + 1);
1824 
1825 	memcpy(str, src, (alen > MAXPATHLEN ? MAXPATHLEN : alen));
1826 
1827 	return;
1828 }
1829 
1830 #define IP_MAX 40
1831 
1832 void
1833 isakmp_cfg_iplist_to_str(dest, count, addr, withmask)
1834 	char *dest;
1835 	int count;
1836 	void *addr;
1837 	int withmask;
1838 {
1839 	int i;
1840 	int p;
1841 	int l;
1842 	struct unity_network tmp;
1843 	for(i = 0, p = 0; i < count; i++) {
1844 		if(withmask == 1)
1845 			l = sizeof(struct unity_network);
1846 		else
1847 			l = sizeof(struct in_addr);
1848 		memcpy(&tmp, addr, l);
1849 		addr += l;
1850 		if((uint32_t)tmp.addr4.s_addr == 0)
1851 			break;
1852 
1853 		inet_ntop(AF_INET, &tmp.addr4, dest + p, IP_MAX);
1854 		p += strlen(dest + p);
1855 		if(withmask == 1) {
1856 			dest[p] = '/';
1857 			p++;
1858 			inet_ntop(AF_INET, &tmp.mask4, dest + p, IP_MAX);
1859 			p += strlen(dest + p);
1860 		}
1861 		dest[p] = ' ';
1862 		p++;
1863 	}
1864 	if(p > 0)
1865 		dest[p-1] = '\0';
1866 	else
1867 		dest[0] = '\0';
1868 }
1869 
1870 int
1871 isakmp_cfg_setenv(iph1, envp, envc)
1872 	struct ph1handle *iph1;
1873 	char ***envp;
1874 	int *envc;
1875 {
1876 	char addrstr[IP_MAX];
1877 	char addrlist[IP_MAX * MAXNS + MAXNS];
1878 	char *splitlist = addrlist;
1879 	char *splitlist_cidr;
1880 	char defdom[MAXPATHLEN + 1];
1881 	int cidr, tmp;
1882 	char cidrstr[4];
1883 	int i, p;
1884 	int test;
1885 
1886 	plog(LLV_DEBUG, LOCATION, NULL, "Starting a script.\n");
1887 
1888 	/*
1889 	 * Internal IPv4 address, either if
1890 	 * we are a client or a server.
1891 	 */
1892 	if ((iph1->mode_cfg->flags & ISAKMP_CFG_GOT_ADDR4) ||
1893 #ifdef HAVE_LIBLDAP
1894 	    (iph1->mode_cfg->flags & ISAKMP_CFG_ADDR4_EXTERN) ||
1895 #endif
1896 #ifdef HAVE_LIBRADIUS
1897 	    (iph1->mode_cfg->flags & ISAKMP_CFG_ADDR4_EXTERN) ||
1898 #endif
1899 	    (iph1->mode_cfg->flags & ISAKMP_CFG_ADDR4_LOCAL)) {
1900 		inet_ntop(AF_INET, &iph1->mode_cfg->addr4,
1901 		    addrstr, IP_MAX);
1902 	} else
1903 		addrstr[0] = '\0';
1904 
1905 	if (script_env_append(envp, envc, "INTERNAL_ADDR4", addrstr) != 0) {
1906 		plog(LLV_ERROR, LOCATION, NULL, "Cannot set INTERNAL_ADDR4\n");
1907 		return -1;
1908 	}
1909 
1910 	if (iph1->mode_cfg->xauth.authdata.generic.usr != NULL) {
1911 		if (script_env_append(envp, envc, "XAUTH_USER",
1912 		    iph1->mode_cfg->xauth.authdata.generic.usr) != 0) {
1913 			plog(LLV_ERROR, LOCATION, NULL,
1914 			    "Cannot set XAUTH_USER\n");
1915 			return -1;
1916 		}
1917 	}
1918 
1919 	/* Internal IPv4 mask */
1920 	if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_MASK4)
1921 		inet_ntop(AF_INET, &iph1->mode_cfg->mask4,
1922 		    addrstr, IP_MAX);
1923 	else
1924 		addrstr[0] = '\0';
1925 
1926 	/*
1927 	 * During several releases, documentation adverised INTERNAL_NETMASK4
1928 	 * while code was using INTERNAL_MASK4. We now do both.
1929 	 */
1930 
1931 	if (script_env_append(envp, envc, "INTERNAL_MASK4", addrstr) != 0) {
1932 		plog(LLV_ERROR, LOCATION, NULL, "Cannot set INTERNAL_MASK4\n");
1933 		return -1;
1934 	}
1935 
1936 	if (script_env_append(envp, envc, "INTERNAL_NETMASK4", addrstr) != 0) {
1937 		plog(LLV_ERROR, LOCATION, NULL,
1938 		    "Cannot set INTERNAL_NETMASK4\n");
1939 		return -1;
1940 	}
1941 
1942 	tmp = ntohl(iph1->mode_cfg->mask4.s_addr);
1943 	for (cidr = 0; tmp != 0; cidr++)
1944 		tmp <<= 1;
1945 	snprintf(cidrstr, 3, "%d", cidr);
1946 
1947 	if (script_env_append(envp, envc, "INTERNAL_CIDR4", cidrstr) != 0) {
1948 		plog(LLV_ERROR, LOCATION, NULL, "Cannot set INTERNAL_CIDR4\n");
1949 		return -1;
1950 	}
1951 
1952 	/* Internal IPv4 DNS */
1953 	if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_DNS4) {
1954 		/* First Internal IPv4 DNS (for compatibilty with older code */
1955 		inet_ntop(AF_INET, &iph1->mode_cfg->dns4[0],
1956 		    addrstr, IP_MAX);
1957 
1958 		/* Internal IPv4 DNS - all */
1959 		isakmp_cfg_iplist_to_str(addrlist, iph1->mode_cfg->dns4_index,
1960 			(void *)iph1->mode_cfg->dns4, 0);
1961 	} else {
1962 		addrstr[0] = '\0';
1963 		addrlist[0] = '\0';
1964 	}
1965 
1966 	if (script_env_append(envp, envc, "INTERNAL_DNS4", addrstr) != 0) {
1967 		plog(LLV_ERROR, LOCATION, NULL, "Cannot set INTERNAL_DNS4\n");
1968 		return -1;
1969 	}
1970 	if (script_env_append(envp, envc, "INTERNAL_DNS4_LIST", addrlist) != 0) {
1971 		plog(LLV_ERROR, LOCATION, NULL,
1972 		    "Cannot set INTERNAL_DNS4_LIST\n");
1973 		return -1;
1974 	}
1975 
1976 	/* Internal IPv4 WINS */
1977 	if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_WINS4) {
1978 		/*
1979 		 * First Internal IPv4 WINS
1980 		 * (for compatibilty with older code
1981 		 */
1982 		inet_ntop(AF_INET, &iph1->mode_cfg->wins4[0],
1983 		    addrstr, IP_MAX);
1984 
1985 		/* Internal IPv4 WINS - all */
1986 		isakmp_cfg_iplist_to_str(addrlist, iph1->mode_cfg->wins4_index,
1987 			(void *)iph1->mode_cfg->wins4, 0);
1988 	} else {
1989 		addrstr[0] = '\0';
1990 		addrlist[0] = '\0';
1991 	}
1992 
1993 	if (script_env_append(envp, envc, "INTERNAL_WINS4", addrstr) != 0) {
1994 		plog(LLV_ERROR, LOCATION, NULL,
1995 		    "Cannot set INTERNAL_WINS4\n");
1996 		return -1;
1997 	}
1998 	if (script_env_append(envp, envc,
1999 	    "INTERNAL_WINS4_LIST", addrlist) != 0) {
2000 		plog(LLV_ERROR, LOCATION, NULL,
2001 		    "Cannot set INTERNAL_WINS4_LIST\n");
2002 		return -1;
2003 	}
2004 
2005 	/* Deault domain */
2006 	if(iph1->mode_cfg->flags & ISAKMP_CFG_GOT_DEFAULT_DOMAIN)
2007 		strncpy(defdom,
2008 		    iph1->mode_cfg->default_domain,
2009 		    MAXPATHLEN + 1);
2010 	else
2011 		defdom[0] = '\0';
2012 
2013 	if (script_env_append(envp, envc, "DEFAULT_DOMAIN", defdom) != 0) {
2014 		plog(LLV_ERROR, LOCATION, NULL,
2015 		    "Cannot set DEFAULT_DOMAIN\n");
2016 		return -1;
2017 	}
2018 
2019 	/* Split networks */
2020 	if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_SPLIT_INCLUDE) {
2021 		splitlist =
2022 		    splitnet_list_2str(iph1->mode_cfg->split_include, NETMASK);
2023 		splitlist_cidr =
2024 		    splitnet_list_2str(iph1->mode_cfg->split_include, CIDR);
2025 	} else {
2026 		splitlist = addrlist;
2027 		splitlist_cidr = addrlist;
2028 		addrlist[0] = '\0';
2029 	}
2030 
2031 	if (script_env_append(envp, envc, "SPLIT_INCLUDE", splitlist) != 0) {
2032 		plog(LLV_ERROR, LOCATION, NULL, "Cannot set SPLIT_INCLUDE\n");
2033 		return -1;
2034 	}
2035 	if (script_env_append(envp, envc,
2036 	    "SPLIT_INCLUDE_CIDR", splitlist_cidr) != 0) {
2037 		plog(LLV_ERROR, LOCATION, NULL,
2038 		     "Cannot set SPLIT_INCLUDE_CIDR\n");
2039 		return -1;
2040 	}
2041 	if (splitlist != addrlist)
2042 		racoon_free(splitlist);
2043 	if (splitlist_cidr != addrlist)
2044 		racoon_free(splitlist_cidr);
2045 
2046 	if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_SPLIT_LOCAL) {
2047 		splitlist =
2048 		    splitnet_list_2str(iph1->mode_cfg->split_local, NETMASK);
2049 		splitlist_cidr =
2050 		    splitnet_list_2str(iph1->mode_cfg->split_local, CIDR);
2051 	} else {
2052 		splitlist = addrlist;
2053 		splitlist_cidr = addrlist;
2054 		addrlist[0] = '\0';
2055 	}
2056 
2057 	if (script_env_append(envp, envc, "SPLIT_LOCAL", splitlist) != 0) {
2058 		plog(LLV_ERROR, LOCATION, NULL, "Cannot set SPLIT_LOCAL\n");
2059 		return -1;
2060 	}
2061 	if (script_env_append(envp, envc,
2062 	    "SPLIT_LOCAL_CIDR", splitlist_cidr) != 0) {
2063 		plog(LLV_ERROR, LOCATION, NULL,
2064 		     "Cannot set SPLIT_LOCAL_CIDR\n");
2065 		return -1;
2066 	}
2067 	if (splitlist != addrlist)
2068 		racoon_free(splitlist);
2069 	if (splitlist_cidr != addrlist)
2070 		racoon_free(splitlist_cidr);
2071 
2072 	return 0;
2073 }
2074 
2075 int
2076 isakmp_cfg_resize_pool(size)
2077 	int size;
2078 {
2079 	struct isakmp_cfg_port *new_pool;
2080 	size_t len;
2081 	int i;
2082 
2083 	if (size == isakmp_cfg_config.pool_size)
2084 		return 0;
2085 
2086 	plog(LLV_INFO, LOCATION, NULL,
2087 	    "Resize address pool from %zu to %d\n",
2088 	    isakmp_cfg_config.pool_size, size);
2089 
2090 	/* If a pool already exists, check if we can shrink it */
2091 	if ((isakmp_cfg_config.port_pool != NULL) &&
2092 	    (size < isakmp_cfg_config.pool_size)) {
2093 		for (i = isakmp_cfg_config.pool_size-1; i >= size; --i) {
2094 			if (isakmp_cfg_config.port_pool[i].used) {
2095 				plog(LLV_ERROR, LOCATION, NULL,
2096 				    "resize pool from %zu to %d impossible "
2097 				    "port %d is in use\n",
2098 				    isakmp_cfg_config.pool_size, size, i);
2099 				size = i;
2100 				break;
2101 			}
2102 		}
2103 	}
2104 
2105 	len = size * sizeof(*isakmp_cfg_config.port_pool);
2106 	new_pool = racoon_realloc(isakmp_cfg_config.port_pool, len);
2107 	if (new_pool == NULL) {
2108 		plog(LLV_ERROR, LOCATION, NULL,
2109 		    "resize pool from %zu to %d impossible: %s",
2110 		    isakmp_cfg_config.pool_size, size, strerror(errno));
2111 		return -1;
2112 	}
2113 
2114 	/* If size increase, intialize correctly the new records */
2115 	if (size > isakmp_cfg_config.pool_size) {
2116 		size_t unit;
2117 		size_t old_size;
2118 
2119 		unit =  sizeof(*isakmp_cfg_config.port_pool);
2120 		old_size = isakmp_cfg_config.pool_size;
2121 
2122 		bzero((char *)new_pool + (old_size * unit),
2123 		    (size - old_size) * unit);
2124 	}
2125 
2126 	isakmp_cfg_config.port_pool = new_pool;
2127 	isakmp_cfg_config.pool_size = size;
2128 
2129 	return 0;
2130 }
2131 
2132 int
2133 isakmp_cfg_init(cold)
2134 	int cold;
2135 {
2136 	int i;
2137 	int error;
2138 
2139 	isakmp_cfg_config.network4 = (in_addr_t)0x00000000;
2140 	isakmp_cfg_config.netmask4 = (in_addr_t)0x00000000;
2141 	for (i = 0; i < MAXNS; i++)
2142 		isakmp_cfg_config.dns4[i] = (in_addr_t)0x00000000;
2143 	isakmp_cfg_config.dns4_index = 0;
2144 	for (i = 0; i < MAXWINS; i++)
2145 		isakmp_cfg_config.nbns4[i] = (in_addr_t)0x00000000;
2146 	isakmp_cfg_config.nbns4_index = 0;
2147 	if (cold == ISAKMP_CFG_INIT_COLD)
2148 		isakmp_cfg_config.port_pool = NULL;
2149 	isakmp_cfg_config.authsource = ISAKMP_CFG_AUTH_SYSTEM;
2150 	isakmp_cfg_config.groupsource = ISAKMP_CFG_GROUP_SYSTEM;
2151 	if (cold == ISAKMP_CFG_INIT_COLD) {
2152 		if (isakmp_cfg_config.grouplist != NULL) {
2153 			for (i = 0; i < isakmp_cfg_config.groupcount; i++)
2154 				racoon_free(isakmp_cfg_config.grouplist[i]);
2155 			racoon_free(isakmp_cfg_config.grouplist);
2156 		}
2157 	}
2158 	isakmp_cfg_config.grouplist = NULL;
2159 	isakmp_cfg_config.groupcount = 0;
2160 	isakmp_cfg_config.confsource = ISAKMP_CFG_CONF_LOCAL;
2161 	isakmp_cfg_config.accounting = ISAKMP_CFG_ACCT_NONE;
2162 	if (cold == ISAKMP_CFG_INIT_COLD)
2163 		isakmp_cfg_config.pool_size = 0;
2164 	isakmp_cfg_config.auth_throttle = THROTTLE_PENALTY;
2165 	strlcpy(isakmp_cfg_config.default_domain, ISAKMP_CFG_DEFAULT_DOMAIN,
2166 	    MAXPATHLEN);
2167 	strlcpy(isakmp_cfg_config.motd, ISAKMP_CFG_MOTD, MAXPATHLEN);
2168 
2169 	if (cold != ISAKMP_CFG_INIT_COLD )
2170 		if (isakmp_cfg_config.splitnet_list != NULL)
2171 			splitnet_list_free(isakmp_cfg_config.splitnet_list,
2172 				&isakmp_cfg_config.splitnet_count);
2173 	isakmp_cfg_config.splitnet_list = NULL;
2174 	isakmp_cfg_config.splitnet_count = 0;
2175 	isakmp_cfg_config.splitnet_type = 0;
2176 
2177 	isakmp_cfg_config.pfs_group = 0;
2178 	isakmp_cfg_config.save_passwd = 0;
2179 
2180 	if (cold != ISAKMP_CFG_INIT_COLD )
2181 		if (isakmp_cfg_config.splitdns_list != NULL)
2182 			racoon_free(isakmp_cfg_config.splitdns_list);
2183 	isakmp_cfg_config.splitdns_list = NULL;
2184 	isakmp_cfg_config.splitdns_len = 0;
2185 
2186 #if 0
2187 	if (cold == ISAKMP_CFG_INIT_COLD) {
2188 		if ((error = isakmp_cfg_resize_pool(ISAKMP_CFG_MAX_CNX)) != 0)
2189 			return error;
2190 	}
2191 #endif
2192 
2193 	return 0;
2194 }
2195 
2196