Return to isakmp_ident.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / ipsec-tools / src / racoon |
1.1 ! misho 1: /* $NetBSD: isakmp_ident.c,v 1.13 2009/09/18 10:31:11 tteras Exp $ */ ! 2: ! 3: /* Id: isakmp_ident.c,v 1.21 2006/04/06 16:46:08 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: /* Identity Protecion Exchange (Main Mode) */ ! 35: ! 36: #include "config.h" ! 37: ! 38: #include <sys/types.h> ! 39: #include <sys/param.h> ! 40: ! 41: #include <stdlib.h> ! 42: #include <stdio.h> ! 43: #include <string.h> ! 44: #include <errno.h> ! 45: #if TIME_WITH_SYS_TIME ! 46: # include <sys/time.h> ! 47: # include <time.h> ! 48: #else ! 49: # if HAVE_SYS_TIME_H ! 50: # include <sys/time.h> ! 51: # else ! 52: # include <time.h> ! 53: # endif ! 54: #endif ! 55: ! 56: #include "var.h" ! 57: #include "misc.h" ! 58: #include "vmbuf.h" ! 59: #include "plog.h" ! 60: #include "sockmisc.h" ! 61: #include "schedule.h" ! 62: #include "debug.h" ! 63: ! 64: #include "localconf.h" ! 65: #include "remoteconf.h" ! 66: #include "isakmp_var.h" ! 67: #include "isakmp.h" ! 68: #include "evt.h" ! 69: #include "oakley.h" ! 70: #include "handler.h" ! 71: #include "ipsec_doi.h" ! 72: #include "crypto_openssl.h" ! 73: #include "pfkey.h" ! 74: #include "isakmp_ident.h" ! 75: #include "isakmp_inf.h" ! 76: #include "vendorid.h" ! 77: ! 78: #ifdef ENABLE_NATT ! 79: #include "nattraversal.h" ! 80: #endif ! 81: #ifdef HAVE_GSSAPI ! 82: #include "gssapi.h" ! 83: #endif ! 84: #ifdef ENABLE_HYBRID ! 85: #include <resolv.h> ! 86: #include "isakmp_xauth.h" ! 87: #include "isakmp_cfg.h" ! 88: #endif ! 89: #ifdef ENABLE_FRAG ! 90: #include "isakmp_frag.h" ! 91: #endif ! 92: ! 93: static vchar_t *ident_ir2mx __P((struct ph1handle *)); ! 94: static vchar_t *ident_ir3mx __P((struct ph1handle *)); ! 95: static int ident_recv_n __P((struct ph1handle *, struct isakmp_gen *)); ! 96: ! 97: /* %%% ! 98: * begin Identity Protection Mode as initiator. ! 99: */ ! 100: /* ! 101: * send to responder ! 102: * psk: HDR, SA ! 103: * sig: HDR, SA ! 104: * rsa: HDR, SA ! 105: * rev: HDR, SA ! 106: */ ! 107: int ! 108: ident_i1send(iph1, msg) ! 109: struct ph1handle *iph1; ! 110: vchar_t *msg; /* must be null */ ! 111: { ! 112: struct payload_list *plist = NULL; ! 113: int error = -1; ! 114: #ifdef ENABLE_NATT ! 115: vchar_t *vid_natt[MAX_NATT_VID_COUNT] = { NULL }; ! 116: int i; ! 117: #endif ! 118: #ifdef ENABLE_HYBRID ! 119: vchar_t *vid_xauth = NULL; ! 120: vchar_t *vid_unity = NULL; ! 121: #endif ! 122: #ifdef ENABLE_FRAG ! 123: vchar_t *vid_frag = NULL; ! 124: #endif ! 125: #ifdef ENABLE_DPD ! 126: vchar_t *vid_dpd = NULL; ! 127: #endif ! 128: /* validity check */ ! 129: if (msg != NULL) { ! 130: plog(LLV_ERROR, LOCATION, NULL, ! 131: "msg has to be NULL in this function.\n"); ! 132: goto end; ! 133: } ! 134: if (iph1->status != PHASE1ST_START) { ! 135: plog(LLV_ERROR, LOCATION, NULL, ! 136: "status mismatched %d.\n", iph1->status); ! 137: goto end; ! 138: } ! 139: ! 140: /* create isakmp index */ ! 141: memset(&iph1->index, 0, sizeof(iph1->index)); ! 142: isakmp_newcookie((caddr_t)&iph1->index, iph1->remote, iph1->local); ! 143: ! 144: /* create SA payload for my proposal */ ! 145: iph1->sa = ipsecdoi_setph1proposal(iph1->rmconf, ! 146: iph1->rmconf->proposal); ! 147: if (iph1->sa == NULL) ! 148: goto end; ! 149: ! 150: /* set SA payload to propose */ ! 151: plist = isakmp_plist_append(plist, iph1->sa, ISAKMP_NPTYPE_SA); ! 152: ! 153: #ifdef ENABLE_NATT ! 154: /* set VID payload for NAT-T if NAT-T support allowed in the config file */ ! 155: if (iph1->rmconf->nat_traversal) ! 156: plist = isakmp_plist_append_natt_vids(plist, vid_natt); ! 157: #endif ! 158: #ifdef ENABLE_HYBRID ! 159: /* Do we need Xauth VID? */ ! 160: switch (iph1->rmconf->proposal->authmethod) { ! 161: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I: ! 162: case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I: ! 163: case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I: ! 164: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I: ! 165: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I: ! 166: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I: ! 167: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I: ! 168: if ((vid_xauth = set_vendorid(VENDORID_XAUTH)) == NULL) ! 169: plog(LLV_ERROR, LOCATION, NULL, ! 170: "Xauth vendor ID generation failed\n"); ! 171: else ! 172: plist = isakmp_plist_append(plist, ! 173: vid_xauth, ISAKMP_NPTYPE_VID); ! 174: ! 175: if ((vid_unity = set_vendorid(VENDORID_UNITY)) == NULL) ! 176: plog(LLV_ERROR, LOCATION, NULL, ! 177: "Unity vendor ID generation failed\n"); ! 178: else ! 179: plist = isakmp_plist_append(plist, ! 180: vid_unity, ISAKMP_NPTYPE_VID); ! 181: break; ! 182: default: ! 183: break; ! 184: } ! 185: #endif ! 186: #ifdef ENABLE_FRAG ! 187: if (iph1->rmconf->ike_frag) { ! 188: if ((vid_frag = set_vendorid(VENDORID_FRAG)) == NULL) { ! 189: plog(LLV_ERROR, LOCATION, NULL, ! 190: "Frag vendorID construction failed\n"); ! 191: } else { ! 192: vid_frag = isakmp_frag_addcap(vid_frag, ! 193: VENDORID_FRAG_IDENT); ! 194: plist = isakmp_plist_append(plist, ! 195: vid_frag, ISAKMP_NPTYPE_VID); ! 196: } ! 197: } ! 198: #endif ! 199: #ifdef ENABLE_DPD ! 200: if(iph1->rmconf->dpd){ ! 201: vid_dpd = set_vendorid(VENDORID_DPD); ! 202: if (vid_dpd != NULL) ! 203: plist = isakmp_plist_append(plist, vid_dpd, ! 204: ISAKMP_NPTYPE_VID); ! 205: } ! 206: #endif ! 207: ! 208: iph1->sendbuf = isakmp_plist_set_all (&plist, iph1); ! 209: ! 210: #ifdef HAVE_PRINT_ISAKMP_C ! 211: isakmp_printpacket(iph1->sendbuf, iph1->local, iph1->remote, 0); ! 212: #endif ! 213: ! 214: /* send the packet, add to the schedule to resend */ ! 215: if (isakmp_ph1send(iph1) == -1) ! 216: goto end; ! 217: ! 218: iph1->status = PHASE1ST_MSG1SENT; ! 219: ! 220: error = 0; ! 221: ! 222: end: ! 223: #ifdef ENABLE_FRAG ! 224: if (vid_frag) ! 225: vfree(vid_frag); ! 226: #endif ! 227: #ifdef ENABLE_NATT ! 228: for (i = 0; i < MAX_NATT_VID_COUNT && vid_natt[i] != NULL; i++) ! 229: vfree(vid_natt[i]); ! 230: #endif ! 231: #ifdef ENABLE_HYBRID ! 232: if (vid_xauth != NULL) ! 233: vfree(vid_xauth); ! 234: if (vid_unity != NULL) ! 235: vfree(vid_unity); ! 236: #endif ! 237: #ifdef ENABLE_DPD ! 238: if (vid_dpd != NULL) ! 239: vfree(vid_dpd); ! 240: #endif ! 241: ! 242: return error; ! 243: } ! 244: ! 245: /* ! 246: * receive from responder ! 247: * psk: HDR, SA ! 248: * sig: HDR, SA ! 249: * rsa: HDR, SA ! 250: * rev: HDR, SA ! 251: */ ! 252: int ! 253: ident_i2recv(iph1, msg) ! 254: struct ph1handle *iph1; ! 255: vchar_t *msg; ! 256: { ! 257: vchar_t *pbuf = NULL; ! 258: struct isakmp_parse_t *pa; ! 259: vchar_t *satmp = NULL; ! 260: int error = -1; ! 261: ! 262: /* validity check */ ! 263: if (iph1->status != PHASE1ST_MSG1SENT) { ! 264: plog(LLV_ERROR, LOCATION, NULL, ! 265: "status mismatched %d.\n", iph1->status); ! 266: goto end; ! 267: } ! 268: ! 269: /* validate the type of next payload */ ! 270: /* ! 271: * NOTE: RedCreek(as responder) attaches N[responder-lifetime] here, ! 272: * if proposal-lifetime > lifetime-redcreek-wants. ! 273: * (see doi-08 4.5.4) ! 274: * => According to the seciton 4.6.3 in RFC 2407, This is illegal. ! 275: * NOTE: we do not really care about ordering of VID and N. ! 276: * does it matters? ! 277: * NOTE: even if there's multiple VID/N, we'll ignore them. ! 278: */ ! 279: pbuf = isakmp_parse(msg); ! 280: if (pbuf == NULL) ! 281: goto end; ! 282: pa = (struct isakmp_parse_t *)pbuf->v; ! 283: ! 284: /* SA payload is fixed postion */ ! 285: if (pa->type != ISAKMP_NPTYPE_SA) { ! 286: plog(LLV_ERROR, LOCATION, iph1->remote, ! 287: "received invalid next payload type %d, " ! 288: "expecting %d.\n", ! 289: pa->type, ISAKMP_NPTYPE_SA); ! 290: goto end; ! 291: } ! 292: if (isakmp_p2ph(&satmp, pa->ptr) < 0) ! 293: goto end; ! 294: pa++; ! 295: ! 296: for (/*nothing*/; ! 297: pa->type != ISAKMP_NPTYPE_NONE; ! 298: pa++) { ! 299: ! 300: switch (pa->type) { ! 301: case ISAKMP_NPTYPE_VID: ! 302: handle_vendorid(iph1, pa->ptr); ! 303: break; ! 304: default: ! 305: /* don't send information, see ident_r1recv() */ ! 306: plog(LLV_ERROR, LOCATION, iph1->remote, ! 307: "ignore the packet, " ! 308: "received unexpecting payload type %d.\n", ! 309: pa->type); ! 310: goto end; ! 311: } ! 312: } ! 313: ! 314: #ifdef ENABLE_NATT ! 315: if (NATT_AVAILABLE(iph1)) ! 316: plog(LLV_INFO, LOCATION, iph1->remote, ! 317: "Selected NAT-T version: %s\n", ! 318: vid_string_by_id(iph1->natt_options->version)); ! 319: #endif ! 320: ! 321: /* check SA payload and set approval SA for use */ ! 322: if (ipsecdoi_checkph1proposal(satmp, iph1) < 0) { ! 323: plog(LLV_ERROR, LOCATION, iph1->remote, ! 324: "failed to get valid proposal.\n"); ! 325: /* XXX send information */ ! 326: goto end; ! 327: } ! 328: VPTRINIT(iph1->sa_ret); ! 329: ! 330: iph1->status = PHASE1ST_MSG2RECEIVED; ! 331: ! 332: error = 0; ! 333: ! 334: end: ! 335: if (pbuf) ! 336: vfree(pbuf); ! 337: if (satmp) ! 338: vfree(satmp); ! 339: return error; ! 340: } ! 341: ! 342: /* ! 343: * send to responder ! 344: * psk: HDR, KE, Ni ! 345: * sig: HDR, KE, Ni ! 346: * gssapi: HDR, KE, Ni, GSSi ! 347: * rsa: HDR, KE, [ HASH(1), ] <IDi1_b>PubKey_r, <Ni_b>PubKey_r ! 348: * rev: HDR, [ HASH(1), ] <Ni_b>Pubkey_r, <KE_b>Ke_i, ! 349: * <IDi1_b>Ke_i, [<<Cert-I_b>Ke_i] ! 350: */ ! 351: int ! 352: ident_i2send(iph1, msg) ! 353: struct ph1handle *iph1; ! 354: vchar_t *msg; ! 355: { ! 356: int error = -1; ! 357: ! 358: /* validity check */ ! 359: if (iph1->status != PHASE1ST_MSG2RECEIVED) { ! 360: plog(LLV_ERROR, LOCATION, NULL, ! 361: "status mismatched %d.\n", iph1->status); ! 362: goto end; ! 363: } ! 364: ! 365: /* fix isakmp index */ ! 366: memcpy(&iph1->index.r_ck, &((struct isakmp *)msg->v)->r_ck, ! 367: sizeof(cookie_t)); ! 368: ! 369: /* generate DH public value */ ! 370: if (oakley_dh_generate(iph1->approval->dhgrp, ! 371: &iph1->dhpub, &iph1->dhpriv) < 0) ! 372: goto end; ! 373: ! 374: /* generate NONCE value */ ! 375: iph1->nonce = eay_set_random(iph1->rmconf->nonce_size); ! 376: if (iph1->nonce == NULL) ! 377: goto end; ! 378: ! 379: #ifdef HAVE_GSSAPI ! 380: if (iph1->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB && ! 381: gssapi_get_itoken(iph1, NULL) < 0) ! 382: goto end; ! 383: #endif ! 384: ! 385: /* create buffer to send isakmp payload */ ! 386: iph1->sendbuf = ident_ir2mx(iph1); ! 387: if (iph1->sendbuf == NULL) ! 388: goto end; ! 389: ! 390: #ifdef HAVE_PRINT_ISAKMP_C ! 391: isakmp_printpacket(iph1->sendbuf, iph1->local, iph1->remote, 0); ! 392: #endif ! 393: ! 394: /* send the packet, add to the schedule to resend */ ! 395: if (isakmp_ph1send(iph1) == -1) ! 396: goto end; ! 397: ! 398: /* the sending message is added to the received-list. */ ! 399: if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg) == -1) { ! 400: plog(LLV_ERROR , LOCATION, NULL, ! 401: "failed to add a response packet to the tree.\n"); ! 402: goto end; ! 403: } ! 404: ! 405: iph1->status = PHASE1ST_MSG2SENT; ! 406: ! 407: error = 0; ! 408: ! 409: end: ! 410: return error; ! 411: } ! 412: ! 413: /* ! 414: * receive from responder ! 415: * psk: HDR, KE, Nr ! 416: * sig: HDR, KE, Nr [, CR ] ! 417: * gssapi: HDR, KE, Nr, GSSr ! 418: * rsa: HDR, KE, <IDr1_b>PubKey_i, <Nr_b>PubKey_i ! 419: * rev: HDR, <Nr_b>PubKey_i, <KE_b>Ke_r, <IDr1_b>Ke_r, ! 420: */ ! 421: int ! 422: ident_i3recv(iph1, msg) ! 423: struct ph1handle *iph1; ! 424: vchar_t *msg; ! 425: { ! 426: vchar_t *pbuf = NULL; ! 427: struct isakmp_parse_t *pa; ! 428: int error = -1; ! 429: #ifdef HAVE_GSSAPI ! 430: vchar_t *gsstoken = NULL; ! 431: #endif ! 432: #ifdef ENABLE_NATT ! 433: vchar_t *natd_received; ! 434: int natd_seq = 0, natd_verified; ! 435: #endif ! 436: ! 437: /* validity check */ ! 438: if (iph1->status != PHASE1ST_MSG2SENT) { ! 439: plog(LLV_ERROR, LOCATION, NULL, ! 440: "status mismatched %d.\n", iph1->status); ! 441: goto end; ! 442: } ! 443: ! 444: /* validate the type of next payload */ ! 445: pbuf = isakmp_parse(msg); ! 446: if (pbuf == NULL) ! 447: goto end; ! 448: ! 449: for (pa = (struct isakmp_parse_t *)pbuf->v; ! 450: pa->type != ISAKMP_NPTYPE_NONE; ! 451: pa++) { ! 452: ! 453: switch (pa->type) { ! 454: case ISAKMP_NPTYPE_KE: ! 455: if (isakmp_p2ph(&iph1->dhpub_p, pa->ptr) < 0) ! 456: goto end; ! 457: break; ! 458: case ISAKMP_NPTYPE_NONCE: ! 459: if (isakmp_p2ph(&iph1->nonce_p, pa->ptr) < 0) ! 460: goto end; ! 461: break; ! 462: case ISAKMP_NPTYPE_VID: ! 463: handle_vendorid(iph1, pa->ptr); ! 464: break; ! 465: case ISAKMP_NPTYPE_CR: ! 466: if (oakley_savecr(iph1, pa->ptr) < 0) ! 467: goto end; ! 468: break; ! 469: #ifdef HAVE_GSSAPI ! 470: case ISAKMP_NPTYPE_GSS: ! 471: if (isakmp_p2ph(&gsstoken, pa->ptr) < 0) ! 472: goto end; ! 473: gssapi_save_received_token(iph1, gsstoken); ! 474: break; ! 475: #endif ! 476: ! 477: #ifdef ENABLE_NATT ! 478: case ISAKMP_NPTYPE_NATD_DRAFT: ! 479: case ISAKMP_NPTYPE_NATD_RFC: ! 480: if (NATT_AVAILABLE(iph1) && iph1->natt_options != NULL && ! 481: pa->type == iph1->natt_options->payload_nat_d) { ! 482: natd_received = NULL; ! 483: if (isakmp_p2ph (&natd_received, pa->ptr) < 0) ! 484: goto end; ! 485: ! 486: /* set both bits first so that we can clear them ! 487: upon verifying hashes */ ! 488: if (natd_seq == 0) ! 489: iph1->natt_flags |= NAT_DETECTED; ! 490: ! 491: /* this function will clear appropriate bits bits ! 492: from iph1->natt_flags */ ! 493: natd_verified = natt_compare_addr_hash (iph1, ! 494: natd_received, natd_seq++); ! 495: ! 496: plog (LLV_INFO, LOCATION, NULL, "NAT-D payload #%d %s\n", ! 497: natd_seq - 1, ! 498: natd_verified ? "verified" : "doesn't match"); ! 499: ! 500: vfree (natd_received); ! 501: break; ! 502: } ! 503: /* passthrough to default... */ ! 504: #endif ! 505: ! 506: default: ! 507: /* don't send information, see ident_r1recv() */ ! 508: plog(LLV_ERROR, LOCATION, iph1->remote, ! 509: "ignore the packet, " ! 510: "received unexpecting payload type %d.\n", ! 511: pa->type); ! 512: goto end; ! 513: } ! 514: } ! 515: ! 516: #ifdef ENABLE_NATT ! 517: if (NATT_AVAILABLE(iph1)) { ! 518: plog (LLV_INFO, LOCATION, NULL, "NAT %s %s%s\n", ! 519: iph1->natt_flags & NAT_DETECTED ? ! 520: "detected:" : "not detected", ! 521: iph1->natt_flags & NAT_DETECTED_ME ? "ME " : "", ! 522: iph1->natt_flags & NAT_DETECTED_PEER ? "PEER" : ""); ! 523: if (iph1->natt_flags & NAT_DETECTED) ! 524: natt_float_ports (iph1); ! 525: } ! 526: #endif ! 527: ! 528: /* payload existency check */ ! 529: if (iph1->dhpub_p == NULL || iph1->nonce_p == NULL) { ! 530: plog(LLV_ERROR, LOCATION, iph1->remote, ! 531: "few isakmp message received.\n"); ! 532: goto end; ! 533: } ! 534: ! 535: if (oakley_checkcr(iph1) < 0) { ! 536: /* Ignore this error in order to be interoperability. */ ! 537: ; ! 538: } ! 539: ! 540: iph1->status = PHASE1ST_MSG3RECEIVED; ! 541: ! 542: error = 0; ! 543: ! 544: end: ! 545: #ifdef HAVE_GSSAPI ! 546: if (gsstoken) ! 547: vfree(gsstoken); ! 548: #endif ! 549: if (pbuf) ! 550: vfree(pbuf); ! 551: if (error) { ! 552: VPTRINIT(iph1->dhpub_p); ! 553: VPTRINIT(iph1->nonce_p); ! 554: VPTRINIT(iph1->id_p); ! 555: VPTRINIT(iph1->cr_p); ! 556: } ! 557: ! 558: return error; ! 559: } ! 560: ! 561: /* ! 562: * send to responder ! 563: * psk: HDR*, IDi1, HASH_I ! 564: * sig: HDR*, IDi1, [ CR, ] [ CERT, ] SIG_I ! 565: * gssapi: HDR*, IDi1, < Gssi(n) | HASH_I > ! 566: * rsa: HDR*, HASH_I ! 567: * rev: HDR*, HASH_I ! 568: */ ! 569: int ! 570: ident_i3send(iph1, msg0) ! 571: struct ph1handle *iph1; ! 572: vchar_t *msg0; ! 573: { ! 574: int error = -1; ! 575: int dohash = 1; ! 576: #ifdef HAVE_GSSAPI ! 577: int len; ! 578: #endif ! 579: ! 580: /* validity check */ ! 581: if (iph1->status != PHASE1ST_MSG3RECEIVED) { ! 582: plog(LLV_ERROR, LOCATION, NULL, ! 583: "status mismatched %d.\n", iph1->status); ! 584: goto end; ! 585: } ! 586: ! 587: /* compute sharing secret of DH */ ! 588: if (oakley_dh_compute(iph1->approval->dhgrp, iph1->dhpub, ! 589: iph1->dhpriv, iph1->dhpub_p, &iph1->dhgxy) < 0) ! 590: goto end; ! 591: ! 592: /* generate SKEYIDs & IV & final cipher key */ ! 593: if (oakley_skeyid(iph1) < 0) ! 594: goto end; ! 595: if (oakley_skeyid_dae(iph1) < 0) ! 596: goto end; ! 597: if (oakley_compute_enckey(iph1) < 0) ! 598: goto end; ! 599: if (oakley_newiv(iph1) < 0) ! 600: goto end; ! 601: ! 602: /* make ID payload into isakmp status */ ! 603: if (ipsecdoi_setid1(iph1) < 0) ! 604: goto end; ! 605: ! 606: #ifdef HAVE_GSSAPI ! 607: if (iph1->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB && ! 608: gssapi_more_tokens(iph1)) { ! 609: plog(LLV_DEBUG, LOCATION, NULL, "calling get_itoken\n"); ! 610: if (gssapi_get_itoken(iph1, &len) < 0) ! 611: goto end; ! 612: if (len != 0) ! 613: dohash = 0; ! 614: } ! 615: #endif ! 616: ! 617: /* generate HASH to send */ ! 618: if (dohash) { ! 619: iph1->hash = oakley_ph1hash_common(iph1, GENERATE); ! 620: if (iph1->hash == NULL) ! 621: goto end; ! 622: } else ! 623: iph1->hash = NULL; ! 624: ! 625: /* set encryption flag */ ! 626: iph1->flags |= ISAKMP_FLAG_E; ! 627: ! 628: /* create HDR;ID;HASH payload */ ! 629: iph1->sendbuf = ident_ir3mx(iph1); ! 630: if (iph1->sendbuf == NULL) ! 631: goto end; ! 632: ! 633: /* send the packet, add to the schedule to resend */ ! 634: if (isakmp_ph1send(iph1) == -1) ! 635: goto end; ! 636: ! 637: /* the sending message is added to the received-list. */ ! 638: if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg0) == -1) { ! 639: plog(LLV_ERROR , LOCATION, NULL, ! 640: "failed to add a response packet to the tree.\n"); ! 641: goto end; ! 642: } ! 643: ! 644: /* see handler.h about IV synchronization. */ ! 645: memcpy(iph1->ivm->ive->v, iph1->ivm->iv->v, iph1->ivm->iv->l); ! 646: ! 647: iph1->status = PHASE1ST_MSG3SENT; ! 648: ! 649: error = 0; ! 650: ! 651: end: ! 652: return error; ! 653: } ! 654: ! 655: /* ! 656: * receive from responder ! 657: * psk: HDR*, IDr1, HASH_R ! 658: * sig: HDR*, IDr1, [ CERT, ] SIG_R ! 659: * gssapi: HDR*, IDr1, < GSSr(n) | HASH_R > ! 660: * rsa: HDR*, HASH_R ! 661: * rev: HDR*, HASH_R ! 662: */ ! 663: int ! 664: ident_i4recv(iph1, msg0) ! 665: struct ph1handle *iph1; ! 666: vchar_t *msg0; ! 667: { ! 668: vchar_t *pbuf = NULL; ! 669: struct isakmp_parse_t *pa; ! 670: vchar_t *msg = NULL; ! 671: int error = -1; ! 672: int type; ! 673: #ifdef HAVE_GSSAPI ! 674: vchar_t *gsstoken = NULL; ! 675: #endif ! 676: ! 677: /* validity check */ ! 678: if (iph1->status != PHASE1ST_MSG3SENT) { ! 679: plog(LLV_ERROR, LOCATION, NULL, ! 680: "status mismatched %d.\n", iph1->status); ! 681: goto end; ! 682: } ! 683: ! 684: /* decrypting */ ! 685: if (!ISSET(((struct isakmp *)msg0->v)->flags, ISAKMP_FLAG_E)) { ! 686: plog(LLV_ERROR, LOCATION, iph1->remote, ! 687: "ignore the packet, " ! 688: "expecting the packet encrypted.\n"); ! 689: goto end; ! 690: } ! 691: msg = oakley_do_decrypt(iph1, msg0, iph1->ivm->iv, iph1->ivm->ive); ! 692: if (msg == NULL) ! 693: goto end; ! 694: ! 695: /* validate the type of next payload */ ! 696: pbuf = isakmp_parse(msg); ! 697: if (pbuf == NULL) ! 698: goto end; ! 699: ! 700: iph1->pl_hash = NULL; ! 701: ! 702: for (pa = (struct isakmp_parse_t *)pbuf->v; ! 703: pa->type != ISAKMP_NPTYPE_NONE; ! 704: pa++) { ! 705: ! 706: switch (pa->type) { ! 707: case ISAKMP_NPTYPE_ID: ! 708: if (isakmp_p2ph(&iph1->id_p, pa->ptr) < 0) ! 709: goto end; ! 710: break; ! 711: case ISAKMP_NPTYPE_HASH: ! 712: iph1->pl_hash = (struct isakmp_pl_hash *)pa->ptr; ! 713: break; ! 714: case ISAKMP_NPTYPE_CERT: ! 715: if (oakley_savecert(iph1, pa->ptr) < 0) ! 716: goto end; ! 717: break; ! 718: case ISAKMP_NPTYPE_SIG: ! 719: if (isakmp_p2ph(&iph1->sig_p, pa->ptr) < 0) ! 720: goto end; ! 721: break; ! 722: #ifdef HAVE_GSSAPI ! 723: case ISAKMP_NPTYPE_GSS: ! 724: if (isakmp_p2ph(&gsstoken, pa->ptr) < 0) ! 725: goto end; ! 726: gssapi_save_received_token(iph1, gsstoken); ! 727: break; ! 728: #endif ! 729: case ISAKMP_NPTYPE_VID: ! 730: handle_vendorid(iph1, pa->ptr); ! 731: break; ! 732: case ISAKMP_NPTYPE_N: ! 733: ident_recv_n(iph1, pa->ptr); ! 734: break; ! 735: default: ! 736: /* don't send information, see ident_r1recv() */ ! 737: plog(LLV_ERROR, LOCATION, iph1->remote, ! 738: "ignore the packet, " ! 739: "received unexpecting payload type %d.\n", ! 740: pa->type); ! 741: goto end; ! 742: } ! 743: } ! 744: ! 745: /* payload existency check */ ! 746: ! 747: /* verify identifier */ ! 748: if (ipsecdoi_checkid1(iph1) != 0) { ! 749: plog(LLV_ERROR, LOCATION, iph1->remote, ! 750: "invalid ID payload.\n"); ! 751: goto end; ! 752: } ! 753: ! 754: /* validate authentication value */ ! 755: #ifdef HAVE_GSSAPI ! 756: if (gsstoken == NULL) { ! 757: #endif ! 758: type = oakley_validate_auth(iph1); ! 759: if (type != 0) { ! 760: if (type == -1) { ! 761: /* msg printed inner oakley_validate_auth() */ ! 762: goto end; ! 763: } ! 764: evt_phase1(iph1, EVT_PHASE1_AUTH_FAILED, NULL); ! 765: isakmp_info_send_n1(iph1, type, NULL); ! 766: goto end; ! 767: } ! 768: #ifdef HAVE_GSSAPI ! 769: } ! 770: #endif ! 771: ! 772: /* ! 773: * XXX: Should we do compare two addresses, ph1handle's and ID ! 774: * payload's. ! 775: */ ! 776: ! 777: plog(LLV_DEBUG, LOCATION, iph1->remote, "peer's ID:"); ! 778: plogdump(LLV_DEBUG, iph1->id_p->v, iph1->id_p->l); ! 779: ! 780: /* see handler.h about IV synchronization. */ ! 781: memcpy(iph1->ivm->iv->v, iph1->ivm->ive->v, iph1->ivm->ive->l); ! 782: ! 783: /* ! 784: * If we got a GSS token, we need to this roundtrip again. ! 785: */ ! 786: #ifdef HAVE_GSSAPI ! 787: iph1->status = gsstoken != 0 ? PHASE1ST_MSG3RECEIVED : ! 788: PHASE1ST_MSG4RECEIVED; ! 789: #else ! 790: iph1->status = PHASE1ST_MSG4RECEIVED; ! 791: #endif ! 792: ! 793: error = 0; ! 794: ! 795: end: ! 796: if (pbuf) ! 797: vfree(pbuf); ! 798: if (msg) ! 799: vfree(msg); ! 800: #ifdef HAVE_GSSAPI ! 801: if (gsstoken) ! 802: vfree(gsstoken); ! 803: #endif ! 804: ! 805: if (error) { ! 806: VPTRINIT(iph1->id_p); ! 807: VPTRINIT(iph1->cert_p); ! 808: VPTRINIT(iph1->crl_p); ! 809: VPTRINIT(iph1->sig_p); ! 810: } ! 811: ! 812: return error; ! 813: } ! 814: ! 815: /* ! 816: * status update and establish isakmp sa. ! 817: */ ! 818: int ! 819: ident_i4send(iph1, msg) ! 820: struct ph1handle *iph1; ! 821: vchar_t *msg; ! 822: { ! 823: int error = -1; ! 824: ! 825: /* validity check */ ! 826: if (iph1->status != PHASE1ST_MSG4RECEIVED) { ! 827: plog(LLV_ERROR, LOCATION, NULL, ! 828: "status mismatched %d.\n", iph1->status); ! 829: goto end; ! 830: } ! 831: ! 832: /* see handler.h about IV synchronization. */ ! 833: memcpy(iph1->ivm->iv->v, iph1->ivm->ive->v, iph1->ivm->iv->l); ! 834: ! 835: iph1->status = PHASE1ST_ESTABLISHED; ! 836: ! 837: error = 0; ! 838: ! 839: end: ! 840: return error; ! 841: } ! 842: ! 843: /* ! 844: * receive from initiator ! 845: * psk: HDR, SA ! 846: * sig: HDR, SA ! 847: * rsa: HDR, SA ! 848: * rev: HDR, SA ! 849: */ ! 850: int ! 851: ident_r1recv(iph1, msg) ! 852: struct ph1handle *iph1; ! 853: vchar_t *msg; ! 854: { ! 855: vchar_t *pbuf = NULL; ! 856: struct isakmp_parse_t *pa; ! 857: int error = -1; ! 858: int vid_numeric; ! 859: ! 860: /* validity check */ ! 861: if (iph1->status != PHASE1ST_START) { ! 862: plog(LLV_ERROR, LOCATION, NULL, ! 863: "status mismatched %d.\n", iph1->status); ! 864: goto end; ! 865: } ! 866: ! 867: /* validate the type of next payload */ ! 868: /* ! 869: * NOTE: XXX even if multiple VID, we'll silently ignore those. ! 870: */ ! 871: pbuf = isakmp_parse(msg); ! 872: if (pbuf == NULL) ! 873: goto end; ! 874: pa = (struct isakmp_parse_t *)pbuf->v; ! 875: ! 876: /* check the position of SA payload */ ! 877: if (pa->type != ISAKMP_NPTYPE_SA) { ! 878: plog(LLV_ERROR, LOCATION, iph1->remote, ! 879: "received invalid next payload type %d, " ! 880: "expecting %d.\n", ! 881: pa->type, ISAKMP_NPTYPE_SA); ! 882: goto end; ! 883: } ! 884: if (isakmp_p2ph(&iph1->sa, pa->ptr) < 0) ! 885: goto end; ! 886: pa++; ! 887: ! 888: for (/*nothing*/; ! 889: pa->type != ISAKMP_NPTYPE_NONE; ! 890: pa++) { ! 891: ! 892: switch (pa->type) { ! 893: case ISAKMP_NPTYPE_VID: ! 894: vid_numeric = handle_vendorid(iph1, pa->ptr); ! 895: #ifdef ENABLE_FRAG ! 896: if ((vid_numeric == VENDORID_FRAG) && ! 897: (vendorid_frag_cap(pa->ptr) & VENDORID_FRAG_IDENT)) ! 898: iph1->frag = 1; ! 899: #endif ! 900: break; ! 901: default: ! 902: /* ! 903: * We don't send information to the peer even ! 904: * if we received malformed packet. Because we ! 905: * can't distinguish the malformed packet and ! 906: * the re-sent packet. And we do same behavior ! 907: * when we expect encrypted packet. ! 908: */ ! 909: plog(LLV_ERROR, LOCATION, iph1->remote, ! 910: "ignore the packet, " ! 911: "received unexpecting payload type %d.\n", ! 912: pa->type); ! 913: goto end; ! 914: } ! 915: } ! 916: ! 917: #ifdef ENABLE_NATT ! 918: if (NATT_AVAILABLE(iph1)) ! 919: plog(LLV_INFO, LOCATION, iph1->remote, ! 920: "Selected NAT-T version: %s\n", ! 921: vid_string_by_id(iph1->natt_options->version)); ! 922: #endif ! 923: ! 924: /* check SA payload and set approval SA for use */ ! 925: if (ipsecdoi_checkph1proposal(iph1->sa, iph1) < 0) { ! 926: plog(LLV_ERROR, LOCATION, iph1->remote, ! 927: "failed to get valid proposal.\n"); ! 928: /* XXX send information */ ! 929: goto end; ! 930: } ! 931: ! 932: iph1->status = PHASE1ST_MSG1RECEIVED; ! 933: ! 934: error = 0; ! 935: ! 936: end: ! 937: if (pbuf) ! 938: vfree(pbuf); ! 939: if (error) { ! 940: VPTRINIT(iph1->sa); ! 941: } ! 942: ! 943: return error; ! 944: } ! 945: ! 946: /* ! 947: * send to initiator ! 948: * psk: HDR, SA ! 949: * sig: HDR, SA ! 950: * rsa: HDR, SA ! 951: * rev: HDR, SA ! 952: */ ! 953: int ! 954: ident_r1send(iph1, msg) ! 955: struct ph1handle *iph1; ! 956: vchar_t *msg; ! 957: { ! 958: struct payload_list *plist = NULL; ! 959: int error = -1; ! 960: vchar_t *gss_sa = NULL; ! 961: #ifdef HAVE_GSSAPI ! 962: int free_gss_sa = 0; ! 963: #endif ! 964: #ifdef ENABLE_NATT ! 965: vchar_t *vid_natt = NULL; ! 966: #endif ! 967: #ifdef ENABLE_HYBRID ! 968: vchar_t *vid_xauth = NULL; ! 969: vchar_t *vid_unity = NULL; ! 970: #endif ! 971: #ifdef ENABLE_DPD ! 972: vchar_t *vid_dpd = NULL; ! 973: #endif ! 974: #ifdef ENABLE_FRAG ! 975: vchar_t *vid_frag = NULL; ! 976: #endif ! 977: ! 978: /* validity check */ ! 979: if (iph1->status != PHASE1ST_MSG1RECEIVED) { ! 980: plog(LLV_ERROR, LOCATION, NULL, ! 981: "status mismatched %d.\n", iph1->status); ! 982: goto end; ! 983: } ! 984: ! 985: /* set responder's cookie */ ! 986: isakmp_newcookie((caddr_t)&iph1->index.r_ck, iph1->remote, iph1->local); ! 987: ! 988: #ifdef HAVE_GSSAPI ! 989: if (iph1->approval->gssid != NULL) { ! 990: gss_sa = ipsecdoi_setph1proposal(iph1->rmconf, iph1->approval); ! 991: if (gss_sa != iph1->sa_ret) ! 992: free_gss_sa = 1; ! 993: } else ! 994: #endif ! 995: gss_sa = iph1->sa_ret; ! 996: ! 997: /* set SA payload to reply */ ! 998: plist = isakmp_plist_append(plist, gss_sa, ISAKMP_NPTYPE_SA); ! 999: ! 1000: #ifdef ENABLE_HYBRID ! 1001: if (iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) { ! 1002: plog (LLV_INFO, LOCATION, NULL, "Adding xauth VID payload.\n"); ! 1003: if ((vid_xauth = set_vendorid(VENDORID_XAUTH)) == NULL) { ! 1004: plog(LLV_ERROR, LOCATION, NULL, ! 1005: "Cannot create Xauth vendor ID\n"); ! 1006: goto end; ! 1007: } ! 1008: plist = isakmp_plist_append(plist, ! 1009: vid_xauth, ISAKMP_NPTYPE_VID); ! 1010: } ! 1011: ! 1012: if (iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_UNITY) { ! 1013: if ((vid_unity = set_vendorid(VENDORID_UNITY)) == NULL) { ! 1014: plog(LLV_ERROR, LOCATION, NULL, ! 1015: "Cannot create Unity vendor ID\n"); ! 1016: goto end; ! 1017: } ! 1018: plist = isakmp_plist_append(plist, ! 1019: vid_unity, ISAKMP_NPTYPE_VID); ! 1020: } ! 1021: #endif ! 1022: #ifdef ENABLE_NATT ! 1023: /* Has the peer announced NAT-T? */ ! 1024: if (NATT_AVAILABLE(iph1)) ! 1025: vid_natt = set_vendorid(iph1->natt_options->version); ! 1026: ! 1027: if (vid_natt) ! 1028: plist = isakmp_plist_append(plist, vid_natt, ISAKMP_NPTYPE_VID); ! 1029: #endif ! 1030: #ifdef ENABLE_DPD ! 1031: if (iph1->dpd_support) { ! 1032: vid_dpd = set_vendorid(VENDORID_DPD); ! 1033: if (vid_dpd != NULL) ! 1034: plist = isakmp_plist_append(plist, vid_dpd, ISAKMP_NPTYPE_VID); ! 1035: } ! 1036: #endif ! 1037: #ifdef ENABLE_FRAG ! 1038: if (iph1->frag) { ! 1039: vid_frag = set_vendorid(VENDORID_FRAG); ! 1040: if (vid_frag != NULL) ! 1041: vid_frag = isakmp_frag_addcap(vid_frag, ! 1042: VENDORID_FRAG_IDENT); ! 1043: if (vid_frag == NULL) ! 1044: plog(LLV_ERROR, LOCATION, NULL, ! 1045: "Frag vendorID construction failed\n"); ! 1046: else ! 1047: plist = isakmp_plist_append(plist, ! 1048: vid_frag, ISAKMP_NPTYPE_VID); ! 1049: } ! 1050: #endif ! 1051: ! 1052: iph1->sendbuf = isakmp_plist_set_all (&plist, iph1); ! 1053: ! 1054: #ifdef HAVE_PRINT_ISAKMP_C ! 1055: isakmp_printpacket(iph1->sendbuf, iph1->local, iph1->remote, 0); ! 1056: #endif ! 1057: ! 1058: /* send the packet, add to the schedule to resend */ ! 1059: if (isakmp_ph1send(iph1) == -1) ! 1060: goto end; ! 1061: ! 1062: /* the sending message is added to the received-list. */ ! 1063: if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg) == -1) { ! 1064: plog(LLV_ERROR , LOCATION, NULL, ! 1065: "failed to add a response packet to the tree.\n"); ! 1066: goto end; ! 1067: } ! 1068: ! 1069: iph1->status = PHASE1ST_MSG1SENT; ! 1070: ! 1071: error = 0; ! 1072: ! 1073: end: ! 1074: #ifdef HAVE_GSSAPI ! 1075: if (free_gss_sa) ! 1076: vfree(gss_sa); ! 1077: #endif ! 1078: #ifdef ENABLE_NATT ! 1079: if (vid_natt) ! 1080: vfree(vid_natt); ! 1081: #endif ! 1082: #ifdef ENABLE_HYBRID ! 1083: if (vid_xauth != NULL) ! 1084: vfree(vid_xauth); ! 1085: if (vid_unity != NULL) ! 1086: vfree(vid_unity); ! 1087: #endif ! 1088: #ifdef ENABLE_DPD ! 1089: if (vid_dpd != NULL) ! 1090: vfree(vid_dpd); ! 1091: #endif ! 1092: #ifdef ENABLE_FRAG ! 1093: if (vid_frag != NULL) ! 1094: vfree(vid_frag); ! 1095: #endif ! 1096: ! 1097: return error; ! 1098: } ! 1099: ! 1100: /* ! 1101: * receive from initiator ! 1102: * psk: HDR, KE, Ni ! 1103: * sig: HDR, KE, Ni ! 1104: * gssapi: HDR, KE, Ni, GSSi ! 1105: * rsa: HDR, KE, [ HASH(1), ] <IDi1_b>PubKey_r, <Ni_b>PubKey_r ! 1106: * rev: HDR, [ HASH(1), ] <Ni_b>Pubkey_r, <KE_b>Ke_i, ! 1107: * <IDi1_b>Ke_i, [<<Cert-I_b>Ke_i] ! 1108: */ ! 1109: int ! 1110: ident_r2recv(iph1, msg) ! 1111: struct ph1handle *iph1; ! 1112: vchar_t *msg; ! 1113: { ! 1114: vchar_t *pbuf = NULL; ! 1115: struct isakmp_parse_t *pa; ! 1116: int error = -1; ! 1117: #ifdef HAVE_GSSAPI ! 1118: vchar_t *gsstoken = NULL; ! 1119: #endif ! 1120: #ifdef ENABLE_NATT ! 1121: int natd_seq = 0; ! 1122: #endif ! 1123: ! 1124: /* validity check */ ! 1125: if (iph1->status != PHASE1ST_MSG1SENT) { ! 1126: plog(LLV_ERROR, LOCATION, NULL, ! 1127: "status mismatched %d.\n", iph1->status); ! 1128: goto end; ! 1129: } ! 1130: ! 1131: /* validate the type of next payload */ ! 1132: pbuf = isakmp_parse(msg); ! 1133: if (pbuf == NULL) ! 1134: goto end; ! 1135: ! 1136: for (pa = (struct isakmp_parse_t *)pbuf->v; ! 1137: pa->type != ISAKMP_NPTYPE_NONE; ! 1138: pa++) { ! 1139: switch (pa->type) { ! 1140: case ISAKMP_NPTYPE_KE: ! 1141: if (isakmp_p2ph(&iph1->dhpub_p, pa->ptr) < 0) ! 1142: goto end; ! 1143: break; ! 1144: case ISAKMP_NPTYPE_NONCE: ! 1145: if (isakmp_p2ph(&iph1->nonce_p, pa->ptr) < 0) ! 1146: goto end; ! 1147: break; ! 1148: case ISAKMP_NPTYPE_VID: ! 1149: handle_vendorid(iph1, pa->ptr); ! 1150: break; ! 1151: case ISAKMP_NPTYPE_CR: ! 1152: plog(LLV_WARNING, LOCATION, iph1->remote, ! 1153: "CR received, ignore it. " ! 1154: "It should be in other exchange.\n"); ! 1155: break; ! 1156: #ifdef HAVE_GSSAPI ! 1157: case ISAKMP_NPTYPE_GSS: ! 1158: if (isakmp_p2ph(&gsstoken, pa->ptr) < 0) ! 1159: goto end; ! 1160: gssapi_save_received_token(iph1, gsstoken); ! 1161: break; ! 1162: #endif ! 1163: ! 1164: #ifdef ENABLE_NATT ! 1165: case ISAKMP_NPTYPE_NATD_DRAFT: ! 1166: case ISAKMP_NPTYPE_NATD_RFC: ! 1167: if (NATT_AVAILABLE(iph1) && iph1->natt_options != NULL && ! 1168: pa->type == iph1->natt_options->payload_nat_d) ! 1169: { ! 1170: vchar_t *natd_received = NULL; ! 1171: int natd_verified; ! 1172: ! 1173: if (isakmp_p2ph (&natd_received, pa->ptr) < 0) ! 1174: goto end; ! 1175: ! 1176: if (natd_seq == 0) ! 1177: iph1->natt_flags |= NAT_DETECTED; ! 1178: ! 1179: natd_verified = natt_compare_addr_hash (iph1, ! 1180: natd_received, natd_seq++); ! 1181: ! 1182: plog (LLV_INFO, LOCATION, NULL, "NAT-D payload #%d %s\n", ! 1183: natd_seq - 1, ! 1184: natd_verified ? "verified" : "doesn't match"); ! 1185: ! 1186: vfree (natd_received); ! 1187: break; ! 1188: } ! 1189: /* passthrough to default... */ ! 1190: #endif ! 1191: ! 1192: default: ! 1193: /* don't send information, see ident_r1recv() */ ! 1194: plog(LLV_ERROR, LOCATION, iph1->remote, ! 1195: "ignore the packet, " ! 1196: "received unexpecting payload type %d.\n", ! 1197: pa->type); ! 1198: goto end; ! 1199: } ! 1200: } ! 1201: ! 1202: #ifdef ENABLE_NATT ! 1203: if (NATT_AVAILABLE(iph1)) ! 1204: plog (LLV_INFO, LOCATION, NULL, "NAT %s %s%s\n", ! 1205: iph1->natt_flags & NAT_DETECTED ? ! 1206: "detected:" : "not detected", ! 1207: iph1->natt_flags & NAT_DETECTED_ME ? "ME " : "", ! 1208: iph1->natt_flags & NAT_DETECTED_PEER ? "PEER" : ""); ! 1209: #endif ! 1210: ! 1211: /* payload existency check */ ! 1212: if (iph1->dhpub_p == NULL || iph1->nonce_p == NULL) { ! 1213: plog(LLV_ERROR, LOCATION, iph1->remote, ! 1214: "few isakmp message received.\n"); ! 1215: goto end; ! 1216: } ! 1217: ! 1218: iph1->status = PHASE1ST_MSG2RECEIVED; ! 1219: ! 1220: error = 0; ! 1221: ! 1222: end: ! 1223: if (pbuf) ! 1224: vfree(pbuf); ! 1225: #ifdef HAVE_GSSAPI ! 1226: if (gsstoken) ! 1227: vfree(gsstoken); ! 1228: #endif ! 1229: ! 1230: if (error) { ! 1231: VPTRINIT(iph1->dhpub_p); ! 1232: VPTRINIT(iph1->nonce_p); ! 1233: VPTRINIT(iph1->id_p); ! 1234: } ! 1235: ! 1236: return error; ! 1237: } ! 1238: ! 1239: /* ! 1240: * send to initiator ! 1241: * psk: HDR, KE, Nr ! 1242: * sig: HDR, KE, Nr [, CR ] ! 1243: * gssapi: HDR, KE, Nr, GSSr ! 1244: * rsa: HDR, KE, <IDr1_b>PubKey_i, <Nr_b>PubKey_i ! 1245: * rev: HDR, <Nr_b>PubKey_i, <KE_b>Ke_r, <IDr1_b>Ke_r, ! 1246: */ ! 1247: int ! 1248: ident_r2send(iph1, msg) ! 1249: struct ph1handle *iph1; ! 1250: vchar_t *msg; ! 1251: { ! 1252: int error = -1; ! 1253: ! 1254: /* validity check */ ! 1255: if (iph1->status != PHASE1ST_MSG2RECEIVED) { ! 1256: plog(LLV_ERROR, LOCATION, NULL, ! 1257: "status mismatched %d.\n", iph1->status); ! 1258: goto end; ! 1259: } ! 1260: ! 1261: /* generate DH public value */ ! 1262: if (oakley_dh_generate(iph1->approval->dhgrp, ! 1263: &iph1->dhpub, &iph1->dhpriv) < 0) ! 1264: goto end; ! 1265: ! 1266: /* generate NONCE value */ ! 1267: iph1->nonce = eay_set_random(RMCONF_NONCE_SIZE(iph1->rmconf)); ! 1268: if (iph1->nonce == NULL) ! 1269: goto end; ! 1270: ! 1271: #ifdef HAVE_GSSAPI ! 1272: if (iph1->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB) ! 1273: gssapi_get_rtoken(iph1, NULL); ! 1274: #endif ! 1275: ! 1276: /* create HDR;KE;NONCE payload */ ! 1277: iph1->sendbuf = ident_ir2mx(iph1); ! 1278: if (iph1->sendbuf == NULL) ! 1279: goto end; ! 1280: ! 1281: #ifdef HAVE_PRINT_ISAKMP_C ! 1282: isakmp_printpacket(iph1->sendbuf, iph1->local, iph1->remote, 0); ! 1283: #endif ! 1284: ! 1285: /* send the packet, add to the schedule to resend */ ! 1286: if (isakmp_ph1send(iph1) == -1) ! 1287: goto end; ! 1288: ! 1289: /* the sending message is added to the received-list. */ ! 1290: if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg) == -1) { ! 1291: plog(LLV_ERROR , LOCATION, NULL, ! 1292: "failed to add a response packet to the tree.\n"); ! 1293: goto end; ! 1294: } ! 1295: ! 1296: /* compute sharing secret of DH */ ! 1297: if (oakley_dh_compute(iph1->approval->dhgrp, iph1->dhpub, ! 1298: iph1->dhpriv, iph1->dhpub_p, &iph1->dhgxy) < 0) ! 1299: goto end; ! 1300: ! 1301: /* generate SKEYIDs & IV & final cipher key */ ! 1302: if (oakley_skeyid(iph1) < 0) ! 1303: goto end; ! 1304: if (oakley_skeyid_dae(iph1) < 0) ! 1305: goto end; ! 1306: if (oakley_compute_enckey(iph1) < 0) ! 1307: goto end; ! 1308: if (oakley_newiv(iph1) < 0) ! 1309: goto end; ! 1310: ! 1311: iph1->status = PHASE1ST_MSG2SENT; ! 1312: ! 1313: error = 0; ! 1314: ! 1315: end: ! 1316: return error; ! 1317: } ! 1318: ! 1319: /* ! 1320: * receive from initiator ! 1321: * psk: HDR*, IDi1, HASH_I ! 1322: * sig: HDR*, IDi1, [ CR, ] [ CERT, ] SIG_I ! 1323: * gssapi: HDR*, [ IDi1, ] < GSSi(n) | HASH_I > ! 1324: * rsa: HDR*, HASH_I ! 1325: * rev: HDR*, HASH_I ! 1326: */ ! 1327: int ! 1328: ident_r3recv(iph1, msg0) ! 1329: struct ph1handle *iph1; ! 1330: vchar_t *msg0; ! 1331: { ! 1332: vchar_t *msg = NULL; ! 1333: vchar_t *pbuf = NULL; ! 1334: struct isakmp_parse_t *pa; ! 1335: int error = -1; ! 1336: int type; ! 1337: #ifdef HAVE_GSSAPI ! 1338: vchar_t *gsstoken = NULL; ! 1339: #endif ! 1340: ! 1341: /* validity check */ ! 1342: if (iph1->status != PHASE1ST_MSG2SENT) { ! 1343: plog(LLV_ERROR, LOCATION, NULL, ! 1344: "status mismatched %d.\n", iph1->status); ! 1345: goto end; ! 1346: } ! 1347: ! 1348: /* decrypting */ ! 1349: if (!ISSET(((struct isakmp *)msg0->v)->flags, ISAKMP_FLAG_E)) { ! 1350: plog(LLV_ERROR, LOCATION, iph1->remote, ! 1351: "reject the packet, " ! 1352: "expecting the packet encrypted.\n"); ! 1353: goto end; ! 1354: } ! 1355: msg = oakley_do_decrypt(iph1, msg0, iph1->ivm->iv, iph1->ivm->ive); ! 1356: if (msg == NULL) ! 1357: goto end; ! 1358: ! 1359: /* validate the type of next payload */ ! 1360: pbuf = isakmp_parse(msg); ! 1361: if (pbuf == NULL) ! 1362: goto end; ! 1363: ! 1364: iph1->pl_hash = NULL; ! 1365: ! 1366: for (pa = (struct isakmp_parse_t *)pbuf->v; ! 1367: pa->type != ISAKMP_NPTYPE_NONE; ! 1368: pa++) { ! 1369: ! 1370: switch (pa->type) { ! 1371: case ISAKMP_NPTYPE_ID: ! 1372: if (isakmp_p2ph(&iph1->id_p, pa->ptr) < 0) ! 1373: goto end; ! 1374: if (resolveph1rmconf(iph1) < 0) ! 1375: goto end; ! 1376: break; ! 1377: case ISAKMP_NPTYPE_HASH: ! 1378: iph1->pl_hash = (struct isakmp_pl_hash *)pa->ptr; ! 1379: break; ! 1380: case ISAKMP_NPTYPE_CR: ! 1381: if (oakley_savecr(iph1, pa->ptr) < 0) ! 1382: goto end; ! 1383: break; ! 1384: case ISAKMP_NPTYPE_CERT: ! 1385: if (oakley_savecert(iph1, pa->ptr) < 0) ! 1386: goto end; ! 1387: break; ! 1388: case ISAKMP_NPTYPE_SIG: ! 1389: if (isakmp_p2ph(&iph1->sig_p, pa->ptr) < 0) ! 1390: goto end; ! 1391: break; ! 1392: #ifdef HAVE_GSSAPI ! 1393: case ISAKMP_NPTYPE_GSS: ! 1394: if (isakmp_p2ph(&gsstoken, pa->ptr) < 0) ! 1395: goto end; ! 1396: gssapi_save_received_token(iph1, gsstoken); ! 1397: break; ! 1398: #endif ! 1399: case ISAKMP_NPTYPE_VID: ! 1400: handle_vendorid(iph1, pa->ptr); ! 1401: break; ! 1402: case ISAKMP_NPTYPE_N: ! 1403: ident_recv_n(iph1, pa->ptr); ! 1404: break; ! 1405: default: ! 1406: /* don't send information, see ident_r1recv() */ ! 1407: plog(LLV_ERROR, LOCATION, iph1->remote, ! 1408: "ignore the packet, " ! 1409: "received unexpecting payload type %d.\n", ! 1410: pa->type); ! 1411: goto end; ! 1412: } ! 1413: } ! 1414: ! 1415: /* payload existency check */ ! 1416: /* XXX same as ident_i4recv(), should be merged. */ ! 1417: { ! 1418: int ng = 0; ! 1419: ! 1420: switch (iph1->approval->authmethod) { ! 1421: case OAKLEY_ATTR_AUTH_METHOD_PSKEY: ! 1422: #ifdef ENABLE_HYBRID ! 1423: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R: ! 1424: case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R: ! 1425: case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R: ! 1426: #endif ! 1427: if (iph1->id_p == NULL || iph1->pl_hash == NULL) ! 1428: ng++; ! 1429: break; ! 1430: case OAKLEY_ATTR_AUTH_METHOD_DSSSIG: ! 1431: case OAKLEY_ATTR_AUTH_METHOD_RSASIG: ! 1432: #ifdef ENABLE_HYBRID ! 1433: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R: ! 1434: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R: ! 1435: #endif ! 1436: if (iph1->id_p == NULL || iph1->sig_p == NULL) ! 1437: ng++; ! 1438: break; ! 1439: case OAKLEY_ATTR_AUTH_METHOD_RSAENC: ! 1440: case OAKLEY_ATTR_AUTH_METHOD_RSAREV: ! 1441: #ifdef ENABLE_HYBRID ! 1442: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R: ! 1443: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R: ! 1444: #endif ! 1445: if (iph1->pl_hash == NULL) ! 1446: ng++; ! 1447: break; ! 1448: #ifdef HAVE_GSSAPI ! 1449: case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB: ! 1450: if (gsstoken == NULL && iph1->pl_hash == NULL) ! 1451: ng++; ! 1452: break; ! 1453: #endif ! 1454: default: ! 1455: plog(LLV_ERROR, LOCATION, iph1->remote, ! 1456: "invalid authmethod %d why ?\n", ! 1457: iph1->approval->authmethod); ! 1458: goto end; ! 1459: } ! 1460: if (ng) { ! 1461: plog(LLV_ERROR, LOCATION, iph1->remote, ! 1462: "few isakmp message received.\n"); ! 1463: goto end; ! 1464: } ! 1465: } ! 1466: ! 1467: /* verify identifier */ ! 1468: if (ipsecdoi_checkid1(iph1) != 0) { ! 1469: plog(LLV_ERROR, LOCATION, iph1->remote, ! 1470: "invalid ID payload.\n"); ! 1471: goto end; ! 1472: } ! 1473: ! 1474: /* validate authentication value */ ! 1475: #ifdef HAVE_GSSAPI ! 1476: if (gsstoken == NULL) { ! 1477: #endif ! 1478: type = oakley_validate_auth(iph1); ! 1479: if (type != 0) { ! 1480: if (type == -1) { ! 1481: /* msg printed inner oakley_validate_auth() */ ! 1482: goto end; ! 1483: } ! 1484: evt_phase1(iph1, EVT_PHASE1_AUTH_FAILED, NULL); ! 1485: isakmp_info_send_n1(iph1, type, NULL); ! 1486: goto end; ! 1487: } ! 1488: #ifdef HAVE_GSSAPI ! 1489: } ! 1490: #endif ! 1491: ! 1492: if (oakley_checkcr(iph1) < 0) { ! 1493: /* Ignore this error in order to be interoperability. */ ! 1494: ; ! 1495: } ! 1496: ! 1497: /* ! 1498: * XXX: Should we do compare two addresses, ph1handle's and ID ! 1499: * payload's. ! 1500: */ ! 1501: ! 1502: plog(LLV_DEBUG, LOCATION, iph1->remote, "peer's ID\n"); ! 1503: plogdump(LLV_DEBUG, iph1->id_p->v, iph1->id_p->l); ! 1504: ! 1505: /* see handler.h about IV synchronization. */ ! 1506: memcpy(iph1->ivm->iv->v, iph1->ivm->ive->v, iph1->ivm->ive->l); ! 1507: ! 1508: #ifdef HAVE_GSSAPI ! 1509: iph1->status = gsstoken != NULL ? PHASE1ST_MSG2RECEIVED : ! 1510: PHASE1ST_MSG3RECEIVED; ! 1511: #else ! 1512: iph1->status = PHASE1ST_MSG3RECEIVED; ! 1513: #endif ! 1514: ! 1515: error = 0; ! 1516: ! 1517: end: ! 1518: if (pbuf) ! 1519: vfree(pbuf); ! 1520: if (msg) ! 1521: vfree(msg); ! 1522: #ifdef HAVE_GSSAPI ! 1523: if (gsstoken) ! 1524: vfree(gsstoken); ! 1525: #endif ! 1526: ! 1527: if (error) { ! 1528: VPTRINIT(iph1->id_p); ! 1529: VPTRINIT(iph1->cert_p); ! 1530: VPTRINIT(iph1->crl_p); ! 1531: VPTRINIT(iph1->sig_p); ! 1532: VPTRINIT(iph1->cr_p); ! 1533: } ! 1534: ! 1535: return error; ! 1536: } ! 1537: ! 1538: /* ! 1539: * send to initiator ! 1540: * psk: HDR*, IDr1, HASH_R ! 1541: * sig: HDR*, IDr1, [ CERT, ] SIG_R ! 1542: * gssapi: HDR*, IDr1, < GSSr(n) | HASH_R > ! 1543: * rsa: HDR*, HASH_R ! 1544: * rev: HDR*, HASH_R ! 1545: */ ! 1546: int ! 1547: ident_r3send(iph1, msg) ! 1548: struct ph1handle *iph1; ! 1549: vchar_t *msg; ! 1550: { ! 1551: int error = -1; ! 1552: int dohash = 1; ! 1553: #ifdef HAVE_GSSAPI ! 1554: int len; ! 1555: #endif ! 1556: ! 1557: /* validity check */ ! 1558: if (iph1->status != PHASE1ST_MSG3RECEIVED) { ! 1559: plog(LLV_ERROR, LOCATION, NULL, ! 1560: "status mismatched %d.\n", iph1->status); ! 1561: goto end; ! 1562: } ! 1563: ! 1564: /* make ID payload into isakmp status */ ! 1565: if (ipsecdoi_setid1(iph1) < 0) ! 1566: goto end; ! 1567: ! 1568: #ifdef HAVE_GSSAPI ! 1569: if (iph1->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB && ! 1570: gssapi_more_tokens(iph1)) { ! 1571: gssapi_get_rtoken(iph1, &len); ! 1572: if (len != 0) ! 1573: dohash = 0; ! 1574: } ! 1575: #endif ! 1576: ! 1577: if (dohash) { ! 1578: /* generate HASH to send */ ! 1579: plog(LLV_DEBUG, LOCATION, NULL, "generate HASH_R\n"); ! 1580: iph1->hash = oakley_ph1hash_common(iph1, GENERATE); ! 1581: if (iph1->hash == NULL) ! 1582: goto end; ! 1583: } else ! 1584: iph1->hash = NULL; ! 1585: ! 1586: /* set encryption flag */ ! 1587: iph1->flags |= ISAKMP_FLAG_E; ! 1588: ! 1589: /* create HDR;ID;HASH payload */ ! 1590: iph1->sendbuf = ident_ir3mx(iph1); ! 1591: if (iph1->sendbuf == NULL) ! 1592: goto end; ! 1593: ! 1594: /* send HDR;ID;HASH to responder */ ! 1595: if (isakmp_send(iph1, iph1->sendbuf) < 0) ! 1596: goto end; ! 1597: ! 1598: /* the sending message is added to the received-list. */ ! 1599: if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg) == -1) { ! 1600: plog(LLV_ERROR , LOCATION, NULL, ! 1601: "failed to add a response packet to the tree.\n"); ! 1602: goto end; ! 1603: } ! 1604: ! 1605: /* see handler.h about IV synchronization. */ ! 1606: memcpy(iph1->ivm->ive->v, iph1->ivm->iv->v, iph1->ivm->iv->l); ! 1607: ! 1608: iph1->status = PHASE1ST_ESTABLISHED; ! 1609: ! 1610: error = 0; ! 1611: ! 1612: end: ! 1613: ! 1614: return error; ! 1615: } ! 1616: ! 1617: /* ! 1618: * This is used in main mode for: ! 1619: * initiator's 3rd exchange send to responder ! 1620: * psk: HDR, KE, Ni ! 1621: * sig: HDR, KE, Ni ! 1622: * rsa: HDR, KE, [ HASH(1), ] <IDi1_b>PubKey_r, <Ni_b>PubKey_r ! 1623: * rev: HDR, [ HASH(1), ] <Ni_b>Pubkey_r, <KE_b>Ke_i, ! 1624: * <IDi1_b>Ke_i, [<<Cert-I_b>Ke_i] ! 1625: * responders 2nd exchnage send to initiator ! 1626: * psk: HDR, KE, Nr ! 1627: * sig: HDR, KE, Nr [, CR ] ! 1628: * rsa: HDR, KE, <IDr1_b>PubKey_i, <Nr_b>PubKey_i ! 1629: * rev: HDR, <Nr_b>PubKey_i, <KE_b>Ke_r, <IDr1_b>Ke_r, ! 1630: */ ! 1631: static vchar_t * ! 1632: ident_ir2mx(iph1) ! 1633: struct ph1handle *iph1; ! 1634: { ! 1635: vchar_t *buf = 0; ! 1636: struct payload_list *plist = NULL; ! 1637: vchar_t *vid = NULL; ! 1638: int error = -1; ! 1639: #ifdef HAVE_GSSAPI ! 1640: vchar_t *gsstoken = NULL; ! 1641: #endif ! 1642: #ifdef ENABLE_NATT ! 1643: vchar_t *natd[2] = { NULL, NULL }; ! 1644: #endif ! 1645: ! 1646: #ifdef HAVE_GSSAPI ! 1647: if (iph1->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB) { ! 1648: if (gssapi_get_token_to_send(iph1, &gsstoken) < 0) { ! 1649: plog(LLV_ERROR, LOCATION, NULL, ! 1650: "Failed to get gssapi token.\n"); ! 1651: goto end; ! 1652: } ! 1653: } ! 1654: #endif ! 1655: ! 1656: /* create isakmp KE payload */ ! 1657: plist = isakmp_plist_append(plist, iph1->dhpub, ISAKMP_NPTYPE_KE); ! 1658: ! 1659: /* create isakmp NONCE payload */ ! 1660: plist = isakmp_plist_append(plist, iph1->nonce, ISAKMP_NPTYPE_NONCE); ! 1661: ! 1662: #ifdef HAVE_GSSAPI ! 1663: if (iph1->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB) ! 1664: plist = isakmp_plist_append(plist, gsstoken, ISAKMP_NPTYPE_GSS); ! 1665: #endif ! 1666: ! 1667: /* append vendor id, if needed */ ! 1668: if (vid) ! 1669: plist = isakmp_plist_append(plist, vid, ISAKMP_NPTYPE_VID); ! 1670: ! 1671: /* create CR if need */ ! 1672: if (iph1->side == RESPONDER && ! 1673: oakley_needcr(iph1->approval->authmethod)) ! 1674: plist = oakley_append_cr(plist, iph1); ! 1675: ! 1676: #ifdef ENABLE_NATT ! 1677: /* generate and append NAT-D payloads */ ! 1678: if (NATT_AVAILABLE(iph1) && iph1->status == PHASE1ST_MSG2RECEIVED) ! 1679: { ! 1680: if ((natd[0] = natt_hash_addr (iph1, iph1->remote)) == NULL) { ! 1681: plog(LLV_ERROR, LOCATION, NULL, ! 1682: "NAT-D hashing failed for %s\n", saddr2str(iph1->remote)); ! 1683: goto end; ! 1684: } ! 1685: ! 1686: if ((natd[1] = natt_hash_addr (iph1, iph1->local)) == NULL) { ! 1687: plog(LLV_ERROR, LOCATION, NULL, ! 1688: "NAT-D hashing failed for %s\n", saddr2str(iph1->local)); ! 1689: goto end; ! 1690: } ! 1691: ! 1692: plog (LLV_INFO, LOCATION, NULL, "Adding remote and local NAT-D payloads.\n"); ! 1693: plist = isakmp_plist_append(plist, natd[0], iph1->natt_options->payload_nat_d); ! 1694: plist = isakmp_plist_append(plist, natd[1], iph1->natt_options->payload_nat_d); ! 1695: } ! 1696: #endif ! 1697: ! 1698: buf = isakmp_plist_set_all (&plist, iph1); ! 1699: ! 1700: error = 0; ! 1701: ! 1702: end: ! 1703: if (error && buf != NULL) { ! 1704: vfree(buf); ! 1705: buf = NULL; ! 1706: } ! 1707: #ifdef HAVE_GSSAPI ! 1708: if (gsstoken) ! 1709: vfree(gsstoken); ! 1710: #endif ! 1711: if (vid) ! 1712: vfree(vid); ! 1713: ! 1714: #ifdef ENABLE_NATT ! 1715: if (natd[0]) ! 1716: vfree(natd[0]); ! 1717: if (natd[1]) ! 1718: vfree(natd[1]); ! 1719: #endif ! 1720: ! 1721: return buf; ! 1722: } ! 1723: ! 1724: /* ! 1725: * This is used in main mode for: ! 1726: * initiator's 4th exchange send to responder ! 1727: * psk: HDR*, IDi1, HASH_I ! 1728: * sig: HDR*, IDi1, [ CR, ] [ CERT, ] SIG_I ! 1729: * gssapi: HDR*, [ IDi1, ] < GSSi(n) | HASH_I > ! 1730: * rsa: HDR*, HASH_I ! 1731: * rev: HDR*, HASH_I ! 1732: * responders 3rd exchnage send to initiator ! 1733: * psk: HDR*, IDr1, HASH_R ! 1734: * sig: HDR*, IDr1, [ CERT, ] SIG_R ! 1735: * gssapi: HDR*, [ IDr1, ] < GSSr(n) | HASH_R > ! 1736: * rsa: HDR*, HASH_R ! 1737: * rev: HDR*, HASH_R ! 1738: */ ! 1739: static vchar_t * ! 1740: ident_ir3mx(iph1) ! 1741: struct ph1handle *iph1; ! 1742: { ! 1743: struct payload_list *plist = NULL; ! 1744: vchar_t *buf = NULL, *new = NULL; ! 1745: int need_cert = 0; ! 1746: int error = -1; ! 1747: #ifdef HAVE_GSSAPI ! 1748: int nptype; ! 1749: vchar_t *gsstoken = NULL; ! 1750: vchar_t *gsshash = NULL; ! 1751: #endif ! 1752: ! 1753: switch (iph1->approval->authmethod) { ! 1754: case OAKLEY_ATTR_AUTH_METHOD_PSKEY: ! 1755: #ifdef ENABLE_HYBRID ! 1756: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I: ! 1757: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R: ! 1758: case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I: ! 1759: case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I: ! 1760: #endif ! 1761: /* create isakmp ID payload */ ! 1762: plist = isakmp_plist_append(plist, iph1->id, ISAKMP_NPTYPE_ID); ! 1763: ! 1764: /* create isakmp HASH payload */ ! 1765: plist = isakmp_plist_append(plist, iph1->hash, ISAKMP_NPTYPE_HASH); ! 1766: break; ! 1767: case OAKLEY_ATTR_AUTH_METHOD_DSSSIG: ! 1768: case OAKLEY_ATTR_AUTH_METHOD_RSASIG: ! 1769: #ifdef ENABLE_HYBRID ! 1770: case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R: ! 1771: case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R: ! 1772: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I: ! 1773: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R: ! 1774: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I: ! 1775: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R: ! 1776: #endif ! 1777: if (oakley_getmycert(iph1) < 0) ! 1778: goto end; ! 1779: ! 1780: if (oakley_getsign(iph1) < 0) ! 1781: goto end; ! 1782: ! 1783: if (iph1->cert != NULL && iph1->rmconf->send_cert) ! 1784: need_cert = 1; ! 1785: ! 1786: /* add ID payload */ ! 1787: plist = isakmp_plist_append(plist, iph1->id, ISAKMP_NPTYPE_ID); ! 1788: ! 1789: /* add CERT payload if there */ ! 1790: if (need_cert) ! 1791: plist = isakmp_plist_append(plist, iph1->cert, ! 1792: ISAKMP_NPTYPE_CERT); ! 1793: /* add SIG payload */ ! 1794: plist = isakmp_plist_append(plist, iph1->sig, ISAKMP_NPTYPE_SIG); ! 1795: ! 1796: /* create isakmp CR payload */ ! 1797: if (iph1->side == INITIATOR && ! 1798: oakley_needcr(iph1->approval->authmethod)) ! 1799: plist = oakley_append_cr(plist, iph1); ! 1800: break; ! 1801: #ifdef HAVE_GSSAPI ! 1802: case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB: ! 1803: if (iph1->hash != NULL) { ! 1804: gsshash = gssapi_wraphash(iph1); ! 1805: if (gsshash == NULL) ! 1806: goto end; ! 1807: } else { ! 1808: if (gssapi_get_token_to_send(iph1, &gsstoken) < 0) { ! 1809: plog(LLV_ERROR, LOCATION, NULL, ! 1810: "Failed to get gssapi token.\n"); ! 1811: goto end; ! 1812: } ! 1813: } ! 1814: ! 1815: if (!gssapi_id_sent(iph1)) { ! 1816: /* create isakmp ID payload */ ! 1817: plist = isakmp_plist_append(plist, iph1->id, ISAKMP_NPTYPE_ID); ! 1818: gssapi_set_id_sent(iph1); ! 1819: } ! 1820: ! 1821: if (iph1->hash != NULL) ! 1822: /* create isakmp HASH payload */ ! 1823: plist = isakmp_plist_append(plist, gsshash, ISAKMP_NPTYPE_HASH); ! 1824: else ! 1825: plist = isakmp_plist_append(plist, gsstoken, ISAKMP_NPTYPE_GSS); ! 1826: break; ! 1827: #endif ! 1828: case OAKLEY_ATTR_AUTH_METHOD_RSAENC: ! 1829: case OAKLEY_ATTR_AUTH_METHOD_RSAREV: ! 1830: #ifdef ENABLE_HYBRID ! 1831: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I: ! 1832: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R: ! 1833: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I: ! 1834: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R: ! 1835: #endif ! 1836: plog(LLV_ERROR, LOCATION, NULL, ! 1837: "not supported authentication type %d\n", ! 1838: iph1->approval->authmethod); ! 1839: goto end; ! 1840: default: ! 1841: plog(LLV_ERROR, LOCATION, NULL, ! 1842: "invalid authentication type %d\n", ! 1843: iph1->approval->authmethod); ! 1844: goto end; ! 1845: } ! 1846: ! 1847: buf = isakmp_plist_set_all (&plist, iph1); ! 1848: ! 1849: #ifdef HAVE_PRINT_ISAKMP_C ! 1850: isakmp_printpacket(buf, iph1->local, iph1->remote, 1); ! 1851: #endif ! 1852: ! 1853: /* encoding */ ! 1854: new = oakley_do_encrypt(iph1, buf, iph1->ivm->ive, iph1->ivm->iv); ! 1855: if (new == NULL) ! 1856: goto end; ! 1857: ! 1858: vfree(buf); ! 1859: ! 1860: buf = new; ! 1861: ! 1862: error = 0; ! 1863: ! 1864: end: ! 1865: #ifdef HAVE_GSSAPI ! 1866: if (gsstoken) ! 1867: vfree(gsstoken); ! 1868: #endif ! 1869: if (error && buf != NULL) { ! 1870: vfree(buf); ! 1871: buf = NULL; ! 1872: } ! 1873: ! 1874: return buf; ! 1875: } ! 1876: ! 1877: /* ! 1878: * handle a notification payload inside identity exchange. ! 1879: * called only when the packet has been verified to be encrypted. ! 1880: */ ! 1881: static int ! 1882: ident_recv_n(iph1, gen) ! 1883: struct ph1handle *iph1; ! 1884: struct isakmp_gen *gen; ! 1885: { ! 1886: struct isakmp_pl_n *notify = (struct isakmp_pl_n *) gen; ! 1887: u_int type; ! 1888: ! 1889: type = ntohs(notify->type); ! 1890: switch (type) { ! 1891: case ISAKMP_NTYPE_INITIAL_CONTACT: ! 1892: iph1->initial_contact_received = TRUE; ! 1893: break; ! 1894: default: ! 1895: isakmp_log_notify(iph1, notify, "identity exchange"); ! 1896: break; ! 1897: } ! 1898: return 0; ! 1899: } ! 1900: