From dd420afb6dacd7e7cd932ee50326c865d4dd1024 Mon Sep 17 00:00:00 2001 From: Scott Cantor Date: Tue, 2 Jan 2007 03:07:22 +0000 Subject: [PATCH] Next integration phase, metadata and trust conversion. --- Shibboleth.sln | 45 +- apache/mod_apache.cpp | 4 +- isapi_shib/isapi_shib.cpp | 3 +- nsapi_shib/nsapi_shib.cpp | 2 +- odbc_ccache/odbc-ccache.cpp | 8 +- schemas/shibboleth-targetconfig-1.0.xsd | 2 +- shib-mysql-ccache/shib-mysql-ccache.cpp | 8 +- shib-target/ArtifactMapper.cpp | 76 +- shib-target/Makefile.am | 2 +- shib-target/ShibHTTPHook.cpp | 14 +- shib-target/hresult.h | 12 +- shib-target/internal.h | 11 +- shib-target/shib-ccache.cpp | 222 +++-- shib-target/shib-config.cpp | 5 - shib-target/shib-handlers.cpp | 106 ++- shib-target/shib-ini.cpp | 175 ++-- shib-target/shib-target.cpp | 69 +- shib-target/shib-target.h | 36 +- shib-target/shibtarget.vcproj | 2 +- shib/BasicTrust.cpp | 165 ---- shib/Makefile.am | 4 +- shib/Metadata.cpp | 96 +- shib/ShibBrowserProfile.cpp | 109 +-- shib/ShibConfig.cpp | 107 +-- shib/ShibbolethTrust.cpp | 537 ------------ shib/hresult.h | 38 - shib/internal.h | 13 - shib/shib.h | 332 +------ shib/shib.vcproj | 8 - shibsp/MetadataExt.h | 2 +- shibsp/MetadataExtImpl.cpp | 10 +- shibsp/SPConfig.cpp | 7 +- shibsp/SocketListener.cpp | 7 +- shibsp/base.h | 2 +- shibsp/internal.h | 6 +- test/shibtest.cpp | 40 +- xmlproviders/CredResolvers.cpp | 47 +- xmlproviders/Makefile.am | 1 - xmlproviders/TargetedID.cpp | 36 +- xmlproviders/XML.cpp | 470 +--------- xmlproviders/XMLAAP.cpp | 99 ++- xmlproviders/XMLCredentials.cpp | 15 +- xmlproviders/XMLMetadata.cpp | 1445 ------------------------------- xmlproviders/XMLProviders.cpp | 35 - xmlproviders/internal.h | 119 +-- xmlproviders/xmlproviders.vcproj | 4 - 46 files changed, 600 insertions(+), 3956 deletions(-) delete mode 100644 shib/BasicTrust.cpp delete mode 100644 shib/ShibbolethTrust.cpp delete mode 100644 shib/hresult.h delete mode 100644 xmlproviders/XMLMetadata.cpp diff --git a/Shibboleth.sln b/Shibboleth.sln index 8c0cc96..2602ebf 100644 --- a/Shibboleth.sln +++ b/Shibboleth.sln @@ -2,96 +2,95 @@ Microsoft Visual Studio Solution File, Format Version 9.00 # Visual Studio 2005 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "isapi_shib", "isapi_shib\isapi_shib.vcproj", "{87C25D4E-8D19-4513-B0BA-BC668BC2DEE3}" ProjectSection(ProjectDependencies) = postProject - {E6CAB6C8-1D73-4410-970A-52BF9EC57810} = {E6CAB6C8-1D73-4410-970A-52BF9EC57810} - {84890110-2190-4AAE-9BDC-58F90DF71E4F} = {84890110-2190-4AAE-9BDC-58F90DF71E4F} {81F0F7A6-DC36-46EF-957F-F9E81D4403F6} = {81F0F7A6-DC36-46EF-957F-F9E81D4403F6} + {84890110-2190-4AAE-9BDC-58F90DF71E4F} = {84890110-2190-4AAE-9BDC-58F90DF71E4F} + {E6CAB6C8-1D73-4410-970A-52BF9EC57810} = {E6CAB6C8-1D73-4410-970A-52BF9EC57810} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "isapi_shib_gui", "isapi_shib_gui\isapi_shib_gui.vcproj", "{D341DCD8-7DCD-43A2-8559-C07DAB838711}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_shib13", "apache\mod_shib13.vcproj", "{D243B43E-728E-4F32-BDFF-B3A897037C6D}" ProjectSection(ProjectDependencies) = postProject - {E6CAB6C8-1D73-4410-970A-52BF9EC57810} = {E6CAB6C8-1D73-4410-970A-52BF9EC57810} - {84890110-2190-4AAE-9BDC-58F90DF71E4F} = {84890110-2190-4AAE-9BDC-58F90DF71E4F} {81F0F7A6-DC36-46EF-957F-F9E81D4403F6} = {81F0F7A6-DC36-46EF-957F-F9E81D4403F6} + {84890110-2190-4AAE-9BDC-58F90DF71E4F} = {84890110-2190-4AAE-9BDC-58F90DF71E4F} + {E6CAB6C8-1D73-4410-970A-52BF9EC57810} = {E6CAB6C8-1D73-4410-970A-52BF9EC57810} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_shib20", "apache\mod_shib20.vcproj", "{68E9568B-476C-4289-B93C-893432378ADC}" ProjectSection(ProjectDependencies) = postProject - {E6CAB6C8-1D73-4410-970A-52BF9EC57810} = {E6CAB6C8-1D73-4410-970A-52BF9EC57810} - {84890110-2190-4AAE-9BDC-58F90DF71E4F} = {84890110-2190-4AAE-9BDC-58F90DF71E4F} {81F0F7A6-DC36-46EF-957F-F9E81D4403F6} = {81F0F7A6-DC36-46EF-957F-F9E81D4403F6} + {84890110-2190-4AAE-9BDC-58F90DF71E4F} = {84890110-2190-4AAE-9BDC-58F90DF71E4F} + {E6CAB6C8-1D73-4410-970A-52BF9EC57810} = {E6CAB6C8-1D73-4410-970A-52BF9EC57810} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "nsapi_shib", "nsapi_shib\nsapi_shib.vcproj", "{1396D80A-8672-4224-9B02-95F3F4207CDB}" ProjectSection(ProjectDependencies) = postProject - {84890110-2190-4AAE-9BDC-58F90DF71E4F} = {84890110-2190-4AAE-9BDC-58F90DF71E4F} - {81F0F7A6-DC36-46EF-957F-F9E81D4403F6} = {81F0F7A6-DC36-46EF-957F-F9E81D4403F6} {E6CAB6C8-1D73-4410-970A-52BF9EC57810} = {E6CAB6C8-1D73-4410-970A-52BF9EC57810} + {81F0F7A6-DC36-46EF-957F-F9E81D4403F6} = {81F0F7A6-DC36-46EF-957F-F9E81D4403F6} + {84890110-2190-4AAE-9BDC-58F90DF71E4F} = {84890110-2190-4AAE-9BDC-58F90DF71E4F} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "posttest", "posttest\posttest.vcproj", "{16E70C47-789E-43D5-AFDF-964D386C3CB5}" ProjectSection(ProjectDependencies) = postProject - {84890110-2190-4AAE-9BDC-58F90DF71E4F} = {84890110-2190-4AAE-9BDC-58F90DF71E4F} - {81F0F7A6-DC36-46EF-957F-F9E81D4403F6} = {81F0F7A6-DC36-46EF-957F-F9E81D4403F6} {E6CAB6C8-1D73-4410-970A-52BF9EC57810} = {E6CAB6C8-1D73-4410-970A-52BF9EC57810} + {81F0F7A6-DC36-46EF-957F-F9E81D4403F6} = {81F0F7A6-DC36-46EF-957F-F9E81D4403F6} + {84890110-2190-4AAE-9BDC-58F90DF71E4F} = {84890110-2190-4AAE-9BDC-58F90DF71E4F} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shar", "shar\shar.vcproj", "{F13141B5-6C87-40BB-8D4E-5CC56EBB4C59}" ProjectSection(ProjectDependencies) = postProject - {E6CAB6C8-1D73-4410-970A-52BF9EC57810} = {E6CAB6C8-1D73-4410-970A-52BF9EC57810} - {84890110-2190-4AAE-9BDC-58F90DF71E4F} = {84890110-2190-4AAE-9BDC-58F90DF71E4F} {81F0F7A6-DC36-46EF-957F-F9E81D4403F6} = {81F0F7A6-DC36-46EF-957F-F9E81D4403F6} + {84890110-2190-4AAE-9BDC-58F90DF71E4F} = {84890110-2190-4AAE-9BDC-58F90DF71E4F} + {E6CAB6C8-1D73-4410-970A-52BF9EC57810} = {E6CAB6C8-1D73-4410-970A-52BF9EC57810} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shib", "shib\shib.vcproj", "{E6CAB6C8-1D73-4410-970A-52BF9EC57810}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shib_mysql_ccache", "shib-mysql-ccache\shib_mysql_ccache.vcproj", "{54671467-CA4D-4BA3-9A27-15ED5576143D}" ProjectSection(ProjectDependencies) = postProject - {E6CAB6C8-1D73-4410-970A-52BF9EC57810} = {E6CAB6C8-1D73-4410-970A-52BF9EC57810} {84890110-2190-4AAE-9BDC-58F90DF71E4F} = {84890110-2190-4AAE-9BDC-58F90DF71E4F} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shibtarget", "shib-target\shibtarget.vcproj", "{84890110-2190-4AAE-9BDC-58F90DF71E4F}" ProjectSection(ProjectDependencies) = postProject - {81F0F7A6-DC36-46EF-957F-F9E81D4403F6} = {81F0F7A6-DC36-46EF-957F-F9E81D4403F6} {E6CAB6C8-1D73-4410-970A-52BF9EC57810} = {E6CAB6C8-1D73-4410-970A-52BF9EC57810} + {81F0F7A6-DC36-46EF-957F-F9E81D4403F6} = {81F0F7A6-DC36-46EF-957F-F9E81D4403F6} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shibtest", "shibtest\shibtest.vcproj", "{67AF22A3-C26E-40BE-B0CA-2ABEE5123763}" ProjectSection(ProjectDependencies) = postProject - {E6CAB6C8-1D73-4410-970A-52BF9EC57810} = {E6CAB6C8-1D73-4410-970A-52BF9EC57810} - {84890110-2190-4AAE-9BDC-58F90DF71E4F} = {84890110-2190-4AAE-9BDC-58F90DF71E4F} {81F0F7A6-DC36-46EF-957F-F9E81D4403F6} = {81F0F7A6-DC36-46EF-957F-F9E81D4403F6} + {84890110-2190-4AAE-9BDC-58F90DF71E4F} = {84890110-2190-4AAE-9BDC-58F90DF71E4F} + {E6CAB6C8-1D73-4410-970A-52BF9EC57810} = {E6CAB6C8-1D73-4410-970A-52BF9EC57810} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "siterefresh", "siterefresh\siterefresh.vcproj", "{4D02F36E-D2CD-4FD1-AC50-2941E27BB3FB}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testclient", "shar\testclient.vcproj", "{B3F1E899-86F9-4D3A-8026-B57D1A5B90B1}" ProjectSection(ProjectDependencies) = postProject - {84890110-2190-4AAE-9BDC-58F90DF71E4F} = {84890110-2190-4AAE-9BDC-58F90DF71E4F} - {81F0F7A6-DC36-46EF-957F-F9E81D4403F6} = {81F0F7A6-DC36-46EF-957F-F9E81D4403F6} {E6CAB6C8-1D73-4410-970A-52BF9EC57810} = {E6CAB6C8-1D73-4410-970A-52BF9EC57810} + {81F0F7A6-DC36-46EF-957F-F9E81D4403F6} = {81F0F7A6-DC36-46EF-957F-F9E81D4403F6} + {84890110-2190-4AAE-9BDC-58F90DF71E4F} = {84890110-2190-4AAE-9BDC-58F90DF71E4F} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xmlproviders", "xmlproviders\xmlproviders.vcproj", "{68E46D06-6B91-4C59-A700-78DD4D4C420B}" ProjectSection(ProjectDependencies) = postProject - {84890110-2190-4AAE-9BDC-58F90DF71E4F} = {84890110-2190-4AAE-9BDC-58F90DF71E4F} - {81F0F7A6-DC36-46EF-957F-F9E81D4403F6} = {81F0F7A6-DC36-46EF-957F-F9E81D4403F6} {E6CAB6C8-1D73-4410-970A-52BF9EC57810} = {E6CAB6C8-1D73-4410-970A-52BF9EC57810} + {81F0F7A6-DC36-46EF-957F-F9E81D4403F6} = {81F0F7A6-DC36-46EF-957F-F9E81D4403F6} + {84890110-2190-4AAE-9BDC-58F90DF71E4F} = {84890110-2190-4AAE-9BDC-58F90DF71E4F} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "odbc_ccache", "odbc_ccache\odbc_ccache.vcproj", "{DAC7FB99-038A-45C9-A27C-21B6C8D4CD1E}" ProjectSection(ProjectDependencies) = postProject - {E6CAB6C8-1D73-4410-970A-52BF9EC57810} = {E6CAB6C8-1D73-4410-970A-52BF9EC57810} + {81F0F7A6-DC36-46EF-957F-F9E81D4403F6} = {81F0F7A6-DC36-46EF-957F-F9E81D4403F6} {84890110-2190-4AAE-9BDC-58F90DF71E4F} = {84890110-2190-4AAE-9BDC-58F90DF71E4F} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_shib22", "apache\mod_shib22.vcproj", "{B44C0852-83B8-4FB2-A86E-097C9C8256D0}" ProjectSection(ProjectDependencies) = postProject - {E6CAB6C8-1D73-4410-970A-52BF9EC57810} = {E6CAB6C8-1D73-4410-970A-52BF9EC57810} - {84890110-2190-4AAE-9BDC-58F90DF71E4F} = {84890110-2190-4AAE-9BDC-58F90DF71E4F} {81F0F7A6-DC36-46EF-957F-F9E81D4403F6} = {81F0F7A6-DC36-46EF-957F-F9E81D4403F6} + {84890110-2190-4AAE-9BDC-58F90DF71E4F} = {84890110-2190-4AAE-9BDC-58F90DF71E4F} + {E6CAB6C8-1D73-4410-970A-52BF9EC57810} = {E6CAB6C8-1D73-4410-970A-52BF9EC57810} EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Server Modules", "Server Modules", "{26BA8F84-6E42-41FA-9B13-5D3F4B5B2050}" diff --git a/apache/mod_apache.cpp b/apache/mod_apache.cpp index 40e0871..7bf01d2 100644 --- a/apache/mod_apache.cpp +++ b/apache/mod_apache.cpp @@ -31,11 +31,13 @@ # define _CRT_SECURE_NO_DEPRECATE 1 #endif +#include +#include + // SAML Runtime #include #include #include -#include #include #ifdef WIN32 diff --git a/isapi_shib/isapi_shib.cpp b/isapi_shib/isapi_shib.cpp index dda800d..0636687 100644 --- a/isapi_shib/isapi_shib.cpp +++ b/isapi_shib/isapi_shib.cpp @@ -25,11 +25,12 @@ #define _CRT_NONSTDC_NO_DEPRECATE 1 #define _CRT_SECURE_NO_DEPRECATE 1 +#include + // SAML Runtime #include #include #include -#include #include #include diff --git a/nsapi_shib/nsapi_shib.cpp b/nsapi_shib/nsapi_shib.cpp index 6a72c0b..05300b9 100644 --- a/nsapi_shib/nsapi_shib.cpp +++ b/nsapi_shib/nsapi_shib.cpp @@ -31,12 +31,12 @@ # define _CRT_SECURE_NO_DEPRECATE 1 #endif +#include // SAML Runtime #include #include #include -#include #include #include diff --git a/odbc_ccache/odbc-ccache.cpp b/odbc_ccache/odbc-ccache.cpp index 350bb27..1dc7b99 100644 --- a/odbc_ccache/odbc-ccache.cpp +++ b/odbc_ccache/odbc-ccache.cpp @@ -39,6 +39,7 @@ #endif #include +#include #include #include @@ -53,8 +54,9 @@ #include #endif +using namespace shibsp; using namespace shibtarget; -using namespace shibboleth; +using namespace opensaml::saml2md; using namespace saml; using namespace xmltooling; using namespace log4cpp; @@ -275,13 +277,13 @@ public: // Delegate all the ISessionCache methods. string insert( const IApplication* application, - const IEntityDescriptor* source, + const RoleDescriptor* role, const char* client_addr, const SAMLSubject* subject, const char* authnContext, const SAMLResponse* tokens ) - { return m_cache->insert(application,source,client_addr,subject,authnContext,tokens); } + { return m_cache->insert(application,role,client_addr,subject,authnContext,tokens); } ISessionCacheEntry* find(const char* key, const IApplication* application, const char* client_addr) { return m_cache->find(key,application,client_addr); } void remove(const char* key, const IApplication* application, const char* client_addr) diff --git a/schemas/shibboleth-targetconfig-1.0.xsd b/schemas/shibboleth-targetconfig-1.0.xsd index 9f8da9e..f05f7da 100644 --- a/schemas/shibboleth-targetconfig-1.0.xsd +++ b/schemas/shibboleth-targetconfig-1.0.xsd @@ -7,7 +7,7 @@ elementFormDefault="qualified" attributeFormDefault="unqualified" blockDefault="substitution" - version="1.1"> + version="2.0"> diff --git a/shib-mysql-ccache/shib-mysql-ccache.cpp b/shib-mysql-ccache/shib-mysql-ccache.cpp index c69ce09..e8f8321 100644 --- a/shib-mysql-ccache/shib-mysql-ccache.cpp +++ b/shib-mysql-ccache/shib-mysql-ccache.cpp @@ -59,7 +59,7 @@ #endif using namespace shibtarget; -using namespace shibboleth; +using namespace opensaml::saml2md; using namespace saml; using namespace log4cpp; using namespace std; @@ -384,13 +384,13 @@ public: // Delegate all the ISessionCache methods. string insert( const IApplication* application, - const IEntityDescriptor* source, + const RoleDescriptor* role, const char* client_addr, const SAMLSubject* subject, const char* authnContext, const SAMLResponse* tokens ) - { return m_cache->insert(application,source,client_addr,subject,authnContext,tokens); } + { return m_cache->insert(application,role,client_addr,subject,authnContext,tokens); } ISessionCacheEntry* find(const char* key, const IApplication* application, const char* client_addr) { return m_cache->find(key,application,client_addr); } void remove(const char* key, const IApplication* application, const char* client_addr) @@ -845,7 +845,7 @@ void* ShibMySQLCCache::cleanup_fcn(void* cache_p) ShibMySQLCCache* cache = (ShibMySQLCCache*)cache_p; #ifndef WIN32 - // First, let's block all signals + // First, let'block all signals xmltooling::Thread::mask_all_signals(); #endif diff --git a/shib-target/ArtifactMapper.cpp b/shib-target/ArtifactMapper.cpp index 02e1b06..a38f896 100644 --- a/shib-target/ArtifactMapper.cpp +++ b/shib-target/ArtifactMapper.cpp @@ -23,11 +23,13 @@ */ #include "internal.h" +#include using namespace shibsp; using namespace shibtarget; -using namespace shibboleth; using namespace saml; +using namespace opensaml::saml2md; +using namespace xmltooling; using namespace log4cpp; using namespace std; @@ -37,17 +39,19 @@ SAMLResponse* STArtifactMapper::resolve(SAMLRequest* request) // First do a search for the issuer. SAMLArtifact* artifact=request->getArtifacts().next(); - Metadata m(m_app->getMetadataProviders()); - const IEntityDescriptor* entity=m.lookup(artifact); + auto_ptr os2art(opensaml::SAMLArtifact::parse(artifact->encode().c_str())); + + MetadataProvider* m=m_app->getMetadataProvider(); + const EntityDescriptor* entity=m->getEntityDescriptor(os2art.get()); if (!entity) { log.error( "metadata lookup failed, unable to determine issuer of artifact (0x%s)", - SAMLArtifact::toHex(artifact->getBytes()).c_str() + opensaml::SAMLArtifact::toHex(artifact->getBytes()).c_str() ); throw MetadataException("Metadata lookup failed, unable to determine artifact issuer"); } - auto_ptr_char issuer(entity->getId()); + xmltooling::auto_ptr_char issuer(entity->getEntityID()); log.info("lookup succeeded, artifact issued by (%s)", issuer.get()); // Sign it? @@ -63,8 +67,8 @@ SAMLResponse* STArtifactMapper::resolve(SAMLRequest* request) pair signingCred=credUse ? credUse->getString("Signing") : pair(false,NULL); if (signRequest.first && signRequest.second && signingCred.first) { if (request->getMinorVersion()==1) { - Credentials creds(ShibTargetConfig::getConfig().getINI()->getCredentialsProviders()); - const ICredResolver* cr=creds.lookup(signingCred.second); + shibboleth::Credentials creds(ShibTargetConfig::getConfig().getINI()->getCredentialsProviders()); + const shibboleth::ICredResolver* cr=creds.lookup(signingCred.second); if (cr) request->sign(cr->getKey(),cr->getCertificates(),signatureAlg.second,digestAlg.second); else @@ -82,23 +86,21 @@ SAMLResponse* STArtifactMapper::resolve(SAMLRequest* request) const SAMLArtifactType0001* type1=dynamic_cast(artifact); if (type1) { // With type 01, any endpoint will do. - const IIDPSSODescriptor* idp=entity->getIDPSSODescriptor( - request->getMinorVersion()==1 ? saml::XML::SAML11_PROTOCOL_ENUM : saml::XML::SAML10_PROTOCOL_ENUM + const IDPSSODescriptor* idp=entity->getIDPSSODescriptor( + request->getMinorVersion()==1 ? samlconstants::SAML11_PROTOCOL_ENUM : samlconstants::SAML10_PROTOCOL_ENUM ); if (idp) { ShibHTTPHook::ShibHTTPHookCallContext callCtx(credUse,idp); - const IEndpointManager* mgr=idp->getArtifactResolutionServiceManager(); - Iterator eps=mgr ? mgr->getEndpoints() : EMPTY(const IEndpoint*); - while (!response && eps.hasNext()) { - const IEndpoint* ep=eps.next(); - const SAMLBinding* binding = m_app->getBinding(ep->getBinding()); + const vector& endpoints=idp->getArtifactResolutionServices(); + for (vector::const_iterator ep=endpoints.begin(); !response && ep!=endpoints.end(); ++ep) { + const SAMLBinding* binding = m_app->getBinding((*ep)->getBinding()); if (!binding) { - auto_ptr_char prot(ep->getBinding()); + xmltooling::auto_ptr_char prot((*ep)->getBinding()); log.warn("skipping binding on unsupported protocol (%s)", prot.get()); continue; } try { - response = binding->send(ep->getLocation(),*request,&callCtx); + response = binding->send((*ep)->getLocation(),*request,&callCtx); if (log.isDebugEnabled()) log.debugStream() << "SAML response from artifact request:\n" << *response << CategoryStream::ENDLINE; @@ -106,11 +108,15 @@ SAMLResponse* STArtifactMapper::resolve(SAMLRequest* request) delete response; throw FatalProfileException("No SAML assertions returned in response to artifact profile request."); } - authenticated = callCtx.isAuthenticated() && !XMLString::compareNString(ep->getLocation(),https,6); + authenticated = callCtx.isAuthenticated() && !XMLString::compareNString((*ep)->getLocation(),https,6); } - catch (SAMLException& ex) { + catch (XMLToolingException& ex) { annotateException(&ex,idp); // rethrows it } + catch (exception& ex) { + opensaml::BindingException ex2(ex.what()); + annotateException(&ex2,idp); // rethrows it + } } } } @@ -118,26 +124,24 @@ SAMLResponse* STArtifactMapper::resolve(SAMLRequest* request) const SAMLArtifactType0002* type2=dynamic_cast(artifact); if (type2) { // With type 02, we have to find the matching location. - const IIDPSSODescriptor* idp=entity->getIDPSSODescriptor( - request->getMinorVersion()==1 ? saml::XML::SAML11_PROTOCOL_ENUM : saml::XML::SAML10_PROTOCOL_ENUM + const IDPSSODescriptor* idp=entity->getIDPSSODescriptor( + request->getMinorVersion()==1 ? samlconstants::SAML11_PROTOCOL_ENUM : samlconstants::SAML10_PROTOCOL_ENUM ); if (idp) { ShibHTTPHook::ShibHTTPHookCallContext callCtx(credUse,idp); - const IEndpointManager* mgr=idp->getArtifactResolutionServiceManager(); - Iterator eps=mgr ? mgr->getEndpoints() : EMPTY(const IEndpoint*); - while (eps.hasNext()) { - const IEndpoint* ep=eps.next(); - auto_ptr_char loc(ep->getLocation()); + const vector& endpoints=idp->getArtifactResolutionServices(); + for (vector::const_iterator ep=endpoints.begin(); !response && ep!=endpoints.end(); ++ep) { + xmltooling::auto_ptr_char loc((*ep)->getLocation()); if (strcmp(loc.get(),type2->getSourceLocation())) continue; - const SAMLBinding* binding = m_app->getBinding(ep->getBinding()); + const SAMLBinding* binding = m_app->getBinding((*ep)->getBinding()); if (!binding) { - auto_ptr_char prot(ep->getBinding()); + xmltooling::auto_ptr_char prot((*ep)->getBinding()); log.warn("skipping binding on unsupported protocol (%s)", prot.get()); continue; } try { - response = binding->send(ep->getLocation(),*request,&callCtx); + response = binding->send((*ep)->getLocation(),*request,&callCtx); if (log.isDebugEnabled()) log.debugStream() << "SAML response from artifact request:\n" << *response << CategoryStream::ENDLINE; @@ -145,17 +149,21 @@ SAMLResponse* STArtifactMapper::resolve(SAMLRequest* request) delete response; throw FatalProfileException("No SAML assertions returned in response to artifact profile request."); } - authenticated = callCtx.isAuthenticated() && !XMLString::compareNString(ep->getLocation(),https,6); - } - catch (SAMLException& ex) { - annotateException(&ex,idp); // rethrows it + authenticated = callCtx.isAuthenticated() && !XMLString::compareNString((*ep)->getLocation(),https,6); } + catch (XMLToolingException& ex) { + annotateException(&ex,idp); // rethrows it + } + catch (exception& ex) { + opensaml::BindingException ex2(ex.what()); + annotateException(&ex2,idp); // rethrows it + } } } } else { log.error("unrecognized artifact type (0x%s)", SAMLArtifact::toHex(artifact->getTypeCode()).c_str()); - throw UnsupportedExtensionException( + throw xmltooling::UnknownExtensionException( string("Received unrecognized artifact type (0x") + SAMLArtifact::toHex(artifact->getTypeCode()) + ")" ); } @@ -169,7 +177,7 @@ SAMLResponse* STArtifactMapper::resolve(SAMLRequest* request) else if (!response->isSigned()) { if (!authenticated || (signedResponse.first && signedResponse.second)) { log.error("unsigned response obtained, but it must be signed."); - TrustException ex("Unable to obtain a signed response from artifact request."); + XMLSecurityException ex("Unable to obtain a signed response from artifact request."); annotateException(&ex,entity); // throws it } } diff --git a/shib-target/Makefile.am b/shib-target/Makefile.am index 73a130f..022e5f9 100644 --- a/shib-target/Makefile.am +++ b/shib-target/Makefile.am @@ -8,7 +8,7 @@ pkgxmldir = $(datadir)/xml/@PACKAGE@ lib_LTLIBRARIES = libshib-target.la libshib_targetdir = $(includedir)/shib-target -libshib_target_HEADERS = shib-target.h shib-paths.h hresult.h +libshib_target_HEADERS = shib-target.h shib-paths.h noinst_HEADERS = internal.h libshib_target_la_SOURCES = \ diff --git a/shib-target/ShibHTTPHook.cpp b/shib-target/ShibHTTPHook.cpp index 47318f6..ba52da5 100644 --- a/shib-target/ShibHTTPHook.cpp +++ b/shib-target/ShibHTTPHook.cpp @@ -24,6 +24,8 @@ #include "internal.h" +#include + #include #include #include @@ -32,6 +34,7 @@ using namespace shibsp; using namespace shibtarget; using namespace shibboleth; using namespace saml; +using namespace xmltooling; using namespace log4cpp; using namespace std; @@ -54,15 +57,8 @@ static int verify_callback(X509_STORE_CTX* x509_ctx, void* arg) reinterpret_cast(SSL_get_verify_depth(ssl)); #endif - // Instead of using the supplied verifier, we let the plugins do whatever they want to do - // with the untrusted certificates we find in the object. We can save a bit of memory by - // just building a vector that points at them inside the supplied structure. - vector chain; - for (int i=0; iuntrusted); i++) - chain.push_back(sk_X509_value(x509_ctx->untrusted,i)); - - Trust t(ctx->getHook()->getTrustProviders()); - if (!t.validate(x509_ctx->cert,chain,ctx->getRoleDescriptor(),false)) { // bypass name check (handled for us) + const OpenSSLTrustEngine* t = dynamic_cast(ctx->getHook()->getTrustEngine()); + if (!t || !t->validate(x509_ctx->cert,x509_ctx->untrusted,*(ctx->getRoleDescriptor()),false)) { // bypass name check (handled for us) x509_ctx->error=X509_V_ERR_APPLICATION_VERIFICATION; // generic error, check log for plugin specifics return 0; } diff --git a/shib-target/hresult.h b/shib-target/hresult.h index 255c8bc..bbf6867 100644 --- a/shib-target/hresult.h +++ b/shib-target/hresult.h @@ -21,15 +21,15 @@ #ifndef __shibtargethresult_h__ #define __shibtargethresult_h__ -#include +#include -/* Codes from 0xA000 - 0xAFFF in FACILITY_ITF are reserved for the Shibboleth SP */ +/* Codes from 0x9000 - 0x9FFF in FACILITY_ITF are reserved for the Shibboleth SP */ -#define SHIBSP_E_FIRST MAKE_HRESULT(SEVERITY_ERROR,FACILITY_ITF,SHIB_E_LAST + 0x0001) -#define SHIBSP_E_LAST MAKE_HRESULT(SEVERITY_ERROR,FACILITY_ITF,SHIB_E_LAST + 0x1000) +#define SHIBSP_E_FIRST MAKE_HRESULT(SEVERITY_ERROR,FACILITY_ITF,SAML_E_LAST + 0x0001) +#define SHIBSP_E_LAST MAKE_HRESULT(SEVERITY_ERROR,FACILITY_ITF,SAML_E_LAST + 0x1000) -#define SHIBSP_S_FIRST MAKE_HRESULT(SEVERITY_SUCCESS,FACILITY_ITF,SHIB_S_LAST + 0x0001) -#define SHIBSP_S_LAST MAKE_HRESULT(SEVERITY_SUCCESS,FACILITY_ITF,SHIB_S_LAST + 0x1000 +#define SHIBSP_S_FIRST MAKE_HRESULT(SEVERITY_SUCCESS,FACILITY_ITF,SAML_S_LAST + 0x0001) +#define SHIBSP_S_LAST MAKE_HRESULT(SEVERITY_SUCCESS,FACILITY_ITF,SAML_S_LAST + 0x1000 /* Specific code definitions */ diff --git a/shib-target/internal.h b/shib-target/internal.h index d2fe324..65f7fb1 100644 --- a/shib-target/internal.h +++ b/shib-target/internal.h @@ -26,6 +26,11 @@ #define __shibtarget_internal_h__ #ifdef WIN32 +# define _CRT_SECURE_NO_DEPRECATE 1 +# define _CRT_NONSTDC_NO_DEPRECATE 1 +#endif + +#ifdef WIN32 # define SHIBTARGET_EXPORTS __declspec(dllexport) #endif @@ -36,13 +41,15 @@ # include "config.h" #endif +#include + #include "shib-target.h" #include "hresult.h" -#include - #include #include +#include +#include #define SHIBT_L(s) shibtarget::XML::Literals::s #define SHIBT_L_QNAME(p,s) shibtarget::XML::Literals::p##_##s diff --git a/shib-target/shib-ccache.cpp b/shib-target/shib-ccache.cpp index e2cd92c..26d6e10 100644 --- a/shib-target/shib-ccache.cpp +++ b/shib-target/shib-ccache.cpp @@ -26,13 +26,13 @@ # include #endif -#include -#include - #include #include #include #include +#include +#include +#include #ifdef HAVE_LIBDMALLOCXX #include @@ -40,8 +40,8 @@ using namespace shibsp; using namespace shibtarget; -using namespace shibboleth; using namespace saml; +using namespace opensaml::saml2md; using namespace xmltooling; using namespace log4cpp; using namespace std; @@ -176,7 +176,7 @@ public: string insert( const IApplication* application, - const IEntityDescriptor* source, + const RoleDescriptor* role, const char* client_addr, const SAMLSubject* subject, const char* authnContext, @@ -200,7 +200,7 @@ StubCache::StubCache(const DOMElement* e) : m_log(&Category::getInstance(SHIBT_L string StubCache::insert( const IApplication* application, - const IEntityDescriptor* source, + const RoleDescriptor* role, const char* client_addr, const SAMLSubject* subject, const char* authnContext, @@ -212,7 +212,7 @@ string StubCache::insert( in.structure(); in.addmember("application_id").string(application->getId()); in.addmember("client_address").string(client_addr); - xmltooling::auto_ptr_char provid(source->getId()); + xmltooling::auto_ptr_char provid(dynamic_cast(role->getParent())->getEntityID()); in.addmember("provider_id").string(provid.get()); in.addmember("major_version").integer(1); in.addmember("minor_version").integer(tokens->getMinorVersion()); @@ -228,7 +228,7 @@ string StubCache::insert( out=ShibTargetConfig::getConfig().getINI()->getListener()->send(in); if (out["key"].isstring()) return out["key"].string(); - throw InvalidSessionException("A remoted cache insertion operation did not return a usable session key."); + throw opensaml::RetryableProfileException("A remoted cache insertion operation did not return a usable session key."); } ISessionCacheEntry* StubCache::find(const char* key, const IApplication* application, const char* client_addr) @@ -280,7 +280,7 @@ public: MemorySessionCache* cache, const char* key, const IApplication* application, - const IEntityDescriptor* source, + const RoleDescriptor* role, const char* client_addr, const SAMLSubject* subject, const char* authnContext, @@ -290,7 +290,7 @@ public: MemorySessionCache* cache, const char* key, const IApplication* application, - const IEntityDescriptor* source, + const RoleDescriptor* role, const char* client_addr, const char* subject, const char* authnContext, @@ -306,7 +306,7 @@ public: void unlock() { m_lock->unlock(); } HRESULT isValid(const IApplication* application, const char* client_addr) const; - void populate(const IApplication* application, const IEntityDescriptor* source, bool initial=false) const; + void populate(const IApplication* application, const EntityDescriptor* source, bool initial=false) const; bool checkApplication(const IApplication* application) { return (m_obj["application_id"]==application->getId()); } time_t created() const { return m_sessionCreated; } time_t lastAccess() const { return m_lastAccess; } @@ -315,8 +315,8 @@ public: private: bool hasAttributes(const SAMLResponse& r) const; time_t calculateExpiration(const SAMLResponse& r) const; - pair getNewResponse(const IApplication* application, const IEntityDescriptor* source) const; - SAMLResponse* filter(const SAMLResponse* r, const IApplication* application, const IEntityDescriptor* source) const; + pair getNewResponse(const IApplication* application, const EntityDescriptor* source) const; + SAMLResponse* filter(const SAMLResponse* r, const IApplication* application, const RoleDescriptor* role) const; time_t m_sessionCreated; mutable time_t m_responseExpiration, m_lastAccess, m_lastRetry; @@ -338,7 +338,7 @@ public: string insert( const IApplication* application, - const IEntityDescriptor* source, + const RoleDescriptor* role, const char* client_addr, const SAMLSubject* subject, const char* authnContext, @@ -379,7 +379,7 @@ MemorySessionCacheEntry::MemorySessionCacheEntry( MemorySessionCache* cache, const char* key, const IApplication* application, - const IEntityDescriptor* source, + const RoleDescriptor* role, const char* client_addr, const SAMLSubject* subject, const char* authnContext, @@ -393,7 +393,7 @@ MemorySessionCacheEntry::MemorySessionCacheEntry( m_obj.addmember("key").string(key); m_obj.addmember("client_address").string(client_addr); m_obj.addmember("application_id").string(application->getId()); - xmltooling::auto_ptr_char pid(source->getId()); + xmltooling::auto_ptr_char pid(dynamic_cast(role->getParent())->getEntityID()); m_obj.addmember("provider_id").string(pid.get()); m_obj.addmember("major_version").integer(1); m_obj.addmember("minor_version").integer(tokens->getMinorVersion()); @@ -413,7 +413,7 @@ MemorySessionCacheEntry::MemorySessionCacheEntry( if (hasAttributes(*tokens)) { // Filter attributes in the response. - auto_ptr filtered(filter(tokens, application, source)); + auto_ptr filtered(filter(tokens, application, role)); // Calculate expiration. m_responseExpiration=calculateExpiration(*(filtered.get())); @@ -461,7 +461,7 @@ MemorySessionCacheEntry::MemorySessionCacheEntry( MemorySessionCache* cache, const char* key, const IApplication* application, - const IEntityDescriptor* source, + const RoleDescriptor* role, const char* client_addr, const char* subject, const char* authnContext, @@ -484,7 +484,7 @@ MemorySessionCacheEntry::MemorySessionCacheEntry( m_obj.addmember("key").string(key); m_obj.addmember("client_address").string(client_addr); m_obj.addmember("application_id").string(application->getId()); - xmltooling::auto_ptr_char pid(source->getId()); + xmltooling::auto_ptr_char pid(dynamic_cast(role->getParent())->getEntityID()); m_obj.addmember("provider_id").string(pid.get()); m_obj.addmember("subject").string(subject); m_obj.addmember("authn_context").string(authnContext); @@ -493,7 +493,7 @@ MemorySessionCacheEntry::MemorySessionCacheEntry( m_obj.addmember("minor_version").integer(minorVersion); if (hasAttributes(*(unfiltered.get()))) { - auto_ptr filtered(filter(unfiltered.get(), application, source)); + auto_ptr filtered(filter(unfiltered.get(), application, role)); // Calculate expiration. m_responseExpiration=calculateExpiration(*(filtered.get())); @@ -528,7 +528,7 @@ MemorySessionCacheEntry::~MemorySessionCacheEntry() HRESULT MemorySessionCacheEntry::isValid(const IApplication* app, const char* client_addr) const { #ifdef _DEBUG - saml::NDC ndc("isValid"); + xmltooling::NDC ndc("isValid"); #endif // Obtain validation rules from application settings. @@ -640,10 +640,10 @@ time_t MemorySessionCacheEntry::calculateExpiration(const SAMLResponse& r) const return expiration; } -void MemorySessionCacheEntry::populate(const IApplication* application, const IEntityDescriptor* source, bool initial) const +void MemorySessionCacheEntry::populate(const IApplication* application, const EntityDescriptor* source, bool initial) const { #ifdef _DEBUG - saml::NDC ndc("populate"); + xmltooling::NDC ndc("populate"); #endif // Do we have any attribute data cached? @@ -659,10 +659,23 @@ void MemorySessionCacheEntry::populate(const IApplication* application, const IE if (FAILED(hr)) m_log->error("cache store failed to return updated tokens"); else if (hr==NOERROR && tokensFromSink!=m_obj["tokens.unfiltered"].string()) { + + // Bah...find role again. + const RoleDescriptor* role=source->getAttributeAuthorityDescriptor(samlconstants::SAML11_PROTOCOL_ENUM); + if (!role) + role=source->getAttributeAuthorityDescriptor(samlconstants::SAML10_PROTOCOL_ENUM); + if (!role) + role=source->getIDPSSODescriptor(samlconstants::SAML11_PROTOCOL_ENUM); + if (!role) + role=source->getIDPSSODescriptor(samlconstants::SAML10_PROTOCOL_ENUM); + if (!role) { + throw MetadataException("Unable to locate attribute-issuing role in metadata."); + } + // The tokens in the sink were different. istringstream is(tokensFromSink); auto_ptr respFromSink(new SAMLResponse(is,m_obj["minor_version"].integer())); - auto_ptr filteredFromSink(filter(respFromSink.get(),application,source)); + auto_ptr filteredFromSink(filter(respFromSink.get(),application,role)); time_t expFromSink=calculateExpiration(*(filteredFromSink.get())); // Recheck to see if the new tokens are valid. @@ -756,10 +769,10 @@ void MemorySessionCacheEntry::populate(const IApplication* application, const IE stc.releaseTransactionLog(); } } - catch (SAMLException&) { + catch (exception&) { if (m_cache->m_propagateErrors) throw; - m_log->warn("suppressed SAML exception caught while trying to fetch attributes"); + m_log->warn("suppressed exception caught while trying to fetch attributes"); } #ifndef _DEBUG catch (...) { @@ -771,11 +784,11 @@ void MemorySessionCacheEntry::populate(const IApplication* application, const IE } pair MemorySessionCacheEntry::getNewResponse( - const IApplication* application, const IEntityDescriptor* source + const IApplication* application, const EntityDescriptor* source ) const { #ifdef _DEBUG - saml::NDC ndc("getNewResponse"); + xmltooling::NDC ndc("getNewResponse"); #endif // The retryInterval determines how often to poll an AA that might be down. @@ -804,12 +817,12 @@ pair MemorySessionCacheEntry::getNewResponse( pair providerID=application->getXMLString("providerId"); if (!providerID.first) { m_log->crit("unable to determine ProviderID for application, not set?"); - throw SAMLException("Unable to determine ProviderID for application, not set?"); + throw ConfigurationException("Unable to determine ProviderID for application, not set?"); } // Try to locate an AA role. - const IAttributeAuthorityDescriptor* AA=source->getAttributeAuthorityDescriptor( - m_obj["minor_version"].integer()==1 ? saml::XML::SAML11_PROTOCOL_ENUM : saml::XML::SAML10_PROTOCOL_ENUM + const AttributeAuthorityDescriptor* AA=source->getAttributeAuthorityDescriptor( + m_obj["minor_version"].integer()==1 ? samlconstants::SAML11_PROTOCOL_ENUM : samlconstants::SAML10_PROTOCOL_ENUM ); if (!AA) { m_log->warn("unable to locate metadata for identity provider's Attribute Authority"); @@ -852,8 +865,8 @@ pair MemorySessionCacheEntry::getNewResponse( // Sign it? if (signRequest.first && signRequest.second && signingCred.first) { if (req->getMinorVersion()==1) { - Credentials creds(ShibTargetConfig::getConfig().getINI()->getCredentialsProviders()); - const ICredResolver* cr=creds.lookup(signingCred.second); + shibboleth::Credentials creds(ShibTargetConfig::getConfig().getINI()->getCredentialsProviders()); + const shibboleth::ICredResolver* cr=creds.lookup(signingCred.second); if (cr) req->sign(cr->getKey(),cr->getCertificates(),signatureAlg.second,digestAlg.second); else @@ -867,32 +880,31 @@ pair MemorySessionCacheEntry::getNewResponse( // Call context object ShibHTTPHook::ShibHTTPHookCallContext ctx(credUse,AA); - Trust t(application->getTrustProviders()); // Use metadata to locate endpoints. - Iterator endpoints=AA->getAttributeServiceManager()->getEndpoints(); - while (!response && endpoints.hasNext()) { - const IEndpoint* ep=endpoints.next(); + const vector& endpoints=AA->getAttributeServices(); + for (vector::const_iterator ep=endpoints.begin(); !response && ep!=endpoints.end(); ++ep) { try { // Get a binding object for this protocol. - const SAMLBinding* binding = application->getBinding(ep->getBinding()); + const SAMLBinding* binding = application->getBinding((*ep)->getBinding()); if (!binding) { - xmltooling::auto_ptr_char prot(ep->getBinding()); + xmltooling::auto_ptr_char prot((*ep)->getBinding()); m_log->warn("skipping binding on unsupported protocol (%s)", prot.get()); continue; } static const XMLCh https[] = {chLatin_h, chLatin_t, chLatin_t, chLatin_p, chLatin_s, chColon, chNull}; - auto_ptr r(binding->send(ep->getLocation(), *(req.get()), &ctx)); + auto_ptr r(binding->send((*ep)->getLocation(), *(req.get()), &ctx)); if (r->isSigned()) { - if (!t.validate(*r,AA)) - throw TrustException("Unable to verify signed response message."); + // TODO: trust stuff will be changing anyway... + //if (!t.validate(*r,AA)) + // throw TrustException("Unable to verify signed response message."); } - else if (!ctx.isAuthenticated() || XMLString::compareNString(ep->getLocation(),https,6)) - throw TrustException("Response message was unauthenticated."); + else if (!ctx.isAuthenticated() || XMLString::compareNString((*ep)->getLocation(),https,6)) + throw XMLSecurityException("Response message was unauthenticated."); response = r.release(); } - catch (SAMLException& e) { - m_log->error("caught SAML exception during SAML attribute query: %s", e.what()); + catch (exception& e) { + m_log->error("caught exception during SAML attribute query: %s", e.what()); } } @@ -900,7 +912,7 @@ pair MemorySessionCacheEntry::getNewResponse( if (signedResponse.first && signedResponse.second && !response->isSigned()) { delete response; m_log->error("unsigned response obtained, but we were told it must be signed."); - throw TrustException("Unable to obtain a signed response message."); + throw XMLSecurityException("Unable to obtain a signed response message."); } // Iterate over the tokens and apply basic validation. @@ -908,7 +920,7 @@ pair MemorySessionCacheEntry::getNewResponse( Iterator assertions=response->getAssertions(); for (unsigned int a=0; agetId(),assertions[a]->getIssuer())) { + if (XMLString::compareString(source->getEntityID(),assertions[a]->getIssuer())) { xmltooling::auto_ptr_char bad(assertions[a]->getIssuer()); m_log->warn("discarding assertion not issued by (%s), instead by (%s)",m_obj["provider_id"].string(),bad.get()); response->removeAssertion(a); @@ -917,22 +929,22 @@ pair MemorySessionCacheEntry::getNewResponse( // Validate the token. try { - application->validateToken(assertions[a],now,AA,application->getTrustProviders()); + application->validateToken(assertions[a],now,AA,application->getTrustEngine()); a++; } - catch (SAMLException&) { + catch (exception&) { m_log->warn("assertion failed to validate, removing it from response"); response->removeAssertion(a); } } // Run it through the filter. - return make_pair(response,filter(response,application,source)); + return make_pair(response,filter(response,application,AA)); } } - catch (SAMLException& e) { - m_log->error("caught SAML exception during query to AA: %s", e.what()); - annotateException(&e,AA); + catch (exception& e) { + m_log->error("caught exception during query to AA: %s", e.what()); + throw; } m_log->error("no response obtained"); @@ -940,11 +952,11 @@ pair MemorySessionCacheEntry::getNewResponse( } SAMLResponse* MemorySessionCacheEntry::filter( - const SAMLResponse* r, const IApplication* application, const IEntityDescriptor* source + const SAMLResponse* r, const IApplication* application, const RoleDescriptor* role ) const { #ifdef _DEBUG - saml::NDC ndc("filter"); + xmltooling::NDC ndc("filter"); #endif // Make a copy of the original and process that against the AAP. @@ -955,11 +967,11 @@ SAMLResponse* MemorySessionCacheEntry::filter( for (unsigned long j=0; j < copies.size();) { try { // Finally, filter the content. - AAP::apply(application->getAAPProviders(),*(copies[j]),source); + shibboleth::AAP::apply(application->getAAPProviders(),*(copies[j]),role); j++; } - catch (SAMLException&) { + catch (exception&) { m_log->info("no statements remain after AAP, removing assertion"); copy->removeAssertion(j); } @@ -1139,16 +1151,17 @@ bool MemorySessionCache::setBackingStore(ISessionCacheStore* store) DDF MemorySessionCache::receive(const DDF& in) { #ifdef _DEBUG - saml::NDC ndc("receive"); + xmltooling::NDC ndc("receive"); #endif // Find application. + saml::Locker confLocker(ShibTargetConfig::getConfig().getINI()); const char* aid=in["application_id"].string(); const IApplication* app=aid ? ShibTargetConfig::getConfig().getINI()->getApplication(aid) : NULL; if (!app) { // Something's horribly wrong. m_log->error("couldn't find application (%s) for session", aid ? aid : "(missing)"); - throw SAMLException("Unable to locate application for session, deleted?"); + throw ConfigurationException("Unable to locate application for session, deleted?"); } if (!strcmp(in.name(),"SessionCache::find")) { @@ -1167,7 +1180,7 @@ DDF MemorySessionCache::receive(const DDF& in) entry->unlock(); return dup; } - catch (SAMLException&) { + catch (exception&) { remove(key,app,client_address); throw; } @@ -1193,13 +1206,26 @@ DDF MemorySessionCache::receive(const DDF& in) throw SAMLException("Required parameters missing in call to SessionCache::insert"); int minor=in["minor_version"].integer(); - // Locate role descriptor to use in filtering. - Metadata m(app->getMetadataProviders()); - const IEntityDescriptor* site=m.lookup(provider_id); + // Locate entity descriptor to use in filtering. + MetadataProvider* m=app->getMetadataProvider(); + xmltooling::Locker locker(m); + const EntityDescriptor* site=m->getEntityDescriptor(provider_id); if (!site) { m_log->error("unable to locate issuing identity provider's metadata"); throw MetadataException("Unable to locate identity provider's metadata."); } + const RoleDescriptor* role=site->getAttributeAuthorityDescriptor(samlconstants::SAML11_PROTOCOL_ENUM); + if (!role) + role=site->getAttributeAuthorityDescriptor(samlconstants::SAML10_PROTOCOL_ENUM); + if (!role) + role=site->getIDPSSODescriptor(samlconstants::SAML11_PROTOCOL_ENUM); + if (!role) + role=site->getIDPSSODescriptor(samlconstants::SAML10_PROTOCOL_ENUM); + if (!role) { + m_log->error("unable to locate attribute-issuing role in identity provider's metadata"); + throw MetadataException("Unable to locate attribute-issuing role in identity provider's metadata."); + } + // Deserialize XML for insert method. istringstream subis(subject); auto_ptr pSubject(new SAMLSubject(subis)); @@ -1207,19 +1233,19 @@ DDF MemorySessionCache::receive(const DDF& in) auto_ptr pTokens(new SAMLResponse(tokis,minor)); // Insert the data and return the cache key. - string key=insert(app,site,client_address,pSubject.get(),authn_context,pTokens.get()); + string key=insert(app,role,client_address,pSubject.get(),authn_context,pTokens.get()); DDF out(NULL); out.structure(); out.addmember("key").string(key.c_str()); return out; } - throw ListenerException("Unsupported operation ($1)",saml::params(1,in.name())); + throw ListenerException("Unsupported operation ($1)",xmltooling::params(1,in.name())); } string MemorySessionCache::insert( const IApplication* application, - const IEntityDescriptor* source, + const RoleDescriptor* role, const char* client_addr, const SAMLSubject* subject, const char* authnContext, @@ -1227,7 +1253,7 @@ string MemorySessionCache::insert( ) { #ifdef _DEBUG - saml::NDC ndc("insert"); + xmltooling::NDC ndc("insert"); #endif SAMLIdentifier id; @@ -1241,20 +1267,20 @@ string MemorySessionCache::insert( this, key.get(), application, - source, + role, client_addr, subject, authnContext, tokens ) ); - entry->populate(application,source,true); + entry->populate(application,dynamic_cast(role->getParent()),true); if (m_sink) { HRESULT hr=m_sink->onCreate(key.get(),application,entry.get(),1,tokens->getMinorVersion(),entry->created()); if (FAILED(hr)) { m_log->error("cache store returned failure while storing new entry"); - throw SAMLException(hr,"Unable to record new session in cache store."); + throw IOException("Unable to record new session in cache store."); } } @@ -1268,7 +1294,7 @@ string MemorySessionCache::insert( ISessionCacheEntry* MemorySessionCache::find(const char* key, const IApplication* application, const char* client_addr) { #ifdef _DEBUG - saml::NDC ndc("find"); + xmltooling::NDC ndc("find"); #endif m_log->debug("searching memory cache for key (%s)", key); @@ -1303,20 +1329,35 @@ ISessionCacheEntry* MemorySessionCache::find(const char* key, const IApplication if (m_log->isDebugEnabled()) m_log->debug("loading cache entry (ID: %s) back into memory for application (%s)", key, appid.c_str()); - // Locate role descriptor to use in filtering. - Metadata m(eapp->getMetadataProviders()); - const IEntityDescriptor* site=m.lookup(pid.c_str()); + // Locate role to use in filtering. + MetadataProvider* m=eapp->getMetadataProvider(); + xmltooling::Locker locker(m); + const EntityDescriptor* site=m->getEntityDescriptor(pid.c_str()); if (!site) { m_log->error("unable to locate issuing identity provider's metadata"); if (FAILED(m_sink->onDelete(key))) m_log->error("cache store returned failure during delete"); return NULL; } + const RoleDescriptor* role=site->getAttributeAuthorityDescriptor(samlconstants::SAML11_PROTOCOL_ENUM); + if (!role) + role=site->getAttributeAuthorityDescriptor(samlconstants::SAML10_PROTOCOL_ENUM); + if (!role) + role=site->getIDPSSODescriptor(samlconstants::SAML11_PROTOCOL_ENUM); + if (!role) + role=site->getIDPSSODescriptor(samlconstants::SAML10_PROTOCOL_ENUM); + if (!role) { + m_log->error("unable to locate attribute-issuing role in identity provider's metadata"); + if (FAILED(m_sink->onDelete(key))) + m_log->error("cache store returned failure during delete"); + return NULL; + } + MemorySessionCacheEntry* entry = new MemorySessionCacheEntry( this, key, eapp, - site, + role, addr.c_str(), sub.c_str(), ac.c_str(), @@ -1354,25 +1395,25 @@ ISessionCacheEntry* MemorySessionCache::find(const char* key, const IApplication try { HRESULT hr=i->second->isValid(application, client_addr); if (FAILED(hr)) { - Metadata m(application->getMetadataProviders()); + MetadataProvider* m=application->getMetadataProvider(); + xmltooling::Locker locker(m); switch (hr) { case SESSION_E_EXPIRED: { - InvalidSessionException ex(SESSION_E_EXPIRED, "Your session has expired, and you must re-authenticate."); - annotateException(&ex,m.lookup(i->second->getProviderId())); // throws it + opensaml::RetryableProfileException ex("Your session has expired, and you must re-authenticate."); + annotateException(&ex,m->getEntityDescriptor(i->second->getProviderId(),false)); // throws it } case SESSION_E_ADDRESSMISMATCH: { - InvalidSessionException ex( - SESSION_E_ADDRESSMISMATCH, + opensaml::RetryableProfileException ex( "Your IP address ($1) does not match the address recorded at the time the session was established.", - saml::params(1,client_addr) + xmltooling::params(1,client_addr) ); - annotateException(&ex,m.lookup(i->second->getProviderId())); // throws it + annotateException(&ex,m->getEntityDescriptor(i->second->getProviderId(),false)); // throws it } default: { - InvalidSessionException ex(hr, "Your session is invalid."); - annotateException(&ex,m.lookup(i->second->getProviderId())); // throws it + opensaml::RetryableProfileException ex("Your session is invalid."); + annotateException(&ex,m->getEntityDescriptor(i->second->getProviderId(),false)); // throws it } } } @@ -1388,8 +1429,9 @@ ISessionCacheEntry* MemorySessionCache::find(const char* key, const IApplication try { // Make sure the entry has valid tokens. - Metadata m(application->getMetadataProviders()); - i->second->populate(application,m.lookup(i->second->getProviderId())); + MetadataProvider* m=application->getMetadataProvider(); + xmltooling::Locker locker(m); + i->second->populate(application,m->getEntityDescriptor(i->second->getProviderId())); } catch (...) { i->second->unlock(); @@ -1402,7 +1444,7 @@ ISessionCacheEntry* MemorySessionCache::find(const char* key, const IApplication void MemorySessionCache::remove(const char* key, const IApplication* application, const char* client_addr) { #ifdef _DEBUG - saml::NDC ndc("remove"); + xmltooling::NDC ndc("remove"); #endif m_log->debug("removing cache entry with key (%s)", key); @@ -1443,7 +1485,7 @@ void MemorySessionCache::remove(const char* key, const IApplication* application void MemorySessionCache::dormant(const char* key) { #ifdef _DEBUG - saml::NDC ndc("dormant"); + xmltooling::NDC ndc("dormant"); #endif m_log->debug("purging old cache entry with key (%s)", key); @@ -1480,7 +1522,7 @@ void MemorySessionCache::dormant(const char* key) void MemorySessionCache::cleanup() { #ifdef _DEBUG - saml::NDC ndc("cleanup()"); + xmltooling::NDC ndc("cleanup()"); #endif int rerun_timer = 0; diff --git a/shib-target/shib-config.cpp b/shib-target/shib-config.cpp index 263e216..80360b6 100644 --- a/shib-target/shib-config.cpp +++ b/shib-target/shib-config.cpp @@ -58,9 +58,6 @@ PlugManager::Factory SAML1ArtifactFactory; PlugManager::Factory ShibLogoutFactory; //PlugManager::Factory htaccessFactory; -SAML_EXCEPTION_FACTORY(ListenerException); -SAML_EXCEPTION_FACTORY(ConfigurationException); - ShibTargetConfig& ShibTargetConfig::getConfig() { return g_Config; @@ -96,8 +93,6 @@ bool STConfig::init(const char* schemadir) } // Register built-in plugin types. - REGISTER_EXCEPTION_FACTORY(ListenerException); - REGISTER_EXCEPTION_FACTORY(ConfigurationException); samlConf.getPlugMgr().regFactory(shibtarget::XML::MemorySessionCacheType,&MemoryCacheFactory); samlConf.getPlugMgr().regFactory(shibtarget::XML::LegacyRequestMapType,&XMLRequestMapFactory); diff --git a/shib-target/shib-handlers.cpp b/shib-target/shib-handlers.cpp index 151ea29..b6e3187 100644 --- a/shib-target/shib-handlers.cpp +++ b/shib-target/shib-handlers.cpp @@ -26,9 +26,12 @@ #include #include #include +#include +#include #include #include #include +#include #ifdef HAVE_UNISTD_H # include @@ -38,6 +41,7 @@ using namespace shibsp; using namespace shibtarget; using namespace shibboleth; using namespace saml; +using namespace opensaml::saml2md; using namespace log4cpp; using namespace std; @@ -129,7 +133,7 @@ pair SessionInitiator::run(ShibTarget* st, bool isHandler) const if (home.first) resource=home.second; else - throw FatalProfileException("Session initiator requires a target parameter or a homeURL application property."); + throw opensaml::FatalProfileException("Session initiator requires a target parameter or a homeURL application property."); } else if (!option) { dupresource=resource; @@ -139,20 +143,24 @@ pair SessionInitiator::run(ShibTarget* st, bool isHandler) const if (option) { // Here we actually use metadata to invoke the SSO service directly. // The only currently understood binding is the Shibboleth profile. - Metadata m(app->getMetadataProviders()); - const IEntityDescriptor* entity=m.lookup(option); + + MetadataProvider* m=app->getMetadataProvider(); + xmltooling::Locker locker(m); + const EntityDescriptor* entity=m->getEntityDescriptor(option); if (!entity) - throw MetadataException("Session initiator unable to locate metadata for provider ($1).", params(1,option)); - const IIDPSSODescriptor* role=entity->getIDPSSODescriptor(shibspconstants::SHIB1_PROTOCOL_ENUM); + throw MetadataException("Session initiator unable to locate metadata for provider ($1).", xmltooling::params(1,option)); + const IDPSSODescriptor* role=entity->getIDPSSODescriptor(shibspconstants::SHIB1_PROTOCOL_ENUM); if (!role) throw MetadataException( - "Session initiator unable to locate a Shibboleth-aware identity provider role for provider ($1).", params(1,option) + "Session initiator unable to locate a Shibboleth-aware identity provider role for provider ($1).", + xmltooling::params(1,option) ); - const IEndpointManager* SSO=role->getSingleSignOnServiceManager(); - const IEndpoint* ep=SSO->getEndpointByBinding(shibspconstants::SHIB1_AUTHNREQUEST_PROFILE_URI); + const EndpointType* ep=EndpointManager(role->getSingleSignOnServices()).getByBinding( + shibspconstants::SHIB1_AUTHNREQUEST_PROFILE_URI + ); if (!ep) throw MetadataException( - "Session initiator unable to locate compatible SSO service for provider ($1).", params(1,option) + "Session initiator unable to locate compatible SSO service for provider ($1).", xmltooling::params(1,option) ); auto_ptr_char dest(ep->getLocation()); return ShibAuthnRequest( @@ -189,7 +197,7 @@ pair SessionInitiator::run(ShibTarget* st, bool isHandler) const return make_pair(true, st->sendRedirect(wayfURL.second)); } - throw UnsupportedProfileException("Unsupported WAYF binding ($1).", params(1,getProperties()->getString("wayfBinding").second)); + throw opensaml::BindingException("Unsupported WAYF binding ($1).", xmltooling::params(1,getProperties()->getString("wayfBinding").second)); } // Handles Shib 1.x AuthnRequest profile. @@ -275,7 +283,7 @@ SAML1Consumer::~SAML1Consumer() DDF SAML1Consumer::receive(const DDF& in) { #ifdef _DEBUG - saml::NDC ndc("receive"); + xmltooling::NDC ndc("receive"); #endif Category& log=Category::getInstance(SHIBT_LOGCAT".SAML1Consumer"); @@ -298,9 +306,10 @@ DDF SAML1Consumer::receive(const DDF& in) log.debug("recipient: %s", recipient); log.debug("application: %s", app->getId()); - // Access the application config. It's already locked behind us. + // Access the application config. STConfig& stc=static_cast(ShibTargetConfig::getConfig()); IConfig* conf=stc.getINI(); + saml::Locker confLocker(conf); auto_ptr_XMLCh wrecipient(recipient); @@ -321,8 +330,10 @@ DDF SAML1Consumer::receive(const DDF& in) if (!version.first) version.second=1; - const IRoleDescriptor* role=NULL; - Metadata m(app->getMetadataProviders()); + const EntityDescriptor* provider=NULL; + const RoleDescriptor* role=NULL; + MetadataProvider* m=app->getMetadataProvider(); + xmltooling::Locker locker(m); SAMLBrowserProfile::BrowserProfileResponse bpr; try { @@ -361,16 +372,15 @@ DDF SAML1Consumer::receive(const DDF& in) } // Try and map to metadata (again). - // Once the metadata layer is in the SAML core, the repetition should be fixed. - const IEntityDescriptor* provider=m.lookup(bpr.assertion->getIssuer()); + // Once the metadata layer is in the SAML core, the repetition will be fixed. + provider=m->getEntityDescriptor(bpr.assertion->getIssuer()); if (!provider && bpr.authnStatement->getSubject()->getNameIdentifier() && bpr.authnStatement->getSubject()->getNameIdentifier()->getNameQualifier()) - provider=m.lookup(bpr.authnStatement->getSubject()->getNameIdentifier()->getNameQualifier()); + provider=m->getEntityDescriptor(bpr.authnStatement->getSubject()->getNameIdentifier()->getNameQualifier()); if (provider) { - const IIDPSSODescriptor* IDP=provider->getIDPSSODescriptor( - version.second==1 ? saml::XML::SAML11_PROTOCOL_ENUM : saml::XML::SAML10_PROTOCOL_ENUM + role=provider->getIDPSSODescriptor( + version.second==1 ? samlconstants::SAML11_PROTOCOL_ENUM : samlconstants::SAML10_PROTOCOL_ENUM ); - role=IDP; } // This isn't likely, since the profile must have found a role. @@ -388,19 +398,18 @@ DDF SAML1Consumer::receive(const DDF& in) // Verify the client address matches authentication auto_ptr_char this_ip(wip); if (strcmp(client_address, this_ip.get())) { - FatalProfileException ex( - SESSION_E_ADDRESSMISMATCH, + opensaml::FatalProfileException ex( "Your client's current address ($1) differs from the one used when you authenticated " "to your identity provider. To correct this problem, you may need to bypass a proxy server. " "Please contact your local support staff or help desk for assistance.", - params(1,client_address) + xmltooling::params(1,client_address) ); annotateException(&ex,role); // throws it } } } } - catch (SAMLException&) { + catch (exception&) { bpr.clear(); throw; } @@ -411,40 +420,29 @@ DDF SAML1Consumer::receive(const DDF& in) throw; #else SAMLException e("An unexpected error occurred while creating your session."); - annotateException(&e,role); + shibboleth::annotateException(&e,role); #endif } // It passes all our tests -- create a new session. log.info("creating new session"); - DDF out; - try { - // Insert into cache. - auto_ptr_char authContext(bpr.authnStatement->getAuthMethod()); - string key=conf->getSessionCache()->insert( - app, - role->getEntityDescriptor(), - client_address, - bpr.authnStatement->getSubject(), - authContext.get(), - bpr.response - ); - // objects owned by cache now - log.debug("new session id: %s", key.c_str()); - auto_ptr_char oname(role->getEntityDescriptor()->getId()); - out=DDF(NULL).structure(); - out.addmember("key").string(key.c_str()); - out.addmember("provider_id").string(oname.get()); - } - catch (...) { -#ifdef _DEBUG - throw; -#else - SAMLException e("An unexpected error occurred while creating your session."); - annotateException(&e,role); -#endif - } + // Insert into cache. + auto_ptr_char authContext(bpr.authnStatement->getAuthMethod()); + string key=conf->getSessionCache()->insert( + app, + role, + client_address, + bpr.authnStatement->getSubject(), + authContext.get(), + bpr.response + ); + // objects owned by cache now + log.debug("new session id: %s", key.c_str()); + auto_ptr_char oname(provider->getEntityID()); + DDF out=DDF(NULL).structure(); + out.addmember("key").string(key.c_str()); + out.addmember("provider_id").string(oname.get()); return out; } @@ -519,7 +517,7 @@ pair SAML1Consumer::run(ShibTarget* st, bool isHandler) const out=st->getConfig()->getListener()->send(in); if (!out["key"].isstring()) - throw FatalProfileException("Remote processing of SAML 1.x Browser profile did not return a usable session key."); + throw opensaml::FatalProfileException("Remote processing of SAML 1.x Browser profile did not return a usable session key."); string key=out["key"].string(); st->log(ShibTarget::LogLevelDebug, string("profile processing succeeded, new session created (") + key + ")"); @@ -597,7 +595,7 @@ pair ShibLogout::run(ShibTarget* st, bool isHandler) const try { st->getConfig()->getSessionCache()->remove(session_id,st->getApplication(),st->getRemoteAddr()); } - catch (SAMLException& e) { + catch (exception& e) { st->log(ShibTarget::LogLevelError, string("logout processing failed with exception: ") + e.what()); } #ifndef _DEBUG diff --git a/shib-target/shib-ini.cpp b/shib-target/shib-ini.cpp index f6bd9c2..eaf3dbf 100644 --- a/shib-target/shib-ini.cpp +++ b/shib-target/shib-ini.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -40,6 +41,7 @@ using namespace shibsp; using namespace shibtarget; using namespace shibboleth; using namespace saml; +using namespace opensaml::saml1; using namespace opensaml::saml2md; using namespace xmltooling; using namespace log4cpp; @@ -67,14 +69,11 @@ namespace shibtarget { const char* getHash() const {return m_hash.c_str();} Iterator getAttributeDesignators() const; Iterator getAAPProviders() const; - Iterator getMetadataProviders() const; - Iterator getTrustProviders() const; + MetadataProvider* getMetadataProvider() const; + TrustEngine* getTrustEngine() const; Iterator getAudiences() const; - const PropertySet* getCredentialUse(const IEntityDescriptor* provider) const; + const PropertySet* getCredentialUse(const EntityDescriptor* provider) const; - const MetadataProvider* getMetadataProvider() const; - const TrustEngine* getTrustEngine() const; - const SAMLBrowserProfile* getBrowserProfile() const {return m_profile;} const SAMLBinding* getBinding(const XMLCh* binding) const {return XMLString::compareString(SAMLBinding::SOAP,binding) ? NULL : m_binding;} @@ -82,8 +81,8 @@ namespace shibtarget { void validateToken( SAMLAssertion* token, time_t t=0, - const IRoleDescriptor* role=NULL, - const Iterator& trusts=EMPTY(ITrust*) + const RoleDescriptor* role=NULL, + const TrustEngine* trust=NULL ) const; const IHandler* getDefaultSessionInitiator() const; const IHandler* getSessionInitiatorById(const char* id) const; @@ -102,8 +101,6 @@ namespace shibtarget { string m_hash; vector m_designators; vector m_aaps; - vector m_metadatas; - vector m_trusts; MetadataProvider* m_metadata; TrustEngine* m_trust; vector m_audiences; @@ -277,12 +274,12 @@ XMLApplication::XMLApplication( hobj=dynamic_cast(hplug); if (!hobj) { delete hplug; - throw UnsupportedProfileException( + throw UnsupportedExtensionException( "Plugin for binding ($1) does not implement IHandler interface.",saml::params(1,bindprop) ); } } - catch (SAMLException& ex) { + catch (exception& ex) { // If we get here, the handler's not built, so dispose of the property set. log.error("caught exception processing a handler element: %s",ex.what()); delete hprops; @@ -363,7 +360,7 @@ XMLApplication::XMLApplication( IHandler* h1=dynamic_cast(hplug); if (!h1) { delete hplug; - throw UnsupportedProfileException( + throw UnsupportedExtensionException( "Plugin for binding ($1) does not implement IHandler interface.",saml::params(1,b1.get()) ); } @@ -376,7 +373,7 @@ XMLApplication::XMLApplication( IHandler* h2=dynamic_cast(hplug); if (!h2) { delete hplug; - throw UnsupportedProfileException( + throw UnsupportedExtensionException( "Plugin for binding ($1) does not implement IHandler interface.",saml::params(1,b2.get()) ); } @@ -417,7 +414,7 @@ XMLApplication::XMLApplication( log.crit("plugin was not an AAP provider"); } } - catch (SAMLException& ex) { + catch (exception& ex) { log.crit("error building AAP provider: %s",ex.what()); } } @@ -432,36 +429,25 @@ XMLApplication::XMLApplication( xmltooling::auto_ptr_char type(static_cast(nlist->item(i))->getAttributeNS(NULL,SHIBT_L(type))); log.info("building metadata provider of type %s...",type.get()); try { - // Old plugins...TODO: remove - IPlugIn* plugin=shibConf.getPlugMgr().newPlugin(type.get(),static_cast(nlist->item(i))); - IMetadata* md=dynamic_cast(plugin); - if (md) - m_metadatas.push_back(md); - else { - delete plugin; - log.crit("plugin was not a metadata provider"); - } - - // New plugins... if (!strcmp(type.get(),"edu.internet2.middleware.shibboleth.common.provider.XMLMetadata") || !strcmp(type.get(),"edu.internet2.middleware.shibboleth.metadata.provider.XMLMetadata")) { - os2providers.push_back( + auto_ptr mp( samlConf.MetadataProviderManager.newPlugin( FILESYSTEM_METADATA_PROVIDER,static_cast(nlist->item(i)) - ) - ); + ) + ); + mp->init(); + os2providers.push_back(mp.release()); } else { - os2providers.push_back( + auto_ptr mp( samlConf.MetadataProviderManager.newPlugin(type.get(),static_cast(nlist->item(i))) - ); + ); + mp->init(); + os2providers.push_back(mp.release()); } } - catch (XMLToolingException& ex) { - log.crit("error building metadata provider: %s",ex.what()); - for_each(os2providers.begin(), os2providers.end(), xmltooling::cleanup()); - } - catch (SAMLException& ex) { + catch (exception& ex) { log.crit("error building metadata provider: %s",ex.what()); } } @@ -469,7 +455,7 @@ XMLApplication::XMLApplication( if (os2providers.size()==1) m_metadata=os2providers.front(); - else { + else if (os2providers.size()>1) { try { m_metadata = samlConf.MetadataProviderManager.newPlugin(CHAINING_METADATA_PROVIDER,NULL); ChainingMetadataProvider* chainMeta = dynamic_cast(m_metadata); @@ -478,8 +464,8 @@ XMLApplication::XMLApplication( os2providers.pop_back(); } } - catch (XMLToolingException& ex) { - log.crit("error building metadata provider: %s",ex.what()); + catch (exception& ex) { + log.crit("error building chaining metadata provider wrapper: %s",ex.what()); for_each(os2providers.begin(), os2providers.end(), xmltooling::cleanup()); } } @@ -493,17 +479,6 @@ XMLApplication::XMLApplication( xmltooling::auto_ptr_char type(static_cast(nlist->item(i))->getAttributeNS(NULL,SHIBT_L(type))); log.info("building trust provider of type %s...",type.get()); try { - // Old plugins...TODO: remove - IPlugIn* plugin=shibConf.getPlugMgr().newPlugin(type.get(),static_cast(nlist->item(i))); - ITrust* trust=dynamic_cast(plugin); - if (trust) - m_trusts.push_back(trust); - else { - delete plugin; - log.crit("plugin was not a trust provider"); - } - - // New plugins... if (!m_trust) { // For compatibility with old engine types, we're assuming a Shib engine is likely, // which requires chaining, so we'll build that regardless. @@ -535,10 +510,7 @@ XMLApplication::XMLApplication( ); } } - catch (XMLToolingException& ex) { - log.crit("error building trust provider: %s",ex.what()); - } - catch (SAMLException& ex) { + catch (exception& ex) { log.crit("error building trust provider: %s",ex.what()); } } @@ -563,11 +535,11 @@ XMLApplication::XMLApplication( // Really finally, build local browser profile and binding objects. m_profile=new ShibBrowserProfile( this, - getMetadataProviders(), - getTrustProviders() + getMetadataProvider(), + getTrustEngine() ); m_bindingHook=new ShibHTTPHook( - getTrustProviders(), + getTrustEngine(), creds ); m_binding=SAMLBinding::getInstance(SAMLBinding::SOAP); @@ -579,7 +551,7 @@ XMLApplication::XMLApplication( bptr->addHook(m_bindingHook,m_bindingHook); // the hook is its own global context } } - catch (SAMLException& e) { + catch (exception& e) { log.errorStream() << "Error while processing applicaton element: " << e.what() << CategoryStream::ENDLINE; cleanup(); throw; @@ -600,9 +572,6 @@ void XMLApplication::cleanup() delete m_profile; for_each(m_handlers.begin(),m_handlers.end(),xmltooling::cleanup()); - delete m_trust; - delete m_metadata; - delete m_credDefault; #ifdef HAVE_GOOD_STL for_each(m_credMap.begin(),m_credMap.end(),xmltooling::cleanup_pair()); @@ -611,8 +580,9 @@ void XMLApplication::cleanup() #endif for_each(m_designators.begin(),m_designators.end(),xmltooling::cleanup()); for_each(m_aaps.begin(),m_aaps.end(),xmltooling::cleanup()); - for_each(m_metadatas.begin(),m_metadatas.end(),xmltooling::cleanup()); - for_each(m_trusts.begin(),m_trusts.end(),xmltooling::cleanup()); + + delete m_trust; + delete m_metadata; } short XMLApplication::acceptNode(const DOMNode* node) const @@ -698,14 +668,14 @@ Iterator XMLApplication::getAAPProviders() const return (m_aaps.empty() && m_base) ? m_base->getAAPProviders() : m_aaps; } -Iterator XMLApplication::getMetadataProviders() const +MetadataProvider* XMLApplication::getMetadataProvider() const { - return (m_metadatas.empty() && m_base) ? m_base->getMetadataProviders() : m_metadatas; + return (!m_metadata && m_base) ? m_base->getMetadataProvider() : m_metadata; } -Iterator XMLApplication::getTrustProviders() const +TrustEngine* XMLApplication::getTrustEngine() const { - return (m_trusts.empty() && m_base) ? m_base->getTrustProviders() : m_trusts; + return (!m_trust && m_base) ? m_base->getTrustEngine() : m_trust; } Iterator XMLApplication::getAudiences() const @@ -713,51 +683,41 @@ Iterator XMLApplication::getAudiences() const return (m_audiences.empty() && m_base) ? m_base->getAudiences() : m_audiences; } -const PropertySet* XMLApplication::getCredentialUse(const IEntityDescriptor* provider) const +const PropertySet* XMLApplication::getCredentialUse(const EntityDescriptor* 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->getEntityID()); if (i!=m_credMap.end()) return i->second; - const IEntitiesDescriptor* group=provider->getEntitiesDescriptor(); + const EntitiesDescriptor* group=dynamic_cast(provider->getParent()); while (group) { if (group->getName()) { i=m_credMap.find(group->getName()); if (i!=m_credMap.end()) return i->second; } - group=group->getEntitiesDescriptor(); + group=dynamic_cast(group->getParent()); } #else map::const_iterator i=m_credMap.begin(); for (; i!=m_credMap.end(); i++) { if (!XMLString::compareString(i->first,provider->getId())) return i->second; - const IEntitiesDescriptor* group=provider->getEntitiesDescriptor(); + const EntitiesDescriptor* group=dynamic_cast(provider->getParent()); while (group) { if (!XMLString::compareString(i->first,group->getName())) return i->second; - group=group->getEntitiesDescriptor(); + group=dynamic_cast(group->getParent()); } } #endif return m_credDefault; } -const MetadataProvider* XMLApplication::getMetadataProvider() const -{ - return (!m_metadata && m_base) ? m_base->getMetadataProvider() : m_metadata; -} - -const TrustEngine* XMLApplication::getTrustEngine() const -{ - return (!m_trust && m_base) ? m_base->getTrustEngine() : m_trust; -} - -void XMLApplication::validateToken(SAMLAssertion* token, time_t ts, const IRoleDescriptor* role, const Iterator& trusts) const +void XMLApplication::validateToken(SAMLAssertion* token, time_t ts, const RoleDescriptor* role, const TrustEngine* trust) const { #ifdef _DEBUG xmltooling::NDC ndc("validateToken"); @@ -769,10 +729,10 @@ void XMLApplication::validateToken(SAMLAssertion* token, time_t ts, const IRoleD if (ts>0) { const SAMLDateTime* notBefore=token->getNotBefore(); if (notBefore && ts+config.clock_skew_secs < notBefore->getEpoch()) - throw ExpiredAssertionException("Assertion is not yet valid."); + throw opensaml::FatalProfileException("Assertion is not yet valid."); const SAMLDateTime* notOnOrAfter=token->getNotOnOrAfter(); if (notOnOrAfter && notOnOrAfter->getEpoch() <= ts-config.clock_skew_secs) - throw ExpiredAssertionException("Assertion is no longer valid."); + throw opensaml::FatalProfileException("Assertion is no longer valid."); } // Now we process conditions. Only audience restrictions at the moment. @@ -784,29 +744,40 @@ void XMLApplication::validateToken(SAMLAssertion* token, time_t ts, const IRoleD ostringstream os; os << *cond; log.error("unrecognized Condition in assertion (%s)",os.str().c_str()); - throw UnsupportedExtensionException("Assertion contains an unrecognized condition."); + throw xmltooling::UnknownExtensionException("Assertion contains an unrecognized condition."); } else if (!ac->eval(getAudiences())) { ostringstream os; os << *ac; log.error("unacceptable AudienceRestrictionCondition in assertion (%s)",os.str().c_str()); - throw UnsupportedProfileException("Assertion contains an unacceptable AudienceRestrictionCondition."); + throw opensaml::FatalProfileException("Assertion contains an unacceptable AudienceRestrictionCondition."); } } - if (!role) { + if (!role || !trust) { log.warn("no metadata provided, so no signature validation was performed"); return; } - const PropertySet* credUse=getCredentialUse(role->getEntityDescriptor()); + const PropertySet* credUse=getCredentialUse(dynamic_cast(role->getParent())); pair signedAssertions=credUse ? credUse->getBool("signedAssertions") : make_pair(false,false); - Trust t(trusts); - if (token->isSigned() && !t.validate(*token,role)) - throw TrustException("Assertion signature did not validate."); + if (token->isSigned()) { + + // This will all change, but for fun, we'll port the object from OS1->OS2 for validation. + stringstream s; + s << *token; + DOMDocument* doc = XMLToolingConfig::getConfig().getValidatingParser().parse(s); + XercesJanitor jdoc(doc); + auto_ptr os2ass(AssertionBuilder::buildAssertion()); + os2ass->unmarshall(doc->getDocumentElement(),true); + jdoc.release(); + + if (!trust->validate(*(os2ass->getSignature()),*role)) + throw xmltooling::XMLSecurityException("Assertion signature did not validate."); + } else if (signedAssertions.first && signedAssertions.second) - throw TrustException("Assertion was unsigned, violating policy based on the issuer."); + throw xmltooling::XMLSecurityException("Assertion was unsigned, violating policy based on the issuer."); } const IHandler* XMLApplication::getDefaultSessionInitiator() const @@ -961,7 +932,7 @@ void XMLConfigImpl::init(bool first) SAMLConfig::getConfig().saml_register_extension(path.get(),exts); log.debug("loaded global extension library %s",path.get()); } - catch (SAMLException& e) { + catch (exception& e) { const XMLCh* fatal=exts->getAttributeNS(NULL,SHIBT_L(fatal)); if (fatal && (*fatal==chLatin_t || *fatal==chDigit_1)) { log.fatal("unable to load mandatory global extension library %s: %s", path.get(), e.what()); @@ -984,7 +955,7 @@ void XMLConfigImpl::init(bool first) SAMLConfig::getConfig().saml_register_extension(path.get(),exts); log.debug("loaded Global extension library %s",path.get()); } - catch (SAMLException& e) { + catch (exception& e) { const XMLCh* fatal=exts->getAttributeNS(NULL,SHIBT_L(fatal)); if (fatal && (*fatal==chLatin_t || *fatal==chDigit_1)) { log.fatal("unable to load mandatory Global extension library %s: %s", path.get(), e.what()); @@ -1008,7 +979,7 @@ void XMLConfigImpl::init(bool first) SAMLConfig::getConfig().saml_register_extension(path.get(),exts); log.debug("loaded Local extension library %s",path.get()); } - catch (SAMLException& e) { + catch (exception& e) { const XMLCh* fatal=exts->getAttributeNS(NULL,SHIBT_L(fatal)); if (fatal && (*fatal==chLatin_t || *fatal==chDigit_1)) { log.fatal("unable to load mandatory Local extension library %s: %s", path.get(), e.what()); @@ -1168,7 +1139,7 @@ void XMLConfigImpl::init(bool first) } } } - catch (SAMLException& ex) { + catch (exception& ex) { log.crit("error building credentials provider: %s",ex.what()); } } @@ -1196,7 +1167,7 @@ void XMLConfigImpl::init(bool first) } } } - catch (SAMLException& ex) { + catch (exception& ex) { log.crit("error building Attribute factory: %s",ex.what()); } } @@ -1222,11 +1193,7 @@ void XMLConfigImpl::init(bool first) m_appmap[iapp->getId()]=iapp.release(); } } - catch (xmltooling::XMLToolingException& e) { - log.errorStream() << "Error while loading SP configuration: " << e.what() << CategoryStream::ENDLINE; - throw ConfigurationException(e.what()); - } - catch (SAMLException& e) { + catch (exception& e) { log.errorStream() << "Error while loading SP configuration: " << e.what() << CategoryStream::ENDLINE; throw ConfigurationException(e.what()); } diff --git a/shib-target/shib-target.cpp b/shib-target/shib-target.cpp index f39af98..acf5fce 100644 --- a/shib-target/shib-target.cpp +++ b/shib-target/shib-target.cpp @@ -39,21 +39,24 @@ #include #include #include +#include #ifndef HAVE_STRCASECMP # define strcasecmp stricmp #endif +using namespace shibsp; using namespace shibtarget; using namespace shibboleth; using namespace saml; +using namespace opensaml::saml2md; using namespace log4cpp; using namespace std; -using shibsp::PropertySet; using xmltooling::TemplateEngine; using xmltooling::XMLToolingException; using xmltooling::XMLToolingConfig; +using xmltooling::XMLHelper; namespace shibtarget { class CgiParse @@ -162,7 +165,7 @@ void ShibTarget::init( #endif if (m_priv->m_app) - throw SAMLException("Request initialization occurred twice!"); + throw XMLToolingException("Request initialization occurred twice!"); if (method) m_method = method; if (protocol) m_protocol = protocol; @@ -262,7 +265,7 @@ pair ShibTarget::doCheckAuthN(bool handler) if (!initiator) throw ConfigurationException( "No session initiator found with id ($1), check requireSessionWith command.", - params(1,requireSessionWith.second) + xmltooling::params(1,requireSessionWith.second) ); } else { @@ -283,9 +286,9 @@ pair ShibTarget::doCheckAuthN(bool handler) ); // Make a localized exception throw if the session isn't valid. if (!m_priv->m_cacheEntry) - throw InvalidSessionException("Session no longer valid."); + throw RetryableProfileException("Session no longer valid."); } - catch (SAMLException& e) { + catch (exception& e) { log(LogLevelError, string("session processing failed: ") + e.what()); // If no session is required, bail now. @@ -297,7 +300,7 @@ pair ShibTarget::doCheckAuthN(bool handler) return make_pair(true, returnOK()); // Try and cast down. - SAMLException* base = &e; + exception* base = &e; RetryableProfileException* trycast=dynamic_cast(base); if (trycast) { // Session is invalid but we can retry -- initiate a new session. @@ -308,7 +311,7 @@ pair ShibTarget::doCheckAuthN(bool handler) if (!initiator) throw ConfigurationException( "No session initiator found with id ($1), check requireSessionWith command.", - params(1,requireSessionWith.second) + xmltooling::params(1,requireSessionWith.second) ); } else { @@ -326,13 +329,6 @@ pair ShibTarget::doCheckAuthN(bool handler) log(LogLevelDebug, "doCheckAuthN succeeded"); return make_pair(false,(void*)NULL); } - catch (SAMLException& e) { // TODO: we're going to yank this handler... - tp.m_map["errorType"] = procState; - tp.m_map["errorText"] = e.what(); - if (targetURL) - tp.m_map["requestURL"] = m_url.substr(0,m_url.find('?')); - return make_pair(true,m_priv->sendError(this, "session", tp)); - } catch (XMLToolingException& e) { tp.m_map["errorType"] = procState; tp.m_map["errorText"] = e.what(); @@ -383,21 +379,21 @@ pair ShibTarget::doHandler(void) // Make sure this is SSL, if it should be if ((!handlerSSL.first || handlerSSL.second) && m_protocol != "https") - throw FatalProfileException("Blocked non-SSL access to Shibboleth handler."); + throw opensaml::FatalProfileException("Blocked non-SSL access to Shibboleth handler."); // We dispatch based on our path info. We know the request URL begins with or equals the handler URL, // so the path info is the next character (or null). const IHandler* handler=m_priv->m_app->getHandler(targetURL + strlen(handlerURL)); if (!handler) - throw SAMLException("Shibboleth handler invoked at an unconfigured location."); + throw opensaml::BindingException("Shibboleth handler invoked at an unconfigured location."); - if (saml::XML::isElementNamed(handler->getProperties()->getElement(),shibtarget::XML::SAML2META_NS,SHIBT_L(AssertionConsumerService))) + if (XMLHelper::isNodeNamed(handler->getProperties()->getElement(),samlconstants::SAML20MD_NS,SHIBT_L(AssertionConsumerService))) procState = "Session Creation Error"; - else if (saml::XML::isElementNamed(handler->getProperties()->getElement(),shibtarget::XML::SHIBTARGET_NS,SHIBT_L(SessionInitiator))) + else if (XMLHelper::isNodeNamed(handler->getProperties()->getElement(),shibtarget::XML::SHIBTARGET_NS,SHIBT_L(SessionInitiator))) procState = "Session Initiator Error"; - else if (saml::XML::isElementNamed(handler->getProperties()->getElement(),shibtarget::XML::SAML2META_NS,SHIBT_L(SingleLogoutService))) + else if (XMLHelper::isNodeNamed(handler->getProperties()->getElement(),samlconstants::SAML20MD_NS,SHIBT_L(SingleLogoutService))) procState = "Session Termination Error"; - else if (saml::XML::isElementNamed(handler->getProperties()->getElement(),shibtarget::XML::SHIBTARGET_NS,SHIBT_L(DiagnosticService))) + else if (XMLHelper::isNodeNamed(handler->getProperties()->getElement(),shibtarget::XML::SHIBTARGET_NS,SHIBT_L(DiagnosticService))) procState = "Diagnostics Error"; else procState = "Extension Service Error"; @@ -407,7 +403,7 @@ pair ShibTarget::doHandler(void) if (hret.first) return hret; - throw XMLToolingException("Configured Shibboleth handler failed to process the request."); + throw opensaml::BindingException("Configured Shibboleth handler failed to process the request."); } catch (MetadataException& e) { tp.m_map["errorText"] = e.what(); @@ -424,13 +420,6 @@ pair ShibTarget::doHandler(void) } throw; } - catch (SAMLException& e) { - tp.m_map["errorType"] = procState; - tp.m_map["errorText"] = e.what(); - if (targetURL) - tp.m_map["requestURL"] = m_url.substr(0,m_url.find('?')); - return make_pair(true,m_priv->sendError(this, "session", tp)); - } catch (XMLToolingException& e) { tp.m_map["errorType"] = procState; tp.m_map["errorText"] = e.what(); @@ -495,7 +484,7 @@ pair ShibTarget::doCheckAuthZ(void) ); } } - catch (SAMLException&) { + catch (exception&) { log(LogLevelError, "doCheckAuthZ: unable to obtain session information to pass to access control provider"); } } @@ -516,20 +505,13 @@ pair ShibTarget::doCheckAuthZ(void) else return make_pair(true,returnDecline()); } - catch (SAMLException& e) { + catch (exception& e) { tp.m_map["errorType"] = procState; tp.m_map["errorText"] = e.what(); if (targetURL) tp.m_map["requestURL"] = m_url.substr(0,m_url.find('?')); return make_pair(true,m_priv->sendError(this, "access", tp)); } - catch (XMLToolingException& e) { - tp.m_map["errorType"] = procState; - tp.m_map["errorText"] = e.what(); - if (targetURL) - tp.m_map["requestURL"] = m_url.substr(0,m_url.find('?')); - return make_pair(true,m_priv->sendError(this, "access", tp, &e)); - } #ifndef _DEBUG catch (...) { tp.m_map["errorType"] = procState; @@ -569,7 +551,7 @@ pair ShibTarget::doExportAssertions(bool requireSession) ); } } - catch (SAMLException&) { + catch (exception&) { log(LogLevelError, "unable to obtain session information to export into request headers"); // If we have to have a session, then this is a fatal error. if (requireSession) @@ -580,7 +562,7 @@ pair ShibTarget::doExportAssertions(bool requireSession) // Still no data? if (!m_priv->m_cacheEntry) { if (requireSession) - throw InvalidSessionException("Unable to obtain session information for request."); + throw RetryableProfileException("Unable to obtain session information for request."); else return make_pair(false,(void*)NULL); // just bail silently } @@ -683,13 +665,6 @@ pair ShibTarget::doExportAssertions(bool requireSession) return make_pair(false,(void*)NULL); } - catch (SAMLException& e) { - tp.m_map["errorType"] = procState; - tp.m_map["errorText"] = e.what(); - if (targetURL) - tp.m_map["requestURL"] = m_url.substr(0,m_url.find('?')); - return make_pair(true,m_priv->sendError(this, "rm", tp)); - } catch (XMLToolingException& e) { tp.m_map["errorType"] = procState; tp.m_map["errorText"] = e.what(); @@ -798,7 +773,7 @@ string ShibTarget::getHandlerURL(const char* resource) const if (!handler || (*handler!='/' && strncmp(handler,"http:",5) && strncmp(handler,"https:",6))) throw ConfigurationException( "Invalid handlerURL property ($1) in Application ($2)", - params(2, handler ? handler : "null", m_priv->m_app->getId()) + xmltooling::params(2, handler ? handler : "null", m_priv->m_app->getId()) ); // The "handlerURL" property can be in one of three formats: diff --git a/shib-target/shib-target.h b/shib-target/shib-target.h index 1376fd8..808f7ef 100644 --- a/shib-target/shib-target.h +++ b/shib-target/shib-target.h @@ -26,10 +26,10 @@ #define SHIB_TARGET_H // New headers -#include -#include +#include #include #include +#include #include // Old headers @@ -49,9 +49,6 @@ namespace shibtarget { - DECLARE_SAML_EXCEPTION(SHIBTARGET_EXPORTS,ListenerException,SAMLException); - DECLARE_SAML_EXCEPTION(SHIBTARGET_EXPORTS,ConfigurationException,SAMLException); - // Abstract APIs for access to configuration information // Forward declaration @@ -93,13 +90,10 @@ namespace shibtarget { virtual saml::Iterator getAttributeDesignators() const=0; virtual saml::Iterator getAAPProviders() const=0; - virtual saml::Iterator getMetadataProviders() const=0; - virtual saml::Iterator getTrustProviders() const=0; + virtual opensaml::saml2md::MetadataProvider* getMetadataProvider() const=0; + virtual xmltooling::TrustEngine* getTrustEngine() const=0; virtual saml::Iterator getAudiences() const=0; - virtual const shibsp::PropertySet* getCredentialUse(const shibboleth::IEntityDescriptor* provider) const=0; - - virtual const opensaml::saml2md::MetadataProvider* getMetadataProvider() const=0; - virtual const xmltooling::TrustEngine* getTrustEngine() const=0; + virtual const shibsp::PropertySet* getCredentialUse(const opensaml::saml2md::EntityDescriptor* provider) const=0; // caller is borrowing object, must use within scope of config lock virtual const saml::SAMLBrowserProfile* getBrowserProfile() const=0; @@ -112,8 +106,8 @@ namespace shibtarget { virtual void validateToken( saml::SAMLAssertion* token, time_t t=0, - const shibboleth::IRoleDescriptor* role=NULL, - const saml::Iterator& trusts=EMPTY(shibboleth::ITrust*) + const opensaml::saml2md::RoleDescriptor* role=NULL, + const xmltooling::TrustEngine* trust=NULL ) const=0; // Used to locate a default or designated session initiator for automatic sessions @@ -142,8 +136,8 @@ namespace shibtarget { class ShibHTTPHook : virtual public saml::SAMLSOAPHTTPBinding::HTTPHook { public: - ShibHTTPHook(const saml::Iterator& trusts, const saml::Iterator& creds) - : m_trusts(trusts), m_creds(creds) {} + ShibHTTPHook(const xmltooling::TrustEngine* trust, const saml::Iterator& creds) + : m_trust(trust), m_creds(creds) {} virtual ~ShibHTTPHook() {} // Only hook we need here is for outgoing connection to server. @@ -152,26 +146,26 @@ namespace shibtarget { // Client declares a context object and pass as callCtx to send() method. class ShibHTTPHookCallContext { public: - ShibHTTPHookCallContext(const shibsp::PropertySet* credUse, const shibboleth::IRoleDescriptor* role) + ShibHTTPHookCallContext(const shibsp::PropertySet* credUse, const opensaml::saml2md::RoleDescriptor* role) : m_credUse(credUse), m_role(role), m_hook(NULL), m_authenticated(false) {} const ShibHTTPHook* getHook() {return m_hook;} const shibsp::PropertySet* getCredentialUse() {return m_credUse;} - const shibboleth::IRoleDescriptor* getRoleDescriptor() {return m_role;} + const opensaml::saml2md::RoleDescriptor* getRoleDescriptor() {return m_role;} bool isAuthenticated() const {return m_authenticated;} void setAuthenticated() {m_authenticated=true;} private: const shibsp::PropertySet* m_credUse; - const shibboleth::IRoleDescriptor* m_role; + const opensaml::saml2md::RoleDescriptor* m_role; ShibHTTPHook* m_hook; bool m_authenticated; friend class ShibHTTPHook; }; - const saml::Iterator& getTrustProviders() const {return m_trusts;} + const xmltooling::TrustEngine* getTrustEngine() const {return m_trust;} const saml::Iterator& getCredentialProviders() const {return m_creds;} private: - saml::Iterator m_trusts; + const xmltooling::TrustEngine* m_trust; saml::Iterator m_creds; }; @@ -243,7 +237,7 @@ namespace shibtarget { { virtual std::string insert( const IApplication* application, - const shibboleth::IEntityDescriptor* source, + const opensaml::saml2md::RoleDescriptor* source, const char* client_addr, const saml::SAMLSubject* subject, const char* authnContext, diff --git a/shib-target/shibtarget.vcproj b/shib-target/shibtarget.vcproj index 8ddaeac..d60e7a1 100644 --- a/shib-target/shibtarget.vcproj +++ b/shib-target/shibtarget.vcproj @@ -47,7 +47,7 @@ -#include - -using namespace shibboleth; -using namespace saml; -using namespace log4cpp; -using namespace std; - -IPlugIn* BasicTrustFactory(const DOMElement* e) -{ - return new BasicTrust(e); -} - -static const XMLCh resolver[] = -{ chLatin_K, chLatin_e, chLatin_y, chLatin_I, chLatin_n, chLatin_f, chLatin_o, - chLatin_R, chLatin_e, chLatin_s, chLatin_o, chLatin_l, chLatin_v, chLatin_e, chLatin_r, chNull -}; -static const XMLCh type[] = -{ chLatin_t, chLatin_y, chLatin_p, chLatin_e, chNull }; - -BasicTrust::BasicTrust(const DOMElement* e) -{ - // Find any KeyResolver plugins. - e=saml::XML::getFirstChildElement(e); - while (e) { - if (!XMLString::compareString(resolver,e->getLocalName()) && e->hasAttributeNS(NULL,type)) { - try { - auto_ptr_char temp(e->getAttributeNS(NULL,type)); - m_resolvers.push_back(KeyInfoResolver::getInstance(temp.get(),e)); - } - catch (SAMLException& ex) { - Category::getInstance(SHIB_LOGCAT".Trust.Basic").error( - "caught SAML exception building KeyInfoResolver plugin: %s",ex.what() - ); - } -#ifndef _DEBUG - catch (...) { - Category::getInstance(SHIB_LOGCAT".Trust.Basic").error("caught unknown exception building KeyInfoResolver plugin"); - } -#endif - } - e=saml::XML::getNextSiblingElement(e); - } - m_resolvers.push_back(KeyInfoResolver::getInstance(e)); -} - -BasicTrust::~BasicTrust() -{ - for (vector::iterator i=m_resolvers.begin(); i!=m_resolvers.end(); i++) - delete *i; -} - -bool BasicTrust::validate(void* certEE, const Iterator& certChain, const IRoleDescriptor* role, bool checkName) -{ -#ifdef _DEBUG - saml::NDC ndc("validate"); -#endif - Category& log=Category::getInstance(SHIB_LOGCAT".Trust.Basic"); - - if (!certEE) { - log.error("no certificate provided for comparison"); - return false; - } - - // The new "basic" trust implementation relies solely on certificates living within the - // role interface to verify the EE certificate. - - log.debug("comparing certificate to KeyDescriptors"); - Iterator kd_i=role->getKeyDescriptors(); - while (kd_i.hasNext()) { - const IKeyDescriptor* kd=kd_i.next(); - if (kd->getUse()==IKeyDescriptor::encryption) - continue; - DSIGKeyInfoList* KIL=kd->getKeyInfo(); - if (!KIL) - continue; - Iterator resolvers(m_resolvers); - while (resolvers.hasNext()) { - XSECCryptoX509* cert=resolvers.next()->resolveCert(KIL); - if (cert) { - log.debug("KeyDescriptor resolved into a certificate, comparing it..."); - if (cert->getProviderName()!=DSIGConstants::s_unicodeStrPROVOpenSSL) { - log.warn("only the OpenSSL XSEC provider is supported"); - continue; - } - else if (!X509_cmp(reinterpret_cast(certEE),static_cast(cert)->getOpenSSLX509())) { - log.info("certificate match found in KeyDescriptor"); - return true; - } - else - log.debug("certificate did not match"); - } - } - } - - log.debug("failed to find an exact match for certificate in KeyDescriptors"); - return false; -} - -bool BasicTrust::validate(const saml::SAMLSignedObject& token, const IRoleDescriptor* role, ITrust* certValidator) -{ -#ifdef _DEBUG - saml::NDC ndc("validate"); -#endif - Category& log=Category::getInstance(SHIB_LOGCAT".Trust.Basic"); - - // The new "basic" trust implementation relies solely on keys living within the - // role interface to verify the token. No indirection of any sort is allowed, - // unless an alternate key resolver is involved. - - log.debug("validating signature with KeyDescriptors"); - Iterator kd_i=role->getKeyDescriptors(); - while (kd_i.hasNext()) { - const IKeyDescriptor* kd=kd_i.next(); - if (kd->getUse()!=IKeyDescriptor::signing) - continue; - DSIGKeyInfoList* KIL=kd->getKeyInfo(); - if (!KIL) - continue; - Iterator resolvers(m_resolvers); - while (resolvers.hasNext()) { - XSECCryptoKey* key=((XSECKeyInfoResolver*)*resolvers.next())->resolveKey(KIL); - if (key) { - log.debug("KeyDescriptor resolved into a key, trying it..."); - try { - token.verify(key); - log.info("signature verified with KeyDescriptor"); - return true; - } - catch (SAMLException& e) { - log.debug("verification with KeyDescriptor failed: %s", e.what()); - } - } - } - } - - log.debug("failed to validate signature with KeyDescriptors"); - return false; -} diff --git a/shib/Makefile.am b/shib/Makefile.am index bac574f..68b6152 100644 --- a/shib/Makefile.am +++ b/shib/Makefile.am @@ -5,14 +5,12 @@ AUTOMAKE_OPTIONS = foreign lib_LTLIBRARIES = libshib.la libshibdir = $(includedir)/shib -libshib_HEADERS = shib.h hresult.h +libshib_HEADERS = shib.h noinst_HEADERS = internal.h libshib_la_SOURCES = \ - BasicTrust.cpp \ Metadata.cpp \ ReloadableXMLFile.cpp \ - ShibbolethTrust.cpp \ ShibConfig.cpp \ ShibBrowserProfile.cpp \ ScopedAttribute.cpp diff --git a/shib/Metadata.cpp b/shib/Metadata.cpp index 314e744..c444ef1 100644 --- a/shib/Metadata.cpp +++ b/shib/Metadata.cpp @@ -23,99 +23,13 @@ */ #include "internal.h" +#include using namespace shibboleth; +using namespace opensaml::saml2md; using namespace saml; using namespace std; -const IEntityDescriptor* Metadata::lookup(const XMLCh* id, bool strict) -{ - if (m_mapper) { - m_mapper->unlock(); - m_mapper=NULL; - } - const IEntityDescriptor* ret=NULL; - m_metadatas.reset(); - while (m_metadatas.hasNext()) { - m_mapper=m_metadatas.next(); - m_mapper->lock(); - if (ret=m_mapper->lookup(id,strict)) { - return ret; - } - m_mapper->unlock(); - m_mapper=NULL; - } - return NULL; -} - -const IEntityDescriptor* Metadata::lookup(const char* id, bool strict) -{ - if (m_mapper) { - m_mapper->unlock(); - m_mapper=NULL; - } - const IEntityDescriptor* ret=NULL; - m_metadatas.reset(); - while (m_metadatas.hasNext()) { - m_mapper=m_metadatas.next(); - m_mapper->lock(); - if (ret=m_mapper->lookup(id,strict)) { - return ret; - } - m_mapper->unlock(); - m_mapper=NULL; - } - return NULL; -} - -const IEntityDescriptor* Metadata::lookup(const SAMLArtifact* artifact) -{ - if (m_mapper) { - m_mapper->unlock(); - m_mapper=NULL; - } - const IEntityDescriptor* ret=NULL; - m_metadatas.reset(); - while (m_metadatas.hasNext()) { - m_mapper=m_metadatas.next(); - m_mapper->lock(); - if (ret=m_mapper->lookup(artifact)) { - return ret; - } - m_mapper->unlock(); - m_mapper=NULL; - } - return NULL; -} - -Metadata::~Metadata() -{ - if (m_mapper) { - m_mapper->unlock(); - m_mapper=NULL; - } -} - -bool Trust::validate(const SAMLSignedObject& token, const IRoleDescriptor* role) const -{ - m_trusts.reset(); - while (m_trusts.hasNext()) { - if (m_trusts.next()->validate(token,role)) - return true; - } - return false; -} - -bool Trust::validate(void* certEE, const Iterator& certChain, const IRoleDescriptor* role, bool checkName) const -{ - m_trusts.reset(); - while (m_trusts.hasNext()) { - if (m_trusts.next()->validate(certEE,certChain,role,checkName)) - return true; - } - return false; -} - const ICredResolver* Credentials::lookup(const char* id) { if (m_mapper) { @@ -180,10 +94,10 @@ AAP::~AAP() } } -void AAP::apply(const saml::Iterator& aaps, saml::SAMLAssertion& assertion, const IEntityDescriptor* source) +void AAP::apply(const saml::Iterator& aaps, saml::SAMLAssertion& assertion, const RoleDescriptor* role) { #ifdef _DEBUG - saml::NDC("apply"); + xmltooling::NDC("apply"); #endif log4cpp::Category& log=log4cpp::Category::getInstance(SHIB_LOGCAT".AAP"); @@ -224,7 +138,7 @@ void AAP::apply(const saml::Iterator& aaps, saml::SAMLAssertion& assertio if (rule=i->lookup(a->getName(),a->getNamespace())) { ruleFound=true; try { - rule->apply(*a,source); + rule->apply(*a,role); } catch (SAMLException&) { // The attribute is now defunct. diff --git a/shib/ShibBrowserProfile.cpp b/shib/ShibBrowserProfile.cpp index 83edb77..f783509 100644 --- a/shib/ShibBrowserProfile.cpp +++ b/shib/ShibBrowserProfile.cpp @@ -25,17 +25,22 @@ #include "internal.h" #include - #include +#include +#include +#include using namespace shibboleth; using namespace saml; +using namespace opensaml::saml1p; +using namespace opensaml::saml2md; +using namespace xmltooling; using namespace log4cpp; using namespace std; ShibBrowserProfile::ShibBrowserProfile( - const ITokenValidator* validator, const Iterator& metadatas, const Iterator& trusts - ) : m_validator(validator), m_metadatas(metadatas), m_trusts(trusts) + const ITokenValidator* validator, MetadataProvider* metadata, TrustEngine* trust + ) : m_validator(validator), m_metadata(metadata), m_trust(trust) { m_profile=SAMLBrowserProfile::getInstance(); } @@ -53,32 +58,14 @@ SAMLBrowserProfile::BrowserProfileResponse ShibBrowserProfile::receive( ) const { #ifdef _DEBUG - saml::NDC("recieve"); + xmltooling::NDC("recieve"); #endif Category& log=Category::getInstance(SHIB_LOGCAT".ShibBrowserProfile"); // The built-in SAML functionality will do most of the basic non-crypto checks. // Note that if the response only contains a status error, it gets tossed out // as an exception. - SAMLBrowserProfile::BrowserProfileResponse bpr; - try { - bpr=m_profile->receive(samlResponse, recipient, replayCache, minorVersion); - } - catch (SAMLException& e) { - // Try our best to attach additional information. - if (e.getProperty("issuer")) { - Metadata m(m_metadatas); - const IEntityDescriptor* provider=m.lookup(e.getProperty("issuer"),false); - if (provider) { - const IIDPSSODescriptor* role=provider->getIDPSSODescriptor( - minorVersion==1 ? saml::XML::SAML11_PROTOCOL_ENUM : saml::XML::SAML10_PROTOCOL_ENUM - ); - if (role) annotateException(&e,role); // throws it - annotateException(&e,provider); // throws it - } - } - throw; - } + SAMLBrowserProfile::BrowserProfileResponse bpr=m_profile->receive(samlResponse, recipient, replayCache, minorVersion); try { postprocess(bpr,minorVersion); @@ -101,25 +88,7 @@ SAMLBrowserProfile::BrowserProfileResponse ShibBrowserProfile::receive( // The built-in SAML functionality will do most of the basic non-crypto checks. // Note that if the response only contains a status error, it gets tossed out // as an exception. - SAMLBrowserProfile::BrowserProfileResponse bpr; - try { - bpr=m_profile->receive(artifacts, recipient, artifactMapper, replayCache, minorVersion); - } - catch (SAMLException& e) { - // Try our best to attach additional information. - if (e.getProperty("issuer")) { - Metadata m(m_metadatas); - const IEntityDescriptor* provider=m.lookup(e.getProperty("issuer"),false); - if (provider) { - const IIDPSSODescriptor* role=provider->getIDPSSODescriptor( - minorVersion==1 ? saml::XML::SAML11_PROTOCOL_ENUM : saml::XML::SAML10_PROTOCOL_ENUM - ); - if (role) annotateException(&e,role); // throws it - annotateException(&e,provider); // throws it - } - } - throw; - } + SAMLBrowserProfile::BrowserProfileResponse bpr=m_profile->receive(artifacts, recipient, artifactMapper, replayCache, minorVersion); try { postprocess(bpr,minorVersion); @@ -134,48 +103,51 @@ SAMLBrowserProfile::BrowserProfileResponse ShibBrowserProfile::receive( void ShibBrowserProfile::postprocess(SAMLBrowserProfile::BrowserProfileResponse& bpr, int minorVersion) const { #ifdef _DEBUG - saml::NDC("postprocess"); + xmltooling::NDC("postprocess"); #endif Category& log=Category::getInstance(SHIB_LOGCAT".ShibBrowserProfile"); + if (!m_metadata) + throw MetadataException("No metadata found, unable to process assertion."); + // Try and locate metadata for the IdP. We try Issuer first. log.debug("searching metadata for assertion issuer..."); - Metadata m(m_metadatas); - const IEntityDescriptor* provider=m.lookup(bpr.assertion->getIssuer()); + xmltooling::Locker locker(m_metadata); + const EntityDescriptor* provider=m_metadata->getEntityDescriptor(bpr.assertion->getIssuer()); if (provider) log.debug("matched assertion issuer against metadata"); else if (bpr.authnStatement->getSubject()->getNameIdentifier() && bpr.authnStatement->getSubject()->getNameIdentifier()->getNameQualifier()) { // Might be a down-level origin. - provider=m.lookup(bpr.authnStatement->getSubject()->getNameIdentifier()->getNameQualifier()); + provider=m_metadata->getEntityDescriptor(bpr.authnStatement->getSubject()->getNameIdentifier()->getNameQualifier()); if (provider) log.debug("matched subject name qualifier against metadata"); } // No metadata at all. if (!provider) { - auto_ptr_char issuer(bpr.assertion->getIssuer()); - auto_ptr_char nq(bpr.authnStatement->getSubject()->getNameIdentifier()->getNameQualifier()); + xmltooling::auto_ptr_char issuer(bpr.assertion->getIssuer()); + xmltooling::auto_ptr_char nq(bpr.authnStatement->getSubject()->getNameIdentifier()->getNameQualifier()); log.error("assertion issuer not found in metadata (Issuer='%s', NameQualifier='%s')", issuer.get(), (nq.get() ? nq.get() : "none")); // Try a non-strict lookup for more contact info. - const IEntityDescriptor* provider=m.lookup(bpr.assertion->getIssuer(),false); + const EntityDescriptor* provider=m_metadata->getEntityDescriptor(bpr.assertion->getIssuer(),false); if (provider) { log.debug("found invalid metadata for assertion issuer, using for contact info"); MetadataException ex("metadata lookup failed, unable to process assertion"); annotateException(&ex,provider); // throws it } - throw MetadataException("Metadata lookup failed, unable to process assertion",namedparams(1,"issuer",issuer.get())); + throw MetadataException("Metadata lookup failed, unable to process assertion",xmltooling::namedparams(1,"issuer",issuer.get())); } // Is this provider an IdP? - const IIDPSSODescriptor* role=provider->getIDPSSODescriptor( - minorVersion==1 ? saml::XML::SAML11_PROTOCOL_ENUM : saml::XML::SAML10_PROTOCOL_ENUM + const IDPSSODescriptor* role=provider->getIDPSSODescriptor( + minorVersion==1 ? samlconstants::SAML11_PROTOCOL_ENUM : samlconstants::SAML10_PROTOCOL_ENUM ); if (!role) { - auto_ptr_char issuer(bpr.assertion->getIssuer()); - auto_ptr_char nq(bpr.authnStatement->getSubject()->getNameIdentifier()->getNameQualifier()); + xmltooling::auto_ptr_char issuer(bpr.assertion->getIssuer()); + xmltooling::auto_ptr_char nq(bpr.authnStatement->getSubject()->getNameIdentifier()->getNameQualifier()); log.error("metadata for assertion issuer indicates no SAML 1.%d identity provider role (Issuer='%s', NameQualifier='%s'", minorVersion, issuer.get(), (nq.get() ? nq.get() : "none")); MetadataException ex("Metadata lookup failed, issuer not registered as SAML 1.x identity provider"); @@ -184,12 +156,25 @@ void ShibBrowserProfile::postprocess(SAMLBrowserProfile::BrowserProfileResponse& // Use this role to evaluate the signature(s). If the response is unsigned, we know // it was an artifact profile run. - Trust t(m_trusts); - if (bpr.response->isSigned()) { + if (bpr.response->isSigned()) { log.debug("passing signed response to trust layer"); - if (!t.validate(*bpr.response,role)) { + if (!m_trust) { + XMLSecurityException ex("No trust provider, unable to verify signed profile response."); + annotateException(&ex,role); // throws it + } + + // This will all change, but for fun, we'll port the object from OS1->OS2 for validation. + stringstream s; + s << *bpr.response; + DOMDocument* doc = XMLToolingConfig::getConfig().getValidatingParser().parse(s); + XercesJanitor jdoc(doc); + auto_ptr os2resp(ResponseBuilder::buildResponse()); + os2resp->unmarshall(doc->getDocumentElement(),true); + jdoc.release(); + + if (!m_trust->validate(*(os2resp->getSignature()),*role,m_metadata->getKeyResolver())) { log.error("unable to verify signed profile response"); - TrustException ex("Unable to verify signed profile response."); + XMLSecurityException ex("Unable to verify signed profile response."); annotateException(&ex,role); // throws it } } @@ -199,7 +184,7 @@ void ShibBrowserProfile::postprocess(SAMLBrowserProfile::BrowserProfileResponse& for (unsigned int a=0; agetIssuer(),assertions[a]->getIssuer())) { - auto_ptr_char bad(assertions[a]->getIssuer()); + xmltooling::auto_ptr_char bad(assertions[a]->getIssuer()); log.warn("discarding assertion not issued by authenticating IdP, instead by (%s)",bad.get()); bpr.response->removeAssertion(a); continue; @@ -207,14 +192,14 @@ void ShibBrowserProfile::postprocess(SAMLBrowserProfile::BrowserProfileResponse& // Validate the token. try { - m_validator->validateToken(assertions[a],now,role,m_trusts); + m_validator->validateToken(assertions[a],now,role,m_trust); a++; } - catch (SAMLException& e) { + catch (SAMLException&) { if (assertions[a]==bpr.assertion) { // If the authn token fails, we have to fail the whole profile run. log.error("authentication assertion failed to validate"); - annotateException(&e,role,false); + //annotateException(&e,role,false); throw; } log.warn("token failed to validate, removing it from response"); diff --git a/shib/ShibConfig.cpp b/shib/ShibConfig.cpp index 96a7314..3f5460b 100644 --- a/shib/ShibConfig.cpp +++ b/shib/ShibConfig.cpp @@ -39,20 +39,11 @@ using namespace log4cpp; using namespace std; -SAML_EXCEPTION_FACTORY(ResourceAccessException); -SAML_EXCEPTION_FACTORY(MetadataException); -SAML_EXCEPTION_FACTORY(CredentialException); -SAML_EXCEPTION_FACTORY(InvalidHandleException); -SAML_EXCEPTION_FACTORY(InvalidSessionException); - -PlugManager::Factory BasicTrustFactory; -PlugManager::Factory ShibbolethTrustFactory; - namespace { ShibConfig g_config; vector g_openssl_locks; #ifdef HAVE_GOOD_STL - map attrMap; + map attrMap; #else map attrMap; #endif @@ -62,7 +53,7 @@ extern "C" SAMLAttribute* ShibAttributeFactory(DOMElement* e) { // First check for an explicit factory. #ifdef HAVE_GOOD_STL - map::const_iterator i=attrMap.find(e->getAttributeNS(NULL,L(AttributeName))); + map::const_iterator i=attrMap.find(e->getAttributeNS(NULL,L(AttributeName))); #else const XMLCh* aname=e->getAttributeNS(NULL,L(AttributeName)); map::const_iterator i; @@ -139,17 +130,6 @@ extern "C" unsigned long openssl_thread_id(void) bool ShibConfig::init() { - REGISTER_EXCEPTION_FACTORY(ResourceAccessException); - REGISTER_EXCEPTION_FACTORY(MetadataException); - REGISTER_EXCEPTION_FACTORY(CredentialException); - REGISTER_EXCEPTION_FACTORY(InvalidHandleException); - REGISTER_EXCEPTION_FACTORY(InvalidSessionException); - - // Register plugin factories (some are legacy aliases) - SAMLConfig& conf=SAMLConfig::getConfig(); - conf.getPlugMgr().regFactory("edu.internet2.middleware.shibboleth.common.provider.BasicTrust",&BasicTrustFactory); - conf.getPlugMgr().regFactory("edu.internet2.middleware.shibboleth.common.provider.ShibbolethTrust",&ShibbolethTrustFactory); - // Set up OpenSSL locking. for (int i=0; i::iterator j=g_openssl_locks.begin(); j!=g_openssl_locks.end(); j++) delete (*j); g_openssl_locks.clear(); - - // Unregister plugin factories - SAMLConfig& conf=SAMLConfig::getConfig(); - conf.getPlugMgr().unregFactory("edu.internet2.middleware.shibboleth.common.provider.BasicTrust"); - conf.getPlugMgr().unregFactory("edu.internet2.middleware.shibboleth.common.provider.ShibbolethTrust"); } ShibConfig& ShibConfig::getConfig() { return g_config; } - -void shibboleth::annotateException(SAMLException* e, const IEntityDescriptor* entity, bool rethrow) -{ - if (entity) { - auto_ptr_char id(entity->getId()); - e->addProperty("providerId",id.get()); - Iterator roles=entity->getRoleDescriptors(); - while (roles.hasNext()) { - const IRoleDescriptor* role=roles.next(); - if (role->isValid()) { - const char* temp=role->getErrorURL(); - if (temp) { - e->addProperty("errorURL",temp); - break; - } - } - } - - Iterator i=entity->getContactPersons(); - while (i.hasNext()) { - const IContactPerson* c=i.next(); - if ((c->getType()==IContactPerson::technical || c->getType()==IContactPerson::support)) { - const char* fname=c->getGivenName(); - const char* lname=c->getSurName(); - if (fname && lname) { - string contact=string(fname) + ' ' + lname; - e->addProperty("contactName",contact.c_str()); - } - else if (fname) - e->addProperty("contactName",fname); - else if (lname) - e->addProperty("contactName",lname); - Iterator emails=c->getEmailAddresses(); - if (emails.hasNext()) - e->addProperty("contactEmail",emails.next().c_str()); - break; - } - } - } - - if (rethrow) - e->raise(); -} - -void shibboleth::annotateException(saml::SAMLException* e, const IRoleDescriptor* role, bool rethrow) -{ - if (role) { - auto_ptr_char id(role->getEntityDescriptor()->getId()); - e->addProperty("providerId",id.get()); - const char* temp=role->getErrorURL(); - if (role->getErrorURL()) - e->addProperty("errorURL",role->getErrorURL()); - - Iterator i=role->getContactPersons(); - while (i.hasNext()) { - const IContactPerson* c=i.next(); - if ((c->getType()==IContactPerson::technical || c->getType()==IContactPerson::support)) { - const char* fname=c->getGivenName(); - const char* lname=c->getSurName(); - if (fname && lname) { - string contact=string(fname) + ' ' + lname; - e->addProperty("contactName",contact.c_str()); - } - else if (fname) - e->addProperty("contactName",fname); - else if (lname) - e->addProperty("contactName",lname); - Iterator emails=c->getEmailAddresses(); - if (emails.hasNext()) - e->addProperty("contactEmail",emails.next().c_str()); - break; - } - } - } - - if (rethrow) - e->raise(); -} diff --git a/shib/ShibbolethTrust.cpp b/shib/ShibbolethTrust.cpp deleted file mode 100644 index 5c686b7..0000000 --- a/shib/ShibbolethTrust.cpp +++ /dev/null @@ -1,537 +0,0 @@ -/* - * Copyright 2001-2005 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. - */ - -/* ShibbolethTrust.cpp - a trust implementation that relies solely on standard SAML metadata - - Scott Cantor - 4/10/05 - - $History:$ -*/ - -#include "internal.h" - -#include -#include -#include -#include -#include - -using namespace shibboleth; -using namespace saml; -using namespace log4cpp; -using namespace std; - -namespace { - void log_openssl() - { - const char* file; - const char* data; - int flags,line; - - unsigned long code=ERR_get_error_line_data(&file,&line,&data,&flags); - while (code) { - Category& log=Category::getInstance("OpenSSL"); - log.errorStream() << "error code: " << code << " in " << file << ", line " << line << CategoryStream::ENDLINE; - if (data && (flags & ERR_TXT_STRING)) - log.errorStream() << "error data: " << data << CategoryStream::ENDLINE; - code=ERR_get_error_line_data(&file,&line,&data,&flags); - } - } - - X509* B64_to_X509(const char* buf) - { - BIO* bmem = BIO_new_mem_buf((void*)buf,-1); - BIO* b64 = BIO_new(BIO_f_base64()); - b64 = BIO_push(b64, bmem); - X509* x=NULL; - d2i_X509_bio(b64,&x); - if (!x) - log_openssl(); - BIO_free_all(b64); - return x; - } - - X509_CRL* B64_to_CRL(const char* buf) - { - BIO* bmem = BIO_new_mem_buf((void*)buf,-1); - BIO* b64 = BIO_new(BIO_f_base64()); - b64 = BIO_push(b64, bmem); - X509_CRL* x=NULL; - d2i_X509_CRL_bio(b64,&x); - if (!x) - log_openssl(); - BIO_free_all(b64); - return x; - } - - class ShibbolethTrust : public BasicTrust - { - public: - ShibbolethTrust(const DOMElement* e); - ~ShibbolethTrust(); - - bool validate(void* certEE, const Iterator& certChain, const IRoleDescriptor* role, bool checkName=true); - bool validate(const saml::SAMLSignedObject& token, const IRoleDescriptor* role, ITrust* certValidator=NULL); - - private: - bool validate(X509* EE, STACK_OF(X509)* untrusted, const IKeyAuthority* rule); - - vector m_metas; - }; -} - -IPlugIn* ShibbolethTrustFactory(const DOMElement* e) -{ - return new ShibbolethTrust(e); -} - -ShibbolethTrust::ShibbolethTrust(const DOMElement* e) : BasicTrust(e) -{ - static const XMLCh MetadataProvider[] = - { chLatin_M, chLatin_e, chLatin_t, chLatin_a, chLatin_d, chLatin_a, chLatin_t, chLatin_a, - chLatin_P, chLatin_r, chLatin_o, chLatin_v, chLatin_i, chLatin_d, chLatin_e, chLatin_r, chNull - }; - static const XMLCh _type[] = { chLatin_t, chLatin_y, chLatin_p, chLatin_e, chNull }; - -#ifdef _DEBUG - saml::NDC ndc("ShibbolethTrust"); -#endif - Category& log=Category::getInstance(SHIB_LOGCAT".Trust.Shibboleth"); - - // Check for embedded trust metadata. - e=saml::XML::getFirstChildElement(e); - while (e) { - if (!XMLString::compareString(e->getLocalName(),MetadataProvider) && e->hasAttributeNS(NULL,_type)) { - auto_ptr_char type(e->getAttributeNS(NULL,_type)); - log.info("trust provider building embedded metadata provider of type %s...",type.get()); - try { - IPlugIn* plugin=SAMLConfig::getConfig().getPlugMgr().newPlugin(type.get(),e); - IMetadata* md=dynamic_cast(plugin); - if (md) - m_metas.push_back(md); - else { - delete plugin; - log.error("plugin was not a metadata provider"); - } - } - catch (SAMLException& ex) { - log.error("caught SAML exception building embedded metadata provider: %s", ex.what()); - } -#ifndef _DEBUG - catch (...) { - log.error("caught unknown exception building embedded metadata provider"); - } -#endif - } - e=saml::XML::getNextSiblingElement(e); - } -} - -ShibbolethTrust::~ShibbolethTrust() -{ - for (vector::iterator i=m_metas.begin(); i!=m_metas.end(); i++) - delete *i; -} - -static int error_callback(int ok, X509_STORE_CTX* ctx) -{ - if (!ok) - Category::getInstance("OpenSSL").error("path validation failure: %s", X509_verify_cert_error_string(ctx->error)); - return ok; -} - -bool ShibbolethTrust::validate(X509* EE, STACK_OF(X509)* untrusted, const IKeyAuthority* rule) -{ - Category& log=Category::getInstance(SHIB_LOGCAT".Trust.Shibboleth"); - - // First we build a stack of CA certs. These objects are all referenced in place. - log.debug("building CA list from KeyAuthority extension"); - - // We need this for CRL support. - X509_STORE* store=X509_STORE_new(); - if (!store) { - log_openssl(); - return false; - } -#if (OPENSSL_VERSION_NUMBER >= 0x00907000L) - X509_STORE_set_flags(store,X509_V_FLAG_CRL_CHECK_ALL); -#endif - - STACK_OF(X509)* CAstack = sk_X509_new_null(); - - // This contains the state of the validate operation. - X509_STORE_CTX ctx; - - Iterator iKIL=rule->getKeyInfos(); - while (iKIL.hasNext()) { - DSIGKeyInfoList* KIL=iKIL.next(); - - // Try and locate a certificate. - Iterator resolvers(m_resolvers); - while (resolvers.hasNext()) { - XSECCryptoX509* cert=resolvers.next()->resolveCert(KIL); - if (cert && cert->getProviderName()==DSIGConstants::s_unicodeStrPROVOpenSSL) { - sk_X509_push(CAstack,static_cast(cert)->getOpenSSLX509()); - break; - } - } - - // Try and locate one or more CRLs. - for (size_t s=0; sgetSize(); s++) { - DSIGKeyInfo* KI=KIL->item(s); - if (KI->getKeyInfoType()==DSIGKeyInfo::KEYINFO_X509) { - const XMLCh* raw=static_cast(KI)->getX509CRL(); - if (raw) { - auto_ptr_char blob(raw); - X509_CRL* crl=B64_to_CRL(blob.get()); - if (crl) - X509_STORE_add_crl(store,crl); // owned by store - else - log.error("unable to create CRL from X509CRL data"); - } - } - } - } - - // AFAICT, EE and untrusted are passed in but not owned by the ctx. -#if (OPENSSL_VERSION_NUMBER >= 0x00907000L) - if (X509_STORE_CTX_init(&ctx,store,EE,untrusted)!=1) { - log_openssl(); - log.error("unable to initialize X509_STORE_CTX"); - sk_X509_free(CAstack); - X509_STORE_free(store); - return false; - } -#else - X509_STORE_CTX_init(&ctx,store,EE,untrusted); -#endif - - // Seems to be most efficient to just pass in the CA stack. - X509_STORE_CTX_trusted_stack(&ctx,CAstack); - X509_STORE_CTX_set_depth(&ctx,100); // we check the depth down below - X509_STORE_CTX_set_verify_cb(&ctx,error_callback); - - int ret=X509_verify_cert(&ctx); - if (ret==1) { - // Now see if the depth was acceptable by counting the number of intermediates. - int depth=sk_X509_num(ctx.chain)-2; - if (rule->getVerifyDepth() < depth) { - log.error( - "certificate chain was too long (%d intermediates, only %d allowed)", - (depth==-1) ? 0 : depth, - rule->getVerifyDepth() - ); - ret=0; - } - } - - // Clean up... - X509_STORE_CTX_cleanup(&ctx); - X509_STORE_free(store); - sk_X509_free(CAstack); - - if (ret==1) { - log.info("successfully validated certificate chain"); - return true; - } - - return false; -} - -bool ShibbolethTrust::validate(void* certEE, const Iterator& certChain, const IRoleDescriptor* role, bool checkName) -{ - if (BasicTrust::validate(certEE,certChain,role)) - return true; - -#ifdef _DEBUG - saml::NDC ndc("validate"); -#endif - Category& log=Category::getInstance(SHIB_LOGCAT".Trust.Shibboleth"); - - if (!certEE) - return false; - - // The extended trust implementation supports metadata extensions to validate - // signing certificates found inside the signature. - - if (checkName) { - // Before we do the cryptogprahy, check that the EE certificate "name" matches - // one of the acceptable key "names" for the signer. - vector keynames; - - // Build a list of acceptable names. Transcode the possible key "names" to UTF-8. - // For some simple cases, this should handle UTF-8 encoded DNs in certificates. - Iterator kd_i=role->getKeyDescriptors(); - while (kd_i.hasNext()) { - const IKeyDescriptor* kd=kd_i.next(); - if (kd->getUse()!=IKeyDescriptor::signing) - continue; - DSIGKeyInfoList* KIL=kd->getKeyInfo(); - if (!KIL) - continue; - for (size_t s=0; sgetSize(); s++) { - const XMLCh* n=KIL->item(s)->getKeyName(); - if (n) { - auto_ptr kn(toUTF8(n)); - keynames.push_back(kn.get()); - } - } - } - auto_ptr kn(toUTF8(role->getEntityDescriptor()->getId())); - keynames.push_back(kn.get()); - - char buf[256]; - X509* x=(X509*)certEE; - X509_NAME* subject=X509_get_subject_name(x); - if (subject) { - // One way is a direct match to the subject DN. - // Seems that the way to do the compare is to write the X509_NAME into a BIO. - BIO* b = BIO_new(BIO_s_mem()); - BIO* b2 = BIO_new(BIO_s_mem()); - BIO_set_mem_eof_return(b, 0); - BIO_set_mem_eof_return(b2, 0); - // The flags give us LDAP order instead of X.500, with a comma separator. - int len=X509_NAME_print_ex(b,subject,0,XN_FLAG_RFC2253); - string subjectstr,subjectstr2; - BIO_flush(b); - while ((len = BIO_read(b, buf, 255)) > 0) { - buf[len] = '\0'; - subjectstr+=buf; - } - log.infoStream() << "certificate subject: " << subjectstr << CategoryStream::ENDLINE; - // The flags give us LDAP order instead of X.500, with a comma plus space separator. - len=X509_NAME_print_ex(b2,subject,0,XN_FLAG_RFC2253 + XN_FLAG_SEP_CPLUS_SPC - XN_FLAG_SEP_COMMA_PLUS); - BIO_flush(b2); - while ((len = BIO_read(b2, buf, 255)) > 0) { - buf[len] = '\0'; - subjectstr2+=buf; - } - - // Check each keyname. - for (vector::const_iterator n=keynames.begin(); n!=keynames.end(); n++) { -#ifdef HAVE_STRCASECMP - if (!strcasecmp(n->c_str(),subjectstr.c_str()) || !strcasecmp(n->c_str(),subjectstr2.c_str())) { -#else - if (!stricmp(n->c_str(),subjectstr.c_str()) || !stricmp(n->c_str(),subjectstr2.c_str())) { -#endif - log.info("matched full subject DN to a key name (%s)", n->c_str()); - checkName=false; - break; - } - } - BIO_free(b); - BIO_free(b2); - - if (checkName) { - log.debug("unable to match DN, trying TLS subjectAltName match"); - STACK_OF(GENERAL_NAME)* altnames=(STACK_OF(GENERAL_NAME)*)X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL); - if (altnames) { - int numalts = sk_GENERAL_NAME_num(altnames); - for (int an=0; checkName && antype==GEN_DNS || check->type==GEN_URI) { - const char* altptr = (char*)ASN1_STRING_data(check->d.ia5); - const int altlen = ASN1_STRING_length(check->d.ia5); - - for (vector::const_iterator n=keynames.begin(); n!=keynames.end(); n++) { -#ifdef HAVE_STRCASECMP - if ((check->type==GEN_DNS && !strncasecmp(altptr,n->c_str(),altlen)) -#else - if ((check->type==GEN_DNS && !strnicmp(altptr,n->c_str(),altlen)) -#endif - || (check->type==GEN_URI && !strncmp(altptr,n->c_str(),altlen))) { - log.info("matched DNS/URI subjectAltName to a key name (%s)", n->c_str()); - checkName=false; - break; - } - } - } - } - GENERAL_NAMES_free(altnames); - } - - if (checkName) { - log.debug("unable to match subjectAltName, trying TLS CN match"); - memset(buf,0,sizeof(buf)); - if (X509_NAME_get_text_by_NID(subject,NID_commonName,buf,255)>0) { - for (vector::const_iterator n=keynames.begin(); n!=keynames.end(); n++) { -#ifdef HAVE_STRCASECMP - if (!strcasecmp(buf,n->c_str())) { -#else - if (!stricmp(buf,n->c_str())) { -#endif - log.info("matched subject CN to a key name (%s)", n->c_str()); - checkName=false; - break; - } - } - } - else - log.warn("no common name in certificate subject"); - } - } - } - else - log.error("certificate has no subject?!"); - } - - if (checkName) { - log.error("cannot match certificate subject against acceptable key names based on KeyDescriptors"); - return false; - } - - log.debug("performing certificate path validation..."); - - STACK_OF(X509)* untrusted=sk_X509_new_null(); - certChain.reset(); - while (certChain.hasNext()) - sk_X509_push(untrusted,(X509*)certChain.next()); - - // Check for entity-level KeyAuthorities. - const IExtendedEntityDescriptor* entity=dynamic_cast(role->getEntityDescriptor()); - if (entity) { - Iterator kauths=entity->getKeyAuthorities(); - while (kauths.hasNext()) - if (validate((X509*)certEE,untrusted,kauths.next())) { - sk_X509_free(untrusted); - return true; - } - } - - // Now repeat using any embedded metadata. - Iterator metas(m_metas); - while (metas.hasNext()) { - IMetadata* m=metas.next(); - Locker locker(m); - const IEntityDescriptor* ed=m->lookup(role->getEntityDescriptor()->getId()); - if (!ed) - continue; - - // Check for entity-level KeyAuthorities. - entity=dynamic_cast(ed); - if (entity) { - Iterator kauths=entity->getKeyAuthorities(); - while (kauths.hasNext()) - if (validate((X509*)certEE,untrusted,kauths.next())) { - sk_X509_free(untrusted); - return true; - } - } - } - - const IEntitiesDescriptor* group=role->getEntityDescriptor()->getEntitiesDescriptor(); - while (group) { - const IExtendedEntitiesDescriptor* egroup=dynamic_cast(group); - if (egroup) { - Iterator kauths=egroup->getKeyAuthorities(); - while (kauths.hasNext()) - if (validate((X509*)certEE,untrusted,kauths.next())) { - sk_X509_free(untrusted); - return true; - } - } - - // Now repeat using any embedded metadata. - Iterator metas(m_metas); - while (metas.hasNext()) { - IMetadata* m=metas.next(); - Locker locker(m); - const IEntitiesDescriptor* g=m->lookupGroup(group->getName()); - if (!g) - continue; - - // Check for group-level KeyAuthorities. - egroup=dynamic_cast(g); - if (egroup) { - Iterator kauths=egroup->getKeyAuthorities(); - while (kauths.hasNext()) - if (validate((X509*)certEE,untrusted,kauths.next())) { - sk_X509_free(untrusted); - return true; - } - } - } - - group=group->getEntitiesDescriptor(); - } - - log.debug("failed to validate certificate chain using KeyAuthority extensions"); - return false; -} - -bool ShibbolethTrust::validate(const saml::SAMLSignedObject& token, const IRoleDescriptor* role, ITrust* certValidator) -{ - if (BasicTrust::validate(token,role)) - return true; - -#ifdef _DEBUG - saml::NDC ndc("validate"); -#endif - Category& log=Category::getInstance(SHIB_LOGCAT".Trust.Shibboleth"); - - // The extended trust implementation supports metadata extensions to validate - // signing certificates found inside the signature. - - // Get the certificate chain out of the object in portable form. - vector certs; - for (unsigned int i=0; i x(XSECPlatformUtils::g_cryptoProvider->X509()); - try { - x->loadX509Base64Bin(cert.get(),strlen(cert.get())); - certs.push_back(x.release()); - } - catch (...) { - log.error("unable to load certificate from signature, skipping it"); - } - } - - log.debug("validating signature using certificate from within the signature"); - - // Native representations. - X509* certEE=NULL; - vector chain; - - // Find and save off a pointer to the certificate that unlocks the object. - // Most of the time, this will be the first one anyway. - Iterator iter(certs); - while (iter.hasNext()) { - try { - XSECCryptoX509* c=iter.next(); - chain.push_back(static_cast(c)->getOpenSSLX509()); - if (!certEE) { - token.verify(*c); - log.info("signature verified with key inside signature, attempting certificate validation..."); - certEE=static_cast(c)->getOpenSSLX509(); - } - } - catch (...) { - // trap failures - } - } - - bool ret=false; - if (certEE) - ret=(certValidator) ? certValidator->validate(certEE,chain,role) : this->validate(certEE,chain,role); - else - log.debug("failed to verify signature with embedded certificates"); - - for (vector::iterator j=certs.begin(); j!=certs.end(); j++) - delete *j; - - return ret; -} diff --git a/shib/hresult.h b/shib/hresult.h deleted file mode 100644 index 46b743a..0000000 --- a/shib/hresult.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2001-2005 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. - */ - -/* - * hresult.h - Code definitions -= */ - -#ifndef __shibhresult_h__ -#define __shibhresult_h__ - -#include - -/* Codes from 0x9000 - 0x9FFF in FACILITY_ITF are reserved for the Shibboleth Core */ - -#define SHIB_E_FIRST MAKE_HRESULT(SEVERITY_ERROR,FACILITY_ITF,SAML_E_LAST + 0x0001) -#define SHIB_E_LAST MAKE_HRESULT(SEVERITY_ERROR,FACILITY_ITF,SAML_E_LAST + 0x1000) - -#define SHIB_S_FIRST MAKE_HRESULT(SEVERITY_SUCCESS,FACILITY_ITF,SAML_S_LAST + 0x0001) -#define SHIB_S_LAST MAKE_HRESULT(SEVERITY_SUCCESS,FACILITY_ITF,SAML_S_LAST + 0x1000 - -/* Specific code definitions */ - -#define SHIB_E_UNSPECIFIED (SHIB_E_FIRST + 0L) - -#endif diff --git a/shib/internal.h b/shib/internal.h index 1124fd6..86455c1 100644 --- a/shib/internal.h +++ b/shib/internal.h @@ -45,19 +45,6 @@ #define SHIB_LOGCAT "Shibboleth" namespace shibboleth { - class BasicTrust : public ITrust - { - public: - BasicTrust(const DOMElement* e); - ~BasicTrust(); - - bool validate(void* certEE, const saml::Iterator& certChain, const IRoleDescriptor* role, bool checkName=true); - bool validate(const saml::SAMLSignedObject& token, const IRoleDescriptor* role, ITrust* certValidator=NULL); - - protected: - std::vector m_resolvers; - }; - class ScopedAttribute : public saml::SAMLAttribute { public: diff --git a/shib/shib.h b/shib/shib.h index 8e93490..5a917b4 100644 --- a/shib/shib.h +++ b/shib/shib.h @@ -25,10 +25,13 @@ #ifndef __shib_h__ #define __shib_h__ +#include +#include +#include #include #include -#include +#undef SAML10_PROTOCOL_ENUM #ifdef WIN32 # ifndef SHIB_EXPORTS @@ -40,250 +43,6 @@ namespace shibboleth { - DECLARE_SAML_EXCEPTION(SHIB_EXPORTS,ResourceAccessException,SAMLException); - DECLARE_SAML_EXCEPTION(SHIB_EXPORTS,MetadataException,SAMLException); - DECLARE_SAML_EXCEPTION(SHIB_EXPORTS,CredentialException,SAMLException); - DECLARE_SAML_EXCEPTION(SHIB_EXPORTS,InvalidHandleException,SAMLException); - DECLARE_SAML_EXCEPTION(SHIB_EXPORTS,InvalidSessionException,RetryableProfileException); - - // Metadata abstract interfaces, based on SAML 2.0 - - struct SHIB_EXPORTS IContactPerson - { - enum ContactType { technical, support, administrative, billing, other }; - virtual ContactType getType() const=0; - virtual const char* getCompany() const=0; - virtual const char* getGivenName() const=0; - virtual const char* getSurName() const=0; - virtual saml::Iterator getEmailAddresses() const=0; - virtual saml::Iterator getTelephoneNumbers() const=0; - virtual const DOMElement* getElement() const=0; - virtual ~IContactPerson() {} - }; - - struct SHIB_EXPORTS IOrganization - { - virtual const char* getName(const char* lang="en") const=0; - virtual const char* getDisplayName(const char* lang="en") const=0; - virtual const char* getURL(const char* lang="en") const=0; - virtual const DOMElement* getElement() const=0; - virtual ~IOrganization() {} - }; - - struct SHIB_EXPORTS IKeyDescriptor - { - enum KeyUse { unspecified, encryption, signing }; - virtual KeyUse getUse() const=0; - virtual DSIGKeyInfoList* getKeyInfo() const=0; - virtual saml::Iterator getEncryptionMethods() const=0; - virtual ~IKeyDescriptor() {} - }; - - struct SHIB_EXPORTS IEndpoint - { - virtual const XMLCh* getBinding() const=0; - virtual const XMLCh* getLocation() const=0; - virtual const XMLCh* getResponseLocation() const=0; - virtual const DOMElement* getElement() const=0; - virtual ~IEndpoint() {} - }; - - struct SHIB_EXPORTS IIndexedEndpoint : public virtual IEndpoint - { - virtual unsigned short getIndex() const=0; - virtual ~IIndexedEndpoint() {} - }; - - struct SHIB_EXPORTS IEndpointManager - { - virtual saml::Iterator getEndpoints() const=0; - virtual const IEndpoint* getDefaultEndpoint() const=0; - virtual const IEndpoint* getEndpointByIndex(unsigned short index) const=0; - virtual const IEndpoint* getEndpointByBinding(const XMLCh* binding) const=0; - virtual ~IEndpointManager() {} - }; - - struct SHIB_EXPORTS IEntityDescriptor; - struct SHIB_EXPORTS IRoleDescriptor - { - virtual const IEntityDescriptor* getEntityDescriptor() const=0; - virtual saml::Iterator getProtocolSupportEnumeration() const=0; - virtual bool hasSupport(const XMLCh* protocol) const=0; - virtual bool isValid() const=0; - virtual const char* getErrorURL() const=0; - virtual saml::Iterator getKeyDescriptors() const=0; - virtual const IOrganization* getOrganization() const=0; - virtual saml::Iterator getContactPersons() const=0; - virtual const DOMElement* getElement() const=0; - virtual ~IRoleDescriptor() {} - }; - - struct SHIB_EXPORTS ISSODescriptor : public virtual IRoleDescriptor - { - virtual const IEndpointManager* getArtifactResolutionServiceManager() const=0; - virtual const IEndpointManager* getSingleLogoutServiceManager() const=0; - virtual const IEndpointManager* getManageNameIDServiceManager() const=0; - virtual saml::Iterator getNameIDFormats() const=0; - virtual ~ISSODescriptor() {} - }; - - struct SHIB_EXPORTS IIDPSSODescriptor : public virtual ISSODescriptor - { - virtual bool getWantAuthnRequestsSigned() const=0; - virtual const IEndpointManager* getSingleSignOnServiceManager() const=0; - virtual const IEndpointManager* getNameIDMappingServiceManager() const=0; - virtual const IEndpointManager* getAssertionIDRequestServiceManager() const=0; - virtual saml::Iterator getAttributeProfiles() const=0; - virtual saml::Iterator getAttributes() const=0; - virtual ~IIDPSSODescriptor() {} - }; - - struct SHIB_EXPORTS IAttributeConsumingService - { - virtual const XMLCh* getName(const char* lang="en") const=0; - virtual const XMLCh* getDescription(const char* lang="en") const=0; - virtual saml::Iterator > getRequestedAttributes() const=0; - virtual ~IAttributeConsumingService() {} - }; - - struct SHIB_EXPORTS ISPSSODescriptor : public virtual ISSODescriptor - { - virtual bool getAuthnRequestsSigned() const=0; - virtual bool getWantAssertionsSigned() const=0; - virtual const IEndpointManager* getAssertionConsumerServiceManager() const=0; - virtual saml::Iterator getAttributeConsumingServices() const=0; - virtual const IAttributeConsumingService* getDefaultAttributeConsumingService() const=0; - virtual const IAttributeConsumingService* getAttributeConsumingServiceByID(const XMLCh* id) const=0; - virtual ~ISPSSODescriptor() {} - }; - - struct SHIB_EXPORTS IAuthnAuthorityDescriptor : public virtual IRoleDescriptor - { - virtual const IEndpointManager* getAuthnQueryServiceManager() const=0; - virtual const IEndpointManager* getAssertionIDRequestServiceManager() const=0; - virtual saml::Iterator getNameIDFormats() const=0; - virtual ~IAuthnAuthorityDescriptor() {} - }; - - struct SHIB_EXPORTS IPDPDescriptor : public virtual IRoleDescriptor - { - virtual const IEndpointManager* getAuthzServiceManager() const=0; - virtual const IEndpointManager* getAssertionIDRequestServiceManager() const=0; - virtual saml::Iterator getNameIDFormats() const=0; - virtual ~IPDPDescriptor() {} - }; - - struct SHIB_EXPORTS IAttributeAuthorityDescriptor : public virtual IRoleDescriptor - { - virtual const IEndpointManager* getAttributeServiceManager() const=0; - virtual const IEndpointManager* getAssertionIDRequestServiceManager() const=0; - virtual saml::Iterator getNameIDFormats() const=0; - virtual saml::Iterator getAttributeProfiles() const=0; - virtual saml::Iterator getAttributes() const=0; - virtual ~IAttributeAuthorityDescriptor() {} - }; - - struct SHIB_EXPORTS IAffiliationDescriptor - { - virtual const IEntityDescriptor* getEntityDescriptor() const=0; - virtual const XMLCh* getOwnerID() const=0; - virtual bool isValid() const=0; - virtual saml::Iterator getMembers() const=0; - virtual bool isMember(const XMLCh* id) const=0; - virtual saml::Iterator getKeyDescriptors() const=0; - virtual const DOMElement* getElement() const=0; - virtual ~IAffiliationDescriptor() {} - }; - - struct SHIB_EXPORTS IEntitiesDescriptor; - struct SHIB_EXPORTS IEntityDescriptor - { - virtual const XMLCh* getId() const=0; - virtual bool isValid() const=0; - virtual saml::Iterator getRoleDescriptors() const=0; - virtual const IIDPSSODescriptor* getIDPSSODescriptor(const XMLCh* protocol) const=0; - virtual const ISPSSODescriptor* getSPSSODescriptor(const XMLCh* protocol) const=0; - virtual const IAuthnAuthorityDescriptor* getAuthnAuthorityDescriptor(const XMLCh* protocol) const=0; - virtual const IAttributeAuthorityDescriptor* getAttributeAuthorityDescriptor(const XMLCh* protocol) const=0; - virtual const IPDPDescriptor* getPDPDescriptor(const XMLCh* protocol) const=0; - virtual const IAffiliationDescriptor* getAffiliationDescriptor() const=0; - virtual const IOrganization* getOrganization() const=0; - virtual saml::Iterator getContactPersons() const=0; - virtual saml::Iterator > getAdditionalMetadataLocations() const=0; - virtual const IEntitiesDescriptor* getEntitiesDescriptor() const=0; - virtual const DOMElement* getElement() const=0; - virtual ~IEntityDescriptor() {} - }; - - struct SHIB_EXPORTS IEntitiesDescriptor - { - virtual const XMLCh* getName() const=0; - virtual bool isValid() const=0; - virtual const IEntitiesDescriptor* getEntitiesDescriptor() const=0; - virtual saml::Iterator getEntitiesDescriptors() const=0; - virtual saml::Iterator getEntityDescriptors() const=0; - virtual const DOMElement* getElement() const=0; - virtual ~IEntitiesDescriptor() {} - }; - - // Shib extension interfaces - struct SHIB_EXPORTS IKeyAuthority - { - virtual int getVerifyDepth() const=0; - virtual saml::Iterator getKeyInfos() const=0; - virtual ~IKeyAuthority() {} - }; - - struct SHIB_EXPORTS IExtendedEntityDescriptor : public virtual IEntityDescriptor - { - virtual saml::Iterator getKeyAuthorities() const=0; - virtual saml::Iterator > getScopes() const=0; - virtual ~IExtendedEntityDescriptor() {} - }; - - struct SHIB_EXPORTS IExtendedEntitiesDescriptor : public virtual IEntitiesDescriptor - { - virtual saml::Iterator getKeyAuthorities() const=0; - virtual ~IExtendedEntitiesDescriptor() {} - }; - - struct SHIB_EXPORTS IMetadata : public virtual saml::ILockable, public virtual saml::IPlugIn - { - virtual const IEntityDescriptor* lookup(const char* id, bool strict=true) const=0; - virtual const IEntityDescriptor* lookup(const XMLCh* id, bool strict=true) const=0; - virtual const IEntityDescriptor* lookup(const saml::SAMLArtifact* artifact) const=0; - virtual const IEntitiesDescriptor* lookupGroup(const char* name, bool strict=true) const=0; - virtual const IEntitiesDescriptor* lookupGroup(const XMLCh* name, bool strict=true) const=0; - virtual std::pair getRoot() const=0; - virtual ~IMetadata() {} - }; - - // Trust interface hides *all* details of signature and SSL validation. - // Pluggable providers can fully override the Shibboleth trust model here. - - struct SHIB_EXPORTS ITrust : public virtual saml::IPlugIn - { - // Performs certificate validation processing of an untrusted certificates - // using a library-specific representation, in this case an OpenSSL X509* - virtual bool validate( - void* certEE, - const saml::Iterator& certChain, - const IRoleDescriptor* role, - bool checkName=true - )=0; - - // Validates signed SAML messages and assertions sent by an entity acting in a specific role. - // If certificate validation is required, the trust provider used can be overridden using - // the last parameter, or left null and the provider will rely on itself. - virtual bool validate( - const saml::SAMLSignedObject& token, - const IRoleDescriptor* role, - ITrust* certValidator=NULL - )=0; - - virtual ~ITrust() {} - }; - // Credentials interface abstracts access to "owned" keys and certificates. struct SHIB_EXPORTS ICredResolver : public virtual saml::IPlugIn @@ -311,7 +70,7 @@ namespace shibboleth virtual const char* getAlias() const=0; virtual const char* getHeader() const=0; virtual bool getCaseSensitive() const=0; - virtual void apply(saml::SAMLAttribute& attribute, const IEntityDescriptor* source=NULL) const=0; + virtual void apply(saml::SAMLAttribute& attribute, const opensaml::saml2md::RoleDescriptor* role=NULL) const=0; virtual ~IAttributeRule() {} }; @@ -331,66 +90,12 @@ namespace shibboleth }; #ifdef SHIB_INSTANTIATE - template class SHIB_EXPORTS saml::Iterator; - template class SHIB_EXPORTS saml::Iterator; - template class SHIB_EXPORTS saml::Iterator; - template class SHIB_EXPORTS saml::Iterator; - template class SHIB_EXPORTS saml::Iterator; - template class SHIB_EXPORTS saml::Iterator; - template class SHIB_EXPORTS saml::Iterator; - template class SHIB_EXPORTS saml::Iterator; - template class SHIB_EXPORTS saml::Iterator; - template class SHIB_EXPORTS saml::Iterator; - template class SHIB_EXPORTS saml::Iterator; - template class SHIB_EXPORTS saml::Iterator; - template class SHIB_EXPORTS saml::ArrayIterator; - template class SHIB_EXPORTS saml::Iterator; - template class SHIB_EXPORTS saml::ArrayIterator; template class SHIB_EXPORTS saml::Iterator; template class SHIB_EXPORTS saml::ArrayIterator; template class SHIB_EXPORTS saml::Iterator; template class SHIB_EXPORTS saml::ArrayIterator; #endif - // Glue classes between abstract metadata and concrete providers - - class SHIB_EXPORTS Metadata - { - public: - Metadata(const saml::Iterator& metadatas) : m_metadatas(metadatas), m_mapper(NULL) {} - ~Metadata(); - - const IEntityDescriptor* lookup(const char* id, bool strict=true); - const IEntityDescriptor* lookup(const XMLCh* id, bool strict=true); - const IEntityDescriptor* lookup(const saml::SAMLArtifact* artifact); - - private: - Metadata(const Metadata&); - void operator=(const Metadata&); - IMetadata* m_mapper; - saml::Iterator m_metadatas; - }; - - class SHIB_EXPORTS Trust - { - public: - Trust(const saml::Iterator& trusts) : m_trusts(trusts) {} - ~Trust() {} - - bool validate( - void* certEE, - const saml::Iterator& certChain, - const IRoleDescriptor* role, - bool checkName=true - ) const; - bool validate(const saml::SAMLSignedObject& token, const IRoleDescriptor* role) const; - - private: - Trust(const Trust&); - void operator=(const Trust&); - saml::Iterator m_trusts; - }; - class SHIB_EXPORTS Credentials { public: @@ -416,7 +121,9 @@ namespace shibboleth const IAttributeRule* operator->() const {return m_rule;} operator const IAttributeRule*() const {return m_rule;} - static void apply(const saml::Iterator& aaps, saml::SAMLAssertion& assertion, const IEntityDescriptor* source=NULL); + static void apply( + const saml::Iterator& aaps, saml::SAMLAssertion& assertion, const opensaml::saml2md::RoleDescriptor* role=NULL + ); private: AAP(const AAP&); @@ -434,16 +141,16 @@ namespace shibboleth virtual void validateToken( saml::SAMLAssertion* token, time_t=0, - const IRoleDescriptor* role=NULL, - const saml::Iterator& trusts=EMPTY(ITrust*) + const opensaml::saml2md::RoleDescriptor* role=NULL, + const xmltooling::TrustEngine* trustEngine=NULL ) const=0; virtual ~ITokenValidator() {} }; ShibBrowserProfile( const ITokenValidator* validator, - const saml::Iterator& metadatas=EMPTY(IMetadata*), - const saml::Iterator& trusts=EMPTY(ITrust*) + opensaml::saml2md::MetadataProvider* metadata=NULL, + xmltooling::TrustEngine* trust=NULL ); virtual ~ShibBrowserProfile(); @@ -465,8 +172,8 @@ namespace shibboleth void postprocess(saml::SAMLBrowserProfile::BrowserProfileResponse& bpr, int minorVersion=1) const; saml::SAMLBrowserProfile* m_profile; - saml::Iterator m_metadatas; - saml::Iterator m_trusts; + opensaml::saml2md::MetadataProvider* m_metadata; + xmltooling::TrustEngine* m_trust; const ITokenValidator* m_validator; }; @@ -529,17 +236,6 @@ namespace shibboleth time_t m_filestamp; xmltooling::RWLock* m_lock; }; - - /* These helpers attach metadata-derived information as exception properties and then - * rethrow the object. The following properties are attached, when possible: - * - * providerId The unique ID of the entity - * errorURL The error support URL of the entity or role - * contactName A formatted support or technical contact name - * contactEmail A contact email address - */ - SHIB_EXPORTS void annotateException(saml::SAMLException* e, const IEntityDescriptor* entity, bool rethrow=true); - SHIB_EXPORTS void annotateException(saml::SAMLException* e, const IRoleDescriptor* role, bool rethrow=true); } #endif diff --git a/shib/shib.vcproj b/shib/shib.vcproj index 29f7745..cc0df45 100644 --- a/shib/shib.vcproj +++ b/shib/shib.vcproj @@ -214,10 +214,6 @@ - - @@ -254,10 +250,6 @@ > - - diff --git a/shibsp/MetadataExt.h b/shibsp/MetadataExt.h index e0a0d6d..f620150 100644 --- a/shibsp/MetadataExt.h +++ b/shibsp/MetadataExt.h @@ -34,7 +34,7 @@ namespace shibsp { BEGIN_XMLOBJECT(SHIBSP_API,Scope,xmltooling::XMLObject,Scope element); - DECL_BOOLEAN_ATTRIB(regexp,REGEXP,false); + DECL_BOOLEAN_ATTRIB(Regexp,REGEXP,false); DECL_SIMPLE_CONTENT(Value); END_XMLOBJECT; diff --git a/shibsp/MetadataExtImpl.cpp b/shibsp/MetadataExtImpl.cpp index 208035f..614217b 100644 --- a/shibsp/MetadataExtImpl.cpp +++ b/shibsp/MetadataExtImpl.cpp @@ -54,7 +54,7 @@ namespace shibsp { public AbstractXMLObjectUnmarshaller { void init() { - m_regexp=XML_BOOL_NULL; + m_Regexp=XML_BOOL_NULL; } public: @@ -67,19 +67,19 @@ namespace shibsp { ScopeImpl(const ScopeImpl& src) : AbstractXMLObject(src), AbstractSimpleElement(src), AbstractDOMCachingXMLObject(src) { init(); - regexp(src.m_regexp); + Regexp(src.m_Regexp); } IMPL_XMLOBJECT_CLONE(Scope); - IMPL_BOOLEAN_ATTRIB(regexp); + IMPL_BOOLEAN_ATTRIB(Regexp); protected: void marshallAttributes(DOMElement* domElement) const { - MARSHALL_BOOLEAN_ATTRIB(regexp,REGEXP,NULL); + MARSHALL_BOOLEAN_ATTRIB(Regexp,REGEXP,NULL); } void processAttribute(const DOMAttr* attribute) { - PROC_BOOLEAN_ATTRIB(regexp,REGEXP,NULL); + PROC_BOOLEAN_ATTRIB(Regexp,REGEXP,NULL); AbstractXMLObjectUnmarshaller::processAttribute(attribute); } }; diff --git a/shibsp/SPConfig.cpp b/shibsp/SPConfig.cpp index 9e37be3..d92bdca 100644 --- a/shibsp/SPConfig.cpp +++ b/shibsp/SPConfig.cpp @@ -74,8 +74,11 @@ bool SPInternalConfig::init(const char* catalog_path) loglevel = SHIBSP_LOGGING; XMLToolingConfig::getConfig().log_config(loglevel); - if (catalog_path) - XMLToolingConfig::getConfig().catalog_path = catalog_path; + if (!catalog_path) + catalog_path = getenv("SHIBSP_SCHEMAS"); + if (!catalog_path) + catalog_path = SHIBSP_SCHEMAS; + XMLToolingConfig::getConfig().catalog_path = catalog_path; if (!SAMLConfig::getConfig().init()) { log.fatal("failed to initialize OpenSAML library"); diff --git a/shibsp/SocketListener.cpp b/shibsp/SocketListener.cpp index baab25f..cdec2ce 100644 --- a/shibsp/SocketListener.cpp +++ b/shibsp/SocketListener.cpp @@ -482,10 +482,15 @@ bool ServerThread::job() // Dispatch the message. out=m_listener->receive(in); } - catch (XMLToolingException &e) { + catch (XMLToolingException& e) { log.error("error processing incoming message: %s", e.what()); out=DDF("exception").string(e.toString().c_str()); } + catch (exception& e) { + log.error("error processing incoming message: %s", e.what()); + ListenerException ex(e.what()); + out=DDF("exception").string(ex.toString().c_str()); + } #ifndef _DEBUG catch (...) { log.error("unexpected error processing incoming message"); diff --git a/shibsp/base.h b/shibsp/base.h index 774d7a1..29e20bd 100644 --- a/shibsp/base.h +++ b/shibsp/base.h @@ -66,7 +66,7 @@ /** * Default catalog path on Windows. */ -# define SHIBSP_SCHEMAS "/opt/shibboleth-sp/share/xml/xmltooling/catalog.xml;/opt/shibboleth-sp/share/xml/opensaml/catalog.xml;/opt/shibboleth-sp/share/xml/shibboleth/catalog.xml" +# define SHIBSP_SCHEMAS "/opt/shibboleth-sp/share/xml/xmltooling/catalog.xml;/opt/shibboleth-sp/share/xml/opensaml/saml20-catalog.xml;/opt/shibboleth-sp/share/xml/opensaml/saml11-catalog.xml;/opt/shibboleth-sp/share/xml/shibboleth/catalog.xml" /** * Default path to configuration file on Windows. diff --git a/shibsp/internal.h b/shibsp/internal.h index 95ca5c2..3827616 100644 --- a/shibsp/internal.h +++ b/shibsp/internal.h @@ -21,9 +21,9 @@ #ifndef __shibsp_internal_h__ #define __shibsp_internal_h__ -#ifndef FD_SETSIZE -# define FD_SETSIZE 1024 -#endif +#ifndef FD_SETSIZE +# define FD_SETSIZE 1024 +#endif #ifdef WIN32 # define _CRT_SECURE_NO_DEPRECATE 1 diff --git a/test/shibtest.cpp b/test/shibtest.cpp index 918eaa4..e5bd7d6 100644 --- a/test/shibtest.cpp +++ b/test/shibtest.cpp @@ -25,7 +25,7 @@ using namespace shibsp; using namespace shibtarget; -using namespace shibboleth; +using namespace opensaml::saml2md; using namespace saml; using namespace std; @@ -107,46 +107,42 @@ int main(int argc,char* argv[]) ) ); - Metadata m(app->getMetadataProviders()); - const IEntityDescriptor* site=m.lookup(domain.get()); + MetadataProvider* m=app->getMetadataProvider(); + xmltooling::Locker locker(m); + const EntityDescriptor* site=m->getEntityDescriptor(domain.get()); if (!site) - throw SAMLException("Unable to locate specified origin site's metadata."); + throw MetadataException("Unable to locate specified origin site's metadata."); // Try to locate an AA role. - const IAttributeAuthorityDescriptor* AA=site->getAttributeAuthorityDescriptor(saml::XML::SAML11_PROTOCOL_ENUM); + const AttributeAuthorityDescriptor* AA=site->getAttributeAuthorityDescriptor(saml::XML::SAML11_PROTOCOL_ENUM); if (!AA) - throw SAMLException("Unable to locate metadata for origin site's Attribute Authority."); + throw MetadataException("Unable to locate metadata for origin site's Attribute Authority."); ShibHTTPHook::ShibHTTPHookCallContext ctx(app->getCredentialUse(site),AA); - Trust t(app->getTrustProviders()); SAMLResponse* response=NULL; - Iterator endpoints=AA->getAttributeServiceManager()->getEndpoints(); - while (!response && endpoints.hasNext()) { - const IEndpoint* ep=endpoints.next(); + const vector& endpoints=AA->getAttributeServices(); + for (vector::const_iterator ep=endpoints.begin(); !response && ep!=endpoints.end(); ++ep) { try { // Get a binding object for this protocol. - const SAMLBinding* binding = app->getBinding(ep->getBinding()); + const SAMLBinding* binding = app->getBinding((*ep)->getBinding()); if (!binding) { continue; } - auto_ptr r(binding->send(ep->getLocation(), *(req.get()), &ctx)); - if (r->isSigned() && !t.validate(*r,AA)) - throw TrustException("unable to verify signed response"); - response = r.release(); + response=binding->send((*ep)->getLocation(), *(req.get()), &ctx); } - catch (SAMLException&) { + catch (exception&) { } } if (!response) - throw SAMLException("unable to successfully query for attributes"); + throw opensaml::BindingException("unable to successfully query for attributes"); // Run it through the AAP. Note that we could end up with an empty response! Iterator a=response->getAssertions(); for (unsigned long c=0; c < a.size();) { try { - AAP::apply(app->getAAPProviders(),*(a[c]),site); + shibboleth::AAP::apply(app->getAAPProviders(),*(a[c]),AA); c++; } catch (SAMLException&) { @@ -195,13 +191,9 @@ int main(int argc,char* argv[]) } } } - catch(SAMLException& e) - { - cerr << "caught a SAML exception: " << e.what() << endl; - } - catch(XMLException& e) + catch(exception& e) { - cerr << "caught an XML exception: "; xmlout(cerr,e.getMessage()); cerr << endl; + cerr << "caught an exception: " << e.what() << endl; } conf.shutdown(); diff --git a/xmlproviders/CredResolvers.cpp b/xmlproviders/CredResolvers.cpp index 89608d9..2c98ded 100644 --- a/xmlproviders/CredResolvers.cpp +++ b/xmlproviders/CredResolvers.cpp @@ -32,9 +32,10 @@ #include #include #include +#include -using namespace saml; using namespace shibboleth; +using namespace xmltooling; using namespace log4cpp; using namespace std; @@ -77,7 +78,7 @@ private: vector m_xseccerts; }; -IPlugIn* FileCredResolverFactory(const DOMElement* e) +saml::IPlugIn* FileCredResolverFactory(const DOMElement* e) { return new FileResolver(e); } @@ -85,7 +86,7 @@ IPlugIn* FileCredResolverFactory(const DOMElement* e) FileResolver::FileResolver(const DOMElement* e) { #ifdef _DEBUG - saml::NDC ndc("FileResolver"); + xmltooling::NDC ndc("FileResolver"); #endif Category& log=Category::getInstance(XMLPROVIDERS_LOGCAT".CredResolvers"); @@ -120,13 +121,13 @@ FileResolver::FileResolver(const DOMElement* e) #endif { log.error("key file (%s) can't be opened", kpath.get()); - throw CredentialException("FileResolver can't access key file ($1)",params(1,kpath.get())); + throw IOException("FileResolver can't access key file ($1)",params(1,kpath.get())); } m_keypath=kpath.get(); } else { log.error("Path element missing inside Key element"); - throw CredentialException("FileResolver can't access key file, no Path element specified."); + throw IOException("FileResolver can't access key file, no Path element specified."); } // Determine the key encoding format dynamically, if not explicitly specified @@ -139,7 +140,7 @@ FileResolver::FileResolver(const DOMElement* e) else { auto_ptr_char unknown(format_xml); log.error("Configuration specifies unknown key encoding format (%s)", unknown.get()); - throw CredentialException("FileResolver configuration contains unknown key encoding format ($1)",params(1,unknown.get())); + throw IOException("FileResolver configuration contains unknown key encoding format ($1)",params(1,unknown.get())); } } else { @@ -150,7 +151,7 @@ FileResolver::FileResolver(const DOMElement* e) } else { log.error("Key file (%s) can't be read to determine encoding format", m_keypath.c_str()); - throw CredentialException("FileResolver can't read key file ($1) to determine encoding format",params(1,m_keypath.c_str())); + throw IOException("FileResolver can't read key file ($1) to determine encoding format",params(1,m_keypath.c_str())); } if (in) BIO_free(in); @@ -173,7 +174,7 @@ FileResolver::FileResolver(const DOMElement* e) DOMElement* ep=saml::XML::getFirstChildElement(e,::XML::CREDS_NS,SHIB_L(Path)); if (!ep || !ep->hasChildNodes()) { log.error("Path element missing inside Certificate element"); - throw CredentialException("FileResolver can't access certificate file, missing Path element."); + throw IOException("FileResolver can't access certificate file, missing Path element."); } auto_ptr_char certpath(ep->getFirstChild()->getNodeValue()); @@ -183,7 +184,7 @@ FileResolver::FileResolver(const DOMElement* e) if (format == UNKNOWN) { auto_ptr_char unknown(format_xml); log.error("Configuration specifies unknown certificate encoding format (%s)", unknown.get()); - throw CredentialException("FileResolver configuration contains unknown certificate encoding format ($1)",params(1,unknown.get())); + throw IOException("FileResolver configuration contains unknown certificate encoding format ($1)",params(1,unknown.get())); } } @@ -212,7 +213,7 @@ FileResolver::FileResolver(const DOMElement* e) else { log_openssl(); BIO_free(in); - throw CredentialException("FileResolver unable to load DER certificate from file ($1)",params(1,certpath.get())); + throw IOException("FileResolver unable to load DER certificate from file ($1)",params(1,certpath.get())); } break; @@ -228,7 +229,7 @@ FileResolver::FileResolver(const DOMElement* e) } else { log_openssl(); BIO_free(in); - throw CredentialException("FileResolver unable to load PKCS12 certificate from file ($1)",params(1,certpath.get())); + throw IOException("FileResolver unable to load PKCS12 certificate from file ($1)",params(1,certpath.get())); } break; } // end switch @@ -239,7 +240,7 @@ FileResolver::FileResolver(const DOMElement* e) BIO_free(in); in=NULL; } - throw CredentialException("FileResolver unable to load certificate(s) from file ($1)",params(1,certpath.get())); + throw IOException("FileResolver unable to load certificate(s) from file ($1)",params(1,certpath.get())); } if (in) { BIO_free(in); @@ -247,7 +248,7 @@ FileResolver::FileResolver(const DOMElement* e) } if (m_certs.empty()) { - throw CredentialException("FileResolver unable to load any certificate(s)"); + throw IOException("FileResolver unable to load any certificate(s)"); } // Load any extra CA files. @@ -281,7 +282,7 @@ FileResolver::FileResolver(const DOMElement* e) else { log_openssl(); BIO_free(in); - throw CredentialException("FileResolver unable to load DER CA certificate from file ($1)",params(1,capath.get())); + throw IOException("FileResolver unable to load DER CA certificate from file ($1)",params(1,capath.get())); } break; @@ -297,7 +298,7 @@ FileResolver::FileResolver(const DOMElement* e) } else { log_openssl(); BIO_free(in); - throw CredentialException("FileResolver unable to load PKCS12 CA certificate from file ($1)",params(1,capath.get())); + throw IOException("FileResolver unable to load PKCS12 CA certificate from file ($1)",params(1,capath.get())); } break; } //end switch @@ -309,7 +310,7 @@ FileResolver::FileResolver(const DOMElement* e) BIO_free(in); log_openssl(); log.error("CA file (%s) can't be opened", capath.get()); - throw CredentialException("FileResolver can't open CA file ($1)",params(1,capath.get())); + throw IOException("FileResolver can't open CA file ($1)",params(1,capath.get())); } } } @@ -373,7 +374,7 @@ void FileResolver::attach(void* ctx) const if (ret!=1) { log_openssl(); - throw CredentialException("Unable to attach private key to SSL context"); + throw IOException("Unable to attach private key to SSL context"); } // Attach certs. @@ -381,7 +382,7 @@ void FileResolver::attach(void* ctx) const if (i==m_certs.begin()) { if (SSL_CTX_use_certificate(ssl_ctx, *i) != 1) { log_openssl(); - throw CredentialException("Unable to attach SP client certificate to SSL context"); + throw IOException("Unable to attach SP client certificate to SSL context"); } } else { @@ -390,7 +391,7 @@ void FileResolver::attach(void* ctx) const if (SSL_CTX_add_extra_chain_cert(ssl_ctx, dup) != 1) { X509_free(dup); log_openssl(); - throw CredentialException("Unable to attach CA certificate to SSL context"); + throw IOException("Unable to attach CA certificate to SSL context"); } } } @@ -514,11 +515,11 @@ FileResolver::format_t FileResolver::getEncodingFormat(BIO* in) const try { if ( (mark = BIO_tell(in)) < 0 ) - throw CredentialException("getEncodingFormat: BIO_tell() can't get the file position"); + throw IOException("getEncodingFormat: BIO_tell() can't get the file position"); if ( BIO_read(in, buf, READSIZE) <= 0 ) - throw CredentialException("getEncodingFormat: BIO_read() can't read from the stream"); + throw IOException("getEncodingFormat: BIO_read() can't read from the stream"); if ( BIO_seek(in, mark) < 0 ) - throw CredentialException("getEncodingFormat: BIO_seek() can't reset the file position"); + throw IOException("getEncodingFormat: BIO_seek() can't reset the file position"); } catch (...) { log_openssl(); @@ -547,7 +548,7 @@ FileResolver::format_t FileResolver::getEncodingFormat(BIO* in) const PKCS12_free(p12); if ( BIO_seek(in, mark) < 0 ) { log_openssl(); - throw CredentialException("getEncodingFormat: BIO_seek() can't reset the file position"); + throw IOException("getEncodingFormat: BIO_seek() can't reset the file position"); } } diff --git a/xmlproviders/Makefile.am b/xmlproviders/Makefile.am index 5dbf938..2a73993 100644 --- a/xmlproviders/Makefile.am +++ b/xmlproviders/Makefile.am @@ -18,7 +18,6 @@ xmlproviders_la_SOURCES = \ XMLAAP.cpp \ XMLAccessControl.cpp \ XMLCredentials.cpp \ - XMLMetadata.cpp \ XMLProviders.cpp diff --git a/xmlproviders/TargetedID.cpp b/xmlproviders/TargetedID.cpp index 8801d1d..c021add 100644 --- a/xmlproviders/TargetedID.cpp +++ b/xmlproviders/TargetedID.cpp @@ -23,10 +23,12 @@ */ #include "internal.h" +#include #include using namespace shibboleth; using namespace saml; +using namespace opensaml::saml2; using namespace std; namespace { @@ -201,10 +203,10 @@ void TargetedID::removeValue(unsigned long index) void TargetedID::valueFromDOM(DOMElement* e) { // Look for a SAML2 NameID. - e=saml::XML::getFirstChildElement(e,::XML::SAML2ASSERT_NS,NameID); - if (e && !XMLString::compareString(FORMAT_PERSISTENT,e->getAttributeNS(NULL,L(Format)))) { - m_nameQualifiers.push_back(e->getAttributeNS(NULL,L(NameQualifier))); - m_spNameQualifiers.push_back(e->getAttributeNS(NULL,SPNameQualifier)); + e=saml::XML::getFirstChildElement(e,samlconstants::SAML20_NS,NameID::LOCAL_NAME); + if (e && !XMLString::compareString(NameIDType::PERSISTENT,e->getAttributeNS(NULL,NameIDType::FORMAT_ATTRIB_NAME))) { + m_nameQualifiers.push_back(e->getAttributeNS(NULL,NameIDType::NAMEQUALIFIER_ATTRIB_NAME)); + m_spNameQualifiers.push_back(e->getAttributeNS(NULL,NameIDType::SPNAMEQUALIFIER_ATTRIB_NAME)); if (e->hasChildNodes() && e->getFirstChild()->getNodeType()==DOMNode::TEXT_NODE) m_values.push_back(e->getFirstChild()->getNodeValue()); else @@ -225,10 +227,10 @@ void TargetedID::valueToDOM(unsigned int index, DOMElement* e) const const XMLCh* val=m_values[index]; if (!saml::XML::isEmpty(nq) && !saml::XML::isEmpty(spnq) && !saml::XML::isEmpty(val)) { // Build a SAML2 NameID. - DOMElement* nameid=e->getOwnerDocument()->createElementNS(::XML::SAML2ASSERT_NS,NameID); - nameid->setAttributeNS(NULL,L(Format),FORMAT_PERSISTENT); - nameid->setAttributeNS(NULL,L(NameQualifier),nq); - nameid->setAttributeNS(NULL,SPNameQualifier,spnq); + DOMElement* nameid=e->getOwnerDocument()->createElementNS(samlconstants::SAML20_NS,NameID::LOCAL_NAME); + nameid->setAttributeNS(NULL,NameIDType::FORMAT_ATTRIB_NAME,NameIDType::PERSISTENT); + nameid->setAttributeNS(NULL,NameIDType::NAMEQUALIFIER_ATTRIB_NAME,nq); + nameid->setAttributeNS(NULL,NameIDType::SPNAMEQUALIFIER_ATTRIB_NAME,spnq); nameid->appendChild(e->getOwnerDocument()->createTextNode(val)); e->appendChild(nameid); } @@ -238,21 +240,3 @@ SAMLObject* TargetedID::clone() const { return new TargetedID(m_name,m_namespace,m_type,m_lifetime,m_values,m_nameQualifiers,m_spNameQualifiers); } - -const XMLCh TargetedID::NameID[] = -{ chLatin_N, chLatin_a, chLatin_m, chLatin_e, chLatin_I, chLatin_D, chNull }; - -const XMLCh TargetedID::SPNameQualifier[] = -{ chLatin_S, chLatin_P, chLatin_N, chLatin_a, chLatin_m, chLatin_e, - chLatin_Q, chLatin_u, chLatin_a, chLatin_l, chLatin_i, chLatin_f, chLatin_i, chLatin_e, chLatin_r, chNull -}; - -const XMLCh TargetedID::FORMAT_PERSISTENT[] = -{ - chLatin_u, chLatin_r, chLatin_n, chColon, chLatin_o, chLatin_a, chLatin_s, chLatin_i, chLatin_s, chColon, - chLatin_n, chLatin_a, chLatin_m, chLatin_e, chLatin_s, chColon, chLatin_t, chLatin_c, chColon, - chLatin_S, chLatin_A, chLatin_M, chLatin_L, chColon, chDigit_2, chPeriod, chDigit_0, chColon, - chLatin_n, chLatin_a, chLatin_m, chLatin_e, chLatin_i, chLatin_d, chDash, - chLatin_f, chLatin_o, chLatin_r, chLatin_m, chLatin_a, chLatin_t, chColon, - chLatin_p, chLatin_e, chLatin_r, chLatin_s, chLatin_i, chLatin_s, chLatin_t, chLatin_e, chLatin_n, chLatin_t, chNull -}; diff --git a/xmlproviders/XML.cpp b/xmlproviders/XML.cpp index 61fa8d9..ca910ea 100644 --- a/xmlproviders/XML.cpp +++ b/xmlproviders/XML.cpp @@ -37,19 +37,6 @@ const XMLCh XML::SHIB_SCHEMA_ID[] = // shibboleth.xsd chPeriod, chLatin_x, chLatin_s, chLatin_d, chNull }; -const XMLCh XML::SHIBMETA_NS[] = // urn:mace:shibboleth:metadata:1.0 -{ chLatin_u, chLatin_r, chLatin_n, chColon, chLatin_m, chLatin_a, chLatin_c, chLatin_e, chColon, - chLatin_s, chLatin_h, chLatin_i, chLatin_b, chLatin_b, chLatin_o, chLatin_l, chLatin_e, chLatin_t, chLatin_h, chColon, - chLatin_m, chLatin_e, chLatin_t, chLatin_a, chLatin_d, chLatin_a, chLatin_t, chLatin_a, chColon, - chDigit_1, chPeriod, chDigit_0, chNull -}; - -const XMLCh XML::SHIBMETA_SCHEMA_ID[] = // shibboleth-metadata-1.0.xsd -{ chLatin_s, chLatin_h, chLatin_i, chLatin_b, chLatin_b, chLatin_o, chLatin_l, chLatin_e, chLatin_t, chLatin_h, chDash, - chLatin_m, chLatin_e, chLatin_t, chLatin_a, chLatin_d, chLatin_a, chLatin_t, chLatin_a, chDash, - chDigit_1, chPeriod, chDigit_0, chPeriod, chLatin_x, chLatin_s, chLatin_d, chNull -}; - const XMLCh XML::CREDS_NS[] = // urn:mace:shibboleth:credentials:1.0 { chLatin_u, chLatin_r, chLatin_n, chColon, chLatin_m, chLatin_a, chLatin_c, chLatin_e, chColon, chLatin_s, chLatin_h, chLatin_i, chLatin_b, chLatin_b, chLatin_o, chLatin_l, chLatin_e, chLatin_t, chLatin_h, chColon, @@ -62,112 +49,8 @@ const XMLCh XML::CREDS_SCHEMA_ID[] = // credentials.xsd chPeriod, chLatin_x, chLatin_s, chLatin_d, chNull }; -const XMLCh XML::TRUST_NS[] = // urn:mace:shibboleth:trust:1.0 -{ chLatin_u, chLatin_r, chLatin_n, chColon, chLatin_m, chLatin_a, chLatin_c, chLatin_e, chColon, - chLatin_s, chLatin_h, chLatin_i, chLatin_b, chLatin_b, chLatin_o, chLatin_l, chLatin_e, chLatin_t, chLatin_h, chColon, - chLatin_t, chLatin_r, chLatin_u, chLatin_s, chLatin_t, chColon, chDigit_1, chPeriod, chDigit_0, chNull -}; - -const XMLCh XML::TRUST_SCHEMA_ID[] = // shibboleth-trust-1.0.xsd -{ chLatin_s, chLatin_h, chLatin_i, chLatin_b, chLatin_b, chLatin_o, chLatin_l, chLatin_e, chLatin_t, chLatin_h, chDash, - chLatin_t, chLatin_r, chLatin_u, chLatin_s, chLatin_t, chDash, chDigit_1, chPeriod, chDigit_0, chPeriod, - chLatin_x, chLatin_s, chLatin_d, chNull -}; - -const XMLCh XML::SAML2ASSERT_NS[] = // urn:oasis:names:tc:SAML:2.0:assertion -{ chLatin_u, chLatin_r, chLatin_n, chColon, chLatin_o, chLatin_a, chLatin_s, chLatin_i, chLatin_s, chColon, - chLatin_n, chLatin_a, chLatin_m, chLatin_e, chLatin_s, chColon, chLatin_t, chLatin_c, chColon, - chLatin_S, chLatin_A, chLatin_M, chLatin_L, chColon, chDigit_2, chPeriod, chDigit_0, chColon, - chLatin_a, chLatin_s, chLatin_s, chLatin_e, chLatin_r, chLatin_t, chLatin_i, chLatin_o, chLatin_n, chNull -}; - -const XMLCh XML::SAML2ASSERT_SCHEMA_ID[] = // saml-schema-assertion-2.0.xsd -{ chLatin_s, chLatin_a, chLatin_m, chLatin_l, chDash, - chLatin_s, chLatin_c, chLatin_h, chLatin_e, chLatin_m, chLatin_a, chDash, - chLatin_a, chLatin_s, chLatin_s, chLatin_e, chLatin_r, chLatin_t, chLatin_i, chLatin_o, chLatin_n, chDash, - chDigit_2, chPeriod, chDigit_0, chPeriod, chLatin_x, chLatin_s, chLatin_d, chNull -}; - -const XMLCh XML::SAML2META_NS[] = // urn:oasis:names:tc:SAML:2.0:metadata -{ chLatin_u, chLatin_r, chLatin_n, chColon, chLatin_o, chLatin_a, chLatin_s, chLatin_i, chLatin_s, chColon, - chLatin_n, chLatin_a, chLatin_m, chLatin_e, chLatin_s, chColon, chLatin_t, chLatin_c, chColon, - chLatin_S, chLatin_A, chLatin_M, chLatin_L, chColon, chDigit_2, chPeriod, chDigit_0, chColon, - chLatin_m, chLatin_e, chLatin_t, chLatin_a, chLatin_d, chLatin_a, chLatin_t, chLatin_a, chNull -}; - -const XMLCh XML::SAML2META_SCHEMA_ID[] = // saml-schema-metadata-2.0.xsd -{ chLatin_s, chLatin_a, chLatin_m, chLatin_l, chDash, - chLatin_s, chLatin_c, chLatin_h, chLatin_e, chLatin_m, chLatin_a, chDash, - chLatin_m, chLatin_e, chLatin_t, chLatin_a, chLatin_d, chLatin_a, chLatin_t, chLatin_a, chDash, - chDigit_2, chPeriod, chDigit_0, chPeriod, chLatin_x, chLatin_s, chLatin_d, chNull -}; - -const XMLCh XML::XMLENC_NS[] = // http://www.w3.org/2001/04/xmlenc# -{ chLatin_h, chLatin_t, chLatin_t, chLatin_p, chColon, chForwardSlash, chForwardSlash, - chLatin_w, chLatin_w, chLatin_w, chPeriod, chLatin_w, chDigit_3, chPeriod, chLatin_o, chLatin_r, chLatin_g, chForwardSlash, - chDigit_2, chDigit_0, chDigit_0, chDigit_1, chForwardSlash, chDigit_0, chDigit_4, chForwardSlash, - chLatin_x, chLatin_m, chLatin_l, chLatin_e, chLatin_n, chLatin_c, chPound, chNull -}; - -const XMLCh XML::XMLENC_SCHEMA_ID[] = // xenc-schema.xsd -{ chLatin_x, chLatin_e, chLatin_n, chLatin_c, chDash, - chLatin_s, chLatin_c, chLatin_h, chLatin_e, chLatin_m, chLatin_a, chPeriod, chLatin_x, chLatin_s, chLatin_d, chNull -}; - -const XMLCh XML::XMLSIG_RETMETHOD_RAWX509[] = // http://www.w3.org/2000/09/xmldsig#rawX509Certificate -{ chLatin_h, chLatin_t, chLatin_t, chLatin_p, chColon, chForwardSlash, chForwardSlash, - chLatin_w, chLatin_w, chLatin_w, chPeriod, chLatin_w, chDigit_3, chPeriod, chLatin_o, chLatin_r, chLatin_g, chForwardSlash, - chDigit_2, chDigit_0, chDigit_0, chDigit_0, chForwardSlash, chDigit_0, chDigit_9, chForwardSlash, - chLatin_x, chLatin_m, chLatin_l, chLatin_d, chLatin_s, chLatin_i, chLatin_g, chPound, - chLatin_r, chLatin_a, chLatin_w, chLatin_X, chDigit_5, chDigit_0, chDigit_9, - chLatin_C, chLatin_e, chLatin_r, chLatin_t, chLatin_i, chLatin_f, chLatin_i, chLatin_c, chLatin_a, chLatin_t, chLatin_e, chNull -}; - -const XMLCh XML::XMLSIG_RETMETHOD_RAWX509CRL[] = // // http://www.w3.org/2000/09/xmldsig-more#rawX509CRL -{ chLatin_h, chLatin_t, chLatin_t, chLatin_p, chColon, chForwardSlash, chForwardSlash, - chLatin_w, chLatin_w, chLatin_w, chPeriod, chLatin_w, chDigit_3, chPeriod, chLatin_o, chLatin_r, chLatin_g, chForwardSlash, - chDigit_2, chDigit_0, chDigit_0, chDigit_0, chForwardSlash, chDigit_0, chDigit_9, chForwardSlash, - chLatin_x, chLatin_m, chLatin_l, chLatin_d, chLatin_s, chLatin_i, chLatin_g, chDash, - chLatin_m, chLatin_o, chLatin_r, chLatin_e, chPound, - chLatin_r, chLatin_a, chLatin_w, chLatin_X, chDigit_5, chDigit_0, chDigit_9, chLatin_C, chLatin_R, chLatin_L, chNull -}; - // Shibboleth vocabulary literals -const XMLCh XML::Literals::AttributeAuthority[] = -{ chLatin_A, chLatin_t, chLatin_t, chLatin_r, chLatin_i, chLatin_b, chLatin_u, chLatin_t, chLatin_e, - chLatin_A, chLatin_u, chLatin_t, chLatin_h, chLatin_o, chLatin_r, chLatin_i, chLatin_t, chLatin_y, chNull -}; - -const XMLCh XML::Literals::Contact[]= -{ chLatin_C, chLatin_o, chLatin_n, chLatin_t, chLatin_a, chLatin_c, chLatin_t, chNull }; - -const XMLCh XML::Literals::Domain[]= -{ chLatin_D, chLatin_o, chLatin_m, chLatin_a, chLatin_i, chLatin_n, chNull }; - -const XMLCh XML::Literals::Email[]= -{ chLatin_E, chLatin_m, chLatin_a, chLatin_i, chLatin_l, chNull }; - -const XMLCh XML::Literals::ErrorURL[]= -{ chLatin_E, chLatin_r, chLatin_r, chLatin_o, chLatin_r, chLatin_U, chLatin_R, chLatin_L, chNull }; - -const XMLCh XML::Literals::HandleService[]= -{ chLatin_H, chLatin_a, chLatin_n, chLatin_d, chLatin_l, chLatin_e, - chLatin_S, chLatin_e, chLatin_r, chLatin_v, chLatin_i, chLatin_c, chLatin_e, chNull }; - -const XMLCh XML::Literals::InvalidHandle[]= -{ chLatin_I, chLatin_n, chLatin_v, chLatin_a, chLatin_l, chLatin_i, chLatin_d, - chLatin_H, chLatin_a, chLatin_n, chLatin_d, chLatin_l, chLatin_e, chNull }; - -const XMLCh XML::Literals::Name[]= -{ chLatin_N, chLatin_a, chLatin_m, chLatin_e, chNull }; - -const XMLCh XML::Literals::OriginSite[]= -{ chLatin_O, chLatin_r, chLatin_i, chLatin_g, chLatin_i, chLatin_n, chLatin_S, chLatin_i, chLatin_t, chLatin_e, chNull }; - -const XMLCh XML::Literals::SiteGroup[]= -{ chLatin_S, chLatin_i, chLatin_t, chLatin_e, chLatin_G, chLatin_r, chLatin_o, chLatin_u, chLatin_p, chNull }; - const XMLCh XML::Literals::CAPath[] = { chLatin_C, chLatin_A, chLatin_P, chLatin_a, chLatin_t, chLatin_h, chNull }; @@ -184,9 +67,6 @@ const XMLCh XML::Literals::CustomResolver[]= { chLatin_C, chLatin_u, chLatin_s, chLatin_t, chLatin_o, chLatin_m, chLatin_R, chLatin_e, chLatin_s, chLatin_o, chLatin_l, chLatin_v, chLatin_e, chLatin_r, chNull }; -const XMLCh XML::Literals::Exponent[] = -{ chLatin_E, chLatin_x, chLatin_p, chLatin_o, chLatin_n, chLatin_e, chLatin_n, chLatin_t, chNull }; - const XMLCh XML::Literals::FileResolver[]= { chLatin_F, chLatin_i, chLatin_l, chLatin_e, chLatin_R, chLatin_e, chLatin_s, chLatin_o, chLatin_l, chLatin_v, chLatin_e, chLatin_r, chNull }; @@ -199,41 +79,12 @@ const XMLCh XML::Literals::Id[] = { chLatin_I, chLatin_d, chNull }; const XMLCh XML::Literals::Key[] = { chLatin_K, chLatin_e, chLatin_y, chNull }; -const XMLCh XML::Literals::KeyAuthority[] = -{ chLatin_K, chLatin_e, chLatin_y, - chLatin_A, chLatin_u, chLatin_t, chLatin_h, chLatin_o, chLatin_r, chLatin_i, chLatin_t, chLatin_y, chNull }; - -const XMLCh XML::Literals::KeyName[] = -{ chLatin_K, chLatin_e, chLatin_y, chLatin_N, chLatin_a, chLatin_m, chLatin_e, chNull }; - -const XMLCh XML::Literals::Modulus[] = -{ chLatin_M, chLatin_o, chLatin_d, chLatin_u, chLatin_l, chLatin_u, chLatin_s, chNull }; - const XMLCh XML::Literals::password[] = { chLatin_p, chLatin_a, chLatin_s, chLatin_s, chLatin_w, chLatin_o, chLatin_r, chLatin_d, chNull }; const XMLCh XML::Literals::Path[] = { chLatin_P, chLatin_a, chLatin_t, chLatin_h, chNull }; -const XMLCh XML::Literals::RetrievalMethod[] = -{ chLatin_R, chLatin_e, chLatin_t, chLatin_r, chLatin_i, chLatin_e, chLatin_v, chLatin_a, chLatin_l, - chLatin_M, chLatin_e, chLatin_t, chLatin_h, chLatin_o, chLatin_d, chNull }; - -const XMLCh XML::Literals::RSAKeyValue[] = -{ chLatin_R, chLatin_S, chLatin_A, chLatin_K, chLatin_e, chLatin_y, chLatin_V, chLatin_a, chLatin_l, chLatin_u, chLatin_e, chNull }; - -const XMLCh XML::Literals::Trust[] = -{ chLatin_T, chLatin_r, chLatin_u, chLatin_s, chLatin_t, chNull }; - -const XMLCh XML::Literals::URI[] = -{ chLatin_U, chLatin_R, chLatin_I, chNull }; - -const XMLCh XML::Literals::VerifyDepth[] = -{ chLatin_V, chLatin_e, chLatin_r, chLatin_i, chLatin_f, chLatin_y, chLatin_D, chLatin_e, chLatin_p, chLatin_t, chLatin_h, chNull }; - -const XMLCh XML::Literals::X509CRL[] = -{ chLatin_X, chDigit_5, chDigit_0, chDigit_9, chLatin_C, chLatin_R, chLatin_L, chNull }; - const XMLCh XML::Literals::Accept[]= { chLatin_A, chLatin_c, chLatin_c, chLatin_e, chLatin_p, chLatin_t, chNull }; @@ -273,6 +124,9 @@ const XMLCh XML::Literals::Factory[]= const XMLCh XML::Literals::Header[]= { chLatin_H, chLatin_e, chLatin_a, chLatin_d, chLatin_e, chLatin_r, chNull }; +const XMLCh XML::Literals::Name[]= +{ chLatin_N, chLatin_a, chLatin_m, chLatin_e, chNull }; + const XMLCh XML::Literals::Namespace[]= { chLatin_N, chLatin_a, chLatin_m, chLatin_e, chLatin_s, chLatin_p, chLatin_a, chLatin_c, chLatin_e, chNull }; @@ -298,326 +152,8 @@ const XMLCh XML::Literals::regexp[] = const XMLCh XML::Literals::xpath[] = { chLatin_x, chLatin_p, chLatin_a, chLatin_t, chLatin_h, chNull }; -const XMLCh XML::Literals::administrative[] = -{ chLatin_a, chLatin_m, chLatin_i, chLatin_n, chLatin_i, chLatin_s, chLatin_t, chLatin_r, chLatin_a, chLatin_t, chLatin_i, chLatin_v, chLatin_e, chNull }; - -const XMLCh XML::Literals::billing[] = -{ chLatin_b, chLatin_i, chLatin_l, chLatin_l, chLatin_i, chLatin_n, chLatin_g, chNull }; - -const XMLCh XML::Literals::other[] = -{ chLatin_o, chLatin_t, chLatin_h, chLatin_e, chLatin_r, chNull }; - -const XMLCh XML::Literals::support[] = -{ chLatin_s, chLatin_u, chLatin_p, chLatin_p, chLatin_o, chLatin_r, chLatin_t, chNull }; - -const XMLCh XML::Literals::technical[] = -{ chLatin_t, chLatin_e, chLatin_c, chLatin_h, chLatin_n, chLatin_i, chLatin_c, chLatin_a, chLatin_l, chNull }; - -const XMLCh XML::Literals::Exclude[] = -{ chLatin_E, chLatin_x, chLatin_c, chLatin_l, chLatin_u, chLatin_d, chLatin_e, chNull }; - -const XMLCh XML::Literals::Include[] = -{ chLatin_I, chLatin_n, chLatin_c, chLatin_l, chLatin_u, chLatin_d, chLatin_e, chNull }; - const XMLCh XML::Literals::url[] = { chLatin_u, chLatin_r, chLatin_l, chNull }; -const XMLCh XML::Literals::verify[] = -{ chLatin_v, chLatin_e, chLatin_r, chLatin_i, chLatin_f, chLatin_y, chNull }; - -const XMLCh XML::Literals::AdditionalMetadataLocation[] = -{ chLatin_A, chLatin_d, chLatin_d, chLatin_i, chLatin_t, chLatin_i, chLatin_o, chLatin_n, chLatin_a, chLatin_l, - chLatin_M, chLatin_e, chLatin_t, chLatin_a, chLatin_d, chLatin_a, chLatin_t, chLatin_a, - chLatin_L, chLatin_o, chLatin_c, chLatin_a, chLatin_t, chLatin_i, chLatin_o, chLatin_n, chNull -}; - -const XMLCh XML::Literals::AffiliateMember[] = -{ chLatin_A, chLatin_f, chLatin_f, chLatin_i, chLatin_l, chLatin_i, chLatin_a, chLatin_t, chLatin_e, - chLatin_M, chLatin_e, chLatin_m, chLatin_b, chLatin_e, chLatin_r, chNull -}; - -const XMLCh XML::Literals::AffiliationDescriptor[] = -{ chLatin_A, chLatin_f, chLatin_f, chLatin_i, chLatin_l, chLatin_i, chLatin_a, chLatin_t, chLatin_i, chLatin_o, chLatin_n, - chLatin_D, chLatin_e, chLatin_s, chLatin_c, chLatin_r, chLatin_i, chLatin_p, chLatin_t, chLatin_o, chLatin_r, chNull -}; - -const XMLCh XML::Literals::affiliationOwnerID[] = -{ chLatin_a, chLatin_f, chLatin_f, chLatin_i, chLatin_l, chLatin_i, chLatin_a, chLatin_t, chLatin_i, chLatin_o, chLatin_n, - chLatin_O, chLatin_w, chLatin_n, chLatin_e, chLatin_r, chLatin_I, chLatin_D, chNull -}; - -const XMLCh XML::Literals::Algorithm[] = -{ chLatin_A, chLatin_l, chLatin_g, chLatin_o, chLatin_r, chLatin_i, chLatin_t, chLatin_h, chLatin_m, chNull }; - -const XMLCh XML::Literals::ArtifactResolutionService[] = -{ chLatin_A, chLatin_r, chLatin_t, chLatin_i, chLatin_f, chLatin_a, chLatin_c, chLatin_t, - chLatin_R, chLatin_e, chLatin_s, chLatin_o, chLatin_l, chLatin_u, chLatin_t, chLatin_i, chLatin_o, chLatin_n, - chLatin_S, chLatin_e, chLatin_r, chLatin_v, chLatin_i, chLatin_c, chLatin_e, chNull -}; - -const XMLCh XML::Literals::AssertionConsumerService[] = -{ chLatin_A, chLatin_s, chLatin_s, chLatin_e, chLatin_r, chLatin_t, chLatin_i, chLatin_o, chLatin_n, - chLatin_C, chLatin_o, chLatin_n, chLatin_s, chLatin_u, chLatin_m, chLatin_e, chLatin_r, - chLatin_S, chLatin_e, chLatin_r, chLatin_v, chLatin_i, chLatin_c, chLatin_e, chNull -}; - -const XMLCh XML::Literals::AssertionIDRequestService[] = -{ chLatin_A, chLatin_s, chLatin_s, chLatin_e, chLatin_r, chLatin_t, chLatin_i, chLatin_o, chLatin_n, chLatin_I, chLatin_D, - chLatin_R, chLatin_e, chLatin_q, chLatin_u, chLatin_e, chLatin_s, chLatin_t, - chLatin_S, chLatin_e, chLatin_r, chLatin_v, chLatin_i, chLatin_c, chLatin_e, chNull -}; - -const XMLCh XML::Literals::AttributeAuthorityDescriptor[] = -{ chLatin_A, chLatin_t, chLatin_t, chLatin_r, chLatin_i, chLatin_b, chLatin_u, chLatin_t, chLatin_e, - chLatin_A, chLatin_u, chLatin_t, chLatin_h, chLatin_o, chLatin_r, chLatin_i, chLatin_t, chLatin_y, - chLatin_D, chLatin_e, chLatin_s, chLatin_c, chLatin_r, chLatin_i, chLatin_p, chLatin_t, chLatin_o, chLatin_r, chNull -}; - -const XMLCh XML::Literals::AttributeConsumingService[] = -{ chLatin_A, chLatin_t, chLatin_t, chLatin_r, chLatin_i, chLatin_b, chLatin_u, chLatin_t, chLatin_e, - chLatin_C, chLatin_o, chLatin_n, chLatin_s, chLatin_u, chLatin_m, chLatin_i, chLatin_n, chLatin_g, - chLatin_S, chLatin_e, chLatin_r, chLatin_v, chLatin_i, chLatin_c, chLatin_e, chNull -}; - -const XMLCh XML::Literals::AttributeProfile[] = -{ chLatin_A, chLatin_t, chLatin_t, chLatin_r, chLatin_i, chLatin_b, chLatin_u, chLatin_t, chLatin_e, - chLatin_P, chLatin_r, chLatin_o, chLatin_f, chLatin_i, chLatin_l, chLatin_e, chNull -}; - -const XMLCh XML::Literals::AttributeService[] = -{ chLatin_A, chLatin_t, chLatin_t, chLatin_r, chLatin_i, chLatin_b, chLatin_u, chLatin_t, chLatin_e, - chLatin_S, chLatin_e, chLatin_r, chLatin_v, chLatin_i, chLatin_c, chLatin_e, chNull -}; - -const XMLCh XML::Literals::AuthnAuthorityDescriptor[] = -{ chLatin_A, chLatin_u, chLatin_t, chLatin_h, chLatin_n, - chLatin_A, chLatin_u, chLatin_t, chLatin_h, chLatin_o, chLatin_r, chLatin_i, chLatin_t, chLatin_y, - chLatin_D, chLatin_e, chLatin_s, chLatin_c, chLatin_r, chLatin_i, chLatin_p, chLatin_t, chLatin_o, chLatin_r, chNull -}; - -const XMLCh XML::Literals::AuthnQueryService[] = -{ chLatin_A, chLatin_u, chLatin_t, chLatin_h, chLatin_n, chLatin_Q, chLatin_u, chLatin_e, chLatin_r, chLatin_y, - chLatin_S, chLatin_e, chLatin_r, chLatin_v, chLatin_i, chLatin_c, chLatin_e, chNull -}; - -const XMLCh XML::Literals::AuthnRequestsSigned[] = -{ chLatin_A, chLatin_u, chLatin_t, chLatin_h, chLatin_n, - chLatin_R, chLatin_e, chLatin_q, chLatin_u, chLatin_e, chLatin_s, chLatin_t, chLatin_s, - chLatin_S, chLatin_i, chLatin_g, chLatin_n, chLatin_e, chLatin_d, chNull -}; - -const XMLCh XML::Literals::AuthzService[] = -{ chLatin_A, chLatin_u, chLatin_t, chLatin_h, chLatin_z, - chLatin_S, chLatin_e, chLatin_r, chLatin_v, chLatin_i, chLatin_c, chLatin_e, chNull -}; - -const XMLCh XML::Literals::cacheDuration[] = -{ chLatin_c, chLatin_a, chLatin_c, chLatin_h, chLatin_e, - chLatin_D, chLatin_u, chLatin_r, chLatin_a, chLatin_t, chLatin_i, chLatin_o, chLatin_n, chNull -}; - -const XMLCh XML::Literals::Company[] = -{ chLatin_C, chLatin_o, chLatin_m, chLatin_p, chLatin_a, chLatin_n, chLatin_y, chNull }; - -const XMLCh XML::Literals::ContactPerson[] = -{ chLatin_C, chLatin_o, chLatin_n, chLatin_t, chLatin_a, chLatin_c, chLatin_t, - chLatin_P, chLatin_e, chLatin_r, chLatin_s, chLatin_o, chLatin_n, chNull -}; - -const XMLCh XML::Literals::contactType[] = -{ chLatin_c, chLatin_o, chLatin_n, chLatin_t, chLatin_a, chLatin_c, chLatin_t, chLatin_T, chLatin_y, chLatin_p, chLatin_e, chNull }; - -const XMLCh XML::Literals::DigestMethod[] = -{ chLatin_D, chLatin_i, chLatin_g, chLatin_e, chLatin_s, chLatin_t, - chLatin_M, chLatin_e, chLatin_t, chLatin_h, chLatin_o, chLatin_d, chNull -}; - -const XMLCh XML::Literals::EmailAddress[] = -{ chLatin_E, chLatin_m, chLatin_a, chLatin_i, chLatin_l, - chLatin_A, chLatin_d, chLatin_d, chLatin_r, chLatin_e, chLatin_s, chLatin_s, chNull -}; - -const XMLCh XML::Literals::encryption[] = -{ chLatin_e, chLatin_n, chLatin_c, chLatin_r, chLatin_y, chLatin_p, chLatin_t, chLatin_i, chLatin_o, chLatin_n, chNull }; - -const XMLCh XML::Literals::EncryptionMethod[] = -{ chLatin_E, chLatin_n, chLatin_c, chLatin_r, chLatin_y, chLatin_p, chLatin_t, chLatin_i, chLatin_o, chLatin_n, - chLatin_M, chLatin_e, chLatin_t, chLatin_h, chLatin_o, chLatin_d, chNull -}; - -const XMLCh XML::Literals::EntitiesDescriptor[] = -{ chLatin_E, chLatin_n, chLatin_t, chLatin_i, chLatin_t, chLatin_i, chLatin_e, chLatin_s, - chLatin_D, chLatin_e, chLatin_s, chLatin_c, chLatin_r, chLatin_i, chLatin_p, chLatin_t, chLatin_o, chLatin_r, chNull -}; - -const XMLCh XML::Literals::EntityDescriptor[] = -{ chLatin_E, chLatin_n, chLatin_t, chLatin_i, chLatin_t, chLatin_y, - chLatin_D, chLatin_e, chLatin_s, chLatin_c, chLatin_r, chLatin_i, chLatin_p, chLatin_t, chLatin_o, chLatin_r, chNull -}; - -const XMLCh XML::Literals::entityID[] = -{ chLatin_e, chLatin_n, chLatin_t, chLatin_i, chLatin_t, chLatin_y, chLatin_I, chLatin_D, chNull}; - -const XMLCh XML::Literals::errorURL[] = -{ chLatin_e, chLatin_r, chLatin_r, chLatin_o, chLatin_r, chLatin_U, chLatin_R, chLatin_L, chNull}; - -const XMLCh XML::Literals::Extensions[] = -{ chLatin_E, chLatin_x, chLatin_t, chLatin_e, chLatin_n, chLatin_s, chLatin_i, chLatin_o, chLatin_n, chLatin_s, chNull }; - -const XMLCh XML::Literals::GivenName[] = -{ chLatin_G, chLatin_i, chLatin_v, chLatin_e, chLatin_n, chLatin_N, chLatin_a, chLatin_m, chLatin_e, chNull }; - -const XMLCh XML::Literals::IDPSSODescriptor[] = -{ chLatin_I, chLatin_D, chLatin_P, chLatin_S, chLatin_S, chLatin_O, - chLatin_D, chLatin_e, chLatin_s, chLatin_c, chLatin_r, chLatin_i, chLatin_p, chLatin_t, chLatin_o, chLatin_r, chNull -}; - -const XMLCh XML::Literals::index[] = -{ chLatin_i, chLatin_n, chLatin_d, chLatin_e, chLatin_x, chNull }; - -const XMLCh XML::Literals::isDefault[] = -{ chLatin_i, chLatin_s, chLatin_D, chLatin_e, chLatin_f, chLatin_a, chLatin_u, chLatin_l, chLatin_t, chNull }; - -const XMLCh XML::Literals::isRequired[] = -{ chLatin_i, chLatin_s, chLatin_R, chLatin_e, chLatin_q, chLatin_u, chLatin_i, chLatin_r, chLatin_e, chLatin_d, chNull }; - -const XMLCh XML::Literals::KeyDescriptor[] = -{ chLatin_K, chLatin_e, chLatin_y, - chLatin_D, chLatin_e, chLatin_s, chLatin_c, chLatin_r, chLatin_i, chLatin_p, chLatin_t, chLatin_o, chLatin_r, chNull -}; - -const XMLCh XML::Literals::KeySize[] = -{ chLatin_K, chLatin_e, chLatin_y, chLatin_S, chLatin_i, chLatin_z, chLatin_e, chNull }; - -const XMLCh XML::Literals::ManageNameIDService[] = -{ chLatin_M, chLatin_a, chLatin_n, chLatin_a, chLatin_g, chLatin_e, - chLatin_N, chLatin_a, chLatin_m, chLatin_e, chLatin_I, chLatin_D, - chLatin_S, chLatin_e, chLatin_r, chLatin_v, chLatin_i, chLatin_c, chLatin_e, chNull -}; - -const XMLCh XML::Literals::_namespace[]= -{ chLatin_n, chLatin_a, chLatin_m, chLatin_e, chLatin_s, chLatin_p, chLatin_a, chLatin_c, chLatin_e, chNull }; - -const XMLCh XML::Literals::NameFormat[] = -{ chLatin_N, chLatin_a, chLatin_m, chLatin_e, chLatin_F, chLatin_o, chLatin_r, chLatin_m, chLatin_a, chLatin_t, chNull }; - -const XMLCh XML::Literals::NameIDFormat[] = -{ chLatin_N, chLatin_a, chLatin_m, chLatin_e, chLatin_I, chLatin_D, - chLatin_F, chLatin_o, chLatin_r, chLatin_m, chLatin_a, chLatin_t, chNull -}; - -const XMLCh XML::Literals::NameIDMappingService[] = -{ chLatin_N, chLatin_a, chLatin_m, chLatin_e, chLatin_I, chLatin_D, - chLatin_M, chLatin_a, chLatin_p, chLatin_p, chLatin_i, chLatin_n, chLatin_g, - chLatin_S, chLatin_e, chLatin_r, chLatin_v, chLatin_i, chLatin_c, chLatin_e, chNull -}; - -const XMLCh XML::Literals::OAEParams[] = -{ chLatin_O, chLatin_A, chLatin_E, chLatin_P, chLatin_a, chLatin_r, chLatin_a, chLatin_m, chLatin_s, chNull }; - -const XMLCh XML::Literals::Organization[] = -{ chLatin_O, chLatin_r, chLatin_g, chLatin_a, chLatin_n, chLatin_i, chLatin_z, chLatin_a, chLatin_t, chLatin_i, chLatin_o, chLatin_n, chNull }; - -const XMLCh XML::Literals::OrganizationName[] = -{ chLatin_O, chLatin_r, chLatin_g, chLatin_a, chLatin_n, chLatin_i, chLatin_z, chLatin_a, chLatin_t, chLatin_i, chLatin_o, chLatin_n, - chLatin_N, chLatin_a, chLatin_m, chLatin_e, chNull -}; - -const XMLCh XML::Literals::OrganizationDisplayName[] = -{ chLatin_O, chLatin_r, chLatin_g, chLatin_a, chLatin_n, chLatin_i, chLatin_z, chLatin_a, chLatin_t, chLatin_i, chLatin_o, chLatin_n, - chLatin_D, chLatin_i, chLatin_s, chLatin_p, chLatin_l, chLatin_a, chLatin_y, - chLatin_N, chLatin_a, chLatin_m, chLatin_e, chNull -}; - -const XMLCh XML::Literals::OrganizationURL[] = -{ chLatin_O, chLatin_r, chLatin_g, chLatin_a, chLatin_n, chLatin_i, chLatin_z, chLatin_a, chLatin_t, chLatin_i, chLatin_o, chLatin_n, - chLatin_U, chLatin_R, chLatin_L, chNull -}; - -const XMLCh XML::Literals::PDPDescriptor[] = -{ chLatin_P, chLatin_D, chLatin_P, - chLatin_D, chLatin_e, chLatin_s, chLatin_c, chLatin_r, chLatin_i, chLatin_p, chLatin_t, chLatin_o, chLatin_r, chNull -}; - -const XMLCh XML::Literals::protocolSupportEnumeration[] = -{ chLatin_p, chLatin_r, chLatin_o, chLatin_t, chLatin_o, chLatin_c, chLatin_o, chLatin_l, - chLatin_S, chLatin_u, chLatin_p, chLatin_p, chLatin_o, chLatin_r, chLatin_t, - chLatin_E, chLatin_n, chLatin_u, chLatin_m, chLatin_e, chLatin_r, chLatin_a, chLatin_t, chLatin_i, chLatin_o, chLatin_n, chNull -}; - -const XMLCh XML::Literals::RequestedAttribute[] = -{ chLatin_R, chLatin_e, chLatin_q, chLatin_u, chLatin_e, chLatin_s, chLatin_t, chLatin_e, chLatin_d, - chLatin_A, chLatin_t, chLatin_t, chLatin_r, chLatin_i, chLatin_b, chLatin_u, chLatin_t, chLatin_e, chNull -}; - -const XMLCh XML::Literals::ResponseLocation[] = -{ chLatin_R, chLatin_e, chLatin_s, chLatin_p, chLatin_o, chLatin_n, chLatin_s, chLatin_e, - chLatin_L, chLatin_o, chLatin_c, chLatin_a, chLatin_t, chLatin_i, chLatin_o, chLatin_n, chNull -}; - -const XMLCh XML::Literals::RoleDescriptor[] = -{ chLatin_R, chLatin_o, chLatin_l, chLatin_e, - chLatin_D, chLatin_e, chLatin_s, chLatin_c, chLatin_r, chLatin_i, chLatin_p, chLatin_t, chLatin_o, chLatin_r, - chNull -}; - -const XMLCh XML::Literals::ServiceDescription[] = -{ chLatin_S, chLatin_e, chLatin_r, chLatin_v, chLatin_i, chLatin_c, chLatin_e, - chLatin_D, chLatin_e, chLatin_s, chLatin_c, chLatin_r, chLatin_i, chLatin_p, chLatin_t, chLatin_i, chLatin_o, chLatin_n, chNull -}; - -const XMLCh XML::Literals::ServiceName[] = -{ chLatin_S, chLatin_e, chLatin_r, chLatin_v, chLatin_i, chLatin_c, chLatin_e, - chLatin_N, chLatin_a, chLatin_m, chLatin_e, chNull -}; - -const XMLCh XML::Literals::signing[] = -{ chLatin_s, chLatin_i, chLatin_g, chLatin_n, chLatin_i, chLatin_n, chLatin_g, chNull }; - -const XMLCh XML::Literals::SingleLogoutService[] = -{ chLatin_S, chLatin_i, chLatin_n, chLatin_g, chLatin_l, chLatin_e, - chLatin_L, chLatin_o, chLatin_g, chLatin_o, chLatin_u, chLatin_t, - chLatin_S, chLatin_e, chLatin_r, chLatin_v, chLatin_i, chLatin_c, chLatin_e, chNull -}; - -const XMLCh XML::Literals::SingleSignOnService[] = -{ chLatin_S, chLatin_i, chLatin_n, chLatin_g, chLatin_l, chLatin_e, - chLatin_S, chLatin_i, chLatin_g, chLatin_n, chLatin_O, chLatin_n, - chLatin_S, chLatin_e, chLatin_r, chLatin_v, chLatin_i, chLatin_c, chLatin_e, chNull -}; - -const XMLCh XML::Literals::SourceID[] = -{ chLatin_S, chLatin_o, chLatin_u, chLatin_r, chLatin_c, chLatin_e, chLatin_I, chLatin_D, chNull }; - -const XMLCh XML::Literals::SPSSODescriptor[] = -{ chLatin_S, chLatin_P, chLatin_S, chLatin_S, chLatin_O, - chLatin_D, chLatin_e, chLatin_s, chLatin_c, chLatin_r, chLatin_i, chLatin_p, chLatin_t, chLatin_o, chLatin_r, chNull -}; - -const XMLCh XML::Literals::SurName[] = -{ chLatin_S, chLatin_u, chLatin_r, chLatin_N, chLatin_a, chLatin_m, chLatin_e, chNull }; - -const XMLCh XML::Literals::TelephoneNumber[] = -{ chLatin_T, chLatin_e, chLatin_l, chLatin_e, chLatin_p, chLatin_h, chLatin_o, chLatin_n, chLatin_e, - chLatin_N, chLatin_u, chLatin_m, chLatin_b, chLatin_e, chLatin_r, chNull -}; - -const XMLCh XML::Literals::use[] = { chLatin_u, chLatin_s, chLatin_e, chNull }; - -const XMLCh XML::Literals::validUntil[] = -{ chLatin_v, chLatin_a, chLatin_l, chLatin_i, chLatin_d, chLatin_U, chLatin_n, chLatin_t, chLatin_i, chLatin_l, chNull }; - -const XMLCh XML::Literals::WantAuthnRequestsSigned[] = -{ chLatin_W, chLatin_a, chLatin_n, chLatin_t, chLatin_A, chLatin_u, chLatin_t, chLatin_h, chLatin_n, - chLatin_R, chLatin_e, chLatin_q, chLatin_u, chLatin_e, chLatin_s, chLatin_t, chLatin_s, - chLatin_S, chLatin_i, chLatin_g, chLatin_n, chLatin_e, chLatin_d, chNull -}; - -const XMLCh XML::Literals::WantAssertionsSigned[] = -{ chLatin_W, chLatin_a, chLatin_n, chLatin_t, - chLatin_A, chLatin_s, chLatin_s, chLatin_e, chLatin_r, chLatin_t, chLatin_i, chLatin_o, chLatin_n, chLatin_s, - chLatin_S, chLatin_i, chLatin_g, chLatin_n, chLatin_e, chLatin_d, chNull -}; - const XMLCh XML::Literals::AccessControl[] = { chLatin_A, chLatin_c, chLatin_c, chLatin_e, chLatin_s, chLatin_s, chLatin_C, chLatin_o, chLatin_n, chLatin_t, chLatin_r, chLatin_o, chLatin_l, chNull diff --git a/xmlproviders/XMLAAP.cpp b/xmlproviders/XMLAAP.cpp index 5d29257..1e6fdd4 100644 --- a/xmlproviders/XMLAAP.cpp +++ b/xmlproviders/XMLAAP.cpp @@ -25,10 +25,15 @@ #include "internal.h" #include #include +#include #include +#include +using namespace shibsp; using namespace shibboleth; using namespace saml; +using namespace opensaml::saml2md; +using namespace xmltooling; using namespace log4cpp; using namespace std; @@ -56,14 +61,14 @@ namespace { const char* getHeader() const { return m_header.get(); } bool getCaseSensitive() const { return m_caseSensitive; } bool getScoped() const { return m_scoped; } - void apply(SAMLAttribute& attribute, const IEntityDescriptor* source=NULL) const; + void apply(SAMLAttribute& attribute, const RoleDescriptor* role=NULL) const; enum value_type { literal, regexp, xpath }; private: const XMLCh* m_name; const XMLCh* m_namespace; - auto_ptr_char m_alias; - auto_ptr_char m_header; + xmltooling::auto_ptr_char m_alias; + xmltooling::auto_ptr_char m_header; bool m_caseSensitive; bool m_scoped; @@ -80,14 +85,14 @@ namespace { value_type toValueType(const DOMElement* e); bool scopeCheck( const DOMElement* e, - const IExtendedEntityDescriptor* source, + const RoleDescriptor* role, const vector& ruleStack ) const; - bool accept(const DOMElement* e, const IExtendedEntityDescriptor* source=NULL) const; + bool accept(const DOMElement* e, const RoleDescriptor* role=NULL) const; SiteRule m_anySiteRule; #ifdef HAVE_GOOD_STL - typedef map sitemap_t; + typedef map sitemap_t; #else typedef map sitemap_t; #endif @@ -98,7 +103,7 @@ namespace { vector m_attrs; map m_aliasMap; #ifdef HAVE_GOOD_STL - typedef map attrmap_t; + typedef map attrmap_t; #else typedef map attrmap_t; #endif @@ -143,7 +148,7 @@ ReloadableXMLFileImpl* XMLAAP::newImplementation(const char* pathname, bool firs void XMLAAPImpl::init() { #ifdef _DEBUG - saml::NDC ndc("init"); + xmltooling::NDC ndc("init"); #endif Category& log=Category::getInstance(XMLPROVIDERS_LOGCAT".AAP"); @@ -168,7 +173,7 @@ void XMLAAPImpl::init() { AttributeRule* rule=new AttributeRule(static_cast(nlist->item(i))); #ifdef HAVE_GOOD_STL - xstring key=rule->getName(); + xmltooling::xstring key=rule->getName(); key=key + chBang + chBang + (rule->getNamespace() ? rule->getNamespace() : shibspconstants::SHIB1_ATTRIBUTE_NAMESPACE_URI); #else auto_ptr_char aname(rule->getName()); @@ -217,7 +222,7 @@ void XMLAAPImpl::init() XMLAAPImpl::~XMLAAPImpl() { #ifdef HAVE_GOOD_STL - for_each(m_attrMap.begin(),m_attrMap.end(),xmltooling::cleanup_pair()); + for_each(m_attrMap.begin(),m_attrMap.end(),xmltooling::cleanup_pair()); #else for_each(m_attrMap.begin(),m_attrMap.end(),xmltooling::cleanup_pair()); #endif @@ -357,7 +362,7 @@ XMLAAPImpl::AttributeRule::value_type XMLAAPImpl::AttributeRule::toValueType(con const IAttributeRule* XMLAAP::lookup(const XMLCh* attrName, const XMLCh* attrNamespace) const { #ifdef HAVE_GOOD_STL - xstring key=attrName; + xmltooling::xstring key=attrName; key=key + chBang + chBang + (attrNamespace ? attrNamespace : shibspconstants::SHIB1_ATTRIBUTE_NAMESPACE_URI); #else auto_ptr_char aname(attrName); @@ -391,15 +396,13 @@ Iterator XMLAAP::getAttributeRules() const namespace { bool match(const XMLCh* exp, const XMLCh* test) { - try - { + try { RegularExpression re(exp); if (re.matches(test)) return true; } - catch (XMLException& ex) - { - auto_ptr tmp(XMLString::transcode(ex.getMessage())); + catch (XMLException& ex) { + xmltooling::auto_ptr_char tmp(ex.getMessage()); Category::getInstance(XMLPROVIDERS_LOGCAT".XMLAAPImpl").errorStream() << "caught exception while parsing regular expression: " << tmp.get() << CategoryStream::ENDLINE; } @@ -409,12 +412,12 @@ namespace { bool XMLAAPImpl::AttributeRule::scopeCheck( const DOMElement* e, - const IExtendedEntityDescriptor* source, + const RoleDescriptor* role, const vector& ruleStack ) const { #ifdef _DEBUG - saml::NDC ndc("scopeCheck"); + xmltooling::NDC ndc("scopeCheck"); #endif Category& log=Category::getInstance(XMLPROVIDERS_LOGCAT".AAP"); @@ -423,7 +426,7 @@ bool XMLAAPImpl::AttributeRule::scopeCheck( if (!scope || !*scope) { // Are we allowed to be unscoped? if (m_scoped && log.isWarnEnabled()) { - auto_ptr_char temp(m_name); + xmltooling::auto_ptr_char temp(m_name); log.warn("attribute (%s) is scoped, no scope supplied, rejecting it",temp.get()); } return !m_scoped; @@ -438,8 +441,8 @@ bool XMLAAPImpl::AttributeRule::scopeCheck( if ((i->first==literal && !XMLString::compareString(i->second,scope)) || (i->first==regexp && match(i->second,scope))) { if (log.isWarnEnabled()) { - auto_ptr_char temp(m_name); - auto_ptr_char temp2(scope); + xmltooling::auto_ptr_char temp(m_name); + xmltooling::auto_ptr_char temp2(scope); log.warn("attribute (%s) scope (%s) denied by site rule, rejecting it",temp.get(),temp2.get()); } return false; @@ -461,11 +464,13 @@ bool XMLAAPImpl::AttributeRule::scopeCheck( } // If we still can't decide, defer to metadata. - if (source) { - Iterator > domains=source->getScopes(); - while (domains.hasNext()) { - const pair& p=domains.next(); - if ((p.second && match(p.first,scope)) || !XMLString::compareString(p.first,scope)) { + if (role && role->getExtensions()) { + const vector& exts=const_cast(role->getExtensions())->getUnknownXMLObjects(); + for (vector::const_iterator it=exts.begin(); it!=exts.end(); ++it) { + const Scope* s=dynamic_cast(*it); + if (!s) + continue; + if ((s->Regexp() && match(s->getValue(),scope)) || XMLString::equals(s->getValue(),scope)) { log.debug("scope match via site metadata"); return true; } @@ -473,23 +478,25 @@ bool XMLAAPImpl::AttributeRule::scopeCheck( } if (log.isWarnEnabled()) { - auto_ptr_char temp(m_name); - auto_ptr_char temp2(scope); + xmltooling::auto_ptr_char temp(m_name); + xmltooling::auto_ptr_char temp2(scope); log.warn("attribute (%s) scope (%s) not accepted",temp.get(),temp2.get()); } return false; } -bool XMLAAPImpl::AttributeRule::accept(const DOMElement* e, const IExtendedEntityDescriptor* source) const +bool XMLAAPImpl::AttributeRule::accept(const DOMElement* e, const RoleDescriptor* role) const { #ifdef _DEBUG - saml::NDC ndc("accept"); + xmltooling::NDC ndc("accept"); #endif Category& log=Category::getInstance(XMLPROVIDERS_LOGCAT".AAP"); - + + const EntityDescriptor* source = role ? dynamic_cast(role->getParent()) : NULL; + if (log.isDebugEnabled()) { - auto_ptr_char temp(m_name); - auto_ptr_char temp2(source ? source->getId() : NULL); + xmltooling::auto_ptr_char temp(m_name); + xmltooling::auto_ptr_char temp2(source ? source->getEntityID() : NULL); log.debug("evaluating value for attribute (%s) from site (%s)",temp.get(),temp2.get() ? temp2.get() : ""); } @@ -500,9 +507,9 @@ bool XMLAAPImpl::AttributeRule::accept(const DOMElement* e, const IExtendedEntit if (source) { // Primary match is against entityID. #ifdef HAVE_GOOD_STL - const XMLCh* os=source->getId(); + const XMLCh* os=source->getEntityID(); #else - auto_ptr_char pos(source->getId()); + auto_ptr_char pos(source->getEntityID()); const char* os=pos.get(); #endif sitemap_t::const_iterator srule=m_siteMap.find(os); @@ -510,7 +517,7 @@ bool XMLAAPImpl::AttributeRule::accept(const DOMElement* e, const IExtendedEntit ruleStack.push_back(&srule->second); // Secondary matches are on groups. - const IEntitiesDescriptor* group=source->getEntitiesDescriptor(); + const EntitiesDescriptor* group=dynamic_cast(source->getParent()); while (group) { if (group->getName()) { #ifdef HAVE_GOOD_STL @@ -523,7 +530,7 @@ bool XMLAAPImpl::AttributeRule::accept(const DOMElement* e, const IExtendedEntit if (srule!=m_siteMap.end()) ruleStack.push_back(&srule->second); } - group = group->getEntitiesDescriptor(); + group=dynamic_cast(group->getParent()); } } // Tertiary match is the AnySite rule. @@ -539,7 +546,7 @@ bool XMLAAPImpl::AttributeRule::accept(const DOMElement* e, const IExtendedEntit // Check for shortcut AnyValue blanket rule. if ((*rule)->anyValue) { log.debug("matching site rule, any value match"); - return scopeCheck(e,source,ruleStack); + return scopeCheck(e,role,ruleStack); } // Now run any denials. @@ -550,7 +557,7 @@ bool XMLAAPImpl::AttributeRule::accept(const DOMElement* e, const IExtendedEntit if ((m_caseSensitive && !XMLString::compareString(i->second,n->getNodeValue())) || (!m_caseSensitive && !XMLString::compareIString(i->second,n->getNodeValue()))) { if (log.isWarnEnabled()) { - auto_ptr_char temp(m_name); + xmltooling::auto_ptr_char temp(m_name); log.warn("attribute (%s) value explicitly denied by site rule, rejecting it",temp.get()); } return false; @@ -560,7 +567,7 @@ bool XMLAAPImpl::AttributeRule::accept(const DOMElement* e, const IExtendedEntit case regexp: if (match(i->second,n->getNodeValue())) { if (log.isWarnEnabled()) { - auto_ptr_char temp(m_name); + xmltooling::auto_ptr_char temp(m_name); log.warn("attribute (%s) value explicitly denied by site rule, rejecting it",temp.get()); } return false; @@ -580,14 +587,14 @@ bool XMLAAPImpl::AttributeRule::accept(const DOMElement* e, const IExtendedEntit if ((m_caseSensitive && !XMLString::compareString(i->second,n->getNodeValue())) || (!m_caseSensitive && !XMLString::compareIString(i->second,n->getNodeValue()))) { log.debug("site rule, value match"); - return scopeCheck(e,source,ruleStack); + return scopeCheck(e,role,ruleStack); } break; case regexp: if (match(i->second,n->getNodeValue())) { log.debug("site rule, value match"); - return scopeCheck(e,source,ruleStack); + return scopeCheck(e,role,ruleStack); } break; @@ -599,21 +606,21 @@ bool XMLAAPImpl::AttributeRule::accept(const DOMElement* e, const IExtendedEntit } if (log.isWarnEnabled()) { - auto_ptr_char temp(m_name); - auto_ptr_char temp2(n->getNodeValue()); + xmltooling::auto_ptr_char temp(m_name); + xmltooling::auto_ptr_char temp2(n->getNodeValue()); log.warn("%sattribute (%s) value (%s) could not be validated by policy, rejecting it", (bSimple ? "" : "complex "),temp.get(),temp2.get()); } return false; } -void XMLAAPImpl::AttributeRule::apply(SAMLAttribute& attribute, const IEntityDescriptor* source) const +void XMLAAPImpl::AttributeRule::apply(SAMLAttribute& attribute, const RoleDescriptor* role) const { // Check each value. DOMNodeList* vals=attribute.getValueElements(); int i2=0; for (XMLSize_t i=0; vals && i < vals->getLength(); i++) { - if (!accept(static_cast(vals->item(i)),source ? dynamic_cast(source) : NULL)) + if (!accept(static_cast(vals->item(i)),role)) attribute.removeValue(i2); else i2++; diff --git a/xmlproviders/XMLCredentials.cpp b/xmlproviders/XMLCredentials.cpp index 7b5ac5f..5c3facb 100644 --- a/xmlproviders/XMLCredentials.cpp +++ b/xmlproviders/XMLCredentials.cpp @@ -29,9 +29,12 @@ #include #include +#include +using namespace shibsp; using namespace shibboleth; using namespace saml; +using namespace xmltooling; using namespace log4cpp; using namespace std; @@ -91,7 +94,7 @@ void XMLCredentialsImpl::init() try { if (!saml::XML::isElementNamed(m_root,::XML::CREDS_NS,SHIB_L(Credentials))) { log.error("Construction requires a valid creds file: (creds:Credentials as root element)"); - throw CredentialException("Construction requires a valid creds file: (creds:Credentials as root element)"); + throw ConfigurationException("Construction requires a valid creds file: (creds:Credentials as root element)"); } DOMElement* child=saml::XML::getFirstChildElement(m_root); @@ -102,7 +105,7 @@ void XMLCredentialsImpl::init() if (saml::XML::isElementNamed(child,::XML::CREDS_NS,SHIB_L(FileResolver))) cr_type="edu.internet2.middleware.shibboleth.common.Credentials.FileCredentialResolver"; else if (saml::XML::isElementNamed(child,::XML::CREDS_NS,SHIB_L(CustomResolver))) { - auto_ptr_char c(child->getAttributeNS(NULL,SHIB_L(Class))); + xmltooling::auto_ptr_char c(child->getAttributeNS(NULL,SHIB_L(Class))); cr_type=c.get(); } @@ -114,23 +117,23 @@ void XMLCredentialsImpl::init() m_resolverMap[id.get()]=cr; else { log.error("plugin was not a credential resolver"); - throw UnsupportedExtensionException("plugin was not a credential resolver"); + throw UnknownExtensionException("plugin was not a credential resolver"); } } - catch (SAMLException& e) { + catch (exception& e) { log.error("failed to instantiate credential resolver (%s): %s", id.get(), e.what()); throw; } } else { log.error("unknown or unimplemented type of credential resolver (%s)", id.get()); - throw CredentialException("Unknown or unimplemented type of credential resolver"); + throw UnknownExtensionException("Unknown or unimplemented type of credential resolver"); } child=saml::XML::getNextSiblingElement(child); } } - catch (SAMLException& e) { + catch (exception& e) { log.errorStream() << "Error while parsing creds configuration: " << e.what() << CategoryStream::ENDLINE; this->~XMLCredentialsImpl(); throw; diff --git a/xmlproviders/XMLMetadata.cpp b/xmlproviders/XMLMetadata.cpp deleted file mode 100644 index 093cc52..0000000 --- a/xmlproviders/XMLMetadata.cpp +++ /dev/null @@ -1,1445 +0,0 @@ -/* - * Copyright 2001-2005 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. - */ - - -/* XMLMetadata.cpp - a metadata implementation that uses an XML-based registry - - Scott Cantor - 9/27/02 - - $History:$ -*/ - -#include "internal.h" - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -using namespace shibboleth; -using namespace saml; -using namespace log4cpp; -using namespace std; - -namespace { - - class XMLMetadata; - class XMLMetadataImpl : public ReloadableXMLFileImpl - { - public: - class ContactPerson : public IContactPerson - { - public: - ContactPerson(const DOMElement* e); - ~ContactPerson() {} - - ContactType getType() const { return m_type; } - const char* getCompany() const { return m_company.get(); } - const char* getGivenName() const { return m_givenName.get(); } - const char* getSurName() const { return m_surName.get(); } - Iterator getEmailAddresses() const { return m_emails; } - Iterator getTelephoneNumbers() const { return m_phones; } - const DOMElement* getElement() const { return m_root; } - - private: - const DOMElement* m_root; - ContactType m_type; - auto_ptr m_givenName,m_surName,m_company; - vector m_emails,m_phones; - }; - - class Organization : public IOrganization - { - public: - Organization(const DOMElement* e); - ~Organization() {} - - const char* getName(const char* lang="en") const { return forLang(m_names,lang); } - const char* getDisplayName(const char* lang="en") const { return forLang(m_displays,lang); } - const char* getURL(const char* lang="en") const { return forLang(m_urls,lang); } - const DOMElement* getElement() const { return m_root; } - - private: - const char* forLang(const map& m, const char* lang) const { - map::const_iterator i=m.find(lang); - return (i==m.end()) ? NULL : i->second.c_str(); - } - const DOMElement* m_root; - map m_names,m_displays,m_urls; - }; - - class EntityDescriptor; - - class EncryptionMethod : public XENCEncryptionMethod - { - public: - EncryptionMethod(const DOMElement* e); - ~EncryptionMethod() {} - - const XMLCh * getAlgorithm(void) const { return m_alg; } - const XMLCh * getDigestMethod(void) const { return m_digest; } - const XMLCh * getOAEPparams(void) const { return m_params; } - int getKeySize(void) const { return m_size; } - DOMElement* getElement(void) const { return const_cast(m_root); } - void setDigestMethod(const XMLCh * method) {throw exception();} - void setOAEPparams(const XMLCh * params) {throw exception();} - void setKeySize(int size) {throw exception();} - - private: - const DOMElement* m_root; - const XMLCh* m_alg; - const XMLCh* m_digest; - const XMLCh* m_params; - int m_size; - }; - - class KeyDescriptor : public IKeyDescriptor - { - public: - KeyDescriptor(const DOMElement* e); - ~KeyDescriptor(); - - KeyUse getUse() const { return m_use; } - DSIGKeyInfoList* getKeyInfo() const { return m_klist; } - saml::Iterator getEncryptionMethods() const { return m_methods; } - const DOMElement* getElement() const { return m_root; } - - private: - const DOMElement* m_root; - KeyUse m_use; - mutable DSIGKeyInfoList* m_klist; - vector m_methods; - }; - - class KeyAuthority : public IKeyAuthority - { - public: - KeyAuthority(const DOMElement* e); - ~KeyAuthority(); - - int getVerifyDepth() const { return m_depth; } - Iterator getKeyInfos() const { return m_klists; } - - private: - int m_depth; - vector m_klists; - }; - - class Role : public virtual IRoleDescriptor - { - public: - Role(const EntityDescriptor* provider, time_t validUntil, const DOMElement* e); - ~Role(); - - // External contract - const IEntityDescriptor* getEntityDescriptor() const {return m_provider;} - Iterator getProtocolSupportEnumeration() const {return m_protocolEnum;} - bool hasSupport(const XMLCh* protocol) const; - const char* getErrorURL() const {return (m_errorURL ? m_errorURL : m_provider->getErrorURL());} - bool isValid() const {return time(NULL) < m_validUntil;} - Iterator getKeyDescriptors() const {return m_keys;} - const IOrganization* getOrganization() const {return m_org ? m_org : m_provider->getOrganization();} - Iterator getContactPersons() const - {return (m_contacts.empty() ? m_provider->getContactPersons() : m_contacts);} - const DOMElement* getElement() const {return m_root;} - - protected: - vector m_protocolEnum; - vector m_keys; - - private: - const EntityDescriptor* m_provider; - const DOMElement* m_root; - XMLCh* m_protocolEnumCopy; - char* m_errorURL; - Organization* m_org; - vector m_contacts; - time_t m_validUntil; - }; - - class Endpoint : public virtual IEndpoint - { - public: - Endpoint(const DOMElement* e) : m_root(e), - m_binding(e->getAttributeNS(NULL,L(Binding))), - m_location(e->getAttributeNS(NULL,L(Location))), - m_resploc(e->getAttributeNS(NULL,SHIB_L(ResponseLocation))) {} - Endpoint(const XMLCh* binding, const XMLCh* loc) - : m_root(NULL), m_binding(binding), m_location(loc), m_resploc(NULL) {} - ~Endpoint() {} - - const XMLCh* getBinding() const { return m_binding; } - const XMLCh* getLocation() const { return m_location; } - const XMLCh* getResponseLocation() const { return m_resploc; } - const DOMElement* getElement() const { return m_root; } - - private: - const DOMElement* m_root; - const XMLCh* m_binding; - const XMLCh* m_location; - const XMLCh* m_resploc; - }; - - class IndexedEndpoint : public Endpoint, public virtual IIndexedEndpoint - { - public: - IndexedEndpoint(const DOMElement* e) : Endpoint(e), m_index(XMLString::parseInt(e->getAttributeNS(NULL,SHIB_L(index)))) {} - unsigned short getIndex() const {return m_index;} - - private: - unsigned short m_index; - }; - - class EndpointManager : public IEndpointManager - { - public: - EndpointManager() : m_soft(NULL), m_hard(NULL) {} - ~EndpointManager() { - for (vector::iterator i=m_endpoints.begin(); i!=m_endpoints.end(); i++) - delete const_cast(*i); - } - saml::Iterator getEndpoints() const {return m_endpoints;} - const IEndpoint* getDefaultEndpoint() const { - if (m_hard) return m_hard; - if (m_soft) return m_soft; - if (!m_endpoints.empty()) return *(m_endpoints.begin()); - return NULL; - } - const IEndpoint* getEndpointByIndex(unsigned short index) const { - for (vector::const_iterator i=m_endpoints.begin(); i!=m_endpoints.end(); i++) { - const IIndexedEndpoint* temp=dynamic_cast(*i); - if (temp && index==temp->getIndex()) - return temp; - } - return NULL; - } - const IEndpoint* getEndpointByBinding(const XMLCh* binding) const { - for (vector::const_iterator i=m_endpoints.begin(); i!=m_endpoints.end(); i++) - if (!XMLString::compareString(binding,(*i)->getBinding())) - return *i; - return NULL; - } - void add(IEndpoint* e) { - m_endpoints.push_back(e); - if (!m_hard && e->getElement()) { - const XMLCh* v=e->getElement()->getAttributeNS(NULL,SHIB_L(isDefault)); - if (v && (*v==chDigit_1 || *v==chLatin_t)) // explicit default - m_hard=e; - else if ((!v || !*v) && !m_soft) // implicit default - m_soft=e; - } - else if (!m_hard && !m_soft) { - // No default yet, so this one qualifies as an implicit. - m_soft=e; - } - } - - private: - vector m_endpoints; - const IEndpoint* m_soft; // Soft default (not explicit) - const IEndpoint* m_hard; // Hard default (explicit) - }; - - class SSORole : public Role, public virtual ISSODescriptor - { - public: - SSORole(const EntityDescriptor* provider, time_t validUntil, const DOMElement* e); - ~SSORole() {} - const IEndpointManager* getArtifactResolutionServiceManager() const {return &m_artifact;} - const IEndpointManager* getSingleLogoutServiceManager() const {return &m_logout;} - const IEndpointManager* getManageNameIDServiceManager() const {return &m_nameid;} - saml::Iterator getNameIDFormats() const {return m_formats;} - - private: - EndpointManager m_artifact,m_logout,m_nameid; - vector m_formats; - }; - - class IDPRole : public SSORole, public virtual IIDPSSODescriptor - { - public: - IDPRole(const EntityDescriptor* provider, time_t validUntil, const DOMElement* e); - ~IDPRole(); - bool getWantAuthnRequestsSigned() const {return m_wantAuthnRequestsSigned;} - const IEndpointManager* getSingleSignOnServiceManager() const {return &m_sso;} - const IEndpointManager* getNameIDMappingServiceManager() const {return &m_mapping;} - const IEndpointManager* getAssertionIDRequestServiceManager() const {return &m_idreq;} - saml::Iterator getAttributeProfiles() const {return m_attrprofs;} - saml::Iterator getAttributes() const {return m_attrs;} - - private: - EndpointManager m_sso,m_mapping,m_idreq; - vector m_attrprofs; - vector m_attrs; - bool m_wantAuthnRequestsSigned; - const XMLCh* m_sourceId; - friend class EntityDescriptor; - }; - - class AARole : public Role, public virtual IAttributeAuthorityDescriptor - { - public: - AARole(const EntityDescriptor* provider, time_t validUntil, const DOMElement* e); - ~AARole(); - const IEndpointManager* getAttributeServiceManager() const {return &m_query;} - const IEndpointManager* getAssertionIDRequestServiceManager() const {return &m_idreq;} - saml::Iterator getNameIDFormats() const {return m_formats;} - saml::Iterator getAttributeProfiles() const {return m_attrprofs;} - saml::Iterator getAttributes() const {return m_attrs;} - - private: - EndpointManager m_query,m_idreq; - vector m_formats,m_attrprofs; - vector m_attrs; - }; - - class EntityDescriptor : public IExtendedEntityDescriptor - { - public: - EntityDescriptor( - const DOMElement* e, - XMLMetadataImpl* wrapper, - time_t validUntil=LONG_MAX, - const IEntitiesDescriptor* parent=NULL - ); - ~EntityDescriptor(); - - // External contract - const XMLCh* getId() const {return m_id;} - bool isValid() const {return time(NULL) < m_validUntil;} - Iterator getRoleDescriptors() const {return m_roles;} - const IIDPSSODescriptor* getIDPSSODescriptor(const XMLCh* protocol) const; - const ISPSSODescriptor* getSPSSODescriptor(const XMLCh* protocol) const {return NULL;} - const IAuthnAuthorityDescriptor* getAuthnAuthorityDescriptor(const XMLCh* protocol) const {return NULL;} - const IAttributeAuthorityDescriptor* getAttributeAuthorityDescriptor(const XMLCh* protocol) const; - const IPDPDescriptor* getPDPDescriptor(const XMLCh* protocol) const {return NULL;} - const IAffiliationDescriptor* getAffiliationDescriptor() const {return NULL;} - const IOrganization* getOrganization() const {return m_org;} - Iterator getContactPersons() const {return m_contacts;} - Iterator > getAdditionalMetadataLocations() const {return m_locs;} - const IEntitiesDescriptor* getEntitiesDescriptor() const {return m_parent;} - Iterator getKeyAuthorities() const {return m_keyauths;} - saml::Iterator > getScopes() const {return m_scopes;} - const DOMElement* getElement() const {return m_root;} - - // Used internally - const char* getErrorURL() const {return m_errorURL.get();} - time_t getValidUntil() const {return m_validUntil;} - private: - const DOMElement* m_root; - const IEntitiesDescriptor* m_parent; - const XMLCh* m_id; - auto_ptr m_errorURL; - IOrganization* m_org; - vector m_contacts; - vector m_roles; - vector > m_locs; - vector m_keyauths; - vector > m_scopes; - time_t m_validUntil; - }; - - class EntitiesDescriptor : public IExtendedEntitiesDescriptor - { - public: - EntitiesDescriptor( - const DOMElement* e, - XMLMetadataImpl* wrapper, - time_t validUntil=LONG_MAX, - const IEntitiesDescriptor* parent=NULL - ); - ~EntitiesDescriptor(); - - const XMLCh* getName() const {return m_name;} - bool isValid() const {return time(NULL) < m_validUntil;} - const IEntitiesDescriptor* getEntitiesDescriptor() const {return m_parent;} - Iterator getEntitiesDescriptors() const {return m_groups;} - Iterator getEntityDescriptors() const {return m_providers;} - Iterator getKeyAuthorities() const {return m_keyauths;} - const DOMElement* getElement() const {return m_root;} - - // Used internally - time_t getValidUntil() const {return m_validUntil;} - private: - const DOMElement* m_root; - const IEntitiesDescriptor* m_parent; - const XMLCh* m_name; - vector m_groups; - vector m_providers; - vector m_keyauths; - time_t m_validUntil; - }; - - XMLMetadataImpl(const char* pathname, const XMLMetadata* wrapper) - : ReloadableXMLFileImpl(pathname), m_outer(wrapper), m_rootProvider(NULL), m_rootGroup(NULL) { init(); } - XMLMetadataImpl(const DOMElement* e, const XMLMetadata* wrapper) - : ReloadableXMLFileImpl(e), m_outer(wrapper), m_rootProvider(NULL), m_rootGroup(NULL) { init(); } - void init(); - ~XMLMetadataImpl(); - - typedef multimap sitemap_t; - typedef multimap groupmap_t; - sitemap_t m_sites; - sitemap_t m_sources; - groupmap_t m_groups; - EntityDescriptor* m_rootProvider; - EntitiesDescriptor* m_rootGroup; - const XMLMetadata* m_outer; - }; - - class XMLMetadata : public IMetadata, public ReloadableXMLFile - { - public: - XMLMetadata(const DOMElement* e); - ~XMLMetadata() {delete m_credResolver;} - - const IEntityDescriptor* lookup(const char* providerId, bool strict=true) const; - const IEntityDescriptor* lookup(const XMLCh* providerId, bool strict=true) const; - const IEntityDescriptor* lookup(const saml::SAMLArtifact* artifact) const; - const IEntitiesDescriptor* lookupGroup(const char* name, bool strict=true) const; - const IEntitiesDescriptor* lookupGroup(const XMLCh* name, bool strict=true) const; - pair getRoot() const; - - bool verifySignature(DOMDocument* doc, const DOMElement* parent, bool failUnsigned) const; - - protected: - virtual ReloadableXMLFileImpl* newImplementation(const char* pathname, bool first=true) const; - virtual ReloadableXMLFileImpl* newImplementation(const DOMElement* e, bool first=true) const; - - private: - bool m_exclusions,m_verify; - set m_set; - ICredResolver* m_credResolver; - }; -} - -IPlugIn* XMLMetadataFactory(const DOMElement* e) -{ - auto_ptr m(new XMLMetadata(e)); - m->getImplementation(); - return m.release(); -} - -ReloadableXMLFileImpl* XMLMetadata::newImplementation(const DOMElement* e, bool first) const -{ - return new XMLMetadataImpl(e,this); -} - -ReloadableXMLFileImpl* XMLMetadata::newImplementation(const char* pathname, bool first) const -{ - return new XMLMetadataImpl(pathname,this); -} - -XMLMetadataImpl::ContactPerson::ContactPerson(const DOMElement* e) : m_root(e) -{ - const XMLCh* type=NULL; - - // Old metadata or new? - if (saml::XML::isElementNamed(e,::XML::SHIB_NS,SHIB_L(Contact))) { - type=e->getAttributeNS(NULL,SHIB_L(Type)); - auto_ptr wrapper(toUTF8(e->getAttributeNS(NULL,SHIB_L(Name)))); - m_surName=wrapper; - if (e->hasAttributeNS(NULL,SHIB_L(Email))) { - auto_ptr temp(toUTF8(e->getAttributeNS(NULL,SHIB_L(Email)))); - if (temp.get()) - m_emails.push_back(temp.get()); - } - } - else if (saml::XML::isElementNamed(e,::XML::SAML2META_NS,SHIB_L(ContactPerson))) { - type=e->getAttributeNS(NULL,SHIB_L(contactType)); - e=saml::XML::getFirstChildElement(e); - while (e) { - if (saml::XML::isElementNamed(e,::XML::SAML2META_NS,SHIB_L(Company)) && e->hasChildNodes()) { - auto_ptr wrapper(toUTF8(e->getFirstChild()->getNodeValue())); - m_company=wrapper; - } - else if (saml::XML::isElementNamed(e,::XML::SAML2META_NS,SHIB_L(GivenName)) && e->hasChildNodes()) { - auto_ptr wrapper(toUTF8(e->getFirstChild()->getNodeValue())); - m_givenName=wrapper; - } - else if (saml::XML::isElementNamed(e,::XML::SAML2META_NS,SHIB_L(SurName)) && e->hasChildNodes()) { - auto_ptr wrapper(toUTF8(e->getFirstChild()->getNodeValue())); - m_surName=wrapper; - } - else if (saml::XML::isElementNamed(e,::XML::SAML2META_NS,SHIB_L(EmailAddress)) && e->hasChildNodes()) { - auto_ptr temp(toUTF8(e->getFirstChild()->getNodeValue())); - if (temp.get()) m_emails.push_back(temp.get()); - } - else if (saml::XML::isElementNamed(e,::XML::SAML2META_NS,SHIB_L(TelephoneNumber)) && e->hasChildNodes()) { - auto_ptr temp(toUTF8(e->getFirstChild()->getNodeValue())); - if (temp.get()) m_phones.push_back(temp.get()); - } - e=saml::XML::getNextSiblingElement(e); - } - } - - if (!XMLString::compareString(type,SHIB_L(technical))) - m_type=IContactPerson::technical; - else if (!XMLString::compareString(type,SHIB_L(support))) - m_type=IContactPerson::support; - else if (!XMLString::compareString(type,SHIB_L(administrative))) - m_type=IContactPerson::administrative; - else if (!XMLString::compareString(type,SHIB_L(billing))) - m_type=IContactPerson::billing; - else if (!XMLString::compareString(type,SHIB_L(other))) - m_type=IContactPerson::other; -} - -XMLMetadataImpl::Organization::Organization(const DOMElement* e) : m_root(e) -{ - DOMNode* n=NULL; - e=saml::XML::getFirstChildElement(e); - while (e) { - if (saml::XML::isElementNamed(e,::XML::SAML2META_NS,SHIB_L(OrganizationName))) { - n=e->getFirstChild(); - if (n) { - auto_ptr name(toUTF8(n->getNodeValue())); - auto_ptr_char lang(e->getAttributeNS(saml::XML::XML_NS,L(lang))); - m_names[lang.get()]=name.get(); - } - } - else if (saml::XML::isElementNamed(e,::XML::SAML2META_NS,SHIB_L(OrganizationDisplayName))) { - n=e->getFirstChild(); - if (n) { - auto_ptr display(toUTF8(n->getNodeValue())); - auto_ptr_char lang(e->getAttributeNS(saml::XML::XML_NS,L(lang))); - m_displays[lang.get()]=display.get(); - } - } - else if (saml::XML::isElementNamed(e,::XML::SAML2META_NS,SHIB_L(OrganizationURL))) { - n=e->getFirstChild(); - if (n) { - auto_ptr url(toUTF8(n->getNodeValue())); - auto_ptr_char lang(e->getAttributeNS(saml::XML::XML_NS,L(lang))); - m_urls[lang.get()]=url.get(); - } - } - e=saml::XML::getNextSiblingElement(e); - } -} - -XMLMetadataImpl::EncryptionMethod::EncryptionMethod(const DOMElement* e) : m_root(e) -{ - m_alg=e->getAttributeNS(NULL,SHIB_L(Algorithm)); - e=saml::XML::getFirstChildElement(e); - while (e) { - if (saml::XML::isElementNamed(e,::XML::XMLENC_NS,SHIB_L(KeySize))) { - DOMNode* n=e->getFirstChild(); - if (n) m_size=XMLString::parseInt(n->getNodeValue()); - } - else if (saml::XML::isElementNamed(e,saml::XML::XMLSIG_NS,SHIB_L(DigestMethod))) { - DOMNode* n=e->getFirstChild(); - if (n) m_digest=n->getNodeValue(); - } - else if (saml::XML::isElementNamed(e,::XML::XMLENC_NS,SHIB_L(OAEParams))) { - DOMNode* n=e->getFirstChild(); - if (n) m_params=n->getNodeValue(); - } - e=saml::XML::getNextSiblingElement(e); - } -} - -XMLMetadataImpl::KeyDescriptor::KeyDescriptor(const DOMElement* e) : m_root(e), m_use(unspecified), m_klist(NULL) -{ -#ifdef _DEBUG - saml::NDC ndc("KeyDescriptor"); -#endif - if (!XMLString::compareString(e->getAttributeNS(NULL,SHIB_L(use)),SHIB_L(encryption))) - m_use=encryption; - else if (!XMLString::compareString(e->getAttributeNS(NULL,SHIB_L(use)),SHIB_L(signing))) - m_use=signing; - - m_klist = new DSIGKeyInfoList(NULL); - - // Process ds:KeyInfo - e=saml::XML::getFirstChildElement(e); - - // We let XMLSec hack through anything it can. This should evolve over time, or we can - // plug in our own KeyResolver later... - try { - if (!m_klist->loadListFromXML(const_cast(e))) - Category::getInstance(XMLPROVIDERS_LOGCAT".Metadata").warn( - "skipping ds:KeyInfo element containing unsupported children" - ); - } - catch (XSECCryptoException& xe) { - Category::getInstance(XMLPROVIDERS_LOGCAT".Metadata").error("unable to process ds:KeyInfo element: %s",xe.getMsg()); - } - - // Check for encryption methods. - e=saml::XML::getNextSiblingElement(e); - while (e && saml::XML::isElementNamed(e,::XML::SAML2META_NS,SHIB_L(EncryptionMethod))) - m_methods.push_back(new EncryptionMethod(e)); -} - -XMLMetadataImpl::KeyDescriptor::~KeyDescriptor() -{ - for_each(m_methods.begin(),m_methods.end(),xmltooling::cleanup()); - delete m_klist; -} - -XMLMetadataImpl::KeyAuthority::KeyAuthority(const DOMElement* e) : m_depth(1) -{ -#ifdef _DEBUG - saml::NDC ndc("KeyAuthority"); -#endif - if (e->hasAttributeNS(NULL,SHIB_L(VerifyDepth))) - m_depth=XMLString::parseInt(e->getAttributeNS(NULL,SHIB_L(VerifyDepth))); - - // Process ds:KeyInfo children - e=saml::XML::getFirstChildElement(e,saml::XML::XMLSIG_NS,L(KeyInfo)); - while (e) { - auto_ptr klist(new DSIGKeyInfoList(NULL)); - - // We let XMLSec hack through anything it can. This should evolve over time, or we can - // plug in our own KeyResolver later... - DOMElement* child=saml::XML::getFirstChildElement(e); - while (child) { - try { - if (!klist->addXMLKeyInfo(child)) { - Category::getInstance(XMLPROVIDERS_LOGCAT".Metadata").warn( - "skipped unresolvable ds:KeyInfo child element"); - } - } - catch (XSECCryptoException& xe) { - Category::getInstance(XMLPROVIDERS_LOGCAT".Metadata").error( - "unable to process ds:KeyInfo child element: %s",xe.getMsg()); - } - child=saml::XML::getNextSiblingElement(child); - } - - if (klist->getSize()>0) - m_klists.push_back(klist.release()); - else - Category::getInstance(XMLPROVIDERS_LOGCAT".Metadata").warn( - "skipping ds:KeyInfo with no resolvable child elements"); - e=saml::XML::getNextSiblingElement(e,saml::XML::XMLSIG_NS,L(KeyInfo)); - } -} - -XMLMetadataImpl::KeyAuthority::~KeyAuthority() -{ - for_each(m_klists.begin(),m_klists.end(),xmltooling::cleanup()); -} - -XMLMetadataImpl::Role::Role(const EntityDescriptor* provider, time_t validUntil, const DOMElement* e) - : m_provider(provider), m_errorURL(NULL), m_protocolEnumCopy(NULL), m_org(NULL), m_validUntil(validUntil), m_root(e) -{ - // Check the root element namespace. If SAML2, assume it's the std schema. - if (e && !XMLString::compareString(e->getNamespaceURI(),::XML::SAML2META_NS)) { - - if (e->hasAttributeNS(NULL,SHIB_L(validUntil))) { - SAMLDateTime exp(e->getAttributeNS(NULL,SHIB_L(validUntil))); - exp.parseDateTime(); - m_validUntil=min(m_validUntil,exp.getEpoch()); - } - - if (e->hasAttributeNS(NULL,SHIB_L(errorURL))) - m_errorURL=toUTF8(e->getAttributeNS(NULL,SHIB_L(errorURL))); - - // Chop the protocol list into pieces...assume any whitespace can appear in between. - m_protocolEnumCopy=XMLString::replicate(e->getAttributeNS(NULL,SHIB_L(protocolSupportEnumeration))); - XMLCh* temp=m_protocolEnumCopy; - while (temp && *temp) { - XMLCh* start=temp++; - while (*temp && !XMLChar1_1::isWhitespace(*temp)) temp++; - if (*temp) - *temp++=chNull; - m_protocolEnum.push_back(start); - while (*temp && XMLChar1_1::isWhitespace(*temp)) temp++; - } - - e=saml::XML::getFirstChildElement(m_root,::XML::SAML2META_NS,SHIB_L(KeyDescriptor)); - while (e) { - m_keys.push_back(new KeyDescriptor(e)); - e=saml::XML::getNextSiblingElement(e,::XML::SAML2META_NS,SHIB_L(KeyDescriptor)); - } - - e=saml::XML::getFirstChildElement(m_root,::XML::SAML2META_NS,SHIB_L(Organization)); - if (e) - m_org=new Organization(e); - - e=saml::XML::getFirstChildElement(m_root,::XML::SAML2META_NS,SHIB_L(ContactPerson)); - while (e) { - m_contacts.push_back(new ContactPerson(e)); - e=saml::XML::getNextSiblingElement(e,::XML::SAML2META_NS,SHIB_L(ContactPerson)); - } - } -} - -XMLMetadataImpl::Role::~Role() -{ - delete m_org; - delete m_errorURL; - if (m_protocolEnumCopy) XMLString::release(&m_protocolEnumCopy); - for_each(m_keys.begin(),m_keys.end(),xmltooling::cleanup()); - for_each(m_contacts.begin(),m_contacts.end(),xmltooling::cleanup()); -} - -bool XMLMetadataImpl::Role::hasSupport(const XMLCh* protocol) const -{ - Iterator i(m_protocolEnum); - while (i.hasNext()) { - if (!XMLString::compareString(protocol,i.next())) - return true; - } - return false; -} - -XMLMetadataImpl::SSORole::SSORole(const EntityDescriptor* provider, time_t validUntil, const DOMElement* e) - : Role(provider,validUntil,e) -{ - // Check the root element namespace. If SAML2, assume it's the std schema. - if (!XMLString::compareString(e->getNamespaceURI(),::XML::SAML2META_NS)) { - unsigned int i; - DOMNodeList* nlist=e->getElementsByTagNameNS(::XML::SAML2META_NS,SHIB_L(ArtifactResolutionService)); - for (i=0; nlist && igetLength(); i++) - m_artifact.add(new IndexedEndpoint(static_cast(nlist->item(i)))); - - nlist=e->getElementsByTagNameNS(::XML::SAML2META_NS,SHIB_L(SingleLogoutService)); - for (i=0; nlist && igetLength(); i++) - m_logout.add(new Endpoint(static_cast(nlist->item(i)))); - - nlist=e->getElementsByTagNameNS(::XML::SAML2META_NS,SHIB_L(ManageNameIDService)); - for (i=0; nlist && igetLength(); i++) - m_nameid.add(new Endpoint(static_cast(nlist->item(i)))); - - nlist=e->getElementsByTagNameNS(::XML::SAML2META_NS,SHIB_L(NameIDFormat)); - for (i=0; nlist && igetLength(); i++) { - DOMNode* n=nlist->item(i)->getFirstChild(); - if (n) m_formats.push_back(n->getNodeValue()); - } - } - else { - // For old style, we just do SAML 1.1 compatibility with Shib handles. - m_protocolEnum.push_back(saml::XML::SAML11_PROTOCOL_ENUM); - m_formats.push_back(shibspconstants::SHIB1_NAMEID_FORMAT_URI); - } -} - -XMLMetadataImpl::IDPRole::IDPRole(const EntityDescriptor* provider, time_t validUntil, const DOMElement* e) - : SSORole(provider,validUntil,e), m_wantAuthnRequestsSigned(false), m_sourceId(NULL) -{ - // Check the root element namespace. If SAML2, assume it's the std schema. - if (!XMLString::compareString(e->getNamespaceURI(),::XML::SAML2META_NS)) { - const XMLCh* flag=e->getAttributeNS(NULL,SHIB_L(WantAuthnRequestsSigned)); - m_wantAuthnRequestsSigned=(flag && (*flag==chDigit_1 || *flag==chLatin_t)); - - // Check for SourceID extension. - DOMElement* ext=saml::XML::getFirstChildElement(e,::XML::SAML2META_NS,SHIB_L(Extensions)); - if (ext) { - ext=saml::XML::getFirstChildElement(ext,saml::XML::SAML_ARTIFACT_SOURCEID,SHIB_L(SourceID)); - if (ext && ext->hasChildNodes()) - m_sourceId=ext->getFirstChild()->getNodeValue(); - } - - unsigned int i; - DOMNodeList* nlist=e->getElementsByTagNameNS(::XML::SAML2META_NS,SHIB_L(SingleSignOnService)); - for (i=0; nlist && igetLength(); i++) - m_sso.add(new Endpoint(static_cast(nlist->item(i)))); - - nlist=e->getElementsByTagNameNS(::XML::SAML2META_NS,SHIB_L(NameIDMappingService)); - for (i=0; nlist && igetLength(); i++) - m_mapping.add(new Endpoint(static_cast(nlist->item(i)))); - - nlist=e->getElementsByTagNameNS(::XML::SAML2META_NS,SHIB_L(AssertionIDRequestService)); - for (i=0; nlist && igetLength(); i++) - m_idreq.add(new Endpoint(static_cast(nlist->item(i)))); - - nlist=e->getElementsByTagNameNS(::XML::SAML2META_NS,SHIB_L(AttributeProfile)); - for (i=0; nlist && igetLength(); i++) { - DOMNode* n=nlist->item(i)->getFirstChild(); - if (n) m_attrprofs.push_back(n->getNodeValue()); - } - - nlist=e->getElementsByTagNameNS(::XML::SAML2ASSERT_NS,L(Attribute)); - for (i=0; nlist && igetLength(); i++) { - // For now, we need to convert these to plain SAML 1.1 attributes. - DOMElement* src=static_cast(nlist->item(i)); - DOMElement* copy=e->getOwnerDocument()->createElementNS(saml::XML::SAML_NS,L(Attribute)); - copy->setAttributeNS(NULL,L(AttributeName),src->getAttributeNS(NULL,SHIB_L(Name))); - copy->setAttributeNS(NULL,L(AttributeNamespace),src->getAttributeNS(NULL,SHIB_L(NameFormat))); - src=saml::XML::getFirstChildElement(src,::XML::SAML2ASSERT_NS,L(AttributeValue)); - while (src) { - src=saml::XML::getNextSiblingElement(src,::XML::SAML2ASSERT_NS,L(AttributeValue)); - DOMElement* val=e->getOwnerDocument()->createElementNS(saml::XML::SAML_NS,L(AttributeValue)); - DOMNamedNodeMap* attrs = src->getAttributes(); - for (unsigned int j=0; jgetLength(); j++) - val->setAttributeNodeNS(static_cast(e->getOwnerDocument()->importNode(attrs->item(j),true))); - while (src->hasChildNodes()) - val->appendChild(src->getFirstChild()); - copy->appendChild(val); - } - m_attrs.push_back(SAMLAttribute::getInstance(copy)); - } - } - else { - m_protocolEnum.push_back(::XML::SHIB_NS); - m_attrprofs.push_back(shibspconstants::SHIB1_ATTRIBUTE_NAMESPACE_URI); - unsigned int i; - DOMNodeList* nlist=e->getElementsByTagNameNS(::XML::SHIB_NS,SHIB_L(HandleService)); - for (i=0; nlist && igetLength(); i++) { - // Manufacture an endpoint for the "Shib" binding. - m_sso.add( - new Endpoint(shibspconstants::SHIB1_AUTHNREQUEST_PROFILE_URI,static_cast(nlist->item(i))->getAttributeNS(NULL,L(Location))) - ); - - // We're going to "mock up" a KeyDescriptor that contains the specified Name as a ds:KeyName. - DOMElement* kd=e->getOwnerDocument()->createElementNS(::XML::SAML2META_NS,SHIB_L(KeyDescriptor)); - DOMElement* ki=e->getOwnerDocument()->createElementNS(saml::XML::XMLSIG_NS,L(KeyInfo)); - DOMElement* kn=e->getOwnerDocument()->createElementNS(saml::XML::XMLSIG_NS,SHIB_L(KeyName)); - kn->appendChild( - e->getOwnerDocument()->createTextNode( - static_cast(nlist->item(i))->getAttributeNS(NULL,SHIB_L(Name)) - ) - ); - ki->appendChild(kn); - kd->appendChild(ki); - kd->setAttributeNS(NULL,SHIB_L(use),SHIB_L(signing)); - m_keys.push_back(new KeyDescriptor(kd)); - } - } -} - -XMLMetadataImpl::IDPRole::~IDPRole() -{ - for_each(m_attrs.begin(),m_attrs.end(),xmltooling::cleanup()); -} - -XMLMetadataImpl::AARole::AARole(const EntityDescriptor* provider, time_t validUntil, const DOMElement* e) - : Role(provider,validUntil,e) -{ - // Check the root element namespace. If SAML2, assume it's the std schema. - if (!XMLString::compareString(e->getNamespaceURI(),::XML::SAML2META_NS)) { - unsigned int i; - DOMNodeList* nlist=e->getElementsByTagNameNS(::XML::SAML2META_NS,SHIB_L(AttributeService)); - for (i=0; nlist && igetLength(); i++) - m_query.add(new Endpoint(static_cast(nlist->item(i)))); - - nlist=e->getElementsByTagNameNS(::XML::SAML2META_NS,SHIB_L(AssertionIDRequestService)); - for (i=0; nlist && igetLength(); i++) - m_idreq.add(new Endpoint(static_cast(nlist->item(i)))); - - nlist=e->getElementsByTagNameNS(::XML::SAML2META_NS,SHIB_L(NameIDFormat)); - for (i=0; nlist && igetLength(); i++) { - DOMNode* n=nlist->item(i)->getFirstChild(); - if (n) m_formats.push_back(n->getNodeValue()); - } - - nlist=e->getElementsByTagNameNS(::XML::SAML2META_NS,SHIB_L(AttributeProfile)); - for (i=0; nlist && igetLength(); i++) { - DOMNode* n=nlist->item(i)->getFirstChild(); - if (n) m_attrprofs.push_back(n->getNodeValue()); - } - - nlist=e->getElementsByTagNameNS(::XML::SAML2ASSERT_NS,L(Attribute)); - for (i=0; nlist && igetLength(); i++) { - // For now, we need to convert these to plain SAML 1.1 attributes. - DOMElement* src=static_cast(nlist->item(i)); - DOMElement* copy=e->getOwnerDocument()->createElementNS(saml::XML::SAML_NS,L(Attribute)); - copy->setAttributeNS(NULL,L(AttributeName),src->getAttributeNS(NULL,SHIB_L(Name))); - copy->setAttributeNS(NULL,L(AttributeNamespace),src->getAttributeNS(NULL,SHIB_L(NameFormat))); - src=saml::XML::getFirstChildElement(src,::XML::SAML2ASSERT_NS,L(AttributeValue)); - while (src) { - src=saml::XML::getNextSiblingElement(src,::XML::SAML2ASSERT_NS,L(AttributeValue)); - DOMElement* val=e->getOwnerDocument()->createElementNS(saml::XML::SAML_NS,L(AttributeValue)); - DOMNamedNodeMap* attrs = src->getAttributes(); - for (unsigned int j=0; jgetLength(); j++) - val->setAttributeNodeNS(static_cast(e->getOwnerDocument()->importNode(attrs->item(j),true))); - while (src->hasChildNodes()) - val->appendChild(src->getFirstChild()); - copy->appendChild(val); - } - m_attrs.push_back(SAMLAttribute::getInstance(copy)); - } - } - else { - // For old style, we just do SAML 1.1 compatibility with Shib handles. - m_protocolEnum.push_back(saml::XML::SAML11_PROTOCOL_ENUM); - m_formats.push_back(shibspconstants::SHIB1_NAMEID_FORMAT_URI); - m_attrprofs.push_back(shibspconstants::SHIB1_ATTRIBUTE_NAMESPACE_URI); - unsigned int i; - DOMNodeList* nlist=e->getElementsByTagNameNS(::XML::SHIB_NS,SHIB_L(AttributeAuthority)); - for (i=0; nlist && igetLength(); i++) { - // Manufacture an endpoint for the SOAP binding. - m_query.add( - new Endpoint( - SAMLBinding::SOAP, - static_cast(nlist->item(i))->getAttributeNS(NULL,L(Location)) - ) - ); - - // We're going to "mock up" a KeyDescriptor that contains the specified Name as a ds:KeyName. - DOMElement* kd=e->getOwnerDocument()->createElementNS(::XML::SAML2META_NS,SHIB_L(KeyDescriptor)); - DOMElement* ki=e->getOwnerDocument()->createElementNS(saml::XML::XMLSIG_NS,L(KeyInfo)); - DOMElement* kn=e->getOwnerDocument()->createElementNS(saml::XML::XMLSIG_NS,SHIB_L(KeyName)); - kn->appendChild( - e->getOwnerDocument()->createTextNode( - static_cast(nlist->item(i))->getAttributeNS(NULL,SHIB_L(Name)) - ) - ); - ki->appendChild(kn); - kd->appendChild(ki); - m_keys.push_back(new KeyDescriptor(kd)); - } - } -} - -XMLMetadataImpl::AARole::~AARole() -{ - for_each(m_attrs.begin(),m_attrs.end(),xmltooling::cleanup()); -} - -XMLMetadataImpl::EntityDescriptor::EntityDescriptor( - const DOMElement* e, XMLMetadataImpl* wrapper, time_t validUntil, const IEntitiesDescriptor* parent - ) : m_root(e), m_parent(parent), m_org(NULL), m_validUntil(validUntil) -{ - // Check the root element namespace. If SAML2, assume it's the std schema. - DOMNodeList* scopes=NULL; - if (!XMLString::compareString(e->getNamespaceURI(),::XML::SAML2META_NS)) { - m_id=e->getAttributeNS(NULL,SHIB_L(entityID)); - - if (e->hasAttributeNS(NULL,SHIB_L(validUntil))) { - SAMLDateTime exp(e->getAttributeNS(NULL,SHIB_L(validUntil))); - exp.parseDateTime(); - m_validUntil=min(validUntil,exp.getEpoch()); - } - - DOMElement* child=saml::XML::getFirstChildElement(e); - while (child) { - // Process the various kinds of children that we care about... - if (saml::XML::isElementNamed(child,::XML::SAML2META_NS,SHIB_L(Extensions))) { - DOMElement* ext = saml::XML::getFirstChildElement(child,::XML::SHIBMETA_NS,SHIB_L(KeyAuthority)); - while (ext) { - m_keyauths.push_back(new KeyAuthority(ext)); - ext = saml::XML::getNextSiblingElement(ext,::XML::SHIBMETA_NS,SHIB_L(KeyAuthority)); - } - } - else if (saml::XML::isElementNamed(child,::XML::SAML2META_NS,SHIB_L(ContactPerson))) { - m_contacts.push_back(new ContactPerson(child)); - } - else if (saml::XML::isElementNamed(child,::XML::SAML2META_NS,SHIB_L(Organization))) { - m_org=new Organization(child); - } - else if (saml::XML::isElementNamed(child,::XML::SAML2META_NS,SHIB_L(AdditionalMetadataLocation))) { - DOMNode* loc=child->getFirstChild(); - if (loc) - m_locs.push_back( - pair(child->getAttributeNS(NULL,::XML::Literals::_namespace),loc->getNodeValue()) - ); - } - else if (saml::XML::isElementNamed(child,::XML::SAML2META_NS,SHIB_L(IDPSSODescriptor))) { - if (wrapper->m_outer->verifySignature(child->getOwnerDocument(),child,false)) - m_roles.push_back(new IDPRole(this,m_validUntil,child)); - } - else if (saml::XML::isElementNamed(child,::XML::SAML2META_NS,SHIB_L(AttributeAuthorityDescriptor))) { - if (wrapper->m_outer->verifySignature(child->getOwnerDocument(),child,false)) - m_roles.push_back(new AARole(this,m_validUntil,child)); - } - child = saml::XML::getNextSiblingElement(child); - } - - // Grab all the shibmd:Scope elements here and at the role level. - scopes=e->getElementsByTagNameNS(::XML::SHIBMETA_NS,SHIB_L(Scope)); - } - else { - m_id=e->getAttributeNS(NULL,SHIB_L(Name)); - auto_ptr wrapper(toUTF8(e->getAttributeNS(NULL,SHIB_L(ErrorURL)))); - m_errorURL=wrapper; - - bool idp=false,aa=false; // only want to build a role once - DOMElement* child=saml::XML::getFirstChildElement(e); - while (child) { - // Process the various kinds of OriginSite children that we care about... - if (saml::XML::isElementNamed(child,::XML::SHIB_NS,SHIB_L(Contact))) { - m_contacts.push_back(new ContactPerson(child)); - } - else if (saml::XML::isElementNamed(child,::XML::SHIB_NS,SHIB_L(HandleService)) && !idp) { - // Create the IDP role if needed. - m_roles.push_back(new IDPRole(this, m_validUntil, e)); - idp=true; - } - else if (saml::XML::isElementNamed(child,::XML::SHIB_NS,SHIB_L(AttributeAuthority)) && !aa) { - // Create the AA role if needed. - m_roles.push_back(new AARole(this, m_validUntil, e)); - aa=true; - } - child = saml::XML::getNextSiblingElement(child); - } - - // Grab all the shib:Domain elements. - scopes=e->getElementsByTagNameNS(::XML::SHIB_NS,SHIB_L(Domain)); - } - - // Process scopes. - for (unsigned int i=0; scopes && i < scopes->getLength(); i++) { - const XMLCh* dom=(scopes->item(i)->hasChildNodes()) ? scopes->item(i)->getFirstChild()->getNodeValue() : NULL; - if (dom && *dom) { - const XMLCh* regexp=static_cast(scopes->item(i))->getAttributeNS(NULL,SHIB_L(regexp)); - m_scopes.push_back( - pair(dom,(regexp && (*regexp==chLatin_t || *regexp==chDigit_1))) - ); - } - } - - auto_ptr_char id(m_id); - wrapper->m_sites.insert(pair(id.get(),this)); - - // Look for an IdP role, and register the artifact source ID and endpoints. - const IDPRole* idp=NULL; - for (vector::const_iterator r=m_roles.begin(); r!=m_roles.end(); r++) { - if (idp=dynamic_cast(*r)) { - if (idp->m_sourceId) { - auto_ptr_char sourceid(idp->m_sourceId); - wrapper->m_sources.insert(pair(sourceid.get(),this)); - } - else { - string sourceid=SAMLArtifact::toHex(SAMLArtifactType0001::generateSourceId(id.get())); - wrapper->m_sources.insert(pair(sourceid,this)); - } - Iterator locs=idp->getArtifactResolutionServiceManager()->getEndpoints(); - while (locs.hasNext()) { - auto_ptr_char loc(locs.next()->getLocation()); - wrapper->m_sources.insert(pair(loc.get(),this)); - } - } - } -} - -const IIDPSSODescriptor* XMLMetadataImpl::EntityDescriptor::getIDPSSODescriptor(const XMLCh* protocol) const -{ - const IIDPSSODescriptor* ret=NULL; - for (vector::const_iterator i=m_roles.begin(); i!=m_roles.end(); i++) { - if ((*i)->hasSupport(protocol) && (*i)->isValid() && (ret=dynamic_cast(*i))) - return ret; - } - return NULL; -} - -const IAttributeAuthorityDescriptor* XMLMetadataImpl::EntityDescriptor::getAttributeAuthorityDescriptor(const XMLCh* protocol) const -{ - const IAttributeAuthorityDescriptor* ret=NULL; - for (vector::const_iterator i=m_roles.begin(); i!=m_roles.end(); i++) { - if ((*i)->hasSupport(protocol) && (*i)->isValid() && (ret=dynamic_cast(*i))) - return ret; - } - return NULL; -} - -XMLMetadataImpl::EntityDescriptor::~EntityDescriptor() -{ - delete m_org; - for_each(m_contacts.begin(),m_contacts.end(),xmltooling::cleanup()); - for_each(m_roles.begin(),m_roles.end(),xmltooling::cleanup()); - for_each(m_keyauths.begin(),m_keyauths.end(),xmltooling::cleanup()); -} - -XMLMetadataImpl::EntitiesDescriptor::EntitiesDescriptor( - const DOMElement* e, XMLMetadataImpl* wrapper, time_t validUntil, const IEntitiesDescriptor* parent - ) : m_root(e), m_name(e->getAttributeNS(NULL,SHIB_L(Name))), m_parent(parent), m_validUntil(validUntil) -{ - // Check the root element namespace. If SAML2, assume it's the std schema. - if (!XMLString::compareString(e->getNamespaceURI(),::XML::SAML2META_NS)) { - - if (e->hasAttributeNS(NULL,SHIB_L(validUntil))) { - SAMLDateTime exp(e->getAttributeNS(NULL,SHIB_L(validUntil))); - exp.parseDateTime(); - m_validUntil=min(validUntil,exp.getEpoch()); - } - - e=saml::XML::getFirstChildElement(e); - while (e) { - if (saml::XML::isElementNamed(e,::XML::SAML2META_NS,SHIB_L(Extensions))) { - DOMElement* ext = saml::XML::getFirstChildElement(e,::XML::SHIBMETA_NS,SHIB_L(KeyAuthority)); - while (ext) { - m_keyauths.push_back(new KeyAuthority(ext)); - ext = saml::XML::getNextSiblingElement(ext,::XML::SHIBMETA_NS,SHIB_L(KeyAuthority)); - } - } - else if (saml::XML::isElementNamed(e,::XML::SAML2META_NS,SHIB_L(EntitiesDescriptor))) { - if (wrapper->m_outer->verifySignature(e->getOwnerDocument(),e,false)) - m_groups.push_back(new EntitiesDescriptor(e,wrapper,m_validUntil,this)); - } - else if (saml::XML::isElementNamed(e,::XML::SAML2META_NS,SHIB_L(EntityDescriptor))) { - if (wrapper->m_outer->verifySignature(e->getOwnerDocument(),e,false)) - m_providers.push_back(new EntityDescriptor(e,wrapper,m_validUntil,this)); - } - e=saml::XML::getNextSiblingElement(e); - } - } - else { - e=saml::XML::getFirstChildElement(e); - while (e) { - if (saml::XML::isElementNamed(e,::XML::SHIB_NS,SHIB_L(SiteGroup))) { - if (wrapper->m_outer->verifySignature(e->getOwnerDocument(),e,false)) - m_groups.push_back(new EntitiesDescriptor(e,wrapper,m_validUntil,this)); - } - else if (saml::XML::isElementNamed(e,::XML::SHIB_NS,SHIB_L(OriginSite))) - m_providers.push_back(new EntityDescriptor(e,wrapper,m_validUntil,this)); - e=saml::XML::getNextSiblingElement(e); - } - } - - if (!saml::XML::isEmpty(m_name)) { - auto_ptr_char n(m_name); - wrapper->m_groups.insert(pair(n.get(),this)); - } - else - m_name=NULL; -} - -XMLMetadataImpl::EntitiesDescriptor::~EntitiesDescriptor() -{ - for_each(m_providers.begin(),m_providers.end(),xmltooling::cleanup()); - for_each(m_groups.begin(),m_groups.end(),xmltooling::cleanup()); - for_each(m_keyauths.begin(),m_keyauths.end(),xmltooling::cleanup()); -} - -void XMLMetadataImpl::init() -{ -#ifdef _DEBUG - NDC ndc("init"); -#endif - Category& log=Category::getInstance(XMLPROVIDERS_LOGCAT".Metadata"); - - try - { - if (saml::XML::isElementNamed(m_root,::XML::SAML2META_NS,SHIB_L(EntitiesDescriptor))) { - if (m_outer->verifySignature(m_root->getOwnerDocument(),m_root,true)) - m_rootGroup=new EntitiesDescriptor(m_root,this); - } - else if (saml::XML::isElementNamed(m_root,::XML::SAML2META_NS,SHIB_L(EntityDescriptor))) { - if (m_outer->verifySignature(m_root->getOwnerDocument(),m_root,true)) - m_rootProvider=new EntityDescriptor(m_root,this); - } - else if (saml::XML::isElementNamed(m_root,::XML::SHIB_NS,SHIB_L(SiteGroup))) { - if (m_outer->verifySignature(m_root->getOwnerDocument(),m_root,true)) - m_rootGroup=new EntitiesDescriptor(m_root,this); - } - else if (saml::XML::isElementNamed(m_root,::XML::SHIB_NS,SHIB_L(OriginSite))) { - if (m_outer->verifySignature(m_root->getOwnerDocument(),m_root,true)) - m_rootProvider=new EntityDescriptor(m_root,this); - } - else { - log.error("Construction requires a valid SAML metadata file"); - throw MetadataException("Construction requires a valid SAML metadata file"); - } - } - catch (SAMLException& e) - { - log.errorStream() << "Error while parsing SAML metadata: " << e.what() << CategoryStream::ENDLINE; - this->~XMLMetadataImpl(); - throw; - } -#ifndef _DEBUG - catch (...) - { - log.error("Unexpected error while parsing SAML metadata"); - this->~XMLMetadataImpl(); - throw; - } -#endif - - if (!m_rootGroup && !m_rootProvider) { - log.error("Metadata file contained no valid information"); - throw MetadataException("Metadata file contained no valid information"); - } -} - -XMLMetadataImpl::~XMLMetadataImpl() -{ - delete m_rootGroup; - delete m_rootProvider; -} - -XMLMetadata::XMLMetadata(const DOMElement* e) : ReloadableXMLFile(e), m_exclusions(true), m_verify(false), m_credResolver(NULL) -{ - static const XMLCh uri[] = { chLatin_u, chLatin_r, chLatin_i, chNull }; - if (e->hasAttributeNS(NULL,uri)) { - // First check for explicit enablement of entities. - DOMNodeList* nlist=e->getElementsByTagName(SHIB_L(Include)); - for (unsigned int i=0; nlist && igetLength(); i++) { - if (nlist->item(i)->hasChildNodes()) { - auto_ptr_char temp(nlist->item(i)->getFirstChild()->getNodeValue()); - if (temp.get()) { - m_set.insert(temp.get()); - m_exclusions=false; - } - } - } - // If there was no explicit enablement, build a set of exclusions. - if (m_exclusions) { - nlist=e->getElementsByTagName(SHIB_L(Exclude)); - for (unsigned int j=0; nlist && jgetLength(); j++) { - if (nlist->item(j)->hasChildNodes()) { - auto_ptr_char temp(nlist->item(j)->getFirstChild()->getNodeValue()); - if (temp.get()) - m_set.insert(temp.get()); - } - } - } - } - - const XMLCh* v=e->getAttributeNS(NULL,SHIB_L(verify)); - m_verify=(v && (*v==chLatin_t || *v==chDigit_1)); - - string cr_type; - DOMElement* r=saml::XML::getFirstChildElement(e,::XML::CREDS_NS,SHIB_L(FileResolver)); - if (r) - cr_type="edu.internet2.middleware.shibboleth.common.Credentials.FileCredentialResolver"; - else { - r=saml::XML::getFirstChildElement(e,::XML::CREDS_NS,SHIB_L(CustomResolver)); - if (r) { - auto_ptr_char c(r->getAttributeNS(NULL,SHIB_L(Class))); - cr_type=c.get(); - } - } - - if (!cr_type.empty()) { - try { - IPlugIn* plugin=SAMLConfig::getConfig().getPlugMgr().newPlugin(cr_type.c_str(),r); - ICredResolver* cr=dynamic_cast(plugin); - if (cr) - m_credResolver=cr; - else { - Category::getInstance(XMLPROVIDERS_LOGCAT".Metadata").error("plugin was not a credential resolver"); - delete plugin; - throw UnsupportedExtensionException("plugin was not a credential resolver"); - } - } - catch (SAMLException& e) { - Category::getInstance(XMLPROVIDERS_LOGCAT".Metadata").error("failed to instantiate credential resolver: %s", e.what()); - throw; - } - } - - if (m_verify && !m_credResolver) { - delete m_credResolver; - throw MalformedException("Metadata provider told to verify signatures, but a verification key is not available."); - } -} - -bool XMLMetadata::verifySignature(DOMDocument* doc, const DOMElement* parent, bool failUnsigned) const -{ - if (!m_verify) - return true; - -#ifdef _DEBUG - saml::NDC ndc("verifySignature"); -#endif - Category& log=Category::getInstance(XMLPROVIDERS_LOGCAT".Metadata"); - - DOMElement* sigNode=saml::XML::getFirstChildElement(parent,saml::XML::XMLSIG_NS,L(Signature)); - if (!sigNode) { - if (failUnsigned) { - log.error("rejecting unsigned element"); - return false; - } - return true; - } - - XSECCryptoX509* cert=NULL; - Iterator certs=m_credResolver->getCertificates(); - if (certs.hasNext()) - cert=certs.next(); - else { - log.error("unable to find any certificates to use in verifying signature"); - return false; - } - - static const XMLCh ID[]={chLatin_I, chLatin_D, chNull}; - static const XMLCh null[]={chDoubleQuote, chDoubleQuote, chNull}; - - // Load the signature. - XSECProvider prov; - DSIGSignature* sig=NULL; - try { - sig=prov.newSignatureFromDOM(doc,sigNode); - sig->load(); - - bool valid=false; - const XMLCh* URI=NULL; - - // Verify the signature coverage. - DSIGReferenceList* refs=sig->getReferenceList(); - if (sig->getSignatureMethod()==SIGNATURE_RSA && refs && refs->getSize()==1) { - DSIGReference* ref=refs->item(0); - if (ref) { - URI=ref->getURI(); - if (!URI || !*URI || (*URI==chPound && - !XMLString::compareString(&URI[1],static_cast(sigNode->getParentNode())->getAttributeNS(NULL,ID)))) { - DSIGTransformList* tlist=ref->getTransforms(); - for (unsigned int i=0; tlist && igetSize(); i++) { - if (tlist->item(i)->getTransformType()==TRANSFORM_ENVELOPED_SIGNATURE) - valid=true; - else if (tlist->item(i)->getTransformType()!=TRANSFORM_EXC_C14N && - tlist->item(i)->getTransformType()!=TRANSFORM_C14N) { - valid=false; - break; - } - } - } - } - } - - if (!valid) { - auto_ptr_char temp((URI && *URI) ? URI : null); - log.error("detected an invalid signature profile (Reference URI was %s)",temp.get()); - return false; - } - - sig->setSigningKey(cert->clonePublicKey()); - if (!sig->verify()) { - auto_ptr_char temp((URI && *URI) ? URI : null); - log.error("detected an invalid signature value (Reference URI was %s)",temp.get()); - return false; - } - - prov.releaseSignature(sig); - } - catch(XSECException& e) { - auto_ptr_char msg(e.getMsg()); - log.errorStream() << "caught XMLSec exception while verifying metadata signature: " << msg.get() << CategoryStream::ENDLINE; - if (sig) - prov.releaseSignature(sig); - return false; - } - catch(XSECCryptoException& e) { - log.errorStream() << "caught XMLSecCrypto exception while verifying metadata signature: " << e.getMsg() << CategoryStream::ENDLINE; - if (sig) - prov.releaseSignature(sig); - return false; - } - catch(...) { - if (sig) - prov.releaseSignature(sig); - log.error("caught unknown exception while verifying metadata signature"); - throw; - } - return true; -} - -const IEntityDescriptor* XMLMetadata::lookup(const char* providerId, bool strict) const -{ - if (strict && m_exclusions && m_set.find(providerId)!=m_set.end()) - return NULL; - else if (strict && !m_exclusions && m_set.find(providerId)==m_set.end()) - return NULL; - - XMLMetadataImpl* impl=dynamic_cast(getImplementation()); - pair range= - impl->m_sites.equal_range(providerId); - - time_t now=time(NULL); - for (XMLMetadataImpl::sitemap_t::const_iterator i=range.first; i!=range.second; i++) - if (now < i->second->getValidUntil()) - return i->second; - - if (!strict && range.first!=range.second) - return range.first->second; - - return NULL; -} - -const IEntityDescriptor* XMLMetadata::lookup(const XMLCh* providerId, bool strict) const -{ - auto_ptr_char temp(providerId); - return lookup(temp.get(),strict); -} - -const IEntityDescriptor* XMLMetadata::lookup(const SAMLArtifact* artifact) const -{ - time_t now=time(NULL); - XMLMetadataImpl* impl=dynamic_cast(getImplementation()); - pair range; - - // Depends on type of artifact. - const SAMLArtifactType0001* type1=dynamic_cast(artifact); - if (type1) { - range=impl->m_sources.equal_range(SAMLArtifact::toHex(type1->getSourceID())); - } - else { - const SAMLArtifactType0002* type2=dynamic_cast(artifact); - if (type2) { - range=impl->m_sources.equal_range(type2->getSourceLocation()); - } - else - return NULL; - } - - // Check exclude list. - if (range.first!=range.second) { - auto_ptr_char id(range.first->second->getId()); - if (m_exclusions && m_set.find(id.get())!=m_set.end()) - return NULL; - else if (!m_exclusions && m_set.find(id.get())==m_set.end()) - return NULL; - - for (XMLMetadataImpl::sitemap_t::iterator i=range.first; i!=range.second; i++) - if (now < i->second->getValidUntil()) - return i->second; - } - - return NULL; -} - -const IEntitiesDescriptor* XMLMetadata::lookupGroup(const char* name, bool strict) const -{ - if (strict && m_exclusions && m_set.find(name)!=m_set.end()) - return NULL; - else if (strict && !m_exclusions && m_set.find(name)==m_set.end()) - return NULL; - - XMLMetadataImpl* impl=dynamic_cast(getImplementation()); - pair range= - impl->m_groups.equal_range(name); - - time_t now=time(NULL); - for (XMLMetadataImpl::groupmap_t::iterator i=range.first; i!=range.second; i++) - if (now < i->second->getValidUntil()) - return i->second; - - if (!strict && range.first!=range.second) - return range.first->second; - - return NULL; -} - -const IEntitiesDescriptor* XMLMetadata::lookupGroup(const XMLCh* name, bool strict) const -{ - auto_ptr_char temp(name); - return lookupGroup(temp.get(),strict); -} - -pair XMLMetadata::getRoot() const -{ - XMLMetadataImpl* impl=dynamic_cast(getImplementation()); - return pair(impl->m_rootGroup,impl->m_rootProvider); -} - diff --git a/xmlproviders/XMLProviders.cpp b/xmlproviders/XMLProviders.cpp index 28165e0..ce01f15 100644 --- a/xmlproviders/XMLProviders.cpp +++ b/xmlproviders/XMLProviders.cpp @@ -41,7 +41,6 @@ using namespace std; // Metadata Factories PlugManager::Factory TargetedIDFactory; -PlugManager::Factory XMLMetadataFactory; PlugManager::Factory XMLCredentialsFactory; PlugManager::Factory XMLAAPFactory; PlugManager::Factory FileCredResolverFactory; @@ -51,17 +50,11 @@ extern "C" int XML_EXPORTS saml_extension_init(void*) { // Register extension schemas. saml::XML::registerSchema(::XML::SHIB_NS,::XML::SHIB_SCHEMA_ID); - saml::XML::registerSchema(::XML::SHIBMETA_NS,::XML::SHIBMETA_SCHEMA_ID); saml::XML::registerSchema(::XML::CREDS_NS,::XML::CREDS_SCHEMA_ID); - saml::XML::registerSchema(::XML::SAML2META_NS,::XML::SAML2META_SCHEMA_ID); - saml::XML::registerSchema(::XML::SAML2ASSERT_NS,::XML::SAML2ASSERT_SCHEMA_ID); - saml::XML::registerSchema(::XML::XMLENC_NS,::XML::XMLENC_SCHEMA_ID); // Register metadata factories (some are legacy aliases) SAMLConfig& conf=SAMLConfig::getConfig(); conf.getPlugMgr().regFactory("edu.internet2.middleware.shibboleth.common.provider.TargetedIDFactory",&TargetedIDFactory); - conf.getPlugMgr().regFactory("edu.internet2.middleware.shibboleth.metadata.provider.XMLMetadata",&XMLMetadataFactory); - conf.getPlugMgr().regFactory("edu.internet2.middleware.shibboleth.common.provider.XMLMetadata",&XMLMetadataFactory); conf.getPlugMgr().regFactory("edu.internet2.middleware.shibboleth.common.Credentials",&XMLCredentialsFactory); conf.getPlugMgr().regFactory("edu.internet2.middleware.shibboleth.common.Credentials.FileCredentialResolver",&FileCredResolverFactory); conf.getPlugMgr().regFactory("edu.internet2.middleware.shibboleth.aap.provider.XMLAAP",&XMLAAPFactory); @@ -76,8 +69,6 @@ extern "C" void XML_EXPORTS saml_extension_term() // Unregister metadata factories SAMLConfig& conf=SAMLConfig::getConfig(); conf.getPlugMgr().unregFactory("edu.internet2.middleware.shibboleth.common.provider.TargetedIDFactory"); - conf.getPlugMgr().unregFactory("edu.internet2.middleware.shibboleth.metadata.provider.XMLMetadata"); - conf.getPlugMgr().unregFactory("edu.internet2.middleware.shibboleth.common.provider.XMLMetadata"); conf.getPlugMgr().unregFactory("edu.internet2.middleware.shibboleth.common.Credentials"); conf.getPlugMgr().unregFactory("edu.internet2.middleware.shibboleth.common.Credentials.FileCredentialResolver"); conf.getPlugMgr().unregFactory("edu.internet2.middleware.shibboleth.aap.provider.XMLAAP"); @@ -100,29 +91,3 @@ void log_openssl() code=ERR_get_error_line_data(&file,&line,&data,&flags); } } - -X509* B64_to_X509(const char* buf) -{ - BIO* bmem = BIO_new_mem_buf((void*)buf,-1); - BIO* b64 = BIO_new(BIO_f_base64()); - b64 = BIO_push(b64, bmem); - X509* x=NULL; - d2i_X509_bio(b64,&x); - if (!x) - log_openssl(); - BIO_free_all(b64); - return x; -} - -X509_CRL* B64_to_CRL(const char* buf) -{ - BIO* bmem = BIO_new_mem_buf((void*)buf,-1); - BIO* b64 = BIO_new(BIO_f_base64()); - b64 = BIO_push(b64, bmem); - X509_CRL* x=NULL; - d2i_X509_CRL_bio(b64,&x); - if (!x) - log_openssl(); - BIO_free_all(b64); - return x; -} diff --git a/xmlproviders/internal.h b/xmlproviders/internal.h index 712f61b..a3abfdf 100644 --- a/xmlproviders/internal.h +++ b/xmlproviders/internal.h @@ -45,56 +45,19 @@ #define SHIB_L(s) ::XML::Literals::s #define SHIB_L_QNAME(p,s) ::XML::Literals::p##_##s -// direct OpenSSL error content to log4cpp void log_openssl(); -// build an OpenSSL object out of a base-64 encoded DER buffer (XML style) -X509_CRL* B64_to_CRL(const char* buf); -X509* B64_to_X509(const char* buf); - class XML { public: // URI constants static const XMLCh SHIB_NS[]; static const XMLCh SHIB_SCHEMA_ID[]; - static const XMLCh SHIBMETA_NS[]; - static const XMLCh SHIBMETA_SCHEMA_ID[]; static const XMLCh CREDS_NS[]; static const XMLCh CREDS_SCHEMA_ID[]; - static const XMLCh TRUST_NS[]; - static const XMLCh TRUST_SCHEMA_ID[]; - static const XMLCh SAML2ASSERT_NS[]; - static const XMLCh SAML2ASSERT_SCHEMA_ID[]; - static const XMLCh SAML2META_NS[]; - static const XMLCh SAML2META_SCHEMA_ID[]; - static const XMLCh XMLENC_NS[]; - static const XMLCh XMLENC_SCHEMA_ID[]; - - // ds:KeyInfo RetrievalMethods - static const XMLCh XMLSIG_RETMETHOD_RAWX509[]; // http://www.w3.org/2000/09/xmldsig#rawX509Certificate - static const XMLCh XMLSIG_RETMETHOD_RAWX509CRL[]; // http://www.w3.org/2000/09/xmldsig-more#rawX509CRL struct Literals { - // old metadata constants - static const XMLCh AttributeAuthority[]; - static const XMLCh Contact[]; - static const XMLCh Domain[]; - static const XMLCh Email[]; - static const XMLCh ErrorURL[]; - static const XMLCh HandleService[]; - static const XMLCh InvalidHandle[]; - static const XMLCh Name[]; - static const XMLCh OriginSite[]; - static const XMLCh SiteGroup[]; - - static const XMLCh administrative[]; - static const XMLCh billing[]; - static const XMLCh other[]; - static const XMLCh support[]; - static const XMLCh technical[]; - // credentials constants static const XMLCh CAPath[]; static const XMLCh Certificate[]; @@ -108,18 +71,6 @@ public: static const XMLCh password[]; static const XMLCh Path[]; - // trust constants - static const XMLCh Exponent[]; - static const XMLCh KeyAuthority[]; - static const XMLCh KeyName[]; - static const XMLCh Modulus[]; - static const XMLCh RetrievalMethod[]; - static const XMLCh RSAKeyValue[]; - static const XMLCh Trust[]; - static const XMLCh URI[]; - static const XMLCh VerifyDepth[]; - static const XMLCh X509CRL[]; - // SAML attribute constants static const XMLCh Accept[]; static const XMLCh Alias[]; @@ -131,6 +82,7 @@ public: static const XMLCh CaseSensitive[]; static const XMLCh Factory[]; static const XMLCh Header[]; + static const XMLCh Name[]; static const XMLCh Namespace[]; static const XMLCh Scope[]; static const XMLCh Scoped[]; @@ -142,77 +94,8 @@ public: static const XMLCh regexp[]; static const XMLCh xpath[]; - static const XMLCh Include[]; - static const XMLCh Exclude[]; static const XMLCh url[]; - static const XMLCh verify[]; - // new metadata constants - static const XMLCh AdditionalMetadataLocation[]; - static const XMLCh AffiliateMember[]; - static const XMLCh AffiliationDescriptor[]; - static const XMLCh affiliationOwnerID[]; - static const XMLCh Algorithm[]; - static const XMLCh ArtifactResolutionService[]; - static const XMLCh AssertionConsumerService[]; - static const XMLCh AssertionIDRequestService[]; - static const XMLCh AttributeAuthorityDescriptor[]; - static const XMLCh AttributeConsumingService[]; - static const XMLCh AttributeProfile[]; - static const XMLCh AttributeService[]; - static const XMLCh AuthnAuthorityDescriptor[]; - static const XMLCh AuthnQueryService[]; - static const XMLCh AuthnRequestsSigned[]; - static const XMLCh AuthzService[]; - static const XMLCh cacheDuration[]; - static const XMLCh Company[]; - static const XMLCh ContactPerson[]; - static const XMLCh contactType[]; - static const XMLCh DigestMethod[]; - static const XMLCh EmailAddress[]; - static const XMLCh encryption[]; - static const XMLCh EncryptionMethod[]; - static const XMLCh EntitiesDescriptor[]; - static const XMLCh EntityDescriptor[]; - static const XMLCh entityID[]; - static const XMLCh errorURL[]; - static const XMLCh Extensions[]; - static const XMLCh GivenName[]; - static const XMLCh IDPSSODescriptor[]; - static const XMLCh index[]; - static const XMLCh isDefault[]; - static const XMLCh isRequired[]; - static const XMLCh KeyDescriptor[]; - static const XMLCh KeySize[]; - static const XMLCh ManageNameIDService[]; - static const XMLCh _namespace[]; - static const XMLCh NameFormat[]; - static const XMLCh NameIDFormat[]; - static const XMLCh NameIDMappingService[]; - static const XMLCh OAEParams[]; - static const XMLCh Organization[]; - static const XMLCh OrganizationName[]; - static const XMLCh OrganizationDisplayName[]; - static const XMLCh OrganizationURL[]; - static const XMLCh PDPDescriptor[]; - static const XMLCh protocolSupportEnumeration[]; - static const XMLCh RequestedAttribute[]; - static const XMLCh ResponseLocation[]; - static const XMLCh RoleDescriptor[]; - static const XMLCh ServiceDescription[]; - static const XMLCh ServiceName[]; - static const XMLCh signing[]; - static const XMLCh SingleLogoutService[]; - static const XMLCh SingleSignOnService[]; - static const XMLCh SourceID[]; - static const XMLCh SPSSODescriptor[]; - static const XMLCh SurName[]; - static const XMLCh TelephoneNumber[]; - static const XMLCh use[]; - static const XMLCh validUntil[]; - static const XMLCh WantAuthnRequestsSigned[]; - static const XMLCh WantAssertionsSigned[]; - // access control constants static const XMLCh AccessControl[]; static const XMLCh AND[]; diff --git a/xmlproviders/xmlproviders.vcproj b/xmlproviders/xmlproviders.vcproj index 4b37757..89c2394 100644 --- a/xmlproviders/xmlproviders.vcproj +++ b/xmlproviders/xmlproviders.vcproj @@ -248,10 +248,6 @@ > - - -- 2.1.4