First set of logout base classes and non-building draft of SP-initiated logout.
[shibboleth/sp.git] / shibsp / handler / impl / SAML2Consumer.cpp
index 5d544ec..414005c 100644 (file)
  */
 
 #include "internal.h"
-#include "Application.h"
-#include "exceptions.h"
-#include "ServiceProvider.h"
-#include "SessionCache.h"
-#include "attribute/Attribute.h"
-#include "attribute/filtering/AttributeFilter.h"
-#include "attribute/filtering/BasicFilteringContext.h"
-#include "attribute/resolver/AttributeExtractor.h"
-#include "attribute/resolver/ResolutionContext.h"
 #include "handler/AssertionConsumerService.h"
 
-#include <saml/saml2/core/Protocols.h>
-#include <saml/saml2/profile/BrowserSSOProfileValidator.h>
-#include <saml/saml2/metadata/Metadata.h>
-#include <saml/saml2/metadata/MetadataCredentialCriteria.h>
-
-using namespace shibsp;
+#ifndef SHIBSP_LITE
+# include "exceptions.h"
+# include "Application.h"
+# include "ServiceProvider.h"
+# include "SessionCache.h"
+# include "attribute/Attribute.h"
+# include "attribute/filtering/AttributeFilter.h"
+# include "attribute/filtering/BasicFilteringContext.h"
+# include "attribute/resolver/AttributeExtractor.h"
+# include "attribute/resolver/ResolutionContext.h"
+# include <saml/saml2/core/Protocols.h>
+# include <saml/saml2/profile/BrowserSSOProfileValidator.h>
+# include <saml/saml2/metadata/Metadata.h>
+# include <saml/saml2/metadata/MetadataCredentialCriteria.h>
 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;
 using namespace xmltooling;
 using namespace log4cpp;
 using namespace std;
@@ -57,11 +62,12 @@ 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() {}
         
     private:
+#ifndef SHIBSP_LITE
         string implementProtocol(
             const Application& application,
             const HTTPRequest& httpRequest,
@@ -69,6 +75,7 @@ namespace shibsp {
             const PropertySet* settings,
             const XMLObject& xmlObject
             ) const;
+#endif
     };
 
 #if defined (_MSC_VER)
@@ -82,6 +89,8 @@ namespace shibsp {
     
 };
 
+#ifndef SHIBSP_LITE
+
 string SAML2Consumer::implementProtocol(
     const Application& application,
     const HTTPRequest& httpRequest,
@@ -319,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();
@@ -357,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);
@@ -376,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()) {
@@ -396,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
             );
@@ -409,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&) {
@@ -420,3 +438,5 @@ string SAML2Consumer::implementProtocol(
         throw;
     }
 }
+
+#endif