-/*
- * Copyright 2001-2010 Internet2
+/**
+ * Licensed to the University Corporation for Advanced Internet
+ * Development, Inc. (UCAID) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for
+ * additional information regarding copyright ownership.
*
- * 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
+ * UCAID licenses this file to you 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
+ * 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.
+ * 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.
*/
/**
#include "attribute/filtering/MatchFunctor.h"
#include "util/SPConstants.h"
+#include <boost/iterator/indirect_iterator.hpp>
+#include <boost/tuple/tuple.hpp>
#include <xmltooling/util/NDC.h>
#include <xmltooling/util/ReloadableXMLFile.h>
#include <xmltooling/util/Threads.h>
using namespace opensaml::saml2md;
using namespace opensaml;
using namespace xmltooling;
+using namespace boost;
using namespace std;
namespace shibsp {
MatchFunctor* buildFunctor(
const DOMElement* e, const FilterPolicyContext& functorMap, const char* logname, bool standalone
);
- pair< string,pair<const MatchFunctor*,const MatchFunctor*> > buildAttributeRule(
+ tuple<string,const MatchFunctor*,const MatchFunctor*> buildAttributeRule(
const DOMElement* e, const FilterPolicyContext& permMap, const FilterPolicyContext& denyMap, bool standalone
);
Category& m_log;
DOMDocument* m_document;
vector<Policy> m_policies;
- map< string,pair<string,pair<const MatchFunctor*,const MatchFunctor*> > > m_attrRules;
+ map< string,tuple<string,const MatchFunctor*,const MatchFunctor*> > m_attrRules;
multimap<string,MatchFunctor*> m_policyReqRules;
multimap<string,MatchFunctor*> m_permitValRules;
multimap<string,MatchFunctor*> m_denyValRules;
class SHIBSP_DLLLOCAL XMLFilter : public AttributeFilter, public ReloadableXMLFile
{
public:
- XMLFilter(const DOMElement* e) : ReloadableXMLFile(e, Category::getInstance(SHIBSP_LOGCAT".AttributeFilter")), m_impl(nullptr) {
+ XMLFilter(const DOMElement* e) : ReloadableXMLFile(e, Category::getInstance(SHIBSP_LOGCAT ".AttributeFilter")) {
background_load();
}
~XMLFilter() {
shutdown();
- delete m_impl;
}
void filterAttributes(const FilteringContext& context, vector<Attribute*>& attributes) const {
pair<bool,DOMElement*> background_load();
private:
- XMLFilterImpl* m_impl;
+ scoped_ptr<XMLFilterImpl> m_impl;
};
#if defined (_MSC_VER)
e = XMLHelper::getNextSiblingElement(e);
while (e) {
if (e && XMLHelper::isNodeNamed(e, SHIB2ATTRIBUTEFILTER_NS, AttributeRule)) {
- pair< string,pair<const MatchFunctor*,const MatchFunctor*> > rule = buildAttributeRule(e, permFunctors, denyFunctors, false);
- if (rule.second.first || rule.second.second)
- m_policies.back().m_rules.insert(Policy::rules_t::value_type(rule.first, rule.second));
+ tuple<string,const MatchFunctor*,const MatchFunctor*> rule = buildAttributeRule(e, permFunctors, denyFunctors, false);
+ if (rule.get<1>() || rule.get<2>())
+ m_policies.back().m_rules.insert(Policy::rules_t::value_type(rule.get<0>(), make_pair(rule.get<1>(), rule.get<2>())));
}
else if (e && XMLHelper::isNodeNamed(e, SHIB2ATTRIBUTEFILTER_NS, AttributeRuleReference)) {
string ref(XMLHelper::getAttrString(e, nullptr, _ref));
if (!ref.empty()) {
- map< string,pair< string,pair< const MatchFunctor*,const MatchFunctor*> > >::const_iterator ar = m_attrRules.find(ref);
- if (ar != m_attrRules.end())
- m_policies.back().m_rules.insert(Policy::rules_t::value_type(ar->second.first, ar->second.second));
- else
+ map< string,tuple<string,const MatchFunctor*,const MatchFunctor*> >::const_iterator ar = m_attrRules.find(ref);
+ if (ar != m_attrRules.end()) {
+ m_policies.back().m_rules.insert(
+ Policy::rules_t::value_type(ar->second.get<0>(), make_pair(ar->second.get<1>(), ar->second.get<2>()))
+ );
+ }
+ else {
m_log.warn("skipping invalid AttributeRuleReference (%s)", ref.c_str());
+ }
}
}
e = XMLHelper::getNextSiblingElement(e);
id.clear();
}
- auto_ptr<xmltooling::QName> type(XMLHelper::getXSIType(e));
- if (type.get()) {
+ scoped_ptr<xmltooling::QName> type(XMLHelper::getXSIType(e));
+ if (type) {
try {
- MatchFunctor* func = SPConfig::getConfig().MatchFunctorManager.newPlugin(*type.get(), make_pair(&functorMap,e));
- functorMap.getMatchFunctors().insert(multimap<string,MatchFunctor*>::value_type(id, func));
- return func;
+ auto_ptr<MatchFunctor> func(SPConfig::getConfig().MatchFunctorManager.newPlugin(*type, make_pair(&functorMap,e)));
+ functorMap.getMatchFunctors().insert(multimap<string,MatchFunctor*>::value_type(id, func.get()));
+ return func.release();
}
catch (exception& ex) {
m_log.error("error building %s with type (%s): %s", logname, type->toString().c_str(), ex.what());
return nullptr;
}
-pair< string,pair<const MatchFunctor*,const MatchFunctor*> > XMLFilterImpl::buildAttributeRule(
+tuple<string,const MatchFunctor*,const MatchFunctor*> XMLFilterImpl::buildAttributeRule(
const DOMElement* e, const FilterPolicyContext& permMap, const FilterPolicyContext& denyMap, bool standalone
)
{
if (standalone && id.empty()) {
m_log.warn("skipping stand-alone AttributeRule with no id");
- return make_pair(string(),pair<const MatchFunctor*,const MatchFunctor*>(nullptr,nullptr));
+ return tuple<string,const MatchFunctor*,const MatchFunctor*>(string(),nullptr,nullptr);
}
else if (!id.empty() && m_attrRules.count(id)) {
if (standalone) {
m_log.warn("skipping duplicate stand-alone AttributeRule with id (%s)", id.c_str());
- return make_pair(string(),pair<const MatchFunctor*,const MatchFunctor*>(nullptr,nullptr));
+ return tuple<string,const MatchFunctor*,const MatchFunctor*>(string(),nullptr,nullptr);
}
else
id.clear();
if (attrID.empty())
m_log.warn("skipping AttributeRule with no attributeID");
- MatchFunctor* perm=nullptr;
- MatchFunctor* deny=nullptr;
+ MatchFunctor* perm = nullptr;
+ MatchFunctor* deny = nullptr;
e = XMLHelper::getFirstChildElement(e);
if (e && XMLHelper::isNodeNamed(e, SHIB2ATTRIBUTEFILTER_NS, PermitValueRule)) {
if (perm || deny) {
if (!id.empty()) {
- m_attrRules[id] =
- pair< string,pair<const MatchFunctor*,const MatchFunctor*> >(attrID, pair<const MatchFunctor*,const MatchFunctor*>(perm,deny));
+ m_attrRules[id] = make_tuple(attrID, perm, deny);
return m_attrRules[id];
}
else {
- return pair< string,pair<const MatchFunctor*,const MatchFunctor*> >(attrID, pair<const MatchFunctor*,const MatchFunctor*>(perm,deny));
+ return make_tuple(attrID, perm, deny);
}
}
m_log.warn("skipping AttributeRule (%s), permit and denial rule(s) invalid or missing", id.c_str());
else
m_log.warn("skipping AttributeRule, permit and denial rule(s) invalid or missing");
- return pair< string,pair<const MatchFunctor*,const MatchFunctor*> >(string(),pair<const MatchFunctor*,const MatchFunctor*>(nullptr,nullptr));
+ return tuple<string,const MatchFunctor*,const MatchFunctor*>(string(),nullptr,nullptr);
}
void XMLFilterImpl::filterAttributes(const FilteringContext& context, vector<Attribute*>& attributes) const
// For efficiency, we build an array of the policies that apply in advance.
vector<const Policy*> applicablePolicies;
- for (vector<Policy>::const_iterator p=m_policies.begin(); p!=m_policies.end(); ++p) {
+ for (vector<Policy>::const_iterator p = m_policies.begin(); p != m_policies.end(); ++p) {
if (p->m_applies->evaluatePolicyRequirement(context))
applicablePolicies.push_back(&(*p));
}
vector< pair<const MatchFunctor*,const MatchFunctor*> > wildcardRules;
// Store off the wildcards ahead of time.
- for (vector<const Policy*>::const_iterator pol=applicablePolicies.begin(); pol!=applicablePolicies.end(); ++pol) {
- pair<Policy::rules_t::const_iterator,Policy::rules_t::const_iterator> rules = (*pol)->m_rules.equal_range("*");
+ for (indirect_iterator<vector<const Policy*>::const_iterator> pol = make_indirect_iterator(applicablePolicies.begin());
+ pol != make_indirect_iterator(applicablePolicies.end()); ++pol) {
+ pair<Policy::rules_t::const_iterator,Policy::rules_t::const_iterator> rules = pol->m_rules.equal_range("*");
for (; rules.first!=rules.second; ++rules.first)
wildcardRules.push_back(rules.first->second);
}
map< Attribute*, vector<bool> > deletedPositions;
// Loop over each attribute to filter them.
- for (vector<Attribute*>::size_type a=0; a<attributes.size(); ++a) {
+ for (vector<Attribute*>::size_type a = 0; a < attributes.size(); ++a) {
Attribute* attr = attributes[a];
// Clear the rule store.
applicableRules.clear();
// Look for rules to run in each policy.
- for (vector<const Policy*>::const_iterator pol=applicablePolicies.begin(); pol!=applicablePolicies.end(); ++pol) {
- pair<Policy::rules_t::const_iterator,Policy::rules_t::const_iterator> rules = (*pol)->m_rules.equal_range(attr->getId());
+ for (indirect_iterator<vector<const Policy*>::const_iterator> pol = make_indirect_iterator(applicablePolicies.begin());
+ pol != make_indirect_iterator(applicablePolicies.end()); ++pol) {
+ pair<Policy::rules_t::const_iterator,Policy::rules_t::const_iterator> rules = pol->m_rules.equal_range(attr->getId());
for (; rules.first!=rules.second; ++rules.first)
applicableRules.push_back(rules.first->second);
}
// If no rules found, apply wildcards.
- const vector< pair<const MatchFunctor*,const MatchFunctor*> >& rulesToRun = applicableRules.empty() ? wildcardRules : applicableRules;
+ const vector< pair<const MatchFunctor*,const MatchFunctor*> >& rulesToRun =
+ applicableRules.empty() ? wildcardRules : applicableRules;
// If no rules apply, remove the attribute entirely.
if (rulesToRun.empty()) {
// Assume we're kicking it out.
kickit=true;
- for (vector< pair<const MatchFunctor*,const MatchFunctor*> >::const_iterator r=rulesToRun.begin(); r!=rulesToRun.end(); ++r) {
+ for (vector< pair<const MatchFunctor*,const MatchFunctor*> >::const_iterator r = rulesToRun.begin(); r != rulesToRun.end(); ++r) {
// If there's a permit rule that passes, don't kick it.
if (r->first && r->first->evaluatePermitValue(context, *attr, index))
kickit = false;
// Final step: go over the deletedPositions matrix and apply the actual changes. In order to delete
// any attributes that end up with no values, we have to do it by looping over the originals.
- for (vector<Attribute*>::size_type a=0; a<attributes.size();) {
+ for (vector<Attribute*>::size_type a = 0; a < attributes.size();) {
Attribute* attr = attributes[a];
if (deletedAttributes[a]) {
// If we own it, wrap it.
XercesJanitor<DOMDocument> docjanitor(raw.first ? raw.second->getOwnerDocument() : nullptr);
- XMLFilterImpl* impl = new XMLFilterImpl(raw.second, m_log);
+ scoped_ptr<XMLFilterImpl> impl(new XMLFilterImpl(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());
if (m_lock)
m_lock->wrlock();
SharedLock locker(m_lock, false);
- delete m_impl;
- m_impl = impl;
+ m_impl.swap(impl);
return make_pair(false,(DOMElement*)nullptr);
}