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