Moved path constants into main header for WIN32
[shibboleth/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/etc/shibboleth"
70 # define SHIB_CONFIG "/opt/shibboleth/etc/shibboleth/shibboleth.xml"
71 #else
72 # include <shib-target/shib-paths.h>
73 # define SHIBTARGET_EXPORTS
74 #endif
75
76 #include <shib-target/shibrpc.h>
77
78 namespace shibtarget {
79   
80   class SHIBTARGET_EXPORTS ShibTargetException : public std::exception
81   {
82   public:
83     explicit ShibTargetException() : m_code(SHIBRPC_OK) {}
84     explicit ShibTargetException(ShibRpcStatus code, const char* msg, const shibboleth::IProvider* provider);
85     explicit ShibTargetException(ShibRpcStatus code, const char* msg, const shibboleth::IProviderRole* role=NULL);
86     
87     virtual ~ShibTargetException() throw () {}
88     virtual ShibRpcStatus which() const throw () { return m_code; }
89     virtual const char* what() const throw () { return m_msg.c_str(); }
90     virtual const char* syswho() const throw() { return m_providerId.c_str(); }
91     virtual const char* where() const throw () { return m_errorURL.c_str(); }
92     virtual const char* who() const throw () { return m_contact.c_str(); }
93     virtual const char* how() const throw () { return m_email.c_str(); }
94
95   private:
96     ShibRpcStatus m_code;
97     std::string m_msg;
98     std::string m_providerId;
99     std::string m_errorURL;
100     std::string m_contact;
101     std::string m_email;
102   };
103
104   class RPCErrorPriv;
105   class SHIBTARGET_EXPORTS RPCError
106   {
107   public:
108     RPCError();
109     RPCError(ShibRpcError* e);
110     RPCError(int s, const char* st);
111     RPCError(ShibTargetException &exp);
112     ~RPCError();
113
114     bool isError();
115     bool isRetryable();
116
117     // Return a set of strings that correspond to the error properties
118     const char* getType();
119     const char* getText();
120     const char* getDesc();
121     const char* getProviderId();
122     const char* getErrorURL();
123     const char* getContactName();
124     const char* getContactEmail();
125     int getCode();
126
127   private:
128     RPCErrorPriv* m_priv;
129   };
130
131     // Abstract APIs for access to configuration information
132     
133     struct SHIBTARGET_EXPORTS IPropertySet
134     {
135         virtual std::pair<bool,bool> getBool(const char* name, const char* ns=NULL) const=0;
136         virtual std::pair<bool,const char*> getString(const char* name, const char* ns=NULL) const=0;
137         virtual std::pair<bool,const XMLCh*> getXMLString(const char* name, const char* ns=NULL) const=0;
138         virtual std::pair<bool,unsigned int> getUnsignedInt(const char* name, const char* ns=NULL) const=0;
139         virtual std::pair<bool,int> getInt(const char* name, const char* ns=NULL) const=0;
140         virtual const IPropertySet* getPropertySet(const char* name, const char* ns="urn:mace:shibboleth:target:config:1.0") const=0;
141         virtual const DOMElement* getElement() const=0;
142         virtual ~IPropertySet() {}
143     };
144
145     struct SHIBTARGET_EXPORTS IListener : public virtual shibboleth::IPlugIn
146     {
147 #ifdef WIN32
148         typedef SOCKET ShibSocket;
149 #else
150         typedef int ShibSocket;
151 #endif
152         virtual bool create(ShibSocket& s) const=0;
153         virtual bool bind(ShibSocket& s, bool force=false) const=0;
154         virtual bool connect(ShibSocket& s) const=0;
155         virtual bool close(ShibSocket& s) const=0;
156         virtual bool accept(ShibSocket& listener, ShibSocket& s) const=0;
157         virtual CLIENT* getClientHandle(ShibSocket& s, u_long program, u_long version) const=0;
158         virtual ~IListener() {}
159     };
160
161     struct SHIBTARGET_EXPORTS IAccessControl : public virtual shibboleth::ILockable, public virtual shibboleth::IPlugIn
162     {
163         virtual bool authorized(const saml::Iterator<saml::SAMLAssertion*>& creds) const=0;
164         virtual ~IAccessControl() {}
165     };
166
167     struct SHIBTARGET_EXPORTS IRequestMapper : public virtual shibboleth::ILockable, public virtual shibboleth::IPlugIn
168     {
169         typedef std::pair<const IPropertySet*,IAccessControl*> Settings;
170         virtual Settings getSettingsFromURL(const char* url) const=0;
171         virtual Settings getSettingsFromParsedURL(
172             const char* scheme, const char* hostname, unsigned int port, const char* path=NULL
173             ) const=0;
174         virtual ~IRequestMapper() {}
175     };
176     
177     struct SHIBTARGET_EXPORTS IApplication : public virtual IPropertySet
178     {
179         virtual const char* getId() const=0;
180         virtual saml::Iterator<saml::SAMLAttributeDesignator*> getAttributeDesignators() const=0;
181         virtual saml::Iterator<shibboleth::IAAP*> getAAPProviders() const=0;
182         virtual saml::Iterator<shibboleth::IMetadata*> getMetadataProviders() const=0;
183         virtual saml::Iterator<shibboleth::ITrust*> getTrustProviders() const=0;
184         virtual saml::Iterator<shibboleth::IRevocation*> getRevocationProviders() const=0;
185         virtual saml::Iterator<const XMLCh*> getAudiences() const=0;
186         virtual const char* getTLSCred(const shibboleth::IProvider* provider) const=0;
187         virtual const char* getSigningCred(const shibboleth::IProvider* provider) const=0;
188         virtual ~IApplication() {}
189     };
190
191         struct SHIBTARGET_EXPORTS ISessionCacheEntry : public virtual shibboleth::ILockable
192     {
193         virtual bool isValid(time_t lifetime, time_t timeout) const=0;
194         virtual const char* getClientAddress() const=0;
195         virtual const char* getSerializedStatement() const=0;
196         virtual const saml::SAMLAuthenticationStatement* getStatement() const=0;
197         virtual void preFetch(int prefetch_window)=0;
198         virtual saml::Iterator<saml::SAMLAssertion*> getAssertions()=0;
199         virtual ~ISessionCacheEntry() {}
200     };
201
202     struct SHIBTARGET_EXPORTS ISessionCache : public virtual shibboleth::IPlugIn
203     {
204         virtual void thread_init()=0;
205         virtual void thread_end()=0;
206         virtual std::string generateKey() const=0;
207         virtual void insert(
208             const char* key,
209             const IApplication* application,
210             saml::SAMLAuthenticationStatement *s,
211             const char* client_addr,
212             saml::SAMLResponse* r=NULL
213             )=0;
214         virtual ISessionCacheEntry* find(const char* key)=0;
215         virtual void remove(const char* key)=0;
216         virtual ~ISessionCache() {}
217     };
218
219     struct SHIBTARGET_EXPORTS IConfig : public virtual shibboleth::ILockable, public virtual IPropertySet, public virtual shibboleth::IPlugIn
220     {
221         virtual const IListener* getListener() const=0;
222         virtual ISessionCache* getSessionCache() const=0;
223         virtual IRequestMapper* getRequestMapper() const=0;
224         virtual const IApplication* getApplication(const char* applicationId) const=0;
225         virtual saml::Iterator<shibboleth::ICredentials*> getCredentialsProviders() const=0;
226         virtual ~IConfig() {}
227     };
228
229     class SHIBTARGET_EXPORTS ShibTargetConfig
230     {
231     public:
232         ShibTargetConfig() : m_ini(NULL), m_features(0) {}
233         virtual ~ShibTargetConfig() {}
234
235         virtual bool init(const char* schemadir, const char* config) = 0;
236         virtual void shutdown() = 0;
237
238         enum components_t {
239             Listener = 1,
240             SessionCache = 2,
241             Metadata = 4,
242             Trust = 8,
243             Credentials = 16,
244             AAP = 32,
245             RequestMapper = 64,
246             SHARExtensions = 128,
247             SHIREExtensions = 256
248         };
249         void setFeatures(long enabled) {m_features = enabled;}
250         bool isEnabled(components_t feature) {return (m_features & feature)>0;}
251         virtual IConfig* getINI() const {return m_ini;}
252
253         static const XMLCh SHIBTARGET_NS[];
254         static ShibTargetConfig& getConfig();
255
256     protected:
257         IConfig* m_ini;
258         
259     private:
260         unsigned long m_features;
261     };
262
263     class CgiParse;
264     class SHIBTARGET_EXPORTS SHIRE
265     {
266     public:
267         SHIRE(const IApplication* app) : m_app(app), m_parser(NULL) {}
268         ~SHIRE();
269     
270         // Find the default assertion consumer service for the resource
271         const char* getShireURL(const char* resource);
272         
273         // Generate a Shib 1.x AuthnRequest redirect URL for the resource
274         const char* getAuthnRequest(const char* resource);
275         
276         // Process a lazy session setup request and turn it into an AuthnRequest
277         const char* getLazyAuthnRequest(const char* query_string);
278         
279         // Process a POST profile submission, and return (SAMLResponse,TARGET) pair.
280         std::pair<const char*,const char*> getFormSubmission(const char* post, unsigned int len);
281         
282         RPCError* sessionCreate(const char* response, const char* ip, std::string &cookie);
283         RPCError* sessionIsValid(const char* session_id, const char* ip);
284     
285     private:
286         const IApplication* m_app;
287         std::string m_shireURL;
288         std::string m_authnRequest;
289         CgiParse* m_parser;
290     };
291
292     class SHIBTARGET_EXPORTS RM
293     {
294     public:
295         RM(const IApplication* app) : m_app(app) {}
296         ~RM() {}
297     
298         RPCError* getAssertions(
299             const char* cookie,
300             const char* ip,
301             std::vector<saml::SAMLAssertion*>& assertions,
302             saml::SAMLAuthenticationStatement **statement = NULL
303             );
304         static void serialize(saml::SAMLAssertion &assertion, std::string &result);
305     
306     private:
307         const IApplication* m_app;
308     };
309
310     class ShibMLPPriv;
311     class SHIBTARGET_EXPORTS ShibMLP {
312     public:
313         ShibMLP(const IApplication* app=NULL);
314         ~ShibMLP();
315
316         void insert (const std::string& key, const std::string& value);
317         void insert (const std::string& key, const char* value) {
318           std::string v = value;
319           insert (key, v);
320         }
321         void insert (const char* key, const std::string& value) {
322           std::string k = key;
323           insert (k, value);
324         }
325         void insert (const char* key, const char* value) {
326           std::string k = key, v = value;
327           insert(k,v);
328         }
329         void insert (RPCError& e);
330
331         void clear () { m_map.clear(); }
332
333         const char* run (std::istream& s);
334         const char* run (const std::string& input);
335         const char* run (const char* input) {
336             std::string i = input;
337             return run(i);
338         }
339
340     private:
341         ShibMLPPriv *m_priv;
342         std::map<std::string,std::string> m_map;
343         std::string m_generated;
344     };
345
346   class SHIBTARGET_EXPORTS ShibTargetResponse
347   {
348   public:
349     // What to do with the response
350     enum ReturnValue {
351       OK = 0,
352       DECLINED,
353       REDIRECT,
354       INTERNAL_ERROR
355     };
356
357     // How to log the message, if any.  (NONE implies no log_msg)
358     enum LogLevel {
359       NONE = 0,
360       DEBUG,
361       INFO,
362       ERR,
363       CRIT
364     };
365
366     ReturnValue status;
367     LogLevel    log_level;
368     bool        has_mlp;
369
370     std::string log_msg;        // message to log if log_level != NONE
371     std::string redirect_to;    // where to redirect if status == REDIRECT
372     ShibMLP     mlp;            // MLP information if has_mlp == true
373   };
374
375   // The ShibTargetError is used by the high-level SHIRE and RM methods
376   // to notify the handlers of high-level errors.
377
378   class SHIBTARGET_EXPORTS ShibTargetError : public std::exception
379   {
380   public:
381     explicit ShibTargetError(ShibTargetResponse *resp = NULL) { m_resp = resp; }
382     virtual ~ShibTargetError() throw () { if (m_resp) delete m_resp; }
383     virtual const ShibTargetResponse* getError() { return m_resp; }
384
385   private:
386     ShibTargetResponse *m_resp;
387   };
388 }
389
390 #endif /* SHIB_TARGET_H */