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