From babaa573efa8ead826e4a97932d2eeb1670aa6cb Mon Sep 17 00:00:00 2001 From: Luke Howard Date: Mon, 20 Sep 2010 12:27:08 +0000 Subject: gss_export_name_composite support for mechanisms that don't implement it git-svn-id: svn://anonsvn.mit.edu/krb5/users/lhoward/namingexts-mechglue@24334 dc483132-0cff-0310-8789-dd5450dbe970 --- src/lib/gssapi/generic/gssapi.hin | 2 + src/lib/gssapi/generic/util_buffer.c | 8 +- src/lib/gssapi/krb5/gssapi_krb5.c | 2 +- src/lib/gssapi/mechglue/g_canon_name.c | 9 +- src/lib/gssapi/mechglue/g_del_name_attr.c | 3 + src/lib/gssapi/mechglue/g_dup_name.c | 8 ++ src/lib/gssapi/mechglue/g_get_name_attr.c | 10 +- src/lib/gssapi/mechglue/g_glue.c | 81 +----------- src/lib/gssapi/mechglue/g_imp_name.c | 137 +++++++++++++++++--- src/lib/gssapi/mechglue/g_inq_name.c | 23 +++- src/lib/gssapi/mechglue/g_nameattr.c | 205 ++++++++++++++++++++++-------- src/lib/gssapi/mechglue/g_set_name_attr.c | 3 + src/lib/gssapi/mechglue/mglueP.h | 7 +- 13 files changed, 339 insertions(+), 159 deletions(-) diff --git a/src/lib/gssapi/generic/gssapi.hin b/src/lib/gssapi/generic/gssapi.hin index fb82e3c..354d9f6 100644 --- a/src/lib/gssapi/generic/gssapi.hin +++ b/src/lib/gssapi/generic/gssapi.hin @@ -408,6 +408,8 @@ GSS_DLLIMP extern gss_OID GSS_C_NT_ANONYMOUS; */ GSS_DLLIMP extern gss_OID GSS_C_NT_EXPORT_NAME; +GSS_DLLIMP extern gss_OID GSS_C_NT_COMPOSITE_EXPORT; + /* Function Prototypes */ OM_uint32 KRB5_CALLCONV diff --git a/src/lib/gssapi/generic/util_buffer.c b/src/lib/gssapi/generic/util_buffer.c index aabed4b..62395ec 100644 --- a/src/lib/gssapi/generic/util_buffer.c +++ b/src/lib/gssapi/generic/util_buffer.c @@ -46,6 +46,12 @@ int g_make_string_buffer(const char *str, gss_buffer_t buffer) int g_duplicate_buffer(const gss_buffer_t src, gss_buffer_t dst) { + if (src->value == NULL) { + dst->value = NULL; + dst->length = 0; + return 1; + } + dst->value = malloc(src->length); if (dst->value == NULL) { dst->length = 0; @@ -55,5 +61,5 @@ int g_duplicate_buffer(const gss_buffer_t src, gss_buffer_t dst) memcpy(dst->value, src->value, src->length); dst->length = src->length; - return 0; + return 1; } diff --git a/src/lib/gssapi/krb5/gssapi_krb5.c b/src/lib/gssapi/krb5/gssapi_krb5.c index ba1dbeb..d902b36 100644 --- a/src/lib/gssapi/krb5/gssapi_krb5.c +++ b/src/lib/gssapi/krb5/gssapi_krb5.c @@ -692,7 +692,7 @@ static struct gss_config krb5_mechanism = { krb5_gss_get_name_attribute, krb5_gss_set_name_attribute, krb5_gss_delete_name_attribute, - krb5_gss_export_name_composite, + NULL, krb5_gss_map_name_to_any, krb5_gss_release_any_name_mapping, krb5_gss_pseudo_random, diff --git a/src/lib/gssapi/mechglue/g_canon_name.c b/src/lib/gssapi/mechglue/g_canon_name.c index 3d371c0..03d36ad 100644 --- a/src/lib/gssapi/mechglue/g_canon_name.c +++ b/src/lib/gssapi/mechglue/g_canon_name.c @@ -97,6 +97,7 @@ gss_name_t *output_name; out_union->name_type = 0; out_union->external_name = 0; out_union->loopback = out_union; + out_union->attributes = NULL; /* Allocate the buffer for the user specified representation */ if (gssint_create_copy_buffer(in_union->external_name, @@ -112,7 +113,13 @@ gss_name_t *output_name; goto allocation_failure; } } - + if (in_union->attributes) { + major_status = gssint_duplicate_name_attributes(minor_status, + in_union->attributes, + &out_union->attributes); + if (major_status != GSS_S_COMPLETE) + goto allocation_failure; + } } /* diff --git a/src/lib/gssapi/mechglue/g_del_name_attr.c b/src/lib/gssapi/mechglue/g_del_name_attr.c index b72ee3b..a12ac8b 100644 --- a/src/lib/gssapi/mechglue/g_del_name_attr.c +++ b/src/lib/gssapi/mechglue/g_del_name_attr.c @@ -49,6 +49,9 @@ gss_delete_name_attribute(OM_uint32 *minor_status, union_name = (gss_union_name_t)name; + if (union_name->attributes != NULL) + return GSS_S_UNAVAILABLE; + if (union_name->mech_type == GSS_C_NO_OID) return GSS_S_UNAVAILABLE; diff --git a/src/lib/gssapi/mechglue/g_dup_name.c b/src/lib/gssapi/mechglue/g_dup_name.c index 9312de7..17763bb 100644 --- a/src/lib/gssapi/mechglue/g_dup_name.c +++ b/src/lib/gssapi/mechglue/g_dup_name.c @@ -80,6 +80,7 @@ gss_name_t *dest_name; dest_union->mech_name = 0; dest_union->name_type = 0; dest_union->external_name = 0; + dest_union->attributes = NULL; /* Now copy the external representaion */ if (gssint_create_copy_buffer(src_union->external_name, @@ -116,6 +117,13 @@ gss_name_t *dest_name; goto allocation_failure; } + if (src_union->attributes) { + major_status = gssint_duplicate_name_attributes(minor_status, + src_union->attributes, + &dest_union->attributes); + if (major_status != GSS_S_COMPLETE) + goto allocation_failure; + } dest_union->loopback = dest_union; *dest_name = (gss_name_t)dest_union; diff --git a/src/lib/gssapi/mechglue/g_get_name_attr.c b/src/lib/gssapi/mechglue/g_get_name_attr.c index a83ebf8..59c2af8 100644 --- a/src/lib/gssapi/mechglue/g_get_name_attr.c +++ b/src/lib/gssapi/mechglue/g_get_name_attr.c @@ -58,6 +58,14 @@ gss_get_name_attribute(OM_uint32 *minor_status, *authenticated = 0; if (complete != NULL) *complete = 0; + if (value != NULL) { + value->value = NULL; + value->length = 0; + } + if (display_value != NULL) { + display_value->value = NULL; + display_value->length = 0; + } *minor_status = 0; @@ -66,7 +74,7 @@ gss_get_name_attribute(OM_uint32 *minor_status, if (union_name->attributes != NULL) { status = gssint_get_name_attribute(minor_status, union_name->attributes, - attr_name, + attr, authenticated, complete, value, diff --git a/src/lib/gssapi/mechglue/g_glue.c b/src/lib/gssapi/mechglue/g_glue.c index 3de298c..3d2f128 100644 --- a/src/lib/gssapi/mechglue/g_glue.c +++ b/src/lib/gssapi/mechglue/g_glue.c @@ -288,86 +288,6 @@ OM_uint32 gssint_get_mech_type(OID, token) * Internal routines to get and release an internal mechanism name */ -#if 0 -static OM_uint32 -import_internal_name_composite(OM_uint32 *minor_status, - gss_mechanism mech, - gss_union_name_t union_name, - gss_name_t *internal_name) -{ - OM_uint32 status, tmp; - gss_mechanism name_mech; - gss_buffer_desc composite_name; - - if (mech->gss_import_name == NULL) - return (GSS_S_UNAVAILABLE); - - name_mech = gssint_get_mechanism(union_name->mech_type); - if (name_mech == NULL) - return (GSS_S_BAD_MECH); - - if (name_mech->gss_export_name_composite == NULL) - return (GSS_S_UNAVAILABLE); - - composite_name.length = 0; - composite_name.value = NULL; - - status = (*name_mech->gss_export_name_composite)(minor_status, - union_name->mech_name, - &composite_name); - if (GSS_ERROR(status)) - return (status); - - status = (*mech->gss_import_name)(minor_status, - &composite_name, - gss_nt_exported_name, - internal_name); - - gss_release_buffer(&tmp, &composite_name); - - return (status); -} -#endif - -OM_uint32 gssint_import_internal_name (minor_status, mech_type, union_name, - internal_name) -OM_uint32 *minor_status; -gss_OID mech_type; -gss_union_name_t union_name; -gss_name_t *internal_name; -{ - OM_uint32 status; - gss_mechanism mech; - - mech = gssint_get_mechanism (mech_type); - if (mech == NULL) - return (GSS_S_BAD_MECH); - -#if 0 - /* Try composite name, it will preserve any extended attributes */ - if (union_name->mech_type && union_name->mech_name) { - status = import_internal_name_composite(minor_status, - mech, - union_name, - internal_name); - if (status == GSS_S_COMPLETE) - return (GSS_S_COMPLETE); - } -#endif - - if (mech->gss_import_name == NULL) - return (GSS_S_UNAVAILABLE); - - status = mech->gss_import_name(minor_status, - union_name->external_name, - union_name->name_type, - internal_name); - if (status != GSS_S_COMPLETE) - map_error(minor_status, mech); - - return (status); -} - OM_uint32 gssint_export_internal_name(minor_status, mech_type, internal_name, name_buf) OM_uint32 *minor_status; @@ -595,6 +515,7 @@ OM_uint32 gssint_convert_name_to_union_name(minor_status, mech, union_name->mech_name = internal_name; union_name->name_type = 0; union_name->external_name = 0; + union_name->attributes = NULL; major_status = generic_gss_copy_oid(minor_status, &mech->mech_type, &union_name->mech_type); diff --git a/src/lib/gssapi/mechglue/g_imp_name.c b/src/lib/gssapi/mechglue/g_imp_name.c index 5cf713f..27e99e0 100644 --- a/src/lib/gssapi/mechglue/g_imp_name.c +++ b/src/lib/gssapi/mechglue/g_imp_name.c @@ -36,7 +36,12 @@ #include /* local function to import GSS_C_EXPORT_NAME names */ -static OM_uint32 importExportName(OM_uint32 *, gss_union_name_t); +static OM_uint32 +importExportName(OM_uint32 *minor_status, + gss_union_name_t union_name, + gss_OID *mech_type, + gss_name_t *mech_name, + gss_name_attribute_t *attrs); static OM_uint32 val_imp_name_args( @@ -109,6 +114,7 @@ gss_name_t * output_name; union_name->mech_name = 0; union_name->name_type = 0; union_name->external_name = 0; + union_name->attributes = NULL; /* * All we do here is record the external name and name_type. @@ -144,8 +150,13 @@ gss_name_t * output_name; * do however make this an MN for names of GSS_C_NT_EXPORT_NAME type. */ if (input_name_type != GSS_C_NULL_OID && - g_OID_equal(input_name_type, GSS_C_NT_EXPORT_NAME)) { - major_status = importExportName(minor_status, union_name); + (g_OID_equal(input_name_type, GSS_C_NT_EXPORT_NAME) || + g_OID_equal(input_name_type, GSS_C_NT_COMPOSITE_EXPORT))) { + major_status = importExportName(minor_status, + union_name, + &union_name->mech_type, + &union_name->mech_name, + &union_name->attributes); if (major_status != GSS_S_COMPLETE) goto allocation_failure; } @@ -182,9 +193,16 @@ importCompositeName(OM_uint32 *minor_status, gss_name_attribute_t head = NULL, *pNext = &head; size_t remain = name_buf->length; unsigned char *p = (unsigned char *)name_buf->value; + ssize_t attrCount; *pAttributes = NULL; + if (remain < 4) + return GSS_S_BAD_NAME; + + TREAD_INT(p, attrCount, 1); + remain -= 4; + do { gss_name_attribute_t attr; @@ -192,8 +210,13 @@ importCompositeName(OM_uint32 *minor_status, &p, &remain); if (GSS_ERROR(status)) break; + + attrCount--; } while (remain != 0); + if (attrCount != 0) + status = GSS_S_BAD_NAME; + if (GSS_ERROR(status)) gssint_release_name_attributes(&tmpMinor, &head); else @@ -210,15 +233,18 @@ static const unsigned int mechOidLenLen = 2; static const unsigned int nameTypeLenLen = 2; static OM_uint32 -importExportName(minor, unionName) - OM_uint32 *minor; - gss_union_name_t unionName; +importExportName(OM_uint32 *minor, + gss_union_name_t unionName, + gss_OID *mech_type, + gss_name_t *mech_name, + gss_name_attribute_t *attributes) { gss_OID_desc mechOid; gss_buffer_desc expName; unsigned char *buf; gss_mechanism mech; - OM_uint32 major, mechOidLen, nameLen, curLength; + OM_uint32 major, tmpMinor; + OM_uint32 mechOidLen, nameLen, curLength; unsigned int bytes; int composite; @@ -236,6 +262,15 @@ importExportName(minor, unionName) return (GSS_S_DEFECTIVE_TOKEN); composite = (buf[1] == 0x02); + /* + * MIT 1.8 emits composite tokens with GSS_C_NT_EXPORT, because + * GSS_C_NT_COMPOSITE_EXPORT was not defined then. So accept + * this, but if the new OID is specified, require composite + * tokens. + */ + if (g_OID_equal(unionName->name_type, GSS_C_NT_COMPOSITE_EXPORT) && + composite == 0) + return (GSS_S_DEFECTIVE_TOKEN); buf += expNameTokIdLen; @@ -286,15 +321,20 @@ importExportName(minor, unionName) */ if (composite ? mech->gss_export_name_composite : mech->gss_export_name) { major = mech->gss_import_name(minor, - &expName, (gss_OID)GSS_C_NT_EXPORT_NAME, - &unionName->mech_name); + &expName, + composite + ? (gss_OID)GSS_C_NT_COMPOSITE_EXPORT + : (gss_OID)GSS_C_NT_EXPORT_NAME, + mech_name); if (major != GSS_S_COMPLETE) map_error(minor, mech); else { major = generic_gss_copy_oid(minor, &mechOid, - &unionName->mech_type); - if (major != GSS_S_COMPLETE) + mech_type); + if (major != GSS_S_COMPLETE) { + gssint_release_internal_name(&tmpMinor, &mechOid, mech_name); map_errcode(minor); + } } return (major); } @@ -325,7 +365,9 @@ importExportName(minor, unionName) /* * we use < here because bad code in rpcsec_gss rounds up exported * name token lengths and pads with nulls, otherwise != would be - * appropriate + * appropriate, for the non-composite name case (the composite + * name is appended to the end of the simple name, so an equality + * check would be inappropriate) */ curLength += nameLen; /* this is the total length */ if (expName.length < curLength) @@ -384,25 +426,80 @@ importExportName(minor, unionName) expName.length = nameLen; expName.value = nameLen ? (void *)buf : NULL; major = mech->gss_import_name(minor, &expName, - GSS_C_NULL_OID, &unionName->mech_name); + GSS_C_NULL_OID, mech_name); if (major != GSS_S_COMPLETE) { map_error(minor, mech); return (major); } - major = generic_gss_copy_oid(minor, &mechOid, &unionName->mech_type); + major = generic_gss_copy_oid(minor, &mechOid, mech_type); if (major != GSS_S_COMPLETE) { map_errcode(minor); + gssint_release_internal_name(&tmpMinor, &mechOid, mech_name); + return (major); } - if (composite) { - expName.length = curLength - nameLen; - expName.value = buf + nameLen; + if (composite && attributes != NULL) { + expName.length = unionName->external_name->length - curLength; + expName.value = buf + nameLen; - major = importCompositeName(minor, &expName, &unionName->attributes); - if (major != GSS_S_COMPLETE) - return major; + major = importCompositeName(minor, &expName, attributes); + if (major != GSS_S_COMPLETE) { + gssint_release_internal_name(&tmpMinor, &mechOid, mech_name); + return (major); + } } return major; } /* importExportName */ + +OM_uint32 +gssint_import_internal_name(OM_uint32 *minor_status, + gss_OID mech_type, + gss_union_name_t union_name, + gss_name_t *internal_name) +{ + OM_uint32 status, tmpMinor; + gss_mechanism mech; + + /* + * This path allows us to take advantage of internal import- + * export name semantics (for use with self-exported composite + * names). Otherwise, a mechanism that supports naming extensions + * but not gss_export_name_composite will fail parsing a + * composite name. + */ + if (union_name->name_type != GSS_C_NULL_OID && + (g_OID_equal(union_name->name_type, GSS_C_NT_EXPORT_NAME) || + g_OID_equal(union_name->name_type, GSS_C_NT_COMPOSITE_EXPORT))) { + gss_OID actualMech = GSS_C_NO_OID; + status = importExportName(minor_status, + union_name, + &actualMech, + internal_name, + NULL); + if (status == GSS_S_COMPLETE && + !g_OID_equal(mech_type, actualMech)) { + gssint_release_internal_name(&tmpMinor, mech_type, internal_name); + status = GSS_S_BAD_MECH; + } + + return (status); + } + + mech = gssint_get_mechanism (mech_type); + if (mech == NULL) + return (GSS_S_BAD_MECH); + + if (mech->gss_import_name == NULL) + return (GSS_S_UNAVAILABLE); + + status = mech->gss_import_name(minor_status, + union_name->external_name, + union_name->name_type, + internal_name); + if (status != GSS_S_COMPLETE) + map_error(minor_status, mech); + + return (status); +} diff --git a/src/lib/gssapi/mechglue/g_inq_name.c b/src/lib/gssapi/mechglue/g_inq_name.c index b2681ea..c800df1 100644 --- a/src/lib/gssapi/mechglue/g_inq_name.c +++ b/src/lib/gssapi/mechglue/g_inq_name.c @@ -50,16 +50,35 @@ gss_inquire_name(OM_uint32 *minor_status, if (MN_mech != NULL) *MN_mech = GSS_C_NO_OID; + if (name_is_MN != NULL) + name_is_MN = 0; + if (attrs != NULL) *attrs = GSS_C_NO_BUFFER_SET; *minor_status = 0; union_name = (gss_union_name_t)name; + if (union_name->attributes != NULL) { + gss_name_attribute_t attr; + + status = GSS_S_COMPLETE; + + for (attr = union_name->attributes; attr != NULL; attr = attr->next) { + status = gss_add_buffer_set_member(minor_status, &attr->attribute, + attrs); + if (GSS_ERROR(status)) + break; + } + + if (GSS_ERROR(status)) + gss_release_buffer_set(&tmp, attrs); + + return status; + } + if (union_name->mech_type == GSS_C_NO_OID) { /* We don't yet support non-mechanism attributes */ - if (name_is_MN != NULL) - name_is_MN = 0; *minor_status = 0; return GSS_S_COMPLETE; } diff --git a/src/lib/gssapi/mechglue/g_nameattr.c b/src/lib/gssapi/mechglue/g_nameattr.c index be254d4..37c1fa9 100644 --- a/src/lib/gssapi/mechglue/g_nameattr.c +++ b/src/lib/gssapi/mechglue/g_nameattr.c @@ -26,13 +26,92 @@ #include "mglueP.h" +static OM_uint32 +duplicateNameAttribute(OM_uint32 *minor_status, + gss_name_attribute_t src, + gss_name_attribute_t *pDst) +{ + OM_uint32 tmpMinor; + gss_name_attribute_t dst; + size_t i; + + dst = calloc(1, sizeof(gss_name_attribute_desc)); + if (dst == NULL) + goto alloc_fail; + + if (!g_duplicate_buffer(&src->attribute, &dst->attribute)) + goto alloc_fail; + + dst->authenticated = src->authenticated; + dst->complete = src->complete; + + if (src->values.count > 0) { + dst->values.elements = calloc(src->values.count, + sizeof(gss_buffer_desc)); + if (dst->values.elements == NULL) + goto alloc_fail; + + dst->display_values.elements = calloc(src->values.count, + sizeof(gss_buffer_desc)); + if (dst->display_values.elements == NULL) + goto alloc_fail; + + for (i = 0; i < src->values.count; i++) { + if (!g_duplicate_buffer(&src->values.elements[i], + &dst->values.elements[i])) + goto alloc_fail; + if (!g_duplicate_buffer(&src->display_values.elements[i], + &dst->display_values.elements[i])) + goto alloc_fail; + } + } + + *pDst = dst; + return GSS_S_COMPLETE; + +alloc_fail: + gssint_release_name_attribute(&tmpMinor, &dst); + *minor_status = ENOMEM; + return GSS_S_FAILURE; +} + +OM_uint32 +gssint_duplicate_name_attributes(OM_uint32 *minor_status, + gss_name_attribute_t srcAttrs, + gss_name_attribute_t *pDstAttrs) +{ + gss_name_attribute_t srcAttr; + gss_name_attribute_t dstAttrHead = NULL, *pDstAttr = &dstAttrHead; + OM_uint32 status, tmpMinor; + + for (srcAttr = srcAttrs; srcAttr != NULL; srcAttr = srcAttr->next) { + gss_name_attribute_t dstAttr; + + status = duplicateNameAttribute(minor_status, srcAttr, &dstAttr); + if (GSS_ERROR(status)) + goto cleanup; + + *pDstAttr = dstAttr; + pDstAttr = &dstAttr->next; + } + + *pDstAttrs = dstAttrHead; + status = GSS_S_COMPLETE; + +cleanup: + if (GSS_ERROR(status)) + gssint_release_name_attributes(&tmpMinor, &dstAttrHead); + + return status; +} + OM_uint32 gssint_release_name_attribute(OM_uint32 *minor_status, - gss_name_attribute_t *pAttribute) + gss_name_attribute_t *pAttr) { OM_uint32 tmpMinor; size_t i; - gss_name_attribute_t attr = *pAttribute; + gss_name_attribute_t attr = *pAttr; if (attr != NULL) { gss_release_buffer(&tmpMinor, &attr->attribute); @@ -42,7 +121,7 @@ gssint_release_name_attribute(OM_uint32 *minor_status, gss_release_buffer(&tmpMinor, &attr->display_values.elements[i]); } free(attr); - *pAttribute = NULL; + *pAttr = NULL; } return GSS_S_COMPLETE; @@ -62,22 +141,8 @@ gssint_get_name_attribute(OM_uint32 *minor_status, int i = *more; OM_uint32 tmpMinor; - if (authenticated != NULL) - *authenticated = 0; - if (complete != NULL) - *complete = 0; *more = 0; - if (value != NULL) { - value->value = NULL; - value->length = 0; - } - - if (display_value != NULL) { - display_value->value = NULL; - display_value->length = 0; - } - for (attr = attributes; attr != NULL; attr = attr->next) { if (attr->attribute.length == attr_name->length && !memcmp(attr->attribute.value, attr_name->value, attr_name->length)) { @@ -94,25 +159,51 @@ gssint_get_name_attribute(OM_uint32 *minor_status, else if ((size_t)i >= attr->values.count) return GSS_S_UNAVAILABLE; - if (value != NULL && - !g_duplicate_buffer(&attr->values.elements[i], value)) { - *minor_status = ENOMEM; - return GSS_S_FAILURE; - } - if (display_value != NULL && - !g_duplicate_buffer(&attr->display_values.elements[i], display_value)) { - gss_release_buffer(&tmpMinor, value); - return GSS_S_FAILURE; + if (attr->values.count > 0) { + if (value != NULL && + !g_duplicate_buffer(&attr->values.elements[i], value)) { + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + if (display_value != NULL && + !g_duplicate_buffer(&attr->display_values.elements[i], + display_value)) { + gss_release_buffer(&tmpMinor, value); + return GSS_S_FAILURE; + } } - *authenticated = attr->authenticated; - *complete = attr->complete; + if (authenticated != NULL) + *authenticated = attr->authenticated; + if (complete != NULL) + *complete = attr->complete; if (attr->values.count > (size_t)++i) *more = i; return GSS_S_COMPLETE; } +/* + * An encoded attribute looks like + * + * uint32 attribute name length + * char[] attribute name data + * uint32 attribute flags + * uint32 value count + * value[] values + * + * where a value is: + * + * uint32 value length + * char[] value data + * uint32 display value length + * char[] display value data + * + * The encoding of a set of attributes consists of the attribute + * count following by the encoding of each attribute. + * + * All integers are big-endian. + */ static size_t nameAttributeSize(gss_name_attribute_t attr) { @@ -143,6 +234,8 @@ nameAttributeExternalize(OM_uint32 *minor_status, unsigned char *p = *pBuffer; size_t i, remain = *pRemain; + assert(remain >= nameAttributeSize(attr)); + if (attr->authenticated) flags |= NAME_FLAG_AUTHENTICATED; if (attr->complete) @@ -171,49 +264,47 @@ nameAttributeExternalize(OM_uint32 *minor_status, return GSS_S_COMPLETE; } -#define CHECK_REMAIN(len) do { \ - if ((remain) < len) { \ - status = GSS_S_BAD_NAME; \ - goto cleanup; \ - } \ - } while (0) - static OM_uint32 internalizeBuffer(OM_uint32 *minor_status, gss_buffer_desc *buffer, unsigned char **pBuffer, size_t *pRemain) { - OM_uint32 status; unsigned char *p = *pBuffer; size_t remain = *pRemain; - CHECK_REMAIN(4); + if (remain < 4) + return GSS_S_BAD_NAME; + TREAD_INT(p, buffer->length, 1); remain -= 4; - CHECK_REMAIN(buffer->length); + if (remain < buffer->length) + return GSS_S_BAD_NAME; /* Attribute name */ buffer->value = malloc(buffer->length + 1); if (buffer->value == NULL) { *minor_status = ENOMEM; - status = GSS_S_FAILURE; - goto cleanup; + return GSS_S_FAILURE; } + memcpy(buffer->value, p, buffer->length); ((char *)buffer->value)[buffer->length] = '\0'; - p += buffer->length; - remain -= buffer->length; + *pBuffer = p + buffer->length; + *pRemain = remain - buffer->length; - *pBuffer = p; - *pRemain = remain; - -cleanup: - return status; + return GSS_S_COMPLETE; } +#define CHECK_REMAIN(len) do { \ + if ((remain) < len) { \ + status = GSS_S_BAD_NAME; \ + goto cleanup; \ + } \ + } while (0) + OM_uint32 gssint_name_attribute_internalize(OM_uint32 *minor_status, gss_name_attribute_t *pAttr, @@ -306,7 +397,7 @@ addNameAttribute(OM_uint32 *minor_status, gss_mechanism mech, gss_name_t internal_name, gss_buffer_t attribute_name, - gss_name_attribute_t *pAttribute, + gss_name_attribute_t *pAttr, gss_name_attribute_t **pNext) { gss_name_attribute_t attr = NULL; @@ -321,6 +412,12 @@ addNameAttribute(OM_uint32 *minor_status, goto cleanup; } + if (!g_duplicate_buffer(attribute_name, &attr->attribute)) { + *minor_status = ENOMEM; + status = GSS_S_FAILURE; + goto cleanup; + } + values = &attr->values; display_values = &attr->display_values; @@ -357,7 +454,7 @@ addNameAttribute(OM_uint32 *minor_status, assert(display_values == &attr->display_values); } - *pAttribute = attr; + *pAttr = attr; if (pNext != NULL) { assert(*pNext != NULL); @@ -375,9 +472,9 @@ cleanup: OM_uint32 gssint_release_name_attributes(OM_uint32 *minor_status, - gss_name_attribute_t *pAttributes) + gss_name_attribute_t *pAttrs) { - gss_name_attribute_t attributes = *pAttributes; + gss_name_attribute_t attributes = *pAttrs; OM_uint32 tmpMinor; if (attributes != NULL) { @@ -389,7 +486,7 @@ gssint_release_name_attributes(OM_uint32 *minor_status, attributes = next; } while (attributes != NULL); - *pAttributes = NULL; + *pAttrs = NULL; } return GSS_S_COMPLETE; @@ -467,6 +564,7 @@ gssint_export_internal_name_composite(OM_uint32 *minor_status, } remain = expName.length; + remain += 4; /* attribute count */ for (i = 0; i < attrNames->count; i++) { status = addNameAttribute(minor_status, @@ -497,6 +595,9 @@ gssint_export_internal_name_composite(OM_uint32 *minor_status, p += expName.length; remain -= expName.length; + TWRITE_INT(p, attrNames->count, 1); + remain -= 4; + for (attr = head; attr != NULL; attr = head->next) { status = nameAttributeExternalize(minor_status, attr, diff --git a/src/lib/gssapi/mechglue/g_set_name_attr.c b/src/lib/gssapi/mechglue/g_set_name_attr.c index 1ec72fc..cd13327 100644 --- a/src/lib/gssapi/mechglue/g_set_name_attr.c +++ b/src/lib/gssapi/mechglue/g_set_name_attr.c @@ -51,6 +51,9 @@ gss_set_name_attribute(OM_uint32 *minor_status, union_name = (gss_union_name_t)name; + if (union_name->attributes != NULL) + return GSS_S_UNAVAILABLE; + if (union_name->mech_type == GSS_C_NO_OID) return GSS_S_UNAVAILABLE; diff --git a/src/lib/gssapi/mechglue/mglueP.h b/src/lib/gssapi/mechglue/mglueP.h index eda4e7f..a6ebfcb 100644 --- a/src/lib/gssapi/mechglue/mglueP.h +++ b/src/lib/gssapi/mechglue/mglueP.h @@ -51,7 +51,7 @@ typedef struct gss_name_struct { gss_OID name_type; gss_buffer_t external_name; /* - * These last two fields are only filled in for mechanism + * These next two fields are only filled in for mechanism * names. */ gss_OID mech_type; @@ -824,4 +824,9 @@ gssint_export_internal_name_composite(OM_uint32 *minor_status, const gss_name_t internal_name, gss_buffer_t name_buf); +OM_uint32 +gssint_duplicate_name_attributes(OM_uint32 *minor_status, + gss_name_attribute_t srcAttrs, + gss_name_attribute_t *pDstAttrs); + #endif /* _GSS_MECHGLUEP_H */ -- cgit v1.1