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)
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];
GSS_C_NO_CONTEXT);
if (ret == false) {
releaseProvider(type);
- break;
+ return false;
}
}
- return ret;
+ return true;
}
DDF
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;
sink << obj;
std::string str = sink.str();
- printf("%s\n", str.c_str());
-
duplicateBuffer(str, buffer);
obj.destroy();
{
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)
{
}
static DDF
-avpExport(const VALUE_PAIR *vp)
+avpMarshall(const VALUE_PAIR *vp)
{
DDF obj(NULL);
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;
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;
}
}
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)
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;
}
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);
}
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;
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)
{
{
}
-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)
{
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);
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,
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<Attribute*>::const_iterator a = m_attributes.begin();
a != m_attributes.end(); ++a) {
DDF attr = (*a)->marshall();
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;