using namespace opensaml::saml2md;
using namespace opensaml;
using namespace xmltooling;
-using namespace log4cpp;
using namespace std;
namespace shibsp {
m_document = doc;
}
- void filterAttributes(const FilteringContext& context, multimap<string,Attribute*>& attributes) const;
+ void filterAttributes(const FilteringContext& context, vector<Attribute*>& attributes) const;
private:
MatchFunctor* buildFunctor(
delete m_impl;
}
- void filterAttributes(const FilteringContext& context, multimap<string,Attribute*>& attributes) const {
+ void filterAttributes(const FilteringContext& context, vector<Attribute*>& attributes) const {
m_impl->filterAttributes(context, attributes);
}
static const XMLCh PermitValueRuleReference[] = UNICODE_LITERAL_24(P,e,r,m,i,t,V,a,l,u,e,R,u,l,e,R,e,f,e,r,e,n,c,e);
static const XMLCh PolicyRequirementRule[] = UNICODE_LITERAL_21(P,o,l,i,c,y,R,e,q,u,i,r,e,m,e,n,t,R,u,l,e);
static const XMLCh PolicyRequirementRuleReference[]=UNICODE_LITERAL_30(P,o,l,i,c,y,R,e,q,u,i,r,e,m,e,n,t,R,u,l,e,R,e,f,e,r,e,n,c,e);
- static const XMLCh attributeId[] = UNICODE_LITERAL_11(a,t,t,r,i,b,u,t,e,I,d);
+ static const XMLCh attributeID[] = UNICODE_LITERAL_11(a,t,t,r,i,b,u,t,e,I,D);
static const XMLCh _id[] = UNICODE_LITERAL_2(i,d);
static const XMLCh _ref[] = UNICODE_LITERAL_3(r,e,f);
};
if (e && XMLHelper::isNodeNamed(e, shibspconstants::SHIB2ATTRIBUTEFILTER_NS, AttributeRule)) {
pair<string,const MatchFunctor*> rule = buildAttributeRule(e, valFunctors, false);
if (rule.second)
- m_policies.back().m_rules.insert(rule);
+ m_policies.back().m_rules.insert(Policy::rules_t::value_type(rule.first, rule.second));
}
else if (e && XMLHelper::isNodeNamed(e, shibspconstants::SHIB2ATTRIBUTEFILTER_NS, AttributeRuleReference)) {
auto_ptr_char ref(e->getAttributeNS(NULL, _ref));
if (ref.get() && *ref.get()) {
map< string,pair<string,const MatchFunctor*> >::const_iterator ar = m_attrRules.find(ref.get());
if (ar != m_attrRules.end())
- m_policies.back().m_rules.insert(ar->second);
+ m_policies.back().m_rules.insert(Policy::rules_t::value_type(ar->second.first, ar->second.second));
else
m_log.warn("skipping invalid AttributeRuleReference (%s)", ref.get());
}
if (type.get()) {
try {
MatchFunctor* func = SPConfig::getConfig().MatchFunctorManager.newPlugin(*type.get(), make_pair(&functorMap,e));
- functorMap.getMatchFunctors().insert(make_pair(id, func));
+ functorMap.getMatchFunctors().insert(multimap<string,MatchFunctor*>::value_type(id, func));
return func;
}
catch (exception& ex) {
if (standalone && !*id) {
m_log.warn("skipping stand-alone AttributeRule with no id");
- return make_pair(string(),(MatchFunctor*)NULL);
+ return make_pair(string(),(const MatchFunctor*)NULL);
}
else if (*id && m_attrRules.count(id)) {
if (standalone) {
m_log.warn("skipping duplicate stand-alone AttributeRule with id (%s)", id);
- return make_pair(string(),(MatchFunctor*)NULL);
+ return make_pair(string(),(const MatchFunctor*)NULL);
}
else
id = "";
}
- auto_ptr_char attrId(e->getAttributeNS(NULL,attributeId));
- if (!attrId.get() || !*attrId.get())
- m_log.warn("skipping AttributeRule with no attributeId");
+ auto_ptr_char attrID(e->getAttributeNS(NULL,attributeID));
+ if (!attrID.get() || !*attrID.get())
+ m_log.warn("skipping AttributeRule with no attributeID");
e = XMLHelper::getFirstChildElement(e);
MatchFunctor* func=NULL;
if (func) {
if (*id)
- return m_attrRules[id] = make_pair(attrId.get(), func);
+ return m_attrRules[id] = pair<string,const MatchFunctor*>(attrID.get(), func);
else
- return make_pair(attrId.get(), func);
+ return pair<string,const MatchFunctor*>(attrID.get(), func);
}
m_log.warn("skipping AttributeRule (%s), PermitValueRule invalid or missing", id);
- return make_pair(string(),(MatchFunctor*)NULL);
+ return make_pair(string(),(const MatchFunctor*)NULL);
}
-void XMLFilterImpl::filterAttributes(const FilteringContext& context, multimap<string,Attribute*>& attributes) const
+void XMLFilterImpl::filterAttributes(const FilteringContext& context, vector<Attribute*>& attributes) const
{
auto_ptr_char issuer(context.getAttributeIssuer());
if (m_policies.empty()) {
m_log.warn("no filter policies were loaded, filtering out all attributes from (%s)", issuer.get() ? issuer.get() : "unknown source");
- for_each(attributes.begin(), attributes.end(), cleanup_pair<string,Attribute>());
+ for_each(attributes.begin(), attributes.end(), xmltooling::cleanup<Attribute>());
attributes.clear();
return;
}
for (vector<Policy>::const_iterator p=m_policies.begin(); p!=m_policies.end(); ++p) {
if (p->m_applies->evaluatePolicyRequirement(context)) {
// Loop over the attributes and look for possible rules to run.
- for (multimap<string,Attribute*>::iterator a=attributes.begin(); a!=attributes.end();) {
- pair<Policy::rules_t::const_iterator,Policy::rules_t::const_iterator> rules = p->m_rules.equal_range(a->second->getId());
- if (rules.first == rules.second) {
- // No rule found, so we're filtering it out.
- m_log.warn(
- "no rule found, filtering out values of attribute (%s) from (%s)", a->second->getId(), issuer.get() ? issuer.get() : "unknown source"
+ for (vector<Attribute*>::size_type a=0; a<attributes.size();) {
+ bool ruleFound = false;
+ Attribute* attr = attributes[a];
+ pair<Policy::rules_t::const_iterator,Policy::rules_t::const_iterator> rules = p->m_rules.equal_range(attr->getId());
+ if (rules.first != rules.second) {
+ ruleFound = true;
+ // Run each rule in sequence.
+ m_log.debug(
+ "applying filtering rule(s) for attribute (%s) from (%s)",
+ attr->getId(), issuer.get() ? issuer.get() : "unknown source"
);
- multimap<string,Attribute*>::iterator dead = a++;
- delete dead->second;
- attributes.erase(dead);
+ for (; rules.first!=rules.second; ++rules.first) {
+ count = attr->valueCount();
+ for (index=0; index < count;) {
+ // The return value tells us whether to index past the accepted value, or stay put and decrement the count.
+ if (rules.first->second->evaluatePermitValue(context, *attr, index)) {
+ index++;
+ }
+ else {
+ m_log.warn(
+ "removed value at position (%lu) of attribute (%s) from (%s)",
+ index, attr->getId(), issuer.get() ? issuer.get() : "unknown source"
+ );
+ attr->removeValue(index);
+ count--;
+ }
+ }
+ }
}
- else {
+
+ rules = p->m_rules.equal_range("*");
+ if (rules.first != rules.second) {
// Run each rule in sequence.
- m_log.debug("filtering values of attribute (%s) from (%s)", a->second->getId(), issuer.get() ? issuer.get() : "unknown source");
+ if (!ruleFound) {
+ m_log.debug(
+ "applying wildcard rule(s) for attribute (%s) from (%s)",
+ attr->getId(), issuer.get() ? issuer.get() : "unknown source"
+ );
+ ruleFound = true;
+ }
for (; rules.first!=rules.second; ++rules.first) {
- count = a->second->valueCount();
+ count = attr->valueCount();
for (index=0; index < count;) {
// The return value tells us whether to index past the accepted value, or stay put and decrement the count.
- if (rules.first->second->evaluatePermitValue(context, *(a->second), index)) {
+ if (rules.first->second->evaluatePermitValue(context, *attr, index)) {
index++;
}
else {
m_log.warn(
- "filtered value at position (%lu) of attribute (%s) from (%s)",
- index, a->second->getId(), issuer.get() ? issuer.get() : "unknown source"
+ "removed value at position (%lu) of attribute (%s) from (%s)",
+ index, attr->getId(), issuer.get() ? issuer.get() : "unknown source"
);
- a->second->removeValue(index);
+ attr->removeValue(index);
count--;
}
}
}
- // See if any values are left, delete if not.
- if (count>0) {
- ++a;
- }
- else {
- multimap<string,Attribute*>::iterator dead = a++;
- delete dead->second;
- attributes.erase(dead);
+ }
+
+ if (!ruleFound || attr->valueCount() == 0) {
+ if (!ruleFound) {
+ // No rule found, so we're filtering it out.
+ m_log.warn(
+ "no rule found, removing all values of attribute (%s) from (%s)",
+ attr->getId(), issuer.get() ? issuer.get() : "unknown source"
+ );
}
+ delete attr;
+ attributes.erase(attributes.begin() + a);
+ }
+ else {
+ ++a;
}
}
}