1 /* $NetBSD: isakmp_inf.c,v 1.53 2018/05/19 19:47:47 maxv Exp $ */ 2 3 /* Id: isakmp_inf.c,v 1.44 2006/05/06 20:45:52 manubsd Exp */ 4 5 /* 6 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. Neither the name of the project nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34 #include "config.h" 35 36 #include <sys/types.h> 37 #include <sys/param.h> 38 #include <sys/socket.h> 39 40 #include <net/pfkeyv2.h> 41 #include <netinet/in.h> 42 #include <sys/queue.h> 43 #include PATH_IPSEC_H 44 45 #include <stdlib.h> 46 #include <stdio.h> 47 #include <string.h> 48 #include <errno.h> 49 #if TIME_WITH_SYS_TIME 50 # include <sys/time.h> 51 # include <time.h> 52 #else 53 # if HAVE_SYS_TIME_H 54 # include <sys/time.h> 55 # else 56 # include <time.h> 57 # endif 58 #endif 59 #ifdef ENABLE_HYBRID 60 #include <resolv.h> 61 #endif 62 63 #include "libpfkey.h" 64 65 #include "var.h" 66 #include "vmbuf.h" 67 #include "schedule.h" 68 #include "str2val.h" 69 #include "misc.h" 70 #include "plog.h" 71 #include "debug.h" 72 73 #include "localconf.h" 74 #include "remoteconf.h" 75 #include "sockmisc.h" 76 #include "handler.h" 77 #include "policy.h" 78 #include "proposal.h" 79 #include "isakmp_var.h" 80 #include "evt.h" 81 #include "isakmp.h" 82 #ifdef ENABLE_HYBRID 83 #include "isakmp_xauth.h" 84 #include "isakmp_unity.h" 85 #include "isakmp_cfg.h" 86 #endif 87 #include "isakmp_inf.h" 88 #include "oakley.h" 89 #include "ipsec_doi.h" 90 #include "crypto_openssl.h" 91 #include "pfkey.h" 92 #include "policy.h" 93 #include "algorithm.h" 94 #include "proposal.h" 95 #include "admin.h" 96 #include "strnames.h" 97 #ifdef ENABLE_NATT 98 #include "nattraversal.h" 99 #endif 100 101 /* information exchange */ 102 static int isakmp_info_recv_n (struct ph1handle *, struct isakmp_pl_n *, u_int32_t, int); 103 static int isakmp_info_recv_d (struct ph1handle *, struct isakmp_pl_d *, u_int32_t, int); 104 105 #ifdef ENABLE_DPD 106 static int isakmp_info_recv_r_u __P((struct ph1handle *, 107 struct isakmp_pl_ru *, u_int32_t)); 108 static int isakmp_info_recv_r_u_ack __P((struct ph1handle *, 109 struct isakmp_pl_ru *, u_int32_t)); 110 static void isakmp_info_send_r_u __P((struct sched *)); 111 #endif 112 113 /* %%% 114 * Information Exchange 115 */ 116 /* 117 * receive Information 118 */ 119 int 120 isakmp_info_recv(iph1, msg0) 121 struct ph1handle *iph1; 122 vchar_t *msg0; 123 { 124 vchar_t *msg = NULL; 125 vchar_t *pbuf = NULL; 126 u_int32_t msgid = 0; 127 int error = -1; 128 struct isakmp *isakmp; 129 struct isakmp_gen *gen; 130 struct isakmp_parse_t *pa; 131 void *p; 132 vchar_t *hash, *payload; 133 struct isakmp_gen *nd; 134 u_int8_t np; 135 int encrypted; 136 137 plog(LLV_DEBUG, LOCATION, NULL, "receive Information.\n"); 138 139 encrypted = ISSET(((struct isakmp *)msg0->v)->flags, ISAKMP_FLAG_E); 140 msgid = ((struct isakmp *)msg0->v)->msgid; 141 142 /* Use new IV to decrypt Informational message. */ 143 if (encrypted) { 144 struct isakmp_ivm *ivm; 145 146 if (iph1->ivm == NULL) { 147 plog(LLV_ERROR, LOCATION, NULL, "iph1->ivm == NULL\n"); 148 return -1; 149 } 150 151 /* compute IV */ 152 ivm = oakley_newiv2(iph1, ((struct isakmp *)msg0->v)->msgid); 153 if (ivm == NULL) 154 return -1; 155 156 msg = oakley_do_decrypt(iph1, msg0, ivm->iv, ivm->ive); 157 oakley_delivm(ivm); 158 if (msg == NULL) 159 return -1; 160 161 } else 162 msg = vdup(msg0); 163 164 /* Safety check */ 165 if (msg->l < sizeof(*isakmp) + sizeof(*gen)) { 166 plog(LLV_ERROR, LOCATION, NULL, 167 "ignore information because the " 168 "message is way too short - %zu byte(s).\n", 169 msg->l); 170 goto end; 171 } 172 173 isakmp = (struct isakmp *)msg->v; 174 gen = (struct isakmp_gen *)((caddr_t)isakmp + sizeof(struct isakmp)); 175 np = gen->np; 176 177 if (encrypted) { 178 if (isakmp->np != ISAKMP_NPTYPE_HASH) { 179 plog(LLV_ERROR, LOCATION, NULL, 180 "ignore information because the " 181 "message has no hash payload.\n"); 182 goto end; 183 } 184 185 if (iph1->status != PHASE1ST_ESTABLISHED && 186 iph1->status != PHASE1ST_DYING) { 187 plog(LLV_ERROR, LOCATION, NULL, 188 "ignore information because ISAKMP-SA " 189 "has not been established yet.\n"); 190 goto end; 191 } 192 193 /* Safety check */ 194 if (msg->l < sizeof(*isakmp) + ntohs(gen->len) + sizeof(*nd)) { 195 plog(LLV_ERROR, LOCATION, NULL, 196 "ignore information because the " 197 "message is too short - %zu byte(s).\n", 198 msg->l); 199 goto end; 200 } 201 202 p = (caddr_t) gen + sizeof(struct isakmp_gen); 203 nd = (struct isakmp_gen *) ((caddr_t) gen + ntohs(gen->len)); 204 205 /* nd length check */ 206 if (ntohs(nd->len) > msg->l - (sizeof(struct isakmp) + 207 ntohs(gen->len))) { 208 plog(LLV_ERROR, LOCATION, NULL, 209 "too long payload length (broken message?)\n"); 210 goto end; 211 } 212 213 if (ntohs(nd->len) < sizeof(*nd)) { 214 plog(LLV_ERROR, LOCATION, NULL, 215 "too short payload length (broken message?)\n"); 216 goto end; 217 } 218 219 payload = vmalloc(ntohs(nd->len)); 220 if (payload == NULL) { 221 plog(LLV_ERROR, LOCATION, NULL, 222 "cannot allocate memory\n"); 223 goto end; 224 } 225 226 memcpy(payload->v, (caddr_t) nd, ntohs(nd->len)); 227 228 /* compute HASH */ 229 hash = oakley_compute_hash1(iph1, isakmp->msgid, payload); 230 if (hash == NULL) { 231 plog(LLV_ERROR, LOCATION, NULL, 232 "cannot compute hash\n"); 233 234 vfree(payload); 235 goto end; 236 } 237 238 if (ntohs(gen->len) - sizeof(struct isakmp_gen) != hash->l) { 239 plog(LLV_ERROR, LOCATION, NULL, 240 "ignore information due to hash length mismatch\n"); 241 242 vfree(hash); 243 vfree(payload); 244 goto end; 245 } 246 247 if (memcmp(p, hash->v, hash->l) != 0) { 248 plog(LLV_ERROR, LOCATION, NULL, 249 "ignore information due to hash mismatch\n"); 250 251 vfree(hash); 252 vfree(payload); 253 goto end; 254 } 255 256 plog(LLV_DEBUG, LOCATION, NULL, "hash validated.\n"); 257 258 vfree(hash); 259 vfree(payload); 260 } else { 261 /* make sure the packet was encrypted after the beginning of phase 1. */ 262 switch (iph1->etype) { 263 case ISAKMP_ETYPE_AGG: 264 case ISAKMP_ETYPE_BASE: 265 case ISAKMP_ETYPE_IDENT: 266 if ((iph1->side == INITIATOR && iph1->status < PHASE1ST_MSG3SENT) 267 || (iph1->side == RESPONDER && iph1->status < PHASE1ST_MSG2SENT)) { 268 break; 269 } 270 /*FALLTHRU*/ 271 default: 272 plog(LLV_ERROR, LOCATION, iph1->remote, 273 "%s message must be encrypted\n", 274 s_isakmp_nptype(np)); 275 error = 0; 276 goto end; 277 } 278 } 279 280 if (!(pbuf = isakmp_parse(msg))) { 281 error = -1; 282 goto end; 283 } 284 285 error = 0; 286 for (pa = (struct isakmp_parse_t *)pbuf->v; pa->type; pa++) { 287 switch (pa->type) { 288 case ISAKMP_NPTYPE_HASH: 289 /* Handled above */ 290 break; 291 case ISAKMP_NPTYPE_N: 292 error = isakmp_info_recv_n(iph1, 293 (struct isakmp_pl_n *)pa->ptr, 294 msgid, encrypted); 295 break; 296 case ISAKMP_NPTYPE_D: 297 error = isakmp_info_recv_d(iph1, 298 (struct isakmp_pl_d *)pa->ptr, 299 msgid, encrypted); 300 break; 301 case ISAKMP_NPTYPE_NONCE: 302 /* XXX to be 6.4.2 ike-01.txt */ 303 /* XXX IV is to be synchronized. */ 304 plog(LLV_ERROR, LOCATION, iph1->remote, 305 "ignore Acknowledged Informational\n"); 306 break; 307 default: 308 /* don't send information, see isakmp_ident_r1() */ 309 error = 0; 310 plog(LLV_ERROR, LOCATION, iph1->remote, 311 "reject the packet, " 312 "received unexpected payload type %s.\n", 313 s_isakmp_nptype(gen->np)); 314 } 315 if (error < 0) 316 break; 317 } 318 end: 319 if (msg != NULL) 320 vfree(msg); 321 if (pbuf != NULL) 322 vfree(pbuf); 323 return error; 324 } 325 326 327 /* 328 * log unhandled / unallowed Notification payload 329 */ 330 int 331 isakmp_log_notify(iph1, notify, exchange) 332 struct ph1handle *iph1; 333 struct isakmp_pl_n *notify; 334 const char *exchange; 335 { 336 u_int type; 337 char *nraw, *ndata, *nhex; 338 size_t l; 339 340 type = ntohs(notify->type); 341 if (ntohs(notify->h.len) < sizeof(*notify) + notify->spi_size) { 342 plog(LLV_ERROR, LOCATION, iph1->remote, 343 "invalid spi_size in %s notification in %s.\n", 344 s_isakmp_notify_msg(type), exchange); 345 return -1; 346 } 347 348 plog(LLV_ERROR, LOCATION, iph1->remote, 349 "notification %s received in %s.\n", 350 s_isakmp_notify_msg(type), exchange); 351 352 nraw = ((char*) notify) + sizeof(*notify) + notify->spi_size; 353 l = ntohs(notify->h.len) - sizeof(*notify) - notify->spi_size; 354 if (l > 0) { 355 if (type >= ISAKMP_NTYPE_MINERROR && 356 type <= ISAKMP_NTYPE_MAXERROR) { 357 ndata = binsanitize(nraw, l); 358 if (ndata != NULL) { 359 plog(LLV_ERROR, LOCATION, iph1->remote, 360 "error message: '%s'.\n", 361 ndata); 362 racoon_free(ndata); 363 } else { 364 plog(LLV_ERROR, LOCATION, iph1->remote, 365 "Cannot allocate memory\n"); 366 } 367 } else { 368 nhex = val2str(nraw, l); 369 if (nhex != NULL) { 370 plog(LLV_ERROR, LOCATION, iph1->remote, 371 "notification payload: %s.\n", 372 nhex); 373 racoon_free(nhex); 374 } else { 375 plog(LLV_ERROR, LOCATION, iph1->remote, 376 "Cannot allocate memory\n"); 377 } 378 } 379 } 380 381 return 0; 382 } 383 384 385 /* 386 * handling of Notification payload 387 */ 388 static int 389 isakmp_info_recv_n(iph1, notify, msgid, encrypted) 390 struct ph1handle *iph1; 391 struct isakmp_pl_n *notify; 392 u_int32_t msgid; 393 int encrypted; 394 { 395 u_int type; 396 397 type = ntohs(notify->type); 398 switch (type) { 399 case ISAKMP_NTYPE_CONNECTED: 400 case ISAKMP_NTYPE_RESPONDER_LIFETIME: 401 case ISAKMP_NTYPE_REPLAY_STATUS: 402 #ifdef ENABLE_HYBRID 403 case ISAKMP_NTYPE_UNITY_HEARTBEAT: 404 #endif 405 /* do something */ 406 break; 407 case ISAKMP_NTYPE_INITIAL_CONTACT: 408 if (encrypted) 409 return isakmp_info_recv_initialcontact(iph1, NULL); 410 break; 411 #ifdef ENABLE_DPD 412 case ISAKMP_NTYPE_R_U_THERE: 413 if (encrypted) 414 return isakmp_info_recv_r_u(iph1, 415 (struct isakmp_pl_ru *)notify, msgid); 416 break; 417 case ISAKMP_NTYPE_R_U_THERE_ACK: 418 if (encrypted) 419 return isakmp_info_recv_r_u_ack(iph1, 420 (struct isakmp_pl_ru *)notify, msgid); 421 break; 422 #endif 423 } 424 425 /* If we receive a error notification we should delete the related 426 * phase1 / phase2 handle, and send an event to racoonctl. 427 * However, since phase1 error notifications are not encrypted and 428 * can not be authenticated, it would allow a DoS attack possibility 429 * to handle them. 430 * Phase2 error notifications should be encrypted, so we could handle 431 * those, but it needs implementing (the old code didn't implement 432 * that either). 433 * So we are good to just log the messages here. 434 */ 435 if (encrypted) 436 isakmp_log_notify(iph1, notify, "informational exchange"); 437 else 438 isakmp_log_notify(iph1, notify, "unencrypted informational exchange"); 439 440 return 0; 441 } 442 443 /* 444 * handling of Deletion payload 445 */ 446 static int 447 isakmp_info_recv_d(iph1, delete, msgid, encrypted) 448 struct ph1handle *iph1; 449 struct isakmp_pl_d *delete; 450 u_int32_t msgid; 451 int encrypted; 452 { 453 int tlen, num_spi; 454 struct ph1handle *del_ph1; 455 union { 456 u_int32_t spi32; 457 u_int16_t spi16[2]; 458 } spi; 459 460 if (ntohl(delete->doi) != IPSEC_DOI) { 461 plog(LLV_ERROR, LOCATION, iph1->remote, 462 "delete payload with invalid doi:%d.\n", 463 ntohl(delete->doi)); 464 #ifdef ENABLE_HYBRID 465 /* 466 * At deconnexion time, Cisco VPN client does this 467 * with a zero DOI. Don't give up in that situation. 468 */ 469 if (((iph1->mode_cfg->flags & 470 ISAKMP_CFG_VENDORID_UNITY) == 0) || (delete->doi != 0)) 471 return 0; 472 #else 473 return 0; 474 #endif 475 } 476 477 num_spi = ntohs(delete->num_spi); 478 tlen = ntohs(delete->h.len) - sizeof(struct isakmp_pl_d); 479 480 if (tlen != num_spi * delete->spi_size) { 481 plog(LLV_ERROR, LOCATION, iph1->remote, 482 "deletion payload with invalid length.\n"); 483 return 0; 484 } 485 486 plog(LLV_DEBUG, LOCATION, iph1->remote, 487 "delete payload for protocol %s\n", 488 s_ipsecdoi_proto(delete->proto_id)); 489 490 if((iph1 == NULL || !iph1->rmconf->weak_phase1_check) && !encrypted) { 491 plog(LLV_WARNING, LOCATION, iph1->remote, 492 "Ignoring unencrypted delete payload " 493 "(check the weak_phase1_check option)\n"); 494 return 0; 495 } 496 497 switch (delete->proto_id) { 498 case IPSECDOI_PROTO_ISAKMP: 499 if (delete->spi_size != sizeof(isakmp_index)) { 500 plog(LLV_ERROR, LOCATION, iph1->remote, 501 "delete payload with strange spi " 502 "size %d(proto_id:%d)\n", 503 delete->spi_size, delete->proto_id); 504 return 0; 505 } 506 507 del_ph1=getph1byindex((isakmp_index *)(delete + 1)); 508 if(del_ph1 != NULL){ 509 510 evt_phase1(iph1, EVT_PHASE1_PEER_DELETED, NULL); 511 sched_cancel(&del_ph1->scr); 512 513 /* 514 * Delete also IPsec-SAs if rekeying is enabled. 515 */ 516 if (ph1_rekey_enabled(del_ph1)) 517 purge_remote(del_ph1); 518 else 519 isakmp_ph1expire(del_ph1); 520 } 521 break; 522 523 case IPSECDOI_PROTO_IPSEC_AH: 524 case IPSECDOI_PROTO_IPSEC_ESP: 525 if (delete->spi_size != sizeof(u_int32_t)) { 526 plog(LLV_ERROR, LOCATION, iph1->remote, 527 "delete payload with strange spi " 528 "size %d(proto_id:%d)\n", 529 delete->spi_size, delete->proto_id); 530 return 0; 531 } 532 purge_ipsec_spi(iph1->remote, delete->proto_id, 533 (u_int32_t *)(delete + 1), num_spi); 534 break; 535 536 case IPSECDOI_PROTO_IPCOMP: 537 /* need to handle both 16bit/32bit SPI */ 538 memset(&spi, 0, sizeof(spi)); 539 if (delete->spi_size == sizeof(spi.spi16[1])) { 540 memcpy(&spi.spi16[1], delete + 1, 541 sizeof(spi.spi16[1])); 542 } else if (delete->spi_size == sizeof(spi.spi32)) 543 memcpy(&spi.spi32, delete + 1, sizeof(spi.spi32)); 544 else { 545 plog(LLV_ERROR, LOCATION, iph1->remote, 546 "delete payload with strange spi " 547 "size %d(proto_id:%d)\n", 548 delete->spi_size, delete->proto_id); 549 return 0; 550 } 551 purge_ipsec_spi(iph1->remote, delete->proto_id, 552 &spi.spi32, num_spi); 553 break; 554 555 default: 556 plog(LLV_ERROR, LOCATION, iph1->remote, 557 "deletion message received, " 558 "invalid proto_id: %d\n", 559 delete->proto_id); 560 return 0; 561 } 562 563 plog(LLV_DEBUG, LOCATION, NULL, "purged SAs.\n"); 564 565 return 0; 566 } 567 568 /* 569 * send Delete payload (for ISAKMP SA) in Informational exchange. 570 */ 571 int 572 isakmp_info_send_d1(iph1) 573 struct ph1handle *iph1; 574 { 575 struct isakmp_pl_d *d; 576 vchar_t *payload = NULL; 577 int tlen; 578 int error = 0; 579 580 if (iph1->status != PHASE2ST_ESTABLISHED) 581 return 0; 582 583 /* create delete payload */ 584 585 /* send SPIs of inbound SAs. */ 586 /* XXX should send outbound SAs's ? */ 587 tlen = sizeof(*d) + sizeof(isakmp_index); 588 payload = vmalloc(tlen); 589 if (payload == NULL) { 590 plog(LLV_ERROR, LOCATION, NULL, 591 "failed to get buffer for payload.\n"); 592 return errno; 593 } 594 595 d = (struct isakmp_pl_d *)payload->v; 596 d->h.np = ISAKMP_NPTYPE_NONE; 597 d->h.len = htons(tlen); 598 d->doi = htonl(IPSEC_DOI); 599 d->proto_id = IPSECDOI_PROTO_ISAKMP; 600 d->spi_size = sizeof(isakmp_index); 601 d->num_spi = htons(1); 602 memcpy(d + 1, &iph1->index, sizeof(isakmp_index)); 603 604 error = isakmp_info_send_common(iph1, payload, 605 ISAKMP_NPTYPE_D, 0); 606 vfree(payload); 607 608 return error; 609 } 610 611 /* 612 * send Delete payload (for IPsec SA) in Informational exchange, based on 613 * pfkey msg. It sends always single SPI. 614 */ 615 int 616 isakmp_info_send_d2(iph2) 617 struct ph2handle *iph2; 618 { 619 struct ph1handle *iph1; 620 struct saproto *pr; 621 struct isakmp_pl_d *d; 622 vchar_t *payload = NULL; 623 int tlen; 624 int error = 0; 625 u_int8_t *spi; 626 627 if (iph2->status != PHASE2ST_ESTABLISHED) 628 return 0; 629 630 /* 631 * don't send delete information if there is no phase 1 handler. 632 * It's nonsensical to negotiate phase 1 to send the information. 633 */ 634 iph1 = getph1byaddr(iph2->src, iph2->dst, 0); 635 if (iph1 == NULL){ 636 plog(LLV_DEBUG2, LOCATION, NULL, 637 "No ph1 handler found, could not send DELETE_SA\n"); 638 return 0; 639 } 640 641 /* create delete payload */ 642 for (pr = iph2->approval->head; pr != NULL; pr = pr->next) { 643 644 /* send SPIs of inbound SAs. */ 645 /* 646 * XXX should I send outbound SAs's ? 647 * I send inbound SAs's SPI only at the moment because I can't 648 * decode any more if peer send encoded packet without aware of 649 * deletion of SA. Outbound SAs don't come under the situation. 650 */ 651 tlen = sizeof(*d) + pr->spisize; 652 payload = vmalloc(tlen); 653 if (payload == NULL) { 654 plog(LLV_ERROR, LOCATION, NULL, 655 "failed to get buffer for payload.\n"); 656 return errno; 657 } 658 659 d = (struct isakmp_pl_d *)payload->v; 660 d->h.np = ISAKMP_NPTYPE_NONE; 661 d->h.len = htons(tlen); 662 d->doi = htonl(IPSEC_DOI); 663 d->proto_id = pr->proto_id; 664 d->spi_size = pr->spisize; 665 d->num_spi = htons(1); 666 /* 667 * XXX SPI bits are left-filled, for use with IPComp. 668 * we should be switching to variable-length spi field... 669 */ 670 spi = (u_int8_t *)&pr->spi; 671 spi += sizeof(pr->spi); 672 spi -= pr->spisize; 673 memcpy(d + 1, spi, pr->spisize); 674 675 error = isakmp_info_send_common(iph1, payload, 676 ISAKMP_NPTYPE_D, 0); 677 vfree(payload); 678 } 679 680 return error; 681 } 682 683 /* 684 * send Notification payload (for without ISAKMP SA) in Informational exchange 685 */ 686 int 687 isakmp_info_send_nx(isakmp, remote, local, type, data) 688 struct isakmp *isakmp; 689 struct sockaddr *remote, *local; 690 int type; 691 vchar_t *data; 692 { 693 struct ph1handle *iph1 = NULL; 694 vchar_t *payload = NULL; 695 int tlen; 696 int error = -1; 697 struct isakmp_pl_n *n; 698 int spisiz = 0; /* see below */ 699 700 /* add new entry to isakmp status table. */ 701 iph1 = newph1(); 702 if (iph1 == NULL) 703 return -1; 704 705 memcpy(&iph1->index.i_ck, &isakmp->i_ck, sizeof(cookie_t)); 706 isakmp_newcookie((char *)&iph1->index.r_ck, remote, local); 707 iph1->status = PHASE1ST_START; 708 iph1->side = INITIATOR; 709 iph1->version = isakmp->v; 710 iph1->flags = 0; 711 iph1->msgid = 0; /* XXX */ 712 #ifdef ENABLE_HYBRID 713 if ((iph1->mode_cfg = isakmp_cfg_mkstate()) == NULL) 714 goto end; 715 #endif 716 #ifdef ENABLE_FRAG 717 iph1->frag = 0; 718 iph1->frag_last_index = 0; 719 iph1->frag_chain = NULL; 720 #endif 721 722 /* copy remote address */ 723 if (copy_ph1addresses(iph1, NULL, remote, local) < 0) 724 goto end; 725 726 tlen = sizeof(*n) + spisiz; 727 if (data) 728 tlen += data->l; 729 payload = vmalloc(tlen); 730 if (payload == NULL) { 731 plog(LLV_ERROR, LOCATION, NULL, 732 "failed to get buffer to send.\n"); 733 goto end; 734 } 735 736 n = (struct isakmp_pl_n *)payload->v; 737 n->h.np = ISAKMP_NPTYPE_NONE; 738 n->h.len = htons(tlen); 739 n->doi = htonl(IPSEC_DOI); 740 n->proto_id = IPSECDOI_KEY_IKE; 741 n->spi_size = spisiz; 742 n->type = htons(type); 743 if (spisiz) 744 memset(n + 1, 0, spisiz); /* XXX spisiz is always 0 */ 745 if (data) 746 memcpy((caddr_t)(n + 1) + spisiz, data->v, data->l); 747 748 error = isakmp_info_send_common(iph1, payload, ISAKMP_NPTYPE_N, 0); 749 vfree(payload); 750 751 end: 752 if (iph1 != NULL) 753 delph1(iph1); 754 755 return error; 756 } 757 758 /* 759 * send Notification payload (for ISAKMP SA) in Informational exchange 760 */ 761 int 762 isakmp_info_send_n1(iph1, type, data) 763 struct ph1handle *iph1; 764 int type; 765 vchar_t *data; 766 { 767 vchar_t *payload = NULL; 768 int tlen; 769 int error = 0; 770 struct isakmp_pl_n *n; 771 int spisiz; 772 773 /* 774 * note on SPI size: which description is correct? I have chosen 775 * this to be 0. 776 * 777 * RFC2408 3.1, 2nd paragraph says: ISAKMP SA is identified by 778 * Initiator/Responder cookie and SPI has no meaning, SPI size = 0. 779 * RFC2408 3.1, first paragraph on page 40: ISAKMP SA is identified 780 * by cookie and SPI has no meaning, 0 <= SPI size <= 16. 781 * RFC2407 4.6.3.3, INITIAL-CONTACT is required to set to 16. 782 */ 783 if (type == ISAKMP_NTYPE_INITIAL_CONTACT) 784 spisiz = sizeof(isakmp_index); 785 else 786 spisiz = 0; 787 788 tlen = sizeof(*n) + spisiz; 789 if (data) 790 tlen += data->l; 791 payload = vmalloc(tlen); 792 if (payload == NULL) { 793 plog(LLV_ERROR, LOCATION, NULL, 794 "failed to get buffer to send.\n"); 795 return errno; 796 } 797 798 n = (struct isakmp_pl_n *)payload->v; 799 n->h.np = ISAKMP_NPTYPE_NONE; 800 n->h.len = htons(tlen); 801 n->doi = htonl(iph1->rmconf->doitype); 802 n->proto_id = IPSECDOI_PROTO_ISAKMP; /* XXX to be configurable ? */ 803 n->spi_size = spisiz; 804 n->type = htons(type); 805 if (spisiz) 806 memcpy(n + 1, &iph1->index, sizeof(isakmp_index)); 807 if (data) 808 memcpy((caddr_t)(n + 1) + spisiz, data->v, data->l); 809 810 error = isakmp_info_send_common(iph1, payload, ISAKMP_NPTYPE_N, iph1->flags); 811 vfree(payload); 812 813 return error; 814 } 815 816 /* 817 * send Notification payload (for IPsec SA) in Informational exchange 818 */ 819 int 820 isakmp_info_send_n2(iph2, type, data) 821 struct ph2handle *iph2; 822 int type; 823 vchar_t *data; 824 { 825 struct ph1handle *iph1 = iph2->ph1; 826 vchar_t *payload = NULL; 827 int tlen; 828 int error = 0; 829 struct isakmp_pl_n *n; 830 struct saproto *pr; 831 832 if (!iph2->approval) 833 return EINVAL; 834 835 pr = iph2->approval->head; 836 837 /* XXX must be get proper spi */ 838 tlen = sizeof(*n) + pr->spisize; 839 if (data) 840 tlen += data->l; 841 payload = vmalloc(tlen); 842 if (payload == NULL) { 843 plog(LLV_ERROR, LOCATION, NULL, 844 "failed to get buffer to send.\n"); 845 return errno; 846 } 847 848 n = (struct isakmp_pl_n *)payload->v; 849 n->h.np = ISAKMP_NPTYPE_NONE; 850 n->h.len = htons(tlen); 851 n->doi = htonl(IPSEC_DOI); /* IPSEC DOI (1) */ 852 n->proto_id = pr->proto_id; /* IPSEC AH/ESP/whatever*/ 853 n->spi_size = pr->spisize; 854 n->type = htons(type); 855 *(u_int32_t *)(n + 1) = pr->spi; 856 if (data) 857 memcpy((caddr_t)(n + 1) + pr->spisize, data->v, data->l); 858 859 iph2->flags |= ISAKMP_FLAG_E; /* XXX Should we do FLAG_A ? */ 860 error = isakmp_info_send_common(iph1, payload, ISAKMP_NPTYPE_N, iph2->flags); 861 vfree(payload); 862 863 return error; 864 } 865 866 /* 867 * send Information 868 * When ph1->skeyid_a == NULL, send message without encoding. 869 */ 870 int 871 isakmp_info_send_common(iph1, payload, np, flags) 872 struct ph1handle *iph1; 873 vchar_t *payload; 874 u_int32_t np; 875 int flags; 876 { 877 struct ph2handle *iph2 = NULL; 878 vchar_t *hash = NULL; 879 struct isakmp *isakmp; 880 struct isakmp_gen *gen; 881 char *p; 882 int tlen; 883 int error = -1; 884 885 /* add new entry to isakmp status table */ 886 iph2 = newph2(); 887 if (iph2 == NULL) 888 goto end; 889 890 iph2->dst = dupsaddr(iph1->remote); 891 if (iph2->dst == NULL) { 892 delph2(iph2); 893 goto end; 894 } 895 iph2->src = dupsaddr(iph1->local); 896 if (iph2->src == NULL) { 897 delph2(iph2); 898 goto end; 899 } 900 iph2->side = INITIATOR; 901 iph2->status = PHASE2ST_START; 902 iph2->msgid = isakmp_newmsgid2(iph1); 903 904 /* get IV and HASH(1) if skeyid_a was generated. */ 905 if (iph1->skeyid_a != NULL) { 906 iph2->ivm = oakley_newiv2(iph1, iph2->msgid); 907 if (iph2->ivm == NULL) { 908 delph2(iph2); 909 goto end; 910 } 911 912 /* generate HASH(1) */ 913 hash = oakley_compute_hash1(iph1, iph2->msgid, payload); 914 if (hash == NULL) { 915 delph2(iph2); 916 goto end; 917 } 918 919 /* initialized total buffer length */ 920 tlen = hash->l; 921 tlen += sizeof(*gen); 922 } else { 923 /* IKE-SA is not established */ 924 hash = NULL; 925 926 /* initialized total buffer length */ 927 tlen = 0; 928 } 929 if ((flags & ISAKMP_FLAG_A) == 0) 930 iph2->flags = (hash == NULL ? 0 : ISAKMP_FLAG_E); 931 else 932 iph2->flags = (hash == NULL ? 0 : ISAKMP_FLAG_A); 933 934 insph2(iph2); 935 bindph12(iph1, iph2); 936 937 tlen += sizeof(*isakmp) + payload->l; 938 939 /* create buffer for isakmp payload */ 940 iph2->sendbuf = vmalloc(tlen); 941 if (iph2->sendbuf == NULL) { 942 plog(LLV_ERROR, LOCATION, NULL, 943 "failed to get buffer to send.\n"); 944 goto err; 945 } 946 947 /* create isakmp header */ 948 isakmp = (struct isakmp *)iph2->sendbuf->v; 949 memcpy(&isakmp->i_ck, &iph1->index.i_ck, sizeof(cookie_t)); 950 memcpy(&isakmp->r_ck, &iph1->index.r_ck, sizeof(cookie_t)); 951 isakmp->np = hash == NULL ? (np & 0xff) : ISAKMP_NPTYPE_HASH; 952 isakmp->v = iph1->version; 953 isakmp->etype = ISAKMP_ETYPE_INFO; 954 isakmp->flags = iph2->flags; 955 memcpy(&isakmp->msgid, &iph2->msgid, sizeof(isakmp->msgid)); 956 isakmp->len = htonl(tlen); 957 p = (char *)(isakmp + 1); 958 959 /* create HASH payload */ 960 if (hash != NULL) { 961 gen = (struct isakmp_gen *)p; 962 gen->np = np & 0xff; 963 gen->len = htons(sizeof(*gen) + hash->l); 964 p += sizeof(*gen); 965 memcpy(p, hash->v, hash->l); 966 p += hash->l; 967 } 968 969 /* add payload */ 970 memcpy(p, payload->v, payload->l); 971 p += payload->l; 972 973 #ifdef HAVE_PRINT_ISAKMP_C 974 isakmp_printpacket(iph2->sendbuf, iph1->local, iph1->remote, 1); 975 #endif 976 977 /* encoding */ 978 if (ISSET(isakmp->flags, ISAKMP_FLAG_E)) { 979 vchar_t *tmp; 980 981 tmp = oakley_do_encrypt(iph2->ph1, iph2->sendbuf, iph2->ivm->ive, 982 iph2->ivm->iv); 983 VPTRINIT(iph2->sendbuf); 984 if (tmp == NULL) 985 goto err; 986 iph2->sendbuf = tmp; 987 } 988 989 /* HDR*, HASH(1), N */ 990 if (isakmp_send(iph2->ph1, iph2->sendbuf) < 0) { 991 VPTRINIT(iph2->sendbuf); 992 goto err; 993 } 994 995 plog(LLV_DEBUG, LOCATION, NULL, 996 "sendto Information %s.\n", s_isakmp_nptype(np)); 997 998 /* 999 * don't resend notify message because peer can use Acknowledged 1000 * Informational if peer requires the reply of the notify message. 1001 */ 1002 1003 /* XXX If Acknowledged Informational required, don't delete ph2handle */ 1004 error = 0; 1005 VPTRINIT(iph2->sendbuf); 1006 goto err; /* XXX */ 1007 1008 end: 1009 if (hash) 1010 vfree(hash); 1011 return error; 1012 1013 err: 1014 remph2(iph2); 1015 delph2(iph2); 1016 goto end; 1017 } 1018 1019 /* 1020 * add a notify payload to buffer by reallocating buffer. 1021 * If buf == NULL, the function only create a notify payload. 1022 * 1023 * XXX Which is SPI to be included, inbound or outbound ? 1024 */ 1025 vchar_t * 1026 isakmp_add_pl_n(buf0, np_p, type, pr, data) 1027 vchar_t *buf0; 1028 u_int8_t **np_p; 1029 int type; 1030 struct saproto *pr; 1031 vchar_t *data; 1032 { 1033 vchar_t *buf = NULL; 1034 struct isakmp_pl_n *n; 1035 int tlen; 1036 int oldlen = 0; 1037 1038 if (*np_p) 1039 **np_p = ISAKMP_NPTYPE_N; 1040 1041 tlen = sizeof(*n) + pr->spisize; 1042 1043 if (data) 1044 tlen += data->l; 1045 if (buf0) { 1046 oldlen = buf0->l; 1047 buf = vrealloc(buf0, buf0->l + tlen); 1048 } else 1049 buf = vmalloc(tlen); 1050 if (!buf) { 1051 plog(LLV_ERROR, LOCATION, NULL, 1052 "failed to get a payload buffer.\n"); 1053 return NULL; 1054 } 1055 1056 n = (struct isakmp_pl_n *)(buf->v + oldlen); 1057 n->h.np = ISAKMP_NPTYPE_NONE; 1058 n->h.len = htons(tlen); 1059 n->doi = htonl(IPSEC_DOI); /* IPSEC DOI (1) */ 1060 n->proto_id = pr->proto_id; /* IPSEC AH/ESP/whatever*/ 1061 n->spi_size = pr->spisize; 1062 n->type = htons(type); 1063 *(u_int32_t *)(n + 1) = pr->spi; /* XXX */ 1064 if (data) 1065 memcpy((caddr_t)(n + 1) + pr->spisize, data->v, data->l); 1066 1067 /* save the pointer of next payload type */ 1068 *np_p = &n->h.np; 1069 1070 return buf; 1071 } 1072 1073 void 1074 purge_ipsec_spi(dst0, proto, spi, n) 1075 struct sockaddr *dst0; 1076 int proto; 1077 u_int32_t *spi; /*network byteorder*/ 1078 size_t n; 1079 { 1080 vchar_t *buf = NULL; 1081 struct sadb_msg *msg, *next, *end; 1082 struct sadb_sa *sa; 1083 struct sadb_lifetime *lt; 1084 struct sockaddr *src, *dst; 1085 struct ph2handle *iph2; 1086 u_int64_t created; 1087 size_t i; 1088 caddr_t mhp[SADB_EXT_MAX + 1]; 1089 unsigned num_purged = 0; 1090 1091 plog(LLV_DEBUG2, LOCATION, NULL, 1092 "purge_ipsec_spi:\n"); 1093 plog(LLV_DEBUG2, LOCATION, NULL, "dst0: %s\n", saddr2str(dst0)); 1094 plog(LLV_DEBUG2, LOCATION, NULL, "SPI: %08X\n", ntohl(spi[0])); 1095 1096 buf = pfkey_dump_sadb(ipsecdoi2pfkey_proto(proto)); 1097 if (buf == NULL) { 1098 plog(LLV_DEBUG, LOCATION, NULL, 1099 "pfkey_dump_sadb returned nothing.\n"); 1100 return; 1101 } 1102 1103 msg = (struct sadb_msg *)buf->v; 1104 end = (struct sadb_msg *)(buf->v + buf->l); 1105 1106 while (msg < end) { 1107 if ((msg->sadb_msg_len << 3) < sizeof(*msg)) 1108 break; 1109 next = (struct sadb_msg *)((caddr_t)msg + (msg->sadb_msg_len << 3)); 1110 if (msg->sadb_msg_type != SADB_DUMP) { 1111 msg = next; 1112 continue; 1113 } 1114 1115 if (pfkey_align(msg, mhp) || pfkey_check(mhp)) { 1116 plog(LLV_ERROR, LOCATION, NULL, 1117 "pfkey_check (%s)\n", ipsec_strerror()); 1118 msg = next; 1119 continue; 1120 } 1121 1122 sa = (struct sadb_sa *)(mhp[SADB_EXT_SA]); 1123 if (!sa 1124 || !mhp[SADB_EXT_ADDRESS_SRC] 1125 || !mhp[SADB_EXT_ADDRESS_DST]) { 1126 msg = next; 1127 continue; 1128 } 1129 pk_fixup_sa_addresses(mhp); 1130 src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]); 1131 dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]); 1132 lt = (struct sadb_lifetime*)mhp[SADB_EXT_LIFETIME_HARD]; 1133 if(lt != NULL) 1134 created = lt->sadb_lifetime_addtime; 1135 else 1136 created = 0; 1137 1138 if (sa->sadb_sa_state != SADB_SASTATE_MATURE 1139 && sa->sadb_sa_state != SADB_SASTATE_DYING) { 1140 msg = next; 1141 continue; 1142 } 1143 1144 plog(LLV_DEBUG2, LOCATION, NULL, "src: %s\n", saddr2str(src)); 1145 plog(LLV_DEBUG2, LOCATION, NULL, "dst: %s\n", saddr2str(dst)); 1146 plog(LLV_DEBUG2, LOCATION, NULL, "spi: %u\n", ntohl(sa->sadb_sa_spi)); 1147 1148 /* XXX n^2 algorithm, inefficient */ 1149 1150 /* don't delete inbound SAs at the moment */ 1151 /* XXX should we remove SAs with opposite direction as well? */ 1152 if (cmpsaddr(dst0, dst) != CMPSADDR_MATCH) { 1153 msg = next; 1154 continue; 1155 } 1156 1157 for (i = 0; i < n; i++) { 1158 plog(LLV_DEBUG, LOCATION, NULL, 1159 "check spi(packet)=%u spi(db)=%u.\n", 1160 ntohl(spi[i]), ntohl(sa->sadb_sa_spi)); 1161 if (spi[i] != sa->sadb_sa_spi) 1162 continue; 1163 1164 pfkey_send_delete(lcconf->sock_pfkey, 1165 msg->sadb_msg_satype, 1166 IPSEC_MODE_ANY, 1167 src, dst, sa->sadb_sa_spi); 1168 1169 /* 1170 * delete a relative phase 2 handler. 1171 * continue to process if no relative phase 2 handler 1172 * exists. 1173 */ 1174 iph2 = getph2bysaidx(src, dst, proto, spi[i]); 1175 if(iph2 != NULL){ 1176 delete_spd(iph2, created); 1177 remph2(iph2); 1178 delph2(iph2); 1179 } 1180 1181 plog(LLV_INFO, LOCATION, NULL, 1182 "purged IPsec-SA proto_id=%s spi=%u.\n", 1183 s_ipsecdoi_proto(proto), 1184 ntohl(spi[i])); 1185 num_purged++; 1186 } 1187 1188 msg = next; 1189 } 1190 1191 if (buf) 1192 vfree(buf); 1193 1194 plog(LLV_DEBUG, LOCATION, NULL, "purged %u SAs.\n", num_purged); 1195 } 1196 1197 /* 1198 * delete all phase2 sa relatived to the destination address 1199 * (except the phase2 within which the INITIAL-CONTACT was received). 1200 * Don't delete Phase 1 handlers on INITIAL-CONTACT, and don't ignore 1201 * an INITIAL-CONTACT if we have contacted the peer. This matches the 1202 * Sun IKE behavior, and makes rekeying work much better when the peer 1203 * restarts. 1204 */ 1205 int 1206 isakmp_info_recv_initialcontact(iph1, protectedph2) 1207 struct ph1handle *iph1; 1208 struct ph2handle *protectedph2; 1209 { 1210 vchar_t *buf = NULL; 1211 struct sadb_msg *msg, *next, *end; 1212 struct sadb_sa *sa; 1213 struct sockaddr *src, *dst; 1214 caddr_t mhp[SADB_EXT_MAX + 1]; 1215 int proto_id, i; 1216 struct ph2handle *iph2; 1217 #if 0 1218 char *loc, *rem; 1219 #endif 1220 1221 plog(LLV_INFO, LOCATION, iph1->remote, "received INITIAL-CONTACT\n"); 1222 1223 if (f_local) 1224 return 0; 1225 1226 #if 0 1227 loc = racoon_strdup(saddrwop2str(iph1->local)); 1228 rem = racoon_strdup(saddrwop2str(iph1->remote)); 1229 STRDUP_FATAL(loc); 1230 STRDUP_FATAL(rem); 1231 1232 /* 1233 * Purge all IPSEC-SAs for the peer. We can do this 1234 * the easy way (using a PF_KEY SADB_DELETE extension) 1235 * or we can do it the hard way. 1236 */ 1237 for (i = 0; i < pfkey_nsatypes; i++) { 1238 proto_id = pfkey2ipsecdoi_proto(pfkey_satypes[i].ps_satype); 1239 1240 plog(LLV_INFO, LOCATION, NULL, 1241 "purging %s SAs for %s -> %s\n", 1242 pfkey_satypes[i].ps_name, loc, rem); 1243 if (pfkey_send_delete_all(lcconf->sock_pfkey, 1244 pfkey_satypes[i].ps_satype, IPSEC_MODE_ANY, 1245 iph1->local, iph1->remote) == -1) { 1246 plog(LLV_ERROR, LOCATION, NULL, 1247 "delete_all %s -> %s failed for %s (%s)\n", 1248 loc, rem, 1249 pfkey_satypes[i].ps_name, ipsec_strerror()); 1250 goto the_hard_way; 1251 } 1252 1253 deleteallph2(iph1->local, iph1->remote, proto_id); 1254 1255 plog(LLV_INFO, LOCATION, NULL, 1256 "purging %s SAs for %s -> %s\n", 1257 pfkey_satypes[i].ps_name, rem, loc); 1258 if (pfkey_send_delete_all(lcconf->sock_pfkey, 1259 pfkey_satypes[i].ps_satype, IPSEC_MODE_ANY, 1260 iph1->remote, iph1->local) == -1) { 1261 plog(LLV_ERROR, LOCATION, NULL, 1262 "delete_all %s -> %s failed for %s (%s)\n", 1263 rem, loc, 1264 pfkey_satypes[i].ps_name, ipsec_strerror()); 1265 goto the_hard_way; 1266 } 1267 1268 deleteallph2(iph1->remote, iph1->local, proto_id); 1269 } 1270 1271 racoon_free(loc); 1272 racoon_free(rem); 1273 return 0; 1274 1275 the_hard_way: 1276 racoon_free(loc); 1277 racoon_free(rem); 1278 #endif 1279 1280 buf = pfkey_dump_sadb(SADB_SATYPE_UNSPEC); 1281 if (buf == NULL) { 1282 plog(LLV_DEBUG, LOCATION, NULL, 1283 "pfkey_dump_sadb returned nothing.\n"); 1284 return 0; 1285 } 1286 1287 msg = (struct sadb_msg *)buf->v; 1288 end = (struct sadb_msg *)(buf->v + buf->l); 1289 1290 for (; msg < end; msg = next) { 1291 if ((msg->sadb_msg_len << 3) < sizeof(*msg)) 1292 break; 1293 1294 next = (struct sadb_msg *)((caddr_t)msg + (msg->sadb_msg_len << 3)); 1295 if (msg->sadb_msg_type != SADB_DUMP) 1296 continue; 1297 1298 if (pfkey_align(msg, mhp) || pfkey_check(mhp)) { 1299 plog(LLV_ERROR, LOCATION, NULL, 1300 "pfkey_check (%s)\n", ipsec_strerror()); 1301 continue; 1302 } 1303 1304 if (mhp[SADB_EXT_SA] == NULL 1305 || mhp[SADB_EXT_ADDRESS_SRC] == NULL 1306 || mhp[SADB_EXT_ADDRESS_DST] == NULL) 1307 continue; 1308 1309 sa = (struct sadb_sa *)mhp[SADB_EXT_SA]; 1310 pk_fixup_sa_addresses(mhp); 1311 src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]); 1312 dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]); 1313 1314 if (sa->sadb_sa_state != SADB_SASTATE_MATURE 1315 && sa->sadb_sa_state != SADB_SASTATE_DYING) 1316 continue; 1317 1318 /* 1319 * RFC2407 4.6.3.3 INITIAL-CONTACT is the message that 1320 * announces the sender of the message was rebooted. 1321 * it is interpreted to delete all SAs which source address 1322 * is the sender of the message. 1323 * racoon only deletes SA which is matched both the 1324 * source address and the destination accress. 1325 */ 1326 1327 /* 1328 * Check that the IP and port match. But this is not optimal, 1329 * since NAT-T can make the peer have multiple different 1330 * ports. Correct thing to do is delete all entries with 1331 * same identity. -TT 1332 */ 1333 if ((cmpsaddr(iph1->local, src) != CMPSADDR_MATCH || 1334 cmpsaddr(iph1->remote, dst) != CMPSADDR_MATCH) && 1335 (cmpsaddr(iph1->local, dst) != CMPSADDR_MATCH || 1336 cmpsaddr(iph1->remote, src) != CMPSADDR_MATCH)) 1337 continue; 1338 1339 /* 1340 * Make sure this is an SATYPE that we manage. 1341 * This is gross; too bad we couldn't do it the 1342 * easy way. 1343 */ 1344 for (i = 0; i < pfkey_nsatypes; i++) { 1345 if (pfkey_satypes[i].ps_satype == 1346 msg->sadb_msg_satype) 1347 break; 1348 } 1349 if (i == pfkey_nsatypes) 1350 continue; 1351 1352 plog(LLV_INFO, LOCATION, NULL, 1353 "purging spi=%u.\n", ntohl(sa->sadb_sa_spi)); 1354 pfkey_send_delete(lcconf->sock_pfkey, 1355 msg->sadb_msg_satype, 1356 IPSEC_MODE_ANY, src, dst, sa->sadb_sa_spi); 1357 1358 /* 1359 * delete a relative phase 2 handler. 1360 * continue to process if no relative phase 2 handler 1361 * exists. 1362 */ 1363 proto_id = pfkey2ipsecdoi_proto(msg->sadb_msg_satype); 1364 iph2 = getph2bysaidx(src, dst, proto_id, sa->sadb_sa_spi); 1365 if (iph2 && iph2 != protectedph2) { 1366 delete_spd(iph2, 0); 1367 remph2(iph2); 1368 delph2(iph2); 1369 } 1370 } 1371 1372 vfree(buf); 1373 return 0; 1374 } 1375 1376 1377 #ifdef ENABLE_DPD 1378 static int 1379 isakmp_info_recv_r_u (iph1, ru, msgid) 1380 struct ph1handle *iph1; 1381 struct isakmp_pl_ru *ru; 1382 u_int32_t msgid; 1383 { 1384 struct isakmp_pl_ru *ru_ack; 1385 vchar_t *payload = NULL; 1386 int tlen; 1387 int error = 0; 1388 1389 plog(LLV_DEBUG, LOCATION, iph1->remote, 1390 "DPD R-U-There received\n"); 1391 1392 /* XXX should compare cookies with iph1->index? 1393 Or is this already done by calling function? */ 1394 tlen = sizeof(*ru_ack); 1395 payload = vmalloc(tlen); 1396 if (payload == NULL) { 1397 plog(LLV_ERROR, LOCATION, NULL, 1398 "failed to get buffer to send.\n"); 1399 return errno; 1400 } 1401 1402 ru_ack = (struct isakmp_pl_ru *)payload->v; 1403 ru_ack->h.np = ISAKMP_NPTYPE_NONE; 1404 ru_ack->h.len = htons(tlen); 1405 ru_ack->doi = htonl(IPSEC_DOI); 1406 ru_ack->type = htons(ISAKMP_NTYPE_R_U_THERE_ACK); 1407 ru_ack->proto_id = IPSECDOI_PROTO_ISAKMP; /* XXX ? */ 1408 ru_ack->spi_size = sizeof(isakmp_index); 1409 memcpy(ru_ack->i_ck, ru->i_ck, sizeof(cookie_t)); 1410 memcpy(ru_ack->r_ck, ru->r_ck, sizeof(cookie_t)); 1411 ru_ack->data = ru->data; 1412 1413 /* XXX Should we do FLAG_A ? */ 1414 error = isakmp_info_send_common(iph1, payload, ISAKMP_NPTYPE_N, 1415 ISAKMP_FLAG_E); 1416 vfree(payload); 1417 1418 plog(LLV_DEBUG, LOCATION, NULL, "received a valid R-U-THERE, ACK sent\n"); 1419 1420 /* Should we mark tunnel as active ? */ 1421 return error; 1422 } 1423 1424 static int 1425 isakmp_info_recv_r_u_ack (iph1, ru, msgid) 1426 struct ph1handle *iph1; 1427 struct isakmp_pl_ru *ru; 1428 u_int32_t msgid; 1429 { 1430 u_int32_t seq; 1431 1432 plog(LLV_DEBUG, LOCATION, iph1->remote, 1433 "DPD R-U-There-Ack received\n"); 1434 1435 seq = ntohl(ru->data); 1436 if (seq <= iph1->dpd_last_ack || seq > iph1->dpd_seq) { 1437 plog(LLV_ERROR, LOCATION, iph1->remote, 1438 "Wrong DPD sequence number (%d; last_ack=%d, seq=%d).\n", 1439 seq, iph1->dpd_last_ack, iph1->dpd_seq); 1440 return 0; 1441 } 1442 1443 /* accept cookies in original or reversed order */ 1444 if ((memcmp(ru->i_ck, iph1->index.i_ck, sizeof(cookie_t)) || 1445 memcmp(ru->r_ck, iph1->index.r_ck, sizeof(cookie_t))) && 1446 (memcmp(ru->r_ck, iph1->index.i_ck, sizeof(cookie_t)) || 1447 memcmp(ru->i_ck, iph1->index.r_ck, sizeof(cookie_t)))) { 1448 plog(LLV_ERROR, LOCATION, iph1->remote, 1449 "Cookie mismatch in DPD ACK!.\n"); 1450 return 0; 1451 } 1452 1453 iph1->dpd_fails = 0; 1454 iph1->dpd_last_ack = seq; 1455 sched_cancel(&iph1->dpd_r_u); 1456 isakmp_sched_r_u(iph1, 0); 1457 1458 plog(LLV_DEBUG, LOCATION, iph1->remote, "received an R-U-THERE-ACK\n"); 1459 1460 return 0; 1461 } 1462 1463 1464 1465 1466 /* 1467 * send DPD R-U-THERE payload in Informational exchange. 1468 */ 1469 static void 1470 isakmp_info_send_r_u(sc) 1471 struct sched *sc; 1472 { 1473 struct ph1handle *iph1 = container_of(sc, struct ph1handle, dpd_r_u); 1474 1475 /* create R-U-THERE payload */ 1476 struct isakmp_pl_ru *ru; 1477 vchar_t *payload = NULL; 1478 int tlen; 1479 int error = 0; 1480 1481 plog(LLV_DEBUG, LOCATION, iph1->remote, "DPD monitoring....\n"); 1482 1483 if (iph1->status == PHASE1ST_EXPIRED) { 1484 /* This can happen after removing tunnels from the 1485 * config file and then reloading. 1486 * Such iph1 have rmconf=NULL, so return before the if 1487 * block below. 1488 */ 1489 return; 1490 } 1491 1492 if (iph1->dpd_fails >= iph1->rmconf->dpd_maxfails) { 1493 1494 plog(LLV_INFO, LOCATION, iph1->remote, 1495 "DPD: remote (ISAKMP-SA spi=%s) seems to be dead.\n", 1496 isakmp_pindex(&iph1->index, 0)); 1497 1498 script_hook(iph1, SCRIPT_PHASE1_DEAD); 1499 evt_phase1(iph1, EVT_PHASE1_DPD_TIMEOUT, NULL); 1500 purge_remote(iph1); 1501 1502 /* Do not reschedule here: phase1 is deleted, 1503 * DPD will be reactivated when a new ph1 will be negociated 1504 */ 1505 return; 1506 } 1507 1508 /* TODO: check recent activity to avoid useless sends... */ 1509 1510 tlen = sizeof(*ru); 1511 payload = vmalloc(tlen); 1512 if (payload == NULL) { 1513 plog(LLV_ERROR, LOCATION, NULL, 1514 "failed to get buffer for payload.\n"); 1515 return; 1516 } 1517 ru = (struct isakmp_pl_ru *)payload->v; 1518 ru->h.np = ISAKMP_NPTYPE_NONE; 1519 ru->h.len = htons(tlen); 1520 ru->doi = htonl(IPSEC_DOI); 1521 ru->type = htons(ISAKMP_NTYPE_R_U_THERE); 1522 ru->proto_id = IPSECDOI_PROTO_ISAKMP; /* XXX ?*/ 1523 ru->spi_size = sizeof(isakmp_index); 1524 1525 memcpy(ru->i_ck, iph1->index.i_ck, sizeof(cookie_t)); 1526 memcpy(ru->r_ck, iph1->index.r_ck, sizeof(cookie_t)); 1527 1528 if (iph1->dpd_seq == 0) { 1529 /* generate a random seq which is not too big */ 1530 iph1->dpd_seq = iph1->dpd_last_ack = rand() & 0x0fff; 1531 } 1532 1533 iph1->dpd_seq++; 1534 iph1->dpd_fails++; 1535 ru->data = htonl(iph1->dpd_seq); 1536 1537 error = isakmp_info_send_common(iph1, payload, ISAKMP_NPTYPE_N, 0); 1538 vfree(payload); 1539 1540 plog(LLV_DEBUG, LOCATION, iph1->remote, 1541 "DPD R-U-There sent (%d)\n", error); 1542 1543 /* Reschedule the r_u_there with a short delay, 1544 * will be deleted/rescheduled if ACK received before */ 1545 isakmp_sched_r_u(iph1, 1); 1546 1547 plog(LLV_DEBUG, LOCATION, iph1->remote, 1548 "rescheduling send_r_u (%d).\n", iph1->rmconf->dpd_retry); 1549 } 1550 1551 /* Schedule a new R-U-THERE */ 1552 int 1553 isakmp_sched_r_u(iph1, retry) 1554 struct ph1handle *iph1; 1555 int retry; 1556 { 1557 if(iph1 == NULL || 1558 iph1->rmconf == NULL) 1559 return 1; 1560 1561 1562 if(iph1->dpd_support == 0 || 1563 iph1->rmconf->dpd_interval == 0) 1564 return 0; 1565 1566 if(retry) 1567 sched_schedule(&iph1->dpd_r_u, iph1->rmconf->dpd_retry, 1568 isakmp_info_send_r_u); 1569 else 1570 sched_schedule(&iph1->dpd_r_u, iph1->rmconf->dpd_interval, 1571 isakmp_info_send_r_u); 1572 1573 return 0; 1574 } 1575 #endif 1576