port to new RADIUS client library
[radsecproxy.git] / lib / include / radsec / radsec.h
1 /** \file radsec.h
2     \brief Public interface for libradsec.  */
3
4 /* See the file COPYING for licensing information.  */
5
6 #ifndef _RADSEC_RADSEC_H_
7 #define _RADSEC_RADSEC_H_ 1
8
9 #include <unistd.h>
10 #include <stdint.h>
11
12 #include <arpa/inet.h>
13 #include <sys/time.h>
14
15 enum rs_error_code {
16     RSE_OK = 0,
17     RSE_NOMEM = 1,
18     RSE_NOSYS = 2,
19     RSE_INVALID_CTX = 3,
20     RSE_INVALID_CONN = 4,
21     RSE_CONN_TYPE_MISMATCH = 5,
22     RSE_FR = 6,
23     RSE_BADADDR = 7,
24     RSE_NOPEER = 8,
25     RSE_EVENT = 9,              /* libevent error.  */
26     RSE_SOCKERR = 10,
27     RSE_CONFIG = 11,
28     RSE_BADAUTH = 12,
29     RSE_INTERNAL = 13,
30     RSE_SSLERR = 14,            /* OpenSSL error.  */
31     RSE_INVALID_PKT = 15,
32     RSE_TIMEOUT_CONN = 16,      /* Connection timeout.  */
33     RSE_INVAL = 17,             /* Invalid argument.  */
34     RSE_TIMEOUT_IO = 18,        /* I/O timeout.  */
35     RSE_TIMEOUT= 19,            /* High level timeout.  */
36     RSE_DISCO = 20,
37     RSE_INUSE = 21,
38     RSE_PACKET_TOO_SMALL = 22,
39     RSE_PACKET_TOO_LARGE = 23,
40     RSE_ATTR_OVERFLOW = 24,
41     RSE_ATTR_TOO_SMALL = 25,
42     RSE_ATTR_TOO_LARGE = 26,
43     RSE_ATTR_UNKNOWN = 27,
44     RSE_ATTR_BAD_NAME = 28,
45     RSE_ATTR_VALUE_MALFORMED = 29,
46     RSE_ATTR_INVALID = 30,
47     RSE_TOO_MANY_ATTRS = 31,
48     RSE_ATTR_TYPE_UNKNOWN = 32,
49     RSE_MSG_AUTH_LEN = 33,
50     RSE_MSG_AUTH_WRONG = 34,
51     RSE_REQUEST_REQUIRED = 35,
52     RSE_INVALID_REQUEST_CODE = 36,
53     RSE_AUTH_VECTOR_WRONG = 37,
54     RSE_INVALID_RESPONSE_CODE = 38,
55     RSE_INVALID_RESPONSE_ID = 39,
56     RSE_INVALID_RESPONSE_SRC = 40,
57     RSE_NO_PACKET_DATA = 41,
58     RSE_VENDOR_UNKNOWN = 42,
59     RSE_MAX = RSE_VENDOR_UNKNOWN
60 };
61
62 enum rs_conn_type {
63     RS_CONN_TYPE_NONE = 0,
64     RS_CONN_TYPE_UDP,
65     RS_CONN_TYPE_TCP,
66     RS_CONN_TYPE_TLS,
67     RS_CONN_TYPE_DTLS,
68 };
69 typedef unsigned int rs_conn_type_t;
70
71 typedef enum rs_attr_type_t {
72     RS_TYPE_INVALID = 0,                /**< Invalid data type */
73     RS_TYPE_STRING,                     /**< printable-text */
74     RS_TYPE_INTEGER,                    /**< a 32-bit unsigned integer */
75     RS_TYPE_IPADDR,                     /**< an IPv4 address */
76     RS_TYPE_DATE,                       /**< a 32-bit date, of seconds since January 1, 1970 */
77     RS_TYPE_OCTETS,                     /**< a sequence of binary octets */
78     RS_TYPE_IFID,                       /**< an Interface Id */
79     RS_TYPE_IPV6ADDR,                   /**< an IPv6 address */
80     RS_TYPE_IPV6PREFIX,                 /**< an IPv6 prefix */
81     RS_TYPE_BYTE,                       /**< an 8-bit integer */
82     RS_TYPE_SHORT,                      /**< a 16-bit integer */
83 } rs_attr_type_t;
84
85 #define PW_ACCESS_REQUEST               1
86 #define PW_ACCESS_ACCEPT                2
87 #define PW_ACCESS_REJECT                3
88 #define PW_ACCOUNTING_REQUEST           4
89 #define PW_ACCOUNTING_RESPONSE          5
90 #define PW_ACCOUNTING_STATUS            6
91 #define PW_PASSWORD_REQUEST             7
92 #define PW_PASSWORD_ACK                 8
93 #define PW_PASSWORD_REJECT              9
94 #define PW_ACCOUNTING_MESSAGE           10
95 #define PW_ACCESS_CHALLENGE             11
96 #define PW_STATUS_SERVER                12
97 #define PW_STATUS_CLIENT                13
98 #define PW_DISCONNECT_REQUEST           40
99 #define PW_DISCONNECT_ACK               41
100 #define PW_DISCONNECT_NAK               42
101 #define PW_COA_REQUEST                  43
102 #define PW_COA_ACK                      44
103 #define PW_COA_NAK                      45
104
105 #if defined (__cplusplus)
106 extern "C" {
107 #endif
108
109 /* Data types.  */
110 struct rs_context;              /* radsec-impl.h */
111 struct rs_connection;           /* radsec-impl.h */
112 struct rs_packet;               /* radsec-impl.h */
113 struct rs_conn;                 /* radsec-impl.h */
114 struct rs_error;                /* radsec-impl.h */
115 struct rs_peer;                 /* radsec-impl.h */
116 struct radius_packet;           /* <radius/client.h> */
117 struct value_pair;              /* <radius/client.h> */
118 struct event_base;              /* <event2/event-internal.h> */
119
120 typedef void *(*rs_calloc_fp) (size_t nmemb, size_t size);
121 typedef void *(*rs_malloc_fp) (size_t size);
122 typedef void (*rs_free_fp) (void *ptr);
123 typedef void *(*rs_realloc_fp) (void *ptr, size_t size);
124 struct rs_alloc_scheme {
125     rs_calloc_fp calloc;
126     rs_malloc_fp malloc;
127     rs_free_fp free;
128     rs_realloc_fp realloc;
129 };
130
131 typedef void (*rs_conn_connected_cb) (void *user_data /* FIXME: peer? */ );
132 typedef void (*rs_conn_disconnected_cb) (void *user_data /* FIXME: reason? */ );
133 typedef void (*rs_conn_packet_received_cb) (struct rs_packet *packet,
134                                             void *user_data);
135 typedef void (*rs_conn_packet_sent_cb) (void *user_data);
136 struct rs_conn_callbacks {
137     /** Callback invoked when the connection has been established.  */
138     rs_conn_connected_cb connected_cb;
139     /** Callback invoked when the connection has been torn down.  */
140     rs_conn_disconnected_cb disconnected_cb;
141     /** Callback invoked when a packet was received.  */
142     rs_conn_packet_received_cb received_cb;
143     /** Callback invoked when a packet was successfully sent.  */
144     rs_conn_packet_sent_cb sent_cb;
145 };
146
147 typedef struct value_pair rs_avp;
148 typedef const struct value_pair rs_const_avp;
149
150 /* Function prototypes.  */
151
152 /*************/
153 /* Context.  */
154 /*************/
155 /** Create a context.  Freed by calling \a rs_context_destroy.  Note
156     that the context must not be freed before all other libradsec
157     objects have been freed.
158
159     \a ctx Address of pointer to a struct rs_context.  This is the
160     output of this function.
161
162     \return RSE_OK (0) on success or RSE_NOMEM on out of memory.  */
163 int rs_context_create(struct rs_context **ctx);
164
165 /** Free a context.  Note that the context must not be freed before
166     all other libradsec objects have been freed.  */
167 void rs_context_destroy(struct rs_context *ctx);
168
169 /** Initialize FreeRADIUS dictionary needed for creating packets.
170
171     \a ctx Context.
172
173     \a dict Optional string with full path to FreeRADIUS dictionary.
174     If \a dict is NULL the path to the dictionary file is taken from
175     the "dictionary" configuration directive.  Note that the
176     configuration file must be read prior to using this option (see \a
177     rs_context_read_config).
178
179     \return RSE_OK (0) on success, RSE_NOMEM on memory allocation
180     error and RSE_FR on FreeRADIUS error.  */
181 int rs_context_init_freeradius_dict(struct rs_context *ctx, const char *dict);
182
183 /** Set allocation scheme to use.  \a scheme is the allocation scheme
184     to use, see \a rs_alloc_scheme.  \return On success, RSE_OK (0) is
185     returned.  On error, !0 is returned and a struct \a rs_error is
186     pushed on the error stack for the context.  The error can be
187     accessed using \a rs_err_ctx_pop.  */
188 int rs_context_set_alloc_scheme(struct rs_context *ctx,
189                                 struct rs_alloc_scheme *scheme);
190
191 /** Read configuration file. \a config_file is the path of the
192     configuration file to read.  \return On success, RSE_OK (0) is
193     returned.  On error, !0 is returned and a struct \a rs_error is
194     pushed on the error stack for the context.  The error can be
195     accessed using \a rs_err_ctx_pop.  */
196 int rs_context_read_config(struct rs_context *ctx, const char *config_file);
197
198 /****************/
199 /* Connection.  */
200 /****************/
201 /** Create a connection.  \a conn is the address of a pointer to an \a
202     rs_connection, the output.  Free the connection using \a
203     rs_conn_destroy.  Note that a connection must not be freed before
204     all packets associated with the connection have been freed.  A
205     packet is associated with a connection when it's created (\a
206     rs_packet_create) or received (\a rs_conn_receive_packet).
207
208     If \a config is not NULL it should be the name of a configuration
209     found in the config file read in using \a rs_context_read_config.
210     \return On success, RSE_OK (0) is returned.  On error, !0 is
211     returned and a struct \a rs_error is pushed on the error stack for
212     the context.  The error can be accessed using \a
213     rs_err_ctx_pop.  */
214 int rs_conn_create(struct rs_context *ctx,
215                    struct rs_connection **conn,
216                    const char *config);
217
218 /** Not implemented.  */
219 int rs_conn_add_listener(struct rs_connection *conn,
220                          rs_conn_type_t type,
221                          const char *hostname,
222                          int port);
223 /** Disconnect connection \a conn.  \return RSE_OK (0) on success, !0
224  * on error.  On error, errno is set appropriately.  */
225 int rs_conn_disconnect (struct rs_connection *conn);
226
227 /** Disconnect and free memory allocated for connection \a conn.  Note
228     that a connection must not be freed before all packets associated
229     with the connection have been freed.  A packet is associated with
230     a connection when it's created (\a rs_packet_create) or received
231     (\a rs_conn_receive_packet).  \return RSE_OK (0) on success, !0 *
232     on error.  On error, errno is set appropriately. */
233 int rs_conn_destroy(struct rs_connection *conn);
234
235 /** Set connection type for \a conn.  */
236 void rs_conn_set_type(struct rs_connection *conn, rs_conn_type_t type);
237
238 /** Not implemented.  */
239 int rs_conn_set_eventbase(struct rs_connection *conn, struct event_base *eb);
240
241 /** Register callbacks \a cb for connection \a conn.  */
242 void rs_conn_set_callbacks(struct rs_connection *conn,
243                            struct rs_conn_callbacks *cb);
244
245 /** Remove callbacks for connection \a conn.  */
246 void rs_conn_del_callbacks(struct rs_connection *conn);
247
248 /** Return callbacks registered for connection \a conn.  \return
249     Installed callbacks are returned.  */
250 struct rs_conn_callbacks *rs_conn_get_callbacks(struct rs_connection *conn);
251
252 /** Not implemented.  */
253 int rs_conn_select_peer(struct rs_connection *conn, const char *name);
254
255 /** Not implemented.  */
256 int rs_conn_get_current_peer(struct rs_connection *conn,
257                              const char *name,
258                              size_t buflen);
259
260 /** Special function used in blocking mode, i.e. with no callbacks
261     registered.  For any other use of libradsec, a \a received_cb
262     callback should be registered using \a rs_conn_set_callbacks.
263
264     If \a req_msg is not NULL, a successfully received RADIUS message
265     is verified against it.  If \a pkt_out is not NULL it will upon
266     return contain a pointer to an \a rs_packet containing the new
267     message.
268
269     \return On error or if the connect (TCP only) or read times out,
270     \a pkt_out will not be changed and one or more errors are pushed
271     on \a conn (available through \a rs_err_conn_pop).  */
272 int rs_conn_receive_packet(struct rs_connection *conn,
273                            struct rs_packet *request,
274                            struct rs_packet **pkt_out);
275
276 /** Get the file descriptor associated with connection \a conn.
277  * \return File descriptor.  */
278 int rs_conn_fd(struct rs_connection *conn);
279
280 /** Set the timeout value for connection \a conn.  */
281 void rs_conn_set_timeout(struct rs_connection *conn, struct timeval *tv);
282
283 /* Peer -- client and server.  */
284 int rs_peer_create(struct rs_connection *conn, struct rs_peer **peer_out);
285 int rs_peer_set_address(struct rs_peer *peer,
286                         const char *hostname,
287                         const char *service);
288 int rs_peer_set_secret(struct rs_peer *peer, const char *secret);
289 void rs_peer_set_timeout(struct rs_peer *peer, int timeout);
290 void rs_peer_set_retries(struct rs_peer *peer, int retries);
291
292 /************/
293 /* Packet.  */
294 /************/
295 /** Create a packet associated with connection \a conn.  */
296 int rs_packet_create(struct rs_connection *conn, struct rs_packet **pkt_out);
297
298 /** Free all memory allocated for packet \a pkt.  */
299 void rs_packet_destroy(struct rs_packet *pkt);
300
301 /** Send packet \a pkt on the connection associated with \a pkt.  \a
302     user_data is sent to the \a rs_conn_packet_received_cb callback
303     registered with the connection.  If no callback is registered with
304     the connection, the event loop is run by \a rs_packet_send and it
305     blocks until the packet has been succesfully sent.
306
307     \return On success, RSE_OK (0) is returned.  On error, !0 is
308     returned and a struct \a rs_error is pushed on the error stack for
309     the connection.  The error can be accessed using \a
310     rs_err_conn_pop.  */
311 int rs_packet_send(struct rs_packet *pkt, void *user_data);
312
313 /** Create a RADIUS authentication request packet associated with
314     connection \a conn.  Optionally, User-Name and User-Password
315     attributes are added to the packet using the data in \a user_name
316     and \a user_pw.  */
317 int rs_packet_create_authn_request(struct rs_connection *conn,
318                                    struct rs_packet **pkt,
319                                    const char *user_name,
320                                    const char *user_pw);
321
322 /*** Append \a tail to packet \a pkt.  */
323 int
324 rs_packet_append_avp(struct rs_packet *pkt,
325                      unsigned int attribute, unsigned int vendor,
326                      const void *data, size_t data_len);
327
328 /*** Get pointer to \a pkt attribute value pairs. */
329 void
330 rs_packet_avps(struct rs_packet *pkt, rs_avp ***vps);
331
332 /*** Get RADIUS packet type of \a pkt. */
333 unsigned int
334 rs_packet_code(struct rs_packet *pkt);
335
336 /*** Get RADIUS AVP from \a pkt. */
337 rs_const_avp *
338 rs_packet_find_avp(struct rs_packet *pkt, unsigned int attr, unsigned int vendor);
339
340 /*** Set packet identifier in \a pkt; returns old identifier */
341 int
342 rs_packet_set_id (struct rs_packet *pkt, int id);
343
344 /************/
345 /* Config.  */
346 /************/
347 /** Find the realm named \a name in the configuration file previoiusly
348     read in using \a rs_context_read_config.  */
349 struct rs_realm *rs_conf_find_realm(struct rs_context *ctx, const char *name);
350
351 /***********/
352 /* Error.  */
353 /***********/
354 /** Create a struct \a rs_error and push it on a FIFO associated with
355     context \a ctx.  Note: The depth of the error stack is one (1) at
356     the moment.  This will change in a future release.  */
357 int rs_err_ctx_push(struct rs_context *ctx, int code, const char *fmt, ...);
358 int rs_err_ctx_push_fl(struct rs_context *ctx,
359                        int code,
360                        const char *file,
361                        int line,
362                        const char *fmt,
363                        ...);
364 /** Pop the first error from the error FIFO associated with context \a
365     ctx or NULL if there are no errors in the FIFO.  */
366 struct rs_error *rs_err_ctx_pop(struct rs_context *ctx);
367
368 /** Create a struct \a rs_error and push it on a FIFO associated with
369     connection \a conn.  Note: The depth of the error stack is one (1)
370     at the moment.  This will change in a future release.  */
371 int rs_err_conn_push(struct rs_connection *conn,
372                      int code,
373                      const char *fmt,
374                      ...);
375 int rs_err_conn_push_fl(struct rs_connection *conn,
376                         int code,
377                         const char *file,
378                         int line,
379                         const char *fmt,
380                         ...);
381 /** Pop the first error from the error FIFO associated with connection
382     \a conn or NULL if there are no errors in the FIFO.  */
383 struct rs_error *rs_err_conn_pop(struct rs_connection *conn);
384
385 int rs_err_conn_peek_code (struct rs_connection *conn);
386 void rs_err_free(struct rs_error *err);
387 char *rs_err_msg(struct rs_error *err);
388 int rs_err_code(struct rs_error *err, int dofree_flag);
389
390 /************/
391 /* AVPs.    */
392 /************/
393 #define rs_avp_is_string(vp)      (rs_avp_typeof(vp) == RS_TYPE_STRING)
394 #define rs_avp_is_integer(vp)     (rs_avp_typeof(vp) == RS_TYPE_INTEGER)
395 #define rs_avp_is_ipaddr(vp)      (rs_avp_typeof(vp) == RS_TYPE_IPADDR)
396 #define rs_avp_is_date(vp)        (rs_avp_typeof(vp) == RS_TYPE_DATE)
397 #define rs_avp_is_octets(vp)      (rs_avp_typeof(vp) == RS_TYPE_OCTETS)
398 #define rs_avp_is_ifid(vp)        (rs_avp_typeof(vp) == RS_TYPE_IFID)
399 #define rs_avp_is_ipv6addr(vp)    (rs_avp_typeof(vp) == RS_TYPE_IPV6ADDR)
400 #define rs_avp_is_ipv6prefix(vp)  (rs_avp_typeof(vp) == RS_TYPE_IPV6PREFIX)
401 #define rs_avp_is_byte(vp)        (rs_avp_typeof(vp) == RS_TYPE_BYTE)
402 #define rs_avp_is_short(vp)       (rs_avp_typeof(vp) == RS_TYPE_SHORT)
403 #define rs_avp_is_tlv(vp)         (rs_avp_typeof(vp) == RS_TYPE_TLV)
404
405 /**  The maximum length of a RADIUS attribute.
406  *
407  *  The RFCs require that a RADIUS attribute transport no more than
408  *  253 octets of data.  We add an extra byte for a trailing NUL, so
409  *  that the VALUE_PAIR::vp_strvalue field can be handled as a C
410  *  string.
411  */
412 #define RS_MAX_STRING_LEN         254
413
414 void
415 rs_avp_free(rs_avp **vps);
416
417 size_t
418 rs_avp_length(rs_const_avp *vp);
419
420 rs_attr_type_t
421 rs_avp_typeof(rs_const_avp *vp);
422
423 void
424 rs_avp_attrid(rs_const_avp *vp, unsigned int *attr, unsigned int *vendor);
425
426
427 void
428 rs_avp_append(rs_avp **head, rs_avp *tail);
429
430 rs_avp *
431 rs_avp_find(rs_avp *vp, unsigned int attr, unsigned int vendor);
432
433 rs_const_avp *
434 rs_avp_find_const(rs_const_avp *vp, unsigned int attr, unsigned int vendor);
435
436 rs_avp *
437 rs_avp_alloc(unsigned int attr, unsigned int vendor);
438
439 rs_avp *
440 rs_avp_dup(rs_const_avp *vp);
441
442 int
443 rs_avp_delete(rs_avp **first, unsigned int attr, unsigned int vendor);
444
445 rs_avp *
446 rs_avp_next(rs_avp *avp);
447
448 rs_const_avp *
449 rs_avp_next_const(rs_const_avp *avp);
450
451 const char *
452 rs_avp_string_value(rs_const_avp *vp);
453
454 int
455 rs_avp_string_set(rs_avp *vp, const char *str);
456
457 uint32_t
458 rs_avp_integer_value(rs_const_avp *vp);
459
460 int
461 rs_avp_integer_set(rs_avp *vp, uint32_t val);
462
463 uint32_t
464 rs_avp_ipaddr_value(rs_const_avp *vp);
465
466 int
467 rs_avp_ipaddr_set(rs_avp *vp, struct in_addr in);
468
469 time_t
470 rs_avp_date_value(rs_const_avp *vp);
471
472 int
473 rs_avp_date_set(rs_avp *vp, time_t date);
474
475 const unsigned char *
476 rs_avp_octets_value_const_ptr(rs_const_avp *vp);
477
478 unsigned char *
479 rs_avp_octets_value_ptr(rs_avp *vp);
480
481 int
482 rs_avp_octets_value_byref(rs_avp *vp,
483                           unsigned char **p,
484                           size_t *len);
485
486 int
487 rs_avp_octets_value(rs_const_avp *vp,
488                     unsigned char *buf,
489                     size_t *len);
490
491 int
492 rs_avp_fragmented_value(rs_const_avp *vps,
493                         unsigned char *buf,
494                         size_t *len);
495
496 int
497 rs_avp_octets_set(rs_avp *vp,
498                   const unsigned char *buf,
499                   size_t len);
500
501 int
502 rs_avp_ifid_value(rs_const_avp *vp, uint8_t val[8]);
503
504 int
505 rs_avp_ifid_set(rs_avp *vp, const uint8_t val[8]);
506
507 uint8_t
508 rs_avp_byte_value(rs_const_avp *vp);
509
510 int
511 rs_avp_byte_set(rs_avp *vp, uint8_t val);
512
513 uint16_t
514 rs_avp_short_value(rs_const_avp *vp);
515
516 int
517 rs_avp_short_set(rs_avp *vp, uint16_t val);
518
519 size_t
520 rs_avp_display_value(rs_const_avp *vp,
521                      char *buffer,
522                      size_t buflen);
523
524 int
525 rs_attr_find(const char *name,
526              unsigned int *attr,
527              unsigned int *vendor);
528
529 const char *
530 rs_avp_name(rs_const_avp *vp);
531
532 #if defined (__cplusplus)
533 }
534 #endif
535
536 #endif /* _RADSEC_RADSEC_H_ */
537
538 /* Local Variables: */
539 /* c-file-style: "stroustrup" */
540 /* End: */