#include <typeinfo>
#include <string>
+#include <sstream>
#include <exception>
#include <new>
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)
+static const char *
+gssEapDdfAttrTypes[ATTR_TYPE_MAX + 1] = {
+ "radius",
+ "saml-assertion",
+ "saml",
+ "local"
+};
-/*
- * 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::unmarshallAndInit(DDF &obj)
{
bool ret = false;
- size_t remain = buffer->length;
- unsigned char *p = (unsigned char *)buffer->value;
- bool didInit[ATTR_TYPE_MAX + 1];
+ bool foundSource[ATTR_TYPE_MAX + 1];
unsigned int type;
for (type = ATTR_TYPE_MIN; type <= ATTR_TYPE_MAX; type++)
- didInit[type] = false;
-
- /* flags */
- CHECK_REMAIN(4);
- m_flags = load_uint32_be(p);
- UPDATE_REMAIN(4);
-
- while (remain) {
- OM_uint32 type;
- gss_buffer_desc providerToken;
- gss_eap_attr_provider *provider;
+ foundSource[type] = false;
- /* TLV encoding of provider type, length, value */
- CHECK_REMAIN(4);
- type = load_uint32_be(p);
- UPDATE_REMAIN(4);
-
- CHECK_REMAIN(4);
- providerToken.length = load_uint32_be(p);
- UPDATE_REMAIN(4);
+ if (obj["version"].integer() != 1)
+ return false;
- CHECK_REMAIN(providerToken.length);
- providerToken.value = p;
- UPDATE_REMAIN(providerToken.length);
+ m_flags = obj["flags"].integer();
- if (type < ATTR_TYPE_MIN || type > ATTR_TYPE_MAX ||
- didInit[type])
- return false;
+ DDF sources = obj["sources"];
+ for (type = ATTR_TYPE_MIN; type <= ATTR_TYPE_MAX; type++) {
if (!providerEnabled(type)) {
releaseProvider(type);
continue;
}
- provider = m_providers[type];
+ DDF providerObj = sources[gssEapDdfAttrTypes[type]];
+ if (providerObj.isempty())
+ continue;
- ret = provider->initFromBuffer(this, &providerToken);
+ gss_eap_attr_provider *provider = m_providers[type];
+
+ ret = provider->unmarshallAndInit(this, providerObj);
if (ret == false) {
releaseProvider(type);
break;
}
- didInit[type] = true;
+
+ foundSource[type] = true;
}
- /*
- * The call the initFromGssContext methods for attribute
- * providers that can initialize themselves from other
- * providers.
- */
+ if (ret == false)
+ return ret;
+
for (type = ATTR_TYPE_MIN; type <= ATTR_TYPE_MAX; type++) {
gss_eap_attr_provider *provider;
- if (didInit[type])
+ if (foundSource[type])
continue;
provider = m_providers[type];
return ret;
}
+DDF
+gss_eap_attr_ctx::marshall(void) const
+{
+ DDF obj(NULL);
+ unsigned int i;
+
+ obj.addmember("version").integer(1);
+ obj.addmember("flags").integer(m_flags);
+
+ DDF sources = obj.addmember("sources");
+
+ for (i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++) {
+ gss_eap_attr_provider *provider = m_providers[i];
+
+ if (provider == NULL)
+ continue;
+
+ DDF providerObj = provider->marshall();
+ if (!providerObj.isempty()) {
+ const char *type = gssEapDdfAttrTypes[i];
+
+ sources.addmember(type).structure().swap(providerObj);
+ } else
+ providerObj.destroy();
+ }
+
+ return obj;
+}
+
+/*
+ * Initialize a context from an exported context or name token
+ */
+bool
+gss_eap_attr_ctx::initFromBuffer(const gss_buffer_t buffer)
+{
+ bool ret;
+
+ if (buffer->length == 0)
+ return false;
+
+ DDF obj(NULL);
+ std::string str((const char *)buffer->value, buffer->length);
+ std::istringstream source(str);
+
+ source >> obj;
+
+ ret = unmarshallAndInit(obj);
+
+ obj.destroy();
+
+ return ret;
+}
+
gss_eap_attr_ctx::~gss_eap_attr_ctx(void)
{
for (unsigned int i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++)
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;
- unsigned int i;
+ DDF obj = marshall();
+ std::ostringstream sink;
- for (i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++) {
- providerTokens[i].length = 0;
- providerTokens[i].value = NULL;
- }
+ sink << obj;
+ std::string str = sink.str();
- for (i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++) {
- gss_eap_attr_provider *provider = m_providers[i];
+ printf("%s\n", str.c_str());
- if (provider == NULL)
- continue;
-
- provider->exportToBuffer(&providerTokens[i]);
-
- if (providerTokens[i].value != NULL)
- length += 8 + providerTokens[i].length;
- }
+ duplicateBuffer(str, buffer);
- buffer->length = length;
- buffer->value = GSSEAP_MALLOC(length);
- if (buffer->value == NULL)
- throw new std::bad_alloc;
-
- p = (unsigned char *)buffer->value;
- store_uint32_be(m_flags, p);
- p += 4;
-
- for (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]);
- }
+ obj.destroy();
}
/*