X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=shibsp%2Fattribute%2Fresolver%2Fimpl%2FXMLAttributeExtractor.cpp;h=f5f1cf2b707f37872df731bded26f12c59cd021f;hb=3ccda9caa12c4e6e38b1f565f53e1057876fb2d6;hp=44bf5e476da9a343d4b91c5fc422a868330a8c50;hpb=7b7c8bd1f79f1ba7650f185970d0864a157b4818;p=shibboleth%2Fsp.git diff --git a/shibsp/attribute/resolver/impl/XMLAttributeExtractor.cpp b/shibsp/attribute/resolver/impl/XMLAttributeExtractor.cpp index 44bf5e4..f5f1cf2 100644 --- a/shibsp/attribute/resolver/impl/XMLAttributeExtractor.cpp +++ b/shibsp/attribute/resolver/impl/XMLAttributeExtractor.cpp @@ -67,16 +67,19 @@ namespace shibsp { } void extractAttributes( - const Application& application, const char* assertingParty, const NameIdentifier& nameid, multimap& attributes + const Application& application, const char* assertingParty, const NameIdentifier& nameid, vector& attributes ) const; void extractAttributes( - const Application& application, const char* assertingParty, const NameID& nameid, multimap& attributes + const Application& application, const char* assertingParty, const NameID& nameid, vector& attributes ) const; void extractAttributes( - const Application& application, const char* assertingParty, const saml1::Attribute& attr, multimap& attributes + const Application& application, const char* assertingParty, const saml1::Attribute& attr, vector& attributes ) const; void extractAttributes( - const Application& application, const char* assertingParty, const saml2::Attribute& attr, multimap& attributes + const Application& application, const char* assertingParty, const saml2::Attribute& attr, vector& attributes + ) const; + void extractAttributes( + const Application& application, const char* assertingParty, const Extensions& ext, vector& attributes ) const; void getAttributeIds(vector& attributes) const { @@ -87,9 +90,9 @@ namespace shibsp { Category& m_log; DOMDocument* m_document; #ifdef HAVE_GOOD_STL - typedef map< pair,pair > attrmap_t; + typedef map< pair,pair< AttributeDecoder*,vector > > attrmap_t; #else - typedef map< pair,pair > attrmap_t; + typedef map< pair,pair< AttributeDecoder*,vector > > attrmap_t; #endif attrmap_t m_attrMap; vector m_attributeIds; @@ -106,7 +109,7 @@ namespace shibsp { } void extractAttributes( - const Application& application, const RoleDescriptor* issuer, const XMLObject& xmlObject, multimap& attributes + const Application& application, const RoleDescriptor* issuer, const XMLObject& xmlObject, vector& attributes ) const; void getAttributeIds(std::vector& attributes) const { @@ -133,15 +136,11 @@ namespace shibsp { 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 _aliases[] = UNICODE_LITERAL_7(a,l,i,a,s,e,s); 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); -} - XMLExtractorImpl::XMLExtractorImpl(const DOMElement* e, Category& log) : m_log(log), m_document(NULL) { #ifdef _DEBUG @@ -201,11 +200,11 @@ XMLExtractorImpl::XMLExtractorImpl(const DOMElement* e, Category& log) : m_log(l // Fetch/create the map entry and see if it's a duplicate rule. #ifdef HAVE_GOOD_STL - pair& decl = m_attrMap[make_pair(name,format)]; + pair< AttributeDecoder*,vector >& decl = m_attrMap[pair(name,format)]; #else auto_ptr_char n(name); auto_ptr_char f(format); - pair& decl = m_attrMap[make_pair(n.get(),f.get())]; + pair< AttributeDecoder*,vector >& decl = m_attrMap[pair(n.get(),f.get())]; #endif if (decl.first) { m_log.warn("skipping duplicate Attribute mapping (same name and nameFormat)"); @@ -223,71 +222,107 @@ XMLExtractorImpl::XMLExtractorImpl(const DOMElement* e, Category& log) : m_log(l } decl.first = decoder; - decl.second = id.get(); + decl.second.push_back(id.get()); m_attributeIds.push_back(id.get()); + + name = child->getAttributeNS(NULL, _aliases); + if (name && *name) { + auto_ptr_char aliases(name); + char* pos; + char* start = const_cast(aliases.get()); + while (start && *start) { + while (*start && isspace(*start)) + start++; + if (!*start) + break; + pos = strchr(start,' '); + if (pos) + *pos=0; + if (strcmp(start, "REMOTE_USER")) { + decl.second.push_back(start); + m_attributeIds.push_back(start); + } + else { + m_log.warn("skipping alias, REMOTE_USER is a reserved name"); + } + start = pos ? pos+1 : NULL; + } + } child = XMLHelper::getNextSiblingElement(child, shibspconstants::SHIB2ATTRIBUTEMAP_NS, saml1::Attribute::LOCAL_NAME); } } void XMLExtractorImpl::extractAttributes( - const Application& application, const char* assertingParty, const NameIdentifier& nameid, multimap& attributes + const Application& application, const char* assertingParty, const NameIdentifier& nameid, vector& attributes ) const { #ifdef HAVE_GOOD_STL - map< pair,pair >::const_iterator rule; + map< pair,pair< AttributeDecoder*,vector > >::const_iterator rule; #else - map< pair,pair >::const_iterator rule; + map< pair,pair< AttributeDecoder*,vector > >::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()) { + if ((rule=m_attrMap.find(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()) { + if ((rule=m_attrMap.find(pair(temp.get(),string()))) != m_attrMap.end()) { #endif - Attribute* a = rule->second.first->decode(rule->second.second.c_str(), &nameid, assertingParty, application.getString("entityID").second); + Attribute* a = rule->second.first->decode(rule->second.second, &nameid, assertingParty, application.getString("entityID").second); if (a) - attributes.insert(make_pair(rule->second.second, a)); + attributes.push_back(a); + } + else if (m_log.isDebugEnabled()) { +#ifdef HAVE_GOOD_STL + auto_ptr_char temp(format); +#endif + m_log.debug("skipping unmapped NameIdentifier with format (%s)", temp.get()); } } void XMLExtractorImpl::extractAttributes( - const Application& application, const char* assertingParty, const NameID& nameid, multimap& attributes + const Application& application, const char* assertingParty, const NameID& nameid, vector& attributes ) const { #ifdef HAVE_GOOD_STL - map< pair,pair >::const_iterator rule; + map< pair,pair< AttributeDecoder*,vector > >::const_iterator rule; #else - map< pair,pair >::const_iterator rule; + map< pair,pair< AttributeDecoder*,vector > >::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()) { + if ((rule=m_attrMap.find(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()) { + if ((rule=m_attrMap.find(pair(temp.get(),string()))) != m_attrMap.end()) { #endif - Attribute* a = rule->second.first->decode(rule->second.second.c_str(), &nameid, assertingParty, application.getString("entityID").second); + Attribute* a = rule->second.first->decode(rule->second.second, &nameid, assertingParty, application.getString("entityID").second); if (a) - attributes.insert(make_pair(rule->second.second, a)); + attributes.push_back(a); + } + else if (m_log.isDebugEnabled()) { +#ifdef HAVE_GOOD_STL + auto_ptr_char temp(format); +#endif + m_log.debug("skipping unmapped NameID with format (%s)", temp.get()); } } void XMLExtractorImpl::extractAttributes( - const Application& application, const char* assertingParty, const saml1::Attribute& attr, multimap& attributes + const Application& application, const char* assertingParty, const saml1::Attribute& attr, vector& attributes ) const { #ifdef HAVE_GOOD_STL - map< pair,pair >::const_iterator rule; + map< pair,pair< AttributeDecoder*,vector > >::const_iterator rule; #else - map< pair,pair >::const_iterator rule; + map< pair,pair< AttributeDecoder*,vector > >::const_iterator rule; #endif const XMLCh* name = attr.getAttributeName(); @@ -297,26 +332,33 @@ void XMLExtractorImpl::extractAttributes( 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()) { + if ((rule=m_attrMap.find(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()) { + if ((rule=m_attrMap.find(pair(temp1.get(),temp2.get()))) != m_attrMap.end()) { #endif - Attribute* a = rule->second.first->decode(rule->second.second.c_str(), &attr, assertingParty, application.getString("entityID").second); + Attribute* a = rule->second.first->decode(rule->second.second, &attr, assertingParty, application.getString("entityID").second); if (a) - attributes.insert(make_pair(rule->second.second, a)); + attributes.push_back(a); + } + else if (m_log.isInfoEnabled()) { +#ifdef HAVE_GOOD_STL + auto_ptr_char temp1(name); + auto_ptr_char temp2(format); +#endif + m_log.info("skipping unmapped SAML 1.x Attribute with Name: %s%s%s", temp1.get(), *temp2.get() ? ", Namespace:" : "", temp2.get()); } } void XMLExtractorImpl::extractAttributes( - const Application& application, const char* assertingParty, const saml2::Attribute& attr, multimap& attributes + const Application& application, const char* assertingParty, const saml2::Attribute& attr, vector& attributes ) const { #ifdef HAVE_GOOD_STL - map< pair,pair >::const_iterator rule; + map< pair,pair< AttributeDecoder*,vector > >::const_iterator rule; #else - map< pair,pair >::const_iterator rule; + map< pair,pair< AttributeDecoder*,vector > >::const_iterator rule; #endif const XMLCh* name = attr.getName(); @@ -328,20 +370,39 @@ void XMLExtractorImpl::extractAttributes( 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()) { + if ((rule=m_attrMap.find(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()) { + if ((rule=m_attrMap.find(pair(temp1.get(),temp2.get()))) != m_attrMap.end()) { #endif - Attribute* a = rule->second.first->decode(rule->second.second.c_str(), &attr, assertingParty, application.getString("entityID").second); + Attribute* a = rule->second.first->decode(rule->second.second, &attr, assertingParty, application.getString("entityID").second); if (a) - attributes.insert(make_pair(rule->second.second, a)); + attributes.push_back(a); + } + else if (m_log.isInfoEnabled()) { +#ifdef HAVE_GOOD_STL + auto_ptr_char temp1(name); + auto_ptr_char temp2(format); +#endif + m_log.info("skipping unmapped SAML 2.0 Attribute with Name: %s%s%s", temp1.get(), *temp2.get() ? ", Format:" : "", temp2.get()); + } +} + +void XMLExtractorImpl::extractAttributes( + const Application& application, const char* assertingParty, const Extensions& ext, vector& attributes + ) const +{ + const vector exts = ext.getUnknownXMLObjects(); + for (vector::const_iterator i = exts.begin(); i!=exts.end(); ++i) { + const saml2::Attribute* attr = dynamic_cast(*i); + if (attr) + extractAttributes(application, assertingParty, *attr, attributes); } } void XMLExtractor::extractAttributes( - const Application& application, const RoleDescriptor* issuer, const XMLObject& xmlObject, multimap& attributes + const Application& application, const RoleDescriptor* issuer, const XMLObject& xmlObject, vector& attributes ) const { if (!m_impl) @@ -380,6 +441,25 @@ void XMLExtractor::extractAttributes( throw AttributeExtractionException("Unable to extract attributes, unknown object type."); } + // Check for metadata. + if (XMLString::equals(xmlObject.getElementQName().getNamespaceURI(), samlconstants::SAML20MD_NS)) { + const EntityDescriptor* entity = dynamic_cast(&xmlObject); + if (!entity) + throw AttributeExtractionException("Unable to extract attributes, unknown metadata object type."); + auto_ptr_char assertingParty(issuer ? dynamic_cast(issuer->getParent())->getEntityID() : NULL); + const Extensions* ext = entity->getExtensions(); + if (ext) + m_impl->extractAttributes(application, assertingParty.get(), *ext, attributes); + const EntitiesDescriptor* group = dynamic_cast(entity->getParent()); + while (group) { + ext = group->getExtensions(); + if (ext) + m_impl->extractAttributes(application, assertingParty.get(), *ext, attributes); + group = dynamic_cast(group->getParent()); + } + return; + } + // Check for attributes. if (XMLString::equals(xmlObject.getElementQName().getLocalPart(), saml1::Attribute::LOCAL_NAME)) { auto_ptr_char assertingParty(issuer ? dynamic_cast(issuer->getParent())->getEntityID() : NULL); @@ -410,10 +490,14 @@ void XMLExtractor::extractAttributes( if (issuer) { MetadataCredentialCriteria mcc(*issuer); auto_ptr decrypted(encattr->decrypt(*cr, recipient, &mcc)); + if (m_log.isDebugEnabled()) + m_log.debugStream() << "decrypted Attribute: " << *(decrypted.get()) << logging::eol; return extractAttributes(application, issuer, *(decrypted.get()), attributes); } else { auto_ptr decrypted(encattr->decrypt(*cr, recipient)); + if (m_log.isDebugEnabled()) + m_log.debugStream() << "decrypted Attribute: " << *(decrypted.get()) << logging::eol; return extractAttributes(application, issuer, *(decrypted.get()), attributes); } }