-\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);
+}