GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: sbin/iked/config.c Lines: 0 422 0.0 %
Date: 2017-11-07 Branches: 0 217 0.0 %

Line Branch Exec Source
1
/*	$OpenBSD: config.c,v 1.48 2017/04/13 07:04:09 patrick Exp $	*/
2
3
/*
4
 * Copyright (c) 2010-2013 Reyk Floeter <reyk@openbsd.org>
5
 *
6
 * Permission to use, copy, modify, and distribute this software for any
7
 * purpose with or without fee is hereby granted, provided that the above
8
 * copyright notice and this permission notice appear in all copies.
9
 *
10
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
 */
18
19
#include <sys/queue.h>
20
#include <sys/wait.h>
21
#include <sys/socket.h>
22
#include <sys/uio.h>
23
24
#include <stdlib.h>
25
#include <stdio.h>
26
#include <unistd.h>
27
#include <string.h>
28
#include <signal.h>
29
#include <errno.h>
30
#include <err.h>
31
#include <pwd.h>
32
#include <event.h>
33
34
#include <openssl/evp.h>
35
#include <openssl/pem.h>
36
37
#include "iked.h"
38
#include "ikev2.h"
39
40
struct iked_sa *
41
config_new_sa(struct iked *env, int initiator)
42
{
43
	struct iked_sa	*sa;
44
45
	if ((sa = calloc(1, sizeof(*sa))) == NULL)
46
		return (NULL);
47
48
	TAILQ_INIT(&sa->sa_proposals);
49
	TAILQ_INIT(&sa->sa_childsas);
50
	TAILQ_INIT(&sa->sa_flows);
51
	TAILQ_INIT(&sa->sa_requests);
52
	TAILQ_INIT(&sa->sa_responses);
53
	sa->sa_hdr.sh_initiator = initiator;
54
	sa->sa_type = IKED_SATYPE_LOCAL;
55
56
	if (initiator)
57
		sa->sa_hdr.sh_ispi = config_getspi();
58
	else
59
		sa->sa_hdr.sh_rspi = config_getspi();
60
61
	gettimeofday(&sa->sa_timecreated, NULL);
62
	memcpy(&sa->sa_timeused, &sa->sa_timecreated, sizeof(sa->sa_timeused));
63
64
	return (sa);
65
}
66
67
uint64_t
68
config_getspi(void)
69
{
70
	uint64_t	 spi;
71
72
	do {
73
		arc4random_buf(&spi, sizeof spi);
74
	} while (spi == 0);
75
76
	return (spi);
77
}
78
79
void
80
config_free_kex(struct iked_kex *kex)
81
{
82
	if (kex == NULL)
83
		return;
84
85
	ibuf_release(kex->kex_inonce);
86
	ibuf_release(kex->kex_rnonce);
87
88
	if (kex->kex_dhgroup != NULL)
89
		group_free(kex->kex_dhgroup);
90
	ibuf_release(kex->kex_dhiexchange);
91
	ibuf_release(kex->kex_dhrexchange);
92
93
	free(kex);
94
}
95
96
void
97
config_free_sa(struct iked *env, struct iked_sa *sa)
98
{
99
	timer_del(env, &sa->sa_timer);
100
	timer_del(env, &sa->sa_keepalive);
101
	timer_del(env, &sa->sa_rekey);
102
103
	config_free_proposals(&sa->sa_proposals, 0);
104
	config_free_childsas(env, &sa->sa_childsas, NULL, NULL);
105
	sa_free_flows(env, &sa->sa_flows);
106
107
	if (sa->sa_addrpool) {
108
		(void)RB_REMOVE(iked_addrpool, &env->sc_addrpool, sa);
109
		free(sa->sa_addrpool);
110
	}
111
	if (sa->sa_addrpool6) {
112
		(void)RB_REMOVE(iked_addrpool6, &env->sc_addrpool6, sa);
113
		free(sa->sa_addrpool6);
114
	}
115
116
	if (sa->sa_policy) {
117
		TAILQ_REMOVE(&sa->sa_policy->pol_sapeers, sa, sa_peer_entry);
118
		policy_unref(env, sa->sa_policy);
119
	}
120
121
	ikev2_msg_flushqueue(env, &sa->sa_requests);
122
	ikev2_msg_flushqueue(env, &sa->sa_responses);
123
124
	ibuf_release(sa->sa_inonce);
125
	ibuf_release(sa->sa_rnonce);
126
127
	if (sa->sa_dhgroup != NULL)
128
		group_free(sa->sa_dhgroup);
129
	ibuf_release(sa->sa_dhiexchange);
130
	ibuf_release(sa->sa_dhrexchange);
131
132
	ibuf_release(sa->sa_simult);
133
134
	hash_free(sa->sa_prf);
135
	hash_free(sa->sa_integr);
136
	cipher_free(sa->sa_encr);
137
138
	ibuf_release(sa->sa_key_d);
139
	ibuf_release(sa->sa_key_iauth);
140
	ibuf_release(sa->sa_key_rauth);
141
	ibuf_release(sa->sa_key_iencr);
142
	ibuf_release(sa->sa_key_rencr);
143
	ibuf_release(sa->sa_key_iprf);
144
	ibuf_release(sa->sa_key_rprf);
145
146
	ibuf_release(sa->sa_1stmsg);
147
	ibuf_release(sa->sa_2ndmsg);
148
149
	ibuf_release(sa->sa_iid.id_buf);
150
	ibuf_release(sa->sa_rid.id_buf);
151
	ibuf_release(sa->sa_icert.id_buf);
152
	ibuf_release(sa->sa_rcert.id_buf);
153
154
	ibuf_release(sa->sa_eap.id_buf);
155
	free(sa->sa_eapid);
156
	ibuf_release(sa->sa_eapmsk);
157
158
	free(sa->sa_tag);
159
	free(sa);
160
}
161
162
struct iked_policy *
163
config_new_policy(struct iked *env)
164
{
165
	struct iked_policy	*pol;
166
167
	if ((pol = calloc(1, sizeof(*pol))) == NULL)
168
		return (NULL);
169
170
	/* XXX caller does this again */
171
	TAILQ_INIT(&pol->pol_proposals);
172
	TAILQ_INIT(&pol->pol_sapeers);
173
	RB_INIT(&pol->pol_flows);
174
175
	return (pol);
176
}
177
178
void
179
config_free_policy(struct iked *env, struct iked_policy *pol)
180
{
181
	struct iked_sa		*sa;
182
183
	if (pol->pol_flags & IKED_POLICY_REFCNT)
184
		goto remove;
185
186
	TAILQ_REMOVE(&env->sc_policies, pol, pol_entry);
187
188
	TAILQ_FOREACH(sa, &pol->pol_sapeers, sa_peer_entry) {
189
		/* Remove from the policy list, but keep for existing SAs */
190
		if (sa->sa_policy == pol)
191
			policy_ref(env, pol);
192
		else
193
			log_warnx("%s: ERROR: sa_policy %p != pol %p",
194
			    __func__, sa->sa_policy, pol);
195
	}
196
197
	if (pol->pol_refcnt)
198
		return;
199
200
 remove:
201
	config_free_proposals(&pol->pol_proposals, 0);
202
	config_free_flows(env, &pol->pol_flows);
203
	free(pol);
204
}
205
206
struct iked_proposal *
207
config_add_proposal(struct iked_proposals *head, unsigned int id,
208
    unsigned int proto)
