Rework sockname, and add sockacl.
[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 #ifdef __cplusplus
62 # include <saml/saml.h>
63 # include <shib/shib.h>
64 #endif
65
66 #ifdef WIN32
67 # ifndef SHIBTARGET_EXPORTS
68 #  define SHIBTARGET_EXPORTS __declspec(dllimport)
69 # endif
70 #else
71 # define SHIBTARGET_EXPORTS
72 #endif
73
74 #include <shib-target/shibrpc.h>
75
76 #ifdef __cplusplus
77 extern "C" {
78 #endif
79
80 #ifdef WIN32
81
82 #include <winsock.h>
83 typedef SOCKET ShibSocket;
84 typedef const char* ShibSockName;
85 #define SHIB_SHAR_SOCKET "127.0.0.1:12345"  /* TCP host:port */
86
87 #else  /* UNIX */
88
89 typedef int ShibSocket;
90 typedef const char* ShibSockName;
91 #define SHIB_SHAR_SOCKET "/tmp/shar-socket" /* Unix domain socket */
92
93 #endif
94
95 /* shib-rpcutil.c */
96
97 /* Create an RPC Client handle for the _connected_ socket sock, attaching
98  * the RPC program and version.
99  *
100  * returns a CLIENT on success, or NULL on error.  The caller can
101  * call clnt_pcreateerror ("<string>") to output an error message from
102  * the RPC library.
103  */
104 SHIBTARGET_EXPORTS CLIENT * shibrpc_client_create (ShibSocket sock, u_long program, u_long version);
105
106 /* shib-sock.c */
107
108 /* Create a new socket and put it into sock.
109  *
110  * Returns 0 on success, non-zero on error 
111  */
112 SHIBTARGET_EXPORTS int shib_sock_create (ShibSocket *sock);
113
114 /*
115  * bind the socket s to the "port" name.
116  *
117  * Returns 0 on success; non-zero on error.
118  *
119  * SIDE EFFECT: On error, the socket is closed!
120  */
121 SHIBTARGET_EXPORTS int shib_sock_bind (ShibSocket s, ShibSockName name);
122
123 /*
124  * connect the socket s to the "port" name on the local host.
125  *
126  * Returns 0 on success; non-zero on error.
127  */
128 SHIBTARGET_EXPORTS int shib_sock_connect (ShibSocket s, ShibSockName name);
129
130 /*
131  * accept a connection.  Returns 0 on success, non-zero on failure.
132  */
133 SHIBTARGET_EXPORTS int shib_sock_accept (ShibSocket listener, ShibSocket* s);
134
135 /*
136  * close the socket
137  */
138 SHIBTARGET_EXPORTS void shib_sock_close (ShibSocket s, ShibSockName name);
139
140 /* shib-target.cpp */
141
142 /* application names */
143 #define SHIBTARGET_GENERAL  "general"
144 #define SHIBTARGET_SHAR     "shar"
145 #define SHIBTARGET_SHIRE    "shire"
146 #define SHIBTARGET_RM       "rm"
147 #define SHIBTARGET_POLICIES "policies"
148
149 /* configuration tags */
150 #define SHIBTARGET_TAG_LOGGER   "logger"
151 #define SHIBTARGET_TAG_SCHEMAS  "schemadir"
152 #define SHIBTARGET_TAG_CERTFILE "certfile"
153 #define SHIBTARGET_TAG_KEYFILE  "keyfile"
154 #define SHIBTARGET_TAG_KEYPASS  "keypass"
155 #define SHIBTARGET_TAG_CALIST   "calist"
156
157 #define SHIBTARGET_TAG_AATIMEOUT    "AATimeout"
158 #define SHIBTARGET_TAG_AACONNECTTO  "AAConnectTimeout"
159 #define SHIBTARGET_TAG_SAMLCOMPAT   "SAMLCompat"
160
161 #define SHIBTARGET_TAG_METADATA "metadata"
162
163 #define SHIBTARGET_TAG_DEFAULTLIFE  "defaultLife"
164
165 #define SHIBTARGET_TAG_CACHETYPE    "cacheType"
166 #define SHIBTARGET_TAG_CACHECLEAN   "cacheClean"
167 #define SHIBTARGET_TAG_CACHETIMEOUT "cacheTimeout"
168
169 #define SHIBTARGET_TAG_REQATTRS     "requestAttributes"
170
171 /* initialize and finalize the target library (return 0 on success, 1 on failure) */
172 SHIBTARGET_EXPORTS int shib_target_initialize (const char* application, const char* ini_file);
173 SHIBTARGET_EXPORTS void shib_target_finalize (void);
174
175 /* access socket specifics from C code */
176 SHIBTARGET_EXPORTS ShibSockName shib_target_sockname(void);
177 SHIBTARGET_EXPORTS ShibSockName shib_target_sockacl(unsigned int index);
178
179 #ifdef __cplusplus
180 }
181
182
183 namespace shibtarget {
184   class ResourcePriv;
185   class SHIBTARGET_EXPORTS Resource
186   {
187   public:
188     Resource(const char* resource_url);
189     Resource(std::string resource_url);
190     ~Resource();
191
192     const char* getResource() const;
193     const char* getURL() const;
194     bool equals(Resource*) const;
195     saml::Iterator<saml::SAMLAttribute*> getDesignators() const;
196
197   private:
198     ResourcePriv *m_priv;
199   };
200
201   class RPCHandleInternal;
202   class SHIBTARGET_EXPORTS RPCHandle
203   {
204   public:
205     RPCHandle(ShibSockName shar, u_long program, u_long version);
206     ~RPCHandle();
207
208     CLIENT *    connect(void);  /* locks the HANDLE and returns the CLIENT */
209     void        release(void);  /* unlocks the HANDLE */
210     void        disconnect(void); /* disconnects */
211
212   private:
213     RPCHandleInternal *m_priv;
214   };
215
216   class SHIBTARGET_EXPORTS ShibTargetException : public std::exception
217   {
218   public:
219     explicit ShibTargetException() { m_code = SHIBRPC_OK; }
220     explicit ShibTargetException(ShibRpcStatus code, const char* msg,
221                                  const XMLCh* origin = NULL)
222         { m_code = code; if (msg) m_msg=msg; if (origin) m_origin = origin; }
223     explicit ShibTargetException(ShibRpcStatus code, const std::string& msg,
224                                  const XMLCh* origin = NULL) : m_msg(msg)
225         { m_code=code; if(origin) m_origin = origin; }
226     virtual ~ShibTargetException() throw () {}
227     virtual const char* what() const throw () { return (m_msg.c_str()); }
228     virtual ShibRpcStatus which() const throw () { return (m_code); }
229     virtual const XMLCh* where() const throw () { return m_origin.c_str(); }
230
231   private:
232     ShibRpcStatus       m_code;
233     std::string         m_msg;
234     saml::xstring       m_origin;
235   };
236
237   class RPCErrorPriv;
238   class SHIBTARGET_EXPORTS RPCError
239   {
240   public:
241     RPCError() { init(0, "", NULL); }
242     RPCError(ShibRpcError* error);
243     RPCError(int s, char const* st, const XMLCh* orig = NULL) { init (s,st,orig); }
244     RPCError(ShibTargetException &exp) { init(exp.which(), exp.what(), exp.where()); }
245     ~RPCError();
246
247     bool        isError();
248     bool        isRetryable();
249
250     // Return a set of strings that corresponds to the type, text, and desc
251     const char* getType();
252     const char* getText();
253     const char* getDesc();
254     std::string getOriginErrorURL();
255     std::string getOriginContactName();
256     std::string getOriginContactEmail();
257     int getCode();
258
259   private:
260     void init(int stat, char const* msg, const XMLCh* origin);
261     RPCErrorPriv* m_priv;
262   };
263
264   class SHIBTARGET_EXPORTS SHIREConfig
265   {
266   public:
267     bool        checkIPAddress;
268     time_t      lifetime;
269     time_t      timeout;
270   };
271
272   class SHIREPriv;
273   class SHIBTARGET_EXPORTS SHIRE
274   {
275   public:
276     SHIRE(RPCHandle *rpc, SHIREConfig config, std::string shire_url);
277     ~SHIRE();
278
279     RPCError* sessionIsValid(const char* cookie, const char* ip, const char* url);
280     RPCError* sessionCreate(const char* post, const char* ip,
281                              std::string &cookie);
282   private:
283     SHIREPriv *m_priv;
284   };
285
286   class SHIBTARGET_EXPORTS RMConfig
287   {
288   public:
289     bool        checkIPAddress;
290   };
291
292   class RMPriv;
293   class SHIBTARGET_EXPORTS RM
294   {
295   public:
296     RM(RPCHandle *rpc, RMConfig config);
297     ~RM();
298
299     RPCError* getAssertions(const char* cookie, const char* ip,
300                             const char* url,
301                             std::vector<saml::SAMLAssertion*> &assertions,
302                             saml::SAMLAuthenticationStatement **statement = NULL);
303     static void serialize(saml::SAMLAssertion &assertion, std::string &result);
304     static saml::Iterator<saml::SAMLAttribute*> getAttributes(saml::SAMLAssertion &assertion);
305   private:
306     RMPriv *m_priv;
307   };
308
309   class ShibINIPriv;
310   class SHIBTARGET_EXPORTS ShibINI {
311   public:
312     ShibINI (std::string& file, bool case_sensitive = true) { init(file,case_sensitive); }
313     ShibINI (const char *file, bool case_sensitive = true) {
314       std::string f = file;
315       init(f, case_sensitive);
316     }
317     ~ShibINI ();
318
319     void refresh(void);
320
321     const std::string get (const std::string& header, const std::string& tag);
322     const std::string get (const char* header, const char* tag) {
323       std::string h = header, t = tag;
324       return get(h,t);
325     }
326
327     const std::string operator() (const std::string& header, const std::string& tag)  {
328       return get(header,tag);
329     }
330     const std::string operator() (const char* header, const char* tag) {
331       std::string h = header, t = tag;
332       return get(h,t);
333     }
334
335     bool exists(const std::string& header);
336     bool exists(const std::string& header, const std::string& tag);
337
338     bool exists(const char* header) {
339       std::string s = header;
340       return exists(s);
341     }
342     bool exists(const char* header, const char* tag) {
343       std::string h = header, t = tag;
344       return exists(h,t);
345     }
346
347     // Special method to look for a tag in one header and maybe in the
348     // 'SHIBTARGET_GENERAL' header
349     bool get_tag(std::string& header, std::string& tag, bool try_general,
350                  std::string* result);
351
352     bool get_tag(std::string& header, const char* tag, bool try_general,
353                  std::string* result) {
354       std::string t = tag;
355       return get_tag (header,t,try_general,result);
356     }
357
358     bool get_tag(const char* header, const char* tag, bool try_general,
359                  std::string* result) {
360       std::string h = header, t = tag;
361       return get_tag (h,t,try_general,result);
362     }
363
364     // Dump out the inifile to the output stream
365     void dump(std::ostream& os);
366
367     // Iterators
368
369     // The begin() functions reset the iterator and return the first element
370     // (or 0 if there are no elements.)
371     // The next() functions return the next element, or 0 if there are no
372     // elements left.
373     //
374     // Example:
375     // for (const foo* current = begin(); current; current = next()) {
376     //   ...
377     // }
378     //
379     // NOTE: Holding an Iterator will lock the INI file and cause it to
380     // stop updating itself.  You should destroy the iterator as soon as
381     // you are done with it.
382     //
383     // ALSO NOTE: the string* returned from the Iterator is only valid
384     // while you hold the iterator.  You should copy the de-reference
385     // of the pointer to your own copy if you want to keep the string.
386
387     class SHIBTARGET_EXPORTS Iterator {
388     public:
389       virtual ~Iterator() {}
390       virtual const std::string* begin() = 0;
391       virtual const std::string* next() = 0;
392     };
393
394     Iterator* header_iterator();
395     Iterator* tag_iterator(const std::string& header);
396
397     static bool boolean(std::string& value);
398
399   private:
400     ShibINIPriv *m_priv;
401     void init(std::string& file, bool case_sensitive);
402   };
403
404   class ShibMLPPriv;
405   class SHIBTARGET_EXPORTS ShibMLP {
406   public:
407     ShibMLP();
408     ~ShibMLP();
409
410     void insert (const std::string& key, const std::string& value);
411     void insert (const std::string& key, const char* value) {
412       std::string v = value;
413       insert (key, v);
414     }
415     void insert (const char* key, const std::string& value) {
416       std::string k = key;
417       insert (k, value);
418     }
419     void insert (const char* key, const char* value) {
420       std::string k = key, v = value;
421       insert(k,v);
422     }
423     void insert (RPCError& e);
424
425     void clear () { m_map.clear(); }
426
427     std::string run (std::istream& s) const;
428     std::string run (const std::string& input) const;
429     std::string run (const char* input) const {
430       std::string i = input;
431       return run(i);
432     }
433
434   private:
435     ShibMLPPriv *m_priv;
436     std::map<std::string,std::string> m_map;
437   };
438
439   class SHIBTARGET_EXPORTS ShibTargetConfig
440   {
441   public:
442     static void preinit();
443     static ShibTargetConfig& init(const char* app_name, const char* inifile);
444     static ShibTargetConfig& getConfig();
445     virtual void init() = 0;
446     virtual void shutdown() = 0;
447     virtual ~ShibTargetConfig() {}
448     virtual ShibINI& getINI() = 0;
449     virtual saml::Iterator<const XMLCh*> getPolicies() = 0;
450   };
451
452 } // namespace
453 #endif
454
455 #endif /* SHIB_TARGET_H */