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