From cd42fc0cc9b1fe1db17bbcaaa6cd2a5efc8918e1 Mon Sep 17 00:00:00 2001 From: cantor Date: Tue, 26 Dec 2006 20:26:50 +0000 Subject: [PATCH] Moved property set classes to new library. git-svn-id: https://svn.middleware.georgetown.edu/cpp-sp/trunk@2093 cb58f699-b61c-0410-a6fe-9272a202ed29 --- apache/mod_apache.cpp | 24 ++-- isapi_shib/isapi_shib.cpp | 2 +- nsapi_shib/nsapi_shib.cpp | 22 ++-- shib-target/ArtifactMapper.cpp | 11 +- shib-target/ShibHTTPHook.cpp | 9 +- shib-target/XMLRequestMapper.cpp | 32 +++--- shib-target/internal.h | 36 ------ shib-target/shib-ccache.cpp | 4 +- shib-target/shib-handlers.cpp | 4 +- shib-target/shib-ini.cpp | 241 +++++---------------------------------- shib-target/shib-target.cpp | 15 +-- shib-target/shib-target.h | 37 ++---- shibsp/DOMPropertySet.cpp | 214 ++++++++++++++++++++++++++++++++++ shibsp/DOMPropertySet.h | 74 ++++++++++++ shibsp/Makefile.am | 3 + shibsp/PropertySet.h | 105 +++++++++++++++++ shibsp/shibsp.vcproj | 12 ++ 17 files changed, 514 insertions(+), 331 deletions(-) create mode 100644 shibsp/DOMPropertySet.cpp create mode 100644 shibsp/DOMPropertySet.h create mode 100644 shibsp/PropertySet.h diff --git a/apache/mod_apache.cpp b/apache/mod_apache.cpp index 955afd6..8dd7095 100644 --- a/apache/mod_apache.cpp +++ b/apache/mod_apache.cpp @@ -477,7 +477,7 @@ IPlugIn* htAccessFactory(const DOMElement* e) return new htAccessControl(); } -class ApacheRequestMapper : public virtual IRequestMapper, public virtual IPropertySet +class ApacheRequestMapper : public virtual IRequestMapper, public virtual PropertySet { public: ApacheRequestMapper(const DOMElement* e); @@ -491,7 +491,7 @@ public: pair getXMLString(const char* name, const char* ns=NULL) const; pair getUnsignedInt(const char* name, const char* ns=NULL) const; pair getInt(const char* name, const char* ns=NULL) const; - const IPropertySet* getPropertySet(const char* name, const char* ns="urn:mace:shibboleth:target:config:1.0") const; + const PropertySet* getPropertySet(const char* name, const char* ns="urn:mace:shibboleth:target:config:1.0") const; const DOMElement* getElement() const; private: @@ -524,13 +524,13 @@ IRequestMapper::Settings ApacheRequestMapper::getSettings(ShibTarget* st) const Settings s=m_mapper->getSettings(st); m_staKey->setData(dynamic_cast(st)); m_propsKey->setData((void*)s.first); - return pair(this,s.second ? s.second : m_htaccess); + return pair(this,s.second ? s.second : m_htaccess); } pair ApacheRequestMapper::getBool(const char* name, const char* ns) const { ShibTargetApache* sta=reinterpret_cast(m_staKey->getData()); - const IPropertySet* s=reinterpret_cast(m_propsKey->getData()); + const PropertySet* s=reinterpret_cast(m_propsKey->getData()); if (sta && !ns) { // Override Apache-settable boolean properties. if (name && !strcmp(name,"requireSession") && sta->m_dc->bRequireSession==1) @@ -544,7 +544,7 @@ pair ApacheRequestMapper::getBool(const char* name, const char* ns) c pair ApacheRequestMapper::getString(const char* name, const char* ns) const { ShibTargetApache* sta=reinterpret_cast(m_staKey->getData()); - const IPropertySet* s=reinterpret_cast(m_propsKey->getData()); + const PropertySet* s=reinterpret_cast(m_propsKey->getData()); if (sta && !ns) { // Override Apache-settable string properties. if (name && !strcmp(name,"authType")) { @@ -568,14 +568,14 @@ pair ApacheRequestMapper::getString(const char* name, const ch pair ApacheRequestMapper::getXMLString(const char* name, const char* ns) const { - const IPropertySet* s=reinterpret_cast(m_propsKey->getData()); + const PropertySet* s=reinterpret_cast(m_propsKey->getData()); return s ? s->getXMLString(name,ns) : pair(false,NULL); } pair ApacheRequestMapper::getUnsignedInt(const char* name, const char* ns) const { ShibTargetApache* sta=reinterpret_cast(m_staKey->getData()); - const IPropertySet* s=reinterpret_cast(m_propsKey->getData()); + const PropertySet* s=reinterpret_cast(m_propsKey->getData()); if (sta && !ns) { // Override Apache-settable int properties. if (name && !strcmp(name,"redirectToSSL") && sta->m_dc->szRedirectToSSL) @@ -587,7 +587,7 @@ pair ApacheRequestMapper::getUnsignedInt(const char* name, co pair ApacheRequestMapper::getInt(const char* name, const char* ns) const { ShibTargetApache* sta=reinterpret_cast(m_staKey->getData()); - const IPropertySet* s=reinterpret_cast(m_propsKey->getData()); + const PropertySet* s=reinterpret_cast(m_propsKey->getData()); if (sta && !ns) { // Override Apache-settable int properties. if (name && !strcmp(name,"redirectToSSL") && sta->m_dc->szRedirectToSSL) @@ -596,15 +596,15 @@ pair ApacheRequestMapper::getInt(const char* name, const char* ns) con return s ? s->getInt(name,ns) : pair(false,0); } -const IPropertySet* ApacheRequestMapper::getPropertySet(const char* name, const char* ns) const +const PropertySet* ApacheRequestMapper::getPropertySet(const char* name, const char* ns) const { - const IPropertySet* s=reinterpret_cast(m_propsKey->getData()); + const PropertySet* s=reinterpret_cast(m_propsKey->getData()); return s ? s->getPropertySet(name,ns) : NULL; } const DOMElement* ApacheRequestMapper::getElement() const { - const IPropertySet* s=reinterpret_cast(m_propsKey->getData()); + const PropertySet* s=reinterpret_cast(m_propsKey->getData()); return s ? s->getElement() : NULL; } @@ -956,7 +956,7 @@ extern "C" void shib_child_init(apr_pool_t* p, server_rec* s) IConfig* conf=g_Config->getINI(); Locker locker(conf); - const IPropertySet* props=conf->getPropertySet("Local"); + const PropertySet* props=conf->getPropertySet("Local"); if (props) { pair unsetValue=props->getString("unsetHeaderValue"); if (unsetValue.first) diff --git a/isapi_shib/isapi_shib.cpp b/isapi_shib/isapi_shib.cpp index 74684b6..0a36bb8 100644 --- a/isapi_shib/isapi_shib.cpp +++ b/isapi_shib/isapi_shib.cpp @@ -181,7 +181,7 @@ extern "C" BOOL WINAPI GetFilterVersion(PHTTP_FILTER_VERSION pVer) // Access the implementation-specifics for site mappings. IConfig* conf=g_Config->getINI(); Locker locker(conf); - const IPropertySet* props=conf->getPropertySet("Local"); + const PropertySet* props=conf->getPropertySet("Local"); if (props) { const DOMElement* impl=saml::XML::getFirstChildElement( props->getElement(),shibtarget::XML::SHIBTARGET_NS,Implementation diff --git a/nsapi_shib/nsapi_shib.cpp b/nsapi_shib/nsapi_shib.cpp index aa0ff5a..6a72c0b 100644 --- a/nsapi_shib/nsapi_shib.cpp +++ b/nsapi_shib/nsapi_shib.cpp @@ -393,7 +393,7 @@ extern "C" NSAPI_PUBLIC int shib_handler(pblock* pb, Session* sn, Request* rq) } -class SunRequestMapper : public virtual IRequestMapper, public virtual IPropertySet +class SunRequestMapper : public virtual IRequestMapper, public virtual PropertySet { public: SunRequestMapper(const DOMElement* e); @@ -407,7 +407,7 @@ public: pair getXMLString(const char* name, const char* ns=NULL) const; pair getUnsignedInt(const char* name, const char* ns=NULL) const; pair getInt(const char* name, const char* ns=NULL) const; - const IPropertySet* getPropertySet(const char* name, const char* ns="urn:mace:shibboleth:target:config:1.0") const; + const PropertySet* getPropertySet(const char* name, const char* ns="urn:mace:shibboleth:target:config:1.0") const; const DOMElement* getElement() const; private: @@ -438,13 +438,13 @@ IRequestMapper::Settings SunRequestMapper::getSettings(ShibTarget* st) const Settings s=m_mapper->getSettings(st); m_stKey->setData(dynamic_cast(st)); m_propsKey->setData((void*)s.first); - return pair(this,s.second); + return pair(this,s.second); } pair SunRequestMapper::getBool(const char* name, const char* ns) const { ShibTargetNSAPI* stn=reinterpret_cast(m_stKey->getData()); - const IPropertySet* s=reinterpret_cast(m_propsKey->getData()); + const PropertySet* s=reinterpret_cast(m_propsKey->getData()); if (stn && !ns && name) { // Override boolean properties. const char* param=pblock_findval(name,stn->m_pb); @@ -457,7 +457,7 @@ pair SunRequestMapper::getBool(const char* name, const char* ns) cons pair SunRequestMapper::getString(const char* name, const char* ns) const { ShibTargetNSAPI* stn=reinterpret_cast(m_stKey->getData()); - const IPropertySet* s=reinterpret_cast(m_propsKey->getData()); + const PropertySet* s=reinterpret_cast(m_propsKey->getData()); if (stn && !ns && name) { // Override string properties. if (!strcmp(name,"authType")) @@ -473,14 +473,14 @@ pair SunRequestMapper::getString(const char* name, const char* pair SunRequestMapper::getXMLString(const char* name, const char* ns) const { - const IPropertySet* s=reinterpret_cast(m_propsKey->getData()); + const PropertySet* s=reinterpret_cast(m_propsKey->getData()); return s ? s->getXMLString(name,ns) : pair(false,NULL); } pair SunRequestMapper::getUnsignedInt(const char* name, const char* ns) const { ShibTargetNSAPI* stn=reinterpret_cast(m_stKey->getData()); - const IPropertySet* s=reinterpret_cast(m_propsKey->getData()); + const PropertySet* s=reinterpret_cast(m_propsKey->getData()); if (stn && !ns && name) { // Override int properties. const char* param=pblock_findval(name,stn->m_pb); @@ -493,7 +493,7 @@ pair SunRequestMapper::getUnsignedInt(const char* name, const pair SunRequestMapper::getInt(const char* name, const char* ns) const { ShibTargetNSAPI* stn=reinterpret_cast(m_stKey->getData()); - const IPropertySet* s=reinterpret_cast(m_propsKey->getData()); + const PropertySet* s=reinterpret_cast(m_propsKey->getData()); if (stn && !ns && name) { // Override int properties. const char* param=pblock_findval(name,stn->m_pb); @@ -503,14 +503,14 @@ pair SunRequestMapper::getInt(const char* name, const char* ns) const return s ? s->getInt(name,ns) : pair(false,0); } -const IPropertySet* SunRequestMapper::getPropertySet(const char* name, const char* ns) const +const PropertySet* SunRequestMapper::getPropertySet(const char* name, const char* ns) const { - const IPropertySet* s=reinterpret_cast(m_propsKey->getData()); + const PropertySet* s=reinterpret_cast(m_propsKey->getData()); return s ? s->getPropertySet(name,ns) : NULL; } const DOMElement* SunRequestMapper::getElement() const { - const IPropertySet* s=reinterpret_cast(m_propsKey->getData()); + const PropertySet* s=reinterpret_cast(m_propsKey->getData()); return s ? s->getElement() : NULL; } diff --git a/shib-target/ArtifactMapper.cpp b/shib-target/ArtifactMapper.cpp index 6f3f22f..02e1b06 100644 --- a/shib-target/ArtifactMapper.cpp +++ b/shib-target/ArtifactMapper.cpp @@ -24,11 +24,12 @@ #include "internal.h" -using namespace std; -using namespace log4cpp; -using namespace saml; -using namespace shibboleth; +using namespace shibsp; using namespace shibtarget; +using namespace shibboleth; +using namespace saml; +using namespace log4cpp; +using namespace std; SAMLResponse* STArtifactMapper::resolve(SAMLRequest* request) { @@ -50,7 +51,7 @@ SAMLResponse* STArtifactMapper::resolve(SAMLRequest* request) log.info("lookup succeeded, artifact issued by (%s)", issuer.get()); // Sign it? - const IPropertySet* credUse=m_app->getCredentialUse(entity); + const PropertySet* credUse=m_app->getCredentialUse(entity); pair signRequest=credUse ? credUse->getBool("signRequest") : make_pair(false,false); pair signatureAlg=credUse ? credUse->getString("signatureAlg") : pair(false,NULL); if (!signatureAlg.first) diff --git a/shib-target/ShibHTTPHook.cpp b/shib-target/ShibHTTPHook.cpp index 5857f0a..47318f6 100644 --- a/shib-target/ShibHTTPHook.cpp +++ b/shib-target/ShibHTTPHook.cpp @@ -28,11 +28,12 @@ #include #include -using namespace std; -using namespace log4cpp; +using namespace shibsp; using namespace shibtarget; using namespace shibboleth; using namespace saml; +using namespace log4cpp; +using namespace std; /* * Our verifier callback is a front-end for invoking each trust plugin until @@ -84,7 +85,7 @@ static bool ssl_ctx_callback(void* ssl_ctx, void* userptr) try { log.debug("OpenSAML invoked SSL context callback"); ShibHTTPHook::ShibHTTPHookCallContext* ctx = reinterpret_cast(userptr); - const IPropertySet* credUse=ctx->getCredentialUse(); + const PropertySet* credUse=ctx->getCredentialUse(); pair TLS=credUse ? credUse->getString("TLS") : pair(false,NULL); if (TLS.first) { Credentials c(ctx->getHook()->getCredentialProviders()); @@ -155,7 +156,7 @@ bool ShibHTTPHook::outgoing(HTTPClient* conn, void* globalCtx, void* callCtx) return false; // Check for HTTP authentication... - const IPropertySet* credUse=reinterpret_cast(callCtx)->getCredentialUse(); + const PropertySet* credUse=reinterpret_cast(callCtx)->getCredentialUse(); pair authType=credUse ? credUse->getString("authType") : pair(false,NULL); if (authType.first) { #ifdef _DEBUG diff --git a/shib-target/XMLRequestMapper.cpp b/shib-target/XMLRequestMapper.cpp index c12fa29..b59bd4b 100644 --- a/shib-target/XMLRequestMapper.cpp +++ b/shib-target/XMLRequestMapper.cpp @@ -26,29 +26,31 @@ #include #include +#include -using namespace std; -using namespace log4cpp; -using namespace saml; -using namespace shibboleth; +using namespace shibsp; using namespace shibtarget; +using namespace shibboleth; +using namespace saml; +using namespace log4cpp; +using namespace std; namespace shibtarget { - class Override : public XMLPropertySet, public DOMNodeFilter + class Override : public DOMPropertySet, public DOMNodeFilter { public: Override() : m_base(NULL), m_acl(NULL) {} Override(const DOMElement* e, Category& log, const Override* base=NULL); ~Override(); - // IPropertySet + // PropertySet pair getBool(const char* name, const char* ns=NULL) const; pair getString(const char* name, const char* ns=NULL) const; pair getXMLString(const char* name, const char* ns=NULL) const; pair getUnsignedInt(const char* name, const char* ns=NULL) const; pair getInt(const char* name, const char* ns=NULL) const; - const IPropertySet* getPropertySet(const char* name, const char* ns="urn:mace:shibboleth:target:config:1.0") const; + const PropertySet* getPropertySet(const char* name, const char* ns="urn:mace:shibboleth:target:config:1.0") const; // Provides filter to exclude special config elements. short acceptNode(const DOMNode* node) const; @@ -247,7 +249,7 @@ Override::~Override() pair Override::getBool(const char* name, const char* ns) const { - pair ret=XMLPropertySet::getBool(name,ns); + pair ret=DOMPropertySet::getBool(name,ns); if (ret.first) return ret; return m_base ? m_base->getBool(name,ns) : ret; @@ -255,7 +257,7 @@ pair Override::getBool(const char* name, const char* ns) const pair Override::getString(const char* name, const char* ns) const { - pair ret=XMLPropertySet::getString(name,ns); + pair ret=DOMPropertySet::getString(name,ns); if (ret.first) return ret; return m_base ? m_base->getString(name,ns) : ret; @@ -263,7 +265,7 @@ pair Override::getString(const char* name, const char* ns) con pair Override::getXMLString(const char* name, const char* ns) const { - pair ret=XMLPropertySet::getXMLString(name,ns); + pair ret=DOMPropertySet::getXMLString(name,ns); if (ret.first) return ret; return m_base ? m_base->getXMLString(name,ns) : ret; @@ -271,7 +273,7 @@ pair Override::getXMLString(const char* name, const char* ns) pair Override::getUnsignedInt(const char* name, const char* ns) const { - pair ret=XMLPropertySet::getUnsignedInt(name,ns); + pair ret=DOMPropertySet::getUnsignedInt(name,ns); if (ret.first) return ret; return m_base ? m_base->getUnsignedInt(name,ns) : ret; @@ -279,15 +281,15 @@ pair Override::getUnsignedInt(const char* name, const char* n pair Override::getInt(const char* name, const char* ns) const { - pair ret=XMLPropertySet::getInt(name,ns); + pair ret=DOMPropertySet::getInt(name,ns); if (ret.first) return ret; return m_base ? m_base->getInt(name,ns) : ret; } -const IPropertySet* Override::getPropertySet(const char* name, const char* ns) const +const PropertySet* Override::getPropertySet(const char* name, const char* ns) const { - const IPropertySet* ret=XMLPropertySet::getPropertySet(name,ns); + const PropertySet* ret=DOMPropertySet::getPropertySet(name,ns); if (ret || !m_base) return ret; return m_base->getPropertySet(name,ns); @@ -508,7 +510,7 @@ IRequestMapper::Settings XMLRequestMapper::getSettings(ShibTarget* st) const if (impl->log->isDebugEnabled()) { #ifdef _DEBUG - saml::NDC ndc("getSettings"); + NDC ndc("getSettings"); #endif pair ret=o->getString("applicationId"); impl->log->debug("mapped %s%s to %s", vhost.str().c_str(), st->getRequestURI() ? st->getRequestURI() : "", ret.second); diff --git a/shib-target/internal.h b/shib-target/internal.h index e68ed96..d2fe324 100644 --- a/shib-target/internal.h +++ b/shib-target/internal.h @@ -50,42 +50,6 @@ #define SHIBTRAN_LOGCAT "Shibboleth-TRANSACTION" namespace shibtarget { - // Generic class, which handles the IPropertySet configuration interface. - // Most of the basic configuration details are exposed via this interface. - // This implementation extracts the XML tree structure and caches it in a map - // with the attributes stored in the various possible formats they might be fetched. - // Elements are treated as nested IPropertySets. - // The "trick" to this is to pass in an "exclude list" using a DOMNodeFilter. Nested - // property sets are extracted by running a TreeWalker againt the filter for the - // immediate children. The filter should skip any excluded elements that will be - // processed separately. - class XMLPropertySet : public virtual IPropertySet - { - public: - XMLPropertySet() {} - ~XMLPropertySet(); - - std::pair getBool(const char* name, const char* ns=NULL) const; - std::pair getString(const char* name, const char* ns=NULL) const; - std::pair getXMLString(const char* name, const char* ns=NULL) const; - std::pair getUnsignedInt(const char* name, const char* ns=NULL) const; - std::pair getInt(const char* name, const char* ns=NULL) const; - const IPropertySet* getPropertySet(const char* name, const char* ns="urn:mace:shibboleth:target:config:1.0") const; - const DOMElement* getElement() const {return m_root;} - - void load( - const DOMElement* e, // root element of property set - log4cpp::Category& log, // log object for tracing - DOMNodeFilter* filter, // control what subelements to include - const std::map* remapper=NULL // on the fly property renaming for legacy support - ); - - private: - const DOMElement* m_root; - std::map > m_map; - std::map m_nested; - }; - // ST-aware class that maps SAML artifacts to appropriate binding information class STArtifactMapper : public virtual saml::SAMLBrowserProfile::ArtifactMapper { diff --git a/shib-target/shib-ccache.cpp b/shib-target/shib-ccache.cpp index fdf6e66..c58fd78 100644 --- a/shib-target/shib-ccache.cpp +++ b/shib-target/shib-ccache.cpp @@ -534,7 +534,7 @@ HRESULT MemorySessionCacheEntry::isValid(const IApplication* app, const char* cl // Obtain validation rules from application settings. bool consistentIPAddress=true; int lifetime=0,timeout=0; - const IPropertySet* props=app->getPropertySet("Sessions"); + const PropertySet* props=app->getPropertySet("Sessions"); if (props) { pair p=props->getUnsignedInt("lifetime"); if (p.first) @@ -817,7 +817,7 @@ pair MemorySessionCacheEntry::getNewResponse( } // Get protocol signing policy. - const IPropertySet* credUse=application->getCredentialUse(source); + const PropertySet* credUse=application->getCredentialUse(source); pair signRequest=credUse ? credUse->getBool("signRequest") : make_pair(false,false); pair signatureAlg=credUse ? credUse->getString("signatureAlg") : pair(false,NULL); if (!signatureAlg.first) diff --git a/shib-target/shib-handlers.cpp b/shib-target/shib-handlers.cpp index 1fcac10..c717d07 100644 --- a/shib-target/shib-handlers.cpp +++ b/shib-target/shib-handlers.cpp @@ -308,7 +308,7 @@ DDF SAML1Consumer::receive(const DDF& in) pair checkAddress=pair(false,true); pair checkReplay=pair(false,true); - const IPropertySet* props=app->getPropertySet("Sessions"); + const PropertySet* props=app->getPropertySet("Sessions"); if (props) { checkAddress=props->getBool("checkAddress"); if (!checkAddress.first) @@ -556,7 +556,7 @@ pair SAML1Consumer::run(ShibTarget* st, bool isHandler) const const char* providerId=out["provider_id"].string(); if (providerId) { - const IPropertySet* sessionProps=st->getApplication()->getPropertySet("Sessions"); + const PropertySet* sessionProps=st->getApplication()->getPropertySet("Sessions"); pair idpHistory=sessionProps->getBool("idpHistory"); if (!idpHistory.first || idpHistory.second) { // Set an IdP history cookie locally (essentially just a CDC). diff --git a/shib-target/shib-ini.cpp b/shib-target/shib-ini.cpp index 4ca58d8..f20bf92 100644 --- a/shib-target/shib-ini.cpp +++ b/shib-target/shib-ini.cpp @@ -22,6 +22,7 @@ #include "internal.h" +#include #include #include #include @@ -39,19 +40,19 @@ using namespace std; namespace shibtarget { // Application configuration wrapper - class XMLApplication : public virtual IApplication, public XMLPropertySet, public DOMNodeFilter + class XMLApplication : public virtual IApplication, public DOMPropertySet, public DOMNodeFilter { public: XMLApplication(const IConfig*, const Iterator& creds, const DOMElement* e, const XMLApplication* base=NULL); ~XMLApplication() { cleanup(); } - // IPropertySet + // PropertySet pair getBool(const char* name, const char* ns=NULL) const; pair getString(const char* name, const char* ns=NULL) const; pair getXMLString(const char* name, const char* ns=NULL) const; pair getUnsignedInt(const char* name, const char* ns=NULL) const; pair getInt(const char* name, const char* ns=NULL) const; - const IPropertySet* getPropertySet(const char* name, const char* ns="urn:mace:shibboleth:target:config:1.0") const; + const PropertySet* getPropertySet(const char* name, const char* ns="urn:mace:shibboleth:target:config:1.0") const; // IApplication const char* getId() const {return getString("id").second;} @@ -61,7 +62,7 @@ namespace shibtarget { Iterator getMetadataProviders() const; Iterator getTrustProviders() const; Iterator getAudiences() const; - const IPropertySet* getCredentialUse(const IEntityDescriptor* provider) const; + const PropertySet* getCredentialUse(const IEntityDescriptor* provider) const; const SAMLBrowserProfile* getBrowserProfile() const {return m_profile;} const SAMLBinding* getBinding(const XMLCh* binding) const {return XMLString::compareString(SAMLBinding::SOAP,binding) ? NULL : m_binding;} @@ -98,7 +99,7 @@ namespace shibtarget { // vectors manage object life for handlers and their property sets vector m_handlers; - vector m_handlerProps; + vector m_handlerProps; // maps location (path info) to applicable handlers map m_handlerMap; @@ -123,17 +124,17 @@ namespace shibtarget { // pointer to default session initiator const IHandler* m_sessionInitDefault; - XMLPropertySet* m_credDefault; + DOMPropertySet* m_credDefault; #ifdef HAVE_GOOD_STL - map m_credMap; + map m_credMap; #else - map m_credMap; + map m_credMap; #endif }; // Top-level configuration implementation class XMLConfig; - class XMLConfigImpl : public ReloadableXMLFileImpl, public XMLPropertySet, public DOMNodeFilter + class XMLConfigImpl : public ReloadableXMLFileImpl, public DOMPropertySet, public DOMNodeFilter { public: XMLConfigImpl(const char* pathname, bool first, const XMLConfig* outer) @@ -172,13 +173,13 @@ namespace shibtarget { void init() { getImplementation(); } - // IPropertySet + // PropertySet pair getBool(const char* name, const char* ns=NULL) const {return static_cast(m_impl)->getBool(name,ns);} pair getString(const char* name, const char* ns=NULL) const {return static_cast(m_impl)->getString(name,ns);} pair getXMLString(const char* name, const char* ns=NULL) const {return static_cast(m_impl)->getXMLString(name,ns);} pair getUnsignedInt(const char* name, const char* ns=NULL) const {return static_cast(m_impl)->getUnsignedInt(name,ns);} pair getInt(const char* name, const char* ns=NULL) const {return static_cast(m_impl)->getInt(name,ns);} - const IPropertySet* getPropertySet(const char* name, const char* ns="urn:mace:shibboleth:target:config:1.0") const {return static_cast(m_impl)->getPropertySet(name,ns);} + const PropertySet* getPropertySet(const char* name, const char* ns="urn:mace:shibboleth:target:config:1.0") const {return static_cast(m_impl)->getPropertySet(name,ns);} const DOMElement* getElement() const {return static_cast(m_impl)->getElement();} // IConfig @@ -209,186 +210,6 @@ IConfig* STConfig::ShibTargetConfigFactory(const DOMElement* e) return new XMLConfig(e); } -XMLPropertySet::~XMLPropertySet() -{ - for (map >::iterator i=m_map.begin(); i!=m_map.end(); i++) - XMLString::release(&(i->second.first)); - for_each(m_nested.begin(),m_nested.end(),xmltooling::cleanup_pair()); -} - -void XMLPropertySet::load( - const DOMElement* e, - Category& log, - DOMNodeFilter* filter, - const std::map* remapper - ) -{ -#ifdef _DEBUG - saml::NDC ndc("load"); -#endif - m_root=e; - - // Process each attribute as a property. - DOMNamedNodeMap* attrs=m_root->getAttributes(); - for (XMLSize_t i=0; igetLength(); i++) { - DOMNode* a=attrs->item(i); - if (!XMLString::compareString(a->getNamespaceURI(),saml::XML::XMLNS_NS)) - continue; - char* val=XMLString::transcode(a->getNodeValue()); - if (val && *val) { - auto_ptr_char ns(a->getNamespaceURI()); - auto_ptr_char name(a->getLocalName()); - const char* realname=name.get(); - if (remapper) { - map::const_iterator remap=remapper->find(realname); - if (remap!=remapper->end()) { - log.warn("remapping property (%s) to (%s)",realname,remap->second.c_str()); - realname=remap->second.c_str(); - } - } - if (ns.get()) { - m_map[string("{") + ns.get() + '}' + realname]=pair(val,a->getNodeValue()); - log.debug("added property {%s}%s (%s)",ns.get(),realname,val); - } - else { - m_map[realname]=pair(val,a->getNodeValue()); - log.debug("added property %s (%s)",realname,val); - } - } - } - - // Process non-excluded elements as nested sets. - DOMTreeWalker* walker= - static_cast( - m_root->getOwnerDocument())->createTreeWalker(const_cast(m_root),DOMNodeFilter::SHOW_ELEMENT,filter,false - ); - e=static_cast(walker->firstChild()); - while (e) { - auto_ptr_char ns(e->getNamespaceURI()); - auto_ptr_char name(e->getLocalName()); - const char* realname=name.get(); - if (remapper) { - map::const_iterator remap=remapper->find(realname); - if (remap!=remapper->end()) { - log.warn("remapping property set (%s) to (%s)",realname,remap->second.c_str()); - realname=remap->second.c_str(); - } - } - string key; - if (ns.get()) - key=string("{") + ns.get() + '}' + realname; - else - key=realname; - if (m_nested.find(key)!=m_nested.end()) - log.warn("load() skipping duplicate property set: %s",key.c_str()); - else { - XMLPropertySet* set=new XMLPropertySet(); - set->load(e,log,filter,remapper); - m_nested[key]=set; - log.debug("added nested property set: %s",key.c_str()); - } - e=static_cast(walker->nextSibling()); - } - walker->release(); -} - -pair XMLPropertySet::getBool(const char* name, const char* ns) const -{ - pair ret(false,false); - map >::const_iterator i; - - if (ns) - i=m_map.find(string("{") + ns + '}' + name); - else - i=m_map.find(name); - - if (i!=m_map.end()) { - ret.first=true; - ret.second=(!strcmp(i->second.first,"true") || !strcmp(i->second.first,"1")); - } - return ret; -} - -pair XMLPropertySet::getString(const char* name, const char* ns) const -{ - pair ret(false,NULL); - map >::const_iterator i; - - if (ns) - i=m_map.find(string("{") + ns + '}' + name); - else - i=m_map.find(name); - - if (i!=m_map.end()) { - ret.first=true; - ret.second=i->second.first; - } - return ret; -} - -pair XMLPropertySet::getXMLString(const char* name, const char* ns) const -{ - pair ret(false,NULL); - map >::const_iterator i; - - if (ns) - i=m_map.find(string("{") + ns + '}' + name); - else - i=m_map.find(name); - - if (i!=m_map.end()) { - ret.first=true; - ret.second=i->second.second; - } - return ret; -} - -pair XMLPropertySet::getUnsignedInt(const char* name, const char* ns) const -{ - pair ret(false,0); - map >::const_iterator i; - - if (ns) - i=m_map.find(string("{") + ns + '}' + name); - else - i=m_map.find(name); - - if (i!=m_map.end()) { - ret.first=true; - ret.second=strtol(i->second.first,NULL,10); - } - return ret; -} - -pair XMLPropertySet::getInt(const char* name, const char* ns) const -{ - pair ret(false,0); - map >::const_iterator i; - - if (ns) - i=m_map.find(string("{") + ns + '}' + name); - else - i=m_map.find(name); - - if (i!=m_map.end()) { - ret.first=true; - ret.second=atoi(i->second.first); - } - return ret; -} - -const IPropertySet* XMLPropertySet::getPropertySet(const char* name, const char* ns) const -{ - map::const_iterator i; - - if (ns) - i=m_nested.find(string("{") + ns + '}' + name); - else - i=m_nested.find(name); - - return (i!=m_nested.end()) ? i->second : NULL; -} - XMLApplication::XMLApplication( const IConfig* ini, const Iterator& creds, @@ -398,7 +219,7 @@ XMLApplication::XMLApplication( m_credDefault(NULL), m_sessionInitDefault(NULL), m_acsDefault(NULL) { #ifdef _DEBUG - saml::NDC ndc("XMLApplication"); + NDC ndc("XMLApplication"); #endif Category& log=Category::getInstance("shibtarget.XMLApplication"); @@ -409,7 +230,7 @@ XMLApplication::XMLApplication( root_remap["shireURL"]="handlerURL"; root_remap["shireSSL"]="handlerSSL"; load(e,log,this,&root_remap); - const IPropertySet* propcheck=getPropertySet("Errors"); + const PropertySet* propcheck=getPropertySet("Errors"); if (propcheck && !propcheck->getString("session").first) throw ConfigurationException(" element requires 'session' (or deprecated 'shire') attribute"); propcheck=getPropertySet("Sessions"); @@ -430,7 +251,7 @@ XMLApplication::XMLApplication( // A handler is split across a property set and the plugin itself, which is based on the Binding property. // We build both objects first and then insert them into various structures for lookup. IHandler* hobj=NULL; - XMLPropertySet* hprops=new XMLPropertySet(); + DOMPropertySet* hprops=new DOMPropertySet(); try { hprops->load(handler,log,this); // filter irrelevant for now, no embedded elements expected const char* bindprop=hprops->getString("Binding").second; @@ -519,7 +340,7 @@ XMLApplication::XMLApplication( // If no handlers defined at the root, assume a legacy configuration. if (!m_base && m_handlers.empty()) { // A legacy config installs a SAML POST handler at the root handler location. - // We use the Sessions element itself as the IPropertySet. + // We use the Sessions element itself as the PropertySet. auto_ptr_char b1(Constants::SHIB_SESSIONINIT_PROFILE_URI); IPlugIn* hplug=shibConf.getPlugMgr().newPlugin(b1.get(),propcheck->getElement()); @@ -656,11 +477,11 @@ XMLApplication::XMLApplication( // Finally, load credential mappings. const DOMElement* cu=saml::XML::getFirstChildElement(e,shibtarget::XML::SHIBTARGET_NS,SHIBT_L(CredentialUse)); if (cu) { - m_credDefault=new XMLPropertySet(); + m_credDefault=new DOMPropertySet(); m_credDefault->load(cu,log,this); cu=saml::XML::getFirstChildElement(cu,shibtarget::XML::SHIBTARGET_NS,SHIBT_L(RelyingParty)); while (cu) { - XMLPropertySet* rp=new XMLPropertySet(); + DOMPropertySet* rp=new DOMPropertySet(); rp->load(cu,log,this); m_credMap[cu->getAttributeNS(NULL,SHIBT_L(Name))]=rp; cu=saml::XML::getNextSiblingElement(cu,shibtarget::XML::SHIBTARGET_NS,SHIBT_L(RelyingParty)); @@ -710,9 +531,9 @@ void XMLApplication::cleanup() delete m_credDefault; #ifdef HAVE_GOOD_STL - for_each(m_credMap.begin(),m_credMap.end(),xmltooling::cleanup_pair()); + for_each(m_credMap.begin(),m_credMap.end(),xmltooling::cleanup_pair()); #else - for_each(m_credMap.begin(),m_credMap.end(),xmltooling::cleanup_pair()); + for_each(m_credMap.begin(),m_credMap.end(),xmltooling::cleanup_pair()); #endif for_each(m_designators.begin(),m_designators.end(),xmltooling::cleanup()); for_each(m_aaps.begin(),m_aaps.end(),xmltooling::cleanup()); @@ -745,7 +566,7 @@ short XMLApplication::acceptNode(const DOMNode* node) const pair XMLApplication::getBool(const char* name, const char* ns) const { - pair ret=XMLPropertySet::getBool(name,ns); + pair ret=DOMPropertySet::getBool(name,ns); if (ret.first) return ret; return m_base ? m_base->getBool(name,ns) : ret; @@ -753,7 +574,7 @@ pair XMLApplication::getBool(const char* name, const char* ns) const pair XMLApplication::getString(const char* name, const char* ns) const { - pair ret=XMLPropertySet::getString(name,ns); + pair ret=DOMPropertySet::getString(name,ns); if (ret.first) return ret; return m_base ? m_base->getString(name,ns) : ret; @@ -761,7 +582,7 @@ pair XMLApplication::getString(const char* name, const char* n pair XMLApplication::getXMLString(const char* name, const char* ns) const { - pair ret=XMLPropertySet::getXMLString(name,ns); + pair ret=DOMPropertySet::getXMLString(name,ns); if (ret.first) return ret; return m_base ? m_base->getXMLString(name,ns) : ret; @@ -769,7 +590,7 @@ pair XMLApplication::getXMLString(const char* name, const cha pair XMLApplication::getUnsignedInt(const char* name, const char* ns) const { - pair ret=XMLPropertySet::getUnsignedInt(name,ns); + pair ret=DOMPropertySet::getUnsignedInt(name,ns); if (ret.first) return ret; return m_base ? m_base->getUnsignedInt(name,ns) : ret; @@ -777,15 +598,15 @@ pair XMLApplication::getUnsignedInt(const char* name, const c pair XMLApplication::getInt(const char* name, const char* ns) const { - pair ret=XMLPropertySet::getInt(name,ns); + pair ret=DOMPropertySet::getInt(name,ns); if (ret.first) return ret; return m_base ? m_base->getInt(name,ns) : ret; } -const IPropertySet* XMLApplication::getPropertySet(const char* name, const char* ns) const +const PropertySet* XMLApplication::getPropertySet(const char* name, const char* ns) const { - const IPropertySet* ret=XMLPropertySet::getPropertySet(name,ns); + const PropertySet* ret=DOMPropertySet::getPropertySet(name,ns); if (ret || !m_base) return ret; return m_base->getPropertySet(name,ns); @@ -818,13 +639,13 @@ Iterator XMLApplication::getAudiences() const return (m_audiences.empty() && m_base) ? m_base->getAudiences() : m_audiences; } -const IPropertySet* XMLApplication::getCredentialUse(const IEntityDescriptor* provider) const +const PropertySet* XMLApplication::getCredentialUse(const IEntityDescriptor* provider) const { if (!m_credDefault && m_base) return m_base->getCredentialUse(provider); #ifdef HAVE_GOOD_STL - map::const_iterator i=m_credMap.find(provider->getId()); + map::const_iterator i=m_credMap.find(provider->getId()); if (i!=m_credMap.end()) return i->second; const IEntitiesDescriptor* group=provider->getEntitiesDescriptor(); @@ -837,7 +658,7 @@ const IPropertySet* XMLApplication::getCredentialUse(const IEntityDescriptor* pr group=group->getEntitiesDescriptor(); } #else - map::const_iterator i=m_credMap.begin(); + map::const_iterator i=m_credMap.begin(); for (; i!=m_credMap.end(); i++) { if (!XMLString::compareString(i->first,provider->getId())) return i->second; @@ -894,7 +715,7 @@ void XMLApplication::validateToken(SAMLAssertion* token, time_t ts, const IRoleD return; } - const IPropertySet* credUse=getCredentialUse(role->getEntityDescriptor()); + const PropertySet* credUse=getCredentialUse(role->getEntityDescriptor()); pair signedAssertions=credUse ? credUse->getBool("signedAssertions") : make_pair(false,false); Trust t(trusts); diff --git a/shib-target/shib-target.cpp b/shib-target/shib-target.cpp index daacdad..f39af98 100644 --- a/shib-target/shib-target.cpp +++ b/shib-target/shib-target.cpp @@ -50,6 +50,7 @@ using namespace saml; using namespace log4cpp; using namespace std; +using shibsp::PropertySet; using xmltooling::TemplateEngine; using xmltooling::XMLToolingException; using xmltooling::XMLToolingConfig; @@ -74,12 +75,12 @@ namespace shibtarget { class ExtTemplateParameters : public TemplateEngine::TemplateParameters { - const IPropertySet* m_props; + const PropertySet* m_props; public: ExtTemplateParameters() : m_props(NULL) {} ~ExtTemplateParameters() {} - void setPropertySet(const IPropertySet* props) { + void setPropertySet(const PropertySet* props) { m_props = props; // Create a timestamp. @@ -373,7 +374,7 @@ pair ShibTarget::doHandler(void) if (!strstr(targetURL,handlerURL)) return make_pair(true, returnDecline()); - const IPropertySet* sessionProps=m_priv->m_app->getPropertySet("Sessions"); + const PropertySet* sessionProps=m_priv->m_app->getPropertySet("Sessions"); if (!sessionProps) throw ConfigurationException("Unable to map request to application session settings, check configuration."); @@ -411,7 +412,7 @@ pair ShibTarget::doHandler(void) catch (MetadataException& e) { tp.m_map["errorText"] = e.what(); // See if a metadata error page is installed. - const IPropertySet* props=m_priv->m_app->getPropertySet("Errors"); + const PropertySet* props=m_priv->m_app->getPropertySet("Errors"); if (props) { pair p=props->getString("metadata"); if (p.first) { @@ -758,7 +759,7 @@ pair ShibTarget::getCookieNameProps(const char* prefix) cons { static const char* defProps="; path=/"; - const IPropertySet* props=m_priv->m_app ? m_priv->m_app->getPropertySet("Sessions") : NULL; + const PropertySet* props=m_priv->m_app ? m_priv->m_app->getPropertySet("Sessions") : NULL; if (props) { pair p=props->getString("cookieProps"); if (!p.first) @@ -783,7 +784,7 @@ string ShibTarget::getHandlerURL(const char* resource) const bool ssl_only=false; const char* handler=NULL; - const IPropertySet* props=m_priv->m_app->getPropertySet("Sessions"); + const PropertySet* props=m_priv->m_app->getPropertySet("Sessions"); if (props) { pair p=props->getBool("handlerSSL"); if (p.first) @@ -962,7 +963,7 @@ void* ShibTargetPriv::sendError( }; TemplateEngine* engine = XMLToolingConfig::getConfig().getTemplateEngine(); - const IPropertySet* props=m_app->getPropertySet("Errors"); + const PropertySet* props=m_app->getPropertySet("Errors"); if (props) { pair p=props->getString(page); if (p.first) { diff --git a/shib-target/shib-target.h b/shib-target/shib-target.h index 08e1e1c..c1c9fa4 100644 --- a/shib-target/shib-target.h +++ b/shib-target/shib-target.h @@ -28,6 +28,7 @@ // New headers #include #include +#include // Old headers #include @@ -51,22 +52,6 @@ namespace shibtarget { // Abstract APIs for access to configuration information - /** - * Interface to a generic set of typed properties or a DOM container of additional - * data. - */ - struct SHIBTARGET_EXPORTS IPropertySet - { - virtual std::pair getBool(const char* name, const char* ns=NULL) const=0; - virtual std::pair getString(const char* name, const char* ns=NULL) const=0; - virtual std::pair getXMLString(const char* name, const char* ns=NULL) const=0; - virtual std::pair getUnsignedInt(const char* name, const char* ns=NULL) const=0; - virtual std::pair getInt(const char* name, const char* ns=NULL) const=0; - virtual const IPropertySet* getPropertySet(const char* name, const char* ns="urn:mace:shibboleth:target:config:1.0") const=0; - virtual const DOMElement* getElement() const=0; - virtual ~IPropertySet() {} - }; - // Forward declaration class SHIBTARGET_EXPORTS ShibTarget; @@ -80,11 +65,11 @@ namespace shibtarget { { IHandler() : m_props(NULL) {} virtual ~IHandler() {} - virtual const IPropertySet* getProperties() const { return m_props; } - virtual void setProperties(const IPropertySet* properties) { m_props=properties; } + virtual const shibsp::PropertySet* getProperties() const { return m_props; } + virtual void setProperties(const shibsp::PropertySet* properties) { m_props=properties; } virtual std::pair run(ShibTarget* st, bool isHandler=true) const=0; private: - const IPropertySet* m_props; + const shibsp::PropertySet* m_props; }; /** @@ -98,7 +83,7 @@ namespace shibtarget { * Application. Implementations should always expose an application named "default" * as a last resort. */ - struct SHIBTARGET_EXPORTS IApplication : public virtual IPropertySet, + struct SHIBTARGET_EXPORTS IApplication : public virtual shibsp::PropertySet, public virtual shibboleth::ShibBrowserProfile::ITokenValidator { virtual const char* getId() const=0; @@ -109,7 +94,7 @@ namespace shibtarget { virtual saml::Iterator getMetadataProviders() const=0; virtual saml::Iterator getTrustProviders() const=0; virtual saml::Iterator getAudiences() const=0; - virtual const IPropertySet* getCredentialUse(const shibboleth::IEntityDescriptor* provider) const=0; + virtual const shibsp::PropertySet* getCredentialUse(const shibboleth::IEntityDescriptor* provider) const=0; // caller is borrowing object, must use within scope of config lock virtual const saml::SAMLBrowserProfile* getBrowserProfile() const=0; @@ -162,16 +147,16 @@ namespace shibtarget { // Client declares a context object and pass as callCtx to send() method. class ShibHTTPHookCallContext { public: - ShibHTTPHookCallContext(const IPropertySet* credUse, const shibboleth::IRoleDescriptor* role) + ShibHTTPHookCallContext(const shibsp::PropertySet* credUse, const shibboleth::IRoleDescriptor* role) : m_credUse(credUse), m_role(role), m_hook(NULL), m_authenticated(false) {} const ShibHTTPHook* getHook() {return m_hook;} - const IPropertySet* getCredentialUse() {return m_credUse;} + const shibsp::PropertySet* getCredentialUse() {return m_credUse;} const shibboleth::IRoleDescriptor* getRoleDescriptor() {return m_role;} bool isAuthenticated() const {return m_authenticated;} void setAuthenticated() {m_authenticated=true;} private: - const IPropertySet* m_credUse; + const shibsp::PropertySet* m_credUse; const shibboleth::IRoleDescriptor* m_role; ShibHTTPHook* m_hook; bool m_authenticated; @@ -291,12 +276,12 @@ namespace shibtarget { */ struct SHIBTARGET_EXPORTS IRequestMapper : public virtual saml::ILockable, public virtual saml::IPlugIn { - typedef std::pair Settings; + typedef std::pair Settings; virtual Settings getSettings(ShibTarget* st) const=0; virtual ~IRequestMapper() {} }; - struct SHIBTARGET_EXPORTS IConfig : public virtual saml::ILockable, public virtual IPropertySet, public virtual saml::IPlugIn + struct SHIBTARGET_EXPORTS IConfig : public virtual saml::ILockable, public virtual shibsp::PropertySet, public virtual saml::IPlugIn { // loads initial configuration virtual void init()=0; diff --git a/shibsp/DOMPropertySet.cpp b/shibsp/DOMPropertySet.cpp new file mode 100644 index 0000000..892fdfc --- /dev/null +++ b/shibsp/DOMPropertySet.cpp @@ -0,0 +1,214 @@ +/* + * Copyright 2001-2006 Internet2 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * DOMPropertySet.cpp + * + * DOM-based property set implementation. + */ + +#include "internal.h" +#include "DOMPropertySet.h" + +#include +#include +#include + +using namespace shibsp; +using namespace xmltooling; +using namespace log4cpp; +using namespace xercesc; +using namespace std; + +DOMPropertySet::~DOMPropertySet() +{ + for (map >::iterator i=m_map.begin(); i!=m_map.end(); i++) + XMLString::release(&(i->second.first)); + for_each(m_nested.begin(),m_nested.end(),xmltooling::cleanup_pair()); +} + +void DOMPropertySet::load( + const DOMElement* e, + Category& log, + DOMNodeFilter* filter, + const std::map* remapper + ) +{ +#ifdef _DEBUG + NDC ndc("load"); +#endif + m_root=e; + + // Process each attribute as a property. + DOMNamedNodeMap* attrs=m_root->getAttributes(); + for (XMLSize_t i=0; igetLength(); i++) { + DOMNode* a=attrs->item(i); + if (!XMLString::compareString(a->getNamespaceURI(),xmlconstants::XMLNS_NS)) + continue; + char* val=XMLString::transcode(a->getNodeValue()); + if (val && *val) { + auto_ptr_char ns(a->getNamespaceURI()); + auto_ptr_char name(a->getLocalName()); + const char* realname=name.get(); + if (remapper) { + map::const_iterator remap=remapper->find(realname); + if (remap!=remapper->end()) { + log.warn("remapping property (%s) to (%s)",realname,remap->second.c_str()); + realname=remap->second.c_str(); + } + } + if (ns.get()) { + m_map[string("{") + ns.get() + '}' + realname]=pair(val,a->getNodeValue()); + log.debug("added property {%s}%s (%s)",ns.get(),realname,val); + } + else { + m_map[realname]=pair(val,a->getNodeValue()); + log.debug("added property %s (%s)",realname,val); + } + } + } + + // Process non-excluded elements as nested sets. + DOMTreeWalker* walker= + static_cast( + m_root->getOwnerDocument())->createTreeWalker(const_cast(m_root),DOMNodeFilter::SHOW_ELEMENT,filter,false + ); + e=static_cast(walker->firstChild()); + while (e) { + auto_ptr_char ns(e->getNamespaceURI()); + auto_ptr_char name(e->getLocalName()); + const char* realname=name.get(); + if (remapper) { + map::const_iterator remap=remapper->find(realname); + if (remap!=remapper->end()) { + log.warn("remapping property set (%s) to (%s)",realname,remap->second.c_str()); + realname=remap->second.c_str(); + } + } + string key; + if (ns.get()) + key=string("{") + ns.get() + '}' + realname; + else + key=realname; + if (m_nested.find(key)!=m_nested.end()) + log.warn("load() skipping duplicate property set: %s",key.c_str()); + else { + DOMPropertySet* set=new DOMPropertySet(); + set->load(e,log,filter,remapper); + m_nested[key]=set; + log.debug("added nested property set: %s",key.c_str()); + } + e=static_cast(walker->nextSibling()); + } + walker->release(); +} + +pair DOMPropertySet::getBool(const char* name, const char* ns) const +{ + pair ret(false,false); + map >::const_iterator i; + + if (ns) + i=m_map.find(string("{") + ns + '}' + name); + else + i=m_map.find(name); + + if (i!=m_map.end()) { + ret.first=true; + ret.second=(!strcmp(i->second.first,"true") || !strcmp(i->second.first,"1")); + } + return ret; +} + +pair DOMPropertySet::getString(const char* name, const char* ns) const +{ + pair ret(false,NULL); + map >::const_iterator i; + + if (ns) + i=m_map.find(string("{") + ns + '}' + name); + else + i=m_map.find(name); + + if (i!=m_map.end()) { + ret.first=true; + ret.second=i->second.first; + } + return ret; +} + +pair DOMPropertySet::getXMLString(const char* name, const char* ns) const +{ + pair ret(false,NULL); + map >::const_iterator i; + + if (ns) + i=m_map.find(string("{") + ns + '}' + name); + else + i=m_map.find(name); + + if (i!=m_map.end()) { + ret.first=true; + ret.second=i->second.second; + } + return ret; +} + +pair DOMPropertySet::getUnsignedInt(const char* name, const char* ns) const +{ + pair ret(false,0); + map >::const_iterator i; + + if (ns) + i=m_map.find(string("{") + ns + '}' + name); + else + i=m_map.find(name); + + if (i!=m_map.end()) { + ret.first=true; + ret.second=strtol(i->second.first,NULL,10); + } + return ret; +} + +pair DOMPropertySet::getInt(const char* name, const char* ns) const +{ + pair ret(false,0); + map >::const_iterator i; + + if (ns) + i=m_map.find(string("{") + ns + '}' + name); + else + i=m_map.find(name); + + if (i!=m_map.end()) { + ret.first=true; + ret.second=atoi(i->second.first); + } + return ret; +} + +const PropertySet* DOMPropertySet::getPropertySet(const char* name, const char* ns) const +{ + map::const_iterator i; + + if (ns) + i=m_nested.find(string("{") + ns + '}' + name); + else + i=m_nested.find(name); + + return (i!=m_nested.end()) ? i->second : NULL; +} diff --git a/shibsp/DOMPropertySet.h b/shibsp/DOMPropertySet.h new file mode 100644 index 0000000..e061071 --- /dev/null +++ b/shibsp/DOMPropertySet.h @@ -0,0 +1,74 @@ +/* + * Copyright 2001-2006 Internet2 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file shibsp/DOMPropertySet.h + * + * DOM-based property set implementation. + */ + +#ifndef __shibsp_dompropset_h__ +#define __shibsp_dompropset_h__ + +#include +#include + +namespace shibsp { + + /** + * DOM-based property set implementation. + */ + class SHIBSP_API DOMPropertySet : public virtual PropertySet + { + public: + DOMPropertySet() {} + + virtual ~DOMPropertySet(); + + std::pair getBool(const char* name, const char* ns=NULL) const; + std::pair getString(const char* name, const char* ns=NULL) const; + std::pair getXMLString(const char* name, const char* ns=NULL) const; + std::pair getUnsignedInt(const char* name, const char* ns=NULL) const; + std::pair getInt(const char* name, const char* ns=NULL) const; + const PropertySet* getPropertySet(const char* name, const char* ns="urn:mace:shibboleth:target:config:1.0") const; + + const xercesc::DOMElement* getElement() const { + return m_root; + } + + /** + * Loads the property set from a DOM element. + * + * @param e root element of property set + * @param log log object for tracing + * @param filter optional filter controls what child elements to include as nested PropertySets + * @param remapper optional map of property rename rules for legacy property support + */ + void load( + const xercesc::DOMElement* e, + log4cpp::Category& log, + xercesc::DOMNodeFilter* filter, + const std::map* remapper=NULL + ); + + private: + const xercesc::DOMElement* m_root; + std::map > m_map; + std::map m_nested; + }; +}; + +#endif /* __shibsp_dompropset_h__ */ diff --git a/shibsp/Makefile.am b/shibsp/Makefile.am index 0c262db..317ded5 100644 --- a/shibsp/Makefile.am +++ b/shibsp/Makefile.am @@ -10,9 +10,11 @@ libshibspincludedir = $(includedir)/shibsp libshibspinclude_HEADERS = \ base.h \ ddf.h \ + DOMPropertySet.h \ exceptions.h \ ListenerService.h \ paths.h \ + PropertySet.h \ version.h \ SocketListener.h \ SPConfig.h @@ -22,6 +24,7 @@ noinst_HEADERS = \ libshibsp_la_SOURCES = \ ddf.cpp \ + DOMPropertySet.cpp \ ListenerService.cpp \ SocketListener.cpp \ TCPListener.cpp \ diff --git a/shibsp/PropertySet.h b/shibsp/PropertySet.h new file mode 100644 index 0000000..260f932 --- /dev/null +++ b/shibsp/PropertySet.h @@ -0,0 +1,105 @@ +/* + * Copyright 2001-2006 Internet2 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file shibsp/PropertySet.h + * + * Interface to a generic set of typed properties or a DOM container of additional data. + */ + +#ifndef __shibsp_propset_h__ +#define __shibsp_propset_h__ + +#include +#include + +namespace shibsp { + + /** + * Interface to a generic set of typed properties or a DOM container of additional data. + */ + class SHIBSP_API PropertySet + { + MAKE_NONCOPYABLE(PropertySet); + protected: + PropertySet() {} + public: + virtual ~PropertySet() {} + + /** + * Returns a boolean-valued property. + * + * @param name property name + * @param ns property namespace, or NULL + * @return a pair consisting of a NULL indicator and the property value iff the indicator is true + */ + virtual std::pair getBool(const char* name, const char* ns=NULL) const=0; + + /** + * Returns a string-valued property. + * + * @param name property name + * @param ns property namespace, or NULL + * @return a pair consisting of a NULL indicator and the property value iff the indicator is true + */ + virtual std::pair getString(const char* name, const char* ns=NULL) const=0; + + /** + * Returns a Unicode string-valued property. + * + * @param name property name + * @param ns property namespace, or NULL + * @return a pair consisting of a NULL indicator and the property value iff the indicator is true + */ + virtual std::pair getXMLString(const char* name, const char* ns=NULL) const=0; + + /** + * Returns an unsigned integer-valued property. + * + * @param name property name + * @param ns property namespace, or NULL + * @return a pair consisting of a NULL indicator and the property value iff the indicator is true + */ + virtual std::pair getUnsignedInt(const char* name, const char* ns=NULL) const=0; + + /** + * Returns an integer-valued property. + * + * @param name property name + * @param ns property namespace, or NULL + * @return a pair consisting of a NULL indicator and the property value iff the indicator is true + */ + virtual std::pair getInt(const char* name, const char* ns=NULL) const=0; + + /** + * Returns a nested property set. + * + * @param name nested property set name + * @param ns nested property set namespace, or NULL + * @return the nested property set, or NULL + */ + virtual const PropertySet* getPropertySet(const char* name, const char* ns="urn:mace:shibboleth:target:config:1.0") const=0; + + /** + * Returns a DOM element representing the property container, if any. + * + * @return a DOM element, or NULL + */ + virtual const xercesc::DOMElement* getElement() const=0; + }; +}; + +#endif /* __shibsp_propset_h__ */ diff --git a/shibsp/shibsp.vcproj b/shibsp/shibsp.vcproj index 2ace6c5..8f2f75e 100644 --- a/shibsp/shibsp.vcproj +++ b/shibsp/shibsp.vcproj @@ -189,6 +189,10 @@ > + + @@ -215,6 +219,10 @@ > + + @@ -227,6 +235,10 @@ > + + -- 2.1.4