Added new OriginSiteMapper design to support refresh.
authorScott Cantor <cantor.2@osu.edu>
Wed, 19 Feb 2003 19:14:37 +0000 (19:14 +0000)
committerScott Cantor <cantor.2@osu.edu>
Wed, 19 Feb 2003 19:14:37 +0000 (19:14 +0000)
12 files changed:
eduPerson/ScopedAttribute.cpp
shib-target/shib-config.cpp
shib/ClubShibPOSTProfile.cpp
shib/Makefile.am
shib/OriginSiteMapper.cpp [new file with mode: 0644]
shib/ShibConfig.cpp
shib/ShibPOSTProfile.cpp
shib/XMLOriginSiteMapper.cpp
shib/internal.h
shib/shib-threads.h
shib/shib.h
test/posttest.cpp

index ad88e2e..42caa20 100644 (file)
@@ -102,8 +102,8 @@ bool ScopedAttribute::addValue(DOMElement* e)
 
 bool ScopedAttribute::accept(DOMElement* e) const
 {
-    IOriginSiteMapper* mapper=ShibConfig::getConfig().origin_mapper;
-    Iterator<pair<xstring,bool> > domains=mapper->getSecurityDomains(m_defaultScope.c_str());
+    OriginSiteMapper mapper;
+    Iterator<pair<xstring,bool> > domains=mapper.getSecurityDomains(m_defaultScope.c_str());
     const XMLCh* this_scope=NULL;
     DOMAttr* scope=e->getAttributeNodeNS(NULL,Scope);
     if (scope)
index dce9d12..f68cb1b 100644 (file)
@@ -153,33 +153,16 @@ STConfig::STConfig(const char* app_name, const char* inifile)
     throw runtime_error ("No Sites File found in configuration");
   }
 
-  string sitesFile = tag;
-  X509Certificate* verifyKey = NULL;
-
+  shibConf.mapperURL=tag;
   try {
     if (ini->get_tag (app, SHIBTARGET_TAG_SITESCERT, true, &tag)) {
-      verifyKey = new X509Certificate (X509Certificate::PEM, tag.c_str());
+      shibConf.mapperCert = new X509Certificate (X509Certificate::PEM, tag.c_str());
     }
   } catch (...) {
     log.crit ("Can not read the x509 certificate.");
     throw;
   }
 
-  try
-  {
-    shibConf.origin_mapper = new XMLOriginSiteMapper(sitesFile.c_str(),
-                                                  samlConf.ssl_calist.c_str(),
-                                                  verifyKey);
-  }
-  catch (SAMLException& ex)
-  {
-      log.fatal("Failed to initialize OriginSiteMapper");
-      throw runtime_error(string("Failed to initialize OriginSiteMapper: ") + ex.what());
-  }
-
-  if (verifyKey)
-    delete verifyKey;
-  
   try { 
     if (!shibConf.init()) {
       log.fatal ("Failed to initialize Shib library");
@@ -254,7 +237,6 @@ STConfig::~STConfig()
   if (g_shibTargetCCache)
     delete g_shibTargetCCache;
 
-  delete shibConf.origin_mapper;
   shibConf.term();
   samlConf.term();
 }
index 1e9adda..b9dff17 100644 (file)
@@ -108,7 +108,7 @@ SAMLResponse* ClubShibPOSTProfile::prepare(const XMLCh* recipient,
                                     responseKey,responseCert,assertionKey,assertionCert);
 }
 
