Expose audience collection on security policy.
[shibboleth/cpp-opensaml.git] / saml / saml2 / profile / Assertion20Validator.cpp
index 3109ec7..463c45c 100644 (file)
@@ -47,8 +47,11 @@ void AssertionValidator::validateAssertion(const Assertion& assertion) const
 #endif
 
     const Conditions* conds = assertion.getConditions();
+    if (!conds)
+        return;
+    
     // First verify the time conditions, using the specified timestamp, if non-zero.
-    if (m_ts>0 && conds) {
+    if (m_ts>0) {
         unsigned int skew = XMLToolingConfig::getConfig().clock_skew_secs;
         time_t t=conds->getNotBeforeEpoch();
         if (m_ts+skew < t)
@@ -58,28 +61,39 @@ void AssertionValidator::validateAssertion(const Assertion& assertion) const
             throw ValidationException("Assertion is no longer valid.");
     }
 
-    // Now we process conditions. Only audience restrictions at the moment.
+    // Now we process conditions, starting with the known types and then extensions.
+    const vector<AudienceRestriction*>& acvec = conds->getAudienceRestrictions();
+    for (vector<AudienceRestriction*>::const_iterator ac = acvec.begin(); ac!=acvec.end(); ++ac)
+        validateCondition(*ac);
+
+    const vector<OneTimeUse*>& dncvec = conds->getOneTimeUses();
+    for (vector<OneTimeUse*>::const_iterator dnc = dncvec.begin(); dnc!=dncvec.end(); ++dnc)
+        validateCondition(*dnc);
+
     const vector<Condition*>& convec = conds->getConditions();
-    for (vector<Condition*>::const_iterator c = convec.begin(); c!=convec.end(); ++c) {
-        if (!validateCondition(*c)) {
-            Category::getInstance(SAML_LOGCAT".AssertionValidator").error("unrecognized Condition in assertion (%s)",
-                (*c)->getSchemaType() ? (*c)->getSchemaType()->toString().c_str() : (*c)->getElementQName().toString().c_str());
-            throw ValidationException("Assertion contains an unrecognized condition.");
-        }
-    }
+    for (vector<Condition*>::const_iterator c = convec.begin(); c!=convec.end(); ++c)
+        validateCondition(*c);
 }
 
-bool AssertionValidator::validateCondition(const Condition* condition) const
+void AssertionValidator::validateCondition(const Condition* c) const
 {
-    const AudienceRestriction* ac=dynamic_cast<const AudienceRestriction*>(condition);
-    if (!ac)
-        return false;
+    const AudienceRestriction* ac=dynamic_cast<const AudienceRestriction*>(c);
+    if (!ac) {
+        Category::getInstance(SAML_LOGCAT".AssertionValidator").error("unrecognized Condition in assertion (%s)",
+            c->getSchemaType() ? c->getSchemaType()->toString().c_str() : c->getElementQName().toString().c_str());
+        throw ValidationException("Assertion contains an unrecognized condition.");
+    }
 
     bool found = false;
     const vector<Audience*>& auds1 = ac->getAudiences();
     for (vector<Audience*>::const_iterator a = auds1.begin(); !found && a!=auds1.end(); ++a) {
-        for (vector<const XMLCh*>::const_iterator a2 = m_audiences.begin(); !found && a2!=m_audiences.end(); ++a2) {
-            found = XMLString::equals((*a)->getAudienceURI(), *a2);
+        if (XMLString::equals(m_recipient, (*a)->getAudienceURI())) {
+            found = true;
+        }
+        else if (m_audiences) {
+            for (vector<const XMLCh*>::const_iterator a2 = m_audiences->begin(); !found && a2!=m_audiences->end(); ++a2) {
+                found = XMLString::equals((*a)->getAudienceURI(), *a2);
+            }
         }
     }
 
@@ -89,6 +103,4 @@ bool AssertionValidator::validateCondition(const Condition* condition) const
         Category::getInstance(SAML_LOGCAT".AssertionValidator").error("unacceptable AudienceRestriction in assertion (%s)", os.str().c_str());
         throw ValidationException("Assertion contains an unacceptable AudienceRestriction.");
     }
-
-    return found;
 }