Updated to xsec 1.2, converted to new HTTP Hook.
[shibboleth/cpp-sp.git] / shib-target / shib-target.h
1 /*
2  * The Shibboleth License, Version 1.
3  * Copyright (c) 2002
4  * University Corporation for Advanced Internet Development, Inc.
5  * All rights reserved
6  *
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions are met:
10  *
11  * Redistributions of source code must retain the above copyright notice, this
12  * list of conditions and the following disclaimer.
13  *
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.
22  *
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
28  *
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.
33  *
34  *
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.
48  */
49
50 /*
51  * shib-target.h -- top-level header file for the SHIB Common Target Library
52  *
53  * Created by:  Derek Atkins <derek@ihtfp.com>
54  *
55  * $Id$
56  */
57
58 #ifndef SHIB_TARGET_H
59 #define SHIB_TARGET_H
60
61 #include <saml/saml.h>
62 #include <shib/shib.h>
63 #include <shib/shib-threads.h>
64
65 #ifdef WIN32
66 # ifndef SHIBTARGET_EXPORTS
67 #  define SHIBTARGET_EXPORTS __declspec(dllimport)
68 # endif
69 # define SHIB_SCHEMAS "/opt/shibboleth/share/xml/shibboleth"
70 # define SHIB_CONFIG "/opt/shibboleth/etc/shibboleth/shibboleth.xml"
71 # include <winsock.h>
72 #else
73 # include <shib-target/shib-paths.h>
74 # define SHIBTARGET_EXPORTS
75 #endif
76
77
78 namespace shibtarget {
79   
80     DECLARE_SAML_EXCEPTION(SHIBTARGET_EXPORTS,ListenerException,SAMLException);
81     DECLARE_SAML_EXCEPTION(SHIBTARGET_EXPORTS,ConfigurationException,SAMLException);
82
83     enum ShibProfile {
84       PROFILE_UNSPECIFIED = 0,
85       SAML10_POST = 1,
86       SAML10_ARTIFACT = 2,
87       SAML11_POST = 4,
88       SAML11_ARTIFACT = 8,
89       SAML20_SSO = 16
90     };
91
92     // Abstract APIs for access to configuration information
93     
94     struct SHIBTARGET_EXPORTS IPropertySet
95     {
96         virtual std::pair<bool,bool> getBool(const char* name, const char* ns=NULL) const=0;
97         virtual std::pair<bool,const char*> getString(const char* name, const char* ns=NULL) const=0;
98         virtual std::pair<bool,const XMLCh*> getXMLString(const char* name, const char* ns=NULL) const=0;
99         virtual std::pair<bool,unsigned int> getUnsignedInt(const char* name, const char* ns=NULL) const=0;
100         virtual std::pair<bool,int> getInt(const char* name, const char* ns=NULL) const=0;
101         virtual const IPropertySet* getPropertySet(const char* name, const char* ns="urn:mace:shibboleth:target:config:1.0") const=0;
102         virtual const DOMElement* getElement() const=0;
103         virtual ~IPropertySet() {}
104     };
105
106     struct SHIBTARGET_EXPORTS IApplication : public virtual IPropertySet
107     {
108         virtual const char* getId() const=0;
109         virtual const char* getHash() const=0;
110         
111         virtual saml::Iterator<saml::SAMLAttributeDesignator*> getAttributeDesignators() const=0;
112         virtual saml::Iterator<shibboleth::IAAP*> getAAPProviders() const=0;
113         virtual saml::Iterator<shibboleth::IMetadata*> getMetadataProviders() const=0;
114         virtual saml::Iterator<shibboleth::ITrust*> getTrustProviders() const=0;
115         virtual saml::Iterator<const XMLCh*> getAudiences() const=0;
116         virtual const IPropertySet* getCredentialUse(const shibboleth::IEntityDescriptor* provider) const=0;
117
118         // caller is borrowing object, must use within scope of config lock
119         virtual const saml::SAMLBrowserProfile* getBrowserProfile() const=0;
120         virtual const saml::SAMLBinding* getBinding(const XMLCh* binding) const=0;
121
122         // caller is given ownership of object, must use and delete within scope of config lock
123         virtual saml::SAMLBrowserProfile::ArtifactMapper* getArtifactMapper() const=0;
124
125         // Used to locate a default or designated session initiator for automatic sessions
126         virtual const IPropertySet* getDefaultSessionInitiator() const=0;
127         virtual const IPropertySet* getSessionInitiatorById(const char* id) const=0;
128         
129         // Used by session initiators to get endpoint to forward to IdP/WAYF
130         virtual const IPropertySet* getDefaultAssertionConsumerService() const=0;
131         virtual const IPropertySet* getAssertionConsumerServiceByIndex(unsigned short index) const=0;
132         
133         // Used by dispatcher to locate the handler configuration for a Shibboleth request
134         virtual const IPropertySet* getHandlerConfig(const char* path) const=0;
135
136         virtual ~IApplication() {}
137     };
138
139     // Instead of wrapping the binding to deal with mutual authentication, we
140     // just use the HTTP hook functionality offered by OpenSAML. The hook will
141     // register "itself" as a globalCtx pointer with the SAML binding and the caller
142     // will declare and pass the embedded struct as callCtx for use by the hook.
143     class ShibHTTPHook : virtual public saml::SAMLSOAPHTTPBinding::HTTPHook
144     {
145     public:
146         ShibHTTPHook(const saml::Iterator<shibboleth::ITrust*>& trusts, const saml::Iterator<shibboleth::ICredentials*>& creds)
147             : m_trusts(trusts), m_creds(creds) {}
148         virtual ~ShibHTTPHook() {}
149         
150         // Only hook we need here is for outgoing connection to server.
151         virtual bool outgoing(saml::HTTPClient* conn, void* globalCtx=NULL, void* callCtx=NULL);
152
153         // Client declares a context object and pass as callCtx to send() method.
154         class ShibHTTPHookCallContext {
155         public:
156             ShibHTTPHookCallContext(const IPropertySet* credUse, const shibboleth::IRoleDescriptor* role)
157                 : m_credUse(credUse), m_role(role), m_hook(NULL), m_authenticated(false) {}
158             const ShibHTTPHook* getHook() {return m_hook;}
159             const IPropertySet* getCredentialUse() {return m_credUse;}
160             const shibboleth::IRoleDescriptor* getRoleDescriptor() {return m_role;}
161             bool isAuthenticated() const {return m_authenticated;}
162             void setAuthenticated() {m_authenticated=true;}
163             
164         private:
165             const IPropertySet* m_credUse;
166             const shibboleth::IRoleDescriptor* m_role;
167             ShibHTTPHook* m_hook;
168             bool m_authenticated;
169             friend class ShibHTTPHook;
170         };
171         
172         const saml::Iterator<shibboleth::ITrust*>& getTrustProviders() const {return m_trusts;}
173         const saml::Iterator<shibboleth::ICredentials*>& getCredentialProviders() const {return m_creds;}
174     private:
175         saml::Iterator<shibboleth::ITrust*> m_trusts;
176         saml::Iterator<shibboleth::ICredentials*> m_creds;
177     };
178
179     struct SHIBTARGET_EXPORTS ISessionCacheEntry : public virtual saml::ILockable
180     {
181         virtual bool isValid(time_t lifetime, time_t timeout) const=0;
182         virtual const char* getClientAddress() const=0;
183         virtual ShibProfile getProfile() const=0;
184         virtual const char* getProviderId() const=0;
185         virtual const saml::SAMLAuthenticationStatement* getAuthnStatement() const=0;
186         struct SHIBTARGET_EXPORTS CachedResponse {
187             CachedResponse(const saml::SAMLResponse* unfiltered, const saml::SAMLResponse* filtered) {
188                 this->unfiltered=unfiltered;
189                 this->filtered=filtered;
190             }
191             bool empty() {return unfiltered==NULL;}
192             const saml::SAMLResponse* unfiltered;
193             const saml::SAMLResponse* filtered;
194         };
195         virtual CachedResponse getResponse()=0;
196         virtual ~ISessionCacheEntry() {}
197     };
198
199     struct SHIBTARGET_EXPORTS ISessionCache : public virtual saml::IPlugIn
200     {
201         virtual void thread_init()=0;
202         virtual void thread_end()=0;
203         virtual std::string generateKey() const=0;
204         virtual void insert(
205             const char* key,
206             const IApplication* application,
207             const char* client_addr,
208             ShibProfile profile,
209             const char* providerId,
210             saml::SAMLAuthenticationStatement* s,
211             saml::SAMLResponse* r=NULL,
212             const shibboleth::IRoleDescriptor* source=NULL,
213             time_t created=0,
214             time_t accessed=0
215             )=0;
216         virtual ISessionCacheEntry* find(const char* key, const IApplication* application)=0;
217         virtual void remove(const char* key)=0;
218         virtual ~ISessionCache() {}
219     };
220
221     struct SHIBTARGET_EXPORTS IListener : public virtual saml::IPlugIn
222     {
223         // The socket APIs should really be somewhere else, but compatibility
224         // with older configuration files dictates that the Listener handles
225         // both client and server socket handling. We can fix this for 2.0...?
226 #ifdef WIN32
227         typedef SOCKET ShibSocket;
228 #else
229         typedef int ShibSocket;
230 #endif
231         virtual bool create(ShibSocket& s) const=0;
232         virtual bool bind(ShibSocket& s, bool force=false) const=0;
233         virtual bool connect(ShibSocket& s) const=0;
234         virtual bool close(ShibSocket& s) const=0;
235         virtual bool accept(ShibSocket& listener, ShibSocket& s) const=0;
236
237         // The "real" Listener API abstracts the primitive operations that make up
238         // the meat of the SP's job. Right now, that's session create/read/delete.
239         virtual void sessionNew(
240             const IApplication* application,
241             int supported_profiles,
242             const char* recipient,
243             const char* packet,
244             const char* ip,
245             std::string& target,
246             std::string& cookie,
247             std::string& provider_id
248             ) const=0;
249     
250         virtual void sessionGet(
251             const IApplication* application,
252             const char* cookie,
253             const char* ip,
254             ISessionCacheEntry** pentry
255             ) const=0;
256     
257         virtual void sessionEnd(
258             const IApplication* application,
259             const char* cookie
260             ) const=0;
261             
262         virtual void ping(int& i) const=0;
263         
264         virtual ~IListener() {}
265     };
266
267     class SHIBTARGET_EXPORTS ShibTarget;
268
269     struct SHIBTARGET_EXPORTS IAccessControl : public virtual saml::ILockable, public virtual saml::IPlugIn
270     {
271         virtual bool authorized(ShibTarget* st, ISessionCacheEntry* entry) const=0;
272         virtual ~IAccessControl() {}
273     };
274
275     struct SHIBTARGET_EXPORTS IRequestMapper : public virtual saml::ILockable, public virtual saml::IPlugIn
276     {
277         typedef std::pair<const IPropertySet*,IAccessControl*> Settings;
278         virtual Settings getSettings(ShibTarget* st) const=0;
279         virtual ~IRequestMapper() {}
280     };
281     
282     struct SHIBTARGET_EXPORTS IHandler : public virtual saml::IPlugIn
283     {
284         virtual std::pair<bool,void*> run(ShibTarget* st, const IPropertySet* config, bool isHandler=true)=0;
285         virtual ~IHandler() {}
286     };
287     
288     struct SHIBTARGET_EXPORTS IConfig : public virtual saml::ILockable, public virtual IPropertySet, public virtual saml::IPlugIn
289     {
290         virtual const IListener* getListener() const=0;
291         virtual ISessionCache* getSessionCache() const=0;
292         virtual saml::IReplayCache* getReplayCache() const=0;
293         virtual IRequestMapper* getRequestMapper() const=0;
294         virtual const IApplication* getApplication(const char* applicationId) const=0;
295         virtual saml::Iterator<shibboleth::ICredentials*> getCredentialsProviders() const=0;
296         virtual ~IConfig() {}
297     };
298
299     class SHIBTARGET_EXPORTS ShibTargetConfig
300     {
301     public:
302         ShibTargetConfig() : m_ini(NULL), m_features(0) {}
303         virtual ~ShibTargetConfig() {}
304         
305         virtual bool init(const char* schemadir) = 0;
306         virtual bool load(const char* config) = 0;
307         virtual void shutdown() = 0;
308
309         enum components_t {
310             Listener = 1,
311             Caching = 2,
312             Metadata = 4,
313             Trust = 8,
314             Credentials = 16,
315             AAP = 32,
316             RequestMapper = 64,
317             GlobalExtensions = 128,
318             LocalExtensions = 256,
319             Logging = 512
320         };
321         void setFeatures(long enabled) {m_features = enabled;}
322         bool isEnabled(components_t feature) {return (m_features & feature)>0;}
323         virtual IConfig* getINI() const {return m_ini;}
324
325         static ShibTargetConfig& getConfig();
326
327     protected:
328         IConfig* m_ini;
329         
330     private:
331         unsigned long m_features;
332     };
333
334   class ShibTargetPriv;
335   class SHIBTARGET_EXPORTS ShibTarget {
336   public:
337     ShibTarget(const IApplication *app);
338     virtual ~ShibTarget(void);
339
340     // These are defined here so the subclass does not need to specifically
341     // depend on log4cpp.  We could use log4cpp::Priority::PriorityLevel
342     // but this is just as easy, IMHO.  It's just a case statement in the
343     // implementation to handle the event level.
344     enum ShibLogLevel {
345       LogLevelDebug,
346       LogLevelInfo,
347       LogLevelWarn,
348       LogLevelError
349     };
350
351     //
352     // Note: subclasses MUST implement ALL of these virtual methods
353     //
354     
355     // Send a message to the Webserver log
356     virtual void log(ShibLogLevel level, const std::string &msg)=0;
357
358     void log(ShibLogLevel level, const char *msg) {
359       std::string s = msg;
360       log(level, s);
361     }
362
363     // Get/Set a cookie for this request
364     virtual std::string getCookies() const=0;
365     virtual void setCookie(const std::string &name, const std::string &value)=0;
366     virtual const char* getCookie(const std::string& name) const;
367     void setCookie(const char *name, const char *value) {
368       std::string ns = name;
369       std::string vs = value;
370       setCookie(ns, vs);
371     }
372     void setCookie(const char *name, const std::string &value) {
373       std::string ns = name;
374       setCookie(ns, value);
375     }
376
377
378     // Get the request's GET arguments or POST data from the server
379     virtual std::string getArgs(void)=0;
380     virtual std::string getPostData(void)=0;
381
382     // Clear a header, set a header
383     // These APIs are used for exporting the Assertions into the
384     // Headers.  It will clear some well-known headers first to make
385     // sure none remain.  Then it will process the set of assertions
386     // and export them via setHeader().
387     virtual void clearHeader(const std::string &name)=0;
388     virtual void setHeader(const std::string &name, const std::string &value)=0;
389     virtual std::string getHeader(const std::string &name)=0;
390     virtual void setRemoteUser(const std::string &user)=0;
391     virtual std::string getRemoteUser(void)=0;
392
393     void clearHeader(const char *n) {
394       std::string s = n;
395       clearHeader(s);
396     }
397     void setHeader(const char *n, const char *v) {
398       std::string ns = n;
399       std::string vs = v;
400       setHeader(ns, vs);
401     }
402     void setHeader(const std::string &n, const char *v) {
403       std::string vs = v;
404       setHeader(n, vs);
405     }
406     void setHeader(const char *n, const std::string &v) {
407       std::string ns = n;
408       setHeader(ns, v);
409     }
410     std::string getHeader(const char *n) {
411       std::string s = n;
412       return getHeader(s);
413     }
414     void setRemoteUser(const char *n) {
415       std::string s = n;
416       setRemoteUser(s);
417     }
418
419     // We're done.  Finish up.  Send specific result content or a redirect.
420     // If there are no headers supplied assume the content-type is text/html
421     typedef std::pair<std::string, std::string> header_t;
422     virtual void* sendPage(
423         const std::string& msg,
424         int code = 200,
425         const std::string& content_type = "text/html",
426         const saml::Iterator<header_t>& headers = EMPTY(header_t)
427         )=0;
428     void* sendPage(const char *msg) {
429       std::string m = msg;
430       return sendPage(m);
431     }
432     virtual void* sendRedirect(const std::string& url)=0;
433     
434     // These next two APIs are used to obtain the module-specific "OK"
435     // and "Decline" results.  OK means "we believe that this request
436     // should be accepted".  Declined means "we believe that this is
437     // not a shibbolized request so we have no comment".
438
439     virtual void* returnDecline(void);
440     virtual void* returnOK(void);
441
442     //
443     // Note:  Subclasses need not implement anything below this line
444     //
445
446     // These functions implement the server-agnostic shibboleth engine
447     // The web server modules implement a subclass and then call into 
448     // these methods once they instantiate their request object.
449     // 
450     // Return value:
451     //   these APIs will always return the result of sendPage(), sendRedirect(),
452     //   returnDecline(), or returnOK() in the void* portion of the return code.
453     //   Exactly what those values are is module- (subclass-) implementation
454     //   specific.  The 'bool' part of the return value declares whether the
455     //   void* is valid or not.  If the bool is true then the void* is valid.
456     //   If the bool is false then the API did not call any callback, the void*
457     //   is not valid, and the caller should continue processing (the API Call
458     //   finished successfully).
459     //
460     //   The handleProfile argument declares whether doCheckAuthN() should
461     //   automatically call doHandlePOST() when it encounters a request for
462     //   the ShireURL;  if false it will call returnOK() instead.
463     //
464     std::pair<bool,void*> doCheckAuthN(bool handler = false);
465     std::pair<bool,void*> doHandler();
466     std::pair<bool,void*> doCheckAuthZ();
467     std::pair<bool,void*> doExportAssertions(bool requireSession = true);
468
469     // Basic request access in case any plugins need the info
470     virtual const IConfig* getConfig() const;
471     virtual const IApplication* getApplication() const;
472     const char* getRequestMethod() const {return m_method.c_str();}
473     const char* getProtocol() const {return m_protocol.c_str();}
474     const char* getHostname() const {return m_hostname.c_str();}
475     int getPort() const {return m_port;}
476     const char* getRequestURI() const {return m_uri.c_str();}
477     const char* getContentType() const {return m_content_type.c_str();}
478     const char* getRemoteAddr() const {return m_remote_addr.c_str();}
479     const char* getRequestURL() const {return m_url.c_str();}
480     
481     // Advanced methods useful to profile handlers implemented outside core
482     
483     // Get per-application session and state cookie name and properties
484     virtual std::pair<std::string,const char*> getCookieNameProps(const char* prefix) const;
485     
486     // Determine the effective handler URL based on the resource URL
487     virtual std::string getHandlerURL(const char* resource) const;
488
489   protected:
490     ShibTarget();
491
492     // Internal APIs
493
494     // Initialize the request from the parsed URL
495     // protocol == http, https, etc
496     // hostname == server name
497     // port == server port
498     // uri == resource path
499     // method == GET, POST, etc.
500     void init(
501         const char* protocol,
502         const char* hostname,
503         int port,
504         const char* uri,
505         const char* content_type,
506         const char* remote_addr,
507         const char* method
508         );
509
510     std::string m_url, m_method, m_protocol, m_hostname, m_uri, m_content_type, m_remote_addr;
511     int m_port;
512
513   private:
514     mutable ShibTargetPriv* m_priv;
515     friend class ShibTargetPriv;
516   };
517
518     struct SHIBTARGET_EXPORTS XML
519     {
520         static const XMLCh SHIBTARGET_NS[];
521         static const XMLCh SHIBTARGET_SCHEMA_ID[];
522         static const XMLCh SAML2ASSERT_NS[];
523         static const XMLCh SAML2ASSERT_SCHEMA_ID[];
524         static const XMLCh SAML2META_NS[];
525         static const XMLCh SAML2META_SCHEMA_ID[];
526         static const XMLCh XMLENC_NS[];
527         static const XMLCh XMLENC_SCHEMA_ID[];
528     
529         // Session cache implementations
530         static const char MemorySessionCacheType[];
531         static const char MySQLSessionCacheType[];
532         
533         // Replay cache implementations
534         static const char MySQLReplayCacheType[];
535         
536         // Request mapping/settings implementations
537         static const char XMLRequestMapType[];      // portable XML-based map
538         static const char NativeRequestMapType[];   // Native web server command override of XML-based map
539         static const char LegacyRequestMapType[];   // older designation of XML map, hijacked by web server
540         
541         // Access control implementations
542         static const char htAccessControlType[];    // Apache-specific .htaccess authz module
543         static const char XMLAccessControlType[];   // Proprietary but portable XML authz syntax
544
545         // Listener implementations
546         static const char TCPListenerType[];        // ONC RPC via TCP socket
547         static const char UnixListenerType[];       // ONC RPC via domain socker
548         static const char MemoryListenerType[];     // "faked" in-process marshalling
549     
550         struct SHIBTARGET_EXPORTS Literals
551         {
552             static const XMLCh AAPProvider[];
553             static const XMLCh AccessControl[];
554             static const XMLCh AccessControlProvider[];
555             static const XMLCh acl[];
556             static const XMLCh AND[];
557             static const XMLCh applicationId[];
558             static const XMLCh Application[];
559             static const XMLCh Applications[];
560             static const XMLCh AssertionConsumerService[];
561             static const XMLCh AttributeFactory[];
562             static const XMLCh config[];
563             static const XMLCh CredentialsProvider[];
564             static const XMLCh CredentialUse[];
565             static const XMLCh DiagnosticService[];
566             static const XMLCh echo[];
567             static const XMLCh Extensions[];
568             static const XMLCh fatal[];
569             static const XMLCh FederationProvider[];
570             static const XMLCh Global[];
571             static const XMLCh Host[];
572             static const XMLCh htaccess[];
573             static const XMLCh Implementation[];
574             static const XMLCh index[];
575             static const XMLCh isDefault[];
576             static const XMLCh Library[];
577             static const XMLCh Listener[];
578             static const XMLCh Local[];
579             static const XMLCh log[];
580             static const XMLCh logger[];
581             static const XMLCh MemorySessionCache[];
582             static const XMLCh MetadataProvider[];
583             static const XMLCh MySQLReplayCache[];
584             static const XMLCh MySQLSessionCache[];
585             static const XMLCh name[];
586             static const XMLCh Name[];
587             static const XMLCh NOT[];
588             static const XMLCh OR[];
589             static const XMLCh Path[];
590             static const XMLCh path[];
591             static const XMLCh RelyingParty[];
592             static const XMLCh ReplayCache[];
593             static const XMLCh RequestMap[];
594             static const XMLCh RequestMapProvider[];
595             static const XMLCh require[];
596             static const XMLCh Rule[];
597             static const XMLCh SessionCache[];
598             static const XMLCh SessionInitiator[];
599             static const XMLCh SHAR[];
600             static const XMLCh ShibbolethTargetConfig[];
601             static const XMLCh SHIRE[];
602             static const XMLCh Signing[];
603             static const XMLCh SingleLogoutService[];
604             static const XMLCh SPConfig[];
605             static const XMLCh TCPListener[];
606             static const XMLCh TLS[];
607             static const XMLCh TrustProvider[];
608             static const XMLCh type[];
609             static const XMLCh UnixListener[];
610         };
611     };
612 }
613
614 #endif /* SHIB_TARGET_H */