From 358a40f43679ba10cfd5a0b227a013b445de439a Mon Sep 17 00:00:00 2001 From: cantor Date: Tue, 2 Jan 2007 19:17:24 +0000 Subject: [PATCH] Switched to xmltooling cred resolver. git-svn-id: https://svn.middleware.georgetown.edu/cpp-sp/trunk@2107 cb58f699-b61c-0410-a6fe-9272a202ed29 --- shib-target/ArtifactMapper.cpp | 7 +- shib-target/ShibHTTPHook.cpp | 10 +- shib-target/XMLRequestMapper.cpp | 1 - shib-target/internal.h | 2 + shib-target/shib-ccache.cpp | 9 +- shib-target/shib-config.cpp | 1 - shib-target/shib-handlers.cpp | 1 - shib-target/shib-ini.cpp | 1 - shib/Metadata.cpp | 5 +- shib/shib.h | 15 +- xmlproviders/CredResolvers.cpp | 591 -------------------------------------- xmlproviders/Makefile.am | 1 - xmlproviders/XML.cpp | 46 --- xmlproviders/XMLAAP.cpp | 1 - xmlproviders/XMLAccessControl.cpp | 2 +- xmlproviders/XMLCredentials.cpp | 96 +++---- xmlproviders/XMLProviders.cpp | 20 -- xmlproviders/internal.h | 18 +- xmlproviders/xmlproviders.vcproj | 4 - 19 files changed, 67 insertions(+), 764 deletions(-) delete mode 100644 xmlproviders/CredResolvers.cpp diff --git a/shib-target/ArtifactMapper.cpp b/shib-target/ArtifactMapper.cpp index a38f896..9f43e44 100644 --- a/shib-target/ArtifactMapper.cpp +++ b/shib-target/ArtifactMapper.cpp @@ -32,6 +32,7 @@ using namespace opensaml::saml2md; using namespace xmltooling; using namespace log4cpp; using namespace std; +using xmlsignature::CredentialResolver; SAMLResponse* STArtifactMapper::resolve(SAMLRequest* request) { @@ -68,9 +69,11 @@ SAMLResponse* STArtifactMapper::resolve(SAMLRequest* request) if (signRequest.first && signRequest.second && signingCred.first) { if (request->getMinorVersion()==1) { shibboleth::Credentials creds(ShibTargetConfig::getConfig().getINI()->getCredentialsProviders()); - const shibboleth::ICredResolver* cr=creds.lookup(signingCred.second); - if (cr) + CredentialResolver* cr=creds.lookup(signingCred.second); + if (cr) { + xmltooling::Locker locker(cr); request->sign(cr->getKey(),cr->getCertificates(),signatureAlg.second,digestAlg.second); + } else log.error("unable to sign artifact request, specified credential (%s) was not found",signingCred.second); } diff --git a/shib-target/ShibHTTPHook.cpp b/shib-target/ShibHTTPHook.cpp index ba52da5..002a65d 100644 --- a/shib-target/ShibHTTPHook.cpp +++ b/shib-target/ShibHTTPHook.cpp @@ -25,6 +25,7 @@ #include "internal.h" #include +#include #include #include @@ -37,6 +38,7 @@ using namespace saml; using namespace xmltooling; using namespace log4cpp; using namespace std; +using xmlsignature::OpenSSLCredentialResolver; /* * Our verifier callback is a front-end for invoking each trust plugin until @@ -85,9 +87,11 @@ static bool ssl_ctx_callback(void* ssl_ctx, void* userptr) pair TLS=credUse ? credUse->getString("TLS") : pair(false,NULL); if (TLS.first) { Credentials c(ctx->getHook()->getCredentialProviders()); - const ICredResolver* cr=c.lookup(TLS.second); - if (cr) - cr->attach(ssl_ctx); + OpenSSLCredentialResolver* cr=dynamic_cast(c.lookup(TLS.second)); + if (cr) { + xmltooling::Locker locker(cr); + cr->attach(reinterpret_cast(ssl_ctx)); + } else log.error("unable to attach credentials to request using (%s), leaving anonymous",TLS.second); } diff --git a/shib-target/XMLRequestMapper.cpp b/shib-target/XMLRequestMapper.cpp index b59bd4b..a356283 100644 --- a/shib-target/XMLRequestMapper.cpp +++ b/shib-target/XMLRequestMapper.cpp @@ -25,7 +25,6 @@ #include "internal.h" #include -#include #include using namespace shibsp; diff --git a/shib-target/internal.h b/shib-target/internal.h index 65f7fb1..607429b 100644 --- a/shib-target/internal.h +++ b/shib-target/internal.h @@ -49,8 +49,10 @@ #include #include #include +#include #include + #define SHIBT_L(s) shibtarget::XML::Literals::s #define SHIBT_L_QNAME(p,s) shibtarget::XML::Literals::p##_##s #define SHIBT_LOGCAT "shibtarget" diff --git a/shib-target/shib-ccache.cpp b/shib-target/shib-ccache.cpp index 26d6e10..484c48d 100644 --- a/shib-target/shib-ccache.cpp +++ b/shib-target/shib-ccache.cpp @@ -30,9 +30,7 @@ #include #include #include -#include #include -#include #ifdef HAVE_LIBDMALLOCXX #include @@ -45,6 +43,7 @@ using namespace opensaml::saml2md; using namespace xmltooling; using namespace log4cpp; using namespace std; +using xmlsignature::CredentialResolver; static const XMLCh cleanupInterval[] = { chLatin_c, chLatin_l, chLatin_e, chLatin_a, chLatin_n, chLatin_u, chLatin_p, @@ -866,9 +865,11 @@ pair MemorySessionCacheEntry::getNewResponse( if (signRequest.first && signRequest.second && signingCred.first) { if (req->getMinorVersion()==1) { shibboleth::Credentials creds(ShibTargetConfig::getConfig().getINI()->getCredentialsProviders()); - const shibboleth::ICredResolver* cr=creds.lookup(signingCred.second); - if (cr) + CredentialResolver* cr=creds.lookup(signingCred.second); + if (cr) { + xmltooling::Locker locker(cr); req->sign(cr->getKey(),cr->getCertificates(),signatureAlg.second,digestAlg.second); + } else m_log->error("unable to sign attribute query, specified credential (%s) was not found",signingCred.second); } diff --git a/shib-target/shib-config.cpp b/shib-target/shib-config.cpp index 80360b6..a267b1b 100644 --- a/shib-target/shib-config.cpp +++ b/shib-target/shib-config.cpp @@ -26,7 +26,6 @@ #include #include #include -#include #include diff --git a/shib-target/shib-handlers.cpp b/shib-target/shib-handlers.cpp index b6e3187..1ac8ea9 100644 --- a/shib-target/shib-handlers.cpp +++ b/shib-target/shib-handlers.cpp @@ -31,7 +31,6 @@ #include #include #include -#include #ifdef HAVE_UNISTD_H # include diff --git a/shib-target/shib-ini.cpp b/shib-target/shib-ini.cpp index eaf3dbf..eea2215 100644 --- a/shib-target/shib-ini.cpp +++ b/shib-target/shib-ini.cpp @@ -35,7 +35,6 @@ #include #include #include -#include using namespace shibsp; using namespace shibtarget; diff --git a/shib/Metadata.cpp b/shib/Metadata.cpp index c444ef1..a87e782 100644 --- a/shib/Metadata.cpp +++ b/shib/Metadata.cpp @@ -29,14 +29,15 @@ using namespace shibboleth; using namespace opensaml::saml2md; using namespace saml; using namespace std; +using xmlsignature::CredentialResolver; -const ICredResolver* Credentials::lookup(const char* id) +CredentialResolver* Credentials::lookup(const char* id) { if (m_mapper) { m_mapper->unlock(); m_mapper=NULL; } - const ICredResolver* ret=NULL; + CredentialResolver* ret=NULL; m_creds.reset(); while (m_creds.hasNext()) { m_mapper=m_creds.next(); diff --git a/shib/shib.h b/shib/shib.h index 5a917b4..d07f4f8 100644 --- a/shib/shib.h +++ b/shib/shib.h @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -45,19 +46,9 @@ namespace shibboleth { // Credentials interface abstracts access to "owned" keys and certificates. - struct SHIB_EXPORTS ICredResolver : public virtual saml::IPlugIn - { - virtual void attach(void* ctx) const=0; - virtual XSECCryptoKey* getKey() const=0; - virtual saml::Iterator getCertificates() const=0; - virtual void dump(FILE* f) const=0; - virtual void dump() const { dump(stdout); } - virtual ~ICredResolver() {} - }; - struct SHIB_EXPORTS ICredentials : public virtual saml::ILockable, public virtual saml::IPlugIn { - virtual const ICredResolver* lookup(const char* id) const=0; + virtual xmlsignature::CredentialResolver* lookup(const char* id) const=0; virtual ~ICredentials() {} }; @@ -102,7 +93,7 @@ namespace shibboleth Credentials(const saml::Iterator& creds) : m_creds(creds), m_mapper(NULL) {} ~Credentials(); - const ICredResolver* lookup(const char* id); + xmlsignature::CredentialResolver* lookup(const char* id); private: Credentials(const Credentials&); diff --git a/xmlproviders/CredResolvers.cpp b/xmlproviders/CredResolvers.cpp deleted file mode 100644 index 2c98ded..0000000 --- a/xmlproviders/CredResolvers.cpp +++ /dev/null @@ -1,591 +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. - */ - -/* CredResolvers.cpp - implementations of the ICredResolver interface - - Scott Cantor - 9/27/02 - - $History:$ -*/ - -#include "internal.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace shibboleth; -using namespace xmltooling; -using namespace log4cpp; -using namespace std; - -// OpenSSL password callback... -static int passwd_callback(char* buf, int len, int verify, void* passwd) -{ - if(!verify) - { - if(passwd && len > strlen(reinterpret_cast(passwd))) - { - strcpy(buf,reinterpret_cast(passwd)); - return strlen(buf); - } - } - return 0; -} - -// File-based resolver - -class FileResolver : public ICredResolver -{ -public: - FileResolver(const DOMElement* e); - ~FileResolver(); - virtual void attach(void* ctx) const; - virtual XSECCryptoKey* getKey() const; - virtual saml::Iterator getCertificates() const { return m_xseccerts; } - virtual void dump(FILE* f) const; - -private: - enum format_t { PEM=SSL_FILETYPE_PEM, DER=SSL_FILETYPE_ASN1, _PKCS12, UNKNOWN }; - - format_t getEncodingFormat(BIO* in) const; - string formatToString(format_t format) const; - format_t xmlFormatToFormat(const XMLCh* format_xml) const; - - format_t m_keyformat; - string m_keypath,m_keypass; - vector m_certs; - vector m_xseccerts; -}; - -saml::IPlugIn* FileCredResolverFactory(const DOMElement* e) -{ - return new FileResolver(e); -} - -FileResolver::FileResolver(const DOMElement* e) -{ -#ifdef _DEBUG - xmltooling::NDC ndc("FileResolver"); -#endif - Category& log=Category::getInstance(XMLPROVIDERS_LOGCAT".CredResolvers"); - - format_t format; - BIO* in = NULL; - - // Move to Key - const DOMElement* root=e; - e=saml::XML::getFirstChildElement(root,::XML::CREDS_NS,SHIB_L(Key)); - if (e) { - - // Get raw format attrib value, but defer processing til later since may need to - // determine format dynamically, and we need the Path for that. - const XMLCh* format_xml=e->getAttributeNS(NULL,SHIB_L(format)); - - const XMLCh* password=e->getAttributeNS(NULL,SHIB_L(password)); - if (password) { - auto_ptr_char kp(password); - m_keypass=kp.get(); - } - - e=saml::XML::getFirstChildElement(e,::XML::CREDS_NS,SHIB_L(Path)); - if (e && e->hasChildNodes()) { - const XMLCh* s=e->getFirstChild()->getNodeValue(); - auto_ptr_char kpath(s); -#ifdef WIN32 - struct _stat stat_buf; - if (_stat(kpath.get(), &stat_buf) != 0) -#else - struct stat stat_buf; - if (stat(kpath.get(), &stat_buf) != 0) -#endif - { - log.error("key file (%s) can't be opened", 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 IOException("FileResolver can't access key file, no Path element specified."); - } - - // Determine the key encoding format dynamically, if not explicitly specified - try { - if (format_xml && *format_xml) { - format = xmlFormatToFormat(format_xml); - if (format != UNKNOWN) { - m_keyformat = format; - } - else { - auto_ptr_char unknown(format_xml); - log.error("Configuration specifies unknown key encoding format (%s)", unknown.get()); - throw IOException("FileResolver configuration contains unknown key encoding format ($1)",params(1,unknown.get())); - } - } - else { - in=BIO_new(BIO_s_file_internal()); - if (in && BIO_read_filename(in,m_keypath.c_str())>0) { - m_keyformat = getEncodingFormat(in); - log.debug("Key encoding format for (%s) dynamically resolved as (%s)", m_keypath.c_str(), formatToString(m_keyformat).c_str()); - } - else { - log.error("Key file (%s) can't be read to determine encoding format", 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); - in = NULL; - } - } - catch (...) { - log.error("Error determining key encoding format"); - throw; - } - - } - - // Check for Certificate - e=saml::XML::getFirstChildElement(root,::XML::CREDS_NS,SHIB_L(Certificate)); - if (!e) - return; - auto_ptr_char certpass(e->getAttributeNS(NULL,SHIB_L(password))); - - 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 IOException("FileResolver can't access certificate file, missing Path element."); - } - - auto_ptr_char certpath(ep->getFirstChild()->getNodeValue()); - const XMLCh* format_xml=e->getAttributeNS(NULL,SHIB_L(format)); - if (format_xml && *format_xml) { - format = xmlFormatToFormat(format_xml); - if (format == UNKNOWN) { - auto_ptr_char unknown(format_xml); - log.error("Configuration specifies unknown certificate encoding format (%s)", unknown.get()); - throw IOException("FileResolver configuration contains unknown certificate encoding format ($1)",params(1,unknown.get())); - } - } - - try { - X509* x=NULL; - PKCS12* p12=NULL; - in=BIO_new(BIO_s_file_internal()); - if (in && BIO_read_filename(in,certpath.get())>0) { - if (!format_xml || !*format_xml) { - // Determine the cert encoding format dynamically, if not explicitly specified - format = getEncodingFormat(in); - log.debug("Cert encoding format for (%s) dynamically resolved as (%s)", certpath.get(), formatToString(format).c_str()); - } - - switch(format) { - case PEM: - while (x=PEM_read_bio_X509(in,NULL,passwd_callback,const_cast(certpass.get()))) { - m_certs.push_back(x); - } - break; - - case DER: - x=d2i_X509_bio(in,NULL); - if (x) - m_certs.push_back(x); - else { - log_openssl(); - BIO_free(in); - throw IOException("FileResolver unable to load DER certificate from file ($1)",params(1,certpath.get())); - } - break; - - case _PKCS12: - p12=d2i_PKCS12_bio(in,NULL); - if (p12) { - PKCS12_parse(p12, certpass.get(), NULL, &x, NULL); - PKCS12_free(p12); - } - if (x) { - m_certs.push_back(x); - x=NULL; - } else { - log_openssl(); - BIO_free(in); - throw IOException("FileResolver unable to load PKCS12 certificate from file ($1)",params(1,certpath.get())); - } - break; - } // end switch - - } else { - log_openssl(); - if (in) { - BIO_free(in); - in=NULL; - } - throw IOException("FileResolver unable to load certificate(s) from file ($1)",params(1,certpath.get())); - } - if (in) { - BIO_free(in); - in=NULL; - } - - if (m_certs.empty()) { - throw IOException("FileResolver unable to load any certificate(s)"); - } - - // Load any extra CA files. - DOMNodeList* nlist=e->getElementsByTagNameNS(::XML::CREDS_NS,SHIB_L(CAPath)); - for (unsigned int i=0; nlist && igetLength(); i++) { - if (!nlist->item(i)->hasChildNodes()) - continue; - auto_ptr_char capath(static_cast(nlist->item(i))->getFirstChild()->getNodeValue()); - x=NULL; - p12=NULL; - in=BIO_new(BIO_s_file_internal()); - if (in && BIO_read_filename(in,capath.get())>0) { - if (!format_xml || !*format_xml) { - // Determine the cert encoding format dynamically, if not explicitly specified - format = getEncodingFormat(in); - log.debug("Cert encoding format for (%s) dynamically resolved as (%s)", certpath.get(), formatToString(format).c_str()); - } - - switch (format) - { - case PEM: - while (x=PEM_read_bio_X509(in,NULL,passwd_callback,const_cast(certpass.get()))) { - m_certs.push_back(x); - } - break; - - case DER: - x=d2i_X509_bio(in,NULL); - if (x) - m_certs.push_back(x); - else { - log_openssl(); - BIO_free(in); - throw IOException("FileResolver unable to load DER CA certificate from file ($1)",params(1,capath.get())); - } - break; - - case _PKCS12: - p12 = d2i_PKCS12_bio(in, NULL); - if (p12) { - PKCS12_parse(p12, certpass.get(), NULL, &x, NULL); - PKCS12_free(p12); - } - if (x) { - m_certs.push_back(x); - x=NULL; - } else { - log_openssl(); - BIO_free(in); - throw IOException("FileResolver unable to load PKCS12 CA certificate from file ($1)",params(1,capath.get())); - } - break; - } //end switch - - BIO_free(in); - - } else { - if (in) - BIO_free(in); - log_openssl(); - log.error("CA file (%s) can't be opened", capath.get()); - throw IOException("FileResolver can't open CA file ($1)",params(1,capath.get())); - } - } - } - catch (...) { - for (vector::iterator j=m_certs.begin(); j!=m_certs.end(); j++) - X509_free(*j); - throw; - } - - // Reflect certs over to XSEC form. - for (vector::iterator j=m_certs.begin(); j!=m_certs.end(); j++) - m_xseccerts.push_back(new OpenSSLCryptoX509(*j)); -} - -FileResolver::~FileResolver() -{ - for_each(m_certs.begin(),m_certs.end(),X509_free); - for_each(m_xseccerts.begin(),m_xseccerts.end(),xmltooling::cleanup()); -} - -void FileResolver::attach(void* ctx) const -{ -#ifdef _DEBUG - saml::NDC ndc("attach"); -#endif - - SSL_CTX* ssl_ctx=reinterpret_cast(ctx); - - // Attach key. - SSL_CTX_set_default_passwd_cb(ssl_ctx, passwd_callback); - SSL_CTX_set_default_passwd_cb_userdata(ssl_ctx, const_cast(m_keypass.c_str())); - - int ret=0; - switch (m_keyformat) { - case PEM: - ret=SSL_CTX_use_PrivateKey_file(ssl_ctx, m_keypath.c_str(), m_keyformat); - break; - - case DER: - ret=SSL_CTX_use_RSAPrivateKey_file(ssl_ctx, m_keypath.c_str(), m_keyformat); - break; - - default: { - BIO* in=BIO_new(BIO_s_file_internal()); - if (in && BIO_read_filename(in,m_keypath.c_str())>0) { - EVP_PKEY* pkey=NULL; - PKCS12* p12 = d2i_PKCS12_bio(in, NULL); - if (p12) { - PKCS12_parse(p12, const_cast(m_keypass.c_str()), &pkey, NULL, NULL); - PKCS12_free(p12); - if (pkey) { - ret=SSL_CTX_use_PrivateKey(ssl_ctx, pkey); - EVP_PKEY_free(pkey); - } - } - } - if (in) - BIO_free(in); - } - } - - if (ret!=1) { - log_openssl(); - throw IOException("Unable to attach private key to SSL context"); - } - - // Attach certs. - for (vector::const_iterator i=m_certs.begin(); i!=m_certs.end(); i++) { - if (i==m_certs.begin()) { - if (SSL_CTX_use_certificate(ssl_ctx, *i) != 1) { - log_openssl(); - throw IOException("Unable to attach SP client certificate to SSL context"); - } - } - else { - // When we add certs, they don't get ref counted, so we need to duplicate them. - X509* dup = X509_dup(*i); - if (SSL_CTX_add_extra_chain_cert(ssl_ctx, dup) != 1) { - X509_free(dup); - log_openssl(); - throw IOException("Unable to attach CA certificate to SSL context"); - } - } - } -} - -XSECCryptoKey* FileResolver::getKey() const -{ -#ifdef _DEBUG - saml::NDC ndc("getKey"); -#endif - - // Get a EVP_PKEY. - EVP_PKEY* pkey=NULL; - BIO* in=BIO_new(BIO_s_file_internal()); - if (in && BIO_read_filename(in,m_keypath.c_str())>0) { - switch (m_keyformat) { - case PEM: - pkey=PEM_read_bio_PrivateKey(in, NULL, passwd_callback, const_cast(m_keypass.c_str())); - break; - - case DER: - pkey=d2i_PrivateKey_bio(in, NULL); - break; - - default: { - PKCS12* p12 = d2i_PKCS12_bio(in, NULL); - if (p12) { - PKCS12_parse(p12, const_cast(m_keypass.c_str()), &pkey, NULL, NULL); - PKCS12_free(p12); - } - } - } - } - if (in) - BIO_free(in); - - // Now map it to an XSEC wrapper. - if (pkey) { - XSECCryptoKey* ret=NULL; - switch (pkey->type) { - case EVP_PKEY_RSA: - ret=new OpenSSLCryptoKeyRSA(pkey); - break; - - case EVP_PKEY_DSA: - ret=new OpenSSLCryptoKeyDSA(pkey); - break; - - default: - Category::getInstance(XMLPROVIDERS_LOGCAT".CredResolvers").error("unsupported private key type"); - } - EVP_PKEY_free(pkey); - if (ret) - return ret; - } - - log_openssl(); - Category::getInstance(XMLPROVIDERS_LOGCAT".CredResolvers").error("FileResolver unable to load private key from file"); - return NULL; -} - -void FileResolver::dump(FILE* f) const -{ - // Dump private key. - RSA* rsa=NULL; - BIO* in=BIO_new(BIO_s_file_internal()); - if (in && BIO_read_filename(in,m_keypath.c_str())>0) { - if (m_keyformat==DER) - rsa=d2i_RSAPrivateKey_bio(in,NULL); - else if (m_keyformat==PEM) - rsa=PEM_read_bio_RSAPrivateKey(in,NULL,passwd_callback,const_cast(m_keypass.c_str())); - else { - EVP_PKEY* pkey=NULL; - PKCS12* p12 = d2i_PKCS12_bio(in, NULL); - if (p12) { - PKCS12_parse(p12, const_cast(m_keypass.c_str()), &pkey, NULL, NULL); - PKCS12_free(p12); - if (pkey) { - fprintf(f,"----- PRIVATE KEY -----\n"); - if (pkey->type==EVP_PK_RSA) - RSA_print_fp(f,pkey->pkey.rsa,0); - else if (pkey->type==EVP_PK_DSA) - DSA_print_fp(f,pkey->pkey.dsa,0); - EVP_PKEY_free(pkey); - } - } - } - if (rsa) { - fprintf(f,"----- PRIVATE KEY -----\n"); - RSA_print_fp(f,rsa,0); - RSA_free(rsa); - } - } - if (in) { - BIO_free(in); - in=NULL; - } - - // Dump certificates. - for (vector::const_iterator i=m_certs.begin(); i!=m_certs.end(); i++) { - fprintf(f,"----- CERTIFICATE(S) -----\n"); -#if (OPENSSL_VERSION_NUMBER > 0x009070000L) - X509_print_ex_fp(f,*i,XN_FLAG_SEP_MULTILINE,0); -#else - X509_print_fp(f,*i); -#endif - } -} - -// Used to determine the encoding format of credentials files -// dynamically. Supports: PEM, DER, PKCS12. -FileResolver::format_t FileResolver::getEncodingFormat(BIO* in) const -{ - PKCS12* p12 = NULL; - format_t format; - - const int READSIZE = 1; - char buf[READSIZE]; - char b1; - int mark; - - try { - if ( (mark = BIO_tell(in)) < 0 ) - throw IOException("getEncodingFormat: BIO_tell() can't get the file position"); - if ( BIO_read(in, buf, READSIZE) <= 0 ) - throw IOException("getEncodingFormat: BIO_read() can't read from the stream"); - if ( BIO_seek(in, mark) < 0 ) - throw IOException("getEncodingFormat: BIO_seek() can't reset the file position"); - } - catch (...) { - log_openssl(); - throw; - } - - b1 = buf[0]; - - // This is a slight variation of the Java code by Chad La Joie. - // - // Check the first byte of the file. If it's some kind of - // DER-encoded structure (including PKCS12), it will begin with ASCII 048. - // Otherwise, assume it's PEM. - if (b1 != 48) { - format = PEM; - } else { - // Here we know it's DER-encoded, now try to parse it as a PKCS12 - // ASN.1 structure. If it fails, must be another kind of DER-encoded - // key/cert structure. A little inefficient...but it works. - if ( (p12=d2i_PKCS12_bio(in,NULL)) == NULL ) { - format = DER; - } else { - format = _PKCS12; - } - if (p12) - PKCS12_free(p12); - if ( BIO_seek(in, mark) < 0 ) { - log_openssl(); - throw IOException("getEncodingFormat: BIO_seek() can't reset the file position"); - } - } - - return format; -} - -// Convert key/cert format_t types to a human-meaningful string for debug output -string FileResolver::formatToString(format_t format) const -{ - switch(format) { - case PEM: - return "PEM"; - case DER: - return "DER"; - case _PKCS12: - return "PKCS12"; - default: - return "UNKNOWN"; - } -} - -// Convert key/cert raw XML format attribute (XMLCh[]) to format_t type -FileResolver::format_t FileResolver::xmlFormatToFormat(const XMLCh* format_xml) const -{ - static const XMLCh cPEM[] = { chLatin_P, chLatin_E, chLatin_M, chNull }; - static const XMLCh cDER[] = { chLatin_D, chLatin_E, chLatin_R, chNull }; - static const XMLCh cPKCS12[] = { chLatin_P, chLatin_K, chLatin_C, chLatin_S, chDigit_1, chDigit_2, chNull }; - format_t format; - - if (!XMLString::compareString(format_xml,cPEM)) - format=PEM; - else if (!XMLString::compareString(format_xml,cDER)) - format=DER; - else if (!XMLString::compareString(format_xml,cPKCS12)) - format=_PKCS12; - else - format=UNKNOWN; - - return format; -} diff --git a/xmlproviders/Makefile.am b/xmlproviders/Makefile.am index 2a73993..b476b14 100644 --- a/xmlproviders/Makefile.am +++ b/xmlproviders/Makefile.am @@ -12,7 +12,6 @@ xmlproviders_la_LIBADD = \ $(top_builddir)/shib-target/libshib-target.la xmlproviders_la_SOURCES = \ - CredResolvers.cpp \ TargetedID.cpp \ XML.cpp \ XMLAAP.cpp \ diff --git a/xmlproviders/XML.cpp b/xmlproviders/XML.cpp index ca910ea..0b95544 100644 --- a/xmlproviders/XML.cpp +++ b/xmlproviders/XML.cpp @@ -37,54 +37,8 @@ const XMLCh XML::SHIB_SCHEMA_ID[] = // shibboleth.xsd 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, - chLatin_c, chLatin_r, chLatin_e, chLatin_d, chLatin_e, chLatin_n, chLatin_t, chLatin_i, chLatin_a, chLatin_l, chLatin_s, chColon, - chDigit_1, chPeriod, chDigit_0, chNull -}; - -const XMLCh XML::CREDS_SCHEMA_ID[] = // credentials.xsd -{ chLatin_c, chLatin_r, chLatin_e, chLatin_d, chLatin_e, chLatin_n, chLatin_t, chLatin_i, chLatin_a, chLatin_l, chLatin_s, - chPeriod, chLatin_x, chLatin_s, chLatin_d, chNull -}; - // Shibboleth vocabulary literals -const XMLCh XML::Literals::CAPath[] = -{ chLatin_C, chLatin_A, chLatin_P, chLatin_a, chLatin_t, chLatin_h, chNull }; - -const XMLCh XML::Literals::Certificate[] = -{ 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::Literals::Class[] = -{ chLatin_c, chLatin_l, chLatin_a, chLatin_s, chLatin_s, chNull }; - -const XMLCh XML::Literals::Credentials[] = -{ chLatin_C, chLatin_r, chLatin_e, chLatin_d, chLatin_e, chLatin_n, chLatin_t, chLatin_i, chLatin_a, chLatin_l, chLatin_s, chNull }; - -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::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 }; - -const XMLCh XML::Literals::format[] = -{ chLatin_f, chLatin_o, chLatin_r, chLatin_m, chLatin_a, chLatin_t, chNull }; - -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::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::Accept[]= { chLatin_A, chLatin_c, chLatin_c, chLatin_e, chLatin_p, chLatin_t, chNull }; diff --git a/xmlproviders/XMLAAP.cpp b/xmlproviders/XMLAAP.cpp index 1e6fdd4..342abf1 100644 --- a/xmlproviders/XMLAAP.cpp +++ b/xmlproviders/XMLAAP.cpp @@ -27,7 +27,6 @@ #include #include #include -#include using namespace shibsp; using namespace shibboleth; diff --git a/xmlproviders/XMLAccessControl.cpp b/xmlproviders/XMLAccessControl.cpp index 04b466a..e7d8e13 100644 --- a/xmlproviders/XMLAccessControl.cpp +++ b/xmlproviders/XMLAccessControl.cpp @@ -246,7 +246,7 @@ bool Operator::authorized(ShibTarget* st, ISessionCacheEntry* entry) const void XMLAccessControlImpl::init() { #ifdef _DEBUG - NDC ndc("init"); + xmltooling::NDC ndc("init"); #endif Category* log=&Category::getInstance(XMLPROVIDERS_LOGCAT".AccessControl"); diff --git a/xmlproviders/XMLCredentials.cpp b/xmlproviders/XMLCredentials.cpp index 5c3facb..c63cccb 100644 --- a/xmlproviders/XMLCredentials.cpp +++ b/xmlproviders/XMLCredentials.cpp @@ -30,13 +30,15 @@ #include #include +#include +#include using namespace shibsp; using namespace shibboleth; -using namespace saml; using namespace xmltooling; using namespace log4cpp; using namespace std; +using xmlsignature::CredentialResolver; namespace { @@ -48,7 +50,7 @@ namespace { void init(); ~XMLCredentialsImpl(); - typedef map resolvermap_t; + typedef map resolvermap_t; resolvermap_t m_resolverMap; }; @@ -58,7 +60,7 @@ namespace { XMLCredentials(const DOMElement* e) : ReloadableXMLFile(e) {} ~XMLCredentials() {} - const ICredResolver* lookup(const char* id) const; + CredentialResolver* lookup(const char* id) const; protected: virtual ReloadableXMLFileImpl* newImplementation(const char* pathname, bool first=true) const; @@ -67,7 +69,7 @@ namespace { } -IPlugIn* XMLCredentialsFactory(const DOMElement* e) +saml::IPlugIn* XMLCredentialsFactory(const DOMElement* e) { auto_ptr creds(new XMLCredentials(e)); creds->getImplementation(); @@ -84,75 +86,57 @@ ReloadableXMLFileImpl* XMLCredentials::newImplementation(const DOMElement* e, bo return new XMLCredentialsImpl(e); } +static const XMLCh Id[] = UNICODE_LITERAL_2(I,d); +static const XMLCh type[] = UNICODE_LITERAL_4(t,y,p,e); +static const XMLCh FileResolver[] = UNICODE_LITERAL_12(F,i,l,e,R,e,s,o,l,v,e,r); + void XMLCredentialsImpl::init() { #ifdef _DEBUG - saml::NDC ndc("init"); + NDC ndc("init"); #endif Category& log=Category::getInstance(XMLPROVIDERS_LOGCAT".Credentials"); - 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 ConfigurationException("Construction requires a valid creds file: (creds:Credentials as root element)"); + DOMElement* child=XMLHelper::getFirstChildElement(m_root); + while (child) { + string cr_type; + auto_ptr_char id(child->getAttributeNS(NULL,Id)); + if (!id.get()) { + child = XMLHelper::getNextSiblingElement(child); + continue; } - - DOMElement* child=saml::XML::getFirstChildElement(m_root); - while (child) { - string cr_type; - auto_ptr id(XMLString::transcode(child->getAttributeNS(NULL,SHIB_L(Id)))); - - 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))) { - xmltooling::auto_ptr_char c(child->getAttributeNS(NULL,SHIB_L(Class))); - cr_type=c.get(); - } - - if (!cr_type.empty()) { - try { - IPlugIn* plugin=SAMLConfig::getConfig().getPlugMgr().newPlugin(cr_type.c_str(),child); - ICredResolver* cr=dynamic_cast(plugin); - if (cr) - m_resolverMap[id.get()]=cr; - else { - log.error("plugin was not a credential resolver"); - throw UnknownExtensionException("plugin was not a credential resolver"); - } - } - catch (exception& e) { - log.error("failed to instantiate credential resolver (%s): %s", id.get(), e.what()); - throw; - } + + if (XMLString::equals(child->getLocalName(),FileResolver)) + cr_type=FILESYSTEM_CREDENTIAL_RESOLVER; + else { + xmltooling::auto_ptr_char c(child->getAttributeNS(NULL,type)); + cr_type=c.get(); + } + + if (!cr_type.empty()) { + try { + CredentialResolver* plugin= + XMLToolingConfig::getConfig().CredentialResolverManager.newPlugin(cr_type.c_str(),child); + m_resolverMap[id.get()] = plugin; } - else { - log.error("unknown or unimplemented type of credential resolver (%s)", id.get()); - throw UnknownExtensionException("Unknown or unimplemented type of credential resolver"); + catch (exception& e) { + log.error("failed to instantiate credential resolver (%s): %s", id.get(), e.what()); } - - child=saml::XML::getNextSiblingElement(child); } + else { + log.error("unknown type of credential resolver (%s)", id.get()); + } + + child = XMLHelper::getNextSiblingElement(child); } - catch (exception& e) { - log.errorStream() << "Error while parsing creds configuration: " << e.what() << CategoryStream::ENDLINE; - this->~XMLCredentialsImpl(); - throw; - } -#ifndef _DEBUG - catch (...) { - log.error("Unexpected error while parsing creds configuration"); - this->~XMLCredentialsImpl(); - throw; - } -#endif } XMLCredentialsImpl::~XMLCredentialsImpl() { - for_each(m_resolverMap.begin(),m_resolverMap.end(),xmltooling::cleanup_pair()); + for_each(m_resolverMap.begin(),m_resolverMap.end(),xmltooling::cleanup_pair()); } -const ICredResolver* XMLCredentials::lookup(const char* id) const +CredentialResolver* XMLCredentials::lookup(const char* id) const { if (id) { XMLCredentialsImpl* impl=dynamic_cast(getImplementation()); diff --git a/xmlproviders/XMLProviders.cpp b/xmlproviders/XMLProviders.cpp index ce01f15..8ddbea5 100644 --- a/xmlproviders/XMLProviders.cpp +++ b/xmlproviders/XMLProviders.cpp @@ -43,20 +43,17 @@ using namespace std; PlugManager::Factory TargetedIDFactory; PlugManager::Factory XMLCredentialsFactory; PlugManager::Factory XMLAAPFactory; -PlugManager::Factory FileCredResolverFactory; PlugManager::Factory XMLAccessControlFactory; 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::CREDS_NS,::XML::CREDS_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.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); conf.getPlugMgr().regFactory("edu.internet2.middleware.shibboleth.target.provider.XMLAAP",&XMLAAPFactory); conf.getPlugMgr().regFactory(shibtarget::XML::XMLAccessControlType,&XMLAccessControlFactory); @@ -70,24 +67,7 @@ extern "C" void XML_EXPORTS saml_extension_term() SAMLConfig& conf=SAMLConfig::getConfig(); conf.getPlugMgr().unregFactory("edu.internet2.middleware.shibboleth.common.provider.TargetedIDFactory"); 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"); conf.getPlugMgr().unregFactory("edu.internet2.middleware.shibboleth.target.provider.XMLAAP"); conf.getPlugMgr().unregFactory(shibtarget::XML::XMLAccessControlType); } - -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); - } -} diff --git a/xmlproviders/internal.h b/xmlproviders/internal.h index a3abfdf..2667472 100644 --- a/xmlproviders/internal.h +++ b/xmlproviders/internal.h @@ -39,38 +39,22 @@ #include #include +#include #define XMLPROVIDERS_LOGCAT "XMLProviders" #define SHIB_L(s) ::XML::Literals::s #define SHIB_L_QNAME(p,s) ::XML::Literals::p##_##s -void log_openssl(); - class XML { public: // URI constants static const XMLCh SHIB_NS[]; static const XMLCh SHIB_SCHEMA_ID[]; - static const XMLCh CREDS_NS[]; - static const XMLCh CREDS_SCHEMA_ID[]; struct Literals { - // credentials constants - static const XMLCh CAPath[]; - static const XMLCh Certificate[]; - static const XMLCh Class[]; - static const XMLCh Credentials[]; - static const XMLCh CustomResolver[]; - static const XMLCh Key[]; - static const XMLCh FileResolver[]; - static const XMLCh format[]; - static const XMLCh Id[]; - static const XMLCh password[]; - static const XMLCh Path[]; - // SAML attribute constants static const XMLCh Accept[]; static const XMLCh Alias[]; diff --git a/xmlproviders/xmlproviders.vcproj b/xmlproviders/xmlproviders.vcproj index 89c2394..cf8b2d8 100644 --- a/xmlproviders/xmlproviders.vcproj +++ b/xmlproviders/xmlproviders.vcproj @@ -216,10 +216,6 @@ - - -- 2.1.4