Add cache method to find but not remove sessions by name.
authorcantor <cantor@cb58f699-b61c-0410-a6fe-9272a202ed29>
Tue, 3 Jul 2007 20:49:49 +0000 (20:49 +0000)
committercantor <cantor@cb58f699-b61c-0410-a6fe-9272a202ed29>
Tue, 3 Jul 2007 20:49:49 +0000 (20:49 +0000)
Switch sign/encrypt flags to 4-way setting to distinguish front and back channel.

git-svn-id: https://svn.middleware.georgetown.edu/cpp-sp/trunk@2335 cb58f699-b61c-0410-a6fe-9272a202ed29

schemas/shibboleth-2.0-native-sp-config.xsd
shibsp/SessionCache.h
shibsp/binding/impl/SOAPClient.cpp
shibsp/handler/impl/AssertionConsumerService.cpp
shibsp/handler/impl/SAML2ArtifactResolution.cpp
shibsp/handler/impl/SAML2SessionInitiator.cpp
shibsp/impl/StorageServiceSessionCache.cpp

index cde7881..1b88c53 100644 (file)
        <simpleType name="listOfURIs">\r
                <list itemType="anyURI"/>\r
        </simpleType>\r
+\r
+       <simpleType name="bindingBoolean">\r
+               <restriction base="string">\r
+                       <enumeration value="true"/>\r
+                       <enumeration value="false"/>\r
+                       <enumeration value="front"/>\r
+                       <enumeration value="back"/>\r
+               </restriction>\r
+       </simpleType>\r
        \r
        <complexType name="PluggableType">\r
                <sequence>\r
                <attribute name="authType" type="conf:string"/>\r
                <attribute name="authUsername" type="conf:string"/>\r
                <attribute name="authPassword" type="conf:string"/>\r
-               <attribute name="signRequests" type="boolean"/>\r
-               <attribute name="signResponses" type="boolean"/>\r
+               <attribute name="signRequests" type="bindingBoolean"/>\r
+               <attribute name="signResponses" type="bindingBoolean"/>\r
                <attribute name="signatureAlg" type="anyURI"/>\r
                <attribute name="digestAlg" type="anyURI"/>\r
-               <attribute name="encryptRequests" type="boolean"/>\r
-               <attribute name="encryptResponses" type="boolean"/>\r
+               <attribute name="encryptRequests" type="bindingBoolean"/>\r
+               <attribute name="encryptResponses" type="bindingBoolean"/>\r
                <attribute name="encryptionAlg" type="anyURI"/>\r
                <attribute name="keyName" type="conf:string"/>\r
                <attribute name="artifactEndpointIndex" type="unsignedShort"/>\r
