Fix old namespace defaults.
authorcantor <cantor@cb58f699-b61c-0410-a6fe-9272a202ed29>
Mon, 30 Apr 2007 19:17:54 +0000 (19:17 +0000)
committercantor <cantor@cb58f699-b61c-0410-a6fe-9272a202ed29>
Mon, 30 Apr 2007 19:17:54 +0000 (19:17 +0000)
Fix vararg error in NameID attribute class.
Working extractor/resolver code.

git-svn-id: https://svn.middleware.georgetown.edu/cpp-sp/trunk@2227 cb58f699-b61c-0410-a6fe-9272a202ed29

apache/mod_apache.cpp
configs/shibboleth.xml.in
nsapi_shib/nsapi_shib.cpp
shibsp/attribute/NameIDAttribute.h
shibsp/attribute/resolver/impl/XMLAttributeExtractor.cpp
shibsp/impl/XMLRequestMapper.cpp
shibsp/impl/XMLServiceProvider.cpp
shibsp/util/DOMPropertySet.h
shibsp/util/PropertySet.h

index 319820c..83ef310 100644 (file)
@@ -585,7 +585,7 @@ public:
     pair<bool,const XMLCh*> getXMLString(const char* name, const char* ns=NULL) const;
     pair<bool,unsigned int> getUnsignedInt(const char* name, const char* ns=NULL) const;
     pair<bool,int> getInt(const char* name, const char* ns=NULL) const;
-    const PropertySet* getPropertySet(const char* name, const char* ns="urn:mace:shibboleth:target:config:1.0") const;
+    const PropertySet* getPropertySet(const char* name, const char* ns="urn:mace:shibboleth:2.0:native:sp:config") const;
     const xercesc::DOMElement* getElement() const;
 
 private:
index e40af74..07bd8ec 100644 (file)
 
                <!-- Map to extract attributes from SAML assertions. -->
                <AttributeExtractor type="XML" path="@-PKGSYSCONFDIR-@/attribute-map.xml"/>
+               
+               <!-- Use a SAML query if no attributes are supplied during SSO. -->
+               <AttributeResolver type="Query"/>
 
                <!-- Simple file-based resolver for key/certificate information. -->
                <CredentialResolver type="File">
index 3ef06e2..6df0c07 100644 (file)
@@ -444,7 +444,7 @@ public:
     pair<bool,const XMLCh*> getXMLString(const char* name, const char* ns=NULL) const;
     pair<bool,unsigned int> getUnsignedInt(const char* name, const char* ns=NULL) const;
     pair<bool,int> getInt(const char* name, const char* ns=NULL) const;
-    const PropertySet* getPropertySet(const char* name, const char* ns="urn:mace:shibboleth:target:config:1.0") const;
+    const PropertySet* getPropertySet(const char* name, const char* ns="urn:mace:shibboleth:2.0:native:sp:config") const;
     const xercesc::DOMElement* getElement() const;
 
 private:
index 1e05a4d..b2fbfc9 100644 (file)
@@ -120,11 +120,11 @@ namespace shibsp {
                         m_formatter,
                         xmltooling::namedparams(
                             5,
-                            "Name", i->m_Name,
-                            "Format", i->m_Format,
-                            "NameQualifier", i->m_NameQualifier,
-                            "SPNameQualifier", i->m_SPNameQualifier,
-                            "SPProvidedID", i->m_SPProvidedID
+                            "Name", i->m_Name.c_str(),
+                            "Format", i->m_Format.c_str(),
+                            "NameQualifier", i->m_NameQualifier.c_str(),
+                            "SPNameQualifier", i->m_SPNameQualifier.c_str(),
+                            "SPProvidedID", i->m_SPProvidedID.c_str()
                             )
                         );
                     m_serialized.push_back(e.what());
