Pull in Apache 2.2 module.
[shibboleth/cpp-sp.git] / shib / shib.h
1 /*
2  *  Copyright 2001-2005 Internet2
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 /* shib.h - Shibboleth header file
18
19    Scott Cantor
20    6/4/02
21
22    $History:$
23 */
24
25 #ifndef __shib_h__
26 #define __shib_h__
27
28 #include <saml/saml.h>
29 #include <shib/shib-threads.h>
30 #include <xsec/xenc/XENCEncryptionMethod.hpp>
31
32 #ifdef WIN32
33 # ifndef SHIB_EXPORTS
34 #  define SHIB_EXPORTS __declspec(dllimport)
35 # endif
36 #else
37 # define SHIB_EXPORTS
38 #endif
39
40 namespace shibboleth
41 {
42     DECLARE_SAML_EXCEPTION(SHIB_EXPORTS,ResourceAccessException,SAMLException);
43     DECLARE_SAML_EXCEPTION(SHIB_EXPORTS,MetadataException,SAMLException);
44     DECLARE_SAML_EXCEPTION(SHIB_EXPORTS,CredentialException,SAMLException);
45     DECLARE_SAML_EXCEPTION(SHIB_EXPORTS,InvalidHandleException,SAMLException);
46     DECLARE_SAML_EXCEPTION(SHIB_EXPORTS,InvalidSessionException,RetryableProfileException);
47
48     // Metadata abstract interfaces, based on SAML 2.0
49     
50     struct SHIB_EXPORTS IContactPerson
51     {
52         enum ContactType { technical, support, administrative, billing, other };
53         virtual ContactType getType() const=0;
54         virtual const char* getCompany() const=0;
55         virtual const char* getGivenName() const=0;
56         virtual const char* getSurName() const=0;
57         virtual saml::Iterator<std::string> getEmailAddresses() const=0;
58         virtual saml::Iterator<std::string> getTelephoneNumbers() const=0;
59         virtual const DOMElement* getElement() const=0;
60         virtual ~IContactPerson() {}
61     };
62
63     struct SHIB_EXPORTS IOrganization
64     {
65         virtual const char* getName(const char* lang="en") const=0;
66         virtual const char* getDisplayName(const char* lang="en") const=0;
67         virtual const char* getURL(const char* lang="en") const=0;
68         virtual const DOMElement* getElement() const=0;
69         virtual ~IOrganization() {}
70     };
71     
72     struct SHIB_EXPORTS IKeyDescriptor
73     {
74         enum KeyUse { unspecified, encryption, signing };
75         virtual KeyUse getUse() const=0;
76         virtual DSIGKeyInfoList* getKeyInfo() const=0;
77         virtual saml::Iterator<const XENCEncryptionMethod*> getEncryptionMethods() const=0;
78         virtual ~IKeyDescriptor() {}
79     };
80
81     struct SHIB_EXPORTS IEndpoint
82     {
83         virtual const XMLCh* getBinding() const=0;
84         virtual const XMLCh* getLocation() const=0;
85         virtual const XMLCh* getResponseLocation() const=0;
86         virtual const DOMElement* getElement() const=0;
87         virtual ~IEndpoint() {}
88     };
89
90     struct SHIB_EXPORTS IIndexedEndpoint : public virtual IEndpoint
91     {
92         virtual unsigned short getIndex() const=0;
93         virtual ~IIndexedEndpoint() {}
94     };
95     
96     struct SHIB_EXPORTS IEndpointManager
97     {
98         virtual saml::Iterator<const IEndpoint*> getEndpoints() const=0;
99         virtual const IEndpoint* getDefaultEndpoint() const=0;
100         virtual const IEndpoint* getEndpointByIndex(unsigned short index) const=0;
101         virtual const IEndpoint* getEndpointByBinding(const XMLCh* binding) const=0;
102         virtual ~IEndpointManager() {}
103     };
104
105     struct SHIB_EXPORTS IEntityDescriptor;
106     struct SHIB_EXPORTS IRoleDescriptor
107     {
108         virtual const IEntityDescriptor* getEntityDescriptor() const=0;
109         virtual saml::Iterator<const XMLCh*> getProtocolSupportEnumeration() const=0;
110         virtual bool hasSupport(const XMLCh* protocol) const=0;
111         virtual bool isValid() const=0;
112         virtual const char* getErrorURL() const=0;
113         virtual saml::Iterator<const IKeyDescriptor*> getKeyDescriptors() const=0;
114         virtual const IOrganization* getOrganization() const=0;
115         virtual saml::Iterator<const IContactPerson*> getContactPersons() const=0;
116         virtual const DOMElement* getElement() const=0;
117         virtual ~IRoleDescriptor() {}
118     };
119
120     struct SHIB_EXPORTS ISSODescriptor : public virtual IRoleDescriptor
121     {
122         virtual const IEndpointManager* getArtifactResolutionServiceManager() const=0;
123         virtual const IEndpointManager* getSingleLogoutServiceManager() const=0;
124         virtual const IEndpointManager* getManageNameIDServiceManager() const=0;
125         virtual saml::Iterator<const XMLCh*> getNameIDFormats() const=0;
126         virtual ~ISSODescriptor() {}
127     };
128     
129     struct SHIB_EXPORTS IIDPSSODescriptor : public virtual ISSODescriptor
130     {
131         virtual bool getWantAuthnRequestsSigned() const=0;
132         virtual const IEndpointManager* getSingleSignOnServiceManager() const=0;
133         virtual const IEndpointManager* getNameIDMappingServiceManager() const=0;
134         virtual const IEndpointManager* getAssertionIDRequestServiceManager() const=0;
135         virtual saml::Iterator<const XMLCh*> getAttributeProfiles() const=0;
136         virtual saml::Iterator<const saml::SAMLAttribute*> getAttributes() const=0;
137         virtual ~IIDPSSODescriptor() {}
138     };
139     
140     struct SHIB_EXPORTS IAttributeConsumingService
141     {
142         virtual const XMLCh* getName(const char* lang="en") const=0;
143         virtual const XMLCh* getDescription(const char* lang="en") const=0;
144         virtual saml::Iterator<std::pair<const saml::SAMLAttribute*,bool> > getRequestedAttributes() const=0;
145         virtual ~IAttributeConsumingService() {}
146     };
147
148     struct SHIB_EXPORTS ISPSSODescriptor : public virtual ISSODescriptor
149     {
150         virtual bool getAuthnRequestsSigned() const=0;
151         virtual bool getWantAssertionsSigned() const=0;
152         virtual const IEndpointManager* getAssertionConsumerServiceManager() const=0;
153         virtual saml::Iterator<const IAttributeConsumingService*> getAttributeConsumingServices() const=0;
154         virtual const IAttributeConsumingService* getDefaultAttributeConsumingService() const=0;
155         virtual const IAttributeConsumingService* getAttributeConsumingServiceByID(const XMLCh* id) const=0;
156         virtual ~ISPSSODescriptor() {}
157     };
158
159     struct SHIB_EXPORTS IAuthnAuthorityDescriptor : public virtual IRoleDescriptor
160     {
161         virtual const IEndpointManager* getAuthnQueryServiceManager() const=0;
162         virtual const IEndpointManager* getAssertionIDRequestServiceManager() const=0;
163         virtual saml::Iterator<const XMLCh*> getNameIDFormats() const=0;
164         virtual ~IAuthnAuthorityDescriptor() {}
165     };
166
167     struct SHIB_EXPORTS IPDPDescriptor : public virtual IRoleDescriptor
168     {
169         virtual const IEndpointManager* getAuthzServiceManager() const=0;
170         virtual const IEndpointManager* getAssertionIDRequestServiceManager() const=0;
171         virtual saml::Iterator<const XMLCh*> getNameIDFormats() const=0;
172         virtual ~IPDPDescriptor() {}
173     };
174
175     struct SHIB_EXPORTS IAttributeAuthorityDescriptor : public virtual IRoleDescriptor
176     {
177         virtual const IEndpointManager* getAttributeServiceManager() const=0;
178         virtual const IEndpointManager* getAssertionIDRequestServiceManager() const=0;
179         virtual saml::Iterator<const XMLCh*> getNameIDFormats() const=0;
180         virtual saml::Iterator<const XMLCh*> getAttributeProfiles() const=0;
181         virtual saml::Iterator<const saml::SAMLAttribute*> getAttributes() const=0;
182         virtual ~IAttributeAuthorityDescriptor() {}
183     };
184     
185     struct SHIB_EXPORTS IAffiliationDescriptor
186     {
187         virtual const IEntityDescriptor* getEntityDescriptor() const=0;
188         virtual const XMLCh* getOwnerID() const=0;
189         virtual bool isValid() const=0;
190         virtual saml::Iterator<const XMLCh*> getMembers() const=0;
191         virtual bool isMember(const XMLCh* id) const=0;
192         virtual saml::Iterator<const IKeyDescriptor*> getKeyDescriptors() const=0;
193         virtual const DOMElement* getElement() const=0;
194         virtual ~IAffiliationDescriptor() {}
195     };
196
197     struct SHIB_EXPORTS IEntitiesDescriptor;
198     struct SHIB_EXPORTS IEntityDescriptor
199     {
200         virtual const XMLCh* getId() const=0;
201         virtual bool isValid() const=0;
202         virtual saml::Iterator<const IRoleDescriptor*> getRoleDescriptors() const=0;
203         virtual const IIDPSSODescriptor* getIDPSSODescriptor(const XMLCh* protocol) const=0;
204         virtual const ISPSSODescriptor* getSPSSODescriptor(const XMLCh* protocol) const=0;
205         virtual const IAuthnAuthorityDescriptor* getAuthnAuthorityDescriptor(const XMLCh* protocol) const=0;
206         virtual const IAttributeAuthorityDescriptor* getAttributeAuthorityDescriptor(const XMLCh* protocol) const=0;
207         virtual const IPDPDescriptor* getPDPDescriptor(const XMLCh* protocol) const=0;
208         virtual const IAffiliationDescriptor* getAffiliationDescriptor() const=0;
209         virtual const IOrganization* getOrganization() const=0;
210         virtual saml::Iterator<const IContactPerson*> getContactPersons() const=0;
211         virtual saml::Iterator<std::pair<const XMLCh*,const XMLCh*> > getAdditionalMetadataLocations() const=0;
212         virtual const IEntitiesDescriptor* getEntitiesDescriptor() const=0;
213         virtual const DOMElement* getElement() const=0;
214         virtual ~IEntityDescriptor() {}
215     };
216     
217     struct SHIB_EXPORTS IEntitiesDescriptor
218     {
219         virtual const XMLCh* getName() const=0;
220         virtual bool isValid() const=0;
221         virtual const IEntitiesDescriptor* getEntitiesDescriptor() const=0;
222         virtual saml::Iterator<const IEntitiesDescriptor*> getEntitiesDescriptors() const=0;
223         virtual saml::Iterator<const IEntityDescriptor*> getEntityDescriptors() const=0;
224         virtual const DOMElement* getElement() const=0;
225         virtual ~IEntitiesDescriptor() {}
226     };
227     
228     // Shib extension interfaces
229     struct SHIB_EXPORTS IKeyAuthority
230     {
231         virtual int getVerifyDepth() const=0;
232         virtual saml::Iterator<DSIGKeyInfoList*> getKeyInfos() const=0;
233         virtual ~IKeyAuthority() {}
234     };
235     
236     struct SHIB_EXPORTS IExtendedEntityDescriptor : public virtual IEntityDescriptor
237     {
238         virtual saml::Iterator<const IKeyAuthority*> getKeyAuthorities() const=0;
239         virtual saml::Iterator<std::pair<const XMLCh*,bool> > getScopes() const=0;
240         virtual ~IExtendedEntityDescriptor() {}
241     };
242
243     struct SHIB_EXPORTS IExtendedEntitiesDescriptor : public virtual IEntitiesDescriptor
244     {
245         virtual saml::Iterator<const IKeyAuthority*> getKeyAuthorities() const=0;
246         virtual ~IExtendedEntitiesDescriptor() {}
247     };
248        
249     struct SHIB_EXPORTS IMetadata : public virtual saml::ILockable, public virtual saml::IPlugIn
250     {
251         virtual const IEntityDescriptor* lookup(const char* id, bool strict=true) const=0;
252         virtual const IEntityDescriptor* lookup(const XMLCh* id, bool strict=true) const=0;
253         virtual const IEntityDescriptor* lookup(const saml::SAMLArtifact* artifact) const=0;
254         virtual const IEntitiesDescriptor* lookupGroup(const char* name, bool strict=true) const=0;
255         virtual const IEntitiesDescriptor* lookupGroup(const XMLCh* name, bool strict=true) const=0;
256         virtual std::pair<const IEntitiesDescriptor*,const IEntityDescriptor*> getRoot() const=0;
257         virtual ~IMetadata() {}
258     };
259
260     // Trust interface hides *all* details of signature and SSL validation.
261     // Pluggable providers can fully override the Shibboleth trust model here.
262     
263     struct SHIB_EXPORTS ITrust : public virtual saml::IPlugIn
264     {
265         // Performs certificate validation processing of an untrusted certificates
266         // using a library-specific representation, in this case an OpenSSL X509*
267         virtual bool validate(
268             void* certEE,
269             const saml::Iterator<void*>& certChain,
270             const IRoleDescriptor* role,
271             bool checkName=true
272             )=0;
273
274         // Validates signed SAML messages and assertions sent by an entity acting in a specific role.
275         // If certificate validation is required, the trust provider used can be overridden using
276         // the last parameter, or left null and the provider will rely on itself.
277         virtual bool validate(
278             const saml::SAMLSignedObject& token,
279             const IRoleDescriptor* role,
280             ITrust* certValidator=NULL
281             )=0;
282         
283         virtual ~ITrust() {}
284     };
285
286     // Credentials interface abstracts access to "owned" keys and certificates.
287     
288     struct SHIB_EXPORTS ICredResolver : public virtual saml::IPlugIn
289     {
290         virtual void attach(void* ctx) const=0;
291         virtual XSECCryptoKey* getKey() const=0;
292         virtual saml::Iterator<XSECCryptoX509*> getCertificates() const=0;
293         virtual void dump(FILE* f) const=0;
294         virtual void dump() const { dump(stdout); }
295         virtual ~ICredResolver() {}
296     };
297
298     struct SHIB_EXPORTS ICredentials : public virtual saml::ILockable, public virtual saml::IPlugIn
299     {
300         virtual const ICredResolver* lookup(const char* id) const=0;
301         virtual ~ICredentials() {}
302     };
303     
304     // Attribute acceptance processing interfaces, applied to incoming attributes.
305
306     struct SHIB_EXPORTS IAttributeRule
307     {
308         virtual const XMLCh* getName() const=0;
309         virtual const XMLCh* getNamespace() const=0;
310         virtual const char* getAlias() const=0;
311         virtual const char* getHeader() const=0;
312         virtual bool getCaseSensitive() const=0;
313         virtual void apply(saml::SAMLAttribute& attribute, const IEntityDescriptor* source=NULL) const=0;
314         virtual ~IAttributeRule() {}
315     };
316     
317     struct SHIB_EXPORTS IAAP : public virtual saml::ILockable, public virtual saml::IPlugIn
318     {
319         virtual bool anyAttribute() const=0;
320         virtual const IAttributeRule* lookup(const XMLCh* attrName, const XMLCh* attrNamespace=NULL) const=0;
321         virtual const IAttributeRule* lookup(const char* alias) const=0;
322         virtual saml::Iterator<const IAttributeRule*> getAttributeRules() const=0;
323         virtual ~IAAP() {}
324     };
325     
326     struct SHIB_EXPORTS IAttributeFactory : public virtual saml::IPlugIn
327     {
328         virtual saml::SAMLAttribute* build(DOMElement* e) const=0;
329         virtual ~IAttributeFactory() {}
330     };
331
332 #ifdef SHIB_INSTANTIATE
333     template class SHIB_EXPORTS saml::Iterator<const IContactPerson*>;
334     template class SHIB_EXPORTS saml::Iterator<const XENCEncryptionMethod*>;
335     template class SHIB_EXPORTS saml::Iterator<const IKeyDescriptor*>;
336     template class SHIB_EXPORTS saml::Iterator<const IAttributeConsumingService*>;
337     template class SHIB_EXPORTS saml::Iterator<const IRoleDescriptor*>;
338     template class SHIB_EXPORTS saml::Iterator<const IEntityDescriptor*>;
339     template class SHIB_EXPORTS saml::Iterator<const IEntitiesDescriptor*>;
340     template class SHIB_EXPORTS saml::Iterator<const IEndpoint*>;
341     template class SHIB_EXPORTS saml::Iterator<const IAttributeRule*>;
342     template class SHIB_EXPORTS saml::Iterator<const IKeyAuthority*>;
343     template class SHIB_EXPORTS saml::Iterator<DSIGKeyInfoList*>;
344     template class SHIB_EXPORTS saml::Iterator<IMetadata*>;
345     template class SHIB_EXPORTS saml::ArrayIterator<IMetadata*>;
346     template class SHIB_EXPORTS saml::Iterator<ITrust*>;
347     template class SHIB_EXPORTS saml::ArrayIterator<ITrust*>;
348     template class SHIB_EXPORTS saml::Iterator<ICredentials*>;
349     template class SHIB_EXPORTS saml::ArrayIterator<ICredentials*>;
350     template class SHIB_EXPORTS saml::Iterator<IAAP*>;
351     template class SHIB_EXPORTS saml::ArrayIterator<IAAP*>;
352 #endif
353
354     struct SHIB_EXPORTS Constants
355     {
356         static const XMLCh SHIB_ATTRIBUTE_NAMESPACE_URI[];
357         static const XMLCh SHIB_NAMEID_FORMAT_URI[];
358         static const XMLCh SHIB_AUTHNREQUEST_PROFILE_URI[];
359         static const XMLCh SHIB_LEGACY_AUTHNREQUEST_PROFILE_URI[];
360         static const XMLCh SHIB_SESSIONINIT_PROFILE_URI[];
361         static const XMLCh SHIB_LOGOUT_PROFILE_URI[];
362         static const XMLCh SHIB_NS[];
363         static const XMLCh InvalidHandle[];
364     };
365
366     // Glue classes between abstract metadata and concrete providers
367     
368     class SHIB_EXPORTS Metadata
369     {
370     public:
371         Metadata(const saml::Iterator<IMetadata*>& metadatas) : m_metadatas(metadatas), m_mapper(NULL) {}
372         ~Metadata();
373
374         const IEntityDescriptor* lookup(const char* id, bool strict=true);
375         const IEntityDescriptor* lookup(const XMLCh* id, bool strict=true);
376         const IEntityDescriptor* lookup(const saml::SAMLArtifact* artifact);
377
378     private:
379         Metadata(const Metadata&);
380         void operator=(const Metadata&);
381         IMetadata* m_mapper;
382         saml::Iterator<IMetadata*> m_metadatas;
383     };
384
385     class SHIB_EXPORTS Trust
386     {
387     public:
388         Trust(const saml::Iterator<ITrust*>& trusts) : m_trusts(trusts) {}
389         ~Trust() {}
390
391         bool validate(
392             void* certEE,
393             const saml::Iterator<void*>& certChain,
394             const IRoleDescriptor* role,
395             bool checkName=true
396             ) const;
397         bool validate(const saml::SAMLSignedObject& token, const IRoleDescriptor* role) const;
398         
399     private:
400         Trust(const Trust&);
401         void operator=(const Trust&);
402         saml::Iterator<ITrust*> m_trusts;
403     };
404     
405     class SHIB_EXPORTS Credentials
406     {
407     public:
408         Credentials(const saml::Iterator<ICredentials*>& creds) : m_creds(creds), m_mapper(NULL) {}
409         ~Credentials();
410
411         const ICredResolver* lookup(const char* id);
412
413     private:
414         Credentials(const Credentials&);
415         void operator=(const Credentials&);
416         ICredentials* m_mapper;
417         saml::Iterator<ICredentials*> m_creds;
418     };
419
420     class SHIB_EXPORTS AAP
421     {
422     public:
423         AAP(const saml::Iterator<IAAP*>& aaps, const XMLCh* attrName, const XMLCh* attrNamespace=NULL);
424         AAP(const saml::Iterator<IAAP*>& aaps, const char* alias);
425         ~AAP();
426         bool fail() const {return m_mapper==NULL;}
427         const IAttributeRule* operator->() const {return m_rule;}
428         operator const IAttributeRule*() const {return m_rule;}
429         
430         static void apply(const saml::Iterator<IAAP*>& aaps, saml::SAMLAssertion& assertion, const IEntityDescriptor* source=NULL);
431         
432     private:
433         AAP(const AAP&);
434         void operator=(const AAP&);
435         IAAP* m_mapper;
436         const IAttributeRule* m_rule;
437     };
438
439     // Subclass around the OpenSAML browser profile interface,
440     // incoporates additional functionality using Shib-defined APIs.
441     class SHIB_EXPORTS ShibBrowserProfile : virtual public saml::SAMLBrowserProfile
442     {
443     public:
444         struct SHIB_EXPORTS ITokenValidator {
445             virtual void validateToken(
446                 saml::SAMLAssertion* token,
447                 time_t=0,
448                 const IRoleDescriptor* role=NULL,
449                 const saml::Iterator<ITrust*>& trusts=EMPTY(ITrust*)
450                 ) const=0;
451             virtual ~ITokenValidator() {}
452         };
453
454         ShibBrowserProfile(
455             const ITokenValidator* validator,
456             const saml::Iterator<IMetadata*>& metadatas=EMPTY(IMetadata*),
457             const saml::Iterator<ITrust*>& trusts=EMPTY(ITrust*)
458             );
459         virtual ~ShibBrowserProfile();
460
461         virtual saml::SAMLBrowserProfile::BrowserProfileResponse receive(
462             const char* samlResponse,
463             const XMLCh* recipient,
464             saml::IReplayCache* replayCache,
465             int minorVersion=1
466             ) const;
467         virtual saml::SAMLBrowserProfile::BrowserProfileResponse receive(
468             saml::Iterator<const char*> artifacts,
469             const XMLCh* recipient,
470             saml::SAMLBrowserProfile::ArtifactMapper* artifactMapper,
471             saml::IReplayCache* replayCache,
472             int minorVersion=1
473             ) const;
474
475     private:
476         void postprocess(saml::SAMLBrowserProfile::BrowserProfileResponse& bpr, int minorVersion=1) const;
477
478         saml::SAMLBrowserProfile* m_profile;
479         saml::Iterator<IMetadata*> m_metadatas;
480         saml::Iterator<ITrust*> m_trusts;
481         const ITokenValidator* m_validator;
482     };
483
484     class SHIB_EXPORTS ShibConfig
485     {
486     public:
487         ShibConfig() {}
488         virtual ~ShibConfig() {}
489
490         // global per-process setup and shutdown of Shibboleth runtime
491         virtual bool init();
492         virtual void term();
493
494         // manages specific attribute name to factory mappings
495         void regAttributeMapping(const XMLCh* name, const IAttributeFactory* factory);
496         void unregAttributeMapping(const XMLCh* name);
497         void clearAttributeMappings();
498
499         // enables runtime and clients to access configuration
500         static ShibConfig& getConfig();
501     };
502
503     /* Helper classes for implementing reloadable XML-based config files
504        The ILockable interface will usually be inherited twice, once as
505        part of the external interface to clients and once as an implementation
506        detail of the reloading class below.
507      */
508     
509     class SHIB_EXPORTS ReloadableXMLFileImpl
510     {
511     public:
512         ReloadableXMLFileImpl(const char* pathname);
513         ReloadableXMLFileImpl(const DOMElement* pathname);
514         virtual ~ReloadableXMLFileImpl();
515         
516     protected:
517         DOMDocument* m_doc;
518         const DOMElement* m_root;
519     };
520
521     class SHIB_EXPORTS ReloadableXMLFile : protected virtual saml::ILockable
522     {
523     public:
524         ReloadableXMLFile(const DOMElement* e);
525         ~ReloadableXMLFile() { delete m_lock; delete m_impl; }
526
527         virtual void lock();
528         virtual void unlock() { if (m_lock) m_lock->unlock(); }
529
530         ReloadableXMLFileImpl* getImplementation() const;
531
532     protected:
533         virtual ReloadableXMLFileImpl* newImplementation(const char* pathname, bool first=true) const=0;
534         virtual ReloadableXMLFileImpl* newImplementation(const DOMElement* e, bool first=true) const=0;
535         mutable ReloadableXMLFileImpl* m_impl;
536         
537     private:
538         const DOMElement* m_root;
539         std::string m_source;
540         time_t m_filestamp;
541         RWLock* m_lock;
542     };
543
544     /* These helpers attach metadata-derived information as exception properties and then
545      * rethrow the object. The following properties are attached, when possible:
546      * 
547      *  providerId          The unique ID of the entity
548      *  errorURL            The error support URL of the entity or role
549      *  contactName         A formatted support or technical contact name
550      *  contactEmail        A contact email address
551      */
552     SHIB_EXPORTS void annotateException(saml::SAMLException* e, const IEntityDescriptor* entity, bool rethrow=true);
553     SHIB_EXPORTS void annotateException(saml::SAMLException* e, const IRoleDescriptor* role, bool rethrow=true);
554 }
555
556 #endif