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

5-freebsd-12
Last change on this file since b376ae1 was b376ae1, checked in by Christian Mauderer <christian.mauderer@…>, on May 3, 2018 at 12:15:11 PM

ipsec-tools: Port libipsec, setkey and racoon.

Note that this replaces the libipsec from FreeBSD with the one provided
by ipsec-tools.

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