index 4e287ed..c93d87d 100644 (file)
-/*\r
- *  Copyright 2001-2007 Internet2\r
- * \r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-/**\r
- * XMLAttributeExtractor.cpp\r
- * \r
- * AttributeExtractor based on an XML mapping file.\r
- */\r
-\r
-#include "internal.h"\r
-#include "Application.h"\r
-#include "ServiceProvider.h"\r
-#include "attribute/AttributeDecoder.h"\r
-#include "attribute/resolver/AttributeExtractor.h"\r
-#include "util/SPConstants.h"\r
-\r
-#include <saml/saml1/core/Assertions.h>\r
-#include <saml/saml2/core/Assertions.h>\r
-#include <saml/saml2/metadata/MetadataCredentialCriteria.h>\r
-#include <xmltooling/util/NDC.h>\r
-#include <xmltooling/util/ReloadableXMLFile.h>\r
-#include <xmltooling/util/XMLHelper.h>\r
-#include <xercesc/util/XMLUniDefs.hpp>\r
-\r
-using namespace shibsp;\r
-using namespace opensaml::saml2md;\r
-using namespace opensaml;\r
-using namespace xmltooling;\r
-using namespace log4cpp;\r
-using namespace std;\r
-using saml1::NameIdentifier;\r
-using saml2::NameID;\r
-using saml2::EncryptedAttribute;\r
-\r
-namespace shibsp {\r
-\r
-#if defined (_MSC_VER)\r
-    #pragma warning( push )\r
-    #pragma warning( disable : 4250 )\r
-#endif\r
-\r
-    class XMLExtractorImpl\r
-    {\r
-    public:\r
-        XMLExtractorImpl(const DOMElement* e, Category& log);\r
-        ~XMLExtractorImpl() {\r
-            for (attrmap_t::iterator i = m_attrMap.begin(); i!=m_attrMap.end(); ++i)\r
-                delete i->second.first;\r
-            if (m_document)\r
-                m_document->release();\r
-        }\r
-\r
-        void setDocument(DOMDocument* doc) {\r
-            m_document = doc;\r
-        }\r
-\r
-        void extractAttributes(\r
-            const Application& application, const char* assertingParty, const NameIdentifier& nameid, multimap<string,Attribute*>& attributes\r
-            ) const;\r
-        void extractAttributes(\r
-            const Application& application, const char* assertingParty, const NameID& nameid, multimap<string,Attribute*>& attributes\r
-            ) const;\r
-        void extractAttributes(\r
-            const Application& application, const char* assertingParty, const saml1::Attribute& attr, multimap<string,Attribute*>& attributes\r
-            ) const;\r
-        void extractAttributes(\r
-            const Application& application, const char* assertingParty, const saml2::Attribute& attr, multimap<string,Attribute*>& attributes\r
-            ) const;\r
-\r
-    private:\r
-        Category& m_log;\r
-        DOMDocument* m_document;\r
-#ifdef HAVE_GOOD_STL\r
-        typedef map< pair<xstring,xstring>,pair<AttributeDecoder*,string> > attrmap_t;\r
-#else\r
-        typedef map< pair<string,string>,pair<AttributeDecoder*,string> > attrmap_t;\r
-#endif\r
-        attrmap_t m_attrMap;\r
-    };\r
-    \r
-    class XMLExtractor : public AttributeExtractor, public ReloadableXMLFile\r
-    {\r
-    public:\r
-        XMLExtractor(const DOMElement* e) : ReloadableXMLFile(e, Category::getInstance(SHIBSP_LOGCAT".AttributeExtractor")), m_impl(NULL) {\r
-            load();\r
-        }\r
-        ~XMLExtractor() {\r
-            delete m_impl;\r
-        }\r
-        \r
-        void extractAttributes(\r
-            const Application& application, const RoleDescriptor* issuer, const XMLObject& xmlObject, multimap<string,Attribute*>& attributes\r
-            ) const;\r
-\r
-    protected:\r
-        pair<bool,DOMElement*> load();\r
-\r
-    private:\r
-        XMLExtractorImpl* m_impl;\r
-    };\r
-\r
-#if defined (_MSC_VER)\r
-    #pragma warning( pop )\r
-#endif\r
-\r
-    AttributeExtractor* SHIBSP_DLLLOCAL XMLAttributeExtractorFactory(const DOMElement* const & e)\r
-    {\r
-        return new XMLExtractor(e);\r
-    }\r
-    \r
-    static const XMLCh _AttributeDecoder[] =    UNICODE_LITERAL_16(A,t,t,r,i,b,u,t,e,D,e,c,o,d,e,r);\r
-    static const XMLCh Attributes[] =           UNICODE_LITERAL_10(A,t,t,r,i,b,u,t,e,s);\r
-    static const XMLCh _id[] =                  UNICODE_LITERAL_2(i,d);\r
-    static const XMLCh _name[] =                UNICODE_LITERAL_4(n,a,m,e);\r
-    static const XMLCh nameFormat[] =           UNICODE_LITERAL_10(n,a,m,e,F,o,r,m,a,t);\r
-};\r
-\r
+/*
+ *  Copyright 2001-2007 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.
+ */
+
+/**
+ * XMLAttributeExtractor.cpp
+ * 
+ * AttributeExtractor based on an XML mapping file.
+ */
+
+#include "internal.h"
+#include "Application.h"
+#include "ServiceProvider.h"
+#include "attribute/AttributeDecoder.h"
+#include "attribute/resolver/AttributeExtractor.h"
+#include "util/SPConstants.h"
+
+#include <saml/saml1/core/Assertions.h>
+#include <saml/saml2/core/Assertions.h>
+#include <saml/saml2/metadata/MetadataCredentialCriteria.h>
+#include <xmltooling/util/NDC.h>
+#include <xmltooling/util/ReloadableXMLFile.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 log4cpp;
+using namespace std;
+using saml1::NameIdentifier;
+using saml2::NameID;
+using saml2::EncryptedAttribute;
+
+namespace shibsp {
+
+#if defined (_MSC_VER)
+    #pragma warning( push )
+    #pragma warning( disable : 4250 )
+#endif
+
+    class XMLExtractorImpl
+    {
+    public:
+        XMLExtractorImpl(const DOMElement* e, Category& log);
+        ~XMLExtractorImpl() {
+            for (attrmap_t::iterator i = m_attrMap.begin(); i!=m_attrMap.end(); ++i)
+                delete i->second.first;
+            if (m_document)
+                m_document->release();
+        }
+
+        void setDocument(DOMDocument* doc) {
+            m_document = doc;
+        }
+
+        void extractAttributes(
+            const Application& application, const char* assertingParty, const NameIdentifier& nameid, multimap<string,Attribute*>& attributes
+            ) const;
+        void extractAttributes(
+            const Application& application, const char* assertingParty, const NameID& nameid, multimap<string,Attribute*>& attributes
+            ) const;
+        void extractAttributes(
+            const Application& application, const char* assertingParty, const saml1::Attribute& attr, multimap<string,Attribute*>& attributes
+            ) const;
+        void extractAttributes(
+            const Application& application, const char* assertingParty, const saml2::Attribute& attr, multimap<string,Attribute*>& attributes
+            ) const;
+
+    private:
+        Category& m_log;
+        DOMDocument* m_document;
+#ifdef HAVE_GOOD_STL
+        typedef map< pair<xstring,xstring>,pair<AttributeDecoder*,string> > attrmap_t;
+#else
+        typedef map< pair<string,string>,pair<AttributeDecoder*,string> > attrmap_t;
+#endif
+        attrmap_t m_attrMap;
+    };
+    
+    class XMLExtractor : public AttributeExtractor, public ReloadableXMLFile
+    {
+    public:
+        XMLExtractor(const DOMElement* e) : ReloadableXMLFile(e, Category::getInstance(SHIBSP_LOGCAT".AttributeExtractor")), m_impl(NULL) {
+            load();
+        }
+        ~XMLExtractor() {
+            delete m_impl;
+        }
+        
+        void extractAttributes(
+            const Application& application, const RoleDescriptor* issuer, const XMLObject& xmlObject, multimap<string,Attribute*>& attributes
+            ) const;
+
+    protected:
+        pair<bool,DOMElement*> load();
+
+    private:
+        XMLExtractorImpl* m_impl;
+    };
+
+#if defined (_MSC_VER)
+    #pragma warning( pop )
+#endif
+
+    AttributeExtractor* SHIBSP_DLLLOCAL XMLAttributeExtractorFactory(const DOMElement* const & e)
+    {
+        return new XMLExtractor(e);
+    }
+    
+    static const XMLCh _AttributeDecoder[] =    UNICODE_LITERAL_16(A,t,t,r,i,b,u,t,e,D,e,c,o,d,e,r);
+    static const XMLCh Attributes[] =           UNICODE_LITERAL_10(A,t,t,r,i,b,u,t,e,s);
+    static const XMLCh _id[] =                  UNICODE_LITERAL_2(i,d);
+    static const XMLCh _name[] =                UNICODE_LITERAL_4(n,a,m,e);
+    static const XMLCh nameFormat[] =           UNICODE_LITERAL_10(n,a,m,e,F,o,r,m,a,t);
+};
+
 void SHIBSP_API shibsp::registerAttributeExtractors()
 {
     SPConfig::getConfig().AttributeExtractorManager.registerFactory(XML_ATTRIBUTE_EXTRACTOR, XMLAttributeExtractorFactory);
 }
