#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);