Annotation of embedaddon/ipsec-tools/src/racoon/isakmp.c, revision 1.1

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>