1 /* $NetBSD: isakmp_unity.c,v 1.7 2006/10/09 06:17:20 manu 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 type
&= ~ISAKMP_GEN_MASK
;
212 struct unity_network
*network
= (struct unity_network
*)(attr
+ 1);
217 case UNITY_SPLIT_INCLUDE
:
219 if ((iph1
->mode_cfg
->flags
& ISAKMP_CFG_GOT_SPLIT_INCLUDE
) == 0) {
221 count
= alen
/ sizeof(struct unity_network
);
223 for(;index
< count
; index
++)
225 &iph1
->mode_cfg
->split_include
,
227 &iph1
->mode_cfg
->include_count
);
229 iph1
->mode_cfg
->flags
|= ISAKMP_CFG_GOT_SPLIT_INCLUDE
;
233 case UNITY_LOCAL_LAN
:
235 if ((iph1
->mode_cfg
->flags
& ISAKMP_CFG_GOT_SPLIT_LOCAL
) == 0) {
237 count
= alen
/ sizeof(struct unity_network
);
239 for(;index
< count
; index
++)
241 &iph1
->mode_cfg
->split_local
,
243 &iph1
->mode_cfg
->local_count
);
245 iph1
->mode_cfg
->flags
|= ISAKMP_CFG_GOT_SPLIT_LOCAL
;
253 case UNITY_SPLITDNS_NAME
:
255 case UNITY_SAVE_PASSWD
:
256 case UNITY_NATT_PORT
:
258 case UNITY_BACKUP_SERVERS
:
259 case UNITY_DDNS_HOSTNAME
:
261 plog(LLV_WARNING
, LOCATION
, NULL
,
262 "Ignored attribute %s\n",
263 s_isakmp_cfg_type(type
));
270 isakmp_cfg_split(iph1
, attr
, netentry
, count
)
271 struct ph1handle
*iph1
;
272 struct isakmp_data
*attr
;
273 struct unity_netentry
*netentry
;
277 struct isakmp_data
*new;
278 struct unity_network
* network
;
285 len
= sizeof(struct unity_network
) * count
;
286 if ((buffer
= vmalloc(sizeof(*attr
) + len
)) == NULL
) {
287 plog(LLV_ERROR
, LOCATION
, NULL
, "Cannot allocate memory\n");
291 new = (struct isakmp_data
*)buffer
->v
;
292 new->type
= attr
->type
;
293 new->lorv
= htons(len
);
295 network
= (struct unity_network
*)(new + 1);
296 for (; index
< count
; index
++) {
298 memcpy(&network
[index
],
300 sizeof(struct unity_network
));
302 inet_ntop(AF_INET
, &netentry
->network
.addr4
, tmp1
, 40);
303 inet_ntop(AF_INET
, &netentry
->network
.mask4
, tmp2
, 40);
304 plog(LLV_DEBUG
, LOCATION
, NULL
, "splitnet: %s/%s\n", tmp1
, tmp2
);
306 netentry
= netentry
->next
;
312 int splitnet_list_add(list
, network
, count
)
313 struct unity_netentry
** list
;
314 struct unity_network
* network
;
317 struct unity_netentry
* newentry
;
320 * allocate new netentry and copy
321 * new splitnet network data
323 newentry
= (struct unity_netentry
*)
324 racoon_malloc(sizeof(struct unity_netentry
));
325 if (newentry
== NULL
)
328 memcpy(&newentry
->network
,network
,
329 sizeof(struct unity_network
));
330 newentry
->next
= NULL
;
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
= newentry
;
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
)
367 struct unity_netentry
* list
;
369 struct unity_netentry
* netentry
;
377 /* determine string length */
380 while (netentry
!= NULL
) {
382 inet_ntop(AF_INET
, &netentry
->network
.addr4
, tmp1
, 40);
383 inet_ntop(AF_INET
, &netentry
->network
.mask4
, tmp2
, 40);
388 netentry
= netentry
->next
;
391 /* allocate network list string */
392 str
= racoon_malloc(len
);
396 /* create network list string */
400 while (netentry
!= NULL
&& print_len
< len
) {
402 inet_ntop(AF_INET
, &netentry
->network
.addr4
, tmp1
, 40);
403 inet_ntop(AF_INET
, &netentry
->network
.mask4
, tmp2
, 40);
405 rc
= snprintf(str
+print_len
, len
-print_len
, "%s/%s ", tmp1
, tmp2
);
407 // failure -> exit loop
412 netentry
= netentry
->next
;