Add configuration options for AATimeout, AAConnectTimeout, and SAML Compat.
[shibboleth/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_AATIMEOUT "AATimeout"
101 #define SHIBTARGET_TAG_AACONNECTTO "AAConnectTimeout"
102 #define SHIBTARGET_TAG_SAMLCOMPAT "SAMLCompat"
103
104 #define SHIBTARGET_TAG_AAP      "aap-uri"
105 #define SHIBTARGET_TAG_SITES    "sitesFile"
106
107 #define SHIBTARGET_TAG_DEFAULTLIFE      "defaultLife"
108
109 #define SHIBTARGET_TAG_CACHETYPE        "cacheType"
110 #define SHIBTARGET_TAG_CACHECLEAN       "cacheClean"
111 #define SHIBTARGET_TAG_CACHETIMEOUT     "cacheTimeout"
112
113 #define SHIBTARGET_TAG_REQATTRS         "requestAttributes"
114
115 /* initialize and finalize the target library (return 0 on success, 1 on failure) */
116 int shib_target_initialize (const char* application, const char* ini_file);
117 void shib_target_finalize (void);
118 ShibSockName shib_target_sockname(void);
119
120 #ifdef __cplusplus
121 }
122
123
124 namespace shibtarget {
125   class ResourcePriv;
126   class Resource
127   {
128   public:
129     Resource(const char* resource_url);
130     Resource(std::string resource_url);
131     ~Resource();
132
133     const char* getResource() const;
134     const char* getURL() const;
135     bool equals(Resource*) const;
136     saml::Iterator<saml::SAMLAttribute*> getDesignators() const;
137
138   private:
139     ResourcePriv *m_priv;
140   };
141
142   class RPCHandleInternal;
143   class RPCHandle
144   {
145   public:
146     RPCHandle(ShibSockName shar, u_long program, u_long version);
147     ~RPCHandle();
148
149     CLIENT *    connect(void);  /* locks the HANDLE and returns the CLIENT */
150     void        release(void);  /* unlocks the HANDLE */
151     void        disconnect(void); /* disconnects */
152
153   private:
154     RPCHandleInternal *m_priv;
155   };
156
157   class ShibTargetException : public std::exception
158   {
159   public:
160     explicit ShibTargetException() { m_code = SHIBRPC_OK; }
161     explicit ShibTargetException(ShibRpcStatus code, const char* msg,
162                                  const XMLCh* origin = NULL)
163         { m_code = code; if (msg) m_msg=msg; if (origin) m_origin = origin; }
164     explicit ShibTargetException(ShibRpcStatus code, const std::string& msg,
165                                  const XMLCh* origin = NULL) : m_msg(msg)
166         { m_code=code; if(origin) m_origin = origin; }
167     virtual ~ShibTargetException() throw () {}
168     virtual const char* what() const throw () { return (m_msg.c_str()); }
169     virtual ShibRpcStatus which() const throw () { return (m_code); }
170     virtual const XMLCh* where() const throw () { return m_origin.c_str(); }
171
172   private:
173     ShibRpcStatus       m_code;
174     std::string         m_msg;
175     saml::xstring       m_origin;
176   };
177
178   class RPCErrorPriv;
179   class RPCError
180   {
181   public:
182     RPCError() { init(0, "", NULL); }
183     RPCError(ShibRpcError* error);
184     RPCError(int s, char const* st, const XMLCh* orig = NULL) { init (s,st,orig); }
185     RPCError(ShibTargetException &exp) { init(exp.which(), exp.what(), exp.where()); }
186     ~RPCError();
187
188     bool        isError();
189     bool        isRetryable();
190
191     // Return a set of strings that corresponds to the type, text, and desc
192     const char* getType();
193     const char* getText();
194     const char* getDesc();
195     const char* getOriginErrorURL();
196     const char* getOriginContactName();
197     const char* getOriginContactEmail();
198     int getCode();
199
200   private:
201     void init(int stat, char const* msg, const XMLCh* origin);
202     RPCErrorPriv* m_priv;
203   };
204
205   class SHIREConfig
206   {
207   public:
208     bool        checkIPAddress;
209     time_t      lifetime;
210     time_t      timeout;
211   };
212
213   class SHIREPriv;
214   class SHIRE
215   {
216   public:
217     SHIRE(RPCHandle *rpc, SHIREConfig config, std::string shire_url);
218     ~SHIRE();
219
220     RPCError* sessionIsValid(const char* cookie, const char* ip, const char* url);
221     RPCError* sessionCreate(const char* post, const char* ip,
222                              std::string &cookie);
223   private:
224     SHIREPriv *m_priv;
225   };
226
227   class RMConfig
228   {
229   public:
230     bool        checkIPAddress;
231   };
232
233   class RMPriv;
234   class RM
235   {
236   public:
237     RM(RPCHandle *rpc, RMConfig config);
238     ~RM();
239
240     RPCError* getAssertions(const char* cookie, const char* ip,
241                             const char* url,
242                             std::vector<saml::SAMLAssertion*> &assertions,
243                             saml::SAMLAuthenticationStatement **statement = NULL);
244     static void serialize(saml::SAMLAssertion &assertion, std::string &result);
245     static saml::Iterator<saml::SAMLAttribute*> getAttributes(saml::SAMLAssertion &assertion);
246   private:
247     RMPriv *m_priv;
248   };
249
250   class ShibINIPriv;
251   class ShibINI {
252   public:
253     ShibINI (std::string& file, bool case_sensitive = true) { init(file,case_sensitive); }
254     ShibINI (const char *file, bool case_sensitive = true) {
255       std::string f = file;
256       init(f, case_sensitive);
257     }
258     ~ShibINI ();
259
260     void refresh(void);
261
262     const std::string get (const std::string& header, const std::string& tag);
263     const std::string get (const char* header, const char* tag) {
264       std::string h = header, t = tag;
265       return get(h,t);
266     }
267
268     const std::string operator() (const std::string& header, const std::string& tag)  {
269       return get(header,tag);
270     }
271     const std::string operator() (const char* header, const char* tag) {
272       std::string h = header, t = tag;
273       return get(h,t);
274     }
275
276     bool exists(const std::string& header);
277     bool exists(const std::string& header, const std::string& tag);
278
279     bool exists(const char* header) {
280       std::string s = header;
281       return exists(s);
282     }
283     bool exists(const char* header, const char* tag) {
284       std::string h = header, t = tag;
285       return exists(h,t);
286     }
287
288     // Special method to look for a tag in one header and maybe in the
289     // 'SHIBTARGET_GENERAL' header
290     bool get_tag(std::string& header, std::string& tag, bool try_general,
291                  std::string* result);
292
293     bool get_tag(std::string& header, const char* tag, bool try_general,
294                  std::string* result) {
295       std::string t = tag;
296       return get_tag (header,t,try_general,result);
297     }
298
299     bool get_tag(const char* header, const char* tag, bool try_general,
300                  std::string* result) {
301       std::string h = header, t = tag;
302       return get_tag (h,t,try_general,result);
303     }
304
305     // Dump out the inifile to the output stream
306     void dump(std::ostream& os);
307
308     // Iterators
309
310     // The begin() functions reset the iterator and return the first element
311     // (or 0 if there are no elements.)
312     // The next() functions return the next element, or 0 if there are no
313     // elements left.
314     //
315     // Example:
316     // for (const foo* current = begin(); current; current = next()) {
317     //   ...
318     // }
319     //
320     // NOTE: Holding an Iterator will lock the INI file and cause it to
321     // stop updating itself.  You should destroy the iterator as soon as
322     // you are done with it.
323     //
324     // ALSO NOTE: the string* returned from the Iterator is only valid
325     // while you hold the iterator.  You should copy the de-reference
326     // of the pointer to your own copy if you want to keep the string.
327
328     class Iterator {
329     public:
330       virtual ~Iterator() = 0;
331       virtual const std::string* begin() = 0;
332       virtual const std::string* next() = 0;
333     };
334
335     Iterator* header_iterator();
336     Iterator* tag_iterator(const std::string& header);
337
338     static bool boolean(std::string& value);
339
340   private:
341     ShibINIPriv *m_priv;
342     void init(std::string& file, bool case_sensitive);
343   };
344
345   class ShibMLPPriv;
346   class ShibMLP {
347   public:
348     ShibMLP();
349     ~ShibMLP();
350
351     void insert (const std::string& key, const std::string& value) { m_map[key] = value; }
352     void insert (const std::string& key, const char* value) {
353       std::string v = value;
354       insert (key, v);
355     }
356     void insert (const char* key, const std::string& value) {
357       std::string k = key;
358       insert (k, value);
359     }
360     void insert (const char* key, const char* value) {
361       std::string k = key, v = value;
362       insert(k,v);
363     }
364     void insert (RPCError& e);
365
366     void clear () { m_map.clear(); }
367
368     std::string run (std::istream& s) const;
369     std::string run (const std::string& input) const;
370     std::string run (const char* input) const {
371       std::string i = input;
372       return run(i);
373     }
374
375   private:
376     ShibMLPPriv *m_priv;
377     std::map<std::string,std::string> m_map;
378   };
379
380   class ShibTargetConfig
381   {
382   public:
383     static void preinit();
384     static ShibTargetConfig& init(const char* app_name, const char* inifile);
385     static ShibTargetConfig& getConfig();
386     virtual void init() = 0;
387     virtual void shutdown() = 0;
388     virtual ~ShibTargetConfig();
389     virtual ShibINI& getINI() = 0;
390     virtual saml::Iterator<const XMLCh*> getPolicies() = 0;
391     
392     ShibSockName m_SocketName;
393   };
394
395 } // namespace
396 #endif
397
398 #endif /* SHIB_TARGET_H */