From 345b96b7cc783365dd9952cc55e36edc5694f1d0 Mon Sep 17 00:00:00 2001 From: Scott Cantor Date: Wed, 27 Dec 2006 18:01:43 +0000 Subject: [PATCH] Move Shib constants to new lib, fixed symbol conflicts. --- Shibboleth.sln | 43 +-- apache/mod_apache.cpp | 35 +- isapi_shib/isapi_shib.cpp | 15 +- odbc_ccache/odbc-ccache.cpp | 4 +- shib-target/shib-ccache.cpp | 26 +- shib-target/shib-config.cpp | 6 +- shib-target/shib-handlers.cpp | 10 +- shib-target/shib-ini.cpp | 26 +- shib-target/shib-target.h | 5 + shib/Makefile.am | 1 - shib/shib.h | 12 - shib/shib.vcproj | 4 - shibsp/SPConstants.cpp | 73 ++++ shibsp/SPConstants.h | 58 +++ shibsp/shibsp.vcproj | 8 + test/shibtest.cpp | 15 +- xmlproviders/Makefile.am | 3 +- xmlproviders/XMLAAP.cpp | 7 +- xmlproviders/XMLMetadata.cpp | 14 +- xmlproviders/XMLProviders.cpp | 6 - xmlproviders/XMLTrust.cpp | 779 --------------------------------------- xmlproviders/xmlproviders.vcproj | 4 - 22 files changed, 247 insertions(+), 907 deletions(-) create mode 100644 shibsp/SPConstants.cpp create mode 100644 shibsp/SPConstants.h delete mode 100644 xmlproviders/XMLTrust.cpp diff --git a/Shibboleth.sln b/Shibboleth.sln index eb94c38..8c0cc96 100644 --- a/Shibboleth.sln +++ b/Shibboleth.sln @@ -2,95 +2,96 @@ 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 - {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} + {84890110-2190-4AAE-9BDC-58F90DF71E4F} = {84890110-2190-4AAE-9BDC-58F90DF71E4F} + {81F0F7A6-DC36-46EF-957F-F9E81D4403F6} = {81F0F7A6-DC36-46EF-957F-F9E81D4403F6} 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 - {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} + {84890110-2190-4AAE-9BDC-58F90DF71E4F} = {84890110-2190-4AAE-9BDC-58F90DF71E4F} + {81F0F7A6-DC36-46EF-957F-F9E81D4403F6} = {81F0F7A6-DC36-46EF-957F-F9E81D4403F6} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_shib20", "apache\mod_shib20.vcproj", "{68E9568B-476C-4289-B93C-893432378ADC}" ProjectSection(ProjectDependencies) = postProject - {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} + {84890110-2190-4AAE-9BDC-58F90DF71E4F} = {84890110-2190-4AAE-9BDC-58F90DF71E4F} + {81F0F7A6-DC36-46EF-957F-F9E81D4403F6} = {81F0F7A6-DC36-46EF-957F-F9E81D4403F6} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "nsapi_shib", "nsapi_shib\nsapi_shib.vcproj", "{1396D80A-8672-4224-9B02-95F3F4207CDB}" 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} + {81F0F7A6-DC36-46EF-957F-F9E81D4403F6} = {81F0F7A6-DC36-46EF-957F-F9E81D4403F6} + {E6CAB6C8-1D73-4410-970A-52BF9EC57810} = {E6CAB6C8-1D73-4410-970A-52BF9EC57810} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "posttest", "posttest\posttest.vcproj", "{16E70C47-789E-43D5-AFDF-964D386C3CB5}" 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} + {81F0F7A6-DC36-46EF-957F-F9E81D4403F6} = {81F0F7A6-DC36-46EF-957F-F9E81D4403F6} + {E6CAB6C8-1D73-4410-970A-52BF9EC57810} = {E6CAB6C8-1D73-4410-970A-52BF9EC57810} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shar", "shar\shar.vcproj", "{F13141B5-6C87-40BB-8D4E-5CC56EBB4C59}" ProjectSection(ProjectDependencies) = postProject - {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} + {84890110-2190-4AAE-9BDC-58F90DF71E4F} = {84890110-2190-4AAE-9BDC-58F90DF71E4F} + {81F0F7A6-DC36-46EF-957F-F9E81D4403F6} = {81F0F7A6-DC36-46EF-957F-F9E81D4403F6} 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 - {84890110-2190-4AAE-9BDC-58F90DF71E4F} = {84890110-2190-4AAE-9BDC-58F90DF71E4F} {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 - {E6CAB6C8-1D73-4410-970A-52BF9EC57810} = {E6CAB6C8-1D73-4410-970A-52BF9EC57810} {81F0F7A6-DC36-46EF-957F-F9E81D4403F6} = {81F0F7A6-DC36-46EF-957F-F9E81D4403F6} + {E6CAB6C8-1D73-4410-970A-52BF9EC57810} = {E6CAB6C8-1D73-4410-970A-52BF9EC57810} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shibtest", "shibtest\shibtest.vcproj", "{67AF22A3-C26E-40BE-B0CA-2ABEE5123763}" ProjectSection(ProjectDependencies) = postProject - {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} + {84890110-2190-4AAE-9BDC-58F90DF71E4F} = {84890110-2190-4AAE-9BDC-58F90DF71E4F} + {81F0F7A6-DC36-46EF-957F-F9E81D4403F6} = {81F0F7A6-DC36-46EF-957F-F9E81D4403F6} 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 - {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} + {81F0F7A6-DC36-46EF-957F-F9E81D4403F6} = {81F0F7A6-DC36-46EF-957F-F9E81D4403F6} + {E6CAB6C8-1D73-4410-970A-52BF9EC57810} = {E6CAB6C8-1D73-4410-970A-52BF9EC57810} 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} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "odbc_ccache", "odbc_ccache\odbc_ccache.vcproj", "{DAC7FB99-038A-45C9-A27C-21B6C8D4CD1E}" ProjectSection(ProjectDependencies) = postProject - {84890110-2190-4AAE-9BDC-58F90DF71E4F} = {84890110-2190-4AAE-9BDC-58F90DF71E4F} {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}") = "mod_shib22", "apache\mod_shib22.vcproj", "{B44C0852-83B8-4FB2-A86E-097C9C8256D0}" ProjectSection(ProjectDependencies) = postProject - {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} + {84890110-2190-4AAE-9BDC-58F90DF71E4F} = {84890110-2190-4AAE-9BDC-58F90DF71E4F} + {81F0F7A6-DC36-46EF-957F-F9E81D4403F6} = {81F0F7A6-DC36-46EF-957F-F9E81D4403F6} 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 8dd7095..40e0871 100644 --- a/apache/mod_apache.cpp +++ b/apache/mod_apache.cpp @@ -68,7 +68,6 @@ using namespace shibsp; using namespace shibtarget; -using namespace saml; using namespace xmltooling; using namespace std; @@ -277,11 +276,11 @@ public: return m_body.c_str(); // Read the posted data if (ap_setup_client_block(m_req, REQUEST_CHUNKED_ERROR)) - throw SAMLException("Apache function (setup_client_block) failed while reading POST request body."); + throw saml::SAMLException("Apache function (setup_client_block) failed while reading POST request body."); if (!ap_should_client_block(m_req)) - throw SAMLException("Apache function (should_client_block) failed while reading POST request body."); + throw saml::SAMLException("Apache function (should_client_block) failed while reading POST request body."); if (m_req->remaining > 1024*1024) - throw SAMLException("Blocked POST request body larger than size limit."); + throw saml::SAMLException("Blocked POST request body larger than size limit."); m_gotBody=true; char buff[HUGE_STRING_LEN]; ap_hard_timeout("[mod_shib] getRequestBody", m_req); @@ -315,7 +314,7 @@ public: const string& msg, int code=200, const string& content_type="text/html", - const Iterator& headers=EMPTY(header_t) + const saml::Iterator& headers=EMPTY(header_t) ) { m_req->content_type = ap_psprintf(m_req->pool, content_type.c_str()); while (headers.hasNext()) { @@ -364,7 +363,7 @@ extern "C" int shib_check_user(request_rec* r) // export happened successfully.. this user is ok. return OK; } - catch (SAMLException& e) { + catch (saml::SAMLException& e) { ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, SH_AP_R(r), "shib_check_user threw an exception: %s", e.what()); return SERVER_ERROR; } @@ -409,7 +408,7 @@ extern "C" int shib_handler(request_rec* r) ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, SH_AP_R(r), "doHandler() did not do anything."); return SERVER_ERROR; } - catch (SAMLException& e) { + catch (saml::SAMLException& e) { ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, SH_AP_R(r), "shib_handler threw an exception: %s", e.what()); return SERVER_ERROR; } @@ -446,7 +445,7 @@ extern "C" int shib_auth_checker(request_rec* r) // We're all okay. return OK; } - catch (SAMLException& e) { + catch (saml::SAMLException& e) { ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, SH_AP_R(r), "shib_auth_checker threw an exception: %s", e.what()); return SERVER_ERROR; } @@ -472,7 +471,7 @@ public: ) const; }; -IPlugIn* htAccessFactory(const DOMElement* e) +saml::IPlugIn* htAccessFactory(const DOMElement* e) { return new htAccessControl(); } @@ -501,18 +500,18 @@ private: IAccessControl* m_htaccess; }; -IPlugIn* ApacheRequestMapFactory(const DOMElement* e) +saml::IPlugIn* ApacheRequestMapFactory(const DOMElement* e) { return new ApacheRequestMapper(e); } ApacheRequestMapper::ApacheRequestMapper(const DOMElement* e) : m_mapper(NULL), m_staKey(NULL), m_propsKey(NULL), m_htaccess(NULL) { - IPlugIn* p=SAMLConfig::getConfig().getPlugMgr().newPlugin(shibtarget::XML::XMLRequestMapType,e); + saml::IPlugIn* p=saml::SAMLConfig::getConfig().getPlugMgr().newPlugin(shibtarget::XML::XMLRequestMapType,e); m_mapper=dynamic_cast(p); if (!m_mapper) { delete p; - throw UnsupportedExtensionException("Embedded request mapper plugin was not of correct type."); + throw saml::UnsupportedExtensionException("Embedded request mapper plugin was not of correct type."); } m_htaccess=new htAccessControl(); m_staKey=ThreadKey::create(NULL); @@ -763,7 +762,7 @@ bool htAccessControl::authorized( } } else { - Iterator provs=st->getApplication()->getAAPProviders(); + saml::Iterator provs=st->getApplication()->getAAPProviders(); shibboleth::AAP wrapper(provs,w); if (wrapper.fail()) { st->log(ShibTarget::LogLevelWarn, string("htAccessControl plugin didn't recognize require rule: ") + w); @@ -799,7 +798,7 @@ bool htAccessControl::authorized( if (i == 0) { st->log(ShibTarget::LogLevelError, string("htAccessControl plugin found invalid header encoding (") + vals + "): starts with a semicolon"); - throw SAMLException("Invalid information supplied to authorization plugin."); + throw saml::SAMLException("Invalid information supplied to authorization plugin."); } if (vals_str.at(i-1) == '\\') { @@ -944,10 +943,10 @@ extern "C" void shib_child_init(apr_pool_t* p, server_rec* s) ap_log_error(APLOG_MARK,APLOG_CRIT|APLOG_NOERRNO,SH_AP_R(s),"shib_child_init() failed to initialize libraries"); exit(1); } - SAMLConfig::getConfig().getPlugMgr().regFactory(shibtarget::XML::htAccessControlType,&htAccessFactory); - SAMLConfig::getConfig().getPlugMgr().regFactory(shibtarget::XML::NativeRequestMapType,&ApacheRequestMapFactory); + saml::SAMLConfig::getConfig().getPlugMgr().regFactory(shibtarget::XML::htAccessControlType,&htAccessFactory); + saml::SAMLConfig::getConfig().getPlugMgr().regFactory(shibtarget::XML::NativeRequestMapType,&ApacheRequestMapFactory); // We hijack the legacy type so that 1.2 config files will load this plugin - SAMLConfig::getConfig().getPlugMgr().regFactory(shibtarget::XML::LegacyRequestMapType,&ApacheRequestMapFactory); + saml::SAMLConfig::getConfig().getPlugMgr().regFactory(shibtarget::XML::LegacyRequestMapType,&ApacheRequestMapFactory); if (!g_Config->load(g_szSHIBConfig)) { ap_log_error(APLOG_MARK,APLOG_CRIT|APLOG_NOERRNO,SH_AP_R(s),"shib_child_init() failed to load configuration"); @@ -955,7 +954,7 @@ extern "C" void shib_child_init(apr_pool_t* p, server_rec* s) } IConfig* conf=g_Config->getINI(); - Locker locker(conf); + saml::Locker locker(conf); const PropertySet* props=conf->getPropertySet("Local"); if (props) { pair unsetValue=props->getString("unsetHeaderValue"); diff --git a/isapi_shib/isapi_shib.cpp b/isapi_shib/isapi_shib.cpp index 0a36bb8..dda800d 100644 --- a/isapi_shib/isapi_shib.cpp +++ b/isapi_shib/isapi_shib.cpp @@ -42,7 +42,6 @@ using namespace shibsp; using namespace shibtarget; -using namespace saml; using namespace xmltooling; using namespace std; @@ -180,7 +179,7 @@ extern "C" BOOL WINAPI GetFilterVersion(PHTTP_FILTER_VERSION pVer) // Access the implementation-specifics for site mappings. IConfig* conf=g_Config->getINI(); - Locker locker(conf); + saml::Locker locker(conf); const PropertySet* props=conf->getPropertySet("Local"); if (props) { const DOMElement* impl=saml::XML::getFirstChildElement( @@ -426,7 +425,7 @@ public: const string& msg, int code=200, const string& content_type="text/html", - const Iterator& headers=EMPTY(header_t)) { + const saml::Iterator& headers=EMPTY(header_t)) { string hdr = string ("Connection: close\r\nContent-type: ") + content_type + "\r\n"; while (headers.hasNext()) { const header_t& h=headers.next(); @@ -538,7 +537,7 @@ extern "C" DWORD WINAPI HttpFilterProc(PHTTP_FILTER_CONTEXT pfc, DWORD notificat else return WriteClientError(pfc,"Shibboleth Filter detected unexpected IIS error."); } - catch (SAMLException& e) { + catch (saml::SAMLException& e) { LogEvent(NULL, EVENTLOG_ERROR_TYPE, 2100, NULL, e.what()); return WriteClientError(pfc,"Shibboleth Filter caught an exception, check Event Log for details."); } @@ -680,7 +679,7 @@ public: if (m_gotBody) return m_body.c_str(); if (m_lpECB->cbTotalBytes > 1024*1024) // 1MB? - throw SAMLException("Size of POST request body exceeded limit."); + throw saml::SAMLException("Size of POST request body exceeded limit."); else if (m_lpECB->cbTotalBytes != m_lpECB->cbAvailable) { m_gotBody=true; char buf[8192]; @@ -689,7 +688,7 @@ public: DWORD buflen=8192; BOOL ret = m_lpECB->ReadClient(m_lpECB->ConnID, buf, &buflen); if (!ret || !buflen) - throw SAMLException("Error reading POST request body from browser."); + throw saml::SAMLException("Error reading POST request body from browser."); m_body.append(buf, buflen); datalen-=buflen; } @@ -704,7 +703,7 @@ public: const string &msg, int code=200, const string& content_type="text/html", - const Iterator& headers=EMPTY(header_t)) { + const saml::Iterator& headers=EMPTY(header_t)) { string hdr = string ("Connection: close\r\nContent-type: ") + content_type + "\r\n"; for (unsigned int k = 0; k < headers.size(); k++) { hdr += headers[k].first + ": " + headers[k].second + "\r\n"; @@ -786,7 +785,7 @@ extern "C" DWORD WINAPI HttpExtensionProc(LPEXTENSION_CONTROL_BLOCK lpECB) else return WriteClientError(lpECB,"Server detected unexpected IIS error."); } - catch (SAMLException& e) { + catch (saml::SAMLException& e) { LogEvent(NULL, EVENTLOG_ERROR_TYPE, 2100, NULL, e.what()); return WriteClientError(lpECB,"Shibboleth Extension caught an exception, check Event Log for details."); } diff --git a/odbc_ccache/odbc-ccache.cpp b/odbc_ccache/odbc-ccache.cpp index 9f7ce9b..350bb27 100644 --- a/odbc_ccache/odbc-ccache.cpp +++ b/odbc_ccache/odbc-ccache.cpp @@ -169,7 +169,7 @@ ODBCBase::ODBCBase(const DOMElement* e) : m_root(e), m_bInitializedODBC(false) m_connstring=p_connstring; } else { - auto_ptr_char arg(e->getFirstChild()->getNodeValue()); + xmltooling::auto_ptr_char arg(e->getFirstChild()->getNodeValue()); m_connstring=arg.get(); p_connstring=m_connstring.c_str(); } @@ -832,7 +832,7 @@ public: ODBCReplayCache(const DOMElement* e); virtual ~ODBCReplayCache() {} - bool check(const XMLCh* str, time_t expires) {auto_ptr_XMLCh temp(str); return check(temp.get(),expires);} + bool check(const XMLCh* str, time_t expires) {xmltooling::auto_ptr_XMLCh temp(str); return check(temp.get(),expires);} bool check(const char* str, time_t expires); }; diff --git a/shib-target/shib-ccache.cpp b/shib-target/shib-ccache.cpp index c58fd78..e2cd92c 100644 --- a/shib-target/shib-ccache.cpp +++ b/shib-target/shib-ccache.cpp @@ -212,7 +212,7 @@ string StubCache::insert( in.structure(); in.addmember("application_id").string(application->getId()); in.addmember("client_address").string(client_addr); - auto_ptr_char provid(source->getId()); + xmltooling::auto_ptr_char provid(source->getId()); in.addmember("provider_id").string(provid.get()); in.addmember("major_version").integer(1); in.addmember("minor_version").integer(tokens->getMinorVersion()); @@ -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()); - auto_ptr_char pid(source->getId()); + xmltooling::auto_ptr_char pid(source->getId()); m_obj.addmember("provider_id").string(pid.get()); m_obj.addmember("major_version").integer(1); m_obj.addmember("minor_version").integer(tokens->getMinorVersion()); @@ -440,7 +440,7 @@ MemorySessionCacheEntry::MemorySessionCacheEntry( } // Transaction Logging - auto_ptr_char hname(subject->getNameIdentifier()->getName()); + xmltooling::auto_ptr_char hname(subject->getNameIdentifier()->getName()); STConfig& stc=static_cast(ShibTargetConfig::getConfig()); stc.getTransactionLog().infoStream() << "New session (ID: " << @@ -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()); - auto_ptr_char pid(source->getId()); + xmltooling::auto_ptr_char pid(source->getId()); m_obj.addmember("provider_id").string(pid.get()); m_obj.addmember("subject").string(subject); m_obj.addmember("authn_context").string(authnContext); @@ -877,7 +877,7 @@ pair MemorySessionCacheEntry::getNewResponse( // Get a binding object for this protocol. const SAMLBinding* binding = application->getBinding(ep->getBinding()); if (!binding) { - 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; } @@ -893,16 +893,6 @@ pair MemorySessionCacheEntry::getNewResponse( } catch (SAMLException& e) { m_log->error("caught SAML exception during SAML attribute query: %s", e.what()); - // Check for shib:InvalidHandle error and propagate it out. - Iterator codes=e.getCodes(); - if (codes.size()>1) { - const saml::QName& code=codes[1]; - if (!XMLString::compareString(code.getNamespaceURI(),shibboleth::Constants::SHIB_NS) && - !XMLString::compareString(code.getLocalName(), shibboleth::Constants::InvalidHandle)) { - codes.reset(); - throw InvalidHandleException(e.what(),saml::params(),codes); - } - } } } @@ -919,7 +909,7 @@ pair MemorySessionCacheEntry::getNewResponse( for (unsigned int a=0; agetId(),assertions[a]->getIssuer())) { - auto_ptr_char bad(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); continue; @@ -997,7 +987,7 @@ SAMLResponse* MemorySessionCacheEntry::filter( Iterator attrs=state ? state->getAttributes() : EMPTY(SAMLAttribute*); while (attrs.hasNext()) { SAMLAttribute* attr=attrs.next(); - auto_ptr_char attrname(attr->getName()); + xmltooling::auto_ptr_char attrname(attr->getName()); tran.infoStream() << "\t" << attrname.get() << " (" << attr->getValues().size() << " values)"; } } @@ -1241,7 +1231,7 @@ string MemorySessionCache::insert( #endif SAMLIdentifier id; - auto_ptr_char key(id); + xmltooling::auto_ptr_char key(id); if (m_log->isDebugEnabled()) m_log->debug("creating new cache entry for application %s: \"%s\"", application->getId(), key.get()); diff --git a/shib-target/shib-config.cpp b/shib-target/shib-config.cpp index 46b7624..263e216 100644 --- a/shib-target/shib-config.cpp +++ b/shib-target/shib-config.cpp @@ -23,8 +23,8 @@ */ #include "internal.h" -#include #include +#include #include #include @@ -104,11 +104,11 @@ bool STConfig::init(const char* schemadir) samlConf.getPlugMgr().regFactory(shibtarget::XML::XMLRequestMapType,&XMLRequestMapFactory); samlConf.getPlugMgr().regFactory(shibtarget::XML::NativeRequestMapType,&XMLRequestMapFactory); - auto_ptr_char temp1(Constants::SHIB_SESSIONINIT_PROFILE_URI); + auto_ptr_char temp1(shibspconstants::SHIB1_SESSIONINIT_PROFILE_URI); samlConf.getPlugMgr().regFactory(temp1.get(),&ShibSessionInitiatorFactory); samlConf.getPlugMgr().regFactory(samlconstants::SAML1_PROFILE_BROWSER_POST,&SAML1POSTFactory); samlConf.getPlugMgr().regFactory(samlconstants::SAML1_PROFILE_BROWSER_ARTIFACT,&SAML1ArtifactFactory); - auto_ptr_char temp4(Constants::SHIB_LOGOUT_PROFILE_URI); + auto_ptr_char temp4(shibspconstants::SHIB1_LOGOUT_PROFILE_URI); samlConf.getPlugMgr().regFactory(temp4.get(),&ShibLogoutFactory); saml::XML::registerSchema(shibtarget::XML::SHIBTARGET_NS,shibtarget::XML::SHIBTARGET_SCHEMA_ID,NULL,false); diff --git a/shib-target/shib-handlers.cpp b/shib-target/shib-handlers.cpp index c717d07..151ea29 100644 --- a/shib-target/shib-handlers.cpp +++ b/shib-target/shib-handlers.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #ifdef HAVE_UNISTD_H # include @@ -142,13 +143,13 @@ pair SessionInitiator::run(ShibTarget* st, bool isHandler) const const IEntityDescriptor* entity=m.lookup(option); if (!entity) throw MetadataException("Session initiator unable to locate metadata for provider ($1).", params(1,option)); - const IIDPSSODescriptor* role=entity->getIDPSSODescriptor(Constants::SHIB_NS); + const IIDPSSODescriptor* 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) ); const IEndpointManager* SSO=role->getSingleSignOnServiceManager(); - const IEndpoint* ep=SSO->getEndpointByBinding(Constants::SHIB_AUTHNREQUEST_PROFILE_URI); + const IEndpoint* ep=SSO->getEndpointByBinding(shibspconstants::SHIB1_AUTHNREQUEST_PROFILE_URI); if (!ep) throw MetadataException( "Session initiator unable to locate compatible SSO service for provider ($1).", params(1,option) @@ -173,12 +174,9 @@ pair SessionInitiator::run(ShibTarget* st, bool isHandler) const throw ConfigurationException("Session initiator is missing wayfURL property."); pair wayfBinding=getProperties()->getXMLString("wayfBinding"); - if (!wayfBinding.first || !XMLString::compareString(wayfBinding.second,Constants::SHIB_AUTHNREQUEST_PROFILE_URI)) + if (!wayfBinding.first || !XMLString::compareString(wayfBinding.second,shibspconstants::SHIB1_AUTHNREQUEST_PROFILE_URI)) // Standard Shib 1.x return ShibAuthnRequest(st,ACS,wayfURL.second,resource,app->getString("providerId").second); - else if (!XMLString::compareString(wayfBinding.second,Constants::SHIB_LEGACY_AUTHNREQUEST_PROFILE_URI)) - // Shib pre-1.2 - return ShibAuthnRequest(st,ACS,wayfURL.second,resource,NULL); else if (!strcmp(getProperties()->getString("wayfBinding").second,"urn:mace:shibboleth:1.0:profiles:EAuth")) { // TODO: Finalize E-Auth profile URI pair localRelayState=st->getConfig()->getPropertySet("InProcess")->getBool("localRelayState"); diff --git a/shib-target/shib-ini.cpp b/shib-target/shib-ini.cpp index f20bf92..3e7244b 100644 --- a/shib-target/shib-ini.cpp +++ b/shib-target/shib-ini.cpp @@ -24,6 +24,7 @@ #include #include +#include #include #include #include @@ -37,6 +38,9 @@ using namespace saml; using namespace log4cpp; using namespace std; +using xmltooling::TrustEngine; +using opensaml::saml2md::MetadataProvider; + namespace shibtarget { // Application configuration wrapper @@ -63,6 +67,10 @@ namespace shibtarget { Iterator getTrustProviders() const; Iterator getAudiences() const; const PropertySet* getCredentialUse(const IEntityDescriptor* 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;} @@ -92,6 +100,8 @@ namespace shibtarget { vector m_aaps; vector m_metadatas; vector m_trusts; + MetadataProvider* m_metadata; + TrustEngine* m_trust; vector m_audiences; ShibBrowserProfile* m_profile; SAMLBinding* m_binding; @@ -215,7 +225,7 @@ XMLApplication::XMLApplication( const Iterator& creds, const DOMElement* e, const XMLApplication* base - ) : m_ini(ini), m_base(base), m_profile(NULL), m_binding(NULL), m_bindingHook(NULL), + ) : m_ini(ini), m_base(base), m_metadata(NULL), m_trust(NULL), m_profile(NULL), m_binding(NULL), m_bindingHook(NULL), m_credDefault(NULL), m_sessionInitDefault(NULL), m_acsDefault(NULL) { #ifdef _DEBUG @@ -342,7 +352,7 @@ XMLApplication::XMLApplication( // A legacy config installs a SAML POST handler at the root handler location. // We use the Sessions element itself as the PropertySet. - auto_ptr_char b1(Constants::SHIB_SESSIONINIT_PROFILE_URI); + auto_ptr_char b1(shibspconstants::SHIB1_SESSIONINIT_PROFILE_URI); IPlugIn* hplug=shibConf.getPlugMgr().newPlugin(b1.get(),propcheck->getElement()); IHandler* h1=dynamic_cast(hplug); if (!h1) { @@ -452,6 +462,8 @@ XMLApplication::XMLApplication( } if (conf.isEnabled(SPConfig::Trust)) { + // First build the old plugins. + // TODO: remove this later nlist=e->getElementsByTagNameNS(shibtarget::XML::SHIBTARGET_NS,SHIBT_L(TrustProvider)); for (i=0; nlist && igetLength(); i++) { if (nlist->item(i)->getParentNode()->isSameNode(e)) { @@ -673,6 +685,16 @@ const PropertySet* XMLApplication::getCredentialUse(const IEntityDescriptor* pro 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 { #ifdef _DEBUG diff --git a/shib-target/shib-target.h b/shib-target/shib-target.h index c1c9fa4..1376fd8 100644 --- a/shib-target/shib-target.h +++ b/shib-target/shib-target.h @@ -27,8 +27,10 @@ // New headers #include +#include #include #include +#include // Old headers #include @@ -96,6 +98,9 @@ namespace shibtarget { 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; + // caller is borrowing object, must use within scope of config lock virtual const saml::SAMLBrowserProfile* getBrowserProfile() const=0; virtual const saml::SAMLBinding* getBinding(const XMLCh* binding) const=0; diff --git a/shib/Makefile.am b/shib/Makefile.am index 66aff7a..bac574f 100644 --- a/shib/Makefile.am +++ b/shib/Makefile.am @@ -10,7 +10,6 @@ noinst_HEADERS = internal.h libshib_la_SOURCES = \ BasicTrust.cpp \ - Constants.cpp \ Metadata.cpp \ ReloadableXMLFile.cpp \ ShibbolethTrust.cpp \ diff --git a/shib/shib.h b/shib/shib.h index 97e9994..8e93490 100644 --- a/shib/shib.h +++ b/shib/shib.h @@ -352,18 +352,6 @@ namespace shibboleth template class SHIB_EXPORTS saml::ArrayIterator; #endif - struct SHIB_EXPORTS Constants - { - static const XMLCh SHIB_ATTRIBUTE_NAMESPACE_URI[]; - static const XMLCh SHIB_NAMEID_FORMAT_URI[]; - static const XMLCh SHIB_AUTHNREQUEST_PROFILE_URI[]; - static const XMLCh SHIB_LEGACY_AUTHNREQUEST_PROFILE_URI[]; - static const XMLCh SHIB_SESSIONINIT_PROFILE_URI[]; - static const XMLCh SHIB_LOGOUT_PROFILE_URI[]; - static const XMLCh SHIB_NS[]; - static const XMLCh InvalidHandle[]; - }; - // Glue classes between abstract metadata and concrete providers class SHIB_EXPORTS Metadata diff --git a/shib/shib.vcproj b/shib/shib.vcproj index 2228474..29f7745 100644 --- a/shib/shib.vcproj +++ b/shib/shib.vcproj @@ -222,10 +222,6 @@ > - - diff --git a/shibsp/SPConstants.cpp b/shibsp/SPConstants.cpp new file mode 100644 index 0000000..5cafeae --- /dev/null +++ b/shibsp/SPConstants.cpp @@ -0,0 +1,73 @@ +/* + * 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. + */ + +/** + * SPConstants.cpp + * + * SP XML namespace constants + */ + +#include "internal.h" +#include "SPConstants.h" +#include + +using namespace shibspconstants; + +const XMLCh shibspconstants::SHIB1_PROTOCOL_ENUM[] = // urn:mace:shibboleth: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, + chDigit_1, chPeriod, chDigit_0, chNull +}; + +const XMLCh shibspconstants::SHIB1_ATTRIBUTE_NAMESPACE_URI[] = // urn:mace:shibboleth:1.0:attributeNamespace:uri +{ 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, + chDigit_1, chPeriod, chDigit_0, chColon, + chLatin_a, chLatin_t, chLatin_t, chLatin_r, chLatin_i, chLatin_b, chLatin_u, chLatin_t, chLatin_e, + chLatin_N, chLatin_a, chLatin_m, chLatin_e, chLatin_s, chLatin_p, chLatin_a, chLatin_c, chLatin_e, chColon, + chLatin_u, chLatin_r, chLatin_i, chNull +}; + +const XMLCh shibspconstants::SHIB1_NAMEID_FORMAT_URI[] = // urn:mace:shibboleth:1.0:nameIdentifier +{ 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, + chDigit_1, chPeriod, chDigit_0, chColon, + chLatin_n, chLatin_a, chLatin_m, chLatin_e, + chLatin_I, chLatin_d, chLatin_e, chLatin_n, chLatin_t, chLatin_i, chLatin_f, chLatin_i, chLatin_e, chLatin_r, chNull +}; + +const XMLCh shibspconstants::SHIB1_AUTHNREQUEST_PROFILE_URI[] = // urn:mace:shibboleth:1.0:profiles:AuthnRequest +{ 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, + chDigit_1, chPeriod, chDigit_0, chColon, + chLatin_p, chLatin_r, chLatin_o, chLatin_f, chLatin_i, chLatin_l, chLatin_e, chLatin_s, chColon, + chLatin_A, chLatin_u, chLatin_t, chLatin_h, chLatin_n, + chLatin_R, chLatin_e, chLatin_q, chLatin_u, chLatin_e, chLatin_s, chLatin_t, chNull +}; + +const XMLCh shibspconstants::SHIB1_SESSIONINIT_PROFILE_URI[] = // urn:mace:shibboleth:sp:1.3:SessionInit +{ 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_s, chLatin_p, chColon, chDigit_1, chPeriod, chDigit_3, chColon, + chLatin_S, chLatin_e, chLatin_s, chLatin_s, chLatin_i, chLatin_o, chLatin_n, chLatin_I, chLatin_n, chLatin_i, chLatin_t, chNull +}; + +const XMLCh shibspconstants::SHIB1_LOGOUT_PROFILE_URI[] = // urn:mace:shibboleth:sp:1.3:Logout +{ 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_s, chLatin_p, chColon, chDigit_1, chPeriod, chDigit_3, chColon, + chLatin_L, chLatin_o, chLatin_g, chLatin_o, chLatin_u, chLatin_t, chNull +}; diff --git a/shibsp/SPConstants.h b/shibsp/SPConstants.h new file mode 100644 index 0000000..16e9d9b --- /dev/null +++ b/shibsp/SPConstants.h @@ -0,0 +1,58 @@ +/* + * Copyright 2001-2006 Internet2 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file shibsp/SPConstants.h + * + * Shibboleth SP XML constants. + */ + +#ifndef __shibsp_constants_h__ +#define __shibsp_constants_h__ + +#include + +/** + * Shibboleth SP XML constants. + */ +namespace shibspconstants { + + /** Shibboleth Metadata XML namespace ("urn:mace:shibboleth:metadata:1.0") */ + extern SHIBSP_API const XMLCh SHIBMD_NS[]; + + /** Shibboleth Metadata QName prefix ("shibmd") */ + extern SHIBSP_API const XMLCh SHIBMD_PREFIX[]; + + /** Shibboleth 1.x Protocol Enumeration constant ("urn:mace:shibboleth:1.0") */ + extern SHIBSP_API const XMLCh SHIB1_PROTOCOL_ENUM[]; + + /** Shibboleth 1.x URI AttributeNamespace constant ("urn:mace:shibboleth:1.0:attributeNamespace:uri") */ + extern SHIBSP_API const XMLCh SHIB1_ATTRIBUTE_NAMESPACE_URI[]; + + /** Shibboleth 1.x transient NameIdentifier Format constant ("urn:mace:shibboleth:1.0:nameIdentifier") */ + extern SHIBSP_API const XMLCh SHIB1_NAMEID_FORMAT_URI[]; + + /** Shibboleth 1.x AuthnRequest binding/profile ("urn:mace:shibboleth:1.0:profiles:AuthnRequest") */ + extern SHIBSP_API const XMLCh SHIB1_AUTHNREQUEST_PROFILE_URI[]; + + /** Shibboleth 1.3 SessionInit binding/profile ("urn:mace:shibboleth:sp:1.3:SessionInit") */ + extern SHIBSP_API const XMLCh SHIB1_SESSIONINIT_PROFILE_URI[]; + + /** Shibboleth 1.3 Local Logout binding/profile ("urn:mace:shibboleth:sp:1.3:Logout") */ + extern SHIBSP_API const XMLCh SHIB1_LOGOUT_PROFILE_URI[]; +}; + +#endif /* __shibsp_constants_h__ */ diff --git a/shibsp/shibsp.vcproj b/shibsp/shibsp.vcproj index 8f2f75e..8d730e9 100644 --- a/shibsp/shibsp.vcproj +++ b/shibsp/shibsp.vcproj @@ -204,6 +204,10 @@ RelativePath=".\SPConfig.cpp" > + + + + diff --git a/test/shibtest.cpp b/test/shibtest.cpp index 1c8724f..918eaa4 100644 --- a/test/shibtest.cpp +++ b/test/shibtest.cpp @@ -21,6 +21,7 @@ #include #include +#include using namespace shibsp; using namespace shibtarget; @@ -97,7 +98,7 @@ int main(int argc,char* argv[]) new SAMLNameIdentifier( handle.get(), domain.get(), - format.get() ? format.get() : Constants::SHIB_NAMEID_FORMAT_URI + format.get() ? format.get() : shibspconstants::SHIB1_NAMEID_FORMAT_URI ) ), resource.get(), @@ -134,17 +135,7 @@ int main(int argc,char* argv[]) throw TrustException("unable to verify signed response"); response = r.release(); } - catch (SAMLException& e) { - // Check for shib:InvalidHandle error and propagate it out. - Iterator codes=e.getCodes(); - if (codes.size()>1) { - const saml::QName& code=codes[1]; - if (!XMLString::compareString(code.getNamespaceURI(),shibboleth::Constants::SHIB_NS) && - !XMLString::compareString(code.getLocalName(), shibboleth::Constants::InvalidHandle)) { - codes.reset(); - throw InvalidHandleException(e.what(),params(),codes); - } - } + catch (SAMLException&) { } } diff --git a/xmlproviders/Makefile.am b/xmlproviders/Makefile.am index 31dfe30..5dbf938 100644 --- a/xmlproviders/Makefile.am +++ b/xmlproviders/Makefile.am @@ -19,8 +19,7 @@ xmlproviders_la_SOURCES = \ XMLAccessControl.cpp \ XMLCredentials.cpp \ XMLMetadata.cpp \ - XMLProviders.cpp \ - XMLTrust.cpp + XMLProviders.cpp xmlproviders_la_LDFLAGS = -module -avoid-version diff --git a/xmlproviders/XMLAAP.cpp b/xmlproviders/XMLAAP.cpp index b7c1b93..5d29257 100644 --- a/xmlproviders/XMLAAP.cpp +++ b/xmlproviders/XMLAAP.cpp @@ -25,6 +25,7 @@ #include "internal.h" #include #include +#include using namespace shibboleth; using namespace saml; @@ -168,7 +169,7 @@ void XMLAAPImpl::init() AttributeRule* rule=new AttributeRule(static_cast(nlist->item(i))); #ifdef HAVE_GOOD_STL xstring key=rule->getName(); - key=key + chBang + chBang + (rule->getNamespace() ? rule->getNamespace() : Constants::SHIB_ATTRIBUTE_NAMESPACE_URI); + key=key + chBang + chBang + (rule->getNamespace() ? rule->getNamespace() : shibspconstants::SHIB1_ATTRIBUTE_NAMESPACE_URI); #else auto_ptr_char aname(rule->getName()); string key(aname.get()); @@ -231,7 +232,7 @@ XMLAAPImpl::AttributeRule::AttributeRule(const DOMElement* e) : m_name=e->getAttributeNS(NULL,SHIB_L(Name)); m_namespace=e->getAttributeNS(NULL,SHIB_L(Namespace)); if (!m_namespace || !*m_namespace) - m_namespace=Constants::SHIB_ATTRIBUTE_NAMESPACE_URI; + m_namespace=shibspconstants::SHIB1_ATTRIBUTE_NAMESPACE_URI; const XMLCh* caseSensitive=e->getAttributeNS(NULL,SHIB_L(CaseSensitive)); m_caseSensitive=(!caseSensitive || !*caseSensitive || *caseSensitive==chDigit_1 || *caseSensitive==chLatin_t); @@ -357,7 +358,7 @@ const IAttributeRule* XMLAAP::lookup(const XMLCh* attrName, const XMLCh* attrNam { #ifdef HAVE_GOOD_STL xstring key=attrName; - key=key + chBang + chBang + (attrNamespace ? attrNamespace : Constants::SHIB_ATTRIBUTE_NAMESPACE_URI); + key=key + chBang + chBang + (attrNamespace ? attrNamespace : shibspconstants::SHIB1_ATTRIBUTE_NAMESPACE_URI); #else auto_ptr_char aname(attrName); string key=aname.get(); diff --git a/xmlproviders/XMLMetadata.cpp b/xmlproviders/XMLMetadata.cpp index 9016456..093cc52 100644 --- a/xmlproviders/XMLMetadata.cpp +++ b/xmlproviders/XMLMetadata.cpp @@ -40,6 +40,8 @@ #include #include +#include + using namespace shibboleth; using namespace saml; using namespace log4cpp; @@ -737,7 +739,7 @@ XMLMetadataImpl::SSORole::SSORole(const EntityDescriptor* provider, time_t valid 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(shibboleth::Constants::SHIB_NAMEID_FORMAT_URI); + m_formats.push_back(shibspconstants::SHIB1_NAMEID_FORMAT_URI); } } @@ -798,14 +800,14 @@ XMLMetadataImpl::IDPRole::IDPRole(const EntityDescriptor* provider, time_t valid } } else { - m_protocolEnum.push_back(Constants::SHIB_NS); - m_attrprofs.push_back(Constants::SHIB_ATTRIBUTE_NAMESPACE_URI); + 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(Constants::SHIB_AUTHNREQUEST_PROFILE_URI,static_cast(nlist->item(i))->getAttributeNS(NULL,L(Location))) + 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. @@ -880,8 +882,8 @@ XMLMetadataImpl::AARole::AARole(const EntityDescriptor* provider, time_t validUn 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(Constants::SHIB_NAMEID_FORMAT_URI); - m_attrprofs.push_back(Constants::SHIB_ATTRIBUTE_NAMESPACE_URI); + 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++) { diff --git a/xmlproviders/XMLProviders.cpp b/xmlproviders/XMLProviders.cpp index e035624..28165e0 100644 --- a/xmlproviders/XMLProviders.cpp +++ b/xmlproviders/XMLProviders.cpp @@ -42,7 +42,6 @@ using namespace std; PlugManager::Factory TargetedIDFactory; PlugManager::Factory XMLMetadataFactory; -PlugManager::Factory XMLTrustFactory; PlugManager::Factory XMLCredentialsFactory; PlugManager::Factory XMLAAPFactory; PlugManager::Factory FileCredResolverFactory; @@ -53,7 +52,6 @@ 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::TRUST_NS,::XML::TRUST_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); @@ -64,8 +62,6 @@ extern "C" int XML_EXPORTS saml_extension_init(void*) 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.trust.provider.XMLTrust",&XMLTrustFactory); - conf.getPlugMgr().regFactory("edu.internet2.middleware.shibboleth.common.provider.XMLTrust",&XMLTrustFactory); 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); @@ -82,8 +78,6 @@ extern "C" void XML_EXPORTS saml_extension_term() 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.trust.provider.XMLTrust"); - conf.getPlugMgr().unregFactory("edu.internet2.middleware.shibboleth.common.provider.XMLTrust"); 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"); diff --git a/xmlproviders/XMLTrust.cpp b/xmlproviders/XMLTrust.cpp deleted file mode 100644 index ef697da..0000000 --- a/xmlproviders/XMLTrust.cpp +++ /dev/null @@ -1,779 +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. - */ - -/* XMLTrust.cpp - a trust implementation that uses an XML file - - Scott Cantor - 9/27/02 - - $History:$ -*/ - -#include "internal.h" - -#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 XMLTrustImpl : public ReloadableXMLFileImpl - { - public: - XMLTrustImpl(const char* pathname) : ReloadableXMLFileImpl(pathname), m_wildcard(NULL) { init(); } - XMLTrustImpl(const DOMElement* e) : ReloadableXMLFileImpl(e), m_wildcard(NULL) { init(); } - void init(); - ~XMLTrustImpl(); - - struct KeyAuthority - { - KeyAuthority() : m_depth(1) {} - ~KeyAuthority(); - X509_STORE* getX509Store(); - -#ifndef HAVE_GOOD_STL - vector m_subjects; -#endif - vector m_certs; - vector m_crls; - unsigned short m_depth; - }; - - vector m_keybinds; - vector m_keyauths; - KeyAuthority* m_wildcard; -#ifdef HAVE_GOOD_STL - typedef map AuthMap; - typedef map BindMap; - AuthMap m_authMap; - BindMap m_bindMap; -#endif - }; - - class XMLTrust : public ITrust, public ReloadableXMLFile - { - public: - XMLTrust(const DOMElement* e); - ~XMLTrust(); - - 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); - - protected: - virtual ReloadableXMLFileImpl* newImplementation(const char* pathname, bool first=true) const; - virtual ReloadableXMLFileImpl* newImplementation(const DOMElement* e, bool first=true) const; - - vector m_resolvers; - ITrust* m_delegate; - }; -} - -IPlugIn* XMLTrustFactory(const DOMElement* e) -{ - auto_ptr t(new XMLTrust(e)); - t->getImplementation(); - return t.release(); -} - - -ReloadableXMLFileImpl* XMLTrust::newImplementation(const char* pathname, bool first) const -{ - return new XMLTrustImpl(pathname); -} - -ReloadableXMLFileImpl* XMLTrust::newImplementation(const DOMElement* e, bool first) const -{ - return new XMLTrustImpl(e); -} - -X509_STORE* XMLTrustImpl::KeyAuthority::getX509Store() -{ -#ifdef _DEBUG - NDC ndc("getX509Store"); -#endif - Category& log=Category::getInstance(XMLPROVIDERS_LOGCAT".Trust"); - - // Load the cert vector into a store. - X509_STORE* store=X509_STORE_new(); - if (!store) { - log_openssl(); - return NULL; - } -#if (OPENSSL_VERSION_NUMBER >= 0x00907000L) - X509_STORE_set_flags(store,X509_V_FLAG_CRL_CHECK_ALL); -#endif - - for (vector::iterator j=m_certs.begin(); j!=m_certs.end(); j++) { - if (!X509_STORE_add_cert(store,*j)) { - log_openssl(); - log.warn("failed to add cert: %s", (*j)->name); - continue; - } - } - - for (vector::iterator k=m_crls.begin(); k!=m_crls.end(); k++) { - if (!X509_STORE_add_crl(store,*k)) { - log_openssl(); - log.warn("failed to add CRL"); - continue; - } - } - - return store; -} - -XMLTrustImpl::KeyAuthority::~KeyAuthority() -{ - for_each(m_certs.begin(),m_certs.end(),X509_free); - for_each(m_crls.begin(),m_crls.end(),X509_CRL_free); -} - -class KeyInfoNodeFilter : public DOMNodeFilter -{ -public: - short acceptNode(const DOMNode* node) const - { - // Our filter just skips any trees not rooted by ds:KeyInfo. - if (node->getNodeType()==DOMNode::ELEMENT_NODE) { - if (saml::XML::isElementNamed(static_cast(node),saml::XML::XMLSIG_NS,L(KeyInfo))) - return FILTER_ACCEPT; - } - return FILTER_REJECT; - } -}; - -void XMLTrustImpl::init() -{ -#ifdef _DEBUG - saml::NDC ndc("init"); -#endif - Category& log=Category::getInstance(XMLPROVIDERS_LOGCAT".Trust"); - - try { - if (!saml::XML::isElementNamed(m_root,::XML::TRUST_NS,SHIB_L(Trust))) { - log.error("Construction requires a valid trust file: (trust:Trust as root element)"); - throw TrustException("Construction requires a valid trust file: (trust:Trust as root element)"); - } - - // Loop over the KeyAuthority elements. - DOMNodeList* nlist=m_root->getElementsByTagNameNS(::XML::TRUST_NS,SHIB_L(KeyAuthority)); - for (unsigned int i=0; nlist && igetLength(); i++) { - auto_ptr ka(new KeyAuthority()); - - const DOMElement* e=static_cast(nlist->item(i)); - const XMLCh* depth=e->getAttributeNS(NULL,SHIB_L(VerifyDepth)); - if (depth && *depth) - ka->m_depth=XMLString::parseInt(depth); - - const DOMElement* k_child=saml::XML::getLastChildElement(e,saml::XML::XMLSIG_NS,L(KeyInfo)); - if (!k_child) { - log.error("ignoring KeyAuthority element with no ds:KeyInfo"); - continue; - } - const DOMElement* badkeyname=saml::XML::getFirstChildElement(k_child,saml::XML::XMLSIG_NS,SHIB_L(KeyName)); - if (badkeyname) { - log.error("ignoring KeyAuthority element with embedded ds:KeyName, these must appear only outside of ds:KeyInfo"); - continue; - } - - // Very rudimentary, grab up all the in-band X509Certificate elements, and flatten into one list. - DOMNodeList* certlist=k_child->getElementsByTagNameNS(saml::XML::XMLSIG_NS,L(X509Certificate)); - for (unsigned int j=0; certlist && jgetLength(); j++) { - auto_ptr_char blob(certlist->item(j)->getFirstChild()->getNodeValue()); - X509* x=B64_to_X509(blob.get()); - if (x) - ka->m_certs.push_back(x); - else - log.error("unable to create certificate from inline X509Certificate data"); - } - - // Now look for externally referenced objects. - certlist=k_child->getElementsByTagNameNS(saml::XML::XMLSIG_NS,SHIB_L(RetrievalMethod)); - for (unsigned int k=0; certlist && kgetLength(); k++) { - DOMElement* cert=static_cast(certlist->item(k)); - if (!XMLString::compareString(cert->getAttributeNS(NULL,SHIB_L(Type)),::XML::XMLSIG_RETMETHOD_RAWX509)) { - // DER format - auto_ptr_char fname(cert->getAttributeNS(NULL,SHIB_L(URI))); - FILE* f=fopen(fname.get(),"r"); - if (f) { - X509* x=NULL; - d2i_X509_fp(f,&x); - if (x) { - ka->m_certs.push_back(x); - continue; - } - else - log_openssl(); - } - log.error("unable to create certificate from externally referenced file"); - } - } - - // Very rudimentary, grab up all the in-band X509CRL elements, and flatten into one list. - certlist=k_child->getElementsByTagNameNS(saml::XML::XMLSIG_NS,SHIB_L(X509CRL)); - for (unsigned int r=0; certlist && rgetLength(); r++) { - auto_ptr_char blob(certlist->item(r)->getFirstChild()->getNodeValue()); - X509_CRL* x=B64_to_CRL(blob.get()); - if (x) - ka->m_crls.push_back(x); - else - log.warn("unable to create CRL from inline X509CRL data"); - } - - KeyAuthority* ka2=ka.release(); - m_keyauths.push_back(ka2); - - // Now map the ds:KeyName values to the list of certs. - bool wildcard=true; - DOMElement* sub=saml::XML::getFirstChildElement(e,saml::XML::XMLSIG_NS,SHIB_L(KeyName)); - while (sub) { - const XMLCh* name=sub->getFirstChild()->getNodeValue(); - if (name && *name) { - wildcard=false; -#ifdef HAVE_GOOD_STL - m_authMap[name]=ka2; -#else - ka2->m_subjects.push_back(name); -#endif - } - sub=saml::XML::getNextSiblingElement(sub,saml::XML::XMLSIG_NS,SHIB_L(KeyName)); - } - - // If no Subjects, this is a catch-all binding. - if (wildcard) { - if (!m_wildcard) { - log.warn("found a wildcard KeyAuthority element, make sure this is what you intend"); - m_wildcard=ka2; - } - else - log.warn("found multiple wildcard KeyAuthority elements, ignoring all but the first"); - } - } - - // Now traverse the outer ds:KeyInfo elements. Supposedly this cast just works... - int count=0; - KeyInfoNodeFilter filter; - XSECKeyInfoResolverDefault resolver; - DOMTreeWalker* walker= - static_cast(m_doc)->createTreeWalker(const_cast(m_root),DOMNodeFilter::SHOW_ELEMENT,&filter,false); - DOMElement* kidom=static_cast(walker->firstChild()); - while (kidom) { - count++; - DSIGKeyInfoList* KIL = 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... - try { - if (!KIL->loadListFromXML(kidom)) - log.error("skipping ds:KeyInfo element (%d) containing unsupported children",count); - } - catch (XSECCryptoException& xe) { - log.error("unable to process ds:KeyInfo element (%d): %s",count,xe.getMsg()); - } - - // Dry run...can we resolve to a key? - XSECCryptoKey* key=resolver.resolveKey(KIL); - if (key) { - // So far so good, now look for the name binding(s). - delete key; - bool named=false; - for (size_t index=0; indexgetSize(); index++) { - DSIGKeyInfo* info=KIL->item(index); - const XMLCh* name=info->getKeyName(); - if (name && *name) { - if (!named) - m_keybinds.push_back(KIL); - named=true; -#ifdef HAVE_GOOD_STL - m_bindMap[name]=KIL; -#endif - } - } - if (!named) { - log.warn("skipping ds:KeyInfo binding (%d) that does not contain a usable key name",count); - delete KIL; - } - } - else { - log.warn("skipping ds:KeyInfo binding (%d) that does not resolve to a key",count); - delete KIL; - } - kidom=static_cast(walker->nextSibling()); - } - walker->release(); // This just cleans up aggressively, but there's no leak if we don't. - } - catch (SAMLException& e) { - log.errorStream() << "Error while parsing trust configuration: " << e.what() << CategoryStream::ENDLINE; - this->~XMLTrustImpl(); - throw; - } -#ifndef _DEBUG - catch (...) { - log.error("Unexpected error while parsing trust configuration"); - this->~XMLTrustImpl(); - throw; - } -#endif -} - -XMLTrustImpl::~XMLTrustImpl() -{ - for_each(m_keyauths.begin(),m_keyauths.end(),xmltooling::cleanup()); - for_each(m_keybinds.begin(),m_keybinds.end(),xmltooling::cleanup()); -} - -XMLTrust::XMLTrust(const DOMElement* e) : ReloadableXMLFile(e), m_delegate(NULL) -{ - 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 }; - - Category& log=Category::getInstance(XMLPROVIDERS_LOGCAT".Trust"); - - // Find any KeyResolver plugins. - DOMElement* child=saml::XML::getFirstChildElement(e); - while (child) { - if (!XMLString::compareString(resolver,child->getLocalName()) && child->hasAttributeNS(NULL,_type)) { - try { - auto_ptr_char temp(child->getAttributeNS(NULL,_type)); - m_resolvers.push_back(KeyInfoResolver::getInstance(temp.get(),child)); - } - catch (SAMLException& ex) { - log.error("caught SAML exception building KeyInfoResolver plugin: %s",ex.what()); - } -#ifndef _DEBUG - catch (...) { - log.error("caught unknown exception building KeyInfoResolver plugin"); - } -#endif - } - child=saml::XML::getNextSiblingElement(child); - } - m_resolvers.push_back(KeyInfoResolver::getInstance(e)); - - try { - IPlugIn* plugin=SAMLConfig::getConfig().getPlugMgr().newPlugin( - "edu.internet2.middleware.shibboleth.common.provider.ShibbolethTrust",e - ); - m_delegate=dynamic_cast(plugin); - if (!m_delegate) { - delete plugin; - log.error("plugin was not a trust provider"); - throw UnsupportedExtensionException("Legacy trust provider requires Shibboleth trust provider in order to function."); - } - } - catch (SAMLException& ex) { - log.error("caught SAML exception building embedded trust provider: %s", ex.what()); - throw; - } -} - -XMLTrust::~XMLTrust() -{ - delete m_delegate; - for_each(m_resolvers.begin(),m_resolvers.end(),xmltooling::cleanup()); -} - -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 XMLTrust::validate(void* certEE, const Iterator& certChain, const IRoleDescriptor* role, bool checkName) -{ - // The delegated trust plugin handles path validation with metadata extensions. - // We only take over if the legacy format has to kick in. - if (m_delegate->validate(certEE,certChain,role,checkName)) - return true; - -#ifdef _DEBUG - saml::NDC ndc("validate"); -#endif - Category& log=Category::getInstance(XMLPROVIDERS_LOGCAT".Trust"); - - 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 (!strncasecmp(altptr,n->c_str(),altlen)) { -#else - if (!_strnicmp(altptr,n->c_str(),altlen)) { -#endif - 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; - } - - lock(); - try { - XMLTrustImpl* impl=dynamic_cast(getImplementation()); - - // Build a list of the names to match. We include any named KeyDescriptors, and the provider ID and its groups. - vector names; - Iterator kdlist=role->getKeyDescriptors(); - while (kdlist.hasNext()) { - const IKeyDescriptor* kd=kdlist.next(); - if (kd->getUse()==IKeyDescriptor::encryption) - continue; - DSIGKeyInfoList* kilist=kd->getKeyInfo(); - for (size_t s=0; kilist && sgetSize(); s++) { - const XMLCh* n=kilist->item(s)->getKeyName(); - if (n) - names.push_back(n); - } - } - names.push_back(role->getEntityDescriptor()->getId()); - const IEntitiesDescriptor* group=role->getEntityDescriptor()->getEntitiesDescriptor(); - while (group) { - if (group->getName()) - names.push_back(group->getName()); - group=group->getEntitiesDescriptor(); - } - - // Now check each name. - XMLTrustImpl::KeyAuthority* kauth=NULL; - for (vector::const_iterator name=names.begin(); !kauth && name!=names.end(); name++) { -#ifdef HAVE_GOOD_STL - XMLTrustImpl::AuthMap::const_iterator c=impl->m_authMap.find(*name); - if (c!=impl->m_authMap.end()) { - kauth=c->second; - if (log.isInfoEnabled()) { - auto_ptr_char temp(*name); - log.info("KeyAuthority match on %s",temp.get()); - } - } -#else - // Without a decent STL, we trade-off the transcoding by doing a linear search. - for (vector::const_iterator keyauths=impl->m_keyauths.begin(); !kauth && keyauths!=impl->m_keyauths.end(); keyauths++) { - for (vector::const_iterator subs=(*keyauths)->m_subjects.begin(); !kauth && subs!=(*keyauths)->m_subjects.end(); subs++) { - if (!XMLString::compareString(*name,*subs)) { - kauth=*keyauths; - if (log.isInfoEnabled()) { - auto_ptr_char temp(*name); - log.info("KeyAuthority match on %s",temp.get()); - } - } - } - } -#endif - } - - if (!kauth) { - if (impl->m_wildcard) { - log.warn("applying wildcard KeyAuthority, use with caution!"); - kauth=impl->m_wildcard; - } - else { - unlock(); - log.warn("no KeyAuthority found to validate SSL connection, leaving it alone"); - return false; - } - } - - log.debug("performing certificate path validation..."); - - // If we have a match, use the associated keyauth. - X509_STORE* store=kauth->getX509Store(); - if (store) { - STACK_OF(X509)* untrusted=sk_X509_new_null(); - certChain.reset(); - while (certChain.hasNext()) - sk_X509_push(untrusted,(X509*)certChain.next()); - - // This contains the state of the validate operation. - X509_STORE_CTX ctx; - - // 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,(X509*)certEE,untrusted)!=1) { - log_openssl(); - log.error("unable to initialize X509_STORE_CTX"); - X509_STORE_free(store); - sk_X509_free(untrusted); - unlock(); - return false; - } -#else - X509_STORE_CTX_init(&ctx,store,(X509*)certEE,untrusted); -#endif - X509_STORE_CTX_set_depth(&ctx,100); // handle depth 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 (kauth->m_depth < depth) { - log.error( - "certificate chain was too long (%d intermediates, only %d allowed)", - (depth==-1) ? 0 : depth, - kauth->m_depth - ); - ret=0; - } - } - - // Clean up... - X509_STORE_CTX_cleanup(&ctx); - X509_STORE_free(store); - - if (ret==1) { - log.info("successfully validated certificate chain"); - unlock(); - return true; - } - } - } - catch (...) { - unlock(); - throw; - } - unlock(); - return false; -} - -bool XMLTrust::validate(const saml::SAMLSignedObject& token, const IRoleDescriptor* role, ITrust* certValidator) -{ - // The delegated trust plugin handles metadata keys and use of metadata extensions. - // If it fails to find an inline key in metadata, then it will branch off to the - // extended version and verify the token using the certificates inside it. At that - // point, control will pass to the other virtual function above and we can handle - // legacy KeyAuthority rules that way. - if (m_delegate->validate(token,role,certValidator ? certValidator : this)) - return true; - -#ifdef _DEBUG - saml::NDC ndc("validate"); -#endif - Category& log=Category::getInstance(XMLPROVIDERS_LOGCAT".Trust"); - - lock(); - try { - XMLTrustImpl* impl=dynamic_cast(getImplementation()); - - // If we actually make it this far, the only case we're handling directly - // is an inline key in the old trust file format. Build a list of key names - // which will be used to find matching rules. - vector names; - - // 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) - names.push_back(n); - } - } - names.push_back(role->getEntityDescriptor()->getId()); - - log.debug("checking for keys in trust file"); - DSIGKeyInfoList* KIL=NULL; - for (vector::const_iterator name=names.begin(); !KIL && name!=names.end(); name++) { -#ifdef HAVE_GOOD_STL - XMLTrustImpl::BindMap::const_iterator c=impl->m_bindMap.find(*name); - if (c!=impl->m_bindMap.end()) { - KIL=c->second; - if (log.isInfoEnabled()) { - auto_ptr_char temp(*name); - log.info("KeyInfo match on %s",temp.get()); - } - } -#else - // Without a decent STL, we trade-off the transcoding by doing a linear search. - for (vector::const_iterator keybinds=impl->m_keybinds.begin(); !KIL && keybinds!=impl->m_keybinds.end(); keybinds++) { - for (size_t s=0; !KIL && s<(*keybinds)->getSize(); s++) { - if (!XMLString::compareString(*name,(*keybinds)->item(s)->getKeyName())) { - KIL=*keybinds; - if (log.isInfoEnabled()) { - auto_ptr_char temp(*name); - log.info("KeyInfo match on %s",temp.get()); - } - } - } - } -#endif - } - - if (KIL) { - // Any inline KeyInfo should ostensibly resolve to a key we can try. - Iterator resolvers(m_resolvers); - while (resolvers.hasNext()) { - XSECCryptoKey* key=((XSECKeyInfoResolver*)*resolvers.next())->resolveKey(KIL); - if (key) { - log.debug("resolved key, trying it..."); - try { - token.verify(key); - unlock(); - log.info("token verified with KeyInfo, nothing more to verify"); - return true; - } - catch (SAMLException& e) { - unlock(); - log.warn("verification with inline key failed: %s", e.what()); - return false; - } - } - } - log.warn("KeyInfo in trust provider did not resolve to a key"); - } - } - catch (...) { - unlock(); - throw; - } - - unlock(); - return false; -} diff --git a/xmlproviders/xmlproviders.vcproj b/xmlproviders/xmlproviders.vcproj index 0f37a8a..4b37757 100644 --- a/xmlproviders/xmlproviders.vcproj +++ b/xmlproviders/xmlproviders.vcproj @@ -259,10 +259,6 @@ RelativePath="xmlproviders.rc" > - - -- 2.1.4