2 * lib/gssapi/generic/oid_ops.c
4 * Copyright 1995 by the Massachusetts Institute of Technology.
7 * Export of this software from the United States of America may
8 * require a specific license from the United States Government.
9 * It is the responsibility of any person or organization contemplating
10 * export to obtain such a license before exporting.
12 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
13 * distribute this software and its documentation for any purpose and
14 * without fee is hereby granted, provided that the above copyright
15 * notice appear in all copies and that both that copyright notice and
16 * this permission notice appear in supporting documentation, and that
17 * the name of M.I.T. not be used in advertising or publicity pertaining
18 * to distribution of the software without specific, written prior
19 * permission. Furthermore if you modify this software you must label
20 * your software as modified software and not distribute it in such a
21 * fashion that it might be confused with the original M.I.T. software.
22 * M.I.T. makes no representations about the suitability of
23 * this software for any purpose. It is provided "as is" without express
24 * or implied warranty.
29 * oid_ops.c - GSS-API V2 interfaces to manipulate OIDs
43 generic_gss_release_oid(minor_status, oid)
44 OM_uint32 *minor_status;
49 static int printed = 0;
52 fprintf(stderr, "gss_generic_release_oid (glue):\n"
53 " GSS_C_NT_USER_NAME %p\n"
54 " GSS_C_NT_MACHINE_UID_NAME %p\n"
55 " GSS_C_NT_STRING_UID_NAME %p\n"
56 " GSS_C_NT_HOSTBASED_SERVICE %p\n"
57 " GSS_C_NT_ANONYMOUS %p\n"
58 " GSS_C_NT_EXPORT_NAME %p\n",
59 GSS_C_NT_USER_NAME, GSS_C_NT_MACHINE_UID_NAME,
60 GSS_C_NT_STRING_UID_NAME, GSS_C_NT_HOSTBASED_SERVICE,
61 GSS_C_NT_ANONYMOUS, GSS_C_NT_EXPORT_NAME);
64 if (*oid == GSS_C_NO_OID)
65 return(GSS_S_COMPLETE);
68 * The V2 API says the following!
70 * gss_release_oid[()] will recognize any of the GSSAPI's own OID values,
71 * and will silently ignore attempts to free these OIDs; for other OIDs
72 * it will call the C free() routine for both the OID data and the
73 * descriptor. This allows applications to freely mix their own heap-
74 * allocated OID values with OIDs returned by GSS-API.
76 if ((*oid != GSS_C_NT_USER_NAME) &&
77 (*oid != GSS_C_NT_MACHINE_UID_NAME) &&
78 (*oid != GSS_C_NT_STRING_UID_NAME) &&
79 (*oid != GSS_C_NT_HOSTBASED_SERVICE) &&
80 (*oid != GSS_C_NT_ANONYMOUS) &&
81 (*oid != GSS_C_NT_EXPORT_NAME)) {
83 fprintf(stderr, "generic_gss_release_oid (glue): freeing *oid at %p\n",
86 free((*oid)->elements);
90 return(GSS_S_COMPLETE);
94 mech_gss_release_oid(minor_status, oid, gss_mech)
95 OM_uint32 *minor_status;
97 gss_mechanism gss_mech;
102 fprintf(stderr, "mech_gss_release_oid: *oid %p, gss_mech %p\n",
105 if (*oid == GSS_C_NO_OID)
106 return (GSS_S_COMPLETE);
108 if (gss_mech == NULL) {
110 fprintf(stderr, "mech_gss_release_oid: no gss_mech!\n");
112 return (generic_gss_release_oid(minor_status, oid));
115 if (!gss_mech->gss_internal_release_oid) {
117 fprintf(stderr, "mech_gss_release_oid: mechanism has "
118 "no gss_internal_release_oid function! using "
119 "generic_gss_release_oid\n");
121 return (generic_gss_release_oid(minor_status, oid));
125 fprintf(stderr, "mech_gss_release_oid: calling mechanism's "
126 "gss_internal_release_oid\n");
128 return (gss_mech->gss_internal_release_oid(minor_status, oid));
132 generic_gss_copy_oid(minor_status, oid, new_oid)
133 OM_uint32 *minor_status;
134 gss_OID oid, *new_oid;
138 if (oid == GSS_C_NO_OID) {
139 *new_oid = GSS_C_NO_OID;
140 return (GSS_S_COMPLETE);
143 p = (gss_OID) malloc(sizeof(gss_OID_desc));
145 *minor_status = ENOMEM;
146 return GSS_S_FAILURE;
148 p->length = oid->length;
149 p->elements = malloc(p->length);
152 *minor_status = ENOMEM;
153 return GSS_S_FAILURE;
155 memcpy(p->elements, oid->elements, p->length);
157 return (GSS_S_COMPLETE);
162 generic_gss_create_empty_oid_set(minor_status, oid_set)
163 OM_uint32 *minor_status;
164 gss_OID_set *oid_set;
166 if ((*oid_set = (gss_OID_set) malloc(sizeof(gss_OID_set_desc)))) {
167 memset(*oid_set, 0, sizeof(gss_OID_set_desc));
169 return(GSS_S_COMPLETE);
172 *minor_status = ENOMEM;
173 return(GSS_S_FAILURE);
178 generic_gss_add_oid_set_member(minor_status, member_oid, oid_set)
179 OM_uint32 *minor_status;
181 gss_OID_set *oid_set;
186 elist = (*oid_set)->elements;
187 /* Get an enlarged copy of the array */
188 if (((*oid_set)->elements = (gss_OID) malloc(((*oid_set)->count+1) *
189 sizeof(gss_OID_desc)))) {
190 /* Copy in the old junk */
192 memcpy((*oid_set)->elements,
194 ((*oid_set)->count * sizeof(gss_OID_desc)));
196 /* Duplicate the input element */
197 lastel = &(*oid_set)->elements[(*oid_set)->count];
198 if ((lastel->elements =
199 (void *) malloc((size_t) member_oid->length))) {
200 /* Success - copy elements */
201 memcpy(lastel->elements, member_oid->elements,
202 (size_t) member_oid->length);
204 lastel->length = member_oid->length;
211 return(GSS_S_COMPLETE);
214 free((*oid_set)->elements);
216 /* Failure - restore old contents of list */
217 (*oid_set)->elements = elist;
218 *minor_status = ENOMEM;
219 return(GSS_S_FAILURE);
223 generic_gss_test_oid_set_member(minor_status, member, set, present)
224 OM_uint32 *minor_status;
233 for (i=0; i<set->count; i++) {
234 if ((set->elements[i].length == member->length) &&
235 !memcmp(set->elements[i].elements,
237 (size_t) member->length)) {
244 return(GSS_S_COMPLETE);
248 * OID<->string routines. These are uuuuugly.
251 generic_gss_oid_to_str(minor_status, oid, oid_str)
252 OM_uint32 *minor_status;
254 gss_buffer_t oid_str;
257 unsigned long number;
259 size_t string_length;
264 /* Decoded according to krb5/gssapi_krb5.c */
266 /* First determine the size of the string */
270 cp = (unsigned char *) oid->elements;
271 number = (unsigned long) cp[0];
272 sprintf(numstr, "%ld ", number/40);
273 string_length += strlen(numstr);
274 sprintf(numstr, "%ld ", number%40);
275 string_length += strlen(numstr);
276 for (i=1; i<oid->length; i++) {
277 if ( (size_t) (numshift+7) < (sizeof(unsigned long)*8)) {
278 number = (number << 7) | (cp[i] & 0x7f);
282 *minor_status = EINVAL;
283 return(GSS_S_FAILURE);
285 if ((cp[i] & 0x80) == 0) {
286 sprintf(numstr, "%ld ", number);
287 string_length += strlen(numstr);
293 * If we get here, we've calculated the length of "n n n ... n ". Add 4
294 * here for "{ " and "}\0".
297 if ((bp = (char *) malloc(string_length))) {
299 number = (unsigned long) cp[0];
300 sprintf(numstr, "%ld ", number/40);
302 sprintf(numstr, "%ld ", number%40);
305 cp = (unsigned char *) oid->elements;
306 for (i=1; i<oid->length; i++) {
307 number = (number << 7) | (cp[i] & 0x7f);
308 if ((cp[i] & 0x80) == 0) {
309 sprintf(numstr, "%ld ", number);
315 oid_str->length = strlen(bp)+1;
316 oid_str->value = (void *) bp;
318 return(GSS_S_COMPLETE);
320 *minor_status = ENOMEM;
321 return(GSS_S_FAILURE);
325 generic_gss_str_to_oid(minor_status, oid_str, oid)
326 OM_uint32 *minor_status;
327 gss_buffer_t oid_str;
330 char *cp, *bp, *startp;
339 bp = (char *) oid_str->value;
341 /* Skip over leading space */
342 while ((bp < &cp[oid_str->length]) && isspace(*bp))
348 while ((bp < &cp[oid_str->length]) && isspace(*bp))
354 * The first two numbers are chewed up by the first octet.
356 if (sscanf(bp, "%ld", &numbuf) != 1) {
357 *minor_status = EINVAL;
358 return(GSS_S_FAILURE);
360 while ((bp < &cp[oid_str->length]) && isdigit(*bp))
362 while ((bp < &cp[oid_str->length]) && isspace(*bp))
364 if (sscanf(bp, "%ld", &numbuf) != 1) {
365 *minor_status = EINVAL;
366 return(GSS_S_FAILURE);
368 while ((bp < &cp[oid_str->length]) && isdigit(*bp))
370 while ((bp < &cp[oid_str->length]) && isspace(*bp))
373 while (isdigit(*bp)) {
374 if (sscanf(bp, "%ld", &numbuf) != 1) {
375 *minor_status = EINVAL;
376 return(GSS_S_FAILURE);
382 while ((bp < &cp[oid_str->length]) && isdigit(*bp))
384 while ((bp < &cp[oid_str->length]) && isspace(*bp))
387 if (brace && (*bp != '}')) {
388 *minor_status = EINVAL;
389 return(GSS_S_FAILURE);
393 * Phew! We've come this far, so the syntax is good.
395 if ((*oid = (gss_OID) malloc(sizeof(gss_OID_desc)))) {
396 if (((*oid)->elements = (void *) malloc((size_t) nbytes))) {
397 (*oid)->length = nbytes;
398 op = (unsigned char *) (*oid)->elements;
400 sscanf(bp, "%ld", &numbuf);
406 sscanf(bp, "%ld", &numbuf);
408 *op = (unsigned char) onumbuf;
414 while (isdigit(*bp)) {
415 sscanf(bp, "%ld", &numbuf);
417 /* Have to fill in the bytes msb-first */
427 op[index] = (unsigned char) numbuf & 0x7f;
439 return(GSS_S_COMPLETE);
446 *minor_status = ENOMEM;
447 return(GSS_S_FAILURE);