X-Git-Url: http://www.project-moonshot.org/gitweb/?p=shibboleth%2Fcpp-opensaml.git;a=blobdiff_plain;f=saml%2Fsaml2%2Fbinding%2Fimpl%2FSAML2RedirectEncoder.cpp;h=604abbca222ea057453658bda3953326ab27007f;hp=c4806f280afbb3ca76cd092bbd32602b27925b58;hb=1462057b3b9ae7e165d34d988e30b14c213672ca;hpb=0e738d39ba71958fe55692498c91fc6e6d402604 diff --git a/saml/saml2/binding/impl/SAML2RedirectEncoder.cpp b/saml/saml2/binding/impl/SAML2RedirectEncoder.cpp index c4806f2..604abbc 100644 --- a/saml/saml2/binding/impl/SAML2RedirectEncoder.cpp +++ b/saml/saml2/binding/impl/SAML2RedirectEncoder.cpp @@ -1,44 +1,53 @@ -/* - * Copyright 2001-2007 Internet2 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/** + * Licensed to the University Corporation for Advanced Internet + * Development, Inc. (UCAID) under one or more contributor license + * agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * UCAID licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the + * License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the License. */ /** * SAML2RedirectEncoder.cpp * - * SAML 2.0 HTTP-POST binding message encoder + * SAML 2.0 HTTP-POST binding message encoder. */ #include "internal.h" #include "exceptions.h" -#include "binding/HTTPResponse.h" #include "binding/MessageEncoder.h" -#include "binding/URLEncoder.h" #include "saml2/binding/SAML2Redirect.h" #include "saml2/core/Protocols.h" #include #include -#include #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 { @@ -46,23 +55,33 @@ namespace opensaml { class SAML_DLLLOCAL SAML2RedirectEncoder : public MessageEncoder { public: - SAML2RedirectEncoder(const DOMElement* e) {} + SAML2RedirectEncoder() {} virtual ~SAML2RedirectEncoder() {} - + + bool isCompact() const { + return true; + } + + const XMLCh* getProtocolFamily() const { + return samlconstants::SAML20P_NS; + } + long encode( GenericResponse& genericResponse, - xmltooling::XMLObject* xmlObject, + XMLObject* xmlObject, const char* destination, - const char* recipientID=NULL, - const char* relayState=NULL, - const xmltooling::CredentialResolver* credResolver=NULL, - const XMLCh* sigAlgorithm=NULL + const EntityDescriptor* recipient=nullptr, + const char* relayState=nullptr, + const ArtifactGenerator* artifactGenerator=nullptr, + const Credential* credential=nullptr, + const XMLCh* signatureAlg=nullptr, + const XMLCh* digestAlg=nullptr ) const; }; - MessageEncoder* SAML_DLLLOCAL SAML2RedirectEncoderFactory(const DOMElement* const & e) + MessageEncoder* SAML_DLLLOCAL SAML2RedirectEncoderFactory(const pair& p) { - return new SAML2RedirectEncoder(e); + return new SAML2RedirectEncoder(); } }; }; @@ -71,16 +90,18 @@ long SAML2RedirectEncoder::encode( GenericResponse& genericResponse, XMLObject* xmlObject, const char* destination, - const char* recipientID, + const EntityDescriptor* recipient, const char* relayState, - const CredentialResolver* credResolver, - const XMLCh* sigAlgorithm + const ArtifactGenerator* artifactGenerator, + const Credential* credential, + const XMLCh* signatureAlg, + const XMLCh* digestAlg ) const { #ifdef _DEBUG xmltooling::NDC ndc("encode"); #endif - Category& log = Category::getInstance(SAML_LOGCAT".MessageEncoder.SAML2Redirect"); + Category& log = Category::getInstance(SAML_LOGCAT ".MessageEncoder.SAML2Redirect"); log.debug("validating input"); HTTPResponse* httpResponse=dynamic_cast(&genericResponse); @@ -89,7 +110,7 @@ long SAML2RedirectEncoder::encode( if (xmlObject->getParent()) throw BindingException("Cannot encode XML content with parent."); - StatusResponseType* response = NULL; + StatusResponseType* response = nullptr; RequestAbstractType* request = dynamic_cast(xmlObject); if (!request) { response = dynamic_cast(xmlObject); @@ -100,49 +121,61 @@ long SAML2RedirectEncoder::encode( // Check for XML signature. if (request ? request->getSignature() : response->getSignature()) { log.debug("message already signed, removing native signature due to size considerations"); - request ? request->setSignature(NULL) : response->setSignature(NULL); + request ? request->setSignature(nullptr) : response->setSignature(nullptr); } log.debug("marshalling, deflating, base64-encoding the message"); DOMElement* rootElement = xmlObject->marshall(); string xmlbuf; XMLHelper::serialize(rootElement, xmlbuf); + log.debug("marshalled message:\n%s", xmlbuf.c_str()); unsigned int len; char* deflated = deflate(const_cast(xmlbuf.c_str()), xmlbuf.length(), &len); if (!deflated) throw BindingException("Failed to deflate message."); - XMLByte* encoded=Base64::encode(reinterpret_cast(deflated),len,&len); + xsecsize_t xlen; + XMLByte* encoded=Base64::encode(reinterpret_cast(deflated), len, &xlen); delete[] deflated; if (!encoded) throw BindingException("Base64 encoding of XML failed."); // Create beginnings of redirect query string. - URLEncoder* escaper = SAMLConfig::getConfig().getURLEncoder(); xmlbuf.erase(); - xmlbuf.append(reinterpret_cast(encoded),len); + for (const XMLByte* xb = encoded; *xb; ++xb) { + if (!isspace(*xb)) + xmlbuf += *xb; + } +#ifdef OPENSAML_XERCESC_HAS_XMLBYTE_RELEASE + XMLString::release(&encoded); +#else + XMLString::release((char**)&encoded); +#endif + + const URLEncoder* escaper = XMLToolingConfig::getConfig().getURLEncoder(); xmlbuf = (request ? "SAMLRequest=" : "SAMLResponse=") + escaper->encode(xmlbuf.c_str()); - if (relayState) + if (relayState && *relayState) xmlbuf = xmlbuf + "&RelayState=" + escaper->encode(relayState); - if (credResolver) { + if (credential) { + log.debug("signing the message"); + // Sign the query string after adding the algorithm. - if (!sigAlgorithm) - sigAlgorithm = DSIGConstants::s_unicodeStrURIRSA_SHA1; - auto_ptr_char alg(sigAlgorithm); + if (!signatureAlg) + signatureAlg = DSIGConstants::s_unicodeStrURIRSA_SHA1; + auto_ptr_char alg(signatureAlg); xmlbuf = xmlbuf + "&SigAlg=" + escaper->encode(alg.get()); char sigbuf[1024]; memset(sigbuf,0,sizeof(sigbuf)); - auto_ptr key(credResolver->getKey()); - Signature::createRawSignature(key.get(), sigAlgorithm, xmlbuf.c_str(), xmlbuf.length(), sigbuf, sizeof(sigbuf)-1); + Signature::createRawSignature(credential->getPrivateKey(), signatureAlg, xmlbuf.c_str(), xmlbuf.length(), sigbuf, sizeof(sigbuf)-1); xmlbuf = xmlbuf + "&Signature=" + escaper->encode(sigbuf); } // Generate redirect. log.debug("message encoded, sending redirect to client"); - xmlbuf.insert(0,1,(strchr(destination,'?') ? '&' : '?')); + xmlbuf.insert((string::size_type)0,(string::size_type)1,(strchr(destination,'?') ? '&' : '?')); xmlbuf.insert(0,destination); long ret = httpResponse->sendRedirect(xmlbuf.c_str());