X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=mech_eap%2Futil_radius.cpp;h=9111e209759a34ec1e2f83dbc3bb18e00adcd139;hb=4b54c7cca6526a4f62c71ac311e84a571441ae62;hp=5462acc1f197ea8f030fdcc240c38304fb7e0110;hpb=10a3b578c38207140378a98c024c03d85941f837;p=mech_eap.orig diff --git a/mech_eap/util_radius.cpp b/mech_eap/util_radius.cpp index 5462acc..9111e20 100644 --- a/mech_eap/util_radius.cpp +++ b/mech_eap/util_radius.cpp @@ -96,7 +96,7 @@ gss_eap_radius_attr_provider::initWithGssContext(const gss_eap_attr_ctx *manager return false; /* We assume libradsec validated this for us */ - assert(pairfind(m_vps, PW_MESSAGE_AUTHENTICATOR) != NULL); + GSSEAP_ASSERT(pairfind(m_vps, PW_MESSAGE_AUTHENTICATOR) != NULL); m_authenticated = true; } } @@ -151,11 +151,21 @@ isInternalAttributeP(uint16_t attrid, uint16_t vendor) bool bInternalAttribute = false; /* should have been filtered */ - assert(!isSecretAttributeP(attrid, vendor)); + GSSEAP_ASSERT(!isSecretAttributeP(attrid, vendor)); switch (vendor) { case VENDORPEC_UKERNA: - bInternalAttribute = true; + switch (attrid) { + case PW_GSS_ACCEPTOR_SERVICE_NAME: + case PW_GSS_ACCEPTOR_HOST_NAME: + case PW_GSS_ACCEPTOR_SERVICE_SPECIFIC: + case PW_GSS_ACCEPTOR_REALM_NAME: + case PW_SAML_AAA_ASSERTION: + bInternalAttribute = true; + break; + default: + break; + } break; default: break; @@ -170,6 +180,20 @@ isInternalAttributeP(uint32_t attribute) return isInternalAttributeP(ATTRID(attribute), VENDOR(attribute)); } +static bool +isFragmentedAttributeP(uint16_t attrid, uint16_t vendor) +{ + /* A bit of a hack for the PAC for now. Should be configurable. */ + return (vendor == VENDORPEC_UKERNA) && + !isInternalAttributeP(attrid, vendor); +} + +static bool +isFragmentedAttributeP(uint32_t attribute) +{ + return isFragmentedAttributeP(ATTRID(attribute), VENDOR(attribute)); +} + /* * Copy AVP list, same as paircopy except it filters out attributes * containing keys. @@ -350,6 +374,15 @@ gss_eap_radius_attr_provider::getAttribute(uint32_t attrid, if (i == -1) i = 0; + if (isSecretAttributeP(attrid) || isInternalAttributeP(attrid)) { + return false; + } else if (isFragmentedAttributeP(attrid)) { + return getFragmentedAttribute(attrid, + authenticated, + complete, + value); + } + for (vp = pairfind(m_vps, attrid); vp != NULL; vp = pairfind(vp->next, attrid)) { @@ -372,7 +405,8 @@ gss_eap_radius_attr_provider::getAttribute(uint32_t attrid, duplicateBuffer(valueBuf, value); } - if (display_value != GSS_C_NO_BUFFER) { + if (display_value != GSS_C_NO_BUFFER && + vp->type != PW_TYPE_OCTETS) { char displayString[MAX_STRING_LEN]; gss_buffer_desc displayBuf; @@ -411,6 +445,16 @@ gss_eap_radius_attr_provider::getFragmentedAttribute(uint16_t attribute, } bool +gss_eap_radius_attr_provider::getFragmentedAttribute(uint32_t attrid, + int *authenticated, + int *complete, + gss_buffer_t value) const +{ + return getFragmentedAttribute(ATTRID(attrid), VENDOR(attrid), + authenticated, complete, value); +} + +bool gss_eap_radius_attr_provider::getAttribute(uint16_t attribute, uint16_t vendor, int *authenticated, @@ -446,32 +490,8 @@ gss_eap_radius_attr_provider::releaseAnyNameMapping(gss_buffer_t type_id GSSEAP_ bool gss_eap_radius_attr_provider::init(void) { - struct rs_context *radContext; - gss_eap_attr_ctx::registerProvider(ATTR_TYPE_RADIUS, createAttrContext); -#if 1 - /* - * This hack is necessary in order to force the loading of the global - * dictionary, otherwise accepting reauthentication tokens fails unless - * the acceptor has already accepted a normal authentication token. - */ - if (rs_context_create(&radContext) != 0) - return false; - - if (rs_context_read_config(radContext, RS_CONFIG_FILE) != 0) { - rs_context_destroy(radContext); - return false; - } - - if (rs_context_init_freeradius_dict(radContext, NULL)) { - rs_context_destroy(radContext); - return false; - } - - rs_context_destroy(radContext); -#endif - return true; } @@ -557,8 +577,10 @@ gssEapRadiusGetAvp(OM_uint32 *minor, unsigned char *p; uint32_t attr = VENDORATTR(vendor, attribute); - buffer->length = 0; - buffer->value = NULL; + if (buffer != GSS_C_NO_BUFFER) { + buffer->length = 0; + buffer->value = NULL; + } vp = pairfind(vps, attr); if (vp == NULL) { @@ -566,23 +588,25 @@ gssEapRadiusGetAvp(OM_uint32 *minor, return GSS_S_UNAVAILABLE; } - do { - buffer->length += vp->length; - } while (concat && (vp = pairfind(vp->next, attr)) != NULL); + if (buffer != GSS_C_NO_BUFFER) { + do { + buffer->length += vp->length; + } while (concat && (vp = pairfind(vp->next, attr)) != NULL); - buffer->value = GSSEAP_MALLOC(buffer->length); - if (buffer->value == NULL) { - *minor = ENOMEM; - return GSS_S_FAILURE; - } + buffer->value = GSSEAP_MALLOC(buffer->length); + if (buffer->value == NULL) { + *minor = ENOMEM; + return GSS_S_FAILURE; + } - p = (unsigned char *)buffer->value; + p = (unsigned char *)buffer->value; - for (vp = pairfind(vps, attr); - concat && vp != NULL; - vp = pairfind(vp->next, attr)) { - memcpy(p, vp->vp_octets, vp->length); - p += vp->length; + for (vp = pairfind(vps, attr); + concat && vp != NULL; + vp = pairfind(vp->next, attr)) { + memcpy(p, vp->vp_octets, vp->length); + p += vp->length; + } } *minor = 0; @@ -623,7 +647,7 @@ avpToJson(const VALUE_PAIR *vp) { JSONObject obj; - assert(vp->length <= MAX_STRING_LEN); + GSSEAP_ASSERT(vp->length <= MAX_STRING_LEN); switch (vp->type) { case PW_TYPE_INTEGER: @@ -761,7 +785,7 @@ gss_eap_radius_attr_provider::initWithJsonObject(const gss_eap_attr_ctx *ctx, pNext = &vp->next; } - m_authenticated = obj["authenticated"].integer(); + m_authenticated = obj["authenticated"].integer() ? true : false; return true; } @@ -807,7 +831,7 @@ gssEapRadiusMapError(OM_uint32 *minor, { int code; - assert(err != NULL); + GSSEAP_ASSERT(err != NULL); code = rs_err_code(err, 0); @@ -823,3 +847,53 @@ gssEapRadiusMapError(OM_uint32 *minor, return GSS_S_FAILURE; } + +OM_uint32 +gssEapCreateRadiusContext(OM_uint32 *minor, + gss_cred_id_t cred, + struct rs_context **pRadContext) +{ + const char *configFile = RS_CONFIG_FILE; + struct rs_context *radContext; + struct rs_alloc_scheme ralloc; + struct rs_error *err; + OM_uint32 major; + + *pRadContext = NULL; + + if (rs_context_create(&radContext) != 0) { + *minor = GSSEAP_RADSEC_CONTEXT_FAILURE; + return GSS_S_FAILURE; + } + + if (cred->radiusConfigFile.value != NULL) + configFile = (const char *)cred->radiusConfigFile.value; + + ralloc.calloc = GSSEAP_CALLOC; + ralloc.malloc = GSSEAP_MALLOC; + ralloc.free = GSSEAP_FREE; + ralloc.realloc = GSSEAP_REALLOC; + + rs_context_set_alloc_scheme(radContext, &ralloc); + + if (rs_context_read_config(radContext, configFile) != 0) { + err = rs_err_ctx_pop(radContext); + goto fail; + } + + if (rs_context_init_freeradius_dict(radContext, NULL) != 0) { + err = rs_err_ctx_pop(radContext); + goto fail; + } + + *pRadContext = radContext; + + *minor = 0; + return GSS_S_COMPLETE; + +fail: + major = gssEapRadiusMapError(minor, err); + rs_context_destroy(radContext); + + return major; +}