From: Luke Howard Date: Sun, 27 Mar 2011 01:46:53 +0000 (+1100) Subject: get DDF marshalling working X-Git-Url: http://www.project-moonshot.org/gitweb/?p=moonshot.git;a=commitdiff_plain;h=ca8dae7f329022bee28d7a37b99bb078dbe48216 get DDF marshalling working --- diff --git a/mech_eap/util_attr.cpp b/mech_eap/util_attr.cpp index e3815e3..48c4291 100644 --- a/mech_eap/util_attr.cpp +++ b/mech_eap/util_attr.cpp @@ -266,13 +266,22 @@ gss_eap_attr_ctx::initFromGssContext(const gss_cred_id_t cred, return ret; } -static const char * -gssEapDdfAttrTypes[ATTR_TYPE_MAX + 1] = { - "radius", - "saml-assertion", - "saml", - "local" -}; +static DDF +findSourceForProvider(DDF &sources, const char *key) +{ + DDF source = sources.first(); + + while (!source.isnull()) { + DDF obj = source.getmember(key); + + if (strcmp(key, source.name()) == 0) + break; + + source = sources.next(); + } + + return source; +} bool gss_eap_attr_ctx::unmarshallAndInit(DDF &obj) @@ -291,34 +300,33 @@ gss_eap_attr_ctx::unmarshallAndInit(DDF &obj) DDF sources = obj["sources"]; + /* Initialize providers from serialized state */ for (type = ATTR_TYPE_MIN; type <= ATTR_TYPE_MAX; type++) { if (!providerEnabled(type)) { releaseProvider(type); continue; } - DDF providerObj = sources[gssEapDdfAttrTypes[type]]; - if (providerObj.isempty()) - continue; - gss_eap_attr_provider *provider = m_providers[type]; + const char *key = provider->marshallingKey(); + if (key == NULL) + continue; - ret = provider->unmarshallAndInit(this, providerObj); - if (ret == false) { + DDF source = findSourceForProvider(sources, key); + if (source.isnull() || + !provider->unmarshallAndInit(this, source)) { releaseProvider(type); - break; + return false; } foundSource[type] = true; } - if (ret == false) - return ret; - + /* Initialize remaining providers from initialized providers */ for (type = ATTR_TYPE_MIN; type <= ATTR_TYPE_MAX; type++) { gss_eap_attr_provider *provider; - if (foundSource[type]) + if (foundSource[type] || !providerEnabled(type)) continue; provider = m_providers[type]; @@ -328,11 +336,11 @@ gss_eap_attr_ctx::unmarshallAndInit(DDF &obj) GSS_C_NO_CONTEXT); if (ret == false) { releaseProvider(type); - break; + return false; } } - return ret; + return true; } DDF @@ -344,21 +352,20 @@ gss_eap_attr_ctx::marshall(void) const obj.addmember("version").integer(1); obj.addmember("flags").integer(m_flags); - DDF sources = obj.addmember("sources"); + DDF sources = obj.addmember("sources").list(); for (i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++) { gss_eap_attr_provider *provider = m_providers[i]; if (provider == NULL) - continue; + continue; /* provider not initialised */ - DDF providerObj = provider->marshall(); - if (!providerObj.isempty()) { - const char *type = gssEapDdfAttrTypes[i]; + const char *key = provider->marshallingKey(); + if (key == NULL) + continue; /* provider does not have state */ - sources.addmember(type).structure().swap(providerObj); - } else - providerObj.destroy(); + DDF source = provider->marshall(); + sources.add(source.name(key)); } return obj; @@ -638,8 +645,6 @@ gss_eap_attr_ctx::exportToBuffer(gss_buffer_t buffer) const sink << obj; std::string str = sink.str(); - printf("%s\n", str.c_str()); - duplicateBuffer(str, buffer); obj.destroy(); diff --git a/mech_eap/util_attr.h b/mech_eap/util_attr.h index fe5d773..1afbbd1 100644 --- a/mech_eap/util_attr.h +++ b/mech_eap/util_attr.h @@ -124,11 +124,17 @@ public: { return NULL; } + virtual void releaseAnyNameMapping(gss_buffer_t type_id GSSEAP_UNUSED, gss_any_t input GSSEAP_UNUSED) const { } + virtual const char *marshallingKey(void) const + { + return NULL; + } + virtual bool unmarshallAndInit(const gss_eap_attr_ctx *manager, DDF &object GSSEAP_UNUSED) { diff --git a/mech_eap/util_radius.cpp b/mech_eap/util_radius.cpp index 4eed829..be553f1 100644 --- a/mech_eap/util_radius.cpp +++ b/mech_eap/util_radius.cpp @@ -624,7 +624,7 @@ gssEapRadiusAttrProviderFinalize(OM_uint32 *minor) } static DDF -avpExport(const VALUE_PAIR *vp) +avpMarshall(const VALUE_PAIR *vp) { DDF obj(NULL); @@ -641,18 +641,24 @@ avpExport(const VALUE_PAIR *vp) case PW_TYPE_STRING: obj.addmember("value").string(vp->vp_strvalue); break; - default: + default: { XMLSize_t len; XMLByte *b64 = xercesc::Base64::encode(vp->vp_octets, vp->length, &len); + + if (b64[len - 1] == '\n') + b64[--len] = '\0'; /* XXX there may be embedded newlines */ + obj.addmember("value").string((char *)b64); + delete b64; break; } + } return obj; } static bool -avpImport(VALUE_PAIR **pVp, DDF &obj) +avpUnmarshall(VALUE_PAIR **pVp, DDF &obj) { VALUE_PAIR *vp = NULL; DICT_ATTR *da; @@ -677,22 +683,31 @@ avpImport(VALUE_PAIR **pVp, DDF &obj) case PW_TYPE_DATE: vp->length = 4; vp->lvalue = obj["value"].integer();; + break; case PW_TYPE_STRING: { const char *str = obj["value"].string(); size_t len = strlen(str); if (str == NULL || len >= MAX_STRING_LEN) goto fail; + + vp->length = len; memcpy(vp->vp_strvalue, str, len + 1); break; } + case PW_TYPE_OCTETS: default: { - const XMLByte *b64 = (const XMLByte *)obj["value"].string(); XMLSize_t len; + const XMLByte *b64 = (const XMLByte *)obj["value"].string(); XMLByte *data = xercesc::Base64::decode(b64, &len); - if (data == NULL || len >= MAX_STRING_LEN) + if (data == NULL || len >= MAX_STRING_LEN) { + delete data; goto fail; + } + + vp->length = len; memcpy(vp->vp_octets, data, len); vp->vp_octets[len] = '\0'; + delete data; break; } } @@ -708,6 +723,12 @@ fail: return false; } +const char * +gss_eap_radius_attr_provider::marshallingKey(void) const +{ + return "radius"; +} + bool gss_eap_radius_attr_provider::unmarshallAndInit(const gss_eap_attr_ctx *ctx, DDF &obj) @@ -723,13 +744,17 @@ gss_eap_radius_attr_provider::unmarshallAndInit(const gss_eap_attr_ctx *ctx, while (!attr.isnull()) { VALUE_PAIR *vp; - if (!avpImport(&vp, attr)) + if (!avpUnmarshall(&vp, attr)) return false; *pNext = vp; pNext = &vp->next; + + attr = attrs.next(); } + obj.dump(); + return true; } @@ -737,12 +762,10 @@ DDF gss_eap_radius_attr_provider::marshall(void) const { DDF obj(NULL); - DDF attrs(NULL); - - attrs = obj.addmember("attributes").list(); + DDF attrs = obj.structure().addmember("attributes").list(); for (VALUE_PAIR *vp = m_vps; vp != NULL; vp = vp->next) { - DDF attr = avpExport(vp); + DDF attr = avpMarshall(vp); attrs.add(attr); } diff --git a/mech_eap/util_radius.h b/mech_eap/util_radius.h index 71d651d..f590d65 100644 --- a/mech_eap/util_radius.h +++ b/mech_eap/util_radius.h @@ -66,6 +66,7 @@ public: void releaseAnyNameMapping(gss_buffer_t type_id, gss_any_t input) const; + const char *marshallingKey(void) const; bool unmarshallAndInit(const gss_eap_attr_ctx *manager, DDF &object GSSEAP_UNUSED); DDF marshall(void) const; diff --git a/mech_eap/util_saml.cpp b/mech_eap/util_saml.cpp index 6a726f4..0c64752 100644 --- a/mech_eap/util_saml.cpp +++ b/mech_eap/util_saml.cpp @@ -304,19 +304,6 @@ gss_eap_saml_assertion_provider::releaseAnyNameMapping(gss_buffer_t type_id GSSE delete ((saml2::Assertion *)input); } -DDF -gss_eap_saml_assertion_provider::marshall(void) const -{ - return DDF(NULL); -} - -bool -gss_eap_saml_assertion_provider::unmarshallAndInit(const gss_eap_attr_ctx *ctx GSSEAP_UNUSED, - DDF &object GSSEAP_UNUSED) -{ - return false; -} - bool gss_eap_saml_assertion_provider::init(void) { @@ -683,19 +670,6 @@ gss_eap_saml_attr_provider::releaseAnyNameMapping(gss_buffer_t type_id GSSEAP_UN { } -DDF -gss_eap_saml_attr_provider::marshall(void) const -{ - return DDF(NULL); -} - -bool -gss_eap_saml_attr_provider::unmarshallAndInit(const gss_eap_attr_ctx *ctx GSSEAP_UNUSED, - DDF &object GSSEAP_UNUSED) -{ - return false; -} - bool gss_eap_saml_attr_provider::init(void) { diff --git a/mech_eap/util_saml.h b/mech_eap/util_saml.h index d309f63..2ad2037 100644 --- a/mech_eap/util_saml.h +++ b/mech_eap/util_saml.h @@ -74,9 +74,16 @@ public: void releaseAnyNameMapping(gss_buffer_t type_id, gss_any_t input) const; - bool unmarshallAndInit(const gss_eap_attr_ctx *manager, - DDF &object GSSEAP_UNUSED); - DDF marshall(void) const; + const char *marshallingKey(void) const { + return NULL; + } + bool unmarshallAndInit(const gss_eap_attr_ctx *manager GSSEAP_UNUSED, + DDF &object GSSEAP_UNUSED) { + return false; + } + DDF marshall(void) const { + return DDF(NULL); + } opensaml::saml2::Assertion *initAssertion(void); @@ -129,9 +136,16 @@ public: void releaseAnyNameMapping(gss_buffer_t type_id, gss_any_t input) const; - bool unmarshallAndInit(const gss_eap_attr_ctx *manager, - DDF &object GSSEAP_UNUSED); - DDF marshall(void) const; + const char *marshallingKey(void) const { + return NULL; + } + bool unmarshallAndInit(const gss_eap_attr_ctx *manager GSSEAP_UNUSED, + DDF &object GSSEAP_UNUSED) { + return false; + } + DDF marshall(void) const { + return DDF(NULL); + } bool getAttribute(const gss_buffer_t attr, int *authenticated, diff --git a/mech_eap/util_shib.cpp b/mech_eap/util_shib.cpp index 92ad70c..ab241a7 100644 --- a/mech_eap/util_shib.cpp +++ b/mech_eap/util_shib.cpp @@ -381,15 +381,20 @@ gss_eap_shib_attr_provider::releaseAnyNameMapping(gss_buffer_t type_id GSSEAP_UN delete v; } +const char * +gss_eap_shib_attr_provider::marshallingKey(void) const +{ + return "local"; +} + DDF gss_eap_shib_attr_provider::marshall(void) const { DDF obj(NULL); - DDF attrs(NULL); obj.addmember("authenticated").integer(m_authenticated); - attrs = obj.addmember("attributes").list(); + DDF attrs = obj.addmember("attributes").list(); for (vector::const_iterator a = m_attributes.begin(); a != m_attributes.end(); ++a) { DDF attr = (*a)->marshall(); diff --git a/mech_eap/util_shib.h b/mech_eap/util_shib.h index 38c594d..79ae90f 100644 --- a/mech_eap/util_shib.h +++ b/mech_eap/util_shib.h @@ -76,6 +76,7 @@ public: void releaseAnyNameMapping(gss_buffer_t type_id, gss_any_t input) const; + const char *marshallingKey(void) const; bool unmarshallAndInit(const gss_eap_attr_ctx *manager, DDF &object GSSEAP_UNUSED); DDF marshall(void) const;