X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=saml%2Fsaml2%2Fbinding%2Fimpl%2FSAML2MessageRule.cpp;h=1c921f4446195e2f3ba070057933b070190e4fc8;hb=9d61992f725e8b73421e9262a711f4cbdd782b18;hp=fe604c2f082addc5e2bea8b15969a4bd777a11e4;hpb=3e40c0e62375c069e7860a87ca4f65fb2003f018;p=shibboleth%2Fcpp-opensaml.git diff --git a/saml/saml2/binding/impl/SAML2MessageRule.cpp b/saml/saml2/binding/impl/SAML2MessageRule.cpp index fe604c2..1c921f4 100644 --- a/saml/saml2/binding/impl/SAML2MessageRule.cpp +++ b/saml/saml2/binding/impl/SAML2MessageRule.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. @@ -15,100 +15,113 @@ */ /** - * SAML1MessageRule.cpp + * SAML2MessageRule.cpp * - * SAML 1.x message extraction rule + * SAML 2.0 message extraction rule */ #include "internal.h" #include "exceptions.h" -#include "saml2/binding/SAML2MessageRule.h" +#include "binding/SecurityPolicyRule.h" #include "saml2/core/Protocols.h" #include "saml2/metadata/Metadata.h" #include "saml2/metadata/MetadataProvider.h" #include "util/SAMLConstants.h" -#include +#include using namespace opensaml::saml2md; using namespace opensaml::saml2p; using namespace opensaml::saml2; using namespace opensaml; +using namespace xmltooling::logging; using namespace xmltooling; -using namespace log4cpp; using namespace std; namespace opensaml { + class SAML_DLLLOCAL SAML2MessageRule : public SecurityPolicyRule + { + public: + SAML2MessageRule(const DOMElement* e) {} + virtual ~SAML2MessageRule() {} + + const char* getType() const { + return SAML2MESSAGE_POLICY_RULE; + } + void evaluate(const XMLObject& message, const GenericRequest* request, const XMLCh* protocol, SecurityPolicy& policy) const; + }; + SecurityPolicyRule* SAML_DLLLOCAL SAML2MessageRuleFactory(const DOMElement* const & e) { return new SAML2MessageRule(e); } }; -void SAML2MessageRule::evaluate(const XMLObject& message, const GenericRequest* request, SecurityPolicy& policy) const +void SAML2MessageRule::evaluate( + const XMLObject& message, const GenericRequest* request, const XMLCh* protocol, SecurityPolicy& policy + ) const { + // Only handle SAML 2.0 protocol and 2.0 messages. + if (!XMLString::equals(protocol, samlconstants::SAML20P_NS)) + return; + const QName& q = message.getElementQName(); + if (!XMLString::equals(q.getNamespaceURI(), samlconstants::SAML20P_NS)&& + !XMLString::equals(q.getNamespaceURI(), samlconstants::SAML20_NS)) + return; + Category& log=Category::getInstance(SAML_LOGCAT".SecurityPolicyRule.SAML2Message"); - const QName& q = message.getElementQName(); - policy.setMessageQName(&q); - try { - const opensaml::RootObject& samlRoot = dynamic_cast(message); + const saml2::RootObject& samlRoot = dynamic_cast(message); policy.setMessageID(samlRoot.getID()); policy.setIssueInstant(samlRoot.getIssueInstantEpoch()); - if (!XMLString::equals(q.getNamespaceURI(), samlconstants::SAML20P_NS)) { - log.warn("not a SAML 2.0 protocol message"); - throw BindingException("Message was not a recognized SAML 2.0 protocol element."); - } - log.debug("extracting issuer from message"); - const saml2::RootObject& saml2Root = dynamic_cast(samlRoot); - Issuer* issuer = saml2Root.getIssuer(); - if (issuer && issuer->getName()) { - auto_ptr copy(issuer->cloneIssuer()); - policy.setIssuer(copy.get()); - copy.release(); + const Issuer* issuer = samlRoot.getIssuer(); + if (issuer) { + policy.setIssuer(issuer); } - else { + else if (XMLString::equals(q.getLocalPart(), Response::LOCAL_NAME)) { // No issuer in the message, so we have to try the Response approach. - const vector& assertions = dynamic_cast(saml2Root).getAssertions(); + const vector& assertions = dynamic_cast(samlRoot).getAssertions(); if (!assertions.empty()) { issuer = assertions.front()->getIssuer(); - if (issuer && issuer->getName()) { - auto_ptr copy(issuer->cloneIssuer()); - policy.setIssuer(copy.get()); - copy.release(); - } + if (issuer) + policy.setIssuer(issuer); } } - if (!policy.getIssuer()) { + if (!issuer) { log.warn("issuer identity not extracted"); return; } if (log.isDebugEnabled()) { - auto_ptr_char iname(policy.getIssuer()->getName()); + auto_ptr_char iname(issuer->getName()); log.debug("message from (%s)", iname.get()); } + if (policy.getIssuerMetadata()) { + log.debug("metadata for issuer already set, leaving in place"); + return; + } + if (policy.getMetadataProvider() && policy.getRole()) { - if (policy.getIssuer()->getFormat() && !XMLString::equals(policy.getIssuer()->getFormat(), saml2::NameIDType::ENTITY)) { + if (issuer->getFormat() && !XMLString::equals(issuer->getFormat(), NameIDType::ENTITY)) { log.warn("non-system entity issuer, skipping metadata lookup"); return; } log.debug("searching metadata for message issuer..."); - const EntityDescriptor* entity = policy.getMetadataProvider()->getEntityDescriptor(policy.getIssuer()->getName()); + const EntityDescriptor* entity = policy.getMetadataProvider()->getEntityDescriptor(issuer->getName()); if (!entity) { - auto_ptr_char temp(policy.getIssuer()->getName()); + auto_ptr_char temp(issuer->getName()); log.warn("no metadata found, can't establish identity of issuer (%s)", temp.get()); return; } log.debug("matched message issuer against metadata, searching for applicable role..."); - const RoleDescriptor* roledesc=entity->getRoleDescriptor(*policy.getRole(), samlconstants::SAML20P_NS); + const RoleDescriptor* roledesc=entity->getRoleDescriptor(*policy.getRole(), protocol); if (!roledesc) { log.warn("unable to find compatible role (%s) in metadata", policy.getRole()->toString().c_str()); return;