X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=saml%2Fbinding%2Fimpl%2FSecurityPolicy.cpp;h=371410e92b7632f1921a8d716fc6a07828b62772;hb=0542de711d105e1cdfd2d9273764e01ccf2fa92a;hp=89aad2d71f0366893020cef9ce62e42080524728;hpb=b951e528ad7d0764ddc4ced037a8bd53bd3c9890;p=shibboleth%2Fcpp-opensaml.git diff --git a/saml/binding/impl/SecurityPolicy.cpp b/saml/binding/impl/SecurityPolicy.cpp index 89aad2d..371410e 100644 --- a/saml/binding/impl/SecurityPolicy.cpp +++ b/saml/binding/impl/SecurityPolicy.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. @@ -22,11 +22,8 @@ #include "internal.h" #include "exceptions.h" -#include "binding/SecurityPolicy.h" -#include "saml1/core/Assertions.h" -#include "saml1/core/Protocols.h" +#include "binding/SecurityPolicyRule.h" #include "saml2/core/Assertions.h" -#include "saml2/core/Protocols.h" using namespace opensaml::saml2md; using namespace opensaml::saml2; @@ -35,10 +32,11 @@ using namespace xmltooling; using namespace std; namespace opensaml { - SAML_DLLLOCAL PluginManager::Factory ClientCertAuthRuleFactory; - SAML_DLLLOCAL PluginManager::Factory MessageFlowRuleFactory; - SAML_DLLLOCAL PluginManager::Factory SimpleSigningRuleFactory; - SAML_DLLLOCAL PluginManager::Factory XMLSigningRuleFactory; + SAML_DLLLOCAL PluginManager::Factory ClientCertAuthRuleFactory; + SAML_DLLLOCAL PluginManager::Factory MessageFlowRuleFactory; + SAML_DLLLOCAL PluginManager::Factory NullSecurityRuleFactory; + SAML_DLLLOCAL PluginManager::Factory SimpleSigningRuleFactory; + SAML_DLLLOCAL PluginManager::Factory XMLSigningRuleFactory; }; void SAML_API opensaml::registerSecurityPolicyRules() @@ -46,63 +44,66 @@ void SAML_API opensaml::registerSecurityPolicyRules() SAMLConfig& conf=SAMLConfig::getConfig(); conf.SecurityPolicyRuleManager.registerFactory(CLIENTCERTAUTH_POLICY_RULE, ClientCertAuthRuleFactory); conf.SecurityPolicyRuleManager.registerFactory(MESSAGEFLOW_POLICY_RULE, MessageFlowRuleFactory); + conf.SecurityPolicyRuleManager.registerFactory(NULLSECURITY_POLICY_RULE, NullSecurityRuleFactory); conf.SecurityPolicyRuleManager.registerFactory(SIMPLESIGNING_POLICY_RULE, SimpleSigningRuleFactory); conf.SecurityPolicyRuleManager.registerFactory(XMLSIGNING_POLICY_RULE, XMLSigningRuleFactory); } SecurityPolicy::IssuerMatchingPolicy SecurityPolicy::m_defaultMatching; -SecurityPolicyRule::MessageExtractor SecurityPolicy::m_defaultExtractor; - SecurityPolicy::~SecurityPolicy() { - delete m_extractor; - delete m_matchingPolicy; - delete m_issuer; + reset(false); } -void SecurityPolicy::evaluate(const GenericRequest& request, const XMLObject& message) +void SecurityPolicy::reset(bool messageOnly) { - for (vector::const_iterator i=m_rules.begin(); i!=m_rules.end(); ++i) { - - // Run the rule... - pair ident = - (*i)->evaluate(request,message,m_metadata,&m_role,m_trust,getMessageExtractor()); - - // Make sure returned issuer doesn't conflict. - - if (ident.first) { - if (!getIssuerMatchingPolicy().issuerMatches(ident.first, m_issuer)) { - delete ident.first; - throw BindingException("Policy rules returned differing Issuers."); - } - delete m_issuer; - m_issuer=ident.first; - } - - if (ident.second) { - if (m_issuerRole && ident.second!=m_issuerRole) - throw BindingException("Policy rules returned differing issuer RoleDescriptors."); - m_issuerRole=ident.second; - } + XMLString::release(&m_messageID); + m_messageID=NULL; + m_issueInstant=0; + if (!messageOnly) { + delete m_issuer; + m_issuer=NULL; + m_issuerRole=NULL; + m_authenticated=false; } } -void SecurityPolicy::setIssuer(saml2::Issuer* issuer) +void SecurityPolicy::evaluate(const XMLObject& message, const GenericRequest* request) +{ + for (vector::const_iterator i=m_rules.begin(); i!=m_rules.end(); ++i) + (*i)->evaluate(message,request,*this); +} + +void SecurityPolicy::setIssuer(const Issuer* issuer) { - if (!getIssuerMatchingPolicy().issuerMatches(issuer, m_issuer)) { - delete issuer; - throw BindingException("Externally provided Issuer conflicts with policy results."); + if (!getIssuerMatchingPolicy().issuerMatches(m_issuer, issuer)) + throw SecurityPolicyException("An Issuer was supplied that conflicts with previous results."); + + if (!m_issuer) { + if (m_entityOnly && issuer->getFormat() && !XMLString::equals(issuer->getFormat(), NameIDType::ENTITY)) + throw SecurityPolicyException("A non-entity Issuer was supplied, violating policy."); + m_issuerRole = NULL; + m_issuer=issuer->cloneIssuer(); } +} + +void SecurityPolicy::setIssuer(const XMLCh* issuer) +{ + if (!getIssuerMatchingPolicy().issuerMatches(m_issuer, issuer)) + throw SecurityPolicyException("An Issuer was supplied that conflicts with previous results."); - delete m_issuer; - m_issuer=issuer; + if (!m_issuer && issuer && *issuer) { + m_issuerRole = NULL; + m_issuer = IssuerBuilder::buildIssuer(); + m_issuer->setName(issuer); + } } void SecurityPolicy::setIssuerMetadata(const RoleDescriptor* issuerRole) { if (issuerRole && m_issuerRole && issuerRole!=m_issuerRole) - throw BindingException("Externally provided RoleDescriptor conflicts with policy results."); + throw SecurityPolicyException("A rule supplied a RoleDescriptor that conflicts with previous results."); m_issuerRole=issuerRole; } @@ -135,61 +136,27 @@ bool SecurityPolicy::IssuerMatchingPolicy::issuerMatches(const Issuer* issuer1, return true; } - -pair SecurityPolicyRule::MessageExtractor::getIssuerAndProtocol(const XMLObject& message) const +bool SecurityPolicy::IssuerMatchingPolicy::issuerMatches(const Issuer* issuer1, const XMLCh* issuer2) const { - // We just let any bad casts throw here. + // NULL matches anything for the purposes of this interface. + if (!issuer1 || !issuer2 || !*issuer2) + return true; - saml2::Issuer* issuer; - - // 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)) { - // 2.0 namespace should be castable to a specialized 2.0 root. - const saml2::RootObject& root = dynamic_cast(message); - issuer = root.getIssuer(); - 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(); - if (!assertions.empty()) { - issuer = assertions.front()->getIssuer(); - if (issuer && issuer->getName()) - return make_pair(issuer->cloneIssuer(), samlconstants::SAML20P_NS); - } - } - else if (XMLString::equals(ns, samlconstants::SAML1P_NS)) { - // Should be a samlp:Response, at least in OpenSAML. - const vector& assertions = dynamic_cast(message).getAssertions(); - if (!assertions.empty()) { - const saml1::Assertion* a = assertions.front(); - if (a->getIssuer()) { - issuer = saml2::IssuerBuilder::buildIssuer(); - issuer->setName(a->getIssuer()); - pair minor = a->getMinorVersion(); - return make_pair( - issuer, - (minor.first && minor.second==0) ? samlconstants::SAML10_PROTOCOL_ENUM : samlconstants::SAML11_PROTOCOL_ENUM - ); - } - } - } - else if (XMLString::equals(ns, samlconstants::SAML1_NS)) { - // Should be a saml:Assertion. - const saml1::Assertion& a = dynamic_cast(message); - if (a.getIssuer()) { - issuer = saml2::IssuerBuilder::buildIssuer(); - issuer->setName(a.getIssuer()); - pair minor = a.getMinorVersion(); - return make_pair( - issuer, - (minor.first && minor.second==0) ? samlconstants::SAML10_PROTOCOL_ENUM : samlconstants::SAML11_PROTOCOL_ENUM - ); - } - } - } - return pair(NULL,NULL); + const XMLCh* op1=issuer1->getName(); + if (!op1 || !XMLString::equals(op1,issuer2)) + return false; + + op1=issuer1->getFormat(); + if (op1 && *op1 && !XMLString::equals(op1, NameIDType::ENTITY)) + return false; + + op1=issuer1->getNameQualifier(); + if (op1 && *op1) + return false; + + op1=issuer1->getSPNameQualifier(); + if (op1 && *op1) + return false; + + return true; }