From: Luke Howard Date: Tue, 21 Sep 2010 10:49:23 +0000 (+0200) Subject: Merge branch 'oldradius' X-Git-Tag: vm/20110310~253 X-Git-Url: http://www.project-moonshot.org/gitweb/?p=mech_eap.orig;a=commitdiff_plain;h=b47c10882ea3409098780eb9608d3008c91f076d;hp=-c Merge branch 'oldradius' Conflicts: mech_eap/accept_sec_context.c mech_eap/init_sec_context.c --- b47c10882ea3409098780eb9608d3008c91f076d diff --combined util_radius.cpp index 97dee6e,7c6552a..2c55bff --- a/util_radius.cpp +++ b/util_radius.cpp @@@ -32,22 -32,69 +32,69 @@@ #include "gssapiP_eap.h" + VALUE_PAIR * + gss_eap_radius_attr_provider::copyAvps(const VALUE_PAIR *src) + { + const VALUE_PAIR *vp; + VALUE_PAIR *dst = NULL, **pDst = &dst; + + for (vp = src; vp != NULL; vp = vp->next) { + VALUE_PAIR *vp2; + + vp2 = (VALUE_PAIR *)GSSEAP_CALLOC(1, sizeof(*vp2)); + if (vp2 == NULL) { + rc_avpair_free(dst); + return NULL; + } + memcpy(vp2, vp, sizeof(*vp)); + vp2->next = NULL; + *pDst = vp2; + pDst = &vp2->next; + } + + return dst; + } + gss_eap_radius_attr_provider::gss_eap_radius_attr_provider(void) { + m_rh = NULL; + m_avps = NULL; m_authenticated = false; } gss_eap_radius_attr_provider::~gss_eap_radius_attr_provider(void) { + if (m_rh != NULL) + rc_config_free(m_rh); + if (m_avps != NULL) + rc_avpair_free(m_avps); + } + + bool + gss_eap_radius_attr_provider::initFromGssCred(const gss_cred_id_t cred) + { + OM_uint32 minor; + + return !GSS_ERROR(gssEapRadiusAllocHandle(&minor, cred, &m_rh)); } bool gss_eap_radius_attr_provider::initFromExistingContext(const gss_eap_attr_ctx *manager, const gss_eap_attr_provider *ctx) { + const gss_eap_radius_attr_provider *radius; + if (!gss_eap_attr_provider::initFromExistingContext(manager, ctx)) return false; + if (!initFromGssCred(GSS_C_NO_CREDENTIAL)) + return false; + + radius = static_cast(ctx); + if (radius->m_avps != NULL) { + m_avps = copyAvps(radius->getAvps()); + } + return true; } @@@ -59,12 -106,54 +106,79 @@@ gss_eap_radius_attr_provider::initFromG if (!gss_eap_attr_provider::initFromGssContext(manager, gssCred, gssCtx)) return false; + if (!initFromGssCred(gssCred)) + return false; + + if (gssCtx != GSS_C_NO_CONTEXT) { + if (gssCtx->acceptorCtx.avps != NULL) { + m_avps = copyAvps(gssCtx->acceptorCtx.avps); + if (m_avps == NULL) + return false; + } + } + return true; } + static bool + alreadyAddedAttributeP(std::vector &attrs, VALUE_PAIR *vp) + { + for (std::vector::const_iterator a = attrs.begin(); + a != attrs.end(); + ++a) { + if (strcmp(vp->name, (*a).c_str()) == 0) + return true; + } + + return false; + } + ++static bool ++isSecretAttributeP(int attrid, int vendor) ++{ ++ bool ret = false; ++ ++ switch (vendor) { ++ case RADIUS_VENDOR_ID_MICROSOFT: ++ switch (attrid) { ++ case RADIUS_VENDOR_ATTR_MS_MPPE_SEND_KEY: ++ case RADIUS_VENDOR_ATTR_MS_MPPE_RECV_KEY: ++ ret = true; ++ break; ++ default: ++ break; ++ } ++ default: ++ break; ++ } ++ ++ return ret; ++} ++ bool gss_eap_radius_attr_provider::getAttributeTypes(gss_eap_attr_enumeration_cb addAttribute, void *data) const { + VALUE_PAIR *vp; + std::vector seen; + + for (vp = m_avps; vp != NULL; vp = vp->next) { + gss_buffer_desc attribute; + ++ if (isSecretAttributeP(ATTRID(vp->attribute), VENDOR(vp->attribute))) ++ continue; ++ + if (alreadyAddedAttributeP(seen, vp)) + continue; + + attribute.value = (void *)vp->name; + attribute.length = strlen(vp->name); + + if (!addAttribute(this, &attribute, data)) + return false; + + seen.push_back(std::string(vp->name)); + } + return true; } @@@ -88,31 -177,147 +202,152 @@@ gss_eap_radius_attr_provider::getAttrib gss_buffer_t display_value, int *more) const { - return false; + OM_uint32 tmpMinor; + gss_buffer_desc strAttr = GSS_C_EMPTY_BUFFER; + DICT_ATTR *d; + int attrid; + char *s; + + /* XXX vendor */ + + duplicateBuffer(*attr, &strAttr); + s = (char *)strAttr.value; + + if (isdigit(((char *)strAttr.value)[0])) { + attrid = strtoul(s, NULL, 10); + } else { + d = rc_dict_findattr(m_rh, (char *)s); + if (d == NULL) { + gss_release_buffer(&tmpMinor, &strAttr); + return false; + } + attrid = d->value; + } + + gss_release_buffer(&tmpMinor, &strAttr); + + return getAttribute(attrid, authenticated, complete, + value, display_value, more); + } + + static bool + isPrintableAttributeP(VALUE_PAIR *vp) + { + size_t i; + + for (i = 0; i < sizeof(vp->strvalue); i++) { + if (!isprint(vp->strvalue[i])) + return false; + } + + return true; } bool - gss_eap_radius_attr_provider::getAttribute(unsigned int attr, + gss_eap_radius_attr_provider::getAttribute(int attrid, + int vendor, int *authenticated, int *complete, gss_buffer_t value, gss_buffer_t display_value, int *more) const { - return false; + OM_uint32 tmpMinor; + VALUE_PAIR *vp; + int i = *more; + int max = 0; + char name[NAME_LENGTH + 1]; + char displayString[AUTH_STRING_LEN + 1]; + gss_buffer_desc valueBuf = GSS_C_EMPTY_BUFFER; + gss_buffer_desc displayBuf = GSS_C_EMPTY_BUFFER; + + *more = 0; + ++ if (isSecretAttributeP(attrid, vendor)) ++ return false; ++ + vp = rc_avpair_get(m_avps, attrid, vendor); + if (vp == NULL) + return false; + + if (i == -1) + i = 0; + + do { + if (i == max) + break; + + max++; + } while ((vp = rc_avpair_get(vp->next, attrid, vendor)) != NULL); + + if (i > max) + return false; + + if (vp->type == PW_TYPE_STRING) { + valueBuf.value = (void *)vp->strvalue; + valueBuf.length = vp->lvalue; + } else { + valueBuf.value = (void *)&vp->lvalue; + valueBuf.length = 4; + } + + if (value != GSS_C_NO_BUFFER) + duplicateBuffer(valueBuf, value); + + if (display_value != GSS_C_NO_BUFFER && + isPrintableAttributeP(vp)) { + if (rc_avpair_tostr(m_rh, vp, name, NAME_LENGTH, + displayString, AUTH_STRING_LEN) != 0) { + gss_release_buffer(&tmpMinor, value); + return false; + } + + displayBuf.value = (void *)displayString; + displayBuf.length = strlen(displayString); + + duplicateBuffer(displayBuf, display_value); + } + + if (authenticated != NULL) + *authenticated = m_authenticated; + if (complete != NULL) + *complete = true; + + if (max > i) + *more = i; + + return true; + } + + bool + gss_eap_radius_attr_provider::getAttribute(int attrid, + int *authenticated, + int *complete, + gss_buffer_t value, + gss_buffer_t display_value, + int *more) const + { - return getAttribute(attrid, 0, authenticated, complete, ++ ++ return getAttribute(ATTRID(attrid), VENDOR(attrid), ++ authenticated, complete, + value, display_value, more); } gss_any_t gss_eap_radius_attr_provider::mapToAny(int authenticated, gss_buffer_t type_id) const { - return (gss_any_t)NULL; + if (authenticated && !m_authenticated) + return (gss_any_t)NULL; + + return (gss_any_t)copyAvps(m_avps); } void gss_eap_radius_attr_provider::releaseAnyNameMapping(gss_buffer_t type_id, gss_any_t input) const { + rc_avpair_free((VALUE_PAIR *)input); } void @@@ -129,6 -334,9 +364,9 @@@ gss_eap_radius_attr_provider::initFromB if (!gss_eap_attr_provider::initFromBuffer(ctx, buffer)) return false; + if (!initFromGssCred(GSS_C_NO_CREDENTIAL)) + return false; + return true; } @@@ -154,6 -362,60 +392,60 @@@ gss_eap_radius_attr_provider::createAtt } OM_uint32 + addAvpFromBuffer(OM_uint32 *minor, + rc_handle *rh, + VALUE_PAIR **vp, + int type, + gss_buffer_t buffer) + { + if (rc_avpair_add(rh, vp, type, buffer->value, buffer->length, 0) == NULL) { + return GSS_S_FAILURE; + } + + return GSS_S_COMPLETE; + } + + OM_uint32 + getBufferFromAvps(OM_uint32 *minor, + VALUE_PAIR *vps, + int type, + gss_buffer_t buffer, + int concat) + { + VALUE_PAIR *vp; + unsigned char *p; + + buffer->length = 0; + buffer->value = NULL; + + vp = rc_avpair_get(vps, type, 0); + if (vp == NULL) + return GSS_S_UNAVAILABLE; + + do { + buffer->length += vp->lvalue; + } while (concat && (vp = rc_avpair_get(vp->next, type, 0)) != NULL); + + buffer->value = GSSEAP_MALLOC(buffer->length); + if (buffer->value == NULL) { + *minor = ENOMEM; + return GSS_S_FAILURE; + } + + p = (unsigned char *)buffer->value; + + for (vp = rc_avpair_get(vps, type, 0); + concat && vp != NULL; + vp = rc_avpair_get(vp->next, type, 0)) { + memcpy(p, vp->strvalue, vp->lvalue); + p += vp->lvalue; + } + + *minor = 0; + return GSS_S_COMPLETE; + } + + OM_uint32 gssEapRadiusAttrProviderInit(OM_uint32 *minor) { return gss_eap_radius_attr_provider::init() @@@ -166,3 -428,32 +458,32 @@@ gssEapRadiusAttrProviderFinalize(OM_uin gss_eap_radius_attr_provider::finalize(); return GSS_S_COMPLETE; } + + OM_uint32 + gssEapRadiusAllocHandle(OM_uint32 *minor, + const gss_cred_id_t cred, + rc_handle **pHandle) + { + rc_handle *rh; + const char *config = RC_CONFIG_FILE; + + *pHandle = NULL; + + if (cred != GSS_C_NO_CREDENTIAL && cred->radiusConfigFile != NULL) + config = cred->radiusConfigFile; + + rh = rc_read_config((char *)config); + if (rh == NULL) { + *minor = errno; + rc_config_free(rh); + return GSS_S_FAILURE; + } + + if (rc_read_dictionary(rh, rc_conf_str(rh, (char *)"dictionary")) != 0) { + *minor = errno; + return GSS_S_FAILURE; + } + + *pHandle = rh; + return GSS_S_COMPLETE; + }