2 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
7 * lib/gssapi/generic/oid_ops.c
9 * Copyright 1995 by the Massachusetts Institute of Technology.
10 * All Rights Reserved.
12 * Export of this software from the United States of America may
13 * require a specific license from the United States Government.
14 * It is the responsibility of any person or organization contemplating
15 * export to obtain such a license before exporting.
17 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
18 * distribute this software and its documentation for any purpose and
19 * without fee is hereby granted, provided that the above copyright
20 * notice appear in all copies and that both that copyright notice and
21 * this permission notice appear in supporting documentation, and that
22 * the name of M.I.T. not be used in advertising or publicity pertaining
23 * to distribution of the software without specific, written prior
24 * permission. M.I.T. makes no representations about the suitability of
25 * this software for any purpose. It is provided "as is" without express
26 * or implied warranty.
31 * oid_ops.c - GSS-API V2 interfaces to manipulate OIDs
34 #include <mechglueP.h>
45 * this oid is defined in the oid structure but not exported to
46 * external callers; we must still ensure that we do not delete it.
48 extern const gss_OID_desc
* const gss_nt_service_name
;
52 generic_gss_release_oid(minor_status
, oid
)
53 OM_uint32
*minor_status
;
59 if (oid
== NULL
|| *oid
== GSS_C_NO_OID
)
60 return (GSS_S_COMPLETE
);
63 * The V2 API says the following!
65 * gss_release_oid[()] will recognize any of the GSSAPI's own OID
66 * values, and will silently ignore attempts to free these OIDs;
67 * for other OIDs it will call the C free() routine for both the OID
68 * data and the descriptor. This allows applications to freely mix
69 * their own heap allocated OID values with OIDs returned by GSS-API.
73 * We use the official OID definitions instead of the unofficial OID
74 * defintions. But we continue to support the unofficial OID
75 * gss_nt_service_name just in case if some gss applications use
79 if ((*oid
!= GSS_C_NT_USER_NAME
) &&
80 (*oid
!= GSS_C_NT_MACHINE_UID_NAME
) &&
81 (*oid
!= GSS_C_NT_STRING_UID_NAME
) &&
82 (*oid
!= GSS_C_NT_HOSTBASED_SERVICE
) &&
83 (*oid
!= GSS_C_NT_ANONYMOUS
) &&
84 (*oid
!= GSS_C_NT_EXPORT_NAME
) &&
85 (*oid
!= gss_nt_service_name
)) {
86 free((*oid
)->elements
);
90 return (GSS_S_COMPLETE
);
94 generic_gss_copy_oid(minor_status
, oid
, new_oid
)
95 OM_uint32
*minor_status
;
105 return (GSS_S_CALL_INACCESSIBLE_WRITE
);
107 if (oid
== GSS_C_NO_OID
)
108 return (GSS_S_CALL_INACCESSIBLE_READ
);
110 p
= (gss_OID
) malloc(sizeof (gss_OID_desc
));
112 return (GSS_S_FAILURE
);
114 p
->length
= oid
->length
;
115 p
->elements
= malloc(p
->length
);
118 return (GSS_S_FAILURE
);
120 (void) memcpy(p
->elements
, oid
->elements
, p
->length
);
122 return (GSS_S_COMPLETE
);
127 generic_gss_create_empty_oid_set(minor_status
, oid_set
)
128 OM_uint32
*minor_status
;
129 gss_OID_set
*oid_set
;
135 return (GSS_S_CALL_INACCESSIBLE_WRITE
);
137 if ((*oid_set
= (gss_OID_set
) malloc(sizeof (gss_OID_set_desc
)))) {
138 (void) memset(*oid_set
, 0, sizeof (gss_OID_set_desc
));
139 return (GSS_S_COMPLETE
);
141 return (GSS_S_FAILURE
);
146 generic_gss_add_oid_set_member(minor_status
, member_oid
, oid_set
)
147 OM_uint32
*minor_status
;
148 const gss_OID member_oid
;
149 gss_OID_set
*oid_set
;
157 if (member_oid
== GSS_C_NO_OID
|| member_oid
->length
== 0 ||
158 member_oid
->elements
== NULL
)
159 return (GSS_S_CALL_INACCESSIBLE_READ
);
162 return (GSS_S_CALL_INACCESSIBLE_WRITE
);
164 elist
= (*oid_set
)->elements
;
165 /* Get an enlarged copy of the array */
166 if (((*oid_set
)->elements
= (gss_OID
) malloc(((*oid_set
)->count
+1) *
167 sizeof (gss_OID_desc
)))) {
168 /* Copy in the old junk */
170 (void) memcpy((*oid_set
)->elements
, elist
,
171 ((*oid_set
)->count
* sizeof (gss_OID_desc
)));
173 /* Duplicate the input element */
174 lastel
= &(*oid_set
)->elements
[(*oid_set
)->count
];
175 if ((lastel
->elements
=
176 (void *) malloc(member_oid
->length
))) {
178 /* Success - copy elements */
179 (void) memcpy(lastel
->elements
, member_oid
->elements
,
182 lastel
->length
= member_oid
->length
;
188 return (GSS_S_COMPLETE
);
190 free((*oid_set
)->elements
);
192 /* Failure - restore old contents of list */
193 (*oid_set
)->elements
= elist
;
194 return (GSS_S_FAILURE
);
198 generic_gss_test_oid_set_member(minor_status
, member
, set
, present
)
199 OM_uint32
*minor_status
;
200 const gss_OID member
;
201 const gss_OID_set set
;
210 if (member
== GSS_C_NO_OID
|| set
== NULL
)
211 return (GSS_S_CALL_INACCESSIBLE_READ
);
214 return (GSS_S_CALL_INACCESSIBLE_WRITE
);
217 for (i
= 0; i
< set
->count
; i
++) {
218 if ((set
->elements
[i
].length
== member
->length
) &&
219 !memcmp(set
->elements
[i
].elements
,
220 member
->elements
, member
->length
)) {
226 return (GSS_S_COMPLETE
);
230 * OID<->string routines. These are uuuuugly.
233 generic_gss_oid_to_str(minor_status
, oid
, oid_str
)
234 OM_uint32
*minor_status
;
236 gss_buffer_t oid_str
;
241 OM_uint32 string_length
;
246 if (minor_status
!= NULL
)
249 if (oid_str
!= GSS_C_NO_BUFFER
) {
251 oid_str
->value
= NULL
;
254 if (oid
== GSS_C_NO_OID
|| oid
->length
== 0 || oid
->elements
== NULL
)
255 return (GSS_S_CALL_INACCESSIBLE_READ
);
257 if (oid_str
== GSS_C_NO_BUFFER
)
258 return (GSS_S_CALL_INACCESSIBLE_WRITE
);
260 /* First determine the size of the string */
264 cp
= (unsigned char *) oid
->elements
;
265 number
= (OM_uint32
) cp
[0];
266 (void) sprintf(numstr
, "%d ", number
/40);
267 string_length
+= strlen(numstr
);
268 (void) sprintf(numstr
, "%d ", number
%40);
269 string_length
+= strlen(numstr
);
270 for (i
= 1; i
< oid
->length
; i
++) {
271 if ((OM_uint32
) (numshift
+7) < (sizeof (OM_uint32
)*8)) {
272 number
= (number
<< 7) | (cp
[i
] & 0x7f);
275 return (GSS_S_FAILURE
);
278 if ((cp
[i
] & 0x80) == 0) {
279 (void) sprintf(numstr
, "%d ", number
);
280 string_length
+= strlen(numstr
);
286 * If we get here, we've calculated the length of "n n n ... n ". Add 4
287 * here for "{ " and "}\0".
290 if ((bp
= (char *)malloc(string_length
))) {
291 (void) strcpy(bp
, "{ ");
292 number
= (OM_uint32
) cp
[0];
293 (void) sprintf(numstr
, "%d ", number
/40);
294 (void) strcat(bp
, numstr
);
295 (void) sprintf(numstr
, "%d ", number
%40);
296 (void) strcat(bp
, numstr
);
298 cp
= (unsigned char *) oid
->elements
;
299 for (i
= 1; i
< oid
->length
; i
++) {
300 number
= (number
<< 7) | (cp
[i
] & 0x7f);
301 if ((cp
[i
] & 0x80) == 0) {
302 (void) sprintf(numstr
, "%d ", number
);
303 (void) strcat(bp
, numstr
);
307 (void) strcat(bp
, "}");
308 oid_str
->length
= strlen(bp
)+1;
309 oid_str
->value
= (void *) bp
;
310 return (GSS_S_COMPLETE
);
312 return (GSS_S_FAILURE
);
316 * This routine will handle 2 types of oid string formats:
317 * 1 - { 1 2 3 4 } where the braces are optional
318 * 2 - 1.2.3.4 this is an alernative format
319 * The first format is mandated by the gss spec. The
320 * second format is popular outside of the gss community so
324 generic_gss_str_to_oid(minor_status
, oid_str
, oid
)
325 OM_uint32
*minor_status
;
326 const gss_buffer_t oid_str
;
329 char *cp
, *bp
, *startp
;
337 if (minor_status
!= NULL
)
343 if (GSS_EMPTY_BUFFER(oid_str
))
344 return (GSS_S_CALL_INACCESSIBLE_READ
);
347 return (GSS_S_CALL_INACCESSIBLE_WRITE
);
350 bp
= (char *)oid_str
->value
;
352 /* Skip over leading space */
353 while ((bp
< &cp
[oid_str
->length
]) && isspace(*bp
))
359 while ((bp
< &cp
[oid_str
->length
]) && isspace(*bp
))
365 * The first two numbers are chewed up by the first octet.
367 if (sscanf(bp
, "%d", &numbuf
) != 1) {
368 return (GSS_S_FAILURE
);
370 while ((bp
< &cp
[oid_str
->length
]) && isdigit(*bp
))
372 while ((bp
< &cp
[oid_str
->length
]) &&
373 (isspace(*bp
) || *bp
== '.'))
375 if (sscanf(bp
, "%d", &numbuf
) != 1) {
376 return (GSS_S_FAILURE
);
378 while ((bp
< &cp
[oid_str
->length
]) && isdigit(*bp
))
380 while ((bp
< &cp
[oid_str
->length
]) &&
381 (isspace(*bp
) || *bp
== '.'))
384 while (isdigit(*bp
)) {
385 if (sscanf(bp
, "%d", &numbuf
) != 1) {
386 return (GSS_S_FAILURE
);
392 while ((bp
< &cp
[oid_str
->length
]) && isdigit(*bp
))
394 while ((bp
< &cp
[oid_str
->length
]) &&
395 (isspace(*bp
) || *bp
== '.'))
398 if (brace
&& (*bp
!= '}')) {
399 return (GSS_S_FAILURE
);
403 * Phew! We've come this far, so the syntax is good.
405 if ((*oid
= (gss_OID
) malloc(sizeof (gss_OID_desc
)))) {
406 if (((*oid
)->elements
= (void *) malloc(nbytes
))) {
407 (*oid
)->length
= nbytes
;
408 op
= (unsigned char *) (*oid
)->elements
;
410 (void) sscanf(bp
, "%d", &numbuf
);
413 while (isspace(*bp
) || *bp
== '.')
416 (void) sscanf(bp
, "%d", &numbuf
);
418 *op
= (unsigned char) onumbuf
;
422 while (isspace(*bp
) || *bp
== '.')
424 while (isdigit(*bp
)) {
425 (void) sscanf(bp
, "%d", &numbuf
);
427 /* Have to fill in the bytes msb-first */
437 op
[index
] = (unsigned char)
446 while (isspace(*bp
) || *bp
== '.')
449 return (GSS_S_COMPLETE
);
455 return (GSS_S_FAILURE
);
459 * Copyright 1993 by OpenVision Technologies, Inc.
461 * Permission to use, copy, modify, distribute, and sell this software
462 * and its documentation for any purpose is hereby granted without fee,
463 * provided that the above copyright notice appears in all copies and
464 * that both that copyright notice and this permission notice appear in
465 * supporting documentation, and that the name of OpenVision not be used
466 * in advertising or publicity pertaining to distribution of the software
467 * without specific, written prior permission. OpenVision makes no
468 * representations about the suitability of this software for any
469 * purpose. It is provided "as is" without express or implied warranty.
471 * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
472 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
473 * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
474 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
475 * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
476 * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
477 * PERFORMANCE OF THIS SOFTWARE.
481 OM_uint32
*minor_status
,
482 const gss_OID_set_desc
* const oidset
,
483 gss_OID_set
*new_oidset
486 gss_OID_set_desc
*copy
;
488 OM_uint32 major
= GSS_S_COMPLETE
;
491 if (minor_status
!= NULL
)
494 if (new_oidset
!= NULL
)
495 *new_oidset
= GSS_C_NO_OID_SET
;
497 if (oidset
== GSS_C_NO_OID_SET
)
498 return (GSS_S_CALL_INACCESSIBLE_READ
);
500 if (new_oidset
== NULL
)
501 return (GSS_S_CALL_INACCESSIBLE_WRITE
);
503 if ((copy
= (gss_OID_set_desc
*) calloc(1, sizeof (*copy
))) == NULL
) {
504 major
= GSS_S_FAILURE
;
508 if ((copy
->elements
= (gss_OID_desc
*)
509 calloc(oidset
->count
, sizeof (*copy
->elements
))) == NULL
) {
510 major
= GSS_S_FAILURE
;
513 copy
->count
= oidset
->count
;
515 for (index
= 0; index
< copy
->count
; index
++) {
516 gss_OID_desc
*out
= ©
->elements
[index
];
517 gss_OID_desc
*in
= &oidset
->elements
[index
];
519 if ((out
->elements
= (void *) malloc(in
->length
)) == NULL
) {
520 major
= GSS_S_FAILURE
;
523 (void) memcpy(out
->elements
, in
->elements
, in
->length
);
524 out
->length
= in
->length
;
529 if (major
!= GSS_S_COMPLETE
) {
530 (void) gss_release_oid_set(&minor
, ©
);