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
39 #include <gssapi_generic.h>
44 generic_gss_release_oid(minor_status
, oid
)
45 OM_uint32
*minor_status
;
51 if (oid
== NULL
|| *oid
== GSS_C_NO_OID
)
52 return(GSS_S_COMPLETE
);
55 * The V2 API says the following!
57 * gss_release_oid[()] will recognize any of the GSSAPI's own OID values,
58 * and will silently ignore attempts to free these OIDs; for other OIDs
59 * it will call the C free() routine for both the OID data and the
60 * descriptor. This allows applications to freely mix their own heap-
61 * allocated OID values with OIDs returned by GSS-API.
65 * We use the official OID definitions instead of the unofficial OID
66 * defintions. But we continue to support the unofficial OID
67 * gss_nt_service_name just in case if some gss applications use
71 if ((*oid
!= GSS_C_NT_USER_NAME
) &&
72 (*oid
!= GSS_C_NT_MACHINE_UID_NAME
) &&
73 (*oid
!= GSS_C_NT_STRING_UID_NAME
) &&
74 (*oid
!= GSS_C_NT_HOSTBASED_SERVICE
) &&
75 (*oid
!= GSS_C_NT_ANONYMOUS
) &&
76 (*oid
!= GSS_C_NT_EXPORT_NAME
) &&
77 (*oid
!= gss_nt_service_name
)) {
78 free((*oid
)->elements
);
82 return(GSS_S_COMPLETE
);
86 generic_gss_copy_oid(minor_status
, oid
, new_oid
)
87 OM_uint32
*minor_status
;
88 gss_OID_desc
* const oid
;
95 p
= (gss_OID
) malloc(sizeof(gss_OID_desc
));
97 *minor_status
= ENOMEM
;
100 p
->length
= oid
->length
;
101 p
->elements
= malloc(p
->length
);
104 return GSS_S_FAILURE
;
106 memcpy(p
->elements
, oid
->elements
, p
->length
);
108 return(GSS_S_COMPLETE
);
113 generic_gss_create_empty_oid_set(minor_status
, oid_set
)
114 OM_uint32
*minor_status
;
115 gss_OID_set
*oid_set
;
119 if ((*oid_set
= (gss_OID_set
) malloc(sizeof(gss_OID_set_desc
)))) {
120 memset(*oid_set
, 0, sizeof(gss_OID_set_desc
));
121 return(GSS_S_COMPLETE
);
124 *minor_status
= ENOMEM
;
125 return(GSS_S_FAILURE
);
130 generic_gss_add_oid_set_member(minor_status
, member_oid
, oid_set
)
131 OM_uint32
*minor_status
;
132 gss_OID_desc
* const member_oid
;
133 gss_OID_set
*oid_set
;
140 if (member_oid
== NULL
|| member_oid
->length
== 0 ||
141 member_oid
->elements
== NULL
)
142 return (GSS_S_CALL_INACCESSIBLE_READ
);
144 elist
= (*oid_set
)->elements
;
145 /* Get an enlarged copy of the array */
146 if (((*oid_set
)->elements
= (gss_OID
) malloc(((*oid_set
)->count
+1) *
147 sizeof(gss_OID_desc
)))) {
148 /* Copy in the old junk */
150 memcpy((*oid_set
)->elements
,
152 ((*oid_set
)->count
* sizeof(gss_OID_desc
)));
154 /* Duplicate the input element */
155 lastel
= &(*oid_set
)->elements
[(*oid_set
)->count
];
156 if ((lastel
->elements
=
157 (void *) malloc((size_t) member_oid
->length
))) {
158 /* Success - copy elements */
159 memcpy(lastel
->elements
, member_oid
->elements
,
160 (size_t) member_oid
->length
);
162 lastel
->length
= member_oid
->length
;
168 return(GSS_S_COMPLETE
);
171 free((*oid_set
)->elements
);
173 /* Failure - restore old contents of list */
174 (*oid_set
)->elements
= elist
;
175 *minor_status
= ENOMEM
;
176 return(GSS_S_FAILURE
);
180 generic_gss_test_oid_set_member(minor_status
, member
, set
, present
)
181 OM_uint32
*minor_status
;
182 gss_OID_desc
* const member
;
191 if (member
== NULL
|| set
== NULL
)
192 return (GSS_S_CALL_INACCESSIBLE_READ
);
195 return (GSS_S_CALL_INACCESSIBLE_WRITE
);
198 for (i
=0; i
<set
->count
; i
++) {
199 if ((set
->elements
[i
].length
== member
->length
) &&
200 !memcmp(set
->elements
[i
].elements
,
202 (size_t) member
->length
)) {
208 return(GSS_S_COMPLETE
);
212 * OID<->string routines. These are uuuuugly.
215 generic_gss_oid_to_str(minor_status
, oid
, oid_str
)
216 OM_uint32
*minor_status
;
217 gss_OID_desc
* const oid
;
218 gss_buffer_t oid_str
;
223 OM_uint32 string_length
;
228 if (minor_status
!= NULL
)
231 if (oid_str
!= GSS_C_NO_BUFFER
) {
233 oid_str
->value
= NULL
;
236 if (oid
== NULL
|| oid
->length
== 0 || oid
->elements
== NULL
)
237 return (GSS_S_CALL_INACCESSIBLE_READ
);
239 if (oid_str
== GSS_C_NO_BUFFER
)
240 return (GSS_S_CALL_INACCESSIBLE_WRITE
);
242 /* Decoded according to krb5/gssapi_krb5.c */
244 /* First determine the size of the string */
248 cp
= (unsigned char *) oid
->elements
;
249 number
= (unsigned long) cp
[0];
250 snprintf(numstr
, sizeof(numstr
), "%lu ", (unsigned long)number
/40);
251 string_length
+= strlen(numstr
);
252 snprintf(numstr
, sizeof(numstr
), "%lu ", (unsigned long)number
%40);
253 string_length
+= strlen(numstr
);
254 for (i
=1; i
<oid
->length
; i
++) {
255 if ((OM_uint32
) (numshift
+7) < (sizeof (OM_uint32
)*8)) {/* XXX */
256 number
= (number
<< 7) | (cp
[i
] & 0x7f);
260 return(GSS_S_FAILURE
);
262 if ((cp
[i
] & 0x80) == 0) {
263 snprintf(numstr
, sizeof(numstr
), "%lu ", (unsigned long)number
);
264 string_length
+= strlen(numstr
);
270 * If we get here, we've calculated the length of "n n n ... n ". Add 4
271 * here for "{ " and "}\0".
274 if ((bp
= (char *) malloc(string_length
))) {
276 number
= (OM_uint32
) cp
[0];
277 snprintf(numstr
, sizeof(numstr
), "%lu ", (unsigned long)number
/40);
279 snprintf(numstr
, sizeof(numstr
), "%lu ", (unsigned long)number
%40);
282 cp
= (unsigned char *) oid
->elements
;
283 for (i
=1; i
<oid
->length
; i
++) {
284 number
= (number
<< 7) | (cp
[i
] & 0x7f);
285 if ((cp
[i
] & 0x80) == 0) {
286 snprintf(numstr
, sizeof(numstr
), "%lu ", (unsigned long)number
);
292 oid_str
->length
= strlen(bp
)+1;
293 oid_str
->value
= (void *) bp
;
294 return(GSS_S_COMPLETE
);
296 *minor_status
= ENOMEM
;
297 return(GSS_S_FAILURE
);
301 generic_gss_str_to_oid(minor_status
, oid_str
, oid
)
302 OM_uint32
*minor_status
;
303 gss_buffer_t oid_str
;
306 unsigned char *cp
, *bp
, *startp
;
314 if (minor_status
!= NULL
)
320 if (GSS_EMPTY_BUFFER(oid_str
))
321 return (GSS_S_CALL_INACCESSIBLE_READ
);
324 return (GSS_S_CALL_INACCESSIBLE_WRITE
);
329 /* Skip over leading space */
330 while ((bp
< &cp
[oid_str
->length
]) && isspace(*bp
))
336 while ((bp
< &cp
[oid_str
->length
]) && isspace(*bp
))
342 * The first two numbers are chewed up by the first octet.
344 if (sscanf((char *)bp
, "%ld", &numbuf
) != 1) {
345 *minor_status
= EINVAL
;
346 return(GSS_S_FAILURE
);
348 while ((bp
< &cp
[oid_str
->length
]) && isdigit(*bp
))
350 while ((bp
< &cp
[oid_str
->length
]) && isspace(*bp
))
352 if (sscanf((char *)bp
, "%ld", &numbuf
) != 1) {
353 *minor_status
= EINVAL
;
354 return(GSS_S_FAILURE
);
356 while ((bp
< &cp
[oid_str
->length
]) && isdigit(*bp
))
358 while ((bp
< &cp
[oid_str
->length
]) &&
359 (isspace(*bp
) || *bp
== '.'))
362 while (isdigit(*bp
)) {
363 if (sscanf((char *)bp
, "%ld", &numbuf
) != 1) {
364 return(GSS_S_FAILURE
);
370 while ((bp
< &cp
[oid_str
->length
]) && isdigit(*bp
))
372 while ((bp
< &cp
[oid_str
->length
]) &&
373 (isspace(*bp
) || *bp
== '.'))
376 if (brace
&& (*bp
!= '}')) {
377 return(GSS_S_FAILURE
);
381 * Phew! We've come this far, so the syntax is good.
383 if ((*oid
= (gss_OID
) malloc(sizeof(gss_OID_desc
)))) {
384 if (((*oid
)->elements
= (void *) malloc(nbytes
))) {
385 (*oid
)->length
= nbytes
;
386 op
= (unsigned char *) (*oid
)->elements
;
388 (void) sscanf((char *)bp
, "%ld", &numbuf
);
391 while (isspace(*bp
) || *bp
== '.')
394 (void) sscanf((char *)bp
, "%ld", &numbuf
);
396 *op
= (unsigned char) onumbuf
;
400 while (isspace(*bp
) || *bp
== '.')
402 while (isdigit(*bp
)) {
403 (void) sscanf((char *)bp
, "%ld", &numbuf
);
405 /* Have to fill in the bytes msb-first */
415 op
[index
] = (unsigned char) numbuf
& 0x7f;
423 while (isspace(*bp
) || *bp
== '.')
426 return(GSS_S_COMPLETE
);
433 return(GSS_S_FAILURE
);
436 /* Compose an OID of a prefix and an integer suffix */
438 generic_gss_oid_compose(
439 OM_uint32
*minor_status
,
449 if (oid
== GSS_C_NO_OID
) {
450 *minor_status
= EINVAL
;
451 return GSS_S_FAILURE
;
453 if (oid
->length
< prefix_len
) {
454 *minor_status
= ERANGE
;
455 return GSS_S_FAILURE
;
458 memcpy(oid
->elements
, prefix
, prefix_len
);
468 if (oid
->length
< prefix_len
+ nbytes
) {
469 *minor_status
= ERANGE
;
470 return GSS_S_FAILURE
;
473 op
= (unsigned char *) oid
->elements
+ prefix_len
+ nbytes
;
476 op
[i
] = (unsigned char)suffix
& 0x7f;
483 oid
->length
= prefix_len
+ nbytes
;
486 return GSS_S_COMPLETE
;
490 generic_gss_oid_decompose(
491 OM_uint32
*minor_status
,
500 if (oid
->length
< prefix_len
||
501 memcmp(oid
->elements
, prefix
, prefix_len
) != 0) {
502 return GSS_S_BAD_MECH
;
505 op
= (unsigned char *) oid
->elements
+ prefix_len
;
509 slen
= oid
->length
- prefix_len
;
511 for (i
= 0; i
< slen
; i
++) {
512 *suffix
= (*suffix
<< 7) | (op
[i
] & 0x7f);
513 if (i
+ 1 != slen
&& (op
[i
] & 0x80) == 0) {
514 *minor_status
= EINVAL
;
515 return GSS_S_FAILURE
;
519 return GSS_S_COMPLETE
;
523 * Copyright 1993 by OpenVision Technologies, Inc.
525 * Permission to use, copy, modify, distribute, and sell this software
526 * and its documentation for any purpose is hereby granted without fee,
527 * provided that the above copyright notice appears in all copies and
528 * that both that copyright notice and this permission notice appear in
529 * supporting documentation, and that the name of OpenVision not be used
530 * in advertising or publicity pertaining to distribution of the software
531 * without specific, written prior permission. OpenVision makes no
532 * representations about the suitability of this software for any
533 * purpose. It is provided "as is" without express or implied warranty.
535 * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
536 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
537 * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
538 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
539 * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
540 * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
541 * PERFORMANCE OF THIS SOFTWARE.
545 OM_uint32
*minor_status
,
546 const gss_OID_set_desc
* const oidset
,
547 gss_OID_set
*new_oidset
550 gss_OID_set_desc
*copy
;
552 OM_uint32 major
= GSS_S_COMPLETE
;
555 if (minor_status
!= NULL
)
558 if (new_oidset
!= NULL
)
559 *new_oidset
= GSS_C_NO_OID_SET
;
561 if (oidset
== GSS_C_NO_OID_SET
)
562 return (GSS_S_CALL_INACCESSIBLE_READ
);
564 if (new_oidset
== NULL
)
565 return (GSS_S_CALL_INACCESSIBLE_WRITE
);
567 if ((copy
= (gss_OID_set_desc
*) calloc(1, sizeof (*copy
))) == NULL
) {
568 major
= GSS_S_FAILURE
;
572 if ((copy
->elements
= (gss_OID_desc
*)
573 calloc(oidset
->count
, sizeof (*copy
->elements
))) == NULL
) {
574 major
= GSS_S_FAILURE
;
577 copy
->count
= oidset
->count
;
579 for (index
= 0; index
< copy
->count
; index
++) {
580 gss_OID_desc
*out
= ©
->elements
[index
];
581 gss_OID_desc
*in
= &oidset
->elements
[index
];
583 if ((out
->elements
= (void *) malloc(in
->length
)) == NULL
) {
584 major
= GSS_S_FAILURE
;
587 (void) memcpy(out
->elements
, in
->elements
, in
->length
);
588 out
->length
= in
->length
;
593 if (major
!= GSS_S_COMPLETE
) {
594 (void) gss_release_oid_set(&minor
, ©
);