1 /*
2 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
4 */
5
6 #pragma ident "@(#)oid_ops.c 1.20 04/09/08 SMI"
7
8 /*
9 * lib/gssapi/generic/oid_ops.c
10 *
11 * Copyright 1995 by the Massachusetts Institute of Technology.
12 * All Rights Reserved.
13 *
14 * Export of this software from the United States of America may
15 * require a specific license from the United States Government.
16 * It is the responsibility of any person or organization contemplating
17 * export to obtain such a license before exporting.
18 *
19 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
20 * distribute this software and its documentation for any purpose and
21 * without fee is hereby granted, provided that the above copyright
22 * notice appear in all copies and that both that copyright notice and
23 * this permission notice appear in supporting documentation, and that
24 * the name of M.I.T. not be used in advertising or publicity pertaining
25 * to distribution of the software without specific, written prior
26 * permission. M.I.T. makes no representations about the suitability of
38 #include <unistd.h>
39 #endif
40 #include <stdlib.h>
41 #include <string.h>
42 #include <stdio.h>
43 #include <errno.h>
44 #include <ctype.h>
45
46 /*
47 * this oid is defined in the oid structure but not exported to
48 * external callers; we must still ensure that we do not delete it.
49 */
50 extern const gss_OID_desc * const gss_nt_service_name;
51
52
53 OM_uint32
54 generic_gss_release_oid(minor_status, oid)
55 OM_uint32 *minor_status;
56 gss_OID *oid;
57 {
58 *minor_status = 0;
59
60 if (*oid == GSS_C_NO_OID)
61 return (GSS_S_COMPLETE);
62
63 /*
64 * The V2 API says the following!
65 *
66 * gss_release_oid[()] will recognize any of the GSSAPI's own OID
67 * values, and will silently ignore attempts to free these OIDs;
68 * for other OIDs it will call the C free() routine for both the OID
69 * data and the descriptor. This allows applications to freely mix
70 * their own heap allocated OID values with OIDs returned by GSS-API.
71 */
72
73 if ((*oid != gss_nt_user_name) &&
74 (*oid != gss_nt_machine_uid_name) &&
75 (*oid != gss_nt_string_uid_name) &&
76 (*oid != gss_nt_service_name) &&
77 (*oid != gss_nt_exported_name) &&
78 (*oid != gss_nt_service_name_v2)) {
79 free((*oid)->elements);
80 free(*oid);
81 }
82 *oid = GSS_C_NO_OID;
83 return (GSS_S_COMPLETE);
84 }
85
86 OM_uint32
87 generic_gss_copy_oid(minor_status, oid, new_oid)
88 OM_uint32 *minor_status;
89 const gss_OID oid;
90 gss_OID *new_oid;
91 {
92 gss_OID p;
93
94 p = (gss_OID) malloc(sizeof (gss_OID_desc));
95 if (!p) {
96 *minor_status = ENOMEM;
97 return (GSS_S_FAILURE);
98 }
99 p->length = oid->length;
100 p->elements = malloc(p->length);
101 if (!p->elements) {
102 free(p);
103 *minor_status = ENOMEM;
104 return (GSS_S_FAILURE);
105 }
106 (void) memcpy(p->elements, oid->elements, p->length);
107 *new_oid = p;
108 return (GSS_S_COMPLETE);
109 }
110
111
112 OM_uint32
113 generic_gss_create_empty_oid_set(minor_status, oid_set)
114 OM_uint32 *minor_status;
115 gss_OID_set *oid_set;
116 {
117 if ((*oid_set = (gss_OID_set) malloc(sizeof (gss_OID_set_desc)))) {
118 (void) memset(*oid_set, 0, sizeof (gss_OID_set_desc));
119 *minor_status = 0;
120 return (GSS_S_COMPLETE);
121 } else {
122 *minor_status = ENOMEM;
123 return (GSS_S_FAILURE);
124 }
125 }
126
127 OM_uint32
128 generic_gss_add_oid_set_member(minor_status, member_oid, oid_set)
129 OM_uint32 *minor_status;
130 const gss_OID member_oid;
131 gss_OID_set *oid_set;
132 {
133 gss_OID elist;
134 gss_OID lastel;
135
136 elist = (*oid_set)->elements;
137 /* Get an enlarged copy of the array */
138 if (((*oid_set)->elements = (gss_OID) malloc(((*oid_set)->count+1) *
139 sizeof (gss_OID_desc)))) {
140 /* Copy in the old junk */
141 if (elist)
142 (void) memcpy((*oid_set)->elements, elist,
143 ((*oid_set)->count * sizeof (gss_OID_desc)));
144
145 /* Duplicate the input element */
146 lastel = &(*oid_set)->elements[(*oid_set)->count];
147 if ((lastel->elements =
148 (void *) malloc(member_oid->length))) {
149 /* Success - copy elements */
150 (void) memcpy(lastel->elements, member_oid->elements,
151 member_oid->length);
152 /* Set length */
153 lastel->length = member_oid->length;
154
155 /* Update count */
156 (*oid_set)->count++;
157 if (elist)
158 free(elist);
159 return (GSS_S_COMPLETE);
160 } else
161 free((*oid_set)->elements);
162 }
163 /* Failure - restore old contents of list */
164 (*oid_set)->elements = elist;
165 *minor_status = ENOMEM;
166 return (GSS_S_FAILURE);
167 }
168
169 OM_uint32
170 generic_gss_test_oid_set_member(minor_status, member, set, present)
171 OM_uint32 *minor_status;
172 const gss_OID member;
173 const gss_OID_set set;
174 int *present;
175 {
176 size_t i;
177 int result;
178
179 result = 0;
180 for (i = 0; i < set->count; i++) {
181 if ((set->elements[i].length == member->length) &&
182 !memcmp(set->elements[i].elements,
183 member->elements, member->length)) {
184 result = 1;
185 break;
186 }
187 }
188 *present = result;
189 *minor_status = 0;
190 return (GSS_S_COMPLETE);
191 }
192
193 /*
194 * OID<->string routines. These are uuuuugly.
195 */
196 OM_uint32
197 generic_gss_oid_to_str(minor_status, oid, oid_str)
198 OM_uint32 *minor_status;
199 const gss_OID oid;
200 gss_buffer_t oid_str;
201 {
202 char numstr[128];
203 unsigned long number;
204 int numshift;
205 size_t string_length;
206 size_t i;
207 unsigned char *cp;
208 char *bp;
209
210 /* Decoded according to krb5/gssapi_krb5.c */
211
212 /* First determine the size of the string */
213 string_length = 0;
214 number = 0;
215 numshift = 0;
216 cp = (unsigned char *) oid->elements;
217 number = (OM_uint32) cp[0];
218 (void) sprintf(numstr, "%d ", number/40);
219 string_length += strlen(numstr);
220 (void) sprintf(numstr, "%d ", number%40);
221 string_length += strlen(numstr);
222 for (i = 1; i < oid->length; i++) {
223 if ((size_t) (numshift+7) < (sizeof (unsigned long)*8)) {
224 number = (number << 7) | (cp[i] & 0x7f);
225 numshift += 7;
226 } else {
227 *minor_status = EINVAL;
228 return (GSS_S_FAILURE);
229 }
230
231 if ((cp[i] & 0x80) == 0) {
232 (void) sprintf(numstr, "%d ", number);
233 string_length += strlen(numstr);
234 number = 0;
235 numshift = 0;
236 }
237 }
238 /*
239 * If we get here, we've calculated the length of "n n n ... n ". Add 4
240 * here for "{ " and "}\0".
241 */
242 string_length += 4;
243 if ((bp = (char *)malloc(string_length))) {
244 (void) strcpy(bp, "{ ");
245 number = (unsigned long) cp[0];
246 (void) sprintf(numstr, "%d ", number/40);
247 (void) strcat(bp, numstr);
248 (void) sprintf(numstr, "%d ", number%40);
249 (void) strcat(bp, numstr);
250 number = 0;
251 cp = (unsigned char *) oid->elements;
252 for (i = 1; i < oid->length; i++) {
253 number = (number << 7) | (cp[i] & 0x7f);
254 if ((cp[i] & 0x80) == 0) {
255 (void) sprintf(numstr, "%d ", number);
256 (void) strcat(bp, numstr);
257 number = 0;
258 }
259 }
260 (void) strcat(bp, "}");
261 oid_str->length = strlen(bp)+1;
262 oid_str->value = (void *) bp;
263 *minor_status = 0;
264 return (GSS_S_COMPLETE);
265 }
266 *minor_status = ENOMEM;
267 return (GSS_S_FAILURE);
268 }
269
270 /*
271 * This routine will handle 2 types of oid string formats:
272 * 1 - { 1 2 3 4 } where the braces are optional
273 * 2 - 1.2.3.4 this is an alernative format
274 * The first format is mandated by the gss spec. The
275 * second format is popular outside of the gss community so
276 * has been added.
277 */
278 OM_uint32
279 generic_gss_str_to_oid(minor_status, oid_str, oid)
280 OM_uint32 *minor_status;
281 const gss_buffer_t oid_str;
282 gss_OID *oid;
283 {
284 char *cp, *bp, *startp;
285 int brace;
286 int numbuf;
287 int onumbuf;
288 OM_uint32 nbytes;
289 int idx;
290 unsigned char *op;
291
292 brace = 0;
293 bp = (char *)oid_str->value;
294 cp = bp;
295 /* Skip over leading space */
296 while ((bp < &cp[oid_str->length]) && isspace(*bp))
297 bp++;
298 if (*bp == '{') {
299 brace = 1;
300 bp++;
301 }
302 while ((bp < &cp[oid_str->length]) && isspace(*bp))
303 bp++;
304 startp = bp;
305 nbytes = 0;
306
307 /*
308 * The first two numbers are chewed up by the first octet.
309 */
310 if (sscanf(bp, "%d", &numbuf) != 1) {
311 *minor_status = EINVAL;
312 return (GSS_S_FAILURE);
313 }
314 while ((bp < &cp[oid_str->length]) && isdigit(*bp))
315 bp++;
316 while ((bp < &cp[oid_str->length]) &&
317 (isspace(*bp) || *bp == '.'))
318 bp++;
319 if (sscanf(bp, "%d", &numbuf) != 1) {
320 *minor_status = EINVAL;
321 return (GSS_S_FAILURE);
322 }
323 while ((bp < &cp[oid_str->length]) && isdigit((int) *bp))
324 bp++;
325 while ((bp < &cp[oid_str->length]) && isspace((int) *bp)
326 bp++;
327 nbytes++;
328 while (isdigit((int) *bp)) {
329 if (sscanf(bp, "%ld", &numbuf) != 1) {
330 *minor_status = EINVAL;
331 return (GSS_S_FAILURE);
332 }
333 while (numbuf) {
334 nbytes++;
335 numbuf >>= 7;
336 }
337 while ((bp < &cp[oid_str->length]) && isdigit((int) *bp))
338 bp++;
339 while ((bp < &cp[oid_str->length]) && isspace((int) *bp))
340 bp++;
341 }
342 if (brace && (*bp != '}')) {
343 *minor_status = EINVAL;
344 return (GSS_S_FAILURE);
345 }
346
347 /*
348 * Phew! We've come this far, so the syntax is good.
349 */
350 if ((*oid = (gss_OID) malloc(sizeof (gss_OID_desc)))) {
351 if (((*oid)->elements = (void *) malloc((size_t) nbytes))) {
352 (*oid)->length = nbytes;
353 op = (unsigned char *) (*oid)->elements;
354 bp = startp;
355 (void) sscanf(bp, "%ld", &numbuf);
356 while (isdigit((int) *bp))
357 bp++;
358 while (isspace((int) *bp) || *bp == '.')
359 bp++;
360 onumbuf = 40*numbuf;
361 (void) sscanf(bp, "%ld", &numbuf);
362 onumbuf += numbuf;
363 *op = (unsigned char) onumbuf;
364 op++;
365 while (isdigit((int) *bp))
366 bp++;
367 while (isspace((int) *bp))
368 bp++;
369 while (isdigit((int) *bp)) {
370 (void) sscanf(bp, "%ld", &numbuf);
371 nbytes = 0;
372 /* Have to fill in the bytes msb-first */
373 onumbuf = numbuf;
374 while (numbuf) {
375 nbytes++;
376 numbuf >>= 7;
377 }
378 numbuf = onumbuf;
379 op += nbytes;
380 index = -1;
381 while (numbuf) {
382 op[index] = (unsigned char)
383 numbuf & 0x7f;
384 if (index != -1)
385 op[index] |= 0x80;
386 index--;
387 numbuf >>= 7;
388 }
389 while (isdigit((int) *bp))
390 bp++;
391 while (isspace((int) *bp))
392 bp++;
393 }
394 *minor_status = 0;
395 return (GSS_S_COMPLETE);
396 } else {
397 free(*oid);
398 *oid = GSS_C_NO_OID;
399 }
400 }
401 *minor_status = ENOMEM;
402 return (GSS_S_FAILURE);
403 }
404
|
1 /*
2 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
4 */
5
6 #pragma ident "@(#)oid_ops.c 1.19 04/02/23 SMI"
7
8 /*
9 * lib/gssapi/generic/oid_ops.c
10 *
11 * Copyright 1995 by the Massachusetts Institute of Technology.
12 * All Rights Reserved.
13 *
14 * Export of this software from the United States of America may
15 * require a specific license from the United States Government.
16 * It is the responsibility of any person or organization contemplating
17 * export to obtain such a license before exporting.
18 *
19 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
20 * distribute this software and its documentation for any purpose and
21 * without fee is hereby granted, provided that the above copyright
22 * notice appear in all copies and that both that copyright notice and
23 * this permission notice appear in supporting documentation, and that
24 * the name of M.I.T. not be used in advertising or publicity pertaining
25 * to distribution of the software without specific, written prior
26 * permission. M.I.T. makes no representations about the suitability of
38 #include <unistd.h>
39 #endif
40 #include <stdlib.h>
41 #include <string.h>
42 #include <stdio.h>
43 #include <errno.h>
44 #include <ctype.h>
45
46 /*
47 * this oid is defined in the oid structure but not exported to
48 * external callers; we must still ensure that we do not delete it.
49 */
50 extern const gss_OID_desc * const gss_nt_service_name;
51
52
53 OM_uint32
54 generic_gss_release_oid(minor_status, oid)
55 OM_uint32 *minor_status;
56 gss_OID *oid;
57 {
58 if (minor_status)
59 *minor_status = 0;
60
61 if (*oid == GSS_C_NO_OID)
62 return (GSS_S_COMPLETE);
63
64 /*
65 * The V2 API says the following!
66 *
67 * gss_release_oid[()] will recognize any of the GSSAPI's own OID
68 * values, and will silently ignore attempts to free these OIDs;
69 * for other OIDs it will call the C free() routine for both the OID
70 * data and the descriptor. This allows applications to freely mix
71 * their own heap allocated OID values with OIDs returned by GSS-API.
72 */
73
74 /*
75 * We use the official OID definitions instead of the unofficial OID
76 * defintions. But we continue to support the unofficial OID
77 * gss_nt_service_name just in case if some gss applications use
78 * the old OID.
79 */
80
81 if ((*oid != GSS_C_NT_USER_NAME) &&
82 (*oid != GSS_C_NT_MACHINE_UID_NAME) &&
83 (*oid != GSS_C_NT_STRING_UID_NAME) &&
84 (*oid != GSS_C_NT_HOSTBASED_SERVICE) &&
85 (*oid != GSS_C_NT_ANONYMOUS) &&
86 (*oid != GSS_C_NT_EXPORT_NAME) &&
87 (*oid != gss_nt_service_name)) {
88 free((*oid)->elements);
89 free(*oid);
90 }
91 *oid = GSS_C_NO_OID;
92 return (GSS_S_COMPLETE);
93 }
94
95 OM_uint32
96 generic_gss_copy_oid(minor_status, oid, new_oid)
97 OM_uint32 *minor_status;
98 const gss_OID oid;
99 gss_OID *new_oid;
100 {
101 gss_OID p;
102
103 if (minor_status)
104 *minor_status = 0;
105
106 p = (gss_OID) malloc(sizeof (gss_OID_desc));
107 if (!p) {
108 return (GSS_S_FAILURE);
109 }
110 p->length = oid->length;
111 p->elements = malloc(p->length);
112 if (!p->elements) {
113 free(p);
114 return (GSS_S_FAILURE);
115 }
116 (void) memcpy(p->elements, oid->elements, p->length);
117 *new_oid = p;
118 return (GSS_S_COMPLETE);
119 }
120
121
122 OM_uint32
123 generic_gss_create_empty_oid_set(minor_status, oid_set)
124 OM_uint32 *minor_status;
125 gss_OID_set *oid_set;
126 {
127 if (minor_status)
128 *minor_status = 0;
129
130 if ((*oid_set = (gss_OID_set) malloc(sizeof (gss_OID_set_desc)))) {
131 (void) memset(*oid_set, 0, sizeof (gss_OID_set_desc));
132 return (GSS_S_COMPLETE);
133 } else {
134 return (GSS_S_FAILURE);
135 }
136 }
137
138 OM_uint32
139 generic_gss_add_oid_set_member(minor_status, member_oid, oid_set)
140 OM_uint32 *minor_status;
141 const gss_OID member_oid;
142 gss_OID_set *oid_set;
143 {
144 gss_OID elist;
145 gss_OID lastel;
146
147 if (minor_status)
148 *minor_status = 0;
149
150 if (member_oid == NULL || member_oid->length == 0 ||
151 member_oid->elements == NULL)
152 return (GSS_S_CALL_INACCESSIBLE_READ);
153
154 elist = (*oid_set)->elements;
155 /* Get an enlarged copy of the array */
156 if (((*oid_set)->elements = (gss_OID) malloc(((*oid_set)->count+1) *
157 sizeof (gss_OID_desc)))) {
158 /* Copy in the old junk */
159 if (elist)
160 (void) memcpy((*oid_set)->elements, elist,
161 ((*oid_set)->count * sizeof (gss_OID_desc)));
162
163 /* Duplicate the input element */
164 lastel = &(*oid_set)->elements[(*oid_set)->count];
165 if ((lastel->elements =
166 (void *) malloc(member_oid->length))) {
167 /* Success - copy elements */
168 (void) memcpy(lastel->elements, member_oid->elements,
169 member_oid->length);
170 /* Set length */
171 lastel->length = member_oid->length;
172
173 /* Update count */
174 (*oid_set)->count++;
175 if (elist)
176 free(elist);
177 return (GSS_S_COMPLETE);
178 } else
179 free((*oid_set)->elements);
180 }
181 /* Failure - restore old contents of list */
182 (*oid_set)->elements = elist;
183 return (GSS_S_FAILURE);
184 }
185
186 OM_uint32
187 generic_gss_test_oid_set_member(minor_status, member, set, present)
188 OM_uint32 *minor_status;
189 const gss_OID member;
190 const gss_OID_set set;
191 int *present;
192 {
193 OM_uint32 i;
194 int result;
195
196 if (minor_status)
197 *minor_status = 0;
198
199 if (member == NULL || set == NULL)
200 return (GSS_S_CALL_INACCESSIBLE_READ);
201
202 if (present == NULL)
203 return (GSS_S_CALL_INACCESSIBLE_WRITE);
204
205 result = 0;
206 for (i = 0; i < set->count; i++) {
207 if ((set->elements[i].length == member->length) &&
208 !memcmp(set->elements[i].elements,
209 member->elements, member->length)) {
210 result = 1;
211 break;
212 }
213 }
214 *present = result;
215 return (GSS_S_COMPLETE);
216 }
217
218 /*
219 * OID<->string routines. These are uuuuugly.
220 */
221 OM_uint32
222 generic_gss_oid_to_str(minor_status, oid, oid_str)
223 OM_uint32 *minor_status;
224 const gss_OID oid;
225 gss_buffer_t oid_str;
226 {
227 char numstr[128];
228 OM_uint32 number;
229 int numshift;
230 OM_uint32 string_length;
231 OM_uint32 i;
232 unsigned char *cp;
233 char *bp;
234
235 if (minor_status)
236 *minor_status = 0;
237
238 if (oid == NULL || oid->length == 0 || oid->elements == NULL)
239 return (GSS_S_CALL_INACCESSIBLE_READ);
240
241 if (oid_str == NULL)
242 return (GSS_S_CALL_INACCESSIBLE_WRITE);
243
244 /* Decoded according to krb5/gssapi_krb5.c */
245
246 /* First determine the size of the string */
247 string_length = 0;
248 number = 0;
249 numshift = 0;
250 cp = (unsigned char *) oid->elements;
251 number = (OM_uint32) cp[0];
252 (void) sprintf(numstr, "%d ", number/40);
253 string_length += strlen(numstr);
254 (void) sprintf(numstr, "%d ", number%40);
255 string_length += strlen(numstr);
256 for (i = 1; i < oid->length; i++) {
257 if ((OM_uint32) (numshift+7) < (sizeof (OM_uint32)*8)) {
258 number = (number << 7) | (cp[i] & 0x7f);
259 numshift += 7;
260 } else {
261 return (GSS_S_FAILURE);
262 }
263
264 if ((cp[i] & 0x80) == 0) {
265 (void) sprintf(numstr, "%d ", number);
266 string_length += strlen(numstr);
267 number = 0;
268 numshift = 0;
269 }
270 }
271 /*
272 * If we get here, we've calculated the length of "n n n ... n ". Add 4
273 * here for "{ " and "}\0".
274 */
275 string_length += 4;
276 if ((bp = (char *)malloc(string_length))) {
277 (void) strcpy(bp, "{ ");
278 number = (OM_uint32) cp[0];
279 (void) sprintf(numstr, "%d ", number/40);
280 (void) strcat(bp, numstr);
281 (void) sprintf(numstr, "%d ", number%40);
282 (void) strcat(bp, numstr);
283 number = 0;
284 cp = (unsigned char *) oid->elements;
285 for (i = 1; i < oid->length; i++) {
286 number = (number << 7) | (cp[i] & 0x7f);
287 if ((cp[i] & 0x80) == 0) {
288 (void) sprintf(numstr, "%d ", number);
289 (void) strcat(bp, numstr);
290 number = 0;
291 }
292 }
293 (void) strcat(bp, "}");
294 oid_str->length = strlen(bp)+1;
295 oid_str->value = (void *) bp;
296 return (GSS_S_COMPLETE);
297 }
298 return (GSS_S_FAILURE);
299 }
300
301 /*
302 * This routine will handle 2 types of oid string formats:
303 * 1 - { 1 2 3 4 } where the braces are optional
304 * 2 - 1.2.3.4 this is an alernative format
305 * The first format is mandated by the gss spec. The
306 * second format is popular outside of the gss community so
307 * has been added.
308 */
309 OM_uint32
310 generic_gss_str_to_oid(minor_status, oid_str, oid)
311 OM_uint32 *minor_status;
312 const gss_buffer_t oid_str;
313 gss_OID *oid;
314 {
315 char *cp, *bp, *startp;
316 int brace;
317 int numbuf;
318 int onumbuf;
319 OM_uint32 nbytes;
320 int index;
321 unsigned char *op;
322
323 if (minor_status)
324 *minor_status = 0;
325
326 if (GSS_EMPTY_BUFFER(oid_str))
327 return (GSS_S_CALL_INACCESSIBLE_READ);
328
329 if (oid == NULL)
330 return (GSS_S_CALL_INACCESSIBLE_WRITE);
331
332 brace = 0;
333 bp = (char *)oid_str->value;
334 cp = bp;
335 /* Skip over leading space */
336 while ((bp < &cp[oid_str->length]) && isspace(*bp))
337 bp++;
338 if (*bp == '{') {
339 brace = 1;
340 bp++;
341 }
342 while ((bp < &cp[oid_str->length]) && isspace(*bp))
343 bp++;
344 startp = bp;
345 nbytes = 0;
346
347 /*
348 * The first two numbers are chewed up by the first octet.
349 */
350 if (sscanf(bp, "%d", &numbuf) != 1) {
351 return (GSS_S_FAILURE);
352 }
353 while ((bp < &cp[oid_str->length]) && isdigit(*bp))
354 bp++;
355 while ((bp < &cp[oid_str->length]) &&
356 (isspace(*bp) || *bp == '.'))
357 bp++;
358 if (sscanf(bp, "%d", &numbuf) != 1) {
359 return (GSS_S_FAILURE);
360 }
361 while ((bp < &cp[oid_str->length]) && isdigit(*bp))
362 bp++;
363 while ((bp < &cp[oid_str->length]) &&
364 (isspace(*bp) || *bp == '.'))
365 bp++;
366 nbytes++;
367 while (isdigit(*bp)) {
368 if (sscanf(bp, "%d", &numbuf) != 1) {
369 return (GSS_S_FAILURE);
370 }
371 while (numbuf) {
372 nbytes++;
373 numbuf >>= 7;
374 }
375 while ((bp < &cp[oid_str->length]) && isdigit(*bp))
376 bp++;
377 while ((bp < &cp[oid_str->length]) &&
378 (isspace(*bp) || *bp == '.'))
379 bp++;
380 }
381 if (brace && (*bp != '}')) {
382 return (GSS_S_FAILURE);
383 }
384
385 /*
386 * Phew! We've come this far, so the syntax is good.
387 */
388 if ((*oid = (gss_OID) malloc(sizeof (gss_OID_desc)))) {
389 if (((*oid)->elements = (void *) malloc(nbytes))) {
390 (*oid)->length = nbytes;
391 op = (unsigned char *) (*oid)->elements;
392 bp = startp;
393 (void) sscanf(bp, "%d", &numbuf);
394 while (isdigit(*bp))
395 bp++;
396 while (isspace(*bp) || *bp == '.')
397 bp++;
398 onumbuf = 40*numbuf;
399 (void) sscanf(bp, "%d", &numbuf);
400 onumbuf += numbuf;
401 *op = (unsigned char) onumbuf;
402 op++;
403 while (isdigit(*bp))
404 bp++;
405 while (isspace(*bp) || *bp == '.')
406 bp++;
407 while (isdigit(*bp)) {
408 (void) sscanf(bp, "%d", &numbuf);
409 nbytes = 0;
410 /* Have to fill in the bytes msb-first */
411 onumbuf = numbuf;
412 while (numbuf) {
413 nbytes++;
414 numbuf >>= 7;
415 }
416 numbuf = onumbuf;
417 op += nbytes;
418 index = -1;
419 while (numbuf) {
420 op[index] = (unsigned char)
421 numbuf & 0x7f;
422 if (index != -1)
423 op[index] |= 0x80;
424 index--;
425 numbuf >>= 7;
426 }
427 while (isdigit(*bp))
428 bp++;
429 while (isspace(*bp) || *bp == '.')
430 bp++;
431 }
432 return (GSS_S_COMPLETE);
433 } else {
434 free(*oid);
435 *oid = GSS_C_NO_OID;
436 }
437 }
438 return (GSS_S_FAILURE);
439 }
440
441 /*
442 * Copyright 1993 by OpenVision Technologies, Inc.
443 *
444 * Permission to use, copy, modify, distribute, and sell this software
445 * and its documentation for any purpose is hereby granted without fee,
446 * provided that the above copyright notice appears in all copies and
447 * that both that copyright notice and this permission notice appear in
448 * supporting documentation, and that the name of OpenVision not be used
449 * in advertising or publicity pertaining to distribution of the software
450 * without specific, written prior permission. OpenVision makes no
451 * representations about the suitability of this software for any
452 * purpose. It is provided "as is" without express or implied warranty.
453 *
454 * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
455 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
456 * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
457 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
458 * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
459 * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
460 * PERFORMANCE OF THIS SOFTWARE.
461 */
462 OM_uint32
463 gss_copy_oid_set(
464 OM_uint32 *minor_status,
465 const gss_OID_set_desc * const oidset,
466 gss_OID_set *new_oidset
467 )
468 {
469 gss_OID_set_desc *copy;
470 OM_uint32 minor = 0;
471 OM_uint32 major = GSS_S_COMPLETE;
472 OM_uint32 index;
473
474 if (minor_status)
475 *minor_status = 0;
476
477 if (oidset == NULL)
478 return (GSS_S_CALL_INACCESSIBLE_READ);
479
480 if (new_oidset == NULL)
481 return (GSS_S_CALL_INACCESSIBLE_WRITE);
482
483 *new_oidset = NULL;
484
485 if ((copy = (gss_OID_set_desc *) calloc(1, sizeof (*copy))) == NULL) {
486 major = GSS_S_FAILURE;
487 goto done;
488 }
489
490 if ((copy->elements = (gss_OID_desc *)
491 calloc(oidset->count, sizeof (*copy->elements))) == NULL) {
492 major = GSS_S_FAILURE;
493 goto done;
494 }
495 copy->count = oidset->count;
496
497 for (index = 0; index < copy->count; index++) {
498 gss_OID_desc *out = ©->elements[index];
499 gss_OID_desc *in = &oidset->elements[index];
500
501 if ((out->elements = (void *) malloc(in->length)) == NULL) {
502 major = GSS_S_FAILURE;
503 goto done;
504 }
505 (void) memcpy(out->elements, in->elements, in->length);
506 out->length = in->length;
507 }
508
509 *new_oidset = copy;
510 done:
511 if (major != GSS_S_COMPLETE) {
512 (void) gss_release_oid_set(&minor, ©);
513 }
514
515 return (major);
516 }
|