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

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: 
                    195:        gps = racoon_calloc(1, sizeof (struct gssapi_ph1_state));
                    196:        if (gps == NULL) {
                    197:                plog(LLV_ERROR, LOCATION, NULL, "racoon_calloc failed\n");
                    198:                return -1;
                    199:        }
                    200:        gps->gss_context = GSS_C_NO_CONTEXT;
                    201:        gps->gss_cred = GSS_C_NO_CREDENTIAL;
                    202: 
                    203:        gssapi_set_state(iph1, gps);
                    204: 
                    205:        if (iph1->rmconf->proposal->gssid != NULL) {
                    206:                id_token.length = iph1->rmconf->proposal->gssid->l;
                    207:                id_token.value = iph1->rmconf->proposal->gssid->v;
                    208:                maj_stat = gss_import_name(&min_stat, &id_token, GSS_C_NO_OID,
                    209:                    &princ);
                    210:                if (GSS_ERROR(maj_stat)) {
                    211:                        gssapi_error(min_stat, LOCATION, "import name\n");
                    212:                        gssapi_free_state(iph1);
                    213:                        return -1;
                    214:                }
                    215:        } else
                    216:                gssapi_get_default_name(iph1, 0, &princ);
                    217: 
                    218:        maj_stat = gss_canonicalize_name(&min_stat, princ, GSS_C_NO_OID,
                    219:            &canon_princ);
                    220:        if (GSS_ERROR(maj_stat)) {
                    221:                gssapi_error(min_stat, LOCATION, "canonicalize name\n");
                    222:                maj_stat = gss_release_name(&min_stat, &princ);
                    223:                if (GSS_ERROR(maj_stat))
                    224:                        gssapi_error(min_stat, LOCATION, "release princ\n");
                    225:                gssapi_free_state(iph1);
                    226:                return -1;
                    227:        }
                    228:        maj_stat = gss_release_name(&min_stat, &princ);
                    229:        if (GSS_ERROR(maj_stat))
                    230:                gssapi_error(min_stat, LOCATION, "release princ\n");
                    231: 
                    232:        maj_stat = gss_export_name(&min_stat, canon_princ, cred);
                    233:        if (GSS_ERROR(maj_stat)) {
                    234:                gssapi_error(min_stat, LOCATION, "export name\n");
                    235:                maj_stat = gss_release_name(&min_stat, &canon_princ);
                    236:                if (GSS_ERROR(maj_stat))
                    237:                        gssapi_error(min_stat, LOCATION,
                    238:                            "release canon_princ\n");
                    239:                gssapi_free_state(iph1);
                    240:                return -1;
                    241:        }
                    242: 
                    243: #if 0
                    244:        /*
                    245:         * XXXJRT Did this debug message ever work?  This is a GSS name
                    246:         * blob at this point.
                    247:         */
                    248:        plog(LLV_DEBUG, LOCATION, NULL, "will try to acquire '%.*s' creds\n",
                    249:            cred->length, cred->value);
                    250: #endif
                    251: 
                    252:        maj_stat = gss_release_buffer(&min_stat, cred);
                    253:        if (GSS_ERROR(maj_stat))
                    254:                gssapi_error(min_stat, LOCATION, "release cred buffer\n");
                    255: 
                    256:        maj_stat = gss_acquire_cred(&min_stat, canon_princ, GSS_C_INDEFINITE,
                    257:            GSS_C_NO_OID_SET, GSS_C_BOTH, &gps->gss_cred, NULL, NULL);
                    258:        if (GSS_ERROR(maj_stat)) {
                    259:                gssapi_error(min_stat, LOCATION, "acquire cred\n");
                    260:                maj_stat = gss_release_name(&min_stat, &canon_princ);
                    261:                if (GSS_ERROR(maj_stat))
                    262:                        gssapi_error(min_stat, LOCATION,
                    263:                            "release canon_princ\n");
                    264:                gssapi_free_state(iph1);
                    265:                return -1;
                    266:        }
                    267:        maj_stat = gss_release_name(&min_stat, &canon_princ);
                    268:        if (GSS_ERROR(maj_stat))
                    269:                gssapi_error(min_stat, LOCATION, "release canon_princ\n");
                    270: 
                    271:        return 0;
                    272: }
                    273: 
                    274: int
                    275: gssapi_get_itoken(struct ph1handle *iph1, int *lenp)
                    276: {
                    277:        struct gssapi_ph1_state *gps;
                    278:        gss_buffer_desc empty, name_token;
                    279:        gss_buffer_t itoken, rtoken, dummy;
                    280:        OM_uint32 maj_stat, min_stat;
                    281:        gss_name_t partner;
                    282: 
                    283:        if (gssapi_get_state(iph1) == NULL && gssapi_init(iph1) < 0)
                    284:                return -1;
                    285: 
                    286:        gps = gssapi_get_state(iph1);
                    287: 
                    288:        empty.length = 0;
                    289:        empty.value = NULL;
                    290:        dummy = &empty;
                    291: 
                    292:        if (iph1->approval != NULL && iph1->approval->gssid != NULL) {
                    293:                plog(LLV_DEBUG, LOCATION, NULL,
                    294:                    "using provided service '%.*s'\n",
                    295:                    (int)iph1->approval->gssid->l, iph1->approval->gssid->v);
                    296:                name_token.length = iph1->approval->gssid->l;
                    297:                name_token.value = iph1->approval->gssid->v;
                    298:                maj_stat = gss_import_name(&min_stat, &name_token,
                    299:                    GSS_C_NO_OID, &partner);
                    300:                if (GSS_ERROR(maj_stat)) {
                    301:                        gssapi_error(min_stat, LOCATION, "import of %.*s\n",
                    302:                            name_token.length, name_token.value);
                    303:                        return -1;
                    304:                }
                    305:        } else
                    306:                if (gssapi_get_default_name(iph1, 1, &partner) < 0)
                    307:                        return -1;
                    308: 
                    309:        rtoken = gps->gsscnt_p == 0 ? dummy : &gps->gss_p[gps->gsscnt_p - 1];
                    310:        itoken = &gps->gss[gps->gsscnt];
                    311: 
                    312:        gps->gss_status = gss_init_sec_context(&min_stat, gps->gss_cred,
                    313:            &gps->gss_context, partner, GSS_C_NO_OID,
                    314:            GSS_C_MUTUAL_FLAG | GSS_C_SEQUENCE_FLAG |
                    315:                GSS_C_CONF_FLAG | GSS_C_INTEG_FLAG,
                    316:            0, GSS_C_NO_CHANNEL_BINDINGS, rtoken, NULL,
                    317:            itoken, NULL, NULL);
                    318: 
                    319:        if (GSS_ERROR(gps->gss_status)) {
                    320:                gssapi_error(min_stat, LOCATION, "init_sec_context\n");
                    321:                maj_stat = gss_release_name(&min_stat, &partner);
                    322:                if (GSS_ERROR(maj_stat))
                    323:                        gssapi_error(min_stat, LOCATION, "release name\n");
                    324:                return -1;
                    325:        }
                    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: 
                    330:        plog(LLV_DEBUG, LOCATION, NULL, "gss_init_sec_context status %x\n",
                    331:            gps->gss_status);
                    332: 
                    333:        if (lenp)
                    334:                *lenp = itoken->length;
                    335: 
                    336:        if (itoken->length != 0)
                    337:                gps->gsscnt++;
                    338: 
                    339:        return 0;
                    340: }
                    341: 
                    342: /*
                    343:  * Call gss_accept_context, with token just read from the wire.
                    344:  */
                    345: int
                    346: gssapi_get_rtoken(struct ph1handle *iph1, int *lenp)
                    347: {
                    348:        struct gssapi_ph1_state *gps;
                    349:        gss_buffer_desc name_token;
                    350:        gss_buffer_t itoken, rtoken;
                    351:        OM_uint32 min_stat, maj_stat;
                    352:        gss_name_t client_name;
                    353: 
                    354:        if (gssapi_get_state(iph1) == NULL && gssapi_init(iph1) < 0)
                    355:                return -1;
                    356: 
                    357:        gps = gssapi_get_state(iph1);
                    358: 
                    359:        rtoken = &gps->gss_p[gps->gsscnt_p - 1];
                    360:        itoken = &gps->gss[gps->gsscnt];
                    361: 
                    362:        gps->gss_status = gss_accept_sec_context(&min_stat, &gps->gss_context,
                    363:            gps->gss_cred, rtoken, GSS_C_NO_CHANNEL_BINDINGS, &client_name,
                    364:            NULL, itoken, NULL, NULL, NULL);
                    365: 
                    366:        if (GSS_ERROR(gps->gss_status)) {
                    367:                gssapi_error(min_stat, LOCATION, "accept_sec_context\n");
                    368:                return -1;
                    369:        }
                    370: 
                    371:        maj_stat = gss_display_name(&min_stat, client_name, &name_token, NULL);
                    372:        if (GSS_ERROR(maj_stat)) {
                    373:                gssapi_error(min_stat, LOCATION, "gss_display_name\n");
                    374:                maj_stat = gss_release_name(&min_stat, &client_name);
                    375:                if (GSS_ERROR(maj_stat))
                    376:                        gssapi_error(min_stat, LOCATION,
                    377:                            "release client_name\n");
                    378:                return -1;
                    379:        }
                    380:        maj_stat = gss_release_name(&min_stat, &client_name);
                    381:        if (GSS_ERROR(maj_stat))
                    382:                gssapi_error(min_stat, LOCATION, "release client_name\n");
                    383: 
                    384:        plog(LLV_DEBUG, LOCATION, NULL,
                    385:                "gss_accept_sec_context: other side is %s\n",
                    386:                (char *)name_token.value);
                    387:        maj_stat = gss_release_buffer(&min_stat, &name_token);
                    388:        if (GSS_ERROR(maj_stat))
                    389:                gssapi_error(min_stat, LOCATION, "release name buffer\n");
                    390: 
                    391:        if (itoken->length != 0)
                    392:                gps->gsscnt++;
                    393: 
                    394:        if (lenp)
                    395:                *lenp = itoken->length;
                    396: 
                    397:        return 0;
                    398: }
                    399: 
                    400: int
                    401: gssapi_save_received_token(struct ph1handle *iph1, vchar_t *token)
                    402: {
                    403:        struct gssapi_ph1_state *gps;
                    404:        gss_buffer_t gsstoken;
                    405:        int ret;
                    406: 
                    407:        if (gssapi_get_state(iph1) == NULL && gssapi_init(iph1) < 0)
                    408:                return -1;
                    409: 
                    410:        gps = gssapi_get_state(iph1);
                    411: 
                    412:        gsstoken = &gps->gss_p[gps->gsscnt_p];
                    413: 
                    414:        ret = gssapi_vm2gssbuf(token, gsstoken);
                    415:        if (ret < 0)
                    416:                return ret;
                    417:        gps->gsscnt_p++;
                    418: 
                    419:        return 0;
                    420: }
                    421: 
                    422: int
                    423: gssapi_get_token_to_send(struct ph1handle *iph1, vchar_t **token)
                    424: {
                    425:        struct gssapi_ph1_state *gps;
                    426:        gss_buffer_t gsstoken;
                    427:        int ret;
                    428: 
                    429:        gps = gssapi_get_state(iph1);
                    430:        if (gps == NULL) {
                    431:                plog(LLV_ERROR, LOCATION, NULL,
                    432:                    "gssapi not yet initialized?\n");
                    433:                return -1;
                    434:        }
                    435:        gsstoken = &gps->gss[gps->gsscnt - 1];
                    436:        ret = gssapi_gss2vmbuf(gsstoken, token);
                    437:        if (ret < 0)
                    438:                return ret;
                    439: 
                    440:        return 0;
                    441: }
                    442: 
                    443: int
                    444: gssapi_get_itokens(struct ph1handle *iph1, vchar_t **tokens)
                    445: {
                    446:        struct gssapi_ph1_state *gps;
                    447:        int len, i;
                    448:        vchar_t *toks;
                    449:        char *p;
                    450: 
                    451:        gps = gssapi_get_state(iph1);
                    452:        if (gps == NULL) {
                    453:                plog(LLV_ERROR, LOCATION, NULL,
                    454:                    "gssapi not yet initialized?\n");
                    455:                return -1;
                    456:        }
                    457: 
                    458:        for (i = len = 0; i < gps->gsscnt; i++)
                    459:                len += gps->gss[i].length;
                    460: 
                    461:        toks = vmalloc(len);
                    462:        if (toks == 0)
                    463:                return -1;
                    464:        p = (char *)toks->v;
                    465:        for (i = 0; i < gps->gsscnt; i++) {
                    466:                memcpy(p, gps->gss[i].value, gps->gss[i].length);
                    467:                p += gps->gss[i].length;
                    468:        }
                    469: 
                    470:        *tokens = toks;
                    471: 
                    472:        plog(LLV_DEBUG, LOCATION, NULL,
                    473:                "%d itokens of length %zu\n", gps->gsscnt, (*tokens)->l);
                    474: 
                    475:        return 0;
                    476: }
                    477: 
                    478: int
                    479: gssapi_get_rtokens(struct ph1handle *iph1, vchar_t **tokens)
                    480: {
                    481:        struct gssapi_ph1_state *gps;
                    482:        int len, i;
                    483:        vchar_t *toks;
                    484:        char *p;
                    485: 
                    486:        gps = gssapi_get_state(iph1);
                    487:        if (gps == NULL) {
                    488:                plog(LLV_ERROR, LOCATION, NULL,
                    489:                    "gssapi not yet initialized?\n");
                    490:                return -1;
                    491:        }
                    492: 
                    493:        if (gssapi_more_tokens(iph1)) {
                    494:                plog(LLV_ERROR, LOCATION, NULL,
                    495:                    "gssapi roundtrips not complete\n");
                    496:                return -1;
                    497:        }
                    498: 
                    499:        for (i = len = 0; i < gps->gsscnt_p; i++)
                    500:                len += gps->gss_p[i].length;
                    501: 
                    502:        toks = vmalloc(len);
                    503:        if (toks == 0)
                    504:                return -1;
                    505:        p = (char *)toks->v;
                    506:        for (i = 0; i < gps->gsscnt_p; i++) {
                    507:                memcpy(p, gps->gss_p[i].value, gps->gss_p[i].length);
                    508:                p += gps->gss_p[i].length;
                    509:        }
                    510: 
                    511:        *tokens = toks;
                    512: 
                    513:        return 0;
                    514: }
                    515: 
                    516: vchar_t *
                    517: gssapi_wraphash(struct ph1handle *iph1)
                    518: {
                    519:        struct gssapi_ph1_state *gps;
                    520:        OM_uint32 maj_stat, min_stat;
                    521:        gss_buffer_desc hash_in_buf, hash_out_buf;
                    522:        gss_buffer_t hash_in = &hash_in_buf, hash_out = &hash_out_buf;
                    523:        vchar_t *outbuf;
                    524: 
                    525:        gps = gssapi_get_state(iph1);
                    526:        if (gps == NULL) {
                    527:                plog(LLV_ERROR, LOCATION, NULL,
                    528:                    "gssapi not yet initialized?\n");
                    529:                return NULL;
                    530:        }
                    531: 
                    532:        if (gssapi_more_tokens(iph1)) {
                    533:                plog(LLV_ERROR, LOCATION, NULL,
                    534:                    "gssapi roundtrips not complete\n");
                    535:                return NULL;
                    536:        }
                    537: 
                    538:        if (gssapi_vm2gssbuf(iph1->hash, hash_in) < 0) {
                    539:                plog(LLV_ERROR, LOCATION, NULL, "vm2gssbuf failed\n");
                    540:                return NULL;
                    541:        }
                    542: 
                    543:        maj_stat = gss_wrap(&min_stat, gps->gss_context, 1, GSS_C_QOP_DEFAULT,
                    544:            hash_in, NULL, hash_out);
                    545:        if (GSS_ERROR(maj_stat)) {
                    546:                gssapi_error(min_stat, LOCATION, "wrapping hash value\n");
                    547:                maj_stat = gss_release_buffer(&min_stat, hash_in);
                    548:                if (GSS_ERROR(maj_stat))
                    549:                        gssapi_error(min_stat, LOCATION,
                    550:                            "release hash_in buffer\n");
                    551:                return NULL;
                    552:        }
                    553: 
                    554:        plog(LLV_DEBUG, LOCATION, NULL, "wrapped HASH, ilen %zu olen %zu\n",
                    555:            hash_in->length, hash_out->length);
                    556: 
                    557:        maj_stat = gss_release_buffer(&min_stat, hash_in);
                    558:        if (GSS_ERROR(maj_stat))
                    559:                gssapi_error(min_stat, LOCATION, "release hash_in buffer\n");
                    560: 
                    561:        if (gssapi_gss2vmbuf(hash_out, &outbuf) < 0) {
                    562:                plog(LLV_ERROR, LOCATION, NULL, "gss2vmbuf failed\n");
                    563:                maj_stat = gss_release_buffer(&min_stat, hash_out);
                    564:                if (GSS_ERROR(maj_stat))
                    565:                        gssapi_error(min_stat, LOCATION,
                    566:                            "release hash_out buffer\n");
                    567:                return NULL;
                    568:        }
                    569:        maj_stat = gss_release_buffer(&min_stat, hash_out);
                    570:        if (GSS_ERROR(maj_stat))
                    571:                gssapi_error(min_stat, LOCATION, "release hash_out buffer\n");
                    572: 
                    573:        return outbuf;
                    574: }
                    575: 
                    576: vchar_t *
                    577: gssapi_unwraphash(struct ph1handle *iph1)
                    578: {
                    579:        struct gssapi_ph1_state *gps;
                    580:        OM_uint32 maj_stat, min_stat;
                    581:        gss_buffer_desc hashbuf, hash_outbuf;
                    582:        gss_buffer_t hash_in = &hashbuf, hash_out = &hash_outbuf;
                    583:        vchar_t *outbuf;
                    584: 
                    585:        gps = gssapi_get_state(iph1);
                    586:        if (gps == NULL) {
                    587:                plog(LLV_ERROR, LOCATION, NULL,
                    588:                    "gssapi not yet initialized?\n");
                    589:                return NULL;
                    590:        }
                    591: 
                    592: 
                    593:        hashbuf.length = ntohs(iph1->pl_hash->h.len) - sizeof(*iph1->pl_hash);
                    594:        hashbuf.value = (char *)(iph1->pl_hash + 1);
                    595: 
                    596:        plog(LLV_DEBUG, LOCATION, NULL, "unwrapping HASH of len %zu\n",
                    597:            hashbuf.length);
                    598: 
                    599:        maj_stat = gss_unwrap(&min_stat, gps->gss_context, hash_in, hash_out,
                    600:            NULL, NULL);
                    601:        if (GSS_ERROR(maj_stat)) {
                    602:                gssapi_error(min_stat, LOCATION, "unwrapping hash value\n");
                    603:                return NULL;
                    604:        }
                    605: 
                    606:        if (gssapi_gss2vmbuf(hash_out, &outbuf) < 0) {
                    607:                plog(LLV_ERROR, LOCATION, NULL, "gss2vmbuf failed\n");
                    608:                maj_stat = gss_release_buffer(&min_stat, hash_out);
                    609:                if (GSS_ERROR(maj_stat))
                    610:                        gssapi_error(min_stat, LOCATION,
                    611:                            "release hash_out buffer\n");
                    612:                return NULL;
                    613:        }
                    614:        maj_stat = gss_release_buffer(&min_stat, hash_out);
                    615:        if (GSS_ERROR(maj_stat))
                    616:                gssapi_error(min_stat, LOCATION, "release hash_out buffer\n");
                    617: 
                    618:        return outbuf;
                    619: }
                    620: 
                    621: void
                    622: gssapi_set_id_sent(struct ph1handle *iph1)
                    623: {
                    624:        struct gssapi_ph1_state *gps;
                    625: 
                    626:        gps = gssapi_get_state(iph1);
                    627: 
                    628:        gps->gss_flags |= GSSFLAG_ID_SENT;
                    629: }
                    630: 
                    631: int
                    632: gssapi_id_sent(struct ph1handle *iph1)
                    633: {
                    634:        struct gssapi_ph1_state *gps;
                    635: 
                    636:        gps = gssapi_get_state(iph1);
                    637: 
                    638:        return (gps->gss_flags & GSSFLAG_ID_SENT) != 0;
                    639: }
                    640: 
                    641: void
                    642: gssapi_set_id_rcvd(struct ph1handle *iph1)
                    643: {
                    644:        struct gssapi_ph1_state *gps;
                    645: 
                    646:        gps = gssapi_get_state(iph1);
                    647: 
                    648:        gps->gss_flags |= GSSFLAG_ID_RCVD;
                    649: }
                    650: 
                    651: int
                    652: gssapi_id_rcvd(struct ph1handle *iph1)
                    653: {
                    654:        struct gssapi_ph1_state *gps;
                    655: 
                    656:        gps = gssapi_get_state(iph1);
                    657: 
                    658:        return (gps->gss_flags & GSSFLAG_ID_RCVD) != 0;
                    659: }
                    660: 
                    661: void
                    662: gssapi_free_state(struct ph1handle *iph1)
                    663: {
                    664:        struct gssapi_ph1_state *gps;
                    665:        OM_uint32 maj_stat, min_stat;
                    666: 
                    667:        gps = gssapi_get_state(iph1);
                    668: 
                    669:        if (gps == NULL)
                    670:                return;
                    671: 
                    672:        gssapi_set_state(iph1, NULL);
                    673: 
                    674:        if (gps->gss_cred != GSS_C_NO_CREDENTIAL) {
                    675:                maj_stat = gss_release_cred(&min_stat, &gps->gss_cred);
                    676:                if (GSS_ERROR(maj_stat))
                    677:                        gssapi_error(min_stat, LOCATION,
                    678:                            "releasing credentials\n");
                    679:        }
                    680:        racoon_free(gps);
                    681: }
                    682: 
                    683: vchar_t *
                    684: gssapi_get_id(struct ph1handle *iph1)
                    685: {
                    686:        gss_buffer_desc id_buffer;
                    687:        gss_buffer_t id = &id_buffer;
                    688:        gss_name_t defname, canon_name;
                    689:        OM_uint32 min_stat, maj_stat;
                    690:        vchar_t *vmbuf;
                    691: 
                    692:        if (iph1->rmconf->proposal->gssid != NULL)
                    693:                return (vdup(iph1->rmconf->proposal->gssid));
                    694: 
                    695:        if (gssapi_get_default_name(iph1, 0, &defname) < 0)
                    696:                return NULL;
                    697: 
                    698:        maj_stat = gss_canonicalize_name(&min_stat, defname, GSS_C_NO_OID,
                    699:            &canon_name);
                    700:        if (GSS_ERROR(maj_stat)) {
                    701:                gssapi_error(min_stat, LOCATION, "canonicalize name\n");
                    702:                maj_stat = gss_release_name(&min_stat, &defname);
                    703:                if (GSS_ERROR(maj_stat))
                    704:                        gssapi_error(min_stat, LOCATION,
                    705:                            "release default name\n");
                    706:                return NULL;
                    707:        }
                    708:        maj_stat = gss_release_name(&min_stat, &defname);
                    709:        if (GSS_ERROR(maj_stat))
                    710:                gssapi_error(min_stat, LOCATION, "release default name\n");
                    711: 
                    712:        maj_stat = gss_export_name(&min_stat, canon_name, id);
                    713:        if (GSS_ERROR(maj_stat)) {
                    714:                gssapi_error(min_stat, LOCATION, "export name\n");
                    715:                maj_stat = gss_release_name(&min_stat, &canon_name);
                    716:                if (GSS_ERROR(maj_stat))
                    717:                        gssapi_error(min_stat, LOCATION,
                    718:                            "release canonical name\n");
                    719:                return NULL;
                    720:        }
                    721:        maj_stat = gss_release_name(&min_stat, &canon_name);
                    722:        if (GSS_ERROR(maj_stat))
                    723:                gssapi_error(min_stat, LOCATION, "release canonical name\n");
                    724: 
                    725: #if 0
                    726:        /*
                    727:         * XXXJRT Did this debug message ever work?  This is a GSS name
                    728:         * blob at this point.
                    729:         */
                    730:        plog(LLV_DEBUG, LOCATION, NULL, "will try to acquire '%.*s' creds\n",
                    731:            id->length, id->value);
                    732: #endif
                    733: 
                    734:        if (gssapi_gss2vmbuf(id, &vmbuf) < 0) {
                    735:                plog(LLV_ERROR, LOCATION, NULL, "gss2vmbuf failed\n");
                    736:                maj_stat = gss_release_buffer(&min_stat, id);
                    737:                if (GSS_ERROR(maj_stat))
                    738:                        gssapi_error(min_stat, LOCATION, "release id buffer\n");
                    739:                return NULL;
                    740:        }
                    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: 
                    745:        return vmbuf;
                    746: }
                    747: #else
                    748: int __gssapi_dUmMy;
                    749: #endif

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