1 /* $NetBSD: isakmp_unity.c,v 1.8 2007/09/19 19:20:25 mgrooms Exp $ */
3 /* Id: isakmp_unity.c,v 1.10 2006/07/31 04:49:23 manubsd Exp */
6 * Copyright (C) 2004 Emmanuel Dreyfus
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
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.
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
36 #include <sys/types.h>
37 #include <sys/param.h>
38 #include <sys/socket.h>
39 #include <sys/queue.h>
41 #include <netinet/in.h>
42 #include <arpa/inet.h>
49 #if TIME_WITH_SYS_TIME
50 # include <sys/time.h>
54 # include <sys/time.h>
74 #include "isakmp_var.h"
77 #include "isakmp_xauth.h"
78 #include "isakmp_unity.h"
79 #include "isakmp_cfg.h"
82 static vchar_t
*isakmp_cfg_split(struct ph1handle
*,
83 struct isakmp_data
*, struct unity_netentry
*,int);
86 isakmp_unity_req(iph1
, attr
)
87 struct ph1handle
*iph1
;
88 struct isakmp_data
*attr
;
91 vchar_t
*reply_attr
= NULL
;
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");
100 type
= ntohs(attr
->type
);
102 /* Handle short attributes */
103 if ((type
& ISAKMP_GEN_MASK
) == ISAKMP_GEN_TV
) {
104 type
&= ~ISAKMP_GEN_MASK
;
106 plog(LLV_DEBUG
, LOCATION
, NULL
,
107 "Short attribute %s = %d\n",
108 s_isakmp_cfg_type(type
), ntohs(attr
->lorv
));
112 plog(LLV_DEBUG
, LOCATION
, NULL
,
113 "Ignored short attribute %s\n",
114 s_isakmp_cfg_type(type
));
123 #define MAXMOTD 65536
124 char buf
[MAXMOTD
+ 1];
126 char *filename
= &isakmp_cfg_config
.motd
[0];
129 if ((fd
= open(filename
, O_RDONLY
, 0)) == -1) {
130 plog(LLV_ERROR
, LOCATION
, NULL
,
131 "Cannot open \"%s\"\n", filename
);
135 if ((len
= read(fd
, buf
, MAXMOTD
)) == -1) {
136 plog(LLV_ERROR
, LOCATION
, NULL
,
137 "Cannot read \"%s\"\n", filename
);
144 reply_attr
= isakmp_cfg_string(iph1
, attr
, buf
);
150 reply_attr
= isakmp_cfg_short(iph1
, attr
,
151 isakmp_cfg_config
.pfs_group
);
154 case UNITY_SAVE_PASSWD
:
155 reply_attr
= isakmp_cfg_short(iph1
, attr
,
156 isakmp_cfg_config
.save_passwd
);
159 case UNITY_DDNS_HOSTNAME
:
160 reply_attr
= isakmp_cfg_copy(iph1
, attr
);
163 case UNITY_DEF_DOMAIN
:
164 reply_attr
= isakmp_cfg_string(iph1
,
165 attr
, isakmp_cfg_config
.default_domain
);
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
);
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
);
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
);
190 case UNITY_NATT_PORT
:
191 case UNITY_BACKUP_SERVERS
:
193 plog(LLV_DEBUG
, LOCATION
, NULL
,
194 "Ignored attribute %s\n", s_isakmp_cfg_type(type
));
203 isakmp_unity_reply(iph1
, attr
)
204 struct ph1handle
*iph1
;
205 struct isakmp_data
*attr
;
207 int type
= ntohs(attr
->type
);
208 int alen
= ntohs(attr
->lorv
);
210 struct unity_network
*network
= (struct unity_network
*)(attr
+ 1);
215 case UNITY_SPLIT_INCLUDE
:
218 count
= alen
/ sizeof(struct unity_network
);
220 for(;index
< count
; index
++)
222 &iph1
->mode_cfg
->split_include
,
224 &iph1
->mode_cfg
->include_count
);
226 iph1
->mode_cfg
->flags
|= ISAKMP_CFG_GOT_SPLIT_INCLUDE
;
229 case UNITY_LOCAL_LAN
:
232 count
= alen
/ sizeof(struct unity_network
);
234 for(;index
< count
; index
++)
236 &iph1
->mode_cfg
->split_local
,
238 &iph1
->mode_cfg
->local_count
);
240 iph1
->mode_cfg
->flags
|= ISAKMP_CFG_GOT_SPLIT_LOCAL
;
243 case UNITY_SPLITDNS_NAME
:
245 case UNITY_SAVE_PASSWD
:
246 case UNITY_NATT_PORT
:
249 case UNITY_BACKUP_SERVERS
:
250 case UNITY_DDNS_HOSTNAME
:
252 plog(LLV_WARNING
, LOCATION
, NULL
,
253 "Ignored attribute %s\n",
254 s_isakmp_cfg_type(type
));
261 isakmp_cfg_split(iph1
, attr
, netentry
, count
)
262 struct ph1handle
*iph1
;
263 struct isakmp_data
*attr
;
264 struct unity_netentry
*netentry
;
268 struct isakmp_data
*new;
269 struct unity_network
* network
;
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");
282 new = (struct isakmp_data
*)buffer
->v
;
283 new->type
= attr
->type
;
284 new->lorv
= htons(len
);
286 network
= (struct unity_network
*)(new + 1);
287 for (; index
< count
; index
++) {
289 memcpy(&network
[index
],
291 sizeof(struct unity_network
));
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
);
297 netentry
= netentry
->next
;
303 int splitnet_list_add(list
, network
, count
)
304 struct unity_netentry
** list
;
305 struct unity_network
* network
;
308 struct unity_netentry
* nentry
;
311 * search for network in current list
312 * to avoid adding duplicates
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 */
320 * allocate new netentry and copy
321 * new splitnet network data
323 nentry
= (struct unity_netentry
*)
324 racoon_malloc(sizeof(struct unity_netentry
));
328 memcpy(&nentry
->network
,network
,
329 sizeof(struct unity_network
));
333 * locate the last netentry in our
334 * splitnet list and add our entry
339 struct unity_netentry
* tmpentry
= *list
;
340 while (tmpentry
->next
!= NULL
)
341 tmpentry
= tmpentry
->next
;
342 tmpentry
->next
= nentry
;
350 void splitnet_list_free(list
, count
)
351 struct unity_netentry
* list
;
354 struct unity_netentry
* netentry
= list
;
355 struct unity_netentry
* delentry
;
359 while (netentry
!= NULL
) {
361 netentry
= netentry
->next
;
362 racoon_free(delentry
);
366 char * splitnet_list_2str(list
, splitnet_ipaddr
)
367 struct unity_netentry
* list
;
368 enum splinet_ipaddr splitnet_ipaddr
;
370 struct unity_netentry
* netentry
;
376 /* determine string length */
379 while (netentry
!= NULL
) {
381 inet_ntop(AF_INET
, &netentry
->network
.addr4
, tmp1
, 40);
382 inet_ntop(AF_INET
, &netentry
->network
.mask4
, tmp2
, 40);
387 netentry
= netentry
->next
;
390 /* allocate network list string */
391 str
= racoon_malloc(len
);
395 /* create network list string */
398 while (netentry
!= NULL
) {
400 inet_ntop(AF_INET
, &netentry
->network
.addr4
, tmp1
, 40);
401 inet_ntop(AF_INET
, &netentry
->network
.mask4
, tmp2
, 40);
402 if (splitnet_ipaddr
== CIDR
) {
406 tmp3
= ntohl(netentry
->network
.mask4
.s_addr
);
407 for (cidrmask
= 0; tmp3
!= 0; cidrmask
++)
409 len
+= sprintf(str
+len
, "%s/%d ", tmp1
, cidrmask
);
411 len
+= sprintf(str
+len
, "%s/%s ", tmp1
, tmp2
);
414 netentry
= netentry
->next
;