Annotation of embedaddon/ipsec-tools/src/racoon/gssapi.c, revision 1.1.1.2
1.1 misho 1: /* $NetBSD: gssapi.c,v 1.4 2006/09/09 16:22:09 manu Exp $ */
2:
3: /* $KAME: gssapi.c,v 1.19 2001/04/03 15:51:55 thorpej Exp $ */
4:
5: /*
6: * Copyright 2000 Wasabi Systems, Inc.
7: * All rights reserved.
8: *
9: * This software was written by Frank van der Linden of Wasabi Systems
10: * for Zembu Labs, Inc. http://www.zembu.com/
11: *
12: * Redistribution and use in source and binary forms, with or without
13: * modification, are permitted provided that the following conditions
14: * are met:
15: * 1. Redistributions of source code must retain the above copyright
16: * notice, this list of conditions and the following disclaimer.
17: * 2. Redistributions in binary form must reproduce the above copyright
18: * notice, this list of conditions and the following disclaimer in the
19: * documentation and/or other materials provided with the distribution.
20: * 3. The name of Wasabi Systems, Inc. may not be used to endorse
21: * or promote products derived from this software without specific prior
22: * written permission.
23: *
24: * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
25: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
26: * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
27: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
28: * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34: * POSSIBILITY OF SUCH DAMAGE.
35: */
36:
37: #include "config.h"
38:
39: #ifdef HAVE_GSSAPI
40:
41: #include <sys/types.h>
42: #include <sys/queue.h>
43: #include <sys/socket.h>
44: #include <netdb.h>
45: #include <unistd.h>
46:
47: #include <stdlib.h>
48: #include <string.h>
49: #include <errno.h>
50:
51: #include "var.h"
52: #include "misc.h"
53: #include "vmbuf.h"
54: #include "plog.h"
55: #include "sockmisc.h"
56: #include "schedule.h"
57: #include "debug.h"
58:
59: #include "localconf.h"
60: #include "remoteconf.h"
61: #include "isakmp_var.h"
62: #include "isakmp.h"
63: #include "oakley.h"
64: #include "handler.h"
65: #include "ipsec_doi.h"
66: #include "crypto_openssl.h"
67: #include "pfkey.h"
68: #include "isakmp_ident.h"
69: #include "isakmp_inf.h"
70: #include "vendorid.h"
71: #include "gcmalloc.h"
72:
73: #include "gssapi.h"
74:
75: static void
76: gssapi_error(OM_uint32 status_code, const char *where,
77: const char *fmt, ...)
78: {
79: OM_uint32 message_context, maj_stat, min_stat;
80: gss_buffer_desc status_string;
81: va_list ap;
82:
83: va_start(ap, fmt);
84: plogv(LLV_ERROR, where, NULL, fmt, ap);
85: va_end(ap);
86:
87: message_context = 0;
88:
89: do {
90: maj_stat = gss_display_status(&min_stat, status_code,
91: GSS_C_MECH_CODE, GSS_C_NO_OID, &message_context,
92: &status_string);
93: if (GSS_ERROR(maj_stat))
94: plog(LLV_ERROR, LOCATION, NULL,
95: "UNABLE TO GET GSSAPI ERROR CODE\n");
96: else {
97: plog(LLV_ERROR, where, NULL,
98: "%s\n", (char *)status_string.value);
99: gss_release_buffer(&min_stat, &status_string);
100: }
101: } while (message_context != 0);
102: }
103:
104: /*
105: * vmbufs and gss_buffer_descs are really just the same on NetBSD, but
106: * this is to be portable.
107: */
108: static int
109: gssapi_vm2gssbuf(vchar_t *vmbuf, gss_buffer_t gsstoken)
110: {
111:
112: gsstoken->value = racoon_malloc(vmbuf->l);
113: if (gsstoken->value == NULL)
114: return -1;
115: memcpy(gsstoken->value, vmbuf->v, vmbuf->l);
116: gsstoken->length = vmbuf->l;
117:
118: return 0;
119: }
120:
121: static int
122: gssapi_gss2vmbuf(gss_buffer_t gsstoken, vchar_t **vmbuf)
123: {
124:
125: *vmbuf = vmalloc(gsstoken->length);
126: if (*vmbuf == NULL)
127: return -1;
128: memcpy((*vmbuf)->v, gsstoken->value, gsstoken->length);
129: (*vmbuf)->l = gsstoken->length;
130:
131: return 0;
132: }
133:
134: vchar_t *
135: gssapi_get_default_gss_id(void)
136: {
137: char name[NI_MAXHOST];
138: vchar_t *gssid;
139:
140: if (gethostname(name, sizeof(name)) != 0) {
141: plog(LLV_ERROR, LOCATION, NULL, "gethostname failed: %s\n",
142: strerror(errno));
143: return (NULL);
144: }
145: name[sizeof(name) - 1] = '\0';
146:
147: gssid = racoon_malloc(sizeof(*gssid));
148: gssid->l = asprintf(&gssid->v, "%s/%s", GSSAPI_DEF_NAME, name);
149:
150: return (gssid);
151: }
152:
153: static int
154: gssapi_get_default_name(struct ph1handle *iph1, int remote, gss_name_t *service)
155: {
156: char name[NI_MAXHOST];
157: struct sockaddr *sa;
158: char* buf = NULL;
159: gss_buffer_desc name_token;
160: OM_uint32 min_stat, maj_stat;
161:
162: sa = remote ? iph1->remote : iph1->local;
163:
164: if (getnameinfo(sa, sysdep_sa_len(sa), name, NI_MAXHOST, NULL, 0, 0) != 0)
165: return -1;
166:
167: name_token.length = asprintf(&buf, "%s@%s", GSSAPI_DEF_NAME, name);
168: name_token.value = buf;
169:
170: maj_stat = gss_import_name(&min_stat, &name_token,
171: GSS_C_NT_HOSTBASED_SERVICE, service);
172: if (GSS_ERROR(maj_stat)) {
173: gssapi_error(min_stat, LOCATION, "import name\n");
174: maj_stat = gss_release_buffer(&min_stat, &name_token);
175: if (GSS_ERROR(maj_stat))
176: gssapi_error(min_stat, LOCATION, "release name_token");
177: return -1;
178: }
179: maj_stat = gss_release_buffer(&min_stat, &name_token);
180: if (GSS_ERROR(maj_stat))
181: gssapi_error(min_stat, LOCATION, "release name_token");
182:
183: return 0;
184: }
185:
186: static int
187: gssapi_init(struct ph1handle *iph1)
188: {
189: struct gssapi_ph1_state *gps;
190: gss_buffer_desc id_token, cred_token;
191: gss_buffer_t cred = &cred_token;
192: gss_name_t princ, canon_princ;
193: OM_uint32 maj_stat, min_stat;
194:
1.1.1.2 ! misho 195: if (iph1->rmconf == NULL) {
! 196: plog(LLV_ERROR, LOCATION, NULL, "no remote config\n");
! 197: return -1;
! 198: }
! 199:
1.1 misho 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:
279: int
280: gssapi_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 = ∅
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: */
350: int
351: gssapi_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:
405: int
406: gssapi_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:
427: int
428: gssapi_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:
448: int
449: gssapi_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:
483: int
484: gssapi_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:
521: vchar_t *
522: gssapi_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:
581: vchar_t *
582: gssapi_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:
626: void
627: gssapi_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:
636: int
637: gssapi_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:
646: void
647: gssapi_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:
656: int
657: gssapi_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:
666: void
667: gssapi_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:
688: vchar_t *
689: gssapi_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
753: int __gssapi_dUmMy;
754: #endif
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>