Annotation of embedaddon/ipsec-tools/src/racoon/isakmp_cfg.c, revision 1.1.1.1.2.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: 
1.1.1.1.2.1! misho      41: #include <utmp.h>
1.1       misho      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;
1.1.1.1.2.1! misho    1664:        struct utmp ut;
        !          1665:        char term[UT_LINESIZE];
1.1       misho    1666:        char addr[NI_MAXHOST];
                   1667:        
                   1668:        if (usr == NULL || usr[0]=='\0') {
                   1669:                plog(LLV_ERROR, LOCATION, NULL,
                   1670:                        "system accounting : no login found\n");
                   1671:                return -1;
                   1672:        }
                   1673: 
1.1.1.1.2.1! misho    1674:        sprintf(term, TERMSPEC, port);
1.1       misho    1675: 
                   1676:        switch (inout) {
                   1677:        case ISAKMP_CFG_LOGIN:
1.1.1.1.2.1! misho    1678:                strncpy(ut.ut_name, usr, UT_NAMESIZE);
        !          1679:                ut.ut_name[UT_NAMESIZE - 1] = '\0';
        !          1680: 
        !          1681:                strncpy(ut.ut_line, term, UT_LINESIZE);
        !          1682:                ut.ut_line[UT_LINESIZE - 1] = '\0';
1.1       misho    1683: 
                   1684:                GETNAMEINFO_NULL(raddr, addr);
1.1.1.1.2.1! misho    1685:                strncpy(ut.ut_host, addr, UT_HOSTSIZE);
        !          1686:                ut.ut_host[UT_HOSTSIZE - 1] = '\0';
1.1       misho    1687: 
1.1.1.1.2.1! misho    1688:                ut.ut_time = time(NULL);
        !          1689:  
1.1       misho    1690:                plog(LLV_INFO, LOCATION, NULL,
                   1691:                        "Accounting : '%s' logging on '%s' from %s.\n",
1.1.1.1.2.1! misho    1692:                        ut.ut_name, ut.ut_line, ut.ut_host);
1.1       misho    1693: 
1.1.1.1.2.1! misho    1694:                login(&ut);
1.1       misho    1695: 
                   1696:                break;
                   1697:        case ISAKMP_CFG_LOGOUT: 
                   1698: 
                   1699:                plog(LLV_INFO, LOCATION, NULL,
                   1700:                        "Accounting : '%s' unlogging from '%s'.\n",
1.1.1.1.2.1! misho    1701:                        usr, term);
1.1       misho    1702: 
1.1.1.1.2.1! misho    1703:                logout(term);
1.1       misho    1704: 
                   1705:                break;
                   1706:        default:
                   1707:                plog(LLV_ERROR, LOCATION, NULL, "Unepected inout\n");
                   1708:                break;
                   1709:        }
                   1710: 
                   1711:        return 0;
                   1712: }
                   1713:        
                   1714: int 
                   1715: isakmp_cfg_getconfig(iph1)
                   1716:        struct ph1handle *iph1;
                   1717: {
                   1718:        vchar_t *buffer;
                   1719:        struct isakmp_pl_attr *attrpl;
                   1720:        struct isakmp_data *attr;
                   1721:        size_t len;
                   1722:        int error;
                   1723:        int attrcount;
                   1724:        int i;
                   1725:        int attrlist[] = {
                   1726:                INTERNAL_IP4_ADDRESS,
                   1727:                INTERNAL_IP4_NETMASK,
                   1728:                INTERNAL_IP4_DNS,
                   1729:                INTERNAL_IP4_NBNS,
                   1730:                UNITY_BANNER,
                   1731:                UNITY_DEF_DOMAIN,
                   1732:                UNITY_SPLITDNS_NAME,
                   1733:                UNITY_SPLIT_INCLUDE,
                   1734:                UNITY_LOCAL_LAN,
                   1735:                APPLICATION_VERSION,
                   1736:        };
                   1737: 
                   1738:        attrcount = sizeof(attrlist) / sizeof(*attrlist);
                   1739:        len = sizeof(*attrpl) + sizeof(*attr) * attrcount;
                   1740:            
                   1741:        if ((buffer = vmalloc(len)) == NULL) {
                   1742:                plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
                   1743:                return -1;
                   1744:        }
                   1745: 
                   1746:        attrpl = (struct isakmp_pl_attr *)buffer->v;
                   1747:        attrpl->h.len = htons(len);
                   1748:        attrpl->type = ISAKMP_CFG_REQUEST;
                   1749:        attrpl->id = htons((u_int16_t)(eay_random() & 0xffff));
                   1750: 
                   1751:        attr = (struct isakmp_data *)(attrpl + 1);
                   1752: 
                   1753:        for (i = 0; i < attrcount; i++) {
                   1754:                attr->type = htons(attrlist[i]);
                   1755:                attr->lorv = htons(0);
                   1756:                attr++;
                   1757:        }
                   1758: 
                   1759:        plog(LLV_DEBUG, LOCATION, NULL, 
                   1760:                    "Sending MODE_CFG REQUEST\n");
                   1761: 
                   1762:        error = isakmp_cfg_send(iph1, buffer,
                   1763:            ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 1);
                   1764: 
                   1765:        vfree(buffer);
                   1766: 
                   1767:        return error;
                   1768: }
                   1769: 
                   1770: static void
                   1771: isakmp_cfg_getaddr4(attr, ip)
                   1772:        struct isakmp_data *attr;
                   1773:        struct in_addr *ip;
                   1774: {
                   1775:        size_t alen = ntohs(attr->lorv);
                   1776:        in_addr_t *addr;
                   1777: 
                   1778:        if (alen != sizeof(*ip)) {
                   1779:                plog(LLV_ERROR, LOCATION, NULL, "Bad IPv4 address len\n");
                   1780:                return;
                   1781:        }
                   1782: 
                   1783:        addr = (in_addr_t *)(attr + 1);
                   1784:        ip->s_addr = *addr;
                   1785: 
                   1786:        return;
                   1787: }
                   1788: 
                   1789: static void
                   1790: isakmp_cfg_appendaddr4(attr, ip, num, max)
                   1791:        struct isakmp_data *attr;
                   1792:        struct in_addr *ip;
                   1793:        int *num;
                   1794:        int max;
                   1795: {
                   1796:        size_t alen = ntohs(attr->lorv);
                   1797:        in_addr_t *addr;
                   1798: 
                   1799:        if (alen != sizeof(*ip)) {
                   1800:                plog(LLV_ERROR, LOCATION, NULL, "Bad IPv4 address len\n");
                   1801:                return;
                   1802:        }
                   1803:        if (*num == max) {
                   1804:                plog(LLV_ERROR, LOCATION, NULL, "Too many addresses given\n");
                   1805:                return;
                   1806:        }
                   1807: 
                   1808:        addr = (in_addr_t *)(attr + 1);
                   1809:        ip->s_addr = *addr;
                   1810:        (*num)++;
                   1811: 
                   1812:        return;
                   1813: }
                   1814: 
                   1815: static void
                   1816: isakmp_cfg_getstring(attr, str)
                   1817:        struct isakmp_data *attr;
                   1818:        char *str;
                   1819: {
                   1820:        size_t alen = ntohs(attr->lorv);
                   1821:        char *src;
                   1822:        src = (char *)(attr + 1);
                   1823: 
                   1824:        memcpy(str, src, (alen > MAXPATHLEN ? MAXPATHLEN : alen));
                   1825: 
                   1826:        return;
                   1827: }
                   1828: 
                   1829: #define IP_MAX 40
                   1830: 
                   1831: void
                   1832: isakmp_cfg_iplist_to_str(dest, count, addr, withmask)
                   1833:        char *dest;
                   1834:        int count;
                   1835:        void *addr;
                   1836:        int withmask;
                   1837: {
                   1838:        int i;
                   1839:        int p;
                   1840:        int l;
                   1841:        struct unity_network tmp;
                   1842:        for(i = 0, p = 0; i < count; i++) {
                   1843:                if(withmask == 1)
                   1844:                        l = sizeof(struct unity_network);
                   1845:                else
                   1846:                        l = sizeof(struct in_addr);
                   1847:                memcpy(&tmp, addr, l);
                   1848:                addr += l;
                   1849:                if((uint32_t)tmp.addr4.s_addr == 0)
                   1850:                        break;
                   1851:        
                   1852:                inet_ntop(AF_INET, &tmp.addr4, dest + p, IP_MAX);
                   1853:                p += strlen(dest + p);
                   1854:                if(withmask == 1) {
                   1855:                        dest[p] = '/';
                   1856:                        p++;
                   1857:                        inet_ntop(AF_INET, &tmp.mask4, dest + p, IP_MAX);
                   1858:                        p += strlen(dest + p);
                   1859:                }
                   1860:                dest[p] = ' ';
                   1861:                p++;
                   1862:        }
                   1863:        if(p > 0)
                   1864:                dest[p-1] = '\0';
                   1865:        else
                   1866:                dest[0] = '\0';
                   1867: }
                   1868: 
                   1869: int
                   1870: isakmp_cfg_setenv(iph1, envp, envc)
                   1871:        struct ph1handle *iph1; 
                   1872:        char ***envp;
                   1873:        int *envc;
                   1874: {
                   1875:        char addrstr[IP_MAX];
                   1876:        char addrlist[IP_MAX * MAXNS + MAXNS];
                   1877:        char *splitlist = addrlist;
                   1878:        char *splitlist_cidr;
                   1879:        char defdom[MAXPATHLEN + 1];
                   1880:        int cidr, tmp;
                   1881:        char cidrstr[4];
                   1882:        int i, p;
                   1883:        int test;
                   1884: 
                   1885:        plog(LLV_DEBUG, LOCATION, NULL, "Starting a script.\n");
                   1886: 
                   1887:        /* 
                   1888:         * Internal IPv4 address, either if 
                   1889:         * we are a client or a server.
                   1890:         */
                   1891:        if ((iph1->mode_cfg->flags & ISAKMP_CFG_GOT_ADDR4) ||
                   1892: #ifdef HAVE_LIBLDAP
                   1893:            (iph1->mode_cfg->flags & ISAKMP_CFG_ADDR4_EXTERN) ||
                   1894: #endif
                   1895: #ifdef HAVE_LIBRADIUS
                   1896:            (iph1->mode_cfg->flags & ISAKMP_CFG_ADDR4_EXTERN) ||
                   1897: #endif
                   1898:            (iph1->mode_cfg->flags & ISAKMP_CFG_ADDR4_LOCAL)) {
                   1899:                inet_ntop(AF_INET, &iph1->mode_cfg->addr4, 
                   1900:                    addrstr, IP_MAX);
                   1901:        } else
                   1902:                addrstr[0] = '\0';
                   1903: 
                   1904:        if (script_env_append(envp, envc, "INTERNAL_ADDR4", addrstr) != 0) {
                   1905:                plog(LLV_ERROR, LOCATION, NULL, "Cannot set INTERNAL_ADDR4\n");
                   1906:                return -1;
                   1907:        }
                   1908: 
                   1909:        if (iph1->mode_cfg->xauth.authdata.generic.usr != NULL) {
                   1910:                if (script_env_append(envp, envc, "XAUTH_USER", 
                   1911:                    iph1->mode_cfg->xauth.authdata.generic.usr) != 0) {
                   1912:                        plog(LLV_ERROR, LOCATION, NULL, 
                   1913:                            "Cannot set XAUTH_USER\n");
                   1914:                        return -1;
                   1915:                }
                   1916:        }
                   1917: 
                   1918:        /* Internal IPv4 mask */
                   1919:        if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_MASK4) 
                   1920:                inet_ntop(AF_INET, &iph1->mode_cfg->mask4, 
                   1921:                    addrstr, IP_MAX);
                   1922:        else
                   1923:                addrstr[0] = '\0';
                   1924: 
                   1925:        /*      
                   1926:         * During several releases, documentation adverised INTERNAL_NETMASK4
                   1927:         * while code was using INTERNAL_MASK4. We now do both.
                   1928:         */
                   1929: 
                   1930:        if (script_env_append(envp, envc, "INTERNAL_MASK4", addrstr) != 0) { 
                   1931:                plog(LLV_ERROR, LOCATION, NULL, "Cannot set INTERNAL_MASK4\n");
                   1932:                return -1;
                   1933:        }
                   1934: 
                   1935:        if (script_env_append(envp, envc, "INTERNAL_NETMASK4", addrstr) != 0) { 
                   1936:                plog(LLV_ERROR, LOCATION, NULL, 
                   1937:                    "Cannot set INTERNAL_NETMASK4\n");
                   1938:                return -1;
                   1939:        }
                   1940: 
                   1941:        tmp = ntohl(iph1->mode_cfg->mask4.s_addr);
                   1942:        for (cidr = 0; tmp != 0; cidr++)
                   1943:                tmp <<= 1;
                   1944:        snprintf(cidrstr, 3, "%d", cidr);
                   1945: 
                   1946:        if (script_env_append(envp, envc, "INTERNAL_CIDR4", cidrstr) != 0) {
                   1947:                plog(LLV_ERROR, LOCATION, NULL, "Cannot set INTERNAL_CIDR4\n");
                   1948:                return -1;
                   1949:        }
                   1950: 
                   1951:        /* Internal IPv4 DNS */
                   1952:        if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_DNS4) {
                   1953:                /* First Internal IPv4 DNS (for compatibilty with older code */
                   1954:                inet_ntop(AF_INET, &iph1->mode_cfg->dns4[0], 
                   1955:                    addrstr, IP_MAX);
                   1956: 
                   1957:                /* Internal IPv4 DNS - all */
                   1958:                isakmp_cfg_iplist_to_str(addrlist, iph1->mode_cfg->dns4_index,
                   1959:                        (void *)iph1->mode_cfg->dns4, 0);
                   1960:        } else {
                   1961:                addrstr[0] = '\0';
                   1962:                addrlist[0] = '\0';
                   1963:        }
                   1964: 
                   1965:        if (script_env_append(envp, envc, "INTERNAL_DNS4", addrstr) != 0) {
                   1966:                plog(LLV_ERROR, LOCATION, NULL, "Cannot set INTERNAL_DNS4\n");
                   1967:                return -1;
                   1968:        }
                   1969:        if (script_env_append(envp, envc, "INTERNAL_DNS4_LIST", addrlist) != 0) {
                   1970:                plog(LLV_ERROR, LOCATION, NULL, 
                   1971:                    "Cannot set INTERNAL_DNS4_LIST\n");
                   1972:                return -1;
                   1973:        }
                   1974:        
                   1975:        /* Internal IPv4 WINS */
                   1976:        if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_WINS4) {
                   1977:                /* 
                   1978:                 * First Internal IPv4 WINS 
                   1979:                 * (for compatibilty with older code 
                   1980:                 */
                   1981:                inet_ntop(AF_INET, &iph1->mode_cfg->wins4[0], 
                   1982:                    addrstr, IP_MAX);
                   1983: 
                   1984:                /* Internal IPv4 WINS - all */
                   1985:                isakmp_cfg_iplist_to_str(addrlist, iph1->mode_cfg->wins4_index,
                   1986:                        (void *)iph1->mode_cfg->wins4, 0);
                   1987:        } else {
                   1988:                addrstr[0] = '\0';
                   1989:                addrlist[0] = '\0';
                   1990:        }
                   1991: 
                   1992:        if (script_env_append(envp, envc, "INTERNAL_WINS4", addrstr) != 0) {
                   1993:                plog(LLV_ERROR, LOCATION, NULL, 
                   1994:                    "Cannot set INTERNAL_WINS4\n");
                   1995:                return -1;
                   1996:        }
                   1997:        if (script_env_append(envp, envc, 
                   1998:            "INTERNAL_WINS4_LIST", addrlist) != 0) {
                   1999:                plog(LLV_ERROR, LOCATION, NULL, 
                   2000:                    "Cannot set INTERNAL_WINS4_LIST\n");
                   2001:                return -1;
                   2002:        }
                   2003: 
                   2004:        /* Deault domain */
                   2005:        if(iph1->mode_cfg->flags & ISAKMP_CFG_GOT_DEFAULT_DOMAIN) 
                   2006:                strncpy(defdom, 
                   2007:                    iph1->mode_cfg->default_domain, 
                   2008:                    MAXPATHLEN + 1);
                   2009:        else
                   2010:                defdom[0] = '\0';
                   2011:        
                   2012:        if (script_env_append(envp, envc, "DEFAULT_DOMAIN", defdom) != 0) { 
                   2013:                plog(LLV_ERROR, LOCATION, NULL, 
                   2014:                    "Cannot set DEFAULT_DOMAIN\n");
                   2015:                return -1;
                   2016:        }
                   2017: 
                   2018:        /* Split networks */
                   2019:        if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_SPLIT_INCLUDE) {
                   2020:                splitlist = 
                   2021:                    splitnet_list_2str(iph1->mode_cfg->split_include, NETMASK);
                   2022:                splitlist_cidr = 
                   2023:                    splitnet_list_2str(iph1->mode_cfg->split_include, CIDR);
                   2024:        } else {
                   2025:                splitlist = addrlist;
                   2026:                splitlist_cidr = addrlist;
                   2027:                addrlist[0] = '\0';
                   2028:        }
                   2029: 
                   2030:        if (script_env_append(envp, envc, "SPLIT_INCLUDE", splitlist) != 0) {
                   2031:                plog(LLV_ERROR, LOCATION, NULL, "Cannot set SPLIT_INCLUDE\n");
                   2032:                return -1;
                   2033:        }
                   2034:        if (script_env_append(envp, envc, 
                   2035:            "SPLIT_INCLUDE_CIDR", splitlist_cidr) != 0) {
                   2036:                plog(LLV_ERROR, LOCATION, NULL,
                   2037:                     "Cannot set SPLIT_INCLUDE_CIDR\n");
                   2038:                return -1;
                   2039:        }
                   2040:        if (splitlist != addrlist)
                   2041:                racoon_free(splitlist);
                   2042:        if (splitlist_cidr != addrlist)
                   2043:                racoon_free(splitlist_cidr);
                   2044: 
                   2045:        if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_SPLIT_LOCAL) {
                   2046:                splitlist =
                   2047:                    splitnet_list_2str(iph1->mode_cfg->split_local, NETMASK);
                   2048:                splitlist_cidr =
                   2049:                    splitnet_list_2str(iph1->mode_cfg->split_local, CIDR);
                   2050:        } else {
                   2051:                splitlist = addrlist;
                   2052:                splitlist_cidr = addrlist;
                   2053:                addrlist[0] = '\0';
                   2054:        }
                   2055: 
                   2056:        if (script_env_append(envp, envc, "SPLIT_LOCAL", splitlist) != 0) {
                   2057:                plog(LLV_ERROR, LOCATION, NULL, "Cannot set SPLIT_LOCAL\n");
                   2058:                return -1;
                   2059:        }
                   2060:        if (script_env_append(envp, envc,
                   2061:            "SPLIT_LOCAL_CIDR", splitlist_cidr) != 0) {
                   2062:                plog(LLV_ERROR, LOCATION, NULL,
                   2063:                     "Cannot set SPLIT_LOCAL_CIDR\n");
                   2064:                return -1;
                   2065:        }
                   2066:        if (splitlist != addrlist)
                   2067:                racoon_free(splitlist);
                   2068:        if (splitlist_cidr != addrlist)
                   2069:                racoon_free(splitlist_cidr);
                   2070:        
                   2071:        return 0;
                   2072: }
                   2073: 
                   2074: int
                   2075: isakmp_cfg_resize_pool(size)
                   2076:        int size;
                   2077: {
                   2078:        struct isakmp_cfg_port *new_pool;
                   2079:        size_t len;
                   2080:        int i;
                   2081: 
                   2082:        if (size == isakmp_cfg_config.pool_size)
                   2083:                return 0;
                   2084: 
                   2085:        plog(LLV_INFO, LOCATION, NULL,
                   2086:            "Resize address pool from %zu to %d\n",
                   2087:            isakmp_cfg_config.pool_size, size);
                   2088: 
                   2089:        /* If a pool already exists, check if we can shrink it */
                   2090:        if ((isakmp_cfg_config.port_pool != NULL) &&
                   2091:            (size < isakmp_cfg_config.pool_size)) {
                   2092:                for (i = isakmp_cfg_config.pool_size-1; i >= size; --i) {
                   2093:                        if (isakmp_cfg_config.port_pool[i].used) {
                   2094:                                plog(LLV_ERROR, LOCATION, NULL, 
                   2095:                                    "resize pool from %zu to %d impossible "
                   2096:                                    "port %d is in use\n", 
                   2097:                                    isakmp_cfg_config.pool_size, size, i);
                   2098:                                size = i;
                   2099:                                break;
                   2100:                        }       
                   2101:                }
                   2102:        }
                   2103: 
                   2104:        len = size * sizeof(*isakmp_cfg_config.port_pool);
                   2105:        new_pool = racoon_realloc(isakmp_cfg_config.port_pool, len);
                   2106:        if (new_pool == NULL) {
                   2107:                plog(LLV_ERROR, LOCATION, NULL, 
                   2108:                    "resize pool from %zu to %d impossible: %s",
                   2109:                    isakmp_cfg_config.pool_size, size, strerror(errno));
                   2110:                return -1;
                   2111:        }
                   2112: 
                   2113:        /* If size increase, intialize correctly the new records */
                   2114:        if (size > isakmp_cfg_config.pool_size) {
                   2115:                size_t unit;
                   2116:                size_t old_size;
                   2117: 
                   2118:                unit =  sizeof(*isakmp_cfg_config.port_pool);
                   2119:                old_size = isakmp_cfg_config.pool_size;
                   2120: 
                   2121:                bzero((char *)new_pool + (old_size * unit), 
                   2122:                    (size - old_size) * unit);
                   2123:        }
                   2124: 
                   2125:        isakmp_cfg_config.port_pool = new_pool;
                   2126:        isakmp_cfg_config.pool_size = size;
                   2127: 
                   2128:        return 0;
                   2129: }
                   2130: 
                   2131: int
                   2132: isakmp_cfg_init(cold) 
                   2133:        int cold;
                   2134: {
                   2135:        int i;
                   2136:        int error;
                   2137: 
                   2138:        isakmp_cfg_config.network4 = (in_addr_t)0x00000000;
                   2139:        isakmp_cfg_config.netmask4 = (in_addr_t)0x00000000;
                   2140:        for (i = 0; i < MAXNS; i++)
                   2141:                isakmp_cfg_config.dns4[i] = (in_addr_t)0x00000000;
                   2142:        isakmp_cfg_config.dns4_index = 0;
                   2143:        for (i = 0; i < MAXWINS; i++)
                   2144:                isakmp_cfg_config.nbns4[i] = (in_addr_t)0x00000000;
                   2145:        isakmp_cfg_config.nbns4_index = 0;
                   2146:        if (cold == ISAKMP_CFG_INIT_COLD)
                   2147:                isakmp_cfg_config.port_pool = NULL;
                   2148:        isakmp_cfg_config.authsource = ISAKMP_CFG_AUTH_SYSTEM;
                   2149:        isakmp_cfg_config.groupsource = ISAKMP_CFG_GROUP_SYSTEM;
                   2150:        if (cold == ISAKMP_CFG_INIT_COLD) {
                   2151:                if (isakmp_cfg_config.grouplist != NULL) {
                   2152:                        for (i = 0; i < isakmp_cfg_config.groupcount; i++)
                   2153:                                racoon_free(isakmp_cfg_config.grouplist[i]);
                   2154:                        racoon_free(isakmp_cfg_config.grouplist);
                   2155:                }
                   2156:        }
                   2157:        isakmp_cfg_config.grouplist = NULL;
                   2158:        isakmp_cfg_config.groupcount = 0;
                   2159:        isakmp_cfg_config.confsource = ISAKMP_CFG_CONF_LOCAL;
                   2160:        isakmp_cfg_config.accounting = ISAKMP_CFG_ACCT_NONE;
                   2161:        if (cold == ISAKMP_CFG_INIT_COLD)
                   2162:                isakmp_cfg_config.pool_size = 0;
                   2163:        isakmp_cfg_config.auth_throttle = THROTTLE_PENALTY;
                   2164:        strlcpy(isakmp_cfg_config.default_domain, ISAKMP_CFG_DEFAULT_DOMAIN,
                   2165:            MAXPATHLEN);
                   2166:        strlcpy(isakmp_cfg_config.motd, ISAKMP_CFG_MOTD, MAXPATHLEN);
                   2167: 
                   2168:        if (cold != ISAKMP_CFG_INIT_COLD )
                   2169:                if (isakmp_cfg_config.splitnet_list != NULL)
                   2170:                        splitnet_list_free(isakmp_cfg_config.splitnet_list,
                   2171:                                &isakmp_cfg_config.splitnet_count);
                   2172:        isakmp_cfg_config.splitnet_list = NULL;
                   2173:        isakmp_cfg_config.splitnet_count = 0;
                   2174:        isakmp_cfg_config.splitnet_type = 0;
                   2175: 
                   2176:        isakmp_cfg_config.pfs_group = 0;
                   2177:        isakmp_cfg_config.save_passwd = 0;
                   2178: 
                   2179:        if (cold != ISAKMP_CFG_INIT_COLD )
                   2180:                if (isakmp_cfg_config.splitdns_list != NULL)
                   2181:                        racoon_free(isakmp_cfg_config.splitdns_list);
                   2182:        isakmp_cfg_config.splitdns_list = NULL;
                   2183:        isakmp_cfg_config.splitdns_len = 0;
                   2184: 
                   2185: #if 0
                   2186:        if (cold == ISAKMP_CFG_INIT_COLD) {
                   2187:                if ((error = isakmp_cfg_resize_pool(ISAKMP_CFG_MAX_CNX)) != 0)
                   2188:                        return error;
                   2189:        }
                   2190: #endif
                   2191: 
                   2192:        return 0;
                   2193: }
                   2194: 

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