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