xref: /freebsd/sys/netipsec/keysock.c (revision 8655c70597b0e0918c82114b1186df5669b83eb6)
1 /*	$FreeBSD$	*/
2 /*	$KAME: keysock.c,v 1.25 2001/08/13 20:07:41 itojun Exp $	*/
3 
4 /*-
5  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. Neither the name of the project nor the names of its contributors
17  *    may be used to endorse or promote products derived from this software
18  *    without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31  */
32 
33 #include "opt_ipsec.h"
34 #include "opt_route.h"
35 
36 /* This code has derived from sys/net/rtsock.c on FreeBSD2.2.5 */
37 
38 #include <sys/types.h>
39 #include <sys/param.h>
40 #include <sys/domain.h>
41 #include <sys/errno.h>
42 #include <sys/kernel.h>
43 #include <sys/lock.h>
44 #include <sys/malloc.h>
45 #include <sys/mbuf.h>
46 #include <sys/mutex.h>
47 #include <sys/priv.h>
48 #include <sys/protosw.h>
49 #include <sys/signalvar.h>
50 #include <sys/socket.h>
51 #include <sys/socketvar.h>
52 #include <sys/sysctl.h>
53 #include <sys/systm.h>
54 #include <sys/vimage.h>
55 
56 #include <net/if.h>
57 #include <net/raw_cb.h>
58 #include <net/route.h>
59 #include <net/vnet.h>
60 
61 #include <netinet/in.h>
62 
63 #include <net/pfkeyv2.h>
64 #include <netipsec/key.h>
65 #include <netipsec/keysock.h>
66 #include <netipsec/key_debug.h>
67 #include <netipsec/ipsec.h>
68 
69 #include <machine/stdarg.h>
70 
71 #ifdef VIMAGE_GLOBALS
72 static struct key_cb key_cb;
73 struct pfkeystat pfkeystat;
74 #endif
75 
76 static struct sockaddr key_src = { 2, PF_KEY };
77 
78 static int key_sendup0 __P((struct rawcb *, struct mbuf *, int));
79 
80 /*
81  * key_output()
82  */
83 int
84 key_output(struct mbuf *m, struct socket *so)
85 {
86 	INIT_VNET_IPSEC(curvnet);
87 	struct sadb_msg *msg;
88 	int len, error = 0;
89 
90 	if (m == 0)
91 		panic("%s: NULL pointer was passed.\n", __func__);
92 
93 	V_pfkeystat.out_total++;
94 	V_pfkeystat.out_bytes += m->m_pkthdr.len;
95 
96 	len = m->m_pkthdr.len;
97 	if (len < sizeof(struct sadb_msg)) {
98 		V_pfkeystat.out_tooshort++;
99 		error = EINVAL;
100 		goto end;
101 	}
102 
103 	if (m->m_len < sizeof(struct sadb_msg)) {
104 		if ((m = m_pullup(m, sizeof(struct sadb_msg))) == 0) {
105 			V_pfkeystat.out_nomem++;
106 			error = ENOBUFS;
107 			goto end;
108 		}
109 	}
110 
111 	M_ASSERTPKTHDR(m);
112 
113 	KEYDEBUG(KEYDEBUG_KEY_DUMP, kdebug_mbuf(m));
114 
115 	msg = mtod(m, struct sadb_msg *);
116 	V_pfkeystat.out_msgtype[msg->sadb_msg_type]++;
117 	if (len != PFKEY_UNUNIT64(msg->sadb_msg_len)) {
118 		V_pfkeystat.out_invlen++;
119 		error = EINVAL;
120 		goto end;
121 	}
122 
123 	error = key_parse(m, so);
124 	m = NULL;
125 end:
126 	if (m)
127 		m_freem(m);
128 	return error;
129 }
130 
131 /*
132  * send message to the socket.
133  */
134 static int
135 key_sendup0(rp, m, promisc)
136 	struct rawcb *rp;
137 	struct mbuf *m;
138 	int promisc;
139 {
140 	INIT_VNET_IPSEC(curvnet);
141 	int error;
142 
143 	if (promisc) {
144 		struct sadb_msg *pmsg;
145 
146 		M_PREPEND(m, sizeof(struct sadb_msg), M_DONTWAIT);
147 		if (m && m->m_len < sizeof(struct sadb_msg))
148 			m = m_pullup(m, sizeof(struct sadb_msg));
149 		if (!m) {
150 			V_pfkeystat.in_nomem++;
151 			m_freem(m);
152 			return ENOBUFS;
153 		}
154 		m->m_pkthdr.len += sizeof(*pmsg);
155 
156 		pmsg = mtod(m, struct sadb_msg *);
157 		bzero(pmsg, sizeof(*pmsg));
158 		pmsg->sadb_msg_version = PF_KEY_V2;
159 		pmsg->sadb_msg_type = SADB_X_PROMISC;
160 		pmsg->sadb_msg_len = PFKEY_UNIT64(m->m_pkthdr.len);
161 		/* pid and seq? */
162 
163 		V_pfkeystat.in_msgtype[pmsg->sadb_msg_type]++;
164 	}
165 
166 	if (!sbappendaddr(&rp->rcb_socket->so_rcv, (struct sockaddr *)&key_src,
167 	    m, NULL)) {
168 		V_pfkeystat.in_nomem++;
169 		m_freem(m);
170 		error = ENOBUFS;
171 	} else
172 		error = 0;
173 	sorwakeup(rp->rcb_socket);
174 	return error;
175 }
176 
177 /* XXX this interface should be obsoleted. */
178 int
179 key_sendup(so, msg, len, target)
180 	struct socket *so;
181 	struct sadb_msg *msg;
182 	u_int len;
183 	int target;	/*target of the resulting message*/
184 {
185 	INIT_VNET_IPSEC(curvnet);
186 	struct mbuf *m, *n, *mprev;
187 	int tlen;
188 
189 	/* sanity check */
190 	if (so == 0 || msg == 0)
191 		panic("%s: NULL pointer was passed.\n", __func__);
192 
193 	KEYDEBUG(KEYDEBUG_KEY_DUMP,
194 		printf("%s: \n", __func__);
195 		kdebug_sadb(msg));
196 
197 	/*
198 	 * we increment statistics here, just in case we have ENOBUFS
199 	 * in this function.
200 	 */
201 	V_pfkeystat.in_total++;
202 	V_pfkeystat.in_bytes += len;
203 	V_pfkeystat.in_msgtype[msg->sadb_msg_type]++;
204 
205 	/*
206 	 * Get mbuf chain whenever possible (not clusters),
207 	 * to save socket buffer.  We'll be generating many SADB_ACQUIRE
208 	 * messages to listening key sockets.  If we simply allocate clusters,
209 	 * sbappendaddr() will raise ENOBUFS due to too little sbspace().
210 	 * sbspace() computes # of actual data bytes AND mbuf region.
211 	 *
212 	 * TODO: SADB_ACQUIRE filters should be implemented.
213 	 */
214 	tlen = len;
215 	m = mprev = NULL;
216 	while (tlen > 0) {
217 		if (tlen == len) {
218 			MGETHDR(n, M_DONTWAIT, MT_DATA);
219 			if (n == NULL) {
220 				V_pfkeystat.in_nomem++;
221 				return ENOBUFS;
222 			}
223 			n->m_len = MHLEN;
224 		} else {
225 			MGET(n, M_DONTWAIT, MT_DATA);
226 			if (n == NULL) {
227 				V_pfkeystat.in_nomem++;
228 				return ENOBUFS;
229 			}
230 			n->m_len = MLEN;
231 		}
232 		if (tlen >= MCLBYTES) {	/*XXX better threshold? */
233 			MCLGET(n, M_DONTWAIT);
234 			if ((n->m_flags & M_EXT) == 0) {
235 				m_free(n);
236 				m_freem(m);
237 				V_pfkeystat.in_nomem++;
238 				return ENOBUFS;
239 			}
240 			n->m_len = MCLBYTES;
241 		}
242 
243 		if (tlen < n->m_len)
244 			n->m_len = tlen;
245 		n->m_next = NULL;
246 		if (m == NULL)
247 			m = mprev = n;
248 		else {
249 			mprev->m_next = n;
250 			mprev = n;
251 		}
252 		tlen -= n->m_len;
253 		n = NULL;
254 	}
255 	m->m_pkthdr.len = len;
256 	m->m_pkthdr.rcvif = NULL;
257 	m_copyback(m, 0, len, (caddr_t)msg);
258 
259 	/* avoid duplicated statistics */
260 	V_pfkeystat.in_total--;
261 	V_pfkeystat.in_bytes -= len;
262 	V_pfkeystat.in_msgtype[msg->sadb_msg_type]--;
263 
264 	return key_sendup_mbuf(so, m, target);
265 }
266 
267 /* so can be NULL if target != KEY_SENDUP_ONE */
268 int
269 key_sendup_mbuf(so, m, target)
270 	struct socket *so;
271 	struct mbuf *m;
272 	int target;
273 {
274 	INIT_VNET_NET(curvnet);
275 	INIT_VNET_IPSEC(curvnet);
276 	struct mbuf *n;
277 	struct keycb *kp;
278 	int sendup;
279 	struct rawcb *rp;
280 	int error = 0;
281 
282 	if (m == NULL)
283 		panic("key_sendup_mbuf: NULL pointer was passed.\n");
284 	if (so == NULL && target == KEY_SENDUP_ONE)
285 		panic("%s: NULL pointer was passed.\n", __func__);
286 
287 	V_pfkeystat.in_total++;
288 	V_pfkeystat.in_bytes += m->m_pkthdr.len;
289 	if (m->m_len < sizeof(struct sadb_msg)) {
290 		m = m_pullup(m, sizeof(struct sadb_msg));
291 		if (m == NULL) {
292 			V_pfkeystat.in_nomem++;
293 			return ENOBUFS;
294 		}
295 	}
296 	if (m->m_len >= sizeof(struct sadb_msg)) {
297 		struct sadb_msg *msg;
298 		msg = mtod(m, struct sadb_msg *);
299 		V_pfkeystat.in_msgtype[msg->sadb_msg_type]++;
300 	}
301 	mtx_lock(&rawcb_mtx);
302 	LIST_FOREACH(rp, &V_rawcb_list, list)
303 	{
304 		if (rp->rcb_proto.sp_family != PF_KEY)
305 			continue;
306 		if (rp->rcb_proto.sp_protocol
307 		 && rp->rcb_proto.sp_protocol != PF_KEY_V2) {
308 			continue;
309 		}
310 
311 		kp = (struct keycb *)rp;
312 
313 		/*
314 		 * If you are in promiscuous mode, and when you get broadcasted
315 		 * reply, you'll get two PF_KEY messages.
316 		 * (based on pf_key@inner.net message on 14 Oct 1998)
317 		 */
318 		if (((struct keycb *)rp)->kp_promisc) {
319 			if ((n = m_copy(m, 0, (int)M_COPYALL)) != NULL) {
320 				(void)key_sendup0(rp, n, 1);
321 				n = NULL;
322 			}
323 		}
324 
325 		/* the exact target will be processed later */
326 		if (so && sotorawcb(so) == rp)
327 			continue;
328 
329 		sendup = 0;
330 		switch (target) {
331 		case KEY_SENDUP_ONE:
332 			/* the statement has no effect */
333 			if (so && sotorawcb(so) == rp)
334 				sendup++;
335 			break;
336 		case KEY_SENDUP_ALL:
337 			sendup++;
338 			break;
339 		case KEY_SENDUP_REGISTERED:
340 			if (kp->kp_registered)
341 				sendup++;
342 			break;
343 		}
344 		V_pfkeystat.in_msgtarget[target]++;
345 
346 		if (!sendup)
347 			continue;
348 
349 		if ((n = m_copy(m, 0, (int)M_COPYALL)) == NULL) {
350 			m_freem(m);
351 			V_pfkeystat.in_nomem++;
352 			mtx_unlock(&rawcb_mtx);
353 			return ENOBUFS;
354 		}
355 
356 		if ((error = key_sendup0(rp, n, 0)) != 0) {
357 			m_freem(m);
358 			mtx_unlock(&rawcb_mtx);
359 			return error;
360 		}
361 
362 		n = NULL;
363 	}
364 
365 	if (so) {
366 		error = key_sendup0(sotorawcb(so), m, 0);
367 		m = NULL;
368 	} else {
369 		error = 0;
370 		m_freem(m);
371 	}
372 	mtx_unlock(&rawcb_mtx);
373 	return error;
374 }
375 
376 /*
377  * key_abort()
378  * derived from net/rtsock.c:rts_abort()
379  */
380 static void
381 key_abort(struct socket *so)
382 {
383 	raw_usrreqs.pru_abort(so);
384 }
385 
386 /*
387  * key_attach()
388  * derived from net/rtsock.c:rts_attach()
389  */
390 static int
391 key_attach(struct socket *so, int proto, struct thread *td)
392 {
393 	INIT_VNET_IPSEC(curvnet);
394 	struct keycb *kp;
395 	int error;
396 
397 	KASSERT(so->so_pcb == NULL, ("key_attach: so_pcb != NULL"));
398 
399 	if (td != NULL) {
400 		error = priv_check(td, PRIV_NET_RAW);
401 		if (error)
402 			return error;
403 	}
404 
405 	/* XXX */
406 	kp = malloc(sizeof *kp, M_PCB, M_WAITOK | M_ZERO);
407 	if (kp == 0)
408 		return ENOBUFS;
409 
410 	so->so_pcb = (caddr_t)kp;
411 	error = raw_attach(so, proto);
412 	kp = (struct keycb *)sotorawcb(so);
413 	if (error) {
414 		free(kp, M_PCB);
415 		so->so_pcb = (caddr_t) 0;
416 		return error;
417 	}
418 
419 	kp->kp_promisc = kp->kp_registered = 0;
420 
421 	if (kp->kp_raw.rcb_proto.sp_protocol == PF_KEY) /* XXX: AF_KEY */
422 		V_key_cb.key_count++;
423 	V_key_cb.any_count++;
424 	soisconnected(so);
425 	so->so_options |= SO_USELOOPBACK;
426 
427 	return 0;
428 }
429 
430 /*
431  * key_bind()
432  * derived from net/rtsock.c:rts_bind()
433  */
434 static int
435 key_bind(struct socket *so, struct sockaddr *nam, struct thread *td)
436 {
437   return EINVAL;
438 }
439 
440 /*
441  * key_close()
442  * derived from net/rtsock.c:rts_close().
443  */
444 static void
445 key_close(struct socket *so)
446 {
447 
448 	raw_usrreqs.pru_close(so);
449 }
450 
451 /*
452  * key_connect()
453  * derived from net/rtsock.c:rts_connect()
454  */
455 static int
456 key_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
457 {
458 	return EINVAL;
459 }
460 
461 /*
462  * key_detach()
463  * derived from net/rtsock.c:rts_detach()
464  */
465 static void
466 key_detach(struct socket *so)
467 {
468 	INIT_VNET_IPSEC(curvnet);
469 	struct keycb *kp = (struct keycb *)sotorawcb(so);
470 
471 	KASSERT(kp != NULL, ("key_detach: kp == NULL"));
472 	if (kp->kp_raw.rcb_proto.sp_protocol
473 	    == PF_KEY) /* XXX: AF_KEY */
474 		V_key_cb.key_count--;
475 	V_key_cb.any_count--;
476 
477 	key_freereg(so);
478 	raw_usrreqs.pru_detach(so);
479 }
480 
481 /*
482  * key_disconnect()
483  * derived from net/rtsock.c:key_disconnect()
484  */
485 static int
486 key_disconnect(struct socket *so)
487 {
488 	return(raw_usrreqs.pru_disconnect(so));
489 }
490 
491 /*
492  * key_peeraddr()
493  * derived from net/rtsock.c:rts_peeraddr()
494  */
495 static int
496 key_peeraddr(struct socket *so, struct sockaddr **nam)
497 {
498 	return(raw_usrreqs.pru_peeraddr(so, nam));
499 }
500 
501 /*
502  * key_send()
503  * derived from net/rtsock.c:rts_send()
504  */
505 static int
506 key_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam,
507 	 struct mbuf *control, struct thread *td)
508 {
509 	return(raw_usrreqs.pru_send(so, flags, m, nam, control, td));
510 }
511 
512 /*
513  * key_shutdown()
514  * derived from net/rtsock.c:rts_shutdown()
515  */
516 static int
517 key_shutdown(struct socket *so)
518 {
519 	return(raw_usrreqs.pru_shutdown(so));
520 }
521 
522 /*
523  * key_sockaddr()
524  * derived from net/rtsock.c:rts_sockaddr()
525  */
526 static int
527 key_sockaddr(struct socket *so, struct sockaddr **nam)
528 {
529 	return(raw_usrreqs.pru_sockaddr(so, nam));
530 }
531 
532 struct pr_usrreqs key_usrreqs = {
533 	.pru_abort =		key_abort,
534 	.pru_attach =		key_attach,
535 	.pru_bind =		key_bind,
536 	.pru_connect =		key_connect,
537 	.pru_detach =		key_detach,
538 	.pru_disconnect =	key_disconnect,
539 	.pru_peeraddr =		key_peeraddr,
540 	.pru_send =		key_send,
541 	.pru_shutdown =		key_shutdown,
542 	.pru_sockaddr =		key_sockaddr,
543 	.pru_close =		key_close,
544 };
545 
546 /* sysctl */
547 SYSCTL_NODE(_net, PF_KEY, key, CTLFLAG_RW, 0, "Key Family");
548 
549 /*
550  * Definitions of protocols supported in the KEY domain.
551  */
552 
553 extern struct domain keydomain;
554 
555 struct protosw keysw[] = {
556 {
557 	.pr_type =		SOCK_RAW,
558 	.pr_domain =		&keydomain,
559 	.pr_protocol =		PF_KEY_V2,
560 	.pr_flags =		PR_ATOMIC|PR_ADDR,
561 	.pr_output =		key_output,
562 	.pr_ctlinput =		raw_ctlinput,
563 	.pr_init =		raw_init,
564 	.pr_usrreqs =		&key_usrreqs
565 }
566 };
567 
568 static void
569 key_init0(void)
570 {
571 	INIT_VNET_IPSEC(curvnet);
572 
573 	bzero((caddr_t)&V_key_cb, sizeof(V_key_cb));
574 	ipsec_init();
575 	key_init();
576 }
577 
578 struct domain keydomain = {
579 	.dom_family =		PF_KEY,
580 	.dom_name =		"key",
581 	.dom_init =		key_init0,
582 	.dom_protosw =		keysw,
583 	.dom_protoswNPROTOSW =	&keysw[sizeof(keysw)/sizeof(keysw[0])]
584 };
585 
586 DOMAIN_SET(key);
587