1/* $NetBSD: isakmp_quick.c,v 1.11.4.1 2007/08/01 11:52:21 vanhu Exp $ */ 2 3/* Id: isakmp_quick.c,v 1.29 2006/08/22 18:17:17 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 <netinet/in.h> 41 42#include <stdlib.h> 43#include <stdio.h> 44#include <string.h> 45#include <errno.h> 46#if TIME_WITH_SYS_TIME 47# include <sys/time.h> 48# include <time.h> 49#else 50# if HAVE_SYS_TIME_H 51# include <sys/time.h> 52# else 53# include <time.h> 54# endif 55#endif 56#ifdef ENABLE_HYBRID 57#include <resolv.h> 58#endif 59 60#include PATH_IPSEC_H 61 62#include "var.h" 63#include "vmbuf.h" 64#include "schedule.h" 65#include "misc.h" 66#include "plog.h" 67#include "debug.h" 68 69#include "localconf.h" 70#include "remoteconf.h" 71#include "handler.h" 72#include "policy.h" 73#include "proposal.h" 74#include "isakmp_var.h" 75#include "isakmp.h" 76#include "isakmp_inf.h" 77#include "isakmp_quick.h" 78#include "oakley.h" 79#include "ipsec_doi.h" 80#include "crypto_openssl.h" 81#include "pfkey.h" 82#include "policy.h" 83#include "algorithm.h" 84#include "sockmisc.h" 85#include "proposal.h" 86#include "sainfo.h" 87#include "admin.h" 88#include "strnames.h" 89 90/* quick mode */ 91static vchar_t *quick_ir1mx __P((struct ph2handle *, vchar_t *, vchar_t *)); 92static int get_sainfo_r __P((struct ph2handle *)); 93static int get_proposal_r __P((struct ph2handle *)); 94 95/* %%% 96 * Quick Mode 97 */ 98/* 99 * begin Quick Mode as initiator. send pfkey getspi message to kernel. 100 */ 101int 102quick_i1prep(iph2, msg) 103 struct ph2handle *iph2; 104 vchar_t *msg; /* must be null pointer */ 105{ 106 int error = ISAKMP_INTERNAL_ERROR; 107 108 /* validity check */ 109 if (iph2->status != PHASE2ST_STATUS2) { 110 plog(LLV_ERROR, LOCATION, NULL, 111 "status mismatched %d.\n", iph2->status); 112 goto end; 113 } 114 115 iph2->msgid = isakmp_newmsgid2(iph2->ph1); 116 iph2->ivm = oakley_newiv2(iph2->ph1, iph2->msgid); 117 if (iph2->ivm == NULL) 118 return 0; 119 120 iph2->status = PHASE2ST_GETSPISENT; 121 122 /* don't anything if local test mode. */ 123 if (f_local) { 124 error = 0; 125 goto end; 126 } 127 128 /* send getspi message */ 129 if (pk_sendgetspi(iph2) < 0) 130 goto end; 131 132 plog(LLV_DEBUG, LOCATION, NULL, "pfkey getspi sent.\n"); 133 134 iph2->sce = sched_new(lcconf->wait_ph2complete, 135 pfkey_timeover_stub, iph2); 136 137 error = 0; 138 139end: 140 return error; 141} 142 143/* 144 * send to responder 145 * HDR*, HASH(1), SA, Ni [, KE ] [, IDi2, IDr2 ] 146 */ 147int 148quick_i1send(iph2, msg) 149 struct ph2handle *iph2; 150 vchar_t *msg; /* must be null pointer */ 151{ 152 vchar_t *body = NULL; 153 vchar_t *hash = NULL; 154 struct isakmp_gen *gen; 155 char *p; 156 int tlen; 157 int error = ISAKMP_INTERNAL_ERROR; 158 int pfsgroup, idci, idcr; 159 int np; 160 struct ipsecdoi_id_b *id, *id_p; 161 162 /* validity check */ 163 if (msg != NULL) { 164 plog(LLV_ERROR, LOCATION, NULL, 165 "msg has to be NULL in this function.\n"); 166 goto end; 167 } 168 if (iph2->status != PHASE2ST_GETSPIDONE) { 169 plog(LLV_ERROR, LOCATION, NULL, 170 "status mismatched %d.\n", iph2->status); 171 goto end; 172 } 173 174 /* create SA payload for my proposal */ 175 if (ipsecdoi_setph2proposal(iph2) < 0) 176 goto end; 177 178 /* generate NONCE value */ 179 iph2->nonce = eay_set_random(iph2->ph1->rmconf->nonce_size); 180 if (iph2->nonce == NULL) 181 goto end; 182 183 /* 184 * DH value calculation is kicked out into cfparse.y. 185 * because pfs group can not be negotiated, it's only to be checked 186 * acceptable. 187 */ 188 /* generate KE value if need */ 189 pfsgroup = iph2->proposal->pfs_group; 190 if (pfsgroup) { 191 /* DH group settting if PFS is required. */ 192 if (oakley_setdhgroup(pfsgroup, &iph2->pfsgrp) < 0) { 193 plog(LLV_ERROR, LOCATION, NULL, 194 "failed to set DH value.\n"); 195 goto end; 196 } 197 if (oakley_dh_generate(iph2->pfsgrp, 198 &iph2->dhpub, &iph2->dhpriv) < 0) { 199 goto end; 200 } 201 } 202 203 /* generate ID value */ 204 if (ipsecdoi_setid2(iph2) < 0) { 205 plog(LLV_ERROR, LOCATION, NULL, 206 "failed to get ID.\n"); 207 goto end; 208 } 209 plog(LLV_DEBUG, LOCATION, NULL, "IDci:\n"); 210 plogdump(LLV_DEBUG, iph2->id->v, iph2->id->l); 211 plog(LLV_DEBUG, LOCATION, NULL, "IDcr:\n"); 212 plogdump(LLV_DEBUG, iph2->id_p->v, iph2->id_p->l); 213 214 /* 215 * we do not attach IDci nor IDcr, under the following condition: 216 * - all proposals are transport mode 217 * - no MIP6 or proxy 218 * - id payload suggests to encrypt all the traffic (no specific 219 * protocol type) 220 */ 221 id = (struct ipsecdoi_id_b *)iph2->id->v; 222 id_p = (struct ipsecdoi_id_b *)iph2->id_p->v; 223 if (id->proto_id == 0 224 && id_p->proto_id == 0 225 && iph2->ph1->rmconf->support_proxy == 0 226 && ipsecdoi_transportmode(iph2->proposal)) { 227 idci = idcr = 0; 228 } else 229 idci = idcr = 1; 230 231 /* create SA;NONCE payload, and KE if need, and IDii, IDir. */ 232 tlen = + sizeof(*gen) + iph2->sa->l 233 + sizeof(*gen) + iph2->nonce->l; 234 if (pfsgroup) 235 tlen += (sizeof(*gen) + iph2->dhpub->l); 236 if (idci) 237 tlen += sizeof(*gen) + iph2->id->l; 238 if (idcr) 239 tlen += sizeof(*gen) + iph2->id_p->l; 240 241 body = vmalloc(tlen); 242 if (body == NULL) { 243 plog(LLV_ERROR, LOCATION, NULL, 244 "failed to get buffer to send.\n"); 245 goto end; 246 } 247 248 p = body->v; 249 250 /* add SA payload */ 251 p = set_isakmp_payload(p, iph2->sa, ISAKMP_NPTYPE_NONCE); 252 253 /* add NONCE payload */ 254 if (pfsgroup) 255 np = ISAKMP_NPTYPE_KE; 256 else if (idci || idcr) 257 np = ISAKMP_NPTYPE_ID; 258 else 259 np = ISAKMP_NPTYPE_NONE; 260 p = set_isakmp_payload(p, iph2->nonce, np); 261 262 /* add KE payload if need. */ 263 np = (idci || idcr) ? ISAKMP_NPTYPE_ID : ISAKMP_NPTYPE_NONE; 264 if (pfsgroup) 265 p = set_isakmp_payload(p, iph2->dhpub, np); 266 267 /* IDci */ 268 np = (idcr) ? ISAKMP_NPTYPE_ID : ISAKMP_NPTYPE_NONE; 269 if (idci) 270 p = set_isakmp_payload(p, iph2->id, np); 271 272 /* IDcr */ 273 if (idcr) 274 p = set_isakmp_payload(p, iph2->id_p, ISAKMP_NPTYPE_NONE); 275 276 /* generate HASH(1) */ 277 hash = oakley_compute_hash1(iph2->ph1, iph2->msgid, body); 278 if (hash == NULL) 279 goto end; 280 281 /* send isakmp payload */ 282 iph2->sendbuf = quick_ir1mx(iph2, body, hash); 283 if (iph2->sendbuf == NULL) 284 goto end; 285 286 /* send the packet, add to the schedule to resend */ 287 iph2->retry_counter = iph2->ph1->rmconf->retry_counter; 288 if (isakmp_ph2resend(iph2) == -1) 289 goto end; 290 291 /* change status of isakmp status entry */ 292 iph2->status = PHASE2ST_MSG1SENT; 293 294 error = 0; 295 296end: 297 if (body != NULL) 298 vfree(body); 299 if (hash != NULL) 300 vfree(hash); 301 302 return error; 303} 304 305/* 306 * receive from responder 307 * HDR*, HASH(2), SA, Nr [, KE ] [, IDi2, IDr2 ] 308 */ 309int 310quick_i2recv(iph2, msg0) 311 struct ph2handle *iph2; 312 vchar_t *msg0; 313{ 314 vchar_t *msg = NULL; 315 vchar_t *hbuf = NULL; /* for hash computing. */ 316 vchar_t *pbuf = NULL; /* for payload parsing */ 317 struct isakmp_parse_t *pa; 318 struct isakmp *isakmp = (struct isakmp *)msg0->v; 319 struct isakmp_pl_hash *hash = NULL; 320 int f_id; 321 char *p; 322 int tlen; 323 int error = ISAKMP_INTERNAL_ERROR; 324 325 /* validity check */ 326 if (iph2->status != PHASE2ST_MSG1SENT) { 327 plog(LLV_ERROR, LOCATION, NULL, 328 "status mismatched %d.\n", iph2->status); 329 goto end; 330 } 331 332 /* decrypt packet */ 333 if (!ISSET(((struct isakmp *)msg0->v)->flags, ISAKMP_FLAG_E)) { 334 plog(LLV_ERROR, LOCATION, iph2->ph1->remote, 335 "Packet wasn't encrypted.\n"); 336 goto end; 337 } 338 msg = oakley_do_decrypt(iph2->ph1, msg0, iph2->ivm->iv, iph2->ivm->ive); 339 if (msg == NULL) 340 goto end; 341 342 /* create buffer for validating HASH(2) */ 343 /* 344 * ordering rule: 345 * 1. the first one must be HASH 346 * 2. the second one must be SA (added in isakmp-oakley-05!) 347 * 3. two IDs must be considered as IDci, then IDcr 348 */ 349 pbuf = isakmp_parse(msg); 350 if (pbuf == NULL) 351 goto end; 352 pa = (struct isakmp_parse_t *)pbuf->v; 353 354 /* HASH payload is fixed postion */ 355 if (pa->type != ISAKMP_NPTYPE_HASH) { 356 plog(LLV_ERROR, LOCATION, iph2->ph1->remote, 357 "received invalid next payload type %d, " 358 "expecting %d.\n", 359 pa->type, ISAKMP_NPTYPE_HASH); 360 goto end; 361 } 362 hash = (struct isakmp_pl_hash *)pa->ptr; 363 pa++; 364 365 /* 366 * this restriction was introduced in isakmp-oakley-05. 367 * we do not check this for backward compatibility. 368 * TODO: command line/config file option to enable/disable this code 369 */ 370 /* HASH payload is fixed postion */ 371 if (pa->type != ISAKMP_NPTYPE_SA) { 372 plog(LLV_WARNING, LOCATION, iph2->ph1->remote, 373 "received invalid next payload type %d, " 374 "expecting %d.\n", 375 pa->type, ISAKMP_NPTYPE_HASH); 376 } 377 378 /* allocate buffer for computing HASH(2) */ 379 tlen = iph2->nonce->l 380 + ntohl(isakmp->len) - sizeof(*isakmp); 381 hbuf = vmalloc(tlen); 382 if (hbuf == NULL) { 383 plog(LLV_ERROR, LOCATION, NULL, 384 "failed to get hash buffer.\n"); 385 goto end; 386 } 387 p = hbuf->v + iph2->nonce->l; /* retain the space for Ni_b */ 388 389 /* 390 * parse the payloads. 391 * copy non-HASH payloads into hbuf, so that we can validate HASH. 392 */ 393 iph2->sa_ret = NULL; 394 f_id = 0; /* flag to use checking ID */ 395 tlen = 0; /* count payload length except of HASH payload. */ 396 for (; pa->type; pa++) { 397 398 /* copy to buffer for HASH */ 399 /* Don't modify the payload */ 400 memcpy(p, pa->ptr, pa->len); 401 402 switch (pa->type) { 403 case ISAKMP_NPTYPE_SA: 404 if (iph2->sa_ret != NULL) { 405 plog(LLV_ERROR, LOCATION, NULL, 406 "Ignored, multiple SA " 407 "isn't supported.\n"); 408 break; 409 } 410 if (isakmp_p2ph(&iph2->sa_ret, pa->ptr) < 0) 411 goto end; 412 break; 413 414 case ISAKMP_NPTYPE_NONCE: 415 if (isakmp_p2ph(&iph2->nonce_p, pa->ptr) < 0) 416 goto end; 417 break; 418 419 case ISAKMP_NPTYPE_KE: 420 if (isakmp_p2ph(&iph2->dhpub_p, pa->ptr) < 0) 421 goto end; 422 break; 423 424 case ISAKMP_NPTYPE_ID: 425 { 426 vchar_t *vp; 427 428 /* check ID value */ 429 if (f_id == 0) { 430 /* for IDci */ 431 f_id = 1; 432 vp = iph2->id; 433 } else { 434 /* for IDcr */ 435 vp = iph2->id_p; 436 } 437 438#ifndef ANDROID_PATCHED 439 if (memcmp(vp->v, (caddr_t)pa->ptr + sizeof(struct isakmp_gen), vp->l)) { 440 441 plog(LLV_ERROR, LOCATION, NULL, 442 "mismatched ID was returned.\n"); 443 error = ISAKMP_NTYPE_ATTRIBUTES_NOT_SUPPORTED; 444 goto end; 445 } 446#endif 447 } 448 break; 449 450 case ISAKMP_NPTYPE_N: 451 isakmp_check_notify(pa->ptr, iph2->ph1); 452 break; 453 454#ifdef ENABLE_NATT 455 case ISAKMP_NPTYPE_NATOA_DRAFT: 456 case ISAKMP_NPTYPE_NATOA_RFC: 457 /* Ignore original source/destination messages */ 458 break; 459#endif 460 461 default: 462 /* don't send information, see ident_r1recv() */ 463 plog(LLV_ERROR, LOCATION, iph2->ph1->remote, 464 "ignore the packet, " 465 "received unexpecting payload type %d.\n", 466 pa->type); 467 goto end; 468 } 469 470 p += pa->len; 471 472 /* compute true length of payload. */ 473 tlen += pa->len; 474 } 475 476 /* payload existency check */ 477 if (hash == NULL || iph2->sa_ret == NULL || iph2->nonce_p == NULL) { 478 plog(LLV_ERROR, LOCATION, iph2->ph1->remote, 479 "few isakmp message received.\n"); 480 goto end; 481 } 482 483 /* Fixed buffer for calculating HASH */ 484 memcpy(hbuf->v, iph2->nonce->v, iph2->nonce->l); 485 plog(LLV_DEBUG, LOCATION, NULL, 486 "HASH allocated:hbuf->l=%zu actual:tlen=%zu\n", 487 hbuf->l, tlen + iph2->nonce->l); 488 /* adjust buffer length for HASH */ 489 hbuf->l = iph2->nonce->l + tlen; 490 491 /* validate HASH(2) */ 492 { 493 char *r_hash; 494 vchar_t *my_hash = NULL; 495 int result; 496 497 r_hash = (char *)hash + sizeof(*hash); 498 499 plog(LLV_DEBUG, LOCATION, NULL, "HASH(2) received:"); 500 plogdump(LLV_DEBUG, r_hash, ntohs(hash->h.len) - sizeof(*hash)); 501 502 my_hash = oakley_compute_hash1(iph2->ph1, iph2->msgid, hbuf); 503 if (my_hash == NULL) 504 goto end; 505 506 result = memcmp(my_hash->v, r_hash, my_hash->l); 507 vfree(my_hash); 508 509 if (result) { 510 plog(LLV_DEBUG, LOCATION, iph2->ph1->remote, 511 "HASH(2) mismatch.\n"); 512 error = ISAKMP_NTYPE_INVALID_HASH_INFORMATION; 513 goto end; 514 } 515 } 516 517 /* validity check SA payload sent from responder */ 518 if (ipsecdoi_checkph2proposal(iph2) < 0) { 519 error = ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN; 520 goto end; 521 } 522 523 /* change status of isakmp status entry */ 524 iph2->status = PHASE2ST_STATUS6; 525 526 error = 0; 527 528end: 529 if (hbuf) 530 vfree(hbuf); 531 if (pbuf) 532 vfree(pbuf); 533 if (msg) 534 vfree(msg); 535 536 if (error) { 537 VPTRINIT(iph2->sa_ret); 538 VPTRINIT(iph2->nonce_p); 539 VPTRINIT(iph2->dhpub_p); 540 VPTRINIT(iph2->id); 541 VPTRINIT(iph2->id_p); 542 } 543 544 return error; 545} 546 547/* 548 * send to responder 549 * HDR*, HASH(3) 550 */ 551int 552quick_i2send(iph2, msg0) 553 struct ph2handle *iph2; 554 vchar_t *msg0; 555{ 556 vchar_t *msg = NULL; 557 vchar_t *buf = NULL; 558 vchar_t *hash = NULL; 559 char *p = NULL; 560 int tlen; 561 int error = ISAKMP_INTERNAL_ERROR; 562 563 /* validity check */ 564 if (iph2->status != PHASE2ST_STATUS6) { 565 plog(LLV_ERROR, LOCATION, NULL, 566 "status mismatched %d.\n", iph2->status); 567 goto end; 568 } 569 570 /* generate HASH(3) */ 571 { 572 vchar_t *tmp = NULL; 573 574 plog(LLV_DEBUG, LOCATION, NULL, "HASH(3) generate\n"); 575 576 tmp = vmalloc(iph2->nonce->l + iph2->nonce_p->l); 577 if (tmp == NULL) { 578 plog(LLV_ERROR, LOCATION, NULL, 579 "failed to get hash buffer.\n"); 580 goto end; 581 } 582 memcpy(tmp->v, iph2->nonce->v, iph2->nonce->l); 583 memcpy(tmp->v + iph2->nonce->l, iph2->nonce_p->v, iph2->nonce_p->l); 584 585 hash = oakley_compute_hash3(iph2->ph1, iph2->msgid, tmp); 586 vfree(tmp); 587 588 if (hash == NULL) 589 goto end; 590 } 591 592 /* create buffer for isakmp payload */ 593 tlen = sizeof(struct isakmp) 594 + sizeof(struct isakmp_gen) + hash->l; 595 buf = vmalloc(tlen); 596 if (buf == NULL) { 597 plog(LLV_ERROR, LOCATION, NULL, 598 "failed to get buffer to send.\n"); 599 goto end; 600 } 601 602 /* create isakmp header */ 603 p = set_isakmp_header2(buf, iph2, ISAKMP_NPTYPE_HASH); 604 if (p == NULL) 605 goto end; 606 607 /* add HASH(3) payload */ 608 p = set_isakmp_payload(p, hash, ISAKMP_NPTYPE_NONE); 609 610#ifdef HAVE_PRINT_ISAKMP_C 611 isakmp_printpacket(buf, iph2->ph1->local, iph2->ph1->remote, 1); 612#endif 613 614 /* encoding */ 615 iph2->sendbuf = oakley_do_encrypt(iph2->ph1, buf, iph2->ivm->ive, iph2->ivm->iv); 616 if (iph2->sendbuf == NULL) 617 goto end; 618 619 /* if there is commit bit, need resending */ 620 if (ISSET(iph2->flags, ISAKMP_FLAG_C)) { 621 /* send the packet, add to the schedule to resend */ 622 iph2->retry_counter = iph2->ph1->rmconf->retry_counter; 623 if (isakmp_ph2resend(iph2) == -1) 624 goto end; 625 } else { 626 /* send the packet */ 627 if (isakmp_send(iph2->ph1, iph2->sendbuf) < 0) 628 goto end; 629 } 630 631 /* the sending message is added to the received-list. */ 632 if (add_recvdpkt(iph2->ph1->remote, iph2->ph1->local, 633 iph2->sendbuf, msg0) == -1) { 634 plog(LLV_ERROR , LOCATION, NULL, 635 "failed to add a response packet to the tree.\n"); 636 goto end; 637 } 638 639 /* compute both of KEYMATs */ 640 if (oakley_compute_keymat(iph2, INITIATOR) < 0) 641 goto end; 642 643 iph2->status = PHASE2ST_ADDSA; 644 645 /* don't anything if local test mode. */ 646 if (f_local) { 647 error = 0; 648 goto end; 649 } 650 651 /* if there is commit bit don't set up SA now. */ 652 if (ISSET(iph2->flags, ISAKMP_FLAG_C)) { 653 iph2->status = PHASE2ST_COMMIT; 654 error = 0; 655 goto end; 656 } 657 658 /* Do UPDATE for initiator */ 659 plog(LLV_DEBUG, LOCATION, NULL, "call pk_sendupdate\n"); 660 if (pk_sendupdate(iph2) < 0) { 661 plog(LLV_ERROR, LOCATION, NULL, "pfkey update failed.\n"); 662 goto end; 663 } 664 plog(LLV_DEBUG, LOCATION, NULL, "pfkey update sent.\n"); 665 666 /* Do ADD for responder */ 667 if (pk_sendadd(iph2) < 0) { 668 plog(LLV_ERROR, LOCATION, NULL, "pfkey add failed.\n"); 669 goto end; 670 } 671 plog(LLV_DEBUG, LOCATION, NULL, "pfkey add sent.\n"); 672 673 error = 0; 674 675end: 676 if (buf != NULL) 677 vfree(buf); 678 if (msg != NULL) 679 vfree(msg); 680 if (hash != NULL) 681 vfree(hash); 682 683 return error; 684} 685 686/* 687 * receive from responder 688 * HDR#*, HASH(4), notify 689 */ 690int 691quick_i3recv(iph2, msg0) 692 struct ph2handle *iph2; 693 vchar_t *msg0; 694{ 695 vchar_t *msg = NULL; 696 vchar_t *pbuf = NULL; /* for payload parsing */ 697 struct isakmp_parse_t *pa; 698 struct isakmp_pl_hash *hash = NULL; 699 vchar_t *notify = NULL; 700 int error = ISAKMP_INTERNAL_ERROR; 701 702 /* validity check */ 703 if (iph2->status != PHASE2ST_COMMIT) { 704 plog(LLV_ERROR, LOCATION, NULL, 705 "status mismatched %d.\n", iph2->status); 706 goto end; 707 } 708 709 /* decrypt packet */ 710 if (!ISSET(((struct isakmp *)msg0->v)->flags, ISAKMP_FLAG_E)) { 711 plog(LLV_ERROR, LOCATION, iph2->ph1->remote, 712 "Packet wasn't encrypted.\n"); 713 goto end; 714 } 715 msg = oakley_do_decrypt(iph2->ph1, msg0, iph2->ivm->iv, iph2->ivm->ive); 716 if (msg == NULL) 717 goto end; 718 719 /* validate the type of next payload */ 720 pbuf = isakmp_parse(msg); 721 if (pbuf == NULL) 722 goto end; 723 724 for (pa = (struct isakmp_parse_t *)pbuf->v; 725 pa->type != ISAKMP_NPTYPE_NONE; 726 pa++) { 727 728 switch (pa->type) { 729 case ISAKMP_NPTYPE_HASH: 730 hash = (struct isakmp_pl_hash *)pa->ptr; 731 break; 732 case ISAKMP_NPTYPE_N: 733 if (notify != NULL) { 734 plog(LLV_WARNING, LOCATION, NULL, 735 "Ignoring multiples notifications\n"); 736 break; 737 } 738 isakmp_check_notify(pa->ptr, iph2->ph1); 739 notify = vmalloc(pa->len); 740 if (notify == NULL) { 741 plog(LLV_ERROR, LOCATION, NULL, 742 "failed to get notify buffer.\n"); 743 goto end; 744 } 745 memcpy(notify->v, pa->ptr, notify->l); 746 break; 747 default: 748 /* don't send information, see ident_r1recv() */ 749 plog(LLV_ERROR, LOCATION, iph2->ph1->remote, 750 "ignore the packet, " 751 "received unexpecting payload type %d.\n", 752 pa->type); 753 goto end; 754 } 755 } 756 757 /* payload existency check */ 758 if (hash == NULL) { 759 plog(LLV_ERROR, LOCATION, iph2->ph1->remote, 760 "few isakmp message received.\n"); 761 goto end; 762 } 763 764 /* validate HASH(4) */ 765 { 766 char *r_hash; 767 vchar_t *my_hash = NULL; 768 vchar_t *tmp = NULL; 769 int result; 770 771 r_hash = (char *)hash + sizeof(*hash); 772 773 plog(LLV_DEBUG, LOCATION, NULL, "HASH(4) validate:"); 774 plogdump(LLV_DEBUG, r_hash, ntohs(hash->h.len) - sizeof(*hash)); 775 776 my_hash = oakley_compute_hash1(iph2->ph1, iph2->msgid, notify); 777 vfree(tmp); 778 if (my_hash == NULL) 779 goto end; 780 781 result = memcmp(my_hash->v, r_hash, my_hash->l); 782 vfree(my_hash); 783 784 if (result) { 785 plog(LLV_DEBUG, LOCATION, iph2->ph1->remote, 786 "HASH(4) mismatch.\n"); 787 error = ISAKMP_NTYPE_INVALID_HASH_INFORMATION; 788 goto end; 789 } 790 } 791 792 iph2->status = PHASE2ST_ADDSA; 793 iph2->flags ^= ISAKMP_FLAG_C; /* reset bit */ 794 795 /* don't anything if local test mode. */ 796 if (f_local) { 797 error = 0; 798 goto end; 799 } 800 801 /* Do UPDATE for initiator */ 802 plog(LLV_DEBUG, LOCATION, NULL, "call pk_sendupdate\n"); 803 if (pk_sendupdate(iph2) < 0) { 804 plog(LLV_ERROR, LOCATION, NULL, "pfkey update failed.\n"); 805 goto end; 806 } 807 plog(LLV_DEBUG, LOCATION, NULL, "pfkey update sent.\n"); 808 809 /* Do ADD for responder */ 810 if (pk_sendadd(iph2) < 0) { 811 plog(LLV_ERROR, LOCATION, NULL, "pfkey add failed.\n"); 812 goto end; 813 } 814 plog(LLV_DEBUG, LOCATION, NULL, "pfkey add sent.\n"); 815 816 error = 0; 817 818end: 819 if (msg != NULL) 820 vfree(msg); 821 if (pbuf != NULL) 822 vfree(pbuf); 823 if (notify != NULL) 824 vfree(notify); 825 826 return error; 827} 828 829/* 830 * receive from initiator 831 * HDR*, HASH(1), SA, Ni [, KE ] [, IDi2, IDr2 ] 832 */ 833int 834quick_r1recv(iph2, msg0) 835 struct ph2handle *iph2; 836 vchar_t *msg0; 837{ 838 vchar_t *msg = NULL; 839 vchar_t *hbuf = NULL; /* for hash computing. */ 840 vchar_t *pbuf = NULL; /* for payload parsing */ 841 struct isakmp_parse_t *pa; 842 struct isakmp *isakmp = (struct isakmp *)msg0->v; 843 struct isakmp_pl_hash *hash = NULL; 844 char *p; 845 int tlen; 846 int f_id_order; /* for ID payload detection */ 847 int error = ISAKMP_INTERNAL_ERROR; 848 849 /* validity check */ 850 if (iph2->status != PHASE2ST_START) { 851 plog(LLV_ERROR, LOCATION, NULL, 852 "status mismatched %d.\n", iph2->status); 853 goto end; 854 } 855 856 /* decrypting */ 857 if (!ISSET(((struct isakmp *)msg0->v)->flags, ISAKMP_FLAG_E)) { 858 plog(LLV_ERROR, LOCATION, iph2->ph1->remote, 859 "Packet wasn't encrypted.\n"); 860 error = ISAKMP_NTYPE_PAYLOAD_MALFORMED; 861 goto end; 862 } 863 /* decrypt packet */ 864 msg = oakley_do_decrypt(iph2->ph1, msg0, iph2->ivm->iv, iph2->ivm->ive); 865 if (msg == NULL) 866 goto end; 867 868 /* create buffer for using to validate HASH(1) */ 869 /* 870 * ordering rule: 871 * 1. the first one must be HASH 872 * 2. the second one must be SA (added in isakmp-oakley-05!) 873 * 3. two IDs must be considered as IDci, then IDcr 874 */ 875 pbuf = isakmp_parse(msg); 876 if (pbuf == NULL) 877 goto end; 878 pa = (struct isakmp_parse_t *)pbuf->v; 879 880 /* HASH payload is fixed postion */ 881 if (pa->type != ISAKMP_NPTYPE_HASH) { 882 plog(LLV_ERROR, LOCATION, iph2->ph1->remote, 883 "received invalid next payload type %d, " 884 "expecting %d.\n", 885 pa->type, ISAKMP_NPTYPE_HASH); 886 error = ISAKMP_NTYPE_BAD_PROPOSAL_SYNTAX; 887 goto end; 888 } 889 hash = (struct isakmp_pl_hash *)pa->ptr; 890 pa++; 891 892 /* 893 * this restriction was introduced in isakmp-oakley-05. 894 * we do not check this for backward compatibility. 895 * TODO: command line/config file option to enable/disable this code 896 */ 897 /* HASH payload is fixed postion */ 898 if (pa->type != ISAKMP_NPTYPE_SA) { 899 plog(LLV_WARNING, LOCATION, iph2->ph1->remote, 900 "received invalid next payload type %d, " 901 "expecting %d.\n", 902 pa->type, ISAKMP_NPTYPE_SA); 903 error = ISAKMP_NTYPE_BAD_PROPOSAL_SYNTAX; 904 } 905 906 /* allocate buffer for computing HASH(1) */ 907 tlen = ntohl(isakmp->len) - sizeof(*isakmp); 908 hbuf = vmalloc(tlen); 909 if (hbuf == NULL) { 910 plog(LLV_ERROR, LOCATION, NULL, 911 "failed to get hash buffer.\n"); 912 goto end; 913 } 914 p = hbuf->v; 915 916 /* 917 * parse the payloads. 918 * copy non-HASH payloads into hbuf, so that we can validate HASH. 919 */ 920 iph2->sa = NULL; /* we don't support multi SAs. */ 921 iph2->nonce_p = NULL; 922 iph2->dhpub_p = NULL; 923 iph2->id_p = NULL; 924 iph2->id = NULL; 925 tlen = 0; /* count payload length except of HASH payload. */ 926 927 /* 928 * IDi2 MUST be immediatelly followed by IDr2. We allowed the 929 * illegal case, but logged. First ID payload is to be IDi2. 930 * And next ID payload is to be IDr2. 931 */ 932 f_id_order = 0; 933 934 for (; pa->type; pa++) { 935 936 /* copy to buffer for HASH */ 937 /* Don't modify the payload */ 938 memcpy(p, pa->ptr, pa->len); 939 940 if (pa->type != ISAKMP_NPTYPE_ID) 941 f_id_order = 0; 942 943 switch (pa->type) { 944 case ISAKMP_NPTYPE_SA: 945 if (iph2->sa != NULL) { 946 plog(LLV_ERROR, LOCATION, NULL, 947 "Multi SAs isn't supported.\n"); 948 goto end; 949 } 950 if (isakmp_p2ph(&iph2->sa, pa->ptr) < 0) 951 goto end; 952 break; 953 954 case ISAKMP_NPTYPE_NONCE: 955 if (isakmp_p2ph(&iph2->nonce_p, pa->ptr) < 0) 956 goto end; 957 break; 958 959 case ISAKMP_NPTYPE_KE: 960 if (isakmp_p2ph(&iph2->dhpub_p, pa->ptr) < 0) 961 goto end; 962 break; 963 964 case ISAKMP_NPTYPE_ID: 965 if (iph2->id_p == NULL) { 966 /* for IDci */ 967 f_id_order++; 968 969 if (isakmp_p2ph(&iph2->id_p, pa->ptr) < 0) 970 goto end; 971 972 } else if (iph2->id == NULL) { 973 /* for IDcr */ 974 if (f_id_order == 0) { 975 plog(LLV_ERROR, LOCATION, NULL, 976 "IDr2 payload is not " 977 "immediatelly followed " 978 "by IDi2. We allowed.\n"); 979 /* XXX we allowed in this case. */ 980 } 981 982 if (isakmp_p2ph(&iph2->id, pa->ptr) < 0) 983 goto end; 984 } else { 985 plog(LLV_ERROR, LOCATION, NULL, 986 "received too many ID payloads.\n"); 987 plogdump(LLV_ERROR, iph2->id->v, iph2->id->l); 988 error = ISAKMP_NTYPE_INVALID_ID_INFORMATION; 989 goto end; 990 } 991 break; 992 993 case ISAKMP_NPTYPE_N: 994 isakmp_check_notify(pa->ptr, iph2->ph1); 995 break; 996 997#ifdef ENABLE_NATT 998 case ISAKMP_NPTYPE_NATOA_DRAFT: 999 case ISAKMP_NPTYPE_NATOA_RFC: 1000 /* Ignore original source/destination messages */ 1001 break; 1002#endif 1003 1004 default: 1005 plog(LLV_ERROR, LOCATION, iph2->ph1->remote, 1006 "ignore the packet, " 1007 "received unexpecting payload type %d.\n", 1008 pa->type); 1009 error = ISAKMP_NTYPE_PAYLOAD_MALFORMED; 1010 goto end; 1011 } 1012 1013 p += pa->len; 1014 1015 /* compute true length of payload. */ 1016 tlen += pa->len; 1017 } 1018 1019 /* payload existency check */ 1020 if (hash == NULL || iph2->sa == NULL || iph2->nonce_p == NULL) { 1021 plog(LLV_ERROR, LOCATION, iph2->ph1->remote, 1022 "few isakmp message received.\n"); 1023 error = ISAKMP_NTYPE_PAYLOAD_MALFORMED; 1024 goto end; 1025 } 1026 1027 if (iph2->id_p) { 1028 plog(LLV_DEBUG, LOCATION, NULL, "received IDci2:"); 1029 plogdump(LLV_DEBUG, iph2->id_p->v, iph2->id_p->l); 1030 } 1031 if (iph2->id) { 1032 plog(LLV_DEBUG, LOCATION, NULL, "received IDcr2:"); 1033 plogdump(LLV_DEBUG, iph2->id->v, iph2->id->l); 1034 } 1035 1036 /* adjust buffer length for HASH */ 1037 hbuf->l = tlen; 1038 1039 /* validate HASH(1) */ 1040 { 1041 char *r_hash; 1042 vchar_t *my_hash = NULL; 1043 int result; 1044 1045 r_hash = (caddr_t)hash + sizeof(*hash); 1046 1047 plog(LLV_DEBUG, LOCATION, NULL, "HASH(1) validate:"); 1048 plogdump(LLV_DEBUG, r_hash, ntohs(hash->h.len) - sizeof(*hash)); 1049 1050 my_hash = oakley_compute_hash1(iph2->ph1, iph2->msgid, hbuf); 1051 if (my_hash == NULL) 1052 goto end; 1053 1054 result = memcmp(my_hash->v, r_hash, my_hash->l); 1055 vfree(my_hash); 1056 1057 if (result) { 1058 plog(LLV_DEBUG, LOCATION, iph2->ph1->remote, 1059 "HASH(1) mismatch.\n"); 1060 error = ISAKMP_NTYPE_INVALID_HASH_INFORMATION; 1061 goto end; 1062 } 1063 } 1064 1065 /* get sainfo */ 1066 error = get_sainfo_r(iph2); 1067 if (error) { 1068 plog(LLV_ERROR, LOCATION, NULL, 1069 "failed to get sainfo.\n"); 1070 goto end; 1071 } 1072 1073 1074 /* check the existence of ID payload and create responder's proposal */ 1075 error = get_proposal_r(iph2); 1076 switch (error) { 1077 case -2: 1078 /* generate a policy template from peer's proposal */ 1079 if (set_proposal_from_proposal(iph2)) { 1080 plog(LLV_ERROR, LOCATION, NULL, 1081 "failed to generate a proposal template " 1082 "from client's proposal.\n"); 1083 return ISAKMP_INTERNAL_ERROR; 1084 } 1085 /*FALLTHROUGH*/ 1086 case 0: 1087 /* select single proposal or reject it. */ 1088 if (ipsecdoi_selectph2proposal(iph2) < 0) { 1089 error = ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN; 1090 goto end; 1091 } 1092 break; 1093 default: 1094 plog(LLV_ERROR, LOCATION, NULL, 1095 "failed to get proposal for responder.\n"); 1096 goto end; 1097 } 1098 1099 /* check KE and attribute of PFS */ 1100 if (iph2->dhpub_p != NULL && iph2->approval->pfs_group == 0) { 1101 plog(LLV_ERROR, LOCATION, NULL, 1102 "no PFS is specified, but peer sends KE.\n"); 1103 error = ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN; 1104 goto end; 1105 } 1106 if (iph2->dhpub_p == NULL && iph2->approval->pfs_group != 0) { 1107 plog(LLV_ERROR, LOCATION, NULL, 1108 "PFS is specified, but peer doesn't sends KE.\n"); 1109 error = ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN; 1110 goto end; 1111 } 1112 1113 /* 1114 * save the packet from the initiator in order to resend the 1115 * responder's first packet against this packet. 1116 */ 1117 iph2->msg1 = vdup(msg0); 1118 1119 /* change status of isakmp status entry */ 1120 iph2->status = PHASE2ST_STATUS2; 1121 1122 error = 0; 1123 1124end: 1125 if (hbuf) 1126 vfree(hbuf); 1127 if (msg) 1128 vfree(msg); 1129 if (pbuf) 1130 vfree(pbuf); 1131 1132 if (error) { 1133 VPTRINIT(iph2->sa); 1134 VPTRINIT(iph2->nonce_p); 1135 VPTRINIT(iph2->dhpub_p); 1136 VPTRINIT(iph2->id); 1137 VPTRINIT(iph2->id_p); 1138 } 1139 1140 return error; 1141} 1142 1143/* 1144 * call pfkey_getspi. 1145 */ 1146int 1147quick_r1prep(iph2, msg) 1148 struct ph2handle *iph2; 1149 vchar_t *msg; 1150{ 1151 int error = ISAKMP_INTERNAL_ERROR; 1152 1153 /* validity check */ 1154 if (iph2->status != PHASE2ST_STATUS2) { 1155 plog(LLV_ERROR, LOCATION, NULL, 1156 "status mismatched %d.\n", iph2->status); 1157 goto end; 1158 } 1159 1160 iph2->status = PHASE2ST_GETSPISENT; 1161 1162 /* send getspi message */ 1163 if (pk_sendgetspi(iph2) < 0) 1164 goto end; 1165 1166 plog(LLV_DEBUG, LOCATION, NULL, "pfkey getspi sent.\n"); 1167 1168 iph2->sce = sched_new(lcconf->wait_ph2complete, 1169 pfkey_timeover_stub, iph2); 1170 1171 error = 0; 1172 1173end: 1174 return error; 1175} 1176 1177/* 1178 * send to initiator 1179 * HDR*, HASH(2), SA, Nr [, KE ] [, IDi2, IDr2 ] 1180 */ 1181int 1182quick_r2send(iph2, msg) 1183 struct ph2handle *iph2; 1184 vchar_t *msg; 1185{ 1186 vchar_t *body = NULL; 1187 vchar_t *hash = NULL; 1188 struct isakmp_gen *gen; 1189 char *p; 1190 int tlen; 1191 int error = ISAKMP_INTERNAL_ERROR; 1192 int pfsgroup; 1193 u_int8_t *np_p = NULL; 1194 1195 /* validity check */ 1196 if (msg != NULL) { 1197 plog(LLV_ERROR, LOCATION, NULL, 1198 "msg has to be NULL in this function.\n"); 1199 goto end; 1200 } 1201 if (iph2->status != PHASE2ST_GETSPIDONE) { 1202 plog(LLV_ERROR, LOCATION, NULL, 1203 "status mismatched %d.\n", iph2->status); 1204 goto end; 1205 } 1206 1207 /* update responders SPI */ 1208 if (ipsecdoi_updatespi(iph2) < 0) { 1209 plog(LLV_ERROR, LOCATION, NULL, "failed to update spi.\n"); 1210 goto end; 1211 } 1212 1213 /* generate NONCE value */ 1214 iph2->nonce = eay_set_random(iph2->ph1->rmconf->nonce_size); 1215 if (iph2->nonce == NULL) 1216 goto end; 1217 1218 /* generate KE value if need */ 1219 pfsgroup = iph2->approval->pfs_group; 1220 if (iph2->dhpub_p != NULL && pfsgroup != 0) { 1221 /* DH group settting if PFS is required. */ 1222 if (oakley_setdhgroup(pfsgroup, &iph2->pfsgrp) < 0) { 1223 plog(LLV_ERROR, LOCATION, NULL, 1224 "failed to set DH value.\n"); 1225 goto end; 1226 } 1227 /* generate DH public value */ 1228 if (oakley_dh_generate(iph2->pfsgrp, 1229 &iph2->dhpub, &iph2->dhpriv) < 0) { 1230 goto end; 1231 } 1232 } 1233 1234 /* create SA;NONCE payload, and KE and ID if need */ 1235 tlen = sizeof(*gen) + iph2->sa_ret->l 1236 + sizeof(*gen) + iph2->nonce->l; 1237 if (iph2->dhpub_p != NULL && pfsgroup != 0) 1238 tlen += (sizeof(*gen) + iph2->dhpub->l); 1239 if (iph2->id_p != NULL) 1240 tlen += (sizeof(*gen) + iph2->id_p->l 1241 + sizeof(*gen) + iph2->id->l); 1242 1243 body = vmalloc(tlen); 1244 if (body == NULL) { 1245 plog(LLV_ERROR, LOCATION, NULL, 1246 "failed to get buffer to send.\n"); 1247 goto end; 1248 } 1249 p = body->v; 1250 1251 /* make SA payload */ 1252 p = set_isakmp_payload(body->v, iph2->sa_ret, ISAKMP_NPTYPE_NONCE); 1253 1254 /* add NONCE payload */ 1255 np_p = &((struct isakmp_gen *)p)->np; /* XXX */ 1256 p = set_isakmp_payload(p, iph2->nonce, 1257 (iph2->dhpub_p != NULL && pfsgroup != 0) 1258 ? ISAKMP_NPTYPE_KE 1259 : (iph2->id_p != NULL 1260 ? ISAKMP_NPTYPE_ID 1261 : ISAKMP_NPTYPE_NONE)); 1262 1263 /* add KE payload if need. */ 1264 if (iph2->dhpub_p != NULL && pfsgroup != 0) { 1265 np_p = &((struct isakmp_gen *)p)->np; /* XXX */ 1266 p = set_isakmp_payload(p, iph2->dhpub, 1267 (iph2->id_p == NULL) 1268 ? ISAKMP_NPTYPE_NONE 1269 : ISAKMP_NPTYPE_ID); 1270 } 1271 1272 /* add ID payloads received. */ 1273 if (iph2->id_p != NULL) { 1274 /* IDci */ 1275 p = set_isakmp_payload(p, iph2->id_p, ISAKMP_NPTYPE_ID); 1276 /* IDcr */ 1277 np_p = &((struct isakmp_gen *)p)->np; /* XXX */ 1278 p = set_isakmp_payload(p, iph2->id, ISAKMP_NPTYPE_NONE); 1279 } 1280 1281 /* add a RESPONDER-LIFETIME notify payload if needed */ 1282 { 1283 vchar_t *data = NULL; 1284 struct saprop *pp = iph2->approval; 1285 struct saproto *pr; 1286 1287 if (pp->claim & IPSECDOI_ATTR_SA_LD_TYPE_SEC) { 1288 u_int32_t v = htonl((u_int32_t)pp->lifetime); 1289 data = isakmp_add_attr_l(data, IPSECDOI_ATTR_SA_LD_TYPE, 1290 IPSECDOI_ATTR_SA_LD_TYPE_SEC); 1291 if (!data) 1292 goto end; 1293 data = isakmp_add_attr_v(data, IPSECDOI_ATTR_SA_LD, 1294 (caddr_t)&v, sizeof(v)); 1295 if (!data) 1296 goto end; 1297 } 1298 if (pp->claim & IPSECDOI_ATTR_SA_LD_TYPE_KB) { 1299 u_int32_t v = htonl((u_int32_t)pp->lifebyte); 1300 data = isakmp_add_attr_l(data, IPSECDOI_ATTR_SA_LD_TYPE, 1301 IPSECDOI_ATTR_SA_LD_TYPE_KB); 1302 if (!data) 1303 goto end; 1304 data = isakmp_add_attr_v(data, IPSECDOI_ATTR_SA_LD, 1305 (caddr_t)&v, sizeof(v)); 1306 if (!data) 1307 goto end; 1308 } 1309 1310 /* 1311 * XXX Is there only single RESPONDER-LIFETIME payload in a IKE message 1312 * in the case of SA bundle ? 1313 */ 1314 if (data) { 1315 for (pr = pp->head; pr; pr = pr->next) { 1316 body = isakmp_add_pl_n(body, &np_p, 1317 ISAKMP_NTYPE_RESPONDER_LIFETIME, pr, data); 1318 if (!body) { 1319 vfree(data); 1320 return error; /* XXX */ 1321 } 1322 } 1323 vfree(data); 1324 } 1325 } 1326 1327 /* generate HASH(2) */ 1328 { 1329 vchar_t *tmp; 1330 1331 tmp = vmalloc(iph2->nonce_p->l + body->l); 1332 if (tmp == NULL) { 1333 plog(LLV_ERROR, LOCATION, NULL, 1334 "failed to get hash buffer.\n"); 1335 goto end; 1336 } 1337 memcpy(tmp->v, iph2->nonce_p->v, iph2->nonce_p->l); 1338 memcpy(tmp->v + iph2->nonce_p->l, body->v, body->l); 1339 1340 hash = oakley_compute_hash1(iph2->ph1, iph2->msgid, tmp); 1341 vfree(tmp); 1342 1343 if (hash == NULL) 1344 goto end; 1345 } 1346 1347 /* send isakmp payload */ 1348 iph2->sendbuf = quick_ir1mx(iph2, body, hash); 1349 if (iph2->sendbuf == NULL) 1350 goto end; 1351 1352 /* send the packet, add to the schedule to resend */ 1353 iph2->retry_counter = iph2->ph1->rmconf->retry_counter; 1354 if (isakmp_ph2resend(iph2) == -1) 1355 goto end; 1356 1357 /* the sending message is added to the received-list. */ 1358 if (add_recvdpkt(iph2->ph1->remote, iph2->ph1->local, iph2->sendbuf, iph2->msg1) == -1) { 1359 plog(LLV_ERROR , LOCATION, NULL, 1360 "failed to add a response packet to the tree.\n"); 1361 goto end; 1362 } 1363 1364 /* change status of isakmp status entry */ 1365 iph2->status = PHASE2ST_MSG1SENT; 1366 1367 error = 0; 1368 1369end: 1370 if (body != NULL) 1371 vfree(body); 1372 if (hash != NULL) 1373 vfree(hash); 1374 1375 return error; 1376} 1377 1378/* 1379 * receive from initiator 1380 * HDR*, HASH(3) 1381 */ 1382int 1383quick_r3recv(iph2, msg0) 1384 struct ph2handle *iph2; 1385 vchar_t *msg0; 1386{ 1387 vchar_t *msg = NULL; 1388 vchar_t *pbuf = NULL; /* for payload parsing */ 1389 struct isakmp_parse_t *pa; 1390 struct isakmp_pl_hash *hash = NULL; 1391 int error = ISAKMP_INTERNAL_ERROR; 1392 1393 /* validity check */ 1394 if (iph2->status != PHASE2ST_MSG1SENT) { 1395 plog(LLV_ERROR, LOCATION, NULL, 1396 "status mismatched %d.\n", iph2->status); 1397 goto end; 1398 } 1399 1400 /* decrypt packet */ 1401 if (!ISSET(((struct isakmp *)msg0->v)->flags, ISAKMP_FLAG_E)) { 1402 plog(LLV_ERROR, LOCATION, iph2->ph1->remote, 1403 "Packet wasn't encrypted.\n"); 1404 goto end; 1405 } 1406 msg = oakley_do_decrypt(iph2->ph1, msg0, iph2->ivm->iv, iph2->ivm->ive); 1407 if (msg == NULL) 1408 goto end; 1409 1410 /* validate the type of next payload */ 1411 pbuf = isakmp_parse(msg); 1412 if (pbuf == NULL) 1413 goto end; 1414 1415 for (pa = (struct isakmp_parse_t *)pbuf->v; 1416 pa->type != ISAKMP_NPTYPE_NONE; 1417 pa++) { 1418 1419 switch (pa->type) { 1420 case ISAKMP_NPTYPE_HASH: 1421 hash = (struct isakmp_pl_hash *)pa->ptr; 1422 break; 1423 case ISAKMP_NPTYPE_N: 1424 isakmp_check_notify(pa->ptr, iph2->ph1); 1425 break; 1426 default: 1427 /* don't send information, see ident_r1recv() */ 1428 plog(LLV_ERROR, LOCATION, iph2->ph1->remote, 1429 "ignore the packet, " 1430 "received unexpecting payload type %d.\n", 1431 pa->type); 1432 goto end; 1433 } 1434 } 1435 1436 /* payload existency check */ 1437 if (hash == NULL) { 1438 plog(LLV_ERROR, LOCATION, iph2->ph1->remote, 1439 "few isakmp message received.\n"); 1440 goto end; 1441 } 1442 1443 /* validate HASH(3) */ 1444 /* HASH(3) = prf(SKEYID_a, 0 | M-ID | Ni_b | Nr_b) */ 1445 { 1446 char *r_hash; 1447 vchar_t *my_hash = NULL; 1448 vchar_t *tmp = NULL; 1449 int result; 1450 1451 r_hash = (char *)hash + sizeof(*hash); 1452 1453 plog(LLV_DEBUG, LOCATION, NULL, "HASH(3) validate:"); 1454 plogdump(LLV_DEBUG, r_hash, ntohs(hash->h.len) - sizeof(*hash)); 1455 1456 tmp = vmalloc(iph2->nonce_p->l + iph2->nonce->l); 1457 if (tmp == NULL) { 1458 plog(LLV_ERROR, LOCATION, NULL, 1459 "failed to get hash buffer.\n"); 1460 goto end; 1461 } 1462 memcpy(tmp->v, iph2->nonce_p->v, iph2->nonce_p->l); 1463 memcpy(tmp->v + iph2->nonce_p->l, iph2->nonce->v, iph2->nonce->l); 1464 1465 my_hash = oakley_compute_hash3(iph2->ph1, iph2->msgid, tmp); 1466 vfree(tmp); 1467 if (my_hash == NULL) 1468 goto end; 1469 1470 result = memcmp(my_hash->v, r_hash, my_hash->l); 1471 vfree(my_hash); 1472 1473 if (result) { 1474 plog(LLV_ERROR, LOCATION, iph2->ph1->remote, 1475 "HASH(3) mismatch.\n"); 1476 error = ISAKMP_NTYPE_INVALID_HASH_INFORMATION; 1477 goto end; 1478 } 1479 } 1480 1481 /* if there is commit bit, don't set up SA now. */ 1482 if (ISSET(iph2->flags, ISAKMP_FLAG_C)) { 1483 iph2->status = PHASE2ST_COMMIT; 1484 } else 1485 iph2->status = PHASE2ST_STATUS6; 1486 1487 error = 0; 1488 1489end: 1490 if (pbuf != NULL) 1491 vfree(pbuf); 1492 if (msg != NULL) 1493 vfree(msg); 1494 1495 return error; 1496} 1497 1498/* 1499 * send to initiator 1500 * HDR#*, HASH(4), notify 1501 */ 1502int 1503quick_r3send(iph2, msg0) 1504 struct ph2handle *iph2; 1505 vchar_t *msg0; 1506{ 1507 vchar_t *buf = NULL; 1508 vchar_t *myhash = NULL; 1509 struct isakmp_pl_n *n; 1510 vchar_t *notify = NULL; 1511 char *p; 1512 int tlen; 1513 int error = ISAKMP_INTERNAL_ERROR; 1514 1515 /* validity check */ 1516 if (iph2->status != PHASE2ST_COMMIT) { 1517 plog(LLV_ERROR, LOCATION, NULL, 1518 "status mismatched %d.\n", iph2->status); 1519 goto end; 1520 } 1521 1522 /* generate HASH(4) */ 1523 /* XXX What can I do in the case of multiple different SA */ 1524 plog(LLV_DEBUG, LOCATION, NULL, "HASH(4) generate\n"); 1525 1526 /* XXX What should I do if there are multiple SAs ? */ 1527 tlen = sizeof(struct isakmp_pl_n) + iph2->approval->head->spisize; 1528 notify = vmalloc(tlen); 1529 if (notify == NULL) { 1530 plog(LLV_ERROR, LOCATION, NULL, 1531 "failed to get notify buffer.\n"); 1532 goto end; 1533 } 1534 n = (struct isakmp_pl_n *)notify->v; 1535 n->h.np = ISAKMP_NPTYPE_NONE; 1536 n->h.len = htons(tlen); 1537 n->doi = htonl(IPSEC_DOI); 1538 n->proto_id = iph2->approval->head->proto_id; 1539 n->spi_size = sizeof(iph2->approval->head->spisize); 1540 n->type = htons(ISAKMP_NTYPE_CONNECTED); 1541 memcpy(n + 1, &iph2->approval->head->spi, iph2->approval->head->spisize); 1542 1543 myhash = oakley_compute_hash1(iph2->ph1, iph2->msgid, notify); 1544 if (myhash == NULL) 1545 goto end; 1546 1547 /* create buffer for isakmp payload */ 1548 tlen = sizeof(struct isakmp) 1549 + sizeof(struct isakmp_gen) + myhash->l 1550 + notify->l; 1551 buf = vmalloc(tlen); 1552 if (buf == NULL) { 1553 plog(LLV_ERROR, LOCATION, NULL, 1554 "failed to get buffer to send.\n"); 1555 goto end; 1556 } 1557 1558 /* create isakmp header */ 1559 p = set_isakmp_header2(buf, iph2, ISAKMP_NPTYPE_HASH); 1560 if (p == NULL) 1561 goto end; 1562 1563 /* add HASH(4) payload */ 1564 p = set_isakmp_payload(p, myhash, ISAKMP_NPTYPE_N); 1565 1566 /* add notify payload */ 1567 memcpy(p, notify->v, notify->l); 1568 1569#ifdef HAVE_PRINT_ISAKMP_C 1570 isakmp_printpacket(buf, iph2->ph1->local, iph2->ph1->remote, 1); 1571#endif 1572 1573 /* encoding */ 1574 iph2->sendbuf = oakley_do_encrypt(iph2->ph1, buf, iph2->ivm->ive, iph2->ivm->iv); 1575 if (iph2->sendbuf == NULL) 1576 goto end; 1577 1578 /* send the packet */ 1579 if (isakmp_send(iph2->ph1, iph2->sendbuf) < 0) 1580 goto end; 1581 1582 /* the sending message is added to the received-list. */ 1583 if (add_recvdpkt(iph2->ph1->remote, iph2->ph1->local, iph2->sendbuf, msg0) == -1) { 1584 plog(LLV_ERROR , LOCATION, NULL, 1585 "failed to add a response packet to the tree.\n"); 1586 goto end; 1587 } 1588 1589 iph2->status = PHASE2ST_COMMIT; 1590 1591 error = 0; 1592 1593end: 1594 if (buf != NULL) 1595 vfree(buf); 1596 if (myhash != NULL) 1597 vfree(myhash); 1598 if (notify != NULL) 1599 vfree(notify); 1600 1601 return error; 1602} 1603 1604int 1605tunnel_mode_prop(p) 1606 struct saprop *p; 1607{ 1608 struct saproto *pr; 1609 1610 for (pr = p->head; pr; pr = pr->next) 1611 if (pr->encmode == IPSECDOI_ATTR_ENC_MODE_TUNNEL) 1612 return 1; 1613 return 0; 1614} 1615 1616/* 1617 * set SA to kernel. 1618 */ 1619int 1620quick_r3prep(iph2, msg0) 1621 struct ph2handle *iph2; 1622 vchar_t *msg0; 1623{ 1624 int error = ISAKMP_INTERNAL_ERROR; 1625 1626 /* validity check */ 1627 if (iph2->status != PHASE2ST_STATUS6) { 1628 plog(LLV_ERROR, LOCATION, NULL, 1629 "status mismatched %d.\n", iph2->status); 1630 goto end; 1631 } 1632 1633 /* compute both of KEYMATs */ 1634 if (oakley_compute_keymat(iph2, RESPONDER) < 0) 1635 goto end; 1636 1637 iph2->status = PHASE2ST_ADDSA; 1638 iph2->flags ^= ISAKMP_FLAG_C; /* reset bit */ 1639 1640 /* don't anything if local test mode. */ 1641 if (f_local) { 1642 error = 0; 1643 goto end; 1644 } 1645 1646 /* Do UPDATE as responder */ 1647 plog(LLV_DEBUG, LOCATION, NULL, "call pk_sendupdate\n"); 1648 if (pk_sendupdate(iph2) < 0) { 1649 plog(LLV_ERROR, LOCATION, NULL, "pfkey update failed.\n"); 1650 goto end; 1651 } 1652 plog(LLV_DEBUG, LOCATION, NULL, "pfkey update sent.\n"); 1653 1654 /* Do ADD for responder */ 1655 if (pk_sendadd(iph2) < 0) { 1656 plog(LLV_ERROR, LOCATION, NULL, "pfkey add failed.\n"); 1657 goto end; 1658 } 1659 plog(LLV_DEBUG, LOCATION, NULL, "pfkey add sent.\n"); 1660 1661 /* 1662 * set policies into SPD if the policy is generated 1663 * from peer's policy. 1664 */ 1665 if (iph2->spidx_gen) { 1666 1667 struct policyindex *spidx; 1668 struct sockaddr_storage addr; 1669 u_int8_t pref; 1670 struct sockaddr *src = iph2->src; 1671 struct sockaddr *dst = iph2->dst; 1672 1673 /* make inbound policy */ 1674 iph2->src = dst; 1675 iph2->dst = src; 1676 if (pk_sendspdupdate2(iph2) < 0) { 1677 plog(LLV_ERROR, LOCATION, NULL, 1678 "pfkey spdupdate2(inbound) failed.\n"); 1679 goto end; 1680 } 1681 plog(LLV_DEBUG, LOCATION, NULL, 1682 "pfkey spdupdate2(inbound) sent.\n"); 1683 1684 spidx = (struct policyindex *)iph2->spidx_gen; 1685#ifdef HAVE_POLICY_FWD 1686 /* make forward policy if required */ 1687 if (tunnel_mode_prop(iph2->approval)) { 1688 spidx->dir = IPSEC_DIR_FWD; 1689 if (pk_sendspdupdate2(iph2) < 0) { 1690 plog(LLV_ERROR, LOCATION, NULL, 1691 "pfkey spdupdate2(forward) failed.\n"); 1692 goto end; 1693 } 1694 plog(LLV_DEBUG, LOCATION, NULL, 1695 "pfkey spdupdate2(forward) sent.\n"); 1696 } 1697#endif 1698 1699 /* make outbound policy */ 1700 iph2->src = src; 1701 iph2->dst = dst; 1702 spidx->dir = IPSEC_DIR_OUTBOUND; 1703 addr = spidx->src; 1704 spidx->src = spidx->dst; 1705 spidx->dst = addr; 1706 pref = spidx->prefs; 1707 spidx->prefs = spidx->prefd; 1708 spidx->prefd = pref; 1709 1710 if (pk_sendspdupdate2(iph2) < 0) { 1711 plog(LLV_ERROR, LOCATION, NULL, 1712 "pfkey spdupdate2(outbound) failed.\n"); 1713 goto end; 1714 } 1715 plog(LLV_DEBUG, LOCATION, NULL, 1716 "pfkey spdupdate2(outbound) sent.\n"); 1717 1718 /* spidx_gen is unnecessary any more */ 1719 delsp_bothdir((struct policyindex *)iph2->spidx_gen); 1720 racoon_free(iph2->spidx_gen); 1721 iph2->spidx_gen = NULL; 1722 iph2->generated_spidx=1; 1723 } 1724 1725 error = 0; 1726 1727end: 1728 return error; 1729} 1730 1731/* 1732 * create HASH, body (SA, NONCE) payload with isakmp header. 1733 */ 1734static vchar_t * 1735quick_ir1mx(iph2, body, hash) 1736 struct ph2handle *iph2; 1737 vchar_t *body, *hash; 1738{ 1739 struct isakmp *isakmp; 1740 vchar_t *buf = NULL, *new = NULL; 1741 char *p; 1742 int tlen; 1743 struct isakmp_gen *gen; 1744 int error = ISAKMP_INTERNAL_ERROR; 1745 1746 /* create buffer for isakmp payload */ 1747 tlen = sizeof(*isakmp) 1748 + sizeof(*gen) + hash->l 1749 + body->l; 1750 buf = vmalloc(tlen); 1751 if (buf == NULL) { 1752 plog(LLV_ERROR, LOCATION, NULL, 1753 "failed to get buffer to send.\n"); 1754 goto end; 1755 } 1756 1757 /* re-set encryption flag, for serurity. */ 1758 iph2->flags |= ISAKMP_FLAG_E; 1759 1760 /* set isakmp header */ 1761 p = set_isakmp_header2(buf, iph2, ISAKMP_NPTYPE_HASH); 1762 if (p == NULL) 1763 goto end; 1764 1765 /* add HASH payload */ 1766 /* XXX is next type always SA ? */ 1767 p = set_isakmp_payload(p, hash, ISAKMP_NPTYPE_SA); 1768 1769 /* add body payload */ 1770 memcpy(p, body->v, body->l); 1771 1772#ifdef HAVE_PRINT_ISAKMP_C 1773 isakmp_printpacket(buf, iph2->ph1->local, iph2->ph1->remote, 1); 1774#endif 1775 1776 /* encoding */ 1777 new = oakley_do_encrypt(iph2->ph1, buf, iph2->ivm->ive, iph2->ivm->iv); 1778 1779 if (new == NULL) 1780 goto end; 1781 1782 vfree(buf); 1783 1784 buf = new; 1785 1786 error = 0; 1787 1788end: 1789 if (error && buf != NULL) { 1790 vfree(buf); 1791 buf = NULL; 1792 } 1793 1794 return buf; 1795} 1796 1797/* 1798 * get remote's sainfo. 1799 * NOTE: this function is for responder. 1800 */ 1801static int 1802get_sainfo_r(iph2) 1803 struct ph2handle *iph2; 1804{ 1805 vchar_t *idsrc = NULL, *iddst = NULL; 1806 int prefixlen; 1807 int error = ISAKMP_INTERNAL_ERROR; 1808 int remoteid = 0; 1809 1810 if (iph2->id == NULL) { 1811 switch (iph2->src->sa_family) { 1812 case AF_INET: 1813 prefixlen = sizeof(struct in_addr) << 3; 1814 break; 1815 case AF_INET6: 1816 prefixlen = sizeof(struct in6_addr) << 3; 1817 break; 1818 default: 1819 plog(LLV_ERROR, LOCATION, NULL, 1820 "invalid family: %d\n", iph2->src->sa_family); 1821 goto end; 1822 } 1823 idsrc = ipsecdoi_sockaddr2id(iph2->src, prefixlen, 1824 IPSEC_ULPROTO_ANY); 1825 } else { 1826 idsrc = vdup(iph2->id); 1827 } 1828 if (idsrc == NULL) { 1829 plog(LLV_ERROR, LOCATION, NULL, 1830 "failed to set ID for source.\n"); 1831 goto end; 1832 } 1833 1834 if (iph2->id_p == NULL) { 1835 switch (iph2->dst->sa_family) { 1836 case AF_INET: 1837 prefixlen = sizeof(struct in_addr) << 3; 1838 break; 1839 case AF_INET6: 1840 prefixlen = sizeof(struct in6_addr) << 3; 1841 break; 1842 default: 1843 plog(LLV_ERROR, LOCATION, NULL, 1844 "invalid family: %d\n", iph2->dst->sa_family); 1845 goto end; 1846 } 1847 iddst = ipsecdoi_sockaddr2id(iph2->dst, prefixlen, 1848 IPSEC_ULPROTO_ANY); 1849 } else { 1850 iddst = vdup(iph2->id_p); 1851 } 1852 if (iddst == NULL) { 1853 plog(LLV_ERROR, LOCATION, NULL, 1854 "failed to set ID for destination.\n"); 1855 goto end; 1856 } 1857 1858 { 1859 struct remoteconf *conf; 1860 conf = getrmconf(iph2->dst); 1861 if (conf != NULL) 1862 remoteid=conf->ph1id; 1863 else{ 1864 plog(LLV_DEBUG, LOCATION, NULL, "Warning: no valid rmconf !\n"); 1865 remoteid=0; 1866 } 1867 1868 } 1869 1870 iph2->sainfo = getsainfo(idsrc, iddst, iph2->ph1->id_p, remoteid); 1871 if (iph2->sainfo == NULL) { 1872 plog(LLV_ERROR, LOCATION, NULL, 1873 "failed to get sainfo.\n"); 1874 goto end; 1875 } 1876 1877#ifdef ENABLE_HYBRID 1878 /* xauth group inclusion check */ 1879 if (iph2->sainfo->group != NULL) 1880 if(group_check(iph2->ph1,&iph2->sainfo->group->v,1)) 1881 goto end; 1882#endif 1883 1884 plog(LLV_DEBUG, LOCATION, NULL, 1885 "selected sainfo: %s\n", sainfo2str(iph2->sainfo)); 1886 1887 error = 0; 1888end: 1889 if (idsrc) 1890 vfree(idsrc); 1891 if (iddst) 1892 vfree(iddst); 1893 1894 return error; 1895} 1896 1897/* 1898 * Copy both IP addresses in ID payloads into [src,dst]_id if both ID types 1899 * are IP address and same address family. 1900 * Then get remote's policy from SPD copied from kernel. 1901 * If the type of ID payload is address or subnet type, then the index is 1902 * made from the payload. If there is no ID payload, or the type of ID 1903 * payload is NOT address type, then the index is made from the address 1904 * pair of phase 1. 1905 * NOTE: This function is only for responder. 1906 */ 1907static int 1908get_proposal_r(iph2) 1909 struct ph2handle *iph2; 1910{ 1911 struct policyindex spidx; 1912 struct secpolicy *sp_in, *sp_out; 1913 int idi2type = 0; /* switch whether copy IDs into id[src,dst]. */ 1914 int error = ISAKMP_INTERNAL_ERROR; 1915 1916 /* check the existence of ID payload */ 1917 if ((iph2->id_p != NULL && iph2->id == NULL) 1918 || (iph2->id_p == NULL && iph2->id != NULL)) { 1919 plog(LLV_ERROR, LOCATION, NULL, 1920 "Both IDs wasn't found in payload.\n"); 1921 return ISAKMP_NTYPE_INVALID_ID_INFORMATION; 1922 } 1923 1924 /* make sure if id[src,dst] is null. */ 1925 if (iph2->src_id || iph2->dst_id) { 1926 plog(LLV_ERROR, LOCATION, NULL, 1927 "Why do ID[src,dst] exist already.\n"); 1928 return ISAKMP_INTERNAL_ERROR; 1929 } 1930 1931 memset(&spidx, 0, sizeof(spidx)); 1932 1933#define _XIDT(d) ((struct ipsecdoi_id_b *)(d)->v)->type 1934 1935 /* make a spidx; a key to search SPD */ 1936 spidx.dir = IPSEC_DIR_INBOUND; 1937 spidx.ul_proto = 0; 1938 1939 /* 1940 * make destination address in spidx from either ID payload 1941 * or phase 1 address into a address in spidx. 1942 */ 1943 if (iph2->id != NULL 1944 && (_XIDT(iph2->id) == IPSECDOI_ID_IPV4_ADDR 1945 || _XIDT(iph2->id) == IPSECDOI_ID_IPV6_ADDR 1946 || _XIDT(iph2->id) == IPSECDOI_ID_IPV4_ADDR_SUBNET 1947 || _XIDT(iph2->id) == IPSECDOI_ID_IPV6_ADDR_SUBNET)) { 1948 /* get a destination address of a policy */ 1949 error = ipsecdoi_id2sockaddr(iph2->id, 1950 (struct sockaddr *)&spidx.dst, 1951 &spidx.prefd, &spidx.ul_proto); 1952 if (error) 1953 return error; 1954 1955#ifdef INET6 1956 /* 1957 * get scopeid from the SA address. 1958 * note that the phase 1 source address is used as 1959 * a destination address to search for a inbound policy entry 1960 * because rcoon is responder. 1961 */ 1962 if (_XIDT(iph2->id) == IPSECDOI_ID_IPV6_ADDR) { 1963 error = setscopeid((struct sockaddr *)&spidx.dst, 1964 iph2->src); 1965 if (error) 1966 return error; 1967 } 1968#endif 1969 1970 if (_XIDT(iph2->id) == IPSECDOI_ID_IPV4_ADDR 1971 || _XIDT(iph2->id) == IPSECDOI_ID_IPV6_ADDR) 1972 idi2type = _XIDT(iph2->id); 1973 1974 } else { 1975 1976 plog(LLV_DEBUG, LOCATION, NULL, 1977 "get a destination address of SP index " 1978 "from phase1 address " 1979 "due to no ID payloads found " 1980 "OR because ID type is not address.\n"); 1981 1982 /* 1983 * copy the SOURCE address of IKE into the DESTINATION address 1984 * of the key to search the SPD because the direction of policy 1985 * is inbound. 1986 */ 1987 memcpy(&spidx.dst, iph2->src, sysdep_sa_len(iph2->src)); 1988 switch (spidx.dst.ss_family) { 1989 case AF_INET: 1990 spidx.prefd = sizeof(struct in_addr) << 3; 1991 break; 1992#ifdef INET6 1993 case AF_INET6: 1994 spidx.prefd = sizeof(struct in6_addr) << 3; 1995 break; 1996#endif 1997 default: 1998 spidx.prefd = 0; 1999 break; 2000 } 2001 } 2002 2003 /* make source address in spidx */ 2004 if (iph2->id_p != NULL 2005 && (_XIDT(iph2->id_p) == IPSECDOI_ID_IPV4_ADDR 2006 || _XIDT(iph2->id_p) == IPSECDOI_ID_IPV6_ADDR 2007 || _XIDT(iph2->id_p) == IPSECDOI_ID_IPV4_ADDR_SUBNET 2008 || _XIDT(iph2->id_p) == IPSECDOI_ID_IPV6_ADDR_SUBNET)) { 2009 /* get a source address of inbound SA */ 2010 error = ipsecdoi_id2sockaddr(iph2->id_p, 2011 (struct sockaddr *)&spidx.src, 2012 &spidx.prefs, &spidx.ul_proto); 2013 if (error) 2014 return error; 2015 2016#ifdef INET6 2017 /* 2018 * get scopeid from the SA address. 2019 * for more detail, see above of this function. 2020 */ 2021 if (_XIDT(iph2->id_p) == IPSECDOI_ID_IPV6_ADDR) { 2022 error = setscopeid((struct sockaddr *)&spidx.src, 2023 iph2->dst); 2024 if (error) 2025 return error; 2026 } 2027#endif 2028 2029 /* make id[src,dst] if both ID types are IP address and same */ 2030 if (_XIDT(iph2->id_p) == idi2type 2031 && spidx.dst.ss_family == spidx.src.ss_family) { 2032 iph2->src_id = dupsaddr((struct sockaddr *)&spidx.dst); 2033 if (iph2->src_id == NULL) { 2034 plog(LLV_ERROR, LOCATION, NULL, 2035 "buffer allocation failed.\n"); 2036 return ISAKMP_INTERNAL_ERROR; 2037 } 2038 iph2->dst_id = dupsaddr((struct sockaddr *)&spidx.src); 2039 if (iph2->dst_id == NULL) { 2040 plog(LLV_ERROR, LOCATION, NULL, 2041 "buffer allocation failed.\n"); 2042 return ISAKMP_INTERNAL_ERROR; 2043 } 2044 } 2045 2046 } else { 2047 plog(LLV_DEBUG, LOCATION, NULL, 2048 "get a source address of SP index " 2049 "from phase1 address " 2050 "due to no ID payloads found " 2051 "OR because ID type is not address.\n"); 2052 2053 /* see above comment. */ 2054 memcpy(&spidx.src, iph2->dst, sysdep_sa_len(iph2->dst)); 2055 switch (spidx.src.ss_family) { 2056 case AF_INET: 2057 spidx.prefs = sizeof(struct in_addr) << 3; 2058 break; 2059#ifdef INET6 2060 case AF_INET6: 2061 spidx.prefs = sizeof(struct in6_addr) << 3; 2062 break; 2063#endif 2064 default: 2065 spidx.prefs = 0; 2066 break; 2067 } 2068 } 2069 2070#undef _XIDT 2071 2072 plog(LLV_DEBUG, LOCATION, NULL, 2073 "get a src address from ID payload " 2074 "%s prefixlen=%u ul_proto=%u\n", 2075 saddr2str((struct sockaddr *)&spidx.src), 2076 spidx.prefs, spidx.ul_proto); 2077 plog(LLV_DEBUG, LOCATION, NULL, 2078 "get dst address from ID payload " 2079 "%s prefixlen=%u ul_proto=%u\n", 2080 saddr2str((struct sockaddr *)&spidx.dst), 2081 spidx.prefd, spidx.ul_proto); 2082 2083 /* 2084 * convert the ul_proto if it is 0 2085 * because 0 in ID payload means a wild card. 2086 */ 2087 if (spidx.ul_proto == 0) 2088 spidx.ul_proto = IPSEC_ULPROTO_ANY; 2089 2090#ifdef HAVE_SECCTX 2091 /* 2092 * Need to use security context in spidx to ensure the correct 2093 * policy is selected. The only way to get the security context 2094 * is to look into the proposal sent by peer ahead of time. 2095 */ 2096 if (get_security_context(iph2->sa, &spidx)) { 2097 plog(LLV_ERROR, LOCATION, NULL, 2098 "error occurred trying to get security context.\n"); 2099 return ISAKMP_INTERNAL_ERROR; 2100 } 2101#endif /* HAVE_SECCTX */ 2102 2103 /* get inbound policy */ 2104 sp_in = getsp_r(&spidx); 2105 if (sp_in == NULL) { 2106 if (iph2->ph1->rmconf->gen_policy) { 2107 plog(LLV_INFO, LOCATION, NULL, 2108 "no policy found, " 2109 "try to generate the policy : %s\n", 2110 spidx2str(&spidx)); 2111 iph2->spidx_gen = racoon_malloc(sizeof(spidx)); 2112 if (!iph2->spidx_gen) { 2113 plog(LLV_ERROR, LOCATION, NULL, 2114 "buffer allocation failed.\n"); 2115 return ISAKMP_INTERNAL_ERROR; 2116 } 2117 memcpy(iph2->spidx_gen, &spidx, sizeof(spidx)); 2118 return -2; /* special value */ 2119 } 2120 plog(LLV_ERROR, LOCATION, NULL, 2121 "no policy found: %s\n", spidx2str(&spidx)); 2122 return ISAKMP_INTERNAL_ERROR; 2123 } 2124 /* Refresh existing generated policies 2125 */ 2126 if (iph2->ph1->rmconf->gen_policy) { 2127 plog(LLV_INFO, LOCATION, NULL, 2128 "Update the generated policy : %s\n", 2129 spidx2str(&spidx)); 2130 iph2->spidx_gen = racoon_malloc(sizeof(spidx)); 2131 if (!iph2->spidx_gen) { 2132 plog(LLV_ERROR, LOCATION, NULL, 2133 "buffer allocation failed.\n"); 2134 return ISAKMP_INTERNAL_ERROR; 2135 } 2136 memcpy(iph2->spidx_gen, &spidx, sizeof(spidx)); 2137 } 2138 2139 /* get outbound policy */ 2140 { 2141 struct sockaddr_storage addr; 2142 u_int8_t pref; 2143 2144 spidx.dir = IPSEC_DIR_OUTBOUND; 2145 addr = spidx.src; 2146 spidx.src = spidx.dst; 2147 spidx.dst = addr; 2148 pref = spidx.prefs; 2149 spidx.prefs = spidx.prefd; 2150 spidx.prefd = pref; 2151 2152 sp_out = getsp_r(&spidx); 2153 if (!sp_out) { 2154 plog(LLV_WARNING, LOCATION, NULL, 2155 "no outbound policy found: %s\n", 2156 spidx2str(&spidx)); 2157 } 2158 } 2159 2160 plog(LLV_DEBUG, LOCATION, NULL, 2161 "suitable SP found:%s\n", spidx2str(&spidx)); 2162 2163 /* 2164 * In the responder side, the inbound policy should be using IPsec. 2165 * outbound policy is not checked currently. 2166 */ 2167 if (sp_in->policy != IPSEC_POLICY_IPSEC) { 2168 plog(LLV_ERROR, LOCATION, NULL, 2169 "policy found, but no IPsec required: %s\n", 2170 spidx2str(&spidx)); 2171 return ISAKMP_INTERNAL_ERROR; 2172 } 2173 2174 /* set new proposal derived from a policy into the iph2->proposal. */ 2175 if (set_proposal_from_policy(iph2, sp_in, sp_out) < 0) { 2176 plog(LLV_ERROR, LOCATION, NULL, 2177 "failed to create saprop.\n"); 2178 return ISAKMP_INTERNAL_ERROR; 2179 } 2180 2181#ifdef HAVE_SECCTX 2182 if (spidx.sec_ctx.ctx_str) { 2183 set_secctx_in_proposal(iph2, spidx); 2184 } 2185#endif /* HAVE_SECCTX */ 2186 2187 return 0; 2188} 2189 2190