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>
73 #include "isakmp_var.h"
76 #include "isakmp_xauth.h"
77 #include "isakmp_unity.h"
78 #include "isakmp_cfg.h"
81 static vchar_t
*isakmp_cfg_split (phase1_handle_t
*,
82 struct isakmp_data
*, struct unity_netentry
*,int);
85 isakmp_unity_req(iph1
, attr
)
86 phase1_handle_t
*iph1
;
87 struct isakmp_data
*attr
;
90 vchar_t
*reply_attr
= NULL
;
92 if ((iph1
->mode_cfg
->flags
& ISAKMP_CFG_VENDORID_UNITY
) == 0) {
94 "Unity mode config request but the peer "
95 "did not declare itself as unity compliant\n");
99 type
= ntohs(attr
->type
);
101 /* Handle short attributes */
102 if ((type
& ISAKMP_GEN_MASK
) == ISAKMP_GEN_TV
) {
103 type
&= ~ISAKMP_GEN_MASK
;
105 plog(ASL_LEVEL_DEBUG
,
106 "Short attribute %s = %d\n",
107 s_isakmp_cfg_type(type
), ntohs(attr
->lorv
));
111 plog(ASL_LEVEL_DEBUG
,
112 "Ignored short attribute %s\n",
113 s_isakmp_cfg_type(type
));
122 #define MAXMOTD 65536
123 char buf
[MAXMOTD
+ 1];
125 char *filename
= &isakmp_cfg_config
.motd
[0];
128 if ((fd
= open(filename
, O_RDONLY
, 0)) == -1) {
130 "Cannot open \"%s\"\n", filename
);
134 if ((len
= read(fd
, buf
, MAXMOTD
)) == -1) {
136 "Cannot read \"%s\"\n", filename
);
143 reply_attr
= isakmp_cfg_string(iph1
, attr
, buf
);
149 reply_attr
= isakmp_cfg_short(iph1
, attr
,
150 isakmp_cfg_config
.pfs_group
);
153 case UNITY_SAVE_PASSWD
:
154 reply_attr
= isakmp_cfg_short(iph1
, attr
,
155 isakmp_cfg_config
.save_passwd
);
158 case UNITY_DDNS_HOSTNAME
:
159 reply_attr
= isakmp_cfg_copy(iph1
, attr
);
162 case UNITY_DEF_DOMAIN
:
163 reply_attr
= isakmp_cfg_string(iph1
,
164 attr
, isakmp_cfg_config
.default_domain
);
167 case UNITY_SPLIT_INCLUDE
:
168 if(isakmp_cfg_config
.splitnet_type
== UNITY_SPLIT_INCLUDE
)
169 reply_attr
= isakmp_cfg_split(iph1
, attr
,
170 isakmp_cfg_config
.splitnet_list
,
171 isakmp_cfg_config
.splitnet_count
);
175 case UNITY_LOCAL_LAN
:
176 if(isakmp_cfg_config
.splitnet_type
== UNITY_LOCAL_LAN
)
177 reply_attr
= isakmp_cfg_split(iph1
, attr
,
178 isakmp_cfg_config
.splitnet_list
,
179 isakmp_cfg_config
.splitnet_count
);
183 case UNITY_SPLITDNS_NAME
:
184 reply_attr
= isakmp_cfg_varlen(iph1
, attr
,
185 isakmp_cfg_config
.splitdns_list
,
186 isakmp_cfg_config
.splitdns_len
);
189 case UNITY_NATT_PORT
:
190 case UNITY_BACKUP_SERVERS
:
192 plog(ASL_LEVEL_DEBUG
,
193 "Ignored attribute %s\n", s_isakmp_cfg_type(type
));
202 isakmp_unity_reply(iph1
, attr
)
203 phase1_handle_t
*iph1
;
204 struct isakmp_data
*attr
;
206 int type
= ntohs(attr
->type
);
207 int alen
= ntohs(attr
->lorv
);
209 type
&= ~ISAKMP_GEN_MASK
;
211 struct unity_network
*network
= (struct unity_network
*)(attr
+ 1);
216 case UNITY_SPLIT_INCLUDE
:
218 if ((iph1
->mode_cfg
->flags
& ISAKMP_CFG_GOT_SPLIT_INCLUDE
) == 0) {
220 count
= alen
/ sizeof(struct unity_network
);
222 for(;index
< count
; index
++)
224 &iph1
->mode_cfg
->split_include
,
226 &iph1
->mode_cfg
->include_count
);
228 iph1
->mode_cfg
->flags
|= ISAKMP_CFG_GOT_SPLIT_INCLUDE
;
232 case UNITY_LOCAL_LAN
:
234 if ((iph1
->mode_cfg
->flags
& ISAKMP_CFG_GOT_SPLIT_LOCAL
) == 0) {
236 count
= alen
/ sizeof(struct unity_network
);
238 for(;index
< count
; index
++)
240 &iph1
->mode_cfg
->split_local
,
242 &iph1
->mode_cfg
->local_count
);
244 iph1
->mode_cfg
->flags
|= ISAKMP_CFG_GOT_SPLIT_LOCAL
;
252 case UNITY_SPLITDNS_NAME
:
254 case UNITY_SAVE_PASSWD
:
255 case UNITY_NATT_PORT
:
257 case UNITY_BACKUP_SERVERS
:
258 case UNITY_DDNS_HOSTNAME
:
260 plog(ASL_LEVEL_WARNING
,
261 "Ignored attribute %s\n",
262 s_isakmp_cfg_type(type
));
269 isakmp_cfg_split(iph1
, attr
, netentry
, count
)
270 phase1_handle_t
*iph1
;
271 struct isakmp_data
*attr
;
272 struct unity_netentry
*netentry
;
276 struct isakmp_data
*new;
277 struct unity_network
* network
;
284 len
= sizeof(struct unity_network
) * count
;
285 if ((buffer
= vmalloc(sizeof(*attr
) + len
)) == NULL
) {
286 plog(ASL_LEVEL_ERR
, "Cannot allocate memory\n");
290 new = (struct isakmp_data
*)buffer
->v
;
291 new->type
= attr
->type
;
292 new->lorv
= htons(len
);
294 network
= (struct unity_network
*)(new + 1);
295 for (; index
< count
; index
++) {
297 memcpy(&network
[index
],
299 sizeof(struct unity_network
));
301 inet_ntop(AF_INET
, &netentry
->network
.addr4
, tmp1
, 40);
302 inet_ntop(AF_INET
, &netentry
->network
.mask4
, tmp2
, 40);
303 plog(ASL_LEVEL_DEBUG
, "splitnet: %s/%s\n", tmp1
, tmp2
);
305 netentry
= netentry
->next
;
311 int splitnet_list_add(list
, network
, count
)
312 struct unity_netentry
** list
;
313 struct unity_network
* network
;
316 struct unity_netentry
* newentry
;
319 * allocate new netentry and copy
320 * new splitnet network data
322 newentry
= (struct unity_netentry
*)
323 racoon_malloc(sizeof(struct unity_netentry
));
324 if (newentry
== NULL
)
327 memcpy(&newentry
->network
,network
,
328 sizeof(struct unity_network
));
329 newentry
->next
= NULL
;
332 * locate the last netentry in our
333 * splitnet list and add our entry
338 struct unity_netentry
* tmpentry
= *list
;
339 while (tmpentry
->next
!= NULL
)
340 tmpentry
= tmpentry
->next
;
341 tmpentry
->next
= newentry
;
349 void splitnet_list_free(list
, count
)
350 struct unity_netentry
* list
;
353 struct unity_netentry
* netentry
= list
;
354 struct unity_netentry
* delentry
;
358 while (netentry
!= NULL
) {
360 netentry
= netentry
->next
;
361 racoon_free(delentry
);
365 char * splitnet_list_2str(list
)
366 struct unity_netentry
* list
;
368 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 */
399 while (netentry
!= NULL
&& print_len
< len
) {
401 inet_ntop(AF_INET
, &netentry
->network
.addr4
, tmp1
, 40);
402 inet_ntop(AF_INET
, &netentry
->network
.mask4
, tmp2
, 40);
404 rc
= snprintf(str
+print_len
, len
-print_len
, "%s/%s ", tmp1
, tmp2
);
406 // failure -> exit loop
411 netentry
= netentry
->next
;