#pragma warning( disable : 4250 )\r
#endif\r
\r
- class SHIBSP_DLLLOCAL TokenValidator : public Validator\r
- {\r
- public:\r
- TokenValidator(const Application& app, time_t ts=0, const RoleDescriptor* role=NULL) : m_app(app), m_ts(ts), m_role(role) {}\r
- void validate(const XMLObject*) const;\r
-\r
- private:\r
- const Application& m_app;\r
- time_t m_ts;\r
- const RoleDescriptor* m_role;\r
- };\r
-\r
static vector<const Handler*> g_noHandlers;\r
\r
// Application configuration wrapper\r
const vector<const XMLCh*>& getAudiences() const {\r
return (m_audiences.empty() && m_base) ? m_base->getAudiences() : m_audiences;\r
}\r
- Validator* getTokenValidator(time_t ts=0, const saml2md::RoleDescriptor* role=NULL) const {\r
- return new TokenValidator(*this, ts, role);\r
- }\r
\r
// Provides filter to exclude special config elements.\r
short acceptNode(const DOMNode* node) const;\r
}\r
};\r
\r
-void TokenValidator::validate(const XMLObject* xmlObject) const\r
-{\r
-#ifdef _DEBUG\r
- xmltooling::NDC ndc("validate");\r
-#endif\r
- Category& log=Category::getInstance(SHIBSP_LOGCAT".Application");\r
-\r
- const opensaml::Assertion* root = NULL;\r
- const saml2::Assertion* token2 = dynamic_cast<const saml2::Assertion*>(xmlObject);\r
- if (token2) {\r
- const saml2::Conditions* conds = token2->getConditions();\r
- // First verify the time conditions, using the specified timestamp, if non-zero.\r
- if (m_ts>0 && conds) {\r
- unsigned int skew = XMLToolingConfig::getConfig().clock_skew_secs;\r
- time_t t=conds->getNotBeforeEpoch();\r
- if (m_ts+skew < t)\r
- throw ValidationException("Assertion is not yet valid.");\r
- t=conds->getNotOnOrAfterEpoch();\r
- if (t <= m_ts-skew)\r
- throw ValidationException("Assertion is no longer valid.");\r
- }\r
-\r
- // Now we process conditions. Only audience restrictions at the moment.\r
- const vector<saml2::Condition*>& convec = conds->getConditions();\r
- for (vector<saml2::Condition*>::const_iterator c = convec.begin(); c!=convec.end(); ++c) {\r
- const saml2::AudienceRestriction* ac=dynamic_cast<const saml2::AudienceRestriction*>(*c);\r
- if (!ac) {\r
- log.error("unrecognized Condition in assertion (%s)",\r
- (*c)->getSchemaType() ? (*c)->getSchemaType()->toString().c_str() : (*c)->getElementQName().toString().c_str());\r
- throw ValidationException("Assertion contains an unrecognized condition.");\r
- }\r
-\r
- bool found = false;\r
- const vector<saml2::Audience*>& auds1 = ac->getAudiences();\r
- const vector<const XMLCh*>& auds2 = m_app.getAudiences();\r
- for (vector<saml2::Audience*>::const_iterator a = auds1.begin(); !found && a!=auds1.end(); ++a) {\r
- for (vector<const XMLCh*>::const_iterator a2 = auds2.begin(); !found && a2!=auds2.end(); ++a2) {\r
- found = XMLString::equals((*a)->getAudienceURI(), *a2);\r
- }\r
- }\r
-\r
- if (!found) {\r
- ostringstream os;\r
- os << *ac;\r
- log.error("unacceptable AudienceRestriction in assertion (%s)", os.str().c_str());\r
- throw ValidationException("Assertion contains an unacceptable AudienceRestriction.");\r
- }\r
- }\r
-\r
- root = token2;\r
- }\r
- else {\r
- const saml1::Assertion* token1 = dynamic_cast<const saml1::Assertion*>(xmlObject);\r
- if (token1) {\r
- const saml1::Conditions* conds = token1->getConditions();\r
- // First verify the time conditions, using the specified timestamp, if non-zero.\r
- if (m_ts>0 && conds) {\r
- unsigned int skew = XMLToolingConfig::getConfig().clock_skew_secs;\r
- time_t t=conds->getNotBeforeEpoch();\r
- if (m_ts+skew < t)\r
- throw ValidationException("Assertion is not yet valid.");\r
- t=conds->getNotOnOrAfterEpoch();\r
- if (t <= m_ts-skew)\r
- throw ValidationException("Assertion is no longer valid.");\r
- }\r
-\r
- // Now we process conditions. Only audience restrictions at the moment.\r
- const vector<saml1::Condition*>& convec = conds->getConditions();\r
- for (vector<saml1::Condition*>::const_iterator c = convec.begin(); c!=convec.end(); ++c) {\r
- const saml1::AudienceRestrictionCondition* ac=dynamic_cast<const saml1::AudienceRestrictionCondition*>(*c);\r
- if (!ac) {\r
- log.error("unrecognized Condition in assertion (%s)",\r
- (*c)->getSchemaType() ? (*c)->getSchemaType()->toString().c_str() : (*c)->getElementQName().toString().c_str());\r
- throw ValidationException("Assertion contains an unrecognized condition.");\r
- }\r
-\r
- bool found = false;\r
- const vector<saml1::Audience*>& auds1 = ac->getAudiences();\r
- const vector<const XMLCh*>& auds2 = m_app.getAudiences();\r
- for (vector<saml1::Audience*>::const_iterator a = auds1.begin(); !found && a!=auds1.end(); ++a) {\r
- for (vector<const XMLCh*>::const_iterator a2 = auds2.begin(); !found && a2!=auds2.end(); ++a2) {\r
- found = XMLString::equals((*a)->getAudienceURI(), *a2);\r
- }\r
- }\r
-\r
- if (!found) {\r
- ostringstream os;\r
- os << *ac;\r
- log.error("unacceptable AudienceRestrictionCondition in assertion (%s)", os.str().c_str());\r
- throw ValidationException("Assertion contains an unacceptable AudienceRestrictionCondition.");\r
- }\r
- }\r
-\r
- root = token1;\r
- }\r
- else {\r
- throw ValidationException("Unknown object type passed to token validator.");\r
- }\r
- }\r
-\r
- if (!m_role || !m_app.getTrustEngine()) {\r
- log.warn("no issuer role or TrustEngine provided, so no signature validation performed");\r
- return;\r
- }\r
-\r
- const PropertySet* policy=m_app.getServiceProvider().getPolicySettings(m_app.getString("policyId").second);\r
- pair<bool,bool> signedAssertions=policy ? policy->getBool("signedAssertions") : make_pair(false,false);\r
-\r
- if (root->getSignature()) {\r
- if (!m_app.getTrustEngine()->validate(*(root->getSignature()),*m_role))\r
- throw ValidationException("Assertion signature did not validate.");\r
- }\r
- else if (signedAssertions.first && signedAssertions.second)\r
- throw ValidationException("Assertion was unsigned, violating policy.");\r
-}\r
-\r
XMLApplication::XMLApplication(\r
const ServiceProvider* sp,\r
const DOMElement* e,\r