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 67 static 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 */ 78 struct sainfo * 79 getsainfo(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 163 struct sainfo * 164 newsainfo() 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 178 void 179 delsainfo(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 200 void 201 inssainfo(new) 202 struct sainfo *new; 203 { 204 LIST_INSERT_HEAD(&sitree, new, chain); 205 } 206 207 void 208 remsainfo(si) 209 struct sainfo *si; 210 { 211 LIST_REMOVE(si, chain); 212 } 213 214 void 215 flushsainfo() 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 226 void 227 initsainfo() 228 { 229 LIST_INIT(&sitree); 230 } 231 232 struct sainfoalg * 233 newsainfoalg() 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 244 void 245 delsainfoalg(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 256 void 257 inssainfoalg(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 271 const char * 272 sainfo2str(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 304 void save_sainfotree(void){ 305 sitree_save=sitree; 306 initsainfo(); 307 } 308 309 void save_sainfotree_flush(void){ 310 sitree_tmp=sitree; 311 sitree=sitree_save; 312 flushsainfo(); 313 sitree=sitree_tmp; 314 } 315 316 void save_sainfotree_restore(void){ 317 flushsainfo(); 318 sitree=sitree_save; 319 } 320