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

1.1     ! misho       1: /*     $NetBSD: isakmp_cfg.c,v 1.24 2010/09/21 13:14:17 vanhu Exp $    */
        !             2: 
        !             3: /* Id: isakmp_cfg.c,v 1.55 2006/08/22 18:17:17 manubsd Exp */
        !             4: 
        !             5: /*
        !             6:  * Copyright (C) 2004-2006 Emmanuel Dreyfus
        !             7:  * All rights reserved.
        !             8:  * 
        !             9:  * Redistribution and use in source and binary forms, with or without
        !            10:  * modification, are permitted provided that the following conditions
        !            11:  * are met:
        !            12:  * 1. Redistributions of source code must retain the above copyright
        !            13:  *    notice, this list of conditions and the following disclaimer.
        !            14:  * 2. Redistributions in binary form must reproduce the above copyright
        !            15:  *    notice, this list of conditions and the following disclaimer in the
        !            16:  *    documentation and/or other materials provided with the distribution.
        !            17:  * 3. Neither the name of the project nor the names of its contributors
        !            18:  *    may be used to endorse or promote products derived from this software
        !            19:  *    without specific prior written permission.
        !            20:  * 
        !            21:  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
        !            22:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        !            23:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        !            24:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
        !            25:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        !            26:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        !            27:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            28:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        !            29:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        !            30:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        !            31:  * SUCH DAMAGE.
        !            32:  */
        !            33: 
        !            34: #include "config.h"
        !            35: 
        !            36: #include <sys/types.h>
        !            37: #include <sys/param.h>
        !            38: #include <sys/socket.h>
        !            39: #include <sys/queue.h>
        !            40: 
        !            41: #include <utmpx.h>
        !            42: #if defined(__APPLE__) && defined(__MACH__)
        !            43: #include <util.h>
        !            44: #endif
        !            45: 
        !            46: #ifdef __FreeBSD__
        !            47: # include <libutil.h>
        !            48: #endif
        !            49: #ifdef __NetBSD__
        !            50: #  include <util.h>
        !            51: #endif
        !            52: 
        !            53: #include <netinet/in.h>
        !            54: #include <arpa/inet.h>
        !            55: 
        !            56: #include <stdlib.h>
        !            57: #include <stdio.h>
        !            58: #include <string.h>
        !            59: #include <errno.h>
        !            60: #if TIME_WITH_SYS_TIME
        !            61: # include <sys/time.h>
        !            62: # include <time.h>
        !            63: #else
        !            64: # if HAVE_SYS_TIME_H
        !            65: #  include <sys/time.h>
        !            66: # else
        !            67: #  include <time.h>
        !            68: # endif
        !            69: #endif
        !            70: #include <netdb.h>
        !            71: #ifdef HAVE_UNISTD_H
        !            72: #include <unistd.h>
        !            73: #endif
        !            74: #if HAVE_STDINT_H
        !            75: #include <stdint.h>
        !            76: #endif
        !            77: #include <ctype.h>
        !            78: #include <resolv.h>
        !            79: 
        !            80: #ifdef HAVE_LIBRADIUS
        !            81: #include <sys/utsname.h>
        !            82: #include <radlib.h>
        !            83: #endif
        !            84: 
        !            85: #include "var.h"
        !            86: #include "misc.h"
        !            87: #include "vmbuf.h"
        !            88: #include "plog.h"
        !            89: #include "sockmisc.h"
        !            90: #include "schedule.h"
        !            91: #include "debug.h"
        !            92: 
        !            93: #include "isakmp_var.h"
        !            94: #include "isakmp.h"
        !            95: #include "handler.h"
        !            96: #include "evt.h"
        !            97: #include "throttle.h"
        !            98: #include "remoteconf.h"
        !            99: #include "crypto_openssl.h"
        !           100: #include "isakmp_inf.h"
        !           101: #include "isakmp_xauth.h"
        !           102: #include "isakmp_unity.h"
        !           103: #include "isakmp_cfg.h"
        !           104: #include "strnames.h"
        !           105: #include "admin.h"
        !           106: #include "privsep.h"
        !           107: 
        !           108: struct isakmp_cfg_config isakmp_cfg_config;
        !           109: 
        !           110: static vchar_t *buffer_cat(vchar_t *s, vchar_t *append);
        !           111: static vchar_t *isakmp_cfg_net(struct ph1handle *, struct isakmp_data *);
        !           112: #if 0
        !           113: static vchar_t *isakmp_cfg_void(struct ph1handle *, struct isakmp_data *);
        !           114: #endif
        !           115: static vchar_t *isakmp_cfg_addr4(struct ph1handle *, 
        !           116:                                 struct isakmp_data *, in_addr_t *);
        !           117: static vchar_t *isakmp_cfg_addrnet4(struct ph1handle *, 
        !           118:                                 struct isakmp_data *, in_addr_t *, in_addr_t *);
        !           119: static void isakmp_cfg_getaddr4(struct isakmp_data *, struct in_addr *);
        !           120: static vchar_t *isakmp_cfg_addr4_list(struct ph1handle *,
        !           121:                                      struct isakmp_data *, in_addr_t *, int);
        !           122: static void isakmp_cfg_appendaddr4(struct isakmp_data *, 
        !           123:                                   struct in_addr *, int *, int);
        !           124: static void isakmp_cfg_getstring(struct isakmp_data *,char *);
        !           125: void isakmp_cfg_iplist_to_str(char *, int, void *, int);
        !           126: 
        !           127: #define ISAKMP_CFG_LOGIN       1
        !           128: #define ISAKMP_CFG_LOGOUT      2
        !           129: static int isakmp_cfg_accounting(struct ph1handle *, int);
        !           130: #ifdef HAVE_LIBRADIUS
        !           131: static int isakmp_cfg_accounting_radius(struct ph1handle *, int);
        !           132: #endif
        !           133: 
        !           134: /* 
        !           135:  * Handle an ISAKMP config mode packet
        !           136:  * We expect HDR, HASH, ATTR
        !           137:  */
        !           138: void
        !           139: isakmp_cfg_r(iph1, msg)
        !           140:        struct ph1handle *iph1;
        !           141:        vchar_t *msg;
        !           142: {
        !           143:        struct isakmp *packet;
        !           144:        struct isakmp_gen *ph;
        !           145:        int tlen;
        !           146:        char *npp;
        !           147:        int np;
        !           148:        vchar_t *dmsg;
        !           149:        struct isakmp_ivm *ivm;
        !           150: 
        !           151:        /* Check that the packet is long enough to have a header */
        !           152:        if (msg->l < sizeof(*packet)) {
        !           153:             plog(LLV_ERROR, LOCATION, NULL, "Unexpected short packet\n");
        !           154:             return;
        !           155:        }
        !           156: 
        !           157:        packet = (struct isakmp *)msg->v;
        !           158: 
        !           159:        /* Is it encrypted? It should be encrypted */
        !           160:        if ((packet->flags & ISAKMP_FLAG_E) == 0) {
        !           161:                plog(LLV_ERROR, LOCATION, NULL, 
        !           162:                    "User credentials sent in cleartext!\n");
        !           163:                return;
        !           164:        }
        !           165: 
        !           166:        /* 
        !           167:         * Decrypt the packet. If this is the beginning of a new
        !           168:         * exchange, reinitialize the IV
        !           169:         */
        !           170:        if (iph1->mode_cfg->ivm == NULL ||
        !           171:            iph1->mode_cfg->last_msgid != packet->msgid )
        !           172:                iph1->mode_cfg->ivm = 
        !           173:                    isakmp_cfg_newiv(iph1, packet->msgid);
        !           174:        ivm = iph1->mode_cfg->ivm;
        !           175: 
        !           176:        dmsg = oakley_do_decrypt(iph1, msg, ivm->iv, ivm->ive);
        !           177:        if (dmsg == NULL) {
        !           178:                plog(LLV_ERROR, LOCATION, NULL, 
        !           179:                    "failed to decrypt message\n");
        !           180:                return;
        !           181:        }
        !           182: 
        !           183:        plog(LLV_DEBUG, LOCATION, NULL, "MODE_CFG packet\n");
        !           184:        plogdump(LLV_DEBUG, dmsg->v, dmsg->l);
        !           185: 
        !           186:        /* Now work with the decrypted packet */
        !           187:        packet = (struct isakmp *)dmsg->v;
        !           188:        tlen = dmsg->l - sizeof(*packet);
        !           189:        ph = (struct isakmp_gen *)(packet + 1);
        !           190: 
        !           191:        np = packet->np;
        !           192:        while ((tlen > 0) && (np != ISAKMP_NPTYPE_NONE)) {
        !           193:                /* Check that the payload header fits in the packet */
        !           194:                if (tlen < sizeof(*ph)) {
        !           195:                         plog(LLV_WARNING, LOCATION, NULL, 
        !           196:                              "Short payload header\n");
        !           197:                         goto out;
        !           198:                }
        !           199: 
        !           200:                /* Check that the payload fits in the packet */
        !           201:                if (tlen < ntohs(ph->len)) {
        !           202:                        plog(LLV_WARNING, LOCATION, NULL, 
        !           203:                              "Short payload\n");
        !           204:                        goto out;
        !           205:                }
        !           206:                
        !           207:                plog(LLV_DEBUG, LOCATION, NULL, "Seen payload %d\n", np);
        !           208:                plogdump(LLV_DEBUG, ph, ntohs(ph->len));
        !           209: 
        !           210:                switch(np) {
        !           211:                case ISAKMP_NPTYPE_HASH: {
        !           212:                        vchar_t *check;
        !           213:                        vchar_t *payload;
        !           214:                        size_t plen;
        !           215:                        struct isakmp_gen *nph;
        !           216: 
        !           217:                        plen = ntohs(ph->len);
        !           218:                        nph = (struct isakmp_gen *)((char *)ph + plen);
        !           219:                        plen = ntohs(nph->len);
        !           220: 
        !           221:                        if ((payload = vmalloc(plen)) == NULL) {
        !           222:                                plog(LLV_ERROR, LOCATION, NULL, 
        !           223:                                    "Cannot allocate memory\n");
        !           224:                                goto out;
        !           225:                        }
        !           226:                        memcpy(payload->v, nph, plen);
        !           227: 
        !           228:                        if ((check = oakley_compute_hash1(iph1, 
        !           229:                            packet->msgid, payload)) == NULL) {
        !           230:                                plog(LLV_ERROR, LOCATION, NULL, 
        !           231:                                    "Cannot compute hash\n");
        !           232:                                vfree(payload);
        !           233:                                goto out;
        !           234:                        }
        !           235: 
        !           236:                        if (memcmp(ph + 1, check->v, check->l) != 0) {
        !           237:                                plog(LLV_ERROR, LOCATION, NULL, 
        !           238:                                    "Hash verification failed\n");
        !           239:                                vfree(payload);
        !           240:                                vfree(check);
        !           241:                                goto out;
        !           242:                        }
        !           243:                        vfree(payload);
        !           244:                        vfree(check);
        !           245:                        break;
        !           246:                }
        !           247:                case ISAKMP_NPTYPE_ATTR: {
        !           248:                        struct isakmp_pl_attr *attrpl;
        !           249: 
        !           250:                        attrpl = (struct isakmp_pl_attr *)ph;
        !           251:                        isakmp_cfg_attr_r(iph1, packet->msgid, attrpl);
        !           252: 
        !           253:                        break;
        !           254:                }
        !           255:                default:
        !           256:                         plog(LLV_WARNING, LOCATION, NULL, 
        !           257:                              "Unexpected next payload %d\n", np);
        !           258:                         /* Skip to the next payload */
        !           259:                         break;
        !           260:                }
        !           261: 
        !           262:                /* Move to the next payload */
        !           263:                np = ph->np;
        !           264:                tlen -= ntohs(ph->len);
        !           265:                npp = (char *)ph;
        !           266:                ph = (struct isakmp_gen *)(npp + ntohs(ph->len));
        !           267:        }
        !           268: 
        !           269: out:
        !           270:        vfree(dmsg);
        !           271: }
        !           272: 
        !           273: int
        !           274: isakmp_cfg_attr_r(iph1, msgid, attrpl) 
        !           275:        struct ph1handle *iph1;
        !           276:        u_int32_t msgid;
        !           277:        struct isakmp_pl_attr *attrpl;
        !           278: {
        !           279:        int type = attrpl->type;
        !           280: 
        !           281:        plog(LLV_DEBUG, LOCATION, NULL,
        !           282:             "Configuration exchange type %s\n", s_isakmp_cfg_ptype(type));
        !           283:        switch (type) {
        !           284:        case ISAKMP_CFG_ACK:
        !           285:                /* ignore, but this is the time to reinit the IV */
        !           286:                oakley_delivm(iph1->mode_cfg->ivm);
        !           287:                iph1->mode_cfg->ivm = NULL;
        !           288:                return 0;
        !           289:                break;
        !           290: 
        !           291:        case ISAKMP_CFG_REPLY:
        !           292:                return isakmp_cfg_reply(iph1, attrpl);
        !           293:                break;
        !           294: 
        !           295:        case ISAKMP_CFG_REQUEST:
        !           296:                iph1->msgid = msgid;
        !           297:                return isakmp_cfg_request(iph1, attrpl);
        !           298:                break;
        !           299: 
        !           300:        case ISAKMP_CFG_SET:
        !           301:                iph1->msgid = msgid;
        !           302:                return isakmp_cfg_set(iph1, attrpl);
        !           303:                break;
        !           304: 
        !           305:        default:
        !           306:                plog(LLV_WARNING, LOCATION, NULL,
        !           307:                     "Unepected configuration exchange type %d\n", type);
        !           308:                return -1;
        !           309:                break;
        !           310:        }
        !           311: 
        !           312:        return 0;
        !           313: }
        !           314: 
        !           315: int
        !           316: isakmp_cfg_reply(iph1, attrpl)
        !           317:        struct ph1handle *iph1;
        !           318:        struct isakmp_pl_attr *attrpl;
        !           319: {
        !           320:        struct isakmp_data *attr;
        !           321:        int tlen;
        !           322:        size_t alen;
        !           323:        char *npp;
        !           324:        int type;
        !           325:        struct sockaddr_in *sin;
        !           326:        int error;
        !           327: 
        !           328:        tlen = ntohs(attrpl->h.len);
        !           329:        attr = (struct isakmp_data *)(attrpl + 1);
        !           330:        tlen -= sizeof(*attrpl);
        !           331:        
        !           332:        while (tlen > 0) {
        !           333:                type = ntohs(attr->type);
        !           334: 
        !           335:                /* Handle short attributes */
        !           336:                if ((type & ISAKMP_GEN_MASK) == ISAKMP_GEN_TV) {
        !           337:                        type &= ~ISAKMP_GEN_MASK;
        !           338: 
        !           339:                        plog(LLV_DEBUG, LOCATION, NULL,
        !           340:                             "Short attribute %s = %d\n", 
        !           341:                             s_isakmp_cfg_type(type), ntohs(attr->lorv));
        !           342: 
        !           343:                        switch (type) {
        !           344:                        case XAUTH_TYPE:
        !           345:                                if ((error = xauth_attr_reply(iph1, 
        !           346:                                    attr, ntohs(attrpl->id))) != 0)
        !           347:                                        return error;
        !           348:                                break;
        !           349: 
        !           350:                        default:
        !           351:                                plog(LLV_WARNING, LOCATION, NULL,
        !           352:                                     "Ignored short attribute %s\n",
        !           353:                                     s_isakmp_cfg_type(type));
        !           354:                                break;
        !           355:                        }
        !           356: 
        !           357:                        tlen -= sizeof(*attr);
        !           358:                        attr++;
        !           359:                        continue;
        !           360:                }
        !           361: 
        !           362:                type = ntohs(attr->type);
        !           363:                alen = ntohs(attr->lorv);
        !           364: 
        !           365:                /* Check that the attribute fit in the packet */
        !           366:                if (tlen < alen) {
        !           367:                        plog(LLV_ERROR, LOCATION, NULL,
        !           368:                             "Short attribute %s\n",
        !           369:                             s_isakmp_cfg_type(type));
        !           370:                        return -1;
        !           371:                }
        !           372: 
        !           373:                plog(LLV_DEBUG, LOCATION, NULL,
        !           374:                     "Attribute %s, len %zu\n", 
        !           375:                     s_isakmp_cfg_type(type), alen);
        !           376: 
        !           377:                switch(type) {
        !           378:                case XAUTH_TYPE:
        !           379:                case XAUTH_USER_NAME:
        !           380:                case XAUTH_USER_PASSWORD:
        !           381:                case XAUTH_PASSCODE:
        !           382:                case XAUTH_MESSAGE:
        !           383:                case XAUTH_CHALLENGE:
        !           384:                case XAUTH_DOMAIN:
        !           385:                case XAUTH_STATUS:
        !           386:                case XAUTH_NEXT_PIN:
        !           387:                case XAUTH_ANSWER:
        !           388:                        if ((error = xauth_attr_reply(iph1, 
        !           389:                            attr, ntohs(attrpl->id))) != 0)
        !           390:                                return error;
        !           391:                        break;
        !           392:                case INTERNAL_IP4_ADDRESS:
        !           393:                        isakmp_cfg_getaddr4(attr, &iph1->mode_cfg->addr4);
        !           394:                        iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_ADDR4;
        !           395:                        break;
        !           396:                case INTERNAL_IP4_NETMASK:
        !           397:                        isakmp_cfg_getaddr4(attr, &iph1->mode_cfg->mask4);
        !           398:                        iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_MASK4;
        !           399:                        break;
        !           400:                case INTERNAL_IP4_DNS:
        !           401:                        isakmp_cfg_appendaddr4(attr, 
        !           402:                            &iph1->mode_cfg->dns4[iph1->mode_cfg->dns4_index],
        !           403:                            &iph1->mode_cfg->dns4_index, MAXNS);
        !           404:                        iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_DNS4;
        !           405:                        break;
        !           406:                case INTERNAL_IP4_NBNS:
        !           407:                        isakmp_cfg_appendaddr4(attr, 
        !           408:                            &iph1->mode_cfg->wins4[iph1->mode_cfg->wins4_index],
        !           409:                            &iph1->mode_cfg->wins4_index, MAXNS);
        !           410:                        iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_WINS4;
        !           411:                        break;
        !           412:                case UNITY_DEF_DOMAIN:
        !           413:                        isakmp_cfg_getstring(attr, 
        !           414:                            iph1->mode_cfg->default_domain);
        !           415:                        iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_DEFAULT_DOMAIN;
        !           416:                        break;
        !           417:                case UNITY_SPLIT_INCLUDE:
        !           418:                case UNITY_LOCAL_LAN:
        !           419:                case UNITY_SPLITDNS_NAME:
        !           420:                case UNITY_BANNER:
        !           421:                case UNITY_SAVE_PASSWD:
        !           422:                case UNITY_NATT_PORT:
        !           423:                case UNITY_PFS:
        !           424:                case UNITY_FW_TYPE:
        !           425:                case UNITY_BACKUP_SERVERS:
        !           426:                case UNITY_DDNS_HOSTNAME:
        !           427:                        isakmp_unity_reply(iph1, attr);
        !           428:                        break;
        !           429:                case INTERNAL_IP4_SUBNET:
        !           430:                case INTERNAL_ADDRESS_EXPIRY:
        !           431:                default:
        !           432:                        plog(LLV_WARNING, LOCATION, NULL,
        !           433:                             "Ignored attribute %s\n",
        !           434:                             s_isakmp_cfg_type(type));
        !           435:                        break;
        !           436:                }
        !           437: 
        !           438:                npp = (char *)attr;
        !           439:                attr = (struct isakmp_data *)(npp + sizeof(*attr) + alen);
        !           440:                tlen -= (sizeof(*attr) + alen);
        !           441:        }
        !           442: 
        !           443:        /* 
        !           444:         * Call the SA up script hook now that we have the configuration
        !           445:         * It is done at the end of phase 1 if ISAKMP mode config is not
        !           446:         * requested.
        !           447:         */
        !           448:        
        !           449:        if ((iph1->status == PHASE1ST_ESTABLISHED) && 
        !           450:            iph1->rmconf->mode_cfg) {
        !           451:                switch (iph1->approval->authmethod) {
        !           452:                case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I:
        !           453:                case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
        !           454:                /* Unimplemented */
        !           455:                case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I: 
        !           456:                case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I: 
        !           457:                case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I:
        !           458:                case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I: 
        !           459:                case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I: 
        !           460:                        script_hook(iph1, SCRIPT_PHASE1_UP);
        !           461:                        break;
        !           462:                default:
        !           463:                        break;
        !           464:                }
        !           465:        }
        !           466:                
        !           467: 
        !           468: #ifdef ENABLE_ADMINPORT
        !           469:        {
        !           470:                vchar_t *buf;
        !           471: 
        !           472:                alen = ntohs(attrpl->h.len) - sizeof(*attrpl);
        !           473:                if ((buf = vmalloc(alen)) == NULL) {
        !           474:                        plog(LLV_WARNING, LOCATION, NULL, 
        !           475:                            "Cannot allocate memory: %s\n", strerror(errno));
        !           476:                } else {
        !           477:                        memcpy(buf->v, attrpl + 1, buf->l);
        !           478:                        evt_phase1(iph1, EVT_PHASE1_MODE_CFG, buf);
        !           479:                        vfree(buf);
        !           480:                }
        !           481:        }
        !           482: #endif
        !           483: 
        !           484:        return 0;
        !           485: }
        !           486: 
        !           487: int
        !           488: isakmp_cfg_request(iph1, attrpl)
        !           489:        struct ph1handle *iph1;
        !           490:        struct isakmp_pl_attr *attrpl;
        !           491: {
        !           492:        struct isakmp_data *attr;
        !           493:        int tlen;
        !           494:        size_t alen;
        !           495:        char *npp;
        !           496:        vchar_t *payload;
        !           497:        struct isakmp_pl_attr *reply;
        !           498:        vchar_t *reply_attr;
        !           499:        int type;
        !           500:        int error = -1;
        !           501: 
        !           502:        if ((payload = vmalloc(sizeof(*reply))) == NULL) {
        !           503:                plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
        !           504:                return -1;
        !           505:        }
        !           506:        memset(payload->v, 0, sizeof(*reply));
        !           507: 
        !           508:        tlen = ntohs(attrpl->h.len);
        !           509:        attr = (struct isakmp_data *)(attrpl + 1);
        !           510:        tlen -= sizeof(*attrpl);
        !           511:        
        !           512:        while (tlen > 0) {
        !           513:                reply_attr = NULL;
        !           514:                type = ntohs(attr->type);
        !           515: 
        !           516:                /* Handle short attributes */
        !           517:                if ((type & ISAKMP_GEN_MASK) == ISAKMP_GEN_TV) {
        !           518:                        type &= ~ISAKMP_GEN_MASK;
        !           519: 
        !           520:                        plog(LLV_DEBUG, LOCATION, NULL,
        !           521:                             "Short attribute %s = %d\n", 
        !           522:                             s_isakmp_cfg_type(type), ntohs(attr->lorv));
        !           523: 
        !           524:                        switch (type) {
        !           525:                        case XAUTH_TYPE:
        !           526:                                reply_attr = isakmp_xauth_req(iph1, attr);
        !           527:                                break;
        !           528:                        default:
        !           529:                                plog(LLV_WARNING, LOCATION, NULL,
        !           530:                                     "Ignored short attribute %s\n",
        !           531:                                     s_isakmp_cfg_type(type));
        !           532:                                break;
        !           533:                        }
        !           534: 
        !           535:                        tlen -= sizeof(*attr);
        !           536:                        attr++;
        !           537: 
        !           538:                        if (reply_attr != NULL) {
        !           539:                                payload = buffer_cat(payload, reply_attr);
        !           540:                                vfree(reply_attr);
        !           541:                        }
        !           542: 
        !           543:                        continue;
        !           544:                }
        !           545: 
        !           546:                type = ntohs(attr->type);
        !           547:                alen = ntohs(attr->lorv);
        !           548: 
        !           549:                /* Check that the attribute fit in the packet */
        !           550:                if (tlen < alen) {
        !           551:                        plog(LLV_ERROR, LOCATION, NULL,
        !           552:                             "Short attribute %s\n",
        !           553:                             s_isakmp_cfg_type(type));
        !           554:                        goto end;
        !           555:                }
        !           556: 
        !           557:                plog(LLV_DEBUG, LOCATION, NULL,
        !           558:                     "Attribute %s, len %zu\n",
        !           559:                     s_isakmp_cfg_type(type), alen);
        !           560: 
        !           561:                switch(type) {
        !           562:                case INTERNAL_IP4_ADDRESS:
        !           563:                case INTERNAL_IP4_NETMASK:
        !           564:                case INTERNAL_IP4_DNS:
        !           565:                case INTERNAL_IP4_NBNS:
        !           566:                case INTERNAL_IP4_SUBNET:
        !           567:                        reply_attr = isakmp_cfg_net(iph1, attr);
        !           568:                        break;
        !           569: 
        !           570:                case XAUTH_TYPE:
        !           571:                case XAUTH_USER_NAME:
        !           572:                case XAUTH_USER_PASSWORD:
        !           573:                case XAUTH_PASSCODE:
        !           574:                case XAUTH_MESSAGE:
        !           575:                case XAUTH_CHALLENGE:
        !           576:                case XAUTH_DOMAIN:
        !           577:                case XAUTH_STATUS:
        !           578:                case XAUTH_NEXT_PIN:
        !           579:                case XAUTH_ANSWER:
        !           580:                        reply_attr = isakmp_xauth_req(iph1, attr);
        !           581:                        break;
        !           582: 
        !           583:                case APPLICATION_VERSION:
        !           584:                        reply_attr = isakmp_cfg_string(iph1, 
        !           585:                            attr, ISAKMP_CFG_RACOON_VERSION);
        !           586:                        break;
        !           587: 
        !           588:                case UNITY_BANNER:
        !           589:                case UNITY_PFS:
        !           590:                case UNITY_SAVE_PASSWD:
        !           591:                case UNITY_DEF_DOMAIN:
        !           592:                case UNITY_DDNS_HOSTNAME:
        !           593:                case UNITY_FW_TYPE:
        !           594:                case UNITY_SPLITDNS_NAME:
        !           595:                case UNITY_SPLIT_INCLUDE:
        !           596:                case UNITY_LOCAL_LAN:
        !           597:                case UNITY_NATT_PORT:
        !           598:                case UNITY_BACKUP_SERVERS:
        !           599:                        reply_attr = isakmp_unity_req(iph1, attr);
        !           600:                        break;
        !           601: 
        !           602:                case INTERNAL_ADDRESS_EXPIRY:
        !           603:                default:
        !           604:                        plog(LLV_WARNING, LOCATION, NULL,
        !           605:                             "Ignored attribute %s\n",
        !           606:                             s_isakmp_cfg_type(type));
        !           607:                        break;
        !           608:                }
        !           609: 
        !           610:                npp = (char *)attr;
        !           611:                attr = (struct isakmp_data *)(npp + sizeof(*attr) + alen);
        !           612:                tlen -= (sizeof(*attr) + alen);
        !           613: 
        !           614:                if (reply_attr != NULL) {
        !           615:                        payload = buffer_cat(payload, reply_attr);
        !           616:                        vfree(reply_attr);
        !           617:                }
        !           618: 
        !           619:        }
        !           620: 
        !           621:        reply = (struct isakmp_pl_attr *)payload->v;
        !           622:        reply->h.len = htons(payload->l);
        !           623:        reply->type = ISAKMP_CFG_REPLY;
        !           624:        reply->id = attrpl->id;
        !           625: 
        !           626:        plog(LLV_DEBUG, LOCATION, NULL, 
        !           627:                    "Sending MODE_CFG REPLY\n");
        !           628: 
        !           629:        error = isakmp_cfg_send(iph1, payload, 
        !           630:            ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 0);
        !           631: 
        !           632:        if (iph1->status == PHASE1ST_ESTABLISHED) {
        !           633:                switch (iph1->approval->authmethod) {
        !           634:                case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R:
        !           635:                case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R:
        !           636:                /* Unimplemented */
        !           637:                case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R: 
        !           638:                case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R: 
        !           639:                case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R:
        !           640:                case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R: 
        !           641:                case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R: 
        !           642:                        script_hook(iph1, SCRIPT_PHASE1_UP);
        !           643:                        break;
        !           644:                default:
        !           645:                        break;
        !           646:                }
        !           647:        }
        !           648:        
        !           649: end:
        !           650:        vfree(payload);
        !           651: 
        !           652:        return error;
        !           653: }
        !           654: 
        !           655: int
        !           656: isakmp_cfg_set(iph1, attrpl)
        !           657:        struct ph1handle *iph1;
        !           658:        struct isakmp_pl_attr *attrpl;
        !           659: {
        !           660:        struct isakmp_data *attr;
        !           661:        int tlen;
        !           662:        size_t alen;
        !           663:        char *npp;
        !           664:        vchar_t *payload;
        !           665:        struct isakmp_pl_attr *reply;
        !           666:        vchar_t *reply_attr;
        !           667:        int type;
        !           668:        int error = -1;
        !           669: 
        !           670:        if ((payload = vmalloc(sizeof(*reply))) == NULL) {
        !           671:                plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
        !           672:                return -1;
        !           673:        }
        !           674:        memset(payload->v, 0, sizeof(*reply));
        !           675: 
        !           676:        tlen = ntohs(attrpl->h.len);
        !           677:        attr = (struct isakmp_data *)(attrpl + 1);
        !           678:        tlen -= sizeof(*attrpl);
        !           679:        
        !           680:        /* 
        !           681:         * We should send ack for the attributes we accepted 
        !           682:         */
        !           683:        while (tlen > 0) {
        !           684:                reply_attr = NULL;
        !           685:                type = ntohs(attr->type);
        !           686: 
        !           687:                plog(LLV_DEBUG, LOCATION, NULL,
        !           688:                     "Attribute %s\n", 
        !           689:                     s_isakmp_cfg_type(type & ~ISAKMP_GEN_MASK));
        !           690:                
        !           691:                switch (type & ~ISAKMP_GEN_MASK) {
        !           692:                case XAUTH_STATUS:
        !           693:                        reply_attr = isakmp_xauth_set(iph1, attr);
        !           694:                        break;
        !           695:                default:
        !           696:                        plog(LLV_DEBUG, LOCATION, NULL,
        !           697:                             "Unexpected SET attribute %s\n", 
        !           698:                             s_isakmp_cfg_type(type & ~ISAKMP_GEN_MASK));
        !           699:                        break;
        !           700:                }
        !           701: 
        !           702:                if (reply_attr != NULL) {
        !           703:                        payload = buffer_cat(payload, reply_attr);
        !           704:                        vfree(reply_attr);
        !           705:                }
        !           706: 
        !           707:                /* 
        !           708:                 * Move to next attribute. If we run out of the packet, 
        !           709:                 * tlen becomes negative and we exit. 
        !           710:                 */
        !           711:                if ((type & ISAKMP_GEN_MASK) == ISAKMP_GEN_TV) {
        !           712:                        tlen -= sizeof(*attr);
        !           713:                        attr++;
        !           714:                } else {
        !           715:                        alen = ntohs(attr->lorv);
        !           716:                        tlen -= (sizeof(*attr) + alen);
        !           717:                        npp = (char *)attr;
        !           718:                        attr = (struct isakmp_data *)
        !           719:                            (npp + sizeof(*attr) + alen);
        !           720:                }
        !           721:        }
        !           722: 
        !           723:        reply = (struct isakmp_pl_attr *)payload->v;
        !           724:        reply->h.len = htons(payload->l);
        !           725:        reply->type = ISAKMP_CFG_ACK;
        !           726:        reply->id = attrpl->id;
        !           727: 
        !           728:        plog(LLV_DEBUG, LOCATION, NULL,
        !           729:                     "Sending MODE_CFG ACK\n");
        !           730: 
        !           731:        error = isakmp_cfg_send(iph1, payload, 
        !           732:            ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 0);
        !           733: 
        !           734:        if (iph1->mode_cfg->flags & ISAKMP_CFG_DELETE_PH1) {
        !           735:                if (iph1->status == PHASE1ST_ESTABLISHED ||
        !           736:                    iph1->status == PHASE1ST_DYING)
        !           737:                        isakmp_info_send_d1(iph1);
        !           738:                remph1(iph1);
        !           739:                delph1(iph1);
        !           740:                iph1 = NULL;
        !           741:        }
        !           742: end:
        !           743:        vfree(payload);
        !           744: 
        !           745:        /* 
        !           746:         * If required, request ISAKMP mode config information
        !           747:         */
        !           748:        if ((iph1 != NULL) && (iph1->rmconf->mode_cfg) && (error == 0))
        !           749:                error = isakmp_cfg_getconfig(iph1);
        !           750: 
        !           751:        return error;
        !           752: }
        !           753: 
        !           754: 
        !           755: static vchar_t *
        !           756: buffer_cat(s, append)
        !           757:        vchar_t *s;
        !           758:        vchar_t *append;
        !           759: {
        !           760:        vchar_t *new;
        !           761: 
        !           762:        new = vmalloc(s->l + append->l);
        !           763:        if (new == NULL) {
        !           764:                plog(LLV_ERROR, LOCATION, NULL, 
        !           765:                    "Cannot allocate memory\n");
        !           766:                return s;
        !           767:        }
        !           768: 
        !           769:        memcpy(new->v, s->v, s->l);
        !           770:        memcpy(new->v + s->l, append->v, append->l);
        !           771: 
        !           772:        vfree(s);
        !           773:        return new;
        !           774: }
        !           775: 
        !           776: static vchar_t *
        !           777: isakmp_cfg_net(iph1, attr)
        !           778:        struct ph1handle *iph1;
        !           779:        struct isakmp_data *attr;
        !           780: {
        !           781:        int type;
        !           782:        int confsource;
        !           783:        in_addr_t addr4;
        !           784: 
        !           785:        type = ntohs(attr->type);
        !           786: 
        !           787:        /* 
        !           788:         * Don't give an address to a peer that did not succeed Xauth
        !           789:         */
        !           790:        if (xauth_check(iph1) != 0) {
        !           791:                plog(LLV_ERROR, LOCATION, NULL,
        !           792:                    "Attempt to start phase config whereas Xauth failed\n");
        !           793:                return NULL;
        !           794:        }
        !           795: 
        !           796:        confsource = isakmp_cfg_config.confsource;
        !           797:        /*
        !           798:         * If we have to fall back to a local
        !           799:         * configuration source, we will jump
        !           800:         * back to this point.
        !           801:         */
        !           802: retry_source:
        !           803: 
        !           804:        switch(type) {
        !           805:        case INTERNAL_IP4_ADDRESS:
        !           806:                switch(confsource) {
        !           807: #ifdef HAVE_LIBLDAP
        !           808:                case ISAKMP_CFG_CONF_LDAP:
        !           809:                        if (iph1->mode_cfg->flags & ISAKMP_CFG_ADDR4_EXTERN)
        !           810:                            break;
        !           811:                        plog(LLV_INFO, LOCATION, NULL, 
        !           812:                            "No IP from LDAP, using local pool\n");
        !           813:                        /* FALLTHROUGH */
        !           814:                        confsource = ISAKMP_CFG_CONF_LOCAL;
        !           815:                        goto retry_source;
        !           816: #endif
        !           817: #ifdef HAVE_LIBRADIUS
        !           818:                case ISAKMP_CFG_CONF_RADIUS:
        !           819:                        if ((iph1->mode_cfg->flags & ISAKMP_CFG_ADDR4_EXTERN)
        !           820:                            && (iph1->mode_cfg->addr4.s_addr != htonl(-2)))
        !           821:                            /*
        !           822:                             * -2 is 255.255.255.254, RADIUS uses that
        !           823:                             * to instruct the NAS to use a local pool
        !           824:                             */
        !           825:                            break;
        !           826:                        plog(LLV_INFO, LOCATION, NULL, 
        !           827:                            "No IP from RADIUS, using local pool\n");
        !           828:                        /* FALLTHROUGH */
        !           829:                        confsource = ISAKMP_CFG_CONF_LOCAL;
        !           830:                        goto retry_source;
        !           831: #endif
        !           832:                case ISAKMP_CFG_CONF_LOCAL:
        !           833:                        if (isakmp_cfg_getport(iph1) == -1) {
        !           834:                                plog(LLV_ERROR, LOCATION, NULL, 
        !           835:                                    "Port pool depleted\n");
        !           836:                                break;
        !           837:                        }
        !           838: 
        !           839:                        iph1->mode_cfg->addr4.s_addr = 
        !           840:                            htonl(ntohl(isakmp_cfg_config.network4) 
        !           841:                            + iph1->mode_cfg->port);
        !           842:                        iph1->mode_cfg->flags |= ISAKMP_CFG_ADDR4_LOCAL;
        !           843:                        break;
        !           844: 
        !           845:                default:
        !           846:                        plog(LLV_ERROR, LOCATION, NULL, 
        !           847:                            "Unexpected confsource\n");
        !           848:                }
        !           849:                        
        !           850:                if (isakmp_cfg_accounting(iph1, ISAKMP_CFG_LOGIN) != 0)
        !           851:                        plog(LLV_ERROR, LOCATION, NULL, "Accounting failed\n");
        !           852: 
        !           853:                return isakmp_cfg_addr4(iph1, 
        !           854:                    attr, &iph1->mode_cfg->addr4.s_addr);
        !           855:                break;
        !           856: 
        !           857:        case INTERNAL_IP4_NETMASK:
        !           858:                switch(confsource) {
        !           859: #ifdef HAVE_LIBLDAP
        !           860:                case ISAKMP_CFG_CONF_LDAP:
        !           861:                        if (iph1->mode_cfg->flags & ISAKMP_CFG_MASK4_EXTERN)
        !           862:                                break;
        !           863:                        plog(LLV_INFO, LOCATION, NULL, 
        !           864:                            "No mask from LDAP, using local pool\n");
        !           865:                        /* FALLTHROUGH */
        !           866:                        confsource = ISAKMP_CFG_CONF_LOCAL;
        !           867:                        goto retry_source;
        !           868: #endif
        !           869: #ifdef HAVE_LIBRADIUS
        !           870:                case ISAKMP_CFG_CONF_RADIUS:
        !           871:                        if (iph1->mode_cfg->flags & ISAKMP_CFG_MASK4_EXTERN)
        !           872:                                break;
        !           873:                        plog(LLV_INFO, LOCATION, NULL, 
        !           874:                            "No mask from RADIUS, using local pool\n");
        !           875:                        /* FALLTHROUGH */
        !           876:                        confsource = ISAKMP_CFG_CONF_LOCAL;
        !           877:                        goto retry_source;
        !           878: #endif
        !           879:                case ISAKMP_CFG_CONF_LOCAL:
        !           880:                        iph1->mode_cfg->mask4.s_addr 
        !           881:                            = isakmp_cfg_config.netmask4;
        !           882:                        iph1->mode_cfg->flags |= ISAKMP_CFG_MASK4_LOCAL;
        !           883:                        break;
        !           884: 
        !           885:                default:
        !           886:                        plog(LLV_ERROR, LOCATION, NULL, 
        !           887:                            "Unexpected confsource\n");
        !           888:                }
        !           889:                return isakmp_cfg_addr4(iph1, attr, 
        !           890:                    &iph1->mode_cfg->mask4.s_addr);
        !           891:                break;
        !           892: 
        !           893:        case INTERNAL_IP4_DNS:
        !           894:                return isakmp_cfg_addr4_list(iph1, 
        !           895:                    attr, &isakmp_cfg_config.dns4[0], 
        !           896:                    isakmp_cfg_config.dns4_index);
        !           897:                break;
        !           898: 
        !           899:        case INTERNAL_IP4_NBNS:
        !           900:                return isakmp_cfg_addr4_list(iph1, 
        !           901:                    attr, &isakmp_cfg_config.nbns4[0], 
        !           902:                    isakmp_cfg_config.nbns4_index);
        !           903:                break;
        !           904: 
        !           905:        case INTERNAL_IP4_SUBNET:
        !           906:                if(isakmp_cfg_config.splitnet_count > 0){
        !           907:                        return isakmp_cfg_addrnet4(iph1, attr,
        !           908:                                                    &isakmp_cfg_config.splitnet_list->network.addr4.s_addr,
        !           909:                                                    &isakmp_cfg_config.splitnet_list->network.mask4.s_addr);
        !           910:                }else{
        !           911:                        plog(LLV_INFO, LOCATION, NULL,
        !           912:                             "%s requested but no splitnet in configuration\n",
        !           913:                             s_isakmp_cfg_type(type));
        !           914:                }
        !           915:                break;
        !           916: 
        !           917:        default:
        !           918:                plog(LLV_ERROR, LOCATION, NULL, "Unexpected type %d\n", type);
        !           919:                break;
        !           920:        }
        !           921:        return NULL;
        !           922: }
        !           923: 
        !           924: #if 0
        !           925: static vchar_t *
        !           926: isakmp_cfg_void(iph1, attr)
        !           927:        struct ph1handle *iph1;
        !           928:        struct isakmp_data *attr;
        !           929: {
        !           930:        vchar_t *buffer;
        !           931:        struct isakmp_data *new;
        !           932: 
        !           933:        if ((buffer = vmalloc(sizeof(*attr))) == NULL) {
        !           934:                plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
        !           935:                return NULL;
        !           936:        }
        !           937: 
        !           938:        new = (struct isakmp_data *)buffer->v;
        !           939: 
        !           940:        new->type = attr->type;
        !           941:        new->lorv = htons(0);
        !           942: 
        !           943:        return buffer;
        !           944: }
        !           945: #endif
        !           946: 
        !           947: vchar_t *
        !           948: isakmp_cfg_copy(iph1, attr)
        !           949:        struct ph1handle *iph1;
        !           950:        struct isakmp_data *attr;
        !           951: {
        !           952:        vchar_t *buffer;
        !           953:        size_t len = 0;
        !           954: 
        !           955:        if ((ntohs(attr->type) & ISAKMP_GEN_MASK) == ISAKMP_GEN_TLV)
        !           956:                len = ntohs(attr->lorv);
        !           957: 
        !           958:        if ((buffer = vmalloc(sizeof(*attr) + len)) == NULL) {
        !           959:                plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
        !           960:                return NULL;
        !           961:        }
        !           962: 
        !           963:        memcpy(buffer->v, attr, sizeof(*attr) + ntohs(attr->lorv));
        !           964: 
        !           965:        return buffer;
        !           966: }
        !           967: 
        !           968: vchar_t *
        !           969: isakmp_cfg_short(iph1, attr, value)
        !           970:        struct ph1handle *iph1;
        !           971:        struct isakmp_data *attr;
        !           972:        int value;
        !           973: {
        !           974:        vchar_t *buffer;
        !           975:        struct isakmp_data *new;
        !           976:        int type;
        !           977: 
        !           978:        if ((buffer = vmalloc(sizeof(*attr))) == NULL) {
        !           979:                plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
        !           980:                return NULL;
        !           981:        }
        !           982: 
        !           983:        new = (struct isakmp_data *)buffer->v;
        !           984:        type = ntohs(attr->type) & ~ISAKMP_GEN_MASK;
        !           985: 
        !           986:        new->type = htons(type | ISAKMP_GEN_TV);
        !           987:        new->lorv = htons(value);
        !           988: 
        !           989:        return buffer;
        !           990: }
        !           991: 
        !           992: vchar_t *
        !           993: isakmp_cfg_varlen(iph1, attr, string, len)
        !           994:        struct ph1handle *iph1;
        !           995:        struct isakmp_data *attr;
        !           996:        char *string;
        !           997:        size_t len;
        !           998: {
        !           999:        vchar_t *buffer;
        !          1000:        struct isakmp_data *new;
        !          1001:        char *data;
        !          1002: 
        !          1003:        if ((buffer = vmalloc(sizeof(*attr) + len)) == NULL) {
        !          1004:                plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
        !          1005:                return NULL;
        !          1006:        }
        !          1007: 
        !          1008:        new = (struct isakmp_data *)buffer->v;
        !          1009: 
        !          1010:        new->type = attr->type;
        !          1011:        new->lorv = htons(len);
        !          1012:        data = (char *)(new + 1);
        !          1013: 
        !          1014:        memcpy(data, string, len);
        !          1015:        
        !          1016:        return buffer;
        !          1017: }
        !          1018: vchar_t *
        !          1019: isakmp_cfg_string(iph1, attr, string)
        !          1020:        struct ph1handle *iph1;
        !          1021:        struct isakmp_data *attr;
        !          1022:        char *string;
        !          1023: {
        !          1024:        size_t len = strlen(string);
        !          1025:        return isakmp_cfg_varlen(iph1, attr, string, len);
        !          1026: }
        !          1027: 
        !          1028: static vchar_t *
        !          1029: isakmp_cfg_addr4(iph1, attr, addr)
        !          1030:        struct ph1handle *iph1;
        !          1031:        struct isakmp_data *attr;
        !          1032:        in_addr_t *addr;
        !          1033: {
        !          1034:        vchar_t *buffer;
        !          1035:        struct isakmp_data *new;
        !          1036:        size_t len;
        !          1037: 
        !          1038:        len = sizeof(*addr);
        !          1039:        if ((buffer = vmalloc(sizeof(*attr) + len)) == NULL) {
        !          1040:                plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
        !          1041:                return NULL;
        !          1042:        }
        !          1043: 
        !          1044:        new = (struct isakmp_data *)buffer->v;
        !          1045: 
        !          1046:        new->type = attr->type;
        !          1047:        new->lorv = htons(len);
        !          1048:        memcpy(new + 1, addr, len);
        !          1049:        
        !          1050:        return buffer;
        !          1051: }
        !          1052: 
        !          1053: static vchar_t *
        !          1054: isakmp_cfg_addrnet4(iph1, attr, addr, mask)
        !          1055:        struct ph1handle *iph1;
        !          1056:        struct isakmp_data *attr;
        !          1057:        in_addr_t *addr;
        !          1058:        in_addr_t *mask;
        !          1059: {
        !          1060:        vchar_t *buffer;
        !          1061:        struct isakmp_data *new;
        !          1062:        size_t len;
        !          1063:        in_addr_t netbuff[2];
        !          1064: 
        !          1065:        len = sizeof(netbuff);
        !          1066:        if ((buffer = vmalloc(sizeof(*attr) + len)) == NULL) {
        !          1067:                plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
        !          1068:                return NULL;
        !          1069:        }
        !          1070: 
        !          1071:        new = (struct isakmp_data *)buffer->v;
        !          1072: 
        !          1073:        new->type = attr->type;
        !          1074:        new->lorv = htons(len);
        !          1075:        netbuff[0]=*addr;
        !          1076:        netbuff[1]=*mask;
        !          1077:        memcpy(new + 1, netbuff, len);
        !          1078:        
        !          1079:        return buffer;
        !          1080: }
        !          1081: 
        !          1082: 
        !          1083: static vchar_t *
        !          1084: isakmp_cfg_addr4_list(iph1, attr, addr, nbr)
        !          1085:        struct ph1handle *iph1;
        !          1086:        struct isakmp_data *attr;
        !          1087:        in_addr_t *addr;
        !          1088:        int nbr;
        !          1089: {
        !          1090:        int error = -1;
        !          1091:        vchar_t *buffer = NULL;
        !          1092:        vchar_t *bufone = NULL;
        !          1093:        struct isakmp_data *new;
        !          1094:        size_t len;
        !          1095:        int i;
        !          1096: 
        !          1097:        len = sizeof(*addr);
        !          1098:        if ((buffer = vmalloc(0)) == NULL) {
        !          1099:                plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
        !          1100:                goto out;
        !          1101:        }
        !          1102:        for(i = 0; i < nbr; i++) {
        !          1103:                if ((bufone = vmalloc(sizeof(*attr) + len)) == NULL) {
        !          1104:                        plog(LLV_ERROR, LOCATION, NULL, 
        !          1105:                            "Cannot allocate memory\n");
        !          1106:                        goto out;
        !          1107:                }
        !          1108:                new = (struct isakmp_data *)bufone->v;
        !          1109:                new->type = attr->type;
        !          1110:                new->lorv = htons(len);
        !          1111:                memcpy(new + 1, &addr[i], len);
        !          1112:                new += (len + sizeof(*attr));
        !          1113:                buffer = buffer_cat(buffer, bufone);
        !          1114:                vfree(bufone);
        !          1115:        }
        !          1116: 
        !          1117:        error = 0;
        !          1118: 
        !          1119: out:
        !          1120:        if ((error != 0) && (buffer != NULL)) {
        !          1121:                vfree(buffer);
        !          1122:                buffer = NULL;
        !          1123:        }
        !          1124: 
        !          1125:        return buffer;
        !          1126: }
        !          1127: 
        !          1128: struct isakmp_ivm *
        !          1129: isakmp_cfg_newiv(iph1, msgid)
        !          1130:        struct ph1handle *iph1;
        !          1131:        u_int32_t msgid;
        !          1132: {
        !          1133:        struct isakmp_cfg_state *ics = iph1->mode_cfg;
        !          1134: 
        !          1135:        if (ics == NULL) {
        !          1136:                plog(LLV_ERROR, LOCATION, NULL,
        !          1137:                    "isakmp_cfg_newiv called without mode config state\n");
        !          1138:                return NULL;
        !          1139:        }
        !          1140: 
        !          1141:        if (ics->ivm != NULL)
        !          1142:                oakley_delivm(ics->ivm);
        !          1143: 
        !          1144:        ics->ivm = oakley_newiv2(iph1, msgid);
        !          1145:        ics->last_msgid = msgid;
        !          1146: 
        !          1147:        return ics->ivm;
        !          1148: }
        !          1149: 
        !          1150: /* Derived from isakmp_info_send_common */
        !          1151: int
        !          1152: isakmp_cfg_send(iph1, payload, np, flags, new_exchange)
        !          1153:        struct ph1handle *iph1;
        !          1154:        vchar_t *payload;
        !          1155:        u_int32_t np;
        !          1156:        int flags;
        !          1157:        int new_exchange;
        !          1158: {
        !          1159:        struct ph2handle *iph2 = NULL;
        !          1160:        vchar_t *hash = NULL;
        !          1161:        struct isakmp *isakmp;
        !          1162:        struct isakmp_gen *gen;
        !          1163:        char *p;
        !          1164:        int tlen;
        !          1165:        int error = -1;
        !          1166:        struct isakmp_cfg_state *ics = iph1->mode_cfg;
        !          1167: 
        !          1168:        /* Check if phase 1 is established */
        !          1169:        if ((iph1->status < PHASE1ST_ESTABLISHED) ||
        !          1170:            (iph1->local == NULL) ||
        !          1171:            (iph1->remote == NULL)) {
        !          1172:                plog(LLV_ERROR, LOCATION, NULL, 
        !          1173:                    "ISAKMP mode config exchange with immature phase 1\n");
        !          1174:                goto end;
        !          1175:        }
        !          1176: 
        !          1177:        /* add new entry to isakmp status table */
        !          1178:        iph2 = newph2();
        !          1179:        if (iph2 == NULL)
        !          1180:                goto end;
        !          1181: 
        !          1182:        iph2->dst = dupsaddr(iph1->remote);
        !          1183:        if (iph2->dst == NULL) {
        !          1184:                delph2(iph2);
        !          1185:                goto end;
        !          1186:        }
        !          1187:        iph2->src = dupsaddr(iph1->local);
        !          1188:        if (iph2->src == NULL) {
        !          1189:                delph2(iph2);
        !          1190:                goto end;
        !          1191:        }
        !          1192: 
        !          1193:        iph2->side = INITIATOR;
        !          1194:        iph2->status = PHASE2ST_START;
        !          1195: 
        !          1196:        if (new_exchange)
        !          1197:                iph2->msgid = isakmp_newmsgid2(iph1);
        !          1198:        else
        !          1199:                iph2->msgid = iph1->msgid;
        !          1200: 
        !          1201:        /* get IV and HASH(1) if skeyid_a was generated. */
        !          1202:        if (iph1->skeyid_a != NULL) {
        !          1203:                if (new_exchange) {
        !          1204:                        if (isakmp_cfg_newiv(iph1, iph2->msgid) == NULL) {
        !          1205:                                delph2(iph2);
        !          1206:                                goto end;
        !          1207:                        }
        !          1208:                }
        !          1209: 
        !          1210:                /* generate HASH(1) */
        !          1211:                hash = oakley_compute_hash1(iph1, iph2->msgid, payload);
        !          1212:                if (hash == NULL) {
        !          1213:                        delph2(iph2);
        !          1214:                        goto end;
        !          1215:                }
        !          1216: 
        !          1217:                /* initialized total buffer length */
        !          1218:                tlen = hash->l;
        !          1219:                tlen += sizeof(*gen);
        !          1220:        } else {
        !          1221:                /* IKE-SA is not established */
        !          1222:                hash = NULL;
        !          1223: 
        !          1224:                /* initialized total buffer length */
        !          1225:                tlen = 0;
        !          1226:        }
        !          1227:        if ((flags & ISAKMP_FLAG_A) == 0)
        !          1228:                iph2->flags = (hash == NULL ? 0 : ISAKMP_FLAG_E);
        !          1229:        else
        !          1230:                iph2->flags = (hash == NULL ? 0 : ISAKMP_FLAG_A);
        !          1231: 
        !          1232:        insph2(iph2);
        !          1233:        bindph12(iph1, iph2);
        !          1234: 
        !          1235:        tlen += sizeof(*isakmp) + payload->l;
        !          1236: 
        !          1237:        /* create buffer for isakmp payload */
        !          1238:        iph2->sendbuf = vmalloc(tlen);
        !          1239:        if (iph2->sendbuf == NULL) { 
        !          1240:                plog(LLV_ERROR, LOCATION, NULL,
        !          1241:                        "failed to get buffer to send.\n");
        !          1242:                goto err;
        !          1243:        }
        !          1244: 
        !          1245:        /* create isakmp header */
        !          1246:        isakmp = (struct isakmp *)iph2->sendbuf->v;
        !          1247:        memcpy(&isakmp->i_ck, &iph1->index.i_ck, sizeof(cookie_t));
        !          1248:        memcpy(&isakmp->r_ck, &iph1->index.r_ck, sizeof(cookie_t));
        !          1249:        isakmp->np = hash == NULL ? (np & 0xff) : ISAKMP_NPTYPE_HASH;
        !          1250:        isakmp->v = iph1->version;
        !          1251:        isakmp->etype = ISAKMP_ETYPE_CFG;
        !          1252:        isakmp->flags = iph2->flags;
        !          1253:        memcpy(&isakmp->msgid, &iph2->msgid, sizeof(isakmp->msgid));
        !          1254:        isakmp->len = htonl(tlen);
        !          1255:        p = (char *)(isakmp + 1);
        !          1256: 
        !          1257:        /* create HASH payload */
        !          1258:        if (hash != NULL) {
        !          1259:                gen = (struct isakmp_gen *)p;
        !          1260:                gen->np = np & 0xff;
        !          1261:                gen->len = htons(sizeof(*gen) + hash->l);
        !          1262:                p += sizeof(*gen);
        !          1263:                memcpy(p, hash->v, hash->l);
        !          1264:                p += hash->l;
        !          1265:        }
        !          1266: 
        !          1267:        /* add payload */
        !          1268:        memcpy(p, payload->v, payload->l);
        !          1269:        p += payload->l;
        !          1270: 
        !          1271: #ifdef HAVE_PRINT_ISAKMP_C
        !          1272:        isakmp_printpacket(iph2->sendbuf, iph1->local, iph1->remote, 1);
        !          1273: #endif
        !          1274:        
        !          1275:        plog(LLV_DEBUG, LOCATION, NULL, "MODE_CFG packet to send\n");
        !          1276:        plogdump(LLV_DEBUG, iph2->sendbuf->v, iph2->sendbuf->l);
        !          1277: 
        !          1278:        /* encoding */
        !          1279:        if (ISSET(isakmp->flags, ISAKMP_FLAG_E)) {
        !          1280:                vchar_t *tmp;
        !          1281: 
        !          1282:                tmp = oakley_do_encrypt(iph2->ph1, iph2->sendbuf, 
        !          1283:                        ics->ivm->ive, ics->ivm->iv);
        !          1284:                VPTRINIT(iph2->sendbuf);
        !          1285:                if (tmp == NULL)
        !          1286:                        goto err;
        !          1287:                iph2->sendbuf = tmp;
        !          1288:        }
        !          1289: 
        !          1290:        /* HDR*, HASH(1), ATTR */
        !          1291:        if (isakmp_send(iph2->ph1, iph2->sendbuf) < 0) {
        !          1292:                VPTRINIT(iph2->sendbuf);
        !          1293:                goto err;
        !          1294:        }
        !          1295: 
        !          1296:        plog(LLV_DEBUG, LOCATION, NULL,
        !          1297:                "sendto mode config %s.\n", s_isakmp_nptype(np));
        !          1298: 
        !          1299:        /*
        !          1300:         * XXX We might need to resend the message...
        !          1301:         */
        !          1302: 
        !          1303:        error = 0;
        !          1304:        VPTRINIT(iph2->sendbuf);
        !          1305: 
        !          1306: err:
        !          1307:        if (iph2->sendbuf != NULL)
        !          1308:                vfree(iph2->sendbuf);
        !          1309: 
        !          1310:        remph2(iph2);
        !          1311:        delph2(iph2);
        !          1312: end:
        !          1313:        if (hash)
        !          1314:                vfree(hash);
        !          1315:        return error;
        !          1316: }
        !          1317: 
        !          1318: 
        !          1319: void 
        !          1320: isakmp_cfg_rmstate(iph1)
        !          1321:        struct ph1handle *iph1;
        !          1322: {
        !          1323:        struct isakmp_cfg_state *state = iph1->mode_cfg;
        !          1324: 
        !          1325:        if (isakmp_cfg_accounting(iph1, ISAKMP_CFG_LOGOUT) != 0)
        !          1326:                plog(LLV_ERROR, LOCATION, NULL, "Accounting failed\n");
        !          1327: 
        !          1328:        if (state->flags & ISAKMP_CFG_PORT_ALLOCATED)
        !          1329:                isakmp_cfg_putport(iph1, state->port);  
        !          1330: 
        !          1331:        /* Delete the IV if it's still there */
        !          1332:        if(iph1->mode_cfg->ivm) {
        !          1333:                oakley_delivm(iph1->mode_cfg->ivm);
        !          1334:                iph1->mode_cfg->ivm = NULL;
        !          1335:        }
        !          1336: 
        !          1337:        /* Free any allocated splitnet lists */
        !          1338:        if(iph1->mode_cfg->split_include != NULL)
        !          1339:                splitnet_list_free(iph1->mode_cfg->split_include,
        !          1340:                        &iph1->mode_cfg->include_count);
        !          1341:        if(iph1->mode_cfg->split_local != NULL)
        !          1342:                splitnet_list_free(iph1->mode_cfg->split_local,
        !          1343:                        &iph1->mode_cfg->local_count);
        !          1344: 
        !          1345:        xauth_rmstate(&state->xauth);
        !          1346: 
        !          1347:        racoon_free(state);
        !          1348:        iph1->mode_cfg = NULL;
        !          1349: 
        !          1350:        return;
        !          1351: }
        !          1352: 
        !          1353: struct isakmp_cfg_state *
        !          1354: isakmp_cfg_mkstate(void) 
        !          1355: {
        !          1356:        struct isakmp_cfg_state *state;
        !          1357: 
        !          1358:        if ((state = racoon_malloc(sizeof(*state))) == NULL) {
        !          1359:                plog(LLV_ERROR, LOCATION, NULL,
        !          1360:                    "Cannot allocate memory for mode config state\n");
        !          1361:                return NULL;
        !          1362:        }
        !          1363:        memset(state, 0, sizeof(*state));
        !          1364: 
        !          1365:        return state;
        !          1366: }
        !          1367: 
        !          1368: int 
        !          1369: isakmp_cfg_getport(iph1)
        !          1370:        struct ph1handle *iph1;
        !          1371: {
        !          1372:        unsigned int i;
        !          1373:        size_t size = isakmp_cfg_config.pool_size;
        !          1374: 
        !          1375:        if (iph1->mode_cfg->flags & ISAKMP_CFG_PORT_ALLOCATED)
        !          1376:                return iph1->mode_cfg->port;
        !          1377: 
        !          1378:        if (isakmp_cfg_config.port_pool == NULL) {
        !          1379:                plog(LLV_ERROR, LOCATION, NULL,
        !          1380:                    "isakmp_cfg_config.port_pool == NULL\n");
        !          1381:                return -1;
        !          1382:        }
        !          1383: 
        !          1384:        for (i = 0; i < size; i++) {
        !          1385:                if (isakmp_cfg_config.port_pool[i].used == 0)
        !          1386:                        break;
        !          1387:        }
        !          1388: 
        !          1389:        if (i == size) {
        !          1390:                plog(LLV_ERROR, LOCATION, NULL, 
        !          1391:                    "No more addresses available\n");
        !          1392:                        return -1;
        !          1393:        }
        !          1394: 
        !          1395:        isakmp_cfg_config.port_pool[i].used = 1;
        !          1396: 
        !          1397:        plog(LLV_INFO, LOCATION, NULL, "Using port %d\n", i);
        !          1398: 
        !          1399:        iph1->mode_cfg->flags |= ISAKMP_CFG_PORT_ALLOCATED;
        !          1400:        iph1->mode_cfg->port = i;
        !          1401: 
        !          1402:        return i;
        !          1403: }
        !          1404: 
        !          1405: int 
        !          1406: isakmp_cfg_putport(iph1, index)
        !          1407:        struct ph1handle *iph1;
        !          1408:        unsigned int index;
        !          1409: {
        !          1410:        if (isakmp_cfg_config.port_pool == NULL) {
        !          1411:                plog(LLV_ERROR, LOCATION, NULL, 
        !          1412:                    "isakmp_cfg_config.port_pool == NULL\n");
        !          1413:                return -1;
        !          1414:        }
        !          1415: 
        !          1416:        if (isakmp_cfg_config.port_pool[index].used == 0) {
        !          1417:                plog(LLV_ERROR, LOCATION, NULL, 
        !          1418:                    "Attempt to release an unallocated address (port %d)\n",
        !          1419:                    index);
        !          1420:                return -1;
        !          1421:        }
        !          1422: 
        !          1423: #ifdef HAVE_LIBPAM
        !          1424:        /* Cleanup PAM status associated with the port */
        !          1425:        if (isakmp_cfg_config.authsource == ISAKMP_CFG_AUTH_PAM)
        !          1426:                privsep_cleanup_pam(index);
        !          1427: #endif
        !          1428:        isakmp_cfg_config.port_pool[index].used = 0;
        !          1429:        iph1->mode_cfg->flags &= ISAKMP_CFG_PORT_ALLOCATED;
        !          1430: 
        !          1431:        plog(LLV_INFO, LOCATION, NULL, "Released port %d\n", index);
        !          1432: 
        !          1433:        return 0;
        !          1434: }
        !          1435: 
        !          1436: #ifdef HAVE_LIBPAM
        !          1437: void
        !          1438: cleanup_pam(port)
        !          1439:        int port;
        !          1440: {
        !          1441:        if (isakmp_cfg_config.port_pool[port].pam != NULL) {
        !          1442:                pam_end(isakmp_cfg_config.port_pool[port].pam, PAM_SUCCESS);
        !          1443:                isakmp_cfg_config.port_pool[port].pam = NULL;
        !          1444:        }
        !          1445: 
        !          1446:        return;
        !          1447: }
        !          1448: #endif
        !          1449: 
        !          1450: /* Accounting, only for RADIUS or PAM */
        !          1451: static int
        !          1452: isakmp_cfg_accounting(iph1, inout)
        !          1453:        struct ph1handle *iph1;
        !          1454:        int inout;
        !          1455: {
        !          1456: #ifdef HAVE_LIBPAM
        !          1457:        if (isakmp_cfg_config.accounting == ISAKMP_CFG_ACCT_PAM)
        !          1458:                return privsep_accounting_pam(iph1->mode_cfg->port, 
        !          1459:                    inout);
        !          1460: #endif 
        !          1461: #ifdef HAVE_LIBRADIUS
        !          1462:        if (isakmp_cfg_config.accounting == ISAKMP_CFG_ACCT_RADIUS)
        !          1463:                return isakmp_cfg_accounting_radius(iph1, inout);
        !          1464: #endif
        !          1465:        if (isakmp_cfg_config.accounting == ISAKMP_CFG_ACCT_SYSTEM)
        !          1466:                return privsep_accounting_system(iph1->mode_cfg->port,
        !          1467:                        iph1->remote, iph1->mode_cfg->login, inout);
        !          1468:        return 0;
        !          1469: }
        !          1470: 
        !          1471: #ifdef HAVE_LIBPAM
        !          1472: int 
        !          1473: isakmp_cfg_accounting_pam(port, inout)
        !          1474:        int port;
        !          1475:        int inout;
        !          1476: {
        !          1477:        int error = 0;
        !          1478:        pam_handle_t *pam;
        !          1479: 
        !          1480:        if (isakmp_cfg_config.port_pool == NULL) {
        !          1481:                plog(LLV_ERROR, LOCATION, NULL, 
        !          1482:                    "isakmp_cfg_config.port_pool == NULL\n");
        !          1483:                return -1;
        !          1484:        }
        !          1485:        
        !          1486:        pam = isakmp_cfg_config.port_pool[port].pam;
        !          1487:        if (pam == NULL) {
        !          1488:                plog(LLV_ERROR, LOCATION, NULL, "pam handle is NULL\n");
        !          1489:                return -1;
        !          1490:        }
        !          1491: 
        !          1492:        switch (inout) {
        !          1493:        case ISAKMP_CFG_LOGIN:
        !          1494:                error = pam_open_session(pam, 0);
        !          1495:                break;
        !          1496:        case ISAKMP_CFG_LOGOUT:
        !          1497:                error = pam_close_session(pam, 0);
        !          1498:                pam_end(pam, error);
        !          1499:                isakmp_cfg_config.port_pool[port].pam = NULL;
        !          1500:                break;
        !          1501:        default:
        !          1502:                plog(LLV_ERROR, LOCATION, NULL, "Unepected inout\n");
        !          1503:                break;
        !          1504:        }
        !          1505:        
        !          1506:        if (error != 0) {
        !          1507:                plog(LLV_ERROR, LOCATION, NULL,
        !          1508:                    "pam_open_session/pam_close_session failed: %s\n",
        !          1509:                    pam_strerror(pam, error)); 
        !          1510:                return -1;
        !          1511:         }
        !          1512: 
        !          1513:        return 0;
        !          1514: }
        !          1515: #endif /* HAVE_LIBPAM */
        !          1516: 
        !          1517: #ifdef HAVE_LIBRADIUS
        !          1518: static int
        !          1519: isakmp_cfg_accounting_radius(iph1, inout)
        !          1520:        struct ph1handle *iph1;
        !          1521:        int inout;
        !          1522: {
        !          1523:        if (rad_create_request(radius_acct_state, 
        !          1524:            RAD_ACCOUNTING_REQUEST) != 0) {
        !          1525:                plog(LLV_ERROR, LOCATION, NULL,
        !          1526:                    "rad_create_request failed: %s\n",
        !          1527:                    rad_strerror(radius_acct_state));
        !          1528:                return -1;
        !          1529:        }
        !          1530: 
        !          1531:        if (rad_put_string(radius_acct_state, RAD_USER_NAME, 
        !          1532:            iph1->mode_cfg->login) != 0) {
        !          1533:                plog(LLV_ERROR, LOCATION, NULL,
        !          1534:                    "rad_put_string failed: %s\n",
        !          1535:                    rad_strerror(radius_acct_state));
        !          1536:                return -1;
        !          1537:        }
        !          1538: 
        !          1539:        switch (inout) {
        !          1540:        case ISAKMP_CFG_LOGIN:
        !          1541:                inout = RAD_START;
        !          1542:                break;
        !          1543:        case ISAKMP_CFG_LOGOUT:
        !          1544:                inout = RAD_STOP;
        !          1545:                break;
        !          1546:        default:
        !          1547:                plog(LLV_ERROR, LOCATION, NULL, "Unepected inout\n");
        !          1548:                break;
        !          1549:        }
        !          1550: 
        !          1551:        if (rad_put_addr(radius_acct_state, 
        !          1552:            RAD_FRAMED_IP_ADDRESS, iph1->mode_cfg->addr4) != 0) {
        !          1553:                plog(LLV_ERROR, LOCATION, NULL,
        !          1554:                    "rad_put_addr failed: %s\n",
        !          1555:                    rad_strerror(radius_acct_state));
        !          1556:                return -1;
        !          1557:        }
        !          1558: 
        !          1559:        if (rad_put_addr(radius_acct_state, 
        !          1560:            RAD_LOGIN_IP_HOST, iph1->mode_cfg->addr4) != 0) {
        !          1561:                plog(LLV_ERROR, LOCATION, NULL,
        !          1562:                    "rad_put_addr failed: %s\n",
        !          1563:                    rad_strerror(radius_acct_state));
        !          1564:                return -1;
        !          1565:        }
        !          1566: 
        !          1567:        if (rad_put_int(radius_acct_state, RAD_ACCT_STATUS_TYPE, inout) != 0) {
        !          1568:                plog(LLV_ERROR, LOCATION, NULL,
        !          1569:                    "rad_put_int failed: %s\n",
        !          1570:                    rad_strerror(radius_acct_state));
        !          1571:                return -1;
        !          1572:        }
        !          1573: 
        !          1574:        if (isakmp_cfg_radius_common(radius_acct_state, 
        !          1575:            iph1->mode_cfg->port) != 0)
        !          1576:                return -1;
        !          1577: 
        !          1578:        if (rad_send_request(radius_acct_state) != RAD_ACCOUNTING_RESPONSE) {
        !          1579:                plog(LLV_ERROR, LOCATION, NULL,
        !          1580:                    "rad_send_request failed: %s\n",
        !          1581:                    rad_strerror(radius_acct_state));
        !          1582:                return -1;
        !          1583:        }
        !          1584: 
        !          1585:        return 0;
        !          1586: }
        !          1587: #endif /* HAVE_LIBRADIUS */
        !          1588: 
        !          1589: /*
        !          1590:  * Attributes common to all RADIUS requests
        !          1591:  */
        !          1592: #ifdef HAVE_LIBRADIUS
        !          1593: int
        !          1594: isakmp_cfg_radius_common(radius_state, port)
        !          1595:        struct rad_handle *radius_state;
        !          1596:        int port;
        !          1597: { 
        !          1598:        struct utsname name;
        !          1599:        static struct hostent *host = NULL;
        !          1600:        struct in_addr nas_addr;
        !          1601: 
        !          1602:        /* 
        !          1603:         * Find our own IP by resolving our nodename
        !          1604:         */
        !          1605:        if (host == NULL) {
        !          1606:                if (uname(&name) != 0) {
        !          1607:                        plog(LLV_ERROR, LOCATION, NULL,
        !          1608:                            "uname failed: %s\n", strerror(errno));
        !          1609:                        return -1;
        !          1610:                }
        !          1611: 
        !          1612:                if ((host = gethostbyname(name.nodename)) == NULL) {
        !          1613:                        plog(LLV_ERROR, LOCATION, NULL,
        !          1614:                            "gethostbyname failed: %s\n", strerror(errno));
        !          1615:                        return -1;
        !          1616:                }
        !          1617:        }
        !          1618: 
        !          1619:        memcpy(&nas_addr, host->h_addr, sizeof(nas_addr));
        !          1620:        if (rad_put_addr(radius_state, RAD_NAS_IP_ADDRESS, nas_addr) != 0) {
        !          1621:                plog(LLV_ERROR, LOCATION, NULL,
        !          1622:                    "rad_put_addr failed: %s\n",
        !          1623:                    rad_strerror(radius_state));
        !          1624:                return -1;
        !          1625:        }
        !          1626: 
        !          1627:        if (rad_put_int(radius_state, RAD_NAS_PORT, port) != 0) {
        !          1628:                plog(LLV_ERROR, LOCATION, NULL,
        !          1629:                    "rad_put_int failed: %s\n",
        !          1630:                    rad_strerror(radius_state));
        !          1631:                return -1;
        !          1632:        }
        !          1633: 
        !          1634:        if (rad_put_int(radius_state, RAD_NAS_PORT_TYPE, RAD_VIRTUAL) != 0) {
        !          1635:                plog(LLV_ERROR, LOCATION, NULL,
        !          1636:                    "rad_put_int failed: %s\n",
        !          1637:                    rad_strerror(radius_state));
        !          1638:                return -1;
        !          1639:        }
        !          1640: 
        !          1641:        if (rad_put_int(radius_state, RAD_SERVICE_TYPE, RAD_FRAMED) != 0) {
        !          1642:                plog(LLV_ERROR, LOCATION, NULL,
        !          1643:                    "rad_put_int failed: %s\n",
        !          1644:                    rad_strerror(radius_state));
        !          1645:                return -1;
        !          1646:        }
        !          1647:        
        !          1648:        return 0;
        !          1649: }
        !          1650: #endif
        !          1651: 
        !          1652: /*
        !          1653:        Logs the user into the utmp system files.
        !          1654: */
        !          1655: 
        !          1656: int
        !          1657: isakmp_cfg_accounting_system(port, raddr, usr, inout)
        !          1658:        int port;
        !          1659:        struct sockaddr *raddr;
        !          1660:        char *usr;
        !          1661:        int inout;
        !          1662: {
        !          1663:        int error = 0;
        !          1664:        struct utmpx ut;
        !          1665:        char addr[NI_MAXHOST];
        !          1666:        
        !          1667:        if (usr == NULL || usr[0]=='\0') {
        !          1668:                plog(LLV_ERROR, LOCATION, NULL,
        !          1669:                        "system accounting : no login found\n");
        !          1670:                return -1;
        !          1671:        }
        !          1672: 
        !          1673:        memset(&ut, 0, sizeof ut);
        !          1674:        gettimeofday((struct timeval *)&ut.ut_tv, NULL);
        !          1675:        snprintf(ut.ut_id, sizeof ut.ut_id, TERMSPEC, port);
        !          1676: 
        !          1677:        switch (inout) {
        !          1678:        case ISAKMP_CFG_LOGIN:
        !          1679:                ut.ut_type = USER_PROCESS;
        !          1680:                strncpy(ut.ut_user, usr, sizeof ut.ut_user);
        !          1681: 
        !          1682:                GETNAMEINFO_NULL(raddr, addr);
        !          1683:                strncpy(ut.ut_host, addr, sizeof ut.ut_host);
        !          1684: 
        !          1685:                plog(LLV_INFO, LOCATION, NULL,
        !          1686:                        "Accounting : '%s' logging on '%s' from %s.\n",
        !          1687:                        ut.ut_user, ut.ut_id, addr);
        !          1688: 
        !          1689:                pututxline(&ut);
        !          1690: 
        !          1691:                break;
        !          1692:        case ISAKMP_CFG_LOGOUT: 
        !          1693:                ut.ut_type = DEAD_PROCESS;
        !          1694: 
        !          1695:                plog(LLV_INFO, LOCATION, NULL,
        !          1696:                        "Accounting : '%s' unlogging from '%s'.\n",
        !          1697:                        usr, ut.ut_id);
        !          1698: 
        !          1699:                pututxline(&ut);
        !          1700: 
        !          1701:                break;
        !          1702:        default:
        !          1703:                plog(LLV_ERROR, LOCATION, NULL, "Unepected inout\n");
        !          1704:                break;
        !          1705:        }
        !          1706: 
        !          1707:        return 0;
        !          1708: }
        !          1709:        
        !          1710: int 
        !          1711: isakmp_cfg_getconfig(iph1)
        !          1712:        struct ph1handle *iph1;
        !          1713: {
        !          1714:        vchar_t *buffer;
        !          1715:        struct isakmp_pl_attr *attrpl;
        !          1716:        struct isakmp_data *attr;
        !          1717:        size_t len;
        !          1718:        int error;
        !          1719:        int attrcount;
        !          1720:        int i;
        !          1721:        int attrlist[] = {
        !          1722:                INTERNAL_IP4_ADDRESS,
        !          1723:                INTERNAL_IP4_NETMASK,
        !          1724:                INTERNAL_IP4_DNS,
        !          1725:                INTERNAL_IP4_NBNS,
        !          1726:                UNITY_BANNER,
        !          1727:                UNITY_DEF_DOMAIN,
        !          1728:                UNITY_SPLITDNS_NAME,
        !          1729:                UNITY_SPLIT_INCLUDE,
        !          1730:                UNITY_LOCAL_LAN,
        !          1731:                APPLICATION_VERSION,
        !          1732:        };
        !          1733: 
        !          1734:        attrcount = sizeof(attrlist) / sizeof(*attrlist);
        !          1735:        len = sizeof(*attrpl) + sizeof(*attr) * attrcount;
        !          1736:            
        !          1737:        if ((buffer = vmalloc(len)) == NULL) {
        !          1738:                plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
        !          1739:                return -1;
        !          1740:        }
        !          1741: 
        !          1742:        attrpl = (struct isakmp_pl_attr *)buffer->v;
        !          1743:        attrpl->h.len = htons(len);
        !          1744:        attrpl->type = ISAKMP_CFG_REQUEST;
        !          1745:        attrpl->id = htons((u_int16_t)(eay_random() & 0xffff));
        !          1746: 
        !          1747:        attr = (struct isakmp_data *)(attrpl + 1);
        !          1748: 
        !          1749:        for (i = 0; i < attrcount; i++) {
        !          1750:                attr->type = htons(attrlist[i]);
        !          1751:                attr->lorv = htons(0);
        !          1752:                attr++;
        !          1753:        }
        !          1754: 
        !          1755:        plog(LLV_DEBUG, LOCATION, NULL, 
        !          1756:                    "Sending MODE_CFG REQUEST\n");
        !          1757: 
        !          1758:        error = isakmp_cfg_send(iph1, buffer,
        !          1759:            ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 1);
        !          1760: 
        !          1761:        vfree(buffer);
        !          1762: 
        !          1763:        return error;
        !          1764: }
        !          1765: 
        !          1766: static void
        !          1767: isakmp_cfg_getaddr4(attr, ip)
        !          1768:        struct isakmp_data *attr;
        !          1769:        struct in_addr *ip;
        !          1770: {
        !          1771:        size_t alen = ntohs(attr->lorv);
        !          1772:        in_addr_t *addr;
        !          1773: 
        !          1774:        if (alen != sizeof(*ip)) {
        !          1775:                plog(LLV_ERROR, LOCATION, NULL, "Bad IPv4 address len\n");
        !          1776:                return;
        !          1777:        }
        !          1778: 
        !          1779:        addr = (in_addr_t *)(attr + 1);
        !          1780:        ip->s_addr = *addr;
        !          1781: 
        !          1782:        return;
        !          1783: }
        !          1784: 
        !          1785: static void
        !          1786: isakmp_cfg_appendaddr4(attr, ip, num, max)
        !          1787:        struct isakmp_data *attr;
        !          1788:        struct in_addr *ip;
        !          1789:        int *num;
        !          1790:        int max;
        !          1791: {
        !          1792:        size_t alen = ntohs(attr->lorv);
        !          1793:        in_addr_t *addr;
        !          1794: 
        !          1795:        if (alen != sizeof(*ip)) {
        !          1796:                plog(LLV_ERROR, LOCATION, NULL, "Bad IPv4 address len\n");
        !          1797:                return;
        !          1798:        }
        !          1799:        if (*num == max) {
        !          1800:                plog(LLV_ERROR, LOCATION, NULL, "Too many addresses given\n");
        !          1801:                return;
        !          1802:        }
        !          1803: 
        !          1804:        addr = (in_addr_t *)(attr + 1);
        !          1805:        ip->s_addr = *addr;
        !          1806:        (*num)++;
        !          1807: 
        !          1808:        return;
        !          1809: }
        !          1810: 
        !          1811: static void
        !          1812: isakmp_cfg_getstring(attr, str)
        !          1813:        struct isakmp_data *attr;
        !          1814:        char *str;
        !          1815: {
        !          1816:        size_t alen = ntohs(attr->lorv);
        !          1817:        char *src;
        !          1818:        src = (char *)(attr + 1);
        !          1819: 
        !          1820:        memcpy(str, src, (alen > MAXPATHLEN ? MAXPATHLEN : alen));
        !          1821: 
        !          1822:        return;
        !          1823: }
        !          1824: 
        !          1825: #define IP_MAX 40
        !          1826: 
        !          1827: void
        !          1828: isakmp_cfg_iplist_to_str(dest, count, addr, withmask)
        !          1829:        char *dest;
        !          1830:        int count;
        !          1831:        void *addr;
        !          1832:        int withmask;
        !          1833: {
        !          1834:        int i;
        !          1835:        int p;
        !          1836:        int l;
        !          1837:        struct unity_network tmp;
        !          1838:        for(i = 0, p = 0; i < count; i++) {
        !          1839:                if(withmask == 1)
        !          1840:                        l = sizeof(struct unity_network);
        !          1841:                else
        !          1842:                        l = sizeof(struct in_addr);
        !          1843:                memcpy(&tmp, addr, l);
        !          1844:                addr += l;
        !          1845:                if((uint32_t)tmp.addr4.s_addr == 0)
        !          1846:                        break;
        !          1847:        
        !          1848:                inet_ntop(AF_INET, &tmp.addr4, dest + p, IP_MAX);
        !          1849:                p += strlen(dest + p);
        !          1850:                if(withmask == 1) {
        !          1851:                        dest[p] = '/';
        !          1852:                        p++;
        !          1853:                        inet_ntop(AF_INET, &tmp.mask4, dest + p, IP_MAX);
        !          1854:                        p += strlen(dest + p);
        !          1855:                }
        !          1856:                dest[p] = ' ';
        !          1857:                p++;
        !          1858:        }
        !          1859:        if(p > 0)
        !          1860:                dest[p-1] = '\0';
        !          1861:        else
        !          1862:                dest[0] = '\0';
        !          1863: }
        !          1864: 
        !          1865: int
        !          1866: isakmp_cfg_setenv(iph1, envp, envc)
        !          1867:        struct ph1handle *iph1; 
        !          1868:        char ***envp;
        !          1869:        int *envc;
        !          1870: {
        !          1871:        char addrstr[IP_MAX];
        !          1872:        char addrlist[IP_MAX * MAXNS + MAXNS];
        !          1873:        char *splitlist = addrlist;
        !          1874:        char *splitlist_cidr;
        !          1875:        char defdom[MAXPATHLEN + 1];
        !          1876:        int cidr, tmp;
        !          1877:        char cidrstr[4];
        !          1878:        int i, p;
        !          1879:        int test;
        !          1880: 
        !          1881:        plog(LLV_DEBUG, LOCATION, NULL, "Starting a script.\n");
        !          1882: 
        !          1883:        /* 
        !          1884:         * Internal IPv4 address, either if 
        !          1885:         * we are a client or a server.
        !          1886:         */
        !          1887:        if ((iph1->mode_cfg->flags & ISAKMP_CFG_GOT_ADDR4) ||
        !          1888: #ifdef HAVE_LIBLDAP
        !          1889:            (iph1->mode_cfg->flags & ISAKMP_CFG_ADDR4_EXTERN) ||
        !          1890: #endif
        !          1891: #ifdef HAVE_LIBRADIUS
        !          1892:            (iph1->mode_cfg->flags & ISAKMP_CFG_ADDR4_EXTERN) ||
        !          1893: #endif
        !          1894:            (iph1->mode_cfg->flags & ISAKMP_CFG_ADDR4_LOCAL)) {
        !          1895:                inet_ntop(AF_INET, &iph1->mode_cfg->addr4, 
        !          1896:                    addrstr, IP_MAX);
        !          1897:        } else
        !          1898:                addrstr[0] = '\0';
        !          1899: 
        !          1900:        if (script_env_append(envp, envc, "INTERNAL_ADDR4", addrstr) != 0) {
        !          1901:                plog(LLV_ERROR, LOCATION, NULL, "Cannot set INTERNAL_ADDR4\n");
        !          1902:                return -1;
        !          1903:        }
        !          1904: 
        !          1905:        if (iph1->mode_cfg->xauth.authdata.generic.usr != NULL) {
        !          1906:                if (script_env_append(envp, envc, "XAUTH_USER", 
        !          1907:                    iph1->mode_cfg->xauth.authdata.generic.usr) != 0) {
        !          1908:                        plog(LLV_ERROR, LOCATION, NULL, 
        !          1909:                            "Cannot set XAUTH_USER\n");
        !          1910:                        return -1;
        !          1911:                }
        !          1912:        }
        !          1913: 
        !          1914:        /* Internal IPv4 mask */
        !          1915:        if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_MASK4) 
        !          1916:                inet_ntop(AF_INET, &iph1->mode_cfg->mask4, 
        !          1917:                    addrstr, IP_MAX);
        !          1918:        else
        !          1919:                addrstr[0] = '\0';
        !          1920: 
        !          1921:        /*      
        !          1922:         * During several releases, documentation adverised INTERNAL_NETMASK4
        !          1923:         * while code was using INTERNAL_MASK4. We now do both.
        !          1924:         */
        !          1925: 
        !          1926:        if (script_env_append(envp, envc, "INTERNAL_MASK4", addrstr) != 0) { 
        !          1927:                plog(LLV_ERROR, LOCATION, NULL, "Cannot set INTERNAL_MASK4\n");
        !          1928:                return -1;
        !          1929:        }
        !          1930: 
        !          1931:        if (script_env_append(envp, envc, "INTERNAL_NETMASK4", addrstr) != 0) { 
        !          1932:                plog(LLV_ERROR, LOCATION, NULL, 
        !          1933:                    "Cannot set INTERNAL_NETMASK4\n");
        !          1934:                return -1;
        !          1935:        }
        !          1936: 
        !          1937:        tmp = ntohl(iph1->mode_cfg->mask4.s_addr);
        !          1938:        for (cidr = 0; tmp != 0; cidr++)
        !          1939:                tmp <<= 1;
        !          1940:        snprintf(cidrstr, 3, "%d", cidr);
        !          1941: 
        !          1942:        if (script_env_append(envp, envc, "INTERNAL_CIDR4", cidrstr) != 0) {
        !          1943:                plog(LLV_ERROR, LOCATION, NULL, "Cannot set INTERNAL_CIDR4\n");
        !          1944:                return -1;
        !          1945:        }
        !          1946: 
        !          1947:        /* Internal IPv4 DNS */
        !          1948:        if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_DNS4) {
        !          1949:                /* First Internal IPv4 DNS (for compatibilty with older code */
        !          1950:                inet_ntop(AF_INET, &iph1->mode_cfg->dns4[0], 
        !          1951:                    addrstr, IP_MAX);
        !          1952: 
        !          1953:                /* Internal IPv4 DNS - all */
        !          1954:                isakmp_cfg_iplist_to_str(addrlist, iph1->mode_cfg->dns4_index,
        !          1955:                        (void *)iph1->mode_cfg->dns4, 0);
        !          1956:        } else {
        !          1957:                addrstr[0] = '\0';
        !          1958:                addrlist[0] = '\0';
        !          1959:        }
        !          1960: 
        !          1961:        if (script_env_append(envp, envc, "INTERNAL_DNS4", addrstr) != 0) {
        !          1962:                plog(LLV_ERROR, LOCATION, NULL, "Cannot set INTERNAL_DNS4\n");
        !          1963:                return -1;
        !          1964:        }
        !          1965:        if (script_env_append(envp, envc, "INTERNAL_DNS4_LIST", addrlist) != 0) {
        !          1966:                plog(LLV_ERROR, LOCATION, NULL, 
        !          1967:                    "Cannot set INTERNAL_DNS4_LIST\n");
        !          1968:                return -1;
        !          1969:        }
        !          1970:        
        !          1971:        /* Internal IPv4 WINS */
        !          1972:        if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_WINS4) {
        !          1973:                /* 
        !          1974:                 * First Internal IPv4 WINS 
        !          1975:                 * (for compatibilty with older code 
        !          1976:                 */
        !          1977:                inet_ntop(AF_INET, &iph1->mode_cfg->wins4[0], 
        !          1978:                    addrstr, IP_MAX);
        !          1979: 
        !          1980:                /* Internal IPv4 WINS - all */
        !          1981:                isakmp_cfg_iplist_to_str(addrlist, iph1->mode_cfg->wins4_index,
        !          1982:                        (void *)iph1->mode_cfg->wins4, 0);
        !          1983:        } else {
        !          1984:                addrstr[0] = '\0';
        !          1985:                addrlist[0] = '\0';
        !          1986:        }
        !          1987: 
        !          1988:        if (script_env_append(envp, envc, "INTERNAL_WINS4", addrstr) != 0) {
        !          1989:                plog(LLV_ERROR, LOCATION, NULL, 
        !          1990:                    "Cannot set INTERNAL_WINS4\n");
        !          1991:                return -1;
        !          1992:        }
        !          1993:        if (script_env_append(envp, envc, 
        !          1994:            "INTERNAL_WINS4_LIST", addrlist) != 0) {
        !          1995:                plog(LLV_ERROR, LOCATION, NULL, 
        !          1996:                    "Cannot set INTERNAL_WINS4_LIST\n");
        !          1997:                return -1;
        !          1998:        }
        !          1999: 
        !          2000:        /* Deault domain */
        !          2001:        if(iph1->mode_cfg->flags & ISAKMP_CFG_GOT_DEFAULT_DOMAIN) 
        !          2002:                strncpy(defdom, 
        !          2003:                    iph1->mode_cfg->default_domain, 
        !          2004:                    MAXPATHLEN + 1);
        !          2005:        else
        !          2006:                defdom[0] = '\0';
        !          2007:        
        !          2008:        if (script_env_append(envp, envc, "DEFAULT_DOMAIN", defdom) != 0) { 
        !          2009:                plog(LLV_ERROR, LOCATION, NULL, 
        !          2010:                    "Cannot set DEFAULT_DOMAIN\n");
        !          2011:                return -1;
        !          2012:        }
        !          2013: 
        !          2014:        /* Split networks */
        !          2015:        if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_SPLIT_INCLUDE) {
        !          2016:                splitlist = 
        !          2017:                    splitnet_list_2str(iph1->mode_cfg->split_include, NETMASK);
        !          2018:                splitlist_cidr = 
        !          2019:                    splitnet_list_2str(iph1->mode_cfg->split_include, CIDR);
        !          2020:        } else {
        !          2021:                splitlist = addrlist;
        !          2022:                splitlist_cidr = addrlist;
        !          2023:                addrlist[0] = '\0';
        !          2024:        }
        !          2025: 
        !          2026:        if (script_env_append(envp, envc, "SPLIT_INCLUDE", splitlist) != 0) {
        !          2027:                plog(LLV_ERROR, LOCATION, NULL, "Cannot set SPLIT_INCLUDE\n");
        !          2028:                return -1;
        !          2029:        }
        !          2030:        if (script_env_append(envp, envc, 
        !          2031:            "SPLIT_INCLUDE_CIDR", splitlist_cidr) != 0) {
        !          2032:                plog(LLV_ERROR, LOCATION, NULL,
        !          2033:                     "Cannot set SPLIT_INCLUDE_CIDR\n");
        !          2034:                return -1;
        !          2035:        }
        !          2036:        if (splitlist != addrlist)
        !          2037:                racoon_free(splitlist);
        !          2038:        if (splitlist_cidr != addrlist)
        !          2039:                racoon_free(splitlist_cidr);
        !          2040: 
        !          2041:        if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_SPLIT_LOCAL) {
        !          2042:                splitlist =
        !          2043:                    splitnet_list_2str(iph1->mode_cfg->split_local, NETMASK);
        !          2044:                splitlist_cidr =
        !          2045:                    splitnet_list_2str(iph1->mode_cfg->split_local, CIDR);
        !          2046:        } else {
        !          2047:                splitlist = addrlist;
        !          2048:                splitlist_cidr = addrlist;
        !          2049:                addrlist[0] = '\0';
        !          2050:        }
        !          2051: 
        !          2052:        if (script_env_append(envp, envc, "SPLIT_LOCAL", splitlist) != 0) {
        !          2053:                plog(LLV_ERROR, LOCATION, NULL, "Cannot set SPLIT_LOCAL\n");
        !          2054:                return -1;
        !          2055:        }
        !          2056:        if (script_env_append(envp, envc,
        !          2057:            "SPLIT_LOCAL_CIDR", splitlist_cidr) != 0) {
        !          2058:                plog(LLV_ERROR, LOCATION, NULL,
        !          2059:                     "Cannot set SPLIT_LOCAL_CIDR\n");
        !          2060:                return -1;
        !          2061:        }
        !          2062:        if (splitlist != addrlist)
        !          2063:                racoon_free(splitlist);
        !          2064:        if (splitlist_cidr != addrlist)
        !          2065:                racoon_free(splitlist_cidr);
        !          2066:        
        !          2067:        return 0;
        !          2068: }
        !          2069: 
        !          2070: int
        !          2071: isakmp_cfg_resize_pool(size)
        !          2072:        int size;
        !          2073: {
        !          2074:        struct isakmp_cfg_port *new_pool;
        !          2075:        size_t len;
        !          2076:        int i;
        !          2077: 
        !          2078:        if (size == isakmp_cfg_config.pool_size)
        !          2079:                return 0;
        !          2080: 
        !          2081:        plog(LLV_INFO, LOCATION, NULL,
        !          2082:            "Resize address pool from %zu to %d\n",
        !          2083:            isakmp_cfg_config.pool_size, size);
        !          2084: 
        !          2085:        /* If a pool already exists, check if we can shrink it */
        !          2086:        if ((isakmp_cfg_config.port_pool != NULL) &&
        !          2087:            (size < isakmp_cfg_config.pool_size)) {
        !          2088:                for (i = isakmp_cfg_config.pool_size-1; i >= size; --i) {
        !          2089:                        if (isakmp_cfg_config.port_pool[i].used) {
        !          2090:                                plog(LLV_ERROR, LOCATION, NULL, 
        !          2091:                                    "resize pool from %zu to %d impossible "
        !          2092:                                    "port %d is in use\n", 
        !          2093:                                    isakmp_cfg_config.pool_size, size, i);
        !          2094:                                size = i;
        !          2095:                                break;
        !          2096:                        }       
        !          2097:                }
        !          2098:        }
        !          2099: 
        !          2100:        len = size * sizeof(*isakmp_cfg_config.port_pool);
        !          2101:        new_pool = racoon_realloc(isakmp_cfg_config.port_pool, len);
        !          2102:        if (new_pool == NULL) {
        !          2103:                plog(LLV_ERROR, LOCATION, NULL, 
        !          2104:                    "resize pool from %zu to %d impossible: %s",
        !          2105:                    isakmp_cfg_config.pool_size, size, strerror(errno));
        !          2106:                return -1;
        !          2107:        }
        !          2108: 
        !          2109:        /* If size increase, intialize correctly the new records */
        !          2110:        if (size > isakmp_cfg_config.pool_size) {
        !          2111:                size_t unit;
        !          2112:                size_t old_size;
        !          2113: 
        !          2114:                unit =  sizeof(*isakmp_cfg_config.port_pool);
        !          2115:                old_size = isakmp_cfg_config.pool_size;
        !          2116: 
        !          2117:                bzero((char *)new_pool + (old_size * unit), 
        !          2118:                    (size - old_size) * unit);
        !          2119:        }
        !          2120: 
        !          2121:        isakmp_cfg_config.port_pool = new_pool;
        !          2122:        isakmp_cfg_config.pool_size = size;
        !          2123: 
        !          2124:        return 0;
        !          2125: }
        !          2126: 
        !          2127: int
        !          2128: isakmp_cfg_init(cold) 
        !          2129:        int cold;
        !          2130: {
        !          2131:        int i;
        !          2132:        int error;
        !          2133: 
        !          2134:        isakmp_cfg_config.network4 = (in_addr_t)0x00000000;
        !          2135:        isakmp_cfg_config.netmask4 = (in_addr_t)0x00000000;
        !          2136:        for (i = 0; i < MAXNS; i++)
        !          2137:                isakmp_cfg_config.dns4[i] = (in_addr_t)0x00000000;
        !          2138:        isakmp_cfg_config.dns4_index = 0;
        !          2139:        for (i = 0; i < MAXWINS; i++)
        !          2140:                isakmp_cfg_config.nbns4[i] = (in_addr_t)0x00000000;
        !          2141:        isakmp_cfg_config.nbns4_index = 0;
        !          2142:        if (cold == ISAKMP_CFG_INIT_COLD)
        !          2143:                isakmp_cfg_config.port_pool = NULL;
        !          2144:        isakmp_cfg_config.authsource = ISAKMP_CFG_AUTH_SYSTEM;
        !          2145:        isakmp_cfg_config.groupsource = ISAKMP_CFG_GROUP_SYSTEM;
        !          2146:        if (cold == ISAKMP_CFG_INIT_COLD) {
        !          2147:                if (isakmp_cfg_config.grouplist != NULL) {
        !          2148:                        for (i = 0; i < isakmp_cfg_config.groupcount; i++)
        !          2149:                                racoon_free(isakmp_cfg_config.grouplist[i]);
        !          2150:                        racoon_free(isakmp_cfg_config.grouplist);
        !          2151:                }
        !          2152:        }
        !          2153:        isakmp_cfg_config.grouplist = NULL;
        !          2154:        isakmp_cfg_config.groupcount = 0;
        !          2155:        isakmp_cfg_config.confsource = ISAKMP_CFG_CONF_LOCAL;
        !          2156:        isakmp_cfg_config.accounting = ISAKMP_CFG_ACCT_NONE;
        !          2157:        if (cold == ISAKMP_CFG_INIT_COLD)
        !          2158:                isakmp_cfg_config.pool_size = 0;
        !          2159:        isakmp_cfg_config.auth_throttle = THROTTLE_PENALTY;
        !          2160:        strlcpy(isakmp_cfg_config.default_domain, ISAKMP_CFG_DEFAULT_DOMAIN,
        !          2161:            MAXPATHLEN);
        !          2162:        strlcpy(isakmp_cfg_config.motd, ISAKMP_CFG_MOTD, MAXPATHLEN);
        !          2163: 
        !          2164:        if (cold != ISAKMP_CFG_INIT_COLD )
        !          2165:                if (isakmp_cfg_config.splitnet_list != NULL)
        !          2166:                        splitnet_list_free(isakmp_cfg_config.splitnet_list,
        !          2167:                                &isakmp_cfg_config.splitnet_count);
        !          2168:        isakmp_cfg_config.splitnet_list = NULL;
        !          2169:        isakmp_cfg_config.splitnet_count = 0;
        !          2170:        isakmp_cfg_config.splitnet_type = 0;
        !          2171: 
        !          2172:        isakmp_cfg_config.pfs_group = 0;
        !          2173:        isakmp_cfg_config.save_passwd = 0;
        !          2174: 
        !          2175:        if (cold != ISAKMP_CFG_INIT_COLD )
        !          2176:                if (isakmp_cfg_config.splitdns_list != NULL)
        !          2177:                        racoon_free(isakmp_cfg_config.splitdns_list);
        !          2178:        isakmp_cfg_config.splitdns_list = NULL;
        !          2179:        isakmp_cfg_config.splitdns_len = 0;
        !          2180: 
        !          2181: #if 0
        !          2182:        if (cold == ISAKMP_CFG_INIT_COLD) {
        !          2183:                if ((error = isakmp_cfg_resize_pool(ISAKMP_CFG_MAX_CNX)) != 0)
        !          2184:                        return error;
        !          2185:        }
        !          2186: #endif
        !          2187: 
        !          2188:        return 0;
        !          2189: }
        !          2190: 

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