-\r
-XMLExtractorImpl::XMLExtractorImpl(const DOMElement* e, Category& log) : m_log(log), m_document(NULL)\r
-{\r
-#ifdef _DEBUG\r
-    xmltooling::NDC ndc("XMLExtractorImpl");\r
-#endif\r
-    \r
-    if (!XMLHelper::isNodeNamed(e, shibspconstants::SHIB2ATTRIBUTEMAP_NS, Attributes))\r
-        throw ConfigurationException("XML AttributeExtractor requires am:Attributes at root of configuration.");\r
-\r
-    DOMElement* child = XMLHelper::getFirstChildElement(e, shibspconstants::SHIB2ATTRIBUTEMAP_NS, saml1::Attribute::LOCAL_NAME);\r
-    while (child) {\r
-        // Check for missing name or id.\r
-        const XMLCh* name = child->getAttributeNS(NULL, _name);\r
-        if (!name || !*name) {\r
-            m_log.warn("skipping Attribute with no name");\r
-            child = XMLHelper::getNextSiblingElement(child, shibspconstants::SHIB2ATTRIBUTEMAP_NS, saml1::Attribute::LOCAL_NAME);\r
-            continue;\r
-        }\r
-\r
-        auto_ptr_char id(child->getAttributeNS(NULL, _id));\r
-        if (!id.get() || !*id.get()) {\r
-            m_log.warn("skipping Attribute with no id");\r
-            child = XMLHelper::getNextSiblingElement(child, shibspconstants::SHIB2ATTRIBUTEMAP_NS, saml1::Attribute::LOCAL_NAME);\r
-            continue;\r
-        }\r
-\r
-        AttributeDecoder* decoder=NULL;\r
-        try {\r
-            DOMElement* dchild = XMLHelper::getFirstChildElement(child, shibspconstants::SHIB2ATTRIBUTEMAP_NS, _AttributeDecoder);\r
-            if (child) {\r
-                auto_ptr<QName> q(XMLHelper::getXSIType(dchild));\r
-                if (q.get())\r
-                    decoder = SPConfig::getConfig().AttributeDecoderManager.newPlugin(*q.get(), dchild);\r
-            }\r
-            if (!decoder)\r
-                decoder = SPConfig::getConfig().AttributeDecoderManager.newPlugin(StringAttributeDecoderType, NULL);\r
-        }\r
-        catch (exception& ex) {\r
-            m_log.error("skipping Attribute (%s), error building AttributeDecoder: %s", id.get(), ex.what());\r
-        }\r
-\r
-        if (!decoder) {\r
-            child = XMLHelper::getNextSiblingElement(child, shibspconstants::SHIB2ATTRIBUTEMAP_NS, saml1::Attribute::LOCAL_NAME);\r
-            continue;\r
-        }\r
-\r
-        // Empty NameFormat implies the usual Shib URI naming defaults.\r
-        const XMLCh* format = child->getAttributeNS(NULL, nameFormat);\r
-        if (!format || XMLString::equals(format, shibspconstants::SHIB1_ATTRIBUTE_NAMESPACE_URI) ||\r
-                XMLString::equals(format, saml2::Attribute::URI_REFERENCE))\r
-            format = &chNull;  // ignore default Format/Namespace values\r
-\r
-        // Fetch/create the map entry and see if it's a duplicate rule.\r
-#ifdef HAVE_GOOD_STL\r
-        pair<AttributeDecoder*,string>& decl = m_attrMap[make_pair(name,format)];\r
-#else\r
-        auto_ptr_char n(name);\r
-        auto_ptr_char f(format);\r
-        pair<AttributeDecoder*,string>& decl = m_attrMap[make_pair(n.get(),f.get())];\r
-#endif\r
-        if (decl.first) {\r
-            m_log.warn("skipping duplicate Attribute declaration (same name and nameFormat)");\r
-            delete decoder;\r
-            child = XMLHelper::getNextSiblingElement(child, shibspconstants::SHIB2ATTRIBUTEMAP_NS, saml1::Attribute::LOCAL_NAME);\r
-            continue;\r
-        }\r
-\r
-        if (m_log.isInfoEnabled()) {\r
-#ifdef HAVE_GOOD_STL\r
-            auto_ptr_char n(name);\r
-            auto_ptr_char f(format);\r
-#endif\r
-            m_log.info("creating declaration for Attribute %s%s%s", n.get(), *f.get() ? ", Format/Namespace:" : "", f.get());\r
-        }\r
-        \r
-        decl.first = decoder;\r
-        decl.second = id.get();\r
-        \r
-        child = XMLHelper::getNextSiblingElement(child, shibspconstants::SHIB2ATTRIBUTEMAP_NS, saml1::Attribute::LOCAL_NAME);\r
-    }\r
-}\r
-\r
-void XMLExtractorImpl::extractAttributes(\r
-    const Application& application, const char* assertingParty, const NameIdentifier& nameid, multimap<string,Attribute*>& attributes\r
-    ) const\r
-{\r
-#ifdef HAVE_GOOD_STL\r
-    map< pair<xstring,xstring>,pair<AttributeDecoder*,string> >::const_iterator rule;\r
-#else\r
-    map< pair<string,string>,pair<AttributeDecoder*,string> >::const_iterator rule;\r
-#endif\r
-\r
-    const XMLCh* format = nameid.getFormat();\r
-    if (!format || !*format)\r
-        format = NameIdentifier::UNSPECIFIED;\r
-#ifdef HAVE_GOOD_STL\r
-    if ((rule=m_attrMap.find(make_pair(format,xstring()))) != m_attrMap.end()) {\r
-#else\r
-    auto_ptr_char temp(format);\r
-    if ((rule=m_attrMap.find(make_pair(temp.get(),string()))) != m_attrMap.end()) {\r
-#endif\r
-        attributes.insert(\r
-            make_pair(\r
-                rule->second.second,\r
-                rule->second.first->decode(rule->second.second.c_str(), &nameid, assertingParty, application.getString("entityID").second)\r
-                )\r
-            );\r
-    }\r
-}\r
-\r
-void XMLExtractorImpl::extractAttributes(\r
-    const Application& application, const char* assertingParty, const NameID& nameid, multimap<string,Attribute*>& attributes\r
-    ) const\r
-{\r
-#ifdef HAVE_GOOD_STL\r
-    map< pair<xstring,xstring>,pair<AttributeDecoder*,string> >::const_iterator rule;\r
-#else\r
-    map< pair<string,string>,pair<AttributeDecoder*,string> >::const_iterator rule;\r
-#endif\r
-\r
-    const XMLCh* format = nameid.getFormat();\r
-    if (!format || !*format)\r
-        format = NameID::UNSPECIFIED;\r
-#ifdef HAVE_GOOD_STL\r
-    if ((rule=m_attrMap.find(make_pair(format,xstring()))) != m_attrMap.end()) {\r
-#else\r
-    auto_ptr_char temp(format);\r
-    if ((rule=m_attrMap.find(make_pair(temp.get(),string()))) != m_attrMap.end()) {\r
-#endif\r
-        attributes.insert(\r
-            make_pair(\r
-                rule->second.second,\r
-                rule->second.first->decode(rule->second.second.c_str(), &nameid, assertingParty, application.getString("entityID").second)\r
-                )\r
-            );\r
-    }\r
-}\r
-\r
-void XMLExtractorImpl::extractAttributes(\r
-    const Application& application, const char* assertingParty, const saml1::Attribute& attr, multimap<string,Attribute*>& attributes\r
-    ) const\r
-{\r
-#ifdef HAVE_GOOD_STL\r
-    map< pair<xstring,xstring>,pair<AttributeDecoder*,string> >::const_iterator rule;\r
-#else\r
-    map< pair<string,string>,pair<AttributeDecoder*,string> >::const_iterator rule;\r
-#endif\r
-\r
-    const XMLCh* name = attr.getAttributeName();\r
-    const XMLCh* format = attr.getAttributeNamespace();\r
-    if (!name || !*name)\r
-        return;\r
-    if (!format || XMLString::equals(format, shibspconstants::SHIB1_ATTRIBUTE_NAMESPACE_URI))\r
-        format = &chNull;\r
-#ifdef HAVE_GOOD_STL\r
-    if ((rule=m_attrMap.find(make_pair(name,format))) != m_attrMap.end()) {\r
-#else\r
-    auto_ptr_char temp1(name);\r
-    auto_ptr_char temp2(format);\r
-    if ((rule=m_attrMap.find(make_pair(temp1.get(),temp2.get()))) != m_attrMap.end()) {\r
-#endif\r
-        attributes.insert(\r
-            make_pair(\r
-                rule->second.second,\r
-                rule->second.first->decode(rule->second.second.c_str(), &attr, assertingParty, application.getString("entityID").second)\r
-                )\r
-            );\r
-    }\r
-}\r
-\r
-void XMLExtractorImpl::extractAttributes(\r
-    const Application& application, const char* assertingParty, const saml2::Attribute& attr, multimap<string,Attribute*>& attributes\r
-    ) const\r
-{\r
-#ifdef HAVE_GOOD_STL\r
-    map< pair<xstring,xstring>,pair<AttributeDecoder*,string> >::const_iterator rule;\r
-#else\r
-    map< pair<string,string>,pair<AttributeDecoder*,string> >::const_iterator rule;\r
-#endif\r
-\r
-    const XMLCh* name = attr.getName();\r
-    const XMLCh* format = attr.getNameFormat();\r
-    if (!name || !*name)\r
-        return;\r
-    if (!format || !*format)\r
-        format = saml2::Attribute::UNSPECIFIED;\r
-    else if (XMLString::equals(format, saml2::Attribute::URI_REFERENCE))\r
-        format = &chNull;\r
-#ifdef HAVE_GOOD_STL\r
-    if ((rule=m_attrMap.find(make_pair(name,format))) != m_attrMap.end()) {\r
-#else\r
-    auto_ptr_char temp1(name);\r
-    auto_ptr_char temp2(format);\r
-    if ((rule=m_attrMap.find(make_pair(temp1.get(),temp2.get()))) != m_attrMap.end()) {\r
-#endif\r
-        attributes.insert(\r
-            make_pair(\r
-                rule->second.second,\r
-                rule->second.first->decode(rule->second.second.c_str(), &attr, assertingParty, application.getString("entityID").second)\r
-                )\r
-            );\r
-    }\r
-}\r
-\r
-void XMLExtractor::extractAttributes(\r
-    const Application& application, const RoleDescriptor* issuer, const XMLObject& xmlObject, multimap<string,Attribute*>& attributes\r
-    ) const\r
-{\r
-    // Check for assertions.\r
-    if (XMLString::equals(xmlObject.getElementQName().getLocalPart(), saml1::Assertion::LOCAL_NAME)) {\r
-        const saml2::Assertion* token2 = dynamic_cast<const saml2::Assertion*>(&xmlObject);\r
-        if (token2) {\r
-            auto_ptr_char assertingParty(issuer ? dynamic_cast<const EntityDescriptor*>(issuer->getParent())->getEntityID() : NULL);\r
-            const vector<saml2::AttributeStatement*>& statements = token2->getAttributeStatements();\r
-            for (vector<saml2::AttributeStatement*>::const_iterator s = statements.begin(); s!=statements.end(); ++s) {\r
-                const vector<saml2::Attribute*>& attrs = const_cast<const saml2::AttributeStatement*>(*s)->getAttributes();\r
-                for (vector<saml2::Attribute*>::const_iterator a = attrs.begin(); a!=attrs.end(); ++a)\r
-                    m_impl->extractAttributes(application, assertingParty.get(), *(*a), attributes);\r
-\r
-                const vector<saml2::EncryptedAttribute*>& encattrs = const_cast<const saml2::AttributeStatement*>(*s)->getEncryptedAttributes();\r
-                for (vector<saml2::EncryptedAttribute*>::const_iterator ea = encattrs.begin(); ea!=encattrs.end(); ++ea)\r
-                    extractAttributes(application, issuer, *(*ea), attributes);\r
-            }\r
-        }\r
-\r
-        const saml1::Assertion* token1 = dynamic_cast<const saml1::Assertion*>(&xmlObject);\r
-        if (token1) {\r
-            auto_ptr_char assertingParty(issuer ? dynamic_cast<const EntityDescriptor*>(issuer->getParent())->getEntityID() : NULL);\r
-            const vector<saml1::AttributeStatement*>& statements = token1->getAttributeStatements();\r
-            for (vector<saml1::AttributeStatement*>::const_iterator s = statements.begin(); s!=statements.end(); ++s) {\r
-                const vector<saml1::Attribute*>& attrs = const_cast<const saml1::AttributeStatement*>(*s)->getAttributes();\r
-                for (vector<saml1::Attribute*>::const_iterator a = attrs.begin(); a!=attrs.end(); ++a)\r
-                    m_impl->extractAttributes(application, assertingParty.get(), *(*a), attributes);\r
-            }\r
-        }\r
-\r
-        throw AttributeExtractionException("Unable to extract attributes, unknown object type.");\r
-    }\r
-\r
-    // Check for attributes.\r
-    if (XMLString::equals(xmlObject.getElementQName().getLocalPart(), saml1::Attribute::LOCAL_NAME)) {\r
-        auto_ptr_char assertingParty(issuer ? dynamic_cast<const EntityDescriptor*>(issuer->getParent())->getEntityID() : NULL);\r
-\r
-        const saml2::Attribute* attr2 = dynamic_cast<const saml2::Attribute*>(&xmlObject);\r
-        if (attr2)\r
-            return m_impl->extractAttributes(application, assertingParty.get(), *attr2, attributes);\r
-\r
-        const saml1::Attribute* attr1 = dynamic_cast<const saml1::Attribute*>(&xmlObject);\r
-        if (attr1)\r
-            return m_impl->extractAttributes(application, assertingParty.get(), *attr1, attributes);\r
-\r
-        throw AttributeExtractionException("Unable to extract attributes, unknown object type.");\r
-    }\r
-\r
-    if (XMLString::equals(xmlObject.getElementQName().getLocalPart(), EncryptedAttribute::LOCAL_NAME)) {\r
-        const EncryptedAttribute* encattr = dynamic_cast<const EncryptedAttribute*>(&xmlObject);\r
-        if (encattr) {\r
-            const XMLCh* recipient = application.getXMLString("entityID").second;\r
-            CredentialResolver* cr = application.getCredentialResolver();\r
-            if (!cr) {\r
-                m_log.warn("found encrypted attribute, but no CredentialResolver was available");\r
-                return;\r
-            }\r
-\r
-            try {\r
-                Locker credlocker(cr);\r
-                if (issuer) {\r
-                    MetadataCredentialCriteria mcc(*issuer);\r
-                    auto_ptr<XMLObject> decrypted(encattr->decrypt(*cr, recipient, &mcc));\r
-                    return extractAttributes(application, issuer, *(decrypted.get()), attributes);\r
-                }\r
-                else {\r
-                    auto_ptr<XMLObject> decrypted(encattr->decrypt(*cr, recipient));\r
-                    return extractAttributes(application, issuer, *(decrypted.get()), attributes);\r
-                }\r
-            }\r
-            catch (exception& ex) {\r
-                m_log.error("caught exception decrypting Attribute: %s", ex.what());\r
-                return;\r
-            }\r
-        }\r
-    }\r
-\r
-    // Check for NameIDs.\r
-    const NameID* name2 = dynamic_cast<const NameID*>(&xmlObject);\r
-    if (name2) {\r
-        auto_ptr_char assertingParty(issuer ? dynamic_cast<const EntityDescriptor*>(issuer->getParent())->getEntityID() : NULL);\r
-        return m_impl->extractAttributes(application, assertingParty.get(), *name2, attributes);\r
-    }\r
-\r
-    const NameIdentifier* name1 = dynamic_cast<const NameIdentifier*>(&xmlObject);\r
-    if (name1) {\r
-        auto_ptr_char assertingParty(issuer ? dynamic_cast<const EntityDescriptor*>(issuer->getParent())->getEntityID() : NULL);\r
-        return m_impl->extractAttributes(application, assertingParty.get(), *name1, attributes);\r
-    }\r
-\r
-    throw AttributeExtractionException("Unable to extract attributes, unknown object type.");\r
-}\r
-\r
-pair<bool,DOMElement*> XMLExtractor::load()\r
-{\r
-    // Load from source using base class.\r
-    pair<bool,DOMElement*> raw = ReloadableXMLFile::load();\r
-    \r
-    // If we own it, wrap it.\r
-    XercesJanitor<DOMDocument> docjanitor(raw.first ? raw.second->getOwnerDocument() : NULL);\r
-\r
-    XMLExtractorImpl* impl = new XMLExtractorImpl(raw.second, m_log);\r
-    \r
-    // If we held the document, transfer it to the impl. If we didn't, it's a no-op.\r
-    impl->setDocument(docjanitor.release());\r
-\r
-    delete m_impl;\r
-    m_impl = impl;\r
-\r
-    return make_pair(false,(DOMElement*)NULL);\r
-}\r
+
+XMLExtractorImpl::XMLExtractorImpl(const DOMElement* e, Category& log) : m_log(log), m_document(NULL)
+{
+#ifdef _DEBUG
+    xmltooling::NDC ndc("XMLExtractorImpl");
+#endif
+    
+    if (!XMLHelper::isNodeNamed(e, shibspconstants::SHIB2ATTRIBUTEMAP_NS, Attributes))
+        throw ConfigurationException("XML AttributeExtractor requires am:Attributes at root of configuration.");
+
+    DOMElement* child = XMLHelper::getFirstChildElement(e, shibspconstants::SHIB2ATTRIBUTEMAP_NS, saml1::Attribute::LOCAL_NAME);
+    while (child) {
+        // Check for missing name or id.
+        const XMLCh* name = child->getAttributeNS(NULL, _name);
+        if (!name || !*name) {
+            m_log.warn("skipping Attribute with no name");
+            child = XMLHelper::getNextSiblingElement(child, shibspconstants::SHIB2ATTRIBUTEMAP_NS, saml1::Attribute::LOCAL_NAME);
+            continue;
+        }
+
+        auto_ptr_char id(child->getAttributeNS(NULL, _id));
+        if (!id.get() || !*id.get()) {
+            m_log.warn("skipping Attribute with no id");
+            child = XMLHelper::getNextSiblingElement(child, shibspconstants::SHIB2ATTRIBUTEMAP_NS, saml1::Attribute::LOCAL_NAME);
+            continue;
+        }
+
+        AttributeDecoder* decoder=NULL;
+        try {
+            DOMElement* dchild = XMLHelper::getFirstChildElement(child, shibspconstants::SHIB2ATTRIBUTEMAP_NS, _AttributeDecoder);
+            if (dchild) {
+                auto_ptr<QName> q(XMLHelper::getXSIType(dchild));
+                if (q.get())
+                    decoder = SPConfig::getConfig().AttributeDecoderManager.newPlugin(*q.get(), dchild);
+            }
+            if (!decoder)
+                decoder = SPConfig::getConfig().AttributeDecoderManager.newPlugin(StringAttributeDecoderType, NULL);
+        }
+        catch (exception& ex) {
+            m_log.error("skipping Attribute (%s), error building AttributeDecoder: %s", id.get(), ex.what());
+        }
+
+        if (!decoder) {
+            child = XMLHelper::getNextSiblingElement(child, shibspconstants::SHIB2ATTRIBUTEMAP_NS, saml1::Attribute::LOCAL_NAME);
+            continue;
+        }
+
+        // Empty NameFormat implies the usual Shib URI naming defaults.
+        const XMLCh* format = child->getAttributeNS(NULL, nameFormat);
+        if (!format || XMLString::equals(format, shibspconstants::SHIB1_ATTRIBUTE_NAMESPACE_URI) ||
+                XMLString::equals(format, saml2::Attribute::URI_REFERENCE))
+            format = &chNull;  // ignore default Format/Namespace values
+
+        // Fetch/create the map entry and see if it's a duplicate rule.
+#ifdef HAVE_GOOD_STL
+        pair<AttributeDecoder*,string>& decl = m_attrMap[make_pair(name,format)];
+#else
+        auto_ptr_char n(name);
+        auto_ptr_char f(format);
+        pair<AttributeDecoder*,string>& decl = m_attrMap[make_pair(n.get(),f.get())];
+#endif
+        if (decl.first) {
+            m_log.warn("skipping duplicate Attribute mapping (same name and nameFormat)");
+            delete decoder;
+            child = XMLHelper::getNextSiblingElement(child, shibspconstants::SHIB2ATTRIBUTEMAP_NS, saml1::Attribute::LOCAL_NAME);
+            continue;
+        }
+
+        if (m_log.isInfoEnabled()) {
+#ifdef HAVE_GOOD_STL
+            auto_ptr_char n(name);
+            auto_ptr_char f(format);
+#endif
+            m_log.info("creating mapping for Attribute %s%s%s", n.get(), *f.get() ? ", Format/Namespace:" : "", f.get());
+        }
+        
+        decl.first = decoder;
+        decl.second = id.get();
+        
+        child = XMLHelper::getNextSiblingElement(child, shibspconstants::SHIB2ATTRIBUTEMAP_NS, saml1::Attribute::LOCAL_NAME);
+    }
+}
+
+void XMLExtractorImpl::extractAttributes(
+    const Application& application, const char* assertingParty, const NameIdentifier& nameid, multimap<string,Attribute*>& attributes
+    ) const
+{
+#ifdef HAVE_GOOD_STL
+    map< pair<xstring,xstring>,pair<AttributeDecoder*,string> >::const_iterator rule;
+#else
+    map< pair<string,string>,pair<AttributeDecoder*,string> >::const_iterator rule;
+#endif
+
+    const XMLCh* format = nameid.getFormat();
+    if (!format || !*format)
+        format = NameIdentifier::UNSPECIFIED;
+#ifdef HAVE_GOOD_STL
+    if ((rule=m_attrMap.find(make_pair(format,xstring()))) != m_attrMap.end()) {
+#else
+    auto_ptr_char temp(format);
+    if ((rule=m_attrMap.find(make_pair(temp.get(),string()))) != m_attrMap.end()) {
+#endif
+        attributes.insert(
+            make_pair(
+                rule->second.second,
+                rule->second.first->decode(rule->second.second.c_str(), &nameid, assertingParty, application.getString("entityID").second)
+                )
+            );
+    }
+}
+
+void XMLExtractorImpl::extractAttributes(
+    const Application& application, const char* assertingParty, const NameID& nameid, multimap<string,Attribute*>& attributes
+    ) const
+{
+#ifdef HAVE_GOOD_STL
+    map< pair<xstring,xstring>,pair<AttributeDecoder*,string> >::const_iterator rule;
+#else
+    map< pair<string,string>,pair<AttributeDecoder*,string> >::const_iterator rule;
+#endif
+
+    const XMLCh* format = nameid.getFormat();
+    if (!format || !*format)
+        format = NameID::UNSPECIFIED;
+#ifdef HAVE_GOOD_STL
+    if ((rule=m_attrMap.find(make_pair(format,xstring()))) != m_attrMap.end()) {
+#else
+    auto_ptr_char temp(format);
+    if ((rule=m_attrMap.find(make_pair(temp.get(),string()))) != m_attrMap.end()) {
+#endif
+        attributes.insert(
+            make_pair(
+                rule->second.second,
+                rule->second.first->decode(rule->second.second.c_str(), &nameid, assertingParty, application.getString("entityID").second)
+                )
+            );
+    }
+}
+
+void XMLExtractorImpl::extractAttributes(
+    const Application& application, const char* assertingParty, const saml1::Attribute& attr, multimap<string,Attribute*>& attributes
+    ) const
+{
+#ifdef HAVE_GOOD_STL
+    map< pair<xstring,xstring>,pair<AttributeDecoder*,string> >::const_iterator rule;
+#else
+    map< pair<string,string>,pair<AttributeDecoder*,string> >::const_iterator rule;
+#endif
+
+    const XMLCh* name = attr.getAttributeName();
+    const XMLCh* format = attr.getAttributeNamespace();
+    if (!name || !*name)
+        return;
+    if (!format || XMLString::equals(format, shibspconstants::SHIB1_ATTRIBUTE_NAMESPACE_URI))
+        format = &chNull;
+#ifdef HAVE_GOOD_STL
+    if ((rule=m_attrMap.find(make_pair(name,format))) != m_attrMap.end()) {
+#else
+    auto_ptr_char temp1(name);
+    auto_ptr_char temp2(format);
+    if ((rule=m_attrMap.find(make_pair(temp1.get(),temp2.get()))) != m_attrMap.end()) {
+#endif
+        attributes.insert(
+            make_pair(
+                rule->second.second,
+                rule->second.first->decode(rule->second.second.c_str(), &attr, assertingParty, application.getString("entityID").second)
+                )
+            );
+    }
+}
+
+void XMLExtractorImpl::extractAttributes(
+    const Application& application, const char* assertingParty, const saml2::Attribute& attr, multimap<string,Attribute*>& attributes
+    ) const
+{
+#ifdef HAVE_GOOD_STL
+    map< pair<xstring,xstring>,pair<AttributeDecoder*,string> >::const_iterator rule;
+#else
+    map< pair<string,string>,pair<AttributeDecoder*,string> >::const_iterator rule;
+#endif
+
+    const XMLCh* name = attr.getName();
+    const XMLCh* format = attr.getNameFormat();
+    if (!name || !*name)
+        return;
+    if (!format || !*format)
+        format = saml2::Attribute::UNSPECIFIED;
+    else if (XMLString::equals(format, saml2::Attribute::URI_REFERENCE))
+        format = &chNull;
+#ifdef HAVE_GOOD_STL
+    if ((rule=m_attrMap.find(make_pair(name,format))) != m_attrMap.end()) {
+#else
+    auto_ptr_char temp1(name);
+    auto_ptr_char temp2(format);
+    if ((rule=m_attrMap.find(make_pair(temp1.get(),temp2.get()))) != m_attrMap.end()) {
+#endif
+        attributes.insert(
+            make_pair(
+                rule->second.second,
+                rule->second.first->decode(rule->second.second.c_str(), &attr, assertingParty, application.getString("entityID").second)
+                )
+            );
+    }
+}
+
+void XMLExtractor::extractAttributes(
+    const Application& application, const RoleDescriptor* issuer, const XMLObject& xmlObject, multimap<string,Attribute*>& attributes
+    ) const
+{
+    // Check for assertions.
+    if (XMLString::equals(xmlObject.getElementQName().getLocalPart(), saml1::Assertion::LOCAL_NAME)) {
+        const saml2::Assertion* token2 = dynamic_cast<const saml2::Assertion*>(&xmlObject);
+        if (token2) {
+            auto_ptr_char assertingParty(issuer ? dynamic_cast<const EntityDescriptor*>(issuer->getParent())->getEntityID() : NULL);
+            const vector<saml2::AttributeStatement*>& statements = token2->getAttributeStatements();
+            for (vector<saml2::AttributeStatement*>::const_iterator s = statements.begin(); s!=statements.end(); ++s) {
+                const vector<saml2::Attribute*>& attrs = const_cast<const saml2::AttributeStatement*>(*s)->getAttributes();
+                for (vector<saml2::Attribute*>::const_iterator a = attrs.begin(); a!=attrs.end(); ++a)
+                    m_impl->extractAttributes(application, assertingParty.get(), *(*a), attributes);
+
+                const vector<saml2::EncryptedAttribute*>& encattrs = const_cast<const saml2::AttributeStatement*>(*s)->getEncryptedAttributes();
+                for (vector<saml2::EncryptedAttribute*>::const_iterator ea = encattrs.begin(); ea!=encattrs.end(); ++ea)
+                    extractAttributes(application, issuer, *(*ea), attributes);
+            }
+            return;
+        }
+
+        const saml1::Assertion* token1 = dynamic_cast<const saml1::Assertion*>(&xmlObject);
+        if (token1) {
+            auto_ptr_char assertingParty(issuer ? dynamic_cast<const EntityDescriptor*>(issuer->getParent())->getEntityID() : NULL);
+            const vector<saml1::AttributeStatement*>& statements = token1->getAttributeStatements();
+            for (vector<saml1::AttributeStatement*>::const_iterator s = statements.begin(); s!=statements.end(); ++s) {
+                const vector<saml1::Attribute*>& attrs = const_cast<const saml1::AttributeStatement*>(*s)->getAttributes();
+                for (vector<saml1::Attribute*>::const_iterator a = attrs.begin(); a!=attrs.end(); ++a)
+                    m_impl->extractAttributes(application, assertingParty.get(), *(*a), attributes);
+            }
+            return;
+        }
+
+        throw AttributeExtractionException("Unable to extract attributes, unknown object type.");
+    }
+
+    // Check for attributes.
+    if (XMLString::equals(xmlObject.getElementQName().getLocalPart(), saml1::Attribute::LOCAL_NAME)) {
+        auto_ptr_char assertingParty(issuer ? dynamic_cast<const EntityDescriptor*>(issuer->getParent())->getEntityID() : NULL);
+
+        const saml2::Attribute* attr2 = dynamic_cast<const saml2::Attribute*>(&xmlObject);
+        if (attr2)
+            return m_impl->extractAttributes(application, assertingParty.get(), *attr2, attributes);
+
+        const saml1::Attribute* attr1 = dynamic_cast<const saml1::Attribute*>(&xmlObject);
+        if (attr1)
+            return m_impl->extractAttributes(application, assertingParty.get(), *attr1, attributes);
+
+        throw AttributeExtractionException("Unable to extract attributes, unknown object type.");
+    }
+
+    if (XMLString::equals(xmlObject.getElementQName().getLocalPart(), EncryptedAttribute::LOCAL_NAME)) {
+        const EncryptedAttribute* encattr = dynamic_cast<const EncryptedAttribute*>(&xmlObject);
+        if (encattr) {
+            const XMLCh* recipient = application.getXMLString("entityID").second;
+            CredentialResolver* cr = application.getCredentialResolver();
+            if (!cr) {
+                m_log.warn("found encrypted attribute, but no CredentialResolver was available");
+                return;
+            }
+
+            try {
+                Locker credlocker(cr);
+                if (issuer) {
+                    MetadataCredentialCriteria mcc(*issuer);
+                    auto_ptr<XMLObject> decrypted(encattr->decrypt(*cr, recipient, &mcc));
+                    return extractAttributes(application, issuer, *(decrypted.get()), attributes);
+                }
+                else {
+                    auto_ptr<XMLObject> decrypted(encattr->decrypt(*cr, recipient));
+                    return extractAttributes(application, issuer, *(decrypted.get()), attributes);
+                }
+            }
+            catch (exception& ex) {
+                m_log.error("caught exception decrypting Attribute: %s", ex.what());
+                return;
+            }
+        }
+    }
+
+    // Check for NameIDs.
+    const NameID* name2 = dynamic_cast<const NameID*>(&xmlObject);
+    if (name2) {
+        auto_ptr_char assertingParty(issuer ? dynamic_cast<const EntityDescriptor*>(issuer->getParent())->getEntityID() : NULL);
+        return m_impl->extractAttributes(application, assertingParty.get(), *name2, attributes);
+    }
+
+    const NameIdentifier* name1 = dynamic_cast<const NameIdentifier*>(&xmlObject);
+    if (name1) {
+        auto_ptr_char assertingParty(issuer ? dynamic_cast<const EntityDescriptor*>(issuer->getParent())->getEntityID() : NULL);
+        return m_impl->extractAttributes(application, assertingParty.get(), *name1, attributes);
+    }
+
+    throw AttributeExtractionException("Unable to extract attributes, unknown object type.");
+}
+
+pair<bool,DOMElement*> XMLExtractor::load()
+{
+    // Load from source using base class.
+    pair<bool,DOMElement*> raw = ReloadableXMLFile::load();
+    
+    // If we own it, wrap it.
+    XercesJanitor<DOMDocument> docjanitor(raw.first ? raw.second->getOwnerDocument() : NULL);
+
+    XMLExtractorImpl* impl = new XMLExtractorImpl(raw.second, m_log);
+    
+    // If we held the document, transfer it to the impl. If we didn't, it's a no-op.
+    impl->setDocument(docjanitor.release());
+
+    delete m_impl;
+    m_impl = impl;
+
+    return make_pair(false,(DOMElement*)NULL);
+}
index 14d0a5d..e69a00f 100644 (file)
@@ -66,7 +66,7 @@ namespace shibsp {
         pair<bool,const XMLCh*> getXMLString(const char* name, const char* ns=NULL) const;\r
         pair<bool,unsigned int> getUnsignedInt(const char* name, const char* ns=NULL) const;\r
         pair<bool,int> getInt(const char* name, const char* ns=NULL) const;\r
-        const PropertySet* getPropertySet(const char* name, const char* ns="urn:mace:shibboleth:target:config:1.0") const;\r
+        const PropertySet* getPropertySet(const char* name, const char* ns="urn:mace:shibboleth:2.0:native:sp:config") const;\r
         \r
         // Provides filter to exclude special config elements.\r
         short acceptNode(const DOMNode* node) const;\r
index ea3f662..2d3fa74 100644 (file)
@@ -213,7 +213,7 @@ namespace {
         pair<bool,const XMLCh*> getXMLString(const char* name, const char* ns=NULL) const {return m_impl->getXMLString(name,ns);}\r
         pair<bool,unsigned int> getUnsignedInt(const char* name, const char* ns=NULL) const {return m_impl->getUnsignedInt(name,ns);}\r
         pair<bool,int> getInt(const char* name, const char* ns=NULL) const {return m_impl->getInt(name,ns);}\r
-        const PropertySet* getPropertySet(const char* name, const char* ns="urn:mace:shibboleth:sp:config:2.0") const {return m_impl->getPropertySet(name,ns);}\r
+        const PropertySet* getPropertySet(const char* name, const char* ns="urn:mace:shibboleth:2.0:native:sp:config") const {return m_impl->getPropertySet(name,ns);}\r
         const DOMElement* getElement() const {return m_impl->getElement();}\r
 \r
         // ServiceProvider\r
index 196a287..817a3ed 100644 (file)
@@ -47,7 +47,7 @@ namespace shibsp {
         std::pair<bool,const XMLCh*> getXMLString(const char* name, const char* ns=NULL) const;
         std::pair<bool,unsigned int> getUnsignedInt(const char* name, const char* ns=NULL) const;
         std::pair<bool,int> getInt(const char* name, const char* ns=NULL) const;
-        const PropertySet* getPropertySet(const char* name, const char* ns="urn:mace:shibboleth:sp:config:2.0") const;
+        const PropertySet* getPropertySet(const char* name, const char* ns="urn:mace:shibboleth:2.0:native:sp:config") const;
 
         const xercesc::DOMElement* getElement() const {
             return m_root;
index 019a05d..81bc859 100644 (file)
@@ -98,7 +98,7 @@ namespace shibsp {
          * @param ns    nested property set namespace, or NULL
          * @return the nested property set, or NULL
          */        
-        virtual const PropertySet* getPropertySet(const char* name, const char* ns="urn:mace:shibboleth:sp:config:2.0") const=0;
+        virtual const PropertySet* getPropertySet(const char* name, const char* ns="urn:mace:shibboleth:2.0:native:sp:config") const=0;
         
         /**
          * Returns a DOM element representing the property container, if any.