#include "attribute/filtering/MatchFunctor.h"
#include "util/SPConstants.h"
+#include <boost/scoped_ptr.hpp>
+#include <boost/lambda/bind.hpp>
+#include <boost/lambda/lambda.hpp>
#include <xercesc/util/XMLUniDefs.hpp>
#include <xmltooling/util/XMLHelper.h>
using namespace shibsp;
using namespace xmltooling;
+using namespace boost::lambda;
+using namespace boost;
using namespace std;
namespace shibsp {
bool evaluatePolicyRequirement(const FilteringContext& filterContext) const {
if (m_functors.empty())
return false;
- for (vector<const MatchFunctor*>::const_iterator mf = m_functors.begin(); mf!=m_functors.end(); ++mf)
- if (!(*mf)->evaluatePolicyRequirement(filterContext))
- return false;
- return true;
+ vector<const MatchFunctor*>::const_iterator i = find_if(
+ m_functors.begin(), m_functors.end(),
+ lambda::bind(&MatchFunctor::evaluatePolicyRequirement, _1, boost::ref(filterContext)) == false
+ );
+ return (i == m_functors.end());
}
bool evaluatePermitValue(const FilteringContext& filterContext, const Attribute& attribute, size_t index) const {
if (m_functors.empty())
return false;
- for (vector<const MatchFunctor*>::const_iterator mf = m_functors.begin(); mf!=m_functors.end(); ++mf)
- if (!(*mf)->evaluatePermitValue(filterContext, attribute, index))
- return false;
- return true;
+ vector<const MatchFunctor*>::const_iterator i = find_if(
+ m_functors.begin(), m_functors.end(),
+ lambda::bind(&MatchFunctor::evaluatePermitValue, _1, boost::ref(filterContext), boost::ref(attribute), index) == false
+ );
+ return (i == m_functors.end());
}
private:
if (!id.empty() && functorMap->getMatchFunctors().count(id))
id.clear();
- auto_ptr<xmltooling::QName> type(XMLHelper::getXSIType(e));
- if (!type.get())
+ scoped_ptr<xmltooling::QName> type(XMLHelper::getXSIType(e));
+ if (!type)
throw ConfigurationException("Child Rule found with no xsi:type.");
- 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();
}
#include "attribute/filtering/FilterPolicyContext.h"
#include "attribute/filtering/MatchFunctor.h"
+#include <boost/scoped_ptr.hpp>
#include <xercesc/util/regx/RegularExpression.hpp>
namespace shibsp {
*/
class SHIBSP_DLLLOCAL AttributeIssuerRegexFunctor : public MatchFunctor
{
- RegularExpression* m_regex;
+ boost::scoped_ptr<RegularExpression> m_regex;
public:
- AttributeIssuerRegexFunctor(const DOMElement* e) : m_regex(nullptr) {
- const XMLCh* r = e ? e->getAttributeNS(nullptr,regex) : nullptr;
+ AttributeIssuerRegexFunctor(const DOMElement* e) {
+ const XMLCh* r = e ? e->getAttributeNS(nullptr, regex) : nullptr;
if (!r || !*r)
throw ConfigurationException("AttributeIssuerRegex MatchFunctor requires non-empty regex attribute.");
try {
- m_regex = new RegularExpression(r, e->getAttributeNS(nullptr,options));
+ m_regex.reset(new RegularExpression(r, e->getAttributeNS(nullptr,options)));
}
catch (XMLException& ex) {
xmltooling::auto_ptr_char temp(ex.getMessage());
}
}
- virtual ~AttributeIssuerRegexFunctor() {
- delete m_regex;
- }
+ virtual ~AttributeIssuerRegexFunctor() {}
bool evaluatePolicyRequirement(const FilteringContext& filterContext) const {
return m_regex->matches(filterContext.getAttributeIssuer());
const XMLCh* m_value;
bool m_ignoreCase;
public:
- AttributeIssuerStringFunctor(const DOMElement* e) : m_value(nullptr), m_ignoreCase(XMLHelper::getAttrBool(e, false, ignoreCase)) {
- m_value = e ? e->getAttributeNS(nullptr,value) : nullptr;
+ AttributeIssuerStringFunctor(const DOMElement* e)
+ : m_value(e ? e->getAttributeNS(nullptr,value) : nullptr),
+ m_ignoreCase(XMLHelper::getAttrBool(e, false, ignoreCase)) {
if (!m_value || !*m_value)
throw ConfigurationException("AttributeIssuerString MatchFunctor requires non-empty value attribute.");
}
#include "attribute/filtering/FilterPolicyContext.h"
#include "attribute/filtering/MatchFunctor.h"
+#include <boost/scoped_ptr.hpp>
#include <xercesc/util/regx/RegularExpression.hpp>
namespace shibsp {
*/
class SHIBSP_DLLLOCAL AttributeRequesterRegexFunctor : public MatchFunctor
{
- RegularExpression* m_regex;
+ boost::scoped_ptr<RegularExpression> m_regex;
public:
- AttributeRequesterRegexFunctor(const DOMElement* e) : m_regex(nullptr) {
- const XMLCh* r = e ? e->getAttributeNS(nullptr,regex) : nullptr;
+ AttributeRequesterRegexFunctor(const DOMElement* e) {
+ const XMLCh* r = e ? e->getAttributeNS(nullptr, regex) : nullptr;
if (!r || !*r)
throw ConfigurationException("AttributeRequesterRegex MatchFunctor requires non-empty regex attribute.");
try {
- m_regex = new RegularExpression(r, e->getAttributeNS(nullptr,options));
+ m_regex.reset(new RegularExpression(r, e->getAttributeNS(nullptr, options)));
}
catch (XMLException& ex) {
xmltooling::auto_ptr_char temp(ex.getMessage());
}
}
- virtual ~AttributeRequesterRegexFunctor() {
- delete m_regex;
- }
+ virtual ~AttributeRequesterRegexFunctor() {}
bool evaluatePolicyRequirement(const FilteringContext& filterContext) const {
return m_regex->matches(filterContext.getAttributeRequester());
const XMLCh* m_value;
bool m_ignoreCase;
public:
- AttributeRequesterStringFunctor(const DOMElement* e) : m_value(nullptr), m_ignoreCase(XMLHelper::getAttrBool(e, false, ignoreCase)) {
- m_value = e ? e->getAttributeNS(nullptr,value) : nullptr;
+ AttributeRequesterStringFunctor(const DOMElement* e)
+ : m_value(e ? e->getAttributeNS(nullptr,value) : nullptr),
+ m_ignoreCase(XMLHelper::getAttrBool(e, false, ignoreCase)) {
if (!m_value || !*m_value)
throw ConfigurationException("AttributeRequesterString MatchFunctor requires non-empty value attribute.");
}
const char* scope = attribute.getScope(index);
if (!scope || !*scope)
return false;
+ auto_arrayptr<XMLCh> widescope(fromUTF8(scope));
const Scope* rule;
- const XMLCh* widescope=nullptr;
const Extensions* ext = issuer->getExtensions();
if (ext) {
const vector<XMLObject*>& exts = ext->getUnknownXMLObjects();
- for (vector<XMLObject*>::const_iterator e = exts.begin(); e!=exts.end(); ++e) {
+ for (vector<XMLObject*>::const_iterator e = exts.begin(); e != exts.end(); ++e) {
rule = dynamic_cast<const Scope*>(*e);
- if (rule) {
- if (!widescope)
- widescope = fromUTF8(scope);
- if (matches(*rule, widescope)) {
- delete[] widescope;
- return true;
- }
+ if (rule && matches(*rule, widescope)) {
+ return true;
}
}
}
ext = dynamic_cast<const EntityDescriptor*>(issuer->getParent())->getExtensions();
if (ext) {
const vector<XMLObject*>& exts = ext->getUnknownXMLObjects();
- for (vector<XMLObject*>::const_iterator e = exts.begin(); e!=exts.end(); ++e) {
+ for (vector<XMLObject*>::const_iterator e = exts.begin(); e != exts.end(); ++e) {
rule = dynamic_cast<const Scope*>(*e);
- if (rule) {
- if (!widescope)
- widescope = fromUTF8(scope);
- if (matches(*rule, widescope)) {
- delete[] widescope;
- return true;
- }
+ if (rule && matches(*rule, widescope)) {
+ return true;
}
}
}
- delete[] widescope;
return false;
}
private:
- bool matches(const Scope& rule, const XMLCh* scope) const {
+ bool matches(const Scope& rule, auto_arrayptr<XMLCh>& scope) const {
const XMLCh* val = rule.getValue();
if (val && *val) {
if (rule.Regexp()) {
RegularExpression re(val);
- return re.matches(scope);
+ return re.matches(scope.get());
}
else {
- return XMLString::equals(val, scope);
+ return XMLString::equals(val, scope.get());
}
}
return false;
}
};
- MatchFunctor* SHIBSP_DLLLOCAL AttributeScopeMatchesShibMDScopeFactory(const std::pair<const FilterPolicyContext*,const DOMElement*>& p)
+ MatchFunctor* SHIBSP_DLLLOCAL AttributeScopeMatchesShibMDScopeFactory(const pair<const FilterPolicyContext*,const DOMElement*>& p)
{
return new AttributeScopeMatchesShibMDScopeFunctor();
}
#include "attribute/filtering/FilterPolicyContext.h"
#include "attribute/filtering/MatchFunctor.h"
+#include <boost/scoped_ptr.hpp>
#include <xmltooling/util/XMLHelper.h>
#include <xercesc/util/regx/RegularExpression.hpp>
using namespace shibsp;
+using namespace xmltooling;
+using namespace boost;
using namespace std;
-using xmltooling::XMLHelper;
namespace shibsp {
class SHIBSP_DLLLOCAL AttributeScopeRegexFunctor : public MatchFunctor
{
string m_attributeID;
- RegularExpression* m_regex;
+ scoped_ptr<RegularExpression> m_regex;
bool hasScope(const FilteringContext& filterContext) const;
bool matches(const Attribute& attribute, size_t index) const;
public:
- AttributeScopeRegexFunctor(const DOMElement* e) : m_attributeID(XMLHelper::getAttrString(e, nullptr, attributeID)), m_regex(nullptr) {
- const XMLCh* r = e ? e->getAttributeNS(nullptr,regex) : nullptr;
+ AttributeScopeRegexFunctor(const DOMElement* e) : m_attributeID(XMLHelper::getAttrString(e, nullptr, attributeID)) {
+ const XMLCh* r = e ? e->getAttributeNS(nullptr, regex) : nullptr;
if (!r || !*r)
throw ConfigurationException("AttributeScopeRegex MatchFunctor requires non-empty regex attribute.");
try {
- m_regex = new RegularExpression(r, e->getAttributeNS(nullptr,options));
+ m_regex.reset(new RegularExpression(r, e->getAttributeNS(nullptr, options)));
}
catch (XMLException& ex) {
xmltooling::auto_ptr_char temp(ex.getMessage());
}
}
- virtual ~AttributeScopeRegexFunctor() {
- delete m_regex;
- }
+ virtual ~AttributeScopeRegexFunctor() {}
bool evaluatePolicyRequirement(const FilteringContext& filterContext) const {
if (m_attributeID.empty())
}
};
- MatchFunctor* SHIBSP_DLLLOCAL AttributeScopeRegexFactory(const std::pair<const FilterPolicyContext*,const DOMElement*>& p)
+ MatchFunctor* SHIBSP_DLLLOCAL AttributeScopeRegexFactory(const pair<const FilterPolicyContext*,const DOMElement*>& p)
{
return new AttributeScopeRegexFunctor(p.second);
}
const char* val = attribute.getScope(index);
if (!val)
return false;
- XMLCh* temp = xmltooling::fromUTF8(val);
- bool ret = m_regex->matches(temp);
- delete[] temp;
- return ret;
+ auto_arrayptr<XMLCh> temp(fromUTF8(val));
+ return m_regex->matches(temp.get());
}
#include <xmltooling/util/XMLHelper.h>
using namespace shibsp;
+using namespace xmltooling;
using namespace std;
-using xmltooling::XMLHelper;
namespace shibsp {
class SHIBSP_DLLLOCAL AttributeScopeStringFunctor : public MatchFunctor
{
string m_attributeID;
- char* m_value;
+ auto_arrayptr<char> m_value;
bool m_ignoreCase;
bool hasScope(const FilteringContext& filterContext) const;
public:
AttributeScopeStringFunctor(const DOMElement* e)
: m_attributeID(XMLHelper::getAttrString(e, nullptr, attributeID)),
- m_value(e ? xmltooling::toUTF8(e->getAttributeNS(nullptr,value)) : nullptr),
+ m_value(e ? toUTF8(e->getAttributeNS(nullptr, value)) : nullptr),
m_ignoreCase(XMLHelper::getAttrBool(e, false, ignoreCase)) {
- if (!m_value || !*m_value) {
- delete[] m_value;
+ if (!m_value.get() || !*m_value.get()) {
throw ConfigurationException("AttributeScopeString MatchFunctor requires non-empty value attribute.");
}
}
- virtual ~AttributeScopeStringFunctor() {
- delete[] m_value;
- }
+ virtual ~AttributeScopeStringFunctor() {}
bool evaluatePolicyRequirement(const FilteringContext& filterContext) const {
if (m_attributeID.empty())
bool evaluatePermitValue(const FilteringContext& filterContext, const Attribute& attribute, size_t index) const {
if (m_attributeID.empty() || m_attributeID == attribute.getId()) {
- if (m_ignoreCase) {
+ const char* scope = attribute.getScope(index);
+ if (!scope) {
+ return false;
+ }
+ else if (m_ignoreCase) {
#ifdef HAVE_STRCASECMP
- return !strcasecmp(attribute.getScope(index), m_value);
+ return !strcasecmp(scope, m_value.get());
#else
- return !stricmp(attribute.getScope(index), m_value);
+ return !stricmp(scope, m_value.get());
#endif
}
- else
- return !strcmp(attribute.getScope(index), m_value);
+ else {
+ return !strcmp(scope, m_value.get());
+ }
}
return hasScope(filterContext);
}
};
- MatchFunctor* SHIBSP_DLLLOCAL AttributeScopeStringFactory(const std::pair<const FilterPolicyContext*,const DOMElement*>& p)
+ MatchFunctor* SHIBSP_DLLLOCAL AttributeScopeStringFactory(const pair<const FilterPolicyContext*,const DOMElement*>& p)
{
return new AttributeScopeStringFunctor(p.second);
}
bool AttributeScopeStringFunctor::hasScope(const FilteringContext& filterContext) const
{
size_t count;
+ const char* scope;
pair<multimap<string,Attribute*>::const_iterator,multimap<string,Attribute*>::const_iterator> attrs =
filterContext.getAttributes().equal_range(m_attributeID);
for (; attrs.first != attrs.second; ++attrs.first) {
count = attrs.first->second->valueCount();
for (size_t index = 0; index < count; ++index) {
- if (m_ignoreCase) {
+ scope = attrs.first->second->getScope(index);
+ if (!scope) {
+ return false;
+ }
+ else if (m_ignoreCase) {
#ifdef HAVE_STRCASECMP
- if (!strcasecmp(attrs.first->second->getScope(index), m_value))
+ if (!strcasecmp(scope, m_value.get()))
return true;
#else
- if (!stricmp(attrs.first->second->getScope(index), m_value))
+ if (!stricmp(scope, m_value.get()))
return true;
#endif
}
else {
- if (!strcmp(attrs.first->second->getScope(index), m_value))
+ if (!strcmp(scope, m_value.get()))
return true;
}
}
#include "attribute/filtering/FilterPolicyContext.h"
#include "attribute/filtering/MatchFunctor.h"
+#include <boost/scoped_ptr.hpp>
#include <xmltooling/util/XMLHelper.h>
-
#include <xercesc/util/regx/RegularExpression.hpp>
using namespace shibsp;
+using namespace xmltooling;
+using namespace boost;
using namespace std;
-using xmltooling::XMLHelper;
namespace shibsp {
class SHIBSP_DLLLOCAL AttributeValueRegexFunctor : public MatchFunctor
{
string m_attributeID;
- RegularExpression* m_regex;
+ scoped_ptr<RegularExpression> m_regex;
bool hasValue(const FilteringContext& filterContext) const;
bool matches(const Attribute& attribute, size_t index) const;
public:
AttributeValueRegexFunctor(const DOMElement* e)
- : m_attributeID(XMLHelper::getAttrString(e, nullptr, attributeID)), m_regex(nullptr) {
- const XMLCh* r = e ? e->getAttributeNS(nullptr,regex) : nullptr;
+ : m_attributeID(XMLHelper::getAttrString(e, nullptr, attributeID)) {
+ const XMLCh* r = e ? e->getAttributeNS(nullptr, regex) : nullptr;
if (!r || !*r)
throw ConfigurationException("AttributeValueRegex MatchFunctor requires non-empty regex attribute.");
try {
- m_regex = new RegularExpression(r, e->getAttributeNS(nullptr,options));
+ m_regex.reset(new RegularExpression(r, e->getAttributeNS(nullptr, options)));
}
catch (XMLException& ex) {
xmltooling::auto_ptr_char temp(ex.getMessage());
}
}
- virtual ~AttributeValueRegexFunctor() {
- delete m_regex;
- }
+ virtual ~AttributeValueRegexFunctor() {}
bool evaluatePolicyRequirement(const FilteringContext& filterContext) const {
if (m_attributeID.empty())
}
};
- MatchFunctor* SHIBSP_DLLLOCAL AttributeValueRegexFactory(const std::pair<const FilterPolicyContext*,const DOMElement*>& p)
+ MatchFunctor* SHIBSP_DLLLOCAL AttributeValueRegexFactory(const pair<const FilterPolicyContext*,const DOMElement*>& p)
{
return new AttributeValueRegexFunctor(p.second);
}
const char* val = attribute.getString(index);
if (!val)
return false;
- XMLCh* temp = xmltooling::fromUTF8(val);
- bool ret = m_regex->matches(temp);
- delete[] temp;
- return ret;
+ auto_arrayptr<XMLCh> temp(fromUTF8(val));
+ return m_regex->matches(temp.get());
}
#include <xmltooling/util/XMLHelper.h>
using namespace shibsp;
+using namespace xmltooling;
using namespace std;
-using xmltooling::XMLHelper;
namespace shibsp {
class SHIBSP_DLLLOCAL AttributeValueStringFunctor : public MatchFunctor
{
string m_attributeID;
- char* m_value;
+ auto_arrayptr<char> m_value;
bool hasValue(const FilteringContext& filterContext) const;
bool matches(const Attribute& attribute, size_t index) const;
public:
AttributeValueStringFunctor(const DOMElement* e)
: m_attributeID(XMLHelper::getAttrString(e, nullptr, attributeID)),
- m_value(e ? xmltooling::toUTF8(e->getAttributeNS(nullptr,value)) : nullptr) {
- if (!m_value || !*m_value) {
- delete[] m_value;
+ m_value(e ? toUTF8(e->getAttributeNS(nullptr, value)) : nullptr) {
+ if (!m_value.get() || !*m_value.get()) {
throw ConfigurationException("AttributeValueString MatchFunctor requires non-empty value attribute.");
}
- if (e && e->hasAttributeNS(nullptr,ignoreCase)) {
- xmltooling::logging::Category::getInstance(SHIBSP_LOGCAT".AttributeFilter").warn(
+ if (e && e->hasAttributeNS(nullptr, ignoreCase)) {
+ Category::getInstance(SHIBSP_LOGCAT".AttributeFilter").warn(
"ignoreCase property ignored by AttributeValueString MatchFunctor in favor of attribute's caseSensitive property"
);
}
}
- virtual ~AttributeValueStringFunctor() {
- delete[] m_value;
- }
+ virtual ~AttributeValueStringFunctor() {}
bool evaluatePolicyRequirement(const FilteringContext& filterContext) const {
if (m_attributeID.empty())
}
};
- MatchFunctor* SHIBSP_DLLLOCAL AttributeValueStringFactory(const std::pair<const FilterPolicyContext*,const DOMElement*>& p)
+ MatchFunctor* SHIBSP_DLLLOCAL AttributeValueStringFactory(const pair<const FilterPolicyContext*,const DOMElement*>& p)
{
return new AttributeValueStringFunctor(p.second);
}
if (!val)
return false;
if (attribute.isCaseSensitive())
- return !strcmp(m_value, val);
+ return !strcmp(m_value.get(), val);
#ifdef HAVE_STRCASECMP
- return !strcasecmp(m_value, val);
+ return !strcasecmp(m_value.get(), val);
#else
- return !stricmp(m_value, val);
+ return !stricmp(m_value.get(), val);
#endif
}
#include "attribute/filtering/FilterPolicyContext.h"
#include "attribute/filtering/MatchFunctor.h"
+#include <boost/scoped_ptr.hpp>
#include <xercesc/util/regx/RegularExpression.hpp>
namespace shibsp {
*/
class SHIBSP_DLLLOCAL AuthenticationMethodRegexFunctor : public MatchFunctor
{
- RegularExpression* m_regex;
+ boost::scoped_ptr<RegularExpression> m_regex;
public:
- AuthenticationMethodRegexFunctor(const DOMElement* e) : m_regex(nullptr) {
- const XMLCh* r = e ? e->getAttributeNS(nullptr,regex) : nullptr;
+ AuthenticationMethodRegexFunctor(const DOMElement* e) {
+ const XMLCh* r = e ? e->getAttributeNS(nullptr, regex) : nullptr;
if (!r || !*r)
throw ConfigurationException("AuthenticationMethodRegex MatchFunctor requires non-empty regex attribute.");
try {
- m_regex = new RegularExpression(r, e->getAttributeNS(nullptr,options));
+ m_regex.reset(new RegularExpression(r, e->getAttributeNS(nullptr, options)));
}
catch (XMLException& ex) {
xmltooling::auto_ptr_char temp(ex.getMessage());
}
}
- virtual ~AuthenticationMethodRegexFunctor() {
- delete m_regex;
- }
+ virtual ~AuthenticationMethodRegexFunctor() {}
bool evaluatePolicyRequirement(const FilteringContext& filterContext) const {
return (m_regex->matches(filterContext.getAuthnContextClassRef()) || m_regex->matches(filterContext.getAuthnContextDeclRef()));
#include "attribute/filtering/AttributeFilter.h"
#include "attribute/filtering/FilteringContext.h"
+#include <boost/ptr_container/ptr_vector.hpp>
#include <xercesc/util/XMLUniDefs.hpp>
#include <xmltooling/util/XMLHelper.h>
using namespace shibsp;
using namespace xmltooling;
+using namespace boost;
using namespace std;
namespace shibsp {
{
public:
ChainingAttributeFilter(const DOMElement* e);
- virtual ~ChainingAttributeFilter() {
- for_each(m_filters.begin(), m_filters.end(), xmltooling::cleanup<AttributeFilter>());
- }
+ virtual ~ChainingAttributeFilter() {}
Lockable* lock() {
return this;
}
void filterAttributes(const FilteringContext& context, vector<Attribute*>& attributes) const {
- for (vector<AttributeFilter*>::const_iterator i=m_filters.begin(); i!=m_filters.end(); ++i) {
- Locker locker(*i);
- (*i)->filterAttributes(context, attributes);
+ for (ptr_vector<AttributeFilter>::iterator i = m_filters.begin(); i != m_filters.end(); ++i) {
+ Locker locker(&(*i));
+ i->filterAttributes(context, attributes);
}
}
private:
- vector<AttributeFilter*> m_filters;
+ mutable ptr_vector<AttributeFilter> m_filters;
};
static const XMLCh _AttributeFilter[] = UNICODE_LITERAL_15(A,t,t,r,i,b,u,t,e,F,i,l,t,e,r);
ChainingAttributeFilter::ChainingAttributeFilter(const DOMElement* e)
{
// Load up the chain of handlers.
- try {
- e = XMLHelper::getFirstChildElement(e, _AttributeFilter);
- while (e) {
- string t(XMLHelper::getAttrString(e, nullptr, _type));
- if (!t.empty()) {
- Category::getInstance(SHIBSP_LOGCAT".AttributeFilter.Chaining").info("building AttributeFilter of type (%s)...", t.c_str());
- m_filters.push_back(SPConfig::getConfig().AttributeFilterManager.newPlugin(t.c_str(), e));
- }
- e = XMLHelper::getNextSiblingElement(e, _AttributeFilter);
+ e = XMLHelper::getFirstChildElement(e, _AttributeFilter);
+ while (e) {
+ string t(XMLHelper::getAttrString(e, nullptr, _type));
+ if (!t.empty()) {
+ Category::getInstance(SHIBSP_LOGCAT".AttributeFilter.Chaining").info("building AttributeFilter of type (%s)...", t.c_str());
+ auto_ptr<AttributeFilter> np(SPConfig::getConfig().AttributeFilterManager.newPlugin(t.c_str(), e));
+ m_filters.push_back(np);
}
- }
- catch (exception&) {
- for_each(m_filters.begin(), m_filters.end(), xmltooling::cleanup<AttributeFilter>());
- throw;
+ e = XMLHelper::getNextSiblingElement(e, _AttributeFilter);
}
if (m_filters.empty())
throw ConfigurationException("Chaining AttributeFilter plugin requires at least one child plugin.");
#include "attribute/filtering/MatchFunctor.h"
#include "util/SPConstants.h"
+#include <boost/scoped_ptr.hpp>
#include <xercesc/util/XMLUniDefs.hpp>
#include <xmltooling/util/XMLHelper.h>
using namespace shibsp;
using namespace xmltooling;
+using namespace boost;
using namespace std;
namespace shibsp {
if (!id.empty() && functorMap->getMatchFunctors().count(id))
id.clear();
- auto_ptr<xmltooling::QName> type(XMLHelper::getXSIType(e));
- if (!type.get())
+ scoped_ptr<xmltooling::QName> type(XMLHelper::getXSIType(e));
+ if (!type)
throw ConfigurationException("Child Rule found with no xsi:type.");
- 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();
}
#include "attribute/filtering/MatchFunctor.h"
#include "util/SPConstants.h"
+#include <boost/scoped_ptr.hpp>
+#include <boost/lambda/bind.hpp>
+#include <boost/lambda/lambda.hpp>
#include <xercesc/util/XMLUniDefs.hpp>
#include <xmltooling/util/XMLHelper.h>
using namespace shibsp;
using namespace xmltooling;
+using namespace boost::lambda;
+using namespace boost;
using namespace std;
namespace shibsp {
OrMatchFunctor(const pair<const FilterPolicyContext*,const DOMElement*>& p);
bool evaluatePolicyRequirement(const FilteringContext& filterContext) const {
- for (vector<const MatchFunctor*>::const_iterator mf = m_functors.begin(); mf!=m_functors.end(); ++mf)
- if ((*mf)->evaluatePolicyRequirement(filterContext))
- return true;
- return false;
+ vector<const MatchFunctor*>::const_iterator i = find_if(
+ m_functors.begin(), m_functors.end(),
+ lambda::bind(&MatchFunctor::evaluatePolicyRequirement, _1, boost::ref(filterContext)) == true
+ );
+ return (i != m_functors.end());
}
bool evaluatePermitValue(const FilteringContext& filterContext, const Attribute& attribute, size_t index) const {
- for (vector<const MatchFunctor*>::const_iterator mf = m_functors.begin(); mf!=m_functors.end(); ++mf)
- if ((*mf)->evaluatePermitValue(filterContext, attribute, index))
- return true;
- return false;
+ vector<const MatchFunctor*>::const_iterator i = find_if(
+ m_functors.begin(), m_functors.end(),
+ lambda::bind(&MatchFunctor::evaluatePermitValue, _1, boost::ref(filterContext), boost::ref(attribute), index) == true
+ );
+ return (i != m_functors.end());
}
private:
if (!id.empty() && functorMap->getMatchFunctors().count(id))
id.clear();
- auto_ptr<xmltooling::QName> type(XMLHelper::getXSIType(e));
- if (!type.get())
+ scoped_ptr<xmltooling::QName> type(XMLHelper::getXSIType(e));
+ if (!type)
throw ConfigurationException("Child Rule found with no xsi:type.");
- 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();
}
#include "attribute/filtering/MatchFunctor.h"
#include "util/SPConstants.h"
+#include <boost/scoped_ptr.hpp>
+#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);
}
if (!m_issuer.empty()) {
const Issuer* i = saml2assertion->getIssuer();
if (i && (!i->getFormat() || !*(i->getFormat()) || XMLString::equals(i->getFormat(), NameIDType::ENTITY))) {
- auto_ptr<SimpleAttribute> issuer(new SimpleAttribute(vector<string>(1, m_issuer)));
auto_ptr_char temp(i->getName());
if (temp.get()) {
+ auto_ptr<SimpleAttribute> issuer(new SimpleAttribute(vector<string>(1, m_issuer)));
issuer->getValues().push_back(temp.get());
- attributes.push_back(issuer.release());
+ attributes.push_back(issuer.get());
+ issuer.release();
}
}
}
// NotOnOrAfter
if (!m_notOnOrAfter.empty() && saml2assertion->getConditions() && saml2assertion->getConditions()->getNotOnOrAfter()) {
- auto_ptr<SimpleAttribute> notonorafter(new SimpleAttribute(vector<string>(1, m_notOnOrAfter)));
auto_ptr_char temp(saml2assertion->getConditions()->getNotOnOrAfter()->getRawData());
if (temp.get()) {
+ auto_ptr<SimpleAttribute> notonorafter(new SimpleAttribute(vector<string>(1, m_notOnOrAfter)));
notonorafter->getValues().push_back(temp.get());
- attributes.push_back(notonorafter.release());
+ attributes.push_back(notonorafter.get());
+ notonorafter.release();
}
}
}
if (saml2statement) {
// AuthnInstant
if (!m_authnInstant.empty() && saml2statement->getAuthnInstant()) {
- auto_ptr<SimpleAttribute> authninstant(new SimpleAttribute(vector<string>(1, m_authnInstant)));
auto_ptr_char temp(saml2statement->getAuthnInstant()->getRawData());
if (temp.get()) {
+ auto_ptr<SimpleAttribute> authninstant(new SimpleAttribute(vector<string>(1, m_authnInstant)));
authninstant->getValues().push_back(temp.get());
- attributes.push_back(authninstant.release());
+ attributes.push_back(authninstant.get());
+ authninstant.release();
}
}
// SessionIndex
if (!m_sessionIndex.empty() && saml2statement->getSessionIndex() && *(saml2statement->getSessionIndex())) {
- auto_ptr<SimpleAttribute> sessionindex(new SimpleAttribute(vector<string>(1, m_sessionIndex)));
auto_ptr_char temp(saml2statement->getSessionIndex());
if (temp.get()) {
+ auto_ptr<SimpleAttribute> sessionindex(new SimpleAttribute(vector<string>(1, m_sessionIndex)));
sessionindex->getValues().push_back(temp.get());
- attributes.push_back(sessionindex.release());
+ attributes.push_back(sessionindex.get());
+ sessionindex.release();
}
}
// SessionNotOnOrAfter
if (!m_sessionNotOnOrAfter.empty() && saml2statement->getSessionNotOnOrAfter()) {
- auto_ptr<SimpleAttribute> sessionnotonorafter(new SimpleAttribute(vector<string>(1, m_sessionNotOnOrAfter)));
auto_ptr_char temp(saml2statement->getSessionNotOnOrAfter()->getRawData());
if (temp.get()) {
+ auto_ptr<SimpleAttribute> sessionnotonorafter(new SimpleAttribute(vector<string>(1, m_sessionNotOnOrAfter)));
sessionnotonorafter->getValues().push_back(temp.get());
- attributes.push_back(sessionnotonorafter.release());
+ attributes.push_back(sessionnotonorafter.get());
+ sessionnotonorafter.release();
}
}
const saml2::SubjectLocality* locality = saml2statement->getSubjectLocality();
// Address
if (!m_subjectAddress.empty() && locality->getAddress() && *(locality->getAddress())) {
- auto_ptr<SimpleAttribute> address(new SimpleAttribute(vector<string>(1, m_subjectAddress)));
auto_ptr_char temp(locality->getAddress());
if (temp.get()) {
+ auto_ptr<SimpleAttribute> address(new SimpleAttribute(vector<string>(1, m_subjectAddress)));
address->getValues().push_back(temp.get());
- attributes.push_back(address.release());
+ attributes.push_back(address.get());
+ address.release();
}
}
// DNSName
if (!m_subjectDNS.empty() && locality->getDNSName() && *(locality->getDNSName())) {
- auto_ptr<SimpleAttribute> dns(new SimpleAttribute(vector<string>(1, m_subjectDNS)));
auto_ptr_char temp(locality->getDNSName());
if (temp.get()) {
+ auto_ptr<SimpleAttribute> dns(new SimpleAttribute(vector<string>(1, m_subjectDNS)));
dns->getValues().push_back(temp.get());
- attributes.push_back(dns.release());
+ attributes.push_back(dns.get());
+ dns.release();
}
}
}
const AuthnContext* ac = saml2statement->getAuthnContext();
// AuthnContextClassRef
if (!m_authnClass.empty() && ac->getAuthnContextClassRef() && ac->getAuthnContextClassRef()->getReference()) {
- auto_ptr<SimpleAttribute> classref(new SimpleAttribute(vector<string>(1, m_authnClass)));
auto_ptr_char temp(ac->getAuthnContextClassRef()->getReference());
if (temp.get()) {
+ auto_ptr<SimpleAttribute> classref(new SimpleAttribute(vector<string>(1, m_authnClass)));
classref->getValues().push_back(temp.get());
- attributes.push_back(classref.release());
+ attributes.push_back(classref.get());
+ classref.release();
}
}
// AuthnContextDeclRef
if (!m_authnDecl.empty() && ac->getAuthnContextDeclRef() && ac->getAuthnContextDeclRef()->getReference()) {
- auto_ptr<SimpleAttribute> declref(new SimpleAttribute(vector<string>(1, m_authnDecl)));
auto_ptr_char temp(ac->getAuthnContextDeclRef()->getReference());
if (temp.get()) {
+ auto_ptr<SimpleAttribute> declref(new SimpleAttribute(vector<string>(1, m_authnDecl)));
declref->getValues().push_back(temp.get());
- attributes.push_back(declref.release());
+ attributes.push_back(declref.get());
+ declref.release();
}
}
attr->getValues().push_back(temp.get());
}
if (attr->valueCount() > 0) {
- attributes.push_back(attr.release());
+ attributes.push_back(attr.get());
+ attr.release();
}
}
}
// Issuer
if (!m_issuer.empty()) {
if (saml1assertion->getIssuer() && *(saml1assertion->getIssuer())) {
- auto_ptr<SimpleAttribute> issuer(new SimpleAttribute(vector<string>(1, m_issuer)));
auto_ptr_char temp(saml1assertion->getIssuer());
if (temp.get()) {
+ auto_ptr<SimpleAttribute> issuer(new SimpleAttribute(vector<string>(1, m_issuer)));
issuer->getValues().push_back(temp.get());
- attributes.push_back(issuer.release());
+ attributes.push_back(issuer.get());
+ issuer.release();
}
}
}
// NotOnOrAfter
if (!m_notOnOrAfter.empty() && saml1assertion->getConditions() && saml1assertion->getConditions()->getNotOnOrAfter()) {
- auto_ptr<SimpleAttribute> notonorafter(new SimpleAttribute(vector<string>(1, m_notOnOrAfter)));
auto_ptr_char temp(saml1assertion->getConditions()->getNotOnOrAfter()->getRawData());
if (temp.get()) {
+ auto_ptr<SimpleAttribute> notonorafter(new SimpleAttribute(vector<string>(1, m_notOnOrAfter)));
notonorafter->getValues().push_back(temp.get());
- attributes.push_back(notonorafter.release());
+ attributes.push_back(notonorafter.get());
+ notonorafter.release();
}
}
}
if (saml1statement) {
// AuthnInstant
if (!m_authnInstant.empty() && saml1statement->getAuthenticationInstant()) {
- auto_ptr<SimpleAttribute> authninstant(new SimpleAttribute(vector<string>(1, m_authnInstant)));
auto_ptr_char temp(saml1statement->getAuthenticationInstant()->getRawData());
if (temp.get()) {
+ auto_ptr<SimpleAttribute> authninstant(new SimpleAttribute(vector<string>(1, m_authnInstant)));
authninstant->getValues().push_back(temp.get());
- attributes.push_back(authninstant.release());
+ attributes.push_back(authninstant.get());
+ authninstant.release();
}
}
// AuthenticationMethod
if (!m_authnClass.empty() && saml1statement->getAuthenticationMethod() && *(saml1statement->getAuthenticationMethod())) {
- auto_ptr<SimpleAttribute> authnmethod(new SimpleAttribute(vector<string>(1, m_authnClass)));
auto_ptr_char temp(saml1statement->getAuthenticationMethod());
if (temp.get()) {
+ auto_ptr<SimpleAttribute> authnmethod(new SimpleAttribute(vector<string>(1, m_authnClass)));
authnmethod->getValues().push_back(temp.get());
- attributes.push_back(authnmethod.release());
+ attributes.push_back(authnmethod.get());
+ authnmethod.release();
}
}
const saml1::SubjectLocality* locality = saml1statement->getSubjectLocality();
// IPAddress
if (!m_subjectAddress.empty() && locality->getIPAddress() && *(locality->getIPAddress())) {
- auto_ptr<SimpleAttribute> address(new SimpleAttribute(vector<string>(1, m_subjectAddress)));
auto_ptr_char temp(locality->getIPAddress());
if (temp.get()) {
+ auto_ptr<SimpleAttribute> address(new SimpleAttribute(vector<string>(1, m_subjectAddress)));
address->getValues().push_back(temp.get());
- attributes.push_back(address.release());
+ attributes.push_back(address.get());
+ address.release();
}
}
// DNSAddress
if (!m_subjectDNS.empty() && locality->getDNSAddress() && *(locality->getDNSAddress())) {
- auto_ptr<SimpleAttribute> dns(new SimpleAttribute(vector<string>(1, m_subjectDNS)));
auto_ptr_char temp(locality->getDNSAddress());
if (temp.get()) {
+ auto_ptr<SimpleAttribute> dns(new SimpleAttribute(vector<string>(1, m_subjectDNS)));
dns->getValues().push_back(temp.get());
- attributes.push_back(dns.release());
+ attributes.push_back(dns.get());
+ dns.release();
}
}
}
#include "attribute/Attribute.h"
#include "attribute/resolver/AttributeExtractor.h"
+#include <boost/ptr_container/ptr_vector.hpp>
#include <xercesc/util/XMLUniDefs.hpp>
#include <xmltooling/util/XMLHelper.h>
using namespace shibsp;
using namespace opensaml::saml2md;
using namespace xmltooling;
+using namespace boost;
using namespace std;
namespace shibsp {
{
public:
ChainingAttributeExtractor(const DOMElement* e);
- virtual ~ChainingAttributeExtractor() {
- for_each(m_extractors.begin(), m_extractors.end(), xmltooling::cleanup<AttributeExtractor>());
- }
+ virtual ~ChainingAttributeExtractor() {}
Lockable* lock() {
return this;
const RoleDescriptor* issuer,
const XMLObject& xmlObject,
vector<Attribute*>& attributes
- ) const;
+ ) const {
+ for (ptr_vector<AttributeExtractor>::iterator i = m_extractors.begin(); i != m_extractors.end(); ++i) {
+ Locker locker(&(*i));
+ i->extractAttributes(application, issuer, xmlObject, attributes);
+ }
+ }
void getAttributeIds(vector<string>& attributes) const {
- for (vector<AttributeExtractor*>::const_iterator i=m_extractors.begin(); i!=m_extractors.end(); ++i) {
- Locker locker(*i);
- (*i)->getAttributeIds(attributes);
+ for (ptr_vector<AttributeExtractor>::iterator i = m_extractors.begin(); i != m_extractors.end(); ++i) {
+ Locker locker(&(*i));
+ i->getAttributeIds(attributes);
}
}
void generateMetadata(SPSSODescriptor& role) const {
- for (vector<AttributeExtractor*>::const_iterator i=m_extractors.begin(); i!=m_extractors.end(); ++i) {
- Locker locker(*i);
- (*i)->generateMetadata(role);
+ for (ptr_vector<AttributeExtractor>::iterator i = m_extractors.begin(); i != m_extractors.end(); ++i) {
+ Locker locker(&(*i));
+ i->generateMetadata(role);
}
}
private:
- vector<AttributeExtractor*> m_extractors;
+ mutable ptr_vector<AttributeExtractor> m_extractors;
};
static const XMLCh _AttributeExtractor[] = UNICODE_LITERAL_18(A,t,t,r,i,b,u,t,e,E,x,t,r,a,c,t,o,r);
Category::getInstance(SHIBSP_LOGCAT".AttributeExtractor.Chaining").info(
"building AttributeExtractor of type (%s)...", t.c_str()
);
- m_extractors.push_back(conf.AttributeExtractorManager.newPlugin(t.c_str(), e));
+ auto_ptr<AttributeExtractor> np(conf.AttributeExtractorManager.newPlugin(t.c_str(), e));
+ m_extractors.push_back(np);
}
catch (exception& ex) {
Category::getInstance(SHIBSP_LOGCAT".AttributeExtractor.Chaining").error(
e = XMLHelper::getNextSiblingElement(e, _AttributeExtractor);
}
}
-
-void ChainingAttributeExtractor::extractAttributes(
- const Application& application, const RoleDescriptor* issuer, const XMLObject& xmlObject, vector<Attribute*>& attributes
- ) const
-{
- for (vector<AttributeExtractor*>::const_iterator i=m_extractors.begin(); i!=m_extractors.end(); ++i) {
- Locker locker(*i);
- (*i)->extractAttributes(application, issuer, xmlObject, attributes);
- }
-}
#include "attribute/resolver/AttributeResolver.h"
#include "attribute/resolver/ResolutionContext.h"
-#include <saml/Assertion.h>
+#include <boost/scoped_ptr.hpp>
+#include <boost/ptr_container/ptr_vector.hpp>
#include <xercesc/util/XMLUniDefs.hpp>
+#include <saml/Assertion.h>
#include <xmltooling/util/XMLHelper.h>
using namespace shibsp;
using namespace opensaml::saml2;
using namespace opensaml::saml2md;
using namespace xmltooling;
+using namespace boost;
using namespace std;
namespace shibsp {
{
public:
ChainingAttributeResolver(const DOMElement* e);
- virtual ~ChainingAttributeResolver() {
- for_each(m_resolvers.begin(), m_resolvers.end(), xmltooling::cleanup<AttributeResolver>());
- }
+ virtual ~ChainingAttributeResolver() {}
Lockable* lock() {
return this;
void resolveAttributes(ResolutionContext& ctx) const;
void getAttributeIds(vector<string>& attributes) const {
- for (vector<AttributeResolver*>::const_iterator i=m_resolvers.begin(); i!=m_resolvers.end(); ++i) {
- Locker locker(*i);
- (*i)->getAttributeIds(attributes);
+ for (ptr_vector<AttributeResolver>::iterator i = m_resolvers.begin(); i != m_resolvers.end(); ++i) {
+ Locker locker(&(*i));
+ i->getAttributeIds(attributes);
}
}
private:
- vector<AttributeResolver*> m_resolvers;
+ mutable ptr_vector<AttributeResolver> m_resolvers;
};
static const XMLCh _AttributeResolver[] = UNICODE_LITERAL_17(A,t,t,r,i,b,u,t,e,R,e,s,o,l,v,e,r);
Category::getInstance(SHIBSP_LOGCAT".AttributeResolver.Chaining").info(
"building AttributeResolver of type (%s)...", t.c_str()
);
- m_resolvers.push_back(conf.AttributeResolverManager.newPlugin(t.c_str(), e));
+ auto_ptr<AttributeResolver> np(conf.AttributeResolverManager.newPlugin(t.c_str(), e));
+ m_resolvers.push_back(np);
}
catch (exception& ex) {
Category::getInstance(SHIBSP_LOGCAT".AttributeResolver.Chaining").error(
void ChainingAttributeResolver::resolveAttributes(ResolutionContext& ctx) const
{
ChainingContext& chain = dynamic_cast<ChainingContext&>(ctx);
- for (vector<AttributeResolver*>::const_iterator i=m_resolvers.begin(); i!=m_resolvers.end(); ++i) {
- Locker locker(*i);
- auto_ptr<ResolutionContext> context(
+ for (ptr_vector<AttributeResolver>::iterator i = m_resolvers.begin(); i != m_resolvers.end(); ++i) {
+ Locker locker(&(*i));
+ scoped_ptr<ResolutionContext> context(
chain.m_session ?
- (*i)->createResolutionContext(chain.m_app, *chain.m_session) :
- (*i)->createResolutionContext(
+ i->createResolutionContext(chain.m_app, *chain.m_session) :
+ i->createResolutionContext(
chain.m_app, chain.m_issuer, chain.m_protocol, chain.m_nameid, chain.m_authclass, chain.m_authdecl, &chain.m_tokens, &chain.m_attributes
)
);
- (*i)->resolveAttributes(*context.get());
+ i->resolveAttributes(*context);
chain.m_attributes.insert(chain.m_attributes.end(), context->getResolvedAttributes().begin(), context->getResolvedAttributes().end());
chain.m_ownedAttributes.insert(chain.m_ownedAttributes.end(), context->getResolvedAttributes().begin(), context->getResolvedAttributes().end());
#include "attribute/resolver/AttributeExtractor.h"
#include "util/SPConstants.h"
+#include <boost/shared_ptr.hpp>
+#include <boost/iterator/indirect_iterator.hpp>
#include <saml/saml2/core/Assertions.h>
#include <saml/saml2/metadata/Metadata.h>
#include <saml/saml2/metadata/MetadataCredentialCriteria.h>
using namespace opensaml::saml2md;
using namespace opensaml;
using namespace xmltooling;
+using namespace boost;
using namespace std;
namespace shibsp {
auto_ptr<ExtensibleAttribute> attr(new ExtensibleAttribute(vector<string>(1,m_attributeId), m_formatter.c_str()));
const vector<saml2::Delegate*>& dels = drt->getDelegates();
- for (vector<saml2::Delegate*>::const_iterator d = dels.begin(); d != dels.end(); ++d) {
- if ((*d)->getBaseID()) {
+ for (indirect_iterator<vector<saml2::Delegate*>::const_iterator> d = make_indirect_iterator(dels.begin());
+ d != make_indirect_iterator(dels.end()); ++d) {
+ if (d->getBaseID()) {
log.error("delegate identified by saml:BaseID cannot be processed into an attribute value");
continue;
}
saml2::NameID* n = nullptr;
- if ((*d)->getEncryptedID()) {
+ boost::shared_ptr<saml2::NameID> namewrapper;
+ if (d->getEncryptedID()) {
CredentialResolver* cr = application.getCredentialResolver();
if (!cr) {
log.warn("found encrypted Delegate, but no CredentialResolver was available");
Locker credlocker(cr);
if (issuer) {
MetadataCredentialCriteria mcc(*issuer);
- auto_ptr<XMLObject> decrypted((*d)->getEncryptedID()->decrypt(*cr, recipient, &mcc));
- n = dynamic_cast<saml2::NameID*>(decrypted.release());
+ boost::shared_ptr<XMLObject> decrypted(d->getEncryptedID()->decrypt(*cr, recipient, &mcc));
+ namewrapper = dynamic_pointer_cast<saml2::NameID>(decrypted);
+ n = namewrapper.get();
}
else {
- auto_ptr<XMLObject> decrypted((*d)->getEncryptedID()->decrypt(*cr, recipient));
- n = dynamic_cast<saml2::NameID*>(decrypted.release());
+ boost::shared_ptr<XMLObject> decrypted(d->getEncryptedID()->decrypt(*cr, recipient));
+ namewrapper = dynamic_pointer_cast<saml2::NameID>(decrypted);
+ n = namewrapper.get();
}
if (n && log.isDebugEnabled())
log.debugStream() << "decrypted Delegate: " << *n << logging::eol;
}
- catch (exception& ex) {
+ catch (std::exception& ex) {
log.error("caught exception decrypting Delegate: %s", ex.what());
}
}
else {
- n = (*d)->getNameID();
+ n = d->getNameID();
}
if (n) {
DDF val = DDF(nullptr).structure();
- if ((*d)->getConfirmationMethod()) {
- auto_ptr_char temp((*d)->getConfirmationMethod());
+ if (d->getConfirmationMethod()) {
+ auto_ptr_char temp(d->getConfirmationMethod());
val.addmember("ConfirmationMethod").string(temp.get());
}
- if ((*d)->getDelegationInstant()) {
- auto_ptr_char temp((*d)->getDelegationInstant()->getRawData());
+ if (d->getDelegationInstant()) {
+ auto_ptr_char temp(d->getDelegationInstant()->getRawData());
val.addmember("DelegationInstant").string(temp.get());
}
auto_arrayptr<char> name(toUTF8(n->getName()));
if (name.get() && *name.get()) {
val.addmember("Name").string(name.get());
- char* str = toUTF8(n->getFormat());
- if (str && *str)
- val.addmember("Format").string(str);
- delete[] str;
-
- str = toUTF8(n->getNameQualifier());
- if (str && *str)
- val.addmember("NameQualifier").string(str);
- delete[] str;
-
- str = toUTF8(n->getSPNameQualifier());
- if (str && *str)
- val.addmember("SPNameQualifier").string(str);
- delete[] str;
-
- str = toUTF8(n->getSPProvidedID());
- if (str && *str)
- val.addmember("SPProvidedID").string(str);
- delete[] str;
- }
+ auto_arrayptr<char> format(toUTF8(n->getFormat()));
+ if (format.get())
+ val.addmember("Format").string(format.get());
+
+ auto_arrayptr<char> nq(toUTF8(n->getNameQualifier()));
+ if (nq.get())
+ val.addmember("NameQualifier").string(nq.get());
- if (n != (*d)->getNameID())
- delete n;
+ auto_arrayptr<char> spnq(toUTF8(n->getSPNameQualifier()));
+ if (spnq.get())
+ val.addmember("SPNameQualifier").string(spnq.get());
+
+ auto_arrayptr<char> sppid(toUTF8(n->getSPProvidedID()));
+ if (sppid.get())
+ val.addmember("SPProvidedID").string(sppid.get());
+ }
if (val.integer())
attr->getValues().add(val);
}
}
- attributes.push_back(attr.release());
+ attributes.push_back(attr.get());
+ attr.release();
}
}
}
#include "attribute/SimpleAttribute.h"
#include "attribute/resolver/AttributeExtractor.h"
+#include <boost/iterator/indirect_iterator.hpp>
#include <saml/saml2/metadata/Metadata.h>
#include <saml/saml2/metadata/MetadataCredentialCriteria.h>
#include <saml/saml2/metadata/MetadataProvider.h>
using namespace opensaml::saml2md;
using namespace opensaml;
using namespace xmltooling;
+using namespace boost;
using namespace std;
namespace shibsp {
if (!m_hashId.empty()) {
auto_ptr<SimpleAttribute> attr(new SimpleAttribute(m_hashId));
vector<string>& vals = attr->getValues();
- for (vector<const Credential*>::const_iterator c = creds.begin(); c != creds.end(); ++c) {
+ for (indirect_iterator<vector<const Credential*>::const_iterator> c = make_indirect_iterator(creds.begin());
+ c != make_indirect_iterator(creds.end()); ++c) {
if (vals.empty() || !vals.back().empty())
vals.push_back(string());
- vals.back() = SecurityHelper::getDEREncoding(*(*c), m_hashAlg.c_str());
+ vals.back() = SecurityHelper::getDEREncoding(*c, m_hashAlg.c_str());
}
if (vals.back().empty())
vals.pop_back();
- if (!vals.empty())
- attributes.push_back(attr.release());
+ if (!vals.empty()) {
+ attributes.push_back(attr.get());
+ attr.release();
+ }
}
if (!m_signingId.empty()) {
auto_ptr<SimpleAttribute> attr(new SimpleAttribute(m_signingId));
vector<string>& vals = attr->getValues();
- for (vector<const Credential*>::const_iterator c = creds.begin(); c != creds.end(); ++c) {
+ for (indirect_iterator<vector<const Credential*>::const_iterator> c = make_indirect_iterator(creds.begin());
+ c != make_indirect_iterator(creds.end()); ++c) {
if (vals.empty() || !vals.back().empty())
vals.push_back(string());
- vals.back() = SecurityHelper::getDEREncoding(*(*c));
+ vals.back() = SecurityHelper::getDEREncoding(*c);
}
if (vals.back().empty())
vals.pop_back();
- if (!vals.empty())
- attributes.push_back(attr.release());
+ if (!vals.empty()) {
+ attributes.push_back(attr.get());
+ attr.release();
+ }
}
creds.clear();
}
if (application.getMetadataProvider()->resolve(creds, &mcc)) {
auto_ptr<SimpleAttribute> attr(new SimpleAttribute(m_encryptionId));
vector<string>& vals = attr->getValues();
- for (vector<const Credential*>::const_iterator c = creds.begin(); c != creds.end(); ++c) {
+ for (indirect_iterator<vector<const Credential*>::const_iterator> c = make_indirect_iterator(creds.begin());
+ c != make_indirect_iterator(creds.end()); ++c) {
if (vals.empty() || !vals.back().empty())
vals.push_back(string());
- vals.back() = SecurityHelper::getDEREncoding(*(*c));
+ vals.back() = SecurityHelper::getDEREncoding(*c);
}
if (vals.back().empty())
vals.pop_back();
- if (!vals.empty())
- attributes.push_back(attr.release());
+ if (!vals.empty()) {
+ attributes.push_back(attr.get());
+ attr.release();
+ }
}
}
}
#include "security/SecurityPolicyProvider.h"
#include "util/SPConstants.h"
+#include <boost/scoped_ptr.hpp>
+#include <boost/iterator/indirect_iterator.hpp>
+#include <boost/ptr_container/ptr_vector.hpp>
#include <saml/exceptions.h>
#include <saml/saml1/binding/SAML1SOAPClient.h>
#include <saml/saml1/core/Assertions.h>
using namespace opensaml::saml2md;
using namespace opensaml;
using namespace xmltooling;
+using namespace boost;
using namespace std;
namespace shibsp {
{
public:
QueryResolver(const DOMElement* e);
- ~QueryResolver() {
- for_each(m_SAML1Designators.begin(), m_SAML1Designators.end(), xmltooling::cleanup<AttributeDesignator>());
- for_each(m_SAML2Designators.begin(), m_SAML2Designators.end(), xmltooling::cleanup<saml2::Attribute>());
- }
+ ~QueryResolver() {}
Lockable* lock() {return this;}
void unlock() {}
Category& m_log;
string m_policyId;
bool m_subjectMatch;
- vector<AttributeDesignator*> m_SAML1Designators;
- vector<saml2::Attribute*> m_SAML2Designators;
+ ptr_vector<AttributeDesignator> m_SAML1Designators;
+ ptr_vector<saml2::Attribute> m_SAML2Designators;
vector<string> m_exceptionId;
};
const char* policyId = m_policyId.empty() ? application.getString("policyId").second : m_policyId.c_str();
// Set up policy and SOAP client.
- auto_ptr<SecurityPolicy> policy(
+ scoped_ptr<SecurityPolicy> policy(
application.getServiceProvider().getSecurityPolicyProvider()->createSecurityPolicy(application, nullptr, policyId)
);
policy->getAudiences().push_back(relyingParty->getXMLString("entityID").second);
MetadataCredentialCriteria mcc(*AA);
- shibsp::SOAPClient soaper(*policy.get());
+ shibsp::SOAPClient soaper(*policy);
auto_ptr_XMLCh binding(samlconstants::SAML1_BINDING_SOAP);
- saml1p::Response* response=nullptr;
+ auto_ptr<saml1p::Response> response;
const vector<AttributeService*>& endpoints=AA->getAttributeServices();
- for (vector<AttributeService*>::const_iterator ep=endpoints.begin(); !response && ep!=endpoints.end(); ++ep) {
- if (!XMLString::equals((*ep)->getBinding(),binding.get()) || !(*ep)->getLocation())
+ for (indirect_iterator<vector<AttributeService*>::const_iterator> ep = make_indirect_iterator(endpoints.begin());
+ !response.get() && ep != make_indirect_iterator(endpoints.end()); ++ep) {
+ if (!XMLString::equals(ep->getBinding(), binding.get()) || !ep->getLocation())
continue;
- auto_ptr_char loc((*ep)->getLocation());
+ auto_ptr_char loc(ep->getLocation());
try {
NameIdentifier* nameid = NameIdentifierBuilder::buildNameIdentifier();
nameid->setName(ctx.getNameID()->getName());
saml1p::AttributeQuery* query = saml1p::AttributeQueryBuilder::buildAttributeQuery();
query->setSubject(subject);
query->setResource(relyingParty->getXMLString("entityID").second);
- for (vector<AttributeDesignator*>::const_iterator ad = m_SAML1Designators.begin(); ad!=m_SAML1Designators.end(); ++ad)
- query->getAttributeDesignators().push_back((*ad)->cloneAttributeDesignator());
+ for (ptr_vector<AttributeDesignator>::const_iterator ad = m_SAML1Designators.begin(); ad != m_SAML1Designators.end(); ++ad) {
+ auto_ptr<AttributeDesignator> adwrapper(ad->cloneAttributeDesignator());
+ query->getAttributeDesignators().push_back(adwrapper.get());
+ adwrapper.release();
+ }
Request* request = RequestBuilder::buildRequest();
request->setAttributeQuery(query);
request->setMinorVersion(version);
SAML1SOAPClient client(soaper, false);
client.sendSAML(request, application.getId(), mcc, loc.get());
- response = client.receiveSAML();
+ response.reset(client.receiveSAML());
}
catch (exception& ex) {
m_log.error("exception during SAML query to %s: %s", loc.get(), ex.what());
}
}
- if (!response) {
+ if (!response.get()) {
m_log.error("unable to obtain a SAML response from attribute authority");
throw BindingException("Unable to obtain a SAML response from attribute authority.");
}
else if (!response->getStatus() || !response->getStatus()->getStatusCode() || response->getStatus()->getStatusCode()->getValue()==nullptr ||
*(response->getStatus()->getStatusCode()->getValue()) != saml1p::StatusCode::SUCCESS) {
- delete response;
m_log.error("attribute authority returned a SAML error");
throw FatalProfileException("Attribute authority returned a SAML error.");
}
- const vector<saml1::Assertion*>& assertions = const_cast<const saml1p::Response*>(response)->getAssertions();
+ const vector<saml1::Assertion*>& assertions = const_cast<const saml1p::Response*>(response.get())->getAssertions();
if (assertions.empty()) {
- delete response;
m_log.warn("response from attribute authority was empty");
return;
}
- else if (assertions.size()>1) {
+ else if (assertions.size() > 1) {
m_log.warn("simple resolver only supports one assertion in the query response");
}
- auto_ptr<saml1p::Response> wrapper(response);
saml1::Assertion* newtoken = assertions.front();
pair<bool,bool> signedAssertions = relyingParty->getBool("requireSignedAssertions");
}
newtoken->detach();
- wrapper.release(); // detach blows away the Response
+ response.release(); // detach blows away the Response
ctx.getResolvedAssertions().push_back(newtoken);
// Finally, extract and filter the result.
if (extractor) {
Locker extlocker(extractor);
const vector<saml1::AttributeStatement*>& statements = const_cast<const saml1::Assertion*>(newtoken)->getAttributeStatements();
- for (vector<saml1::AttributeStatement*>::const_iterator s = statements.begin(); s!=statements.end(); ++s) {
+ for (indirect_iterator<vector<saml1::AttributeStatement*>::const_iterator> s = make_indirect_iterator(statements.begin());
+ s != make_indirect_iterator(statements.end()); ++s) {
if (m_subjectMatch) {
// Check for subject match.
- const NameIdentifier* respName = (*s)->getSubject() ? (*s)->getSubject()->getNameIdentifier() : nullptr;
+ const NameIdentifier* respName = s->getSubject() ? s->getSubject()->getNameIdentifier() : nullptr;
if (!respName || !XMLString::equals(respName->getName(), ctx.getNameID()->getName()) ||
!XMLString::equals(respName->getFormat(), ctx.getNameID()->getFormat()) ||
!XMLString::equals(respName->getNameQualifier(), ctx.getNameID()->getNameQualifier())) {
continue;
}
}
- extractor->extractAttributes(application, AA, *(*s), ctx.getResolvedAttributes());
+ extractor->extractAttributes(application, AA, *s, ctx.getResolvedAttributes());
}
}
const char* policyId = m_policyId.empty() ? application.getString("policyId").second : m_policyId.c_str();
// Set up policy and SOAP client.
- auto_ptr<SecurityPolicy> policy(
+ scoped_ptr<SecurityPolicy> policy(
application.getServiceProvider().getSecurityPolicyProvider()->createSecurityPolicy(application, nullptr, policyId)
);
policy->getAudiences().push_back(relyingParty->getXMLString("entityID").second);
MetadataCredentialCriteria mcc(*AA);
- shibsp::SOAPClient soaper(*policy.get());
+ shibsp::SOAPClient soaper(*policy);
auto_ptr_XMLCh binding(samlconstants::SAML20_BINDING_SOAP);
- saml2p::StatusResponseType* srt=nullptr;
+ auto_ptr<saml2p::StatusResponseType> srt;
const vector<AttributeService*>& endpoints=AA->getAttributeServices();
- for (vector<AttributeService*>::const_iterator ep=endpoints.begin(); !srt && ep!=endpoints.end(); ++ep) {
- if (!XMLString::equals((*ep)->getBinding(),binding.get()) || !(*ep)->getLocation())
+ for (indirect_iterator<vector<AttributeService*>::const_iterator> ep = make_indirect_iterator(endpoints.begin());
+ !srt.get() && ep != make_indirect_iterator(endpoints.end()); ++ep) {
+ if (!XMLString::equals(ep->getBinding(), binding.get()) || !ep->getLocation())
continue;
- auto_ptr_char loc((*ep)->getLocation());
+ auto_ptr_char loc(ep->getLocation());
try {
auto_ptr<saml2::Subject> subject(saml2::SubjectBuilder::buildSubject());
false,
relyingParty->getXMLString("encryptionAlg").second
);
- subject->setEncryptedID(encrypted.release());
+ subject->setEncryptedID(encrypted.get());
+ encrypted.release();
}
else {
- subject->setNameID(ctx.getNameID()->cloneNameID());
+ auto_ptr<NameID> namewrapper(ctx.getNameID()->cloneNameID());
+ subject->setNameID(namewrapper.get());
+ namewrapper.release();
}
saml2p::AttributeQuery* query = saml2p::AttributeQueryBuilder::buildAttributeQuery();
Issuer* iss = IssuerBuilder::buildIssuer();
iss->setName(relyingParty->getXMLString("entityID").second);
query->setIssuer(iss);
- for (vector<saml2::Attribute*>::const_iterator ad = m_SAML2Designators.begin(); ad!=m_SAML2Designators.end(); ++ad)
- query->getAttributes().push_back((*ad)->cloneAttribute());
+ for (ptr_vector<saml2::Attribute>::const_iterator ad = m_SAML2Designators.begin(); ad != m_SAML2Designators.end(); ++ad) {
+ auto_ptr<saml2::Attribute> adwrapper(ad->cloneAttribute());
+ query->getAttributes().push_back(adwrapper.get());
+ adwrapper.release();
+ }
SAML2SOAPClient client(soaper, false);
client.sendSAML(query, application.getId(), mcc, loc.get());
- srt = client.receiveSAML();
+ srt.reset(client.receiveSAML());
}
catch (exception& ex) {
m_log.error("exception during SAML query to %s: %s", loc.get(), ex.what());
}
}
- if (!srt) {
+ if (!srt.get()) {
m_log.error("unable to obtain a SAML response from attribute authority");
throw BindingException("Unable to obtain a SAML response from attribute authority.");
}
- auto_ptr<saml2p::StatusResponseType> wrapper(srt);
-
- saml2p::Response* response = dynamic_cast<saml2p::Response*>(srt);
+ saml2p::Response* response = dynamic_cast<saml2p::Response*>(srt.get());
if (!response) {
m_log.error("message was not a samlp:Response");
throw FatalProfileException("Attribute authority returned an unrecognized message.");
}
saml2::Assertion* newtoken = nullptr;
+ auto_ptr<saml2::Assertion> newtokenwrapper;
const vector<saml2::Assertion*>& assertions = const_cast<const saml2p::Response*>(response)->getAssertions();
if (assertions.empty()) {
// Check for encryption.
newtoken = dynamic_cast<saml2::Assertion*>(tokenwrapper.get());
if (newtoken) {
tokenwrapper.release();
+ newtokenwrapper.reset(newtoken);
if (m_log.isDebugEnabled())
m_log.debugStream() << "decrypted Assertion: " << *newtoken << logging::eol;
- // Free the Response now, so we know this is a stand-alone token later.
- delete wrapper.release();
}
}
catch (exception& ex) {
if (!newtoken->getSignature() && signedAssertions.first && signedAssertions.second) {
m_log.error("assertion unsigned, rejecting it based on signedAssertions policy");
- if (!wrapper.get())
- delete newtoken;
throw SecurityPolicyException("Rejected unsigned assertion based on local policy.");
}
if (m_subjectMatch) {
// Check for subject match.
- bool ownedName = false;
+ auto_ptr<NameID> nameIDwrapper;
NameID* respName = newtoken->getSubject() ? newtoken->getSubject()->getNameID() : nullptr;
if (!respName) {
// Check for encryption.
auto_ptr<XMLObject> decryptedID(encname->decrypt(*cr, relyingParty->getXMLString("entityID").second, &mcc));
respName = dynamic_cast<NameID*>(decryptedID.get());
if (respName) {
- ownedName = true;
decryptedID.release();
+ nameIDwrapper.reset(respName);
if (m_log.isDebugEnabled())
m_log.debugStream() << "decrypted NameID: " << *respName << logging::eol;
}
}
}
- auto_ptr<NameID> nameIDwrapper(ownedName ? respName : nullptr);
-
if (!respName || !XMLString::equals(respName->getName(), ctx.getNameID()->getName()) ||
!XMLString::equals(respName->getFormat(), ctx.getNameID()->getFormat()) ||
!XMLString::equals(respName->getNameQualifier(), ctx.getNameID()->getNameQualifier()) ||
*respName << logging::eol;
else
m_log.warn("ignoring Assertion without NameID in Subject");
- if (!wrapper.get())
- delete newtoken;
return;
}
}
}
catch (exception& ex) {
m_log.error("assertion failed policy validation: %s", ex.what());
- if (!wrapper.get())
- delete newtoken;
throw;
}
- if (wrapper.get()) {
+ // If the token's embedded, detach it.
+ if (!newtokenwrapper.get()) {
newtoken->detach();
- wrapper.release(); // detach blows away the Response
+ srt.release(); // detach blows away the Response, so avoid a double free
+ newtokenwrapper.reset(newtoken);
}
ctx.getResolvedAssertions().push_back(newtoken);
+ newtokenwrapper.release();
// Finally, extract and filter the result.
try {
catch (exception& ex) {
// Already logged.
if (!m_exceptionId.empty()) {
- SimpleAttribute* attr = new SimpleAttribute(m_exceptionId);
+ auto_ptr<SimpleAttribute> attr(new SimpleAttribute(m_exceptionId));
attr->getValues().push_back(XMLToolingConfig::getConfig().getURLEncoder()->encode(ex.what()));
- qctx.getResolvedAttributes().push_back(attr);
+ qctx.getResolvedAttributes().push_back(attr.get());
+ attr.release();
}
}
}
#include "security/SecurityPolicyProvider.h"
#include "util/SPConstants.h"
+#include <boost/scoped_ptr.hpp>
+#include <boost/algorithm/string.hpp>
+#include <boost/iterator/indirect_iterator.hpp>
+#include <boost/ptr_container/ptr_vector.hpp>
#include <saml/exceptions.h>
#include <saml/SAMLConfig.h>
#include <saml/saml2/binding/SAML2SOAPClient.h>
using namespace opensaml::saml2md;
using namespace opensaml;
using namespace xmltooling;
+using namespace boost;
using namespace std;
namespace shibsp {
: m_app(application),
m_session(&session),
m_nameid(nullptr),
- m_entityid(nullptr),
- m_class(XMLString::transcode(session.getAuthnContextClassRef())),
- m_decl(XMLString::transcode(session.getAuthnContextDeclRef())),
+ m_class(session.getAuthnContextClassRef()),
+ m_decl(session.getAuthnContextDeclRef()),
m_inputTokens(nullptr),
m_inputAttributes(nullptr) {
}
) : m_app(application),
m_session(nullptr),
m_nameid(nameid),
- m_entityid(entityID ? XMLString::transcode(entityID) : nullptr),
- m_class(const_cast<XMLCh*>(authncontext_class)),
- m_decl(const_cast<XMLCh*>(authncontext_decl)),
+ m_entityid(entityID),
+ m_class(authncontext_class),
+ m_decl(authncontext_decl),
m_inputTokens(tokens),
m_inputAttributes(attributes) {
}
~SimpleAggregationContext() {
for_each(m_attributes.begin(), m_attributes.end(), xmltooling::cleanup<shibsp::Attribute>());
for_each(m_assertions.begin(), m_assertions.end(), xmltooling::cleanup<opensaml::Assertion>());
- if (m_session) {
- XMLString::release(&m_class);
- XMLString::release(&m_decl);
- }
- XMLString::release(&m_entityid);
}
const Application& getApplication() const {
return m_app;
}
const char* getEntityID() const {
- return m_session ? m_session->getEntityID() : m_entityid;
+ return m_session ? m_session->getEntityID() : m_entityid.get();
}
const NameID* getNameID() const {
return m_session ? m_session->getNameID() : m_nameid;
}
const XMLCh* getClassRef() const {
- return m_class;
+ return m_class.get();
}
const XMLCh* getDeclRef() const {
- return m_decl;
+ return m_decl.get();
}
const Session* getSession() const {
return m_session;
const Application& m_app;
const Session* m_session;
const NameID* m_nameid;
- char* m_entityid;
- XMLCh* m_class;
- XMLCh* m_decl;
+ auto_ptr_char m_entityid;
+ auto_ptr_XMLCh m_class;
+ auto_ptr_XMLCh m_decl;
const vector<const opensaml::Assertion*>* m_inputTokens;
const vector<shibsp::Attribute*>* m_inputAttributes;
vector<shibsp::Attribute*> m_attributes;
{
public:
SimpleAggregationResolver(const DOMElement* e);
- ~SimpleAggregationResolver() {
- delete m_trust;
- delete m_metadata;
- for_each(m_designators.begin(), m_designators.end(), xmltooling::cleanup<saml2::Attribute>());
- }
+ ~SimpleAggregationResolver() {}
Lockable* lock() {return this;}
void unlock() {}
bool m_subjectMatch;
vector<string> m_attributeIds;
xstring m_format;
- MetadataProvider* m_metadata;
- TrustEngine* m_trust;
- vector<saml2::Attribute*> m_designators;
+ scoped_ptr<MetadataProvider> m_metadata;
+ scoped_ptr<TrustEngine> m_trust;
+ ptr_vector<saml2::Attribute> m_designators;
vector< pair<string,bool> > m_sources;
vector<string> m_exceptionId;
};
SimpleAggregationResolver::SimpleAggregationResolver(const DOMElement* e)
: m_log(Category::getInstance(SHIBSP_LOGCAT".AttributeResolver.SimpleAggregation")),
m_policyId(XMLHelper::getAttrString(e, nullptr, policyId)),
- m_subjectMatch(XMLHelper::getAttrBool(e, false, subjectMatch)),
- m_metadata(nullptr), m_trust(nullptr)
+ m_subjectMatch(XMLHelper::getAttrBool(e, false, subjectMatch))
{
#ifdef _DEBUG
xmltooling::NDC ndc("SimpleAggregationResolver");
const XMLCh* aid = e ? e->getAttributeNS(nullptr, attributeId) : nullptr;
if (aid && *aid) {
- char* dup = XMLString::transcode(aid);
- char* pos;
- char* start = dup;
- while (start && *start) {
- while (*start && isspace(*start))
- start++;
- if (!*start)
- break;
- pos = strchr(start,' ');
- if (pos)
- *pos=0;
- m_attributeIds.push_back(start);
- start = pos ? pos+1 : nullptr;
- }
- XMLString::release(&dup);
+ auto_ptr_char dup(aid);
+ string sdup(dup.get());
+ split(m_attributeIds, sdup, is_space(), algorithm::token_compress_on);
aid = e->getAttributeNS(nullptr, format);
if (aid && *aid)
if (t.empty())
throw ConfigurationException("MetadataProvider element missing type attribute.");
m_log.info("building MetadataProvider of type %s...", t.c_str());
- auto_ptr<MetadataProvider> mp(SAMLConfig::getConfig().MetadataProviderManager.newPlugin(t.c_str(), child));
- mp->init();
- m_metadata = mp.release();
+ m_metadata.reset(SAMLConfig::getConfig().MetadataProviderManager.newPlugin(t.c_str(), child));
+ m_metadata->init();
}
child = XMLHelper::getFirstChildElement(e, _TrustEngine);
if (child) {
- try {
- string t(XMLHelper::getAttrString(child, nullptr, _type));
- if (t.empty())
- throw ConfigurationException("TrustEngine element missing type attribute.");
- m_log.info("building TrustEngine of type %s...", t.c_str());
- m_trust = XMLToolingConfig::getConfig().TrustEngineManager.newPlugin(t.c_str(), child);
- }
- catch (exception&) {
- delete m_metadata;
- throw;
- }
+ string t(XMLHelper::getAttrString(child, nullptr, _type));
+ if (t.empty())
+ throw ConfigurationException("TrustEngine element missing type attribute.");
+ m_log.info("building TrustEngine of type %s...", t.c_str());
+ m_trust.reset(XMLToolingConfig::getConfig().TrustEngineManager.newPlugin(t.c_str(), child));
}
child = XMLHelper::getFirstChildElement(e);
obj.release();
}
}
- catch (exception& ex) {
+ catch (std::exception& ex) {
m_log.error("exception loading attribute designator: %s", ex.what());
}
}
#endif
const Application& application = ctx.getApplication();
MetadataProviderCriteria mc(application, entityID, &AttributeAuthorityDescriptor::ELEMENT_QNAME, samlconstants::SAML20P_NS);
- Locker mlocker(m_metadata);
+ Locker mlocker(m_metadata.get());
const AttributeAuthorityDescriptor* AA=nullptr;
pair<const EntityDescriptor*,const RoleDescriptor*> mdresult =
- (m_metadata ? m_metadata : application.getMetadataProvider())->getEntityDescriptor(mc);
+ (m_metadata ? m_metadata.get() : application.getMetadataProvider())->getEntityDescriptor(mc);
if (!mdresult.first) {
m_log.warn("unable to locate metadata for provider (%s)", entityID);
return;
const char* policyId = m_policyId.empty() ? application.getString("policyId").second : m_policyId.c_str();
// Set up policy and SOAP client.
- auto_ptr<SecurityPolicy> policy(
+ scoped_ptr<SecurityPolicy> policy(
application.getServiceProvider().getSecurityPolicyProvider()->createSecurityPolicy(application, nullptr, policyId)
);
if (m_metadata)
- policy->setMetadataProvider(m_metadata);
+ policy->setMetadataProvider(m_metadata.get());
if (m_trust)
- policy->setTrustEngine(m_trust);
+ policy->setTrustEngine(m_trust.get());
policy->getAudiences().push_back(relyingParty->getXMLString("entityID").second);
MetadataCredentialCriteria mcc(*AA);
shibsp::SOAPClient soaper(*policy.get());
auto_ptr_XMLCh binding(samlconstants::SAML20_BINDING_SOAP);
- saml2p::StatusResponseType* srt=nullptr;
+ auto_ptr<saml2p::StatusResponseType> srt;
const vector<AttributeService*>& endpoints=AA->getAttributeServices();
- for (vector<AttributeService*>::const_iterator ep=endpoints.begin(); !srt && ep!=endpoints.end(); ++ep) {
- if (!XMLString::equals((*ep)->getBinding(),binding.get()) || !(*ep)->getLocation())
+ for (indirect_iterator<vector<AttributeService*>::const_iterator> ep = make_indirect_iterator(endpoints.begin());
+ !srt.get() && ep != make_indirect_iterator(endpoints.end()); ++ep) {
+ if (!XMLString::equals(ep->getBinding(), binding.get()) || !ep->getLocation())
continue;
- auto_ptr_char loc((*ep)->getLocation());
+ auto_ptr_char loc(ep->getLocation());
try {
auto_ptr<saml2::Subject> subject(saml2::SubjectBuilder::buildSubject());
false,
relyingParty->getXMLString("encryptionAlg").second
);
- subject->setEncryptedID(encrypted.release());
+ subject->setEncryptedID(encrypted.get());
+ encrypted.release();
}
else {
subject->setNameID(name->cloneNameID());
Issuer* iss = IssuerBuilder::buildIssuer();
iss->setName(relyingParty->getXMLString("entityID").second);
query->setIssuer(iss);
- for (vector<saml2::Attribute*>::const_iterator ad = m_designators.begin(); ad!=m_designators.end(); ++ad)
- query->getAttributes().push_back((*ad)->cloneAttribute());
+ for (ptr_vector<saml2::Attribute>::const_iterator ad = m_designators.begin(); ad != m_designators.end(); ++ad) {
+ auto_ptr<saml2::Attribute> adwrapper(ad->cloneAttribute());
+ query->getAttributes().push_back(adwrapper.get());
+ adwrapper.release();
+ }
SAML2SOAPClient client(soaper, false);
client.sendSAML(query, application.getId(), mcc, loc.get());
- srt = client.receiveSAML();
+ srt.reset(client.receiveSAML());
}
- catch (exception& ex) {
+ catch (std::exception& ex) {
m_log.error("exception during SAML query to %s: %s", loc.get(), ex.what());
soaper.reset();
}
}
- if (!srt) {
+ if (!srt.get()) {
m_log.error("unable to obtain a SAML response from attribute authority (%s)", entityID);
throw BindingException("Unable to obtain a SAML response from attribute authority.");
}
- auto_ptr<saml2p::StatusResponseType> wrapper(srt);
-
- saml2p::Response* response = dynamic_cast<saml2p::Response*>(srt);
+ saml2p::Response* response = dynamic_cast<saml2p::Response*>(srt.get());
if (!response) {
m_log.error("message was not a samlp:Response");
throw FatalProfileException("Attribute authority returned an unrecognized message.");
}
saml2::Assertion* newtoken = nullptr;
+ auto_ptr<saml2::Assertion> newtokenwrapper;
const vector<saml2::Assertion*>& assertions = const_cast<const saml2p::Response*>(response)->getAssertions();
if (assertions.empty()) {
// Check for encryption.
newtoken = dynamic_cast<saml2::Assertion*>(tokenwrapper.get());
if (newtoken) {
tokenwrapper.release();
+ newtokenwrapper.reset(newtoken);
if (m_log.isDebugEnabled())
m_log.debugStream() << "decrypted Assertion: " << *newtoken << logging::eol;
- // Free the Response now, so we know this is a stand-alone token later.
- delete wrapper.release();
}
}
- catch (exception& ex) {
+ catch (std::exception& ex) {
m_log.error(ex.what());
throw;
}
if (!newtoken->getSignature() && signedAssertions.first && signedAssertions.second) {
m_log.error("assertion unsigned, rejecting it based on signedAssertions policy");
- if (!wrapper.get())
- delete newtoken;
throw SecurityPolicyException("Rejected unsigned assertion based on local policy.");
}
if (m_subjectMatch) {
// Check for subject match.
- bool ownedName = false;
+ auto_ptr<NameID> nameIDwrapper;
NameID* respName = newtoken->getSubject() ? newtoken->getSubject()->getNameID() : nullptr;
if (!respName) {
// Check for encryption.
auto_ptr<XMLObject> decryptedID(encname->decrypt(*cr, relyingParty->getXMLString("entityID").second, &mcc));
respName = dynamic_cast<NameID*>(decryptedID.get());
if (respName) {
- ownedName = true;
decryptedID.release();
+ nameIDwrapper.reset(respName);
if (m_log.isDebugEnabled())
m_log.debugStream() << "decrypted NameID: " << *respName << logging::eol;
}
}
}
- auto_ptr<NameID> nameIDwrapper(ownedName ? respName : nullptr);
-
if (!respName || !XMLString::equals(respName->getName(), name->getName()) ||
!XMLString::equals(respName->getFormat(), name->getFormat()) ||
!XMLString::equals(respName->getNameQualifier(), name->getNameQualifier()) ||
*respName << logging::eol;
else
m_log.warn("ignoring Assertion without NameID in Subject");
- if (!wrapper.get())
- delete newtoken;
return;
}
}
}
- catch (exception& ex) {
+ catch (std::exception& ex) {
m_log.error("assertion failed policy validation: %s", ex.what());
- if (!wrapper.get())
- delete newtoken;
throw;
}
- if (wrapper.get()) {
+ // If the token's embedded, detach it.
+ if (!newtokenwrapper.get()) {
newtoken->detach();
- wrapper.release(); // detach blows away the Response
+ srt.release(); // detach blows away the Response, so avoid a double free
+ newtokenwrapper.reset(newtoken);
}
ctx.getResolvedAssertions().push_back(newtoken);
+ newtokenwrapper.release();
// Finally, extract and filter the result.
try {
filter->filterAttributes(fc, ctx.getResolvedAttributes());
}
}
- catch (exception& ex) {
+ catch (std::exception& ex) {
m_log.error("caught exception extracting/filtering attributes from query result: %s", ex.what());
for_each(ctx.getResolvedAttributes().begin(), ctx.getResolvedAttributes().end(), xmltooling::cleanup<shibsp::Attribute>());
ctx.getResolvedAttributes().clear();
SimpleAggregationContext& qctx = dynamic_cast<SimpleAggregationContext&>(ctx);
// First we manufacture the appropriate NameID to use.
- NameID* n=nullptr;
- for (vector<string>::const_iterator a = m_attributeIds.begin(); !n && a != m_attributeIds.end(); ++a) {
+ scoped_ptr<NameID> n;
+ for (vector<string>::const_iterator a = m_attributeIds.begin(); !n.get() && a != m_attributeIds.end(); ++a) {
const Attribute* attr=nullptr;
if (qctx.getSession()) {
// Input attributes should be available via multimap.
else if (qctx.getInputAttributes()) {
// Have to loop over unindexed set.
const vector<Attribute*>* matches = qctx.getInputAttributes();
- for (vector<Attribute*>::const_iterator match = matches->begin(); !attr && match != matches->end(); ++match) {
- if (*a == (*match)->getId() && (*match)->valueCount() > 0)
- attr = *match;
+ for (indirect_iterator<vector<Attribute*>::const_iterator> match = make_indirect_iterator(matches->begin());
+ !attr && match != make_indirect_iterator(matches->end()); ++match) {
+ if (*a == match->getId() && match->valueCount() > 0)
+ attr = &(*match);
}
}
if (attr) {
m_log.debug("using input attribute (%s) as identifier for queries", attr->getId());
- n = NameIDBuilder::buildNameID();
+ n.reset(NameIDBuilder::buildNameID());
const NameIDAttribute* down = dynamic_cast<const NameIDAttribute*>(attr);
if (down) {
// We can create a NameID directly from the source material.
const NameIDAttribute::Value& v = down->getValues().front();
- XMLCh* val = fromUTF8(v.m_Name.c_str());
- n->setName(val);
- delete[] val;
+ auto_arrayptr<XMLCh> val(fromUTF8(v.m_Name.c_str()));
+ n->setName(val.get());
+
if (!v.m_Format.empty()) {
- val = fromUTF8(v.m_Format.c_str());
- n->setFormat(val);
- delete[] val;
+ auto_arrayptr<XMLCh> format(fromUTF8(v.m_Format.c_str()));
+ n->setFormat(format.get());
}
if (!v.m_NameQualifier.empty()) {
- val = fromUTF8(v.m_NameQualifier.c_str());
- n->setNameQualifier(val);
- delete[] val;
+ auto_arrayptr<XMLCh> nq(fromUTF8(v.m_NameQualifier.c_str()));
+ n->setNameQualifier(nq.get());
}
if (!v.m_SPNameQualifier.empty()) {
- val = fromUTF8(v.m_SPNameQualifier.c_str());
- n->setSPNameQualifier(val);
- delete[] val;
+ auto_arrayptr<XMLCh> spnq(fromUTF8(v.m_SPNameQualifier.c_str()));
+ n->setSPNameQualifier(spnq.get());
}
if (!v.m_SPProvidedID.empty()) {
- val = fromUTF8(v.m_SPProvidedID.c_str());
- n->setSPProvidedID(val);
- delete[] val;
+ auto_arrayptr<XMLCh> sppid(fromUTF8(v.m_SPProvidedID.c_str()));
+ n->setSPProvidedID(sppid.get());
}
}
else {
// We have to mock up the NameID.
- XMLCh* val = fromUTF8(attr->getSerializedValues().front().c_str());
- n->setName(val);
- delete[] val;
+ auto_arrayptr<XMLCh> val(fromUTF8(attr->getSerializedValues().front().c_str()));
+ n->setName(val.get());
if (!m_format.empty())
n->setFormat(m_format.c_str());
}
}
}
- auto_ptr<NameID> wrapper(n);
-
set<string> history;
// Put initial IdP into history to prevent extra query.
history.insert(qctx.getEntityID());
// Prepare to track exceptions.
- SimpleAttribute* exceptAttr = nullptr;
- if (!m_exceptionId.empty()) {
- exceptAttr = new SimpleAttribute(m_exceptionId);
- }
- auto_ptr<Attribute> exceptWrapper(exceptAttr);
+ auto_ptr<SimpleAttribute> exceptAttr;
+ if (!m_exceptionId.empty())
+ exceptAttr.reset(new SimpleAttribute(m_exceptionId));
// We have a master loop over all the possible sources of material.
for (vector< pair<string,bool> >::const_iterator source = m_sources.begin(); source != m_sources.end(); ++source) {
if (history.count(source->first) == 0) {
m_log.debug("issuing SAML query to (%s)", source->first.c_str());
try {
- doQuery(qctx, source->first.c_str(), n ? n : qctx.getNameID());
+ doQuery(qctx, source->first.c_str(), n ? n.get() : qctx.getNameID());
}
- catch (exception& ex) {
- if (exceptAttr)
+ catch (std::exception& ex) {
+ if (exceptAttr.get())
exceptAttr->getValues().push_back(XMLToolingConfig::getConfig().getURLEncoder()->encode(ex.what()));
}
history.insert(source->first);
if (history.count(*link) == 0) {
m_log.debug("issuing SAML query to (%s)", link->c_str());
try {
- doQuery(qctx, link->c_str(), n ? n : qctx.getNameID());
+ doQuery(qctx, link->c_str(), n ? n.get() : qctx.getNameID());
}
- catch (exception& ex) {
- if (exceptAttr)
+ catch (std::exception& ex) {
+ if (exceptAttr.get())
exceptAttr->getValues().push_back(XMLToolingConfig::getConfig().getURLEncoder()->encode(ex.what()));
}
history.insert(*link);
else if (qctx.getInputAttributes()) {
// Have to loop over unindexed set.
const vector<Attribute*>* matches = qctx.getInputAttributes();
- for (vector<Attribute*>::const_iterator match = matches->begin(); match != matches->end(); ++match) {
- if (source->first == (*match)->getId()) {
- const vector<string>& links = (*match)->getSerializedValues();
+ for (indirect_iterator<vector<Attribute*>::const_iterator> match = make_indirect_iterator(matches->begin());
+ match != make_indirect_iterator(matches->end()); ++match) {
+ if (source->first == match->getId()) {
+ const vector<string>& links = match->getSerializedValues();
for (vector<string>::const_iterator link = links.begin(); link != links.end(); ++link) {
if (history.count(*link) == 0) {
m_log.debug("issuing SAML query to (%s)", link->c_str());
try {
- doQuery(qctx, link->c_str(), n ? n : qctx.getNameID());
+ doQuery(qctx, link->c_str(), n ? n.get() : qctx.getNameID());
}
- catch (exception& ex) {
- if (exceptAttr)
+ catch (std::exception& ex) {
+ if (exceptAttr.get())
exceptAttr->getValues().push_back(XMLToolingConfig::getConfig().getURLEncoder()->encode(ex.what()));
}
history.insert(*link);
}
}
- if (exceptAttr) {
- qctx.getResolvedAttributes().push_back(exceptWrapper.release());
+ if (exceptAttr.get()) {
+ qctx.getResolvedAttributes().push_back(exceptAttr.get());
+ exceptAttr.release();
}
}
) const = &XMLExtractorImpl::extractAttributes;
for_each(
make_indirect_iterator(container->getAttributes().begin()), make_indirect_iterator(container->getAttributes().end()),
- boost::bind(extractV2Attr, this, boost::ref(application), nullptr, relyingParty, _1, boost::ref(holding))
+ boost::bind(extractV2Attr, this, boost::ref(application), (const char*)nullptr, relyingParty, _1, boost::ref(holding))
);
if (entityID && m_entityAssertions) {
#include <shibsp/handler/AbstractHandler.h>
#include <shibsp/handler/RemotedHandler.h>
+#include <boost/scoped_ptr.hpp>
+
#ifndef SHIBSP_LITE
namespace opensaml {
class SAML_API Assertion;
) const;
#ifndef SHIBSP_LITE
- opensaml::MessageDecoder* m_decoder;
- xmltooling::QName m_role;
+ boost::scoped_ptr<opensaml::MessageDecoder> m_decoder;
#endif
};
#include <vector>
#include <fstream>
+#include <boost/bind.hpp>
+#include <boost/lexical_cast.hpp>
+#include <boost/algorithm/string.hpp>
#include <xmltooling/XMLToolingConfig.h>
#include <xmltooling/util/PathResolver.h>
#include <xmltooling/util/URLEncoder.h>
using namespace samlconstants;
using namespace xmltooling;
using namespace xercesc;
+using namespace boost;
using namespace std;
namespace shibsp {
int port = request.getPort();
const char* scheme = request.getScheme();
string root = string(scheme) + "://" + request.getHostname();
- if ((!strcmp(scheme,"http") && port!=80) || (!strcmp(scheme,"https") && port!=443)) {
- ostringstream portstr;
- portstr << port;
- root += ":" + portstr.str();
+ if ((!strcmp(scheme, "http") && port != 80) || (!strcmp(scheme, "https") && port != 443)) {
+ root += ":" + lexical_cast<string>(port);
}
url = root + url;
}
else if (!strcmp(httpRequest.getScheme(), "http") && httpRequest.getPort() == 80) {
whitelist.push_back(string("http://") + httpRequest.getHostname() + '/');
}
- ostringstream portstr;
- portstr << httpRequest.getPort();
- whitelist.push_back(string(httpRequest.getScheme()) + "://" + httpRequest.getHostname() + ':' + portstr.str() + '/');
+ whitelist.push_back(
+ string(httpRequest.getScheme()) + "://" + httpRequest.getHostname() + ':' + lexical_cast<string>(httpRequest.getPort()) + '/'
+ );
}
else if (!strcmp(relayStateLimit.second, "host")) {
// Allow any scheme or port.
// Literal set of comparisons to use.
pair<bool,const char*> whitelistval = sessionProps->getString("relayStateWhitelist");
if (whitelistval.first) {
-#ifdef HAVE_STRTOK_R
- char* pos=nullptr;
- const char* token = strtok_r(const_cast<char*>(whitelistval.second), " ", &pos);
-#else
- const char* token = strtok(const_cast<char*>(whitelistval.second), " ");
-#endif
- while (token) {
- whitelist.push_back(token);
-#ifdef HAVE_STRTOK_R
- token = strtok_r(nullptr, " ", &pos);
-#else
- token = strtok(nullptr, " ");
-#endif
- }
+ string dup(whitelistval.second);
+ split(whitelist, dup, is_space(), algorithm::token_compress_on);
}
}
else {
throw opensaml::SecurityPolicyException("Unrecognized relayStateLimit setting.");
}
- for (vector<string>::const_iterator w = whitelist.begin(); w != whitelist.end(); ++w) {
- if (XMLString::startsWithI(relayState, w->c_str())) {
- return;
- }
+ static bool (*startsWithI)(const char*,const char*) = XMLString::startsWithI;
+ if (find_if(whitelist.begin(), whitelist.end(),
+ boost::bind(startsWithI, relayState, boost::bind(&string::c_str, _1))) == whitelist.end()) {
+ log.warn("relayStateLimit policy (%s), blocked redirect to (%s)", relayStateLimit.second, relayState);
+ throw opensaml::SecurityPolicyException("Blocked unacceptable redirect location.");
}
-
- log.warn("relayStateLimit policy (%s), blocked redirect to (%s)", relayStateLimit.second, relayState);
- throw opensaml::SecurityPolicyException("Blocked unacceptable redirect location.");
}
}
}
string stateval = urlenc->encode(relayState.c_str()) + shib_cookie.second;
// Generate a random key for the cookie name instead of the fixed name.
string rsKey;
- generateRandomHex(rsKey,5);
+ generateRandomHex(rsKey, 5);
shib_cookie.first = "_shibstate_" + rsKey;
- response.setCookie(shib_cookie.first.c_str(),stateval.c_str());
+ response.setCookie(shib_cookie.first.c_str(), stateval.c_str());
relayState = "cookie:" + rsKey;
}
}
AbstractHandler::AbstractHandler(
const DOMElement* e, Category& log, DOMNodeFilter* filter, const map<string,string>* remapper
) : m_log(log), m_configNS(shibspconstants::SHIB2SPCONFIG_NS) {
- load(e,nullptr,filter,remapper);
+ load(e, nullptr, filter, remapper);
}
AbstractHandler::~AbstractHandler()
if (storage) {
// Use a random key
string rsKey;
- SAMLConfig::getConfig().generateRandomBytes(rsKey,32);
+ SAMLConfig::getConfig().generateRandomBytes(rsKey, 32);
rsKey = SAMLArtifact::toHex(rsKey);
ostringstream out;
out << postData;
{
string contentType = request.getContentType();
if (contentType.find("application/x-www-form-urlencoded") != string::npos) {
- const PropertySet* props=application.getPropertySet("Sessions");
+ const PropertySet* props = application.getPropertySet("Sessions");
pair<bool,unsigned int> plimit = props ? props->getUnsignedInt("postLimit") : pair<bool,unsigned int>(false,0);
if (!plimit.first)
plimit.second = 1024 * 1024;
{
if (type & HANDLER_PROPERTY_REQUEST) {
const char* param = request.getParameter(name);
- if (param && *param)
- return pair<bool,unsigned int>(true, strtol(param,nullptr,10));
+ if (param && *param) {
+ try {
+ return pair<bool,unsigned int>(true, lexical_cast<unsigned int>(param));
+ }
+ catch (bad_lexical_cast&) {
+ return pair<bool,unsigned int>(false,0);
+ }
+ }
}
if (type & HANDLER_PROPERTY_MAP) {
# include "metadata/MetadataProviderCriteria.h"
# include "security/SecurityPolicy.h"
# include "security/SecurityPolicyProvider.h"
+# include <boost/iterator/indirect_iterator.hpp>
# include <saml/exceptions.h>
# include <saml/SAMLConfig.h>
# include <saml/saml1/core/Assertions.h>
using namespace shibsp;
using namespace opensaml;
using namespace xmltooling;
+using namespace boost;
using namespace std;
AssertionConsumerService::AssertionConsumerService(
const DOMElement* e, const char* appId, Category& log, DOMNodeFilter* filter, const map<string,string>* remapper
) : AbstractHandler(e, log, filter, remapper)
-#ifndef SHIBSP_LITE
- ,m_decoder(nullptr), m_role(samlconstants::SAML20MD_NS, opensaml::saml2md::IDPSSODescriptor::LOCAL_NAME)
-#endif
{
if (!e)
return;
setAddress(address.c_str());
#ifndef SHIBSP_LITE
if (SPConfig::getConfig().isEnabled(SPConfig::OutOfProcess)) {
- m_decoder = SAMLConfig::getConfig().MessageDecoderManager.newPlugin(
- getString("Binding").second, pair<const DOMElement*,const XMLCh*>(e,shibspconstants::SHIB2SPCONFIG_NS)
+ m_decoder.reset(
+ SAMLConfig::getConfig().MessageDecoderManager.newPlugin(
+ getString("Binding").second, pair<const DOMElement*,const XMLCh*>(e,shibspconstants::SHIB2SPCONFIG_NS)
+ )
);
m_decoder->setArtifactResolver(SPConfig::getConfig().getArtifactResolver());
}
AssertionConsumerService::~AssertionConsumerService()
{
-#ifndef SHIBSP_LITE
- delete m_decoder;
-#endif
}
pair<bool,long> AssertionConsumerService::run(SPRequest& request, bool isHandler) const
}
// Unpack the request.
- auto_ptr<HTTPRequest> req(getRequest(in));
+ scoped_ptr<HTTPRequest> req(getRequest(in));
// Wrap a response shim.
DDF ret(nullptr);
DDFJanitor jout(ret);
- auto_ptr<HTTPResponse> resp(getResponse(ret));
+ scoped_ptr<HTTPResponse> resp(getResponse(ret));
// Since we're remoted, the result should either be a throw, a false/0 return,
// which we just return as an empty structure, or a response/redirect,
// which we capture in the facade and send back.
- processMessage(*app, *req.get(), *resp.get());
+ processMessage(*app, *req, *resp);
out << ret;
}
Locker metadataLocker(application.getMetadataProvider());
// Create the policy.
- auto_ptr<opensaml::SecurityPolicy> policy(
- application.getServiceProvider().getSecurityPolicyProvider()->createSecurityPolicy(application, &m_role, policyId.second)
+ scoped_ptr<opensaml::SecurityPolicy> policy(
+ application.getServiceProvider().getSecurityPolicyProvider()->createSecurityPolicy(application, &IDPSSODescriptor::ELEMENT_QNAME, policyId.second)
);
string relayState;
bool relayStateOK = true;
- auto_ptr<XMLObject> msg(nullptr);
+ scoped_ptr<XMLObject> msg;
try {
// Decode the message and process it in a protocol-specific way.
- auto_ptr<XMLObject> msg2(m_decoder->decode(relayState, httpRequest, *(policy.get())));
- if (!msg2.get())
+ msg.reset(m_decoder->decode(relayState, httpRequest, *(policy.get())));
+ if (!msg)
throw BindingException("Failed to decode an SSO protocol response.");
- msg = msg2; // save off to allow access from within exception handler.
DDF postData = recoverPostData(application, httpRequest, httpResponse, relayState.c_str());
DDFJanitor postjan(postData);
recoverRelayState(application, httpRequest, httpResponse, relayState);
limitRelayState(m_log, application, httpRequest, relayState.c_str());
- implementProtocol(application, httpRequest, httpResponse, *(policy.get()), NULL, *msg.get());
+ implementProtocol(application, httpRequest, httpResponse, *policy, nullptr, *msg);
auto_ptr_char issuer(policy->getIssuer() ? policy->getIssuer()->getName() : nullptr);
// Log the error.
try {
- auto_ptr<TransactionLog::Event> event(SPConfig::getConfig().EventManager.newPlugin(LOGIN_EVENT, nullptr));
+ scoped_ptr<TransactionLog::Event> event(SPConfig::getConfig().EventManager.newPlugin(LOGIN_EVENT, nullptr));
LoginEvent* error_event = dynamic_cast<LoginEvent*>(event.get());
if (error_event) {
error_event->m_exception = &ex;
m_log.warn("unable to audit event, log event object was of an incorrect type");
}
}
- catch (exception& ex) {
+ catch (std::exception& ex) {
m_log.warn("exception auditing event: %s", ex.what());
}
if (!issuedTo || !*issuedTo)
return;
- const PropertySet* props=application.getPropertySet("Sessions");
+ const PropertySet* props = application.getPropertySet("Sessions");
pair<bool,bool> checkAddress = props ? props->getBool("checkAddress") : make_pair(false,true);
if (!checkAddress.first)
- checkAddress.second=true;
+ checkAddress.second = true;
if (checkAddress.second) {
m_log.debug("checking client address");
"Your client's current address ($client_addr) differs from the one used when you authenticated "
"to your identity provider. To correct this problem, you may need to bypass a proxy server. "
"Please contact your local support staff or help desk for assistance.",
- namedparams(1,"client_addr",httpRequest.getRemoteAddr().c_str())
+ namedparams(1, "client_addr", httpRequest.getRemoteAddr().c_str())
);
}
}
try {
// We pass nullptr for "issuer" because the IdP isn't the one asserting metadata-based attributes.
extractor->extractAttributes(application, nullptr, *issuer, resolvedAttributes);
- for (vector<Attribute*>::iterator a = resolvedAttributes.begin(); a != resolvedAttributes.end(); ++a) {
- vector<string>& ids = (*a)->getAliases();
+ for (indirect_iterator<vector<Attribute*>::iterator> a = make_indirect_iterator(resolvedAttributes.begin());
+ a != make_indirect_iterator(resolvedAttributes.end()); ++a) {
+ vector<string>& ids = a->getAliases();
for (vector<string>::iterator id = ids.begin(); id != ids.end(); ++id)
*id = mprefix.second + *id;
}
}
- catch (exception& ex) {
+ catch (std::exception& ex) {
m_log.error("caught exception extracting attributes: %s", ex.what());
}
}
else
extractor->extractAttributes(application, issuer, *nameid, resolvedAttributes);
}
- catch (exception& ex) {
+ catch (std::exception& ex) {
m_log.error("caught exception extracting attributes: %s", ex.what());
}
}
else
extractor->extractAttributes(application, issuer, *statement, resolvedAttributes);
}
- catch (exception& ex) {
+ catch (std::exception& ex) {
m_log.error("caught exception extracting attributes: %s", ex.what());
}
}
if (tokens) {
- for (vector<const Assertion*>::const_iterator t = tokens->begin(); t!=tokens->end(); ++t) {
+ for (indirect_iterator<vector<const Assertion*>::const_iterator> t = make_indirect_iterator(tokens->begin());
+ t != make_indirect_iterator(tokens->end()); ++t) {
try {
- extractor->extractAttributes(application, issuer, *(*t), resolvedAttributes);
+ extractor->extractAttributes(application, issuer, *t, resolvedAttributes);
}
- catch (exception& ex) {
+ catch (std::exception& ex) {
m_log.error("caught exception extracting attributes: %s", ex.what());
}
}
try {
filter->filterAttributes(fc, resolvedAttributes);
}
- catch (exception& ex) {
+ catch (std::exception& ex) {
m_log.error("caught exception filtering attributes: %s", ex.what());
m_log.error("dumping extracted attributes due to filtering exception");
for_each(resolvedAttributes.begin(), resolvedAttributes.end(), xmltooling::cleanup<shibsp::Attribute>());
&resolvedAttributes
)
);
- resolver->resolveAttributes(*ctx.get());
+ resolver->resolveAttributes(*ctx);
// Copy over any pushed attributes.
- if (!resolvedAttributes.empty())
- ctx->getResolvedAttributes().insert(ctx->getResolvedAttributes().end(), resolvedAttributes.begin(), resolvedAttributes.end());
+ while (!resolvedAttributes.empty()) {
+ ctx->getResolvedAttributes().push_back(resolvedAttributes.back());
+ resolvedAttributes.pop_back();
+ }
return ctx.release();
}
}
- catch (exception& ex) {
+ catch (std::exception& ex) {
m_log.error("attribute resolution failed: %s", ex.what());
}
- if (!resolvedAttributes.empty())
- return new DummyContext(resolvedAttributes);
+ if (!resolvedAttributes.empty()) {
+ try {
+ return new DummyContext(resolvedAttributes);
+ }
+ catch (bad_alloc&) {
+ for_each(resolvedAttributes.begin(), resolvedAttributes.end(), xmltooling::cleanup<shibsp::Attribute>());
+ }
+ }
return nullptr;
}
m_log.warn("unable to audit event, log event object was of an incorrect type");
}
}
- catch (exception& ex) {
+ catch (std::exception& ex) {
m_log.warn("exception auditing event: %s", ex.what());
}
return nullptr;
#include "util/IPRange.h"
#include "util/SPConstants.h"
+#include <boost/bind.hpp>
+#include <boost/scoped_ptr.hpp>
+#include <boost/algorithm/string.hpp>
+
#ifndef SHIBSP_LITE
# include <saml/exceptions.h>
# include <saml/Assertion.h>
using namespace shibspconstants;
using namespace shibsp;
using namespace xmltooling;
+using namespace boost;
using namespace std;
namespace shibsp {
private:
pair<bool,long> processMessage(const Application& application, HTTPRequest& httpRequest, HTTPResponse& httpResponse) const;
+ void parseACL(const string& acl) {
+ try {
+ m_acl.push_back(IPRange::parseCIDRBlock(acl.c_str()));
+ }
+ catch (std::exception& ex) {
+ m_log.error("invalid CIDR block (%s): %s", acl.c_str(), ex.what());
+ }
+ }
vector<IPRange> m_acl;
};
pair<bool,const char*> acl = getString("exportACL");
if (acl.first) {
string aclbuf=acl.second;
- int j = 0;
- for (unsigned int i=0; i < aclbuf.length(); i++) {
- if (aclbuf.at(i)==' ') {
- try {
- m_acl.push_back(IPRange::parseCIDRBlock(aclbuf.substr(j, i-j).c_str()));
- }
- catch (exception& ex) {
- m_log.error("invalid CIDR block (%s): %s", aclbuf.substr(j, i-j).c_str(), ex.what());
- }
- j = i+1;
- }
- }
- try {
- m_acl.push_back(IPRange::parseCIDRBlock(aclbuf.substr(j, aclbuf.length()-j).c_str()));
- }
- catch (exception& ex) {
- m_log.error("invalid CIDR block (%s): %s", aclbuf.substr(j, aclbuf.length()-j).c_str(), ex.what());
- }
-
+ vector<string> aclarray;
+ split(aclarray, aclbuf, is_space(), algorithm::token_compress_on);
+ for_each(aclarray.begin(), aclarray.end(), boost::bind(&AssertionLookup::parseACL, this, _1));
if (m_acl.empty()) {
m_log.warn("invalid CIDR range(s) in acl property, allowing 127.0.0.1 as a fall back");
m_acl.push_back(IPRange::parseCIDRBlock("127.0.0.1"));
{
SPConfig& conf = SPConfig::getConfig();
if (conf.isEnabled(SPConfig::InProcess) && !m_acl.empty()) {
- bool found = false;
- for (vector<IPRange>::const_iterator acl = m_acl.begin(); !found && acl != m_acl.end(); ++acl) {
- found = acl->contains(request.getRemoteAddr().c_str());
- }
- if (!found) {
+ static bool (IPRange::* contains)(const char*) const = &IPRange::contains;
+ if (find_if(m_acl.begin(), m_acl.end(), boost::bind(contains, _1, request.getRemoteAddr().c_str())) == m_acl.end()) {
m_log.error("request for assertion lookup blocked from invalid address (%s)", request.getRemoteAddr().c_str());
istringstream msg("Assertion Lookup Blocked");
return make_pair(true,request.sendResponse(msg, HTTPResponse::XMLTOOLING_HTTP_STATUS_FORBIDDEN));
return unwrap(request, out);
}
}
- catch (exception& ex) {
+ catch (std::exception& ex) {
m_log.error("error while processing request: %s", ex.what());
istringstream msg("Assertion Lookup Failed");
- return make_pair(true,request.sendResponse(msg, HTTPResponse::XMLTOOLING_HTTP_STATUS_ERROR));
+ return make_pair(true, request.sendResponse(msg, HTTPResponse::XMLTOOLING_HTTP_STATUS_ERROR));
}
}
}
// Unpack the request.
- auto_ptr<HTTPRequest> req(getRequest(in));
+ scoped_ptr<HTTPRequest> req(getRequest(in));
//m_log.debug("found %d client certificates", req->getClientCertificates().size());
// Wrap a response shim.
DDF ret(nullptr);
DDFJanitor jout(ret);
- auto_ptr<HTTPResponse> resp(getResponse(ret));
+ scoped_ptr<HTTPResponse> resp(getResponse(ret));
// Since we're remoted, the result should either be a throw, a false/0 return,
// which we just return as an empty structure, or a response/redirect,
// which we capture in the facade and send back.
- processMessage(*app, *req.get(), *resp.get());
+ processMessage(*app, *req, *resp);
out << ret;
}
#include "handler/LogoutInitiator.h"
#include "util/SPConstants.h"
+#include <boost/bind.hpp>
+#include <boost/ptr_container/ptr_vector.hpp>
#include <xercesc/util/XMLUniDefs.hpp>
#include <xmltooling/util/XMLHelper.h>
using namespace shibsp;
using namespace xmltooling;
+using namespace boost;
using namespace std;
namespace shibsp {
{
public:
ChainingLogoutInitiator(const DOMElement* e, const char* appId);
- virtual ~ChainingLogoutInitiator() {
- for_each(m_handlers.begin(), m_handlers.end(), xmltooling::cleanup<Handler>());
- }
+ virtual ~ChainingLogoutInitiator() {}
pair<bool,long> run(SPRequest& request, bool isHandler=true) const;
#ifndef SHIBSP_LITE
void generateMetadata(opensaml::saml2md::SPSSODescriptor& role, const char* handlerURL) const {
- for (vector<Handler*>::const_iterator i = m_handlers.begin(); i!=m_handlers.end(); ++i)
- (*i)->generateMetadata(role, handlerURL);
+ for_each(m_handlers.begin(), m_handlers.end(), boost::bind(&Handler::generateMetadata, _1, boost::ref(role), handlerURL));
}
#endif
private:
- vector<Handler*> m_handlers;
+ ptr_vector<Handler> m_handlers;
};
#if defined (_MSC_VER)
string t(XMLHelper::getAttrString(e, nullptr, _type));
if (!t.empty()) {
try {
- m_handlers.push_back(conf.LogoutInitiatorManager.newPlugin(t.c_str(), make_pair(e, appId)));
- m_handlers.back()->setParent(this);
+ auto_ptr<Handler> np(conf.LogoutInitiatorManager.newPlugin(t.c_str(), make_pair(e, appId)));
+ m_handlers.push_back(np);
+ m_handlers.back().setParent(this);
}
- catch (exception& ex) {
+ catch (std::exception& ex) {
m_log.error("caught exception processing embedded LogoutInitiator element: %s", ex.what());
}
}
if (ret.first)
return ret;
- for (vector<Handler*>::const_iterator i = m_handlers.begin(); i!=m_handlers.end(); ++i) {
- ret = (*i)->run(request, isHandler);
+ for (ptr_vector<Handler>::const_iterator i = m_handlers.begin(); i != m_handlers.end(); ++i) {
+ ret = i->run(request, isHandler);
if (ret.first)
return ret;
}
#include "handler/SessionInitiator.h"
#include "util/SPConstants.h"
+#include <boost/bind.hpp>
+#include <boost/ptr_container/ptr_vector.hpp>
#include <xercesc/util/XMLUniDefs.hpp>
#include <xmltooling/util/XMLHelper.h>
using namespace shibsp;
using namespace xmltooling;
+using namespace boost;
using namespace std;
namespace shibsp {
{
public:
ChainingSessionInitiator(const DOMElement* e, const char* appId);
- virtual ~ChainingSessionInitiator() {
- for_each(m_handlers.begin(), m_handlers.end(), xmltooling::cleanup<SessionInitiator>());
- }
+ virtual ~ChainingSessionInitiator() {}
pair<bool,long> run(SPRequest& request, string& entityID, bool isHandler=true) const;
#ifndef SHIBSP_LITE
void generateMetadata(opensaml::saml2md::SPSSODescriptor& role, const char* handlerURL) const {
SessionInitiator::generateMetadata(role, handlerURL);
- for (vector<SessionInitiator*>::const_iterator i = m_handlers.begin(); i!=m_handlers.end(); ++i)
- (*i)->generateMetadata(role, handlerURL);
+ for_each(m_handlers.begin(), m_handlers.end(), boost::bind(&SessionInitiator::generateMetadata, _1, boost::ref(role), handlerURL));
}
#endif
private:
- vector<SessionInitiator*> m_handlers;
+ ptr_vector<SessionInitiator> m_handlers;
};
#if defined (_MSC_VER)
// Load up the chain of handlers.
e = e ? XMLHelper::getFirstChildElement(e, _SessionInitiator) : nullptr;
while (e) {
- auto_ptr_char type(e->getAttributeNS(nullptr,_type));
- if (type.get() && *(type.get())) {
+ string t(XMLHelper::getAttrString(e, nullptr, _type));
+ if (!t.empty()) {
try {
- m_handlers.push_back(conf.SessionInitiatorManager.newPlugin(type.get(),make_pair(e, appId)));
- m_handlers.back()->setParent(this);
+ auto_ptr<SessionInitiator> np(conf.SessionInitiatorManager.newPlugin(t.c_str(), make_pair(e, appId)));
+ m_handlers.push_back(np);
+ m_handlers.back().setParent(this);
}
- catch (exception& ex) {
+ catch (std::exception& ex) {
m_log.error("caught exception processing embedded SessionInitiator element: %s", ex.what());
}
}
pair<bool,long> ChainingSessionInitiator::run(SPRequest& request, string& entityID, bool isHandler) const
{
if (!checkCompatibility(request, isHandler))
- return make_pair(false,0L);
+ return make_pair(false, 0L);
pair<bool,long> ret;
- for (vector<SessionInitiator*>::const_iterator i = m_handlers.begin(); i!=m_handlers.end(); ++i) {
- ret = (*i)->run(request, entityID, isHandler);
+ for (ptr_vector<SessionInitiator>::const_iterator i = m_handlers.begin(); i != m_handlers.end(); ++i) {
+ ret = i->run(request, entityID, isHandler);
if (ret.first)
return ret;
}
#ifndef SHIBSP_LITE
# include <queue>
+# include <boost/scoped_ptr.hpp>
# include <saml/exceptions.h>
# include <saml/SAMLConfig.h>
# include <saml/saml2/metadata/DiscoverableMetadataProvider.h>
#ifndef SHIBSP_LITE
using namespace opensaml::saml2md;
using namespace opensaml;
+using namespace boost;
#endif
using namespace xmltooling;
using namespace std;
// A queue of feed files, linked to the last time of "access".
// Each filename is also a cache tag.
mutable queue< pair<string,time_t> > m_feedQueue;
- Mutex* m_feedLock;
+ scoped_ptr<Mutex> m_feedLock;
#endif
};
DiscoveryFeed::DiscoveryFeed(const DOMElement* e, const char* appId)
: AbstractHandler(e, Category::getInstance(SHIBSP_LOGCAT".DiscoveryFeed"), &g_Blocker), m_cacheToClient(false)
-#ifndef SHIBSP_LITE
- , m_feedLock(nullptr)
-#endif
{
pair<bool,const char*> prop = getString("Location");
if (!prop.first)
XMLToolingConfig::getConfig().getPathResolver()->resolve(m_dir, PathResolver::XMLTOOLING_RUN_FILE);
m_log.info("feed files will be cached in %s", m_dir.c_str());
#ifndef SHIBSP_LITE
- m_feedLock = Mutex::create();
+ m_feedLock.reset(Mutex::create());
#endif
}
}
remove(fname.c_str());
m_feedQueue.pop();
}
- delete m_feedLock;
}
#endif
}
request.setContentType("application/json");
return make_pair(true, request.sendResponse(feed));
}
- catch (exception& ex) {
+ catch (std::exception& ex) {
request.log(SPRequest::SPError, string("error while processing request:") + ex.what());
istringstream msg("Discovery Request Failed");
return make_pair(true, request.sendResponse(msg, HTTPResponse::XMLTOOLING_HTTP_STATUS_ERROR));
#ifndef SHIBSP_LITE
m_log.debug("processing discovery feed request");
- DiscoverableMetadataProvider* m=dynamic_cast<DiscoverableMetadataProvider*>(application.getMetadataProvider(false));
+ DiscoverableMetadataProvider* m = dynamic_cast<DiscoverableMetadataProvider*>(application.getMetadataProvider(false));
if (!m)
m_log.warn("MetadataProvider missing or does not support discovery feed");
Locker locker(m);
#ifndef SHIBSP_LITE
m_log.debug("processing discovery feed request");
- DiscoverableMetadataProvider* m=dynamic_cast<DiscoverableMetadataProvider*>(application.getMetadataProvider(false));
+ DiscoverableMetadataProvider* m = dynamic_cast<DiscoverableMetadataProvider*>(application.getMetadataProvider(false));
if (!m)
m_log.warn("MetadataProvider missing or does not support discovery feed");
Locker locker(m);
#include "handler/AbstractHandler.h"
#include "handler/LogoutInitiator.h"
+#ifndef SHIBSP_LITE
+# include <boost/scoped_ptr.hpp>
+using namespace boost;
+#endif
+
using namespace shibsp;
using namespace xmltooling;
using namespace std;
try {
session = request.getSession(false, true, false); // don't cache it and ignore all checks
}
- catch (exception& ex) {
+ catch (std::exception& ex) {
m_log.error("error accessing current session: %s", ex.what());
}
return doRequest(request.getApplication(), request, request, session);
}
// Unpack the request.
- auto_ptr<HTTPRequest> req(getRequest(in));
+ scoped_ptr<HTTPRequest> req(getRequest(in));
// Set up a response shim.
DDF ret(nullptr);
DDFJanitor jout(ret);
- auto_ptr<HTTPResponse> resp(getResponse(ret));
+ scoped_ptr<HTTPResponse> resp(getResponse(ret));
Session* session = nullptr;
try {
- session = app->getServiceProvider().getSessionCache()->find(*app, *req.get(), nullptr, nullptr);
+ session = app->getServiceProvider().getSessionCache()->find(*app, *req, nullptr, nullptr);
}
- catch (exception& ex) {
+ catch (std::exception& ex) {
m_log.error("error accessing current session: %s", ex.what());
}
// This is the "last chance" handler so even without a session, we "complete" the logout.
- doRequest(*app, *req.get(), *resp.get(), session);
+ doRequest(*app, *req, *resp, session);
out << ret;
#else
) const
{
if (session) {
+ // Guard the session in case of exception.
+ Locker locker(session, false);
+
// Do back channel notification.
bool result;
vector<string> sessions(1, session->getID());
result = notifyBackChannel(application, httpRequest.getRequestURL(), sessions, true);
#ifndef SHIBSP_LITE
- auto_ptr<LogoutEvent> logout_event(newLogoutEvent(application, &httpRequest, session));
- if (logout_event.get()) {
+ scoped_ptr<LogoutEvent> logout_event(newLogoutEvent(application, &httpRequest, session));
+ if (logout_event) {
logout_event->m_logoutType = result ? LogoutEvent::LOGOUT_EVENT_LOCAL : LogoutEvent::LOGOUT_EVENT_PARTIAL;
application.getServiceProvider().getTransactionLog()->write(*logout_event);
}
#endif
- session->unlock();
+ locker.assign(); // unlock the session
application.getServiceProvider().getSessionCache()->remove(application, httpRequest, &httpResponse);
if (!result)
return sendLogoutPage(application, httpRequest, httpResponse, "partial");
#include "handler/LogoutHandler.h"
#include "util/TemplateParameters.h"
+#ifndef SHIBSP_LITE
+# include <boost/scoped_ptr.hpp>
+#endif
+
#include <fstream>
+#include <boost/lexical_cast.hpp>
#include <xmltooling/XMLToolingConfig.h>
#include <xmltooling/util/PathResolver.h>
#include <xmltooling/util/URLEncoder.h>
using namespace shibsp;
using namespace xmltooling;
+using namespace boost;
using namespace std;
LogoutHandler::LogoutHandler() : m_initiator(true)
loc = loc + (strchr(loc.c_str(),'?') ? '&' : '?') + "action=logout";
// Now we create a second URL representing the return location back to us.
- ostringstream locstr;
const char* start = request.getRequestURL();
- const char* end = strchr(start,'?');
- string tempstr(start, end ? end-start : strlen(start));
+ const char* end = strchr(start, '?');
+ string locstr(start, end ? end - start : strlen(start));
// Add a signal that we're coming back from notification and the next index.
- locstr << tempstr << "?notifying=1&index=" << index;
+ locstr = locstr + "?notifying=1&index=" + lexical_cast<string>(index);
// Add return if set.
if (param)
- locstr << "&return=" << encoder->encode(param);
+ locstr = locstr + "&return=" + encoder->encode(param);
// We preserve anything we're instructed to directly.
if (params) {
for (map<string,string>::const_iterator p = params->begin(); p!=params->end(); ++p)
- locstr << '&' << p->first << '=' << encoder->encode(p->second.c_str());
+ locstr = locstr + '&' + p->first + '=' + encoder->encode(p->second.c_str());
}
else {
for (vector<string>::const_iterator q = m_preserve.begin(); q!=m_preserve.end(); ++q) {
param = request.getParameter(q->c_str());
if (param)
- locstr << '&' << *q << '=' << encoder->encode(param);
+ locstr = locstr + '&' + *q + '=' + encoder->encode(param);
}
}
// Add the notifier's return parameter to the destination location and redirect.
// This is NOT the same as the return parameter that might be embedded inside it ;-)
- loc = loc + "&return=" + encoder->encode(locstr.str().c_str());
- return make_pair(true,response.sendRedirect(loc.c_str()));
+ loc = loc + "&return=" + encoder->encode(locstr.c_str());
+ return make_pair(true, response.sendRedirect(loc.c_str()));
}
#ifndef SHIBSP_LITE
HTTPSOAPTransport* http = dynamic_cast<HTTPSOAPTransport*>(&transport);
if (http) {
http->useChunkedEncoding(false);
- http->setRequestHeader("User-Agent", PACKAGE_NAME);
http->setRequestHeader(PACKAGE_NAME, PACKAGE_VERSION);
}
}
if (SPConfig::getConfig().isEnabled(SPConfig::OutOfProcess)) {
#ifndef SHIBSP_LITE
- auto_ptr<Envelope> env(EnvelopeBuilder::buildEnvelope());
+ scoped_ptr<Envelope> env(EnvelopeBuilder::buildEnvelope());
Body* body = BodyBuilder::buildBody();
env->setBody(body);
ElementProxy* msg = new AnyElementImpl(shibspconstants::SHIB2SPNOTIFY_NS, LogoutNotification);
body->getUnknownXMLObjects().push_back(msg);
msg->setAttribute(xmltooling::QName(nullptr, _type), local ? _local : _global);
- for (vector<string>::const_iterator s = sessions.begin(); s!=sessions.end(); ++s) {
+ for (vector<string>::const_iterator s = sessions.begin(); s != sessions.end(); ++s) {
auto_ptr_XMLCh temp(s->c_str());
ElementProxy* child = new AnyElementImpl(shibspconstants::SHIB2SPNOTIFY_NS, SessionID);
child->setTextContent(temp.get());
SOAPNotifier soaper;
while (!endpoint.empty()) {
try {
- soaper.send(*env.get(), SOAPTransport::Address(application.getId(), application.getId(), endpoint.c_str()));
+ soaper.send(*env, SOAPTransport::Address(application.getId(), application.getId(), endpoint.c_str()));
delete soaper.receive();
}
- catch (exception& ex) {
+ catch (std::exception& ex) {
Category::getInstance(SHIBSP_LOGCAT".Logout").error("error notifying application of logout event: %s", ex.what());
result = false;
}
DDF temp = DDF(nullptr).string(i->c_str());
s.add(temp);
}
- out=application.getServiceProvider().getListenerService()->send(in);
+ out = application.getServiceProvider().getListenerService()->send(in);
return (out.integer() == 1);
}
Category::getInstance(SHIBSP_LOGCAT".Logout").warn("unable to audit event, log event object was of an incorrect type");
}
}
- catch (exception& ex) {
+ catch (std::exception& ex) {
Category::getInstance(SHIBSP_LOGCAT".Logout").warn("exception auditing event: %s", ex.what());
}
return nullptr;
#include "handler/RemotedHandler.h"
#include "util/IPRange.h"
+#include <boost/bind.hpp>
+#include <boost/scoped_ptr.hpp>
+#include <boost/iterator/indirect_iterator.hpp>
+#include <boost/algorithm/string.hpp>
+
#ifndef SHIBSP_LITE
# include "attribute/resolver/AttributeExtractor.h"
# include "metadata/MetadataProviderCriteria.h"
+# include <boost/ptr_container/ptr_vector.hpp>
# include <saml/exceptions.h>
# include <saml/SAMLConfig.h>
# include <saml/signature/ContentReference.h>
using namespace xmlsignature;
#endif
using namespace xmltooling;
+using namespace boost;
using namespace std;
namespace shibsp {
{
public:
MetadataGenerator(const DOMElement* e, const char* appId);
- virtual ~MetadataGenerator() {
-#ifndef SHIBSP_LITE
- delete m_uiinfo;
- delete m_org;
- delete m_entityAttrs;
- for_each(m_contacts.begin(), m_contacts.end(), xmltooling::cleanup<ContactPerson>());
- for_each(m_formats.begin(), m_formats.end(), xmltooling::cleanup<NameIDFormat>());
- for_each(m_reqAttrs.begin(), m_reqAttrs.end(), xmltooling::cleanup<RequestedAttribute>());
- for_each(m_attrConsumers.begin(), m_attrConsumers.end(), xmltooling::cleanup<AttributeConsumingService>());
-#endif
- }
+ virtual ~MetadataGenerator() {}
pair<bool,long> run(SPRequest& request, bool isHandler=true) const;
void receive(DDF& in, ostream& out);
HTTPResponse& httpResponse
) const;
+ void parseACL(const string& acl) {
+ try {
+ m_acl.push_back(IPRange::parseCIDRBlock(acl.c_str()));
+ }
+ catch (std::exception& ex) {
+ m_log.error("invalid CIDR block (%s): %s", acl.c_str(), ex.what());
+ }
+ }
+
vector<IPRange> m_acl;
#ifndef SHIBSP_LITE
string m_salt;
short m_http,m_https;
vector<string> m_bases;
- UIInfo* m_uiinfo;
- Organization* m_org;
- EntityAttributes* m_entityAttrs;
- vector<ContactPerson*> m_contacts;
- vector<NameIDFormat*> m_formats;
- vector<RequestedAttribute*> m_reqAttrs;
- vector<AttributeConsumingService*> m_attrConsumers;
+ scoped_ptr<UIInfo> m_uiinfo;
+ scoped_ptr<Organization> m_org;
+ scoped_ptr<EntityAttributes> m_entityAttrs;
+ ptr_vector<ContactPerson> m_contacts;
+ ptr_vector<NameIDFormat> m_formats;
+ ptr_vector<RequestedAttribute> m_reqAttrs;
+ ptr_vector<AttributeConsumingService> m_attrConsumers;
#endif
};
MetadataGenerator::MetadataGenerator(const DOMElement* e, const char* appId)
: AbstractHandler(e, Category::getInstance(SHIBSP_LOGCAT".MetadataGenerator"), &g_Blocker)
#ifndef SHIBSP_LITE
- ,m_http(0), m_https(0), m_uiinfo(nullptr), m_org(nullptr), m_entityAttrs(nullptr)
+ ,m_http(0), m_https(0)
#endif
{
string address(appId);
pair<bool,const char*> acl = getString("acl");
if (acl.first) {
string aclbuf=acl.second;
- int j = 0;
- for (unsigned int i=0; i < aclbuf.length(); ++i) {
- if (aclbuf.at(i)==' ') {
- try {
- m_acl.push_back(IPRange::parseCIDRBlock(aclbuf.substr(j, i-j).c_str()));
- }
- catch (exception& ex) {
- m_log.error("invalid CIDR block (%s): %s", aclbuf.substr(j, i-j).c_str(), ex.what());
- }
- j = i + 1;
- }
- }
- try {
- m_acl.push_back(IPRange::parseCIDRBlock(aclbuf.substr(j, aclbuf.length()-j).c_str()));
- }
- catch (exception& ex) {
- m_log.error("invalid CIDR block (%s): %s", aclbuf.substr(j, aclbuf.length()-j).c_str(), ex.what());
- }
-
+ vector<string> aclarray;
+ split(aclarray, aclbuf, is_space(), algorithm::token_compress_on);
+ for_each(aclarray.begin(), aclarray.end(), boost::bind(&MetadataGenerator::parseACL, this, _1));
if (m_acl.empty()) {
m_log.warn("invalid CIDR range(s) in Metadata Generator acl property, allowing 127.0.0.1 as a fall back");
m_acl.push_back(IPRange::parseCIDRBlock("127.0.0.1"));
auto_ptr<XMLObject> child(XMLObjectBuilder::buildOneFromElement(const_cast<DOMElement*>(e)));
ContactPerson* cp = dynamic_cast<ContactPerson*>(child.get());
if (cp) {
- child.release();
m_contacts.push_back(cp);
+ child.release();
}
else {
NameIDFormat* nif = dynamic_cast<NameIDFormat*>(child.get());
if (nif) {
- child.release();
m_formats.push_back(nif);
+ child.release();
}
else {
RequestedAttribute* req = dynamic_cast<RequestedAttribute*>(child.get());
if (req) {
- child.release();
m_reqAttrs.push_back(req);
+ child.release();
}
else {
AttributeConsumingService* acs = dynamic_cast<AttributeConsumingService*>(child.get());
if (acs) {
- child.release();
m_attrConsumers.push_back(acs);
+ child.release();
}
else {
UIInfo* info = dynamic_cast<UIInfo*>(child.get());
if (info) {
if (!m_uiinfo) {
+ m_uiinfo.reset(info);
child.release();
- m_uiinfo = info;
}
else {
m_log.warn("skipping duplicate UIInfo element");
Organization* org = dynamic_cast<Organization*>(child.get());
if (org) {
if (!m_org) {
+ m_org.reset(org);
child.release();
- m_org = org;
}
else {
m_log.warn("skipping duplicate Organization element");
EntityAttributes* ea = dynamic_cast<EntityAttributes*>(child.get());
if (ea) {
if (!m_entityAttrs) {
+ m_entityAttrs.reset(ea);
child.release();
- m_entityAttrs = ea;
}
else {
m_log.warn("skipping duplicate EntityAttributes element");
{
SPConfig& conf = SPConfig::getConfig();
if (conf.isEnabled(SPConfig::InProcess) && !m_acl.empty()) {
- bool found = false;
- for (vector<IPRange>::const_iterator acl = m_acl.begin(); !found && acl != m_acl.end(); ++acl) {
- found = acl->contains(request.getRemoteAddr().c_str());
- }
- if (!found) {
+ static bool (IPRange::* contains)(const char*) const = &IPRange::contains;
+ if (find_if(m_acl.begin(), m_acl.end(), boost::bind(contains, _1, request.getRemoteAddr().c_str())) == m_acl.end()) {
m_log.error("request for metadata blocked from invalid address (%s)", request.getRemoteAddr().c_str());
istringstream msg("Metadata Request Blocked");
- return make_pair(true,request.sendResponse(msg, HTTPResponse::XMLTOOLING_HTTP_STATUS_FORBIDDEN));
+ return make_pair(true, request.sendResponse(msg, HTTPResponse::XMLTOOLING_HTTP_STATUS_FORBIDDEN));
}
}
return unwrap(request, out);
}
}
- catch (exception& ex) {
+ catch (std::exception& ex) {
m_log.error("error while processing request: %s", ex.what());
istringstream msg("Metadata Request Failed");
- return make_pair(true,request.sendResponse(msg, HTTPResponse::XMLTOOLING_HTTP_STATUS_ERROR));
+ return make_pair(true, request.sendResponse(msg, HTTPResponse::XMLTOOLING_HTTP_STATUS_ERROR));
}
}
// Wrap a response shim.
DDF ret(nullptr);
DDFJanitor jout(ret);
- auto_ptr<HTTPResponse> resp(getResponse(ret));
+ scoped_ptr<HTTPResponse> resp(getResponse(ret));
// Since we're remoted, the result should either be a throw, a false/0 return,
// which we just return as an empty structure, or a response/redirect,
// which we capture in the facade and send back.
- processMessage(*app, hurl, in["entity_id"].string(), *resp.get());
+ processMessage(*app, hurl, in["entity_id"].string(), *resp);
out << ret;
}
#ifndef SHIBSP_LITE
m_log.debug("processing metadata request");
- const PropertySet* relyingParty=nullptr;
+ const PropertySet* relyingParty = nullptr;
if (entityID) {
- MetadataProvider* m=application.getMetadataProvider();
+ MetadataProvider* m = application.getMetadataProvider();
Locker locker(m);
MetadataProviderCriteria mc(application, entityID);
relyingParty = application.getRelyingParty(m->getEntityDescriptor(mc).first);
relyingParty = &application;
}
- EntityDescriptor* entity;
+ scoped_ptr<EntityDescriptor> entity;
pair<bool,const char*> prop = getString("template");
if (prop.first) {
// Load a template to use for our metadata.
auto_ptr_XMLCh widenit(templ.c_str());
LocalFileInputSource src(widenit.get());
Wrapper4InputSource dsrc(&src,false);
- DOMDocument* doc=XMLToolingConfig::getConfig().getParser().parse(dsrc);
+ DOMDocument* doc = XMLToolingConfig::getConfig().getParser().parse(dsrc);
XercesJanitor<DOMDocument> docjan(doc);
auto_ptr<XMLObject> xmlobj(XMLObjectBuilder::buildOneFromElement(doc->getDocumentElement(), true));
docjan.release();
- entity = dynamic_cast<EntityDescriptor*>(xmlobj.get());
+ entity.reset(dynamic_cast<EntityDescriptor*>(xmlobj.get()));
+ xmlobj.release();
if (!entity)
throw ConfigurationException("Template file ($1) did not contain an EntityDescriptor", params(1, templ.c_str()));
- xmlobj.release();
}
else {
- entity = EntityDescriptorBuilder::buildEntityDescriptor();
+ entity.reset(EntityDescriptorBuilder::buildEntityDescriptor());
}
if (!entity->getID()) {
entity->setID(widenit.get());
}
- auto_ptr<EntityDescriptor> wrapper(entity);
pair<bool,unsigned int> cache = getUnsignedInt("cacheDuration");
if (cache.first) {
entity->setCacheDuration(cache.second);
if (m_org && !entity->getOrganization())
entity->setOrganization(m_org->cloneOrganization());
- for (vector<ContactPerson*>::const_iterator cp = m_contacts.begin(); cp != m_contacts.end(); ++cp)
- entity->getContactPersons().push_back((*cp)->cloneContactPerson());
+ for (ptr_vector<ContactPerson>::const_iterator cp = m_contacts.begin(); cp != m_contacts.end(); ++cp)
+ entity->getContactPersons().push_back(cp->cloneContactPerson());
if (m_entityAttrs) {
if (!entity->getExtensions())
role = entity->getSPSSODescriptors().front();
}
- for (vector<NameIDFormat*>::const_iterator nif = m_formats.begin(); nif != m_formats.end(); ++nif)
- role->getNameIDFormats().push_back((*nif)->cloneNameIDFormat());
+ for (ptr_vector<NameIDFormat>::const_iterator nif = m_formats.begin(); nif != m_formats.end(); ++nif)
+ role->getNameIDFormats().push_back(nif->cloneNameIDFormat());
if (m_uiinfo) {
if (!role->getExtensions())
role->getExtensions()->getUnknownXMLObjects().push_back(m_uiinfo->cloneUIInfo());
}
- for (vector<AttributeConsumingService*>::const_iterator acs = m_attrConsumers.begin(); acs != m_attrConsumers.end(); ++acs)
- role->getAttributeConsumingServices().push_back((*acs)->cloneAttributeConsumingService());
+ for (ptr_vector<AttributeConsumingService>::const_iterator acs = m_attrConsumers.begin(); acs != m_attrConsumers.end(); ++acs)
+ role->getAttributeConsumingServices().push_back(acs->cloneAttributeConsumingService());
if (!m_reqAttrs.empty()) {
int index = 1;
const vector<AttributeConsumingService*>& svcs = const_cast<const SPSSODescriptor*>(role)->getAttributeConsumingServices();
- for (vector<AttributeConsumingService*>::const_iterator s =svcs.begin(); s != svcs.end(); ++s) {
- pair<bool,int> i = (*s)->getIndex();
+ for (indirect_iterator<vector<AttributeConsumingService*>::const_iterator> s = make_indirect_iterator(svcs.begin());
+ s != make_indirect_iterator(svcs.end()); ++s) {
+ pair<bool,int> i = s->getIndex();
if (i.first && index == i.second)
index = i.second + 1;
}
sn->setName(entity->getEntityID());
static const XMLCh english[] = UNICODE_LITERAL_2(e,n);
sn->setLang(english);
- for (vector<RequestedAttribute*>::const_iterator req = m_reqAttrs.begin(); req != m_reqAttrs.end(); ++req)
- svc->getRequestedAttributes().push_back((*req)->cloneRequestedAttribute());
+ for (ptr_vector<RequestedAttribute>::const_iterator req = m_reqAttrs.begin(); req != m_reqAttrs.end(); ++req)
+ svc->getRequestedAttributes().push_back(req->cloneRequestedAttribute());
}
// Policy flags.
// Ask each handler to generate itself.
vector<const Handler*> handlers;
application.getHandlers(handlers);
- for (vector<const Handler*>::const_iterator h = handlers.begin(); h != handlers.end(); ++h) {
+ for (indirect_iterator<vector<const Handler*>::const_iterator> h = make_indirect_iterator(handlers.begin());
+ h != make_indirect_iterator(handlers.end()); ++h) {
if (m_bases.empty()) {
if (strncmp(handlerURL, "https", 5) == 0) {
if (m_https >= 0)
- (*h)->generateMetadata(*role, handlerURL);
+ h->generateMetadata(*role, handlerURL);
if (m_http == 1) {
string temp(handlerURL);
temp.erase(4, 1);
- (*h)->generateMetadata(*role, temp.c_str());
+ h->generateMetadata(*role, temp.c_str());
}
}
else {
if (m_http >= 0)
- (*h)->generateMetadata(*role, handlerURL);
+ h->generateMetadata(*role, handlerURL);
if (m_https == 1) {
string temp(handlerURL);
temp.insert(temp.begin() + 4, 's');
- (*h)->generateMetadata(*role, temp.c_str());
+ h->generateMetadata(*role, temp.c_str());
}
}
}
else {
for (vector<string>::const_iterator b = m_bases.begin(); b != m_bases.end(); ++b)
- (*h)->generateMetadata(*role, b->c_str());
+ h->generateMetadata(*role, b->c_str());
}
}
stringstream pretty;
XMLHelper::serialize(entity->marshall(), pretty, true);
DOMDocument* prettydoc = XMLToolingConfig::getConfig().getParser().parse(pretty);
- auto_ptr<XMLObject> prettyentity(XMLObjectBuilder::buildOneFromElement(prettydoc->getDocumentElement(), true));
+ scoped_ptr<XMLObject> prettyentity(XMLObjectBuilder::buildOneFromElement(prettydoc->getDocumentElement(), true));
Signature* sig = SignatureBuilder::buildSignature();
dynamic_cast<EntityDescriptor*>(prettyentity.get())->setSignature(sig);
#include "handler/RemotedHandler.h"
#include <algorithm>
+#include <boost/scoped_ptr.hpp>
#include <xmltooling/unicode.h>
#include <xercesc/util/Base64.hpp>
using namespace opensaml;
using namespace xmltooling;
using namespace xercesc;
+using namespace boost;
using namespace std;
#ifndef SHIBSP_LITE
public HTTPRequest
{
DDF& m_input;
- mutable CGIParser* m_parser;
+ mutable scoped_ptr<CGIParser> m_parser;
mutable vector<XSECCryptoX509*> m_certs;
#ifdef SHIBSP_HAVE_GSSAPI
mutable gss_ctx_id_t m_gss;
virtual ~RemotedRequest() {
for_each(m_certs.begin(), m_certs.end(), xmltooling::cleanup<XSECCryptoX509>());
- delete m_parser;
#ifdef SHIBSP_HAVE_GSSAPI
if (m_gss != GSS_C_NO_CONTEXT) {
OM_uint32 minor;
const char* RemotedRequest::getParameter(const char* name) const
{
if (!m_parser)
- m_parser=new CGIParser(*this);
+ m_parser.reset(new CGIParser(*this));
- pair<CGIParser::walker,CGIParser::walker> bounds=m_parser->getParameters(name);
+ pair<CGIParser::walker,CGIParser::walker> bounds = m_parser->getParameters(name);
return (bounds.first==bounds.second) ? nullptr : bounds.first->second;
}
std::vector<const char*>::size_type RemotedRequest::getParameters(const char* name, std::vector<const char*>& values) const
{
if (!m_parser)
- m_parser=new CGIParser(*this);
+ m_parser.reset(new CGIParser(*this));
- pair<CGIParser::walker,CGIParser::walker> bounds=m_parser->getParameters(name);
- while (bounds.first!=bounds.second) {
+ pair<CGIParser::walker,CGIParser::walker> bounds = m_parser->getParameters(name);
+ while (bounds.first != bounds.second) {
values.push_back(bounds.first->second);
++bounds.first;
}
x509->loadX509PEM(cert.string(), cert.strlen());
else
x509->loadX509Base64Bin(cert.string(), cert.strlen());
- m_certs.push_back(x509.release());
+ m_certs.push_back(x509.get());
+ x509.release();
}
catch(XSECException& e) {
auto_ptr_char temp(e.getMsg());
string msg;
char buf[1024];
while (in) {
- in.read(buf,1024);
- msg.append(buf,in.gcount());
+ in.read(buf, 1024);
+ msg.append(buf, in.gcount());
}
if (!m_output.isstruct())
m_output.structure();
if (!conf.isEnabled(SPConfig::InProcess)) {
ListenerService* listener = conf.getServiceProvider()->getListenerService(false);
if (listener)
- listener->regListener(m_address.c_str(),this);
+ listener->regListener(m_address.c_str(), this);
else
Category::getInstance(SHIBSP_LOGCAT".Handler").info("no ListenerService available, handler remoting disabled");
}
string hdr;
DDF hin = in.addmember("headers").structure();
if (headers) {
- for (vector<string>::const_iterator h = headers->begin(); h!=headers->end(); ++h) {
+ for (vector<string>::const_iterator h = headers->begin(); h != headers->end(); ++h) {
hdr = request.getHeader(h->c_str());
if (!hdr.empty())
hin.addmember(h->c_str()).unsafe_string(hdr.c_str());
istringstream s(h["data"].string());
return make_pair(true, request.sendResponse(s, h["status"].integer()));
}
- return make_pair(false,0L);
+ return make_pair(false, 0L);
}
HTTPRequest* RemotedHandler::getRequest(DDF& in) const
# include "SessionCache.h"
# include "TransactionLog.h"
# include "attribute/resolver/ResolutionContext.h"
+# include <boost/scoped_ptr.hpp>
+# include <boost/iterator/indirect_iterator.hpp>
# include <saml/exceptions.h>
# include <saml/SAMLConfig.h>
# include <saml/binding/SecurityPolicy.h>
using namespace opensaml::saml1;
using namespace opensaml::saml1p;
using namespace opensaml;
+using namespace boost;
using saml2::NameID;
using saml2::NameIDBuilder;
using saml2md::EntityDescriptor;
SAML1Consumer(const DOMElement* e, const char* appId)
: AssertionConsumerService(e, appId, Category::getInstance(SHIBSP_LOGCAT".SSO.SAML1")) {
#ifndef SHIBSP_LITE
- m_ssoRule = nullptr;
m_post = XMLString::equals(getString("Binding").second, samlconstants::SAML1_PROFILE_BROWSER_POST);
if (SPConfig::getConfig().isEnabled(SPConfig::OutOfProcess))
- m_ssoRule = SAMLConfig::getConfig().SecurityPolicyRuleManager.newPlugin(SAML1BROWSERSSO_POLICY_RULE, e);
-#endif
- }
- virtual ~SAML1Consumer() {
-#ifndef SHIBSP_LITE
- delete m_ssoRule;
+ m_ssoRule.reset(SAMLConfig::getConfig().SecurityPolicyRuleManager.newPlugin(SAML1BROWSERSSO_POLICY_RULE, e));
#endif
}
+ virtual ~SAML1Consumer() {}
#ifndef SHIBSP_LITE
void generateMetadata(SPSSODescriptor& role, const char* handlerURL) const {
) const;
bool m_post;
- SecurityPolicyRule* m_ssoRule;
+ scoped_ptr<SecurityPolicyRule> m_ssoRule;
#else
const XMLCh* getProtocolFamily() const {
return samlconstants::SAML11_PROTOCOL_ENUM;
// Ensure the BrowserSSO rule is in the policy set.
if (find_if(policy.getRules(), _rulenamed(SAML1BROWSERSSO_POLICY_RULE)) == nullptr)
- policy.getRules().push_back(m_ssoRule);
+ policy.getRules().push_back(m_ssoRule.get());
// Populate recipient as audience.
policy.getAudiences().push_back(application.getRelyingParty(entity)->getXMLString("entityID").second);
time_t now = time(nullptr);
- for (vector<saml1::Assertion*>::const_iterator a = assertions.begin(); a!=assertions.end(); ++a) {
+ for (indirect_iterator<vector<saml1::Assertion*>::const_iterator> a = make_indirect_iterator(assertions.begin());
+ a != make_indirect_iterator(assertions.end()); ++a) {
try {
// Skip unsigned assertion?
- if (!(*a)->getSignature() && flag.first && flag.second)
+ if (!a->getSignature() && flag.first && flag.second)
throw SecurityPolicyException("The incoming assertion was unsigned, violating local security policy.");
// We clear the security flag, so we can tell whether the token was secured on its own.
// Extract message bits and re-verify Issuer information.
extractMessageDetails(
- *(*a),
- (minor.first && minor.second==0) ? samlconstants::SAML10_PROTOCOL_ENUM : samlconstants::SAML11_PROTOCOL_ENUM, policy
+ *a, (minor.first && minor.second==0) ? samlconstants::SAML10_PROTOCOL_ENUM : samlconstants::SAML11_PROTOCOL_ENUM, policy
);
// Run the policy over the assertion. Handles replay, freshness, and
// signature verification, assuming the relevant rules are configured,
// along with condition and profile enforcement.
- policy.evaluate(*(*a), &httpRequest);
+ policy.evaluate(*a, &httpRequest);
// If no security is in place now, we kick it.
if (!alreadySecured && !policy.isAuthenticated())
throw SecurityPolicyException("Unable to establish security of incoming assertion.");
// Track it as a valid token.
- tokens.push_back(*a);
+ tokens.push_back(&(*a));
// Save off the first valid SSO statement.
const vector<AuthenticationStatement*>& statements =
- const_cast<const saml1::Assertion*>(*a)->getAuthenticationStatements();
- for (vector<AuthenticationStatement*>::const_iterator s = statements.begin(); s!=statements.end(); ++s) {
- if ((*s)->getAuthenticationInstant() &&
- (*s)->getAuthenticationInstantEpoch() - XMLToolingConfig::getConfig().clock_skew_secs > now) {
+ const_cast<const saml1::Assertion&>(*a).getAuthenticationStatements();
+ for (indirect_iterator<vector<AuthenticationStatement*>::const_iterator> s = make_indirect_iterator(statements.begin());
+ s != make_indirect_iterator(statements.end()); ++s) {
+ if (s->getAuthenticationInstant() &&
+ s->getAuthenticationInstantEpoch() - XMLToolingConfig::getConfig().clock_skew_secs > now) {
contextualError = "The login time at your identity provider was future-dated.";
}
- else if (authnskew.first && authnskew.second && (*s)->getAuthenticationInstant() &&
- (*s)->getAuthenticationInstantEpoch() <= now && (now - (*s)->getAuthenticationInstantEpoch() > authnskew.second)) {
+ else if (authnskew.first && authnskew.second && s->getAuthenticationInstant() &&
+ s->getAuthenticationInstantEpoch() <= now && (now - s->getAuthenticationInstantEpoch() > authnskew.second)) {
contextualError = "The gap between now and the time you logged into your identity provider exceeds the allowed limit.";
}
- else if (authnskew.first && authnskew.second && (*s)->getAuthenticationInstant() == nullptr) {
+ else if (authnskew.first && authnskew.second && s->getAuthenticationInstant() == nullptr) {
contextualError = "Your identity provider did not supply a time of login, violating local policy.";
}
else if (!ssoStatement) {
- ssoStatement = *s;
+ ssoStatement = &(*s);
break;
}
}
}
- catch (exception& ex) {
+ catch (std::exception& ex) {
m_log.warn("detected a problem with assertion: %s", ex.what());
if (!ssoStatement)
contextualError = ex.what();
- badtokens.push_back(*a);
+ badtokens.push_back(&(*a));
}
}
// To complete processing, we need to extract and resolve attributes and then create the session.
// Normalize the SAML 1.x NameIdentifier...
- auto_ptr<NameID> nameid(n ? NameIDBuilder::buildNameID() : nullptr);
+ scoped_ptr<NameID> nameid(n ? NameIDBuilder::buildNameID() : nullptr);
if (n) {
nameid->setName(n->getName());
nameid->setFormat(n->getFormat());
}
// The context will handle deleting attributes and new tokens.
- auto_ptr<ResolutionContext> ctx(
+ scoped_ptr<ResolutionContext> ctx(
resolveAttributes(
application,
policy.getIssuerMetadata(),
)
);
- if (ctx.get()) {
+ if (ctx) {
// Copy over any new tokens, but leave them in the context for cleanup.
tokens.insert(tokens.end(), ctx->getResolvedAssertions().begin(), ctx->getResolvedAssertions().end());
}
ssoStatement->getAuthenticationMethod(),
nullptr,
&tokens,
- ctx.get() ? &ctx->getResolvedAttributes() : nullptr
+ ctx ? &ctx->getResolvedAttributes() : nullptr
);
- auto_ptr<LoginEvent> login_event(newLoginEvent(application, httpRequest));
- if (login_event.get()) {
+ scoped_ptr<LoginEvent> login_event(newLoginEvent(application, httpRequest));
+ if (login_event) {
login_event->m_sessionID = session_id.c_str();
login_event->m_peer = entity;
auto_ptr_char prot(
login_event->m_nameID = nameid.get();
login_event->m_saml1AuthnStatement = ssoStatement;
login_event->m_saml1Response = response;
- if (ctx.get())
+ if (ctx)
login_event->m_attributes = &ctx->getResolvedAttributes();
application.getServiceProvider().getTransactionLog()->write(*login_event);
}
# include "lite/SAMLConstants.h"
#endif
+#include <boost/scoped_ptr.hpp>
#include <xmltooling/soap/SOAP.h>
using namespace shibspconstants;
using namespace shibsp;
using namespace soap11;
using namespace xmltooling;
+using namespace boost;
using namespace std;
namespace shibsp {
{
public:
SAML2ArtifactResolution(const DOMElement* e, const char* appId);
- virtual ~SAML2ArtifactResolution();
+ virtual ~SAML2ArtifactResolution() {}
pair<bool,long> run(SPRequest& request, bool isHandler=true) const;
void receive(DDF& in, ostream& out);
hurl += loc;
auto_ptr_XMLCh widen(hurl.c_str());
- ArtifactResolutionService* ep = ArtifactResolutionServiceBuilder::buildArtifactResolutionService();
+ auto_ptr<ArtifactResolutionService> ep(ArtifactResolutionServiceBuilder::buildArtifactResolutionService());
ep->setLocation(widen.get());
ep->setBinding(getXMLString("Binding").second);
ep->setIndex(ix.second);
- role.getArtifactResolutionServices().push_back(ep);
+ role.getArtifactResolutionServices().push_back(ep.get());
+ ep.release();
}
#endif
const XMLCh* getProtocolFamily() const {
const Application& app, const ArtifactResolve& request, HTTPResponse& httpResponse, const EntityDescriptor* recipient
) const;
- MessageEncoder* m_encoder;
- MessageDecoder* m_decoder;
- xmltooling::QName m_role;
+ scoped_ptr<MessageEncoder> m_encoder;
+ scoped_ptr<MessageDecoder> m_decoder;
#endif
};
SAML2ArtifactResolution::SAML2ArtifactResolution(const DOMElement* e, const char* appId)
: AbstractHandler(e, Category::getInstance(SHIBSP_LOGCAT".ArtifactResolution.SAML2"))
-#ifndef SHIBSP_LITE
- ,m_encoder(nullptr), m_decoder(nullptr), m_role(samlconstants::SAML20MD_NS, opensaml::saml2md::IDPSSODescriptor::LOCAL_NAME)
-#endif
{
#ifndef SHIBSP_LITE
if (SPConfig::getConfig().isEnabled(SPConfig::OutOfProcess)) {
- try {
- m_encoder = SAMLConfig::getConfig().MessageEncoderManager.newPlugin(
- getString("Binding").second,pair<const DOMElement*,const XMLCh*>(e,nullptr)
- );
- m_decoder = SAMLConfig::getConfig().MessageDecoderManager.newPlugin(
- getString("Binding").second,pair<const DOMElement*,const XMLCh*>(e,nullptr)
- );
- }
- catch (exception&) {
- m_log.error("error building MessageEncoder/Decoder pair for binding (%s)", getString("Binding").second);
- delete m_encoder;
- delete m_decoder;
- throw;
- }
+ m_encoder.reset(
+ SAMLConfig::getConfig().MessageEncoderManager.newPlugin(
+ getString("Binding").second, pair<const DOMElement*,const XMLCh*>(e,shibspconstants::SHIB2SPCONFIG_NS)
+ )
+ );
+ m_decoder.reset(
+ SAMLConfig::getConfig().MessageDecoderManager.newPlugin(
+ getString("Binding").second, pair<const DOMElement*,const XMLCh*>(e,shibspconstants::SHIB2SPCONFIG_NS)
+ )
+ );
}
#endif
string address(appId);
setAddress(address.c_str());
}
-SAML2ArtifactResolution::~SAML2ArtifactResolution()
-{
-#ifndef SHIBSP_LITE
- delete m_encoder;
- delete m_decoder;
-#endif
-}
-
pair<bool,long> SAML2ArtifactResolution::run(SPRequest& request, bool isHandler) const
{
string relayState;
DDF out,in = wrap(request, nullptr, true);
DDFJanitor jin(in), jout(out);
- out=request.getServiceProvider().getListenerService()->send(in);
+ out = request.getServiceProvider().getListenerService()->send(in);
return unwrap(request, out);
}
}
- catch (exception& ex) {
+ catch (std::exception& ex) {
m_log.error("error while processing request: %s", ex.what());
// Build a SOAP fault around the error.
return make_pair(true, ret);
#else
// Brute force the fault to avoid library dependency.
- auto_ptr<Envelope> env(EnvelopeBuilder::buildEnvelope());
+ scoped_ptr<Envelope> env(EnvelopeBuilder::buildEnvelope());
Body* body = BodyBuilder::buildBody();
env->setBody(body);
- body->getUnknownXMLObjects().push_back(fault.release());
+ body->getUnknownXMLObjects().push_back(fault.get());
+ fault.release();
string xmlbuf;
XMLHelper::serialize(env->marshall(), xmlbuf);
istringstream s(xmlbuf);
}
// Unpack the request.
- auto_ptr<HTTPRequest> req(getRequest(in));
+ scoped_ptr<HTTPRequest> req(getRequest(in));
//m_log.debug("found %d client certificates", req->getClientCertificates().size());
// Wrap a response shim.
DDF ret(nullptr);
DDFJanitor jout(ret);
- auto_ptr<HTTPResponse> resp(getResponse(ret));
+ scoped_ptr<HTTPResponse> resp(getResponse(ret));
try {
// Since we're remoted, the result should either be a throw, a false/0 return,
// which we just return as an empty structure, or a response/redirect,
// which we capture in the facade and send back.
- processMessage(*app, *req.get(), *resp.get());
+ processMessage(*app, *req, *resp);
out << ret;
}
- catch (exception& ex) {
+ catch (std::exception& ex) {
#ifndef SHIBSP_LITE
m_log.error("error while processing request: %s", ex.what());
pair<bool,bool> flag = getBool("detailedErrors", m_configNS.get());
auto_ptr_XMLCh msg((flag.first && flag.second) ? ex.what() : "Error processing request.");
fs->setString(msg.get());
- m_encoder->encode(*resp.get(), fault.get(), nullptr);
+ m_encoder->encode(*resp, fault.get(), nullptr);
fault.release();
out << ret;
#else
Locker metadataLocker(application.getMetadataProvider());
// Create the policy.
- auto_ptr<SecurityPolicy> policy(
- application.getServiceProvider().getSecurityPolicyProvider()->createSecurityPolicy(application, &m_role, policyId.second)
+ scoped_ptr<SecurityPolicy> policy(
+ application.getServiceProvider().getSecurityPolicyProvider()->createSecurityPolicy(application, &IDPSSODescriptor::ELEMENT_QNAME, policyId.second)
);
// Decode the message and verify that it's a secured ArtifactResolve request.
string relayState;
- auto_ptr<XMLObject> msg(m_decoder->decode(relayState, httpRequest, *policy.get()));
- if (!msg.get())
+ scoped_ptr<XMLObject> msg(m_decoder->decode(relayState, httpRequest, *policy));
+ if (!msg)
throw BindingException("Failed to decode a SAML request.");
const ArtifactResolve* req = dynamic_cast<const ArtifactResolve*>(msg.get());
if (!req)
m_log.info("resolving artifact (%s) for (%s)", artifact.get(), issuer.get() ? issuer.get() : "unknown");
// Parse the artifact and retrieve the object.
- auto_ptr<SAMLArtifact> artobj(SAMLArtifact::parse(artifact.get()));
+ scoped_ptr<SAMLArtifact> artobj(SAMLArtifact::parse(artifact.get()));
auto_ptr<XMLObject> payload(artmap->retrieveContent(artobj.get(), issuer.get()));
if (!policy->isAuthenticated()) {
resp->setInResponseTo(req->getID());
Issuer* me = IssuerBuilder::buildIssuer();
me->setName(application.getRelyingParty(entity)->getXMLString("entityID").second);
- resp->setPayload(payload.release());
+ resp->setPayload(payload.get());
+ payload.release();
long ret = sendMessage(
*m_encoder, resp.get(), relayState.c_str(), nullptr, policy->getIssuerMetadata(), application, httpResponse, "signResponses"
);
resp.release(); // freed by encoder
- return make_pair(true,ret);
+ return make_pair(true, ret);
}
- catch (exception& ex) {
+ catch (std::exception& ex) {
// Trap localized errors.
m_log.error("error processing artifact request: %s", ex.what());
return emptyResponse(application, *req, httpResponse, entity);
resp->setInResponseTo(request.getID());
Issuer* me = IssuerBuilder::buildIssuer();
me->setName(app.getRelyingParty(recipient)->getXMLString("entityID").second);
- fillStatus(*resp.get(), StatusCode::SUCCESS);
+ fillStatus(*resp, StatusCode::SUCCESS);
long ret = m_encoder->encode(httpResponse, resp.get(), nullptr);
resp.release(); // freed by encoder
- return make_pair(true,ret);
+ return make_pair(true, ret);
}
#endif
# include "SessionCache.h"
# include "TransactionLog.h"
# include "attribute/resolver/ResolutionContext.h"
+# include <boost/scoped_ptr.hpp>
+# include <boost/iterator/indirect_iterator.hpp>
# include <saml/exceptions.h>
# include <saml/SAMLConfig.h>
# include <saml/binding/SecurityPolicyRule.h>
using namespace opensaml::saml2p;
using namespace opensaml::saml2md;
using namespace opensaml;
+using namespace boost;
# ifndef min
# define min(a,b) (((a) < (b)) ? (a) : (b))
# endif
SAML2Consumer(const DOMElement* e, const char* appId)
: AssertionConsumerService(e, appId, Category::getInstance(SHIBSP_LOGCAT".SSO.SAML2")) {
#ifndef SHIBSP_LITE
- m_ssoRule = nullptr;
if (SPConfig::getConfig().isEnabled(SPConfig::OutOfProcess))
- m_ssoRule = SAMLConfig::getConfig().SecurityPolicyRuleManager.newPlugin(BEARER_POLICY_RULE, e);
-#endif
- }
- virtual ~SAML2Consumer() {
-#ifndef SHIBSP_LITE
- delete m_ssoRule;
+ m_ssoRule.reset(SAMLConfig::getConfig().SecurityPolicyRuleManager.newPlugin(BEARER_POLICY_RULE, e));
#endif
}
+ virtual ~SAML2Consumer() {}
#ifndef SHIBSP_LITE
void generateMetadata(SPSSODescriptor& role, const char* handlerURL) const {
const XMLObject& xmlObject
) const;
- SecurityPolicyRule* m_ssoRule;
+ scoped_ptr<SecurityPolicyRule> m_ssoRule;
#else
const XMLCh* getProtocolFamily() const {
return samlconstants::SAML20P_NS;
vector<const opensaml::Assertion*> badtokens;
// And also track "owned" tokens that we decrypt here.
- vector<saml2::Assertion*> ownedtokens;
+ vector< boost::shared_ptr<saml2::Assertion> > ownedtokens;
// With this flag on, we ignore any unsigned assertions.
const EntityDescriptor* entity = nullptr;
// Ensure the Bearer rule is in the policy set.
if (find_if(policy.getRules(), _rulenamed(BEARER_POLICY_RULE)) == nullptr)
- policy.getRules().push_back(m_ssoRule);
+ policy.getRules().push_back(m_ssoRule.get());
// Populate recipient as audience.
policy.getAudiences().push_back(application.getRelyingParty(entity)->getXMLString("entityID").second);
time_t now = time(nullptr);
- for (vector<saml2::Assertion*>::const_iterator a = assertions.begin(); a!=assertions.end(); ++a) {
+ for (indirect_iterator<vector<saml2::Assertion*>::const_iterator> a = make_indirect_iterator(assertions.begin());
+ a != make_indirect_iterator(assertions.end()); ++a) {
try {
// Skip unsigned assertion?
- if (!(*a)->getSignature() && flag.first && flag.second)
+ if (!a->getSignature() && flag.first && flag.second)
throw SecurityPolicyException("The incoming assertion was unsigned, violating local security policy.");
// We clear the security flag, so we can tell whether the token was secured on its own.
policy.reset(true);
// Extract message bits and re-verify Issuer information.
- extractMessageDetails(*(*a), samlconstants::SAML20P_NS, policy);
+ extractMessageDetails(*a, samlconstants::SAML20P_NS, policy);
// Run the policy over the assertion. Handles replay, freshness, and
// signature verification, assuming the relevant rules are configured,
// along with condition and profile enforcement.
- policy.evaluate(*(*a), &httpRequest);
+ policy.evaluate(*a, &httpRequest);
// If no security is in place now, we kick it.
if (!alreadySecured && !policy.isAuthenticated())
if (!entity && policy.getIssuerMetadata()) {
entity = dynamic_cast<const EntityDescriptor*>(policy.getIssuerMetadata()->getParent());
flag = application.getRelyingParty(entity)->getBool("requireSignedAssertions");
- if (!(*a)->getSignature() && flag.first && flag.second)
+ if (!a->getSignature() && flag.first && flag.second)
throw SecurityPolicyException("The incoming assertion was unsigned, violating local security policy.");
}
}
// Track it as a valid token.
- tokens.push_back(*a);
+ tokens.push_back(&(*a));
// Save off the first valid SSO statement, but favor the "soonest" session expiration.
- const vector<AuthnStatement*>& statements = const_cast<const saml2::Assertion*>(*a)->getAuthnStatements();
- for (vector<AuthnStatement*>::const_iterator s = statements.begin(); s!=statements.end(); ++s) {
- if ((*s)->getAuthnInstant() && (*s)->getAuthnInstantEpoch() - XMLToolingConfig::getConfig().clock_skew_secs > now) {
+ const vector<AuthnStatement*>& statements = const_cast<const saml2::Assertion&>(*a).getAuthnStatements();
+ for (indirect_iterator<vector<AuthnStatement*>::const_iterator> s = make_indirect_iterator(statements.begin());
+ s != make_indirect_iterator(statements.end()); ++s) {
+ if (s->getAuthnInstant() && s->getAuthnInstantEpoch() - XMLToolingConfig::getConfig().clock_skew_secs > now) {
contextualError = "The login time at your identity provider was future-dated.";
}
- else if (authnskew.first && authnskew.second && (*s)->getAuthnInstant() &&
- (*s)->getAuthnInstantEpoch() <= now && (now - (*s)->getAuthnInstantEpoch() > authnskew.second)) {
+ else if (authnskew.first && authnskew.second && s->getAuthnInstant() &&
+ s->getAuthnInstantEpoch() <= now && (now - s->getAuthnInstantEpoch() > authnskew.second)) {
contextualError = "The gap between now and the time you logged into your identity provider exceeds the allowed limit.";
}
- else if (authnskew.first && authnskew.second && (*s)->getAuthnInstant() == nullptr) {
+ else if (authnskew.first && authnskew.second && s->getAuthnInstant() == nullptr) {
contextualError = "Your identity provider did not supply a time of login, violating local policy.";
}
- else if (!ssoStatement || (*s)->getSessionNotOnOrAfterEpoch() < ssoStatement->getSessionNotOnOrAfterEpoch()) {
- ssoStatement = *s;
+ else if (!ssoStatement || s->getSessionNotOnOrAfterEpoch() < ssoStatement->getSessionNotOnOrAfterEpoch()) {
+ ssoStatement = &(*s);
}
}
// Save off the first valid Subject, but favor an unencrypted NameID over anything else.
- if (!ssoSubject || (!ssoSubject->getNameID() && (*a)->getSubject()->getNameID()))
- ssoSubject = (*a)->getSubject();
+ if (!ssoSubject || (!ssoSubject->getNameID() && a->getSubject()->getNameID()))
+ ssoSubject = a->getSubject();
}
- catch (exception& ex) {
+ catch (std::exception& ex) {
m_log.warn("detected a problem with assertion: %s", ex.what());
if (!ssoStatement)
contextualError = ex.what();
- badtokens.push_back(*a);
+ badtokens.push_back(&(*a));
}
}
if (!cr && !encassertions.empty())
m_log.warn("found encrypted assertions, but no CredentialResolver was available");
- for (vector<saml2::EncryptedAssertion*>::const_iterator ea = encassertions.begin(); cr && ea!=encassertions.end(); ++ea) {
+ for (indirect_iterator<vector<saml2::EncryptedAssertion*>::const_iterator> ea = make_indirect_iterator(encassertions.begin());
+ ea != make_indirect_iterator(encassertions.end()); ++ea) {
// Attempt to decrypt it.
- saml2::Assertion* decrypted=nullptr;
+ boost::shared_ptr<saml2::Assertion> decrypted;
try {
Locker credlocker(cr);
- auto_ptr<MetadataCredentialCriteria> mcc(
+ scoped_ptr<MetadataCredentialCriteria> mcc(
policy.getIssuerMetadata() ? new MetadataCredentialCriteria(*policy.getIssuerMetadata()) : nullptr
);
- auto_ptr<XMLObject> wrapper((*ea)->decrypt(*cr, application.getRelyingParty(entity)->getXMLString("entityID").second, mcc.get()));
- decrypted = dynamic_cast<saml2::Assertion*>(wrapper.get());
+ boost::shared_ptr<XMLObject> wrapper(ea->decrypt(*cr, application.getRelyingParty(entity)->getXMLString("entityID").second, mcc.get()));
+ decrypted = dynamic_pointer_cast<saml2::Assertion>(wrapper);
if (decrypted) {
- wrapper.release();
ownedtokens.push_back(decrypted);
if (m_log.isDebugEnabled())
m_log.debugStream() << "decrypted Assertion: " << *decrypted << logging::eol;
}
}
- catch (exception& ex) {
+ catch (std::exception& ex) {
m_log.error(ex.what());
}
if (!decrypted)
}
// Track it as a valid token.
- tokens.push_back(decrypted);
+ tokens.push_back(decrypted.get());
// Save off the first valid SSO statement, but favor the "soonest" session expiration.
- const vector<AuthnStatement*>& statements = const_cast<const saml2::Assertion*>(decrypted)->getAuthnStatements();
- for (vector<AuthnStatement*>::const_iterator s = statements.begin(); s!=statements.end(); ++s) {
- if (authnskew.first && authnskew.second && (*s)->getAuthnInstant() && (now - (*s)->getAuthnInstantEpoch() > authnskew.second))
+ const vector<AuthnStatement*>& statements = const_cast<const saml2::Assertion*>(decrypted.get())->getAuthnStatements();
+ for (indirect_iterator<vector<AuthnStatement*>::const_iterator> s = make_indirect_iterator(statements.begin());
+ s != make_indirect_iterator(statements.end()); ++s) {
+ if (authnskew.first && authnskew.second && s->getAuthnInstant() && (now - s->getAuthnInstantEpoch() > authnskew.second))
contextualError = "The gap between now and the time you logged into your identity provider exceeds the limit.";
- else if (!ssoStatement || (*s)->getSessionNotOnOrAfterEpoch() < ssoStatement->getSessionNotOnOrAfterEpoch())
- ssoStatement = *s;
+ else if (!ssoStatement || s->getSessionNotOnOrAfterEpoch() < ssoStatement->getSessionNotOnOrAfterEpoch())
+ ssoStatement = &(*s);
}
// Save off the first valid Subject, but favor an unencrypted NameID over anything else.
if (!ssoSubject || (!ssoSubject->getNameID() && decrypted->getSubject()->getNameID()))
ssoSubject = decrypted->getSubject();
}
- catch (exception& ex) {
+ catch (std::exception& ex) {
m_log.warn("detected a problem with assertion: %s", ex.what());
if (!ssoStatement)
contextualError = ex.what();
- badtokens.push_back(decrypted);
+ badtokens.push_back(decrypted.get());
}
}
if (!ssoStatement) {
- for_each(ownedtokens.begin(), ownedtokens.end(), xmltooling::cleanup<saml2::Assertion>());
if (contextualError.empty())
throw FatalProfileException("A valid authentication statement was not found in the incoming message.");
throw FatalProfileException(contextualError.c_str());
}
// May need to decrypt NameID.
- bool ownedName = false;
+ scoped_ptr<XMLObject> decryptedID;
NameID* ssoName = ssoSubject->getNameID();
if (!ssoName) {
EncryptedID* encname = ssoSubject->getEncryptedID();
m_log.warn("found encrypted NameID, but no decryption credential was available");
else {
Locker credlocker(cr);
- auto_ptr<MetadataCredentialCriteria> mcc(
+ scoped_ptr<MetadataCredentialCriteria> mcc(
policy.getIssuerMetadata() ? new MetadataCredentialCriteria(*policy.getIssuerMetadata()) : nullptr
);
try {
- auto_ptr<XMLObject> decryptedID(encname->decrypt(*cr,application.getRelyingParty(entity)->getXMLString("entityID").second,mcc.get()));
+ decryptedID.reset(encname->decrypt(*cr, application.getRelyingParty(entity)->getXMLString("entityID").second, mcc.get()));
ssoName = dynamic_cast<NameID*>(decryptedID.get());
if (ssoName) {
- ownedName = true;
- decryptedID.release();
if (m_log.isDebugEnabled())
m_log.debugStream() << "decrypted NameID: " << *ssoName << logging::eol;
}
}
- catch (exception& ex) {
+ catch (std::exception& ex) {
m_log.error(ex.what());
}
}
const AuthnContext* authnContext = ssoStatement->getAuthnContext();
- try {
- // The context will handle deleting attributes and new tokens.
- auto_ptr<ResolutionContext> ctx(
- resolveAttributes(
- application,
- policy.getIssuerMetadata(),
- samlconstants::SAML20P_NS,
- nullptr,
- nullptr,
- ssoName,
- ssoStatement,
- (authnContext && authnContext->getAuthnContextClassRef()) ? authnContext->getAuthnContextClassRef()->getReference() : nullptr,
- (authnContext && authnContext->getAuthnContextDeclRef()) ? authnContext->getAuthnContextDeclRef()->getReference() : nullptr,
- &tokens
- )
- );
-
- if (ctx.get()) {
- // Copy over any new tokens, but leave them in the context for cleanup.
- tokens.insert(tokens.end(), ctx->getResolvedAssertions().begin(), ctx->getResolvedAssertions().end());
- }
-
- // Now merge in bad tokens for caching.
- tokens.insert(tokens.end(), badtokens.begin(), badtokens.end());
-
- string session_id;
- application.getServiceProvider().getSessionCache()->insert(
- session_id,
+ // The context will handle deleting attributes and new tokens.
+ scoped_ptr<ResolutionContext> ctx(
+ resolveAttributes(
application,
- httpRequest,
- httpResponse,
- sessionExp,
- entity,
+ policy.getIssuerMetadata(),
samlconstants::SAML20P_NS,
+ nullptr,
+ nullptr,
ssoName,
- ssoStatement->getAuthnInstant() ? ssoStatement->getAuthnInstant()->getRawData() : nullptr,
- ssoStatement->getSessionIndex(),
+ ssoStatement,
(authnContext && authnContext->getAuthnContextClassRef()) ? authnContext->getAuthnContextClassRef()->getReference() : nullptr,
(authnContext && authnContext->getAuthnContextDeclRef()) ? authnContext->getAuthnContextDeclRef()->getReference() : nullptr,
- &tokens,
- ctx.get() ? &ctx->getResolvedAttributes() : nullptr
- );
+ &tokens
+ )
+ );
- try {
- auto_ptr<TransactionLog::Event> event(newLoginEvent(application, httpRequest));
- LoginEvent* login_event = dynamic_cast<LoginEvent*>(event.get());
- if (login_event) {
- login_event->m_sessionID = session_id.c_str();
- login_event->m_peer = entity;
- auto_ptr_char prot(getProtocolFamily());
- login_event->m_protocol = prot.get();
- login_event->m_nameID = ssoName;
- login_event->m_saml2AuthnStatement = ssoStatement;
- login_event->m_saml2Response = response;
- if (ctx.get())
- login_event->m_attributes = &ctx->getResolvedAttributes();
- application.getServiceProvider().getTransactionLog()->write(*login_event);
- }
- else {
- m_log.warn("unable to audit event, log event object was of an incorrect type");
- }
+ if (ctx) {
+ // Copy over any new tokens, but leave them in the context for cleanup.
+ tokens.insert(tokens.end(), ctx->getResolvedAssertions().begin(), ctx->getResolvedAssertions().end());
+ }
+
+ // Now merge in bad tokens for caching.
+ tokens.insert(tokens.end(), badtokens.begin(), badtokens.end());
+
+ string session_id;
+ application.getServiceProvider().getSessionCache()->insert(
+ session_id,
+ application,
+ httpRequest,
+ httpResponse,
+ sessionExp,
+ entity,
+ samlconstants::SAML20P_NS,
+ ssoName,
+ ssoStatement->getAuthnInstant() ? ssoStatement->getAuthnInstant()->getRawData() : nullptr,
+ ssoStatement->getSessionIndex(),
+ (authnContext && authnContext->getAuthnContextClassRef()) ? authnContext->getAuthnContextClassRef()->getReference() : nullptr,
+ (authnContext && authnContext->getAuthnContextDeclRef()) ? authnContext->getAuthnContextDeclRef()->getReference() : nullptr,
+ &tokens,
+ ctx ? &ctx->getResolvedAttributes() : nullptr
+ );
+
+ try {
+ scoped_ptr<TransactionLog::Event> event(newLoginEvent(application, httpRequest));
+ LoginEvent* login_event = dynamic_cast<LoginEvent*>(event.get());
+ if (login_event) {
+ login_event->m_sessionID = session_id.c_str();
+ login_event->m_peer = entity;
+ auto_ptr_char prot(getProtocolFamily());
+ login_event->m_protocol = prot.get();
+ login_event->m_nameID = ssoName;
+ login_event->m_saml2AuthnStatement = ssoStatement;
+ login_event->m_saml2Response = response;
+ if (ctx)
+ login_event->m_attributes = &ctx->getResolvedAttributes();
+ application.getServiceProvider().getTransactionLog()->write(*login_event);
}
- catch (exception& ex) {
- m_log.warn("exception auditing event: %s", ex.what());
+ else {
+ m_log.warn("unable to audit event, log event object was of an incorrect type");
}
-
- if (ownedName)
- delete ssoName;
- for_each(ownedtokens.begin(), ownedtokens.end(), xmltooling::cleanup<saml2::Assertion>());
}
- catch (exception&) {
- if (ownedName)
- delete ssoName;
- for_each(ownedtokens.begin(), ownedtokens.end(), xmltooling::cleanup<saml2::Assertion>());
- throw;
+ catch (std::exception& ex) {
+ m_log.warn("exception auditing event: %s", ex.what());
}
}
# include "security/SecurityPolicyProvider.h"
# include "metadata/MetadataProviderCriteria.h"
# include <fstream>
+# include <boost/algorithm/string.hpp>
+# include <boost/iterator/indirect_iterator.hpp>
+# include <boost/lambda/bind.hpp>
+# include <boost/lambda/if.hpp>
+# include <boost/lambda/lambda.hpp>
# include <saml/exceptions.h>
# include <saml/SAMLConfig.h>
# include <saml/saml2/core/Protocols.h>
using namespace opensaml::saml2p;
using namespace opensaml::saml2md;
using namespace opensaml;
+using namespace boost::lambda;
#else
# include "lite/SAMLConstants.h"
#endif
+#include <boost/scoped_ptr.hpp>
+
using namespace shibsp;
using namespace xmltooling;
+using namespace boost;
using namespace std;
namespace shibsp {
{
public:
SAML2Logout(const DOMElement* e, const char* appId);
- virtual ~SAML2Logout() {
-#ifndef SHIBSP_LITE
- if (SPConfig::getConfig().isEnabled(SPConfig::OutOfProcess)) {
- delete m_decoder;
- XMLString::release(&m_outgoing);
- for_each(m_encoders.begin(), m_encoders.end(), cleanup_pair<const XMLCh*,MessageEncoder>());
- }
-#endif
- }
+ virtual ~SAML2Logout() {}
void receive(DDF& in, ostream& out);
pair<bool,long> run(SPRequest& request, bool isHandler=true) const;
return e;
}
- xmltooling::QName m_role;
- MessageDecoder* m_decoder;
- XMLCh* m_outgoing;
- vector<const XMLCh*> m_bindings;
- map<const XMLCh*,MessageEncoder*> m_encoders;
+ scoped_ptr<MessageDecoder> m_decoder;
+ vector<string> m_bindings;
+ map< string,boost::shared_ptr<MessageEncoder> > m_encoders;
auto_ptr_char m_protocol;
#endif
};
SAML2Logout::SAML2Logout(const DOMElement* e, const char* appId)
: AbstractHandler(e, Category::getInstance(SHIBSP_LOGCAT".Logout.SAML2"))
#ifndef SHIBSP_LITE
- ,m_role(samlconstants::SAML20MD_NS, IDPSSODescriptor::LOCAL_NAME), m_decoder(nullptr), m_outgoing(nullptr), m_protocol(samlconstants::SAML20P_NS)
+ ,m_protocol(samlconstants::SAML20P_NS)
#endif
{
m_initiator = false;
SAMLConfig& conf = SAMLConfig::getConfig();
// Handle incoming binding.
- m_decoder = conf.MessageDecoderManager.newPlugin(
- getString("Binding").second, pair<const DOMElement*,const XMLCh*>(e,shibspconstants::SHIB2SPCONFIG_NS)
+ m_decoder.reset(
+ conf.MessageDecoderManager.newPlugin(
+ getString("Binding").second, pair<const DOMElement*,const XMLCh*>(e,shibspconstants::SHIB2SPCONFIG_NS)
+ )
);
m_decoder->setArtifactResolver(SPConfig::getConfig().getArtifactResolver());
if (m_decoder->isUserAgentPresent()) {
// Handle front-channel binding setup.
- pair<bool,const XMLCh*> outgoing = getXMLString("outgoingBindings", m_configNS.get());
+ string dupBindings;
+ pair<bool,const char*> outgoing = getString("outgoingBindings", m_configNS.get());
if (outgoing.first) {
- m_outgoing = XMLString::replicate(outgoing.second);
- XMLString::trim(m_outgoing);
+ dupBindings = outgoing.second;
}
else {
// No override, so we'll install a default binding precedence.
- string prec = string(samlconstants::SAML20_BINDING_HTTP_REDIRECT) + ' ' + samlconstants::SAML20_BINDING_HTTP_POST + ' ' +
+ dupBindings = string(samlconstants::SAML20_BINDING_HTTP_REDIRECT) + ' ' + samlconstants::SAML20_BINDING_HTTP_POST + ' ' +
samlconstants::SAML20_BINDING_HTTP_POST_SIMPLESIGN + ' ' + samlconstants::SAML20_BINDING_HTTP_ARTIFACT;
- m_outgoing = XMLString::transcode(prec.c_str());
}
- int pos;
- XMLCh* start = m_outgoing;
- while (start && *start) {
- pos = XMLString::indexOf(start,chSpace);
- if (pos != -1)
- *(start + pos)=chNull;
- m_bindings.push_back(start);
+ split(m_bindings, dupBindings, is_space(), algorithm::token_compress_on);
+ for (vector<string>::const_iterator b = m_bindings.begin(); b != m_bindings.end(); ++b) {
try {
- auto_ptr_char b(start);
- MessageEncoder * encoder = conf.MessageEncoderManager.newPlugin(
- b.get(), pair<const DOMElement*,const XMLCh*>(e,shibspconstants::SHIB2SPCONFIG_NS)
+ boost::shared_ptr<MessageEncoder> encoder(
+ conf.MessageEncoderManager.newPlugin(*b, pair<const DOMElement*,const XMLCh*>(e,shibspconstants::SHIB2SPCONFIG_NS))
);
if (encoder->isUserAgentPresent() && XMLString::equals(getProtocolFamily(), encoder->getProtocolFamily())) {
- m_encoders[start] = encoder;
- m_log.debug("supporting outgoing binding (%s)", b.get());
+ m_encoders[*b] = encoder;
+ m_log.debug("supporting outgoing binding (%s)", b->c_str());
}
else {
- delete encoder;
- m_log.warn("skipping outgoing binding (%s), not a SAML 2.0 front-channel mechanism", b.get());
+ m_log.warn("skipping outgoing binding (%s), not a SAML 2.0 front-channel mechanism", b->c_str());
}
}
- catch (exception& ex) {
+ catch (std::exception& ex) {
m_log.error("error building MessageEncoder: %s", ex.what());
}
- if (pos != -1)
- start = start + pos + 1;
- else
- break;
}
}
else {
- MessageEncoder* encoder = conf.MessageEncoderManager.newPlugin(
- getString("Binding").second, pair<const DOMElement*,const XMLCh*>(e,shibspconstants::SHIB2SPCONFIG_NS)
+ pair<bool,const char*> b = getString("Binding");
+ boost::shared_ptr<MessageEncoder> encoder(
+ conf.MessageEncoderManager.newPlugin(b.second, pair<const DOMElement*,const XMLCh*>(e,shibspconstants::SHIB2SPCONFIG_NS))
);
- m_encoders.insert(pair<const XMLCh*,MessageEncoder*>(nullptr, encoder));
+ m_encoders[b.second] = encoder;
}
}
#endif
void SAML2Logout::receive(DDF& in, ostream& out)
{
// Find application.
- const char* aid=in["application_id"].string();
- const Application* app=aid ? SPConfig::getConfig().getServiceProvider()->getApplication(aid) : nullptr;
+ const char* aid = in["application_id"].string();
+ const Application* app = aid ? SPConfig::getConfig().getServiceProvider()->getApplication(aid) : nullptr;
if (!app) {
// Something's horribly wrong.
m_log.error("couldn't find application (%s) for logout", aid ? aid : "(missing)");
}
// Unpack the request.
- auto_ptr<HTTPRequest> req(getRequest(in));
+ scoped_ptr<HTTPRequest> req(getRequest(in));
// Wrap a response shim.
DDF ret(nullptr);
DDFJanitor jout(ret);
- auto_ptr<HTTPResponse> resp(getResponse(ret));
+ scoped_ptr<HTTPResponse> resp(getResponse(ret));
// Since we're remoted, the result should either be a throw, which we pass on,
// a false/0 return, which we just return as an empty structure, or a response/redirect,
// which we capture in the facade and send back.
- doRequest(*app, *req.get(), *resp.get());
+ doRequest(*app, *req, *resp);
out << ret;
}
SessionCacheEx* cacheex = dynamic_cast<SessionCacheEx*>(cache);
string session_id = cache->active(application, request);
- auto_ptr<LogoutEvent> logout_event(newLogoutEvent(application, &request));
+ scoped_ptr<LogoutEvent> logout_event(newLogoutEvent(application, &request));
if (logout_event.get() && !session_id.empty())
logout_event->m_sessions.push_back(session_id);
cache->remove(application, request, &response);
worked2 = true;
}
- catch (exception& ex) {
+ catch (std::exception& ex) {
m_log.error("error removing session (%s): %s", session_id.c_str(), ex.what());
}
}
Locker metadataLocker(application.getMetadataProvider());
// Create the policy.
- auto_ptr<SecurityPolicy> policy(
- application.getServiceProvider().getSecurityPolicyProvider()->createSecurityPolicy(application, &m_role, policyId.second)
+ scoped_ptr<SecurityPolicy> policy(
+ application.getServiceProvider().getSecurityPolicyProvider()->createSecurityPolicy(application, &IDPSSODescriptor::ELEMENT_QNAME, policyId.second)
);
// Decode the message.
string relayState;
- auto_ptr<XMLObject> msg(m_decoder->decode(relayState, request, *policy.get()));
+ scoped_ptr<XMLObject> msg(m_decoder->decode(relayState, request, *policy));
const LogoutRequest* logoutRequest = dynamic_cast<LogoutRequest*>(msg.get());
if (logoutRequest) {
if (!policy->isAuthenticated())
throw SecurityPolicyException("Security of LogoutRequest not established.");
- if (logout_event.get()) {
+ if (logout_event) {
logout_event->m_saml2Request = logoutRequest;
if (policy->getIssuerMetadata())
logout_event->m_peer = dynamic_cast<const EntityDescriptor*>(policy->getIssuerMetadata()->getParent());
);
}
- bool ownedName = false;
+ scoped_ptr<XMLObject> decryptedID;
NameID* nameid = logoutRequest->getNameID();
if (!nameid) {
// Check for EncryptedID.
m_log.warn("found encrypted NameID, but no decryption credential was available");
else {
Locker credlocker(cr);
- auto_ptr<MetadataCredentialCriteria> mcc(
+ scoped_ptr<MetadataCredentialCriteria> mcc(
policy->getIssuerMetadata() ? new MetadataCredentialCriteria(*policy->getIssuerMetadata()) : nullptr
);
try {
- auto_ptr<XMLObject> decryptedID(
+ decryptedID.reset(
encname->decrypt(
*cr,
application.getRelyingParty(
)
);
nameid = dynamic_cast<NameID*>(decryptedID.get());
- if (nameid) {
- ownedName = true;
- decryptedID.release();
- }
}
- catch (exception& ex) {
+ catch (std::exception& ex) {
m_log.error(ex.what());
}
}
);
}
- auto_ptr<NameID> namewrapper(ownedName ? nameid : nullptr);
-
// Suck indexes out of the request for next steps.
set<string> indexes;
EntityDescriptor* entity = policy->getIssuerMetadata() ? dynamic_cast<EntityDescriptor*>(policy->getIssuerMetadata()->getParent()) : nullptr;
const vector<SessionIndex*> sindexes = logoutRequest->getSessionIndexs();
- for (vector<SessionIndex*>::const_iterator i = sindexes.begin(); i != sindexes.end(); ++i) {
- auto_ptr_char sindex((*i)->getSessionIndex());
+ for (indirect_iterator<vector<SessionIndex*>::const_iterator> i = make_indirect_iterator(sindexes.begin());
+ i != make_indirect_iterator(sindexes.end()); ++i) {
+ auto_ptr_char sindex(i->getSessionIndex());
indexes.insert(sindex.get());
}
// Now we actually terminate everything except for the active session,
// if this is front-channel, for notification purposes.
- for (vector<string>::const_iterator sit = sessions.begin(); sit != sessions.end(); ++sit)
- if (*sit != session_id)
- cacheex->remove(application, sit->c_str()); // using the ID-based removal operation
+ for_each(
+ sessions.begin(), sessions.end(),
+ if_(_1 != session_id)[lambda::bind(&SessionCacheEx::remove, cacheex, boost::ref(application), lambda::bind(&string::c_str, _1))]
+ );
}
else {
m_log.warn("session cache does not support extended API, can't implement indirect logout of sessions");
sessions.push_back(session_id);
}
}
- catch (exception& ex) {
+ catch (std::exception& ex) {
m_log.error("error while logging out matching sessions: %s", ex.what());
- if (logout_event.get()) {
+ if (logout_event) {
logout_event->m_nameID = nameid;
logout_event->m_sessions = sessions;
logout_event->m_logoutType = LogoutEvent::LOGOUT_EVENT_PARTIAL;
try {
cache->remove(application, request, &response);
}
- catch (exception& ex) {
+ catch (std::exception& ex) {
worked2 = false;
m_log.error("error removing active session (%s): %s", session_id.c_str(), ex.what());
}
}
- if (logout_event.get()) {
+ if (logout_event) {
logout_event->m_nameID = nameid;
logout_event->m_sessions = sessions;
logout_event->m_logoutType = (worked1 && worked2) ? LogoutEvent::LOGOUT_EVENT_PARTIAL : LogoutEvent::LOGOUT_EVENT_GLOBAL;
ex.raise();
}
- if (logout_event.get()) {
+ if (logout_event) {
logout_event->m_logoutType = LogoutEvent::LOGOUT_EVENT_PARTIAL;
logout_event->m_saml2Response = logoutResponse;
if (policy->getIssuerMetadata())
try {
checkError(logoutResponse, policy->getIssuerMetadata()); // throws if Status doesn't look good...
}
- catch (exception& ex) {
- if (logout_event.get()) {
+ catch (std::exception& ex) {
+ if (logout_event) {
logout_event->m_exception = &ex;
application.getServiceProvider().getTransactionLog()->write(*logout_event);
}
const StatusCode* sc = logoutResponse->getStatus() ? logoutResponse->getStatus()->getStatusCode() : nullptr;
sc = sc ? sc->getStatusCode() : nullptr;
if (sc && XMLString::equals(sc->getValue(), StatusCode::PARTIAL_LOGOUT)) {
- if (logout_event.get())
+ if (logout_event)
application.getServiceProvider().getTransactionLog()->write(*logout_event);
return sendLogoutPage(application, request, response, "partial");
}
- if (logout_event.get()) {
+ if (logout_event) {
logout_event->m_logoutType = LogoutEvent::LOGOUT_EVENT_GLOBAL;
application.getServiceProvider().getTransactionLog()->write(*logout_event);
}
const MessageEncoder* encoder = nullptr;
if (front) {
const IDPSSODescriptor* idp = dynamic_cast<const IDPSSODescriptor*>(role);
- for (vector<const XMLCh*>::const_iterator b = m_bindings.begin(); idp && b!=m_bindings.end(); ++b) {
- if ((ep=EndpointManager<SingleLogoutService>(idp->getSingleLogoutServices()).getByBinding(*b))) {
- map<const XMLCh*,MessageEncoder*>::const_iterator enc = m_encoders.find(*b);
- if (enc!=m_encoders.end())
- encoder = enc->second;
+ for (vector<string>::const_iterator b = m_bindings.begin(); idp && b != m_bindings.end(); ++b) {
+ auto_ptr_XMLCh wideb(b->c_str());
+ if ((ep = EndpointManager<SingleLogoutService>(idp->getSingleLogoutServices()).getByBinding(wideb.get()))) {
+ map< string,boost::shared_ptr<MessageEncoder> >::const_iterator enc = m_encoders.find(*b);
+ if (enc != m_encoders.end())
+ encoder = enc->second.get();
break;
}
}
}
}
else {
- encoder = m_encoders.begin()->second;
+ encoder = m_encoders.begin()->second.get();
}
// Prepare response.
Issuer* issuer = IssuerBuilder::buildIssuer();
logout->setIssuer(issuer);
issuer->setName(application.getRelyingParty(dynamic_cast<EntityDescriptor*>(role->getParent()))->getXMLString("entityID").second);
- fillStatus(*logout.get(), code, subcode, msg);
+ fillStatus(*logout, code, subcode, msg);
logout->setID(SAMLConfig::getConfig().generateIdentifier());
logout->setIssueInstant(time(nullptr));
auto_ptr_char dest(logout->getDestination());
long ret = sendMessage(*encoder, logout.get(), relayState, dest.get(), role, application, httpResponse, front);
logout.release(); // freed by encoder
- return make_pair(true,ret);
+ return make_pair(true, ret);
}
#endif
# include "binding/SOAPClient.h"
# include "metadata/MetadataProviderCriteria.h"
# include "security/SecurityPolicy.h"
+# include <boost/algorithm/string.hpp>
+# include <boost/iterator/indirect_iterator.hpp>
# include <saml/exceptions.h>
# include <saml/SAMLConfig.h>
# include <saml/saml2/core/Protocols.h>
# include "lite/SAMLConstants.h"
#endif
+#include <boost/scoped_ptr.hpp>
+
using namespace shibsp;
using namespace xmltooling;
+using namespace boost;
using namespace std;
namespace shibsp {
{
public:
SAML2LogoutInitiator(const DOMElement* e, const char* appId);
- virtual ~SAML2LogoutInitiator() {
-#ifndef SHIBSP_LITE
- if (SPConfig::getConfig().isEnabled(SPConfig::OutOfProcess)) {
- XMLString::release(&m_outgoing);
- for_each(m_encoders.begin(), m_encoders.end(), cleanup_pair<const XMLCh*,MessageEncoder>());
- }
-#endif
- }
+ virtual ~SAML2LogoutInitiator() {}
void init(const char* location); // encapsulates actions that need to run either in the c'tor or setParent
string m_appId;
#ifndef SHIBSP_LITE
- LogoutRequest* buildRequest(
+ auto_ptr<LogoutRequest> buildRequest(
const Application& application, const Session& session, const RoleDescriptor& role, const MessageEncoder* encoder=nullptr
) const;
return e;
}
- XMLCh* m_outgoing;
- vector<const XMLCh*> m_bindings;
- map<const XMLCh*,MessageEncoder*> m_encoders;
+ vector<string> m_bindings;
+ map< string,boost::shared_ptr<MessageEncoder> > m_encoders;
#endif
auto_ptr_char m_protocol;
};
};
SAML2LogoutInitiator::SAML2LogoutInitiator(const DOMElement* e, const char* appId)
- : AbstractHandler(e, Category::getInstance(SHIBSP_LOGCAT".LogoutInitiator.SAML2")), m_appId(appId),
-#ifndef SHIBSP_LITE
- m_outgoing(nullptr),
-#endif
- m_protocol(samlconstants::SAML20P_NS)
+ : AbstractHandler(e, Category::getInstance(SHIBSP_LOGCAT".LogoutInitiator.SAML2")), m_appId(appId), m_protocol(samlconstants::SAML20P_NS)
{
// If Location isn't set, defer initialization until the setParent call.
pair<bool,const char*> loc = getString("Location");
#ifndef SHIBSP_LITE
if (SPConfig::getConfig().isEnabled(SPConfig::OutOfProcess)) {
- // Handle outgoing binding setup.
- pair<bool,const XMLCh*> outgoing = getXMLString("outgoingBindings");
+ string dupBindings;
+ pair<bool,const char*> outgoing = getString("outgoingBindings");
if (outgoing.first) {
- m_outgoing = XMLString::replicate(outgoing.second);
- XMLString::trim(m_outgoing);
+ dupBindings = outgoing.second;
}
else {
// No override, so we'll install a default binding precedence.
- string prec = string(samlconstants::SAML20_BINDING_HTTP_REDIRECT) + ' ' + samlconstants::SAML20_BINDING_HTTP_POST + ' ' +
+ dupBindings = string(samlconstants::SAML20_BINDING_HTTP_REDIRECT) + ' ' + samlconstants::SAML20_BINDING_HTTP_POST + ' ' +
samlconstants::SAML20_BINDING_HTTP_POST_SIMPLESIGN + ' ' + samlconstants::SAML20_BINDING_HTTP_ARTIFACT;
- m_outgoing = XMLString::transcode(prec.c_str());
}
-
- int pos;
- XMLCh* start = m_outgoing;
- while (start && *start) {
- pos = XMLString::indexOf(start,chSpace);
- if (pos != -1)
- *(start + pos)=chNull;
- m_bindings.push_back(start);
+ split(m_bindings, dupBindings, is_space(), algorithm::token_compress_on);
+ for (vector<string>::const_iterator b = m_bindings.begin(); b != m_bindings.end(); ++b) {
try {
- auto_ptr_char b(start);
- MessageEncoder * encoder =
- SAMLConfig::getConfig().MessageEncoderManager.newPlugin(b.get(), pair<const DOMElement*,const XMLCh*>(getElement(), nullptr));
+ boost::shared_ptr<MessageEncoder> encoder(
+ SAMLConfig::getConfig().MessageEncoderManager.newPlugin(*b, pair<const DOMElement*,const XMLCh*>(getElement(),nullptr))
+ );
if (encoder->isUserAgentPresent() && XMLString::equals(getProtocolFamily(), encoder->getProtocolFamily())) {
- m_encoders[start] = encoder;
- m_log.debug("supporting outgoing binding (%s)", b.get());
+ m_encoders[*b] = encoder;
+ m_log.debug("supporting outgoing binding (%s)", b->c_str());
}
else {
- delete encoder;
- m_log.warn("skipping outgoing binding (%s), not a SAML 2.0 front-channel mechanism", b.get());
+ m_log.warn("skipping outgoing binding (%s), not a SAML 2.0 front-channel mechanism", b->c_str());
}
}
- catch (exception& ex) {
+ catch (std::exception& ex) {
m_log.error("error building MessageEncoder: %s", ex.what());
}
- if (pos != -1)
- start = start + pos + 1;
- else
- break;
}
}
#endif
try {
session = request.getSession(false, true, false); // don't cache it and ignore all checks
if (!session)
- return make_pair(false,0L);
+ return make_pair(false, 0L);
// We only handle SAML 2.0 sessions.
if (!XMLString::equals(session->getProtocol(), m_protocol.get())) {
session->unlock();
- return make_pair(false,0L);
+ return make_pair(false, 0L);
}
}
- catch (exception& ex) {
+ catch (std::exception& ex) {
m_log.error("error accessing current session: %s", ex.what());
- return make_pair(false,0L);
+ return make_pair(false, 0L);
}
if (SPConfig::getConfig().isEnabled(SPConfig::OutOfProcess)) {
}
// Unpack the request.
- auto_ptr<HTTPRequest> req(getRequest(in));
+ scoped_ptr<HTTPRequest> req(getRequest(in));
// Set up a response shim.
DDF ret(nullptr);
DDFJanitor jout(ret);
- auto_ptr<HTTPResponse> resp(getResponse(ret));
+ scoped_ptr<HTTPResponse> resp(getResponse(ret));
Session* session = nullptr;
try {
- session = app->getServiceProvider().getSessionCache()->find(*app, *req.get(), nullptr, nullptr);
+ session = app->getServiceProvider().getSessionCache()->find(*app, *req, nullptr, nullptr);
}
- catch (exception& ex) {
+ catch (std::exception& ex) {
m_log.error("error accessing current session: %s", ex.what());
}
// Since we're remoted, the result should either be a throw, which we pass on,
// a false/0 return, which we just return as an empty structure, or a response/redirect,
// which we capture in the facade and send back.
- doRequest(*app, *req.get(), *resp.get(), session);
+ doRequest(*app, *req, *resp, session);
}
else {
- m_log.log(getParent() ? Priority::WARN : Priority::ERROR, "bypassing SAML 2.0 logout, no NameID or issuing entityID found in session");
session->unlock();
- app->getServiceProvider().getSessionCache()->remove(*app, *req.get(), resp.get());
+ m_log.log(getParent() ? Priority::WARN : Priority::ERROR, "bypassing SAML 2.0 logout, no NameID or issuing entityID found in session");
+ app->getServiceProvider().getSessionCache()->remove(*app, *req, resp.get());
}
}
out << ret;
const Application& application, const HTTPRequest& httpRequest, HTTPResponse& httpResponse, Session* session
) const
{
+ Locker sessionLocker(session, false);
#ifndef SHIBSP_LITE
- auto_ptr<LogoutEvent> logout_event(newLogoutEvent(application, &httpRequest, session));
+ scoped_ptr<LogoutEvent> logout_event(newLogoutEvent(application, &httpRequest, session));
#endif
// Do back channel notification.
vector<string> sessions(1, session->getID());
if (!notifyBackChannel(application, httpRequest.getRequestURL(), sessions, false)) {
#ifndef SHIBSP_LITE
- if (logout_event.get()) {
+ if (logout_event) {
logout_event->m_logoutType = LogoutEvent::LOGOUT_EVENT_PARTIAL;
application.getServiceProvider().getTransactionLog()->write(*logout_event);
}
#endif
- session->unlock();
+ sessionLocker.assign();
+ session = nullptr;
application.getServiceProvider().getSessionCache()->remove(application, httpRequest, &httpResponse);
return sendLogoutPage(application, httpRequest, httpResponse, "partial");
}
#ifndef SHIBSP_LITE
- pair<bool,long> ret = make_pair(false,0L);
+ pair<bool,long> ret = make_pair(false, 0L);
try {
// With a session in hand, we can create a LogoutRequest message, if we can find a compatible endpoint.
MetadataProvider* m = application.getMetadataProvider();
);
}
- const EndpointType* ep=nullptr;
- const MessageEncoder* encoder=nullptr;
- vector<const XMLCh*>::const_iterator b;
- for (b = m_bindings.begin(); b!=m_bindings.end(); ++b) {
- if (ep=EndpointManager<SingleLogoutService>(role->getSingleLogoutServices()).getByBinding(*b)) {
- map<const XMLCh*,MessageEncoder*>::const_iterator enc = m_encoders.find(*b);
- if (enc!=m_encoders.end())
- encoder = enc->second;
+ const EndpointType* ep = nullptr;
+ const MessageEncoder* encoder = nullptr;
+ for (vector<string>::const_iterator b = m_bindings.begin(); b != m_bindings.end(); ++b) {
+ auto_ptr_XMLCh wideb(b->c_str());
+ if (ep = EndpointManager<SingleLogoutService>(role->getSingleLogoutServices()).getByBinding(wideb.get())) {
+ map< string,boost::shared_ptr<MessageEncoder> >::const_iterator enc = m_encoders.find(*b);
+ if (enc != m_encoders.end())
+ encoder = enc->second.get();
break;
}
}
shibsp::SOAPClient soaper(policy);
MetadataCredentialCriteria mcc(*role);
- LogoutResponse* logoutResponse=nullptr;
+ LogoutResponse* logoutResponse = nullptr;
+ scoped_ptr<StatusResponseType> srt;
auto_ptr_XMLCh binding(samlconstants::SAML20_BINDING_SOAP);
- const vector<SingleLogoutService*>& endpoints=role->getSingleLogoutServices();
- for (vector<SingleLogoutService*>::const_iterator epit=endpoints.begin(); !logoutResponse && epit!=endpoints.end(); ++epit) {
+ const vector<SingleLogoutService*>& endpoints = role->getSingleLogoutServices();
+ for (indirect_iterator<vector<SingleLogoutService*>::const_iterator> epit = make_indirect_iterator(endpoints.begin());
+ !logoutResponse && epit != make_indirect_iterator(endpoints.end()); ++epit) {
try {
- if (!XMLString::equals((*epit)->getBinding(),binding.get()))
+ if (!XMLString::equals(epit->getBinding(), binding.get()))
continue;
- LogoutRequest* msg = buildRequest(application, *session, *role);
+ auto_ptr<LogoutRequest> msg(buildRequest(application, *session, *role));
// Log the request.
- if (logout_event.get()) {
+ if (logout_event) {
logout_event->m_logoutType = LogoutEvent::LOGOUT_EVENT_UNKNOWN;
- logout_event->m_saml2Request = msg;
+ logout_event->m_saml2Request = msg.get();
application.getServiceProvider().getTransactionLog()->write(*logout_event);
}
- auto_ptr_char dest((*epit)->getLocation());
+ auto_ptr_char dest(epit->getLocation());
SAML2SOAPClient client(soaper, false);
- client.sendSAML(msg, application.getId(), mcc, dest.get());
- StatusResponseType* srt = client.receiveSAML();
- if (!(logoutResponse = dynamic_cast<LogoutResponse*>(srt))) {
- delete srt;
+ client.sendSAML(msg.release(), application.getId(), mcc, dest.get());
+ srt.reset(client.receiveSAML());
+ if (!(logoutResponse = dynamic_cast<LogoutResponse*>(srt.get()))) {
break;
}
}
- catch (exception& ex) {
+ catch (std::exception& ex) {
m_log.error("error sending LogoutRequest message: %s", ex.what());
soaper.reset();
}
m_log.warn("IdP didn't respond to logout request");
// Log the end result.
- if (logout_event.get()) {
+ if (logout_event) {
logout_event->m_logoutType = LogoutEvent::LOGOUT_EVENT_PARTIAL;
application.getServiceProvider().getTransactionLog()->write(*logout_event);
}
}
// Log the end result.
- if (logout_event.get()) {
+ if (logout_event) {
logout_event->m_logoutType = partial ? LogoutEvent::LOGOUT_EVENT_PARTIAL : LogoutEvent::LOGOUT_EVENT_GLOBAL;
logout_event->m_saml2Response = logoutResponse;
application.getServiceProvider().getTransactionLog()->write(*logout_event);
}
- delete logoutResponse;
if (partial)
ret = sendLogoutPage(application, httpRequest, httpResponse, "partial");
else {
}
if (session) {
- session->unlock();
+ sessionLocker.assign();
session = nullptr;
application.getServiceProvider().getSessionCache()->remove(application, httpRequest, &httpResponse);
}
msg->setDestination(ep->getLocation());
// Log the request.
- if (logout_event.get()) {
+ if (logout_event) {
logout_event->m_logoutType = LogoutEvent::LOGOUT_EVENT_UNKNOWN;
logout_event->m_saml2Request = msg.get();
application.getServiceProvider().getTransactionLog()->write(*logout_event);
msg.release(); // freed by encoder
if (session) {
- session->unlock();
+ sessionLocker.assign();
session = nullptr;
application.getServiceProvider().getSessionCache()->remove(application, httpRequest, &httpResponse);
}
// Less noise for IdPs that don't support logout (i.e. most)
m_log.info("unable to issue SAML 2.0 logout request: %s", mex.what());
}
- catch (exception& ex) {
+ catch (std::exception& ex) {
m_log.error("error issuing SAML 2.0 logout request: %s", ex.what());
}
- if (session)
- session->unlock();
return ret;
#else
- if (session)
- session->unlock();
throw ConfigurationException("Cannot perform logout using lite version of shibsp library.");
#endif
}
#ifndef SHIBSP_LITE
-LogoutRequest* SAML2LogoutInitiator::buildRequest(
+auto_ptr<LogoutRequest> SAML2LogoutInitiator::buildRequest(
const Application& application, const Session& session, const RoleDescriptor& role, const MessageEncoder* encoder
) const
{
encoder ? encoder->isCompact() : false,
relyingParty->getXMLString("encryptionAlg").second
);
- msg->setEncryptedID(encrypted.release());
+ msg->setEncryptedID(encrypted.get());
+ encrypted.release();
}
else {
msg->setNameID(nameid->cloneNameID());
msg->setID(SAMLConfig::getConfig().generateIdentifier());
msg->setIssueInstant(time(nullptr));
- return msg.release();
+ return msg;
}
#endif
# include "security/SecurityPolicy.h"
# include "security/SecurityPolicyProvider.h"
# include <fstream>
+# include <boost/algorithm/string.hpp>
+# include <boost/iterator/indirect_iterator.hpp>
# include <saml/exceptions.h>
# include <saml/SAMLConfig.h>
# include <saml/saml2/core/Protocols.h>
# include "lite/SAMLConstants.h"
#endif
+#include <boost/scoped_ptr.hpp>
+
using namespace shibsp;
using namespace xmltooling;
+using namespace boost;
using namespace std;
namespace shibsp {
{
public:
SAML2NameIDMgmt(const DOMElement* e, const char* appId);
- virtual ~SAML2NameIDMgmt() {
-#ifndef SHIBSP_LITE
- if (SPConfig::getConfig().isEnabled(SPConfig::OutOfProcess)) {
- delete m_decoder;
- XMLString::release(&m_outgoing);
- for_each(m_encoders.begin(), m_encoders.end(), cleanup_pair<const XMLCh*,MessageEncoder>());
- }
-#endif
- }
+ virtual ~SAML2NameIDMgmt() {}
void receive(DDF& in, ostream& out);
pair<bool,long> run(SPRequest& request, bool isHandler=true) const;
bool front
) const;
- xmltooling::QName m_role;
- MessageDecoder* m_decoder;
- XMLCh* m_outgoing;
- vector<const XMLCh*> m_bindings;
- map<const XMLCh*,MessageEncoder*> m_encoders;
+ scoped_ptr<MessageDecoder> m_decoder;
+ vector<string> m_bindings;
+ map< string,boost::shared_ptr<MessageEncoder> > m_encoders;
#endif
};
SAML2NameIDMgmt::SAML2NameIDMgmt(const DOMElement* e, const char* appId)
: AbstractHandler(e, Category::getInstance(SHIBSP_LOGCAT".NameIDMgmt.SAML2"))
-#ifndef SHIBSP_LITE
- ,m_role(samlconstants::SAML20MD_NS, IDPSSODescriptor::LOCAL_NAME), m_decoder(nullptr), m_outgoing(nullptr)
-#endif
{
#ifndef SHIBSP_LITE
if (SPConfig::getConfig().isEnabled(SPConfig::OutOfProcess)) {
SAMLConfig& conf = SAMLConfig::getConfig();
// Handle incoming binding.
- m_decoder = conf.MessageDecoderManager.newPlugin(
- getString("Binding").second, pair<const DOMElement*,const XMLCh*>(e,shibspconstants::SHIB2SPCONFIG_NS)
+ m_decoder.reset(
+ conf.MessageDecoderManager.newPlugin(
+ getString("Binding").second, pair<const DOMElement*,const XMLCh*>(e,shibspconstants::SHIB2SPCONFIG_NS)
+ )
);
m_decoder->setArtifactResolver(SPConfig::getConfig().getArtifactResolver());
if (m_decoder->isUserAgentPresent()) {
// Handle front-channel binding setup.
- pair<bool,const XMLCh*> outgoing = getXMLString("outgoingBindings", m_configNS.get());
+ string dupBindings;
+ pair<bool,const char*> outgoing = getString("outgoingBindings", m_configNS.get());
if (outgoing.first) {
- m_outgoing = XMLString::replicate(outgoing.second);
- XMLString::trim(m_outgoing);
+ dupBindings = outgoing.second;
}
else {
// No override, so we'll install a default binding precedence.
- string prec = string(samlconstants::SAML20_BINDING_HTTP_REDIRECT) + ' ' + samlconstants::SAML20_BINDING_HTTP_POST + ' ' +
+ dupBindings = string(samlconstants::SAML20_BINDING_HTTP_REDIRECT) + ' ' + samlconstants::SAML20_BINDING_HTTP_POST + ' ' +
samlconstants::SAML20_BINDING_HTTP_POST_SIMPLESIGN + ' ' + samlconstants::SAML20_BINDING_HTTP_ARTIFACT;
- m_outgoing = XMLString::transcode(prec.c_str());
}
- int pos;
- XMLCh* start = m_outgoing;
- while (start && *start) {
- pos = XMLString::indexOf(start,chSpace);
- if (pos != -1)
- *(start + pos)=chNull;
- m_bindings.push_back(start);
+ split(m_bindings, dupBindings, is_space(), algorithm::token_compress_on);
+ for (vector<string>::const_iterator b = m_bindings.begin(); b != m_bindings.end(); ++b) {
try {
- auto_ptr_char b(start);
- MessageEncoder * encoder = conf.MessageEncoderManager.newPlugin(
- b.get(), pair<const DOMElement*,const XMLCh*>(e,shibspconstants::SHIB2SPCONFIG_NS)
+ boost::shared_ptr<MessageEncoder> encoder(
+ conf.MessageEncoderManager.newPlugin(*b, pair<const DOMElement*,const XMLCh*>(e,shibspconstants::SHIB2SPCONFIG_NS))
);
if (encoder->isUserAgentPresent() && XMLString::equals(getProtocolFamily(), encoder->getProtocolFamily())) {
- m_encoders[start] = encoder;
- m_log.debug("supporting outgoing binding (%s)", b.get());
+ m_encoders[*b] = encoder;
+ m_log.debug("supporting outgoing binding (%s)", b->c_str());
}
else {
- delete encoder;
- m_log.warn("skipping outgoing binding (%s), not a SAML 2.0 front-channel mechanism", b.get());
+ m_log.warn("skipping outgoing binding (%s), not a SAML 2.0 front-channel mechanism", b->c_str());
}
}
- catch (exception& ex) {
+ catch (std::exception& ex) {
m_log.error("error building MessageEncoder: %s", ex.what());
}
- if (pos != -1)
- start = start + pos + 1;
- else
- break;
}
}
else {
- MessageEncoder* encoder = conf.MessageEncoderManager.newPlugin(
- getString("Binding").second, pair<const DOMElement*,const XMLCh*>(e,shibspconstants::SHIB2SPCONFIG_NS)
+ pair<bool,const char*> b = getString("Binding");
+ boost::shared_ptr<MessageEncoder> encoder(
+ conf.MessageEncoderManager.newPlugin(b.second, pair<const DOMElement*,const XMLCh*>(e,shibspconstants::SHIB2SPCONFIG_NS))
);
- m_encoders.insert(pair<const XMLCh*,MessageEncoder*>(nullptr, encoder));
+ m_encoders[b.second] = encoder;
}
}
#endif
void SAML2NameIDMgmt::receive(DDF& in, ostream& out)
{
// Find application.
- const char* aid=in["application_id"].string();
- const Application* app=aid ? SPConfig::getConfig().getServiceProvider()->getApplication(aid) : nullptr;
+ const char* aid = in["application_id"].string();
+ const Application* app = aid ? SPConfig::getConfig().getServiceProvider()->getApplication(aid) : nullptr;
if (!app) {
// Something's horribly wrong.
m_log.error("couldn't find application (%s) for NameID mgmt", aid ? aid : "(missing)");
}
// Unpack the request.
- auto_ptr<HTTPRequest> req(getRequest(in));
+ scoped_ptr<HTTPRequest> req(getRequest(in));
// Wrap a response shim.
DDF ret(nullptr);
DDFJanitor jout(ret);
- auto_ptr<HTTPResponse> resp(getResponse(ret));
+ scoped_ptr<HTTPResponse> resp(getResponse(ret));
// Since we're remoted, the result should either be a throw, which we pass on,
// a false/0 return, which we just return as an empty structure, or a response/redirect,
// which we capture in the facade and send back.
- doRequest(*app, *req.get(), *resp.get());
+ doRequest(*app, *req, *resp);
out << ret;
}
-pair<bool,long> SAML2NameIDMgmt::doRequest(
- const Application& application, const HTTPRequest& request, HTTPResponse& response
- ) const
+pair<bool,long> SAML2NameIDMgmt::doRequest(const Application& application, const HTTPRequest& request, HTTPResponse& response) const
{
#ifndef SHIBSP_LITE
SessionCache* cache = application.getServiceProvider().getSessionCache();
Locker metadataLocker(application.getMetadataProvider());
// Create the policy.
- auto_ptr<SecurityPolicy> policy(
- application.getServiceProvider().getSecurityPolicyProvider()->createSecurityPolicy(application, &m_role, policyId.second)
+ scoped_ptr<SecurityPolicy> policy(
+ application.getServiceProvider().getSecurityPolicyProvider()->createSecurityPolicy(application, &IDPSSODescriptor::ELEMENT_QNAME, policyId.second)
);
// Decode the message.
string relayState;
- auto_ptr<XMLObject> msg(m_decoder->decode(relayState, request, *policy.get()));
+ scoped_ptr<XMLObject> msg(m_decoder->decode(relayState, request, *policy));
const ManageNameIDRequest* mgmtRequest = dynamic_cast<ManageNameIDRequest*>(msg.get());
if (mgmtRequest) {
if (!policy->isAuthenticated())
EntityDescriptor* entity = policy->getIssuerMetadata() ? dynamic_cast<EntityDescriptor*>(policy->getIssuerMetadata()->getParent()) : nullptr;
- bool ownedName = false;
+ scoped_ptr<XMLObject> decryptedID;
NameID* nameid = mgmtRequest->getNameID();
if (!nameid) {
// Check for EncryptedID.
m_log.warn("found encrypted NameID, but no decryption credential was available");
else {
Locker credlocker(cr);
- auto_ptr<MetadataCredentialCriteria> mcc(
+ scoped_ptr<MetadataCredentialCriteria> mcc(
policy->getIssuerMetadata() ? new MetadataCredentialCriteria(*policy->getIssuerMetadata()) : nullptr
);
try {
- auto_ptr<XMLObject> decryptedID(
- encname->decrypt(*cr,application.getRelyingParty(entity)->getXMLString("entityID").second,mcc.get())
- );
+ decryptedID.reset(encname->decrypt(*cr, application.getRelyingParty(entity)->getXMLString("entityID").second, mcc.get()));
nameid = dynamic_cast<NameID*>(decryptedID.get());
- if (nameid) {
- ownedName = true;
- decryptedID.release();
- }
}
- catch (exception& ex) {
+ catch (std::exception& ex) {
m_log.error(ex.what());
}
}
);
}
- auto_ptr<NameID> namewrapper(ownedName ? nameid : nullptr);
-
// For a front-channel request, we have to match the information in the request
// against the current session.
if (!session_id.empty()) {
}
// Determine what's happening...
- bool ownedNewID = false;
+ scoped_ptr<XMLObject> newDecryptedID;
NewID* newid = nullptr;
if (!mgmtRequest->getTerminate()) {
// Better be a NewID in there.
m_log.warn("found encrypted NewID, but no decryption credential was available");
else {
Locker credlocker(cr);
- auto_ptr<MetadataCredentialCriteria> mcc(
+ scoped_ptr<MetadataCredentialCriteria> mcc(
policy->getIssuerMetadata() ? new MetadataCredentialCriteria(*policy->getIssuerMetadata()) : nullptr
);
try {
- auto_ptr<XMLObject> decryptedID(
- encnewid->decrypt(*cr,application.getRelyingParty(entity)->getXMLString("entityID").second,mcc.get())
- );
- newid = dynamic_cast<NewID*>(decryptedID.get());
- if (newid) {
- ownedNewID = true;
- decryptedID.release();
- }
+ newDecryptedID.reset(encnewid->decrypt(*cr, application.getRelyingParty(entity)->getXMLString("entityID").second, mcc.get()));
+ newid = dynamic_cast<NewID*>(newDecryptedID.get());
}
- catch (exception& ex) {
+ catch (std::exception& ex) {
m_log.error(ex.what());
}
}
}
}
- auto_ptr<NewID> newwrapper(ownedNewID ? newid : nullptr);
-
// TODO: maybe support in-place modification of sessions?
/*
vector<string> sessions;
*/
// Do back-channel app notifications.
- // Not supporting front-channel due to privacy fears.
+ // Not supporting front-channel due to privacy concerns.
bool worked = notifyBackChannel(application, request.getRequestURL(), *nameid, newid);
return sendResponse(
if (policy->getIssuerMetadata())
annotateException(&ex, policy->getIssuerMetadata()); // throws it
ex.raise();
- return make_pair(false,0L); // never happen, satisfies compiler
+ return make_pair(false, 0L); // never happen, satisfies compiler
#else
throw ConfigurationException("Cannot process NameID mgmt message using lite version of shibsp library.");
#endif
const MessageEncoder* encoder = nullptr;
if (front) {
const IDPSSODescriptor* idp = dynamic_cast<const IDPSSODescriptor*>(role);
- for (vector<const XMLCh*>::const_iterator b = m_bindings.begin(); idp && b!=m_bindings.end(); ++b) {
- if ((ep=EndpointManager<ManageNameIDService>(idp->getManageNameIDServices()).getByBinding(*b))) {
- map<const XMLCh*,MessageEncoder*>::const_iterator enc = m_encoders.find(*b);
- if (enc!=m_encoders.end())
- encoder = enc->second;
+ for (vector<string>::const_iterator b = m_bindings.begin(); idp && b != m_bindings.end(); ++b) {
+ auto_ptr_XMLCh wideb(b->c_str());
+ if ((ep = EndpointManager<ManageNameIDService>(idp->getManageNameIDServices()).getByBinding(wideb.get()))) {
+ map< string,boost::shared_ptr<MessageEncoder> >::const_iterator enc = m_encoders.find(*b);
+ if (enc != m_encoders.end())
+ encoder = enc->second.get();
break;
}
}
}
}
else {
- encoder = m_encoders.begin()->second;
+ encoder = m_encoders.begin()->second.get();
}
// Prepare response.
Issuer* issuer = IssuerBuilder::buildIssuer();
nim->setIssuer(issuer);
issuer->setName(application.getRelyingParty(dynamic_cast<EntityDescriptor*>(role->getParent()))->getXMLString("entityID").second);
- fillStatus(*nim.get(), code, subcode, msg);
+ fillStatus(*nim, code, subcode, msg);
auto_ptr_char dest(nim->getDestination());
long ret = sendMessage(*encoder, nim.get(), relayState, dest.get(), role, application, httpResponse);
nim.release(); // freed by encoder
- return make_pair(true,ret);
+ return make_pair(true, ret);
}
#include "util/SPConstants.h"
HTTPSOAPTransport* http = dynamic_cast<HTTPSOAPTransport*>(&transport);
if (http) {
http->useChunkedEncoding(false);
- http->setRequestHeader("User-Agent", PACKAGE_NAME);
http->setRequestHeader(PACKAGE_NAME, PACKAGE_VERSION);
}
}
if (endpoint.empty())
return true;
- auto_ptr<Envelope> env(EnvelopeBuilder::buildEnvelope());
+ scoped_ptr<Envelope> env(EnvelopeBuilder::buildEnvelope());
Body* body = BodyBuilder::buildBody();
env->setBody(body);
ElementProxy* msg = new AnyElementImpl(shibspconstants::SHIB2SPNOTIFY_NS, NameIDNotification);
SOAPNotifier soaper;
while (!endpoint.empty()) {
try {
- soaper.send(*env.get(), SOAPTransport::Address(application.getId(), application.getId(), endpoint.c_str()));
+ soaper.send(*env, SOAPTransport::Address(application.getId(), application.getId(), endpoint.c_str()));
delete soaper.receive();
}
- catch (exception& ex) {
+ catch (std::exception& ex) {
m_log.error("error notifying application of logout event: %s", ex.what());
result = false;
}
#ifndef SHIBSP_LITE
# include "metadata/MetadataProviderCriteria.h"
+# include <boost/bind.hpp>
+# include <boost/algorithm/string.hpp>
+# include <boost/iterator/indirect_iterator.hpp>
# include <saml/SAMLConfig.h>
# include <saml/saml2/core/Protocols.h>
# include <saml/saml2/metadata/EndpointManager.h>
# include <xercesc/util/XMLUniDefs.hpp>
#endif
+#include <boost/scoped_ptr.hpp>
+
using namespace shibsp;
using namespace opensaml;
using namespace xmltooling;
+using namespace boost;
using namespace std;
namespace shibsp {
{
public:
SAML2SessionInitiator(const DOMElement* e, const char* appId);
- virtual ~SAML2SessionInitiator() {
-#ifndef SHIBSP_LITE
- if (SPConfig::getConfig().isEnabled(SPConfig::OutOfProcess)) {
- XMLString::release(&m_outgoing);
- for_each(m_encoders.begin(), m_encoders.end(), cleanup_pair<const XMLCh*,MessageEncoder>());
- delete m_requestTemplate;
- delete m_ecp;
- }
-#endif
- }
+ virtual ~SAML2SessionInitiator() {}
void init(const char* location); // encapsulates actions that need to run either in the c'tor or setParent
auto_ptr_char m_paosNS,m_ecpNS;
auto_ptr_XMLCh m_paosBinding;
#ifndef SHIBSP_LITE
- XMLCh* m_outgoing;
- vector<const XMLCh*> m_bindings;
- map<const XMLCh*,MessageEncoder*> m_encoders;
- MessageEncoder* m_ecp;
- AuthnRequest* m_requestTemplate;
+ vector<string> m_bindings;
+ map< string,boost::shared_ptr<MessageEncoder> > m_encoders;
+ scoped_ptr<MessageEncoder> m_ecp;
+ scoped_ptr<AuthnRequest> m_requestTemplate;
#else
bool m_ecp;
#endif
SAML2SessionInitiator::SAML2SessionInitiator(const DOMElement* e, const char* appId)
: AbstractHandler(e, Category::getInstance(SHIBSP_LOGCAT".SessionInitiator.SAML2"), nullptr, &m_remapper), m_appId(appId),
- m_paosNS(samlconstants::PAOS_NS), m_ecpNS(samlconstants::SAML20ECP_NS), m_paosBinding(samlconstants::SAML20_BINDING_PAOS),
-#ifndef SHIBSP_LITE
- m_outgoing(nullptr), m_ecp(nullptr), m_requestTemplate(nullptr)
-#else
- m_ecp(false)
+ m_paosNS(samlconstants::PAOS_NS), m_ecpNS(samlconstants::SAML20ECP_NS), m_paosBinding(samlconstants::SAML20_BINDING_PAOS)
+#ifdef SHIBSP_LITE
+ ,m_ecp(false)
#endif
{
#ifndef SHIBSP_LITE
// Check for a template AuthnRequest to build from.
DOMElement* child = XMLHelper::getFirstChildElement(e, samlconstants::SAML20P_NS, AuthnRequest::LOCAL_NAME);
if (child)
- m_requestTemplate = dynamic_cast<AuthnRequest*>(AuthnRequestBuilder::buildOneFromElement(child));
+ m_requestTemplate.reset(dynamic_cast<AuthnRequest*>(AuthnRequestBuilder::buildOneFromElement(child)));
}
#endif
#ifdef SHIBSP_LITE
m_ecp = flag.first && flag.second;
#else
- m_outgoing=nullptr;
- m_ecp = nullptr;
if (SPConfig::getConfig().isEnabled(SPConfig::OutOfProcess)) {
// If directed, build an ECP encoder.
if (flag.first && flag.second) {
try {
- m_ecp = SAMLConfig::getConfig().MessageEncoderManager.newPlugin(
- samlconstants::SAML20_BINDING_PAOS, pair<const DOMElement*,const XMLCh*>(getElement(), nullptr)
+ m_ecp.reset(
+ SAMLConfig::getConfig().MessageEncoderManager.newPlugin(
+ samlconstants::SAML20_BINDING_PAOS, pair<const DOMElement*,const XMLCh*>(getElement(), nullptr)
+ )
);
}
- catch (exception& ex) {
+ catch (std::exception& ex) {
m_log.error("error building PAOS/ECP MessageEncoder: %s", ex.what());
}
}
- // Handle outgoing binding setup.
- pair<bool,const XMLCh*> outgoing = getXMLString("outgoingBindings");
+ string dupBindings;
+ pair<bool,const char*> outgoing = getString("outgoingBindings");
if (outgoing.first) {
- m_outgoing = XMLString::replicate(outgoing.second);
- XMLString::trim(m_outgoing);
+ dupBindings = outgoing.second;
}
else {
// No override, so we'll install a default binding precedence.
- string prec = string(samlconstants::SAML20_BINDING_HTTP_REDIRECT) + ' ' + samlconstants::SAML20_BINDING_HTTP_POST + ' ' +
+ dupBindings = string(samlconstants::SAML20_BINDING_HTTP_REDIRECT) + ' ' + samlconstants::SAML20_BINDING_HTTP_POST + ' ' +
samlconstants::SAML20_BINDING_HTTP_POST_SIMPLESIGN + ' ' + samlconstants::SAML20_BINDING_HTTP_ARTIFACT;
- m_outgoing = XMLString::transcode(prec.c_str());
}
-
- int pos;
- XMLCh* start = m_outgoing;
- while (start && *start) {
- pos = XMLString::indexOf(start,chSpace);
- if (pos != -1)
- *(start + pos)=chNull;
- m_bindings.push_back(start);
+ split(m_bindings, dupBindings, is_space(), algorithm::token_compress_on);
+ for (vector<string>::const_iterator b = m_bindings.begin(); b != m_bindings.end(); ++b) {
try {
- auto_ptr_char b(start);
- MessageEncoder * encoder = SAMLConfig::getConfig().MessageEncoderManager.newPlugin(
- b.get(),pair<const DOMElement*,const XMLCh*>(getElement(), nullptr)
+ boost::shared_ptr<MessageEncoder> encoder(
+ SAMLConfig::getConfig().MessageEncoderManager.newPlugin(*b, pair<const DOMElement*,const XMLCh*>(getElement(),nullptr))
);
if (encoder->isUserAgentPresent() && XMLString::equals(getProtocolFamily(), encoder->getProtocolFamily())) {
- m_encoders[start] = encoder;
- m_log.debug("supporting outgoing binding (%s)", b.get());
+ m_encoders[*b] = encoder;
+ m_log.debug("supporting outgoing binding (%s)", b->c_str());
}
else {
- delete encoder;
- m_log.warn("skipping outgoing binding (%s), not a SAML 2.0 front-channel mechanism", b.get());
+ m_log.warn("skipping outgoing binding (%s), not a SAML 2.0 front-channel mechanism", b->c_str());
}
}
- catch (exception& ex) {
+ catch (std::exception& ex) {
m_log.error("error building MessageEncoder: %s", ex.what());
}
- if (pos != -1)
- start = start + pos + 1;
- else
- break;
}
}
#endif
// We have to know the IdP to function unless this is ECP.
if ((!ECP && entityID.empty()) || !checkCompatibility(request, isHandler))
- return make_pair(false,0L);
+ return make_pair(false, 0L);
string target;
pair<bool,const char*> prop;
- const Handler* ACS=nullptr;
+ const Handler* ACS = nullptr;
pair<bool,const char*> acClass, acComp, nidFormat, spQual;
bool isPassive=false,forceAuthn=false;
- const Application& app=request.getApplication();
+ const Application& app = request.getApplication();
// ECP means the ACS will be by value no matter what.
pair<bool,bool> acsByIndex = ECP ? make_pair(true,false) : getBool("acsByIndex");
// Determine index to use.
pair<bool,const XMLCh*> ix = pair<bool,const XMLCh*>(false,nullptr);
- if (!strncmp(ACSloc.c_str(), "https", 5)) {
+ if (!strncmp(ACSloc.c_str(), "https://", 8)) {
ix = ACS->getXMLString("sslIndex", shibspconstants::ASCII_SHIB2SPCONFIG_NS);
if (!ix.first)
ix = ACS->getXMLString("index");
if (acsByIndex.first && acsByIndex.second) {
// Determine index to use.
pair<bool,const char*> ix = pair<bool,const char*>(false,nullptr);
- if (!strncmp(ACSloc.c_str(), "https", 5)) {
+ if (!strncmp(ACSloc.c_str(), "https://", 8)) {
ix = ACS->getString("sslIndex", shibspconstants::ASCII_SHIB2SPCONFIG_NS);
if (!ix.first)
ix = ACS->getString("index");
void SAML2SessionInitiator::receive(DDF& in, ostream& out)
{
// Find application.
- const char* aid=in["application_id"].string();
- const Application* app=aid ? SPConfig::getConfig().getServiceProvider()->getApplication(aid) : nullptr;
+ const char* aid = in["application_id"].string();
+ const Application* app = aid ? SPConfig::getConfig().getServiceProvider()->getApplication(aid) : nullptr;
if (!app) {
// Something's horribly wrong.
m_log.error("couldn't find application (%s) to generate AuthnRequest", aid ? aid : "(missing)");
DDFJanitor jout(ret);
// Wrap the outgoing object with a Response facade.
- auto_ptr<HTTPResponse> http(getResponse(ret));
+ scoped_ptr<HTTPResponse> http(getResponse(ret));
auto_ptr_XMLCh index(in["acsIndex"].string());
auto_ptr_XMLCh bind(in["acsBinding"].string());
// a false/0 return, which we just return as an empty structure, or a response/redirect,
// which we capture in the facade and send back.
doRequest(
- *app, nullptr, *http.get(), in["entity_id"].string(),
+ *app, nullptr, *http, in["entity_id"].string(),
index.get(),
(in["artifact"].integer() != 0),
in["acsLocation"].string(), bind.get(),
out << ret;
}
-#ifndef SHIBSP_LITE
-namespace {
- class _sameIdP : public binary_function<const IDPEntry*, const XMLCh*, bool>
- {
- public:
- bool operator()(const IDPEntry* entry, const XMLCh* entityID) const {
- return entry ? XMLString::equals(entry->getProviderID(), entityID) : false;
- }
- };
-};
-#endif
-
pair<bool,long> SAML2SessionInitiator::doRequest(
const Application& app,
const HTTPRequest* httpRequest,
const MessageEncoder* encoder = nullptr;
// We won't need this for ECP, but safety dictates we get the lock here.
- MetadataProvider* m=app.getMetadataProvider();
+ MetadataProvider* m = app.getMetadataProvider();
Locker locker(m);
if (ECP) {
- encoder = m_ecp;
+ encoder = m_ecp.get();
if (!encoder) {
m_log.error("MessageEncoder for PAOS binding not available");
- return make_pair(false,0L);
+ return make_pair(false, 0L);
}
}
else {
// Use metadata to locate the IdP's SSO service.
MetadataProviderCriteria mc(app, entityID, &IDPSSODescriptor::ELEMENT_QNAME, samlconstants::SAML20P_NS);
- entity=m->getEntityDescriptor(mc);
+ entity = m->getEntityDescriptor(mc);
if (!entity.first) {
m_log.warn("unable to locate metadata for provider (%s)", entityID);
throw MetadataException("Unable to locate metadata for identity provider ($entityID)", namedparams(1, "entityID", entityID));
else if (!entity.second) {
m_log.log(getParent() ? Priority::INFO : Priority::WARN, "unable to locate SAML 2.0 identity provider role for provider (%s)", entityID);
if (getParent())
- return make_pair(false,0L);
+ return make_pair(false, 0L);
throw MetadataException("Unable to locate SAML 2.0 identity provider role for provider ($entityID)", namedparams(1, "entityID", entityID));
}
else if (artifactInbound && !SPConfig::getConfig().getArtifactResolver()->isSupported(dynamic_cast<const SSODescriptorType&>(*entity.second))) {
m_log.warn("artifact binding selected for response, but identity provider lacks support");
if (getParent())
- return make_pair(false,0L);
+ return make_pair(false, 0L);
throw MetadataException("Identity provider ($entityID) lacks SAML 2.0 artifact support.", namedparams(1, "entityID", entityID));
}
// Loop over the supportable outgoing bindings.
role = dynamic_cast<const IDPSSODescriptor*>(entity.second);
- vector<const XMLCh*>::const_iterator b;
- for (b = m_bindings.begin(); b!=m_bindings.end(); ++b) {
- if (ep=EndpointManager<SingleSignOnService>(role->getSingleSignOnServices()).getByBinding(*b)) {
- map<const XMLCh*,MessageEncoder*>::const_iterator enc = m_encoders.find(*b);
- if (enc!=m_encoders.end())
- encoder = enc->second;
+ for (vector<string>::const_iterator b = m_bindings.begin(); b != m_bindings.end(); ++b) {
+ auto_ptr_XMLCh wideb(b->c_str());
+ if (ep=EndpointManager<SingleSignOnService>(role->getSingleSignOnServices()).getByBinding(wideb.get())) {
+ map< string,boost::shared_ptr<MessageEncoder> >::const_iterator enc = m_encoders.find(*b);
+ if (enc != m_encoders.end())
+ encoder = enc->second.get();
break;
}
}
if (!ep || !encoder) {
m_log.warn("unable to locate compatible SSO service for provider (%s)", entityID);
if (getParent())
- return make_pair(false,0L);
+ return make_pair(false, 0L);
throw MetadataException("Unable to locate compatible SSO service for provider ($entityID)", namedparams(1, "entityID", entityID));
}
}
}
if (authnContextClassRef) {
reqContext->getAuthnContextDeclRefs().clear();
- XMLCh* wideclass = XMLString::transcode(authnContextClassRef);
- XMLString::trim(wideclass);
- int pos;
- XMLCh* start = wideclass;
- while (start && *start) {
- pos = XMLString::indexOf(start, chSpace);
- if (pos != -1)
- *(start + pos) = chNull;
- AuthnContextClassRef* cref = AuthnContextClassRefBuilder::buildAuthnContextClassRef();
- cref->setReference(start);
- reqContext->getAuthnContextClassRefs().push_back(cref);
- if (pos != -1)
- start = start + pos + 1;
- else
- break;
+ string dup(authnContextClassRef);
+ vector<string> contexts;
+ split(contexts, dup, is_space(), algorithm::token_compress_on);
+ for (vector<string>::const_iterator ac = contexts.begin(); ac != contexts.end(); ++ac) {
+ auto_ptr_XMLCh wideac(ac->c_str());
+ auto_ptr<AuthnContextClassRef> cref(AuthnContextClassRefBuilder::buildAuthnContextClassRef());
+ cref->setReference(wideac.get());
+ reqContext->getAuthnContextClassRefs().push_back(cref.get());
+ cref.release();
}
- XMLString::release(&wideclass);
}
if (reqContext->getAuthnContextClassRefs().empty() && reqContext->getAuthnContextDeclRefs().empty()) {
scoping->setIDPList(idplist);
}
VectorOf(IDPEntry) entries = idplist->getIDPEntrys();
- if (find_if(entries, bind2nd(_sameIdP(), wideid.get())) == nullptr) {
+ static bool (*wideequals)(const XMLCh*,const XMLCh*) = &XMLString::equals;
+ if (find_if(entries, boost::bind(wideequals, boost::bind(&IDPEntry::getProviderID, _1), wideid.get())) == nullptr) {
IDPEntry* entry = IDPEntryBuilder::buildIDPEntry();
entry->setProviderID(wideid.get());
entries.push_back(entry);
req->setID(SAMLConfig::getConfig().generateIdentifier());
req->setIssueInstant(time(nullptr));
- auto_ptr<AuthnRequestEvent> ar_event(newAuthnRequestEvent(app, httpRequest));
- if (ar_event.get()) {
+ scoped_ptr<AuthnRequestEvent> ar_event(newAuthnRequestEvent(app, httpRequest));
+ if (ar_event) {
auto_ptr_char b(ep ? ep->getBinding() : nullptr);
ar_event->m_binding = b.get() ? b.get() : samlconstants::SAML20_BINDING_SOAP;
auto_ptr_char prot(getProtocolFamily());
*encoder, req.get(), relayState.c_str(), dest.get(), role, app, httpResponse, role ? role->WantAuthnRequestsSigned() : false
);
req.release(); // freed by encoder
- return make_pair(true,ret);
+ return make_pair(true, ret);
#else
- return make_pair(false,0L);
+ return make_pair(false, 0L);
#endif
}
#include "handler/AbstractHandler.h"
#include "handler/SessionInitiator.h"
+#include <boost/algorithm/string.hpp>
#include <xmltooling/XMLToolingConfig.h>
#include <xmltooling/util/URLEncoder.h>
using namespace shibsp;
using namespace opensaml;
using namespace xmltooling;
+using namespace boost;
using namespace std;
#ifndef SHIBSP_LITE
pair<bool,const char*> options = getString("preservedOptions");
if (options.first) {
- int j = 0;
string opt = options.second;
- for (unsigned int i = 0; i < opt.length(); i++) {
- if (opt.at(i) == ' ') {
- m_preservedOptions.push_back(opt.substr(j, i-j));
- j = i+1;
- }
- }
- m_preservedOptions.push_back(opt.substr(j, opt.length()-j));
+ split(m_preservedOptions, opt, is_space(), algorithm::token_compress_on);
}
else {
m_preservedOptions.push_back("isPassive");
string target;
pair<bool,const char*> prop;
- bool isPassive=false;
- const Application& app=request.getApplication();
+ bool isPassive = false;
+ const Application& app = request.getApplication();
pair<bool,const char*> discoveryURL = pair<bool,const char*>(true, m_url);
if (isHandler) {
#include "util/IPRange.h"
#include <ctime>
+#include <boost/bind.hpp>
+#include <boost/algorithm/string.hpp>
using namespace shibsp;
using namespace xmltooling;
+using namespace boost;
using namespace std;
namespace shibsp {
pair<bool,long> run(SPRequest& request, bool isHandler=true) const;
private:
+ void parseACL(const string& acl) {
+ try {
+ m_acl.push_back(IPRange::parseCIDRBlock(acl.c_str()));
+ }
+ catch (std::exception& ex) {
+ m_log.error("invalid CIDR block (%s): %s", acl.c_str(), ex.what());
+ }
+ }
+
bool m_values;
vector<IPRange> m_acl;
};
pair<bool,const char*> acl = getString("acl");
if (acl.first) {
string aclbuf=acl.second;
- int j = 0;
- for (unsigned int i=0; i < aclbuf.length(); ++i) {
- if (aclbuf.at(i)==' ') {
- try {
- m_acl.push_back(IPRange::parseCIDRBlock(aclbuf.substr(j, i-j).c_str()));
- }
- catch (exception& ex) {
- m_log.error("invalid CIDR block (%s): %s", aclbuf.substr(j, i-j).c_str(), ex.what());
- }
- j = i + 1;
- }
- }
- try {
- m_acl.push_back(IPRange::parseCIDRBlock(aclbuf.substr(j, aclbuf.length()-j).c_str()));
- }
- catch (exception& ex) {
- m_log.error("invalid CIDR block (%s): %s", aclbuf.substr(j, aclbuf.length()-j).c_str(), ex.what());
- }
-
+ vector<string> aclarray;
+ split(aclarray, aclbuf, is_space(), algorithm::token_compress_on);
+ for_each(aclarray.begin(), aclarray.end(), boost::bind(&SessionHandler::parseACL, this, _1));
if (m_acl.empty()) {
m_log.warn("invalid CIDR range(s) in Session handler acl property, allowing 127.0.0.1 as a fall back");
m_acl.push_back(IPRange::parseCIDRBlock("127.0.0.1"));
pair<bool,long> SessionHandler::run(SPRequest& request, bool isHandler) const
{
if (!m_acl.empty()) {
- bool found = false;
- for (vector<IPRange>::const_iterator acl = m_acl.begin(); !found && acl != m_acl.end(); ++acl) {
- found = acl->contains(request.getRemoteAddr().c_str());
- }
- if (!found) {
+ static bool (IPRange::* contains)(const char*) const = &IPRange::contains;
+ if (find_if(m_acl.begin(), m_acl.end(), boost::bind(contains, _1, request.getRemoteAddr().c_str())) == m_acl.end()) {
m_log.error("session handler request blocked from invalid address (%s)", request.getRemoteAddr().c_str());
istringstream msg("Session Handler Blocked");
return make_pair(true,request.sendResponse(msg, HTTPResponse::XMLTOOLING_HTTP_STATUS_FORBIDDEN));
Session* session = nullptr;
try {
- session = request.getSession();
+ session = request.getSession(); // caches the locked session in the request so it's unlocked automatically
if (!session) {
s << "A valid session was not found.</pre></body></html>" << endl;
request.setContentType("text/html");
return make_pair(true, request.sendResponse(s));
}
}
- catch (exception& ex) {
+ catch (std::exception& ex) {
s << "Exception while retrieving active session:" << endl
<< '\t' << ex.what() << "</pre></body></html>" << endl;
request.setContentType("text/html");
#ifndef SHIBSP_LITE
# include "metadata/MetadataProviderCriteria.h"
+# include <boost/lexical_cast.hpp>
# include <saml/saml2/metadata/Metadata.h>
# include <saml/saml2/metadata/EndpointManager.h>
# include <saml/util/SAMLConstants.h>
#else
# include "lite/SAMLConstants.h"
#endif
+#include <boost/scoped_ptr.hpp>
#include <xmltooling/XMLToolingConfig.h>
#include <xmltooling/util/URLEncoder.h>
using namespace opensaml::saml2md;
using namespace opensaml;
using namespace xmltooling;
+using namespace boost;
using namespace std;
namespace shibsp {
{
// We have to know the IdP to function.
if (entityID.empty() || !checkCompatibility(request, isHandler))
- return make_pair(false,0L);
+ return make_pair(false, 0L);
string target;
pair<bool,const char*> prop;
- const Handler* ACS=nullptr;
+ const Handler* ACS = nullptr;
const Application& app = request.getApplication();
if (isHandler) {
void Shib1SessionInitiator::receive(DDF& in, ostream& out)
{
// Find application.
- const char* aid=in["application_id"].string();
- const Application* app=aid ? SPConfig::getConfig().getServiceProvider()->getApplication(aid) : nullptr;
+ const char* aid = in["application_id"].string();
+ const Application* app = aid ? SPConfig::getConfig().getServiceProvider()->getApplication(aid) : nullptr;
if (!app) {
// Something's horribly wrong.
m_log.error("couldn't find application (%s) to generate AuthnRequest", aid ? aid : "(missing)");
DDFJanitor jout(ret);
// Wrap the outgoing object with a Response facade.
- auto_ptr<HTTPResponse> http(getResponse(ret));
+ scoped_ptr<HTTPResponse> http(getResponse(ret));
string relayState(in["RelayState"].string() ? in["RelayState"].string() : "");
// Since we're remoted, the result should either be a throw, which we pass on,
// a false/0 return, which we just return as an empty structure, or a response/redirect,
// which we capture in the facade and send back.
- doRequest(*app, nullptr, *http.get(), entityID, acsLocation, (in["artifact"].integer() != 0), relayState);
+ doRequest(*app, nullptr, *http, entityID, acsLocation, (in["artifact"].integer() != 0), relayState);
if (!ret.isstruct())
ret.structure();
ret.addmember("RelayState").unsafe_string(relayState.c_str());
{
#ifndef SHIBSP_LITE
// Use metadata to invoke the SSO service directly.
- MetadataProvider* m=app.getMetadataProvider();
+ MetadataProvider* m = app.getMetadataProvider();
Locker locker(m);
MetadataProviderCriteria mc(app, entityID, &IDPSSODescriptor::ELEMENT_QNAME, shibspconstants::SHIB1_PROTOCOL_ENUM);
pair<const EntityDescriptor*,const RoleDescriptor*> entity = m->getEntityDescriptor(mc);
else if (!entity.second) {
m_log.log(getParent() ? Priority::INFO : Priority::WARN, "unable to locate Shibboleth-aware identity provider role for provider (%s)", entityID);
if (getParent())
- return make_pair(false,0L);
+ return make_pair(false, 0L);
throw MetadataException("Unable to locate Shibboleth-aware identity provider role for provider ($entityID)", namedparams(1, "entityID", entityID));
}
else if (artifact && !SPConfig::getConfig().getArtifactResolver()->isSupported(dynamic_cast<const SSODescriptorType&>(*entity.second))) {
m_log.warn("artifact profile selected for response, but identity provider lacks support");
if (getParent())
- return make_pair(false,0L);
+ return make_pair(false, 0L);
throw MetadataException("Identity provider ($entityID) lacks SAML artifact support.", namedparams(1, "entityID", entityID));
}
- const EndpointType* ep=EndpointManager<SingleSignOnService>(
+ const EndpointType* ep = EndpointManager<SingleSignOnService>(
dynamic_cast<const IDPSSODescriptor*>(entity.second)->getSingleSignOnServices()
).getByBinding(shibspconstants::SHIB1_AUTHNREQUEST_PROFILE_URI);
if (!ep) {
m_log.warn("unable to locate compatible SSO service for provider (%s)", entityID);
if (getParent())
- return make_pair(false,0L);
+ return make_pair(false, 0L);
throw MetadataException("Unable to locate compatible SSO service for provider ($entityID)", namedparams(1, "entityID", entityID));
}
preserveRelayState(app, httpResponse, relayState);
- auto_ptr<AuthnRequestEvent> ar_event(newAuthnRequestEvent(app, httpRequest));
- if (ar_event.get()) {
+ scoped_ptr<AuthnRequestEvent> ar_event(newAuthnRequestEvent(app, httpRequest));
+ if (ar_event) {
auto_ptr_char prot(getProtocolFamily());
ar_event->m_protocol = prot.get();
auto_ptr_char b(shibspconstants::SHIB1_AUTHNREQUEST_PROFILE_URI);
if (relayState.empty())
relayState = "default";
- char timebuf[16];
- sprintf(timebuf,"%lu",time(nullptr));
const URLEncoder* urlenc = XMLToolingConfig::getConfig().getURLEncoder();
auto_ptr_char dest(ep->getLocation());
string req=string(dest.get()) + (strchr(dest.get(),'?') ? '&' : '?') + "shire=" + urlenc->encode(acsLocation) +
- "&time=" + timebuf + "&target=" + urlenc->encode(relayState.c_str()) +
+ "&time=" + lexical_cast<string>(time(nullptr)) + "&target=" + urlenc->encode(relayState.c_str()) +
"&providerId=" + urlenc->encode(app.getRelyingParty(entity.first)->getString("entityID").second);
if (httpRequest) {
return make_pair(true, httpResponse.sendRedirect(req.c_str()));
#else
- return make_pair(false,0L);
+ return make_pair(false, 0L);
#endif
}
#include "util/IPRange.h"
#include "util/CGIParser.h"
+#include <boost/bind.hpp>
+#include <boost/iterator/indirect_iterator.hpp>
+#include <boost/scoped_ptr.hpp>
+#include <boost/algorithm/string.hpp>
#include <xmltooling/version.h>
#include <xmltooling/util/DateTime.h>
using namespace xmlsignature;
#endif
using namespace xmltooling;
+using namespace boost;
using namespace std;
namespace shibsp {
private:
pair<bool,long> processMessage(const Application& application, const HTTPRequest& httpRequest, HTTPResponse& httpResponse) const;
ostream& systemInfo(ostream& os) const;
+ void parseACL(const string& acl) {
+ try {
+ m_acl.push_back(IPRange::parseCIDRBlock(acl.c_str()));
+ }
+ catch (std::exception& ex) {
+ m_log.error("invalid CIDR block (%s): %s", acl.c_str(), ex.what());
+ }
+ }
vector<IPRange> m_acl;
};
public:
DummyRequest(const char* url) : m_parser(nullptr), m_url(url), m_scheme(nullptr), m_query(nullptr), m_port(0) {
#ifdef HAVE_STRCASECMP
- if (url && !strncasecmp(url,"http://",7)) {
- m_scheme="http";
- url+=7;
+ if (url && !strncasecmp(url,"http://", 7)) {
+ m_scheme = "http";
+ m_port = 80;
+ url += 7;
}
- else if (url && !strncasecmp(url,"https://",8)) {
- m_scheme="https";
- url+=8;
+ else if (url && !strncasecmp(url,"https://", 8)) {
+ m_scheme = "https";
+ m_port = 443;
+ url += 8;
}
else
#else
- if (url && !strnicmp(url,"http://",7)) {
- m_scheme="http";
+ if (url && !strnicmp(url,"http://", 7)) {
+ m_scheme = "http";
m_port = 80;
- url+=7;
+ url += 7;
}
- else if (url && !strnicmp(url,"https://",8)) {
+ else if (url && !strnicmp(url,"https://", 8)) {
m_scheme="https";
m_port = 443;
- url+=8;
+ url += 8;
}
else
#endif
}
}
- virtual ~DummyRequest() {
- delete m_parser;
- }
+ virtual ~DummyRequest() {}
const char* getRequestURL() const {
return m_url;
const char* getParameter(const char* name) const
{
if (!m_parser)
- m_parser=new CGIParser(*this);
+ m_parser.reset(new CGIParser(*this));
- pair<CGIParser::walker,CGIParser::walker> bounds=m_parser->getParameters(name);
- return (bounds.first==bounds.second) ? nullptr : bounds.first->second;
+ pair<CGIParser::walker,CGIParser::walker> bounds = m_parser->getParameters(name);
+ return (bounds.first == bounds.second) ? nullptr : bounds.first->second;
}
vector<const char*>::size_type getParameters(const char* name, vector<const char*>& values) const
{
if (!m_parser)
- m_parser=new CGIParser(*this);
+ m_parser.reset(new CGIParser(*this));
- pair<CGIParser::walker,CGIParser::walker> bounds=m_parser->getParameters(name);
- while (bounds.first!=bounds.second) {
+ pair<CGIParser::walker,CGIParser::walker> bounds = m_parser->getParameters(name);
+ while (bounds.first != bounds.second) {
values.push_back(bounds.first->second);
++bounds.first;
}
}
private:
- mutable CGIParser* m_parser;
+ mutable scoped_ptr<CGIParser> m_parser;
const char* m_url;
const char* m_scheme;
const char* m_query;
pair<bool,const char*> acl = getString("acl");
if (acl.first) {
string aclbuf=acl.second;
- int j = 0;
- for (unsigned int i=0; i < aclbuf.length(); i++) {
- if (aclbuf.at(i)==' ') {
- try {
- m_acl.push_back(IPRange::parseCIDRBlock(aclbuf.substr(j, i-j).c_str()));
- }
- catch (exception& ex) {
- m_log.error("invalid CIDR block (%s): %s", aclbuf.substr(j, i-j).c_str(), ex.what());
- }
- j = i + 1;
- }
- }
- try {
- m_acl.push_back(IPRange::parseCIDRBlock(aclbuf.substr(j, aclbuf.length()-j).c_str()));
- }
- catch (exception& ex) {
- m_log.error("invalid CIDR block (%s): %s", aclbuf.substr(j, aclbuf.length()-j).c_str(), ex.what());
- }
-
+ vector<string> aclarray;
+ split(aclarray, aclbuf, is_space(), algorithm::token_compress_on);
+ for_each(aclarray.begin(), aclarray.end(), boost::bind(&StatusHandler::parseACL, this, _1));
if (m_acl.empty()) {
m_log.warn("invalid CIDR range(s) in Status handler acl property, allowing 127.0.0.1 as a fall back");
m_acl.push_back(IPRange::parseCIDRBlock("127.0.0.1"));
{
SPConfig& conf = SPConfig::getConfig();
if (conf.isEnabled(SPConfig::InProcess) && !m_acl.empty()) {
- bool found = false;
- for (vector<IPRange>::const_iterator acl = m_acl.begin(); !found && acl != m_acl.end(); ++acl) {
- found = acl->contains(request.getRemoteAddr().c_str());
- }
- if (!found) {
+ static bool (IPRange::* contains)(const char*) const = &IPRange::contains;
+ if (find_if(m_acl.begin(), m_acl.end(), boost::bind(contains, _1, request.getRemoteAddr().c_str())) == m_acl.end()) {
m_log.error("status handler request blocked from invalid address (%s)", request.getRemoteAddr().c_str());
istringstream msg("Status Handler Blocked");
return make_pair(true,request.sendResponse(msg, HTTPResponse::XMLTOOLING_HTTP_STATUS_FORBIDDEN));
msg << '>' << target << "</RequestSettings>";
msg << "<Status><OK/></Status>";
msg << "</StatusHandler>";
- return make_pair(true,request.sendResponse(msg));
+ return make_pair(true, request.sendResponse(msg));
}
try {
<< "' Shibboleth='" << PACKAGE_VERSION << "'/>";
systemInfo(msg) << "<Status><Exception type='" << ex.getClassName() << "'>" << ex.what() << "</Exception></Status>";
msg << "</StatusHandler>";
- return make_pair(true,request.sendResponse(msg, HTTPResponse::XMLTOOLING_HTTP_STATUS_ERROR));
+ return make_pair(true, request.sendResponse(msg, HTTPResponse::XMLTOOLING_HTTP_STATUS_ERROR));
}
- catch (exception& ex) {
+ catch (std::exception& ex) {
m_log.error("error while processing request: %s", ex.what());
DateTime now(time(nullptr));
now.parseDateTime();
<< "' Shibboleth='" << PACKAGE_VERSION << "'/>";
systemInfo(msg) << "<Status><Exception type='std::exception'>" << ex.what() << "</Exception></Status>";
msg << "</StatusHandler>";
- return make_pair(true,request.sendResponse(msg, HTTPResponse::XMLTOOLING_HTTP_STATUS_ERROR));
+ return make_pair(true, request.sendResponse(msg, HTTPResponse::XMLTOOLING_HTTP_STATUS_ERROR));
}
}
void StatusHandler::receive(DDF& in, ostream& out)
{
// Find application.
- const char* aid=in["application_id"].string();
- const Application* app=aid ? SPConfig::getConfig().getServiceProvider()->getApplication(aid) : nullptr;
+ const char* aid = in["application_id"].string();
+ const Application* app = aid ? SPConfig::getConfig().getServiceProvider()->getApplication(aid) : nullptr;
if (!app) {
// Something's horribly wrong.
m_log.error("couldn't find application (%s) for status request", aid ? aid : "(missing)");
// Wrap a response shim.
DDF ret(nullptr);
DDFJanitor jout(ret);
- auto_ptr<HTTPRequest> req(getRequest(in));
- auto_ptr<HTTPResponse> resp(getResponse(ret));
+ scoped_ptr<HTTPRequest> req(getRequest(in));
+ scoped_ptr<HTTPResponse> resp(getResponse(ret));
// Since we're remoted, the result should either be a throw, a false/0 return,
// which we just return as an empty structure, or a response/redirect,
// which we capture in the facade and send back.
- processMessage(*app, *req.get(), *resp.get());
+ processMessage(*app, *req, *resp);
out << ret;
}
s << "<SessionCache><Exception type='" << ex.getClassName() << "'>" << ex.what() << "</Exception></SessionCache>";
status = "<Partial/>";
}
- catch (exception& ex) {
+ catch (std::exception& ex) {
s << "<SessionCache><Exception type='std::exception'>" << ex.what() << "</Exception></SessionCache>";
status = "<Partial/>";
}
MetadataProvider* m = application.getMetadataProvider();
Locker mlock(m);
- const PropertySet* relyingParty=nullptr;
+ const PropertySet* relyingParty = nullptr;
param=httpRequest.getParameter("entityID");
if (param)
relyingParty = application.getRelyingParty(m->getEntityDescriptor(MetadataProviderCriteria(application, param)).first);
s << "<Handlers>";
vector<const Handler*> handlers;
application.getHandlers(handlers);
- for (vector<const Handler*>::const_iterator h = handlers.begin(); h != handlers.end(); ++h) {
- s << "<Handler type='" << (*h)->getType() << "' Location='" << (*h)->getString("Location").second << "'";
- if ((*h)->getString("Binding").first)
- s << " Binding='" << (*h)->getString("Binding").second << "'";
+ for (indirect_iterator<vector<const Handler*>::const_iterator> h = make_indirect_iterator(handlers.begin());
+ h != make_indirect_iterator(handlers.end()); ++h) {
+ s << "<Handler type='" << h->getType() << "' Location='" << h->getString("Location").second << "'";
+ if (h->getString("Binding").first)
+ s << " Binding='" << h->getString("Binding").second << "'";
s << "/>";
}
s << "</Handlers>";
- CredentialResolver* credResolver=application.getCredentialResolver();
+ CredentialResolver* credResolver = application.getCredentialResolver();
if (credResolver) {
Locker credLocker(credResolver);
CredentialCriteria cc;
if (keyName.first)
cc.getKeyNames().insert(keyName.second);
vector<const Credential*> creds;
- credResolver->resolve(creds,&cc);
+ credResolver->resolve(creds, &cc);
for (vector<const Credential*>::const_iterator c = creds.begin(); c != creds.end(); ++c) {
KeyInfo* kinfo = (*c)->getKeyInfo();
if (kinfo) {
- auto_ptr<KeyDescriptor> kd(KeyDescriptorBuilder::buildKeyDescriptor());
+ scoped_ptr<KeyDescriptor> kd(KeyDescriptorBuilder::buildKeyDescriptor());
kd->setUse(KeyDescriptor::KEYTYPE_SIGNING);
kd->setKeyInfo(kinfo);
s << *(kd.get());
cc.setUsage(Credential::ENCRYPTION_CREDENTIAL);
creds.clear();
cc.getKeyNames().clear();
- credResolver->resolve(creds,&cc);
+ credResolver->resolve(creds, &cc);
for (vector<const Credential*>::const_iterator c = creds.begin(); c != creds.end(); ++c) {
KeyInfo* kinfo = (*c)->getKeyInfo();
if (kinfo) {
- auto_ptr<KeyDescriptor> kd(KeyDescriptorBuilder::buildKeyDescriptor());
+ scoped_ptr<KeyDescriptor> kd(KeyDescriptorBuilder::buildKeyDescriptor());
kd->setUse(KeyDescriptor::KEYTYPE_ENCRYPTION);
kd->setKeyInfo(kinfo);
s << *(kd.get());
httpResponse.setContentType("text/xml");
return make_pair(true, httpResponse.sendResponse(s));
#else
- return make_pair(false,0L);
+ return make_pair(false, 0L);
#endif
}
# include "metadata/MetadataProviderCriteria.h"
# include <saml/saml2/metadata/Metadata.h>
#endif
+#include <boost/tuple/tuple.hpp>
#include <xmltooling/XMLToolingConfig.h>
#include <xmltooling/util/URLEncoder.h>
#include <xercesc/util/XMLUniDefs.hpp>
using namespace opensaml::saml2md;
using namespace opensaml;
using namespace xmltooling;
+using namespace boost;
using namespace std;
namespace shibsp {
e = XMLHelper::getFirstChildElement(e);
while (e) {
if (e->hasChildNodes()) {
- const XMLCh* flag = e->getAttributeNS(nullptr, force);
- if (!flag)
- flag = &chNull;
+ bool flag = XMLHelper::getAttrBool(e, false, force);
if (XMLString::equals(e->getLocalName(), Subst)) {
- auto_ptr_char temp(e->getFirstChild()->getNodeValue());
+ auto_ptr_char temp(e->getTextContent());
if (temp.get() && *temp.get())
- m_subst.push_back(pair<bool,string>((*flag==chDigit_1 || *flag==chLatin_t), temp.get()));
+ m_subst.push_back(pair<bool,string>(flag, temp.get()));
}
else if (XMLString::equals(e->getLocalName(), Regex) && e->hasAttributeNS(nullptr, match)) {
auto_ptr_char m(e->getAttributeNS(nullptr, match));
- auto_ptr_char repl(e->getFirstChild()->getNodeValue());
+ auto_ptr_char repl(e->getTextContent());
if (m.get() && *m.get() && repl.get() && *repl.get())
- m_regex.push_back(make_pair((*flag==chDigit_1 || *flag==chLatin_t), pair<string,string>(m.get(), repl.get())));
+ m_regex.push_back(tuple<bool,string,string>(flag, m.get(), repl.get()));
}
else {
m_log.warn("Unknown element found in Transform SessionInitiator configuration, check for errors.");
#ifndef SHIBSP_LITE
bool m_alwaysRun;
vector< pair<bool, string> > m_subst;
- vector< pair< bool, pair<string,string> > > m_regex;
+ vector< tuple<bool,string,string> > m_regex;
#endif
};
{
// We have to have a candidate name to function.
if (entityID.empty() || !checkCompatibility(request, isHandler))
- return make_pair(false,0L);
+ return make_pair(false, 0L);
- const Application& app=request.getApplication();
+ const Application& app = request.getApplication();
m_log.debug("attempting to transform input (%s) into a valid entityID", entityID.c_str());
entityID = out.string();
}
- return make_pair(false,0L);
+ return make_pair(false, 0L);
}
void TransformSessionInitiator::receive(DDF& in, ostream& out)
{
// Find application.
- const char* aid=in["application_id"].string();
- const Application* app=aid ? SPConfig::getConfig().getServiceProvider()->getApplication(aid) : nullptr;
+ const char* aid = in["application_id"].string();
+ const Application* app = aid ? SPConfig::getConfig().getServiceProvider()->getApplication(aid) : nullptr;
if (!app) {
// Something's horribly wrong.
m_log.error("couldn't find application (%s) to generate AuthnRequest", aid ? aid : "(missing)");
void TransformSessionInitiator::doRequest(const Application& application, string& entityID) const
{
#ifndef SHIBSP_LITE
- MetadataProvider* m=application.getMetadataProvider();
+ MetadataProvider* m = application.getMetadataProvider();
Locker locker(m);
MetadataProviderCriteria mc(application, entityID.c_str(), &IDPSSODescriptor::ELEMENT_QNAME);
}
// Now try regexs.
- for (vector< pair< bool, pair<string,string> > >::const_iterator r = m_regex.begin(); r != m_regex.end(); ++r) {
+ for (vector< tuple<bool,string,string> >::const_iterator r = m_regex.begin(); r != m_regex.end(); ++r) {
try {
- RegularExpression exp(r->second.first.c_str());
- XMLCh* temp = exp.replace(entityID.c_str(), r->second.second.c_str());
+ RegularExpression exp(r->get<1>().c_str());
+ XMLCh* temp = exp.replace(entityID.c_str(), r->get<2>().c_str());
if (temp) {
auto_ptr_char narrow(temp);
XMLString::release(&temp);
if (entityID == narrow.get())
continue;
- if (r->first) {
+ if (r->get<0>()) {
m_log.info("forcibly transformed entityID from (%s) to (%s)", entityID.c_str(), narrow.get());
entityID = narrow.get();
}
entity = m->getEntityDescriptor(mc);
if (entity.first) {
m_log.info("transformed entityID from (%s) to (%s)", entityID.c_str(), narrow.get());
- if (!r->first)
+ if (!r->get<0>())
entityID = narrow.get();
return;
}
#endif
#include <ctime>
+#include <boost/lexical_cast.hpp>
#include <xmltooling/XMLToolingConfig.h>
#include <xmltooling/util/URLEncoder.h>
using namespace shibsp;
using namespace opensaml;
using namespace xmltooling;
+using namespace boost;
using namespace std;
namespace shibsp {
// The IdP CANNOT be specified for us to run. Otherwise, we'd be redirecting to a WAYF
// anytime the IdP's metadata was wrong.
if (!entityID.empty() || !checkCompatibility(request, isHandler))
- return make_pair(false,0L);
+ return make_pair(false, 0L);
string target;
pair<bool,const char*> prop;
- const Handler* ACS=nullptr;
- const Application& app=request.getApplication();
+ const Handler* ACS = nullptr;
+ const Application& app = request.getApplication();
pair<bool,const char*> discoveryURL = pair<bool,const char*>(true, m_url);
if (isHandler) {
if (target.empty())
target = "default";
- char timebuf[16];
- sprintf(timebuf,"%lu",time(nullptr));
const URLEncoder* urlenc = XMLToolingConfig::getConfig().getURLEncoder();
string req=string(discoveryURL.second) + (strchr(discoveryURL.second,'?') ? '&' : '?') + "shire=" + urlenc->encode(ACSloc.c_str()) +
- "&time=" + timebuf + "&target=" + urlenc->encode(target.c_str()) +
+ "&time=" + lexical_cast<string>(time(nullptr)) + "&target=" + urlenc->encode(target.c_str()) +
"&providerId=" + urlenc->encode(app.getString("entityID").second);
return make_pair(true, request.sendRedirect(req.c_str()));
DDF m_obj;
#ifndef SHIBSP_LITE
scoped_ptr<saml2::NameID> m_nameid;
- mutable map<string,boost::shared_ptr<Assertion>> m_tokens;
+ mutable map< string,boost::shared_ptr<Assertion> > m_tokens;
#endif
mutable vector<Attribute*> m_attributes;
mutable multimap<string,const Attribute*> m_attributeIndex;
CGIParser::~CGIParser()
{
- for_each(kvp_map.begin(), kvp_map.end(), boost::bind(&free, boost::bind(&multimap<string,char*>::value_type::second, _1)));
+ for_each(kvp_map.begin(), kvp_map.end(), boost::bind<void>(&free, boost::bind(&multimap<string,char*>::value_type::second, _1)));
}
void CGIParser::parse(const char* pch)
pair<bool,bool> DOMPropertySet::getBool(const char* name, const char* ns) const
{
- map<string,pair<char*,const XMLCh*> >::const_iterator i;
+ map< string,pair<char*,const XMLCh*> >::const_iterator i;
if (ns)
i=m_map.find(string("{") + ns + '}' + name);
pair<bool,const char*> DOMPropertySet::getString(const char* name, const char* ns) const
{
pair<bool,const char*> ret(false,nullptr);
- map<string,pair<char*,const XMLCh*> >::const_iterator i;
+ map< string,pair<char*,const XMLCh*> >::const_iterator i;
if (ns)
i=m_map.find(string("{") + ns + '}' + name);
pair<bool,const XMLCh*> DOMPropertySet::getXMLString(const char* name, const char* ns) const
{
- map<string,pair<char*,const XMLCh*> >::const_iterator i;
+ map< string,pair<char*,const XMLCh*> >::const_iterator i;
if (ns)
i=m_map.find(string("{") + ns + '}' + name);
pair<bool,int> DOMPropertySet::getInt(const char* name, const char* ns) const
{
- map<string,pair<char*,const XMLCh*> >::const_iterator i;
+ map< string,pair<char*,const XMLCh*> >::const_iterator i;
if (ns)
i=m_map.find(string("{") + ns + '}' + name);
const PropertySet* DOMPropertySet::getPropertySet(const char* name, const char* ns) const
{
- map<string,boost::shared_ptr<DOMPropertySet>>::const_iterator i;
+ map< string,boost::shared_ptr<DOMPropertySet> >::const_iterator i;
if (ns)
i = m_nested.find(string("{") + ns + '}' + name);
const PropertySet* m_parent;
const xercesc::DOMElement* m_root;
std::map<std::string,std::pair<char*,const XMLCh*> > m_map;
- std::map<std::string,boost::shared_ptr<DOMPropertySet>> m_nested;
+ std::map< std::string,boost::shared_ptr<DOMPropertySet> > m_nested;
std::vector<xmltooling::xstring> m_injected;
};