X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=saml%2Fsaml2%2Fbinding%2Fimpl%2FSAML2RedirectDecoder.cpp;h=4c8e3b02d388a2903d22fd3b55feeabe7185dca2;hb=932cfaae2176c2eba1a9938dc420591a9551a7f3;hp=9efd6e4ff3199dcd1d92e4fdbbbebec24de264e8;hpb=2b23fb86e346ed4a6cadd182384873245ec41a6c;p=shibboleth%2Fcpp-opensaml.git diff --git a/saml/saml2/binding/impl/SAML2RedirectDecoder.cpp b/saml/saml2/binding/impl/SAML2RedirectDecoder.cpp index 9efd6e4..4c8e3b0 100644 --- a/saml/saml2/binding/impl/SAML2RedirectDecoder.cpp +++ b/saml/saml2/binding/impl/SAML2RedirectDecoder.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2001-2006 Internet2 + * 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. @@ -54,8 +54,6 @@ namespace opensaml { SAML2RedirectDecoder::SAML2RedirectDecoder(const DOMElement* e) {} -SAML2RedirectDecoder::~SAML2RedirectDecoder() {} - XMLObject* SAML2RedirectDecoder::decode( string& relayState, const GenericRequest& genericRequest, @@ -114,42 +112,36 @@ XMLObject* SAML2RedirectDecoder::decode( auto_ptr xmlObject(XMLObjectBuilder::buildOneFromElement(doc->getDocumentElement(), true)); janitor.release(); - saml2::RootObject* root = dynamic_cast(xmlObject.get()); - if (!root) - throw BindingException("XML content for SAML 2.0 HTTP-POST Decoder must be a SAML 2.0 protocol message."); + saml2::RootObject* root = NULL; + StatusResponseType* response = NULL; + RequestAbstractType* request = dynamic_cast(xmlObject.get()); + if (!request) { + response = dynamic_cast(xmlObject.get()); + if (!response) + throw BindingException("XML content for SAML 2.0 HTTP-POST Decoder must be a SAML 2.0 protocol message."); + root = static_cast(response); + } + else { + root = static_cast(request); + } - try { - if (!m_validate) - SchemaValidators.validate(xmlObject.get()); - - // Run through the policy. - policy.evaluate(genericRequest, *root); + if (!m_validate) + SchemaValidators.validate(xmlObject.get()); + + // Check destination URL. + auto_ptr_char dest(request ? request->getDestination() : response->getDestination()); + const char* dest2 = httpRequest->getRequestURL(); + if ((root->getSignature() || httpRequest->getParameter("Signature")) && !dest.get() || !*(dest.get())) { + log.error("signed SAML message missing Destination attribute"); + throw BindingException("Signed SAML message missing Destination attribute identifying intended destination."); } - catch (XMLToolingException& ex) { - // This is just to maximize the likelihood of attaching a source to the message for support purposes. - if (policy.getIssuerMetadata()) - annotateException(&ex,policy.getIssuerMetadata()); // throws it - - const Issuer* claimedIssuer = root->getIssuer(); - if (!claimedIssuer || !claimedIssuer->getName()) - throw; - const EntityDescriptor* provider=NULL; - if (!policy.getMetadataProvider() || - !(provider=policy.getMetadataProvider()->getEntityDescriptor(claimedIssuer->getName(), false))) { - // Just record it. - auto_ptr_char iname(claimedIssuer->getName()); - if (iname.get()) - ex.addProperty("entityID", iname.get()); - throw; - } - - if (policy.getRole()) { - const RoleDescriptor* roledesc=provider->getRoleDescriptor(*(policy.getRole()), samlconstants::SAML20P_NS); - if (roledesc) annotateException(&ex,roledesc); // throws it - } - annotateException(&ex,provider); // throws it + else if (dest.get() && (!dest2 || !*dest2 || strcmp(dest.get(),dest2))) { + log.error("Redirect targeted at (%s), but delivered to (%s)", dest.get(), dest2 ? dest2 : "none"); + throw BindingException("SAML message delivered with Redirect to incorrect server URL."); } - xmlObject.release(); - return root; + // Run through the policy. + policy.evaluate(*root, &genericRequest); + + return xmlObject.release(); }