1 /* $OpenBSD: policy.c,v 1.36 2015/01/16 06:39:58 deraadt Exp $ */ 2 3 /* 4 * Copyright (c) 2010-2013 Reyk Floeter <reyk@openbsd.org> 5 * Copyright (c) 2001 Daniel Hartmeier 6 * 7 * Permission to use, copy, modify, and distribute this software for any 8 * purpose with or without fee is hereby granted, provided that the above 9 * copyright notice and this permission notice appear in all copies. 10 * 11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 #include <sys/queue.h> 21 #include <sys/socket.h> 22 #include <sys/uio.h> 23 #include <sys/tree.h> 24 25 #include <stdio.h> 26 #include <stdlib.h> 27 #include <unistd.h> 28 #include <string.h> 29 #include <errno.h> 30 #include <fcntl.h> 31 #include <event.h> 32 33 #include "iked.h" 34 #include "ikev2.h" 35 36 static __inline int 37 sa_cmp(struct iked_sa *, struct iked_sa *); 38 static __inline int 39 user_cmp(struct iked_user *, struct iked_user *); 40 static __inline int 41 childsa_cmp(struct iked_childsa *, struct iked_childsa *); 42 static __inline int 43 flow_cmp(struct iked_flow *, struct iked_flow *); 44 45 46 void 47 policy_init(struct iked *env) 48 { 49 TAILQ_INIT(&env->sc_policies); 50 RB_INIT(&env->sc_users); 51 RB_INIT(&env->sc_sas); 52 RB_INIT(&env->sc_activesas); 53 RB_INIT(&env->sc_activeflows); 54 } 55 56 int 57 policy_lookup(struct iked *env, struct iked_message *msg) 58 { 59 struct iked_policy pol; 60 char *s, idstr[IKED_ID_SIZE]; 61 62 63 if (msg->msg_sa != NULL && msg->msg_sa->sa_policy != NULL) { 64 /* Existing SA with policy */ 65 msg->msg_policy = msg->msg_sa->sa_policy; 66 goto found; 67 } 68 69 bzero(&pol, sizeof(pol)); 70 pol.pol_af = msg->msg_peer.ss_family; 71 memcpy(&pol.pol_peer.addr, &msg->msg_peer, sizeof(msg->msg_peer)); 72 memcpy(&pol.pol_local.addr, &msg->msg_local, sizeof(msg->msg_local)); 73 if (msg->msg_id.id_type && 74 ikev2_print_id(&msg->msg_id, idstr, IKED_ID_SIZE) == 0 && 75 (s = strchr(idstr, '/')) != NULL) { 76 pol.pol_peerid.id_type = msg->msg_id.id_type; 77 pol.pol_peerid.id_length = strlen(s+1); 78 strlcpy(pol.pol_peerid.id_data, s+1, 79 sizeof(pol.pol_peerid.id_data)); 80 log_debug("%s: peerid '%s'", __func__, s+1); 81 } 82 83 /* Try to find a matching policy for this message */ 84 if ((msg->msg_policy = policy_test(env, &pol)) != NULL) 85 goto found; 86 87 /* No matching policy found, try the default */ 88 if ((msg->msg_policy = env->sc_defaultcon) != NULL) 89 goto found; 90 91 /* No policy found */ 92 return (-1); 93 94 found: 95 return (0); 96 } 97 98 struct iked_policy * 99 policy_test(struct iked *env, struct iked_policy *key) 100 { 101 struct iked_policy *p = NULL, *pol = NULL; 102 struct iked_flow *flow = NULL, *flowkey; 103 u_int cnt = 0; 104 105 p = TAILQ_FIRST(&env->sc_policies); 106 while (p != NULL) { 107 cnt++; 108 if (p->pol_flags & IKED_POLICY_SKIP) 109 p = p->pol_skip[IKED_SKIP_FLAGS]; 110 else if (key->pol_af && p->pol_af && 111 key->pol_af != p->pol_af) 112 p = p->pol_skip[IKED_SKIP_AF]; 113 else if (key->pol_ipproto && p->pol_ipproto && 114 key->pol_ipproto != p->pol_ipproto) 115 p = p->pol_skip[IKED_SKIP_PROTO]; 116 else if (sockaddr_cmp((struct sockaddr *)&key->pol_peer.addr, 117 (struct sockaddr *)&p->pol_peer.addr, 118 p->pol_peer.addr_mask) != 0) 119 p = p->pol_skip[IKED_SKIP_DST_ADDR]; 120 else if (sockaddr_cmp((struct sockaddr *)&key->pol_local.addr, 121 (struct sockaddr *)&p->pol_local.addr, 122 p->pol_local.addr_mask) != 0) 123 p = p->pol_skip[IKED_SKIP_SRC_ADDR]; 124 else { 125 /* 126 * Check if a specific flow is requested 127 * (eg. for acquire messages from the kernel) 128 * and find a matching flow. 129 */ 130 if (key->pol_nflows && 131 (flowkey = RB_MIN(iked_flows, 132 &key->pol_flows)) != NULL && 133 (flow = RB_FIND(iked_flows, &p->pol_flows, 134 flowkey)) == NULL) { 135 p = TAILQ_NEXT(p, pol_entry); 136 continue; 137 } 138 /* make sure the peer ID matches */ 139 if (key->pol_peerid.id_type && 140 (key->pol_peerid.id_type != p->pol_peerid.id_type || 141 memcmp(key->pol_peerid.id_data, 142 p->pol_peerid.id_data, 143 sizeof(key->pol_peerid.id_data)) != 0)) { 144 p = TAILQ_NEXT(p, pol_entry); 145 continue; 146 } 147 148 /* Policy matched */ 149 pol = p; 150 151 if (pol->pol_flags & IKED_POLICY_QUICK) 152 break; 153 154 /* Continue to find last matching policy */ 155 p = TAILQ_NEXT(p, pol_entry); 156 } 157 } 158 159 return (pol); 160 } 161 162 #define IKED_SET_SKIP_STEPS(i) \ 163 do { \ 164 while (head[i] != cur) { \ 165 head[i]->pol_skip[i] = cur; \ 166 head[i] = TAILQ_NEXT(head[i], pol_entry); \ 167 } \ 168 } while (0) 169 170 /* This code is derived from pf_calc_skip_steps() from pf.c */ 171 void 172 policy_calc_skip_steps(struct iked_policies *policies) 173 { 174 struct iked_policy *head[IKED_SKIP_COUNT], *cur, *prev; 175 int i; 176 177 cur = TAILQ_FIRST(policies); 178 prev = cur; 179 for (i = 0; i < IKED_SKIP_COUNT; ++i) 180 head[i] = cur; 181 while (cur != NULL) { 182 if (cur->pol_flags & IKED_POLICY_SKIP) 183 IKED_SET_SKIP_STEPS(IKED_SKIP_FLAGS); 184 else if (cur->pol_af != AF_UNSPEC && 185 prev->pol_af != AF_UNSPEC && 186 cur->pol_af != prev->pol_af) 187 IKED_SET_SKIP_STEPS(IKED_SKIP_AF); 188 else if (cur->pol_ipproto && prev->pol_ipproto && 189 cur->pol_ipproto != prev->pol_ipproto) 190 IKED_SET_SKIP_STEPS(IKED_SKIP_PROTO); 191 else if (IKED_ADDR_NEQ(&cur->pol_peer, &prev->pol_peer)) 192 IKED_SET_SKIP_STEPS(IKED_SKIP_DST_ADDR); 193 else if (IKED_ADDR_NEQ(&cur->pol_local, &prev->pol_local)) 194 IKED_SET_SKIP_STEPS(IKED_SKIP_SRC_ADDR); 195 196 prev = cur; 197 cur = TAILQ_NEXT(cur, pol_entry); 198 } 199 for (i = 0; i < IKED_SKIP_COUNT; ++i) 200 IKED_SET_SKIP_STEPS(i); 201 } 202 203 void 204 policy_ref(struct iked *env, struct iked_policy *pol) 205 { 206 pol->pol_refcnt++; 207 pol->pol_flags |= IKED_POLICY_REFCNT; 208 } 209 210 void 211 policy_unref(struct iked *env, struct iked_policy *pol) 212 { 213 if (pol == NULL || (pol->pol_flags & IKED_POLICY_REFCNT) == 0) 214 return; 215 if (--(pol->pol_refcnt) <= 0) 216 config_free_policy(env, pol); 217 } 218 219 void 220 sa_state(struct iked *env, struct iked_sa *sa, int state) 221 { 222 const char *a; 223 const char *b; 224 int ostate = sa->sa_state; 225 226 a = print_map(ostate, ikev2_state_map); 227 b = print_map(state, ikev2_state_map); 228 229 sa->sa_state = state; 230 if (ostate != IKEV2_STATE_INIT && 231 !sa_stateok(sa, state)) { 232 log_debug("%s: cannot switch: %s -> %s", __func__, a, b); 233 sa->sa_state = ostate; 234 } else if (ostate != sa->sa_state) { 235 switch (state) { 236 case IKEV2_STATE_ESTABLISHED: 237 case IKEV2_STATE_CLOSED: 238 log_info("%s: %s -> %s from %s to %s policy '%s'", 239 __func__, a, b, 240 print_host((struct sockaddr *)&sa->sa_peer.addr, 241 NULL, 0), 242 print_host((struct sockaddr *)&sa->sa_local.addr, 243 NULL, 0), 244 sa->sa_policy ? sa->sa_policy->pol_name : 245 "<unknown>"); 246 break; 247 default: 248 log_debug("%s: %s -> %s", __func__, a, b); 249 break; 250 } 251 } 252 253 } 254 255 void 256 sa_stateflags(struct iked_sa *sa, u_int flags) 257 { 258 u_int require; 259 260 if (sa->sa_state > IKEV2_STATE_SA_INIT) 261 require = sa->sa_statevalid; 262 else 263 require = sa->sa_stateinit; 264 265 log_debug("%s: 0x%02x -> 0x%02x %s (required 0x%02x %s)", __func__, 266 sa->sa_stateflags, sa->sa_stateflags | flags, 267 print_bits(sa->sa_stateflags | flags, IKED_REQ_BITS), require, 268 print_bits(require, IKED_REQ_BITS)); 269 270 sa->sa_stateflags |= flags; 271 } 272 273 int 274 sa_stateok(struct iked_sa *sa, int state) 275 { 276 u_int require; 277 278 if (sa->sa_state < state) 279 return (0); 280 281 if (state == IKEV2_STATE_SA_INIT) 282 require = sa->sa_stateinit; 283 else 284 require = sa->sa_statevalid; 285 286 if (state == IKEV2_STATE_SA_INIT || 287 state == IKEV2_STATE_VALID || 288 state == IKEV2_STATE_EAP_VALID) { 289 log_debug("%s: %s flags 0x%02x, require 0x%02x %s", __func__, 290 print_map(state, ikev2_state_map), 291 (sa->sa_stateflags & require), require, 292 print_bits(require, IKED_REQ_BITS)); 293 294 if ((sa->sa_stateflags & require) != require) 295 return (0); /* not ready, ignore */ 296 } 297 return (1); 298 } 299 300 struct iked_sa * 301 sa_new(struct iked *env, u_int64_t ispi, u_int64_t rspi, 302 u_int initiator, struct iked_policy *pol) 303 { 304 struct iked_sa *sa; 305 struct iked_sa *old; 306 struct iked_id *localid; 307 u_int diff; 308 309 if ((ispi == 0 && rspi == 0) || 310 (sa = sa_lookup(env, ispi, rspi, initiator)) == NULL) { 311 /* Create new SA */ 312 if (!initiator && ispi == 0) { 313 log_debug("%s: cannot create responder IKE SA w/o ispi", 314 __func__); 315 return (NULL); 316 } 317 sa = config_new_sa(env, initiator); 318 if (sa == NULL) { 319 log_debug("%s: failed to allocate IKE SA", __func__); 320 return (NULL); 321 } 322 if (!initiator) 323 sa->sa_hdr.sh_ispi = ispi; 324 old = RB_INSERT(iked_sas, &env->sc_sas, sa); 325 if (old && old != sa) { 326 log_warnx("%s: duplicate IKE SA", __func__); 327 config_free_sa(env, sa); 328 return (NULL); 329 } 330 } 331 /* Update rspi in the initator case */ 332 if (initiator && sa->sa_hdr.sh_rspi == 0 && rspi) 333 sa->sa_hdr.sh_rspi = rspi; 334 335 if (sa->sa_policy == NULL) 336 sa->sa_policy = pol; 337 else 338 pol = sa->sa_policy; 339 340 sa->sa_statevalid = IKED_REQ_AUTH|IKED_REQ_AUTHVALID|IKED_REQ_SA; 341 if (pol != NULL && pol->pol_auth.auth_eap) { 342 sa->sa_statevalid |= IKED_REQ_CERT|IKED_REQ_EAPVALID; 343 } else if (pol != NULL && pol->pol_auth.auth_method != 344 IKEV2_AUTH_SHARED_KEY_MIC) { 345 sa->sa_statevalid |= IKED_REQ_CERTVALID|IKED_REQ_CERT; 346 } 347 348 if (initiator) { 349 localid = &sa->sa_iid; 350 diff = IKED_REQ_CERTVALID|IKED_REQ_AUTHVALID|IKED_REQ_SA| 351 IKED_REQ_EAPVALID; 352 sa->sa_stateinit = sa->sa_statevalid & ~diff; 353 sa->sa_statevalid = sa->sa_statevalid & diff; 354 } else 355 localid = &sa->sa_rid; 356 357 if (!ibuf_length(localid->id_buf) && pol != NULL && 358 ikev2_policy2id(&pol->pol_localid, localid, 1) != 0) { 359 log_debug("%s: failed to get local id", __func__); 360 sa_free(env, sa); 361 return (NULL); 362 } 363 364 return (sa); 365 } 366 367 void 368 sa_free(struct iked *env, struct iked_sa *sa) 369 { 370 log_debug("%s: ispi %s rspi %s", __func__, 371 print_spi(sa->sa_hdr.sh_ispi, 8), 372 print_spi(sa->sa_hdr.sh_rspi, 8)); 373 374 /* IKE rekeying running? */ 375 if (sa->sa_next) { 376 RB_REMOVE(iked_sas, &env->sc_sas, sa->sa_next); 377 config_free_sa(env, sa->sa_next); 378 } 379 RB_REMOVE(iked_sas, &env->sc_sas, sa); 380 config_free_sa(env, sa); 381 } 382 383 void 384 sa_free_flows(struct iked *env, struct iked_saflows *head) 385 { 386 struct iked_flow *flow, *next; 387 388 for (flow = TAILQ_FIRST(head); flow != NULL; flow = next) { 389 next = TAILQ_NEXT(flow, flow_entry); 390 391 log_debug("%s: free %p", __func__, flow); 392 393 if (flow->flow_loaded) 394 RB_REMOVE(iked_flows, &env->sc_activeflows, flow); 395 TAILQ_REMOVE(head, flow, flow_entry); 396 (void)pfkey_flow_delete(env->sc_pfkey, flow); 397 flow_free(flow); 398 } 399 } 400 401 402 int 403 sa_address(struct iked_sa *sa, struct iked_addr *addr, 404 struct sockaddr_storage *peer, int initiator) 405 { 406 struct iked_policy *pol = sa->sa_policy; 407 408 if (sa->sa_state != IKEV2_STATE_CLOSING && pol == NULL) { 409 log_debug("%s: missing policy", __func__); 410 return (-1); 411 } 412 413 bzero(addr, sizeof(*addr)); 414 addr->addr_af = peer->ss_family; 415 addr->addr_port = htons(socket_getport((struct sockaddr *)peer)); 416 memcpy(&addr->addr, peer, sizeof(*peer)); 417 if (socket_af((struct sockaddr *)&addr->addr, addr->addr_port) == -1) { 418 log_debug("%s: invalid address", __func__); 419 return (-1); 420 } 421 422 if (addr == &sa->sa_peer && pol) { 423 /* XXX Re-insert node into the tree */ 424 RB_REMOVE(iked_sapeers, &pol->pol_sapeers, sa); 425 memcpy(&sa->sa_polpeer, initiator ? &pol->pol_peer : 426 &sa->sa_peer, sizeof(sa->sa_polpeer)); 427 RB_INSERT(iked_sapeers, &pol->pol_sapeers, sa); 428 } 429 430 return (0); 431 } 432 433 void 434 childsa_free(struct iked_childsa *csa) 435 { 436 if (csa->csa_children) { 437 /* XXX should not happen */ 438 log_warnx("%s: trying to remove CSA %p children %u", 439 __func__, csa, csa->csa_children); 440 return; 441 } 442 if (csa->csa_parent) 443 csa->csa_parent->csa_children--; 444 ibuf_release(csa->csa_encrkey); 445 ibuf_release(csa->csa_integrkey); 446 free(csa); 447 } 448 449 struct iked_childsa * 450 childsa_lookup(struct iked_sa *sa, u_int64_t spi, u_int8_t protoid) 451 { 452 struct iked_childsa *csa; 453 454 if (sa == NULL || spi == 0 || protoid == 0) 455 return (NULL); 456 457 TAILQ_FOREACH(csa, &sa->sa_childsas, csa_entry) { 458 if (csa->csa_spi.spi_protoid == protoid && 459 (csa->csa_spi.spi == spi)) 460 break; 461 } 462 return (csa); 463 } 464 465 void 466 flow_free(struct iked_flow *flow) 467 { 468 free(flow); 469 } 470 471 struct iked_sa * 472 sa_lookup(struct iked *env, u_int64_t ispi, u_int64_t rspi, 473 u_int initiator) 474 { 475 struct iked_sa *sa, key; 476 477 key.sa_hdr.sh_ispi = ispi; 478 /* key.sa_hdr.sh_rspi = rspi; */ 479 key.sa_hdr.sh_initiator = initiator; 480 481 if ((sa = RB_FIND(iked_sas, &env->sc_sas, &key)) != NULL) { 482 gettimeofday(&sa->sa_timeused, NULL); 483 484 /* Validate if SPIr matches */ 485 if ((sa->sa_hdr.sh_rspi != 0) && 486 (rspi != 0) && 487 (sa->sa_hdr.sh_rspi != rspi)) 488 return (NULL); 489 } 490 491 return (sa); 492 } 493 494 static __inline int 495 sa_cmp(struct iked_sa *a, struct iked_sa *b) 496 { 497 if (a->sa_hdr.sh_initiator > b->sa_hdr.sh_initiator) 498 return (-1); 499 if (a->sa_hdr.sh_initiator < b->sa_hdr.sh_initiator) 500 return (1); 501 502 if (a->sa_hdr.sh_ispi > b->sa_hdr.sh_ispi) 503 return (-1); 504 if (a->sa_hdr.sh_ispi < b->sa_hdr.sh_ispi) 505 return (1); 506 507 #if 0 508 /* Responder SPI is not yet set in the local IKE SADB */ 509 if ((b->sa_type == IKED_SATYPE_LOCAL && b->sa_hdr.sh_rspi == 0) || 510 (a->sa_type == IKED_SATYPE_LOCAL && a->sa_hdr.sh_rspi == 0)) 511 return (0); 512 513 if (a->sa_hdr.sh_rspi > b->sa_hdr.sh_rspi) 514 return (-1); 515 if (a->sa_hdr.sh_rspi < b->sa_hdr.sh_rspi) 516 return (1); 517 #endif 518 519 return (0); 520 } 521 522 struct iked_sa * 523 sa_peer_lookup(struct iked_policy *pol, struct sockaddr_storage *peer) 524 { 525 struct iked_sa key; 526 527 memcpy(&key.sa_polpeer.addr, peer, sizeof(*peer)); 528 return (RB_FIND(iked_sapeers, &pol->pol_sapeers, &key)); 529 } 530 531 static __inline int 532 sa_peer_cmp(struct iked_sa *a, struct iked_sa *b) 533 { 534 return (sockaddr_cmp((struct sockaddr *)&a->sa_polpeer.addr, 535 (struct sockaddr *)&b->sa_polpeer.addr, -1)); 536 } 537 538 static __inline int 539 sa_addrpool_cmp(struct iked_sa *a, struct iked_sa *b) 540 { 541 return (sockaddr_cmp((struct sockaddr *)&a->sa_addrpool->addr, 542 (struct sockaddr *)&b->sa_addrpool->addr, -1)); 543 } 544 545 struct iked_user * 546 user_lookup(struct iked *env, const char *user) 547 { 548 struct iked_user key; 549 550 if (strlcpy(key.usr_name, user, 551 sizeof(key.usr_name)) >= sizeof(key.usr_name)) 552 return (NULL); 553 554 return (RB_FIND(iked_users, &env->sc_users, &key)); 555 } 556 557 static __inline int 558 user_cmp(struct iked_user *a, struct iked_user *b) 559 { 560 return (strcmp(a->usr_name, b->usr_name)); 561 } 562 563 static __inline int 564 childsa_cmp(struct iked_childsa *a, struct iked_childsa *b) 565 { 566 if (a->csa_spi.spi > b->csa_spi.spi) 567 return (1); 568 if (a->csa_spi.spi < b->csa_spi.spi) 569 return (-1); 570 return (0); 571 } 572 573 static __inline int 574 addr_cmp(struct iked_addr *a, struct iked_addr *b, int useports) 575 { 576 int diff = 0; 577 578 diff = sockaddr_cmp((struct sockaddr *)&a->addr, 579 (struct sockaddr *)&b->addr, 128); 580 if (!diff) 581 diff = (int)a->addr_mask - (int)b->addr_mask; 582 if (!diff && useports) 583 diff = a->addr_port - b->addr_port; 584 585 return (diff); 586 } 587 588 static __inline int 589 flow_cmp(struct iked_flow *a, struct iked_flow *b) 590 { 591 int diff = 0; 592 593 if (a->flow_peer && b->flow_peer) 594 diff = addr_cmp(a->flow_peer, b->flow_peer, 0); 595 if (!diff) 596 diff = addr_cmp(&a->flow_dst, &b->flow_dst, 1); 597 if (!diff) 598 diff = addr_cmp(&a->flow_src, &b->flow_src, 1); 599 if (!diff && a->flow_dir && b->flow_dir) 600 diff = (int)a->flow_dir - (int)b->flow_dir; 601 602 return (diff); 603 } 604 605 RB_GENERATE(iked_sas, iked_sa, sa_entry, sa_cmp); 606 RB_GENERATE(iked_sapeers, iked_sa, sa_peer_entry, sa_peer_cmp); 607 RB_GENERATE(iked_addrpool, iked_sa, sa_addrpool_entry, sa_addrpool_cmp); 608 RB_GENERATE(iked_users, iked_user, usr_entry, user_cmp); 609 RB_GENERATE(iked_activesas, iked_childsa, csa_node, childsa_cmp); 610 RB_GENERATE(iked_flows, iked_flow, flow_node, flow_cmp); 611