summaryrefslogtreecommitdiff
path: root/usr/src/lib/libgss/oid_ops.c
diff options
context:
space:
mode:
authorstevel@tonic-gate <none@none>2005-06-14 00:00:00 -0700
committerstevel@tonic-gate <none@none>2005-06-14 00:00:00 -0700
commit7c478bd95313f5f23a4c958a745db2134aa03244 (patch)
treec871e58545497667cbb4b0a4f2daf204743e1fe7 /usr/src/lib/libgss/oid_ops.c
downloadillumos-gate-7c478bd95313f5f23a4c958a745db2134aa03244.tar.gz
OpenSolaris Launch
Diffstat (limited to 'usr/src/lib/libgss/oid_ops.c')
-rw-r--r--usr/src/lib/libgss/oid_ops.c516
1 files changed, 516 insertions, 0 deletions
diff --git a/usr/src/lib/libgss/oid_ops.c b/usr/src/lib/libgss/oid_ops.c
new file mode 100644
index 0000000000..135b45deea
--- /dev/null
+++ b/usr/src/lib/libgss/oid_ops.c
@@ -0,0 +1,516 @@
+/*
+ * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * lib/gssapi/generic/oid_ops.c
+ *
+ * Copyright 1995 by the Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ *
+ */
+
+/*
+ * oid_ops.c - GSS-API V2 interfaces to manipulate OIDs
+ */
+
+#include <mechglueP.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <errno.h>
+#include <ctype.h>
+
+/*
+ * this oid is defined in the oid structure but not exported to
+ * external callers; we must still ensure that we do not delete it.
+ */
+extern const gss_OID_desc * const gss_nt_service_name;
+
+
+OM_uint32
+generic_gss_release_oid(minor_status, oid)
+OM_uint32 *minor_status;
+gss_OID *oid;
+{
+ if (minor_status)
+ *minor_status = 0;
+
+ if (*oid == GSS_C_NO_OID)
+ return (GSS_S_COMPLETE);
+
+ /*
+ * The V2 API says the following!
+ *
+ * gss_release_oid[()] will recognize any of the GSSAPI's own OID
+ * values, and will silently ignore attempts to free these OIDs;
+ * for other OIDs it will call the C free() routine for both the OID
+ * data and the descriptor. This allows applications to freely mix
+ * their own heap allocated OID values with OIDs returned by GSS-API.
+ */
+
+ /*
+ * We use the official OID definitions instead of the unofficial OID
+ * defintions. But we continue to support the unofficial OID
+ * gss_nt_service_name just in case if some gss applications use
+ * the old OID.
+ */
+
+ if ((*oid != GSS_C_NT_USER_NAME) &&
+ (*oid != GSS_C_NT_MACHINE_UID_NAME) &&
+ (*oid != GSS_C_NT_STRING_UID_NAME) &&
+ (*oid != GSS_C_NT_HOSTBASED_SERVICE) &&
+ (*oid != GSS_C_NT_ANONYMOUS) &&
+ (*oid != GSS_C_NT_EXPORT_NAME) &&
+ (*oid != gss_nt_service_name)) {
+ free((*oid)->elements);
+ free(*oid);
+ }
+ *oid = GSS_C_NO_OID;
+ return (GSS_S_COMPLETE);
+}
+
+OM_uint32
+generic_gss_copy_oid(minor_status, oid, new_oid)
+ OM_uint32 *minor_status;
+ const gss_OID oid;
+ gss_OID *new_oid;
+{
+ gss_OID p;
+
+ if (minor_status)
+ *minor_status = 0;
+
+ p = (gss_OID) malloc(sizeof (gss_OID_desc));
+ if (!p) {
+ return (GSS_S_FAILURE);
+ }
+ p->length = oid->length;
+ p->elements = malloc(p->length);
+ if (!p->elements) {
+ free(p);
+ return (GSS_S_FAILURE);
+ }
+ (void) memcpy(p->elements, oid->elements, p->length);
+ *new_oid = p;
+ return (GSS_S_COMPLETE);
+}
+
+
+OM_uint32
+generic_gss_create_empty_oid_set(minor_status, oid_set)
+OM_uint32 *minor_status;
+gss_OID_set *oid_set;
+{
+ if (minor_status)
+ *minor_status = 0;
+
+ if ((*oid_set = (gss_OID_set) malloc(sizeof (gss_OID_set_desc)))) {
+ (void) memset(*oid_set, 0, sizeof (gss_OID_set_desc));
+ return (GSS_S_COMPLETE);
+ } else {
+ return (GSS_S_FAILURE);
+ }
+}
+
+OM_uint32
+generic_gss_add_oid_set_member(minor_status, member_oid, oid_set)
+OM_uint32 *minor_status;
+const gss_OID member_oid;
+gss_OID_set *oid_set;
+{
+ gss_OID elist;
+ gss_OID lastel;
+
+ if (minor_status)
+ *minor_status = 0;
+
+ if (member_oid == NULL || member_oid->length == 0 ||
+ member_oid->elements == NULL)
+ return (GSS_S_CALL_INACCESSIBLE_READ);
+
+ elist = (*oid_set)->elements;
+ /* Get an enlarged copy of the array */
+ if (((*oid_set)->elements = (gss_OID) malloc(((*oid_set)->count+1) *
+ sizeof (gss_OID_desc)))) {
+ /* Copy in the old junk */
+ if (elist)
+ (void) memcpy((*oid_set)->elements, elist,
+ ((*oid_set)->count * sizeof (gss_OID_desc)));
+
+ /* Duplicate the input element */
+ lastel = &(*oid_set)->elements[(*oid_set)->count];
+ if ((lastel->elements =
+ (void *) malloc(member_oid->length))) {
+ /* Success - copy elements */
+ (void) memcpy(lastel->elements, member_oid->elements,
+ member_oid->length);
+ /* Set length */
+ lastel->length = member_oid->length;
+
+ /* Update count */
+ (*oid_set)->count++;
+ if (elist)
+ free(elist);
+ return (GSS_S_COMPLETE);
+ } else
+ free((*oid_set)->elements);
+ }
+ /* Failure - restore old contents of list */
+ (*oid_set)->elements = elist;
+ return (GSS_S_FAILURE);
+}
+
+OM_uint32
+generic_gss_test_oid_set_member(minor_status, member, set, present)
+ OM_uint32 *minor_status;
+ const gss_OID member;
+ const gss_OID_set set;
+ int *present;
+{
+ OM_uint32 i;
+ int result;
+
+ if (minor_status)
+ *minor_status = 0;
+
+ if (member == NULL || set == NULL)
+ return (GSS_S_CALL_INACCESSIBLE_READ);
+
+ if (present == NULL)
+ return (GSS_S_CALL_INACCESSIBLE_WRITE);
+
+ result = 0;
+ for (i = 0; i < set->count; i++) {
+ if ((set->elements[i].length == member->length) &&
+ !memcmp(set->elements[i].elements,
+ member->elements, member->length)) {
+ result = 1;
+ break;
+ }
+ }
+ *present = result;
+ return (GSS_S_COMPLETE);
+}
+
+/*
+ * OID<->string routines. These are uuuuugly.
+ */
+OM_uint32
+generic_gss_oid_to_str(minor_status, oid, oid_str)
+OM_uint32 *minor_status;
+const gss_OID oid;
+gss_buffer_t oid_str;
+{
+ char numstr[128];
+ OM_uint32 number;
+ int numshift;
+ OM_uint32 string_length;
+ OM_uint32 i;
+ unsigned char *cp;
+ char *bp;
+
+ if (minor_status)
+ *minor_status = 0;
+
+ if (oid == NULL || oid->length == 0 || oid->elements == NULL)
+ return (GSS_S_CALL_INACCESSIBLE_READ);
+
+ if (oid_str == NULL)
+ return (GSS_S_CALL_INACCESSIBLE_WRITE);
+
+ /* Decoded according to krb5/gssapi_krb5.c */
+
+ /* First determine the size of the string */
+ string_length = 0;
+ number = 0;
+ numshift = 0;
+ cp = (unsigned char *) oid->elements;
+ number = (OM_uint32) cp[0];
+ (void) sprintf(numstr, "%d ", number/40);
+ string_length += strlen(numstr);
+ (void) sprintf(numstr, "%d ", number%40);
+ string_length += strlen(numstr);
+ for (i = 1; i < oid->length; i++) {
+ if ((OM_uint32) (numshift+7) < (sizeof (OM_uint32)*8)) {
+ number = (number << 7) | (cp[i] & 0x7f);
+ numshift += 7;
+ } else {
+ return (GSS_S_FAILURE);
+ }
+
+ if ((cp[i] & 0x80) == 0) {
+ (void) sprintf(numstr, "%d ", number);
+ string_length += strlen(numstr);
+ number = 0;
+ numshift = 0;
+ }
+ }
+ /*
+ * If we get here, we've calculated the length of "n n n ... n ". Add 4
+ * here for "{ " and "}\0".
+ */
+ string_length += 4;
+ if ((bp = (char *)malloc(string_length))) {
+ (void) strcpy(bp, "{ ");
+ number = (OM_uint32) cp[0];
+ (void) sprintf(numstr, "%d ", number/40);
+ (void) strcat(bp, numstr);
+ (void) sprintf(numstr, "%d ", number%40);
+ (void) strcat(bp, numstr);
+ number = 0;
+ cp = (unsigned char *) oid->elements;
+ for (i = 1; i < oid->length; i++) {
+ number = (number << 7) | (cp[i] & 0x7f);
+ if ((cp[i] & 0x80) == 0) {
+ (void) sprintf(numstr, "%d ", number);
+ (void) strcat(bp, numstr);
+ number = 0;
+ }
+ }
+ (void) strcat(bp, "}");
+ oid_str->length = strlen(bp)+1;
+ oid_str->value = (void *) bp;
+ return (GSS_S_COMPLETE);
+ }
+ return (GSS_S_FAILURE);
+}
+
+/*
+ * This routine will handle 2 types of oid string formats:
+ * 1 - { 1 2 3 4 } where the braces are optional
+ * 2 - 1.2.3.4 this is an alernative format
+ * The first format is mandated by the gss spec. The
+ * second format is popular outside of the gss community so
+ * has been added.
+ */
+OM_uint32
+generic_gss_str_to_oid(minor_status, oid_str, oid)
+OM_uint32 *minor_status;
+const gss_buffer_t oid_str;
+gss_OID *oid;
+{
+ char *cp, *bp, *startp;
+ int brace;
+ int numbuf;
+ int onumbuf;
+ OM_uint32 nbytes;
+ int index;
+ unsigned char *op;
+
+ if (minor_status)
+ *minor_status = 0;
+
+ if (GSS_EMPTY_BUFFER(oid_str))
+ return (GSS_S_CALL_INACCESSIBLE_READ);
+
+ if (oid == NULL)
+ return (GSS_S_CALL_INACCESSIBLE_WRITE);
+
+ brace = 0;
+ bp = (char *)oid_str->value;
+ cp = bp;
+ /* Skip over leading space */
+ while ((bp < &cp[oid_str->length]) && isspace(*bp))
+ bp++;
+ if (*bp == '{') {
+ brace = 1;
+ bp++;
+ }
+ while ((bp < &cp[oid_str->length]) && isspace(*bp))
+ bp++;
+ startp = bp;
+ nbytes = 0;
+
+ /*
+ * The first two numbers are chewed up by the first octet.
+ */
+ if (sscanf(bp, "%d", &numbuf) != 1) {
+ return (GSS_S_FAILURE);
+ }
+ while ((bp < &cp[oid_str->length]) && isdigit(*bp))
+ bp++;
+ while ((bp < &cp[oid_str->length]) &&
+ (isspace(*bp) || *bp == '.'))
+ bp++;
+ if (sscanf(bp, "%d", &numbuf) != 1) {
+ return (GSS_S_FAILURE);
+ }
+ while ((bp < &cp[oid_str->length]) && isdigit(*bp))
+ bp++;
+ while ((bp < &cp[oid_str->length]) &&
+ (isspace(*bp) || *bp == '.'))
+ bp++;
+ nbytes++;
+ while (isdigit(*bp)) {
+ if (sscanf(bp, "%d", &numbuf) != 1) {
+ return (GSS_S_FAILURE);
+ }
+ while (numbuf) {
+ nbytes++;
+ numbuf >>= 7;
+ }
+ while ((bp < &cp[oid_str->length]) && isdigit(*bp))
+ bp++;
+ while ((bp < &cp[oid_str->length]) &&
+ (isspace(*bp) || *bp == '.'))
+ bp++;
+ }
+ if (brace && (*bp != '}')) {
+ return (GSS_S_FAILURE);
+ }
+
+ /*
+ * Phew! We've come this far, so the syntax is good.
+ */
+ if ((*oid = (gss_OID) malloc(sizeof (gss_OID_desc)))) {
+ if (((*oid)->elements = (void *) malloc(nbytes))) {
+ (*oid)->length = nbytes;
+ op = (unsigned char *) (*oid)->elements;
+ bp = startp;
+ (void) sscanf(bp, "%d", &numbuf);
+ while (isdigit(*bp))
+ bp++;
+ while (isspace(*bp) || *bp == '.')
+ bp++;
+ onumbuf = 40*numbuf;
+ (void) sscanf(bp, "%d", &numbuf);
+ onumbuf += numbuf;
+ *op = (unsigned char) onumbuf;
+ op++;
+ while (isdigit(*bp))
+ bp++;
+ while (isspace(*bp) || *bp == '.')
+ bp++;
+ while (isdigit(*bp)) {
+ (void) sscanf(bp, "%d", &numbuf);
+ nbytes = 0;
+ /* Have to fill in the bytes msb-first */
+ onumbuf = numbuf;
+ while (numbuf) {
+ nbytes++;
+ numbuf >>= 7;
+ }
+ numbuf = onumbuf;
+ op += nbytes;
+ index = -1;
+ while (numbuf) {
+ op[index] = (unsigned char)
+ numbuf & 0x7f;
+ if (index != -1)
+ op[index] |= 0x80;
+ index--;
+ numbuf >>= 7;
+ }
+ while (isdigit(*bp))
+ bp++;
+ while (isspace(*bp) || *bp == '.')
+ bp++;
+ }
+ return (GSS_S_COMPLETE);
+ } else {
+ free(*oid);
+ *oid = GSS_C_NO_OID;
+ }
+ }
+ return (GSS_S_FAILURE);
+}
+
+/*
+ * Copyright 1993 by OpenVision Technologies, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appears in all copies and
+ * that both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of OpenVision not be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. OpenVision makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+ * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+OM_uint32
+gss_copy_oid_set(
+ OM_uint32 *minor_status,
+ const gss_OID_set_desc * const oidset,
+ gss_OID_set *new_oidset
+)
+{
+ gss_OID_set_desc *copy;
+ OM_uint32 minor = 0;
+ OM_uint32 major = GSS_S_COMPLETE;
+ OM_uint32 index;
+
+ if (minor_status)
+ *minor_status = 0;
+
+ if (oidset == NULL)
+ return (GSS_S_CALL_INACCESSIBLE_READ);
+
+ if (new_oidset == NULL)
+ return (GSS_S_CALL_INACCESSIBLE_WRITE);
+
+ *new_oidset = NULL;
+
+ if ((copy = (gss_OID_set_desc *) calloc(1, sizeof (*copy))) == NULL) {
+ major = GSS_S_FAILURE;
+ goto done;
+ }
+
+ if ((copy->elements = (gss_OID_desc *)
+ calloc(oidset->count, sizeof (*copy->elements))) == NULL) {
+ major = GSS_S_FAILURE;
+ goto done;
+ }
+ copy->count = oidset->count;
+
+ for (index = 0; index < copy->count; index++) {
+ gss_OID_desc *out = &copy->elements[index];
+ gss_OID_desc *in = &oidset->elements[index];
+
+ if ((out->elements = (void *) malloc(in->length)) == NULL) {
+ major = GSS_S_FAILURE;
+ goto done;
+ }
+ (void) memcpy(out->elements, in->elements, in->length);
+ out->length = in->length;
+ }
+
+ *new_oidset = copy;
+done:
+ if (major != GSS_S_COMPLETE) {
+ (void) gss_release_oid_set(&minor, &copy);
+ }
+
+ return (major);
+}