1 /* #ident "@(#)g_glue.c 1.1 96/02/06 SMI" */
4 * Copyright 1996 by Sun Microsystems, Inc.
6 * Permission to use, copy, modify, distribute, and sell this software
7 * and its documentation for any purpose is hereby granted without fee,
8 * provided that the above copyright notice appears in all copies and
9 * that both that copyright notice and this permission notice appear in
10 * supporting documentation, and that the name of Sun Microsystems not be used
11 * in advertising or publicity pertaining to distribution of the software
12 * without specific, written prior permission. Sun Microsystems makes no
13 * representations about the suitability of this software for any
14 * purpose. It is provided "as is" without express or implied warranty.
16 * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
17 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
18 * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
19 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
20 * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
21 * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
22 * PERFORMANCE OF THIS SOFTWARE.
33 #define g_OID_equal(o1,o2) \
34 (((o1)->length == (o2)->length) && \
35 (memcmp((o1)->elements,(o2)->elements,(int) (o1)->length) == 0))
37 extern gss_mechanism *__gss_mechs_array;
40 * This file contains the support routines for the glue layer.
44 * given the mechs_array and a mechanism OID, return the
45 * pointer to the mechanism, or NULL if that mechanism is
46 * not supported. If the requested OID is NULL, then return
47 * the first mechanism.
50 gss_mechanism __gss_get_mechanism (type)
55 if (type == GSS_C_NULL_OID)
56 return (__gss_mechs_array[0]);
58 for (i=0; __gss_mechs_array[i]->mech_type.length != 0; i++) {
59 if ((__gss_mechs_array[i]->mech_type.length == type->length) &&
60 (memcmp (__gss_mechs_array[i]->mech_type.elements, type->elements,
61 type->length) == 0)) {
63 return (__gss_mechs_array[i]);
71 * glue routine for get_mech_type
75 OM_uint32 __gss_get_mech_type(OID, token)
79 unsigned char * buffer_ptr;
83 * This routine reads the prefix of "token" in order to determine
84 * its mechanism type. It assumes the encoding suggested in
85 * Appendix B of RFC 1508. This format starts out as follows :
87 * tag for APPLICATION 0, Sequence[constructed, definite length]
88 * length of remainder of token
89 * tag of OBJECT IDENTIFIER
90 * length of mechanism OID
91 * encoding of mechanism OID
92 * <the rest of the token>
94 * Numerically, this looks like :
97 * <length> - could be multiple bytes
99 * <length> - assume only one byte, hence OID length < 127
102 * The routine fills in the OID value and returns an error as necessary.
106 return (GSS_S_DEFECTIVE_TOKEN);
108 /* Skip past the APP/Sequnce byte and the token length */
110 buffer_ptr = (unsigned char *) token->value;
112 if (*(buffer_ptr++) != 0x60)
113 return (GSS_S_DEFECTIVE_TOKEN);
114 length = *buffer_ptr++;
116 if ((length & 0x7f) > 4)
117 return (GSS_S_DEFECTIVE_TOKEN);
118 buffer_ptr += length & 0x7f;
121 if (*(buffer_ptr++) != 0x06)
122 return (GSS_S_DEFECTIVE_TOKEN);
124 OID->length = (OM_uint32) *(buffer_ptr++);
125 OID->elements = (void *) buffer_ptr;
126 return (GSS_S_COMPLETE);
131 * Internal routines to get and release an internal mechanism name
136 OM_uint32 __gss_import_internal_name (minor_status, mech_type, union_name,
138 OM_uint32 *minor_status;
140 gss_union_name_t union_name;
141 gss_name_t *internal_name;
146 mech = __gss_get_mechanism (mech_type);
148 if (mech->gss_import_name)
149 status = mech->gss_import_name (
150 #ifdef USE_MECH_CONTEXT
154 union_name->external_name,
155 union_name->name_type,
158 status = GSS_S_BAD_BINDINGS;
163 return (GSS_S_BAD_MECH);
166 OM_uint32 __gss_display_internal_name (minor_status, mech_type, internal_name,
167 external_name, name_type)
168 OM_uint32 *minor_status;
170 gss_name_t internal_name;
171 gss_buffer_t external_name;
177 mech = __gss_get_mechanism (mech_type);
179 if (mech->gss_display_name)
180 status = mech->gss_display_name (
181 #ifdef USE_MECH_CONTEXT
189 status = GSS_S_BAD_BINDINGS;
194 return (GSS_S_BAD_MECH);
197 OM_uint32 __gss_release_internal_name (minor_status, mech_type, internal_name)
198 OM_uint32 *minor_status;
200 gss_name_t *internal_name;
205 mech = __gss_get_mechanism (mech_type);
207 if (mech->gss_release_name)
208 status = mech->gss_release_name (
209 #ifdef USE_MECH_CONTEXT
215 status = GSS_S_BAD_BINDINGS;
220 return (GSS_S_BAD_MECH);
225 * This function converts an internal gssapi name to a union gssapi
226 * name. Note that internal_name should be considered "consumed" by
227 * this call, whether or not we return an error.
229 OM_uint32 __gss_convert_name_to_union_name(minor_status, mech,
230 internal_name, external_name)
231 OM_uint32 *minor_status;
233 gss_name_t internal_name;
234 gss_name_t *external_name;
236 OM_uint32 major_status,tmp;
237 gss_union_name_t union_name;
239 union_name = (gss_union_name_t) malloc (sizeof(gss_union_name_desc));
241 *minor_status = ENOMEM;
242 goto allocation_failure;
244 union_name->mech_type = 0;
245 union_name->mech_name = internal_name;
246 union_name->name_type = 0;
247 union_name->external_name = 0;
248 union_name->gss_mech = mech;
250 major_status = generic_gss_copy_oid(minor_status, &mech->mech_type,
251 &union_name->mech_type);
252 if (major_status != GSS_S_COMPLETE)
253 goto allocation_failure;
255 union_name->external_name =
256 (gss_buffer_t) malloc(sizeof(gss_buffer_desc));
257 if (!union_name->external_name) {
258 *minor_status = ENOMEM;
259 goto allocation_failure;
262 #ifdef USE_MECH_CONTEXT
263 major_status = mech->gss_display_name(mech->context, minor_status,
265 major_status = mech->gss_display_name(minor_status,
268 union_name->external_name,
269 &union_name->name_type);
270 if (major_status != GSS_S_COMPLETE)
271 goto allocation_failure;
273 *external_name = union_name;
274 return (GSS_S_COMPLETE);
278 if (union_name->external_name) {
279 if (union_name->external_name->value)
280 free(union_name->external_name->value);
281 free(union_name->external_name);
283 if (union_name->name_type)
284 generic_gss_release_oid(&tmp, &union_name->name_type);
285 if (union_name->mech_name)
286 __gss_release_internal_name(minor_status, union_name->mech_type,
287 &union_name->mech_name);
288 if (union_name->mech_type)
289 mech_gss_release_oid(&tmp, &union_name->mech_type, mech);
292 return (major_status);
296 * Glue routine for returning the mechanism-specific credential from a
297 * external union credential.
300 __gss_get_mechanism_cred(union_cred, mech_type)
301 gss_union_cred_t union_cred;
306 if (union_cred == GSS_C_NO_CREDENTIAL)
307 return GSS_C_NO_CREDENTIAL;
309 for (i=0; i < union_cred->count; i++) {
310 if (g_OID_equal(mech_type, &union_cred->mechs_array[i]))
311 return union_cred->cred_array[i];
313 return GSS_C_NO_CREDENTIAL;
318 * Glue routine to copy an external name buffer (used by gss_duplicate_name)
320 OM_uint32 __gss_copy_namebuf(src, dest)
324 gss_buffer_t temp = NULL;
327 return (GSS_S_BAD_NAME);
329 temp = (gss_buffer_t) malloc (sizeof(gss_buffer_t));
331 return(GSS_S_FAILURE);
333 temp->value = (void *) malloc (src->length + 1);
334 if (temp->value == NULL) {
336 return(GSS_S_FAILURE);
339 memcpy(temp->value, src->value, src->length);
340 temp->length = src->length;
343 return (GSS_S_COMPLETE);