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

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

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