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

1.1       misho       1: /*     $NetBSD: gssapi.c,v 1.4 2006/09/09 16:22:09 manu Exp $  */
                      2: 
                      3: /*     $KAME: gssapi.c,v 1.19 2001/04/03 15:51:55 thorpej Exp $        */
                      4: 
                      5: /*
                      6:  * Copyright 2000 Wasabi Systems, Inc.
                      7:  * All rights reserved.
                      8:  *
                      9:  * This software was written by Frank van der Linden of Wasabi Systems
                     10:  * for Zembu Labs, Inc. http://www.zembu.com/
                     11:  *
                     12:  * Redistribution and use in source and binary forms, with or without
                     13:  * modification, are permitted provided that the following conditions
                     14:  * are met:
                     15:  * 1. Redistributions of source code must retain the above copyright
                     16:  *    notice, this list of conditions and the following disclaimer.
                     17:  * 2. Redistributions in binary form must reproduce the above copyright
                     18:  *    notice, this list of conditions and the following disclaimer in the
                     19:  *    documentation and/or other materials provided with the distribution.
                     20:  * 3. The name of Wasabi Systems, Inc. may not be used to endorse
                     21:  *    or promote products derived from this software without specific prior
                     22:  *    written permission.
                     23:  *
                     24:  * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
                     25:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     26:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     27:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASABI SYSTEMS, INC
                     28:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     29:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     30:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     31:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     32:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     33:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     34:  * POSSIBILITY OF SUCH DAMAGE.
                     35:  */
                     36: 
                     37: #include "config.h"
                     38: 
                     39: #ifdef HAVE_GSSAPI
                     40: 
                     41: #include <sys/types.h>
                     42: #include <sys/queue.h>
                     43: #include <sys/socket.h>
                     44: #include <netdb.h>
                     45: #include <unistd.h>
                     46: 
                     47: #include <stdlib.h>
                     48: #include <string.h>
                     49: #include <errno.h>
                     50: 
                     51: #include "var.h"
                     52: #include "misc.h"
                     53: #include "vmbuf.h"
                     54: #include "plog.h"
                     55: #include "sockmisc.h"
                     56: #include "schedule.h"
                     57: #include "debug.h"
                     58: 
                     59: #include "localconf.h"
                     60: #include "remoteconf.h"
                     61: #include "isakmp_var.h"
                     62: #include "isakmp.h"
                     63: #include "oakley.h"
                     64: #include "handler.h"
                     65: #include "ipsec_doi.h"
                     66: #include "crypto_openssl.h"
                     67: #include "pfkey.h"
                     68: #include "isakmp_ident.h"
                     69: #include "isakmp_inf.h"
                     70: #include "vendorid.h"
                     71: #include "gcmalloc.h"
                     72: 
                     73: #include "gssapi.h"
                     74: 
                     75: static void
                     76: gssapi_error(OM_uint32 status_code, const char *where,
                     77:             const char *fmt, ...)
                     78: {
                     79:        OM_uint32 message_context, maj_stat, min_stat;
                     80:        gss_buffer_desc status_string;
                     81:        va_list ap;
                     82: 
                     83:        va_start(ap, fmt);
                     84:        plogv(LLV_ERROR, where, NULL, fmt, ap);
                     85:        va_end(ap);
                     86: 
                     87:        message_context = 0;
                     88: 
                     89:        do {
                     90:                maj_stat = gss_display_status(&min_stat, status_code,
                     91:                    GSS_C_MECH_CODE, GSS_C_NO_OID, &message_context,
                     92:                    &status_string);
                     93:                if (GSS_ERROR(maj_stat))
                     94:                        plog(LLV_ERROR, LOCATION, NULL,
                     95:                            "UNABLE TO GET GSSAPI ERROR CODE\n");
                     96:                else {
                     97:                        plog(LLV_ERROR, where, NULL,
                     98:                            "%s\n", (char *)status_string.value);
                     99:                        gss_release_buffer(&min_stat, &status_string);
                    100:                }
                    101:        } while (message_context != 0);
                    102: }
                    103: 
                    104: /*
                    105:  * vmbufs and gss_buffer_descs are really just the same on NetBSD, but
                    106:  * this is to be portable.
                    107:  */
                    108: static int
                    109: gssapi_vm2gssbuf(vchar_t *vmbuf, gss_buffer_t gsstoken)
                    110: {
                    111: 
                    112:        gsstoken->value = racoon_malloc(vmbuf->l);
                    113:        if (gsstoken->value == NULL)
                    114:                return -1;
                    115:        memcpy(gsstoken->value, vmbuf->v, vmbuf->l);
                    116:        gsstoken->length = vmbuf->l;
                    117: 
                    118:        return 0;
                    119: }
                    120: 
                    121: static int
                    122: gssapi_gss2vmbuf(gss_buffer_t gsstoken, vchar_t **vmbuf)
                    123: {
                    124: 
                    125:        *vmbuf = vmalloc(gsstoken->length);
                    126:        if (*vmbuf == NULL)
                    127:                return -1;
                    128:        memcpy((*vmbuf)->v, gsstoken->value, gsstoken->length);
                    129:        (*vmbuf)->l = gsstoken->length;
                    130: 
                    131:        return 0;
                    132: }
                    133: 
                    134: vchar_t *
                    135: gssapi_get_default_gss_id(void)
                    136: {
                    137:        char name[NI_MAXHOST];
                    138:        vchar_t *gssid;
                    139: 
                    140:        if (gethostname(name, sizeof(name)) != 0) {
                    141:                plog(LLV_ERROR, LOCATION, NULL, "gethostname failed: %s\n",
                    142:                    strerror(errno));
                    143:                return (NULL);
                    144:        }
                    145:        name[sizeof(name) - 1] = '\0';
                    146: 
                    147:        gssid = racoon_malloc(sizeof(*gssid));
                    148:        gssid->l = asprintf(&gssid->v, "%s/%s", GSSAPI_DEF_NAME, name);
                    149: 
                    150:        return (gssid);
                    151: }
                    152: 
                    153: static int
                    154: gssapi_get_default_name(struct ph1handle *iph1, int remote, gss_name_t *service)
                    155: {
                    156:        char name[NI_MAXHOST];
                    157:        struct sockaddr *sa;
                    158:        char* buf = NULL;
                    159:        gss_buffer_desc name_token;
                    160:        OM_uint32 min_stat, maj_stat;
                    161: 
                    162:        sa = remote ? iph1->remote : iph1->local;
                    163: 
                    164:        if (getnameinfo(sa, sysdep_sa_len(sa), name, NI_MAXHOST, NULL, 0, 0) != 0)
                    165:                return -1;
                    166: 
                    167:        name_token.length = asprintf(&buf, "%s@%s", GSSAPI_DEF_NAME, name);
                    168:        name_token.value = buf;
                    169: 
                    170:        maj_stat = gss_import_name(&min_stat, &name_token,
                    171:            GSS_C_NT_HOSTBASED_SERVICE, service);
                    172:        if (GSS_ERROR(maj_stat)) {
                    173:                gssapi_error(min_stat, LOCATION, "import name\n");
                    174:                maj_stat = gss_release_buffer(&min_stat, &name_token);
                    175:                if (GSS_ERROR(maj_stat))
                    176:                        gssapi_error(min_stat, LOCATION, "release name_token");
                    177:                return -1;
                    178:        }
                    179:        maj_stat = gss_release_buffer(&min_stat, &name_token);
                    180:        if (GSS_ERROR(maj_stat))
                    181:                gssapi_error(min_stat, LOCATION, "release name_token");
                    182: 
                    183:        return 0;
                    184: }
                    185: 
                    186: static int
                    187: gssapi_init(struct ph1handle *iph1)
                    188: {
                    189:        struct gssapi_ph1_state *gps;
                    190:        gss_buffer_desc id_token, cred_token;
                    191:        gss_buffer_t cred = &cred_token;
                    192:        gss_name_t princ, canon_princ;
                    193:        OM_uint32 maj_stat, min_stat;
                    194: 
1.1.1.2 ! misho     195:        if (iph1->rmconf == NULL) {
        !           196:                plog(LLV_ERROR, LOCATION, NULL, "no remote config\n");
        !           197:                return -1;
        !           198:        }
        !           199: 
1.1       misho     200:        gps = racoon_calloc(1, sizeof (struct gssapi_ph1_state));
                    201:        if (gps == NULL) {
                    202:                plog(LLV_ERROR, LOCATION, NULL, "racoon_calloc failed\n");
                    203:                return -1;
                    204:        }
                    205:        gps->gss_context = GSS_C_NO_CONTEXT;
                    206:        gps->gss_cred = GSS_C_NO_CREDENTIAL;
                    207: 
                    208:        gssapi_set_state(iph1, gps);
                    209: 
                    210:        if (iph1->rmconf->proposal->gssid != NULL) {
                    211:                id_token.length = iph1->rmconf->proposal->gssid->l;
                    212:                id_token.value = iph1->rmconf->proposal->gssid->v;
                    213:                maj_stat = gss_import_name(&min_stat, &id_token, GSS_C_NO_OID,
                    214:                    &princ);
                    215:                if (GSS_ERROR(maj_stat)) {
                    216:                        gssapi_error(min_stat, LOCATION, "import name\n");
                    217:                        gssapi_free_state(iph1);
                    218:                        return -1;
                    219:                }
                    220:        } else
                    221:                gssapi_get_default_name(iph1, 0, &princ);
                    222: 
                    223:        maj_stat = gss_canonicalize_name(&min_stat, princ, GSS_C_NO_OID,
                    224:            &canon_princ);
                    225:        if (GSS_ERROR(maj_stat)) {
                    226:                gssapi_error(min_stat, LOCATION, "canonicalize name\n");
                    227:                maj_stat = gss_release_name(&min_stat, &princ);
                    228:                if (GSS_ERROR(maj_stat))
                    229:                        gssapi_error(min_stat, LOCATION, "release princ\n");
                    230:                gssapi_free_state(iph1);
                    231:                return -1;
                    232:        }
                    233:        maj_stat = gss_release_name(&min_stat, &princ);
                    234:        if (GSS_ERROR(maj_stat))
                    235:                gssapi_error(min_stat, LOCATION, "release princ\n");
                    236: 
                    237:        maj_stat = gss_export_name(&min_stat, canon_princ, cred);
                    238:        if (GSS_ERROR(maj_stat)) {
                    239:                gssapi_error(min_stat, LOCATION, "export name\n");
                    240:                maj_stat = gss_release_name(&min_stat, &canon_princ);
                    241:                if (GSS_ERROR(maj_stat))
                    242:                        gssapi_error(min_stat, LOCATION,
                    243:                            "release canon_princ\n");
                    244:                gssapi_free_state(iph1);
                    245:                return -1;
                    246:        }
                    247: 
                    248: #if 0
                    249:        /*
                    250:         * XXXJRT Did this debug message ever work?  This is a GSS name
                    251:         * blob at this point.
                    252:         */
                    253:        plog(LLV_DEBUG, LOCATION, NULL, "will try to acquire '%.*s' creds\n",
                    254:            cred->length, cred->value);
                    255: #endif
                    256: 
                    257:        maj_stat = gss_release_buffer(&min_stat, cred);
                    258:        if (GSS_ERROR(maj_stat))
                    259:                gssapi_error(min_stat, LOCATION, "release cred buffer\n");
                    260: 
                    261:        maj_stat = gss_acquire_cred(&min_stat, canon_princ, GSS_C_INDEFINITE,
                    262:            GSS_C_NO_OID_SET, GSS_C_BOTH, &gps->gss_cred, NULL, NULL);
                    263:        if (GSS_ERROR(maj_stat)) {
                    264:                gssapi_error(min_stat, LOCATION, "acquire cred\n");
                    265:                maj_stat = gss_release_name(&min_stat, &canon_princ);
                    266:                if (GSS_ERROR(maj_stat))
                    267:                        gssapi_error(min_stat, LOCATION,
                    268:                            "release canon_princ\n");
                    269:                gssapi_free_state(iph1);
                    270:                return -1;
                    271:        }
                    272:        maj_stat = gss_release_name(&min_stat, &canon_princ);
                    273:        if (GSS_ERROR(maj_stat))
                    274:                gssapi_error(min_stat, LOCATION, "release canon_princ\n");
                    275: 
                    276:        return 0;
                    277: }
                    278: 
                    279: int
                    280: gssapi_get_itoken(struct ph1handle *iph1, int *lenp)
                    281: {
                    282:        struct gssapi_ph1_state *gps;
                    283:        gss_buffer_desc empty, name_token;
                    284:        gss_buffer_t itoken, rtoken, dummy;
                    285:        OM_uint32 maj_stat, min_stat;
                    286:        gss_name_t partner;
                    287: 
                    288:        if (gssapi_get_state(iph1) == NULL && gssapi_init(iph1) < 0)
                    289:                return -1;
                    290: 
                    291:        gps = gssapi_get_state(iph1);
                    292: 
                    293:        empty.length = 0;
                    294:        empty.value = NULL;
                    295:        dummy = &empty;
                    296: 
                    297:        if (iph1->approval != NULL && iph1->approval->gssid != NULL) {
                    298:                plog(LLV_DEBUG, LOCATION, NULL,
                    299:                    "using provided service '%.*s'\n",
                    300:                    (int)iph1->approval->gssid->l, iph1->approval->gssid->v);
                    301:                name_token.length = iph1->approval->gssid->l;
                    302:                name_token.value = iph1->approval->gssid->v;
                    303:                maj_stat = gss_import_name(&min_stat, &name_token,
                    304:                    GSS_C_NO_OID, &partner);
                    305:                if (GSS_ERROR(maj_stat)) {
                    306:                        gssapi_error(min_stat, LOCATION, "import of %.*s\n",
                    307:                            name_token.length, name_token.value);
                    308:                        return -1;
                    309:                }
                    310:        } else
                    311:                if (gssapi_get_default_name(iph1, 1, &partner) < 0)
                    312:                        return -1;
                    313: 
                    314:        rtoken = gps->gsscnt_p == 0 ? dummy : &gps->gss_p[gps->gsscnt_p - 1];
                    315:        itoken = &gps->gss[gps->gsscnt];
                    316: 
                    317:        gps->gss_status = gss_init_sec_context(&min_stat, gps->gss_cred,
                    318:            &gps->gss_context, partner, GSS_C_NO_OID,
                    319:            GSS_C_MUTUAL_FLAG | GSS_C_SEQUENCE_FLAG |
                    320:                GSS_C_CONF_FLAG | GSS_C_INTEG_FLAG,
                    321:            0, GSS_C_NO_CHANNEL_BINDINGS, rtoken, NULL,
                    322:            itoken, NULL, NULL);
                    323: 
                    324:        if (GSS_ERROR(gps->gss_status)) {
                    325:                gssapi_error(min_stat, LOCATION, "init_sec_context\n");
                    326:                maj_stat = gss_release_name(&min_stat, &partner);
                    327:                if (GSS_ERROR(maj_stat))
                    328:                        gssapi_error(min_stat, LOCATION, "release name\n");
                    329:                return -1;
                    330:        }
                    331:        maj_stat = gss_release_name(&min_stat, &partner);
                    332:        if (GSS_ERROR(maj_stat))
                    333:                gssapi_error(min_stat, LOCATION, "release name\n");
                    334: 
                    335:        plog(LLV_DEBUG, LOCATION, NULL, "gss_init_sec_context status %x\n",
                    336:            gps->gss_status);
                    337: 
                    338:        if (lenp)
                    339:                *lenp = itoken->length;
                    340: 
                    341:        if (itoken->length != 0)
                    342:                gps->gsscnt++;
                    343: 
                    344:        return 0;
                    345: }
                    346: 
                    347: /*
                    348:  * Call gss_accept_context, with token just read from the wire.
                    349:  */
                    350: int
                    351: gssapi_get_rtoken(struct ph1handle *iph1, int *lenp)
                    352: {
                    353:        struct gssapi_ph1_state *gps;
                    354:        gss_buffer_desc name_token;
                    355:        gss_buffer_t itoken, rtoken;
                    356:        OM_uint32 min_stat, maj_stat;
                    357:        gss_name_t client_name;
                    358: 
                    359:        if (gssapi_get_state(iph1) == NULL && gssapi_init(iph1) < 0)
                    360:                return -1;
                    361: 
                    362:        gps = gssapi_get_state(iph1);
                    363: 
                    364:        rtoken = &gps->gss_p[gps->gsscnt_p - 1];
                    365:        itoken = &gps->gss[gps->gsscnt];
                    366: 
                    367:        gps->gss_status = gss_accept_sec_context(&min_stat, &gps->gss_context,
                    368:            gps->gss_cred, rtoken, GSS_C_NO_CHANNEL_BINDINGS, &client_name,
                    369:            NULL, itoken, NULL, NULL, NULL);
                    370: 
                    371:        if (GSS_ERROR(gps->gss_status)) {
                    372:                gssapi_error(min_stat, LOCATION, "accept_sec_context\n");
                    373:                return -1;
                    374:        }
                    375: 
                    376:        maj_stat = gss_display_name(&min_stat, client_name, &name_token, NULL);
                    377:        if (GSS_ERROR(maj_stat)) {
                    378:                gssapi_error(min_stat, LOCATION, "gss_display_name\n");
                    379:                maj_stat = gss_release_name(&min_stat, &client_name);
                    380:                if (GSS_ERROR(maj_stat))
                    381:                        gssapi_error(min_stat, LOCATION,
                    382:                            "release client_name\n");
                    383:                return -1;
                    384:        }
                    385:        maj_stat = gss_release_name(&min_stat, &client_name);
                    386:        if (GSS_ERROR(maj_stat))
                    387:                gssapi_error(min_stat, LOCATION, "release client_name\n");
                    388: 
                    389:        plog(LLV_DEBUG, LOCATION, NULL,
                    390:                "gss_accept_sec_context: other side is %s\n",
                    391:                (char *)name_token.value);
                    392:        maj_stat = gss_release_buffer(&min_stat, &name_token);
                    393:        if (GSS_ERROR(maj_stat))
                    394:                gssapi_error(min_stat, LOCATION, "release name buffer\n");
                    395: 
                    396:        if (itoken->length != 0)
                    397:                gps->gsscnt++;
                    398: 
                    399:        if (lenp)
                    400:                *lenp = itoken->length;
                    401: 
                    402:        return 0;
                    403: }
                    404: 
                    405: int
                    406: gssapi_save_received_token(struct ph1handle *iph1, vchar_t *token)
                    407: {
                    408:        struct gssapi_ph1_state *gps;
                    409:        gss_buffer_t gsstoken;
                    410:        int ret;
                    411: 
                    412:        if (gssapi_get_state(iph1) == NULL && gssapi_init(iph1) < 0)
                    413:                return -1;
                    414: 
                    415:        gps = gssapi_get_state(iph1);
                    416: 
                    417:        gsstoken = &gps->gss_p[gps->gsscnt_p];
                    418: 
                    419:        ret = gssapi_vm2gssbuf(token, gsstoken);
                    420:        if (ret < 0)
                    421:                return ret;
                    422:        gps->gsscnt_p++;
                    423: 
                    424:        return 0;
                    425: }
                    426: 
                    427: int
                    428: gssapi_get_token_to_send(struct ph1handle *iph1, vchar_t **token)
                    429: {
                    430:        struct gssapi_ph1_state *gps;
                    431:        gss_buffer_t gsstoken;
                    432:        int ret;
                    433: 
                    434:        gps = gssapi_get_state(iph1);
                    435:        if (gps == NULL) {
                    436:                plog(LLV_ERROR, LOCATION, NULL,
                    437:                    "gssapi not yet initialized?\n");
                    438:                return -1;
                    439:        }
                    440:        gsstoken = &gps->gss[gps->gsscnt - 1];
                    441:        ret = gssapi_gss2vmbuf(gsstoken, token);
                    442:        if (ret < 0)
                    443:                return ret;
                    444: 
                    445:        return 0;
                    446: }
                    447: 
                    448: int
                    449: gssapi_get_itokens(struct ph1handle *iph1, vchar_t **tokens)
                    450: {
                    451:        struct gssapi_ph1_state *gps;
                    452:        int len, i;
                    453:        vchar_t *toks;
                    454:        char *p;
                    455: 
                    456:        gps = gssapi_get_state(iph1);
                    457:        if (gps == NULL) {
                    458:                plog(LLV_ERROR, LOCATION, NULL,
                    459:                    "gssapi not yet initialized?\n");
                    460:                return -1;
                    461:        }
                    462: 
                    463:        for (i = len = 0; i < gps->gsscnt; i++)
                    464:                len += gps->gss[i].length;
                    465: 
                    466:        toks = vmalloc(len);
                    467:        if (toks == 0)
                    468:                return -1;
                    469:        p = (char *)toks->v;
                    470:        for (i = 0; i < gps->gsscnt; i++) {
                    471:                memcpy(p, gps->gss[i].value, gps->gss[i].length);
                    472:                p += gps->gss[i].length;
                    473:        }
                    474: 
                    475:        *tokens = toks;
                    476: 
                    477:        plog(LLV_DEBUG, LOCATION, NULL,
                    478:                "%d itokens of length %zu\n", gps->gsscnt, (*tokens)->l);
                    479: 
                    480:        return 0;
                    481: }
                    482: 
                    483: int
                    484: gssapi_get_rtokens(struct ph1handle *iph1, vchar_t **tokens)
                    485: {
                    486:        struct gssapi_ph1_state *gps;
                    487:        int len, i;
                    488:        vchar_t *toks;
                    489:        char *p;
                    490: 
                    491:        gps = gssapi_get_state(iph1);
                    492:        if (gps == NULL) {
                    493:                plog(LLV_ERROR, LOCATION, NULL,
                    494:                    "gssapi not yet initialized?\n");
                    495:                return -1;
                    496:        }
                    497: 
                    498:        if (gssapi_more_tokens(iph1)) {
                    499:                plog(LLV_ERROR, LOCATION, NULL,
                    500:                    "gssapi roundtrips not complete\n");
                    501:                return -1;
                    502:        }
                    503: 
                    504:        for (i = len = 0; i < gps->gsscnt_p; i++)
                    505:                len += gps->gss_p[i].length;
                    506: 
                    507:        toks = vmalloc(len);
                    508:        if (toks == 0)
                    509:                return -1;
                    510:        p = (char *)toks->v;
                    511:        for (i = 0; i < gps->gsscnt_p; i++) {
                    512:                memcpy(p, gps->gss_p[i].value, gps->gss_p[i].length);
                    513:                p += gps->gss_p[i].length;
                    514:        }
                    515: 
                    516:        *tokens = toks;
                    517: 
                    518:        return 0;
                    519: }
                    520: 
                    521: vchar_t *
                    522: gssapi_wraphash(struct ph1handle *iph1)
                    523: {
                    524:        struct gssapi_ph1_state *gps;
                    525:        OM_uint32 maj_stat, min_stat;
                    526:        gss_buffer_desc hash_in_buf, hash_out_buf;
                    527:        gss_buffer_t hash_in = &hash_in_buf, hash_out = &hash_out_buf;
                    528:        vchar_t *outbuf;
                    529: 
                    530:        gps = gssapi_get_state(iph1);
                    531:        if (gps == NULL) {
                    532:                plog(LLV_ERROR, LOCATION, NULL,
                    533:                    "gssapi not yet initialized?\n");
                    534:                return NULL;
                    535:        }
                    536: 
                    537:        if (gssapi_more_tokens(iph1)) {
                    538:                plog(LLV_ERROR, LOCATION, NULL,
                    539:                    "gssapi roundtrips not complete\n");
                    540:                return NULL;
                    541:        }
                    542: 
                    543:        if (gssapi_vm2gssbuf(iph1->hash, hash_in) < 0) {
                    544:                plog(LLV_ERROR, LOCATION, NULL, "vm2gssbuf failed\n");
                    545:                return NULL;
                    546:        }
                    547: 
                    548:        maj_stat = gss_wrap(&min_stat, gps->gss_context, 1, GSS_C_QOP_DEFAULT,
                    549:            hash_in, NULL, hash_out);
                    550:        if (GSS_ERROR(maj_stat)) {
                    551:                gssapi_error(min_stat, LOCATION, "wrapping hash value\n");
                    552:                maj_stat = gss_release_buffer(&min_stat, hash_in);
                    553:                if (GSS_ERROR(maj_stat))
                    554:                        gssapi_error(min_stat, LOCATION,
                    555:                            "release hash_in buffer\n");
                    556:                return NULL;
                    557:        }
                    558: 
                    559:        plog(LLV_DEBUG, LOCATION, NULL, "wrapped HASH, ilen %zu olen %zu\n",
                    560:            hash_in->length, hash_out->length);
                    561: 
                    562:        maj_stat = gss_release_buffer(&min_stat, hash_in);
                    563:        if (GSS_ERROR(maj_stat))
                    564:                gssapi_error(min_stat, LOCATION, "release hash_in buffer\n");
                    565: 
                    566:        if (gssapi_gss2vmbuf(hash_out, &outbuf) < 0) {
                    567:                plog(LLV_ERROR, LOCATION, NULL, "gss2vmbuf failed\n");
                    568:                maj_stat = gss_release_buffer(&min_stat, hash_out);
                    569:                if (GSS_ERROR(maj_stat))
                    570:                        gssapi_error(min_stat, LOCATION,
                    571:                            "release hash_out buffer\n");
                    572:                return NULL;
                    573:        }
                    574:        maj_stat = gss_release_buffer(&min_stat, hash_out);
                    575:        if (GSS_ERROR(maj_stat))
                    576:                gssapi_error(min_stat, LOCATION, "release hash_out buffer\n");
                    577: 
                    578:        return outbuf;
                    579: }
                    580: 
                    581: vchar_t *
                    582: gssapi_unwraphash(struct ph1handle *iph1)
                    583: {
                    584:        struct gssapi_ph1_state *gps;
                    585:        OM_uint32 maj_stat, min_stat;
                    586:        gss_buffer_desc hashbuf, hash_outbuf;
                    587:        gss_buffer_t hash_in = &hashbuf, hash_out = &hash_outbuf;
                    588:        vchar_t *outbuf;
                    589: 
                    590:        gps = gssapi_get_state(iph1);
                    591:        if (gps == NULL) {
                    592:                plog(LLV_ERROR, LOCATION, NULL,
                    593:                    "gssapi not yet initialized?\n");
                    594:                return NULL;
                    595:        }
                    596: 
                    597: 
                    598:        hashbuf.length = ntohs(iph1->pl_hash->h.len) - sizeof(*iph1->pl_hash);
                    599:        hashbuf.value = (char *)(iph1->pl_hash + 1);
                    600: 
                    601:        plog(LLV_DEBUG, LOCATION, NULL, "unwrapping HASH of len %zu\n",
                    602:            hashbuf.length);
                    603: 
                    604:        maj_stat = gss_unwrap(&min_stat, gps->gss_context, hash_in, hash_out,
                    605:            NULL, NULL);
                    606:        if (GSS_ERROR(maj_stat)) {
                    607:                gssapi_error(min_stat, LOCATION, "unwrapping hash value\n");
                    608:                return NULL;
                    609:        }
                    610: 
                    611:        if (gssapi_gss2vmbuf(hash_out, &outbuf) < 0) {
                    612:                plog(LLV_ERROR, LOCATION, NULL, "gss2vmbuf failed\n");
                    613:                maj_stat = gss_release_buffer(&min_stat, hash_out);
                    614:                if (GSS_ERROR(maj_stat))
                    615:                        gssapi_error(min_stat, LOCATION,
                    616:                            "release hash_out buffer\n");
                    617:                return NULL;
                    618:        }
                    619:        maj_stat = gss_release_buffer(&min_stat, hash_out);
                    620:        if (GSS_ERROR(maj_stat))
                    621:                gssapi_error(min_stat, LOCATION, "release hash_out buffer\n");
                    622: 
                    623:        return outbuf;
                    624: }
                    625: 
                    626: void
                    627: gssapi_set_id_sent(struct ph1handle *iph1)
                    628: {
                    629:        struct gssapi_ph1_state *gps;
                    630: 
                    631:        gps = gssapi_get_state(iph1);
                    632: 
                    633:        gps->gss_flags |= GSSFLAG_ID_SENT;
                    634: }
                    635: 
                    636: int
                    637: gssapi_id_sent(struct ph1handle *iph1)
                    638: {
                    639:        struct gssapi_ph1_state *gps;
                    640: 
                    641:        gps = gssapi_get_state(iph1);
                    642: 
                    643:        return (gps->gss_flags & GSSFLAG_ID_SENT) != 0;
                    644: }
                    645: 
                    646: void
                    647: gssapi_set_id_rcvd(struct ph1handle *iph1)
                    648: {
                    649:        struct gssapi_ph1_state *gps;
                    650: 
                    651:        gps = gssapi_get_state(iph1);
                    652: 
                    653:        gps->gss_flags |= GSSFLAG_ID_RCVD;
                    654: }
                    655: 
                    656: int
                    657: gssapi_id_rcvd(struct ph1handle *iph1)
                    658: {
                    659:        struct gssapi_ph1_state *gps;
                    660: 
                    661:        gps = gssapi_get_state(iph1);
                    662: 
                    663:        return (gps->gss_flags & GSSFLAG_ID_RCVD) != 0;
                    664: }
                    665: 
                    666: void
                    667: gssapi_free_state(struct ph1handle *iph1)
                    668: {
                    669:        struct gssapi_ph1_state *gps;
                    670:        OM_uint32 maj_stat, min_stat;
                    671: 
                    672:        gps = gssapi_get_state(iph1);
                    673: 
                    674:        if (gps == NULL)
                    675:                return;
                    676: 
                    677:        gssapi_set_state(iph1, NULL);
                    678: 
                    679:        if (gps->gss_cred != GSS_C_NO_CREDENTIAL) {
                    680:                maj_stat = gss_release_cred(&min_stat, &gps->gss_cred);
                    681:                if (GSS_ERROR(maj_stat))
                    682:                        gssapi_error(min_stat, LOCATION,
                    683:                            "releasing credentials\n");
                    684:        }
                    685:        racoon_free(gps);
                    686: }
                    687: 
                    688: vchar_t *
                    689: gssapi_get_id(struct ph1handle *iph1)
                    690: {
                    691:        gss_buffer_desc id_buffer;
                    692:        gss_buffer_t id = &id_buffer;
                    693:        gss_name_t defname, canon_name;
                    694:        OM_uint32 min_stat, maj_stat;
                    695:        vchar_t *vmbuf;
                    696: 
                    697:        if (iph1->rmconf->proposal->gssid != NULL)
                    698:                return (vdup(iph1->rmconf->proposal->gssid));
                    699: 
                    700:        if (gssapi_get_default_name(iph1, 0, &defname) < 0)
                    701:                return NULL;
                    702: 
                    703:        maj_stat = gss_canonicalize_name(&min_stat, defname, GSS_C_NO_OID,
                    704:            &canon_name);
                    705:        if (GSS_ERROR(maj_stat)) {
                    706:                gssapi_error(min_stat, LOCATION, "canonicalize name\n");
                    707:                maj_stat = gss_release_name(&min_stat, &defname);
                    708:                if (GSS_ERROR(maj_stat))
                    709:                        gssapi_error(min_stat, LOCATION,
                    710:                            "release default name\n");
                    711:                return NULL;
                    712:        }
                    713:        maj_stat = gss_release_name(&min_stat, &defname);
                    714:        if (GSS_ERROR(maj_stat))
                    715:                gssapi_error(min_stat, LOCATION, "release default name\n");
                    716: 
                    717:        maj_stat = gss_export_name(&min_stat, canon_name, id);
                    718:        if (GSS_ERROR(maj_stat)) {
                    719:                gssapi_error(min_stat, LOCATION, "export name\n");
                    720:                maj_stat = gss_release_name(&min_stat, &canon_name);
                    721:                if (GSS_ERROR(maj_stat))
                    722:                        gssapi_error(min_stat, LOCATION,
                    723:                            "release canonical name\n");
                    724:                return NULL;
                    725:        }
                    726:        maj_stat = gss_release_name(&min_stat, &canon_name);
                    727:        if (GSS_ERROR(maj_stat))
                    728:                gssapi_error(min_stat, LOCATION, "release canonical name\n");
                    729: 
                    730: #if 0
                    731:        /*
                    732:         * XXXJRT Did this debug message ever work?  This is a GSS name
                    733:         * blob at this point.
                    734:         */
                    735:        plog(LLV_DEBUG, LOCATION, NULL, "will try to acquire '%.*s' creds\n",
                    736:            id->length, id->value);
                    737: #endif
                    738: 
                    739:        if (gssapi_gss2vmbuf(id, &vmbuf) < 0) {
                    740:                plog(LLV_ERROR, LOCATION, NULL, "gss2vmbuf failed\n");
                    741:                maj_stat = gss_release_buffer(&min_stat, id);
                    742:                if (GSS_ERROR(maj_stat))
                    743:                        gssapi_error(min_stat, LOCATION, "release id buffer\n");
                    744:                return NULL;
                    745:        }
                    746:        maj_stat = gss_release_buffer(&min_stat, id);
                    747:        if (GSS_ERROR(maj_stat))
                    748:                gssapi_error(min_stat, LOCATION, "release id buffer\n");
                    749: 
                    750:        return vmbuf;
                    751: }
                    752: #else
                    753: int __gssapi_dUmMy;
                    754: #endif

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