209
{
210
	struct iked_proposal	*pp;
211
212
	TAILQ_FOREACH(pp, head, prop_entry) {
213
		if (pp->prop_protoid == proto &&
214
		    pp->prop_id == id)
215
			return (pp);
216
	}
217
218
	if ((pp = calloc(1, sizeof(*pp))) == NULL)
219
		return (NULL);
220
221
	pp->prop_protoid = proto;
222
	pp->prop_id = id;
223
224
	TAILQ_INSERT_TAIL(head, pp, prop_entry);
225
226
	return (pp);
227
}
228
229
void
230
config_free_proposals(struct iked_proposals *head, unsigned int proto)
231
{
232
	struct iked_proposal	*prop, *next;
233
234
	for (prop = TAILQ_FIRST(head); prop != NULL; prop = next) {
235
		next = TAILQ_NEXT(prop, prop_entry);
236
237
		/* Free any proposal or only selected SA proto */
238
		if (proto != 0 && prop->prop_protoid != proto)
239
			continue;
240
241
		log_debug("%s: free %p", __func__, prop);
242
243
		TAILQ_REMOVE(head, prop, prop_entry);
244
		if (prop->prop_nxforms)
245
			free(prop->prop_xforms);
246
		free(prop);
247
	}
248
}
249
250
void
251
config_free_flows(struct iked *env, struct iked_flows *head)
252
{
253
	struct iked_flow	*flow, *next;
254
255
	for (flow = RB_MIN(iked_flows, head); flow != NULL; flow = next) {
256
		next = RB_NEXT(iked_flows, head, flow);
257
		log_debug("%s: free %p", __func__, flow);
258
		RB_REMOVE(iked_flows, head, flow);
259
		flow_free(flow);
260
	}
261
}
262
263
void
264
config_free_childsas(struct iked *env, struct iked_childsas *head,
265
    struct iked_spi *peerspi, struct iked_spi *localspi)
