xref: /openbsd-src/usr.sbin/ldpd/pfkey.c (revision f2da64fbbbf1b03f09f390ab01267c93dfd77c4c)
1 /*	$OpenBSD: pfkey.c,v 1.10 2016/05/23 19:11:42 renato Exp $ */
2 
3 /*
4  * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
5  * Copyright (c) 2003, 2004 Markus Friedl <markus@openbsd.org>
6  *
7  * Permission to use, copy, modify, and distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 #include <sys/types.h>
21 #include <errno.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <unistd.h>
25 
26 #include "ldpd.h"
27 #include "ldpe.h"
28 #include "log.h"
29 
30 static int	 pfkey_send(int, uint8_t, uint8_t, uint8_t,
31 		    int, union ldpd_addr *, union ldpd_addr *,
32 		    uint32_t, uint8_t, int, char *, uint8_t, int, char *,
33 		    uint16_t, uint16_t);
34 static int	 pfkey_reply(int, uint32_t *);
35 static int	 pfkey_sa_add(int, union ldpd_addr *, union ldpd_addr *,
36 		    uint8_t, char *, uint32_t *);
37 static int	 pfkey_sa_remove(int, union ldpd_addr *, union ldpd_addr *,
38 		    uint32_t *);
39 static int	 pfkey_md5sig_establish(struct nbr *, struct nbr_params *nbrp);
40 static int	 pfkey_md5sig_remove(struct nbr *);
41 
42 #define	PFKEY2_CHUNK sizeof(uint64_t)
43 #define	ROUNDUP(x) (((x) + (PFKEY2_CHUNK - 1)) & ~(PFKEY2_CHUNK - 1))
44 #define	IOV_CNT	20
45 
46 static uint32_t	 sadb_msg_seq;
47 static uint32_t	 pid; /* should pid_t but pfkey needs uint32_t */
48 static int	 fd;
49 
50 static int
51 pfkey_send(int sd, uint8_t satype, uint8_t mtype, uint8_t dir,
52     int af, union ldpd_addr *src, union ldpd_addr *dst, uint32_t spi,
53     uint8_t aalg, int alen, char *akey, uint8_t ealg, int elen, char *ekey,
54     uint16_t sport, uint16_t dport)
55 {
56 	struct sadb_msg		smsg;
57 	struct sadb_sa		sa;
58 	struct sadb_address	sa_src, sa_dst;
59 	struct sadb_key		sa_akey, sa_ekey;
60 	struct sadb_spirange	sa_spirange;
61 	struct iovec		iov[IOV_CNT];
62 	ssize_t			n;
63 	int			len = 0;
64 	int			iov_cnt;
65 	struct sockaddr_storage	ssrc, sdst, smask, dmask;
66 	struct sockaddr		*saptr;
67 
68 	if (!pid)
69 		pid = getpid();
70 
71 	/* we need clean sockaddr... no ports set */
72 	memset(&ssrc, 0, sizeof(ssrc));
73 	memset(&smask, 0, sizeof(smask));
74 	if ((saptr = addr2sa(af, src, 0)))
75 		memcpy(&ssrc, saptr, sizeof(ssrc));
76 	switch (af) {
77 	case AF_INET:
78 		memset(&((struct sockaddr_in *)&smask)->sin_addr, 0xff, 32/8);
79 		break;
80 	case AF_INET6:
81 		memset(&((struct sockaddr_in6 *)&smask)->sin6_addr, 0xff,
82 		    128/8);
83 		break;
84 	default:
85 		return (-1);
86 	}
87 	smask.ss_family = ssrc.ss_family;
88 	smask.ss_len = ssrc.ss_len;
89 
90 	memset(&sdst, 0, sizeof(sdst));
91 	memset(&dmask, 0, sizeof(dmask));
92 	if ((saptr = addr2sa(af, dst, 0)))
93 		memcpy(&sdst, saptr, sizeof(sdst));
94 	switch (af) {
95 	case AF_INET:
96 		memset(&((struct sockaddr_in *)&dmask)->sin_addr, 0xff, 32/8);
97 		break;
98 	case AF_INET6:
99 		memset(&((struct sockaddr_in6 *)&dmask)->sin6_addr, 0xff,
100 		    128/8);
101 		break;
102 	default:
103 		return (-1);
104 	}
105 	dmask.ss_family = sdst.ss_family;
106 	dmask.ss_len = sdst.ss_len;
107 
108 	memset(&smsg, 0, sizeof(smsg));
109 	smsg.sadb_msg_version = PF_KEY_V2;
110 	smsg.sadb_msg_seq = ++sadb_msg_seq;
111 	smsg.sadb_msg_pid = pid;
112 	smsg.sadb_msg_len = sizeof(smsg) / 8;
113 	smsg.sadb_msg_type = mtype;
114 	smsg.sadb_msg_satype = satype;
115 
116 	switch (mtype) {
117 	case SADB_GETSPI:
118 		memset(&sa_spirange, 0, sizeof(sa_spirange));
119 		sa_spirange.sadb_spirange_exttype = SADB_EXT_SPIRANGE;
120 		sa_spirange.sadb_spirange_len = sizeof(sa_spirange) / 8;
121 		sa_spirange.sadb_spirange_min = 0x100;
122 		sa_spirange.sadb_spirange_max = 0xffffffff;
123 		sa_spirange.sadb_spirange_reserved = 0;
124 		break;
125 	case SADB_ADD:
126 	case SADB_UPDATE:
127 	case SADB_DELETE:
128 		memset(&sa, 0, sizeof(sa));
129 		sa.sadb_sa_exttype = SADB_EXT_SA;
130 		sa.sadb_sa_len = sizeof(sa) / 8;
131 		sa.sadb_sa_replay = 0;
132 		sa.sadb_sa_spi = spi;
133 		sa.sadb_sa_state = SADB_SASTATE_MATURE;
134 		break;
135 	}
136 
137 	memset(&sa_src, 0, sizeof(sa_src));
138 	sa_src.sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
139 	sa_src.sadb_address_len = (sizeof(sa_src) + ROUNDUP(ssrc.ss_len)) / 8;
140 
141 	memset(&sa_dst, 0, sizeof(sa_dst));
142 	sa_dst.sadb_address_exttype = SADB_EXT_ADDRESS_DST;
143 	sa_dst.sadb_address_len = (sizeof(sa_dst) + ROUNDUP(sdst.ss_len)) / 8;
144 
145 	sa.sadb_sa_auth = aalg;
146 	sa.sadb_sa_encrypt = SADB_X_EALG_AES; /* XXX */
147 
148 	switch (mtype) {
149 	case SADB_ADD:
150 	case SADB_UPDATE:
151 		memset(&sa_akey, 0, sizeof(sa_akey));
152 		sa_akey.sadb_key_exttype = SADB_EXT_KEY_AUTH;
153 		sa_akey.sadb_key_len = (sizeof(sa_akey) +
154 		    ((alen + 7) / 8) * 8) / 8;
155 		sa_akey.sadb_key_bits = 8 * alen;
156 
157 		memset(&sa_ekey, 0, sizeof(sa_ekey));
158 		sa_ekey.sadb_key_exttype = SADB_EXT_KEY_ENCRYPT;
159 		sa_ekey.sadb_key_len = (sizeof(sa_ekey) +
160 		    ((elen + 7) / 8) * 8) / 8;
161 		sa_ekey.sadb_key_bits = 8 * elen;
162 
163 		break;
164 	}
165 
166 	iov_cnt = 0;
167 
168 	/* msghdr */
169 	iov[iov_cnt].iov_base = &smsg;
170 	iov[iov_cnt].iov_len = sizeof(smsg);
171 	iov_cnt++;
172 
173 	switch (mtype) {
174 	case SADB_ADD:
175 	case SADB_UPDATE:
176 	case SADB_DELETE:
177 		/* SA hdr */
178 		iov[iov_cnt].iov_base = &sa;
179 		iov[iov_cnt].iov_len = sizeof(sa);
180 		smsg.sadb_msg_len += sa.sadb_sa_len;
181 		iov_cnt++;
182 		break;
183 	case SADB_GETSPI:
184 		/* SPI range */
185 		iov[iov_cnt].iov_base = &sa_spirange;
186 		iov[iov_cnt].iov_len = sizeof(sa_spirange);
187 		smsg.sadb_msg_len += sa_spirange.sadb_spirange_len;
188 		iov_cnt++;
189 		break;
190 	}
191 
192 	/* dest addr */
193 	iov[iov_cnt].iov_base = &sa_dst;
194 	iov[iov_cnt].iov_len = sizeof(sa_dst);
195 	iov_cnt++;
196 	iov[iov_cnt].iov_base = &sdst;
197 	iov[iov_cnt].iov_len = ROUNDUP(sdst.ss_len);
198 	smsg.sadb_msg_len += sa_dst.sadb_address_len;
199 	iov_cnt++;
200 
201 	/* src addr */
202 	iov[iov_cnt].iov_base = &sa_src;
203 	iov[iov_cnt].iov_len = sizeof(sa_src);
204 	iov_cnt++;
205 	iov[iov_cnt].iov_base = &ssrc;
206 	iov[iov_cnt].iov_len = ROUNDUP(ssrc.ss_len);
207 	smsg.sadb_msg_len += sa_src.sadb_address_len;
208 	iov_cnt++;
209 
210 	switch (mtype) {
211 	case SADB_ADD:
212 	case SADB_UPDATE:
213 		if (alen) {
214 			/* auth key */
215 			iov[iov_cnt].iov_base = &sa_akey;
216 			iov[iov_cnt].iov_len = sizeof(sa_akey);
217 			iov_cnt++;
218 			iov[iov_cnt].iov_base = akey;
219 			iov[iov_cnt].iov_len = ((alen + 7) / 8) * 8;
220 			smsg.sadb_msg_len += sa_akey.sadb_key_len;
221 			iov_cnt++;
222 		}
223 		if (elen) {
224 			/* encryption key */
225 			iov[iov_cnt].iov_base = &sa_ekey;
226 			iov[iov_cnt].iov_len = sizeof(sa_ekey);
227 			iov_cnt++;
228 			iov[iov_cnt].iov_base = ekey;
229 			iov[iov_cnt].iov_len = ((elen + 7) / 8) * 8;
230 			smsg.sadb_msg_len += sa_ekey.sadb_key_len;
231 			iov_cnt++;
232 		}
233 		break;
234 	}
235 
236 	len = smsg.sadb_msg_len * 8;
237 	do {
238 		n = writev(sd, iov, iov_cnt);
239 	} while (n == -1 && (errno == EAGAIN || errno == EINTR));
240 
241 	if (n == -1) {
242 		log_warn("writev (%d/%d)", iov_cnt, len);
243 		return (-1);
244 	}
245 
246 	return (0);
247 }
248 
249 int
250 pfkey_read(int sd, struct sadb_msg *h)
251 {
252 	struct sadb_msg hdr;
253 
254 	if (recv(sd, &hdr, sizeof(hdr), MSG_PEEK) != sizeof(hdr)) {
255 		if (errno == EAGAIN || errno == EINTR)
256 			return (0);
257 		log_warn("pfkey peek");
258 		return (-1);
259 	}
260 
261 	/* XXX: Only one message can be outstanding. */
262 	if (hdr.sadb_msg_seq == sadb_msg_seq &&
263 	    hdr.sadb_msg_pid == pid) {
264 		if (h)
265 			*h = hdr;
266 		return (0);
267 	}
268 
269 	/* not ours, discard */
270 	if (read(sd, &hdr, sizeof(hdr)) == -1) {
271 		if (errno == EAGAIN || errno == EINTR)
272 			return (0);
273 		log_warn("pfkey read");
274 		return (-1);
275 	}
276 
277 	return (1);
278 }
279 
280 static int
281 pfkey_reply(int sd, uint32_t *spip)
282 {
283 	struct sadb_msg hdr, *msg;
284 	struct sadb_ext *ext;
285 	struct sadb_sa *sa;
286 	uint8_t *data;
287 	ssize_t len;
288 	int rv;
289 
290 	do {
291 		rv = pfkey_read(sd, &hdr);
292 		if (rv == -1)
293 			return (-1);
294 	} while (rv);
295 
296 	if (hdr.sadb_msg_errno != 0) {
297 		errno = hdr.sadb_msg_errno;
298 		if (errno == ESRCH)
299 			return (0);
300 		else {
301 			log_warn("pfkey");
302 			return (-1);
303 		}
304 	}
305 	if ((data = reallocarray(NULL, hdr.sadb_msg_len, PFKEY2_CHUNK)) == NULL) {
306 		log_warn("pfkey malloc");
307 		return (-1);
308 	}
309 	len = hdr.sadb_msg_len * PFKEY2_CHUNK;
310 	if (read(sd, data, len) != len) {
311 		log_warn("pfkey read");
312 		explicit_bzero(data, len);
313 		free(data);
314 		return (-1);
315 	}
316 
317 	if (hdr.sadb_msg_type == SADB_GETSPI) {
318 		if (spip == NULL) {
319 			explicit_bzero(data, len);
320 			free(data);
321 			return (0);
322 		}
323 
324 		msg = (struct sadb_msg *)data;
325 		for (ext = (struct sadb_ext *)(msg + 1);
326 		    (size_t)((uint8_t *)ext - (uint8_t *)msg) <
327 		    msg->sadb_msg_len * PFKEY2_CHUNK;
328 		    ext = (struct sadb_ext *)((uint8_t *)ext +
329 		    ext->sadb_ext_len * PFKEY2_CHUNK)) {
330 			if (ext->sadb_ext_type == SADB_EXT_SA) {
331 				sa = (struct sadb_sa *) ext;
332 				*spip = sa->sadb_sa_spi;
333 				break;
334 			}
335 		}
336 	}
337 	explicit_bzero(data, len);
338 	free(data);
339 	return (0);
340 }
341 
342 static int
343 pfkey_sa_add(int af, union ldpd_addr *src, union ldpd_addr *dst, uint8_t keylen,
344     char *key, uint32_t *spi)
345 {
346 	if (pfkey_send(fd, SADB_X_SATYPE_TCPSIGNATURE, SADB_GETSPI, 0,
347 	    af, src, dst, 0, 0, 0, NULL, 0, 0, NULL, 0, 0) < 0)
348 		return (-1);
349 	if (pfkey_reply(fd, spi) < 0)
350 		return (-1);
351 	if (pfkey_send(fd, SADB_X_SATYPE_TCPSIGNATURE, SADB_UPDATE, 0,
352 	    af, src, dst, *spi, 0, keylen, key, 0, 0, NULL, 0, 0) < 0)
353 		return (-1);
354 	if (pfkey_reply(fd, NULL) < 0)
355 		return (-1);
356 	return (0);
357 }
358 
359 static int
360 pfkey_sa_remove(int af, union ldpd_addr *src, union ldpd_addr *dst,
361     uint32_t *spi)
362 {
363 	if (pfkey_send(fd, SADB_X_SATYPE_TCPSIGNATURE, SADB_DELETE, 0,
364 	    af, src, dst, *spi, 0, 0, NULL, 0, 0, NULL, 0, 0) < 0)
365 		return (-1);
366 	if (pfkey_reply(fd, NULL) < 0)
367 		return (-1);
368 	*spi = 0;
369 	return (0);
370 }
371 
372 static int
373 pfkey_md5sig_establish(struct nbr *nbr, struct nbr_params *nbrp)
374 {
375 	sleep(1);
376 
377 	if (!nbr->auth.spi_out)
378 		if (pfkey_sa_add(nbr->af, &nbr->laddr, &nbr->raddr,
379 		    nbrp->auth.md5key_len, nbrp->auth.md5key,
380 		    &nbr->auth.spi_out) == -1)
381 			return (-1);
382 	if (!nbr->auth.spi_in)
383 		if (pfkey_sa_add(nbr->af, &nbr->raddr, &nbr->laddr,
384 		    nbrp->auth.md5key_len, nbrp->auth.md5key,
385 		    &nbr->auth.spi_in) == -1)
386 			return (-1);
387 
388 	nbr->auth.established = 1;
389 	return (0);
390 }
391 
392 static int
393 pfkey_md5sig_remove(struct nbr *nbr)
394 {
395 	if (nbr->auth.spi_out)
396 		if (pfkey_sa_remove(nbr->af, &nbr->laddr, &nbr->raddr,
397 		    &nbr->auth.spi_out) == -1)
398 			return (-1);
399 	if (nbr->auth.spi_in)
400 		if (pfkey_sa_remove(nbr->af, &nbr->raddr, &nbr->laddr,
401 		    &nbr->auth.spi_in) == -1)
402 			return (-1);
403 
404 	nbr->auth.established = 0;
405 	nbr->auth.spi_in = 0;
406 	nbr->auth.spi_out = 0;
407 	nbr->auth.method = AUTH_NONE;
408 	memset(nbr->auth.md5key, 0, sizeof(nbr->auth.md5key));
409 
410 	return (0);
411 }
412 
413 int
414 pfkey_establish(struct nbr *nbr, struct nbr_params *nbrp)
415 {
416 	if (nbrp->auth.method == AUTH_NONE)
417 		return (0);
418 
419 	/*
420 	 * make sure we keep copies of everything we need to
421 	 * remove SAs and flows later again.
422 	 */
423 	nbr->auth.method = nbrp->auth.method;
424 
425 	switch (nbr->auth.method) {
426 	case AUTH_MD5SIG:
427 		strlcpy(nbr->auth.md5key, nbrp->auth.md5key,
428 		    sizeof(nbr->auth.md5key));
429 		return (pfkey_md5sig_establish(nbr, nbrp));
430 	default:
431 		break;
432 	}
433 
434 	return (0);
435 }
436 
437 int
438 pfkey_remove(struct nbr *nbr)
439 {
440 	if (nbr->auth.method == AUTH_NONE || !nbr->auth.established)
441 		return (0);
442 
443 	switch (nbr->auth.method) {
444 	case AUTH_MD5SIG:
445 		return (pfkey_md5sig_remove(nbr));
446 	default:
447 		break;
448 	}
449 
450 	return (0);
451 }
452 
453 int
454 pfkey_init(void)
455 {
456 	if ((fd = socket(PF_KEY, SOCK_RAW | SOCK_CLOEXEC | SOCK_NONBLOCK,
457 	    PF_KEY_V2)) == -1) {
458 		if (errno == EPROTONOSUPPORT) {
459 			log_warnx("PF_KEY not available");
460 			sysdep.no_pfkey = 1;
461 			return (-1);
462 		} else
463 			fatal("pfkey setup failed");
464 	}
465 	return (fd);
466 }
467