<extension base="string">
<attribute name="Accept" type="boolean" use="optional" default="true"/>
<attribute name="Type" type="shib:AttributeRuleValueType" use="optional" default="literal"/>
+ <anyAttribute namespace="##any" processContents="lax"/>
</extension>
</simpleContent>
</complexType>
<element name="AnyValue">
<complexType>
<sequence/>
+ <anyAttribute namespace="##any" processContents="lax"/>
</complexType>
</element>
<element name="Value" maxOccurs="unbounded">
<simpleContent>
<extension base="string">
<attribute name="Type" type="shib:AttributeRuleValueType" use="optional" default="literal"/>
+ <anyAttribute namespace="##any" processContents="lax"/>
</extension>
</simpleContent>
</complexType>
<complexContent>
<extension base="shib:SiteRuleType">
<attribute name="Name" type="string" use="required"/>
+ <anyAttribute namespace="##any" processContents="lax"/>
</extension>
</complexContent>
</complexType>
<attribute name="Factory" type="string" use="optional"/>
<attribute name="Alias" type="string" use="optional"/>
<attribute name="Header" type="string" use="optional"/>
+ <anyAttribute namespace="##any" processContents="lax"/>
</complexType>
<element name="AttributeRule" type="shib:AttributeRuleType">
<sequence>
<element ref="shib:AttributeRule" minOccurs="0" maxOccurs="unbounded"/>
</sequence>
+ <anyAttribute namespace="##any" processContents="lax"/>
</complexType>
</element>
</sequence>
<attribute name="Name" type="string" use="required"/>
<attribute name="ErrorURL" type="anyURI" use="optional"/>
+ <anyAttribute namespace="##any" processContents="lax"/>
</complexType>
<simpleType name="ContactTypeType">
<sequence/>
<attribute name="Name" type="string" use="required"/>
<attribute name="Location" type="anyURI" use="required"/>
+ <anyAttribute namespace="##any" processContents="lax"/>
</complexType>
<complexType name="OriginSiteType">
<attribute name="lastChanged" type="dateTime" use="optional"/>
<attribute name="validUntil" type="dateTime" use="optional"/>
<attribute name="cacheDuration" type="duration" use="optional"/>
- <anyAttribute/>
+ <anyAttribute namespace="##any" processContents="lax"/>
</complexType>
<element name="OriginSite" type="shib:OriginSiteType"/>
</restriction>
</simpleType>
</attribute>
+ <anyAttribute namespace="##any" processContents="lax"/>
</complexType>
<element name="KeyAuthority" type="shib:KeyAuthorityType"/>
<attribute name="lastChanged" type="dateTime" use="optional"/>
<attribute name="validUntil" type="dateTime" use="optional"/>
<attribute name="cacheDuration" type="duration" use="optional"/>
- <anyAttribute/>
+ <anyAttribute namespace="##any" processContents="lax"/>
</complexType>
</element>
<sequence>
<element ref="shib:KeyUse" maxOccurs="unbounded"/>
</sequence>
- <anyAttribute/>
+ <anyAttribute namespace="##any" processContents="lax"/>
</complexType>
</element>
ShibMySQLCCache();
virtual ~ShibMySQLCCache();
- virtual SAMLBinding* getBinding(const XMLCh* bindingProt)
- { return m_cache->getBinding(bindingProt); }
virtual CCacheEntry* find(const char* key);
virtual void insert(const char* key, SAMLAuthenticationStatement *s,
const char *client_addr);
public:
virtual ~CCache() = 0;
- virtual saml::SAMLBinding* getBinding(const XMLCh* bindingProt) = 0;
-
// insert() the Auth Statement into the CCache.
//
// Make sure you do not hold any open CCacheEntry objects before
InternalCCache();
virtual ~InternalCCache();
- virtual SAMLBinding* getBinding(const XMLCh* bindingProt);
virtual CCacheEntry* find(const char* key);
virtual void insert(const char* key, SAMLAuthenticationStatement *s,
const char *client_addr);
private:
RWLock *lock;
- SAMLBinding* m_SAMLBinding;
map<string,InternalCCacheEntry*> m_hashtable;
log4cpp::Category* log;
InternalCCache::InternalCCache()
{
- m_SAMLBinding=SAMLBindingFactory::getInstance();
string ctx="shibtarget.InternalCCache";
log = &(log4cpp::Category::getInstance(ctx));
lock = RWLock::create();
shutdown_wait->signal();
cleanup_thread->join(NULL);
- delete m_SAMLBinding;
for (map<string,InternalCCacheEntry*>::iterator i=m_hashtable.begin(); i!=m_hashtable.end(); i++)
delete i->second;
delete lock;
delete shutdown_wait;
}
-SAMLBinding* InternalCCache::getBinding(const XMLCh* bindingProt)
-{
- log->debug("looking for binding...");
- if (!XMLString::compareString(bindingProt,SAMLBinding::SAML_SOAP_HTTPS)) {
- log->debug("https binding found");
- return m_SAMLBinding;
- }
- return NULL;
-}
-
// assumed a lock is held..
InternalCCacheEntry* InternalCCache::findi(const char* key)
{
if (ini->get_tag (app, SHIBTARGET_TAG_AACONNECTTO, true, &tag))
samlConf.binding_defaults.conn_timeout = atoi(tag.c_str());
if (ini->get_tag (app, SHIBTARGET_TAG_CERTFILE, true, &tag))
- samlConf.binding_defaults.ssl_certfile = tag;
+ log.error("using OBSOLETE certfile setting, please migrate to the XML-based credential format (see the latest target deploy guide)");
if (ini->get_tag (app, SHIBTARGET_TAG_KEYFILE, true, &tag))
- samlConf.binding_defaults.ssl_keyfile = tag;
+ log.error("using OBSOLETE keyfile setting, please migrate to the XML-based credential format (see the latest target deploy guide)");
if (ini->get_tag (app, SHIBTARGET_TAG_KEYPASS, true, &tag))
- samlConf.binding_defaults.ssl_keypass = tag;
+ log.error("using OBSOLETE keypass setting, please migrate to the XML-based credential format (see the latest target deploy guide)");
if (ini->get_tag (app, SHIBTARGET_TAG_CALIST, true, &tag))
- samlConf.binding_defaults.ssl_calist = tag;
+ log.error("using OBSOLETE calist setting, please use the XML-based trust format (see the latest target deploy guide)");
try {
if (!samlConf.init()) {
// Try this request against all the bindings in the AuthenticationStatement
// (i.e. send it to each AA in the list of bindings)
SAMLResponse* response = NULL;
+ OriginMetadata site(subject->getNameQualifier());
+ if (site.fail())
+ throw MetadataException("unable to locate origin site's metadata during attribute query");
+ auto_ptr<XMLCh> caller(XMLString::transcode(resource.getResource()));
+ auto_ptr<SAMLBinding> pBinding(SAMLBindingFactory::getInstance(caller.get(),site));
while (!response && AAbindings.hasNext()) {
SAMLAuthorityBinding* binding = AAbindings.next();
priv->log->debug("Trying binding...");
- SAMLBinding* pBinding=m_cache->getBinding(binding->getBinding());
priv->log->debug("Sending request");
response=pBinding->send(*binding,*req);
}
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
-# ADD LINK32 log4cpp.lib xerces-c_2.lib xsec_lib_02.lib wsock32.lib saml_4.lib /nologo /dll /machine:I386 /out:"Release/shibtarget_3.dll" /libpath:"../../../opensaml/c/saml/Release" /export:shibrpc_prog_1 /export:shibrpc_ping_1
+# ADD LINK32 log4cpp.lib xerces-c_2.lib xsec_lib_02.lib wsock32.lib saml_4.lib /nologo /dll /machine:I386 /out:"Release/shibtarget_4.dll" /libpath:"../../../opensaml/c/saml/Release" /export:shibrpc_prog_1 /export:shibrpc_ping_1
# SUBTRACT LINK32 /pdb:none
!ELSEIF "$(CFG)" == "shibtarget - Win32 Debug"
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 log4cppD.lib xerces-c_2D.lib xsec_lib_02D.lib wsock32.lib saml_4D.lib /nologo /dll /debug /machine:I386 /out:"Debug/shibtarget_3D.dll" /pdbtype:sept /libpath:"../../../opensaml/c/saml/Debug" /export:shibrpc_prog_1 /export:shibrpc_ping_1
+# ADD LINK32 log4cppD.lib xerces-c_2D.lib xsec_lib_02D.lib wsock32.lib saml_4D.lib /nologo /dll /debug /machine:I386 /out:"Debug/shibtarget_4D.dll" /pdbtype:sept /libpath:"../../../opensaml/c/saml/Debug" /export:shibrpc_prog_1 /export:shibrpc_ping_1
# SUBTRACT LINK32 /pdb:none
!ENDIF
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_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
};
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
+ 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 Constants::XMLSIG_RETMETHOD_RAWX509[] = // http://www.w3.org/2000/09/xmldsig#rawX509Certificate
+{
+ chLatin_h, chLatin_t, chLatin_t, chLatin_p, chColon, chForwardSlash, chForwardSlash,
+ chLatin_w, chLatin_w, chLatin_w, chPeriod, chLatin_w, chDigit_3, chPeriod, chLatin_o, chLatin_r, chLatin_g, chForwardSlash,
+ chDigit_2, chDigit_0, chDigit_0, chDigit_0, chForwardSlash, chDigit_0, chDigit_9, chForwardSlash,
+ chLatin_x, chLatin_m, chLatin_l, chLatin_d, chLatin_s, chLatin_i, chLatin_g, chPound,
+ chLatin_r, chLatin_a, chLatin_w, chLatin_X, chDigit_5, chDigit_0, chDigit_9,
+ chLatin_C, chLatin_e, chLatin_r, chLatin_t, chLatin_i, chLatin_f, chLatin_i, chLatin_c, chLatin_a, chLatin_t, chLatin_e, chNull
+};
+
+const XMLCh Constants::SHIB_RETMETHOD_PEMX509[] = // urn:mace:shibboleth:1.0:xmldsig:pemX509Certificate
+{
+ 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_x, chLatin_m, chLatin_l, chLatin_d, chLatin_s, chLatin_i, chLatin_g, chColon,
+ chLatin_p, chLatin_e, chLatin_m, chLatin_X, chDigit_5, chDigit_0, chDigit_9,
+ chLatin_C, chLatin_e, chLatin_r, chLatin_t, chLatin_i, chLatin_f, chLatin_i, chLatin_c, chLatin_a, chLatin_t, chLatin_e, chNull
+};
+
+const XMLCh Constants::SHIB_RETMETHOD_DERRSA[] = // urn:mace:shibboleth:1.0:xmldsig:derRSAPrivateKey
+{
+ 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_x, chLatin_m, chLatin_l, chLatin_d, chLatin_s, chLatin_i, chLatin_g, chColon,
+ chLatin_d, chLatin_e, chLatin_r, chLatin_R, chLatin_S, chLatin_A,
+ chLatin_P, chLatin_r, chLatin_i, chLatin_v, chLatin_a, chLatin_t, chLatin_e, chLatin_K, chLatin_e, chLatin_y, chNull
+};
+
+const XMLCh Constants::SHIB_RETMETHOD_PEMRSA[] = // urn:mace:shibboleth:1.0:xmldsig:pemRSAPrivateKey
+{
+ 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_x, chLatin_m, chLatin_l, chLatin_d, chLatin_s, chLatin_i, chLatin_g, chColon,
+ chLatin_p, chLatin_e, chLatin_m, chLatin_R, chLatin_S, chLatin_A,
+ chLatin_P, chLatin_r, chLatin_i, chLatin_v, chLatin_a, chLatin_t, chLatin_e, chLatin_K, chLatin_e, chLatin_y, chNull
};
saml::QName Constants::SHIB_ATTRIBUTE_VALUE_TYPE(XML::SHIB_NS,XML::Literals::AttributeValueType);
ShibConfig.cpp \
ShibPOSTProfile.cpp \
ShibPOSTProfileFactory.cpp \
+ ShibSOAPBinding.cpp \
ScopedAttribute.cpp \
SimpleAttribute.cpp \
XML.cpp \
XMLMetadata.cpp \
XMLTrust.cpp \
+ XMLCredentials.cpp \
shib-threads.cpp
return ret;
}
+bool Trust::attach(const ISite* site, SSL_CTX* ctx) const
+{
+ bool ret=false;
+ Iterator<ITrust*> it=ShibConfig::getConfig().getTrustProviders();
+ while (!ret && it.hasNext())
+ {
+ ITrust* i=it.next();
+ i->lock();
+ ret=i->attach(site,ctx);
+ i->unlock();
+ }
+ return ret;
+}
+
Trust::~Trust()
{
if (m_mapper)
m_mapper->unlock();
}
+bool Credentials::attach(const XMLCh* subject, const ISite* relyingParty, SSL_CTX* ctx)
+{
+ bool ret=false;
+ Iterator<ICredentials*> it=ShibConfig::getConfig().getCredentialProviders();
+ while (!ret && it.hasNext())
+ {
+ ICredentials* i=it.next();
+ i->lock();
+ ret=i->attach(subject,relyingParty,ctx);
+ i->unlock();
+
+ }
+ return ret;
+}
+
AAP::AAP(const XMLCh* attrName, const XMLCh* attrNamespace) : m_mapper(NULL), m_rule(NULL)
{
Iterator<IAAP*> it=ShibConfig::getConfig().getAAPProviders();
using namespace shibboleth;
using namespace saml;
-SAMLBinding* SAMLBindingFactory::getInstance(const XMLCh* protocol)
+SAMLBinding* SAMLBindingFactory::getInstance(const XMLCh* subject, const ISite* relyingParty, const XMLCh* protocol)
{
if (!protocol || XMLString::compareString(protocol,SAMLBinding::SAML_SOAP_HTTPS))
throw UnsupportedProtocolException("SAMLBindingFactory::getInstance() unable to find binding implementation for specified protocol");
- return new SAMLSOAPBinding();
+ return new ShibSOAPBinding(subject, relyingParty);
}
return new XMLTrust(source);
}
+extern "C" ICredentials* XMLCredentialsFactory(const char* source)
+{
+ return new XMLCredentials(source);
+}
+
extern "C" IAAP* XMLAAPFactory(const char* source)
{
return new XMLAAP(source);
regFactory("edu.internet2.middleware.shibboleth.metadata.XML",&XMLMetadataFactory);
regFactory("edu.internet2.middleware.shibboleth.trust.XML",&XMLTrustFactory);
+ regFactory("edu.internet2.middleware.shibboleth.creds.XML",&XMLCredentialsFactory);
regFactory("edu.internet2.middleware.shibboleth.target.AAP.XML",&XMLAAPFactory);
regFactory("edu.internet2.middleware.shibboleth.target.AttributeFactory",&ShibAttributeFactory);
delete *i;
for (vector<ITrust*>::iterator j=m_trust_providers.begin(); j!=m_trust_providers.end(); j++)
delete *j;
- for (vector<IAAP*>::iterator k=m_aap_providers.begin(); k!=m_aap_providers.end(); k++)
+ for (vector<ICredentials*>::iterator k=m_cred_providers.begin(); k!=m_cred_providers.end(); k++)
delete *k;
+ for (vector<IAAP*>::iterator l=m_aap_providers.begin(); l!=m_aap_providers.end(); l++)
+ delete *l;
}
void ShibInternalConfig::regFactory(const char* type, MetadataFactory* factory)
m_trustFactoryMap[type]=factory;
}
+void ShibInternalConfig::regFactory(const char* type, CredentialsFactory* factory)
+{
+ if (type && factory)
+ {
+ m_credFactoryMap[type]=factory;
+ SAMLConfig::getConfig().binding_defaults.ssl_ctx_callback=ssl_ctx_callback;
+ }
+}
+
void ShibInternalConfig::regFactory(const char* type, AAPFactory* factory)
{
if (type && factory)
{
m_metadataFactoryMap.erase(type);
m_trustFactoryMap.erase(type);
+ m_credFactoryMap.erase(type);
m_aapFactoryMap.erase(type);
}
}
}
else
{
- AAPFactoryMap::const_iterator k=m_aapFactoryMap.find(type);
- if (k!=m_aapFactoryMap.end())
+ CredentialsFactoryMap::const_iterator k=m_credFactoryMap.find(type);
+ if (k!=m_credFactoryMap.end())
{
- m_aap_providers.push_back((k->second)(source));
+ m_cred_providers.push_back((k->second)(source));
ret=true;
}
else
- throw MetadataException("ShibConfig::addMetadata() unable to locate a metadata factory of the requested type");
+ {
+ AAPFactoryMap::const_iterator l=m_aapFactoryMap.find(type);
+ if (l!=m_aapFactoryMap.end())
+ {
+ m_aap_providers.push_back((l->second)(source));
+ ret=true;
+ }
+ else
+ throw MetadataException("ShibConfig::addMetadata() unable to locate a metadata factory of the requested type");
+ }
}
}
}
Trust t;
Iterator<XSECCryptoX509*> certs=t.getCertificates(hs->getName());
+ Iterator<XSECCryptoX509*> certs2=t.getCertificates(originSite);
// Signature verification now takes place. We check the assertion and the response.
// Assertion signing is optional, response signing is mandatory.
bool bVerified=false;
if (assertion->isSigned())
{
- while (certs.hasNext())
+ while (!bVerified && certs.hasNext())
{
try {
verifySignature(*assertion, mapper, handleService, certs.next()->clonePublicKey());
// continue trying others
}
}
+ while (!bVerified && certs2.hasNext())
+ {
+ try {
+ verifySignature(*assertion, mapper, handleService, certs2.next()->clonePublicKey());
+ bVerified=true;
+ }
+ catch (InvalidCryptoException&) {
+ // continue trying others
+ }
+ }
if (!bVerified)
verifySignature(*assertion, mapper, handleService);
}
bVerified=false;
- while (certs.hasNext())
+ while (!bVerified && certs.hasNext())
{
try {
verifySignature(*r, mapper, handleService, certs.next()->clonePublicKey());
// continue trying others
}
}
+ while (!bVerified && certs2.hasNext())
+ {
+ try {
+ verifySignature(*r, mapper, handleService, certs2.next()->clonePublicKey());
+ bVerified=true;
+ }
+ catch (InvalidCryptoException&) {
+ // continue trying others
+ }
+ }
if (!bVerified)
verifySignature(*r, mapper, handleService);
--- /dev/null
+/*
+ * The Shibboleth License, Version 1.
+ * Copyright (c) 2002
+ * University Corporation for Advanced Internet Development, Inc.
+ * All rights reserved
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution, if any, must include
+ * the following acknowledgment: "This product includes software developed by
+ * the University Corporation for Advanced Internet Development
+ * <http://www.ucaid.edu>Internet2 Project. Alternately, this acknowledegement
+ * may appear in the software itself, if and wherever such third-party
+ * acknowledgments normally appear.
+ *
+ * Neither the name of Shibboleth nor the names of its contributors, nor
+ * Internet2, nor the University Corporation for Advanced Internet Development,
+ * Inc., nor UCAID may be used to endorse or promote products derived from this
+ * software without specific prior written permission. For written permission,
+ * please contact shibboleth@shibboleth.org
+ *
+ * Products derived from this software may not be called Shibboleth, Internet2,
+ * UCAID, or the University Corporation for Advanced Internet Development, nor
+ * may Shibboleth appear in their name, without prior written permission of the
+ * University Corporation for Advanced Internet Development.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND WITH ALL FAULTS. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, AND NON-INFRINGEMENT ARE DISCLAIMED AND THE ENTIRE RISK
+ * OF SATISFACTORY QUALITY, PERFORMANCE, ACCURACY, AND EFFORT IS WITH LICENSEE.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER, CONTRIBUTORS OR THE UNIVERSITY
+ * CORPORATION FOR ADVANCED INTERNET DEVELOPMENT, INC. BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+/* ShibSOAPBinding.cpp - Shibboleth version of SOAP Binding with SSL callback
+
+ Scott Cantor
+ 10/30/03
+
+ $History:$
+*/
+
+#include "internal.h"
+
+#include <log4cpp/Category.hh>
+
+using namespace std;
+using namespace log4cpp;
+using namespace shibboleth;
+using namespace saml;
+
+SAMLResponse* ShibSOAPBinding::send(const SAMLAuthorityBinding& bindingInfo, SAMLRequest& req, SAMLConfig::SAMLBindingConfig& conf)
+{
+ conf.ssl_ctx_callback=ssl_ctx_callback;
+ conf.ssl_ctx_data=this;
+
+ return SAMLSOAPBinding::send(bindingInfo, req, conf);
+}
+
+bool shibboleth::ssl_ctx_callback(void* ssl_ctx, void* userptr)
+{
+ try
+ {
+ ShibSOAPBinding* b = reinterpret_cast<ShibSOAPBinding*>(userptr);
+ if (!Credentials::attach(b->m_subject, b->m_relyingParty, reinterpret_cast<ssl_ctx_st*>(ssl_ctx)))
+ {
+ NDC("ssl_ctx_callback");
+ Category::getInstance(SHIB_LOGCAT".ShibSOAPBinding").warn("found no appropriate credentials to attach, request will be anonymous");
+ }
+
+ Trust t;
+ if (!t.attach(b->m_relyingParty, reinterpret_cast<ssl_ctx_st*>(ssl_ctx)))
+ {
+ NDC("ssl_ctx_callback");
+ Category::getInstance(SHIB_LOGCAT".ShibSOAPBinding").warn("found no appropriate authorities to attach, request will be unverified");
+ }
+ }
+ catch (SAMLException& e)
+ {
+ NDC("ssl_ctx_callback");
+ Category::getInstance(SHIB_LOGCAT".ShibSOAPBinding").error(string("caught a SAML exception while attaching credentials to request: ") + e.what());
+ return false;
+ }
+ catch (...)
+ {
+ NDC("ssl_ctx_callback");
+ Category::getInstance(SHIB_LOGCAT".ShibSOAPBinding").error("caught an unknown exception while attaching credentials to request: ");
+ return false;
+ }
+
+ return true;
+}
const XMLCh XML::Literals::SiteGroup[]=
{ chLatin_S, chLatin_i, chLatin_t, chLatin_e, chLatin_G, chLatin_r, chLatin_o, chLatin_u, chLatin_p, chNull };
+const XMLCh XML::Literals::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::Exponent[] =
+{ chLatin_E, chLatin_x, chLatin_p, chLatin_o, chLatin_n, chLatin_e, chLatin_n, chLatin_t, chNull };
+
const XMLCh XML::Literals::KeyAuthority[] =
{ chLatin_K, chLatin_e, chLatin_y,
chLatin_A, chLatin_u, chLatin_t, chLatin_h, chLatin_o, chLatin_r, chLatin_i, chLatin_t, chLatin_y, chNull };
+const XMLCh XML::Literals::KeyUse[] =
+{ chLatin_K, chLatin_e, chLatin_y, chLatin_U, chLatin_s, chLatin_e, chNull };
+
+const XMLCh XML::Literals::Modulus[] =
+{ chLatin_M, chLatin_o, chLatin_d, chLatin_u, chLatin_l, chLatin_u, chLatin_s, chNull };
+
+const XMLCh XML::Literals::RelyingParty[] =
+{ chLatin_R, chLatin_e, chLatin_l, chLatin_y, chLatin_i, chLatin_n, chLatin_g,
+ chLatin_P, chLatin_a, chLatin_r, chLatin_t, chLatin_y, chNull };
+
+const XMLCh XML::Literals::RetrievalMethod[] =
+{ chLatin_R, chLatin_e, chLatin_t, chLatin_r, chLatin_i, chLatin_e, chLatin_v, chLatin_a, chLatin_l,
+ chLatin_M, chLatin_e, chLatin_t, chLatin_h, chLatin_o, chLatin_d, chNull };
+
+const XMLCh XML::Literals::RSAKeyValue[] =
+{ chLatin_R, chLatin_S, chLatin_A, chLatin_K, chLatin_e, chLatin_y, chLatin_V, chLatin_a, chLatin_l, chLatin_u, chLatin_e, chNull };
+
const XMLCh XML::Literals::Trust[] =
{ chLatin_T, chLatin_r, chLatin_u, chLatin_s, chLatin_t, chNull };
+const XMLCh XML::Literals::URI[] =
+{ chLatin_U, chLatin_R, chLatin_I, chNull };
+
+const XMLCh XML::Literals::VerifyDepth[] =
+{ chLatin_V, chLatin_e, chLatin_r, chLatin_i, chLatin_f, chLatin_y, chLatin_D, chLatin_e, chLatin_p, chLatin_t, chLatin_h, chNull };
+
const XMLCh XML::Literals::Accept[]=
{ chLatin_A, chLatin_c, chLatin_c, chLatin_e, chLatin_p, chLatin_t, chNull };
--- /dev/null
+/*
+ * The Shibboleth License, Version 1.
+ * Copyright (c) 2002
+ * University Corporation for Advanced Internet Development, Inc.
+ * All rights reserved
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution, if any, must include
+ * the following acknowledgment: "This product includes software developed by
+ * the University Corporation for Advanced Internet Development
+ * <http://www.ucaid.edu>Internet2 Project. Alternately, this acknowledegement
+ * may appear in the software itself, if and wherever such third-party
+ * acknowledgments normally appear.
+ *
+ * Neither the name of Shibboleth nor the names of its contributors, nor
+ * Internet2, nor the University Corporation for Advanced Internet Development,
+ * Inc., nor UCAID may be used to endorse or promote products derived from this
+ * software without specific prior written permission. For written permission,
+ * please contact shibboleth@shibboleth.org
+ *
+ * Products derived from this software may not be called Shibboleth, Internet2,
+ * UCAID, or the University Corporation for Advanced Internet Development, nor
+ * may Shibboleth appear in their name, without prior written permission of the
+ * University Corporation for Advanced Internet Development.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND WITH ALL FAULTS. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, AND NON-INFRINGEMENT ARE DISCLAIMED AND THE ENTIRE RISK
+ * OF SATISFACTORY QUALITY, PERFORMANCE, ACCURACY, AND EFFORT IS WITH LICENSEE.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER, CONTRIBUTORS OR THE UNIVERSITY
+ * CORPORATION FOR ADVANCED INTERNET DEVELOPMENT, INC. BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* XMLTrust.h - a trust implementation that uses an XML file
+
+ Scott Cantor
+ 9/27/02
+
+ $History:$
+*/
+
+#include "internal.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <log4cpp/Category.hh>
+#include <xercesc/framework/URLInputSource.hpp>
+#include <xercesc/util/regx/RegularExpression.hpp>
+#include <xsec/enc/OpenSSL/OpenSSLCryptoX509.hpp>
+
+using namespace shibboleth;
+using namespace saml;
+using namespace log4cpp;
+using namespace std;
+
+class shibboleth::XMLCredentialsImpl
+{
+public:
+ XMLCredentialsImpl(const char* pathname);
+ ~XMLCredentialsImpl();
+
+ struct KeyUse
+ {
+ KeyUse() {}
+ ~KeyUse();
+
+ bool attach(SSL_CTX* ctx);
+
+ enum format_t { X509DATA, DER, PEM };
+
+ format_t m_certtype, m_keytype;
+ vector<X509*> m_certs;
+ string m_certfile, m_keyfile;
+ vector<pair<const XMLCh*,bool> > m_relying;
+ };
+
+ vector<KeyUse*> m_keyuses;
+ typedef multimap<pair<const XMLCh*,bool>,KeyUse*> BindingMap;
+ BindingMap m_bindings;
+
+ DOMDocument* m_doc;
+};
+
+XMLCredentialsImpl::KeyUse::~KeyUse()
+{
+ for (vector<X509*>::iterator i=m_certs.begin(); i!=m_certs.end(); i++)
+ X509_free(*i);
+}
+
+bool XMLCredentialsImpl::KeyUse::attach(SSL_CTX* ctx)
+{
+ switch (m_certtype)
+ {
+ case PEM:
+ if (SSL_CTX_use_certificate_chain_file(ctx, m_certfile.c_str()) != 1)
+ {
+ log_openssl();
+ throw TrustException("XMLCredentials::KeyUse::attach() unable to set PEM certificate chain");
+ }
+ break;
+
+ case DER:
+ if (SSL_CTX_use_certificate_file(ctx, m_certfile.c_str(), SSL_FILETYPE_ASN1) != 1)
+ {
+ log_openssl();
+ throw TrustException("XMLCredentials::KeyUse::attach() unable to set DER certificate");
+ }
+ break;
+
+ case X509DATA:
+ for (vector<X509*>::reverse_iterator i=m_certs.rbegin(); i!=m_certs.rend(); i++)
+ {
+ if (i==m_certs.rbegin())
+ {
+ if (SSL_CTX_use_certificate(ctx, *i) != 1)
+ {
+ log_openssl();
+ throw TrustException("XMLCredentials::KeyUse::attach() unable to set certificate from X509Data");
+ }
+ }
+ else
+ {
+ // When we add extra 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(ctx, dup) != 0)
+ {
+ X509_free(dup);
+ log_openssl();
+ throw TrustException("XMLCredentials::KeyUse::attach() unable to add CA certificate from X509Data");
+ }
+ }
+ }
+ }
+
+ switch (m_keytype)
+ {
+ case PEM:
+ if (SSL_CTX_use_PrivateKey_file(ctx, m_keyfile.c_str(), SSL_FILETYPE_PEM) != 1)
+ {
+ log_openssl();
+ throw TrustException("XMLCredentials::KeyUse::attach() unable to set PEM private key");
+ }
+ break;
+
+ case DER:
+ if (SSL_CTX_use_PrivateKey_file(ctx, m_keyfile.c_str(), SSL_FILETYPE_ASN1) != 1)
+ {
+ log_openssl();
+ throw TrustException("XMLCredentials::KeyUse::attach() unable to set PEM private key");
+ }
+ }
+
+ if (!SSL_CTX_check_private_key(ctx))
+ {
+ log_openssl();
+ throw TrustException("XMLCredentials::KeyUse::attach found mismatch between the private key and certificate");
+ }
+
+ return true;
+}
+
+XMLCredentialsImpl::XMLCredentialsImpl(const char* pathname) : m_doc(NULL)
+{
+ NDC ndc("XMLCredentialsImpl");
+ Category& log=Category::getInstance(SHIB_LOGCAT".XMLCredentialsImpl");
+
+ saml::XML::Parser p;
+ try
+ {
+ static XMLCh base[]={chLatin_f, chLatin_i, chLatin_l, chLatin_e, chColon, chForwardSlash, chForwardSlash, chForwardSlash, chNull};
+ URLInputSource src(base,pathname);
+ Wrapper4InputSource dsrc(&src,false);
+ m_doc=p.parse(dsrc);
+
+ log.infoStream() << "Loaded and parsed creds file (" << pathname << ")" << CategoryStream::ENDLINE;
+
+ DOMElement* e = m_doc->getDocumentElement();
+ if (XMLString::compareString(XML::SHIB_NS,e->getNamespaceURI()) ||
+ XMLString::compareString(SHIB_L(Credentials),e->getLocalName()))
+ {
+ log.error("Construction requires a valid creds file: (shib:Credentials as root element)");
+ throw MetadataException("Construction requires a valid creds file: (shib:Credentials as root element)");
+ }
+
+ // Loop over the KeyUse elements.
+ DOMNodeList* nlist=e->getElementsByTagNameNS(XML::SHIB_NS,SHIB_L(KeyUse));
+ for (int i=0; nlist && i<nlist->getLength(); i++)
+ {
+ auto_ptr<KeyUse> ku(new KeyUse());
+
+ bool key=false,cert=false;
+
+ // Grab all the RetrievalMethods for external material.
+ DOMNodeList* extlist=static_cast<DOMElement*>(nlist->item(i))->getElementsByTagNameNS(
+ saml::XML::XMLSIG_NS,SHIB_L(RetrievalMethod)
+ );
+ for (int j=0; (!key || !cert) && extlist && j<extlist->getLength(); j++)
+ {
+ DOMElement* method=static_cast<DOMElement*>(extlist->item(j));
+ const XMLCh* rmtype=method->getAttributeNS(NULL,SHIB_L(Type));
+ auto_ptr<char> uri(XMLString::transcode(method->getAttributeNS(NULL,SHIB_L(URI))));
+
+ // Is the URI locally accessible as a relative URL?
+#ifdef WIN32
+ struct _stat stat_buf;
+ if (_stat(uri.get(), &stat_buf) != 0)
+#else
+ struct stat stat_buf;
+ if (stat(uri.get(), &stat_buf) != 0)
+#endif
+ {
+ log.warn("Credential referenced by ds:RetrievalMethod can't be opened");
+ continue;
+ }
+
+ if (!XMLString::compareString(rmtype,shibboleth::Constants::XMLSIG_RETMETHOD_RAWX509))
+ {
+ if (cert)
+ log.warn("Found another certificate credential (DER), replacing the original with it");
+ ku->m_certfile=uri.get();
+ ku->m_certtype=KeyUse::DER;
+ cert=true;
+ }
+ else if (!XMLString::compareString(rmtype,shibboleth::Constants::SHIB_RETMETHOD_PEMX509))
+ {
+ if (cert)
+ log.warn("Found another certificate credential (PEM), replacing the original with it");
+ ku->m_certfile=uri.get();
+ ku->m_certtype=KeyUse::PEM;
+ cert=true;
+ }
+ else if (!XMLString::compareString(rmtype,shibboleth::Constants::SHIB_RETMETHOD_PEMRSA))
+ {
+ if (key)
+ log.warn("Found another private key credential (PEM/RSA), replacing the original with it");
+ ku->m_keyfile=uri.get();
+ ku->m_keytype=KeyUse::PEM;
+ key=true;
+ }
+ else if (!XMLString::compareString(rmtype,shibboleth::Constants::SHIB_RETMETHOD_DERRSA))
+ {
+ if (key)
+ log.warn("Found another private key credential (DER/RSA), replacing the original with it");
+ ku->m_keyfile=uri.get();
+ ku->m_keytype=KeyUse::DER;
+ key=true;
+ }
+ }
+
+ if (!cert)
+ {
+ // Is there an X509Data?
+ DOMNodeList* x509data=static_cast<DOMElement*>(nlist->item(i))->getElementsByTagNameNS(
+ saml::XML::XMLSIG_NS,L(X509Data)
+ );
+ if (x509data && x509data->getLength())
+ {
+ if (x509data->getLength()>1)
+ log.warn("Found multiple certificate chains, using the first");
+
+ // Grab up any X509Certificate elements, and flatten into one list.
+ DOMNodeList* certlist=static_cast<DOMElement*>(x509data->item(0))->getElementsByTagNameNS(
+ saml::XML::XMLSIG_NS,L(X509Certificate)
+ );
+ for (int k=0; certlist && k<certlist->getLength(); k++)
+ {
+ auto_ptr<char> blob(XMLString::transcode(certlist->item(k)->getFirstChild()->getNodeValue()));
+ X509* x=B64_to_X509(blob.get());
+ if (x)
+ ku->m_certs.push_back(x);
+ else
+ log.warn("Unable to parse ds:X509Certificate element, can't include in chain");
+ }
+
+ if (ku->m_certs.size()>0)
+ {
+ ku->m_certtype=KeyUse::X509DATA;
+ cert=true;
+ }
+ else
+ log.warn("Found no inline certificates in the ds:X509Data element, ignoring it");
+ }
+ }
+
+ if (!cert)
+ {
+ log.error("Found no acceptable certificate in shib:KeyUse element, ignoring it");
+ continue;
+ }
+
+ if (!key)
+ {
+ log.error("Found no acceptable private/secret key in shib:KeyUse element, ignoring it");
+ continue;
+ }
+
+ // Pull in the relying parties.
+ DOMNodeList* parties=static_cast<DOMElement*>(nlist->item(i))->getElementsByTagNameNS(XML::SHIB_NS,SHIB_L(RelyingParty));
+ int m=0;
+ while (parties && m<parties->getLength())
+ {
+ const XMLCh* name=parties->item(m)->getFirstChild()->getNodeValue();
+ if (name && *name)
+ {
+ static const XMLCh one[]={ chDigit_1, chNull };
+ static const XMLCh tru[]={ chLatin_t, chLatin_r, chLatin_u, chLatin_e, chNull };
+ const XMLCh* regexp=
+ static_cast<DOMElement*>(parties->item(m))->getAttributeNS(NULL,SHIB_L(regexp));
+ bool flag=(!XMLString::compareString(regexp,one) || !XMLString::compareString(regexp,tru));
+ ku->m_relying.push_back(pair<const XMLCh*,bool>(name,flag));
+ }
+ m++;
+ }
+ // If no RelyingParties, this is a catch-all binding.
+ if (m==0)
+ ku->m_relying.push_back(pair<const XMLCh*,bool>(NULL,false));
+
+ // Now map the subjects to the credentials.
+ DOMNodeList* subs=static_cast<DOMElement*>(nlist->item(i))->getElementsByTagNameNS(XML::SHIB_NS,L(Subject));
+ int l=0;
+ while (subs && l<subs->getLength())
+ {
+ const XMLCh* name=subs->item(l)->getFirstChild()->getNodeValue();
+ if (name && *name)
+ {
+ static const XMLCh one[]={ chDigit_1, chNull };
+ static const XMLCh tru[]={ chLatin_t, chLatin_r, chLatin_u, chLatin_e, chNull };
+ const XMLCh* regexp=
+ static_cast<DOMElement*>(subs->item(l))->getAttributeNS(NULL,SHIB_L(regexp));
+ bool flag=(!XMLString::compareString(regexp,one) || !XMLString::compareString(regexp,tru));
+ m_bindings.insert(BindingMap::value_type(pair<const XMLCh*,bool>(name,flag),ku.get()));
+ }
+ l++;
+ }
+ // If no Subjects, this is a catch-all binding.
+ if (l==0)
+ m_bindings.insert(BindingMap::value_type(pair<const XMLCh*,bool>(NULL,false),ku.get()));
+
+ m_keyuses.push_back(ku.release());
+ }
+ }
+ catch (SAMLException& e)
+ {
+ log.errorStream() << "XML error while parsing creds configuration: " << e.what() << CategoryStream::ENDLINE;
+ for (vector<KeyUse*>::iterator i=m_keyuses.begin(); i!=m_keyuses.end(); i++)
+ delete (*i);
+ if (m_doc)
+ m_doc->release();
+ throw;
+ }
+ catch (...)
+ {
+ log.error("Unexpected error while parsing creds configuration");
+ for (vector<KeyUse*>::iterator i=m_keyuses.begin(); i!=m_keyuses.end(); i++)
+ delete (*i);
+ if (m_doc)
+ m_doc->release();
+ throw;
+ }
+}
+
+XMLCredentialsImpl::~XMLCredentialsImpl()
+{
+ for (vector<KeyUse*>::iterator i=m_keyuses.begin(); i!=m_keyuses.end(); i++)
+ delete (*i);
+ if (m_doc)
+ m_doc->release();
+}
+
+XMLCredentials::XMLCredentials(const char* pathname) : m_filestamp(0), m_source(pathname), m_impl(NULL)
+{
+#ifdef WIN32
+ struct _stat stat_buf;
+ if (_stat(pathname, &stat_buf) == 0)
+#else
+ struct stat stat_buf;
+ if (stat(pathname, &stat_buf) == 0)
+#endif
+ m_filestamp=stat_buf.st_mtime;
+ m_impl=new XMLCredentialsImpl(pathname);
+ m_lock=RWLock::create();
+}
+
+XMLCredentials::~XMLCredentials()
+{
+ delete m_lock;
+ delete m_impl;
+}
+
+void XMLCredentials::lock()
+{
+ m_lock->rdlock();
+
+ // Check if we need to refresh.
+#ifdef WIN32
+ struct _stat stat_buf;
+ if (_stat(m_source.c_str(), &stat_buf) == 0)
+#else
+ struct stat stat_buf;
+ if (stat(m_source.c_str(), &stat_buf) == 0)
+#endif
+ {
+ if (m_filestamp>0 && m_filestamp<stat_buf.st_mtime)
+ {
+ // Elevate lock and recheck.
+ m_lock->unlock();
+ m_lock->wrlock();
+ if (m_filestamp>0 && m_filestamp<stat_buf.st_mtime)
+ {
+ try
+ {
+ XMLCredentialsImpl* new_mapper=new XMLCredentialsImpl(m_source.c_str());
+ delete m_impl;
+ m_impl=new_mapper;
+ m_filestamp=stat_buf.st_mtime;
+ m_lock->unlock();
+ }
+ catch(SAMLException& e)
+ {
+ m_lock->unlock();
+ saml::NDC ndc("lock");
+ Category::getInstance(SHIB_LOGCAT".XMLCredentials").error("failed to reload credentials metadata, sticking with what we have: %s", e.what());
+ }
+ catch(...)
+ {
+ m_lock->unlock();
+ saml::NDC ndc("lock");
+ Category::getInstance(SHIB_LOGCAT".XMLCredentials").error("caught an unknown exception, sticking with what we have");
+ }
+ }
+ else
+ {
+ m_lock->unlock();
+ }
+ m_lock->rdlock();
+ }
+ }
+}
+
+void XMLCredentials::unlock()
+{
+ m_lock->unlock();
+}
+
+
+bool XMLCredentials::attach(const XMLCh* subject, const ISite* relyingParty, SSL_CTX* ctx) const
+{
+ NDC ndc("attach");
+
+ // Use the matching bindings.
+ for (XMLCredentialsImpl::BindingMap::const_iterator i=m_impl->m_bindings.begin(); i!=m_impl->m_bindings.end(); i++)
+ {
+ bool match=false;
+
+ if (i->first.first==NULL) // catch-all entry
+ {
+ match=true;
+ }
+ else if (i->first.second) // regexp
+ {
+ try
+ {
+ RegularExpression re(i->first.first);
+ if (re.matches(subject))
+ match=true;
+ }
+ catch (XMLException& ex)
+ {
+ auto_ptr<char> tmp(XMLString::transcode(ex.getMessage()));
+ Category& log=Category::getInstance(SHIB_LOGCAT".XMLCredentials");
+ log.errorStream() << "caught exception while parsing regular expression: " << tmp.get()
+ << CategoryStream::ENDLINE;
+ }
+ }
+ else if (!XMLString::compareString(subject,i->first.first))
+ {
+ match=true;
+ }
+
+ if (match)
+ {
+ // See if the relying party applies...
+ match=false;
+ for (vector<pair<const XMLCh*,bool> >::const_iterator j=i->second->m_relying.begin(); j!=i->second->m_relying.end(); j++)
+ {
+ if (j->first==NULL) // catch-all entry
+ {
+ match=true;
+ }
+ else if (j->second) // regexp
+ {
+ try
+ {
+ RegularExpression re(j->first);
+ if (re.matches(relyingParty->getName()))
+ match=true;
+ else
+ {
+ Iterator<const XMLCh*> groups=relyingParty->getGroups();
+ while (!match && groups.hasNext())
+ if (re.matches(groups.next()))
+ match=true;
+ }
+ }
+ catch (XMLException& ex)
+ {
+ auto_ptr<char> tmp(XMLString::transcode(ex.getMessage()));
+ Category& log=Category::getInstance(SHIB_LOGCAT".XMLCredentials");
+ log.errorStream() << "caught exception while parsing regular expression: " << tmp.get()
+ << CategoryStream::ENDLINE;
+ }
+ }
+ else if (!XMLString::compareString(relyingParty->getName(),j->first))
+ {
+ match=true;
+ }
+ else
+ {
+ Iterator<const XMLCh*> groups=relyingParty->getGroups();
+ while (!match && groups.hasNext())
+ if (!XMLString::compareString(groups.next(),j->first))
+ match=true;
+ }
+ }
+ }
+
+ if (match)
+ {
+ // We have the credentials to use...
+ return i->second->attach(ctx);
+ }
+ }
+
+ return false;
+}
struct KeyAuthority
{
- KeyAuthority() : m_store(NULL) {}
+ KeyAuthority() : m_store(NULL), m_depth(0), m_type(authority) {}
~KeyAuthority();
- X509_STORE* getX509Store();
+ X509_STORE* getX509Store(bool cached=true);
vector<XSECCryptoX509*> m_certs;
+ vector<X509*> m_nativecerts;
X509_STORE* m_store;
+ unsigned short m_depth;
+ enum {authority, entity} m_type;
};
vector<KeyAuthority*> m_keyauths;
DOMDocument* m_doc;
};
-X509_STORE* XMLTrustImpl::KeyAuthority::getX509Store()
+X509_STORE* XMLTrustImpl::KeyAuthority::getX509Store(bool cached)
{
// We cache them once they're built...
- if (m_store)
+ if (m_store && cached)
return m_store;
-
+
NDC ndc("getX509Store");
+ Category& log=Category::getInstance(SHIB_LOGCAT".XMLTrust");
- // Load the cert vector into a store.
+ // Do we need to convert to native cert format?
+ if (m_nativecerts.empty())
+ {
+ for (vector<XSECCryptoX509*>::const_iterator i=m_certs.begin(); i!=m_certs.end(); i++)
+ {
+ X509* x509=B64_to_X509((*i)->getDEREncodingSB().rawCharBuffer());
+ if (!x509)
+ {
+ log.warn("failed to parse X509 buffer: %s", (*i)->getDEREncodingSB().rawCharBuffer());
+ continue;
+ }
+ m_nativecerts.push_back(x509);
+ }
+ }
- if (!(m_store=X509_STORE_new()))
+ // Load the cert vector into a store.
+ X509_STORE* store=NULL;
+ if (!(store=X509_STORE_new()))
{
log_openssl();
return NULL;
}
- X509_STORE_set_verify_cb_func(m_store,verify_callback);
+ X509_STORE_set_verify_cb_func(store,verify_callback);
- Category& log=Category::getInstance(SHIB_LOGCAT".XMLTrustImpl");
-
- for (vector<XSECCryptoX509*>::const_iterator i=m_certs.begin(); i!=m_certs.end(); i++)
+ for (vector<X509*>::iterator j=m_nativecerts.begin(); j!=m_nativecerts.end(); j++)
{
- X509* x509=B64_to_X509((*i)->getDEREncodingSB().rawCharBuffer());
- if (!x509)
- {
- //X509_STORE_free(m_store);
- //return m_store=NULL;
- log.warn("failed to parse X509 buffer: %s",
- (*i)->getDEREncodingSB().rawCharBuffer());
- continue;
- }
-
- if (!X509_STORE_add_cert(m_store,x509))
+ if (!X509_STORE_add_cert(store,X509_dup(*j)))
{
log_openssl();
- log.warn("failed to add cert: %s", x509->name);
- X509_free(x509);
- //X509_STORE_free(m_store);
- //return m_store=NULL;
- continue;
+ log.warn("failed to add cert: %s", (*j)->name);
+ continue;
}
}
- return m_store;
+ if (cached)
+ m_store=store;
+ return store;
}
XMLTrustImpl::KeyAuthority::~KeyAuthority()
{
- for (vector<XSECCryptoX509*>::iterator i=m_certs.begin(); i!=m_certs.end(); i++)
- delete (*i);
- X509_STORE_free(m_store);
+ if (m_store)
+ X509_STORE_free(m_store);
+ for (vector<X509*>::iterator i=m_nativecerts.begin(); i!=m_nativecerts.end(); i++)
+ X509_free(*i);
+ for (vector<XSECCryptoX509*>::iterator j=m_certs.begin(); j!=m_certs.end(); j++)
+ delete (*j);
}
XMLTrustImpl::XMLTrustImpl(const char* pathname) : m_doc(NULL)
DOMElement* e = m_doc->getDocumentElement();
if (XMLString::compareString(XML::SHIB_NS,e->getNamespaceURI()) ||
- XMLString::compareString(XML::Literals::Trust,e->getLocalName()))
+ XMLString::compareString(SHIB_L(Trust),e->getLocalName()))
{
log.error("Construction requires a valid trust file: (shib:Trust as root element)");
throw MetadataException("Construction requires a valid trust file: (shib:Trust as root element)");
}
// Loop over the KeyAuthority elements.
- DOMNodeList* nlist=e->getElementsByTagNameNS(XML::SHIB_NS,XML::Literals::KeyAuthority);
+ DOMNodeList* nlist=e->getElementsByTagNameNS(XML::SHIB_NS,SHIB_L(KeyAuthority));
for (int i=0; nlist && i<nlist->getLength(); i++)
{
KeyAuthority* ka=new KeyAuthority();
m_keyauths.push_back(ka);
+ const XMLCh* depth=static_cast<DOMElement*>(nlist->item(i))->getAttributeNS(NULL,SHIB_L(VerifyDepth));
+ if (depth && *depth)
+ ka->m_depth=XMLString::parseInt(depth);
+
+ const XMLCh* type=static_cast<DOMElement*>(nlist->item(i))->getAttributeNS(NULL,SHIB_L(Type));
+ if (type && *type==chLatin_e)
+ ka->m_type=KeyAuthority::entity;
+
// Very rudimentary, grab up all the X509Certificate elements, and flatten into one list.
DOMNodeList* certlist=static_cast<DOMElement*>(nlist->item(i))->getElementsByTagNameNS(
saml::XML::XMLSIG_NS,L(X509Certificate)
// Now map the subjects to the list of certs.
DOMNodeList* subs=static_cast<DOMElement*>(nlist->item(i))->getElementsByTagNameNS(XML::SHIB_NS,L(Subject));
- for (int k=0; subs && k<subs->getLength(); k++)
+ int k=0;
+ while (subs && k<subs->getLength())
{
const XMLCh* name=subs->item(k)->getFirstChild()->getNodeValue();
if (name && *name)
static const XMLCh one[]={ chDigit_1, chNull };
static const XMLCh tru[]={ chLatin_t, chLatin_r, chLatin_u, chLatin_e, chNull };
const XMLCh* regexp=
- static_cast<DOMElement*>(subs->item(k))->getAttributeNS(NULL,XML::Literals::regexp);
+ static_cast<DOMElement*>(subs->item(k))->getAttributeNS(NULL,SHIB_L(regexp));
bool flag=(!XMLString::compareString(regexp,one) || !XMLString::compareString(regexp,tru));
m_bindings[pair<const XMLCh*,bool>(name,flag)]=ka;
}
+ k++;
}
+ // If no Subjects, this is a catch-all binding.
+ if (k==0)
+ m_bindings[pair<const XMLCh*,bool>(NULL,false)]=ka;
}
}
catch (SAMLException& e)
{
- log.errorStream() << "XML error while parsing site configuration: " << e.what() << CategoryStream::ENDLINE;
+ log.errorStream() << "XML error while parsing trust configuration: " << e.what() << CategoryStream::ENDLINE;
for (vector<KeyAuthority*>::iterator i=m_keyauths.begin(); i!=m_keyauths.end(); i++)
delete (*i);
if (m_doc)
}
catch (...)
{
- log.error("Unexpected error while parsing site configuration");
+ log.error("Unexpected error while parsing trust configuration");
for (vector<KeyAuthority*>::iterator i=m_keyauths.begin(); i!=m_keyauths.end(); i++)
delete (*i);
if (m_doc)
saml::NDC ndc("lock");
Category::getInstance(SHIB_LOGCAT".XMLTrust").error("failed to reload trust metadata, sticking with what we have: %s", e.what());
}
- catch(...)
+/* catch(...)
{
m_lock->unlock();
saml::NDC ndc("lock");
Category::getInstance(SHIB_LOGCAT".XMLTrust").error("caught an unknown exception, sticking with what we have");
- }
+ } */
}
else
{
Iterator<XSECCryptoX509*> XMLTrust::getCertificates(const XMLCh* subject) const
{
- // Find the first matching binding.
+ // Find the first matching entity binding.
for (XMLTrustImpl::BindingMap::const_iterator i=m_impl->m_bindings.begin(); i!=m_impl->m_bindings.end(); i++)
{
- if (i->first.second) // regexp
+ if (i->second->m_type!=XMLTrustImpl::KeyAuthority::entity)
+ continue;
+
+ if (i->first.first==NULL) // catch-all entry
+ {
+ return i->second->m_certs;
+ }
+ else if (i->first.second) // regexp
{
try
{
<< CategoryStream::ENDLINE;
}
}
- else if (!XMLString::compareString(subject,i->first.first))
+ else if (!XMLString::compareString(subject,i->first.first)) // exact match
{
return i->second->m_certs;
}
return EMPTY(XSECCryptoX509*);
}
+bool XMLTrust::attach(const ISite* site, SSL_CTX* ctx) const
+{
+ NDC ndc("attach");
+
+ // Use the matching bindings.
+ for (XMLTrustImpl::BindingMap::const_iterator i=m_impl->m_bindings.begin(); i!=m_impl->m_bindings.end(); i++)
+ {
+ if (i->second->m_type!=XMLTrustImpl::KeyAuthority::authority)
+ continue;
+
+ bool match=false;
+ if (i->first.first==NULL) // catch-all entry
+ {
+ match=true;
+ }
+ else if (i->first.second) // regexp
+ {
+ try
+ {
+ RegularExpression re(i->first.first);
+ if (re.matches(site->getName()))
+ match=true;
+ else
+ {
+ Iterator<const XMLCh*> groups=site->getGroups();
+ while (!match && groups.hasNext())
+ if (re.matches(groups.next()))
+ match=true;
+ }
+ }
+ catch (XMLException& ex)
+ {
+ auto_ptr<char> tmp(XMLString::transcode(ex.getMessage()));
+ Category& log=Category::getInstance(SHIB_LOGCAT".XMLTrust");
+ log.errorStream() << "caught exception while parsing regular expression: " << tmp.get()
+ << CategoryStream::ENDLINE;
+ }
+ }
+ else if (!XMLString::compareString(site->getName(),i->first.first)) // exact match
+ {
+ match=true;
+ }
+ else
+ {
+ Iterator<const XMLCh*> groups=site->getGroups();
+ while (!match && groups.hasNext())
+ if (!XMLString::compareString(i->first.first,groups.next()))
+ match=true;
+ }
+
+ // If we have a match, use the associated keyauth and load it into the context's store.
+ if (match)
+ {
+ X509_STORE* store=i->second->getX509Store(false);
+ if (store)
+ {
+ SSL_CTX_set_cert_store(ctx,store);
+ SSL_CTX_set_verify_depth(ctx,i->second->m_depth);
+ }
+ return true;
+ }
+ }
+
+ return false;
+}
+
bool XMLTrust::validate(const ISite* site, Iterator<XSECCryptoX509*> certs) const
{
vector<const XMLCh*> temp;
// Use the matching bindings.
for (XMLTrustImpl::BindingMap::const_iterator i=m_impl->m_bindings.begin(); i!=m_impl->m_bindings.end(); i++)
{
+ if (i->second->m_type!=XMLTrustImpl::KeyAuthority::authority)
+ continue;
+
bool match=false;
- if (i->first.second) // regexp
+ if (i->first.first==NULL) // catch-all entry
+ {
+ match=true;
+ }
+ else if (i->first.second) // regexp
{
try
{
catch (XMLException& ex)
{
auto_ptr<char> tmp(XMLString::transcode(ex.getMessage()));
- NDC ndc("getCertificates");
Category& log=Category::getInstance(SHIB_LOGCAT".XMLTrust");
log.errorStream() << "caught exception while parsing regular expression: " << tmp.get()
<< CategoryStream::ENDLINE;
}
}
- else if (!XMLString::compareString(site->getName(),i->first.first))
+ else if (!XMLString::compareString(site->getName(),i->first.first)) // exact match
{
match=true;
}
#else
X509_STORE_CTX_init(ctx,store,sk_X509_value(chain,0),chain);
#endif
+ if (i->second->m_depth)
+ X509_STORE_CTX_set_depth(ctx,i->second->m_depth);
if (X509_verify_cert(ctx)==1)
{
sk_X509_pop_free(chain,X509_free);
#include "shib.h"
#include "shib-threads.h"
+#include <openssl/x509.h>
+
#define SHIB_LOGCAT "Shibboleth"
namespace shibboleth
{
class XMLMetadataImpl;
- class SHIB_EXPORTS XMLMetadata : public IMetadata
+ class XMLMetadata : public IMetadata
{
public:
XMLMetadata(const char* pathname);
};
class XMLTrustImpl;
- class SHIB_EXPORTS XMLTrust : public ITrust
+ class XMLTrust : public ITrust
{
public:
XMLTrust(const char* pathname);
saml::Iterator<XSECCryptoX509*> getCertificates(const XMLCh* subject) const;
bool validate(const ISite* site, saml::Iterator<XSECCryptoX509*> certs) const;
bool validate(const ISite* site, saml::Iterator<const XMLCh*> certs) const;
+ bool attach(const ISite* site, SSL_CTX* ctx) const;
private:
std::string m_source;
XMLTrustImpl* m_impl;
};
+ class XMLCredentialsImpl;
+ class XMLCredentials : public ICredentials
+ {
+ public:
+ XMLCredentials(const char* pathname);
+ ~XMLCredentials();
+ bool attach(const XMLCh* subject, const ISite* relyingParty, SSL_CTX* ctx) const;
+
+ private:
+ void lock();
+ void unlock();
+ std::string m_source;
+ time_t m_filestamp;
+ RWLock* m_lock;
+ XMLCredentialsImpl* m_impl;
+ };
+
class XMLAAPImpl;
- class SHIB_EXPORTS XMLAAP : public IAAP
+ class XMLAAP : public IAAP
{
public:
XMLAAP(const char* pathname);
XMLAAPImpl* m_impl;
};
+ class ClubShibPOSTProfile : public ShibPOSTProfile
+ {
+ public:
+ ClubShibPOSTProfile(const saml::Iterator<const XMLCh*>& policies, const XMLCh* receiver, int ttlSeconds);
+ ClubShibPOSTProfile(const saml::Iterator<const XMLCh*>& policies, const XMLCh* issuer);
+ virtual ~ClubShibPOSTProfile();
+
+ virtual saml::SAMLResponse* prepare(
+ const XMLCh* recipient,
+ const XMLCh* name,
+ const XMLCh* nameQualifier,
+ const XMLCh* subjectIP,
+ const XMLCh* authMethod,
+ time_t authInstant,
+ const saml::Iterator<saml::SAMLAuthorityBinding*>& bindings,
+ XSECCryptoKey* responseKey,
+ const saml::Iterator<XSECCryptoX509*>& responseCerts=EMPTY(XSECCryptoX509*),
+ XSECCryptoKey* assertionKey=NULL,
+ const saml::Iterator<XSECCryptoX509*>& assertionCerts=EMPTY(XSECCryptoX509*)
+ );
+
+ protected:
+ virtual void verifySignature(
+ const saml::SAMLSignedObject& obj,
+ const IOriginSite* originSite,
+ const XMLCh* signerName,
+ XSECCryptoKey* knownKey=NULL);
+ };
+
+ class ShibSOAPBinding : public saml::SAMLSOAPBinding
+ {
+ public:
+ ShibSOAPBinding(const XMLCh* subject, const ISite* relyingParty) : m_subject(subject), m_relyingParty(relyingParty) {}
+ virtual ~ShibSOAPBinding() {}
+
+ virtual saml::SAMLResponse* send(
+ const saml::SAMLAuthorityBinding& bindingInfo,
+ saml::SAMLRequest& req,
+ saml::SAMLConfig::SAMLBindingConfig& conf=saml::SAMLConfig::getConfig().binding_defaults
+ );
+
+ private:
+ friend bool ssl_ctx_callback(void* ssl_ctx, void* userptr);
+ const XMLCh* m_subject;
+ const ISite* m_relyingParty;
+ };
+
class ShibInternalConfig : public ShibConfig
{
public:
void regFactory(const char* type, MetadataFactory* factory);
void regFactory(const char* type, TrustFactory* factory);
+ void regFactory(const char* type, CredentialsFactory* factory);
void regFactory(const char* type, AAPFactory* factory);
void regFactory(const char* type, saml::SAMLAttributeFactory* factory);
void unregFactory(const char* type);
saml::Iterator<IMetadata*> getMetadataProviders() const {return m_providers;}
saml::Iterator<ITrust*> getTrustProviders() const {return m_trust_providers;}
+ saml::Iterator<ICredentials*> getCredentialProviders() const {return m_cred_providers;}
saml::Iterator<IAAP*> getAAPProviders() const {return m_aap_providers;}
saml::SAMLAttributeFactory* getAttributeFactory(const char* type) const;
private:
friend class OriginMetadata;
friend class Trust;
+ friend class Credentials;
friend class AAP;
typedef std::map<std::string, MetadataFactory*> MetadataFactoryMap;
typedef std::map<std::string, TrustFactory*> TrustFactoryMap;
+ typedef std::map<std::string, CredentialsFactory*> CredentialsFactoryMap;
typedef std::map<std::string, AAPFactory*> AAPFactoryMap;
typedef std::map<std::string, saml::SAMLAttributeFactory*> AttributeFactoryMap;
MetadataFactoryMap m_metadataFactoryMap;
TrustFactoryMap m_trustFactoryMap;
+ CredentialsFactoryMap m_credFactoryMap;
AAPFactoryMap m_aapFactoryMap;
AttributeFactoryMap m_attrFactoryMap;
std::vector<IMetadata*> m_providers;
std::vector<ITrust*> m_trust_providers;
+ std::vector<ICredentials*> m_cred_providers;
std::vector<IAAP*> m_aap_providers;
};
+
+ // OpenSSL Utilities
+
+ // Custom metadata-driven SSL context callback
+ bool ssl_ctx_callback(void* ssl_ctx, void* userptr);
+
+ // Log errors from OpenSSL error queue
+ void log_openssl();
+
+ // build an OpenSSL cert out of a base-64 encoded DER buffer (XML style)
+ X509* B64_to_X509(const char* buf);
}
#endif
public:
ThreadKeyImpl(void (*destroy_fcn)(void*)) : destroy_hook(destroy_fcn) { key=TlsAlloc(); };
- virtual ~ThreadKeyImpl() { destroy_hook(TlsGetValue(key)); TlsFree(key); }
+ virtual ~ThreadKeyImpl() { if (destroy_hook) destroy_hook(TlsGetValue(key)); TlsFree(key); }
int setData(void* data) { TlsSetValue(key,data); return 0;}
void* getData() { return TlsGetValue(key); }
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
-# ADD LINK32 log4cpp.lib xerces-c_2.lib xsec_lib_02.lib libeay32.lib saml_4.lib /nologo /dll /machine:I386 /out:"Release/shib_5.dll" /libpath:"..\..\..\opensaml\c\saml\Release" /libpath:"\openssl-0.9.7b\out32dll"
+# ADD LINK32 log4cpp.lib xerces-c_2.lib xsec_lib_02.lib saml_4.lib libeay32.lib ssleay32.lib /nologo /dll /machine:I386 /out:"Release/shib_5.dll" /libpath:"..\..\..\opensaml\c\saml\Release" /libpath:"\openssl-0.9.7b\out32dll"
!ELSEIF "$(CFG)" == "shib - Win32 Debug"
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 log4cppD.lib xerces-c_2D.lib xsec_lib_02D.lib libeay32.lib saml_4D.lib /nologo /dll /debug /machine:I386 /out:"Debug/shib_5D.dll" /pdbtype:sept /libpath:"..\..\..\opensaml\c\saml\Debug" /libpath:"\openssl-0.9.7b\out32dll.dbg"
+# ADD LINK32 log4cppD.lib xerces-c_2D.lib xsec_lib_02D.lib saml_4D.lib libeay32.lib ssleay32.lib /nologo /dll /debug /machine:I386 /out:"Debug/shib_5D.dll" /pdbtype:sept /libpath:"..\..\..\opensaml\c\saml\Debug" /libpath:"\openssl-0.9.7b\out32dll.dbg"
!ENDIF
# End Source File
# Begin Source File
+SOURCE=.\ShibSOAPBinding.cpp
+# End Source File
+# Begin Source File
+
SOURCE=.\SimpleAttribute.cpp
# End Source File
# Begin Source File
# End Source File
# Begin Source File
+SOURCE=.\XMLCredentials.cpp
+# End Source File
+# Begin Source File
+
SOURCE=.\XMLMetadata.cpp
# End Source File
# Begin Source File
#define __shib_h__
#include <saml/saml.h>
-#include <openssl/x509.h>
+#include <openssl/ssl.h>
#ifdef WIN32
# ifndef SHIB_EXPORTS
namespace shibboleth
{
-#ifdef NO_RTTI
- extern SHIB_EXPORTS const unsigned short RTTI_UnsupportedProtocolException;
- extern SHIB_EXPORTS const unsigned short RTTI_OriginSiteMapperException;
-#endif
-
#define DECLARE_SHIB_EXCEPTION(name,base) \
class SHIB_EXPORTS name : public saml::base \
{ \
virtual saml::Iterator<XSECCryptoX509*> getCertificates(const XMLCh* subject) const=0;
virtual bool validate(const ISite* site, saml::Iterator<XSECCryptoX509*> certs) const=0;
virtual bool validate(const ISite* site, saml::Iterator<const XMLCh*> certs) const=0;
+ virtual bool attach(const ISite* site, SSL_CTX* ctx) const=0;
virtual ~ITrust() {}
};
+ struct SHIB_EXPORTS ICredentials
+ {
+ virtual void lock()=0;
+ virtual void unlock()=0;
+ virtual bool attach(const XMLCh* subject, const ISite* relyingParty, SSL_CTX* ctx) const=0;
+ virtual ~ICredentials() {}
+ };
+
struct SHIB_EXPORTS IAttributeRule
{
virtual const XMLCh* getName() const=0;
};
#ifdef SHIB_INSTANTIATE
-# ifdef NO_RTTI
- const unsigned short RTTI_UnsupportedProtocolException= RTTI_EXTENSION_BASE;
- const unsigned short RTTI_MetadataException= RTTI_EXTENSION_BASE+1;
-# endif
-// template class SHIB_EXPORTS saml::Iterator<std::pair<saml::xstring,bool> >;
-// template class SHIB_EXPORTS saml::ArrayIterator<std::pair<saml::xstring,bool> >;
template class SHIB_EXPORTS saml::Iterator<const IContactInfo*>;
template class SHIB_EXPORTS saml::ArrayIterator<const IContactInfo*>;
template class SHIB_EXPORTS saml::Iterator<const IAuthority*>;
template class SHIB_EXPORTS saml::ArrayIterator<IMetadata*>;
template class SHIB_EXPORTS saml::Iterator<ITrust*>;
template class SHIB_EXPORTS saml::ArrayIterator<ITrust*>;
+ template class SHIB_EXPORTS saml::Iterator<ICredentials*>;
+ template class SHIB_EXPORTS saml::ArrayIterator<ICredentials*>;
template class SHIB_EXPORTS saml::Iterator<IAAP*>;
template class SHIB_EXPORTS saml::ArrayIterator<IAAP*>;
#endif
ShibPOSTProfile& operator=(const ShibPOSTProfile&) {return *this;}
};
- class SHIB_EXPORTS ClubShibPOSTProfile : public ShibPOSTProfile
- {
- public:
- ClubShibPOSTProfile(const saml::Iterator<const XMLCh*>& policies, const XMLCh* receiver, int ttlSeconds);
- ClubShibPOSTProfile(const saml::Iterator<const XMLCh*>& policies, const XMLCh* issuer);
- virtual ~ClubShibPOSTProfile();
-
- virtual saml::SAMLResponse* prepare(
- const XMLCh* recipient,
- const XMLCh* name,
- const XMLCh* nameQualifier,
- const XMLCh* subjectIP,
- const XMLCh* authMethod,
- time_t authInstant,
- const saml::Iterator<saml::SAMLAuthorityBinding*>& bindings,
- XSECCryptoKey* responseKey,
- const saml::Iterator<XSECCryptoX509*>& responseCerts=EMPTY(XSECCryptoX509*),
- XSECCryptoKey* assertionKey=NULL,
- const saml::Iterator<XSECCryptoX509*>& assertionCerts=EMPTY(XSECCryptoX509*)
- );
-
- protected:
- virtual void verifySignature(
- const saml::SAMLSignedObject& obj,
- const IOriginSite* originSite,
- const XMLCh* signerName,
- XSECCryptoKey* knownKey=NULL);
- };
-
class SHIB_EXPORTS ShibPOSTProfileFactory
{
public:
saml::Iterator<XSECCryptoX509*> getCertificates(const XMLCh* subject);
bool validate(const ISite* site, saml::Iterator<XSECCryptoX509*> certs) const;
bool validate(const ISite* site, saml::Iterator<const XMLCh*> certs) const;
+ bool attach(const ISite* site, SSL_CTX* ctx) const;
private:
Trust(const Trust&);
void operator=(const Trust&);
ITrust* m_mapper;
};
+
+ class SHIB_EXPORTS Credentials
+ {
+ public:
+ static bool attach(const XMLCh* subject, const ISite* relyingParty, SSL_CTX* ctx);
+ };
class SHIB_EXPORTS AAP
{
extern "C" { typedef IMetadata* MetadataFactory(const char* source); }
extern "C" { typedef ITrust* TrustFactory(const char* source); }
+ extern "C" { typedef ICredentials* CredentialsFactory(const char* source); }
extern "C" { typedef IAAP* AAPFactory(const char* source); }
class SHIB_EXPORTS ShibConfig
// allows pluggable implementations of metadata
virtual void regFactory(const char* type, MetadataFactory* factory)=0;
virtual void regFactory(const char* type, TrustFactory* factory)=0;
+ virtual void regFactory(const char* type, CredentialsFactory* factory)=0;
virtual void regFactory(const char* type, AAPFactory* factory)=0;
virtual void regFactory(const char* type, saml::SAMLAttributeFactory* factory)=0;
virtual void unregFactory(const char* type)=0;
virtual saml::Iterator<IMetadata*> getMetadataProviders() const=0;
virtual saml::Iterator<ITrust*> getTrustProviders() const=0;
+ virtual saml::Iterator<ICredentials*> getCredentialProviders() const=0;
virtual saml::Iterator<IAAP*> getAAPProviders() const=0;
virtual saml::SAMLAttributeFactory* getAttributeFactory(const char* type) const=0;
};
{
static const XMLCh SHIB_ATTRIBUTE_NAMESPACE_URI[];
static const XMLCh SHIB_NAMEID_FORMAT_URI[];
+
+ static const XMLCh XMLSIG_RETMETHOD_RAWX509[]; // DER X.509 defined by xmlsig
+ static const XMLCh SHIB_RETMETHOD_PEMX509[]; // PEM cert chain
+ static const XMLCh SHIB_RETMETHOD_DERRSA[]; // PKCS1/DER RSA private key
+ static const XMLCh SHIB_RETMETHOD_PEMRSA[]; // PEM RSA private key
+
static saml::QName SHIB_ATTRIBUTE_VALUE_TYPE;
};
static const XMLCh OriginSite[];
static const XMLCh SiteGroup[];
+ static const XMLCh Credentials[];
+ static const XMLCh Exponent[];
static const XMLCh KeyAuthority[];
+ static const XMLCh KeyUse[];
+ static const XMLCh Modulus[];
+ static const XMLCh RelyingParty[];
+ static const XMLCh RetrievalMethod[];
+ static const XMLCh RSAKeyValue[];
static const XMLCh Trust[];
+ static const XMLCh URI[];
+ static const XMLCh VerifyDepth[];
static const XMLCh Accept[];
static const XMLCh Alias[];
};
};
-
class SHIB_EXPORTS SAMLBindingFactory
{
public:
- static saml::SAMLBinding* getInstance(const XMLCh* protocol=saml::SAMLBinding::SAML_SOAP_HTTPS);
+ static saml::SAMLBinding* getInstance(
+ const XMLCh* subject,
+ const ISite* relyingParty,
+ const XMLCh* protocol=saml::SAMLBinding::SAML_SOAP_HTTPS);
};
-
- // OpenSSL Utilities
-
- // Log errors from OpenSSL error queue.
- void log_openssl();
-
- // build an OpenSSL cert out of a base-64 encoded DER buffer (XML style)
- X509* B64_to_X509(const char* buf);
}
#endif