source: rtems-libbsd/ipsec-tools/src/racoon/gssapi.c @ ff36f5e

5-freebsd-12
Last change on this file since ff36f5e was ff36f5e, checked in by Christian Mauderer <christian.mauderer@…>, on May 30, 2018 at 12:27:35 PM

Import ipsec-tools 0.8.2.

Import unchanged ipsec-tools sources in the release version 0.8.2. The
homepage of ipsec-tools is http://ipsec-tools.sourceforge.net/. The
sources can be obtained from there.

  • Property mode set to 100644
File size: 18.9 KB
Line 
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
75static void
76gssapi_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 */
108static int
109gssapi_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
121static int
122gssapi_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
134vchar_t *
135gssapi_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
153static int
154gssapi_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
186static int
187gssapi_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
274int
275gssapi_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 */
345int
346gssapi_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
400int
401gssapi_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
422int
423gssapi_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
443int
444gssapi_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
478int
479gssapi_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
516vchar_t *
517gssapi_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
576vchar_t *
577gssapi_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
621void
622gssapi_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
631int
632gssapi_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
641void
642gssapi_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
651int
652gssapi_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
661void
662gssapi_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
683vchar_t *
684gssapi_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
748int __gssapi_dUmMy;
749#endif
Note: See TracBrowser for help on using the repository browser.