266
{
267
	struct iked_childsa	*csa, *nextcsa;
268
269
	if (localspi != NULL)
270
		bzero(localspi, sizeof(*localspi));
271
272
	for (csa = TAILQ_FIRST(head); csa != NULL; csa = nextcsa) {
273
		nextcsa = TAILQ_NEXT(csa, csa_entry);
274
275
		if (peerspi != NULL) {
276
			/* Only delete matching peer SPIs */
277
			if (peerspi->spi != csa->csa_peerspi)
278
				continue;
279
280
			/* Store assigned local SPI */
281
			if (localspi != NULL && localspi->spi == 0)
282
				memcpy(localspi, &csa->csa_spi,
283
				    sizeof(*localspi));
284
		}
285
		log_debug("%s: free %p", __func__, csa);
286
287
		TAILQ_REMOVE(head, csa, csa_entry);
288
		if (csa->csa_loaded) {
289
			RB_REMOVE(iked_activesas, &env->sc_activesas, csa);
290
			(void)pfkey_sa_delete(env->sc_pfkey, csa);
291
		}
292
		childsa_free(csa);
293
	}
294
}
295
296
struct iked_transform *
297
config_add_transform(struct iked_proposal *prop, unsigned int type,
298
    unsigned int id, unsigned int length, unsigned int keylength)
299
{
300
	struct iked_transform	*xform;
301
	struct iked_constmap	*map = NULL;
302
	int			 score = 1;
303
	unsigned int		 i;
304
305
	switch (type) {
306
	case IKEV2_XFORMTYPE_ENCR:
307
		map = ikev2_xformencr_map;
308
		break;
309
	case IKEV2_XFORMTYPE_PRF:
310
		map = ikev2_xformprf_map;
311
		break;
312
	case IKEV2_XFORMTYPE_INTEGR:
313
		map = ikev2_xformauth_map;
314
		break;
315
	case IKEV2_XFORMTYPE_DH:
316
		map = ikev2_xformdh_map;
317
		break;
318
	case IKEV2_XFORMTYPE_ESN:
319
		map = ikev2_xformesn_map;
320
		break;
321
	default:
322
		log_debug("%s: invalid transform type %d", __func__, type);
323
		return (NULL);
324
	}
325
326
	for (i = 0; i < prop->prop_nxforms; i++) {
327
		xform = prop->prop_xforms + i;
328
		if (xform->xform_type == type &&
329
		    xform->xform_id == id &&
330
		    xform->xform_length == length)
331
			return (xform);
332
	}
333
334
	for (i = 0; i < prop->prop_nxforms; i++) {
335
		xform = prop->prop_xforms + i;
336
		if (xform->xform_type == type) {
337
			switch (type) {
338
			case IKEV2_XFORMTYPE_ENCR:
339
			case IKEV2_XFORMTYPE_INTEGR:
340
				score += 3;
341
				break;
342
			case IKEV2_XFORMTYPE_DH:
343
				score += 2;
344
				break;
345
			default:
346
				score += 1;
347
				break;
348
			}
349
		}
350
	}
351
352
	if ((xform = reallocarray(prop->prop_xforms,
353
	    prop->prop_nxforms + 1, sizeof(*xform))) == NULL) {
354
		return (NULL);
355
	}
356
357
	prop->prop_xforms = xform;
358
	xform = prop->prop_xforms + prop->prop_nxforms++;
359
	bzero(xform, sizeof(*xform));
360
361
	xform->xform_type = type;
362
	xform->xform_id = id;
363
	xform->xform_length = length;
364
	xform->xform_keylength = keylength;
365
	xform->xform_score = score;
366
	xform->xform_map = map;
367
368
	return (xform);
369
}
370
371
struct iked_transform *
372
config_findtransform(struct iked_proposals *props, uint8_t type,
373
    unsigned int proto)
