]>
git.saurik.com Git - apple/network_cmds.git/blob - racoon.tproj/policy.c
1 /* $KAME: policy.c,v 1.46 2001/11/16 04:08:10 sakane Exp $ */
4 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the project nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 #include <sys/param.h>
33 #include <sys/types.h>
34 #include <sys/socket.h>
35 #include <sys/queue.h>
37 #include <netkey/key_var.h>
38 #include <netinet/in.h>
39 #include <netinet6/ipsec.h>
54 #include "localconf.h"
55 #include "isakmp_var.h"
62 static TAILQ_HEAD(_sptree
, secpolicy
) sptree
;
64 /* perform exact match against security policy table. */
67 struct policyindex
*spidx
;
71 for (p
= TAILQ_FIRST(&sptree
); p
; p
= TAILQ_NEXT(p
, chain
)) {
72 if (!cmpspidxstrict(spidx
, &p
->spidx
))
80 * perform non-exact match against security policy table, only if this is
81 * transport mode SA negotiation. for example, 0.0.0.0/0 -> 0.0.0.0/0
82 * entry in policy.txt can be returned when we're negotiating transport
83 * mode SA. this is how the kernel works.
88 struct policyindex
*spidx
;
92 for (p
= TAILQ_FIRST(&sptree
); p
; p
= TAILQ_NEXT(p
, chain
)) {
93 if (!cmpspidxwild(spidx
, &p
->spidx
))
102 struct policyindex
*spidx
;
103 struct ph2handle
*iph2
;
108 plog(LLV_DEBUG
, LOCATION
, NULL
, "checking for transport mode\n");
110 if (spidx
->src
.ss_family
!= spidx
->dst
.ss_family
) {
111 plog(LLV_ERROR
, LOCATION
, NULL
,
112 "address family mismatch, src:%d dst:%d\n",
113 spidx
->src
.ss_family
,
114 spidx
->dst
.ss_family
);
117 switch (spidx
->src
.ss_family
) {
119 prefixlen
= sizeof(struct in_addr
) << 3;
123 prefixlen
= sizeof(struct in6_addr
) << 3;
127 plog(LLV_ERROR
, LOCATION
, NULL
,
128 "invalid family: %d\n", spidx
->src
.ss_family
);
132 /* is it transport mode SA negotiation? */
133 plog(LLV_DEBUG
, LOCATION
, NULL
, "src1: %s\n",
134 saddr2str(iph2
->src
));
135 plog(LLV_DEBUG
, LOCATION
, NULL
, "src2: %s\n",
136 saddr2str((struct sockaddr
*)&spidx
->src
));
137 if (cmpsaddrwop(iph2
->src
, (struct sockaddr
*)&spidx
->src
)
138 || spidx
->prefs
!= prefixlen
)
141 plog(LLV_DEBUG
, LOCATION
, NULL
, "dst1: %s\n",
142 saddr2str(iph2
->dst
));
143 plog(LLV_DEBUG
, LOCATION
, NULL
, "dst2: %s\n",
144 saddr2str((struct sockaddr
*)&spidx
->dst
));
145 if (cmpsaddrwop(iph2
->dst
, (struct sockaddr
*)&spidx
->dst
)
146 || spidx
->prefd
!= prefixlen
)
149 plog(LLV_DEBUG
, LOCATION
, NULL
, "looks to be transport mode\n");
151 for (p
= TAILQ_FIRST(&sptree
); p
; p
= TAILQ_NEXT(p
, chain
)) {
152 if (!cmpspidx_wild(spidx
, &p
->spidx
))
166 for (p
= TAILQ_FIRST(&sptree
); p
; p
= TAILQ_NEXT(p
, chain
)) {
175 * compare policyindex.
182 struct policyindex
*a
, *b
;
184 plog(LLV_DEBUG
, LOCATION
, NULL
, "sub:%p: %s\n", a
, spidx2str(a
));
185 plog(LLV_DEBUG
, LOCATION
, NULL
, "db :%p: %s\n", b
, spidx2str(b
));
187 /* XXX don't check direction now, but it's to be checked carefully. */
189 || a
->prefs
!= b
->prefs
190 || a
->prefd
!= b
->prefd
191 || a
->ul_proto
!= b
->ul_proto
)
194 if (cmpsaddrstrict((struct sockaddr
*)&a
->src
,
195 (struct sockaddr
*)&b
->src
))
197 if (cmpsaddrstrict((struct sockaddr
*)&a
->dst
,
198 (struct sockaddr
*)&b
->dst
))
205 * compare policyindex, with wildcard address/protocol match.
206 * a: subject b: db, can contain wildcard things.
212 struct policyindex
*a
, *b
;
214 struct sockaddr_storage sa1
, sa2
;
216 plog(LLV_DEBUG
, LOCATION
, NULL
, "sub:%p: %s\n", a
, spidx2str(a
));
217 plog(LLV_DEBUG
, LOCATION
, NULL
, "db: %p: %s\n", b
, spidx2str(b
));
219 if (!(b
->dir
== IPSEC_DIR_ANY
|| a
->dir
== b
->dir
))
222 if (!(a
->ul_proto
== IPSEC_ULPROTO_ANY
||
223 b
->ul_proto
== IPSEC_ULPROTO_ANY
||
224 a
->ul_proto
== b
->ul_proto
))
227 if (a
->src
.ss_family
!= b
->src
.ss_family
)
229 if (a
->dst
.ss_family
!= b
->dst
.ss_family
)
232 /* compare src address */
233 if (sizeof(sa1
) < a
->src
.ss_len
|| sizeof(sa2
) < b
->src
.ss_len
) {
234 plog(LLV_ERROR
, LOCATION
, NULL
,
236 "src.ss_len:%d dst.ss_len:%d\n",
237 a
->src
.ss_len
, b
->src
.ss_len
);
240 mask_sockaddr((struct sockaddr
*)&sa1
, (struct sockaddr
*)&a
->src
,
242 mask_sockaddr((struct sockaddr
*)&sa2
, (struct sockaddr
*)&b
->src
,
244 plog(LLV_DEBUG
, LOCATION
, NULL
, "%p masked with /%d: %s\n",
245 a
, b
->prefs
, saddr2str((struct sockaddr
*)&sa1
));
246 plog(LLV_DEBUG
, LOCATION
, NULL
, "%p masked with /%d: %s\n",
247 b
, b
->prefs
, saddr2str((struct sockaddr
*)&sa2
));
248 if (cmpsaddrwild((struct sockaddr
*)&sa1
, (struct sockaddr
*)&sa2
))
251 /* compare dst address */
252 if (sizeof(sa1
) < a
->dst
.ss_len
|| sizeof(sa2
) < b
->dst
.ss_len
) {
253 plog(LLV_ERROR
, LOCATION
, NULL
, "unexpected error\n");
256 mask_sockaddr((struct sockaddr
*)&sa1
, (struct sockaddr
*)&a
->dst
,
258 mask_sockaddr((struct sockaddr
*)&sa2
, (struct sockaddr
*)&b
->dst
,
260 plog(LLV_DEBUG
, LOCATION
, NULL
, "%p masked with /%d: %s\n",
261 a
, b
->prefd
, saddr2str((struct sockaddr
*)&sa1
));
262 plog(LLV_DEBUG
, LOCATION
, NULL
, "%p masked with /%d: %s\n",
263 b
, b
->prefd
, saddr2str((struct sockaddr
*)&sa2
));
264 if (cmpsaddrwild((struct sockaddr
*)&sa1
, (struct sockaddr
*)&sa2
))
273 struct secpolicy
*new;
275 new = racoon_calloc(1, sizeof(*new));
284 struct secpolicy
*sp
;
286 struct ipsecrequest
*req
= NULL
, *next
;
288 for (req
= sp
->req
; req
; req
= next
) {
297 delsp_bothdir(spidx0
)
298 struct policyindex
*spidx0
;
300 struct policyindex spidx
;
301 struct secpolicy
*sp
;
302 struct sockaddr_storage addr
;
305 memcpy(&spidx
, spidx0
, sizeof(spidx
));
313 spidx
.dir
= spidx
.dir
== IPSEC_DIR_OUTBOUND
315 : IPSEC_DIR_OUTBOUND
;
317 spidx
.src
= spidx
.dst
;
320 spidx
.prefs
= spidx
.prefd
;
332 struct secpolicy
*new;
334 TAILQ_INSERT_TAIL(&sptree
, new, chain
);
339 struct secpolicy
*sp
;
341 TAILQ_REMOVE(&sptree
, sp
, chain
);
347 struct secpolicy
*p
, *next
;
349 for (p
= TAILQ_FIRST(&sptree
); p
; p
= next
) {
350 next
= TAILQ_NEXT(p
, chain
);
362 struct ipsecrequest
*
365 struct ipsecrequest
*new;
367 new = racoon_calloc(1, sizeof(*new));
376 const struct policyindex
*spidx
;
378 /* addr/pref[port] addr/pref[port] ul dir act */
379 static char buf
[256];
383 blen
= sizeof(buf
) - 1;
386 a
= saddr2str((const struct sockaddr
*)&spidx
->src
);
387 for (b
= a
; *b
!= '\0'; b
++)
393 i
= snprintf(p
, blen
, "%s/%d[%s ", a
, spidx
->prefs
, b
);
394 if (i
< 0 || i
>= blen
)
399 a
= saddr2str((const struct sockaddr
*)&spidx
->dst
);
400 for (b
= a
; *b
!= '\0'; b
++)
406 i
= snprintf(p
, blen
, "%s/%d[%s ", a
, spidx
->prefd
, b
);
407 if (i
< 0 || i
>= blen
)
412 snprintf(p
, blen
, "proto=%s dir=%s",
413 s_proto(spidx
->ul_proto
), s_direction(spidx
->dir
));