index fb621e6..954f5ea 100644 (file)
@@ -213,6 +213,23 @@ namespace shibsp {
             )=0;
 
         /**
+         * Locates an existing session or sessions by subject identifier.
+         * 
+         * @param issuer        source of session(s)
+         * @param nameid        name identifier associated with the session(s) to locate
+         * @param index         index of session, or NULL for all sessions associated with other parameters
+         * @param application   reference to Application that owns the session(s)
+         * @param sessions      on exit, contains the IDs of the matching sessions
+         */
+        virtual void find(
+            const opensaml::saml2md::EntityDescriptor& issuer,
+            const opensaml::saml2::NameID& nameid,
+            const char* index,
+            const Application& application,
+            std::vector<std::string>& sessions
+            )=0;
+
+        /**
          * Deletes an existing session or sessions.
          * 
          * @param issuer        source of session(s)
index 0cb3a4e..8dc0574 100644 (file)
@@ -52,8 +52,8 @@ void SOAPClient::send(const soap11::Envelope& env, MetadataCredentialCriteria& p
 {
     // Check for message signing requirements.   
     m_relyingParty = m_app.getRelyingParty(dynamic_cast<const EntityDescriptor*>(peer.getRole().getParent()));
-    pair<bool,bool> flag = m_relyingParty->getBool("signRequests");
-    if (flag.first && flag.second) {
+    pair<bool,const char*> flag = m_relyingParty->getString("signRequests");
+    if (flag.first && (!strcmp(flag.second, "true") || !strcmp(flag.second, "back"))) {
         m_credResolver=m_app.getCredentialResolver();
         if (m_credResolver) {
             m_credResolver->lock();
index 285b0a6..434d1f0 100644 (file)
@@ -55,7 +55,6 @@ AssertionConsumerService::AssertionConsumerService(const DOMElement* e, const ch
 {
     string address(appId);
     address += getString("Location").second;
-    address += "::run::ACS";
     setAddress(address.c_str());
 #ifndef SHIBSP_LITE
     if (SPConfig::getConfig().isEnabled(SPConfig::OutOfProcess)) {
index 12d6004..ba801f4 100644 (file)
@@ -298,8 +298,8 @@ pair<bool,long> SAML2ArtifactResolution::processMessage(const Application& appli
         const EntityDescriptor* entity =
             policy.getIssuerMetadata() ? dynamic_cast<EntityDescriptor*>(policy.getIssuerMetadata()->getParent()) : NULL;
         const PropertySet* relyingParty = application.getRelyingParty(entity);
-        pair<bool,bool> flag = relyingParty->getBool("signResponses");
-        if (flag.first && flag.second && policy.getIssuerMetadata()) {
+        pair<bool,const char*> flag = relyingParty->getBool("signResponses");
+        if (policy.getIssuerMetadata() && flag.first && (!strcmp(flag.second, "true") || !strcmp(flag.second, "back"))) {
             CredentialResolver* credResolver=application.getCredentialResolver();
             if (credResolver) {
                 Locker credLocker(credResolver);
index afb5e70..8b297ca 100644 (file)
@@ -123,13 +123,13 @@ SAML2SessionInitiator::SAML2SessionInitiator(const DOMElement* e, const char* ap
         pair<bool,const XMLCh*> outgoing = getXMLString("outgoingBindings");
         if (outgoing.first) {
             m_outgoing = XMLString::replicate(outgoing.second);
+            XMLString::trim(m_outgoing);
         }
         else {
             // No override, so we'll install a default binding precedence.
             string prec = string(samlconstants::SAML20_BINDING_HTTP_REDIRECT) + ' ' + samlconstants::SAML20_BINDING_HTTP_POST + ' ' +
                 samlconstants::SAML20_BINDING_HTTP_POST_SIMPLESIGN + ' ' + samlconstants::SAML20_BINDING_HTTP_ARTIFACT;
             m_outgoing = XMLString::transcode(prec.c_str());
-            XMLString::trim(m_outgoing);
         }
 
         int pos;
@@ -487,8 +487,8 @@ pair<bool,long> SAML2SessionInitiator::doRequest(
 
     // Check for signing.
     const PropertySet* relyingParty = app.getRelyingParty(entity);
-    pair<bool,bool> flag = relyingParty->getBool("signRequests");
-    if ((flag.first && flag.second) || role->WantAuthnRequestsSigned()) {
+    pair<bool,const char*> flag = relyingParty->getString("signRequests");
+    if (role->WantAuthnRequestsSigned() || (flag.first && (!strcmp(flag.second, "true") || !strcmp(flag.second, "front")))) {
         CredentialResolver* credResolver=app.getCredentialResolver();
         if (credResolver) {
             Locker credLocker(credResolver);
index 2072493..2d2f0a8 100644 (file)
@@ -160,13 +160,24 @@ namespace shibsp {
             );\r
         Session* find(const char* key, const Application& application, const char* client_addr=NULL, time_t* timeout=NULL);\r
         void remove(const char* key, const Application& application);\r
+        void find(\r
+            const saml2md::EntityDescriptor& issuer,\r
+            const saml2::NameID& nameid,\r
+            const char* index,\r
+            const Application& application,\r
+            vector<string>& sessions\r
+            ) {\r
+            byname(issuer, nameid, index, application, sessions, false);\r
+        }\r
         void remove(\r
             const saml2md::EntityDescriptor& issuer,\r
             const saml2::NameID& nameid,\r
             const char* index,\r
             const Application& application,\r
             vector<string>& sessions\r
-            );\r
+            ) {\r
+            byname(issuer, nameid, index, application, sessions, true);\r
+        }\r
 \r
         Category& m_log;\r
         StorageService* m_storage;\r
@@ -174,6 +185,14 @@ namespace shibsp {
     private:\r
         // maintain back-mappings of NameID/SessionIndex -> session key\r
         void insert(const char* key, time_t expires, const char* name, const char* index);\r
+        void byname(\r
+            const saml2md::EntityDescriptor& issuer,\r
+            const saml2::NameID& nameid,\r
+            const char* index,\r
+            const Application& application,\r
+            vector<string>& sessions,\r
+            bool logout\r
+            );\r
 \r
         bool stronglyMatches(const XMLCh* idp, const XMLCh* sp, const saml2::NameID& n1, const saml2::NameID& n2) const;\r
     };\r
@@ -770,12 +789,13 @@ void SSCache::remove(const char* key, const Application& application)
     xlog->log.info("Destroyed session (applicationId: %s) (ID: %s)", application.getId(), key);\r
 }\r
 \r
-void SSCache::remove(\r
+void SSCache::byname(\r
     const saml2md::EntityDescriptor& issuer,\r
     const saml2::NameID& nameid,\r
     const char* index,\r
     const Application& application,\r
-    vector<string>& sessionsKilled\r
+    vector<string>& sessionsKilled,\r
+    bool logout\r
     )\r
 {\r
 #ifdef _DEBUG\r
@@ -785,7 +805,10 @@ void SSCache::remove(
     auto_ptr_char entityID(issuer.getEntityID());\r
     auto_ptr_char name(nameid.getName());\r
 \r
-    m_log.info("request to logout sessions from (%s) for (%s) for session index (%s)", entityID.get(), name.get(), index ? index : "all");\r
+    m_log.info(\r
+        "request to %s sessions from (%s) for (%s) for session index (%s)",\r
+        logout ? "logout" : "locate", entityID.get(), name.get(), index ? index : "all"\r
+        );\r
 \r
     if (strlen(name.get()) > 255)\r
         const_cast<char*>(name.get())[255] = 0;\r
@@ -818,9 +841,11 @@ void SSCache::remove(
                     if (session->getEntityID() && !strcmp(session->getEntityID(), entityID.get())) {\r
                         // Same NameID?\r
                         if (stronglyMatches(issuer.getEntityID(), application.getXMLString("entityID").second, nameid, *session->getNameID())) {\r
-                            remove(key.string(), application);  // let this throw to detect errors in case logout failed\r
+                            if (logout) {\r
+                                remove(key.string(), application);  // let this throw to detect errors in case the full logout fails?\r
+                                key.destroy();\r
+                            }\r
                             sessionsKilled.push_back(key.string());\r
-                            key.destroy();\r
                         }\r
                         else {\r
                             m_log.debug("session (%s) contained a non-matching NameID, leaving it alone", key.string());\r
@@ -853,7 +878,7 @@ void SSCache::remove(
         if (obj.isnull()) {\r
             m_storage->deleteText("Logout", name.get());\r
         }\r
-        else {\r
+        else if (!sessionsKilled.empty()) {\r
             ostringstream out;\r
             out << obj;\r
             if (m_storage->updateText("Logout", name.get(), out.str().c_str(), 0, ver) <= 0)\r