GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: sbin/ipsecctl/pfkey.c Lines: 0 753 0.0 %
Date: 2016-12-06 Branches: 0 311 0.0 %

Line Branch Exec Source
1
/*	$OpenBSD: pfkey.c,v 1.57 2015/12/10 17:27:00 mmcc Exp $	*/
2
/*
3
 * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
4
 * Copyright (c) 2003, 2004 Markus Friedl <markus@openbsd.org>
5
 * Copyright (c) 2004, 2005 Hans-Joerg Hoexer <hshoexer@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 <sys/queue.h>
22
#include <sys/uio.h>
23
#include <sys/socket.h>
24
#include <netinet/in.h>
25
#include <netinet/ip_ipsp.h>
26
#include <net/pfkeyv2.h>
27
28
#include <err.h>
29
#include <errno.h>
30
#include <stdio.h>
31
#include <string.h>
32
#include <stdlib.h>
33
#include <poll.h>
34
#include <unistd.h>
35
36
#include "ipsecctl.h"
37
#include "pfkey.h"
38
39
#define ROUNDUP(x) (((x) + (PFKEYV2_CHUNK - 1)) & ~(PFKEYV2_CHUNK - 1))
40
#define IOV_CNT 20
41
42
static int	fd;
43
static u_int32_t sadb_msg_seq = 1;
44
45
static int	pfkey_flow(int, u_int8_t, u_int8_t, u_int8_t, u_int8_t,
46
		    struct ipsec_addr_wrap *, u_int16_t,
47
		    struct ipsec_addr_wrap *, u_int16_t,
48
		    struct ipsec_addr_wrap *, struct ipsec_addr_wrap *,
49
		    struct ipsec_auth *, u_int8_t);
50
static int	pfkey_sa(int, u_int8_t, u_int8_t, u_int32_t,
51
		    struct ipsec_addr_wrap *, struct ipsec_addr_wrap *,
52
		    struct ipsec_transforms *, struct ipsec_key *,
53
		    struct ipsec_key *, u_int8_t);
54
static int	pfkey_sagroup(int, u_int8_t, u_int8_t, u_int8_t,
55
		    struct ipsec_addr_wrap *, u_int32_t,
56
		    struct ipsec_addr_wrap *, u_int32_t);
57
static int	pfkey_reply(int, u_int8_t **, ssize_t *);
58
int		pfkey_parse(struct sadb_msg *, struct ipsec_rule *);
59
int		pfkey_ipsec_flush(void);
60
int		pfkey_ipsec_establish(int, struct ipsec_rule *);
61
int		pfkey_init(void);
62
63
static int
64
pfkey_flow(int sd, u_int8_t satype, u_int8_t action, u_int8_t direction,
65
    u_int8_t proto, struct ipsec_addr_wrap *src, u_int16_t sport,
66
    struct ipsec_addr_wrap *dst, u_int16_t dport,
67
    struct ipsec_addr_wrap *local, struct ipsec_addr_wrap *peer,
68
    struct ipsec_auth *auth, u_int8_t flowtype)
69
{
70
	struct sadb_msg		 smsg;
71
	struct sadb_address	 sa_src, sa_dst, sa_local, sa_peer, sa_smask,
72
				 sa_dmask;
73
	struct sadb_protocol	 sa_flowtype, sa_protocol;
74
	struct sadb_ident	*sa_srcid, *sa_dstid;
75
	struct sockaddr_storage	 ssrc, sdst, slocal, speer, smask, dmask;
76
	struct iovec		 iov[IOV_CNT];
77
	ssize_t			 n;
78
	int			 iov_cnt, len, ret = 0;
79
80
	sa_srcid = sa_dstid = NULL;
81
82
	bzero(&ssrc, sizeof(ssrc));
83
	bzero(&smask, sizeof(smask));
84
	ssrc.ss_family = smask.ss_family = src->af;
85
	switch (src->af) {
86
	case AF_INET:
87
		((struct sockaddr_in *)&ssrc)->sin_addr = src->address.v4;
88
		ssrc.ss_len = sizeof(struct sockaddr_in);
89
		((struct sockaddr_in *)&smask)->sin_addr = src->mask.v4;
90
		if (sport) {
91
			((struct sockaddr_in *)&ssrc)->sin_port = sport;
92
			((struct sockaddr_in *)&smask)->sin_port = 0xffff;
93
		}
94
		break;
95
	case AF_INET6:
96
		((struct sockaddr_in6 *)&ssrc)->sin6_addr = src->address.v6;
97
		ssrc.ss_len = sizeof(struct sockaddr_in6);
98
		((struct sockaddr_in6 *)&smask)->sin6_addr = src->mask.v6;
99
		if (sport) {
100
			((struct sockaddr_in6 *)&ssrc)->sin6_port = sport;
101
			((struct sockaddr_in6 *)&smask)->sin6_port = 0xffff;
102
		}
103
		break;
104
	default:
105
		warnx("unsupported address family %d", src->af);
106
		return -1;
107
	}
108
	smask.ss_len = ssrc.ss_len;
109
110
	bzero(&sdst, sizeof(sdst));
111
	bzero(&dmask, sizeof(dmask));
112
	sdst.ss_family = dmask.ss_family = dst->af;
113
	switch (dst->af) {
114
	case AF_INET:
115
		((struct sockaddr_in *)&sdst)->sin_addr = dst->address.v4;
116
		sdst.ss_len = sizeof(struct sockaddr_in);
117
		((struct sockaddr_in *)&dmask)->sin_addr = dst->mask.v4;
118
		if (dport) {
119
			((struct sockaddr_in *)&sdst)->sin_port = dport;
120
			((struct sockaddr_in *)&dmask)->sin_port = 0xffff;
121
		}
122
		break;
123
	case AF_INET6:
124
		((struct sockaddr_in6 *)&sdst)->sin6_addr = dst->address.v6;
125
		sdst.ss_len = sizeof(struct sockaddr_in6);
126
		((struct sockaddr_in6 *)&dmask)->sin6_addr = dst->mask.v6;
127
		if (dport) {
128
			((struct sockaddr_in6 *)&sdst)->sin6_port = dport;
129
			((struct sockaddr_in6 *)&dmask)->sin6_port = 0xffff;
130
		}
131
		break;
132
	default:
133
		warnx("unsupported address family %d", dst->af);
134
		return -1;
135
	}
136
	dmask.ss_len = sdst.ss_len;
137
138
	bzero(&slocal, sizeof(slocal));
139
	if (local) {
140
		slocal.ss_family = local->af;
141
		switch (local->af) {
142
		case AF_INET:
143
			((struct sockaddr_in *)&slocal)->sin_addr =
144
			    local->address.v4;
145
			slocal.ss_len = sizeof(struct sockaddr_in);
146
			break;
147
		case AF_INET6:
148
			((struct sockaddr_in6 *)&slocal)->sin6_addr =
149
			    local->address.v6;
150
			slocal.ss_len = sizeof(struct sockaddr_in6);
151
			break;
152
		default:
153
			warnx("unsupported address family %d", local->af);
154
			return -1;
155
		}
156
	}
157
158
	bzero(&speer, sizeof(speer));
159
	if (peer) {
160
		speer.ss_family = peer->af;
161
		switch (peer->af) {
162
		case AF_INET:
163
			((struct sockaddr_in *)&speer)->sin_addr =
164
			    peer->address.v4;
165
			speer.ss_len = sizeof(struct sockaddr_in);
166
			break;
167
		case AF_INET6:
168
			((struct sockaddr_in6 *)&speer)->sin6_addr =
169
			    peer->address.v6;
170
			speer.ss_len = sizeof(struct sockaddr_in6);
171
			break;
172
		default:
173
			warnx("unsupported address family %d", peer->af);
174
			return -1;
175
		}
176
	}
177
178
	bzero(&smsg, sizeof(smsg));
179
	smsg.sadb_msg_version = PF_KEY_V2;
180
	smsg.sadb_msg_seq = sadb_msg_seq++;
181
	smsg.sadb_msg_pid = getpid();
182
	smsg.sadb_msg_len = sizeof(smsg) / 8;
183
	smsg.sadb_msg_type = action;
184
	smsg.sadb_msg_satype = satype;
185
186
	bzero(&sa_flowtype, sizeof(sa_flowtype));
187
	sa_flowtype.sadb_protocol_exttype = SADB_X_EXT_FLOW_TYPE;
188
	sa_flowtype.sadb_protocol_len = sizeof(sa_flowtype) / 8;
189
	sa_flowtype.sadb_protocol_direction = direction;
190
191
	switch (flowtype) {
192
	case TYPE_USE:
193
		sa_flowtype.sadb_protocol_proto = SADB_X_FLOW_TYPE_USE;
194
		break;
195
	case TYPE_ACQUIRE:
196
		sa_flowtype.sadb_protocol_proto = SADB_X_FLOW_TYPE_ACQUIRE;
197
		break;
198
	case TYPE_REQUIRE:
199
		sa_flowtype.sadb_protocol_proto = SADB_X_FLOW_TYPE_REQUIRE;
200
		break;
201
	case TYPE_DENY:
202
		sa_flowtype.sadb_protocol_proto = SADB_X_FLOW_TYPE_DENY;
203
		break;
204
	case TYPE_BYPASS:
205
		sa_flowtype.sadb_protocol_proto = SADB_X_FLOW_TYPE_BYPASS;
206
		break;
207
	case TYPE_DONTACQ:
208
		sa_flowtype.sadb_protocol_proto = SADB_X_FLOW_TYPE_DONTACQ;
209
		break;
210
	default:
211
		warnx("unsupported flowtype %d", flowtype);
212
		return -1;
213
	}
214
215
	bzero(&sa_protocol, sizeof(sa_protocol));
216
	sa_protocol.sadb_protocol_exttype = SADB_X_EXT_PROTOCOL;
217
	sa_protocol.sadb_protocol_len = sizeof(sa_protocol) / 8;
218
	sa_protocol.sadb_protocol_direction = 0;
219
	sa_protocol.sadb_protocol_proto = proto;
220
221
	bzero(&sa_src, sizeof(sa_src));
222
	sa_src.sadb_address_exttype = SADB_X_EXT_SRC_FLOW;
223
	sa_src.sadb_address_len = (sizeof(sa_src) + ROUNDUP(ssrc.ss_len)) / 8;
224
225
	bzero(&sa_smask, sizeof(sa_smask));
226
	sa_smask.sadb_address_exttype = SADB_X_EXT_SRC_MASK;
227
	sa_smask.sadb_address_len =
228
	    (sizeof(sa_smask) + ROUNDUP(smask.ss_len)) / 8;
229
230
	bzero(&sa_dst, sizeof(sa_dst));
231
	sa_dst.sadb_address_exttype = SADB_X_EXT_DST_FLOW;
232
	sa_dst.sadb_address_len = (sizeof(sa_dst) + ROUNDUP(sdst.ss_len)) / 8;
233
234
	bzero(&sa_dmask, sizeof(sa_dmask));
235
	sa_dmask.sadb_address_exttype = SADB_X_EXT_DST_MASK;
236
	sa_dmask.sadb_address_len =
237
	    (sizeof(sa_dmask) + ROUNDUP(dmask.ss_len)) / 8;
238
239
	if (local) {
240
		bzero(&sa_local, sizeof(sa_local));
241
		sa_local.sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
242
		sa_local.sadb_address_len =
243
		    (sizeof(sa_local) + ROUNDUP(slocal.ss_len)) / 8;
244
	}
245
	if (peer) {
246
		bzero(&sa_peer, sizeof(sa_peer));
247
		sa_peer.sadb_address_exttype = SADB_EXT_ADDRESS_DST;
248
		sa_peer.sadb_address_len =
249
		    (sizeof(sa_peer) + ROUNDUP(speer.ss_len)) / 8;
250
	}
251
252
	if (auth && auth->srcid) {
253
		len = ROUNDUP(strlen(auth->srcid) + 1) + sizeof(*sa_srcid);
254
255
		sa_srcid = calloc(len, sizeof(u_int8_t));
256
		if (sa_srcid == NULL)
257
			err(1, "pfkey_flow: calloc");
258
259
		sa_srcid->sadb_ident_type = auth->srcid_type;
260
		sa_srcid->sadb_ident_len = len / 8;
261
		sa_srcid->sadb_ident_exttype = SADB_EXT_IDENTITY_SRC;
262
263
		strlcpy((char *)(sa_srcid + 1), auth->srcid,
264
		    ROUNDUP(strlen(auth->srcid) + 1));
265
	}
266
	if (auth && auth->dstid) {
267
		len = ROUNDUP(strlen(auth->dstid) + 1) + sizeof(*sa_dstid);
268
269
		sa_dstid = calloc(len, sizeof(u_int8_t));
270
		if (sa_dstid == NULL)
271
			err(1, "pfkey_flow: calloc");
272
273
		sa_dstid->sadb_ident_type = auth->dstid_type;
274
		sa_dstid->sadb_ident_len = len / 8;
275
		sa_dstid->sadb_ident_exttype = SADB_EXT_IDENTITY_DST;
276
277
		strlcpy((char *)(sa_dstid + 1), auth->dstid,
278
		    ROUNDUP(strlen(auth->dstid) + 1));
279
	}
280
281
	iov_cnt = 0;
282
283
	/* header */
