From 5614d09808af42eb625cc8f5605dd5ebaefe9457 Mon Sep 17 00:00:00 2001 From: cantor Date: Tue, 6 Nov 2007 17:08:12 +0000 Subject: [PATCH] Simplify encoder processing a bit. git-svn-id: https://svn.middleware.georgetown.edu/cpp-opensaml2/trunk@330 fb386ef7-a10c-0410-8ebf-fd3f8e989ab0 --- saml/saml1/binding/impl/SAML1SOAPEncoder.cpp | 100 ++++++++++----------------- saml/saml2/binding/impl/SAML2SOAPEncoder.cpp | 96 +++++++++---------------- 2 files changed, 69 insertions(+), 127 deletions(-) diff --git a/saml/saml1/binding/impl/SAML1SOAPEncoder.cpp b/saml/saml1/binding/impl/SAML1SOAPEncoder.cpp index 4f56e76..025a88c 100644 --- a/saml/saml1/binding/impl/SAML1SOAPEncoder.cpp +++ b/saml/saml1/binding/impl/SAML1SOAPEncoder.cpp @@ -101,15 +101,31 @@ long SAML1SOAPEncoder::encode( httpResponse->setResponseHeader("Pragma", "no-cache"); } + bool detachOnFailure = false; DOMElement* rootElement = NULL; + + // Check for a naked Response. Response* response = dynamic_cast(xmlObject); if (response) { + // 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(response); + xmlObject = env; + } + + // Now check for a full Envelope (which might have just been created). + Envelope* env = dynamic_cast(xmlObject); + if (env) { + if (!response) { + response = (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(response); - if (credential) { + // Now check for signing requirements. + if (response && credential) { if (response->getSignature()) { log.debug("response already signed, skipping signature operation"); rootElement = env->marshall(); @@ -128,7 +144,7 @@ long SAML1SOAPEncoder::encode( cr->setDigestAlgorithm(digestAlg); } - // Sign response while marshalling. + // Sign message while marshalling. vector sigs(1,sig); rootElement = env->marshall((DOMDocument*)NULL,&sigs,credential); } @@ -137,22 +153,27 @@ long SAML1SOAPEncoder::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 = (!response && 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 (response->getParent()) { - response->getParent()->detach(); - response->detach(); + if (response && detachOnFailure) { + // A bit weird...we have to "revert" things so that the response is isolated + // so the caller can free it. + if (response->getParent()) { + response->getParent()->detach(); + response->detach(); + } } throw; } @@ -188,55 +209,6 @@ long SAML1SOAPEncoder::encode( throw; } } - - Envelope* env = dynamic_cast(xmlObject); - if (env) { - Response* response = - (env->getBody() && env->getBody()->hasChildren()) ? - dynamic_cast(env->getBody()->getUnknownXMLObjects().front()) : NULL; - if (response && credential) { - if (response->getSignature()) { - log.debug("response already signed, skipping signature operation"); - rootElement = env->marshall(); - } - else { - log.debug("signing the response and marshalling the envelope"); - // Build a Signature. - Signature* sig = SignatureBuilder::buildSignature(); - response->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 1.x SOAP Encoder must be a SAML 1.x or SOAP Fault/Envelope."); } 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."); } -- 2.1.4