Annotation of embedaddon/ipsec-tools/src/racoon/isakmp_unity.c, revision 1.1.1.2
1.1.1.2 ! misho 1: /* $NetBSD: isakmp_unity.c,v 1.9.18.1 2012/01/01 17:32:04 tteras Exp $ */
1.1 misho 2:
3: /* Id: isakmp_unity.c,v 1.10 2006/07/31 04:49:23 manubsd Exp */
4:
5: /*
6: * Copyright (C) 2004 Emmanuel Dreyfus
7: * All rights reserved.
8: *
9: * Redistribution and use in source and binary forms, with or without
10: * modification, are permitted provided that the following conditions
11: * are met:
12: * 1. Redistributions of source code must retain the above copyright
13: * notice, this list of conditions and the following disclaimer.
14: * 2. Redistributions in binary form must reproduce the above copyright
15: * notice, this list of conditions and the following disclaimer in the
16: * documentation and/or other materials provided with the distribution.
17: * 3. Neither the name of the project nor the names of its contributors
18: * may be used to endorse or promote products derived from this software
19: * without specific prior written permission.
20: *
21: * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
22: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24: * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
25: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31: * SUCH DAMAGE.
32: */
33:
34: #include "config.h"
35:
36: #include <sys/types.h>
37: #include <sys/param.h>
38: #include <sys/socket.h>
39: #include <sys/queue.h>
40:
41: #include <netinet/in.h>
42: #include <arpa/inet.h>
43:
44: #include <stdlib.h>
45: #include <stdio.h>
46: #include <fcntl.h>
47: #include <string.h>
48: #include <errno.h>
49: #if TIME_WITH_SYS_TIME
50: # include <sys/time.h>
51: # include <time.h>
52: #else
53: # if HAVE_SYS_TIME_H
54: # include <sys/time.h>
55: # else
56: # include <time.h>
57: # endif
58: #endif
59: #include <netdb.h>
60: #ifdef HAVE_UNISTD_H
61: #include <unistd.h>
62: #endif
63: #include <ctype.h>
64: #include <resolv.h>
65:
66: #include "var.h"
67: #include "misc.h"
68: #include "vmbuf.h"
69: #include "plog.h"
70: #include "sockmisc.h"
71: #include "schedule.h"
72: #include "debug.h"
73:
74: #include "isakmp_var.h"
75: #include "isakmp.h"
76: #include "handler.h"
77: #include "isakmp_xauth.h"
78: #include "isakmp_unity.h"
79: #include "isakmp_cfg.h"
80: #include "strnames.h"
81:
82: static vchar_t *isakmp_cfg_split(struct ph1handle *,
83: struct isakmp_data *, struct unity_netentry*,int);
84:
85: vchar_t *
86: isakmp_unity_req(iph1, attr)
87: struct ph1handle *iph1;
88: struct isakmp_data *attr;
89: {
90: int type;
91: vchar_t *reply_attr = NULL;
92:
93: if ((iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_UNITY) == 0) {
94: plog(LLV_ERROR, LOCATION, NULL,
95: "Unity mode config request but the peer "
96: "did not declare itself as unity compliant\n");
97: return NULL;
98: }
99:
100: type = ntohs(attr->type);
101:
102: /* Handle short attributes */
103: if ((type & ISAKMP_GEN_MASK) == ISAKMP_GEN_TV) {
104: type &= ~ISAKMP_GEN_MASK;
105:
106: plog(LLV_DEBUG, LOCATION, NULL,
107: "Short attribute %s = %d\n",
108: s_isakmp_cfg_type(type), ntohs(attr->lorv));
109:
110: switch (type) {
111: default:
112: plog(LLV_DEBUG, LOCATION, NULL,
113: "Ignored short attribute %s\n",
114: s_isakmp_cfg_type(type));
115: break;
116: }
117:
118: return reply_attr;
119: }
120:
121: switch(type) {
122: case UNITY_BANNER: {
123: #define MAXMOTD 65536
124: char buf[MAXMOTD + 1];
125: int fd;
126: char *filename = &isakmp_cfg_config.motd[0];
127: int len;
128:
129: if ((fd = open(filename, O_RDONLY, 0)) == -1) {
130: plog(LLV_ERROR, LOCATION, NULL,
131: "Cannot open \"%s\"\n", filename);
132: return NULL;
133: }
134:
135: if ((len = read(fd, buf, MAXMOTD)) == -1) {
136: plog(LLV_ERROR, LOCATION, NULL,
137: "Cannot read \"%s\"\n", filename);
138: close(fd);
139: return NULL;
140: }
141: close(fd);
142:
143: buf[len] = '\0';
144: reply_attr = isakmp_cfg_string(iph1, attr, buf);
145:
146: break;
147: }
148:
149: case UNITY_PFS:
150: reply_attr = isakmp_cfg_short(iph1, attr,
151: isakmp_cfg_config.pfs_group);
152: break;
153:
154: case UNITY_SAVE_PASSWD:
155: reply_attr = isakmp_cfg_short(iph1, attr,
156: isakmp_cfg_config.save_passwd);
157: break;
158:
159: case UNITY_DDNS_HOSTNAME:
160: reply_attr = isakmp_cfg_copy(iph1, attr);
161: break;
162:
163: case UNITY_DEF_DOMAIN:
164: reply_attr = isakmp_cfg_string(iph1,
165: attr, isakmp_cfg_config.default_domain);
166: break;
167:
168: case UNITY_SPLIT_INCLUDE:
169: if(isakmp_cfg_config.splitnet_type == UNITY_SPLIT_INCLUDE)
170: reply_attr = isakmp_cfg_split(iph1, attr,
171: isakmp_cfg_config.splitnet_list,
172: isakmp_cfg_config.splitnet_count);
173: else
174: return NULL;
175: break;
176: case UNITY_LOCAL_LAN:
177: if(isakmp_cfg_config.splitnet_type == UNITY_LOCAL_LAN)
178: reply_attr = isakmp_cfg_split(iph1, attr,
179: isakmp_cfg_config.splitnet_list,
180: isakmp_cfg_config.splitnet_count);
181: else
182: return NULL;
183: break;
184: case UNITY_SPLITDNS_NAME:
185: reply_attr = isakmp_cfg_varlen(iph1, attr,
186: isakmp_cfg_config.splitdns_list,
187: isakmp_cfg_config.splitdns_len);
188: break;
189: case UNITY_FW_TYPE:
190: case UNITY_NATT_PORT:
191: case UNITY_BACKUP_SERVERS:
192: default:
193: plog(LLV_DEBUG, LOCATION, NULL,
194: "Ignored attribute %s\n", s_isakmp_cfg_type(type));
195: return NULL;
196: break;
197: }
198:
199: return reply_attr;
200: }
201:
202: void
203: isakmp_unity_reply(iph1, attr)
204: struct ph1handle *iph1;
205: struct isakmp_data *attr;
206: {
207: int type = ntohs(attr->type);
208: int alen = ntohs(attr->lorv);
209:
210: struct unity_network *network = (struct unity_network *)(attr + 1);
211: int index = 0;
212: int count = 0;
213:
214: switch(type) {
215: case UNITY_SPLIT_INCLUDE:
216: {
217: if (alen)
218: count = alen / sizeof(struct unity_network);
219:
220: for(;index < count; index++)
221: splitnet_list_add(
222: &iph1->mode_cfg->split_include,
223: &network[index],
224: &iph1->mode_cfg->include_count);
225:
226: iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_SPLIT_INCLUDE;
227: break;
228: }
229: case UNITY_LOCAL_LAN:
230: {
231: if (alen)
232: count = alen / sizeof(struct unity_network);
233:
234: for(;index < count; index++)
235: splitnet_list_add(
236: &iph1->mode_cfg->split_local,
237: &network[index],
238: &iph1->mode_cfg->local_count);
239:
240: iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_SPLIT_LOCAL;
241: break;
242: }
243: case UNITY_SPLITDNS_NAME:
244: case UNITY_BANNER:
245: case UNITY_SAVE_PASSWD:
246: case UNITY_NATT_PORT:
247: case UNITY_PFS:
248: case UNITY_FW_TYPE:
249: case UNITY_BACKUP_SERVERS:
250: case UNITY_DDNS_HOSTNAME:
251: default:
252: plog(LLV_WARNING, LOCATION, NULL,
253: "Ignored attribute %s\n",
254: s_isakmp_cfg_type(type));
255: break;
256: }
257: return;
258: }
259:
260: static vchar_t *
261: isakmp_cfg_split(iph1, attr, netentry, count)
262: struct ph1handle *iph1;
263: struct isakmp_data *attr;
264: struct unity_netentry *netentry;
265: int count;
266: {
267: vchar_t *buffer;
268: struct isakmp_data *new;
269: struct unity_network * network;
270: size_t len;
271: int index = 0;
272:
273: char tmp1[40];
274: char tmp2[40];
275:
276: len = sizeof(struct unity_network) * count;
277: if ((buffer = vmalloc(sizeof(*attr) + len)) == NULL) {
278: plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
279: return NULL;
280: }
281:
282: new = (struct isakmp_data *)buffer->v;
283: new->type = attr->type;
284: new->lorv = htons(len);
285:
286: network = (struct unity_network *)(new + 1);
287: for (; index < count; index++) {
288:
289: memcpy(&network[index],
290: &netentry->network,
291: sizeof(struct unity_network));
292:
293: inet_ntop(AF_INET, &netentry->network.addr4, tmp1, 40);
294: inet_ntop(AF_INET, &netentry->network.mask4, tmp2, 40);
295: plog(LLV_DEBUG, LOCATION, NULL, "splitnet: %s/%s\n", tmp1, tmp2);
296:
297: netentry = netentry->next;
298: }
299:
300: return buffer;
301: }
302:
303: int splitnet_list_add(list, network, count)
304: struct unity_netentry ** list;
305: struct unity_network * network;
306: int *count;
307: {
308: struct unity_netentry * nentry;
309:
310: /*
311: * search for network in current list
312: * to avoid adding duplicates
313: */
314: for (nentry = *list; nentry != NULL; nentry = nentry->next)
315: if (memcmp(&nentry->network, network,
316: sizeof(struct unity_network)) == 0)
317: return 0; /* it's a dupe */
318:
319: /*
320: * allocate new netentry and copy
321: * new splitnet network data
322: */
323: nentry = (struct unity_netentry *)
324: racoon_malloc(sizeof(struct unity_netentry));
325: if (nentry == NULL)
326: return -1;
327:
328: memcpy(&nentry->network,network,
329: sizeof(struct unity_network));
330: nentry->next = NULL;
331:
332: /*
333: * locate the last netentry in our
334: * splitnet list and add our entry
335: */
336: if (*list == NULL)
337: *list = nentry;
338: else {
339: struct unity_netentry * tmpentry = *list;
340: while (tmpentry->next != NULL)
341: tmpentry = tmpentry->next;
342: tmpentry->next = nentry;
343: }
344:
345: (*count)++;
346:
347: return 0;
348: }
349:
350: void splitnet_list_free(list, count)
351: struct unity_netentry * list;
352: int *count;
353: {
354: struct unity_netentry * netentry = list;
355: struct unity_netentry * delentry;
356:
357: *count = 0;
358:
359: while (netentry != NULL) {
360: delentry = netentry;
361: netentry = netentry->next;
362: racoon_free(delentry);
363: }
364: }
365:
366: char * splitnet_list_2str(list, splitnet_ipaddr)
367: struct unity_netentry * list;
368: enum splinet_ipaddr splitnet_ipaddr;
369: {
370: struct unity_netentry * netentry;
371: char tmp1[40];
372: char tmp2[40];
373: char * str;
374: int len;
375:
376: /* determine string length */
377: len = 0;
378: netentry = list;
379: while (netentry != NULL) {
380:
381: inet_ntop(AF_INET, &netentry->network.addr4, tmp1, 40);
382: inet_ntop(AF_INET, &netentry->network.mask4, tmp2, 40);
383: len += strlen(tmp1);
384: len += strlen(tmp2);
385: len += 2;
386:
387: netentry = netentry->next;
388: }
389:
1.1.1.2 ! misho 390: /* allocate network list string; we need the extra byte temporarily
! 391: * as sprintf() will write trailing 0-byte after the space. */
! 392: str = racoon_malloc(len + 1);
1.1 misho 393: if (str == NULL)
394: return NULL;
395:
396: /* create network list string */
397: len = 0;
398: netentry = list;
399: while (netentry != NULL) {
400:
401: inet_ntop(AF_INET, &netentry->network.addr4, tmp1, 40);
402: inet_ntop(AF_INET, &netentry->network.mask4, tmp2, 40);
403: if (splitnet_ipaddr == CIDR) {
404: uint32_t tmp3;
405: int cidrmask;
406:
407: tmp3 = ntohl(netentry->network.mask4.s_addr);
408: for (cidrmask = 0; tmp3 != 0; cidrmask++)
409: tmp3 <<= 1;
410: len += sprintf(str+len, "%s/%d ", tmp1, cidrmask);
411: } else {
412: len += sprintf(str+len, "%s/%s ", tmp1, tmp2);
413: }
414:
415: netentry = netentry->next;
416: }
417:
1.1.1.2 ! misho 418: /* trim the string to not have trailing spaces */
1.1 misho 419: str[len-1]=0;
420:
421: return str;
422: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>