284
	iov[iov_cnt].iov_base = &smsg;
285
	iov[iov_cnt].iov_len = sizeof(smsg);
286
	iov_cnt++;
287
288
	/* add flow type */
289
	iov[iov_cnt].iov_base = &sa_flowtype;
290
	iov[iov_cnt].iov_len = sizeof(sa_flowtype);
291
	smsg.sadb_msg_len += sa_flowtype.sadb_protocol_len;
292
	iov_cnt++;
293
294
	/* local ip */
295
	if (local) {
296
		iov[iov_cnt].iov_base = &sa_local;
297
		iov[iov_cnt].iov_len = sizeof(sa_local);
298
		iov_cnt++;
299
		iov[iov_cnt].iov_base = &slocal;
300
		iov[iov_cnt].iov_len = ROUNDUP(slocal.ss_len);
301
		smsg.sadb_msg_len += sa_local.sadb_address_len;
302
		iov_cnt++;
303
	}
304
305
	/* remote peer */
306
	if (peer) {
307
		iov[iov_cnt].iov_base = &sa_peer;
308
		iov[iov_cnt].iov_len = sizeof(sa_peer);
309
		iov_cnt++;
310
		iov[iov_cnt].iov_base = &speer;
311
		iov[iov_cnt].iov_len = ROUNDUP(speer.ss_len);
312
		smsg.sadb_msg_len += sa_peer.sadb_address_len;
313
		iov_cnt++;
314
	}
