1 /* $OpenBSD: sa.c,v 1.51 2001/11/21 10:01:43 ho Exp $ */ 2 /* $EOM: sa.c,v 1.112 2000/12/12 00:22:52 niklas Exp $ */ 3 4 /* 5 * Copyright (c) 1998, 1999, 2000, 2001 Niklas Hallqvist. All rights reserved. 6 * Copyright (c) 1999, 2001 Angelos D. Keromytis. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. All advertising materials mentioning features or use of this software 17 * must display the following acknowledgement: 18 * This product includes software developed by Ericsson Radio Systems. 19 * 4. The name of the author may not be used to endorse or promote products 20 * derived from this software without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 /* 35 * This code was written under funding by Ericsson Radio Systems. 36 */ 37 38 #include <sys/types.h> 39 #include <stdlib.h> 40 #include <string.h> 41 42 #if defined (USE_KEYNOTE) || defined (USE_POLICY) 43 #include <regex.h> 44 #include <keynote.h> 45 #endif /* USE_KEYNOTE || USE_POLICY */ 46 47 #include "sysdep.h" 48 49 #include "cookie.h" 50 #include "doi.h" 51 #include "exchange.h" 52 #include "isakmp.h" 53 #include "log.h" 54 #include "message.h" 55 #include "sa.h" 56 #include "timer.h" 57 #include "transport.h" 58 #include "util.h" 59 #include "cert.h" 60 #include "policy.h" 61 #include "key.h" 62 63 /* Initial number of bits from the cookies used as hash. */ 64 #define INITIAL_BUCKET_BITS 6 65 66 /* 67 * Don't try to use more bits than this as a hash. 68 * We only XOR 16 bits so going above that means changing the code below 69 * too. 70 */ 71 #define MAX_BUCKET_BITS 16 72 73 #if 0 74 static void sa_resize (void); 75 #endif 76 static void sa_dump (char *, struct sa *); 77 static void sa_soft_expire (void *); 78 static void sa_hard_expire (void *); 79 80 static LIST_HEAD (sa_list, sa) *sa_tab; 81 82 /* Works both as a maximum index and a mask. */ 83 static int bucket_mask; 84 85 void 86 sa_init (void) 87 { 88 int i; 89 90 bucket_mask = (1 << INITIAL_BUCKET_BITS) - 1; 91 sa_tab = malloc ((bucket_mask + 1) * sizeof (struct sa_list)); 92 if (!sa_tab) 93 log_fatal ("sa_init: malloc (%s) failed", 94 (bucket_mask + 1) * sizeof (struct sa_list)); 95 for (i = 0; i <= bucket_mask; i++) 96 { 97 LIST_INIT (&sa_tab[i]); 98 } 99 } 100 101 #if 0 102 /* XXX We don't yet resize. */ 103 static void 104 sa_resize (void) 105 { 106 int new_mask = (bucket_mask + 1) * 2 - 1; 107 int i; 108 struct sa_list *new_tab; 109 110 new_tab = realloc (sa_tab, (new_mask + 1) * sizeof (struct sa_list)); 111 if (!new_tab) 112 return; 113 sa_tab = new_tab; 114 for (i = bucket_mask + 1; i <= new_mask; i++) 115 { 116 LIST_INIT (&sa_tab[i]); 117 } 118 bucket_mask = new_mask; 119 120 /* XXX Rehash existing entries. */ 121 } 122 #endif 123 124 /* Lookup an SA with the help from a user-supplied checking function. */ 125 struct sa * 126 sa_find (int (*check) (struct sa *, void *), void *arg) 127 { 128 int i; 129 struct sa *sa; 130 131 for (i = 0; i <= bucket_mask; i++) 132 for (sa = LIST_FIRST (&sa_tab[i]); sa; sa = LIST_NEXT (sa, link)) 133 if (check (sa, arg)) 134 { 135 LOG_DBG ((LOG_SA, 90, "sa_find: return SA %p", sa)); 136 return sa; 137 } 138 LOG_DBG ((LOG_SA, 90, "sa_find: no SA matched query")); 139 return 0; 140 } 141 142 /* Check if SA is an ISAKMP SA with an initiar cookie equal to ICOOKIE. */ 143 static int 144 sa_check_icookie (struct sa *sa, void *icookie) 145 { 146 return sa->phase == 1 147 && memcmp (sa->cookies, icookie, ISAKMP_HDR_ICOOKIE_LEN) == 0; 148 } 149 150 /* Lookup an ISAKMP SA out of just the initiator cookie. */ 151 struct sa * 152 sa_lookup_from_icookie (u_int8_t *cookie) 153 { 154 return sa_find (sa_check_icookie, cookie); 155 } 156 157 struct name_phase_arg { 158 char *name; 159 u_int8_t phase; 160 }; 161 162 /* Check if SA has the name and phase given by V_ARG. */ 163 static int 164 sa_check_name_phase (struct sa *sa, void *v_arg) 165 { 166 struct name_phase_arg *arg = v_arg; 167 168 return sa->name && strcasecmp (sa->name, arg->name) == 0 && 169 sa->phase == arg->phase && !(sa->flags & SA_FLAG_REPLACED); 170 } 171 172 /* Lookup an SA by name, case-independent, and phase. */ 173 struct sa * 174 sa_lookup_by_name (char *name, int phase) 175 { 176 struct name_phase_arg arg = { name, phase }; 177 178 return sa_find (sa_check_name_phase, &arg); 179 } 180 181 struct addr_arg 182 { 183 struct sockaddr *addr; 184 socklen_t len; 185 int phase; 186 int flags; 187 }; 188 189 /* 190 * Check if SA is ready and has a peer with an address equal the one given 191 * by V_ADDR. Furthermore if we are searching for a specific phase, check 192 * that too. 193 */ 194 static int 195 sa_check_peer (struct sa *sa, void *v_addr) 196 { 197 struct addr_arg *addr = v_addr; 198 struct sockaddr *dst; 199 200 if (!sa->transport || (sa->flags & SA_FLAG_READY) == 0 201 || (addr->phase && addr->phase != sa->phase)) 202 return 0; 203 204 sa->transport->vtbl->get_dst (sa->transport, &dst); 205 return sysdep_sa_len (dst) == addr->len 206 && memcmp (dst, addr->addr, sysdep_sa_len (dst)) == 0; 207 } 208 209 struct dst_isakmpspi_arg { 210 struct sockaddr *dst; 211 u_int8_t *spi; /* must be ISAKMP_SPI_SIZE octets */ 212 }; 213 214 /* 215 * Check if SA matches what we are asking for through V_ARG. It has to 216 * be a finished phaes 1 (ISAKMP) SA. 217 */ 218 static int 219 isakmp_sa_check (struct sa *sa, void *v_arg) 220 { 221 struct dst_isakmpspi_arg *arg = v_arg; 222 struct sockaddr *dst, *src; 223 224 if (sa->phase != 1 || !(sa->flags & SA_FLAG_READY)) 225 return 0; 226 227 /* verify address is either src or dst for this sa */ 228 sa->transport->vtbl->get_dst (sa->transport, &dst); 229 sa->transport->vtbl->get_src (sa->transport, &src); 230 if (memcmp (src, arg->dst, sysdep_sa_len (src)) && 231 memcmp (dst, arg->dst, sysdep_sa_len (dst))) 232 return 0; 233 234 /* match icookie+rcookie against spi */ 235 if (memcmp (sa->cookies, arg->spi, ISAKMP_HDR_COOKIES_LEN) == 0) 236 return 1; 237 238 return 0; 239 } 240 241 /* 242 * Find an ISAKMP SA with a "name" of DST & SPI. 243 */ 244 struct sa * 245 sa_lookup_isakmp_sa (struct sockaddr *dst, u_int8_t *spi) 246 { 247 struct dst_isakmpspi_arg arg = { dst, spi }; 248 249 return sa_find (isakmp_sa_check, &arg); 250 } 251 252 /* Lookup a ready SA by the peer's address. */ 253 struct sa * 254 sa_lookup_by_peer (struct sockaddr *dst, socklen_t dstlen) 255 { 256 struct addr_arg arg = { dst, dstlen, 0 }; 257 258 return sa_find (sa_check_peer, &arg); 259 } 260 261 /* Lookup a ready ISAKMP SA given its peer address. */ 262 struct sa * 263 sa_isakmp_lookup_by_peer (struct sockaddr *dst, socklen_t dstlen) 264 { 265 struct addr_arg arg = { dst, dstlen, 1 }; 266 267 return sa_find (sa_check_peer, &arg); 268 } 269 270 int 271 sa_enter (struct sa *sa) 272 { 273 u_int16_t bucket = 0; 274 int i; 275 u_int8_t *cp; 276 277 /* XXX We might resize if we are crossing a certain threshold */ 278 279 for (i = 0; i < ISAKMP_HDR_COOKIES_LEN; i += 2) 280 { 281 cp = sa->cookies + i; 282 /* Doing it this way avoids alignment problems. */ 283 bucket ^= cp[0] | cp[1] << 8; 284 } 285 for (i = 0; i < ISAKMP_HDR_MESSAGE_ID_LEN; i += 2) 286 { 287 cp = sa->message_id + i; 288 /* Doing it this way avoids alignment problems. */ 289 bucket ^= cp[0] | cp[1] << 8; 290 } 291 bucket &= bucket_mask; 292 LIST_INSERT_HEAD (&sa_tab[bucket], sa, link); 293 sa_reference (sa); 294 LOG_DBG ((LOG_SA, 70, "sa_enter: SA %p added to SA list", sa)); 295 return 1; 296 } 297 298 /* 299 * Lookup the SA given by the header fields MSG. PHASE2 is false when 300 * looking for phase 1 SAa and true otherwise. 301 */ 302 struct sa * 303 sa_lookup_by_header (u_int8_t *msg, int phase2) 304 { 305 return sa_lookup (msg + ISAKMP_HDR_COOKIES_OFF, 306 phase2 ? msg + ISAKMP_HDR_MESSAGE_ID_OFF : 0); 307 } 308 309 /* 310 * Lookup the SA given by the COOKIES and possibly the MESSAGE_ID unless 311 * a null pointer, meaning we are looking for phase 1 SAs. 312 */ 313 struct sa * 314 sa_lookup (u_int8_t *cookies, u_int8_t *message_id) 315 { 316 u_int16_t bucket = 0; 317 int i; 318 struct sa *sa; 319 u_int8_t *cp; 320 321 /* 322 * We use the cookies to get bits to use as an index into sa_tab, as at 323 * least one (our cookie) is a good hash, xoring all the bits, 16 at a 324 * time, and then masking, should do. Doing it this way means we can 325 * validate cookies very fast thus delimiting the effects of "Denial of 326 * service"-attacks using packet flooding. 327 */ 328 for (i = 0; i < ISAKMP_HDR_COOKIES_LEN; i += 2) 329 { 330 cp = cookies + i; 331 /* Doing it this way avoids alignment problems. */ 332 bucket ^= cp[0] | cp[1] << 8; 333 } 334 if (message_id) 335 for (i = 0; i < ISAKMP_HDR_MESSAGE_ID_LEN; i += 2) 336 { 337 cp = message_id + i; 338 /* Doing it this way avoids alignment problems. */ 339 bucket ^= cp[0] | cp[1] << 8; 340 } 341 bucket &= bucket_mask; 342 for (sa = LIST_FIRST (&sa_tab[bucket]); 343 sa && (memcmp (cookies, sa->cookies, ISAKMP_HDR_COOKIES_LEN) != 0 344 || (message_id && memcmp (message_id, sa->message_id, 345 ISAKMP_HDR_MESSAGE_ID_LEN) 346 != 0) 347 || (!message_id && !zero_test (sa->message_id, 348 ISAKMP_HDR_MESSAGE_ID_LEN))); 349 sa = LIST_NEXT (sa, link)) 350 ; 351 352 return sa; 353 } 354 355 /* Create an SA. */ 356 int 357 sa_create (struct exchange *exchange, struct transport *t) 358 { 359 struct sa *sa; 360 361 /* 362 * We want the SA zeroed for sa_free to be able to find out what fields 363 * have been filled-in. 364 */ 365 sa = calloc (1, sizeof *sa); 366 if (!sa) 367 { 368 log_error ("sa_create: calloc (1, %d) failed", sizeof *sa); 369 return -1; 370 } 371 sa->transport = t; 372 if (t) 373 transport_reference (t); 374 sa->phase = exchange->phase; 375 memcpy (sa->cookies, exchange->cookies, ISAKMP_HDR_COOKIES_LEN); 376 memcpy (sa->message_id, exchange->message_id, ISAKMP_HDR_MESSAGE_ID_LEN); 377 sa->doi = exchange->doi; 378 sa->policy_id = -1; 379 380 if (sa->doi->sa_size) 381 { 382 /* Allocate the DOI-specific structure and initialize it to zeroes. */ 383 sa->data = calloc (1, sa->doi->sa_size); 384 if (!sa->data) 385 { 386 log_error ("sa_create: calloc (1, %d) failed", sa->doi->sa_size); 387 free (sa); 388 return -1; 389 } 390 } 391 392 TAILQ_INIT (&sa->protos); 393 394 sa_enter (sa); 395 TAILQ_INSERT_TAIL (&exchange->sa_list, sa, next); 396 sa_reference (sa); 397 398 LOG_DBG ((LOG_SA, 60, 399 "sa_create: sa %p phase %d added to exchange %p (%s)", sa, 400 sa->phase, exchange, 401 exchange->name ? exchange->name : "<unnamed>")); 402 return 0; 403 } 404 405 /* 406 * Dump the internal state of SA to the report channel, with HEADER 407 * prepended to each line. 408 */ 409 static void 410 sa_dump (char *header, struct sa *sa) 411 { 412 struct proto *proto; 413 char spi_header[80]; 414 int i; 415 416 LOG_DBG ((LOG_REPORT, 0, "%s: %p %s phase %d doi %d flags 0x%x", 417 header, sa, sa->name ? sa->name : "<unnamed>", sa->phase, 418 sa->doi->id, sa->flags)); 419 LOG_DBG ((LOG_REPORT, 0, 420 "%s: icookie %08x%08x rcookie %08x%08x", header, 421 decode_32 (sa->cookies), decode_32 (sa->cookies + 4), 422 decode_32 (sa->cookies + 8), decode_32 (sa->cookies + 12))); 423 LOG_DBG ((LOG_REPORT, 0, "%s: msgid %08x refcnt %d", header, 424 decode_32 (sa->message_id), sa->refcnt)); 425 LOG_DBG ((LOG_REPORT, 0, "%s: life secs %llu kb %llu", header, 426 sa->seconds, sa->kilobytes)); 427 for (proto = TAILQ_FIRST (&sa->protos); proto; 428 proto = TAILQ_NEXT (proto, link)) 429 { 430 LOG_DBG ((LOG_REPORT, 0, 431 "%s: suite %d proto %d", header, proto->no, proto->proto)); 432 LOG_DBG ((LOG_REPORT, 0, 433 "%s: spi_sz[0] %d spi[0] %p spi_sz[1] %d spi[1] %p", header, 434 proto->spi_sz[0], proto->spi[0], proto->spi_sz[1], 435 proto->spi[1])); 436 LOG_DBG ((LOG_REPORT, 0, "%s: %s, %s", header, 437 !sa->doi ? "<nodoi>" 438 : sa->doi->decode_ids ("initiator id: %s, responder id: %s", 439 sa->id_i, sa->id_i_len, 440 sa->id_r, sa->id_r_len, 0), 441 !sa->transport ? "<no transport>" : 442 sa->transport->vtbl->decode_ids (sa->transport))); 443 for (i = 0; i < 2; i++) 444 if (proto->spi[i]) 445 { 446 snprintf (spi_header, 80, "%s: spi[%d]", header, i); 447 LOG_DBG_BUF ((LOG_REPORT, 0, spi_header, proto->spi[i], 448 proto->spi_sz[i])); 449 } 450 } 451 } 452 453 /* Report all the SAs to the report channel. */ 454 void 455 sa_report (void) 456 { 457 int i; 458 struct sa *sa; 459 460 for (i = 0; i <= bucket_mask; i++) 461 for (sa = LIST_FIRST (&sa_tab[i]); sa; sa = LIST_NEXT (sa, link)) 462 sa_dump ("sa_report", sa); 463 } 464 465 /* Free the protocol structure pointed to by PROTO. */ 466 void 467 proto_free (struct proto *proto) 468 { 469 int i; 470 struct sa *sa = proto->sa; 471 472 for (i = 0; i < 2; i++) 473 if (proto->spi[i]) 474 { 475 if (sa->doi->delete_spi) 476 sa->doi->delete_spi (sa, proto, i); 477 free (proto->spi[i]); 478 } 479 TAILQ_REMOVE (&sa->protos, proto, link); 480 if (proto->data) 481 { 482 if (sa->doi && sa->doi->free_proto_data) 483 sa->doi->free_proto_data (proto->data); 484 free (proto->data); 485 } 486 487 /* XXX Use class LOG_SA instead? */ 488 LOG_DBG ((LOG_MISC, 90, "proto_free: freeing %p", proto)); 489 490 free (proto); 491 } 492 493 /* Release all resources this SA is using. */ 494 void 495 sa_free (struct sa *sa) 496 { 497 if (sa->death) 498 { 499 timer_remove_event (sa->death); 500 sa->death = 0; 501 sa->refcnt--; 502 } 503 if (sa->soft_death) 504 { 505 timer_remove_event (sa->soft_death); 506 sa->soft_death = 0; 507 sa->refcnt--; 508 } 509 sa_remove (sa); 510 } 511 512 /* Remove the SA from the hash table of live SAs. */ 513 void 514 sa_remove (struct sa *sa) 515 { 516 LIST_REMOVE (sa, link); 517 LOG_DBG ((LOG_SA, 70, "sa_remove: SA %p removed from SA list", sa)); 518 sa_release (sa); 519 } 520 521 /* Raise the reference count of SA. */ 522 void 523 sa_reference (struct sa *sa) 524 { 525 sa->refcnt++; 526 LOG_DBG ((LOG_SA, 80, "sa_reference: SA %p now has %d references", 527 sa, sa->refcnt)); 528 } 529 530 /* Release a reference to SA. */ 531 void 532 sa_release (struct sa *sa) 533 { 534 struct proto *proto; 535 struct cert_handler *handler; 536 537 LOG_DBG ((LOG_SA, 80, "sa_release: SA %p had %d references", 538 sa, sa->refcnt)); 539 540 if (--sa->refcnt) 541 return; 542 543 LOG_DBG ((LOG_SA, 60, "sa_release: freeing SA %p", sa)); 544 545 while ((proto = TAILQ_FIRST (&sa->protos)) != 0) 546 proto_free (proto); 547 if (sa->data) 548 { 549 if (sa->doi && sa->doi->free_sa_data) 550 sa->doi->free_sa_data (sa->data); 551 free (sa->data); 552 } 553 if (sa->id_i) 554 free (sa->id_i); 555 if (sa->id_r) 556 free (sa->id_r); 557 if (sa->recv_cert) 558 { 559 handler = cert_get (sa->recv_certtype); 560 if (handler) 561 handler->cert_free (sa->recv_cert); 562 } 563 if (sa->sent_cert) 564 { 565 handler = cert_get (sa->sent_certtype); 566 if (handler) 567 handler->cert_free (sa->sent_cert); 568 } 569 if (sa->recv_key) 570 key_free (sa->recv_keytype, ISAKMP_KEYTYPE_PUBLIC, sa->recv_key); 571 if (sa->sent_key) 572 key_free (sa->sent_keytype, ISAKMP_KEYTYPE_PRIVATE, sa->sent_key); 573 if (sa->keynote_key) 574 free (sa->keynote_key); /* This is just a string */ 575 #if defined (USE_POLICY) || defined (USE_KEYNOTE) 576 if (sa->policy_id != -1) 577 LK (kn_close, (sa->policy_id)); 578 #endif 579 if (sa->name) 580 free (sa->name); 581 if (sa->keystate) 582 free (sa->keystate); 583 if (sa->transport) 584 transport_release (sa->transport); 585 free (sa); 586 } 587 588 /* 589 * Rehash the ISAKMP SA this MSG is negotiating with the responder cookie 590 * filled in. 591 */ 592 void 593 sa_isakmp_upgrade (struct message *msg) 594 { 595 struct sa *sa = TAILQ_FIRST (&msg->exchange->sa_list); 596 597 sa_remove (sa); 598 GET_ISAKMP_HDR_RCOOKIE (msg->iov[0].iov_base, 599 sa->cookies + ISAKMP_HDR_ICOOKIE_LEN); 600 601 /* 602 * We don't install a transport in the initiator case as we don't know 603 * what local address will be chosen. Do it now instead. 604 */ 605 sa->transport = msg->transport; 606 transport_reference (sa->transport); 607 sa_enter (sa); 608 } 609 610 /* 611 * Register the chosen transform XF into SA. As a side effect set PROTOP 612 * to point at the corresponding proto structure. INITIATOR is true if we 613 * are the initiator. 614 */ 615 int 616 sa_add_transform (struct sa *sa, struct payload *xf, int initiator, 617 struct proto **protop) 618 { 619 struct proto *proto; 620 struct payload *prop = xf->context; 621 622 *protop = 0; 623 if (!initiator) 624 { 625 proto = calloc (1, sizeof *proto); 626 if (!proto) 627 log_error ("sa_add_transform: calloc (1, %d) failed", sizeof *proto); 628 } 629 else 630 /* Find the protection suite that were chosen. */ 631 for (proto = TAILQ_FIRST (&sa->protos); 632 proto && proto->no != GET_ISAKMP_PROP_NO (prop->p); 633 proto = TAILQ_NEXT (proto, link)) 634 ; 635 if (!proto) 636 return -1; 637 *protop = proto; 638 639 /* Allocate DOI-specific part. */ 640 if (!initiator) 641 { 642 proto->data = calloc (1, sa->doi->proto_size); 643 if (!proto->data) 644 { 645 log_error ("sa_add_transform: calloc (1, %d) failed", 646 sa->doi->proto_size); 647 goto cleanup; 648 } 649 } 650 651 proto->no = GET_ISAKMP_PROP_NO (prop->p); 652 proto->proto = GET_ISAKMP_PROP_PROTO (prop->p); 653 proto->spi_sz[0] = GET_ISAKMP_PROP_SPI_SZ (prop->p); 654 if (proto->spi_sz[0]) 655 { 656 proto->spi[0] = malloc (proto->spi_sz[0]); 657 if (!proto->spi[0]) 658 goto cleanup; 659 memcpy (proto->spi[0], prop->p + ISAKMP_PROP_SPI_OFF, proto->spi_sz[0]); 660 } 661 proto->chosen = xf; 662 proto->sa = sa; 663 proto->id = GET_ISAKMP_TRANSFORM_ID (xf->p); 664 if (!initiator) 665 TAILQ_INSERT_TAIL (&sa->protos, proto, link); 666 667 /* Let the DOI get at proto for initializing its own data. */ 668 if (sa->doi->proto_init) 669 sa->doi->proto_init (proto, 0); 670 671 LOG_DBG ((LOG_SA, 80, 672 "sa_add_transform: " 673 "proto %p no %d proto %d chosen %p sa %p id %d", 674 proto, proto->no, proto->proto, proto->chosen, proto->sa, 675 proto->id)); 676 677 return 0; 678 679 cleanup: 680 if (!initiator) 681 { 682 if (proto->data) 683 free (proto->data); 684 free (proto); 685 } 686 *protop = 0; 687 return -1; 688 } 689 690 /* Delete an SA. Tell the peer if NOTIFY is set. */ 691 void 692 sa_delete (struct sa *sa, int notify) 693 { 694 /* Don't bother notifying of Phase 1 SA deletes. */ 695 if (sa->phase != 1 && notify) 696 message_send_delete (sa); 697 sa_free (sa); 698 } 699 700 /* 701 * This function will get called when we are closing in on the death time of SA 702 */ 703 static void 704 sa_soft_expire (void *v_sa) 705 { 706 struct sa *sa = v_sa; 707 708 sa->soft_death = 0; 709 sa_release (sa); 710 711 if ((sa->flags & (SA_FLAG_STAYALIVE | SA_FLAG_REPLACED)) 712 == SA_FLAG_STAYALIVE) 713 exchange_establish (sa->name, 0, 0); 714 else 715 /* 716 * Start to watch the use of this SA, so a renegotiation can 717 * happen as soon as it is shown to be alive. 718 */ 719 sa->flags |= SA_FLAG_FADING; 720 } 721 722 /* SA has passed its best before date. */ 723 static void 724 sa_hard_expire (void *v_sa) 725 { 726 struct sa *sa = v_sa; 727 728 sa->death = 0; 729 sa_release (sa); 730 731 if ((sa->flags & (SA_FLAG_STAYALIVE | SA_FLAG_REPLACED)) 732 == SA_FLAG_STAYALIVE) 733 exchange_establish (sa->name, 0, 0); 734 735 sa_delete (sa, 1); 736 } 737 738 /* 739 * Get an SA attribute's flag value out of textual description. 740 */ 741 int 742 sa_flag (char *attr) 743 { 744 static struct sa_flag_map { 745 char *name; 746 int flag; 747 } sa_flag_map[] = { 748 { "active-only", SA_FLAG_ACTIVE_ONLY }, 749 /* Below this point are flags that are internal to the implementation. */ 750 { "__ondemand", SA_FLAG_ONDEMAND } 751 }; 752 int i; 753 754 for (i = 0; i < sizeof sa_flag_map / sizeof sa_flag_map[0]; i++) 755 if (strcasecmp (attr, sa_flag_map[i].name) == 0) 756 return sa_flag_map[i].flag; 757 log_print ("sa_flag: attribute \"%s\" unknown", attr); 758 return 0; 759 } 760 761 /* Mark SA as replaced. */ 762 void 763 sa_mark_replaced (struct sa *sa) 764 { 765 LOG_DBG ((LOG_SA, 60, "sa_mark_replaced: SA %p (%s) marked as replaced", 766 sa, sa->name ? sa->name : "unnamed")); 767 sa->flags |= SA_FLAG_REPLACED; 768 } 769 770 /* 771 * Setup expiration timers for SA. This is used for ISAKMP SAs, but also 772 * possible to use for application SAs if the application does not deal 773 * with expirations itself. An example is the Linux FreeS/WAN KLIPS IPsec 774 * stack. 775 */ 776 int 777 sa_setup_expirations (struct sa *sa) 778 { 779 u_int64_t seconds = sa->seconds; 780 struct timeval expiration; 781 782 /* 783 * Set the soft timeout to a random percentage between 85 & 95 of 784 * the negotiated lifetime to break strictly synchronized 785 * renegotiations. This works better when the randomization is on the 786 * order of processing plus network-roundtrip times, or larger. 787 * I.e. it depends on configuration and negotiated lifetimes. 788 * It is not good to do the decrease on the hard timeout, because then 789 * we may drop our SA before our peer. 790 * XXX Better scheme to come? 791 */ 792 if (!sa->soft_death) 793 { 794 gettimeofday (&expiration, 0); 795 /* XXX This should probably be configuration controlled somehow. */ 796 seconds = sa->seconds * (850 + sysdep_random () % 100) / 1000; 797 LOG_DBG ((LOG_TIMER, 95, 798 "sa_setup_expirations: SA %p soft timeout in %llu seconds", 799 sa, seconds)); 800 expiration.tv_sec += seconds; 801 sa->soft_death 802 = timer_add_event ("sa_soft_expire", sa_soft_expire, sa, &expiration); 803 if (!sa->soft_death) 804 { 805 /* If we don't give up we might start leaking... */ 806 sa_delete (sa, 1); 807 return -1; 808 } 809 sa_reference (sa); 810 } 811 812 if (!sa->death) 813 { 814 gettimeofday (&expiration, 0); 815 LOG_DBG ((LOG_TIMER, 95, 816 "sa_setup_expirations: SA %p hard timeout in %llu seconds", 817 sa, sa->seconds)); 818 expiration.tv_sec += sa->seconds; 819 sa->death 820 = timer_add_event ("sa_hard_expire", sa_hard_expire, sa, &expiration); 821 if (!sa->death) 822 { 823 /* If we don't give up we might start leaking... */ 824 sa_delete (sa, 1); 825 return -1; 826 } 827 sa_reference (sa); 828 } 829 return 0; 830 } 831