#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();
}
/*
#include <string>
#include <new>
+#include <shibsp/remoting/ddf.h>
+
+using namespace shibsp;
+
struct gss_eap_attr_provider;
struct gss_eap_attr_ctx;
{
}
- virtual void exportToBuffer(gss_buffer_t buffer GSSEAP_UNUSED) const
+ virtual bool unmarshallAndInit(const gss_eap_attr_ctx *manager,
+ DDF &object GSSEAP_UNUSED)
{
+ return initWithManager(manager);
}
- virtual bool initFromBuffer(const gss_eap_attr_ctx *manager,
- const gss_buffer_t buffer GSSEAP_UNUSED)
+ virtual DDF marshall(void) const
{
- return initWithManager(manager);
+ return DDF(NULL);
}
virtual time_t getExpiryTime(void) const { return 0; }
bool providerEnabled(unsigned int type) const;
void releaseProvider(unsigned int type);
+ bool unmarshallAndInit(DDF &object);
+ DDF marshall(void) const;
+
gss_eap_attr_provider *getPrimaryProvider(void) const;
/* make non-copyable */
#include "gssapiP_eap.h"
+#include <xercesc/util/Base64.hpp>
+
/* stuff that should be provided by libradsec/libfreeradius-radius */
#define VENDORATTR(vendor, attr) (((vendor) << 16) | (attr))
return GSS_S_COMPLETE;
}
-/*
- * Encoding is:
- * 4 octet NBO attribute ID | 4 octet attribute length | attribute data
- */
-static size_t
-avpSize(const VALUE_PAIR *vp)
-{
- size_t size = 4 + 1;
-
- if (vp != NULL)
- size += vp->length;
-
- return size;
-}
-
-static bool
-avpExport(const VALUE_PAIR *vp,
- unsigned char **pBuffer,
- size_t *pRemain)
+static DDF
+avpExport(const VALUE_PAIR *vp)
{
- unsigned char *p = *pBuffer;
- size_t remain = *pRemain;
+ DDF obj(NULL);
- assert(remain >= avpSize(vp));
+ obj.addmember("type").integer(vp->attribute);
- store_uint32_be(vp->attribute, p);
+ assert(vp->length <= MAX_STRING_LEN);
switch (vp->type) {
case PW_TYPE_INTEGER:
case PW_TYPE_IPADDR:
case PW_TYPE_DATE:
- p[4] = 4;
- store_uint32_be(vp->lvalue, p + 5);
+ obj.addmember("value").integer(vp->lvalue);
+ break;
+ case PW_TYPE_STRING:
+ obj.addmember("value").string(vp->vp_strvalue);
break;
default:
- assert(vp->length <= MAX_STRING_LEN);
- p[4] = (uint8_t)vp->length;
- memcpy(p + 5, vp->vp_octets, vp->length);
+ XMLSize_t len;
+ XMLByte *b64 = xercesc::Base64::encode(vp->vp_octets, vp->length, &len);
+ obj.addmember("value").string((char *)b64);
break;
}
- *pBuffer += 5 + p[4];
- *pRemain -= 5 + p[4];
-
- return true;
-
+ return obj;
}
static bool
-avpImport(VALUE_PAIR **pVp,
- unsigned char **pBuffer,
- size_t *pRemain)
+avpImport(VALUE_PAIR **pVp, DDF &obj)
{
- unsigned char *p = *pBuffer;
- size_t remain = *pRemain;
VALUE_PAIR *vp = NULL;
DICT_ATTR *da;
uint32_t attrid;
- if (remain < avpSize(NULL))
- goto fail;
-
- attrid = load_uint32_be(p);
- p += 4;
- remain -= 4;
+ attrid = obj["type"].integer();
da = dict_attrbyvalue(attrid);
if (da != NULL) {
goto fail;
}
- if (remain < p[0])
- goto fail;
-
switch (vp->type) {
case PW_TYPE_INTEGER:
case PW_TYPE_IPADDR:
case PW_TYPE_DATE:
- if (p[0] != 4)
- goto fail;
-
vp->length = 4;
- vp->lvalue = load_uint32_be(p + 1);
- p += 5;
- remain -= 5;
+ vp->lvalue = obj["value"].integer();;
+ case PW_TYPE_STRING: {
+ const char *str = obj["value"].string();
+ size_t len = strlen(str);
+ if (str == NULL || len >= MAX_STRING_LEN)
+ goto fail;
+ memcpy(vp->vp_strvalue, str, len + 1);
break;
- case PW_TYPE_STRING:
- default:
- if (p[0] >= MAX_STRING_LEN)
+ }
+ default: {
+ const XMLByte *b64 = (const XMLByte *)obj["value"].string();
+ XMLSize_t len;
+ XMLByte *data = xercesc::Base64::decode(b64, &len);
+ if (data == NULL || len >= MAX_STRING_LEN)
goto fail;
-
- vp->length = (uint32_t)p[0];
- memcpy(vp->vp_octets, p + 1, vp->length);
-
- if (vp->type == PW_TYPE_STRING)
- vp->vp_strvalue[vp->length] = '\0';
-
- p += 1 + vp->length;
- remain -= 1 + vp->length;
+ memcpy(vp->vp_octets, data, len);
+ vp->vp_octets[len] = '\0';
break;
}
+ }
*pVp = vp;
- *pBuffer = p;
- *pRemain = remain;
return true;
}
bool
-gss_eap_radius_attr_provider::initFromBuffer(const gss_eap_attr_ctx *ctx,
- const gss_buffer_t buffer)
+gss_eap_radius_attr_provider::unmarshallAndInit(const gss_eap_attr_ctx *ctx,
+ DDF &obj)
{
- unsigned char *p = (unsigned char *)buffer->value;
- size_t remain = buffer->length;
VALUE_PAIR **pNext = &m_vps;
- if (!gss_eap_attr_provider::initFromBuffer(ctx, buffer))
+ if (!gss_eap_attr_provider::unmarshallAndInit(ctx, obj))
return false;
- do {
- VALUE_PAIR *attr;
+ DDF attrs = obj["attributes"];
+ DDF attr = attrs.first();
+
+ while (!attr.isnull()) {
+ VALUE_PAIR *vp;
- if (!avpImport(&attr, &p, &remain))
+ if (!avpImport(&vp, attr))
return false;
- *pNext = attr;
- pNext = &attr->next;
- } while (remain != 0);
+ *pNext = vp;
+ pNext = &vp->next;
+ }
return true;
}
-void
-gss_eap_radius_attr_provider::exportToBuffer(gss_buffer_t buffer) const
+DDF
+gss_eap_radius_attr_provider::marshall(void) const
{
- VALUE_PAIR *vp;
- unsigned char *p;
- size_t remain = 0;
-
- for (vp = m_vps; vp != NULL; vp = vp->next) {
- remain += avpSize(vp);
- }
+ DDF obj(NULL);
+ DDF attrs(NULL);
- buffer->value = GSSEAP_MALLOC(remain);
- if (buffer->value == NULL) {
- throw new std::bad_alloc;
- return;
- }
- buffer->length = remain;
+ attrs = obj.addmember("attributes").list();
- p = (unsigned char *)buffer->value;
-
- for (vp = m_vps; vp != NULL; vp = vp->next) {
- avpExport(vp, &p, &remain);
+ for (VALUE_PAIR *vp = m_vps; vp != NULL; vp = vp->next) {
+ DDF attr = avpExport(vp);
+ attrs.add(attr);
}
- assert(remain == 0);
+ return obj;
}
time_t
void releaseAnyNameMapping(gss_buffer_t type_id,
gss_any_t input) const;
- void exportToBuffer(gss_buffer_t buffer) const;
- bool initFromBuffer(const gss_eap_attr_ctx *ctx,
- const gss_buffer_t buffer);
+ bool unmarshallAndInit(const gss_eap_attr_ctx *manager,
+ DDF &object GSSEAP_UNUSED);
+ DDF marshall(void) const;
bool getAttribute(uint32_t attribute,
int *authenticated,
delete ((saml2::Assertion *)input);
}
-void
-gss_eap_saml_assertion_provider::exportToBuffer(gss_buffer_t buffer) const
+DDF
+gss_eap_saml_assertion_provider::marshall(void) const
{
- buffer->length = 0;
- buffer->value = NULL;
+ return DDF(NULL);
}
bool
-gss_eap_saml_assertion_provider::initFromBuffer(const gss_eap_attr_ctx *ctx GSSEAP_UNUSED,
- const gss_buffer_t buffer GSSEAP_UNUSED)
+gss_eap_saml_assertion_provider::unmarshallAndInit(const gss_eap_attr_ctx *ctx GSSEAP_UNUSED,
+ DDF &object GSSEAP_UNUSED)
{
return false;
}
{
}
-void
-gss_eap_saml_attr_provider::exportToBuffer(gss_buffer_t buffer) const
+DDF
+gss_eap_saml_attr_provider::marshall(void) const
{
- buffer->length = 0;
- buffer->value = NULL;
+ return DDF(NULL);
}
bool
-gss_eap_saml_attr_provider::initFromBuffer(const gss_eap_attr_ctx *ctx GSSEAP_UNUSED,
- const gss_buffer_t buffer GSSEAP_UNUSED)
+gss_eap_saml_attr_provider::unmarshallAndInit(const gss_eap_attr_ctx *ctx GSSEAP_UNUSED,
+ DDF &object GSSEAP_UNUSED)
{
return false;
}
void releaseAnyNameMapping(gss_buffer_t type_id,
gss_any_t input) const;
- void exportToBuffer(gss_buffer_t buffer) const;
- bool initFromBuffer(const gss_eap_attr_ctx *ctx,
- const gss_buffer_t buffer);
+ bool unmarshallAndInit(const gss_eap_attr_ctx *manager,
+ DDF &object GSSEAP_UNUSED);
+ DDF marshall(void) const;
opensaml::saml2::Assertion *initAssertion(void);
void releaseAnyNameMapping(gss_buffer_t type_id,
gss_any_t input) const;
- void exportToBuffer(gss_buffer_t buffer) const;
- bool initFromBuffer(const gss_eap_attr_ctx *ctx,
- const gss_buffer_t buffer);
+ bool unmarshallAndInit(const gss_eap_attr_ctx *manager,
+ DDF &object GSSEAP_UNUSED);
+ DDF marshall(void) const;
bool getAttribute(const gss_buffer_t attr,
int *authenticated,
delete v;
}
-void
-gss_eap_shib_attr_provider::exportToBuffer(gss_buffer_t buffer) const
+DDF
+gss_eap_shib_attr_provider::marshall(void) const
{
DDF obj(NULL);
DDF attrs(NULL);
- buffer->length = 0;
- buffer->value = NULL;
-
- obj.addmember("version").integer(1);
obj.addmember("authenticated").integer(m_authenticated);
attrs = obj.addmember("attributes").list();
attrs.add(attr);
}
- ostringstream sink;
- sink << obj;
- string str = sink.str();
-
- duplicateBuffer(str, buffer);
-
- attrs.destroy();
+ return obj;
}
bool
-gss_eap_shib_attr_provider::initFromBuffer(const gss_eap_attr_ctx *ctx,
- const gss_buffer_t buffer)
+gss_eap_shib_attr_provider::unmarshallAndInit(const gss_eap_attr_ctx *ctx,
+ DDF &obj)
{
- if (!gss_eap_attr_provider::initFromBuffer(ctx, buffer))
+ if (!gss_eap_attr_provider::unmarshallAndInit(ctx, obj))
return false;
- if (buffer->length == 0)
- return true;
-
assert(m_authenticated == false);
assert(m_attributes.size() == 0);
- DDF obj(NULL);
- string str((const char *)buffer->value, buffer->length);
- istringstream source(str);
-
- source >> obj;
-
- if (obj["version"].integer() != 1)
- return false;
-
m_authenticated = (obj["authenticated"].integer() != 0);
DDF attrs = obj["attributes"];
attr = attrs.next();
}
- attrs.destroy();
-
return true;
}
void releaseAnyNameMapping(gss_buffer_t type_id,
gss_any_t input) const;
- void exportToBuffer(gss_buffer_t buffer) const;
- bool initFromBuffer(const gss_eap_attr_ctx *ctx,
- const gss_buffer_t buffer);
+ bool unmarshallAndInit(const gss_eap_attr_ctx *manager,
+ DDF &object GSSEAP_UNUSED);
+ DDF marshall(void) const;
static bool init(void);
static void finalize(void);