-void ClubShibPOSTProfile::verifySignature(const SAMLSignedObject& obj, const XMLCh* signerName, const saml::Key* knownKey)
+void ClubShibPOSTProfile::verifySignature(const SAMLSignedObject& obj, const XMLCh* signerName, const X509Certificate* knownKey)
 {
     ShibPOSTProfile::verifySignature(obj,signerName,knownKey);
     if (obj.getSignatureAlgorithm()!=SAMLSignedObject::RSA_SHA1)
index 4d94efd..a7c858e 100644 (file)
@@ -11,6 +11,7 @@ noinst_HEADERS = internal.h
 libshib_la_SOURCES = \
                     ClubShibPOSTProfile.cpp \
                     Constants.cpp \
+                    OriginSiteMapper.cpp \
                     SAMLBindingFactory.cpp \
                     ShibConfig.cpp \
                     ShibPOSTProfile.cpp \
diff --git a/shib/OriginSiteMapper.cpp b/shib/OriginSiteMapper.cpp
new file mode 100644 (file)
index 0000000..bfb6211
--- /dev/null
@@ -0,0 +1,91 @@
+/* 
+ * The Shibboleth License, Version 1. 
+ * Copyright (c) 2002 
+ * University Corporation for Advanced Internet Development, Inc. 
+ * All rights reserved
+ * 
+ * 
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions are met:
+ * 
+ * Redistributions of source code must retain the above copyright notice, this 
+ * list of conditions and the following disclaimer.
+ * 
+ * Redistributions in binary form must reproduce the above copyright notice, 
+ * this list of conditions and the following disclaimer in the documentation 
+ * and/or other materials provided with the distribution, if any, must include 
+ * the following acknowledgment: "This product includes software developed by 
+ * the University Corporation for Advanced Internet Development 
+ * <http://www.ucaid.edu>Internet2 Project. Alternately, this acknowledegement 
+ * may appear in the software itself, if and wherever such third-party 
+ * acknowledgments normally appear.
+ * 
+ * Neither the name of Shibboleth nor the names of its contributors, nor 
+ * Internet2, nor the University Corporation for Advanced Internet Development, 
+ * Inc., nor UCAID may be used to endorse or promote products derived from this 
+ * software without specific prior written permission. For written permission, 
+ * please contact shibboleth@shibboleth.org
+ * 
+ * Products derived from this software may not be called Shibboleth, Internet2, 
+ * UCAID, or the University Corporation for Advanced Internet Development, nor 
+ * may Shibboleth appear in their name, without prior written permission of the 
+ * University Corporation for Advanced Internet Development.
+ * 
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
+ * AND WITH ALL FAULTS. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 
+ * PARTICULAR PURPOSE, AND NON-INFRINGEMENT ARE DISCLAIMED AND THE ENTIRE RISK 
+ * OF SATISFACTORY QUALITY, PERFORMANCE, ACCURACY, AND EFFORT IS WITH LICENSEE. 
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER, CONTRIBUTORS OR THE UNIVERSITY 
+ * CORPORATION FOR ADVANCED INTERNET DEVELOPMENT, INC. BE LIABLE FOR ANY DIRECT, 
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* XMLOriginSiteMapper.h - a mapper implementation that uses an XML-based registry
+
+   Scott Cantor
+   9/27/02
+
+   $History:$
+*/
+
+#define SHIB_INSTANTIATE
+
+#include "internal.h"
+
+using namespace shibboleth;
+using namespace saml;
+using namespace std;
+
+OriginSiteMapper::OriginSiteMapper() : m_mapper(ShibConfig::getConfig().getMapper()) {}
+
+OriginSiteMapper::~OriginSiteMapper()
+{
+    ShibConfig::getConfig().releaseMapper(m_mapper);
+}
+
+Iterator<xstring> OriginSiteMapper::getHandleServiceNames(const XMLCh* originSite)
+{
+    return m_mapper->getHandleServiceNames(originSite);
+}
+
+const X509Certificate* OriginSiteMapper::getHandleServiceCert(const XMLCh* handleService)
+{
+    return m_mapper->getHandleServiceCert(handleService);
+}
+
+Iterator<pair<xstring,bool> > OriginSiteMapper::getSecurityDomains(const XMLCh* originSite)
+{
+    return m_mapper->getSecurityDomains(originSite);
+}
+
+const char* OriginSiteMapper::getTrustedRoots()
+{
+    return m_mapper->getTrustedRoots();
+}
index beb0581..0324c25 100644 (file)
@@ -56,6 +56,9 @@
    $History:$
 */
 
+#include <time.h>
+#include <signal.h>
+
 #include "internal.h"
 #include <log4cpp/Category.hh>
 
@@ -69,6 +72,8 @@ namespace {
     ShibInternalConfig g_config;
 }
 
+ShibConfig::~ShibConfig() {}
+
 bool ShibInternalConfig::init()
 {
     saml::NDC ndc("init");
@@ -79,27 +84,137 @@ bool ShibInternalConfig::init()
     // Register extension schema.
     saml::XML::registerSchema(XML::SHIB_NS,XML::SHIB_SCHEMA_ID);
 
+    m_lock=RWLock::create();
+    m_shutdown_wait = CondWait::create();
+    if (!m_lock || !m_shutdown_wait)
+    {
+        log4cpp::Category::getInstance(SHIB_LOGCAT".ShibConfig").fatal("init: failed to create mapper locks");
+        delete m_lock;
+        delete m_shutdown_wait;
+        return false;
+    }
+
+    try
+    {
+        m_mapper=new XMLOriginSiteMapper(mapperURL.c_str(),SAMLConfig::getConfig().ssl_calist.c_str(),mapperCert);
+    }
+    catch(SAMLException& e)
+    {
+        log4cpp::Category::getInstance(SHIB_LOGCAT".ShibConfig").fatal("init: failed to initialize origin site mapper: %s", e.what());
+        delete m_lock;
+        delete m_shutdown_wait;
+        return false;
+    }
+
     m_manager=xmlSecSimpleKeysMngrCreate();
-    if (origin_mapper && origin_mapper->getTrustedRoots() && *(origin_mapper->getTrustedRoots()) &&
-        xmlSecSimpleKeysMngrLoadPemCert(m_manager,origin_mapper->getTrustedRoots(),true) < 0)
+    const char* roots=m_mapper->getTrustedRoots();
+    if (roots && *roots && xmlSecSimpleKeysMngrLoadPemCert(m_manager,roots,true) < 0)
     {
         log4cpp::Category::getInstance(SHIB_LOGCAT".ShibConfig").fatal("init: failed to load CAs into simple key manager");
         xmlSecSimpleKeysMngrDestroy(m_manager);
-        m_manager=NULL;
+        delete m_mapper;
+        delete m_lock;
+        delete m_shutdown_wait;
         return false;
     }
     SAMLConfig::getConfig().xmlsig_ptr=m_manager;
+    if (mapperRefreshInterval)
+        m_refresh_thread = Thread::create(&refresh_fn, (void*)this);
 
     return true;
 }
 
 void ShibInternalConfig::term()
 {
+    // Shut down the refresh thread and let it know...
+    if (m_refresh_thread)
+    {
+        m_shutdown = true;
+        m_shutdown_wait->signal();
+        m_refresh_thread->join(NULL);
+    }
+
+    delete m_mapper;
     if (m_manager)
         xmlSecSimpleKeysMngrDestroy(m_manager);
+    delete mapperCert;
+    delete m_lock;
+    delete m_shutdown_wait;
+}
+
+IOriginSiteMapper* ShibInternalConfig::getMapper()
+{
+    m_lock->rdlock();
+    return m_mapper;
+}
+
+void ShibInternalConfig::releaseMapper(IOriginSiteMapper* mapper)
+{
+    m_lock->unlock();
 }
 
 ShibConfig& ShibConfig::getConfig()
 {
     return g_config;
 }
+
+void* ShibInternalConfig::refresh_fn(void* config_p)
+{
+  ShibInternalConfig* config = reinterpret_cast<ShibInternalConfig*>(config_p);
+
+  // First, let's block all signals
+  sigset_t sigmask;
+  sigfillset(&sigmask);
+  Thread::mask_signals(SIG_BLOCK, &sigmask, NULL);
+
+  // Now run the cleanup process.
+  config->refresh();
+}
+
+void ShibInternalConfig::refresh()
+{
+    Mutex* mutex = Mutex::create();
+    saml::NDC ndc("cleanup");
+    log4cpp::Category& log=log4cpp::Category::getInstance(SHIB_LOGCAT".ShibConfig");
+
+    mutex->lock();
+
+    log.debug("XMLMapper refresh thread started...");
+
+    while (!m_shutdown)
+    {
+        struct timespec ts;
+        memset (&ts, 0, sizeof(ts));
+        ts.tv_sec = time(NULL) + mapperRefreshInterval;
+
+        m_shutdown_wait->timedwait(mutex, &ts);
+
+        if (m_shutdown)
+            break;
+
+        log.info("Refresh thread running...");
+
+        // To refresh the mapper, we basically build a new one in the background and if it works,
+        // we grab the write lock and replace the official pointer with the new one.
+        try
+        {
+            IOriginSiteMapper* new_mapper=new XMLOriginSiteMapper(mapperURL.c_str(),SAMLConfig::getConfig().ssl_calist.c_str(),mapperCert);
+            m_lock->wrlock();
+            delete m_mapper;
+            m_mapper=new_mapper;
+            m_lock->unlock();
+        }
+        catch(SAMLException& e)
+        {
+            log.error("failed to build a refreshed origin site mapper, sticking with what we have: %s", e.what());
+        }
+        catch(...)
+        {
+            log.error("caught an unknown exception, sticking with what we have");
+        }
+    }
+
+    mutex->unlock();
+    delete mutex;
+    Thread::exit(NULL);
+}
index 6475043..d4ec7b0 100644 (file)
@@ -127,7 +127,8 @@ SAMLResponse* ShibPOSTProfile::accept(const XMLByte* buf)
     const XMLCh* handleService = assertion->getIssuer();
 
     // Is this a trusted HS?
-    Iterator<xstring> hsNames=ShibConfig::getConfig().origin_mapper->getHandleServiceNames(originSite);
+    OriginSiteMapper mapper;
+    Iterator<xstring> hsNames=mapper.getHandleServiceNames(originSite);
     bool bFound = false;
     while (!bFound && hsNames.hasNext())
         if (!XMLString::compareString(hsNames.next().c_str(),handleService))
@@ -135,13 +136,13 @@ SAMLResponse* ShibPOSTProfile::accept(const XMLByte* buf)
     if (!bFound)
         throw TrustException(SAMLException::RESPONDER, "ShibPOSTProfile::accept() detected an untrusted HS for the origin site");
 
-    const Key* hsKey=ShibConfig::getConfig().origin_mapper->getHandleServiceKey(handleService);
+    const X509Certificate* hsCert=mapper.getHandleServiceCert(handleService);
 
     // Signature verification now takes place. We check the assertion and the response.
     // Assertion signing is optional, response signing is mandatory.
     if (assertion->isSigned())
-        verifySignature(*assertion, handleService, hsKey);
-    verifySignature(*r, handleService, hsKey);
+        verifySignature(*assertion, handleService, hsCert);
+    verifySignature(*r, handleService, hsCert);
 
     return r.release();
 }
