X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=util_attr.cpp;h=d9c4614fa2537e9c509ae5bdb2fb63c11e6f773f;hb=f12a2be8e6409006eaf326c204ea5c99b78b3b2b;hp=76468f9ba64f05e4adb4f2c897a9eaf6e625e987;hpb=61b5bb62a91f636f4d8bbc280dbc69f63c9f25a9;p=mech_eap.git diff --git a/util_attr.cpp b/util_attr.cpp index 76468f9..d9c4614 100644 --- a/util_attr.cpp +++ b/util_attr.cpp @@ -38,7 +38,9 @@ #include #include +#include #include +#include #include /* lazy initialisation */ @@ -95,14 +97,12 @@ gssEapAttrProvidersFinalize(OM_uint32 *minor) } static gss_eap_attr_create_provider gssEapAttrFactories[ATTR_TYPE_MAX + 1]; -static gss_buffer_desc gssEapAttrPrefixes[ATTR_TYPE_MAX + 1]; /* * Register a provider for a particular type and prefix */ void gss_eap_attr_ctx::registerProvider(unsigned int type, - const char *prefix, gss_eap_attr_create_provider factory) { assert(type <= ATTR_TYPE_MAX); @@ -110,13 +110,6 @@ gss_eap_attr_ctx::registerProvider(unsigned int type, assert(gssEapAttrFactories[type] == NULL); gssEapAttrFactories[type] = factory; - if (prefix != NULL) { - gssEapAttrPrefixes[type].value = (void *)prefix; - gssEapAttrPrefixes[type].length = strlen(prefix); - } else { - gssEapAttrPrefixes[type].value = NULL; - gssEapAttrPrefixes[type].length = 0; - } } /* @@ -128,8 +121,6 @@ gss_eap_attr_ctx::unregisterProvider(unsigned int type) assert(type <= ATTR_TYPE_MAX); gssEapAttrFactories[type] = NULL; - gssEapAttrPrefixes[type].value = NULL; - gssEapAttrPrefixes[type].length = 0; } /* @@ -156,12 +147,22 @@ gss_eap_attr_ctx::gss_eap_attr_ctx(void) * Convert an attribute prefix to a type */ unsigned int -gss_eap_attr_ctx::attributePrefixToType(const gss_buffer_t prefix) +gss_eap_attr_ctx::attributePrefixToType(const gss_buffer_t prefix) const { unsigned int i; for (i = ATTR_TYPE_MIN; i < ATTR_TYPE_MAX; i++) { - if (bufferEqual(&gssEapAttrPrefixes[i], prefix)) + const char *pprefix; + + if (!providerEnabled(i)) + continue; + + pprefix = m_providers[i]->prefix(); + if (pprefix == NULL) + continue; + + if (strlen(pprefix) == prefix->length && + memcmp(pprefix, prefix->value, prefix->length) == 0) return i; } @@ -171,13 +172,22 @@ gss_eap_attr_ctx::attributePrefixToType(const gss_buffer_t prefix) /* * Convert a type to an attribute prefix */ -const gss_buffer_t -gss_eap_attr_ctx::attributeTypeToPrefix(unsigned int type) +gss_buffer_desc +gss_eap_attr_ctx::attributeTypeToPrefix(unsigned int type) const { + gss_buffer_desc prefix = GSS_C_EMPTY_BUFFER; + if (type < ATTR_TYPE_MIN || type >= ATTR_TYPE_MAX) - return GSS_C_NO_BUFFER; + return prefix; - return &gssEapAttrPrefixes[type]; + if (!providerEnabled(type)) + return prefix; + + prefix.value = (void *)m_providers[type]->prefix(); + if (prefix.value != NULL) + prefix.length = strlen((char *)prefix.value); + + return prefix; } bool @@ -265,56 +275,27 @@ gss_eap_attr_ctx::initFromGssContext(const gss_cred_id_t cred, return ret; } -#define UPDATE_REMAIN(n) do { \ - p += (n); \ - remain -= (n); \ - } while (0) - -#define CHECK_REMAIN(n) do { \ - if (remain < (n)) { \ - return false; \ - } \ - } while (0) - -/* - * Initialize a context from an exported context or name token - */ bool -gss_eap_attr_ctx::initFromBuffer(const gss_buffer_t buffer) +gss_eap_attr_ctx::initWithJsonObject(JSONObject &obj) { - bool ret; - size_t remain = buffer->length; - unsigned char *p = (unsigned char *)buffer->value; - bool didInit[ATTR_TYPE_MAX + 1]; - - memset(didInit, 0, sizeof(didInit)); - - /* flags */ - CHECK_REMAIN(4); - m_flags = load_uint32_be(p); - UPDATE_REMAIN(4); + bool ret = false; + bool foundSource[ATTR_TYPE_MAX + 1]; + unsigned int type; - while (remain) { - OM_uint32 type; - gss_buffer_desc providerToken; - gss_eap_attr_provider *provider; + for (type = ATTR_TYPE_MIN; type <= ATTR_TYPE_MAX; type++) + foundSource[type] = false; - /* TLV encoding of provider type, length, value */ - CHECK_REMAIN(4); - type = load_uint32_be(p); - UPDATE_REMAIN(4); + if (obj["version"].integer() != 1) + return false; - CHECK_REMAIN(4); - providerToken.length = load_uint32_be(p); - UPDATE_REMAIN(4); + m_flags = obj["flags"].integer(); - CHECK_REMAIN(providerToken.length); - providerToken.value = p; - UPDATE_REMAIN(providerToken.length); + JSONObject sources = obj["sources"]; - if (type < ATTR_TYPE_MIN || type > ATTR_TYPE_MAX || - didInit[type]) - return false; + /* Initialize providers from serialized state */ + for (type = ATTR_TYPE_MIN; type <= ATTR_TYPE_MAX; type++) { + gss_eap_attr_provider *provider; + const char *key; if (!providerEnabled(type)) { releaseProvider(type); @@ -322,24 +303,25 @@ gss_eap_attr_ctx::initFromBuffer(const gss_buffer_t buffer) } provider = m_providers[type]; + key = provider->name(); + if (key == NULL) + continue; - ret = provider->initFromBuffer(this, &providerToken); - if (ret == false) { + JSONObject source = sources.get(key); + if (!source.isnull() && + !provider->initWithJsonObject(this, source)) { releaseProvider(type); - break; + return false; } - didInit[type] = true; + + foundSource[type] = true; } - /* - * The call the initFromGssContext methods for attribute - * providers that can initialize themselves from other - * providers. - */ - for (size_t type = ATTR_TYPE_MIN; type <= ATTR_TYPE_MAX; type++) { + /* Initialize remaining providers from initialized providers */ + for (type = ATTR_TYPE_MIN; type <= ATTR_TYPE_MAX; type++) { gss_eap_attr_provider *provider; - if (didInit[type]) + if (foundSource[type] || !providerEnabled(type)) continue; provider = m_providers[type]; @@ -349,10 +331,66 @@ gss_eap_attr_ctx::initFromBuffer(const gss_buffer_t buffer) GSS_C_NO_CONTEXT); if (ret == false) { releaseProvider(type); - break; + return false; } } + return true; +} + +JSONObject +gss_eap_attr_ctx::jsonRepresentation(void) const +{ + JSONObject obj, sources; + unsigned int i; + + obj.set("version", 1); + obj.set("flags", m_flags); + + for (i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++) { + gss_eap_attr_provider *provider; + const char *key; + + provider = m_providers[i]; + if (provider == NULL) + continue; /* provider not initialised */ + + key = provider->name(); + if (key == NULL) + continue; /* provider does not have state */ + + JSONObject source = provider->jsonRepresentation(); + sources.set(key, source); + } + + obj.set("sources", sources); + + return obj; +} + +/* + * Initialize a context from an exported context or name token + */ +bool +gss_eap_attr_ctx::initFromBuffer(const gss_buffer_t buffer) +{ + OM_uint32 major, minor; + bool ret; + char *s; + json_error_t error; + + major = bufferToString(&minor, buffer, &s); + if (GSS_ERROR(major)) + return false; + + JSONObject obj = JSONObject::load(s, 0, &error); + if (!obj.isnull()) { + ret = initWithJsonObject(obj); + } else + ret = false; + + GSSEAP_FREE(s); + return ret; } @@ -373,19 +411,6 @@ gss_eap_attr_ctx::getProvider(unsigned int type) const } /* - * Locate provider for a given prefix - */ -gss_eap_attr_provider * -gss_eap_attr_ctx::getProvider(const gss_buffer_t prefix) const -{ - unsigned int type; - - type = attributePrefixToType(prefix); - - return m_providers[type]; -} - -/* * Get primary provider. Only the primary provider is serialised when * gss_export_sec_context() or gss_export_name_composite() is called. */ @@ -470,7 +495,8 @@ struct eap_gss_get_attr_types_args { }; static bool -addAttribute(const gss_eap_attr_provider *provider GSSEAP_UNUSED, +addAttribute(const gss_eap_attr_ctx *manager, + const gss_eap_attr_provider *provider GSSEAP_UNUSED, const gss_buffer_t attribute, void *data) { @@ -479,7 +505,7 @@ addAttribute(const gss_eap_attr_provider *provider GSSEAP_UNUSED, OM_uint32 major, minor; if (args->type != ATTR_TYPE_LOCAL) { - gss_eap_attr_ctx::composeAttributeName(args->type, attribute, &qualified); + manager->composeAttributeName(args->type, attribute, &qualified); major = gss_add_buffer_set_member(&minor, &qualified, &args->attrs); gss_release_buffer(&minor, &qualified); } else { @@ -501,10 +527,8 @@ gss_eap_attr_ctx::getAttributeTypes(gss_buffer_set_t *attrs) unsigned int i; major = gss_create_empty_buffer_set(&minor, attrs); - if (GSS_ERROR(major)) { + if (GSS_ERROR(major)) throw new std::bad_alloc; - return false; - } args.attrs = *attrs; @@ -600,47 +624,17 @@ gss_eap_attr_ctx::releaseAnyNameMapping(gss_buffer_t type_id, void gss_eap_attr_ctx::exportToBuffer(gss_buffer_t buffer) const { - OM_uint32 tmpMinor; - gss_buffer_desc providerTokens[ATTR_TYPE_MAX + 1]; - size_t length = 4; /* m_flags */ - unsigned char *p; + OM_uint32 minor; + char *s; - memset(providerTokens, 0, sizeof(providerTokens)); + JSONObject obj = jsonRepresentation(); - for (size_t i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++) { - gss_eap_attr_provider *provider = m_providers[i]; + obj.dump(stdout, JSON_INDENT(3)); - if (provider == NULL) - continue; + s = obj.dump(JSON_COMPACT); - provider->exportToBuffer(&providerTokens[i]); - - if (providerTokens[i].value != NULL) - length += 8 + providerTokens[i].length; - } - - buffer->length = length; - buffer->value = GSSEAP_MALLOC(length); - if (buffer->value == NULL) + if (GSS_ERROR(makeStringBuffer(&minor, s, buffer))) throw new std::bad_alloc; - - p = (unsigned char *)buffer->value; - store_uint32_be(m_flags, p); - p += 4; - - for (size_t i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++) { - if (providerTokens[i].value == NULL) - continue; - - store_uint32_be(i, p); - p += 4; - store_uint32_be(providerTokens[i].length, p); - p += 4; - memcpy(p, providerTokens[i].value, providerTokens[i].length); - p += providerTokens[i].length; - - gss_release_buffer(&tmpMinor, &providerTokens[i]); - } } /* @@ -750,7 +744,7 @@ gss_eap_attr_ctx::decomposeAttributeName(const gss_buffer_t attribute, void gss_eap_attr_ctx::decomposeAttributeName(const gss_buffer_t attribute, unsigned int *type, - gss_buffer_t suffix) + gss_buffer_t suffix) const { gss_buffer_desc prefix = GSS_C_EMPTY_BUFFER; @@ -787,9 +781,9 @@ std::string gss_eap_attr_ctx::composeAttributeName(unsigned int type, const gss_buffer_t suffix) { - const gss_buffer_t prefix = attributeTypeToPrefix(type); + gss_buffer_desc prefix = attributeTypeToPrefix(type); - return composeAttributeName(prefix, suffix); + return composeAttributeName(&prefix, suffix); } /* @@ -816,11 +810,11 @@ gss_eap_attr_ctx::composeAttributeName(const gss_buffer_t prefix, void gss_eap_attr_ctx::composeAttributeName(unsigned int type, const gss_buffer_t suffix, - gss_buffer_t attribute) + gss_buffer_t attribute) const { - gss_buffer_t prefix = attributeTypeToPrefix(type); + gss_buffer_desc prefix = attributeTypeToPrefix(type); - return composeAttributeName(prefix, suffix, attribute); + return composeAttributeName(&prefix, suffix, attribute); } /*