1 /*	$NetBSD: isakmp_cfg.c,v 1.29 2021/07/24 21:31:31 andvar 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
isakmp_cfg_r(iph1,msg)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
isakmp_cfg_attr_r(iph1,msgid,attrpl)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
isakmp_cfg_reply(iph1,attrpl)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 	int error;
326 
327 	tlen = ntohs(attrpl->h.len);
328 	attr = (struct isakmp_data *)(attrpl + 1);
329 	tlen -= sizeof(*attrpl);
330 
331 	while (tlen > 0) {
332 		type = ntohs(attr->type);
333 
334 		/* Handle short attributes */
335 		if ((type & ISAKMP_GEN_MASK) == ISAKMP_GEN_TV) {
336 			type &= ~ISAKMP_GEN_MASK;
337 
338 			plog(LLV_DEBUG, LOCATION, NULL,
339 			     "Short attribute %s = %d\n",
340 			     s_isakmp_cfg_type(type), ntohs(attr->lorv));
341 
342 			switch (type) {
343 			case XAUTH_TYPE:
344 				if ((error = xauth_attr_reply(iph1,
345 				    attr, ntohs(attrpl->id))) != 0)
346 					return error;
347 				break;
348 
349 			default:
350 				plog(LLV_WARNING, LOCATION, NULL,
351 				     "Ignored short attribute %s\n",
352 				     s_isakmp_cfg_type(type));
353 				break;
354 			}
355 
356 			tlen -= sizeof(*attr);
357 			attr++;
358 			continue;
359 		}
360 
361 		type = ntohs(attr->type);
362 		alen = ntohs(attr->lorv);
363 
364 		/* Check that the attribute fit in the packet */
365 		if (tlen < alen) {
366 			plog(LLV_ERROR, LOCATION, NULL,
367 			     "Short attribute %s\n",
368 			     s_isakmp_cfg_type(type));
369 			return -1;
370 		}
371 
372 		plog(LLV_DEBUG, LOCATION, NULL,
373 		     "Attribute %s, len %zu\n",
374 		     s_isakmp_cfg_type(type), alen);
375 
376 		switch(type) {
377 		case XAUTH_TYPE:
378 		case XAUTH_USER_NAME:
379 		case XAUTH_USER_PASSWORD:
380 		case XAUTH_PASSCODE:
381 		case XAUTH_MESSAGE:
382 		case XAUTH_CHALLENGE:
383 		case XAUTH_DOMAIN:
384 		case XAUTH_STATUS:
385 		case XAUTH_NEXT_PIN:
386 		case XAUTH_ANSWER:
387 			if ((error = xauth_attr_reply(iph1,
388 			    attr, ntohs(attrpl->id))) != 0)
389 				return error;
390 			break;
391 		case INTERNAL_IP4_ADDRESS:
392 			isakmp_cfg_getaddr4(attr, &iph1->mode_cfg->addr4);
393 			iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_ADDR4;
394 			break;
395 		case INTERNAL_IP4_NETMASK:
396 			isakmp_cfg_getaddr4(attr, &iph1->mode_cfg->mask4);
397 			iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_MASK4;
398 			break;
399 		case INTERNAL_IP4_DNS:
400 			isakmp_cfg_appendaddr4(attr,
401 			    &iph1->mode_cfg->dns4[iph1->mode_cfg->dns4_index],
402 			    &iph1->mode_cfg->dns4_index, MAXNS);
403 			iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_DNS4;
404 			break;
405 		case INTERNAL_IP4_NBNS:
406 			isakmp_cfg_appendaddr4(attr,
407 			    &iph1->mode_cfg->wins4[iph1->mode_cfg->wins4_index],
408 			    &iph1->mode_cfg->wins4_index, MAXNS);
409 			iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_WINS4;
410 			break;
411 		case UNITY_DEF_DOMAIN:
412 			isakmp_cfg_getstring(attr,
413 			    iph1->mode_cfg->default_domain);
414 			iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_DEFAULT_DOMAIN;
415 			break;
416 		case UNITY_SPLIT_INCLUDE:
417 		case UNITY_LOCAL_LAN:
418 		case UNITY_SPLITDNS_NAME:
419 		case UNITY_BANNER:
420 		case UNITY_SAVE_PASSWD:
421 		case UNITY_NATT_PORT:
422 		case UNITY_PFS:
423 		case UNITY_FW_TYPE:
424 		case UNITY_BACKUP_SERVERS:
425 		case UNITY_DDNS_HOSTNAME:
426 			isakmp_unity_reply(iph1, attr);
427 			break;
428 		case INTERNAL_IP4_SUBNET:
429 		case INTERNAL_ADDRESS_EXPIRY:
430 		default:
431 			plog(LLV_WARNING, LOCATION, NULL,
432 			     "Ignored attribute %s\n",
433 			     s_isakmp_cfg_type(type));
434 			break;
435 		}
436 
437 		npp = (char *)attr;
438 		attr = (struct isakmp_data *)(npp + sizeof(*attr) + alen);
439 		tlen -= (sizeof(*attr) + alen);
440 	}
441 
442 	/*
443 	 * Call the SA up script hook now that we have the configuration
444 	 * It is done at the end of phase 1 if ISAKMP mode config is not
445 	 * requested.
446 	 */
447 
448 	if ((iph1->status == PHASE1ST_ESTABLISHED) &&
449 	    iph1->rmconf->mode_cfg) {
450 		switch (iph1->approval->authmethod) {
451 		case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I:
452 		case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
453 		/* Unimplemented */
454 		case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I:
455 		case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I:
456 		case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I:
457 		case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I:
458 		case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I:
459 		case OAKLEY_ATTR_AUTH_METHOD_RSASIG:
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_phase1(iph1, EVT_PHASE1_MODE_CFG, buf);
479 			vfree(buf);
480 		}
481 	}
482 #endif
483 
484 	return 0;
485 }
486 
487 int
isakmp_cfg_request(iph1,attrpl)488 isakmp_cfg_request(iph1, attrpl)
489 	struct ph1handle *iph1;
490 	struct isakmp_pl_attr *attrpl;
491 {
492 	struct isakmp_data *attr;
493 	int tlen;
494 	size_t alen;
495 	char *npp;
496 	vchar_t *payload;
497 	struct isakmp_pl_attr *reply;
498 	vchar_t *reply_attr;
499 	int type;
500 	int error = -1;
501 
502 	if ((payload = vmalloc(sizeof(*reply))) == NULL) {
503 		plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
504 		return -1;
505 	}
506 	memset(payload->v, 0, sizeof(*reply));
507 
508 	tlen = ntohs(attrpl->h.len);
509 	attr = (struct isakmp_data *)(attrpl + 1);
510 	tlen -= sizeof(*attrpl);
511 
512 	while (tlen > 0) {
513 		reply_attr = NULL;
514 		type = ntohs(attr->type);
515 
516 		/* Handle short attributes */
517 		if ((type & ISAKMP_GEN_MASK) == ISAKMP_GEN_TV) {
518 			type &= ~ISAKMP_GEN_MASK;
519 
520 			plog(LLV_DEBUG, LOCATION, NULL,
521 			     "Short attribute %s = %d\n",
522 			     s_isakmp_cfg_type(type), ntohs(attr->lorv));
523 
524 			switch (type) {
525 			case XAUTH_TYPE:
526 				reply_attr = isakmp_xauth_req(iph1, attr);
527 				break;
528 			default:
529 				plog(LLV_WARNING, LOCATION, NULL,
530 				     "Ignored short attribute %s\n",
531 				     s_isakmp_cfg_type(type));
532 				break;
533 			}
534 
535 			tlen -= sizeof(*attr);
536 			attr++;
537 
538 			if (reply_attr != NULL) {
539 				payload = buffer_cat(payload, reply_attr);
540 				vfree(reply_attr);
541 			}
542 
543 			continue;
544 		}
545 
546 		type = ntohs(attr->type);
547 		alen = ntohs(attr->lorv);
548 
549 		/* Check that the attribute fit in the packet */
550 		if (tlen < alen) {
551 			plog(LLV_ERROR, LOCATION, NULL,
552 			     "Short attribute %s\n",
553 			     s_isakmp_cfg_type(type));
554 			goto end;
555 		}
556 
557 		plog(LLV_DEBUG, LOCATION, NULL,
558 		     "Attribute %s, len %zu\n",
559 		     s_isakmp_cfg_type(type), alen);
560 
561 		switch(type) {
562 		case INTERNAL_IP4_ADDRESS:
563 		case INTERNAL_IP4_NETMASK:
564 		case INTERNAL_IP4_DNS:
565 		case INTERNAL_IP4_NBNS:
566 		case INTERNAL_IP4_SUBNET:
567 			reply_attr = isakmp_cfg_net(iph1, attr);
568 			break;
569 
570 		case XAUTH_TYPE:
571 		case XAUTH_USER_NAME:
572 		case XAUTH_USER_PASSWORD:
573 		case XAUTH_PASSCODE:
574 		case XAUTH_MESSAGE:
575 		case XAUTH_CHALLENGE:
576 		case XAUTH_DOMAIN:
577 		case XAUTH_STATUS:
578 		case XAUTH_NEXT_PIN:
579 		case XAUTH_ANSWER:
580 			reply_attr = isakmp_xauth_req(iph1, attr);
581 			break;
582 
583 		case APPLICATION_VERSION:
584 			reply_attr = isakmp_cfg_string(iph1,
585 			    attr, ISAKMP_CFG_RACOON_VERSION);
586 			break;
587 
588 		case UNITY_BANNER:
589 		case UNITY_PFS:
590 		case UNITY_SAVE_PASSWD:
591 		case UNITY_DEF_DOMAIN:
592 		case UNITY_DDNS_HOSTNAME:
593 		case UNITY_FW_TYPE:
594 		case UNITY_SPLITDNS_NAME:
595 		case UNITY_SPLIT_INCLUDE:
596 		case UNITY_LOCAL_LAN:
597 		case UNITY_NATT_PORT:
598 		case UNITY_BACKUP_SERVERS:
599 			reply_attr = isakmp_unity_req(iph1, attr);
600 			break;
601 
602 		case INTERNAL_ADDRESS_EXPIRY:
603 		default:
604 			plog(LLV_WARNING, LOCATION, NULL,
605 			     "Ignored attribute %s\n",
606 			     s_isakmp_cfg_type(type));
607 			break;
608 		}
609 
610 		npp = (char *)attr;
611 		attr = (struct isakmp_data *)(npp + sizeof(*attr) + alen);
612 		tlen -= (sizeof(*attr) + alen);
613 
614 		if (reply_attr != NULL) {
615 			payload = buffer_cat(payload, reply_attr);
616 			vfree(reply_attr);
617 		}
618 
619 	}
620 
621 	reply = (struct isakmp_pl_attr *)payload->v;
622 	reply->h.len = htons(payload->l);
623 	reply->type = ISAKMP_CFG_REPLY;
624 	reply->id = attrpl->id;
625 
626 	plog(LLV_DEBUG, LOCATION, NULL,
627 		    "Sending MODE_CFG REPLY\n");
628 
629 	error = isakmp_cfg_send(iph1, payload,
630 	    ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 0);
631 
632 	if (iph1->status == PHASE1ST_ESTABLISHED) {
633 		switch (iph1->approval->authmethod) {
634 		case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R:
635 		case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R:
636 		/* Unimplemented */
637 		case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R:
638 		case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R:
639 		case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R:
640 		case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R:
641 		case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R:
642 		case OAKLEY_ATTR_AUTH_METHOD_RSASIG:
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
isakmp_cfg_set(iph1,attrpl)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 		    iph1->status == PHASE1ST_DYING)
738 			isakmp_info_send_d1(iph1);
739 		remph1(iph1);
740 		delph1(iph1);
741 		iph1 = NULL;
742 	}
743 
744 	vfree(payload);
745 
746 	/*
747 	 * If required, request ISAKMP mode config information
748 	 */
749 	if ((iph1 != NULL) && (iph1->rmconf->mode_cfg) && (error == 0))
750 		error = isakmp_cfg_getconfig(iph1);
751 
752 	return error;
753 }
754 
755 
756 static vchar_t *
buffer_cat(s,append)757 buffer_cat(s, append)
758 	vchar_t *s;
759 	vchar_t *append;
760 {
761 	vchar_t *new;
762 
763 	new = vmalloc(s->l + append->l);
764 	if (new == NULL) {
765 		plog(LLV_ERROR, LOCATION, NULL,
766 		    "Cannot allocate memory\n");
767 		return s;
768 	}
769 
770 	memcpy(new->v, s->v, s->l);
771 	memcpy(new->v + s->l, append->v, append->l);
772 
773 	vfree(s);
774 	return new;
775 }
776 
777 static vchar_t *
isakmp_cfg_net(iph1,attr)778 isakmp_cfg_net(iph1, attr)
779 	struct ph1handle *iph1;
780 	struct isakmp_data *attr;
781 {
782 	int type;
783 	int confsource;
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 		if(isakmp_cfg_config.splitnet_count > 0){
907 			return isakmp_cfg_addrnet4(iph1, attr,
908 						    &isakmp_cfg_config.splitnet_list->network.addr4.s_addr,
909 						    &isakmp_cfg_config.splitnet_list->network.mask4.s_addr);
910 		}else{
911 			plog(LLV_INFO, LOCATION, NULL,
912 			     "%s requested but no splitnet in configuration\n",
913 			     s_isakmp_cfg_type(type));
914 		}
915 		break;
916 
917 	default:
918 		plog(LLV_ERROR, LOCATION, NULL, "Unexpected type %d\n", type);
919 		break;
920 	}
921 	return NULL;
922 }
923 
924 #if 0
925 static vchar_t *
926 isakmp_cfg_void(iph1, attr)
927 	struct ph1handle *iph1;
928 	struct isakmp_data *attr;
929 {
930 	vchar_t *buffer;
931 	struct isakmp_data *new;
932 
933 	if ((buffer = vmalloc(sizeof(*attr))) == NULL) {
934 		plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
935 		return NULL;
936 	}
937 
938 	new = (struct isakmp_data *)buffer->v;
939 
940 	new->type = attr->type;
941 	new->lorv = htons(0);
942 
943 	return buffer;
944 }
945 #endif
946 
947 vchar_t *
isakmp_cfg_copy(iph1,attr)948 isakmp_cfg_copy(iph1, attr)
949 	struct ph1handle *iph1;
950 	struct isakmp_data *attr;
951 {
952 	vchar_t *buffer;
953 	size_t len = 0;
954 
955 	if ((ntohs(attr->type) & ISAKMP_GEN_MASK) == ISAKMP_GEN_TLV)
956 		len = ntohs(attr->lorv);
957 
958 	if ((buffer = vmalloc(sizeof(*attr) + len)) == NULL) {
959 		plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
960 		return NULL;
961 	}
962 
963 	memcpy(buffer->v, attr, sizeof(*attr) + ntohs(attr->lorv));
964 
965 	return buffer;
966 }
967 
968 vchar_t *
isakmp_cfg_short(iph1,attr,value)969 isakmp_cfg_short(iph1, attr, value)
970 	struct ph1handle *iph1;
971 	struct isakmp_data *attr;
972 	int value;
973 {
974 	vchar_t *buffer;
975 	struct isakmp_data *new;
976 	int type;
977 
978 	if ((buffer = vmalloc(sizeof(*attr))) == NULL) {
979 		plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
980 		return NULL;
981 	}
982 
983 	new = (struct isakmp_data *)buffer->v;
984 	type = ntohs(attr->type) & ~ISAKMP_GEN_MASK;
985 
986 	new->type = htons(type | ISAKMP_GEN_TV);
987 	new->lorv = htons(value);
988 
989 	return buffer;
990 }
991 
992 vchar_t *
isakmp_cfg_varlen(iph1,attr,string,len)993 isakmp_cfg_varlen(iph1, attr, string, len)
994 	struct ph1handle *iph1;
995 	struct isakmp_data *attr;
996 	char *string;
997 	size_t len;
998 {
999 	vchar_t *buffer;
1000 	struct isakmp_data *new;
1001 	char *data;
1002 
1003 	if (!len)
1004 		return NULL;
1005 
1006 	if ((buffer = vmalloc(sizeof(*attr) + len)) == NULL) {
1007 		plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
1008 		return NULL;
1009 	}
1010 
1011 	new = (struct isakmp_data *)buffer->v;
1012 
1013 	new->type = attr->type;
1014 	new->lorv = htons(len);
1015 	data = (char *)(new + 1);
1016 
1017 	memcpy(data, string, len);
1018 
1019 	return buffer;
1020 }
1021 vchar_t *
isakmp_cfg_string(iph1,attr,string)1022 isakmp_cfg_string(iph1, attr, string)
1023 	struct ph1handle *iph1;
1024 	struct isakmp_data *attr;
1025 	char *string;
1026 {
1027 	size_t len = strlen(string);
1028 	return isakmp_cfg_varlen(iph1, attr, string, len);
1029 }
1030 
1031 static vchar_t *
isakmp_cfg_addr4(iph1,attr,addr)1032 isakmp_cfg_addr4(iph1, attr, addr)
1033 	struct ph1handle *iph1;
1034 	struct isakmp_data *attr;
1035 	in_addr_t *addr;
1036 {
1037 	vchar_t *buffer;
1038 	struct isakmp_data *new;
1039 	size_t len;
1040 
1041 	len = sizeof(*addr);
1042 	if ((buffer = vmalloc(sizeof(*attr) + len)) == NULL) {
1043 		plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
1044 		return NULL;
1045 	}
1046 
1047 	new = (struct isakmp_data *)buffer->v;
1048 
1049 	new->type = attr->type;
1050 	new->lorv = htons(len);
1051 	memcpy(new + 1, addr, len);
1052 
1053 	return buffer;
1054 }
1055 
1056 static vchar_t *
isakmp_cfg_addrnet4(iph1,attr,addr,mask)1057 isakmp_cfg_addrnet4(iph1, attr, addr, mask)
1058 	struct ph1handle *iph1;
1059 	struct isakmp_data *attr;
1060 	in_addr_t *addr;
1061 	in_addr_t *mask;
1062 {
1063 	vchar_t *buffer;
1064 	struct isakmp_data *new;
1065 	size_t len;
1066 	in_addr_t netbuff[2];
1067 
1068 	len = sizeof(netbuff);
1069 	if ((buffer = vmalloc(sizeof(*attr) + len)) == NULL) {
1070 		plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
1071 		return NULL;
1072 	}
1073 
1074 	new = (struct isakmp_data *)buffer->v;
1075 
1076 	new->type = attr->type;
1077 	new->lorv = htons(len);
1078 	netbuff[0]=*addr;
1079 	netbuff[1]=*mask;
1080 	memcpy(new + 1, netbuff, len);
1081 
1082 	return buffer;
1083 }
1084 
1085 
1086 static vchar_t *
isakmp_cfg_addr4_list(iph1,attr,addr,nbr)1087 isakmp_cfg_addr4_list(iph1, attr, addr, nbr)
1088 	struct ph1handle *iph1;
1089 	struct isakmp_data *attr;
1090 	in_addr_t *addr;
1091 	int nbr;
1092 {
1093 	int error = -1;
1094 	vchar_t *buffer = NULL;
1095 	vchar_t *bufone = NULL;
1096 	struct isakmp_data *new;
1097 	size_t len;
1098 	int i;
1099 
1100 	len = sizeof(*addr);
1101 	if ((buffer = vmalloc(0)) == NULL) {
1102 		plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
1103 		goto out;
1104 	}
1105 	for(i = 0; i < nbr; i++) {
1106 		if ((bufone = vmalloc(sizeof(*attr) + len)) == NULL) {
1107 			plog(LLV_ERROR, LOCATION, NULL,
1108 			    "Cannot allocate memory\n");
1109 			goto out;
1110 		}
1111 		new = (struct isakmp_data *)bufone->v;
1112 		new->type = attr->type;
1113 		new->lorv = htons(len);
1114 		memcpy(new + 1, &addr[i], len);
1115 		new += (len + sizeof(*attr));
1116 		buffer = buffer_cat(buffer, bufone);
1117 		vfree(bufone);
1118 	}
1119 
1120 	error = 0;
1121 
1122 out:
1123 	if ((error != 0) && (buffer != NULL)) {
1124 		vfree(buffer);
1125 		buffer = NULL;
1126 	}
1127 
1128 	return buffer;
1129 }
1130 
1131 struct isakmp_ivm *
isakmp_cfg_newiv(iph1,msgid)1132 isakmp_cfg_newiv(iph1, msgid)
1133 	struct ph1handle *iph1;
1134 	u_int32_t msgid;
1135 {
1136 	struct isakmp_cfg_state *ics = iph1->mode_cfg;
1137 
1138 	if (ics == NULL) {
1139 		plog(LLV_ERROR, LOCATION, NULL,
1140 		    "isakmp_cfg_newiv called without mode config state\n");
1141 		return NULL;
1142 	}
1143 
1144 	if (ics->ivm != NULL)
1145 		oakley_delivm(ics->ivm);
1146 
1147 	ics->ivm = oakley_newiv2(iph1, msgid);
1148 	ics->last_msgid = msgid;
1149 
1150 	return ics->ivm;
1151 }
1152 
1153 /* Derived from isakmp_info_send_common */
1154 int
isakmp_cfg_send(iph1,payload,np,flags,new_exchange)1155 isakmp_cfg_send(iph1, payload, np, flags, new_exchange)
1156 	struct ph1handle *iph1;
1157 	vchar_t *payload;
1158 	u_int32_t np;
1159 	int flags;
1160 	int new_exchange;
1161 {
1162 	struct ph2handle *iph2 = NULL;
1163 	vchar_t *hash = NULL;
1164 	struct isakmp *isakmp;
1165 	struct isakmp_gen *gen;
1166 	char *p;
1167 	int tlen;
1168 	int error = -1;
1169 	struct isakmp_cfg_state *ics = iph1->mode_cfg;
1170 
1171 	/* Check if phase 1 is established */
1172 	if ((iph1->status < PHASE1ST_ESTABLISHED) ||
1173 	    (iph1->local == NULL) ||
1174 	    (iph1->remote == NULL)) {
1175 		plog(LLV_ERROR, LOCATION, NULL,
1176 		    "ISAKMP mode config exchange with immature phase 1\n");
1177 		goto end;
1178 	}
1179 
1180 	/* add new entry to isakmp status table */
1181 	iph2 = newph2();
1182 	if (iph2 == NULL)
1183 		goto end;
1184 
1185 	iph2->dst = dupsaddr(iph1->remote);
1186 	if (iph2->dst == NULL) {
1187 		delph2(iph2);
1188 		goto end;
1189 	}
1190 	iph2->src = dupsaddr(iph1->local);
1191 	if (iph2->src == NULL) {
1192 		delph2(iph2);
1193 		goto end;
1194 	}
1195 
1196 	iph2->side = INITIATOR;
1197 	iph2->status = PHASE2ST_START;
1198 
1199 	if (new_exchange)
1200 		iph2->msgid = isakmp_newmsgid2(iph1);
1201 	else
1202 		iph2->msgid = iph1->msgid;
1203 
1204 	/* get IV and HASH(1) if skeyid_a was generated. */
1205 	if (iph1->skeyid_a != NULL) {
1206 		if (new_exchange) {
1207 			if (isakmp_cfg_newiv(iph1, iph2->msgid) == NULL) {
1208 				delph2(iph2);
1209 				goto end;
1210 			}
1211 		}
1212 
1213 		/* generate HASH(1) */
1214 		hash = oakley_compute_hash1(iph1, iph2->msgid, payload);
1215 		if (hash == NULL) {
1216 			delph2(iph2);
1217 			goto end;
1218 		}
1219 
1220 		/* initialized total buffer length */
1221 		tlen = hash->l;
1222 		tlen += sizeof(*gen);
1223 	} else {
1224 		/* IKE-SA is not established */
1225 		hash = NULL;
1226 
1227 		/* initialized total buffer length */
1228 		tlen = 0;
1229 	}
1230 	if ((flags & ISAKMP_FLAG_A) == 0)
1231 		iph2->flags = (hash == NULL ? 0 : ISAKMP_FLAG_E);
1232 	else
1233 		iph2->flags = (hash == NULL ? 0 : ISAKMP_FLAG_A);
1234 
1235 	insph2(iph2);
1236 	bindph12(iph1, iph2);
1237 
1238 	tlen += sizeof(*isakmp) + payload->l;
1239 
1240 	/* create buffer for isakmp payload */
1241 	iph2->sendbuf = vmalloc(tlen);
1242 	if (iph2->sendbuf == NULL) {
1243 		plog(LLV_ERROR, LOCATION, NULL,
1244 			"failed to get buffer to send.\n");
1245 		goto err;
1246 	}
1247 
1248 	/* create isakmp header */
1249 	isakmp = (struct isakmp *)iph2->sendbuf->v;
1250 	memcpy(&isakmp->i_ck, &iph1->index.i_ck, sizeof(cookie_t));
1251 	memcpy(&isakmp->r_ck, &iph1->index.r_ck, sizeof(cookie_t));
1252 	isakmp->np = hash == NULL ? (np & 0xff) : ISAKMP_NPTYPE_HASH;
1253 	isakmp->v = iph1->version;
1254 	isakmp->etype = ISAKMP_ETYPE_CFG;
1255 	isakmp->flags = iph2->flags;
1256 	memcpy(&isakmp->msgid, &iph2->msgid, sizeof(isakmp->msgid));
1257 	isakmp->len = htonl(tlen);
1258 	p = (char *)(isakmp + 1);
1259 
1260 	/* create HASH payload */
1261 	if (hash != NULL) {
1262 		gen = (struct isakmp_gen *)p;
1263 		gen->np = np & 0xff;
1264 		gen->len = htons(sizeof(*gen) + hash->l);
1265 		p += sizeof(*gen);
1266 		memcpy(p, hash->v, hash->l);
1267 		p += hash->l;
1268 	}
1269 
1270 	/* add payload */
1271 	memcpy(p, payload->v, payload->l);
1272 	p += payload->l;
1273 
1274 #ifdef HAVE_PRINT_ISAKMP_C
1275 	isakmp_printpacket(iph2->sendbuf, iph1->local, iph1->remote, 1);
1276 #endif
1277 
1278 	plog(LLV_DEBUG, LOCATION, NULL, "MODE_CFG packet to send\n");
1279 	plogdump(LLV_DEBUG, iph2->sendbuf->v, iph2->sendbuf->l);
1280 
1281 	/* encoding */
1282 	if (ISSET(isakmp->flags, ISAKMP_FLAG_E)) {
1283 		vchar_t *tmp;
1284 
1285 		tmp = oakley_do_encrypt(iph2->ph1, iph2->sendbuf,
1286 			ics->ivm->ive, ics->ivm->iv);
1287 		VPTRINIT(iph2->sendbuf);
1288 		if (tmp == NULL)
1289 			goto err;
1290 		iph2->sendbuf = tmp;
1291 	}
1292 
1293 	/* HDR*, HASH(1), ATTR */
1294 	if (isakmp_send(iph2->ph1, iph2->sendbuf) < 0) {
1295 		VPTRINIT(iph2->sendbuf);
1296 		goto err;
1297 	}
1298 
1299 	plog(LLV_DEBUG, LOCATION, NULL,
1300 		"sendto mode config %s.\n", s_isakmp_nptype(np));
1301 
1302 	/*
1303 	 * XXX We might need to resend the message...
1304 	 */
1305 
1306 	error = 0;
1307 	VPTRINIT(iph2->sendbuf);
1308 
1309 err:
1310 	if (iph2->sendbuf != NULL)
1311 		vfree(iph2->sendbuf);
1312 
1313 	remph2(iph2);
1314 	delph2(iph2);
1315 end:
1316 	if (hash)
1317 		vfree(hash);
1318 	return error;
1319 }
1320 
1321 
1322 void
isakmp_cfg_rmstate(iph1)1323 isakmp_cfg_rmstate(iph1)
1324 	struct ph1handle *iph1;
1325 {
1326 	struct isakmp_cfg_state *state = iph1->mode_cfg;
1327 
1328 	if (isakmp_cfg_accounting(iph1, ISAKMP_CFG_LOGOUT) != 0)
1329 		plog(LLV_ERROR, LOCATION, NULL, "Accounting failed\n");
1330 
1331 	if (state->flags & ISAKMP_CFG_PORT_ALLOCATED)
1332 		isakmp_cfg_putport(iph1, state->port);
1333 
1334 	/* Delete the IV if it's still there */
1335 	if(iph1->mode_cfg->ivm) {
1336 		oakley_delivm(iph1->mode_cfg->ivm);
1337 		iph1->mode_cfg->ivm = NULL;
1338 	}
1339 
1340 	/* Free any allocated splitnet lists */
1341 	if(iph1->mode_cfg->split_include != NULL)
1342 		splitnet_list_free(iph1->mode_cfg->split_include,
1343 			&iph1->mode_cfg->include_count);
1344 	if(iph1->mode_cfg->split_local != NULL)
1345 		splitnet_list_free(iph1->mode_cfg->split_local,
1346 			&iph1->mode_cfg->local_count);
1347 
1348 	xauth_rmstate(&state->xauth);
1349 
1350 	racoon_free(state);
1351 	iph1->mode_cfg = NULL;
1352 
1353 	return;
1354 }
1355 
1356 struct isakmp_cfg_state *
isakmp_cfg_mkstate(void)1357 isakmp_cfg_mkstate(void)
1358 {
1359 	struct isakmp_cfg_state *state;
1360 
1361 	if ((state = racoon_malloc(sizeof(*state))) == NULL) {
1362 		plog(LLV_ERROR, LOCATION, NULL,
1363 		    "Cannot allocate memory for mode config state\n");
1364 		return NULL;
1365 	}
1366 	memset(state, 0, sizeof(*state));
1367 
1368 	return state;
1369 }
1370 
1371 int
isakmp_cfg_getport(iph1)1372 isakmp_cfg_getport(iph1)
1373 	struct ph1handle *iph1;
1374 {
1375 	unsigned int i;
1376 	size_t size = isakmp_cfg_config.pool_size;
1377 
1378 	if (iph1->mode_cfg->flags & ISAKMP_CFG_PORT_ALLOCATED)
1379 		return iph1->mode_cfg->port;
1380 
1381 	if (isakmp_cfg_config.port_pool == NULL) {
1382 		plog(LLV_ERROR, LOCATION, NULL,
1383 		    "isakmp_cfg_config.port_pool == NULL\n");
1384 		return -1;
1385 	}
1386 
1387 	for (i = 0; i < size; i++) {
1388 		if (isakmp_cfg_config.port_pool[i].used == 0)
1389 			break;
1390 	}
1391 
1392 	if (i == size) {
1393 		plog(LLV_ERROR, LOCATION, NULL,
1394 		    "No more addresses available\n");
1395 			return -1;
1396 	}
1397 
1398 	isakmp_cfg_config.port_pool[i].used = 1;
1399 
1400 	plog(LLV_INFO, LOCATION, NULL, "Using port %d\n", i);
1401 
1402 	iph1->mode_cfg->flags |= ISAKMP_CFG_PORT_ALLOCATED;
1403 	iph1->mode_cfg->port = i;
1404 
1405 	return i;
1406 }
1407 
1408 int
isakmp_cfg_putport(iph1,index)1409 isakmp_cfg_putport(iph1, index)
1410 	struct ph1handle *iph1;
1411 	unsigned int index;
1412 {
1413 	if (isakmp_cfg_config.port_pool == NULL) {
1414 		plog(LLV_ERROR, LOCATION, NULL,
1415 		    "isakmp_cfg_config.port_pool == NULL\n");
1416 		return -1;
1417 	}
1418 
1419 	if (isakmp_cfg_config.port_pool[index].used == 0) {
1420 		plog(LLV_ERROR, LOCATION, NULL,
1421 		    "Attempt to release an unallocated address (port %d)\n",
1422 		    index);
1423 		return -1;
1424 	}
1425 
1426 #ifdef HAVE_LIBPAM
1427 	/* Cleanup PAM status associated with the port */
1428 	if (isakmp_cfg_config.authsource == ISAKMP_CFG_AUTH_PAM)
1429 		privsep_cleanup_pam(index);
1430 #endif
1431 	isakmp_cfg_config.port_pool[index].used = 0;
1432 	iph1->mode_cfg->flags &= ISAKMP_CFG_PORT_ALLOCATED;
1433 
1434 	plog(LLV_INFO, LOCATION, NULL, "Released port %d\n", index);
1435 
1436 	return 0;
1437 }
1438 
1439 #ifdef HAVE_LIBPAM
1440 void
cleanup_pam(port)1441 cleanup_pam(port)
1442 	int port;
1443 {
1444 	if (isakmp_cfg_config.port_pool[port].pam != NULL) {
1445 		pam_end(isakmp_cfg_config.port_pool[port].pam, PAM_SUCCESS);
1446 		isakmp_cfg_config.port_pool[port].pam = NULL;
1447 	}
1448 
1449 	return;
1450 }
1451 #endif
1452 
1453 /* Accounting, only for RADIUS or PAM */
1454 static int
isakmp_cfg_accounting(iph1,inout)1455 isakmp_cfg_accounting(iph1, inout)
1456 	struct ph1handle *iph1;
1457 	int inout;
1458 {
1459 #ifdef HAVE_LIBPAM
1460 	if (isakmp_cfg_config.accounting == ISAKMP_CFG_ACCT_PAM)
1461 		return privsep_accounting_pam(iph1->mode_cfg->port,
1462 		    inout);
1463 #endif
1464 #ifdef HAVE_LIBRADIUS
1465 	if (isakmp_cfg_config.accounting == ISAKMP_CFG_ACCT_RADIUS)
1466 		return isakmp_cfg_accounting_radius(iph1, inout);
1467 #endif
1468 	if (isakmp_cfg_config.accounting == ISAKMP_CFG_ACCT_SYSTEM)
1469 		return privsep_accounting_system(iph1->mode_cfg->port,
1470 			iph1->remote, iph1->mode_cfg->login, inout);
1471 	return 0;
1472 }
1473 
1474 #ifdef HAVE_LIBPAM
1475 int
isakmp_cfg_accounting_pam(port,inout)1476 isakmp_cfg_accounting_pam(port, inout)
1477 	int port;
1478 	int inout;
1479 {
1480 	int error = 0;
1481 	pam_handle_t *pam;
1482 
1483 	if (isakmp_cfg_config.port_pool == NULL) {
1484 		plog(LLV_ERROR, LOCATION, NULL,
1485 		    "isakmp_cfg_config.port_pool == NULL\n");
1486 		return -1;
1487 	}
1488 
1489 	pam = isakmp_cfg_config.port_pool[port].pam;
1490 	if (pam == NULL) {
1491 		plog(LLV_ERROR, LOCATION, NULL, "pam handle is NULL\n");
1492 		return -1;
1493 	}
1494 
1495 	switch (inout) {
1496 	case ISAKMP_CFG_LOGIN:
1497 		error = pam_open_session(pam, 0);
1498 		break;
1499 	case ISAKMP_CFG_LOGOUT:
1500 		error = pam_close_session(pam, 0);
1501 		pam_end(pam, error);
1502 		isakmp_cfg_config.port_pool[port].pam = NULL;
1503 		break;
1504 	default:
1505 		plog(LLV_ERROR, LOCATION, NULL, "Unepected inout\n");
1506 		break;
1507 	}
1508 
1509 	if (error != 0) {
1510 		plog(LLV_ERROR, LOCATION, NULL,
1511 		    "pam_open_session/pam_close_session failed: %s\n",
1512 		    pam_strerror(pam, error));
1513 		return -1;
1514         }
1515 
1516 	return 0;
1517 }
1518 #endif /* HAVE_LIBPAM */
1519 
1520 #ifdef HAVE_LIBRADIUS
1521 static int
isakmp_cfg_accounting_radius(iph1,inout)1522 isakmp_cfg_accounting_radius(iph1, inout)
1523 	struct ph1handle *iph1;
1524 	int inout;
1525 {
1526 	if (rad_create_request(radius_acct_state,
1527 	    RAD_ACCOUNTING_REQUEST) != 0) {
1528 		plog(LLV_ERROR, LOCATION, NULL,
1529 		    "rad_create_request failed: %s\n",
1530 		    rad_strerror(radius_acct_state));
1531 		return -1;
1532 	}
1533 
1534 	if (rad_put_string(radius_acct_state, RAD_USER_NAME,
1535 	    iph1->mode_cfg->login) != 0) {
1536 		plog(LLV_ERROR, LOCATION, NULL,
1537 		    "rad_put_string failed: %s\n",
1538 		    rad_strerror(radius_acct_state));
1539 		return -1;
1540 	}
1541 
1542 	switch (inout) {
1543 	case ISAKMP_CFG_LOGIN:
1544 		inout = RAD_START;
1545 		break;
1546 	case ISAKMP_CFG_LOGOUT:
1547 		inout = RAD_STOP;
1548 		break;
1549 	default:
1550 		plog(LLV_ERROR, LOCATION, NULL, "Unepected inout\n");
1551 		break;
1552 	}
1553 
1554 	if (rad_put_addr(radius_acct_state,
1555 	    RAD_FRAMED_IP_ADDRESS, iph1->mode_cfg->addr4) != 0) {
1556 		plog(LLV_ERROR, LOCATION, NULL,
1557 		    "rad_put_addr failed: %s\n",
1558 		    rad_strerror(radius_acct_state));
1559 		return -1;
1560 	}
1561 
1562 	if (rad_put_addr(radius_acct_state,
1563 	    RAD_LOGIN_IP_HOST, iph1->mode_cfg->addr4) != 0) {
1564 		plog(LLV_ERROR, LOCATION, NULL,
1565 		    "rad_put_addr failed: %s\n",
1566 		    rad_strerror(radius_acct_state));
1567 		return -1;
1568 	}
1569 
1570 	if (rad_put_int(radius_acct_state, RAD_ACCT_STATUS_TYPE, inout) != 0) {
1571 		plog(LLV_ERROR, LOCATION, NULL,
1572 		    "rad_put_int failed: %s\n",
1573 		    rad_strerror(radius_acct_state));
1574 		return -1;
1575 	}
1576 
1577 	if (isakmp_cfg_radius_common(radius_acct_state,
1578 	    iph1->mode_cfg->port) != 0)
1579 		return -1;
1580 
1581 	if (rad_send_request(radius_acct_state) != RAD_ACCOUNTING_RESPONSE) {
1582 		plog(LLV_ERROR, LOCATION, NULL,
1583 		    "rad_send_request failed: %s\n",
1584 		    rad_strerror(radius_acct_state));
1585 		return -1;
1586 	}
1587 
1588 	return 0;
1589 }
1590 #endif /* HAVE_LIBRADIUS */
1591 
1592 /*
1593  * Attributes common to all RADIUS requests
1594  */
1595 #ifdef HAVE_LIBRADIUS
1596 int
isakmp_cfg_radius_common(radius_state,port)1597 isakmp_cfg_radius_common(radius_state, port)
1598 	struct rad_handle *radius_state;
1599 	int port;
1600 {
1601 	struct utsname name;
1602 	static struct hostent *host = NULL;
1603 	struct in_addr nas_addr;
1604 
1605 	/*
1606 	 * Find our own IP by resolving our nodename
1607 	 */
1608 	if (host == NULL) {
1609 		if (uname(&name) != 0) {
1610 			plog(LLV_ERROR, LOCATION, NULL,
1611 			    "uname failed: %s\n", strerror(errno));
1612 			return -1;
1613 		}
1614 
1615 		if ((host = gethostbyname(name.nodename)) == NULL) {
1616 			plog(LLV_ERROR, LOCATION, NULL,
1617 			    "gethostbyname failed: %s\n", strerror(errno));
1618 			return -1;
1619 		}
1620 	}
1621 
1622 	memcpy(&nas_addr, host->h_addr, sizeof(nas_addr));
1623 	if (rad_put_addr(radius_state, RAD_NAS_IP_ADDRESS, nas_addr) != 0) {
1624 		plog(LLV_ERROR, LOCATION, NULL,
1625 		    "rad_put_addr failed: %s\n",
1626 		    rad_strerror(radius_state));
1627 		return -1;
1628 	}
1629 
1630 	if (rad_put_int(radius_state, RAD_NAS_PORT, port) != 0) {
1631 		plog(LLV_ERROR, LOCATION, NULL,
1632 		    "rad_put_int failed: %s\n",
1633 		    rad_strerror(radius_state));
1634 		return -1;
1635 	}
1636 
1637 	if (rad_put_int(radius_state, RAD_NAS_PORT_TYPE, RAD_VIRTUAL) != 0) {
1638 		plog(LLV_ERROR, LOCATION, NULL,
1639 		    "rad_put_int failed: %s\n",
1640 		    rad_strerror(radius_state));
1641 		return -1;
1642 	}
1643 
1644 	if (rad_put_int(radius_state, RAD_SERVICE_TYPE, RAD_FRAMED) != 0) {
1645 		plog(LLV_ERROR, LOCATION, NULL,
1646 		    "rad_put_int failed: %s\n",
1647 		    rad_strerror(radius_state));
1648 		return -1;
1649 	}
1650 
1651 	return 0;
1652 }
1653 #endif
1654 
1655 /*
1656 	Logs the user into the utmp system files.
1657 */
1658 
1659 int
isakmp_cfg_accounting_system(port,raddr,usr,inout)1660 isakmp_cfg_accounting_system(port, raddr, usr, inout)
1661 	int port;
1662 	struct sockaddr *raddr;
1663 	char *usr;
1664 	int inout;
1665 {
1666 	struct utmpx ut;
1667 	char addr[NI_MAXHOST];
1668 
1669 	if (usr == NULL || usr[0]=='\0') {
1670 		plog(LLV_ERROR, LOCATION, NULL,
1671 			"system accounting : no login found\n");
1672 		return -1;
1673 	}
1674 
1675 	memset(&ut, 0, sizeof ut);
1676 	gettimeofday((struct timeval *)&ut.ut_tv, NULL);
1677 	snprintf(ut.ut_id, sizeof ut.ut_id, TERMSPEC, port);
1678 
1679 	switch (inout) {
1680 	case ISAKMP_CFG_LOGIN:
1681 		ut.ut_type = USER_PROCESS;
1682 		strncpy(ut.ut_user, usr, sizeof ut.ut_user);
1683 
1684 		GETNAMEINFO_NULL(raddr, addr);
1685 		strncpy(ut.ut_host, addr, sizeof ut.ut_host);
1686 
1687 		plog(LLV_INFO, LOCATION, NULL,
1688 			"Accounting : '%s' logging on '%s' from %s.\n",
1689 			ut.ut_user, ut.ut_id, addr);
1690 
1691 		pututxline(&ut);
1692 
1693 		break;
1694 	case ISAKMP_CFG_LOGOUT:
1695 		ut.ut_type = DEAD_PROCESS;
1696 
1697 		plog(LLV_INFO, LOCATION, NULL,
1698 			"Accounting : '%s' unlogging from '%s'.\n",
1699 			usr, ut.ut_id);
1700 
1701 		pututxline(&ut);
1702 
1703 		break;
1704 	default:
1705 		plog(LLV_ERROR, LOCATION, NULL, "Unepected inout\n");
1706 		break;
1707 	}
1708 
1709 	return 0;
1710 }
1711 
1712 int
isakmp_cfg_getconfig(iph1)1713 isakmp_cfg_getconfig(iph1)
1714 	struct ph1handle *iph1;
1715 {
1716 	vchar_t *buffer;
1717 	struct isakmp_pl_attr *attrpl;
1718 	struct isakmp_data *attr;
1719 	size_t len;
1720 	int error;
1721 	int attrcount;
1722 	int i;
1723 	int attrlist[] = {
1724 		INTERNAL_IP4_ADDRESS,
1725 		INTERNAL_IP4_NETMASK,
1726 		INTERNAL_IP4_DNS,
1727 		INTERNAL_IP4_NBNS,
1728 		UNITY_BANNER,
1729 		UNITY_DEF_DOMAIN,
1730 		UNITY_SPLITDNS_NAME,
1731 		UNITY_SPLIT_INCLUDE,
1732 		UNITY_LOCAL_LAN,
1733 		APPLICATION_VERSION,
1734 	};
1735 
1736 	attrcount = sizeof(attrlist) / sizeof(*attrlist);
1737 	len = sizeof(*attrpl) + sizeof(*attr) * attrcount;
1738 
1739 	if ((buffer = vmalloc(len)) == NULL) {
1740 		plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
1741 		return -1;
1742 	}
1743 
1744 	attrpl = (struct isakmp_pl_attr *)buffer->v;
1745 	attrpl->h.len = htons(len);
1746 	attrpl->type = ISAKMP_CFG_REQUEST;
1747 	attrpl->id = htons((u_int16_t)(eay_random() & 0xffff));
1748 
1749 	attr = (struct isakmp_data *)(attrpl + 1);
1750 
1751 	for (i = 0; i < attrcount; i++) {
1752 		attr->type = htons(attrlist[i]);
1753 		attr->lorv = htons(0);
1754 		attr++;
1755 	}
1756 
1757 	plog(LLV_DEBUG, LOCATION, NULL,
1758 		    "Sending MODE_CFG REQUEST\n");
1759 
1760 	error = isakmp_cfg_send(iph1, buffer,
1761 	    ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 1);
1762 
1763 	vfree(buffer);
1764 
1765 	return error;
1766 }
1767 
1768 static void
isakmp_cfg_getaddr4(attr,ip)1769 isakmp_cfg_getaddr4(attr, ip)
1770 	struct isakmp_data *attr;
1771 	struct in_addr *ip;
1772 {
1773 	size_t alen = ntohs(attr->lorv);
1774 	in_addr_t *addr;
1775 
1776 	if (alen != sizeof(*ip)) {
1777 		plog(LLV_ERROR, LOCATION, NULL, "Bad IPv4 address len\n");
1778 		return;
1779 	}
1780 
1781 	addr = (in_addr_t *)(attr + 1);
1782 	ip->s_addr = *addr;
1783 
1784 	return;
1785 }
1786 
1787 static void
isakmp_cfg_appendaddr4(attr,ip,num,max)1788 isakmp_cfg_appendaddr4(attr, ip, num, max)
1789 	struct isakmp_data *attr;
1790 	struct in_addr *ip;
1791 	int *num;
1792 	int max;
1793 {
1794 	size_t alen = ntohs(attr->lorv);
1795 	in_addr_t *addr;
1796 
1797 	if (alen != sizeof(*ip)) {
1798 		plog(LLV_ERROR, LOCATION, NULL, "Bad IPv4 address len\n");
1799 		return;
1800 	}
1801 	if (*num == max) {
1802 		plog(LLV_ERROR, LOCATION, NULL, "Too many addresses given\n");
1803 		return;
1804 	}
1805 
1806 	addr = (in_addr_t *)(attr + 1);
1807 	ip->s_addr = *addr;
1808 	(*num)++;
1809 
1810 	return;
1811 }
1812 
1813 static void
isakmp_cfg_getstring(attr,str)1814 isakmp_cfg_getstring(attr, str)
1815 	struct isakmp_data *attr;
1816 	char *str;
1817 {
1818 	size_t alen = ntohs(attr->lorv);
1819 	char *src;
1820 	src = (char *)(attr + 1);
1821 
1822 	memcpy(str, src, (alen > MAXPATHLEN ? MAXPATHLEN : alen));
1823 
1824 	return;
1825 }
1826 
1827 #define IP_MAX 40
1828 
1829 void
isakmp_cfg_iplist_to_str(dest,count,addr,withmask)1830 isakmp_cfg_iplist_to_str(dest, count, addr, withmask)
1831 	char *dest;
1832 	int count;
1833 	void *addr;
1834 	int withmask;
1835 {
1836 	int i;
1837 	int p;
1838 	int l;
1839 	struct unity_network tmp;
1840 	for(i = 0, p = 0; i < count; i++) {
1841 		if(withmask == 1)
1842 			l = sizeof(struct unity_network);
1843 		else
1844 			l = sizeof(struct in_addr);
1845 		memcpy(&tmp, addr, l);
1846 		addr += l;
1847 		if((uint32_t)tmp.addr4.s_addr == 0)
1848 			break;
1849 
1850 		inet_ntop(AF_INET, &tmp.addr4, dest + p, IP_MAX);
1851 		p += strlen(dest + p);
1852 		if(withmask == 1) {
1853 			dest[p] = '/';
1854 			p++;
1855 			inet_ntop(AF_INET, &tmp.mask4, dest + p, IP_MAX);
1856 			p += strlen(dest + p);
1857 		}
1858 		dest[p] = ' ';
1859 		p++;
1860 	}
1861 	if(p > 0)
1862 		dest[p-1] = '\0';
1863 	else
1864 		dest[0] = '\0';
1865 }
1866 
1867 int
isakmp_cfg_setenv(iph1,envp,envc)1868 isakmp_cfg_setenv(iph1, envp, envc)
1869 	struct ph1handle *iph1;
1870 	char ***envp;
1871 	int *envc;
1872 {
1873 	char addrstr[IP_MAX];
1874 	char addrlist[IP_MAX * MAXNS + MAXNS];
1875 	char *splitlist = addrlist;
1876 	char *splitlist_cidr;
1877 	char defdom[MAXPATHLEN + 1];
1878 	int cidr, tmp;
1879 	char cidrstr[4];
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 	/* Default 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
isakmp_cfg_resize_pool(size)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
isakmp_cfg_init(cold)2128 isakmp_cfg_init(cold)
2129 	int cold;
2130 {
2131 	int i;
2132 
2133 	isakmp_cfg_config.network4 = (in_addr_t)0x00000000;
2134 	isakmp_cfg_config.netmask4 = (in_addr_t)0x00000000;
2135 	for (i = 0; i < MAXNS; i++)
2136 		isakmp_cfg_config.dns4[i] = (in_addr_t)0x00000000;
2137 	isakmp_cfg_config.dns4_index = 0;
2138 	for (i = 0; i < MAXWINS; i++)
2139 		isakmp_cfg_config.nbns4[i] = (in_addr_t)0x00000000;
2140 	isakmp_cfg_config.nbns4_index = 0;
2141 	if (cold == ISAKMP_CFG_INIT_COLD)
2142 		isakmp_cfg_config.port_pool = NULL;
2143 	isakmp_cfg_config.authsource = ISAKMP_CFG_AUTH_SYSTEM;
2144 	isakmp_cfg_config.groupsource = ISAKMP_CFG_GROUP_SYSTEM;
2145 	if (cold == ISAKMP_CFG_INIT_COLD) {
2146 		if (isakmp_cfg_config.grouplist != NULL) {
2147 			for (i = 0; i < isakmp_cfg_config.groupcount; i++)
2148 				racoon_free(isakmp_cfg_config.grouplist[i]);
2149 			racoon_free(isakmp_cfg_config.grouplist);
2150 		}
2151 	}
2152 	isakmp_cfg_config.grouplist = NULL;
2153 	isakmp_cfg_config.groupcount = 0;
2154 	isakmp_cfg_config.confsource = ISAKMP_CFG_CONF_LOCAL;
2155 	isakmp_cfg_config.accounting = ISAKMP_CFG_ACCT_NONE;
2156 	if (cold == ISAKMP_CFG_INIT_COLD)
2157 		isakmp_cfg_config.pool_size = 0;
2158 	isakmp_cfg_config.auth_throttle = THROTTLE_PENALTY;
2159 	strlcpy(isakmp_cfg_config.default_domain, ISAKMP_CFG_DEFAULT_DOMAIN,
2160 	    MAXPATHLEN);
2161 	strlcpy(isakmp_cfg_config.motd, ISAKMP_CFG_MOTD, MAXPATHLEN);
2162 
2163 	if (cold != ISAKMP_CFG_INIT_COLD )
2164 		if (isakmp_cfg_config.splitnet_list != NULL)
2165 			splitnet_list_free(isakmp_cfg_config.splitnet_list,
2166 				&isakmp_cfg_config.splitnet_count);
2167 	isakmp_cfg_config.splitnet_list = NULL;
2168 	isakmp_cfg_config.splitnet_count = 0;
2169 	isakmp_cfg_config.splitnet_type = 0;
2170 
2171 	isakmp_cfg_config.pfs_group = 0;
2172 	isakmp_cfg_config.save_passwd = 0;
2173 
2174 	if (cold != ISAKMP_CFG_INIT_COLD )
2175 		if (isakmp_cfg_config.splitdns_list != NULL)
2176 			racoon_free(isakmp_cfg_config.splitdns_list);
2177 	isakmp_cfg_config.splitdns_list = NULL;
2178 	isakmp_cfg_config.splitdns_len = 0;
2179 
2180 #if 0
2181 	int error;
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