374
{
375
	struct iked_proposal	*prop;
376
	struct iked_transform	*xform;
377
	unsigned int		 i;
378
379
	/* Search of the first transform with the desired type */
380
	TAILQ_FOREACH(prop, props, prop_entry) {
381
		/* Find any proposal or only selected SA proto */
382
		if (proto != 0 && prop->prop_protoid != proto)
383
			continue;
384
		for (i = 0; i < prop->prop_nxforms; i++) {
385
			xform = prop->prop_xforms + i;
386
			if (xform->xform_type == type)
387
				return (xform);
388
		}
389
	}
390
391
	return (NULL);
392
}
393
394
struct iked_user *
395
config_new_user(struct iked *env, struct iked_user *new)
396
{
397
	struct iked_user	*usr, *old;
398
399
	if ((usr = calloc(1, sizeof(*usr))) == NULL)
400
		return (NULL);
401
402
	memcpy(usr, new, sizeof(*usr));
403
404
	if ((old = RB_INSERT(iked_users, &env->sc_users, usr)) != NULL) {
405
		/* Update the password of an existing user*/
406
		memcpy(old, new, sizeof(*old));
407
408
		log_debug("%s: updating user %s", __func__, usr->usr_name);
409
		free(usr);
410
411
		return (old);
412
	}
413
414
	log_debug("%s: inserting new user %s", __func__, usr->usr_name);
415
	return (usr);
416
}
417
418
/*
419
 * Inter-process communication of configuration items.
420
 */
