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