#include <string>
#include <sstream>
#include <exception>
+#include <stdexcept>
#include <new>
/* lazy initialisation */
assert(gssEapAttrProvidersInitStatus == GSS_S_UNAVAILABLE);
major = gssEapRadiusAttrProviderInit(&minor);
- if (major == GSS_S_COMPLETE)
- major = gssEapSamlAttrProvidersInit(&minor);
- if (major == GSS_S_COMPLETE)
- major = gssEapLocalAttrProviderInit(&minor);
+ if (GSS_ERROR(major))
+ goto cleanup;
+
+ major = gssEapSamlAttrProvidersInit(&minor);
+ if (GSS_ERROR(major))
+ goto cleanup;
+
+ /* Allow Shibboleth initialization failure to be non-fatal */
+ gssEapLocalAttrProviderInit(&minor);
+cleanup:
#ifdef GSSEAP_DEBUG
assert(major == GSS_S_COMPLETE);
#endif
return ret;
}
-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)
+gss_eap_attr_ctx::initWithJsonObject(JSONObject &obj)
{
bool ret = false;
bool foundSource[ATTR_TYPE_MAX + 1];
m_flags = obj["flags"].integer();
- DDF sources = obj["sources"];
+ JSONObject sources = obj["sources"];
/* 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);
continue;
}
- gss_eap_attr_provider *provider = m_providers[type];
- const char *key = provider->marshallingKey();
+ provider = m_providers[type];
+ key = provider->name();
if (key == NULL)
continue;
- DDF source = findSourceForProvider(sources, key);
- if (source.isnull() ||
- !provider->unmarshallAndInit(this, source)) {
+ JSONObject source = sources.get(key);
+ if (!source.isNull() &&
+ !provider->initWithJsonObject(this, source)) {
releaseProvider(type);
return false;
}
foundSource[type] = true;
}
- /* Initialize remaining providers from initialized providers */
+ /* Initialize remaining providers from initialized providers */
for (type = ATTR_TYPE_MIN; type <= ATTR_TYPE_MAX; type++) {
gss_eap_attr_provider *provider;
return true;
}
-DDF
-gss_eap_attr_ctx::marshall(void) const
+JSONObject
+gss_eap_attr_ctx::jsonRepresentation(void) const
{
- DDF obj(NULL);
+ JSONObject obj, sources;
unsigned int i;
- obj.addmember("version").integer(1);
- obj.addmember("flags").integer(m_flags);
-
- DDF sources = obj.addmember("sources").list();
+ obj.set("version", 1);
+ obj.set("flags", m_flags);
for (i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++) {
- gss_eap_attr_provider *provider = m_providers[i];
+ gss_eap_attr_provider *provider;
+ const char *key;
+ provider = m_providers[i];
if (provider == NULL)
continue; /* provider not initialised */
- const char *key = provider->marshallingKey();
+ key = provider->name();
if (key == NULL)
continue; /* provider does not have state */
- DDF source = provider->marshall();
- sources.add(source.name(key));
+ JSONObject source = provider->jsonRepresentation();
+ sources.set(key, source);
}
+ obj.set("sources", sources);
+
return obj;
}
bool
gss_eap_attr_ctx::initFromBuffer(const gss_buffer_t buffer)
{
+ OM_uint32 major, minor;
bool ret;
+ char *s;
+ json_error_t error;
- if (buffer->length == 0)
+ major = bufferToString(&minor, buffer, &s);
+ if (GSS_ERROR(major))
return false;
- DDF obj(NULL);
- std::string str((const char *)buffer->value, buffer->length);
- std::istringstream source(str);
-
- source >> obj;
-
- ret = unmarshallAndInit(obj);
+ JSONObject obj = JSONObject::load(s, 0, &error);
+ if (!obj.isNull()) {
+ ret = initWithJsonObject(obj);
+ } else
+ ret = false;
- obj.destroy();
+ GSSEAP_FREE(s);
return ret;
}
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;
void
gss_eap_attr_ctx::exportToBuffer(gss_buffer_t buffer) const
{
- DDF obj = marshall();
- std::ostringstream sink;
+ OM_uint32 minor;
+ char *s;
- sink << obj;
- std::string str = sink.str();
+ JSONObject obj = jsonRepresentation();
+
+#if 0
+ obj.dump(stdout);
+#endif
- duplicateBuffer(str, buffer);
+ s = obj.dump(JSON_COMPACT);
- obj.destroy();
+ if (GSS_ERROR(makeStringBuffer(&minor, s, buffer)))
+ throw new std::bad_alloc;
}
/*
OM_uint32 major;
/* Errors we handle ourselves */
- major = GSS_S_FAILURE;
-
if (typeid(e) == typeid(std::bad_alloc)) {
*minor = ENOMEM;
goto cleanup;
+ } else if (typeid(e) == typeid(std::runtime_error)) {
+ major = GSS_S_BAD_NAME;
+ *minor = GSSEAP_BAD_ATTR_TOKEN;
+ goto cleanup;
+ } else if (this == NULL) {
+ major = GSS_S_FAILURE;
+ goto cleanup;
}
/* Errors we delegate to providers */
gss_buffer_t display_value,
int *more)
{
- *authenticated = 0;
- *complete = 0;
+ if (authenticated != NULL)
+ *authenticated = 0;
+ if (complete != NULL)
+ *complete = 0;
if (value != NULL) {
value->length = 0;
if (!ctx->initFromBuffer(buffer)) {
delete ctx;
*minor = GSSEAP_BAD_ATTR_TOKEN;
- return GSS_S_DEFECTIVE_TOKEN;
+ return GSS_S_BAD_NAME;
}
name->attrCtx = ctx;
} catch (std::exception &e) {
major = GSS_S_FAILURE;
try {
- ctx = new gss_eap_attr_ctx();
+ *pAttrContext = ctx = new gss_eap_attr_ctx();
if (ctx->initFromGssContext(gssCred, gssCtx)) {
*minor = 0;
major = GSS_S_COMPLETE;
- } else {
- delete ctx;
}
} catch (std::exception &e) {
if (ctx != NULL)
}
if (major == GSS_S_COMPLETE) {
- *pAttrContext = ctx;
*pExpiryTime = ctx->getExpiryTime();
+ } else {
+ delete ctx;
+ *pAttrContext = NULL;
}
return major;