@@ -189,7 +190,7 @@ bool ShibPOSTProfile::checkReplayCache(const SAMLAssertion& a)
     return SAMLPOSTProfile::checkReplayCache(a);
 }
 
-void ShibPOSTProfile::verifySignature(const SAMLSignedObject& obj, const XMLCh* signerName, const saml::Key* knownKey)
+void ShibPOSTProfile::verifySignature(const SAMLSignedObject& obj, const XMLCh* signerName, const X509Certificate* knownKey)
 {
     const SAMLObject* pobj=&obj;
     const SAMLResponse* ptr=dynaptr(SAMLResponse,pobj);
index 9c5f742..b81f4ef 100644 (file)
@@ -134,15 +134,35 @@ XMLOriginSiteMapper::XMLOriginSiteMapper(const char* registryURI, const char* ca
                     {
                                                os_obj->m_handleServices.push_back(hs_name.get());
 
-                                               /* Ignore KeyInfo for now...
-                                               DOM*Node ki = os_child->getFirstChild();
+                        // Look for ds:KeyInfo.
+                                               DOMNode* ki=os_child->getFirstChild();
                         while (ki && ki->getNodeType()!=DOMNode::ELEMENT_NODE)
-                                                       ki = ki->getNextSibling();
+                                                       ki=ki->getNextSibling();
                         if (ki && !XMLString::compareString(saml::XML::XMLSIG_NS,ki->getNamespaceURI()) &&
                             !XMLString::compareString(saml::XML::Literals::KeyInfo,ki->getNamespaceURI()))
                         {
+                            // Look for ds:X509Data.
+                            DOMNode* xdata=ki->getFirstChild();
+                            while (xdata && xdata->getNodeType()!=DOMNode::ELEMENT_NODE)
+                                                           xdata=xdata->getNextSibling();
+                            if (xdata && !XMLString::compareString(saml::XML::XMLSIG_NS,xdata->getNamespaceURI()) &&
+                                !XMLString::compareString(saml::XML::Literals::X509Data,xdata->getNamespaceURI()))
+                            {
+                                // Look for ds:X509Certificate.
+                                DOMNode* x509=xdata->getFirstChild();
+                                while (x509 && x509->getNodeType()!=DOMNode::ELEMENT_NODE)
+                                                               x509=x509->getNextSibling();
+                                if (x509 && !XMLString::compareString(saml::XML::XMLSIG_NS,x509->getNamespaceURI()) &&
+                                    !XMLString::compareString(saml::XML::Literals::X509Certificate,x509->getNamespaceURI()))
+                                {
+                                    const XMLCh* blob=x509->getFirstChild()->getNodeValue();
+                                    X509Certificate* cert=new X509Certificate(X509Certificate::DER_B64,
+                                                                              reinterpret_cast<const XMLByte*>(blob),
+                                                                              XMLString::stringLen(reinterpret_cast<const char*>(blob)));
+                                    m_hsCerts[hs_name.get()]=cert;
+                                }
+                            }
                                                }
-                        */
                                        }
                                }
                 else if (!XMLString::compareString(XML::SHIB_NS,os_child->getNamespaceURI()) &&
@@ -193,7 +213,7 @@ XMLOriginSiteMapper::~XMLOriginSiteMapper()
 {
     for (map<xstring,OriginSite*>::iterator i=m_sites.begin(); i!=m_sites.end(); i++)
         delete i->second;
-    for (map<xstring,Key*>::iterator j=m_hsKeys.begin(); j!=m_hsKeys.end(); j++)
+    for (map<xstring,X509Certificate*>::iterator j=m_hsCerts.begin(); j!=m_hsCerts.end(); j++)
         delete j->second;
 }
 
@@ -205,10 +225,10 @@ Iterator<xstring> XMLOriginSiteMapper::getHandleServiceNames(const XMLCh* origin
     return Iterator<xstring>(i->second->m_handleServices);
 }
 
-const Key* XMLOriginSiteMapper::getHandleServiceKey(const XMLCh* handleService)
+const X509Certificate* XMLOriginSiteMapper::getHandleServiceCert(const XMLCh* handleService)
 {
-    map<xstring,Key*>::const_iterator i=m_hsKeys.find(handleService);
-    return (i!=m_hsKeys.end()) ? i->second : NULL;
+    map<xstring,X509Certificate*>::const_iterator i=m_hsCerts.find(handleService);
+    return (i!=m_hsCerts.end()) ? i->second : NULL;
 }
 
 Iterator<pair<xstring,bool> > XMLOriginSiteMapper::getSecurityDomains(const XMLCh* originSite)
@@ -351,6 +371,37 @@ void XMLOriginSiteMapper::validateSignature(const X509Certificate* verifyKey, DO
             msg="XMLOriginSiteMapper::validateSignature() found a ds:Reference with a non-empty URL";
         else
         {
+            xmlNodePtr transforms=ref->self->children;
+            while (transforms && (transforms->type!=XML_ELEMENT_NODE ||
+                   !xmlSecCheckNodeName(transforms,reinterpret_cast<const xmlChar*>("Transforms"),xmlSecDSigNs)))
+                transforms=transforms->next;
+            if (!transforms)
+                msg="XMLOriginSiteMapper::validateSignature() unable to locate the ds:Transforms element";
+            else
+            {
+                transforms=transforms->children;
+                while (transforms && (transforms->type!=XML_ELEMENT_NODE ||
+                       !xmlSecCheckNodeName(transforms,reinterpret_cast<const xmlChar*>("Transform"),xmlSecDSigNs)))
+                    transforms=transforms->next;
+                if (!transforms)
+                    msg="XMLOriginSiteMapper::validateSignature() unable to locate a ds:Transform element";
+                else
+                {
+                    xmlChar* alg=xmlGetProp(transforms,reinterpret_cast<const xmlChar*>("Algorithm"));
+                    if (xmlStrcmp(alg,reinterpret_cast<const xmlChar*>("http://www.w3.org/2000/09/xmldsig#enveloped-signature")))
+                        msg="XMLOriginSiteMapper::validateSignature() found a non-enveloped ds:Transform";
+                    if (alg)
+                        xmlFree(alg);
+                    if (msg.empty())
+                    {
+                        transforms=transforms->next;
+                        while (transforms && transforms->type==XML_TEXT_NODE)
+                            transforms=transforms->next;
+                        if (transforms)
+                            msg="XMLOriginSiteMapper::validateSignature() found an extra ds:Transform element";
+                    }
+                }
+            }
         }
     }
     
index b336b8b..edc0335 100644 (file)
@@ -73,6 +73,7 @@
 #include <xmlsec/keysmngr.h>
 
 #include "shib.h"
+#include "shib-threads.h"
 
 #define SHIB_LOGCAT "Shibboleth"
 
@@ -81,15 +82,51 @@ namespace shibboleth
     class ShibInternalConfig : public ShibConfig
     {
     public:
-        ShibInternalConfig() : m_manager(NULL) {}
+        ShibInternalConfig() : m_mapper(NULL), m_manager(NULL), m_lock(NULL), m_shutdown_wait(NULL), m_refresh_thread(NULL), m_shutdown(false) {}
 
         // global per-process setup and shutdown of runtime
         bool init();
         void term();
 
+        IOriginSiteMapper* getMapper();
+        void releaseMapper(IOriginSiteMapper* mapper);
+        void refresh();
+
     private:
+        IOriginSiteMapper* m_mapper;
         xmlSecKeysMngrPtr m_manager;
+        RWLock* m_lock;
+        static void* refresh_fn(void*);
+        bool m_shutdown;
+        CondWait* m_shutdown_wait;
+        Thread*        m_refresh_thread;
     };
+
+    class SHIB_EXPORTS XMLOriginSiteMapper : public IOriginSiteMapper
+    {
+    public:
+        XMLOriginSiteMapper(const char* registryURI, const char* calist=NULL, const saml::X509Certificate* verifyKey=NULL);
+        ~XMLOriginSiteMapper();
+
+        virtual saml::Iterator<saml::xstring> getHandleServiceNames(const XMLCh* originSite);
+        virtual const saml::X509Certificate* getHandleServiceCert(const XMLCh* handleService);
+        virtual saml::Iterator<std::pair<saml::xstring,bool> > getSecurityDomains(const XMLCh* originSite);
+        virtual const char* getTrustedRoots();
+
+    private:
+        void validateSignature(const saml::X509Certificate* verifyKey, DOMElement* e);
+
+        struct OriginSite
+        {
+            std::vector<saml::xstring> m_handleServices;
+            std::vector<std::pair<saml::xstring,bool> > m_domains;
+        };
+
+        std::string m_calist;
+        std::map<saml::xstring,OriginSite*> m_sites;
+        std::map<saml::xstring,saml::X509Certificate*> m_hsCerts;
+    };
+
 }
 
 #endif
index 01e9e4c..71d30a7 100644 (file)
@@ -24,8 +24,9 @@ namespace shibboleth {
   public:
     static Thread* create(void* (*start_routine)(void*), void* arg);
     static void exit(void* return_val);
+#ifndef WIN32
     static int mask_signals(int how, const sigset_t *newmask, sigset_t *oldmask);
-
+#endif
     virtual int detach() = 0;
     virtual int join(void** thread_return) = 0;
     virtual int kill(int signo) = 0;
index dd70fe2..cebe37d 100644 (file)
@@ -59,6 +59,7 @@
 #ifndef __shib_h__
 #define __shib_h__
 
+#include <ctime>
 #include <saml/saml.h>
 
 #ifdef WIN32
@@ -106,34 +107,25 @@ namespace shibboleth
     struct SHIB_EXPORTS IOriginSiteMapper
     {
         virtual saml::Iterator<saml::xstring> getHandleServiceNames(const XMLCh* originSite)=0;
-        virtual const saml::Key* getHandleServiceKey(const XMLCh* handleService)=0;
+        virtual const saml::X509Certificate* getHandleServiceCert(const XMLCh* handleService)=0;
         virtual saml::Iterator<std::pair<saml::xstring,bool> > getSecurityDomains(const XMLCh* originSite)=0;
         virtual const char* getTrustedRoots()=0;
     };
 
-    class SHIB_EXPORTS XMLOriginSiteMapper : public IOriginSiteMapper
+    class SHIB_EXPORTS OriginSiteMapper : public IOriginSiteMapper
     {
     public:
-        XMLOriginSiteMapper(const char* registryURI, const char* calist=NULL, const saml::X509Certificate* verifyKey=NULL);
-        ~XMLOriginSiteMapper();
-
+        OriginSiteMapper();
+        ~OriginSiteMapper();
         virtual saml::Iterator<saml::xstring> getHandleServiceNames(const XMLCh* originSite);
-        virtual const saml::Key* getHandleServiceKey(const XMLCh* handleService);
+        virtual const saml::X509Certificate* getHandleServiceCert(const XMLCh* handleService);
         virtual saml::Iterator<std::pair<saml::xstring,bool> > getSecurityDomains(const XMLCh* originSite);
         virtual const char* getTrustedRoots();
 
     private:
-        void validateSignature(const saml::X509Certificate* verifyKey, DOMElement* e);
-
-        struct OriginSite
-        {
-            std::vector<saml::xstring> m_handleServices;
-            std::vector<std::pair<saml::xstring,bool> > m_domains;
-        };
-
-        std::string m_calist;
-        std::map<saml::xstring,OriginSite*> m_sites;
-        std::map<saml::xstring,saml::Key*> m_hsKeys;
+        OriginSiteMapper(const OriginSiteMapper&);
+        void operator=(const OriginSiteMapper&);
+        IOriginSiteMapper* m_mapper;
     };
 
     class SHIB_EXPORTS ShibPOSTProfile
@@ -158,7 +150,7 @@ namespace shibboleth
         virtual bool checkReplayCache(const saml::SAMLAssertion& a);
 
     protected:
-        virtual void verifySignature(const saml::SAMLSignedObject& obj, const XMLCh* signerName, const saml::Key* knownKey);
+        virtual void verifySignature(const saml::SAMLSignedObject& obj, const XMLCh* signerName, const saml::X509Certificate* knownKey);
 
         saml::SAMLSignedObject::sigs_t m_algorithm;
         std::vector<const XMLCh*> m_policies;
@@ -189,7 +181,7 @@ namespace shibboleth
                                             const saml::Key* assertionKey=NULL, const saml::X509Certificate* assertionCert=NULL);
 
     protected:
-        virtual void verifySignature(const saml::SAMLSignedObject& obj, const XMLCh* signerName, const saml::Key* knownKey);
+        virtual void verifySignature(const saml::SAMLSignedObject& obj, const XMLCh* signerName, const saml::X509Certificate* knownKey);
     };
 
     class SHIB_EXPORTS ShibPOSTProfileFactory
