2 * This library is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU Lesser General Public
4 * License as published by the Free Software Foundation; either
5 * version 2.1 of the License, or (at your option) any later version.
7 * This library is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10 * Lesser General Public License for more details.
12 * You should have received a copy of the GNU Lesser General Public
13 * License along with this library; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 * @brief Structures and prototypes for the radius library.
24 * @copyright 1999-2008 The FreeRADIUS server project
27 #include <freeradius-devel/ident.h>
28 RCSIDH(libradius_h, "$Id$")
30 #include <freeradius-devel/missing.h>
35 * Let any external program building against the library know what
36 * features the library was built with.
38 #include <freeradius-devel/features.h>
44 #include <freeradius-devel/radius.h>
45 #include <freeradius-devel/token.h>
46 #include <freeradius-devel/hash.h>
48 #ifdef SIZEOF_UNSIGNED_INT
49 #if SIZEOF_UNSIGNED_INT != 4
50 #error FATAL: sizeof(unsigned int) != 4
59 * This definition of true as NOT false is definitive. :) Making
60 * it '1' can cause problems on stupid platforms. See articles
61 * on C portability for more information.
67 * Include for modules.
69 #include <freeradius-devel/sha1.h>
70 #include <freeradius-devel/md4.h>
78 #define AUTH_VECTOR_LEN 16
79 #define CHAP_VALUE_LENGTH 16
80 #define MAX_STRING_LEN 254 /* RFC2138: string 0-253 octets */
81 #define FR_MAX_VENDOR (1 << 24) /* RFC limitations */
84 # define AUTH_HDR_LEN 20
85 # define VENDORPEC_USR 429
86 #define VENDORPEC_LUCENT 4846
87 #define VENDORPEC_STARENT 8164
88 # define DEBUG if (fr_debug_flag && fr_log_fp) fr_printf_log
89 # define debug_pair(vp) do { if (fr_debug_flag && fr_log_fp) { \
90 vp_print(fr_log_fp, vp); \
95 #define TAG_VALID(x) ((x) > 0 && (x) < 0x20)
96 #define TAG_VALID_ZERO(x) ((x) < 0x20)
97 #define TAG_ANY -128 /* minimum signed char */
100 #if defined(__GNUC__)
101 # define PRINTF_LIKE(n) __attribute__ ((format(printf, n, n+1)))
102 # define NEVER_RETURNS __attribute__ ((noreturn))
103 # define UNUSED __attribute__ ((unused))
104 # define BLANK_FORMAT " " /* GCC_LINT whines about empty formats */
106 # define PRINTF_LIKE(n) /* ignore */
107 # define NEVER_RETURNS /* ignore */
108 # define UNUSED /* ignore */
109 # define BLANK_FORMAT ""
112 typedef struct attr_flags {
113 unsigned int is_unknown : 1; //!< Attribute number or
114 //!< vendor is unknown.
115 unsigned int is_tlv : 1; //!< Is a sub attribute.
116 unsigned int vp_free : 1; //!< Should be freed when
117 //!< VALUE_PAIR is freed.
119 unsigned int has_tag : 1; //!< Tagged attribute.
120 unsigned int array : 1; //!< Pack multiples into 1 attr.
121 unsigned int has_value : 1; //!< Has a value.
122 unsigned int has_value_alias : 1; //!< Has a value alias.
123 unsigned int has_tlv : 1; //!< Has sub attributes.
125 unsigned int extended : 1; //!< Extended attribute.
126 unsigned int long_extended : 1; //!< Long format.
127 unsigned int evs : 1; //!< Extended VSA.
128 unsigned int wimax: 1; //!< WiMAX format=1,1,c.
130 uint8_t encrypt; //!< Ecryption method.
135 * Values of the encryption flags.
137 #define FLAG_ENCRYPT_NONE (0)
138 #define FLAG_ENCRYPT_USER_PASSWORD (1)
139 #define FLAG_ENCRYPT_TUNNEL_PASSWORD (2)
140 #define FLAG_ENCRYPT_ASCEND_SECRET (3)
142 extern const FR_NAME_NUMBER dict_attr_types[];
144 typedef struct dict_attr {
152 typedef struct dict_value {
159 typedef struct dict_vendor {
160 unsigned int vendorpec;
161 size_t type; /* length of type data */
162 size_t length; /* length of length data */
167 typedef union value_pair_data {
168 char strvalue[MAX_STRING_LEN];
169 uint8_t octets[MAX_STRING_LEN];
170 struct in_addr ipaddr;
171 struct in6_addr ipv6addr;
177 uint8_t ifid[8]; /* struct? */
178 uint8_t ipv6prefix[18]; /* struct? */
179 uint8_t ipv4prefix[6]; /* struct? */
184 typedef enum value_type {
185 VT_NONE = 0, //!< VALUE_PAIR has no value.
186 VT_SET, //!< VALUE_PAIR has children.
187 VT_LIST, //!< VALUE_PAIR has multiple
189 VT_DATA, //!< VALUE_PAIR has a single
191 VT_XLAT //!< valuepair value must be
192 //!< xlat expanded when it's
193 //!< added to VALUE_PAIR tree.
196 typedef struct value_pair {
197 const DICT_ATTR *da; //!< Dictionary attribute
198 //!< defines the attribute
199 //!< number, vendor and type
200 //!< of the attribute.
202 struct value_pair *next;
204 FR_TOKEN op; //!< Operator to use when
205 //!< moving or inserting
206 //!< valuepair into a list.
208 int8_t tag; //!< Tag value used to group
212 // VALUE_SET *set; //!< Set of child attributes.
213 // VLAUE_LIST *list; //!< List of values for
214 //!< multivalued attribute.
215 // VALUE_DATA *data; //!< Value data for this
218 const char *xlat; //!< Source string for xlat
222 value_type_t type; //!< Type of pointer in value
225 size_t length; //!< of Data field.
226 VALUE_PAIR_DATA data;
230 typedef struct value_pair_raw {
231 char l_opand[64]; //!< Left hand side of the
233 char r_opand[1024]; //!< Right hand side of the
236 FR_TOKEN quote; //!< Type of quoting around
239 FR_TOKEN op; //!< Operator.
242 #define vp_strvalue data.strvalue
243 #define vp_octets data.octets
244 #define vp_ipv6addr data.ipv6addr
245 #define vp_ifid data.ifid
246 #define vp_ipv6prefix data.ipv6prefix
247 #define vp_ipv4prefix data.ipv4prefix
248 #define vp_filter data.filter
249 #define vp_ether data.ether
250 #define vp_signed data.sinteger
251 #define vp_tlv data.tlv
252 #define vp_integer64 data.integer64
253 #define vp_ipaddr data.ipaddr.s_addr
254 #define vp_date data.date
255 #define vp_integer data.integer
257 typedef struct fr_ipaddr_t {
258 int af; /* address family */
260 struct in_addr ip4addr;
261 struct in6_addr ip6addr; /* maybe defined in missing.h */
263 uint32_t scope; /* for IPv6 */
267 * vector: Request authenticator from access-request packet
268 * Put in there by rad_decode, and must be put in the
269 * response RADIUS_PACKET as well before calling rad_send
271 * verified: Filled in by rad_decode for accounting-request packets
273 * data,data_len: Used between rad_recv and rad_decode.
275 typedef struct radius_packet {
277 fr_ipaddr_t src_ipaddr;
278 fr_ipaddr_t dst_ipaddr;
283 uint8_t vector[AUTH_VECTOR_LEN];
284 struct timeval timestamp;
295 * Printing functions.
297 int fr_utf8_char(const uint8_t *str);
298 size_t fr_print_string(const char *in, size_t inlen,
299 char *out, size_t outlen);
300 int vp_prints_value(char *out, size_t outlen,
301 const VALUE_PAIR *vp, int delimitst);
302 int vp_prints_value_json(char *out, size_t outlen,
303 const VALUE_PAIR *vp);
304 size_t vp_print_name(char *buffer, size_t bufsize,
305 unsigned int attr, unsigned int vendor);
306 int vp_prints(char *out, size_t outlen, const VALUE_PAIR *vp);
307 void vp_print(FILE *, const VALUE_PAIR *);
308 void vp_printlist(FILE *, const VALUE_PAIR *);
309 #define fprint_attr_val vp_print
312 * Dictionary functions.
314 int str2argv(char *str, char **argv, int max_argc);
315 int dict_str2oid(const char *ptr, unsigned int *pattr,
316 unsigned int *pvendor, int tlv_depth);
317 int dict_addvendor(const char *name, unsigned int value);
318 int dict_addattr(const char *name, int attr, unsigned int vendor, int type, ATTR_FLAGS flags);
319 int dict_addvalue(const char *namestr, const char *attrstr, int value);
320 int dict_init(const char *dir, const char *fn);
321 void dict_free(void);
322 void dict_attr_free(DICT_ATTR const **da);
323 const DICT_ATTR *dict_attr_copy(const DICT_ATTR *da, int vp_free);
324 const DICT_ATTR *dict_attrunknown(unsigned int attr, unsigned int vendor, int vp_free);
325 const DICT_ATTR *dict_attrunknownbyname(const char *attribute, int vp_free);
326 const DICT_ATTR *dict_attrbyvalue(unsigned int attr, unsigned int vendor);
327 const DICT_ATTR *dict_attrbyname(const char *attr);
328 const DICT_ATTR *dict_attrbytype(unsigned int attr, unsigned int vendor,
330 const DICT_ATTR *dict_attrbyparent(const DICT_ATTR *parent, unsigned int attr,
331 unsigned int vendor);
332 int dict_attr_child(const DICT_ATTR *parent,
333 unsigned int *pattr, unsigned int *pvendor);
334 DICT_VALUE *dict_valbyattr(unsigned int attr, unsigned int vendor, int val);
335 DICT_VALUE *dict_valbyname(unsigned int attr, unsigned int vendor, const char *val);
336 const char *dict_valnamebyattr(unsigned int attr, unsigned int vendor, int value);
337 int dict_vendorbyname(const char *name);
338 DICT_VENDOR *dict_vendorbyvalue(int vendor);
340 #if 1 /* FIXME: compat */
341 #define dict_attrget dict_attrbyvalue
342 #define dict_attrfind dict_attrbyname
343 #define dict_valfind dict_valbyname
344 /*#define dict_valget dict_valbyattr almost but not quite*/
349 void fr_md5_calc(uint8_t *, const uint8_t *, unsigned int);
353 void fr_hmac_md5(const uint8_t *text, int text_len,
354 const uint8_t *key, int key_len,
355 unsigned char *digest);
359 void fr_hmac_sha1(const uint8_t *text, int text_len,
360 const uint8_t *key, int key_len,
364 int rad_send(RADIUS_PACKET *, const RADIUS_PACKET *, const char *secret);
365 int rad_packet_ok(RADIUS_PACKET *packet, int flags);
366 RADIUS_PACKET *rad_recv(int fd, int flags);
367 ssize_t rad_recv_header(int sockfd, fr_ipaddr_t *src_ipaddr, int *src_port,
369 void rad_recv_discard(int sockfd);
370 int rad_verify(RADIUS_PACKET *packet, RADIUS_PACKET *original,
372 int rad_decode(RADIUS_PACKET *packet, RADIUS_PACKET *original, const char *secret);
373 int rad_encode(RADIUS_PACKET *packet, const RADIUS_PACKET *original,
375 int rad_sign(RADIUS_PACKET *packet, const RADIUS_PACKET *original,
378 int rad_digest_cmp(const uint8_t *a, const uint8_t *b, size_t length);
379 RADIUS_PACKET *rad_alloc(int newvector);
380 RADIUS_PACKET *rad_alloc_reply(RADIUS_PACKET *);
381 void rad_free(RADIUS_PACKET **);
382 int rad_pwencode(char *encpw, size_t *len, const char *secret,
383 const uint8_t *vector);
384 int rad_pwdecode(char *encpw, size_t len, const char *secret,
385 const uint8_t *vector);
386 int rad_tunnel_pwencode(char *encpw, size_t *len, const char *secret,
387 const uint8_t *vector);
388 int rad_tunnel_pwdecode(uint8_t *encpw, size_t *len,
389 const char *secret, const uint8_t *vector);
390 int rad_chap_encode(RADIUS_PACKET *packet, uint8_t *output,
391 int id, VALUE_PAIR *password);
393 int rad_attr_ok(const RADIUS_PACKET *packet, const RADIUS_PACKET *original,
395 const uint8_t *data, size_t length);
396 int rad_tlv_ok(const uint8_t *data, size_t length,
397 size_t dv_type, size_t dv_length);
399 ssize_t rad_attr2vp(const RADIUS_PACKET *packet, const RADIUS_PACKET *original,
401 const uint8_t *data, size_t length,
404 ssize_t rad_data2vp(unsigned int attribute, unsigned int vendor,
405 const uint8_t *data, size_t length,
408 ssize_t rad_vp2data(const VALUE_PAIR *vp, uint8_t *out, size_t outlen);
410 int rad_vp2extended(const RADIUS_PACKET *packet,
411 const RADIUS_PACKET *original,
412 const char *secret, const VALUE_PAIR **pvp,
413 uint8_t *ptr, size_t room);
414 int rad_vp2wimax(const RADIUS_PACKET *packet,
415 const RADIUS_PACKET *original,
416 const char *secret, const VALUE_PAIR **pvp,
417 uint8_t *ptr, size_t room);
418 int rad_vp2vsa(const RADIUS_PACKET *packet, const RADIUS_PACKET *original,
419 const char *secret, const VALUE_PAIR **pvp, uint8_t *start,
421 int rad_vp2rfc(const RADIUS_PACKET *packet,
422 const RADIUS_PACKET *original,
423 const char *secret, const VALUE_PAIR **pvp,
424 uint8_t *ptr, size_t room);
426 int rad_vp2attr(const RADIUS_PACKET *packet,
427 const RADIUS_PACKET *original, const char *secret,
428 const VALUE_PAIR **pvp, uint8_t *ptr, size_t room);
431 VALUE_PAIR *pairalloc(TALLOC_CTX *ctx, const DICT_ATTR *da);
432 VALUE_PAIR *paircreate(unsigned int attr, unsigned int vendor);
433 int pair2unknown(VALUE_PAIR *vp);
434 void pairfree(VALUE_PAIR **);
435 void pairbasicfree(VALUE_PAIR *pair);
436 VALUE_PAIR *pairfind(VALUE_PAIR *, unsigned int attr, unsigned int vendor, int8_t tag);
437 void pairdelete(VALUE_PAIR **, unsigned int attr, unsigned int vendor, int8_t tag);
438 void pairadd(VALUE_PAIR **, VALUE_PAIR *);
439 void pairreplace(VALUE_PAIR **first, VALUE_PAIR *add);
440 int paircmp(VALUE_PAIR *check, VALUE_PAIR *data);
441 VALUE_PAIR *paircopyvp(const VALUE_PAIR *vp);
442 VALUE_PAIR *paircopyvpdata(const DICT_ATTR *da, const VALUE_PAIR *vp);
443 VALUE_PAIR *paircopy(VALUE_PAIR *vp);
444 VALUE_PAIR *paircopy2(VALUE_PAIR *vp, unsigned int attr, unsigned int vendor, int8_t tag);
445 void pairmove(VALUE_PAIR **to, VALUE_PAIR **from);
446 void pairmove2(VALUE_PAIR **to, VALUE_PAIR **from, unsigned int attr, unsigned int vendor, int8_t tag);
447 int pairparsevalue(VALUE_PAIR *vp, const char *value);
448 VALUE_PAIR *pairmake(const char *attribute, const char *value, FR_TOKEN op);
449 int pairmark_xlat(VALUE_PAIR *vp, const char *value);
450 FR_TOKEN pairread(const char **ptr, VALUE_PAIR_RAW *raw);
451 FR_TOKEN userparse(const char *buffer, VALUE_PAIR **head);
452 VALUE_PAIR *readvp2(FILE *fp, int *pfiledone, const char *errprefix);
458 void fr_strerror_printf(const char *, ...)
460 __attribute__ ((format (printf, 1, 2)))
464 void fr_perror(const char *, ...)
466 __attribute__ ((format (printf, 1, 2)))
469 extern const char *fr_strerror(void);
470 extern int fr_dns_lookups; /* 0 = no dns lookups */
471 extern int fr_debug_flag; /* 0 = no debugging information */
472 extern int fr_max_attributes; /* per incoming packet */
473 #define FR_MAX_PACKET_CODE (52)
474 extern const char *fr_packet_codes[FR_MAX_PACKET_CODE];
475 extern FILE *fr_log_fp;
476 extern void rad_print_hex(RADIUS_PACKET *packet);
477 void fr_printf_log(const char *, ...)
479 __attribute__ ((format (printf, 1, 2)))
484 * Several handy miscellaneous functions.
486 const char *ip_ntoa(char *, uint32_t);
487 char *ifid_ntoa(char *buffer, size_t size, const uint8_t *ifid);
488 uint8_t *ifid_aton(const char *ifid_str, uint8_t *ifid);
489 int rad_lockfd(int fd, int lock_len);
490 int rad_lockfd_nonblock(int fd, int lock_len);
491 int rad_unlockfd(int fd, int lock_len);
492 size_t fr_bin2hex(const uint8_t *bin, char *hex, size_t len);
493 size_t fr_hex2bin(const char *hex, uint8_t *bin, size_t len);
494 int fr_ipaddr_cmp(const fr_ipaddr_t *a, const fr_ipaddr_t *b);
496 int ip_hton(const char *src, int af, fr_ipaddr_t *dst);
497 const char *ip_ntoh(const fr_ipaddr_t *src, char *dst, size_t cnt);
498 int fr_ipaddr2sockaddr(const fr_ipaddr_t *ipaddr, int port,
499 struct sockaddr_storage *sa, socklen_t *salen);
500 int fr_sockaddr2ipaddr(const struct sockaddr_storage *sa, socklen_t salen,
501 fr_ipaddr_t *ipaddr, int * port);
504 #ifdef WITH_ASCEND_BINARY
506 int ascend_parse_filter(VALUE_PAIR *pair);
507 void print_abinary(const VALUE_PAIR *vp, char *buffer, size_t len, int delimitst);
508 #endif /*WITH_ASCEND_BINARY*/
510 /* random numbers in isaac.c */
511 /* context of random number generator */
512 typedef struct fr_randctx {
514 uint32_t randrsl[256];
515 uint32_t randmem[256];
521 void fr_isaac(fr_randctx *ctx);
522 void fr_randinit(fr_randctx *ctx, int flag);
523 uint32_t fr_rand(void); /* like rand(), but better. */
524 void fr_rand_seed(const void *, size_t ); /* seed the random pool */
527 /* crypt wrapper from crypt.c */
528 int fr_crypt_check(const char *key, const char *salt);
531 typedef struct rbtree_t rbtree_t;
532 typedef struct rbnode_t rbnode_t;
534 #define RBTREE_FLAG_NONE (0)
535 #define RBTREE_FLAG_REPLACE (1 << 0)
536 #define RBTREE_FLAG_LOCK (1 << 1)
537 rbtree_t *rbtree_create(int (*Compare)(const void *, const void *),
538 void (*freeNode)(void *),
540 void rbtree_free(rbtree_t *tree);
541 int rbtree_insert(rbtree_t *tree, void *Data);
542 rbnode_t *rbtree_insertnode(rbtree_t *tree, void *Data);
543 void rbtree_delete(rbtree_t *tree, rbnode_t *Z);
544 int rbtree_deletebydata(rbtree_t *tree, const void *data);
545 rbnode_t *rbtree_find(rbtree_t *tree, const void *Data);
546 void *rbtree_finddata(rbtree_t *tree, const void *Data);
547 int rbtree_num_elements(rbtree_t *tree);
548 void *rbtree_min(rbtree_t *tree);
549 void *rbtree_node2data(rbtree_t *tree, rbnode_t *node);
551 /* callback order for walking */
552 typedef enum { PreOrder, InOrder, PostOrder } RBTREE_ORDER;
555 * The callback should be declared as:
556 * int callback(void *context, void *data)
558 * The "context" is some user-defined context.
559 * The "data" is the pointer to the user data in the node,
560 * NOT the node itself.
562 * It should return 0 if all is OK, and !0 for any error.
563 * The walking will stop on any error.
565 int rbtree_walk(rbtree_t *tree, RBTREE_ORDER order, int (*callback)(void *, void *), void *context);
570 typedef struct fr_fifo_t fr_fifo_t;
571 typedef void (*fr_fifo_free_t)(void *);
572 fr_fifo_t *fr_fifo_create(int max_entries, fr_fifo_free_t freeNode);
573 void fr_fifo_free(fr_fifo_t *fi);
574 int fr_fifo_push(fr_fifo_t *fi, void *data);
575 void *fr_fifo_pop(fr_fifo_t *fi);
576 void *fr_fifo_peek(fr_fifo_t *fi);
577 int fr_fifo_num_elements(fr_fifo_t *fi);
583 #include <freeradius-devel/packet.h>
586 #include <freeradius-devel/tcp.h>
589 #endif /*LIBRADIUS_H*/