315
316
	/* src addr */
317
	iov[iov_cnt].iov_base = &sa_src;
318
	iov[iov_cnt].iov_len = sizeof(sa_src);
319
	iov_cnt++;
320
	iov[iov_cnt].iov_base = &ssrc;
321
	iov[iov_cnt].iov_len = ROUNDUP(ssrc.ss_len);
322
	smsg.sadb_msg_len += sa_src.sadb_address_len;
323
	iov_cnt++;
324
325
	/* src mask */
326
	iov[iov_cnt].iov_base = &sa_smask;
327
	iov[iov_cnt].iov_len = sizeof(sa_smask);
328
	iov_cnt++;
329
	iov[iov_cnt].iov_base = &smask;
330
	iov[iov_cnt].iov_len = ROUNDUP(smask.ss_len);
331
	smsg.sadb_msg_len += sa_smask.sadb_address_len;
332
	iov_cnt++;
333
334
	/* dest addr */
335
	iov[iov_cnt].iov_base = &sa_dst;
336
	iov[iov_cnt].iov_len = sizeof(sa_dst);
337
	iov_cnt++;
338
	iov[iov_cnt].iov_base = &sdst;
339
	iov[iov_cnt].iov_len = ROUNDUP(sdst.ss_len);
340
	smsg.sadb_msg_len += sa_dst.sadb_address_len;
341
	iov_cnt++;
342
343
	/* dst mask */
344
	iov[iov_cnt].iov_base = &sa_dmask;
345
	iov[iov_cnt].iov_len = sizeof(sa_dmask);
346
	iov_cnt++;
347
	iov[iov_cnt].iov_base = &dmask;
348
	iov[iov_cnt].iov_len = ROUNDUP(dmask.ss_len);
349
	smsg.sadb_msg_len += sa_dmask.sadb_address_len;
350
	iov_cnt++;
351
352
	/* add protocol */
353
	iov[iov_cnt].iov_base = &sa_protocol;
354
	iov[iov_cnt].iov_len = sizeof(sa_protocol);
355
	smsg.sadb_msg_len += sa_protocol.sadb_protocol_len;
356
	iov_cnt++;
357
358
	if (sa_srcid) {
359
		/* src identity */
360
		iov[iov_cnt].iov_base = sa_srcid;
361
		iov[iov_cnt].iov_len = sa_srcid->sadb_ident_len * 8;
362
		smsg.sadb_msg_len += sa_srcid->sadb_ident_len;
363
		iov_cnt++;
364
	}
365
	if (sa_dstid) {
366
		/* dst identity */
367
		iov[iov_cnt].iov_base = sa_dstid;
368
		iov[iov_cnt].iov_len = sa_dstid->sadb_ident_len * 8;
369
		smsg.sadb_msg_len += sa_dstid->sadb_ident_len;
370
		iov_cnt++;
371
	}
372
	len = smsg.sadb_msg_len * 8;
373
374
	do {
375
		n = writev(sd, iov, iov_cnt);
376
	} while (n == -1 && (errno == EAGAIN || errno == EINTR));
377
	if (n == -1) {
378
		warn("writev failed");
379
		ret = -1;
380
	}
381
382
	free(sa_srcid);
383
	free(sa_dstid);
384
385
	return ret;
386
}
387
388
static int
389
pfkey_sa(int sd, u_int8_t satype, u_int8_t action, u_int32_t spi,
390
    struct ipsec_addr_wrap *src, struct ipsec_addr_wrap *dst,
391
    struct ipsec_transforms *xfs, struct ipsec_key *authkey,
392
    struct ipsec_key *enckey, u_int8_t tmode)
