No empty .Rs/.Re
[netbsd-mini2440.git] / crypto / dist / ipsec-tools / src / racoon / sainfo.c
blob2b1f61b4892aaf4de8ef49007bfa29a3b2714518
1 /* $NetBSD: sainfo.c,v 1.10 2007/09/12 23:39:51 mgrooms Exp $ */
3 /* $KAME: sainfo.c,v 1.16 2003/06/27 07:32:39 sakane Exp $ */
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.
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.
34 #include "config.h"
36 #include <sys/param.h>
37 #include <sys/types.h>
38 #include <sys/socket.h>
39 #include <sys/queue.h>
41 #include <netinet/in.h>
42 #include <netinet/in.h>
43 #include PATH_IPSEC_H
45 #include <stdlib.h>
46 #include <stdio.h>
47 #include <string.h>
48 #include <errno.h>
50 #include "var.h"
51 #include "misc.h"
52 #include "vmbuf.h"
53 #include "plog.h"
54 #include "sockmisc.h"
55 #include "debug.h"
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"
67 static LIST_HEAD(_sitree, sainfo) sitree, sitree_save, sitree_tmp;
69 /* %%%
70 * modules for ipsec sa info
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.
78 struct sainfo *
79 getsainfo(loc, rmt, peer, client, remoteid)
80 const vchar_t *loc, *rmt, *peer, *client;
81 int remoteid;
83 struct sainfo *s = NULL;
85 /* debug level output */
86 if(loglevel >= LLV_DEBUG) {
87 char *dloc, *drmt, *dpeer, *dclient;
89 if (loc == NULL)
90 dloc = strdup("ANONYMOUS");
91 else
92 dloc = ipsecdoi_id2str(loc);
94 if (rmt == SAINFO_ANONYMOUS)
95 drmt = strdup("ANONYMOUS");
96 else if (rmt == SAINFO_CLIENTADDR)
97 drmt = strdup("CLIENTADDR");
98 else
99 drmt = ipsecdoi_id2str(rmt);
101 if (peer == NULL)
102 dpeer = strdup("NULL");
103 else
104 dpeer = ipsecdoi_id2str(peer);
106 if (client == NULL)
107 dclient = strdup("NULL");
108 else
109 dclient = ipsecdoi_id2str(client);
111 plog(LLV_DEBUG, LOCATION, NULL,
112 "getsainfo params: loc=\'%s\' rmt=\'%s\' peer=\'%s\' client=\'%s\' id=%i\n",
113 dloc, drmt, dpeer, dclient, remoteid );
115 racoon_free(dloc);
116 racoon_free(drmt);
117 racoon_free(dpeer);
120 LIST_FOREACH(s, &sitree, chain) {
121 const char *sainfostr = sainfo2str(s);
122 plog(LLV_DEBUG, LOCATION, NULL,
123 "evaluating sainfo: %s\n", sainfostr);
125 if(s->remoteid != remoteid) {
126 plog(LLV_DEBUG, LOCATION, NULL,
127 "remoteid mismatch: %i != %i\n",
128 s->remoteid, remoteid);
129 continue;
132 /* compare 'from' id value */
133 if (s->id_i != NULL)
134 if (ipsecdoi_chkcmpids(peer, s->id_i, 0))
135 continue;
137 /* compare ids - client */
138 if( s->iddst == SAINFO_CLIENTADDR ) {
140 * This sainfo section enforces client address
141 * checking. Prevent match if the client value
142 * ( modecfg or tunnel address ) is NULL.
145 if (client == NULL)
146 continue;
148 if( rmt == SAINFO_CLIENTADDR ) {
150 * In the case where a supplied rmt value is
151 * also SAINFO_CLIENTADDR, we are comparing
152 * with another sainfo to check for duplicate.
153 * Only compare the local values to determine
154 * a match.
157 if (!ipsecdoi_chkcmpids(loc, s->idsrc, 0))
158 return s;
160 else {
162 * In the case where a supplied rmt value is
163 * not SAINFO_CLIENTADDR, do a standard match
164 * for local values and enforce that the rmt
165 * id matches the client address value.
168 if (!ipsecdoi_chkcmpids(loc, s->idsrc, 0) &&
169 !ipsecdoi_chkcmpids(rmt, client, 0))
170 return s;
173 continue;
177 /* compare ids - standard */
178 if (!ipsecdoi_chkcmpids(loc, s->idsrc, 0) &&
179 !ipsecdoi_chkcmpids(rmt, s->iddst, 0))
180 return s;
183 return NULL;
186 struct sainfo *
187 newsainfo()
189 struct sainfo *new;
191 new = racoon_calloc(1, sizeof(*new));
192 if (new == NULL)
193 return NULL;
195 new->lifetime = IPSECDOI_ATTR_SA_LD_SEC_DEFAULT;
196 new->lifebyte = IPSECDOI_ATTR_SA_LD_KB_MAX;
198 return new;
201 void
202 delsainfo(si)
203 struct sainfo *si;
205 int i;
207 for (i = 0; i < MAXALGCLASS; i++)
208 delsainfoalg(si->algs[i]);
210 if (si->idsrc)
211 vfree(si->idsrc);
212 if (si->iddst != NULL &&
213 si->iddst != SAINFO_CLIENTADDR)
214 vfree(si->iddst);
216 #ifdef ENABLE_HYBRID
217 if (si->group)
218 vfree(si->group);
219 #endif
221 racoon_free(si);
224 int prisainfo(s)
225 struct sainfo *s;
228 * determine the matching priority
229 * of an sainfo section
232 int pri = 0;
234 if(s->remoteid)
235 pri += 3;
237 if(s->id_i)
238 pri += 3;
240 if(s->idsrc)
241 pri++;
243 if(s->iddst)
244 pri++;
246 return pri;
249 void
250 inssainfo(new)
251 struct sainfo *new;
253 if(LIST_EMPTY(&sitree)) {
255 /* first in list */
256 LIST_INSERT_HEAD(&sitree, new, chain);
258 else {
259 int npri, spri;
260 struct sainfo *s, *n;
263 * insert our new sainfo section
264 * into our list which is sorted
265 * based on the match priority
268 npri = prisainfo(new);
270 s = LIST_FIRST(&sitree);
271 while (1) {
273 spri = prisainfo(s);
274 n = LIST_NEXT(s, chain);
276 if(npri > spri)
278 /* higher priority */
279 LIST_INSERT_BEFORE(s, new, chain);
280 return;
283 if(n == NULL)
285 /* last in list */
286 LIST_INSERT_AFTER(s, new, chain);
287 return;
290 s = n;
295 void
296 remsainfo(si)
297 struct sainfo *si;
299 LIST_REMOVE(si, chain);
302 void
303 flushsainfo()
305 struct sainfo *s, *next;
307 for (s = LIST_FIRST(&sitree); s; s = next) {
308 next = LIST_NEXT(s, chain);
309 remsainfo(s);
310 delsainfo(s);
314 void
315 initsainfo()
317 LIST_INIT(&sitree);
320 struct sainfoalg *
321 newsainfoalg()
323 struct sainfoalg *new;
325 new = racoon_calloc(1, sizeof(*new));
326 if (new == NULL)
327 return NULL;
329 return new;
332 void
333 delsainfoalg(alg)
334 struct sainfoalg *alg;
336 struct sainfoalg *a, *next;
338 for (a = alg; a; a = next) {
339 next = a->next;
340 racoon_free(a);
344 void
345 inssainfoalg(head, new)
346 struct sainfoalg **head;
347 struct sainfoalg *new;
349 struct sainfoalg *a;
351 for (a = *head; a && a->next; a = a->next)
353 if (a)
354 a->next = new;
355 else
356 *head = new;
359 const char *
360 sainfo2str(si)
361 const struct sainfo *si;
363 static char buf[256];
365 char *idloc = NULL, *idrmt = NULL, *id_i;
367 if (si->idsrc == SAINFO_ANONYMOUS)
368 idloc = strdup("ANONYMOUS");
369 else
370 idloc = ipsecdoi_id2str(si->idsrc);
372 if (si->iddst == SAINFO_ANONYMOUS)
373 idrmt = strdup("ANONYMOUS");
374 else if (si->iddst == SAINFO_CLIENTADDR)
375 idrmt = strdup("CLIENTADDR");
376 else
377 idrmt = ipsecdoi_id2str(si->iddst);
379 if (si->id_i == NULL)
380 id_i = strdup("ANY");
381 else
382 id_i = ipsecdoi_id2str(si->id_i);
384 snprintf(buf, 255, "loc=\'%s\', rmt=\'%s\', peer=\'%s\', id=%i",
385 idloc, idrmt, id_i, si->remoteid);
387 racoon_free(idloc);
388 racoon_free(idrmt);
389 racoon_free(id_i);
391 return buf;
394 void save_sainfotree(void){
395 sitree_save=sitree;
396 initsainfo();
399 void save_sainfotree_flush(void){
400 sitree_tmp=sitree;
401 sitree=sitree_save;
402 flushsainfo();
403 sitree=sitree_tmp;
406 void save_sainfotree_restore(void){
407 flushsainfo();
408 sitree=sitree_save;