X-Git-Url: http://www.project-moonshot.org/gitweb/?p=shibboleth%2Fopensaml2.git;a=blobdiff_plain;f=saml%2Fsaml2%2Fbinding%2Fimpl%2FSAML2SOAPEncoder.cpp;h=64acb647470a9f8bdb77efcf19339ddf2879afa6;hp=c8c4739def66dbd340683a03ed90dc1ff6502131;hb=5614d09808af42eb625cc8f5605dd5ebaefe9457;hpb=52e60cde5677b1bd021778292a27e6df8396de40 diff --git a/saml/saml2/binding/impl/SAML2SOAPEncoder.cpp b/saml/saml2/binding/impl/SAML2SOAPEncoder.cpp index c8c4739..64acb64 100644 --- a/saml/saml2/binding/impl/SAML2SOAPEncoder.cpp +++ b/saml/saml2/binding/impl/SAML2SOAPEncoder.cpp @@ -101,15 +101,29 @@ long SAML2SOAPEncoder::encode( httpResponse->setResponseHeader("Pragma", "no-cache"); } + bool detachOnFailure = false; DOMElement* rootElement = NULL; + + // Check for a naked message. SignableObject* msg = dynamic_cast(xmlObject); if (msg) { + // Wrap it in a SOAP envelope and point xmlObject at that. + detachOnFailure = true; + Envelope* env = EnvelopeBuilder::buildEnvelope(); + Body* body = BodyBuilder::buildBody(); + env->setBody(body); + body->getUnknownXMLObjects().push_back(msg); + xmlObject = env; + } + + Envelope* env = dynamic_cast(xmlObject); + if (env) { + if (!msg) { + msg = (env->getBody() && env->getBody()->hasChildren()) ? + dynamic_cast(env->getBody()->getUnknownXMLObjects().front()) : NULL; + } try { - Envelope* env = EnvelopeBuilder::buildEnvelope(); - Body* body = BodyBuilder::buildBody(); - env->setBody(body); - body->getUnknownXMLObjects().push_back(msg); - if (credential) { + if (msg && credential) { if (msg->getSignature()) { log.debug("message already signed, skipping signature operation"); rootElement = env->marshall(); @@ -137,22 +151,27 @@ long SAML2SOAPEncoder::encode( log.debug("marshalling the envelope"); rootElement = env->marshall(); } - - stringstream s; - s << *rootElement; + + string xmlbuf; + XMLHelper::serialize(rootElement, xmlbuf); + istringstream s(xmlbuf); log.debug("sending serialized envelope"); - long ret = genericResponse.sendResponse(s); + bool error = (!msg && env->getBody() && env->getBody()->hasChildren() && + dynamic_cast(env->getBody()->getUnknownXMLObjects().front())); + long ret = error ? genericResponse.sendError(s) : genericResponse.sendResponse(s); // Cleanup by destroying XML. delete env; return ret; } catch (XMLToolingException&) { - // A bit weird...we have to "revert" things so that the response is isolated - // so the caller can free it. - if (msg->getParent()) { - msg->getParent()->detach(); - msg->detach(); + if (msg && detachOnFailure) { + // A bit weird...we have to "revert" things so that the message is isolated + // so the caller can free it. + if (msg->getParent()) { + msg->getParent()->detach(); + msg->detach(); + } } throw; } @@ -189,54 +208,5 @@ long SAML2SOAPEncoder::encode( } } - Envelope* env = dynamic_cast(xmlObject); - if (env) { - SignableObject* msg = - (env->getBody() && env->getBody()->hasChildren()) ? - dynamic_cast(env->getBody()->getUnknownXMLObjects().front()) : NULL; - if (msg && credential) { - if (msg->getSignature()) { - log.debug("message already signed, skipping signature operation"); - rootElement = env->marshall(); - } - else { - log.debug("signing the message and marshalling the envelope"); - - // Build a Signature. - Signature* sig = SignatureBuilder::buildSignature(); - msg->setSignature(sig); - if (signatureAlg) - sig->setSignatureAlgorithm(signatureAlg); - if (digestAlg) { - opensaml::ContentReference* cr = dynamic_cast(sig->getContentReference()); - if (cr) - cr->setDigestAlgorithm(digestAlg); - } - - // Sign message while marshalling. - vector sigs(1,sig); - rootElement = env->marshall((DOMDocument*)NULL,&sigs,credential); - } - } - else { - log.debug("marshalling the envelope"); - rootElement = env->marshall(); - } - - string xmlbuf; - XMLHelper::serialize(rootElement, xmlbuf); - istringstream s(xmlbuf); - log.debug("sending serialized envelope"); - bool error = - (env->getBody() && - env->getBody()->hasChildren() && - dynamic_cast(env->getBody()->getUnknownXMLObjects().front())); - long ret = error ? genericResponse.sendError(s) : genericResponse.sendResponse(s); - - // Cleanup by destroying XML. - delete env; - return ret; - } - throw BindingException("XML content for SAML 2.0 SOAP Encoder must be a SAML 2.0 message or SOAP Fault/Envelope."); }