namespace shibboleth {
- class XMLTrustImpl
+ class XMLTrustImpl : public ReloadableXMLFileImpl
{
public:
XMLTrustImpl(const char* pathname);
vector<KeyAuthority*> m_keyauths;
typedef map<pair<const XMLCh*,bool>,KeyAuthority*> BindingMap;
BindingMap m_bindings;
-
- DOMDocument* m_doc;
};
- class XMLTrust : public ITrust
+ class XMLTrust : public ITrust, public ReloadableXMLFile
{
public:
- XMLTrust(const char* pathname);
- ~XMLTrust() { delete m_lock; delete m_impl; }
+ XMLTrust(const char* pathname) : ReloadableXMLFile(pathname) {}
+ ~XMLTrust() {}
- void lock();
- void unlock() { m_lock->unlock(); }
saml::Iterator<XSECCryptoX509*> getCertificates(const XMLCh* subject) const;
- bool validate(const ISite* site, saml::Iterator<XSECCryptoX509*> certs) const;
- bool validate(const ISite* site, saml::Iterator<const XMLCh*> certs) const;
+ bool validate(const ISite* site, const saml::Iterator<XSECCryptoX509*>& certs) const;
+ bool validate(const ISite* site, const saml::Iterator<const XMLCh*>& certs) const;
bool attach(const ISite* site, SSL_CTX* ctx) const;
- private:
- std::string m_source;
- time_t m_filestamp;
- RWLock* m_lock;
- XMLTrustImpl* m_impl;
+ protected:
+ virtual ReloadableXMLFileImpl* newImplementation(const char* pathname) const;
};
}
extern "C" ITrust* XMLTrustFactory(const char* source)
{
- return new XMLTrust(source);
+ XMLTrust* t=new XMLTrust(source);
+ try
+ {
+ t->getImplementation();
+ }
+ catch (...)
+ {
+ delete t;
+ throw;
+ }
+ return t;
+}
+
+
+ReloadableXMLFileImpl* XMLTrust::newImplementation(const char* pathname) const
+{
+ return new XMLTrustImpl(pathname);
}
X509_STORE* XMLTrustImpl::KeyAuthority::getX509Store(bool cached)
delete (*j);
}
-XMLTrustImpl::XMLTrustImpl(const char* pathname) : m_doc(NULL)
+XMLTrustImpl::XMLTrustImpl(const char* pathname) : ReloadableXMLFileImpl(pathname)
{
NDC ndc("XMLTrustImpl");
Category& log=Category::getInstance(SHIB_LOGCAT".XMLTrustImpl");
- saml::XML::Parser p;
try
{
- static XMLCh base[]={chLatin_f, chLatin_i, chLatin_l, chLatin_e, chColon, chForwardSlash, chForwardSlash, chForwardSlash, chNull};
- URLInputSource src(base,pathname);
- Wrapper4InputSource dsrc(&src,false);
- m_doc=p.parse(dsrc);
-
- log.infoStream() << "Loaded and parsed trust file (" << pathname << ")" << CategoryStream::ENDLINE;
-
DOMElement* e = m_doc->getDocumentElement();
if (XMLString::compareString(XML::SHIB_NS,e->getNamespaceURI()) ||
XMLString::compareString(SHIB_L(Trust),e->getLocalName()))
}
catch (SAMLException& e)
{
- log.errorStream() << "XML error while parsing trust configuration: " << e.what() << CategoryStream::ENDLINE;
+ log.errorStream() << "Error while parsing trust configuration: " << e.what() << CategoryStream::ENDLINE;
for (vector<KeyAuthority*>::iterator i=m_keyauths.begin(); i!=m_keyauths.end(); i++)
delete (*i);
if (m_doc)
{
for (vector<KeyAuthority*>::iterator i=m_keyauths.begin(); i!=m_keyauths.end(); i++)
delete (*i);
- if (m_doc)
- m_doc->release();
-}
-
-XMLTrust::XMLTrust(const char* pathname) : m_filestamp(0), m_source(pathname), m_impl(NULL)
-{
-#ifdef WIN32
- struct _stat stat_buf;
- if (_stat(pathname, &stat_buf) == 0)
-#else
- struct stat stat_buf;
- if (stat(pathname, &stat_buf) == 0)
-#endif
- m_filestamp=stat_buf.st_mtime;
- m_impl=new XMLTrustImpl(pathname);
- m_lock=RWLock::create();
-}
-
-void XMLTrust::lock()
-{
- m_lock->rdlock();
-
- // Check if we need to refresh.
-#ifdef WIN32
- struct _stat stat_buf;
- if (_stat(m_source.c_str(), &stat_buf) == 0)
-#else
- struct stat stat_buf;
- if (stat(m_source.c_str(), &stat_buf) == 0)
-#endif
- {
- if (m_filestamp>0 && m_filestamp<stat_buf.st_mtime)
- {
- // Elevate lock and recheck.
- m_lock->unlock();
- m_lock->wrlock();
- if (m_filestamp>0 && m_filestamp<stat_buf.st_mtime)
- {
- try
- {
- XMLTrustImpl* new_mapper=new XMLTrustImpl(m_source.c_str());
- delete m_impl;
- m_impl=new_mapper;
- m_filestamp=stat_buf.st_mtime;
- m_lock->unlock();
- }
- catch(SAMLException& e)
- {
- m_lock->unlock();
- saml::NDC ndc("lock");
- Category::getInstance(SHIB_LOGCAT".XMLTrust").error("failed to reload trust metadata, sticking with what we have: %s", e.what());
- }
- catch(...)
- {
- m_lock->unlock();
- saml::NDC ndc("lock");
- Category::getInstance(SHIB_LOGCAT".XMLTrust").error("caught an unknown exception, sticking with what we have");
- }
- }
- else
- {
- m_lock->unlock();
- }
- m_lock->rdlock();
- }
- }
}
Iterator<XSECCryptoX509*> XMLTrust::getCertificates(const XMLCh* subject) const
{
// Find the first matching entity binding.
- for (XMLTrustImpl::BindingMap::const_iterator i=m_impl->m_bindings.begin(); i!=m_impl->m_bindings.end(); i++)
+ XMLTrustImpl* impl=dynamic_cast<XMLTrustImpl*>(getImplementation());
+ for (XMLTrustImpl::BindingMap::const_iterator i=impl->m_bindings.begin(); i!=impl->m_bindings.end(); i++)
{
if (i->second->m_type!=XMLTrustImpl::KeyAuthority::entity)
continue;
NDC ndc("attach");
// Use the matching bindings.
- for (XMLTrustImpl::BindingMap::const_iterator i=m_impl->m_bindings.begin(); i!=m_impl->m_bindings.end(); i++)
+ XMLTrustImpl* impl=dynamic_cast<XMLTrustImpl*>(getImplementation());
+ for (XMLTrustImpl::BindingMap::const_iterator i=impl->m_bindings.begin(); i!=impl->m_bindings.end(); i++)
{
if (i->second->m_type!=XMLTrustImpl::KeyAuthority::authority)
continue;
return false;
}
-bool XMLTrust::validate(const ISite* site, Iterator<XSECCryptoX509*> certs) const
+bool XMLTrust::validate(const ISite* site, const Iterator<XSECCryptoX509*>& certs) const
{
vector<const XMLCh*> temp;
while (certs.hasNext())
return validate(site,temp);
}
-bool XMLTrust::validate(const ISite* site, Iterator<const XMLCh*> certs) const
+bool XMLTrust::validate(const ISite* site, const Iterator<const XMLCh*>& certs) const
{
NDC ndc("validate");
STACK_OF(X509)* chain=sk_X509_new_null();
while (certs.hasNext())
{
- auto_ptr<char> temp(XMLString::transcode(certs.next()));
+ auto_ptr_char temp(certs.next());
X509* x=B64_to_X509(temp.get());
if (!x)
{
}
// Use the matching bindings.
- for (XMLTrustImpl::BindingMap::const_iterator i=m_impl->m_bindings.begin(); i!=m_impl->m_bindings.end(); i++)
+ XMLTrustImpl* impl=dynamic_cast<XMLTrustImpl*>(getImplementation());
+ for (XMLTrustImpl::BindingMap::const_iterator i=impl->m_bindings.begin(); i!=impl->m_bindings.end(); i++)
{
if (i->second->m_type!=XMLTrustImpl::KeyAuthority::authority)
continue;
}
catch (XMLException& ex)
{
- auto_ptr<char> tmp(XMLString::transcode(ex.getMessage()));
+ auto_ptr_char tmp(ex.getMessage());
Category& log=Category::getInstance(SHIB_LOGCAT".XMLTrust");
log.errorStream() << "caught exception while parsing regular expression: " << tmp.get()
<< CategoryStream::ENDLINE;