393
{
394
	struct sadb_msg		smsg;
395
	struct sadb_sa		sa;
396
	struct sadb_address	sa_src, sa_dst;
397
	struct sadb_key		sa_authkey, sa_enckey;
398
	struct sockaddr_storage	ssrc, sdst;
399
	struct iovec		iov[IOV_CNT];
400
	ssize_t			n;
401
	int			iov_cnt, len, ret = 0;
402
403
	bzero(&ssrc, sizeof(ssrc));
404
	ssrc.ss_family = src->af;
405
	switch (src->af) {
406
	case AF_INET:
407
		((struct sockaddr_in *)&ssrc)->sin_addr = src->address.v4;
408
		ssrc.ss_len = sizeof(struct sockaddr_in);
409
		break;
410
	case AF_INET6:
411
		((struct sockaddr_in6 *)&ssrc)->sin6_addr = src->address.v6;
412
		ssrc.ss_len = sizeof(struct sockaddr_in6);
413
		break;
414
	default:
415
		warnx("unsupported address family %d", src->af);
416
		return -1;
417
	}
418
419
	bzero(&sdst, sizeof(sdst));
420
	sdst.ss_family = dst->af;
421
	switch (dst->af) {
422
	case AF_INET:
423
		((struct sockaddr_in *)&sdst)->sin_addr = dst->address.v4;
424
		sdst.ss_len = sizeof(struct sockaddr_in);
425
		break;
426
	case AF_INET6:
427
		((struct sockaddr_in6 *)&sdst)->sin6_addr = dst->address.v6;
428
		sdst.ss_len = sizeof(struct sockaddr_in6);
429
		break;
430
	default:
431
		warnx("unsupported address family %d", dst->af);
432
		return -1;
433
	}
434
435
	bzero(&smsg, sizeof(smsg));
436
	smsg.sadb_msg_version = PF_KEY_V2;
437
	smsg.sadb_msg_seq = sadb_msg_seq++;
438
	smsg.sadb_msg_pid = getpid();
439
	smsg.sadb_msg_len = sizeof(smsg) / 8;
440
	smsg.sadb_msg_type = action;
441
	smsg.sadb_msg_satype = satype;
442
443
	bzero(&sa, sizeof(sa));
444
	sa.sadb_sa_len = sizeof(sa) / 8;
445
	sa.sadb_sa_exttype = SADB_EXT_SA;
446
	sa.sadb_sa_spi = htonl(spi);
447
	sa.sadb_sa_state = SADB_SASTATE_MATURE;
448
449
	if (satype != SADB_X_SATYPE_IPIP && tmode == IPSEC_TUNNEL)
450
		sa.sadb_sa_flags |= SADB_X_SAFLAGS_TUNNEL;
451
452
	if (xfs && xfs->authxf) {
453
		switch (xfs->authxf->id) {
454
		case AUTHXF_NONE:
455
			break;
456
		case AUTHXF_HMAC_MD5:
457
			sa.sadb_sa_auth = SADB_AALG_MD5HMAC;
458
			break;
459
		case AUTHXF_HMAC_RIPEMD160:
460
			sa.sadb_sa_auth = SADB_X_AALG_RIPEMD160HMAC;
461
			break;
462
		case AUTHXF_HMAC_SHA1:
463
			sa.sadb_sa_auth = SADB_AALG_SHA1HMAC;
464
			break;
465
		case AUTHXF_HMAC_SHA2_256:
466
			sa.sadb_sa_auth = SADB_X_AALG_SHA2_256;
467
			break;
468
		case AUTHXF_HMAC_SHA2_384:
469
			sa.sadb_sa_auth = SADB_X_AALG_SHA2_384;
470
			break;
471
		case AUTHXF_HMAC_SHA2_512:
472
			sa.sadb_sa_auth = SADB_X_AALG_SHA2_512;
473
			break;
474
		default:
475
			warnx("unsupported authentication algorithm %d",
476
			    xfs->authxf->id);
477
		}
478
	}
479
	if (xfs && xfs->encxf) {
480
		switch (xfs->encxf->id) {
481
		case ENCXF_NONE:
482
			break;
483
		case ENCXF_3DES_CBC:
484
			sa.sadb_sa_encrypt = SADB_EALG_3DESCBC;
485
			break;
486
		case ENCXF_AES:
487
		case ENCXF_AES_128:
488
		case ENCXF_AES_192:
489
		case ENCXF_AES_256:
490
			sa.sadb_sa_encrypt = SADB_X_EALG_AES;
491
			break;
492
		case ENCXF_AESCTR:
493
		case ENCXF_AES_128_CTR:
494
		case ENCXF_AES_192_CTR:
495
		case ENCXF_AES_256_CTR:
496
			sa.sadb_sa_encrypt = SADB_X_EALG_AESCTR;
497
			break;
498
		case ENCXF_AES_128_GCM:
499
		case ENCXF_AES_192_GCM:
500
		case ENCXF_AES_256_GCM:
501
			sa.sadb_sa_encrypt = SADB_X_EALG_AESGCM16;
502
			break;
503
		case ENCXF_AES_128_GMAC:
504
		case ENCXF_AES_192_GMAC:
505
		case ENCXF_AES_256_GMAC:
506
			sa.sadb_sa_encrypt = SADB_X_EALG_AESGMAC;
507
			break;
508
		case ENCXF_BLOWFISH:
509
			sa.sadb_sa_encrypt = SADB_X_EALG_BLF;
510
			break;
511
		case ENCXF_CAST128:
512
			sa.sadb_sa_encrypt = SADB_X_EALG_CAST;
513
			break;
514
		case ENCXF_NULL:
515
			sa.sadb_sa_encrypt = SADB_EALG_NULL;
516
			break;
517
		default:
518
			warnx("unsupported encryption algorithm %d",
519
			    xfs->encxf->id);
520
		}
521
	}
522
	if (xfs && xfs->compxf) {
523
		switch (xfs->compxf->id) {
524
		case COMPXF_DEFLATE:
525
			sa.sadb_sa_encrypt = SADB_X_CALG_DEFLATE;
526
			break;
527
		case COMPXF_LZS:
528
			sa.sadb_sa_encrypt = SADB_X_CALG_LZS;
529
			break;
530
		default:
531
			warnx("unsupported compression algorithm %d",
532
			    xfs->compxf->id);
533
		}
534
	}
535
536
	bzero(&sa_src, sizeof(sa_src));
537
	sa_src.sadb_address_len = (sizeof(sa_src) + ROUNDUP(ssrc.ss_len)) / 8;
538
	sa_src.sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
539
540
	bzero(&sa_dst, sizeof(sa_dst));
541
	sa_dst.sadb_address_len = (sizeof(sa_dst) + ROUNDUP(sdst.ss_len)) / 8;
542
	sa_dst.sadb_address_exttype = SADB_EXT_ADDRESS_DST;
543
544
	if (action == SADB_ADD && !authkey && !enckey && satype !=
545
	    SADB_X_SATYPE_IPCOMP && satype != SADB_X_SATYPE_IPIP) { /* XXX ENCNULL */
546
		warnx("no key specified");
547
		return -1;
548
	}
549
	if (authkey) {
550
		bzero(&sa_authkey, sizeof(sa_authkey));
551
		sa_authkey.sadb_key_len = (sizeof(sa_authkey) +
552
		    ((authkey->len + 7) / 8) * 8) / 8;
553
		sa_authkey.sadb_key_exttype = SADB_EXT_KEY_AUTH;
554
		sa_authkey.sadb_key_bits = 8 * authkey->len;
555
	}
556
	if (enckey) {
557
		bzero(&sa_enckey, sizeof(sa_enckey));
558
		sa_enckey.sadb_key_len = (sizeof(sa_enckey) +
559
		    ((enckey->len + 7) / 8) * 8) / 8;
560
		sa_enckey.sadb_key_exttype = SADB_EXT_KEY_ENCRYPT;
561
		sa_enckey.sadb_key_bits = 8 * enckey->len;
562
	}
563
564
	iov_cnt = 0;
565
566
	/* header */
567
	iov[iov_cnt].iov_base = &smsg;
568
	iov[iov_cnt].iov_len = sizeof(smsg);
569
	iov_cnt++;
570
571
	/* sa */
572
	iov[iov_cnt].iov_base = &sa;
573
	iov[iov_cnt].iov_len = sizeof(sa);
574
	smsg.sadb_msg_len += sa.sadb_sa_len;
575
	iov_cnt++;
576
577
	/* src addr */
578
	iov[iov_cnt].iov_base = &sa_src;
579
	iov[iov_cnt].iov_len = sizeof(sa_src);
580
	iov_cnt++;
581
	iov[iov_cnt].iov_base = &ssrc;
582
	iov[iov_cnt].iov_len = ROUNDUP(ssrc.ss_len);
583
	smsg.sadb_msg_len += sa_src.sadb_address_len;
584
	iov_cnt++;
585
586
	/* dst addr */
587
	iov[iov_cnt].iov_base = &sa_dst;
588
	iov[iov_cnt].iov_len = sizeof(sa_dst);
589
	iov_cnt++;
590
	iov[iov_cnt].iov_base = &sdst;
591
	iov[iov_cnt].iov_len = ROUNDUP(sdst.ss_len);
592
	smsg.sadb_msg_len += sa_dst.sadb_address_len;
593
	iov_cnt++;
594
595
	if (authkey) {
596
		/* authentication key */
597
		iov[iov_cnt].iov_base = &sa_authkey;
598
		iov[iov_cnt].iov_len = sizeof(sa_authkey);
599
		iov_cnt++;
600
		iov[iov_cnt].iov_base = authkey->data;
601
		iov[iov_cnt].iov_len = ((authkey->len + 7) / 8) * 8;
602
		smsg.sadb_msg_len += sa_authkey.sadb_key_len;
603
		iov_cnt++;
604
	}
605
	if (enckey) {
606
		/* encryption key */
607
		iov[iov_cnt].iov_base = &sa_enckey;
608
		iov[iov_cnt].iov_len = sizeof(sa_enckey);
609
		iov_cnt++;
610
		iov[iov_cnt].iov_base = enckey->data;
611
		iov[iov_cnt].iov_len = ((enckey->len + 7) / 8) * 8;
612
		smsg.sadb_msg_len += sa_enckey.sadb_key_len;
613
		iov_cnt++;
614
	}
615
616
	len = smsg.sadb_msg_len * 8;
617
	if ((n = writev(sd, iov, iov_cnt)) == -1) {
618
		warn("writev failed");
619
		ret = -1;
620
	} else if (n != len) {
621
		warnx("short write");
622
		ret = -1;
623
	}
624
625
	return ret;
626
}
627
628
static int
629
pfkey_sagroup(int sd, u_int8_t satype, u_int8_t satype2, u_int8_t action,
630
    struct ipsec_addr_wrap *dst, u_int32_t spi, struct ipsec_addr_wrap *dst2,
631
    u_int32_t spi2)
