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