#include "util/SPConstants.h"
#include <map>
+#include <boost/shared_ptr.hpp>
#include <saml/SAMLConfig.h>
#include <saml/binding/SecurityPolicyRule.h>
#include <xmltooling/io/HTTPResponse.h>
using opensaml::SecurityPolicyRule;
using namespace shibsp;
using namespace xmltooling;
+using namespace boost;
using namespace std;
namespace shibsp {
class SHIBSP_DLLLOCAL XMLSecurityPolicyProviderImpl
{
public:
- XMLSecurityPolicyProviderImpl(const DOMElement* e, Category& log);
+ XMLSecurityPolicyProviderImpl(const DOMElement*, Category&);
~XMLSecurityPolicyProviderImpl() {
- for (map< string,pair<PropertySet*,vector<const SecurityPolicyRule*> > >::iterator i = m_policyMap.begin(); i != m_policyMap.end(); ++i) {
- delete i->second.first;
- for_each(i->second.second.begin(), i->second.second.end(), xmltooling::cleanup<SecurityPolicyRule>());
- }
if (m_document)
m_document->release();
}
private:
DOMDocument* m_document;
+ bool m_includeDefaultBlacklist;
vector<xstring> m_whitelist,m_blacklist;
- map< string,pair< PropertySet*,vector<const SecurityPolicyRule*> > > m_policyMap;
- map< string,pair< PropertySet*,vector<const SecurityPolicyRule*> > >::const_iterator m_defaultPolicy;
+ vector< boost::shared_ptr<SecurityPolicyRule> > m_ruleJanitor; // need this to maintain vector type in API
+ typedef map< string,pair< boost::shared_ptr<PropertySet>,vector<const SecurityPolicyRule*> > > policymap_t;
+ policymap_t m_policyMap;
+ policymap_t::const_iterator m_defaultPolicy;
friend class SHIBSP_DLLLOCAL XMLSecurityPolicyProvider;
};
{
public:
XMLSecurityPolicyProvider(const DOMElement* e)
- : ReloadableXMLFile(e, Category::getInstance(SHIBSP_LOGCAT".SecurityPolicyProvider.XML")), m_impl(nullptr) {
+ : ReloadableXMLFile(e, Category::getInstance(SHIBSP_LOGCAT".SecurityPolicyProvider.XML")) {
background_load(); // guarantees an exception or the policy is loaded
}
~XMLSecurityPolicyProvider() {
shutdown();
- delete m_impl;
}
const PropertySet* getPolicySettings(const char* id=nullptr) const {
if (!id || !*id)
- return m_impl->m_defaultPolicy->second.first;
- map<string,pair<PropertySet*,vector<const SecurityPolicyRule*> > >::const_iterator i = m_impl->m_policyMap.find(id);
+ return m_impl->m_defaultPolicy->second.first.get();
+ XMLSecurityPolicyProviderImpl::policymap_t::const_iterator i = m_impl->m_policyMap.find(id);
if (i != m_impl->m_policyMap.end())
- return i->second.first;
+ return i->second.first.get();
throw ConfigurationException("Security Policy ($1) not found, check <SecurityPolicies> element.", params(1,id));
}
const vector<const SecurityPolicyRule*>& getPolicyRules(const char* id=nullptr) const {
if (!id || !*id)
return m_impl->m_defaultPolicy->second.second;
- map<string,pair<PropertySet*,vector<const SecurityPolicyRule*> > >::const_iterator i = m_impl->m_policyMap.find(id);
+ XMLSecurityPolicyProviderImpl::policymap_t::const_iterator i = m_impl->m_policyMap.find(id);
if (i != m_impl->m_policyMap.end())
return i->second.second;
throw ConfigurationException("Security Policy ($1) not found, check <SecurityPolicies> element.", params(1,id));
}
+ const vector<xstring>& getDefaultAlgorithmBlacklist() const {
+ return m_impl->m_includeDefaultBlacklist ? m_defaultBlacklist : m_empty;
+ }
const vector<xstring>& getAlgorithmBlacklist() const {
return m_impl->m_blacklist;
}
pair<bool,DOMElement*> background_load();
private:
- XMLSecurityPolicyProviderImpl* m_impl;
+ scoped_ptr<XMLSecurityPolicyProviderImpl> m_impl;
+ static vector<xstring> m_empty;
};
#if defined (_MSC_VER)
static const XMLCh _id[] = UNICODE_LITERAL_2(i,d);
static const XMLCh _type[] = UNICODE_LITERAL_4(t,y,p,e);
+ static const XMLCh includeDefaultBlacklist[] = UNICODE_LITERAL_23(i,n,c,l,u,d,e,D,e,f,a,u,l,t,B,l,a,c,k,l,i,s,t);
static const XMLCh AlgorithmBlacklist[] = UNICODE_LITERAL_18(A,l,g,o,r,i,t,h,m,B,l,a,c,k,l,i,s,t);
static const XMLCh AlgorithmWhitelist[] = UNICODE_LITERAL_18(A,l,g,o,r,i,t,h,m,W,h,i,t,e,l,i,s,t);
static const XMLCh Policy[] = UNICODE_LITERAL_6(P,o,l,i,c,y);
SecurityPolicyProvider::SecurityPolicyProvider()
{
+ m_defaultBlacklist.push_back(DSIGConstants::s_unicodeStrURIRSA_MD5);
+ m_defaultBlacklist.push_back(DSIGConstants::s_unicodeStrURIMD5);
+ m_defaultBlacklist.push_back(DSIGConstants::s_unicodeStrURIRSA_1_5);
}
SecurityPolicyProvider::~SecurityPolicyProvider()
{
}
+const vector<xstring>& SecurityPolicyProvider::getDefaultAlgorithmBlacklist() const
+{
+ return m_defaultBlacklist;
+}
+
SecurityPolicy* SecurityPolicyProvider::createSecurityPolicy(
const Application& application, const xmltooling::QName* role, const char* policyId
) const
}
XMLSecurityPolicyProviderImpl::XMLSecurityPolicyProviderImpl(const DOMElement* e, Category& log)
- : m_document(nullptr), m_defaultPolicy(m_policyMap.end())
+ : m_document(nullptr), m_includeDefaultBlacklist(true), m_defaultPolicy(m_policyMap.end())
{
#ifdef _DEBUG
xmltooling::NDC ndc("XMLSecurityPolicyProviderImpl");
const XMLCh* algs = nullptr;
const DOMElement* alglist = XMLHelper::getLastChildElement(e, AlgorithmBlacklist);
- if (alglist && alglist->hasChildNodes()) {
- algs = alglist->getFirstChild()->getNodeValue();
+ if (alglist) {
+ m_includeDefaultBlacklist = XMLHelper::getAttrBool(alglist, true, includeDefaultBlacklist);
+ if (alglist->hasChildNodes()) {
+ algs = alglist->getFirstChild()->getNodeValue();
+ }
}
else if ((alglist = XMLHelper::getLastChildElement(e, AlgorithmWhitelist)) && alglist->hasChildNodes()) {
algs = alglist->getFirstChild()->getNodeValue();
+ m_includeDefaultBlacklist = false;
}
if (algs) {
const XMLCh* token;
e = XMLHelper::getFirstChildElement(e, Policy);
while (e) {
string id(XMLHelper::getAttrString(e, nullptr, _id));
- pair< PropertySet*,vector<const SecurityPolicyRule*> >& rules = m_policyMap[id];
- rules.first = nullptr;
- auto_ptr<DOMPropertySet> settings(new DOMPropertySet());
+ policymap_t::mapped_type& rules = m_policyMap[id];
+ boost::shared_ptr<DOMPropertySet> settings(new DOMPropertySet());
settings->load(e, nullptr, &filter);
- rules.first = settings.release();
+ rules.first = settings;
// Set default policy if not set, or id is "default".
if (m_defaultPolicy == m_policyMap.end() || id == "default")
string t(XMLHelper::getAttrString(rule, nullptr, _type));
if (!t.empty()) {
try {
- rules.second.push_back(samlConf.SecurityPolicyRuleManager.newPlugin(t.c_str(), rule));
+ boost::shared_ptr<SecurityPolicyRule> ptr(samlConf.SecurityPolicyRuleManager.newPlugin(t.c_str(), rule));
+ m_ruleJanitor.push_back(ptr);
+ rules.second.push_back(ptr.get());
}
- catch (exception& ex) {
+ catch (std::exception& ex) {
log.crit("error instantiating policy rule (%s) in policy (%s): %s", t.c_str(), id.c_str(), ex.what());
}
}
if (rules.second.size() == 0) {
// Process Rule elements.
- log.warn("detected legacy Policy configuration, please convert to new PolicyRule syntax");
+ log.warn("detected deprecated Policy configuration, consider converting to new PolicyRule syntax");
rule = XMLHelper::getFirstChildElement(e, Rule);
while (rule) {
string t(XMLHelper::getAttrString(rule, nullptr, _type));
if (!t.empty()) {
try {
- rules.second.push_back(samlConf.SecurityPolicyRuleManager.newPlugin(t.c_str(), rule));
+ boost::shared_ptr<SecurityPolicyRule> ptr(samlConf.SecurityPolicyRuleManager.newPlugin(t.c_str(), rule));
+ m_ruleJanitor.push_back(ptr);
+ rules.second.push_back(ptr.get());
}
- catch (exception& ex) {
+ catch (std::exception& ex) {
log.crit("error instantiating policy rule (%s) in policy (%s): %s", t.c_str(), id.c_str(), ex.what());
}
}
// Manually add a basic Conditions rule.
log.info("installing a default Conditions rule in policy (%s) for compatibility with legacy configuration", id.c_str());
- rules.second.push_back(samlConf.SecurityPolicyRuleManager.newPlugin(CONDITIONS_POLICY_RULE, nullptr));
+ boost::shared_ptr<SecurityPolicyRule> cptr(samlConf.SecurityPolicyRuleManager.newPlugin(CONDITIONS_POLICY_RULE, nullptr));
+ m_ruleJanitor.push_back(cptr);
+ rules.second.push_back(cptr.get());
}
e = XMLHelper::getNextSiblingElement(e, Policy);
throw ConfigurationException("XML SecurityPolicyProvider requires at least one Policy.");
}
+vector<xstring> XMLSecurityPolicyProvider::m_empty;
+
pair<bool,DOMElement*> XMLSecurityPolicyProvider::load(bool backup)
{
// Load from source using base class.
// If we own it, wrap it.
XercesJanitor<DOMDocument> docjanitor(raw.first ? raw.second->getOwnerDocument() : nullptr);
- XMLSecurityPolicyProviderImpl* impl = new XMLSecurityPolicyProviderImpl(raw.second, m_log);
+ scoped_ptr<XMLSecurityPolicyProviderImpl> impl(new XMLSecurityPolicyProviderImpl(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);
}
return load(true);
throw;
}
- catch (exception&) {
+ catch (std::exception&) {
if (!m_loaded && !m_backing.empty())
return load(true);
throw;