xref: /openbsd/sbin/iked/policy.c (revision f36db9c4)
1 /*	$OpenBSD: policy.c,v 1.99 2024/07/13 12:22:46 yasuoka Exp $	*/
2 
3 /*
4  * Copyright (c) 2020-2021 Tobias Heider <tobhe@openbsd.org>
5  * Copyright (c) 2010-2013 Reyk Floeter <reyk@openbsd.org>
6  * Copyright (c) 2001 Daniel Hartmeier
7  *
8  * Permission to use, copy, modify, and distribute this software for any
9  * purpose with or without fee is hereby granted, provided that the above
10  * copyright notice and this permission notice appear in all copies.
11  *
12  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19  */
20 
21 #include <sys/queue.h>
22 #include <sys/socket.h>
23 #include <sys/uio.h>
24 #include <sys/tree.h>
25 
26 #include <netinet/in.h>
27 
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <unistd.h>
31 #include <string.h>
32 #include <errno.h>
33 #include <fcntl.h>
34 #include <event.h>
35 
36 #include "iked.h"
37 #include "ikev2.h"
38 
39 static __inline int
40 	 sa_cmp(struct iked_sa *, struct iked_sa *);
41 static __inline int
42 	 sa_dstid_cmp(struct iked_sa *, struct iked_sa *);
43 static __inline int
44 	 user_cmp(struct iked_user *, struct iked_user *);
45 static __inline int
46 	 childsa_cmp(struct iked_childsa *, struct iked_childsa *);
47 static __inline int
48 	 flow_cmp(struct iked_flow *, struct iked_flow *);
49 static __inline int
50 	 addr_cmp(struct iked_addr *, struct iked_addr *, int);
51 static __inline int
52 	 ts_insert_unique(struct iked_addr *, struct iked_tss *, int);
53 
54 static int	policy_test_flows(struct iked_policy *, struct iked_policy *);
55 static int	proposals_match(struct iked_proposal *, struct iked_proposal *,
56 		    struct iked_transform **, int, int);
57 
58 void
policy_init(struct iked * env)59 policy_init(struct iked *env)
60 {
61 	TAILQ_INIT(&env->sc_policies);
62 	TAILQ_INIT(&env->sc_ocsp);
63 	TAILQ_INIT(&env->sc_radauthservers);
64 	TAILQ_INIT(&env->sc_radacctservers);
65 	TAILQ_INIT(&env->sc_radcfgmaps);
66 	TAILQ_INIT(&env->sc_raddaes);
67 	TAILQ_INIT(&env->sc_raddaeclients);
68 	RB_INIT(&env->sc_users);
69 	RB_INIT(&env->sc_sas);
70 	RB_INIT(&env->sc_dstid_sas);
71 	RB_INIT(&env->sc_activesas);
72 	RB_INIT(&env->sc_activeflows);
73 }
74 
75 /*
76  * Lookup an iked policy matching the IKE_AUTH message msg
77  * and store a pointer to the found policy in msg.  If no policy
78  * matches a pointer to the default policy is stored in msg.
79  * If 'proposals' is not NULL policy_lookup only returns policies
80  * compatible with 'proposals'.
81  *
82  * Returns 0 on success and -1 if no matching policy was
83  * found and no default exists.
84  */
85 int
policy_lookup(struct iked * env,struct iked_message * msg,struct iked_proposals * proposals,struct iked_flows * flows,int nflows)86 policy_lookup(struct iked *env, struct iked_message *msg,
87     struct iked_proposals *proposals, struct iked_flows *flows,
88     int nflows)
89 {
90 	struct iked_policy	 pol;
91 	char			*s, idstr[IKED_ID_SIZE];
92 
93 
94 	if (msg->msg_sa != NULL && msg->msg_sa->sa_policy != NULL) {
95 		/* Existing SA with policy */
96 		msg->msg_policy = msg->msg_sa->sa_policy;
97 		return (0);
98 	}
99 
100 	bzero(&pol, sizeof(pol));
101 	if (proposals != NULL)
102 		pol.pol_proposals = *proposals;
103 	pol.pol_af = msg->msg_peer.ss_family;
104 	if (flows)
105 		pol.pol_flows = *flows;
106 	pol.pol_nflows = nflows;
107 	if (msg->msg_flags & IKED_MSG_FLAGS_USE_TRANSPORT)
108 		pol.pol_flags |= IKED_POLICY_TRANSPORT;
109 	memcpy(&pol.pol_peer.addr, &msg->msg_peer, sizeof(msg->msg_peer));
110 	memcpy(&pol.pol_local.addr, &msg->msg_local, sizeof(msg->msg_local));
111 	if (msg->msg_peerid.id_type &&
112 	    ikev2_print_id(&msg->msg_peerid, idstr, IKED_ID_SIZE) == 0 &&
113 	    (s = strchr(idstr, '/')) != NULL) {
114 		pol.pol_peerid.id_type = msg->msg_peerid.id_type;
115 		pol.pol_peerid.id_length = strlen(s+1);
116 		strlcpy(pol.pol_peerid.id_data, s+1,
117 		    sizeof(pol.pol_peerid.id_data));
118 		log_debug("%s: peerid '%s'", __func__, s+1);
119 	}
120 	if (msg->msg_localid.id_type &&
121 	    ikev2_print_id(&msg->msg_localid, idstr, IKED_ID_SIZE) == 0 &&
122 	    (s = strchr(idstr, '/')) != NULL) {
123 		pol.pol_localid.id_type = msg->msg_localid.id_type;
124 		pol.pol_localid.id_length = strlen(s+1);
125 		strlcpy(pol.pol_localid.id_data, s+1,
126 		    sizeof(pol.pol_localid.id_data));
127 		log_debug("%s: localid '%s'", __func__, s+1);
128 	}
129 
130 	/* Try to find a matching policy for this message */
131 	if ((msg->msg_policy = policy_test(env, &pol)) != NULL) {
132 		log_debug("%s: setting policy '%s'", __func__,
133 		    msg->msg_policy->pol_name);
134 		return (0);
135 	}
136 
137 	/* No matching policy found, try the default */
138 	if ((msg->msg_policy = env->sc_defaultcon) != NULL)
139 		return (0);
140 
141 	/* No policy found */
142 	return (-1);
143 }
144 
145 /*
146  * Lookup an iked policy matching the SA sa and store a pointer
147  * to the found policy in SA.
148  *
149  * Returns 0 on success and -1 if no matching policy was
150  * found
151  */
152 int
policy_lookup_sa(struct iked * env,struct iked_sa * sa)153 policy_lookup_sa(struct iked *env, struct iked_sa *sa)
154 {
155 	struct iked_policy	 pol, *pol_found;
156 	struct iked_id		*lid, *pid;
157 	char			*s, idstr[IKED_ID_SIZE];
158 
159 	/*
160 	 * The SA should never be without policy. In the case of
161 	 * 'ikectl reload' the policy is no longer in sc_policies
162 	 * but is kept alive by the reference from the sa.
163 	 */
164 	if (sa->sa_policy == NULL) {
165 		log_warn("%s: missing SA policy.", SPI_SA(sa, __func__));
166 		return (-1);
167 	}
168 
169 	bzero(&pol, sizeof(pol));
170 	pol.pol_proposals = sa->sa_proposals;
171 	pol.pol_af = sa->sa_peer.addr_af;
172 	if (sa->sa_used_transport_mode)
173 		pol.pol_flags |= IKED_POLICY_TRANSPORT;
174 	memcpy(&pol.pol_peer.addr, &sa->sa_peer.addr, sizeof(sa->sa_peer.addr));
175 	memcpy(&pol.pol_local.addr, &sa->sa_local.addr, sizeof(sa->sa_local.addr));
176 	pol.pol_flows = sa->sa_policy->pol_flows;
177 	pol.pol_nflows = sa->sa_policy->pol_nflows;
178 
179 	if (sa->sa_hdr.sh_initiator) {
180 		lid = &sa->sa_iid;
181 		pid = &sa->sa_rid;
182 	} else {
183 		lid = &sa->sa_rid;
184 		pid = &sa->sa_iid;
185 	}
186 
187 	if (pid->id_type &&
188 	    ikev2_print_id(pid, idstr, IKED_ID_SIZE) == 0 &&
189 	    (s = strchr(idstr, '/')) != NULL) {
190 		pol.pol_peerid.id_type = pid->id_type;
191 		pol.pol_peerid.id_length = strlen(s+1);
192 		strlcpy(pol.pol_peerid.id_data, s+1,
193 		    sizeof(pol.pol_peerid.id_data));
194 		log_debug("%s: peerid '%s'", __func__, s+1);
195 	}
196 
197 	if (lid->id_type &&
198 	    ikev2_print_id(lid, idstr, IKED_ID_SIZE) == 0 &&
199 	    (s = strchr(idstr, '/')) != NULL) {
200 		pol.pol_localid.id_type = lid->id_type;
201 		pol.pol_localid.id_length = strlen(s+1);
202 		strlcpy(pol.pol_localid.id_data, s+1,
203 		    sizeof(pol.pol_localid.id_data));
204 		log_debug("%s: localid '%s'", __func__, s+1);
205 	}
206 
207 	/* Try to find a matching policy for this message */
208 	if ((pol_found = policy_test(env, &pol)) != NULL) {
209 		log_debug("%s: found policy '%s'", SPI_SA(sa, __func__),
210 		    pol_found->pol_name);
211 		sa->sa_policy = pol_found;
212 		return (0);
213 	}
214 
215 	/* No policy found */
216 	return (-1);
217 }
218 
219 /*
220  * Find a policy matching the query policy key in the global env.
221  * If multiple matching policies are found the policy with the highest
222  * priority is selected.
223  *
224  * Returns a pointer to a matching policy, or NULL if no policy matches.
225  */
226 struct iked_policy *
policy_test(struct iked * env,struct iked_policy * key)227 policy_test(struct iked *env, struct iked_policy *key)
228 {
229 	struct iked_policy	*p = NULL, *pol = NULL;
230 
231 	p = TAILQ_FIRST(&env->sc_policies);
232 	while (p != NULL) {
233 		if (p->pol_flags & IKED_POLICY_SKIP)
234 			p = p->pol_skip[IKED_SKIP_FLAGS];
235 		else if (key->pol_af && p->pol_af &&
236 		    key->pol_af != p->pol_af)
237 			p = p->pol_skip[IKED_SKIP_AF];
238 		else if (sockaddr_cmp((struct sockaddr *)&key->pol_peer.addr,
239 		    (struct sockaddr *)&p->pol_peer.addr,
240 		    p->pol_peer.addr_mask) != 0)
241 			p = p->pol_skip[IKED_SKIP_DST_ADDR];
242 		else if (sockaddr_cmp((struct sockaddr *)&key->pol_local.addr,
243 		    (struct sockaddr *)&p->pol_local.addr,
244 		    p->pol_local.addr_mask) != 0)
245 			p = p->pol_skip[IKED_SKIP_SRC_ADDR];
246 		else {
247 			/*
248 			 * Check if flows are requested and if they
249 			 * are compatible.
250 			 */
251 			if (key->pol_nflows && policy_test_flows(key, p)) {
252 				p = TAILQ_NEXT(p, pol_entry);
253 				continue;
254 			}
255 			/* make sure the peer ID matches */
256 			if (key->pol_peerid.id_type &&
257 			    p->pol_peerid.id_type &&
258 			    (key->pol_peerid.id_type != p->pol_peerid.id_type ||
259 			    memcmp(key->pol_peerid.id_data,
260 			    p->pol_peerid.id_data,
261 			    sizeof(key->pol_peerid.id_data)) != 0)) {
262 				p = TAILQ_NEXT(p, pol_entry);
263 				continue;
264 			}
265 
266 			/* make sure the local ID matches */
267 			if (key->pol_localid.id_type &&
268 			    p->pol_localid.id_type &&
269 			    (key->pol_localid.id_type != p->pol_localid.id_type ||
270 			    memcmp(key->pol_localid.id_data,
271 			    p->pol_localid.id_data,
272 			    sizeof(key->pol_localid.id_data)) != 0)) {
273 				log_info("%s: localid mismatch", __func__);
274 				p = TAILQ_NEXT(p, pol_entry);
275 				continue;
276 			}
277 
278 			/* check transport mode */
279 			if ((key->pol_flags & IKED_POLICY_TRANSPORT) &&
280 			    !(p->pol_flags & IKED_POLICY_TRANSPORT)) {
281 				p = TAILQ_NEXT(p, pol_entry);
282 				continue;
283 			}
284 
285 			/* Make sure the proposals are compatible */
286 			if (TAILQ_FIRST(&key->pol_proposals) &&
287 			    proposals_negotiate(NULL, &p->pol_proposals,
288 			    &key->pol_proposals, 0, -1) == -1) {
289 				p = TAILQ_NEXT(p, pol_entry);
290 				continue;
291 			}
292 
293 			/* Policy matched */
294 			pol = p;
295 
296 			if (pol->pol_flags & IKED_POLICY_QUICK)
297 				break;
298 
299 			/* Continue to find last matching policy */
300 			p = TAILQ_NEXT(p, pol_entry);
301 		}
302 	}
303 
304 	return (pol);
305 }
306 
307 static int
policy_test_flows(struct iked_policy * key,struct iked_policy * p)308 policy_test_flows(struct iked_policy *key, struct iked_policy *p)
309 {
310 	struct iked_flow	*f;
311 
312 	for (f = RB_MIN(iked_flows, &key->pol_flows); f != NULL;
313 	    f = RB_NEXT(iked_flows, &key->pol_flows, f))
314 		if (RB_FIND(iked_flows, &p->pol_flows, f) == NULL)
315 			return (-1);
316 
317 	return (0);
318 }
319 
320 #define	IKED_SET_SKIP_STEPS(i)						\
321 	do {								\
322 		while (head[i] != cur) {				\
323 			head[i]->pol_skip[i] = cur;			\
324 			head[i] = TAILQ_NEXT(head[i], pol_entry);	\
325 		}							\
326 	} while (0)
327 
328 /* This code is derived from pf_calc_skip_steps() from pf.c */
329 void
policy_calc_skip_steps(struct iked_policies * policies)330 policy_calc_skip_steps(struct iked_policies *policies)
331 {
332 	struct iked_policy	*head[IKED_SKIP_COUNT], *cur, *prev;
333 	int			 i;
334 
335 	cur = TAILQ_FIRST(policies);
336 	prev = cur;
337 	for (i = 0; i < IKED_SKIP_COUNT; ++i)
338 		head[i] = cur;
339 	while (cur != NULL) {
340 		if (cur->pol_flags & IKED_POLICY_SKIP)
341 			IKED_SET_SKIP_STEPS(IKED_SKIP_FLAGS);
342 		if (cur->pol_af != AF_UNSPEC &&
343 		    prev->pol_af != AF_UNSPEC &&
344 		    cur->pol_af != prev->pol_af)
345 			IKED_SET_SKIP_STEPS(IKED_SKIP_AF);
346 		if (IKED_ADDR_NEQ(&cur->pol_peer, &prev->pol_peer))
347 			IKED_SET_SKIP_STEPS(IKED_SKIP_DST_ADDR);
348 		if (IKED_ADDR_NEQ(&cur->pol_local, &prev->pol_local))
349 			IKED_SET_SKIP_STEPS(IKED_SKIP_SRC_ADDR);
350 
351 		prev = cur;
352 		cur = TAILQ_NEXT(cur, pol_entry);
353 	}
354 	for (i = 0; i < IKED_SKIP_COUNT; ++i)
355 		IKED_SET_SKIP_STEPS(i);
356 }
357 
358 void
policy_ref(struct iked * env,struct iked_policy * pol)359 policy_ref(struct iked *env, struct iked_policy *pol)
360 {
361 	if (pol->pol_flags & IKED_POLICY_REFCNT)
362 		pol->pol_refcnt++;
363 }
364 
365 void
policy_unref(struct iked * env,struct iked_policy * pol)366 policy_unref(struct iked *env, struct iked_policy *pol)
367 {
368 	if (pol == NULL || (pol->pol_flags & IKED_POLICY_REFCNT) == 0)
369 		return;
370 	if (--(pol->pol_refcnt) <= 0)
371 		config_free_policy(env, pol);
372 	else {
373 		struct iked_sa		*tmp;
374 		int			 count = 0;
375 
376 		TAILQ_FOREACH(tmp, &pol->pol_sapeers, sa_peer_entry)
377 			count++;
378 		if (count != pol->pol_refcnt)
379 			log_warnx("%s: ERROR pol %p pol_refcnt %d != count %d",
380 			    __func__, pol, pol->pol_refcnt, count);
381 	}
382 }
383 
384 void
sa_state(struct iked * env,struct iked_sa * sa,int state)385 sa_state(struct iked *env, struct iked_sa *sa, int state)
386 {
387 	const char		*a;
388 	const char		*b;
389 	int			 ostate = sa->sa_state;
390 
391 	a = print_map(ostate, ikev2_state_map);
392 	b = print_map(state, ikev2_state_map);
393 
394 	sa->sa_state = state;
395 	if (ostate != IKEV2_STATE_INIT &&
396 	    !sa_stateok(sa, state)) {
397 		log_debug("%s: cannot switch: %s -> %s",
398 		    SPI_SA(sa, __func__), a, b);
399 		sa->sa_state = ostate;
400 	} else if (ostate != sa->sa_state) {
401 		switch (state) {
402 		case IKEV2_STATE_ESTABLISHED:
403 		case IKEV2_STATE_CLOSED:
404 			log_debug("%s: %s -> %s from %s to %s policy '%s'",
405 			    SPI_SA(sa, __func__), a, b,
406 			    print_addr(&sa->sa_peer.addr),
407 			    print_addr(&sa->sa_local.addr),
408 			    sa->sa_policy ? sa->sa_policy->pol_name :
409 			    "<unknown>");
410 			break;
411 		default:
412 			log_debug("%s: %s -> %s",
413 			    SPI_SA(sa, __func__), a, b);
414 			break;
415 		}
416 	}
417 
418 	if (ostate != sa->sa_state) {
419 		switch (sa->sa_state) {
420 		case IKEV2_STATE_ESTABLISHED:
421 			ikestat_inc(env, ikes_sa_established_total);
422 			ikestat_inc(env, ikes_sa_established_current);
423 			break;
424 		case IKEV2_STATE_CLOSED:
425 		case IKEV2_STATE_CLOSING:
426 			switch (ostate) {
427 			case IKEV2_STATE_ESTABLISHED:
428 				ikestat_dec(env, ikes_sa_established_current);
429 				break;
430 			case IKEV2_STATE_CLOSED:
431 			case IKEV2_STATE_CLOSING:
432 				break;
433 			default:
434 				ikestat_inc(env, ikes_sa_established_failures);
435 				break;
436 			}
437 			break;
438 		}
439 	}
440 }
441 
442 void
sa_stateflags(struct iked_sa * sa,unsigned int flags)443 sa_stateflags(struct iked_sa *sa, unsigned int flags)
444 {
445 	unsigned int	require;
446 
447 	if (sa->sa_state > IKEV2_STATE_SA_INIT)
448 		require = sa->sa_statevalid;
449 	else
450 		require = sa->sa_stateinit;
451 
452 	log_debug("%s: 0x%04x -> 0x%04x %s (required 0x%04x %s)", __func__,
453 	    sa->sa_stateflags, sa->sa_stateflags | flags,
454 	    print_bits(sa->sa_stateflags | flags, IKED_REQ_BITS), require,
455 	    print_bits(require, IKED_REQ_BITS));
456 
457 	sa->sa_stateflags |= flags;
458 }
459 
460 int
sa_stateok(const struct iked_sa * sa,int state)461 sa_stateok(const struct iked_sa *sa, int state)
462 {
463 	unsigned int	 require;
464 
465 	if (sa->sa_state < state)
466 		return (0);
467 
468 	if (state == IKEV2_STATE_SA_INIT)
469 		require = sa->sa_stateinit;
470 	else
471 		require = sa->sa_statevalid;
472 
473 	if (state == IKEV2_STATE_SA_INIT ||
474 	    state == IKEV2_STATE_VALID ||
475 	    state == IKEV2_STATE_EAP_VALID) {
476 		log_debug("%s: %s flags 0x%04x, require 0x%04x %s", __func__,
477 		    print_map(state, ikev2_state_map),
478 		    (sa->sa_stateflags & require), require,
479 		    print_bits(require, IKED_REQ_BITS));
480 
481 		if ((sa->sa_stateflags & require) != require)
482 			return (0);	/* not ready, ignore */
483 	}
484 	return (1);
485 }
486 
487 struct iked_sa *
sa_new(struct iked * env,uint64_t ispi,uint64_t rspi,unsigned int initiator,struct iked_policy * pol)488 sa_new(struct iked *env, uint64_t ispi, uint64_t rspi,
489     unsigned int initiator, struct iked_policy *pol)
490 {
491 	struct iked_sa	*sa;
492 	struct iked_sa	*old;
493 	struct iked_id	*localid;
494 	unsigned int	 diff;
495 
496 	if ((ispi == 0 && rspi == 0) ||
497 	    (sa = sa_lookup(env, ispi, rspi, initiator)) == NULL) {
498 		/* Create new SA */
499 		if (!initiator && ispi == 0) {
500 			log_debug("%s: cannot create responder IKE SA w/o ispi",
501 			    __func__);
502 			return (NULL);
503 		}
504 		sa = config_new_sa(env, initiator);
505 		if (sa == NULL) {
506 			log_debug("%s: failed to allocate IKE SA", __func__);
507 			return (NULL);
508 		}
509 		if (!initiator)
510 			sa->sa_hdr.sh_ispi = ispi;
511 		old = RB_INSERT(iked_sas, &env->sc_sas, sa);
512 		if (old && old != sa) {
513 			log_warnx("%s: duplicate IKE SA", __func__);
514 			config_free_sa(env, sa);
515 			return (NULL);
516 		}
517 	}
518 	/* Update rspi in the initator case */
519 	if (initiator && sa->sa_hdr.sh_rspi == 0 && rspi)
520 		sa->sa_hdr.sh_rspi = rspi;
521 
522 	if (pol == NULL && sa->sa_policy == NULL)
523 		fatalx("%s: sa %p no policy", __func__, sa);
524 	else if (sa->sa_policy == NULL) {
525 		policy_ref(env, pol);
526 		sa->sa_policy = pol;
527 		TAILQ_INSERT_TAIL(&pol->pol_sapeers, sa, sa_peer_entry);
528 	} else
529 		pol = sa->sa_policy;
530 
531 	sa->sa_statevalid = IKED_REQ_AUTH|IKED_REQ_AUTHVALID|IKED_REQ_SA;
532 	if (pol != NULL && pol->pol_auth.auth_eap) {
533 		sa->sa_statevalid |= IKED_REQ_CERT|IKED_REQ_EAPVALID;
534 	} else if (pol != NULL && pol->pol_auth.auth_method !=
535 	    IKEV2_AUTH_SHARED_KEY_MIC) {
536 		sa->sa_statevalid |= IKED_REQ_CERTVALID|IKED_REQ_CERT;
537 	}
538 
539 	if (initiator) {
540 		localid = &sa->sa_iid;
541 		diff = IKED_REQ_CERTVALID|IKED_REQ_AUTHVALID|IKED_REQ_SA|
542 		    IKED_REQ_EAPVALID;
543 		sa->sa_stateinit = sa->sa_statevalid & ~diff;
544 		sa->sa_statevalid = sa->sa_statevalid & diff;
545 	} else
546 		localid = &sa->sa_rid;
547 
548 	if (pol != NULL &&
549 	    ikev2_policy2id(&pol->pol_localid, localid, 1) != 0) {
550 		log_debug("%s: failed to get local id", __func__);
551 		ikev2_ike_sa_setreason(sa, "failed to get local id");
552 		sa_free(env, sa);
553 		return (NULL);
554 	}
555 
556 	return (sa);
557 }
558 
559 int
policy_generate_ts(struct iked_policy * pol)560 policy_generate_ts(struct iked_policy *pol)
561 {
562 	struct iked_flow	*flow;
563 
564 	/* Generate list of traffic selectors from flows */
565 	RB_FOREACH(flow, iked_flows, &pol->pol_flows) {
566 		if (ts_insert_unique(&flow->flow_src, &pol->pol_tssrc,
567 		    flow->flow_ipproto) == 1)
568 			pol->pol_tssrc_count++;
569 		if (ts_insert_unique(&flow->flow_dst, &pol->pol_tsdst,
570 		    flow->flow_ipproto) == 1)
571 			pol->pol_tsdst_count++;
572 	}
573 	if (pol->pol_tssrc_count > IKEV2_MAXNUM_TSS ||
574 	    pol->pol_tsdst_count > IKEV2_MAXNUM_TSS)
575 		return (-1);
576 
577 	return (0);
578 }
579 
580 int
ts_insert_unique(struct iked_addr * addr,struct iked_tss * tss,int ipproto)581 ts_insert_unique(struct iked_addr *addr, struct iked_tss *tss, int ipproto)
582 {
583 	struct iked_ts		*ts;
584 
585 	/* Remove duplicates */
586 	TAILQ_FOREACH(ts, tss, ts_entry) {
587 		if (addr_cmp(addr, &ts->ts_addr, 1) == 0)
588 			return (0);
589 	}
590 
591 	if ((ts = calloc(1, sizeof(*ts))) == NULL)
592 		return (-1);
593 
594 	ts->ts_ipproto = ipproto;
595 	ts->ts_addr = *addr;
596 
597 	TAILQ_INSERT_TAIL(tss, ts, ts_entry);
598 	return (1);
599 }
600 
601 void
sa_free(struct iked * env,struct iked_sa * sa)602 sa_free(struct iked *env, struct iked_sa *sa)
603 {
604 	struct iked_sa	*osa;
605 
606 	if (sa->sa_reason)
607 		log_info("%s: %s", SPI_SA(sa, __func__), sa->sa_reason);
608 	else
609 		log_debug("%s: ispi %s rspi %s", SPI_SA(sa, __func__),
610 		    print_spi(sa->sa_hdr.sh_ispi, 8),
611 		    print_spi(sa->sa_hdr.sh_rspi, 8));
612 
613 	/* IKE rekeying running? (old sa freed before new sa) */
614 	if (sa->sa_nexti) {
615 		RB_REMOVE(iked_sas, &env->sc_sas, sa->sa_nexti);
616 		if (sa->sa_nexti->sa_dstid_entry_valid) {
617 			log_info("%s: nexti established? %s",
618 			    SPI_SA(sa, __func__), SPI_SA(sa->sa_nexti, NULL));
619 			sa_dstid_remove(env, sa->sa_nexti);
620 		}
621 		config_free_sa(env, sa->sa_nexti);
622 	}
623 	if (sa->sa_nextr) {
624 		RB_REMOVE(iked_sas, &env->sc_sas, sa->sa_nextr);
625 		if (sa->sa_nextr->sa_dstid_entry_valid) {
626 			log_info("%s: nextr established? %s",
627 			    SPI_SA(sa, __func__), SPI_SA(sa->sa_nextr, NULL));
628 			sa_dstid_remove(env, sa->sa_nextr);
629 		}
630 		config_free_sa(env, sa->sa_nextr);
631 	}
632 	/* reset matching backpointers (new sa freed before old sa) */
633 	if ((osa = sa->sa_previ) != NULL) {
634 		if (osa->sa_nexti == sa) {
635 			log_debug("%s: resetting: sa %p == osa->sa_nexti %p"
636 			    " (osa %p)",
637 			    SPI_SA(sa, __func__), osa, sa, osa->sa_nexti);
638 			osa->sa_nexti = NULL;
639 		} else {
640 			log_info("%s: inconsistent: sa %p != osa->sa_nexti %p"
641 			    " (osa %p)",
642 			    SPI_SA(sa, __func__), osa, sa, osa->sa_nexti);
643 		}
644 	}
645 	if ((osa = sa->sa_prevr) != NULL) {
646 		if (osa->sa_nextr == sa) {
647 			log_debug("%s: resetting: sa %p == osa->sa_nextr %p"
648 			    " (osa %p)",
649 			    SPI_SA(sa, __func__), osa, sa, osa->sa_nextr);
650 			osa->sa_nextr = NULL;
651 		} else {
652 			log_info("%s: inconsistent: sa %p != osa->sa_nextr %p"
653 			    " (osa %p)",
654 			    SPI_SA(sa, __func__), osa, sa, osa->sa_nextr);
655 		}
656 	}
657 	RB_REMOVE(iked_sas, &env->sc_sas, sa);
658 	if (sa->sa_dstid_entry_valid)
659 		sa_dstid_remove(env, sa);
660 	config_free_sa(env, sa);
661 }
662 
663 void
sa_free_flows(struct iked * env,struct iked_saflows * head)664 sa_free_flows(struct iked *env, struct iked_saflows *head)
665 {
666 	struct iked_flow	*flow, *flowtmp;
667 
668 	TAILQ_FOREACH_SAFE(flow, head, flow_entry, flowtmp) {
669 		log_debug("%s: free %p", __func__, flow);
670 
671 		if (flow->flow_loaded)
672 			RB_REMOVE(iked_flows, &env->sc_activeflows, flow);
673 		TAILQ_REMOVE(head, flow, flow_entry);
674 		(void)pfkey_flow_delete(env, flow);
675 		flow_free(flow);
676 	}
677 }
678 
679 
680 int
sa_address(struct iked_sa * sa,struct iked_addr * addr,struct sockaddr * peer)681 sa_address(struct iked_sa *sa, struct iked_addr *addr, struct sockaddr *peer)
682 {
683 	bzero(addr, sizeof(*addr));
684 	addr->addr_af = peer->sa_family;
685 	addr->addr_port = htons(socket_getport(peer));
686 	memcpy(&addr->addr, peer, peer->sa_len);
687 	if (socket_af((struct sockaddr *)&addr->addr, addr->addr_port) == -1) {
688 		log_debug("%s: invalid address", __func__);
689 		return (-1);
690 	}
691 	return (0);
692 }
693 
694 int
sa_configure_iface(struct iked * env,struct iked_sa * sa,int add)695 sa_configure_iface(struct iked *env, struct iked_sa *sa, int add)
696 {
697 	struct iked_flow	*saflow;
698 	struct sockaddr		*caddr;
699 	int			 rdomain;
700 
701 	if (sa->sa_policy == NULL || sa->sa_policy->pol_iface == 0)
702 		return (0);
703 
704 	if (sa->sa_cp_dns) {
705 		if (vroute_setdns(env, add,
706 		    (struct sockaddr *)&sa->sa_cp_dns->addr,
707 		    sa->sa_policy->pol_iface) != 0)
708 			return (-1);
709 	}
710 
711 	if (!sa->sa_cp_addr && !sa->sa_cp_addr6)
712 		return (0);
713 
714 	if (sa->sa_cp_addr) {
715 		if (vroute_setaddr(env, add,
716 		    (struct sockaddr *)&sa->sa_cp_addr->addr,
717 		    sa->sa_cp_addr->addr_mask, sa->sa_policy->pol_iface) != 0)
718 			return (-1);
719 	}
720 	if (sa->sa_cp_addr6) {
721 		if (vroute_setaddr(env, add,
722 		    (struct sockaddr *)&sa->sa_cp_addr6->addr,
723 		    sa->sa_cp_addr6->addr_mask, sa->sa_policy->pol_iface) != 0)
724 			return (-1);
725 	}
726 
727 	if (add) {
728 		/* Add direct route to peer */
729 		if (vroute_setcloneroute(env, getrtable(),
730 		    (struct sockaddr *)&sa->sa_peer.addr, 0, NULL))
731 			return (-1);
732 	} else {
733 		if (vroute_setdelroute(env, getrtable(),
734 		    (struct sockaddr *)&sa->sa_peer.addr,
735 		    0, NULL))
736 			return (-1);
737 	}
738 
739 	TAILQ_FOREACH(saflow, &sa->sa_flows, flow_entry) {
740 		rdomain = saflow->flow_rdomain == -1 ?
741 		    getrtable() : saflow->flow_rdomain;
742 
743 		switch(saflow->flow_src.addr_af) {
744 		case AF_INET:
745 			if (sa->sa_cp_addr == NULL)
746 				continue;
747 			caddr = (struct sockaddr *)&sa->sa_cp_addr->addr;
748 			break;
749 		case AF_INET6:
750 			if (sa->sa_cp_addr6 == NULL)
751 				continue;
752 			caddr = (struct sockaddr *)&sa->sa_cp_addr6->addr;
753 			break;
754 		default:
755 			return (-1);
756 		}
757 		if (sockaddr_cmp((struct sockaddr *)&saflow->flow_src.addr,
758 		    caddr, -1) != 0)
759 			continue;
760 
761 		if (add) {
762 			if (vroute_setaddroute(env, rdomain,
763 			    (struct sockaddr *)&saflow->flow_dst.addr,
764 			    saflow->flow_dst.addr_mask, caddr))
765 				return (-1);
766 		} else {
767 			if (vroute_setdelroute(env, rdomain,
768 			    (struct sockaddr *)&saflow->flow_dst.addr,
769 			    saflow->flow_dst.addr_mask, caddr))
770 				return (-1);
771 		}
772 	}
773 
774 	return (0);
775 }
776 
777 void
childsa_free(struct iked_childsa * csa)778 childsa_free(struct iked_childsa *csa)
779 {
780 	struct iked_childsa *csb;
781 
782 	if (csa == NULL)
783 		return;
784 
785 	if (csa->csa_loaded)
786 		log_info("%s: CHILD SA spi %s is still loaded",
787 		    csa->csa_ikesa ? SPI_SA(csa->csa_ikesa, __func__) :
788 		    __func__,
789 		    print_spi(csa->csa_spi.spi, csa->csa_spi.spi_size));
790 	if ((csb = csa->csa_bundled) != NULL)
791 		csb->csa_bundled = NULL;
792 	if ((csb = csa->csa_peersa) != NULL)
793 		csb->csa_peersa = NULL;
794 	ibuf_free(csa->csa_encrkey);
795 	ibuf_free(csa->csa_integrkey);
796 	free(csa);
797 }
798 
799 struct iked_childsa *
childsa_lookup(struct iked_sa * sa,uint64_t spi,uint8_t protoid)800 childsa_lookup(struct iked_sa *sa, uint64_t spi, uint8_t protoid)
801 {
802 	struct iked_childsa	*csa;
803 
804 	if (sa == NULL || spi == 0 || protoid == 0)
805 		return (NULL);
806 
807 	TAILQ_FOREACH(csa, &sa->sa_childsas, csa_entry) {
808 		if (csa->csa_spi.spi_protoid == protoid &&
809 		    (csa->csa_spi.spi == spi))
810 			break;
811 	}
812 	return (csa);
813 }
814 
815 void
flow_free(struct iked_flow * flow)816 flow_free(struct iked_flow *flow)
817 {
818 	free(flow);
819 }
820 
821 struct iked_sa *
sa_lookup(struct iked * env,uint64_t ispi,uint64_t rspi,unsigned int initiator)822 sa_lookup(struct iked *env, uint64_t ispi, uint64_t rspi,
823     unsigned int initiator)
824 {
825 	struct iked_sa	*sa, key;
826 
827 	key.sa_hdr.sh_ispi = ispi;
828 	key.sa_hdr.sh_initiator = initiator;
829 
830 	if ((sa = RB_FIND(iked_sas, &env->sc_sas, &key)) != NULL) {
831 		gettimeofday(&sa->sa_timeused, NULL);
832 
833 		/* Validate if SPIr matches */
834 		if ((sa->sa_hdr.sh_rspi != 0) &&
835 		    (rspi != 0) &&
836 		    (sa->sa_hdr.sh_rspi != rspi))
837 			return (NULL);
838 	}
839 
840 	return (sa);
841 }
842 
843 static __inline int
sa_cmp(struct iked_sa * a,struct iked_sa * b)844 sa_cmp(struct iked_sa *a, struct iked_sa *b)
845 {
846 	if (a->sa_hdr.sh_initiator > b->sa_hdr.sh_initiator)
847 		return (-1);
848 	if (a->sa_hdr.sh_initiator < b->sa_hdr.sh_initiator)
849 		return (1);
850 
851 	if (a->sa_hdr.sh_ispi > b->sa_hdr.sh_ispi)
852 		return (-1);
853 	if (a->sa_hdr.sh_ispi < b->sa_hdr.sh_ispi)
854 		return (1);
855 
856 	return (0);
857 }
858 
859 static struct iked_id *
sa_dstid_checked(struct iked_sa * sa)860 sa_dstid_checked(struct iked_sa *sa)
861 {
862 	struct iked_id *id;
863 
864 	id = IKESA_DSTID(sa);
865 	if (id == NULL || id->id_buf == NULL ||
866 	    ibuf_data(id->id_buf) == NULL)
867 		return (NULL);
868 	if (ibuf_size(id->id_buf) <= id->id_offset)
869 		return (NULL);
870 	return (id);
871 }
872 
873 struct iked_sa *
sa_dstid_lookup(struct iked * env,struct iked_sa * key)874 sa_dstid_lookup(struct iked *env, struct iked_sa *key)
875 {
876 	struct iked_sa *sa;
877 
878 	if (sa_dstid_checked(key) == NULL)
879 		fatalx("%s: no id for key %p", __func__, key);
880 	sa = RB_FIND(iked_dstid_sas, &env->sc_dstid_sas, key);
881 	if (sa != NULL && !sa->sa_dstid_entry_valid)
882 		fatalx("%s: sa %p not estab (key %p)", __func__, sa, key);
883 	return (sa);
884 }
885 
886 struct iked_sa *
sa_dstid_insert(struct iked * env,struct iked_sa * sa)887 sa_dstid_insert(struct iked *env, struct iked_sa *sa)
888 {
889 	struct iked_sa *osa;
890 
891 	if (sa->sa_dstid_entry_valid)
892 		fatalx("%s: sa %p is estab", __func__, sa);
893 	if (sa_dstid_checked(sa) == NULL)
894 		fatalx("%s: no id for sa %p", __func__, sa);
895 	osa = RB_FIND(iked_dstid_sas, &env->sc_dstid_sas, sa);
896 	if (osa == NULL) {
897 		osa = RB_INSERT(iked_dstid_sas, &env->sc_dstid_sas, sa);
898 		if (osa && osa != sa) {
899 			log_warnx("%s: duplicate IKE SA", SPI_SA(sa, __func__));
900 			return (osa);
901 		}
902 		sa->sa_dstid_entry_valid = 1;
903 		return (NULL);
904 	}
905 	if (!osa->sa_dstid_entry_valid)
906 		fatalx("%s: osa %p not estab (sa %p)", __func__, osa, sa);
907 	return (osa);
908 }
909 
910 void
sa_dstid_remove(struct iked * env,struct iked_sa * sa)911 sa_dstid_remove(struct iked *env, struct iked_sa *sa)
912 {
913 	if (!sa->sa_dstid_entry_valid)
914 		fatalx("%s: sa %p is not estab", __func__, sa);
915 	if (sa_dstid_checked(sa) == NULL)
916 		fatalx("%s: no id for sa %p", __func__, sa);
917 	RB_REMOVE(iked_dstid_sas, &env->sc_dstid_sas, sa);
918 	sa->sa_dstid_entry_valid = 0;
919 }
920 
921 static __inline int
sa_dstid_cmp(struct iked_sa * a,struct iked_sa * b)922 sa_dstid_cmp(struct iked_sa *a, struct iked_sa *b)
923 {
924 	struct iked_id		*aid = NULL, *bid = NULL;
925 	size_t			 alen, blen;
926 	uint8_t			*aptr, *bptr;
927 
928 	aid = sa_dstid_checked(a);
929 	bid = sa_dstid_checked(b);
930 	if (aid == NULL || bid == NULL)
931 		fatalx("corrupt IDs");
932 	if (aid->id_type > bid->id_type)
933 		return (-1);
934 	else if (aid->id_type < bid->id_type)
935 		return (1);
936 	alen = ibuf_size(aid->id_buf);
937 	blen = ibuf_size(bid->id_buf);
938 	aptr = ibuf_data(aid->id_buf);
939 	bptr = ibuf_data(bid->id_buf);
940 	if (aptr == NULL || bptr == NULL)
941 		fatalx("corrupt ID bufs");
942 	if (alen <= aid->id_offset || blen <= bid->id_offset)
943 		fatalx("corrupt ID lens");
944 	aptr += aid->id_offset;
945 	alen -= aid->id_offset;
946 	bptr += bid->id_offset;
947 	blen -= bid->id_offset;
948 	if (alen > blen)
949 		return (-1);
950 	if (alen < blen)
951 		return (1);
952 	return (memcmp(aptr, bptr, alen));
953 }
954 
955 static __inline int
sa_addrpool_cmp(struct iked_sa * a,struct iked_sa * b)956 sa_addrpool_cmp(struct iked_sa *a, struct iked_sa *b)
957 {
958 	return (sockaddr_cmp((struct sockaddr *)&a->sa_addrpool->addr,
959 	    (struct sockaddr *)&b->sa_addrpool->addr, -1));
960 }
961 
962 static __inline int
sa_addrpool6_cmp(struct iked_sa * a,struct iked_sa * b)963 sa_addrpool6_cmp(struct iked_sa *a, struct iked_sa *b)
964 {
965 	return (sockaddr_cmp((struct sockaddr *)&a->sa_addrpool6->addr,
966 	    (struct sockaddr *)&b->sa_addrpool6->addr, -1));
967 }
968 
969 struct iked_user *
user_lookup(struct iked * env,const char * user)970 user_lookup(struct iked *env, const char *user)
971 {
972 	struct iked_user	 key;
973 
974 	if (strlcpy(key.usr_name, user,
975 	    sizeof(key.usr_name)) >= sizeof(key.usr_name))
976 		return (NULL);
977 
978 	return (RB_FIND(iked_users, &env->sc_users, &key));
979 }
980 
981 static __inline int
user_cmp(struct iked_user * a,struct iked_user * b)982 user_cmp(struct iked_user *a, struct iked_user *b)
983 {
984 	return (strcmp(a->usr_name, b->usr_name));
985 }
986 
987 /*
988  * Find a matching subset of the proposal lists 'local' and 'peer'.
989  * The resulting proposal is stored in 'result' if 'result' is not NULL.
990  * The 'rekey' parameter indicates a CREATE_CHILD_SA exchange where
991  * an extra group is necessary for PFS. For the initial IKE_AUTH exchange
992  * the ESP SA proposal never includes an explicit DH group.
993  *
994  * Return 0 if a matching subset was found and -1 if no subset was found
995  * or an error occured.
996  */
997 int
proposals_negotiate(struct iked_proposals * result,struct iked_proposals * local,struct iked_proposals * peer,int rekey,int groupid)998 proposals_negotiate(struct iked_proposals *result, struct iked_proposals *local,
999     struct iked_proposals *peer, int rekey, int groupid)
1000 {
1001 	struct iked_proposal	*ppeer = NULL, *plocal, *prop, vpeer, vlocal;
1002 	struct iked_transform	 chosen[IKEV2_XFORMTYPE_MAX];
1003 	struct iked_transform	*valid[IKEV2_XFORMTYPE_MAX];
1004 	struct iked_transform	*match[IKEV2_XFORMTYPE_MAX];
1005 	unsigned int		 i, score, chosen_score = 0;
1006 	uint8_t			 protoid = 0;
1007 
1008 	bzero(valid, sizeof(valid));
1009 	bzero(&vlocal, sizeof(vlocal));
1010 	bzero(&vpeer, sizeof(vpeer));
1011 
1012 	if (TAILQ_EMPTY(peer)) {
1013 		log_debug("%s: peer did not send %s proposals", __func__,
1014 		    print_map(protoid, ikev2_saproto_map));
1015 		return (-1);
1016 	}
1017 
1018 	TAILQ_FOREACH(plocal, local, prop_entry) {
1019 		TAILQ_FOREACH(ppeer, peer, prop_entry) {
1020 			if (ppeer->prop_protoid != plocal->prop_protoid)
1021 				continue;
1022 			bzero(match, sizeof(match));
1023 			score = proposals_match(plocal, ppeer, match,
1024 			    rekey, groupid);
1025 			log_debug("%s: score %d", __func__, score);
1026 			if (score && (!chosen_score || score < chosen_score)) {
1027 				chosen_score = score;
1028 				for (i = 0; i < IKEV2_XFORMTYPE_MAX; i++) {
1029 					if ((valid[i] = match[i]))
1030 						memcpy(&chosen[i], match[i],
1031 						    sizeof(chosen[0]));
1032 				}
1033 				memcpy(&vpeer, ppeer, sizeof(vpeer));
1034 				memcpy(&vlocal, plocal, sizeof(vlocal));
1035 			}
1036 		}
1037 		if (chosen_score != 0)
1038 			break;
1039 	}
1040 
1041 	if (chosen_score == 0)
1042 		return (-1);
1043 	else if (result == NULL)
1044 		return (0);
1045 
1046 	(void)config_free_proposals(result, vpeer.prop_protoid);
1047 	prop = config_add_proposal(result, vpeer.prop_id, vpeer.prop_protoid);
1048 
1049 	if (vpeer.prop_localspi.spi_size) {
1050 		prop->prop_localspi.spi_size = vpeer.prop_localspi.spi_size;
1051 		prop->prop_peerspi = vpeer.prop_peerspi;
1052 	}
1053 	if (vlocal.prop_localspi.spi_size) {
1054 		prop->prop_localspi.spi_size = vlocal.prop_localspi.spi_size;
1055 		prop->prop_localspi.spi = vlocal.prop_localspi.spi;
1056 	}
1057 
1058 	for (i = 0; i < IKEV2_XFORMTYPE_MAX; i++) {
1059 		if (valid[i] == NULL)
1060 			continue;
1061 		print_debug("%s: score %d: %s %s", __func__,
1062 		    chosen[i].xform_score, print_map(i, ikev2_xformtype_map),
1063 		    print_map(chosen[i].xform_id, chosen[i].xform_map));
1064 		if (chosen[i].xform_length)
1065 			print_debug(" %d", chosen[i].xform_length);
1066 		print_debug("\n");
1067 
1068 		if (config_add_transform(prop, chosen[i].xform_type,
1069 		    chosen[i].xform_id, chosen[i].xform_length,
1070 		    chosen[i].xform_keylength) != 0)
1071 			break;
1072 	}
1073 
1074 	return (0);
1075 }
1076 
1077 static int
proposals_match(struct iked_proposal * local,struct iked_proposal * peer,struct iked_transform ** xforms,int rekey,int dhgroup)1078 proposals_match(struct iked_proposal *local, struct iked_proposal *peer,
1079     struct iked_transform **xforms, int rekey, int dhgroup)
1080 {
1081 	struct iked_transform	*tpeer, *tlocal;
1082 	unsigned int		 i, j, type, score, requiredh = 0, nodh = 0, noauth = 0;
1083 	unsigned int		 dhforced = 0;
1084 	uint8_t			 protoid = peer->prop_protoid;
1085 	uint8_t			 peerxfs[IKEV2_XFORMTYPE_MAX];
1086 
1087 	bzero(peerxfs, sizeof(peerxfs));
1088 
1089 	for (i = 0; i < peer->prop_nxforms; i++) {
1090 		tpeer = peer->prop_xforms + i;
1091 		/* If any of the ENC transforms is an AEAD, ignore auth */
1092 		if (tpeer->xform_type == IKEV2_XFORMTYPE_ENCR &&
1093 		    encxf_noauth(tpeer->xform_id))
1094 			noauth = 1;
1095 	}
1096 
1097 	for (i = 0; i < peer->prop_nxforms; i++) {
1098 		tpeer = peer->prop_xforms + i;
1099 		if (tpeer->xform_type >= IKEV2_XFORMTYPE_MAX)
1100 			continue;
1101 		if (noauth && tpeer->xform_type == IKEV2_XFORMTYPE_INTEGR)
1102 			return (0);
1103 
1104 		/*
1105 		 * Record all transform types from the peer's proposal,
1106 		 * because if we want this proposal we have to select
1107 		 * a transform for each proposed transform type.
1108 		 */
1109 		peerxfs[tpeer->xform_type] = 1;
1110 
1111 		for (j = 0; j < local->prop_nxforms; j++) {
1112 			tlocal = local->prop_xforms + j;
1113 
1114 			/*
1115 			 * We require a DH group for ESP if there is any
1116 			 * local proposal with DH enabled.
1117 			 */
1118 			if (rekey && requiredh == 0 &&
1119 			    protoid == IKEV2_SAPROTO_ESP &&
1120 			    tlocal->xform_type == IKEV2_XFORMTYPE_DH &&
1121 			    tlocal->xform_id != IKEV2_XFORMDH_NONE)
1122 				requiredh = 1;
1123 
1124 			/*
1125 			 * If none is an explicit option, don't require
1126 			 * DH group. Overrides requiredh = 1.
1127 			 */
1128 			if (rekey && nodh == 0 &&
1129 			    protoid == IKEV2_SAPROTO_ESP &&
1130 			    tlocal->xform_type == IKEV2_XFORMTYPE_DH &&
1131 			    tlocal->xform_id == IKEV2_XFORMDH_NONE)
1132 				nodh = 1;
1133 
1134 			/* Compare peer and local proposals */
1135 			if (tpeer->xform_type != tlocal->xform_type ||
1136 			    tpeer->xform_id != tlocal->xform_id ||
1137 			    tpeer->xform_length != tlocal->xform_length)
1138 				continue;
1139 			type = tpeer->xform_type;
1140 
1141 			if (nodh == 0 && dhgroup >= 0 &&
1142 			    type == IKEV2_XFORMTYPE_DH) {
1143 				if (dhforced)
1144 					continue;
1145 				/* reset xform, so this xform w/matching group is enforced */
1146 				if (tlocal->xform_id == dhgroup) {
1147 					xforms[type] = NULL;
1148 					dhforced = 1;
1149 				}
1150 			}
1151 
1152 			if (xforms[type] == NULL || tlocal->xform_score <
1153 			    xforms[type]->xform_score) {
1154 				xforms[type] = tlocal;
1155 			} else
1156 				continue;
1157 
1158 			print_debug("%s: xform %d <-> %d (%d): %s %s "
1159 			    "(keylength %d <-> %d)", __func__,
1160 			    peer->prop_id, local->prop_id, tlocal->xform_score,
1161 			    print_map(type, ikev2_xformtype_map),
1162 			    print_map(tpeer->xform_id, tpeer->xform_map),
1163 			    tpeer->xform_keylength, tlocal->xform_keylength);
1164 			if (tpeer->xform_length)
1165 				print_debug(" %d", tpeer->xform_length);
1166 			print_debug("\n");
1167 		}
1168 	}
1169 
1170 	for (i = score = 0; i < IKEV2_XFORMTYPE_MAX; i++) {
1171 		if (protoid == IKEV2_SAPROTO_IKE && xforms[i] == NULL &&
1172 		    (i == IKEV2_XFORMTYPE_ENCR || i == IKEV2_XFORMTYPE_PRF ||
1173 		    (!noauth && i == IKEV2_XFORMTYPE_INTEGR) ||
1174 		    i == IKEV2_XFORMTYPE_DH)) {
1175 			score = 0;
1176 			break;
1177 		} else if (protoid == IKEV2_SAPROTO_AH && xforms[i] == NULL &&
1178 		    (i == IKEV2_XFORMTYPE_INTEGR || i == IKEV2_XFORMTYPE_ESN)) {
1179 			score = 0;
1180 			break;
1181 		} else if (protoid == IKEV2_SAPROTO_ESP && xforms[i] == NULL &&
1182 		    (i == IKEV2_XFORMTYPE_ENCR || i == IKEV2_XFORMTYPE_ESN ||
1183 		    (requiredh && !nodh && i == IKEV2_XFORMTYPE_DH))) {
1184 			score = 0;
1185 			break;
1186 		} else if (peerxfs[i] && xforms[i] == NULL) {
1187 			score = 0;
1188 			break;
1189 		} else if (xforms[i] == NULL)
1190 			continue;
1191 
1192 		score += xforms[i]->xform_score;
1193 	}
1194 
1195 	return (score);
1196 }
1197 
1198 static __inline int
childsa_cmp(struct iked_childsa * a,struct iked_childsa * b)1199 childsa_cmp(struct iked_childsa *a, struct iked_childsa *b)
1200 {
1201 	if (a->csa_spi.spi > b->csa_spi.spi)
1202 		return (1);
1203 	if (a->csa_spi.spi < b->csa_spi.spi)
1204 		return (-1);
1205 	return (0);
1206 }
1207 
1208 static __inline int
addr_cmp(struct iked_addr * a,struct iked_addr * b,int useports)1209 addr_cmp(struct iked_addr *a, struct iked_addr *b, int useports)
1210 {
1211 	int		diff = 0;
1212 
1213 	diff = sockaddr_cmp((struct sockaddr *)&a->addr,
1214 	    (struct sockaddr *)&b->addr, 128);
1215 	if (!diff)
1216 		diff = (int)a->addr_mask - (int)b->addr_mask;
1217 	if (!diff && useports)
1218 		diff = a->addr_port - b->addr_port;
1219 
1220 	return (diff);
1221 }
1222 
1223 static __inline int
flow_cmp(struct iked_flow * a,struct iked_flow * b)1224 flow_cmp(struct iked_flow *a, struct iked_flow *b)
1225 {
1226 	int		diff = 0;
1227 
1228 	if (!diff)
1229 		diff = a->flow_rdomain - b->flow_rdomain;
1230 	if (!diff)
1231 		diff = (int)a->flow_ipproto - (int)b->flow_ipproto;
1232 	if (!diff)
1233 		diff = (int)a->flow_saproto - (int)b->flow_saproto;
1234 	if (!diff)
1235 		diff = (int)a->flow_dir - (int)b->flow_dir;
1236 	if (!diff)
1237 		diff = addr_cmp(&a->flow_dst, &b->flow_dst, 1);
1238 	if (!diff)
1239 		diff = addr_cmp(&a->flow_src, &b->flow_src, 1);
1240 	if (!diff)
1241 		diff = addr_cmp(&a->flow_prenat, &b->flow_prenat, 0);
1242 
1243 	return (diff);
1244 }
1245 
1246 int
flow_equal(struct iked_flow * a,struct iked_flow * b)1247 flow_equal(struct iked_flow *a, struct iked_flow *b)
1248 {
1249 	return (flow_cmp(a, b) == 0);
1250 }
1251 
1252 RB_GENERATE(iked_sas, iked_sa, sa_entry, sa_cmp);
1253 RB_GENERATE(iked_dstid_sas, iked_sa, sa_dstid_entry, sa_dstid_cmp);
1254 RB_GENERATE(iked_addrpool, iked_sa, sa_addrpool_entry, sa_addrpool_cmp);
1255 RB_GENERATE(iked_addrpool6, iked_sa, sa_addrpool6_entry, sa_addrpool6_cmp);
1256 RB_GENERATE(iked_users, iked_user, usr_entry, user_cmp);
1257 RB_GENERATE(iked_activesas, iked_childsa, csa_node, childsa_cmp);
1258 RB_GENERATE(iked_flows, iked_flow, flow_node, flow_cmp);
1259