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