Move token validation into SAML library, first draft SAML 1 SSO handler.
[shibboleth/cpp-sp.git] / shibsp / impl / XMLServiceProvider.cpp
index b419c2e..b7d6f39 100644 (file)
@@ -66,18 +66,6 @@ namespace {
     #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
@@ -122,9 +110,6 @@ namespace {
         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
@@ -358,122 +343,6 @@ namespace shibsp {
     }\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