Adjusted ACL API to take authn statement as well as attrs.
[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(
164             const saml::SAMLAuthenticationStatement& authn, const saml::Iterator<saml::SAMLAssertion*>& attrs
165             ) const=0;
166         virtual ~IAccessControl() {}
167     };
168
169     struct SHIBTARGET_EXPORTS IRequestMapper : public virtual shibboleth::ILockable, public virtual shibboleth::IPlugIn
170     {
171         typedef std::pair<const IPropertySet*,IAccessControl*> Settings;
172         virtual Settings getSettingsFromURL(const char* url) const=0;
173         virtual Settings getSettingsFromParsedURL(
174             const char* scheme, const char* hostname, unsigned int port, const char* path=NULL
175             ) const=0;
176         virtual ~IRequestMapper() {}
177     };
178     
179     struct SHIBTARGET_EXPORTS IApplication : public virtual IPropertySet
180     {
181         virtual const char* getId() const=0;
182         virtual saml::Iterator<saml::SAMLAttributeDesignator*> getAttributeDesignators() const=0;
183         virtual saml::Iterator<shibboleth::IAAP*> getAAPProviders() const=0;
184         virtual saml::Iterator<shibboleth::IMetadata*> getMetadataProviders() const=0;
185         virtual saml::Iterator<shibboleth::ITrust*> getTrustProviders() const=0;
186         virtual saml::Iterator<shibboleth::IRevocation*> getRevocationProviders() const=0;
187         virtual saml::Iterator<const XMLCh*> getAudiences() const=0;
188         virtual const char* getTLSCred(const shibboleth::IProvider* provider) const=0;
189         virtual const char* getSigningCred(const shibboleth::IProvider* provider) const=0;
190         virtual ~IApplication() {}
191     };
192
193         struct SHIBTARGET_EXPORTS ISessionCacheEntry : public virtual shibboleth::ILockable
194     {
195         virtual bool isValid(time_t lifetime, time_t timeout) const=0;
196         virtual const char* getClientAddress() const=0;
197         virtual const char* getSerializedStatement() const=0;
198         virtual const saml::SAMLAuthenticationStatement* getStatement() const=0;
199         virtual void preFetch(int prefetch_window)=0;
200         virtual saml::Iterator<saml::SAMLAssertion*> getAssertions()=0;
201         virtual ~ISessionCacheEntry() {}
202     };
203
204     struct SHIBTARGET_EXPORTS ISessionCache : public virtual shibboleth::IPlugIn
205     {
206         virtual void thread_init()=0;
207         virtual void thread_end()=0;
208         virtual std::string generateKey() const=0;
209         virtual void insert(
210             const char* key,
211             const IApplication* application,
212             saml::SAMLAuthenticationStatement *s,
213             const char* client_addr,
214             saml::SAMLResponse* r=NULL
215             )=0;
216         virtual ISessionCacheEntry* find(const char* key)=0;
217         virtual void remove(const char* key)=0;
218         virtual ~ISessionCache() {}
219     };
220
221     struct SHIBTARGET_EXPORTS IConfig : public virtual shibboleth::ILockable, public virtual IPropertySet, public virtual shibboleth::IPlugIn
222     {
223         virtual const IListener* getListener() const=0;
224         virtual ISessionCache* getSessionCache() const=0;
225         virtual IRequestMapper* getRequestMapper() const=0;
226         virtual const IApplication* getApplication(const char* applicationId) const=0;
227         virtual saml::Iterator<shibboleth::ICredentials*> getCredentialsProviders() const=0;
228         virtual ~IConfig() {}
229     };
230
231     class SHIBTARGET_EXPORTS ShibTargetConfig
232     {
233     public:
234         ShibTargetConfig() : m_ini(NULL), m_features(0) {}
235         virtual ~ShibTargetConfig() {}
236
237         virtual bool init(const char* schemadir, const char* config) = 0;
238         virtual void shutdown() = 0;
239
240         enum components_t {
241             Listener = 1,
242             SessionCache = 2,
243             Metadata = 4,
244             Trust = 8,
245             Credentials = 16,
246             AAP = 32,
247             RequestMapper = 64,
248             SHARExtensions = 128,
249             SHIREExtensions = 256,
250             Logging = 512
251         };
252         void setFeatures(long enabled) {m_features = enabled;}
253         bool isEnabled(components_t feature) {return (m_features & feature)>0;}
254         virtual IConfig* getINI() const {return m_ini;}
255
256         static const XMLCh SHIBTARGET_NS[];
257         static ShibTargetConfig& getConfig();
258
259     protected:
260         IConfig* m_ini;
261         
262     private:
263         unsigned long m_features;
264     };
265
266     class CgiParse;
267     class SHIBTARGET_EXPORTS SHIRE
268     {
269     public:
270         SHIRE(const IApplication* app) : m_app(app), m_parser(NULL) {}
271         ~SHIRE();
272         
273         // Get the session cookie name and properties for the application
274         std::pair<const char*,const char*> getCookieNameProps() const;
275         
276         // Find the default assertion consumer service for the resource
277         const char* getShireURL(const char* resource) const;
278         
279         // Generate a Shib 1.x AuthnRequest redirect URL for the resource
280         const char* getAuthnRequest(const char* resource) const;
281         
282         // Process a lazy session setup request and turn it into an AuthnRequest
283         const char* getLazyAuthnRequest(const char* query_string) const;
284         
285         // Process a POST profile submission, and return (SAMLResponse,TARGET) pair.
286         std::pair<const char*,const char*> getFormSubmission(const char* post, unsigned int len) const;
287         
288         RPCError* sessionCreate(const char* response, const char* ip, std::string &cookie) const;
289         RPCError* sessionIsValid(const char* session_id, const char* ip) const;
290     
291     private:
292         const IApplication* m_app;
293         mutable std::string m_cookieName;
294         mutable std::string m_shireURL;
295         mutable std::string m_authnRequest;
296         mutable CgiParse* m_parser;
297     };
298
299     class SHIBTARGET_EXPORTS RM
300     {
301     public:
302         RM(const IApplication* app) : m_app(app) {}
303         ~RM() {}
304     
305         RPCError* getAssertions(
306             const char* cookie,
307             const char* ip,
308             std::vector<saml::SAMLAssertion*>& assertions,
309             saml::SAMLAuthenticationStatement **statement = NULL
310             );
311         static void serialize(saml::SAMLAssertion &assertion, std::string &result);
312     
313     private:
314         const IApplication* m_app;
315     };
316
317     class ShibMLPPriv;
318     class SHIBTARGET_EXPORTS ShibMLP {
319     public:
320         ShibMLP();
321         ~ShibMLP();
322
323         void insert (const std::string& key, const std::string& value);
324         void insert (const std::string& key, const char* value) {
325           std::string v = value;
326           insert (key, v);
327         }
328         void insert (const char* key, const std::string& value) {
329           std::string k = key;
330           insert (k, value);
331         }
332         void insert (const char* key, const char* value) {
333           std::string k = key, v = value;
334           insert(k,v);
335         }
336         void insert (RPCError& e);
337
338         void clear () { m_map.clear(); }
339
340         const char* run (std::istream& s, const IPropertySet* props=NULL);
341         const char* run (const std::string& input, const IPropertySet* props=NULL);
342         const char* run (const char* input, const IPropertySet* props=NULL) {
343             std::string i = input;
344             return run(i,props);
345         }
346
347     private:
348         ShibMLPPriv *m_priv;
349         std::map<std::string,std::string> m_map;
350         std::string m_generated;
351     };
352 }
353
354 #endif /* SHIB_TARGET_H */