Switch to library for URL encoder.
[shibboleth/cpp-sp.git] / shib-target / shib-target.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 /*
18  * shib-target.h -- top-level header file for the SHIB Common Target Library
19  *
20  * Created by:  Derek Atkins <derek@ihtfp.com>
21  *
22  * $Id$
23  */
24
25 #ifndef SHIB_TARGET_H
26 #define SHIB_TARGET_H
27
28 // New headers
29 #include <saml/base.h>
30 #include <xmltooling/PluginManager.h>
31
32 // Old headers
33 #include <saml/saml.h>
34 #include <shib/shib.h>
35
36 #ifdef WIN32
37 # ifndef SHIBTARGET_EXPORTS
38 #  define SHIBTARGET_EXPORTS __declspec(dllimport)
39 # endif
40 # define SHIB_SCHEMAS "/opt/shibboleth-sp/share/xml/shibboleth"
41 # define SHIB_CONFIG "/opt/shibboleth-sp/etc/shibboleth/shibboleth.xml"
42 #else
43 # include <shib-target/shib-paths.h>
44 # define SHIBTARGET_EXPORTS
45 #endif
46
47 #include <shib-target/ddf.h>
48
49 namespace shibtarget {
50   
51     DECLARE_SAML_EXCEPTION(SHIBTARGET_EXPORTS,ListenerException,SAMLException);
52     DECLARE_SAML_EXCEPTION(SHIBTARGET_EXPORTS,ConfigurationException,SAMLException);
53
54     // Abstract APIs for access to configuration information
55     
56     /**
57      * Interface to a generic set of typed properties or a DOM container of additional
58      * data.
59      */
60     struct SHIBTARGET_EXPORTS IPropertySet
61     {
62         virtual std::pair<bool,bool> getBool(const char* name, const char* ns=NULL) const=0;
63         virtual std::pair<bool,const char*> getString(const char* name, const char* ns=NULL) const=0;
64         virtual std::pair<bool,const XMLCh*> getXMLString(const char* name, const char* ns=NULL) const=0;
65         virtual std::pair<bool,unsigned int> getUnsignedInt(const char* name, const char* ns=NULL) const=0;
66         virtual std::pair<bool,int> getInt(const char* name, const char* ns=NULL) const=0;
67         virtual const IPropertySet* getPropertySet(const char* name, const char* ns="urn:mace:shibboleth:target:config:1.0") const=0;
68         virtual const DOMElement* getElement() const=0;
69         virtual ~IPropertySet() {}
70     };
71
72     // Forward declaration
73     class SHIBTARGET_EXPORTS ShibTarget;
74
75     /**
76      * Interface to a protocol handler
77      * 
78      * Protocol handlers perform system functions such as processing SAML protocol
79      * messages to create and logout sessions or creating protocol requests.
80      */
81     struct SHIBTARGET_EXPORTS IHandler : public virtual saml::IPlugIn
82     {
83         IHandler() : m_props(NULL) {}
84         virtual ~IHandler() {}
85         virtual const IPropertySet* getProperties() const { return m_props; }
86         virtual void setProperties(const IPropertySet* properties) { m_props=properties; }
87         virtual std::pair<bool,void*> run(ShibTarget* st, bool isHandler=true) const=0;
88     private:
89         const IPropertySet* m_props;
90     };
91     
92     /**
93      * Interface to Shibboleth Applications, which exposes most of the functionality
94      * required to process web requests or security protocol messages for resources
95      * associated with them.
96      * 
97      * Applications are implementation-specific, but generally correspond to collections
98      * of resources related to one another in logical ways, such as a virtual host or
99      * a Java servlet context. Most complex configuration data is associated with an
100      * Application. Implementations should always expose an application named "default"
101      * as a last resort.
102      */
103     struct SHIBTARGET_EXPORTS IApplication : public virtual IPropertySet,
104         public virtual shibboleth::ShibBrowserProfile::ITokenValidator
105     {
106         virtual const char* getId() const=0;
107         virtual const char* getHash() const=0;
108         
109         virtual saml::Iterator<saml::SAMLAttributeDesignator*> getAttributeDesignators() const=0;
110         virtual saml::Iterator<shibboleth::IAAP*> getAAPProviders() const=0;
111         virtual saml::Iterator<shibboleth::IMetadata*> getMetadataProviders() const=0;
112         virtual saml::Iterator<shibboleth::ITrust*> getTrustProviders() const=0;
113         virtual saml::Iterator<const XMLCh*> getAudiences() const=0;
114         virtual const IPropertySet* getCredentialUse(const shibboleth::IEntityDescriptor* provider) const=0;
115
116         // caller is borrowing object, must use within scope of config lock
117         virtual const saml::SAMLBrowserProfile* getBrowserProfile() const=0;
118         virtual const saml::SAMLBinding* getBinding(const XMLCh* binding) const=0;
119
120         // caller is given ownership of object, must use and delete within scope of config lock
121         virtual saml::SAMLBrowserProfile::ArtifactMapper* getArtifactMapper() const=0;
122
123         // general token validation based on conditions, signatures, etc.
124         virtual void validateToken(
125             saml::SAMLAssertion* token,
126             time_t t=0,
127             const shibboleth::IRoleDescriptor* role=NULL,
128             const saml::Iterator<shibboleth::ITrust*>& trusts=EMPTY(shibboleth::ITrust*)
129             ) const=0;
130
131         // Used to locate a default or designated session initiator for automatic sessions
132         virtual const IHandler* getDefaultSessionInitiator() const=0;
133         virtual const IHandler* getSessionInitiatorById(const char* id) const=0;
134         
135         // Used by session initiators to get endpoint to forward to IdP/WAYF
136         virtual const IHandler* getDefaultAssertionConsumerService() const=0;
137         virtual const IHandler* getAssertionConsumerServiceByIndex(unsigned short index) const=0;
138         virtual saml::Iterator<const IHandler*> getAssertionConsumerServicesByBinding(const XMLCh* binding) const=0;
139         
140         // Used by dispatcher to locate the handler for a request
141         virtual const IHandler* getHandler(const char* path) const=0;
142
143         virtual ~IApplication() {}
144     };
145
146     /**
147      * OpenSAML binding hook
148      *
149      * Instead of wrapping the binding to deal with mutual authentication, we
150      * just use the HTTP hook functionality offered by OpenSAML. The hook will
151      * register "itself" as a globalCtx pointer with the SAML binding and the caller
152      * will declare and pass the embedded struct as callCtx for use by the hook.
153      */
154     class ShibHTTPHook : virtual public saml::SAMLSOAPHTTPBinding::HTTPHook
155     {
156     public:
157         ShibHTTPHook(const saml::Iterator<shibboleth::ITrust*>& trusts, const saml::Iterator<shibboleth::ICredentials*>& creds)
158             : m_trusts(trusts), m_creds(creds) {}
159         virtual ~ShibHTTPHook() {}
160         
161         // Only hook we need here is for outgoing connection to server.
162         virtual bool outgoing(saml::HTTPClient* conn, void* globalCtx=NULL, void* callCtx=NULL);
163
164         // Client declares a context object and pass as callCtx to send() method.
165         class ShibHTTPHookCallContext {
166         public:
167             ShibHTTPHookCallContext(const IPropertySet* credUse, const shibboleth::IRoleDescriptor* role)
168                 : m_credUse(credUse), m_role(role), m_hook(NULL), m_authenticated(false) {}
169             const ShibHTTPHook* getHook() {return m_hook;}
170             const IPropertySet* getCredentialUse() {return m_credUse;}
171             const shibboleth::IRoleDescriptor* getRoleDescriptor() {return m_role;}
172             bool isAuthenticated() const {return m_authenticated;}
173             void setAuthenticated() {m_authenticated=true;}
174             
175         private:
176             const IPropertySet* m_credUse;
177             const shibboleth::IRoleDescriptor* m_role;
178             ShibHTTPHook* m_hook;
179             bool m_authenticated;
180             friend class ShibHTTPHook;
181         };
182         
183         const saml::Iterator<shibboleth::ITrust*>& getTrustProviders() const {return m_trusts;}
184         const saml::Iterator<shibboleth::ICredentials*>& getCredentialProviders() const {return m_creds;}
185     private:
186         saml::Iterator<shibboleth::ITrust*> m_trusts;
187         saml::Iterator<shibboleth::ICredentials*> m_creds;
188     };
189
190     /**
191      * Interface to a cached user session.
192      * 
193      * Cache entries provide implementations with access to the raw SAML information they
194      * need to publish or provide access to the data for applications to use. All creation
195      * or access to entries is through the ISessionCache interface, and callers must unlock
196      * the entry when finished using it, rather than explicitly freeing them.
197      */
198     struct SHIBTARGET_EXPORTS ISessionCacheEntry : public virtual saml::ILockable
199     {
200         virtual const char* getClientAddress() const=0;
201         virtual const char* getProviderId() const=0;
202         virtual std::pair<const char*,const saml::SAMLSubject*> getSubject(bool xml=true, bool obj=false) const=0;
203         virtual const char* getAuthnContext() const=0;
204         virtual std::pair<const char*,const saml::SAMLResponse*> getTokens(bool xml=true, bool obj=false) const=0;
205         virtual std::pair<const char*,const saml::SAMLResponse*> getFilteredTokens(bool xml=true, bool obj=false) const=0;
206         virtual ~ISessionCacheEntry() {}
207     };
208
209     /**
210      * Interface to a sink for session cache events.
211      *
212      * All caches support registration of a backing store that can be informed
213      * of significant events in the lifecycle of a cache entry.
214      */
215     struct SHIBTARGET_EXPORTS ISessionCacheStore
216     {
217         virtual HRESULT onCreate(
218             const char* key,
219             const IApplication* application,
220             const ISessionCacheEntry* entry,
221             int majorVersion,
222             int minorVersion,
223             time_t created
224             )=0;
225         virtual HRESULT onRead(
226             const char* key,
227             std::string& applicationId,
228             std::string& clientAddress,
229             std::string& providerId,
230             std::string& subject,
231             std::string& authnContext,
232             std::string& tokens,
233             int& majorVersion,
234             int& minorVersion,
235             time_t& created,
236             time_t& accessed
237             )=0;
238         virtual HRESULT onRead(const char* key, time_t& accessed)=0;
239         virtual HRESULT onRead(const char* key, std::string& tokens)=0;
240         virtual HRESULT onUpdate(const char* key, const char* tokens=NULL, time_t lastAccess=0)=0;
241         virtual HRESULT onDelete(const char* key)=0;
242         virtual ~ISessionCacheStore() {}
243     };
244
245     /**
246      * Interface to the session cache.
247      * 
248      * The session cache abstracts a persistent (meaning across requests) cache of
249      * instances of the ISessionCacheEntry interface. Creation of new entries and entry
250      * lookup are confined to this interface to enable implementations to flexibly
251      * remote and/or optimize calls by implementing custom versions of the
252      * ISessionCacheEntry interface as required.
253      */
254     struct SHIBTARGET_EXPORTS ISessionCache : public virtual saml::IPlugIn
255     {
256         virtual std::string insert(
257             const IApplication* application,
258             const shibboleth::IEntityDescriptor* source,
259             const char* client_addr,
260             const saml::SAMLSubject* subject,
261             const char* authnContext,
262             const saml::SAMLResponse* tokens
263             )=0;
264         virtual ISessionCacheEntry* find(
265             const char* key, const IApplication* application, const char* client_addr
266             )=0;
267         virtual void remove(
268             const char* key, const IApplication* application, const char* client_addr
269             )=0;
270
271         virtual bool setBackingStore(ISessionCacheStore* store)=0;
272         virtual ~ISessionCache() {}
273     };
274
275     /**
276      * Interface to a remoted service
277      * 
278      * Plugins that support remoted messages delivered by the IListener runtime
279      * support this interface and register themselves with the runtime to receive
280      * particular messages.
281      */
282     struct SHIBTARGET_EXPORTS IRemoted : public virtual saml::IPlugIn
283     {
284         virtual DDF receive(const DDF& in)=0;
285         virtual ~IRemoted() {}
286     };
287
288     /**
289      * Interface to the remoting engine
290      * 
291      * A listener supports the remoting of DDF objects, which are dynamic data trees
292      * that interface implementations can use to remote themselves by calling an
293      * out-of-process peer implementation with arbitrary data to carry out tasks
294      * on the implementation's behalf that require isolation from the dynamic process
295      * fluctuations that web servers are prone to. The ability to pass arbitrary data
296      * trees across the boundary allows arbitrary separation of duty between the
297      * in-process and out-of-process "halves". The implementation is responsible
298      * for marshalling and transmitting messages, as well as managing connections
299      * and communication errors.
300      */
301     class SHIBTARGET_EXPORTS IListener : public virtual IRemoted
302     {
303     public:
304         virtual DDF send(const DDF& in)=0;
305         virtual DDF receive(const DDF& in);
306         virtual ~IListener() {}
307
308         // Remoted classes register and unregister for messages using these methods.
309         // Registration returns any existing listeners, allowing message hooking.
310         virtual IRemoted* regListener(const char* address, IRemoted* listener);
311         virtual bool unregListener(const char* address, IRemoted* current, IRemoted* restore=NULL);
312         virtual IRemoted* lookup(const char* address) const;
313
314         // OutOfProcess servers can implement server-side transport handling by
315         // calling the run method and supplying a flag to monitor for shutdown.
316         virtual bool run(bool* shutdown)=0;
317
318     private:
319         std::map<std::string,IRemoted*> m_listenerMap;
320     };
321
322     /**
323      * Interface to an access control plugin
324      * 
325      * Access control plugins return authorization decisions based on the intersection
326      * of the resource request and the active session. They can be implemented through
327      * cross-platform or platform-specific mechanisms.
328      */
329     struct SHIBTARGET_EXPORTS IAccessControl : public virtual saml::ILockable, public virtual saml::IPlugIn
330     {
331         virtual bool authorized(ShibTarget* st, ISessionCacheEntry* entry) const=0;
332         virtual ~IAccessControl() {}
333     };
334
335     /**
336      * Interface to a request mapping plugin
337      * 
338      * Request mapping plugins return configuration settings that apply to resource requests.
339      * They can be implemented through cross-platform or platform-specific mechanisms.
340      */
341     struct SHIBTARGET_EXPORTS IRequestMapper : public virtual saml::ILockable, public virtual saml::IPlugIn
342     {
343         typedef std::pair<const IPropertySet*,IAccessControl*> Settings;
344         virtual Settings getSettings(ShibTarget* st) const=0;
345         virtual ~IRequestMapper() {}
346     };
347     
348     struct SHIBTARGET_EXPORTS IConfig : public virtual saml::ILockable, public virtual IPropertySet, public virtual saml::IPlugIn
349     {
350         // loads initial configuration
351         virtual void init()=0;
352
353         virtual IListener* getListener() const=0;
354         virtual ISessionCache* getSessionCache() const=0;
355         virtual saml::IReplayCache* getReplayCache() const=0;
356         virtual IRequestMapper* getRequestMapper() const=0;
357         virtual const IApplication* getApplication(const char* applicationId) const=0;
358         virtual saml::Iterator<shibboleth::ICredentials*> getCredentialsProviders() const=0;
359         virtual ~IConfig() {}
360     };
361
362     class SHIBTARGET_EXPORTS ShibTargetConfig
363     {
364     public:
365         ShibTargetConfig() : m_ini(NULL) {}
366         virtual ~ShibTargetConfig() {}
367         
368         virtual bool init(const char* schemadir) = 0;
369         virtual bool load(const char* config) = 0;
370         virtual void shutdown() = 0;
371
372         virtual IConfig* getINI() const {return m_ini;}
373
374         static ShibTargetConfig& getConfig();
375
376     protected:
377         IConfig* m_ini;
378     };
379
380     class ShibTargetPriv;
381     class SHIBTARGET_EXPORTS ShibTarget {
382     public:
383         ShibTarget(const IApplication* app);
384         virtual ~ShibTarget(void);
385
386         // These are defined here so the subclass does not need to specifically
387         // depend on log4cpp.  We could use log4cpp::Priority::PriorityLevel
388         // but this is just as easy, IMHO.  It's just a case statement in the
389         // implementation to handle the event level.
390         enum ShibLogLevel {
391           LogLevelDebug,
392           LogLevelInfo,
393           LogLevelWarn,
394           LogLevelError
395         };
396
397         //
398         // Note: subclasses MUST implement ALL of these virtual methods
399         //
400         
401         // Send a message to the Webserver log
402         virtual void log(ShibLogLevel level, const std::string &msg)=0;
403
404         void log(ShibLogLevel level, const char* msg) {
405           std::string s = msg;
406           log(level, s);
407         }
408
409         // Get/Set a cookie for this request
410         virtual std::string getCookies() const=0;
411         virtual void setCookie(const std::string& name, const std::string& value)=0;
412         virtual const char* getCookie(const std::string& name) const;
413         void setCookie(const char* name, const char* value) {
414           std::string ns = name;
415           std::string vs = value;
416           setCookie(ns, vs);
417         }
418         void setCookie(const char* name, const std::string& value) {
419           std::string ns = name;
420           setCookie(ns, value);
421         }
422
423         // Get any URL-encoded arguments or the raw POST body from the server
424         virtual const char* getQueryString() const=0;
425         virtual const char* getRequestBody() const=0;
426         virtual const char* getRequestParameter(const char* param, size_t index=0) const;
427
428         // Clear a header, set a header
429         // These APIs are used for exporting the Assertions into the
430         // Headers.  It will clear some well-known headers first to make
431         // sure none remain.  Then it will process the set of assertions
432         // and export them via setHeader().
433         virtual void clearHeader(const std::string& name)=0;
434         virtual void setHeader(const std::string& name, const std::string& value)=0;
435         virtual std::string getHeader(const std::string& name)=0;
436         virtual void setRemoteUser(const std::string& user)=0;
437         virtual std::string getRemoteUser()=0;
438
439         void clearHeader(const char* n) {
440           std::string s = n;
441           clearHeader(s);
442         }
443         void setHeader(const char* n, const char* v) {
444           std::string ns = n;
445           std::string vs = v;
446           setHeader(ns, vs);
447         }
448         void setHeader(const std::string& n, const char* v) {
449           std::string vs = v;
450           setHeader(n, vs);
451         }
452         void setHeader(const char* n, const std::string& v) {
453           std::string ns = n;
454           setHeader(ns, v);
455         }
456         std::string getHeader(const char* n) {
457           std::string s = n;
458           return getHeader(s);
459         }
460         void setRemoteUser(const char* n) {
461           std::string s = n;
462           setRemoteUser(s);
463         }
464
465         // We're done.  Finish up.  Send specific result content or a redirect.
466         // If there are no headers supplied assume the content-type is text/html
467         typedef std::pair<std::string, std::string> header_t;
468         virtual void* sendPage(
469             const std::string& msg,
470             int code = 200,
471             const std::string& content_type = "text/html",
472             const saml::Iterator<header_t>& headers = EMPTY(header_t)
473             )=0;
474         void* sendPage(const char* msg) {
475           std::string m = msg;
476           return sendPage(m);
477         }
478         virtual void* sendRedirect(const std::string& url)=0;
479         
480         // These next two APIs are used to obtain the module-specific "OK"
481         // and "Decline" results.  OK means "we believe that this request
482         // should be accepted".  Declined means "we believe that this is
483         // not a shibbolized request so we have no comment".
484
485         virtual void* returnDecline();
486         virtual void* returnOK();
487
488         //
489         // Note:  Subclasses need not implement anything below this line
490         //
491
492         // These functions implement the server-agnostic shibboleth engine
493         // The web server modules implement a subclass and then call into 
494         // these methods once they instantiate their request object.
495         // 
496         // Return value:
497         //   these APIs will always return the result of sendPage(), sendRedirect(),
498         //   returnDecline(), or returnOK() in the void* portion of the return code.
499         //   Exactly what those values are is module- (subclass-) implementation
500         //   specific.  The 'bool' part of the return value declares whether the
501         //   void* is valid or not.  If the bool is true then the void* is valid.
502         //   If the bool is false then the API did not call any callback, the void*
503         //   is not valid, and the caller should continue processing (the API Call
504         //   finished successfully).
505         //
506         //   The handleProfile argument declares whether doCheckAuthN() should
507         //   automatically call doHandlePOST() when it encounters a request for
508         //   the ShireURL;  if false it will call returnOK() instead.
509         //
510         std::pair<bool,void*> doCheckAuthN(bool handler = false);
511         std::pair<bool,void*> doHandler();
512         std::pair<bool,void*> doCheckAuthZ();
513         std::pair<bool,void*> doExportAssertions(bool requireSession = true);
514
515         // Basic request access in case any plugins need the info
516         virtual const IConfig* getConfig() const;
517         virtual const IApplication* getApplication() const;
518         const char* getRequestMethod() const {return m_method.c_str();}
519         const char* getProtocol() const {return m_protocol.c_str();}
520         const char* getHostname() const {return m_hostname.c_str();}
521         int getPort() const {return m_port;}
522         const char* getRequestURI() const {return m_uri.c_str();}
523         const char* getContentType() const {return m_content_type.c_str();}
524         const char* getRemoteAddr() const {return m_remote_addr.c_str();}
525         const char* getRequestURL() const {return m_url.c_str();}
526         
527         // Advanced methods useful to profile handlers implemented outside core
528         
529         // Get per-application session and state cookie name and properties
530         virtual std::pair<std::string,const char*> getCookieNameProps(const char* prefix) const;
531         
532         // Determine the effective handler URL based on the resource URL
533         virtual std::string getHandlerURL(const char* resource) const;
534
535     protected:
536         ShibTarget();
537
538         // Internal APIs
539
540         // Initialize the request from the parsed URL
541         // protocol == http, https, etc
542         // hostname == server name
543         // port == server port
544         // uri == resource path
545         // method == GET, POST, etc.
546         void init(
547             const char* protocol,
548             const char* hostname,
549             int port,
550             const char* uri,
551             const char* content_type,
552             const char* remote_addr,
553             const char* method
554             );
555
556         std::string m_url, m_method, m_protocol, m_hostname, m_uri, m_content_type, m_remote_addr;
557         int m_port;
558
559     private:
560         mutable ShibTargetPriv* m_priv;
561         friend class ShibTargetPriv;
562     };
563
564     struct SHIBTARGET_EXPORTS XML
565     {
566         static const XMLCh SHIBTARGET_NS[];
567         static const XMLCh SHIBTARGET_SCHEMA_ID[];
568         static const XMLCh SAML2ASSERT_NS[];
569         static const XMLCh SAML2ASSERT_SCHEMA_ID[];
570         static const XMLCh SAML2META_NS[];
571         static const XMLCh SAML2META_SCHEMA_ID[];
572         static const XMLCh XMLENC_NS[];
573         static const XMLCh XMLENC_SCHEMA_ID[];
574     
575         // Session cache implementations
576         static const char MemorySessionCacheType[];
577         static const char MySQLSessionCacheType[];
578         static const char ODBCSessionCacheType[];
579         
580         // Replay cache implementations
581         static const char MySQLReplayCacheType[];
582         static const char ODBCReplayCacheType[];
583         
584         // Request mapping/settings implementations
585         static const char XMLRequestMapType[];      // portable XML-based map
586         static const char NativeRequestMapType[];   // Native web server command override of XML-based map
587         static const char LegacyRequestMapType[];   // older designation of XML map, hijacked by web server
588         
589         // Access control implementations
590         static const char htAccessControlType[];    // Apache-specific .htaccess authz module
591         static const char XMLAccessControlType[];   // Proprietary but portable XML authz syntax
592
593         // Listener implementations
594         static const char TCPListenerType[];        // ONC RPC via TCP socket
595         static const char UnixListenerType[];       // ONC RPC via domain socker
596         static const char MemoryListenerType[];     // "faked" in-process marshalling
597     
598         struct SHIBTARGET_EXPORTS Literals
599         {
600             static const XMLCh AAPProvider[];
601             static const XMLCh AccessControl[];
602             static const XMLCh AccessControlProvider[];
603             static const XMLCh acl[];
604             static const XMLCh AND[];
605             static const XMLCh applicationId[];
606             static const XMLCh Application[];
607             static const XMLCh Applications[];
608             static const XMLCh AssertionConsumerService[];
609             static const XMLCh AttributeFactory[];
610             static const XMLCh config[];
611             static const XMLCh CredentialsProvider[];
612             static const XMLCh CredentialUse[];
613             static const XMLCh DiagnosticService[];
614             static const XMLCh echo[];
615             static const XMLCh Extensions[];
616             static const XMLCh fatal[];
617             static const XMLCh FederationProvider[];
618             static const XMLCh Global[];
619             static const XMLCh Host[];
620             static const XMLCh htaccess[];
621             static const XMLCh Implementation[];
622             static const XMLCh index[];
623             static const XMLCh InProcess[];
624             static const XMLCh isDefault[];
625             static const XMLCh Library[];
626             static const XMLCh Listener[];
627             static const XMLCh Local[];
628             static const XMLCh log[];
629             static const XMLCh logger[];
630             static const XMLCh MemorySessionCache[];
631             static const XMLCh MetadataProvider[];
632             static const XMLCh MySQLReplayCache[];
633             static const XMLCh MySQLSessionCache[];
634             static const XMLCh name[];
635             static const XMLCh Name[];
636             static const XMLCh NOT[];
637             static const XMLCh ODBCReplayCache[];
638             static const XMLCh ODBCSessionCache[];
639             static const XMLCh OR[];
640             static const XMLCh OutOfProcess[];
641             static const XMLCh Path[];
642             static const XMLCh path[];
643             static const XMLCh RelyingParty[];
644             static const XMLCh ReplayCache[];
645             static const XMLCh RequestMap[];
646             static const XMLCh RequestMapProvider[];
647             static const XMLCh require[];
648             static const XMLCh Rule[];
649             static const XMLCh SessionCache[];
650             static const XMLCh SessionInitiator[];
651             static const XMLCh SHAR[];
652             static const XMLCh ShibbolethTargetConfig[];
653             static const XMLCh SHIRE[];
654             static const XMLCh Signing[];
655             static const XMLCh SingleLogoutService[];
656             static const XMLCh SPConfig[];
657             static const XMLCh TCPListener[];
658             static const XMLCh TLS[];
659             static const XMLCh TrustProvider[];
660             static const XMLCh type[];
661             static const XMLCh UnixListener[];
662         };
663     };
664 }
665
666 #endif /* SHIB_TARGET_H */