2 * Copyright 2001-2005 Internet2
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 * shib-target.h -- top-level header file for the SHIB Common Target Library
20 * Created by: Derek Atkins <derek@ihtfp.com>
29 #include <shibsp/AbstractSPRequest.h>
30 #include <shibsp/Application.h>
31 #include <shibsp/ServiceProvider.h>
32 #include <shibsp/remoting/ListenerService.h>
35 #include <saml/saml.h>
36 #include <shib/shib.h>
39 # ifndef SHIBTARGET_EXPORTS
40 # define SHIBTARGET_EXPORTS __declspec(dllimport)
42 # define SHIB_SCHEMAS "/opt/shibboleth-sp/share/xml/shibboleth"
43 # define SHIB_CONFIG "/opt/shibboleth-sp/etc/shibboleth/shibboleth.xml"
45 # include <shib-target/shib-paths.h>
46 # define SHIBTARGET_EXPORTS
49 namespace shibtarget {
51 // Abstract APIs for access to configuration information
53 // Forward declaration
54 class SHIBTARGET_EXPORTS ShibTarget;
57 * Interface to a protocol handler
59 * Protocol handlers perform system functions such as processing SAML protocol
60 * messages to create and logout sessions or creating protocol requests.
62 struct SHIBTARGET_EXPORTS IHandler : public virtual saml::IPlugIn
64 IHandler() : m_props(NULL) {}
65 virtual ~IHandler() {}
66 virtual const shibsp::PropertySet* getProperties() const { return m_props; }
67 virtual void setProperties(const shibsp::PropertySet* properties) { m_props=properties; }
68 virtual std::pair<bool,long> run(ShibTarget* st, bool isHandler=true) const=0;
70 const shibsp::PropertySet* m_props;
74 * Interface to Shibboleth Applications, which exposes most of the functionality
75 * required to process web requests or security protocol messages for resources
76 * associated with them.
78 * Applications are implementation-specific, but generally correspond to collections
79 * of resources related to one another in logical ways, such as a virtual host or
80 * a Java servlet context. Most complex configuration data is associated with an
81 * Application. Implementations should always expose an application named "default"
84 struct SHIBTARGET_EXPORTS IApplication : public virtual shibsp::Application,
85 public virtual shibboleth::ShibBrowserProfile::ITokenValidator
87 virtual saml::Iterator<saml::SAMLAttributeDesignator*> getAttributeDesignators() const=0;
88 virtual saml::Iterator<shibboleth::IAAP*> getAAPProviders() const=0;
89 virtual saml::Iterator<const XMLCh*> getAudiences() const=0;
91 // caller is borrowing object, must use within scope of config lock
92 virtual const saml::SAMLBrowserProfile* getBrowserProfile() const=0;
93 virtual const saml::SAMLBinding* getBinding(const XMLCh* binding) const=0;
95 // caller is given ownership of object, must use and delete within scope of config lock
96 virtual saml::SAMLBrowserProfile::ArtifactMapper* getArtifactMapper() const=0;
98 // general token validation based on conditions, signatures, etc.
99 virtual void validateToken(
100 saml::SAMLAssertion* token,
102 const opensaml::saml2md::RoleDescriptor* role=NULL,
103 const xmltooling::TrustEngine* trust=NULL
106 // Used to locate a default or designated session initiator for automatic sessions
107 virtual const IHandler* getDefaultSessionInitiator() const=0;
108 virtual const IHandler* getSessionInitiatorById(const char* id) const=0;
110 // Used by session initiators to get endpoint to forward to IdP/WAYF
111 virtual const IHandler* getDefaultAssertionConsumerService() const=0;
112 virtual const IHandler* getAssertionConsumerServiceByIndex(unsigned short index) const=0;
113 virtual saml::Iterator<const IHandler*> getAssertionConsumerServicesByBinding(const XMLCh* binding) const=0;
115 // Used by dispatcher to locate the handler for a request
116 virtual const IHandler* getHandler(const char* path) const=0;
118 virtual ~IApplication() {}
122 * OpenSAML binding hook
124 * Instead of wrapping the binding to deal with mutual authentication, we
125 * just use the HTTP hook functionality offered by OpenSAML. The hook will
126 * register "itself" as a globalCtx pointer with the SAML binding and the caller
127 * will declare and pass the embedded struct as callCtx for use by the hook.
129 class ShibHTTPHook : virtual public saml::SAMLSOAPHTTPBinding::HTTPHook
132 ShibHTTPHook(const xmltooling::TrustEngine* trust) : m_trust(trust) {}
133 virtual ~ShibHTTPHook() {}
135 // Only hook we need here is for outgoing connection to server.
136 virtual bool outgoing(saml::HTTPClient* conn, void* globalCtx=NULL, void* callCtx=NULL);
138 // Client declares a context object and pass as callCtx to send() method.
139 class ShibHTTPHookCallContext {
141 ShibHTTPHookCallContext(const shibsp::PropertySet* credUse, const opensaml::saml2md::RoleDescriptor* role)
142 : m_credUse(credUse), m_role(role), m_hook(NULL), m_authenticated(false) {}
143 const ShibHTTPHook* getHook() {return m_hook;}
144 const shibsp::PropertySet* getCredentialUse() {return m_credUse;}
145 const opensaml::saml2md::RoleDescriptor* getRoleDescriptor() {return m_role;}
146 bool isAuthenticated() const {return m_authenticated;}
147 void setAuthenticated() {m_authenticated=true;}
150 const shibsp::PropertySet* m_credUse;
151 const opensaml::saml2md::RoleDescriptor* m_role;
152 ShibHTTPHook* m_hook;
153 bool m_authenticated;
154 friend class ShibHTTPHook;
157 const xmltooling::TrustEngine* getTrustEngine() const {return m_trust;}
159 const xmltooling::TrustEngine* m_trust;
163 * Interface to a cached user session.
165 * Cache entries provide implementations with access to the raw SAML information they
166 * need to publish or provide access to the data for applications to use. All creation
167 * or access to entries is through the ISessionCache interface, and callers must unlock
168 * the entry when finished using it, rather than explicitly freeing them.
170 struct SHIBTARGET_EXPORTS ISessionCacheEntry : public virtual saml::ILockable
172 virtual const char* getClientAddress() const=0;
173 virtual const char* getProviderId() const=0;
174 virtual std::pair<const char*,const saml::SAMLSubject*> getSubject(bool xml=true, bool obj=false) const=0;
175 virtual const char* getAuthnContext() const=0;
176 virtual std::pair<const char*,const saml::SAMLResponse*> getTokens(bool xml=true, bool obj=false) const=0;
177 virtual std::pair<const char*,const saml::SAMLResponse*> getFilteredTokens(bool xml=true, bool obj=false) const=0;
178 virtual ~ISessionCacheEntry() {}
182 * Interface to a sink for session cache events.
184 * All caches support registration of a backing store that can be informed
185 * of significant events in the lifecycle of a cache entry.
187 struct SHIBTARGET_EXPORTS ISessionCacheStore
189 virtual HRESULT onCreate(
191 const IApplication* application,
192 const ISessionCacheEntry* entry,
197 virtual HRESULT onRead(
199 std::string& applicationId,
200 std::string& clientAddress,
201 std::string& providerId,
202 std::string& subject,
203 std::string& authnContext,
210 virtual HRESULT onRead(const char* key, time_t& accessed)=0;
211 virtual HRESULT onRead(const char* key, std::string& tokens)=0;
212 virtual HRESULT onUpdate(const char* key, const char* tokens=NULL, time_t lastAccess=0)=0;
213 virtual HRESULT onDelete(const char* key)=0;
214 virtual ~ISessionCacheStore() {}
218 * Interface to the session cache.
220 * The session cache abstracts a persistent (meaning across requests) cache of
221 * instances of the ISessionCacheEntry interface. Creation of new entries and entry
222 * lookup are confined to this interface to enable implementations to flexibly
223 * remote and/or optimize calls by implementing custom versions of the
224 * ISessionCacheEntry interface as required.
226 struct SHIBTARGET_EXPORTS ISessionCache : public virtual saml::IPlugIn
228 virtual std::string insert(
229 const IApplication* application,
230 const opensaml::saml2md::RoleDescriptor* source,
231 const char* client_addr,
232 const saml::SAMLSubject* subject,
233 const char* authnContext,
234 const saml::SAMLResponse* tokens
236 virtual ISessionCacheEntry* find(
237 const char* key, const IApplication* application, const char* client_addr
240 const char* key, const IApplication* application, const char* client_addr
243 virtual bool setBackingStore(ISessionCacheStore* store)=0;
244 virtual ~ISessionCache() {}
247 #define MEMORY_SESSIONCACHE "edu.internet2.middleware.shibboleth.sp.provider.MemorySessionCacheProvider"
248 #define MYSQL_SESSIONCACHE "edu.internet2.middleware.shibboleth.sp.provider.MySQLSessionCacheProvider"
249 #define ODBC_SESSIONCACHE "edu.internet2.middleware.shibboleth.sp.provider.ODBCSessionCacheProvider"
251 #define MYSQL_REPLAYCACHE "edu.internet2.middleware.shibboleth.sp.provider.MySQLReplayCacheProvider"
252 #define ODBC_REPLAYCACHE "edu.internet2.middleware.shibboleth.sp.provider.ODBCReplayCacheProvider"
255 struct SHIBTARGET_EXPORTS IConfig : public virtual shibsp::ServiceProvider
257 virtual ISessionCache* getSessionCache() const=0;
258 virtual saml::IReplayCache* getReplayCache() const=0;
259 virtual ~IConfig() {}
262 class SHIBTARGET_EXPORTS ShibTargetConfig
265 ShibTargetConfig() : m_ini(NULL) {}
266 virtual ~ShibTargetConfig() {}
268 virtual bool init(const char* schemadir) = 0;
269 virtual bool load(const char* config) = 0;
270 virtual void shutdown() = 0;
272 virtual IConfig* getINI() const {return m_ini;}
274 static ShibTargetConfig& getConfig();
280 class ShibTargetPriv;
281 class SHIBTARGET_EXPORTS ShibTarget : public shibsp::AbstractSPRequest {
283 ShibTarget(const IApplication* app);
284 virtual ~ShibTarget(void);
286 // These next two APIs are used to obtain the module-specific "OK"
287 // and "Decline" results. OK means "we believe that this request
288 // should be accepted". Declined means "we believe that this is
289 // not a shibbolized request so we have no comment".
291 virtual long returnDecline();
292 virtual long returnOK();
295 // Note: Subclasses need not implement anything below this line
298 // These functions implement the server-agnostic shibboleth engine
299 // The web server modules implement a subclass and then call into
300 // these methods once they instantiate their request object.
303 // these APIs will always return the result of sendPage(), sendRedirect(),
304 // returnDecline(), or returnOK() in the void* portion of the return code.
305 // Exactly what those values are is module- (subclass-) implementation
306 // specific. The 'bool' part of the return value declares whether the
307 // void* is valid or not. If the bool is true then the void* is valid.
308 // If the bool is false then the API did not call any callback, the void*
309 // is not valid, and the caller should continue processing (the API Call
310 // finished successfully).
312 // The handleProfile argument declares whether doCheckAuthN() should
313 // automatically call doHandlePOST() when it encounters a request for
314 // the ShireURL; if false it will call returnOK() instead.
316 std::pair<bool,long> doCheckAuthN(bool handler = false);
317 std::pair<bool,long> doHandler();
318 std::pair<bool,long> doCheckAuthZ();
319 std::pair<bool,long> doExportAssertions(bool requireSession = true);
321 // Basic request access in case any plugins need the info
322 virtual const IConfig* getConfig() const;
323 virtual const IApplication* getApplication() const;
330 // Initialize the request from the parsed URL
331 // scheme == http, https, etc
332 // hostname == server name
333 // port == server port
334 // uri == resource path
335 // method == GET, POST, etc.
338 const char* hostname,
344 mutable ShibTargetPriv* m_priv;
345 friend class ShibTargetPriv;
350 #endif /* SHIB_TARGET_H */