X-Git-Url: http://www.project-moonshot.org/gitweb/?p=shibboleth%2Fcpp-opensaml.git;a=blobdiff_plain;f=saml%2Fsaml2%2Fbinding%2Fimpl%2FSAML2POSTEncoder.cpp;h=6fc4bc6ab738e38fa13c8f4cb75a0dac0e80f02a;hp=662d52f68cf200b5a71a8da0c5697801b8a4bf8b;hb=07dbbcf3a8fc0aba6fefe741f1760442a0a6ea65;hpb=11cd3b15c71ee22f2818d810a17c213123e8c248 diff --git a/saml/saml2/binding/impl/SAML2POSTEncoder.cpp b/saml/saml2/binding/impl/SAML2POSTEncoder.cpp index 662d52f..6fc4bc6 100644 --- a/saml/saml2/binding/impl/SAML2POSTEncoder.cpp +++ b/saml/saml2/binding/impl/SAML2POSTEncoder.cpp @@ -28,17 +28,19 @@ #include #include -#include #include +#include +#include #include +#include #include using namespace opensaml::saml2p; using namespace opensaml::saml2md; using namespace opensaml; using namespace xmlsignature; +using namespace xmltooling::logging; using namespace xmltooling; -using namespace log4cpp; using namespace std; namespace opensaml { @@ -89,6 +91,7 @@ SAML2POSTEncoder::SAML2POSTEncoder(const DOMElement* e, const XMLCh* ns, bool si } if (m_template.empty()) throw XMLToolingException("SAML2POSTEncoder requires template XML attribute."); + XMLToolingConfig::getConfig().getPathResolver()->resolve(m_template, PathResolver::XMLTOOLING_CFG_FILE); } long SAML2POSTEncoder::encode( @@ -108,6 +111,10 @@ long SAML2POSTEncoder::encode( #endif Category& log = Category::getInstance(SAML_LOGCAT".MessageEncoder.SAML2POST"); + TemplateEngine* engine = XMLToolingConfig::getConfig().getTemplateEngine(); + if (!engine) + throw BindingException("Encoding message using POST requires a TemplateEngine instance."); + log.debug("validating input"); if (xmlObject->getParent()) throw BindingException("Cannot encode XML content with parent."); @@ -150,15 +157,12 @@ long SAML2POSTEncoder::encode( rootElement = xmlObject->marshall((DOMDocument*)NULL); } - // Start tracking data. - TemplateEngine::TemplateParameters pmap; - if (relayState && *relayState) - pmap.m_map["RelayState"] = relayState; - // Serialize the message. + TemplateEngine::TemplateParameters pmap; string& msg = pmap.m_map[(request ? "SAMLRequest" : "SAMLResponse")]; XMLHelper::serialize(rootElement, msg); - + log.debug("marshalled message:\n%s", msg.c_str()); + // SimpleSign. if (credential && m_simple) { log.debug("applying simple signature to message data"); @@ -175,29 +179,55 @@ long SAML2POSTEncoder::encode( memset(sigbuf,0,sizeof(sigbuf)); Signature::createRawSignature(credential->getPrivateKey(), signatureAlg, input.c_str(), input.length(), sigbuf, sizeof(sigbuf)-1); pmap.m_map["Signature"] = sigbuf; + + auto_ptr keyInfo(credential->getKeyInfo()); + if (keyInfo.get()) { + string& kstring = pmap.m_map["KeyInfo"]; + XMLHelper::serialize(keyInfo->marshall((DOMDocument*)NULL), kstring); + xsecsize_t len=0; + XMLByte* out=Base64::encode(reinterpret_cast(kstring.data()),kstring.size(),&len); + if (!out) + throw BindingException("Base64 encoding of XML failed."); + kstring.erase(); + kstring.append(reinterpret_cast(out),len); +#ifdef OPENSAML_XERCESC_HAS_XMLBYTE_RELEASE + XMLString::release(&out); +#else + XMLString::release((char**)&out); +#endif + } } // Base64 the message. - unsigned int len=0; + xsecsize_t len=0; XMLByte* out=Base64::encode(reinterpret_cast(msg.data()),msg.size(),&len); if (!out) throw BindingException("Base64 encoding of XML failed."); msg.erase(); msg.append(reinterpret_cast(out),len); +#ifdef OPENSAML_XERCESC_HAS_XMLBYTE_RELEASE XMLString::release(&out); +#else + XMLString::release((char**)&out); +#endif - // Push message into template and send result to client. + // Push the rest of it into template and send result to client. log.debug("message encoded, sending HTML form template to client"); - TemplateEngine* engine = XMLToolingConfig::getConfig().getTemplateEngine(); - if (!engine) - throw BindingException("Encoding message using POST requires a TemplateEngine instance."); ifstream infile(m_template.c_str()); if (!infile) throw BindingException("Failed to open HTML template for POST message ($1).", params(1,m_template.c_str())); pmap.m_map["action"] = destination; + if (relayState && *relayState) + pmap.m_map["RelayState"] = relayState; stringstream s; engine->run(infile, s, pmap); genericResponse.setContentType("text/html"); + HTTPResponse* httpResponse = dynamic_cast(&genericResponse); + if (httpResponse) { + httpResponse->setResponseHeader("Expires", "01-Jan-1997 12:00:00 GMT"); + httpResponse->setResponseHeader("Cache-Control", "no-cache, no-store, must-revalidate, private"); + httpResponse->setResponseHeader("Pragma", "no-cache"); + } long ret = genericResponse.sendResponse(s); // Cleanup by destroying XML.