421
422
int
423
config_setcoupled(struct iked *env, unsigned int couple)
424
{
425
	unsigned int	 type;
426
427
	type = couple ? IMSG_CTL_COUPLE : IMSG_CTL_DECOUPLE;
428
	proc_compose(&env->sc_ps, PROC_IKEV2, type, NULL, 0);
429
430
	return (0);
431
}
432
433
int
434
config_getcoupled(struct iked *env, unsigned int type)
435
{
436
	return (pfkey_couple(env->sc_pfkey, &env->sc_sas,
437
	    type == IMSG_CTL_COUPLE ? 1 : 0));
438
}
439
440
int
441
config_setmode(struct iked *env, unsigned int passive)
442
{
443
	unsigned int	 type;
444
445
	type = passive ? IMSG_CTL_PASSIVE : IMSG_CTL_ACTIVE;
446
	proc_compose(&env->sc_ps, PROC_IKEV2, type, NULL, 0);
447
448
	return (0);
449
}
450
451
int
452
config_getmode(struct iked *env, unsigned int type)
453
{
454
	uint8_t		 old;
455
	unsigned char	*mode[] = { "active", "passive" };
456
457
	old = env->sc_passive ? 1 : 0;
458
	env->sc_passive = type == IMSG_CTL_PASSIVE ? 1 : 0;
459
460
	if (old == env->sc_passive)
461
		return (0);
462
463
	log_debug("%s: mode %s -> %s", __func__,
464
	    mode[old], mode[env->sc_passive]);
465
466
	return (0);
467
}
468
469
int
470
config_setreset(struct iked *env, unsigned int mode, enum privsep_procid id)
471
{
472
	proc_compose(&env->sc_ps, id, IMSG_CTL_RESET, &mode, sizeof(mode));
473
	return (0);
474
}
475
476
int
477
config_getreset(struct iked *env, struct imsg *imsg)
478
{
479
	struct iked_policy	*pol, *nextpol;
480
	struct iked_sa		*sa, *nextsa;
481
	struct iked_user	*usr, *nextusr;
482
	unsigned int		 mode;
483
484
	IMSG_SIZE_CHECK(imsg, &mode);
485
	memcpy(&mode, imsg->data, sizeof(mode));
486
487
	if (mode == RESET_ALL || mode == RESET_POLICY) {
488
		log_debug("%s: flushing policies", __func__);
489
		for (pol = TAILQ_FIRST(&env->sc_policies);
490
		    pol != NULL; pol = nextpol) {
491
			nextpol = TAILQ_NEXT(pol, pol_entry);
492
			config_free_policy(env, pol);
493
		}
494
	}
495
496
	if (mode == RESET_ALL || mode == RESET_SA) {
497
		log_debug("%s: flushing SAs", __func__);
498
		for (sa = RB_MIN(iked_sas, &env->sc_sas);
499
		    sa != NULL; sa = nextsa) {
500
			nextsa = RB_NEXT(iked_sas, &env->sc_sas, sa);
501
			RB_REMOVE(iked_sas, &env->sc_sas, sa);
502
			config_free_sa(env, sa);
503
		}
504
	}
505
506
	if (mode == RESET_ALL || mode == RESET_USER) {
507
		log_debug("%s: flushing users", __func__);
508
		for (usr = RB_MIN(iked_users, &env->sc_users);
509
		    usr != NULL; usr = nextusr) {
510
			nextusr = RB_NEXT(iked_users, &env->sc_users, usr);
511
			RB_REMOVE(iked_users, &env->sc_users, usr);
512
			free(usr);
513
		}
514
	}
515
516
	return (0);
517
}
518
519
int
520
config_setsocket(struct iked *env, struct sockaddr_storage *ss,
521
    in_port_t port, enum privsep_procid id)
522
{
523
	int	 s;
524
525
	if ((s = udp_bind((struct sockaddr *)ss, port)) == -1)
526
		return (-1);
527
	proc_compose_imsg(&env->sc_ps, id, -1,
528
	    IMSG_UDP_SOCKET, -1, s, ss, sizeof(*ss));
529
	return (0);
530
}
531
532
int
533
config_getsocket(struct iked *env, struct imsg *imsg,
534
    void (*cb)(int, short, void *))
535
{
536
	struct iked_socket	*sock, **sptr, **nptr;
537
538
	log_debug("%s: received socket fd %d", __func__, imsg->fd);
539
540
	if ((sock = calloc(1, sizeof(*sock))) == NULL)
541
		fatal("config_getsocket: calloc");
542
543
	IMSG_SIZE_CHECK(imsg, &sock->sock_addr);
544
545
	memcpy(&sock->sock_addr, imsg->data, sizeof(sock->sock_addr));
546
	sock->sock_fd = imsg->fd;
547
	sock->sock_env = env;
548
549
	switch (sock->sock_addr.ss_family) {
550
	case AF_INET:
551
		sptr = &env->sc_sock4[0];
552
		nptr = &env->sc_sock4[1];
553
		break;
554
	case AF_INET6:
555
		sptr = &env->sc_sock6[0];
556
		nptr = &env->sc_sock6[1];
557
		break;
558
	default:
559
		fatal("config_getsocket: socket af");
560
		/* NOTREACHED */
561
	}
562
	if (*sptr == NULL)
563
		*sptr = sock;
564
	if (*nptr == NULL &&
565
	    socket_getport((struct sockaddr *)&sock->sock_addr) ==
566
	    IKED_NATT_PORT)
567
		*nptr = sock;
568
569
	event_set(&sock->sock_ev, sock->sock_fd,
570
	    EV_READ|EV_PERSIST, cb, sock);
571
	event_add(&sock->sock_ev, NULL);
572
573
	return (0);
574
}
575
576
int
577
config_setpfkey(struct iked *env, enum privsep_procid id)
578
{
579
	int	 s;
580
581
	if ((s = pfkey_socket()) == -1)
582
		return (-1);
583
	proc_compose_imsg(&env->sc_ps, id, -1,
584
	    IMSG_PFKEY_SOCKET, -1, s, NULL, 0);
585
	return (0);
586
}
587
588
int
589
config_getpfkey(struct iked *env, struct imsg *imsg)
590
{
591
	log_debug("%s: received pfkey fd %d", __func__, imsg->fd);
592
	pfkey_init(env, imsg->fd);
593
	return (0);
594
}
595
596
int
597
config_setuser(struct iked *env, struct iked_user *usr, enum privsep_procid id)
598
{
599
	if (env->sc_opts & IKED_OPT_NOACTION) {
600
		print_user(usr);
601
		return (0);
602
	}
603
604
	proc_compose(&env->sc_ps, id, IMSG_CFG_USER, usr, sizeof(*usr));
605
	return (0);
606
}
607
608
int
609
config_getuser(struct iked *env, struct imsg *imsg)
610
{
611
	struct iked_user	 usr;
612
613
	IMSG_SIZE_CHECK(imsg, &usr);
614
	memcpy(&usr, imsg->data, sizeof(usr));
615
616
	if (config_new_user(env, &usr) == NULL)
617
		return (-1);
618
619
	print_user(&usr);
620
621
	return (0);
622
}
623
624
int
625
config_setpolicy(struct iked *env, struct iked_policy *pol,
626
    enum privsep_procid id)
