10Sstevel@tonic-gate /* 2*9698SPeter.Shoults@Sun.COM * CDDL HEADER START 3*9698SPeter.Shoults@Sun.COM * 4*9698SPeter.Shoults@Sun.COM * The contents of this file are subject to the terms of the 5*9698SPeter.Shoults@Sun.COM * Common Development and Distribution License (the "License"). 6*9698SPeter.Shoults@Sun.COM * You may not use this file except in compliance with the License. 7*9698SPeter.Shoults@Sun.COM * 8*9698SPeter.Shoults@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*9698SPeter.Shoults@Sun.COM * or http://www.opensolaris.org/os/licensing. 10*9698SPeter.Shoults@Sun.COM * See the License for the specific language governing permissions 11*9698SPeter.Shoults@Sun.COM * and limitations under the License. 12*9698SPeter.Shoults@Sun.COM * 13*9698SPeter.Shoults@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each 14*9698SPeter.Shoults@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*9698SPeter.Shoults@Sun.COM * If applicable, add the following below this CDDL HEADER, with the 16*9698SPeter.Shoults@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying 17*9698SPeter.Shoults@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner] 18*9698SPeter.Shoults@Sun.COM * 19*9698SPeter.Shoults@Sun.COM * CDDL HEADER END 20*9698SPeter.Shoults@Sun.COM */ 21*9698SPeter.Shoults@Sun.COM /* 22*9698SPeter.Shoults@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 230Sstevel@tonic-gate * Use is subject to license terms. 240Sstevel@tonic-gate */ 250Sstevel@tonic-gate 260Sstevel@tonic-gate /* 270Sstevel@tonic-gate * lib/gssapi/generic/oid_ops.c 280Sstevel@tonic-gate * 290Sstevel@tonic-gate * Copyright 1995 by the Massachusetts Institute of Technology. 300Sstevel@tonic-gate * All Rights Reserved. 310Sstevel@tonic-gate * 320Sstevel@tonic-gate * Export of this software from the United States of America may 330Sstevel@tonic-gate * require a specific license from the United States Government. 340Sstevel@tonic-gate * It is the responsibility of any person or organization contemplating 350Sstevel@tonic-gate * export to obtain such a license before exporting. 360Sstevel@tonic-gate * 370Sstevel@tonic-gate * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and 380Sstevel@tonic-gate * distribute this software and its documentation for any purpose and 390Sstevel@tonic-gate * without fee is hereby granted, provided that the above copyright 400Sstevel@tonic-gate * notice appear in all copies and that both that copyright notice and 410Sstevel@tonic-gate * this permission notice appear in supporting documentation, and that 420Sstevel@tonic-gate * the name of M.I.T. not be used in advertising or publicity pertaining 430Sstevel@tonic-gate * to distribution of the software without specific, written prior 440Sstevel@tonic-gate * permission. M.I.T. makes no representations about the suitability of 450Sstevel@tonic-gate * this software for any purpose. It is provided "as is" without express 460Sstevel@tonic-gate * or implied warranty. 470Sstevel@tonic-gate * 480Sstevel@tonic-gate */ 490Sstevel@tonic-gate 500Sstevel@tonic-gate /* 510Sstevel@tonic-gate * oid_ops.c - GSS-API V2 interfaces to manipulate OIDs 520Sstevel@tonic-gate */ 530Sstevel@tonic-gate 540Sstevel@tonic-gate #include <mechglueP.h> 550Sstevel@tonic-gate #ifdef HAVE_UNISTD_H 560Sstevel@tonic-gate #include <unistd.h> 570Sstevel@tonic-gate #endif 580Sstevel@tonic-gate #include <stdlib.h> 590Sstevel@tonic-gate #include <string.h> 600Sstevel@tonic-gate #include <stdio.h> 610Sstevel@tonic-gate #include <errno.h> 620Sstevel@tonic-gate #include <ctype.h> 630Sstevel@tonic-gate 640Sstevel@tonic-gate /* 650Sstevel@tonic-gate * this oid is defined in the oid structure but not exported to 660Sstevel@tonic-gate * external callers; we must still ensure that we do not delete it. 670Sstevel@tonic-gate */ 680Sstevel@tonic-gate extern const gss_OID_desc * const gss_nt_service_name; 690Sstevel@tonic-gate 700Sstevel@tonic-gate 710Sstevel@tonic-gate OM_uint32 720Sstevel@tonic-gate generic_gss_release_oid(minor_status, oid) 730Sstevel@tonic-gate OM_uint32 *minor_status; 740Sstevel@tonic-gate gss_OID *oid; 750Sstevel@tonic-gate { 760Sstevel@tonic-gate if (minor_status) 770Sstevel@tonic-gate *minor_status = 0; 780Sstevel@tonic-gate 79*9698SPeter.Shoults@Sun.COM if (oid == NULL || *oid == GSS_C_NO_OID) 800Sstevel@tonic-gate return (GSS_S_COMPLETE); 810Sstevel@tonic-gate 820Sstevel@tonic-gate /* 830Sstevel@tonic-gate * The V2 API says the following! 840Sstevel@tonic-gate * 850Sstevel@tonic-gate * gss_release_oid[()] will recognize any of the GSSAPI's own OID 860Sstevel@tonic-gate * values, and will silently ignore attempts to free these OIDs; 870Sstevel@tonic-gate * for other OIDs it will call the C free() routine for both the OID 880Sstevel@tonic-gate * data and the descriptor. This allows applications to freely mix 890Sstevel@tonic-gate * their own heap allocated OID values with OIDs returned by GSS-API. 900Sstevel@tonic-gate */ 910Sstevel@tonic-gate 920Sstevel@tonic-gate /* 930Sstevel@tonic-gate * We use the official OID definitions instead of the unofficial OID 940Sstevel@tonic-gate * defintions. But we continue to support the unofficial OID 950Sstevel@tonic-gate * gss_nt_service_name just in case if some gss applications use 960Sstevel@tonic-gate * the old OID. 970Sstevel@tonic-gate */ 980Sstevel@tonic-gate 990Sstevel@tonic-gate if ((*oid != GSS_C_NT_USER_NAME) && 1000Sstevel@tonic-gate (*oid != GSS_C_NT_MACHINE_UID_NAME) && 1010Sstevel@tonic-gate (*oid != GSS_C_NT_STRING_UID_NAME) && 1020Sstevel@tonic-gate (*oid != GSS_C_NT_HOSTBASED_SERVICE) && 1030Sstevel@tonic-gate (*oid != GSS_C_NT_ANONYMOUS) && 1040Sstevel@tonic-gate (*oid != GSS_C_NT_EXPORT_NAME) && 1050Sstevel@tonic-gate (*oid != gss_nt_service_name)) { 1060Sstevel@tonic-gate free((*oid)->elements); 1070Sstevel@tonic-gate free(*oid); 1080Sstevel@tonic-gate } 1090Sstevel@tonic-gate *oid = GSS_C_NO_OID; 1100Sstevel@tonic-gate return (GSS_S_COMPLETE); 1110Sstevel@tonic-gate } 1120Sstevel@tonic-gate 1130Sstevel@tonic-gate OM_uint32 1140Sstevel@tonic-gate generic_gss_copy_oid(minor_status, oid, new_oid) 1150Sstevel@tonic-gate OM_uint32 *minor_status; 1160Sstevel@tonic-gate const gss_OID oid; 1170Sstevel@tonic-gate gss_OID *new_oid; 1180Sstevel@tonic-gate { 1190Sstevel@tonic-gate gss_OID p; 1200Sstevel@tonic-gate 1210Sstevel@tonic-gate if (minor_status) 1220Sstevel@tonic-gate *minor_status = 0; 1230Sstevel@tonic-gate 124160Swyllys if (new_oid == NULL) 125160Swyllys return (GSS_S_CALL_INACCESSIBLE_WRITE); 126160Swyllys 127160Swyllys if (oid == GSS_C_NO_OID) 128160Swyllys return (GSS_S_CALL_INACCESSIBLE_READ); 129160Swyllys 1300Sstevel@tonic-gate p = (gss_OID) malloc(sizeof (gss_OID_desc)); 1310Sstevel@tonic-gate if (!p) { 1320Sstevel@tonic-gate return (GSS_S_FAILURE); 1330Sstevel@tonic-gate } 1340Sstevel@tonic-gate p->length = oid->length; 1350Sstevel@tonic-gate p->elements = malloc(p->length); 1360Sstevel@tonic-gate if (!p->elements) { 1370Sstevel@tonic-gate free(p); 1380Sstevel@tonic-gate return (GSS_S_FAILURE); 1390Sstevel@tonic-gate } 1400Sstevel@tonic-gate (void) memcpy(p->elements, oid->elements, p->length); 1410Sstevel@tonic-gate *new_oid = p; 1420Sstevel@tonic-gate return (GSS_S_COMPLETE); 1430Sstevel@tonic-gate } 1440Sstevel@tonic-gate 1450Sstevel@tonic-gate 1460Sstevel@tonic-gate OM_uint32 1470Sstevel@tonic-gate generic_gss_create_empty_oid_set(minor_status, oid_set) 1480Sstevel@tonic-gate OM_uint32 *minor_status; 1490Sstevel@tonic-gate gss_OID_set *oid_set; 1500Sstevel@tonic-gate { 1510Sstevel@tonic-gate if (minor_status) 1520Sstevel@tonic-gate *minor_status = 0; 1530Sstevel@tonic-gate 154160Swyllys if (oid_set == NULL) 155160Swyllys return (GSS_S_CALL_INACCESSIBLE_WRITE); 156160Swyllys 1570Sstevel@tonic-gate if ((*oid_set = (gss_OID_set) malloc(sizeof (gss_OID_set_desc)))) { 1580Sstevel@tonic-gate (void) memset(*oid_set, 0, sizeof (gss_OID_set_desc)); 1590Sstevel@tonic-gate return (GSS_S_COMPLETE); 1600Sstevel@tonic-gate } else { 1610Sstevel@tonic-gate return (GSS_S_FAILURE); 1620Sstevel@tonic-gate } 1630Sstevel@tonic-gate } 1640Sstevel@tonic-gate 1650Sstevel@tonic-gate OM_uint32 1660Sstevel@tonic-gate generic_gss_add_oid_set_member(minor_status, member_oid, oid_set) 1670Sstevel@tonic-gate OM_uint32 *minor_status; 1680Sstevel@tonic-gate const gss_OID member_oid; 1690Sstevel@tonic-gate gss_OID_set *oid_set; 1700Sstevel@tonic-gate { 1710Sstevel@tonic-gate gss_OID elist; 1720Sstevel@tonic-gate gss_OID lastel; 1730Sstevel@tonic-gate 1740Sstevel@tonic-gate if (minor_status) 1750Sstevel@tonic-gate *minor_status = 0; 1760Sstevel@tonic-gate 177160Swyllys if (member_oid == GSS_C_NO_OID || member_oid->length == 0 || 1780Sstevel@tonic-gate member_oid->elements == NULL) 1790Sstevel@tonic-gate return (GSS_S_CALL_INACCESSIBLE_READ); 1800Sstevel@tonic-gate 181160Swyllys if (oid_set == NULL) 182160Swyllys return (GSS_S_CALL_INACCESSIBLE_WRITE); 183160Swyllys 1840Sstevel@tonic-gate elist = (*oid_set)->elements; 1850Sstevel@tonic-gate /* Get an enlarged copy of the array */ 1860Sstevel@tonic-gate if (((*oid_set)->elements = (gss_OID) malloc(((*oid_set)->count+1) * 1870Sstevel@tonic-gate sizeof (gss_OID_desc)))) { 188160Swyllys /* Copy in the old junk */ 1890Sstevel@tonic-gate if (elist) 1900Sstevel@tonic-gate (void) memcpy((*oid_set)->elements, elist, 1910Sstevel@tonic-gate ((*oid_set)->count * sizeof (gss_OID_desc))); 1920Sstevel@tonic-gate 193160Swyllys /* Duplicate the input element */ 1940Sstevel@tonic-gate lastel = &(*oid_set)->elements[(*oid_set)->count]; 1950Sstevel@tonic-gate if ((lastel->elements = 1960Sstevel@tonic-gate (void *) malloc(member_oid->length))) { 197160Swyllys 198160Swyllys /* Success - copy elements */ 1990Sstevel@tonic-gate (void) memcpy(lastel->elements, member_oid->elements, 2000Sstevel@tonic-gate member_oid->length); 201160Swyllys /* Set length */ 2020Sstevel@tonic-gate lastel->length = member_oid->length; 2030Sstevel@tonic-gate 204160Swyllys /* Update count */ 2050Sstevel@tonic-gate (*oid_set)->count++; 2060Sstevel@tonic-gate if (elist) 2070Sstevel@tonic-gate free(elist); 2080Sstevel@tonic-gate return (GSS_S_COMPLETE); 2090Sstevel@tonic-gate } else 2100Sstevel@tonic-gate free((*oid_set)->elements); 2110Sstevel@tonic-gate } 2120Sstevel@tonic-gate /* Failure - restore old contents of list */ 2130Sstevel@tonic-gate (*oid_set)->elements = elist; 2140Sstevel@tonic-gate return (GSS_S_FAILURE); 2150Sstevel@tonic-gate } 2160Sstevel@tonic-gate 2170Sstevel@tonic-gate OM_uint32 2180Sstevel@tonic-gate generic_gss_test_oid_set_member(minor_status, member, set, present) 2190Sstevel@tonic-gate OM_uint32 *minor_status; 2200Sstevel@tonic-gate const gss_OID member; 2210Sstevel@tonic-gate const gss_OID_set set; 2220Sstevel@tonic-gate int *present; 2230Sstevel@tonic-gate { 2240Sstevel@tonic-gate OM_uint32 i; 2250Sstevel@tonic-gate int result; 2260Sstevel@tonic-gate 2270Sstevel@tonic-gate if (minor_status) 2280Sstevel@tonic-gate *minor_status = 0; 2290Sstevel@tonic-gate 230160Swyllys if (member == GSS_C_NO_OID || set == NULL) 2310Sstevel@tonic-gate return (GSS_S_CALL_INACCESSIBLE_READ); 2320Sstevel@tonic-gate 2330Sstevel@tonic-gate if (present == NULL) 2340Sstevel@tonic-gate return (GSS_S_CALL_INACCESSIBLE_WRITE); 2350Sstevel@tonic-gate 2360Sstevel@tonic-gate result = 0; 2370Sstevel@tonic-gate for (i = 0; i < set->count; i++) { 2380Sstevel@tonic-gate if ((set->elements[i].length == member->length) && 2390Sstevel@tonic-gate !memcmp(set->elements[i].elements, 2400Sstevel@tonic-gate member->elements, member->length)) { 2410Sstevel@tonic-gate result = 1; 2420Sstevel@tonic-gate break; 2430Sstevel@tonic-gate } 2440Sstevel@tonic-gate } 2450Sstevel@tonic-gate *present = result; 2460Sstevel@tonic-gate return (GSS_S_COMPLETE); 2470Sstevel@tonic-gate } 2480Sstevel@tonic-gate 2490Sstevel@tonic-gate /* 2500Sstevel@tonic-gate * OID<->string routines. These are uuuuugly. 2510Sstevel@tonic-gate */ 2520Sstevel@tonic-gate OM_uint32 2530Sstevel@tonic-gate generic_gss_oid_to_str(minor_status, oid, oid_str) 2540Sstevel@tonic-gate OM_uint32 *minor_status; 2550Sstevel@tonic-gate const gss_OID oid; 2560Sstevel@tonic-gate gss_buffer_t oid_str; 2570Sstevel@tonic-gate { 2580Sstevel@tonic-gate char numstr[128]; 2590Sstevel@tonic-gate OM_uint32 number; 2600Sstevel@tonic-gate int numshift; 2610Sstevel@tonic-gate OM_uint32 string_length; 2620Sstevel@tonic-gate OM_uint32 i; 2630Sstevel@tonic-gate unsigned char *cp; 2640Sstevel@tonic-gate char *bp; 2650Sstevel@tonic-gate 266*9698SPeter.Shoults@Sun.COM if (minor_status != NULL) 2670Sstevel@tonic-gate *minor_status = 0; 2680Sstevel@tonic-gate 269*9698SPeter.Shoults@Sun.COM if (oid_str != GSS_C_NO_BUFFER) { 270*9698SPeter.Shoults@Sun.COM oid_str->length = 0; 271*9698SPeter.Shoults@Sun.COM oid_str->value = NULL; 272*9698SPeter.Shoults@Sun.COM } 273*9698SPeter.Shoults@Sun.COM 274160Swyllys if (oid == GSS_C_NO_OID || oid->length == 0 || oid->elements == NULL) 2750Sstevel@tonic-gate return (GSS_S_CALL_INACCESSIBLE_READ); 2760Sstevel@tonic-gate 277*9698SPeter.Shoults@Sun.COM if (oid_str == GSS_C_NO_BUFFER) 2780Sstevel@tonic-gate return (GSS_S_CALL_INACCESSIBLE_WRITE); 2790Sstevel@tonic-gate 2800Sstevel@tonic-gate /* First determine the size of the string */ 2810Sstevel@tonic-gate string_length = 0; 2820Sstevel@tonic-gate number = 0; 2830Sstevel@tonic-gate numshift = 0; 2840Sstevel@tonic-gate cp = (unsigned char *) oid->elements; 2850Sstevel@tonic-gate number = (OM_uint32) cp[0]; 2860Sstevel@tonic-gate (void) sprintf(numstr, "%d ", number/40); 2870Sstevel@tonic-gate string_length += strlen(numstr); 2880Sstevel@tonic-gate (void) sprintf(numstr, "%d ", number%40); 2890Sstevel@tonic-gate string_length += strlen(numstr); 2900Sstevel@tonic-gate for (i = 1; i < oid->length; i++) { 2910Sstevel@tonic-gate if ((OM_uint32) (numshift+7) < (sizeof (OM_uint32)*8)) { 2920Sstevel@tonic-gate number = (number << 7) | (cp[i] & 0x7f); 2930Sstevel@tonic-gate numshift += 7; 2940Sstevel@tonic-gate } else { 2950Sstevel@tonic-gate return (GSS_S_FAILURE); 2960Sstevel@tonic-gate } 2970Sstevel@tonic-gate 2980Sstevel@tonic-gate if ((cp[i] & 0x80) == 0) { 2990Sstevel@tonic-gate (void) sprintf(numstr, "%d ", number); 3000Sstevel@tonic-gate string_length += strlen(numstr); 3010Sstevel@tonic-gate number = 0; 3020Sstevel@tonic-gate numshift = 0; 3030Sstevel@tonic-gate } 3040Sstevel@tonic-gate } 3050Sstevel@tonic-gate /* 3060Sstevel@tonic-gate * If we get here, we've calculated the length of "n n n ... n ". Add 4 3070Sstevel@tonic-gate * here for "{ " and "}\0". 3080Sstevel@tonic-gate */ 3090Sstevel@tonic-gate string_length += 4; 3100Sstevel@tonic-gate if ((bp = (char *)malloc(string_length))) { 3110Sstevel@tonic-gate (void) strcpy(bp, "{ "); 3120Sstevel@tonic-gate number = (OM_uint32) cp[0]; 3130Sstevel@tonic-gate (void) sprintf(numstr, "%d ", number/40); 3140Sstevel@tonic-gate (void) strcat(bp, numstr); 3150Sstevel@tonic-gate (void) sprintf(numstr, "%d ", number%40); 3160Sstevel@tonic-gate (void) strcat(bp, numstr); 3170Sstevel@tonic-gate number = 0; 3180Sstevel@tonic-gate cp = (unsigned char *) oid->elements; 3190Sstevel@tonic-gate for (i = 1; i < oid->length; i++) { 3200Sstevel@tonic-gate number = (number << 7) | (cp[i] & 0x7f); 3210Sstevel@tonic-gate if ((cp[i] & 0x80) == 0) { 3220Sstevel@tonic-gate (void) sprintf(numstr, "%d ", number); 3230Sstevel@tonic-gate (void) strcat(bp, numstr); 3240Sstevel@tonic-gate number = 0; 3250Sstevel@tonic-gate } 3260Sstevel@tonic-gate } 3270Sstevel@tonic-gate (void) strcat(bp, "}"); 3280Sstevel@tonic-gate oid_str->length = strlen(bp)+1; 3290Sstevel@tonic-gate oid_str->value = (void *) bp; 3300Sstevel@tonic-gate return (GSS_S_COMPLETE); 3310Sstevel@tonic-gate } 3320Sstevel@tonic-gate return (GSS_S_FAILURE); 3330Sstevel@tonic-gate } 3340Sstevel@tonic-gate 3350Sstevel@tonic-gate /* 3360Sstevel@tonic-gate * This routine will handle 2 types of oid string formats: 3370Sstevel@tonic-gate * 1 - { 1 2 3 4 } where the braces are optional 3380Sstevel@tonic-gate * 2 - 1.2.3.4 this is an alernative format 3390Sstevel@tonic-gate * The first format is mandated by the gss spec. The 3400Sstevel@tonic-gate * second format is popular outside of the gss community so 3410Sstevel@tonic-gate * has been added. 3420Sstevel@tonic-gate */ 3430Sstevel@tonic-gate OM_uint32 3440Sstevel@tonic-gate generic_gss_str_to_oid(minor_status, oid_str, oid) 3450Sstevel@tonic-gate OM_uint32 *minor_status; 3460Sstevel@tonic-gate const gss_buffer_t oid_str; 3470Sstevel@tonic-gate gss_OID *oid; 3480Sstevel@tonic-gate { 3490Sstevel@tonic-gate char *cp, *bp, *startp; 3500Sstevel@tonic-gate int brace; 3510Sstevel@tonic-gate int numbuf; 3520Sstevel@tonic-gate int onumbuf; 3530Sstevel@tonic-gate OM_uint32 nbytes; 3540Sstevel@tonic-gate int index; 3550Sstevel@tonic-gate unsigned char *op; 3560Sstevel@tonic-gate 357*9698SPeter.Shoults@Sun.COM if (minor_status != NULL) 3580Sstevel@tonic-gate *minor_status = 0; 3590Sstevel@tonic-gate 360*9698SPeter.Shoults@Sun.COM if (oid != NULL) 361*9698SPeter.Shoults@Sun.COM *oid = GSS_C_NO_OID; 362*9698SPeter.Shoults@Sun.COM 3630Sstevel@tonic-gate if (GSS_EMPTY_BUFFER(oid_str)) 3640Sstevel@tonic-gate return (GSS_S_CALL_INACCESSIBLE_READ); 3650Sstevel@tonic-gate 3660Sstevel@tonic-gate if (oid == NULL) 3670Sstevel@tonic-gate return (GSS_S_CALL_INACCESSIBLE_WRITE); 3680Sstevel@tonic-gate 3690Sstevel@tonic-gate brace = 0; 3700Sstevel@tonic-gate bp = (char *)oid_str->value; 3710Sstevel@tonic-gate cp = bp; 3720Sstevel@tonic-gate /* Skip over leading space */ 3730Sstevel@tonic-gate while ((bp < &cp[oid_str->length]) && isspace(*bp)) 3740Sstevel@tonic-gate bp++; 3750Sstevel@tonic-gate if (*bp == '{') { 3760Sstevel@tonic-gate brace = 1; 3770Sstevel@tonic-gate bp++; 3780Sstevel@tonic-gate } 3790Sstevel@tonic-gate while ((bp < &cp[oid_str->length]) && isspace(*bp)) 3800Sstevel@tonic-gate bp++; 3810Sstevel@tonic-gate startp = bp; 3820Sstevel@tonic-gate nbytes = 0; 3830Sstevel@tonic-gate 3840Sstevel@tonic-gate /* 3850Sstevel@tonic-gate * The first two numbers are chewed up by the first octet. 3860Sstevel@tonic-gate */ 3870Sstevel@tonic-gate if (sscanf(bp, "%d", &numbuf) != 1) { 3880Sstevel@tonic-gate return (GSS_S_FAILURE); 3890Sstevel@tonic-gate } 3900Sstevel@tonic-gate while ((bp < &cp[oid_str->length]) && isdigit(*bp)) 3910Sstevel@tonic-gate bp++; 3920Sstevel@tonic-gate while ((bp < &cp[oid_str->length]) && 3930Sstevel@tonic-gate (isspace(*bp) || *bp == '.')) 3940Sstevel@tonic-gate bp++; 3950Sstevel@tonic-gate if (sscanf(bp, "%d", &numbuf) != 1) { 3960Sstevel@tonic-gate return (GSS_S_FAILURE); 3970Sstevel@tonic-gate } 3980Sstevel@tonic-gate while ((bp < &cp[oid_str->length]) && isdigit(*bp)) 3990Sstevel@tonic-gate bp++; 4000Sstevel@tonic-gate while ((bp < &cp[oid_str->length]) && 4010Sstevel@tonic-gate (isspace(*bp) || *bp == '.')) 4020Sstevel@tonic-gate bp++; 4030Sstevel@tonic-gate nbytes++; 4040Sstevel@tonic-gate while (isdigit(*bp)) { 4050Sstevel@tonic-gate if (sscanf(bp, "%d", &numbuf) != 1) { 4060Sstevel@tonic-gate return (GSS_S_FAILURE); 4070Sstevel@tonic-gate } 4080Sstevel@tonic-gate while (numbuf) { 4090Sstevel@tonic-gate nbytes++; 4100Sstevel@tonic-gate numbuf >>= 7; 4110Sstevel@tonic-gate } 4120Sstevel@tonic-gate while ((bp < &cp[oid_str->length]) && isdigit(*bp)) 4130Sstevel@tonic-gate bp++; 4140Sstevel@tonic-gate while ((bp < &cp[oid_str->length]) && 4150Sstevel@tonic-gate (isspace(*bp) || *bp == '.')) 4160Sstevel@tonic-gate bp++; 4170Sstevel@tonic-gate } 4180Sstevel@tonic-gate if (brace && (*bp != '}')) { 4190Sstevel@tonic-gate return (GSS_S_FAILURE); 4200Sstevel@tonic-gate } 4210Sstevel@tonic-gate 4220Sstevel@tonic-gate /* 4230Sstevel@tonic-gate * Phew! We've come this far, so the syntax is good. 4240Sstevel@tonic-gate */ 4250Sstevel@tonic-gate if ((*oid = (gss_OID) malloc(sizeof (gss_OID_desc)))) { 4260Sstevel@tonic-gate if (((*oid)->elements = (void *) malloc(nbytes))) { 4270Sstevel@tonic-gate (*oid)->length = nbytes; 4280Sstevel@tonic-gate op = (unsigned char *) (*oid)->elements; 4290Sstevel@tonic-gate bp = startp; 4300Sstevel@tonic-gate (void) sscanf(bp, "%d", &numbuf); 4310Sstevel@tonic-gate while (isdigit(*bp)) 4320Sstevel@tonic-gate bp++; 4330Sstevel@tonic-gate while (isspace(*bp) || *bp == '.') 4340Sstevel@tonic-gate bp++; 4350Sstevel@tonic-gate onumbuf = 40*numbuf; 4360Sstevel@tonic-gate (void) sscanf(bp, "%d", &numbuf); 4370Sstevel@tonic-gate onumbuf += numbuf; 4380Sstevel@tonic-gate *op = (unsigned char) onumbuf; 4390Sstevel@tonic-gate op++; 4400Sstevel@tonic-gate while (isdigit(*bp)) 4410Sstevel@tonic-gate bp++; 4420Sstevel@tonic-gate while (isspace(*bp) || *bp == '.') 4430Sstevel@tonic-gate bp++; 4440Sstevel@tonic-gate while (isdigit(*bp)) { 4450Sstevel@tonic-gate (void) sscanf(bp, "%d", &numbuf); 4460Sstevel@tonic-gate nbytes = 0; 4470Sstevel@tonic-gate /* Have to fill in the bytes msb-first */ 4480Sstevel@tonic-gate onumbuf = numbuf; 4490Sstevel@tonic-gate while (numbuf) { 4500Sstevel@tonic-gate nbytes++; 4510Sstevel@tonic-gate numbuf >>= 7; 4520Sstevel@tonic-gate } 4530Sstevel@tonic-gate numbuf = onumbuf; 4540Sstevel@tonic-gate op += nbytes; 4550Sstevel@tonic-gate index = -1; 4560Sstevel@tonic-gate while (numbuf) { 4570Sstevel@tonic-gate op[index] = (unsigned char) 4580Sstevel@tonic-gate numbuf & 0x7f; 4590Sstevel@tonic-gate if (index != -1) 4600Sstevel@tonic-gate op[index] |= 0x80; 4610Sstevel@tonic-gate index--; 4620Sstevel@tonic-gate numbuf >>= 7; 4630Sstevel@tonic-gate } 4640Sstevel@tonic-gate while (isdigit(*bp)) 4650Sstevel@tonic-gate bp++; 4660Sstevel@tonic-gate while (isspace(*bp) || *bp == '.') 4670Sstevel@tonic-gate bp++; 4680Sstevel@tonic-gate } 4690Sstevel@tonic-gate return (GSS_S_COMPLETE); 4700Sstevel@tonic-gate } else { 4710Sstevel@tonic-gate free(*oid); 4720Sstevel@tonic-gate *oid = GSS_C_NO_OID; 4730Sstevel@tonic-gate } 4740Sstevel@tonic-gate } 4750Sstevel@tonic-gate return (GSS_S_FAILURE); 4760Sstevel@tonic-gate } 4770Sstevel@tonic-gate 4780Sstevel@tonic-gate /* 4790Sstevel@tonic-gate * Copyright 1993 by OpenVision Technologies, Inc. 4800Sstevel@tonic-gate * 4810Sstevel@tonic-gate * Permission to use, copy, modify, distribute, and sell this software 4820Sstevel@tonic-gate * and its documentation for any purpose is hereby granted without fee, 4830Sstevel@tonic-gate * provided that the above copyright notice appears in all copies and 4840Sstevel@tonic-gate * that both that copyright notice and this permission notice appear in 4850Sstevel@tonic-gate * supporting documentation, and that the name of OpenVision not be used 4860Sstevel@tonic-gate * in advertising or publicity pertaining to distribution of the software 4870Sstevel@tonic-gate * without specific, written prior permission. OpenVision makes no 4880Sstevel@tonic-gate * representations about the suitability of this software for any 4890Sstevel@tonic-gate * purpose. It is provided "as is" without express or implied warranty. 4900Sstevel@tonic-gate * 4910Sstevel@tonic-gate * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 4920Sstevel@tonic-gate * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 4930Sstevel@tonic-gate * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR 4940Sstevel@tonic-gate * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF 4950Sstevel@tonic-gate * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 4960Sstevel@tonic-gate * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 4970Sstevel@tonic-gate * PERFORMANCE OF THIS SOFTWARE. 4980Sstevel@tonic-gate */ 4990Sstevel@tonic-gate OM_uint32 5000Sstevel@tonic-gate gss_copy_oid_set( 5010Sstevel@tonic-gate OM_uint32 *minor_status, 5020Sstevel@tonic-gate const gss_OID_set_desc * const oidset, 5030Sstevel@tonic-gate gss_OID_set *new_oidset 5040Sstevel@tonic-gate ) 5050Sstevel@tonic-gate { 5060Sstevel@tonic-gate gss_OID_set_desc *copy; 5070Sstevel@tonic-gate OM_uint32 minor = 0; 5080Sstevel@tonic-gate OM_uint32 major = GSS_S_COMPLETE; 5090Sstevel@tonic-gate OM_uint32 index; 5100Sstevel@tonic-gate 511*9698SPeter.Shoults@Sun.COM if (minor_status != NULL) 5120Sstevel@tonic-gate *minor_status = 0; 5130Sstevel@tonic-gate 514*9698SPeter.Shoults@Sun.COM if (new_oidset != NULL) 515*9698SPeter.Shoults@Sun.COM *new_oidset = GSS_C_NO_OID_SET; 516*9698SPeter.Shoults@Sun.COM 517*9698SPeter.Shoults@Sun.COM if (oidset == GSS_C_NO_OID_SET) 5180Sstevel@tonic-gate return (GSS_S_CALL_INACCESSIBLE_READ); 5190Sstevel@tonic-gate 5200Sstevel@tonic-gate if (new_oidset == NULL) 5210Sstevel@tonic-gate return (GSS_S_CALL_INACCESSIBLE_WRITE); 5220Sstevel@tonic-gate 5230Sstevel@tonic-gate if ((copy = (gss_OID_set_desc *) calloc(1, sizeof (*copy))) == NULL) { 5240Sstevel@tonic-gate major = GSS_S_FAILURE; 5250Sstevel@tonic-gate goto done; 5260Sstevel@tonic-gate } 5270Sstevel@tonic-gate 5280Sstevel@tonic-gate if ((copy->elements = (gss_OID_desc *) 5290Sstevel@tonic-gate calloc(oidset->count, sizeof (*copy->elements))) == NULL) { 5300Sstevel@tonic-gate major = GSS_S_FAILURE; 5310Sstevel@tonic-gate goto done; 5320Sstevel@tonic-gate } 5330Sstevel@tonic-gate copy->count = oidset->count; 5340Sstevel@tonic-gate 5350Sstevel@tonic-gate for (index = 0; index < copy->count; index++) { 5360Sstevel@tonic-gate gss_OID_desc *out = ©->elements[index]; 5370Sstevel@tonic-gate gss_OID_desc *in = &oidset->elements[index]; 5380Sstevel@tonic-gate 5390Sstevel@tonic-gate if ((out->elements = (void *) malloc(in->length)) == NULL) { 5400Sstevel@tonic-gate major = GSS_S_FAILURE; 5410Sstevel@tonic-gate goto done; 5420Sstevel@tonic-gate } 5430Sstevel@tonic-gate (void) memcpy(out->elements, in->elements, in->length); 5440Sstevel@tonic-gate out->length = in->length; 5450Sstevel@tonic-gate } 5460Sstevel@tonic-gate 5470Sstevel@tonic-gate *new_oidset = copy; 5480Sstevel@tonic-gate done: 5490Sstevel@tonic-gate if (major != GSS_S_COMPLETE) { 5500Sstevel@tonic-gate (void) gss_release_oid_set(&minor, ©); 5510Sstevel@tonic-gate } 5520Sstevel@tonic-gate 5530Sstevel@tonic-gate return (major); 5540Sstevel@tonic-gate } 555