Expose SAML objects from ICacheEntry
authorScott Cantor <cantor.2@osu.edu>
Tue, 25 Oct 2005 03:39:02 +0000 (03:39 +0000)
committerScott Cantor <cantor.2@osu.edu>
Tue, 25 Oct 2005 03:39:02 +0000 (03:39 +0000)
shar/shibrpc-server.cpp
shib-mysql-ccache/shib-mysql-ccache.cpp
shib-target/RPCListener.cpp
shib-target/shib-ccache.cpp
shib-target/shib-target.cpp
shib-target/shib-target.h
xmlproviders/XMLAccessControl.cpp
xmlproviders/xmlproviders.vcproj

index 2086c4b..a436511 100644 (file)
@@ -117,9 +117,9 @@ extern "C" bool_t shibrpc_get_session_2_svc(
      
         // Now grab the pre-serialized authentication statement and responses
         free(result->auth_statement);
-        result->auth_statement = strdup(entry->getAuthnStatement());
+        result->auth_statement = strdup(entry->getAuthnStatementXML());
       
-        ISessionCacheEntry::CachedResponse responses=entry->getResponse();
+        ISessionCacheEntry::CachedResponseXML responses=entry->getResponseXML();
         if (responses.unfiltered) {
             free(result->attr_response_pre);
             result->attr_response_pre = strdup(responses.unfiltered);
index 5a51246..08733e6 100644 (file)
@@ -397,8 +397,10 @@ public:
   virtual const char* getClientAddress() const { return m_cacheEntry->getClientAddress(); }
   virtual ShibProfile getProfile() const { return m_cacheEntry->getProfile(); }
   virtual const char* getProviderId() const { return m_cacheEntry->getProviderId(); }
-  virtual const char* getAuthnStatement() const { return m_cacheEntry->getAuthnStatement(); }
-  virtual CachedResponse getResponse();
+  virtual const char* getAuthnStatementXML() const { return m_cacheEntry->getAuthnStatementXML(); }
+  virtual const SAMLAuthenticationStatement* getAuthnStatementSAML() const { return m_cacheEntry->getAuthnStatementSAML(); }
+  virtual CachedResponseXML getResponseXML();
+  virtual CachedResponseSAML getResponseSAML() { return m_cacheEntry->getResponseSAML(); }
 
 private:
   bool touch() const;
@@ -817,14 +819,14 @@ bool ShibMySQLCCacheEntry::touch() const
   return true;
 }
 
-ISessionCacheEntry::CachedResponse ShibMySQLCCacheEntry::getResponse()
+ISessionCacheEntry::CachedResponseXML ShibMySQLCCacheEntry::getResponseXML()
 {
     // Let the memory cache do the work first.
     // If we're hands off, just pass it back.
     if (!m_cache->m_storeAttributes)
-        return m_cacheEntry->getResponse();
+        return m_cacheEntry->getResponseXML();
     
-    CachedResponse r=m_cacheEntry->getResponse();
+    CachedResponseXML r=m_cacheEntry->getResponseXML();
     if (!r.unfiltered || !*r.unfiltered) return r;
     
     // Load the key from state if needed.
index 8f3a465..427d220 100644 (file)
@@ -89,22 +89,25 @@ namespace shibtarget {
     {
     public:
         EntryWrapper(shibrpc_get_session_ret_2& ret, Category& log);
-        ~EntryWrapper() {}
+        ~EntryWrapper() { delete p_statement; delete p_pre_response; delete p_post_response; }
         void lock() {}
         void unlock() { delete this; }
         virtual bool isValid(time_t lifetime, time_t timeout) const { return true; }
         virtual const char* getClientAddress() const { return NULL; }
         virtual ShibProfile getProfile() const { return profile; }
         virtual const char* getProviderId() const { return provider_id.c_str(); }
-        virtual const char* getAuthnStatement() const { return statement.c_str(); }
-        virtual CachedResponse getResponse() { return CachedResponse(pre_response.c_str(),post_response.c_str()); }
+        virtual const char* getAuthnStatementXML() const { return statement.c_str(); }
+        virtual const SAMLAuthenticationStatement* getAuthnStatementSAML() const { return p_statement; }
+        virtual CachedResponseXML getResponseXML() { return CachedResponseXML(pre_response.c_str(),post_response.c_str()); }
+        virtual CachedResponseSAML getResponseSAML() { return CachedResponseSAML(p_pre_response,p_post_response); }
     
     private:
         string provider_id;
         ShibProfile profile;
-        string statement;
-        string pre_response;
-        string post_response;
+        string statement,pre_response,post_response;
+        SAMLAuthenticationStatement* p_statement;
+        SAMLResponse* p_pre_response;
+        SAMLResponse* p_post_response;
     };
 }
 
@@ -231,15 +234,42 @@ void RPCListener::sessionNew(
 EntryWrapper::EntryWrapper(shibrpc_get_session_ret_2& ret, Category& log)
 {
     profile = static_cast<ShibProfile>(ret.profile);
+    int minor = (profile==SAML10_POST || profile==SAML10_ARTIFACT) ? 0 : 1;
+
     provider_id = ret.provider_id;
-    
-    // Just copy over the XML.
+
+    // Copy over the XML.
     if (ret.auth_statement)
         statement=ret.auth_statement;
     if (ret.attr_response_pre)
         pre_response = ret.attr_response_pre;
     if (ret.attr_response_post)
         post_response = ret.attr_response_post;
+
+    istringstream authstream(ret.auth_statement);
+    log.debugStream() << "trying to decode authentication statement: "
+        << ((ret.auth_statement && *ret.auth_statement) ? ret.auth_statement : "(none)") << CategoryStream::ENDLINE;
+    auto_ptr<SAMLAuthenticationStatement> s(
+       (ret.auth_statement && *ret.auth_statement) ? new SAMLAuthenticationStatement(authstream) : NULL
+       );
+
+    istringstream prestream(ret.attr_response_pre);
+    log.debugStream() << "trying to decode unfiltered attribute response: "
+        << ((ret.attr_response_pre && *ret.attr_response_pre) ? ret.attr_response_pre : "(none)") << CategoryStream::ENDLINE;
+    auto_ptr<SAMLResponse> pre(
+       (ret.attr_response_pre && *ret.attr_response_pre) ? new SAMLResponse(prestream,minor) : NULL
+       );
+
+    istringstream poststream(ret.attr_response_post);
+    log.debugStream() << "trying to decode filtered attribute response: "
+        << ((ret.attr_response_post && *ret.attr_response_post) ? ret.attr_response_post : "(none)") << CategoryStream::ENDLINE;
+    auto_ptr<SAMLResponse> post(
+       (ret.attr_response_post && *ret.attr_response_post) ? new SAMLResponse(poststream,minor) : NULL
+       );
+
+    p_statement=s.release();
+    p_pre_response = pre.release();
+    p_post_response = post.release();
 }
 
 void RPCListener::sessionGet(
index b9a2164..48c446a 100644 (file)
@@ -104,8 +104,10 @@ public:
   const char* getClientAddress() const { return m_clientAddress.c_str(); }
   ShibProfile getProfile() const { return m_profile; }
   const char* getProviderId() const { return m_provider_id.c_str(); }
-  const char* getAuthnStatement() const { return m_auth_statement.c_str(); }
-  CachedResponse getResponse();
+  const char* getAuthnStatementXML() const { return m_auth_statement.c_str(); }
+  CachedResponseXML getResponseXML();
+  const SAMLAuthenticationStatement* getAuthnStatementSAML() const { throw SAMLException("unsupported operation"); }
+  CachedResponseSAML getResponseSAML() { throw SAMLException("unsupported operation"); }
 
   time_t lastAccess() const { return m_lastAccess; }
   
@@ -542,10 +544,10 @@ bool InternalCCacheEntry::isValid(time_t lifetime, time_t timeout) const
   return true;
 }
 
-ISessionCacheEntry::CachedResponse InternalCCacheEntry::getResponse()
+ISessionCacheEntry::CachedResponseXML InternalCCacheEntry::getResponseXML()
 {
     populate();
-    return CachedResponse(m_response_pre.c_str(),m_response_post.c_str());
+    return CachedResponseXML(m_response_pre.c_str(),m_response_post.c_str());
 }
 
 time_t InternalCCacheEntry::calculateExpiration(const SAMLResponse& r) const
index 2293cbd..697def9 100644 (file)
@@ -513,33 +513,15 @@ pair<bool,void*> ShibTarget::doExportAssertions(bool requireSession)
                        return pair<bool,void*>(false,NULL);    // just bail silently
         }
 
-        ISessionCacheEntry::CachedResponse cr=m_priv->m_cacheEntry->getResponse();
+        const SAMLAuthenticationStatement* authn=m_priv->m_cacheEntry->getAuthnStatementSAML();
+        ISessionCacheEntry::CachedResponseSAML scr=m_priv->m_cacheEntry->getResponseSAML();
+        ISessionCacheEntry::CachedResponseXML xcr=m_priv->m_cacheEntry->getResponseXML();
 
-        // Reconstitute SAML objects from XML in session cache and wrap them in smart pointers
-        SAMLAuthenticationStatement* authn=NULL;
-        SAMLResponse* response=NULL;
-        
-        const char* xml=m_priv->m_cacheEntry->getAuthnStatement();
-        if (xml && *xml) {
-            istringstream authstream(xml);
-            log(LogLevelDebug,string("parsing authentication statement: ") + xml);
-            authn = new SAMLAuthenticationStatement(authstream);
-        }
-        auto_ptr<SAMLAuthenticationStatement> authnwrapper(authn);
-    
-        if (cr.unfiltered && *cr.unfiltered) {
-            int minor = (m_priv->m_cacheEntry->getProfile()==SAML10_POST || m_priv->m_cacheEntry->getProfile()==SAML10_ARTIFACT) ? 0 : 1;
-            istringstream rstream((cr.filtered && *cr.filtered) ? cr.filtered : cr.unfiltered);
-            log(LogLevelDebug,string("parsing attribute response: ") + ((cr.filtered && *cr.filtered) ? cr.filtered : cr.unfiltered));
-            response = new SAMLResponse(rstream,minor);
-        }
-        auto_ptr<SAMLResponse> responsewrapper(response);
-    
         // Maybe export the response.
         pair<bool,bool> exp=m_priv->m_settings.first->getBool("exportAssertion");
-        if (exp.first && exp.second && cr.unfiltered && *cr.unfiltered) {
+        if (exp.first && exp.second && xcr.unfiltered && *xcr.unfiltered) {
             unsigned int outlen;
-            XMLByte* serialized = Base64::encode(reinterpret_cast<XMLByte*>((char*)cr.unfiltered), strlen(cr.unfiltered), &outlen);
+            XMLByte* serialized = Base64::encode(reinterpret_cast<XMLByte*>((char*)xcr.unfiltered), strlen(xcr.unfiltered), &outlen);
             XMLByte *pos, *pos2;
             for (pos=serialized, pos2=serialized; *pos2; pos2++)
                 if (isgraph(*pos2))
@@ -548,7 +530,7 @@ pair<bool,void*> ShibTarget::doExportAssertions(bool requireSession)
             setHeader("Shib-Attributes", reinterpret_cast<char*>(serialized));
             XMLString::release(&serialized);
         }
-    
+
         // Export the SAML AuthnMethod and the origin site name, and possibly the NameIdentifier.
         setHeader("Shib-Origin-Site", m_priv->m_cacheEntry->getProviderId());
         setHeader("Shib-Identity-Provider", m_priv->m_cacheEntry->getProviderId());
@@ -578,7 +560,7 @@ pair<bool,void*> ShibTarget::doExportAssertions(bool requireSession)
         setHeader("Shib-Application-ID", m_priv->m_app->getId());
     
         // Export the attributes.
-        Iterator<SAMLAssertion*> a_iter(response ? response->getAssertions() : EMPTY(SAMLAssertion*));
+        Iterator<SAMLAssertion*> a_iter(scr.filtered ? scr.filtered->getAssertions() : EMPTY(SAMLAssertion*));
         while (a_iter.hasNext()) {
             SAMLAssertion* assert=a_iter.next();
             Iterator<SAMLStatement*> statements=assert->getStatements();
index 9da91ea..84c6d8a 100644 (file)
@@ -149,16 +149,26 @@ namespace shibtarget {
         virtual const char* getClientAddress() const=0;
         virtual ShibProfile getProfile() const=0;
         virtual const char* getProviderId() const=0;
-        virtual const char* getAuthnStatement() const=0;
-        struct SHIBTARGET_EXPORTS CachedResponse {
-            CachedResponse(const char* unfiltered, const char* filtered) {
+        virtual const char* getAuthnStatementXML() const=0;
+        virtual const saml::SAMLAuthenticationStatement* getAuthnStatementSAML() const=0;
+        struct SHIBTARGET_EXPORTS CachedResponseXML {
+            CachedResponseXML(const char* unfiltered, const char* filtered) {
                 this->unfiltered=unfiltered;
                 this->filtered=filtered;
             }
             const char* unfiltered;
             const char* filtered;
         };
-        virtual CachedResponse getResponse()=0;
+        struct SHIBTARGET_EXPORTS CachedResponseSAML {
+            CachedResponseSAML(const saml::SAMLResponse* unfiltered, const saml::SAMLResponse* filtered) {
+                this->unfiltered=unfiltered;
+                this->filtered=filtered;
+            }
+            const saml::SAMLResponse* unfiltered;
+            const saml::SAMLResponse* filtered;
+        };
+        virtual CachedResponseXML getResponseXML()=0;
+        virtual CachedResponseSAML getResponseSAML()=0;
         virtual ~ISessionCacheEntry() {}
     };
 
index be0e744..8e06566 100644 (file)
@@ -132,7 +132,7 @@ bool Rule::authorized(ShibTarget* st, ISessionCacheEntry* entry) const
     }
     
     // Find the corresponding attribute. This isn't very efficient...
-    ISessionCacheEntry::CachedResponse cr=entry->getResponse();
+    ISessionCacheEntry::CachedResponseSAML cr=entry->getResponseSAML();
     Iterator<SAMLAssertion*> a_iter(cr.filtered ? cr.filtered->getAssertions() : EMPTY(SAMLAssertion*));
     while (a_iter.hasNext()) {
         SAMLAssertion* assert=a_iter.next();
index 9db4379..03f97f0 100644 (file)
                        </FileConfiguration>
                </File>
                <File
+                       RelativePath=".\XMLAccessControl.cpp">
+               </File>
+               <File
                        RelativePath="XMLCredentials.cpp">
                        <FileConfiguration
                                Name="Release|Win32">