Add support for the originErrorURL, originContactName, and originContactEmail
[shibboleth/cpp-sp.git] / shib-target / shib-target.h
1 /*
2  * shib-target.h -- top-level header file for the SHIB Common Target Library
3  *
4  * Created by:  Derek Atkins <derek@ihtfp.com>
5  *
6  * $Id$
7  */
8
9 #ifndef SHIB_TARGET_H
10 #define SHIB_TARGET_H
11
12 #ifdef __cplusplus
13 # include <saml/saml.h>
14 # include <shib/shib.h>
15 #endif
16
17 #include <shib-target/shibrpc.h>
18
19 #ifdef __cplusplus
20 extern "C" {
21 #endif
22
23 #ifdef WIN32
24
25 #include <winsock.h>
26 typedef SOCKET ShibSocket;
27 typedef u_short ShibSockName;
28 #define SHIB_SHAR_SOCKET 12345  /* shar portnumber */
29
30 #else  /* UNIX */
31
32 typedef int ShibSocket;
33 typedef char * ShibSockName;
34 #define SHIB_SHAR_SOCKET "/tmp/shar-socket"
35
36 #endif
37
38 /* shib-rpcutil.c */
39
40 /* Create an RPC Client handle for the _connected_ socket sock, attaching
41  * the RPC program and version.
42  *
43  * returns a CLIENT on success, or NULL on error.  The caller can
44  * call clnt_pcreateerror ("<string>") to output an error message from
45  * the RPC library.
46  */
47 CLIENT * shibrpc_client_create (ShibSocket sock, u_long program, u_long version);
48
49 /* shib-sock.c */
50
51 /* Create a new socket and put it into sock.
52  *
53  * Returns 0 on success, non-zero on error 
54  */
55 int shib_sock_create (ShibSocket *sock);
56
57 /*
58  * bind the socket s to the "port" name.
59  *
60  * Returns 0 on success; non-zero on error.
61  *
62  * SIDE EFFECT: On error, the socket is closed!
63  */
64 int shib_sock_bind (ShibSocket s, ShibSockName name);
65
66 /*
67  * connect the socket s to the "port" name on the local host.
68  *
69  * Returns 0 on success; non-zero on error.
70  */
71 int shib_sock_connect (ShibSocket s, ShibSockName name);
72
73 /*
74  * accept a connection.  Returns 0 on success, non-zero on failure.
75  */
76 int shib_sock_accept (ShibSocket listener, ShibSocket* s);
77
78 /*
79  * close the socket
80  */
81 void shib_sock_close (ShibSocket s, ShibSockName name);
82
83 /* shib-target.cpp */
84
85 /* application names */
86 #define SHIBTARGET_GENERAL      "general"
87 #define SHIBTARGET_SHAR     "shar"
88 #define SHIBTARGET_SHIRE        "shire"
89 #define SHIBTARGET_RM           "rm"
90 #define SHIBTARGET_POLICIES "policies"
91
92 /* configuration tags */
93 #define SHIBTARGET_TAG_LOGGER   "logger"
94 #define SHIBTARGET_TAG_SCHEMAS  "schemadir"
95 #define SHIBTARGET_TAG_CERTFILE "certfile"
96 #define SHIBTARGET_TAG_KEYFILE  "keyfile"
97 #define SHIBTARGET_TAG_KEYPASS  "keypass"
98 #define SHIBTARGET_TAG_CALIST   "calist"
99
100 #define SHIBTARGET_TAG_AAP      "aap-uri"
101 #define SHIBTARGET_TAG_SITES    "sitesFile"
102
103 #define SHIBTARGET_TAG_DEFAULTLIFE      "defaultLife"
104
105 #define SHIBTARGET_TAG_CACHETYPE        "cacheType"
106 #define SHIBTARGET_TAG_CACHECLEAN       "cacheClean"
107 #define SHIBTARGET_TAG_CACHETIMEOUT     "cacheTimeout"
108
109 #define SHIBTARGET_TAG_REQATTRS         "requestAttributes"
110
111 /* initialize and finalize the target library (return 0 on success, 1 on failure) */
112 int shib_target_initialize (const char* application, const char* ini_file);
113 void shib_target_finalize (void);
114 ShibSockName shib_target_sockname(void);
115
116 #ifdef __cplusplus
117 }
118
119
120 namespace shibtarget {
121   class ResourcePriv;
122   class Resource
123   {
124   public:
125     Resource(const char* resource_url);
126     Resource(std::string resource_url);
127     ~Resource();
128
129     const char* getResource() const;
130     const char* getURL() const;
131     bool equals(Resource*) const;
132     saml::Iterator<saml::SAMLAttribute*> getDesignators() const;
133
134   private:
135     ResourcePriv *m_priv;
136   };
137
138   class RPCHandleInternal;
139   class RPCHandle
140   {
141   public:
142     RPCHandle(ShibSockName shar, u_long program, u_long version);
143     ~RPCHandle();
144
145     CLIENT *    connect(void);  /* locks the HANDLE and returns the CLIENT */
146     void        release(void);  /* unlocks the HANDLE */
147     void        disconnect(void); /* disconnects */
148
149   private:
150     RPCHandleInternal *m_priv;
151   };
152
153   class ShibTargetException : public std::exception
154   {
155   public:
156     explicit ShibTargetException() { m_code = SHIBRPC_OK; m_msg=""; }
157     explicit ShibTargetException(ShibRpcStatus code, const char* msg) { m_code = code; if (msg) m_msg=msg; }
158     explicit ShibTargetException(ShibRpcStatus code, const std::string& msg) : m_msg(msg) { m_code=code; }
159     virtual ~ShibTargetException() throw () {}
160     virtual const char* what() const throw () { return (m_msg.c_str()); }
161     virtual ShibRpcStatus which() const throw () { return (m_code); }
162
163   private:
164     ShibRpcStatus       m_code;
165     std::string         m_msg;
166   };
167
168   class RPCErrorPriv;
169   class RPCError
170   {
171   public:
172     RPCError() { init(0,""); }
173     RPCError(int s, char const* st) { init(s,st); }
174     RPCError(ShibTargetException &exp) { init(exp.which(), exp.what()); }
175     ~RPCError();
176
177     bool        isError();
178     bool        isRetryable();
179
180     // Return a set of strings that corresponds to the type, text, and desc
181     const char* getType();
182     const char* getText();
183     const char* getDesc();
184     const char* getOriginErrorURL();
185     const char* getOriginContactName();
186     const char* getOriginContactEmail();
187     int getCode();
188
189   private:
190     void init(int code, char const* msg);
191     RPCErrorPriv* m_priv;
192   };
193
194   class SHIREConfig
195   {
196   public:
197     bool        checkIPAddress;
198     time_t      lifetime;
199     time_t      timeout;
200   };
201
202   class SHIREPriv;
203   class SHIRE
204   {
205   public:
206     SHIRE(RPCHandle *rpc, SHIREConfig config, std::string shire_url);
207     ~SHIRE();
208
209     RPCError* sessionIsValid(const char* cookie, const char* ip, const char* url);
210     RPCError* sessionCreate(const char* post, const char* ip,
211                              std::string &cookie);
212   private:
213     SHIREPriv *m_priv;
214   };
215
216   class RMConfig
217   {
218   public:
219     bool        checkIPAddress;
220   };
221
222   class RMPriv;
223   class RM
224   {
225   public:
226     RM(RPCHandle *rpc, RMConfig config);
227     ~RM();
228
229     RPCError* getAssertions(const char* cookie, const char* ip,
230                             const char* url,
231                             std::vector<saml::SAMLAssertion*> &assertions,
232                             saml::SAMLAuthenticationStatement **statement = NULL);
233     static void serialize(saml::SAMLAssertion &assertion, std::string &result);
234     static saml::Iterator<saml::SAMLAttribute*> getAttributes(saml::SAMLAssertion &assertion);
235   private:
236     RMPriv *m_priv;
237   };
238
239   class ShibINIPriv;
240   class ShibINI {
241   public:
242     ShibINI (std::string& file, bool case_sensitive = true) { init(file,case_sensitive); }
243     ShibINI (const char *file, bool case_sensitive = true) {
244       std::string f = file;
245       init(f, case_sensitive);
246     }
247     ~ShibINI ();
248
249     void refresh(void);
250
251     const std::string get (const std::string& header, const std::string& tag);
252     const std::string get (const char* header, const char* tag) {
253       std::string h = header, t = tag;
254       return get(h,t);
255     }
256
257     const std::string operator() (const std::string& header, const std::string& tag)  {
258       return get(header,tag);
259     }
260     const std::string operator() (const char* header, const char* tag) {
261       std::string h = header, t = tag;
262       return get(h,t);
263     }
264
265     bool exists(const std::string& header);
266     bool exists(const std::string& header, const std::string& tag);
267
268     bool exists(const char* header) {
269       std::string s = header;
270       return exists(s);
271     }
272     bool exists(const char* header, const char* tag) {
273       std::string h = header, t = tag;
274       return exists(h,t);
275     }
276
277     // Special method to look for a tag in one header and maybe in the
278     // 'SHIBTARGET_GENERAL' header
279     bool get_tag(std::string& header, std::string& tag, bool try_general,
280                  std::string* result);
281
282     bool get_tag(std::string& header, const char* tag, bool try_general,
283                  std::string* result) {
284       std::string t = tag;
285       return get_tag (header,t,try_general,result);
286     }
287
288     bool get_tag(const char* header, const char* tag, bool try_general,
289                  std::string* result) {
290       std::string h = header, t = tag;
291       return get_tag (h,t,try_general,result);
292     }
293
294     // Dump out the inifile to the output stream
295     void dump(std::ostream& os);
296
297     // Iterators
298
299     // The begin() functions reset the iterator and return the first element
300     // (or 0 if there are no elements.)
301     // The next() functions return the next element, or 0 if there are no
302     // elements left.
303     //
304     // Example:
305     // for (const foo* current = begin(); current; current = next()) {
306     //   ...
307     // }
308     //
309     // NOTE: Holding an Iterator will lock the INI file and cause it to
310     // stop updating itself.  You should destroy the iterator as soon as
311     // you are done with it.
312     //
313     // ALSO NOTE: the string* returned from the Iterator is only valid
314     // while you hold the iterator.  You should copy the de-reference
315     // of the pointer to your own copy if you want to keep the string.
316
317     class Iterator {
318     public:
319       virtual ~Iterator() = 0;
320       virtual const std::string* begin() = 0;
321       virtual const std::string* next() = 0;
322     };
323
324     Iterator* header_iterator();
325     Iterator* tag_iterator(const std::string& header);
326
327     static bool boolean(std::string& value);
328
329   private:
330     ShibINIPriv *m_priv;
331     void init(std::string& file, bool case_sensitive);
332   };
333
334   class ShibMLPPriv;
335   class ShibMLP {
336   public:
337     ShibMLP();
338     ~ShibMLP();
339
340     void insert (const std::string& key, const std::string& value) { m_map[key] = value; }
341     void insert (const std::string& key, const char* value) {
342       std::string v = value;
343       insert (key, v);
344     }
345     void insert (const char* key, const std::string& value) {
346       std::string k = key;
347       insert (k, value);
348     }
349     void insert (const char* key, const char* value) {
350       std::string k = key, v = value;
351       insert(k,v);
352     }
353     void insert (RPCError& e);
354
355     void clear () { m_map.clear(); }
356
357     std::string run (std::istream& s) const;
358     std::string run (const std::string& input) const;
359     std::string run (const char* input) const {
360       std::string i = input;
361       return run(i);
362     }
363
364   private:
365     ShibMLPPriv *m_priv;
366     std::map<std::string,std::string> m_map;
367   };
368
369   class ShibTargetConfig
370   {
371   public:
372     static void preinit();
373     static ShibTargetConfig& init(const char* app_name, const char* inifile);
374     static ShibTargetConfig& getConfig();
375     virtual void init() = 0;
376     virtual void shutdown() = 0;
377     virtual ~ShibTargetConfig();
378     virtual ShibINI& getINI() = 0;
379     virtual saml::Iterator<const XMLCh*> getPolicies() = 0;
380     
381     ShibSockName m_SocketName;
382   };
383
384 } // namespace
385 #endif
386
387 #endif /* SHIB_TARGET_H */