Return to isakmp.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / ipsec-tools / src / racoon |
1.1 ! misho 1: /* $NetBSD: isakmp.c,v 1.71 2011/03/15 13:20:14 vanhu Exp $ */ ! 2: ! 3: /* Id: isakmp.c,v 1.74 2006/05/07 21:32:59 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: #include <sys/queue.h> ! 40: ! 41: #include <netinet/in.h> ! 42: #include <arpa/inet.h> ! 43: ! 44: #include PATH_IPSEC_H ! 45: ! 46: #include <stdlib.h> ! 47: #include <stdio.h> ! 48: #include <string.h> ! 49: #include <errno.h> ! 50: #if TIME_WITH_SYS_TIME ! 51: # include <sys/time.h> ! 52: # include <time.h> ! 53: #else ! 54: # if HAVE_SYS_TIME_H ! 55: # include <sys/time.h> ! 56: # else ! 57: # include <time.h> ! 58: # endif ! 59: #endif ! 60: #include <netdb.h> ! 61: #ifdef HAVE_UNISTD_H ! 62: #include <unistd.h> ! 63: #endif ! 64: #include <ctype.h> ! 65: #ifdef ENABLE_HYBRID ! 66: #include <resolv.h> ! 67: #endif ! 68: ! 69: #include "var.h" ! 70: #include "misc.h" ! 71: #include "vmbuf.h" ! 72: #include "plog.h" ! 73: #include "sockmisc.h" ! 74: #include "schedule.h" ! 75: #include "session.h" ! 76: #include "debug.h" ! 77: ! 78: #include "remoteconf.h" ! 79: #include "localconf.h" ! 80: #include "grabmyaddr.h" ! 81: #include "admin.h" ! 82: #include "privsep.h" ! 83: #include "isakmp_var.h" ! 84: #include "isakmp.h" ! 85: #include "oakley.h" ! 86: #include "evt.h" ! 87: #include "handler.h" ! 88: #include "ipsec_doi.h" ! 89: #include "pfkey.h" ! 90: #include "crypto_openssl.h" ! 91: #include "policy.h" ! 92: #include "algorithm.h" ! 93: #include "proposal.h" ! 94: #include "sainfo.h" ! 95: #include "isakmp_ident.h" ! 96: #include "isakmp_agg.h" ! 97: #include "isakmp_base.h" ! 98: #include "isakmp_quick.h" ! 99: #include "isakmp_inf.h" ! 100: #include "isakmp_newg.h" ! 101: #ifdef ENABLE_HYBRID ! 102: #include "vendorid.h" ! 103: #include "isakmp_xauth.h" ! 104: #include "isakmp_unity.h" ! 105: #include "isakmp_cfg.h" ! 106: #endif ! 107: #ifdef ENABLE_FRAG ! 108: #include "isakmp_frag.h" ! 109: #endif ! 110: #include "strnames.h" ! 111: ! 112: #include <fcntl.h> ! 113: ! 114: #ifdef ENABLE_NATT ! 115: # include "nattraversal.h" ! 116: #endif ! 117: # ifdef __linux__ ! 118: # include <linux/udp.h> ! 119: # include <linux/ip.h> ! 120: # ifndef SOL_UDP ! 121: # define SOL_UDP 17 ! 122: # endif ! 123: # endif /* __linux__ */ ! 124: # if defined(__NetBSD__) || defined(__FreeBSD__) || \ ! 125: (defined(__APPLE__) && defined(__MACH__)) ! 126: # include <netinet/in.h> ! 127: # include <netinet/udp.h> ! 128: # include <netinet/in_systm.h> ! 129: # include <netinet/ip.h> ! 130: # define SOL_UDP IPPROTO_UDP ! 131: # endif /* __NetBSD__ / __FreeBSD__ */ ! 132: ! 133: static int nostate1 __P((struct ph1handle *, vchar_t *)); ! 134: static int nostate2 __P((struct ph2handle *, vchar_t *)); ! 135: ! 136: extern caddr_t val2str(const char *, size_t); ! 137: ! 138: static int (*ph1exchange[][2][PHASE1ST_MAX]) ! 139: __P((struct ph1handle *, vchar_t *)) = { ! 140: /* error */ ! 141: { { 0 }, { 0 }, }, ! 142: /* Identity Protection exchange */ ! 143: { ! 144: { nostate1, ident_i1send, nostate1, ident_i2recv, ident_i2send, ! 145: ident_i3recv, ident_i3send, ident_i4recv, ident_i4send, nostate1, nostate1,}, ! 146: { nostate1, ident_r1recv, ident_r1send, ident_r2recv, ident_r2send, ! 147: ident_r3recv, ident_r3send, nostate1, nostate1, nostate1, nostate1, }, ! 148: }, ! 149: /* Aggressive exchange */ ! 150: { ! 151: { nostate1, agg_i1send, nostate1, agg_i2recv, agg_i2send, ! 152: nostate1, nostate1, nostate1, nostate1, nostate1, nostate1, }, ! 153: { nostate1, agg_r1recv, agg_r1send, agg_r2recv, agg_r2send, ! 154: nostate1, nostate1, nostate1, nostate1, nostate1, nostate1, }, ! 155: }, ! 156: /* Base exchange */ ! 157: { ! 158: { nostate1, base_i1send, nostate1, base_i2recv, base_i2send, ! 159: base_i3recv, base_i3send, nostate1, nostate1, nostate1, nostate1, }, ! 160: { nostate1, base_r1recv, base_r1send, base_r2recv, base_r2send, ! 161: nostate1, nostate1, nostate1, nostate1, nostate1, nostate1, }, ! 162: }, ! 163: }; ! 164: ! 165: static int (*ph2exchange[][2][PHASE2ST_MAX]) ! 166: __P((struct ph2handle *, vchar_t *)) = { ! 167: /* error */ ! 168: { { 0 }, { 0 }, }, ! 169: /* Quick mode for IKE */ ! 170: { ! 171: { nostate2, nostate2, quick_i1prep, nostate2, quick_i1send, ! 172: quick_i2recv, quick_i2send, quick_i3recv, nostate2, nostate2, }, ! 173: { nostate2, quick_r1recv, quick_r1prep, nostate2, quick_r2send, ! 174: quick_r3recv, quick_r3prep, quick_r3send, nostate2, nostate2, } ! 175: }, ! 176: }; ! 177: ! 178: static u_char r_ck0[] = { 0,0,0,0,0,0,0,0 }; /* used to verify the r_ck. */ ! 179: ! 180: static int isakmp_main __P((vchar_t *, struct sockaddr *, struct sockaddr *)); ! 181: static int ph1_main __P((struct ph1handle *, vchar_t *)); ! 182: static int quick_main __P((struct ph2handle *, vchar_t *)); ! 183: static int isakmp_ph1begin_r __P((vchar_t *, ! 184: struct sockaddr *, struct sockaddr *, u_int8_t)); ! 185: static int isakmp_ph2begin_i __P((struct ph1handle *, struct ph2handle *)); ! 186: static int isakmp_ph2begin_r __P((struct ph1handle *, vchar_t *)); ! 187: static int etypesw1 __P((int)); ! 188: static int etypesw2 __P((int)); ! 189: static int isakmp_ph1resend __P((struct ph1handle *)); ! 190: static int isakmp_ph2resend __P((struct ph2handle *)); ! 191: ! 192: #ifdef ENABLE_FRAG ! 193: static int frag_handler(struct ph1handle *, ! 194: vchar_t *, struct sockaddr *, struct sockaddr *); ! 195: #endif ! 196: ! 197: /* ! 198: * isakmp packet handler ! 199: */ ! 200: static int ! 201: isakmp_handler(ctx, so_isakmp) ! 202: void *ctx; ! 203: int so_isakmp; ! 204: { ! 205: struct isakmp isakmp; ! 206: union { ! 207: char buf[sizeof (isakmp) + 4]; ! 208: u_int32_t non_esp[2]; ! 209: struct { ! 210: struct udphdr udp; ! 211: #ifdef __linux ! 212: struct iphdr ip; ! 213: #else ! 214: struct ip ip; ! 215: #endif ! 216: char buf[sizeof(isakmp) + 4]; ! 217: } lbuf; ! 218: } x; ! 219: struct sockaddr_storage remote; ! 220: struct sockaddr_storage local; ! 221: unsigned int remote_len = sizeof(remote); ! 222: unsigned int local_len = sizeof(local); ! 223: int len = 0, extralen = 0; ! 224: vchar_t *buf = NULL, *tmpbuf = NULL; ! 225: int error = -1, res; ! 226: ! 227: /* read message by MSG_PEEK */ ! 228: while ((len = recvfromto(so_isakmp, x.buf, sizeof(x), ! 229: MSG_PEEK, (struct sockaddr *)&remote, &remote_len, ! 230: (struct sockaddr *)&local, &local_len)) < 0) { ! 231: if (errno == EINTR) ! 232: continue; ! 233: plog(LLV_ERROR, LOCATION, NULL, ! 234: "failed to receive isakmp packet: %s\n", ! 235: strerror (errno)); ! 236: goto end; ! 237: } ! 238: ! 239: /* keep-alive packet - ignore */ ! 240: if (len == 1 && (x.buf[0]&0xff) == 0xff) { ! 241: /* Pull the keep-alive packet */ ! 242: if ((len = recvfrom(so_isakmp, (char *)x.buf, 1, ! 243: 0, (struct sockaddr *)&remote, &remote_len)) != 1) { ! 244: plog(LLV_ERROR, LOCATION, NULL, ! 245: "failed to receive keep alive packet: %s\n", ! 246: strerror (errno)); ! 247: } ! 248: goto end; ! 249: } ! 250: ! 251: /* Lucent IKE in UDP encapsulation */ ! 252: { ! 253: #ifdef __linux__ ! 254: if (ntohs(x.lbuf.udp.dest) == 501) { ! 255: extralen += sizeof(x.lbuf.udp) + x.lbuf.ip.ihl; ! 256: } ! 257: #else ! 258: if (ntohs(x.lbuf.udp.uh_dport) == 501) { ! 259: extralen += sizeof(x.lbuf.udp) + x.lbuf.ip.ip_hl; ! 260: } ! 261: #endif ! 262: } ! 263: ! 264: #ifdef ENABLE_NATT ! 265: /* we don't know about portchange yet, ! 266: look for non-esp marker instead */ ! 267: if (x.non_esp[0] == 0 && x.non_esp[1] != 0) ! 268: extralen = NON_ESP_MARKER_LEN; ! 269: #endif ! 270: ! 271: /* now we know if there is an extra non-esp ! 272: marker at the beginning or not */ ! 273: memcpy ((char *)&isakmp, x.buf + extralen, sizeof (isakmp)); ! 274: ! 275: /* check isakmp header length, as well as sanity of header length */ ! 276: if (len < sizeof(isakmp) || ntohl(isakmp.len) < sizeof(isakmp)) { ! 277: plog(LLV_ERROR, LOCATION, (struct sockaddr *)&remote, ! 278: "packet shorter than isakmp header size (%u, %u, %zu)\n", ! 279: len, ntohl(isakmp.len), sizeof(isakmp)); ! 280: /* dummy receive */ ! 281: if ((len = recvfrom(so_isakmp, (char *)&isakmp, sizeof(isakmp), ! 282: 0, (struct sockaddr *)&remote, &remote_len)) < 0) { ! 283: plog(LLV_ERROR, LOCATION, NULL, ! 284: "failed to receive isakmp packet: %s\n", ! 285: strerror (errno)); ! 286: } ! 287: goto end; ! 288: } ! 289: ! 290: /* reject it if the size is tooooo big. */ ! 291: if (ntohl(isakmp.len) > 0xffff) { ! 292: plog(LLV_ERROR, LOCATION, NULL, ! 293: "the length in the isakmp header is too big.\n"); ! 294: if ((len = recvfrom(so_isakmp, (char *)&isakmp, sizeof(isakmp), ! 295: 0, (struct sockaddr *)&remote, &remote_len)) < 0) { ! 296: plog(LLV_ERROR, LOCATION, NULL, ! 297: "failed to receive isakmp packet: %s\n", ! 298: strerror (errno)); ! 299: } ! 300: goto end; ! 301: } ! 302: ! 303: /* read real message */ ! 304: if ((tmpbuf = vmalloc(ntohl(isakmp.len) + extralen)) == NULL) { ! 305: plog(LLV_ERROR, LOCATION, NULL, ! 306: "failed to allocate reading buffer (%u Bytes)\n", ! 307: ntohl(isakmp.len) + extralen); ! 308: /* dummy receive */ ! 309: if ((len = recvfrom(so_isakmp, (char *)&isakmp, sizeof(isakmp), ! 310: 0, (struct sockaddr *)&remote, &remote_len)) < 0) { ! 311: plog(LLV_ERROR, LOCATION, NULL, ! 312: "failed to receive isakmp packet: %s\n", ! 313: strerror (errno)); ! 314: } ! 315: goto end; ! 316: } ! 317: ! 318: while ((len = recvfromto(so_isakmp, (char *)tmpbuf->v, tmpbuf->l, ! 319: 0, (struct sockaddr *)&remote, &remote_len, ! 320: (struct sockaddr *)&local, &local_len)) < 0) { ! 321: if (errno == EINTR) ! 322: continue; ! 323: plog(LLV_ERROR, LOCATION, NULL, ! 324: "failed to receive isakmp packet: %s\n", ! 325: strerror (errno)); ! 326: goto end; ! 327: } ! 328: ! 329: if ((buf = vmalloc(len - extralen)) == NULL) { ! 330: plog(LLV_ERROR, LOCATION, NULL, ! 331: "failed to allocate reading buffer (%u Bytes)\n", ! 332: (len - extralen)); ! 333: goto end; ! 334: } ! 335: ! 336: memcpy (buf->v, tmpbuf->v + extralen, buf->l); ! 337: ! 338: len -= extralen; ! 339: ! 340: if (len != buf->l) { ! 341: plog(LLV_ERROR, LOCATION, (struct sockaddr *)&remote, ! 342: "received invalid length (%d != %zu), why ?\n", ! 343: len, buf->l); ! 344: goto end; ! 345: } ! 346: ! 347: plog(LLV_DEBUG, LOCATION, NULL, "===\n"); ! 348: plog(LLV_DEBUG, LOCATION, NULL, ! 349: "%d bytes message received %s\n", ! 350: len, saddr2str_fromto("from %s to %s", ! 351: (struct sockaddr *)&remote, ! 352: (struct sockaddr *)&local)); ! 353: plogdump(LLV_DEBUG, buf->v, buf->l); ! 354: ! 355: /* avoid packets with malicious port/address */ ! 356: if (extract_port((struct sockaddr *)&remote) == 0) { ! 357: plog(LLV_ERROR, LOCATION, (struct sockaddr *)&remote, ! 358: "src port == 0 (valid as UDP but not with IKE)\n"); ! 359: goto end; ! 360: } ! 361: ! 362: /* XXX: check sender whether to be allowed or not to accept */ ! 363: ! 364: /* XXX: I don't know how to check isakmp half connection attack. */ ! 365: ! 366: /* simply reply if the packet was processed. */ ! 367: res=check_recvdpkt((struct sockaddr *)&remote,(struct sockaddr *)&local, buf); ! 368: if (res) { ! 369: plog(LLV_NOTIFY, LOCATION, NULL, ! 370: "the packet is retransmitted by %s (%d).\n", ! 371: saddr2str((struct sockaddr *)&remote), res); ! 372: error = 0; ! 373: goto end; ! 374: } ! 375: ! 376: /* isakmp main routine */ ! 377: if (isakmp_main(buf, (struct sockaddr *)&remote, ! 378: (struct sockaddr *)&local) != 0) goto end; ! 379: ! 380: error = 0; ! 381: ! 382: end: ! 383: if (tmpbuf != NULL) ! 384: vfree(tmpbuf); ! 385: if (buf != NULL) ! 386: vfree(buf); ! 387: return error; ! 388: } ! 389: ! 390: /* ! 391: * main processing to handle isakmp payload ! 392: */ ! 393: static int ! 394: isakmp_main(msg, remote, local) ! 395: vchar_t *msg; ! 396: struct sockaddr *remote, *local; ! 397: { ! 398: struct isakmp *isakmp = (struct isakmp *)msg->v; ! 399: isakmp_index *index = (isakmp_index *)isakmp; ! 400: u_int32_t msgid = isakmp->msgid; ! 401: struct ph1handle *iph1; ! 402: ! 403: #ifdef HAVE_PRINT_ISAKMP_C ! 404: isakmp_printpacket(msg, remote, local, 0); ! 405: #endif ! 406: ! 407: /* the initiator's cookie must not be zero */ ! 408: if (memcmp(&isakmp->i_ck, r_ck0, sizeof(cookie_t)) == 0) { ! 409: plog(LLV_ERROR, LOCATION, remote, ! 410: "malformed cookie received.\n"); ! 411: return -1; ! 412: } ! 413: ! 414: /* Check the Major and Minor Version fields. */ ! 415: /* ! 416: * XXX Is is right to check version here ? ! 417: * I think it may no be here because the version depends ! 418: * on exchange status. ! 419: */ ! 420: if (isakmp->v < ISAKMP_VERSION_NUMBER) { ! 421: if (ISAKMP_GETMAJORV(isakmp->v) < ISAKMP_MAJOR_VERSION) { ! 422: plog(LLV_ERROR, LOCATION, remote, ! 423: "invalid major version %d.\n", ! 424: ISAKMP_GETMAJORV(isakmp->v)); ! 425: return -1; ! 426: } ! 427: #if ISAKMP_MINOR_VERSION > 0 ! 428: if (ISAKMP_GETMINORV(isakmp->v) < ISAKMP_MINOR_VERSION) { ! 429: plog(LLV_ERROR, LOCATION, remote, ! 430: "invalid minor version %d.\n", ! 431: ISAKMP_GETMINORV(isakmp->v)); ! 432: return -1; ! 433: } ! 434: #endif ! 435: } ! 436: ! 437: /* check the Flags field. */ ! 438: /* XXX How is the exclusive check, E and A ? */ ! 439: if (isakmp->flags & ~(ISAKMP_FLAG_E | ISAKMP_FLAG_C | ISAKMP_FLAG_A)) { ! 440: plog(LLV_ERROR, LOCATION, remote, ! 441: "invalid flag 0x%02x.\n", isakmp->flags); ! 442: return -1; ! 443: } ! 444: ! 445: /* ignore commit bit. */ ! 446: if (ISSET(isakmp->flags, ISAKMP_FLAG_C)) { ! 447: if (isakmp->msgid == 0) { ! 448: isakmp_info_send_nx(isakmp, remote, local, ! 449: ISAKMP_NTYPE_INVALID_FLAGS, NULL); ! 450: plog(LLV_ERROR, LOCATION, remote, ! 451: "Commit bit on phase1 forbidden.\n"); ! 452: return -1; ! 453: } ! 454: } ! 455: ! 456: iph1 = getph1byindex(index); ! 457: if (iph1 != NULL) { ! 458: /* validity check */ ! 459: if (memcmp(&isakmp->r_ck, r_ck0, sizeof(cookie_t)) == 0 && ! 460: iph1->side == INITIATOR) { ! 461: plog(LLV_DEBUG, LOCATION, remote, ! 462: "malformed cookie received or " ! 463: "the initiator's cookies collide.\n"); ! 464: return -1; ! 465: } ! 466: ! 467: #ifdef ENABLE_NATT ! 468: /* Floating ports for NAT-T */ ! 469: if (NATT_AVAILABLE(iph1) && ! 470: ! (iph1->natt_flags & NAT_PORTS_CHANGED) && ! 471: ((cmpsaddr(iph1->remote, remote) != CMPSADDR_MATCH) || ! 472: (cmpsaddr(iph1->local, local) != CMPSADDR_MATCH))) ! 473: { ! 474: /* prevent memory leak */ ! 475: racoon_free(iph1->remote); ! 476: racoon_free(iph1->local); ! 477: iph1->remote = NULL; ! 478: iph1->local = NULL; ! 479: ! 480: /* copy-in new addresses */ ! 481: iph1->remote = dupsaddr(remote); ! 482: if (iph1->remote == NULL) { ! 483: plog(LLV_ERROR, LOCATION, iph1->remote, ! 484: "phase1 failed: dupsaddr failed.\n"); ! 485: remph1(iph1); ! 486: delph1(iph1); ! 487: return -1; ! 488: } ! 489: iph1->local = dupsaddr(local); ! 490: if (iph1->local == NULL) { ! 491: plog(LLV_ERROR, LOCATION, iph1->remote, ! 492: "phase1 failed: dupsaddr failed.\n"); ! 493: remph1(iph1); ! 494: delph1(iph1); ! 495: return -1; ! 496: } ! 497: ! 498: /* set the flag to prevent further port floating ! 499: (FIXME: should we allow it? E.g. when the NAT gw ! 500: is rebooted?) */ ! 501: iph1->natt_flags |= NAT_PORTS_CHANGED | NAT_ADD_NON_ESP_MARKER; ! 502: ! 503: /* print some neat info */ ! 504: plog (LLV_INFO, LOCATION, NULL, ! 505: "NAT-T: ports changed to: %s\n", ! 506: saddr2str_fromto ("%s<->%s", iph1->remote, iph1->local)); ! 507: ! 508: natt_keepalive_add_ph1 (iph1); ! 509: } ! 510: #endif ! 511: ! 512: /* must be same addresses in one stream of a phase at least. */ ! 513: if (cmpsaddr(iph1->remote, remote) != CMPSADDR_MATCH) { ! 514: char *saddr_db, *saddr_act; ! 515: ! 516: saddr_db = racoon_strdup(saddr2str(iph1->remote)); ! 517: saddr_act = racoon_strdup(saddr2str(remote)); ! 518: STRDUP_FATAL(saddr_db); ! 519: STRDUP_FATAL(saddr_act); ! 520: ! 521: plog(LLV_WARNING, LOCATION, remote, ! 522: "remote address mismatched. db=%s, act=%s\n", ! 523: saddr_db, saddr_act); ! 524: ! 525: racoon_free(saddr_db); ! 526: racoon_free(saddr_act); ! 527: } ! 528: ! 529: /* ! 530: * don't check of exchange type here because other type will be ! 531: * with same index, for example, informational exchange. ! 532: */ ! 533: ! 534: /* XXX more acceptable check */ ! 535: } ! 536: ! 537: switch (isakmp->etype) { ! 538: case ISAKMP_ETYPE_IDENT: ! 539: case ISAKMP_ETYPE_AGG: ! 540: case ISAKMP_ETYPE_BASE: ! 541: /* phase 1 validity check */ ! 542: if (isakmp->msgid != 0) { ! 543: plog(LLV_ERROR, LOCATION, remote, ! 544: "message id should be zero in phase1.\n"); ! 545: return -1; ! 546: } ! 547: ! 548: /* search for isakmp status record of phase 1 */ ! 549: if (iph1 == NULL) { ! 550: /* ! 551: * the packet must be the 1st message from a initiator ! 552: * or the 2nd message from the responder. ! 553: */ ! 554: ! 555: /* search for phase1 handle by index without r_ck */ ! 556: iph1 = getph1byindex0(index); ! 557: if (iph1 == NULL) { ! 558: /*it must be the 1st message from a initiator.*/ ! 559: if (memcmp(&isakmp->r_ck, r_ck0, ! 560: sizeof(cookie_t)) != 0) { ! 561: ! 562: plog(LLV_DEBUG, LOCATION, remote, ! 563: "malformed cookie received " ! 564: "or the spi expired.\n"); ! 565: return -1; ! 566: } ! 567: ! 568: /* it must be responder's 1st exchange. */ ! 569: if (isakmp_ph1begin_r(msg, remote, local, ! 570: isakmp->etype) < 0) ! 571: return -1; ! 572: break; ! 573: ! 574: /*NOTREACHED*/ ! 575: } ! 576: ! 577: /* it must be the 2nd message from the responder. */ ! 578: if (iph1->side != INITIATOR) { ! 579: plog(LLV_DEBUG, LOCATION, remote, ! 580: "malformed cookie received. " ! 581: "it has to be as the initiator. %s\n", ! 582: isakmp_pindex(&iph1->index, 0)); ! 583: return -1; ! 584: } ! 585: } ! 586: ! 587: /* ! 588: * Don't delete phase 1 handler when the exchange type ! 589: * in handler is not equal to packet's one because of no ! 590: * authencication completed. ! 591: */ ! 592: if (iph1->etype != isakmp->etype) { ! 593: plog(LLV_ERROR, LOCATION, iph1->remote, ! 594: "exchange type is mismatched: " ! 595: "db=%s packet=%s, ignore it.\n", ! 596: s_isakmp_etype(iph1->etype), ! 597: s_isakmp_etype(isakmp->etype)); ! 598: return -1; ! 599: } ! 600: ! 601: #ifdef ENABLE_FRAG ! 602: if (isakmp->np == ISAKMP_NPTYPE_FRAG) ! 603: return frag_handler(iph1, msg, remote, local); ! 604: #endif ! 605: ! 606: /* call main process of phase 1 */ ! 607: if (ph1_main(iph1, msg) < 0) { ! 608: plog(LLV_ERROR, LOCATION, iph1->remote, ! 609: "phase1 negotiation failed.\n"); ! 610: remph1(iph1); ! 611: delph1(iph1); ! 612: return -1; ! 613: } ! 614: break; ! 615: ! 616: case ISAKMP_ETYPE_AUTH: ! 617: plog(LLV_INFO, LOCATION, remote, ! 618: "unsupported exchange %d received.\n", ! 619: isakmp->etype); ! 620: break; ! 621: ! 622: case ISAKMP_ETYPE_INFO: ! 623: case ISAKMP_ETYPE_ACKINFO: ! 624: /* ! 625: * iph1 must be present for Information message. ! 626: * if iph1 is null then trying to get the phase1 status ! 627: * as the packet from responder againt initiator's 1st ! 628: * exchange in phase 1. ! 629: * NOTE: We think such informational exchange should be ignored. ! 630: */ ! 631: if (iph1 == NULL) { ! 632: iph1 = getph1byindex0(index); ! 633: if (iph1 == NULL) { ! 634: plog(LLV_ERROR, LOCATION, remote, ! 635: "unknown Informational " ! 636: "exchange received.\n"); ! 637: return -1; ! 638: } ! 639: if (cmpsaddr(iph1->remote, remote) != CMPSADDR_MATCH) { ! 640: plog(LLV_WARNING, LOCATION, remote, ! 641: "remote address mismatched. " ! 642: "db=%s\n", ! 643: saddr2str(iph1->remote)); ! 644: } ! 645: } ! 646: ! 647: #ifdef ENABLE_FRAG ! 648: if (isakmp->np == ISAKMP_NPTYPE_FRAG) ! 649: return frag_handler(iph1, msg, remote, local); ! 650: #endif ! 651: ! 652: if (isakmp_info_recv(iph1, msg) < 0) ! 653: return -1; ! 654: break; ! 655: ! 656: case ISAKMP_ETYPE_QUICK: ! 657: { ! 658: struct ph2handle *iph2; ! 659: ! 660: if (iph1 == NULL) { ! 661: isakmp_info_send_nx(isakmp, remote, local, ! 662: ISAKMP_NTYPE_INVALID_COOKIE, NULL); ! 663: plog(LLV_ERROR, LOCATION, remote, ! 664: "can't start the quick mode, " ! 665: "there is no ISAKMP-SA, %s\n", ! 666: isakmp_pindex((isakmp_index *)&isakmp->i_ck, ! 667: isakmp->msgid)); ! 668: return -1; ! 669: } ! 670: #ifdef ENABLE_HYBRID ! 671: /* Reinit the IVM if it's still there */ ! 672: if (iph1->mode_cfg && iph1->mode_cfg->ivm) { ! 673: oakley_delivm(iph1->mode_cfg->ivm); ! 674: iph1->mode_cfg->ivm = NULL; ! 675: } ! 676: #endif ! 677: #ifdef ENABLE_FRAG ! 678: if (isakmp->np == ISAKMP_NPTYPE_FRAG) ! 679: return frag_handler(iph1, msg, remote, local); ! 680: #endif ! 681: ! 682: /* check status of phase 1 whether negotiated or not. */ ! 683: if (iph1->status != PHASE1ST_ESTABLISHED && ! 684: iph1->status != PHASE1ST_DYING) { ! 685: plog(LLV_ERROR, LOCATION, remote, ! 686: "can't start the quick mode, " ! 687: "there is no valid ISAKMP-SA, %s\n", ! 688: isakmp_pindex(&iph1->index, iph1->msgid)); ! 689: return -1; ! 690: } ! 691: ! 692: /* search isakmp phase 2 stauts record. */ ! 693: iph2 = getph2bymsgid(iph1, msgid); ! 694: if (iph2 == NULL) { ! 695: /* it must be new negotiation as responder */ ! 696: if (isakmp_ph2begin_r(iph1, msg) < 0) ! 697: return -1; ! 698: return 0; ! 699: /*NOTREACHED*/ ! 700: } ! 701: ! 702: /* commit bit. */ ! 703: /* XXX ! 704: * we keep to set commit bit during negotiation. ! 705: * When SA is configured, bit will be reset. ! 706: * XXX ! 707: * don't initiate commit bit. should be fixed in the future. ! 708: */ ! 709: if (ISSET(isakmp->flags, ISAKMP_FLAG_C)) ! 710: iph2->flags |= ISAKMP_FLAG_C; ! 711: ! 712: /* call main process of quick mode */ ! 713: if (quick_main(iph2, msg) < 0) { ! 714: plog(LLV_ERROR, LOCATION, iph1->remote, ! 715: "phase2 negotiation failed.\n"); ! 716: remph2(iph2); ! 717: delph2(iph2); ! 718: return -1; ! 719: } ! 720: } ! 721: break; ! 722: ! 723: case ISAKMP_ETYPE_NEWGRP: ! 724: if (iph1 == NULL) { ! 725: plog(LLV_ERROR, LOCATION, remote, ! 726: "Unknown new group mode exchange, " ! 727: "there is no ISAKMP-SA.\n"); ! 728: return -1; ! 729: } ! 730: ! 731: #ifdef ENABLE_FRAG ! 732: if (isakmp->np == ISAKMP_NPTYPE_FRAG) ! 733: return frag_handler(iph1, msg, remote, local); ! 734: #endif ! 735: ! 736: isakmp_newgroup_r(iph1, msg); ! 737: break; ! 738: ! 739: #ifdef ENABLE_HYBRID ! 740: case ISAKMP_ETYPE_CFG: ! 741: if (iph1 == NULL) { ! 742: plog(LLV_ERROR, LOCATION, NULL, ! 743: "mode config %d from %s, " ! 744: "but we have no ISAKMP-SA.\n", ! 745: isakmp->etype, saddr2str(remote)); ! 746: return -1; ! 747: } ! 748: ! 749: #ifdef ENABLE_FRAG ! 750: if (isakmp->np == ISAKMP_NPTYPE_FRAG) ! 751: return frag_handler(iph1, msg, remote, local); ! 752: #endif ! 753: ! 754: isakmp_cfg_r(iph1, msg); ! 755: break; ! 756: #endif ! 757: ! 758: case ISAKMP_ETYPE_NONE: ! 759: default: ! 760: plog(LLV_ERROR, LOCATION, NULL, ! 761: "Invalid exchange type %d from %s.\n", ! 762: isakmp->etype, saddr2str(remote)); ! 763: return -1; ! 764: } ! 765: ! 766: return 0; ! 767: } ! 768: ! 769: /* ! 770: * main function of phase 1. ! 771: */ ! 772: static int ! 773: ph1_main(iph1, msg) ! 774: struct ph1handle *iph1; ! 775: vchar_t *msg; ! 776: { ! 777: int error; ! 778: #ifdef ENABLE_STATS ! 779: struct timeval start, end; ! 780: #endif ! 781: ! 782: /* ignore a packet */ ! 783: if (iph1->status >= PHASE1ST_ESTABLISHED) ! 784: return 0; ! 785: ! 786: #ifdef ENABLE_STATS ! 787: gettimeofday(&start, NULL); ! 788: #endif ! 789: /* receive */ ! 790: if (ph1exchange[etypesw1(iph1->etype)] ! 791: [iph1->side] ! 792: [iph1->status] == NULL) { ! 793: plog(LLV_ERROR, LOCATION, iph1->remote, ! 794: "why isn't the function defined.\n"); ! 795: return -1; ! 796: } ! 797: error = (ph1exchange[etypesw1(iph1->etype)] ! 798: [iph1->side] ! 799: [iph1->status])(iph1, msg); ! 800: if (error != 0) { ! 801: ! 802: /* XXX ! 803: * When an invalid packet is received on phase1, it should ! 804: * be selected to process this packet. That is to respond ! 805: * with a notify and delete phase 1 handler, OR not to respond ! 806: * and keep phase 1 handler. However, in PHASE1ST_START when ! 807: * acting as RESPONDER we must not keep phase 1 handler or else ! 808: * it will stay forever. ! 809: */ ! 810: ! 811: if (iph1->side == RESPONDER && iph1->status == PHASE1ST_START) { ! 812: plog(LLV_ERROR, LOCATION, iph1->remote, ! 813: "failed to pre-process ph1 packet (side: %d, status %d).\n", ! 814: iph1->side, iph1->status); ! 815: return -1; ! 816: } else { ! 817: /* ignore the error and keep phase 1 handler */ ! 818: return 0; ! 819: } ! 820: } ! 821: ! 822: #ifndef ENABLE_FRAG ! 823: /* free resend buffer */ ! 824: if (iph1->sendbuf == NULL) { ! 825: plog(LLV_ERROR, LOCATION, NULL, ! 826: "no buffer found as sendbuf\n"); ! 827: return -1; ! 828: } ! 829: #endif ! 830: ! 831: VPTRINIT(iph1->sendbuf); ! 832: ! 833: /* turn off schedule */ ! 834: sched_cancel(&iph1->scr); ! 835: ! 836: /* send */ ! 837: plog(LLV_DEBUG, LOCATION, NULL, "===\n"); ! 838: if ((ph1exchange[etypesw1(iph1->etype)] ! 839: [iph1->side] ! 840: [iph1->status])(iph1, msg) != 0) { ! 841: plog(LLV_ERROR, LOCATION, iph1->remote, ! 842: "failed to process ph1 packet (side: %d, status: %d).\n", ! 843: iph1->side, iph1->status); ! 844: return -1; ! 845: } ! 846: ! 847: #ifdef ENABLE_STATS ! 848: gettimeofday(&end, NULL); ! 849: syslog(LOG_NOTICE, "%s(%s): %8.6f", ! 850: "phase1", s_isakmp_state(iph1->etype, iph1->side, iph1->status), ! 851: timedelta(&start, &end)); ! 852: #endif ! 853: if (iph1->status == PHASE1ST_ESTABLISHED) { ! 854: ! 855: #ifdef ENABLE_STATS ! 856: gettimeofday(&iph1->end, NULL); ! 857: syslog(LOG_NOTICE, "%s(%s): %8.6f", ! 858: "phase1", s_isakmp_etype(iph1->etype), ! 859: timedelta(&iph1->start, &iph1->end)); ! 860: #endif ! 861: ! 862: /* save created date. */ ! 863: (void)time(&iph1->created); ! 864: ! 865: /* migrate ph2s from dying ph1s */ ! 866: migrate_dying_ph12(iph1); ! 867: ! 868: /* add to the schedule to expire, and seve back pointer. */ ! 869: if (ph1_rekey_enabled(iph1)) { ! 870: sched_schedule(&iph1->sce, ! 871: iph1->approval->lifetime * ! 872: PFKEY_SOFT_LIFETIME_RATE / 100, ! 873: isakmp_ph1dying_stub); ! 874: } else { ! 875: sched_schedule(&iph1->sce, iph1->approval->lifetime, ! 876: isakmp_ph1expire_stub); ! 877: } ! 878: ! 879: #ifdef ENABLE_HYBRID ! 880: if (iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) { ! 881: switch (iph1->approval->authmethod) { ! 882: case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R: ! 883: case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R: ! 884: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R: ! 885: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R: ! 886: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R: ! 887: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R: ! 888: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R: ! 889: xauth_sendreq(iph1); ! 890: /* XXX Don't process INITIAL_CONTACT */ ! 891: iph1->rmconf->ini_contact = 0; ! 892: break; ! 893: default: ! 894: break; ! 895: } ! 896: } ! 897: #endif ! 898: #ifdef ENABLE_DPD ! 899: /* Schedule the r_u_there.... */ ! 900: if(iph1->dpd_support && iph1->rmconf->dpd_interval) ! 901: isakmp_sched_r_u(iph1, 0); ! 902: #endif ! 903: ! 904: /* INITIAL-CONTACT processing */ ! 905: /* don't anything if local test mode. */ ! 906: if (!f_local ! 907: && iph1->rmconf->ini_contact && !getcontacted(iph1->remote)) { ! 908: /* send INITIAL-CONTACT */ ! 909: isakmp_info_send_n1(iph1, ! 910: ISAKMP_NTYPE_INITIAL_CONTACT, NULL); ! 911: /* insert a node into contacted list. */ ! 912: if (inscontacted(iph1->remote) == -1) { ! 913: plog(LLV_ERROR, LOCATION, iph1->remote, ! 914: "failed to add contacted list.\n"); ! 915: /* ignore */ ! 916: } ! 917: } ! 918: if (iph1->initial_contact_received) ! 919: isakmp_info_recv_initialcontact(iph1, NULL); ! 920: ! 921: log_ph1established(iph1); ! 922: plog(LLV_DEBUG, LOCATION, NULL, "===\n"); ! 923: ! 924: /* ! 925: * SA up shell script hook: do it now,except if ! 926: * ISAKMP mode config was requested. In the later ! 927: * case it is done when we receive the configuration. ! 928: */ ! 929: if ((iph1->status == PHASE1ST_ESTABLISHED) && ! 930: !iph1->rmconf->mode_cfg) { ! 931: switch (iph1->approval->authmethod) { ! 932: #ifdef ENABLE_HYBRID ! 933: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R: ! 934: case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R: ! 935: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R: ! 936: /* Unimplemeted... */ ! 937: case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R: ! 938: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R: ! 939: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R: ! 940: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R: ! 941: break; ! 942: #endif ! 943: default: ! 944: script_hook(iph1, SCRIPT_PHASE1_UP); ! 945: break; ! 946: } ! 947: } ! 948: } ! 949: ! 950: return 0; ! 951: } ! 952: ! 953: /* ! 954: * main function of quick mode. ! 955: */ ! 956: static int ! 957: quick_main(iph2, msg) ! 958: struct ph2handle *iph2; ! 959: vchar_t *msg; ! 960: { ! 961: struct isakmp *isakmp = (struct isakmp *)msg->v; ! 962: int error; ! 963: #ifdef ENABLE_STATS ! 964: struct timeval start, end; ! 965: #endif ! 966: ! 967: /* ignore a packet */ ! 968: if (iph2->status == PHASE2ST_ESTABLISHED ! 969: || iph2->status == PHASE2ST_GETSPISENT) ! 970: return 0; ! 971: ! 972: #ifdef ENABLE_STATS ! 973: gettimeofday(&start, NULL); ! 974: #endif ! 975: ! 976: /* receive */ ! 977: if (ph2exchange[etypesw2(isakmp->etype)] ! 978: [iph2->side] ! 979: [iph2->status] == NULL) { ! 980: plog(LLV_ERROR, LOCATION, iph2->ph1->remote, ! 981: "why isn't the function defined.\n"); ! 982: return -1; ! 983: } ! 984: error = (ph2exchange[etypesw2(isakmp->etype)] ! 985: [iph2->side] ! 986: [iph2->status])(iph2, msg); ! 987: if (error != 0) { ! 988: plog(LLV_ERROR, LOCATION, iph2->ph1->remote, ! 989: "failed to pre-process ph2 packet (side: %d, status %d).\n", ! 990: iph2->side, iph2->status); ! 991: if (error == ISAKMP_INTERNAL_ERROR) ! 992: return 0; ! 993: isakmp_info_send_n1(iph2->ph1, error, NULL); ! 994: return -1; ! 995: } ! 996: ! 997: /* when using commit bit, status will be reached here. */ ! 998: if (iph2->status == PHASE2ST_ADDSA) ! 999: return 0; ! 1000: ! 1001: /* free resend buffer */ ! 1002: if (iph2->sendbuf == NULL) { ! 1003: plog(LLV_ERROR, LOCATION, NULL, ! 1004: "no buffer found as sendbuf\n"); ! 1005: return -1; ! 1006: } ! 1007: VPTRINIT(iph2->sendbuf); ! 1008: ! 1009: /* turn off schedule */ ! 1010: sched_cancel(&iph2->scr); ! 1011: ! 1012: /* send */ ! 1013: plog(LLV_DEBUG, LOCATION, NULL, "===\n"); ! 1014: if ((ph2exchange[etypesw2(isakmp->etype)] ! 1015: [iph2->side] ! 1016: [iph2->status])(iph2, msg) != 0) { ! 1017: plog(LLV_ERROR, LOCATION, iph2->ph1->remote, ! 1018: "failed to process ph2 packet (side: %d, status: %d).\n", ! 1019: iph2->side, iph2->status); ! 1020: return -1; ! 1021: } ! 1022: ! 1023: #ifdef ENABLE_STATS ! 1024: gettimeofday(&end, NULL); ! 1025: syslog(LOG_NOTICE, "%s(%s): %8.6f", ! 1026: "phase2", ! 1027: s_isakmp_state(ISAKMP_ETYPE_QUICK, iph2->side, iph2->status), ! 1028: timedelta(&start, &end)); ! 1029: #endif ! 1030: ! 1031: return 0; ! 1032: } ! 1033: ! 1034: /* new negotiation of phase 1 for initiator */ ! 1035: struct ph1handle * ! 1036: isakmp_ph1begin_i(rmconf, remote, local) ! 1037: struct remoteconf *rmconf; ! 1038: struct sockaddr *remote, *local; ! 1039: { ! 1040: struct ph1handle *iph1; ! 1041: #ifdef ENABLE_STATS ! 1042: struct timeval start, end; ! 1043: #endif ! 1044: ! 1045: /* get new entry to isakmp status table. */ ! 1046: iph1 = newph1(); ! 1047: if (iph1 == NULL) ! 1048: return NULL; ! 1049: ! 1050: iph1->status = PHASE1ST_START; ! 1051: iph1->rmconf = rmconf; ! 1052: iph1->side = INITIATOR; ! 1053: iph1->version = ISAKMP_VERSION_NUMBER; ! 1054: iph1->msgid = 0; ! 1055: iph1->flags = 0; ! 1056: iph1->ph2cnt = 0; ! 1057: #ifdef HAVE_GSSAPI ! 1058: iph1->gssapi_state = NULL; ! 1059: #endif ! 1060: #ifdef ENABLE_HYBRID ! 1061: if ((iph1->mode_cfg = isakmp_cfg_mkstate()) == NULL) { ! 1062: delph1(iph1); ! 1063: return NULL; ! 1064: } ! 1065: #endif ! 1066: #ifdef ENABLE_FRAG ! 1067: ! 1068: if(rmconf->ike_frag == ISAKMP_FRAG_FORCE) ! 1069: iph1->frag = 1; ! 1070: else ! 1071: iph1->frag = 0; ! 1072: iph1->frag_chain = NULL; ! 1073: #endif ! 1074: iph1->approval = NULL; ! 1075: ! 1076: /* XXX copy remote address */ ! 1077: if (copy_ph1addresses(iph1, rmconf, remote, local) < 0) { ! 1078: delph1(iph1); ! 1079: return NULL; ! 1080: } ! 1081: ! 1082: (void)insph1(iph1); ! 1083: ! 1084: /* start phase 1 exchange */ ! 1085: iph1->etype = rmconf->etypes->type; ! 1086: ! 1087: plog(LLV_DEBUG, LOCATION, NULL, "===\n"); ! 1088: { ! 1089: char *a; ! 1090: ! 1091: a = racoon_strdup(saddr2str(iph1->local)); ! 1092: STRDUP_FATAL(a); ! 1093: ! 1094: plog(LLV_INFO, LOCATION, NULL, ! 1095: "initiate new phase 1 negotiation: %s<=>%s\n", ! 1096: a, saddr2str(iph1->remote)); ! 1097: racoon_free(a); ! 1098: } ! 1099: plog(LLV_INFO, LOCATION, NULL, ! 1100: "begin %s mode.\n", ! 1101: s_isakmp_etype(iph1->etype)); ! 1102: ! 1103: #ifdef ENABLE_STATS ! 1104: gettimeofday(&iph1->start, NULL); ! 1105: gettimeofday(&start, NULL); ! 1106: #endif ! 1107: /* start exchange */ ! 1108: if ((ph1exchange[etypesw1(iph1->etype)] ! 1109: [iph1->side] ! 1110: [iph1->status])(iph1, NULL) != 0) { ! 1111: /* failed to start phase 1 negotiation */ ! 1112: remph1(iph1); ! 1113: delph1(iph1); ! 1114: ! 1115: return NULL; ! 1116: } ! 1117: ! 1118: #ifdef ENABLE_STATS ! 1119: gettimeofday(&end, NULL); ! 1120: syslog(LOG_NOTICE, "%s(%s): %8.6f", ! 1121: "phase1", ! 1122: s_isakmp_state(iph1->etype, iph1->side, iph1->status), ! 1123: timedelta(&start, &end)); ! 1124: #endif ! 1125: ! 1126: return iph1; ! 1127: } ! 1128: ! 1129: /* new negotiation of phase 1 for responder */ ! 1130: static int ! 1131: isakmp_ph1begin_r(msg, remote, local, etype) ! 1132: vchar_t *msg; ! 1133: struct sockaddr *remote, *local; ! 1134: u_int8_t etype; ! 1135: { ! 1136: struct isakmp *isakmp = (struct isakmp *)msg->v; ! 1137: struct ph1handle *iph1; ! 1138: struct rmconfselector rmsel; ! 1139: #ifdef ENABLE_STATS ! 1140: struct timeval start, end; ! 1141: #endif ! 1142: ! 1143: /* check if this etype is allowed */ ! 1144: memset(&rmsel, 0, sizeof(rmsel)); ! 1145: rmsel.remote = remote; ! 1146: if (enumrmconf(&rmsel, check_etypeok, (void *) (intptr_t) etype) == 0) { ! 1147: plog(LLV_ERROR, LOCATION, remote, ! 1148: "exchange %s not allowed in any applicable rmconf.\n", ! 1149: s_isakmp_etype(etype)); ! 1150: return -1; ! 1151: } ! 1152: ! 1153: /* get new entry to isakmp status table. */ ! 1154: iph1 = newph1(); ! 1155: if (iph1 == NULL) ! 1156: return -1; ! 1157: ! 1158: memcpy(&iph1->index.i_ck, &isakmp->i_ck, sizeof(iph1->index.i_ck)); ! 1159: iph1->status = PHASE1ST_START; ! 1160: iph1->flags = 0; ! 1161: iph1->side = RESPONDER; ! 1162: iph1->etype = etype; ! 1163: iph1->version = isakmp->v; ! 1164: iph1->msgid = 0; ! 1165: #ifdef HAVE_GSSAPI ! 1166: iph1->gssapi_state = NULL; ! 1167: #endif ! 1168: #ifdef ENABLE_HYBRID ! 1169: if ((iph1->mode_cfg = isakmp_cfg_mkstate()) == NULL) { ! 1170: delph1(iph1); ! 1171: return -1; ! 1172: } ! 1173: #endif ! 1174: #ifdef ENABLE_FRAG ! 1175: iph1->frag = 0; ! 1176: iph1->frag_chain = NULL; ! 1177: #endif ! 1178: iph1->approval = NULL; ! 1179: ! 1180: #ifdef ENABLE_NATT ! 1181: /* RFC3947 says that we MUST accept new phases1 on NAT-T floated port. ! 1182: * We have to setup this flag now to correctly generate the first reply. ! 1183: * Don't know if a better check could be done for that ? ! 1184: */ ! 1185: if(extract_port(local) == lcconf->port_isakmp_natt) ! 1186: iph1->natt_flags |= (NAT_PORTS_CHANGED); ! 1187: #endif ! 1188: ! 1189: /* copy remote address; remote and local always contain ! 1190: * port numbers so rmconf is not needed */ ! 1191: if (copy_ph1addresses(iph1, NULL, remote, local) < 0) { ! 1192: delph1(iph1); ! 1193: return -1; ! 1194: } ! 1195: (void)insph1(iph1); ! 1196: ! 1197: plog(LLV_DEBUG, LOCATION, NULL, "===\n"); ! 1198: { ! 1199: char *a; ! 1200: ! 1201: a = racoon_strdup(saddr2str(iph1->local)); ! 1202: STRDUP_FATAL(a); ! 1203: ! 1204: plog(LLV_INFO, LOCATION, NULL, ! 1205: "respond new phase 1 negotiation: %s<=>%s\n", ! 1206: a, saddr2str(iph1->remote)); ! 1207: racoon_free(a); ! 1208: } ! 1209: plog(LLV_INFO, LOCATION, NULL, ! 1210: "begin %s mode.\n", s_isakmp_etype(etype)); ! 1211: ! 1212: #ifdef ENABLE_STATS ! 1213: gettimeofday(&iph1->start, NULL); ! 1214: gettimeofday(&start, NULL); ! 1215: #endif ! 1216: ! 1217: #ifndef ENABLE_FRAG ! 1218: ! 1219: /* start exchange */ ! 1220: if ((ph1exchange[etypesw1(iph1->etype)] ! 1221: [iph1->side] ! 1222: [iph1->status])(iph1, msg) < 0 ! 1223: || (ph1exchange[etypesw1(iph1->etype)] ! 1224: [iph1->side] ! 1225: [iph1->status])(iph1, msg) < 0) { ! 1226: plog(LLV_ERROR, LOCATION, remote, ! 1227: "failed to process ph1 packet (side: %d, status: %d).\n", ! 1228: iph1->side, iph1->status); ! 1229: remph1(iph1); ! 1230: delph1(iph1); ! 1231: return -1; ! 1232: } ! 1233: ! 1234: #ifdef ENABLE_STATS ! 1235: gettimeofday(&end, NULL); ! 1236: syslog(LOG_NOTICE, "%s(%s): %8.6f", ! 1237: "phase1", ! 1238: s_isakmp_state(iph1->etype, iph1->side, iph1->status), ! 1239: timedelta(&start, &end)); ! 1240: #endif ! 1241: ! 1242: return 0; ! 1243: ! 1244: #else /* ENABLE_FRAG */ ! 1245: ! 1246: /* now that we have a phase1 handle, feed back into our ! 1247: * main receive function to catch fragmented packets ! 1248: */ ! 1249: ! 1250: return isakmp_main(msg, remote, local); ! 1251: ! 1252: #endif /* ENABLE_FRAG */ ! 1253: ! 1254: } ! 1255: ! 1256: /* new negotiation of phase 2 for initiator */ ! 1257: static int ! 1258: isakmp_ph2begin_i(iph1, iph2) ! 1259: struct ph1handle *iph1; ! 1260: struct ph2handle *iph2; ! 1261: { ! 1262: #ifdef ENABLE_HYBRID ! 1263: if (xauth_check(iph1) != 0) { ! 1264: plog(LLV_ERROR, LOCATION, NULL, ! 1265: "Attempt to start phase 2 whereas Xauth failed\n"); ! 1266: return -1; ! 1267: } ! 1268: #endif ! 1269: ! 1270: /* fixup ph2 ports for this ph1 */ ! 1271: if (extract_port(iph2->src) == 0) ! 1272: set_port(iph2->src, extract_port(iph1->local)); ! 1273: if (extract_port(iph2->dst) == 0) ! 1274: set_port(iph2->dst, extract_port(iph1->remote)); ! 1275: ! 1276: /* found ISAKMP-SA. */ ! 1277: plog(LLV_DEBUG, LOCATION, NULL, "===\n"); ! 1278: plog(LLV_DEBUG, LOCATION, NULL, "begin QUICK mode.\n"); ! 1279: { ! 1280: char *a; ! 1281: a = racoon_strdup(saddr2str(iph2->src)); ! 1282: STRDUP_FATAL(a); ! 1283: ! 1284: plog(LLV_INFO, LOCATION, NULL, ! 1285: "initiate new phase 2 negotiation: %s<=>%s\n", ! 1286: a, saddr2str(iph2->dst)); ! 1287: racoon_free(a); ! 1288: } ! 1289: ! 1290: #ifdef ENABLE_STATS ! 1291: gettimeofday(&iph2->start, NULL); ! 1292: #endif ! 1293: if (iph2->status != PHASE2ST_EXPIRED) /* Phase 1 is already bound (ongoing rekeying) */ ! 1294: bindph12(iph1, iph2); ! 1295: iph2->status = PHASE2ST_STATUS2; ! 1296: ! 1297: if ((ph2exchange[etypesw2(ISAKMP_ETYPE_QUICK)] ! 1298: [iph2->side] ! 1299: [iph2->status])(iph2, NULL) < 0) { ! 1300: /* release ipsecsa handler due to internal error. */ ! 1301: remph2(iph2); ! 1302: return -1; ! 1303: } ! 1304: return 0; ! 1305: } ! 1306: ! 1307: /* new negotiation of phase 2 for responder */ ! 1308: static int ! 1309: isakmp_ph2begin_r(iph1, msg) ! 1310: struct ph1handle *iph1; ! 1311: vchar_t *msg; ! 1312: { ! 1313: struct isakmp *isakmp = (struct isakmp *)msg->v; ! 1314: struct ph2handle *iph2 = 0; ! 1315: int error; ! 1316: #ifdef ENABLE_STATS ! 1317: struct timeval start, end; ! 1318: #endif ! 1319: #ifdef ENABLE_HYBRID ! 1320: if (xauth_check(iph1) != 0) { ! 1321: plog(LLV_ERROR, LOCATION, NULL, ! 1322: "Attempt to start phase 2 whereas Xauth failed\n"); ! 1323: return -1; ! 1324: } ! 1325: #endif ! 1326: ! 1327: iph2 = newph2(); ! 1328: if (iph2 == NULL) { ! 1329: plog(LLV_ERROR, LOCATION, NULL, ! 1330: "failed to allocate phase2 entry.\n"); ! 1331: return -1; ! 1332: } ! 1333: ! 1334: iph2->side = RESPONDER; ! 1335: iph2->status = PHASE2ST_START; ! 1336: iph2->flags = isakmp->flags; ! 1337: iph2->msgid = isakmp->msgid; ! 1338: iph2->seq = pk_getseq(); ! 1339: iph2->ivm = oakley_newiv2(iph1, iph2->msgid); ! 1340: if (iph2->ivm == NULL) { ! 1341: delph2(iph2); ! 1342: return -1; ! 1343: } ! 1344: iph2->dst = dupsaddr(iph1->remote); /* XXX should be considered */ ! 1345: if (iph2->dst == NULL) { ! 1346: delph2(iph2); ! 1347: return -1; ! 1348: } ! 1349: iph2->src = dupsaddr(iph1->local); /* XXX should be considered */ ! 1350: if (iph2->src == NULL) { ! 1351: delph2(iph2); ! 1352: return -1; ! 1353: } ! 1354: ! 1355: /* add new entry to isakmp status table */ ! 1356: insph2(iph2); ! 1357: bindph12(iph1, iph2); ! 1358: ! 1359: plog(LLV_DEBUG, LOCATION, NULL, "===\n"); ! 1360: { ! 1361: char *a; ! 1362: ! 1363: a = racoon_strdup(saddr2str(iph2->src)); ! 1364: STRDUP_FATAL(a); ! 1365: ! 1366: plog(LLV_INFO, LOCATION, NULL, ! 1367: "respond new phase 2 negotiation: %s<=>%s\n", ! 1368: a, saddr2str(iph2->dst)); ! 1369: racoon_free(a); ! 1370: } ! 1371: ! 1372: #ifdef ENABLE_STATS ! 1373: gettimeofday(&start, NULL); ! 1374: #endif ! 1375: ! 1376: error = (ph2exchange[etypesw2(ISAKMP_ETYPE_QUICK)] ! 1377: [iph2->side] ! 1378: [iph2->status])(iph2, msg); ! 1379: if (error != 0) { ! 1380: plog(LLV_ERROR, LOCATION, iph1->remote, ! 1381: "failed to pre-process ph2 packet (side: %d, status: %d).\n", ! 1382: iph2->side, iph2->status); ! 1383: if (error != ISAKMP_INTERNAL_ERROR) ! 1384: isakmp_info_send_n1(iph2->ph1, error, NULL); ! 1385: /* ! 1386: * release handler because it's wrong that ph2handle is kept ! 1387: * after failed to check message for responder's. ! 1388: */ ! 1389: remph2(iph2); ! 1390: delph2(iph2); ! 1391: return -1; ! 1392: } ! 1393: ! 1394: /* send */ ! 1395: plog(LLV_DEBUG, LOCATION, NULL, "===\n"); ! 1396: if ((ph2exchange[etypesw2(isakmp->etype)] ! 1397: [iph2->side] ! 1398: [iph2->status])(iph2, msg) < 0) { ! 1399: plog(LLV_ERROR, LOCATION, iph2->ph1->remote, ! 1400: "failed to process ph2 packet (side: %d, status: %d).\n", ! 1401: iph2->side, iph2->status); ! 1402: /* don't release handler */ ! 1403: return -1; ! 1404: } ! 1405: #ifdef ENABLE_STATS ! 1406: gettimeofday(&end, NULL); ! 1407: syslog(LOG_NOTICE, "%s(%s): %8.6f", ! 1408: "phase2", ! 1409: s_isakmp_state(ISAKMP_ETYPE_QUICK, iph2->side, iph2->status), ! 1410: timedelta(&start, &end)); ! 1411: #endif ! 1412: ! 1413: return 0; ! 1414: } ! 1415: ! 1416: /* ! 1417: * parse ISAKMP payloads, without ISAKMP base header. ! 1418: */ ! 1419: vchar_t * ! 1420: isakmp_parsewoh(np0, gen, len) ! 1421: int np0; ! 1422: struct isakmp_gen *gen; ! 1423: int len; ! 1424: { ! 1425: u_char np = np0 & 0xff; ! 1426: int tlen, plen; ! 1427: vchar_t *result; ! 1428: struct isakmp_parse_t *p, *ep; ! 1429: ! 1430: plog(LLV_DEBUG, LOCATION, NULL, "begin.\n"); ! 1431: ! 1432: /* ! 1433: * 5 is a magic number, but any value larger than 2 should be fine ! 1434: * as we do vrealloc() in the following loop. ! 1435: */ ! 1436: result = vmalloc(sizeof(struct isakmp_parse_t) * 5); ! 1437: if (result == NULL) { ! 1438: plog(LLV_ERROR, LOCATION, NULL, ! 1439: "failed to get buffer.\n"); ! 1440: return NULL; ! 1441: } ! 1442: p = (struct isakmp_parse_t *)result->v; ! 1443: ep = (struct isakmp_parse_t *)(result->v + result->l - sizeof(*ep)); ! 1444: ! 1445: tlen = len; ! 1446: ! 1447: /* parse through general headers */ ! 1448: while (0 < tlen && np != ISAKMP_NPTYPE_NONE) { ! 1449: if (tlen <= sizeof(struct isakmp_gen)) { ! 1450: /* don't send information, see isakmp_ident_r1() */ ! 1451: plog(LLV_ERROR, LOCATION, NULL, ! 1452: "invalid length of payload\n"); ! 1453: vfree(result); ! 1454: return NULL; ! 1455: } ! 1456: ! 1457: plog(LLV_DEBUG, LOCATION, NULL, ! 1458: "seen nptype=%u(%s)\n", np, s_isakmp_nptype(np)); ! 1459: ! 1460: p->type = np; ! 1461: p->len = ntohs(gen->len); ! 1462: if (p->len < sizeof(struct isakmp_gen) || p->len > tlen) { ! 1463: plog(LLV_DEBUG, LOCATION, NULL, ! 1464: "invalid length of payload\n"); ! 1465: vfree(result); ! 1466: return NULL; ! 1467: } ! 1468: p->ptr = gen; ! 1469: p++; ! 1470: if (ep <= p) { ! 1471: int off; ! 1472: ! 1473: off = p - (struct isakmp_parse_t *)result->v; ! 1474: result = vrealloc(result, result->l * 2); ! 1475: if (result == NULL) { ! 1476: plog(LLV_DEBUG, LOCATION, NULL, ! 1477: "failed to realloc buffer.\n"); ! 1478: vfree(result); ! 1479: return NULL; ! 1480: } ! 1481: ep = (struct isakmp_parse_t *) ! 1482: (result->v + result->l - sizeof(*ep)); ! 1483: p = (struct isakmp_parse_t *)result->v; ! 1484: p += off; ! 1485: } ! 1486: ! 1487: np = gen->np; ! 1488: plen = ntohs(gen->len); ! 1489: gen = (struct isakmp_gen *)((caddr_t)gen + plen); ! 1490: tlen -= plen; ! 1491: } ! 1492: p->type = ISAKMP_NPTYPE_NONE; ! 1493: p->len = 0; ! 1494: p->ptr = NULL; ! 1495: ! 1496: plog(LLV_DEBUG, LOCATION, NULL, "succeed.\n"); ! 1497: ! 1498: return result; ! 1499: } ! 1500: ! 1501: /* ! 1502: * parse ISAKMP payloads, including ISAKMP base header. ! 1503: */ ! 1504: vchar_t * ! 1505: isakmp_parse(buf) ! 1506: vchar_t *buf; ! 1507: { ! 1508: struct isakmp *isakmp = (struct isakmp *)buf->v; ! 1509: struct isakmp_gen *gen; ! 1510: int tlen; ! 1511: vchar_t *result; ! 1512: u_char np; ! 1513: ! 1514: np = isakmp->np; ! 1515: gen = (struct isakmp_gen *)(buf->v + sizeof(*isakmp)); ! 1516: tlen = buf->l - sizeof(struct isakmp); ! 1517: result = isakmp_parsewoh(np, gen, tlen); ! 1518: ! 1519: return result; ! 1520: } ! 1521: ! 1522: /* %%% */ ! 1523: int ! 1524: isakmp_init() ! 1525: { ! 1526: /* initialize a isakmp status table */ ! 1527: initph1tree(); ! 1528: initph2tree(); ! 1529: initctdtree(); ! 1530: init_recvdpkt(); ! 1531: ! 1532: return 0; ! 1533: } ! 1534: ! 1535: /* ! 1536: * make strings containing i_cookie + r_cookie + msgid ! 1537: */ ! 1538: const char * ! 1539: isakmp_pindex(index, msgid) ! 1540: const isakmp_index *index; ! 1541: const u_int32_t msgid; ! 1542: { ! 1543: static char buf[64]; ! 1544: const u_char *p; ! 1545: int i, j; ! 1546: ! 1547: memset(buf, 0, sizeof(buf)); ! 1548: ! 1549: /* copy index */ ! 1550: p = (const u_char *)index; ! 1551: for (j = 0, i = 0; i < sizeof(isakmp_index); i++) { ! 1552: snprintf((char *)&buf[j], sizeof(buf) - j, "%02x", p[i]); ! 1553: j += 2; ! 1554: switch (i) { ! 1555: case 7: ! 1556: buf[j++] = ':'; ! 1557: } ! 1558: } ! 1559: ! 1560: if (msgid == 0) ! 1561: return buf; ! 1562: ! 1563: /* copy msgid */ ! 1564: snprintf((char *)&buf[j], sizeof(buf) - j, ":%08x", ntohs(msgid)); ! 1565: ! 1566: return buf; ! 1567: } ! 1568: ! 1569: /* open ISAKMP sockets. */ ! 1570: int ! 1571: isakmp_open(struct sockaddr *addr, int udp_encap) ! 1572: { ! 1573: const int yes = 1; ! 1574: int ifnum = 0, encap_ifnum = 0, fd; ! 1575: struct sockaddr_in *sin = (struct sockaddr_in *) addr; ! 1576: #ifdef INET6 ! 1577: struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) addr; ! 1578: int pktinfo; ! 1579: #endif ! 1580: #ifdef ENABLE_NATT ! 1581: int option = -1; ! 1582: #endif ! 1583: ! 1584: /* warn if wildcard address - should we forbid this? */ ! 1585: switch (addr->sa_family) { ! 1586: case AF_INET: ! 1587: if (sin->sin_addr.s_addr == 0) ! 1588: plog(LLV_WARNING, LOCATION, NULL, ! 1589: "listening to wildcard address," ! 1590: "broadcast IKE packet may kill you\n"); ! 1591: break; ! 1592: #ifdef INET6 ! 1593: case AF_INET6: ! 1594: if (IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr)) { ! 1595: plog(LLV_DEBUG, LOCATION, NULL, ! 1596: "ignoring multicast address %s\n", ! 1597: saddr2str(addr)); ! 1598: return -1; ! 1599: } ! 1600: ! 1601: if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) ! 1602: plog(LLV_WARNING, LOCATION, NULL, ! 1603: "listening to wildcard address, " ! 1604: "broadcast IKE packet may kill you\n"); ! 1605: break; ! 1606: #endif ! 1607: default: ! 1608: plog(LLV_ERROR, LOCATION, NULL, ! 1609: "unsupported address family %d\n", ! 1610: addr->sa_family); ! 1611: return -1; ! 1612: } ! 1613: ! 1614: if ((fd = privsep_socket(addr->sa_family, SOCK_DGRAM, 0)) < 0) { ! 1615: plog(LLV_ERROR, LOCATION, NULL, ! 1616: "socket(%s)\n", strerror(errno)); ! 1617: return -1; ! 1618: } ! 1619: close_on_exec(fd); ! 1620: if (fcntl(fd, F_SETFL, O_NONBLOCK) == -1) ! 1621: plog(LLV_WARNING, LOCATION, NULL, ! 1622: "failed to put socket in non-blocking mode\n"); ! 1623: ! 1624: /* receive my interface address on inbound packets. */ ! 1625: switch (addr->sa_family) { ! 1626: case AF_INET: ! 1627: if (setsockopt(fd, IPPROTO_IP, ! 1628: #ifdef __linux__ ! 1629: IP_PKTINFO, ! 1630: #else ! 1631: IP_RECVDSTADDR, ! 1632: #endif ! 1633: (const void *) &yes, sizeof(yes)) < 0) { ! 1634: plog(LLV_ERROR, LOCATION, NULL, ! 1635: "setsockopt IP_RECVDSTADDR (%s)\n", ! 1636: strerror(errno)); ! 1637: goto err; ! 1638: } ! 1639: ! 1640: #ifdef ENABLE_NATT ! 1641: if (udp_encap) ! 1642: option = UDP_ENCAP_ESPINUDP; ! 1643: #if defined(ENABLE_NATT_00) || defined(ENABLE_NATT_01) ! 1644: else ! 1645: option = UDP_ENCAP_ESPINUDP_NON_IKE; ! 1646: #endif ! 1647: if (option == -1) ! 1648: break; ! 1649: ! 1650: if (setsockopt(fd, SOL_UDP, ! 1651: UDP_ENCAP, &option, ! 1652: sizeof(option)) < 0) { ! 1653: plog(LLV_WARNING, LOCATION, NULL, ! 1654: "setsockopt(%s): UDP_ENCAP %s\n", ! 1655: option == UDP_ENCAP_ESPINUDP ? "UDP_ENCAP_ESPINUDP" : "UDP_ENCAP_ESPINUDP_NON_IKE", ! 1656: strerror(errno)); ! 1657: } else { ! 1658: plog(LLV_INFO, LOCATION, NULL, ! 1659: "%s used for NAT-T\n", ! 1660: saddr2str(addr)); ! 1661: } ! 1662: #endif ! 1663: break; ! 1664: ! 1665: #ifdef INET6 ! 1666: case AF_INET6: ! 1667: #if defined(INET6_ADVAPI) ! 1668: #ifdef IPV6_RECVPKTINFO ! 1669: pktinfo = IPV6_RECVPKTINFO; ! 1670: #else /* old adv. API */ ! 1671: pktinfo = IPV6_PKTINFO; ! 1672: #endif /* IPV6_RECVPKTINFO */ ! 1673: #else ! 1674: pktinfo = IPV6_RECVDSTADDR; ! 1675: #endif ! 1676: if (setsockopt(fd, IPPROTO_IPV6, pktinfo, ! 1677: (const void *) &yes, sizeof(yes)) < 0) { ! 1678: plog(LLV_ERROR, LOCATION, NULL, ! 1679: "setsockopt IPV6_RECVDSTADDR (%d):%s\n", ! 1680: pktinfo, strerror(errno)); ! 1681: goto err; ! 1682: } ! 1683: ! 1684: #ifdef IPV6_USE_MIN_MTU ! 1685: if (setsockopt(fd, IPPROTO_IPV6, IPV6_USE_MIN_MTU, ! 1686: (void *) &yes, sizeof(yes)) < 0) { ! 1687: plog(LLV_ERROR, LOCATION, NULL, ! 1688: "setsockopt IPV6_USE_MIN_MTU (%s)\n", ! 1689: strerror(errno)); ! 1690: goto err; ! 1691: } ! 1692: #endif ! 1693: break; ! 1694: #endif ! 1695: } ! 1696: ! 1697: if (setsockopt(fd, SOL_SOCKET, ! 1698: #ifdef __linux__ ! 1699: SO_REUSEADDR, ! 1700: #else ! 1701: SO_REUSEPORT, ! 1702: #endif ! 1703: (void *) &yes, sizeof(yes)) < 0) { ! 1704: plog(LLV_ERROR, LOCATION, NULL, ! 1705: "failed to set REUSE flag on %s (%s).\n", ! 1706: saddr2str(addr), strerror(errno)); ! 1707: goto err; ! 1708: } ! 1709: ! 1710: if (setsockopt_bypass(fd, addr->sa_family) < 0) ! 1711: goto err; ! 1712: ! 1713: if (privsep_bind(fd, addr, sysdep_sa_len(addr)) < 0) { ! 1714: plog(LLV_ERROR, LOCATION, addr, ! 1715: "failed to bind to address %s (%s).\n", ! 1716: saddr2str(addr), strerror(errno)); ! 1717: goto err; ! 1718: } ! 1719: ! 1720: plog(LLV_INFO, LOCATION, NULL, ! 1721: "%s used as isakmp port (fd=%d)\n", ! 1722: saddr2str(addr), fd); ! 1723: ! 1724: monitor_fd(fd, isakmp_handler, NULL, 1); ! 1725: return fd; ! 1726: ! 1727: err: ! 1728: close(fd); ! 1729: return -1; ! 1730: } ! 1731: ! 1732: void ! 1733: isakmp_close(int fd) ! 1734: { ! 1735: unmonitor_fd(fd); ! 1736: close(fd); ! 1737: } ! 1738: ! 1739: int ! 1740: isakmp_send(iph1, sbuf) ! 1741: struct ph1handle *iph1; ! 1742: vchar_t *sbuf; ! 1743: { ! 1744: int len = 0; ! 1745: int s; ! 1746: vchar_t *vbuf = NULL, swap; ! 1747: ! 1748: #ifdef ENABLE_NATT ! 1749: size_t extralen = NON_ESP_MARKER_USE(iph1) ? NON_ESP_MARKER_LEN : 0; ! 1750: ! 1751: /* Check if NON_ESP_MARKER_LEN is already there (happens when resending packets) ! 1752: */ ! 1753: if(extralen == NON_ESP_MARKER_LEN && ! 1754: *(u_int32_t *)sbuf->v == 0) ! 1755: extralen = 0; ! 1756: ! 1757: #ifdef ENABLE_FRAG ! 1758: /* ! 1759: * Do not add the non ESP marker for a packet that will ! 1760: * be fragmented. The non ESP marker should appear in ! 1761: * all fragment's packets, but not in the fragmented packet ! 1762: */ ! 1763: if (iph1->frag && sbuf->l > ISAKMP_FRAG_MAXLEN) ! 1764: extralen = 0; ! 1765: #endif ! 1766: if (extralen) ! 1767: plog (LLV_DEBUG, LOCATION, NULL, "Adding NON-ESP marker\n"); ! 1768: ! 1769: /* If NAT-T port floating is in use, 4 zero bytes (non-ESP marker) ! 1770: must added just before the packet itself. For this we must ! 1771: allocate a new buffer and release it at the end. */ ! 1772: if (extralen) { ! 1773: if ((vbuf = vmalloc (sbuf->l + extralen)) == NULL) { ! 1774: plog(LLV_ERROR, LOCATION, NULL, ! 1775: "vbuf allocation failed\n"); ! 1776: return -1; ! 1777: } ! 1778: *(u_int32_t *)vbuf->v = 0; ! 1779: memcpy (vbuf->v + extralen, sbuf->v, sbuf->l); ! 1780: /* ensures that the modified buffer will be sent back to the caller, so ! 1781: * add_recvdpkt() will add the correct buffer ! 1782: */ ! 1783: swap = *sbuf; ! 1784: *sbuf = *vbuf; ! 1785: *vbuf = swap; ! 1786: vfree(vbuf); ! 1787: } ! 1788: #endif ! 1789: ! 1790: /* select the socket to be sent */ ! 1791: s = myaddr_getfd(iph1->local); ! 1792: if (s == -1) ! 1793: return -1; ! 1794: ! 1795: plog (LLV_DEBUG, LOCATION, NULL, "%zu bytes %s\n", sbuf->l, ! 1796: saddr2str_fromto("from %s to %s", iph1->local, iph1->remote)); ! 1797: ! 1798: #ifdef ENABLE_FRAG ! 1799: if (iph1->frag && sbuf->l > ISAKMP_FRAG_MAXLEN) { ! 1800: if (isakmp_sendfrags(iph1, sbuf) == -1) { ! 1801: plog(LLV_ERROR, LOCATION, NULL, ! 1802: "isakmp_sendfrags failed\n"); ! 1803: return -1; ! 1804: } ! 1805: } else ! 1806: #endif ! 1807: { ! 1808: len = sendfromto(s, sbuf->v, sbuf->l, ! 1809: iph1->local, iph1->remote, lcconf->count_persend); ! 1810: ! 1811: if (len == -1) { ! 1812: plog(LLV_ERROR, LOCATION, NULL, "sendfromto failed\n"); ! 1813: return -1; ! 1814: } ! 1815: } ! 1816: ! 1817: return 0; ! 1818: } ! 1819: ! 1820: /* called from scheduler */ ! 1821: static void ! 1822: isakmp_ph1resend_stub(p) ! 1823: struct sched *p; ! 1824: { ! 1825: struct ph1handle *iph1 = container_of(p, struct ph1handle, scr); ! 1826: ! 1827: if (isakmp_ph1resend(iph1) < 0) { ! 1828: remph1(iph1); ! 1829: delph1(iph1); ! 1830: } ! 1831: } ! 1832: ! 1833: static int ! 1834: isakmp_ph1resend(iph1) ! 1835: struct ph1handle *iph1; ! 1836: { ! 1837: /* Note: NEVER do the rem/del here, it will be done by the caller or by the _stub function ! 1838: */ ! 1839: if (iph1->retry_counter <= 0) { ! 1840: plog(LLV_ERROR, LOCATION, NULL, ! 1841: "phase1 negotiation failed due to time up. %s\n", ! 1842: isakmp_pindex(&iph1->index, iph1->msgid)); ! 1843: /* XXX is the peer really "dead" here ??? */ ! 1844: script_hook(iph1, SCRIPT_PHASE1_DEAD); ! 1845: evt_phase1(iph1, EVT_PHASE1_NO_RESPONSE, NULL); ! 1846: ! 1847: return -1; ! 1848: } ! 1849: ! 1850: if (isakmp_send(iph1, iph1->sendbuf) < 0){ ! 1851: plog(LLV_ERROR, LOCATION, NULL, ! 1852: "phase1 negotiation failed due to send error. %s\n", ! 1853: isakmp_pindex(&iph1->index, iph1->msgid)); ! 1854: evt_phase1(iph1, EVT_PHASE1_NO_RESPONSE, NULL); ! 1855: return -1; ! 1856: } ! 1857: ! 1858: plog(LLV_DEBUG, LOCATION, NULL, ! 1859: "resend phase1 packet %s\n", ! 1860: isakmp_pindex(&iph1->index, iph1->msgid)); ! 1861: ! 1862: iph1->retry_counter--; ! 1863: ! 1864: sched_schedule(&iph1->scr, lcconf->retry_interval, ! 1865: isakmp_ph1resend_stub); ! 1866: ! 1867: return 0; ! 1868: } ! 1869: ! 1870: int ! 1871: isakmp_ph1send(iph1) ! 1872: struct ph1handle *iph1; ! 1873: { ! 1874: iph1->retry_counter = lcconf->retry_counter; ! 1875: return isakmp_ph1resend(iph1); ! 1876: } ! 1877: ! 1878: /* called from scheduler */ ! 1879: static void ! 1880: isakmp_ph2resend_stub(p) ! 1881: struct sched *p; ! 1882: { ! 1883: struct ph2handle *iph2 = container_of(p, struct ph2handle, scr); ! 1884: ! 1885: if (isakmp_ph2resend(iph2) < 0) { ! 1886: remph2(iph2); ! 1887: delph2(iph2); ! 1888: } ! 1889: } ! 1890: ! 1891: static int ! 1892: isakmp_ph2resend(iph2) ! 1893: struct ph2handle *iph2; ! 1894: { ! 1895: /* Note: NEVER do the unbind/rem/del here, it will be done by the caller or by the _stub function ! 1896: */ ! 1897: if (iph2->ph1->status >= PHASE1ST_EXPIRED) { ! 1898: plog(LLV_ERROR, LOCATION, NULL, ! 1899: "phase2 negotiation failed due to phase1 expired. %s\n", ! 1900: isakmp_pindex(&iph2->ph1->index, iph2->msgid)); ! 1901: return -1; ! 1902: } ! 1903: ! 1904: if (iph2->retry_counter <= 0) { ! 1905: plog(LLV_ERROR, LOCATION, NULL, ! 1906: "phase2 negotiation failed due to time up. %s\n", ! 1907: isakmp_pindex(&iph2->ph1->index, iph2->msgid)); ! 1908: evt_phase2(iph2, EVT_PHASE2_NO_RESPONSE, NULL); ! 1909: unbindph12(iph2); ! 1910: return -1; ! 1911: } ! 1912: ! 1913: if (isakmp_send(iph2->ph1, iph2->sendbuf) < 0){ ! 1914: plog(LLV_ERROR, LOCATION, NULL, ! 1915: "phase2 negotiation failed due to send error. %s\n", ! 1916: isakmp_pindex(&iph2->ph1->index, iph2->msgid)); ! 1917: evt_phase2(iph2, EVT_PHASE2_NO_RESPONSE, NULL); ! 1918: return -1; ! 1919: } ! 1920: ! 1921: plog(LLV_DEBUG, LOCATION, NULL, ! 1922: "resend phase2 packet %s\n", ! 1923: isakmp_pindex(&iph2->ph1->index, iph2->msgid)); ! 1924: ! 1925: iph2->retry_counter--; ! 1926: ! 1927: sched_schedule(&iph2->scr, lcconf->retry_interval, ! 1928: isakmp_ph2resend_stub); ! 1929: ! 1930: return 0; ! 1931: } ! 1932: ! 1933: int ! 1934: isakmp_ph2send(iph2) ! 1935: struct ph2handle *iph2; ! 1936: { ! 1937: iph2->retry_counter = lcconf->retry_counter; ! 1938: return isakmp_ph2resend(iph2); ! 1939: } ! 1940: ! 1941: /* called from scheduler */ ! 1942: void ! 1943: isakmp_ph1dying_stub(p) ! 1944: struct sched *p; ! 1945: { ! 1946: ! 1947: isakmp_ph1dying(container_of(p, struct ph1handle, sce)); ! 1948: } ! 1949: ! 1950: void ! 1951: isakmp_ph1dying(iph1) ! 1952: struct ph1handle *iph1; ! 1953: { ! 1954: struct ph1handle *new_iph1; ! 1955: struct ph2handle *p; ! 1956: struct remoteconf *rmconf; ! 1957: ! 1958: if (iph1->status >= PHASE1ST_DYING) ! 1959: return; ! 1960: ! 1961: /* Going away in after a while... */ ! 1962: iph1->status = PHASE1ST_DYING; ! 1963: ! 1964: /* Any fresh phase1s? */ ! 1965: new_iph1 = getph1(iph1, iph1->local, iph1->remote, 1); ! 1966: if (new_iph1 == NULL) { ! 1967: LIST_FOREACH(p, &iph1->ph2tree, ph1bind) { ! 1968: if (p->status != PHASE2ST_ESTABLISHED) ! 1969: continue; ! 1970: ! 1971: plog(LLV_INFO, LOCATION, NULL, ! 1972: "renegotiating phase1 to %s due to " ! 1973: "active phase2\n", ! 1974: saddrwop2str(iph1->remote)); ! 1975: ! 1976: if (iph1->side == INITIATOR) ! 1977: isakmp_ph1begin_i(iph1->rmconf, iph1->remote, ! 1978: iph1->local); ! 1979: ! 1980: break; ! 1981: } ! 1982: } else { ! 1983: migrate_ph12(iph1, new_iph1); ! 1984: } ! 1985: ! 1986: /* Schedule for expiration */ ! 1987: sched_schedule(&iph1->sce, iph1->approval->lifetime * ! 1988: (100 - PFKEY_SOFT_LIFETIME_RATE) / 100, ! 1989: isakmp_ph1expire_stub); ! 1990: } ! 1991: ! 1992: /* called from scheduler */ ! 1993: void ! 1994: isakmp_ph1expire_stub(p) ! 1995: struct sched *p; ! 1996: { ! 1997: isakmp_ph1expire(container_of(p, struct ph1handle, sce)); ! 1998: } ! 1999: ! 2000: void ! 2001: isakmp_ph1expire(iph1) ! 2002: struct ph1handle *iph1; ! 2003: { ! 2004: char *src, *dst; ! 2005: ! 2006: if (iph1->status < PHASE1ST_EXPIRED) { ! 2007: src = racoon_strdup(saddr2str(iph1->local)); ! 2008: dst = racoon_strdup(saddr2str(iph1->remote)); ! 2009: STRDUP_FATAL(src); ! 2010: STRDUP_FATAL(dst); ! 2011: ! 2012: plog(LLV_INFO, LOCATION, NULL, ! 2013: "ISAKMP-SA expired %s-%s spi:%s\n", ! 2014: src, dst, ! 2015: isakmp_pindex(&iph1->index, 0)); ! 2016: racoon_free(src); ! 2017: racoon_free(dst); ! 2018: iph1->status = PHASE1ST_EXPIRED; ! 2019: } ! 2020: ! 2021: isakmp_ph1delete(iph1); ! 2022: } ! 2023: ! 2024: /* called from scheduler */ ! 2025: void ! 2026: isakmp_ph1delete_stub(p) ! 2027: struct sched *p; ! 2028: { ! 2029: ! 2030: isakmp_ph1delete(container_of(p, struct ph1handle, sce)); ! 2031: } ! 2032: ! 2033: void ! 2034: isakmp_ph1delete(iph1) ! 2035: struct ph1handle *iph1; ! 2036: { ! 2037: struct ph2handle *p, *next; ! 2038: struct ph1handle *new_iph1; ! 2039: char *src, *dst; ! 2040: ! 2041: /* Migrate established phase2s. Any fresh phase1s? */ ! 2042: new_iph1 = getph1(iph1, iph1->local, iph1->remote, 1); ! 2043: if (new_iph1 != NULL) ! 2044: migrate_ph12(iph1, new_iph1); ! 2045: ! 2046: /* Discard any left phase2s */ ! 2047: for (p = LIST_FIRST(&iph1->ph2tree); p; p = next) { ! 2048: next = LIST_NEXT(p, ph1bind); ! 2049: if (p->status == PHASE2ST_ESTABLISHED) ! 2050: isakmp_info_send_d2(p); ! 2051: /* remove all ph2 handles, ! 2052: * as ph1handle will be expired soon ! 2053: */ ! 2054: delete_spd(p, 1); ! 2055: remph2(p); ! 2056: delph2(p); ! 2057: } ! 2058: ! 2059: src = racoon_strdup(saddr2str(iph1->local)); ! 2060: dst = racoon_strdup(saddr2str(iph1->remote)); ! 2061: STRDUP_FATAL(src); ! 2062: STRDUP_FATAL(dst); ! 2063: ! 2064: plog(LLV_INFO, LOCATION, NULL, ! 2065: "ISAKMP-SA deleted %s-%s spi:%s\n", ! 2066: src, dst, isakmp_pindex(&iph1->index, 0)); ! 2067: ! 2068: evt_phase1(iph1, EVT_PHASE1_DOWN, NULL); ! 2069: if (new_iph1 == NULL && ph1_rekey_enabled(iph1)) ! 2070: script_hook(iph1, SCRIPT_PHASE1_DEAD); ! 2071: ! 2072: racoon_free(src); ! 2073: racoon_free(dst); ! 2074: ! 2075: remph1(iph1); ! 2076: delph1(iph1); ! 2077: } ! 2078: ! 2079: /* called from scheduler. ! 2080: * this function will call only isakmp_ph2delete(). ! 2081: * phase 2 handler remain forever if kernel doesn't cry a expire of phase 2 SA ! 2082: * by something cause. That's why this function is called after phase 2 SA ! 2083: * expires in the userland. ! 2084: */ ! 2085: void ! 2086: isakmp_ph2expire_stub(p) ! 2087: struct sched *p; ! 2088: { ! 2089: ! 2090: isakmp_ph2expire(container_of(p, struct ph2handle, sce)); ! 2091: } ! 2092: ! 2093: void ! 2094: isakmp_ph2expire(iph2) ! 2095: struct ph2handle *iph2; ! 2096: { ! 2097: char *src, *dst; ! 2098: ! 2099: src = racoon_strdup(saddrwop2str(iph2->src)); ! 2100: dst = racoon_strdup(saddrwop2str(iph2->dst)); ! 2101: STRDUP_FATAL(src); ! 2102: STRDUP_FATAL(dst); ! 2103: ! 2104: plog(LLV_INFO, LOCATION, NULL, ! 2105: "phase2 sa expired %s-%s\n", src, dst); ! 2106: racoon_free(src); ! 2107: racoon_free(dst); ! 2108: ! 2109: iph2->status = PHASE2ST_EXPIRED; ! 2110: sched_schedule(&iph2->sce, 1, isakmp_ph2delete_stub); ! 2111: } ! 2112: ! 2113: /* called from scheduler */ ! 2114: void ! 2115: isakmp_ph2delete_stub(p) ! 2116: struct sched *p; ! 2117: { ! 2118: ! 2119: isakmp_ph2delete(container_of(p, struct ph2handle, sce)); ! 2120: } ! 2121: ! 2122: void ! 2123: isakmp_ph2delete(iph2) ! 2124: struct ph2handle *iph2; ! 2125: { ! 2126: char *src, *dst; ! 2127: ! 2128: src = racoon_strdup(saddrwop2str(iph2->src)); ! 2129: dst = racoon_strdup(saddrwop2str(iph2->dst)); ! 2130: STRDUP_FATAL(src); ! 2131: STRDUP_FATAL(dst); ! 2132: ! 2133: plog(LLV_INFO, LOCATION, NULL, ! 2134: "phase2 sa deleted %s-%s\n", src, dst); ! 2135: racoon_free(src); ! 2136: racoon_free(dst); ! 2137: ! 2138: remph2(iph2); ! 2139: delph2(iph2); ! 2140: ! 2141: return; ! 2142: } ! 2143: ! 2144: /* %%% ! 2145: * Interface between PF_KEYv2 and ISAKMP ! 2146: */ ! 2147: /* ! 2148: * receive ACQUIRE from kernel, and begin either phase1 or phase2. ! 2149: * if phase1 has been finished, begin phase2. ! 2150: */ ! 2151: int ! 2152: isakmp_post_acquire(iph2, iph1hint, nopassive) ! 2153: struct ph2handle *iph2; ! 2154: struct ph1handle *iph1hint; ! 2155: int nopassive; ! 2156: { ! 2157: struct remoteconf *rmconf; ! 2158: struct ph1handle *iph1 = NULL; ! 2159: ! 2160: plog(LLV_DEBUG, LOCATION, NULL, "in post_acquire\n"); ! 2161: ! 2162: /* Search appropriate configuration with masking port. Note that ! 2163: * we always use iph2->dst, and not iph2->sa_dst. ! 2164: * ! 2165: * XXX One possible need for using iph2->sa_dst if not NULL would ! 2166: * be for selecting a remote configuration based on a stable ! 2167: * address of a mobile node (not a CoA provided by MIGRATE/KMADDRESS ! 2168: * as iph2->dst hint). This scenario would require additional changes, ! 2169: * so no need to bother yet. --arno */ ! 2170: ! 2171: if (iph1hint == NULL || iph1hint->rmconf == NULL) { ! 2172: rmconf = getrmconf(iph2->dst, nopassive ? GETRMCONF_F_NO_PASSIVE : 0); ! 2173: if (rmconf == NULL) { ! 2174: plog(LLV_ERROR, LOCATION, NULL, ! 2175: "no configuration found for %s.\n", ! 2176: saddrwop2str(iph2->dst)); ! 2177: return -1; ! 2178: } ! 2179: } else { ! 2180: rmconf = iph1hint->rmconf; ! 2181: } ! 2182: ! 2183: /* if passive mode, ignore the acquire message */ ! 2184: if (nopassive && rmconf->passive) { ! 2185: plog(LLV_DEBUG, LOCATION, NULL, ! 2186: "because of passive mode, " ! 2187: "ignore the acquire message for %s.\n", ! 2188: saddrwop2str(iph2->dst)); ! 2189: return 0; ! 2190: } ! 2191: ! 2192: /* ! 2193: * XXX Searching by IP addresses + ports might fail on ! 2194: * some cases, we should use the ISAKMP identity to search ! 2195: * matching ISAKMP. ! 2196: */ ! 2197: iph1 = getph1(iph1hint, iph2->src, iph2->dst, 0); ! 2198: ! 2199: /* no ISAKMP-SA found. */ ! 2200: if (iph1 == NULL) { ! 2201: iph2->retry_checkph1 = lcconf->retry_checkph1; ! 2202: sched_schedule(&iph2->sce, 1, isakmp_chkph1there_stub); ! 2203: plog(LLV_INFO, LOCATION, NULL, ! 2204: "IPsec-SA request for %s queued " ! 2205: "due to no phase1 found.\n", ! 2206: saddrwop2str(iph2->dst)); ! 2207: ! 2208: /* start phase 1 negotiation as a initiator. */ ! 2209: if (isakmp_ph1begin_i(rmconf, iph2->dst, iph2->src) == NULL) { ! 2210: sched_cancel(&iph2->sce); ! 2211: return -1; ! 2212: } ! 2213: ! 2214: return 0; ! 2215: /*NOTREACHED*/ ! 2216: } ! 2217: ! 2218: /* found ISAKMP-SA, but on negotiation. */ ! 2219: if (iph1->status < PHASE1ST_ESTABLISHED) { ! 2220: iph2->retry_checkph1 = lcconf->retry_checkph1; ! 2221: sched_schedule(&iph2->sce, 1, isakmp_chkph1there_stub); ! 2222: plog(LLV_INFO, LOCATION, iph2->dst, ! 2223: "request for establishing IPsec-SA was queued " ! 2224: "due to no phase1 found.\n"); ! 2225: return 0; ! 2226: /*NOTREACHED*/ ! 2227: } ! 2228: ! 2229: /* found established ISAKMP-SA */ ! 2230: /* i.e. iph1->status == PHASE1ST_ESTABLISHED */ ! 2231: ! 2232: /* found ISAKMP-SA. */ ! 2233: plog(LLV_DEBUG, LOCATION, NULL, "begin QUICK mode.\n"); ! 2234: ! 2235: /* begin quick mode */ ! 2236: if (isakmp_ph2begin_i(iph1, iph2)) ! 2237: return -1; ! 2238: ! 2239: return 0; ! 2240: } ! 2241: ! 2242: int ! 2243: isakmp_get_sainfo(iph2, sp_out, sp_in) ! 2244: struct ph2handle *iph2; ! 2245: struct secpolicy *sp_out, *sp_in; ! 2246: { ! 2247: struct remoteconf *conf; ! 2248: uint32_t remoteid = 0; ! 2249: ! 2250: plog(LLV_DEBUG, LOCATION, NULL, ! 2251: "new acquire %s\n", spidx2str(&sp_out->spidx)); ! 2252: ! 2253: /* get sainfo */ ! 2254: { ! 2255: vchar_t *idsrc, *iddst; ! 2256: ! 2257: idsrc = ipsecdoi_sockaddr2id((struct sockaddr *)&sp_out->spidx.src, ! 2258: sp_out->spidx.prefs, sp_out->spidx.ul_proto); ! 2259: if (idsrc == NULL) { ! 2260: plog(LLV_ERROR, LOCATION, NULL, ! 2261: "failed to get ID for %s\n", ! 2262: spidx2str(&sp_out->spidx)); ! 2263: return -1; ! 2264: } ! 2265: iddst = ipsecdoi_sockaddr2id((struct sockaddr *)&sp_out->spidx.dst, ! 2266: sp_out->spidx.prefd, sp_out->spidx.ul_proto); ! 2267: if (iddst == NULL) { ! 2268: plog(LLV_ERROR, LOCATION, NULL, ! 2269: "failed to get ID for %s\n", ! 2270: spidx2str(&sp_out->spidx)); ! 2271: vfree(idsrc); ! 2272: return -1; ! 2273: } ! 2274: ! 2275: conf = getrmconf(iph2->dst, 0); ! 2276: if (conf != NULL) ! 2277: remoteid = conf->ph1id; ! 2278: else ! 2279: plog(LLV_DEBUG, LOCATION, NULL, "Warning: no valid rmconf !\n"); ! 2280: ! 2281: iph2->sainfo = getsainfo(idsrc, iddst, NULL, NULL, remoteid); ! 2282: vfree(idsrc); ! 2283: vfree(iddst); ! 2284: if (iph2->sainfo == NULL) { ! 2285: plog(LLV_ERROR, LOCATION, NULL, ! 2286: "failed to get sainfo.\n"); ! 2287: return -1; ! 2288: /* XXX should use the algorithm list from register message */ ! 2289: } ! 2290: ! 2291: plog(LLV_DEBUG, LOCATION, NULL, ! 2292: "selected sainfo: %s\n", sainfo2str(iph2->sainfo)); ! 2293: } ! 2294: ! 2295: if (set_proposal_from_policy(iph2, sp_out, sp_in) < 0) { ! 2296: plog(LLV_ERROR, LOCATION, NULL, ! 2297: "failed to create saprop.\n"); ! 2298: return -1; ! 2299: } ! 2300: ! 2301: return 0; ! 2302: } ! 2303: ! 2304: ! 2305: /* ! 2306: * receive GETSPI from kernel. ! 2307: */ ! 2308: int ! 2309: isakmp_post_getspi(iph2) ! 2310: struct ph2handle *iph2; ! 2311: { ! 2312: #ifdef ENABLE_STATS ! 2313: struct timeval start, end; ! 2314: #endif ! 2315: ! 2316: /* don't process it because there is no suitable phase1-sa. */ ! 2317: if (iph2->ph1->status >= PHASE1ST_EXPIRED) { ! 2318: plog(LLV_ERROR, LOCATION, iph2->ph1->remote, ! 2319: "the negotiation is stopped, " ! 2320: "because there is no suitable ISAKMP-SA.\n"); ! 2321: return -1; ! 2322: } ! 2323: ! 2324: #ifdef ENABLE_STATS ! 2325: gettimeofday(&start, NULL); ! 2326: #endif ! 2327: if ((ph2exchange[etypesw2(ISAKMP_ETYPE_QUICK)] ! 2328: [iph2->side] ! 2329: [iph2->status])(iph2, NULL) != 0) ! 2330: return -1; ! 2331: #ifdef ENABLE_STATS ! 2332: gettimeofday(&end, NULL); ! 2333: syslog(LOG_NOTICE, "%s(%s): %8.6f", ! 2334: "phase2", ! 2335: s_isakmp_state(ISAKMP_ETYPE_QUICK, iph2->side, iph2->status), ! 2336: timedelta(&start, &end)); ! 2337: #endif ! 2338: ! 2339: return 0; ! 2340: } ! 2341: ! 2342: /* called by scheduler */ ! 2343: void ! 2344: isakmp_chkph1there_stub(p) ! 2345: struct sched *p; ! 2346: { ! 2347: isakmp_chkph1there(container_of(p, struct ph2handle, sce)); ! 2348: } ! 2349: ! 2350: void ! 2351: isakmp_chkph1there(iph2) ! 2352: struct ph2handle *iph2; ! 2353: { ! 2354: struct ph1handle *iph1; ! 2355: ! 2356: iph2->retry_checkph1--; ! 2357: if (iph2->retry_checkph1 < 0) { ! 2358: plog(LLV_ERROR, LOCATION, iph2->dst, ! 2359: "phase2 negotiation failed " ! 2360: "due to time up waiting for phase1. %s\n", ! 2361: sadbsecas2str(iph2->dst, iph2->src, ! 2362: iph2->satype, 0, 0)); ! 2363: plog(LLV_INFO, LOCATION, NULL, ! 2364: "delete phase 2 handler.\n"); ! 2365: ! 2366: /* send acquire to kernel as error */ ! 2367: pk_sendeacquire(iph2); ! 2368: ! 2369: remph2(iph2); ! 2370: delph2(iph2); ! 2371: ! 2372: return; ! 2373: } ! 2374: ! 2375: /* Search isakmp status table by address and port */ ! 2376: iph1 = getph1byaddr(iph2->src, iph2->dst, 0); ! 2377: ! 2378: /* XXX Even if ph1 as responder is there, should we not start ! 2379: * phase 2 negotiation ? */ ! 2380: if (iph1 != NULL ! 2381: && iph1->status == PHASE1ST_ESTABLISHED) { ! 2382: /* found isakmp-sa */ ! 2383: ! 2384: plog(LLV_DEBUG2, LOCATION, NULL, "CHKPH1THERE: got a ph1 handler, setting ports.\n"); ! 2385: plog(LLV_DEBUG2, LOCATION, NULL, "iph1->local: %s\n", saddr2str(iph1->local)); ! 2386: plog(LLV_DEBUG2, LOCATION, NULL, "iph1->remote: %s\n", saddr2str(iph1->remote)); ! 2387: plog(LLV_DEBUG2, LOCATION, NULL, "before:\n"); ! 2388: plog(LLV_DEBUG2, LOCATION, NULL, "src: %s\n", saddr2str(iph2->src)); ! 2389: plog(LLV_DEBUG2, LOCATION, NULL, "dst: %s\n", saddr2str(iph2->dst)); ! 2390: set_port(iph2->src, extract_port(iph1->local)); ! 2391: set_port(iph2->dst, extract_port(iph1->remote)); ! 2392: plog(LLV_DEBUG2, LOCATION, NULL, "After:\n"); ! 2393: plog(LLV_DEBUG2, LOCATION, NULL, "src: %s\n", saddr2str(iph2->src)); ! 2394: plog(LLV_DEBUG2, LOCATION, NULL, "dst: %s\n", saddr2str(iph2->dst)); ! 2395: ! 2396: /* begin quick mode */ ! 2397: (void)isakmp_ph2begin_i(iph1, iph2); ! 2398: return; ! 2399: } ! 2400: ! 2401: plog(LLV_DEBUG2, LOCATION, NULL, "CHKPH1THERE: no established ph1 handler found\n"); ! 2402: ! 2403: /* no isakmp-sa found */ ! 2404: sched_schedule(&iph2->sce, 1, isakmp_chkph1there_stub); ! 2405: ! 2406: return; ! 2407: } ! 2408: ! 2409: /* copy variable data into ALLOCATED buffer. */ ! 2410: caddr_t ! 2411: isakmp_set_attr_v(buf, type, val, len) ! 2412: caddr_t buf; ! 2413: int type; ! 2414: caddr_t val; ! 2415: int len; ! 2416: { ! 2417: struct isakmp_data *data; ! 2418: ! 2419: data = (struct isakmp_data *)buf; ! 2420: data->type = htons((u_int16_t)type | ISAKMP_GEN_TLV); ! 2421: data->lorv = htons((u_int16_t)len); ! 2422: memcpy(data + 1, val, len); ! 2423: ! 2424: return buf + sizeof(*data) + len; ! 2425: } ! 2426: ! 2427: /* copy fixed length data into ALLOCATED buffer. */ ! 2428: caddr_t ! 2429: isakmp_set_attr_l(buf, type, val) ! 2430: caddr_t buf; ! 2431: int type; ! 2432: u_int32_t val; ! 2433: { ! 2434: struct isakmp_data *data; ! 2435: ! 2436: data = (struct isakmp_data *)buf; ! 2437: data->type = htons((u_int16_t)type | ISAKMP_GEN_TV); ! 2438: data->lorv = htons((u_int16_t)val); ! 2439: ! 2440: return buf + sizeof(*data); ! 2441: } ! 2442: ! 2443: /* add a variable data attribute to the buffer by reallocating it. */ ! 2444: vchar_t * ! 2445: isakmp_add_attr_v(buf0, type, val, len) ! 2446: vchar_t *buf0; ! 2447: int type; ! 2448: caddr_t val; ! 2449: int len; ! 2450: { ! 2451: vchar_t *buf = NULL; ! 2452: struct isakmp_data *data; ! 2453: int tlen; ! 2454: int oldlen = 0; ! 2455: ! 2456: tlen = sizeof(*data) + len; ! 2457: ! 2458: if (buf0) { ! 2459: oldlen = buf0->l; ! 2460: buf = vrealloc(buf0, oldlen + tlen); ! 2461: } else ! 2462: buf = vmalloc(tlen); ! 2463: if (!buf) { ! 2464: plog(LLV_ERROR, LOCATION, NULL, ! 2465: "failed to get a attribute buffer.\n"); ! 2466: return NULL; ! 2467: } ! 2468: ! 2469: data = (struct isakmp_data *)(buf->v + oldlen); ! 2470: data->type = htons((u_int16_t)type | ISAKMP_GEN_TLV); ! 2471: data->lorv = htons((u_int16_t)len); ! 2472: memcpy(data + 1, val, len); ! 2473: ! 2474: return buf; ! 2475: } ! 2476: ! 2477: /* add a fixed data attribute to the buffer by reallocating it. */ ! 2478: vchar_t * ! 2479: isakmp_add_attr_l(buf0, type, val) ! 2480: vchar_t *buf0; ! 2481: int type; ! 2482: u_int32_t val; ! 2483: { ! 2484: vchar_t *buf = NULL; ! 2485: struct isakmp_data *data; ! 2486: int tlen; ! 2487: int oldlen = 0; ! 2488: ! 2489: tlen = sizeof(*data); ! 2490: ! 2491: if (buf0) { ! 2492: oldlen = buf0->l; ! 2493: buf = vrealloc(buf0, oldlen + tlen); ! 2494: } else ! 2495: buf = vmalloc(tlen); ! 2496: if (!buf) { ! 2497: plog(LLV_ERROR, LOCATION, NULL, ! 2498: "failed to get a attribute buffer.\n"); ! 2499: return NULL; ! 2500: } ! 2501: ! 2502: data = (struct isakmp_data *)(buf->v + oldlen); ! 2503: data->type = htons((u_int16_t)type | ISAKMP_GEN_TV); ! 2504: data->lorv = htons((u_int16_t)val); ! 2505: ! 2506: return buf; ! 2507: } ! 2508: ! 2509: /* ! 2510: * calculate cookie and set. ! 2511: */ ! 2512: int ! 2513: isakmp_newcookie(place, remote, local) ! 2514: caddr_t place; ! 2515: struct sockaddr *remote; ! 2516: struct sockaddr *local; ! 2517: { ! 2518: vchar_t *buf = NULL, *buf2 = NULL; ! 2519: char *p; ! 2520: int blen; ! 2521: int alen; ! 2522: caddr_t sa1, sa2; ! 2523: time_t t; ! 2524: int error = -1; ! 2525: u_short port; ! 2526: ! 2527: ! 2528: if (remote->sa_family != local->sa_family) { ! 2529: plog(LLV_ERROR, LOCATION, NULL, ! 2530: "address family mismatch, remote:%d local:%d\n", ! 2531: remote->sa_family, local->sa_family); ! 2532: goto end; ! 2533: } ! 2534: switch (remote->sa_family) { ! 2535: case AF_INET: ! 2536: alen = sizeof(struct in_addr); ! 2537: sa1 = (caddr_t)&((struct sockaddr_in *)remote)->sin_addr; ! 2538: sa2 = (caddr_t)&((struct sockaddr_in *)local)->sin_addr; ! 2539: break; ! 2540: #ifdef INET6 ! 2541: case AF_INET6: ! 2542: alen = sizeof(struct in6_addr); ! 2543: sa1 = (caddr_t)&((struct sockaddr_in6 *)remote)->sin6_addr; ! 2544: sa2 = (caddr_t)&((struct sockaddr_in6 *)local)->sin6_addr; ! 2545: break; ! 2546: #endif ! 2547: default: ! 2548: plog(LLV_ERROR, LOCATION, NULL, ! 2549: "invalid family: %d\n", remote->sa_family); ! 2550: goto end; ! 2551: } ! 2552: blen = (alen + sizeof(u_short)) * 2 ! 2553: + sizeof(time_t) + lcconf->secret_size; ! 2554: buf = vmalloc(blen); ! 2555: if (buf == NULL) { ! 2556: plog(LLV_ERROR, LOCATION, NULL, ! 2557: "failed to get a cookie.\n"); ! 2558: goto end; ! 2559: } ! 2560: p = buf->v; ! 2561: ! 2562: /* copy my address */ ! 2563: memcpy(p, sa1, alen); ! 2564: p += alen; ! 2565: port = ((struct sockaddr_in *)remote)->sin_port; ! 2566: memcpy(p, &port, sizeof(u_short)); ! 2567: p += sizeof(u_short); ! 2568: ! 2569: /* copy target address */ ! 2570: memcpy(p, sa2, alen); ! 2571: p += alen; ! 2572: port = ((struct sockaddr_in *)local)->sin_port; ! 2573: memcpy(p, &port, sizeof(u_short)); ! 2574: p += sizeof(u_short); ! 2575: ! 2576: /* copy time */ ! 2577: t = time(0); ! 2578: memcpy(p, (caddr_t)&t, sizeof(t)); ! 2579: p += sizeof(t); ! 2580: ! 2581: /* copy random value */ ! 2582: buf2 = eay_set_random(lcconf->secret_size); ! 2583: if (buf2 == NULL) ! 2584: goto end; ! 2585: memcpy(p, buf2->v, lcconf->secret_size); ! 2586: p += lcconf->secret_size; ! 2587: vfree(buf2); ! 2588: ! 2589: buf2 = eay_sha1_one(buf); ! 2590: memcpy(place, buf2->v, sizeof(cookie_t)); ! 2591: ! 2592: sa1 = val2str(place, sizeof (cookie_t)); ! 2593: plog(LLV_DEBUG, LOCATION, NULL, "new cookie:\n%s\n", sa1); ! 2594: racoon_free(sa1); ! 2595: ! 2596: error = 0; ! 2597: end: ! 2598: if (buf != NULL) ! 2599: vfree(buf); ! 2600: if (buf2 != NULL) ! 2601: vfree(buf2); ! 2602: return error; ! 2603: } ! 2604: ! 2605: /* ! 2606: * save partner's(payload) data into phhandle. ! 2607: */ ! 2608: int ! 2609: isakmp_p2ph(buf, gen) ! 2610: vchar_t **buf; ! 2611: struct isakmp_gen *gen; ! 2612: { ! 2613: /* XXX to be checked in each functions for logging. */ ! 2614: if (*buf) { ! 2615: plog(LLV_WARNING, LOCATION, NULL, ! 2616: "ignore this payload, same payload type exist.\n"); ! 2617: return -1; ! 2618: } ! 2619: ! 2620: *buf = vmalloc(ntohs(gen->len) - sizeof(*gen)); ! 2621: if (*buf == NULL) { ! 2622: plog(LLV_ERROR, LOCATION, NULL, ! 2623: "failed to get buffer.\n"); ! 2624: return -1; ! 2625: } ! 2626: memcpy((*buf)->v, gen + 1, (*buf)->l); ! 2627: ! 2628: return 0; ! 2629: } ! 2630: ! 2631: u_int32_t ! 2632: isakmp_newmsgid2(iph1) ! 2633: struct ph1handle *iph1; ! 2634: { ! 2635: u_int32_t msgid2; ! 2636: ! 2637: do { ! 2638: msgid2 = eay_random(); ! 2639: } while (getph2bymsgid(iph1, msgid2)); ! 2640: ! 2641: return msgid2; ! 2642: } ! 2643: ! 2644: /* ! 2645: * set values into allocated buffer of isakmp header for phase 1 ! 2646: */ ! 2647: static caddr_t ! 2648: set_isakmp_header(vbuf, iph1, nptype, etype, flags, msgid) ! 2649: vchar_t *vbuf; ! 2650: struct ph1handle *iph1; ! 2651: int nptype; ! 2652: u_int8_t etype; ! 2653: u_int8_t flags; ! 2654: u_int32_t msgid; ! 2655: { ! 2656: struct isakmp *isakmp; ! 2657: ! 2658: if (vbuf->l < sizeof(*isakmp)) ! 2659: return NULL; ! 2660: ! 2661: isakmp = (struct isakmp *)vbuf->v; ! 2662: ! 2663: memcpy(&isakmp->i_ck, &iph1->index.i_ck, sizeof(cookie_t)); ! 2664: memcpy(&isakmp->r_ck, &iph1->index.r_ck, sizeof(cookie_t)); ! 2665: isakmp->np = nptype; ! 2666: isakmp->v = iph1->version; ! 2667: isakmp->etype = etype; ! 2668: isakmp->flags = flags; ! 2669: isakmp->msgid = msgid; ! 2670: isakmp->len = htonl(vbuf->l); ! 2671: ! 2672: return vbuf->v + sizeof(*isakmp); ! 2673: } ! 2674: ! 2675: /* ! 2676: * set values into allocated buffer of isakmp header for phase 1 ! 2677: */ ! 2678: caddr_t ! 2679: set_isakmp_header1(vbuf, iph1, nptype) ! 2680: vchar_t *vbuf; ! 2681: struct ph1handle *iph1; ! 2682: int nptype; ! 2683: { ! 2684: return set_isakmp_header (vbuf, iph1, nptype, iph1->etype, iph1->flags, iph1->msgid); ! 2685: } ! 2686: ! 2687: /* ! 2688: * set values into allocated buffer of isakmp header for phase 2 ! 2689: */ ! 2690: caddr_t ! 2691: set_isakmp_header2(vbuf, iph2, nptype) ! 2692: vchar_t *vbuf; ! 2693: struct ph2handle *iph2; ! 2694: int nptype; ! 2695: { ! 2696: return set_isakmp_header (vbuf, iph2->ph1, nptype, ISAKMP_ETYPE_QUICK, iph2->flags, iph2->msgid); ! 2697: } ! 2698: ! 2699: /* ! 2700: * set values into allocated buffer of isakmp payload. ! 2701: */ ! 2702: caddr_t ! 2703: set_isakmp_payload(buf, src, nptype) ! 2704: caddr_t buf; ! 2705: vchar_t *src; ! 2706: int nptype; ! 2707: { ! 2708: struct isakmp_gen *gen; ! 2709: caddr_t p = buf; ! 2710: ! 2711: plog(LLV_DEBUG, LOCATION, NULL, "add payload of len %zu, next type %d\n", ! 2712: src->l, nptype); ! 2713: ! 2714: gen = (struct isakmp_gen *)p; ! 2715: gen->np = nptype; ! 2716: gen->len = htons(sizeof(*gen) + src->l); ! 2717: p += sizeof(*gen); ! 2718: memcpy(p, src->v, src->l); ! 2719: p += src->l; ! 2720: ! 2721: return p; ! 2722: } ! 2723: ! 2724: static int ! 2725: etypesw1(etype) ! 2726: int etype; ! 2727: { ! 2728: switch (etype) { ! 2729: case ISAKMP_ETYPE_IDENT: ! 2730: return 1; ! 2731: case ISAKMP_ETYPE_AGG: ! 2732: return 2; ! 2733: case ISAKMP_ETYPE_BASE: ! 2734: return 3; ! 2735: default: ! 2736: return 0; ! 2737: } ! 2738: /*NOTREACHED*/ ! 2739: } ! 2740: ! 2741: static int ! 2742: etypesw2(etype) ! 2743: int etype; ! 2744: { ! 2745: switch (etype) { ! 2746: case ISAKMP_ETYPE_QUICK: ! 2747: return 1; ! 2748: default: ! 2749: return 0; ! 2750: } ! 2751: /*NOTREACHED*/ ! 2752: } ! 2753: ! 2754: #ifdef HAVE_PRINT_ISAKMP_C ! 2755: /* for print-isakmp.c */ ! 2756: char *snapend; ! 2757: extern void isakmp_print __P((const u_char *, u_int, const u_char *)); ! 2758: ! 2759: char *getname __P((const u_char *)); ! 2760: #ifdef INET6 ! 2761: char *getname6 __P((const u_char *)); ! 2762: #endif ! 2763: int safeputchar __P((int)); ! 2764: ! 2765: /* ! 2766: * Return a name for the IP address pointed to by ap. This address ! 2767: * is assumed to be in network byte order. ! 2768: */ ! 2769: char * ! 2770: getname(ap) ! 2771: const u_char *ap; ! 2772: { ! 2773: struct sockaddr_in addr; ! 2774: static char ntop_buf[NI_MAXHOST]; ! 2775: ! 2776: memset(&addr, 0, sizeof(addr)); ! 2777: #ifndef __linux__ ! 2778: addr.sin_len = sizeof(struct sockaddr_in); ! 2779: #endif ! 2780: addr.sin_family = AF_INET; ! 2781: memcpy(&addr.sin_addr, ap, sizeof(addr.sin_addr)); ! 2782: if (getnameinfo((struct sockaddr *)&addr, sizeof(addr), ! 2783: ntop_buf, sizeof(ntop_buf), NULL, 0, ! 2784: NI_NUMERICHOST | niflags)) ! 2785: strlcpy(ntop_buf, "?", sizeof(ntop_buf)); ! 2786: ! 2787: return ntop_buf; ! 2788: } ! 2789: ! 2790: #ifdef INET6 ! 2791: /* ! 2792: * Return a name for the IP6 address pointed to by ap. This address ! 2793: * is assumed to be in network byte order. ! 2794: */ ! 2795: char * ! 2796: getname6(ap) ! 2797: const u_char *ap; ! 2798: { ! 2799: struct sockaddr_in6 addr; ! 2800: static char ntop_buf[NI_MAXHOST]; ! 2801: ! 2802: memset(&addr, 0, sizeof(addr)); ! 2803: addr.sin6_len = sizeof(struct sockaddr_in6); ! 2804: addr.sin6_family = AF_INET6; ! 2805: memcpy(&addr.sin6_addr, ap, sizeof(addr.sin6_addr)); ! 2806: if (getnameinfo((struct sockaddr *)&addr, addr.sin6_len, ! 2807: ntop_buf, sizeof(ntop_buf), NULL, 0, ! 2808: NI_NUMERICHOST | niflags)) ! 2809: strlcpy(ntop_buf, "?", sizeof(ntop_buf)); ! 2810: ! 2811: return ntop_buf; ! 2812: } ! 2813: #endif /* INET6 */ ! 2814: ! 2815: int ! 2816: safeputchar(c) ! 2817: int c; ! 2818: { ! 2819: unsigned char ch; ! 2820: ! 2821: ch = (unsigned char)(c & 0xff); ! 2822: if (c < 0x80 && isprint(c)) ! 2823: return printf("%c", c & 0xff); ! 2824: else ! 2825: return printf("\\%03o", c & 0xff); ! 2826: } ! 2827: ! 2828: void ! 2829: isakmp_printpacket(msg, from, my, decoded) ! 2830: vchar_t *msg; ! 2831: struct sockaddr *from; ! 2832: struct sockaddr *my; ! 2833: int decoded; ! 2834: { ! 2835: #ifdef YIPS_DEBUG ! 2836: struct timeval tv; ! 2837: int s; ! 2838: char hostbuf[NI_MAXHOST]; ! 2839: char portbuf[NI_MAXSERV]; ! 2840: struct isakmp *isakmp; ! 2841: vchar_t *buf; ! 2842: #endif ! 2843: ! 2844: if (loglevel < LLV_DEBUG) ! 2845: return; ! 2846: ! 2847: #ifdef YIPS_DEBUG ! 2848: plog(LLV_DEBUG, LOCATION, NULL, "begin.\n"); ! 2849: ! 2850: gettimeofday(&tv, NULL); ! 2851: s = tv.tv_sec % 3600; ! 2852: printf("%02d:%02d.%06u ", s / 60, s % 60, (u_int32_t)tv.tv_usec); ! 2853: ! 2854: if (from) { ! 2855: if (getnameinfo(from, sysdep_sa_len(from), hostbuf, sizeof(hostbuf), ! 2856: portbuf, sizeof(portbuf), ! 2857: NI_NUMERICHOST | NI_NUMERICSERV | niflags)) { ! 2858: strlcpy(hostbuf, "?", sizeof(hostbuf)); ! 2859: strlcpy(portbuf, "?", sizeof(portbuf)); ! 2860: } ! 2861: printf("%s:%s", hostbuf, portbuf); ! 2862: } else ! 2863: printf("?"); ! 2864: printf(" -> "); ! 2865: if (my) { ! 2866: if (getnameinfo(my, sysdep_sa_len(my), hostbuf, sizeof(hostbuf), ! 2867: portbuf, sizeof(portbuf), ! 2868: NI_NUMERICHOST | NI_NUMERICSERV | niflags)) { ! 2869: strlcpy(hostbuf, "?", sizeof(hostbuf)); ! 2870: strlcpy(portbuf, "?", sizeof(portbuf)); ! 2871: } ! 2872: printf("%s:%s", hostbuf, portbuf); ! 2873: } else ! 2874: printf("?"); ! 2875: printf(": "); ! 2876: ! 2877: buf = vdup(msg); ! 2878: if (!buf) { ! 2879: printf("(malloc fail)\n"); ! 2880: return; ! 2881: } ! 2882: if (decoded) { ! 2883: isakmp = (struct isakmp *)buf->v; ! 2884: if (isakmp->flags & ISAKMP_FLAG_E) { ! 2885: #if 0 ! 2886: int pad; ! 2887: pad = *(u_char *)(buf->v + buf->l - 1); ! 2888: if (buf->l < pad && 2 < vflag) ! 2889: printf("(wrong padding)"); ! 2890: #endif ! 2891: isakmp->flags &= ~ISAKMP_FLAG_E; ! 2892: } ! 2893: } ! 2894: ! 2895: snapend = buf->v + buf->l; ! 2896: isakmp_print(buf->v, buf->l, NULL); ! 2897: vfree(buf); ! 2898: printf("\n"); ! 2899: fflush(stdout); ! 2900: ! 2901: return; ! 2902: #endif ! 2903: } ! 2904: #endif /*HAVE_PRINT_ISAKMP_C*/ ! 2905: ! 2906: int ! 2907: copy_ph1addresses(iph1, rmconf, remote, local) ! 2908: struct ph1handle *iph1; ! 2909: struct remoteconf *rmconf; ! 2910: struct sockaddr *remote, *local; ! 2911: { ! 2912: u_int16_t port; ! 2913: ! 2914: /* address portion must be grabbed from real remote address "remote" */ ! 2915: iph1->remote = dupsaddr(remote); ! 2916: if (iph1->remote == NULL) ! 2917: return -1; ! 2918: ! 2919: /* ! 2920: * if remote has no port # (in case of initiator - from ACQUIRE msg) ! 2921: * - if remote.conf specifies port #, use that ! 2922: * - if remote.conf does not, use 500 ! 2923: * if remote has port # (in case of responder - from recvfrom(2)) ! 2924: * respect content of "remote". ! 2925: */ ! 2926: if (extract_port(iph1->remote) == 0) { ! 2927: port = 0; ! 2928: if (rmconf != NULL) ! 2929: port = extract_port(rmconf->remote); ! 2930: if (port == 0) ! 2931: port = PORT_ISAKMP; ! 2932: set_port(iph1->remote, port); ! 2933: } ! 2934: ! 2935: if (local == NULL) ! 2936: iph1->local = getlocaladdr(iph1->remote); ! 2937: else ! 2938: iph1->local = dupsaddr(local); ! 2939: if (iph1->local == NULL) ! 2940: return -1; ! 2941: ! 2942: if (extract_port(iph1->local) == 0) { ! 2943: port = myaddr_getsport(iph1->local); ! 2944: if (port == 0) ! 2945: port = PORT_ISAKMP; ! 2946: set_port(iph1->local, PORT_ISAKMP); ! 2947: } ! 2948: ! 2949: #ifdef ENABLE_NATT ! 2950: if (extract_port(iph1->local) == lcconf->port_isakmp_natt) { ! 2951: plog(LLV_DEBUG, LOCATION, NULL, "Marking ports as changed\n"); ! 2952: iph1->natt_flags |= NAT_ADD_NON_ESP_MARKER; ! 2953: } ! 2954: #endif ! 2955: ! 2956: return 0; ! 2957: } ! 2958: ! 2959: static int ! 2960: nostate1(iph1, msg) ! 2961: struct ph1handle *iph1; ! 2962: vchar_t *msg; ! 2963: { ! 2964: plog(LLV_ERROR, LOCATION, iph1->remote, "wrong state %u.\n", ! 2965: iph1->status); ! 2966: return -1; ! 2967: } ! 2968: ! 2969: static int ! 2970: nostate2(iph2, msg) ! 2971: struct ph2handle *iph2; ! 2972: vchar_t *msg; ! 2973: { ! 2974: plog(LLV_ERROR, LOCATION, iph2->ph1->remote, "wrong state %u.\n", ! 2975: iph2->status); ! 2976: return -1; ! 2977: } ! 2978: ! 2979: void ! 2980: log_ph1established(iph1) ! 2981: const struct ph1handle *iph1; ! 2982: { ! 2983: char *src, *dst; ! 2984: ! 2985: src = racoon_strdup(saddr2str(iph1->local)); ! 2986: dst = racoon_strdup(saddr2str(iph1->remote)); ! 2987: STRDUP_FATAL(src); ! 2988: STRDUP_FATAL(dst); ! 2989: ! 2990: plog(LLV_INFO, LOCATION, NULL, ! 2991: "ISAKMP-SA established %s-%s spi:%s\n", ! 2992: src, dst, ! 2993: isakmp_pindex(&iph1->index, 0)); ! 2994: ! 2995: evt_phase1(iph1, EVT_PHASE1_UP, NULL); ! 2996: if(!iph1->rmconf->mode_cfg) ! 2997: evt_phase1(iph1, EVT_PHASE1_MODE_CFG, NULL); ! 2998: ! 2999: racoon_free(src); ! 3000: racoon_free(dst); ! 3001: ! 3002: return; ! 3003: } ! 3004: ! 3005: struct payload_list * ! 3006: isakmp_plist_append_full (struct payload_list *plist, vchar_t *payload, ! 3007: u_int8_t payload_type, u_int8_t free_payload) ! 3008: { ! 3009: if (! plist) { ! 3010: plist = racoon_malloc (sizeof (struct payload_list)); ! 3011: plist->prev = NULL; ! 3012: } ! 3013: else { ! 3014: plist->next = racoon_malloc (sizeof (struct payload_list)); ! 3015: plist->next->prev = plist; ! 3016: plist = plist->next; ! 3017: } ! 3018: ! 3019: plist->next = NULL; ! 3020: plist->payload = payload; ! 3021: plist->payload_type = payload_type; ! 3022: plist->free_payload = free_payload; ! 3023: ! 3024: return plist; ! 3025: } ! 3026: ! 3027: vchar_t * ! 3028: isakmp_plist_set_all (struct payload_list **plist, struct ph1handle *iph1) ! 3029: { ! 3030: struct payload_list *ptr = *plist, *first; ! 3031: size_t tlen = sizeof (struct isakmp), n = 0; ! 3032: vchar_t *buf = NULL; ! 3033: char *p; ! 3034: ! 3035: /* Seek to the first item. */ ! 3036: while (ptr->prev) ptr = ptr->prev; ! 3037: first = ptr; ! 3038: ! 3039: /* Compute the whole length. */ ! 3040: while (ptr) { ! 3041: tlen += ptr->payload->l + sizeof (struct isakmp_gen); ! 3042: ptr = ptr->next; ! 3043: } ! 3044: ! 3045: buf = vmalloc(tlen); ! 3046: if (buf == NULL) { ! 3047: plog(LLV_ERROR, LOCATION, NULL, ! 3048: "failed to get buffer to send.\n"); ! 3049: goto end; ! 3050: } ! 3051: ! 3052: ptr = first; ! 3053: ! 3054: p = set_isakmp_header1(buf, iph1, ptr->payload_type); ! 3055: if (p == NULL) ! 3056: goto end; ! 3057: ! 3058: while (ptr) ! 3059: { ! 3060: p = set_isakmp_payload (p, ptr->payload, ptr->next ? ptr->next->payload_type : ISAKMP_NPTYPE_NONE); ! 3061: first = ptr; ! 3062: ptr = ptr->next; ! 3063: if (first->free_payload) ! 3064: vfree(first->payload); ! 3065: racoon_free (first); ! 3066: /* ptr->prev = NULL; first = NULL; ... omitted. */ ! 3067: n++; ! 3068: } ! 3069: ! 3070: *plist = NULL; ! 3071: ! 3072: return buf; ! 3073: end: ! 3074: if (buf != NULL) ! 3075: vfree(buf); ! 3076: return NULL; ! 3077: } ! 3078: ! 3079: #ifdef ENABLE_FRAG ! 3080: int ! 3081: frag_handler(iph1, msg, remote, local) ! 3082: struct ph1handle *iph1; ! 3083: vchar_t *msg; ! 3084: struct sockaddr *remote; ! 3085: struct sockaddr *local; ! 3086: { ! 3087: vchar_t *newmsg; ! 3088: ! 3089: if (isakmp_frag_extract(iph1, msg) == 1) { ! 3090: if ((newmsg = isakmp_frag_reassembly(iph1)) == NULL) { ! 3091: plog(LLV_ERROR, LOCATION, remote, ! 3092: "Packet reassembly failed\n"); ! 3093: return -1; ! 3094: } ! 3095: return isakmp_main(newmsg, remote, local); ! 3096: } ! 3097: ! 3098: return 0; ! 3099: } ! 3100: #endif ! 3101: ! 3102: void ! 3103: script_hook(iph1, script) ! 3104: struct ph1handle *iph1; ! 3105: int script; ! 3106: { ! 3107: #define IP_MAX 40 ! 3108: #define PORT_MAX 6 ! 3109: char addrstr[IP_MAX]; ! 3110: char portstr[PORT_MAX]; ! 3111: char **envp = NULL; ! 3112: int envc = 1; ! 3113: char **c; ! 3114: ! 3115: if (iph1 == NULL || ! 3116: iph1->rmconf == NULL || ! 3117: iph1->rmconf->script[script] == NULL) ! 3118: return; ! 3119: ! 3120: #ifdef ENABLE_HYBRID ! 3121: (void)isakmp_cfg_setenv(iph1, &envp, &envc); ! 3122: #endif ! 3123: ! 3124: /* local address */ ! 3125: GETNAMEINFO(iph1->local, addrstr, portstr); ! 3126: ! 3127: if (script_env_append(&envp, &envc, "LOCAL_ADDR", addrstr) != 0) { ! 3128: plog(LLV_ERROR, LOCATION, NULL, "Cannot set LOCAL_ADDR\n"); ! 3129: goto out; ! 3130: } ! 3131: ! 3132: if (script_env_append(&envp, &envc, "LOCAL_PORT", portstr) != 0) { ! 3133: plog(LLV_ERROR, LOCATION, NULL, "Cannot set LOCAL_PORT\n"); ! 3134: goto out; ! 3135: } ! 3136: ! 3137: /* Peer address */ ! 3138: if (iph1->remote != NULL) { ! 3139: GETNAMEINFO(iph1->remote, addrstr, portstr); ! 3140: ! 3141: if (script_env_append(&envp, &envc, ! 3142: "REMOTE_ADDR", addrstr) != 0) { ! 3143: plog(LLV_ERROR, LOCATION, NULL, ! 3144: "Cannot set REMOTE_ADDR\n"); ! 3145: goto out; ! 3146: } ! 3147: ! 3148: if (script_env_append(&envp, &envc, ! 3149: "REMOTE_PORT", portstr) != 0) { ! 3150: plog(LLV_ERROR, LOCATION, NULL, ! 3151: "Cannot set REMOTEL_PORT\n"); ! 3152: goto out; ! 3153: } ! 3154: } ! 3155: ! 3156: /* Peer identity. */ ! 3157: if (iph1->id_p != NULL) { ! 3158: if (script_env_append(&envp, &envc, "REMOTE_ID", ! 3159: ipsecdoi_id2str(iph1->id_p)) != 0) { ! 3160: plog(LLV_ERROR, LOCATION, NULL, ! 3161: "Cannot set REMOTE_ID\n"); ! 3162: goto out; ! 3163: } ! 3164: } ! 3165: ! 3166: if (privsep_script_exec(iph1->rmconf->script[script]->v, ! 3167: script, envp) != 0) ! 3168: plog(LLV_ERROR, LOCATION, NULL, ! 3169: "Script %s execution failed\n", script_names[script]); ! 3170: ! 3171: out: ! 3172: for (c = envp; *c; c++) ! 3173: racoon_free(*c); ! 3174: ! 3175: racoon_free(envp); ! 3176: ! 3177: return; ! 3178: } ! 3179: ! 3180: int ! 3181: script_env_append(envp, envc, name, value) ! 3182: char ***envp; ! 3183: int *envc; ! 3184: char *name; ! 3185: char *value; ! 3186: { ! 3187: char *envitem; ! 3188: char **newenvp; ! 3189: int newenvc; ! 3190: ! 3191: envitem = racoon_malloc(strlen(name) + 1 + strlen(value) + 1); ! 3192: if (envitem == NULL) { ! 3193: plog(LLV_ERROR, LOCATION, NULL, ! 3194: "Cannot allocate memory: %s\n", strerror(errno)); ! 3195: return -1; ! 3196: } ! 3197: sprintf(envitem, "%s=%s", name, value); ! 3198: ! 3199: newenvc = (*envc) + 1; ! 3200: newenvp = racoon_realloc(*envp, newenvc * sizeof(char *)); ! 3201: if (newenvp == NULL) { ! 3202: plog(LLV_ERROR, LOCATION, NULL, ! 3203: "Cannot allocate memory: %s\n", strerror(errno)); ! 3204: racoon_free(envitem); ! 3205: return -1; ! 3206: } ! 3207: ! 3208: newenvp[newenvc - 2] = envitem; ! 3209: newenvp[newenvc - 1] = NULL; ! 3210: ! 3211: *envp = newenvp; ! 3212: *envc = newenvc; ! 3213: return 0; ! 3214: } ! 3215: ! 3216: int ! 3217: script_exec(script, name, envp) ! 3218: char *script; ! 3219: int name; ! 3220: char *const envp[]; ! 3221: { ! 3222: char *argv[] = { NULL, NULL, NULL }; ! 3223: ! 3224: argv[0] = script; ! 3225: argv[1] = script_names[name]; ! 3226: argv[2] = NULL; ! 3227: ! 3228: switch (fork()) { ! 3229: case 0: ! 3230: execve(argv[0], argv, envp); ! 3231: plog(LLV_ERROR, LOCATION, NULL, ! 3232: "execve(\"%s\") failed: %s\n", ! 3233: argv[0], strerror(errno)); ! 3234: _exit(1); ! 3235: break; ! 3236: case -1: ! 3237: plog(LLV_ERROR, LOCATION, NULL, ! 3238: "Cannot fork: %s\n", strerror(errno)); ! 3239: return -1; ! 3240: break; ! 3241: default: ! 3242: break; ! 3243: } ! 3244: return 0; ! 3245: ! 3246: } ! 3247: ! 3248: void ! 3249: purge_remote(iph1) ! 3250: struct ph1handle *iph1; ! 3251: { ! 3252: vchar_t *buf = NULL; ! 3253: struct sadb_msg *msg, *next, *end; ! 3254: struct sadb_sa *sa; ! 3255: struct sockaddr *src, *dst; ! 3256: caddr_t mhp[SADB_EXT_MAX + 1]; ! 3257: u_int proto_id; ! 3258: struct ph2handle *iph2; ! 3259: struct ph1handle *new_iph1; ! 3260: ! 3261: plog(LLV_INFO, LOCATION, NULL, ! 3262: "purging ISAKMP-SA spi=%s.\n", ! 3263: isakmp_pindex(&(iph1->index), iph1->msgid)); ! 3264: ! 3265: /* Mark as expired. */ ! 3266: iph1->status = PHASE1ST_EXPIRED; ! 3267: ! 3268: /* Check if we have another, still valid, phase1 SA. */ ! 3269: new_iph1 = getph1(iph1, iph1->local, iph1->remote, GETPH1_F_ESTABLISHED); ! 3270: ! 3271: /* ! 3272: * Delete all orphaned or binded to the deleting ph1handle phase2 SAs. ! 3273: * Keep all others phase2 SAs. ! 3274: */ ! 3275: buf = pfkey_dump_sadb(SADB_SATYPE_UNSPEC); ! 3276: if (buf == NULL) { ! 3277: plog(LLV_DEBUG, LOCATION, NULL, ! 3278: "pfkey_dump_sadb returned nothing.\n"); ! 3279: return; ! 3280: } ! 3281: ! 3282: msg = (struct sadb_msg *)buf->v; ! 3283: end = (struct sadb_msg *)(buf->v + buf->l); ! 3284: ! 3285: while (msg < end) { ! 3286: if ((msg->sadb_msg_len << 3) < sizeof(*msg)) ! 3287: break; ! 3288: next = (struct sadb_msg *)((caddr_t)msg + (msg->sadb_msg_len << 3)); ! 3289: if (msg->sadb_msg_type != SADB_DUMP) { ! 3290: msg = next; ! 3291: continue; ! 3292: } ! 3293: ! 3294: if (pfkey_align(msg, mhp) || pfkey_check(mhp)) { ! 3295: plog(LLV_ERROR, LOCATION, NULL, ! 3296: "pfkey_check (%s)\n", ipsec_strerror()); ! 3297: msg = next; ! 3298: continue; ! 3299: } ! 3300: ! 3301: sa = (struct sadb_sa *)(mhp[SADB_EXT_SA]); ! 3302: if (!sa || ! 3303: !mhp[SADB_EXT_ADDRESS_SRC] || ! 3304: !mhp[SADB_EXT_ADDRESS_DST]) { ! 3305: msg = next; ! 3306: continue; ! 3307: } ! 3308: pk_fixup_sa_addresses(mhp); ! 3309: src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]); ! 3310: dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]); ! 3311: ! 3312: if (sa->sadb_sa_state != SADB_SASTATE_LARVAL && ! 3313: sa->sadb_sa_state != SADB_SASTATE_MATURE && ! 3314: sa->sadb_sa_state != SADB_SASTATE_DYING) { ! 3315: msg = next; ! 3316: continue; ! 3317: } ! 3318: ! 3319: /* ! 3320: * check in/outbound SAs. ! 3321: * Select only SAs where src == local and dst == remote (outgoing) ! 3322: * or src == remote and dst == local (incoming). ! 3323: */ ! 3324: if ((cmpsaddr(iph1->local, src) != CMPSADDR_MATCH || ! 3325: cmpsaddr(iph1->remote, dst) != CMPSADDR_MATCH) && ! 3326: (cmpsaddr(iph1->local, dst) != CMPSADDR_MATCH || ! 3327: cmpsaddr(iph1->remote, src) != CMPSADDR_MATCH)) { ! 3328: msg = next; ! 3329: continue; ! 3330: } ! 3331: ! 3332: proto_id = pfkey2ipsecdoi_proto(msg->sadb_msg_satype); ! 3333: iph2 = getph2bysaidx(src, dst, proto_id, sa->sadb_sa_spi); ! 3334: ! 3335: /* Check if there is another valid ISAKMP-SA */ ! 3336: if (new_iph1 != NULL) { ! 3337: ! 3338: if (iph2 == NULL) { ! 3339: /* No handler... still send a pfkey_delete message, but log this !*/ ! 3340: plog(LLV_INFO, LOCATION, NULL, ! 3341: "Unknown IPsec-SA spi=%u, hmmmm?\n", ! 3342: ntohl(sa->sadb_sa_spi)); ! 3343: }else{ ! 3344: ! 3345: /* ! 3346: * If we have a new ph1, do not purge IPsec-SAs binded ! 3347: * to a different ISAKMP-SA ! 3348: */ ! 3349: if (iph2->ph1 != NULL && iph2->ph1 != iph1){ ! 3350: msg = next; ! 3351: continue; ! 3352: } ! 3353: ! 3354: /* If the ph2handle is established, do not purge IPsec-SA */ ! 3355: if (iph2->status == PHASE2ST_ESTABLISHED || ! 3356: iph2->status == PHASE2ST_EXPIRED) { ! 3357: ! 3358: plog(LLV_INFO, LOCATION, NULL, ! 3359: "keeping IPsec-SA spi=%u - found valid ISAKMP-SA spi=%s.\n", ! 3360: ntohl(sa->sadb_sa_spi), ! 3361: isakmp_pindex(&(new_iph1->index), new_iph1->msgid)); ! 3362: msg = next; ! 3363: continue; ! 3364: } ! 3365: } ! 3366: } ! 3367: ! 3368: ! 3369: pfkey_send_delete(lcconf->sock_pfkey, ! 3370: msg->sadb_msg_satype, ! 3371: IPSEC_MODE_ANY, ! 3372: src, dst, sa->sadb_sa_spi); ! 3373: ! 3374: /* delete a relative phase 2 handle. */ ! 3375: if (iph2 != NULL) { ! 3376: delete_spd(iph2, 0); ! 3377: remph2(iph2); ! 3378: delph2(iph2); ! 3379: } ! 3380: ! 3381: plog(LLV_INFO, LOCATION, NULL, ! 3382: "purged IPsec-SA spi=%u.\n", ! 3383: ntohl(sa->sadb_sa_spi)); ! 3384: ! 3385: msg = next; ! 3386: } ! 3387: ! 3388: if (buf) ! 3389: vfree(buf); ! 3390: ! 3391: /* Mark the phase1 handler as EXPIRED */ ! 3392: plog(LLV_INFO, LOCATION, NULL, ! 3393: "purged ISAKMP-SA spi=%s.\n", ! 3394: isakmp_pindex(&(iph1->index), iph1->msgid)); ! 3395: ! 3396: isakmp_ph1delete(iph1); ! 3397: } ! 3398: ! 3399: void ! 3400: delete_spd(iph2, created) ! 3401: struct ph2handle *iph2; ! 3402: u_int64_t created; ! 3403: { ! 3404: struct policyindex spidx; ! 3405: struct sockaddr_storage addr; ! 3406: u_int8_t pref; ! 3407: struct sockaddr *src; ! 3408: struct sockaddr *dst; ! 3409: int error; ! 3410: int idi2type = 0;/* switch whether copy IDs into id[src,dst]. */ ! 3411: ! 3412: if (iph2 == NULL) ! 3413: return; ! 3414: ! 3415: /* Delete the SPD entry if we generated it ! 3416: */ ! 3417: if (! iph2->generated_spidx ) ! 3418: return; ! 3419: ! 3420: src = iph2->src; ! 3421: dst = iph2->dst; ! 3422: ! 3423: plog(LLV_INFO, LOCATION, NULL, ! 3424: "deleting a generated policy.\n"); ! 3425: ! 3426: memset(&spidx, 0, sizeof(spidx)); ! 3427: iph2->spidx_gen = (caddr_t )&spidx; ! 3428: ! 3429: /* make inbound policy */ ! 3430: iph2->src = dst; ! 3431: iph2->dst = src; ! 3432: spidx.dir = IPSEC_DIR_INBOUND; ! 3433: spidx.ul_proto = 0; ! 3434: ! 3435: /* ! 3436: * Note: code from get_proposal_r ! 3437: */ ! 3438: ! 3439: #define _XIDT(d) ((struct ipsecdoi_id_b *)(d)->v)->type ! 3440: ! 3441: /* ! 3442: * make destination address in spidx from either ID payload ! 3443: * or phase 1 address into a address in spidx. ! 3444: */ ! 3445: if (iph2->id != NULL ! 3446: && (_XIDT(iph2->id) == IPSECDOI_ID_IPV4_ADDR ! 3447: || _XIDT(iph2->id) == IPSECDOI_ID_IPV6_ADDR ! 3448: || _XIDT(iph2->id) == IPSECDOI_ID_IPV4_ADDR_SUBNET ! 3449: || _XIDT(iph2->id) == IPSECDOI_ID_IPV6_ADDR_SUBNET)) { ! 3450: /* get a destination address of a policy */ ! 3451: error = ipsecdoi_id2sockaddr(iph2->id, ! 3452: (struct sockaddr *)&spidx.dst, ! 3453: &spidx.prefd, &spidx.ul_proto); ! 3454: if (error) ! 3455: goto purge; ! 3456: ! 3457: #ifdef INET6 ! 3458: /* ! 3459: * get scopeid from the SA address. ! 3460: * note that the phase 1 source address is used as ! 3461: * a destination address to search for a inbound ! 3462: * policy entry because rcoon is responder. ! 3463: */ ! 3464: if (_XIDT(iph2->id) == IPSECDOI_ID_IPV6_ADDR) { ! 3465: if ((error = ! 3466: setscopeid((struct sockaddr *)&spidx.dst, ! 3467: iph2->src)) != 0) ! 3468: goto purge; ! 3469: } ! 3470: #endif ! 3471: ! 3472: if (_XIDT(iph2->id) == IPSECDOI_ID_IPV4_ADDR ! 3473: || _XIDT(iph2->id) == IPSECDOI_ID_IPV6_ADDR) ! 3474: idi2type = _XIDT(iph2->id); ! 3475: ! 3476: } else { ! 3477: ! 3478: plog(LLV_DEBUG, LOCATION, NULL, ! 3479: "get a destination address of SP index " ! 3480: "from phase1 address " ! 3481: "due to no ID payloads found " ! 3482: "OR because ID type is not address.\n"); ! 3483: ! 3484: /* ! 3485: * copy the SOURCE address of IKE into the ! 3486: * DESTINATION address of the key to search the ! 3487: * SPD because the direction of policy is inbound. ! 3488: */ ! 3489: memcpy(&spidx.dst, iph2->src, sysdep_sa_len(iph2->src)); ! 3490: switch (spidx.dst.ss_family) { ! 3491: case AF_INET: ! 3492: spidx.prefd = ! 3493: sizeof(struct in_addr) << 3; ! 3494: break; ! 3495: #ifdef INET6 ! 3496: case AF_INET6: ! 3497: spidx.prefd = ! 3498: sizeof(struct in6_addr) << 3; ! 3499: break; ! 3500: #endif ! 3501: default: ! 3502: spidx.prefd = 0; ! 3503: break; ! 3504: } ! 3505: } ! 3506: ! 3507: /* make source address in spidx */ ! 3508: if (iph2->id_p != NULL ! 3509: && (_XIDT(iph2->id_p) == IPSECDOI_ID_IPV4_ADDR ! 3510: || _XIDT(iph2->id_p) == IPSECDOI_ID_IPV6_ADDR ! 3511: || _XIDT(iph2->id_p) == IPSECDOI_ID_IPV4_ADDR_SUBNET ! 3512: || _XIDT(iph2->id_p) == IPSECDOI_ID_IPV6_ADDR_SUBNET)) { ! 3513: /* get a source address of inbound SA */ ! 3514: error = ipsecdoi_id2sockaddr(iph2->id_p, ! 3515: (struct sockaddr *)&spidx.src, ! 3516: &spidx.prefs, &spidx.ul_proto); ! 3517: if (error) ! 3518: goto purge; ! 3519: ! 3520: #ifdef INET6 ! 3521: /* ! 3522: * get scopeid from the SA address. ! 3523: * for more detail, see above of this function. ! 3524: */ ! 3525: if (_XIDT(iph2->id_p) == IPSECDOI_ID_IPV6_ADDR) { ! 3526: error = ! 3527: setscopeid((struct sockaddr *)&spidx.src, ! 3528: iph2->dst); ! 3529: if (error) ! 3530: goto purge; ! 3531: } ! 3532: #endif ! 3533: ! 3534: /* make sa_[src,dst] if both ID types are IP address and same */ ! 3535: if (_XIDT(iph2->id_p) == idi2type ! 3536: && spidx.dst.ss_family == spidx.src.ss_family) { ! 3537: iph2->sa_src = ! 3538: dupsaddr((struct sockaddr *)&spidx.dst); ! 3539: if (iph2->sa_src == NULL) { ! 3540: plog(LLV_ERROR, LOCATION, NULL, ! 3541: "allocation failed\n"); ! 3542: goto purge; ! 3543: } ! 3544: iph2->sa_dst = ! 3545: dupsaddr((struct sockaddr *)&spidx.src); ! 3546: if (iph2->sa_dst == NULL) { ! 3547: plog(LLV_ERROR, LOCATION, NULL, ! 3548: "allocation failed\n"); ! 3549: goto purge; ! 3550: } ! 3551: } ! 3552: ! 3553: } else { ! 3554: plog(LLV_DEBUG, LOCATION, NULL, ! 3555: "get a source address of SP index " ! 3556: "from phase1 address " ! 3557: "due to no ID payloads found " ! 3558: "OR because ID type is not address.\n"); ! 3559: ! 3560: /* see above comment. */ ! 3561: memcpy(&spidx.src, iph2->dst, sysdep_sa_len(iph2->dst)); ! 3562: switch (spidx.src.ss_family) { ! 3563: case AF_INET: ! 3564: spidx.prefs = ! 3565: sizeof(struct in_addr) << 3; ! 3566: break; ! 3567: #ifdef INET6 ! 3568: case AF_INET6: ! 3569: spidx.prefs = ! 3570: sizeof(struct in6_addr) << 3; ! 3571: break; ! 3572: #endif ! 3573: default: ! 3574: spidx.prefs = 0; ! 3575: break; ! 3576: } ! 3577: } ! 3578: ! 3579: #undef _XIDT ! 3580: ! 3581: plog(LLV_DEBUG, LOCATION, NULL, ! 3582: "get a src address from ID payload " ! 3583: "%s prefixlen=%u ul_proto=%u\n", ! 3584: saddr2str((struct sockaddr *)&spidx.src), ! 3585: spidx.prefs, spidx.ul_proto); ! 3586: plog(LLV_DEBUG, LOCATION, NULL, ! 3587: "get dst address from ID payload " ! 3588: "%s prefixlen=%u ul_proto=%u\n", ! 3589: saddr2str((struct sockaddr *)&spidx.dst), ! 3590: spidx.prefd, spidx.ul_proto); ! 3591: ! 3592: /* ! 3593: * convert the ul_proto if it is 0 ! 3594: * because 0 in ID payload means a wild card. ! 3595: */ ! 3596: if (spidx.ul_proto == 0) ! 3597: spidx.ul_proto = IPSEC_ULPROTO_ANY; ! 3598: ! 3599: #undef _XIDT ! 3600: ! 3601: /* Check if the generated SPD has the same timestamp as the SA. ! 3602: * If timestamps are different, this means that the SPD entry has been ! 3603: * refreshed by another SA, and should NOT be deleted with the current SA. ! 3604: */ ! 3605: if( created ){ ! 3606: struct secpolicy *p; ! 3607: ! 3608: p = getsp(&spidx); ! 3609: if(p != NULL){ ! 3610: /* just do no test if p is NULL, because this probably just means ! 3611: * that the policy has already be deleted for some reason. ! 3612: */ ! 3613: if(p->spidx.created != created) ! 3614: goto purge; ! 3615: } ! 3616: } ! 3617: ! 3618: /* End of code from get_proposal_r ! 3619: */ ! 3620: ! 3621: if (pk_sendspddelete(iph2) < 0) { ! 3622: plog(LLV_ERROR, LOCATION, NULL, ! 3623: "pfkey spddelete(inbound) failed.\n"); ! 3624: }else{ ! 3625: plog(LLV_DEBUG, LOCATION, NULL, ! 3626: "pfkey spddelete(inbound) sent.\n"); ! 3627: } ! 3628: ! 3629: #ifdef HAVE_POLICY_FWD ! 3630: /* make forward policy if required */ ! 3631: if (tunnel_mode_prop(iph2->approval)) { ! 3632: spidx.dir = IPSEC_DIR_FWD; ! 3633: if (pk_sendspddelete(iph2) < 0) { ! 3634: plog(LLV_ERROR, LOCATION, NULL, ! 3635: "pfkey spddelete(forward) failed.\n"); ! 3636: }else{ ! 3637: plog(LLV_DEBUG, LOCATION, NULL, ! 3638: "pfkey spddelete(forward) sent.\n"); ! 3639: } ! 3640: } ! 3641: #endif ! 3642: ! 3643: /* make outbound policy */ ! 3644: iph2->src = src; ! 3645: iph2->dst = dst; ! 3646: spidx.dir = IPSEC_DIR_OUTBOUND; ! 3647: addr = spidx.src; ! 3648: spidx.src = spidx.dst; ! 3649: spidx.dst = addr; ! 3650: pref = spidx.prefs; ! 3651: spidx.prefs = spidx.prefd; ! 3652: spidx.prefd = pref; ! 3653: ! 3654: if (pk_sendspddelete(iph2) < 0) { ! 3655: plog(LLV_ERROR, LOCATION, NULL, ! 3656: "pfkey spddelete(outbound) failed.\n"); ! 3657: }else{ ! 3658: plog(LLV_DEBUG, LOCATION, NULL, ! 3659: "pfkey spddelete(outbound) sent.\n"); ! 3660: } ! 3661: purge: ! 3662: iph2->spidx_gen=NULL; ! 3663: } ! 3664: ! 3665: ! 3666: #ifdef INET6 ! 3667: u_int32_t ! 3668: setscopeid(sp_addr0, sa_addr0) ! 3669: struct sockaddr *sp_addr0, *sa_addr0; ! 3670: { ! 3671: struct sockaddr_in6 *sp_addr, *sa_addr; ! 3672: ! 3673: sp_addr = (struct sockaddr_in6 *)sp_addr0; ! 3674: sa_addr = (struct sockaddr_in6 *)sa_addr0; ! 3675: ! 3676: if (!IN6_IS_ADDR_LINKLOCAL(&sp_addr->sin6_addr) ! 3677: && !IN6_IS_ADDR_SITELOCAL(&sp_addr->sin6_addr) ! 3678: && !IN6_IS_ADDR_MULTICAST(&sp_addr->sin6_addr)) ! 3679: return 0; ! 3680: ! 3681: /* this check should not be here ? */ ! 3682: if (sa_addr->sin6_family != AF_INET6) { ! 3683: plog(LLV_ERROR, LOCATION, NULL, ! 3684: "can't get scope ID: family mismatch\n"); ! 3685: return -1; ! 3686: } ! 3687: ! 3688: if (!IN6_IS_ADDR_LINKLOCAL(&sa_addr->sin6_addr)) { ! 3689: plog(LLV_ERROR, LOCATION, NULL, ! 3690: "scope ID is not supported except of lladdr.\n"); ! 3691: return -1; ! 3692: } ! 3693: ! 3694: sp_addr->sin6_scope_id = sa_addr->sin6_scope_id; ! 3695: ! 3696: return 0; ! 3697: } ! 3698: #endif