Annotation of embedaddon/ipsec-tools/src/racoon/isakmp_cfg.c, revision 1.1.1.2
1.1.1.2 ! misho 1: /* $NetBSD: isakmp_cfg.c,v 1.24.4.1 2013/04/12 10:04:21 tteras Exp $ */
1.1 misho 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:
1.1.1.2 ! misho 41: #if __FreeBSD_version >= 900007
1.1 misho 42: #include <utmpx.h>
1.1.1.2 ! misho 43: #endif
1.1 misho 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
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
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
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
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
658: isakmp_cfg_set(iph1, attrpl)
659: struct ph1handle *iph1;
660: struct isakmp_pl_attr *attrpl;
661: {
662: struct isakmp_data *attr;
663: int tlen;
664: size_t alen;
665: char *npp;
666: vchar_t *payload;
667: struct isakmp_pl_attr *reply;
668: vchar_t *reply_attr;
669: int type;
670: int error = -1;
671:
672: if ((payload = vmalloc(sizeof(*reply))) == NULL) {
673: plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
674: return -1;
675: }
676: memset(payload->v, 0, sizeof(*reply));
677:
678: tlen = ntohs(attrpl->h.len);
679: attr = (struct isakmp_data *)(attrpl + 1);
680: tlen -= sizeof(*attrpl);
681:
682: /*
683: * We should send ack for the attributes we accepted
684: */
685: while (tlen > 0) {
686: reply_attr = NULL;
687: type = ntohs(attr->type);
688:
689: plog(LLV_DEBUG, LOCATION, NULL,
690: "Attribute %s\n",
691: s_isakmp_cfg_type(type & ~ISAKMP_GEN_MASK));
692:
693: switch (type & ~ISAKMP_GEN_MASK) {
694: case XAUTH_STATUS:
695: reply_attr = isakmp_xauth_set(iph1, attr);
696: break;
697: default:
698: plog(LLV_DEBUG, LOCATION, NULL,
699: "Unexpected SET attribute %s\n",
700: s_isakmp_cfg_type(type & ~ISAKMP_GEN_MASK));
701: break;
702: }
703:
704: if (reply_attr != NULL) {
705: payload = buffer_cat(payload, reply_attr);
706: vfree(reply_attr);
707: }
708:
709: /*
710: * Move to next attribute. If we run out of the packet,
711: * tlen becomes negative and we exit.
712: */
713: if ((type & ISAKMP_GEN_MASK) == ISAKMP_GEN_TV) {
714: tlen -= sizeof(*attr);
715: attr++;
716: } else {
717: alen = ntohs(attr->lorv);
718: tlen -= (sizeof(*attr) + alen);
719: npp = (char *)attr;
720: attr = (struct isakmp_data *)
721: (npp + sizeof(*attr) + alen);
722: }
723: }
724:
725: reply = (struct isakmp_pl_attr *)payload->v;
726: reply->h.len = htons(payload->l);
727: reply->type = ISAKMP_CFG_ACK;
728: reply->id = attrpl->id;
729:
730: plog(LLV_DEBUG, LOCATION, NULL,
731: "Sending MODE_CFG ACK\n");
732:
733: error = isakmp_cfg_send(iph1, payload,
734: ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 0);
735:
736: if (iph1->mode_cfg->flags & ISAKMP_CFG_DELETE_PH1) {
737: if (iph1->status == PHASE1ST_ESTABLISHED ||
738: iph1->status == PHASE1ST_DYING)
739: isakmp_info_send_d1(iph1);
740: remph1(iph1);
741: delph1(iph1);
742: iph1 = NULL;
743: }
744: end:
745: vfree(payload);
746:
747: /*
748: * If required, request ISAKMP mode config information
749: */
750: if ((iph1 != NULL) && (iph1->rmconf->mode_cfg) && (error == 0))
751: error = isakmp_cfg_getconfig(iph1);
752:
753: return error;
754: }
755:
756:
757: static vchar_t *
758: buffer_cat(s, append)
759: vchar_t *s;
760: vchar_t *append;
761: {
762: vchar_t *new;
763:
764: new = vmalloc(s->l + append->l);
765: if (new == NULL) {
766: plog(LLV_ERROR, LOCATION, NULL,
767: "Cannot allocate memory\n");
768: return s;
769: }
770:
771: memcpy(new->v, s->v, s->l);
772: memcpy(new->v + s->l, append->v, append->l);
773:
774: vfree(s);
775: return new;
776: }
777:
778: static vchar_t *
779: isakmp_cfg_net(iph1, attr)
780: struct ph1handle *iph1;
781: struct isakmp_data *attr;
782: {
783: int type;
784: int confsource;
785: in_addr_t addr4;
786:
787: type = ntohs(attr->type);
788:
789: /*
790: * Don't give an address to a peer that did not succeed Xauth
791: */
792: if (xauth_check(iph1) != 0) {
793: plog(LLV_ERROR, LOCATION, NULL,
794: "Attempt to start phase config whereas Xauth failed\n");
795: return NULL;
796: }
797:
798: confsource = isakmp_cfg_config.confsource;
799: /*
800: * If we have to fall back to a local
801: * configuration source, we will jump
802: * back to this point.
803: */
804: retry_source:
805:
806: switch(type) {
807: case INTERNAL_IP4_ADDRESS:
808: switch(confsource) {
809: #ifdef HAVE_LIBLDAP
810: case ISAKMP_CFG_CONF_LDAP:
811: if (iph1->mode_cfg->flags & ISAKMP_CFG_ADDR4_EXTERN)
812: break;
813: plog(LLV_INFO, LOCATION, NULL,
814: "No IP from LDAP, using local pool\n");
815: /* FALLTHROUGH */
816: confsource = ISAKMP_CFG_CONF_LOCAL;
817: goto retry_source;
818: #endif
819: #ifdef HAVE_LIBRADIUS
820: case ISAKMP_CFG_CONF_RADIUS:
821: if ((iph1->mode_cfg->flags & ISAKMP_CFG_ADDR4_EXTERN)
822: && (iph1->mode_cfg->addr4.s_addr != htonl(-2)))
823: /*
824: * -2 is 255.255.255.254, RADIUS uses that
825: * to instruct the NAS to use a local pool
826: */
827: break;
828: plog(LLV_INFO, LOCATION, NULL,
829: "No IP from RADIUS, using local pool\n");
830: /* FALLTHROUGH */
831: confsource = ISAKMP_CFG_CONF_LOCAL;
832: goto retry_source;
833: #endif
834: case ISAKMP_CFG_CONF_LOCAL:
835: if (isakmp_cfg_getport(iph1) == -1) {
836: plog(LLV_ERROR, LOCATION, NULL,
837: "Port pool depleted\n");
838: break;
839: }
840:
841: iph1->mode_cfg->addr4.s_addr =
842: htonl(ntohl(isakmp_cfg_config.network4)
843: + iph1->mode_cfg->port);
844: iph1->mode_cfg->flags |= ISAKMP_CFG_ADDR4_LOCAL;
845: break;
846:
847: default:
848: plog(LLV_ERROR, LOCATION, NULL,
849: "Unexpected confsource\n");
850: }
851:
852: if (isakmp_cfg_accounting(iph1, ISAKMP_CFG_LOGIN) != 0)
853: plog(LLV_ERROR, LOCATION, NULL, "Accounting failed\n");
854:
855: return isakmp_cfg_addr4(iph1,
856: attr, &iph1->mode_cfg->addr4.s_addr);
857: break;
858:
859: case INTERNAL_IP4_NETMASK:
860: switch(confsource) {
861: #ifdef HAVE_LIBLDAP
862: case ISAKMP_CFG_CONF_LDAP:
863: if (iph1->mode_cfg->flags & ISAKMP_CFG_MASK4_EXTERN)
864: break;
865: plog(LLV_INFO, LOCATION, NULL,
866: "No mask from LDAP, using local pool\n");
867: /* FALLTHROUGH */
868: confsource = ISAKMP_CFG_CONF_LOCAL;
869: goto retry_source;
870: #endif
871: #ifdef HAVE_LIBRADIUS
872: case ISAKMP_CFG_CONF_RADIUS:
873: if (iph1->mode_cfg->flags & ISAKMP_CFG_MASK4_EXTERN)
874: break;
875: plog(LLV_INFO, LOCATION, NULL,
876: "No mask from RADIUS, using local pool\n");
877: /* FALLTHROUGH */
878: confsource = ISAKMP_CFG_CONF_LOCAL;
879: goto retry_source;
880: #endif
881: case ISAKMP_CFG_CONF_LOCAL:
882: iph1->mode_cfg->mask4.s_addr
883: = isakmp_cfg_config.netmask4;
884: iph1->mode_cfg->flags |= ISAKMP_CFG_MASK4_LOCAL;
885: break;
886:
887: default:
888: plog(LLV_ERROR, LOCATION, NULL,
889: "Unexpected confsource\n");
890: }
891: return isakmp_cfg_addr4(iph1, attr,
892: &iph1->mode_cfg->mask4.s_addr);
893: break;
894:
895: case INTERNAL_IP4_DNS:
896: return isakmp_cfg_addr4_list(iph1,
897: attr, &isakmp_cfg_config.dns4[0],
898: isakmp_cfg_config.dns4_index);
899: break;
900:
901: case INTERNAL_IP4_NBNS:
902: return isakmp_cfg_addr4_list(iph1,
903: attr, &isakmp_cfg_config.nbns4[0],
904: isakmp_cfg_config.nbns4_index);
905: break;
906:
907: case INTERNAL_IP4_SUBNET:
908: if(isakmp_cfg_config.splitnet_count > 0){
909: return isakmp_cfg_addrnet4(iph1, attr,
910: &isakmp_cfg_config.splitnet_list->network.addr4.s_addr,
911: &isakmp_cfg_config.splitnet_list->network.mask4.s_addr);
912: }else{
913: plog(LLV_INFO, LOCATION, NULL,
914: "%s requested but no splitnet in configuration\n",
915: s_isakmp_cfg_type(type));
916: }
917: break;
918:
919: default:
920: plog(LLV_ERROR, LOCATION, NULL, "Unexpected type %d\n", type);
921: break;
922: }
923: return NULL;
924: }
925:
926: #if 0
927: static vchar_t *
928: isakmp_cfg_void(iph1, attr)
929: struct ph1handle *iph1;
930: struct isakmp_data *attr;
931: {
932: vchar_t *buffer;
933: struct isakmp_data *new;
934:
935: if ((buffer = vmalloc(sizeof(*attr))) == NULL) {
936: plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
937: return NULL;
938: }
939:
940: new = (struct isakmp_data *)buffer->v;
941:
942: new->type = attr->type;
943: new->lorv = htons(0);
944:
945: return buffer;
946: }
947: #endif
948:
949: vchar_t *
950: isakmp_cfg_copy(iph1, attr)
951: struct ph1handle *iph1;
952: struct isakmp_data *attr;
953: {
954: vchar_t *buffer;
955: size_t len = 0;
956:
957: if ((ntohs(attr->type) & ISAKMP_GEN_MASK) == ISAKMP_GEN_TLV)
958: len = ntohs(attr->lorv);
959:
960: if ((buffer = vmalloc(sizeof(*attr) + len)) == NULL) {
961: plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
962: return NULL;
963: }
964:
965: memcpy(buffer->v, attr, sizeof(*attr) + ntohs(attr->lorv));
966:
967: return buffer;
968: }
969:
970: vchar_t *
971: isakmp_cfg_short(iph1, attr, value)
972: struct ph1handle *iph1;
973: struct isakmp_data *attr;
974: int value;
975: {
976: vchar_t *buffer;
977: struct isakmp_data *new;
978: int type;
979:
980: if ((buffer = vmalloc(sizeof(*attr))) == NULL) {
981: plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
982: return NULL;
983: }
984:
985: new = (struct isakmp_data *)buffer->v;
986: type = ntohs(attr->type) & ~ISAKMP_GEN_MASK;
987:
988: new->type = htons(type | ISAKMP_GEN_TV);
989: new->lorv = htons(value);
990:
991: return buffer;
992: }
993:
994: vchar_t *
995: isakmp_cfg_varlen(iph1, attr, string, len)
996: struct ph1handle *iph1;
997: struct isakmp_data *attr;
998: char *string;
999: size_t len;
1000: {
1001: vchar_t *buffer;
1002: struct isakmp_data *new;
1003: char *data;
1004:
1.1.1.2 ! misho 1005: if (!len)
! 1006: return NULL;
! 1007:
1.1 misho 1008: if ((buffer = vmalloc(sizeof(*attr) + len)) == NULL) {
1009: plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
1010: return NULL;
1011: }
1012:
1013: new = (struct isakmp_data *)buffer->v;
1014:
1015: new->type = attr->type;
1016: new->lorv = htons(len);
1017: data = (char *)(new + 1);
1018:
1019: memcpy(data, string, len);
1020:
1021: return buffer;
1022: }
1023: vchar_t *
1024: isakmp_cfg_string(iph1, attr, string)
1025: struct ph1handle *iph1;
1026: struct isakmp_data *attr;
1027: char *string;
1028: {
1029: size_t len = strlen(string);
1030: return isakmp_cfg_varlen(iph1, attr, string, len);
1031: }
1032:
1033: static vchar_t *
1034: isakmp_cfg_addr4(iph1, attr, addr)
1035: struct ph1handle *iph1;
1036: struct isakmp_data *attr;
1037: in_addr_t *addr;
1038: {
1039: vchar_t *buffer;
1040: struct isakmp_data *new;
1041: size_t len;
1042:
1043: len = sizeof(*addr);
1044: if ((buffer = vmalloc(sizeof(*attr) + len)) == NULL) {
1045: plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
1046: return NULL;
1047: }
1048:
1049: new = (struct isakmp_data *)buffer->v;
1050:
1051: new->type = attr->type;
1052: new->lorv = htons(len);
1053: memcpy(new + 1, addr, len);
1054:
1055: return buffer;
1056: }
1057:
1058: static vchar_t *
1059: isakmp_cfg_addrnet4(iph1, attr, addr, mask)
1060: struct ph1handle *iph1;
1061: struct isakmp_data *attr;
1062: in_addr_t *addr;
1063: in_addr_t *mask;
1064: {
1065: vchar_t *buffer;
1066: struct isakmp_data *new;
1067: size_t len;
1068: in_addr_t netbuff[2];
1069:
1070: len = sizeof(netbuff);
1071: if ((buffer = vmalloc(sizeof(*attr) + len)) == NULL) {
1072: plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
1073: return NULL;
1074: }
1075:
1076: new = (struct isakmp_data *)buffer->v;
1077:
1078: new->type = attr->type;
1079: new->lorv = htons(len);
1080: netbuff[0]=*addr;
1081: netbuff[1]=*mask;
1082: memcpy(new + 1, netbuff, len);
1083:
1084: return buffer;
1085: }
1086:
1087:
1088: static vchar_t *
1089: isakmp_cfg_addr4_list(iph1, attr, addr, nbr)
1090: struct ph1handle *iph1;
1091: struct isakmp_data *attr;
1092: in_addr_t *addr;
1093: int nbr;
1094: {
1095: int error = -1;
1096: vchar_t *buffer = NULL;
1097: vchar_t *bufone = NULL;
1098: struct isakmp_data *new;
1099: size_t len;
1100: int i;
1101:
1102: len = sizeof(*addr);
1103: if ((buffer = vmalloc(0)) == NULL) {
1104: plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
1105: goto out;
1106: }
1107: for(i = 0; i < nbr; i++) {
1108: if ((bufone = vmalloc(sizeof(*attr) + len)) == NULL) {
1109: plog(LLV_ERROR, LOCATION, NULL,
1110: "Cannot allocate memory\n");
1111: goto out;
1112: }
1113: new = (struct isakmp_data *)bufone->v;
1114: new->type = attr->type;
1115: new->lorv = htons(len);
1116: memcpy(new + 1, &addr[i], len);
1117: new += (len + sizeof(*attr));
1118: buffer = buffer_cat(buffer, bufone);
1119: vfree(bufone);
1120: }
1121:
1122: error = 0;
1123:
1124: out:
1125: if ((error != 0) && (buffer != NULL)) {
1126: vfree(buffer);
1127: buffer = NULL;
1128: }
1129:
1130: return buffer;
1131: }
1132:
1133: struct isakmp_ivm *
1134: isakmp_cfg_newiv(iph1, msgid)
1135: struct ph1handle *iph1;
1136: u_int32_t msgid;
1137: {
1138: struct isakmp_cfg_state *ics = iph1->mode_cfg;
1139:
1140: if (ics == NULL) {
1141: plog(LLV_ERROR, LOCATION, NULL,
1142: "isakmp_cfg_newiv called without mode config state\n");
1143: return NULL;
1144: }
1145:
1146: if (ics->ivm != NULL)
1147: oakley_delivm(ics->ivm);
1148:
1149: ics->ivm = oakley_newiv2(iph1, msgid);
1150: ics->last_msgid = msgid;
1151:
1152: return ics->ivm;
1153: }
1154:
1155: /* Derived from isakmp_info_send_common */
1156: int
1157: isakmp_cfg_send(iph1, payload, np, flags, new_exchange)
1158: struct ph1handle *iph1;
1159: vchar_t *payload;
1160: u_int32_t np;
1161: int flags;
1162: int new_exchange;
1163: {
1164: struct ph2handle *iph2 = NULL;
1165: vchar_t *hash = NULL;
1166: struct isakmp *isakmp;
1167: struct isakmp_gen *gen;
1168: char *p;
1169: int tlen;
1170: int error = -1;
1171: struct isakmp_cfg_state *ics = iph1->mode_cfg;
1172:
1173: /* Check if phase 1 is established */
1174: if ((iph1->status < PHASE1ST_ESTABLISHED) ||
1175: (iph1->local == NULL) ||
1176: (iph1->remote == NULL)) {
1177: plog(LLV_ERROR, LOCATION, NULL,
1178: "ISAKMP mode config exchange with immature phase 1\n");
1179: goto end;
1180: }
1181:
1182: /* add new entry to isakmp status table */
1183: iph2 = newph2();
1184: if (iph2 == NULL)
1185: goto end;
1186:
1187: iph2->dst = dupsaddr(iph1->remote);
1188: if (iph2->dst == NULL) {
1189: delph2(iph2);
1190: goto end;
1191: }
1192: iph2->src = dupsaddr(iph1->local);
1193: if (iph2->src == NULL) {
1194: delph2(iph2);
1195: goto end;
1196: }
1197:
1198: iph2->side = INITIATOR;
1199: iph2->status = PHASE2ST_START;
1200:
1201: if (new_exchange)
1202: iph2->msgid = isakmp_newmsgid2(iph1);
1203: else
1204: iph2->msgid = iph1->msgid;
1205:
1206: /* get IV and HASH(1) if skeyid_a was generated. */
1207: if (iph1->skeyid_a != NULL) {
1208: if (new_exchange) {
1209: if (isakmp_cfg_newiv(iph1, iph2->msgid) == NULL) {
1210: delph2(iph2);
1211: goto end;
1212: }
1213: }
1214:
1215: /* generate HASH(1) */
1216: hash = oakley_compute_hash1(iph1, iph2->msgid, payload);
1217: if (hash == NULL) {
1218: delph2(iph2);
1219: goto end;
1220: }
1221:
1222: /* initialized total buffer length */
1223: tlen = hash->l;
1224: tlen += sizeof(*gen);
1225: } else {
1226: /* IKE-SA is not established */
1227: hash = NULL;
1228:
1229: /* initialized total buffer length */
1230: tlen = 0;
1231: }
1232: if ((flags & ISAKMP_FLAG_A) == 0)
1233: iph2->flags = (hash == NULL ? 0 : ISAKMP_FLAG_E);
1234: else
1235: iph2->flags = (hash == NULL ? 0 : ISAKMP_FLAG_A);
1236:
1237: insph2(iph2);
1238: bindph12(iph1, iph2);
1239:
1240: tlen += sizeof(*isakmp) + payload->l;
1241:
1242: /* create buffer for isakmp payload */
1243: iph2->sendbuf = vmalloc(tlen);
1244: if (iph2->sendbuf == NULL) {
1245: plog(LLV_ERROR, LOCATION, NULL,
1246: "failed to get buffer to send.\n");
1247: goto err;
1248: }
1249:
1250: /* create isakmp header */
1251: isakmp = (struct isakmp *)iph2->sendbuf->v;
1252: memcpy(&isakmp->i_ck, &iph1->index.i_ck, sizeof(cookie_t));
1253: memcpy(&isakmp->r_ck, &iph1->index.r_ck, sizeof(cookie_t));
1254: isakmp->np = hash == NULL ? (np & 0xff) : ISAKMP_NPTYPE_HASH;
1255: isakmp->v = iph1->version;
1256: isakmp->etype = ISAKMP_ETYPE_CFG;
1257: isakmp->flags = iph2->flags;
1258: memcpy(&isakmp->msgid, &iph2->msgid, sizeof(isakmp->msgid));
1259: isakmp->len = htonl(tlen);
1260: p = (char *)(isakmp + 1);
1261:
1262: /* create HASH payload */
1263: if (hash != NULL) {
1264: gen = (struct isakmp_gen *)p;
1265: gen->np = np & 0xff;
1266: gen->len = htons(sizeof(*gen) + hash->l);
1267: p += sizeof(*gen);
1268: memcpy(p, hash->v, hash->l);
1269: p += hash->l;
1270: }
1271:
1272: /* add payload */
1273: memcpy(p, payload->v, payload->l);
1274: p += payload->l;
1275:
1276: #ifdef HAVE_PRINT_ISAKMP_C
1277: isakmp_printpacket(iph2->sendbuf, iph1->local, iph1->remote, 1);
1278: #endif
1279:
1280: plog(LLV_DEBUG, LOCATION, NULL, "MODE_CFG packet to send\n");
1281: plogdump(LLV_DEBUG, iph2->sendbuf->v, iph2->sendbuf->l);
1282:
1283: /* encoding */
1284: if (ISSET(isakmp->flags, ISAKMP_FLAG_E)) {
1285: vchar_t *tmp;
1286:
1287: tmp = oakley_do_encrypt(iph2->ph1, iph2->sendbuf,
1288: ics->ivm->ive, ics->ivm->iv);
1289: VPTRINIT(iph2->sendbuf);
1290: if (tmp == NULL)
1291: goto err;
1292: iph2->sendbuf = tmp;
1293: }
1294:
1295: /* HDR*, HASH(1), ATTR */
1296: if (isakmp_send(iph2->ph1, iph2->sendbuf) < 0) {
1297: VPTRINIT(iph2->sendbuf);
1298: goto err;
1299: }
1300:
1301: plog(LLV_DEBUG, LOCATION, NULL,
1302: "sendto mode config %s.\n", s_isakmp_nptype(np));
1303:
1304: /*
1305: * XXX We might need to resend the message...
1306: */
1307:
1308: error = 0;
1309: VPTRINIT(iph2->sendbuf);
1310:
1311: err:
1312: if (iph2->sendbuf != NULL)
1313: vfree(iph2->sendbuf);
1314:
1315: remph2(iph2);
1316: delph2(iph2);
1317: end:
1318: if (hash)
1319: vfree(hash);
1320: return error;
1321: }
1322:
1323:
1324: void
1325: isakmp_cfg_rmstate(iph1)
1326: struct ph1handle *iph1;
1327: {
1328: struct isakmp_cfg_state *state = iph1->mode_cfg;
1329:
1330: if (isakmp_cfg_accounting(iph1, ISAKMP_CFG_LOGOUT) != 0)
1331: plog(LLV_ERROR, LOCATION, NULL, "Accounting failed\n");
1332:
1333: if (state->flags & ISAKMP_CFG_PORT_ALLOCATED)
1334: isakmp_cfg_putport(iph1, state->port);
1335:
1336: /* Delete the IV if it's still there */
1337: if(iph1->mode_cfg->ivm) {
1338: oakley_delivm(iph1->mode_cfg->ivm);
1339: iph1->mode_cfg->ivm = NULL;
1340: }
1341:
1342: /* Free any allocated splitnet lists */
1343: if(iph1->mode_cfg->split_include != NULL)
1344: splitnet_list_free(iph1->mode_cfg->split_include,
1345: &iph1->mode_cfg->include_count);
1346: if(iph1->mode_cfg->split_local != NULL)
1347: splitnet_list_free(iph1->mode_cfg->split_local,
1348: &iph1->mode_cfg->local_count);
1349:
1350: xauth_rmstate(&state->xauth);
1351:
1352: racoon_free(state);
1353: iph1->mode_cfg = NULL;
1354:
1355: return;
1356: }
1357:
1358: struct isakmp_cfg_state *
1359: isakmp_cfg_mkstate(void)
1360: {
1361: struct isakmp_cfg_state *state;
1362:
1363: if ((state = racoon_malloc(sizeof(*state))) == NULL) {
1364: plog(LLV_ERROR, LOCATION, NULL,
1365: "Cannot allocate memory for mode config state\n");
1366: return NULL;
1367: }
1368: memset(state, 0, sizeof(*state));
1369:
1370: return state;
1371: }
1372:
1373: int
1374: isakmp_cfg_getport(iph1)
1375: struct ph1handle *iph1;
1376: {
1377: unsigned int i;
1378: size_t size = isakmp_cfg_config.pool_size;
1379:
1380: if (iph1->mode_cfg->flags & ISAKMP_CFG_PORT_ALLOCATED)
1381: return iph1->mode_cfg->port;
1382:
1383: if (isakmp_cfg_config.port_pool == NULL) {
1384: plog(LLV_ERROR, LOCATION, NULL,
1385: "isakmp_cfg_config.port_pool == NULL\n");
1386: return -1;
1387: }
1388:
1389: for (i = 0; i < size; i++) {
1390: if (isakmp_cfg_config.port_pool[i].used == 0)
1391: break;
1392: }
1393:
1394: if (i == size) {
1395: plog(LLV_ERROR, LOCATION, NULL,
1396: "No more addresses available\n");
1397: return -1;
1398: }
1399:
1400: isakmp_cfg_config.port_pool[i].used = 1;
1401:
1402: plog(LLV_INFO, LOCATION, NULL, "Using port %d\n", i);
1403:
1404: iph1->mode_cfg->flags |= ISAKMP_CFG_PORT_ALLOCATED;
1405: iph1->mode_cfg->port = i;
1406:
1407: return i;
1408: }
1409:
1410: int
1411: isakmp_cfg_putport(iph1, index)
1412: struct ph1handle *iph1;
1413: unsigned int index;
1414: {
1415: if (isakmp_cfg_config.port_pool == NULL) {
1416: plog(LLV_ERROR, LOCATION, NULL,
1417: "isakmp_cfg_config.port_pool == NULL\n");
1418: return -1;
1419: }
1420:
1421: if (isakmp_cfg_config.port_pool[index].used == 0) {
1422: plog(LLV_ERROR, LOCATION, NULL,
1423: "Attempt to release an unallocated address (port %d)\n",
1424: index);
1425: return -1;
1426: }
1427:
1428: #ifdef HAVE_LIBPAM
1429: /* Cleanup PAM status associated with the port */
1430: if (isakmp_cfg_config.authsource == ISAKMP_CFG_AUTH_PAM)
1431: privsep_cleanup_pam(index);
1432: #endif
1433: isakmp_cfg_config.port_pool[index].used = 0;
1434: iph1->mode_cfg->flags &= ISAKMP_CFG_PORT_ALLOCATED;
1435:
1436: plog(LLV_INFO, LOCATION, NULL, "Released port %d\n", index);
1437:
1438: return 0;
1439: }
1440:
1441: #ifdef HAVE_LIBPAM
1442: void
1443: cleanup_pam(port)
1444: int port;
1445: {
1446: if (isakmp_cfg_config.port_pool[port].pam != NULL) {
1447: pam_end(isakmp_cfg_config.port_pool[port].pam, PAM_SUCCESS);
1448: isakmp_cfg_config.port_pool[port].pam = NULL;
1449: }
1450:
1451: return;
1452: }
1453: #endif
1454:
1455: /* Accounting, only for RADIUS or PAM */
1456: static int
1457: isakmp_cfg_accounting(iph1, inout)
1458: struct ph1handle *iph1;
1459: int inout;
1460: {
1461: #ifdef HAVE_LIBPAM
1462: if (isakmp_cfg_config.accounting == ISAKMP_CFG_ACCT_PAM)
1463: return privsep_accounting_pam(iph1->mode_cfg->port,
1464: inout);
1465: #endif
1466: #ifdef HAVE_LIBRADIUS
1467: if (isakmp_cfg_config.accounting == ISAKMP_CFG_ACCT_RADIUS)
1468: return isakmp_cfg_accounting_radius(iph1, inout);
1469: #endif
1470: if (isakmp_cfg_config.accounting == ISAKMP_CFG_ACCT_SYSTEM)
1471: return privsep_accounting_system(iph1->mode_cfg->port,
1472: iph1->remote, iph1->mode_cfg->login, inout);
1473: return 0;
1474: }
1475:
1476: #ifdef HAVE_LIBPAM
1477: int
1478: isakmp_cfg_accounting_pam(port, inout)
1479: int port;
1480: int inout;
1481: {
1482: int error = 0;
1483: pam_handle_t *pam;
1484:
1485: if (isakmp_cfg_config.port_pool == NULL) {
1486: plog(LLV_ERROR, LOCATION, NULL,
1487: "isakmp_cfg_config.port_pool == NULL\n");
1488: return -1;
1489: }
1490:
1491: pam = isakmp_cfg_config.port_pool[port].pam;
1492: if (pam == NULL) {
1493: plog(LLV_ERROR, LOCATION, NULL, "pam handle is NULL\n");
1494: return -1;
1495: }
1496:
1497: switch (inout) {
1498: case ISAKMP_CFG_LOGIN:
1499: error = pam_open_session(pam, 0);
1500: break;
1501: case ISAKMP_CFG_LOGOUT:
1502: error = pam_close_session(pam, 0);
1503: pam_end(pam, error);
1504: isakmp_cfg_config.port_pool[port].pam = NULL;
1505: break;
1506: default:
1507: plog(LLV_ERROR, LOCATION, NULL, "Unepected inout\n");
1508: break;
1509: }
1510:
1511: if (error != 0) {
1512: plog(LLV_ERROR, LOCATION, NULL,
1513: "pam_open_session/pam_close_session failed: %s\n",
1514: pam_strerror(pam, error));
1515: return -1;
1516: }
1517:
1518: return 0;
1519: }
1520: #endif /* HAVE_LIBPAM */
1521:
1522: #ifdef HAVE_LIBRADIUS
1523: static int
1524: isakmp_cfg_accounting_radius(iph1, inout)
1525: struct ph1handle *iph1;
1526: int inout;
1527: {
1528: if (rad_create_request(radius_acct_state,
1529: RAD_ACCOUNTING_REQUEST) != 0) {
1530: plog(LLV_ERROR, LOCATION, NULL,
1531: "rad_create_request failed: %s\n",
1532: rad_strerror(radius_acct_state));
1533: return -1;
1534: }
1535:
1536: if (rad_put_string(radius_acct_state, RAD_USER_NAME,
1537: iph1->mode_cfg->login) != 0) {
1538: plog(LLV_ERROR, LOCATION, NULL,
1539: "rad_put_string failed: %s\n",
1540: rad_strerror(radius_acct_state));
1541: return -1;
1542: }
1543:
1544: switch (inout) {
1545: case ISAKMP_CFG_LOGIN:
1546: inout = RAD_START;
1547: break;
1548: case ISAKMP_CFG_LOGOUT:
1549: inout = RAD_STOP;
1550: break;
1551: default:
1552: plog(LLV_ERROR, LOCATION, NULL, "Unepected inout\n");
1553: break;
1554: }
1555:
1556: if (rad_put_addr(radius_acct_state,
1557: RAD_FRAMED_IP_ADDRESS, iph1->mode_cfg->addr4) != 0) {
1558: plog(LLV_ERROR, LOCATION, NULL,
1559: "rad_put_addr failed: %s\n",
1560: rad_strerror(radius_acct_state));
1561: return -1;
1562: }
1563:
1564: if (rad_put_addr(radius_acct_state,
1565: RAD_LOGIN_IP_HOST, iph1->mode_cfg->addr4) != 0) {
1566: plog(LLV_ERROR, LOCATION, NULL,
1567: "rad_put_addr failed: %s\n",
1568: rad_strerror(radius_acct_state));
1569: return -1;
1570: }
1571:
1572: if (rad_put_int(radius_acct_state, RAD_ACCT_STATUS_TYPE, inout) != 0) {
1573: plog(LLV_ERROR, LOCATION, NULL,
1574: "rad_put_int failed: %s\n",
1575: rad_strerror(radius_acct_state));
1576: return -1;
1577: }
1578:
1579: if (isakmp_cfg_radius_common(radius_acct_state,
1580: iph1->mode_cfg->port) != 0)
1581: return -1;
1582:
1583: if (rad_send_request(radius_acct_state) != RAD_ACCOUNTING_RESPONSE) {
1584: plog(LLV_ERROR, LOCATION, NULL,
1585: "rad_send_request failed: %s\n",
1586: rad_strerror(radius_acct_state));
1587: return -1;
1588: }
1589:
1590: return 0;
1591: }
1592: #endif /* HAVE_LIBRADIUS */
1593:
1594: /*
1595: * Attributes common to all RADIUS requests
1596: */
1597: #ifdef HAVE_LIBRADIUS
1598: int
1599: isakmp_cfg_radius_common(radius_state, port)
1600: struct rad_handle *radius_state;
1601: int port;
1602: {
1603: struct utsname name;
1604: static struct hostent *host = NULL;
1605: struct in_addr nas_addr;
1606:
1607: /*
1608: * Find our own IP by resolving our nodename
1609: */
1610: if (host == NULL) {
1611: if (uname(&name) != 0) {
1612: plog(LLV_ERROR, LOCATION, NULL,
1613: "uname failed: %s\n", strerror(errno));
1614: return -1;
1615: }
1616:
1617: if ((host = gethostbyname(name.nodename)) == NULL) {
1618: plog(LLV_ERROR, LOCATION, NULL,
1619: "gethostbyname failed: %s\n", strerror(errno));
1620: return -1;
1621: }
1622: }
1623:
1624: memcpy(&nas_addr, host->h_addr, sizeof(nas_addr));
1625: if (rad_put_addr(radius_state, RAD_NAS_IP_ADDRESS, nas_addr) != 0) {
1626: plog(LLV_ERROR, LOCATION, NULL,
1627: "rad_put_addr failed: %s\n",
1628: rad_strerror(radius_state));
1629: return -1;
1630: }
1631:
1632: if (rad_put_int(radius_state, RAD_NAS_PORT, port) != 0) {
1633: plog(LLV_ERROR, LOCATION, NULL,
1634: "rad_put_int failed: %s\n",
1635: rad_strerror(radius_state));
1636: return -1;
1637: }
1638:
1639: if (rad_put_int(radius_state, RAD_NAS_PORT_TYPE, RAD_VIRTUAL) != 0) {
1640: plog(LLV_ERROR, LOCATION, NULL,
1641: "rad_put_int failed: %s\n",
1642: rad_strerror(radius_state));
1643: return -1;
1644: }
1645:
1646: if (rad_put_int(radius_state, RAD_SERVICE_TYPE, RAD_FRAMED) != 0) {
1647: plog(LLV_ERROR, LOCATION, NULL,
1648: "rad_put_int failed: %s\n",
1649: rad_strerror(radius_state));
1650: return -1;
1651: }
1652:
1653: return 0;
1654: }
1655: #endif
1656:
1657: /*
1658: Logs the user into the utmp system files.
1659: */
1660:
1661: int
1662: isakmp_cfg_accounting_system(port, raddr, usr, inout)
1663: int port;
1664: struct sockaddr *raddr;
1665: char *usr;
1666: int inout;
1667: {
1.1.1.2 ! misho 1668: #if __FreeBSD_version >= 900007
1.1 misho 1669: int error = 0;
1670: struct utmpx ut;
1671: char addr[NI_MAXHOST];
1672:
1673: if (usr == NULL || usr[0]=='\0') {
1674: plog(LLV_ERROR, LOCATION, NULL,
1675: "system accounting : no login found\n");
1676: return -1;
1677: }
1678:
1679: memset(&ut, 0, sizeof ut);
1680: gettimeofday((struct timeval *)&ut.ut_tv, NULL);
1681: snprintf(ut.ut_id, sizeof ut.ut_id, TERMSPEC, port);
1682:
1683: switch (inout) {
1684: case ISAKMP_CFG_LOGIN:
1685: ut.ut_type = USER_PROCESS;
1686: strncpy(ut.ut_user, usr, sizeof ut.ut_user);
1687:
1688: GETNAMEINFO_NULL(raddr, addr);
1689: strncpy(ut.ut_host, addr, sizeof ut.ut_host);
1690:
1691: plog(LLV_INFO, LOCATION, NULL,
1692: "Accounting : '%s' logging on '%s' from %s.\n",
1693: ut.ut_user, ut.ut_id, addr);
1694:
1695: pututxline(&ut);
1696:
1697: break;
1698: case ISAKMP_CFG_LOGOUT:
1699: ut.ut_type = DEAD_PROCESS;
1700:
1701: plog(LLV_INFO, LOCATION, NULL,
1702: "Accounting : '%s' unlogging from '%s'.\n",
1703: usr, ut.ut_id);
1704:
1705: pututxline(&ut);
1706:
1707: break;
1708: default:
1709: plog(LLV_ERROR, LOCATION, NULL, "Unepected inout\n");
1710: break;
1711: }
1.1.1.2 ! misho 1712: #endif
1.1 misho 1713:
1714: return 0;
1715: }
1716:
1717: int
1718: isakmp_cfg_getconfig(iph1)
1719: struct ph1handle *iph1;
1720: {
1721: vchar_t *buffer;
1722: struct isakmp_pl_attr *attrpl;
1723: struct isakmp_data *attr;
1724: size_t len;
1725: int error;
1726: int attrcount;
1727: int i;
1728: int attrlist[] = {
1729: INTERNAL_IP4_ADDRESS,
1730: INTERNAL_IP4_NETMASK,
1731: INTERNAL_IP4_DNS,
1732: INTERNAL_IP4_NBNS,
1733: UNITY_BANNER,
1734: UNITY_DEF_DOMAIN,
1735: UNITY_SPLITDNS_NAME,
1736: UNITY_SPLIT_INCLUDE,
1737: UNITY_LOCAL_LAN,
1738: APPLICATION_VERSION,
1739: };
1740:
1741: attrcount = sizeof(attrlist) / sizeof(*attrlist);
1742: len = sizeof(*attrpl) + sizeof(*attr) * attrcount;
1743:
1744: if ((buffer = vmalloc(len)) == NULL) {
1745: plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
1746: return -1;
1747: }
1748:
1749: attrpl = (struct isakmp_pl_attr *)buffer->v;
1750: attrpl->h.len = htons(len);
1751: attrpl->type = ISAKMP_CFG_REQUEST;
1752: attrpl->id = htons((u_int16_t)(eay_random() & 0xffff));
1753:
1754: attr = (struct isakmp_data *)(attrpl + 1);
1755:
1756: for (i = 0; i < attrcount; i++) {
1757: attr->type = htons(attrlist[i]);
1758: attr->lorv = htons(0);
1759: attr++;
1760: }
1761:
1762: plog(LLV_DEBUG, LOCATION, NULL,
1763: "Sending MODE_CFG REQUEST\n");
1764:
1765: error = isakmp_cfg_send(iph1, buffer,
1766: ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 1);
1767:
1768: vfree(buffer);
1769:
1770: return error;
1771: }
1772:
1773: static void
1774: isakmp_cfg_getaddr4(attr, ip)
1775: struct isakmp_data *attr;
1776: struct in_addr *ip;
1777: {
1778: size_t alen = ntohs(attr->lorv);
1779: in_addr_t *addr;
1780:
1781: if (alen != sizeof(*ip)) {
1782: plog(LLV_ERROR, LOCATION, NULL, "Bad IPv4 address len\n");
1783: return;
1784: }
1785:
1786: addr = (in_addr_t *)(attr + 1);
1787: ip->s_addr = *addr;
1788:
1789: return;
1790: }
1791:
1792: static void
1793: isakmp_cfg_appendaddr4(attr, ip, num, max)
1794: struct isakmp_data *attr;
1795: struct in_addr *ip;
1796: int *num;
1797: int max;
1798: {
1799: size_t alen = ntohs(attr->lorv);
1800: in_addr_t *addr;
1801:
1802: if (alen != sizeof(*ip)) {
1803: plog(LLV_ERROR, LOCATION, NULL, "Bad IPv4 address len\n");
1804: return;
1805: }
1806: if (*num == max) {
1807: plog(LLV_ERROR, LOCATION, NULL, "Too many addresses given\n");
1808: return;
1809: }
1810:
1811: addr = (in_addr_t *)(attr + 1);
1812: ip->s_addr = *addr;
1813: (*num)++;
1814:
1815: return;
1816: }
1817:
1818: static void
1819: isakmp_cfg_getstring(attr, str)
1820: struct isakmp_data *attr;
1821: char *str;
1822: {
1823: size_t alen = ntohs(attr->lorv);
1824: char *src;
1825: src = (char *)(attr + 1);
1826:
1827: memcpy(str, src, (alen > MAXPATHLEN ? MAXPATHLEN : alen));
1828:
1829: return;
1830: }
1831:
1832: #define IP_MAX 40
1833:
1834: void
1835: isakmp_cfg_iplist_to_str(dest, count, addr, withmask)
1836: char *dest;
1837: int count;
1838: void *addr;
1839: int withmask;
1840: {
1841: int i;
1842: int p;
1843: int l;
1844: struct unity_network tmp;
1845: for(i = 0, p = 0; i < count; i++) {
1846: if(withmask == 1)
1847: l = sizeof(struct unity_network);
1848: else
1849: l = sizeof(struct in_addr);
1850: memcpy(&tmp, addr, l);
1851: addr += l;
1852: if((uint32_t)tmp.addr4.s_addr == 0)
1853: break;
1854:
1855: inet_ntop(AF_INET, &tmp.addr4, dest + p, IP_MAX);
1856: p += strlen(dest + p);
1857: if(withmask == 1) {
1858: dest[p] = '/';
1859: p++;
1860: inet_ntop(AF_INET, &tmp.mask4, dest + p, IP_MAX);
1861: p += strlen(dest + p);
1862: }
1863: dest[p] = ' ';
1864: p++;
1865: }
1866: if(p > 0)
1867: dest[p-1] = '\0';
1868: else
1869: dest[0] = '\0';
1870: }
1871:
1872: int
1873: isakmp_cfg_setenv(iph1, envp, envc)
1874: struct ph1handle *iph1;
1875: char ***envp;
1876: int *envc;
1877: {
1878: char addrstr[IP_MAX];
1879: char addrlist[IP_MAX * MAXNS + MAXNS];
1880: char *splitlist = addrlist;
1881: char *splitlist_cidr;
1882: char defdom[MAXPATHLEN + 1];
1883: int cidr, tmp;
1884: char cidrstr[4];
1885: int i, p;
1886: int test;
1887:
1888: plog(LLV_DEBUG, LOCATION, NULL, "Starting a script.\n");
1889:
1890: /*
1891: * Internal IPv4 address, either if
1892: * we are a client or a server.
1893: */
1894: if ((iph1->mode_cfg->flags & ISAKMP_CFG_GOT_ADDR4) ||
1895: #ifdef HAVE_LIBLDAP
1896: (iph1->mode_cfg->flags & ISAKMP_CFG_ADDR4_EXTERN) ||
1897: #endif
1898: #ifdef HAVE_LIBRADIUS
1899: (iph1->mode_cfg->flags & ISAKMP_CFG_ADDR4_EXTERN) ||
1900: #endif
1901: (iph1->mode_cfg->flags & ISAKMP_CFG_ADDR4_LOCAL)) {
1902: inet_ntop(AF_INET, &iph1->mode_cfg->addr4,
1903: addrstr, IP_MAX);
1904: } else
1905: addrstr[0] = '\0';
1906:
1907: if (script_env_append(envp, envc, "INTERNAL_ADDR4", addrstr) != 0) {
1908: plog(LLV_ERROR, LOCATION, NULL, "Cannot set INTERNAL_ADDR4\n");
1909: return -1;
1910: }
1911:
1912: if (iph1->mode_cfg->xauth.authdata.generic.usr != NULL) {
1913: if (script_env_append(envp, envc, "XAUTH_USER",
1914: iph1->mode_cfg->xauth.authdata.generic.usr) != 0) {
1915: plog(LLV_ERROR, LOCATION, NULL,
1916: "Cannot set XAUTH_USER\n");
1917: return -1;
1918: }
1919: }
1920:
1921: /* Internal IPv4 mask */
1922: if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_MASK4)
1923: inet_ntop(AF_INET, &iph1->mode_cfg->mask4,
1924: addrstr, IP_MAX);
1925: else
1926: addrstr[0] = '\0';
1927:
1928: /*
1929: * During several releases, documentation adverised INTERNAL_NETMASK4
1930: * while code was using INTERNAL_MASK4. We now do both.
1931: */
1932:
1933: if (script_env_append(envp, envc, "INTERNAL_MASK4", addrstr) != 0) {
1934: plog(LLV_ERROR, LOCATION, NULL, "Cannot set INTERNAL_MASK4\n");
1935: return -1;
1936: }
1937:
1938: if (script_env_append(envp, envc, "INTERNAL_NETMASK4", addrstr) != 0) {
1939: plog(LLV_ERROR, LOCATION, NULL,
1940: "Cannot set INTERNAL_NETMASK4\n");
1941: return -1;
1942: }
1943:
1944: tmp = ntohl(iph1->mode_cfg->mask4.s_addr);
1945: for (cidr = 0; tmp != 0; cidr++)
1946: tmp <<= 1;
1947: snprintf(cidrstr, 3, "%d", cidr);
1948:
1949: if (script_env_append(envp, envc, "INTERNAL_CIDR4", cidrstr) != 0) {
1950: plog(LLV_ERROR, LOCATION, NULL, "Cannot set INTERNAL_CIDR4\n");
1951: return -1;
1952: }
1953:
1954: /* Internal IPv4 DNS */
1955: if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_DNS4) {
1956: /* First Internal IPv4 DNS (for compatibilty with older code */
1957: inet_ntop(AF_INET, &iph1->mode_cfg->dns4[0],
1958: addrstr, IP_MAX);
1959:
1960: /* Internal IPv4 DNS - all */
1961: isakmp_cfg_iplist_to_str(addrlist, iph1->mode_cfg->dns4_index,
1962: (void *)iph1->mode_cfg->dns4, 0);
1963: } else {
1964: addrstr[0] = '\0';
1965: addrlist[0] = '\0';
1966: }
1967:
1968: if (script_env_append(envp, envc, "INTERNAL_DNS4", addrstr) != 0) {
1969: plog(LLV_ERROR, LOCATION, NULL, "Cannot set INTERNAL_DNS4\n");
1970: return -1;
1971: }
1972: if (script_env_append(envp, envc, "INTERNAL_DNS4_LIST", addrlist) != 0) {
1973: plog(LLV_ERROR, LOCATION, NULL,
1974: "Cannot set INTERNAL_DNS4_LIST\n");
1975: return -1;
1976: }
1977:
1978: /* Internal IPv4 WINS */
1979: if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_WINS4) {
1980: /*
1981: * First Internal IPv4 WINS
1982: * (for compatibilty with older code
1983: */
1984: inet_ntop(AF_INET, &iph1->mode_cfg->wins4[0],
1985: addrstr, IP_MAX);
1986:
1987: /* Internal IPv4 WINS - all */
1988: isakmp_cfg_iplist_to_str(addrlist, iph1->mode_cfg->wins4_index,
1989: (void *)iph1->mode_cfg->wins4, 0);
1990: } else {
1991: addrstr[0] = '\0';
1992: addrlist[0] = '\0';
1993: }
1994:
1995: if (script_env_append(envp, envc, "INTERNAL_WINS4", addrstr) != 0) {
1996: plog(LLV_ERROR, LOCATION, NULL,
1997: "Cannot set INTERNAL_WINS4\n");
1998: return -1;
1999: }
2000: if (script_env_append(envp, envc,
2001: "INTERNAL_WINS4_LIST", addrlist) != 0) {
2002: plog(LLV_ERROR, LOCATION, NULL,
2003: "Cannot set INTERNAL_WINS4_LIST\n");
2004: return -1;
2005: }
2006:
2007: /* Deault domain */
2008: if(iph1->mode_cfg->flags & ISAKMP_CFG_GOT_DEFAULT_DOMAIN)
2009: strncpy(defdom,
2010: iph1->mode_cfg->default_domain,
2011: MAXPATHLEN + 1);
2012: else
2013: defdom[0] = '\0';
2014:
2015: if (script_env_append(envp, envc, "DEFAULT_DOMAIN", defdom) != 0) {
2016: plog(LLV_ERROR, LOCATION, NULL,
2017: "Cannot set DEFAULT_DOMAIN\n");
2018: return -1;
2019: }
2020:
2021: /* Split networks */
2022: if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_SPLIT_INCLUDE) {
2023: splitlist =
2024: splitnet_list_2str(iph1->mode_cfg->split_include, NETMASK);
2025: splitlist_cidr =
2026: splitnet_list_2str(iph1->mode_cfg->split_include, CIDR);
2027: } else {
2028: splitlist = addrlist;
2029: splitlist_cidr = addrlist;
2030: addrlist[0] = '\0';
2031: }
2032:
2033: if (script_env_append(envp, envc, "SPLIT_INCLUDE", splitlist) != 0) {
2034: plog(LLV_ERROR, LOCATION, NULL, "Cannot set SPLIT_INCLUDE\n");
2035: return -1;
2036: }
2037: if (script_env_append(envp, envc,
2038: "SPLIT_INCLUDE_CIDR", splitlist_cidr) != 0) {
2039: plog(LLV_ERROR, LOCATION, NULL,
2040: "Cannot set SPLIT_INCLUDE_CIDR\n");
2041: return -1;
2042: }
2043: if (splitlist != addrlist)
2044: racoon_free(splitlist);
2045: if (splitlist_cidr != addrlist)
2046: racoon_free(splitlist_cidr);
2047:
2048: if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_SPLIT_LOCAL) {
2049: splitlist =
2050: splitnet_list_2str(iph1->mode_cfg->split_local, NETMASK);
2051: splitlist_cidr =
2052: splitnet_list_2str(iph1->mode_cfg->split_local, CIDR);
2053: } else {
2054: splitlist = addrlist;
2055: splitlist_cidr = addrlist;
2056: addrlist[0] = '\0';
2057: }
2058:
2059: if (script_env_append(envp, envc, "SPLIT_LOCAL", splitlist) != 0) {
2060: plog(LLV_ERROR, LOCATION, NULL, "Cannot set SPLIT_LOCAL\n");
2061: return -1;
2062: }
2063: if (script_env_append(envp, envc,
2064: "SPLIT_LOCAL_CIDR", splitlist_cidr) != 0) {
2065: plog(LLV_ERROR, LOCATION, NULL,
2066: "Cannot set SPLIT_LOCAL_CIDR\n");
2067: return -1;
2068: }
2069: if (splitlist != addrlist)
2070: racoon_free(splitlist);
2071: if (splitlist_cidr != addrlist)
2072: racoon_free(splitlist_cidr);
2073:
2074: return 0;
2075: }
2076:
2077: int
2078: isakmp_cfg_resize_pool(size)
2079: int size;
2080: {
2081: struct isakmp_cfg_port *new_pool;
2082: size_t len;
2083: int i;
2084:
2085: if (size == isakmp_cfg_config.pool_size)
2086: return 0;
2087:
2088: plog(LLV_INFO, LOCATION, NULL,
2089: "Resize address pool from %zu to %d\n",
2090: isakmp_cfg_config.pool_size, size);
2091:
2092: /* If a pool already exists, check if we can shrink it */
2093: if ((isakmp_cfg_config.port_pool != NULL) &&
2094: (size < isakmp_cfg_config.pool_size)) {
2095: for (i = isakmp_cfg_config.pool_size-1; i >= size; --i) {
2096: if (isakmp_cfg_config.port_pool[i].used) {
2097: plog(LLV_ERROR, LOCATION, NULL,
2098: "resize pool from %zu to %d impossible "
2099: "port %d is in use\n",
2100: isakmp_cfg_config.pool_size, size, i);
2101: size = i;
2102: break;
2103: }
2104: }
2105: }
2106:
2107: len = size * sizeof(*isakmp_cfg_config.port_pool);
2108: new_pool = racoon_realloc(isakmp_cfg_config.port_pool, len);
2109: if (new_pool == NULL) {
2110: plog(LLV_ERROR, LOCATION, NULL,
2111: "resize pool from %zu to %d impossible: %s",
2112: isakmp_cfg_config.pool_size, size, strerror(errno));
2113: return -1;
2114: }
2115:
2116: /* If size increase, intialize correctly the new records */
2117: if (size > isakmp_cfg_config.pool_size) {
2118: size_t unit;
2119: size_t old_size;
2120:
2121: unit = sizeof(*isakmp_cfg_config.port_pool);
2122: old_size = isakmp_cfg_config.pool_size;
2123:
2124: bzero((char *)new_pool + (old_size * unit),
2125: (size - old_size) * unit);
2126: }
2127:
2128: isakmp_cfg_config.port_pool = new_pool;
2129: isakmp_cfg_config.pool_size = size;
2130:
2131: return 0;
2132: }
2133:
2134: int
2135: isakmp_cfg_init(cold)
2136: int cold;
2137: {
2138: int i;
2139: int error;
2140:
2141: isakmp_cfg_config.network4 = (in_addr_t)0x00000000;
2142: isakmp_cfg_config.netmask4 = (in_addr_t)0x00000000;
2143: for (i = 0; i < MAXNS; i++)
2144: isakmp_cfg_config.dns4[i] = (in_addr_t)0x00000000;
2145: isakmp_cfg_config.dns4_index = 0;
2146: for (i = 0; i < MAXWINS; i++)
2147: isakmp_cfg_config.nbns4[i] = (in_addr_t)0x00000000;
2148: isakmp_cfg_config.nbns4_index = 0;
2149: if (cold == ISAKMP_CFG_INIT_COLD)
2150: isakmp_cfg_config.port_pool = NULL;
2151: isakmp_cfg_config.authsource = ISAKMP_CFG_AUTH_SYSTEM;
2152: isakmp_cfg_config.groupsource = ISAKMP_CFG_GROUP_SYSTEM;
2153: if (cold == ISAKMP_CFG_INIT_COLD) {
2154: if (isakmp_cfg_config.grouplist != NULL) {
2155: for (i = 0; i < isakmp_cfg_config.groupcount; i++)
2156: racoon_free(isakmp_cfg_config.grouplist[i]);
2157: racoon_free(isakmp_cfg_config.grouplist);
2158: }
2159: }
2160: isakmp_cfg_config.grouplist = NULL;
2161: isakmp_cfg_config.groupcount = 0;
2162: isakmp_cfg_config.confsource = ISAKMP_CFG_CONF_LOCAL;
2163: isakmp_cfg_config.accounting = ISAKMP_CFG_ACCT_NONE;
2164: if (cold == ISAKMP_CFG_INIT_COLD)
2165: isakmp_cfg_config.pool_size = 0;
2166: isakmp_cfg_config.auth_throttle = THROTTLE_PENALTY;
2167: strlcpy(isakmp_cfg_config.default_domain, ISAKMP_CFG_DEFAULT_DOMAIN,
2168: MAXPATHLEN);
2169: strlcpy(isakmp_cfg_config.motd, ISAKMP_CFG_MOTD, MAXPATHLEN);
2170:
2171: if (cold != ISAKMP_CFG_INIT_COLD )
2172: if (isakmp_cfg_config.splitnet_list != NULL)
2173: splitnet_list_free(isakmp_cfg_config.splitnet_list,
2174: &isakmp_cfg_config.splitnet_count);
2175: isakmp_cfg_config.splitnet_list = NULL;
2176: isakmp_cfg_config.splitnet_count = 0;
2177: isakmp_cfg_config.splitnet_type = 0;
2178:
2179: isakmp_cfg_config.pfs_group = 0;
2180: isakmp_cfg_config.save_passwd = 0;
2181:
2182: if (cold != ISAKMP_CFG_INIT_COLD )
2183: if (isakmp_cfg_config.splitdns_list != NULL)
2184: racoon_free(isakmp_cfg_config.splitdns_list);
2185: isakmp_cfg_config.splitdns_list = NULL;
2186: isakmp_cfg_config.splitdns_len = 0;
2187:
2188: #if 0
2189: if (cold == ISAKMP_CFG_INIT_COLD) {
2190: if ((error = isakmp_cfg_resize_pool(ISAKMP_CFG_MAX_CNX)) != 0)
2191: return error;
2192: }
2193: #endif
2194:
2195: return 0;
2196: }
2197:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>