627
{
628
	struct iked_proposal	*prop;
629
	struct iked_transform	*xform;
630
	size_t			 iovcnt, j, c = 0;
631
	struct iovec		 iov[IOV_MAX];
632
633
	iovcnt = 1;
634
	TAILQ_FOREACH(prop, &pol->pol_proposals, prop_entry) {
635
		iovcnt += prop->prop_nxforms + 1;
636
	}
637
638
	if (iovcnt > IOV_MAX) {
639
		log_warn("%s: too many proposals", __func__);
640
		return (-1);
641
	}
642
643
	iov[c].iov_base = pol;
644
	iov[c++].iov_len = sizeof(*pol);
645
646
	TAILQ_FOREACH(prop, &pol->pol_proposals, prop_entry) {
647
		iov[c].iov_base = prop;
648
		iov[c++].iov_len = sizeof(*prop);
649
650
		for (j = 0; j < prop->prop_nxforms; j++) {
651
			xform = prop->prop_xforms + j;
652
653
			iov[c].iov_base = xform;
654
			iov[c++].iov_len = sizeof(*xform);
655
		}
656
	}
657
658
	print_policy(pol);
659
660
	if (env->sc_opts & IKED_OPT_NOACTION)
661
		return (0);
662
663
	if (proc_composev(&env->sc_ps, id, IMSG_CFG_POLICY, iov,
664
	    iovcnt) == -1) {
665
		log_debug("%s: proc_composev failed", __func__);
666
		return (-1);
667
	}
668
669
	return (0);
670
}
671
672
int
673
config_setflow(struct iked *env, struct iked_policy *pol,
674
    enum privsep_procid id)
