X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=util_saml.cpp;h=b859d9b91f8479c6c07bf817e281790fb5bc5adc;hb=81378d116795fa8a7a56dc8e00c3b2666126682d;hp=7d5ae0124ff5f75ebebf8e6316f70b5f0b2d0727;hpb=1f273eda615c04331df6849cfbf3cfad069ea8b0;p=mech_eap.git diff --git a/util_saml.cpp b/util_saml.cpp index 7d5ae01..b859d9b 100644 --- a/util_saml.cpp +++ b/util_saml.cpp @@ -29,832 +29,394 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -/* - * Copyright 2001-2009 Internet2 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ #include "gssapiP_eap.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include +#include + #include -#include +#include #include -#include "resolver.h" +#include +#include +#include -using namespace shibsp; -using namespace shibresolver; +using namespace xmltooling; using namespace opensaml::saml2md; using namespace opensaml; -using namespace xmltooling::logging; -using namespace xmltooling; using namespace xercesc; using namespace std; -static vector -duplicateAttributes(const vector src); - -struct gss_eap_saml_attr_ctx -{ -public: - gss_eap_saml_attr_ctx(const gss_buffer_t buffer = GSS_C_NO_BUFFER) { - if (buffer != GSS_C_NO_BUFFER && buffer->length != 0) - parseAssertion(buffer); - } - - gss_eap_saml_attr_ctx(const vector& attributes, - const saml2::Assertion *assertion = NULL) { - if (assertion != NULL) - m_assertion = dynamic_cast(assertion->clone()); - if (attributes.size()) - setAttributes(duplicateAttributes(attributes)); - } - - gss_eap_saml_attr_ctx(const gss_eap_saml_attr_ctx &ctx) { - gss_eap_saml_attr_ctx(ctx.m_attributes, ctx.m_assertion); - } - - ~gss_eap_saml_attr_ctx() { - for_each(m_attributes.begin(), - m_attributes.end(), - xmltooling::cleanup()) - ; - delete m_assertion; - } - - const vector getAttributes(void) const { - return m_attributes; - } - - void addAttribute(Attribute *attr, bool copy = true); - void setAttributes(const vector attributes); - - void setAttribute(int complete, - const gss_buffer_t attr, - const gss_buffer_t value); - void deleteAttribute(const gss_buffer_t attr); - - int getAttributeIndex(const gss_buffer_t attr) const; - const Attribute *getAttribute(const gss_buffer_t attr) const; - - bool getAttribute(const gss_buffer_t attr, - int *authenticated, - int *complete, - gss_buffer_t value, - gss_buffer_t display_value, - int *more); +class auto_ptr_gss_buffer { + MAKE_NONCOPYABLE(auto_ptr_gss_buffer); + public: + auto_ptr_gss_buffer() : m_buf(NULL) { + } + auto_ptr_gss_buffer(const gss_buffer_t src) { + m_buf = new XMLCh[src->length + 1]; + XMLString::transcode((const char *)src->value, m_buf, src->length); + } + ~auto_ptr_gss_buffer() { + xercesc::XMLString::release(&m_buf); + } + const XMLCh* get() const { + return m_buf; + } + XMLCh* release() { + XMLCh *temp = m_buf; m_buf = NULL; return temp; + } + private: + XMLCh *m_buf; +}; - const saml2::Assertion *getAssertion(void) const { - return m_assertion; +/* + * gss_eap_saml_assertion_provider is for retrieving the underlying + * assertion. + */ +gss_eap_saml_assertion_provider::gss_eap_saml_assertion_provider(const gss_eap_attr_ctx *ctx, + gss_cred_id_t gssCred, + gss_ctx_id_t gssCtx) + : gss_eap_attr_provider(ctx, gssCred, gssCtx) +{ + if (gssCtx == GSS_C_NO_CONTEXT) { + /* Then we are creating from an existing attribute context */ + gss_eap_saml_assertion_provider *saml; + + saml = dynamic_cast + (ctx->getProvider(ATTR_TYPE_SAML_ASSERTION)); + if (saml != NULL) + setAssertion(saml->getAssertion()); + } else { + gss_eap_radius_attr_provider *radius; + gss_buffer_desc value = GSS_C_EMPTY_BUFFER; + int authenticated, complete, more = -1; + OM_uint32 minor; + + radius = dynamic_cast + (ctx->getProvider(ATTR_TYPE_RADIUS)); + if (radius != NULL && + radius->getAttribute(512, &authenticated, &complete, + &value, NULL, &more)) { + m_assertion = parseAssertion(&value); + gss_release_buffer(&minor, &value); + } } +} - bool getAssertion(gss_buffer_t buffer); - - DDF marshall() const; - static gss_eap_saml_attr_ctx *unmarshall(DDF &in); - - void marshall(gss_buffer_t buffer); - static gss_eap_saml_attr_ctx *unmarshall(const gss_buffer_t buffer); - -private: - mutable vector m_attributes; - mutable saml2::Assertion *m_assertion; - - bool parseAssertion(const gss_buffer_t buffer); -}; +gss_eap_saml_assertion_provider::~gss_eap_saml_assertion_provider(void) +{ + delete m_assertion; +} -static OM_uint32 -mapException(OM_uint32 *minor, exception &e) +void +gss_eap_saml_assertion_provider::setAssertion(const saml2::Assertion *assertion) { - *minor = 0; - return GSS_S_FAILURE; + + delete m_assertion; + m_assertion = dynamic_cast(assertion->clone()); } -bool -gss_eap_saml_attr_ctx::parseAssertion(const gss_buffer_t buffer) +saml2::Assertion * +gss_eap_saml_assertion_provider::parseAssertion(const gss_buffer_t buffer) { - DOMDocument *doc; - const XMLObjectBuilder *b; - DOMElement *elem; - XMLObject *xobj; string str((char *)buffer->value, buffer->length); istringstream istream(str); + DOMDocument *doc; + const XMLObjectBuilder *b; doc = XMLToolingConfig::getConfig().getParser().parse(istream); - b = XMLObjectBuilder::getDefaultBuilder(); - elem = doc->getDocumentElement(); - xobj = b->buildOneFromElement(elem, true); - - m_assertion = dynamic_cast(xobj); + b = XMLObjectBuilder::getBuilder(doc->getDocumentElement()); - return (m_assertion != NULL); + return dynamic_cast(b->buildFromDocument(doc)); } -static inline void -duplicateBuffer(gss_buffer_desc &src, gss_buffer_t dst) +bool +gss_eap_saml_assertion_provider::getAttributeTypes(gss_eap_attr_enumeration_cb addAttribute, void *data) const { - OM_uint32 minor; - - if (GSS_ERROR(duplicateBuffer(&minor, &src, dst))) - throw new bad_alloc(); + addAttribute(this, GSS_C_NO_BUFFER, data); } -static inline void -duplicateBuffer(string &str, gss_buffer_t buffer) +void +gss_eap_saml_assertion_provider::setAttribute(int complete, + const gss_buffer_t attr, + const gss_buffer_t value) { - gss_buffer_desc tmp; - - tmp.length = str.length(); - tmp.value = (char *)str.c_str(); + saml2::Assertion *assertion = parseAssertion(value); - duplicateBuffer(tmp, buffer); + m_assertion = assertion; } -DDF -gss_eap_saml_attr_ctx::marshall() const +void +gss_eap_saml_assertion_provider::deleteAttribute(const gss_buffer_t value) { - DDF obj(NULL); - DDF attrs; - DDF assertion; - - obj.addmember("version").integer(1); - - attrs = obj.addmember("attributes").list(); - for (vector::const_iterator a = m_attributes.begin(); - a != m_attributes.end(); ++a) { - DDF attr = (*a)->marshall(); - attrs.add(attr); - } - - ostringstream sink; - sink << *m_assertion; - assertion = obj.addmember("assertion").string(sink.str().c_str()); - - return obj; + delete m_assertion; + m_assertion = NULL; } -gss_eap_saml_attr_ctx * -gss_eap_saml_attr_ctx::unmarshall(DDF &obj) +bool +gss_eap_saml_assertion_provider::getAttribute(const gss_buffer_t attr, + int *authenticated, + int *complete, + gss_buffer_t value, + gss_buffer_t display_value, + int *more) const { - gss_eap_saml_attr_ctx *ctx = new gss_eap_saml_attr_ctx(); + string str; - DDF version = obj["version"]; - if (version.integer() != 1) - return NULL; + if (attr->length != 0 || m_assertion == NULL) + return false; - DDF assertion = obj["assertion"]; - gss_buffer_desc buffer; + if (*more == -1) + *more = 0; - if (!assertion.isnull()) { - buffer.length = assertion.strlen(); - buffer.value = (void *)assertion.string(); - } else { - buffer.length = 0; - } + if (*more == 0) { + *authenticated = true; + *complete = false; - if (buffer.length != 0) - ctx->parseAssertion(&buffer); + XMLHelper::serialize(m_assertion->marshall((DOMDocument *)NULL), str); - DDF attrs = obj["attributes"]; - DDF attr = attrs.first(); - while (!attr.isnull()) { - Attribute *attribute = Attribute::unmarshall(attr); - ctx->addAttribute(attribute, false); - attr = attrs.next(); + duplicateBuffer(str, value); } - return ctx; + return true; } -void -gss_eap_saml_attr_ctx::marshall(gss_buffer_t buffer) +gss_any_t +gss_eap_saml_assertion_provider::mapToAny(int authenticated, + gss_buffer_t type_id) const { - DDF obj = marshall(); - ostringstream sink; - sink << obj; - string str = sink.str(); - - duplicateBuffer(str, buffer); - - obj.destroy(); + return (gss_any_t)m_assertion; } -gss_eap_saml_attr_ctx * -gss_eap_saml_attr_ctx::unmarshall(const gss_buffer_t buffer) +void +gss_eap_saml_assertion_provider::releaseAnyNameMapping(gss_buffer_t type_id, + gss_any_t input) const { - gss_eap_saml_attr_ctx *ctx; - - string str((const char *)buffer->value, buffer->length); - istringstream source(str); - DDF obj(NULL); - source >> obj; - - ctx = unmarshall(obj); - - obj.destroy(); - - return ctx; + delete ((saml2::Assertion *)input); } -bool -gss_eap_saml_attr_ctx::getAssertion(gss_buffer_t buffer) +void +gss_eap_saml_assertion_provider::marshall(gss_buffer_t buffer) const { + ostringstream sink; string str; - if (m_assertion == NULL) - return false; - - buffer->value = NULL; buffer->length = 0; + buffer->value = NULL; - XMLHelper::serialize(m_assertion->marshall((DOMDocument *)NULL), str); + if (m_assertion == NULL) + return; - duplicateBuffer(str, buffer); + sink << *m_assertion; + str = sink.str(); - return true; + duplicateBuffer(str, buffer); } -static Attribute * -duplicateAttribute(const Attribute *src) +gss_eap_attr_provider * +gss_eap_saml_assertion_provider::unmarshall(const gss_eap_attr_ctx *ctx, + const gss_buffer_t buffer) { - Attribute *attribute; - - DDF obj = src->marshall(); - attribute = Attribute::unmarshall(obj); - obj.destroy(); - - return attribute; + return new gss_eap_saml_assertion_provider(ctx, buffer); } -static vector -duplicateAttributes(const vector src) +bool +gss_eap_saml_assertion_provider::init(void) { - vector dst; - - for (vector::const_iterator a = src.begin(); - a != src.end(); - ++a) - dst.push_back(duplicateAttribute(*a)); - - return dst; } void -gss_eap_saml_attr_ctx::addAttribute(Attribute *attribute, bool copy) +gss_eap_saml_assertion_provider::finalize(void) { - Attribute *a; - - a = copy ? duplicateAttribute(attribute) : attribute; - - m_attributes.push_back(a); } -void -gss_eap_saml_attr_ctx::setAttributes(const vector attributes) +gss_eap_attr_provider * +gss_eap_saml_assertion_provider::createAttrContext(const gss_eap_attr_ctx *ctx, + gss_cred_id_t gssCred, + gss_ctx_id_t gssCtx) { - for_each(m_attributes.begin(), m_attributes.end(), xmltooling::cleanup()); - m_attributes = attributes; + return new gss_eap_saml_assertion_provider(ctx, gssCred, gssCtx); } -int -gss_eap_saml_attr_ctx::getAttributeIndex(const gss_buffer_t attr) const +/* + * gss_eap_saml_attr_provider is for retrieving the underlying attributes. + */ +const saml2::Assertion * +gss_eap_saml_attr_provider::getAssertion(void) const { - int i = 0; + gss_eap_saml_assertion_provider *saml; + + saml = dynamic_cast(m_source->getProvider(ATTR_TYPE_SAML_ASSERTION)); + assert(saml != NULL); - for (vector::const_iterator a = getAttributes().begin(); - a != getAttributes().end(); - ++a) - { - for (vector::const_iterator s = (*a)->getAliases().begin(); - s != (*a)->getAliases().end(); - ++s) { - if (attr->length == (*s).length() && - memcmp((*s).c_str(), attr->value, attr->length) == 0) { - return i; - } - } - } - - return -1; + return saml->getAssertion(); } -const Attribute * -gss_eap_saml_attr_ctx::getAttribute(const gss_buffer_t attr) const +gss_eap_saml_attr_provider::gss_eap_saml_attr_provider(const gss_eap_attr_ctx *ctx, + gss_cred_id_t gssCred, + gss_ctx_id_t gssCtx) + : gss_eap_attr_provider(ctx, gssCred, gssCtx) { - const Attribute *ret = NULL; - - for (vector::const_iterator a = getAttributes().begin(); - a != getAttributes().end(); - ++a) - { - for (vector::const_iterator s = (*a)->getAliases().begin(); - s != (*a)->getAliases().end(); - ++s) { - if (attr->length == (*s).length() && - memcmp((*s).c_str(), attr->value, attr->length) == 0) { - ret = *a; - break; - } - } - if (ret != NULL) - break; - } + /* Nothing to do, we're just a wrapper around the assertion provider. */ +} - return ret; +gss_eap_saml_attr_provider::~gss_eap_saml_attr_provider(void) +{ + /* Nothing to do, we're just a wrapper around the assertion provider. */ } bool -gss_eap_saml_attr_ctx::getAttribute(const gss_buffer_t attr, - int *authenticated, - int *complete, - gss_buffer_t value, - gss_buffer_t display_value, - int *more) +gss_eap_saml_attr_provider::getAttributeTypes(gss_eap_attr_enumeration_cb addAttribute, + void *data) const { - const Attribute *shibAttr = NULL; - gss_buffer_desc buf; + const saml2::Assertion *assertion = getAssertion(); - shibAttr = getAttribute(attr); - if (shibAttr == NULL) - return false; - - if (*more == -1) { - *more = 0; - } else if (*more >= (int)shibAttr->valueCount()) { - *more = 0; + if (assertion == NULL) return true; - } - - buf.value = (void *)shibAttr->getString(*more); - buf.length = strlen((char *)buf.value); - - duplicateBuffer(buf, value); - - *authenticated = TRUE; - *complete = FALSE; - return true; -} - -static Attribute * -samlAttributeFromGssBuffers(const gss_buffer_t attr, - const gss_buffer_t value) -{ - string attrStr((char *)attr->value, attr->length); - vector ids(1); - SimpleAttribute *a; - - ids.push_back(attrStr); + const vector& attrs2 = + const_cast(assertion->getAttributeStatements().front())->getAttributes(); + for (vector::const_iterator a = attrs2.begin(); + a != attrs2.end(); + ++a) + { + gss_buffer_desc attribute; - a = new SimpleAttribute(ids); + attribute.value = (void *)toUTF8((*a)->getName(), true); + attribute.length = strlen((char *)attribute.value); - if (value->length != 0) { - string valStr((char *)value->value, value->length); + if (!addAttribute(this, &attribute, data)) + return false; - a->getValues().push_back(valStr); + delete (char *)attribute.value; } - return a; + return true; } void -gss_eap_saml_attr_ctx::setAttribute(int complete, - const gss_buffer_t attr, - const gss_buffer_t value) +gss_eap_saml_attr_provider::setAttribute(int complete, + const gss_buffer_t attr, + const gss_buffer_t value) { - Attribute *a = samlAttributeFromGssBuffers(attr, value); - - addAttribute(a, false); } void -gss_eap_saml_attr_ctx::deleteAttribute(const gss_buffer_t attr) -{ - int i; - - i = getAttributeIndex(attr); - if (i >= 0) - m_attributes.erase(m_attributes.begin() + i); -} - -OM_uint32 -samlReleaseAttrContext(OM_uint32 *minor, gss_name_t name) -{ - try { - delete name->samlCtx; - name->samlCtx = NULL; - } catch (exception &e) { - return mapException(minor, e); - } - - return GSS_S_COMPLETE; -} - -static gss_buffer_desc -gssEapRadiusAssertionAttr = { 3, (void *)"128" }; - -static OM_uint32 -samlAddRadiusAttribute(OM_uint32 *minor, - gss_name_t name, - gss_buffer_t attr, - void *data) -{ - OM_uint32 major; - ShibbolethResolver *resolver = (ShibbolethResolver *)resolver; - Attribute *a; - int authenticated, complete, more = -1; - gss_buffer_desc value; - - if (bufferEqual(attr, &gssEapRadiusAssertionAttr)) { - return GSS_S_COMPLETE; - } - - major = radiusGetAttribute(minor, name, attr, - &authenticated, &complete, - &value, GSS_C_NO_BUFFER, &more); - if (major == GSS_S_COMPLETE) { - /* Do some prefixing? */ - a = samlAttributeFromGssBuffers(attr, &value); - /* XXX leaky */ - resolver->addAttribute(a); - } - - return GSS_S_COMPLETE; -} - -static OM_uint32 -samlAddRadiusAttributes(OM_uint32 *minor, - gss_name_t name, - ShibbolethResolver *resolver) +gss_eap_saml_attr_provider::deleteAttribute(const gss_buffer_t value) { - return radiusGetAttributeTypes(minor, - name, - samlAddRadiusAttribute, - (void *)resolver); } -static OM_uint32 -samlInitAttrContextFromRadius(OM_uint32 *minor, - gss_name_t name, - gss_eap_saml_attr_ctx **pSamlCtx) +const saml2::Attribute * +gss_eap_saml_attr_provider::getAttribute(const gss_buffer_t attr) const { - OM_uint32 major; - int authenticated, complete, more = -1; - gss_buffer_desc value; - - value.value = NULL; - value.length = 0; - - major = radiusGetAttribute(minor, name, &gssEapRadiusAssertionAttr, - &authenticated, &complete, - &value, GSS_C_NO_BUFFER, &more); - if (major == GSS_S_UNAVAILABLE) { - /* No assertion provided via RADIUS. */ - value.length = 0; - value.value = NULL; - } else if (GSS_ERROR(major)) { - /* Some other error */ - return major; - } - - *pSamlCtx = new gss_eap_saml_attr_ctx(&value); - - gss_release_buffer(minor, &value); - - return GSS_S_COMPLETE; -} - -OM_uint32 -samlCreateAttrContext(OM_uint32 *minor, - gss_cred_id_t acceptorCred, - gss_name_t initiatorName, - time_t *pExpiryTime) -{ - OM_uint32 major, tmpMinor; - gss_buffer_desc nameBuf; - gss_eap_saml_attr_ctx *ctx = NULL; - ShibbolethResolver *resolver = NULL; - - assert(initiatorName != GSS_C_NO_NAME); - - nameBuf.length = 0; - nameBuf.value = NULL; - - resolver = ShibbolethResolver::create(); - if (resolver == NULL) - return GSS_S_FAILURE; - - if (acceptorCred != GSS_C_NO_CREDENTIAL) { - major = gss_display_name(minor, acceptorCred->name, &nameBuf, NULL); - if (GSS_ERROR(major)) - goto cleanup; - } - - try { - const saml2::Assertion *assertion; - vector attrs; - - major = samlInitAttrContextFromRadius(minor, initiatorName, &ctx); - if (GSS_ERROR(major)) - goto cleanup; - - assertion = ctx->getAssertion(); - - if (assertion != NULL) { - if (assertion->getConditions()) { - *pExpiryTime = - assertion->getConditions()->getNotOnOrAfter()->getEpoch(); - } - - resolver->addToken(assertion); - } - - if (initiatorName->radiusCtx != NULL) { - samlAddRadiusAttributes(minor, initiatorName, resolver); - } - - resolver->resolveAttributes(attrs); - ctx->setAttributes(attrs); - } catch (exception &ex) { - major = mapException(minor, ex); - goto cleanup; - } - - *minor = 0; - major = GSS_S_COMPLETE; - - initiatorName->samlCtx = ctx; + const saml2::Assertion *assertion = getAssertion(); + saml2::AttributeStatement *statement; -cleanup: - gss_release_buffer(&tmpMinor, &nameBuf); - if (GSS_ERROR(major)) - delete ctx; - delete resolver; - - return major; -} + if (assertion == NULL) + return NULL; -OM_uint32 -samlGetAttributeTypes(OM_uint32 *minor, - gss_name_t name, - enum gss_eap_attribute_type type, - gss_eap_add_attr_cb addAttribute, - void *data) -{ - OM_uint32 major = GSS_S_COMPLETE; - gss_eap_saml_attr_ctx *ctx = name->samlCtx; + if (assertion->getAttributeStatements().size() == 0) + return NULL; - if (ctx == NULL) - return GSS_S_COMPLETE; + statement = assertion->getAttributeStatements().front(); - if (type != ATTR_TYPE_NONE) - return GSS_S_UNAVAILABLE; + auto_ptr_gss_buffer attrname(attr); - for (vector::const_iterator a = ctx->getAttributes().begin(); - a != ctx->getAttributes().end(); - ++a) - { - gss_buffer_desc attribute; + const vector& attrs2 = + const_cast(statement)->getAttributes(); - attribute.value = (void *)((*a)->getId()); - attribute.length = strlen((char *)attribute.value); - - major = addAttribute(minor, name, &attribute, data); - if (GSS_ERROR(major)) - break; + for (vector::const_iterator a = attrs2.begin(); + a != attrs2.end(); + ++a) { + if (XMLString::equals((*a)->getName(), attrname.get())) + return *a; } - return major; + return NULL; } -/* - * SAML implementation of gss_get_name_attribute - */ -OM_uint32 -samlGetAttribute(OM_uint32 *minor, - enum gss_eap_attribute_type type, - gss_name_t name, - gss_buffer_t attr, - int *authenticated, - int *complete, - gss_buffer_t value, - gss_buffer_t display_value, - int *more) -{ - struct gss_eap_saml_attr_ctx *ctx = name->samlCtx; - bool ret; - - if (ctx == NULL) - return GSS_S_UNAVAILABLE; - - switch (type) { - case ATTR_TYPE_NONE: - ret = ctx->getAttribute(attr, authenticated, complete, - value, display_value, more); - break; - default: - ret = false; - break; - } - - return ret ? GSS_S_COMPLETE : GSS_S_UNAVAILABLE; -} - -OM_uint32 -samlSetAttribute(OM_uint32 *minor, - gss_name_t name, - int complete, - gss_buffer_t attr, - gss_buffer_t value) +bool +gss_eap_saml_attr_provider::getAttribute(const gss_buffer_t attr, + int *authenticated, + int *complete, + gss_buffer_t value, + gss_buffer_t display_value, + int *more) const { - struct gss_eap_saml_attr_ctx *ctx = name->samlCtx; - - if (ctx == NULL) - return GSS_S_UNAVAILABLE; + const saml2::Attribute *a; + const saml2::AttributeValue *av; + int nvalues, i = *more; - try { - ctx->setAttribute(complete, attr, value); - } catch (exception &e) { - return mapException(minor, e); - } - - return GSS_S_COMPLETE; -} + *more = 0; -OM_uint32 -samlDeleteAttribute(OM_uint32 *minor, - gss_name_t name, - gss_buffer_t attr) -{ - struct gss_eap_saml_attr_ctx *ctx = name->samlCtx; + a = getAttribute(attr); + if (a == NULL) + return false; - if (ctx == NULL) - return GSS_S_UNAVAILABLE; + nvalues = a->getAttributeValues().size(); - try { - ctx->deleteAttribute(attr); - } catch (exception &e) { - return mapException(minor, e); - } + if (i == -1) + i = 0; + else if (i >= nvalues) + return false; + av = dynamic_cast(a->getAttributeValues().at(i) +); + if (av == NULL) + return false; - return GSS_S_COMPLETE; -} + *authenticated = TRUE; + *complete = FALSE; -/* - * In order to implement gss_export_name and gss_export_sec_context, - * we need to serialise a resolved attribute context to a buffer. - */ -OM_uint32 -samlExportAttrContext(OM_uint32 *minor, - gss_name_t name, - gss_buffer_t buffer) -{ - struct gss_eap_saml_attr_ctx *ctx = name->samlCtx; + value->value = toUTF8(av->getTextContent(), true); + value->length = strlen((char *)value->value); - try { - ctx->marshall(buffer); - } catch (exception &e) { - return mapException(minor, e); - } + if (nvalues > ++i) + *more = i; - return GSS_S_COMPLETE; + return true; } -/* - * In order to implement gss_import_name and gss_import_sec_context, - * we need to deserialise a resolved attribute context from a buffer. - */ -OM_uint32 -samlImportAttrContext(OM_uint32 *minor, - gss_buffer_t buffer, - gss_name_t name) +gss_any_t +gss_eap_saml_attr_provider::mapToAny(int authenticated, + gss_buffer_t type_id) const { - try { - assert(name->samlCtx == NULL); - name->samlCtx = gss_eap_saml_attr_ctx::unmarshall(buffer); - } catch (exception &e) { - return mapException(minor, e); - } - - return GSS_S_COMPLETE; + return (gss_any_t)0; } -OM_uint32 -samlGetAssertion(OM_uint32 *minor, - gss_name_t name, - gss_buffer_t assertion) +void +gss_eap_saml_attr_provider::releaseAnyNameMapping(gss_buffer_t type_id, + gss_any_t input) const { - struct gss_eap_saml_attr_ctx *ctx = name->samlCtx; - - if (ctx == NULL) - return GSS_S_UNAVAILABLE; - - try { - ctx->getAssertion(assertion); - } catch (exception &e) { - return mapException(minor, e); - } - - return GSS_S_COMPLETE; } -OM_uint32 -samlDuplicateAttrContext(OM_uint32 *minor, - gss_name_t in, - gss_name_t out) +void +gss_eap_saml_attr_provider::marshall(gss_buffer_t buffer) const { - try { - if (in->samlCtx != NULL) - out->samlCtx = new gss_eap_saml_attr_ctx(*(in->samlCtx)); - else - out->samlCtx = NULL; - } catch (exception &e) { - return mapException(minor, e); - } - - return GSS_S_COMPLETE; } -OM_uint32 -samlMapNameToAny(OM_uint32 *minor, - gss_name_t name, - int authenticated, - gss_buffer_t type_id, - gss_any_t *output) +gss_eap_attr_provider * +gss_eap_saml_attr_provider::unmarshall(const gss_eap_attr_ctx *ctx, + const gss_buffer_t buffer) { - struct gss_eap_saml_attr_ctx *ctx = name->samlCtx; - - if (bufferEqualString(type_id, "shibsp::Attribute")) { - vector v = duplicateAttributes(ctx->getAttributes()); - - *output = (gss_any_t)new vector (v); - } else if (bufferEqualString(type_id, "opensaml::Assertion")) { - *output = (gss_any_t)ctx->getAssertion()->clone(); - } else { - *output = (gss_any_t)NULL; - return GSS_S_UNAVAILABLE; - } - - return GSS_S_COMPLETE; + return new gss_eap_saml_attr_provider(ctx); } -OM_uint32 -samlReleaseAnyNameMapping(OM_uint32 *minor, - gss_name_t name, - gss_buffer_t type_id, - gss_any_t *input) +bool +gss_eap_saml_attr_provider::init(void) { - if (bufferEqualString(type_id, "vector")) { - vector *v = ((vector *)*input); - delete v; - } else if (bufferEqualString(type_id, "opensaml::Assertion")) { - delete (Assertion *)*input; - } else { - return GSS_S_UNAVAILABLE; - } - - *input = (gss_any_t)NULL; - return GSS_S_COMPLETE; + return true; } -OM_uint32 -samlInit(OM_uint32 *minor) +void +gss_eap_saml_attr_provider::finalize(void) { - *minor = 0; - - return ShibbolethResolver::init() ? GSS_S_COMPLETE : GSS_S_FAILURE; } -OM_uint32 -samlFinalize(OM_uint32 *minor) +gss_eap_attr_provider * +gss_eap_saml_attr_provider::createAttrContext(const gss_eap_attr_ctx *ctx, + gss_cred_id_t gssCred, + gss_ctx_id_t gssCtx) { - *minor = 0; - - ShibbolethResolver::term(); - return GSS_S_COMPLETE; + return new gss_eap_saml_attr_provider(ctx, gssCred, gssCtx); }