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