632
{
633
	struct sadb_msg		smsg;
634
	struct sadb_sa		sa1, sa2;
635
	struct sadb_address	sa_dst, sa_dst2;
636
	struct sockaddr_storage	sdst, sdst2;
637
	struct sadb_protocol	sa_proto;
638
	struct iovec		iov[IOV_CNT];
639
	ssize_t			n;
640
	int			iov_cnt, len, ret = 0;
641
642
	bzero(&sdst, sizeof(sdst));
643
	sdst.ss_family = dst->af;
644
	switch (dst->af) {
645
	case AF_INET:
646
		((struct sockaddr_in *)&sdst)->sin_addr = dst->address.v4;
647
		sdst.ss_len = sizeof(struct sockaddr_in);
648
		break;
649
	case AF_INET6:
650
		((struct sockaddr_in6 *)&sdst)->sin6_addr = dst->address.v6;
651
		sdst.ss_len = sizeof(struct sockaddr_in6);
652
		break;
653
	default:
654
		warnx("unsupported address family %d", dst->af);
655
		return -1;
656
	}
657
658
	bzero(&sdst2, sizeof(sdst2));
659
	sdst2.ss_family = dst2->af;
660
	switch (dst2->af) {
661
	case AF_INET:
662
		((struct sockaddr_in *)&sdst2)->sin_addr = dst2->address.v4;
663
		sdst2.ss_len = sizeof(struct sockaddr_in);
664
		break;
665
	case AF_INET6:
666
		((struct sockaddr_in6 *)&sdst2)->sin6_addr = dst2->address.v6;
667
		sdst2.ss_len = sizeof(struct sockaddr_in6);
668
		break;
669
	default:
670
		warnx("unsupported address family %d", dst2->af);
671
		return -1;
672
	}
673
674
	bzero(&smsg, sizeof(smsg));
675
	smsg.sadb_msg_version = PF_KEY_V2;
676
	smsg.sadb_msg_seq = sadb_msg_seq++;
677
	smsg.sadb_msg_pid = getpid();
678
	smsg.sadb_msg_len = sizeof(smsg) / 8;
679
	smsg.sadb_msg_type = action;
680
	smsg.sadb_msg_satype = satype;
681
682
	bzero(&sa1, sizeof(sa1));
683
	sa1.sadb_sa_len = sizeof(sa1) / 8;
684
	sa1.sadb_sa_exttype = SADB_EXT_SA;
685
	sa1.sadb_sa_spi = htonl(spi);
686
	sa1.sadb_sa_state = SADB_SASTATE_MATURE;
687
688
	bzero(&sa2, sizeof(sa2));
689
	sa2.sadb_sa_len = sizeof(sa2) / 8;
690
	sa2.sadb_sa_exttype = SADB_X_EXT_SA2;
691
	sa2.sadb_sa_spi = htonl(spi2);
692
	sa2.sadb_sa_state = SADB_SASTATE_MATURE;
693
	iov_cnt = 0;
694
695
	bzero(&sa_dst, sizeof(sa_dst));
696
	sa_dst.sadb_address_exttype = SADB_EXT_ADDRESS_DST;
697
	sa_dst.sadb_address_len = (sizeof(sa_dst) + ROUNDUP(sdst.ss_len)) / 8;
698
699
	bzero(&sa_dst2, sizeof(sa_dst2));
700
	sa_dst2.sadb_address_exttype = SADB_X_EXT_DST2;
701
	sa_dst2.sadb_address_len = (sizeof(sa_dst2) + ROUNDUP(sdst2.ss_len)) / 8;
702
703
	bzero(&sa_proto, sizeof(sa_proto));
704
	sa_proto.sadb_protocol_exttype = SADB_X_EXT_PROTOCOL;
705
	sa_proto.sadb_protocol_len = sizeof(sa_proto) / 8;
706
	sa_proto.sadb_protocol_direction = 0;
707
	sa_proto.sadb_protocol_proto = satype2;
708
709
	/* header */
710
	iov[iov_cnt].iov_base = &smsg;
711
	iov[iov_cnt].iov_len = sizeof(smsg);
712
	iov_cnt++;
713
714
	/* sa */
715
	iov[iov_cnt].iov_base = &sa1;
716
	iov[iov_cnt].iov_len = sizeof(sa1);
717
	smsg.sadb_msg_len += sa1.sadb_sa_len;
718
	iov_cnt++;
719
720
	/* dst addr */
721
	iov[iov_cnt].iov_base = &sa_dst;
722
	iov[iov_cnt].iov_len = sizeof(sa_dst);
723
	iov_cnt++;
724
	iov[iov_cnt].iov_base = &sdst;
725
	iov[iov_cnt].iov_len = ROUNDUP(sdst.ss_len);
726
	smsg.sadb_msg_len += sa_dst.sadb_address_len;
727
	iov_cnt++;
728
729
	/* second sa */
730
	iov[iov_cnt].iov_base = &sa2;
731
	iov[iov_cnt].iov_len = sizeof(sa2);
732
	smsg.sadb_msg_len += sa2.sadb_sa_len;
733
	iov_cnt++;
734
735
	/* second dst addr */
736
	iov[iov_cnt].iov_base = &sa_dst2;
737
	iov[iov_cnt].iov_len = sizeof(sa_dst2);
738
	iov_cnt++;
739
	iov[iov_cnt].iov_base = &sdst2;
740
	iov[iov_cnt].iov_len = ROUNDUP(sdst2.ss_len);
741
	smsg.sadb_msg_len += sa_dst2.sadb_address_len;
742
	iov_cnt++;
743
744
	/* SA type */
745
	iov[iov_cnt].iov_base = &sa_proto;
746
	iov[iov_cnt].iov_len = sizeof(sa_proto);
747
	smsg.sadb_msg_len += sa_proto.sadb_protocol_len;
748
	iov_cnt++;
749
750
	len = smsg.sadb_msg_len * 8;
751
	if ((n = writev(sd, iov, iov_cnt)) == -1) {
752
		warn("writev failed");
753
		ret = -1;
754
	} else if (n != len) {
755
		warnx("short write");
756
		ret = -1;
757
	}
758
759
	return (ret);
760
}
761
762
static int
763
pfkey_reply(int sd, u_int8_t **datap, ssize_t *lenp)
764
{
765
	struct sadb_msg	 hdr;
766
	ssize_t		 len;
767
	u_int8_t	*data;
768
769
	if (recv(sd, &hdr, sizeof(hdr), MSG_PEEK) != sizeof(hdr)) {
770
		warnx("short read");
771
		return -1;
772
	}
773
	len = hdr.sadb_msg_len * PFKEYV2_CHUNK;
774
	if ((data = malloc(len)) == NULL)
775
		err(1, "pfkey_reply: malloc");
776
	if (read(sd, data, len) != len) {
777
		warn("PF_KEY short read");
778
		explicit_bzero(data, len);
779
		free(data);
780
		return -1;
781
	}
782
	if (datap) {
783
		*datap = data;
784
		if (lenp)
785
			*lenp = len;
786
	} else {
787
		explicit_bzero(data, len);
788
		free(data);
789
	}
790
	if (datap == NULL && hdr.sadb_msg_errno != 0) {
791
		errno = hdr.sadb_msg_errno;
792
		if (errno != EEXIST) {
793
			warn("PF_KEY failed");
794
			return -1;
795
		}
796
	}
797
	return 0;
798
}
799
800
int
801
pfkey_parse(struct sadb_msg *msg, struct ipsec_rule *rule)
802
{
803
	struct sadb_ext		*ext;
804
	struct sadb_address	*saddr;
805
	struct sadb_protocol	*sproto;
806
	struct sadb_ident	*sident;
807
	struct sockaddr		*sa;
808
	struct sockaddr_in	*sa_in;
809
	struct sockaddr_in6	*sa_in6;
810
	int			 len;
811
812
	switch (msg->sadb_msg_satype) {
813
	case SADB_SATYPE_ESP:
814
		rule->satype = IPSEC_ESP;
815
		break;
816
	case SADB_SATYPE_AH:
817
		rule->satype = IPSEC_AH;
818
		break;
819
	case SADB_X_SATYPE_IPCOMP:
820
		rule->satype = IPSEC_IPCOMP;
821
		break;
822
	case SADB_X_SATYPE_IPIP:
823
		rule->satype = IPSEC_IPIP;
824
		break;
825
	default:
826
		return (1);
827
	}
828
829
	for (ext = (struct sadb_ext *)(msg + 1);
830
	    (size_t)((u_int8_t *)ext - (u_int8_t *)msg) <
831
	    msg->sadb_msg_len * PFKEYV2_CHUNK && ext->sadb_ext_len > 0;
832
	    ext = (struct sadb_ext *)((u_int8_t *)ext +
833
	    ext->sadb_ext_len * PFKEYV2_CHUNK)) {
834
		switch (ext->sadb_ext_type) {
835
		case SADB_EXT_ADDRESS_SRC:
836
			saddr = (struct sadb_address *)ext;
837
			sa = (struct sockaddr *)(saddr + 1);
838
839
			rule->local = calloc(1, sizeof(struct ipsec_addr_wrap));
840
			if (rule->local == NULL)
841
				err(1, "pfkey_parse: calloc");
842
843
			rule->local->af = sa->sa_family;
844
			switch (sa->sa_family) {
845
			case AF_INET:
846
				bcopy(&((struct sockaddr_in *)sa)->sin_addr,
847
				    &rule->local->address.v4,
848
				    sizeof(struct in_addr));
849
				set_ipmask(rule->local, 32);
850
				break;
851
			case AF_INET6:
852
				bcopy(&((struct sockaddr_in6 *)sa)->sin6_addr,
853
				    &rule->local->address.v6,
854
				    sizeof(struct in6_addr));
855
				set_ipmask(rule->local, 128);
856
				break;
857
			default:
858
				return (1);
859
			}
860
			break;
861
862
863
		case SADB_EXT_ADDRESS_DST:
864
			saddr = (struct sadb_address *)ext;
865
			sa = (struct sockaddr *)(saddr + 1);
866
867
			rule->peer = calloc(1, sizeof(struct ipsec_addr_wrap));
868
			if (rule->peer == NULL)
869
				err(1, "pfkey_parse: calloc");
870
871
			rule->peer->af = sa->sa_family;
872
			switch (sa->sa_family) {
873
			case AF_INET:
874
				bcopy(&((struct sockaddr_in *)sa)->sin_addr,
875
				    &rule->peer->address.v4,
876
				    sizeof(struct in_addr));
877
				set_ipmask(rule->peer, 32);
878
				break;
879
			case AF_INET6:
880
				bcopy(&((struct sockaddr_in6 *)sa)->sin6_addr,
881
				    &rule->peer->address.v6,
882
				    sizeof(struct in6_addr));
883
				set_ipmask(rule->peer, 128);
884
				break;
885
			default:
886
				return (1);
887
			}
888
			break;
889
890
		case SADB_EXT_IDENTITY_SRC:
891
			sident = (struct sadb_ident *)ext;
892
			len = (sident->sadb_ident_len * sizeof(uint64_t)) -
893
			    sizeof(struct sadb_ident);
894
895
			if (rule->auth == NULL) {
896
				rule->auth = calloc(1, sizeof(struct
897
				    ipsec_auth));
898
				if (rule->auth == NULL)
899
					err(1, "pfkey_parse: calloc");
900
			}
901
902
			rule->auth->srcid = calloc(1, len);
903
			if (rule->auth->srcid == NULL)
904
				err(1, "pfkey_parse: calloc");
905
906
			strlcpy(rule->auth->srcid, (char *)(sident + 1), len);
907
			break;
908
909
		case SADB_EXT_IDENTITY_DST:
910
			sident = (struct sadb_ident *)ext;
911
			len = (sident->sadb_ident_len * sizeof(uint64_t)) -
912
			    sizeof(struct sadb_ident);
913
914
			if (rule->auth == NULL) {
915
				rule->auth = calloc(1, sizeof(struct
916
				    ipsec_auth));
917
				if (rule->auth == NULL)
918
					err(1, "pfkey_parse: calloc");
919
			}
920
921
			rule->auth->dstid = calloc(1, len);
922
			if (rule->auth->dstid == NULL)
923
				err(1, "pfkey_parse: calloc");
924
925
			strlcpy(rule->auth->dstid, (char *)(sident + 1), len);
926
			break;
927
928
		case SADB_X_EXT_PROTOCOL:
929
			sproto = (struct sadb_protocol *)ext;
930
			if (sproto->sadb_protocol_direction == 0)
931
				rule->proto = sproto->sadb_protocol_proto;
932
			break;
933
934
		case SADB_X_EXT_FLOW_TYPE:
935
			sproto = (struct sadb_protocol *)ext;
936
937
			switch (sproto->sadb_protocol_direction) {
938
			case IPSP_DIRECTION_IN:
939
				rule->direction = IPSEC_IN;
940
				break;
941
			case IPSP_DIRECTION_OUT:
942
				rule->direction = IPSEC_OUT;
943
				break;
944
			default:
945
				return (1);
946
			}
947
			switch (sproto->sadb_protocol_proto) {
948
			case SADB_X_FLOW_TYPE_USE:
949
				rule->flowtype = TYPE_USE;
950
				break;
951
			case SADB_X_FLOW_TYPE_ACQUIRE:
952
				rule->flowtype = TYPE_ACQUIRE;
953
				break;
954
			case SADB_X_FLOW_TYPE_REQUIRE:
955
				rule->flowtype = TYPE_REQUIRE;
956
				break;
957
			case SADB_X_FLOW_TYPE_DENY:
958
				rule->flowtype = TYPE_DENY;
959
				break;
960
			case SADB_X_FLOW_TYPE_BYPASS:
961
				rule->flowtype = TYPE_BYPASS;
962
				break;
963
			case SADB_X_FLOW_TYPE_DONTACQ:
964
				rule->flowtype = TYPE_DONTACQ;
965
				break;
966
			default:
967
				rule->flowtype = TYPE_UNKNOWN;
968
				break;
969
			}
970
			break;
971
972
		case SADB_X_EXT_SRC_FLOW:
973
			saddr = (struct sadb_address *)ext;
974
			sa = (struct sockaddr *)(saddr + 1);
975
976
			if (rule->src == NULL) {
977
				rule->src = calloc(1,
978
				    sizeof(struct ipsec_addr_wrap));
979
				if (rule->src == NULL)
980
					err(1, "pfkey_parse: calloc");
981
			}
982
983
			rule->src->af = sa->sa_family;
984
			switch (sa->sa_family) {
985
			case AF_INET:
986
				bcopy(&((struct sockaddr_in *)sa)->sin_addr,
987
				    &rule->src->address.v4,
988
				    sizeof(struct in_addr));
989
				rule->sport =
990
				    ((struct sockaddr_in *)sa)->sin_port;
991
				break;
992
			case AF_INET6:
993
				bcopy(&((struct sockaddr_in6 *)sa)->sin6_addr,
994
				    &rule->src->address.v6,
995
				    sizeof(struct in6_addr));
996
				rule->sport =
997
				    ((struct sockaddr_in6 *)sa)->sin6_port;
998
				break;
999
			default:
1000
				return (1);
1001
			}
1002
			break;
1003
1004
		case SADB_X_EXT_DST_FLOW:
1005
			saddr = (struct sadb_address *)ext;
1006
			sa = (struct sockaddr *)(saddr + 1);
1007
1008
			if (rule->dst == NULL) {
1009
				rule->dst = calloc(1,
1010
				    sizeof(struct ipsec_addr_wrap));
1011
				if (rule->dst == NULL)
1012
					err(1, "pfkey_parse: calloc");
1013
			}
1014
1015
			rule->dst->af = sa->sa_family;
1016
			switch (sa->sa_family) {
1017
			case AF_INET:
1018
				bcopy(&((struct sockaddr_in *)sa)->sin_addr,
1019
				    &rule->dst->address.v4,
1020
				    sizeof(struct in_addr));
1021
				rule->dport =
1022
				    ((struct sockaddr_in *)sa)->sin_port;
1023
				break;
1024
			case AF_INET6:
1025
				bcopy(&((struct sockaddr_in6 *)sa)->sin6_addr,
1026
				    &rule->dst->address.v6,
1027
				    sizeof(struct in6_addr));
1028
				rule->dport =
1029
				    ((struct sockaddr_in6 *)sa)->sin6_port;
1030
				break;
1031
			default:
1032
				return (1);
1033
			}
1034
			break;
1035
1036
1037
		case SADB_X_EXT_SRC_MASK:
1038
			saddr = (struct sadb_address *)ext;
1039
			sa = (struct sockaddr *)(saddr + 1);
1040
1041
			if (rule->src == NULL) {
1042
				rule->src = calloc(1,
1043
				    sizeof(struct ipsec_addr_wrap));
1044
				if (rule->src == NULL)
1045
					err(1, "pfkey_parse: calloc");
1046
			}
1047
1048
			rule->src->af = sa->sa_family;
1049
			switch (sa->sa_family) {
1050
			case AF_INET:
1051
				sa_in = (struct sockaddr_in *)sa;
1052
				bcopy(&sa_in->sin_addr, &rule->src->mask.v4,
1053
				    sizeof(struct in_addr));
1054
				break;
1055
			case AF_INET6:
1056
				sa_in6 = (struct sockaddr_in6 *)sa;
1057
				bcopy(&sa_in6->sin6_addr, &rule->src->mask.v6,
1058
				    sizeof(struct in6_addr));
1059
				break;
1060
1061
			default:
1062
				return (1);
1063
			}
1064
			break;
1065
1066
		case SADB_X_EXT_DST_MASK:
1067
			saddr = (struct sadb_address *)ext;
1068
			sa = (struct sockaddr *)(saddr + 1);
1069
1070
			if (rule->dst == NULL) {
1071
				rule->dst = calloc(1,
1072
				    sizeof(struct ipsec_addr_wrap));
1073
				if (rule->dst == NULL)
1074
					err(1, "pfkey_parse: calloc");
1075
			}
1076
1077
			rule->dst->af = sa->sa_family;
1078
			switch (sa->sa_family) {
1079
			case AF_INET:
1080
				sa_in = (struct sockaddr_in *)sa;
1081
				bcopy(&sa_in->sin_addr, &rule->dst->mask.v4,
1082
				    sizeof(struct in_addr));
1083
				break;
1084
			case AF_INET6:
1085
				sa_in6 = (struct sockaddr_in6 *)sa;
1086
				bcopy(&sa_in6->sin6_addr, &rule->dst->mask.v6,
1087
				    sizeof(struct in6_addr));
1088
				break;
1089
			default:
1090
				return (1);
1091
			}
1092
			break;
1093
1094
		default:
1095
			return (1);
1096
		}
1097
	}
1098
1099
	return (0);
1100
}
1101
1102
int
1103
pfkey_ipsec_establish(int action, struct ipsec_rule *r)
1104
{
1105
	int		ret;
1106
	u_int8_t	satype, satype2, direction;
1107
1108
	if (r->type == RULE_FLOW) {
1109
		switch (r->satype) {
1110
		case IPSEC_ESP:
1111
			satype = SADB_SATYPE_ESP;
1112
			break;
1113
		case IPSEC_AH:
1114
			satype = SADB_SATYPE_AH;
1115
			break;
1116
		case IPSEC_IPCOMP:
1117
			satype = SADB_X_SATYPE_IPCOMP;
1118
			break;
1119
		case IPSEC_IPIP:
1120
			satype = SADB_X_SATYPE_IPIP;
1121
			break;
1122
		default:
1123
			return -1;
1124
		}
1125
1126
		switch (r->direction) {
1127
		case IPSEC_IN:
1128
			direction = IPSP_DIRECTION_IN;
1129
			break;
1130
		case IPSEC_OUT:
1131
			direction = IPSP_DIRECTION_OUT;
1132
			break;
1133
		default:
1134
			return -1;
1135
		}
1136
1137
		switch (action) {
1138
		case ACTION_ADD:
1139
			ret = pfkey_flow(fd, satype, SADB_X_ADDFLOW, direction,
1140
			    r->proto, r->src, r->sport, r->dst, r->dport,
1141
			    r->local, r->peer, r->auth, r->flowtype);
1142
			break;
1143
		case ACTION_DELETE:
1144
			/* No peer for flow deletion. */
1145
			ret = pfkey_flow(fd, satype, SADB_X_DELFLOW, direction,
1146
			    r->proto, r->src, r->sport, r->dst, r->dport,
1147
			    NULL, NULL, NULL, r->flowtype);
1148
			break;
1149
		default:
1150
			return -1;
1151
		}
1152
	} else if (r->type == RULE_SA) {
1153
		switch (r->satype) {
1154
		case IPSEC_AH:
1155
			satype = SADB_SATYPE_AH;
1156
			break;
1157
		case IPSEC_ESP:
1158
			satype = SADB_SATYPE_ESP;
1159
			break;
1160
		case IPSEC_IPCOMP:
1161
			satype = SADB_X_SATYPE_IPCOMP;
1162
			break;
1163
		case IPSEC_TCPMD5:
1164
			satype = SADB_X_SATYPE_TCPSIGNATURE;
1165
			break;
1166
		case IPSEC_IPIP:
1167
			satype = SADB_X_SATYPE_IPIP;
1168
			break;
1169
		default:
1170
			return -1;
1171
		}
1172
		switch (action) {
1173
		case ACTION_ADD:
1174
			ret = pfkey_sa(fd, satype, SADB_ADD, r->spi,
1175
			    r->src, r->dst, r->xfs, r->authkey, r->enckey,
1176
			    r->tmode);
1177
			break;
1178
		case ACTION_DELETE:
1179
			ret = pfkey_sa(fd, satype, SADB_DELETE, r->spi,
1180
			    r->src, r->dst, r->xfs, NULL, NULL, r->tmode);
1181
			break;
1182
		default:
1183
			return -1;
1184
		}
1185
	} else if (r->type == RULE_GROUP) {
1186
		switch (r->satype) {
1187
		case IPSEC_AH:
1188
			satype = SADB_SATYPE_AH;
1189
			break;
1190
		case IPSEC_ESP:
1191
			satype = SADB_SATYPE_ESP;
1192
			break;
1193
		case IPSEC_IPCOMP:
1194
			satype = SADB_X_SATYPE_IPCOMP;
1195
			break;
1196
		case IPSEC_TCPMD5:
1197
			satype = SADB_X_SATYPE_TCPSIGNATURE;
1198
			break;
1199
		case IPSEC_IPIP:
1200
			satype = SADB_X_SATYPE_IPIP;
1201
			break;
1202
		default:
1203
			return -1;
1204
		}
1205
		switch (r->proto2) {
1206
		case IPSEC_AH:
1207
			satype2 = SADB_SATYPE_AH;
1208
			break;
1209
		case IPSEC_ESP:
1210
			satype2 = SADB_SATYPE_ESP;
1211
			break;
1212
		case IPSEC_IPCOMP:
1213
			satype2 = SADB_X_SATYPE_IPCOMP;
1214
			break;
1215
		case IPSEC_TCPMD5:
1216
			satype2 = SADB_X_SATYPE_TCPSIGNATURE;
1217
			break;
1218
		case IPSEC_IPIP:
1219
			satype2 = SADB_X_SATYPE_IPIP;
1220
			break;
1221
		default:
1222
			return -1;
1223
		}
1224
		switch (action) {
1225
		case ACTION_ADD:
1226
			ret = pfkey_sagroup(fd, satype, satype2,
1227
			    SADB_X_GRPSPIS, r->dst, r->spi, r->dst2, r->spi2);
1228
			break;
1229
		case ACTION_DELETE:
1230
			return 0;
1231
		default:
1232
			return -1;
1233
		}
1234
	} else
1235
		return -1;
1236
1237
	if (ret < 0)
1238
		return -1;
1239
	if (pfkey_reply(fd, NULL, NULL) < 0)
1240
		return -1;
1241
1242
	return 0;
1243
}
1244
1245
int
1246
pfkey_ipsec_flush(void)
1247
{
1248
	struct sadb_msg smsg;
1249
	struct iovec	iov[IOV_CNT];
1250
	ssize_t		n;
1251
	int		iov_cnt, len;
1252
1253
	bzero(&smsg, sizeof(smsg));
1254
	smsg.sadb_msg_version = PF_KEY_V2;
1255
	smsg.sadb_msg_seq = sadb_msg_seq++;
1256
	smsg.sadb_msg_pid = getpid();
1257
	smsg.sadb_msg_len = sizeof(smsg) / 8;
1258
	smsg.sadb_msg_type = SADB_FLUSH;
1259
	smsg.sadb_msg_satype = SADB_SATYPE_UNSPEC;
1260
1261
	iov_cnt = 0;
1262
1263
	iov[iov_cnt].iov_base = &smsg;
1264
	iov[iov_cnt].iov_len = sizeof(smsg);
1265
	iov_cnt++;
1266
1267
	len = smsg.sadb_msg_len * 8;
1268
	if ((n = writev(fd, iov, iov_cnt)) == -1) {
1269
		warn("writev failed");
1270
		return -1;
1271
	}
1272
	if (n != len) {
1273
		warnx("short write");
1274
		return -1;
1275
	}
1276
	if (pfkey_reply(fd, NULL, NULL) < 0)
1277
		return -1;
1278
1279
	return 0;
1280
}
1281
1282
static int
1283
pfkey_promisc(void)
1284
{
1285
	struct sadb_msg msg;
1286
1287
	memset(&msg, 0, sizeof(msg));
1288
	msg.sadb_msg_version = PF_KEY_V2;
1289
	msg.sadb_msg_seq = sadb_msg_seq++;
1290
	msg.sadb_msg_pid = getpid();
1291
	msg.sadb_msg_len = sizeof(msg) / PFKEYV2_CHUNK;
1292
	msg.sadb_msg_type = SADB_X_PROMISC;
1293
	msg.sadb_msg_satype = 1;	/* enable */
1294
	if (write(fd, &msg, sizeof(msg)) != sizeof(msg)) {
1295
		warn("pfkey_promisc: write failed");
1296
		return -1;
1297
	}
1298
	if (pfkey_reply(fd, NULL, NULL) < 0)
1299
		return -1;
1300
	return 0;
1301
}
1302
1303
int
1304
pfkey_monitor(int opts)
1305
{
1306
	struct pollfd pfd[1];
1307
	struct sadb_msg *msg;
1308
	u_int8_t *data;
1309
	ssize_t len;
1310
	int n;
1311
1312
	if (pfkey_init() < 0)
1313
		return -1;
1314
	if (pfkey_promisc() < 0)
1315
		return -1;
1316
1317
	pfd[0].fd = fd;
1318
	pfd[0].events = POLLIN;
1319
	for (;;) {
1320
		if ((n = poll(pfd, 1, -1)) < 0)
1321
			err(2, "poll");
1322
		if (n == 0)
1323
			break;
1324
		if ((pfd[0].revents & POLLIN) == 0)
1325
			continue;
1326
		if (pfkey_reply(fd, &data, &len) < 0)
1327
			continue;
1328
		msg = (struct sadb_msg *)data;
1329
		if (msg->sadb_msg_type == SADB_X_PROMISC) {
1330
			/* remove extra header from promisc messages */
1331
			if ((msg->sadb_msg_len * PFKEYV2_CHUNK) >=
1332
			    2 * sizeof(struct sadb_msg)) {
1333
				msg++;
1334
			}
1335
		}
1336
		pfkey_monitor_sa(msg, opts);
1337
		if (opts & IPSECCTL_OPT_VERBOSE)
1338
			pfkey_print_raw(data, len);
1339
		explicit_bzero(data, len);
1340
		free(data);
1341
	}
1342
	close(fd);
1343
	return 0;
1344
}
1345
1346
int
1347
pfkey_init(void)
1348
{
1349
	if ((fd = socket(PF_KEY, SOCK_RAW, PF_KEY_V2)) == -1)
1350
		err(1, "pfkey_init: failed to open PF_KEY socket");
1351
1352
	return 0;
1353
}