xref: /openbsd-src/sbin/iked/policy.c (revision 4c1e55dc91edd6e69ccc60ce855900fbc12cf34f)
1 /*	$OpenBSD: policy.c,v 1.20 2012/05/30 09:39:35 mikeb Exp $	*/
2 /*	$vantronix: policy.c,v 1.29 2010/05/28 15:34:35 reyk Exp $	*/
3 
4 /*
5  * Copyright (c) 2010, 2011 Reyk Floeter <reyk@vantronix.net>
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/param.h>
22 #include <sys/queue.h>
23 #include <sys/socket.h>
24 #include <sys/uio.h>
25 #include <sys/tree.h>
26 
27 #include <net/if.h>
28 #include <netinet/in_systm.h>
29 #include <netinet/in.h>
30 #include <netinet/ip.h>
31 #include <netinet/tcp.h>
32 #include <arpa/inet.h>
33 
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <unistd.h>
37 #include <string.h>
38 #include <errno.h>
39 #include <fcntl.h>
40 #include <event.h>
41 
42 #include "iked.h"
43 #include "ikev2.h"
44 
45 static __inline int
46 	 sa_cmp(struct iked_sa *, struct iked_sa *);
47 static __inline int
48 	 user_cmp(struct iked_user *, struct iked_user *);
49 static __inline int
50 	 childsa_cmp(struct iked_childsa *, struct iked_childsa *);
51 static __inline int
52 	 flow_cmp(struct iked_flow *, struct iked_flow *);
53 
54 
55 void
56 policy_init(struct iked *env)
57 {
58 	TAILQ_INIT(&env->sc_policies);
59 	RB_INIT(&env->sc_users);
60 	RB_INIT(&env->sc_sas);
61 	RB_INIT(&env->sc_activesas);
62 	RB_INIT(&env->sc_activeflows);
63 }
64 
65 int
66 policy_lookup(struct iked *env, struct iked_message *msg)
67 {
68 	struct iked_policy	 pol;
69 
70 	if (msg->msg_sa != NULL && msg->msg_sa->sa_policy != NULL) {
71 		/* Existing SA with policy */
72 		msg->msg_policy = msg->msg_sa->sa_policy;
73 		goto found;
74 	}
75 
76 	bzero(&pol, sizeof(pol));
77 	pol.pol_af = msg->msg_peer.ss_family;
78 	memcpy(&pol.pol_peer.addr, &msg->msg_peer, sizeof(msg->msg_peer));
79 	memcpy(&pol.pol_local.addr, &msg->msg_local, sizeof(msg->msg_local));
80 
81 	/* Try to find a matching policy for this message */
82 	if ((msg->msg_policy = policy_test(env, &pol)) != NULL)
83 		goto found;
84 
85 	/* No matching policy found, try the default */
86 	if ((msg->msg_policy = env->sc_defaultcon) != NULL)
87 		goto found;
88 
89 	/* No policy found */
90 	return (-1);
91 
92  found:
93 	return (0);
94 }
95 
96 struct iked_policy *
97 policy_test(struct iked *env, struct iked_policy *key)
98 {
99 	struct iked_policy	*p = NULL, *pol = NULL;
100 	struct iked_flow	*flow = NULL, *flowkey;
101 	u_int			 cnt = 0;
102 
103 	p = TAILQ_FIRST(&env->sc_policies);
104 	while (p != NULL) {
105 		cnt++;
106 		if (p->pol_flags & IKED_POLICY_SKIP)
107 			p = p->pol_skip[IKED_SKIP_FLAGS];
108 		else if (key->pol_af && p->pol_af &&
109 		    key->pol_af != p->pol_af)
110 			p = p->pol_skip[IKED_SKIP_AF];
111 		else if (key->pol_ipproto && p->pol_ipproto &&
112 		    key->pol_ipproto != p->pol_ipproto)
113 			p = p->pol_skip[IKED_SKIP_PROTO];
114 		else if (sockaddr_cmp((struct sockaddr *)&key->pol_peer.addr,
115 		    (struct sockaddr *)&p->pol_peer.addr,
116 		    p->pol_peer.addr_mask) != 0)
117 			p = p->pol_skip[IKED_SKIP_DST_ADDR];
118 		else if (sockaddr_cmp((struct sockaddr *)&key->pol_local.addr,
119 		    (struct sockaddr *)&p->pol_local.addr,
120 		    p->pol_local.addr_mask) != 0)
121 			p = p->pol_skip[IKED_SKIP_SRC_ADDR];
122 		else {
123 			/*
124 			 * Check if a specific flow is requested
125 			 * (eg. for acquire messages from the kernel)
126 			 * and find a matching flow.
127 			 */
128 			if (key->pol_nflows &&
129 			    (flowkey = RB_MIN(iked_flows,
130 			    &key->pol_flows)) != NULL &&
131 			    (flow = RB_FIND(iked_flows, &p->pol_flows,
132 			    flowkey)) == NULL) {
133 				p = TAILQ_NEXT(p, pol_entry);
134 				continue;
135 			}
136 
137 			/* Policy matched */
138 			pol = p;
139 
140 			if (pol->pol_flags & IKED_POLICY_QUICK)
141 				break;
142 
143 			/* Continue to find last matching policy */
144 			p = TAILQ_NEXT(p, pol_entry);
145 		}
146 	}
147 
148 	return (pol);
149 }
150 
151 #define	IKED_SET_SKIP_STEPS(i)						\
152 	do {								\
153 		while (head[i] != cur) {				\
154 			head[i]->pol_skip[i] = cur;			\
155 			head[i] = TAILQ_NEXT(head[i], pol_entry);	\
156 		}							\
157 	} while (0)
158 
159 /* This code is derived from pf_calc_skip_steps() from pf.c */
160 void
161 policy_calc_skip_steps(struct iked_policies *policies)
162 {
163 	struct iked_policy	*head[IKED_SKIP_COUNT], *cur, *prev;
164 	int			 i;
165 
166 	cur = TAILQ_FIRST(policies);
167 	prev = cur;
168 	for (i = 0; i < IKED_SKIP_COUNT; ++i)
169 		head[i] = cur;
170 	while (cur != NULL) {
171 		if (cur->pol_flags & IKED_POLICY_SKIP)
172 			IKED_SET_SKIP_STEPS(IKED_SKIP_FLAGS);
173 		else if (cur->pol_af != AF_UNSPEC &&
174 		    prev->pol_af != AF_UNSPEC &&
175 		    cur->pol_af != prev->pol_af)
176 			IKED_SET_SKIP_STEPS(IKED_SKIP_AF);
177 		else if (cur->pol_ipproto && prev->pol_ipproto &&
178 		    cur->pol_ipproto != prev->pol_ipproto)
179 			IKED_SET_SKIP_STEPS(IKED_SKIP_PROTO);
180 		else if (IKED_ADDR_NEQ(&cur->pol_peer, &prev->pol_peer))
181 			IKED_SET_SKIP_STEPS(IKED_SKIP_DST_ADDR);
182 		else if (IKED_ADDR_NEQ(&cur->pol_local, &prev->pol_local))
183 			IKED_SET_SKIP_STEPS(IKED_SKIP_SRC_ADDR);
184 
185 		prev = cur;
186 		cur = TAILQ_NEXT(cur, pol_entry);
187 	}
188 	for (i = 0; i < IKED_SKIP_COUNT; ++i)
189 		IKED_SET_SKIP_STEPS(i);
190 }
191 
192 void
193 policy_ref(struct iked *env, struct iked_policy *pol)
194 {
195 	pol->pol_refcnt++;
196 	pol->pol_flags |= IKED_POLICY_REFCNT;
197 }
198 
199 void
200 policy_unref(struct iked *env, struct iked_policy *pol)
201 {
202 	if (pol == NULL || (pol->pol_flags & IKED_POLICY_REFCNT) == 0)
203 		return;
204 	if (--(pol->pol_refcnt) <= 0)
205 		config_free_policy(env, pol);
206 }
207 
208 void
209 sa_state(struct iked *env, struct iked_sa *sa, int state)
210 {
211 	const char		*a;
212 	const char		*b;
213 
214 	a = print_map(sa->sa_state, ikev2_state_map);
215 	b = print_map(state, ikev2_state_map);
216 
217 	if (state > sa->sa_state) {
218 		switch (state) {
219 		case IKEV2_STATE_ESTABLISHED:
220 		case IKEV2_STATE_CLOSED:
221 			log_info("%s: %s -> %s from %s to %s policy '%s'",
222 			    __func__, a, b,
223 			    print_host(&sa->sa_peer.addr, NULL, 0),
224 			    print_host(&sa->sa_local.addr, NULL, 0),
225 			    sa->sa_policy->pol_name);
226 			break;
227 		default:
228 			log_debug("%s: %s -> %s", __func__, a, b);
229 			break;
230 		}
231 	}
232 
233 	sa->sa_state = state;
234 }
235 
236 void
237 sa_stateflags(struct iked_sa *sa, u_int flags)
238 {
239 	u_int	require;
240 
241 	if (sa->sa_state > IKEV2_STATE_SA_INIT)
242 		require = sa->sa_statevalid;
243 	else
244 		require = sa->sa_stateinit;
245 
246 	log_debug("%s: 0x%02x -> 0x%02x %s (required 0x%02x %s)", __func__,
247 	    sa->sa_stateflags, sa->sa_stateflags | flags,
248 	    print_bits(sa->sa_stateflags | flags, IKED_REQ_BITS), require,
249 	    print_bits(require, IKED_REQ_BITS));
250 
251 	sa->sa_stateflags |= flags;
252 }
253 
254 int
255 sa_stateok(struct iked_sa *sa, int state)
256 {
257 	u_int	 require;
258 
259 	if (sa->sa_state < state)
260 		return (0);
261 
262 	if (state == IKEV2_STATE_SA_INIT)
263 		require = sa->sa_stateinit;
264 	else
265 		require = sa->sa_statevalid;
266 
267 	if (state == IKEV2_STATE_SA_INIT ||
268 	    state == IKEV2_STATE_VALID ||
269 	    state == IKEV2_STATE_EAP) {
270 		log_debug("%s: %s flags 0x%02x, require 0x%02x %s", __func__,
271 		    print_map(state, ikev2_state_map),
272 		    (sa->sa_stateflags & require), require,
273 		    print_bits(require, IKED_REQ_BITS));
274 
275 		if ((sa->sa_stateflags & require) != require)
276 			return (0);	/* not ready, ignore */
277 	}
278 	return (1);
279 }
280 
281 struct iked_sa *
282 sa_new(struct iked *env, u_int64_t ispi, u_int64_t rspi,
283     u_int initiator, struct iked_policy *pol)
284 {
285 	struct iked_sa	*sa;
286 	struct iked_id	*localid;
287 	u_int		 diff;
288 
289 	if ((ispi == 0 && rspi == 0) ||
290 	    (sa = sa_lookup(env, ispi, rspi, initiator)) == NULL) {
291 		/* Create new SA */
292 		sa = config_new_sa(env, initiator);
293 	}
294 	if (sa == NULL) {
295 		log_debug("%s: failed to get sa", __func__);
296 		return (NULL);
297 	}
298 	if (sa->sa_policy == NULL)
299 		sa->sa_policy = pol;
300 	else
301 		pol = sa->sa_policy;
302 
303 	sa->sa_statevalid = IKED_REQ_AUTH|IKED_REQ_SA;
304 	if (pol != NULL && pol->pol_auth.auth_eap) {
305 		sa->sa_statevalid |= IKED_REQ_CERT;
306 	} else if (pol != NULL && pol->pol_auth.auth_method !=
307 	    IKEV2_AUTH_SHARED_KEY_MIC) {
308 		sa->sa_statevalid |= IKED_REQ_VALID|IKED_REQ_CERT;
309 	}
310 
311 	if (initiator) {
312 		localid = &sa->sa_iid;
313 		diff = IKED_REQ_VALID|IKED_REQ_SA;
314 		sa->sa_stateinit = sa->sa_statevalid & ~diff;
315 		sa->sa_statevalid = sa->sa_statevalid & diff;
316 	} else
317 		localid = &sa->sa_rid;
318 
319 	if (!ibuf_length(localid->id_buf) &&
320 	    ikev2_policy2id(&pol->pol_localid, localid, 1) != 0) {
321 		log_debug("%s: failed to get local id", __func__);
322 		sa_free(env, sa);
323 		return (NULL);
324 	}
325 
326 	if (sa->sa_hdr.sh_ispi == 0)
327 		sa->sa_hdr.sh_ispi = ispi;
328 	if (sa->sa_hdr.sh_rspi == 0)
329 		sa->sa_hdr.sh_rspi = rspi;
330 
331 	/* Re-insert node into the tree */
332 	RB_INSERT(iked_sas, &env->sc_sas, sa);
333 
334 	return (sa);
335 }
336 
337 void
338 sa_free(struct iked *env, struct iked_sa *sa)
339 {
340 	log_debug("%s: ispi %s rspi %s", __func__,
341 	    print_spi(sa->sa_hdr.sh_ispi, 8),
342 	    print_spi(sa->sa_hdr.sh_rspi, 8));
343 
344 	config_free_sa(env, sa);
345 }
346 
347 void
348 sa_free_flows(struct iked *env, struct iked_saflows *head)
349 {
350 	struct iked_flow	*flow, *next;
351 
352 	for (flow = TAILQ_FIRST(head); flow != NULL; flow = next) {
353 		next = TAILQ_NEXT(flow, flow_entry);
354 
355 		log_debug("%s: free %p", __func__, flow);
356 
357 		if (flow->flow_loaded)
358 			RB_REMOVE(iked_flows, &env->sc_activeflows, flow);
359 		TAILQ_REMOVE(head, flow, flow_entry);
360 		(void)pfkey_flow_delete(env->sc_pfkey, flow);
361 		flow_free(flow);
362 	}
363 }
364 
365 
366 int
367 sa_address(struct iked_sa *sa, struct iked_addr *addr,
368     struct sockaddr_storage *peer, int initiator)
369 {
370 	struct iked_policy	*pol = sa->sa_policy;
371 
372 	if (pol == NULL) {
373 		log_debug("%s: invalid policy", __func__);
374 		return (-1);
375 	}
376 
377 	bzero(addr, sizeof(*addr));
378 	addr->addr_af = peer->ss_family;
379 	addr->addr_port = htons(socket_getport(peer));
380 	memcpy(&addr->addr, peer, sizeof(*peer));
381 	if (socket_af((struct sockaddr *)&addr->addr, addr->addr_port) == -1) {
382 		log_debug("%s: invalid address", __func__);
383 		return (-1);
384 	}
385 
386 	if (addr == &sa->sa_peer) {
387 		/* XXX Re-insert node into the tree */
388 		RB_REMOVE(iked_sapeers, &pol->pol_sapeers, sa);
389 		memcpy(&sa->sa_polpeer, initiator ? &pol->pol_peer :
390 		    &sa->sa_peer, sizeof(sa->sa_polpeer));
391 		RB_INSERT(iked_sapeers, &pol->pol_sapeers, sa);
392 	}
393 
394 	return (0);
395 }
396 
397 void
398 childsa_free(struct iked_childsa *sa)
399 {
400 	ibuf_release(sa->csa_encrkey);
401 	ibuf_release(sa->csa_integrkey);
402 	free(sa);
403 }
404 
405 struct iked_childsa *
406 childsa_lookup(struct iked_sa *sa, u_int64_t spi, u_int8_t protoid)
407 {
408 	struct iked_childsa	*csa;
409 
410 	if (sa == NULL || spi == 0 || protoid == 0)
411 		return (NULL);
412 
413 	TAILQ_FOREACH(csa, &sa->sa_childsas, csa_entry) {
414 		if (csa->csa_spi.spi_protoid == protoid &&
415 		    (csa->csa_spi.spi == spi))
416 			break;
417 	}
418 	return (csa);
419 }
420 
421 void
422 flow_free(struct iked_flow *flow)
423 {
424 	free(flow);
425 }
426 
427 struct iked_sa *
428 sa_lookup(struct iked *env, u_int64_t ispi, u_int64_t rspi,
429     u_int initiator)
430 {
431 	struct iked_sa	*sa, key;
432 
433 	key.sa_hdr.sh_ispi = ispi;
434 	key.sa_hdr.sh_rspi = rspi;
435 	key.sa_hdr.sh_initiator = initiator;
436 
437 	if ((sa = RB_FIND(iked_sas, &env->sc_sas, &key)) != NULL) {
438 		gettimeofday(&sa->sa_timeused, NULL);
439 
440 		/* Validate if SPIr matches */
441 		if ((sa->sa_hdr.sh_rspi != 0) &&
442 		    (sa->sa_hdr.sh_rspi != rspi))
443 			return (NULL);
444 	}
445 
446 	return (sa);
447 }
448 
449 static __inline int
450 sa_cmp(struct iked_sa *a, struct iked_sa *b)
451 {
452 	if (a->sa_hdr.sh_initiator != b->sa_hdr.sh_initiator)
453 		return (-2);
454 
455 	if (a->sa_hdr.sh_ispi > b->sa_hdr.sh_ispi)
456 		return (-1);
457 	if (a->sa_hdr.sh_ispi < b->sa_hdr.sh_ispi)
458 		return (1);
459 
460 #if 0
461 	/* Responder SPI is not yet set in the local IKE SADB */
462 	if ((b->sa_type == IKED_SATYPE_LOCAL && b->sa_hdr.sh_rspi == 0) ||
463 	    (a->sa_type == IKED_SATYPE_LOCAL && a->sa_hdr.sh_rspi == 0))
464 		return (0);
465 
466 	if (a->sa_hdr.sh_rspi > b->sa_hdr.sh_rspi)
467 		return (-1);
468 	if (a->sa_hdr.sh_rspi < b->sa_hdr.sh_rspi)
469 		return (1);
470 #endif
471 
472 	return (0);
473 }
474 
475 RB_GENERATE(iked_sas, iked_sa, sa_entry, sa_cmp);
476 
477 struct iked_sa *
478 sa_peer_lookup(struct iked_policy *pol, struct sockaddr_storage *peer)
479 {
480 	struct iked_sa	 key;
481 
482 	memcpy(&key.sa_polpeer.addr, peer, sizeof(*peer));
483 	return (RB_FIND(iked_sapeers, &pol->pol_sapeers, &key));
484 }
485 
486 static __inline int
487 sa_peer_cmp(struct iked_sa *a, struct iked_sa *b)
488 {
489 	return (sockaddr_cmp((struct sockaddr *)&a->sa_polpeer.addr,
490 	    (struct sockaddr *)&b->sa_polpeer.addr, -1));
491 }
492 
493 RB_GENERATE(iked_sapeers, iked_sa, sa_peer_entry, sa_peer_cmp);
494 
495 struct iked_user *
496 user_lookup(struct iked *env, const char *user)
497 {
498 	struct iked_user	 key;
499 
500 	if (strlcpy(key.usr_name, user,
501 	    sizeof(key.usr_name)) >= sizeof(key.usr_name))
502 		return (NULL);
503 
504 	return (RB_FIND(iked_users, &env->sc_users, &key));
505 }
506 
507 static __inline int
508 user_cmp(struct iked_user *a, struct iked_user *b)
509 {
510 	return (strcmp(a->usr_name, b->usr_name));
511 }
512 
513 RB_GENERATE(iked_users, iked_user, usr_entry, user_cmp);
514 
515 static __inline int
516 childsa_cmp(struct iked_childsa *a, struct iked_childsa *b)
517 {
518 	if (a->csa_spi.spi > b->csa_spi.spi)
519 		return (1);
520 	if (a->csa_spi.spi < b->csa_spi.spi)
521 		return (-1);
522 	return (0);
523 }
524 
525 RB_GENERATE(iked_activesas, iked_childsa, csa_node, childsa_cmp);
526 
527 static __inline int
528 addr_cmp(struct iked_addr *a, struct iked_addr *b, int useports)
529 {
530 	int		diff = 0;
531 
532 	diff = sockaddr_cmp((struct sockaddr *)&a->addr,
533 	    (struct sockaddr *)&b->addr, 128);
534 	if (!diff)
535 		diff = (int)a->addr_mask - (int)b->addr_mask;
536 	if (!diff && useports)
537 		diff = a->addr_port - b->addr_port;
538 
539 	return (diff);
540 }
541 
542 static __inline int
543 flow_cmp(struct iked_flow *a, struct iked_flow *b)
544 {
545 	int		diff = 0;
546 
547 	if (a->flow_peer && b->flow_peer)
548 		diff = addr_cmp(a->flow_peer, b->flow_peer, 0);
549 	if (!diff)
550 		diff = addr_cmp(&a->flow_dst, &b->flow_dst, 1);
551 	if (!diff)
552 		diff = addr_cmp(&a->flow_src, &b->flow_src, 1);
553 	if (!diff && a->flow_dir && b->flow_dir)
554 		diff = (int)a->flow_dir - (int)b->flow_dir;
555 
556 	return (diff);
557 }
558 
559 RB_GENERATE(iked_flows, iked_flow, flow_node, flow_cmp);
560