20#define PARSE_MODE_NAME 0
21#define PARSE_MODE_EQUAL 1
22#define PARSE_MODE_VALUE 2
23#define PARSE_MODE_INVALID 3
46VALUE_PAIR *
rc_avpair_add (rc_handle
const *rh, VALUE_PAIR **list, uint32_t attrid,
void const *pval,
int len, uint32_t vendorspec)
71 VALUE_PAIR *vp, *prev, *tmp;
74 if(vendorspec != VENDOR_NONE)
75 vattrid = RADCLI_VENDOR_ATTR_SET(attrid, vendorspec);
90 prev->next = vp->next;
142 len = (uint32_t)strlen((
char const *)pval);
146 if (len > (
int)(VENDOR(vp->
attribute) ? (AUTH_STRING_LEN - VSA_HDR_LEN) : (AUTH_STRING_LEN))) {
147 rc_log(LOG_ERR,
"rc_avpair_assign: bad attribute length");
150 memcpy(vp->
strvalue, (
char const *)pval, len);
158 vp->
lvalue = * (uint32_t *) pval;
162 rc_log(LOG_ERR,
"rc_avpair_assign: bad IPv6 length");
165 memcpy(vp->
strvalue, (
char const *)pval, len);
170 if (len < 2 || len > 18) {
171 rc_log(LOG_ERR,
"rc_avpair_assign: bad IPv6 prefix length");
174 memcpy(vp->
strvalue, (
char const *)pval, len);
179 rc_log(LOG_ERR,
"rc_avpair_assign: no attribute %d in dictionary", vp->
type);
196VALUE_PAIR *
rc_avpair_new (rc_handle
const *rh, uint32_t attrid,
void const *pval,
int len, uint32_t vendorspec)
198 VALUE_PAIR *vp = NULL;
202 if(vendorspec != VENDOR_NONE) {
203 vattrid = RADCLI_VENDOR_ATTR_SET(attrid, vendorspec);
210 rc_log(LOG_ERR,
"rc_avpair_new: no attribute %d/%u in dictionary", vendorspec, attrid);
215 rc_log(LOG_ERR,
"rc_avpair_new: no Vendor-Id %d in dictionary", vendorspec);
218 if ((vp = malloc (
sizeof (VALUE_PAIR))) != NULL)
239 if (vp->
lvalue > AUTH_STRING_LEN - 2)
240 vp->
lvalue = AUTH_STRING_LEN - 2;
257 rc_log(LOG_CRIT,
"rc_avpair_new: out of memory");
266static int rc_avpair_gen2(rc_handle
const *rh, VALUE_PAIR *pair,
267 pkt_buf *pb, uint32_t vendorspec,
270 VALUE_PAIR *head = pair;
271 VALUE_PAIR **tail = &head;
272 const uint8_t *attr_data, *ptr;
278 char buffer[(AUTH_STRING_LEN * 2) + 1];
281 while (*tail != NULL)
282 tail = &(*tail)->next;
284 while (pb_len(pb) > 0) {
285 if (pb_len(pb) < 2) {
286 rc_log(LOG_ERR,
"rc_avpair_gen: received attribute with "
290 attrlen = pb->data[1];
291 if (attrlen < 2 || (
size_t)attrlen > pb_len(pb)) {
292 rc_log(LOG_ERR,
"rc_avpair_gen: received attribute with "
297 attr_data = pb->data;
298 assert(pb_pull(pb, attrlen) == 0);
300 attribute = RADCLI_VENDOR_ATTR_SET(attr_data[0], vendorspec);
307 rc_log(LOG_ERR,
"rc_avpair_gen: received VSA "
308 "attribute with invalid length");
311 memcpy(&lvalue, ptr, 4);
312 lvalue = ntohl(lvalue);
314 rc_log(LOG_WARNING,
"rc_avpair_gen: received VSA "
315 "attribute with unknown Vendor-Id %d", lvalue);
321 VALUE_PAIR *vsa_list = NULL;
322 pb_init_read(&vsa_pb,
323 (
void *)(uintptr_t)(ptr + 4),
324 attrlen - 4, attrlen - 4);
325 if (rc_avpair_gen2(rh, NULL, &vsa_pb, lvalue,
329 if (vsa_list != NULL) {
331 while (*tail != NULL)
332 tail = &(*tail)->next;
341 rc_bin2hex(buffer,
sizeof(buffer), ptr, (
size_t)attrlen);
342 if (vendorspec == 0) {
343 rc_log(LOG_WARNING,
"rc_avpair_gen: received "
344 "unknown attribute %d of length %d: 0x%s",
345 (
unsigned)attribute, attrlen + 2, buffer);
347 rc_log(LOG_WARNING,
"rc_avpair_gen: received "
348 "unknown VSA attribute %u, vendor %u of "
349 "length %d: 0x%s", (
unsigned)ATTRID(attribute),
350 (
unsigned)VENDOR(attribute), attrlen + 2, buffer);
355 rpair = calloc(1,
sizeof(*rpair));
357 rc_log(LOG_CRIT,
"rc_avpair_gen: out of memory");
365 switch (attr->
type) {
367 if (attrlen > AUTH_STRING_LEN) {
368 rc_log(LOG_ERR,
"rc_avpair_gen: string attribute too long: %d", attrlen);
372 memcpy(rpair->
strvalue, (
char *)ptr, (
size_t)attrlen);
379 rc_log(LOG_ERR,
"rc_avpair_gen: received "
380 "INTEGER/IPADDR attribute with invalid length");
384 memcpy((
char *)&lvalue, (
char *)ptr, 4);
385 rpair->
lvalue = ntohl(lvalue);
389 rc_log(LOG_ERR,
"rc_avpair_gen: received IPV6ADDR"
390 " attribute with invalid length");
394 memcpy(rpair->
strvalue, (
char *)ptr, 16);
398 if (attrlen > 18 || attrlen < 2) {
399 rc_log(LOG_ERR,
"rc_avpair_gen: received IPV6PREFIX"
400 " attribute with invalid length: %d", attrlen);
404 memcpy(rpair->
strvalue, (
char *)ptr, attrlen);
409 rc_log(LOG_ERR,
"rc_avpair_gen: received DATE "
410 "attribute with invalid length");
414 memcpy((
char *)&lvalue, (
char *)ptr, 4);
415 rpair->
lvalue = ntohl(lvalue);
418 rc_log(LOG_WARNING,
"rc_avpair_gen: %s has unknown type",
460 unsigned char const *ptr,
int length,
464 VALUE_PAIR *out = NULL;
467 pb_init_read(&pb, (
void *)ptr, (
size_t)length, (
size_t)length);
468 if (rc_avpair_gen2(rh, pair, &pb, vendorspec, &out) < 0)
480VALUE_PAIR *
rc_avpair_get (VALUE_PAIR *vp, uint32_t attrid, uint32_t vendorspec)
482 uint64_t attr = RADCLI_VENDOR_ATTR_SET(attrid, vendorspec);
484 for (; vp != NULL && !(attr == vp->
attribute); vp = vp->next)
499 VALUE_PAIR *vp, *fp = NULL, *lp = NULL;
502 vp = malloc(
sizeof(VALUE_PAIR));
534 VALUE_PAIR *this_node = NULL;
539 rc_log(LOG_CRIT,
"rc_avpair_insert: value pair (0x%p) next ptr. (0x%p) not NULL", b, b->next);
562 while (this_node != NULL)
568 this_node = this_node->next;
573 b->next = this_node->next;
607static void rc_fieldcpy(
char *
string,
char const **uptr,
char const *stopat,
size_t len)
609 char const *ptr, *estring;
612 estring =
string + len - 1;
616 while (*ptr !=
'"' && *ptr !=
'\0' && *ptr !=
'\n')
618 if (
string < estring)
631 while (*ptr !=
'\0' && strchr(stopat, *ptr) == NULL)
633 if (
string < estring)
653 char attrstr[AUTH_ID_LEN];
654 char valstr[AUTH_STRING_LEN + 1], *p;
655 DICT_ATTR *attr = NULL;
662 mode = PARSE_MODE_NAME;
663 while (*buffer !=
'\n' && *buffer !=
'\0')
665 if (*buffer ==
' ' || *buffer ==
'\t')
673 case PARSE_MODE_NAME:
674 rc_fieldcpy (attrstr, &buffer,
" \t\n=,",
sizeof(attrstr));
678 rc_log(LOG_ERR,
"rc_avpair_parse: unknown attribute");
685 mode = PARSE_MODE_EQUAL;
688 case PARSE_MODE_EQUAL:
691 mode = PARSE_MODE_VALUE;
696 rc_log(LOG_ERR,
"rc_avpair_parse: missing or misplaced equal sign");
705 case PARSE_MODE_VALUE:
706 rc_fieldcpy (valstr, &buffer,
" \t\n,",
sizeof(valstr));
708 if ((pair = malloc (
sizeof (VALUE_PAIR))) == NULL)
710 rc_log(LOG_CRIT,
"rc_avpair_parse: out of memory");
726 rc_log(LOG_ERR,
"rc_avpair_parse: string value too long");
733 if (isdigit (*valstr))
735 pair->
lvalue = atoi (valstr);
742 rc_log(LOG_ERR,
"rc_avpair_parse: unknown attribute value: %s", valstr);
752 pair->
lvalue = dval->value;
758 if (inet_pton(AF_INET, valstr, &pair->
lvalue) == 0) {
759 rc_log(LOG_ERR,
"rc_avpair_parse: invalid IPv4 address %s", valstr);
768 if (inet_pton(AF_INET6, valstr, pair->
strvalue) == 0) {
769 rc_log(LOG_ERR,
"rc_avpair_parse: invalid IPv6 address %s", valstr);
777 p = strchr(valstr,
'/');
779 rc_log(LOG_ERR,
"rc_avpair_parse: invalid IPv6 prefix %s", valstr);
788 if (inet_pton(AF_INET6, valstr, pair->
strvalue+2) == 0) {
789 rc_log(LOG_ERR,
"rc_avpair_parse: invalid IPv6 prefix %s", valstr);
798 tm = localtime_r (&timeval, &_tm);
802 if (rc_str2tm (valstr, tm) < 0) {
803 rc_log(LOG_ERR,
"rc_avpair_parse: invalid date %s", valstr);
807 pair->
lvalue = (uint32_t) mktime (tm);
811 rc_log(LOG_ERR,
"rc_avpair_parse: unknown attribute type %d", pair->
type);
833 if (pair->
lvalue > AUTH_STRING_LEN - 2)
834 pair->
lvalue = AUTH_STRING_LEN - 2;
848 if (*first_pair == NULL)
855 while (link->next != NULL)
862 mode = PARSE_MODE_NAME;
866 mode = PARSE_MODE_NAME;
883int rc_avpair_tostr (rc_handle
const *rh, VALUE_PAIR *pair,
char *name,
int ln,
char *value,
int lv)
891 *name = *value =
'\0';
893 if (!pair || pair->
name[0] ==
'\0') {
894 rc_log(LOG_ERR,
"rc_avpair_tostr: pair is NULL or empty");
898 strlcpy(name, pair->
name, (
size_t) ln);
905 ptr = (
unsigned char *) pair->
strvalue;
914 if (!(isprint (*ptr)))
917 snprintf (&value[pos], lv,
"\\%03o", *ptr);
942 strlcpy(value, dval->name, (
size_t) lv);
946 snprintf(value, lv,
"%ld", (
long int)pair->
lvalue);
951 inad.s_addr = htonl(pair->
lvalue);
952 strlcpy (value, inet_ntoa (inad), (
size_t) lv);
956 if (inet_ntop(AF_INET6, pair->
strvalue, value, lv) == NULL)
966 memset(ip, 0,
sizeof(ip));
969 if (inet_ntop(AF_INET6, ip, (
void*)txt,
sizeof(txt)) == NULL)
971 snprintf(value, lv,
"%s/%u", txt, (
unsigned)pair->
strvalue[1]);
977 struct tm *ptm = gmtime_r((time_t *) & pair->
lvalue, &_tm);
981 strftime (value, lv,
"%m/%d/%y %H:%M:%S", ptm);
986 rc_log(LOG_ERR,
"rc_avpair_tostr: unknown attribute type %d", pair->
type);
1004char *
rc_avpair_log(rc_handle
const *rh, VALUE_PAIR *pair,
char *buf,
size_t buf_len)
1009 char name[RC_NAME_LENGTH + 1], value[256];
1012 for (vp = pair; vp != NULL; vp = vp->next) {
1014 sizeof(value)) == -1)
1018 n = snprintf(buf + len, buf_len - len,
"%-32s = '%s'\n", name, value);
1019 if (n < 0 || (
size_t)n >= buf_len - len)
1072 *prefix = (
unsigned char)vp->
strvalue[1];
void rc_avpair_remove(VALUE_PAIR **list, uint32_t attrid, uint32_t vendorspec)
Removes an attribute-value pair from the given list.
DICT_VALUE * rc_dict_getval(rc_handle const *rh, uint32_t value, char const *attrname)
Get DICT_VALUE based on attribute name and integer value number.
int rc_avpair_get_raw(VALUE_PAIR *vp, char **res, unsigned *res_size)
Get the raw value of the given attribute value-pair.
char * rc_avpair_log(rc_handle const *rh, VALUE_PAIR *pair, char *buf, size_t buf_len)
Format a sequence of attribute value pairs into a printable string.
VALUE_PAIR * rc_avpair_next(VALUE_PAIR *t)
Iterates through the attribute-value pairs.
int rc_avpair_get_uint32(VALUE_PAIR *vp, uint32_t *res)
Get the integer value of the given attribute value-pair.
int rc_avpair_get_in6(VALUE_PAIR *vp, struct in6_addr *res, unsigned *prefix)
Get the IPv6 address and prefix value of the given attribute value-pair.
void rc_avpair_get_attr(VALUE_PAIR *vp, unsigned *type, unsigned *id)
Get the attribute ID and type of the given attribute value-pair.
VALUE_PAIR * rc_avpair_gen(rc_handle const *rh, VALUE_PAIR *pair, unsigned char const *ptr, int length, uint32_t vendorspec)
Decode a raw RADIUS attribute buffer into a VALUE_PAIR list.
void rc_avpair_free(VALUE_PAIR *pair)
Frees all value_pairs in the list.
VALUE_PAIR * rc_avpair_copy(VALUE_PAIR *p)
Return a copy of the existing list "p" ala strdup().
int rc_avpair_tostr(rc_handle const *rh, VALUE_PAIR *pair, char *name, int ln, char *value, int lv)
Translate an av_pair into printable strings.
int rc_avpair_assign(VALUE_PAIR *vp, void const *pval, int len)
Assigns the given value to an attribute-value pair.
DICT_VALUE * rc_dict_findval(rc_handle const *rh, char const *valname)
Lookup a DICT_VALUE by its name.
int rc_avpair_parse(rc_handle const *rh, char const *buffer, VALUE_PAIR **first_pair)
Parses the buffer to extract the attribute-value pairs.
DICT_VENDOR * rc_dict_getvend(rc_handle const *rh, uint32_t vendorspec)
Lookup a DICT_VENDOR by its IANA number.
DICT_ATTR * rc_dict_getattr(rc_handle const *rh, uint64_t attribute)
Lookup a DICT_ATTR by attribute number.
VALUE_PAIR * rc_avpair_add(rc_handle const *rh, VALUE_PAIR **list, uint32_t attrid, void const *pval, int len, uint32_t vendorspec)
Adds an attribute-value pair to the given list.
void rc_avpair_insert(VALUE_PAIR **a, VALUE_PAIR *p, VALUE_PAIR *b)
Insert a VALUE_PAIR into a list.
VALUE_PAIR * rc_avpair_get(VALUE_PAIR *vp, uint32_t attrid, uint32_t vendorspec)
Find the first attribute value-pair (which matches the given attribute) from the specified value-pair...
DICT_ATTR * rc_dict_findattr(rc_handle const *rh, char const *attrname)
Lookup a DICT_ATTR by its name.
VALUE_PAIR * rc_avpair_new(rc_handle const *rh, uint32_t attrid, void const *pval, int len, uint32_t vendorspec)
Make a new attribute-value pair with given parameters.
@ PW_DIGEST_NONCE
Its type is string.
@ PW_DIGEST_REALM
Its type is string.
@ PW_DIGEST_USER_NAME
Its type is string.
@ PW_DIGEST_URI
Its type is string.
@ PW_DIGEST_QOP
Its type is string.
@ PW_DIGEST_BODY_DIGEST
Its type is string.
@ PW_DIGEST_ATTRIBUTES
Its type is string.
@ PW_DIGEST_NONCE_COUNT
Its type is string.
@ PW_DIGEST_ALGORITHM
Its type is string.
@ PW_DIGEST_CNONCE
Its type is string.
@ PW_DIGEST_METHOD
Its type is string.
@ PW_VENDOR_SPECIFIC
Its type is string.
@ PW_TYPE_IPADDR
The attribute is an IPv4 address in host-byte order.
@ PW_TYPE_IPV6ADDR
The attribute is an 128-bit IPv6 address.
@ PW_TYPE_IPV6PREFIX
The attribute is an IPv6 prefix; the lvalue will indicate its size.
@ PW_TYPE_INTEGER
The attribute is a 32-bit integer.
@ PW_TYPE_DATE
The attribute contains a 32-bit number indicating the seconds since epoch.
@ PW_TYPE_STRING
The attribute is a printable string.
Public API of the radcli library.
rc_attr_type type
string, int, etc..
uint64_t value
attribute index and vendor number; use VENDOR() and ATTRID() to separate.
char name[RC_NAME_LENGTH+1]
attribute name.
rc_attr_type type
attribute type.
uint64_t attribute
attribute numeric value of type rc_attr_id including vendor; use VENDOR() and ATTRID() to separate.
uint32_t lvalue
attribute value if type is PW_TYPE_INTEGER, PW_TYPE_DATE or PW_TYPE_IPADDR.
char strvalue[AUTH_STRING_LEN+1]
contains attribute value in other cases.
char name[RC_NAME_LENGTH+1]
attribute name if known.