2 * The Shibboleth License, Version 1.
4 * University Corporation for Advanced Internet Development, Inc.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are met:
11 * Redistributions of source code must retain the above copyright notice, this
12 * list of conditions and the following disclaimer.
14 * Redistributions in binary form must reproduce the above copyright notice,
15 * this list of conditions and the following disclaimer in the documentation
16 * and/or other materials provided with the distribution, if any, must include
17 * the following acknowledgment: "This product includes software developed by
18 * the University Corporation for Advanced Internet Development
19 * <http://www.ucaid.edu>Internet2 Project. Alternately, this acknowledegement
20 * may appear in the software itself, if and wherever such third-party
21 * acknowledgments normally appear.
23 * Neither the name of Shibboleth nor the names of its contributors, nor
24 * Internet2, nor the University Corporation for Advanced Internet Development,
25 * Inc., nor UCAID may be used to endorse or promote products derived from this
26 * software without specific prior written permission. For written permission,
27 * please contact shibboleth@shibboleth.org
29 * Products derived from this software may not be called Shibboleth, Internet2,
30 * UCAID, or the University Corporation for Advanced Internet Development, nor
31 * may Shibboleth appear in their name, without prior written permission of the
32 * University Corporation for Advanced Internet Development.
35 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
36 * AND WITH ALL FAULTS. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
37 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
38 * PARTICULAR PURPOSE, AND NON-INFRINGEMENT ARE DISCLAIMED AND THE ENTIRE RISK
39 * OF SATISFACTORY QUALITY, PERFORMANCE, ACCURACY, AND EFFORT IS WITH LICENSEE.
40 * IN NO EVENT SHALL THE COPYRIGHT OWNER, CONTRIBUTORS OR THE UNIVERSITY
41 * CORPORATION FOR ADVANCED INTERNET DEVELOPMENT, INC. BE LIABLE FOR ANY DIRECT,
42 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
43 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
44 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
45 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
46 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
47 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
51 /* shib.h - Shibboleth header file
62 #include <saml/saml.h>
63 #include <shib/shib-threads.h>
67 # define SHIB_EXPORTS __declspec(dllimport)
75 #define DECLARE_SHIB_EXCEPTION(name,base) \
76 class SHIB_EXPORTS name : public saml::base \
79 name(const char* msg) : saml::base(msg) {RTTI(name);} \
80 name(const std::string& msg) : saml::base(msg) {RTTI(name);} \
81 name(const saml::Iterator<saml::QName>& codes, const char* msg) : saml::base(codes,msg) {RTTI(name);} \
82 name(const saml::Iterator<saml::QName>& codes, const std::string& msg) : saml::base(codes, msg) {RTTI(name);} \
83 name(const saml::QName& code, const char* msg) : saml::base(code,msg) {RTTI(name);} \
84 name(const saml::QName& code, const std::string& msg) : saml::base(code, msg) {RTTI(name);} \
85 name(DOMElement* e) : saml::base(e) {RTTI(name);} \
86 name(std::istream& in) : saml::base(in) {RTTI(name);} \
87 virtual ~name() throw () {} \
90 DECLARE_SHIB_EXCEPTION(MetadataException,SAMLException);
91 DECLARE_SHIB_EXCEPTION(CredentialException,SAMLException);
92 DECLARE_SHIB_EXCEPTION(InvalidHandleException,RetryableProfileException);
94 // Manages pluggable implementations of interfaces
95 // Would prefer this to be a template, but the Windows STL isn't DLL-safe.
97 struct SHIB_EXPORTS IPlugIn
102 class SHIB_EXPORTS PlugManager
108 typedef IPlugIn* Factory(const DOMElement* source);
109 void regFactory(const char* type, Factory* factory);
110 void unregFactory(const char* type);
111 IPlugIn* newPlugin(const char* type, const DOMElement* source);
114 typedef std::map<std::string, Factory*> FactoryMap;
118 // Metadata abstract interfaces, inching toward SAML 2.0...
120 struct SHIB_EXPORTS ILockable
122 virtual void lock()=0;
123 virtual void unlock()=0;
124 virtual ~ILockable() {}
127 struct SHIB_EXPORTS IContactPerson
129 enum ContactType { technical, support, administrative, billing, other };
130 virtual ContactType getType() const=0;
131 virtual const char* getCompany() const=0;
132 virtual const char* getName() const=0;
133 virtual saml::Iterator<std::string> getEmails() const=0;
134 virtual saml::Iterator<std::string> getTelephones() const=0;
135 virtual const DOMElement* getElement() const=0;
136 virtual ~IContactPerson() {}
139 struct SHIB_EXPORTS IOrganization
141 virtual const char* getName(const char* lang) const=0;
142 virtual const char* getDisplayName(const char* lang) const=0;
143 virtual const char* getURL(const char* lang) const=0;
144 virtual const DOMElement* getElement() const=0;
145 virtual ~IOrganization() {}
148 struct SHIB_EXPORTS IKeyDescriptor
150 enum KeyUse { encryption, signing };
151 virtual KeyUse getUse() const=0;
152 virtual const XMLCh* getEncryptionMethod() const=0;
153 virtual int getKeySize() const=0;
154 virtual DSIGKeyInfoList* getKeyInfo() const=0;
155 virtual const DOMElement* getElement() const=0;
156 virtual ~IKeyDescriptor() {}
159 struct SHIB_EXPORTS IEndpoint
161 virtual const XMLCh* getBinding() const=0;
162 virtual const XMLCh* getVersion() const=0;
163 virtual const XMLCh* getLocation() const=0;
164 virtual const XMLCh* getResponseLocation() const=0;
165 virtual const DOMElement* getElement() const=0;
166 virtual ~IEndpoint() {}
169 struct SHIB_EXPORTS IProvider;
170 struct SHIB_EXPORTS IProviderRole
172 virtual const IProvider* getProvider() const=0;
173 virtual saml::Iterator<const XMLCh*> getProtocolSupportEnumeration() const=0;
174 virtual bool hasSupport(const XMLCh* version) const=0;
175 virtual saml::Iterator<const IKeyDescriptor*> getKeyDescriptors() const=0;
176 virtual const IOrganization* getOrganization() const=0;
177 virtual saml::Iterator<const IContactPerson*> getContacts() const=0;
178 virtual saml::Iterator<const IEndpoint*> getDefaultEndpoints() const=0;
179 virtual const char* getErrorURL() const=0;
180 virtual const DOMElement* getElement() const=0;
181 virtual ~IProviderRole() {}
184 struct SHIB_EXPORTS ISSOProviderRole : public virtual IProviderRole
186 virtual saml::Iterator<const IEndpoint*> getSingleLogoutServices() const=0;
187 virtual saml::Iterator<const IEndpoint*> getManageNameIdentifierServices() const=0;
188 virtual ~ISSOProviderRole() {}
191 struct SHIB_EXPORTS IIDPProviderRole : public virtual ISSOProviderRole
193 virtual saml::Iterator<const IEndpoint*> getSingleSignOnServices() const=0;
194 virtual ~IIDPProviderRole() {}
197 struct SHIB_EXPORTS ISPProviderRole : public virtual ISSOProviderRole
199 virtual bool getAuthnRequestsSigned() const=0;
200 virtual const IEndpoint* getDefaultAssertionConsumerServiceURL() const=0;
201 virtual const IEndpoint* getAssertionConsumerServiceURL(const XMLCh* id) const=0;
202 virtual ~ISPProviderRole() {}
205 struct SHIB_EXPORTS IPDPProviderRole : public virtual IProviderRole
207 virtual saml::Iterator<const IEndpoint*> getAuthorizationServices() const=0;
208 virtual ~IPDPProviderRole() {}
211 struct SHIB_EXPORTS IAttributeAuthorityRole : public virtual IProviderRole
213 virtual saml::Iterator<const IEndpoint*> getAttributeServices() const=0;
214 virtual ~IAttributeAuthorityRole() {}
217 struct SHIB_EXPORTS IAttributeRequestingService
219 virtual const XMLCh* getName(const XMLCh* lang) const=0;
220 virtual const XMLCh* getDescription(const XMLCh* lang) const=0;
221 virtual saml::Iterator<std::pair<const saml::SAMLAttributeDesignator*,bool> > getWantedAttributes() const=0;
222 virtual const DOMElement* getElement() const=0;
223 virtual ~IAttributeRequestingService() {}
226 struct SHIB_EXPORTS IAttributeRequesterRole : public virtual IProviderRole
228 virtual const IAttributeRequestingService* getDefaultAttributeRequestingService() const=0;
229 virtual const IAttributeRequestingService* getAttributeRequestingService(const XMLCh* id) const=0;
230 virtual saml::Iterator<const IAttributeRequestingService*> getAttributeRequestingServices() const=0;
231 virtual ~IAttributeRequesterRole() {}
234 struct SHIB_EXPORTS IProvider
236 virtual const XMLCh* getId() const=0;
237 virtual saml::Iterator<const XMLCh*> getGroups() const=0;
238 virtual const IOrganization* getOrganization() const=0;
239 virtual saml::Iterator<const IContactPerson*> getContacts() const=0;
240 virtual saml::Iterator<const IProviderRole*> getRoles() const=0;
241 virtual const DOMElement* getElement() const=0;
242 virtual saml::Iterator<std::pair<const XMLCh*,bool> > getSecurityDomains() const=0;
243 virtual ~IProvider() {}
246 struct SHIB_EXPORTS IMetadata : public virtual ILockable, public virtual IPlugIn
248 virtual const IProvider* lookup(const XMLCh* providerId) const=0;
249 virtual ~IMetadata() {}
252 struct SHIB_EXPORTS IRevocation : public virtual ILockable, public virtual IPlugIn
254 virtual saml::Iterator<void*> getRevocationLists(const IProvider* provider, const IProviderRole* role=NULL) const=0;
255 virtual ~IRevocation() {}
258 // Trust interface hides *all* details of signature and SSL validation.
259 // Pluggable providers can fully override the Shibboleth trust model here.
261 struct SHIB_EXPORTS ITrust : public virtual IPlugIn
263 virtual bool validate(
264 const saml::Iterator<IRevocation*>& revocations,
265 const IProviderRole* role, const saml::SAMLSignedObject& token,
266 const saml::Iterator<IMetadata*>& metadatas=EMPTY(IMetadata*)
268 virtual bool attach(const saml::Iterator<IRevocation*>& revocations, const IProviderRole* role, void* ctx)=0;
272 struct SHIB_EXPORTS ICredResolver : public virtual IPlugIn
274 virtual void attach(void* ctx) const=0;
275 virtual XSECCryptoKey* getKey() const=0;
276 virtual saml::Iterator<XSECCryptoX509*> getCertificates() const=0;
277 virtual void dump(FILE* f) const=0;
278 virtual void dump() const { dump(stdout); }
279 virtual ~ICredResolver() {}
282 struct SHIB_EXPORTS ICredentials : public virtual ILockable, public virtual IPlugIn
284 virtual const ICredResolver* lookup(const char* id) const=0;
285 virtual ~ICredentials() {}
288 struct SHIB_EXPORTS IAttributeRule
290 virtual const XMLCh* getName() const=0;
291 virtual const XMLCh* getNamespace() const=0;
292 virtual const char* getFactory() const=0;
293 virtual const char* getAlias() const=0;
294 virtual const char* getHeader() const=0;
295 virtual void apply(const IProvider* originSite, saml::SAMLAttribute& attribute) const=0;
296 virtual ~IAttributeRule() {}
299 struct SHIB_EXPORTS IAAP : public virtual ILockable, public virtual IPlugIn
301 virtual const IAttributeRule* lookup(const XMLCh* attrName, const XMLCh* attrNamespace=NULL) const=0;
302 virtual const IAttributeRule* lookup(const char* alias) const=0;
303 virtual saml::Iterator<const IAttributeRule*> getAttributeRules() const=0;
307 #ifdef SHIB_INSTANTIATE
308 template class SHIB_EXPORTS saml::Iterator<const IContactPerson*>;
309 template class SHIB_EXPORTS saml::Iterator<const IProviderRole*>;
310 template class SHIB_EXPORTS saml::Iterator<const IKeyDescriptor*>;
311 template class SHIB_EXPORTS saml::Iterator<const IEndpoint*>;
312 template class SHIB_EXPORTS saml::Iterator<const IAttributeRule*>;
313 template class SHIB_EXPORTS saml::Iterator<IMetadata*>;
314 template class SHIB_EXPORTS saml::ArrayIterator<IMetadata*>;
315 template class SHIB_EXPORTS saml::Iterator<ITrust*>;
316 template class SHIB_EXPORTS saml::ArrayIterator<ITrust*>;
317 template class SHIB_EXPORTS saml::Iterator<IRevocation*>;
318 template class SHIB_EXPORTS saml::ArrayIterator<IRevocation*>;
319 template class SHIB_EXPORTS saml::Iterator<ICredentials*>;
320 template class SHIB_EXPORTS saml::ArrayIterator<ICredentials*>;
321 template class SHIB_EXPORTS saml::Iterator<IAAP*>;
322 template class SHIB_EXPORTS saml::ArrayIterator<IAAP*>;
325 struct SHIB_EXPORTS Constants
327 static const XMLCh SHIB_ATTRIBUTE_NAMESPACE_URI[];
328 static const XMLCh SHIB_NAMEID_FORMAT_URI[];
329 static const XMLCh SHIB_NS[];
330 static const XMLCh InvalidHandle[];
333 // Glue classes between abstract metadata and concrete providers
335 class SHIB_EXPORTS Locker
338 Locker(ILockable* lockee) : m_lockee(lockee) {m_lockee->lock();}
339 ~Locker() {if (m_lockee) m_lockee->unlock();}
342 Locker(const Locker&);
343 void operator=(const Locker&);
347 class SHIB_EXPORTS Metadata
350 Metadata(const saml::Iterator<IMetadata*>& metadatas) : m_metadatas(metadatas), m_mapper(NULL) {}
353 const IProvider* lookup(const XMLCh* providerId);
356 Metadata(const Metadata&);
357 void operator=(const Metadata&);
359 const saml::Iterator<IMetadata*>& m_metadatas;
362 class SHIB_EXPORTS Revocation
365 Revocation(const saml::Iterator<IRevocation*>& revocations) : m_revocations(revocations), m_mapper(NULL) {}
368 saml::Iterator<void*> getRevocationLists(const IProvider* provider, const IProviderRole* role=NULL);
371 Revocation(const Revocation&);
372 void operator=(const Revocation&);
373 IRevocation* m_mapper;
374 const saml::Iterator<IRevocation*>& m_revocations;
377 class SHIB_EXPORTS Trust
380 Trust(const saml::Iterator<ITrust*>& trusts) : m_trusts(trusts) {}
384 const saml::Iterator<IRevocation*>& revocations,
385 const IProviderRole* role, const saml::SAMLSignedObject& token,
386 const saml::Iterator<IMetadata*>& metadatas=EMPTY(IMetadata*)
388 bool attach(const saml::Iterator<IRevocation*>& revocations, const IProviderRole* role, void* ctx) const;
392 void operator=(const Trust&);
393 const saml::Iterator<ITrust*>& m_trusts;
396 class SHIB_EXPORTS Credentials
399 Credentials(const saml::Iterator<ICredentials*>& creds) : m_creds(creds), m_mapper(NULL) {}
402 const ICredResolver* lookup(const char* id);
405 Credentials(const Credentials&);
406 void operator=(const Credentials&);
407 ICredentials* m_mapper;
408 const saml::Iterator<ICredentials*>& m_creds;
411 class SHIB_EXPORTS AAP
414 AAP(const saml::Iterator<IAAP*>& aaps, const XMLCh* attrName, const XMLCh* attrNamespace=NULL);
415 AAP(const saml::Iterator<IAAP*>& aaps, const char* alias);
417 bool fail() const {return m_mapper==NULL;}
418 const IAttributeRule* operator->() const {return m_rule;}
419 operator const IAttributeRule*() const {return m_rule;}
421 static void apply(const saml::Iterator<IAAP*>& aaps, const IProvider* originSite, saml::SAMLAssertion& assertion);
425 void operator=(const AAP&);
427 const IAttributeRule* m_rule;
430 // Wrapper classes around the POST profile and SAML binding
432 class SHIB_EXPORTS ShibPOSTProfile
436 const saml::Iterator<IMetadata*>& metadatas=EMPTY(IMetadata*),
437 const saml::Iterator<IRevocation*>& revocations=EMPTY(IRevocation*),
438 const saml::Iterator<ITrust*>& trusts=EMPTY(ITrust*),
439 const saml::Iterator<ICredentials*>& creds=EMPTY(ICredentials*)
441 virtual ~ShibPOSTProfile() {}
443 virtual const saml::SAMLAssertion* getSSOAssertion(
444 const saml::SAMLResponse& r, const saml::Iterator<const XMLCh*>& audiences=EMPTY(const XMLCh*)
446 virtual const saml::SAMLAuthenticationStatement* getSSOStatement(const saml::SAMLAssertion& a);
447 virtual saml::SAMLResponse* accept(
449 const XMLCh* recipient,
451 const saml::Iterator<const XMLCh*>& audiences=EMPTY(const XMLCh*),
452 XMLCh** pproviderId=NULL
454 virtual saml::SAMLResponse* prepare(
455 const IIDPProviderRole* role,
456 const char* credResolverId,
457 const XMLCh* recipient,
458 const XMLCh* authMethod,
461 const XMLCh* format=Constants::SHIB_NAMEID_FORMAT_URI,
462 const XMLCh* nameQualifier=NULL,
463 const XMLCh* subjectIP=NULL,
464 const saml::Iterator<const XMLCh*>& audiences=EMPTY(const XMLCh*),
465 const saml::Iterator<saml::SAMLAuthorityBinding*>& bindings=EMPTY(saml::SAMLAuthorityBinding*)
467 virtual bool checkReplayCache(const saml::SAMLAssertion& a);
468 virtual const XMLCh* getProviderId(const saml::SAMLResponse& r);
471 const saml::Iterator<IMetadata*>& m_metadatas;
472 const saml::Iterator<IRevocation*>& m_revocations;
473 const saml::Iterator<ITrust*>& m_trusts;
474 const saml::Iterator<ICredentials*>& m_creds;
477 class SHIB_EXPORTS ShibBinding
481 const saml::Iterator<IRevocation*>& revocations,
482 const saml::Iterator<ITrust*>& trusts,
483 const saml::Iterator<ICredentials*>& creds
484 ) : m_revocations(revocations), m_trusts(trusts), m_creds(creds),
485 m_credResolverId(NULL), m_AA(NULL), m_binding(NULL) {}
486 virtual ~ShibBinding() {delete m_binding;}
488 saml::SAMLResponse* send(
489 saml::SAMLRequest& req,
490 const IAttributeAuthorityRole* AA,
491 const char* credResolverId=NULL,
492 const saml::Iterator<const XMLCh*>& audiences=EMPTY(const XMLCh*),
493 const saml::Iterator<saml::SAMLAuthorityBinding*>& bindings=EMPTY(saml::SAMLAuthorityBinding*),
494 saml::SAMLConfig::SAMLBindingConfig& conf=saml::SAMLConfig::getConfig().binding_defaults
498 friend bool ssl_ctx_callback(void* ssl_ctx, void* userptr);
499 const saml::Iterator<IRevocation*>& m_revocations;
500 const saml::Iterator<ITrust*>& m_trusts;
501 const saml::Iterator<ICredentials*>& m_creds;
502 const char* m_credResolverId;
503 const IAttributeAuthorityRole* m_AA;
504 saml::SAMLBinding* m_binding;
507 class SHIB_EXPORTS ShibConfig
511 virtual ~ShibConfig() {}
513 // global per-process setup and shutdown of Shibboleth runtime
517 // enables runtime and clients to access configuration
518 static ShibConfig& getConfig();
520 // allows pluggable implementations of metadata and configuration data
521 PlugManager m_plugMgr;
524 /* Helper classes for implementing reloadable XML-based config files
525 The ILockable interface will usually be inherited twice, once as
526 part of the external interface to clients and once as an implementation
527 detail of the reloading class below.
530 class SHIB_EXPORTS ReloadableXMLFileImpl
533 ReloadableXMLFileImpl(const char* pathname);
534 ReloadableXMLFileImpl(const DOMElement* pathname);
535 virtual ~ReloadableXMLFileImpl();
539 const DOMElement* m_root;
542 class SHIB_EXPORTS ReloadableXMLFile : protected virtual ILockable
545 ReloadableXMLFile(const DOMElement* e);
546 ~ReloadableXMLFile() { delete m_lock; delete m_impl; }
549 virtual void unlock() { if (m_lock) m_lock->unlock(); }
551 ReloadableXMLFileImpl* getImplementation() const;
554 virtual ReloadableXMLFileImpl* newImplementation(const char* pathname, bool first=true) const=0;
555 virtual ReloadableXMLFileImpl* newImplementation(const DOMElement* e, bool first=true) const=0;
556 mutable ReloadableXMLFileImpl* m_impl;
559 const DOMElement* m_root;
560 std::string m_source;