X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=shibsp%2Fhandler%2Fimpl%2FSAML2ArtifactResolution.cpp;h=ef85778f409ecd4abe51c8b44b9e6cacbc560dcd;hb=392d1448deb48beb75f219532ac248b4776f16db;hp=e61ade58467cbd1c906c2c67b6a01e3f9c29f519;hpb=be3785013d147caabe3b931285f27a674bd05cf8;p=shibboleth%2Fsp.git diff --git a/shibsp/handler/impl/SAML2ArtifactResolution.cpp b/shibsp/handler/impl/SAML2ArtifactResolution.cpp index e61ade5..ef85778 100644 --- a/shibsp/handler/impl/SAML2ArtifactResolution.cpp +++ b/shibsp/handler/impl/SAML2ArtifactResolution.cpp @@ -38,7 +38,6 @@ # include # include # include -# include using namespace opensaml::saml2md; using namespace opensaml::saml2p; using namespace opensaml::saml2; @@ -52,14 +51,10 @@ using namespace shibsp; using namespace opensaml; using namespace soap11; using namespace xmltooling; -using namespace log4cpp; using namespace std; namespace shibsp { - class SHIBSP_API Attribute; - class SHIBSP_API ResolutionContext; - #if defined (_MSC_VER) #pragma warning( push ) #pragma warning( disable : 4250 ) @@ -74,6 +69,12 @@ namespace shibsp { pair run(SPRequest& request, bool isHandler=true) const; void receive(DDF& in, ostream& out); +#ifndef SHIBSP_LITE + const char* getType() const { + return "ArtifactResolutionService"; + } +#endif + private: pair processMessage(const Application& application, HTTPRequest& httpRequest, HTTPResponse& httpResponse) const; #ifndef SHIBSP_LITE @@ -81,6 +82,7 @@ namespace shibsp { const Application& app, const ArtifactResolve& request, HTTPResponse& httpResponse, + const EntityDescriptor* recipient, const XMLCh* code, const XMLCh* subcode=NULL, const char* msg=NULL @@ -104,7 +106,7 @@ namespace shibsp { }; SAML2ArtifactResolution::SAML2ArtifactResolution(const DOMElement* e, const char* appId) - : AbstractHandler(e, Category::getInstance(SHIBSP_LOGCAT".SAML2ArtifactResolution")) + : AbstractHandler(e, Category::getInstance(SHIBSP_LOGCAT".ArtifactResolution.SAML2")) #ifndef SHIBSP_LITE ,m_encoder(NULL), m_decoder(NULL), m_role(samlconstants::SAML20MD_NS, opensaml::saml2md::IDPSSODescriptor::LOCAL_NAME) #endif @@ -112,8 +114,12 @@ SAML2ArtifactResolution::SAML2ArtifactResolution(const DOMElement* e, const char #ifndef SHIBSP_LITE if (SPConfig::getConfig().isEnabled(SPConfig::OutOfProcess)) { try { - m_encoder = SAMLConfig::getConfig().MessageEncoderManager.newPlugin(getString("Binding").second,e); - m_decoder = SAMLConfig::getConfig().MessageDecoderManager.newPlugin(getString("Binding").second,e); + m_encoder = SAMLConfig::getConfig().MessageEncoderManager.newPlugin( + getString("Binding").second,pair(e,NULL) + ); + m_decoder = SAMLConfig::getConfig().MessageDecoderManager.newPlugin( + getString("Binding").second,pair(e,NULL) + ); } catch (exception& ex) { m_log.error("error building MessageEncoder/Decoder pair for binding (%s)", getString("Binding").second); @@ -145,7 +151,6 @@ pair SAML2ArtifactResolution::run(SPRequest& request, bool isHandler) try { if (conf.isEnabled(SPConfig::OutOfProcess)) { // When out of process, we run natively and directly process the message. - string entityID; return processMessage(request.getApplication(), request, request); } else { @@ -153,7 +158,6 @@ pair SAML2ArtifactResolution::run(SPRequest& request, bool isHandler) DDF out,in = wrap(request, NULL, true); DDFJanitor jin(in), jout(out); - in.addmember("application_id").string(request.getApplication().getId()); out=request.getServiceProvider().getListenerService()->send(in); return unwrap(request, out); } @@ -199,7 +203,7 @@ void SAML2ArtifactResolution::receive(DDF& in, ostream& out) if (!app) { // Something's horribly wrong. m_log.error("couldn't find application (%s) for artifact resolution", aid ? aid : "(missing)"); - throw ConfigurationException("Unable to locate application for new session, deleted?"); + throw ConfigurationException("Unable to locate application for artifact resolution, deleted?"); } // Unpack the request. @@ -274,10 +278,12 @@ pair SAML2ArtifactResolution::processMessage(const Application& appli if (!req) throw FatalProfileException("Decoded message was not a samlp::ArtifactResolve request."); + const EntityDescriptor* entity = policy.getIssuerMetadata() ? dynamic_cast(policy.getIssuerMetadata()->getParent()) : NULL; + try { auto_ptr_char artifact(req->getArtifact() ? req->getArtifact()->getArtifact() : NULL); if (!artifact.get() || !*artifact.get()) - return samlError(application, *req, httpResponse, StatusCode::REQUESTER, NULL, "Request did not contain an artifact to resolve."); + return samlError(application, *req, httpResponse, entity, StatusCode::REQUESTER, NULL, "Request did not contain an artifact to resolve."); auto_ptr_char issuer(policy.getIssuer() ? policy.getIssuer()->getName() : NULL); m_log.info("resolving artifact (%s) for (%s)", artifact.get(), issuer.get() ? issuer.get() : "unknown"); @@ -286,9 +292,9 @@ pair SAML2ArtifactResolution::processMessage(const Application& appli auto_ptr artobj(SAMLArtifact::parse(artifact.get())); auto_ptr payload(artmap->retrieveContent(artobj.get(), issuer.get())); - if (!policy.isSecure()) { + if (!policy.isAuthenticated()) { m_log.error("request for artifact was unauthenticated, purging the artifact mapping"); - return samlError(application, *req, httpResponse, StatusCode::REQUESTER, StatusCode::AUTHN_FAILED, "Unable to authenticate request."); + return samlError(application, *req, httpResponse, entity, StatusCode::REQUESTER, StatusCode::AUTHN_FAILED, "Unable to authenticate request."); } m_log.debug("artifact resolved, preparing response"); @@ -297,73 +303,41 @@ pair SAML2ArtifactResolution::processMessage(const Application& appli auto_ptr resp(ArtifactResponseBuilder::buildArtifactResponse()); resp->setInResponseTo(req->getID()); Issuer* me = IssuerBuilder::buildIssuer(); - me->setName(application.getXMLString("entityID").second); + me->setName(application.getRelyingParty(entity)->getXMLString("entityID").second); resp->setPayload(payload.release()); - const EntityDescriptor* entity = - policy.getIssuerMetadata() ? dynamic_cast(policy.getIssuerMetadata()->getParent()) : NULL; - const PropertySet* relyingParty = application.getRelyingParty(entity); - pair flag = relyingParty->getBool("signResponses"); - if (flag.first && flag.second && policy.getIssuerMetadata()) { - CredentialResolver* credResolver=application.getCredentialResolver(); - if (credResolver) { - Locker credLocker(credResolver); - // Fill in criteria to use. - MetadataCredentialCriteria mcc(*policy.getIssuerMetadata()); - mcc.setUsage(CredentialCriteria::SIGNING_CREDENTIAL); - pair keyName = relyingParty->getString("keyName"); - if (keyName.first) - mcc.getKeyNames().insert(keyName.second); - pair sigalg = relyingParty->getXMLString("signatureAlg"); - if (sigalg.first) - mcc.setXMLAlgorithm(sigalg.second); - const Credential* cred = credResolver->resolve(&mcc); - if (cred) { - // Signed request. - long ret = m_encoder->encode( - httpResponse, - resp.get(), - NULL, - entity, - relayState.c_str(), - NULL, - cred, - sigalg.second, - relyingParty->getXMLString("digestAlg").second - ); - resp.release(); // freed by encoder - return make_pair(true,ret); - } - else { - m_log.warn("no signing credential resolved, leaving response unsigned"); - } - } - } - - long ret = m_encoder->encode(httpResponse, resp.get(), NULL, entity, relayState.c_str()); + long ret = sendMessage( + *m_encoder, resp.get(), relayState.c_str(), NULL, policy.getIssuerMetadata(), application, httpResponse, "signResponses" + ); resp.release(); // freed by encoder return make_pair(true,ret); } catch (exception& ex) { // Trap localized errors in a SAML Response. m_log.error("error processing artifact request, returning SAML error: %s", ex.what()); - return samlError(application, *req, httpResponse, StatusCode::RESPONDER, NULL, ex.what()); + return samlError(application, *req, httpResponse, entity, StatusCode::RESPONDER, NULL, ex.what()); } #else - return make_pair(false,0); + return make_pair(false,0L); #endif } #ifndef SHIBSP_LITE pair SAML2ArtifactResolution::samlError( - const Application& app, const ArtifactResolve& request, HTTPResponse& httpResponse, const XMLCh* code, const XMLCh* subcode, const char* msg + const Application& app, + const ArtifactResolve& request, + HTTPResponse& httpResponse, + const EntityDescriptor* recipient, + const XMLCh* code, + const XMLCh* subcode, + const char* msg ) const { auto_ptr resp(ArtifactResponseBuilder::buildArtifactResponse()); resp->setInResponseTo(request.getID()); Issuer* me = IssuerBuilder::buildIssuer(); - me->setName(app.getXMLString("entityID").second); - prepareResponse(*resp.get(), code, subcode, msg); + me->setName(app.getRelyingParty(recipient)->getXMLString("entityID").second); + fillStatus(*resp.get(), code, subcode, msg); long ret = m_encoder->encode(httpResponse, resp.get(), NULL); resp.release(); // freed by encoder return make_pair(true,ret);