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

1.1     ! misho       1: /*     $NetBSD: isakmp_xauth.c,v 1.22 2011/03/14 15:50:36 vanhu Exp $  */
        !             2: 
        !             3: /* Id: isakmp_xauth.c,v 1.38 2006/08/22 18:17:17 manubsd Exp */
        !             4: 
        !             5: /*
        !             6:  * Copyright (C) 2004-2005 Emmanuel Dreyfus
        !             7:  * All rights reserved.
        !             8:  * 
        !             9:  * Redistribution and use in source and binary forms, with or without
        !            10:  * modification, are permitted provided that the following conditions
        !            11:  * are met:
        !            12:  * 1. Redistributions of source code must retain the above copyright
        !            13:  *    notice, this list of conditions and the following disclaimer.
        !            14:  * 2. Redistributions in binary form must reproduce the above copyright
        !            15:  *    notice, this list of conditions and the following disclaimer in the
        !            16:  *    documentation and/or other materials provided with the distribution.
        !            17:  * 3. Neither the name of the project nor the names of its contributors
        !            18:  *    may be used to endorse or promote products derived from this software
        !            19:  *    without specific prior written permission.
        !            20:  * 
        !            21:  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
        !            22:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        !            23:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        !            24:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
        !            25:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        !            26:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        !            27:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            28:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        !            29:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        !            30:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        !            31:  * SUCH DAMAGE.
        !            32:  */
        !            33: 
        !            34: #include "config.h"
        !            35: 
        !            36: #include <sys/types.h>
        !            37: #include <sys/param.h>
        !            38: #include <sys/socket.h>
        !            39: #include <sys/queue.h>
        !            40: 
        !            41: #include <netinet/in.h>
        !            42: 
        !            43: #include <assert.h>
        !            44: #include <stdlib.h>
        !            45: #include <stdio.h>
        !            46: #include <string.h>
        !            47: #include <errno.h>
        !            48: #include <pwd.h>
        !            49: #include <grp.h>
        !            50: #if TIME_WITH_SYS_TIME
        !            51: # include <sys/time.h>
        !            52: # include <time.h>
        !            53: #else
        !            54: # if HAVE_SYS_TIME_H
        !            55: #  include <sys/time.h>
        !            56: # else
        !            57: #  include <time.h>
        !            58: # endif
        !            59: #endif
        !            60: #include <netdb.h>
        !            61: #ifdef HAVE_UNISTD_H
        !            62: #include <unistd.h>
        !            63: #endif
        !            64: #include <ctype.h>
        !            65: #include <resolv.h>
        !            66: 
        !            67: #ifdef HAVE_SHADOW_H
        !            68: #include <shadow.h>
        !            69: #endif
        !            70: 
        !            71: #include "var.h"
        !            72: #include "misc.h"
        !            73: #include "vmbuf.h"
        !            74: #include "plog.h"
        !            75: #include "sockmisc.h"
        !            76: #include "schedule.h"
        !            77: #include "debug.h"
        !            78: 
        !            79: #include "crypto_openssl.h"
        !            80: #include "isakmp_var.h"
        !            81: #include "isakmp.h"
        !            82: #include "admin.h"
        !            83: #include "privsep.h"
        !            84: #include "evt.h"
        !            85: #include "handler.h"
        !            86: #include "throttle.h"
        !            87: #include "remoteconf.h"
        !            88: #include "isakmp_inf.h"
        !            89: #include "isakmp_xauth.h"
        !            90: #include "isakmp_unity.h"
        !            91: #include "isakmp_cfg.h"
        !            92: #include "strnames.h"
        !            93: #include "ipsec_doi.h"
        !            94: #include "remoteconf.h"
        !            95: #include "localconf.h"
        !            96: 
        !            97: #ifdef HAVE_LIBRADIUS
        !            98: #include <radlib.h>
        !            99: struct rad_handle *radius_auth_state = NULL;
        !           100: struct rad_handle *radius_acct_state = NULL;
        !           101: struct xauth_rad_config xauth_rad_config;
        !           102: #endif
        !           103: 
        !           104: #ifdef HAVE_LIBPAM
        !           105: #include <security/pam_appl.h>
        !           106: 
        !           107: static char *PAM_usr = NULL;
        !           108: static char *PAM_pwd = NULL;
        !           109: static int PAM_conv(int, const struct pam_message **, 
        !           110:     struct pam_response **, void *);
        !           111: static struct pam_conv PAM_chat = { &PAM_conv, NULL };
        !           112: #endif
        !           113: 
        !           114: #ifdef HAVE_LIBLDAP
        !           115: #include "ldap.h"
        !           116: #include <arpa/inet.h>
        !           117: struct xauth_ldap_config xauth_ldap_config;
        !           118: #endif
        !           119: 
        !           120: void 
        !           121: xauth_sendreq(iph1)
        !           122:        struct ph1handle *iph1;
        !           123: {
        !           124:        vchar_t *buffer;
        !           125:        struct isakmp_pl_attr *attr;
        !           126:        struct isakmp_data *typeattr;
        !           127:        struct isakmp_data *usrattr;
        !           128:        struct isakmp_data *pwdattr;
        !           129:        struct xauth_state *xst = &iph1->mode_cfg->xauth;
        !           130:        size_t tlen;
        !           131: 
        !           132:        /* Status checks */
        !           133:        if (iph1->status < PHASE1ST_ESTABLISHED) {
        !           134:                plog(LLV_ERROR, LOCATION, NULL, 
        !           135:                    "Xauth request while phase 1 is not completed\n");
        !           136:                return;
        !           137:        }
        !           138: 
        !           139:        if (xst->status != XAUTHST_NOTYET) {
        !           140:                plog(LLV_ERROR, LOCATION, NULL, 
        !           141:                    "Xauth request whith Xauth state %d\n", xst->status);
        !           142:                return;
        !           143:        }
        !           144: 
        !           145:        plog(LLV_INFO, LOCATION, NULL, "Sending Xauth request\n");
        !           146: 
        !           147:        tlen = sizeof(*attr) +
        !           148:               + sizeof(*typeattr) +
        !           149:               + sizeof(*usrattr) +
        !           150:               + sizeof(*pwdattr);
        !           151:        
        !           152:        if ((buffer = vmalloc(tlen)) == NULL) {
        !           153:                plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate buffer\n");
        !           154:                return;
        !           155:        }
        !           156:        
        !           157:        attr = (struct isakmp_pl_attr *)buffer->v;
        !           158:        memset(attr, 0, tlen);
        !           159: 
        !           160:        attr->h.len = htons(tlen);
        !           161:        attr->type = ISAKMP_CFG_REQUEST;
        !           162:        attr->id = htons(eay_random());
        !           163: 
        !           164:        typeattr = (struct isakmp_data *)(attr + 1);
        !           165:        typeattr->type = htons(XAUTH_TYPE | ISAKMP_GEN_TV);
        !           166:        typeattr->lorv = htons(XAUTH_TYPE_GENERIC);
        !           167: 
        !           168:        usrattr = (struct isakmp_data *)(typeattr + 1);
        !           169:        usrattr->type = htons(XAUTH_USER_NAME | ISAKMP_GEN_TLV);
        !           170:        usrattr->lorv = htons(0);
        !           171: 
        !           172:        pwdattr = (struct isakmp_data *)(usrattr + 1);
        !           173:        pwdattr->type = htons(XAUTH_USER_PASSWORD | ISAKMP_GEN_TLV);
        !           174:        pwdattr->lorv = htons(0);
        !           175: 
        !           176:        isakmp_cfg_send(iph1, buffer, 
        !           177:            ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 1);
        !           178:        
        !           179:        vfree(buffer);
        !           180: 
        !           181:        xst->status = XAUTHST_REQSENT;
        !           182: 
        !           183:        return;
        !           184: }
        !           185: 
        !           186: int
        !           187: xauth_attr_reply(iph1, attr, id)
        !           188:        struct ph1handle *iph1;
        !           189:        struct isakmp_data *attr;
        !           190:        int id;
        !           191: {
        !           192:        char **outlet = NULL;
        !           193:        size_t alen = 0;
        !           194:        int type;
        !           195:        struct xauth_state *xst = &iph1->mode_cfg->xauth;
        !           196: 
        !           197:        if ((iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) == 0) {
        !           198:                plog(LLV_ERROR, LOCATION, NULL, 
        !           199:                    "Xauth reply but peer did not declare "
        !           200:                    "itself as Xauth capable\n");
        !           201:                return -1;
        !           202:        }
        !           203: 
        !           204:        if (xst->status != XAUTHST_REQSENT) {
        !           205:                plog(LLV_ERROR, LOCATION, NULL, 
        !           206:                    "Xauth reply while Xauth state is %d\n", xst->status);
        !           207:                return -1;
        !           208:        }
        !           209: 
        !           210:        type = ntohs(attr->type) & ~ISAKMP_GEN_MASK;
        !           211:        switch (type) {
        !           212:        case XAUTH_TYPE:
        !           213:                switch (ntohs(attr->lorv)) {
        !           214:                case XAUTH_TYPE_GENERIC:
        !           215:                        xst->authtype = XAUTH_TYPE_GENERIC;
        !           216:                        break;
        !           217:                default:
        !           218:                        plog(LLV_WARNING, LOCATION, NULL, 
        !           219:                            "Unexpected authentication type %d\n", 
        !           220:                            ntohs(type));
        !           221:                        return -1;
        !           222:                }
        !           223:                break;
        !           224: 
        !           225:        case XAUTH_USER_NAME:
        !           226:                outlet = &xst->authdata.generic.usr;
        !           227:                break;
        !           228: 
        !           229:        case XAUTH_USER_PASSWORD:
        !           230:                outlet = &xst->authdata.generic.pwd; 
        !           231:                break;
        !           232: 
        !           233:        default:
        !           234:                plog(LLV_WARNING, LOCATION, NULL, 
        !           235:                    "ignored Xauth attribute %d\n", type);
        !           236:                break;
        !           237:        }
        !           238: 
        !           239:        if (outlet != NULL) {
        !           240:                alen = ntohs(attr->lorv);
        !           241: 
        !           242:                if ((*outlet = racoon_malloc(alen + 1)) == NULL) {
        !           243:                        plog(LLV_ERROR, LOCATION, NULL, 
        !           244:                            "Cannot allocate memory for Xauth Data\n");
        !           245:                        return -1;
        !           246:                }
        !           247: 
        !           248:                memcpy(*outlet, attr + 1, alen);
        !           249:                (*outlet)[alen] = '\0';
        !           250:                outlet = NULL;
        !           251:        }
        !           252: 
        !           253:        
        !           254:        if ((xst->authdata.generic.usr != NULL) &&
        !           255:           (xst->authdata.generic.pwd != NULL)) {
        !           256:                int port;
        !           257:                int res;
        !           258:                char *usr = xst->authdata.generic.usr;
        !           259:                char *pwd = xst->authdata.generic.pwd;
        !           260:                time_t throttle_delay = 0;
        !           261: 
        !           262: #if 0  /* Real debug, don't do that at home */
        !           263:                plog(LLV_DEBUG, LOCATION, NULL, 
        !           264:                    "Got username \"%s\", password \"%s\"\n", usr, pwd);
        !           265: #endif
        !           266:                strncpy(iph1->mode_cfg->login, usr, LOGINLEN);
        !           267:                iph1->mode_cfg->login[LOGINLEN] = '\0';
        !           268: 
        !           269:                res = -1;
        !           270:                if ((port = isakmp_cfg_getport(iph1)) == -1) {
        !           271:                        plog(LLV_ERROR, LOCATION, NULL, 
        !           272:                            "Port pool depleted\n");
        !           273:                        goto skip_auth;
        !           274:                }       
        !           275: 
        !           276:                switch (isakmp_cfg_config.authsource) {
        !           277:                case ISAKMP_CFG_AUTH_SYSTEM:
        !           278:                        res = privsep_xauth_login_system(usr, pwd);
        !           279:                        break;
        !           280: #ifdef HAVE_LIBRADIUS
        !           281:                case ISAKMP_CFG_AUTH_RADIUS:
        !           282:                        res = xauth_login_radius(iph1, usr, pwd);
        !           283:                        break;
        !           284: #endif
        !           285: #ifdef HAVE_LIBPAM
        !           286:                case ISAKMP_CFG_AUTH_PAM:
        !           287:                        res = privsep_xauth_login_pam(iph1->mode_cfg->port, 
        !           288:                            iph1->remote, usr, pwd);
        !           289:                        break;
        !           290: #endif
        !           291: #ifdef HAVE_LIBLDAP
        !           292:                case ISAKMP_CFG_AUTH_LDAP:
        !           293:                        res = xauth_login_ldap(iph1, usr, pwd);
        !           294:                        break;
        !           295: #endif
        !           296:                default:
        !           297:                        plog(LLV_ERROR, LOCATION, NULL, 
        !           298:                            "Unexpected authentication source\n");
        !           299:                        res = -1;
        !           300:                        break;
        !           301:                }
        !           302: 
        !           303:                /*
        !           304:                 * Optional group authentication
        !           305:                 */
        !           306:                if (!res && (isakmp_cfg_config.groupcount))
        !           307:                        res = group_check(iph1,
        !           308:                                isakmp_cfg_config.grouplist,
        !           309:                                isakmp_cfg_config.groupcount);
        !           310: 
        !           311:                /*
        !           312:                 * On failure, throttle the connexion for the remote host
        !           313:                 * in order to make password attacks more difficult.
        !           314:                 */
        !           315:                throttle_delay = throttle_host(iph1->remote, res);
        !           316:                if (throttle_delay > 0) {
        !           317:                        char *str;
        !           318: 
        !           319:                        str = saddrwop2str(iph1->remote);
        !           320: 
        !           321:                        plog(LLV_ERROR, LOCATION, NULL, 
        !           322:                            "Throttling in action for %s: delay %lds\n",
        !           323:                            str, (unsigned long)throttle_delay);
        !           324:                        res = -1;
        !           325:                } else {
        !           326:                        throttle_delay = 0;
        !           327:                }
        !           328: 
        !           329: skip_auth:
        !           330:                if (throttle_delay != 0) {
        !           331:                        struct xauth_reply_arg *xra;
        !           332: 
        !           333:                        if ((xra = racoon_calloc(1, sizeof(*xra))) == NULL) {
        !           334:                                plog(LLV_ERROR, LOCATION, NULL, 
        !           335:                                    "malloc failed, bypass throttling\n");
        !           336:                                return xauth_reply(iph1, port, id, res);
        !           337:                        }
        !           338: 
        !           339:                        /*
        !           340:                         * We need to store the ph1, but it might have
        !           341:                         * disapeared when xauth_reply is called, so
        !           342:                         * store the index instead.
        !           343:                         */
        !           344:                        xra->index = iph1->index;
        !           345:                        xra->port = port;
        !           346:                        xra->id = id;
        !           347:                        xra->res = res;
        !           348:                        sched_schedule(&xra->sc, throttle_delay,
        !           349:                                       xauth_reply_stub);
        !           350:                } else {
        !           351:                        return xauth_reply(iph1, port, id, res);
        !           352:                }
        !           353:        }
        !           354: 
        !           355:        return 0;
        !           356: }
        !           357: 
        !           358: void 
        !           359: xauth_reply_stub(sc)
        !           360:        struct sched *sc;
        !           361: {
        !           362:        struct xauth_reply_arg *xra = container_of(sc, struct xauth_reply_arg, sc);
        !           363:        struct ph1handle *iph1;
        !           364: 
        !           365:        if ((iph1 = getph1byindex(&xra->index)) != NULL)
        !           366:                (void)xauth_reply(iph1, xra->port, xra->id, xra->res);
        !           367:        else
        !           368:                plog(LLV_ERROR, LOCATION, NULL, 
        !           369:                    "Delayed Xauth reply: phase 1 no longer exists.\n"); 
        !           370: 
        !           371:        racoon_free(xra);
        !           372: }
        !           373: 
        !           374: int
        !           375: xauth_reply(iph1, port, id, res)
        !           376:        struct ph1handle *iph1;
        !           377:        int port;
        !           378:        int id;
        !           379: {
        !           380:        struct xauth_state *xst = &iph1->mode_cfg->xauth;
        !           381:        char *usr = xst->authdata.generic.usr;
        !           382: 
        !           383:        if (res != 0) {
        !           384:                if (port != -1)
        !           385:                        isakmp_cfg_putport(iph1, port);
        !           386: 
        !           387:                plog(LLV_INFO, LOCATION, NULL, 
        !           388:                    "login failed for user \"%s\"\n", usr);
        !           389:                
        !           390:                xauth_sendstatus(iph1, XAUTH_STATUS_FAIL, id);
        !           391:                xst->status = XAUTHST_NOTYET;
        !           392: 
        !           393:                /* Delete Phase 1 SA */
        !           394:                if (iph1->status >= PHASE1ST_ESTABLISHED)
        !           395:                        isakmp_info_send_d1(iph1);
        !           396:                remph1(iph1);
        !           397:                delph1(iph1);
        !           398: 
        !           399:                return -1;
        !           400:        }
        !           401: 
        !           402:        xst->status = XAUTHST_OK;
        !           403:        plog(LLV_INFO, LOCATION, NULL, 
        !           404:            "login succeeded for user \"%s\"\n", usr);
        !           405: 
        !           406:        xauth_sendstatus(iph1, XAUTH_STATUS_OK, id);
        !           407: 
        !           408:        return 0;
        !           409: }
        !           410: 
        !           411: void
        !           412: xauth_sendstatus(iph1, status, id)
        !           413:        struct ph1handle *iph1;
        !           414:        int status;
        !           415:        int id;
        !           416: {
        !           417:        vchar_t *buffer;
        !           418:        struct isakmp_pl_attr *attr;
        !           419:        struct isakmp_data *stattr;
        !           420:        size_t tlen;
        !           421: 
        !           422:        tlen = sizeof(*attr) +
        !           423:               + sizeof(*stattr); 
        !           424:        
        !           425:        if ((buffer = vmalloc(tlen)) == NULL) {
        !           426:                plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate buffer\n");
        !           427:                return;
        !           428:        }
        !           429:        
        !           430:        attr = (struct isakmp_pl_attr *)buffer->v;
        !           431:        memset(attr, 0, tlen);
        !           432: 
        !           433:        attr->h.len = htons(tlen);
        !           434:        attr->type = ISAKMP_CFG_SET;
        !           435:        attr->id = htons(id);
        !           436: 
        !           437:        stattr = (struct isakmp_data *)(attr + 1);
        !           438:        stattr->type = htons(XAUTH_STATUS | ISAKMP_GEN_TV);
        !           439:        stattr->lorv = htons(status);
        !           440: 
        !           441:        isakmp_cfg_send(iph1, buffer, 
        !           442:            ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 1);
        !           443:        
        !           444:        vfree(buffer);
        !           445: 
        !           446:        return; 
        !           447: }
        !           448: 
        !           449: #ifdef HAVE_LIBRADIUS
        !           450: int
        !           451: xauth_radius_init_conf(int free)
        !           452: {
        !           453:        /* free radius config resources */
        !           454:        if (free) {
        !           455:                int i;
        !           456:                for (i = 0; i < xauth_rad_config.auth_server_count; i++) {
        !           457:                        vfree(xauth_rad_config.auth_server_list[i].host);
        !           458:                        vfree(xauth_rad_config.auth_server_list[i].secret);
        !           459:                }
        !           460:                for (i = 0; i < xauth_rad_config.acct_server_count; i++) {
        !           461:                        vfree(xauth_rad_config.acct_server_list[i].host);
        !           462:                        vfree(xauth_rad_config.acct_server_list[i].secret);
        !           463:                }
        !           464:                if (radius_auth_state != NULL)
        !           465:                        rad_close(radius_auth_state);
        !           466:                if (radius_acct_state != NULL)
        !           467:                        rad_close(radius_acct_state);
        !           468:        }
        !           469: 
        !           470:        /* initialize radius config */
        !           471:        memset(&xauth_rad_config, 0, sizeof(xauth_rad_config));
        !           472:        return 0;
        !           473: }
        !           474: 
        !           475: int
        !           476: xauth_radius_init(void)
        !           477: {
        !           478:        /* For first time use, initialize Radius */
        !           479:        if ((isakmp_cfg_config.authsource == ISAKMP_CFG_AUTH_RADIUS) &&
        !           480:            (radius_auth_state == NULL)) {
        !           481:                if ((radius_auth_state = rad_auth_open()) == NULL) {
        !           482:                        plog(LLV_ERROR, LOCATION, NULL, 
        !           483:                            "Cannot init libradius\n");
        !           484:                        return -1;
        !           485:                }
        !           486: 
        !           487:                int auth_count = xauth_rad_config.auth_server_count;
        !           488:                int auth_added = 0;
        !           489:                if (auth_count) {
        !           490:                        int i;
        !           491:                        for (i = 0; i < auth_count; i++) {
        !           492:                                if(!rad_add_server(
        !           493:                                        radius_auth_state,
        !           494:                                        xauth_rad_config.auth_server_list[i].host->v,
        !           495:                                        xauth_rad_config.auth_server_list[i].port,
        !           496:                                        xauth_rad_config.auth_server_list[i].secret->v,
        !           497:                                        xauth_rad_config.timeout,
        !           498:                                        xauth_rad_config.retries ))
        !           499:                                        auth_added++;
        !           500:                                else
        !           501:                                        plog(LLV_WARNING, LOCATION, NULL,
        !           502:                                                "could not add radius auth server %s\n",
        !           503:                                                xauth_rad_config.auth_server_list[i].host->v);
        !           504:                        }
        !           505:                }
        !           506: 
        !           507:                if (!auth_added) {
        !           508:                        if (rad_config(radius_auth_state, NULL) != 0) {
        !           509:                                plog(LLV_ERROR, LOCATION, NULL, 
        !           510:                                    "Cannot open libradius config file: %s\n", 
        !           511:                                    rad_strerror(radius_auth_state));
        !           512:                                rad_close(radius_auth_state);
        !           513:                                radius_auth_state = NULL;
        !           514:                                return -1;
        !           515:                        }
        !           516:                }
        !           517:        }
        !           518: 
        !           519:        if ((isakmp_cfg_config.accounting == ISAKMP_CFG_ACCT_RADIUS) &&
        !           520:            (radius_acct_state == NULL)) {
        !           521:                if ((radius_acct_state = rad_acct_open()) == NULL) {
        !           522:                        plog(LLV_ERROR, LOCATION, NULL, 
        !           523:                            "Cannot init libradius\n");
        !           524:                        return -1;
        !           525:                }
        !           526: 
        !           527:                int acct_count = xauth_rad_config.acct_server_count;
        !           528:                int acct_added = 0;
        !           529:                if (acct_count) {
        !           530:                        int i;
        !           531:                        for (i = 0; i < acct_count; i++) {
        !           532:                                if(!rad_add_server(
        !           533:                                        radius_acct_state,
        !           534:                                        xauth_rad_config.acct_server_list[i].host->v,
        !           535:                                        xauth_rad_config.acct_server_list[i].port,
        !           536:                                        xauth_rad_config.acct_server_list[i].secret->v,
        !           537:                                        xauth_rad_config.timeout,
        !           538:                                        xauth_rad_config.retries ))
        !           539:                                        acct_added++;
        !           540:                                else
        !           541:                                        plog(LLV_WARNING, LOCATION, NULL,
        !           542:                                                "could not add radius account server %s\n",
        !           543:                                                xauth_rad_config.acct_server_list[i].host->v);
        !           544:                        }
        !           545:                }
        !           546: 
        !           547:                if (!acct_added) {
        !           548:                        if (rad_config(radius_acct_state, NULL) != 0) {
        !           549:                                plog(LLV_ERROR, LOCATION, NULL, 
        !           550:                                    "Cannot open libradius config file: %s\n", 
        !           551:                                    rad_strerror(radius_acct_state));
        !           552:                                rad_close(radius_acct_state);
        !           553:                                radius_acct_state = NULL;
        !           554:                                return -1;
        !           555:                        }
        !           556:                }
        !           557:        }
        !           558: 
        !           559:        return 0;
        !           560: }
        !           561: 
        !           562: int
        !           563: xauth_login_radius(iph1, usr, pwd)
        !           564:        struct ph1handle *iph1;
        !           565:        char *usr;
        !           566:        char *pwd;
        !           567: {
        !           568:        int res;
        !           569:        const void *data;
        !           570:        size_t len;
        !           571:        int type;
        !           572: 
        !           573:        if (rad_create_request(radius_auth_state, RAD_ACCESS_REQUEST) != 0) {
        !           574:                plog(LLV_ERROR, LOCATION, NULL, 
        !           575:                    "rad_create_request failed: %s\n", 
        !           576:                    rad_strerror(radius_auth_state));
        !           577:                return -1;
        !           578:        }
        !           579:        
        !           580:        if (rad_put_string(radius_auth_state, RAD_USER_NAME, usr) != 0) {
        !           581:                plog(LLV_ERROR, LOCATION, NULL, 
        !           582:                    "rad_put_string failed: %s\n", 
        !           583:                    rad_strerror(radius_auth_state));
        !           584:                return -1;
        !           585:        }
        !           586: 
        !           587:        if (rad_put_string(radius_auth_state, RAD_USER_PASSWORD, pwd) != 0) {
        !           588:                plog(LLV_ERROR, LOCATION, NULL, 
        !           589:                    "rad_put_string failed: %s\n", 
        !           590:                    rad_strerror(radius_auth_state));
        !           591:                return -1;
        !           592:        }
        !           593: 
        !           594:        if (isakmp_cfg_radius_common(radius_auth_state, iph1->mode_cfg->port) != 0)
        !           595:                return -1;
        !           596: 
        !           597:        switch (res = rad_send_request(radius_auth_state)) {
        !           598:        case RAD_ACCESS_ACCEPT:
        !           599:                while ((type = rad_get_attr(radius_auth_state, &data, &len)) != 0) {
        !           600:                        switch (type) {
        !           601:                        case RAD_FRAMED_IP_ADDRESS:
        !           602:                                iph1->mode_cfg->addr4 = rad_cvt_addr(data);
        !           603:                                iph1->mode_cfg->flags 
        !           604:                                    |= ISAKMP_CFG_ADDR4_EXTERN;
        !           605:                                break;
        !           606: 
        !           607:                        case RAD_FRAMED_IP_NETMASK:
        !           608:                                iph1->mode_cfg->mask4 = rad_cvt_addr(data);
        !           609:                                iph1->mode_cfg->flags 
        !           610:                                    |= ISAKMP_CFG_MASK4_EXTERN;
        !           611:                                break;
        !           612: 
        !           613:                        default:
        !           614:                                plog(LLV_INFO, LOCATION, NULL,
        !           615:                                    "Unexpected attribute: %d\n", type);
        !           616:                                break;
        !           617:                        }
        !           618:                }
        !           619: 
        !           620:                return 0;
        !           621:                break;
        !           622: 
        !           623:        case RAD_ACCESS_REJECT:
        !           624:                return -1;
        !           625:                break;
        !           626: 
        !           627:        case -1:
        !           628:                plog(LLV_ERROR, LOCATION, NULL, 
        !           629:                    "rad_send_request failed: %s\n", 
        !           630:                    rad_strerror(radius_auth_state));
        !           631:                return -1;
        !           632:                break;
        !           633:        default:
        !           634:                plog(LLV_ERROR, LOCATION, NULL, 
        !           635:                    "rad_send_request returned %d\n", res);
        !           636:                return -1;
        !           637:                break;
        !           638:        }
        !           639: 
        !           640:        return -1;
        !           641: }
        !           642: #endif
        !           643: 
        !           644: #ifdef HAVE_LIBPAM
        !           645: static int 
        !           646: PAM_conv(msg_count, msg, rsp, dontcare)
        !           647:        int msg_count;
        !           648:        const struct pam_message **msg;
        !           649:        struct pam_response **rsp;
        !           650:        void *dontcare;
        !           651: {
        !           652:        int i;
        !           653:        int replies = 0;
        !           654:        struct pam_response *reply = NULL;
        !           655: 
        !           656:        if ((reply = racoon_malloc(sizeof(*reply) * msg_count)) == NULL) 
        !           657:                return PAM_CONV_ERR;
        !           658:        bzero(reply, sizeof(*reply) * msg_count);
        !           659: 
        !           660:        for (i = 0; i < msg_count; i++) {
        !           661:                switch (msg[i]->msg_style) {
        !           662:                case PAM_PROMPT_ECHO_ON:
        !           663:                        /* Send the username, libpam frees resp */
        !           664:                        reply[i].resp_retcode = PAM_SUCCESS;
        !           665:                        if ((reply[i].resp = strdup(PAM_usr)) == NULL) {
        !           666:                                plog(LLV_ERROR, LOCATION, 
        !           667:                                    NULL, "strdup failed\n");
        !           668:                                exit(1);
        !           669:                        }
        !           670:                        break;
        !           671: 
        !           672:                case PAM_PROMPT_ECHO_OFF:
        !           673:                        /* Send the password, libpam frees resp */
        !           674:                        reply[i].resp_retcode = PAM_SUCCESS;
        !           675:                        if ((reply[i].resp = strdup(PAM_pwd)) == NULL) {
        !           676:                                plog(LLV_ERROR, LOCATION, 
        !           677:                                    NULL, "strdup failed\n");
        !           678:                                exit(1);
        !           679:                        }
        !           680:                        break;
        !           681: 
        !           682:                case PAM_TEXT_INFO:
        !           683:                case PAM_ERROR_MSG:
        !           684:                        reply[i].resp_retcode = PAM_SUCCESS;
        !           685:                        reply[i].resp = NULL;
        !           686:                        break;
        !           687: 
        !           688:                default:
        !           689:                        if (reply != NULL)
        !           690:                                racoon_free(reply);
        !           691:                        return PAM_CONV_ERR;
        !           692:                        break;
        !           693:                }
        !           694:        }
        !           695: 
        !           696:        if (reply != NULL)
        !           697:                *rsp = reply;
        !           698: 
        !           699:        return PAM_SUCCESS;
        !           700: }
        !           701: 
        !           702: int
        !           703: xauth_login_pam(port, raddr, usr, pwd)
        !           704:        int port;
        !           705:        struct sockaddr *raddr;
        !           706:        char *usr;
        !           707:        char *pwd;
        !           708: {
        !           709:        int error;
        !           710:        int res;
        !           711:        const void *data;
        !           712:        size_t len;
        !           713:        int type;
        !           714:        char *remote = NULL;
        !           715:        pam_handle_t *pam = NULL;
        !           716: 
        !           717:        if (isakmp_cfg_config.port_pool == NULL) {
        !           718:                plog(LLV_ERROR, LOCATION, NULL,
        !           719:                    "isakmp_cfg_config.port_pool == NULL\n");
        !           720:                return -1;
        !           721:        }
        !           722: 
        !           723:        if ((error = pam_start("racoon", usr, 
        !           724:            &PAM_chat, &isakmp_cfg_config.port_pool[port].pam)) != 0) {
        !           725:                if (isakmp_cfg_config.port_pool[port].pam == NULL) {
        !           726:                        plog(LLV_ERROR, LOCATION, NULL, "pam_start failed\n");
        !           727:                        return -1;
        !           728:                } else {
        !           729:                        plog(LLV_ERROR, LOCATION, NULL, 
        !           730:                            "pam_start failed: %s\n", 
        !           731:                            pam_strerror(isakmp_cfg_config.port_pool[port].pam,
        !           732:                            error));
        !           733:                        goto out;
        !           734:                }
        !           735:        }
        !           736:        pam = isakmp_cfg_config.port_pool[port].pam;
        !           737: 
        !           738:        if ((remote = strdup(saddrwop2str(raddr))) == NULL) {
        !           739:                plog(LLV_ERROR, LOCATION, NULL,
        !           740:                    "cannot allocate memory: %s\n", strerror(errno)); 
        !           741:                goto out;
        !           742:        }
        !           743: 
        !           744:        if ((error = pam_set_item(pam, PAM_RHOST, remote)) != 0) {
        !           745:                plog(LLV_ERROR, LOCATION, NULL, 
        !           746:                    "pam_set_item failed: %s\n", 
        !           747:                    pam_strerror(pam, error));
        !           748:                goto out;
        !           749:        }
        !           750: 
        !           751:        if ((error = pam_set_item(pam, PAM_RUSER, usr)) != 0) {
        !           752:                plog(LLV_ERROR, LOCATION, NULL, 
        !           753:                    "pam_set_item failed: %s\n", 
        !           754:                    pam_strerror(pam, error));
        !           755:                goto out;
        !           756:        }
        !           757: 
        !           758:        PAM_usr = usr;
        !           759:        PAM_pwd = pwd;
        !           760:        error = pam_authenticate(pam, 0);
        !           761:        PAM_usr = NULL;
        !           762:        PAM_pwd = NULL;
        !           763:        if (error != 0) {
        !           764:                plog(LLV_ERROR, LOCATION, NULL, 
        !           765:                    "pam_authenticate failed: %s\n", 
        !           766:                    pam_strerror(pam, error));
        !           767:                goto out;
        !           768:        }
        !           769: 
        !           770:        if ((error = pam_acct_mgmt(pam, 0)) != 0) {
        !           771:                plog(LLV_ERROR, LOCATION, NULL, 
        !           772:                    "pam_acct_mgmt failed: %s\n", 
        !           773:                    pam_strerror(pam, error));
        !           774:                goto out;
        !           775:        }
        !           776: 
        !           777:        if ((error = pam_setcred(pam, 0)) != 0) {
        !           778:                plog(LLV_ERROR, LOCATION, NULL, 
        !           779:                    "pam_setcred failed: %s\n", 
        !           780:                    pam_strerror(pam, error));
        !           781:                goto out;
        !           782:        }
        !           783: 
        !           784:        if (remote != NULL)
        !           785:                free(remote);
        !           786: 
        !           787:        return 0;
        !           788: 
        !           789: out:
        !           790:        pam_end(pam, error);
        !           791:        isakmp_cfg_config.port_pool[port].pam = NULL;
        !           792:        if (remote != NULL)
        !           793:                free(remote);
        !           794:        return -1;
        !           795: }
        !           796: #endif
        !           797: 
        !           798: #ifdef HAVE_LIBLDAP
        !           799: int 
        !           800: xauth_ldap_init_conf(void)
        !           801: {
        !           802:        int tmplen;
        !           803:        int error = -1;
        !           804: 
        !           805:        xauth_ldap_config.pver = 3;
        !           806:        xauth_ldap_config.host = NULL;
        !           807:        xauth_ldap_config.port = LDAP_PORT;
        !           808:        xauth_ldap_config.base = NULL;
        !           809:        xauth_ldap_config.subtree = 0;
        !           810:        xauth_ldap_config.bind_dn = NULL;
        !           811:        xauth_ldap_config.bind_pw = NULL;
        !           812:        xauth_ldap_config.auth_type = LDAP_AUTH_SIMPLE;
        !           813:        xauth_ldap_config.attr_user = NULL;
        !           814:        xauth_ldap_config.attr_addr = NULL;
        !           815:        xauth_ldap_config.attr_mask = NULL;
        !           816:        xauth_ldap_config.attr_group = NULL;
        !           817:        xauth_ldap_config.attr_member = NULL;
        !           818: 
        !           819:        /* set default host */
        !           820:        tmplen = strlen(LDAP_DFLT_HOST);
        !           821:        xauth_ldap_config.host = vmalloc(tmplen);
        !           822:        if (xauth_ldap_config.host == NULL)
        !           823:                goto out;
        !           824:        memcpy(xauth_ldap_config.host->v, LDAP_DFLT_HOST, tmplen);
        !           825: 
        !           826:        /* set default user naming attribute */
        !           827:        tmplen = strlen(LDAP_DFLT_USER);
        !           828:        xauth_ldap_config.attr_user = vmalloc(tmplen);
        !           829:        if (xauth_ldap_config.attr_user == NULL)
        !           830:                goto out;       
        !           831:        memcpy(xauth_ldap_config.attr_user->v, LDAP_DFLT_USER, tmplen);
        !           832: 
        !           833:        /* set default address attribute */
        !           834:        tmplen = strlen(LDAP_DFLT_ADDR);
        !           835:        xauth_ldap_config.attr_addr = vmalloc(tmplen);
        !           836:        if (xauth_ldap_config.attr_addr == NULL)
        !           837:                goto out;
        !           838:        memcpy(xauth_ldap_config.attr_addr->v, LDAP_DFLT_ADDR, tmplen);
        !           839: 
        !           840:        /* set default netmask attribute */
        !           841:        tmplen = strlen(LDAP_DFLT_MASK);
        !           842:        xauth_ldap_config.attr_mask = vmalloc(tmplen);
        !           843:        if (xauth_ldap_config.attr_mask == NULL)
        !           844:                goto out;
        !           845:        memcpy(xauth_ldap_config.attr_mask->v, LDAP_DFLT_MASK, tmplen);
        !           846: 
        !           847:        /* set default group naming attribute */
        !           848:        tmplen = strlen(LDAP_DFLT_GROUP);
        !           849:        xauth_ldap_config.attr_group = vmalloc(tmplen);
        !           850:        if (xauth_ldap_config.attr_group == NULL)
        !           851:                goto out;
        !           852:        memcpy(xauth_ldap_config.attr_group->v, LDAP_DFLT_GROUP, tmplen);
        !           853: 
        !           854:        /* set default member attribute */
        !           855:        tmplen = strlen(LDAP_DFLT_MEMBER);
        !           856:        xauth_ldap_config.attr_member = vmalloc(tmplen);
        !           857:        if (xauth_ldap_config.attr_member == NULL)
        !           858:                goto out;
        !           859:        memcpy(xauth_ldap_config.attr_member->v, LDAP_DFLT_MEMBER, tmplen);
        !           860: 
        !           861:        error = 0;
        !           862: out:
        !           863:        if (error != 0)
        !           864:                plog(LLV_ERROR, LOCATION, NULL, "cannot allocate memory\n");
        !           865: 
        !           866:        return error;
        !           867: }
        !           868: 
        !           869: int
        !           870: xauth_login_ldap(iph1, usr, pwd)
        !           871:        struct ph1handle *iph1;
        !           872:        char *usr;
        !           873:        char *pwd;
        !           874: {
        !           875:        int rtn = -1;
        !           876:        int res = -1;
        !           877:        LDAP *ld = NULL;
        !           878:        LDAPMessage *lr = NULL;
        !           879:        LDAPMessage *le = NULL;
        !           880:        struct berval cred;
        !           881:        struct berval **bv = NULL;
        !           882:        struct timeval timeout;
        !           883:        char *init = NULL;
        !           884:        char *filter = NULL;
        !           885:        char *atlist[3];
        !           886:        char *basedn = NULL;
        !           887:        char *userdn = NULL;
        !           888:        int tmplen = 0;
        !           889:        int ecount = 0;
        !           890:        int scope = LDAP_SCOPE_ONE;
        !           891: 
        !           892:        atlist[0] = NULL;
        !           893:        atlist[1] = NULL;
        !           894:        atlist[2] = NULL;
        !           895: 
        !           896:        /* build our initialization url */
        !           897:        tmplen = strlen("ldap://:") + 17;
        !           898:        tmplen += strlen(xauth_ldap_config.host->v);
        !           899:        init = racoon_malloc(tmplen);
        !           900:        if (init == NULL) {
        !           901:                plog(LLV_ERROR, LOCATION, NULL,
        !           902:                        "unable to alloc ldap init url\n");
        !           903:                goto ldap_end;
        !           904:        }
        !           905:        sprintf(init,"ldap://%s:%d",
        !           906:                xauth_ldap_config.host->v,
        !           907:                xauth_ldap_config.port );
        !           908: 
        !           909:        /* initialize the ldap handle */
        !           910:        res = ldap_initialize(&ld, init);
        !           911:        if (res != LDAP_SUCCESS) {
        !           912:                plog(LLV_ERROR, LOCATION, NULL,
        !           913:                        "ldap_initialize failed: %s\n",
        !           914:                        ldap_err2string(res));
        !           915:                goto ldap_end;
        !           916:        }
        !           917: 
        !           918:        /* initialize the protocol version */
        !           919:        ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION,
        !           920:                &xauth_ldap_config.pver);
        !           921: 
        !           922:        /*
        !           923:         * attempt to bind to the ldap server.
        !           924:          * default to anonymous bind unless a
        !           925:         * user dn and password has been
        !           926:         * specified in our configuration
        !           927:          */
        !           928:        if ((xauth_ldap_config.bind_dn != NULL)&&
        !           929:            (xauth_ldap_config.bind_pw != NULL))
        !           930:        {
        !           931:                cred.bv_val = xauth_ldap_config.bind_pw->v;
        !           932:                cred.bv_len = strlen( cred.bv_val );
        !           933:                res = ldap_sasl_bind_s(ld,
        !           934:                        xauth_ldap_config.bind_dn->v, NULL, &cred,
        !           935:                        NULL, NULL, NULL);
        !           936:        }
        !           937:        else
        !           938:        {
        !           939:                res = ldap_sasl_bind_s(ld,
        !           940:                        NULL, NULL, NULL,
        !           941:                        NULL, NULL, NULL);
        !           942:        }
        !           943:        
        !           944:        if (res!=LDAP_SUCCESS) {
        !           945:                plog(LLV_ERROR, LOCATION, NULL,
        !           946:                        "ldap_sasl_bind_s (search) failed: %s\n",
        !           947:                        ldap_err2string(res));
        !           948:                goto ldap_end;
        !           949:        }
        !           950: 
        !           951:        /* build an ldap user search filter */
        !           952:        tmplen = strlen(xauth_ldap_config.attr_user->v);
        !           953:        tmplen += 1;
        !           954:        tmplen += strlen(usr);
        !           955:        tmplen += 1;
        !           956:        filter = racoon_malloc(tmplen);
        !           957:        if (filter == NULL) {
        !           958:                plog(LLV_ERROR, LOCATION, NULL,
        !           959:                        "unable to alloc ldap search filter buffer\n");
        !           960:                goto ldap_end;
        !           961:        }
        !           962:        sprintf(filter, "%s=%s",
        !           963:                xauth_ldap_config.attr_user->v, usr);
        !           964: 
        !           965:        /* build our return attribute list */
        !           966:        tmplen = strlen(xauth_ldap_config.attr_addr->v) + 1;
        !           967:        atlist[0] = racoon_malloc(tmplen);
        !           968:        tmplen = strlen(xauth_ldap_config.attr_mask->v) + 1;
        !           969:        atlist[1] = racoon_malloc(tmplen);
        !           970:        if ((atlist[0] == NULL)||(atlist[1] == NULL)) {
        !           971:                plog(LLV_ERROR, LOCATION, NULL,
        !           972:                        "unable to alloc ldap attrib list buffer\n");
        !           973:                goto ldap_end;
        !           974:        }
        !           975:        strcpy(atlist[0],xauth_ldap_config.attr_addr->v);
        !           976:        strcpy(atlist[1],xauth_ldap_config.attr_mask->v);
        !           977: 
        !           978:        /* attempt to locate the user dn */
        !           979:        if (xauth_ldap_config.base != NULL)
        !           980:                basedn = xauth_ldap_config.base->v;
        !           981:        if (xauth_ldap_config.subtree)
        !           982:                scope = LDAP_SCOPE_SUBTREE;
        !           983:        timeout.tv_sec = 15;
        !           984:        timeout.tv_usec = 0;
        !           985:        res = ldap_search_ext_s(ld, basedn, scope,
        !           986:                filter, atlist, 0, NULL, NULL,
        !           987:                &timeout, 2, &lr);
        !           988:        if (res != LDAP_SUCCESS) {
        !           989:                plog(LLV_ERROR, LOCATION, NULL,
        !           990:                        "ldap_search_ext_s failed: %s\n",
        !           991:                        ldap_err2string(res));
        !           992:                goto ldap_end;
        !           993:        }
        !           994: 
        !           995:        /* check the number of ldap entries returned */
        !           996:        ecount = ldap_count_entries(ld, lr);
        !           997:        if (ecount < 1) {
        !           998:                plog(LLV_WARNING, LOCATION, NULL, 
        !           999:                        "no ldap results for filter \'%s\'\n", 
        !          1000:                         filter);
        !          1001:                goto ldap_end;
        !          1002:        }
        !          1003:        if (ecount > 1) {
        !          1004:                plog(LLV_WARNING, LOCATION, NULL, 
        !          1005:                        "multiple (%i) ldap results for filter \'%s\'\n", 
        !          1006:                        ecount, filter);
        !          1007:        }
        !          1008: 
        !          1009:        /* obtain the dn from the first result */
        !          1010:        le = ldap_first_entry(ld, lr);
        !          1011:        if (le == NULL) {
        !          1012:                plog(LLV_ERROR, LOCATION, NULL,
        !          1013:                        "ldap_first_entry failed: invalid entry returned\n");
        !          1014:                goto ldap_end;
        !          1015:        }
        !          1016:        userdn = ldap_get_dn(ld, le);
        !          1017:        if (userdn == NULL) {
        !          1018:                plog(LLV_ERROR, LOCATION, NULL,
        !          1019:                        "ldap_get_dn failed: invalid string returned\n");
        !          1020:                goto ldap_end;
        !          1021:        }
        !          1022: 
        !          1023:        /* cache the user dn in the xauth state */
        !          1024:        iph1->mode_cfg->xauth.udn = racoon_malloc(strlen(userdn)+1);
        !          1025:        strcpy(iph1->mode_cfg->xauth.udn,userdn);
        !          1026: 
        !          1027:        /* retrieve modecfg address */
        !          1028:        bv = ldap_get_values_len(ld, le, xauth_ldap_config.attr_addr->v);
        !          1029:        if (bv != NULL) {
        !          1030:                char tmpaddr[16];
        !          1031:                /* sanity check for address value */
        !          1032:                if ((bv[0]->bv_len < 7)||(bv[0]->bv_len > 15)) {
        !          1033:                        plog(LLV_DEBUG, LOCATION, NULL,
        !          1034:                                "ldap returned invalid modecfg address\n");
        !          1035:                        ldap_value_free_len(bv);
        !          1036:                        goto ldap_end;
        !          1037:                }
        !          1038:                memcpy(tmpaddr,bv[0]->bv_val,bv[0]->bv_len);
        !          1039:                tmpaddr[bv[0]->bv_len]=0;
        !          1040:                iph1->mode_cfg->addr4.s_addr = inet_addr(tmpaddr);
        !          1041:                iph1->mode_cfg->flags |= ISAKMP_CFG_ADDR4_EXTERN;
        !          1042:                plog(LLV_INFO, LOCATION, NULL,
        !          1043:                        "ldap returned modecfg address %s\n", tmpaddr);
        !          1044:                ldap_value_free_len(bv);
        !          1045:        }
        !          1046: 
        !          1047:        /* retrieve modecfg netmask */
        !          1048:        bv = ldap_get_values_len(ld, le, xauth_ldap_config.attr_mask->v);
        !          1049:        if (bv != NULL) {
        !          1050:                char tmpmask[16];
        !          1051:                /* sanity check for netmask value */
        !          1052:                if ((bv[0]->bv_len < 7)||(bv[0]->bv_len > 15)) {
        !          1053:                        plog(LLV_DEBUG, LOCATION, NULL,
        !          1054:                                "ldap returned invalid modecfg netmask\n");
        !          1055:                        ldap_value_free_len(bv);
        !          1056:                        goto ldap_end;
        !          1057:                }
        !          1058:                memcpy(tmpmask,bv[0]->bv_val,bv[0]->bv_len);
        !          1059:                tmpmask[bv[0]->bv_len]=0;
        !          1060:                iph1->mode_cfg->mask4.s_addr = inet_addr(tmpmask);
        !          1061:                iph1->mode_cfg->flags |= ISAKMP_CFG_MASK4_EXTERN;
        !          1062:                plog(LLV_INFO, LOCATION, NULL,
        !          1063:                        "ldap returned modecfg netmask %s\n", tmpmask);
        !          1064:                ldap_value_free_len(bv);
        !          1065:        }
        !          1066: 
        !          1067:        /*
        !          1068:         * finally, use the dn and the xauth
        !          1069:         * password to check the users given
        !          1070:         * credentials by attempting to bind
        !          1071:         * to the ldap server
        !          1072:         */
        !          1073:        plog(LLV_INFO, LOCATION, NULL,
        !          1074:                "attempting ldap bind for dn \'%s\'\n", userdn);
        !          1075:        cred.bv_val = pwd;
        !          1076:        cred.bv_len = strlen( cred.bv_val );
        !          1077:        res = ldap_sasl_bind_s(ld,
        !          1078:                userdn, NULL, &cred,
        !          1079:                NULL, NULL, NULL);
        !          1080:         if(res==LDAP_SUCCESS)
        !          1081:                rtn = 0;
        !          1082: 
        !          1083: ldap_end:
        !          1084: 
        !          1085:        /* free ldap resources */
        !          1086:        if (userdn != NULL)
        !          1087:                ldap_memfree(userdn);
        !          1088:        if (atlist[0] != NULL)
        !          1089:                racoon_free(atlist[0]);
        !          1090:        if (atlist[1] != NULL)
        !          1091:                racoon_free(atlist[1]);
        !          1092:        if (filter != NULL)
        !          1093:                racoon_free(filter);
        !          1094:        if (lr != NULL)
        !          1095:                ldap_msgfree(lr);
        !          1096:        if (init != NULL)
        !          1097:                racoon_free(init);
        !          1098: 
        !          1099:        ldap_unbind_ext_s(ld, NULL, NULL);
        !          1100: 
        !          1101:        return rtn;
        !          1102: }
        !          1103: 
        !          1104: int
        !          1105: xauth_group_ldap(udn, grp)
        !          1106:        char * udn;
        !          1107:        char * grp;
        !          1108: {
        !          1109:        int rtn = -1;
        !          1110:        int res = -1;
        !          1111:        LDAP *ld = NULL;
        !          1112:        LDAPMessage *lr = NULL;
        !          1113:        LDAPMessage *le = NULL;
        !          1114:        struct berval cred;
        !          1115:        struct timeval timeout;
        !          1116:        char *init = NULL;
        !          1117:        char *filter = NULL;
        !          1118:        char *basedn = NULL;
        !          1119:        char *groupdn = NULL;
        !          1120:        int tmplen = 0;
        !          1121:        int ecount = 0;
        !          1122:        int scope = LDAP_SCOPE_ONE;
        !          1123: 
        !          1124:        /* build our initialization url */
        !          1125:        tmplen = strlen("ldap://:") + 17;
        !          1126:        tmplen += strlen(xauth_ldap_config.host->v);
        !          1127:        init = racoon_malloc(tmplen);
        !          1128:        if (init == NULL) {
        !          1129:                plog(LLV_ERROR, LOCATION, NULL,
        !          1130:                        "unable to alloc ldap init url\n");
        !          1131:                goto ldap_group_end;
        !          1132:        }
        !          1133:        sprintf(init,"ldap://%s:%d",
        !          1134:                xauth_ldap_config.host->v,
        !          1135:                xauth_ldap_config.port );
        !          1136: 
        !          1137:        /* initialize the ldap handle */
        !          1138:        res = ldap_initialize(&ld, init);
        !          1139:        if (res != LDAP_SUCCESS) {
        !          1140:                plog(LLV_ERROR, LOCATION, NULL,
        !          1141:                        "ldap_initialize failed: %s\n",
        !          1142:                        ldap_err2string(res));
        !          1143:                goto ldap_group_end;
        !          1144:        }
        !          1145: 
        !          1146:        /* initialize the protocol version */
        !          1147:        ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION,
        !          1148:                &xauth_ldap_config.pver);
        !          1149: 
        !          1150:        /*
        !          1151:         * attempt to bind to the ldap server.
        !          1152:          * default to anonymous bind unless a
        !          1153:         * user dn and password has been
        !          1154:         * specified in our configuration
        !          1155:          */
        !          1156:        if ((xauth_ldap_config.bind_dn != NULL)&&
        !          1157:            (xauth_ldap_config.bind_pw != NULL))
        !          1158:        {
        !          1159:                cred.bv_val = xauth_ldap_config.bind_pw->v;
        !          1160:                cred.bv_len = strlen( cred.bv_val );
        !          1161:                res = ldap_sasl_bind_s(ld,
        !          1162:                        xauth_ldap_config.bind_dn->v, NULL, &cred,
        !          1163:                        NULL, NULL, NULL);
        !          1164:        }
        !          1165:        else
        !          1166:        {
        !          1167:                res = ldap_sasl_bind_s(ld,
        !          1168:                        NULL, NULL, NULL,
        !          1169:                        NULL, NULL, NULL);
        !          1170:        }
        !          1171: 
        !          1172:        if (res!=LDAP_SUCCESS) {
        !          1173:                plog(LLV_ERROR, LOCATION, NULL,
        !          1174:                        "ldap_sasl_bind_s (search) failed: %s\n",
        !          1175:                        ldap_err2string(res));
        !          1176:                goto ldap_group_end;
        !          1177:        }
        !          1178: 
        !          1179:        /* build an ldap group search filter */
        !          1180:        tmplen = strlen("(&(=)(=))") + 1;
        !          1181:        tmplen += strlen(xauth_ldap_config.attr_group->v);
        !          1182:        tmplen += strlen(grp);
        !          1183:        tmplen += strlen(xauth_ldap_config.attr_member->v);
        !          1184:        tmplen += strlen(udn);
        !          1185:        filter = racoon_malloc(tmplen);
        !          1186:        if (filter == NULL) {
        !          1187:                plog(LLV_ERROR, LOCATION, NULL,
        !          1188:                        "unable to alloc ldap search filter buffer\n");
        !          1189:                goto ldap_group_end;
        !          1190:        }
        !          1191:        sprintf(filter, "(&(%s=%s)(%s=%s))",
        !          1192:                xauth_ldap_config.attr_group->v, grp,
        !          1193:                xauth_ldap_config.attr_member->v, udn);
        !          1194: 
        !          1195:        /* attempt to locate the group dn */
        !          1196:        if (xauth_ldap_config.base != NULL)
        !          1197:                basedn = xauth_ldap_config.base->v;
        !          1198:        if (xauth_ldap_config.subtree)
        !          1199:                scope = LDAP_SCOPE_SUBTREE;
        !          1200:        timeout.tv_sec = 15;
        !          1201:        timeout.tv_usec = 0;
        !          1202:        res = ldap_search_ext_s(ld, basedn, scope,
        !          1203:                filter, NULL, 0, NULL, NULL,
        !          1204:                &timeout, 2, &lr);
        !          1205:        if (res != LDAP_SUCCESS) {
        !          1206:                plog(LLV_ERROR, LOCATION, NULL,
        !          1207:                        "ldap_search_ext_s failed: %s\n",
        !          1208:                        ldap_err2string(res));
        !          1209:                goto ldap_group_end;
        !          1210:        }
        !          1211: 
        !          1212:        /* check the number of ldap entries returned */
        !          1213:        ecount = ldap_count_entries(ld, lr);
        !          1214:        if (ecount < 1) {
        !          1215:                plog(LLV_WARNING, LOCATION, NULL, 
        !          1216:                        "no ldap results for filter \'%s\'\n", 
        !          1217:                         filter);
        !          1218:                goto ldap_group_end;
        !          1219:        }
        !          1220: 
        !          1221:        /* success */
        !          1222:        rtn = 0;
        !          1223: 
        !          1224:        /* obtain the dn from the first result */
        !          1225:        le = ldap_first_entry(ld, lr);
        !          1226:        if (le == NULL) {
        !          1227:                plog(LLV_ERROR, LOCATION, NULL,
        !          1228:                        "ldap_first_entry failed: invalid entry returned\n");
        !          1229:                goto ldap_group_end;
        !          1230:        }
        !          1231:        groupdn = ldap_get_dn(ld, le);
        !          1232:        if (groupdn == NULL) {
        !          1233:                plog(LLV_ERROR, LOCATION, NULL,
        !          1234:                        "ldap_get_dn failed: invalid string returned\n");
        !          1235:                goto ldap_group_end;
        !          1236:        }
        !          1237: 
        !          1238:        plog(LLV_INFO, LOCATION, NULL,
        !          1239:                "ldap membership group returned \'%s\'\n", groupdn);
        !          1240: ldap_group_end:
        !          1241: 
        !          1242:        /* free ldap resources */
        !          1243:        if (groupdn != NULL)
        !          1244:                ldap_memfree(groupdn);
        !          1245:        if (filter != NULL)
        !          1246:                racoon_free(filter);
        !          1247:        if (lr != NULL)
        !          1248:                ldap_msgfree(lr);
        !          1249:        if (init != NULL)
        !          1250:                racoon_free(init);
        !          1251: 
        !          1252:        ldap_unbind_ext_s(ld, NULL, NULL);
        !          1253: 
        !          1254:        return rtn;
        !          1255: }
        !          1256: 
        !          1257: #endif
        !          1258: 
        !          1259: int
        !          1260: xauth_login_system(usr, pwd)
        !          1261:        char *usr;
        !          1262:        char *pwd;
        !          1263: {
        !          1264:        struct passwd *pw;
        !          1265:        char *cryptpwd;
        !          1266:        char *syscryptpwd;
        !          1267: #ifdef HAVE_SHADOW_H
        !          1268:        struct spwd *spw;
        !          1269: 
        !          1270:        if ((spw = getspnam(usr)) == NULL)
        !          1271:                return -1;
        !          1272: 
        !          1273:        syscryptpwd = spw->sp_pwdp;
        !          1274: #endif
        !          1275: 
        !          1276:        if ((pw = getpwnam(usr)) == NULL)
        !          1277:                return -1;
        !          1278: 
        !          1279: #ifndef HAVE_SHADOW_H
        !          1280:        syscryptpwd = pw->pw_passwd;
        !          1281: #endif
        !          1282: 
        !          1283:        /* No root login. Ever. */
        !          1284:        if (pw->pw_uid == 0)
        !          1285:                return -1;
        !          1286: 
        !          1287:        if ((cryptpwd = crypt(pwd, syscryptpwd)) == NULL)
        !          1288:                return -1;
        !          1289: 
        !          1290:        if (strcmp(cryptpwd, syscryptpwd) == 0)
        !          1291:                return 0;
        !          1292: 
        !          1293:        return -1;
        !          1294: }
        !          1295: 
        !          1296: int
        !          1297: xauth_group_system(usr, grp)
        !          1298:        char * usr;
        !          1299:        char * grp;
        !          1300: {
        !          1301:        struct group * gr;
        !          1302:        char * member;
        !          1303:        int index = 0;
        !          1304: 
        !          1305:        gr = getgrnam(grp);
        !          1306:        if (gr == NULL) {
        !          1307:                plog(LLV_ERROR, LOCATION, NULL,
        !          1308:                        "the system group name \'%s\' is unknown\n",
        !          1309:                        grp);
        !          1310:                return -1;
        !          1311:        }
        !          1312: 
        !          1313:        while ((member = gr->gr_mem[index++])!=NULL) {
        !          1314:                if (!strcmp(member,usr)) {
        !          1315:                        plog(LLV_INFO, LOCATION, NULL,
        !          1316:                                "membership validated\n");
        !          1317:                        return 0;
        !          1318:                }
        !          1319:        }
        !          1320: 
        !          1321:        return -1;
        !          1322: }
        !          1323: 
        !          1324: int 
        !          1325: xauth_check(iph1)
        !          1326:        struct ph1handle *iph1;
        !          1327: {
        !          1328:        struct xauth_state *xst = &iph1->mode_cfg->xauth;
        !          1329: 
        !          1330:        /* 
        !          1331:         * Only the server side (edge device) really check for Xauth 
        !          1332:         * status. It does it if the chose authmethod is using Xauth.
        !          1333:         * On the client side (roadwarrior), we don't check anything.
        !          1334:         */
        !          1335:        switch (iph1->approval->authmethod) {
        !          1336:        case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R:
        !          1337:        case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R:
        !          1338:        case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R:
        !          1339:        /* The following are not yet implemented */
        !          1340:        case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R:
        !          1341:        case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R:
        !          1342:        case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R:
        !          1343:        case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R:
        !          1344:                if ((iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) == 0) {
        !          1345:                        plog(LLV_ERROR, LOCATION, NULL,
        !          1346:                            "Hybrid auth negotiated but peer did not "
        !          1347:                            "announced as Xauth capable\n");
        !          1348:                        return -1;
        !          1349:                }
        !          1350: 
        !          1351:                if (xst->status != XAUTHST_OK) {
        !          1352:                        plog(LLV_ERROR, LOCATION, NULL,
        !          1353:                            "Hybrid auth negotiated but peer did not "
        !          1354:                            "succeed Xauth exchange\n");
        !          1355:                        return -1;
        !          1356:                }
        !          1357: 
        !          1358:                return 0;
        !          1359:                break;
        !          1360:        default:
        !          1361:                return 0;
        !          1362:                break;
        !          1363:        }
        !          1364: 
        !          1365:        return 0;
        !          1366: }
        !          1367: 
        !          1368: int
        !          1369: group_check(iph1, grp_list, grp_count)
        !          1370:        struct ph1handle *iph1;
        !          1371:        char **grp_list;
        !          1372:        int grp_count;
        !          1373: {
        !          1374:        int res = -1;
        !          1375:        int grp_index = 0;
        !          1376:        char * usr = NULL;
        !          1377: 
        !          1378:        /* check for presence of modecfg data */
        !          1379: 
        !          1380:        if(iph1->mode_cfg == NULL) {
        !          1381:                plog(LLV_ERROR, LOCATION, NULL,
        !          1382:                        "xauth group specified but modecfg not found\n");
        !          1383:                return res;
        !          1384:        }
        !          1385: 
        !          1386:        /* loop through our group list */
        !          1387: 
        !          1388:        for(; grp_index < grp_count; grp_index++) {
        !          1389: 
        !          1390:                /* check for presence of xauth data */
        !          1391: 
        !          1392:                usr = iph1->mode_cfg->xauth.authdata.generic.usr;
        !          1393: 
        !          1394:                if(usr == NULL) {
        !          1395:                        plog(LLV_ERROR, LOCATION, NULL,
        !          1396:                                "xauth group specified but xauth not found\n");
        !          1397:                        return res;
        !          1398:                }
        !          1399: 
        !          1400:                /* call appropriate group validation funtion */
        !          1401: 
        !          1402:                switch (isakmp_cfg_config.groupsource) {
        !          1403: 
        !          1404:                        case ISAKMP_CFG_GROUP_SYSTEM:
        !          1405:                                res = xauth_group_system(
        !          1406:                                        usr,
        !          1407:                                        grp_list[grp_index]);
        !          1408:                                break;
        !          1409: 
        !          1410: #ifdef HAVE_LIBLDAP
        !          1411:                        case ISAKMP_CFG_GROUP_LDAP:
        !          1412:                                res = xauth_group_ldap(
        !          1413:                                        iph1->mode_cfg->xauth.udn,
        !          1414:                                        grp_list[grp_index]);
        !          1415:                                break;
        !          1416: #endif
        !          1417: 
        !          1418:                        default:
        !          1419:                                /* we should never get here */
        !          1420:                                plog(LLV_ERROR, LOCATION, NULL,
        !          1421:                                    "Unknown group auth source\n");
        !          1422:                                break;
        !          1423:                }
        !          1424: 
        !          1425:                if( !res ) {
        !          1426:                        plog(LLV_INFO, LOCATION, NULL,
        !          1427:                                "user \"%s\" is a member of group \"%s\"\n",
        !          1428:                                usr,
        !          1429:                                grp_list[grp_index]);
        !          1430:                        break;
        !          1431:                } else {
        !          1432:                        plog(LLV_INFO, LOCATION, NULL,
        !          1433:                                "user \"%s\" is not a member of group \"%s\"\n",
        !          1434:                                usr,
        !          1435:                                grp_list[grp_index]);
        !          1436:                }
        !          1437:        }
        !          1438: 
        !          1439:        return res;
        !          1440: }
        !          1441: 
        !          1442: vchar_t *
        !          1443: isakmp_xauth_req(iph1, attr)
        !          1444:        struct ph1handle *iph1;
        !          1445:        struct isakmp_data *attr;
        !          1446: {
        !          1447:        int type;
        !          1448:        size_t dlen = 0;
        !          1449:        int ashort = 0;
        !          1450:        int value = 0;
        !          1451:        vchar_t *buffer = NULL;
        !          1452:        char *mraw = NULL, *mdata;
        !          1453:        char *data;
        !          1454:        vchar_t *usr = NULL;
        !          1455:        vchar_t *pwd = NULL;
        !          1456:        size_t skip = 0;
        !          1457:        int freepwd = 0;
        !          1458: 
        !          1459:        if ((iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) == 0) {
        !          1460:                plog(LLV_ERROR, LOCATION, NULL, 
        !          1461:                    "Xauth mode config request but peer "
        !          1462:                    "did not declare itself as Xauth capable\n");
        !          1463:                return NULL;
        !          1464:        }
        !          1465: 
        !          1466:        type = ntohs(attr->type) & ~ISAKMP_GEN_MASK;
        !          1467: 
        !          1468:        /* Sanity checks */
        !          1469:        switch(type) {
        !          1470:        case XAUTH_TYPE:
        !          1471:                if ((ntohs(attr->type) & ISAKMP_GEN_TV) == 0) {
        !          1472:                        plog(LLV_ERROR, LOCATION, NULL, 
        !          1473:                            "Unexpected long XAUTH_TYPE attribute\n");
        !          1474:                        return NULL;
        !          1475:                }
        !          1476:                if (ntohs(attr->lorv) != XAUTH_TYPE_GENERIC) {
        !          1477:                        plog(LLV_ERROR, LOCATION, NULL, 
        !          1478:                            "Unsupported Xauth authentication %d\n", 
        !          1479:                            ntohs(attr->lorv));
        !          1480:                        return NULL;
        !          1481:                }
        !          1482:                ashort = 1;
        !          1483:                dlen = 0;
        !          1484:                value = XAUTH_TYPE_GENERIC;
        !          1485:                break;
        !          1486: 
        !          1487:        case XAUTH_USER_NAME:
        !          1488:                if (!iph1->rmconf->xauth || !iph1->rmconf->xauth->login) {
        !          1489:                        plog(LLV_ERROR, LOCATION, NULL, "Xauth performed "
        !          1490:                            "with no login supplied\n");
        !          1491:                        return NULL;
        !          1492:                }
        !          1493: 
        !          1494:                dlen = iph1->rmconf->xauth->login->l - 1;
        !          1495:                iph1->rmconf->xauth->state |= XAUTH_SENT_USERNAME;
        !          1496:                break;
        !          1497: 
        !          1498:        case XAUTH_USER_PASSWORD:
        !          1499:                if (!iph1->rmconf->xauth || !iph1->rmconf->xauth->login)
        !          1500:                        return NULL;
        !          1501: 
        !          1502:                skip = sizeof(struct ipsecdoi_id_b);
        !          1503:                usr = vmalloc(iph1->rmconf->xauth->login->l - 1 + skip);
        !          1504:                if (usr == NULL) {
        !          1505:                        plog(LLV_ERROR, LOCATION, NULL, 
        !          1506:                            "Cannot allocate memory\n");
        !          1507:                        return NULL;
        !          1508:                }
        !          1509:                memset(usr->v, 0, skip);
        !          1510:                memcpy(usr->v + skip, 
        !          1511:                    iph1->rmconf->xauth->login->v, 
        !          1512:                    iph1->rmconf->xauth->login->l - 1);
        !          1513: 
        !          1514:                if (iph1->rmconf->xauth->pass) {
        !          1515:                        /* A key given through racoonctl */
        !          1516:                        pwd = iph1->rmconf->xauth->pass;
        !          1517:                } else {
        !          1518:                        if ((pwd = getpskbyname(usr)) == NULL) {
        !          1519:                                plog(LLV_ERROR, LOCATION, NULL, 
        !          1520:                                    "No password was found for login %s\n", 
        !          1521:                                    iph1->rmconf->xauth->login->v);
        !          1522:                                vfree(usr);
        !          1523:                                return NULL;
        !          1524:                        }
        !          1525:                        /* We have to free it before returning */
        !          1526:                        freepwd = 1;
        !          1527:                }
        !          1528:                vfree(usr);
        !          1529: 
        !          1530:                iph1->rmconf->xauth->state |= XAUTH_SENT_PASSWORD;
        !          1531:                dlen = pwd->l;
        !          1532: 
        !          1533:                break;
        !          1534:        case XAUTH_MESSAGE:
        !          1535:                if ((ntohs(attr->type) & ISAKMP_GEN_TV) == 0) {
        !          1536:                        dlen = ntohs(attr->lorv);
        !          1537:                        if (dlen > 0) {
        !          1538:                                mraw = (char*)(attr + 1);
        !          1539:                                mdata = binsanitize(mraw, dlen);
        !          1540:                                if (mdata == NULL) {
        !          1541:                                        plog(LLV_ERROR, LOCATION, iph1->remote,
        !          1542:                                            "Cannot allocate memory\n");
        !          1543:                                        return NULL;
        !          1544:                                }
        !          1545:                                plog(LLV_NOTIFY,LOCATION, iph1->remote,
        !          1546:                                        "XAUTH Message: '%s'.\n",
        !          1547:                                        mdata);
        !          1548:                                racoon_free(mdata);
        !          1549:                        }
        !          1550:                }
        !          1551:                return NULL;
        !          1552:        default:
        !          1553:                plog(LLV_WARNING, LOCATION, NULL,
        !          1554:                    "Ignored attribute %s\n", s_isakmp_cfg_type(type));
        !          1555:                return NULL;
        !          1556:                break;
        !          1557:        }
        !          1558: 
        !          1559:        if ((buffer = vmalloc(sizeof(*attr) + dlen)) == NULL) {
        !          1560:                plog(LLV_ERROR, LOCATION, NULL,
        !          1561:                    "Cannot allocate memory\n");
        !          1562:                goto out;
        !          1563:        }
        !          1564: 
        !          1565:        attr = (struct isakmp_data *)buffer->v;
        !          1566:        if (ashort) {
        !          1567:                attr->type = htons(type | ISAKMP_GEN_TV);
        !          1568:                attr->lorv = htons(value);
        !          1569:                goto out;
        !          1570:        }
        !          1571: 
        !          1572:        attr->type = htons(type | ISAKMP_GEN_TLV);
        !          1573:        attr->lorv = htons(dlen);
        !          1574:        data = (char *)(attr + 1);
        !          1575: 
        !          1576:        switch(type) {
        !          1577:        case XAUTH_USER_NAME:
        !          1578:                /* 
        !          1579:                 * iph1->rmconf->xauth->login->v is valid, 
        !          1580:                 * we just checked it in the previous switch case 
        !          1581:                 */
        !          1582:                memcpy(data, iph1->rmconf->xauth->login->v, dlen);
        !          1583:                break;
        !          1584:        case XAUTH_USER_PASSWORD:
        !          1585:                memcpy(data, pwd->v, dlen);
        !          1586:                break;
        !          1587:        default:
        !          1588:                break;
        !          1589:        }
        !          1590: 
        !          1591: out:
        !          1592:        if (freepwd)
        !          1593:                vfree(pwd);
        !          1594: 
        !          1595:        return buffer;
        !          1596: }
        !          1597: 
        !          1598: vchar_t *
        !          1599: isakmp_xauth_set(iph1, attr)
        !          1600:        struct ph1handle *iph1;
        !          1601:        struct isakmp_data *attr;
        !          1602: {
        !          1603:        int type;
        !          1604:        vchar_t *buffer = NULL;
        !          1605:        char *data;
        !          1606:        struct xauth_state *xst;
        !          1607:        size_t dlen = 0;
        !          1608:        char* mraw = NULL, *mdata;
        !          1609: 
        !          1610:        if ((iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) == 0) {
        !          1611:                plog(LLV_ERROR, LOCATION, NULL, 
        !          1612:                    "Xauth mode config set but peer "
        !          1613:                    "did not declare itself as Xauth capable\n");
        !          1614:                return NULL;
        !          1615:        }
        !          1616: 
        !          1617:        type = ntohs(attr->type) & ~ISAKMP_GEN_MASK;
        !          1618: 
        !          1619:        switch(type) {
        !          1620:        case XAUTH_STATUS:
        !          1621:                /* 
        !          1622:                 * We should only receive ISAKMP mode_cfg SET XAUTH_STATUS
        !          1623:                 * when running as a client (initiator).
        !          1624:                 */
        !          1625:                xst = &iph1->mode_cfg->xauth;
        !          1626:                switch (iph1->approval->authmethod) {
        !          1627:                case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
        !          1628:                case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I:
        !          1629:                case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I:
        !          1630:                /* Not implemented ... */
        !          1631:                case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I:
        !          1632:                case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I:
        !          1633:                case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I:
        !          1634:                case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I:
        !          1635:                        break;
        !          1636:                default:
        !          1637:                        plog(LLV_ERROR, LOCATION, NULL, 
        !          1638:                            "Unexpected XAUTH_STATUS_OK\n");
        !          1639:                        return NULL;
        !          1640:                        break;
        !          1641:                }
        !          1642: 
        !          1643:                /* If we got a failure, delete iph1 */
        !          1644:                if (ntohs(attr->lorv) != XAUTH_STATUS_OK) {
        !          1645:                        plog(LLV_ERROR, LOCATION, NULL, 
        !          1646:                            "Xauth authentication failed\n");
        !          1647: 
        !          1648:                        evt_phase1(iph1, EVT_PHASE1_XAUTH_FAILED, NULL);
        !          1649: 
        !          1650:                        iph1->mode_cfg->flags |= ISAKMP_CFG_DELETE_PH1;
        !          1651:                } else {
        !          1652:                        evt_phase1(iph1, EVT_PHASE1_XAUTH_SUCCESS, NULL);
        !          1653:                }
        !          1654: 
        !          1655: 
        !          1656:                /* We acknowledge it */
        !          1657:                break;
        !          1658:        case XAUTH_MESSAGE:
        !          1659:                if ((ntohs(attr->type) & ISAKMP_GEN_TV) == 0) {
        !          1660:                        dlen = ntohs(attr->lorv);
        !          1661:                        if (dlen > 0) {
        !          1662:                                mraw = (char*)(attr + 1);
        !          1663:                                mdata = binsanitize(mraw, dlen);
        !          1664:                                if (mdata == NULL) {
        !          1665:                                        plog(LLV_ERROR, LOCATION, iph1->remote,
        !          1666:                                            "Cannot allocate memory\n");
        !          1667:                                        return NULL;
        !          1668:                                }
        !          1669:                                plog(LLV_NOTIFY,LOCATION, iph1->remote,
        !          1670:                                        "XAUTH Message: '%s'.\n",
        !          1671:                                        mdata);
        !          1672:                                racoon_free(mdata);
        !          1673:                        }
        !          1674:                }
        !          1675: 
        !          1676:        default:
        !          1677:                plog(LLV_WARNING, LOCATION, NULL,
        !          1678:                    "Ignored attribute %s\n", s_isakmp_cfg_type(type));
        !          1679:                return NULL;
        !          1680:                break;
        !          1681:        }
        !          1682: 
        !          1683:        if ((buffer = vmalloc(sizeof(*attr))) == NULL) {
        !          1684:                plog(LLV_ERROR, LOCATION, NULL,
        !          1685:                    "Cannot allocate memory\n");
        !          1686:                return NULL;
        !          1687:        }
        !          1688: 
        !          1689:        attr = (struct isakmp_data *)buffer->v;
        !          1690:        attr->type = htons(type | ISAKMP_GEN_TV);
        !          1691:        attr->lorv = htons(0);
        !          1692: 
        !          1693:        return buffer;
        !          1694: }
        !          1695: 
        !          1696: 
        !          1697: void 
        !          1698: xauth_rmstate(xst)
        !          1699:        struct xauth_state *xst;
        !          1700: {
        !          1701:        switch (xst->authtype) {
        !          1702:        case XAUTH_TYPE_GENERIC:
        !          1703:                if (xst->authdata.generic.usr)
        !          1704:                        racoon_free(xst->authdata.generic.usr);
        !          1705: 
        !          1706:                if (xst->authdata.generic.pwd)
        !          1707:                        racoon_free(xst->authdata.generic.pwd);
        !          1708: 
        !          1709:                break;
        !          1710: 
        !          1711:        case XAUTH_TYPE_CHAP:
        !          1712:        case XAUTH_TYPE_OTP:
        !          1713:        case XAUTH_TYPE_SKEY:
        !          1714:                plog(LLV_WARNING, LOCATION, NULL, 
        !          1715:                    "Unsupported authtype %d\n", xst->authtype);
        !          1716:                break;
        !          1717: 
        !          1718:        default:
        !          1719:                plog(LLV_WARNING, LOCATION, NULL, 
        !          1720:                    "Unexpected authtype %d\n", xst->authtype);
        !          1721:                break;
        !          1722:        }
        !          1723: 
        !          1724: #ifdef HAVE_LIBLDAP
        !          1725:        if (xst->udn != NULL)
        !          1726:                racoon_free(xst->udn);
        !          1727: #endif
        !          1728:        return;
        !          1729: }
        !          1730: 
        !          1731: int
        !          1732: xauth_rmconf_used(xauth_rmconf)
        !          1733:        struct xauth_rmconf **xauth_rmconf;
        !          1734: {
        !          1735:        if (*xauth_rmconf == NULL) {
        !          1736:                *xauth_rmconf = racoon_malloc(sizeof(**xauth_rmconf));
        !          1737:                if (*xauth_rmconf == NULL) {
        !          1738:                        plog(LLV_ERROR, LOCATION, NULL, 
        !          1739:                            "xauth_rmconf_used: malloc failed\n");
        !          1740:                        return -1;
        !          1741:                }
        !          1742: 
        !          1743:                (*xauth_rmconf)->login = NULL;
        !          1744:                (*xauth_rmconf)->pass = NULL;
        !          1745:                (*xauth_rmconf)->state = 0;
        !          1746:        }
        !          1747: 
        !          1748:        return 0;
        !          1749: }
        !          1750: 
        !          1751: void 
        !          1752: xauth_rmconf_delete(xauth_rmconf)
        !          1753:        struct xauth_rmconf **xauth_rmconf;
        !          1754: {
        !          1755:        if (*xauth_rmconf != NULL) { 
        !          1756:                if ((*xauth_rmconf)->login != NULL)
        !          1757:                        vfree((*xauth_rmconf)->login);
        !          1758:                if ((*xauth_rmconf)->pass != NULL)
        !          1759:                        vfree((*xauth_rmconf)->pass);
        !          1760: 
        !          1761:                racoon_free(*xauth_rmconf);
        !          1762:                *xauth_rmconf = NULL;
        !          1763:        }
        !          1764: 
        !          1765:        return;
        !          1766: }
        !          1767: 
        !          1768: struct xauth_rmconf *
        !          1769: xauth_rmconf_dup(xauth_rmconf)
        !          1770:        struct xauth_rmconf *xauth_rmconf;
        !          1771: {
        !          1772:        struct xauth_rmconf *new;
        !          1773: 
        !          1774:        if (xauth_rmconf != NULL) {
        !          1775:                new = racoon_malloc(sizeof(*new));
        !          1776:                if (new == NULL) {
        !          1777:                        plog(LLV_ERROR, LOCATION, NULL, 
        !          1778:                            "xauth_rmconf_dup: malloc failed\n");
        !          1779:                        return NULL;
        !          1780:                }
        !          1781: 
        !          1782:                memcpy(new, xauth_rmconf, sizeof(*new));
        !          1783: 
        !          1784:                if (xauth_rmconf->login != NULL) {
        !          1785:                        new->login = vdup(xauth_rmconf->login);
        !          1786:                        if (new->login == NULL) {
        !          1787:                                plog(LLV_ERROR, LOCATION, NULL, 
        !          1788:                                    "xauth_rmconf_dup: malloc failed (login)\n");
        !          1789:                                return NULL;
        !          1790:                        }
        !          1791:                }
        !          1792:                if (xauth_rmconf->pass != NULL) {
        !          1793:                        new->pass = vdup(xauth_rmconf->pass);
        !          1794:                        if (new->pass == NULL) {
        !          1795:                                plog(LLV_ERROR, LOCATION, NULL, 
        !          1796:                                    "xauth_rmconf_dup: malloc failed (password)\n");
        !          1797:                                return NULL;
        !          1798:                        }
        !          1799:                }
        !          1800: 
        !          1801:                return new;
        !          1802:        }
        !          1803: 
        !          1804:        return NULL;
        !          1805: }

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