Moved handler accessors up to base.
[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 <shibsp/AbstractSPRequest.h>
30 #include <shibsp/Application.h>
31 #include <shibsp/Handler.h>
32 #include <shibsp/RequestMapper.h>
33 #include <shibsp/ServiceProvider.h>
34 #include <shibsp/remoting/ListenerService.h>
35
36 // Old headers
37 #include <saml/saml.h>
38 #include <shib/shib.h>
39
40 #ifdef WIN32
41 # ifndef SHIBTARGET_EXPORTS
42 #  define SHIBTARGET_EXPORTS __declspec(dllimport)
43 # endif
44 # define SHIB_SCHEMAS "/opt/shibboleth-sp/share/xml/shibboleth"
45 # define SHIB_CONFIG "/opt/shibboleth-sp/etc/shibboleth/shibboleth.xml"
46 #else
47 # include <shib-target/shib-paths.h>
48 # define SHIBTARGET_EXPORTS
49 #endif
50
51 namespace shibtarget {
52   
53     // Abstract APIs for access to configuration information
54     
55     /**
56      * Interface to Shibboleth Applications, which exposes most of the functionality
57      * required to process web requests or security protocol messages for resources
58      * associated with them.
59      * 
60      * Applications are implementation-specific, but generally correspond to collections
61      * of resources related to one another in logical ways, such as a virtual host or
62      * a Java servlet context. Most complex configuration data is associated with an
63      * Application. Implementations should always expose an application named "default"
64      * as a last resort.
65      */
66     struct SHIBTARGET_EXPORTS IApplication : public virtual shibsp::Application,
67         public virtual shibboleth::ShibBrowserProfile::ITokenValidator
68     {
69         virtual saml::Iterator<saml::SAMLAttributeDesignator*> getAttributeDesignators() const=0;
70         virtual saml::Iterator<shibboleth::IAAP*> getAAPProviders() const=0;
71         virtual saml::Iterator<const XMLCh*> getAudiences() const=0;
72
73         // caller is borrowing object, must use within scope of config lock
74         virtual const saml::SAMLBrowserProfile* getBrowserProfile() const=0;
75         virtual const saml::SAMLBinding* getBinding(const XMLCh* binding) const=0;
76
77         // caller is given ownership of object, must use and delete within scope of config lock
78         virtual saml::SAMLBrowserProfile::ArtifactMapper* getArtifactMapper() const=0;
79
80         // general token validation based on conditions, signatures, etc.
81         virtual void validateToken(
82             saml::SAMLAssertion* token,
83             time_t t=0,
84             const opensaml::saml2md::RoleDescriptor* role=NULL,
85             const xmltooling::TrustEngine* trust=NULL
86             ) const=0;
87
88         virtual ~IApplication() {}
89     };
90
91     /**
92      * OpenSAML binding hook
93      *
94      * Instead of wrapping the binding to deal with mutual authentication, we
95      * just use the HTTP hook functionality offered by OpenSAML. The hook will
96      * register "itself" as a globalCtx pointer with the SAML binding and the caller
97      * will declare and pass the embedded struct as callCtx for use by the hook.
98      */
99     class ShibHTTPHook : virtual public saml::SAMLSOAPHTTPBinding::HTTPHook
100     {
101     public:
102         ShibHTTPHook(const xmltooling::TrustEngine* trust) : m_trust(trust) {}
103         virtual ~ShibHTTPHook() {}
104         
105         // Only hook we need here is for outgoing connection to server.
106         virtual bool outgoing(saml::HTTPClient* conn, void* globalCtx=NULL, void* callCtx=NULL);
107
108         // Client declares a context object and pass as callCtx to send() method.
109         class ShibHTTPHookCallContext {
110         public:
111             ShibHTTPHookCallContext(const shibsp::PropertySet* credUse, const opensaml::saml2md::RoleDescriptor* role)
112                 : m_credUse(credUse), m_role(role), m_hook(NULL), m_authenticated(false) {}
113             const ShibHTTPHook* getHook() {return m_hook;}
114             const shibsp::PropertySet* getCredentialUse() {return m_credUse;}
115             const opensaml::saml2md::RoleDescriptor* getRoleDescriptor() {return m_role;}
116             bool isAuthenticated() const {return m_authenticated;}
117             void setAuthenticated() {m_authenticated=true;}
118             
119         private:
120             const shibsp::PropertySet* m_credUse;
121             const opensaml::saml2md::RoleDescriptor* m_role;
122             ShibHTTPHook* m_hook;
123             bool m_authenticated;
124             friend class ShibHTTPHook;
125         };
126         
127         const xmltooling::TrustEngine* getTrustEngine() const {return m_trust;}
128     private:
129         const xmltooling::TrustEngine* m_trust;
130     };
131
132     /**
133      * Interface to a cached user session.
134      * 
135      * Cache entries provide implementations with access to the raw SAML information they
136      * need to publish or provide access to the data for applications to use. All creation
137      * or access to entries is through the ISessionCache interface, and callers must unlock
138      * the entry when finished using it, rather than explicitly freeing them.
139      */
140     struct SHIBTARGET_EXPORTS ISessionCacheEntry : public virtual saml::ILockable
141     {
142         virtual const char* getClientAddress() const=0;
143         virtual const char* getProviderId() const=0;
144         virtual std::pair<const char*,const saml::SAMLSubject*> getSubject(bool xml=true, bool obj=false) const=0;
145         virtual const char* getAuthnContext() const=0;
146         virtual std::pair<const char*,const saml::SAMLResponse*> getTokens(bool xml=true, bool obj=false) const=0;
147         virtual std::pair<const char*,const saml::SAMLResponse*> getFilteredTokens(bool xml=true, bool obj=false) const=0;
148         virtual ~ISessionCacheEntry() {}
149     };
150
151     /**
152      * Interface to a sink for session cache events.
153      *
154      * All caches support registration of a backing store that can be informed
155      * of significant events in the lifecycle of a cache entry.
156      */
157     struct SHIBTARGET_EXPORTS ISessionCacheStore
158     {
159         virtual HRESULT onCreate(
160             const char* key,
161             const IApplication* application,
162             const ISessionCacheEntry* entry,
163             int majorVersion,
164             int minorVersion,
165             time_t created
166             )=0;
167         virtual HRESULT onRead(
168             const char* key,
169             std::string& applicationId,
170             std::string& clientAddress,
171             std::string& providerId,
172             std::string& subject,
173             std::string& authnContext,
174             std::string& tokens,
175             int& majorVersion,
176             int& minorVersion,
177             time_t& created,
178             time_t& accessed
179             )=0;
180         virtual HRESULT onRead(const char* key, time_t& accessed)=0;
181         virtual HRESULT onRead(const char* key, std::string& tokens)=0;
182         virtual HRESULT onUpdate(const char* key, const char* tokens=NULL, time_t lastAccess=0)=0;
183         virtual HRESULT onDelete(const char* key)=0;
184         virtual ~ISessionCacheStore() {}
185     };
186
187     /**
188      * Interface to the session cache.
189      * 
190      * The session cache abstracts a persistent (meaning across requests) cache of
191      * instances of the ISessionCacheEntry interface. Creation of new entries and entry
192      * lookup are confined to this interface to enable implementations to flexibly
193      * remote and/or optimize calls by implementing custom versions of the
194      * ISessionCacheEntry interface as required.
195      */
196     struct SHIBTARGET_EXPORTS ISessionCache : public virtual saml::IPlugIn
197     {
198         virtual std::string insert(
199             const IApplication* application,
200             const opensaml::saml2md::RoleDescriptor* source,
201             const char* client_addr,
202             const saml::SAMLSubject* subject,
203             const char* authnContext,
204             const saml::SAMLResponse* tokens
205             )=0;
206         virtual ISessionCacheEntry* find(
207             const char* key, const IApplication* application, const char* client_addr
208             )=0;
209         virtual void remove(
210             const char* key, const IApplication* application, const char* client_addr
211             )=0;
212
213         virtual bool setBackingStore(ISessionCacheStore* store)=0;
214         virtual ~ISessionCache() {}
215     };
216
217     #define MEMORY_SESSIONCACHE "edu.internet2.middleware.shibboleth.sp.provider.MemorySessionCacheProvider"
218     #define MYSQL_SESSIONCACHE  "edu.internet2.middleware.shibboleth.sp.provider.MySQLSessionCacheProvider"
219     #define ODBC_SESSIONCACHE   "edu.internet2.middleware.shibboleth.sp.provider.ODBCSessionCacheProvider"
220
221     #define MYSQL_REPLAYCACHE   "edu.internet2.middleware.shibboleth.sp.provider.MySQLReplayCacheProvider"
222     #define ODBC_REPLAYCACHE    "edu.internet2.middleware.shibboleth.sp.provider.ODBCReplayCacheProvider"
223
224
225     struct SHIBTARGET_EXPORTS IConfig : public virtual shibsp::ServiceProvider
226     {
227         virtual ISessionCache* getSessionCache() const=0;
228         virtual saml::IReplayCache* getReplayCache() const=0;
229         virtual ~IConfig() {}
230     };
231
232     class SHIBTARGET_EXPORTS ShibTargetConfig
233     {
234     public:
235         ShibTargetConfig() {}
236         virtual ~ShibTargetConfig() {}
237         
238         virtual bool init(const char* schemadir) = 0;
239         virtual bool load(const char* config) = 0;
240         virtual void shutdown() = 0;
241
242         static ShibTargetConfig& getConfig();
243     };
244
245     class ShibTargetPriv;
246     class SHIBTARGET_EXPORTS ShibTarget : public shibsp::AbstractSPRequest {
247     public:
248         virtual ~ShibTarget() {}
249
250         //
251         // Note:  Subclasses need not implement anything below this line
252         //
253
254         // These functions implement the server-agnostic shibboleth engine
255         // The web server modules implement a subclass and then call into 
256         // these methods once they instantiate their request object.
257         // 
258         // Return value:
259         //   these APIs will always return the result of sendPage(), sendRedirect(),
260         //   returnDecline(), or returnOK() in the void* portion of the return code.
261         //   Exactly what those values are is module- (subclass-) implementation
262         //   specific.  The 'bool' part of the return value declares whether the
263         //   void* is valid or not.  If the bool is true then the void* is valid.
264         //   If the bool is false then the API did not call any callback, the void*
265         //   is not valid, and the caller should continue processing (the API Call
266         //   finished successfully).
267         //
268         //   The handleProfile argument declares whether doCheckAuthN() should
269         //   automatically call doHandlePOST() when it encounters a request for
270         //   the ShireURL;  if false it will call returnOK() instead.
271         //
272         std::pair<bool,long> doCheckAuthN(bool handler = false);
273         std::pair<bool,long> doHandler();
274         std::pair<bool,long> doCheckAuthZ();
275         std::pair<bool,long> doExportAssertions(bool requireSession = true);
276
277     protected:
278         ShibTarget() {}
279
280     private:
281         void clearHeaders();
282     };
283
284 }
285
286 #endif /* SHIB_TARGET_H */