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