X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=saml%2Fsaml2%2Fprofile%2Fimpl%2FBearerConfirmationRule.cpp;fp=saml%2Fsaml2%2Fprofile%2Fimpl%2FBearerConfirmationRule.cpp;h=b197226f02fff6760957deb78170fbaeead54674;hb=69a716dedfd9e239bcc9206a7b8dc137b43f5f89;hp=0000000000000000000000000000000000000000;hpb=df39928338a40f7a2980406e9737893289673611;p=shibboleth%2Fcpp-opensaml.git diff --git a/saml/saml2/profile/impl/BearerConfirmationRule.cpp b/saml/saml2/profile/impl/BearerConfirmationRule.cpp new file mode 100644 index 0000000..b197226 --- /dev/null +++ b/saml/saml2/profile/impl/BearerConfirmationRule.cpp @@ -0,0 +1,144 @@ +/* + * Copyright 2009 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 + * + * 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. + */ + +/** + * BearerConfirmationRule.cpp + * + * SAML 2.0 Bearer SubjectConfirmation SecurityPolicyRule + */ + +#include "internal.h" +#include "exceptions.h" +#include "binding/SecurityPolicyRule.h" +#include "saml2/core/Assertions.h" +#include "saml2/profile/SAML2AssertionPolicy.h" + +#include +#include + +using namespace opensaml::saml2; +using namespace xmltooling; +using namespace std; + +namespace opensaml { + namespace saml2 { + + class SAML_DLLLOCAL BearerConfirmationRule : public opensaml::SecurityPolicyRule + { + public: + BearerConfirmationRule(const DOMElement* e); + + virtual ~BearerConfirmationRule() { + } + const char* getType() const { + return BEARER_POLICY_RULE; + } + bool evaluate(const XMLObject& message, const GenericRequest* request, opensaml::SecurityPolicy& policy) const; + + private: + bool m_validity, m_recipient, m_correlation, m_fatal; + }; + + opensaml::SecurityPolicyRule* SAML_DLLLOCAL BearerConfirmationRuleFactory(const DOMElement* const & e) + { + return new BearerConfirmationRule(e); + } + + static const XMLCh checkValidity[] = UNICODE_LITERAL_13(c,h,e,c,k,V,a,l,i,d,i,t,y); + static const XMLCh checkRecipient[] = UNICODE_LITERAL_14(c,h,e,c,k,R,e,c,i,p,i,e,n,t); + static const XMLCh checkCorrelation[] = UNICODE_LITERAL_16(c,h,e,c,k,C,o,r,r,e,l,a,t,i,o,n); + static const XMLCh missingFatal[] = UNICODE_LITERAL_12(m,i,s,s,i,n,g,F,a,t,a,l); + }; +}; + +BearerConfirmationRule::BearerConfirmationRule(const DOMElement* e) : m_validity(true), m_recipient(true), m_correlation(true), m_fatal(true) +{ + const XMLCh* flag = e ? e->getAttributeNS(NULL, checkValidity) : NULL; + m_validity = (!flag || (*flag != chLatin_f && *flag != chDigit_0)); + flag = e ? e->getAttributeNS(NULL, checkRecipient) : NULL; + m_recipient = (!flag || (*flag != chLatin_f && *flag != chDigit_0)); + flag = e ? e->getAttributeNS(NULL, checkCorrelation) : NULL; + m_correlation = (!flag || (*flag != chLatin_f && *flag != chDigit_0)); + flag = e ? e->getAttributeNS(NULL, missingFatal) : NULL; + m_fatal = (!flag || (*flag != chLatin_f && *flag != chDigit_0)); +} + +bool BearerConfirmationRule::evaluate(const XMLObject& message, const GenericRequest* request, opensaml::SecurityPolicy& policy) const +{ + const Assertion* a=dynamic_cast(&message); + if (!a) + return false; + + logging::Category& log = logging::Category::getInstance(SAML_LOGCAT".SecurityPolicyRule.BearerConfirmation"); + + const char* msg=NULL; + const Subject* subject = a->getSubject(); + if (subject) { + const vector& confs = subject->getSubjectConfirmations(); + for (vector::const_iterator sc = confs.begin(); sc!=confs.end(); ++sc) { + if (XMLString::equals((*sc)->getMethod(), SubjectConfirmation::BEARER)) { + + const SubjectConfirmationDataType* data = dynamic_cast((*sc)->getSubjectConfirmationData()); + + if (m_recipient) { + const HTTPRequest* httpRequest = dynamic_cast(request); + if (httpRequest && httpRequest->getRequestURL()) { + string dest = httpRequest->getRequestURL(); + auto_ptr_XMLCh destination(dest.substr(0,dest.find('?')).c_str()); + if (!XMLString::equals(destination.get(), data ? data->getRecipient() : NULL)) { + msg = "bearer confirmation failed with recipient mismatch"; + continue; + } + } + } + + if (m_correlation && policy.getCorrelationID()) { + if (!XMLString::equals(policy.getCorrelationID(), data ? data->getInResponseTo() : NULL)) { + msg = "bearer confirmation failed with request correlation mismatch"; + continue; + } + } + + if (m_validity) { + if (!data || !data->getNotOnOrAfter()) { + msg = "bearer SubjectConfirmationData missing NotOnOrAfter attribute"; + continue; + } + else if (data->getNotOnOrAfterEpoch() <= policy.getTime() - XMLToolingConfig::getConfig().clock_skew_secs) { + msg = "bearer confirmation has expired"; + continue; + } + + if (data && data->getNotBefore() && policy.getTime() + XMLToolingConfig::getConfig().clock_skew_secs < data->getNotBeforeEpoch()) { + msg = "bearer confirmation not yet valid"; + continue; + } + } + + SAML2AssertionPolicy* saml2policy = dynamic_cast(&policy); + if (saml2policy) + saml2policy->setSubjectConfirmation(*sc); + log.debug("assertion satisfied bearer confirmation requirements"); + return true; + } + } + } + + log.error(msg); + if (m_fatal) + throw SecurityPolicyException("Unable to locate satisfiable bearer SubjectConfirmation in assertion."); + return false; +}