Annotation of embedaddon/ipsec-tools/src/racoon/isakmp_inf.c, revision 1.1.1.3

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

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