@@ -202,6 +194,9 @@ namespace shibboleth
     class SHIB_EXPORTS ShibConfig
     {
     public:
+        ShibConfig() : mapperCert(NULL), mapperRefreshInterval(0) {}
+        virtual ~ShibConfig();
+
         // global per-process setup and shutdown of Shibboleth runtime
         virtual bool init()=0;
         virtual void term()=0;
@@ -209,8 +204,13 @@ namespace shibboleth
         // enables runtime and clients to access configuration
         static ShibConfig& getConfig();
 
+        virtual IOriginSiteMapper* getMapper()=0;
+        virtual void releaseMapper(IOriginSiteMapper* mapper)=0;
+
     /* start of external configuration */
-        IOriginSiteMapper* origin_mapper;
+        std::string mapperURL;
+        saml::X509Certificate* mapperCert;
+        time_t mapperRefreshInterval;
     /* end of external configuration */
     };
 
index 2cd70fd..ec5d9e2 100644 (file)
@@ -93,13 +93,13 @@ int main(int argc,char* argv[])
     }
 
     conf1.schema_dir=path;
+    conf1.ssl_calist="C:/shib/etc/ca-bundle.crt";
     if (!conf1.init())
         cerr << "unable to initialize SAML runtime" << endl;
 
-    X509Certificate cert(X509Certificate::PEM,"C:/shib/etc/internet2.pem");
-    XMLOriginSiteMapper mapper("/Tomcat4.0/webapps/shibboleth/sites.xml","C:/shib/etc/ca-bundle.crt",&cert);
+    conf2.mapperURL="/Tomcat4.0/webapps/shibboleth/sites.xml";
+    conf2.mapperCert=new X509Certificate(X509Certificate::PEM,"C:/shib/etc/internet2.pem");
     //XMLOriginSiteMapper mapper("http://wayf.internet2.edu/shibboleth/sites.xml","/shib/etc/ca-bundle.crt",&cert);
-    conf2.origin_mapper=&mapper;
     if (!conf2.init())
         cerr << "unable to initialize Shibboleth runtime" << endl;