[shibboleth-sp2] 46/89: SSPCPP-528 - AttributeQuery Handler
Ferenc Wágner
wferi at moszumanska.debian.org
Thu Sep 1 09:24:08 UTC 2016
This is an automated email from the git hooks/post-receive script.
wferi pushed a commit to branch master
in repository shibboleth-sp2.
commit 09616f149b56532aeb60cad07e7a935b72f1dfec
Author: Scott Cantor <cantor.2 at osu.edu>
Date: Tue Jun 7 14:08:12 2016 -0400
SSPCPP-528 - AttributeQuery Handler
https://issues.shibboleth.net/jira/browse/SSPCPP-528
Reworked to support more flexible configuration.
---
plugins/AttributeResolverHandler.cpp | 165 ++++++++++++++++++++---------------
1 file changed, 93 insertions(+), 72 deletions(-)
diff --git a/plugins/AttributeResolverHandler.cpp b/plugins/AttributeResolverHandler.cpp
index 554b3a0..3fdbc9d 100644
--- a/plugins/AttributeResolverHandler.cpp
+++ b/plugins/AttributeResolverHandler.cpp
@@ -24,12 +24,6 @@
* Handler that runs the attribute resolver machinery and outputs the results directly.
*/
-#if defined (_MSC_VER) || defined(__BORLANDC__)
-# include "config_win32.h"
-#else
-# include "config.h"
-#endif
-
#include "internal.h"
#include <shibsp/Application.h>
@@ -65,13 +59,13 @@
using namespace std;
using namespace shibsp;
+using namespace opensaml;
using namespace xmltooling;
using namespace xercesc;
using namespace boost;
#ifndef SHIBSP_LITE
using namespace opensaml::saml2md;
-using namespace opensaml;
#endif
namespace shibsp {
@@ -93,23 +87,24 @@ namespace shibsp {
private:
pair<bool,long> processMessage(
const Application& application,
- const HTTPRequest& httpRequest,
+ const char* protocol,
+ const char* entityID,
+ const char* format,
+ const char* nameID,
+ const char* encoding,
HTTPResponse& httpResponse
) const;
#ifndef SHIBSP_LITE
ResolutionContext* resolveAttributes(
const Application& application,
- const GenericRequest* request,
const RoleDescriptor* issuer,
const XMLCh* protocol,
const saml1::NameIdentifier* v1nameid,
const saml2::NameID* nameid
) const;
- ostream& buildJSON(ostream& os, vector<shibsp::Attribute*>& attributes) const;
-
- string m_encoding;
+ ostream& buildJSON(ostream& os, vector<shibsp::Attribute*>& attributes, const char* encoding) const;
#endif
};
@@ -196,11 +191,6 @@ AttributeResolverHandler::AttributeResolverHandler(const DOMElement* e, const ch
string address(appId);
address += prop.second;
setAddress(address.c_str());
-
-#ifndef SHIBSP_LITE
- pair<bool, const char*> encoding = getString("encoding");
- m_encoding = encoding.first ? encoding.second : "";
-#endif
}
pair<bool,long> AttributeResolverHandler::run(SPRequest& request, bool isHandler) const
@@ -213,15 +203,45 @@ pair<bool,long> AttributeResolverHandler::run(SPRequest& request, bool isHandler
request.setResponseHeader("Expires","Wed, 01 Jan 1997 12:00:00 GMT");
request.setResponseHeader("Cache-Control","private,no-store,no-cache,max-age=0");
request.setContentType("application/json; charset=utf-8");
+
+ pair<bool,const char*> param_protocol = getString("protocol", request, HANDLER_PROPERTY_REQUEST|HANDLER_PROPERTY_FIXED);
+ pair<bool,const char*> param_issuer = getString("entityID", request, HANDLER_PROPERTY_REQUEST|HANDLER_PROPERTY_FIXED);
+ pair<bool,const char*> param_format = getString("format", request, HANDLER_PROPERTY_REQUEST|HANDLER_PROPERTY_FIXED);
+ pair<bool,const char*> param_nameid = getString("nameId", request, HANDLER_PROPERTY_REQUEST|HANDLER_PROPERTY_FIXED);
+ pair<bool,const char*> param_encoding = getString("encoding", request, HANDLER_PROPERTY_REQUEST|HANDLER_PROPERTY_FIXED);
+
+ if (!param_nameid.first) {
+ m_log.error("AttributResolver handler requires nameId parameter");
+ istringstream msg("{}");
+ return make_pair(true, request.sendResponse(msg, HTTPResponse::XMLTOOLING_HTTP_STATUS_BADREQUEST));
+ }
+
try {
if (SPConfig::getConfig().isEnabled(SPConfig::OutOfProcess)) {
// When out of process, we run natively and directly process the message.
- return processMessage(request.getApplication(), request, request);
+ return processMessage(
+ request.getApplication(),
+ param_protocol.second,
+ param_issuer.second,
+ param_format.second,
+ param_nameid.second,
+ param_encoding.second,
+ request);
}
else {
// When not out of process, we remote all the message processing.
- DDF out,in = wrap(request);
+ DDF out,in = DDF(m_address.c_str()).structure();
DDFJanitor jin(in), jout(out);
+ in.addmember("application_id").string(request.getApplication().getId());
+ if (param_protocol.first)
+ in.addmember("protocol").string(param_protocol.second);
+ if (param_issuer.first)
+ in.addmember("entityID").string(param_issuer.second);
+ if (param_format.first)
+ in.addmember("format").string(param_format.second);
+ in.addmember("nameID").string(param_nameid.second);
+ if (param_encoding.first)
+ in.addmember("encoding").string(param_encoding.second);
out=request.getServiceProvider().getListenerService()->send(in);
return unwrap(request, out);
}
@@ -240,21 +260,34 @@ void AttributeResolverHandler::receive(DDF& in, ostream& out)
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 AttributeQuery request", aid ? aid : "(missing)");
+ m_log.error("couldn't find application (%s) for AttributeResolver request", aid ? aid : "(missing)");
throw ConfigurationException("Unable to locate application for request, deleted?");
}
+ const char* nameID = in["nameID"].string();
+ if (!nameID) {
+ // Something's horribly wrong.
+ m_log.error("no nameId parameter supplied for request");
+ throw FatalProfileException("Required nameId parameter not found");
+ }
+
// Wrap a response shim.
DDF ret(nullptr);
DDFJanitor jout(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.
try {
- processMessage(*app, *req, *resp);
+ processMessage(
+ *app,
+ in["protocol"].string(),
+ in["entityID"].string(),
+ in["format"].string(),
+ in["nameID"].string(),
+ in["encoding"].string(),
+ *resp);
}
catch (std::exception& ex) {
m_log.error("raising exception: %s", ex.what());
@@ -264,45 +297,34 @@ void AttributeResolverHandler::receive(DDF& in, ostream& out)
}
pair<bool,long> AttributeResolverHandler::processMessage(
- const Application& application, const HTTPRequest& httpRequest, HTTPResponse& httpResponse
+ const Application& application,
+ const char* protocol,
+ const char* entityID,
+ const char* format,
+ const char* nameID,
+ const char* encoding,
+ HTTPResponse& httpResponse
) const
{
#ifndef SHIBSP_LITE
- m_log.debug("processing status request");
- m_log.debug("request URL: %s", httpRequest.getRequestURL());
-
- const char* param_protocol = httpRequest.getParameter("protocol");
- const char* param_issuer = httpRequest.getParameter("entityID");
- const char* param_format = httpRequest.getParameter("format");
- const char* param_nameid = httpRequest.getParameter("nameId");
-
- m_log.debug("protocol = %s, entityID = %s, format = %s, name = %s",
- param_protocol, param_issuer, param_format, param_nameid);
-
stringstream msg;
- if (!param_nameid || !*param_nameid) {
- m_log.error("AttributeQuery Handler requires nameId parameter");
- msg << "{}";
- return make_pair(true, httpResponse.sendResponse(msg, HTTPResponse::XMLTOOLING_HTTP_STATUS_BADREQUEST));
- }
-
- const auto_ptr_XMLCh issuer(param_issuer);
- const auto_ptr_XMLCh nameid(param_nameid);
- const auto_ptr_XMLCh format(param_format);
-
- if (param_protocol) {
- if (strcmp(param_protocol, "SAML2.0") == 0)
- param_protocol = "urn:oasis:names:tc:SAML:2.0:protocol"; // samlconstants::SAML20P_NS;
- else if (strcmp(param_protocol, "SAML1.1") == 0)
- param_protocol = "urn:oasis:names:tc:SAML:1.1:protocol"; // samlconstants::SAML11_PROTOCOL_ENUM;
- else if (strcmp(param_protocol, "SAML1.0") == 0)
- param_protocol = "urn:oasis:names:tc:SAML:1.0:protocol"; // samlconstants::SAML10_PROTOCOL_ENUM;
+ const auto_ptr_XMLCh w_entityID(entityID);
+ const auto_ptr_XMLCh w_nameID(nameID);
+ const auto_ptr_XMLCh w_format(format);
+
+ if (protocol) {
+ if (!strcmp(protocol, "SAML2.0"))
+ protocol = "urn:oasis:names:tc:SAML:2.0:protocol"; // samlconstants::SAML20P_NS;
+ else if (!strcmp(protocol, "SAML1.1"))
+ protocol = "urn:oasis:names:tc:SAML:1.1:protocol"; // samlconstants::SAML11_PROTOCOL_ENUM;
+ else if (!strcmp(protocol, "SAML1.0"))
+ protocol = "urn:oasis:names:tc:SAML:1.0:protocol"; // samlconstants::SAML10_PROTOCOL_ENUM;
}
else {
- param_protocol = "urn:oasis:names:tc:SAML:2.0:protocol"; // samlconstants::SAML20P_NS;
+ protocol = "urn:oasis:names:tc:SAML:2.0:protocol"; // samlconstants::SAML20P_NS;
}
- const auto_ptr_XMLCh protocol(param_protocol);
+ const auto_ptr_XMLCh w_protocol(protocol);
try {
scoped_ptr<ResolutionContext> ctx;
@@ -310,28 +332,28 @@ pair<bool,long> AttributeResolverHandler::processMessage(
MetadataProvider* m = application.getMetadataProvider();
Locker mlock(m);
- MetadataProviderCriteria mc(application, param_issuer, &IDPSSODescriptor::ELEMENT_QNAME, protocol.get());
+ MetadataProviderCriteria mc(application, entityID, &IDPSSODescriptor::ELEMENT_QNAME, w_protocol.get());
pair<const EntityDescriptor*,const RoleDescriptor*> site = m->getEntityDescriptor(mc);
if (!site.first)
- m_log.info("Unable to locate metadata for IdP (%s).", param_issuer);
+ m_log.info("Unable to locate metadata for IdP (%s).", entityID);
// Build NameID(s).
scoped_ptr<saml1::NameIdentifier> v1name;
scoped_ptr<saml2::NameID> v2name(saml2::NameIDBuilder::buildNameID());
- v2name->setName(nameid.get());
- v2name->setFormat(format.get());
- v2name->setNameQualifier(issuer.get());
+ v2name->setName(w_nameID.get());
+ v2name->setFormat(w_format.get());
+ v2name->setNameQualifier(w_entityID.get());
v2name->setSPNameQualifier(application.getRelyingParty(site.first)->getXMLString("entityID").second);
- if (!XMLString::equals(protocol.get(), samlconstants::SAML20P_NS)) {
+ if (!XMLString::equals(w_protocol.get(), samlconstants::SAML20P_NS)) {
v1name.reset(saml1::NameIdentifierBuilder::buildNameIdentifier());
- v1name->setName(nameid.get());
- v1name->setFormat(format.get());
- v1name->setNameQualifier(issuer.get());
+ v1name->setName(w_nameID.get());
+ v1name->setFormat(w_format.get());
+ v1name->setNameQualifier(w_entityID.get());
}
- ctx.reset(resolveAttributes(application, &httpRequest, site.second, protocol.get(), v1name.get(), v2name.get()));
+ ctx.reset(resolveAttributes(application, site.second, w_protocol.get(), v1name.get(), v2name.get()));
- buildJSON(msg, ctx->getResolvedAttributes());
+ buildJSON(msg, ctx->getResolvedAttributes(), encoding);
}
catch (std::exception& ex) {
m_log.error("error while processing request: %s", ex.what());
@@ -347,7 +369,6 @@ pair<bool,long> AttributeResolverHandler::processMessage(
#ifndef SHIBSP_LITE
ResolutionContext* AttributeResolverHandler::resolveAttributes(
const Application& application,
- const GenericRequest* request,
const RoleDescriptor* issuer,
const XMLCh* protocol,
const saml1::NameIdentifier* v1nameid,
@@ -365,7 +386,7 @@ ResolutionContext* AttributeResolverHandler::resolveAttributes(
m_log.debug("extracting metadata-derived attributes...");
try {
// We pass nullptr for "issuer" because the IdP isn't the one asserting metadata-based attributes.
- extractor->extractAttributes(application, request, nullptr, *issuer, resolvedAttributes);
+ extractor->extractAttributes(application, nullptr, nullptr, *issuer, resolvedAttributes);
for (indirect_iterator<vector<Attribute*>::iterator> a = make_indirect_iterator(resolvedAttributes.begin());
a != make_indirect_iterator(resolvedAttributes.end()); ++a) {
vector<string>& ids = a->getAliases();
@@ -384,9 +405,9 @@ ResolutionContext* AttributeResolverHandler::resolveAttributes(
if (v1nameid || nameid) {
try {
if (v1nameid)
- extractor->extractAttributes(application, request, issuer, *v1nameid, resolvedAttributes);
+ extractor->extractAttributes(application, nullptr, issuer, *v1nameid, resolvedAttributes);
else
- extractor->extractAttributes(application, request, issuer, *nameid, resolvedAttributes);
+ extractor->extractAttributes(application, nullptr, issuer, *nameid, resolvedAttributes);
}
catch (std::exception& ex) {
m_log.error("caught exception extracting attributes: %s", ex.what());
@@ -418,7 +439,7 @@ ResolutionContext* AttributeResolverHandler::resolveAttributes(
auto_ptr<ResolutionContext> ctx(
resolver->createResolutionContext(
application,
- request,
+ nullptr,
issuer ? dynamic_cast<const saml2md::EntityDescriptor*>(issuer->getParent()) : nullptr,
protocol,
nameid,
@@ -452,7 +473,7 @@ ResolutionContext* AttributeResolverHandler::resolveAttributes(
return nullptr;
}
-ostream& AttributeResolverHandler::buildJSON(ostream& os, vector<shibsp::Attribute*>& attributes) const
+ostream& AttributeResolverHandler::buildJSON(ostream& os, vector<shibsp::Attribute*>& attributes, const char* encoding) const
{
m_log.debug("building JSON from attributes..");
@@ -473,7 +494,7 @@ ostream& AttributeResolverHandler::buildJSON(ostream& os, vector<shibsp::Attribu
json_safe(os, s->c_str());
os << " : ";
- if (m_encoding.empty() || m_encoding == "JSON") {
+ if (!encoding || !strcmp(encoding,"JSON")) {
os << '[' << endl;
vector<string>::const_iterator vhead = a->getSerializedValues().begin();
for (vector<string>::const_iterator v = vhead; v != a->getSerializedValues().end(); ++v) {
@@ -484,7 +505,7 @@ ostream& AttributeResolverHandler::buildJSON(ostream& os, vector<shibsp::Attribu
}
os << endl << " ]";
}
- else if (m_encoding == "JSON/CGI") {
+ else if (!strcmp(encoding,"JSON/CGI")) {
string attrValues;
vector<string>::const_iterator vhead = a->getSerializedValues().begin();
for (vector<string>::const_iterator v = vhead; v != a->getSerializedValues().end(); ++v) {
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-shibboleth/shibboleth-sp2.git
More information about the Pkg-shibboleth-devel
mailing list