policy.c revision 0a1907d434839af6a9cb6329bbde60b237bf53dc
1e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt/* $NetBSD: policy.c,v 1.6.4.1 2007/08/01 11:52:21 vanhu Exp $ */ 2e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 3e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt/* $KAME: policy.c,v 1.46 2001/11/16 04:08:10 sakane Exp $ */ 4e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 5e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt/* 6e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 7e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * All rights reserved. 8e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * 9e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * Redistribution and use in source and binary forms, with or without 10e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * modification, are permitted provided that the following conditions 11e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * are met: 12e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * 1. Redistributions of source code must retain the above copyright 13e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * notice, this list of conditions and the following disclaimer. 14e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * 2. Redistributions in binary form must reproduce the above copyright 15e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * notice, this list of conditions and the following disclaimer in the 16e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * documentation and/or other materials provided with the distribution. 17e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * 3. Neither the name of the project nor the names of its contributors 18e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * may be used to endorse or promote products derived from this software 19e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * without specific prior written permission. 20e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * 21e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 22e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 25e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * SUCH DAMAGE. 32e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt */ 33e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 34e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include "config.h" 35e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 36e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include <sys/param.h> 37e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include <sys/types.h> 38e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include <sys/socket.h> 39e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include <sys/queue.h> 40e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 41e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include <netinet/in.h> 42e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include PATH_IPSEC_H 43e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 44e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include <stdlib.h> 45e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include <stdio.h> 46e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include <string.h> 47e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include <errno.h> 48e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 49e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include "var.h" 50e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include "misc.h" 51e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include "vmbuf.h" 52e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include "plog.h" 53e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include "sockmisc.h" 54e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include "debug.h" 55e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 56e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include "policy.h" 57e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include "localconf.h" 58e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include "isakmp_var.h" 59e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include "isakmp.h" 60e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include "oakley.h" 61e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include "handler.h" 62e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include "strnames.h" 63e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include "gcmalloc.h" 64e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 65e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtstatic TAILQ_HEAD(_sptree, secpolicy) sptree; 66e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 67e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt/* perform exact match against security policy table. */ 68e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtstruct secpolicy * 69e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtgetsp(spidx) 70e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt struct policyindex *spidx; 71e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt{ 72e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt struct secpolicy *p; 73e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 74e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt for (p = TAILQ_FIRST(&sptree); p; p = TAILQ_NEXT(p, chain)) { 75e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (!cmpspidxstrict(spidx, &p->spidx)) 76e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return p; 77e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 78e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 79e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return NULL; 80e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt} 81e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 82e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt/* 83e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * perform non-exact match against security policy table, only if this is 84e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * transport mode SA negotiation. for example, 0.0.0.0/0 -> 0.0.0.0/0 85e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * entry in policy.txt can be returned when we're negotiating transport 86e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * mode SA. this is how the kernel works. 87e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt */ 88e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#if 1 89e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtstruct secpolicy * 90e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtgetsp_r(spidx) 91e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt struct policyindex *spidx; 92e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt{ 93e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt struct secpolicy *p; 94e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 95e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt for (p = TAILQ_FIRST(&sptree); p; p = TAILQ_NEXT(p, chain)) { 96e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (!cmpspidxwild(spidx, &p->spidx)) 97e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return p; 98e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 99e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 100e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return NULL; 101e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt} 102e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#else 103e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtstruct secpolicy * 104e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtgetsp_r(spidx, iph2) 105e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt struct policyindex *spidx; 106e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt struct ph2handle *iph2; 107e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt{ 108e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt struct secpolicy *p; 109e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt u_int8_t prefixlen; 110e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 111e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt plog(LLV_DEBUG, LOCATION, NULL, "checking for transport mode\n"); 112e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 113e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (spidx->src.ss_family != spidx->dst.ss_family) { 114e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt plog(LLV_ERROR, LOCATION, NULL, 115e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt "address family mismatch, src:%d dst:%d\n", 116e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt spidx->src.ss_family, 117e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt spidx->dst.ss_family); 118e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return NULL; 119e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 120e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt switch (spidx->src.ss_family) { 121e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt case AF_INET: 122e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt prefixlen = sizeof(struct in_addr) << 3; 123e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt break; 124e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#ifdef INET6 125e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt case AF_INET6: 126e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt prefixlen = sizeof(struct in6_addr) << 3; 127e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt break; 128e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#endif 129e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt default: 130e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt plog(LLV_ERROR, LOCATION, NULL, 131e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt "invalid family: %d\n", spidx->src.ss_family); 132e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return NULL; 133e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 134e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 135e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt /* is it transport mode SA negotiation? */ 136e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt plog(LLV_DEBUG, LOCATION, NULL, "src1: %s\n", 137e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt saddr2str(iph2->src)); 138e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt plog(LLV_DEBUG, LOCATION, NULL, "src2: %s\n", 139e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt saddr2str((struct sockaddr *)&spidx->src)); 140e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (cmpsaddrwop(iph2->src, (struct sockaddr *)&spidx->src) 141e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt || spidx->prefs != prefixlen) 142e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return NULL; 143e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 144e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt plog(LLV_DEBUG, LOCATION, NULL, "dst1: %s\n", 145e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt saddr2str(iph2->dst)); 146e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt plog(LLV_DEBUG, LOCATION, NULL, "dst2: %s\n", 147e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt saddr2str((struct sockaddr *)&spidx->dst)); 148e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (cmpsaddrwop(iph2->dst, (struct sockaddr *)&spidx->dst) 149e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt || spidx->prefd != prefixlen) 150e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return NULL; 151e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 152e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt plog(LLV_DEBUG, LOCATION, NULL, "looks to be transport mode\n"); 153e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 154e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt for (p = TAILQ_FIRST(&sptree); p; p = TAILQ_NEXT(p, chain)) { 155e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (!cmpspidx_wild(spidx, &p->spidx)) 156e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return p; 157 } 158 159 return NULL; 160} 161#endif 162 163struct secpolicy * 164getspbyspid(spid) 165 u_int32_t spid; 166{ 167 struct secpolicy *p; 168 169 for (p = TAILQ_FIRST(&sptree); p; p = TAILQ_NEXT(p, chain)) { 170 if (p->id == spid) 171 return p; 172 } 173 174 return NULL; 175} 176 177/* 178 * compare policyindex. 179 * a: subject b: db 180 * OUT: 0: equal 181 * 1: not equal 182 */ 183int 184cmpspidxstrict(a, b) 185 struct policyindex *a, *b; 186{ 187 plog(LLV_DEBUG, LOCATION, NULL, "sub:%p: %s\n", a, spidx2str(a)); 188 plog(LLV_DEBUG, LOCATION, NULL, "db :%p: %s\n", b, spidx2str(b)); 189 190 /* XXX don't check direction now, but it's to be checked carefully. */ 191 if (a->dir != b->dir 192 || a->prefs != b->prefs 193 || a->prefd != b->prefd 194 || a->ul_proto != b->ul_proto) 195 return 1; 196 197 if (cmpsaddrstrict((struct sockaddr *)&a->src, 198 (struct sockaddr *)&b->src)) 199 return 1; 200 if (cmpsaddrstrict((struct sockaddr *)&a->dst, 201 (struct sockaddr *)&b->dst)) 202 return 1; 203 204#ifdef HAVE_SECCTX 205 if (a->sec_ctx.ctx_alg != b->sec_ctx.ctx_alg 206 || a->sec_ctx.ctx_doi != b->sec_ctx.ctx_doi 207 || !within_range(a->sec_ctx.ctx_str, b->sec_ctx.ctx_str)) 208 return 1; 209#endif 210 return 0; 211} 212 213/* 214 * compare policyindex, with wildcard address/protocol match. 215 * a: subject b: db, can contain wildcard things. 216 * OUT: 0: equal 217 * 1: not equal 218 */ 219int 220cmpspidxwild(a, b) 221 struct policyindex *a, *b; 222{ 223 struct sockaddr_storage sa1, sa2; 224 225 plog(LLV_DEBUG, LOCATION, NULL, "sub:%p: %s\n", a, spidx2str(a)); 226 plog(LLV_DEBUG, LOCATION, NULL, "db: %p: %s\n", b, spidx2str(b)); 227 228 if (!(b->dir == IPSEC_DIR_ANY || a->dir == b->dir)) 229 return 1; 230 231 if (!(a->ul_proto == IPSEC_ULPROTO_ANY || 232 b->ul_proto == IPSEC_ULPROTO_ANY || 233 a->ul_proto == b->ul_proto)) 234 return 1; 235 236 if (a->src.ss_family != b->src.ss_family) 237 return 1; 238 if (a->dst.ss_family != b->dst.ss_family) 239 return 1; 240 241#ifndef __linux__ 242 /* compare src address */ 243 if (sizeof(sa1) < a->src.ss_len || sizeof(sa2) < b->src.ss_len) { 244 plog(LLV_ERROR, LOCATION, NULL, 245 "unexpected error: " 246 "src.ss_len:%d dst.ss_len:%d\n", 247 a->src.ss_len, b->src.ss_len); 248 return 1; 249 } 250#endif 251 mask_sockaddr((struct sockaddr *)&sa1, (struct sockaddr *)&a->src, 252 b->prefs); 253 mask_sockaddr((struct sockaddr *)&sa2, (struct sockaddr *)&b->src, 254 b->prefs); 255 plog(LLV_DEBUG, LOCATION, NULL, "%p masked with /%d: %s\n", 256 a, b->prefs, saddr2str((struct sockaddr *)&sa1)); 257 plog(LLV_DEBUG, LOCATION, NULL, "%p masked with /%d: %s\n", 258 b, b->prefs, saddr2str((struct sockaddr *)&sa2)); 259 if (cmpsaddrwild((struct sockaddr *)&sa1, (struct sockaddr *)&sa2)) 260 return 1; 261 262#ifndef __linux__ 263 /* compare dst address */ 264 if (sizeof(sa1) < a->dst.ss_len || sizeof(sa2) < b->dst.ss_len) { 265 plog(LLV_ERROR, LOCATION, NULL, "unexpected error\n"); 266 exit(1); 267 } 268#endif 269 mask_sockaddr((struct sockaddr *)&sa1, (struct sockaddr *)&a->dst, 270 b->prefd); 271 mask_sockaddr((struct sockaddr *)&sa2, (struct sockaddr *)&b->dst, 272 b->prefd); 273 plog(LLV_DEBUG, LOCATION, NULL, "%p masked with /%d: %s\n", 274 a, b->prefd, saddr2str((struct sockaddr *)&sa1)); 275 plog(LLV_DEBUG, LOCATION, NULL, "%p masked with /%d: %s\n", 276 b, b->prefd, saddr2str((struct sockaddr *)&sa2)); 277 if (cmpsaddrwild((struct sockaddr *)&sa1, (struct sockaddr *)&sa2)) 278 return 1; 279 280#ifdef HAVE_SECCTX 281 if (a->sec_ctx.ctx_alg != b->sec_ctx.ctx_alg 282 || a->sec_ctx.ctx_doi != b->sec_ctx.ctx_doi 283 || !within_range(a->sec_ctx.ctx_str, b->sec_ctx.ctx_str)) 284 return 1; 285#endif 286 return 0; 287} 288 289struct secpolicy * 290newsp() 291{ 292 struct secpolicy *new; 293 294 new = racoon_calloc(1, sizeof(*new)); 295 if (new == NULL) 296 return NULL; 297 298 return new; 299} 300 301void 302delsp(sp) 303 struct secpolicy *sp; 304{ 305 struct ipsecrequest *req = NULL, *next; 306 307 for (req = sp->req; req; req = next) { 308 next = req->next; 309 racoon_free(req); 310 } 311 312 racoon_free(sp); 313} 314 315void 316delsp_bothdir(spidx0) 317 struct policyindex *spidx0; 318{ 319 struct policyindex spidx; 320 struct secpolicy *sp; 321 struct sockaddr_storage src, dst; 322 u_int8_t prefs, prefd; 323 324 memcpy(&spidx, spidx0, sizeof(spidx)); 325 switch (spidx.dir) { 326 case IPSEC_DIR_INBOUND: 327#ifdef HAVE_POLICY_FWD 328 case IPSEC_DIR_FWD: 329#endif 330 src = spidx.src; 331 dst = spidx.dst; 332 prefs = spidx.prefs; 333 prefd = spidx.prefd; 334 break; 335 case IPSEC_DIR_OUTBOUND: 336 src = spidx.dst; 337 dst = spidx.src; 338 prefs = spidx.prefd; 339 prefd = spidx.prefs; 340 break; 341 default: 342 return; 343 } 344 345 spidx.src = src; 346 spidx.dst = dst; 347 spidx.prefs = prefs; 348 spidx.prefd = prefd; 349 spidx.dir = IPSEC_DIR_INBOUND; 350 351 sp = getsp(&spidx); 352 if (sp) { 353 remsp(sp); 354 delsp(sp); 355 } 356 357#ifdef HAVE_POLICY_FWD 358 spidx.dir = IPSEC_DIR_FWD; 359 360 sp = getsp(&spidx); 361 if (sp) { 362 remsp(sp); 363 delsp(sp); 364 } 365#endif 366 367 spidx.src = dst; 368 spidx.dst = src; 369 spidx.prefs = prefd; 370 spidx.prefd = prefs; 371 spidx.dir = IPSEC_DIR_OUTBOUND; 372 373 sp = getsp(&spidx); 374 if (sp) { 375 remsp(sp); 376 delsp(sp); 377 } 378} 379 380void 381inssp(new) 382 struct secpolicy *new; 383{ 384#ifdef HAVE_PFKEY_POLICY_PRIORITY 385 struct secpolicy *p; 386 387 TAILQ_FOREACH(p, &sptree, chain) { 388 if (new->spidx.priority < p->spidx.priority) { 389 TAILQ_INSERT_BEFORE(p, new, chain); 390 return; 391 } 392 } 393 if (p == NULL) 394#endif 395 TAILQ_INSERT_TAIL(&sptree, new, chain); 396 397 return; 398} 399 400void 401remsp(sp) 402 struct secpolicy *sp; 403{ 404 TAILQ_REMOVE(&sptree, sp, chain); 405} 406 407void 408flushsp() 409{ 410 struct secpolicy *p, *next; 411 412 for (p = TAILQ_FIRST(&sptree); p; p = next) { 413 next = TAILQ_NEXT(p, chain); 414 remsp(p); 415 delsp(p); 416 } 417} 418 419void 420initsp() 421{ 422 TAILQ_INIT(&sptree); 423} 424 425struct ipsecrequest * 426newipsecreq() 427{ 428 struct ipsecrequest *new; 429 430 new = racoon_calloc(1, sizeof(*new)); 431 if (new == NULL) 432 return NULL; 433 434 return new; 435} 436 437const char * 438spidx2str(spidx) 439 const struct policyindex *spidx; 440{ 441 /* addr/pref[port] addr/pref[port] ul dir act */ 442 static char buf[256]; 443 char *p, *a, *b; 444 int blen, i; 445 446 blen = sizeof(buf) - 1; 447 p = buf; 448 449 a = saddr2str((const struct sockaddr *)&spidx->src); 450 for (b = a; *b != '\0'; b++) 451 if (*b == '[') { 452 *b = '\0'; 453 b++; 454 break; 455 } 456 i = snprintf(p, blen, "%s/%d[%s ", a, spidx->prefs, b); 457 if (i < 0 || i >= blen) 458 return NULL; 459 p += i; 460 blen -= i; 461 462 a = saddr2str((const struct sockaddr *)&spidx->dst); 463 for (b = a; *b != '\0'; b++) 464 if (*b == '[') { 465 *b = '\0'; 466 b++; 467 break; 468 } 469 i = snprintf(p, blen, "%s/%d[%s ", a, spidx->prefd, b); 470 if (i < 0 || i >= blen) 471 return NULL; 472 p += i; 473 blen -= i; 474 475 i = snprintf(p, blen, "proto=%s dir=%s", 476 s_proto(spidx->ul_proto), s_direction(spidx->dir)); 477 478#ifdef HAVE_SECCTX 479 if (spidx->sec_ctx.ctx_strlen) { 480 p += i; 481 blen -= i; 482 snprintf(p, blen, " sec_ctx:doi=%d,alg=%d,len=%d,str=%s", 483 spidx->sec_ctx.ctx_doi, spidx->sec_ctx.ctx_alg, 484 spidx->sec_ctx.ctx_strlen, spidx->sec_ctx.ctx_str); 485 } 486#endif 487 return buf; 488} 489