X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=saml%2Fbinding%2Fimpl%2FSimpleSigningRule.cpp;h=3a0963856c1fa896249314a9ab20d3cad5aa4efe;hb=7b0820d9540ad50c497d8d69e4109b28c4c15944;hp=3e7952dcd3e5a04f2e25adb137f256f87103b930;hpb=3707f5b955c6f538e1b0122f51290cfe684db4f8;p=shibboleth%2Fopensaml2.git diff --git a/saml/binding/impl/SimpleSigningRule.cpp b/saml/binding/impl/SimpleSigningRule.cpp index 3e7952d..3a09638 100644 --- a/saml/binding/impl/SimpleSigningRule.cpp +++ b/saml/binding/impl/SimpleSigningRule.cpp @@ -22,13 +22,11 @@ #include "internal.h" #include "exceptions.h" -#include "RootObject.h" #include "binding/HTTPRequest.h" #include "binding/SimpleSigningRule.h" #include "saml2/core/Protocols.h" #include "saml2/metadata/Metadata.h" #include "saml2/metadata/MetadataProvider.h" -#include "security/TrustEngine.h" #include #include @@ -69,12 +67,12 @@ namespace opensaml { }; -pair SimpleSigningRule::evaluate( +pair SimpleSigningRule::evaluate( const GenericRequest& request, const XMLObject& message, const MetadataProvider* metadataProvider, const QName* role, - const opensaml::TrustEngine* trustEngine + const TrustEngine* trustEngine ) const { Category& log=Category::getInstance(SAML_LOGCAT".SecurityPolicyRule.SimpleSigning"); @@ -118,31 +116,48 @@ pair SimpleSigningRule::evaluate( return ret; } - log.debug("matched assertion issuer against metadata, searching for applicable role..."); + log.debug("matched message issuer against metadata, searching for applicable role..."); const RoleDescriptor* roledesc=entity->getRoleDescriptor(*role, issuerInfo.second); if (!roledesc) { log.warn("unable to find compatible role (%s) in metadata", role->toString().c_str()); return ret; } - // We have to construct a string containing the signature input by accessing the - // request directly. We can't use the decoded parameters because we need the raw - // data and URL-encoding isn't canonical. string input; + const char* pch; const HTTPRequest& httpRequest = dynamic_cast(request); - const char* raw = - (!strcmp(httpRequest.getMethod(), "GET")) ? httpRequest.getQueryString() : httpRequest.getRequestBody(); - if (!appendParameter(input, raw, "SAMLRequest=")) - appendParameter(input, raw, "SAMLResponse="); - appendParameter(input, raw, "RelayState="); - appendParameter(input, raw, "SigAlg="); + if (!strcmp(httpRequest.getMethod(), "GET")) { + // We have to construct a string containing the signature input by accessing the + // request directly. We can't use the decoded parameters because we need the raw + // data and URL-encoding isn't canonical. + pch = httpRequest.getQueryString(); + if (!appendParameter(input, pch, "SAMLRequest=")) + appendParameter(input, pch, "SAMLResponse="); + appendParameter(input, pch, "RelayState="); + appendParameter(input, pch, "SigAlg="); + } + else { + // With POST, the input string is concatenated from the decoded form controls. + // GET should be this way too, but I messed up the spec, sorry. + pch = httpRequest.getParameter("SAMLRequest"); + if (pch) + input = string("SAMLRequest=") + pch; + else { + pch = httpRequest.getParameter("SAMLResponse"); + input = string("SAMLResponse=") + pch; + } + pch = httpRequest.getParameter("RelayState"); + if (pch) + input = input + "&RelayState=" + pch; + input = input + "&SigAlg=" + sigAlgorithm; + } // Check for KeyInfo, but defensively (we might be able to run without it). KeyInfo* keyInfo=NULL; - const char* k = request.getParameter("KeyInfo"); - if (k) { + pch = request.getParameter("KeyInfo"); + if (pch) { try { - istringstream kstrm(k); + istringstream kstrm(pch); DOMDocument* doc = XMLToolingConfig::getConfig().getParser().parse(kstrm); XercesJanitor janitor(doc); XMLObject* kxml = XMLObjectBuilder::buildOneFromElement(doc->getDocumentElement(), true); @@ -185,13 +200,12 @@ pair SimpleSigningRule::getIssuerAndProtocol(const // Shortcuts some of the casting. const XMLCh* ns = message.getElementQName().getNamespaceURI(); if (ns) { - if (XMLString::equals(ns, samlconstants::SAML20P_NS) || XMLString::equals(ns, samlconstants::SAML20_NS)) { + if (XMLString::equals(ns, samlconstants::SAML20P_NS)) { // 2.0 namespace should be castable to a specialized 2.0 root. const saml2::RootObject& root = dynamic_cast(message); saml2::Issuer* issuer = root.getIssuer(); - if (issuer && issuer->getName()) { + if (issuer && issuer->getName()) return make_pair(issuer->cloneIssuer(), samlconstants::SAML20P_NS); - } // No issuer in the message, so we have to try the Response approach. const vector& assertions = dynamic_cast(message).getAssertions();