void extractAttributes(
const Application& application, const char* assertingParty, const saml2::Attribute& attr, vector<Attribute*>& attributes
) const;
+ void extractAttributes(
+ const Application& application, const char* assertingParty, const Extensions& ext, vector<Attribute*>& attributes
+ ) const;
void getAttributeIds(vector<string>& attributes) const {
attributes.insert(attributes.end(), m_attributeIds.begin(), m_attributeIds.end());
Category& m_log;
DOMDocument* m_document;
#ifdef HAVE_GOOD_STL
- typedef map< pair<xstring,xstring>,pair<AttributeDecoder*,string> > attrmap_t;
+ typedef map< pair<xstring,xstring>,pair< AttributeDecoder*,vector<string> > > attrmap_t;
#else
- typedef map< pair<string,string>,pair<AttributeDecoder*,string> > attrmap_t;
+ typedef map< pair<string,string>,pair< AttributeDecoder*,vector<string> > > attrmap_t;
#endif
attrmap_t m_attrMap;
vector<string> m_attributeIds;
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
// 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)];
+ pair< AttributeDecoder*,vector<string> >& decl = m_attrMap[pair<xstring,xstring>(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())];
+ pair< AttributeDecoder*,vector<string> >& decl = m_attrMap[pair<string,string>(n.get(),f.get())];
#endif
if (decl.first) {
m_log.warn("skipping duplicate Attribute mapping (same name and nameFormat)");
}
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<char*>(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);
}
) const
{
#ifdef HAVE_GOOD_STL
- map< pair<xstring,xstring>,pair<AttributeDecoder*,string> >::const_iterator rule;
+ map< pair<xstring,xstring>,pair< AttributeDecoder*,vector<string> > >::const_iterator rule;
#else
- map< pair<string,string>,pair<AttributeDecoder*,string> >::const_iterator rule;
+ map< pair<string,string>,pair< AttributeDecoder*,vector<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()) {
+ if ((rule=m_attrMap.find(pair<xstring,xstring>(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<string,string>(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.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
{
#ifdef HAVE_GOOD_STL
- map< pair<xstring,xstring>,pair<AttributeDecoder*,string> >::const_iterator rule;
+ map< pair<xstring,xstring>,pair< AttributeDecoder*,vector<string> > >::const_iterator rule;
#else
- map< pair<string,string>,pair<AttributeDecoder*,string> >::const_iterator rule;
+ map< pair<string,string>,pair< AttributeDecoder*,vector<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()) {
+ if ((rule=m_attrMap.find(pair<xstring,xstring>(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<string,string>(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.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
{
#ifdef HAVE_GOOD_STL
- map< pair<xstring,xstring>,pair<AttributeDecoder*,string> >::const_iterator rule;
+ map< pair<xstring,xstring>,pair< AttributeDecoder*,vector<string> > >::const_iterator rule;
#else
- map< pair<string,string>,pair<AttributeDecoder*,string> >::const_iterator rule;
+ map< pair<string,string>,pair< AttributeDecoder*,vector<string> > >::const_iterator rule;
#endif
const XMLCh* name = attr.getAttributeName();
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<xstring,xstring>(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<string,string>(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.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
{
#ifdef HAVE_GOOD_STL
- map< pair<xstring,xstring>,pair<AttributeDecoder*,string> >::const_iterator rule;
+ map< pair<xstring,xstring>,pair< AttributeDecoder*,vector<string> > >::const_iterator rule;
#else
- map< pair<string,string>,pair<AttributeDecoder*,string> >::const_iterator rule;
+ map< pair<string,string>,pair< AttributeDecoder*,vector<string> > >::const_iterator rule;
#endif
const XMLCh* name = attr.getName();
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<xstring,xstring>(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<string,string>(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.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<Attribute*>& attributes
+ ) const
+{
+ const vector<XMLObject*> exts = ext.getUnknownXMLObjects();
+ for (vector<XMLObject*>::const_iterator i = exts.begin(); i!=exts.end(); ++i) {
+ const saml2::Attribute* attr = dynamic_cast<const saml2::Attribute*>(*i);
+ if (attr)
+ extractAttributes(application, assertingParty, *attr, attributes);
+ }
}
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<const EntityDescriptor*>(&xmlObject);
+ if (!entity)
+ throw AttributeExtractionException("Unable to extract attributes, unknown metadata object type.");
+ auto_ptr_char assertingParty(issuer ? dynamic_cast<const EntityDescriptor*>(issuer->getParent())->getEntityID() : NULL);
+ const Extensions* ext = entity->getExtensions();
+ if (ext)
+ m_impl->extractAttributes(application, assertingParty.get(), *ext, attributes);
+ const EntitiesDescriptor* group = dynamic_cast<const EntitiesDescriptor*>(entity->getParent());
+ while (group) {
+ ext = group->getExtensions();
+ if (ext)
+ m_impl->extractAttributes(application, assertingParty.get(), *ext, attributes);
+ group = dynamic_cast<const EntitiesDescriptor*>(group->getParent());
+ }
+ return;
+ }
+
// 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);
if (issuer) {
MetadataCredentialCriteria mcc(*issuer);
auto_ptr<XMLObject> 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<XMLObject> 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);
}
}