First set of logout base classes and non-building draft of SP-initiated logout.
[shibboleth/sp.git] / shibsp / handler / impl / SAML2Consumer.cpp
index cca120e..414005c 100644 (file)
@@ -41,6 +41,9 @@ using namespace opensaml::saml2;
 using namespace opensaml::saml2p;
 using namespace opensaml::saml2md;
 using namespace opensaml;
+# ifndef min
+#  define min(a,b)            (((a) < (b)) ? (a) : (b))
+# endif
 #endif
 
 using namespace shibsp;
@@ -59,7 +62,7 @@ namespace shibsp {
     {
     public:
         SAML2Consumer(const DOMElement* e, const char* appId)
-            : AssertionConsumerService(e, appId, Category::getInstance(SHIBSP_LOGCAT".SAML2")) {
+            : AssertionConsumerService(e, appId, Category::getInstance(SHIBSP_LOGCAT".SAML2SSO")) {
         }
         virtual ~SAML2Consumer() {}
         
@@ -325,22 +328,13 @@ string SAML2Consumer::implementProtocol(
     // Session expiration for SAML 2.0 is jointly IdP- and SP-driven.
     time_t sessionExp = ssoStatement->getSessionNotOnOrAfter() ? ssoStatement->getSessionNotOnOrAfterEpoch() : 0;
     const PropertySet* sessionProps = application.getPropertySet("Sessions");
-    pair<bool,unsigned int> lifetime = sessionProps ? sessionProps->getUnsignedInt("lifetime") : make_pair(true,28800);
-    if (!lifetime.first)
+    pair<bool,unsigned int> lifetime = sessionProps ? sessionProps->getUnsignedInt("lifetime") : pair<bool,unsigned int>(true,28800);
+    if (!lifetime.first || lifetime.second == 0)
         lifetime.second = 28800;
-    if (lifetime.second != 0) {
-        if (sessionExp == 0)
-            sessionExp = now + lifetime.second;     // IdP says nothing, calulate based on SP.
-        else
-            sessionExp = min(sessionExp, now + lifetime.second);    // Use the lowest.
-    }
-
-    // Other details...
-    const AuthnContext* authnContext = ssoStatement->getAuthnContext();
-    auto_ptr_char authnClass((authnContext && authnContext->getAuthnContextClassRef()) ? authnContext->getAuthnContextClassRef()->getReference() : NULL);
-    auto_ptr_char authnDecl((authnContext && authnContext->getAuthnContextDeclRef()) ? authnContext->getAuthnContextDeclRef()->getReference() : NULL);
-    auto_ptr_char index(ssoStatement->getSessionIndex());
-    auto_ptr_char authnInstant(ssoStatement->getAuthnInstant() ? ssoStatement->getAuthnInstant()->getRawData() : NULL);
+    if (sessionExp == 0)
+        sessionExp = now + lifetime.second;     // IdP says nothing, calulate based on SP.
+    else
+        sessionExp = min(sessionExp, now + lifetime.second);    // Use the lowest.
 
     multimap<string,Attribute*> resolvedAttributes;
     AttributeExtractor* extractor = application.getAttributeExtractor();
@@ -363,9 +357,17 @@ string SAML2Consumer::implementProtocol(
         }
     }
 
+    const AuthnContext* authnContext = ssoStatement->getAuthnContext();
+
     AttributeFilter* filter = application.getAttributeFilter();
     if (filter && !resolvedAttributes.empty()) {
-        BasicFilteringContext fc(application, resolvedAttributes, policy.getIssuerMetadata(), authnClass.get(), authnDecl.get());
+        BasicFilteringContext fc(
+            application,
+            resolvedAttributes,
+            policy.getIssuerMetadata(),
+            (authnContext && authnContext->getAuthnContextClassRef()) ? authnContext->getAuthnContextClassRef()->getReference() : NULL,
+            (authnContext && authnContext->getAuthnContextDeclRef()) ? authnContext->getAuthnContextDeclRef()->getReference() : NULL
+            );
         Locker filtlocker(filter);
         try {
             filter->filterAttributes(fc, resolvedAttributes);
@@ -382,7 +384,16 @@ string SAML2Consumer::implementProtocol(
         const EntityDescriptor* issuerMetadata =
             policy.getIssuerMetadata() ? dynamic_cast<const EntityDescriptor*>(policy.getIssuerMetadata()->getParent()) : NULL;
         auto_ptr<ResolutionContext> ctx(
-            resolveAttributes(application, issuerMetadata, ssoName, authnClass.get(), authnDecl.get(), &tokens, &resolvedAttributes)
+            resolveAttributes(
+                application,
+                issuerMetadata,
+                samlconstants::SAML20P_NS,
+                ssoName,
+                (authnContext && authnContext->getAuthnContextClassRef()) ? authnContext->getAuthnContextClassRef()->getReference() : NULL,
+                (authnContext && authnContext->getAuthnContextDeclRef()) ? authnContext->getAuthnContextDeclRef()->getReference() : NULL,
+                &tokens,
+                &resolvedAttributes
+                )
             );
 
         if (ctx.get()) {
@@ -402,11 +413,12 @@ string SAML2Consumer::implementProtocol(
             application,
             httpRequest.getRemoteAddr().c_str(),
             issuerMetadata,
+            samlconstants::SAML20P_NS,
             ssoName,
-            authnInstant.get(),
-            index.get(),
-            authnClass.get(),
-            authnDecl.get(),
+            ssoStatement->getAuthnInstant() ? ssoStatement->getAuthnInstant()->getRawData() : NULL,
+            ssoStatement->getSessionIndex(),
+            (authnContext && authnContext->getAuthnContextClassRef()) ? authnContext->getAuthnContextClassRef()->getReference() : NULL,
+            (authnContext && authnContext->getAuthnContextDeclRef()) ? authnContext->getAuthnContextDeclRef()->getReference() : NULL,
             &tokens,
             &resolvedAttributes
             );
@@ -415,7 +427,7 @@ string SAML2Consumer::implementProtocol(
         if (ownedName)
             delete ssoName;
         for_each(ownedtokens.begin(), ownedtokens.end(), xmltooling::cleanup<saml2::Assertion>());
-
+        for_each(resolvedAttributes.begin(), resolvedAttributes.end(), cleanup_pair<string,Attribute>());
         return key;
     }
     catch (exception&) {