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