attrinclude_HEADERS = \
attribute/Attribute.h \
attribute/AttributeDecoder.h \
+ attribute/ExtensibleAttribute.h \
attribute/NameIDAttribute.h \
attribute/ScopedAttribute.h \
attribute/SimpleAttribute.h
ServiceProvider.cpp \
SPConfig.cpp \
attribute/Attribute.cpp \
+ attribute/ExtensibleAttribute.cpp \
handler/impl/AbstractHandler.cpp \
handler/impl/AssertionConsumerService.cpp \
handler/impl/AssertionLookup.cpp \
#include "attribute/SimpleAttribute.h"
#include "attribute/ScopedAttribute.h"
#include "attribute/NameIDAttribute.h"
+#include "attribute/ExtensibleAttribute.h"
#include "util/SPConstants.h"
#include <xercesc/util/XMLUniDefs.hpp>
return new NameIDAttribute(in);
}
+ SHIBSP_DLLLOCAL Attribute* ExtensibleAttributeFactory(DDF& in) {
+ return new ExtensibleAttribute(in);
+ }
+
#ifndef SHIBSP_LITE
SHIBSP_DLLLOCAL PluginManager<AttributeDecoder,xmltooling::QName,const DOMElement*>::Factory StringAttributeDecoderFactory;
SHIBSP_DLLLOCAL PluginManager<AttributeDecoder,xmltooling::QName,const DOMElement*>::Factory ScopedAttributeDecoderFactory;
Attribute::registerFactory("Simple", SimpleAttributeFactory);
Attribute::registerFactory("Scoped", ScopedAttributeFactory);
Attribute::registerFactory("NameID", NameIDAttributeFactory);
+ Attribute::registerFactory("Extensible", ExtensibleAttributeFactory);
}
-std::map<std::string,Attribute::AttributeFactory*> Attribute::m_factoryMap;
+map<string,Attribute::AttributeFactory*> Attribute::m_factoryMap;
Attribute* Attribute::unmarshall(DDF& in)
{
map<string,AttributeFactory*>::const_iterator i = m_factoryMap.find(in.name() ? in.name() : "");
if (i == m_factoryMap.end())
- throw AttributeException("No registered factory for Attribute of type ($1).", xmltooling::params(1,in.name()));
+ throw AttributeException("No registered factory for Attribute of type ($1).", params(1,in.name()));
return (i->second)(in);
}
--- /dev/null
+/*
+ * Copyright 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.
+ */
+
+/**
+ * shibsp/attribute/ExtensibleAttribute.cpp
+ *
+ * An Attribute whose values are arbitrary structures.
+ */
+
+#include "internal.h"
+#include "SPConfig.h"
+#include "attribute/ExtensibleAttribute.h"
+#include "util/SPConstants.h"
+
+using namespace shibsp;
+using namespace xmltooling;
+using namespace std;
+
+
+const vector<string>& ExtensibleAttribute::getSerializedValues() const
+{
+ if (m_serialized.empty()) {
+ const char* formatter = m_obj["_formatter"].string();
+ if (formatter) {
+ string msg = formatter;
+ DDF val = m_obj.first().first();
+ while (!val.isnull()) {
+
+ static const char* legal="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890_";
+
+ m_serialized.push_back(string());
+ string& processed = m_serialized.back();
+
+ string::size_type i=0,start=0;
+ while (start!=string::npos && start<msg.length() && (i=msg.find("$",start))!=string::npos) {
+ if (i>start)
+ processed += msg.substr(start,i-start); // append everything in between
+ start=i+1; // move start to the beginning of the token name
+ i=msg.find_first_not_of(legal,start); // find token delimiter
+ if (i==start) { // append a non legal character
+ processed+=msg[start++];
+ continue;
+ }
+
+ string tag = msg.substr(start,(i==string::npos) ? i : i-start);
+ if (tag == "_string" && val.string()) {
+ processed += val.string();
+ start=i;
+ }
+ else {
+ DDF child = val.getmember(tag.c_str());
+ if (child.string())
+ processed += child.string();
+ start=i;
+ }
+ }
+ if (start!=string::npos && start<msg.length())
+ processed += msg.substr(start,i); // append rest of string
+
+ val = m_obj.first().next();
+ }
+ }
+ }
+ return Attribute::getSerializedValues();
+}
--- /dev/null
+/*
+ * Copyright 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.
+ */
+
+/**
+ * @file shibsp/attribute/ExtensibleAttribute.h
+ *
+ * An Attribute whose values are arbitrary structures.
+ */
+
+#ifndef __shibsp_extattr_h__
+#define __shibsp_extattr_h__
+
+#include <shibsp/attribute/Attribute.h>
+#include <xmltooling/exceptions.h>
+
+namespace shibsp {
+
+#if defined (_MSC_VER)
+ #pragma warning( push )
+ #pragma warning( disable : 4251 )
+#endif
+
+ /**
+ * An Attribute whose values are arbitrary structures.
+ */
+ class SHIBSP_API ExtensibleAttribute : public Attribute
+ {
+ public:
+ /**
+ * Constructor.
+ *
+ * @param ids array with primary identifier in first position, followed by any aliases
+ * @param formatter template for serialization of values
+ */
+ ExtensibleAttribute(const std::vector<std::string>& ids, const char* formatter) : Attribute(ids) {
+ m_obj = Attribute::marshall();
+ m_obj.name("Extensible");
+ m_obj.addmember("_formatter").string(formatter);
+ }
+
+ /**
+ * Constructs based on a remoted ExtensibleAttribute.
+ *
+ * @param in input object containing marshalled ExtensibleAttribute
+ */
+ ExtensibleAttribute(DDF& in) : Attribute(in), m_obj(in.copy()) {
+ }
+
+ virtual ~ExtensibleAttribute() {}
+
+ /**
+ * Returns the set of values in a DDF list.
+ *
+ * @return a mutable list object containing the values
+ */
+ DDF getValues() {
+ return m_obj.first();
+ }
+
+ size_t valueCount() const {
+ return m_obj.first().integer();
+ }
+
+ void clearSerializedValues() {
+ m_serialized.clear();
+ }
+
+ const char* getString(size_t index) const {
+ return m_obj.first()[static_cast<unsigned long>(index)].string();
+ }
+
+ const char* getScope(size_t index) const {
+ return NULL;
+ }
+
+ void removeValue(size_t index) {
+ Attribute::removeValue(index);
+ DDF vals = m_obj.first();
+ if (index < static_cast<size_t>(vals.integer()))
+ vals[static_cast<unsigned long>(index)].remove().destroy();
+ }
+
+ const std::vector<std::string>& getSerializedValues() const;
+
+ DDF marshall() const {
+ return m_obj.copy();
+ }
+
+ private:
+ mutable DDF m_obj;
+ };
+
+#if defined (_MSC_VER)
+ #pragma warning( pop )
+#endif
+
+};
+
+#endif /* __shibsp_nameidattr_h__ */
/**
* @file shibsp/attribute/NameIDAttribute.h
*
- * An Attribute whose values are relations of a value and a scope.
+ * An Attribute whose values are derived from or mappable to a SAML NameID.
*/
#ifndef __shibsp_nameidattr_h__
/*
- * Copyright 2001-2007 Internet2
+ * 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.
/** AttributeExtractor based on an XML mapping schema. */
#define XML_ATTRIBUTE_EXTRACTOR "XML"
+ /** AttributeExtractor for DelegationRestriction information. */
+ #define DELEGATION_ATTRIBUTE_EXTRACTOR "Delegation"
+
/** AttributeExtractor based on chaining together other extractors. */
#define CHAINING_ATTRIBUTE_EXTRACTOR "Chaining"
};
/*
- * Copyright 2001-2007 Internet2
+ * 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.
static const XMLCh _type[] = UNICODE_LITERAL_4(t,y,p,e);
SHIBSP_DLLLOCAL PluginManager<AttributeExtractor,string,const DOMElement*>::Factory XMLAttributeExtractorFactory;
+ SHIBSP_DLLLOCAL PluginManager<AttributeExtractor,string,const DOMElement*>::Factory DelegationAttributeExtractorFactory;
AttributeExtractor* SHIBSP_DLLLOCAL ChainingExtractorFactory(const DOMElement* const & e)
{
return new ChainingAttributeExtractor(e);
void SHIBSP_API shibsp::registerAttributeExtractors()
{
+ SPConfig::getConfig().AttributeExtractorManager.registerFactory(DELEGATION_ATTRIBUTE_EXTRACTOR, DelegationAttributeExtractorFactory);
SPConfig::getConfig().AttributeExtractorManager.registerFactory(XML_ATTRIBUTE_EXTRACTOR, XMLAttributeExtractorFactory);
SPConfig::getConfig().AttributeExtractorManager.registerFactory(CHAINING_ATTRIBUTE_EXTRACTOR, ChainingExtractorFactory);
}
--- /dev/null
+/*
+ * Copyright 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.
+ */
+
+/**
+ * DelegationAttributeExtractor.cpp
+ *
+ * AttributeExtractor for DelegationRestriction information.
+ */
+
+#include "internal.h"
+#include "Application.h"
+#include "ServiceProvider.h"
+#include "attribute/ExtensibleAttribute.h"
+#include "attribute/resolver/AttributeExtractor.h"
+#include "util/SPConstants.h"
+
+#include <saml/saml2/core/Assertions.h>
+#include <saml/saml2/metadata/MetadataCredentialCriteria.h>
+#include <xmltooling/util/XMLHelper.h>
+#include <xercesc/util/XMLUniDefs.hpp>
+
+using namespace shibsp;
+using namespace opensaml::saml2md;
+using namespace opensaml;
+using namespace xmltooling;
+using namespace std;
+
+namespace shibsp {
+
+#if defined (_MSC_VER)
+ #pragma warning( push )
+ #pragma warning( disable : 4250 )
+#endif
+
+ class DelegationExtractor : public AttributeExtractor
+ {
+ public:
+ DelegationExtractor(const DOMElement* e);
+ ~DelegationExtractor() {}
+
+ Lockable* lock() {
+ return this;
+ }
+
+ void unlock() {
+ }
+
+ void extractAttributes(
+ const Application& application, const RoleDescriptor* issuer, const XMLObject& xmlObject, vector<Attribute*>& attributes
+ ) const;
+
+ void getAttributeIds(std::vector<std::string>& attributes) const {
+ attributes.push_back(m_attributeId);
+ }
+
+ private:
+ string m_attributeId,m_formatter;
+ };
+
+#if defined (_MSC_VER)
+ #pragma warning( pop )
+#endif
+
+ AttributeExtractor* SHIBSP_DLLLOCAL DelegationAttributeExtractorFactory(const DOMElement* const & e)
+ {
+ return new DelegationExtractor(e);
+ }
+
+ static const XMLCh attributeId[] = UNICODE_LITERAL_11(a,t,t,r,i,b,u,t,e,I,d);
+ static const XMLCh formatter[] = UNICODE_LITERAL_9(f,o,r,m,a,t,t,e,r);
+};
+
+DelegationExtractor::DelegationExtractor(const DOMElement* e) : m_attributeId("delegate"), m_formatter("$Name")
+{
+ if (e) {
+ const XMLCh* a = e->getAttributeNS(NULL, attributeId);
+ if (a && *a) {
+ auto_ptr_char temp(a);
+ m_attributeId = temp.get();
+ }
+ a = e->getAttributeNS(NULL, formatter);
+ if (a && *a) {
+ auto_ptr_char temp(a);
+ m_formatter = temp.get();
+ }
+ }
+}
+
+void DelegationExtractor::extractAttributes(
+ const Application& application, const RoleDescriptor* issuer, const XMLObject& xmlObject, vector<Attribute*>& attributes
+ ) const
+{
+ const saml2::Assertion* assertion = dynamic_cast<const saml2::Assertion*>(&xmlObject);
+ if (!assertion || !assertion->getConditions())
+ return;
+
+ const vector<saml2::Condition*>& conditions = const_cast<const saml2::Conditions*>(assertion->getConditions())->getConditions();
+ for (vector<saml2::Condition*>::const_iterator c = conditions.begin(); c != conditions.end(); ++c) {
+ const saml2::DelegationRestrictionType* drt = dynamic_cast<const saml2::DelegationRestrictionType*>(*c);
+ if (drt) {
+ auto_ptr<ExtensibleAttribute> attr(new ExtensibleAttribute(vector<string>(1,m_attributeId), m_formatter.c_str()));
+
+ const vector<saml2::Delegate*>& dels = drt->getDelegates();
+ for (vector<saml2::Delegate*>::const_iterator d = dels.begin(); d != dels.end(); ++d) {
+ if ((*d)->getBaseID()) {
+ Category::getInstance(SHIBSP_LOGCAT".AttributeExtractor.Delegation").error(
+ "delegate identified by saml:BaseID cannot be processed into an attribute value"
+ );
+ continue;
+ }
+
+ saml2::NameID* n = NULL;
+ if ((*d)->getEncryptedID()) {
+ // TODO: add decryption
+ }
+ else {
+ n = (*d)->getNameID();
+ }
+ if (n) {
+ DDF val = DDF(NULL).structure();
+ if ((*d)->getConfirmationMethod()) {
+ auto_ptr_char temp((*d)->getConfirmationMethod());
+ val.addmember("ConfirmationMethod").string(temp.get());
+ }
+ if ((*d)->getDelegationInstant()) {
+ auto_ptr_char temp((*d)->getDelegationInstant()->getRawData());
+ val.addmember("DelegationInstant").string(temp.get());
+ }
+
+ auto_arrayptr<char> name(toUTF8(n->getName()));\r
+ if (name.get() && *name.get()) {\r
+ val.addmember("Name").string(name.get());\r
+ char* str = toUTF8(n->getFormat());\r
+ if (str && *str)\r
+ val.addmember("Format").string(str);\r
+ delete[] str;\r
+\r
+ str = toUTF8(n->getNameQualifier());\r
+ if (str && *str)\r
+ val.addmember("NameQualifier").string(str);\r
+ delete[] str;\r
+\r
+ str = toUTF8(n->getSPNameQualifier());\r
+ if (str && *str)\r
+ val.addmember("SPNameQualifier").string(str);\r
+ delete[] str;\r
+\r
+ str = toUTF8(n->getSPProvidedID());\r
+ if (str && *str)\r
+ val.addmember("SPProvidedID").string(str);\r
+ delete[] str;\r
+ }\r
+
+ if (n != (*d)->getNameID())
+ delete n;
+
+ if (val.integer())
+ attr->getValues().add(val);
+ else
+ val.destroy();
+ }
+ }
+
+ attributes.push_back(attr.release());
+ }
+ }
+}
RelativePath=".\attribute\Attribute.cpp"\r
>\r
</File>\r
+ <File\r
+ RelativePath=".\attribute\ExtensibleAttribute.cpp"\r
+ >\r
+ </File>\r
</Filter>\r
<Filter\r
Name="handler"\r
>\r
</File>\r
<File\r
+ RelativePath=".\attribute\ExtensibleAttribute.h"\r
+ >\r
+ </File>\r
+ <File\r
RelativePath=".\attribute\NameIDAttribute.h"\r
>\r
</File>\r
>\r
</File>\r
<File\r
+ RelativePath=".\attribute\ExtensibleAttribute.cpp"\r
+ >\r
+ </File>\r
+ <File\r
RelativePath=".\attribute\NameIDAttributeDecoder.cpp"\r
>\r
</File>\r
>\r
</File>\r
<File\r
+ RelativePath=".\attribute\resolver\impl\DelegationAttributeExtractor.cpp"\r
+ >\r
+ </File>\r
+ <File\r
RelativePath=".\attribute\resolver\impl\QueryAttributeResolver.cpp"\r
>\r
</File>\r
>\r
</File>\r
<File\r
+ RelativePath=".\attribute\ExtensibleAttribute.h"\r
+ >\r
+ </File>\r
+ <File\r
RelativePath=".\attribute\NameIDAttribute.h"\r
>\r
</File>\r