675
{
676
	struct iked_flow	*flow;
677
	struct iovec		 iov[2];
678
679
	if (env->sc_opts & IKED_OPT_NOACTION)
680
		return (0);
681
682
	RB_FOREACH(flow, iked_flows, &pol->pol_flows) {
683
		iov[0].iov_base = &pol->pol_id;
684
		iov[0].iov_len = sizeof(pol->pol_id);
685
		iov[1].iov_base = flow;
686
		iov[1].iov_len = sizeof(*flow);
687
688
		if (proc_composev(&env->sc_ps, id, IMSG_CFG_FLOW,
689
		    iov, 2) == -1) {
690
			log_debug("%s: proc_composev failed", __func__);
691
			return (-1);
692
		}
693
	}
694
695
	return (0);
696
}
697
698
int
699
config_getpolicy(struct iked *env, struct imsg *imsg)
700
{
701
	struct iked_policy	*pol;
702
	struct iked_proposal	 pp, *prop;
703
	struct iked_transform	 xf, *xform;
704
	off_t			 offset = 0;
705
	unsigned int		 i, j;
706
	uint8_t			*buf = (uint8_t *)imsg->data;
707
708
	IMSG_SIZE_CHECK(imsg, pol);
709
	log_debug("%s: received policy", __func__);
710
711
	if ((pol = config_new_policy(NULL)) == NULL)
712
		fatal("config_getpolicy: new policy");
713
714
	memcpy(pol, buf, sizeof(*pol));
715
	offset += sizeof(*pol);
716
717
	TAILQ_INIT(&pol->pol_proposals);
718
	TAILQ_INIT(&pol->pol_sapeers);
719
	RB_INIT(&pol->pol_flows);
720
721
	for (i = 0; i < pol->pol_nproposals; i++) {
722
		memcpy(&pp, buf + offset, sizeof(pp));
723
		offset += sizeof(pp);
724
725
		if ((prop = config_add_proposal(&pol->pol_proposals,
726
		    pp.prop_id, pp.prop_protoid)) == NULL)
727
			fatal("config_getpolicy: add proposal");
728
729
		for (j = 0; j < pp.prop_nxforms; j++) {
730
			memcpy(&xf, buf + offset, sizeof(xf));
731
			offset += sizeof(xf);
732
733
			if ((xform = config_add_transform(prop, xf.xform_type,
734
			    xf.xform_id, xf.xform_length,
735
			    xf.xform_keylength)) == NULL)
736
				fatal("config_getpolicy: add transform");
737
		}
738
	}
739
740
	/* Flows are sent separately */
741
	pol->pol_nflows = 0;
742
743
	TAILQ_INSERT_TAIL(&env->sc_policies, pol, pol_entry);
744
745
	if (pol->pol_flags & IKED_POLICY_DEFAULT) {
746
		/* Only one default policy, just free/unref the old one */
747
		if (env->sc_defaultcon != NULL)
748
			config_free_policy(env, env->sc_defaultcon);
749
		env->sc_defaultcon = pol;
750
	}
751
752
	return (0);
753
}
754
755
int
756
config_getflow(struct iked *env, struct imsg *imsg)
757
{
758
	struct iked_policy	*pol;
759
	struct iked_flow	*flow;
760
	off_t			 offset = 0;
761
	unsigned int		 id;
762
	uint8_t			*buf = (uint8_t *)imsg->data;
763
764
	if (IMSG_DATA_SIZE(imsg) < sizeof(id))
765
		fatalx("bad length imsg received");
766
767
	memcpy(&id, buf, sizeof(id));
768
	offset += sizeof(id);
769
770
	TAILQ_FOREACH(pol, &env->sc_policies, pol_entry) {
771
		if (pol->pol_id == id)
772
			break;
773
	}
774
	if (pol == NULL) {
775
		log_warnx("%s: unknown policy %u", __func__, id);
776
		return (-1);
777
	}
778
779
	if ((flow = calloc(1, sizeof(*flow))) == NULL)
780
		fatal("config_getpolicy: new flow");
781
782
	memcpy(flow, buf + offset, sizeof(*flow));
783
784
	if (RB_INSERT(iked_flows, &pol->pol_flows, flow)) {
785
		log_warnx("%s: received duplicate flow", __func__);
786
		free(flow);
787
		return (-1);
788
	}
789
	pol->pol_nflows++;
790
791
	return (0);
792
}
793
794
int
795
config_setcompile(struct iked *env, enum privsep_procid id)
796
{
797
	if (env->sc_opts & IKED_OPT_NOACTION)
798
		return (0);
799
800
	proc_compose(&env->sc_ps, id, IMSG_COMPILE, NULL, 0);
801
	return (0);
802
}
803
804
int
805
config_getcompile(struct iked *env, struct imsg *imsg)
806
{
807
	/*
808
	 * Do any necessary steps after configuration, for now we
809
	 * only need to compile the skip steps.
810
	 */
811
	policy_calc_skip_steps(&env->sc_policies);
812
813
	log_debug("%s: compilation done", __func__);
814
	return (0);
815
}
816
817
int
818
config_setocsp(struct iked *env)
819
{
820
	if (env->sc_opts & IKED_OPT_NOACTION)
821
		return (0);
822
	proc_compose(&env->sc_ps, PROC_CERT,
823
	    IMSG_OCSP_URL, env->sc_ocsp_url,
824
	    env->sc_ocsp_url ? strlen(env->sc_ocsp_url) : 0);
825
826
	return (0);
827
}
828
829
int
830
config_getocsp(struct iked *env, struct imsg *imsg)
831
{
832
	free(env->sc_ocsp_url);
833
	if (IMSG_DATA_SIZE(imsg) > 0)
834
		env->sc_ocsp_url = get_string(imsg->data, IMSG_DATA_SIZE(imsg));
835
	else
836
		env->sc_ocsp_url = NULL;
837
	log_debug("%s: ocsp_url %s", __func__,
838
	    env->sc_ocsp_url ? env->sc_ocsp_url : "none");
839
	return (0);
840
}
841
842
int
843
config_setkeys(struct iked *env)
844
{
845
	FILE			*fp = NULL;
846
	EVP_PKEY		*key = NULL;
847
	struct iked_id		 privkey;
848
	struct iked_id		 pubkey;
849
	struct iovec		 iov[2];
850
	int			 ret = -1;
851
852
	memset(&privkey, 0, sizeof(privkey));
853
	memset(&pubkey, 0, sizeof(pubkey));
854
855
	/* Read private key */
856
	if ((fp = fopen(IKED_PRIVKEY, "r")) == NULL) {
857
		log_warn("%s: failed to open private key", __func__);
858
		goto done;
859
	}
860
861
	if ((key = PEM_read_PrivateKey(fp, NULL, NULL, NULL)) == NULL) {
862
		log_warnx("%s: failed to read private key", __func__);
863
		goto done;
864
	}
865
866
	if (ca_privkey_serialize(key, &privkey) != 0) {
867
		log_warnx("%s: failed to serialize private key", __func__);
868
		goto done;
869
	}
870
	if (ca_pubkey_serialize(key, &pubkey) != 0) {
871
		log_warnx("%s: failed to serialize public key", __func__);
872
		goto done;
873
	}
874
875
	iov[0].iov_base = &privkey;
876
	iov[0].iov_len = sizeof(privkey);
877
	iov[1].iov_base = ibuf_data(privkey.id_buf);
878
	iov[1].iov_len = ibuf_length(privkey.id_buf);
879
880
	if (proc_composev(&env->sc_ps, PROC_CERT, IMSG_PRIVKEY, iov, 2) == -1) {
881
		log_warnx("%s: failed to send private key", __func__);
882
		goto done;
883
	}
884
885
	iov[0].iov_base = &pubkey;
886
	iov[0].iov_len = sizeof(pubkey);
887
	iov[1].iov_base = ibuf_data(pubkey.id_buf);
888
	iov[1].iov_len = ibuf_length(pubkey.id_buf);
889
890
	if (proc_composev(&env->sc_ps, PROC_CERT, IMSG_PUBKEY, iov, 2) == -1) {
891
		log_warnx("%s: failed to send public key", __func__);
892
		goto done;
893
	}
894
895
	ret = 0;
896
 done:
897
	if (fp != NULL)
898
		fclose(fp);
899
900
	ibuf_release(pubkey.id_buf);
901
	ibuf_release(privkey.id_buf);
902
	EVP_PKEY_free(key);
903
904
	return (ret);
905
}
906
907
int
908
config_getkey(struct iked *env, struct imsg *imsg)
909
{
910
	size_t		 len;
911
	struct iked_id	 id;
912
913
	len = IMSG_DATA_SIZE(imsg);
914
	if (len <= sizeof(id))
915
		fatalx("%s: invalid key message", __func__);
916
917
	memcpy(&id, imsg->data, sizeof(id));
918
	if ((id.id_buf = ibuf_new((uint8_t *)imsg->data + sizeof(id),
919
	    len - sizeof(id))) == NULL)
920
		fatalx("%s: failed to get key", __func__);
921
922
	explicit_bzero(imsg->data, len);
923
	ca_getkey(&env->sc_ps, &id, imsg->hdr.type);
924
925
	return (0);
926
}