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

5-freebsd-12
Last change on this file since 8645c9d7 was 8645c9d7, checked in by Christian Mauderer <christian.mauderer@…>, on Jun 6, 2018 at 9:11:52 AM

ipsec-tools: Apply patches from FreeBSD ports.

Source: https://svnweb.freebsd.org/ports/head/security/ipsec-tools/files/ revision 468617.

  • Property mode set to 100644
File size: 19.0 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        if (iph1->rmconf == NULL) {
196                plog(LLV_ERROR, LOCATION, NULL, "no remote config\n");
197                return -1;
198        }
199
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
279int
280gssapi_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 */
350int
351gssapi_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
405int
406gssapi_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
427int
428gssapi_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
448int
449gssapi_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
483int
484gssapi_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
521vchar_t *
522gssapi_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
581vchar_t *
582gssapi_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
626void
627gssapi_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
636int
637gssapi_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
646void
647gssapi_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
656int
657gssapi_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
666void
667gssapi_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
688vchar_t *
689gssapi_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
753int __gssapi_dUmMy;
754#endif
Note: See TracBrowser for help on using the repository browser.