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 *
newsainfo()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
delsainfo(si)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
inssainfo(new)201 inssainfo(new)
202 struct sainfo *new;
203 {
204 LIST_INSERT_HEAD(&sitree, new, chain);
205 }
206
207 void
remsainfo(si)208 remsainfo(si)
209 struct sainfo *si;
210 {
211 LIST_REMOVE(si, chain);
212 }
213
214 void
flushsainfo()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
initsainfo()227 initsainfo()
228 {
229 LIST_INIT(&sitree);
230 }
231
232 struct sainfoalg *
newsainfoalg()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
delsainfoalg(alg)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
inssainfoalg(head,new)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 *
sainfo2str(si)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
save_sainfotree(void)304 void save_sainfotree(void){
305 sitree_save=sitree;
306 initsainfo();
307 }
308
save_sainfotree_flush(void)309 void save_sainfotree_flush(void){
310 sitree_tmp=sitree;
311 sitree=sitree_save;
312 flushsainfo();
313 sitree=sitree_tmp;
314 }
315
save_sainfotree_restore(void)316 void save_sainfotree_restore(void){
317 flushsainfo();
318 sitree=sitree_save;
319 }
320