]>
Commit | Line | Data |
---|---|---|
1c79356b A |
1 | /* $KAME: key.c,v 1.76 2000/03/27 05:11:04 sumikawa Exp $ */ |
2 | ||
3 | /* | |
4 | * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. | |
5 | * All rights reserved. | |
6 | * | |
7 | * Redistribution and use in source and binary forms, with or without | |
8 | * modification, are permitted provided that the following conditions | |
9 | * are met: | |
10 | * 1. Redistributions of source code must retain the above copyright | |
11 | * notice, this list of conditions and the following disclaimer. | |
12 | * 2. Redistributions in binary form must reproduce the above copyright | |
13 | * notice, this list of conditions and the following disclaimer in the | |
14 | * documentation and/or other materials provided with the distribution. | |
15 | * 3. Neither the name of the project nor the names of its contributors | |
16 | * may be used to endorse or promote products derived from this software | |
17 | * without specific prior written permission. | |
18 | * | |
19 | * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND | |
20 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE | |
23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
25 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
26 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
28 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
29 | * SUCH DAMAGE. | |
30 | */ | |
31 | ||
32 | /* | |
33 | * This code is referd to RFC 2367 | |
34 | */ | |
35 | ||
36 | #if (defined(__FreeBSD__) && __FreeBSD__ >= 3) || defined(__NetBSD__) | |
37 | #include "opt_inet.h" | |
38 | #ifdef __NetBSD__ | |
39 | #include "opt_ipsec.h" | |
40 | #endif | |
41 | #endif | |
42 | ||
43 | /* this is for backward compatibility. we should not touch those. */ | |
44 | #define ss_len __ss_len | |
45 | #define ss_family __ss_family | |
46 | ||
47 | #include <sys/types.h> | |
48 | #include <sys/param.h> | |
49 | #include <sys/systm.h> | |
50 | #include <sys/kernel.h> | |
51 | #include <sys/mbuf.h> | |
52 | #include <sys/domain.h> | |
53 | #include <sys/protosw.h> | |
54 | #include <sys/malloc.h> | |
55 | #include <sys/socket.h> | |
56 | #include <sys/socketvar.h> | |
57 | #if defined(__FreeBSD__) || defined (__APPLE__) | |
58 | #include <sys/sysctl.h> | |
59 | #endif | |
60 | #include <sys/errno.h> | |
61 | #include <sys/proc.h> | |
62 | #include <sys/queue.h> | |
63 | ||
64 | #include <net/if.h> | |
65 | #include <net/route.h> | |
66 | #include <net/raw_cb.h> | |
67 | ||
68 | #include <netinet/in.h> | |
69 | #include <netinet/in_systm.h> | |
70 | #include <netinet/ip.h> | |
71 | #include <netinet/in_var.h> | |
72 | ||
73 | #if INET6 | |
74 | #include <netinet/ip6.h> | |
75 | #include <netinet6/in6_var.h> | |
76 | #include <netinet6/ip6_var.h> | |
77 | #endif /* INET6 */ | |
78 | ||
79 | #if INET | |
80 | #include <netinet/in_pcb.h> | |
81 | #endif | |
82 | #if INET6 | |
83 | #if !(defined(__bsdi__) && _BSDI_VERSION >= 199802) | |
84 | #include <netinet6/in6_pcb.h> | |
85 | #endif | |
86 | #endif /* INET6 */ | |
87 | ||
88 | #include <net/pfkeyv2.h> | |
89 | #include <netkey/keydb.h> | |
90 | #include <netkey/key.h> | |
91 | #include <netkey/keysock.h> | |
92 | #include <netkey/key_debug.h> | |
93 | ||
94 | #include <netinet6/ipsec.h> | |
95 | #include <netinet6/ah.h> | |
96 | #if IPSEC_ESP | |
97 | #include <netinet6/esp.h> | |
98 | #endif | |
99 | #include <netinet6/ipcomp.h> | |
100 | ||
101 | #include <net/net_osdep.h> | |
102 | ||
103 | /* | |
104 | * Note on SA reference counting: | |
105 | * - SAs that are not in DEAD state will have (total external reference + 1) | |
106 | * following value in reference count field. they cannot be freed and are | |
107 | * referenced from SA header. | |
108 | * - SAs that are in DEAD state will have (total external reference) | |
109 | * in reference count field. they are ready to be freed. reference from | |
110 | * SA header will be removed in key_delsav(), when the reference count | |
111 | * field hits 0 (= no external reference other than from SA header. | |
112 | */ | |
113 | ||
114 | u_int32_t key_debug_level = 0; //### our sysctl is not dynamic | |
115 | static u_int key_spi_trycnt = 1000; | |
116 | static u_int32_t key_spi_minval = 0x100; | |
117 | static u_int32_t key_spi_maxval = 0x0fffffff; /* XXX */ | |
118 | static u_int32_t policy_id = 0; | |
119 | static u_int key_int_random = 60; /*interval to initialize randseed,1(m)*/ | |
120 | static u_int key_larval_lifetime = 30; /* interval to expire acquiring, 30(s)*/ | |
121 | static int key_blockacq_count = 10; /* counter for blocking SADB_ACQUIRE.*/ | |
122 | static int key_blockacq_lifetime = 20; /* lifetime for blocking SADB_ACQUIRE.*/ | |
123 | ||
124 | static u_int32_t acq_seq = 0; | |
125 | static int key_tick_init_random = 0; | |
126 | ||
127 | static LIST_HEAD(_sptree, secpolicy) sptree[IPSEC_DIR_MAX]; /* SPD */ | |
128 | static LIST_HEAD(_sahtree, secashead) sahtree; /* SAD */ | |
129 | static LIST_HEAD(_regtree, secreg) regtree[SADB_SATYPE_MAX + 1]; | |
130 | /* registed list */ | |
131 | #ifndef IPSEC_NONBLOCK_ACQUIRE | |
132 | static LIST_HEAD(_acqtree, secacq) acqtree; /* acquiring list */ | |
133 | #endif | |
134 | static LIST_HEAD(_spacqtree, secspacq) spacqtree; /* SP acquiring list */ | |
135 | ||
136 | struct key_cb key_cb; | |
137 | ||
138 | /* search order for SAs */ | |
139 | static u_int saorder_state_valid[] = { | |
140 | SADB_SASTATE_DYING, SADB_SASTATE_MATURE, | |
141 | /* | |
142 | * This order is important because we must select a oldest SA | |
143 | * for outbound processing. For inbound, This is not important. | |
144 | */ | |
145 | }; | |
146 | static u_int saorder_state_alive[] = { | |
147 | /* except DEAD */ | |
148 | SADB_SASTATE_MATURE, SADB_SASTATE_DYING, SADB_SASTATE_LARVAL | |
149 | }; | |
150 | static u_int saorder_state_any[] = { | |
151 | SADB_SASTATE_MATURE, SADB_SASTATE_DYING, | |
152 | SADB_SASTATE_LARVAL, SADB_SASTATE_DEAD | |
153 | }; | |
154 | ||
155 | #if defined(__FreeBSD__) || defined (__APPLE__) | |
156 | SYSCTL_DECL(_net_key); | |
157 | //#if defined(IPSEC_DEBUG) | |
158 | SYSCTL_INT(_net_key, KEYCTL_DEBUG_LEVEL, debug, CTLFLAG_RW, \ | |
159 | &key_debug_level, 0, ""); | |
160 | //#endif /* defined(IPSEC_DEBUG) */ | |
161 | ||
162 | /* max count of trial for the decision of spi value */ | |
163 | SYSCTL_INT(_net_key, KEYCTL_SPI_TRY, spi_trycnt, CTLFLAG_RW, \ | |
164 | &key_spi_trycnt, 0, ""); | |
165 | ||
166 | /* minimum spi value to allocate automatically. */ | |
167 | SYSCTL_INT(_net_key, KEYCTL_SPI_MIN_VALUE, spi_minval, CTLFLAG_RW, \ | |
168 | &key_spi_minval, 0, ""); | |
169 | ||
170 | /* maximun spi value to allocate automatically. */ | |
171 | SYSCTL_INT(_net_key, KEYCTL_SPI_MAX_VALUE, spi_maxval, CTLFLAG_RW, \ | |
172 | &key_spi_maxval, 0, ""); | |
173 | ||
174 | /* interval to initialize randseed */ | |
175 | SYSCTL_INT(_net_key, KEYCTL_RANDOM_INT, int_random, CTLFLAG_RW, \ | |
176 | &key_int_random, 0, ""); | |
177 | ||
178 | /* lifetime for larval SA */ | |
179 | SYSCTL_INT(_net_key, KEYCTL_LARVAL_LIFETIME, larval_lifetime, CTLFLAG_RW, \ | |
180 | &key_larval_lifetime, 0, ""); | |
181 | ||
182 | /* counter for blocking to send SADB_ACQUIRE to IKEd */ | |
183 | SYSCTL_INT(_net_key, KEYCTL_BLOCKACQ_COUNT, blockacq_count, CTLFLAG_RW, \ | |
184 | &key_blockacq_count, 0, ""); | |
185 | ||
186 | /* lifetime for blocking to send SADB_ACQUIRE to IKEd */ | |
187 | SYSCTL_INT(_net_key, KEYCTL_BLOCKACQ_LIFETIME, blockacq_lifetime, CTLFLAG_RW, \ | |
188 | &key_blockacq_lifetime, 0, ""); | |
189 | ||
190 | #endif /* __FreeBSD__ */ | |
191 | ||
192 | #ifndef LIST_FOREACH | |
193 | #define LIST_FOREACH(elm, head, field) \ | |
194 | for (elm = LIST_FIRST(head); elm; elm = LIST_NEXT(elm, field)) | |
195 | #endif | |
196 | #define __LIST_CHAINED(elm) \ | |
197 | (!((elm)->chain.le_next == NULL && (elm)->chain.le_prev == NULL)) | |
198 | #define LIST_INSERT_TAIL(head, elm, type, field) \ | |
199 | do {\ | |
200 | struct type *curelm = LIST_FIRST(head); \ | |
201 | if (curelm == NULL) {\ | |
202 | LIST_INSERT_HEAD(head, elm, field); \ | |
203 | } else { \ | |
204 | while (LIST_NEXT(curelm, field)) \ | |
205 | curelm = LIST_NEXT(curelm, field);\ | |
206 | LIST_INSERT_AFTER(curelm, elm, field);\ | |
207 | }\ | |
208 | } while (0) | |
209 | ||
210 | #define KEY_CHKSASTATE(head, sav, name) \ | |
211 | do { \ | |
212 | if ((head) != (sav)) { \ | |
213 | printf("%s: state mismatched (TREE=%d SA=%d)\n", \ | |
214 | (name), (head), (sav)); \ | |
215 | continue; \ | |
216 | } \ | |
217 | } while (0) | |
218 | ||
219 | #define KEY_CHKSPDIR(head, sp, name) \ | |
220 | do { \ | |
221 | if ((head) != (sp)) { \ | |
222 | printf("%s: direction mismatched (TREE=%d SP=%d), " \ | |
223 | "anyway continue.\n", \ | |
224 | (name), (head), (sp)); \ | |
225 | } \ | |
226 | } while (0) | |
227 | ||
228 | #if 1 | |
229 | #define KMALLOC(p, t, n) \ | |
230 | ((p) = (t) _MALLOC((unsigned long)(n), M_SECA, M_NOWAIT)) | |
231 | #define KFREE(p) \ | |
232 | _FREE((caddr_t)(p), M_SECA); | |
233 | #else | |
234 | #define KMALLOC(p, t, n) \ | |
235 | do { \ | |
236 | ((p) = (t)_MALLOC((unsigned long)(n), M_SECA, M_NOWAIT)); \ | |
237 | printf("%s %d: %p <- KMALLOC(%s, %d)\n", \ | |
238 | __FILE__, __LINE__, (p), #t, n); \ | |
239 | } while (0) | |
240 | ||
241 | #define KFREE(p) \ | |
242 | do { \ | |
243 | printf("%s %d: %p -> KFREE()\n", __FILE__, __LINE__, (p)); \ | |
244 | _FREE((caddr_t)(p), M_SECA); \ | |
245 | } while (0) | |
246 | #endif | |
247 | ||
248 | /* | |
249 | * set parameters into secpolicyindex buffer. | |
250 | * Must allocate secpolicyindex buffer passed to this function. | |
251 | */ | |
252 | #define KEY_SETSECSPIDX(_dir, s, d, ps, pd, ulp, idx) \ | |
253 | do { \ | |
254 | bzero((idx), sizeof(struct secpolicyindex)); \ | |
255 | (idx)->dir = (_dir); \ | |
256 | (idx)->prefs = (ps); \ | |
257 | (idx)->prefd = (pd); \ | |
258 | (idx)->ul_proto = (ulp); \ | |
259 | bcopy((s), &(idx)->src, ((struct sockaddr *)(s))->sa_len); \ | |
260 | bcopy((d), &(idx)->dst, ((struct sockaddr *)(d))->sa_len); \ | |
261 | } while (0) | |
262 | ||
263 | /* | |
264 | * set parameters into secasindex buffer. | |
265 | * Must allocate secasindex buffer before calling this function. | |
266 | */ | |
267 | #define KEY_SETSECASIDX(p, m, s, d, idx) \ | |
268 | do { \ | |
269 | bzero((idx), sizeof(struct secasindex)); \ | |
270 | (idx)->proto = (p); \ | |
271 | (idx)->mode = (m)->sadb_msg_mode; \ | |
272 | (idx)->reqid = (m)->sadb_msg_reqid; \ | |
273 | bcopy((s), &(idx)->src, ((struct sockaddr *)(s))->sa_len); \ | |
274 | bcopy((d), &(idx)->dst, ((struct sockaddr *)(d))->sa_len); \ | |
275 | } while (0) | |
276 | ||
277 | /* key statistics */ | |
278 | struct _keystat { | |
279 | u_long getspi_count; /* the avarage of count to try to get new SPI */ | |
280 | } keystat; | |
281 | ||
282 | static struct secasvar *key_allocsa_policy __P((struct secasindex *saidx)); | |
283 | static void key_freesp_so __P((struct secpolicy **sp)); | |
284 | static struct secasvar *key_do_allocsa_policy __P((struct secashead *sah, | |
285 | u_int state)); | |
286 | static void key_delsp __P((struct secpolicy *sp)); | |
287 | static struct secpolicy *key_getsp __P((struct secpolicyindex *spidx)); | |
288 | static struct secpolicy *key_getspbyid __P((u_int32_t id)); | |
289 | static u_int32_t key_newreqid __P((void)); | |
290 | static struct sadb_msg *key_spdadd __P((caddr_t *mhp)); | |
291 | static u_int32_t key_getnewspid __P((void)); | |
292 | static struct sadb_msg *key_spddelete __P((caddr_t *mhp)); | |
293 | static struct sadb_msg *key_spddelete2 __P((caddr_t *mhp)); | |
294 | static int key_spdget __P((caddr_t *mhp, struct socket *so, int target)); | |
295 | static struct sadb_msg *key_spdflush __P((caddr_t *mhp)); | |
296 | static int key_spddump __P((caddr_t *mhp, struct socket *so, int target)); | |
297 | static struct mbuf *key_setdumpsp __P((struct secpolicy *sp, | |
298 | u_int8_t type, u_int32_t seq, u_int32_t pid)); | |
299 | static u_int key_getspmsglen __P((struct secpolicy *sp)); | |
300 | static u_int key_getspreqmsglen __P((struct secpolicy *sp)); | |
301 | static struct secashead *key_newsah __P((struct secasindex *saidx)); | |
302 | static void key_delsah __P((struct secashead *sah)); | |
303 | static struct secasvar *key_newsav __P((caddr_t *mhp, struct secashead *sah)); | |
304 | static void key_delsav __P((struct secasvar *sav)); | |
305 | static struct secashead *key_getsah __P((struct secasindex *saidx)); | |
306 | static struct secasvar *key_checkspidup __P((struct secasindex *saidx, | |
307 | u_int32_t spi)); | |
308 | static struct secasvar *key_getsavbyspi __P((struct secashead *sah, | |
309 | u_int32_t spi)); | |
310 | static int key_setsaval __P((struct secasvar *sav, caddr_t *mhp)); | |
311 | static u_int key_getmsglen __P((struct secasvar *sav)); | |
312 | static int key_mature __P((struct secasvar *sav)); | |
313 | static u_int key_setdumpsa __P((struct sadb_msg *newmsg, struct secasvar *sav, | |
314 | u_int8_t type, u_int8_t satype, | |
315 | u_int32_t seq, u_int32_t pid)); | |
316 | #if 1 | |
317 | static int key_setsadbmsg_m __P((struct mbuf *, u_int8_t type, int tlen, | |
318 | u_int8_t satype, u_int32_t seq, pid_t pid, | |
319 | u_int8_t mode, u_int32_t reqid, | |
320 | u_int8_t reserved1, u_int32_t reserved2)); | |
321 | #endif | |
322 | static caddr_t key_setsadbmsg __P((caddr_t buf, u_int8_t type, int tlen, | |
323 | u_int8_t satype, u_int32_t seq, pid_t pid, | |
324 | u_int8_t mode, u_int32_t reqid, | |
325 | u_int8_t reserved1, u_int32_t reserved2)); | |
326 | static caddr_t key_setsadbsa __P((caddr_t buf, struct secasvar *sav)); | |
327 | #if 1 | |
328 | static int key_setsadbaddr_m __P((struct mbuf *m, u_int16_t exttype, | |
329 | struct sockaddr *saddr, u_int8_t prefixlen, u_int16_t ul_proto)); | |
330 | #endif | |
331 | static caddr_t key_setsadbaddr __P((caddr_t buf, u_int16_t exttype, | |
332 | struct sockaddr *saddr, u_int8_t prefixlen, u_int16_t ul_proto)); | |
333 | static caddr_t key_setsadbident | |
334 | __P((caddr_t buf, u_int16_t exttype, u_int16_t idtype, | |
335 | caddr_t string, int stringlen, u_int64_t id)); | |
336 | static caddr_t key_setsadbxpolicy | |
337 | __P((caddr_t buf, u_int16_t type, u_int8_t dir, u_int32_t id)); | |
338 | static caddr_t key_setsadbext __P((caddr_t p, caddr_t ext)); | |
339 | static void *key_newbuf __P((void *src, u_int len)); | |
340 | #if INET6 | |
341 | static int key_ismyaddr6 __P((caddr_t addr)); | |
342 | #endif | |
343 | #if 0 | |
344 | static int key_isloopback __P((u_int family, caddr_t addr)); | |
345 | #endif | |
346 | static int key_cmpsaidx_exactly | |
347 | __P((struct secasindex *saidx0, struct secasindex *saidx1)); | |
348 | static int key_cmpsaidx_withmode | |
349 | __P((struct secasindex *saidx0, struct secasindex *saidx1)); | |
350 | static int key_cmpspidx_exactly | |
351 | __P((struct secpolicyindex *spidx0, struct secpolicyindex *spidx1)); | |
352 | static int key_cmpspidx_withmask | |
353 | __P((struct secpolicyindex *spidx0, struct secpolicyindex *spidx1)); | |
354 | static int key_bbcmp __P((caddr_t p1, caddr_t p2, u_int bits)); | |
355 | static u_int16_t key_satype2proto __P((u_int8_t satype)); | |
356 | static u_int8_t key_proto2satype __P((u_int16_t proto)); | |
357 | ||
358 | static struct sadb_msg *key_getspi __P((caddr_t *mhp)); | |
359 | static u_int32_t key_do_getnewspi __P((struct sadb_spirange *spirange, | |
360 | struct secasindex *saidx)); | |
361 | static struct sadb_msg *key_update __P((caddr_t *mhp)); | |
362 | #ifdef IPSEC_DOSEQCHECK | |
363 | static struct secasvar *key_getsavbyseq __P((struct secashead *sah, | |
364 | u_int32_t seq)); | |
365 | #endif | |
366 | static struct sadb_msg *key_add __P((caddr_t *mhp)); | |
367 | static int key_setident __P((struct secashead *sah, caddr_t *mhp)); | |
368 | static struct sadb_msg *key_getmsgbuf_x1 __P((caddr_t *mhp)); | |
369 | static struct sadb_msg *key_delete __P((caddr_t *mhp)); | |
370 | static struct sadb_msg *key_get __P((caddr_t *mhp)); | |
371 | static int key_acquire __P((struct secasindex *, struct secpolicy *)); | |
372 | static struct secacq *key_newacq __P((struct secasindex *saidx)); | |
373 | static struct secacq *key_getacq __P((struct secasindex *saidx)); | |
374 | static struct secacq *key_getacqbyseq __P((u_int32_t seq)); | |
375 | static struct secspacq *key_newspacq __P((struct secpolicyindex *spidx)); | |
376 | static struct secspacq *key_getspacq __P((struct secpolicyindex *spidx)); | |
377 | static struct sadb_msg *key_acquire2 __P((caddr_t *mhp)); | |
378 | static struct sadb_msg *key_register __P((caddr_t *mhp, struct socket *so)); | |
379 | static int key_expire __P((struct secasvar *sav)); | |
380 | static struct sadb_msg *key_flush __P((caddr_t *mhp)); | |
381 | static int key_dump __P((caddr_t *mhp, struct socket *so, int target)); | |
382 | static void key_promisc __P((caddr_t *mhp, struct socket *so)); | |
383 | static int key_sendall __P((struct sadb_msg *msg, u_int len)); | |
384 | static int key_align __P((struct sadb_msg *msg, caddr_t *mhp)); | |
385 | #if 0 | |
386 | static const char *key_getfqdn __P((void)); | |
387 | static const char *key_getuserfqdn __P((void)); | |
388 | #endif | |
389 | static void key_sa_chgstate __P((struct secasvar *sav, u_int8_t state)); | |
390 | static caddr_t key_appendmbuf __P((struct mbuf *, int)); | |
391 | ||
392 | /* %%% IPsec policy management */ | |
393 | /* | |
394 | * allocating a SP for OUTBOUND or INBOUND packet. | |
395 | * Must call key_freesp() later. | |
396 | * OUT: NULL: not found | |
397 | * others: found and return the pointer. | |
398 | */ | |
399 | struct secpolicy * | |
400 | key_allocsp(spidx, dir) | |
401 | struct secpolicyindex *spidx; | |
402 | u_int dir; | |
403 | { | |
404 | struct secpolicy *sp; | |
405 | int s; | |
406 | ||
407 | /* sanity check */ | |
408 | if (spidx == NULL) | |
409 | panic("key_allocsp: NULL pointer is passed.\n"); | |
410 | ||
411 | /* check direction */ | |
412 | switch (dir) { | |
413 | case IPSEC_DIR_INBOUND: | |
414 | case IPSEC_DIR_OUTBOUND: | |
415 | break; | |
416 | default: | |
417 | panic("key_allocsp: Invalid direction is passed.\n"); | |
418 | } | |
419 | ||
420 | /* get a SP entry */ | |
421 | #ifdef __NetBSD__ | |
422 | s = splsoftnet(); /*called from softclock()*/ | |
423 | #else | |
424 | s = splnet(); /*called from softclock()*/ | |
425 | #endif | |
426 | KEYDEBUG(KEYDEBUG_IPSEC_DATA, | |
427 | printf("*** objects\n"); | |
428 | kdebug_secpolicyindex(spidx)); | |
429 | ||
430 | LIST_FOREACH(sp, &sptree[dir], chain) { | |
431 | KEYDEBUG(KEYDEBUG_IPSEC_DATA, | |
432 | printf("*** in SPD\n"); | |
433 | kdebug_secpolicyindex(&sp->spidx)); | |
434 | ||
435 | if (sp->state == IPSEC_SPSTATE_DEAD) | |
436 | continue; | |
437 | if (key_cmpspidx_withmask(&sp->spidx, spidx)) | |
438 | goto found; | |
439 | } | |
440 | ||
441 | splx(s); | |
442 | return NULL; | |
443 | ||
444 | found: | |
445 | /* sanity check */ | |
446 | KEY_CHKSPDIR(sp->spidx.dir, dir, "key_allocsp"); | |
447 | ||
448 | /* found a SPD entry */ | |
449 | sp->refcnt++; | |
450 | splx(s); | |
451 | KEYDEBUG(KEYDEBUG_IPSEC_STAMP, | |
452 | printf("DP key_allocsp cause refcnt++:%d SP:%p\n", | |
453 | sp->refcnt, sp)); | |
454 | ||
455 | return sp; | |
456 | } | |
457 | ||
458 | /* | |
459 | * allocating a SA entry for a *OUTBOUND* packet. | |
460 | * checking each request entries in SP, and acquire SA if need. | |
461 | * OUT: 0: there are valid requests. | |
462 | * ENOENT: policy may be valid, but SA with REQUIRE is on acquiring. | |
463 | */ | |
464 | int | |
465 | key_checkrequest(isr, saidx) | |
466 | struct ipsecrequest *isr; | |
467 | struct secasindex *saidx; | |
468 | { | |
469 | u_int level; | |
470 | int error; | |
471 | ||
472 | /* sanity check */ | |
473 | if (isr == NULL || saidx == NULL) | |
474 | panic("key_checkrequest: NULL pointer is passed.\n"); | |
475 | ||
476 | /* check mode */ | |
477 | switch (saidx->mode) { | |
478 | case IPSEC_MODE_TRANSPORT: | |
479 | case IPSEC_MODE_TUNNEL: | |
480 | break; | |
481 | case IPSEC_MODE_ANY: | |
482 | default: | |
483 | panic("key_checkrequest: Invalid policy defined.\n"); | |
484 | } | |
485 | ||
486 | /* get current level */ | |
487 | level = ipsec_get_reqlevel(isr); | |
488 | ||
489 | #if 0 | |
490 | /* | |
491 | * We do allocate new SA only if the state of SA in the holder is | |
492 | * SADB_SASTATE_DEAD. The SA for outbound must be the oldest. | |
493 | */ | |
494 | if (isr->sav != NULL) { | |
495 | if (isr->sav->sah == NULL) | |
496 | panic("key_checkrequest: sah is null.\n"); | |
497 | if (isr->sav == (struct secasvar *)LIST_FIRST( | |
498 | &isr->sav->sah->savtree[SADB_SASTATE_DEAD])) { | |
499 | KEYDEBUG(KEYDEBUG_IPSEC_STAMP, | |
500 | printf("DP checkrequest calls free SA:%p\n", | |
501 | isr->sav)); | |
502 | key_freesav(isr->sav); | |
503 | isr->sav = NULL; | |
504 | } | |
505 | } | |
506 | #else | |
507 | /* | |
508 | * we free any SA stashed in the IPsec request because a different | |
509 | * SA may be involved each time this request is checked, either | |
510 | * because new SAs are being configured, or this request is | |
511 | * associated with an unconnected datagram socket, or this request | |
512 | * is associated with a system default policy. | |
513 | * | |
514 | * The operation may have negative impact to performance. We may | |
515 | * want to check cached SA carefully, rather than picking new SA | |
516 | * every time. | |
517 | */ | |
518 | if (isr->sav != NULL) { | |
519 | key_freesav(isr->sav); | |
520 | isr->sav = NULL; | |
521 | } | |
522 | #endif | |
523 | ||
524 | /* | |
525 | * new SA allocation if no SA found. | |
526 | * key_allocsa_policy should allocate the oldest SA available. | |
527 | * See key_do_allocsa_policy(), and draft-jenkins-ipsec-rekeying-03.txt. | |
528 | */ | |
529 | if (isr->sav == NULL) | |
530 | isr->sav = key_allocsa_policy(saidx); | |
531 | ||
532 | /* When there is SA. */ | |
533 | if (isr->sav != NULL) | |
534 | return 0; | |
535 | ||
536 | /* there is no SA */ | |
537 | if ((error = key_acquire(saidx, isr->sp)) != 0) { | |
538 | /* XXX What I do ? */ | |
539 | #ifdef IPSEC_DEBUG | |
540 | printf("key_checkrequest: error %d returned " | |
541 | "from key_acquire.\n", error); | |
542 | #endif | |
543 | return error; | |
544 | } | |
545 | ||
546 | return level == IPSEC_LEVEL_REQUIRE ? ENOENT : 0; | |
547 | } | |
548 | ||
549 | /* | |
550 | * allocating a SA for policy entry from SAD. | |
551 | * NOTE: searching SAD of aliving state. | |
552 | * OUT: NULL: not found. | |
553 | * others: found and return the pointer. | |
554 | */ | |
555 | static struct secasvar * | |
556 | key_allocsa_policy(saidx) | |
557 | struct secasindex *saidx; | |
558 | { | |
559 | struct secashead *sah; | |
560 | struct secasvar *sav; | |
561 | u_int stateidx, state; | |
562 | ||
563 | LIST_FOREACH(sah, &sahtree, chain) { | |
564 | if (sah->state == SADB_SASTATE_DEAD) | |
565 | continue; | |
566 | if (key_cmpsaidx_withmode(&sah->saidx, saidx)) | |
567 | goto found; | |
568 | } | |
569 | ||
570 | return NULL; | |
571 | ||
572 | found: | |
573 | ||
574 | /* search valid state */ | |
575 | for (stateidx = 0; | |
576 | stateidx < _ARRAYLEN(saorder_state_valid); | |
577 | stateidx++) { | |
578 | ||
579 | state = saorder_state_valid[stateidx]; | |
580 | ||
581 | sav = key_do_allocsa_policy(sah, state); | |
582 | if (sav != NULL) | |
583 | return sav; | |
584 | } | |
585 | ||
586 | return NULL; | |
587 | } | |
588 | ||
589 | /* | |
590 | * searching SAD with direction, protocol, mode and state. | |
591 | * called by key_allocsa_policy(). | |
592 | * OUT: | |
593 | * NULL : not found | |
594 | * others : found, pointer to a SA. | |
595 | */ | |
596 | static struct secasvar * | |
597 | key_do_allocsa_policy(sah, state) | |
598 | struct secashead *sah; | |
599 | u_int state; | |
600 | { | |
601 | struct secasvar *sav, *candidate; | |
602 | ||
603 | /* initilize */ | |
604 | candidate = NULL; | |
605 | ||
606 | LIST_FOREACH(sav, &sah->savtree[state], chain) { | |
607 | ||
608 | /* sanity check */ | |
609 | KEY_CHKSASTATE(sav->state, state, "key_do_allocsa_policy"); | |
610 | ||
611 | /* initialize */ | |
612 | if (candidate == NULL) { | |
613 | candidate = sav; | |
614 | continue; | |
615 | } | |
616 | ||
617 | /* Which SA is the better ? */ | |
618 | ||
619 | /* sanity check 2 */ | |
620 | if (candidate->lft_c == NULL || sav->lft_c == NULL) | |
621 | panic("key_do_allocsa_policy: " | |
622 | "lifetime_current is NULL.\n"); | |
623 | ||
624 | /* XXX What the best method is to compare ? */ | |
625 | if (candidate->lft_c->sadb_lifetime_addtime > | |
626 | sav->lft_c->sadb_lifetime_addtime) { | |
627 | candidate = sav; | |
628 | continue; | |
629 | } | |
630 | } | |
631 | ||
632 | if (candidate) { | |
633 | candidate->refcnt++; | |
634 | KEYDEBUG(KEYDEBUG_IPSEC_STAMP, | |
635 | printf("DP allocsa_policy cause " | |
636 | "refcnt++:%d SA:%p\n", | |
637 | candidate->refcnt, candidate)); | |
638 | } | |
639 | return candidate; | |
640 | } | |
641 | ||
642 | /* | |
643 | * allocating a SA entry for a *INBOUND* packet. | |
644 | * Must call key_freesav() later. | |
645 | * OUT: positive: pointer to a sav. | |
646 | * NULL: not found, or error occured. | |
647 | * | |
648 | * In the comparison, source address will be ignored for RFC2401 conformance. | |
649 | * To quote, from section 4.1: | |
650 | * A security association is uniquely identified by a triple consisting | |
651 | * of a Security Parameter Index (SPI), an IP Destination Address, and a | |
652 | * security protocol (AH or ESP) identifier. | |
653 | * Note that, however, we do need to keep source address in IPsec SA. | |
654 | * IPsec SA. IKE specification and PF_KEY specification do assume that we | |
655 | * keep source address in IPsec SA. We see a tricky situation here. | |
656 | */ | |
657 | struct secasvar * | |
658 | key_allocsa(family, src, dst, proto, spi) | |
659 | u_int family, proto; | |
660 | caddr_t src, dst; | |
661 | u_int32_t spi; | |
662 | { | |
663 | struct secashead *sah; | |
664 | struct secasvar *sav; | |
665 | u_int stateidx, state; | |
666 | int s; | |
667 | ||
668 | /* sanity check */ | |
669 | if (src == NULL || dst == NULL) | |
670 | panic("key_allocsa: NULL pointer is passed.\n"); | |
671 | ||
672 | /* | |
673 | * searching SAD. | |
674 | * XXX: to be checked internal IP header somewhere. Also when | |
675 | * IPsec tunnel packet is received. But ESP tunnel mode is | |
676 | * encrypted so we can't check internal IP header. | |
677 | */ | |
678 | #ifdef __NetBSD__ | |
679 | s = splsoftnet(); /*called from softclock()*/ | |
680 | #else | |
681 | s = splnet(); /*called from softclock()*/ | |
682 | #endif | |
683 | LIST_FOREACH(sah, &sahtree, chain) { | |
684 | ||
685 | /* search valid state */ | |
686 | for (stateidx = 0; | |
687 | stateidx < _ARRAYLEN(saorder_state_valid); | |
688 | stateidx++) { | |
689 | ||
690 | state = saorder_state_valid[stateidx]; | |
691 | LIST_FOREACH(sav, &sah->savtree[state], chain) { | |
692 | ||
693 | /* sanity check */ | |
694 | KEY_CHKSASTATE(sav->state, state, "key_allocsav"); | |
695 | if (proto != sav->sah->saidx.proto) | |
696 | continue; | |
697 | if (spi != sav->spi) | |
698 | continue; | |
699 | ||
700 | #if 0 /* don't check src */ | |
701 | if (!key_bbcmp(src, | |
702 | _INADDRBYSA(&sav->sah->saidx.src), | |
703 | _INALENBYAF(sav->sah->saidx.src.ss_family) << 3)) | |
704 | continue; | |
705 | #endif | |
706 | if (!key_bbcmp(dst, | |
707 | _INADDRBYSA(&sav->sah->saidx.dst), | |
708 | _INALENBYAF(sav->sah->saidx.dst.ss_family) << 3)) | |
709 | continue; | |
710 | ||
711 | goto found; | |
712 | } | |
713 | } | |
714 | } | |
715 | ||
716 | /* not found */ | |
717 | splx(s); | |
718 | return NULL; | |
719 | ||
720 | found: | |
721 | sav->refcnt++; | |
722 | splx(s); | |
723 | KEYDEBUG(KEYDEBUG_IPSEC_STAMP, | |
724 | printf("DP allocsa cause refcnt++:%d SA:%p\n", | |
725 | sav->refcnt, sav)); | |
726 | return sav; | |
727 | } | |
728 | ||
729 | /* | |
730 | * Must be called after calling key_allocsp(). | |
731 | * For both the packet without socket and key_freeso(). | |
732 | */ | |
733 | void | |
734 | key_freesp(sp) | |
735 | struct secpolicy *sp; | |
736 | { | |
737 | /* sanity check */ | |
738 | if (sp == NULL) | |
739 | panic("key_freesp: NULL pointer is passed.\n"); | |
740 | ||
741 | sp->refcnt--; | |
742 | KEYDEBUG(KEYDEBUG_IPSEC_STAMP, | |
743 | printf("DP freesp cause refcnt--:%d SP:%p\n", | |
744 | sp->refcnt, sp)); | |
745 | ||
746 | if (sp->refcnt == 0) | |
747 | key_delsp(sp); | |
748 | ||
749 | return; | |
750 | } | |
751 | ||
752 | /* | |
753 | * Must be called after calling key_allocsp(). | |
754 | * For the packet with socket. | |
755 | */ | |
756 | void | |
757 | key_freeso(so) | |
758 | struct socket *so; | |
759 | { | |
760 | /* sanity check */ | |
761 | if (so == NULL) | |
762 | panic("key_freeso: NULL pointer is passed.\n"); | |
763 | ||
764 | switch (so->so_proto->pr_domain->dom_family) { | |
765 | #if INET | |
766 | case PF_INET: | |
767 | { | |
768 | struct inpcb *pcb = sotoinpcb(so); | |
769 | ||
770 | /* Does it have a PCB ? */ | |
771 | if (pcb == NULL) | |
772 | return; | |
773 | key_freesp_so(&pcb->inp_sp->sp_in); | |
774 | key_freesp_so(&pcb->inp_sp->sp_out); | |
775 | } | |
776 | break; | |
777 | #endif | |
778 | #if INET6 | |
779 | case PF_INET6: | |
780 | { | |
781 | #if HAVE_NRL_INPCB | |
782 | struct inpcb *pcb = sotoinpcb(so); | |
783 | ||
784 | /* Does it have a PCB ? */ | |
785 | if (pcb == NULL) | |
786 | return; | |
787 | key_freesp_so(&pcb->inp_sp->sp_in); | |
788 | key_freesp_so(&pcb->inp_sp->sp_out); | |
789 | #else | |
790 | struct in6pcb *pcb = sotoin6pcb(so); | |
791 | ||
792 | /* Does it have a PCB ? */ | |
793 | if (pcb == NULL) | |
794 | return; | |
795 | key_freesp_so(&pcb->in6p_sp->sp_in); | |
796 | key_freesp_so(&pcb->in6p_sp->sp_out); | |
797 | #endif | |
798 | } | |
799 | break; | |
800 | #endif /* INET6 */ | |
801 | default: | |
802 | #if IPSEC_DEBUG | |
803 | printf("key_freeso: unknown address family=%d.\n", | |
804 | so->so_proto->pr_domain->dom_family); | |
805 | #endif | |
806 | return; | |
807 | } | |
808 | ||
809 | return; | |
810 | } | |
811 | ||
812 | static void | |
813 | key_freesp_so(sp) | |
814 | struct secpolicy **sp; | |
815 | { | |
816 | /* sanity check */ | |
817 | if (sp == NULL || *sp == NULL) | |
818 | panic("key_freesp_so: sp == NULL\n"); | |
819 | ||
820 | switch ((*sp)->policy) { | |
821 | case IPSEC_POLICY_IPSEC: | |
822 | KEYDEBUG(KEYDEBUG_IPSEC_STAMP, | |
823 | printf("DP freeso calls free SP:%p\n", *sp)); | |
824 | key_freesp(*sp); | |
825 | *sp = NULL; | |
826 | break; | |
827 | case IPSEC_POLICY_ENTRUST: | |
828 | case IPSEC_POLICY_BYPASS: | |
829 | return; | |
830 | default: | |
831 | panic("key_freesp_so: Invalid policy found %d", (*sp)->policy); | |
832 | } | |
833 | ||
834 | return; | |
835 | } | |
836 | ||
837 | /* | |
838 | * Must be called after calling key_allocsa(). | |
839 | * This function is called by key_freesp() to free some SA allocated | |
840 | * for a policy. | |
841 | */ | |
842 | void | |
843 | key_freesav(sav) | |
844 | struct secasvar *sav; | |
845 | { | |
846 | /* sanity check */ | |
847 | if (sav == NULL) | |
848 | panic("key_freesav: NULL pointer is passed.\n"); | |
849 | ||
850 | sav->refcnt--; | |
851 | KEYDEBUG(KEYDEBUG_IPSEC_STAMP, | |
852 | printf("DP freesav cause refcnt--:%d SA:%p SPI %d\n", | |
853 | sav->refcnt, sav, (u_int32_t)ntohl(sav->spi))); | |
854 | ||
855 | if (sav->refcnt == 0) | |
856 | key_delsav(sav); | |
857 | ||
858 | return; | |
859 | } | |
860 | ||
861 | /* %%% SPD management */ | |
862 | /* | |
863 | * free security policy entry. | |
864 | */ | |
865 | static void | |
866 | key_delsp(sp) | |
867 | struct secpolicy *sp; | |
868 | { | |
869 | int s; | |
870 | ||
871 | /* sanity check */ | |
872 | if (sp == NULL) | |
873 | panic("key_delsp: NULL pointer is passed.\n"); | |
874 | ||
875 | sp->state = IPSEC_SPSTATE_DEAD; | |
876 | ||
877 | if (sp->refcnt > 0) | |
878 | return; /* can't free */ | |
879 | ||
880 | #if __NetBSD__ | |
881 | s = splsoftnet(); /*called from softclock()*/ | |
882 | #else | |
883 | s = splnet(); /*called from softclock()*/ | |
884 | #endif | |
885 | /* remove from SP index */ | |
886 | if (__LIST_CHAINED(sp)) | |
887 | LIST_REMOVE(sp, chain); | |
888 | ||
889 | { | |
890 | struct ipsecrequest *isr = sp->req, *nextisr; | |
891 | ||
892 | while (isr != NULL) { | |
893 | if (isr->sav != NULL) { | |
894 | KEYDEBUG(KEYDEBUG_IPSEC_STAMP, | |
895 | printf("DP delsp calls free SA:%p\n", | |
896 | isr->sav)); | |
897 | key_freesav(isr->sav); | |
898 | isr->sav = NULL; | |
899 | } | |
900 | ||
901 | nextisr = isr->next; | |
902 | KFREE(isr); | |
903 | isr = nextisr; | |
904 | } | |
905 | } | |
906 | ||
907 | keydb_delsecpolicy(sp); | |
908 | ||
909 | splx(s); | |
910 | ||
911 | return; | |
912 | } | |
913 | ||
914 | /* | |
915 | * search SPD | |
916 | * OUT: NULL : not found | |
917 | * others : found, pointer to a SP. | |
918 | */ | |
919 | static struct secpolicy * | |
920 | key_getsp(spidx) | |
921 | struct secpolicyindex *spidx; | |
922 | { | |
923 | struct secpolicy *sp; | |
924 | ||
925 | /* sanity check */ | |
926 | if (spidx == NULL) | |
927 | panic("key_getsp: NULL pointer is passed.\n"); | |
928 | ||
929 | LIST_FOREACH(sp, &sptree[spidx->dir], chain) { | |
930 | if (sp->state == IPSEC_SPSTATE_DEAD) | |
931 | continue; | |
932 | if (key_cmpspidx_exactly(spidx, &sp->spidx)) { | |
933 | sp->refcnt++; | |
934 | return sp; | |
935 | } | |
936 | } | |
937 | ||
938 | return NULL; | |
939 | } | |
940 | ||
941 | /* | |
942 | * get SP by index. | |
943 | * OUT: NULL : not found | |
944 | * others : found, pointer to a SP. | |
945 | */ | |
946 | static struct secpolicy * | |
947 | key_getspbyid(id) | |
948 | u_int32_t id; | |
949 | { | |
950 | struct secpolicy *sp; | |
951 | ||
952 | LIST_FOREACH(sp, &sptree[IPSEC_DIR_INBOUND], chain) { | |
953 | if (sp->state == IPSEC_SPSTATE_DEAD) | |
954 | continue; | |
955 | if (sp->id == id) { | |
956 | sp->refcnt++; | |
957 | return sp; | |
958 | } | |
959 | } | |
960 | ||
961 | LIST_FOREACH(sp, &sptree[IPSEC_DIR_OUTBOUND], chain) { | |
962 | if (sp->state == IPSEC_SPSTATE_DEAD) | |
963 | continue; | |
964 | if (sp->id == id) { | |
965 | sp->refcnt++; | |
966 | return sp; | |
967 | } | |
968 | } | |
969 | ||
970 | return NULL; | |
971 | } | |
972 | ||
973 | struct secpolicy * | |
974 | key_newsp() | |
975 | { | |
976 | struct secpolicy *newsp = NULL; | |
977 | ||
978 | newsp = keydb_newsecpolicy(); | |
979 | if (!newsp) | |
980 | return newsp; | |
981 | ||
982 | newsp->refcnt = 1; | |
983 | newsp->req = NULL; | |
984 | ||
985 | return newsp; | |
986 | } | |
987 | ||
988 | /* | |
989 | * create secpolicy structure from sadb_x_policy structure. | |
990 | * NOTE: `state', `secpolicyindex' in secpolicy structure are not set, | |
991 | * so must be set properly later. | |
992 | */ | |
993 | struct secpolicy * | |
994 | key_msg2sp(xpl0, len, error) | |
995 | struct sadb_x_policy *xpl0; | |
996 | size_t len; | |
997 | int *error; | |
998 | { | |
999 | struct secpolicy *newsp; | |
1000 | ||
1001 | /* sanity check */ | |
1002 | if (xpl0 == NULL) | |
1003 | panic("key_msg2sp: NULL pointer was passed.\n"); | |
1004 | if (len < sizeof(*xpl0)) | |
1005 | panic("key_msg2sp: invalid length.\n"); | |
1006 | if (len != PFKEY_EXTLEN(xpl0)) { | |
1007 | #if IPSEC_DEBUG | |
1008 | printf("key_msg2sp: Invalid msg length.\n"); | |
1009 | #endif | |
1010 | *error = EINVAL; | |
1011 | return NULL; | |
1012 | } | |
1013 | ||
1014 | if ((newsp = key_newsp()) == NULL) { | |
1015 | *error = ENOBUFS; | |
1016 | return NULL; | |
1017 | } | |
1018 | ||
1019 | newsp->spidx.dir = xpl0->sadb_x_policy_dir; | |
1020 | newsp->policy = xpl0->sadb_x_policy_type; | |
1021 | ||
1022 | /* check policy */ | |
1023 | switch (xpl0->sadb_x_policy_type) { | |
1024 | case IPSEC_POLICY_DISCARD: | |
1025 | case IPSEC_POLICY_NONE: | |
1026 | case IPSEC_POLICY_ENTRUST: | |
1027 | case IPSEC_POLICY_BYPASS: | |
1028 | newsp->req = NULL; | |
1029 | break; | |
1030 | ||
1031 | case IPSEC_POLICY_IPSEC: | |
1032 | { | |
1033 | int tlen; | |
1034 | struct sadb_x_ipsecrequest *xisr; | |
1035 | struct ipsecrequest **p_isr = &newsp->req; | |
1036 | ||
1037 | /* validity check */ | |
1038 | if (PFKEY_EXTLEN(xpl0) < sizeof(*xpl0)) { | |
1039 | #if IPSEC_DEBUG | |
1040 | printf("key_msg2sp: Invalid msg length.\n"); | |
1041 | #endif | |
1042 | key_freesp(newsp); | |
1043 | *error = EINVAL; | |
1044 | return NULL; | |
1045 | } | |
1046 | ||
1047 | tlen = PFKEY_EXTLEN(xpl0) - sizeof(*xpl0); | |
1048 | xisr = (struct sadb_x_ipsecrequest *)(xpl0 + 1); | |
1049 | ||
1050 | while (tlen > 0) { | |
1051 | ||
1052 | /* length check */ | |
1053 | if (xisr->sadb_x_ipsecrequest_len < sizeof(*xisr)) { | |
1054 | #if IPSEC_DEBUG | |
1055 | printf("key_msg2sp: " | |
1056 | "invalid ipsecrequest length.\n"); | |
1057 | #endif | |
1058 | key_freesp(newsp); | |
1059 | *error = EINVAL; | |
1060 | return NULL; | |
1061 | } | |
1062 | ||
1063 | /* allocate request buffer */ | |
1064 | KMALLOC(*p_isr, struct ipsecrequest *, sizeof(**p_isr)); | |
1065 | if ((*p_isr) == NULL) { | |
1066 | #if IPSEC_DEBUG | |
1067 | printf("key_msg2sp: No more memory.\n"); | |
1068 | #endif | |
1069 | key_freesp(newsp); | |
1070 | *error = ENOBUFS; | |
1071 | return NULL; | |
1072 | } | |
1073 | bzero(*p_isr, sizeof(**p_isr)); | |
1074 | ||
1075 | /* set values */ | |
1076 | (*p_isr)->next = NULL; | |
1077 | ||
1078 | switch (xisr->sadb_x_ipsecrequest_proto) { | |
1079 | case IPPROTO_ESP: | |
1080 | case IPPROTO_AH: | |
1081 | #if 1 /*nonstandard*/ | |
1082 | case IPPROTO_IPCOMP: | |
1083 | #endif | |
1084 | break; | |
1085 | default: | |
1086 | #if IPSEC_DEBUG | |
1087 | printf("key_msg2sp: invalid proto type=%u\n", | |
1088 | xisr->sadb_x_ipsecrequest_proto); | |
1089 | #endif | |
1090 | key_freesp(newsp); | |
1091 | *error = EPROTONOSUPPORT; | |
1092 | return NULL; | |
1093 | } | |
1094 | (*p_isr)->saidx.proto = xisr->sadb_x_ipsecrequest_proto; | |
1095 | ||
1096 | switch (xisr->sadb_x_ipsecrequest_mode) { | |
1097 | case IPSEC_MODE_TRANSPORT: | |
1098 | case IPSEC_MODE_TUNNEL: | |
1099 | break; | |
1100 | case IPSEC_MODE_ANY: | |
1101 | default: | |
1102 | #if IPSEC_DEBUG | |
1103 | printf("key_msg2sp: invalid mode=%u\n", | |
1104 | xisr->sadb_x_ipsecrequest_mode); | |
1105 | #endif | |
1106 | key_freesp(newsp); | |
1107 | *error = EINVAL; | |
1108 | return NULL; | |
1109 | } | |
1110 | (*p_isr)->saidx.mode = xisr->sadb_x_ipsecrequest_mode; | |
1111 | ||
1112 | switch (xisr->sadb_x_ipsecrequest_level) { | |
1113 | case IPSEC_LEVEL_DEFAULT: | |
1114 | case IPSEC_LEVEL_USE: | |
1115 | case IPSEC_LEVEL_REQUIRE: | |
1116 | break; | |
1117 | case IPSEC_LEVEL_UNIQUE: | |
1118 | /* validity check */ | |
1119 | /* | |
1120 | * If range violation of reqid, kernel will | |
1121 | * update it, don't refuse it. | |
1122 | */ | |
1123 | if (xisr->sadb_x_ipsecrequest_reqid | |
1124 | > IPSEC_MANUAL_REQID_MAX) { | |
1125 | #if IPSEC_DEBUG | |
1126 | printf("key_msg2sp: reqid=%d " | |
1127 | "range violation, " | |
1128 | "updated by kernel.\n", | |
1129 | xisr->sadb_x_ipsecrequest_reqid); | |
1130 | #endif | |
1131 | xisr->sadb_x_ipsecrequest_reqid = 0; | |
1132 | } | |
1133 | ||
1134 | /* allocate new reqid id if reqid is zero. */ | |
1135 | if (xisr->sadb_x_ipsecrequest_reqid == 0) { | |
1136 | u_int32_t reqid; | |
1137 | if ((reqid = key_newreqid()) == 0) { | |
1138 | key_freesp(newsp); | |
1139 | *error = ENOBUFS; | |
1140 | return NULL; | |
1141 | } | |
1142 | (*p_isr)->saidx.reqid = reqid; | |
1143 | xisr->sadb_x_ipsecrequest_reqid = reqid; | |
1144 | } else { | |
1145 | /* set it for manual keying. */ | |
1146 | (*p_isr)->saidx.reqid = | |
1147 | xisr->sadb_x_ipsecrequest_reqid; | |
1148 | } | |
1149 | break; | |
1150 | ||
1151 | default: | |
1152 | #if IPSEC_DEBUG | |
1153 | printf("key_msg2sp: invalid level=%u\n", | |
1154 | xisr->sadb_x_ipsecrequest_level); | |
1155 | #endif | |
1156 | key_freesp(newsp); | |
1157 | *error = EINVAL; | |
1158 | return NULL; | |
1159 | } | |
1160 | (*p_isr)->level = xisr->sadb_x_ipsecrequest_level; | |
1161 | ||
1162 | /* set IP addresses if there */ | |
1163 | if (xisr->sadb_x_ipsecrequest_len > sizeof(*xisr)) { | |
1164 | struct sockaddr *paddr; | |
1165 | ||
1166 | paddr = (struct sockaddr *)(xisr + 1); | |
1167 | ||
1168 | /* validity check */ | |
1169 | if (paddr->sa_len | |
1170 | > sizeof((*p_isr)->saidx.src)) { | |
1171 | #if IPSEC_DEBUG | |
1172 | printf("key_msg2sp: invalid request " | |
1173 | "address length.\n"); | |
1174 | #endif | |
1175 | key_freesp(newsp); | |
1176 | *error = EINVAL; | |
1177 | return NULL; | |
1178 | } | |
1179 | bcopy(paddr, &(*p_isr)->saidx.src, | |
1180 | paddr->sa_len); | |
1181 | ||
1182 | paddr = (struct sockaddr *)((caddr_t)paddr | |
1183 | + paddr->sa_len); | |
1184 | ||
1185 | /* validity check */ | |
1186 | if (paddr->sa_len | |
1187 | > sizeof((*p_isr)->saidx.dst)) { | |
1188 | #if IPSEC_DEBUG | |
1189 | printf("key_msg2sp: invalid request " | |
1190 | "address length.\n"); | |
1191 | #endif | |
1192 | key_freesp(newsp); | |
1193 | *error = EINVAL; | |
1194 | return NULL; | |
1195 | } | |
1196 | bcopy(paddr, &(*p_isr)->saidx.dst, | |
1197 | paddr->sa_len); | |
1198 | } | |
1199 | ||
1200 | (*p_isr)->sav = NULL; | |
1201 | (*p_isr)->sp = newsp; | |
1202 | ||
1203 | /* initialization for the next. */ | |
1204 | p_isr = &(*p_isr)->next; | |
1205 | tlen -= xisr->sadb_x_ipsecrequest_len; | |
1206 | ||
1207 | /* validity check */ | |
1208 | if (tlen < 0) { | |
1209 | #if IPSEC_DEBUG | |
1210 | printf("key_msg2sp: becoming tlen < 0.\n"); | |
1211 | #endif | |
1212 | key_freesp(newsp); | |
1213 | *error = EINVAL; | |
1214 | return NULL; | |
1215 | } | |
1216 | ||
1217 | xisr = (struct sadb_x_ipsecrequest *)((caddr_t)xisr | |
1218 | + xisr->sadb_x_ipsecrequest_len); | |
1219 | } | |
1220 | } | |
1221 | break; | |
1222 | default: | |
1223 | #if IPSEC_DEBUG | |
1224 | printf("key_msg2sp: invalid policy type.\n"); | |
1225 | #endif | |
1226 | key_freesp(newsp); | |
1227 | *error = EINVAL; | |
1228 | return NULL; | |
1229 | } | |
1230 | ||
1231 | *error = 0; | |
1232 | return newsp; | |
1233 | } | |
1234 | ||
1235 | static u_int32_t | |
1236 | key_newreqid() | |
1237 | { | |
1238 | static u_int32_t auto_reqid = IPSEC_MANUAL_REQID_MAX + 1; | |
1239 | ||
1240 | auto_reqid = (auto_reqid == ~0 | |
1241 | ? IPSEC_MANUAL_REQID_MAX + 1 : auto_reqid + 1); | |
1242 | ||
1243 | /* XXX should be unique check */ | |
1244 | ||
1245 | return auto_reqid; | |
1246 | } | |
1247 | ||
1248 | /* | |
1249 | * copy secpolicy struct to sadb_x_policy structure indicated. | |
1250 | */ | |
1251 | struct mbuf * | |
1252 | key_sp2msg(sp) | |
1253 | struct secpolicy *sp; | |
1254 | { | |
1255 | struct sadb_x_policy *xpl; | |
1256 | int tlen; | |
1257 | caddr_t p; | |
1258 | struct mbuf *m; | |
1259 | ||
1260 | /* sanity check. */ | |
1261 | if (sp == NULL) | |
1262 | panic("key_sp2msg: NULL pointer was passed.\n"); | |
1263 | ||
1264 | tlen = key_getspreqmsglen(sp); | |
1265 | ||
1266 | MGET(m, M_DONTWAIT, MT_DATA); | |
1267 | if (m && MLEN < tlen) { | |
1268 | MCLGET(m, M_DONTWAIT); | |
1269 | if ((m->m_flags & M_EXT) == 0) { | |
1270 | m_free(m); | |
1271 | m = NULL; | |
1272 | } | |
1273 | } | |
1274 | m->m_len = 0; | |
1275 | if (!m || M_TRAILINGSPACE(m) < tlen) { | |
1276 | #if IPSEC_DEBUG | |
1277 | printf("key_sp2msg: No more memory.\n"); | |
1278 | #endif | |
1279 | if (m) | |
1280 | m_free(m); | |
1281 | return NULL; | |
1282 | } | |
1283 | ||
1284 | m->m_len = tlen; | |
1285 | m->m_next = NULL; | |
1286 | xpl = mtod(m, struct sadb_x_policy *); | |
1287 | bzero(xpl, tlen); | |
1288 | ||
1289 | xpl->sadb_x_policy_len = PFKEY_UNIT64(tlen); | |
1290 | xpl->sadb_x_policy_exttype = SADB_X_EXT_POLICY; | |
1291 | xpl->sadb_x_policy_type = sp->policy; | |
1292 | xpl->sadb_x_policy_dir = sp->spidx.dir; | |
1293 | xpl->sadb_x_policy_id = sp->id; | |
1294 | p = (caddr_t)xpl + sizeof(*xpl); | |
1295 | ||
1296 | /* if is the policy for ipsec ? */ | |
1297 | if (sp->policy == IPSEC_POLICY_IPSEC) { | |
1298 | struct sadb_x_ipsecrequest *xisr; | |
1299 | struct ipsecrequest *isr; | |
1300 | ||
1301 | for (isr = sp->req; isr != NULL; isr = isr->next) { | |
1302 | ||
1303 | xisr = (struct sadb_x_ipsecrequest *)p; | |
1304 | ||
1305 | xisr->sadb_x_ipsecrequest_proto = isr->saidx.proto; | |
1306 | xisr->sadb_x_ipsecrequest_mode = isr->saidx.mode; | |
1307 | xisr->sadb_x_ipsecrequest_level = isr->level; | |
1308 | xisr->sadb_x_ipsecrequest_reqid = isr->saidx.reqid; | |
1309 | ||
1310 | p += sizeof(*xisr); | |
1311 | bcopy(&isr->saidx.src, p, isr->saidx.src.ss_len); | |
1312 | p += isr->saidx.src.ss_len; | |
1313 | bcopy(&isr->saidx.dst, p, isr->saidx.dst.ss_len); | |
1314 | p += isr->saidx.src.ss_len; | |
1315 | ||
1316 | xisr->sadb_x_ipsecrequest_len = | |
1317 | PFKEY_ALIGN8(sizeof(*xisr) | |
1318 | + isr->saidx.src.ss_len | |
1319 | + isr->saidx.dst.ss_len); | |
1320 | } | |
1321 | } | |
1322 | ||
1323 | return m; | |
1324 | } | |
1325 | ||
1326 | /* | |
1327 | * SADB_X_SPDADD, SADB_X_SPDSETIDX or SADB_X_SPDUPDATE processing | |
1328 | * add a entry to SP database, when received | |
1329 | * <base, address(SD), policy> | |
1330 | * from the user(?). | |
1331 | * Adding to SP database, | |
1332 | * and send | |
1333 | * <base, address(SD), policy> | |
1334 | * to the socket which was send. | |
1335 | * | |
1336 | * SPDADD set a unique policy entry. | |
1337 | * SPDSETIDX like SPDADD without a part of policy requests. | |
1338 | * SPDUPDATE replace a unique policy entry. | |
1339 | * | |
1340 | * IN: mhp: pointer to the pointer to each header. | |
1341 | * OUT: NULL if fail. | |
1342 | * other if success, return pointer to the message to send. | |
1343 | * | |
1344 | */ | |
1345 | static struct sadb_msg * | |
1346 | key_spdadd(mhp) | |
1347 | caddr_t *mhp; | |
1348 | { | |
1349 | struct sadb_msg *msg0; | |
1350 | struct sadb_address *src0, *dst0; | |
1351 | struct sadb_x_policy *xpl0; | |
1352 | struct secpolicyindex spidx; | |
1353 | struct secpolicy *newsp; | |
1354 | int error; | |
1355 | ||
1356 | /* sanity check */ | |
1357 | if (mhp == NULL || mhp[0] == NULL) | |
1358 | panic("key_spdadd: NULL pointer is passed.\n"); | |
1359 | ||
1360 | msg0 = (struct sadb_msg *)mhp[0]; | |
1361 | ||
1362 | if (mhp[SADB_EXT_ADDRESS_SRC] == NULL | |
1363 | || mhp[SADB_EXT_ADDRESS_DST] == NULL | |
1364 | || mhp[SADB_X_EXT_POLICY] == NULL) { | |
1365 | #if IPSEC_DEBUG | |
1366 | printf("key_spdadd: invalid message is passed.\n"); | |
1367 | #endif | |
1368 | msg0->sadb_msg_errno = EINVAL; | |
1369 | return NULL; | |
1370 | } | |
1371 | ||
1372 | src0 = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC]; | |
1373 | dst0 = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST]; | |
1374 | xpl0 = (struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY]; | |
1375 | ||
1376 | /* make secindex */ | |
1377 | KEY_SETSECSPIDX(xpl0->sadb_x_policy_dir, | |
1378 | src0 + 1, | |
1379 | dst0 + 1, | |
1380 | src0->sadb_address_prefixlen, | |
1381 | dst0->sadb_address_prefixlen, | |
1382 | src0->sadb_address_proto, | |
1383 | &spidx); | |
1384 | ||
1385 | /* checking the direciton. */ | |
1386 | switch (xpl0->sadb_x_policy_dir) { | |
1387 | case IPSEC_DIR_INBOUND: | |
1388 | case IPSEC_DIR_OUTBOUND: | |
1389 | break; | |
1390 | default: | |
1391 | #if IPSEC_DEBUG | |
1392 | printf("key_spdadd: Invalid SP direction.\n"); | |
1393 | #endif | |
1394 | msg0->sadb_msg_errno = EINVAL; | |
1395 | return NULL; | |
1396 | } | |
1397 | ||
1398 | /* check policy */ | |
1399 | /* key_spdadd() accepts DISCARD, NONE and IPSEC. */ | |
1400 | if (xpl0->sadb_x_policy_type == IPSEC_POLICY_ENTRUST | |
1401 | || xpl0->sadb_x_policy_type == IPSEC_POLICY_BYPASS) { | |
1402 | #if IPSEC_DEBUG | |
1403 | printf("key_spdadd: Invalid policy type.\n"); | |
1404 | #endif | |
1405 | msg0->sadb_msg_errno = EINVAL; | |
1406 | return NULL; | |
1407 | } | |
1408 | ||
1409 | /* policy requests are mandatory when action is ipsec. */ | |
1410 | if (msg0->sadb_msg_type != SADB_X_SPDSETIDX | |
1411 | && xpl0->sadb_x_policy_type == IPSEC_POLICY_IPSEC | |
1412 | && PFKEY_EXTLEN(xpl0) <= sizeof(*xpl0)) { | |
1413 | #if IPSEC_DEBUG | |
1414 | printf("key_spdadd: some policy requests part required.\n"); | |
1415 | #endif | |
1416 | msg0->sadb_msg_errno = EINVAL; | |
1417 | return NULL; | |
1418 | } | |
1419 | ||
1420 | /* | |
1421 | * checking there is SP already or not. | |
1422 | * If type is SPDUPDATE and no SP found, then error. | |
1423 | * If type is either SPDADD or SPDSETIDX and SP found, then error. | |
1424 | */ | |
1425 | newsp = key_getsp(&spidx); | |
1426 | if (msg0->sadb_msg_type == SADB_X_SPDUPDATE) { | |
1427 | if (newsp == NULL) { | |
1428 | #if IPSEC_DEBUG | |
1429 | printf("key_spdadd: no SP found.\n"); | |
1430 | #endif | |
1431 | msg0->sadb_msg_errno = ENOENT; | |
1432 | return NULL; | |
1433 | } | |
1434 | ||
1435 | newsp->state = IPSEC_SPSTATE_DEAD; | |
1436 | key_freesp(newsp); | |
1437 | } else { | |
1438 | if (newsp != NULL) { | |
1439 | key_freesp(newsp); | |
1440 | #if IPSEC_DEBUG | |
1441 | printf("key_spdadd: a SP entry exists already.\n"); | |
1442 | #endif | |
1443 | msg0->sadb_msg_errno = EEXIST; | |
1444 | return NULL; | |
1445 | } | |
1446 | } | |
1447 | ||
1448 | /* allocation new SP entry */ | |
1449 | if ((newsp = key_msg2sp(xpl0, PFKEY_EXTLEN(xpl0), &error)) == NULL) { | |
1450 | msg0->sadb_msg_errno = error; | |
1451 | return NULL; | |
1452 | } | |
1453 | ||
1454 | if ((newsp->id = key_getnewspid()) == 0) { | |
1455 | msg0->sadb_msg_errno = ENOBUFS; | |
1456 | keydb_delsecpolicy(newsp); | |
1457 | return NULL; | |
1458 | } | |
1459 | ||
1460 | KEY_SETSECSPIDX(xpl0->sadb_x_policy_dir, | |
1461 | src0 + 1, | |
1462 | dst0 + 1, | |
1463 | src0->sadb_address_prefixlen, | |
1464 | dst0->sadb_address_prefixlen, | |
1465 | src0->sadb_address_proto, | |
1466 | &newsp->spidx); | |
1467 | ||
1468 | /* sanity check on addr pair */ | |
1469 | if (((struct sockaddr *)(src0 + 1))->sa_family != | |
1470 | ((struct sockaddr *)(dst0+ 1))->sa_family) { | |
1471 | msg0->sadb_msg_errno = EINVAL; | |
1472 | keydb_delsecpolicy(newsp); | |
1473 | return NULL; | |
1474 | } | |
1475 | #if 1 | |
1476 | if (newsp->req && newsp->req->saidx.src.ss_family) { | |
1477 | struct sockaddr *sa; | |
1478 | sa = (struct sockaddr *)(src0 + 1); | |
1479 | if (sa->sa_family != newsp->req->saidx.src.ss_family) { | |
1480 | msg0->sadb_msg_errno = EINVAL; | |
1481 | keydb_delsecpolicy(newsp); | |
1482 | return NULL; | |
1483 | } | |
1484 | } | |
1485 | if (newsp->req && newsp->req->saidx.dst.ss_family) { | |
1486 | struct sockaddr *sa; | |
1487 | sa = (struct sockaddr *)(dst0 + 1); | |
1488 | if (sa->sa_family != newsp->req->saidx.dst.ss_family) { | |
1489 | msg0->sadb_msg_errno = EINVAL; | |
1490 | keydb_delsecpolicy(newsp); | |
1491 | return NULL; | |
1492 | } | |
1493 | } | |
1494 | #endif | |
1495 | ||
1496 | newsp->refcnt = 1; /* do not reclaim until I say I do */ | |
1497 | newsp->state = IPSEC_SPSTATE_ALIVE; | |
1498 | LIST_INSERT_HEAD(&sptree[newsp->spidx.dir], newsp, chain); | |
1499 | ||
1500 | /* delete the entry in spacqtree */ | |
1501 | if (msg0->sadb_msg_type == SADB_X_SPDUPDATE) { | |
1502 | struct secspacq *spacq; | |
1503 | if ((spacq = key_getspacq(&spidx)) != NULL) { | |
1504 | /* reset counter in order to deletion by timehander. */ | |
1505 | spacq->tick = key_blockacq_lifetime; | |
1506 | spacq->count = 0; | |
1507 | } | |
1508 | } | |
1509 | ||
1510 | { | |
1511 | struct sadb_msg *newmsg; | |
1512 | u_int len; | |
1513 | caddr_t p; | |
1514 | ||
1515 | /* create new sadb_msg to reply. */ | |
1516 | len = sizeof(struct sadb_msg) | |
1517 | + PFKEY_EXTLEN(mhp[SADB_X_EXT_POLICY]) | |
1518 | + PFKEY_EXTLEN(mhp[SADB_EXT_ADDRESS_SRC]) | |
1519 | + PFKEY_EXTLEN(mhp[SADB_EXT_ADDRESS_DST]); | |
1520 | ||
1521 | KMALLOC(newmsg, struct sadb_msg *, len); | |
1522 | if (newmsg == NULL) { | |
1523 | #if IPSEC_DEBUG | |
1524 | printf("key_spdadd: No more memory.\n"); | |
1525 | #endif | |
1526 | /* newsp persists in the kernel */ | |
1527 | msg0->sadb_msg_errno = ENOBUFS; | |
1528 | return NULL; | |
1529 | } | |
1530 | bzero((caddr_t)newmsg, len); | |
1531 | ||
1532 | bcopy((caddr_t)msg0, (caddr_t)newmsg, sizeof(*msg0)); | |
1533 | newmsg->sadb_msg_errno = 0; | |
1534 | newmsg->sadb_msg_len = PFKEY_UNIT64(len); | |
1535 | p = (caddr_t)newmsg + sizeof(*msg0); | |
1536 | ||
1537 | /* | |
1538 | * reqid may had been updated at key_msg2sp() if reqid's | |
1539 | * range violation. | |
1540 | */ | |
1541 | ((struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY])->sadb_x_policy_id = newsp->id; | |
1542 | p = key_setsadbext(p, mhp[SADB_X_EXT_POLICY]); | |
1543 | ||
1544 | p = key_setsadbext(p, mhp[SADB_EXT_ADDRESS_SRC]); | |
1545 | p = key_setsadbext(p, mhp[SADB_EXT_ADDRESS_DST]); | |
1546 | ||
1547 | return newmsg; | |
1548 | } | |
1549 | } | |
1550 | ||
1551 | /* | |
1552 | * get new policy id. | |
1553 | * OUT: | |
1554 | * 0: failure. | |
1555 | * others: success. | |
1556 | */ | |
1557 | static u_int32_t | |
1558 | key_getnewspid() | |
1559 | { | |
1560 | u_int32_t newid = 0; | |
1561 | int count = key_spi_trycnt; /* XXX */ | |
1562 | struct secpolicy *sp; | |
1563 | ||
1564 | /* when requesting to allocate spi ranged */ | |
1565 | while (count--) { | |
1566 | newid = (policy_id = (policy_id == ~0 ? 1 : ++policy_id)); | |
1567 | ||
1568 | if ((sp = key_getspbyid(newid)) == NULL) | |
1569 | break; | |
1570 | ||
1571 | key_freesp(sp); | |
1572 | } | |
1573 | ||
1574 | if (count == 0 || newid == 0) { | |
1575 | #if IPSEC_DEBUG | |
1576 | printf("key_getnewspid: to allocate policy id is failed.\n"); | |
1577 | #endif | |
1578 | return 0; | |
1579 | } | |
1580 | ||
1581 | return newid; | |
1582 | } | |
1583 | ||
1584 | /* | |
1585 | * SADB_SPDDELETE processing | |
1586 | * receive | |
1587 | * <base, address(SD), policy(*)> | |
1588 | * from the user(?), and set SADB_SASTATE_DEAD, | |
1589 | * and send, | |
1590 | * <base, address(SD), policy(*)> | |
1591 | * to the ikmpd. | |
1592 | * policy(*) including direction of policy. | |
1593 | * | |
1594 | * IN: mhp: pointer to the pointer to each header. | |
1595 | * OUT: other if success, return pointer to the message to send. | |
1596 | * 0 if fail. | |
1597 | */ | |
1598 | static struct sadb_msg * | |
1599 | key_spddelete(mhp) | |
1600 | caddr_t *mhp; | |
1601 | { | |
1602 | struct sadb_msg *msg0; | |
1603 | struct sadb_address *src0, *dst0; | |
1604 | struct sadb_x_policy *xpl0; | |
1605 | struct secpolicyindex spidx; | |
1606 | struct secpolicy *sp; | |
1607 | ||
1608 | /* sanity check */ | |
1609 | if (mhp == NULL || mhp[0] == NULL) | |
1610 | panic("key_spddelete: NULL pointer is passed.\n"); | |
1611 | ||
1612 | msg0 = (struct sadb_msg *)mhp[0]; | |
1613 | ||
1614 | if (mhp[SADB_EXT_ADDRESS_SRC] == NULL | |
1615 | || mhp[SADB_EXT_ADDRESS_DST] == NULL | |
1616 | || mhp[SADB_X_EXT_POLICY] == NULL) { | |
1617 | #if IPSEC_DEBUG | |
1618 | printf("key_spddelete: invalid message is passed.\n"); | |
1619 | #endif | |
1620 | msg0->sadb_msg_errno = EINVAL; | |
1621 | return NULL; | |
1622 | } | |
1623 | ||
1624 | src0 = (struct sadb_address *)(mhp[SADB_EXT_ADDRESS_SRC]); | |
1625 | dst0 = (struct sadb_address *)(mhp[SADB_EXT_ADDRESS_DST]); | |
1626 | xpl0 = (struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY]; | |
1627 | ||
1628 | /* make secindex */ | |
1629 | KEY_SETSECSPIDX(xpl0->sadb_x_policy_dir, | |
1630 | src0 + 1, | |
1631 | dst0 + 1, | |
1632 | src0->sadb_address_prefixlen, | |
1633 | dst0->sadb_address_prefixlen, | |
1634 | src0->sadb_address_proto, | |
1635 | &spidx); | |
1636 | ||
1637 | /* checking the direciton. */ | |
1638 | switch (xpl0->sadb_x_policy_dir) { | |
1639 | case IPSEC_DIR_INBOUND: | |
1640 | case IPSEC_DIR_OUTBOUND: | |
1641 | break; | |
1642 | default: | |
1643 | #if IPSEC_DEBUG | |
1644 | printf("key_spddelete: Invalid SP direction.\n"); | |
1645 | #endif | |
1646 | msg0->sadb_msg_errno = EINVAL; | |
1647 | return NULL; | |
1648 | } | |
1649 | ||
1650 | /* Is there SP in SPD ? */ | |
1651 | if ((sp = key_getsp(&spidx)) == NULL) { | |
1652 | #if IPSEC_DEBUG | |
1653 | printf("key_spddelete: no SP found.\n"); | |
1654 | #endif | |
1655 | msg0->sadb_msg_errno = ENOENT; | |
1656 | return NULL; | |
1657 | } | |
1658 | ||
1659 | /* save policy id to buffer to be returned. */ | |
1660 | xpl0->sadb_x_policy_id = sp->id; | |
1661 | ||
1662 | sp->state = IPSEC_SPSTATE_DEAD; | |
1663 | key_freesp(sp); | |
1664 | ||
1665 | { | |
1666 | struct sadb_msg *newmsg; | |
1667 | u_int len; | |
1668 | caddr_t p; | |
1669 | ||
1670 | /* create new sadb_msg to reply. */ | |
1671 | len = sizeof(struct sadb_msg) | |
1672 | + PFKEY_EXTLEN(mhp[SADB_X_EXT_POLICY]) | |
1673 | + PFKEY_EXTLEN(mhp[SADB_EXT_ADDRESS_SRC]) | |
1674 | + PFKEY_EXTLEN(mhp[SADB_EXT_ADDRESS_DST]); | |
1675 | ||
1676 | KMALLOC(newmsg, struct sadb_msg *, len); | |
1677 | if (newmsg == NULL) { | |
1678 | #if IPSEC_DEBUG | |
1679 | printf("key_spddelete: No more memory.\n"); | |
1680 | #endif | |
1681 | msg0->sadb_msg_errno = ENOBUFS; | |
1682 | return NULL; | |
1683 | } | |
1684 | bzero((caddr_t)newmsg, len); | |
1685 | ||
1686 | bcopy((caddr_t)mhp[0], (caddr_t)newmsg, sizeof(*msg0)); | |
1687 | newmsg->sadb_msg_errno = 0; | |
1688 | newmsg->sadb_msg_len = PFKEY_UNIT64(len); | |
1689 | p = (caddr_t)newmsg + sizeof(*msg0); | |
1690 | ||
1691 | p = key_setsadbext(p, mhp[SADB_X_EXT_POLICY]); | |
1692 | p = key_setsadbext(p, mhp[SADB_EXT_ADDRESS_SRC]); | |
1693 | p = key_setsadbext(p, mhp[SADB_EXT_ADDRESS_DST]); | |
1694 | ||
1695 | return newmsg; | |
1696 | } | |
1697 | } | |
1698 | ||
1699 | /* | |
1700 | * SADB_SPDDELETE2 processing | |
1701 | * receive | |
1702 | * <base, policy(*)> | |
1703 | * from the user(?), and set SADB_SASTATE_DEAD, | |
1704 | * and send, | |
1705 | * <base, policy(*)> | |
1706 | * to the ikmpd. | |
1707 | * policy(*) including direction of policy. | |
1708 | * | |
1709 | * IN: mhp: pointer to the pointer to each header. | |
1710 | * OUT: other if success, return pointer to the message to send. | |
1711 | * 0 if fail. | |
1712 | */ | |
1713 | static struct sadb_msg * | |
1714 | key_spddelete2(mhp) | |
1715 | caddr_t *mhp; | |
1716 | { | |
1717 | struct sadb_msg *msg0; | |
1718 | u_int32_t id; | |
1719 | struct secpolicy *sp; | |
1720 | ||
1721 | /* sanity check */ | |
1722 | if (mhp == NULL || mhp[0] == NULL) | |
1723 | panic("key_spddelete2: NULL pointer is passed.\n"); | |
1724 | ||
1725 | msg0 = (struct sadb_msg *)mhp[0]; | |
1726 | ||
1727 | if (mhp[SADB_X_EXT_POLICY] == NULL) { | |
1728 | #if IPSEC_DEBUG | |
1729 | printf("key_spddelete2: invalid message is passed.\n"); | |
1730 | #endif | |
1731 | msg0->sadb_msg_errno = EINVAL; | |
1732 | return NULL; | |
1733 | } | |
1734 | ||
1735 | id = ((struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY])->sadb_x_policy_id; | |
1736 | ||
1737 | /* Is there SP in SPD ? */ | |
1738 | if ((sp = key_getspbyid(id)) == NULL) { | |
1739 | #if IPSEC_DEBUG | |
1740 | printf("key_spddelete2: no SP found id:%u.\n", id); | |
1741 | #endif | |
1742 | msg0->sadb_msg_errno = ENOENT; | |
1743 | return NULL; | |
1744 | } | |
1745 | ||
1746 | sp->state = IPSEC_SPSTATE_DEAD; | |
1747 | key_freesp(sp); | |
1748 | ||
1749 | { | |
1750 | struct sadb_msg *newmsg; | |
1751 | u_int len; | |
1752 | caddr_t p; | |
1753 | ||
1754 | /* create new sadb_msg to reply. */ | |
1755 | len = sizeof(struct sadb_msg) | |
1756 | + PFKEY_EXTLEN(mhp[SADB_X_EXT_POLICY]); | |
1757 | ||
1758 | KMALLOC(newmsg, struct sadb_msg *, len); | |
1759 | if (newmsg == NULL) { | |
1760 | #if IPSEC_DEBUG | |
1761 | printf("key_spddelete2: No more memory.\n"); | |
1762 | #endif | |
1763 | msg0->sadb_msg_errno = ENOBUFS; | |
1764 | return NULL; | |
1765 | } | |
1766 | bzero((caddr_t)newmsg, len); | |
1767 | ||
1768 | bcopy((caddr_t)mhp[0], (caddr_t)newmsg, sizeof(*msg0)); | |
1769 | newmsg->sadb_msg_errno = 0; | |
1770 | newmsg->sadb_msg_len = PFKEY_UNIT64(len); | |
1771 | p = (caddr_t)newmsg + sizeof(*msg0); | |
1772 | ||
1773 | p = key_setsadbext(p, mhp[SADB_X_EXT_POLICY]); | |
1774 | ||
1775 | return newmsg; | |
1776 | } | |
1777 | } | |
1778 | ||
1779 | /* | |
1780 | * SADB_X_GET processing | |
1781 | * receive | |
1782 | * <base, policy(*)> | |
1783 | * from the user(?), | |
1784 | * and send, | |
1785 | * <base, address(SD), policy> | |
1786 | * to the ikmpd. | |
1787 | * policy(*) including direction of policy. | |
1788 | * | |
1789 | * IN: mhp: pointer to the pointer to each header. | |
1790 | * OUT: other if success, return pointer to the message to send. | |
1791 | * 0 if fail. | |
1792 | */ | |
1793 | static int | |
1794 | key_spdget(mhp, so, target) | |
1795 | caddr_t *mhp; | |
1796 | struct socket *so; | |
1797 | int target; | |
1798 | { | |
1799 | struct sadb_msg *msg0; | |
1800 | u_int32_t id; | |
1801 | struct secpolicy *sp; | |
1802 | struct mbuf *m; | |
1803 | ||
1804 | /* sanity check */ | |
1805 | if (mhp == NULL || mhp[0] == NULL) | |
1806 | panic("key_spdget: NULL pointer is passed.\n"); | |
1807 | ||
1808 | msg0 = (struct sadb_msg *)mhp[0]; | |
1809 | ||
1810 | if (mhp[SADB_X_EXT_POLICY] == NULL) { | |
1811 | #if IPSEC_DEBUG | |
1812 | printf("key_spdget: invalid message is passed.\n"); | |
1813 | #endif | |
1814 | return EINVAL; | |
1815 | } | |
1816 | ||
1817 | id = ((struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY])->sadb_x_policy_id; | |
1818 | ||
1819 | /* Is there SP in SPD ? */ | |
1820 | if ((sp = key_getspbyid(id)) == NULL) { | |
1821 | #if IPSEC_DEBUG | |
1822 | printf("key_spdget: no SP found id:%u.\n", id); | |
1823 | #endif | |
1824 | return ENOENT; | |
1825 | } | |
1826 | ||
1827 | m = key_setdumpsp(sp, SADB_X_SPDGET, 0, msg0->sadb_msg_pid); | |
1828 | if (m != NULL) | |
1829 | key_sendup_mbuf(so, m, target); | |
1830 | ||
1831 | return 0; | |
1832 | } | |
1833 | ||
1834 | /* | |
1835 | * SADB_X_SPDACQUIRE processing. | |
1836 | * Acquire policy and SA(s) for a *OUTBOUND* packet. | |
1837 | * send | |
1838 | * <base, policy(*)> | |
1839 | * to KMD, and expect to receive | |
1840 | * <base> with SADB_X_SPDACQUIRE if error occured, | |
1841 | * or | |
1842 | * <base, policy> | |
1843 | * with SADB_X_SPDUPDATE from KMD by PF_KEY. | |
1844 | * policy(*) is without policy requests. | |
1845 | * | |
1846 | * 0 : succeed | |
1847 | * others: error number | |
1848 | */ | |
1849 | int | |
1850 | key_spdacquire(sp) | |
1851 | struct secpolicy *sp; | |
1852 | { | |
1853 | struct secspacq *newspacq; | |
1854 | int error; | |
1855 | ||
1856 | /* sanity check */ | |
1857 | if (sp == NULL) | |
1858 | panic("key_spdacquire: NULL pointer is passed.\n"); | |
1859 | if (sp->req != NULL) | |
1860 | panic("key_spdacquire: called but there is request.\n"); | |
1861 | if (sp->policy != IPSEC_POLICY_IPSEC) | |
1862 | panic("key_spdacquire: policy mismathed. IPsec is expected.\n"); | |
1863 | ||
1864 | /* get a entry to check whether sent message or not. */ | |
1865 | if ((newspacq = key_getspacq(&sp->spidx)) != NULL) { | |
1866 | if (key_blockacq_count < newspacq->count) { | |
1867 | /* reset counter and do send message. */ | |
1868 | newspacq->count = 0; | |
1869 | } else { | |
1870 | /* increment counter and do nothing. */ | |
1871 | newspacq->count++; | |
1872 | return 0; | |
1873 | } | |
1874 | } else { | |
1875 | /* make new entry for blocking to send SADB_ACQUIRE. */ | |
1876 | if ((newspacq = key_newspacq(&sp->spidx)) == NULL) | |
1877 | return ENOBUFS; | |
1878 | ||
1879 | /* add to acqtree */ | |
1880 | LIST_INSERT_HEAD(&spacqtree, newspacq, chain); | |
1881 | } | |
1882 | ||
1883 | { | |
1884 | struct sadb_msg *newmsg = NULL; | |
1885 | union sadb_x_ident_id id; | |
1886 | u_int len; | |
1887 | caddr_t p; | |
1888 | ||
1889 | /* create new sadb_msg to reply. */ | |
1890 | len = sizeof(struct sadb_msg) | |
1891 | + sizeof(struct sadb_ident) | |
1892 | + PFKEY_ALIGN8(sp->spidx.src.ss_len) | |
1893 | + sizeof(struct sadb_ident) | |
1894 | + PFKEY_ALIGN8(sp->spidx.dst.ss_len); | |
1895 | ||
1896 | KMALLOC(newmsg, struct sadb_msg *, len); | |
1897 | if (newmsg == 0) { | |
1898 | #if IPSEC_DEBUG | |
1899 | printf("key_spdacquire: No more memory.\n"); | |
1900 | #endif | |
1901 | return ENOBUFS; | |
1902 | } | |
1903 | bzero((caddr_t)newmsg, len); | |
1904 | ||
1905 | newmsg->sadb_msg_version = PF_KEY_V2; | |
1906 | newmsg->sadb_msg_type = SADB_X_SPDACQUIRE; | |
1907 | newmsg->sadb_msg_errno = 0; | |
1908 | newmsg->sadb_msg_satype = 0; | |
1909 | newmsg->sadb_msg_len = PFKEY_UNIT64(len); | |
1910 | newmsg->sadb_msg_mode = 0; | |
1911 | newmsg->sadb_msg_reqid = 0; | |
1912 | newmsg->sadb_msg_seq = 0; | |
1913 | newmsg->sadb_msg_pid = 0; | |
1914 | p = (caddr_t)newmsg + sizeof(struct sadb_msg); | |
1915 | ||
1916 | /* set sadb_address for spidx's. */ | |
1917 | bzero(&id, sizeof(id)); | |
1918 | id.sadb_x_ident_id_addr.prefix = sp->spidx.prefs; | |
1919 | id.sadb_x_ident_id_addr.ul_proto = sp->spidx.ul_proto; | |
1920 | p = key_setsadbident(p, | |
1921 | SADB_EXT_IDENTITY_SRC, | |
1922 | SADB_X_IDENTTYPE_ADDR, | |
1923 | (caddr_t)&sp->spidx.src, | |
1924 | sp->spidx.src.ss_len, | |
1925 | *(u_int64_t *)&id); | |
1926 | ||
1927 | bzero(&id, sizeof(id)); | |
1928 | id.sadb_x_ident_id_addr.prefix = sp->spidx.prefd; | |
1929 | id.sadb_x_ident_id_addr.ul_proto = sp->spidx.ul_proto; | |
1930 | p = key_setsadbident(p, | |
1931 | SADB_EXT_IDENTITY_DST, | |
1932 | SADB_X_IDENTTYPE_ADDR, | |
1933 | (caddr_t)&sp->spidx.dst, | |
1934 | sp->spidx.dst.ss_len, | |
1935 | *(u_int64_t *)&id); | |
1936 | ||
1937 | error = key_sendall(newmsg, len); | |
1938 | #if IPSEC_DEBUG | |
1939 | if (error != 0) | |
1940 | printf("key_spdacquire: key_sendall returned %d\n", error); | |
1941 | #endif | |
1942 | return error; | |
1943 | } | |
1944 | ||
1945 | return 0; | |
1946 | } | |
1947 | ||
1948 | /* | |
1949 | * SADB_SPDFLUSH processing | |
1950 | * receive | |
1951 | * <base> | |
1952 | * from the user, and free all entries in secpctree. | |
1953 | * and send, | |
1954 | * <base> | |
1955 | * to the user. | |
1956 | * NOTE: what to do is only marking SADB_SASTATE_DEAD. | |
1957 | * | |
1958 | * IN: mhp: pointer to the pointer to each header. | |
1959 | * OUT: other if success, return pointer to the message to send. | |
1960 | * 0 if fail. | |
1961 | */ | |
1962 | static struct sadb_msg * | |
1963 | key_spdflush(mhp) | |
1964 | caddr_t *mhp; | |
1965 | { | |
1966 | struct sadb_msg *msg0; | |
1967 | struct secpolicy *sp; | |
1968 | u_int dir; | |
1969 | ||
1970 | /* sanity check */ | |
1971 | if (mhp == NULL || mhp[0] == NULL) | |
1972 | panic("key_spdflush: NULL pointer is passed.\n"); | |
1973 | ||
1974 | msg0 = (struct sadb_msg *)mhp[0]; | |
1975 | ||
1976 | for (dir = 0; dir < IPSEC_DIR_MAX; dir++) { | |
1977 | LIST_FOREACH(sp, &sptree[dir], chain) { | |
1978 | sp->state = IPSEC_SPSTATE_DEAD; | |
1979 | } | |
1980 | } | |
1981 | ||
1982 | { | |
1983 | struct sadb_msg *newmsg; | |
1984 | u_int len; | |
1985 | ||
1986 | /* create new sadb_msg to reply. */ | |
1987 | len = sizeof(struct sadb_msg); | |
1988 | ||
1989 | KMALLOC(newmsg, struct sadb_msg *, len); | |
1990 | if (newmsg == NULL) { | |
1991 | #if IPSEC_DEBUG | |
1992 | printf("key_spdflush: No more memory.\n"); | |
1993 | #endif | |
1994 | msg0->sadb_msg_errno = ENOBUFS; | |
1995 | return NULL; | |
1996 | } | |
1997 | bzero((caddr_t)newmsg, len); | |
1998 | ||
1999 | bcopy((caddr_t)mhp[0], (caddr_t)newmsg, sizeof(*msg0)); | |
2000 | newmsg->sadb_msg_errno = 0; | |
2001 | newmsg->sadb_msg_len = PFKEY_UNIT64(len); | |
2002 | ||
2003 | return(newmsg); | |
2004 | } | |
2005 | } | |
2006 | ||
2007 | /* | |
2008 | * SADB_SPDDUMP processing | |
2009 | * receive | |
2010 | * <base> | |
2011 | * from the user, and dump all SP leaves | |
2012 | * and send, | |
2013 | * <base> ..... | |
2014 | * to the ikmpd. | |
2015 | * | |
2016 | * IN: mhp: pointer to the pointer to each header. | |
2017 | * OUT: other if success, return pointer to the message to send. | |
2018 | * 0 if fail. | |
2019 | */ | |
2020 | static int | |
2021 | key_spddump(mhp, so, target) | |
2022 | caddr_t *mhp; | |
2023 | struct socket *so; | |
2024 | int target; | |
2025 | { | |
2026 | struct sadb_msg *msg0; | |
2027 | struct secpolicy *sp; | |
2028 | int cnt; | |
2029 | u_int dir; | |
2030 | struct mbuf *m; | |
2031 | ||
2032 | /* sanity check */ | |
2033 | if (mhp == NULL || mhp[0] == NULL) | |
2034 | panic("key_spddump: NULL pointer is passed.\n"); | |
2035 | ||
2036 | msg0 = (struct sadb_msg *)mhp[0]; | |
2037 | ||
2038 | /* search SPD entry and get buffer size. */ | |
2039 | cnt = 0; | |
2040 | for (dir = 0; dir < IPSEC_DIR_MAX; dir++) { | |
2041 | LIST_FOREACH(sp, &sptree[dir], chain) { | |
2042 | cnt++; | |
2043 | } | |
2044 | } | |
2045 | ||
2046 | if (cnt == 0) | |
2047 | return ENOENT; | |
2048 | ||
2049 | for (dir = 0; dir < IPSEC_DIR_MAX; dir++) { | |
2050 | LIST_FOREACH(sp, &sptree[dir], chain) { | |
2051 | --cnt; | |
2052 | m = key_setdumpsp(sp, SADB_X_SPDDUMP, | |
2053 | cnt, msg0->sadb_msg_pid); | |
2054 | ||
2055 | if (m) | |
2056 | key_sendup_mbuf(so, m, target); | |
2057 | } | |
2058 | } | |
2059 | ||
2060 | return 0; | |
2061 | } | |
2062 | ||
2063 | static struct mbuf * | |
2064 | key_setdumpsp(sp, type, seq, pid) | |
2065 | struct secpolicy *sp; | |
2066 | u_int8_t type; | |
2067 | u_int32_t seq, pid; | |
2068 | { | |
2069 | struct mbuf *m; | |
2070 | u_int tlen; | |
2071 | ||
2072 | /* XXX it would be better to avoid pre-computing length */ | |
2073 | tlen = key_getspmsglen(sp); | |
2074 | ||
2075 | /* XXX maybe it's a wrong idea to insist on cluster? */ | |
2076 | MGETHDR(m, M_DONTWAIT, MT_DATA); | |
2077 | if (m != NULL) { | |
2078 | MCLGET(m, M_DONTWAIT); | |
2079 | if ((m->m_flags & M_EXT) == 0) { | |
2080 | m_freem(m); | |
2081 | m = NULL; | |
2082 | } | |
2083 | } | |
2084 | if (m == NULL) | |
2085 | return NULL; /*ENOBUFS*/ | |
2086 | ||
2087 | m->m_pkthdr.len = m->m_len = 0; | |
2088 | m->m_next = NULL; | |
2089 | ||
2090 | /* sadb_msg->sadb_msg_len must be filled afterwards */ | |
2091 | if (key_setsadbmsg_m(m, type, 0, SADB_SATYPE_UNSPEC, seq, pid, | |
2092 | IPSEC_MODE_ANY, 0, 0, sp->refcnt) != 0) { | |
2093 | m_freem(m); | |
2094 | return NULL; | |
2095 | } | |
2096 | ||
2097 | if (key_setsadbaddr_m(m, SADB_EXT_ADDRESS_SRC, | |
2098 | (struct sockaddr *)&sp->spidx.src, sp->spidx.prefs, | |
2099 | sp->spidx.ul_proto) != 0) { | |
2100 | m_freem(m); | |
2101 | return NULL; | |
2102 | } | |
2103 | ||
2104 | if (key_setsadbaddr_m(m, SADB_EXT_ADDRESS_DST, | |
2105 | (struct sockaddr *)&sp->spidx.dst, sp->spidx.prefd, | |
2106 | sp->spidx.ul_proto) != 0) { | |
2107 | m_freem(m); | |
2108 | return NULL; | |
2109 | } | |
2110 | ||
2111 | { | |
2112 | struct mbuf *n; | |
2113 | struct sadb_x_policy *tmp; | |
2114 | ||
2115 | n = key_sp2msg(sp); | |
2116 | if (!n || n->m_len < sizeof(*tmp)) { | |
2117 | #if IPSEC_DEBUG | |
2118 | printf("key_setdumpsp: No more memory.\n"); | |
2119 | #endif | |
2120 | m_freem(m); | |
2121 | if (n) | |
2122 | m_freem(n); | |
2123 | return NULL; | |
2124 | } | |
2125 | ||
2126 | tmp = mtod(n, struct sadb_x_policy *); | |
2127 | ||
2128 | /* validity check */ | |
2129 | if (key_getspreqmsglen(sp) != PFKEY_UNUNIT64(tmp->sadb_x_policy_len) | |
2130 | || n->m_len != PFKEY_UNUNIT64(tmp->sadb_x_policy_len)) | |
2131 | panic("key_setdumpsp: length mismatch." | |
2132 | "sp:%d msg:%d\n", | |
2133 | key_getspreqmsglen(sp), | |
2134 | PFKEY_UNUNIT64(tmp->sadb_x_policy_len)); | |
2135 | ||
2136 | m_cat(m, n); | |
2137 | m->m_pkthdr.len += n->m_len; | |
2138 | } | |
2139 | ||
2140 | if (m->m_len < sizeof(struct sadb_msg)) { | |
2141 | m = m_pullup(m, sizeof(struct sadb_msg)); | |
2142 | if (m == NULL) | |
2143 | return NULL; | |
2144 | } | |
2145 | mtod(m, struct sadb_msg *)->sadb_msg_len = | |
2146 | PFKEY_UNIT64(m->m_pkthdr.len); | |
2147 | ||
2148 | return m; | |
2149 | } | |
2150 | ||
2151 | /* get sadb message length for a SP. */ | |
2152 | static u_int | |
2153 | key_getspmsglen(sp) | |
2154 | struct secpolicy *sp; | |
2155 | { | |
2156 | u_int tlen; | |
2157 | ||
2158 | /* sanity check */ | |
2159 | if (sp == NULL) | |
2160 | panic("key_getspmsglen: NULL pointer is passed.\n"); | |
2161 | ||
2162 | tlen = (sizeof(struct sadb_msg) | |
2163 | + sizeof(struct sadb_address) | |
2164 | + PFKEY_ALIGN8(_SALENBYAF(sp->spidx.src.ss_family)) | |
2165 | + sizeof(struct sadb_address) | |
2166 | + PFKEY_ALIGN8(_SALENBYAF(sp->spidx.dst.ss_family))); | |
2167 | ||
2168 | tlen += key_getspreqmsglen(sp); | |
2169 | ||
2170 | return tlen; | |
2171 | } | |
2172 | ||
2173 | /* | |
2174 | * get PFKEY message length for security policy and request. | |
2175 | */ | |
2176 | static u_int | |
2177 | key_getspreqmsglen(sp) | |
2178 | struct secpolicy *sp; | |
2179 | { | |
2180 | u_int tlen; | |
2181 | ||
2182 | tlen = sizeof(struct sadb_x_policy); | |
2183 | ||
2184 | /* if is the policy for ipsec ? */ | |
2185 | if (sp->policy != IPSEC_POLICY_IPSEC) | |
2186 | return tlen; | |
2187 | ||
2188 | /* get length of ipsec requests */ | |
2189 | { | |
2190 | struct ipsecrequest *isr; | |
2191 | int len; | |
2192 | ||
2193 | for (isr = sp->req; isr != NULL; isr = isr->next) { | |
2194 | len = sizeof(struct sadb_x_ipsecrequest) | |
2195 | + isr->saidx.src.ss_len | |
2196 | + isr->saidx.dst.ss_len; | |
2197 | ||
2198 | tlen += PFKEY_ALIGN8(len); | |
2199 | } | |
2200 | } | |
2201 | ||
2202 | return tlen; | |
2203 | } | |
2204 | ||
2205 | /* %%% SAD management */ | |
2206 | /* | |
2207 | * allocating a memory for new SA head, and copy from the values of mhp. | |
2208 | * OUT: NULL : failure due to the lack of memory. | |
2209 | * others : pointer to new SA head. | |
2210 | */ | |
2211 | static struct secashead * | |
2212 | key_newsah(saidx) | |
2213 | struct secasindex *saidx; | |
2214 | { | |
2215 | struct secashead *newsah; | |
2216 | ||
2217 | /* sanity check */ | |
2218 | if (saidx == NULL) | |
2219 | panic("key_newsaidx: NULL pointer is passed.\n"); | |
2220 | ||
2221 | newsah = keydb_newsecashead(); | |
2222 | if (newsah == NULL) | |
2223 | return NULL; | |
2224 | ||
2225 | bcopy(saidx, &newsah->saidx, sizeof(newsah->saidx)); | |
2226 | ||
2227 | /* add to saidxtree */ | |
2228 | newsah->state = SADB_SASTATE_MATURE; | |
2229 | LIST_INSERT_HEAD(&sahtree, newsah, chain); | |
2230 | ||
2231 | return(newsah); | |
2232 | } | |
2233 | ||
2234 | /* | |
2235 | * delete SA index and all SA registerd. | |
2236 | */ | |
2237 | static void | |
2238 | key_delsah(sah) | |
2239 | struct secashead *sah; | |
2240 | { | |
2241 | struct secasvar *sav, *nextsav; | |
2242 | u_int stateidx, state; | |
2243 | int s; | |
2244 | int zombie = 0; | |
2245 | ||
2246 | /* sanity check */ | |
2247 | if (sah == NULL) | |
2248 | panic("key_delsah: NULL pointer is passed.\n"); | |
2249 | ||
2250 | #ifdef __NetBSD__ | |
2251 | s = splsoftnet(); /*called from softclock()*/ | |
2252 | #else | |
2253 | s = splnet(); /*called from softclock()*/ | |
2254 | #endif | |
2255 | ||
2256 | /* searching all SA registerd in the secindex. */ | |
2257 | for (stateidx = 0; | |
2258 | stateidx < _ARRAYLEN(saorder_state_any); | |
2259 | stateidx++) { | |
2260 | ||
2261 | state = saorder_state_any[stateidx]; | |
2262 | for (sav = (struct secasvar *)LIST_FIRST(&sah->savtree[state]); | |
2263 | sav != NULL; | |
2264 | sav = nextsav) { | |
2265 | ||
2266 | nextsav = LIST_NEXT(sav, chain); | |
2267 | ||
2268 | if (sav->refcnt > 0) { | |
2269 | /* give up to delete this sa */ | |
2270 | zombie++; | |
2271 | continue; | |
2272 | } | |
2273 | ||
2274 | /* sanity check */ | |
2275 | KEY_CHKSASTATE(state, sav->state, "key_delsah"); | |
2276 | ||
2277 | key_freesav(sav); | |
2278 | ||
2279 | /* remove back pointer */ | |
2280 | sav->sah = NULL; | |
2281 | sav = NULL; | |
2282 | } | |
2283 | } | |
2284 | ||
2285 | /* don't delete sah only if there are savs. */ | |
2286 | if (zombie) { | |
2287 | splx(s); | |
2288 | return; | |
2289 | } | |
2290 | ||
2291 | if (sah->sa_route.ro_rt) { | |
2292 | RTFREE(sah->sa_route.ro_rt); | |
2293 | sah->sa_route.ro_rt = (struct rtentry *)NULL; | |
2294 | } | |
2295 | ||
2296 | /* remove from tree of SA index */ | |
2297 | if (__LIST_CHAINED(sah)) | |
2298 | LIST_REMOVE(sah, chain); | |
2299 | ||
2300 | KFREE(sah); | |
2301 | ||
2302 | splx(s); | |
2303 | return; | |
2304 | } | |
2305 | ||
2306 | /* | |
2307 | * allocating a new SA with LARVAL state. key_add() and key_getspi() call, | |
2308 | * and copy the values of mhp into new buffer. | |
2309 | * When SAD message type is GETSPI: | |
2310 | * to set sequence number from acq_seq++, | |
2311 | * to set zero to SPI. | |
2312 | * not to call key_setsava(). | |
2313 | * OUT: NULL : fail | |
2314 | * others : pointer to new secasvar. | |
2315 | */ | |
2316 | static struct secasvar * | |
2317 | key_newsav(mhp, sah) | |
2318 | caddr_t *mhp; | |
2319 | struct secashead *sah; | |
2320 | { | |
2321 | struct secasvar *newsav; | |
2322 | struct sadb_msg *msg0; | |
2323 | ||
2324 | /* sanity check */ | |
2325 | if (mhp == NULL || mhp[0] == NULL || sah == NULL) | |
2326 | panic("key_newsa: NULL pointer is passed.\n"); | |
2327 | ||
2328 | msg0 = (struct sadb_msg *)mhp[0]; | |
2329 | ||
2330 | KMALLOC(newsav, struct secasvar *, sizeof(struct secasvar)); | |
2331 | if (newsav == NULL) { | |
2332 | #if IPSEC_DEBUG | |
2333 | printf("key_newsa: No more memory.\n"); | |
2334 | #endif | |
2335 | msg0->sadb_msg_errno = ENOBUFS; | |
2336 | return NULL; | |
2337 | } | |
2338 | bzero((caddr_t)newsav, sizeof(struct secasvar)); | |
2339 | ||
2340 | switch (msg0->sadb_msg_type) { | |
2341 | case SADB_GETSPI: | |
2342 | newsav->spi = 0; | |
2343 | ||
2344 | #if IPSEC_DOSEQCHECK | |
2345 | /* sync sequence number */ | |
2346 | if (msg0->sadb_msg_seq == 0) | |
2347 | newsav->seq = | |
2348 | (acq_seq = (acq_seq == ~0 ? 1 : ++acq_seq)); | |
2349 | else | |
2350 | #endif | |
2351 | newsav->seq = msg0->sadb_msg_seq; | |
2352 | break; | |
2353 | ||
2354 | case SADB_ADD: | |
2355 | /* sanity check */ | |
2356 | if (mhp[SADB_EXT_SA] == NULL) { | |
2357 | KFREE(newsav); | |
2358 | #if IPSEC_DEBUG | |
2359 | printf("key_newsa: invalid message is passed.\n"); | |
2360 | #endif | |
2361 | msg0->sadb_msg_errno = EINVAL; | |
2362 | return NULL; | |
2363 | } | |
2364 | newsav->spi = ((struct sadb_sa *)mhp[SADB_EXT_SA])->sadb_sa_spi; | |
2365 | newsav->seq = msg0->sadb_msg_seq; | |
2366 | break; | |
2367 | default: | |
2368 | KFREE(newsav); | |
2369 | msg0->sadb_msg_errno = EINVAL; | |
2370 | return NULL; | |
2371 | } | |
2372 | ||
2373 | /* copy sav values */ | |
2374 | if (msg0->sadb_msg_type != SADB_GETSPI && key_setsaval(newsav, mhp)) { | |
2375 | KFREE(newsav); | |
2376 | /* msg0->sadb_msg_errno is set at key_setsaval. */ | |
2377 | return NULL; | |
2378 | } | |
2379 | ||
2380 | /* reset tick */ | |
2381 | newsav->tick = 0; | |
2382 | ||
2383 | newsav->pid = msg0->sadb_msg_pid; | |
2384 | ||
2385 | /* add to satree */ | |
2386 | newsav->sah = sah; | |
2387 | newsav->refcnt = 1; | |
2388 | newsav->state = SADB_SASTATE_LARVAL; | |
2389 | LIST_INSERT_TAIL(&sah->savtree[SADB_SASTATE_LARVAL], newsav, | |
2390 | secasvar, chain); | |
2391 | ||
2392 | return newsav; | |
2393 | } | |
2394 | ||
2395 | /* | |
2396 | * free() SA variable entry. | |
2397 | */ | |
2398 | static void | |
2399 | key_delsav(sav) | |
2400 | struct secasvar *sav; | |
2401 | { | |
2402 | /* sanity check */ | |
2403 | if (sav == NULL) | |
2404 | panic("key_delsav: NULL pointer is passed.\n"); | |
2405 | ||
2406 | if (sav->refcnt > 0) | |
2407 | return; /* can't free */ | |
2408 | ||
2409 | /* remove from SA header */ | |
2410 | if (__LIST_CHAINED(sav)) | |
2411 | LIST_REMOVE(sav, chain); | |
2412 | ||
2413 | if (sav->key_auth != NULL) | |
2414 | KFREE(sav->key_auth); | |
2415 | if (sav->key_enc != NULL) | |
2416 | KFREE(sav->key_enc); | |
2417 | if (sav->replay != NULL) | |
2418 | keydb_delsecreplay(sav->replay); | |
2419 | if (sav->lft_c != NULL) | |
2420 | KFREE(sav->lft_c); | |
2421 | if (sav->lft_h != NULL) | |
2422 | KFREE(sav->lft_h); | |
2423 | if (sav->lft_s != NULL) | |
2424 | KFREE(sav->lft_s); | |
2425 | if (sav->iv != NULL) | |
2426 | KFREE(sav->iv); | |
2427 | #if notyet | |
2428 | if (sav->misc1 != NULL) | |
2429 | KFREE(sav->misc1); | |
2430 | if (sav->misc2 != NULL) | |
2431 | KFREE(sav->misc2); | |
2432 | if (sav->misc3 != NULL) | |
2433 | KFREE(sav->misc3); | |
2434 | #endif | |
2435 | ||
2436 | KFREE(sav); | |
2437 | ||
2438 | return; | |
2439 | } | |
2440 | ||
2441 | /* | |
2442 | * search SAD. | |
2443 | * OUT: | |
2444 | * NULL : not found | |
2445 | * others : found, pointer to a SA. | |
2446 | */ | |
2447 | static struct secashead * | |
2448 | key_getsah(saidx) | |
2449 | struct secasindex *saidx; | |
2450 | { | |
2451 | struct secashead *sah; | |
2452 | ||
2453 | LIST_FOREACH(sah, &sahtree, chain) { | |
2454 | if (sah->state == SADB_SASTATE_DEAD) | |
2455 | continue; | |
2456 | if (key_cmpsaidx_exactly(&sah->saidx, saidx)) | |
2457 | return(sah); | |
2458 | } | |
2459 | ||
2460 | return NULL; | |
2461 | } | |
2462 | ||
2463 | /* | |
2464 | * check not to be duplicated SPI. | |
2465 | * NOTE: this function is too slow due to searching all SAD. | |
2466 | * OUT: | |
2467 | * NULL : not found | |
2468 | * others : found, pointer to a SA. | |
2469 | */ | |
2470 | static struct secasvar * | |
2471 | key_checkspidup(saidx, spi) | |
2472 | struct secasindex *saidx; | |
2473 | u_int32_t spi; | |
2474 | { | |
2475 | struct secashead *sah; | |
2476 | struct secasvar *sav; | |
2477 | ||
2478 | /* check address family */ | |
2479 | if (saidx->src.ss_family != saidx->dst.ss_family) { | |
2480 | #if IPSEC_DEBUG | |
2481 | printf("key_checkspidup: address family mismatched.\n"); | |
2482 | #endif | |
2483 | return NULL; | |
2484 | } | |
2485 | ||
2486 | /* check all SAD */ | |
2487 | LIST_FOREACH(sah, &sahtree, chain) { | |
2488 | if (!key_ismyaddr(sah->saidx.dst.ss_family, | |
2489 | _INADDRBYSA(&sah->saidx.dst))) | |
2490 | continue; | |
2491 | sav = key_getsavbyspi(sah, spi); | |
2492 | if (sav != NULL) | |
2493 | return sav; | |
2494 | } | |
2495 | ||
2496 | return NULL; | |
2497 | } | |
2498 | ||
2499 | /* | |
2500 | * search SAD litmited alive SA, protocol, SPI. | |
2501 | * OUT: | |
2502 | * NULL : not found | |
2503 | * others : found, pointer to a SA. | |
2504 | */ | |
2505 | static struct secasvar * | |
2506 | key_getsavbyspi(sah, spi) | |
2507 | struct secashead *sah; | |
2508 | u_int32_t spi; | |
2509 | { | |
2510 | struct secasvar *sav; | |
2511 | u_int stateidx, state; | |
2512 | ||
2513 | /* search all status */ | |
2514 | for (stateidx = 0; | |
2515 | stateidx < _ARRAYLEN(saorder_state_alive); | |
2516 | stateidx++) { | |
2517 | ||
2518 | state = saorder_state_alive[stateidx]; | |
2519 | LIST_FOREACH(sav, &sah->savtree[state], chain) { | |
2520 | ||
2521 | /* sanity check */ | |
2522 | if (sav->state != state) { | |
2523 | #if IPSEC_DEBUG | |
2524 | printf("key_getsavbyspi: " | |
2525 | "invalid sav->state " | |
2526 | "(queue: %d SA: %d)\n", | |
2527 | state, sav->state); | |
2528 | #endif | |
2529 | continue; | |
2530 | } | |
2531 | ||
2532 | if (sav->spi == spi) | |
2533 | return sav; | |
2534 | } | |
2535 | } | |
2536 | ||
2537 | return NULL; | |
2538 | } | |
2539 | ||
2540 | /* | |
2541 | * copy SA values from PF_KEY message except *SPI, SEQ, PID, STATE and TYPE*. | |
2542 | * You must update these if need. | |
2543 | * OUT: 0: success. | |
2544 | * 1: failure. set errno to (mhp[0])->sadb_msg_errno. | |
2545 | */ | |
2546 | static int | |
2547 | key_setsaval(sav, mhp) | |
2548 | struct secasvar *sav; | |
2549 | caddr_t *mhp; | |
2550 | { | |
2551 | struct sadb_msg *msg0; | |
2552 | int error = 0; | |
2553 | ||
2554 | /* sanity check */ | |
2555 | if (mhp == NULL || mhp[0] == NULL) | |
2556 | panic("key_setsaval: NULL pointer is passed.\n"); | |
2557 | ||
2558 | msg0 = (struct sadb_msg *)mhp[0]; | |
2559 | ||
2560 | /* initialization */ | |
2561 | sav->replay = NULL; | |
2562 | sav->key_auth = NULL; | |
2563 | sav->key_enc = NULL; | |
2564 | sav->iv = NULL; | |
2565 | sav->lft_c = NULL; | |
2566 | sav->lft_h = NULL; | |
2567 | sav->lft_s = NULL; | |
2568 | #if notyet | |
2569 | sav->misc1 = NULL; | |
2570 | sav->misc2 = NULL; | |
2571 | sav->misc3 = NULL; | |
2572 | #endif | |
2573 | ||
2574 | /* SA */ | |
2575 | if (mhp[SADB_EXT_SA] != NULL) { | |
2576 | struct sadb_sa *sa0 = (struct sadb_sa *)mhp[SADB_EXT_SA]; | |
2577 | ||
2578 | sav->alg_auth = sa0->sadb_sa_auth; | |
2579 | sav->alg_enc = sa0->sadb_sa_encrypt; | |
2580 | sav->flags = sa0->sadb_sa_flags; | |
2581 | ||
2582 | /* replay window */ | |
2583 | if ((sa0->sadb_sa_flags & SADB_X_EXT_OLD) == 0) { | |
2584 | sav->replay = keydb_newsecreplay(sa0->sadb_sa_replay); | |
2585 | if (sav->replay == NULL) { | |
2586 | #if IPSEC_DEBUG | |
2587 | printf("key_setsaval: No more memory.\n"); | |
2588 | #endif | |
2589 | error = ENOBUFS; | |
2590 | goto err; | |
2591 | } | |
2592 | } | |
2593 | } | |
2594 | ||
2595 | /* Authentication keys */ | |
2596 | if (mhp[SADB_EXT_KEY_AUTH] != NULL) { | |
2597 | struct sadb_key *key0; | |
2598 | u_int len; | |
2599 | ||
2600 | key0 = (struct sadb_key *)mhp[SADB_EXT_KEY_AUTH]; | |
2601 | len = PFKEY_UNUNIT64(key0->sadb_key_len); | |
2602 | ||
2603 | error = 0; | |
2604 | if (len < sizeof(struct sadb_key)) | |
2605 | error = EINVAL; | |
2606 | switch (msg0->sadb_msg_satype) { | |
2607 | case SADB_SATYPE_AH: | |
2608 | case SADB_SATYPE_ESP: | |
2609 | if (len == sizeof(struct sadb_key) | |
2610 | && sav->alg_auth != SADB_AALG_NULL) { | |
2611 | error = EINVAL; | |
2612 | } | |
2613 | break; | |
2614 | case SADB_X_SATYPE_IPCOMP: | |
2615 | error = EINVAL; | |
2616 | break; | |
2617 | default: | |
2618 | error = EINVAL; | |
2619 | break; | |
2620 | } | |
2621 | if (error) { | |
2622 | #if IPSEC_DEBUG | |
2623 | printf("key_setsaval: invalid key_auth values.\n"); | |
2624 | #endif | |
2625 | goto err; | |
2626 | } | |
2627 | ||
2628 | sav->key_auth = (struct sadb_key *)key_newbuf(key0, len); | |
2629 | if (sav->key_auth == NULL) { | |
2630 | #if IPSEC_DEBUG | |
2631 | printf("key_setsaval: No more memory.\n"); | |
2632 | #endif | |
2633 | error = ENOBUFS; | |
2634 | goto err; | |
2635 | } | |
2636 | ||
2637 | /* make length shift up for kernel*/ | |
2638 | sav->key_auth->sadb_key_len = len; | |
2639 | } | |
2640 | ||
2641 | /* Encryption key */ | |
2642 | if (mhp[SADB_EXT_KEY_ENCRYPT] != NULL) { | |
2643 | struct sadb_key *key0; | |
2644 | u_int len; | |
2645 | ||
2646 | key0 = (struct sadb_key *)mhp[SADB_EXT_KEY_ENCRYPT]; | |
2647 | len = PFKEY_UNUNIT64(key0->sadb_key_len); | |
2648 | ||
2649 | error = 0; | |
2650 | if (len < sizeof(struct sadb_key)) | |
2651 | error = EINVAL; | |
2652 | switch (msg0->sadb_msg_satype) { | |
2653 | case SADB_SATYPE_ESP: | |
2654 | if (len == sizeof(struct sadb_key) | |
2655 | && sav->alg_enc != SADB_EALG_NULL) { | |
2656 | error = EINVAL; | |
2657 | } | |
2658 | break; | |
2659 | case SADB_SATYPE_AH: | |
2660 | error = EINVAL; | |
2661 | break; | |
2662 | case SADB_X_SATYPE_IPCOMP: | |
2663 | break; | |
2664 | default: | |
2665 | error = EINVAL; | |
2666 | break; | |
2667 | } | |
2668 | if (error) { | |
2669 | #if IPSEC_DEBUG | |
2670 | printf("key_setsatval: invalid key_enc value.\n"); | |
2671 | #endif | |
2672 | goto err; | |
2673 | } | |
2674 | ||
2675 | sav->key_enc = (struct sadb_key *)key_newbuf(key0, len); | |
2676 | if (sav->key_enc == NULL) { | |
2677 | #if IPSEC_DEBUG | |
2678 | printf("key_setsaval: No more memory.\n"); | |
2679 | #endif | |
2680 | error = ENOBUFS; | |
2681 | goto err; | |
2682 | } | |
2683 | ||
2684 | /* make length shift up for kernel*/ | |
2685 | sav->key_enc->sadb_key_len = len; | |
2686 | } | |
2687 | ||
2688 | /* set iv */ | |
2689 | sav->ivlen = 0; | |
2690 | ||
2691 | switch (msg0->sadb_msg_satype) { | |
2692 | case SADB_SATYPE_ESP: | |
2693 | #if IPSEC_ESP | |
2694 | { | |
2695 | struct esp_algorithm *algo; | |
2696 | ||
2697 | algo = &esp_algorithms[sav->alg_enc]; | |
2698 | if (algo && algo->ivlen) | |
2699 | sav->ivlen = (*algo->ivlen)(sav); | |
2700 | KMALLOC(sav->iv, caddr_t, sav->ivlen); | |
2701 | if (sav->iv == 0) { | |
2702 | #if IPSEC_DEBUG | |
2703 | printf("key_setsaval: No more memory.\n"); | |
2704 | #endif | |
2705 | error = ENOBUFS; | |
2706 | goto err; | |
2707 | } | |
2708 | /* initialize ? */ | |
2709 | break; | |
2710 | } | |
2711 | #else | |
2712 | break; | |
2713 | #endif | |
2714 | case SADB_SATYPE_AH: | |
2715 | #if 1 /*nonstandard*/ | |
2716 | case SADB_X_SATYPE_IPCOMP: | |
2717 | #endif | |
2718 | break; | |
2719 | default: | |
2720 | #if IPSEC_DEBUG | |
2721 | printf("key_setsaval: invalid SA type.\n"); | |
2722 | #endif | |
2723 | error = EINVAL; | |
2724 | goto err; | |
2725 | } | |
2726 | ||
2727 | /* reset tick */ | |
2728 | sav->tick = 0; | |
2729 | ||
2730 | /* make lifetime for CURRENT */ | |
2731 | { | |
2732 | struct timeval tv; | |
2733 | ||
2734 | KMALLOC(sav->lft_c, struct sadb_lifetime *, | |
2735 | sizeof(struct sadb_lifetime)); | |
2736 | if (sav->lft_c == NULL) { | |
2737 | #if IPSEC_DEBUG | |
2738 | printf("key_setsaval: No more memory.\n"); | |
2739 | #endif | |
2740 | error = ENOBUFS; | |
2741 | goto err; | |
2742 | } | |
2743 | ||
2744 | microtime(&tv); | |
2745 | ||
2746 | sav->lft_c->sadb_lifetime_len = | |
2747 | PFKEY_UNIT64(sizeof(struct sadb_lifetime)); | |
2748 | sav->lft_c->sadb_lifetime_exttype = SADB_EXT_LIFETIME_CURRENT; | |
2749 | sav->lft_c->sadb_lifetime_allocations = 0; | |
2750 | sav->lft_c->sadb_lifetime_bytes = 0; | |
2751 | sav->lft_c->sadb_lifetime_addtime = tv.tv_sec; | |
2752 | sav->lft_c->sadb_lifetime_usetime = 0; | |
2753 | } | |
2754 | ||
2755 | /* lifetimes for HARD and SOFT */ | |
2756 | { | |
2757 | struct sadb_lifetime *lft0; | |
2758 | ||
2759 | lft0 = (struct sadb_lifetime *)mhp[SADB_EXT_LIFETIME_HARD]; | |
2760 | if (lft0 != NULL) { | |
2761 | sav->lft_h = (struct sadb_lifetime *)key_newbuf(lft0, | |
2762 | sizeof(*lft0)); | |
2763 | if (sav->lft_h == NULL) { | |
2764 | #if IPSEC_DEBUG | |
2765 | printf("key_setsaval: No more memory.\n"); | |
2766 | #endif | |
2767 | error = ENOBUFS; | |
2768 | goto err; | |
2769 | } | |
2770 | /* to be initialize ? */ | |
2771 | } | |
2772 | ||
2773 | lft0 = (struct sadb_lifetime *)mhp[SADB_EXT_LIFETIME_SOFT]; | |
2774 | if (lft0 != NULL) { | |
2775 | sav->lft_s = (struct sadb_lifetime *)key_newbuf(lft0, | |
2776 | sizeof(*lft0)); | |
2777 | if (sav->lft_s == NULL) { | |
2778 | #if IPSEC_DEBUG | |
2779 | printf("key_setsaval: No more memory.\n"); | |
2780 | #endif | |
2781 | error = ENOBUFS; | |
2782 | goto err; | |
2783 | } | |
2784 | /* to be initialize ? */ | |
2785 | } | |
2786 | } | |
2787 | ||
2788 | #if notyet | |
2789 | /* pre-processing for DES */ | |
2790 | switch (sav->alg_enc) { | |
2791 | case SADB_EALG_DESCBC: | |
2792 | if (des_key_sched((C_Block *)_KEYBUF(sav->key_enc), | |
2793 | (des_key_schedule)sav->misc1) != 0) { | |
2794 | #if IPSEC_DEBUG | |
2795 | printf("key_setsaval: error des_key_sched.\n"); | |
2796 | #endif | |
2797 | sav->misc1 = NULL; | |
2798 | /* THROUGH */ | |
2799 | } | |
2800 | break; | |
2801 | case SADB_EALG_3DESCBC: | |
2802 | if (des_key_sched((C_Block *)_KEYBUF(sav->key_enc), | |
2803 | (des_key_schedule)sav->misc1) != 0 | |
2804 | || des_key_sched((C_Block *)(_KEYBUF(sav->key_enc) + 8), | |
2805 | (des_key_schedule)sav->misc2) != 0 | |
2806 | || des_key_sched((C_Block *)(_KEYBUF(sav->key_enc) + 16), | |
2807 | (des_key_schedule)sav->misc3) != 0) { | |
2808 | #if IPSEC_DEBUG | |
2809 | printf("key_setsaval: error des_key_sched.\n"); | |
2810 | #endif | |
2811 | sav->misc1 = NULL; | |
2812 | sav->misc2 = NULL; | |
2813 | sav->misc3 = NULL; | |
2814 | /* THROUGH */ | |
2815 | } | |
2816 | } | |
2817 | #endif | |
2818 | ||
2819 | msg0->sadb_msg_errno = 0; | |
2820 | return 0; | |
2821 | ||
2822 | err: | |
2823 | /* initialization */ | |
2824 | if (sav->replay != NULL) | |
2825 | keydb_delsecreplay(sav->replay); | |
2826 | if (sav->key_auth != NULL) | |
2827 | KFREE(sav->key_auth); | |
2828 | if (sav->key_enc != NULL) | |
2829 | KFREE(sav->key_enc); | |
2830 | if (sav->iv != NULL) | |
2831 | KFREE(sav->iv); | |
2832 | if (sav->lft_c != NULL) | |
2833 | KFREE(sav->lft_c); | |
2834 | if (sav->lft_h != NULL) | |
2835 | KFREE(sav->lft_h); | |
2836 | if (sav->lft_s != NULL) | |
2837 | KFREE(sav->lft_s); | |
2838 | #if notyet | |
2839 | if (sav->misc1 != NULL) | |
2840 | KFREE(sav->misc1); | |
2841 | if (sav->misc2 != NULL) | |
2842 | KFREE(sav->misc2); | |
2843 | if (sav->misc3 != NULL) | |
2844 | KFREE(sav->misc3); | |
2845 | #endif | |
2846 | ||
2847 | msg0->sadb_msg_errno = error; | |
2848 | return 1; | |
2849 | } | |
2850 | ||
2851 | /* | |
2852 | * get message buffer length. | |
2853 | */ | |
2854 | static u_int | |
2855 | key_getmsglen(sav) | |
2856 | struct secasvar *sav; | |
2857 | { | |
2858 | int len = sizeof(struct sadb_msg); | |
2859 | ||
2860 | len += sizeof(struct sadb_sa); | |
2861 | len += (sizeof(struct sadb_address) | |
2862 | + PFKEY_ALIGN8(_SALENBYAF(sav->sah->saidx.src.ss_family))); | |
2863 | len += (sizeof(struct sadb_address) | |
2864 | + PFKEY_ALIGN8(_SALENBYAF(sav->sah->saidx.dst.ss_family))); | |
2865 | ||
2866 | if (sav->key_auth != NULL) | |
2867 | len += sav->key_auth->sadb_key_len; | |
2868 | if (sav->key_enc != NULL) | |
2869 | len += sav->key_enc->sadb_key_len; | |
2870 | ||
2871 | if (sav->lft_c != NULL) | |
2872 | len += sizeof(struct sadb_lifetime); | |
2873 | if (sav->lft_h != NULL) | |
2874 | len += sizeof(struct sadb_lifetime); | |
2875 | if (sav->lft_s != NULL) | |
2876 | len += sizeof(struct sadb_lifetime); | |
2877 | ||
2878 | return len; | |
2879 | } | |
2880 | ||
2881 | /* | |
2882 | * validation with a secasvar entry, and set SADB_SATYPE_MATURE. | |
2883 | * OUT: 0: valid | |
2884 | * other: errno | |
2885 | */ | |
2886 | static int | |
2887 | key_mature(sav) | |
2888 | struct secasvar *sav; | |
2889 | { | |
2890 | int mature; | |
2891 | int checkmask = 0; /* 2^0: ealg 2^1: aalg 2^2: calg */ | |
2892 | int mustmask = 0; /* 2^0: ealg 2^1: aalg 2^2: calg */ | |
2893 | ||
2894 | mature = 0; | |
2895 | ||
2896 | /* check SPI value */ | |
2897 | if (ntohl(sav->spi) >= 0 && ntohl(sav->spi) <= 255) { | |
2898 | #if IPSEC_DEBUG | |
2899 | printf("key_mature: illegal range of SPI %d.\n", sav->spi); | |
2900 | #endif | |
2901 | return EINVAL; | |
2902 | } | |
2903 | ||
2904 | /* check satype */ | |
2905 | switch (sav->sah->saidx.proto) { | |
2906 | case IPPROTO_ESP: | |
2907 | /* check flags */ | |
2908 | if ((sav->flags & SADB_X_EXT_OLD) | |
2909 | && (sav->flags & SADB_X_EXT_DERIV)) { | |
2910 | #if IPSEC_DEBUG | |
2911 | printf("key_mature: " | |
2912 | "invalid flag (derived) given to old-esp.\n"); | |
2913 | #endif | |
2914 | return EINVAL; | |
2915 | } | |
2916 | checkmask = 3; | |
2917 | mustmask = 1; | |
2918 | break; | |
2919 | case IPPROTO_AH: | |
2920 | /* check flags */ | |
2921 | if (sav->flags & SADB_X_EXT_DERIV) { | |
2922 | #if IPSEC_DEBUG | |
2923 | printf("key_mature: " | |
2924 | "invalid flag (derived) given to AH SA.\n"); | |
2925 | #endif | |
2926 | return EINVAL; | |
2927 | } | |
2928 | if (sav->alg_enc != SADB_EALG_NONE) { | |
2929 | #if IPSEC_DEBUG | |
2930 | printf("key_mature: " | |
2931 | "protocol and algorithm mismated.\n"); | |
2932 | #endif | |
2933 | return(EINVAL); | |
2934 | } | |
2935 | checkmask = 2; | |
2936 | mustmask = 2; | |
2937 | break; | |
2938 | #if 1 /*nonstandard*/ | |
2939 | case IPPROTO_IPCOMP: | |
2940 | if (sav->alg_auth != SADB_AALG_NONE) { | |
2941 | #if IPSEC_DEBUG | |
2942 | printf("key_mature: " | |
2943 | "protocol and algorithm mismated.\n"); | |
2944 | #endif | |
2945 | return(EINVAL); | |
2946 | } | |
2947 | if ((sav->flags & SADB_X_EXT_RAWCPI) == 0 | |
2948 | && ntohl(sav->spi) >= 0x10000) { | |
2949 | #if IPSEC_DEBUG | |
2950 | printf("key_mature: invalid cpi for IPComp.\n"); | |
2951 | #endif | |
2952 | return(EINVAL); | |
2953 | } | |
2954 | checkmask = 4; | |
2955 | mustmask = 4; | |
2956 | break; | |
2957 | #endif | |
2958 | default: | |
2959 | #if IPSEC_DEBUG | |
2960 | printf("key_mature: Invalid satype.\n"); | |
2961 | #endif | |
2962 | return EPROTONOSUPPORT; | |
2963 | } | |
2964 | ||
2965 | /* check authentication algorithm */ | |
2966 | if ((checkmask & 2) != 0) { | |
2967 | struct ah_algorithm *algo; | |
2968 | int keylen; | |
2969 | ||
2970 | /* XXX: should use algorithm map to check. */ | |
2971 | switch (sav->alg_auth) { | |
2972 | case SADB_AALG_NONE: | |
2973 | case SADB_AALG_MD5HMAC: | |
2974 | case SADB_AALG_SHA1HMAC: | |
2975 | case SADB_AALG_MD5: | |
2976 | case SADB_AALG_SHA: | |
2977 | case SADB_AALG_NULL: | |
2978 | break; | |
2979 | default: | |
2980 | #if IPSEC_DEBUG | |
2981 | printf("key_mature: " | |
2982 | "unknown authentication algorithm.\n"); | |
2983 | #endif | |
2984 | return EINVAL; | |
2985 | } | |
2986 | ||
2987 | /* algorithm-dependent check */ | |
2988 | algo = &ah_algorithms[sav->alg_auth]; | |
2989 | ||
2990 | if (sav->key_auth) | |
2991 | keylen = sav->key_auth->sadb_key_bits; | |
2992 | else | |
2993 | keylen = 0; | |
2994 | if (keylen < algo->keymin || algo->keymax < keylen) { | |
2995 | #if IPSEC_DEBUG | |
2996 | printf("key_mature: invalid AH key length %d " | |
2997 | "(%d-%d allowed)\n", keylen, | |
2998 | algo->keymin, algo->keymax); | |
2999 | #endif | |
3000 | return EINVAL; | |
3001 | } | |
3002 | ||
3003 | if (algo->mature) { | |
3004 | if ((*algo->mature)(sav)) { | |
3005 | /* message generated in per-algorithm function*/ | |
3006 | return EINVAL; | |
3007 | } else | |
3008 | mature = SADB_SATYPE_AH; | |
3009 | } | |
3010 | ||
3011 | if ((mustmask & 2) != 0 && mature != SADB_SATYPE_AH) { | |
3012 | #if IPSEC_DEBUG | |
3013 | printf("key_mature: no satisfy algorithm for AH\n"); | |
3014 | #endif | |
3015 | return EINVAL; | |
3016 | } | |
3017 | } | |
3018 | ||
3019 | /* check encryption algorithm */ | |
3020 | if ((checkmask & 1) != 0) { | |
3021 | #if IPSEC_ESP | |
3022 | struct esp_algorithm *algo; | |
3023 | int keylen; | |
3024 | ||
3025 | switch (sav->alg_enc) { | |
3026 | case SADB_EALG_NONE: | |
3027 | case SADB_EALG_DESCBC: | |
3028 | case SADB_EALG_3DESCBC: | |
3029 | case SADB_EALG_NULL: | |
3030 | case SADB_EALG_BLOWFISHCBC: | |
3031 | case SADB_EALG_CAST128CBC: | |
3032 | case SADB_EALG_RC5CBC: | |
3033 | break; | |
3034 | default: | |
3035 | #if IPSEC_DEBUG | |
3036 | printf("key_mature: unknown encryption algorithm.\n"); | |
3037 | #endif | |
3038 | return EINVAL; | |
3039 | } | |
3040 | ||
3041 | /* algorithm-dependent check */ | |
3042 | algo = &esp_algorithms[sav->alg_enc]; | |
3043 | ||
3044 | if (sav->key_enc) | |
3045 | keylen = sav->key_enc->sadb_key_bits; | |
3046 | else | |
3047 | keylen = 0; | |
3048 | if (keylen < algo->keymin || algo->keymax < keylen) { | |
3049 | #if IPSEC_DEBUG | |
3050 | printf("key_mature: invalid ESP key length %d " | |
3051 | "(%d-%d allowed)\n", keylen, | |
3052 | algo->keymin, algo->keymax); | |
3053 | #endif | |
3054 | return EINVAL; | |
3055 | } | |
3056 | ||
3057 | if (algo->mature) { | |
3058 | if ((*algo->mature)(sav)) { | |
3059 | /* message generated in per-algorithm function*/ | |
3060 | return EINVAL; | |
3061 | } else | |
3062 | mature = SADB_SATYPE_ESP; | |
3063 | } | |
3064 | ||
3065 | if ((mustmask & 1) != 0 && mature != SADB_SATYPE_ESP) { | |
3066 | #if IPSEC_DEBUG | |
3067 | printf("key_mature: no satisfy algorithm for ESP\n"); | |
3068 | #endif | |
3069 | return EINVAL; | |
3070 | } | |
3071 | #else /*IPSEC_ESP*/ | |
3072 | #if IPSEC_DEBUG | |
3073 | printf("key_mature: ESP not supported in this configuration\n"); | |
3074 | #endif | |
3075 | return EINVAL; | |
3076 | #endif | |
3077 | } | |
3078 | ||
3079 | /* check compression algorithm */ | |
3080 | if ((checkmask & 4) != 0) { | |
3081 | struct ipcomp_algorithm *algo; | |
3082 | ||
3083 | switch (sav->alg_enc) { | |
3084 | case SADB_X_CALG_NONE: | |
3085 | case SADB_X_CALG_OUI: | |
3086 | case SADB_X_CALG_DEFLATE: | |
3087 | case SADB_X_CALG_LZS: | |
3088 | break; | |
3089 | default: | |
3090 | #if IPSEC_DEBUG | |
3091 | printf("key_mature: unknown compression algorithm.\n"); | |
3092 | #endif | |
3093 | return EINVAL; | |
3094 | } | |
3095 | ||
3096 | /* algorithm-dependent check */ | |
3097 | algo = &ipcomp_algorithms[sav->alg_enc]; | |
3098 | ||
3099 | if (!(algo->compress && algo->decompress)) { | |
3100 | #if IPSEC_DEBUG | |
3101 | printf("key_mature: " | |
3102 | "unsupported compression algorithm.\n"); | |
3103 | #endif | |
3104 | return EINVAL; | |
3105 | } | |
3106 | } | |
3107 | ||
3108 | key_sa_chgstate(sav, SADB_SASTATE_MATURE); | |
3109 | ||
3110 | return 0; | |
3111 | } | |
3112 | ||
3113 | /* | |
3114 | * subroutine for SADB_GET and SADB_DUMP. | |
3115 | * the buf must be allocated sufficent space. | |
3116 | */ | |
3117 | static u_int | |
3118 | key_setdumpsa(newmsg, sav, type, satype, seq, pid) | |
3119 | struct sadb_msg *newmsg; | |
3120 | struct secasvar *sav; | |
3121 | u_int8_t type, satype; | |
3122 | u_int32_t seq, pid; | |
3123 | { | |
3124 | u_int tlen; | |
3125 | caddr_t p; | |
3126 | int i; | |
3127 | ||
3128 | tlen = key_getmsglen(sav); | |
3129 | ||
3130 | p = key_setsadbmsg((caddr_t)newmsg, type, tlen, | |
3131 | satype, seq, pid, | |
3132 | sav->sah->saidx.mode, sav->sah->saidx.reqid, | |
3133 | 0, sav->refcnt); | |
3134 | ||
3135 | for (i = 1; i <= SADB_EXT_MAX; i++) { | |
3136 | switch (i) { | |
3137 | case SADB_EXT_SA: | |
3138 | p = key_setsadbsa(p, sav); | |
3139 | break; | |
3140 | ||
3141 | case SADB_EXT_ADDRESS_SRC: | |
3142 | p = key_setsadbaddr(p, | |
3143 | SADB_EXT_ADDRESS_SRC, | |
3144 | (struct sockaddr *)&sav->sah->saidx.src, | |
3145 | _INALENBYAF(sav->sah->saidx.src.ss_family) << 3, | |
3146 | IPSEC_ULPROTO_ANY); | |
3147 | break; | |
3148 | ||
3149 | case SADB_EXT_ADDRESS_DST: | |
3150 | p = key_setsadbaddr(p, | |
3151 | SADB_EXT_ADDRESS_DST, | |
3152 | (struct sockaddr *)&sav->sah->saidx.dst, | |
3153 | _INALENBYAF(sav->sah->saidx.dst.ss_family) << 3, | |
3154 | IPSEC_ULPROTO_ANY); | |
3155 | break; | |
3156 | ||
3157 | case SADB_EXT_KEY_AUTH: | |
3158 | { | |
3159 | u_int len; | |
3160 | if (sav->key_auth == NULL) break; | |
3161 | len = sav->key_auth->sadb_key_len; /* real length */ | |
3162 | bcopy((caddr_t)sav->key_auth, p, len); | |
3163 | ((struct sadb_ext *)p)->sadb_ext_len = PFKEY_UNIT64(len); | |
3164 | p += len; | |
3165 | } | |
3166 | break; | |
3167 | ||
3168 | case SADB_EXT_KEY_ENCRYPT: | |
3169 | { | |
3170 | u_int len; | |
3171 | if (sav->key_enc == NULL) break; | |
3172 | len = sav->key_enc->sadb_key_len; /* real length */ | |
3173 | bcopy((caddr_t)sav->key_enc, p, len); | |
3174 | ((struct sadb_ext *)p)->sadb_ext_len = PFKEY_UNIT64(len); | |
3175 | p += len; | |
3176 | } | |
3177 | break;; | |
3178 | ||
3179 | case SADB_EXT_LIFETIME_CURRENT: | |
3180 | if (sav->lft_c == NULL) break; | |
3181 | p = key_setsadbext(p, (caddr_t)sav->lft_c); | |
3182 | break; | |
3183 | ||
3184 | case SADB_EXT_LIFETIME_HARD: | |
3185 | if (sav->lft_h == NULL) break; | |
3186 | p = key_setsadbext(p, (caddr_t)sav->lft_h); | |
3187 | break; | |
3188 | ||
3189 | case SADB_EXT_LIFETIME_SOFT: | |
3190 | if (sav->lft_s == NULL) break; | |
3191 | p = key_setsadbext(p, (caddr_t)sav->lft_s); | |
3192 | break; | |
3193 | ||
3194 | case SADB_EXT_IDENTITY_SRC: | |
3195 | case SADB_EXT_IDENTITY_DST: | |
3196 | /* XXX: should we brought from SPD ? */ | |
3197 | case SADB_EXT_SENSITIVITY: | |
3198 | default: | |
3199 | break; | |
3200 | } | |
3201 | } | |
3202 | ||
3203 | return tlen; | |
3204 | } | |
3205 | ||
3206 | #if 1 | |
3207 | static int | |
3208 | key_setsadbmsg_m(m, type, tlen, satype, seq, pid, mode, reqid, | |
3209 | reserved1, reserved2) | |
3210 | struct mbuf *m; | |
3211 | u_int8_t type, satype; | |
3212 | u_int16_t tlen; | |
3213 | u_int32_t seq; | |
3214 | pid_t pid; | |
3215 | u_int8_t mode; | |
3216 | u_int32_t reqid; | |
3217 | u_int8_t reserved1; | |
3218 | u_int32_t reserved2; | |
3219 | { | |
3220 | caddr_t p; | |
3221 | const size_t len = sizeof(struct sadb_msg); | |
3222 | ||
3223 | p = key_appendmbuf(m, len); | |
3224 | if (p == NULL) | |
3225 | return ENOBUFS; | |
3226 | ||
3227 | if (key_setsadbmsg(p, type, tlen, satype, seq, pid, mode, reqid, | |
3228 | reserved1, reserved2)) | |
3229 | return 0; | |
3230 | else | |
3231 | return EINVAL; | |
3232 | } | |
3233 | #endif | |
3234 | ||
3235 | /* | |
3236 | * set data into sadb_msg. | |
3237 | * `buf' must has been allocated sufficiently. | |
3238 | */ | |
3239 | static caddr_t | |
3240 | key_setsadbmsg(buf, type, tlen, satype, seq, pid, mode, reqid, | |
3241 | reserved1, reserved2) | |
3242 | caddr_t buf; | |
3243 | u_int8_t type, satype; | |
3244 | u_int16_t tlen; | |
3245 | u_int32_t seq; | |
3246 | pid_t pid; | |
3247 | u_int8_t mode; | |
3248 | u_int32_t reqid; | |
3249 | u_int8_t reserved1; | |
3250 | u_int32_t reserved2; | |
3251 | { | |
3252 | struct sadb_msg *p; | |
3253 | u_int len; | |
3254 | ||
3255 | p = (struct sadb_msg *)buf; | |
3256 | len = sizeof(struct sadb_msg); | |
3257 | ||
3258 | bzero(p, len); | |
3259 | p->sadb_msg_version = PF_KEY_V2; | |
3260 | p->sadb_msg_type = type; | |
3261 | p->sadb_msg_errno = 0; | |
3262 | p->sadb_msg_satype = satype; | |
3263 | p->sadb_msg_len = PFKEY_UNIT64(tlen); | |
3264 | p->sadb_msg_mode = mode; | |
3265 | p->sadb_msg_reserved1 = reserved1; | |
3266 | p->sadb_msg_seq = seq; | |
3267 | p->sadb_msg_pid = (u_int32_t)pid; | |
3268 | p->sadb_msg_reqid = reqid; | |
3269 | p->sadb_msg_reserved2 = reserved2; | |
3270 | ||
3271 | return(buf + len); | |
3272 | } | |
3273 | ||
3274 | /* | |
3275 | * copy secasvar data into sadb_address. | |
3276 | * `buf' must has been allocated sufficiently. | |
3277 | */ | |
3278 | static caddr_t | |
3279 | key_setsadbsa(buf, sav) | |
3280 | caddr_t buf; | |
3281 | struct secasvar *sav; | |
3282 | { | |
3283 | struct sadb_sa *p; | |
3284 | u_int len; | |
3285 | ||
3286 | p = (struct sadb_sa *)buf; | |
3287 | len = sizeof(struct sadb_sa); | |
3288 | ||
3289 | bzero(p, len); | |
3290 | p->sadb_sa_len = PFKEY_UNIT64(len); | |
3291 | p->sadb_sa_exttype = SADB_EXT_SA; | |
3292 | p->sadb_sa_spi = sav->spi; | |
3293 | p->sadb_sa_replay = (sav->replay != NULL ? sav->replay->wsize : 0); | |
3294 | p->sadb_sa_state = sav->state; | |
3295 | p->sadb_sa_auth = sav->alg_auth; | |
3296 | p->sadb_sa_encrypt = sav->alg_enc; | |
3297 | p->sadb_sa_flags = sav->flags; | |
3298 | ||
3299 | return(buf + len); | |
3300 | } | |
3301 | ||
3302 | #if 1 | |
3303 | static int | |
3304 | key_setsadbaddr_m(m, exttype, saddr, prefixlen, ul_proto) | |
3305 | struct mbuf *m; | |
3306 | u_int16_t exttype; | |
3307 | struct sockaddr *saddr; | |
3308 | u_int8_t prefixlen; | |
3309 | u_int16_t ul_proto; | |
3310 | { | |
3311 | caddr_t p; | |
3312 | const size_t len = | |
3313 | sizeof(struct sadb_address) + PFKEY_ALIGN8(saddr->sa_len); | |
3314 | ||
3315 | p = key_appendmbuf(m, len); | |
3316 | if (p == NULL) | |
3317 | return ENOBUFS; | |
3318 | ||
3319 | if (key_setsadbaddr(p, exttype, saddr, prefixlen, ul_proto)) | |
3320 | return 0; | |
3321 | else | |
3322 | return EINVAL; | |
3323 | } | |
3324 | #endif | |
3325 | ||
3326 | /* | |
3327 | * set data into sadb_address. | |
3328 | * `buf' must has been allocated sufficiently. | |
3329 | */ | |
3330 | static caddr_t | |
3331 | key_setsadbaddr(buf, exttype, saddr, prefixlen, ul_proto) | |
3332 | caddr_t buf; | |
3333 | u_int16_t exttype; | |
3334 | struct sockaddr *saddr; | |
3335 | u_int8_t prefixlen; | |
3336 | u_int16_t ul_proto; | |
3337 | { | |
3338 | struct sadb_address *p; | |
3339 | size_t len; | |
3340 | ||
3341 | p = (struct sadb_address *)buf; | |
3342 | len = sizeof(struct sadb_address) + PFKEY_ALIGN8(saddr->sa_len); | |
3343 | ||
3344 | bzero(p, len); | |
3345 | p->sadb_address_len = PFKEY_UNIT64(len); | |
3346 | p->sadb_address_exttype = exttype; | |
3347 | p->sadb_address_proto = ul_proto; | |
3348 | p->sadb_address_prefixlen = prefixlen; | |
3349 | p->sadb_address_reserved = 0; | |
3350 | ||
3351 | bcopy(saddr, p + 1, saddr->sa_len); | |
3352 | ||
3353 | return(buf + len); | |
3354 | } | |
3355 | ||
3356 | /* | |
3357 | * set data into sadb_ident. | |
3358 | * `buf' must has been allocated sufficiently. | |
3359 | */ | |
3360 | static caddr_t | |
3361 | key_setsadbident(buf, exttype, idtype, string, stringlen, id) | |
3362 | caddr_t buf; | |
3363 | u_int16_t exttype, idtype; | |
3364 | caddr_t string; | |
3365 | int stringlen; | |
3366 | u_int64_t id; | |
3367 | { | |
3368 | struct sadb_ident *p; | |
3369 | u_int len; | |
3370 | ||
3371 | p = (struct sadb_ident *)buf; | |
3372 | len = sizeof(struct sadb_ident) + PFKEY_ALIGN8(stringlen); | |
3373 | ||
3374 | bzero(p, len); | |
3375 | p->sadb_ident_len = PFKEY_UNIT64(len); | |
3376 | p->sadb_ident_exttype = exttype; | |
3377 | p->sadb_ident_type = idtype; | |
3378 | p->sadb_ident_reserved = 0; | |
3379 | p->sadb_ident_id = id; | |
3380 | ||
3381 | bcopy(string, p + 1, stringlen); | |
3382 | ||
3383 | return(buf + len); | |
3384 | } | |
3385 | ||
3386 | /* | |
3387 | * set data into sadb_x_policy | |
3388 | * `buf' must has been allocated sufficiently. | |
3389 | */ | |
3390 | static caddr_t | |
3391 | key_setsadbxpolicy(buf, type, dir, id) | |
3392 | caddr_t buf; | |
3393 | u_int16_t type; | |
3394 | u_int8_t dir; | |
3395 | u_int32_t id; | |
3396 | { | |
3397 | struct sadb_x_policy *p; | |
3398 | u_int len; | |
3399 | ||
3400 | p = (struct sadb_x_policy *)buf; | |
3401 | len = sizeof(struct sadb_x_policy); | |
3402 | ||
3403 | bzero(p, len); | |
3404 | p->sadb_x_policy_len = PFKEY_UNIT64(len); | |
3405 | p->sadb_x_policy_exttype = SADB_X_EXT_POLICY; | |
3406 | p->sadb_x_policy_type = type; | |
3407 | p->sadb_x_policy_dir = dir; | |
3408 | p->sadb_x_policy_id = id; | |
3409 | ||
3410 | return(buf + len); | |
3411 | } | |
3412 | ||
3413 | /* | |
3414 | * copy buffer of any sadb extension type into sadb_ext. | |
3415 | * assume that sadb_ext_len shifted down >> 3. | |
3416 | * i.e. shift length up when setting length of extension. | |
3417 | */ | |
3418 | static caddr_t | |
3419 | key_setsadbext(p, ext) | |
3420 | caddr_t p, ext; | |
3421 | { | |
3422 | u_int len; | |
3423 | ||
3424 | len = PFKEY_UNUNIT64(((struct sadb_ext *)ext)->sadb_ext_len); | |
3425 | ||
3426 | bcopy(ext, p, len); | |
3427 | ||
3428 | return(p + len); | |
3429 | } | |
3430 | ||
3431 | /* %%% utilities */ | |
3432 | /* | |
3433 | * copy a buffer into the new buffer allocated. | |
3434 | */ | |
3435 | static void * | |
3436 | key_newbuf(src, len) | |
3437 | void *src; | |
3438 | u_int len; | |
3439 | { | |
3440 | caddr_t new; | |
3441 | ||
3442 | KMALLOC(new, caddr_t, len); | |
3443 | if (new == NULL) { | |
3444 | #if IPSEC_DEBUG | |
3445 | printf("key_newbuf: No more memory.\n"); | |
3446 | #endif | |
3447 | return NULL; | |
3448 | } | |
3449 | bcopy((caddr_t)src, new, len); | |
3450 | ||
3451 | return new; | |
3452 | } | |
3453 | ||
3454 | /* compare my own address | |
3455 | * OUT: 1: true, i.e. my address. | |
3456 | * 0: false | |
3457 | */ | |
3458 | int | |
3459 | key_ismyaddr(family, addr) | |
3460 | u_int family; | |
3461 | caddr_t addr; | |
3462 | { | |
3463 | /* sanity check */ | |
3464 | if (addr == NULL) | |
3465 | panic("key_ismyaddr: NULL pointer is passed.\n"); | |
3466 | ||
3467 | switch (family) { | |
3468 | case AF_INET: | |
3469 | { | |
3470 | struct in_ifaddr *ia; | |
3471 | ||
3472 | #ifdef __NetBSD__ | |
3473 | for (ia = in_ifaddr.tqh_first; ia; ia = ia->ia_list.tqe_next) | |
3474 | #elif defined(__FreeBSD__) && __FreeBSD__ >= 3 || defined (__APPLE__) | |
3475 | for (ia = in_ifaddrhead.tqh_first; ia; | |
3476 | ia = ia->ia_link.tqe_next) | |
3477 | #else | |
3478 | for (ia = in_ifaddr; ia; ia = ia->ia_next) | |
3479 | #endif | |
3480 | if (bcmp(addr, | |
3481 | (caddr_t)&ia->ia_addr.sin_addr, | |
3482 | _INALENBYAF(family)) == 0) | |
3483 | return 1; | |
3484 | } | |
3485 | break; | |
3486 | #if INET6 | |
3487 | case AF_INET6: | |
3488 | return key_ismyaddr6(addr); | |
3489 | #endif | |
3490 | } | |
3491 | ||
3492 | return 0; | |
3493 | } | |
3494 | ||
3495 | #if INET6 | |
3496 | /* | |
3497 | * compare my own address for IPv6. | |
3498 | * 1: ours | |
3499 | * 0: other | |
3500 | * NOTE: derived ip6_input() in KAME. This is necessary to modify more. | |
3501 | */ | |
3502 | #include <netinet6/in6_var.h> | |
3503 | ||
3504 | static int | |
3505 | key_ismyaddr6(addr) | |
3506 | caddr_t addr; | |
3507 | { | |
3508 | struct in6_addr *a = (struct in6_addr *)addr; | |
3509 | struct in6_ifaddr *ia; | |
3510 | ||
3511 | for (ia = in6_ifaddr; ia; ia = ia->ia_next) { | |
3512 | if (bcmp(addr, (caddr_t)&ia->ia_addr.sin6_addr, | |
3513 | _INALENBYAF(AF_INET6)) == 0) { | |
3514 | return 1; | |
3515 | } | |
3516 | ||
3517 | /* XXX Multicast */ | |
3518 | { | |
3519 | struct in6_multi *in6m = 0; | |
3520 | ||
3521 | #if defined(__FreeBSD__) && __FreeBSD__ >= 3 || defined (__APPLE__) | |
3522 | IN6_LOOKUP_MULTI(*(struct in6_addr *)addr, ia->ia_ifp, in6m); | |
3523 | #else | |
3524 | for ((in6m) = ia->ia6_multiaddrs.lh_first; | |
3525 | (in6m) != NULL && | |
3526 | !IN6_ARE_ADDR_EQUAL(&(in6m)->in6m_addr, a); | |
3527 | (in6m) = in6m->in6m_entry.le_next) | |
3528 | continue; | |
3529 | #endif | |
3530 | if (in6m) | |
3531 | return 1; | |
3532 | } | |
3533 | } | |
3534 | ||
3535 | /* loopback, just for safety */ | |
3536 | if (IN6_IS_ADDR_LOOPBACK(a)) | |
3537 | return 1; | |
3538 | ||
3539 | #if 0 | |
3540 | /* FAITH */ | |
3541 | if (ip6_keepfaith && | |
3542 | (a->s6_addr32[0] == ip6_faith_prefix.s6_addr32[0] && | |
3543 | a->s6_addr32[1] == ip6_faith_prefix.s6_addr32[1] && | |
3544 | a->s6_addr32[2] == ip6_faith_prefix.s6_addr32[2])) | |
3545 | return 1; | |
3546 | #endif | |
3547 | ||
3548 | /* XXX anycast */ | |
3549 | ||
3550 | return 0; | |
3551 | } | |
3552 | #endif /*INET6*/ | |
3553 | ||
3554 | #if 0 | |
3555 | /* checking address is whether loopback or not. | |
3556 | * OUT: 1: true | |
3557 | * 0: false | |
3558 | */ | |
3559 | static int | |
3560 | key_isloopback(family, addr) | |
3561 | u_int family; | |
3562 | caddr_t addr; | |
3563 | { | |
3564 | switch (family) { | |
3565 | case PF_INET: | |
3566 | if (((caddr_t)addr)[0] == IN_LOOPBACKNET) | |
3567 | return 1; | |
3568 | break; | |
3569 | #if INET6 | |
3570 | case PF_INET6: | |
3571 | if (IN6_IS_ADDR_LOOPBACK((struct in6_addr *)addr)) | |
3572 | return 1; | |
3573 | break; | |
3574 | #endif /* INET6 */ | |
3575 | default: | |
3576 | #if IPSEC_DEBUG | |
3577 | printf("key_isloopback: unknown address family=%d.\n", family); | |
3578 | #endif | |
3579 | return 0; | |
3580 | } | |
3581 | ||
3582 | return 0; | |
3583 | } | |
3584 | #endif | |
3585 | ||
3586 | /* | |
3587 | * compare two secasindex structure exactly. | |
3588 | * IN: | |
3589 | * saidx0: source, it can be in SAD. | |
3590 | * saidx1: object. | |
3591 | * OUT: | |
3592 | * 1 : equal | |
3593 | * 0 : not equal | |
3594 | */ | |
3595 | static int | |
3596 | key_cmpsaidx_exactly(saidx0, saidx1) | |
3597 | struct secasindex *saidx0, *saidx1; | |
3598 | { | |
3599 | /* sanity */ | |
3600 | if (saidx0 == NULL && saidx1 == NULL) | |
3601 | return 1; | |
3602 | ||
3603 | if (saidx0 == NULL || saidx1 == NULL) | |
3604 | return 0; | |
3605 | ||
3606 | if (saidx0->proto != saidx1->proto | |
3607 | || saidx0->mode != saidx1->mode | |
3608 | || saidx0->reqid != saidx1->reqid) | |
3609 | return 0; | |
3610 | ||
3611 | if (bcmp(&saidx0->src, &saidx1->src, saidx0->src.ss_len) != 0 | |
3612 | || bcmp(&saidx0->dst, &saidx1->dst, saidx0->dst.ss_len) != 0) | |
3613 | return 0; | |
3614 | ||
3615 | return 1; | |
3616 | } | |
3617 | ||
3618 | /* | |
3619 | * compare two secasindex structure with consideration mode. | |
3620 | * don't compare port. | |
3621 | * IN: | |
3622 | * saidx0: source, it is often in SAD. | |
3623 | * saidx1: object, it is often from SPD. | |
3624 | * OUT: | |
3625 | * 1 : equal | |
3626 | * 0 : not equal | |
3627 | */ | |
3628 | static int | |
3629 | key_cmpsaidx_withmode(saidx0, saidx1) | |
3630 | struct secasindex *saidx0, *saidx1; | |
3631 | { | |
3632 | /* sanity */ | |
3633 | if (saidx0 == NULL && saidx1 == NULL) | |
3634 | return 1; | |
3635 | ||
3636 | if (saidx0 == NULL || saidx1 == NULL) | |
3637 | return 0; | |
3638 | ||
3639 | if (saidx0->proto != saidx1->proto | |
3640 | || saidx0->src.ss_family != saidx1->src.ss_family | |
3641 | || saidx0->dst.ss_family != saidx1->dst.ss_family) | |
3642 | return 0; | |
3643 | ||
3644 | /* | |
3645 | * If reqid of SPD is non-zero, unique SA is required. | |
3646 | * The result must be of same reqid in this case. | |
3647 | */ | |
3648 | if (saidx1->reqid != 0 | |
3649 | && saidx0->reqid != saidx1->reqid) | |
3650 | return 0; | |
3651 | ||
3652 | if (saidx0->mode != IPSEC_MODE_ANY | |
3653 | && saidx0->mode != saidx1->mode) | |
3654 | return 0; | |
3655 | ||
3656 | { | |
3657 | int sa_len = _INALENBYAF(saidx0->src.ss_family); | |
3658 | ||
3659 | if (bcmp(_INADDRBYSA(&saidx0->src), _INADDRBYSA(&saidx1->src), sa_len) | |
3660 | || bcmp(_INADDRBYSA(&saidx0->dst), _INADDRBYSA(&saidx1->dst), sa_len)) | |
3661 | return 0; | |
3662 | } | |
3663 | ||
3664 | return 1; | |
3665 | } | |
3666 | ||
3667 | /* | |
3668 | * compare two secindex structure exactly. | |
3669 | * IN: | |
3670 | * spidx0: source, it is often in SPD. | |
3671 | * spidx1: object, it is often from PFKEY message. | |
3672 | * OUT: | |
3673 | * 1 : equal | |
3674 | * 0 : not equal | |
3675 | */ | |
3676 | static int | |
3677 | key_cmpspidx_exactly(spidx0, spidx1) | |
3678 | struct secpolicyindex *spidx0, *spidx1; | |
3679 | { | |
3680 | /* sanity */ | |
3681 | if (spidx0 == NULL && spidx1 == NULL) | |
3682 | return 1; | |
3683 | ||
3684 | if (spidx0 == NULL || spidx1 == NULL) | |
3685 | return 0; | |
3686 | ||
3687 | if (spidx0->prefs != spidx1->prefs | |
3688 | || spidx0->prefd != spidx1->prefd | |
3689 | || spidx0->ul_proto != spidx1->ul_proto) | |
3690 | return 0; | |
3691 | ||
3692 | if (bcmp(&spidx0->src, &spidx1->src, spidx0->src.ss_len) != 0 | |
3693 | || bcmp(&spidx0->dst, &spidx1->dst, spidx0->dst.ss_len) != 0) | |
3694 | return 0; | |
3695 | ||
3696 | return 1; | |
3697 | } | |
3698 | ||
3699 | /* | |
3700 | * compare two secindex structure with mask. | |
3701 | * IN: | |
3702 | * spidx0: source, it is often in SPD. | |
3703 | * spidx1: object, it is often from IP header. | |
3704 | * OUT: | |
3705 | * 1 : equal | |
3706 | * 0 : not equal | |
3707 | */ | |
3708 | static int | |
3709 | key_cmpspidx_withmask(spidx0, spidx1) | |
3710 | struct secpolicyindex *spidx0, *spidx1; | |
3711 | { | |
3712 | /* sanity */ | |
3713 | if (spidx0 == NULL && spidx1 == NULL) | |
3714 | return 1; | |
3715 | ||
3716 | if (spidx0 == NULL || spidx1 == NULL) | |
3717 | return 0; | |
3718 | ||
3719 | if (spidx0->src.ss_family != spidx1->src.ss_family | |
3720 | || spidx0->dst.ss_family != spidx1->dst.ss_family) | |
3721 | return 0; | |
3722 | ||
3723 | /* if spidx.ul_proto == IPSEC_ULPROTO_ANY, ignore. */ | |
3724 | if (spidx0->ul_proto != (u_int16_t)IPSEC_ULPROTO_ANY | |
3725 | && spidx0->ul_proto != spidx1->ul_proto) | |
3726 | return 0; | |
3727 | ||
3728 | if (_INPORTBYSA(&spidx0->src) != IPSEC_PORT_ANY | |
3729 | && _INPORTBYSA(&spidx0->src) != _INPORTBYSA(&spidx1->src)) | |
3730 | return 0; | |
3731 | ||
3732 | if (_INPORTBYSA(&spidx0->dst) != IPSEC_PORT_ANY | |
3733 | && _INPORTBYSA(&spidx0->dst) != _INPORTBYSA(&spidx1->dst)) | |
3734 | return 0; | |
3735 | ||
3736 | if (!key_bbcmp(_INADDRBYSA(&spidx0->src), | |
3737 | _INADDRBYSA(&spidx1->src), | |
3738 | spidx0->prefs)) | |
3739 | return 0; | |
3740 | ||
3741 | if (!key_bbcmp(_INADDRBYSA(&spidx0->dst), | |
3742 | _INADDRBYSA(&spidx1->dst), | |
3743 | spidx0->prefd)) | |
3744 | return 0; | |
3745 | ||
3746 | /* XXX Do we check other field ? e.g. flowinfo, scope_id. */ | |
3747 | ||
3748 | return 1; | |
3749 | } | |
3750 | ||
3751 | /* | |
3752 | * compare two buffers with mask. | |
3753 | * IN: | |
3754 | * addr1: source | |
3755 | * addr2: object | |
3756 | * bits: Number of bits to compare | |
3757 | * OUT: | |
3758 | * 1 : equal | |
3759 | * 0 : not equal | |
3760 | */ | |
3761 | static int | |
3762 | key_bbcmp(p1, p2, bits) | |
3763 | register caddr_t p1, p2; | |
3764 | register u_int bits; | |
3765 | { | |
3766 | u_int8_t mask; | |
3767 | ||
3768 | /* XXX: This could be considerably faster if we compare a word | |
3769 | * at a time, but it is complicated on LSB Endian machines */ | |
3770 | ||
3771 | /* Handle null pointers */ | |
3772 | if (p1 == NULL || p2 == NULL) | |
3773 | return (p1 == p2); | |
3774 | ||
3775 | while (bits >= 8) { | |
3776 | if (*p1++ != *p2++) | |
3777 | return 0; | |
3778 | bits -= 8; | |
3779 | } | |
3780 | ||
3781 | if (bits > 0) { | |
3782 | mask = ~((1<<(8-bits))-1); | |
3783 | if ((*p1 & mask) != (*p2 & mask)) | |
3784 | return 0; | |
3785 | } | |
3786 | return 1; /* Match! */ | |
3787 | } | |
3788 | ||
3789 | /* | |
3790 | * time handler. | |
3791 | * scanning SPD and SAD to check status for each entries, | |
3792 | * and do to remove or to expire. | |
3793 | */ | |
0b4e3aa0 A |
3794 | static void |
3795 | key_timehandler_funneled(void) | |
3796 | { | |
3797 | boolean_t funnel_state; | |
3798 | funnel_state = thread_funnel_set(network_flock, TRUE); | |
3799 | key_timehandler(); | |
3800 | (void) thread_funnel_set(network_flock, FALSE); | |
3801 | } | |
3802 | ||
1c79356b A |
3803 | void |
3804 | key_timehandler(void) | |
3805 | { | |
3806 | u_int dir; | |
3807 | int s; | |
3808 | ||
0b4e3aa0 A |
3809 | boolean_t funnel_state; |
3810 | funnel_state = thread_funnel_set(network_flock, TRUE); | |
1c79356b A |
3811 | #if __NetBSD__ |
3812 | s = splsoftnet(); /*called from softclock()*/ | |
3813 | #else | |
3814 | s = splnet(); /*called from softclock()*/ | |
3815 | #endif | |
3816 | ||
3817 | /* SPD */ | |
3818 | { | |
3819 | struct secpolicy *sp, *nextsp; | |
3820 | ||
3821 | for (dir = 0; dir < IPSEC_DIR_MAX; dir++) { | |
3822 | for (sp = LIST_FIRST(&sptree[dir]); | |
3823 | sp != NULL; | |
3824 | sp = nextsp) { | |
3825 | ||
3826 | nextsp = LIST_NEXT(sp, chain); | |
3827 | ||
3828 | if (sp->state == IPSEC_SPSTATE_DEAD) | |
3829 | key_freesp(sp); | |
3830 | } | |
3831 | } | |
3832 | } | |
3833 | ||
3834 | /* SAD */ | |
3835 | { | |
3836 | struct secashead *sah, *nextsah; | |
3837 | struct secasvar *sav, *nextsav; | |
3838 | ||
3839 | for (sah = LIST_FIRST(&sahtree); | |
3840 | sah != NULL; | |
3841 | sah = nextsah) { | |
3842 | ||
3843 | nextsah = LIST_NEXT(sah, chain); | |
3844 | ||
3845 | /* if sah has been dead, then delete it and process next sah. */ | |
3846 | if (sah->state == SADB_SASTATE_DEAD) { | |
3847 | key_delsah(sah); | |
3848 | continue; | |
3849 | } | |
3850 | ||
3851 | /* if LARVAL entry doesn't become MATURE, delete it. */ | |
3852 | for (sav = LIST_FIRST(&sah->savtree[SADB_SASTATE_LARVAL]); | |
3853 | sav != NULL; | |
3854 | sav = nextsav) { | |
3855 | ||
3856 | nextsav = LIST_NEXT(sav, chain); | |
3857 | ||
3858 | sav->tick++; | |
3859 | ||
3860 | if (key_larval_lifetime < sav->tick) { | |
3861 | key_freesav(sav); | |
3862 | } | |
3863 | } | |
3864 | ||
3865 | /* | |
3866 | * check MATURE entry to start to send expire message | |
3867 | * whether or not. | |
3868 | */ | |
3869 | for (sav = LIST_FIRST(&sah->savtree[SADB_SASTATE_MATURE]); | |
3870 | sav != NULL; | |
3871 | sav = nextsav) { | |
3872 | ||
3873 | nextsav = LIST_NEXT(sav, chain); | |
3874 | ||
3875 | sav->tick++; | |
3876 | ||
3877 | /* we don't need to check. */ | |
3878 | if (sav->lft_s == NULL) | |
3879 | continue; | |
3880 | ||
3881 | /* sanity check */ | |
3882 | if (sav->lft_c == NULL) { | |
3883 | #if IPSEC_DEBUG | |
3884 | printf("key_timehandler: " | |
3885 | "There is no CURRENT time, why?\n"); | |
3886 | #endif | |
3887 | continue; | |
3888 | } | |
3889 | ||
3890 | /* compare SOFT lifetime and tick */ | |
3891 | if (sav->lft_s->sadb_lifetime_addtime != 0 | |
3892 | && sav->lft_s->sadb_lifetime_addtime < sav->tick) { | |
3893 | /* | |
3894 | * check SA to be used whether or not. | |
3895 | * when SA hasn't been used, delete it. | |
3896 | */ | |
3897 | if (sav->lft_c->sadb_lifetime_usetime == 0) { | |
3898 | key_sa_chgstate(sav, SADB_SASTATE_DEAD); | |
3899 | key_freesav(sav); | |
3900 | sav = NULL; | |
3901 | } else { | |
3902 | key_sa_chgstate(sav, SADB_SASTATE_DYING); | |
3903 | /* | |
3904 | * XXX If we keep to send expire | |
3905 | * message in the status of | |
3906 | * DYING. Do remove below code. | |
3907 | */ | |
3908 | key_expire(sav); | |
3909 | } | |
3910 | } | |
3911 | /* check SOFT lifetime by bytes */ | |
3912 | /* | |
3913 | * XXX I don't know the way to delete this SA | |
3914 | * when new SA is installed. Caution when it's | |
3915 | * installed too big lifetime by time. | |
3916 | */ | |
3917 | else if (sav->lft_s->sadb_lifetime_bytes != 0 | |
3918 | && sav->lft_s->sadb_lifetime_bytes < sav->lft_c->sadb_lifetime_bytes) { | |
3919 | ||
3920 | key_sa_chgstate(sav, SADB_SASTATE_DYING); | |
3921 | /* | |
3922 | * XXX If we keep to send expire | |
3923 | * message in the status of | |
3924 | * DYING. Do remove below code. | |
3925 | */ | |
3926 | key_expire(sav); | |
3927 | } | |
3928 | } | |
3929 | ||
3930 | /* check DYING entry to change status to DEAD. */ | |
3931 | for (sav = LIST_FIRST(&sah->savtree[SADB_SASTATE_DYING]); | |
3932 | sav != NULL; | |
3933 | sav = nextsav) { | |
3934 | ||
3935 | nextsav = LIST_NEXT(sav, chain); | |
3936 | ||
3937 | sav->tick++; | |
3938 | ||
3939 | /* we don't need to check. */ | |
3940 | if (sav->lft_h == NULL) | |
3941 | continue; | |
3942 | ||
3943 | /* sanity check */ | |
3944 | if (sav->lft_c == NULL) { | |
3945 | #if IPSEC_DEBUG | |
3946 | printf("key_timehandler: " | |
3947 | "There is no CURRENT time, why?\n"); | |
3948 | #endif | |
3949 | continue; | |
3950 | } | |
3951 | ||
3952 | /* compare HARD lifetime and tick */ | |
3953 | if (sav->lft_h->sadb_lifetime_addtime != 0 | |
3954 | && sav->lft_h->sadb_lifetime_addtime < sav->tick) { | |
3955 | key_sa_chgstate(sav, SADB_SASTATE_DEAD); | |
3956 | key_freesav(sav); | |
3957 | sav = NULL; | |
3958 | } | |
3959 | #if 0 /* XXX Should we keep to send expire message until HARD lifetime ? */ | |
3960 | else if (sav->lft_s != NULL | |
3961 | && sav->lft_s->sadb_lifetime_addtime != 0 | |
3962 | && sav->lft_s->sadb_lifetime_addtime < sav->tick) { | |
3963 | /* | |
3964 | * XXX: should be checked to be | |
3965 | * installed the valid SA. | |
3966 | */ | |
3967 | ||
3968 | /* | |
3969 | * If there is no SA then sending | |
3970 | * expire message. | |
3971 | */ | |
3972 | key_expire(sav); | |
3973 | } | |
3974 | #endif | |
3975 | /* check HARD lifetime by bytes */ | |
3976 | else if (sav->lft_h->sadb_lifetime_bytes != 0 | |
3977 | && sav->lft_h->sadb_lifetime_bytes < sav->lft_c->sadb_lifetime_bytes) { | |
3978 | key_sa_chgstate(sav, SADB_SASTATE_DEAD); | |
3979 | key_freesav(sav); | |
3980 | sav = NULL; | |
3981 | } | |
3982 | } | |
3983 | ||
3984 | /* delete entry in DEAD */ | |
3985 | for (sav = LIST_FIRST(&sah->savtree[SADB_SASTATE_DEAD]); | |
3986 | sav != NULL; | |
3987 | sav = nextsav) { | |
3988 | ||
3989 | nextsav = LIST_NEXT(sav, chain); | |
3990 | ||
3991 | /* sanity check */ | |
3992 | if (sav->state != SADB_SASTATE_DEAD) { | |
3993 | #if IPSEC_DEBUG | |
3994 | printf("key_timehandler: " | |
3995 | "invalid sav->state " | |
3996 | "(queue: %d SA: %d): " | |
3997 | "kill it anyway\n", | |
3998 | SADB_SASTATE_DEAD, sav->state); | |
3999 | #endif | |
4000 | } | |
4001 | ||
4002 | /* | |
4003 | * do not call key_freesav() here. | |
4004 | * sav should already be freed, and sav->refcnt | |
4005 | * shows other references to sav | |
4006 | * (such as from SPD). | |
4007 | */ | |
4008 | } | |
4009 | } | |
4010 | } | |
4011 | ||
4012 | #ifndef IPSEC_NONBLOCK_ACQUIRE | |
4013 | /* ACQ tree */ | |
4014 | { | |
4015 | struct secacq *acq, *nextacq; | |
4016 | ||
4017 | for (acq = LIST_FIRST(&acqtree); | |
4018 | acq != NULL; | |
4019 | acq = nextacq) { | |
4020 | ||
4021 | nextacq = LIST_NEXT(acq, chain); | |
4022 | ||
4023 | acq->tick++; | |
4024 | ||
4025 | if (key_blockacq_lifetime < acq->tick && __LIST_CHAINED(acq)) { | |
4026 | LIST_REMOVE(acq, chain); | |
4027 | KFREE(acq); | |
4028 | } | |
4029 | } | |
4030 | } | |
4031 | #endif | |
4032 | ||
4033 | /* SP ACQ tree */ | |
4034 | { | |
4035 | struct secspacq *acq, *nextacq; | |
4036 | ||
4037 | for (acq = LIST_FIRST(&spacqtree); | |
4038 | acq != NULL; | |
4039 | acq = nextacq) { | |
4040 | ||
4041 | nextacq = LIST_NEXT(acq, chain); | |
4042 | ||
4043 | acq->tick++; | |
4044 | ||
4045 | if (key_blockacq_lifetime < acq->tick && __LIST_CHAINED(acq)) { | |
4046 | LIST_REMOVE(acq, chain); | |
4047 | KFREE(acq); | |
4048 | } | |
4049 | } | |
4050 | } | |
4051 | ||
4052 | /* initialize random seed */ | |
4053 | if (key_tick_init_random++ > key_int_random) { | |
4054 | key_tick_init_random = 0; | |
4055 | key_srandom(); | |
4056 | } | |
4057 | ||
4058 | #ifndef IPSEC_DEBUG2 | |
4059 | /* do exchange to tick time !! */ | |
0b4e3aa0 | 4060 | (void)timeout((void *)key_timehandler_funneled, (void *)0, 100); |
1c79356b A |
4061 | #endif /* IPSEC_DEBUG2 */ |
4062 | ||
4063 | splx(s); | |
1c79356b A |
4064 | return; |
4065 | } | |
4066 | ||
4067 | /* | |
4068 | * to initialize a seed for random() | |
4069 | */ | |
4070 | void | |
4071 | key_srandom() | |
4072 | { | |
4073 | struct timeval tv; | |
4074 | #ifdef __bsdi__ | |
4075 | extern long randseed; /* it's defined at i386/i386/random.s */ | |
4076 | #endif /* __bsdi__ */ | |
4077 | ||
4078 | microtime(&tv); | |
4079 | ||
4080 | #if defined(__FreeBSD__) | |
4081 | srandom(tv.tv_usec); | |
4082 | #endif /* __FreeBSD__ */ | |
4083 | #if defined(__APPLE__) | |
4084 | random(); | |
4085 | #endif | |
4086 | #ifdef __bsdi__ | |
4087 | randseed = tv.tv_usec; | |
4088 | #endif /* __bsdi__ */ | |
4089 | ||
4090 | return; | |
4091 | } | |
4092 | ||
4093 | /* | |
4094 | * map SADB_SATYPE_* to IPPROTO_*. | |
4095 | * if satype == SADB_SATYPE then satype is mapped to ~0. | |
4096 | * OUT: | |
4097 | * 0: invalid satype. | |
4098 | */ | |
4099 | static u_int16_t | |
4100 | key_satype2proto(satype) | |
4101 | u_int8_t satype; | |
4102 | { | |
4103 | switch (satype) { | |
4104 | case SADB_SATYPE_UNSPEC: | |
4105 | return IPSEC_PROTO_ANY; | |
4106 | case SADB_SATYPE_AH: | |
4107 | return IPPROTO_AH; | |
4108 | case SADB_SATYPE_ESP: | |
4109 | return IPPROTO_ESP; | |
4110 | #if 1 /*nonstandard*/ | |
4111 | case SADB_X_SATYPE_IPCOMP: | |
4112 | return IPPROTO_IPCOMP; | |
4113 | break; | |
4114 | #endif | |
4115 | default: | |
4116 | return 0; | |
4117 | } | |
4118 | /* NOTREACHED */ | |
4119 | } | |
4120 | ||
4121 | /* | |
4122 | * map IPPROTO_* to SADB_SATYPE_* | |
4123 | * OUT: | |
4124 | * 0: invalid protocol type. | |
4125 | */ | |
4126 | static u_int8_t | |
4127 | key_proto2satype(proto) | |
4128 | u_int16_t proto; | |
4129 | { | |
4130 | switch (proto) { | |
4131 | case IPPROTO_AH: | |
4132 | return SADB_SATYPE_AH; | |
4133 | case IPPROTO_ESP: | |
4134 | return SADB_SATYPE_ESP; | |
4135 | #if 1 /*nonstandard*/ | |
4136 | case IPPROTO_IPCOMP: | |
4137 | return SADB_X_SATYPE_IPCOMP; | |
4138 | break; | |
4139 | #endif | |
4140 | default: | |
4141 | return 0; | |
4142 | } | |
4143 | /* NOTREACHED */ | |
4144 | } | |
4145 | ||
4146 | /* %%% PF_KEY */ | |
4147 | /* | |
4148 | * SADB_GETSPI processing is to receive | |
4149 | * <base, src address, dst address, (SPI range)> | |
4150 | * from the IKMPd, to assign a unique spi value, to hang on the INBOUND | |
4151 | * tree with the status of LARVAL, and send | |
4152 | * <base, SA(*), address(SD)> | |
4153 | * to the IKMPd. | |
4154 | * | |
4155 | * IN: mhp: pointer to the pointer to each header. | |
4156 | * OUT: NULL if fail. | |
4157 | * other if success, return pointer to the message to send. | |
4158 | */ | |
4159 | static struct sadb_msg * | |
4160 | key_getspi(mhp) | |
4161 | caddr_t *mhp; | |
4162 | { | |
4163 | struct sadb_msg *msg0; | |
4164 | struct sadb_address *src0, *dst0; | |
4165 | struct secasindex saidx; | |
4166 | struct secashead *newsah; | |
4167 | struct secasvar *newsav; | |
4168 | u_int8_t proto; | |
4169 | u_int32_t spi; | |
4170 | ||
4171 | /* sanity check */ | |
4172 | if (mhp == NULL || mhp[0] == NULL) | |
4173 | panic("key_getspi: NULL pointer is passed.\n"); | |
4174 | ||
4175 | msg0 = (struct sadb_msg *)mhp[0]; | |
4176 | ||
4177 | if (mhp[SADB_EXT_ADDRESS_SRC] == NULL | |
4178 | || mhp[SADB_EXT_ADDRESS_DST] == NULL) { | |
4179 | #if IPSEC_DEBUG | |
4180 | printf("key_getspi: invalid message is passed.\n"); | |
4181 | #endif | |
4182 | msg0->sadb_msg_errno = EINVAL; | |
4183 | return NULL; | |
4184 | } | |
4185 | ||
4186 | src0 = (struct sadb_address *)(mhp[SADB_EXT_ADDRESS_SRC]); | |
4187 | dst0 = (struct sadb_address *)(mhp[SADB_EXT_ADDRESS_DST]); | |
4188 | ||
4189 | /* map satype to proto */ | |
4190 | if ((proto = key_satype2proto(msg0->sadb_msg_satype)) == 0) { | |
4191 | #if IPSEC_DEBUG | |
4192 | printf("key_getspi: invalid satype is passed.\n"); | |
4193 | #endif | |
4194 | msg0->sadb_msg_errno = EINVAL; | |
4195 | return NULL; | |
4196 | } | |
4197 | ||
4198 | KEY_SETSECASIDX(proto, msg0, src0+1, dst0+1, &saidx); | |
4199 | ||
4200 | /* SPI allocation */ | |
4201 | spi = key_do_getnewspi((struct sadb_spirange *)mhp[SADB_EXT_SPIRANGE], | |
4202 | &saidx); | |
4203 | if (spi == 0) { | |
4204 | msg0->sadb_msg_errno = EEXIST; | |
4205 | return NULL; | |
4206 | } | |
4207 | ||
4208 | /* get a SA index */ | |
4209 | if ((newsah = key_getsah(&saidx)) == NULL) { | |
4210 | ||
4211 | /* create a new SA index */ | |
4212 | if ((newsah = key_newsah(&saidx)) == NULL) { | |
4213 | #if IPSEC_DEBUG | |
4214 | printf("key_getspi: No more memory.\n"); | |
4215 | #endif | |
4216 | msg0->sadb_msg_errno = ENOBUFS; | |
4217 | return NULL; | |
4218 | } | |
4219 | } | |
4220 | ||
4221 | /* get a new SA */ | |
4222 | if ((newsav = key_newsav(mhp, newsah)) == NULL) { | |
4223 | msg0->sadb_msg_errno = ENOBUFS; | |
4224 | /* XXX don't free new SA index allocated in above. */ | |
4225 | return NULL; | |
4226 | } | |
4227 | ||
4228 | /* set spi */ | |
4229 | newsav->spi = htonl(spi); | |
4230 | ||
4231 | #ifndef IPSEC_NONBLOCK_ACQUIRE | |
4232 | /* delete the entry in acqtree */ | |
4233 | if (msg0->sadb_msg_seq != 0) { | |
4234 | struct secacq *acq; | |
4235 | if ((acq = key_getacqbyseq(msg0->sadb_msg_seq)) != NULL) { | |
4236 | /* reset counter in order to deletion by timehander. */ | |
4237 | acq->tick = key_blockacq_lifetime; | |
4238 | acq->count = 0; | |
4239 | } | |
4240 | } | |
4241 | #endif | |
4242 | ||
4243 | { | |
4244 | struct sadb_msg *newmsg; | |
4245 | u_int len; | |
4246 | caddr_t p; | |
4247 | ||
4248 | /* create new sadb_msg to reply. */ | |
4249 | len = sizeof(struct sadb_msg) | |
4250 | + sizeof(struct sadb_sa) | |
4251 | + PFKEY_EXTLEN(mhp[SADB_EXT_ADDRESS_SRC]) | |
4252 | + PFKEY_EXTLEN(mhp[SADB_EXT_ADDRESS_DST]); | |
4253 | ||
4254 | KMALLOC(newmsg, struct sadb_msg *, len); | |
4255 | if (newmsg == NULL) { | |
4256 | #if IPSEC_DEBUG | |
4257 | printf("key_getspi: No more memory.\n"); | |
4258 | #endif | |
4259 | msg0->sadb_msg_errno = ENOBUFS; | |
4260 | return NULL; | |
4261 | } | |
4262 | bzero((caddr_t)newmsg, len); | |
4263 | ||
4264 | bcopy((caddr_t)mhp[0], (caddr_t)newmsg, sizeof(*msg0)); | |
4265 | newmsg->sadb_msg_seq = newsav->seq; | |
4266 | newmsg->sadb_msg_errno = 0; | |
4267 | newmsg->sadb_msg_len = PFKEY_UNIT64(len); | |
4268 | p = (caddr_t)newmsg + sizeof(*msg0); | |
4269 | ||
4270 | { | |
4271 | struct sadb_sa *m_sa; | |
4272 | m_sa = (struct sadb_sa *)p; | |
4273 | m_sa->sadb_sa_len = PFKEY_UNIT64(sizeof(struct sadb_sa)); | |
4274 | m_sa->sadb_sa_exttype = SADB_EXT_SA; | |
4275 | m_sa->sadb_sa_spi = htonl(spi); | |
4276 | p += sizeof(struct sadb_sa); | |
4277 | } | |
4278 | ||
4279 | p = key_setsadbext(p, mhp[SADB_EXT_ADDRESS_SRC]); | |
4280 | p = key_setsadbext(p, mhp[SADB_EXT_ADDRESS_DST]); | |
4281 | ||
4282 | return newmsg; | |
4283 | } | |
4284 | } | |
4285 | ||
4286 | /* | |
4287 | * allocating new SPI | |
4288 | * called by key_getspi(). | |
4289 | * OUT: | |
4290 | * 0: failure. | |
4291 | * others: success. | |
4292 | */ | |
4293 | static u_int32_t | |
4294 | key_do_getnewspi(spirange, saidx) | |
4295 | struct sadb_spirange *spirange; | |
4296 | struct secasindex *saidx; | |
4297 | { | |
4298 | u_int32_t newspi; | |
4299 | u_int32_t min, max; | |
4300 | int count = key_spi_trycnt; | |
4301 | ||
4302 | /* set spi range to allocate */ | |
4303 | if (spirange != NULL) { | |
4304 | min = spirange->sadb_spirange_min; | |
4305 | max = spirange->sadb_spirange_max; | |
4306 | } else { | |
4307 | min = key_spi_minval; | |
4308 | max = key_spi_maxval; | |
4309 | } | |
4310 | /* IPCOMP needs 2-byte SPI */ | |
4311 | if (saidx->proto == IPPROTO_IPCOMP) { | |
4312 | u_int32_t t; | |
4313 | if (min >= 0x10000) | |
4314 | min = 0xffff; | |
4315 | if (max >= 0x10000) | |
4316 | max = 0xffff; | |
4317 | if (min > max) { | |
4318 | t = min; min = max; max = t; | |
4319 | } | |
4320 | } | |
4321 | ||
4322 | if (min == max) { | |
4323 | if (key_checkspidup(saidx, min) != NULL) { | |
4324 | #if IPSEC_DEBUG | |
4325 | printf("key_do_getnewspi: SPI %u exists already.\n", min); | |
4326 | #endif | |
4327 | return 0; | |
4328 | } | |
4329 | ||
4330 | count--; /* taking one cost. */ | |
4331 | newspi = min; | |
4332 | ||
4333 | } else { | |
4334 | ||
4335 | /* init SPI */ | |
4336 | newspi = 0; | |
4337 | ||
4338 | /* when requesting to allocate spi ranged */ | |
4339 | while (count--) { | |
4340 | /* generate pseudo-random SPI value ranged. */ | |
4341 | newspi = min + (random() % ( max - min + 1 )); | |
4342 | ||
4343 | if (key_checkspidup(saidx, newspi) == NULL) | |
4344 | break; | |
4345 | } | |
4346 | ||
4347 | if (count == 0 || newspi == 0) { | |
4348 | #if IPSEC_DEBUG | |
4349 | printf("key_do_getnewspi: to allocate spi is failed.\n"); | |
4350 | #endif | |
4351 | return 0; | |
4352 | } | |
4353 | } | |
4354 | ||
4355 | /* statistics */ | |
4356 | keystat.getspi_count = | |
4357 | (keystat.getspi_count + key_spi_trycnt - count) / 2; | |
4358 | ||
4359 | return newspi; | |
4360 | } | |
4361 | ||
4362 | /* | |
4363 | * SADB_UPDATE processing | |
4364 | * receive | |
4365 | * <base, SA, (lifetime(HSC),) address(SD), (address(P),) | |
4366 | * key(AE), (identity(SD),) (sensitivity)> | |
4367 | * from the ikmpd, and update a secasvar entry whose status is SADB_SASTATE_LARVAL. | |
4368 | * and send | |
4369 | * <base, SA, (lifetime(HSC),) address(SD), (address(P),) | |
4370 | * (identity(SD),) (sensitivity)> | |
4371 | * to the ikmpd. | |
4372 | * | |
4373 | * IN: mhp: pointer to the pointer to each header. | |
4374 | * OUT: NULL if fail. | |
4375 | * other if success, return pointer to the message to send. | |
4376 | */ | |
4377 | static struct sadb_msg * | |
4378 | key_update(mhp) | |
4379 | caddr_t *mhp; | |
4380 | { | |
4381 | struct sadb_msg *msg0; | |
4382 | struct sadb_sa *sa0; | |
4383 | struct sadb_address *src0, *dst0; | |
4384 | struct secasindex saidx; | |
4385 | struct secashead *sah; | |
4386 | struct secasvar *sav; | |
4387 | u_int16_t proto; | |
4388 | ||
4389 | /* sanity check */ | |
4390 | if (mhp == NULL || mhp[0] == NULL) | |
4391 | panic("key_update: NULL pointer is passed.\n"); | |
4392 | ||
4393 | msg0 = (struct sadb_msg *)mhp[0]; | |
4394 | ||
4395 | /* map satype to proto */ | |
4396 | if ((proto = key_satype2proto(msg0->sadb_msg_satype)) == 0) { | |
4397 | #if IPSEC_DEBUG | |
4398 | printf("key_update: invalid satype is passed.\n"); | |
4399 | #endif | |
4400 | msg0->sadb_msg_errno = EINVAL; | |
4401 | return NULL; | |
4402 | } | |
4403 | ||
4404 | if (mhp[SADB_EXT_SA] == NULL | |
4405 | || mhp[SADB_EXT_ADDRESS_SRC] == NULL | |
4406 | || mhp[SADB_EXT_ADDRESS_DST] == NULL | |
4407 | || (msg0->sadb_msg_satype == SADB_SATYPE_ESP | |
4408 | && mhp[SADB_EXT_KEY_ENCRYPT] == NULL) | |
4409 | || (msg0->sadb_msg_satype == SADB_SATYPE_AH | |
4410 | && mhp[SADB_EXT_KEY_AUTH] == NULL) | |
4411 | || (mhp[SADB_EXT_LIFETIME_HARD] != NULL | |
4412 | && mhp[SADB_EXT_LIFETIME_SOFT] == NULL) | |
4413 | || (mhp[SADB_EXT_LIFETIME_HARD] == NULL | |
4414 | && mhp[SADB_EXT_LIFETIME_SOFT] != NULL)) { | |
4415 | #if IPSEC_DEBUG | |
4416 | printf("key_update: invalid message is passed.\n"); | |
4417 | #endif | |
4418 | msg0->sadb_msg_errno = EINVAL; | |
4419 | return NULL; | |
4420 | } | |
4421 | ||
4422 | sa0 = (struct sadb_sa *)mhp[SADB_EXT_SA]; | |
4423 | src0 = (struct sadb_address *)(mhp[SADB_EXT_ADDRESS_SRC]); | |
4424 | dst0 = (struct sadb_address *)(mhp[SADB_EXT_ADDRESS_DST]); | |
4425 | ||
4426 | KEY_SETSECASIDX(proto, msg0, src0+1, dst0+1, &saidx); | |
4427 | ||
4428 | /* get a SA header */ | |
4429 | if ((sah = key_getsah(&saidx)) == NULL) { | |
4430 | #if IPSEC_DEBUG | |
4431 | printf("key_update: no SA index found.\n"); | |
4432 | #endif | |
4433 | msg0->sadb_msg_errno = ENOENT; | |
4434 | return NULL; | |
4435 | } | |
4436 | ||
4437 | /* set spidx if there */ | |
4438 | if (key_setident(sah, mhp) < 0) | |
4439 | return NULL; | |
4440 | ||
4441 | /* find a SA with sequence number. */ | |
4442 | #if IPSEC_DOSEQCHECK | |
4443 | if (msg0->sadb_msg_seq != 0 | |
4444 | && (sav = key_getsavbyseq(sah, msg0->sadb_msg_seq)) == NULL) { | |
4445 | #if IPSEC_DEBUG | |
4446 | printf("key_update: no larval SA with sequence %u exists.\n", | |
4447 | msg0->sadb_msg_seq); | |
4448 | #endif | |
4449 | msg0->sadb_msg_errno = ENOENT; | |
4450 | return NULL; | |
4451 | } | |
4452 | #else | |
4453 | if ((sav = key_getsavbyspi(sah, sa0->sadb_sa_spi)) == NULL) { | |
4454 | #if IPSEC_DEBUG | |
4455 | printf("key_update: no such a SA found (spi:%u)\n", | |
4456 | (u_int32_t)ntohl(sa0->sadb_sa_spi)); | |
4457 | #endif | |
4458 | msg0->sadb_msg_errno = EINVAL; | |
4459 | return NULL; | |
4460 | } | |
4461 | #endif | |
4462 | ||
4463 | /* validity check */ | |
4464 | if (sav->sah->saidx.proto != proto) { | |
4465 | #if IPSEC_DEBUG | |
4466 | printf("key_update: protocol mismatched (DB=%u param=%u)\n", | |
4467 | sav->sah->saidx.proto, proto); | |
4468 | #endif | |
4469 | msg0->sadb_msg_errno = EINVAL; | |
4470 | return NULL; | |
4471 | } | |
4472 | #if IPSEC_DOSEQCHECK | |
4473 | if (sav->spi != sa0->sadb_sa_spi) { | |
4474 | #if IPSEC_DEBUG | |
4475 | printf("key_update: SPI mismatched (DB:%u param:%u)\n", | |
4476 | (u_int32_t)ntohl(sav->spi), | |
4477 | (u_int32_t)ntohl(sa0->sadb_sa_spi)); | |
4478 | #endif | |
4479 | msg0->sadb_msg_errno = EINVAL; | |
4480 | return NULL; | |
4481 | } | |
4482 | #endif | |
4483 | if (sav->pid != msg0->sadb_msg_pid) { | |
4484 | #if IPSEC_DEBUG | |
4485 | printf("key_update: pid mismatched (DB:%u param:%u)\n", | |
4486 | sav->pid, msg0->sadb_msg_pid); | |
4487 | #endif | |
4488 | msg0->sadb_msg_errno = EINVAL; | |
4489 | return NULL; | |
4490 | } | |
4491 | ||
4492 | /* copy sav values */ | |
4493 | if (key_setsaval(sav, mhp)) { | |
4494 | key_freesav(sav); | |
4495 | return NULL; | |
4496 | } | |
4497 | ||
4498 | /* check SA values to be mature. */ | |
4499 | if ((msg0->sadb_msg_errno = key_mature(sav)) != 0) { | |
4500 | key_freesav(sav); | |
4501 | return NULL; | |
4502 | } | |
4503 | ||
4504 | { | |
4505 | struct sadb_msg *newmsg; | |
4506 | ||
4507 | /* set msg buf from mhp */ | |
4508 | if ((newmsg = key_getmsgbuf_x1(mhp)) == NULL) { | |
4509 | #if IPSEC_DEBUG | |
4510 | printf("key_update: No more memory.\n"); | |
4511 | #endif | |
4512 | msg0->sadb_msg_errno = ENOBUFS; | |
4513 | return NULL; | |
4514 | } | |
4515 | return newmsg; | |
4516 | } | |
4517 | } | |
4518 | ||
4519 | /* | |
4520 | * search SAD with sequence for a SA which state is SADB_SASTATE_LARVAL. | |
4521 | * only called by key_update(). | |
4522 | * OUT: | |
4523 | * NULL : not found | |
4524 | * others : found, pointer to a SA. | |
4525 | */ | |
4526 | #if IPSEC_DOSEQCHECK | |
4527 | static struct secasvar * | |
4528 | key_getsavbyseq(sah, seq) | |
4529 | struct secashead *sah; | |
4530 | u_int32_t seq; | |
4531 | { | |
4532 | struct secasvar *sav; | |
4533 | u_int state; | |
4534 | ||
4535 | state = SADB_SASTATE_LARVAL; | |
4536 | ||
4537 | /* search SAD with sequence number ? */ | |
4538 | LIST_FOREACH(sav, &sah->savtree[state], chain) { | |
4539 | ||
4540 | KEY_CHKSASTATE(state, sav->state, "key_getsabyseq"); | |
4541 | ||
4542 | if (sav->seq == seq) { | |
4543 | sav->refcnt++; | |
4544 | KEYDEBUG(KEYDEBUG_IPSEC_STAMP, | |
4545 | printf("DP key_getsavbyseq cause " | |
4546 | "refcnt++:%d SA:%p\n", | |
4547 | sav->refcnt, sav)); | |
4548 | return sav; | |
4549 | } | |
4550 | } | |
4551 | ||
4552 | return NULL; | |
4553 | } | |
4554 | #endif | |
4555 | ||
4556 | /* | |
4557 | * SADB_ADD processing | |
4558 | * add a entry to SA database, when received | |
4559 | * <base, SA, (lifetime(HSC),) address(SD), (address(P),) | |
4560 | * key(AE), (identity(SD),) (sensitivity)> | |
4561 | * from the ikmpd, | |
4562 | * and send | |
4563 | * <base, SA, (lifetime(HSC),) address(SD), (address(P),) | |
4564 | * (identity(SD),) (sensitivity)> | |
4565 | * to the ikmpd. | |
4566 | * | |
4567 | * IGNORE identity and sensitivity messages. | |
4568 | * | |
4569 | * IN: mhp: pointer to the pointer to each header. | |
4570 | * OUT: NULL if fail. | |
4571 | * other if success, return pointer to the message to send. | |
4572 | */ | |
4573 | static struct sadb_msg * | |
4574 | key_add(mhp) | |
4575 | caddr_t *mhp; | |
4576 | { | |
4577 | struct sadb_msg *msg0; | |
4578 | struct sadb_sa *sa0; | |
4579 | struct sadb_address *src0, *dst0; | |
4580 | struct secasindex saidx; | |
4581 | struct secashead *newsah; | |
4582 | struct secasvar *newsav; | |
4583 | u_int16_t proto; | |
4584 | ||
4585 | /* sanity check */ | |
4586 | if (mhp == NULL || mhp[0] == NULL) | |
4587 | panic("key_add: NULL pointer is passed.\n"); | |
4588 | ||
4589 | msg0 = (struct sadb_msg *)mhp[0]; | |
4590 | ||
4591 | /* map satype to proto */ | |
4592 | if ((proto = key_satype2proto(msg0->sadb_msg_satype)) == 0) { | |
4593 | #if IPSEC_DEBUG | |
4594 | printf("key_add: invalid satype is passed.\n"); | |
4595 | #endif | |
4596 | msg0->sadb_msg_errno = EINVAL; | |
4597 | return NULL; | |
4598 | } | |
4599 | ||
4600 | if (mhp[SADB_EXT_SA] == NULL | |
4601 | || mhp[SADB_EXT_ADDRESS_SRC] == NULL | |
4602 | || mhp[SADB_EXT_ADDRESS_DST] == NULL | |
4603 | || (msg0->sadb_msg_satype == SADB_SATYPE_ESP | |
4604 | && mhp[SADB_EXT_KEY_ENCRYPT] == NULL) | |
4605 | || (msg0->sadb_msg_satype == SADB_SATYPE_AH | |
4606 | && mhp[SADB_EXT_KEY_AUTH] == NULL) | |
4607 | || (mhp[SADB_EXT_LIFETIME_HARD] != NULL | |
4608 | && mhp[SADB_EXT_LIFETIME_SOFT] == NULL) | |
4609 | || (mhp[SADB_EXT_LIFETIME_HARD] == NULL | |
4610 | && mhp[SADB_EXT_LIFETIME_SOFT] != NULL)) { | |
4611 | #if IPSEC_DEBUG | |
4612 | printf("key_add: invalid message is passed.\n"); | |
4613 | #endif | |
4614 | msg0->sadb_msg_errno = EINVAL; | |
4615 | return NULL; | |
4616 | } | |
4617 | ||
4618 | sa0 = (struct sadb_sa *)mhp[SADB_EXT_SA]; | |
4619 | src0 = (struct sadb_address *)(mhp[SADB_EXT_ADDRESS_SRC]); | |
4620 | dst0 = (struct sadb_address *)(mhp[SADB_EXT_ADDRESS_DST]); | |
4621 | ||
4622 | KEY_SETSECASIDX(proto, msg0, src0+1, dst0+1, &saidx); | |
4623 | ||
4624 | /* get a SA header */ | |
4625 | if ((newsah = key_getsah(&saidx)) == NULL) { | |
4626 | ||
4627 | /* create a new SA header */ | |
4628 | if ((newsah = key_newsah(&saidx)) == NULL) { | |
4629 | #if IPSEC_DEBUG | |
4630 | printf("key_add: No more memory.\n"); | |
4631 | #endif | |
4632 | msg0->sadb_msg_errno = ENOBUFS; | |
4633 | return NULL; | |
4634 | } | |
4635 | } | |
4636 | ||
4637 | /* set spidx if there */ | |
4638 | if (key_setident(newsah, mhp) < 0) | |
4639 | return NULL; | |
4640 | ||
4641 | /* create new SA entry. */ | |
4642 | /* We can create new SA only if SPI is differenct. */ | |
4643 | if (key_getsavbyspi(newsah, sa0->sadb_sa_spi)) { | |
4644 | #if IPSEC_DEBUG | |
4645 | printf("key_add: SA already exists.\n"); | |
4646 | #endif | |
4647 | msg0->sadb_msg_errno = EEXIST; | |
4648 | return NULL; | |
4649 | } | |
4650 | if ((newsav = key_newsav(mhp, newsah)) == NULL) | |
4651 | return NULL; | |
4652 | ||
4653 | /* check SA values to be mature. */ | |
4654 | if ((msg0->sadb_msg_errno = key_mature(newsav)) != NULL) { | |
4655 | key_freesav(newsav); | |
4656 | return NULL; | |
4657 | } | |
4658 | ||
4659 | /* | |
4660 | * don't call key_freesav() here, as we would like to keep the SA | |
4661 | * in the database on success. | |
4662 | */ | |
4663 | ||
4664 | { | |
4665 | struct sadb_msg *newmsg; | |
4666 | ||
4667 | /* set msg buf from mhp */ | |
4668 | if ((newmsg = key_getmsgbuf_x1(mhp)) == NULL) { | |
4669 | #if IPSEC_DEBUG | |
4670 | printf("key_add: No more memory.\n"); | |
4671 | #endif | |
4672 | msg0->sadb_msg_errno = ENOBUFS; | |
4673 | return NULL; | |
4674 | } | |
4675 | ||
4676 | return newmsg; | |
4677 | } | |
4678 | } | |
4679 | ||
4680 | static int | |
4681 | key_setident(sah, mhp) | |
4682 | struct secashead *sah; | |
4683 | caddr_t *mhp; | |
4684 | { | |
4685 | struct sadb_msg *msg0; | |
4686 | struct sadb_ident *idsrc, *iddst; | |
4687 | int idsrclen, iddstlen; | |
4688 | ||
4689 | /* sanity check */ | |
4690 | if (sah == NULL || mhp == NULL || mhp[0] == NULL) | |
4691 | panic("key_setident: NULL pointer is passed.\n"); | |
4692 | ||
4693 | msg0 = (struct sadb_msg *)mhp[0]; | |
4694 | ||
4695 | /* don't make buffer if not there */ | |
4696 | if (mhp[SADB_EXT_IDENTITY_SRC] == NULL | |
4697 | && mhp[SADB_EXT_IDENTITY_DST] == NULL) { | |
4698 | sah->idents = NULL; | |
4699 | sah->identd = NULL; | |
4700 | return 0; | |
4701 | } | |
4702 | ||
4703 | if (mhp[SADB_EXT_IDENTITY_SRC] == NULL | |
4704 | || mhp[SADB_EXT_IDENTITY_DST] == NULL) { | |
4705 | #if IPSEC_DEBUG | |
4706 | printf("key_setident: invalid identity.\n"); | |
4707 | #endif | |
4708 | msg0->sadb_msg_errno = EINVAL; | |
4709 | return -1; | |
4710 | } | |
4711 | ||
4712 | idsrc = (struct sadb_ident *)mhp[SADB_EXT_IDENTITY_SRC]; | |
4713 | iddst = (struct sadb_ident *)mhp[SADB_EXT_IDENTITY_DST]; | |
4714 | idsrclen = PFKEY_UNUNIT64(idsrc->sadb_ident_len); | |
4715 | iddstlen = PFKEY_UNUNIT64(idsrc->sadb_ident_len); | |
4716 | ||
4717 | /* validity check */ | |
4718 | if (idsrc->sadb_ident_type != iddst->sadb_ident_type) { | |
4719 | #if IPSEC_DEBUG | |
4720 | printf("key_setident: ident type mismatch.\n"); | |
4721 | #endif | |
4722 | msg0->sadb_msg_errno = EINVAL; | |
4723 | return -1; | |
4724 | } | |
4725 | ||
4726 | switch (idsrc->sadb_ident_type) { | |
4727 | case SADB_X_IDENTTYPE_ADDR: | |
4728 | if (idsrclen != | |
4729 | sizeof(*idsrc) + ((struct sockaddr *)(idsrc + 1))->sa_len | |
4730 | || iddstlen != | |
4731 | sizeof(*iddst) + ((struct sockaddr *)(iddst + 1))->sa_len) { | |
4732 | #if IPSEC_DEBUG | |
4733 | printf("key_setident: invalid length is passed.\n"); | |
4734 | #endif | |
4735 | msg0->sadb_msg_errno = EINVAL; | |
4736 | return -1; | |
4737 | } | |
4738 | if (((struct sockaddr *)(idsrc + 1))->sa_len > | |
4739 | sizeof(struct sockaddr_storage) | |
4740 | || ((struct sockaddr *)(iddst + 1))->sa_len > | |
4741 | sizeof(struct sockaddr_storage)) { | |
4742 | #if IPSEC_DEBUG | |
4743 | printf("key_setident: invalid sa_len is passed.\n"); | |
4744 | #endif | |
4745 | msg0->sadb_msg_errno = EINVAL; | |
4746 | return -1; | |
4747 | } | |
4748 | #define __IDENTXID(a) ((union sadb_x_ident_id *)&(a)->sadb_ident_id) | |
4749 | if (__IDENTXID(idsrc)->sadb_x_ident_id_addr.ul_proto | |
4750 | != __IDENTXID(iddst)->sadb_x_ident_id_addr.ul_proto) { | |
4751 | #if IPSEC_DEBUG | |
4752 | printf("key_setident: ul_proto mismatch.\n"); | |
4753 | #endif | |
4754 | msg0->sadb_msg_errno = EINVAL; | |
4755 | return -1; | |
4756 | } | |
4757 | #undef __IDENTXID(a) | |
4758 | break; | |
4759 | case SADB_IDENTTYPE_PREFIX: | |
4760 | case SADB_IDENTTYPE_FQDN: | |
4761 | case SADB_IDENTTYPE_USERFQDN: | |
4762 | default: | |
4763 | /* XXX do nothing */ | |
4764 | sah->idents = NULL; | |
4765 | sah->identd = NULL; | |
4766 | return 0; | |
4767 | } | |
4768 | ||
4769 | /* make structure */ | |
4770 | KMALLOC(sah->idents, struct sadb_ident *, idsrclen); | |
4771 | if (sah->idents == NULL) { | |
4772 | #if IPSEC_DEBUG | |
4773 | printf("key_setident: No more memory.\n"); | |
4774 | #endif | |
4775 | msg0->sadb_msg_errno = ENOBUFS; | |
4776 | return -1; | |
4777 | } | |
4778 | KMALLOC(sah->identd, struct sadb_ident *, iddstlen); | |
4779 | if (sah->identd == NULL) { | |
4780 | KFREE(sah->idents); | |
4781 | #if IPSEC_DEBUG | |
4782 | printf("key_setident: No more memory.\n"); | |
4783 | #endif | |
4784 | msg0->sadb_msg_errno = ENOBUFS; | |
4785 | return -1; | |
4786 | } | |
4787 | bcopy(idsrc, sah->idents, idsrclen); | |
4788 | bcopy(iddst, sah->identd, iddstlen); | |
4789 | ||
4790 | return 0; | |
4791 | } | |
4792 | ||
4793 | static struct sadb_msg * | |
4794 | key_getmsgbuf_x1(mhp) | |
4795 | caddr_t *mhp; | |
4796 | { | |
4797 | struct sadb_msg *msg0; | |
4798 | struct sadb_msg *newmsg; | |
4799 | u_int len; | |
4800 | caddr_t p; | |
4801 | ||
4802 | /* sanity check */ | |
4803 | if (mhp == NULL || mhp[0] == NULL) | |
4804 | panic("key_getmsgbuf_x1: NULL pointer is passed.\n"); | |
4805 | ||
4806 | msg0 = (struct sadb_msg *)mhp[0]; | |
4807 | ||
4808 | /* create new sadb_msg to reply. */ | |
4809 | len = sizeof(struct sadb_msg) | |
4810 | + sizeof(struct sadb_sa) | |
4811 | + PFKEY_EXTLEN(mhp[SADB_EXT_ADDRESS_SRC]) | |
4812 | + PFKEY_EXTLEN(mhp[SADB_EXT_ADDRESS_DST]) | |
4813 | + (mhp[SADB_EXT_LIFETIME_HARD] == NULL | |
4814 | ? 0 : sizeof(struct sadb_lifetime)) | |
4815 | + (mhp[SADB_EXT_LIFETIME_SOFT] == NULL | |
4816 | ? 0 : sizeof(struct sadb_lifetime)) | |
4817 | + (mhp[SADB_EXT_IDENTITY_SRC] == NULL | |
4818 | ? 0 : PFKEY_EXTLEN(mhp[SADB_EXT_IDENTITY_SRC])) | |
4819 | + (mhp[SADB_EXT_IDENTITY_DST] == NULL | |
4820 | ? 0 : PFKEY_EXTLEN(mhp[SADB_EXT_IDENTITY_DST])); | |
4821 | ||
4822 | KMALLOC(newmsg, struct sadb_msg *, len); | |
4823 | if (newmsg == NULL) | |
4824 | return NULL; | |
4825 | bzero((caddr_t)newmsg, len); | |
4826 | ||
4827 | bcopy((caddr_t)mhp[0], (caddr_t)newmsg, sizeof(*msg0)); | |
4828 | newmsg->sadb_msg_errno = 0; | |
4829 | newmsg->sadb_msg_len = PFKEY_UNIT64(len); | |
4830 | p = (caddr_t)newmsg + sizeof(*msg0); | |
4831 | ||
4832 | p = key_setsadbext(p, mhp[SADB_EXT_SA]); | |
4833 | p = key_setsadbext(p, mhp[SADB_EXT_ADDRESS_SRC]); | |
4834 | p = key_setsadbext(p, mhp[SADB_EXT_ADDRESS_DST]); | |
4835 | ||
4836 | if (mhp[SADB_EXT_LIFETIME_HARD] != NULL) | |
4837 | p = key_setsadbext(p, mhp[SADB_EXT_LIFETIME_HARD]); | |
4838 | ||
4839 | if (mhp[SADB_EXT_LIFETIME_SOFT] != NULL) | |
4840 | p = key_setsadbext(p, mhp[SADB_EXT_LIFETIME_SOFT]); | |
4841 | ||
4842 | if (mhp[SADB_EXT_IDENTITY_SRC] != NULL) | |
4843 | p = key_setsadbext(p, mhp[SADB_EXT_IDENTITY_SRC]); | |
4844 | if (mhp[SADB_EXT_IDENTITY_DST] != NULL) | |
4845 | p = key_setsadbext(p, mhp[SADB_EXT_IDENTITY_DST]); | |
4846 | ||
4847 | return newmsg; | |
4848 | } | |
4849 | ||
4850 | /* | |
4851 | * SADB_DELETE processing | |
4852 | * receive | |
4853 | * <base, SA(*), address(SD)> | |
4854 | * from the ikmpd, and set SADB_SASTATE_DEAD, | |
4855 | * and send, | |
4856 | * <base, SA(*), address(SD)> | |
4857 | * to the ikmpd. | |
4858 | * | |
4859 | * IN: mhp: pointer to the pointer to each header. | |
4860 | * OUT: NULL if fail. | |
4861 | * other if success, return pointer to the message to send. | |
4862 | */ | |
4863 | static struct sadb_msg * | |
4864 | key_delete(mhp) | |
4865 | caddr_t *mhp; | |
4866 | { | |
4867 | struct sadb_msg *msg0; | |
4868 | struct sadb_sa *sa0; | |
4869 | struct sadb_address *src0, *dst0; | |
4870 | struct secasindex saidx; | |
4871 | struct secashead *sah; | |
4872 | struct secasvar *sav; | |
4873 | u_int16_t proto; | |
4874 | ||
4875 | /* sanity check */ | |
4876 | if (mhp == NULL || mhp[0] == NULL) | |
4877 | panic("key_delete: NULL pointer is passed.\n"); | |
4878 | ||
4879 | msg0 = (struct sadb_msg *)mhp[0]; | |
4880 | ||
4881 | /* map satype to proto */ | |
4882 | if ((proto = key_satype2proto(msg0->sadb_msg_satype)) == 0) { | |
4883 | #if IPSEC_DEBUG | |
4884 | printf("key_delete: invalid satype is passed.\n"); | |
4885 | #endif | |
4886 | msg0->sadb_msg_errno = EINVAL; | |
4887 | return NULL; | |
4888 | } | |
4889 | ||
4890 | if (mhp[SADB_EXT_SA] == NULL | |
4891 | || mhp[SADB_EXT_ADDRESS_SRC] == NULL | |
4892 | || mhp[SADB_EXT_ADDRESS_DST] == NULL) { | |
4893 | #if IPSEC_DEBUG | |
4894 | printf("key_delete: invalid message is passed.\n"); | |
4895 | #endif | |
4896 | msg0->sadb_msg_errno = EINVAL; | |
4897 | return NULL; | |
4898 | } | |
4899 | sa0 = (struct sadb_sa *)mhp[SADB_EXT_SA]; | |
4900 | src0 = (struct sadb_address *)(mhp[SADB_EXT_ADDRESS_SRC]); | |
4901 | dst0 = (struct sadb_address *)(mhp[SADB_EXT_ADDRESS_DST]); | |
4902 | ||
4903 | KEY_SETSECASIDX(proto, msg0, src0+1, dst0+1, &saidx); | |
4904 | ||
4905 | /* get a SA header */ | |
4906 | if ((sah = key_getsah(&saidx)) == NULL) { | |
4907 | #if IPSEC_DEBUG | |
4908 | printf("key_delete: no SA found.\n"); | |
4909 | #endif | |
4910 | msg0->sadb_msg_errno = ENOENT; | |
4911 | return NULL; | |
4912 | } | |
4913 | ||
4914 | /* get a SA with SPI. */ | |
4915 | sav = key_getsavbyspi(sah, sa0->sadb_sa_spi); | |
4916 | if (sav == NULL) { | |
4917 | #if IPSEC_DEBUG | |
4918 | printf("key_delete: no alive SA found.\n"); | |
4919 | #endif | |
4920 | msg0->sadb_msg_errno = ENOENT; | |
4921 | return NULL; | |
4922 | } | |
4923 | ||
4924 | key_sa_chgstate(sav, SADB_SASTATE_DEAD); | |
4925 | key_freesav(sav); | |
4926 | sav = NULL; | |
4927 | ||
4928 | { | |
4929 | struct sadb_msg *newmsg; | |
4930 | u_int len; | |
4931 | caddr_t p; | |
4932 | ||
4933 | /* create new sadb_msg to reply. */ | |
4934 | len = sizeof(struct sadb_msg) | |
4935 | + sizeof(struct sadb_sa) | |
4936 | + PFKEY_EXTLEN(mhp[SADB_EXT_ADDRESS_SRC]) | |
4937 | + PFKEY_EXTLEN(mhp[SADB_EXT_ADDRESS_DST]); | |
4938 | ||
4939 | KMALLOC(newmsg, struct sadb_msg *, len); | |
4940 | if (newmsg == NULL) { | |
4941 | #if IPSEC_DEBUG | |
4942 | printf("key_delete: No more memory.\n"); | |
4943 | #endif | |
4944 | msg0->sadb_msg_errno = ENOBUFS; | |
4945 | return NULL; | |
4946 | } | |
4947 | bzero((caddr_t)newmsg, len); | |
4948 | ||
4949 | bcopy((caddr_t)mhp[0], (caddr_t)newmsg, sizeof(*msg0)); | |
4950 | newmsg->sadb_msg_errno = 0; | |
4951 | newmsg->sadb_msg_len = PFKEY_UNIT64(len); | |
4952 | p = (caddr_t)newmsg + sizeof(*msg0); | |
4953 | ||
4954 | p = key_setsadbext(p, mhp[SADB_EXT_SA]); | |
4955 | p = key_setsadbext(p, mhp[SADB_EXT_ADDRESS_SRC]); | |
4956 | p = key_setsadbext(p, mhp[SADB_EXT_ADDRESS_DST]); | |
4957 | ||
4958 | return newmsg; | |
4959 | } | |
4960 | } | |
4961 | ||
4962 | /* | |
4963 | * SADB_GET processing | |
4964 | * receive | |
4965 | * <base, SA(*), address(SD)> | |
4966 | * from the ikmpd, and get a SP and a SA to respond, | |
4967 | * and send, | |
4968 | * <base, SA, (lifetime(HSC),) address(SD), (address(P),) key(AE), | |
4969 | * (identity(SD),) (sensitivity)> | |
4970 | * to the ikmpd. | |
4971 | * | |
4972 | * IN: mhp: pointer to the pointer to each header. | |
4973 | * OUT: NULL if fail. | |
4974 | * other if success, return pointer to the message to send. | |
4975 | */ | |
4976 | static struct sadb_msg * | |
4977 | key_get(mhp) | |
4978 | caddr_t *mhp; | |
4979 | { | |
4980 | struct sadb_msg *msg0; | |
4981 | struct sadb_sa *sa0; | |
4982 | struct sadb_address *src0, *dst0; | |
4983 | struct secasindex saidx; | |
4984 | struct secashead *sah; | |
4985 | struct secasvar *sav; | |
4986 | u_int16_t proto; | |
4987 | ||
4988 | /* sanity check */ | |
4989 | if (mhp == NULL || mhp[0] == NULL) | |
4990 | panic("key_get: NULL pointer is passed.\n"); | |
4991 | ||
4992 | msg0 = (struct sadb_msg *)mhp[0]; | |
4993 | ||
4994 | /* map satype to proto */ | |
4995 | if ((proto = key_satype2proto(msg0->sadb_msg_satype)) == 0) { | |
4996 | #if IPSEC_DEBUG | |
4997 | printf("key_get: invalid satype is passed.\n"); | |
4998 | #endif | |
4999 | msg0->sadb_msg_errno = EINVAL; | |
5000 | return NULL; | |
5001 | } | |
5002 | ||
5003 | if (mhp[SADB_EXT_SA] == NULL | |
5004 | || mhp[SADB_EXT_ADDRESS_SRC] == NULL | |
5005 | || mhp[SADB_EXT_ADDRESS_DST] == NULL) { | |
5006 | #if IPSEC_DEBUG | |
5007 | printf("key_get: invalid message is passed.\n"); | |
5008 | #endif | |
5009 | msg0->sadb_msg_errno = EINVAL; | |
5010 | return NULL; | |
5011 | } | |
5012 | sa0 = (struct sadb_sa *)mhp[SADB_EXT_SA]; | |
5013 | src0 = (struct sadb_address *)(mhp[SADB_EXT_ADDRESS_SRC]); | |
5014 | dst0 = (struct sadb_address *)(mhp[SADB_EXT_ADDRESS_DST]); | |
5015 | ||
5016 | KEY_SETSECASIDX(proto, msg0, src0+1, dst0+1, &saidx); | |
5017 | ||
5018 | /* get a SA header */ | |
5019 | if ((sah = key_getsah(&saidx)) == NULL) { | |
5020 | #if IPSEC_DEBUG | |
5021 | printf("key_get: no SA found.\n"); | |
5022 | #endif | |
5023 | msg0->sadb_msg_errno = ENOENT; | |
5024 | return NULL; | |
5025 | } | |
5026 | ||
5027 | /* get a SA with SPI. */ | |
5028 | sav = key_getsavbyspi(sah, sa0->sadb_sa_spi); | |
5029 | if (sav == NULL) { | |
5030 | #if IPSEC_DEBUG | |
5031 | printf("key_get: no SA with state of mature found.\n"); | |
5032 | #endif | |
5033 | msg0->sadb_msg_errno = ENOENT; | |
5034 | return NULL; | |
5035 | } | |
5036 | ||
5037 | { | |
5038 | struct sadb_msg *newmsg; | |
5039 | u_int len; | |
5040 | u_int8_t satype; | |
5041 | ||
5042 | /* map proto to satype */ | |
5043 | if ((satype = key_proto2satype(sah->saidx.proto)) == 0) { | |
5044 | #if IPSEC_DEBUG | |
5045 | printf("key_get: there was invalid proto in SAD.\n"); | |
5046 | #endif | |
5047 | msg0->sadb_msg_errno = EINVAL; | |
5048 | return NULL; | |
5049 | } | |
5050 | ||
5051 | /* calculate a length of message buffer */ | |
5052 | len = key_getmsglen(sav); | |
5053 | ||
5054 | KMALLOC(newmsg, struct sadb_msg *, len); | |
5055 | if (newmsg == NULL) { | |
5056 | #if IPSEC_DEBUG | |
5057 | printf("key_get: No more memory.\n"); | |
5058 | #endif | |
5059 | msg0->sadb_msg_errno = ENOBUFS; | |
5060 | return NULL; | |
5061 | } | |
5062 | ||
5063 | /* create new sadb_msg to reply. */ | |
5064 | (void)key_setdumpsa(newmsg, sav, SADB_GET, | |
5065 | satype, msg0->sadb_msg_seq, msg0->sadb_msg_pid); | |
5066 | ||
5067 | return newmsg; | |
5068 | } | |
5069 | } | |
5070 | ||
5071 | /* | |
5072 | * SADB_ACQUIRE processing called by key_checkrequest() and key_acquire2(). | |
5073 | * send | |
5074 | * <base, SA, address(SD), (address(P)), | |
5075 | * (identity(SD),) (sensitivity,) proposal> | |
5076 | * to KMD, and expect to receive | |
5077 | * <base> with SADB_ACQUIRE if error occured, | |
5078 | * or | |
5079 | * <base, src address, dst address, (SPI range)> with SADB_GETSPI | |
5080 | * from KMD by PF_KEY. | |
5081 | * | |
5082 | * sensitivity is not supported. | |
5083 | * | |
5084 | * OUT: | |
5085 | * 0 : succeed | |
5086 | * others: error number | |
5087 | */ | |
5088 | static int | |
5089 | key_acquire(saidx, sp) | |
5090 | struct secasindex *saidx; | |
5091 | struct secpolicy *sp; | |
5092 | { | |
5093 | #ifndef IPSEC_NONBLOCK_ACQUIRE | |
5094 | struct secacq *newacq; | |
5095 | #endif | |
5096 | struct secpolicyindex *spidx = NULL; | |
5097 | u_int8_t satype; | |
5098 | int error; | |
5099 | ||
5100 | /* sanity check */ | |
5101 | if (saidx == NULL || sp == NULL) | |
5102 | panic("key_acquire: NULL pointer is passed.\n"); | |
5103 | if ((satype = key_proto2satype(saidx->proto)) == 0) | |
5104 | panic("key_acquire: invalid proto is passed.\n"); | |
5105 | ||
5106 | spidx = &sp->spidx; | |
5107 | ||
5108 | #ifndef IPSEC_NONBLOCK_ACQUIRE | |
5109 | /* | |
5110 | * We never do anything about acquirng SA. There is anather | |
5111 | * solution that kernel blocks to send SADB_ACQUIRE message until | |
5112 | * getting something message from IKEd. In later case, to be | |
5113 | * managed with ACQUIRING list. | |
5114 | */ | |
5115 | /* get a entry to check whether sending message or not. */ | |
5116 | if ((newacq = key_getacq(saidx)) != NULL) { | |
5117 | if (key_blockacq_count < newacq->count) { | |
5118 | /* reset counter and do send message. */ | |
5119 | newacq->count = 0; | |
5120 | } else { | |
5121 | /* increment counter and do nothing. */ | |
5122 | newacq->count++; | |
5123 | return 0; | |
5124 | } | |
5125 | } else { | |
5126 | /* make new entry for blocking to send SADB_ACQUIRE. */ | |
5127 | if ((newacq = key_newacq(saidx)) == NULL) | |
5128 | return ENOBUFS; | |
5129 | ||
5130 | /* add to acqtree */ | |
5131 | LIST_INSERT_HEAD(&acqtree, newacq, chain); | |
5132 | } | |
5133 | #endif | |
5134 | ||
5135 | { | |
5136 | struct sadb_msg *newmsg = NULL; | |
5137 | union sadb_x_ident_id id; | |
5138 | u_int len; | |
5139 | caddr_t p; | |
5140 | ||
5141 | /* create new sadb_msg to reply. */ | |
5142 | len = sizeof(struct sadb_msg) | |
5143 | + sizeof(struct sadb_address) | |
5144 | + PFKEY_ALIGN8(saidx->src.ss_len) | |
5145 | + sizeof(struct sadb_address) | |
5146 | + PFKEY_ALIGN8(saidx->dst.ss_len) | |
5147 | + sizeof(struct sadb_x_policy) | |
5148 | + sizeof(struct sadb_ident) | |
5149 | + PFKEY_ALIGN8(spidx->src.ss_len) | |
5150 | + sizeof(struct sadb_ident) | |
5151 | + PFKEY_ALIGN8(spidx->dst.ss_len) | |
5152 | + sizeof(struct sadb_prop) | |
5153 | + sizeof(struct sadb_comb); /* XXX to be multiple */ | |
5154 | ||
5155 | KMALLOC(newmsg, struct sadb_msg *, len); | |
5156 | if (newmsg == 0) { | |
5157 | #if IPSEC_DEBUG | |
5158 | printf("key_acquire: No more memory.\n"); | |
5159 | #endif | |
5160 | return ENOBUFS; | |
5161 | } | |
5162 | bzero((caddr_t)newmsg, len); | |
5163 | ||
5164 | newmsg->sadb_msg_version = PF_KEY_V2; | |
5165 | newmsg->sadb_msg_type = SADB_ACQUIRE; | |
5166 | newmsg->sadb_msg_errno = 0; | |
5167 | newmsg->sadb_msg_satype = satype; | |
5168 | newmsg->sadb_msg_len = PFKEY_UNIT64(len); | |
5169 | newmsg->sadb_msg_mode = saidx->mode; | |
5170 | newmsg->sadb_msg_reqid = saidx->reqid; | |
5171 | ||
5172 | #ifndef IPSEC_NONBLOCK_ACQUIRE | |
5173 | newmsg->sadb_msg_seq = newacq->seq; | |
5174 | #else | |
5175 | newmsg->sadb_msg_seq = (acq_seq = (acq_seq == ~0 ? 1 : ++acq_seq)); | |
5176 | #endif | |
5177 | ||
5178 | newmsg->sadb_msg_pid = 0; | |
5179 | ||
5180 | p = (caddr_t)newmsg + sizeof(struct sadb_msg); | |
5181 | ||
5182 | /* set sadb_address for saidx's. */ | |
5183 | p = key_setsadbaddr(p, | |
5184 | SADB_EXT_ADDRESS_SRC, | |
5185 | (struct sockaddr *)&saidx->src, | |
5186 | _INALENBYAF(saidx->src.ss_family) << 3, | |
5187 | IPSEC_ULPROTO_ANY); | |
5188 | p = key_setsadbaddr(p, | |
5189 | SADB_EXT_ADDRESS_DST, | |
5190 | (struct sockaddr *)&saidx->dst, | |
5191 | _INALENBYAF(saidx->dst.ss_family) << 3, | |
5192 | IPSEC_ULPROTO_ANY); | |
5193 | ||
5194 | /* set sadb_x_policy */ | |
5195 | p = key_setsadbxpolicy(p, sp->policy, sp->spidx.dir, sp->id); | |
5196 | ||
5197 | /* set sadb_address for spidx's. */ | |
5198 | bzero(&id, sizeof(id)); | |
5199 | id.sadb_x_ident_id_addr.prefix = spidx->prefs; | |
5200 | id.sadb_x_ident_id_addr.ul_proto = spidx->ul_proto; | |
5201 | p = key_setsadbident(p, | |
5202 | SADB_EXT_IDENTITY_SRC, | |
5203 | SADB_X_IDENTTYPE_ADDR, | |
5204 | (caddr_t)&spidx->src, | |
5205 | spidx->src.ss_len, | |
5206 | *(u_int64_t *)&id); | |
5207 | ||
5208 | bzero(&id, sizeof(id)); | |
5209 | id.sadb_x_ident_id_addr.prefix = spidx->prefd; | |
5210 | id.sadb_x_ident_id_addr.ul_proto = spidx->ul_proto; | |
5211 | p = key_setsadbident(p, | |
5212 | SADB_EXT_IDENTITY_DST, | |
5213 | SADB_X_IDENTTYPE_ADDR, | |
5214 | (caddr_t)&spidx->dst, | |
5215 | spidx->dst.ss_len, | |
5216 | *(u_int64_t *)&id); | |
5217 | ||
5218 | /* create proposal extension */ | |
5219 | /* set combination extension */ | |
5220 | /* XXX: to be defined by proposal database */ | |
5221 | { | |
5222 | struct sadb_prop *prop; | |
5223 | struct sadb_comb *comb; | |
5224 | ||
5225 | prop = (struct sadb_prop *)p; | |
5226 | prop->sadb_prop_len = PFKEY_UNIT64(sizeof(*prop) + sizeof(*comb)); | |
5227 | /* XXX to be multiple */ | |
5228 | prop->sadb_prop_exttype = SADB_EXT_PROPOSAL; | |
5229 | prop->sadb_prop_replay = 32; /* XXX be variable ? */ | |
5230 | p += sizeof(struct sadb_prop); | |
5231 | ||
5232 | comb = (struct sadb_comb *)p; | |
5233 | comb->sadb_comb_auth = SADB_AALG_SHA1HMAC; /* XXX ??? */ | |
5234 | comb->sadb_comb_encrypt = SADB_EALG_DESCBC; /* XXX ??? */ | |
5235 | comb->sadb_comb_flags = 0; | |
5236 | comb->sadb_comb_auth_minbits = 8; /* XXX */ | |
5237 | comb->sadb_comb_auth_maxbits = 1024; /* XXX */ | |
5238 | comb->sadb_comb_encrypt_minbits = 64; /* XXX */ | |
5239 | comb->sadb_comb_encrypt_maxbits = 64; /* XXX */ | |
5240 | comb->sadb_comb_soft_allocations = 0; | |
5241 | comb->sadb_comb_hard_allocations = 0; | |
5242 | comb->sadb_comb_soft_bytes = 0; | |
5243 | comb->sadb_comb_hard_bytes = 0; | |
5244 | comb->sadb_comb_soft_addtime = 0; | |
5245 | comb->sadb_comb_hard_addtime = 0; | |
5246 | comb->sadb_comb_soft_usetime = 0; | |
5247 | comb->sadb_comb_hard_usetime = 0; | |
5248 | ||
5249 | p += sizeof(*comb); | |
5250 | } | |
5251 | ||
5252 | #if 0 /* XXX Do it ?*/ | |
5253 | if (idexttype && fqdn) { | |
5254 | /* create identity extension (FQDN) */ | |
5255 | struct sadb_ident *id; | |
5256 | int fqdnlen; | |
5257 | ||
5258 | fqdnlen = strlen(fqdn) + 1; /* +1 for terminating-NUL */ | |
5259 | id = (struct sadb_ident *)p; | |
5260 | bzero(id, sizeof(*id) + PFKEY_ALIGN8(fqdnlen)); | |
5261 | id->sadb_ident_len = PFKEY_UNIT64(sizeof(*id) + PFKEY_ALIGN8(fqdnlen)); | |
5262 | id->sadb_ident_exttype = idexttype; | |
5263 | id->sadb_ident_type = SADB_IDENTTYPE_FQDN; | |
5264 | bcopy(fqdn, id + 1, fqdnlen); | |
5265 | p += sizeof(struct sadb_ident) + PFKEY_ALIGN8(fqdnlen); | |
5266 | } | |
5267 | ||
5268 | if (idexttype) { | |
5269 | /* create identity extension (USERFQDN) */ | |
5270 | struct sadb_ident *id; | |
5271 | int userfqdnlen; | |
5272 | ||
5273 | if (userfqdn) { | |
5274 | /* +1 for terminating-NUL */ | |
5275 | userfqdnlen = strlen(userfqdn) + 1; | |
5276 | } else | |
5277 | userfqdnlen = 0; | |
5278 | id = (struct sadb_ident *)p; | |
5279 | bzero(id, sizeof(*id) + PFKEY_ALIGN8(userfqdnlen)); | |
5280 | id->sadb_ident_len = PFKEY_UNIT64(sizeof(*id) + PFKEY_ALIGN8(userfqdnlen)); | |
5281 | id->sadb_ident_exttype = idexttype; | |
5282 | id->sadb_ident_type = SADB_IDENTTYPE_USERFQDN; | |
5283 | /* XXX is it correct? */ | |
5284 | if (curproc && curproc->p_cred) | |
5285 | id->sadb_ident_id = curproc->p_cred->p_ruid; | |
5286 | if (userfqdn && userfqdnlen) | |
5287 | bcopy(userfqdn, id + 1, userfqdnlen); | |
5288 | p += sizeof(struct sadb_ident) + PFKEY_ALIGN8(userfqdnlen); | |
5289 | } | |
5290 | #endif | |
5291 | ||
5292 | error = key_sendall(newmsg, len); | |
5293 | #if IPSEC_DEBUG | |
5294 | if (error != 0) | |
5295 | printf("key_acquire: key_sendall returned %d\n", error); | |
5296 | #endif | |
5297 | return error; | |
5298 | } | |
5299 | ||
5300 | return 0; | |
5301 | } | |
5302 | ||
5303 | #ifndef IPSEC_NONBLOCK_ACQUIRE | |
5304 | static struct secacq * | |
5305 | key_newacq(saidx) | |
5306 | struct secasindex *saidx; | |
5307 | { | |
5308 | struct secacq *newacq; | |
5309 | ||
5310 | /* get new entry */ | |
5311 | KMALLOC(newacq, struct secacq *, sizeof(struct secacq)); | |
5312 | if (newacq == NULL) { | |
5313 | #if IPSEC_DEBUG | |
5314 | printf("key_newacq: No more memory.\n"); | |
5315 | #endif | |
5316 | return NULL; | |
5317 | } | |
5318 | bzero(newacq, sizeof(*newacq)); | |
5319 | ||
5320 | /* copy secindex */ | |
5321 | bcopy(saidx, &newacq->saidx, sizeof(newacq->saidx)); | |
5322 | newacq->seq = (acq_seq == ~0 ? 1 : ++acq_seq); | |
5323 | newacq->tick = 0; | |
5324 | newacq->count = 0; | |
5325 | ||
5326 | return newacq; | |
5327 | } | |
5328 | ||
5329 | static struct secacq * | |
5330 | key_getacq(saidx) | |
5331 | struct secasindex *saidx; | |
5332 | { | |
5333 | struct secacq *acq; | |
5334 | ||
5335 | LIST_FOREACH(acq, &acqtree, chain) { | |
5336 | if (key_cmpsaidx_exactly(saidx, &acq->saidx)) | |
5337 | return acq; | |
5338 | } | |
5339 | ||
5340 | return NULL; | |
5341 | } | |
5342 | ||
5343 | static struct secacq * | |
5344 | key_getacqbyseq(seq) | |
5345 | u_int32_t seq; | |
5346 | { | |
5347 | struct secacq *acq; | |
5348 | ||
5349 | LIST_FOREACH(acq, &acqtree, chain) { | |
5350 | if (acq->seq == seq) | |
5351 | return acq; | |
5352 | } | |
5353 | ||
5354 | return NULL; | |
5355 | } | |
5356 | #endif | |
5357 | ||
5358 | static struct secspacq * | |
5359 | key_newspacq(spidx) | |
5360 | struct secpolicyindex *spidx; | |
5361 | { | |
5362 | struct secspacq *acq; | |
5363 | ||
5364 | /* get new entry */ | |
5365 | KMALLOC(acq, struct secspacq *, sizeof(struct secspacq)); | |
5366 | if (acq == NULL) { | |
5367 | #if IPSEC_DEBUG | |
5368 | printf("key_newspacq: No more memory.\n"); | |
5369 | #endif | |
5370 | return NULL; | |
5371 | } | |
5372 | bzero(acq, sizeof(*acq)); | |
5373 | ||
5374 | /* copy secindex */ | |
5375 | bcopy(spidx, &acq->spidx, sizeof(acq->spidx)); | |
5376 | acq->tick = 0; | |
5377 | acq->count = 0; | |
5378 | ||
5379 | return acq; | |
5380 | } | |
5381 | ||
5382 | static struct secspacq * | |
5383 | key_getspacq(spidx) | |
5384 | struct secpolicyindex *spidx; | |
5385 | { | |
5386 | struct secspacq *acq; | |
5387 | ||
5388 | LIST_FOREACH(acq, &spacqtree, chain) { | |
5389 | if (key_cmpspidx_exactly(spidx, &acq->spidx)) | |
5390 | return acq; | |
5391 | } | |
5392 | ||
5393 | return NULL; | |
5394 | } | |
5395 | ||
5396 | /* | |
5397 | * SADB_ACQUIRE processing, | |
5398 | * in first situation, is receiving | |
5399 | * <base> | |
5400 | * from the ikmpd, and clear sequence of its secasvar entry. | |
5401 | * | |
5402 | * In second situation, is receiving | |
5403 | * <base, address(SD), (address(P),) (identity(SD),) (sensitivity,) proposal> | |
5404 | * from a user land process, and return | |
5405 | * <base, address(SD), (address(P),) (identity(SD),) (sensitivity,) proposal> | |
5406 | * to the socket. | |
5407 | * | |
5408 | * IN: mhp: pointer to the pointer to each header. | |
5409 | * OUT: NULL if fail. | |
5410 | * other if success, return pointer to the message to send. | |
5411 | */ | |
5412 | static struct sadb_msg * | |
5413 | key_acquire2(mhp) | |
5414 | caddr_t *mhp; | |
5415 | { | |
5416 | struct sadb_msg *msg0; | |
5417 | struct sadb_address *src0, *dst0; | |
5418 | struct secasindex saidx; | |
5419 | struct secashead *sah; | |
5420 | u_int16_t proto; | |
5421 | ||
5422 | /* sanity check */ | |
5423 | if (mhp == NULL || mhp[0] == NULL) | |
5424 | panic("key_acquire2: NULL pointer is passed.\n"); | |
5425 | ||
5426 | msg0 = (struct sadb_msg *)mhp[0]; | |
5427 | ||
5428 | /* | |
5429 | * Error message from KMd. | |
5430 | * We assume that if error was occured in IKEd, the length of PFKEY | |
5431 | * message is equal to the size of sadb_msg structure. | |
5432 | * We return ~0 even if error occured in this function. | |
5433 | */ | |
5434 | if (msg0->sadb_msg_len == PFKEY_UNIT64(sizeof(struct sadb_msg))) { | |
5435 | ||
5436 | #ifndef IPSEC_NONBLOCK_ACQUIRE | |
5437 | struct secacq *acq; | |
5438 | ||
5439 | /* check sequence number */ | |
5440 | if (msg0->sadb_msg_seq == 0) { | |
5441 | #if IPSEC_DEBUG | |
5442 | printf("key_acquire2: must specify sequence number.\n"); | |
5443 | #endif | |
5444 | return (struct sadb_msg *)~0; | |
5445 | } | |
5446 | ||
5447 | if ((acq = key_getacqbyseq(msg0->sadb_msg_seq)) == NULL) { | |
5448 | #if IPSEC_DEBUG | |
5449 | printf("key_acquire2: " | |
5450 | "invalid sequence number is passed.\n"); | |
5451 | #endif | |
5452 | return (struct sadb_msg *)~0; | |
5453 | } | |
5454 | ||
5455 | /* reset acq counter in order to deletion by timehander. */ | |
5456 | acq->tick = key_blockacq_lifetime; | |
5457 | acq->count = 0; | |
5458 | #endif | |
5459 | return (struct sadb_msg *)~0; | |
5460 | /* NOTREACHED */ | |
5461 | } | |
5462 | ||
5463 | /* | |
5464 | * This message is from user land. | |
5465 | */ | |
5466 | ||
5467 | /* map satype to proto */ | |
5468 | if ((proto = key_satype2proto(msg0->sadb_msg_satype)) == 0) { | |
5469 | #if IPSEC_DEBUG | |
5470 | printf("key_acquire2: invalid satype is passed.\n"); | |
5471 | #endif | |
5472 | msg0->sadb_msg_errno = EINVAL; | |
5473 | return NULL; | |
5474 | } | |
5475 | ||
5476 | if (mhp[SADB_EXT_ADDRESS_SRC] == NULL | |
5477 | || mhp[SADB_EXT_ADDRESS_DST] == NULL | |
5478 | || mhp[SADB_EXT_PROPOSAL] == NULL) { | |
5479 | /* error */ | |
5480 | #if IPSEC_DEBUG | |
5481 | printf("key_acquire2: invalid message is passed.\n"); | |
5482 | #endif | |
5483 | msg0->sadb_msg_errno = EINVAL; | |
5484 | return NULL; | |
5485 | } | |
5486 | src0 = (struct sadb_address *)(mhp[SADB_EXT_ADDRESS_SRC]); | |
5487 | dst0 = (struct sadb_address *)(mhp[SADB_EXT_ADDRESS_DST]); | |
5488 | ||
5489 | KEY_SETSECASIDX(proto, msg0, src0+1, dst0+1, &saidx); | |
5490 | ||
5491 | /* get a SA index */ | |
5492 | if ((sah = key_getsah(&saidx)) != NULL) { | |
5493 | #if IPSEC_DEBUG | |
5494 | printf("key_acquire2: a SA exists already.\n"); | |
5495 | #endif | |
5496 | msg0->sadb_msg_errno = EEXIST; | |
5497 | return NULL; | |
5498 | } | |
5499 | ||
5500 | msg0->sadb_msg_errno = key_acquire(&saidx, NULL); | |
5501 | if (msg0->sadb_msg_errno != 0) { | |
5502 | #if IPSEC_DEBUG | |
5503 | printf("key_acquire2: error %d returned " | |
5504 | "from key_acquire.\n", msg0->sadb_msg_errno); | |
5505 | #endif | |
5506 | return NULL; | |
5507 | } | |
5508 | ||
5509 | { | |
5510 | struct sadb_msg *newmsg; | |
5511 | u_int len; | |
5512 | ||
5513 | /* create new sadb_msg to reply. */ | |
5514 | len = PFKEY_UNUNIT64(msg0->sadb_msg_len); | |
5515 | ||
5516 | KMALLOC(newmsg, struct sadb_msg *, len); | |
5517 | if (newmsg == NULL) { | |
5518 | #if IPSEC_DEBUG | |
5519 | printf("key_acquire2: No more memory.\n"); | |
5520 | #endif | |
5521 | msg0->sadb_msg_errno = ENOBUFS; | |
5522 | return NULL; | |
5523 | } | |
5524 | bzero((caddr_t)newmsg, len); | |
5525 | ||
5526 | bcopy(mhp[0], (caddr_t)newmsg, len); | |
5527 | ||
5528 | return newmsg; | |
5529 | } | |
5530 | } | |
5531 | ||
5532 | /* | |
5533 | * SADB_REGISTER processing. | |
5534 | * If SATYPE_UNSPEC has been passed as satype, only return sabd_supported. | |
5535 | * receive | |
5536 | * <base> | |
5537 | * from the ikmpd, and register a socket to send PF_KEY messages, | |
5538 | * and send | |
5539 | * <base, supported> | |
5540 | * to KMD by PF_KEY. | |
5541 | * If socket is detached, must free from regnode. | |
5542 | * OUT: | |
5543 | * 0 : succeed | |
5544 | * others: error number | |
5545 | */ | |
5546 | static struct sadb_msg * | |
5547 | key_register(mhp, so) | |
5548 | caddr_t *mhp; | |
5549 | struct socket *so; | |
5550 | { | |
5551 | struct sadb_msg *msg0; | |
5552 | struct secreg *reg, *newreg = 0; | |
5553 | ||
5554 | /* sanity check */ | |
5555 | if (mhp == NULL || so == NULL || mhp[0] == NULL) | |
5556 | panic("key_register: NULL pointer is passed.\n"); | |
5557 | ||
5558 | msg0 = (struct sadb_msg *)mhp[0]; | |
5559 | ||
5560 | /* check for invalid register message */ | |
5561 | if (msg0->sadb_msg_satype >= sizeof(regtree)/sizeof(regtree[0])) { | |
5562 | msg0->sadb_msg_errno = EINVAL; | |
5563 | return NULL; | |
5564 | } | |
5565 | ||
5566 | /* When SATYPE_UNSPEC is specified, only return sabd_supported. */ | |
5567 | if (msg0->sadb_msg_satype == SADB_SATYPE_UNSPEC) | |
5568 | goto setmsg; | |
5569 | ||
5570 | /* check whether existing or not */ | |
5571 | LIST_FOREACH(reg, ®tree[msg0->sadb_msg_satype], chain) { | |
5572 | if (reg->so == so) { | |
5573 | #if IPSEC_DEBUG | |
5574 | printf("key_register: socket exists already.\n"); | |
5575 | #endif | |
5576 | msg0->sadb_msg_errno = EEXIST; | |
5577 | return NULL; | |
5578 | } | |
5579 | } | |
5580 | ||
5581 | /* create regnode */ | |
5582 | KMALLOC(newreg, struct secreg *, sizeof(struct secreg)); | |
5583 | if (newreg == NULL) { | |
5584 | #if IPSEC_DEBUG | |
5585 | printf("key_register: No more memory.\n"); | |
5586 | #endif | |
5587 | msg0->sadb_msg_errno = ENOBUFS; | |
5588 | return NULL; | |
5589 | } | |
5590 | bzero((caddr_t)newreg, sizeof(struct secreg)); | |
5591 | ||
5592 | newreg->so = so; | |
5593 | ((struct keycb *)sotorawcb(so))->kp_registered++; | |
5594 | ||
5595 | /* add regnode to regtree. */ | |
5596 | LIST_INSERT_HEAD(®tree[msg0->sadb_msg_satype], newreg, chain); | |
5597 | ||
5598 | setmsg: | |
5599 | { | |
5600 | struct sadb_msg *newmsg; | |
5601 | struct sadb_supported *sup; | |
5602 | u_int len, alen, elen; | |
5603 | caddr_t p; | |
5604 | ||
5605 | /* create new sadb_msg to reply. */ | |
5606 | alen = sizeof(struct sadb_supported) | |
5607 | + ((SADB_AALG_MAX - 1) * sizeof(struct sadb_alg)); | |
5608 | ||
5609 | #if IPSEC_ESP | |
5610 | elen = sizeof(struct sadb_supported) | |
5611 | + ((SADB_EALG_MAX - 1) * sizeof(struct sadb_alg)); | |
5612 | #else | |
5613 | elen = 0; | |
5614 | #endif | |
5615 | ||
5616 | len = sizeof(struct sadb_msg) | |
5617 | + alen | |
5618 | + elen; | |
5619 | ||
5620 | KMALLOC(newmsg, struct sadb_msg *, len); | |
5621 | if (newmsg == NULL) { | |
5622 | #if IPSEC_DEBUG | |
5623 | printf("key_register: No more memory.\n"); | |
5624 | #endif | |
5625 | msg0->sadb_msg_errno = ENOBUFS; | |
5626 | return NULL; | |
5627 | } | |
5628 | bzero((caddr_t)newmsg, len); | |
5629 | ||
5630 | bcopy((caddr_t)mhp[0], (caddr_t)newmsg, sizeof(*msg0)); | |
5631 | newmsg->sadb_msg_errno = 0; | |
5632 | newmsg->sadb_msg_len = PFKEY_UNIT64(len); | |
5633 | p = (caddr_t)newmsg + sizeof(*msg0); | |
5634 | ||
5635 | /* for authentication algorithm */ | |
5636 | sup = (struct sadb_supported *)p; | |
5637 | sup->sadb_supported_len = PFKEY_UNIT64(alen); | |
5638 | sup->sadb_supported_exttype = SADB_EXT_SUPPORTED_AUTH; | |
5639 | p += sizeof(*sup); | |
5640 | ||
5641 | { | |
5642 | int i; | |
5643 | struct sadb_alg *alg; | |
5644 | struct ah_algorithm *algo; | |
5645 | ||
5646 | for (i = 1; i < SADB_AALG_MAX; i++) { | |
5647 | algo = &ah_algorithms[i]; | |
5648 | alg = (struct sadb_alg *)p; | |
5649 | alg->sadb_alg_id = i; | |
5650 | alg->sadb_alg_ivlen = 0; | |
5651 | alg->sadb_alg_minbits = algo->keymin; | |
5652 | alg->sadb_alg_maxbits = algo->keymax; | |
5653 | p += sizeof(struct sadb_alg); | |
5654 | } | |
5655 | } | |
5656 | ||
5657 | #if IPSEC_ESP | |
5658 | /* for encryption algorithm */ | |
5659 | sup = (struct sadb_supported *)p; | |
5660 | sup->sadb_supported_len = PFKEY_UNIT64(elen); | |
5661 | sup->sadb_supported_exttype = SADB_EXT_SUPPORTED_ENCRYPT; | |
5662 | p += sizeof(*sup); | |
5663 | ||
5664 | { | |
5665 | int i; | |
5666 | struct sadb_alg *alg; | |
5667 | struct esp_algorithm *algo; | |
5668 | ||
5669 | for (i = 1; i < SADB_EALG_MAX; i++) { | |
5670 | algo = &esp_algorithms[i]; | |
5671 | ||
5672 | alg = (struct sadb_alg *)p; | |
5673 | alg->sadb_alg_id = i; | |
5674 | if (algo && algo->ivlen) { | |
5675 | /* | |
5676 | * give NULL to get the value preferred by algorithm | |
5677 | * XXX SADB_X_EXT_DERIV ? | |
5678 | */ | |
5679 | alg->sadb_alg_ivlen = (*algo->ivlen)(NULL); | |
5680 | } else | |
5681 | alg->sadb_alg_ivlen = 0; | |
5682 | alg->sadb_alg_minbits = algo->keymin; | |
5683 | alg->sadb_alg_maxbits = algo->keymax; | |
5684 | p += sizeof(struct sadb_alg); | |
5685 | } | |
5686 | } | |
5687 | #endif | |
5688 | ||
5689 | return newmsg; | |
5690 | } | |
5691 | } | |
5692 | ||
5693 | /* | |
5694 | * free secreg entry registered. | |
5695 | * XXX: I want to do free a socket marked done SADB_RESIGER to socket. | |
5696 | */ | |
5697 | void | |
5698 | key_freereg(so) | |
5699 | struct socket *so; | |
5700 | { | |
5701 | struct secreg *reg; | |
5702 | int i; | |
5703 | ||
5704 | /* sanity check */ | |
5705 | if (so == NULL) | |
5706 | panic("key_freereg: NULL pointer is passed.\n"); | |
5707 | ||
5708 | /* | |
5709 | * check whether existing or not. | |
5710 | * check all type of SA, because there is a potential that | |
5711 | * one socket is registered to multiple type of SA. | |
5712 | */ | |
5713 | for (i = 0; i <= SADB_SATYPE_MAX; i++) { | |
5714 | LIST_FOREACH(reg, ®tree[i], chain) { | |
5715 | if (reg->so == so | |
5716 | && __LIST_CHAINED(reg)) { | |
5717 | LIST_REMOVE(reg, chain); | |
5718 | KFREE(reg); | |
5719 | break; | |
5720 | } | |
5721 | } | |
5722 | } | |
5723 | ||
5724 | return; | |
5725 | } | |
5726 | ||
5727 | /* | |
5728 | * SADB_EXPIRE processing | |
5729 | * send | |
5730 | * <base, SA, lifetime(C and one of HS), address(SD)> | |
5731 | * to KMD by PF_KEY. | |
5732 | * NOTE: We send only soft lifetime extension. | |
5733 | * | |
5734 | * OUT: 0 : succeed | |
5735 | * others : error number | |
5736 | */ | |
5737 | static int | |
5738 | key_expire(sav) | |
5739 | struct secasvar *sav; | |
5740 | { | |
5741 | int s; | |
5742 | int satype; | |
5743 | ||
5744 | /* XXX: Why do we lock ? */ | |
5745 | #ifdef __NetBSD__ | |
5746 | s = splsoftnet(); /*called from softclock()*/ | |
5747 | #else | |
5748 | s = splnet(); /*called from softclock()*/ | |
5749 | #endif | |
5750 | ||
5751 | /* sanity check */ | |
5752 | if (sav == NULL) | |
5753 | panic("key_expire: NULL pointer is passed.\n"); | |
5754 | if (sav->sah == NULL) | |
5755 | panic("key_expire: Why was SA index in SA NULL.\n"); | |
5756 | if ((satype = key_proto2satype(sav->sah->saidx.proto)) == 0) | |
5757 | panic("key_expire: invalid proto is passed.\n"); | |
5758 | ||
5759 | { | |
5760 | struct sadb_msg *newmsg = NULL; | |
5761 | u_int len; | |
5762 | caddr_t p; | |
5763 | int error; | |
5764 | ||
5765 | /* create new sadb_msg to reply. */ | |
5766 | len = sizeof(struct sadb_msg) | |
5767 | + sizeof(struct sadb_sa) | |
5768 | + sizeof(struct sadb_lifetime) | |
5769 | + sizeof(struct sadb_lifetime) | |
5770 | + sizeof(struct sadb_address) | |
5771 | + PFKEY_ALIGN8(sav->sah->saidx.src.ss_len) | |
5772 | + sizeof(struct sadb_address) | |
5773 | + PFKEY_ALIGN8(sav->sah->saidx.dst.ss_len); | |
5774 | ||
5775 | KMALLOC(newmsg, struct sadb_msg *, len); | |
5776 | if (newmsg == NULL) { | |
5777 | #if IPSEC_DEBUG | |
5778 | printf("key_expire: No more memory.\n"); | |
5779 | #endif | |
5780 | splx(s); | |
5781 | return ENOBUFS; | |
5782 | } | |
5783 | bzero((caddr_t)newmsg, len); | |
5784 | ||
5785 | /* set msg header */ | |
5786 | p = key_setsadbmsg((caddr_t)newmsg, SADB_EXPIRE, len, | |
5787 | satype, sav->seq, 0, | |
5788 | sav->sah->saidx.mode, sav->sah->saidx.reqid, | |
5789 | 0, sav->refcnt); | |
5790 | ||
5791 | /* create SA extension */ | |
5792 | p = key_setsadbsa(p, sav); | |
5793 | ||
5794 | /* create lifetime extension */ | |
5795 | { | |
5796 | struct sadb_lifetime *m_lt = (struct sadb_lifetime *)p; | |
5797 | ||
5798 | m_lt->sadb_lifetime_len = PFKEY_UNIT64(sizeof(struct sadb_lifetime)); | |
5799 | m_lt->sadb_lifetime_exttype = SADB_EXT_LIFETIME_CURRENT; | |
5800 | m_lt->sadb_lifetime_allocations = sav->lft_c->sadb_lifetime_allocations; | |
5801 | m_lt->sadb_lifetime_bytes = sav->lft_c->sadb_lifetime_bytes; | |
5802 | m_lt->sadb_lifetime_addtime = sav->lft_c->sadb_lifetime_addtime; | |
5803 | m_lt->sadb_lifetime_usetime = sav->lft_c->sadb_lifetime_usetime; | |
5804 | p += sizeof(struct sadb_lifetime); | |
5805 | ||
5806 | /* copy SOFT lifetime extension. */ | |
5807 | bcopy(sav->lft_s, p, sizeof(struct sadb_lifetime)); | |
5808 | p += sizeof(struct sadb_lifetime); | |
5809 | } | |
5810 | ||
5811 | /* set sadb_address for source */ | |
5812 | p = key_setsadbaddr(p, | |
5813 | SADB_EXT_ADDRESS_SRC, | |
5814 | (struct sockaddr *)&sav->sah->saidx.src, | |
5815 | _INALENBYAF(sav->sah->saidx.src.ss_family) << 3, | |
5816 | IPSEC_ULPROTO_ANY); | |
5817 | ||
5818 | /* set sadb_address for destination */ | |
5819 | p = key_setsadbaddr(p, | |
5820 | SADB_EXT_ADDRESS_DST, | |
5821 | (struct sockaddr *)&sav->sah->saidx.dst, | |
5822 | _INALENBYAF(sav->sah->saidx.dst.ss_family) << 3, | |
5823 | IPSEC_ULPROTO_ANY); | |
5824 | ||
5825 | error = key_sendall(newmsg, len); | |
5826 | splx(s); | |
5827 | return error; | |
5828 | } | |
5829 | } | |
5830 | ||
5831 | /* | |
5832 | * SADB_FLUSH processing | |
5833 | * receive | |
5834 | * <base> | |
5835 | * from the ikmpd, and free all entries in secastree. | |
5836 | * and send, | |
5837 | * <base> | |
5838 | * to the ikmpd. | |
5839 | * NOTE: to do is only marking SADB_SASTATE_DEAD. | |
5840 | * | |
5841 | * IN: mhp: pointer to the pointer to each header. | |
5842 | * OUT: NULL if fail. | |
5843 | * other if success, return pointer to the message to send. | |
5844 | */ | |
5845 | static struct sadb_msg * | |
5846 | key_flush(mhp) | |
5847 | caddr_t *mhp; | |
5848 | { | |
5849 | struct sadb_msg *msg0; | |
5850 | struct secashead *sah, *nextsah; | |
5851 | struct secasvar *sav, *nextsav; | |
5852 | u_int16_t proto; | |
5853 | u_int8_t state; | |
5854 | u_int stateidx; | |
5855 | ||
5856 | /* sanity check */ | |
5857 | if (mhp == NULL || mhp[0] == NULL) | |
5858 | panic("key_flush: NULL pointer is passed.\n"); | |
5859 | ||
5860 | msg0 = (struct sadb_msg *)mhp[0]; | |
5861 | ||
5862 | /* map satype to proto */ | |
5863 | if ((proto = key_satype2proto(msg0->sadb_msg_satype)) == 0) { | |
5864 | #if IPSEC_DEBUG | |
5865 | printf("key_flush: invalid satype is passed.\n"); | |
5866 | #endif | |
5867 | msg0->sadb_msg_errno = EINVAL; | |
5868 | return NULL; | |
5869 | } | |
5870 | ||
5871 | /* no SATYPE specified, i.e. flushing all SA. */ | |
5872 | for (sah = LIST_FIRST(&sahtree); | |
5873 | sah != NULL; | |
5874 | sah = nextsah) { | |
5875 | ||
5876 | nextsah = LIST_NEXT(sah, chain); | |
5877 | ||
5878 | if (msg0->sadb_msg_satype != SADB_SATYPE_UNSPEC | |
5879 | && proto != sah->saidx.proto) | |
5880 | continue; | |
5881 | ||
5882 | for (stateidx = 0; | |
5883 | stateidx < _ARRAYLEN(saorder_state_alive); | |
5884 | stateidx++) { | |
5885 | ||
5886 | state = saorder_state_any[stateidx]; | |
5887 | for (sav = LIST_FIRST(&sah->savtree[state]); | |
5888 | sav != NULL; | |
5889 | sav = nextsav) { | |
5890 | ||
5891 | nextsav = LIST_NEXT(sav, chain); | |
5892 | ||
5893 | key_sa_chgstate(sav, SADB_SASTATE_DEAD); | |
5894 | key_freesav(sav); | |
5895 | } | |
5896 | } | |
5897 | ||
5898 | sah->state = SADB_SASTATE_DEAD; | |
5899 | } | |
5900 | ||
5901 | { | |
5902 | struct sadb_msg *newmsg; | |
5903 | u_int len; | |
5904 | ||
5905 | /* create new sadb_msg to reply. */ | |
5906 | len = sizeof(struct sadb_msg); | |
5907 | ||
5908 | KMALLOC(newmsg, struct sadb_msg *, len); | |
5909 | if (newmsg == NULL) { | |
5910 | #if IPSEC_DEBUG | |
5911 | printf("key_flush: No more memory.\n"); | |
5912 | #endif | |
5913 | msg0->sadb_msg_errno = ENOBUFS; | |
5914 | return NULL; | |
5915 | } | |
5916 | bzero((caddr_t)newmsg, len); | |
5917 | ||
5918 | bcopy((caddr_t)mhp[0], (caddr_t)newmsg, sizeof(*msg0)); | |
5919 | newmsg->sadb_msg_errno = 0; | |
5920 | newmsg->sadb_msg_len = PFKEY_UNIT64(len); | |
5921 | ||
5922 | return newmsg; | |
5923 | } | |
5924 | } | |
5925 | ||
5926 | /* | |
5927 | * SADB_DUMP processing | |
5928 | * dump all entries including status of DEAD in SAD. | |
5929 | * receive | |
5930 | * <base> | |
5931 | * from the ikmpd, and dump all secasvar leaves | |
5932 | * and send, | |
5933 | * <base> ..... | |
5934 | * to the ikmpd. | |
5935 | * | |
5936 | * IN: mhp: pointer to the pointer to each header. | |
5937 | * OUT: error code. 0 on success. | |
5938 | */ | |
5939 | static int | |
5940 | key_dump(mhp, so, target) | |
5941 | caddr_t *mhp; | |
5942 | struct socket *so; | |
5943 | int target; | |
5944 | { | |
5945 | struct sadb_msg *msg0; | |
5946 | struct secashead *sah; | |
5947 | struct secasvar *sav; | |
5948 | u_int16_t proto; | |
5949 | u_int stateidx; | |
5950 | u_int8_t satype; | |
5951 | u_int8_t state; | |
5952 | int len, cnt; | |
5953 | struct sadb_msg *newmsg; | |
5954 | ||
5955 | /* sanity check */ | |
5956 | if (mhp == NULL || mhp[0] == NULL) | |
5957 | panic("key_dump: NULL pointer is passed.\n"); | |
5958 | ||
5959 | msg0 = (struct sadb_msg *)mhp[0]; | |
5960 | ||
5961 | /* map satype to proto */ | |
5962 | if ((proto = key_satype2proto(msg0->sadb_msg_satype)) == 0) { | |
5963 | #if IPSEC_DEBUG | |
5964 | printf("key_dump: invalid satype is passed.\n"); | |
5965 | #endif | |
5966 | msg0->sadb_msg_errno = EINVAL; | |
5967 | return NULL; | |
5968 | } | |
5969 | ||
5970 | /* count sav entries to be sent to the userland. */ | |
5971 | cnt = 0; | |
5972 | LIST_FOREACH(sah, &sahtree, chain) { | |
5973 | ||
5974 | if (msg0->sadb_msg_satype != SADB_SATYPE_UNSPEC | |
5975 | && proto != sah->saidx.proto) | |
5976 | continue; | |
5977 | ||
5978 | for (stateidx = 0; | |
5979 | stateidx < _ARRAYLEN(saorder_state_any); | |
5980 | stateidx++) { | |
5981 | ||
5982 | state = saorder_state_any[stateidx]; | |
5983 | LIST_FOREACH(sav, &sah->savtree[state], chain) { | |
5984 | cnt++; | |
5985 | } | |
5986 | } | |
5987 | } | |
5988 | ||
5989 | if (cnt == 0) | |
5990 | return ENOENT; | |
5991 | ||
5992 | /* send this to the userland, one at a time. */ | |
5993 | newmsg = NULL; | |
5994 | LIST_FOREACH(sah, &sahtree, chain) { | |
5995 | ||
5996 | if (msg0->sadb_msg_satype != SADB_SATYPE_UNSPEC | |
5997 | && proto != sah->saidx.proto) | |
5998 | continue; | |
5999 | ||
6000 | /* map proto to satype */ | |
6001 | if ((satype = key_proto2satype(sah->saidx.proto)) == 0) { | |
6002 | #if IPSEC_DEBUG | |
6003 | printf("key_dump: there was invalid proto in SAD.\n"); | |
6004 | #endif | |
6005 | msg0->sadb_msg_errno = EINVAL; | |
6006 | return NULL; | |
6007 | } | |
6008 | ||
6009 | for (stateidx = 0; | |
6010 | stateidx < _ARRAYLEN(saorder_state_any); | |
6011 | stateidx++) { | |
6012 | ||
6013 | state = saorder_state_any[stateidx]; | |
6014 | LIST_FOREACH(sav, &sah->savtree[state], chain) { | |
6015 | ||
6016 | len = key_getmsglen(sav); | |
6017 | KMALLOC(newmsg, struct sadb_msg *, len); | |
6018 | if (newmsg == NULL) { | |
6019 | #if IPSEC_DEBUG | |
6020 | printf("key_dump: No more memory.\n"); | |
6021 | #endif | |
6022 | return ENOBUFS; | |
6023 | } | |
6024 | bzero((caddr_t)newmsg, len); | |
6025 | ||
6026 | --cnt; | |
6027 | (void)key_setdumpsa(newmsg, sav, SADB_DUMP, | |
6028 | satype, cnt, msg0->sadb_msg_pid); | |
6029 | ||
6030 | key_sendup(so, newmsg, len, target); | |
6031 | KFREE(newmsg); | |
6032 | newmsg = NULL; | |
6033 | } | |
6034 | } | |
6035 | } | |
6036 | ||
6037 | return 0; | |
6038 | } | |
6039 | ||
6040 | /* | |
6041 | * SADB_X_PROMISC processing | |
6042 | */ | |
6043 | static void | |
6044 | key_promisc(mhp, so) | |
6045 | caddr_t *mhp; | |
6046 | struct socket *so; | |
6047 | { | |
6048 | struct sadb_msg *msg0; | |
6049 | int olen; | |
6050 | ||
6051 | /* sanity check */ | |
6052 | if (mhp == NULL || mhp[0] == NULL) | |
6053 | panic("key_promisc: NULL pointer is passed.\n"); | |
6054 | ||
6055 | msg0 = (struct sadb_msg *)mhp[0]; | |
6056 | olen = PFKEY_UNUNIT64(msg0->sadb_msg_len); | |
6057 | ||
6058 | if (olen < sizeof(struct sadb_msg)) { | |
6059 | return; | |
6060 | } else if (olen == sizeof(struct sadb_msg)) { | |
6061 | /* enable/disable promisc mode */ | |
6062 | struct keycb *kp; | |
6063 | int target = 0; | |
6064 | ||
6065 | target = KEY_SENDUP_ONE; | |
6066 | ||
6067 | if (so == NULL) { | |
6068 | return; | |
6069 | } | |
6070 | if ((kp = (struct keycb *)sotorawcb(so)) == NULL) { | |
6071 | msg0->sadb_msg_errno = EINVAL; | |
6072 | goto sendorig; | |
6073 | } | |
6074 | msg0->sadb_msg_errno = 0; | |
6075 | if (msg0->sadb_msg_satype == 1 || msg0->sadb_msg_satype == 0) { | |
6076 | kp->kp_promisc = msg0->sadb_msg_satype; | |
6077 | } else { | |
6078 | msg0->sadb_msg_errno = EINVAL; | |
6079 | goto sendorig; | |
6080 | } | |
6081 | ||
6082 | /* send the original message back to everyone */ | |
6083 | msg0->sadb_msg_errno = 0; | |
6084 | target = KEY_SENDUP_ALL; | |
6085 | sendorig: | |
6086 | key_sendup(so, msg0, PFKEY_UNUNIT64(msg0->sadb_msg_len), target); | |
6087 | } else { | |
6088 | /* send packet as is */ | |
6089 | struct sadb_msg *msg; | |
6090 | int len; | |
6091 | ||
6092 | len = olen - sizeof(struct sadb_msg); | |
6093 | KMALLOC(msg, struct sadb_msg *, len); | |
6094 | if (msg == NULL) { | |
6095 | msg0->sadb_msg_errno = ENOBUFS; | |
6096 | key_sendup(so, msg0, PFKEY_UNUNIT64(msg0->sadb_msg_len), | |
6097 | KEY_SENDUP_ONE); /*XXX*/ | |
6098 | } | |
6099 | ||
6100 | /* XXX if sadb_msg_seq is specified, send to specific pid */ | |
6101 | key_sendup(so, msg, len, KEY_SENDUP_ALL); | |
6102 | KFREE(msg); | |
6103 | } | |
6104 | } | |
6105 | ||
6106 | /* | |
6107 | * send message to the socket. | |
6108 | * OUT: | |
6109 | * 0 : success | |
6110 | * others : fail | |
6111 | */ | |
6112 | static int | |
6113 | key_sendall(msg, len) | |
6114 | struct sadb_msg *msg; | |
6115 | u_int len; | |
6116 | { | |
6117 | struct secreg *reg; | |
6118 | int error = 0; | |
6119 | ||
6120 | /* sanity check */ | |
6121 | if (msg == NULL) | |
6122 | panic("key_sendall: NULL pointer is passed.\n"); | |
6123 | ||
6124 | /* search table registerd socket to send a message. */ | |
6125 | LIST_FOREACH(reg, ®tree[msg->sadb_msg_satype], chain) { | |
6126 | error = key_sendup(reg->so, msg, len, KEY_SENDUP_ONE); | |
6127 | if (error != 0) { | |
6128 | #if IPSEC_DEBUG | |
6129 | if (error == ENOBUFS) | |
6130 | printf("key_sendall: No more memory.\n"); | |
6131 | else { | |
6132 | printf("key_sendall: key_sendup returned %d\n", | |
6133 | error); | |
6134 | } | |
6135 | #endif | |
6136 | KFREE(msg); | |
6137 | return error; | |
6138 | } | |
6139 | } | |
6140 | ||
6141 | KFREE(msg); | |
6142 | return 0; | |
6143 | } | |
6144 | ||
6145 | /* | |
6146 | * parse sadb_msg buffer to process PFKEYv2, | |
6147 | * and create a data to response if needed. | |
6148 | * I think to be dealed with mbuf directly. | |
6149 | * IN: | |
6150 | * msgp : pointer to pointer to a received buffer pulluped. | |
6151 | * This is rewrited to response. | |
6152 | * so : pointer to socket. | |
6153 | * OUT: | |
6154 | * length for buffer to send to user process. | |
6155 | */ | |
6156 | int | |
6157 | key_parse(msgp, so, targetp) | |
6158 | struct sadb_msg **msgp; | |
6159 | struct socket *so; | |
6160 | int *targetp; | |
6161 | { | |
6162 | struct sadb_msg *msg = *msgp, *newmsg = NULL; | |
6163 | caddr_t mhp[SADB_EXT_MAX + 1]; | |
6164 | u_int orglen; | |
6165 | int error; | |
6166 | ||
6167 | /* sanity check */ | |
6168 | if (msg == NULL || so == NULL) | |
6169 | panic("key_parse: NULL pointer is passed.\n"); | |
6170 | ||
6171 | KEYDEBUG(KEYDEBUG_KEY_DUMP, | |
6172 | printf("key_parse: passed sadb_msg\n"); | |
6173 | kdebug_sadb(msg)); | |
6174 | ||
6175 | orglen = PFKEY_UNUNIT64(msg->sadb_msg_len); | |
6176 | ||
6177 | if (targetp) | |
6178 | *targetp = KEY_SENDUP_ONE; | |
6179 | ||
6180 | /* check version */ | |
6181 | if (msg->sadb_msg_version != PF_KEY_V2) { | |
6182 | #if IPSEC_DEBUG | |
6183 | printf("key_parse: PF_KEY version %u is mismatched.\n", | |
6184 | msg->sadb_msg_version); | |
6185 | #endif | |
6186 | pfkeystat.out_invver++; | |
6187 | msg->sadb_msg_errno = EINVAL; | |
6188 | return orglen; | |
6189 | } | |
6190 | ||
6191 | /* check type */ | |
6192 | if (msg->sadb_msg_type > SADB_MAX) { | |
6193 | #if IPSEC_DEBUG | |
6194 | printf("key_parse: invalid type %u is passed.\n", | |
6195 | msg->sadb_msg_type); | |
6196 | #endif | |
6197 | msg->sadb_msg_errno = EINVAL; | |
6198 | pfkeystat.out_invmsgtype++; | |
6199 | return orglen; | |
6200 | } | |
6201 | ||
6202 | /* align message. */ | |
6203 | if (key_align(msg, mhp) != 0) { | |
6204 | msg->sadb_msg_errno = EINVAL; | |
6205 | return orglen; | |
6206 | } | |
6207 | ||
6208 | /* check SA type */ | |
6209 | switch (msg->sadb_msg_satype) { | |
6210 | case SADB_SATYPE_UNSPEC: | |
6211 | switch (msg->sadb_msg_type) { | |
6212 | case SADB_GETSPI: | |
6213 | case SADB_UPDATE: | |
6214 | case SADB_ADD: | |
6215 | case SADB_DELETE: | |
6216 | case SADB_GET: | |
6217 | case SADB_ACQUIRE: | |
6218 | case SADB_EXPIRE: | |
6219 | #if IPSEC_DEBUG | |
6220 | printf("key_parse: must specify satype " | |
6221 | "when msg type=%u.\n", | |
6222 | msg->sadb_msg_type); | |
6223 | #endif | |
6224 | msg->sadb_msg_errno = EINVAL; | |
6225 | pfkeystat.out_invsatype++; | |
6226 | return orglen; | |
6227 | } | |
6228 | break; | |
6229 | case SADB_SATYPE_AH: | |
6230 | case SADB_SATYPE_ESP: | |
6231 | #if 1 /*nonstandard*/ | |
6232 | case SADB_X_SATYPE_IPCOMP: | |
6233 | #endif | |
6234 | switch (msg->sadb_msg_type) { | |
6235 | case SADB_X_SPDADD: | |
6236 | case SADB_X_SPDDELETE: | |
6237 | case SADB_X_SPDGET: | |
6238 | case SADB_X_SPDDUMP: | |
6239 | case SADB_X_SPDFLUSH: | |
6240 | case SADB_X_SPDSETIDX: | |
6241 | case SADB_X_SPDUPDATE: | |
6242 | case SADB_X_SPDDELETE2: | |
6243 | #if IPSEC_DEBUG | |
6244 | printf("key_parse: illegal satype=%u\n", | |
6245 | msg->sadb_msg_type); | |
6246 | #endif | |
6247 | msg->sadb_msg_errno = EINVAL; | |
6248 | pfkeystat.out_invsatype++; | |
6249 | return orglen; | |
6250 | } | |
6251 | break; | |
6252 | case SADB_SATYPE_RSVP: | |
6253 | case SADB_SATYPE_OSPFV2: | |
6254 | case SADB_SATYPE_RIPV2: | |
6255 | case SADB_SATYPE_MIP: | |
6256 | #if IPSEC_DEBUG | |
6257 | printf("key_parse: type %u isn't supported.\n", | |
6258 | msg->sadb_msg_satype); | |
6259 | #endif | |
6260 | msg->sadb_msg_errno = EOPNOTSUPP; | |
6261 | pfkeystat.out_invsatype++; | |
6262 | return orglen; | |
6263 | case 1: /* XXX: What does it do ? */ | |
6264 | if (msg->sadb_msg_type == SADB_X_PROMISC) | |
6265 | break; | |
6266 | /*FALLTHROUGH*/ | |
6267 | default: | |
6268 | #if IPSEC_DEBUG | |
6269 | printf("key_parse: invalid type %u is passed.\n", | |
6270 | msg->sadb_msg_satype); | |
6271 | #endif | |
6272 | msg->sadb_msg_errno = EINVAL; | |
6273 | pfkeystat.out_invsatype++; | |
6274 | return orglen; | |
6275 | } | |
6276 | ||
6277 | /* check field of upper layer protocol and address family */ | |
6278 | if (mhp[SADB_EXT_ADDRESS_SRC] != NULL | |
6279 | && mhp[SADB_EXT_ADDRESS_DST] != NULL) { | |
6280 | struct sadb_address *src0, *dst0; | |
6281 | u_int prefix; | |
6282 | ||
6283 | src0 = (struct sadb_address *)(mhp[SADB_EXT_ADDRESS_SRC]); | |
6284 | dst0 = (struct sadb_address *)(mhp[SADB_EXT_ADDRESS_DST]); | |
6285 | ||
6286 | /* check upper layer protocol */ | |
6287 | if (src0->sadb_address_proto != dst0->sadb_address_proto) { | |
6288 | #if IPSEC_DEBUG | |
6289 | printf("key_parse: upper layer protocol mismatched.\n"); | |
6290 | #endif | |
6291 | msg->sadb_msg_errno = EINVAL; | |
6292 | pfkeystat.out_invaddr++; | |
6293 | return orglen; | |
6294 | } | |
6295 | ||
6296 | /* check family */ | |
6297 | if (PFKEY_ADDR_SADDR(src0)->sa_family | |
6298 | != PFKEY_ADDR_SADDR(dst0)->sa_family) { | |
6299 | #if IPSEC_DEBUG | |
6300 | printf("key_parse: address family mismatched.\n"); | |
6301 | #endif | |
6302 | msg->sadb_msg_errno = EINVAL; | |
6303 | pfkeystat.out_invaddr++; | |
6304 | return orglen; | |
6305 | } | |
6306 | ||
6307 | prefix = _INALENBYAF(PFKEY_ADDR_SADDR(src0)->sa_family) << 3; | |
6308 | ||
6309 | /* check max prefixlen */ | |
6310 | if (prefix < src0->sadb_address_prefixlen | |
6311 | || prefix < dst0->sadb_address_prefixlen) { | |
6312 | #if IPSEC_DEBUG | |
6313 | printf("key_parse: illegal prefixlen.\n"); | |
6314 | #endif | |
6315 | msg->sadb_msg_errno = EINVAL; | |
6316 | pfkeystat.out_invaddr++; | |
6317 | return orglen; | |
6318 | } | |
6319 | ||
6320 | switch (PFKEY_ADDR_SADDR(src0)->sa_family) { | |
6321 | case AF_INET: | |
6322 | case AF_INET6: | |
6323 | break; | |
6324 | default: | |
6325 | #if IPSEC_DEBUG | |
6326 | printf("key_parse: invalid address family.\n"); | |
6327 | #endif | |
6328 | msg->sadb_msg_errno = EINVAL; | |
6329 | pfkeystat.out_invaddr++; | |
6330 | return orglen; | |
6331 | } | |
6332 | ||
6333 | /* | |
6334 | * prefixlen == 0 is valid because there can be a case when | |
6335 | * all addresses are matched. | |
6336 | */ | |
6337 | } | |
6338 | ||
6339 | switch (msg->sadb_msg_type) { | |
6340 | case SADB_GETSPI: | |
6341 | if ((newmsg = key_getspi(mhp)) == NULL) | |
6342 | return orglen; | |
6343 | if (targetp) | |
6344 | *targetp = KEY_SENDUP_ALL; | |
6345 | break; | |
6346 | ||
6347 | case SADB_UPDATE: | |
6348 | if ((newmsg = key_update(mhp)) == NULL) | |
6349 | return orglen; | |
6350 | if (targetp) | |
6351 | *targetp = KEY_SENDUP_ALL; | |
6352 | break; | |
6353 | ||
6354 | case SADB_ADD: | |
6355 | if ((newmsg = key_add(mhp)) == NULL) | |
6356 | return orglen; | |
6357 | if (targetp) | |
6358 | *targetp = KEY_SENDUP_ALL; | |
6359 | break; | |
6360 | ||
6361 | case SADB_DELETE: | |
6362 | if ((newmsg = key_delete(mhp)) == NULL) | |
6363 | return orglen; | |
6364 | if (targetp) | |
6365 | *targetp = KEY_SENDUP_ALL; | |
6366 | break; | |
6367 | ||
6368 | case SADB_GET: | |
6369 | if ((newmsg = key_get(mhp)) == NULL) | |
6370 | return orglen; | |
6371 | break; | |
6372 | ||
6373 | case SADB_ACQUIRE: | |
6374 | if ((newmsg = key_acquire2(mhp)) == NULL) | |
6375 | return orglen; | |
6376 | ||
6377 | if (newmsg == (struct sadb_msg *)~0) { | |
6378 | /* | |
6379 | * It's not need to reply because of the message | |
6380 | * that was reporting an error occured from the KMd. | |
6381 | */ | |
6382 | KFREE(msg); | |
6383 | return 0; | |
6384 | } | |
6385 | break; | |
6386 | ||
6387 | case SADB_REGISTER: | |
6388 | if ((newmsg = key_register(mhp, so)) == NULL) | |
6389 | return orglen; | |
6390 | #if 1 | |
6391 | if (targetp) | |
6392 | *targetp = KEY_SENDUP_REGISTERED; | |
6393 | #else | |
6394 | /* send result to all registered sockets */ | |
6395 | KFREE(msg); | |
6396 | key_sendall(newmsg, PFKEY_UNUNIT64(newmsg->sadb_msg_len)); | |
6397 | return 0; | |
6398 | #endif | |
6399 | break; | |
6400 | ||
6401 | case SADB_EXPIRE: | |
6402 | #if IPSEC_DEBUG | |
6403 | printf("key_parse: why is SADB_EXPIRE received ?\n"); | |
6404 | #endif | |
6405 | msg->sadb_msg_errno = EINVAL; | |
6406 | if (targetp) | |
6407 | *targetp = KEY_SENDUP_ALL; | |
6408 | pfkeystat.out_invmsgtype++; | |
6409 | return orglen; | |
6410 | ||
6411 | case SADB_FLUSH: | |
6412 | if ((newmsg = key_flush(mhp)) == NULL) | |
6413 | return orglen; | |
6414 | if (targetp) | |
6415 | *targetp = KEY_SENDUP_ALL; | |
6416 | break; | |
6417 | ||
6418 | case SADB_DUMP: | |
6419 | /* key_dump will call key_sendup() on her own */ | |
6420 | error = key_dump(mhp, so, KEY_SENDUP_ONE); | |
6421 | if (error) { | |
6422 | msg->sadb_msg_errno = error; | |
6423 | return orglen; | |
6424 | } else { | |
6425 | KFREE(msg); | |
6426 | return 0; | |
6427 | } | |
6428 | break; | |
6429 | ||
6430 | case SADB_X_PROMISC: | |
6431 | /* everything is handled in key_promisc() */ | |
6432 | key_promisc(mhp, so); | |
6433 | KFREE(msg); | |
6434 | return 0; /*nothing to reply*/ | |
6435 | ||
6436 | case SADB_X_PCHANGE: | |
6437 | #if IPSEC_DEBUG | |
6438 | printf("key_parse: SADB_X_PCHANGE isn't supported.\n"); | |
6439 | #endif | |
6440 | msg->sadb_msg_errno = EINVAL; | |
6441 | pfkeystat.out_invmsgtype++; | |
6442 | return orglen; | |
6443 | #if 0 | |
6444 | if (targetp) | |
6445 | *targetp = KEY_SENDUP_REGISTERED; | |
6446 | #endif | |
6447 | ||
6448 | case SADB_X_SPDADD: | |
6449 | case SADB_X_SPDSETIDX: | |
6450 | case SADB_X_SPDUPDATE: | |
6451 | if ((newmsg = key_spdadd(mhp)) == NULL) | |
6452 | return orglen; | |
6453 | if (targetp) | |
6454 | *targetp = KEY_SENDUP_ALL; | |
6455 | break; | |
6456 | ||
6457 | case SADB_X_SPDDELETE: | |
6458 | if ((newmsg = key_spddelete(mhp)) == NULL) | |
6459 | return orglen; | |
6460 | if (targetp) | |
6461 | *targetp = KEY_SENDUP_ALL; | |
6462 | break; | |
6463 | ||
6464 | case SADB_X_SPDDELETE2: | |
6465 | if ((newmsg = key_spddelete2(mhp)) == NULL) | |
6466 | return orglen; | |
6467 | if (targetp) | |
6468 | *targetp = KEY_SENDUP_ALL; | |
6469 | break; | |
6470 | ||
6471 | case SADB_X_SPDGET: | |
6472 | /* key_spdget will call key_sendup() on her own */ | |
6473 | error = key_spdget(mhp, so, KEY_SENDUP_ONE); | |
6474 | if (error) { | |
6475 | msg->sadb_msg_errno = error; | |
6476 | return orglen; | |
6477 | } else { | |
6478 | KFREE(msg); | |
6479 | return 0; | |
6480 | } | |
6481 | break; | |
6482 | ||
6483 | case SADB_X_SPDDUMP: | |
6484 | /* key_spddump will call key_sendup() on her own */ | |
6485 | error = key_spddump(mhp, so, KEY_SENDUP_ONE); | |
6486 | if (error) { | |
6487 | msg->sadb_msg_errno = error; | |
6488 | return orglen; | |
6489 | } else { | |
6490 | KFREE(msg); | |
6491 | return 0; | |
6492 | } | |
6493 | break; | |
6494 | ||
6495 | case SADB_X_SPDFLUSH: | |
6496 | if ((newmsg = key_spdflush(mhp)) == NULL) | |
6497 | return orglen; | |
6498 | if (targetp) | |
6499 | *targetp = KEY_SENDUP_ALL; | |
6500 | break; | |
6501 | ||
6502 | default: | |
6503 | msg->sadb_msg_errno = EOPNOTSUPP; | |
6504 | return orglen; | |
6505 | } | |
6506 | ||
6507 | /* switch from old sadb_msg to new one if success. */ | |
6508 | KFREE(msg); | |
6509 | *msgp = newmsg; | |
6510 | ||
6511 | return PFKEY_UNUNIT64((*msgp)->sadb_msg_len); | |
6512 | } | |
6513 | ||
6514 | /* | |
6515 | * set the pointer to each header into message buffer. | |
6516 | * IN: msg: pointer to message buffer. | |
6517 | * mhp: pointer to the buffer allocated like below: | |
6518 | * caddr_t mhp[SADB_EXT_MAX + 1]; | |
6519 | * OUT: 0: | |
6520 | * EINVAL: | |
6521 | */ | |
6522 | static int | |
6523 | key_align(msg, mhp) | |
6524 | struct sadb_msg *msg; | |
6525 | caddr_t *mhp; | |
6526 | { | |
6527 | struct sadb_ext *ext; | |
6528 | int tlen, extlen; | |
6529 | int i; | |
6530 | ||
6531 | /* sanity check */ | |
6532 | if (msg == NULL || mhp == NULL) | |
6533 | panic("key_align: NULL pointer is passed.\n"); | |
6534 | ||
6535 | /* initialize */ | |
6536 | for (i = 0; i < SADB_EXT_MAX + 1; i++) | |
6537 | mhp[i] = NULL; | |
6538 | ||
6539 | mhp[0] = (caddr_t)msg; | |
6540 | ||
6541 | tlen = PFKEY_UNUNIT64(msg->sadb_msg_len) - sizeof(struct sadb_msg); | |
6542 | ext = (struct sadb_ext *)((caddr_t)msg + sizeof(struct sadb_msg)); | |
6543 | ||
6544 | while (tlen > 0) { | |
6545 | /* set pointer */ | |
6546 | switch (ext->sadb_ext_type) { | |
6547 | case SADB_EXT_SA: | |
6548 | case SADB_EXT_LIFETIME_CURRENT: | |
6549 | case SADB_EXT_LIFETIME_HARD: | |
6550 | case SADB_EXT_LIFETIME_SOFT: | |
6551 | case SADB_EXT_ADDRESS_SRC: | |
6552 | case SADB_EXT_ADDRESS_DST: | |
6553 | case SADB_EXT_ADDRESS_PROXY: | |
6554 | case SADB_EXT_KEY_AUTH: | |
6555 | case SADB_EXT_KEY_ENCRYPT: | |
6556 | case SADB_EXT_IDENTITY_SRC: | |
6557 | case SADB_EXT_IDENTITY_DST: | |
6558 | case SADB_EXT_SENSITIVITY: | |
6559 | case SADB_EXT_PROPOSAL: | |
6560 | case SADB_EXT_SUPPORTED_AUTH: | |
6561 | case SADB_EXT_SUPPORTED_ENCRYPT: | |
6562 | case SADB_EXT_SPIRANGE: | |
6563 | case SADB_X_EXT_POLICY: | |
6564 | /* duplicate check */ | |
6565 | /* | |
6566 | * XXX Are there duplication payloads of either | |
6567 | * KEY_AUTH or KEY_ENCRYPT ? | |
6568 | */ | |
6569 | if (mhp[ext->sadb_ext_type] != NULL) { | |
6570 | #if IPSEC_DEBUG | |
6571 | printf("key_align: duplicate ext_type %u " | |
6572 | "is passed.\n", | |
6573 | ext->sadb_ext_type); | |
6574 | #endif | |
6575 | pfkeystat.out_dupext++; | |
6576 | return EINVAL; | |
6577 | } | |
6578 | mhp[ext->sadb_ext_type] = (caddr_t)ext; | |
6579 | break; | |
6580 | default: | |
6581 | #if IPSEC_DEBUG | |
6582 | printf("key_align: invalid ext_type %u is passed.\n", | |
6583 | ext->sadb_ext_type); | |
6584 | #endif | |
6585 | pfkeystat.out_invexttype++; | |
6586 | return EINVAL; | |
6587 | } | |
6588 | ||
6589 | extlen = PFKEY_UNUNIT64(ext->sadb_ext_len); | |
6590 | tlen -= extlen; | |
6591 | ext = (struct sadb_ext *)((caddr_t)ext + extlen); | |
6592 | } | |
6593 | ||
6594 | return 0; | |
6595 | } | |
6596 | ||
6597 | void | |
6598 | key_init() | |
6599 | { | |
6600 | int i; | |
6601 | ||
6602 | bzero((caddr_t)&key_cb, sizeof(key_cb)); | |
6603 | ||
6604 | for (i = 0; i < IPSEC_DIR_MAX; i++) { | |
6605 | LIST_INIT(&sptree[i]); | |
6606 | } | |
6607 | ||
6608 | LIST_INIT(&sahtree); | |
6609 | ||
6610 | for (i = 0; i <= SADB_SATYPE_MAX; i++) { | |
6611 | LIST_INIT(®tree[i]); | |
6612 | } | |
6613 | ||
6614 | #ifndef IPSEC_NONBLOCK_ACQUIRE | |
6615 | LIST_INIT(&acqtree); | |
6616 | #endif | |
6617 | LIST_INIT(&spacqtree); | |
6618 | ||
6619 | /* system default */ | |
6620 | ip4_def_policy.policy = IPSEC_POLICY_NONE; | |
6621 | ip4_def_policy.refcnt++; /*never reclaim this*/ | |
6622 | #if INET6 | |
6623 | ip6_def_policy.policy = IPSEC_POLICY_NONE; | |
6624 | ip6_def_policy.refcnt++; /*never reclaim this*/ | |
6625 | #endif | |
6626 | ||
6627 | #ifndef IPSEC_DEBUG2 | |
0b4e3aa0 | 6628 | timeout((void *)key_timehandler_funneled, (void *)0, hz); |
1c79356b A |
6629 | #endif /*IPSEC_DEBUG2*/ |
6630 | ||
6631 | /* initialize key statistics */ | |
6632 | keystat.getspi_count = 1; | |
6633 | ||
6634 | printf("IPsec: Initialized Security Association Processing.\n"); | |
6635 | ||
6636 | return; | |
6637 | } | |
6638 | ||
6639 | /* | |
6640 | * XXX: maybe This function is called after INBOUND IPsec processing. | |
6641 | * | |
6642 | * Special check for tunnel-mode packets. | |
6643 | * We must make some checks for consistency between inner and outer IP header. | |
6644 | * | |
6645 | * xxx more checks to be provided | |
6646 | */ | |
6647 | int | |
6648 | key_checktunnelsanity(sav, family, src, dst) | |
6649 | struct secasvar *sav; | |
6650 | u_int family; | |
6651 | caddr_t src; | |
6652 | caddr_t dst; | |
6653 | { | |
6654 | /* sanity check */ | |
6655 | if (sav->sah == NULL) | |
6656 | panic("sav->sah == NULL at key_checktunnelsanity"); | |
6657 | ||
6658 | /* XXX: check inner IP header */ | |
6659 | ||
6660 | return 1; | |
6661 | } | |
6662 | ||
6663 | #if 0 | |
6664 | #ifdef __FreeBSD__ | |
6665 | #define hostnamelen strlen(hostname) | |
6666 | #endif | |
6667 | ||
6668 | /* | |
6669 | * Get FQDN for the host. | |
6670 | * If the administrator configured hostname (by hostname(1)) without | |
6671 | * domain name, returns nothing. | |
6672 | */ | |
6673 | static const char * | |
6674 | key_getfqdn() | |
6675 | { | |
6676 | int i; | |
6677 | int hasdot; | |
6678 | static char fqdn[MAXHOSTNAMELEN + 1]; | |
6679 | ||
6680 | if (!hostnamelen) | |
6681 | return NULL; | |
6682 | ||
6683 | /* check if it comes with domain name. */ | |
6684 | hasdot = 0; | |
6685 | for (i = 0; i < hostnamelen; i++) { | |
6686 | if (hostname[i] == '.') | |
6687 | hasdot++; | |
6688 | } | |
6689 | if (!hasdot) | |
6690 | return NULL; | |
6691 | ||
6692 | /* NOTE: hostname may not be NUL-terminated. */ | |
6693 | bzero(fqdn, sizeof(fqdn)); | |
6694 | bcopy(hostname, fqdn, hostnamelen); | |
6695 | fqdn[hostnamelen] = '\0'; | |
6696 | return fqdn; | |
6697 | } | |
6698 | ||
6699 | /* | |
6700 | * get username@FQDN for the host/user. | |
6701 | */ | |
6702 | static const char * | |
6703 | key_getuserfqdn() | |
6704 | { | |
6705 | const char *host; | |
6706 | static char userfqdn[MAXHOSTNAMELEN + MAXLOGNAME + 2]; | |
6707 | struct proc *p = curproc; | |
6708 | char *q; | |
6709 | ||
6710 | if (!p || !p->p_pgrp || !p->p_pgrp->pg_session) | |
6711 | return NULL; | |
6712 | if (!(host = key_getfqdn())) | |
6713 | return NULL; | |
6714 | ||
6715 | /* NOTE: s_login may not be-NUL terminated. */ | |
6716 | bzero(userfqdn, sizeof(userfqdn)); | |
6717 | bcopy(p->p_pgrp->pg_session->s_login, userfqdn, MAXLOGNAME); | |
6718 | userfqdn[MAXLOGNAME] = '\0'; /* safeguard */ | |
6719 | q = userfqdn + strlen(userfqdn); | |
6720 | *q++ = '@'; | |
6721 | bcopy(host, q, strlen(host)); | |
6722 | q += strlen(host); | |
6723 | *q++ = '\0'; | |
6724 | ||
6725 | return userfqdn; | |
6726 | } | |
6727 | #endif | |
6728 | ||
6729 | /* record data transfer on SA, and update timestamps */ | |
6730 | void | |
6731 | key_sa_recordxfer(sav, m) | |
6732 | struct secasvar *sav; | |
6733 | struct mbuf *m; | |
6734 | { | |
6735 | if (!sav) | |
6736 | panic("key_sa_recordxfer called with sav == NULL"); | |
6737 | if (!m) | |
6738 | panic("key_sa_recordxfer called with m == NULL"); | |
6739 | if (!sav->lft_c) | |
6740 | return; | |
6741 | ||
6742 | /* | |
6743 | * XXX Currently, there is a difference of bytes size | |
6744 | * between inbound and outbound processing. | |
6745 | */ | |
6746 | sav->lft_c->sadb_lifetime_bytes += m->m_pkthdr.len; | |
6747 | /* to check bytes lifetime is done in key_timehandler(). */ | |
6748 | ||
6749 | /* | |
6750 | * We use the number of packets as the unit of | |
6751 | * sadb_lifetime_allocations. We increment the variable | |
6752 | * whenever {esp,ah}_{in,out}put is called. | |
6753 | */ | |
6754 | sav->lft_c->sadb_lifetime_allocations++; | |
6755 | /* XXX check for expires? */ | |
6756 | ||
6757 | /* | |
6758 | * NOTE: We record CURRENT sadb_lifetime_usetime by using wall clock, | |
6759 | * in seconds. HARD and SOFT lifetime are measured by the time | |
6760 | * difference (again in seconds) from sadb_lifetime_usetime. | |
6761 | * | |
6762 | * usetime | |
6763 | * v expire expire | |
6764 | * -----+-----+--------+---> t | |
6765 | * <--------------> HARD | |
6766 | * <-----> SOFT | |
6767 | */ | |
6768 | { | |
6769 | struct timeval tv; | |
6770 | microtime(&tv); | |
6771 | sav->lft_c->sadb_lifetime_usetime = tv.tv_sec; | |
6772 | /* XXX check for expires? */ | |
6773 | } | |
6774 | ||
6775 | return; | |
6776 | } | |
6777 | ||
6778 | /* dumb version */ | |
6779 | void | |
6780 | key_sa_routechange(dst) | |
6781 | struct sockaddr *dst; | |
6782 | { | |
6783 | struct secashead *sah; | |
6784 | struct route *ro; | |
6785 | ||
6786 | LIST_FOREACH(sah, &sahtree, chain) { | |
6787 | ro = &sah->sa_route; | |
6788 | if (ro->ro_rt && dst->sa_len == ro->ro_dst.sa_len | |
6789 | && bcmp(dst, &ro->ro_dst, dst->sa_len) == 0) { | |
6790 | RTFREE(ro->ro_rt); | |
6791 | ro->ro_rt = (struct rtentry *)NULL; | |
6792 | } | |
6793 | } | |
6794 | ||
6795 | return; | |
6796 | } | |
6797 | ||
6798 | static void | |
6799 | key_sa_chgstate(sav, state) | |
6800 | struct secasvar *sav; | |
6801 | u_int8_t state; | |
6802 | { | |
6803 | if (sav == NULL) | |
6804 | panic("key_sa_chgstate called with sav == NULL"); | |
6805 | ||
6806 | if (sav->state == state) | |
6807 | return; | |
6808 | ||
6809 | if (__LIST_CHAINED(sav)) | |
6810 | LIST_REMOVE(sav, chain); | |
6811 | ||
6812 | sav->state = state; | |
6813 | LIST_INSERT_HEAD(&sav->sah->savtree[state], sav, chain); | |
6814 | } | |
6815 | ||
6816 | /* returns NULL on error, m0 will be left unchanged */ | |
6817 | static caddr_t | |
6818 | key_appendmbuf(m0, len) | |
6819 | struct mbuf *m0; | |
6820 | int len; | |
6821 | { | |
6822 | caddr_t p; | |
6823 | struct mbuf *m; | |
6824 | struct mbuf *n; | |
6825 | ||
6826 | if (!m0 || (m0->m_flags & M_PKTHDR) == 0) | |
6827 | return NULL; /*EINVAL*/ | |
6828 | if (len > MCLBYTES) | |
6829 | return NULL; /*EINVAL*/ | |
6830 | ||
6831 | for (m = m0; m && m->m_next; m = m->m_next) | |
6832 | ; | |
6833 | if (len <= M_TRAILINGSPACE(m)) { | |
6834 | p = mtod(m, caddr_t) + m->m_len; | |
6835 | m->m_len += len; | |
6836 | m0->m_pkthdr.len += len; | |
6837 | ||
6838 | return p; | |
6839 | } | |
6840 | MGET(n, M_DONTWAIT, m->m_type); | |
6841 | if (n != NULL) { | |
6842 | MCLGET(n, M_DONTWAIT); | |
6843 | if ((n->m_flags & M_EXT) == 0) { | |
6844 | m_freem(n); | |
6845 | n = NULL; | |
6846 | } | |
6847 | } | |
6848 | if (n == NULL) | |
6849 | return NULL; /*ENOBUFS*/ | |
6850 | n->m_next = NULL; | |
6851 | m->m_next = n; | |
6852 | n->m_len = len; | |
6853 | m0->m_pkthdr.len += len; | |
6854 | ||
6855 | return mtod(n, caddr_t); | |
6856 | } | |
6857 | ||
6858 | #ifdef __bsdi__ | |
6859 | #include <sys/user.h> | |
6860 | #include <sys/sysctl.h> | |
6861 | ||
6862 | int *key_sysvars[] = KEYCTL_VARS; | |
6863 | ||
6864 | int | |
6865 | key_sysctl(name, namelen, oldp, oldlenp, newp, newlen) | |
6866 | int *name; | |
6867 | u_int namelen; | |
6868 | void *oldp; | |
6869 | size_t *oldlenp; | |
6870 | void *newp; | |
6871 | size_t newlen; | |
6872 | { | |
6873 | if (name[0] >= KEYCTL_MAXID) | |
6874 | return EOPNOTSUPP; | |
6875 | switch (name[0]) { | |
6876 | default: | |
6877 | return sysctl_int_arr(key_sysvars, name, namelen, | |
6878 | oldp, oldlenp, newp, newlen); | |
6879 | } | |
6880 | } | |
6881 | #endif /*__bsdi__*/ | |
6882 | ||
6883 | #ifdef __NetBSD__ | |
6884 | #include <vm/vm.h> | |
6885 | #include <sys/sysctl.h> | |
6886 | ||
6887 | static int *key_sysvars[] = KEYCTL_VARS; | |
6888 | ||
6889 | int | |
6890 | key_sysctl(name, namelen, oldp, oldlenp, newp, newlen) | |
6891 | int *name; | |
6892 | u_int namelen; | |
6893 | void *oldp; | |
6894 | size_t *oldlenp; | |
6895 | void *newp; | |
6896 | size_t newlen; | |
6897 | { | |
6898 | if (name[0] >= KEYCTL_MAXID) | |
6899 | return EOPNOTSUPP; | |
6900 | if (!key_sysvars[name[0]]) | |
6901 | return EOPNOTSUPP; | |
6902 | switch (name[0]) { | |
6903 | default: | |
6904 | return sysctl_int(oldp, oldlenp, newp, newlen, | |
6905 | key_sysvars[name[0]]); | |
6906 | } | |
6907 | } | |
6908 | #endif /*__NetBSD__*/ |