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