1/* $NetBSD: sainfo.c,v 1.7.6.1 2007/08/01 11:52:22 vanhu Exp $ */ 2 3/* $KAME: sainfo.c,v 1.16 2003/06/27 07:32:39 sakane Exp $ */ 4 5/* 6 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 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. 20 * 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 31 * SUCH DAMAGE. 32 */ 33 34#include "config.h" 35 36#include <sys/param.h> 37#include <sys/types.h> 38#include <sys/socket.h> 39#include <sys/queue.h> 40 41#include <netinet/in.h> 42#include <netinet/in.h> 43#include PATH_IPSEC_H 44 45#include <stdlib.h> 46#include <stdio.h> 47#include <string.h> 48#include <errno.h> 49 50#include "var.h" 51#include "misc.h" 52#include "vmbuf.h" 53#include "plog.h" 54#include "sockmisc.h" 55#include "debug.h" 56 57#include "localconf.h" 58#include "isakmp_var.h" 59#include "isakmp.h" 60#include "ipsec_doi.h" 61#include "oakley.h" 62#include "handler.h" 63#include "algorithm.h" 64#include "sainfo.h" 65#include "gcmalloc.h" 66 67static LIST_HEAD(_sitree, sainfo) sitree, sitree_save, sitree_tmp; 68 69/* %%% 70 * modules for ipsec sa info 71 */ 72/* 73 * return matching entry. 74 * no matching entry found and if there is anonymous entry, return it. 75 * else return NULL. 76 * First pass is for sainfo from a specified peer, second for others. 77 */ 78struct sainfo * 79getsainfo(loc, rmt, peer, remoteid) 80 const vchar_t *loc, *rmt, *peer; 81 int remoteid; 82{ 83 struct sainfo *s = NULL; 84 struct sainfo *anonymous = NULL; 85 int pass = 1; 86 87 if (peer == NULL) 88 pass = 2; 89 90 /* debug level output */ 91 if(loglevel >= LLV_DEBUG) { 92 char *dloc, *drmt, *dpeer, *dclient; 93 94 if (loc == NULL) 95 dloc = strdup("ANONYMOUS"); 96 else 97 dloc = ipsecdoi_id2str(loc); 98 99 if (rmt == NULL) 100 drmt = strdup("ANONYMOUS"); 101 else 102 drmt = ipsecdoi_id2str(rmt); 103 104 if (peer == NULL) 105 dpeer = strdup("NULL"); 106 else 107 dpeer = ipsecdoi_id2str(peer); 108 109 plog(LLV_DEBUG, LOCATION, NULL, 110 "getsainfo params: loc=\'%s\', rmt=\'%s\', peer=\'%s\', id=%i\n", 111 dloc, drmt, dpeer, remoteid ); 112 113 racoon_free(dloc); 114 racoon_free(drmt); 115 racoon_free(dpeer); 116 } 117 118 again: 119 plog(LLV_DEBUG, LOCATION, NULL, 120 "getsainfo pass #%i\n", pass); 121 122 LIST_FOREACH(s, &sitree, chain) { 123 const char *sainfostr = sainfo2str(s); 124 plog(LLV_DEBUG, LOCATION, NULL, 125 "evaluating sainfo: %s\n", sainfostr); 126 127 if(s->remoteid != remoteid) 128 continue; 129 130 if (s->id_i != NULL) { 131 if (pass == 2) 132 continue; 133 if (ipsecdoi_chkcmpids(peer, s->id_i, 0)) 134 continue; 135 } else if (pass == 1) 136 continue; 137 if (s->idsrc == NULL && s->iddst == NULL) { 138 anonymous = s; 139 continue; 140 } 141 142 /* anonymous ? */ 143 if (loc == NULL) { 144 if (anonymous != NULL) 145 break; 146 continue; 147 } 148 149 /* compare the ids */ 150 if (!ipsecdoi_chkcmpids(loc, s->idsrc, 0) && 151 !ipsecdoi_chkcmpids(rmt, s->iddst, 0)) 152 return s; 153 } 154 155 if ((anonymous == NULL) && (pass == 1)) { 156 pass++; 157 goto again; 158 } 159 160 return anonymous; 161} 162 163struct sainfo * 164newsainfo() 165{ 166 struct sainfo *new; 167 168 new = racoon_calloc(1, sizeof(*new)); 169 if (new == NULL) 170 return NULL; 171 172 new->lifetime = IPSECDOI_ATTR_SA_LD_SEC_DEFAULT; 173 new->lifebyte = IPSECDOI_ATTR_SA_LD_KB_MAX; 174 175 return new; 176} 177 178void 179delsainfo(si) 180 struct sainfo *si; 181{ 182 int i; 183 184 for (i = 0; i < MAXALGCLASS; i++) 185 delsainfoalg(si->algs[i]); 186 187 if (si->idsrc) 188 vfree(si->idsrc); 189 if (si->iddst) 190 vfree(si->iddst); 191 192#ifdef ENABLE_HYBRID 193 if (si->group) 194 vfree(si->group); 195#endif 196 197 racoon_free(si); 198} 199 200void 201inssainfo(new) 202 struct sainfo *new; 203{ 204 LIST_INSERT_HEAD(&sitree, new, chain); 205} 206 207void 208remsainfo(si) 209 struct sainfo *si; 210{ 211 LIST_REMOVE(si, chain); 212} 213 214void 215flushsainfo() 216{ 217 struct sainfo *s, *next; 218 219 for (s = LIST_FIRST(&sitree); s; s = next) { 220 next = LIST_NEXT(s, chain); 221 remsainfo(s); 222 delsainfo(s); 223 } 224} 225 226void 227initsainfo() 228{ 229 LIST_INIT(&sitree); 230} 231 232struct sainfoalg * 233newsainfoalg() 234{ 235 struct sainfoalg *new; 236 237 new = racoon_calloc(1, sizeof(*new)); 238 if (new == NULL) 239 return NULL; 240 241 return new; 242} 243 244void 245delsainfoalg(alg) 246 struct sainfoalg *alg; 247{ 248 struct sainfoalg *a, *next; 249 250 for (a = alg; a; a = next) { 251 next = a->next; 252 racoon_free(a); 253 } 254} 255 256void 257inssainfoalg(head, new) 258 struct sainfoalg **head; 259 struct sainfoalg *new; 260{ 261 struct sainfoalg *a; 262 263 for (a = *head; a && a->next; a = a->next) 264 ; 265 if (a) 266 a->next = new; 267 else 268 *head = new; 269} 270 271const char * 272sainfo2str(si) 273 const struct sainfo *si; 274{ 275 static char buf[256]; 276 277 char *idloc = NULL, *idrmt = NULL, *id_i; 278 279 if (si->idsrc == NULL) 280 idloc = strdup("ANONYMOUS"); 281 else 282 idloc = ipsecdoi_id2str(si->idsrc); 283 284 if (si->iddst == NULL) 285 idrmt = strdup("ANONYMOUS"); 286 else 287 idrmt = ipsecdoi_id2str(si->iddst); 288 289 if (si->id_i == NULL) 290 id_i = strdup("ANY"); 291 else 292 id_i = ipsecdoi_id2str(si->id_i); 293 294 snprintf(buf, 255, "loc=\'%s\', rmt=\'%s\', peer=\'%s\', id=%i", 295 idloc, idrmt, id_i, si->remoteid); 296 297 racoon_free(idloc); 298 racoon_free(idrmt); 299 racoon_free(id_i); 300 301 return buf; 302} 303 304void save_sainfotree(void){ 305 sitree_save=sitree; 306 initsainfo(); 307} 308 309void save_sainfotree_flush(void){ 310 sitree_tmp=sitree; 311 sitree=sitree_save; 312 flushsainfo(); 313 sitree=sitree_tmp; 314} 315 316void save_sainfotree_restore(void){ 317 flushsainfo(); 318 sitree=sitree_save; 319} 320