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