summaryrefslogtreecommitdiff
path: root/usr/src/lib/libgss/g_glue.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/lib/libgss/g_glue.c')
-rw-r--r--usr/src/lib/libgss/g_glue.c1039
1 files changed, 581 insertions, 458 deletions
diff --git a/usr/src/lib/libgss/g_glue.c b/usr/src/lib/libgss/g_glue.c
index e402dc67b8..49ece2fd35 100644
--- a/usr/src/lib/libgss/g_glue.c
+++ b/usr/src/lib/libgss/g_glue.c
@@ -1,38 +1,44 @@
/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
+#include "mglueP.h"
-#include <mechglueP.h>
#include <stdio.h>
+#ifdef HAVE_STDLIB_H
#include <stdlib.h>
-#include <strings.h>
+#endif
+#include <string.h>
#include <errno.h>
+#include "k5-platform-store_32.h"
+#include "k5-platform-store_16.h"
+/*
+ * SUNW17PACresync
+ * MIT has diff names for these GSS utilities. Solaris needs to change
+ * them globally to get in sync w/MIT.
+ * Revisit for full 1.7 resync.
+ */
+#define gssint_get_modOptions __gss_get_modOptions
+#define gssint_der_length_size der_length_size
+#define gssint_get_der_length get_der_length
+#define gssint_put_der_length put_der_length
+#define gssint_get_mechanism __gss_get_mechanism
+#define gssint_get_mechanism_cred __gss_get_mechanism_cred
+#define gssint_copy_oid_set gss_copy_oid_set
+#define gssint_get_mech_type __gss_get_mech_type
+#define gssint_export_internal_name __gss_export_internal_name
+#define gssint_release_internal_name __gss_release_internal_name
+#define gssint_convert_name_to_union_name __gss_convert_name_to_union_name
+#define gssint_import_internal_name __gss_import_internal_name
+#define gssint_display_internal_name __gss_display_internal_name
+
+
#define MSO_BIT (8*(sizeof (int) - 1)) /* Most significant octet bit */
+extern gss_mechanism *gssint_mechs_array;
+
/*
* This file contains the support routines for the glue layer.
*/
@@ -45,72 +51,72 @@
* by the buffer. Note we return -1 on error.
*/
int
-get_der_length(unsigned char **buf, unsigned int buf_len, unsigned int *bytes)
+gssint_get_der_length(unsigned char **buf, unsigned int buf_len, unsigned int *bytes)
{
- /* p points to the beginning of the buffer */
- unsigned char *p = *buf;
- int length, new_length;
- int octets;
-
- if (buf_len < 1)
- return (-1);
-
- /* We should have at least one byte */
- *bytes = 1;
-
- /*
- * If the High order bit is not set then the length is just the value
- * of *p.
- */
- if (*p < 128) {
- *buf = p+1; /* Advance the buffer */
+ /* p points to the beginning of the buffer */
+ unsigned char *p = *buf;
+ int length, new_length;
+ unsigned int octets;
+
+ if (buf_len < 1)
+ return (-1);
+
+ /* We should have at least one byte */
+ *bytes = 1;
+
+ /*
+ * If the High order bit is not set then the length is just the value
+ * of *p.
+ */
+ if (*p < 128) {
+ *buf = p+1; /* Advance the buffer */
return (*p); /* return the length */
- }
-
- /*
- * if the High order bit is set, then the low order bits represent
- * the number of bytes that contain the DER encoding of the length.
- */
-
- octets = *p++ & 0x7f;
- *bytes += octets;
-
- /* See if the supplied buffer contains enough bytes for the length. */
- if (octets > buf_len - 1)
- return (-1);
-
- /*
- * Calculate a multibyte length. The length is encoded as an
- * unsigned integer base 256.
- */
- for (length = 0; octets; octets--) {
- new_length = (length << 8) + *p++;
- if (new_length < length) /* overflow */
- return (-1);
- length = new_length;
- }
-
- *buf = p; /* Advance the buffer */
-
- return (length);
+ }
+
+ /*
+ * if the High order bit is set, then the low order bits represent
+ * the number of bytes that contain the DER encoding of the length.
+ */
+
+ octets = *p++ & 0x7f;
+ *bytes += octets;
+
+ /* See if the supplied buffer contains enough bytes for the length. */
+ if (octets > buf_len - 1)
+ return (-1);
+
+ /*
+ * Calculate a multibyte length. The length is encoded as an
+ * unsigned integer base 256.
+ */
+ for (length = 0; octets; octets--) {
+ new_length = (length << 8) + *p++;
+ if (new_length < length) /* overflow */
+ return (-1);
+ length = new_length;
+ }
+
+ *buf = p; /* Advance the buffer */
+
+ return (length);
}
/*
* der_length_size: Return the number of bytes to encode a given length.
*/
unsigned int
-der_length_size(unsigned int len)
+gssint_der_length_size(unsigned int len)
{
- int i;
+ int i;
- if (len < 128)
- return (1);
+ if (len < 128)
+ return (1);
- for (i = 0; len; i++) {
- len >>= 8;
- }
+ for (i = 0; len; i++) {
+ len >>= 8;
+ }
- return (i+1);
+ return (i+1);
}
/*
@@ -121,58 +127,60 @@ der_length_size(unsigned int len)
* be encoded in max_len characters.
*/
int
-put_der_length(unsigned length, unsigned char **buf, unsigned int max_len)
+gssint_put_der_length(unsigned int length, unsigned char **buf, unsigned int max_len)
{
- unsigned char *s = *buf, *p;
- unsigned int buf_len = 0;
- int i, first;
-
- /* Oops */
- if (buf == 0 || max_len < 1)
- return (-1);
-
- /* Single byte is the length */
- if (length < 128) {
- *s++ = length;
- *buf = s;
- return (0);
- }
+ unsigned char *s, *p;
+ unsigned int buf_len = 0;
+ int i, first;
- /* First byte contains the number of octets */
- p = s + 1;
-
- /* Running total of the DER encoding length */
- buf_len = 0;
-
- /*
- * Encode MSB first. We do the encoding by setting a shift
- * factor to MSO_BIT (24 for 32 bit words) and then shifting the length
- * by the factor. We then encode the resulting low order byte.
- * We subtract 8 from the shift factor and repeat to ecnode the next
- * byte. We stop when the shift factor is zero or we've run out of
- * buffer to encode into.
- */
- first = 0;
- for (i = MSO_BIT; i >= 0 && buf_len <= max_len; i -= 8) {
- unsigned int v;
- v = (length >> i) & 0xff;
- if ((v) || first) {
- buf_len += 1;
- *p++ = v;
- first = 1;
- }
- }
- if (i >= 0) /* buffer overflow */
- return (-1);
+ /* Oops */
+ if (buf == 0 || max_len < 1)
+ return (-1);
- /*
- * We go back now and set the first byte to be the length with
- * the high order bit set.
- */
- *s = buf_len | 0x80;
- *buf = p;
+ s = *buf;
+ /* Single byte is the length */
+ if (length < 128) {
+ *s++ = length;
+ *buf = s;
return (0);
+ }
+
+ /* First byte contains the number of octets */
+ p = s + 1;
+
+ /* Running total of the DER encoding length */
+ buf_len = 0;
+
+ /*
+ * Encode MSB first. We do the encoding by setting a shift
+ * factor to MSO_BIT (24 for 32 bit words) and then shifting the length
+ * by the factor. We then encode the resulting low order byte.
+ * We subtract 8 from the shift factor and repeat to ecnode the next
+ * byte. We stop when the shift factor is zero or we've run out of
+ * buffer to encode into.
+ */
+ first = 0;
+ for (i = MSO_BIT; i >= 0 && buf_len <= max_len; i -= 8) {
+ unsigned int v;
+ v = (length >> i) & 0xff;
+ if ((v) || first) {
+ buf_len += 1;
+ *p++ = v;
+ first = 1;
+ }
+ }
+ if (i >= 0) /* buffer overflow */
+ return (-1);
+
+ /*
+ * We go back now and set the first byte to be the length with
+ * the high order bit set.
+ */
+ *s = buf_len | 0x80;
+ *buf = p;
+
+ return (0);
}
@@ -180,342 +188,433 @@ put_der_length(unsigned length, unsigned char **buf, unsigned int max_len)
* glue routine for get_mech_type
*
*/
-OM_uint32
-__gss_get_mech_type(OID, token)
- gss_OID OID;
- const gss_buffer_t token;
-{
- unsigned char *buffer_ptr;
- int length;
-
- /*
- * This routine reads the prefix of "token" in order to determine
- * its mechanism type. It assumes the encoding suggested in
- * Appendix B of RFC 1508. This format starts out as follows :
- *
- * tag for APPLICATION 0, Sequence[constructed, definite length]
- * length of remainder of token
- * tag of OBJECT IDENTIFIER
- * length of mechanism OID
- * encoding of mechanism OID
- * <the rest of the token>
- *
- * Numerically, this looks like :
- *
- * 0x60
- * <length> - could be multiple bytes
- * 0x06
- * <length> - assume only one byte, hence OID length < 127
- * <mech OID bytes>
- *
- * The routine fills in the OID value and returns an error as necessary.
- */
+OM_uint32 gssint_get_mech_type_oid(OID, token)
+ gss_OID OID;
+ gss_buffer_t token;
+{
+ unsigned char * buffer_ptr;
+ int length;
+
+ /*
+ * This routine reads the prefix of "token" in order to determine
+ * its mechanism type. It assumes the encoding suggested in
+ * Appendix B of RFC 1508. This format starts out as follows :
+ *
+ * tag for APPLICATION 0, Sequence[constructed, definite length]
+ * length of remainder of token
+ * tag of OBJECT IDENTIFIER
+ * length of mechanism OID
+ * encoding of mechanism OID
+ * <the rest of the token>
+ *
+ * Numerically, this looks like :
+ *
+ * 0x60
+ * <length> - could be multiple bytes
+ * 0x06
+ * <length> - assume only one byte, hence OID length < 127
+ * <mech OID bytes>
+ *
+ * The routine fills in the OID value and returns an error as necessary.
+ */
+
if (OID == NULL)
return (GSS_S_CALL_INACCESSIBLE_WRITE);
if ((token == NULL) || (token->value == NULL))
- return (GSS_S_DEFECTIVE_TOKEN);
-
- /* Skip past the APP/Sequnce byte and the token length */
+ return (GSS_S_DEFECTIVE_TOKEN);
+
+ /* Skip past the APP/Sequnce byte and the token length */
+
+ buffer_ptr = (unsigned char *) token->value;
- buffer_ptr = (unsigned char *) token->value;
-
- if (*(buffer_ptr++) != 0x60)
- return (GSS_S_DEFECTIVE_TOKEN);
- length = *buffer_ptr++;
+ if (*(buffer_ptr++) != 0x60)
+ return (GSS_S_DEFECTIVE_TOKEN);
+ length = *buffer_ptr++;
/* check if token length is null */
if (length == 0)
return (GSS_S_DEFECTIVE_TOKEN);
- if (length & 0x80) {
- if ((length & 0x7f) > 4)
- return (GSS_S_DEFECTIVE_TOKEN);
- buffer_ptr += length & 0x7f;
- }
-
- if (*(buffer_ptr++) != 0x06)
- return (GSS_S_DEFECTIVE_TOKEN);
+ if (length & 0x80) {
+ if ((length & 0x7f) > 4)
+ return (GSS_S_DEFECTIVE_TOKEN);
+ buffer_ptr += length & 0x7f;
+ }
+
+ if (*(buffer_ptr++) != 0x06)
+ return (GSS_S_DEFECTIVE_TOKEN);
+
+ OID->length = (OM_uint32) *(buffer_ptr++);
+ OID->elements = (void *) buffer_ptr;
+ return (GSS_S_COMPLETE);
+}
- OID->length = (OM_uint32) *(buffer_ptr++);
- OID->elements = (void *) buffer_ptr;
- return (GSS_S_COMPLETE);
+/*
+ * The following mechanisms do not always identify themselves
+ * per the GSS-API specification, when interoperating with MS
+ * peers. We include the OIDs here so we do not have to link
+ * with the mechanism.
+ */
+static gss_OID_desc gss_ntlm_mechanism_oid_desc =
+ {10, (void *)"\x2b\x06\x01\x04\x01\x82\x37\x02\x02\x0a"};
+static gss_OID_desc gss_spnego_mechanism_oid_desc =
+ {6, (void *)"\x2b\x06\x01\x05\x05\x02"};
+static gss_OID_desc gss_krb5_mechanism_oid_desc =
+ {9, (void *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x02"};
+
+#define NTLMSSP_SIGNATURE "NTLMSSP"
+
+OM_uint32 gssint_get_mech_type(OID, token)
+ gss_OID OID;
+ gss_buffer_t token;
+{
+ /* Check for interoperability exceptions */
+ if (token->length >= sizeof(NTLMSSP_SIGNATURE) &&
+ memcmp(token->value, NTLMSSP_SIGNATURE,
+ sizeof(NTLMSSP_SIGNATURE)) == 0) {
+ *OID = gss_ntlm_mechanism_oid_desc;
+ } else if (token->length != 0 &&
+ ((char *)token->value)[0] == 0x6E) {
+ /* Could be a raw AP-REQ (check for APPLICATION tag) */
+ *OID = gss_krb5_mechanism_oid_desc;
+ } else if (token->length == 0) {
+ *OID = gss_spnego_mechanism_oid_desc;
+ } else {
+ return gssint_get_mech_type_oid(OID, token);
+ }
+
+ return (GSS_S_COMPLETE);
}
/*
* Internal routines to get and release an internal mechanism name
*/
-OM_uint32 __gss_import_internal_name(minor_status, mech_type, union_name,
- internal_name)
+
+#if 0 /* SUNW17PACresync */
+#include "mglueP.h"
+#endif
+
+OM_uint32 gssint_import_internal_name (minor_status, mech_type, union_name,
+ internal_name)
OM_uint32 *minor_status;
-const gss_OID mech_type;
+gss_OID mech_type;
gss_union_name_t union_name;
gss_name_t *internal_name;
{
- OM_uint32 status;
- gss_mechanism mech;
-
- mech = __gss_get_mechanism(mech_type);
- if (mech) {
- if (mech->gss_import_name)
- status = mech->gss_import_name(
- mech->context,
- minor_status,
- union_name->external_name,
- union_name->name_type,
- internal_name);
- else
- status = GSS_S_UNAVAILABLE;
-
- return (status);
- }
-
- return (GSS_S_BAD_MECH);
+ OM_uint32 status;
+ gss_mechanism mech;
+
+ mech = gssint_get_mechanism (mech_type);
+ if (mech) {
+ if (mech->gss_import_name) {
+ status = mech->gss_import_name (
+ mech->context, /* SUNW17PACresync */
+ minor_status,
+ union_name->external_name,
+ union_name->name_type,
+ internal_name);
+ if (status != GSS_S_COMPLETE)
+ map_error(minor_status, mech);
+ } else
+ status = GSS_S_UNAVAILABLE;
+
+ return (status);
+ }
+
+ return (GSS_S_BAD_MECH);
}
-
-OM_uint32 __gss_export_internal_name(minor_status, mech_type,
- internal_name, name_buf)
-OM_uint32 *minor_status;
-const gss_OID mech_type;
-const gss_name_t internal_name;
-gss_buffer_t name_buf;
+OM_uint32 gssint_export_internal_name(minor_status, mech_type,
+ internal_name, name_buf)
+ OM_uint32 *minor_status;
+ const gss_OID mech_type;
+ const gss_name_t internal_name;
+ gss_buffer_t name_buf;
{
- OM_uint32 status;
- gss_mechanism mech;
- gss_buffer_desc dispName;
- gss_OID nameOid;
- unsigned char *buf = NULL;
- const unsigned char tokId[] = "\x04\x01";
- const int tokIdLen = 2;
- const int mechOidLenLen = 2, mechOidTagLen = 1, nameLenLen = 4;
- int mechOidDERLen = 0;
- int mechOidLen = 0;
-
- mech = __gss_get_mechanism(mech_type);
- if (!mech)
- return (GSS_S_BAD_MECH);
-
- if (mech->gss_export_name)
- return (mech->gss_export_name(mech->context,
- minor_status,
- internal_name,
- name_buf));
-
- /*
- * if we are here it is because the mechanism does not provide
- * a gss_export_name so we will use our implementation. We
- * do required that the mechanism define a gss_display_name.
- */
- if (!mech->gss_display_name)
- return (GSS_S_UNAVAILABLE);
-
- /*
- * NOTE: RFC2743 (section 3.2) governs the format of the outer
- * wrapper of exported names; the mechanisms' specs govern
- * the format of the inner portion of the exported name
- * and, for some (e.g., RFC1964, the Kerberos V mech), a
- * generic default as implemented here will do.
- *
- * The outer wrapper of an exported MN is: 2-octet tok Id
- * (0x0401) + 2-octet network-byte order mech OID length + mech
- * oid (in DER format, including DER tag and DER length) +
- * 4-octet network-byte order length of inner portion + inner
- * portion.
- *
- * For the Kerberos V mechanism the inner portion of an exported
- * MN is the display name string and ignores the name type OID
- * altogether. And we hope this will be so for any future
- * mechanisms also, so that factoring name export/import out of
- * the mech and into libgss pays off.
- */
- if ((status = mech->gss_display_name(mech->context,
- minor_status,
- internal_name,
- &dispName,
- &nameOid))
- != GSS_S_COMPLETE)
- return (status);
-
- /* determine the size of the buffer needed */
- mechOidDERLen = der_length_size(mech_type->length);
- name_buf->length = tokIdLen + mechOidLenLen +
- mechOidTagLen + mechOidDERLen +
- mech_type->length +
- nameLenLen + dispName.length;
- if ((name_buf->value = (void*)malloc(name_buf->length)) ==
- (void*)NULL) {
- name_buf->length = 0;
- (void) gss_release_buffer(&status, &dispName);
- return (GSS_S_FAILURE);
- }
-
- /* now create the name ..... */
- buf = (unsigned char *)name_buf->value;
- (void) memset(name_buf->value, 0, name_buf->length);
- (void) memcpy(buf, tokId, tokIdLen);
- buf += tokIdLen;
-
- /* spec allows only 2 bytes for the mech oid length */
- mechOidLen = mechOidDERLen + mechOidTagLen + mech_type->length;
- *buf++ = (mechOidLen & 0xFF00) >> 8;
- *buf++ = (mechOidLen & 0x00FF);
-
- /*
- * DER Encoding of mech OID contains OID Tag (0x06), length and
- * mech OID value
- */
- *buf++ = 0x06;
- if (put_der_length(mech_type->length, &buf,
- (name_buf->length - tokIdLen -2)) != 0) {
- name_buf->length = 0;
- free(name_buf->value);
- (void) gss_release_buffer(&status, &dispName);
- return (GSS_S_FAILURE);
- }
-
- (void) memcpy(buf, mech_type->elements, mech_type->length);
- buf += mech_type->length;
-
- /* spec designates the next 4 bytes for the name length */
- *buf++ = (dispName.length & 0xFF000000) >> 24;
- *buf++ = (dispName.length & 0x00FF0000) >> 16;
- *buf++ = (dispName.length & 0x0000FF00) >> 8;
- *buf++ = (dispName.length & 0X000000FF);
-
- /* for the final ingredient - add the name from gss_display_name */
- (void) memcpy(buf, dispName.value, dispName.length);
-
- /* release the buffer obtained from gss_display_name */
- (void) gss_release_buffer(minor_status, &dispName);
- return (GSS_S_COMPLETE);
-} /* __gss_export_internal_name */
-
+ OM_uint32 status;
+ gss_mechanism mech;
+ gss_buffer_desc dispName;
+ gss_OID nameOid;
+ unsigned char *buf = NULL;
+ const unsigned char tokId[] = "\x04\x01";
+ const unsigned int tokIdLen = 2;
+ const int mechOidLenLen = 2, mechOidTagLen = 1, nameLenLen = 4;
+ int mechOidDERLen = 0;
+ int mechOidLen = 0;
+
+ mech = gssint_get_mechanism(mech_type);
+ if (!mech)
+ return (GSS_S_BAD_MECH);
-OM_uint32 __gss_display_internal_name(minor_status, mech_type, internal_name,
- external_name, name_type)
-OM_uint32 *minor_status;
-const gss_OID mech_type;
-const gss_name_t internal_name;
-gss_buffer_t external_name;
-gss_OID *name_type;
+ if (mech->gss_export_name) {
+ status = mech->gss_export_name(
+ mech->context, /* SUNW17PACresync */
+ minor_status,
+ internal_name,
+ name_buf);
+ if (status != GSS_S_COMPLETE)
+ map_error(minor_status, mech);
+ return status;
+ }
+
+ /*
+ * if we are here it is because the mechanism does not provide
+ * a gss_export_name so we will use our implementation. We
+ * do required that the mechanism define a gss_display_name.
+ */
+ if (!mech->gss_display_name)
+ return (GSS_S_UNAVAILABLE);
+
+ /*
+ * NOTE: RFC2743 (section 3.2) governs the format of the outer
+ * wrapper of exported names; the mechanisms' specs govern
+ * the format of the inner portion of the exported name
+ * and, for some (e.g., RFC1964, the Kerberos V mech), a
+ * generic default as implemented here will do.
+ *
+ * The outer wrapper of an exported MN is: 2-octet tok Id
+ * (0x0401) + 2-octet network-byte order mech OID length + mech
+ * oid (in DER format, including DER tag and DER length) +
+ * 4-octet network-byte order length of inner portion + inner
+ * portion.
+ *
+ * For the Kerberos V mechanism the inner portion of an exported
+ * MN is the display name string and ignores the name type OID
+ * altogether. And we hope this will be so for any future
+ * mechanisms also, so that factoring name export/import out of
+ * the mech and into libgss pays off.
+ */
+ if ((status = mech->gss_display_name(
+ mech->context,
+ minor_status,
+ internal_name,
+ &dispName,
+ &nameOid))
+ != GSS_S_COMPLETE) {
+ map_error(minor_status, mech);
+ return (status);
+ }
+
+ /* determine the size of the buffer needed */
+ mechOidDERLen = gssint_der_length_size(mech_type->length);
+ name_buf->length = tokIdLen + mechOidLenLen +
+ mechOidTagLen + mechOidDERLen +
+ mech_type->length +
+ nameLenLen + dispName.length;
+ if ((name_buf->value = (void*)malloc(name_buf->length)) ==
+ (void*)NULL) {
+ name_buf->length = 0;
+ (void) gss_release_buffer(&status, &dispName);
+ return (GSS_S_FAILURE);
+ }
+
+ /* now create the name ..... */
+ buf = (unsigned char *)name_buf->value;
+ (void) memset(name_buf->value, 0, name_buf->length);
+ (void) memcpy(buf, tokId, tokIdLen);
+ buf += tokIdLen;
+
+ /* spec allows only 2 bytes for the mech oid length */
+ mechOidLen = mechOidDERLen + mechOidTagLen + mech_type->length;
+ store_16_be(mechOidLen, buf);
+ buf += 2;
+
+ /*
+ * DER Encoding of mech OID contains OID Tag (0x06), length and
+ * mech OID value
+ */
+ *buf++ = 0x06;
+ if (gssint_put_der_length(mech_type->length, &buf,
+ (name_buf->length - tokIdLen -2)) != 0) {
+ name_buf->length = 0;
+ free(name_buf->value);
+ (void) gss_release_buffer(&status, &dispName);
+ return (GSS_S_FAILURE);
+ }
+
+ (void) memcpy(buf, mech_type->elements, mech_type->length);
+ buf += mech_type->length;
+
+ /* spec designates the next 4 bytes for the name length */
+ store_32_be(dispName.length, buf);
+ buf += 4;
+
+ /* for the final ingredient - add the name from gss_display_name */
+ (void) memcpy(buf, dispName.value, dispName.length);
+
+ /* release the buffer obtained from gss_display_name */
+ (void) gss_release_buffer(minor_status, &dispName);
+ return (GSS_S_COMPLETE);
+} /* gssint_export_internal_name */
+
+OM_uint32 gssint_display_internal_name (minor_status, mech_type, internal_name,
+ external_name, name_type)
+OM_uint32 *minor_status;
+gss_OID mech_type;
+gss_name_t internal_name;
+gss_buffer_t external_name;
+gss_OID *name_type;
{
- OM_uint32 status;
- gss_mechanism mech;
-
- mech = __gss_get_mechanism(mech_type);
- if (mech) {
- if (mech->gss_display_name)
- status = mech->gss_display_name(
- mech->context,
- minor_status,
- internal_name,
- external_name,
- name_type);
- else
- status = GSS_S_UNAVAILABLE;
-
- return (status);
- }
+ OM_uint32 status;
+ gss_mechanism mech;
+
+ mech = gssint_get_mechanism (mech_type);
+ if (mech) {
+ if (mech->gss_display_name) {
+ status = mech->gss_display_name (
+ mech->context,
+ minor_status,
+ internal_name,
+ external_name,
+ name_type);
+ if (status != GSS_S_COMPLETE)
+ map_error(minor_status, mech);
+ } else
+ status = GSS_S_UNAVAILABLE;
+
+ return (status);
+ }
+
+ return (GSS_S_BAD_MECH);
+}
- return (GSS_S_BAD_MECH);
+OM_uint32 gssint_release_internal_name (minor_status, mech_type, internal_name)
+OM_uint32 *minor_status;
+gss_OID mech_type;
+gss_name_t *internal_name;
+{
+ OM_uint32 status;
+ gss_mechanism mech;
+
+ mech = gssint_get_mechanism (mech_type);
+ if (mech) {
+ if (mech->gss_release_name) {
+ status = mech->gss_release_name (
+ mech->context,
+ minor_status,
+ internal_name);
+ if (status != GSS_S_COMPLETE)
+ map_error(minor_status, mech);
+ } else
+ status = GSS_S_UNAVAILABLE;
+
+ return (status);
+ }
+
+ return (GSS_S_BAD_MECH);
}
-OM_uint32
-__gss_release_internal_name(minor_status, mech_type, internal_name)
-OM_uint32 *minor_status;
-const gss_OID mech_type;
-gss_name_t *internal_name;
+OM_uint32 gssint_delete_internal_sec_context (minor_status,
+ mech_type,
+ internal_ctx,
+ output_token)
+OM_uint32 *minor_status;
+gss_OID mech_type;
+gss_ctx_id_t *internal_ctx;
+gss_buffer_t output_token;
{
- OM_uint32 status;
- gss_mechanism mech;
-
- mech = __gss_get_mechanism(mech_type);
- if (mech) {
- if (mech->gss_release_name)
- status = mech->gss_release_name(
- mech->context,
- minor_status,
- internal_name);
- else
- status = GSS_S_UNAVAILABLE;
-
- return (status);
- }
+ OM_uint32 status;
+ gss_mechanism mech;
+
+ mech = gssint_get_mechanism (mech_type);
+ if (mech) {
+ if (mech->gss_delete_sec_context)
+ status = mech->gss_delete_sec_context (
+ mech->context, /* SUNW17PACresync */
+ minor_status,
+ internal_ctx,
+ output_token);
+ else
+ /* SUNW17PACresync - map error here? */
+ status = GSS_S_UNAVAILABLE;
- return (GSS_S_BAD_MECH);
-}
+ return (status);
+ }
+ return (GSS_S_BAD_MECH);
+}
/*
* This function converts an internal gssapi name to a union gssapi
* name. Note that internal_name should be considered "consumed" by
* this call, whether or not we return an error.
*/
-OM_uint32 __gss_convert_name_to_union_name(minor_status, mech,
- internal_name, external_name)
- OM_uint32 *minor_status;
- gss_mechanism mech;
- gss_name_t internal_name;
- gss_name_t *external_name;
+OM_uint32 gssint_convert_name_to_union_name(minor_status, mech,
+ internal_name, external_name)
+ OM_uint32 *minor_status;
+ gss_mechanism mech;
+ gss_name_t internal_name;
+ gss_name_t *external_name;
{
- OM_uint32 major_status, tmp;
- gss_union_name_t union_name;
-
- union_name = (gss_union_name_t)malloc(sizeof (gss_union_name_desc));
- if (!union_name) {
- goto allocation_failure;
- }
- union_name->mech_type = 0;
- union_name->mech_name = internal_name;
- union_name->name_type = 0;
- union_name->external_name = 0;
-
- major_status = generic_gss_copy_oid(minor_status, &mech->mech_type,
- &union_name->mech_type);
- if (major_status != GSS_S_COMPLETE)
- goto allocation_failure;
-
- union_name->external_name =
- (gss_buffer_t)malloc(sizeof (gss_buffer_desc));
- if (!union_name->external_name) {
- goto allocation_failure;
- }
-
- major_status = mech->gss_display_name(mech->context, minor_status,
- internal_name,
- union_name->external_name,
- &union_name->name_type);
- if (major_status != GSS_S_COMPLETE)
- goto allocation_failure;
-
- *external_name = (gss_name_t)union_name;
- return (GSS_S_COMPLETE);
+ OM_uint32 major_status,tmp;
+ gss_union_name_t union_name;
+
+ union_name = (gss_union_name_t) malloc (sizeof(gss_union_name_desc));
+ if (!union_name) {
+ major_status = GSS_S_FAILURE;
+ *minor_status = ENOMEM;
+ map_errcode(minor_status);
+ goto allocation_failure;
+ }
+ union_name->mech_type = 0;
+ union_name->mech_name = internal_name;
+ union_name->name_type = 0;
+ union_name->external_name = 0;
+
+ major_status = generic_gss_copy_oid(minor_status, &mech->mech_type,
+ &union_name->mech_type);
+ if (major_status != GSS_S_COMPLETE) {
+ map_errcode(minor_status);
+ goto allocation_failure;
+ }
+
+ union_name->external_name =
+ (gss_buffer_t) malloc(sizeof(gss_buffer_desc));
+ if (!union_name->external_name) {
+ major_status = GSS_S_FAILURE;
+ *minor_status = ENOMEM;
+ goto allocation_failure;
+ }
+
+ major_status = mech->gss_display_name(
+ mech->context, /* SUNW17PACresync */
+ minor_status,
+ internal_name,
+ union_name->external_name,
+ &union_name->name_type);
+ if (major_status != GSS_S_COMPLETE) {
+ map_error(minor_status, mech);
+ goto allocation_failure;
+ }
+
+ union_name->loopback = union_name;
+ *external_name = (gss_name_t) union_name;
+ return (GSS_S_COMPLETE);
allocation_failure:
- if (union_name) {
- if (union_name->external_name) {
- if (union_name->external_name->value)
- free(union_name->external_name->value);
- free(union_name->external_name);
- }
- if (union_name->name_type)
- (void) gss_release_oid(&tmp, &union_name->name_type);
- if (union_name->mech_type)
- (void) gss_release_oid(&tmp, &union_name->mech_type);
- free(union_name);
+ if (union_name) {
+ if (union_name->external_name) {
+ if (union_name->external_name->value)
+ free(union_name->external_name->value);
+ free(union_name->external_name);
}
- /*
- * do as the top comment says - since we are now owners of
- * internal_name, we must clean it up
- */
- if (internal_name)
- (void) __gss_release_internal_name(&tmp, &mech->mech_type,
- &internal_name);
-
- return (major_status);
+ if (union_name->name_type)
+ (void) gss_release_oid(&tmp, &union_name->name_type);
+ if (union_name->mech_type)
+ (void) gss_release_oid(&tmp, &union_name->mech_type);
+ free(union_name);
+ }
+ /*
+ * do as the top comment says - since we are now owners of
+ * internal_name, we must clean it up
+ */
+ if (internal_name)
+ (void) gssint_release_internal_name(&tmp, &mech->mech_type,
+ &internal_name);
+ return (major_status);
}
/*
@@ -523,22 +622,45 @@ allocation_failure:
* external union credential.
*/
gss_cred_id_t
-__gss_get_mechanism_cred(union_cred, mech_type)
- const gss_union_cred_t union_cred;
- const gss_OID mech_type;
+gssint_get_mechanism_cred(union_cred, mech_type)
+ gss_union_cred_t union_cred;
+ gss_OID mech_type;
{
- int i;
-
- if (union_cred == (gss_union_cred_t)GSS_C_NO_CREDENTIAL)
- return (GSS_C_NO_CREDENTIAL);
-
- for (i = 0; i < union_cred->count; i++) {
- if (g_OID_equal(mech_type, &union_cred->mechs_array[i]))
- return (union_cred->cred_array[i]);
+ int i;
+
+ if (union_cred == (gss_union_cred_t) GSS_C_NO_CREDENTIAL)
+ return GSS_C_NO_CREDENTIAL;
+
+ /*
+ * SUNW17PACresync
+ * Disable this block as it causes problems for gss_add_cred
+ * for HTTP SSO (and also probably causes STC gss.13 to fail too).
+ */
+#if 0
+ /* SPNEGO mechanism will again call into GSSAPI */
+ if (g_OID_equal(&gss_spnego_mechanism_oid_desc, mech_type))
+ return (gss_cred_id_t)union_cred;
+#endif
+
+ for (i=0; i < union_cred->count; i++) {
+ if (g_OID_equal(mech_type, &union_cred->mechs_array[i]))
+ return union_cred->cred_array[i];
+
+ /* for SPNEGO, check the next-lower set of creds */
+ if (g_OID_equal(&gss_spnego_mechanism_oid_desc, &union_cred->mechs_array[i])) {
+ gss_union_cred_t candidate_cred;
+ gss_cred_id_t sub_cred;
+
+ candidate_cred = (gss_union_cred_t)union_cred->cred_array[i];
+ sub_cred = gssint_get_mechanism_cred(candidate_cred, mech_type);
+
+ if(sub_cred != GSS_C_NO_CREDENTIAL)
+ return sub_cred;
}
- return (GSS_C_NO_CREDENTIAL);
-}
+ }
+ return GSS_C_NO_CREDENTIAL;
+}
/*
* Routine to create and copy the gss_buffer_desc structure.
@@ -546,40 +668,41 @@ __gss_get_mechanism_cred(union_cred, mech_type)
*/
OM_uint32
gssint_create_copy_buffer(srcBuf, destBuf, addNullChar)
- const gss_buffer_t srcBuf;
- gss_buffer_t *destBuf;
- int addNullChar;
+ const gss_buffer_t srcBuf;
+ gss_buffer_t *destBuf;
+ int addNullChar;
{
- gss_buffer_t aBuf;
- int len;
+ gss_buffer_t aBuf;
+ unsigned int len;
- if (destBuf == NULL)
- return (GSS_S_CALL_INACCESSIBLE_WRITE);
+ if (destBuf == NULL)
+ return (GSS_S_CALL_INACCESSIBLE_WRITE);
- *destBuf = 0;
+ *destBuf = 0;
- aBuf = (gss_buffer_t)malloc(sizeof (gss_buffer_desc));
- if (!aBuf)
- return (GSS_S_FAILURE);
+ aBuf = (gss_buffer_t)malloc(sizeof (gss_buffer_desc));
+ if (!aBuf)
+ return (GSS_S_FAILURE);
- if (addNullChar)
- len = srcBuf->length + 1;
- else
- len = srcBuf->length;
+ if (addNullChar)
+ len = srcBuf->length + 1;
+ else
+ len = srcBuf->length;
+
+ if (!(aBuf->value = (void*)malloc(len))) {
+ free(aBuf);
+ return (GSS_S_FAILURE);
+ }
- if (!(aBuf->value = (void*)malloc(len))) {
- free(aBuf);
- return (GSS_S_FAILURE);
- }
+ (void) memcpy(aBuf->value, srcBuf->value, srcBuf->length);
+ aBuf->length = srcBuf->length;
+ *destBuf = aBuf;
- (void) memcpy(aBuf->value, srcBuf->value, srcBuf->length);
- aBuf->length = srcBuf->length;
- *destBuf = aBuf;
+ /* optionally add a NULL character */
+ if (addNullChar)
+ ((char *)aBuf->value)[aBuf->length] = '\0';
- /* optionally add a NULL character */
- if (addNullChar)
- ((char *)aBuf->value)[aBuf->length] = '\0';
+ return (GSS_S_COMPLETE);
+} /* ****** gssint_create_copy_buffer ****** */
- return (GSS_S_COMPLETE);
-} /* ****** __gss_create_copy_buffer ****** */